diff --git a/.github/workflows/build-linux-aarch64-wheels.yml b/.github/workflows/build-linux-aarch64-wheels.yml index 003e9e311b..a38721dbc8 100644 --- a/.github/workflows/build-linux-aarch64-wheels.yml +++ b/.github/workflows/build-linux-aarch64-wheels.yml @@ -29,13 +29,15 @@ jobs: dnf install -y /usr/bin/patch - name: Checkout uses: actions/checkout@main + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + rustflags: "-A warnings -A unexpected-cfgs -A unused-macros -A static-mut-refs -A unused-variables -A unused-imports" + cache: false - name: Build wheels run: | + export PIP_GRAALPY_PATCHES_URL="${GITHUB_WORKSPACE}/graalpython/lib-graalpython/patches" python3 -m venv wheelbuilder_venv - export PIP_EXTRA_INDEX_URL=https://pypi.org/simple wheelbuilder_venv/bin/python3 scripts/wheelbuilder/build_wheels.py ${{ inputs.graalpy_url }} - - name: Build wheels - run: python3 scripts/wheelbuilder/build_wheels.py ${{ inputs.graalpy_url }} - name: Store wheels uses: actions/upload-artifact@main with: diff --git a/.github/workflows/build-linux-amd64-wheels.yml b/.github/workflows/build-linux-amd64-wheels.yml index a8bffb78d2..03578196c4 100644 --- a/.github/workflows/build-linux-amd64-wheels.yml +++ b/.github/workflows/build-linux-amd64-wheels.yml @@ -27,10 +27,14 @@ jobs: dnf install -y /usr/bin/patch - name: Checkout uses: actions/checkout@main + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + rustflags: "-A warnings -A unexpected-cfgs -A unused-macros -A static-mut-refs -A unused-variables -A unused-imports" + cache: false - name: Build wheels run: | + export PIP_GRAALPY_PATCHES_URL="${GITHUB_WORKSPACE}/graalpython/lib-graalpython/patches" python3 -m venv wheelbuilder_venv - export PIP_EXTRA_INDEX_URL=https://pypi.org/simple wheelbuilder_venv/bin/python3 scripts/wheelbuilder/build_wheels.py ${{ inputs.graalpy_url }} - name: Store wheels uses: actions/upload-artifact@main diff --git a/.github/workflows/build-macos-aarch64-wheels.yml b/.github/workflows/build-macos-aarch64-wheels.yml index 08e8048541..0e74bcea44 100644 --- a/.github/workflows/build-macos-aarch64-wheels.yml +++ b/.github/workflows/build-macos-aarch64-wheels.yml @@ -18,13 +18,17 @@ jobs: steps: - name: Checkout uses: actions/checkout@main + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + rustflags: "-A warnings -A unexpected-cfgs -A unused-macros -A static-mut-refs -A unused-variables -A unused-imports" + cache: false - name: Setup Python uses: actions/setup-python@v5 with: python-version: 3.12 - name: Build wheels run: | - export PIP_EXTRA_INDEX_URL=https://pypi.org/simple + export PIP_GRAALPY_PATCHES_URL="${GITHUB_WORKSPACE}/graalpython/lib-graalpython/patches" python3 scripts/wheelbuilder/build_wheels.py ${{ inputs.graalpy_url }} - name: Store wheels uses: actions/upload-artifact@main diff --git a/.github/workflows/build-macos-amd64-wheels.yml b/.github/workflows/build-macos-amd64-wheels.yml index 3382d5f163..b6bd9a4226 100644 --- a/.github/workflows/build-macos-amd64-wheels.yml +++ b/.github/workflows/build-macos-amd64-wheels.yml @@ -18,13 +18,17 @@ jobs: steps: - name: Checkout uses: actions/checkout@main + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + rustflags: "-A warnings -A unexpected-cfgs -A unused-macros -A static-mut-refs -A unused-variables -A unused-imports" + cache: false - name: Setup Python uses: actions/setup-python@v5 with: python-version: 3.12 - name: Build wheels run: | - export PIP_EXTRA_INDEX_URL=https://pypi.org/simple + export PIP_GRAALPY_PATCHES_URL="${GITHUB_WORKSPACE}/graalpython/lib-graalpython/patches" python3 scripts/wheelbuilder/build_wheels.py ${{ inputs.graalpy_url }} - name: Store wheels uses: actions/upload-artifact@main diff --git a/.github/workflows/build-windows-amd64-wheels.yml b/.github/workflows/build-windows-amd64-wheels.yml index 8563dcb7de..782524ed7b 100644 --- a/.github/workflows/build-windows-amd64-wheels.yml +++ b/.github/workflows/build-windows-amd64-wheels.yml @@ -19,6 +19,10 @@ jobs: - uses: ilammy/msvc-dev-cmd@v1 - name: Checkout uses: actions/checkout@main + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + rustflags: "-A warnings -A unexpected-cfgs -A unused-macros -A static-mut-refs -A unused-variables -A unused-imports" + cache: false - name: Setup Python uses: actions/setup-python@v5 with: @@ -26,7 +30,8 @@ jobs: - name: Build wheels run: | $env:PATH+=";C:\Program Files\Git\usr\bin" - $env:PIP_EXTRA_INDEX_URL="https://pypi.org/simple" + $env:PIP_GRAALPY_PATCHES_URL=$env:GITHUB_WORKSPACE + $env:PIP_GRAALPY_PATCHES_URL+="/graalpython/lib-graalpython/patches" python3 scripts/wheelbuilder/build_wheels.py ${{ inputs.graalpy_url }} - name: Store wheels uses: actions/upload-artifact@main diff --git a/.gitignore b/.gitignore index f4da3d24c6..bf2d8928b6 100644 --- a/.gitignore +++ b/.gitignore @@ -70,6 +70,7 @@ Python.asdl.stamp *.jfr .DS_Store +docs/site/_site graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/antlr/.antlr/ graalpython/lib-python/3/test/data !graalpython/lib-python/3/test/data/README @@ -94,3 +95,5 @@ graalpython/com.oracle.graal.python.test/src/tests/cpyext/build/ pom-mx.xml .venv !graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/gradle-test-project/gradle/wrapper/gradle-wrapper.jar +/*-venv/ +.aider* diff --git a/CHANGELOG.md b/CHANGELOG.md index 02b01a9454..737ca73d43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,14 @@ This changelog summarizes major changes between GraalVM versions of the Python language runtime. The main focus is on user-observable behavior of the engine. +## Version 25.0.0 +* `sys.implementation.version` now returns the GraalPy version instead of the Python version it implements. Also available as `sys.graalpy_version_info` for better discoverability by people already familiar with PyPy and its `sys.pypy_version_info`. +* `GRAALPY_VERSION_NUM` C macro now inlcudes the release level and serial number at the end to conform to the `hexversion` format. This shouldn't break any existing comparisons. +* `dir(foreign_object)` now returns both foreign methods and Python methods (it used to return only foreign methods). +* Support `__name__`, `__doc__`, `__text_signature__` fields on foreign executables to serve as their proper counterparts on the Python side. This is useful to, for example, use Java functional interfaces in lieu of Python functions for things like LangChain's `@tool` annotation that want to inspect the underlying function. +* Remove support for running C extensions as LLVM bitcode. This also removes the related options `python.UseSystemToolchain` and `python.NativeModules`. +* Remove built-in HPy module. HPy can now be installed and used from the upstream sources. + ## Version 24.2.0 * Updated developer metadata of Maven artifacts. * Added gradle plugin for polyglot embedding of Python packages into Java. diff --git a/README.md b/README.md index 2e036787f1..3d42b21e50 100644 --- a/README.md +++ b/README.md @@ -54,20 +54,20 @@ Refer to our [embedding documentation](https://www.graalvm.org/latest/reference- org.graalvm.polyglot polyglot - 24.1.1 + 24.2.0 org.graalvm.polyglot python - 24.1.1 + 24.2.0 pom ``` * Gradle ```kotlin - implementation("org.graalvm.polyglot:polyglot:24.1.1") - implementation("org.graalvm.polyglot:python:24.1.1") + implementation("org.graalvm.polyglot:polyglot:24.2.0") + implementation("org.graalvm.polyglot:python:24.2.0") ``` @@ -85,12 +85,12 @@ Thanks to our integration with GraalVM Native Image, we can deploy Python applic * Linux The easiest way to install GraalPy on Linux is to use [Pyenv](https://github.com/pyenv/pyenv) (the Python version manager). - To install version 24.1.1 using Pyenv, run the following commands: + To install version 24.2.0 using Pyenv, run the following commands: ```bash - pyenv install graalpy-24.1.1 + pyenv install graalpy-24.2.0 ``` ```bash - pyenv shell graalpy-24.1.1 + pyenv shell graalpy-24.2.0 ``` > NOTE: There will be a delay between GraalPy release and its availability on Pyenv. Make sure to update Pyenv. @@ -102,12 +102,12 @@ Thanks to our integration with GraalVM Native Image, we can deploy Python applic * macOS The easiest way to install GraalPy on macOS is to use [Pyenv](https://github.com/pyenv/pyenv) (the Python version manager). - To install version 24.1.1 using Pyenv, run the following commands: + To install version 24.2.0 using Pyenv, run the following commands: ```bash - pyenv install graalpy-24.1.1 + pyenv install graalpy-24.2.0 ``` ```bash - pyenv shell graalpy-24.1.1 + pyenv shell graalpy-24.2.0 ``` > NOTE: There will be a delay between GraalPy release and its availability on Pyenv. Make sure to update Pyenv. @@ -120,7 +120,7 @@ Thanks to our integration with GraalVM Native Image, we can deploy Python applic ``` For example: ```bash - sudo xattr -r -d com.apple.quarantine ~/.pyenv/versions/graalpy-24.1.1 + sudo xattr -r -d com.apple.quarantine ~/.pyenv/versions/graalpy-24.2.0 ``` 3. Uncompress the file and update your `PATH` environment variable to include to the _graalpy-XX.Y.Z-macos-amd64/bin_ (or _graalpy-XX.Y.Z-macos-aarch64/bin_) directory. @@ -128,12 +128,12 @@ Thanks to our integration with GraalVM Native Image, we can deploy Python applic The Windows support of GraalPy is still experimental, so not all features and packages may be available. The easiest way to install GraalPy on Windows is to use [Pyenv-win](https://pyenv-win.github.io/pyenv-win/) (the Python version manager for Windows). - To install version 24.1.1 using Pyenv-win, run the following commands: + To install version 24.2.0 using Pyenv-win, run the following commands: ```cmd - pyenv install graalpy-24.1.1-windows-amd64 + pyenv install graalpy-24.2.0-windows-amd64 ``` ```cmd - pyenv shell graalpy-24.1.1-windows-amd64 + pyenv shell graalpy-24.2.0-windows-amd64 ``` > NOTE: There will be a delay between GraalPy release and its availability on Pyenv. Make sure to update Pyenv. @@ -152,7 +152,7 @@ The _setup-python_ action supports GraalPy: - name: Setup GraalPy uses: actions/setup-python@v5 with: - python-version: graalpy # or graalpy24.1 to pin a version + python-version: graalpy # or graalpy24.2 to pin a version ``` @@ -179,7 +179,7 @@ To run Jython scripts, you need to use a GraalPy distribution running on the JVM ``` For example: ```bash - sudo xattr -r -d com.apple.quarantine ~/.pyenv/versions/graalpy-24.1.1 + sudo xattr -r -d com.apple.quarantine ~/.pyenv/versions/graalpy-24.2.0 ``` 3. Uncompress the file and update your `PATH` environment variable to include to the _graalpy-jvm-XX.Y.Z-macos-amd64/bin_ (or _graalpy-jvm-XX.Y.Z-macos-aarch64/bin_) directory. 4. Run your scripts with `graalpy --python.EmulateJython`. diff --git a/ci.jsonnet b/ci.jsonnet index 60791dfb90..20a3bc7c16 100644 --- a/ci.jsonnet +++ b/ci.jsonnet @@ -1 +1 @@ -{ "overlay": "bfb3f7fd7d0d4df846dad9d87dfa10d7a79dfd8b" } +{ "overlay": "a74e2e4ae250150f0f974c20c80ac212a9116ea1" } diff --git a/docs/contributor/DEV_TASKS.md b/docs/contributor/DEV_TASKS.md index 6fed69a26a..da569c4a5b 100644 --- a/docs/contributor/DEV_TASKS.md +++ b/docs/contributor/DEV_TASKS.md @@ -3,7 +3,7 @@ ### Updating dependencies We can use the following command to update our CI jsonnet as well as all -dependencies (truffle, sulong, ...) in one go: +dependencies (truffle, ...) in one go: mx python-update-import @@ -26,32 +26,22 @@ It prints a fairly long help. Note that you'll need to make sure you also pushed your `python-import` branch after doing the update, so that any conflicts you resolved don't have to be resolved again by the next person. -### Updating hpy - -Follow these steps to update HPy. - - - 1. Merge updated hpy sources. To do so, clone hpy somewhere next to - graalpython. Then run the following command on a new branch of graalpython: +### Updating patch branch +GraalPy's `pip` has an ability to download newer versions of patches from our +GitHub so that we can update patches outside of the release cycle. There should +be a patch branch for every minor release, with the name +`github/patches/$version`. When creating the branch, it should be based on the +release tag commit and then it should change the CI overlay version to point to +the head of branch `graalpy-patch-branch` in order to disable unnecessary gates +on it. The GitHub sync needs to be manually enabled in the mirroring service +configuration. - mx python-update-hpy-import --pull /path/to/clone/of/hpy - - Follow the instructions. - 2. We need to fix compilation. We patch the hpy sources, and the merge may - have introduced new API or types, and for these we need to apply - patches. At the time of this writing, we redefine hpy types conditionally - on `#ifdef GRAALVM_PYTHON_LLVM` (grep for this to find some - examples). Also, we use macros to convert between the structured hpy types - and plain pointers for our native interface, see the uses of the `WRAP` and - `UNWRAP` macros. - 3. Once compilation is working, we try to run the tests and go on fixing - them. If new API was added, `GraalHPyContext` needs to be adapted with the - new signatures and/or types. This may include: - - - Updating the HPyContextMember enum - - Updating the HPyContextSignatureType enum - - Adding `GraalHPyContextFunction` implementations for the new APIs - - Updating the `createMembers` method to assign the appropriate - implementations to the context members - - Updating hpy.c to assign new context members to their native locations +### Updating hpy +1. Switch to the `hpy-import` branch +2. Delete `graalpython/hpy` +3. Copy the sources from the hpy repo into `graalpython/hpy` (e.g git clone + them there, then delete the `graalpython/hpy/.git` folder) +4. Go back to your previous branch and merge hpy-import. +5. Go to `graalpython/hpy/build.py` and update the `VERSION` constant to + whatever you updated to. diff --git a/docs/site/01-docs.md b/docs/site/01-docs.md new file mode 100644 index 0000000000..294c748ac1 --- /dev/null +++ b/docs/site/01-docs.md @@ -0,0 +1,19 @@ +--- +layout: docs +title: Documentation +permalink: docs/ +--- + +{% gfm_docs ../user/README.md %} +{% gfm_docs ../user/Python-Runtime.md %} +{% gfm_docs ../user/Performance.md %} +{% gfm_docs ../user/Python-on-JVM.md %} +{% gfm_docs ../user/Native-Images-with-Python.md %} +{% gfm_docs ../user/Python-Standalone-Applications.md %} +{% gfm_docs ../user/Interoperability.md %} +{% gfm_docs ../user/Embedding-Build-Tools.md %} +{% gfm_docs ../user/Embedding-Permissions.md %} +{% gfm_docs ../user/Tooling.md %} +{% gfm_docs ../user/Troubleshooting.md %} + +{% copy_assets ../user/assets %} diff --git a/docs/site/02-downloads.md b/docs/site/02-downloads.md new file mode 100644 index 0000000000..fcf6ca3795 --- /dev/null +++ b/docs/site/02-downloads.md @@ -0,0 +1,396 @@ +--- +layout: base +title: Downloads +permalink: downloads/ +published: false +--- + +
+
+
+
+

Download GraalPy from Maven Central

+
+
+ Have a Java application? +
+
+You can extend it with Python code or leverage packages from the Python ecosystem. GraalPy is available on Maven Central and can be added as a dependency to your Maven or Gradle project as — see setup instructions. +
+
+
+
+
+
+ +
+
+
+
+

Download Standalone Distributions of GraalPy

+
+
+ Do you want to test your Python application or package on GraalPy? +
+
+ To test Python code on GraalPy, a standalone distribution is available for different platforms and in two different kinds: Native (for compact download and footprint) and JVM (for full Java interoperability). We recommend the distributions based on Oracle GraalVM for best performance and advanced features (released under the GFTC license). Distributions based on GraalVM Community Edition (released under the OSI-approved UPL license) are available on GitHub. Standalone distributions are also available via pyenv, pyenv-win, and setup-python: +
+
+
+
+
+ {%- highlight bash -%} +# Latest GraalPy release +pyenv install graalpy-{{ site.language_version }} +pyenv shell graalpy-{{ site.language_version }} + +# Latest EA build of GraalPy +pyenv install graalpy-dev +pyenv shell graalpy-dev + {%- endhighlight -%} +
+
+
+ pyenv and pyenv-win +
+
+
+
+
+ {%- highlight yml -%} +steps: +- uses: actions/checkout@v4 +- uses: actions/setup-python@v5 + with: + python-version: 'graalpy-{{ site.language_version }}' +- run: python my_script.py + {%- endhighlight -%} +
+ +
+
+ +
GraalPy on Oracle GraalVM is free to use in production and free to redistribute, at no cost, under the GraalVM Free Terms and Conditions.
+
+
+
+
diff --git a/docs/site/03-compatibility.md b/docs/site/03-compatibility.md new file mode 100644 index 0000000000..8d3f1b86be --- /dev/null +++ b/docs/site/03-compatibility.md @@ -0,0 +1,379 @@ +--- +layout: base +title: Compatibility +permalink: compatibility/ +--- + + + +
+
+
+
+

GraalPy: Package Compatibility

+
+
+

GraalPy 24.2

+

GraalPy 24.1

+
+
+
+
+
+
+ +
+
+
+
+
To ensure GraalPy is compatible with common Python packages, the GraalPy team conducts + compatibility testing to verify the presence and correct functioning of + the top 500 packages on PyPI plus some more that are of special interest to us, including + libraries and frameworks such as NumPy, Pandas, and Django.
+
Compatibility testing ensures that + developers can leverage GraalPy's powerful capabilities in their existing applications. + It also enables developers to use GraalPy to create more efficient and productive applications in the areas of + machine learning, data analysis, and web development using their familiar Python + toolsets.
+
Many more Python packages than are on this list work on GraalPy. + If there is a package you are interested in that you cannot find here, chances are that it + might just work.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Compatible: loading...
+
+ Currently Untested: loading...
+
+
+
Currently + Incompatible: loading...
+
Not + Supported: loading...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

Python Packages

+
+ +
+
+ + +
+ +
+
+
+ + + + + + + + + + + +
Python Packages
NameVersionTest Level %Package URL
+
+
+
+ + +
+
+ + +
+
+
+
+
+
+
diff --git a/docs/site/Gemfile b/docs/site/Gemfile new file mode 100644 index 0000000000..2c11ff519e --- /dev/null +++ b/docs/site/Gemfile @@ -0,0 +1,33 @@ +source "https://rubygems.org/" + +gem "jekyll", "~> 4.3.4" + +gem "graal-languages-jekyll-theme" + +group :jekyll_plugins do + gem "jekyll-relative-links" + gem "jekyll-seo-tag" +end + +# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem +# and associated library. +platforms :mingw, :x64_mingw, :mswin, :jruby do + gem "tzinfo", ">= 1", "< 3" + gem "tzinfo-data" +end + +# Performance-booster for watching directories on Windows +gem "wdm", "~> 0.1", :platforms => [:mingw, :x64_mingw, :mswin] + +# Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem +# do not have a Java counterpart. +gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby] + +# Clean unused resources with `bundle exec siteleaf clean resources` +group :development do + gem 'siteleaf' + gem 'pry' + gem 'html-proofer' + # Run this with: + # bundle exec htmlproofer --swap-urls '^/python/:/' ./_site/ +end diff --git a/docs/site/Gemfile.lock b/docs/site/Gemfile.lock new file mode 100644 index 0000000000..d7ae358a10 --- /dev/null +++ b/docs/site/Gemfile.lock @@ -0,0 +1,157 @@ +GEM + remote: https://rubygems.org/ + specs: + Ascii85 (2.0.1) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + afm (0.2.2) + async (2.23.0) + console (~> 1.29) + fiber-annotation + io-event (~> 1.9) + metrics (~> 0.12) + traces (~> 0.15) + bigdecimal (3.1.8) + coderay (1.1.3) + colorator (1.1.0) + concurrent-ruby (1.3.4) + console (1.29.3) + fiber-annotation + fiber-local (~> 1.1) + json + csv (3.3.0) + em-websocket (0.5.3) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0) + ethon (0.16.0) + ffi (>= 1.15.0) + eventmachine (1.2.7) + ffi (1.17.0-x86_64-linux-gnu) + fiber-annotation (0.2.0) + fiber-local (1.1.0) + fiber-storage + fiber-storage (1.0.0) + forwardable-extended (2.6.0) + google-protobuf (4.28.3-x86_64-linux) + bigdecimal + rake (>= 13) + graal-languages-jekyll-theme (0.1.0) + jekyll (~> 4.3) + hashery (2.1.2) + html-proofer (5.0.10) + addressable (~> 2.3) + async (~> 2.1) + nokogiri (~> 1.13) + pdf-reader (~> 2.11) + rainbow (~> 3.0) + typhoeus (~> 1.3) + yell (~> 2.0) + zeitwerk (~> 2.5) + http_parser.rb (0.8.0) + httparty (0.22.0) + csv + mini_mime (>= 1.0.0) + multi_xml (>= 0.5.2) + i18n (1.14.6) + concurrent-ruby (~> 1.0) + io-event (1.9.0) + jekyll (4.3.4) + addressable (~> 2.4) + colorator (~> 1.0) + em-websocket (~> 0.5) + i18n (~> 1.0) + jekyll-sass-converter (>= 2.0, < 4.0) + jekyll-watch (~> 2.0) + kramdown (~> 2.3, >= 2.3.1) + kramdown-parser-gfm (~> 1.0) + liquid (~> 4.0) + mercenary (>= 0.3.6, < 0.5) + pathutil (~> 0.9) + rouge (>= 3.0, < 5.0) + safe_yaml (~> 1.0) + terminal-table (>= 1.8, < 4.0) + webrick (~> 1.7) + jekyll-relative-links (0.7.0) + jekyll (>= 3.3, < 5.0) + jekyll-sass-converter (3.0.0) + sass-embedded (~> 1.54) + jekyll-seo-tag (2.8.0) + jekyll (>= 3.8, < 5.0) + jekyll-watch (2.2.1) + listen (~> 3.0) + json (2.10.1) + kramdown (2.4.0) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liquid (4.0.4) + listen (3.9.0) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + mercenary (0.4.0) + method_source (1.1.0) + metrics (0.12.1) + mini_mime (1.1.5) + multi_xml (0.7.1) + bigdecimal (~> 3.1) + nokogiri (1.18.3-x86_64-linux-gnu) + racc (~> 1.4) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + pdf-reader (2.14.1) + Ascii85 (>= 1.0, < 3.0, != 2.0.0) + afm (~> 0.2.1) + hashery (~> 2.0) + ruby-rc4 + ttfunk + pry (0.14.2) + coderay (~> 1.1) + method_source (~> 1.0) + public_suffix (6.0.1) + racc (1.8.1) + rack (3.1.8) + rainbow (3.1.1) + rake (13.2.1) + rb-fsevent (0.11.2) + rb-inotify (0.11.1) + ffi (~> 1.0) + rexml (3.3.9) + rouge (4.5.1) + ruby-rc4 (0.1.5) + safe_yaml (1.0.5) + sass-embedded (1.81.0-x86_64-linux-gnu) + google-protobuf (~> 4.28) + siteleaf (2.3.0) + httparty (>= 0.16.0) + jekyll (>= 1.4.1) + rack + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) + traces (0.15.2) + ttfunk (1.8.0) + bigdecimal (~> 3.1) + typhoeus (1.4.1) + ethon (>= 0.9.0) + unicode-display_width (2.6.0) + webrick (1.9.0) + yell (2.2.2) + zeitwerk (2.7.2) + +PLATFORMS + x86_64-linux + +DEPENDENCIES + graal-languages-jekyll-theme + html-proofer + http_parser.rb (~> 0.6.0) + jekyll (~> 4.3.4) + jekyll-relative-links + jekyll-seo-tag + pry + siteleaf + tzinfo (>= 1, < 3) + tzinfo-data + wdm (~> 0.1) + +BUNDLED WITH + 2.5.9 diff --git a/docs/site/_config.yml b/docs/site/_config.yml new file mode 100644 index 0000000000..645b2f75c2 --- /dev/null +++ b/docs/site/_config.yml @@ -0,0 +1,21 @@ +baseurl: "/python" +url: "https://graalvm.org/" +github: "oracle/graalpython" +language_version: 24.2.0 +name: GraalPy + +permalink: pretty + +plugins: + - jekyll-relative-links + - jekyll-seo-tag + - graal-languages-jekyll-theme + +theme: graal-languages-jekyll-theme + +sass: + quiet_deps: true + +exclude: + - Gemfile + - Gemfile.lock diff --git a/docs/site/_plugins/graalpy_wheels.txt b/docs/site/_plugins/graalpy_wheels.txt new file mode 100644 index 0000000000..8136d81c2e --- /dev/null +++ b/docs/site/_plugins/graalpy_wheels.txt @@ -0,0 +1,54 @@ +# This file is processed by _plugins/wheel_repo_plugin.rb +# Each line is a wheel filename. Comments and empty lines are ignored +# GraalPy 24.1: +contourpy-1.2.1-graalpy311-graalpy241_311_native-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl +httptools-0.6.1-graalpy311-graalpy241_311_native-macosx_11_0_arm64.whl +httptools-0.6.1-graalpy311-graalpy241_311_native-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl +httptools-0.6.1-graalpy311-graalpy241_311_native-win_amd64.whl +jiter-0.5.0-graalpy311-graalpy241_311_native-manylinux_2_28_x86_64.whl +kiwisolver-1.4.5-graalpy311-graalpy241_311_native-macosx_11_0_arm64.whl +kiwisolver-1.4.5-graalpy311-graalpy241_311_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl +kiwisolver-1.4.5-graalpy311-graalpy241_311_native-win_amd64.whl +numpy-1.26.4-graalpy311-graalpy241_311_native-macosx_11_0_arm64.whl +numpy-1.26.4-graalpy311-graalpy241_311_native-manylinux_2_28_x86_64.whl +numpy-1.26.4-graalpy311-graalpy241_311_native-win_amd64.whl +oracledb-2.2.1-graalpy311-graalpy241_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl +psutil-5.9.8-graalpy311-graalpy241_311_native-macosx_11_0_arm64.whl +psutil-5.9.8-graalpy311-graalpy241_311_native-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_28_x86_64.whl +psutil-5.9.8-graalpy311-graalpy241_311_native-win_amd64.whl +pydantic_core-2.10.1-graalpy311-graalpy241_311_native-manylinux_2_28_x86_64.whl +ujson-5.10.0-graalpy311-graalpy241_311_native-macosx_11_0_arm64.whl +ujson-5.10.0-graalpy311-graalpy241_311_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl +ujson-5.10.0-graalpy311-graalpy241_311_native-win_amd64.whl +uvloop-0.19.0-graalpy311-graalpy241_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl +watchfiles-0.21.0-graalpy311-graalpy241_311_native-manylinux_2_28_x86_64.whl +xxhash-3.4.1-graalpy311-graalpy241_311_native-macosx_11_0_arm64.whl +xxhash-3.4.1-graalpy311-graalpy241_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl +xxhash-3.4.1-graalpy311-graalpy241_311_native-win_amd64.whl + +# GraalPy 24.2 +contourpy-1.2.1-graalpy311-graalpy242_311_native-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl +httptools-0.6.1-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl +httptools-0.6.1-graalpy311-graalpy242_311_native-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl +httptools-0.6.1-graalpy311-graalpy242_311_native-win_amd64.whl +jiter-0.5.0-graalpy311-graalpy242_311_native-manylinux_2_28_x86_64.whl +kiwisolver-1.4.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl +kiwisolver-1.4.5-graalpy311-graalpy242_311_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl +kiwisolver-1.4.5-graalpy311-graalpy242_311_native-win_amd64.whl +numpy-1.26.4-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl +numpy-1.26.4-graalpy311-graalpy242_311_native-manylinux_2_28_x86_64.whl +numpy-1.26.4-graalpy311-graalpy242_311_native-win_amd64.whl +oracledb-3.0.0-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl +polyleven-0.8-graalpy311-graalpy242_311_native-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl +psutil-5.9.8-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl +psutil-5.9.8-graalpy311-graalpy242_311_native-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_28_x86_64.whl +psutil-5.9.8-graalpy311-graalpy242_311_native-win_amd64.whl +pydantic_core-2.10.1-graalpy311-graalpy242_311_native-manylinux_2_28_x86_64.whl +ujson-5.10.0-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl +ujson-5.10.0-graalpy311-graalpy242_311_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl +ujson-5.10.0-graalpy311-graalpy242_311_native-win_amd64.whl +uvloop-0.19.0-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl +watchfiles-0.21.0-graalpy311-graalpy242_311_native-manylinux_2_28_x86_64.whl +xxhash-3.4.1-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl +xxhash-3.4.1-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl +xxhash-3.4.1-graalpy311-graalpy242_311_native-win_amd64.whl diff --git a/docs/site/_plugins/wheel_repo_plugin.rb b/docs/site/_plugins/wheel_repo_plugin.rb new file mode 100644 index 0000000000..05a0a70ce6 --- /dev/null +++ b/docs/site/_plugins/wheel_repo_plugin.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +# Plugin that generates a Python repository index for GraalPy wheels at +# /python/wheels. The input is the graalpy_wheels.txt file next to this file. +# The wheels themselves are hosted in GDS. +module WheelRepoPlugin + TEMPLATE = <<~EOF + + + + GraalPy wheel repository + + +
+      %{content}
+      
+ + + EOF + + Wheel = Struct.new(:name, :filename) + + class IndexGenerator < Jekyll::Generator + safe true + + def generate(site) + index_path = File.join(__dir__, "graalpy_wheels.txt") + all_wheels = File.readlines(index_path).select do |line| + !line.strip.empty? && !line.start_with?("#") + end.collect do |line| + if /([^-]+)-([^-]+)-.*\.whl/ =~ line + Wheel.new($1.downcase.gsub(/[-_.]+/, "-"), line.strip) + else + raise "Invalid wheel name in #{index_path}: #{line.inspect}" + end + end + wheels_by_name = all_wheels.group_by(&:name) + index_links = wheels_by_name.keys.map do |name| + "#{name}" + end + index_page = Jekyll::PageWithoutAFile.new(site, "", "/wheels", "index.html") + index_page.content = render index_links + site.pages << index_page + + wheels_by_name.each do |name, wheels| + package_links = wheels.collect do |wheel| + "#{wheel.filename}" + end + package_page = Jekyll::PageWithoutAFile.new(site, "", "/wheels/#{name}", "index.html") + package_page.content = render package_links + site.pages << package_page + end + end + + def render(links) + TEMPLATE % { content: links.join("\n") } + end + end +end diff --git a/docs/site/assets/img/python/devoxx2024-cover.png b/docs/site/assets/img/python/devoxx2024-cover.png new file mode 100644 index 0000000000..c3980a6d39 Binary files /dev/null and b/docs/site/assets/img/python/devoxx2024-cover.png differ diff --git a/docs/site/assets/img/python/jfocus2025-cover.png b/docs/site/assets/img/python/jfocus2025-cover.png new file mode 100644 index 0000000000..50d98b313f Binary files /dev/null and b/docs/site/assets/img/python/jfocus2025-cover.png differ diff --git a/docs/site/assets/js/check_compatibility_helpers.js b/docs/site/assets/js/check_compatibility_helpers.js new file mode 100644 index 0000000000..2cb2384b76 --- /dev/null +++ b/docs/site/assets/js/check_compatibility_helpers.js @@ -0,0 +1,280 @@ +class RequestedModule { + constructor(name, version) { + this.name = name; + this.version = Utilities.normalize_version(version); + } +} + +class ModuleListing { + constructor(name, contents) { + this.name = name; + this.contents = contents; + } +} + +class DBEntry { + constructor([library_name, library_version, test_status, pass_percentage]) { + this.name = library_name; + this.version = Utilities.normalize_version(library_version); + this.test_status = parseInt(test_status); + this.pass_percentage = pass_percentage; + } +} + +class DB { + constructor(language, db_contents) { + this.db = {}; + this.language = language; + + const lines = db_contents.split('\n'); + + for (let l in lines) { + const entry = new DBEntry(lines[l].split(',')); + + if (!(entry.name in this.db)) { + this.db[entry.name] = {}; + } + + this.db[entry.name][entry.version] = entry; + this.db[entry.name][Utilities.approximate_recommendation(entry.version)] = entry; + } + } + + lookup(requested_name, requested_version, print_missing) { + const ret = []; + + if (requested_name in this.db) { + if (requested_version === undefined) { + const versions = this.db[requested_name]; + for (let version in versions) { + if (!version.startsWith('~')) { + const entry = versions[version]; + ret.push([entry.name, version, entry.test_status, entry.pass_percentage]); + } + } + } else { + if (requested_version in this.db[requested_name]) { + const entry = this.db[requested_name][requested_version]; + ret.push([entry.name, entry.version, entry.test_status, entry.pass_percentage]); + } else { + const semver_match = Utilities.approximate_recommendation(requested_version); + if (semver_match in this.db[requested_name]) { + const entry = this.db[requested_name][semver_match]; + ret.push([entry.name, entry.version, entry.test_status, entry.pass_percentage]); + } else { + ret.push([requested_name, requested_version, 'unknown', undefined]); + } + } + } + } else { + if (print_missing) { + ret.push([requested_name, '*', 'library not yet tested', undefined]); + } + } + + // In the event of multiple versions for a module, sort the results from highest version to lowest. + ret.sort(function(a, b) { + return b[1].localeCompare(a[1]); + }); + + return ret; + } + + lookup_module(module, print_missing) { + return this.lookup(module.name, module.version, print_missing); + } + +} + +class Utilities { + static pretty_name(language) { + switch(language) { + case 'js': return 'GraalVM JavaScript'; + case 'r': return 'GraalVM R'; + case 'ruby': return 'GraalVM Ruby'; + case 'python': return 'GraalVM Python'; + } + } + + static normalize_version(version) { + if (version === undefined) { + return undefined; + } else { + return version.replace(/^v(\d.*)/, '$1'); + } + } + + static version_segments(version) { + if (version === undefined) { + return undefined; + } + + const string_parts = version.match(/[0-9]+|[a-z]+/ig); + + // The result of the regexp match will be an array of strings. We would like to be + // able to perform numeric comparisons on the parts corresponding to integer values, + // so convert them here. + return string_parts.map(function(e) { + let x = parseInt(e); + + if (isNaN(x)) { + return e; + } else { + return x; + } + }); + } + + static approximate_recommendation(version) { + if (version === undefined) { + return undefined; + } + + const segments = this.version_segments(version); + + while (segments.some(function(e) { typeof(e) === 'string' })) { + segments.pop(); + } + + while (segments.length > 2) { + segments.pop(); + } + + while (segments.length < 2) { + segments.push(0); + } + + return `~> ${segments.join('.')}` + } +} + +class DependencyFileProcessor { + static handle_gemfile(db, contents) { + if (db.language !== 'ruby') { + return []; + } + + const r = /\n (\S+?) \((.+?)\)/g; + let match; + const queries = []; + + while (match = r.exec(contents)) { + queries.push(match.slice(1, 3)); + } + + queries.sort(function(a, b) { + return a[0].localeCompare(b[0]); + }); + + let results = []; + for (let [name, version] of queries) { + results = results.concat(db.lookup(name, version, true)); + } + + return results; + } + + static handle_package_json(db, contents) { + if (db.language !== 'js') { + return []; + } + + const json = JSON.parse(contents); + let queries = []; + + for (let name in json['dependencies']) { + queries.push([name, undefined]); + } + + let results = []; + for (let [name, version] of queries) { + results = results.concat(db.lookup(name, version, true)); + } + + return results; + } + + static handle_package_lock(db, contents) { + if (db.language !== 'js') { + return []; + } + + const json = JSON.parse(contents); + let queries = [[json['name'], json['version']]]; + + for (let name in json['dependencies']) { + let metadata = json['dependencies'][name]; + + if (metadata['dev'] || metadata['optional']) { + continue; + } + + queries.push([name, metadata['version']]); + } + + let results = []; + for (let [name, version] of queries) { + results = results.concat(db.lookup(name, version, true)); + } + + return results; + } + + static handle_yarn_lock(db, contents) { + if (db.language != 'js') { + return []; + } + + const r = /\n(\w.*?)@.+?:\s+?version "(.+?)"/g; + let match; + const queries = []; + + while (match = r.exec(contents)) { + queries.push(match.slice(1, 3)); + } + + queries.sort(function(a, b) { + return a[0].localeCompare(b[0]); + }); + + let results = []; + for (let [name, version] of queries) { + results = results.concat(db.lookup(name, version, true)); + } + + return results; + } + + static handle_packrat_lock(db, contents) { + if (db.language != 'r') { + return []; + } + + const r = /\nPackage: (\w+)\nSource: (\w+)\nVersion: (.+?)\n/g; + let match; + const queries = []; + + while (match = r.exec(contents)) { + queries.push(match.slice(1, 4)); + } + + queries.sort(function(a, b) { + return a[0].localeCompare(b[0]); + }); + + let results = []; + for (let [name, repository, version] of queries) { + results = results.concat(db.lookup(name, version, true)); + } + + return results; + } +} + +if (typeof module !== 'undefined') { + module.exports.DB = DB; + module.exports.DependencyFileProcessor = DependencyFileProcessor; + module.exports.ModuleListing = ModuleListing; + module.exports.RequestedModule = RequestedModule; + module.exports.Utilities = Utilities; +} diff --git a/docs/site/assets/logo.svg b/docs/site/assets/logo.svg new file mode 100644 index 0000000000..4b73a0e933 --- /dev/null +++ b/docs/site/assets/logo.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/docs/site/index.md b/docs/site/index.md new file mode 100644 index 0000000000..b544cbd82c --- /dev/null +++ b/docs/site/index.md @@ -0,0 +1,387 @@ +--- +layout: base +--- +
+
+
+
+
+
+

A high-performance embeddable Python 3 runtime for Java

+ +
+
+ Python icon +
+
+
+
+
+
+ + +
+
+
+
+

Benefits

+
+
+
+ access icon +
+
+

Python for Java

+
+ +
+
+
+ compatibility icon +
+
+

Python 3 Compatible

+
+
+
Compatible with many Python packages, including popular AI and Data Science libraries
+
+
+
+
+ speed icon +
+
+

Fastest Python on the JVM

+
+
+
Graal JIT compiles Python for native code speed
+
+
+
+
+
+
+ upgrade icon +
+
+

Modern Python for the JVM

+
+
+
GraalPy provides an upgrade path for Jython users
+
+
+
+
+ code icon +
+
+

Script Java with Python

+
+
+
Extend applications with Python scripts that interact with Java
+
+
+
+
+ binary icon +
+
+

Simple distribution

+
+
+
Package Python applications as a single binary with GraalVM Native Image
+
+
+
+
+
+
+
+ + +
+
+
+
+

How to Get Started

+
+
You have the option to extend your Java application with Python, or go straight to the starter project
+
+
+
+

1. Add GraalPy as a dependency from Maven Central

+
+
+
+
+

1. Add GraalPy as a dependency from Maven Central

+
+ {%- highlight xml -%} + + org.graalvm.polyglot + polyglot + {{ site.language_version }} + + + org.graalvm.polyglot + python + {{ site.language_version }} + pom + + {%- endhighlight -%} +
+
+ +
+
+
+
+
+

or

+
+ {%- highlight groovy -%} +implementation("org.graalvm.polyglot:polyglot:{{ site.language_version }}") +implementation("org.graalvm.polyglot:python:{{ site.language_version }}") + {%- endhighlight -%} +
+
+ +
+
+
+

2. Embed Python code in Java

+
+
+
+
+

2. Embed Python code in Java

+
+ {%- highlight java -%} +import org.graalvm.polyglot.Context; + +try (Context context = Context.create()) { + context.eval("python", "print('Hello from GraalPy!')"); +} + {%- endhighlight -%} +
+
+ +
+
+
+

3. Add GraalPy plugins for additional Python packages (optional)

+
+
+
+
+

3. Add GraalPy plugins for additional Python packages (optional)

+
+ {%- highlight xml -%} + + org.graalvm.python + graalpy-maven-plugin + {{ site.language_version }} + + + + + + pyfiglet==1.0.2 + + + + process-graalpy-resources + + + + + {%- endhighlight -%} +
+
+ +
+
+
+
+
+

or

+
+ {%- highlight groovy -%} +plugins { + id("org.graalvm.python") version "{{ site.language_version }}" +} + +graalPy { + packages = setOf("pyfiglet==1.0.2") +} + {%- endhighlight -%} +
+
+ +
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+
+
+

Videos

+
+ +
+
+

Supercharge your Java Applications with Python!
Jfokus'25

+
+
+
Projects such as LangChain4j, Spring AI, and llama3.java got the Java community very excited about AI in the last year. + The Python ecosystem also provides many powerful packages for data science, machine learning, and more. + Wouldn't it be cool if you, as a Java developer, could benefit from this, too? +
+ In this talk, we show how you can get started with GraalPy and use packages from the Python ecosystem. + We also show some live demos and preview upcoming features that will improve the interaction between Java and native extensions that ship with popular Python packages. +
+
+
+
+
+ +
+
+

Supercharge your Java Applications with Python!
Devoxx'24

+
+
+
The Python ecosystem provides many powerful packages for data science, machine learning, and more, that you can now leverage in Java. + Get started by adding GraalPy as a dependency to your Java project. + There are also Maven and Gradle plugins for GraalPy that help you install additional Python packages. + In this presentation, we also show live demos that illustrate different use cases, such as a Spring Boot application that visualizes data with Python, Python running on JBang!, a Java application scripted with Python, and more. +
+
+
+
+
+
+
+
diff --git a/docs/site/module_results/python-module-testing-v241.csv b/docs/site/module_results/python-module-testing-v241.csv new file mode 100644 index 0000000000..76fba74795 --- /dev/null +++ b/docs/site/module_results/python-module-testing-v241.csv @@ -0,0 +1,689 @@ +absl-py,1.3.0,0,99.25 +aif360,0.5.0,2,0.00 +aiodns,3.0.0,1,33.33 +aiofiles,22.1.0,0,98.99 +aiohttp,3.8.3,0,94.55 +aiohttp_cors,0.7.0,0,97.98 +aioredis,2.0.1,2,0.00 +aiorwlock,1.3.0,0,97.78 +aiosignal,1.3.1,0,100.00 +alembic,1.8.1,0,99.64 +aliyun-python-sdk-core,2.13.36,0,90.22 +altair,4.2.2,0,100.00 +ansible-core,2.14.2,1,0.00 +anyio,3.7.0,1,0.00 +appdirs,1.4.4,0,100.00 +APScheduler,3.9.1.post1,1,0.00 +argcomplete,2.0.0,0,100.00 +arrow,1.2.3,0,99.95 +asgiref,3.5.2,0,98.46 +asn1crypto,1.5.1,0,99.87 +astor,0.8.1,0,94.55 +astroid,2.12.13,1,0.00 +astropy,5.2.1,2,0.00 +asttokens,2.2.1,0,82.76 +asttokens,2.4.1,0,96.55 +astunparse,1.6.3,1,60.64 +async-timeout,4.0.2,0,100.00 +async_generator,1.10,0,88.37 +asyncpg,0.27.0,1,0.00 +atomicwrites,1.4.1,0,100.00 +attrs,22.1.0,0,96.04 +autoflake,2.0.0,0,100.00 +autopep8,2.0.1,1,0.00 +autopep8,2.3.1,0,99.65 +awscli,1.27.23,0,99.96 +azure-common,1.1.28,0,100.00 +azure-identity,1.12.0,0,97.45 +azure-storage-blob,12.14.1,2,0.00 +azure-storage-blob,12.18.3,1,0.00 +Babel,2.11.0,0,99.60 +backcall,0.2.0,0,100.00 +backoff,2.2.1,0,97.48 +bandit,1.7.4,1,0.00 +base58,2.1.1,0,100.00 +bcrypt,4.0.1,0,100.00 +bcrypt,4.2.0,0,100.00 +beautifulsoup4,4.11.1,0,99.81 +biopython,1.80,1,0.00 +black,22.10.0,1,44.19 +black,24.2.0,1,53.81 +bleach,5.0.0,0,100.00 +blessed,1.20.0,1,0.00 +blessings,1.7,1,0.00 +blinker,1.5,0,78.57 +blis,0.9.1,2,0.00 +bokeh,3.0.2,2,0.00 +boto3,1.26.23,1,66.01 +boto3,1.34.116,0,93.91 +botocore,1.29.23,1,0.00 +bottle,0.12.23,0,100.00 +build,0.9.0,0,95.65 +bump2version,1.0.1,0,97.63 +CacheControl,0.12.11,1,0.00 +cached-property,1.5.2,2,0.00 +cachetools,5.2.0,0,99.52 +catalogue,2.0.8,0,100.00 +catboost,1.2.2,2,0.00 +category-encoders,2.5.1.post0,1,0.00 +category-encoders,2.6.3,1,0.00 +cchardet,2.1.7,2,0.00 +celery,5.2.7,2,0.00 +celery,5.3.6,2,0.00 +Cerberus,1.3.4,0,100.00 +certifi,2022.9.24,0,100.00 +cffi,1.15.1,1,0.00 +chardet,5.1.0,0,100.00 +charset-normalizer,3.0.1,0,81.68 +charset-normalizer,3.3.2,0,79.56 +check-manifest,0.49,0,100.00 +circuitbreaker,2.0.0,0,100.00 +click,8.1.3,0,100.00 +cliff,4.3.0,1,0.00 +cloudpickle,2.2.1,0,98.85 +cmaes,0.9.1,1,0.00 +cmd2,2.4.3,1,0.00 +codecov,2.1.12,0,100.00 +colorama,0.4.6,0,100.00 +coloredlogs,15.0.1,1,0.00 +colorful,0.5.5,0,99.65 +colorlog,6.7.0,0,100.00 +commonmark,0.9.1,0,100.00 +ConfigArgParse,1.5.3,0,100.00 +configobj,5.0.6,0,100.00 +configparser,5.3.0,0,95.79 +confluent-kafka,2.0.2,1,0.00 +cookiecutter,2.1.1,0,99.68 +coverage,6.5.0,1,0.00 +coveralls,3.3.1,1,0.00 +cryptography,3.4.7,0,99.90 +cryptography,42.0.5,0,99.23 +cryptography,43.0.0,0,99.24 +cssselect,1.2.0,0,100.00 +cycler,0.11.0,0,100.00 +cymem,2.0.7,2,0.00 +Cython,0.29.32,1,0.00 +dask,2022.12.0,1,0.00 +dataclasses-json,0.5.7,0,99.57 +datasets,2.10.0,1,69.88 +datasets,2.18.0,1,0.00 +dateparser,1.1.4,0,99.98 +DateTime,4.7,2,0.00 +DAWG-Python,0.7.2,2,0.00 +debugpy,1.6.7,1,0.00 +decorator,5.1.1,0,100.00 +deepdiff,6.2.1,2,0.00 +defusedxml,0.7.1,0,95.06 +Deprecated,1.2.13,0,88.68 +dice-ml,0.9,2,0.00 +dill,0.3.6,1,0.00 +discord.py,2.1.0,1,0.00 +distlib,0.3.6,0,77.02 +distributed,2022.12.0,2,0.00 +distro,1.8.0,0,100.00 +Django,4.1.4,2,0.00 +django-filter,22.1,0,93.11 +django-model-utils,4.3.1,0,99.40 +djangorestframework,3.14.0,1,29.40 +dnspython,2.2.1,0,95.61 +docker,6.0.1,0,99.83 +docopt,0.6.2,0,100.00 +docutils,0.19,0,99.81 +dohq-artifactory,0.8.4,0,96.39 +ecdsa,0.18.0,1,0.00 +einops,0.6.0,2,0.00 +elasticsearch,8.13.0,0,94.04 +elasticsearch,8.5.2,2,0.00 +email-validator,1.3.1,0,100.00 +emoji,2.2.0,0,97.37 +entrypoints,0.4,0,100.00 +eventlet,0.33.3,1,0.00 +execnet,1.9.0,2,0.00 +executing,1.2.0,1,43.33 +faiss,1.5.3,2,0.00 +fake-useragent,1.1.1,0,100.00 +Faker,15.3.4,0,99.46 +fastapi,0.88.0,1,0.00 +feedparser,6.0.10,1,0.00 +filelock,3.8.2,0,100.00 +Fiona,1.9.1,1,0.00 +fiona,1.9.1,1,0.00 +fire,0.4.0,2,0.00 +fire,0.6.0,0,99.63 +flake8,6.0.0,0,99.13 +flake8-bandit,4.1.1,0,88.89 +flake8-bugbear,23.2.13,0,94.23 +flake8-comprehensions,3.11.1,0,99.22 +flake8-polyfill,1.0.2,2,0.00 +Flask,2.2.2,0,100.00 +Flask-Cors,3.0.10,0,100.00 +Flask-Login,0.6.2,0,100.00 +Flask-OpenTracing,1.1.0,0,93.75 +Flask-RESTful,0.3.9,0,99.06 +Flask-SQLAlchemy,3.0.3,0,100.00 +Flask-WTF,1.0.1,0,96.08 +flatbuffers,23.5.26,2,0.00 +fonttools,4.38.0,2,0.00 +fpdf2,2.7.4,1,0.00 +freezegun,1.2.1,0,99.19 +frozenlist,1.3.3,2,0.00 +fsspec,2022.11.0,0,88.27 +fsspec,2023.12.2,0,75.76 +fsspec,2024.2.0,0,97.15 +future,0.18.2,1,0.00 +fuzzywuzzy,0.18.0,0,98.59 +gast,0.5.4,0,97.87 +GDAL,3.6.1,1,0.06 +gensim,4.2.0,2,0.00 +geojson,3.0.0,2,0.00 +geojson,3.1.0,0,100.00 +geopandas,0.12.1,0,96.43 +geopy,2.3.0,1,0.00 +gevent,22.10.2,1,0.00 +gitdb,4.0.10,0,100.00 +gitdb2,4.0.2,0,80.00 +GitPython,3.1.29,0,99.34 +google-api-core,2.11.0,2,0.00 +google-api-python-client,2.68.0,0,99.67 +google-auth,2.15.0,2,0.00 +google-auth-httplib2,0.1.0,0,100.00 +google-auth-oauthlib,1.0.0,2,0.00 +google-cloud-bigquery,3.4.0,2,0.00 +google-cloud-storage,2.6.0,0,100.00 +google-pasta,0.2.0,0,78.24 +googleapis-common-protos,1.57.0,2,0.00 +gpustat,1.1,2,0.00 +graphviz,0.20.1,2,0.00 +graphviz,0.20.3,0,99.73 +greenlet,2.0.1,1,0.00 +grpcio,1.51.1,1,0.00 +grpcio,1.60.0,1,0.00 +grpcio-tools,1.51.1,2,0.00 +grpcio-tools,1.60.0,2,0.00 +gssapi,1.8.2,2,0.00 +gunicorn,20.1.0,1,0.00 +gym,0.26.2,2,0.00 +h11,0.14.0,0,100.00 +h5py,3.10.0,0,98.64 +horovod,0.28.1,1,53.59 +html2text,2020.1.16,0,100.00 +html5lib,1.1,0,99.99 +httplib2,0.21.0,1,0.00 +httplib2,0.22.0,0,99.60 +httpx,0.23.1,1,0.00 +huggingface-hub,0.15.1,2,0.00 +humanfriendly,10.0,1,27.78 +humanize,4.4.0,0,100.00 +hvac,1.1.1,1,47.56 +hypothesis,6.60.0,1,0.00 +idna,3.4,0,100.00 +imageio,2.22.4,0,85.79 +imbalanced-learn,0.10.0,2,0.00 +implicit,0.7.2,0,97.48 +importlib-metadata,5.1.0,0,100.00 +importlib-resources,5.10.1,0,88.81 +inflection,0.5.1,0,100.00 +iniconfig,2.0.0,0,100.00 +invoke,1.7.3,2,0.00 +ipaddress,1.0.23,2,0.00 +ipdb,0.13.9,0,100.00 +ipykernel,6.17.1,1,0.00 +ipython,8.7.0,1,0.00 +ipywidgets,8.0.3,0,91.23 +iso8601,1.1.0,0,100.00 +isodate,0.6.1,0,100.00 +isort,5.10.1,0,98.65 +itsdangerous,2.1.2,0,100.00 +jaeger-client,4.8.0,2,0.00 +jax,0.4.13,2,0.00 +jedi,0.18.2,1,0.00 +jeepney,0.8.0,2,0.00 +jieba,0.42.1,0,100.00 +Jinja2,3.1.2,0,99.76 +jmespath,1.0.1,0,100.00 +joblib,1.2.0,0,84.36 +jsii,1.72.0,2,0.00 +json5,0.9.14,0,100.00 +jsonpickle,3.0.0,1,0.00 +jsonschema,4.17.3,1,0.00 +jupyter-client,7.4.8,1,0.00 +jupyter-core,5.2.0,0,100.00 +jupyterlab,3.5.1,1,0.00 +kafka-python,2.0.2,0,91.89 +kazoo,2.9.0,2,0.00 +keras,2.14.0,2,0.00 +Keras-Preprocessing,1.1.2,1,56.67 +keyboard,0.13.5,0,99.36 +keyring,23.11.0,0,80.26 +keyring,25.2.1,0,99.65 +kiwisolver,1.4.4,0,100.00 +krb5,0.5.0,0,100.00 +kubernetes,25.3.0,0,99.62 +lark-parser,0.12.0,2,0.00 +lazy-object-proxy,1.8.0,0,96.87 +libclang,16.0.0,2,0.00 +librosa,0.9.2,2,0.00 +lightfm,1.17,2,0.00 +lightgbm,3.3.3,0,99.28 +lightgbm,4.3.0,2,0.00 +livereload,2.6.3,2,0.00 +lizard,1.17.10,1,0.00 +llvmlite,0.40.1,2,0.00 +llvmlite,0.40.2,2,0.00 +llvmlite,0.42.0,1,0.00 +loguru,0.6.0,2,0.00 +loguru,0.7.2,2,0.00 +logzero,1.7.0,1,0.00 +lxml,4.9.1,0,94.24 +lxml,5.3.0,1,0.00 +m2r2,0.3.3,0,100.00 +Mako,1.2.4,0,100.00 +Markdown,3.4.1,0,100.00 +MarkupSafe,2.1.1,0,100.00 +marshmallow,3.19.0,0,100.00 +matplotlib,3.7.0,0,99.62 +matplotlib-inline,0.1.6,2,0.00 +mccabe,0.7.0,0,93.75 +memory-profiler,0.61.0,2,0.00 +mistune,2.0.4,0,100.00 +mkdocs,1.4.2,0,100.00 +mkdocstrings,0.19.0,1,0.00 +mlflow,2.0.1,2,0.00 +mock,4.0.3,1,0.00 +more-itertools,9.0.0,1,0.00 +moto,4.1.2,1,7.18 +moviepy,1.0.3,0,84.55 +msgpack,1.0.4,1,0.00 +msrest,0.7.1,1,0.00 +multidict,6.0.3,1,72.08 +multiprocess,0.70.14,2,0.00 +murmurhash,1.0.9,2,0.00 +mypy,0.991,0,96.62 +mypy-extensions,0.4.3,0,85.71 +mypy-extensions,1.0.0,0,100.00 +mysql-connector-python,8.0.31,1,0.00 +mysqlclient,2.1.1,0,100.00 +myst-parser,0.18.1,0,95.94 +natsort,8.2.0,1,0.00 +nbconvert,7.2.6,0,97.66 +nbformat,5.7.0,0,100.00 +nest-asyncio,1.5.6,0,100.00 +netaddr,0.8.0,0,100.00 +netCDF4,1.6.2,0,91.35 +netifaces,0.11.0,0,100.00 +networkx,2.8.8,1,0.00 +nibabel,4.0.2,2,0.00 +nltk,3.7,1,0.00 +nltk,3.8.1,0,98.12 +notebook,6.5.2,1,39.17 +nox,2022.11.21,0,97.71 +numba,0.56.4,2,0.00 +numba,0.59.1,1,0.00 +numexpr,2.8.4,0,84.38 +numpy,1.23.5,0,88.55 +numpy,1.24.3,0,95.24 +numpydoc,1.5.0,0,99.59 +oauthlib,3.2.2,0,99.85 +oci,2.104.3,1,56.76 +onnx,1.12.0,2,0.00 +onnx,1.15.0,0,99.28 +onnx,1.16.0,2,0.00 +onnxmltools,1.11.1,1,0.00 +onnxruntime,1.14.1,0,79.10 +onnxruntime,1.17.1,0,98.31 +openai,0.27.4,0,80.70 +opencensus,0.11.2,2,0.00 +opencensus-context,0.1.3,2,0.00 +opencv-python,4.6.0.66,2,0.00 +opencv-python-headless,4.6.0.66,2,0.00 +openpyxl,3.0.10,0,99.55 +opentracing,2.4.0,2,0.00 +opt-einsum,3.3.0,0,99.91 +optree,0.12.1,1,0.00 +optuna,3.1.1,2,0.00 +optuna,3.2.0,0,98.30 +oracledb,1.3.2,0,99.82 +oracledb,2.2.1,0,83.76 +orbit-ml,1.1.4.2,2,0.00 +orjson,3.8.3,1,0.00 +orjson,3.9.7,1,0.17 +oslo.config,9.0.0,1,0.00 +oslo.utils,6.1.0,1,0.00 +packaging,21.3,0,100.00 +paho-mqtt,1.6.1,0,100.00 +pandas,1.5.2,0,86.84 +papermill,2.4.0,0,99.45 +paramiko,2.12.0,0,99.76 +parse,1.19.0,0,100.00 +parso,0.8.3,0,91.49 +pathlib2,2.3.7.post1,0,100.00 +pathos,0.3.0,1,0.00 +pathspec,0.10.2,0,100.00 +pathy,0.10.2,0,100.00 +patsy,0.5.3,0,98.65 +pbr,5.11.0,1,0.00 +peewee,3.15.4,0,100.00 +pendulum,2.1.2,0,99.83 +pep8-naming,0.13.2,0,100.00 +peppercorn,0.6,0,100.00 +pexpect,4.8.0,1,29.91 +phonenumbers,8.13.6,1,49.34 +pickleshare,0.7.5,0,100.00 +pika,1.3.1,0,83.57 +pillow,10.2.0,0,99.00 +pillow,10.3.0,0,99.03 +Pillow,9.3.0,0,98.15 +pillow,9.3.0,0,98.17 +Pint,0.20.1,0,99.09 +pip,22.3.1,1,58.47 +pip-tools,6.11.0,0,90.05 +pkginfo,1.9.2,0,100.00 +platformdirs,3.0.0,0,100.00 +plotly,5.11.0,1,0.00 +pluggy,1.0.0,0,100.00 +ply,3.11,0,90.91 +polyleven,0.8,0,100.00 +pre-commit,2.20.0,1,0.00 +preshed,3.0.8,2,0.00 +prettytable,3.5.0,0,100.00 +progress,1.6,0,100.00 +progressbar2,4.2.0,0,100.00 +prometheus-client,0.15.0,0,100.00 +prompt-toolkit,3.0.33,0,100.00 +prophet,1.1.4,0,100.00 +prophet,1.1.5,0,100.00 +protobuf,4.21.10,1,0.00 +psutil,5.9.4,0,76.03 +psutil,5.9.5,0,93.68 +psutil,5.9.8,1,0.00 +psycopg2,2.9.5,0,98.11 +psycopg2,2.9.9,0,98.25 +psycopg2-binary,2.9.9,0,98.11 +ptyprocess,0.7.0,1,14.29 +pure-eval,0.2.2,0,97.87 +py,1.11.0,0,91.22 +py-spy,0.3.14,2,0.00 +py4j,0.10.9.7,2,0.00 +pyaml,21.10.1,0,100.00 +pyarrow,12.0.0,0,98.15 +pyarrow,15.0.0,0,98.22 +pyasn1,0.4.8,0,97.90 +pyasn1-modules,0.2.8,0,100.00 +PyAudio,0.2.12,1,42.31 +PyAutoGUI,0.9.53,1,0.00 +pybind11,2.10.1,2,0.00 +pycodestyle,2.10.0,0,98.11 +pycparser,2.21,0,98.46 +pycryptodome,3.16.0,1,0.00 +pycryptodomex,3.16.0,1,0.00 +pydantic,1.10.2,1,0.00 +pydata-sphinx-theme,0.12.0,2,0.00 +pydicom,2.3.1,0,99.64 +pydocstyle,6.1.1,2,0.00 +pydot,1.4.2,0,93.75 +PyDriller,2.2,0,99.60 +pydub,0.25.1,1,0.00 +pyfiglet,0.8.post0,0,100.00 +pyflakes,3.0.1,0,99.45 +pygame,2.1.2,2,0.00 +PyGithub,1.57,0,100.00 +Pygments,2.13.0,0,100.00 +PyGObject,3.42.2,1,0.00 +PyJWT,2.6.0,1,0.00 +pylint,2.15.8,1,0.00 +pymdown-extensions,10.0.1,0,98.95 +pymongo,4.3.3,0,99.45 +pymorphy2,0.9.1,1,0.00 +pymorphy2-dicts-ru,2.4.417127.4579844,2,0.00 +PyNaCl,1.5.0,0,100.00 +pyod,1.0.6,1,0.00 +pyod,1.1.3,1,0.00 +pyodbc,4.0.35,1,0.00 +pyOpenSSL,22.1.0,1,0.00 +pypandoc,1.10,0,87.50 +pyparsing,3.0.9,0,100.00 +PyPDF2,2.11.2,2,0.00 +PyPDF2,3.0.0,2,0.00 +pyperclip,1.8.2,0,100.00 +pyproj,3.4.0,0,98.93 +pyqtgraph,0.13.1,1,0.00 +pyramid,2.0,0,99.89 +pyrsistent,0.19.2,0,100.00 +pysam,0.20.0,1,0.00 +pyserial,3.5,0,93.48 +PySide2,5.15.2.1,2,0.00 +PySocks,1.7.1,0,100.00 +pysolr,3.9.0,1,0.00 +pyspark,3.4.1,1,0.00 +pyspnego,0.9.1,0,99.70 +pytesseract,0.3.10,0,89.58 +pytest,7.2.0,0,97.45 +pytest,8.0.0,0,98.54 +pytest,8.3.2,0,98.57 +pytest-asyncio,0.20.3,1,0.00 +pytest-benchmark,4.0.0,0,94.14 +pytest-cov,4.0.0,1,62.50 +pytest-django,4.5.2,1,0.00 +pytest-django,4.8.0,0,79.40 +pytest-flake8,1.1.1,0,100.00 +pytest-forked,1.6.0,0,90.91 +pytest-mock,3.10.0,0,98.72 +pytest-mypy,0.10.2,0,84.21 +pytest-runner,6.0.0,1,44.44 +pytest-sugar,0.9.6,1,0.00 +pytest-sugar,1.0.0,0,83.00 +pytest-timeout,2.1.0,0,75.47 +pytest-xdist,3.1.0,0,93.30 +python-dateutil,2.8.2,0,98.71 +python-dotenv,0.21.0,0,93.10 +python-editor,1.0.4,2,0.00 +python-jose,3.3.0,0,99.79 +python-json-logger,2.0.4,0,100.00 +python-magic,0.4.27,0,95.00 +python-multipart,0.0.5,0,90.38 +python-slugify,7.0.0,0,98.77 +pytorch-lightning,1.8.3.post1,2,0.00 +pytorch-tabnet,4.0,1,0.00 +pytz,2022.6,0,100.00 +PyYAML,6.0,0,100.00 +pyzmq,24.0.1,0,98.04 +qrcode,7.3.1,0,98.63 +QtPy,2.3.0,2,0.00 +rasterio,1.3.4,2,0.00 +ray,2.3.0,2,0.00 +ray,2.9.1,2,0.00 +rdflib,6.2.0,1,0.00 +readme-renderer,37.3,0,87.67 +recommonmark,0.7.1,1,60.71 +redis,4.4.0,0,99.59 +regex,2022.10.31,0,99.01 +reportlab,3.6.12,1,0.00 +requests,2.28.1,0,99.49 +requests-cache,0.9.7,1,41.98 +requests-kerberos,0.14.0,0,100.00 +requests-mock,1.10.0,0,100.00 +requests-oauthlib,1.3.1,0,95.59 +requests-toolbelt,0.10.1,0,100.00 +responses,0.22.0,0,95.38 +retrying,1.3.4,0,100.00 +rfc3986,2.0.0,0,100.00 +rich,12.6.0,0,94.27 +robotframework,6.0.1,1,5.98 +rsa,4.9,0,98.85 +ruamel.yaml,0.17.21,0,99.76 +s3fs,2022.11.0,1,8.38 +s3transfer,0.10.1,1,49.39 +s3transfer,0.6.0,2,0.00 +sacremoses,0.0.53,2,0.00 +sanic,22.9.1,2,0.00 +sanic,23.12.1,1,0.00 +schedule,1.1.0,0,82.86 +schema,0.7.5,0,100.00 +scikit-image,0.19.3,2,0.00 +scikit-learn,1.1.3,1,65.03 +scikit-learn,1.2.2,0,85.12 +scipy,1.10.1,1,63.17 +Scrapy,2.7.1,1,0.00 +seaborn,0.12.1,1,65.38 +seaborn,0.13.2,1,0.00 +SecretStorage,3.3.3,1,26.92 +seldon-core,1.16.0,2,0.00 +selenium,4.20.0,2,0.00 +selenium,4.7.2,1,0.00 +semantic-version,2.10.0,0,100.00 +semver,2.13.0,1,50.00 +semver,3.0.2,0,100.00 +sentence-transformers,2.2.2,2,0.00 +sentencepiece,0.1.97,1,0.00 +sentry-sdk,1.15.0,0,87.63 +setproctitle,1.3.2,0,82.14 +setproctitle,1.3.3,0,82.14 +setuptools,65.5.0,0,89.31 +setuptools,65.6.3,2,0.00 +setuptools-scm,7.0.5,0,100.00 +setuptools-scm-git-archive,1.4,2,0.00 +sh,1.14.3,1,14.86 +shap,0.41.0,2,0.00 +shap,0.45.1,2,0.00 +shapely,2.0.0,0,99.97 +simplejson,3.18.0,0,100.00 +six,1.16.0,0,100.00 +skl2onnx,1.13,2,0.00 +skl2onnx,1.16,2,0.00 +sktime,0.19.1,2,0.00 +sktime,0.24.0,0,96.94 +slackclient,2.9.4,0,98.89 +slicer,0.0.7,2,0.00 +smart-open,6.3.0,2,0.00 +smart-open,7.0.4,1,0.00 +smmap,5.0.0,0,100.00 +smmap2,3.0.1,2,0.00 +sniffio,1.3.0,0,100.00 +snowballstemmer,2.2.0,2,0.00 +sortedcontainers,2.4.0,1,0.00 +soupsieve,2.3.2.post1,0,100.00 +spacy,3.4.3,2,0.00 +spacy-legacy,3.0.12,2,0.00 +spacy-lookups-data,1.0.3,2,0.00 +spacy-pkuseg,0.0.32,2,0.00 +Sphinx,5.3.0,1,47.80 +sphinx-autobuild,2021.3.14,0,100.00 +sphinx-autodoc-typehints,1.19.5,0,94.74 +sphinx-click,4.4.0,2,0.00 +sphinx-click,6.0.0,0,100.00 +sphinx-gallery,0.11.1,0,81.95 +sphinx-multiversion,0.2.4,0,100.00 +sphinx-rtd-theme,1.1.1,1,0.00 +sphinxcontrib-bibtex,2.5.0,2,0.00 +sphinxcontrib-bibtex,2.6.2,0,98.37 +SQLAlchemy,1.4.44,1,0.00 +SQLAlchemy,1.4.52,1,0.00 +SQLAlchemy-Utils,0.38.3,0,77.62 +sqlparse,0.4.3,0,100.00 +srsly,2.4.6,2,0.00 +stack-data,0.6.2,2,0.00 +starlette,0.23.0,1,0.00 +statsmodels,0.13.5,1,0.00 +statsmodels,0.14.0,1,0.00 +statsmodels,0.14.1,1,0.00 +stevedore,4.1.1,1,0.00 +streamlit,1.15.2,2,0.00 +structlog,22.3.0,0,96.26 +sympy,1.11.1,1,0.00 +tables,3.7.0,2,0.00 +tabulate,0.9.0,0,99.33 +tenacity,8.1.0,0,99.07 +tensorboard,2.11.0,2,0.00 +tensorboard-data-server,0.7.1,2,0.00 +tensorboard-plugin-wit,1.8.1,2,0.00 +tensorboardX,2.6.1,1,0.00 +tensorflow,2.15.0,1,0.00 +tensorflow-estimator,2.12.0,2,0.00 +tensorflow-gpu,2.11.0,2,0.00 +tensorflow-io-gcs-filesystem,0.32.0,2,0.00 +tensorflow-probability,0.19.0,2,0.00 +termcolor,2.1.1,0,100.00 +terminaltables,3.1.10,0,90.76 +testbook,0.4.2,0,100.00 +thinc,8.1.10,1,43.84 +threadloop,1.0.2,2,0.00 +threadpoolctl,3.1.0,0,100.00 +thrift,0.16.0,2,0.00 +tifffile,2022.10.10,2,0.00 +tinydb,4.7.0,0,100.00 +tldextract,3.4.0,1,0.00 +tokenizers,0.13.3,2,0.00 +toml,0.10.2,0,91.30 +tomli,2.0.1,0,100.00 +tomlkit,0.11.6,0,99.76 +toolz,0.12.0,0,97.06 +torch,1.13.1,0,98.14 +torch,2.2.1,2,11.56 +torchvision,0.14.1,1,0.00 +torchvision,0.17.1,0,98.20 +tornado,6.2,0,98.05 +tox,3.27.1,0,90.14 +tqdm,4.64.1,1,0.00 +tqdm,4.66.4,0,98.01 +traitlets,5.6.0,0,99.82 +transformers,4.33.3,2,0.00 +trio,0.22.0,1,0.00 +twine,4.0.2,0,96.11 +Twisted,22.10.0,2,0.00 +typed-ast,1.5.4,1,0.00 +typeguard,2.13.3,1,74.49 +typer,0.7.0,1,0.00 +types-pytz,2022.6.0.1,0,85.71 +types-PyYAML,6.0.12.2,0,85.71 +types-requests,2.28.11.5,1,71.43 +types-requests,2.31.0.20240311,2,0.00 +types-setuptools,65.6.0.2,0,85.71 +typing-extensions,4.4.0,2,0.00 +tzlocal,4.2,0,100.00 +ujson,5.10.0,0,96.91 +ujson,5.6.0,0,97.85 +umap-learn,0.5.3,1,0.00 +Unidecode,1.3.6,0,98.57 +urllib3,1.26.13,0,98.59 +uvicorn,0.20.0,1,30.80 +uvloop,0.17.0,1,0.50 +uvloop,0.19.0,1,0.00 +validators,0.20.0,0,100.00 +versioneer,0.28,0,83.94 +virtualenv,20.17.1,0,86.46 +virtualenv,20.26.3,1,61.75 +wagtail,4.1.1,1,0.00 +waitress,2.1.2,1,0.00 +wandb,0.13.5,1,33.33 +wasabi,1.1.2,0,100.00 +watchdog,2.2.0,0,96.99 +wcwidth,0.2.13,0,100.00 +wcwidth,0.2.5,1,63.64 +webdriver-manager,3.8.5,0,75.29 +webencodings,0.5.1,0,87.50 +WebOb,1.8.7,0,98.16 +websocket-client,1.4.2,0,98.46 +websockets,10.4,1,0.00 +Werkzeug,2.2.2,0,96.30 +wget,3.2,0,100.00 +wheel,0.38.4,0,98.57 +wheel,0.43.0,0,100.00 +wrapt,1.14.1,0,92.35 +WTForms,3.0.1,0,100.00 +xarray,2022.12.0,0,99.60 +xarray,2024.6.0,0,99.89 +xgboost,1.7.1,0,83.15 +xgboost,2.0.3,2,0.00 +xlrd,2.0.1,0,100.00 +XlsxWriter,3.0.3,0,100.00 +xlwt,1.3.0,0,100.00 +xmltodict,0.13.0,0,100.00 +xxhash,3.2.0,0,100.00 +yamale,4.0.4,0,100.00 +yapf,0.32.0,1,0.00 +yarl,1.8.2,0,99.24 +youtube_dl,2021.12.17,0,86.87 +zarr,2.14.0,1,0.00 +zeep,4.2.1,0,99.39 +zipp,3.11.0,1,0.00 +zope.interface,5.5.2,0,94.97 diff --git a/docs/site/module_results/python-module-testing-v242.csv b/docs/site/module_results/python-module-testing-v242.csv new file mode 100644 index 0000000000..8e19918730 --- /dev/null +++ b/docs/site/module_results/python-module-testing-v242.csv @@ -0,0 +1,615 @@ +absl-py,1.3.0,0,98.61 +aif360,0.5.0,2,0.00 +aiodns,3.0.0,1,33.33 +aiofiles,22.1.0,0,98.99 +aiohttp,3.8.3,0,94.55 +aiohttp_cors,0.7.0,2,0.00 +aioredis,2.0.1,2,0.00 +aiorwlock,1.3.0,0,97.78 +aiosignal,1.3.1,0,100.00 +alembic,1.8.1,0,99.64 +aliyun-python-sdk-core,2.13.36,0,90.22 +altair,4.2.2,0,100.00 +annotated-types,0.7.0,0,100.00 +ansible-core,2.14.2,1,0.00 +anyio,3.7.0,1,0.00 +appdirs,1.4.4,0,100.00 +APScheduler,3.9.1.post1,1,0.00 +argcomplete,2.0.0,0,100.00 +arrow,1.2.3,0,99.95 +asgiref,3.5.2,0,98.46 +asn1crypto,1.5.1,0,99.87 +astor,0.8.1,0,94.55 +astroid,2.12.13,1,0.00 +astropy,5.2.1,2,0.00 +asttokens,2.4.1,0,96.55 +async-timeout,4.0.2,0,100.00 +async_generator,1.10,0,88.37 +asyncpg,0.27.0,1,0.00 +atomicwrites,1.4.1,0,100.00 +attrs,22.1.0,0,96.12 +autoflake,2.0.0,0,100.00 +autopep8,2.3.1,0,99.65 +awscli,1.34.23,1,0.00 +azure-common,1.1.28,0,100.00 +azure-identity,1.12.0,0,97.45 +azure-storage-blob,12.18.3,1,0.00 +backcall,0.2.0,0,100.00 +backoff,2.2.1,0,97.48 +bandit,1.7.4,1,0.00 +base58,2.1.1,0,100.00 +bcrypt,4.2.0,0,100.00 +beautifulsoup4,4.11.1,0,99.04 +biopython,1.80,1,0.00 +black,24.2.0,0,99.61 +bleach,5.0.0,0,100.00 +blessed,1.20.0,1,0.00 +blessings,1.7,1,0.00 +blinker,1.8.2,0,80.00 +blis,0.9.1,2,0.00 +bokeh,3.0.2,2,0.00 +boto3,1.34.116,0,93.91 +botocore,1.35.23,1,0.00 +bottle,0.12.23,0,100.00 +build,0.9.0,0,95.65 +bump2version,1.0.1,0,97.63 +CacheControl,0.12.11,1,0.00 +cachetools,5.2.0,0,99.52 +catalogue,2.0.8,0,100.00 +catboost,1.2.3,2,0.00 +category-encoders,2.6.1,1,0.00 +celery,5.3.6,2,0.00 +Cerberus,1.3.4,0,100.00 +certifi,2022.9.24,0,100.00 +cffi,1.17.1,1,0.00 +chardet,5.1.0,0,100.00 +charset-normalizer,3.3.2,0,79.56 +check-manifest,0.49,0,100.00 +circuitbreaker,2.0.0,0,100.00 +click,8.1.7,0,100.00 +cliff,4.3.0,1,0.00 +cloudpickle,2.2.1,0,98.85 +cmaes,0.9.1,1,0.00 +cmd2,2.4.3,1,0.00 +codecov,2.1.12,0,100.00 +colorama,0.4.6,0,100.00 +coloredlogs,15.0.1,1,0.00 +colorful,0.5.5,0,100.00 +colorlog,6.7.0,0,100.00 +commonmark,0.9.1,0,100.00 +ConfigArgParse,1.7,0,100.00 +configobj,5.0.6,0,100.00 +configparser,5.3.0,0,97.63 +confluent-kafka,2.0.2,1,0.00 +contourpy,1.2.1,0,99.00 +contourpy,1.3.0,0,98.37 +cookiecutter,2.1.1,0,99.68 +coverage,6.5.0,1,0.00 +coveralls,3.3.1,1,0.00 +cryptography,43.0.0,0,100.00 +cssselect,1.2.0,0,100.00 +cycler,0.11.0,0,100.00 +cymem,2.0.7,2,0.00 +Cython,0.29.32,2,0.00 +dask,2022.12.0,1,0.00 +dataclasses-json,0.5.7,0,99.57 +datasets,2.18.0,1,0.00 +dateparser,1.1.4,0,99.98 +DateTime,4.7,1,0.00 +DAWG-Python,0.7.2,2,0.00 +debugpy,1.6.7,1,0.00 +decorator,5.1.1,0,100.00 +deepdiff,6.2.1,2,0.00 +defusedxml,0.7.1,0,95.06 +Deprecated,1.2.13,0,88.68 +dice-ml,0.9,2,0.00 +dill,0.3.6,1,0.00 +discord.py,2.1.0,1,0.00 +diskcache,5.6.3,1,0.00 +distlib,0.3.6,0,77.02 +distributed,2022.12.0,2,0.00 +distro,1.8.0,0,100.00 +Django,4.1.4,2,0.00 +django-filter,22.1,0,94.09 +django-model-utils,4.3.1,0,99.40 +djangorestframework,3.14.0,0,99.72 +dnspython,2.2.1,0,95.61 +docker,6.0.1,0,99.83 +docopt,0.6.2,0,100.00 +docutils,0.19,0,99.81 +dohq-artifactory,0.8.4,0,96.39 +ecdsa,0.18.0,1,0.00 +einops,0.6.0,2,0.00 +elasticsearch,8.13.0,0,94.04 +email-validator,2.2.0,0,100.00 +emoji,2.2.0,0,100.00 +entrypoints,0.4,0,100.00 +eventlet,0.33.3,1,0.00 +execnet,1.9.0,2,0.00 +fake-useragent,1.1.1,0,100.00 +Faker,15.3.4,0,99.46 +fastapi,0.88.0,1,0.00 +feedparser,6.0.10,1,0.00 +filelock,3.8.2,0,100.00 +fiona,1.9.1,1,0.00 +fire,0.6.0,0,99.63 +flake8,6.0.0,0,99.13 +flake8-bandit,4.1.1,0,87.98 +flake8-bugbear,23.2.13,0,96.15 +flake8-comprehensions,3.11.1,0,99.22 +flake8-polyfill,1.0.2,2,0.00 +FLAML,2.3.1,2,0.00 +Flask,3.0.3,0,100.00 +flask-cors,5.0.1,2,0.00 +Flask-Login,0.6.3,0,100.00 +Flask-OpenTracing,1.1.0,0,93.75 +Flask-RESTful,0.3.9,0,98.43 +Flask-SQLAlchemy,3.0.3,0,100.00 +Flask-WTF,1.2.1,0,100.00 +flatbuffers,23.5.26,2,0.00 +fonttools,4.38.0,2,0.00 +fpdf2,2.7.4,1,0.00 +freezegun,1.2.1,0,99.19 +frozenlist,1.3.3,2,0.00 +fsspec,2024.2.0,0,94.25 +future,0.18.2,1,0.00 +fuzzywuzzy,0.18.0,0,98.59 +gast,0.5.4,0,97.87 +gensim,4.3.1,1,0.00 +geojson,3.1.0,0,100.00 +geopandas,0.12.1,0,94.96 +geopy,2.3.0,0,98.78 +gevent,22.10.2,2,0.00 +gitdb,4.0.10,0,95.83 +gitdb2,4.0.2,0,80.00 +GitPython,3.1.29,0,99.56 +google-api-core,2.11.0,1,0.00 +google-api-python-client,2.68.0,0,99.67 +google-auth,2.15.0,0,99.42 +google-auth-httplib2,0.1.0,0,100.00 +google-auth-oauthlib,1.0.0,2,0.00 +google-cloud-bigquery,3.4.0,2,0.00 +google-cloud-storage,2.6.0,0,100.00 +google-pasta,0.2.0,0,78.24 +googleapis-common-protos,1.57.0,0,100.00 +gpustat,1.1,2,0.00 +graphviz,0.20.3,0,99.73 +greenlet,2.0.1,1,0.00 +grpcio,1.60.0,2,0.00 +grpcio-tools,1.60.0,2,0.00 +gssapi,1.8.2,2,0.00 +gunicorn,20.1.0,1,0.00 +h11,0.14.0,0,100.00 +h5py,3.11.0,0,98.79 +horovod,0.28.1,1,53.04 +html2text,2020.1.16,0,100.00 +html5lib,1.1,0,99.99 +httpcore,1.0.6,1,0.00 +httplib2,0.22.0,0,99.60 +httptools,0.6.1,1,0.00 +httpx,0.23.1,1,0.00 +huggingface-hub,0.15.1,1,0.00 +humanfriendly,10.0,1,27.78 +humanize,4.4.0,0,100.00 +hvac,1.1.1,1,47.56 +hypothesis,6.112.1,1,0.00 +idna,3.4,0,100.00 +imageio,2.22.4,0,85.79 +imbalanced-learn,0.12.3,0,99.91 +implicit,0.7.2,0,100.00 +importlib-metadata,5.1.0,0,100.00 +importlib-resources,5.10.1,0,99.64 +inflection,0.5.1,0,100.00 +iniconfig,2.0.0,0,100.00 +invoke,1.7.3,2,0.00 +ipdb,0.13.13,0,100.00 +ipykernel,6.17.1,1,0.00 +ipython,8.7.0,1,0.00 +ipywidgets,8.0.3,0,91.23 +iso8601,1.1.0,0,100.00 +isodate,0.6.1,0,100.00 +isort,5.10.1,0,98.84 +itsdangerous,2.2.0,0,100.00 +jaeger-client,4.8.0,2,0.00 +jax,0.4.13,2,0.00 +jedi,0.18.2,1,0.00 +jeepney,0.8.0,2,0.00 +jieba,0.42.1,0,100.00 +Jinja2,3.1.4,0,99.65 +jiter,0.5.0,0,100.00 +jmespath,1.0.1,0,100.00 +joblib,1.2.0,0,84.02 +jq,1.8.0,1,0.00 +jsii,1.72.0,2,0.00 +json5,0.9.14,0,100.00 +jsonpickle,3.0.0,1,0.00 +jsonschema,4.17.3,1,0.00 +jupyter-client,7.4.8,1,0.00 +jupyter-core,5.2.0,0,100.00 +jupyterlab,3.5.1,1,0.00 +kafka-python,2.0.2,0,91.89 +kazoo,2.9.0,2,0.00 +keras,2.14.0,2,0.00 +Keras-Preprocessing,1.1.2,1,56.67 +keyboard,0.13.5,0,99.36 +keyring,25.2.1,0,99.65 +kiwisolver,1.4.4,0,100.00 +kiwisolver,1.4.5,0,100.00 +krb5,0.5.0,0,100.00 +kubernetes,25.3.0,0,99.62 +langchain,0.3.19,2,0.00 +lark-parser,0.12.0,2,0.00 +lazy-object-proxy,1.8.0,0,96.87 +libclang,16.0.0,2,0.00 +librosa,0.9.2,2,0.00 +lightfm,1.17,2,0.00 +lightgbm,4.3.0,2,0.00 +livereload,2.6.3,2,0.00 +lizard,1.17.10,0,98.35 +llvmlite,0.42.0,1,0.00 +loguru,0.7.2,2,0.00 +logzero,1.7.0,1,0.00 +lxml,5.3.0,1,0.00 +m2r2,0.3.3,0,100.00 +Mako,1.2.4,0,100.00 +Markdown,3.4.1,0,100.00 +MarkupSafe,2.1.5,0,100.00 +marshmallow,3.19.0,0,100.00 +matplotlib,3.9.2,0,99.74 +matplotlib-inline,0.1.7,2,0.00 +mccabe,0.7.0,0,93.75 +memory-profiler,0.61.0,2,0.00 +mistune,2.0.4,0,100.00 +mkdocs,1.4.2,0,100.00 +mkdocstrings,0.19.0,1,0.00 +mlflow,2.0.1,2,0.00 +mock,4.0.3,1,0.00 +more-itertools,9.0.0,1,0.00 +moto,4.1.2,1,4.96 +moviepy,1.0.3,1,0.00 +msgpack,1.0.4,1,0.00 +msrest,0.7.1,1,0.00 +multidict,6.0.3,0,86.99 +multiprocess,0.70.14,2,0.00 +murmurhash,1.0.9,2,0.00 +mypy,0.991,0,96.65 +mypy-extensions,1.0.0,0,100.00 +mysql-connector-python,8.0.31,1,0.00 +mysqlclient,2.1.1,0,100.00 +myst-parser,0.18.1,0,95.94 +natsort,8.2.0,1,0.00 +nbconvert,7.2.6,0,97.66 +nbformat,5.7.0,0,100.00 +nest-asyncio,1.5.6,0,100.00 +netaddr,0.8.0,0,100.00 +netCDF4,1.6.2,0,92.31 +netifaces,0.11.0,0,100.00 +networkx,2.8.8,1,0.00 +nibabel,4.0.2,2,0.00 +nltk,3.8.1,0,97.93 +notebook,6.5.2,1,39.17 +nox,2022.11.21,0,99.54 +numba,0.59.1,1,0.00 +numexpr,2.10.1,0,95.33 +numpy,1.24.3,1,64.39 +numpydoc,1.5.0,0,97.53 +oauthlib,3.2.2,0,99.85 +oci,2.104.3,1,56.76 +onnx,1.16.0,1,0.00 +onnxmltools,1.11.1,1,68.61 +onnxruntime,1.17.1,0,98.31 +openai,0.27.4,0,80.70 +opencensus,0.11.2,2,0.00 +opencensus-context,0.1.3,2,0.00 +opencv-python,4.6.0.66,2,0.00 +opencv-python-headless,4.6.0.66,2,0.00 +openpyxl,3.0.10,0,99.55 +opentracing,2.4.0,2,0.00 +opt-einsum,3.3.0,0,99.93 +optree,0.12.1,1,0.00 +optuna,3.2.0,1,0.00 +oracledb,3.0.0,2,0.00 +orbit-ml,1.1.4.2,1,0.00 +orjson,3.9.7,1,0.17 +oslo.config,9.0.0,1,0.00 +oslo.utils,6.1.0,1,0.00 +packaging,24.1,0,100.00 +paho-mqtt,2.1.0,0,96.95 +pandas,2.2.3,1,36.01 +papermill,2.4.0,0,98.90 +paramiko,2.12.0,0,99.76 +parse,1.19.0,0,100.00 +parso,0.8.3,0,91.49 +pathlib2,2.3.7.post1,0,100.00 +pathos,0.3.0,1,0.00 +pathspec,0.10.2,0,100.00 +pathy,0.10.2,0,100.00 +patsy,1.0.1,0,99.32 +pbr,5.11.0,1,0.00 +peewee,3.15.4,0,100.00 +pendulum,2.1.2,0,99.83 +pep8-naming,0.13.2,0,100.00 +peppercorn,0.6,0,100.00 +pexpect,4.8.0,1,29.91 +phonenumbers,8.13.6,1,49.34 +pickleshare,0.7.5,0,100.00 +pika,1.3.1,0,83.57 +pillow,10.3.0,0,99.06 +Pint,0.20.1,0,99.09 +pip,22.3.1,1,58.47 +pip-tools,6.11.0,0,90.05 +pkginfo,1.9.2,0,100.00 +platformdirs,3.0.0,0,100.00 +plotly,5.11.0,1,0.00 +pluggy,1.0.0,0,100.00 +ply,3.11,0,90.91 +polyleven,0.8,0,100.00 +pre-commit,2.20.0,1,0.00 +preshed,3.0.8,2,0.00 +prettytable,3.5.0,0,100.00 +progress,1.6,0,100.00 +progressbar2,4.2.0,0,100.00 +prometheus-client,0.15.0,0,100.00 +prompt-toolkit,3.0.33,0,100.00 +prophet,1.1.5,0,98.72 +protobuf,4.21.10,2,0.00 +psutil,5.9.8,1,0.00 +psycopg2,2.9.9,0,98.38 +psycopg2-binary,2.9.9,0,97.98 +ptyprocess,0.7.0,1,14.29 +pure-eval,0.2.2,0,97.87 +py,1.11.0,0,95.12 +py-spy,0.3.14,1,25.00 +py4j,0.10.9.7,2,0.00 +pyaml,21.10.1,0,100.00 +pyarrow,15.0.0,1,0.00 +pyasn1,0.4.8,0,97.90 +pyasn1-modules,0.2.8,0,100.00 +PyAudio,0.2.12,1,42.31 +pyautogen,0.3.0,2,0.00 +PyAutoGUI,0.9.53,1,0.00 +pybind11,2.10.1,1,0.00 +pycodestyle,2.10.0,0,98.11 +pycparser,2.21,0,98.46 +pycryptodome,3.16.0,1,0.00 +pycryptodomex,3.16.0,1,0.00 +pydantic,2.4.2,0,98.41 +pydantic-core,2.10.1,0,99.68 +pydantic-settings,2.8.1,1,0.00 +pydata-sphinx-theme,0.12.0,2,0.00 +pydicom,2.3.1,0,99.64 +pydocstyle,6.1.1,2,0.00 +pydot,1.4.2,0,93.75 +PyDriller,2.2,0,99.20 +pydub,0.25.1,1,0.00 +pyfiglet,0.8.post0,0,100.00 +pyflakes,3.0.1,0,99.45 +pygame,2.1.2,2,0.00 +PyGithub,1.57,1,0.00 +Pygments,2.13.0,0,100.00 +PyGObject,3.42.2,2,0.00 +PyJWT,2.6.0,1,0.00 +pylint,2.15.8,1,0.00 +pymdown-extensions,10.0.1,0,89.08 +pymongo,4.9.1,1,14.44 +PyNaCl,1.5.0,0,100.00 +pyod,1.1.3,1,0.00 +pyodbc,4.0.35,1,0.00 +pyOpenSSL,22.1.0,1,0.00 +pypandoc,1.13,0,87.80 +pyparsing,3.0.9,0,100.00 +PyPDF2,3.0.0,0,77.80 +pyperclip,1.8.2,0,100.00 +pyproj,3.7.0,0,100.00 +pyqtgraph,0.13.1,1,0.00 +pyramid,2.0,0,99.89 +pyrsistent,0.20.0,0,100.00 +pysam,0.20.0,1,0.00 +pyserial,3.5,0,93.48 +PySide2,5.15.2.1,2,0.00 +PySocks,1.7.1,0,100.00 +pysolr,3.9.0,1,0.00 +pyspark,3.4.1,2,0.00 +pyspnego,0.9.1,0,99.70 +pytesseract,0.3.10,0,89.58 +pytest,8.3.2,0,98.98 +pytest-asyncio,0.20.3,1,0.00 +pytest-benchmark,4.0.0,0,95.69 +pytest-cov,4.0.0,1,61.72 +pytest-django,4.8.0,0,81.65 +pytest-flake8,1.1.1,0,100.00 +pytest-forked,1.6.0,0,100.00 +pytest-mock,3.10.0,0,96.15 +pytest-mypy,0.10.2,0,84.21 +pytest-runner,6.0.0,1,50.00 +pytest-sugar,1.0.0,0,100.00 +pytest-timeout,2.1.0,0,90.24 +pytest-xdist,3.1.0,0,98.33 +python-dateutil,2.8.2,0,98.71 +python-dotenv,0.21.0,0,93.10 +python-editor,1.0.4,2,0.00 +python-jose,3.3.0,0,99.79 +python-json-logger,2.0.4,0,100.00 +python-magic,0.4.27,0,95.00 +python-multipart,0.0.5,0,90.38 +python-slugify,7.0.0,0,100.00 +pytorch-lightning,1.8.3.post1,2,0.00 +pytorch-tabnet,4.0,1,0.00 +pytype,2024.9.13,2,0.00 +pytz,2022.6,0,100.00 +PyYAML,6.0,0,100.00 +pyzmq,24.0.1,0,97.77 +qrcode,7.3.1,0,98.63 +QtPy,2.3.0,2,0.00 +rasterio,1.3.4,2,0.00 +ray,2.9.1,2,0.00 +rdflib,6.2.0,1,0.00 +readme-renderer,37.3,0,87.67 +redis,4.4.0,0,99.64 +regex,2024.5.15,0,99.02 +reportlab,3.6.12,1,0.00 +requests,2.28.1,0,99.49 +requests-cache,0.9.7,1,41.98 +requests-kerberos,0.14.0,0,100.00 +requests-mock,1.10.0,0,100.00 +requests-oauthlib,1.3.1,1,0.00 +requests-toolbelt,0.10.1,0,100.00 +responses,0.22.0,0,95.38 +retrying,1.3.4,0,100.00 +rfc3986,2.0.0,0,100.00 +rich,12.6.0,0,94.39 +robotframework,6.0.1,1,5.98 +rsa,4.9,0,98.85 +ruamel.yaml,0.17.21,0,100.00 +s3fs,2022.11.0,1,8.38 +s3transfer,0.10.2,1,49.39 +sacremoses,0.0.53,2,0.00 +sanic,23.12.1,1,0.00 +schedule,1.1.0,0,82.86 +schema,0.7.5,0,100.00 +scikit-image,0.25.0,1,0.00 +scikit-learn,1.5.2,1,0.00 +scipy,1.13.1,0,79.39 +Scrapy,2.7.1,1,0.00 +seaborn,0.13.2,0,98.95 +SecretStorage,3.3.3,1,26.92 +seldon-core,1.16.0,2,0.00 +selenium,4.20.0,1,0.00 +semantic-version,2.10.0,0,100.00 +semver,3.0.2,0,100.00 +sentence-transformers,2.2.2,2,0.00 +sentencepiece,0.1.97,2,0.00 +sentry-sdk,1.15.0,0,87.77 +setproctitle,1.3.3,0,82.14 +setuptools,65.5.0,2,0.00 +setuptools-scm,7.0.5,0,100.00 +setuptools-scm-git-archive,1.4,2,0.00 +sh,1.14.3,1,14.86 +shap,0.45.1,2,0.00 +shapely,2.0.0,0,99.97 +simplejson,3.18.0,0,100.00 +six,1.16.0,0,100.00 +skl2onnx,1.16,2,0.00 +sktime,0.24.0,1,0.00 +slackclient,2.9.4,0,98.89 +slicer,0.0.7,2,0.00 +smart-open,7.0.4,1,0.00 +smmap,5.0.0,0,100.00 +smmap2,3.0.1,2,0.00 +sniffio,1.3.0,0,100.00 +snowballstemmer,2.2.0,2,0.00 +sortedcontainers,2.4.0,1,0.00 +soupsieve,2.3.2.post1,2,0.00 +spacy,3.6.1,0,97.83 +spacy-legacy,3.0.12,0,97.96 +spacy-loggers,1.0.4,0,100.00 +spacy-lookups-data,1.0.5,1,59.91 +spacy-model-manager,0.1.3,0,100.00 +spacy-pkuseg,0.0.32,2,0.00 +Sphinx,5.3.0,1,47.80 +sphinx-autobuild,2021.3.14,0,100.00 +sphinx-autodoc-typehints,1.19.5,0,94.74 +sphinx-click,6.0.0,0,100.00 +sphinx-gallery,0.18.0,0,99.56 +sphinx-multiversion,0.2.4,0,100.00 +sphinx-rtd-theme,1.1.1,1,0.00 +sphinxcontrib-bibtex,2.6.2,0,98.37 +SQLAlchemy,1.4.52,1,0.00 +SQLAlchemy-Utils,0.38.3,1,0.00 +sqlparse,0.4.3,0,100.00 +srsly,2.4.6,2,0.00 +stack-data,0.6.2,2,0.00 +starlette,0.23.0,2,0.00 +statsmodels,0.14.1,0,99.96 +stevedore,4.1.1,1,0.00 +streamlit,1.15.2,2,0.00 +structlog,22.3.0,0,96.26 +sympy,1.11.1,1,0.00 +tables,3.7.0,2,0.00 +tabulate,0.9.0,0,99.33 +tenacity,8.1.0,0,99.07 +tensorboard,2.11.0,2,0.00 +tensorboard-data-server,0.7.1,2,0.00 +tensorboard-plugin-wit,1.8.1,2,0.00 +tensorboardX,2.6.1,1,0.00 +tensorflow,2.15.0,1,0.00 +tensorflow-estimator,2.12.0,2,0.00 +tensorflow-gpu,2.11.0,2,0.00 +tensorflow-io-gcs-filesystem,0.32.0,2,0.00 +tensorflow-probability,0.19.0,2,0.00 +termcolor,2.1.1,0,100.00 +terminaltables,3.1.10,0,90.76 +testbook,0.4.2,0,100.00 +thinc,8.1.10,1,43.84 +threadloop,1.0.2,1,64.29 +threadpoolctl,3.1.0,0,100.00 +thrift,0.16.0,2,0.00 +tifffile,2022.10.10,2,0.00 +tiktoken,0.7.0,2,0.00 +tinydb,4.7.0,0,100.00 +tldextract,3.4.0,1,0.00 +tokenizers,0.13.3,2,0.00 +toml,0.10.2,0,91.30 +tomli,2.0.1,0,100.00 +tomlkit,0.11.6,0,99.76 +toolz,0.12.0,0,97.06 +torch,2.4.1,2,0.00 +torchvision,0.19.1,0,96.38 +tornado,6.2,0,98.14 +tox,3.27.1,0,99.37 +tqdm,4.66.4,0,99.33 +traitlets,5.6.0,0,99.82 +transformers,4.33.3,2,0.00 +trio,0.22.0,1,0.00 +twine,4.0.2,0,96.11 +Twisted,22.10.0,1,0.00 +typed-ast,1.5.4,1,0.00 +typeguard,2.13.3,1,74.49 +typer,0.7.0,1,0.00 +types-pytz,2024.2.0.20240913,1,75.00 +types-PyYAML,6.0.12.20240917,1,75.00 +types-requests,2.31.0.20240311,0,88.89 +types-setuptools,75.1.0.20240917,1,75.00 +typing-extensions,4.4.0,2,0.00 +tzlocal,4.2,0,100.00 +ujson,5.10.0,0,96.91 +umap-learn,0.5.3,1,0.00 +Unidecode,1.3.6,0,98.57 +urllib3,1.26.13,0,98.54 +uvicorn,0.20.0,1,25.94 +uvloop,0.19.0,1,0.00 +validators,0.20.0,0,100.00 +versioneer,0.28,0,100.00 +virtualenv,20.26.3,0,89.46 +wagtail,4.1.1,1,64.47 +waitress,2.1.2,2,0.00 +wandb,0.13.5,1,0.00 +wasabi,1.1.2,0,100.00 +watchdog,2.2.0,2,0.00 +watchfiles,0.21.0,2,0.00 +wcwidth,0.2.13,0,100.00 +webdriver-manager,3.8.5,0,75.29 +webencodings,0.5.1,0,87.50 +WebOb,1.8.7,0,98.16 +websocket-client,1.4.2,0,98.46 +websockets,10.4,1,0.00 +Werkzeug,3.0.4,1,0.00 +wget,3.2,0,100.00 +wheel,0.43.0,0,100.00 +wrapt,1.14.1,0,92.60 +WTForms,3.0.1,0,100.00 +xarray,2024.6.0,0,99.89 +xgboost,2.0.3,2,0.00 +xlrd,2.0.1,0,100.00 +XlsxWriter,3.0.3,0,100.00 +xlwt,1.3.0,0,100.00 +xmltodict,0.13.0,0,100.00 +xxhash,3.4.1,0,100.00 +yamale,4.0.4,0,100.00 +yapf,0.32.0,1,0.00 +yarl,1.8.2,0,99.24 +youtube_dl,2021.12.17,0,86.87 +zarr,2.14.0,1,0.00 +zeep,4.2.1,0,99.18 +zipp,3.11.0,0,98.61 +zope.interface,5.5.2,0,97.56 diff --git a/docs/user/Embedding-Build-Tools.md b/docs/user/Embedding-Build-Tools.md index 3b845cabc1..8f79dfe0a8 100644 --- a/docs/user/Embedding-Build-Tools.md +++ b/docs/user/Embedding-Build-Tools.md @@ -1,10 +1,3 @@ ---- -layout: docs -toc_group: python -link_title: Embedding Build Tools -permalink: /reference-manual/python/Embedding-Build-Tools/ ---- - # Embedding Build Tools The GraalPy **Maven** and **Gradle** plugins provide functionality to manage Python related resources @@ -13,7 +6,7 @@ required for embedding Python code in Java-based applications: - *Third-party Python packages* installed by the plugin during the build according to the plugin configuration. Apart from physically managing and deploying those files, it is also necessary to make them available in Python at runtime by configuring the **GraalPy Context** in your Java code accordingly. -The [GraalPyResources](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/utils/GraalPyResources.java) API provides factory methods to create a Context preconfigured for accessing Python, embedding relevant resources with a **Virtual Filesystem** or from a dedicated **external directory**. +The [GraalPyResources](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java) API provides factory methods to create a Context preconfigured for accessing Python, embedding relevant resources with a **Virtual Filesystem** or from a dedicated **external directory**. ## Deployment @@ -33,7 +26,7 @@ User can choose relative Java resources path that will be made accessible in Pyt by default it is `org.graalvm.python.vfs`. All resources subdirectories with this path are merged during build and mapped to a configurable Virtual Filesystem mount point at the Python side, by default `/graalpy_vfs`. For example, a Python file with the real filesystem path `${project_resources_directory}/org.graalvm.python.vfs/src/foo/bar.py` will be accessible as `/graalpy_vfs/src/foo/bar.py` in Python. -Use the following [GraalPyResources](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/utils/GraalPyResources.java) +Use the following [GraalPyResources](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java) factory methods to create GraalPy Context preconfigured for the use of the Virtual Filesystem: * `GraalPyResources.createContext()` * `GraalPyResources.contextBuilder()` @@ -41,20 +34,34 @@ factory methods to create GraalPy Context preconfigured for the use of the Virtu #### Java Resource Path Particularly when developing reusable libraries, it is recommended to use custom unique Java resources path for your -virtual filesystem to avoid conflicts with other libraries on the classpath or modulepath that may also use the +virtual filesystem to avoid conflicts with other libraries on the classpath or module path that may also use the Virtual Filesystem. The recommended path is: - ``` - GRAALPY-VFS/${project.groupId}/${project.artifactId} - ``` +```bash +GRAALPY-VFS/${project.groupId}/${project.artifactId} +``` The Java resources path must be configured in the Maven and Gradle plugins and must be also set to the same value at runtime using the `VirtualFileSystem$Builder#resourceDirectory` API. *Note regarding Java module system: resources in named modules are subject to the encapsulation rules specified by [Module.getResourceAsStream](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Module.html#getResourceAsStream(java.lang.String)). -This is also the case of the default virtual filesystem location. When a resources directory is not -a valid Java package name, such as the recommended "GRAALPY-VFS", the resources are not subject to -the encapsulation rules and do not require additional module system configuration.* +This is also the case of the default virtual filesystem location. +When a resources directory is not a valid Java package name, such as the recommended "GRAALPY-VFS", the resources are not subject to the encapsulation rules and do not require additional module system configuration.* + +#### Extracting files from Virtual Filesystem +Normally, Virtual Filesystem resources are loaded like java resources, but there are cases when files need to be accessed +outside the Truffle sandbox, e.g. Python C extension files which need to be accessed by the operating system loader. + +By default, files which are of type `.so`, `.dylib`, `.pyd`, `.dll`, or `.ttf`, are automatically extracted to a temporary directory +in the real filesystem when accessed for the first time and the Virtual Filesystem then delegates to those real files. + +The default extract rule can be enhanced using the `VirtualFileSystem$Builder#extractFilter` API. + +Alternatively, it is possible to extract all Python resources into a user-defined directory before creating a GraalPy +context, and then configure the context to use that directory. Please refer to the following [GraalPyResources](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java) +methods for more details: +* `GraalPyResources.extractVirtualFileSystemResources(VirtualFileSystem vfs, Path externalResourcesDirectory)` +* `GraalPyResourcescontextBuilder(Path externalResourcesDirectory)` ### External Directory @@ -62,12 +69,12 @@ As an alternative to Java resources with the Virtual Filesystem, it is also poss A user is then responsible for the deployment of such directory. Python code will access the files directly from the real filesystem. -Use the following [GraalPyResources](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/utils/GraalPyResources.java) factory methods to create GraalPy Context preconfigured for the use of an external directory: +Use the following [GraalPyResources](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java) factory methods to create GraalPy Context preconfigured for the use of an external directory: * `GraalPyResources.createContextBuilder(Path)` ## Conventions -The factory methods in [GraalPyResources](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/utils/GraalPyResources.java) rely on the following conventions, where the `${root}` is either an external directory, or a Virtual System mount point on the Python side and Java resources directories, such as `${project_resources_directory}/org.graalvm.python.vfs`, on the real filesystem: +The factory methods in [GraalPyResources](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java) rely on the following conventions, where the `${root}` is either an external directory, or a Virtual System mount point on the Python side and Java resources directories, such as `${project_resources_directory}/org.graalvm.python.vfs`, on the real filesystem: - `${root}/src`: used for Python application files. This directory will be configured as the default search path for Python module files (equivalent to `PYTHONPATH` environment variable). - `${root}/venv`: used for the Python virtual environment holding installed third-party Python packages. The Context will be configured as if it is executed from this virtual environment. Notably packages installed in this @@ -79,7 +86,42 @@ Any manual change will be overridden by the plugin during the build. The _src_ subdirectory is left to be manually populated by the user with custom Python scripts or modules. -## GraalPy Maven Plugin Configuration +To manage third-party Python packages, a [Python virtual environment](https://docs.python.org/3.11/tutorial/venv.html) is used behind the scenes. +Whether deployed in a virtual filesystem or an external directory, its contents are managed by the plugin based on the Python packages +specified in the plugin configuration. + +## Python Dependency Management for Reproducible Builds + +In Python ecosystem, it is common that packages specify their dependencies as ranges rather than a fixed version. +For example, package A depends on package B of any version higher or equal to 2.0.0 (denoted as `B>=2.0.0`). +Installation of package A today may pull package `B==2.0.0`. Tomorrow package B releases new version `2.0.1` +and a clean build of a project depending on A will pull new version of B, which may not be compatible +with GraalPy or may introduce (unintentional) breaking changes. + +### Locking Dependencies + +We **highly recommend locking** all Python dependencies whenever there is a change in the list of required packages +for a project. Locking the dependencies means explicitly invoking a Maven goal or Gradle task that generates file +`graalpy.lock` that captures versions of all Python package dependencies: those specified explicitly in +`pom.xml` or `build.gradle` and all their transitive dependencies. + +The `graalpy.lock` file should be commited to version control system (e.g., git). Once the `graalpy.lock` file exists, +the package installation during Maven or Gradle build installs the exact same versions as captured in `graalpy.lock`. + +When the set of explicit dependencies in `pom.xml` or `build.gradle` changes and does not match what is in +`graalpy.lock` anymore, the build will fail and the user will be asked to explicitly regenerate the `graalpy.lock` file. + +Note that unless specific version of a package is desired, we recommend to specify explicit dependencies in +`pom.xml` or `build.gradle` without version quantifier. For some well known packages, GraalPy automatically +installs the version that is known to be compatible with GraalPy. However, once installed, the versions should be +locked to ensure reproducible builds. + +For information on the specific Maven or Gradle lock packages actions, please refer to the +Locking Python Packages subsections below. + +## GraalPy Maven Plugin + +### Maven Plugin Configuration Add the plugin configuration in the `configuration` block of `graalpy-maven-plugin` in the _pom.xml_ file: ```xml @@ -104,7 +146,7 @@ The Python packages and their versions are specified as if used with `pip`: ... ``` - + - The **resourceDirectory** element can specify the relative [Java resource path](#java-resource-path). Remember to use `VirtualFileSystem$Builder#resourceDirectory` when configuring the `VirtualFileSystem` in Java. ```xml @@ -119,12 +161,34 @@ Remember to use the appropriate `GraalPyResources` API to create the Context. Th ... ``` + +### Locking Python Packages +To lock the dependency tree of the specified Python packages, execute the GraalPy plugin goal `org.graalvm.python:graalpy-maven-plugin:lock-packages`. +```bash +$ mvn org.graalvm.python:graalpy-maven-plugin:lock-packages +``` +*Note that the action will override the existing lock file.* + +For a high level description of this feature, please refer to the +[Python Dependency Management for Reproducible Builds](#pythop-dependency-management-for-reproducible-builds) section +in this document. + +* The **graalPyLockFile** element can change the default path to the GraalPy lock file. Default value is `${basedir}/graalpy.lock`. + The **graalPyLockFile** element by itself will not trigger the locking. The locking must be done by explicitly executing the + `org.graalvm.python:graalpy-maven-plugin:lock-packages` goal. + ```xml + + ${basedir}/graalpy.lock + ... + + ``` -## GraalPy Gradle Plugin Configuration +## GraalPy Gradle Plugin +### Gradle Plugin Configuration The plugin must be added to the plugins section in the _build.gradle_ file. The **version** property defines which version of GraalPy to use. -``` +```groovy plugins { // other plugins ... id 'org.graalvm.python' version '24.2.0' @@ -139,22 +203,22 @@ The plugin can be configured in the `graalPy` block: - The **packages** element declares a list of third-party Python packages to be downloaded and installed by the plugin. The Python packages and their versions are specified as if used with `pip`. - ``` + ```bash graalPy { packages = ["termcolor==2.2"] ... } ``` - + - The **resourceDirectory** element can specify the relative [Java resource path](#java-resource-path). Remember to use `VirtualFileSystem$Builder#resourceDirectory` when configuring the `VirtualFileSystem` in Java. - ``` + ```bash resourceDirectory = "GRAALPY-VFS/my.group.id/artifact.id" ``` - If the **externalDirectory** element is specified, then the given directory is used as an [external directory](#external-directory) and no Java resources are embedded. Remember to use the appropriate `GraalPyResources` API to create the Context. - ``` + ```bash graalPy { externalDirectory = file("$rootDir/python-resources") ... @@ -162,14 +226,33 @@ The plugin can be configured in the `graalPy` block: ``` - Boolean flag **community** switches the automatically injected dependency `org.graalvm.python:python` to the community build: `org.graalvm.python:python-community`. - ``` + ```bash graalPy { community = true ... } ``` +### Locking Python Packages +To lock the dependency tree of the specified Python packages, execute the GraalPy plugin task `graalPyLockPackages`. +```bash +gradle graalPyLockPackages +``` +*Note that the action will override the existing lock file.* + +For a high level description of this feature, please refer to the +[Python Dependency Management for Reproducible Builds](#pythop-dependency-management-for-reproducible-builds) section +in this document. + +* The **graalPyLockFile** element can change the default path to the GraalPy lock file. Default value is `${basedir}/graalpy.lock`. + The **graalPyLockFile** element by itself will not trigger the locking. The locking must be done by explicitly executing the + `graalPyLockPackages` task. + ``` + graalPy { + graalPyLockFile = file("$rootDir/graalpy.lock") + ... + } -### Related Documentation +## Related Documentation * [Embedding Graal languages in Java](https://www.graalvm.org/reference-manual/embed-languages/) * [Permissions for Python Embeddings](Embedding-Permissions.md) diff --git a/docs/user/Embedding-Permissions.md b/docs/user/Embedding-Permissions.md index 30bbd29696..aec8ea7a50 100644 --- a/docs/user/Embedding-Permissions.md +++ b/docs/user/Embedding-Permissions.md @@ -1,11 +1,3 @@ ---- -layout: docs -toc_group: python -link_title: Embedding Permissions -permalink: /reference-manual/python/Embedding-Permissions/ -redirect_from: /reference-manual/python/OSInterface/ ---- - # Permissions for Python Embeddings ## Access Control and Security Limits for Python Scripts diff --git a/docs/user/Interoperability.md b/docs/user/Interoperability.md index 69611b0507..5dec91c72b 100644 --- a/docs/user/Interoperability.md +++ b/docs/user/Interoperability.md @@ -1,9 +1,3 @@ ---- -layout: docs -toc_group: python -link_title: Interoperability -permalink: /reference-manual/python/Interoperability/ ---- # Interoperability Besides being primarily recommended to use in your Java application, GraalPy can interoperate with other Graal languages (languages implemented on the [Truffle framework](https://www.graalvm.org/latest/graalvm-as-a-platform/language-implementation-framework/)). @@ -118,14 +112,14 @@ For example, if you have already configured a Maven project with GraalPy, add th org.graalvm.polyglot js - 24.1.0 + 24.2.0 ``` @@ -181,7 +175,7 @@ libexec/graalpy-polyglot-get js md = pattern.exec("Look, we have matching strings! This string was matched by Graal.js") assert "Graal.js" in md[1] - ``` + ``` This program matches Python strings using the JavaScript regular expression object. Python reads the captured group from the JavaScript result and checks for a substring in it. @@ -363,6 +357,7 @@ class Main { } ``` #### Interop Types + The `register_interop_type` API allows the usage of python classes for foreign objects. The class of such a foreign object will no longer be `polyglot.ForeignObject` or `polyglot.Foreign*`. Instead, it will be a generated class with the registered python classes and `polyglot.ForeignObject` as super class. @@ -394,7 +389,6 @@ class MyJavaClass { import org.example.MyJavaClass; class Main { - public static void main(String[] args) { MyJavaClass myJavaObject = new MyJavaClass(42, 17); @@ -450,7 +444,6 @@ Registering classes may be more convenient with `@interop_type`: import java from polyglot import interop_type - foreign_class = java.type("org.example.MyJavaClass") @interop_type(foreign_class) diff --git a/docs/user/Native-Extensions.md b/docs/user/Native-Extensions.md index d34614ea89..5746d1372a 100644 --- a/docs/user/Native-Extensions.md +++ b/docs/user/Native-Extensions.md @@ -1,17 +1,10 @@ ---- -layout: docs-experimental -toc_group: python -link_title: Native Extensions Support -permalink: /reference-manual/python/Native-Extensions/ ---- - # Native Extensions Support CPython provides a [native extensions API](https://docs.python.org/3/c-api/index.html) for writing Python extensions in C/C++. GraalPy provides experimental support for this API, which allows many packages like NumPy and PyTorch to work well for many use cases. The support extends only to the API, not the binary interface (ABI), so extensions built for CPython are not binary compatible with GraalPy. Packages that use the native API must be built and installed with GraalPy, and the prebuilt wheels for CPython from pypi.org cannot be used. -For best results, it is crucial that you only use the `pip` command that comes preinstalled in GraalPy virtualenvs to install packages. +For best results, it is crucial that you only use the `pip` command that comes preinstalled in GraalPy virtual environments to install packages. The version of `pip` shipped with GraalPy applies additional patches to packages upon installation to fix known compatibility issues and it is preconfigured to use an additional repository from graalvm.org where we publish a selection of prebuilt wheels for GraalPy. Please do not update `pip` or use alternative tools such as `uv`. @@ -51,8 +44,8 @@ You can also manually trigger the detector with the Python `gc.collect()` call. Using C extensions in multiple contexts is only possible on Linux for now, and many C extensions still have issues in this mode. You should test your applications thoroughly if you want to use this feature. -There are many possiblities for native code to sidestep the library isolation through other process-wide global state, corrupting the state and leading to incorrect results or crashing. -The implementation also relies on a venv to work, even if you are not using external packages. +There are many possibilities for native code to sidestep the library isolation through other process-wide global state, corrupting the state and leading to incorrect results or crashing. +The implementation also relies on `venv` to work, even if you are not using external packages. To support creating multiple GraalPy contexts that access native modules within the same JVM or Native Image, we need to isolate them from each other. The current strategy for this is to copy the libraries and modify them such that the dynamic library loader of the operating system will isolate them for us. diff --git a/docs/user/Native-Images-with-Python.md b/docs/user/Native-Images-with-Python.md index dad20dabfd..1c16f43f66 100644 --- a/docs/user/Native-Images-with-Python.md +++ b/docs/user/Native-Images-with-Python.md @@ -1,11 +1,3 @@ ---- -layout: docs -toc_group: python -link_title: Native Java-Python Applications -permalink: /reference-manual/python/native-applications/ -redirect_from: /reference-manual/python/native-image/ ---- - # Native Executables with Python GraalPy supports GraalVM Native Image to generate native binaries of Java applications that use GraalPy. @@ -62,7 +54,6 @@ These are: This uses an `ExecutorService` with a thread pool. If you want to disallow such extra threads or avoid pulling in `ExecutorService` and related classes, then set this property to `false` and retrieve the `PollPythonAsyncActions` object from the context's polyglot bindings. This object is executable and can be used to trigger Python asynchronous actions at the locations you desire. -* `python.WithoutJNI=true` - This option removes any code that uses JNI. As a consequence, you cannot use the HPy JNI backend and maybe other parts that rely on JNI. ### Removing Pre-initialized Python Heap diff --git a/docs/user/Performance.md b/docs/user/Performance.md index a13213ecda..fa84d2be43 100644 --- a/docs/user/Performance.md +++ b/docs/user/Performance.md @@ -1,18 +1,10 @@ ---- -layout: docs -toc_group: python -link_title: Python Performance -permalink: /reference-manual/python/Performance/ -redirect_from: /reference-manual/python/ParserDetails/ ---- - # Python Performance ## Execution Performance GraalPy uses the state-of-the-art just-in-time (JIT) compiler of GraalVM. When JIT compiled, GraalPy runs Python code ~4x faster than CPython on the official [Python Performance Benchmark Suite](https://pyperformance.readthedocs.io/). -![](assets/performance.svg) +![](./assets/performance.svg) These benchmarks can be run by installing the `pyperformance` package and calling `pyperformance run` on each of CPython and GraalPy. To get the Jython numbers we adapted the harness and benchmarks because of missing Python 3 support in Jython. @@ -52,7 +44,8 @@ The magic number is hard-coded in the source of Python and can not be changed by The developers of GraalPy change the magic number when the bytecode format changes. This is an implementation detail, so the magic number does not have to correspond to the version of GraalPy (as in CPython). -The magic number of `pyc` is a function of the actual Python runtime Java code that is running. Changes to the magic number are communicated in the release notes so that developers or system administrators can delete old _.pyc_ files when upgrading. +The magic number of `pyc` is a function of the actual Python runtime Java code that is running. +Changes to the magic number are communicated in the release notes so that developers or system administrators can delete old _.pyc_ files when upgrading. Note that if you use _.pyc_ files, you must allow write-access to GraalPy at least when switching versions or modifying the original source code file. Otherwise, the regeneration of source code files will fail and every import will have the overhead of accessing each old _.pyc_ file, parsing the code, serializing it, and trying (and failing) to write out a new _.pyc_ file. @@ -74,7 +67,8 @@ top_directory/ By default, GraalPy creates the _\_\_pycache\_\__ directory on the same directory level as a source code file and in this directory all _.pyc_ files from the same directory are stored. This directory may store _.pyc_ files created with different versions of Python (including, for example, CPython), so the user may see files ending in _.cpython3-6.pyc_, for example. -_.pyc_ files are largely managed automatically by GraalPy in a manner compatible with CPython. GraalPy provides options similar to CPython to specify the location of t_.pyc_ files, and if they should be written at all, and both of these options can be changed by guest code. +_.pyc_ files are largely managed automatically by GraalPy in a manner compatible with CPython. +GraalPy provides options similar to CPython to specify the location of t_.pyc_ files, and if they should be written at all, and both of these options can be changed by guest code. The creation of _.pyc_ files can be controlled in the [same way as CPython](https://docs.python.org/3/using/cmdline.html): @@ -93,23 +87,20 @@ The creation of _.pyc_ files can be controlled in the [same way as CPython](http * A guest language code can change the attribute `pycache_prefix` of the `sys` module at runtime to change the location for subsequent imports. -Because the developer cannot use environment variables or CPython options to -communicate these options to GraalPy, these options are made available as language options: +Because the developer cannot use environment variables or CPython options to communicate these options to GraalPy, these options are made available as language options: * `python.DontWriteBytecodeFlag` - equivalent to `-B` or `PYTHONDONTWRITEBYTECODE` * `python.PyCachePrefix` - equivalent to `PYTHONPYCACHEPREFIX` - Note that a Python context will not enable writing _.pyc_ files by default. The GraalPy launcher enables it by default, but if this is desired in the embedding use case, care should be taken to ensure that the _\_\_pycache\_\__ location is properly managed and the files in that location are secured against manipulation in the same way as the source code files (_.py_) from which they were derived. -Note also that to upgrade the application sources to Oracle GraalPy, old _.pyc_ -files must be removed by the developer as required. +Note also that to upgrade the application sources to Oracle GraalPy, old _.pyc_ files must be removed by the developer as required. ### Security Considerations -GraalPy performs all file operations (obtaining the data, timestamps, and writing _.pyc_ files) -via the [FileSystem API](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/io/FileSystem.html). Developers can modify all of these operations by means of custom (for example, read-only) `FileSystem` implementations. +GraalPy performs all file operations (obtaining the data, timestamps, and writing _.pyc_ files) via the [FileSystem API](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/io/FileSystem.html). +Developers can modify all of these operations by means of custom (for example, read-only) `FileSystem` implementations. The developer can also effectively disable the creation of _.pyc_ files by disabling I/O permissions for GraalPy. If _.pyc_ files are not readable, their location is not writable. diff --git a/docs/user/Python-Runtime.md b/docs/user/Python-Runtime.md index 8a491682c0..2415adcb7f 100644 --- a/docs/user/Python-Runtime.md +++ b/docs/user/Python-Runtime.md @@ -1,12 +1,4 @@ ---- -layout: docs -toc_group: python -link_title: Python Runtime -permalink: /reference-manual/python/Python-Runtime/ -redirect_from: /reference-manual/python/Packages/ ---- - -# GraalPy as a CPython Replacement +# Testing Python Applications and Packages on GraalPy ## Choosing the GraalPy Runtime @@ -16,7 +8,7 @@ GraalPy is distributed as an ahead-of-time compiled native executable, compact i GraalPy provides the following capabilities: -* Replacement for CPython. Use GraalPy as a replacement for CPython. It is the most compatible, since it most closely resembles the structure of CPython installation packages. +* CPython-compatible distribution. This is the most compatible option to test Python code on GraalPy, since it most closely resembles the structure of CPython distributions. * Unique deployment mode for Python applications. Compile a Python application on GraalPy to [a single native binary](Python-Standalone-Applications.md) that embeds all needed resources. * Access to GraalVM's language ecosystems and tools. GraalPy can run many standard Python tools as well as tools from the GraalVM ecosystem. @@ -77,12 +69,12 @@ The four GraalPy runtimes are identified as follows, using the general pattern _ ### Linux The easiest way to install GraalPy on Linux is to use [Pyenv](https://github.com/pyenv/pyenv) (the Python version manager). -To install version 24.1.0 using Pyenv, run the following commands: +To install version 24.2.0 using Pyenv, run the following commands: ```bash -pyenv install graalpy-24.1.0 +pyenv install graalpy-24.2.0 ``` ```bash -pyenv shell graalpy-24.1.0 +pyenv shell graalpy-24.2.0 ``` > Before running `pyenv install`, you may need to update `pyenv` to include the latest GraalPy versions. @@ -94,12 +86,12 @@ Alternatively, you can download a compressed GraalPy installation file from [Git ### macOS The easiest way to install GraalPy on macOS is to use [Pyenv](https://github.com/pyenv/pyenv) (the Python version manager). -To install version 24.1.0 using Pyenv, run the following commands: +To install version 24.2.0 using Pyenv, run the following commands: ```bash -pyenv install graalpy-24.1.0 +pyenv install graalpy-24.2.0 ``` ```bash -pyenv shell graalpy-24.1.0 +pyenv shell graalpy-24.2.0 ``` > Before running `pyenv install`, you may need to update `pyenv` to include the latest GraalPy versions. @@ -112,7 +104,7 @@ Alternatively, you can download a compressed GraalPy installation file from [Git ``` For example: ```bash - sudo xattr -r -d com.apple.quarantine ~/.pyenv/versions/graalpy-24.1.0 + sudo xattr -r -d com.apple.quarantine ~/.pyenv/versions/graalpy-24.2.0 ``` 3. Uncompress the file and update your `PATH` environment variable to include to the _graalpy-XX.Y.Z-macos-amd64/bin_ (or _graalpy-XX.Y.Z-macos-aarch64/bin_) directory. @@ -147,7 +139,7 @@ This generates wrapper scripts and makes the implementation usable from a shell ``` For example: ```bash - graalpy -m venv ~/.virtualenvs/graalpy-24.1.0 + graalpy -m venv ~/.virtualenvs/graalpy-24.2.0 ``` 2. Activate the environment in your shell session: @@ -156,7 +148,7 @@ This generates wrapper scripts and makes the implementation usable from a shell ``` For example: ```bash - source ~/.virtualenvs/graalpy-24.1.0/bin/activate + source ~/.virtualenvs/graalpy-24.2.0/bin/activate ``` Multiple executables are available in the virtual environment, including: `python`, `python3`, and `graalpy`. diff --git a/docs/user/Python-Standalone-Applications.md b/docs/user/Python-Standalone-Applications.md index 333349ddee..fdbedb729b 100644 --- a/docs/user/Python-Standalone-Applications.md +++ b/docs/user/Python-Standalone-Applications.md @@ -1,11 +1,3 @@ ---- -layout: docs -toc_group: python -link_title: Python Standalone Applications -permalink: /reference-manual/python/standalone-applications/ -redirect_from: /reference-manual/python/standalone-binaries/ ---- - # Python Standalone Applications GraalPy enables you to create a Python application or library as a native application or JAR file with no external dependencies. @@ -29,7 +21,7 @@ graalpy -m standalone native \ It produces a native _my_binary_ file which includes your Python code, the GraalPy runtime, and the Python standard library in a single, self-contained executable. Use `graalpy -m standalone native --help` for further options. -## Security Considerations +### Security Considerations of Python Standalone Applications Creating a native executable or a JAR file that includes Python code could be seen as a mild form of obfuscation, but it does not protect your source code. Python source code is not stored verbatim into the executable (only the GraalPy bytecode is stored), but bytecode is easy to convert back into Python source code. diff --git a/docs/user/Python-on-JVM.md b/docs/user/Python-on-JVM.md index 6f2f5ceb86..3ee3be1e2c 100644 --- a/docs/user/Python-on-JVM.md +++ b/docs/user/Python-on-JVM.md @@ -1,11 +1,3 @@ ---- -layout: docs -toc_group: python -link_title: Jython Compatibility -permalink: /reference-manual/python/Modern-Python-on-JVM/ -redirect_from: /reference-manual/python/Jython/ ---- - # Modern Python for the JVM For Python version 2 (now EOL), Jython is the _de facto_ means of interfacing Python and Java. @@ -296,7 +288,7 @@ The other way to use Jython was to embed it into a Java application. There were 1. Use the `PythonInterpreter` object that Jython provides. Existing code using Jython in this manner depends directly on the Jython package (for example, in the Maven configuration), because the Java code has references to Jython internal classes. These classes do not exist in GraalVM, and no equivalent classes are exposed. -To migrate from this usage, switch to the [GraalVM SDK](https://mvnrepository.com/artifact/org.graalvm.sdk/graal-sdk). +To migrate from this usage, switch to the [GraalVM SDK](https://central.sonatype.com/artifact/org.graalvm.sdk/graal-sdk). Using this SDK, no APIs particular to Python are exposed, everything is achieved via the GraalVM API, with maximum configurability of the Python runtime. Refer to the [Getting Started](README.md) documentation for preparing a setup. diff --git a/docs/user/README.md b/docs/user/README.md index f4f990bf1f..43886c14b4 100644 --- a/docs/user/README.md +++ b/docs/user/README.md @@ -1,13 +1,3 @@ ---- -layout: docs -toc_group: python -link_title: Python Reference -permalink: /reference-manual/python/ -redirect_from: - - /docs/reference-manual/python/ - - /reference-manual/python/FAQ/ ---- - # Getting Started with GraalPy on the JVM You can use GraalPy with GraalVM JDK, Oracle JDK, or OpenJDK. @@ -16,23 +6,23 @@ Other build systems (Ant, Make, CMake, and so on) can also be used with a bit mo ## Maven -GraalPy can generate a Maven project that embeds Python packages into a Java application using [Maven artefacts](https://mvnrepository.com/artifact/org.graalvm.python). +GraalPy can generate a Maven project that embeds Python packages into a Java application using [Maven artefacts](https://central.sonatype.com/namespace/org.graalvm.python). 1. GraalPy project publishes a Maven archetype to generate a starter project: ```bash mvn archetype:generate \ -DarchetypeGroupId=org.graalvm.python \ -DarchetypeArtifactId=graalpy-archetype-polyglot-app \ - -DarchetypeVersion=24.1.0 + -DarchetypeVersion=24.2.0 ``` -2. Build a native executable using the [ GraalVM Native Image "tool"](https://www.graalvm.org/latest/reference-manual/native-image/) plugin that was added for you automatically: +2. Build a native executable using the [GraalVM Native Image "tool"](https://www.graalvm.org/latest/reference-manual/native-image/) plugin that was added for you automatically: ```bash mvn -Pnative package ``` 3. Once completed, run the executable: - ``` + ```bash ./target/polyglot_app ``` The application prints "hello java" to the console. @@ -66,8 +56,6 @@ In order to distribute the resulting application for other systems, follow these ## Gradle -> Note: GraalPy Gradle Plugin will become available as of GraalPy version 24.1.1, planned for October 15, 2024. - 1. Create a Java application with Gradle using the command below and follow the prompts (select the Groovy build script language, select a test framework, and so on): ```bash gradle init --type java-application \ @@ -90,9 +78,9 @@ In order to distribute the resulting application for other systems, follow these 2. Open your project configuration file, _app/build.gradle_, and modify it as follows. - Include the GraalPy support and the [GraalVM Polyglot API](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/package-summary.html) in the `dependencies` section: - ``` - implementation("org.graalvm.polyglot:polyglot:24.1.1") - implementation("org.graalvm.polyglot:python:24.1.1") + ```bash + implementation("org.graalvm.polyglot:polyglot:24.2.0") + implementation("org.graalvm.polyglot:python:24.2.0") ``` 3. Finally, replace the code in the file named _App.java_ as follows for a small Python embedding: @@ -118,23 +106,23 @@ In order to distribute the resulting application for other systems, follow these > Note: The performance of the GraalPy runtime depends on the JDK in which you embed it. For more information, see [Runtime Optimization Support](https://www.graalvm.org/latest/reference-manual/embed-languages/#runtime-optimization-support). -5. Optionally, you can also use a third-party Python package: +5. Optionally, you can also use a third-party Python package. 5.1. In _app/build.gradle_: - add the graalpy-gradle-plugin to the `plugins` section: - ``` - id "org.graalvm.python" version "24.1.1" + ```bash + id "org.graalvm.python" version "24.2.0" ``` - configure the GraalPy Gradle plugin: - ``` + ```bash graalPy { packages = ["termcolor==2.2"] } ``` 5.2. In _settings.gradle_, add the following `pluginManagement` configuration. - ``` + ```bash pluginManagement { repositories { gradlePluginPortal() @@ -173,7 +161,7 @@ GraalPy comes with a tool to obtain the required JAR files from Maven. 1. Assuming there is some directory where third-party dependencies are stored for the project and that the build system is set up to put any JAR files there on the classpath, the project directory tree might look similar to this: - ``` + ```bash ├───lib │ └─── ... *.jar dependencies are here └───src @@ -187,13 +175,13 @@ GraalPy comes with a tool to obtain the required JAR files from Maven. In a POSIX shell: ```bash export GRAALPY_HOME=$(graalpy -c 'print(__graalpython__.home)') - "${GRAALPY_HOME}/libexec/graalpy-polyglot-get" -a python -o lib -v "24.1.0" + "${GRAALPY_HOME}/libexec/graalpy-polyglot-get" -a python -o lib -v "24.2.0" ``` In PowerShell: - ``` + ```bash $GRAALPY_HOME = graalpy -c "print(__graalpython__.home)" - & "$GRAALPY_HOME/libexec/graalpy-polyglot-get" -a python -o lib -v "24.1.0" + & "$GRAALPY_HOME/libexec/graalpy-polyglot-get" -a python -o lib -v "24.2.0" ``` These commands download all GraalPy dependencies into the _lib_ directory. @@ -212,9 +200,9 @@ GraalPy comes with a tool to obtain the required JAR files from Maven. } ``` -## GraalPy as CPython Replacement +## Testing Python Applications and Packages on GraalPy -Go [here](Python-Runtime.md) to get started with GraalPy as CPython replacement. +Go [here](Python-Runtime.md) to get a CPython compatible distribution of GraalPy to test Python applications and packages. #### Related Documentation diff --git a/docs/user/Tooling.md b/docs/user/Tooling.md index c7f4a427bc..1861ba588a 100644 --- a/docs/user/Tooling.md +++ b/docs/user/Tooling.md @@ -1,9 +1,3 @@ ---- -layout: docs -toc_group: python -link_title: Tooling Support for Python -permalink: /reference-manual/python/Tooling/ ---- # Tooling Support for Python ## Debugging @@ -49,7 +43,7 @@ You should see output similar to: {::options parse_block_html="true" /}
CPU Sampler Output (Click to expand) -``` +```bash -------------------------------------------------------------------------------------------------------------------------------------------------------------- Sampling Histogram. Recorded 564 samples with period 10ms. Missed 235 samples. Self Time: Time spent on the top of the stack. @@ -81,7 +75,7 @@ You should see output similar to: {::options parse_block_html="true" /}
CPU Tracer Output (Click to Expand) -``` +```bash -------------------------------------------------------------------------------------------------------------------- Tracing Histogram. Counted a total of 1135 element executions. Total Count: Number of times the element was executed and percentage of total executions. @@ -117,7 +111,7 @@ You should see output similar to: {::options parse_block_html="true" /}
Memory Tracer Output (Click to Expand) -``` +```bash ---------------------------------------------------------------------------- Location Histogram with Allocation Counts. Recorded a total of 565 allocations. Total Count: Number of allocations during the execution of this element. @@ -153,7 +147,7 @@ You should see output similar to: {::options parse_block_html="true" /}
CPU Sampler Output (Click to expand) -``` +```bash ------------------------------------------------------------------------------------------------------------------------------------------------ Code coverage histogram. Shows what percent of each element was covered during execution @@ -211,17 +205,17 @@ The standard Python `trace` module is also provided. > Note: This works in the same way as CPython. The programmatic API also works, with some limitations: it does not currently track calls, only line counts and called functions. -For example, the command +For example, running this command: ```bash graalpy -m trace -c -s text_styler.py Welcome to GraalPy! ``` -Give example output +You should see output similar to: {::options parse_block_html="true" /} -
CPU Sampler Output (Click to expand) -``` +
CPU Tracer Output (Click to Expand) +```bash _ __ __ __ | | / /__ / /________ ____ ___ ___ / /_____ | | /| / / _ \/ / ___/ __ \/ __ `__ \/ _ \ / __/ __ \ @@ -331,7 +325,7 @@ You can use GraalPy in PyCharm to create a virtual environment, install packages 3. Create, or open, a Python project. (For more information, see [Create a Python project](https://www.jetbrains.com/help/pycharm/creating-empty-project.html), or [Open, reopen, and close projects](https://www.jetbrains.com/help/pycharm/open-projects.html), respectively.) -4. Create a new _venv_ virtual environment for your Python project. +4. Create a new `venv` virtual environment for your Python project. (For more information, see [Create a virtualenv environment](https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html#python_create_virtual_env).) 5. Install packages by following the PyCharm instructions. @@ -346,7 +340,7 @@ You can use GraalPy in Visual Studio (VS) Code to create a virtual environment, 1. Install `graalpy`. (For more information, see [Installing GraalPy](Python-Runtime.md).) -2. Install VS Code and the Python Extension, following the instructions here: [Install Visual Studio Code and the Python Extension](https://code.visualstudio.com/docs/python/python-tutorial#_install-visual-studio-code-and-the-python-extension). +2. Install VS Code and the Python Extension, following the instructions here: [Install Visual Studio Code and the Python Extension](https://code.visualstudio.com/docs/python/python-tutorial#_prerequisites). 3. Create, or open, a Python file. @@ -356,9 +350,8 @@ You can use GraalPy in Visual Studio (VS) Code to create a virtual environment, 5. Install packages by following the VS Code instructions. (For more information, see [Install and use packages](https://code.visualstudio.com/docs/python/python-tutorial#_install-and-use-packages).) -6. Use the VS Code menu items to run your Python application. (For more information, see [Run Hello World](https://code.visualstudio.com/docs/python/python-tutorial#_run-hello-world).) +6. Use the VS Code menu items to run your Python application. (For more information, see [Run Hello World](https://code.visualstudio.com/docs/python/python-tutorial#_run-python-code).) Alternatively, use a VS Code terminal emulator to run the `graalpy` command. 7. You cannot use VS Code to debug your Python application. Instead, open a VS Code terminal emulator and follow these instructions: [Debugging a Python Application](#debugging). - diff --git a/docs/user/Troubleshooting.md b/docs/user/Troubleshooting.md new file mode 100644 index 0000000000..da916dcc22 --- /dev/null +++ b/docs/user/Troubleshooting.md @@ -0,0 +1,141 @@ +# GraalPy Troubleshooting + +[[TOC]] + +## GraalPy Embedding + +#### VirtualFileSystem cannot load a file +There are situations where a file cannot be loaded even though it is part of the Virtual Filesystem resources. +GraalPy tries to prevent such situations by automatically [extracting](Embedding-Build-Tools.md#extracting-files-from-virtual-filesystem) +some well known files to the real filesystem, but if you see an error like: +``` +ImportError: cannot load /graalpy_vfs/venv/lib/python3.11/site-packages/_cffi_backend.graalpy250dev09433ef706-311-native-aarch64-darwin.so: +NFIUnsatisfiedLinkError: dlopen(/graalpy_vfs/venv/lib/python3.11/site-packages/_cffi_backend.graalpy250dev09433ef706-311-native-aarch64-darwin.so, 0x0002): +``` +then the default behavior did not work as intended. + +Depending on how you [deploy Python resources](Embedding-Build-Tools.md#deployment) in your application, you can try one of the following: +- if you need to package resources within your Jar or Native Image executable: + - if the problematic file is not one of the following types: `.so`, `.dylib`, `.pyd`, `.dll`, or `.ttf`, which are extracted to + the real filesystem by default, you can simply attempt to add it to the extraction filter using: + ```java + VirtualFileSystem.Builder.extractFilter(filter); + ``` + - if the previous does not help, it is also possible to extract all Python resources into a user-defined directory before creating a GraalPy + context, and then configure the context to use that directory: + ```java + // extract the Python resources from the jar or native image into a given directory + GraalPyResources.extractVirtualFileSystemResources(VirtualFileSystem.create(), externalResourceDirectoryPath); + // create a GraalPy context configured with an external Python resource directory + Context context = GraalPyResources.contextBuilder(externalResourceDirectoryPath).build(); + ``` +- or if you're able to ship resources in a separate directory, you have to set the `externalDirectory` tag in + [Maven](Embedding-Build-Tools.md#graalpy-maven-plugin) or `externalDirectory` field in [Gradle](Embedding-Build-Tools.md#graalpy-gradle-plugin) + and also configure the GraalPy context to use that directory as well: + ```java + // create a Context configured with an external Python resource directory + Context context = GraalPyResources.contextBuilder(externalResourceDirectoryPath).build(); + ``` + Please **note**, that if switching from Virtual FileSystem to an external directory, also all **user files** from the previous + Virtual FileSystem resource root have to be moved into that directory as well. + +For more details about the Python resources in GraalPy Embedding please refer to the [Embedding Build Tools](Embedding-Build-Tools.md) documentation. + +For more details about GraalPy context and Virtual FileSystem configuration please refer to [GraalPyResources](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java) and +[VirtualFileSystem](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/VirtualFileSystem.java) javadoc. + +#### Issues with GraalPy 'java' posix backend +The Virtual FileSystem is built on the Truffle filesystem and relies on the GraalPy Java POSIX backend. +Unfortunately, certain Python packages bypass Python's I/O and directly access files through their +native extensions. If you encounter an error like: +``` +NotImplementedError: 'PyObject_AsFileDescriptor' not supported when using 'java' posix backend +``` +then you have to override the default `java` GraalPy backend option byt setting the `native` POSIX backend +and completely omit the Virtual FileSystem at runtime. + +Depending on how you [deploy Python resources](Embedding-Build-Tools.md#deployment) in your application, +you can do one of the following: + +- if you need to package Python resources within your Jar or Native Image executable, then: + ```java + // extract the Python resources from the jar or native image into a given directory + GraalPyResources.extractVirtualFileSystemResources(VirtualFileSystem.create(), externalResourceDirectoryPath); + // create a Context.Builder configured with an external python resource directory + Builder builder = GraalPyResources.contextBuilder(externalResourceDirectoryPath); + // override the python.PosixModuleBackend option with "native" + builder.option("python.PosixModuleBackend", "native"); + // create a context + Context context = builder.build(); + ``` +- or if you're able to ship Python resources in a separate directory, you have to set the `externalDirectory` tag in + [Maven](Embedding-Build-Tools.md#graalpy-maven-plugin) or `externalDirectory` field in [Gradle](Embedding-Build-Tools.md#graalpy-gradle-plugin) + and configure the GraalPy context accordingly: + ```java + // create a Context.Builder configured with an external python resource directory + Builder builder = GraalPyResources.contextBuilder(externalResourceDirectoryPath); + // override the python.PosixModuleBackend option with "native" + builder.option("python.PosixModuleBackend", "native"); + // create a context + Context context = builder.build(); + ``` + Please **note**, that if switching from Virtual FileSystem to an external directory, also all **user files** from the previous + Virtual FileSystem resource root have to be moved into that directory as well. + +For more details about the Python resources in GraalPy Embedding please refer to the [Embedding Build Tools](Embedding-Build-Tools.md) documentation. + +For more details about GraalPy context and Virtual FileSystem configuration please refer to [GraalPyResources](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java) and +[VirtualFileSystem](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/VirtualFileSystem.java) javadoc. + +### Maven and Gradle applications + +#### ImportError reports "unknown location" +A possible cause of an `ImportError` ending with `(unknown location)` when running a GraalPy Java Embedding project might be +that an embedded Python package was built for a different operating system. If you see an error like the following: +``` +ImportError: cannot import name 'exceptions' from 'cryptography.hazmat.bindings._rust' (unknown location) +``` +You probably need to rebuild your project on the correct operating system before running it. + +#### GraalVM JDK Compatibility +To enable runtime compilation when running GraalPy from a Maven or Gradle application, +you must use versions of GraalPy and the Polyglot API dependencies that are compatible +with the specified GraalVM JDK version. If you see errors like the following: + +``` +Your Java runtime '23.0.1+11-jvmci-b01' with compiler version '24.1.1' is incompatible with polyglot version '24.1.0'. +``` +You need to keep the versions of your GraalPy and Polyglot dependencies according to the error message, +so either upgrade the version of your JDK or your polyglot and GraalPy dependencies. + +Note, this can also apply to cases when your dependencies are transitively pulled in by another artifact, +e.g. micronaut-graalpy. + +#### The following artifacts could not be resolved: org.graalvm.python:python-language-enterprise +`python-language-enterprise` was discontinued, use `org.graalvm.polyglot:python` instead. + +#### Issues with Meson build system when installing Python packages on OSX with Maven or Gradle GraalPy plugin +Errors like the following: +``` +../meson.build:1:0: ERROR: Failed running 'cython', binary or interpreter not executable. +``` + +could be caused by the GraalPy launcher used internally by the Maven or Gradle GraalPy plugin +for installing Python packages. Currently, there is no straightforward solution. However, +a workaround is to set the Java system property graalpy.vfs.venvLauncher to a launcher from +a downloaded [GraalPy](https://github.com/oracle/graalpython/releases/) distribution with a version +matching the GraalPy Maven artifacts version. + +e.g. +``` +mvn package -Dgraalpy.vfs.venvLauncher={graalpy_directroy}/Contents/Home/bin/graalpy +``` + +#### No language and polyglot implementation was found on the module-path. +If you see an error like: +``` +java.lang.IllegalStateException: No language and polyglot implementation was found on the module-path. Make sure at last one language is added to the module-path. +``` +you are probably missing the python langauge dependency in your Maven of Gradle configuration file. +You need to add either `org.graalvm.polyglot:python` or `org.graalvm.polyglot:python-community` to your dependencies. + diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/advanced/CustomBuiltinsTest.java b/graalpython/com.oracle.graal.python.annotations/src/com/oracle/graal/python/annotations/HashNotImplemented.java similarity index 75% rename from graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/advanced/CustomBuiltinsTest.java rename to graalpython/com.oracle.graal.python.annotations/src/com/oracle/graal/python/annotations/HashNotImplemented.java index c6970a1416..8e29954896 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/advanced/CustomBuiltinsTest.java +++ b/graalpython/com.oracle.graal.python.annotations/src/com/oracle/graal/python/annotations/HashNotImplemented.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,15 +38,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.test.advanced; +package com.oracle.graal.python.annotations; -import org.junit.Test; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; -import com.oracle.graal.python.test.PythonTests; - -public class CustomBuiltinsTest extends PythonTests { - @Test - public void testCustomBuiltinModule() { - assertPrints("success\n", "import CustomModule; print(CustomModule.success)"); - } +/** + * Indicates that the annotated class inheriting {@code PythonBuiltins} should have slot + * {@code tp_hash} filled with the {@code PyObject_HashNotImplemented} placeholder. There is some + * special inheritance semantics for this specific slot value. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface HashNotImplemented { } diff --git a/graalpython/com.oracle.graal.python.annotations/src/com/oracle/graal/python/annotations/Slot.java b/graalpython/com.oracle.graal.python.annotations/src/com/oracle/graal/python/annotations/Slot.java index bf54294c82..e4deb40dd7 100644 --- a/graalpython/com.oracle.graal.python.annotations/src/com/oracle/graal/python/annotations/Slot.java +++ b/graalpython/com.oracle.graal.python.annotations/src/com/oracle/graal/python/annotations/Slot.java @@ -76,19 +76,28 @@ */ @Retention(RetentionPolicy.RUNTIME) @interface SlotSignature { + /** + * Used to supply the function name for error messages from argument parsing. + */ + String name() default ""; + int minNumOfPositionalArgs() default 0; + int maxNumOfPositionalArgs() default -1; + + int numOfPositionalOnlyArgs() default -1; + boolean takesVarArgs() default false; boolean takesVarKeywordArgs() default false; String[] parameterNames() default {}; + String[] keywordOnlyNames() default {}; + boolean needsFrame() default false; boolean alwaysNeedsCallerFrame() default false; - - String raiseErrorName() default ""; } /** See slot documentation */ @@ -135,6 +144,34 @@ enum SlotKind { nb_true_divide("__truediv__, __rtruediv__"), /** foo @ bar */ nb_matrix_multiply("__matmul__, __rmatmul__"), + /** foo ** bar */ + nb_power("__pow__, __rpow__"), + /** foo += bar */ + nb_inplace_add("__iadd__"), + /** foo -= bar */ + nb_inplace_subtract("__isub__"), + /** foo *= bar */ + nb_inplace_multiply("__imul__"), + /** foo %= bar */ + nb_inplace_remainder("__imod__"), + /** foo <<= bar */ + nb_inplace_lshift("__ilshift__"), + /** foo >>= bar */ + nb_inplace_rshift("__irshift__"), + /** foo &= bar */ + nb_inplace_and("__iand__"), + /** foo ^= bar */ + nb_inplace_xor("__ixor__"), + /** foo |= bar */ + nb_inplace_or("__ior__"), + /** foo //= bar */ + nb_inplace_floor_divide("__ifloordiv__"), + /** foo /= bar */ + nb_inplace_true_divide("__itruediv__"), + /** foo @= bar */ + nb_inplace_matrix_multiply("__imatmul__"), + /** foo **= bar */ + nb_inplace_power("__ipow__"), /** sequence length/size */ sq_length("__len__"), /** sequence item: read element at index */ @@ -145,20 +182,46 @@ enum SlotKind { sq_concat("__add__"), /** seq * number, nb_multiply is tried before */ sq_repeat("__mul__"), + /** seq += seq */ + sq_inplace_concat("__iadd__"), + /** seq *= seq */ + sq_inplace_repeat("__imul__"), + /** item in seq **/ + sq_contains("__contains__"), /** mapping length */ mp_length("__len__"), /** mapping subscript, e.g. o[key], o[i:j] */ mp_subscript("__getitem__"), /** o[key] = value */ mp_ass_subscript("__setitem__"), + /** comparison operations: >,=>, ==, !=, <, <= */ + tp_richcompare("__lt__, __le__, __eq__, __ne__, __gt__, __ge__"), /** type descriptor get */ tp_descr_get("__get__"), /** type descriptor set/delete */ tp_descr_set("__set__, __delete__"), + /** + * hash code. See also if {@link HashNotImplemented} is not more appropriate. + */ + tp_hash("__hash__"), /** get object attribute */ tp_getattro("__getattribute__, __getattr__"), /** set/delete object attribute */ - tp_setattro("__setattr__, __delattr__"); + tp_setattro("__setattr__, __delattr__"), + /** iter(obj) */ + tp_iter("__iter__"), + /** next(obj) */ + tp_iternext("__next__"), + /** str(obj) */ + tp_str("__str__"), + /** repr(obj) */ + tp_repr("__repr__"), + tp_init("__init__"), + tp_new("__new__"), + tp_call("__call__"), + am_await("__await__"), + am_aiter("__aiter__"), + am_anext("__anext__"); SlotKind(@SuppressWarnings("unused") String specialMethods) { } diff --git a/graalpython/com.oracle.graal.python.benchmarks/python/harness.py b/graalpython/com.oracle.graal.python.benchmarks/python/harness.py index 8d66b5e47f..2de6bbdcbc 100644 --- a/graalpython/com.oracle.graal.python.benchmarks/python/harness.py +++ b/graalpython/com.oracle.graal.python.benchmarks/python/harness.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -270,9 +270,10 @@ def get_bench_module(bench_file): name = bench_file.rpartition(os.sep)[2].partition(".")[0].replace('.py', '') directory = bench_file.rpartition(os.sep)[0] pkg = [] - while any(f.endswith("__init__.py") for f in os.listdir(directory)): - directory, slash, postfix = directory.rpartition("/") - pkg.insert(0, postfix) + if directory: + while any(f.endswith("__init__.py") for f in os.listdir(directory)): + directory, slash, postfix = directory.rpartition("/") + pkg.insert(0, postfix) if pkg: sys.path.insert(0, directory) @@ -501,6 +502,9 @@ def run_benchmark(args): else: print("### no extra module search paths specified") + if GRAALPYTHON: + print(f"### using bytecode DSL interpreter: {__graalpython__.is_bytecode_dsl_interpreter}") + BenchRunner(bench_file, bench_args=bench_args, iterations=iterations, warmup=warmup, warmup_runs=warmup_runs, startup=startup, live_results=live_results).run() diff --git a/scripts/gate_python_test.sh b/graalpython/com.oracle.graal.python.benchmarks/python/heap/allocate-objects.py old mode 100755 new mode 100644 similarity index 81% rename from scripts/gate_python_test.sh rename to graalpython/com.oracle.graal.python.benchmarks/python/heap/allocate-objects.py index 7ec00cf8b7..64eb36ed03 --- a/scripts/gate_python_test.sh +++ b/graalpython/com.oracle.graal.python.benchmarks/python/heap/allocate-objects.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,8 +37,15 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -# mx --strict-compliance --dynamicimports sulong --primary gate --tags python-junit,python-unittest -# -# DEFAULT_DYNAMIC_IMPORTS="sulong,/compiler" -mx --strict-compliance --dynamicimports sulong,/compiler --primary gate --tags python-junit -B=--force-deprecation-as-warning-for-dependencies -# mx --dynamicimports /compiler python-gate --tags python-junit,python-unittest +import time + +class MyObject: + def __init__(self, name, value): + self.name = name + self.value = value + +objects = [MyObject("foo", 42) for i in range(10 ** 6)] + +# Sleep a bit to shake out weakref callbacks and get more measurement samples +for i in range(30): + time.sleep(0.1) diff --git a/graalpython/com.oracle.graal.python.benchmarks/python/heap/import-a-lot.py b/graalpython/com.oracle.graal.python.benchmarks/python/heap/import-a-lot.py new file mode 100644 index 0000000000..e609712a8c --- /dev/null +++ b/graalpython/com.oracle.graal.python.benchmarks/python/heap/import-a-lot.py @@ -0,0 +1,72 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# Measure the heap after importing many modules +import time +import urllib.request, urllib.parse +import pickle +import os +import xmlrpc +import json +import email +import multiprocessing +import re +import concurrent.futures +import collections +import inspect +import hashlib +import decimal +import fractions +import unittest +import contextlib +import configparser +import tomllib +import argparse +import subprocess +import sys + +# We log the bytecode DSL flag only in this benchamark, because we do not want to influence +# the other benchmarks by importing the sys module. Other benchmarks will print a warning +# that bytecode DSL flag could not be verified +if getattr(getattr(sys, "implementation", None), "name", None) == "graalpy": + print(f"### using bytecode DSL interpreter: {__graalpython__.is_bytecode_dsl_interpreter}") + +# Sleep a bit to shake out weakref callbacks and get more measurement samples +for i in range(30): + time.sleep(0.1) diff --git a/graalpython/com.oracle.graal.python.benchmarks/python/heap/post-startup.py b/graalpython/com.oracle.graal.python.benchmarks/python/heap/post-startup.py new file mode 100644 index 0000000000..109dace077 --- /dev/null +++ b/graalpython/com.oracle.graal.python.benchmarks/python/heap/post-startup.py @@ -0,0 +1,45 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# Measure the heap after startup +import time + +# Sleep a bit to shake out weakref callbacks and get more measurement samples +for i in range(30): + time.sleep(0.1) diff --git a/graalpython/com.oracle.graal.python.cext/CEXT-WINDOWS-README.md b/graalpython/com.oracle.graal.python.cext/CEXT-WINDOWS-README.md deleted file mode 100644 index 26fb62009f..0000000000 --- a/graalpython/com.oracle.graal.python.cext/CEXT-WINDOWS-README.md +++ /dev/null @@ -1 +0,0 @@ -C extensions on Windows not supported yet diff --git a/graalpython/com.oracle.graal.python.cext/CMakeLists.txt b/graalpython/com.oracle.graal.python.cext/CMakeLists.txt index 6359abef77..dafc8d0f1f 100644 --- a/graalpython/com.oracle.graal.python.cext/CMakeLists.txt +++ b/graalpython/com.oracle.graal.python.cext/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2023, 2024, Oracle and/or its affiliates. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. # # All rights reserved. # @@ -37,17 +37,9 @@ endfunction() set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -if(MSVC) - message(FATAL_ERROR "C API cannot be built with MSVC") -endif() - -if(WIN32) - require_var(GRAALVM_LLVM_LIB_DIR) -endif() require_var(GRAALPY_PARENT_DIR) require_var(CAPI_INC_DIR) require_var(PYCONFIG_INCLUDE_DIR) -require_var(TRUFFLE_H_INC) require_var(TRUFFLE_NFI_H_INC) require_var(GRAALPY_EXT) @@ -61,31 +53,67 @@ set(TARGET_LIBPYTHON "python-native") # common variables and compile/link options (for all build targets) ###################################################################### -set(CFLAGS_WARNINGS -Wall -Werror,-Wunknown-warning-option -Wno-unused-function -Wno-unused-variable -Wno-unused-const-variable +if (MSVC) + SET(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "" FORCE) + SET(CFLAGS_WARNINGS /Wall /WX + # Many warnings that are just MSVC being a bit pedantic + /wd4255 # no function prototype given: converting '()' to '(void)' + /wd4820 # padding added after data member + /wd4100 # unreferenced formal parameter + /wd4200 # nonstandard extension used: zero-sized array in struct/union + /wd4996 # This function or variable may be unsafe ... see _CRT_SECURE_NO_WARNINGS + /wd4668 # ... is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' + /wd4115 # named type definition in parentheses + /wd4152 # nonstandard extension, function/data pointer conversion in expression + /wd5045 # Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified + /wd4047 # 'int64_t' differs in levels of indirection from 'char []' / 'void *' + /wd4242 # conversion from 'int' to 'char', possible loss of data + /wd4244 # conversion from 'long' to 'char', possible loss of data + /wd4267 # conversion from 'size_t' to 'int', possible loss of data + /wd4127 # conditional expression is constant + /wd4702 # unreachable code + /wd4101 # unreferenced local variable + /wd4456 # declaration hides previous local declaration + /wd4459 # declaration hides global declaration + /wd4061 # enumerator X in switch of enum Y is not explicitly handled by a case label + /wd4464 # relative include path contains '..' + /wd4710 # 'fprintf': function not inlined + /wd4706 # assignment within conditional expression + + # Some that I'm not so happy about + /wd4232 # sre: nonstandard extension used: 'ml_meth': address of dllimport 'Py_GenericAlias' is not static, identity not guaranteed + /wd4191 # sre and sqlite: 'type cast': like unsafe conversion from 'PyObject *(__cdecl *)(MatchObject *,PyObject *const *,Py_ssize_t)' to 'void (__cdecl *)(void)' + /wd4918 # sre: invalid character in pragma optimization list + /wd4701 # cpython_unicodedata: potentially uninitialized local variable 'rc' used + /wd4574 # sqlite: 'SQLITE_ATOMIC_INTRINSICS' is defined to be '0': did you mean to use '#if SQLITE_ATOMIC_INTRINSICS'? + /wd4310 # xmlparse: cast truncates constant value + ) +else() + set(CFLAGS_WARNINGS -Wall -Werror -Wno-unused-function -Wno-unused-variable -Wno-unused-const-variable + -Wno-unknown-warning-option + -Wno-discarded-qualifiers # _testbuffer.c -Wno-tautological-constant-out-of-range-compare # fileutils.c: wchar_t > MAX_UNICODE is always false on Windows -Wno-unused-but-set-variable # sqlite.c: BOOL bRc -Wno-ignored-pragmas # sre.c: #pragma optimize("agtw", on) - -Wno-discarded-qualifiers # longobject.c: *pend = str; (gcc only hence: '-Wunknown-warning-option') -Wno-int-to-pointer-cast -Wno-int-conversion -Wno-void-pointer-to-int-cast - -Wno-incompatible-pointer-types-discards-qualifiers -Wno-pointer-type-mismatch + -Wno-incompatible-pointer-types-discards-qualifiers -Wno-braced-scalar-init -Wno-deprecated-declarations) + add_compile_options(-ffile-prefix-map=${GRAALPY_PARENT_DIR}=.) +endif() -add_compile_options(-ffile-prefix-map=${GRAALPY_PARENT_DIR}=.) # preprocessor defines for all platforms add_compile_definitions( NDEBUG - GRAALVM_PYTHON_LLVM ) -add_compile_definitions(GRAALVM_PYTHON_LLVM_NATIVE) - if(WIN32) add_compile_definitions( MS_WINDOWS Py_ENABLE_SHARED HAVE_DECLSPEC_DLL + ) endif() @@ -155,7 +183,6 @@ include_directories( "${SRC_DIR}/include" "${CAPI_INC_DIR}" "${PYCONFIG_INCLUDE_DIR}" - "${TRUFFLE_H_INC}" "${TRUFFLE_NFI_H_INC}" ) @@ -261,9 +288,9 @@ target_compile_definitions(${TARGET_LIBPYTHON} PRIVATE Py_BUILD_CORE Py_BUILD_CO target_compile_options(${TARGET_LIBPYTHON} PRIVATE ${CFLAGS_WARNINGS}) if(WIN32) - target_link_directories(${TARGET_LIBPYTHON} PRIVATE ${GRAALVM_LLVM_LIB_DIR}) - target_compile_options(${TARGET_LIBPYTHON} PRIVATE "-fmsc-version=1920") - target_link_libraries(${TARGET_LIBPYTHON} sulong-native graalvm-llvm) + if (NOT MSVC) + target_compile_options(${TARGET_LIBPYTHON} PRIVATE "-fmsc-version=1920") + endif() else() # Link to math library; required for functions like 'hypot' or similar target_link_libraries(${TARGET_LIBPYTHON} m) diff --git a/graalpython/com.oracle.graal.python.cext/expat/winconfig.h b/graalpython/com.oracle.graal.python.cext/expat/winconfig.h index 2ecd61b5b9..f3e6a9c06c 100644 --- a/graalpython/com.oracle.graal.python.cext/expat/winconfig.h +++ b/graalpython/com.oracle.graal.python.cext/expat/winconfig.h @@ -42,4 +42,6 @@ #include #include +#include "expat_config.h" + #endif /* ndef WINCONFIG_H */ diff --git a/graalpython/com.oracle.graal.python.cext/include/cpython/tupleobject.h b/graalpython/com.oracle.graal.python.cext/include/cpython/tupleobject.h index ef3d3c3790..e5d9ea8436 100644 --- a/graalpython/com.oracle.graal.python.cext/include/cpython/tupleobject.h +++ b/graalpython/com.oracle.graal.python.cext/include/cpython/tupleobject.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2020, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2020 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -39,14 +39,9 @@ PyAPI_FUNC(PyObject *) _PyTuple_GET_ITEM(PyObject *, Py_ssize_t); // GraalPy-specific PyAPI_FUNC(PyObject **) PyTruffleTuple_GetItems(PyObject *op); -/* Function *only* to be used to fill in brand new tuples */ -static inline void -PyTuple_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) { - PyTruffleTuple_GetItems(op)[index] = value; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 +// GraalPy change: Export PyTuple_SET_ITEM as regular API function to use in PyO3 and others +PyAPI_FUNC(void) PyTuple_SET_ITEM(PyObject*, Py_ssize_t, PyObject*); #define PyTuple_SET_ITEM(op, index, value) \ - PyTuple_SET_ITEM(_PyObject_CAST(op), index, _PyObject_CAST(value)) -#endif + PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value)) PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out); diff --git a/graalpython/com.oracle.graal.python.cext/include/internal/pycore_gc.h b/graalpython/com.oracle.graal.python.cext/include/internal/pycore_gc.h index 2e3f0fda5f..ef2771a7a7 100644 --- a/graalpython/com.oracle.graal.python.cext/include/internal/pycore_gc.h +++ b/graalpython/com.oracle.graal.python.cext/include/internal/pycore_gc.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2022, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2022, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2022 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -174,7 +174,8 @@ struct _gc_runtime_state { extern void _PyGC_InitState(struct _gc_runtime_state *); -extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate); +// GraalPy change: exporting _PyGC_CollectNoFail +extern PyAPI_FUNC(Py_ssize_t) _PyGC_CollectNoFail(PyThreadState *tstate); // Functions to clear types free lists diff --git a/graalpython/com.oracle.graal.python.cext/include/internal/pycore_global_objects.h b/graalpython/com.oracle.graal.python.cext/include/internal/pycore_global_objects.h index c3dc82f453..ff8cb933c7 100644 --- a/graalpython/com.oracle.graal.python.cext/include/internal/pycore_global_objects.h +++ b/graalpython/com.oracle.graal.python.cext/include/internal/pycore_global_objects.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2024, Oracle and/or its affiliates. +/* Copyright (c) 2024, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2023 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -53,6 +53,7 @@ struct _Py_global_objects { _PyGC_Head_UNUSED _tuple_empty_gc_not_used; PyTupleObject tuple_empty; */ + char GraalDummyField; } singletons; }; diff --git a/graalpython/com.oracle.graal.python.cext/include/internal/pycore_object.h b/graalpython/com.oracle.graal.python.cext/include/internal/pycore_object.h index 2878dd1605..36f6e95602 100644 --- a/graalpython/com.oracle.graal.python.cext/include/internal/pycore_object.h +++ b/graalpython/com.oracle.graal.python.cext/include/internal/pycore_object.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2022, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2022, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2022 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -251,7 +251,7 @@ _PyType_PreHeaderSize(PyTypeObject *tp) void _PyObject_GC_Link(PyObject *op); -void _GraalPyObject_GC_NotifyOwnershipTransfer(PyObject *op); +PyAPI_FUNC(void) _GraalPyObject_GC_NotifyOwnershipTransfer(PyObject *op); // Usage: assert(_Py_CheckSlotResult(obj, "__getitem__", result != NULL)); extern int _Py_CheckSlotResult( diff --git a/graalpython/com.oracle.graal.python.cext/include/object.h b/graalpython/com.oracle.graal.python.cext/include/object.h index 7d88c22cb1..a427c70040 100644 --- a/graalpython/com.oracle.graal.python.cext/include/object.h +++ b/graalpython/com.oracle.graal.python.cext/include/object.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2018, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2020 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -124,7 +124,9 @@ typedef struct { // Test if the 'x' object is the 'y' object, the same as "x is y" in Python. PyAPI_FUNC(int) Py_Is(PyObject *x, PyObject *y); +#if 0 // GraalPy change #define Py_Is(x, y) ((x) == (y)) +#endif // GraalPy change PyAPI_FUNC(Py_ssize_t) PyTruffle_REFCNT(PyObject *ob); diff --git a/graalpython/com.oracle.graal.python.cext/include/pythonrun.h b/graalpython/com.oracle.graal.python.cext/include/pythonrun.h index e14625daae..95d64fbcc9 100644 --- a/graalpython/com.oracle.graal.python.cext/include/pythonrun.h +++ b/graalpython/com.oracle.graal.python.cext/include/pythonrun.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, 2023, Oracle and/or its affiliates. +/* Copyright (c) 2018, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2020 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -27,11 +27,13 @@ PyAPI_DATA(int) (*PyOS_InputHook)(void); to an 8k margin. */ #define PYOS_STACK_MARGIN 2048 +#if 0 // GraalPy change #if defined(WIN32) && !defined(MS_WIN64) && !defined(_M_ARM) && defined(_MSC_VER) && _MSC_VER >= 1300 /* Enable stack checking under Microsoft C */ // When changing the platforms, ensure PyOS_CheckStack() docs are still correct #define USE_STACKCHECK #endif +#endif #ifdef USE_STACKCHECK /* Check that we aren't overflowing our stack */ diff --git a/graalpython/com.oracle.graal.python.cext/modules/_cpython_sre/sre.c b/graalpython/com.oracle.graal.python.cext/modules/_cpython_sre/sre.c index db0e8e2831..126594b905 100644 --- a/graalpython/com.oracle.graal.python.cext/modules/_cpython_sre/sre.c +++ b/graalpython/com.oracle.graal.python.cext/modules/_cpython_sre/sre.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2018, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2020 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -1052,19 +1052,6 @@ _sre_SRE_Pattern_split_impl(PatternObject *self, PyObject *string, } -__attribute__((always_inline)) -inline static void *_memchr(const void *s, int c, Py_ssize_t n) { - unsigned char *p = (unsigned char*)s; - while(n--) { - if(*p != (unsigned char)c) { - p++; - } else { - return p; - } - } - return 0; -} - static PyObject* pattern_subx(_sremodulestate* module_state, PatternObject* self, @@ -1099,7 +1086,7 @@ pattern_subx(_sremodulestate* module_state, ptr = getstring(ptemplate, &n, &isbytes, &charsize, &view); if (ptr) { if (charsize == 1) - literal = _memchr(ptr, '\\', n) == NULL; + literal = memchr(ptr, '\\', n) == NULL; else literal = PyUnicode_FindChar(ptemplate, '\\', 0, n, 1) == -1; } else { diff --git a/graalpython/com.oracle.graal.python.cext/src/abstract.c b/graalpython/com.oracle.graal.python.cext/src/abstract.c index de966ccf55..52f1a1fd6d 100644 --- a/graalpython/com.oracle.graal.python.cext/src/abstract.c +++ b/graalpython/com.oracle.graal.python.cext/src/abstract.c @@ -7,8 +7,8 @@ #include "Python.h" #include "capi.h" // GraalPy change -#if 0 // GraalPy change #include "pycore_abstract.h" // _PyIndex_Check() +#if 0 // GraalPy change #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() #include "pycore_object.h" // _Py_CheckSlotResult() @@ -22,37 +22,6 @@ #include // offsetof() -// GraalPy-specific -typedef enum e_binop { - ADD=0, SUB, MUL, TRUEDIV, LSHIFT, RSHIFT, OR, AND, XOR, FLOORDIV, MOD, - INPLACE_OFFSET, MATRIX_MUL -} BinOp; - -// GraalPy-specific -typedef enum e_unaryop { - POS=0, NEG, INVERT -} UnaryOp; - -// GraalPy-specific -static PyObject * -do_unaryop(PyObject *v, UnaryOp unaryop) -{ - return GraalPyTruffleNumber_UnaryOp(v, (int) unaryop); -} - -// GraalPy-specific -MUST_INLINE static PyObject * -do_binop(PyObject *v, PyObject *w, BinOp binop) -{ - return GraalPyTruffleNumber_BinOp(v, w, (int) binop); -} - -// GraalPy-specific -MUST_INLINE static PyObject * -do_inplace_binop(PyObject *v, PyObject *w, BinOp binop) -{ - return GraalPyTruffleNumber_InPlaceBinOp(v, w, (int) binop); -} /* Shorthands to return certain errors */ @@ -875,6 +844,7 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) Py_XDECREF(empty); return result; } +#endif // GraalPy /* Operations on numbers */ int @@ -885,7 +855,6 @@ PyNumber_Check(PyObject *o) PyNumberMethods *nb = Py_TYPE(o)->tp_as_number; return nb && (nb->nb_index || nb->nb_int || nb->nb_float || PyComplex_Check(o)); } -#endif // GraalPy /* Binary operators */ @@ -983,7 +952,7 @@ binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name) if (result == Py_NotImplemented) { Py_DECREF(result); - if (op_slot == NB_SLOT(nb_rshift) && + if (op_slot == (int)NB_SLOT(nb_rshift) && PyCFunction_CheckExact(v) && strcmp(((PyCFunctionObject *)v)->m_ml->ml_name, "print") == 0) { @@ -1103,13 +1072,16 @@ ternary_op(PyObject *v, return NULL; } +// GraalPy change: upcall when both managed to save on doing multiple upcalls #define BINARY_FUNC(func, op, op_name) \ PyObject * \ func(PyObject *v, PyObject *w) { \ + if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) { \ + return GraalPyTruffle##func(v, w); \ + } \ return binary_op(v, w, NB_SLOT(op), op_name); \ } -#if 0 // GraalPy BINARY_FUNC(PyNumber_Or, nb_or, "|") BINARY_FUNC(PyNumber_Xor, nb_xor, "^") BINARY_FUNC(PyNumber_And, nb_and, "&") @@ -1117,16 +1089,30 @@ BINARY_FUNC(PyNumber_Lshift, nb_lshift, "<<") BINARY_FUNC(PyNumber_Rshift, nb_rshift, ">>") BINARY_FUNC(PyNumber_Subtract, nb_subtract, "-") BINARY_FUNC(PyNumber_Divmod, nb_divmod, "divmod()") -#endif // GraalPy change PyObject * PyNumber_Add(PyObject *v, PyObject *w) { - // GraalPy change: different implementation - return do_binop(v, w, ADD); + // GraalPy change: upcall when both managed to save on doing multiple upcalls + if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) { + return GraalPyTrufflePyNumber_Add(v, w); + } + PyObject *result = BINARY_OP1(v, w, NB_SLOT(nb_add), "+"); + if (result != Py_NotImplemented) { + return result; + } + Py_DECREF(result); + + PySequenceMethods *m = Py_TYPE(v)->tp_as_sequence; + if (m && m->sq_concat) { + result = (*m->sq_concat)(v, w); + assert(_Py_CheckSlotResult(v, "+", result != NULL)); + return result; + } + + return binop_type_error(v, w, "+"); } -#if 0 // GraalPy change static PyObject * sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n) { @@ -1145,47 +1131,77 @@ sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n) assert(_Py_CheckSlotResult(seq, "*", res != NULL)); return res; } -#endif // GraalPy change PyObject * PyNumber_Multiply(PyObject *v, PyObject *w) { - // GraalPy change: different implementation - return do_binop(v, w, MUL); + // GraalPy change: upcall when both managed to save on doing multiple upcalls + if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) { + return GraalPyTrufflePyNumber_Multiply(v, w); + } + PyObject *result = BINARY_OP1(v, w, NB_SLOT(nb_multiply), "*"); + if (result == Py_NotImplemented) { + PySequenceMethods *mv = Py_TYPE(v)->tp_as_sequence; + PySequenceMethods *mw = Py_TYPE(w)->tp_as_sequence; + Py_DECREF(result); + if (mv && mv->sq_repeat) { + return sequence_repeat(mv->sq_repeat, v, w); + } + else if (mw && mw->sq_repeat) { + return sequence_repeat(mw->sq_repeat, w, v); + } + result = binop_type_error(v, w, "*"); + } + return result; } PyObject * PyNumber_MatrixMultiply(PyObject *v, PyObject *w) { - // GraalPy change: different implementation - return do_binop(v, w, MATRIX_MUL); + // GraalPy change: upcall when both managed to save on doing multiple upcalls + if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) { + return GraalPyTrufflePyNumber_MatrixMultiply(v, w); + } + return binary_op(v, w, NB_SLOT(nb_matrix_multiply), "@"); } PyObject * PyNumber_FloorDivide(PyObject *v, PyObject *w) { - // GraalPy change: different implementation - return do_binop(v, w, FLOORDIV); + // GraalPy change: upcall when both managed to save on doing multiple upcalls + if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) { + return GraalPyTrufflePyNumber_FloorDivide(v, w); + } + return binary_op(v, w, NB_SLOT(nb_floor_divide), "//"); } PyObject * PyNumber_TrueDivide(PyObject *v, PyObject *w) { - // GraalPy change: different implementation - return do_binop(v, w, TRUEDIV); + // GraalPy change: upcall when both managed to save on doing multiple upcalls + if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) { + return GraalPyTrufflePyNumber_TrueDivide(v, w); + } + return binary_op(v, w, NB_SLOT(nb_true_divide), "/"); } PyObject * PyNumber_Remainder(PyObject *v, PyObject *w) { - // GraalPy change: different implementation - return do_binop(v, w, MOD); + // GraalPy change: upcall when both managed to save on doing multiple upcalls + if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) { + return GraalPyTrufflePyNumber_Remainder(v, w); + } + return binary_op(v, w, NB_SLOT(nb_remainder), "%"); } -#if 0 // GraalPy change PyObject * PyNumber_Power(PyObject *v, PyObject *w, PyObject *z) { + // GraalPy change: upcall when both managed to save on doing multiple upcalls + if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) { + return GraalPyTrufflePyNumber_Power(v, w, z); + } return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()"); } @@ -1273,9 +1289,13 @@ ternary_iop(PyObject *v, PyObject *w, PyObject *z, const int iop_slot, const int return ternary_op(v, w, z, op_slot, op_name); } +// GraalPy change: upcall when v is managed to avoid multiple upcalls #define INPLACE_BINOP(func, iop, op, op_name) \ PyObject * \ func(PyObject *v, PyObject *w) { \ + if (points_to_py_handle_space(v)) { \ + return GraalPyTruffle##func(v, w); \ + } \ return binary_iop(v, w, NB_SLOT(iop), NB_SLOT(op), op_name); \ } @@ -1289,26 +1309,74 @@ INPLACE_BINOP(PyNumber_InPlaceMatrixMultiply, nb_inplace_matrix_multiply, nb_mat INPLACE_BINOP(PyNumber_InPlaceFloorDivide, nb_inplace_floor_divide, nb_floor_divide, "//=") INPLACE_BINOP(PyNumber_InPlaceTrueDivide, nb_inplace_true_divide, nb_true_divide, "/=") INPLACE_BINOP(PyNumber_InPlaceRemainder, nb_inplace_remainder, nb_remainder, "%=") -#endif // GraalPy change PyObject * PyNumber_InPlaceAdd(PyObject *v, PyObject *w) { - // GraalPy change: different implementation - return do_inplace_binop(v, w, ADD); + // GraalPy change: upcall when v is managed to avoid multiple upcalls + if (points_to_py_handle_space(v)) { + return GraalPyTrufflePyNumber_InPlaceAdd(v, w); + } + PyObject *result = BINARY_IOP1(v, w, NB_SLOT(nb_inplace_add), + NB_SLOT(nb_add), "+="); + if (result == Py_NotImplemented) { + PySequenceMethods *m = Py_TYPE(v)->tp_as_sequence; + Py_DECREF(result); + if (m != NULL) { + binaryfunc func = m->sq_inplace_concat; + if (func == NULL) + func = m->sq_concat; + if (func != NULL) { + result = func(v, w); + assert(_Py_CheckSlotResult(v, "+=", result != NULL)); + return result; + } + } + result = binop_type_error(v, w, "+="); + } + return result; } PyObject * PyNumber_InPlaceMultiply(PyObject *v, PyObject *w) { - // GraalPy change: different implementation - return do_inplace_binop(v, w, MUL); + // GraalPy change: upcall when v is managed to avoid multiple upcalls + if (points_to_py_handle_space(v)) { + return GraalPyTrufflePyNumber_InPlaceMultiply(v, w); + } + PyObject *result = BINARY_IOP1(v, w, NB_SLOT(nb_inplace_multiply), + NB_SLOT(nb_multiply), "*="); + if (result == Py_NotImplemented) { + ssizeargfunc f = NULL; + PySequenceMethods *mv = Py_TYPE(v)->tp_as_sequence; + PySequenceMethods *mw = Py_TYPE(w)->tp_as_sequence; + Py_DECREF(result); + if (mv != NULL) { + f = mv->sq_inplace_repeat; + if (f == NULL) + f = mv->sq_repeat; + if (f != NULL) + return sequence_repeat(f, v, w); + } + else if (mw != NULL) { + /* Note that the right hand operand should not be + * mutated in this case so sq_inplace_repeat is not + * used. */ + if (mw->sq_repeat) + return sequence_repeat(mw->sq_repeat, w, v); + } + result = binop_type_error(v, w, "*="); + } + return result; } -# if 0 // GraalPy change PyObject * PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z) { + // GraalPy change: upcall when v is managed to avoid multiple upcalls + if (points_to_py_handle_space(v)) { + return GraalPyTrufflePyNumber_InPlacePower(v, w, z); + } return ternary_iop(v, w, z, NB_SLOT(nb_inplace_power), NB_SLOT(nb_power), "**="); } @@ -1318,33 +1386,60 @@ _PyNumber_InPlacePowerNoMod(PyObject *lhs, PyObject *rhs) { return PyNumber_InPlacePower(lhs, rhs, Py_None); } -#endif // GraalPy change - /* Unary operators and functions */ PyObject * PyNumber_Negative(PyObject *o) { - // GraalPy change: different implementation - return do_unaryop(o, NEG); + if (o == NULL) { + return null_error(); + } + + PyNumberMethods *m = Py_TYPE(o)->tp_as_number; + if (m && m->nb_negative) { + PyObject *res = (*m->nb_negative)(o); + assert(_Py_CheckSlotResult(o, "__neg__", res != NULL)); + return res; + } + + return type_error("bad operand type for unary -: '%.200s'", o); } PyObject * PyNumber_Positive(PyObject *o) { - // GraalPy change: different implementation - return do_unaryop(o, POS); + if (o == NULL) { + return null_error(); + } + + PyNumberMethods *m = Py_TYPE(o)->tp_as_number; + if (m && m->nb_positive) { + PyObject *res = (*m->nb_positive)(o); + assert(_Py_CheckSlotResult(o, "__pos__", res != NULL)); + return res; + } + + return type_error("bad operand type for unary +: '%.200s'", o); } PyObject * PyNumber_Invert(PyObject *o) { - // GraalPy change: different implementation - return do_unaryop(o, INVERT); + if (o == NULL) { + return null_error(); + } + + PyNumberMethods *m = Py_TYPE(o)->tp_as_number; + if (m && m->nb_invert) { + PyObject *res = (*m->nb_invert)(o); + assert(_Py_CheckSlotResult(o, "__invert__", res != NULL)); + return res; + } + + return type_error("bad operand type for unary ~: '%.200s'", o); } -# if 0 // GraalPy change PyObject * PyNumber_Absolute(PyObject *o) { @@ -1370,6 +1465,7 @@ PyIndex_Check(PyObject *obj) } +#if 0 // GraalPy change /* Return a Python int from the object item. Can return an instance of int subclass. Raise TypeError if the result is not an int @@ -2964,103 +3060,6 @@ _Py_FreeCharPArray(char *const array[]) } #endif // GraalPy change -// GraalPy note: The following functions are declared in CPython via macros, so we declare them separate here -PyObject * -PyNumber_Subtract(PyObject *v, PyObject *w) -{ - return do_binop(v, w, SUB); -} - -PyObject * -PyNumber_Lshift(PyObject *v, PyObject *w) -{ - return do_binop(v, w, LSHIFT); -} - -PyObject * -PyNumber_Rshift(PyObject *v, PyObject *w) -{ - return do_binop(v, w, RSHIFT); -} - -PyObject * -PyNumber_Or(PyObject *v, PyObject *w) -{ - return do_binop(v, w, OR); -} - -PyObject * -PyNumber_And(PyObject *v, PyObject *w) -{ - return do_binop(v, w, AND); -} - -PyObject * -PyNumber_Xor(PyObject *v, PyObject *w) -{ - return do_binop(v, w, XOR); -} - -PyObject * -PyNumber_InPlaceSubtract(PyObject *v, PyObject *w) -{ - return do_inplace_binop(v, w, SUB); -} - -PyObject * -PyNumber_InPlaceMatrixMultiply(PyObject *v, PyObject *w) -{ - return do_inplace_binop(v, w, MATRIX_MUL); -} - -PyObject * -PyNumber_InPlaceFloorDivide(PyObject *v, PyObject *w) -{ - return do_inplace_binop(v, w, FLOORDIV); -} - -PyObject * -PyNumber_InPlaceTrueDivide(PyObject *v, PyObject *w) -{ - return do_inplace_binop(v, w, TRUEDIV); -} - -PyObject* -PyNumber_InPlaceRemainder(PyObject *v, PyObject *w) -{ - return do_inplace_binop(v, w, MOD); -} - -PyObject* -PyNumber_InPlaceLshift(PyObject *v, PyObject *w) -{ - return do_inplace_binop(v, w, LSHIFT); -} - -PyObject* -PyNumber_InPlaceRshift(PyObject *v, PyObject *w) -{ - return do_inplace_binop(v, w, RSHIFT); -} - -PyObject* -PyNumber_InPlaceAnd(PyObject *v, PyObject *w) -{ - return do_inplace_binop(v, w, AND); -} - -PyObject* -PyNumber_InPlaceXor(PyObject *v, PyObject *w) -{ - return do_inplace_binop(v, w, XOR); -} - -PyObject* -PyNumber_InPlaceOr(PyObject *v, PyObject *w) -{ - return do_inplace_binop(v, w, OR); -} - // GraalPy additions PyObject ** PyTruffleSequence_Fast_ITEMS(PyObject *o) @@ -3075,6 +3074,6 @@ PyTruffleSequence_Fast_ITEMS(PyObject *o) PyObject* PyTruffleSequence_ITEM(PyObject* obj, Py_ssize_t index) { - PySequenceMethods* methods = Py_TYPE(obj)->tp_as_sequence; - return methods->sq_item(obj, index); + PySequenceMethods* methods = Py_TYPE(obj)->tp_as_sequence; + return methods->sq_item(obj, index); } diff --git a/graalpython/com.oracle.graal.python.cext/src/bytesobject.c b/graalpython/com.oracle.graal.python.cext/src/bytesobject.c index 5e18cba0a6..c3ff5c70ce 100644 --- a/graalpython/com.oracle.graal.python.cext/src/bytesobject.c +++ b/graalpython/com.oracle.graal.python.cext/src/bytesobject.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2024, Oracle and/or its affiliates. +/* Copyright (c) 2024, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2024 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -166,7 +166,7 @@ PyBytes_FromFormatV(const char *format, va_list vargs) (__buffer)[(__pos)++] = (__spec);\ } while(0) - for(int i=0; i < sizeof(buffer); i++) { + for(int i=0; i < (int)sizeof(buffer); i++) { buffer[i] = '\0'; } diff --git a/graalpython/com.oracle.graal.python.cext/src/call.c b/graalpython/com.oracle.graal.python.cext/src/call.c index edcdbe0aa0..bd837d6827 100644 --- a/graalpython/com.oracle.graal.python.cext/src/call.c +++ b/graalpython/com.oracle.graal.python.cext/src/call.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2023, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2023, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2022 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -87,7 +87,6 @@ _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable, } -#if 0 // GraalPy change int _Py_CheckSlotResult(PyObject *obj, const char *slot_name, int success) { @@ -110,7 +109,6 @@ _Py_CheckSlotResult(PyObject *obj, const char *slot_name, int success) } return 1; } -#endif // GraalPy change /* --- Core PyObject call functions ------------------------------- */ diff --git a/graalpython/com.oracle.graal.python.cext/src/capi.c b/graalpython/com.oracle.graal.python.cext/src/capi.c index c977055aa8..a06f7173a1 100644 --- a/graalpython/com.oracle.graal.python.cext/src/capi.c +++ b/graalpython/com.oracle.graal.python.cext/src/capi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -262,7 +262,7 @@ static int cdata_getbuffer(PyObject* type, Py_buffer* view, int flags) { } static void cdata_releasebuffer(PyObject* obj, Py_buffer* view) { - return GraalPyTruffleCData_ReleaseBuffer(obj, view); + GraalPyTruffleCData_ReleaseBuffer(obj, view); } PyAPI_FUNC(void) PyTruffleCData_InitBufferProtocol(PyObject* type) { @@ -374,86 +374,6 @@ int is_builtin_type(PyTypeObject *tp) { #undef PY_TRUFFLE_TYPE_UNIMPLEMENTED } -PyAPI_FUNC(int64_t) get_methods_flags(PyTypeObject *cls) { - if (cls == NULL) { - return 0; - } - - int64_t flags = 0; - PyNumberMethods* number = cls->tp_as_number; - if (number != NULL) { -#define COMPUTE_FLAGS(NAME, BIT_IDX) flags |= ((number->NAME != NULL) * BIT_IDX); - COMPUTE_FLAGS(nb_subtract, NB_SUBTRACT) - COMPUTE_FLAGS(nb_multiply, NB_MULTIPLY) - COMPUTE_FLAGS(nb_remainder, NB_REMAINDER) - COMPUTE_FLAGS(nb_divmod, NB_DIVMOD) - COMPUTE_FLAGS(nb_power, NB_POWER) - COMPUTE_FLAGS(nb_negative, NB_NEGATIVE) - COMPUTE_FLAGS(nb_positive, NB_POSITIVE) - COMPUTE_FLAGS(nb_absolute, NB_ABSOLUTE) - COMPUTE_FLAGS(nb_bool, NB_BOOL) - COMPUTE_FLAGS(nb_invert, NB_INVERT) - COMPUTE_FLAGS(nb_lshift, NB_LSHIFT) - COMPUTE_FLAGS(nb_rshift, NB_RSHIFT) - COMPUTE_FLAGS(nb_and, NB_AND) - COMPUTE_FLAGS(nb_xor, NB_XOR) - COMPUTE_FLAGS(nb_or, NB_OR) - COMPUTE_FLAGS(nb_int, NB_INT) - COMPUTE_FLAGS(nb_float, NB_FLOAT) - COMPUTE_FLAGS(nb_inplace_add, NB_INPLACE_ADD) - COMPUTE_FLAGS(nb_inplace_subtract, NB_INPLACE_SUBTRACT) - COMPUTE_FLAGS(nb_inplace_multiply, NB_INPLACE_MULTIPLY) - COMPUTE_FLAGS(nb_inplace_remainder, NB_INPLACE_REMAINDER) - COMPUTE_FLAGS(nb_inplace_power, NB_INPLACE_POWER) - COMPUTE_FLAGS(nb_inplace_lshift, NB_INPLACE_LSHIFT) - COMPUTE_FLAGS(nb_inplace_rshift, NB_INPLACE_RSHIFT) - COMPUTE_FLAGS(nb_inplace_and, NB_INPLACE_AND) - COMPUTE_FLAGS(nb_inplace_xor, NB_INPLACE_XOR) - COMPUTE_FLAGS(nb_inplace_or, NB_INPLACE_OR) - COMPUTE_FLAGS(nb_floor_divide, NB_FLOOR_DIVIDE) - COMPUTE_FLAGS(nb_true_divide, NB_TRUE_DIVIDE) - COMPUTE_FLAGS(nb_inplace_floor_divide, NB_INPLACE_FLOOR_DIVIDE) - COMPUTE_FLAGS(nb_inplace_true_divide, NB_INPLACE_TRUE_DIVIDE) - COMPUTE_FLAGS(nb_index, NB_INDEX) - COMPUTE_FLAGS(nb_matrix_multiply, NB_MATRIX_MULTIPLY) - COMPUTE_FLAGS(nb_inplace_matrix_multiply, NB_INPLACE_MATRIX_MULTIPLY) -#undef COMPUTE_FLAGS - } - - PySequenceMethods *sequence = cls->tp_as_sequence; - if (sequence != NULL) { -#define COMPUTE_FLAGS(NAME, BIT_IDX) flags |= ((sequence->NAME != NULL) * BIT_IDX); - COMPUTE_FLAGS(sq_length, SQ_LENGTH) - COMPUTE_FLAGS(sq_repeat, SQ_REPEAT) - COMPUTE_FLAGS(sq_item, SQ_ITEM) - COMPUTE_FLAGS(sq_ass_item, SQ_ASS_ITEM) - COMPUTE_FLAGS(sq_contains, SQ_CONTAINS) - COMPUTE_FLAGS(sq_inplace_concat, SQ_INPLACE_CONCAT) - COMPUTE_FLAGS(sq_inplace_repeat, SQ_INPLACE_REPEAT) -#undef COMPUTE_FLAGS - } - - PyMappingMethods *mapping = cls->tp_as_mapping; - if (mapping != NULL) { -#define COMPUTE_FLAGS(NAME, BIT_IDX) flags |= ((mapping->NAME != NULL) * BIT_IDX); - COMPUTE_FLAGS(mp_length, MP_LENGTH) - COMPUTE_FLAGS(mp_subscript, MP_SUBSCRIPT) - COMPUTE_FLAGS(mp_ass_subscript, MP_ASS_SUBSCRIPT) -#undef COMPUTE_FLAGS - } - - PyAsyncMethods *async = cls->tp_as_async; - if (async != NULL) { -#define COMPUTE_FLAGS(NAME, BIT_IDX) flags |= ((async->NAME != NULL) * BIT_IDX); - COMPUTE_FLAGS(am_await, AM_AWAIT) - COMPUTE_FLAGS(am_aiter, AM_AITER) - COMPUTE_FLAGS(am_anext, AM_ANEXT) - COMPUTE_FLAGS(am_send, AM_SEND) -#undef COMPUTE_FLAGS - } - return flags; -} - // not quite as in CPython, this assumes that x is already a double. The rest of // the implementation is in the Float constructor in Java PyAPI_FUNC(PyObject*) float_subtype_new(PyTypeObject *type, double x) { @@ -598,7 +518,7 @@ PyAPI_FUNC(size_t) PyTruffle_GetCurrentRSS() { // Linux FILE* fp = NULL; if ((fp = fopen( "/proc/self/statm", "r" )) != NULL) { - if (fscanf(fp, "%*s%ld", (long) &rss)) { + if (fscanf(fp, "%*s%ld", (long *) &rss)) { rss *= (uint64_t) sysconf( _SC_PAGESIZE); } fclose(fp); @@ -740,12 +660,7 @@ PyAPI_FUNC(int) WriteStringMember(void* object, Py_ssize_t offset, char* value) PyAPI_FUNC(int) WriteStringInPlaceMember(void* object, Py_ssize_t offset, char* value) { char *addr = (char*) (((char*) object) + offset); - size_t n; -// if (polyglot_has_array_elements(value)) { -// n = polyglot_get_array_size(value); -// } else { - n = strlen(value); -// } + size_t n = strlen(value); memcpy(addr, value, n); return 0; } @@ -847,11 +762,11 @@ PyAPI_FUNC(void*) truffle_ptr_convert(size_t value) { } PyAPI_FUNC(void*) truffle_ptr_add(void* x, Py_ssize_t y) { - return x + y; + return (char *)x + y; } PyAPI_FUNC(void) truffle_memcpy_bytes(void *dest, size_t dest_offset, void *src, size_t src_offset, size_t len) { - memcpy(dest + dest_offset, src + src_offset, len); + memcpy((char *)dest + dest_offset, (char *)src + src_offset, len); } PyAPI_FUNC(void*) truffle_calloc(size_t count, size_t elsize) { @@ -886,7 +801,7 @@ PyAPI_FUNC(int) tuffle_check_basesize_for_getstate(PyTypeObject* type, int slot_ if (type->tp_weaklistoffset) basicsize += sizeof(PyObject *); if (slot_num) - basicsize += sizeof(PyObject *) * PyList_GET_SIZE(slot_num); + basicsize += sizeof(PyObject *) * slot_num; return type->tp_basicsize > basicsize; } @@ -951,7 +866,7 @@ Py_LOCAL_SYMBOL TruffleContext* TRUFFLE_CONTEXT; * that do not work during context shutdown! (This means that it would be safe * to share this global across multiple contexts.) */ -Py_LOCAL_SYMBOL int32_t graalpy_finalizing; +Py_LOCAL_SYMBOL int8_t *_graalpy_finalizing = NULL; PyAPI_FUNC(void) initialize_graal_capi(TruffleEnv* env, void **builtin_closures, GCState *gc) { clock_t t = clock(); @@ -1007,48 +922,20 @@ PyAPI_FUNC(void) initialize_graal_capi(TruffleEnv* env, void **builtin_closures, /* * This function is called from Java during C API initialization to get the - * pointer `graalpy_finalizing`. + * pointer `_graalpy_finalizing`. */ -PyAPI_FUNC(int32_t *) GraalPy_get_finalize_capi_pointer() { - return &graalpy_finalizing; +PyAPI_FUNC(int8_t *) GraalPy_get_finalize_capi_pointer() { + assert(!_graalpy_finalizing); + // We actually leak this memory on purpose. On the Java side, this is + // written to in a VM shutdown hook. Once such a hook is registered it + // sticks around, so we're leaking those hooks anyway. 1 byte more to leak + // does not strike me (timfel) as significant. + _graalpy_finalizing = (int8_t *)calloc(1, sizeof(int8_t)); + return _graalpy_finalizing; } -#if ((__linux__ && __GNU_LIBRARY__) || __APPLE__) - -#include -#include -#include - -static void print_c_stacktrace() { - size_t max_stack_size = 16; - void* stack = calloc(sizeof(void*), max_stack_size); - if (stack == NULL) { - return; - } - - size_t stack_size = backtrace(stack, max_stack_size); - char** symbols = backtrace_symbols(stack, stack_size); - if (symbols == NULL) { - free(stack); - return; - } - - for (size_t i = 0; i < stack_size; i++) { - printf ("%s\n", symbols[i]); - } -} - -#else - -static void print_c_stacktrace() { - // other platforms are not supported -} - -#endif - static void unimplemented(const char* name) { printf("Function not implemented in GraalPy: %s\n", name); - printf("Native stacktrace:\n"); print_c_stacktrace(); } diff --git a/graalpython/com.oracle.graal.python.cext/src/capi.h b/graalpython/com.oracle.graal.python.cext/src/capi.h index 4429807808..b9ae1a05d5 100644 --- a/graalpython/com.oracle.graal.python.cext/src/capi.h +++ b/graalpython/com.oracle.graal.python.cext/src/capi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -157,7 +157,48 @@ PyAPI_DATA(uint32_t) Py_Truffle_Options; extern THREAD_LOCAL Py_LOCAL_SYMBOL PyThreadState *tstate_current; -extern Py_LOCAL_SYMBOL int graalpy_finalizing; +extern Py_LOCAL_SYMBOL int8_t *_graalpy_finalizing; +#define graalpy_finalizing (_graalpy_finalizing != NULL && *_graalpy_finalizing) + +#if (__linux__ && __GNU_LIBRARY__) +#include +#include +#include +#include +static void print_c_stacktrace() { + fprintf(stderr, "Native stacktrace:\n"); + intptr_t stack[16]; + size_t stack_size = backtrace((void *)stack, sizeof(stack) / sizeof(stack[0])); + backtrace_symbols_fd((void *)stack, stack_size, STDERR_FILENO); + fflush(stderr); +} + +static void attach_gdb() { + pid_t my_pid = getpid(); + char pathname = "/bin/sh"; + char gdbcmd[28] = {'\0'}; + snprintf(gdbcmd, sizeof(gdbcmd) - 1, "gdb -p %u", my_pid); + char *argv[4]; + argv[0] = pathname; + argv[1] = "-c"; + argv[2] = gdbcmd; + argv[3] = NULL; + if (fork() == 0) { + execv(pathname, argv); + } else { + // give gdb time to attach + sleep(5); + } +} +#else +static void print_c_stacktrace() { + // not supported +} + +static void attach_gdb() { + // not supported +} +#endif /* Flags definitions representing global (debug) options. */ static MUST_INLINE int PyTruffle_Trace_Memory() { diff --git a/graalpython/com.oracle.graal.python.cext/src/gcmodule.c b/graalpython/com.oracle.graal.python.cext/src/gcmodule.c index 512d90acaf..3d0ede7b82 100644 --- a/graalpython/com.oracle.graal.python.cext/src/gcmodule.c +++ b/graalpython/com.oracle.graal.python.cext/src/gcmodule.c @@ -49,6 +49,18 @@ call_traverse(traverseproc traverse, PyObject *op, visitproc visit, void *arg) Py_TYPE((op))->tp_name); return 0; } else { + if (_PyObject_IsFreed(op)) { + PyTruffle_Log(PY_TRUFFLE_LOG_FINE, + "we tried to call tp_traverse on a freed object at %p (ctx %p)!", + op, arg); + return 0; + } + if (_PyObject_IsFreed((PyObject *)Py_TYPE(op))) { + PyTruffle_Log(PY_TRUFFLE_LOG_FINE, + "we tried to call tp_traverse on an object at %p with a freed type at %p (ctx %p)!", + op, Py_TYPE(op), arg); + return 0; + } return traverse(op, (visitproc)visit, arg); } @@ -1581,7 +1593,8 @@ gc_collect_main(PyThreadState *tstate, int generation, PyGC_Head unreachable; /* non-problematic unreachable trash */ PyGC_Head finalizers; /* objects with, & reachable from, __del__ */ PyGC_Head *gc; - _PyTime_t t1 = 0; /* initialize to prevent a compiler warning */ + // GraalPy change: t1 usage commented out + // _PyTime_t t1 = 0; /* initialize to prevent a compiler warning */ GCState *gcstate = graalpy_get_gc_state(tstate); // GraalPy change if (GraalPyTruffle_DisableReferneceQueuePolling()) { diff --git a/graalpython/com.oracle.graal.python.cext/src/listobject.c b/graalpython/com.oracle.graal.python.cext/src/listobject.c index bc4f998f7e..93a6f56920 100644 --- a/graalpython/com.oracle.graal.python.cext/src/listobject.c +++ b/graalpython/com.oracle.graal.python.cext/src/listobject.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -133,7 +133,7 @@ PyTypeObject PyList_Type = { // alias for internal function, currently used in PyO3 PyAPI_FUNC(void) _PyList_SET_ITEM(PyObject* a, Py_ssize_t b, PyObject* c) { - return PyList_SET_ITEM(a, b, c); + PyList_SET_ITEM(a, b, c); } static inline int diff --git a/graalpython/com.oracle.graal.python.cext/src/longobject.c b/graalpython/com.oracle.graal.python.cext/src/longobject.c index 2ff9bc635f..c211991c0a 100644 --- a/graalpython/com.oracle.graal.python.cext/src/longobject.c +++ b/graalpython/com.oracle.graal.python.cext/src/longobject.c @@ -888,7 +888,7 @@ PyLong_FromVoidPtr(void *p) { // GraalPy change: different implementation // directly do the upcall to avoid a cast to primitive and reference counting - return ((PyObject* (*)(void*))GraalPyLong_FromUnsignedLongLong)(p); + return GraalPyLong_FromUnsignedLongLong((uint64_t)p); } #if 0 // GraalPy change @@ -1904,98 +1904,99 @@ long_from_binary_base(const char **str, int base, PyLongObject **res) PyObject * PyLong_FromString(const char *str, char **pend, int base) { - // GraalPy change: different implementation - int negative = 0, error_if_nonzero = 0; + int sign = 1, error_if_nonzero = 0; + const char *start, *orig_str = str; + PyObject *z = NULL; + PyObject *strobj; + Py_ssize_t slen; + if ((base != 0 && base < 2) || base > 36) { PyErr_SetString(PyExc_ValueError, "int() arg 2 must be >= 2 and <= 36"); return NULL; } - while (*str != '\0' && Py_ISSPACE(Py_CHARMASK(*str))) { + while (*str != '\0' && Py_ISSPACE(*str)) { str++; } - const char *orig_str = str; if (*str == '+') { ++str; - } else if (*str == '-') { + } + else if (*str == '-') { ++str; - negative = 1; + sign = -1; } if (base == 0) { if (str[0] != '0') { base = 10; - } else if (str[1] == 'x' || str[1] == 'X') { + } + else if (str[1] == 'x' || str[1] == 'X') { base = 16; - str += 2; - } else if (str[1] == 'o' || str[1] == 'O') { + } + else if (str[1] == 'o' || str[1] == 'O') { base = 8; - str += 2; - } else if (str[1] == 'b' || str[1] == 'B') { + } + else if (str[1] == 'b' || str[1] == 'B') { base = 2; - str += 2; - } else { + } + else { /* "old" (C-style) octal literal, now invalid. it might still be zero though */ error_if_nonzero = 1; base = 10; } } - - char* numberStart = str; - int overflow = 0; - int digits = 0; - char prev; - long value; - while (1) { + if (str[0] == '0' && + ((base == 16 && (str[1] == 'x' || str[1] == 'X')) || + (base == 8 && (str[1] == 'o' || str[1] == 'O')) || + (base == 2 && (str[1] == 'b' || str[1] == 'B')))) { + str += 2; + /* One underscore allowed here. */ if (*str == '_') { - if (prev == '_') { - goto error; - } - } else { - unsigned char digit = _PyLong_DigitValue[Py_CHARMASK(*str)]; - if (digit >= base) { + ++str; + } + } + + // GraalPy change: remove the CPython code below and upcall quickly. Only + // optimization we do is to check if this may be a small-ish integer. There + // is a small integer cache and if we're lucky we can just return from + // that. + // In base 2, up to 8 digits may be a small integer, in base 36 8 digits + // still fit easily in 64 bits + for (int i = 0; i < 8; i++) { + char c = str[i]; + if (c == '\0') { + int errsv = errno; + char *endptr; + long long result = strtoll(str, &endptr, base); + if (error_if_nonzero && result != 0) { + // let upcall handle the error reporting + base = 0; break; } - long new_value = value * base - digit; - if (new_value > value) { - // overflow - overflow = 1; + // POSIX.1-2008: strtoll must not set errno on success, and set + // *endptr to str when no conversion is performed + if (errno == 0 && str != endptr) { + while (*endptr && Py_ISSPACE(*endptr)) { + endptr++; + } + if (*endptr == '\0') { + z = PyLong_FromLongLong(sign < 0 ? -result : result); + } } - value = new_value; + errno = errsv; + break; + } else if (!(isascii(c) && isalnum(c))) { + // cannot be a base 2 to 36 digit + break; } - prev = *str; - ++str; - ++digits; - } - - if (prev == '_') { - /* Trailing underscore not allowed. */ - goto error; - } - while (*str != '\0' && Py_ISSPACE(Py_CHARMASK(*str))) { - str++; } - if (pend != NULL) { - *pend = str; - } - if (value == LONG_MIN && !negative) { - overflow = 1; - } - - if (overflow || (error_if_nonzero && value != 0)) { - if (error_if_nonzero) { - base = 0; + if (!z) { + z = GraalPyTruffleLong_FromString((char *)orig_str, base); + if (z) { + // TODO: we should probably set the **pend out argument } - return GraalPyTruffleLong_FromString(orig_str, base); - } else { - return PyLong_FromLong(negative ? value : -value); } - - error: - PyErr_Format(PyExc_ValueError, - "invalid literal for int() with base %d: %.200R", - base, PyUnicode_FromString(str)); - return NULL; + return z; } #if 0 // GraalPy change diff --git a/graalpython/com.oracle.graal.python.cext/src/moduleobject.c b/graalpython/com.oracle.graal.python.cext/src/moduleobject.c index 0df65eb0d3..c9e19fdaff 100644 --- a/graalpython/com.oracle.graal.python.cext/src/moduleobject.c +++ b/graalpython/com.oracle.graal.python.cext/src/moduleobject.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2022, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2022, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2022 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -258,7 +258,6 @@ _PyModule_CreateInitialized(PyModuleDef* module, int module_api_version) return (PyObject*)m; } -#if 0 // GraalPy change PyObject * PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_version) { @@ -340,8 +339,12 @@ PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_versio } if (PyModule_Check(m)) { - ((PyModuleObject*)m)->md_state = NULL; - ((PyModuleObject*)m)->md_def = def; + // GraalPy change: avoid direct struct access + GraalPy_set_PyModuleObject_md_state((PyModuleObject *)m, NULL); + GraalPy_set_PyModuleObject_md_def((PyModuleObject *)m, def); + // End of GraalPy change, CPython code was next two lines + // ((PyModuleObject*)m)->md_state = NULL; + // ((PyModuleObject*)m)->md_def = def; } else { if (def->m_size > 0 || def->m_traverse || def->m_clear || def->m_free) { PyErr_Format( @@ -361,10 +364,16 @@ PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_versio } if (def->m_methods != NULL) { - ret = _add_methods_to_object(m, nameobj, def->m_methods); - if (ret != 0) { - goto error; + // GraalPy change: use PyModule_AddFunctions instead of _add_methods_to_object + if (PyModule_AddFunctions(m, def->m_methods) != 0) { + Py_DECREF(m); + return NULL; } + // End of GraalPy change, original code below + // ret = _add_methods_to_object(m, nameobj, def->m_methods); + // if (ret != 0) { + // goto error; + // } } if (def->m_doc != NULL) { @@ -397,16 +406,27 @@ PyModule_ExecDef(PyObject *module, PyModuleDef *def) if (def->m_size >= 0) { PyModuleObject *md = (PyModuleObject*)module; - if (md->md_state == NULL) { - /* Always set a state pointer; this serves as a marker to skip - * multiple initialization (importlib.reload() is no-op) */ - md->md_state = PyMem_Malloc(def->m_size); - if (!md->md_state) { + // GraalPy change: avoid direct struct access + if (GraalPy_get_PyModuleObject_md_state(md) == NULL) { + void* md_state = PyMem_Malloc(def->m_size); + if (!md_state) { PyErr_NoMemory(); return -1; } - memset(md->md_state, 0, def->m_size); + memset(md_state, 0, def->m_size); + GraalPy_set_PyModuleObject_md_state(md, md_state); } + // End GraalPy change, original code below + // if (md->md_state == NULL) { + // /* Always set a state pointer; this serves as a marker to skip + // * multiple initialization (importlib.reload() is no-op) */ + // md->md_state = PyMem_Malloc(def->m_size); + // if (!md->md_state) { + // PyErr_NoMemory(); + // return -1; + // } + // memset(md->md_state, 0, def->m_size); + // } } if (def->m_slots == NULL) { @@ -447,7 +467,6 @@ PyModule_ExecDef(PyObject *module, PyModuleDef *def) } return 0; } -#endif // GraalPy change int PyModule_AddFunctions(PyObject *m, PyMethodDef *functions) @@ -555,6 +574,7 @@ PyModule_GetFilenameObject(PyObject *m) Py_INCREF(fileobj); return fileobj; } +#endif // GraalPy change const char * PyModule_GetFilename(PyObject *m) @@ -568,7 +588,6 @@ PyModule_GetFilename(PyObject *m) Py_DECREF(fileobj); /* module dict has still a reference */ return utf8; } -#endif // GraalPy change PyModuleDef* PyModule_GetDef(PyObject* m) diff --git a/graalpython/com.oracle.graal.python.cext/src/object.c b/graalpython/com.oracle.graal.python.cext/src/object.c index 9ad7908e8a..b514e8ded1 100644 --- a/graalpython/com.oracle.graal.python.cext/src/object.c +++ b/graalpython/com.oracle.graal.python.cext/src/object.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2018, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2022 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -372,7 +372,6 @@ PyObject_Print(PyObject *op, FILE *fp, int flags) return ret; } -#if 0 // GraalPy change /* For debugging convenience. Set a breakpoint here and call it from your DLL */ void _Py_BreakPoint(void) @@ -389,9 +388,14 @@ _Py_BreakPoint(void) int _PyObject_IsFreed(PyObject *op) { + if (points_to_py_handle_space(op)) { + return Graal_PyTruffleObject_IsFreed(op); + } +#if 0 // GraalPy change if (_PyMem_IsPtrFreed(op) || _PyMem_IsPtrFreed(Py_TYPE(op))) { return 1; } +#endif /* ignore op->ob_ref: its value can have be modified by Py_INCREF() and Py_DECREF(). */ #ifdef Py_TRACE_REFS @@ -405,11 +409,14 @@ _PyObject_IsFreed(PyObject *op) return 0; } - /* For debugging convenience. See Misc/gdbinit for some useful gdb hooks */ void _PyObject_Dump(PyObject* op) { + if (points_to_py_handle_space(op)) { + Graal_PyTruffleObject_Dump(op); + return; + } if (_PyObject_IsFreed(op)) { /* It seems like the object memory has been freed: don't access it to prevent a segmentation fault. */ @@ -448,6 +455,7 @@ _PyObject_Dump(PyObject* op) fflush(stderr); } +#if 0 // GraalPy change PyObject * PyObject_Repr(PyObject *v) { @@ -2370,7 +2378,6 @@ _PyTrash_cond(PyObject *op, destructor dealloc) } -#if 0 // GraalPy change void _Py_NO_RETURN _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, const char *file, int line, const char *function) @@ -2395,6 +2402,10 @@ _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, fprintf(stderr, "\n"); fflush(stderr); + // Begin GraalPy change + print_c_stacktrace(); + // End GraalPy change + if (_PyObject_IsFreed(obj)) { /* It seems like the object memory has been freed: don't access it to prevent a segmentation fault. */ @@ -2402,6 +2413,7 @@ _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, fflush(stderr); } else { +#if 0 // GraalPy change /* Display the traceback where the object has been allocated. Do it before dumping repr(obj), since repr() is more likely to crash than dumping the traceback. */ @@ -2415,6 +2427,7 @@ _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, } _PyMem_DumpTraceback(fileno(stderr), ptr); +#endif // GraalPy change /* This might succeed or fail, but we're about to abort, so at least try to provide any extra info we can: */ _PyObject_Dump(obj); @@ -2425,7 +2438,6 @@ _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, Py_FatalError("_PyObject_AssertFailed"); } -#endif // GraalPy change void @@ -2507,7 +2519,12 @@ Py_XNewRef(PyObject *obj) // for the stable ABI. int Py_Is(PyObject *x, PyObject *y) { +#if 0 // GraalPy change return (x == y); +#else + return (x == y) || + (points_to_py_handle_space(x) && points_to_py_handle_space(y) && GraalPyTruffle_Is(x, y)); +#endif } int Py_IsNone(PyObject *x) @@ -2671,7 +2688,8 @@ _decref_notify(const PyObject *op, const Py_ssize_t updated_refcnt) GraalPyTruffle_BulkNotifyRefCount(deferred_notify_ops, DEFERRED_NOTIFY_SIZE); } #else - GraalPyTruffle_BulkNotifyRefCount(&op, 1); + PyObject *nonConstOp = (PyObject *)op; + GraalPyTruffle_BulkNotifyRefCount(&nonConstOp, 1); #endif } } diff --git a/graalpython/com.oracle.graal.python.cext/src/obmalloc.c b/graalpython/com.oracle.graal.python.cext/src/obmalloc.c index ec97957209..559347aec6 100644 --- a/graalpython/com.oracle.graal.python.cext/src/obmalloc.c +++ b/graalpython/com.oracle.graal.python.cext/src/obmalloc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -384,7 +384,6 @@ _GraalPyMem_PrepareAlloc(GraalPyMem_t *state, size_t size) __func__, state->native_memory_gc_barrier, size, state->allocated_memory); size_t delay = 0; - int iteration = 0; for (int iteration = 0; iteration < MAX_COLLECTION_RETRIES; iteration++) { GraalPyTruffle_TriggerGC(delay); diff --git a/graalpython/com.oracle.graal.python.cext/src/structseq.c b/graalpython/com.oracle.graal.python.cext/src/structseq.c index 2858e8d7ea..b6bff24c4c 100644 --- a/graalpython/com.oracle.graal.python.cext/src/structseq.c +++ b/graalpython/com.oracle.graal.python.cext/src/structseq.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2024, Oracle and/or its affiliates. +/* Copyright (c) 2024, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2022 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -385,6 +385,7 @@ static PyMethodDef structseq_methods[] = { {"__reduce__", (PyCFunction)structseq_reduce, METH_NOARGS, NULL}, {NULL, NULL} }; +#endif // GraalPy change static Py_ssize_t count_members(PyStructSequence_Desc *desc, Py_ssize_t *n_unnamed_members) { @@ -399,6 +400,7 @@ count_members(PyStructSequence_Desc *desc, Py_ssize_t *n_unnamed_members) { return i; } +#if 0 // GraalPy change static int initialize_structseq_dict(PyStructSequence_Desc *desc, PyObject* dict, Py_ssize_t n_members, Py_ssize_t n_unnamed_members) { @@ -455,6 +457,7 @@ initialize_structseq_dict(PyStructSequence_Desc *desc, PyObject* dict, Py_DECREF(keys); return -1; } +#endif // GraalPy change static void initialize_members(PyStructSequence_Desc *desc, PyMemberDef* members, @@ -478,7 +481,6 @@ initialize_members(PyStructSequence_Desc *desc, PyMemberDef* members, } members[k].name = NULL; } -#endif // GraalPy change int @@ -518,7 +520,6 @@ _PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc, type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | tp_flags; type->tp_traverse = (traverseproc) structseq_traverse; -#if 0 // GraalPy change: initialize members in an upcall later n_members = count_members(desc, &n_unnamed_members); members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); if (members == NULL) { @@ -527,9 +528,6 @@ _PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc, } initialize_members(desc, members, n_members); type->tp_members = members; -#else // GraalPy change - type->tp_members = NULL; -#endif // GraalPy change if (PyType_Ready(type) < 0) { // GraalPy change: not initialized diff --git a/graalpython/com.oracle.graal.python.cext/src/tupleobject.c b/graalpython/com.oracle.graal.python.cext/src/tupleobject.c index 007bab220d..659c6b5d4a 100644 --- a/graalpython/com.oracle.graal.python.cext/src/tupleobject.c +++ b/graalpython/com.oracle.graal.python.cext/src/tupleobject.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2018, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2022 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -959,7 +959,6 @@ PyTypeObject PyTuple_Type = { }; -#if 0 // GraalPy change /* The following function breaks the notion that tuples are immutable: it changes the size of a tuple. We get away with this only if there is only one module referencing the object. You can also think of it @@ -977,7 +976,8 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) v = (PyTupleObject *) *pv; if (v == NULL || !Py_IS_TYPE(v, &PyTuple_Type) || - (Py_SIZE(v) != 0 && Py_REFCNT(v) != 1)) { + // GraalPy change: ignore refcnt + /* (Py_SIZE(v) != 0 && Py_REFCNT(v) != 1) */ 0) { *pv = 0; Py_XDECREF(v); PyErr_BadInternalCall(); @@ -990,7 +990,9 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) } if (newsize == 0) { Py_DECREF(v); - *pv = tuple_get_empty(); + // GraalPy change: no empty tuple singleton + // *pv = tuple_get_empty(); + *pv = PyTuple_New(0); return 0; } if (oldsize == 0) { @@ -1004,6 +1006,19 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) return *pv == NULL ? -1 : 0; } + // Begin GraalPy change + if (points_to_py_handle_space(v)) { + GraalPyVarObject *o = (GraalPyVarObject *)pointer_to_stub(v); + PyObject** new_items = GraalPyTruffleTuple_Resize((PyObject *)v, newsize, o->ob_item); + if (new_items == NULL && o->ob_item != NULL) { + *pv = NULL; + return -1; + } + o->ob_size = newsize; + o->ob_item = new_items; + return 0; + } + // End GraalPy change /* XXX UNREF/NEWREF interface should be more symmetrical */ #ifdef Py_REF_DEBUG _Py_RefTotal--; @@ -1034,6 +1049,7 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) return 0; } +#if 0 // GraalPy change PyStatus _PyTuple_InitTypes(PyInterpreterState *interp) @@ -1424,3 +1440,9 @@ _PyTuple_GET_ITEM(PyObject* a, Py_ssize_t b) { } return NULL; // an exception has happend during transtion } + +#undef PyTuple_SET_ITEM +// Export PyTuple_SET_ITEM as regular API function to use in PyO3 and others +void PyTuple_SET_ITEM(PyObject* op, Py_ssize_t index, PyObject* value) { + PyTruffleTuple_GetItems(op)[index] = value; +} diff --git a/graalpython/com.oracle.graal.python.cext/src/typeobject.c b/graalpython/com.oracle.graal.python.cext/src/typeobject.c index ea3848e108..65737e0ddc 100644 --- a/graalpython/com.oracle.graal.python.cext/src/typeobject.c +++ b/graalpython/com.oracle.graal.python.cext/src/typeobject.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2018, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2022 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -6359,9 +6359,6 @@ type_ready_inherit(PyTypeObject *type) if (!(type->tp_alloc)) { type->tp_alloc = PyType_GenericAlloc; } - if (!(type->tp_new)) { - type->tp_new = PyType_GenericNew; - } return 0; } @@ -6608,9 +6605,6 @@ PyType_Ready(PyTypeObject *type) type->tp_flags = (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY; assert(_PyType_CheckConsistency(type)); - // GraalPy change - GraalPyTruffle_InitializeOldStyleSlots(type); - // GraalPy change: for reason, see first call to Py_INCREF in this function Py_DECREF(type); return 0; @@ -9362,13 +9356,8 @@ static int type_ready_graalpy_slot_conv(PyTypeObject* cls) { ADD_SLOT_CONV("__delattr__", cls->tp_setattro, -3, JWRAPPER_DELATTRO); ADD_SLOT_CONV("__clear__", cls->tp_clear, -1, JWRAPPER_INQUIRY); - /* IMPORTANT NOTE: If the class already provides 'tp_richcompare' but this is the default - 'object.__truffle_richcompare__' function, then we need to break a recursive cycle since - the default function dispatches to the individual comparison functions which would in - this case again invoke 'object.__truffle_richcompare__'. */ richcmpfunc richcompare = cls->tp_richcompare; - if (richcompare && richcompare != PyBaseObject_Type.tp_richcompare) { - ADD_SLOT_CONV("__compare__", richcompare, -3, JWRAPPER_RICHCMP); + if (richcompare) { ADD_SLOT_CONV("__lt__", richcompare, -2, JWRAPPER_LT); ADD_SLOT_CONV("__le__", richcompare, -2, JWRAPPER_LE); ADD_SLOT_CONV("__eq__", richcompare, -2, JWRAPPER_EQ); diff --git a/graalpython/com.oracle.graal.python.cext/src/unicodeobject.c b/graalpython/com.oracle.graal.python.cext/src/unicodeobject.c index 42699b743a..2ab9336131 100644 --- a/graalpython/com.oracle.graal.python.cext/src/unicodeobject.c +++ b/graalpython/com.oracle.graal.python.cext/src/unicodeobject.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2018, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2020 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -1381,7 +1381,6 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) { // GraalPy change: different implementation /* add one to size for the null character */ - int is_ascii = 0; if (maxchar < 128) { /* We intentionally use 'size' (which is one element less than the allocated array) * because interop users should not see the null character. */ @@ -6220,16 +6219,17 @@ _PyUnicode_DecodeRawUnicodeEscapeStateful(const char *s, Py_XDECREF(exc); return NULL; } - +#endif // GraalPy change PyObject * PyUnicode_DecodeRawUnicodeEscape(const char *s, Py_ssize_t size, const char *errors) { - return _PyUnicode_DecodeRawUnicodeEscapeStateful(s, size, errors, NULL); + return PyUnicode_Decode(s, size, "raw_unicode_escape", errors); + // return _PyUnicode_DecodeRawUnicodeEscapeStateful(s, size, errors, NULL); } - +#if 0 // GraalPy change PyObject * PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) { diff --git a/graalpython/com.oracle.graal.python.frozen/freeze_modules.py b/graalpython/com.oracle.graal.python.frozen/freeze_modules.py index c08d654cd6..f31ce5be5b 100644 --- a/graalpython/com.oracle.graal.python.frozen/freeze_modules.py +++ b/graalpython/com.oracle.graal.python.frozen/freeze_modules.py @@ -1,4 +1,4 @@ -# Copyright (c) 2021, 2024, Oracle and/or its affiliates. +# Copyright (c) 2021, 2025, Oracle and/or its affiliates. # Copyright (C) 1996-2020 Python Software Foundation # # Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -105,13 +105,15 @@ def add_graalpython_core(): l.append("polyglot.arrow : polyglot.arrow = " + os.path.join(lib_graalpython, "modules/_polyglot_arrow.py")) for name in [ "modules/_sysconfigdata", + "modules/_polyglot", + "modules/_polyglot_datetime", + "modules/_polyglot_time", ]: modname = os.path.basename(name) modpath = os.path.join(lib_graalpython, f"{name}.py") l.append(f"{modname} : {modname} = {modpath}") for name in [ "__graalpython__", - "_polyglot", "_sre", "_sysconfig", "_weakref", @@ -119,6 +121,7 @@ def add_graalpython_core(): "java", "pip_hook", "unicodedata", + "_nt", ]: modname = f"graalpy.{os.path.basename(name)}" modpath = os.path.join(lib_graalpython, f"{name}.py") @@ -153,7 +156,7 @@ def relpath_for_posix_display(path, base): ####################################### # specs -def parse_frozen_specs(): +def parse_frozen_specs(suffix): seen = {} for section, specs in FROZEN: parsed = _parse_specs(specs, section, seen) @@ -162,7 +165,7 @@ def parse_frozen_specs(): try: source = seen[frozenid] except KeyError: - source = FrozenSource.from_id(frozenid, pyfile) + source = FrozenSource.from_id(frozenid, suffix, pyfile) seen[frozenid] = source else: assert not pyfile or pyfile == source.pyfile, item @@ -270,11 +273,11 @@ def iter_subs(): class FrozenSource(namedtuple('FrozenSource', 'id pyfile frozenfile deepfreezefile')): @classmethod - def from_id(cls, frozenid, pyfile=None): + def from_id(cls, frozenid, suffix, pyfile=None): if not pyfile: pyfile = os.path.join(STDLIB_DIR, *frozenid.split('.')) + '.py' #assert os.path.exists(pyfile), (frozenid, pyfile) - frozenfile = resolve_frozen_file(frozenid, FROZEN_MODULES_DIR) + frozenfile = resolve_frozen_file(frozenid, FROZEN_MODULES_DIR, suffix) return cls(frozenid, pyfile, frozenfile, STDLIB_DIR) @classmethod @@ -310,7 +313,7 @@ def isbootstrap(self): return self.id in BOOTSTRAP -def resolve_frozen_file(frozenid, destdir): +def resolve_frozen_file(frozenid, destdir, suffix): """Return the filename corresponding to the given frozen ID. For stdlib modules the ID will always be the full name @@ -323,7 +326,7 @@ def resolve_frozen_file(frozenid, destdir): raise ValueError(f'unsupported frozenid {frozenid!r}') # We use a consistent naming convention for all frozen modules. frozen_symbol = FrozenSource.resolve_symbol(frozenid) - frozenfile = f"Frozen{frozen_symbol}.bin" + frozenfile = f"Frozen{frozen_symbol}.{suffix}" if not destdir: return frozenfile @@ -495,7 +498,7 @@ def lower_camel_case(str): # write frozen files FROZEN_MODULES_HEADER = """/* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -588,19 +591,27 @@ def write_frozen_module_file(file, modules): if os.path.exists(file): with open(file, "r", encoding="utf-8", newline=os.linesep) as f: content = f.read() + if os.linesep != "\n": + if content.replace(os.linesep, "\n") == content: + # Windows file has Unix line endings + linesep = "\n" + else: + linesep = os.linesep + else: + linesep = "\n" stat_result = os.stat(file) atime, mtime = stat_result.st_atime, stat_result.st_mtime else: content = None os.makedirs(os.path.dirname(file), exist_ok=True) - with open(file, "w", encoding="utf-8", newline=os.linesep) as out_file: + with open(file, "w", encoding="utf-8", newline=linesep) as out_file: out_file.write(FROZEN_MODULES_HEADER) out_file.write("\n\n") write_frozen_modules_map(out_file, modules) out_file.write("\n") write_frozen_lookup(out_file, modules) out_file.write("}\n") - with open(file, "r", encoding="utf-8", newline=os.linesep) as f: + with open(file, "r", encoding="utf-8", newline=linesep) as f: new_content = f.read() if new_content == content: # set mtime to the old one, if we didn't change anything @@ -633,11 +644,17 @@ def main(): STDLIB_DIR = os.path.abspath(parsed_args.python_lib) FROZEN_MODULES_DIR = os.path.abspath(parsed_args.binary_dir) + if __graalpython__.is_bytecode_dsl_interpreter: + suffix = "bin_dsl" + assert os.path.isdir(parsed_args.binary_dir), "Frozen modules for the DSL should be built after the manual bytecode interpreter." + else: + suffix = "bin" + shutil.rmtree(parsed_args.binary_dir, ignore_errors=True) + os.makedirs(parsed_args.binary_dir) + # create module specs - modules = list(parse_frozen_specs()) + modules = list(parse_frozen_specs(suffix)) - shutil.rmtree(parsed_args.binary_dir, ignore_errors=True) - os.makedirs(parsed_args.binary_dir) # write frozen module binary files containing the byte code and class files # used for importing the binary files for src in _iter_sources(modules): diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/CMakeLists.txt b/graalpython/com.oracle.graal.python.hpy.llvm/CMakeLists.txt deleted file mode 100644 index 86b908fb4e..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.llvm/CMakeLists.txt +++ /dev/null @@ -1,143 +0,0 @@ -# -# Copyright (c) 2023, 2024, Oracle and/or its affiliates. -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, are -# permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this list of -# conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or other materials provided -# with the distribution. -# 3. Neither the name of the copyright holder nor the names of its contributors may be used to -# endorse or promote products derived from this software without specific prior written -# permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -# OF THE POSSIBILITY OF SUCH DAMAGE. -# -cmake_minimum_required(VERSION 3.22) -project(com.oracle.graal.python.hpy.llvm) - -function(require_var var) - if (NOT DEFINED ${var}) - message(FATAL_ERROR "${var} needs to be set") - endif() -endfunction() - -# default to CMake's source dir if not explicitly provided -if(NOT DEFINED SRC_DIR) - set(SRC_DIR "${CMAKE_SOURCE_DIR}") -endif() - -set(TARGET_LIB "hpy-native") - -# don't install into the system but into the MX project's output dir -set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}) - -require_var(GRAALPY_PARENT_DIR) -require_var(GRAALVM_HPY_INCLUDE_DIR) -require_var(GRAALVM_PYTHON_INCLUDE_DIR) -require_var(PYCONFIG_INCLUDE_DIR) -require_var(TRUFFLE_H_INC) - -set(HPY_SRC "${SRC_DIR}/src") -set(HPY_INC "${SRC_DIR}/include") - -# using glob patterns is not recommended: https://cmake.org/cmake/help/latest/command/file.html#glob -set(SRC_FILES ${HPY_SRC}/hpy.c - ${HPY_SRC}/hpynative.h -) - -set(HPY_HEADERS ${HPY_INC}/hpy/autogen_hpyslot.h - ${HPY_INC}/hpy/version.h - ${HPY_INC}/hpy/hpytype.h - ${HPY_INC}/hpy/universal/hpyfunc_trampolines.h - ${HPY_INC}/hpy/universal/autogen_trampolines.h - ${HPY_INC}/hpy/universal/misc_trampolines.h - ${HPY_INC}/hpy/universal/autogen_ctx.h - ${HPY_INC}/hpy/universal/autogen_hpyfunc_trampolines.h - ${HPY_INC}/hpy/hpydef.h - ${HPY_INC}/hpy/runtime/argparse.h - ${HPY_INC}/hpy/runtime/ctx_type.h - ${HPY_INC}/hpy/runtime/buildvalue.h - ${HPY_INC}/hpy/runtime/ctx_funcs.h - ${HPY_INC}/hpy/runtime/structseq.h - ${HPY_INC}/hpy/runtime/helpers.h - ${HPY_INC}/hpy/inline_helpers.h - ${HPY_INC}/hpy/cpython/hpyfunc_trampolines.h - ${HPY_INC}/hpy/cpython/misc.h - ${HPY_INC}/hpy/cpython/autogen_api_impl.h - ${HPY_INC}/hpy/cpython/autogen_hpyfunc_trampolines.h - ${HPY_INC}/hpy/macros.h - ${HPY_INC}/hpy/hpymodule.h - ${HPY_INC}/hpy/autogen_hpyfunc_declare.h - ${HPY_INC}/hpy/cpy_types.h - ${HPY_INC}/hpy/hpyfunc.h - ${HPY_INC}/hpy.h -) - -add_library(${TARGET_LIB} SHARED) - -target_sources(${TARGET_LIB} PRIVATE ${SRC_FILES} ${HPY_HEADERS}) -target_include_directories(${TARGET_LIB} PRIVATE - "${GRAALVM_HPY_INCLUDE_DIR}" - "${GRAALVM_PYTHON_INCLUDE_DIR}" - "${PYCONFIG_INCLUDE_DIR}" - "${TRUFFLE_H_INC}" -) - -target_compile_definitions(${TARGET_LIB} PRIVATE - HPY_ABI_HYBRID - NDEBUG - GRAALVM_PYTHON_LLVM - Py_BUILD_CORE -) - -if(WIN32) - require_var(GRAALVM_LLVM_LIB_DIR) - target_link_directories(${TARGET_LIB} PRIVATE ${GRAALVM_LLVM_LIB_DIR}) - target_link_libraries(${TARGET_LIB} PRIVATE graalvm-llvm) - # Following defines are for 'Python.h'. Since HPy includes it, we need them. - target_compile_definitions(${TARGET_LIB} PRIVATE - MS_WINDOWS - Py_ENABLE_SHARED - HAVE_DECLSPEC_DLL - ) -endif() - -if(MSVC) - target_compile_options(${TARGET_LIB} PRIVATE /O2 /WX) -else() - if(NOT WIN32) - target_compile_options(${TARGET_LIB} PRIVATE - -Werror - ) - endif() - target_compile_options(${TARGET_LIB} PRIVATE - -ffile-prefix-map=${GRAALPY_PARENT_DIR}=. - -Wno-int-to-pointer-cast - -Wno-int-conversion - -Wno-void-pointer-to-int-cast - -Wno-incompatible-pointer-types-discards-qualifiers - -Wno-pointer-type-mismatch - -Wno-braced-scalar-init - -Wno-deprecated-declarations - ) -endif() - -if(APPLE) - target_link_options(${TARGET_LIB} PRIVATE -undefined dynamic_lookup) -endif() - -install(TARGETS ${TARGET_LIB} DESTINATION bin) diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/forbid_python_h/Python.h b/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/forbid_python_h/Python.h deleted file mode 100644 index f71e69c6d2..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/forbid_python_h/Python.h +++ /dev/null @@ -1,30 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -// sanity check -#ifndef HPY_ABI_UNIVERSAL -# error "Internal HPy error, something is wrong with your build system. The directory hpy/forbid_python_h has been added to the include_dirs but the target ABI does not seems to be 'universal'" -#endif - -#error "It is forbidden to #include when targeting the HPy Universal ABI" diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpyexports.h b/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpyexports.h deleted file mode 100644 index f627b7d361..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpyexports.h +++ /dev/null @@ -1,37 +0,0 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef HPy_EXPORTS_H -#define HPy_EXPORTS_H - -// Copied from Python's exports.h -#ifndef HPy_EXPORTED_SYMBOL - #if defined(_WIN32) || defined(__CYGWIN__) - #define HPy_EXPORTED_SYMBOL __declspec(dllexport) - #else - #define HPy_EXPORTED_SYMBOL __attribute__ ((visibility ("default"))) - #endif -#endif - -#endif /* HPy_EXPORTS_H */ diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/argparse.h b/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/argparse.h deleted file mode 100644 index 927d87db96..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/argparse.h +++ /dev/null @@ -1,50 +0,0 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef HPY_COMMON_RUNTIME_ARGPARSE_H -#define HPY_COMMON_RUNTIME_ARGPARSE_H -#ifdef __cplusplus -extern "C" { -#endif - -#include "hpy.h" - -HPyAPI_HELPER int -HPyArg_Parse(HPyContext *ctx, HPyTracker *ht, const HPy *args, - size_t nargs, const char *fmt, ...); - -HPyAPI_HELPER int -HPyArg_ParseKeywords(HPyContext *ctx, HPyTracker *ht, const HPy *args, - size_t nargs, HPy kwnames, const char *fmt, - const char *keywords[], ...); - -HPyAPI_HELPER int -HPyArg_ParseKeywordsDict(HPyContext *ctx, HPyTracker *ht, const HPy *args, - HPy_ssize_t nargs, HPy kw, const char *fmt, - const char *keywords[], ...); - -#ifdef __cplusplus -} -#endif -#endif /* HPY_COMMON_RUNTIME_ARGPARSE_H */ diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/buildvalue.h b/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/buildvalue.h deleted file mode 100644 index 78fda36b64..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/buildvalue.h +++ /dev/null @@ -1,33 +0,0 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef HPY_COMMON_RUNTIME_BUILDVALUE_H -#define HPY_COMMON_RUNTIME_BUILDVALUE_H - -#include "hpy.h" - -HPyAPI_HELPER HPy -HPy_BuildValue(HPyContext *ctx, const char *fmt, ...); - -#endif /* HPY_COMMON_RUNTIME_BUILDVALUE_H */ diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/ctx_module.h b/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/ctx_module.h deleted file mode 100644 index 079e772b0f..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/ctx_module.h +++ /dev/null @@ -1,49 +0,0 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef HPY_COMMON_RUNTIME_CTX_MODULE_H -#define HPY_COMMON_RUNTIME_CTX_MODULE_H - -#include -#include "hpy.h" - -// Helper functions for CPython implementation (both CPython ABI and -// HPy universal module impl for CPython) - -/** Converts HPy module definition to CPython module definition for multiphase - * initialization */ -_HPy_HIDDEN PyModuleDef* -_HPyModuleDef_CreatePyModuleDef(HPyModuleDef *hpydef); - -/** Converts HPy module definition to PyObject that wraps CPython module - * definition for multiphase initialization */ -_HPy_HIDDEN PyObject* -_HPyModuleDef_AsPyInit(HPyModuleDef *hpydef); - -/** Implements the extra HPy specific validation that should be applied to the - * result of the HPy_mod_create slot. */ -_HPy_HIDDEN void -_HPyModule_CheckCreateSlotResult(PyObject **result); - -#endif //HPY_COMMON_RUNTIME_CTX_MODULE_H diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/ctx_type.h b/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/ctx_type.h deleted file mode 100644 index 90d7e08c08..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/ctx_type.h +++ /dev/null @@ -1,40 +0,0 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef HPY_COMMON_RUNTIME_CTX_TYPE_H -#define HPY_COMMON_RUNTIME_CTX_TYPE_H - -#include -#include "hpy.h" -#include "hpy/hpytype.h" - -_HPy_HIDDEN PyMethodDef *create_method_defs(HPyDef *hpydefs[], - PyMethodDef *legacy_methods); - -_HPy_HIDDEN int call_traverseproc_from_trampoline(HPyFunc_traverseproc tp_traverse, - PyObject *self, - cpy_visitproc cpy_visit, - void *cpy_arg); - -#endif /* HPY_COMMON_RUNTIME_CTX_TYPE_H */ diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/format.h b/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/format.h deleted file mode 100644 index b04b5d12b9..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/format.h +++ /dev/null @@ -1,42 +0,0 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * String formatting helpers. These functions are not part of HPy ABI. The implementation will be linked into HPy extensions. - */ -#ifndef HPY_COMMON_RUNTIME_FORMAT_H -#define HPY_COMMON_RUNTIME_FORMAT_H - -#include "hpy.h" - -HPyAPI_HELPER HPy -HPyUnicode_FromFormat(HPyContext *ctx, const char *fmt, ...); - -HPyAPI_HELPER HPy -HPyUnicode_FromFormatV(HPyContext *ctx, const char *format, va_list vargs); - -HPyAPI_HELPER HPy -HPyErr_Format(HPyContext *ctx, HPy h_type, const char *fmt, ...); - -#endif /* HPY_COMMON_RUNTIME_FORMAT_H */ diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/helpers.h b/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/helpers.h deleted file mode 100644 index 7cfd833a40..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/helpers.h +++ /dev/null @@ -1,39 +0,0 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef HPY_COMMON_RUNTIME_HELPERS_H -#define HPY_COMMON_RUNTIME_HELPERS_H - -#include "hpy.h" -#include "hpy/hpytype.h" - -HPyAPI_HELPER int -HPyHelpers_AddType(HPyContext *ctx, HPy obj, const char *name, - HPyType_Spec *hpyspec, HPyType_SpecParam *params); - -HPyAPI_HELPER int -HPyHelpers_PackArgsAndKeywords(HPyContext *ctx, const HPy *args, size_t nargs, - HPy kwnames, HPy *out_args_tuple, HPy *out_kwd); - -#endif /* HPY_COMMON_RUNTIME_HELPERS_H */ diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/autogen_trampolines.h b/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/autogen_trampolines.h deleted file mode 100644 index 186fd8386b..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/autogen_trampolines.h +++ /dev/null @@ -1,1158 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.graalpy.autogen_llvm_trampolines_h - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -#ifdef GRAALVM_PYTHON_LLVM -#define UNWRAP(_h) ((_h)._i) -#define WRAP(_ptr) ((HPy){(_ptr)}) -#define UNWRAP_TUPLE_BUILDER(_h) ((_h)._tup) -#define WRAP_TUPLE_BUILDER(_ptr) ((HPyTupleBuilder){(_ptr)}) -#define UNWRAP_LIST_BUILDER(_h) ((_h)._lst) -#define WRAP_LIST_BUILDER(_ptr) ((HPyListBuilder){(_ptr)}) -#define UNWRAP_TRACKER(_h) ((_h)._i) -#define WRAP_TRACKER(_ptr) ((HPyTracker){(_ptr)}) -#define UNWRAP_THREADSTATE(_ts) ((_ts)._i) -#define WRAP_THREADSTATE(_ptr) ((HPyThreadState){(_ptr)}) -#define UNWRAP_FIELD(_h) ((_h)._i) -#define WRAP_FIELD(_ptr) ((HPyField){(_ptr)}) -#define UNWRAP_GLOBAL(_h) ((_h)._i) -#define WRAP_GLOBAL(_ptr) ((HPyGlobal){(_ptr)}) -#define UNWRAP_SOURCE_KIND(_h) ((int)(_h)) -#else -#define UNWRAP(_h) _h -#define WRAP(_ptr) _ptr -#define UNWRAP_TUPLE_BUILDER(_h) _h -#define WRAP_TUPLE_BUILDER(_ptr) _ptr -#define UNWRAP_LIST_BUILDER(_h) _h -#define WRAP_LIST_BUILDER(_ptr) _ptr -#define UNWRAP_TRACKER(_h) _h -#define WRAP_TRACKER(_ptr) _ptr -#define UNWRAP_THREADSTATE(_ts) _ts -#define WRAP_THREADSTATE(_data) _data -#define UNWRAP_FIELD(_h) _h -#define WRAP_FIELD(_ptr) _ptr -#define UNWRAP_GLOBAL(_h) _h -#define WRAP_GLOBAL(_ptr) _ptr -#define UNWRAP_SOURCE_KIND(_h) _h -#endif -HPyAPI_FUNC -HPy HPy_Dup(HPyContext *ctx, HPy h) -{ - return WRAP(ctx->ctx_Dup((ctx), UNWRAP(h))); -} - -HPyAPI_FUNC -void HPy_Close(HPyContext *ctx, HPy h) -{ - ctx->ctx_Close((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy HPyLong_FromInt32_t(HPyContext *ctx, int32_t value) -{ - return WRAP(ctx->ctx_Long_FromInt32_t((ctx), (value))); -} - -HPyAPI_FUNC -HPy HPyLong_FromUInt32_t(HPyContext *ctx, uint32_t value) -{ - return WRAP(ctx->ctx_Long_FromUInt32_t((ctx), (value))); -} - -HPyAPI_FUNC -HPy HPyLong_FromInt64_t(HPyContext *ctx, int64_t v) -{ - return WRAP(ctx->ctx_Long_FromInt64_t((ctx), (v))); -} - -HPyAPI_FUNC -HPy HPyLong_FromUInt64_t(HPyContext *ctx, uint64_t v) -{ - return WRAP(ctx->ctx_Long_FromUInt64_t((ctx), (v))); -} - -HPyAPI_FUNC -HPy HPyLong_FromSize_t(HPyContext *ctx, size_t value) -{ - return WRAP(ctx->ctx_Long_FromSize_t((ctx), (value))); -} - -HPyAPI_FUNC -HPy HPyLong_FromSsize_t(HPyContext *ctx, HPy_ssize_t value) -{ - return WRAP(ctx->ctx_Long_FromSsize_t((ctx), (value))); -} - -HPyAPI_FUNC -int32_t HPyLong_AsInt32_t(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Long_AsInt32_t((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -uint32_t HPyLong_AsUInt32_t(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Long_AsUInt32_t((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -uint32_t HPyLong_AsUInt32_tMask(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Long_AsUInt32_tMask((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -int64_t HPyLong_AsInt64_t(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Long_AsInt64_t((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -uint64_t HPyLong_AsUInt64_t(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Long_AsUInt64_t((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -uint64_t HPyLong_AsUInt64_tMask(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Long_AsUInt64_tMask((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -size_t HPyLong_AsSize_t(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Long_AsSize_t((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy_ssize_t HPyLong_AsSsize_t(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Long_AsSsize_t((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -void *HPyLong_AsVoidPtr(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Long_AsVoidPtr((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -double HPyLong_AsDouble(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Long_AsDouble((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy HPyFloat_FromDouble(HPyContext *ctx, double v) -{ - return WRAP(ctx->ctx_Float_FromDouble((ctx), (v))); -} - -HPyAPI_FUNC -double HPyFloat_AsDouble(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Float_AsDouble((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy HPyBool_FromBool(HPyContext *ctx, bool v) -{ - return WRAP(ctx->ctx_Bool_FromBool((ctx), (v))); -} - -HPyAPI_FUNC -HPy_ssize_t HPy_Length(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Length((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -int HPyNumber_Check(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Number_Check((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_Add((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_Subtract(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_Subtract((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_Multiply(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_Multiply((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_MatrixMultiply(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_MatrixMultiply((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_FloorDivide(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_FloorDivide((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_TrueDivide(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_TrueDivide((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_Remainder(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_Remainder((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_Divmod(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_Divmod((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_Power(HPyContext *ctx, HPy h1, HPy h2, HPy h3) -{ - return WRAP(ctx->ctx_Power((ctx), UNWRAP(h1), UNWRAP(h2), UNWRAP(h3))); -} - -HPyAPI_FUNC -HPy HPy_Negative(HPyContext *ctx, HPy h1) -{ - return WRAP(ctx->ctx_Negative((ctx), UNWRAP(h1))); -} - -HPyAPI_FUNC -HPy HPy_Positive(HPyContext *ctx, HPy h1) -{ - return WRAP(ctx->ctx_Positive((ctx), UNWRAP(h1))); -} - -HPyAPI_FUNC -HPy HPy_Absolute(HPyContext *ctx, HPy h1) -{ - return WRAP(ctx->ctx_Absolute((ctx), UNWRAP(h1))); -} - -HPyAPI_FUNC -HPy HPy_Invert(HPyContext *ctx, HPy h1) -{ - return WRAP(ctx->ctx_Invert((ctx), UNWRAP(h1))); -} - -HPyAPI_FUNC -HPy HPy_Lshift(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_Lshift((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_Rshift(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_Rshift((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_And(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_And((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_Xor(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_Xor((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_Or(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_Or((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_Index(HPyContext *ctx, HPy h1) -{ - return WRAP(ctx->ctx_Index((ctx), UNWRAP(h1))); -} - -HPyAPI_FUNC -HPy HPy_Long(HPyContext *ctx, HPy h1) -{ - return WRAP(ctx->ctx_Long((ctx), UNWRAP(h1))); -} - -HPyAPI_FUNC -HPy HPy_Float(HPyContext *ctx, HPy h1) -{ - return WRAP(ctx->ctx_Float((ctx), UNWRAP(h1))); -} - -HPyAPI_FUNC -HPy HPy_InPlaceAdd(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_InPlaceAdd((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_InPlaceSubtract(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_InPlaceSubtract((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_InPlaceMultiply(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_InPlaceMultiply((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_InPlaceMatrixMultiply(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_InPlaceMatrixMultiply((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_InPlaceFloorDivide(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_InPlaceFloorDivide((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_InPlaceTrueDivide(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_InPlaceTrueDivide((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_InPlaceRemainder(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_InPlaceRemainder((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_InPlacePower(HPyContext *ctx, HPy h1, HPy h2, HPy h3) -{ - return WRAP(ctx->ctx_InPlacePower((ctx), UNWRAP(h1), UNWRAP(h2), UNWRAP(h3))); -} - -HPyAPI_FUNC -HPy HPy_InPlaceLshift(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_InPlaceLshift((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_InPlaceRshift(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_InPlaceRshift((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_InPlaceAnd(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_InPlaceAnd((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_InPlaceXor(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_InPlaceXor((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -HPy HPy_InPlaceOr(HPyContext *ctx, HPy h1, HPy h2) -{ - return WRAP(ctx->ctx_InPlaceOr((ctx), UNWRAP(h1), UNWRAP(h2))); -} - -HPyAPI_FUNC -int HPyCallable_Check(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Callable_Check((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy HPy_CallTupleDict(HPyContext *ctx, HPy callable, HPy args, HPy kw) -{ - return WRAP(ctx->ctx_CallTupleDict((ctx), UNWRAP(callable), UNWRAP(args), UNWRAP(kw))); -} - -HPyAPI_FUNC -HPy HPy_Call(HPyContext *ctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames) -{ - return WRAP(ctx->ctx_Call((ctx), UNWRAP(callable), (args), (nargs), UNWRAP(kwnames))); -} - -HPyAPI_FUNC -HPy HPy_CallMethod(HPyContext *ctx, HPy name, const HPy *args, size_t nargs, HPy kwnames) -{ - return WRAP(ctx->ctx_CallMethod((ctx), UNWRAP(name), (args), (nargs), UNWRAP(kwnames))); -} - -HPyAPI_FUNC -HPy HPyErr_SetString(HPyContext *ctx, HPy h_type, const char *utf8_message) -{ - ctx->ctx_Err_SetString((ctx), UNWRAP(h_type), (utf8_message)); -return HPy_NULL; -} - -HPyAPI_FUNC -HPy HPyErr_SetObject(HPyContext *ctx, HPy h_type, HPy h_value) -{ - ctx->ctx_Err_SetObject((ctx), UNWRAP(h_type), UNWRAP(h_value)); -return HPy_NULL; -} - -HPyAPI_FUNC -HPy HPyErr_SetFromErrnoWithFilename(HPyContext *ctx, HPy h_type, const char *filename_fsencoded) -{ - return WRAP(ctx->ctx_Err_SetFromErrnoWithFilename((ctx), UNWRAP(h_type), (filename_fsencoded))); -} - -HPyAPI_FUNC -HPy HPyErr_SetFromErrnoWithFilenameObjects(HPyContext *ctx, HPy h_type, HPy filename1, HPy filename2) -{ - ctx->ctx_Err_SetFromErrnoWithFilenameObjects((ctx), UNWRAP(h_type), UNWRAP(filename1), UNWRAP(filename2)); -return HPy_NULL; -} - -HPyAPI_FUNC -int HPyErr_Occurred(HPyContext *ctx) -{ - return ctx->ctx_Err_Occurred((ctx)); -} - -HPyAPI_FUNC -int HPyErr_ExceptionMatches(HPyContext *ctx, HPy exc) -{ - return ctx->ctx_Err_ExceptionMatches((ctx), UNWRAP(exc)); -} - -HPyAPI_FUNC -HPy HPyErr_NoMemory(HPyContext *ctx) -{ - ctx->ctx_Err_NoMemory((ctx)); -return HPy_NULL; -} - -HPyAPI_FUNC -void HPyErr_Clear(HPyContext *ctx) -{ - ctx->ctx_Err_Clear((ctx)); -} - -HPyAPI_FUNC -HPy HPyErr_NewException(HPyContext *ctx, const char *utf8_name, HPy base, HPy dict) -{ - return WRAP(ctx->ctx_Err_NewException((ctx), (utf8_name), UNWRAP(base), UNWRAP(dict))); -} - -HPyAPI_FUNC -HPy HPyErr_NewExceptionWithDoc(HPyContext *ctx, const char *utf8_name, const char *utf8_doc, HPy base, HPy dict) -{ - return WRAP(ctx->ctx_Err_NewExceptionWithDoc((ctx), (utf8_name), (utf8_doc), UNWRAP(base), UNWRAP(dict))); -} - -HPyAPI_FUNC -int HPyErr_WarnEx(HPyContext *ctx, HPy category, const char *utf8_message, HPy_ssize_t stack_level) -{ - return ctx->ctx_Err_WarnEx((ctx), UNWRAP(category), (utf8_message), (stack_level)); -} - -HPyAPI_FUNC -void HPyErr_WriteUnraisable(HPyContext *ctx, HPy obj) -{ - ctx->ctx_Err_WriteUnraisable((ctx), UNWRAP(obj)); -} - -HPyAPI_FUNC -int HPy_IsTrue(HPyContext *ctx, HPy h) -{ - return ctx->ctx_IsTrue((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy HPyType_FromSpec(HPyContext *ctx, HPyType_Spec *spec, HPyType_SpecParam *params) -{ - return WRAP(ctx->ctx_Type_FromSpec((ctx), (spec), (params))); -} - -HPyAPI_FUNC -HPy HPyType_GenericNew(HPyContext *ctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw) -{ - return WRAP(ctx->ctx_Type_GenericNew((ctx), UNWRAP(type), (args), (nargs), UNWRAP(kw))); -} - -HPyAPI_FUNC -HPy HPy_GetAttr(HPyContext *ctx, HPy obj, HPy name) -{ - return WRAP(ctx->ctx_GetAttr((ctx), UNWRAP(obj), UNWRAP(name))); -} - -HPyAPI_FUNC -HPy HPy_GetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name) -{ - return WRAP(ctx->ctx_GetAttr_s((ctx), UNWRAP(obj), (utf8_name))); -} - -HPyAPI_FUNC -int HPy_HasAttr(HPyContext *ctx, HPy obj, HPy name) -{ - return ctx->ctx_HasAttr((ctx), UNWRAP(obj), UNWRAP(name)); -} - -HPyAPI_FUNC -int HPy_HasAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name) -{ - return ctx->ctx_HasAttr_s((ctx), UNWRAP(obj), (utf8_name)); -} - -HPyAPI_FUNC -int HPy_SetAttr(HPyContext *ctx, HPy obj, HPy name, HPy value) -{ - return ctx->ctx_SetAttr((ctx), UNWRAP(obj), UNWRAP(name), UNWRAP(value)); -} - -HPyAPI_FUNC -int HPy_SetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name, HPy value) -{ - return ctx->ctx_SetAttr_s((ctx), UNWRAP(obj), (utf8_name), UNWRAP(value)); -} - -HPyAPI_FUNC -HPy HPy_GetItem(HPyContext *ctx, HPy obj, HPy key) -{ - return WRAP(ctx->ctx_GetItem((ctx), UNWRAP(obj), UNWRAP(key))); -} - -HPyAPI_FUNC -HPy HPy_GetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx) -{ - return WRAP(ctx->ctx_GetItem_i((ctx), UNWRAP(obj), (idx))); -} - -HPyAPI_FUNC -HPy HPy_GetItem_s(HPyContext *ctx, HPy obj, const char *utf8_key) -{ - return WRAP(ctx->ctx_GetItem_s((ctx), UNWRAP(obj), (utf8_key))); -} - -HPyAPI_FUNC -int HPy_Contains(HPyContext *ctx, HPy container, HPy key) -{ - return ctx->ctx_Contains((ctx), UNWRAP(container), UNWRAP(key)); -} - -HPyAPI_FUNC -int HPy_SetItem(HPyContext *ctx, HPy obj, HPy key, HPy value) -{ - return ctx->ctx_SetItem((ctx), UNWRAP(obj), UNWRAP(key), UNWRAP(value)); -} - -HPyAPI_FUNC -int HPy_SetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx, HPy value) -{ - return ctx->ctx_SetItem_i((ctx), UNWRAP(obj), (idx), UNWRAP(value)); -} - -HPyAPI_FUNC -int HPy_SetItem_s(HPyContext *ctx, HPy obj, const char *utf8_key, HPy value) -{ - return ctx->ctx_SetItem_s((ctx), UNWRAP(obj), (utf8_key), UNWRAP(value)); -} - -HPyAPI_FUNC -int HPy_DelItem(HPyContext *ctx, HPy obj, HPy key) -{ - return ctx->ctx_DelItem((ctx), UNWRAP(obj), UNWRAP(key)); -} - -HPyAPI_FUNC -int HPy_DelItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx) -{ - return ctx->ctx_DelItem_i((ctx), UNWRAP(obj), (idx)); -} - -HPyAPI_FUNC -int HPy_DelItem_s(HPyContext *ctx, HPy obj, const char *utf8_key) -{ - return ctx->ctx_DelItem_s((ctx), UNWRAP(obj), (utf8_key)); -} - -HPyAPI_FUNC -HPy HPy_Type(HPyContext *ctx, HPy obj) -{ - return WRAP(ctx->ctx_Type((ctx), UNWRAP(obj))); -} - -HPyAPI_FUNC -int HPy_TypeCheck(HPyContext *ctx, HPy obj, HPy type) -{ - return ctx->ctx_TypeCheck((ctx), UNWRAP(obj), UNWRAP(type)); -} - -HPyAPI_FUNC -const char *HPyType_GetName(HPyContext *ctx, HPy type) -{ - return ctx->ctx_Type_GetName((ctx), UNWRAP(type)); -} - -HPyAPI_FUNC -int HPyType_IsSubtype(HPyContext *ctx, HPy sub, HPy type) -{ - return ctx->ctx_Type_IsSubtype((ctx), UNWRAP(sub), UNWRAP(type)); -} - -HPyAPI_FUNC -int HPy_Is(HPyContext *ctx, HPy obj, HPy other) -{ - return ctx->ctx_Is((ctx), UNWRAP(obj), UNWRAP(other)); -} - -HPyAPI_FUNC -void *_HPy_AsStruct_Object(HPyContext *ctx, HPy h) -{ - return ctx->ctx_AsStruct_Object((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -void *_HPy_AsStruct_Legacy(HPyContext *ctx, HPy h) -{ - return ctx->ctx_AsStruct_Legacy((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -void *_HPy_AsStruct_Type(HPyContext *ctx, HPy h) -{ - return ctx->ctx_AsStruct_Type((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -void *_HPy_AsStruct_Long(HPyContext *ctx, HPy h) -{ - return ctx->ctx_AsStruct_Long((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -void *_HPy_AsStruct_Float(HPyContext *ctx, HPy h) -{ - return ctx->ctx_AsStruct_Float((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -void *_HPy_AsStruct_Unicode(HPyContext *ctx, HPy h) -{ - return ctx->ctx_AsStruct_Unicode((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -void *_HPy_AsStruct_Tuple(HPyContext *ctx, HPy h) -{ - return ctx->ctx_AsStruct_Tuple((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -void *_HPy_AsStruct_List(HPyContext *ctx, HPy h) -{ - return ctx->ctx_AsStruct_List((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPyType_BuiltinShape _HPyType_GetBuiltinShape(HPyContext *ctx, HPy h_type) -{ - return ctx->ctx_Type_GetBuiltinShape((ctx), UNWRAP(h_type)); -} - -HPyAPI_FUNC -HPy HPy_Repr(HPyContext *ctx, HPy obj) -{ - return WRAP(ctx->ctx_Repr((ctx), UNWRAP(obj))); -} - -HPyAPI_FUNC -HPy HPy_Str(HPyContext *ctx, HPy obj) -{ - return WRAP(ctx->ctx_Str((ctx), UNWRAP(obj))); -} - -HPyAPI_FUNC -HPy HPy_ASCII(HPyContext *ctx, HPy obj) -{ - return WRAP(ctx->ctx_ASCII((ctx), UNWRAP(obj))); -} - -HPyAPI_FUNC -HPy HPy_Bytes(HPyContext *ctx, HPy obj) -{ - return WRAP(ctx->ctx_Bytes((ctx), UNWRAP(obj))); -} - -HPyAPI_FUNC -HPy HPy_RichCompare(HPyContext *ctx, HPy v, HPy w, int op) -{ - return WRAP(ctx->ctx_RichCompare((ctx), UNWRAP(v), UNWRAP(w), (op))); -} - -HPyAPI_FUNC -int HPy_RichCompareBool(HPyContext *ctx, HPy v, HPy w, int op) -{ - return ctx->ctx_RichCompareBool((ctx), UNWRAP(v), UNWRAP(w), (op)); -} - -HPyAPI_FUNC -HPy_hash_t HPy_Hash(HPyContext *ctx, HPy obj) -{ - return ctx->ctx_Hash((ctx), UNWRAP(obj)); -} - -HPyAPI_FUNC -int HPyBytes_Check(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Bytes_Check((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy_ssize_t HPyBytes_Size(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Bytes_Size((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy_ssize_t HPyBytes_GET_SIZE(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Bytes_GET_SIZE((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -const char *HPyBytes_AsString(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Bytes_AsString((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -const char *HPyBytes_AS_STRING(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Bytes_AS_STRING((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy HPyBytes_FromString(HPyContext *ctx, const char *bytes) -{ - return WRAP(ctx->ctx_Bytes_FromString((ctx), (bytes))); -} - -HPyAPI_FUNC -HPy HPyBytes_FromStringAndSize(HPyContext *ctx, const char *bytes, HPy_ssize_t len) -{ - return WRAP(ctx->ctx_Bytes_FromStringAndSize((ctx), (bytes), (len))); -} - -HPyAPI_FUNC -HPy HPyUnicode_FromString(HPyContext *ctx, const char *utf8) -{ - return WRAP(ctx->ctx_Unicode_FromString((ctx), (utf8))); -} - -HPyAPI_FUNC -int HPyUnicode_Check(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Unicode_Check((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy HPyUnicode_AsASCIIString(HPyContext *ctx, HPy h) -{ - return WRAP(ctx->ctx_Unicode_AsASCIIString((ctx), UNWRAP(h))); -} - -HPyAPI_FUNC -HPy HPyUnicode_AsLatin1String(HPyContext *ctx, HPy h) -{ - return WRAP(ctx->ctx_Unicode_AsLatin1String((ctx), UNWRAP(h))); -} - -HPyAPI_FUNC -HPy HPyUnicode_AsUTF8String(HPyContext *ctx, HPy h) -{ - return WRAP(ctx->ctx_Unicode_AsUTF8String((ctx), UNWRAP(h))); -} - -HPyAPI_FUNC -const char *HPyUnicode_AsUTF8AndSize(HPyContext *ctx, HPy h, HPy_ssize_t *size) -{ - return ctx->ctx_Unicode_AsUTF8AndSize((ctx), UNWRAP(h), (size)); -} - -HPyAPI_FUNC -HPy HPyUnicode_FromWideChar(HPyContext *ctx, const wchar_t *w, HPy_ssize_t size) -{ - return WRAP(ctx->ctx_Unicode_FromWideChar((ctx), (w), (size))); -} - -HPyAPI_FUNC -HPy HPyUnicode_DecodeFSDefault(HPyContext *ctx, const char *v) -{ - return WRAP(ctx->ctx_Unicode_DecodeFSDefault((ctx), (v))); -} - -HPyAPI_FUNC -HPy HPyUnicode_DecodeFSDefaultAndSize(HPyContext *ctx, const char *v, HPy_ssize_t size) -{ - return WRAP(ctx->ctx_Unicode_DecodeFSDefaultAndSize((ctx), (v), (size))); -} - -HPyAPI_FUNC -HPy HPyUnicode_EncodeFSDefault(HPyContext *ctx, HPy h) -{ - return WRAP(ctx->ctx_Unicode_EncodeFSDefault((ctx), UNWRAP(h))); -} - -HPyAPI_FUNC -HPy_UCS4 HPyUnicode_ReadChar(HPyContext *ctx, HPy h, HPy_ssize_t index) -{ - return ctx->ctx_Unicode_ReadChar((ctx), UNWRAP(h), (index)); -} - -HPyAPI_FUNC -HPy HPyUnicode_DecodeASCII(HPyContext *ctx, const char *ascii, HPy_ssize_t size, const char *errors) -{ - return WRAP(ctx->ctx_Unicode_DecodeASCII((ctx), (ascii), (size), (errors))); -} - -HPyAPI_FUNC -HPy HPyUnicode_DecodeLatin1(HPyContext *ctx, const char *latin1, HPy_ssize_t size, const char *errors) -{ - return WRAP(ctx->ctx_Unicode_DecodeLatin1((ctx), (latin1), (size), (errors))); -} - -HPyAPI_FUNC -HPy HPyUnicode_FromEncodedObject(HPyContext *ctx, HPy obj, const char *encoding, const char *errors) -{ - return WRAP(ctx->ctx_Unicode_FromEncodedObject((ctx), UNWRAP(obj), (encoding), (errors))); -} - -HPyAPI_FUNC -HPy HPyUnicode_Substring(HPyContext *ctx, HPy str, HPy_ssize_t start, HPy_ssize_t end) -{ - return WRAP(ctx->ctx_Unicode_Substring((ctx), UNWRAP(str), (start), (end))); -} - -HPyAPI_FUNC -int HPyList_Check(HPyContext *ctx, HPy h) -{ - return ctx->ctx_List_Check((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy HPyList_New(HPyContext *ctx, HPy_ssize_t len) -{ - return WRAP(ctx->ctx_List_New((ctx), (len))); -} - -HPyAPI_FUNC -int HPyList_Append(HPyContext *ctx, HPy h_list, HPy h_item) -{ - return ctx->ctx_List_Append((ctx), UNWRAP(h_list), UNWRAP(h_item)); -} - -HPyAPI_FUNC -int HPyDict_Check(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Dict_Check((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy HPyDict_New(HPyContext *ctx) -{ - return WRAP(ctx->ctx_Dict_New((ctx))); -} - -HPyAPI_FUNC -HPy HPyDict_Keys(HPyContext *ctx, HPy h) -{ - return WRAP(ctx->ctx_Dict_Keys((ctx), UNWRAP(h))); -} - -HPyAPI_FUNC -HPy HPyDict_Copy(HPyContext *ctx, HPy h) -{ - return WRAP(ctx->ctx_Dict_Copy((ctx), UNWRAP(h))); -} - -HPyAPI_FUNC -int HPyTuple_Check(HPyContext *ctx, HPy h) -{ - return ctx->ctx_Tuple_Check((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy HPyTuple_FromArray(HPyContext *ctx, HPy items[], HPy_ssize_t n) -{ - return WRAP(ctx->ctx_Tuple_FromArray((ctx), (items), (n))); -} - -HPyAPI_FUNC -int HPySlice_Unpack(HPyContext *ctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step) -{ - return ctx->ctx_Slice_Unpack((ctx), UNWRAP(slice), (start), (stop), (step)); -} - -HPyAPI_FUNC -HPy HPyImport_ImportModule(HPyContext *ctx, const char *utf8_name) -{ - return WRAP(ctx->ctx_Import_ImportModule((ctx), (utf8_name))); -} - -HPyAPI_FUNC -HPy HPyCapsule_New(HPyContext *ctx, void *pointer, const char *utf8_name, HPyCapsule_Destructor *destructor) -{ - return WRAP(ctx->ctx_Capsule_New((ctx), (pointer), (utf8_name), (destructor))); -} - -HPyAPI_FUNC -void *HPyCapsule_Get(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, const char *utf8_name) -{ - return ctx->ctx_Capsule_Get((ctx), UNWRAP(capsule), (key), (utf8_name)); -} - -HPyAPI_FUNC -int HPyCapsule_IsValid(HPyContext *ctx, HPy capsule, const char *utf8_name) -{ - return ctx->ctx_Capsule_IsValid((ctx), UNWRAP(capsule), (utf8_name)); -} - -HPyAPI_FUNC -int HPyCapsule_Set(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, void *value) -{ - return ctx->ctx_Capsule_Set((ctx), UNWRAP(capsule), (key), (value)); -} - -HPyAPI_FUNC -HPy HPy_FromPyObject(HPyContext *ctx, cpy_PyObject *obj) -{ - return WRAP(ctx->ctx_FromPyObject((ctx), (obj))); -} - -HPyAPI_FUNC -cpy_PyObject *HPy_AsPyObject(HPyContext *ctx, HPy h) -{ - return ctx->ctx_AsPyObject((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -void _HPy_CallRealFunctionFromTrampoline(HPyContext *ctx, HPyFunc_Signature sig, HPyCFunction func, void *args) -{ - ctx->ctx_CallRealFunctionFromTrampoline((ctx), (sig), (func), (args)); -} - -HPyAPI_FUNC -HPyListBuilder HPyListBuilder_New(HPyContext *ctx, HPy_ssize_t size) -{ - return WRAP_LIST_BUILDER(ctx->ctx_ListBuilder_New((ctx), (size))); -} - -HPyAPI_FUNC -void HPyListBuilder_Set(HPyContext *ctx, HPyListBuilder builder, HPy_ssize_t index, HPy h_item) -{ - ctx->ctx_ListBuilder_Set((ctx), UNWRAP_LIST_BUILDER(builder), (index), UNWRAP(h_item)); -} - -HPyAPI_FUNC -HPy HPyListBuilder_Build(HPyContext *ctx, HPyListBuilder builder) -{ - return WRAP(ctx->ctx_ListBuilder_Build((ctx), UNWRAP_LIST_BUILDER(builder))); -} - -HPyAPI_FUNC -void HPyListBuilder_Cancel(HPyContext *ctx, HPyListBuilder builder) -{ - ctx->ctx_ListBuilder_Cancel((ctx), UNWRAP_LIST_BUILDER(builder)); -} - -HPyAPI_FUNC -HPyTupleBuilder HPyTupleBuilder_New(HPyContext *ctx, HPy_ssize_t size) -{ - return WRAP_TUPLE_BUILDER(ctx->ctx_TupleBuilder_New((ctx), (size))); -} - -HPyAPI_FUNC -void HPyTupleBuilder_Set(HPyContext *ctx, HPyTupleBuilder builder, HPy_ssize_t index, HPy h_item) -{ - ctx->ctx_TupleBuilder_Set((ctx), UNWRAP_TUPLE_BUILDER(builder), (index), UNWRAP(h_item)); -} - -HPyAPI_FUNC -HPy HPyTupleBuilder_Build(HPyContext *ctx, HPyTupleBuilder builder) -{ - return WRAP(ctx->ctx_TupleBuilder_Build((ctx), UNWRAP_TUPLE_BUILDER(builder))); -} - -HPyAPI_FUNC -void HPyTupleBuilder_Cancel(HPyContext *ctx, HPyTupleBuilder builder) -{ - ctx->ctx_TupleBuilder_Cancel((ctx), UNWRAP_TUPLE_BUILDER(builder)); -} - -HPyAPI_FUNC -HPyTracker HPyTracker_New(HPyContext *ctx, HPy_ssize_t size) -{ - return WRAP_TRACKER(ctx->ctx_Tracker_New((ctx), (size))); -} - -HPyAPI_FUNC -int HPyTracker_Add(HPyContext *ctx, HPyTracker ht, HPy h) -{ - return ctx->ctx_Tracker_Add((ctx), UNWRAP_TRACKER(ht), UNWRAP(h)); -} - -HPyAPI_FUNC -void HPyTracker_ForgetAll(HPyContext *ctx, HPyTracker ht) -{ - ctx->ctx_Tracker_ForgetAll((ctx), UNWRAP_TRACKER(ht)); -} - -HPyAPI_FUNC -void HPyTracker_Close(HPyContext *ctx, HPyTracker ht) -{ - ctx->ctx_Tracker_Close((ctx), UNWRAP_TRACKER(ht)); -} - -HPyAPI_FUNC -void HPyField_Store(HPyContext *ctx, HPy target_object, HPyField *target_field, HPy h) -{ - ctx->ctx_Field_Store((ctx), UNWRAP(target_object), (target_field), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy HPyField_Load(HPyContext *ctx, HPy source_object, HPyField source_field) -{ - return WRAP(ctx->ctx_Field_Load((ctx), UNWRAP(source_object), UNWRAP_FIELD(source_field))); -} - -HPyAPI_FUNC -void HPy_ReenterPythonExecution(HPyContext *ctx, HPyThreadState state) -{ - ctx->ctx_ReenterPythonExecution((ctx), UNWRAP_THREADSTATE(state)); -} - -HPyAPI_FUNC -HPyThreadState HPy_LeavePythonExecution(HPyContext *ctx) -{ - return WRAP_THREADSTATE(ctx->ctx_LeavePythonExecution((ctx))); -} - -HPyAPI_FUNC -void HPyGlobal_Store(HPyContext *ctx, HPyGlobal *global, HPy h) -{ - ctx->ctx_Global_Store((ctx), (global), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy HPyGlobal_Load(HPyContext *ctx, HPyGlobal global) -{ - return WRAP(ctx->ctx_Global_Load((ctx), UNWRAP_GLOBAL(global))); -} - -HPyAPI_FUNC -void _HPy_Dump(HPyContext *ctx, HPy h) -{ - ctx->ctx_Dump((ctx), UNWRAP(h)); -} - -HPyAPI_FUNC -HPy HPy_Compile_s(HPyContext *ctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind) -{ - return WRAP(ctx->ctx_Compile_s((ctx), (utf8_source), (utf8_filename), UNWRAP_SOURCE_KIND(kind))); -} - -HPyAPI_FUNC -HPy HPy_EvalCode(HPyContext *ctx, HPy code, HPy globals, HPy locals) -{ - return WRAP(ctx->ctx_EvalCode((ctx), UNWRAP(code), UNWRAP(globals), UNWRAP(locals))); -} - -HPyAPI_FUNC -HPy HPyContextVar_New(HPyContext *ctx, const char *name, HPy default_value) -{ - return WRAP(ctx->ctx_ContextVar_New((ctx), (name), UNWRAP(default_value))); -} - -HPyAPI_FUNC -int32_t HPyContextVar_Get(HPyContext *ctx, HPy context_var, HPy default_value, HPy *result) -{ - return ctx->ctx_ContextVar_Get((ctx), UNWRAP(context_var), UNWRAP(default_value), (result)); -} - -HPyAPI_FUNC -HPy HPyContextVar_Set(HPyContext *ctx, HPy context_var, HPy value) -{ - return WRAP(ctx->ctx_ContextVar_Set((ctx), UNWRAP(context_var), UNWRAP(value))); -} - -HPyAPI_FUNC -int HPy_SetCallFunction(HPyContext *ctx, HPy h, HPyCallFunction *func) -{ - return ctx->ctx_SetCallFunction((ctx), UNWRAP(h), (func)); -} - diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/version.h b/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/version.h deleted file mode 100644 index eb57b14570..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/version.h +++ /dev/null @@ -1,27 +0,0 @@ -/* MIT License - * - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -// automatically generated by setup.py:get_scm_config() -#define HPY_VERSION "0.9.0" -#define HPY_GIT_REVISION "f6114734" diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/src/autogen_c_access.h b/graalpython/com.oracle.graal.python.hpy.llvm/src/autogen_c_access.h deleted file mode 100644 index f345a3209b..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.llvm/src/autogen_c_access.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.graalpy.autogen_c_access - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -#ifndef _AUTOGEN_C_ACCESS_H -#define _AUTOGEN_C_ACCESS_H -#include - -#include "Python.h" -#include "structmember.h" - -static int fill_c_type_sizes(int32_t *ctype_sizes) -{ - ctype_sizes[0] = (int32_t) sizeof(HPyContext*); - ctype_sizes[1] = (int32_t) 0; - ctype_sizes[2] = (int32_t) sizeof(void*); - ctype_sizes[3] = (int32_t) sizeof(void**); - ctype_sizes[4] = (int32_t) sizeof(bool); - ctype_sizes[5] = (int32_t) sizeof(int); - ctype_sizes[6] = (int32_t) sizeof(unsigned int); - ctype_sizes[7] = (int32_t) sizeof(long); - ctype_sizes[8] = (int32_t) sizeof(unsigned long); - ctype_sizes[9] = (int32_t) sizeof(int8_t); - ctype_sizes[10] = (int32_t) sizeof(uint8_t); - ctype_sizes[11] = (int32_t) sizeof(int16_t); - ctype_sizes[12] = (int32_t) sizeof(uint16_t); - ctype_sizes[13] = (int32_t) sizeof(int32_t); - ctype_sizes[14] = (int32_t) sizeof(uint32_t); - ctype_sizes[15] = (int32_t) sizeof(float); - ctype_sizes[16] = (int32_t) sizeof(double); - ctype_sizes[17] = (int32_t) sizeof(int64_t); - ctype_sizes[18] = (int32_t) sizeof(uint64_t); - ctype_sizes[19] = (int32_t) sizeof(HPy); - ctype_sizes[20] = (int32_t) sizeof(HPy*); - ctype_sizes[21] = (int32_t) sizeof(const HPy*); - ctype_sizes[22] = (int32_t) sizeof(wchar_t*); - ctype_sizes[23] = (int32_t) sizeof(const wchar_t*); - ctype_sizes[24] = (int32_t) sizeof(char*); - ctype_sizes[25] = (int32_t) sizeof(const char*); - ctype_sizes[26] = (int32_t) sizeof(void*); - ctype_sizes[27] = (int32_t) sizeof(void**); - ctype_sizes[28] = (int32_t) sizeof(HPyTracker); - ctype_sizes[29] = (int32_t) sizeof(size_t); - ctype_sizes[30] = (int32_t) sizeof(HPy_ssize_t); - ctype_sizes[31] = (int32_t) sizeof(HPy_ssize_t*); - ctype_sizes[32] = (int32_t) sizeof(HPy_hash_t); - ctype_sizes[33] = (int32_t) sizeof(HPy_UCS4); - ctype_sizes[34] = (int32_t) sizeof(HPyTupleBuilder); - ctype_sizes[35] = (int32_t) sizeof(HPyListBuilder); - ctype_sizes[36] = (int32_t) sizeof(cpy_PyObject*); - ctype_sizes[37] = (int32_t) sizeof(cpy_PyMethodDef*); - ctype_sizes[38] = (int32_t) sizeof(HPyModuleDef*); - ctype_sizes[39] = (int32_t) sizeof(HPyType_Spec*); - ctype_sizes[40] = (int32_t) sizeof(HPyType_SpecParam); - ctype_sizes[41] = (int32_t) sizeof(HPyType_SpecParam*); - ctype_sizes[42] = (int32_t) sizeof(HPyDef*); - ctype_sizes[43] = (int32_t) sizeof(HPyThreadState); - ctype_sizes[44] = (int32_t) sizeof(HPyField); - ctype_sizes[45] = (int32_t) sizeof(HPyField*); - ctype_sizes[46] = (int32_t) sizeof(HPyGlobal); - ctype_sizes[47] = (int32_t) sizeof(HPyGlobal*); - ctype_sizes[48] = (int32_t) sizeof(HPyCapsule_Destructor*); - ctype_sizes[49] = (int32_t) sizeof(_HPyCapsule_key); - ctype_sizes[50] = (int32_t) sizeof(HPyType_BuiltinShape); - ctype_sizes[51] = (int32_t) sizeof(HPy_SourceKind); - ctype_sizes[52] = (int32_t) sizeof(HPyCallFunction*); - ctype_sizes[53] = (int32_t) sizeof(PyType_Slot); - ctype_sizes[54] = (int32_t) sizeof(PyType_Slot*); - ctype_sizes[55] = (int32_t) sizeof(HPyFunc_Signature); - ctype_sizes[56] = (int32_t) sizeof(HPyMember_FieldType); - ctype_sizes[57] = (int32_t) sizeof(HPySlot_Slot); - ctype_sizes[58] = (int32_t) sizeof(PyMemberDef); - ctype_sizes[59] = (int32_t) sizeof(HPy_buffer); - ctype_sizes[60] = (int32_t) sizeof(PyGetSetDef); - return 0; -}; - -static int fill_c_field_offsets(int32_t *cfield_offsets) -{ - cfield_offsets[0] = (int32_t) offsetof(HPyType_SpecParam, kind); - cfield_offsets[1] = (int32_t) offsetof(HPyType_SpecParam, object); - cfield_offsets[2] = (int32_t) offsetof(HPyType_Spec, name); - cfield_offsets[3] = (int32_t) offsetof(HPyType_Spec, basicsize); - cfield_offsets[4] = (int32_t) offsetof(HPyType_Spec, itemsize); - cfield_offsets[5] = (int32_t) offsetof(HPyType_Spec, flags); - cfield_offsets[6] = (int32_t) offsetof(HPyType_Spec, builtin_shape); - cfield_offsets[7] = (int32_t) offsetof(HPyType_Spec, legacy_slots); - cfield_offsets[8] = (int32_t) offsetof(HPyType_Spec, defines); - cfield_offsets[9] = (int32_t) offsetof(HPyType_Spec, doc); - cfield_offsets[10] = (int32_t) offsetof(HPyDef, kind); - cfield_offsets[11] = (int32_t) offsetof(HPyDef, meth.name); - cfield_offsets[12] = (int32_t) offsetof(HPyDef, meth.impl); - cfield_offsets[13] = (int32_t) offsetof(HPyDef, meth.signature); - cfield_offsets[14] = (int32_t) offsetof(HPyDef, meth.doc); - cfield_offsets[15] = (int32_t) offsetof(HPyDef, member.name); - cfield_offsets[16] = (int32_t) offsetof(HPyDef, member.type); - cfield_offsets[17] = (int32_t) offsetof(HPyDef, member.offset); - cfield_offsets[18] = (int32_t) offsetof(HPyDef, member.readonly); - cfield_offsets[19] = (int32_t) offsetof(HPyDef, member.doc); - cfield_offsets[20] = (int32_t) offsetof(HPyDef, getset.name); - cfield_offsets[21] = (int32_t) offsetof(HPyDef, getset.getter_impl); - cfield_offsets[22] = (int32_t) offsetof(HPyDef, getset.setter_impl); - cfield_offsets[23] = (int32_t) offsetof(HPyDef, getset.doc); - cfield_offsets[24] = (int32_t) offsetof(HPyDef, getset.closure); - cfield_offsets[25] = (int32_t) offsetof(HPyDef, slot.slot); - cfield_offsets[26] = (int32_t) offsetof(HPyDef, slot.impl); - cfield_offsets[27] = (int32_t) offsetof(PyType_Slot, slot); - cfield_offsets[28] = (int32_t) offsetof(PyType_Slot, pfunc); - cfield_offsets[29] = (int32_t) offsetof(HPyCapsule_Destructor, cpy_trampoline); - cfield_offsets[30] = (int32_t) offsetof(HPyCapsule_Destructor, impl); - cfield_offsets[31] = (int32_t) offsetof(HPyCallFunction, impl); - cfield_offsets[32] = (int32_t) offsetof(HPyModuleDef, doc); - cfield_offsets[33] = (int32_t) offsetof(HPyModuleDef, size); - cfield_offsets[34] = (int32_t) offsetof(HPyModuleDef, legacy_methods); - cfield_offsets[35] = (int32_t) offsetof(HPyModuleDef, defines); - cfield_offsets[36] = (int32_t) offsetof(HPyModuleDef, globals); - cfield_offsets[37] = (int32_t) offsetof(PyGetSetDef, name); - cfield_offsets[38] = (int32_t) offsetof(PyGetSetDef, get); - cfield_offsets[39] = (int32_t) offsetof(PyGetSetDef, set); - cfield_offsets[40] = (int32_t) offsetof(PyGetSetDef, doc); - cfield_offsets[41] = (int32_t) offsetof(PyGetSetDef, closure); - cfield_offsets[42] = (int32_t) offsetof(PyMemberDef, name); - cfield_offsets[43] = (int32_t) offsetof(PyMemberDef, type); - cfield_offsets[44] = (int32_t) offsetof(PyMemberDef, offset); - cfield_offsets[45] = (int32_t) offsetof(PyMemberDef, flags); - cfield_offsets[46] = (int32_t) offsetof(PyMemberDef, doc); - cfield_offsets[47] = (int32_t) offsetof(HPy_buffer, buf); - cfield_offsets[48] = (int32_t) offsetof(HPy_buffer, obj); - cfield_offsets[49] = (int32_t) offsetof(HPy_buffer, len); - cfield_offsets[50] = (int32_t) offsetof(HPy_buffer, itemsize); - cfield_offsets[51] = (int32_t) offsetof(HPy_buffer, readonly); - cfield_offsets[52] = (int32_t) offsetof(HPy_buffer, ndim); - cfield_offsets[53] = (int32_t) offsetof(HPy_buffer, format); - cfield_offsets[54] = (int32_t) offsetof(HPy_buffer, shape); - cfield_offsets[55] = (int32_t) offsetof(HPy_buffer, strides); - cfield_offsets[56] = (int32_t) offsetof(HPy_buffer, suboffsets); - cfield_offsets[57] = (int32_t) offsetof(HPy_buffer, internal); - return 0; -}; - -#endif - diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/src/hpy.c b/graalpython/com.oracle.graal.python.hpy.llvm/src/hpy.c deleted file mode 100644 index 6e2e4e92e0..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.llvm/src/hpy.c +++ /dev/null @@ -1,1357 +0,0 @@ -/* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "hpy.h" -#include "structmember.h" -#include -#include - -#include -#include -#include - -#include "autogen_c_access.h" - - -#define SRC_CS "utf-8" -#define UNWRAP(_h) ((_h)._i) -#define WRAP(_ptr) ((HPy){(_ptr)}) - -/* References to the managed HPy contexts (Java objects). */ -static HPyContext *g_universal_ctx; - -typedef HPyDef* HPyDefPtr; -typedef PyMemberDef cpy_PyMemberDef; -typedef PyGetSetDef cpy_PyGetSetDef; -typedef PyType_Slot cpy_PyTypeSlot; -typedef void* VoidPtr; - -POLYGLOT_DECLARE_TYPE(VoidPtr); -POLYGLOT_DECLARE_TYPE(HPy) -POLYGLOT_DECLARE_TYPE(HPyContext) -POLYGLOT_DECLARE_TYPE(int8_t) - -int Py_EXPORTED_SYMBOL graal_hpy_init(HPyContext *context, void *initObject, int32_t *c_type_sizes, int32_t *c_field_offsets) { - // save context in global for NFI upcalls - g_universal_ctx = context; - - // register the native type of HPy - polyglot_invoke(initObject, "setHPyContextNativeType", polyglot_HPyContext_typeid()); - polyglot_invoke(initObject, "setHPyNativeType", polyglot_HPy_typeid()); - polyglot_invoke(initObject, "setHPyArrayNativeType", polyglot_array_typeid(polyglot_HPy_typeid(), 0)); - - if (fill_c_type_sizes(c_type_sizes)) { - return 1; - } - if (fill_c_field_offsets(c_field_offsets)) { - return 1; - } - - return 0; -} - -void *graal_hpy_get_element_ptr(void *base, int64_t offset) { - return base + offset; -} - -void* graal_hpy_calloc(size_t count, size_t eltsize) { - return calloc(count, eltsize); -} - -void graal_hpy_free(void *ptr) { - free(ptr); -} - -void* graal_hpy_get_field_i(HPyField *hf) { - return hf->_i; -} - -void graal_hpy_set_field_i(HPyField *hf, void* i) { - hf->_i = i; -} - -void* graal_hpy_get_global_i(HPyGlobal *hg) { - return hg->_i; -} - -void graal_hpy_set_global_i(HPyGlobal *hg, void* i) { - hg->_i = i; -} - -void* graal_hpy_from_string(const char *ptr) { - return polyglot_from_string(ptr, SRC_CS); -} - -int graal_hpy_get_errno() { - return errno; -} - -char *graal_hpy_get_strerror(int i) { - if (i != 0) { - return strerror(i); - } - return "Error"; -} - -uint64_t graal_hpy_strlen(const char *ptr) { - return strlen(ptr); -} - -void* graal_hpy_from_HPy_array(void *arr, uint64_t len) { - /* - * We attach type 'VoidPtr arr[len]' instead of 'HPy arr[len]' because that - * saves the additional read of member '_i' if we would use - */ - return polyglot_from_VoidPtr_array(arr, len); -} - -void* graal_hpy_from_i8_array(void *arr, uint64_t len) { - return polyglot_from_i8_array(arr, len); -} - -/* - * Casts a 'wchar_t*' array to an 'int8_t*' array and also associates the proper length. - * The length is determined using 'wcslen' if 'len == -1'. - */ -int8_t* graal_hpy_i8_from_wchar_array(wchar_t *arr, uint64_t len) { - if (len == -1) { - len = (uint64_t) (wcslen(arr) * sizeof(wchar_t)); - } - return polyglot_from_i8_array((int8_t *) arr, len); -} - -/* - * Transforms a Java handle array to native. - * TODO(fa): This currently uses a workaround because Sulong does not fully - * support passing structs via interop. Therefore, we pretend to have 'void *' - * array and convert to handle using 'HPy_FromVoidP'. - */ -void* graal_hpy_array_to_native(VoidPtr *source, uint64_t len) { - uint64_t i; - HPy *dest = (HPy *)malloc(len*sizeof(HPy)); - for (i=0; i < len; i++) { - dest[i] = HPy_FromVoidP(source[i]); - } - return polyglot_from_HPy_array(dest, len); -} - -HPy_buffer* graal_hpy_buffer_to_native(void* buf, HPy obj, HPy_ssize_t len, HPy_ssize_t item_size, int readonly, int ndim, - int64_t format_ptr, int64_t shape_ptr, int64_t strides_ptr, int64_t suboffsets_ptr, void *internal) { - HPy_buffer *hpy_buffer = (HPy_buffer *) malloc(sizeof(HPy_buffer)); - hpy_buffer->buf = buf; - hpy_buffer->obj = obj; - hpy_buffer->len = len; - hpy_buffer->itemsize = item_size; - hpy_buffer->readonly = readonly; - hpy_buffer->ndim = ndim; - hpy_buffer->format = (char *)format_ptr; - hpy_buffer->shape = (HPy_ssize_t *)shape_ptr; - hpy_buffer->strides = (HPy_ssize_t *)strides_ptr; - hpy_buffer->suboffsets = (HPy_ssize_t *)suboffsets_ptr; - hpy_buffer->internal = internal; - return hpy_buffer; -} - -#define PRIMITIVE_ARRAY_TO_NATIVE(__jtype__, __ctype__, __polyglot_type__, __element_cast__) \ - void* graal_hpy_##__jtype__##_array_to_native(const void* jarray, int64_t len) { \ - int64_t i; \ - int64_t size = len + 1; \ - __ctype__* carr = (__ctype__*) malloc(size * sizeof(__ctype__)); \ - carr[len] = (__ctype__)0; \ - for (i=0; i < len; i++) { \ - carr[i] = __element_cast__(polyglot_get_array_element(jarray, i)); \ - } \ - return polyglot_from_##__polyglot_type__##_array(carr, len); \ - } \ - -PRIMITIVE_ARRAY_TO_NATIVE(byte, int8_t, i8, polyglot_as_i8); -PRIMITIVE_ARRAY_TO_NATIVE(int, int32_t, i32, polyglot_as_i32); -PRIMITIVE_ARRAY_TO_NATIVE(long, int64_t, i64, polyglot_as_i64); -PRIMITIVE_ARRAY_TO_NATIVE(double, double, double, polyglot_as_double); -PRIMITIVE_ARRAY_TO_NATIVE(pointer, VoidPtr, VoidPtr, (VoidPtr)); - -/*****************************************************************************/ -/* getter for reading native members */ -/*****************************************************************************/ - -#define ReadMember(object, offset, T) ((T*)(((char*)object) + offset))[0] - -bool graal_hpy_read_bool(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, bool); -} - -uint8_t graal_hpy_read_ui8(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, uint8_t); -} - -int8_t graal_hpy_read_i8(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, int8_t); -} - -int16_t graal_hpy_read_i16(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, int16_t); -} - -uint16_t graal_hpy_read_ui16(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, uint16_t); -} - -int32_t graal_hpy_read_i32(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, int32_t); -} - -uint32_t graal_hpy_read_ui32(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, uint32_t); -} - -int64_t graal_hpy_read_i64(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, int64_t); -} - -uint64_t graal_hpy_read_ui64(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, uint64_t); -} - -int graal_hpy_read_i(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, int); -} - -unsigned int graal_hpy_read_ui(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, unsigned int); -} - -long graal_hpy_read_l(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, long); -} - -unsigned long graal_hpy_read_ul(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, unsigned long); -} - -double graal_hpy_read_f(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, float); -} - -double graal_hpy_read_d(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, double); -} - -void* graal_hpy_read_ptr(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, void*); -} - -void* graal_hpy_read_HPy(void* object, HPy_ssize_t offset) { - return UNWRAP_FIELD(ReadMember(object, offset, HPy)); -} - -void* graal_hpy_read_HPyField(void* object, HPy_ssize_t offset) { - return UNWRAP_FIELD(ReadMember(object, offset, HPyField)); -} - -HPy_ssize_t graal_hpy_read_HPy_ssize_t(void* object, HPy_ssize_t offset) { - return ReadMember(object, offset, HPy_ssize_t); -} - -#undef ReadMember - -/*****************************************************************************/ -/* setter for writing native members */ -/*****************************************************************************/ - -#define WriteMember(object, offset, value, T) *(T*)(((char*)object) + offset) = (value) - -void graal_hpy_write_bool(void* object, HPy_ssize_t offset, bool value) { - WriteMember(object, offset, value, bool); -} - -void graal_hpy_write_i8(void* object, HPy_ssize_t offset, int8_t value) { - WriteMember(object, offset, value, int8_t); -} - -void graal_hpy_write_ui8(void* object, HPy_ssize_t offset, uint8_t value) { - WriteMember(object, offset, value, uint8_t); -} - -void graal_hpy_write_i16(void* object, HPy_ssize_t offset, int16_t value) { - WriteMember(object, offset, value, int16_t); -} - -void graal_hpy_write_ui16(void* object, HPy_ssize_t offset, uint16_t value) { - WriteMember(object, offset, value, uint16_t); -} - -void graal_hpy_write_i32(void* object, HPy_ssize_t offset, int32_t value) { - WriteMember(object, offset, value, int32_t); -} - -void graal_hpy_write_ui32(void* object, HPy_ssize_t offset, uint32_t value) { - WriteMember(object, offset, value, uint32_t); -} - -void graal_hpy_write_i64(void* object, HPy_ssize_t offset, int64_t value) { - WriteMember(object, offset, value, int64_t); -} - -void graal_hpy_write_ui64(void* object, HPy_ssize_t offset, uint64_t value) { - WriteMember(object, offset, value, uint64_t); -} - -void graal_hpy_write_i(void* object, HPy_ssize_t offset, int value) { - WriteMember(object, offset, (value), int); -} - -void graal_hpy_write_l(void* object, HPy_ssize_t offset, long value) { - WriteMember(object, offset, (value), long); -} - -void graal_hpy_write_f(void* object, HPy_ssize_t offset, float value) { - WriteMember(object, offset, (value), float); -} - -void graal_hpy_write_d(void* object, HPy_ssize_t offset, double value) { - WriteMember(object, offset, (value), double); -} - -void graal_hpy_write_HPy(void* object, HPy_ssize_t offset, void* value) { - WriteMember(object, offset, WRAP(value), HPy); -} - -void graal_hpy_write_HPyField(void* object, HPy_ssize_t offset, void* value) { - WriteMember(object, offset, WRAP_FIELD(value), HPyField); -} - -void graal_hpy_write_ui(void* object, HPy_ssize_t offset, unsigned int value) { - WriteMember(object, offset, value, unsigned int); -} - -void graal_hpy_write_ul(void* object, HPy_ssize_t offset, unsigned long value) { - WriteMember(object, offset, value, unsigned long); -} - -void graal_hpy_write_HPy_ssize_t(void* object, HPy_ssize_t offset, HPy_ssize_t value) { - WriteMember(object, offset, value, HPy_ssize_t); -} - -void graal_hpy_write_ptr(void* object, HPy_ssize_t offset, void* value) { - WriteMember(object, offset, value, void*); -} - -#undef WriteMember - -typedef void (*destroyfunc)(void*); -/* to be used from Java code only */ -int graal_hpy_bulk_free(uint64_t ptrArray[], int64_t len) -{ - int64_t i; - uint64_t obj; - destroyfunc func; - - for (i = 0; i < len; i += 2) { - obj = ptrArray[i]; - func = (destroyfunc) ptrArray[i + 1]; - if (obj) { - if (func != NULL) { - func((void*) obj); - } - free((void*) obj); - } - } - return 0; -} - -/*****************************************************************************/ -/* HPy context helper functions */ -/*****************************************************************************/ - - -#define HPyAPI_STORAGE _HPy_HIDDEN -#define _HPy_IMPL_NAME(name) ctx_##name -#define _HPy_IMPL_NAME_NOPREFIX(name) ctx_##name -#define _py2h(_x) HPy_NULL -#define _h2py(_x) NULL - -typedef HPy* _HPyPtr; -typedef HPyField* _HPyFieldPtr; -typedef HPy _HPyConst; -typedef HPyGlobal* _HPyGlobalPtr; - -#define HPy void* -#define HPyListBuilder void* -#define HPyTupleBuilder void* -#define HPyTracker void* -#define HPyField void* -#define HPyThreadState void* -#define HPyGlobal void* -#define _HPyCapsule_key int32_t - -#define SELECT_CTX(__ctx__) (g_universal_ctx) - -#define UPCALL_HPY(__name__, __ctx__, ...) polyglot_invoke(SELECT_CTX(__ctx__), #__name__, (__ctx__), __VA_ARGS__) -#define UPCALL_HPY0(__name__, __ctx__) polyglot_invoke(SELECT_CTX(__ctx__), #__name__, (__ctx__)) -#define UPCALL_CHARPTR(__name__, __ctx__, ...) ((char*)polyglot_invoke(SELECT_CTX(__ctx__), #__name__, (__ctx__), __VA_ARGS__)) -#define UPCALL_VOID(__name__, __ctx__, ...) (void)polyglot_invoke(SELECT_CTX(__ctx__), #__name__, (__ctx__), __VA_ARGS__) -#define UPCALL_VOID0(__name__, __ctx__) ((void)polyglot_invoke(SELECT_CTX(__ctx__), #__name__, (__ctx__))) -#define UPCALL_DOUBLE(__name__, __ctx__, ...) polyglot_as_double(polyglot_invoke(SELECT_CTX(__ctx__), #__name__, (__ctx__), __VA_ARGS__)) -#define UPCALL_I64(__name__, __ctx__, ...) polyglot_as_i64(polyglot_invoke(SELECT_CTX(__ctx__), #__name__, (__ctx__), __VA_ARGS__)) -#define UPCALL_I32(__name__, __ctx__, ...) polyglot_as_i32(polyglot_invoke(SELECT_CTX(__ctx__), #__name__, (__ctx__), __VA_ARGS__)) - - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Module_Create)(HPyContext *ctx, HPyModuleDef *hpydef) -{ - return UPCALL_HPY(ctx_Module_Create, ctx, hpydef); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Dup)(HPyContext *ctx, HPy h) -{ - return UPCALL_HPY(ctx_Dup, ctx, h); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(Close)(HPyContext *ctx, HPy h) -{ - UPCALL_VOID(ctx_Close, ctx, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Long_FromLong)(HPyContext *ctx, long v) -{ - return UPCALL_HPY(ctx_Long_FromLong, ctx, v); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Long_FromUnsignedLong)(HPyContext *ctx, unsigned long v) -{ - return UPCALL_HPY(ctx_Long_FromUnsignedLong, ctx, v); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Long_FromLongLong)(HPyContext *ctx, long long v) -{ - return UPCALL_HPY(ctx_Long_FromLongLong, ctx, v); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Long_FromUnsignedLongLong)(HPyContext *ctx, unsigned long long v) -{ - return UPCALL_HPY(ctx_Long_FromUnsignedLongLong, ctx, v); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Long_FromSize_t)(HPyContext *ctx, size_t v) -{ - return UPCALL_HPY(ctx_Long_FromSize_t, ctx, v); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Long_FromSsize_t)(HPyContext *ctx, HPy_ssize_t v) -{ - return UPCALL_HPY(ctx_Long_FromSsize_t, ctx, v); -} - -HPyAPI_STORAGE long _HPy_IMPL_NAME(Long_AsLong)(HPyContext *ctx, HPy h) -{ - return (long) UPCALL_I64(ctx_Long_AsLong, ctx, h); -} - -HPyAPI_STORAGE unsigned long _HPy_IMPL_NAME(Long_AsUnsignedLong)(HPyContext *ctx, HPy h) -{ - return (unsigned long) UPCALL_I64(ctx_Long_AsUnsignedLong, ctx, h); -} - -HPyAPI_STORAGE unsigned long _HPy_IMPL_NAME(Long_AsUnsignedLongMask)(HPyContext *ctx, HPy h) -{ - return (unsigned long) UPCALL_I64(ctx_Long_AsUnsignedLongMask, ctx, h); -} - -HPyAPI_STORAGE long long _HPy_IMPL_NAME(Long_AsLongLong)(HPyContext *ctx, HPy h) -{ - return (long long) UPCALL_I64(ctx_Long_AsLongLong, ctx, h); -} - -HPyAPI_STORAGE unsigned long long _HPy_IMPL_NAME(Long_AsUnsignedLongLong)(HPyContext *ctx, HPy h) -{ - return (unsigned long long) UPCALL_I64(ctx_Long_AsUnsignedLongLong, ctx, h); -} - -HPyAPI_STORAGE unsigned long long _HPy_IMPL_NAME(Long_AsUnsignedLongLongMask)(HPyContext *ctx, HPy h) -{ - return (unsigned long long) UPCALL_I64(ctx_Long_AsUnsignedLongLongMask, ctx, h); -} - -HPyAPI_STORAGE size_t _HPy_IMPL_NAME(Long_AsSize_t)(HPyContext *ctx, HPy h) -{ - return (size_t) UPCALL_I64(ctx_Long_AsSize_t, ctx, h); -} - -HPyAPI_STORAGE HPy_ssize_t _HPy_IMPL_NAME(Long_AsSsize_t)(HPyContext *ctx, HPy h) -{ - return (HPy_ssize_t) UPCALL_I64(ctx_Long_AsSsize_t, ctx, h); -} - -HPyAPI_STORAGE void* _HPy_IMPL_NAME(Long_AsVoidPtr)(HPyContext *ctx, HPy h) { - return (void *) UPCALL_I64(ctx_Long_AsVoidPtr, ctx, h); -} - -HPyAPI_STORAGE double _HPy_IMPL_NAME(Long_AsDouble)(HPyContext *ctx, HPy h) { - return UPCALL_DOUBLE(ctx_Long_AsDouble, ctx, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Float_FromDouble)(HPyContext *ctx, double v) -{ - return UPCALL_HPY(ctx_Float_FromDouble, ctx, v); -} - -HPyAPI_STORAGE double _HPy_IMPL_NAME(Float_AsDouble)(HPyContext *ctx, HPy h) -{ - return UPCALL_DOUBLE(ctx_Float_AsDouble, ctx, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Bool_FromLong)(HPyContext *ctx, long v) -{ - return UPCALL_HPY(ctx_Bool_FromLong, ctx, v); -} - -HPyAPI_STORAGE HPy_ssize_t _HPy_IMPL_NAME_NOPREFIX(Length)(HPyContext *ctx, HPy h) -{ - return (HPy_ssize_t) UPCALL_I64(ctx_Length, ctx, h); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Number_Check)(HPyContext *ctx, HPy h) -{ - return (int) UPCALL_I32(ctx_Number_Check, ctx, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Add)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_Add, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Subtract)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_Subtract, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Multiply)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_Multiply, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(MatrixMultiply)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_MatrixMultiply, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(FloorDivide)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_FloorDivide, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(TrueDivide)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_TrueDivide, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Remainder)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_Remainder, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Divmod)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_Divmod, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Power)(HPyContext *ctx, HPy h1, HPy h2, HPy h3) -{ - return UPCALL_HPY(ctx_Power, ctx, h1, h2, h3); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Negative)(HPyContext *ctx, HPy h1) -{ - return UPCALL_HPY(ctx_Negative, ctx, h1); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Positive)(HPyContext *ctx, HPy h1) -{ - return UPCALL_HPY(ctx_Positive, ctx, h1); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Absolute)(HPyContext *ctx, HPy h1) -{ - return UPCALL_HPY(ctx_Absolute, ctx, h1); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Invert)(HPyContext *ctx, HPy h1) -{ - return UPCALL_HPY(ctx_Invert, ctx, h1); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Lshift)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_Lshift, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Rshift)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_Rshift, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(And)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_And, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Xor)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_Xor, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Or)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_Or, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Index)(HPyContext *ctx, HPy h1) -{ - return UPCALL_HPY(ctx_Index, ctx, h1); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Long)(HPyContext *ctx, HPy h1) -{ - return UPCALL_HPY(ctx_Long, ctx, h1); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Float)(HPyContext *ctx, HPy h1) -{ - return UPCALL_HPY(ctx_Float, ctx, h1); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(InPlaceAdd)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_InPlaceAdd, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(InPlaceSubtract)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_InPlaceSubtract, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(InPlaceMultiply)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_InPlaceMultiply, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(InPlaceMatrixMultiply)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_InPlaceMatrixMultiply, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(InPlaceFloorDivide)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_InPlaceFloorDivide, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(InPlaceTrueDivide)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_InPlaceTrueDivide, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(InPlaceRemainder)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_InPlaceRemainder, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(InPlacePower)(HPyContext *ctx, HPy h1, HPy h2, HPy h3) -{ - return UPCALL_HPY(ctx_InPlacePower, ctx, h1, h2, h3); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(InPlaceLshift)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_InPlaceLshift, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(InPlaceRshift)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_InPlaceRshift, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(InPlaceAnd)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_InPlaceAnd, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(InPlaceXor)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_InPlaceXor, ctx, h1, h2); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(InPlaceOr)(HPyContext *ctx, HPy h1, HPy h2) -{ - return UPCALL_HPY(ctx_InPlaceOr, ctx, h1, h2); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Callable_Check)(HPyContext *ctx, HPy h) -{ - return (int) UPCALL_I32(ctx_Callable_Check, ctx, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(CallTupleDict)(HPyContext *ctx, HPy callable, HPy args, HPy kw) -{ - return UPCALL_HPY(ctx_CallTupleDict, ctx, callable, args, kw); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(Err_SetString)(HPyContext *ctx, HPy h_type, const char *message) -{ - UPCALL_VOID(ctx_Err_SetString, ctx, h_type, message); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(Err_SetObject)(HPyContext *ctx, HPy h_type, HPy h_value) -{ - UPCALL_VOID(ctx_Err_SetObject, ctx, h_type, h_value); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Err_SetFromErrnoWithFilename)(HPyContext *ctx, HPy h_type, const char *filename_fsencoded) { - return UPCALL_HPY(ctx_Err_SetFromErrnoWithFilename, ctx, h_type, filename_fsencoded); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(Err_SetFromErrnoWithFilenameObjects)(HPyContext *ctx, HPy h_type, HPy filename1, HPy filename2) { - UPCALL_VOID(ctx_Err_SetFromErrnoWithFilenameObjects, ctx, h_type, filename1, filename2); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Err_Occurred)(HPyContext *ctx) -{ - return (int) polyglot_as_i32(UPCALL_HPY0(ctx_Err_Occurred, ctx)); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Err_ExceptionMatches)(HPyContext *ctx, HPy exc) { - return (int) UPCALL_I32(ctx_Err_ExceptionMatches, ctx, exc); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(Err_NoMemory)(HPyContext *ctx) -{ - UPCALL_VOID0(ctx_Err_NoMemory, ctx); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(Err_Clear)(HPyContext *ctx) -{ - UPCALL_VOID0(ctx_Err_Clear, ctx); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Err_NewException)(HPyContext *ctx, const char *name, HPy base, HPy dict) { - return UPCALL_HPY(ctx_Err_NewException, ctx, name, base, dict); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Err_NewExceptionWithDoc)(HPyContext *ctx, const char *name, const char *doc, HPy base, HPy dict) { - return UPCALL_HPY(ctx_Err_NewExceptionWithDoc, ctx, name, doc, base, dict); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Err_WarnEx)(HPyContext *ctx, HPy category, const char *message, HPy_ssize_t stack_level) { - return (int) UPCALL_I32(ctx_Err_WarnEx, ctx, category, message, stack_level); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(Err_WriteUnraisable)(HPyContext *ctx, HPy obj) { - UPCALL_VOID(ctx_Err_WriteUnraisable, ctx, obj); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(FatalError)(HPyContext *ctx, const char *msg) { - UPCALL_VOID(ctx_FatalError, ctx, msg); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(IsTrue)(HPyContext *ctx, HPy h) -{ - return UPCALL_HPY(ctx_IsTrue, ctx, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Type_FromSpec)(HPyContext *ctx, HPyType_Spec *spec, HPyType_SpecParam *params) -{ - return UPCALL_HPY(ctx_Type_FromSpec, ctx, spec, params); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Type_GenericNew)(HPyContext *ctx, HPy type, _HPyPtr args, HPy_ssize_t nargs, HPy kw) -{ - return UPCALL_HPY(ctx_Type_GenericNew, ctx, type, args, nargs, kw); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(GetAttr)(HPyContext *ctx, HPy obj, HPy name) -{ - return UPCALL_HPY(ctx_GetAttr, ctx, obj, name); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(GetAttr_s)(HPyContext *ctx, HPy obj, const char *name) -{ - return UPCALL_HPY(ctx_GetAttr_s, ctx, obj, name); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(HasAttr)(HPyContext *ctx, HPy obj, HPy name) -{ - return (int) UPCALL_I32(ctx_HasAttr, ctx, obj, name); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(HasAttr_s)(HPyContext *ctx, HPy obj, const char *name) -{ - return (int) UPCALL_I32(ctx_HasAttr_s, ctx, obj, name); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(SetAttr)(HPyContext *ctx, HPy obj, HPy name, HPy value) -{ - return (int) UPCALL_I32(ctx_SetAttr, ctx, obj, name, value); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(SetAttr_s)(HPyContext *ctx, HPy obj, const char *name, HPy value) -{ - return (int) UPCALL_I32(ctx_SetAttr_s, ctx, obj, name, value); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(GetItem)(HPyContext *ctx, HPy obj, HPy key) -{ - return UPCALL_HPY(ctx_GetItem, ctx, obj, key); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(GetItem_i)(HPyContext *ctx, HPy obj, HPy_ssize_t idx) -{ - return UPCALL_HPY(ctx_GetItem_i, ctx, obj, idx); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(GetItem_s)(HPyContext *ctx, HPy obj, const char *key) -{ - return UPCALL_HPY(ctx_GetItem_s, ctx, obj, key); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(Contains)(HPyContext *ctx, HPy container, HPy key) { - return (int) UPCALL_I32(ctx_Contains, ctx, container, key); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(SetItem)(HPyContext *ctx, HPy obj, HPy key, HPy value) -{ - return UPCALL_HPY(ctx_SetItem, ctx, obj, key, value); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(SetItem_i)(HPyContext *ctx, HPy obj, HPy_ssize_t idx, HPy value) -{ - return UPCALL_HPY(ctx_SetItem_i, ctx, obj, idx, value); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(SetItem_s)(HPyContext *ctx, HPy obj, const char *key, HPy value) -{ - return UPCALL_HPY(ctx_SetItem_s, ctx, obj, key, value); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Type)(HPyContext *ctx, HPy obj) -{ - return UPCALL_HPY(ctx_Type, ctx, obj); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(TypeCheck)(HPyContext *ctx, HPy obj, HPy type) -{ - return (int) UPCALL_I32(ctx_TypeCheck, ctx, obj, type); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(TypeCheck_g)(HPyContext *ctx, HPy obj, HPyGlobal type) -{ - return (int) UPCALL_I32(ctx_TypeCheck_g, ctx, obj, type); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(Is)(HPyContext *ctx, HPy obj, HPy other) -{ - return (int) UPCALL_I32(ctx_Is, ctx, obj, other); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(Is_g)(HPyContext *ctx, HPy obj, HPyGlobal other) -{ - return (int) UPCALL_I32(ctx_Is_g, ctx, obj, other); -} - -HPyAPI_STORAGE void *_HPy_IMPL_NAME_NOPREFIX(AsStruct)(HPyContext *ctx, HPy obj) -{ - return UPCALL_HPY(ctx_AsStruct, ctx, obj); -} - -HPyAPI_STORAGE void *_HPy_IMPL_NAME_NOPREFIX(AsStructLegacy)(HPyContext *ctx, HPy obj) -{ - return UPCALL_HPY(ctx_AsStructLegacy, ctx, obj); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(New)(HPyContext *ctx, HPy h_type, void **data) -{ - return UPCALL_HPY(ctx_New, ctx, h_type, data); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Repr)(HPyContext *ctx, HPy obj) -{ - return UPCALL_HPY(ctx_Repr, ctx, obj); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Str)(HPyContext *ctx, HPy obj) -{ - return UPCALL_HPY(ctx_Str, ctx, obj); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(ASCII)(HPyContext *ctx, HPy obj) -{ - return UPCALL_HPY(ctx_ASCII, ctx, obj); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(Bytes)(HPyContext *ctx, HPy obj) -{ - return UPCALL_HPY(ctx_Bytes, ctx, obj); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(RichCompare)(HPyContext *ctx, HPy v, HPy w, int op) -{ - return UPCALL_HPY(ctx_RichCompare, ctx, v, w, op); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(RichCompareBool)(HPyContext *ctx, HPy v, HPy w, int op) -{ - return (int) UPCALL_I32(ctx_RichCompareBool, ctx, v, w, op); -} - -HPyAPI_STORAGE HPy_hash_t _HPy_IMPL_NAME_NOPREFIX(Hash)(HPyContext *ctx, HPy obj) -{ - return (HPy_hash_t) UPCALL_I64(ctx_Hash, ctx, obj); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Bytes_Check)(HPyContext *ctx, HPy h) -{ - return (int) UPCALL_I32(ctx_Bytes_Check, ctx, h); -} - -HPyAPI_STORAGE HPy_ssize_t _HPy_IMPL_NAME(Bytes_Size)(HPyContext *ctx, HPy h) -{ - return (HPy_ssize_t) UPCALL_I64(ctx_Bytes_Size, ctx, h); -} - -HPyAPI_STORAGE HPy_ssize_t _HPy_IMPL_NAME(Bytes_GET_SIZE)(HPyContext *ctx, HPy h) -{ - return (HPy_ssize_t) UPCALL_I64(ctx_Bytes_GET_SIZE, ctx, h); -} - -HPyAPI_STORAGE char *_HPy_IMPL_NAME(Bytes_AsString)(HPyContext *ctx, HPy h) -{ - return UPCALL_CHARPTR(ctx_Bytes_AsString, ctx, h); -} - -HPyAPI_STORAGE char *_HPy_IMPL_NAME(Bytes_AS_STRING)(HPyContext *ctx, HPy h) -{ - return UPCALL_CHARPTR(ctx_Bytes_AS_STRING, ctx, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Bytes_FromString)(HPyContext *ctx, const char *v) -{ - return UPCALL_HPY(ctx_Bytes_FromString, ctx, v); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Bytes_FromStringAndSize)(HPyContext *ctx, const char *v, HPy_ssize_t len) -{ - return UPCALL_HPY(ctx_Bytes_FromStringAndSize, ctx, v, len); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_FromString)(HPyContext *ctx, const char *utf8) -{ - return UPCALL_HPY(ctx_Unicode_FromString, ctx, utf8); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Unicode_Check)(HPyContext *ctx, HPy h) -{ - return (int) UPCALL_I32(ctx_Unicode_Check, ctx, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_AsASCIIString)(HPyContext *ctx, HPy h) { - return UPCALL_HPY(ctx_Unicode_AsASCIIString, ctx, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_AsLatin1String)(HPyContext *ctx, HPy h) { - return UPCALL_HPY(ctx_Unicode_AsLatin1String, ctx, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_AsUTF8String)(HPyContext *ctx, HPy h) -{ - return UPCALL_HPY(ctx_Unicode_AsUTF8String, ctx, h); -} - -HPyAPI_STORAGE const char *_HPy_IMPL_NAME(Unicode_AsUTF8AndSize)(HPyContext *ctx, HPy h, HPy_ssize_t *size) { - return UPCALL_CHARPTR(ctx_Unicode_AsUTF8AndSize, ctx, h, size); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_FromWideChar)(HPyContext *ctx, const wchar_t *w, HPy_ssize_t size) -{ - return UPCALL_HPY(ctx_Unicode_FromWideChar, ctx, w, size); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_DecodeFSDefault)(HPyContext *ctx, const char *v) -{ - return UPCALL_HPY(ctx_Unicode_DecodeFSDefault, ctx, v); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_DecodeFSDefaultAndSize)(HPyContext *ctx, const char *v, HPy_ssize_t size) { - return UPCALL_HPY(ctx_Unicode_DecodeFSDefaultAndSize, ctx, v, size); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_EncodeFSDefault)(HPyContext *ctx, HPy h) { - return UPCALL_HPY(ctx_Unicode_EncodeFSDefault, ctx, h); -} - -HPyAPI_STORAGE uint32_t _HPy_IMPL_NAME(Unicode_ReadChar)(HPyContext *ctx, HPy h, HPy_ssize_t index) { - return (uint32_t) UPCALL_I32(ctx_Unicode_ReadChar, ctx, h, index); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_DecodeLatin1)(HPyContext *ctx, const char *s, HPy_ssize_t size, const char *errors) { - return UPCALL_HPY(ctx_Unicode_DecodeLatin1, ctx, s, size, errors ); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_DecodeASCII)(HPyContext *ctx, const char *s, HPy_ssize_t size, const char *errors) { - return UPCALL_HPY(ctx_Unicode_DecodeASCII, ctx, s, size, errors ); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(List_Check)(HPyContext *ctx, HPy h) -{ - return (int) UPCALL_I32(ctx_List_Check, ctx, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(List_New)(HPyContext *ctx, HPy_ssize_t len) -{ - return UPCALL_HPY(ctx_List_New, ctx, len); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(List_Append)(HPyContext *ctx, HPy h_list, HPy h_item) -{ - return (int) UPCALL_I32(ctx_List_Append, ctx, h_list, h_item); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Dict_Check)(HPyContext *ctx, HPy h) -{ - return (int) UPCALL_I32(ctx_Dict_Check, ctx, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Dict_New)(HPyContext *ctx) -{ - return UPCALL_HPY0(ctx_Dict_New, ctx); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Tuple_Check)(HPyContext *ctx, HPy h) -{ - return (int) UPCALL_I32(ctx_Tuple_Check, ctx, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Tuple_FromArray)(HPyContext *ctx, _HPyPtr items, HPy_ssize_t n) -{ - return UPCALL_HPY(ctx_Tuple_FromArray, ctx, items, n); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Import_ImportModule)(HPyContext *ctx, const char *name) -{ - return UPCALL_HPY(ctx_Import_ImportModule, ctx, name); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(FromPyObject)(HPyContext *ctx, cpy_PyObject *obj) -{ - /* Although, this operation is not supported for in ABI compatibility mode, we still - need to implement the callback properly because it might still be a valid path - in other modes. */ - return UPCALL_HPY(ctx_FromPyObject, ctx, obj); -} - -HPyAPI_STORAGE cpy_PyObject *_HPy_IMPL_NAME_NOPREFIX(AsPyObject)(HPyContext *ctx, HPy h) -{ - return (cpy_PyObject *) UPCALL_CHARPTR(ctx_AsPyObject, ctx, h); -} - -HPyAPI_STORAGE HPyListBuilder _HPy_IMPL_NAME(ListBuilder_New)(HPyContext *ctx, HPy_ssize_t initial_size) { - return UPCALL_HPY(ctx_ListBuilder_New, ctx, initial_size); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(ListBuilder_Set)(HPyContext *ctx, HPyListBuilder builder, HPy_ssize_t index, HPy h_item) { - UPCALL_VOID(ctx_ListBuilder_Set, ctx, builder, index, h_item); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(ListBuilder_Build)(HPyContext *ctx, HPyListBuilder builder) { - return UPCALL_HPY(ctx_ListBuilder_Build, ctx, builder); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(ListBuilder_Cancel)(HPyContext *ctx, HPyListBuilder builder) { - UPCALL_VOID(ctx_ListBuilder_Cancel, ctx, builder); -} - -HPyAPI_STORAGE HPyTupleBuilder _HPy_IMPL_NAME(TupleBuilder_New)(HPyContext *ctx, HPy_ssize_t initial_size) { - return UPCALL_HPY(ctx_TupleBuilder_New, ctx, initial_size); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(TupleBuilder_Set)(HPyContext *ctx, HPyTupleBuilder builder, HPy_ssize_t index, HPy h_item) { - UPCALL_VOID(ctx_TupleBuilder_Set, ctx, builder, index, h_item); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(TupleBuilder_Build)(HPyContext *ctx, HPyTupleBuilder builder) { - return UPCALL_HPY(ctx_TupleBuilder_Build, ctx, builder); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(TupleBuilder_Cancel)(HPyContext *ctx, HPyTupleBuilder builder) { - UPCALL_VOID(ctx_TupleBuilder_Cancel, ctx, builder); -} - -HPyAPI_STORAGE HPyTracker _HPy_IMPL_NAME(Tracker_New)(HPyContext *ctx, HPy_ssize_t size) { - return UPCALL_HPY(ctx_Tracker_New, ctx, size); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Tracker_Add)(HPyContext *ctx, HPyTracker ht, HPy h) { - return (int) UPCALL_I32(ctx_Tracker_Add, ctx, ht, h); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(Tracker_ForgetAll)(HPyContext *ctx, HPyTracker ht) { - UPCALL_VOID(ctx_Tracker_ForgetAll, ctx, ht); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(Tracker_Close)(HPyContext *ctx, HPyTracker ht) { - UPCALL_VOID(ctx_Tracker_Close, ctx, ht); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(Field_Store)(HPyContext *ctx, HPy target_object, _HPyFieldPtr target_field, HPy h) { - UPCALL_VOID(ctx_Field_Store, ctx, target_object, target_field, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Field_Load)(HPyContext *ctx, HPy source_object, HPyField source_field) { - return UPCALL_HPY(ctx_Field_Load, ctx, source_object, source_field); -} - -HPyAPI_STORAGE HPyThreadState _HPy_IMPL_NAME(LeavePythonExecution)(HPyContext *ctx) { - return UPCALL_HPY0(ctx_LeavePythonExecution, ctx); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(ReenterPythonExecution)(HPyContext *ctx, HPyThreadState state) { - UPCALL_VOID(ctx_ReenterPythonExecution, ctx, state); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(Global_Store)(HPyContext *ctx, _HPyGlobalPtr global, HPy h) { - UPCALL_VOID(ctx_Global_Store, ctx, global, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Global_Load)(HPyContext *ctx, HPyGlobal global) { - return UPCALL_HPY(ctx_Global_Load, ctx, global); -} - -HPyAPI_STORAGE void _HPy_IMPL_NAME(Dump)(HPyContext *ctx, HPy h) { - UPCALL_VOID(ctx_Dump, ctx, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(MaybeGetAttr_s)(HPyContext *ctx, HPy obj, const char *name) { - return UPCALL_HPY(ctx_MaybeGetAttr_s, ctx, obj, name); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(SetType)(HPyContext *ctx, HPy obj, HPy type) { - return (int) UPCALL_I32(ctx_SetType, ctx, obj, type); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Type_IsSubtype)(HPyContext *ctx, HPy sub, HPy type) { - return (int) UPCALL_I32(ctx_Type_IsSubtype, ctx, sub, type); -} - -HPyAPI_STORAGE const char* _HPy_IMPL_NAME(Type_GetName)(HPyContext *ctx, HPy type) { - return UPCALL_CHARPTR(ctx_Type_GetName, ctx, type); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_FromEncodedObject)(HPyContext *ctx, HPy obj, const char *encoding, const char *errors) { - return UPCALL_HPY(ctx_Unicode_FromEncodedObject, ctx, obj, encoding, errors); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_InternFromString)(HPyContext *ctx, const char *str) { - return UPCALL_HPY(ctx_Unicode_InternFromString, ctx, str); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_Substring)(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) { - return UPCALL_HPY(ctx_Unicode_Substring, ctx, obj, start, end); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Dict_Keys)(HPyContext *ctx, HPy h) { - return UPCALL_HPY(ctx_Dict_Keys, ctx, h); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Dict_GetItem)(HPyContext *ctx, HPy op, HPy key) { - return UPCALL_HPY(ctx_Dict_GetItem, ctx, op, key); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(ContextVar_New)(HPyContext *ctx, const char *name, HPy default_value) { - return UPCALL_HPY(ctx_ContextVar_New, ctx, name, default_value); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(ContextVar_Get)(HPyContext *ctx, HPy context_var, HPy default_value, _HPyPtr result) { - return (int) UPCALL_I32(ctx_ContextVar_Get, ctx, context_var, default_value, result); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(ContextVar_Set)(HPyContext *ctx, HPy context_var, HPy value) { - return UPCALL_HPY(ctx_ContextVar_Set, ctx, context_var, value); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Capsule_New)(HPyContext *ctx, void *pointer, const char *name, HPyCapsule_Destructor destructor) { - return UPCALL_HPY(ctx_Capsule_New, ctx, pointer, name, destructor); -} - -HPyAPI_STORAGE void *_HPy_IMPL_NAME(Capsule_Get)(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, const char *name) { - return UPCALL_HPY(ctx_Capsule_Get, ctx, capsule, (int32_t)key, name); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Capsule_IsValid)(HPyContext *ctx, HPy capsule, const char *name) { - return (int) UPCALL_I32(ctx_Capsule_IsValid, ctx, capsule, name); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Capsule_Set)(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, void *value) { - return (int) UPCALL_I32(ctx_Capsule_Set, ctx, capsule, (int32_t)key, value); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Type_CheckSlot)(HPyContext *ctx, HPy type, HPyDef *expected) { - return (int) UPCALL_I32(ctx_Type_CheckSlot, ctx, type, expected); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Sequence_Check)(HPyContext *ctx, HPy obj) { - return (int) UPCALL_I32(ctx_Sequence_Check, ctx, obj); -} - -HPyAPI_STORAGE int _HPy_IMPL_NAME(Slice_Unpack)(HPyContext *ctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step) { - return (int) UPCALL_I32(ctx_Slice_Unpack, ctx, slice, start, stop, step); -} - -HPyAPI_STORAGE HPy _HPy_IMPL_NAME(SeqIter_New)(HPyContext *ctx, HPy seq) { - return UPCALL_HPY(ctx_SeqIter_New, ctx, seq); -} - -#undef HPy -#undef HPyListBuilder -#undef HPyTupleBuilder -#undef HPyTracker -#undef HPyField -#undef HPyThreadState -#undef HPyGlobal -#undef _HPyCapsule_key - -#undef _HPy_IMPL_NAME_NOPREFIX -#undef _HPy_IMPL_NAME - -#include "hpynative.h" - -/* Allocate a native HPy context structure and fill it. */ -HPyContext *graal_hpy_context_to_native(HPyContext *managed_context) { - GraalHPyContext *full_native_context = (GraalHPyContext *) malloc(sizeof(GraalHPyContext)); - - HPyContext *native_context = graal_native_context_get_hpy_context(full_native_context); - -#define COPY(__member) native_context->__member = managed_context->__member - COPY(name); - COPY(abi_version); - COPY(h_None); - COPY(h_True); - COPY(h_False); - COPY(h_NotImplemented); - COPY(h_Ellipsis); - COPY(h_BaseException); - COPY(h_Exception); - COPY(h_StopAsyncIteration); - COPY(h_StopIteration); - COPY(h_GeneratorExit); - COPY(h_ArithmeticError); - COPY(h_LookupError); - COPY(h_AssertionError); - COPY(h_AttributeError); - COPY(h_BufferError); - COPY(h_EOFError); - COPY(h_FloatingPointError); - COPY(h_OSError); - COPY(h_ImportError); - COPY(h_ModuleNotFoundError); - COPY(h_IndexError); - COPY(h_KeyError); - COPY(h_KeyboardInterrupt); - COPY(h_MemoryError); - COPY(h_NameError); - COPY(h_OverflowError); - COPY(h_RuntimeError); - COPY(h_RecursionError); - COPY(h_NotImplementedError); - COPY(h_SyntaxError); - COPY(h_IndentationError); - COPY(h_TabError); - COPY(h_ReferenceError); - COPY(h_SystemError); - COPY(h_SystemExit); - COPY(h_TypeError); - COPY(h_UnboundLocalError); - COPY(h_UnicodeError); - COPY(h_UnicodeEncodeError); - COPY(h_UnicodeDecodeError); - COPY(h_UnicodeTranslateError); - COPY(h_ValueError); - COPY(h_ZeroDivisionError); - COPY(h_BlockingIOError); - COPY(h_BrokenPipeError); - COPY(h_ChildProcessError); - COPY(h_ConnectionError); - COPY(h_ConnectionAbortedError); - COPY(h_ConnectionRefusedError); - COPY(h_ConnectionResetError); - COPY(h_FileExistsError); - COPY(h_FileNotFoundError); - COPY(h_InterruptedError); - COPY(h_IsADirectoryError); - COPY(h_NotADirectoryError); - COPY(h_PermissionError); - COPY(h_ProcessLookupError); - COPY(h_TimeoutError); - COPY(h_Warning); - COPY(h_UserWarning); - COPY(h_DeprecationWarning); - COPY(h_PendingDeprecationWarning); - COPY(h_SyntaxWarning); - COPY(h_RuntimeWarning); - COPY(h_FutureWarning); - COPY(h_ImportWarning); - COPY(h_UnicodeWarning); - COPY(h_BytesWarning); - COPY(h_ResourceWarning); - COPY(h_BaseObjectType); - COPY(h_TypeType); - COPY(h_BoolType); - COPY(h_LongType); - COPY(h_FloatType); - COPY(h_UnicodeType); - COPY(h_TupleType); - COPY(h_ListType); - COPY(h_ComplexType); - COPY(h_BytesType); - COPY(h_MemoryViewType); - COPY(h_CapsuleType); - COPY(h_SliceType); -#undef COPY - - return native_context; -} - -#undef WRAP -#undef UNWRAP diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/src/hpynative.h b/graalpython/com.oracle.graal.python.hpy.llvm/src/hpynative.h deleted file mode 100644 index decae94d0c..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.llvm/src/hpynative.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef HPY_HPYNATIVE_H_ -#define HPY_HPYNATIVE_H_ - -#include - -#include "hpy.h" - -typedef struct { - void *jni_backend; - void *jni_context; - - /* embed HPy context */ - HPyContext hpy_context; -} GraalHPyContext; - -#if defined(_MSC_VER) && !defined(__clang__) -#define MUST_INLINE static inline -#else -#define MUST_INLINE __attribute__((always_inline)) static inline -#endif - -MUST_INLINE HPyContext *graal_native_context_get_hpy_context(GraalHPyContext *native_context) { - return &(native_context->hpy_context); -} - -MUST_INLINE GraalHPyContext *graal_hpy_context_get_native_context(HPyContext *hpy_context) { - return (GraalHPyContext *)(((char *)hpy_context) - offsetof(GraalHPyContext, hpy_context)); -} - -#endif /* HPY_HPYNATIVE_H_ */ diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/__init__.py b/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/__init__.py deleted file mode 100644 index f8907d5ea7..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/hpy_devel/test_abitag.py b/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/hpy_devel/test_abitag.py deleted file mode 100644 index 1daedcbcfe..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/hpy_devel/test_abitag.py +++ /dev/null @@ -1,48 +0,0 @@ -# MIT License -# -# Copyright (c) 2023, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -from hpy.devel.abitag import parse_ext_suffix, get_hpy_ext_suffix, HPY_ABI_TAG - -def test_parse_ext_suffix_ext(): - _, ext = parse_ext_suffix('.cpython-310-x86_64-linux-gnu.so') - assert ext == 'so' - -def test_parse_ext_suffix_abi_tag(): - def abi_tag(suffix): - tag, ext = parse_ext_suffix(suffix) - return tag - - assert abi_tag('.cpython-38-x86_64-linux-gnu.so') == 'cp38' - assert abi_tag('.cpython-38d-x86_64-linux-gnu.so') == 'cp38d' - assert abi_tag('.cpython-310-x86_64-linux-gnu.so') == 'cp310' - assert abi_tag('.cpython-310d-x86_64-linux-gnu.so') == 'cp310d' - assert abi_tag('.cpython-310-darwin.so') == 'cp310' - assert abi_tag('.cp310-win_amd64.pyd') == 'cp310' - assert abi_tag('.pypy38-pp73-x86_64-linux-gnu.so') == 'pypy38-pp73' - assert abi_tag('.graalpy-38-native-x86_64-darwin.dylib') == 'graalpy-38-native' - -def test_get_hpy_ext_suffix(): - get = get_hpy_ext_suffix - hpy0 = HPY_ABI_TAG - assert get('universal', '.cpython-38-x86_64-linux-gnu.so') == f'.{hpy0}.so' - assert get('hybrid', '.cpython-38-x86_64-linux-gnu.so') == f'.{hpy0}-cp38.so' diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyglobal.py b/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyglobal.py deleted file mode 100644 index b5d43ee628..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyglobal.py +++ /dev/null @@ -1,123 +0,0 @@ -# Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# The Universal Permissive License (UPL), Version 1.0 -# -# Subject to the condition set forth below, permission is hereby granted to any -# person obtaining a copy of this software, associated documentation and/or -# data (collectively the "Software"), free of charge and under any and all -# copyright rights in the Software, and any and all patent rights owned or -# freely licensable by each licensor hereunder covering either (i) the -# unmodified Software as contributed to or provided by such licensor, or (ii) -# the Larger Works (as defined below), to deal in both -# -# (a) the Software, and -# -# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -# one is included with the Software each a "Larger Work" to which the Software -# is contributed by such licensors), -# -# without restriction, including without limitation the rights to copy, create -# derivative works of, display, perform, and distribute the Software and make, -# use, sell, offer for sale, import, export, have made, and have sold the -# Software and the Larger Work(s), and to sublicense the foregoing rights on -# either these or other terms. -# -# This license is subject to the following condition: -# -# The above copyright notice and either this complete permission notice or at a -# minimum a reference to the UPL must be included in all copies or substantial -# portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -""" -NOTE: this tests are also meant to be run as PyPy "applevel" tests. - -This means that global imports will NOT be visible inside the test -functions. In particular, you have to "import pytest" inside the test in order -to be able to use e.g. pytest.raises (which on PyPy will be implemented by a -"fake pytest module") -""" -from .support import HPyTest - - -class TestHPyGlobal(HPyTest): - - def test_basics(self): - mod = self.make_module(""" - HPyGlobal myglobal; - - HPyDef_METH(setg, "setg", HPyFunc_O) - static HPy setg_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPyGlobal_Store(ctx, &myglobal, arg); - return HPy_Dup(ctx, ctx->h_None); - } - - HPyDef_METH(getg, "getg", HPyFunc_NOARGS) - static HPy getg_impl(HPyContext *ctx, HPy self) - { - return HPyGlobal_Load(ctx, myglobal); - } - - @EXPORT(setg) - @EXPORT(getg) - @EXPORT_GLOBAL(myglobal) - @INIT - """) - obj = {'hello': 'world'} - assert mod.setg(obj) is None - assert mod.getg() is obj - - def test_twoglobals(self): - mod = self.make_module(""" - HPyGlobal myglobal1; - HPyGlobal myglobal2; - - HPyDef_METH(setg1, "setg1", HPyFunc_O) - static HPy setg1_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPyGlobal_Store(ctx, &myglobal1, arg); - return HPy_Dup(ctx, ctx->h_None); - } - - HPyDef_METH(setg2, "setg2", HPyFunc_O) - static HPy setg2_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPyGlobal_Store(ctx, &myglobal2, arg); - return HPy_Dup(ctx, ctx->h_None); - } - - HPyDef_METH(getg1, "getg1", HPyFunc_NOARGS) - static HPy getg1_impl(HPyContext *ctx, HPy self) - { - return HPyGlobal_Load(ctx, myglobal1); - } - - HPyDef_METH(getg2, "getg2", HPyFunc_NOARGS) - static HPy getg2_impl(HPyContext *ctx, HPy self) - { - return HPyGlobal_Load(ctx, myglobal2); - } - - @EXPORT(setg1) - @EXPORT(setg2) - @EXPORT(getg1) - @EXPORT(getg2) - @EXPORT_GLOBAL(myglobal1) - @EXPORT_GLOBAL(myglobal2) - @INIT - """) - obj1 = {'hello': 'world'} - obj2 = {'foo': 'bar'} - assert mod.setg1(obj1) is None - assert mod.setg2(obj2) is None - assert mod.getg1() is obj1 - assert mod.getg2() is obj2 diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyimport.py b/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyimport.py deleted file mode 100644 index bf9b2edb55..0000000000 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyimport.py +++ /dev/null @@ -1,47 +0,0 @@ -# MIT License -# -# Copyright (c) 2021, 2024, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -from .support import HPyTest - -class TestImport(HPyTest): - - def test_ImportModule(self): - import pytest - import sys - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy h_name) - { - // we use bytes because ATM we don't have HPyUnicode_AsUTF8 or similar - const char *name = HPyBytes_AsString(ctx, h_name); - if (name == NULL) - return HPy_NULL; - return HPyImport_ImportModule(ctx, name); - } - @EXPORT(f) - @INIT - """) - sys2 = mod.f(b'sys') - assert sys is sys2 - with pytest.raises(ImportError): - mod.f(b'This is the name of a module which does not exist, hopefully') diff --git a/graalpython/com.oracle.graal.python.jni/src/autogen_ctx_call_jni.c b/graalpython/com.oracle.graal.python.jni/src/autogen_ctx_call_jni.c deleted file mode 100644 index a718db4a96..0000000000 --- a/graalpython/com.oracle.graal.python.jni/src/autogen_ctx_call_jni.c +++ /dev/null @@ -1,647 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.graalpy.autogen_ctx_call_jni - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -#include "hpy_jni.h" -#include "com_oracle_graal_python_builtins_objects_cext_hpy_jni_GraalHPyJNITrampolines.h" - -#define TRAMPOLINE(name) Java_com_oracle_graal_python_builtins_objects_cext_hpy_jni_GraalHPyJNITrampolines_ ## name - -/******************************************************************* - * UNIVERSAL MODE TRAMPOLINES * - ******************************************************************/ - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeModuleInit)(JNIEnv *env, jclass clazz, jlong target) -{ - return (jlong) (((HPyModuleDef *(*)(void)) target)()); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeNoargs)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong self) -{ - HPyFunc_noargs f = (HPyFunc_noargs)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(self))); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeO)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong self, jlong arg) -{ - HPyFunc_o f = (HPyFunc_o)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(self), _jlong2h(arg))); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeVarargs)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong self, jlong args, jlong nargs) -{ - HPyFunc_varargs f = (HPyFunc_varargs)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(self), (const HPy *) args, (size_t) nargs)); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeKeywords)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong self, jlong args, jlong nargs, jlong kwnames) -{ - HPyFunc_keywords f = (HPyFunc_keywords)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(self), (const HPy *) args, (size_t) nargs, _jlong2h(kwnames))); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeUnaryfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyFunc_unaryfunc f = (HPyFunc_unaryfunc)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(arg0))); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeBinaryfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1) -{ - HPyFunc_binaryfunc f = (HPyFunc_binaryfunc)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(arg0), _jlong2h(arg1))); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeTernaryfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyFunc_ternaryfunc f = (HPyFunc_ternaryfunc)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(arg0), _jlong2h(arg1), _jlong2h(arg2))); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeInquiry)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyFunc_inquiry f = (HPyFunc_inquiry)target; - return (jint) f((HPyContext *)ctx, _jlong2h(arg0)); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeLenfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyFunc_lenfunc f = (HPyFunc_lenfunc)target; - return (jlong) f((HPyContext *)ctx, _jlong2h(arg0)); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeSsizeargfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1) -{ - HPyFunc_ssizeargfunc f = (HPyFunc_ssizeargfunc)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(arg0), (HPy_ssize_t) arg1)); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeSsizessizeargfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyFunc_ssizessizeargfunc f = (HPyFunc_ssizessizeargfunc)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(arg0), (HPy_ssize_t) arg1, (HPy_ssize_t) arg2)); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeSsizeobjargproc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyFunc_ssizeobjargproc f = (HPyFunc_ssizeobjargproc)target; - return (jint) f((HPyContext *)ctx, _jlong2h(arg0), (HPy_ssize_t) arg1, _jlong2h(arg2)); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeSsizessizeobjargproc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2, jlong arg3) -{ - HPyFunc_ssizessizeobjargproc f = (HPyFunc_ssizessizeobjargproc)target; - return (jint) f((HPyContext *)ctx, _jlong2h(arg0), (HPy_ssize_t) arg1, (HPy_ssize_t) arg2, _jlong2h(arg3)); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeObjobjargproc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyFunc_objobjargproc f = (HPyFunc_objobjargproc)target; - return (jint) f((HPyContext *)ctx, _jlong2h(arg0), _jlong2h(arg1), _jlong2h(arg2)); -} - -JNIEXPORT void JNICALL TRAMPOLINE(executeFreefunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyFunc_freefunc f = (HPyFunc_freefunc)target; - f((HPyContext *)ctx, (void *) arg0); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeGetattrfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1) -{ - HPyFunc_getattrfunc f = (HPyFunc_getattrfunc)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(arg0), (char *) arg1)); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeGetattrofunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1) -{ - HPyFunc_getattrofunc f = (HPyFunc_getattrofunc)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(arg0), _jlong2h(arg1))); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeSetattrfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyFunc_setattrfunc f = (HPyFunc_setattrfunc)target; - return (jint) f((HPyContext *)ctx, _jlong2h(arg0), (char *) arg1, _jlong2h(arg2)); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeSetattrofunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyFunc_setattrofunc f = (HPyFunc_setattrofunc)target; - return (jint) f((HPyContext *)ctx, _jlong2h(arg0), _jlong2h(arg1), _jlong2h(arg2)); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeReprfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyFunc_reprfunc f = (HPyFunc_reprfunc)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(arg0))); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeHashfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyFunc_hashfunc f = (HPyFunc_hashfunc)target; - return (jlong) f((HPyContext *)ctx, _jlong2h(arg0)); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeRichcmpfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyFunc_richcmpfunc f = (HPyFunc_richcmpfunc)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(arg0), _jlong2h(arg1), (HPy_RichCmpOp) arg2)); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeGetiterfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyFunc_getiterfunc f = (HPyFunc_getiterfunc)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(arg0))); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeIternextfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyFunc_iternextfunc f = (HPyFunc_iternextfunc)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(arg0))); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDescrgetfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyFunc_descrgetfunc f = (HPyFunc_descrgetfunc)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(arg0), _jlong2h(arg1), _jlong2h(arg2))); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeDescrsetfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyFunc_descrsetfunc f = (HPyFunc_descrsetfunc)target; - return (jint) f((HPyContext *)ctx, _jlong2h(arg0), _jlong2h(arg1), _jlong2h(arg2)); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeInitproc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong self, jlong args, jlong nargs, jlong kw) -{ - HPyFunc_initproc f = (HPyFunc_initproc)target; - return (jint) f((HPyContext *)ctx, _jlong2h(self), (const HPy *) args, (HPy_ssize_t) nargs, _jlong2h(kw)); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeNewfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong type, jlong args, jlong nargs, jlong kw) -{ - HPyFunc_newfunc f = (HPyFunc_newfunc)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(type), (const HPy *) args, (HPy_ssize_t) nargs, _jlong2h(kw))); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeGetter)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1) -{ - HPyFunc_getter f = (HPyFunc_getter)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(arg0), (void *) arg1)); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeSetter)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyFunc_setter f = (HPyFunc_setter)target; - return (jint) f((HPyContext *)ctx, _jlong2h(arg0), _jlong2h(arg1), (void *) arg2); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeObjobjproc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1) -{ - HPyFunc_objobjproc f = (HPyFunc_objobjproc)target; - return (jint) f((HPyContext *)ctx, _jlong2h(arg0), _jlong2h(arg1)); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeGetbufferproc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jint arg2) -{ - HPyFunc_getbufferproc f = (HPyFunc_getbufferproc)target; - return (jint) f((HPyContext *)ctx, _jlong2h(arg0), (HPy_buffer *) arg1, (int) arg2); -} - -JNIEXPORT void JNICALL TRAMPOLINE(executeReleasebufferproc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1) -{ - HPyFunc_releasebufferproc f = (HPyFunc_releasebufferproc)target; - f((HPyContext *)ctx, _jlong2h(arg0), (HPy_buffer *) arg1); -} - -JNIEXPORT void JNICALL TRAMPOLINE(executeDestructor)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyFunc_destructor f = (HPyFunc_destructor)target; - f((HPyContext *)ctx, _jlong2h(arg0)); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeModcreate)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyFunc_mod_create f = (HPyFunc_mod_create)target; - return _h2jlong(f((HPyContext *)ctx, _jlong2h(arg0))); -} - - -/******************************************************************* - * DEBUG MODE TRAMPOLINES * - ******************************************************************/ - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugNoargs)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong self) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_noargs f = (HPyFunc_noargs)target; - DHPy dh_self = _jlong2dh(dctx, self); - DHPy dh_result = f(dctx, dh_self); - DHPy_close_and_check(dctx, dh_self); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugO)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong self, jlong arg) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_o f = (HPyFunc_o)target; - DHPy dh_self = _jlong2dh(dctx, self); - DHPy dh_arg = _jlong2dh(dctx, arg); - DHPy dh_result = f(dctx, dh_self, dh_arg); - DHPy_close_and_check(dctx, dh_self); - DHPy_close_and_check(dctx, dh_arg); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugVarargs)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong self, jlong args, jlong nargs) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_varargs f = (HPyFunc_varargs)target; - DHPy dh_self = _jlong2dh(dctx, self); - _ARR_JLONG2DH(dctx, dh_args, args, nargs) - DHPy dh_result = f(dctx, dh_self, dh_args, (size_t)nargs); - _ARR_DH_CLOSE(dctx, dh_args, nargs) - DHPy_close_and_check(dctx, dh_self); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugUnaryfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_unaryfunc f = (HPyFunc_unaryfunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_result = f(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg0); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugBinaryfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_binaryfunc f = (HPyFunc_binaryfunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_arg1 = _jlong2dh(dctx, arg1); - DHPy dh_result = f(dctx, dh_arg0, dh_arg1); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg1); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugTernaryfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_ternaryfunc f = (HPyFunc_ternaryfunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_arg1 = _jlong2dh(dctx, arg1); - DHPy dh_arg2 = _jlong2dh(dctx, arg2); - DHPy dh_result = f(dctx, dh_arg0, dh_arg1, dh_arg2); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg1); - DHPy_close_and_check(dctx, dh_arg2); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeDebugInquiry)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_inquiry f = (HPyFunc_inquiry)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - jint result = (jint) f(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg0); - return result; -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugLenfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_lenfunc f = (HPyFunc_lenfunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - jlong result = (jlong) f(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg0); - return result; -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugSsizeargfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_ssizeargfunc f = (HPyFunc_ssizeargfunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_result = f(dctx, dh_arg0, (HPy_ssize_t)arg1); - DHPy_close_and_check(dctx, dh_arg0); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugSsizessizeargfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_ssizessizeargfunc f = (HPyFunc_ssizessizeargfunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_result = f(dctx, dh_arg0, (HPy_ssize_t)arg1, (HPy_ssize_t)arg2); - DHPy_close_and_check(dctx, dh_arg0); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeDebugSsizeobjargproc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_ssizeobjargproc f = (HPyFunc_ssizeobjargproc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_arg2 = _jlong2dh(dctx, arg2); - jint result = (jint) f(dctx, dh_arg0, (HPy_ssize_t)arg1, dh_arg2); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg2); - return result; -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeDebugSsizessizeobjargproc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2, jlong arg3) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_ssizessizeobjargproc f = (HPyFunc_ssizessizeobjargproc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_arg3 = _jlong2dh(dctx, arg3); - jint result = (jint) f(dctx, dh_arg0, (HPy_ssize_t)arg1, (HPy_ssize_t)arg2, dh_arg3); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg3); - return result; -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeDebugObjobjargproc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_objobjargproc f = (HPyFunc_objobjargproc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_arg1 = _jlong2dh(dctx, arg1); - DHPy dh_arg2 = _jlong2dh(dctx, arg2); - jint result = (jint) f(dctx, dh_arg0, dh_arg1, dh_arg2); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg1); - DHPy_close_and_check(dctx, dh_arg2); - return result; -} - -JNIEXPORT void JNICALL TRAMPOLINE(executeDebugFreefunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_freefunc f = (HPyFunc_freefunc)target; - f(dctx, (void *)arg0); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugGetattrfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_getattrfunc f = (HPyFunc_getattrfunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_result = f(dctx, dh_arg0, (char *)arg1); - DHPy_close_and_check(dctx, dh_arg0); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugGetattrofunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_getattrofunc f = (HPyFunc_getattrofunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_arg1 = _jlong2dh(dctx, arg1); - DHPy dh_result = f(dctx, dh_arg0, dh_arg1); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg1); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeDebugSetattrfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_setattrfunc f = (HPyFunc_setattrfunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_arg2 = _jlong2dh(dctx, arg2); - jint result = (jint) f(dctx, dh_arg0, (char *)arg1, dh_arg2); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg2); - return result; -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeDebugSetattrofunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_setattrofunc f = (HPyFunc_setattrofunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_arg1 = _jlong2dh(dctx, arg1); - DHPy dh_arg2 = _jlong2dh(dctx, arg2); - jint result = (jint) f(dctx, dh_arg0, dh_arg1, dh_arg2); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg1); - DHPy_close_and_check(dctx, dh_arg2); - return result; -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugReprfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_reprfunc f = (HPyFunc_reprfunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_result = f(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg0); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugHashfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_hashfunc f = (HPyFunc_hashfunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - jlong result = (jlong) f(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg0); - return result; -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugRichcmpfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_richcmpfunc f = (HPyFunc_richcmpfunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_arg1 = _jlong2dh(dctx, arg1); - DHPy dh_result = f(dctx, dh_arg0, dh_arg1, (HPy_RichCmpOp)arg2); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg1); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugGetiterfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_getiterfunc f = (HPyFunc_getiterfunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_result = f(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg0); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugIternextfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_iternextfunc f = (HPyFunc_iternextfunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_result = f(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg0); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugDescrgetfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_descrgetfunc f = (HPyFunc_descrgetfunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_arg1 = _jlong2dh(dctx, arg1); - DHPy dh_arg2 = _jlong2dh(dctx, arg2); - DHPy dh_result = f(dctx, dh_arg0, dh_arg1, dh_arg2); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg1); - DHPy_close_and_check(dctx, dh_arg2); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeDebugDescrsetfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_descrsetfunc f = (HPyFunc_descrsetfunc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_arg1 = _jlong2dh(dctx, arg1); - DHPy dh_arg2 = _jlong2dh(dctx, arg2); - jint result = (jint) f(dctx, dh_arg0, dh_arg1, dh_arg2); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg1); - DHPy_close_and_check(dctx, dh_arg2); - return result; -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeDebugInitproc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong self, jlong args, jlong nargs, jlong kw) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_initproc f = (HPyFunc_initproc)target; - DHPy dh_self = _jlong2dh(dctx, self); - DHPy dh_kw = _jlong2dh(dctx, kw); - _ARR_JLONG2DH(dctx, dh_args, args, nargs) - jint result = (jint) f(dctx, dh_self, dh_args, (HPy_ssize_t)nargs, dh_kw); - _ARR_DH_CLOSE(dctx, dh_args, nargs) - DHPy_close_and_check(dctx, dh_self); - DHPy_close_and_check(dctx, dh_kw); - return result; -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugNewfunc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong type, jlong args, jlong nargs, jlong kw) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_newfunc f = (HPyFunc_newfunc)target; - DHPy dh_type = _jlong2dh(dctx, type); - DHPy dh_kw = _jlong2dh(dctx, kw); - _ARR_JLONG2DH(dctx, dh_args, args, nargs) - DHPy dh_result = f(dctx, dh_type, dh_args, (HPy_ssize_t)nargs, dh_kw); - _ARR_DH_CLOSE(dctx, dh_args, nargs) - DHPy_close_and_check(dctx, dh_type); - DHPy_close_and_check(dctx, dh_kw); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugGetter)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_getter f = (HPyFunc_getter)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_result = f(dctx, dh_arg0, (void *)arg1); - DHPy_close_and_check(dctx, dh_arg0); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeDebugSetter)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1, jlong arg2) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_setter f = (HPyFunc_setter)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_arg1 = _jlong2dh(dctx, arg1); - jint result = (jint) f(dctx, dh_arg0, dh_arg1, (void *)arg2); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg1); - return result; -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeDebugObjobjproc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0, jlong arg1) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_objobjproc f = (HPyFunc_objobjproc)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_arg1 = _jlong2dh(dctx, arg1); - jint result = (jint) f(dctx, dh_arg0, dh_arg1); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg1); - return result; -} - -JNIEXPORT void JNICALL TRAMPOLINE(executeDebugDestructor)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_destructor f = (HPyFunc_destructor)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - f(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg0); -} - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugModcreate)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg0) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_mod_create f = (HPyFunc_mod_create)target; - DHPy dh_arg0 = _jlong2dh(dctx, arg0); - DHPy dh_result = f(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg0); - return from_dh(dctx, dh_result); -} - -#undef TRAMPOLINE diff --git a/graalpython/com.oracle.graal.python.jni/src/autogen_ctx_init_jni.h b/graalpython/com.oracle.graal.python.jni/src/autogen_ctx_init_jni.h deleted file mode 100644 index 80305c6288..0000000000 --- a/graalpython/com.oracle.graal.python.jni/src/autogen_ctx_init_jni.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.graalpy.autogen_ctx_init_jni_h - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -_HPy_HIDDEN int init_autogen_jni_ctx(JNIEnv *env, jclass clazz, HPyContext *ctx, jlongArray jctx_handles); -_HPy_HIDDEN extern jmethodID jniMethod_ctx_Unicode_FromWideChar; -_HPy_HIDDEN HPy ctx_Unicode_FromWideChar_jni(HPyContext *ctx, const wchar_t *w, HPy_ssize_t size); -_HPy_HIDDEN extern jmethodID jniMethod_ctx_ListBuilder_New; -_HPy_HIDDEN HPyListBuilder ctx_ListBuilder_New_jni(HPyContext *ctx, HPy_ssize_t size); -_HPy_HIDDEN extern jmethodID jniMethod_ctx_ListBuilder_Set; -_HPy_HIDDEN void ctx_ListBuilder_Set_jni(HPyContext *ctx, HPyListBuilder builder, HPy_ssize_t index, HPy h_item); -_HPy_HIDDEN extern jmethodID jniMethod_ctx_ListBuilder_Build; -_HPy_HIDDEN HPy ctx_ListBuilder_Build_jni(HPyContext *ctx, HPyListBuilder builder); -_HPy_HIDDEN extern jmethodID jniMethod_ctx_ListBuilder_Cancel; -_HPy_HIDDEN void ctx_ListBuilder_Cancel_jni(HPyContext *ctx, HPyListBuilder builder); -_HPy_HIDDEN extern jmethodID jniMethod_ctx_TupleBuilder_New; -_HPy_HIDDEN HPyTupleBuilder ctx_TupleBuilder_New_jni(HPyContext *ctx, HPy_ssize_t size); -_HPy_HIDDEN extern jmethodID jniMethod_ctx_TupleBuilder_Set; -_HPy_HIDDEN void ctx_TupleBuilder_Set_jni(HPyContext *ctx, HPyTupleBuilder builder, HPy_ssize_t index, HPy h_item); -_HPy_HIDDEN extern jmethodID jniMethod_ctx_TupleBuilder_Build; -_HPy_HIDDEN HPy ctx_TupleBuilder_Build_jni(HPyContext *ctx, HPyTupleBuilder builder); -_HPy_HIDDEN extern jmethodID jniMethod_ctx_TupleBuilder_Cancel; -_HPy_HIDDEN void ctx_TupleBuilder_Cancel_jni(HPyContext *ctx, HPyTupleBuilder builder); -_HPy_HIDDEN extern jmethodID jniMethod_ctx_Global_Load; -_HPy_HIDDEN HPy ctx_Global_Load_jni(HPyContext *ctx, HPyGlobal global); - diff --git a/graalpython/com.oracle.graal.python.jni/src/autogen_wrappers_jni.c b/graalpython/com.oracle.graal.python.jni/src/autogen_wrappers_jni.c deleted file mode 100644 index 949f71b8c6..0000000000 --- a/graalpython/com.oracle.graal.python.jni/src/autogen_wrappers_jni.c +++ /dev/null @@ -1,2282 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.graalpy.autogen_wrappers_jni - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -#include "hpy_jni.h" -#include "hpynative.h" -#include "hpy_log.h" -#include "com_oracle_graal_python_builtins_objects_cext_hpy_jni_GraalHPyJNIContext.h" -#include "autogen_ctx_init_jni.h" - -#define TRAMPOLINE(FUN_NAME) Java_com_oracle_graal_python_builtins_objects_cext_hpy_jni_GraalHPyJNIContext_ ## FUN_NAME - -static jmethodID jniMethod_ctx_Dup; -static HPy ctx_Dup_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Close; -static void ctx_Close_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Long_FromInt32_t; -static HPy ctx_Long_FromInt32_t_jni(HPyContext *ctx, int32_t value); -static jmethodID jniMethod_ctx_Long_FromUInt32_t; -static HPy ctx_Long_FromUInt32_t_jni(HPyContext *ctx, uint32_t value); -static jmethodID jniMethod_ctx_Long_FromInt64_t; -static HPy ctx_Long_FromInt64_t_jni(HPyContext *ctx, int64_t v); -static jmethodID jniMethod_ctx_Long_FromUInt64_t; -static HPy ctx_Long_FromUInt64_t_jni(HPyContext *ctx, uint64_t v); -static jmethodID jniMethod_ctx_Long_FromSize_t; -static HPy ctx_Long_FromSize_t_jni(HPyContext *ctx, size_t value); -static jmethodID jniMethod_ctx_Long_FromSsize_t; -static HPy ctx_Long_FromSsize_t_jni(HPyContext *ctx, HPy_ssize_t value); -static jmethodID jniMethod_ctx_Long_AsInt32_t; -static int32_t ctx_Long_AsInt32_t_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Long_AsUInt32_t; -static uint32_t ctx_Long_AsUInt32_t_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Long_AsUInt32_tMask; -static uint32_t ctx_Long_AsUInt32_tMask_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Long_AsInt64_t; -static int64_t ctx_Long_AsInt64_t_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Long_AsUInt64_t; -static uint64_t ctx_Long_AsUInt64_t_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Long_AsUInt64_tMask; -static uint64_t ctx_Long_AsUInt64_tMask_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Long_AsSize_t; -static size_t ctx_Long_AsSize_t_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Long_AsSsize_t; -static HPy_ssize_t ctx_Long_AsSsize_t_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Long_AsVoidPtr; -static void *ctx_Long_AsVoidPtr_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Long_AsDouble; -static double ctx_Long_AsDouble_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Float_FromDouble; -static HPy ctx_Float_FromDouble_jni(HPyContext *ctx, double v); -static jmethodID jniMethod_ctx_Float_AsDouble; -static double ctx_Float_AsDouble_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Bool_FromBool; -static HPy ctx_Bool_FromBool_jni(HPyContext *ctx, bool v); -static jmethodID jniMethod_ctx_Length; -static HPy_ssize_t ctx_Length_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Number_Check; -static int ctx_Number_Check_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Add; -static HPy ctx_Add_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_Subtract; -static HPy ctx_Subtract_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_Multiply; -static HPy ctx_Multiply_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_MatrixMultiply; -static HPy ctx_MatrixMultiply_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_FloorDivide; -static HPy ctx_FloorDivide_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_TrueDivide; -static HPy ctx_TrueDivide_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_Remainder; -static HPy ctx_Remainder_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_Divmod; -static HPy ctx_Divmod_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_Power; -static HPy ctx_Power_jni(HPyContext *ctx, HPy h1, HPy h2, HPy h3); -static jmethodID jniMethod_ctx_Negative; -static HPy ctx_Negative_jni(HPyContext *ctx, HPy h1); -static jmethodID jniMethod_ctx_Positive; -static HPy ctx_Positive_jni(HPyContext *ctx, HPy h1); -static jmethodID jniMethod_ctx_Absolute; -static HPy ctx_Absolute_jni(HPyContext *ctx, HPy h1); -static jmethodID jniMethod_ctx_Invert; -static HPy ctx_Invert_jni(HPyContext *ctx, HPy h1); -static jmethodID jniMethod_ctx_Lshift; -static HPy ctx_Lshift_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_Rshift; -static HPy ctx_Rshift_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_And; -static HPy ctx_And_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_Xor; -static HPy ctx_Xor_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_Or; -static HPy ctx_Or_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_Index; -static HPy ctx_Index_jni(HPyContext *ctx, HPy h1); -static jmethodID jniMethod_ctx_Long; -static HPy ctx_Long_jni(HPyContext *ctx, HPy h1); -static jmethodID jniMethod_ctx_Float; -static HPy ctx_Float_jni(HPyContext *ctx, HPy h1); -static jmethodID jniMethod_ctx_InPlaceAdd; -static HPy ctx_InPlaceAdd_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_InPlaceSubtract; -static HPy ctx_InPlaceSubtract_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_InPlaceMultiply; -static HPy ctx_InPlaceMultiply_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_InPlaceMatrixMultiply; -static HPy ctx_InPlaceMatrixMultiply_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_InPlaceFloorDivide; -static HPy ctx_InPlaceFloorDivide_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_InPlaceTrueDivide; -static HPy ctx_InPlaceTrueDivide_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_InPlaceRemainder; -static HPy ctx_InPlaceRemainder_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_InPlacePower; -static HPy ctx_InPlacePower_jni(HPyContext *ctx, HPy h1, HPy h2, HPy h3); -static jmethodID jniMethod_ctx_InPlaceLshift; -static HPy ctx_InPlaceLshift_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_InPlaceRshift; -static HPy ctx_InPlaceRshift_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_InPlaceAnd; -static HPy ctx_InPlaceAnd_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_InPlaceXor; -static HPy ctx_InPlaceXor_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_InPlaceOr; -static HPy ctx_InPlaceOr_jni(HPyContext *ctx, HPy h1, HPy h2); -static jmethodID jniMethod_ctx_Callable_Check; -static int ctx_Callable_Check_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_CallTupleDict; -static HPy ctx_CallTupleDict_jni(HPyContext *ctx, HPy callable, HPy args, HPy kw); -static jmethodID jniMethod_ctx_Call; -static HPy ctx_Call_jni(HPyContext *ctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames); -static jmethodID jniMethod_ctx_CallMethod; -static HPy ctx_CallMethod_jni(HPyContext *ctx, HPy name, const HPy *args, size_t nargs, HPy kwnames); -static jmethodID jniMethod_ctx_FatalError; -static void ctx_FatalError_jni(HPyContext *ctx, const char *message); -static jmethodID jniMethod_ctx_Err_SetString; -static void ctx_Err_SetString_jni(HPyContext *ctx, HPy h_type, const char *utf8_message); -static jmethodID jniMethod_ctx_Err_SetObject; -static void ctx_Err_SetObject_jni(HPyContext *ctx, HPy h_type, HPy h_value); -static jmethodID jniMethod_ctx_Err_SetFromErrnoWithFilename; -static HPy ctx_Err_SetFromErrnoWithFilename_jni(HPyContext *ctx, HPy h_type, const char *filename_fsencoded); -static jmethodID jniMethod_ctx_Err_SetFromErrnoWithFilenameObjects; -static void ctx_Err_SetFromErrnoWithFilenameObjects_jni(HPyContext *ctx, HPy h_type, HPy filename1, HPy filename2); -static jmethodID jniMethod_ctx_Err_Occurred; -static int ctx_Err_Occurred_jni(HPyContext *ctx); -static jmethodID jniMethod_ctx_Err_ExceptionMatches; -static int ctx_Err_ExceptionMatches_jni(HPyContext *ctx, HPy exc); -static jmethodID jniMethod_ctx_Err_NoMemory; -static void ctx_Err_NoMemory_jni(HPyContext *ctx); -static jmethodID jniMethod_ctx_Err_Clear; -static void ctx_Err_Clear_jni(HPyContext *ctx); -static jmethodID jniMethod_ctx_Err_NewException; -static HPy ctx_Err_NewException_jni(HPyContext *ctx, const char *utf8_name, HPy base, HPy dict); -static jmethodID jniMethod_ctx_Err_NewExceptionWithDoc; -static HPy ctx_Err_NewExceptionWithDoc_jni(HPyContext *ctx, const char *utf8_name, const char *utf8_doc, HPy base, HPy dict); -static jmethodID jniMethod_ctx_Err_WarnEx; -static int ctx_Err_WarnEx_jni(HPyContext *ctx, HPy category, const char *utf8_message, HPy_ssize_t stack_level); -static jmethodID jniMethod_ctx_Err_WriteUnraisable; -static void ctx_Err_WriteUnraisable_jni(HPyContext *ctx, HPy obj); -static jmethodID jniMethod_ctx_IsTrue; -static int ctx_IsTrue_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Type_FromSpec; -static HPy ctx_Type_FromSpec_jni(HPyContext *ctx, HPyType_Spec *spec, HPyType_SpecParam *params); -static jmethodID jniMethod_ctx_Type_GenericNew; -static HPy ctx_Type_GenericNew_jni(HPyContext *ctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw); -static jmethodID jniMethod_ctx_GetAttr; -static HPy ctx_GetAttr_jni(HPyContext *ctx, HPy obj, HPy name); -static jmethodID jniMethod_ctx_HasAttr; -static int ctx_HasAttr_jni(HPyContext *ctx, HPy obj, HPy name); -static jmethodID jniMethod_ctx_HasAttr_s; -static int ctx_HasAttr_s_jni(HPyContext *ctx, HPy obj, const char *utf8_name); -static jmethodID jniMethod_ctx_SetAttr; -static int ctx_SetAttr_jni(HPyContext *ctx, HPy obj, HPy name, HPy value); -static jmethodID jniMethod_ctx_SetAttr_s; -static int ctx_SetAttr_s_jni(HPyContext *ctx, HPy obj, const char *utf8_name, HPy value); -static jmethodID jniMethod_ctx_GetItem; -static HPy ctx_GetItem_jni(HPyContext *ctx, HPy obj, HPy key); -static jmethodID jniMethod_ctx_GetItem_i; -static HPy ctx_GetItem_i_jni(HPyContext *ctx, HPy obj, HPy_ssize_t idx); -static jmethodID jniMethod_ctx_Contains; -static int ctx_Contains_jni(HPyContext *ctx, HPy container, HPy key); -static jmethodID jniMethod_ctx_SetItem; -static int ctx_SetItem_jni(HPyContext *ctx, HPy obj, HPy key, HPy value); -static jmethodID jniMethod_ctx_SetItem_i; -static int ctx_SetItem_i_jni(HPyContext *ctx, HPy obj, HPy_ssize_t idx, HPy value); -static jmethodID jniMethod_ctx_DelItem; -static int ctx_DelItem_jni(HPyContext *ctx, HPy obj, HPy key); -static jmethodID jniMethod_ctx_DelItem_i; -static int ctx_DelItem_i_jni(HPyContext *ctx, HPy obj, HPy_ssize_t idx); -static jmethodID jniMethod_ctx_DelItem_s; -static int ctx_DelItem_s_jni(HPyContext *ctx, HPy obj, const char *utf8_key); -static jmethodID jniMethod_ctx_Type; -static HPy ctx_Type_jni(HPyContext *ctx, HPy obj); -static jmethodID jniMethod_ctx_TypeCheck; -static int ctx_TypeCheck_jni(HPyContext *ctx, HPy obj, HPy type); -static jmethodID jniMethod_ctx_Type_GetName; -static const char *ctx_Type_GetName_jni(HPyContext *ctx, HPy type); -static jmethodID jniMethod_ctx_Type_IsSubtype; -static int ctx_Type_IsSubtype_jni(HPyContext *ctx, HPy sub, HPy type); -static jmethodID jniMethod_ctx_Is; -static int ctx_Is_jni(HPyContext *ctx, HPy obj, HPy other); -static jmethodID jniMethod_ctx_AsStruct_Object; -static void *ctx_AsStruct_Object_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_AsStruct_Legacy; -static void *ctx_AsStruct_Legacy_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_AsStruct_Type; -static void *ctx_AsStruct_Type_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_AsStruct_Long; -static void *ctx_AsStruct_Long_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_AsStruct_Float; -static void *ctx_AsStruct_Float_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_AsStruct_Unicode; -static void *ctx_AsStruct_Unicode_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_AsStruct_Tuple; -static void *ctx_AsStruct_Tuple_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_AsStruct_List; -static void *ctx_AsStruct_List_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Type_GetBuiltinShape; -static HPyType_BuiltinShape ctx_Type_GetBuiltinShape_jni(HPyContext *ctx, HPy h_type); -static jmethodID jniMethod_ctx_New; -static HPy ctx_New_jni(HPyContext *ctx, HPy h_type, void **data); -static jmethodID jniMethod_ctx_Repr; -static HPy ctx_Repr_jni(HPyContext *ctx, HPy obj); -static jmethodID jniMethod_ctx_Str; -static HPy ctx_Str_jni(HPyContext *ctx, HPy obj); -static jmethodID jniMethod_ctx_ASCII; -static HPy ctx_ASCII_jni(HPyContext *ctx, HPy obj); -static jmethodID jniMethod_ctx_Bytes; -static HPy ctx_Bytes_jni(HPyContext *ctx, HPy obj); -static jmethodID jniMethod_ctx_RichCompare; -static HPy ctx_RichCompare_jni(HPyContext *ctx, HPy v, HPy w, int op); -static jmethodID jniMethod_ctx_RichCompareBool; -static int ctx_RichCompareBool_jni(HPyContext *ctx, HPy v, HPy w, int op); -static jmethodID jniMethod_ctx_Hash; -static HPy_hash_t ctx_Hash_jni(HPyContext *ctx, HPy obj); -static jmethodID jniMethod_ctx_Bytes_Check; -static int ctx_Bytes_Check_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Bytes_Size; -static HPy_ssize_t ctx_Bytes_Size_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Bytes_GET_SIZE; -static HPy_ssize_t ctx_Bytes_GET_SIZE_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Bytes_AsString; -static const char *ctx_Bytes_AsString_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Bytes_AS_STRING; -static const char *ctx_Bytes_AS_STRING_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Bytes_FromString; -static HPy ctx_Bytes_FromString_jni(HPyContext *ctx, const char *bytes); -static jmethodID jniMethod_ctx_Bytes_FromStringAndSize; -static HPy ctx_Bytes_FromStringAndSize_jni(HPyContext *ctx, const char *bytes, HPy_ssize_t len); -static jmethodID jniMethod_ctx_Unicode_FromString; -static HPy ctx_Unicode_FromString_jni(HPyContext *ctx, const char *utf8); -static jmethodID jniMethod_ctx_Unicode_Check; -static int ctx_Unicode_Check_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Unicode_AsASCIIString; -static HPy ctx_Unicode_AsASCIIString_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Unicode_AsLatin1String; -static HPy ctx_Unicode_AsLatin1String_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Unicode_AsUTF8String; -static HPy ctx_Unicode_AsUTF8String_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Unicode_AsUTF8AndSize; -static const char *ctx_Unicode_AsUTF8AndSize_jni(HPyContext *ctx, HPy h, HPy_ssize_t *size); -_HPy_HIDDEN jmethodID jniMethod_ctx_Unicode_FromWideChar; -static jmethodID jniMethod_ctx_Unicode_DecodeFSDefault; -static HPy ctx_Unicode_DecodeFSDefault_jni(HPyContext *ctx, const char *v); -static jmethodID jniMethod_ctx_Unicode_DecodeFSDefaultAndSize; -static HPy ctx_Unicode_DecodeFSDefaultAndSize_jni(HPyContext *ctx, const char *v, HPy_ssize_t size); -static jmethodID jniMethod_ctx_Unicode_EncodeFSDefault; -static HPy ctx_Unicode_EncodeFSDefault_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Unicode_ReadChar; -static HPy_UCS4 ctx_Unicode_ReadChar_jni(HPyContext *ctx, HPy h, HPy_ssize_t index); -static jmethodID jniMethod_ctx_Unicode_DecodeASCII; -static HPy ctx_Unicode_DecodeASCII_jni(HPyContext *ctx, const char *ascii, HPy_ssize_t size, const char *errors); -static jmethodID jniMethod_ctx_Unicode_DecodeLatin1; -static HPy ctx_Unicode_DecodeLatin1_jni(HPyContext *ctx, const char *latin1, HPy_ssize_t size, const char *errors); -static jmethodID jniMethod_ctx_Unicode_FromEncodedObject; -static HPy ctx_Unicode_FromEncodedObject_jni(HPyContext *ctx, HPy obj, const char *encoding, const char *errors); -static jmethodID jniMethod_ctx_Unicode_Substring; -static HPy ctx_Unicode_Substring_jni(HPyContext *ctx, HPy str, HPy_ssize_t start, HPy_ssize_t end); -static jmethodID jniMethod_ctx_List_Check; -static int ctx_List_Check_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_List_New; -static HPy ctx_List_New_jni(HPyContext *ctx, HPy_ssize_t len); -static jmethodID jniMethod_ctx_List_Append; -static int ctx_List_Append_jni(HPyContext *ctx, HPy h_list, HPy h_item); -static jmethodID jniMethod_ctx_Dict_Check; -static int ctx_Dict_Check_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Dict_New; -static HPy ctx_Dict_New_jni(HPyContext *ctx); -static jmethodID jniMethod_ctx_Dict_Keys; -static HPy ctx_Dict_Keys_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Dict_Copy; -static HPy ctx_Dict_Copy_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Tuple_Check; -static int ctx_Tuple_Check_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Slice_Unpack; -static int ctx_Slice_Unpack_jni(HPyContext *ctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step); -static jmethodID jniMethod_ctx_Import_ImportModule; -static HPy ctx_Import_ImportModule_jni(HPyContext *ctx, const char *utf8_name); -static jmethodID jniMethod_ctx_Capsule_New; -static HPy ctx_Capsule_New_jni(HPyContext *ctx, void *pointer, const char *utf8_name, HPyCapsule_Destructor *destructor); -static jmethodID jniMethod_ctx_Capsule_Get; -static void *ctx_Capsule_Get_jni(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, const char *utf8_name); -static jmethodID jniMethod_ctx_Capsule_IsValid; -static int ctx_Capsule_IsValid_jni(HPyContext *ctx, HPy capsule, const char *utf8_name); -static jmethodID jniMethod_ctx_Capsule_Set; -static int ctx_Capsule_Set_jni(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, void *value); -static jmethodID jniMethod_ctx_FromPyObject; -static HPy ctx_FromPyObject_jni(HPyContext *ctx, cpy_PyObject *obj); -static jmethodID jniMethod_ctx_AsPyObject; -static cpy_PyObject *ctx_AsPyObject_jni(HPyContext *ctx, HPy h); -_HPy_HIDDEN jmethodID jniMethod_ctx_ListBuilder_New; -_HPy_HIDDEN jmethodID jniMethod_ctx_ListBuilder_Set; -_HPy_HIDDEN jmethodID jniMethod_ctx_ListBuilder_Build; -_HPy_HIDDEN jmethodID jniMethod_ctx_ListBuilder_Cancel; -_HPy_HIDDEN jmethodID jniMethod_ctx_TupleBuilder_New; -_HPy_HIDDEN jmethodID jniMethod_ctx_TupleBuilder_Set; -_HPy_HIDDEN jmethodID jniMethod_ctx_TupleBuilder_Build; -_HPy_HIDDEN jmethodID jniMethod_ctx_TupleBuilder_Cancel; -static jmethodID jniMethod_ctx_Field_Load; -static HPy ctx_Field_Load_jni(HPyContext *ctx, HPy source_object, HPyField source_field); -static jmethodID jniMethod_ctx_ReenterPythonExecution; -static void ctx_ReenterPythonExecution_jni(HPyContext *ctx, HPyThreadState state); -static jmethodID jniMethod_ctx_LeavePythonExecution; -static HPyThreadState ctx_LeavePythonExecution_jni(HPyContext *ctx); -_HPy_HIDDEN jmethodID jniMethod_ctx_Global_Load; -static jmethodID jniMethod_ctx_Dump; -static void ctx_Dump_jni(HPyContext *ctx, HPy h); -static jmethodID jniMethod_ctx_Compile_s; -static HPy ctx_Compile_s_jni(HPyContext *ctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind); -static jmethodID jniMethod_ctx_EvalCode; -static HPy ctx_EvalCode_jni(HPyContext *ctx, HPy code, HPy globals, HPy locals); -static jmethodID jniMethod_ctx_ContextVar_New; -static HPy ctx_ContextVar_New_jni(HPyContext *ctx, const char *name, HPy default_value); -static jmethodID jniMethod_ctx_ContextVar_Set; -static HPy ctx_ContextVar_Set_jni(HPyContext *ctx, HPy context_var, HPy value); -static jmethodID jniMethod_ctx_SetCallFunction; -static int ctx_SetCallFunction_jni(HPyContext *ctx, HPy h, HPyCallFunction *func); - -_HPy_HIDDEN int init_autogen_jni_ctx(JNIEnv *env, jclass clazz, HPyContext *ctx, jlongArray jctx_handles) -{ - - jlong *ctx_handles = (*env)->GetPrimitiveArrayCritical(env, jctx_handles, NULL); - if (ctx_handles == NULL) { - LOGS("ERROR: Could not access Java context handle array elements\n"); - return 1; - } - ctx->h_None = _jlong2h(ctx_handles[0]); - ctx->h_True = _jlong2h(ctx_handles[1]); - ctx->h_False = _jlong2h(ctx_handles[2]); - ctx->h_NotImplemented = _jlong2h(ctx_handles[3]); - ctx->h_Ellipsis = _jlong2h(ctx_handles[4]); - ctx->h_BaseException = _jlong2h(ctx_handles[5]); - ctx->h_Exception = _jlong2h(ctx_handles[6]); - ctx->h_StopAsyncIteration = _jlong2h(ctx_handles[7]); - ctx->h_StopIteration = _jlong2h(ctx_handles[8]); - ctx->h_GeneratorExit = _jlong2h(ctx_handles[9]); - ctx->h_ArithmeticError = _jlong2h(ctx_handles[10]); - ctx->h_LookupError = _jlong2h(ctx_handles[11]); - ctx->h_AssertionError = _jlong2h(ctx_handles[12]); - ctx->h_AttributeError = _jlong2h(ctx_handles[13]); - ctx->h_BufferError = _jlong2h(ctx_handles[14]); - ctx->h_EOFError = _jlong2h(ctx_handles[15]); - ctx->h_FloatingPointError = _jlong2h(ctx_handles[16]); - ctx->h_OSError = _jlong2h(ctx_handles[17]); - ctx->h_ImportError = _jlong2h(ctx_handles[18]); - ctx->h_ModuleNotFoundError = _jlong2h(ctx_handles[19]); - ctx->h_IndexError = _jlong2h(ctx_handles[20]); - ctx->h_KeyError = _jlong2h(ctx_handles[21]); - ctx->h_KeyboardInterrupt = _jlong2h(ctx_handles[22]); - ctx->h_MemoryError = _jlong2h(ctx_handles[23]); - ctx->h_NameError = _jlong2h(ctx_handles[24]); - ctx->h_OverflowError = _jlong2h(ctx_handles[25]); - ctx->h_RuntimeError = _jlong2h(ctx_handles[26]); - ctx->h_RecursionError = _jlong2h(ctx_handles[27]); - ctx->h_NotImplementedError = _jlong2h(ctx_handles[28]); - ctx->h_SyntaxError = _jlong2h(ctx_handles[29]); - ctx->h_IndentationError = _jlong2h(ctx_handles[30]); - ctx->h_TabError = _jlong2h(ctx_handles[31]); - ctx->h_ReferenceError = _jlong2h(ctx_handles[32]); - ctx->h_SystemError = _jlong2h(ctx_handles[33]); - ctx->h_SystemExit = _jlong2h(ctx_handles[34]); - ctx->h_TypeError = _jlong2h(ctx_handles[35]); - ctx->h_UnboundLocalError = _jlong2h(ctx_handles[36]); - ctx->h_UnicodeError = _jlong2h(ctx_handles[37]); - ctx->h_UnicodeEncodeError = _jlong2h(ctx_handles[38]); - ctx->h_UnicodeDecodeError = _jlong2h(ctx_handles[39]); - ctx->h_UnicodeTranslateError = _jlong2h(ctx_handles[40]); - ctx->h_ValueError = _jlong2h(ctx_handles[41]); - ctx->h_ZeroDivisionError = _jlong2h(ctx_handles[42]); - ctx->h_BlockingIOError = _jlong2h(ctx_handles[43]); - ctx->h_BrokenPipeError = _jlong2h(ctx_handles[44]); - ctx->h_ChildProcessError = _jlong2h(ctx_handles[45]); - ctx->h_ConnectionError = _jlong2h(ctx_handles[46]); - ctx->h_ConnectionAbortedError = _jlong2h(ctx_handles[47]); - ctx->h_ConnectionRefusedError = _jlong2h(ctx_handles[48]); - ctx->h_ConnectionResetError = _jlong2h(ctx_handles[49]); - ctx->h_FileExistsError = _jlong2h(ctx_handles[50]); - ctx->h_FileNotFoundError = _jlong2h(ctx_handles[51]); - ctx->h_InterruptedError = _jlong2h(ctx_handles[52]); - ctx->h_IsADirectoryError = _jlong2h(ctx_handles[53]); - ctx->h_NotADirectoryError = _jlong2h(ctx_handles[54]); - ctx->h_PermissionError = _jlong2h(ctx_handles[55]); - ctx->h_ProcessLookupError = _jlong2h(ctx_handles[56]); - ctx->h_TimeoutError = _jlong2h(ctx_handles[57]); - ctx->h_Warning = _jlong2h(ctx_handles[58]); - ctx->h_UserWarning = _jlong2h(ctx_handles[59]); - ctx->h_DeprecationWarning = _jlong2h(ctx_handles[60]); - ctx->h_PendingDeprecationWarning = _jlong2h(ctx_handles[61]); - ctx->h_SyntaxWarning = _jlong2h(ctx_handles[62]); - ctx->h_RuntimeWarning = _jlong2h(ctx_handles[63]); - ctx->h_FutureWarning = _jlong2h(ctx_handles[64]); - ctx->h_ImportWarning = _jlong2h(ctx_handles[65]); - ctx->h_UnicodeWarning = _jlong2h(ctx_handles[66]); - ctx->h_BytesWarning = _jlong2h(ctx_handles[67]); - ctx->h_ResourceWarning = _jlong2h(ctx_handles[68]); - ctx->h_BaseObjectType = _jlong2h(ctx_handles[69]); - ctx->h_TypeType = _jlong2h(ctx_handles[70]); - ctx->h_BoolType = _jlong2h(ctx_handles[71]); - ctx->h_LongType = _jlong2h(ctx_handles[72]); - ctx->h_FloatType = _jlong2h(ctx_handles[73]); - ctx->h_UnicodeType = _jlong2h(ctx_handles[74]); - ctx->h_TupleType = _jlong2h(ctx_handles[75]); - ctx->h_ListType = _jlong2h(ctx_handles[76]); - ctx->h_ComplexType = _jlong2h(ctx_handles[238]); - ctx->h_BytesType = _jlong2h(ctx_handles[239]); - ctx->h_MemoryViewType = _jlong2h(ctx_handles[240]); - ctx->h_CapsuleType = _jlong2h(ctx_handles[241]); - ctx->h_SliceType = _jlong2h(ctx_handles[242]); - ctx->h_Builtins = _jlong2h(ctx_handles[243]); - (*env)->ReleasePrimitiveArrayCritical(env, jctx_handles, ctx_handles, JNI_ABORT); - - jniMethod_ctx_Dup = (*env)->GetMethodID(env, clazz, "ctxDup", "(J)J"); - if (jniMethod_ctx_Dup == NULL) { - LOGS("ERROR: Java method ctxDup not found found !\n"); - return 1; - } - ctx->ctx_Dup = &ctx_Dup_jni; - jniMethod_ctx_Close = (*env)->GetMethodID(env, clazz, "ctxClose", "(J)V"); - if (jniMethod_ctx_Close == NULL) { - LOGS("ERROR: Java method ctxClose not found found !\n"); - return 1; - } - ctx->ctx_Close = &ctx_Close_jni; - jniMethod_ctx_Long_FromInt32_t = (*env)->GetMethodID(env, clazz, "ctxLongFromInt32t", "(I)J"); - if (jniMethod_ctx_Long_FromInt32_t == NULL) { - LOGS("ERROR: Java method ctxLongFromInt32t not found found !\n"); - return 1; - } - ctx->ctx_Long_FromInt32_t = &ctx_Long_FromInt32_t_jni; - jniMethod_ctx_Long_FromUInt32_t = (*env)->GetMethodID(env, clazz, "ctxLongFromUInt32t", "(I)J"); - if (jniMethod_ctx_Long_FromUInt32_t == NULL) { - LOGS("ERROR: Java method ctxLongFromUInt32t not found found !\n"); - return 1; - } - ctx->ctx_Long_FromUInt32_t = &ctx_Long_FromUInt32_t_jni; - jniMethod_ctx_Long_FromInt64_t = (*env)->GetMethodID(env, clazz, "ctxLongFromInt64t", "(J)J"); - if (jniMethod_ctx_Long_FromInt64_t == NULL) { - LOGS("ERROR: Java method ctxLongFromInt64t not found found !\n"); - return 1; - } - ctx->ctx_Long_FromInt64_t = &ctx_Long_FromInt64_t_jni; - jniMethod_ctx_Long_FromUInt64_t = (*env)->GetMethodID(env, clazz, "ctxLongFromUInt64t", "(J)J"); - if (jniMethod_ctx_Long_FromUInt64_t == NULL) { - LOGS("ERROR: Java method ctxLongFromUInt64t not found found !\n"); - return 1; - } - ctx->ctx_Long_FromUInt64_t = &ctx_Long_FromUInt64_t_jni; - jniMethod_ctx_Long_FromSize_t = (*env)->GetMethodID(env, clazz, "ctxLongFromSizet", "(J)J"); - if (jniMethod_ctx_Long_FromSize_t == NULL) { - LOGS("ERROR: Java method ctxLongFromSizet not found found !\n"); - return 1; - } - ctx->ctx_Long_FromSize_t = &ctx_Long_FromSize_t_jni; - jniMethod_ctx_Long_FromSsize_t = (*env)->GetMethodID(env, clazz, "ctxLongFromSsizet", "(J)J"); - if (jniMethod_ctx_Long_FromSsize_t == NULL) { - LOGS("ERROR: Java method ctxLongFromSsizet not found found !\n"); - return 1; - } - ctx->ctx_Long_FromSsize_t = &ctx_Long_FromSsize_t_jni; - jniMethod_ctx_Long_AsInt32_t = (*env)->GetMethodID(env, clazz, "ctxLongAsInt32t", "(J)I"); - if (jniMethod_ctx_Long_AsInt32_t == NULL) { - LOGS("ERROR: Java method ctxLongAsInt32t not found found !\n"); - return 1; - } - ctx->ctx_Long_AsInt32_t = &ctx_Long_AsInt32_t_jni; - jniMethod_ctx_Long_AsUInt32_t = (*env)->GetMethodID(env, clazz, "ctxLongAsUInt32t", "(J)I"); - if (jniMethod_ctx_Long_AsUInt32_t == NULL) { - LOGS("ERROR: Java method ctxLongAsUInt32t not found found !\n"); - return 1; - } - ctx->ctx_Long_AsUInt32_t = &ctx_Long_AsUInt32_t_jni; - jniMethod_ctx_Long_AsUInt32_tMask = (*env)->GetMethodID(env, clazz, "ctxLongAsUInt32tMask", "(J)I"); - if (jniMethod_ctx_Long_AsUInt32_tMask == NULL) { - LOGS("ERROR: Java method ctxLongAsUInt32tMask not found found !\n"); - return 1; - } - ctx->ctx_Long_AsUInt32_tMask = &ctx_Long_AsUInt32_tMask_jni; - jniMethod_ctx_Long_AsInt64_t = (*env)->GetMethodID(env, clazz, "ctxLongAsInt64t", "(J)J"); - if (jniMethod_ctx_Long_AsInt64_t == NULL) { - LOGS("ERROR: Java method ctxLongAsInt64t not found found !\n"); - return 1; - } - ctx->ctx_Long_AsInt64_t = &ctx_Long_AsInt64_t_jni; - jniMethod_ctx_Long_AsUInt64_t = (*env)->GetMethodID(env, clazz, "ctxLongAsUInt64t", "(J)J"); - if (jniMethod_ctx_Long_AsUInt64_t == NULL) { - LOGS("ERROR: Java method ctxLongAsUInt64t not found found !\n"); - return 1; - } - ctx->ctx_Long_AsUInt64_t = &ctx_Long_AsUInt64_t_jni; - jniMethod_ctx_Long_AsUInt64_tMask = (*env)->GetMethodID(env, clazz, "ctxLongAsUInt64tMask", "(J)J"); - if (jniMethod_ctx_Long_AsUInt64_tMask == NULL) { - LOGS("ERROR: Java method ctxLongAsUInt64tMask not found found !\n"); - return 1; - } - ctx->ctx_Long_AsUInt64_tMask = &ctx_Long_AsUInt64_tMask_jni; - jniMethod_ctx_Long_AsSize_t = (*env)->GetMethodID(env, clazz, "ctxLongAsSizet", "(J)J"); - if (jniMethod_ctx_Long_AsSize_t == NULL) { - LOGS("ERROR: Java method ctxLongAsSizet not found found !\n"); - return 1; - } - ctx->ctx_Long_AsSize_t = &ctx_Long_AsSize_t_jni; - jniMethod_ctx_Long_AsSsize_t = (*env)->GetMethodID(env, clazz, "ctxLongAsSsizet", "(J)J"); - if (jniMethod_ctx_Long_AsSsize_t == NULL) { - LOGS("ERROR: Java method ctxLongAsSsizet not found found !\n"); - return 1; - } - ctx->ctx_Long_AsSsize_t = &ctx_Long_AsSsize_t_jni; - jniMethod_ctx_Long_AsVoidPtr = (*env)->GetMethodID(env, clazz, "ctxLongAsVoidPtr", "(J)J"); - if (jniMethod_ctx_Long_AsVoidPtr == NULL) { - LOGS("ERROR: Java method ctxLongAsVoidPtr not found found !\n"); - return 1; - } - ctx->ctx_Long_AsVoidPtr = &ctx_Long_AsVoidPtr_jni; - jniMethod_ctx_Long_AsDouble = (*env)->GetMethodID(env, clazz, "ctxLongAsDouble", "(J)D"); - if (jniMethod_ctx_Long_AsDouble == NULL) { - LOGS("ERROR: Java method ctxLongAsDouble not found found !\n"); - return 1; - } - ctx->ctx_Long_AsDouble = &ctx_Long_AsDouble_jni; - jniMethod_ctx_Float_FromDouble = (*env)->GetMethodID(env, clazz, "ctxFloatFromDouble", "(D)J"); - if (jniMethod_ctx_Float_FromDouble == NULL) { - LOGS("ERROR: Java method ctxFloatFromDouble not found found !\n"); - return 1; - } - ctx->ctx_Float_FromDouble = &ctx_Float_FromDouble_jni; - jniMethod_ctx_Float_AsDouble = (*env)->GetMethodID(env, clazz, "ctxFloatAsDouble", "(J)D"); - if (jniMethod_ctx_Float_AsDouble == NULL) { - LOGS("ERROR: Java method ctxFloatAsDouble not found found !\n"); - return 1; - } - ctx->ctx_Float_AsDouble = &ctx_Float_AsDouble_jni; - jniMethod_ctx_Bool_FromBool = (*env)->GetMethodID(env, clazz, "ctxBoolFromBool", "(Z)J"); - if (jniMethod_ctx_Bool_FromBool == NULL) { - LOGS("ERROR: Java method ctxBoolFromBool not found found !\n"); - return 1; - } - ctx->ctx_Bool_FromBool = &ctx_Bool_FromBool_jni; - jniMethod_ctx_Length = (*env)->GetMethodID(env, clazz, "ctxLength", "(J)J"); - if (jniMethod_ctx_Length == NULL) { - LOGS("ERROR: Java method ctxLength not found found !\n"); - return 1; - } - ctx->ctx_Length = &ctx_Length_jni; - jniMethod_ctx_Number_Check = (*env)->GetMethodID(env, clazz, "ctxNumberCheck", "(J)I"); - if (jniMethod_ctx_Number_Check == NULL) { - LOGS("ERROR: Java method ctxNumberCheck not found found !\n"); - return 1; - } - ctx->ctx_Number_Check = &ctx_Number_Check_jni; - jniMethod_ctx_Add = (*env)->GetMethodID(env, clazz, "ctxAdd", "(JJ)J"); - if (jniMethod_ctx_Add == NULL) { - LOGS("ERROR: Java method ctxAdd not found found !\n"); - return 1; - } - ctx->ctx_Add = &ctx_Add_jni; - jniMethod_ctx_Subtract = (*env)->GetMethodID(env, clazz, "ctxSubtract", "(JJ)J"); - if (jniMethod_ctx_Subtract == NULL) { - LOGS("ERROR: Java method ctxSubtract not found found !\n"); - return 1; - } - ctx->ctx_Subtract = &ctx_Subtract_jni; - jniMethod_ctx_Multiply = (*env)->GetMethodID(env, clazz, "ctxMultiply", "(JJ)J"); - if (jniMethod_ctx_Multiply == NULL) { - LOGS("ERROR: Java method ctxMultiply not found found !\n"); - return 1; - } - ctx->ctx_Multiply = &ctx_Multiply_jni; - jniMethod_ctx_MatrixMultiply = (*env)->GetMethodID(env, clazz, "ctxMatrixMultiply", "(JJ)J"); - if (jniMethod_ctx_MatrixMultiply == NULL) { - LOGS("ERROR: Java method ctxMatrixMultiply not found found !\n"); - return 1; - } - ctx->ctx_MatrixMultiply = &ctx_MatrixMultiply_jni; - jniMethod_ctx_FloorDivide = (*env)->GetMethodID(env, clazz, "ctxFloorDivide", "(JJ)J"); - if (jniMethod_ctx_FloorDivide == NULL) { - LOGS("ERROR: Java method ctxFloorDivide not found found !\n"); - return 1; - } - ctx->ctx_FloorDivide = &ctx_FloorDivide_jni; - jniMethod_ctx_TrueDivide = (*env)->GetMethodID(env, clazz, "ctxTrueDivide", "(JJ)J"); - if (jniMethod_ctx_TrueDivide == NULL) { - LOGS("ERROR: Java method ctxTrueDivide not found found !\n"); - return 1; - } - ctx->ctx_TrueDivide = &ctx_TrueDivide_jni; - jniMethod_ctx_Remainder = (*env)->GetMethodID(env, clazz, "ctxRemainder", "(JJ)J"); - if (jniMethod_ctx_Remainder == NULL) { - LOGS("ERROR: Java method ctxRemainder not found found !\n"); - return 1; - } - ctx->ctx_Remainder = &ctx_Remainder_jni; - jniMethod_ctx_Divmod = (*env)->GetMethodID(env, clazz, "ctxDivmod", "(JJ)J"); - if (jniMethod_ctx_Divmod == NULL) { - LOGS("ERROR: Java method ctxDivmod not found found !\n"); - return 1; - } - ctx->ctx_Divmod = &ctx_Divmod_jni; - jniMethod_ctx_Power = (*env)->GetMethodID(env, clazz, "ctxPower", "(JJJ)J"); - if (jniMethod_ctx_Power == NULL) { - LOGS("ERROR: Java method ctxPower not found found !\n"); - return 1; - } - ctx->ctx_Power = &ctx_Power_jni; - jniMethod_ctx_Negative = (*env)->GetMethodID(env, clazz, "ctxNegative", "(J)J"); - if (jniMethod_ctx_Negative == NULL) { - LOGS("ERROR: Java method ctxNegative not found found !\n"); - return 1; - } - ctx->ctx_Negative = &ctx_Negative_jni; - jniMethod_ctx_Positive = (*env)->GetMethodID(env, clazz, "ctxPositive", "(J)J"); - if (jniMethod_ctx_Positive == NULL) { - LOGS("ERROR: Java method ctxPositive not found found !\n"); - return 1; - } - ctx->ctx_Positive = &ctx_Positive_jni; - jniMethod_ctx_Absolute = (*env)->GetMethodID(env, clazz, "ctxAbsolute", "(J)J"); - if (jniMethod_ctx_Absolute == NULL) { - LOGS("ERROR: Java method ctxAbsolute not found found !\n"); - return 1; - } - ctx->ctx_Absolute = &ctx_Absolute_jni; - jniMethod_ctx_Invert = (*env)->GetMethodID(env, clazz, "ctxInvert", "(J)J"); - if (jniMethod_ctx_Invert == NULL) { - LOGS("ERROR: Java method ctxInvert not found found !\n"); - return 1; - } - ctx->ctx_Invert = &ctx_Invert_jni; - jniMethod_ctx_Lshift = (*env)->GetMethodID(env, clazz, "ctxLshift", "(JJ)J"); - if (jniMethod_ctx_Lshift == NULL) { - LOGS("ERROR: Java method ctxLshift not found found !\n"); - return 1; - } - ctx->ctx_Lshift = &ctx_Lshift_jni; - jniMethod_ctx_Rshift = (*env)->GetMethodID(env, clazz, "ctxRshift", "(JJ)J"); - if (jniMethod_ctx_Rshift == NULL) { - LOGS("ERROR: Java method ctxRshift not found found !\n"); - return 1; - } - ctx->ctx_Rshift = &ctx_Rshift_jni; - jniMethod_ctx_And = (*env)->GetMethodID(env, clazz, "ctxAnd", "(JJ)J"); - if (jniMethod_ctx_And == NULL) { - LOGS("ERROR: Java method ctxAnd not found found !\n"); - return 1; - } - ctx->ctx_And = &ctx_And_jni; - jniMethod_ctx_Xor = (*env)->GetMethodID(env, clazz, "ctxXor", "(JJ)J"); - if (jniMethod_ctx_Xor == NULL) { - LOGS("ERROR: Java method ctxXor not found found !\n"); - return 1; - } - ctx->ctx_Xor = &ctx_Xor_jni; - jniMethod_ctx_Or = (*env)->GetMethodID(env, clazz, "ctxOr", "(JJ)J"); - if (jniMethod_ctx_Or == NULL) { - LOGS("ERROR: Java method ctxOr not found found !\n"); - return 1; - } - ctx->ctx_Or = &ctx_Or_jni; - jniMethod_ctx_Index = (*env)->GetMethodID(env, clazz, "ctxIndex", "(J)J"); - if (jniMethod_ctx_Index == NULL) { - LOGS("ERROR: Java method ctxIndex not found found !\n"); - return 1; - } - ctx->ctx_Index = &ctx_Index_jni; - jniMethod_ctx_Long = (*env)->GetMethodID(env, clazz, "ctxLong", "(J)J"); - if (jniMethod_ctx_Long == NULL) { - LOGS("ERROR: Java method ctxLong not found found !\n"); - return 1; - } - ctx->ctx_Long = &ctx_Long_jni; - jniMethod_ctx_Float = (*env)->GetMethodID(env, clazz, "ctxFloat", "(J)J"); - if (jniMethod_ctx_Float == NULL) { - LOGS("ERROR: Java method ctxFloat not found found !\n"); - return 1; - } - ctx->ctx_Float = &ctx_Float_jni; - jniMethod_ctx_InPlaceAdd = (*env)->GetMethodID(env, clazz, "ctxInPlaceAdd", "(JJ)J"); - if (jniMethod_ctx_InPlaceAdd == NULL) { - LOGS("ERROR: Java method ctxInPlaceAdd not found found !\n"); - return 1; - } - ctx->ctx_InPlaceAdd = &ctx_InPlaceAdd_jni; - jniMethod_ctx_InPlaceSubtract = (*env)->GetMethodID(env, clazz, "ctxInPlaceSubtract", "(JJ)J"); - if (jniMethod_ctx_InPlaceSubtract == NULL) { - LOGS("ERROR: Java method ctxInPlaceSubtract not found found !\n"); - return 1; - } - ctx->ctx_InPlaceSubtract = &ctx_InPlaceSubtract_jni; - jniMethod_ctx_InPlaceMultiply = (*env)->GetMethodID(env, clazz, "ctxInPlaceMultiply", "(JJ)J"); - if (jniMethod_ctx_InPlaceMultiply == NULL) { - LOGS("ERROR: Java method ctxInPlaceMultiply not found found !\n"); - return 1; - } - ctx->ctx_InPlaceMultiply = &ctx_InPlaceMultiply_jni; - jniMethod_ctx_InPlaceMatrixMultiply = (*env)->GetMethodID(env, clazz, "ctxInPlaceMatrixMultiply", "(JJ)J"); - if (jniMethod_ctx_InPlaceMatrixMultiply == NULL) { - LOGS("ERROR: Java method ctxInPlaceMatrixMultiply not found found !\n"); - return 1; - } - ctx->ctx_InPlaceMatrixMultiply = &ctx_InPlaceMatrixMultiply_jni; - jniMethod_ctx_InPlaceFloorDivide = (*env)->GetMethodID(env, clazz, "ctxInPlaceFloorDivide", "(JJ)J"); - if (jniMethod_ctx_InPlaceFloorDivide == NULL) { - LOGS("ERROR: Java method ctxInPlaceFloorDivide not found found !\n"); - return 1; - } - ctx->ctx_InPlaceFloorDivide = &ctx_InPlaceFloorDivide_jni; - jniMethod_ctx_InPlaceTrueDivide = (*env)->GetMethodID(env, clazz, "ctxInPlaceTrueDivide", "(JJ)J"); - if (jniMethod_ctx_InPlaceTrueDivide == NULL) { - LOGS("ERROR: Java method ctxInPlaceTrueDivide not found found !\n"); - return 1; - } - ctx->ctx_InPlaceTrueDivide = &ctx_InPlaceTrueDivide_jni; - jniMethod_ctx_InPlaceRemainder = (*env)->GetMethodID(env, clazz, "ctxInPlaceRemainder", "(JJ)J"); - if (jniMethod_ctx_InPlaceRemainder == NULL) { - LOGS("ERROR: Java method ctxInPlaceRemainder not found found !\n"); - return 1; - } - ctx->ctx_InPlaceRemainder = &ctx_InPlaceRemainder_jni; - jniMethod_ctx_InPlacePower = (*env)->GetMethodID(env, clazz, "ctxInPlacePower", "(JJJ)J"); - if (jniMethod_ctx_InPlacePower == NULL) { - LOGS("ERROR: Java method ctxInPlacePower not found found !\n"); - return 1; - } - ctx->ctx_InPlacePower = &ctx_InPlacePower_jni; - jniMethod_ctx_InPlaceLshift = (*env)->GetMethodID(env, clazz, "ctxInPlaceLshift", "(JJ)J"); - if (jniMethod_ctx_InPlaceLshift == NULL) { - LOGS("ERROR: Java method ctxInPlaceLshift not found found !\n"); - return 1; - } - ctx->ctx_InPlaceLshift = &ctx_InPlaceLshift_jni; - jniMethod_ctx_InPlaceRshift = (*env)->GetMethodID(env, clazz, "ctxInPlaceRshift", "(JJ)J"); - if (jniMethod_ctx_InPlaceRshift == NULL) { - LOGS("ERROR: Java method ctxInPlaceRshift not found found !\n"); - return 1; - } - ctx->ctx_InPlaceRshift = &ctx_InPlaceRshift_jni; - jniMethod_ctx_InPlaceAnd = (*env)->GetMethodID(env, clazz, "ctxInPlaceAnd", "(JJ)J"); - if (jniMethod_ctx_InPlaceAnd == NULL) { - LOGS("ERROR: Java method ctxInPlaceAnd not found found !\n"); - return 1; - } - ctx->ctx_InPlaceAnd = &ctx_InPlaceAnd_jni; - jniMethod_ctx_InPlaceXor = (*env)->GetMethodID(env, clazz, "ctxInPlaceXor", "(JJ)J"); - if (jniMethod_ctx_InPlaceXor == NULL) { - LOGS("ERROR: Java method ctxInPlaceXor not found found !\n"); - return 1; - } - ctx->ctx_InPlaceXor = &ctx_InPlaceXor_jni; - jniMethod_ctx_InPlaceOr = (*env)->GetMethodID(env, clazz, "ctxInPlaceOr", "(JJ)J"); - if (jniMethod_ctx_InPlaceOr == NULL) { - LOGS("ERROR: Java method ctxInPlaceOr not found found !\n"); - return 1; - } - ctx->ctx_InPlaceOr = &ctx_InPlaceOr_jni; - jniMethod_ctx_Callable_Check = (*env)->GetMethodID(env, clazz, "ctxCallableCheck", "(J)I"); - if (jniMethod_ctx_Callable_Check == NULL) { - LOGS("ERROR: Java method ctxCallableCheck not found found !\n"); - return 1; - } - ctx->ctx_Callable_Check = &ctx_Callable_Check_jni; - jniMethod_ctx_CallTupleDict = (*env)->GetMethodID(env, clazz, "ctxCallTupleDict", "(JJJ)J"); - if (jniMethod_ctx_CallTupleDict == NULL) { - LOGS("ERROR: Java method ctxCallTupleDict not found found !\n"); - return 1; - } - ctx->ctx_CallTupleDict = &ctx_CallTupleDict_jni; - jniMethod_ctx_Call = (*env)->GetMethodID(env, clazz, "ctxCall", "(JJJJ)J"); - if (jniMethod_ctx_Call == NULL) { - LOGS("ERROR: Java method ctxCall not found found !\n"); - return 1; - } - ctx->ctx_Call = &ctx_Call_jni; - jniMethod_ctx_CallMethod = (*env)->GetMethodID(env, clazz, "ctxCallMethod", "(JJJJ)J"); - if (jniMethod_ctx_CallMethod == NULL) { - LOGS("ERROR: Java method ctxCallMethod not found found !\n"); - return 1; - } - ctx->ctx_CallMethod = &ctx_CallMethod_jni; - jniMethod_ctx_FatalError = (*env)->GetMethodID(env, clazz, "ctxFatalError", "(J)V"); - if (jniMethod_ctx_FatalError == NULL) { - LOGS("ERROR: Java method ctxFatalError not found found !\n"); - return 1; - } - ctx->ctx_FatalError = &ctx_FatalError_jni; - jniMethod_ctx_Err_SetString = (*env)->GetMethodID(env, clazz, "ctxErrSetString", "(JJ)V"); - if (jniMethod_ctx_Err_SetString == NULL) { - LOGS("ERROR: Java method ctxErrSetString not found found !\n"); - return 1; - } - ctx->ctx_Err_SetString = &ctx_Err_SetString_jni; - jniMethod_ctx_Err_SetObject = (*env)->GetMethodID(env, clazz, "ctxErrSetObject", "(JJ)V"); - if (jniMethod_ctx_Err_SetObject == NULL) { - LOGS("ERROR: Java method ctxErrSetObject not found found !\n"); - return 1; - } - ctx->ctx_Err_SetObject = &ctx_Err_SetObject_jni; - jniMethod_ctx_Err_SetFromErrnoWithFilename = (*env)->GetMethodID(env, clazz, "ctxErrSetFromErrnoWithFilename", "(JJ)J"); - if (jniMethod_ctx_Err_SetFromErrnoWithFilename == NULL) { - LOGS("ERROR: Java method ctxErrSetFromErrnoWithFilename not found found !\n"); - return 1; - } - ctx->ctx_Err_SetFromErrnoWithFilename = &ctx_Err_SetFromErrnoWithFilename_jni; - jniMethod_ctx_Err_SetFromErrnoWithFilenameObjects = (*env)->GetMethodID(env, clazz, "ctxErrSetFromErrnoWithFilenameObjects", "(JJJ)V"); - if (jniMethod_ctx_Err_SetFromErrnoWithFilenameObjects == NULL) { - LOGS("ERROR: Java method ctxErrSetFromErrnoWithFilenameObjects not found found !\n"); - return 1; - } - ctx->ctx_Err_SetFromErrnoWithFilenameObjects = &ctx_Err_SetFromErrnoWithFilenameObjects_jni; - jniMethod_ctx_Err_Occurred = (*env)->GetMethodID(env, clazz, "ctxErrOccurred", "()I"); - if (jniMethod_ctx_Err_Occurred == NULL) { - LOGS("ERROR: Java method ctxErrOccurred not found found !\n"); - return 1; - } - ctx->ctx_Err_Occurred = &ctx_Err_Occurred_jni; - jniMethod_ctx_Err_ExceptionMatches = (*env)->GetMethodID(env, clazz, "ctxErrExceptionMatches", "(J)I"); - if (jniMethod_ctx_Err_ExceptionMatches == NULL) { - LOGS("ERROR: Java method ctxErrExceptionMatches not found found !\n"); - return 1; - } - ctx->ctx_Err_ExceptionMatches = &ctx_Err_ExceptionMatches_jni; - jniMethod_ctx_Err_NoMemory = (*env)->GetMethodID(env, clazz, "ctxErrNoMemory", "()V"); - if (jniMethod_ctx_Err_NoMemory == NULL) { - LOGS("ERROR: Java method ctxErrNoMemory not found found !\n"); - return 1; - } - ctx->ctx_Err_NoMemory = &ctx_Err_NoMemory_jni; - jniMethod_ctx_Err_Clear = (*env)->GetMethodID(env, clazz, "ctxErrClear", "()V"); - if (jniMethod_ctx_Err_Clear == NULL) { - LOGS("ERROR: Java method ctxErrClear not found found !\n"); - return 1; - } - ctx->ctx_Err_Clear = &ctx_Err_Clear_jni; - jniMethod_ctx_Err_NewException = (*env)->GetMethodID(env, clazz, "ctxErrNewException", "(JJJ)J"); - if (jniMethod_ctx_Err_NewException == NULL) { - LOGS("ERROR: Java method ctxErrNewException not found found !\n"); - return 1; - } - ctx->ctx_Err_NewException = &ctx_Err_NewException_jni; - jniMethod_ctx_Err_NewExceptionWithDoc = (*env)->GetMethodID(env, clazz, "ctxErrNewExceptionWithDoc", "(JJJJ)J"); - if (jniMethod_ctx_Err_NewExceptionWithDoc == NULL) { - LOGS("ERROR: Java method ctxErrNewExceptionWithDoc not found found !\n"); - return 1; - } - ctx->ctx_Err_NewExceptionWithDoc = &ctx_Err_NewExceptionWithDoc_jni; - jniMethod_ctx_Err_WarnEx = (*env)->GetMethodID(env, clazz, "ctxErrWarnEx", "(JJJ)I"); - if (jniMethod_ctx_Err_WarnEx == NULL) { - LOGS("ERROR: Java method ctxErrWarnEx not found found !\n"); - return 1; - } - ctx->ctx_Err_WarnEx = &ctx_Err_WarnEx_jni; - jniMethod_ctx_Err_WriteUnraisable = (*env)->GetMethodID(env, clazz, "ctxErrWriteUnraisable", "(J)V"); - if (jniMethod_ctx_Err_WriteUnraisable == NULL) { - LOGS("ERROR: Java method ctxErrWriteUnraisable not found found !\n"); - return 1; - } - ctx->ctx_Err_WriteUnraisable = &ctx_Err_WriteUnraisable_jni; - jniMethod_ctx_IsTrue = (*env)->GetMethodID(env, clazz, "ctxIsTrue", "(J)I"); - if (jniMethod_ctx_IsTrue == NULL) { - LOGS("ERROR: Java method ctxIsTrue not found found !\n"); - return 1; - } - ctx->ctx_IsTrue = &ctx_IsTrue_jni; - jniMethod_ctx_Type_FromSpec = (*env)->GetMethodID(env, clazz, "ctxTypeFromSpec", "(JJ)J"); - if (jniMethod_ctx_Type_FromSpec == NULL) { - LOGS("ERROR: Java method ctxTypeFromSpec not found found !\n"); - return 1; - } - ctx->ctx_Type_FromSpec = &ctx_Type_FromSpec_jni; - jniMethod_ctx_Type_GenericNew = (*env)->GetMethodID(env, clazz, "ctxTypeGenericNew", "(JJJJ)J"); - if (jniMethod_ctx_Type_GenericNew == NULL) { - LOGS("ERROR: Java method ctxTypeGenericNew not found found !\n"); - return 1; - } - ctx->ctx_Type_GenericNew = &ctx_Type_GenericNew_jni; - jniMethod_ctx_GetAttr = (*env)->GetMethodID(env, clazz, "ctxGetAttr", "(JJ)J"); - if (jniMethod_ctx_GetAttr == NULL) { - LOGS("ERROR: Java method ctxGetAttr not found found !\n"); - return 1; - } - ctx->ctx_GetAttr = &ctx_GetAttr_jni; - jniMethod_ctx_HasAttr = (*env)->GetMethodID(env, clazz, "ctxHasAttr", "(JJ)I"); - if (jniMethod_ctx_HasAttr == NULL) { - LOGS("ERROR: Java method ctxHasAttr not found found !\n"); - return 1; - } - ctx->ctx_HasAttr = &ctx_HasAttr_jni; - jniMethod_ctx_HasAttr_s = (*env)->GetMethodID(env, clazz, "ctxHasAttrs", "(JJ)I"); - if (jniMethod_ctx_HasAttr_s == NULL) { - LOGS("ERROR: Java method ctxHasAttrs not found found !\n"); - return 1; - } - ctx->ctx_HasAttr_s = &ctx_HasAttr_s_jni; - jniMethod_ctx_SetAttr = (*env)->GetMethodID(env, clazz, "ctxSetAttr", "(JJJ)I"); - if (jniMethod_ctx_SetAttr == NULL) { - LOGS("ERROR: Java method ctxSetAttr not found found !\n"); - return 1; - } - ctx->ctx_SetAttr = &ctx_SetAttr_jni; - jniMethod_ctx_SetAttr_s = (*env)->GetMethodID(env, clazz, "ctxSetAttrs", "(JJJ)I"); - if (jniMethod_ctx_SetAttr_s == NULL) { - LOGS("ERROR: Java method ctxSetAttrs not found found !\n"); - return 1; - } - ctx->ctx_SetAttr_s = &ctx_SetAttr_s_jni; - jniMethod_ctx_GetItem = (*env)->GetMethodID(env, clazz, "ctxGetItem", "(JJ)J"); - if (jniMethod_ctx_GetItem == NULL) { - LOGS("ERROR: Java method ctxGetItem not found found !\n"); - return 1; - } - ctx->ctx_GetItem = &ctx_GetItem_jni; - jniMethod_ctx_GetItem_i = (*env)->GetMethodID(env, clazz, "ctxGetItemi", "(JJ)J"); - if (jniMethod_ctx_GetItem_i == NULL) { - LOGS("ERROR: Java method ctxGetItemi not found found !\n"); - return 1; - } - ctx->ctx_GetItem_i = &ctx_GetItem_i_jni; - jniMethod_ctx_Contains = (*env)->GetMethodID(env, clazz, "ctxContains", "(JJ)I"); - if (jniMethod_ctx_Contains == NULL) { - LOGS("ERROR: Java method ctxContains not found found !\n"); - return 1; - } - ctx->ctx_Contains = &ctx_Contains_jni; - jniMethod_ctx_SetItem = (*env)->GetMethodID(env, clazz, "ctxSetItem", "(JJJ)I"); - if (jniMethod_ctx_SetItem == NULL) { - LOGS("ERROR: Java method ctxSetItem not found found !\n"); - return 1; - } - ctx->ctx_SetItem = &ctx_SetItem_jni; - jniMethod_ctx_SetItem_i = (*env)->GetMethodID(env, clazz, "ctxSetItemi", "(JJJ)I"); - if (jniMethod_ctx_SetItem_i == NULL) { - LOGS("ERROR: Java method ctxSetItemi not found found !\n"); - return 1; - } - ctx->ctx_SetItem_i = &ctx_SetItem_i_jni; - jniMethod_ctx_DelItem = (*env)->GetMethodID(env, clazz, "ctxDelItem", "(JJ)I"); - if (jniMethod_ctx_DelItem == NULL) { - LOGS("ERROR: Java method ctxDelItem not found found !\n"); - return 1; - } - ctx->ctx_DelItem = &ctx_DelItem_jni; - jniMethod_ctx_DelItem_i = (*env)->GetMethodID(env, clazz, "ctxDelItemi", "(JJ)I"); - if (jniMethod_ctx_DelItem_i == NULL) { - LOGS("ERROR: Java method ctxDelItemi not found found !\n"); - return 1; - } - ctx->ctx_DelItem_i = &ctx_DelItem_i_jni; - jniMethod_ctx_DelItem_s = (*env)->GetMethodID(env, clazz, "ctxDelItems", "(JJ)I"); - if (jniMethod_ctx_DelItem_s == NULL) { - LOGS("ERROR: Java method ctxDelItems not found found !\n"); - return 1; - } - ctx->ctx_DelItem_s = &ctx_DelItem_s_jni; - jniMethod_ctx_Type = (*env)->GetMethodID(env, clazz, "ctxType", "(J)J"); - if (jniMethod_ctx_Type == NULL) { - LOGS("ERROR: Java method ctxType not found found !\n"); - return 1; - } - ctx->ctx_Type = &ctx_Type_jni; - jniMethod_ctx_TypeCheck = (*env)->GetMethodID(env, clazz, "ctxTypeCheck", "(JJ)I"); - if (jniMethod_ctx_TypeCheck == NULL) { - LOGS("ERROR: Java method ctxTypeCheck not found found !\n"); - return 1; - } - ctx->ctx_TypeCheck = &ctx_TypeCheck_jni; - jniMethod_ctx_Type_GetName = (*env)->GetMethodID(env, clazz, "ctxTypeGetName", "(J)J"); - if (jniMethod_ctx_Type_GetName == NULL) { - LOGS("ERROR: Java method ctxTypeGetName not found found !\n"); - return 1; - } - ctx->ctx_Type_GetName = &ctx_Type_GetName_jni; - jniMethod_ctx_Type_IsSubtype = (*env)->GetMethodID(env, clazz, "ctxTypeIsSubtype", "(JJ)I"); - if (jniMethod_ctx_Type_IsSubtype == NULL) { - LOGS("ERROR: Java method ctxTypeIsSubtype not found found !\n"); - return 1; - } - ctx->ctx_Type_IsSubtype = &ctx_Type_IsSubtype_jni; - jniMethod_ctx_Is = (*env)->GetMethodID(env, clazz, "ctxIs", "(JJ)I"); - if (jniMethod_ctx_Is == NULL) { - LOGS("ERROR: Java method ctxIs not found found !\n"); - return 1; - } - ctx->ctx_Is = &ctx_Is_jni; - jniMethod_ctx_AsStruct_Object = (*env)->GetMethodID(env, clazz, "ctxAsStructObject", "(J)J"); - if (jniMethod_ctx_AsStruct_Object == NULL) { - LOGS("ERROR: Java method ctxAsStructObject not found found !\n"); - return 1; - } - ctx->ctx_AsStruct_Object = &ctx_AsStruct_Object_jni; - jniMethod_ctx_AsStruct_Legacy = (*env)->GetMethodID(env, clazz, "ctxAsStructLegacy", "(J)J"); - if (jniMethod_ctx_AsStruct_Legacy == NULL) { - LOGS("ERROR: Java method ctxAsStructLegacy not found found !\n"); - return 1; - } - ctx->ctx_AsStruct_Legacy = &ctx_AsStruct_Legacy_jni; - jniMethod_ctx_AsStruct_Type = (*env)->GetMethodID(env, clazz, "ctxAsStructType", "(J)J"); - if (jniMethod_ctx_AsStruct_Type == NULL) { - LOGS("ERROR: Java method ctxAsStructType not found found !\n"); - return 1; - } - ctx->ctx_AsStruct_Type = &ctx_AsStruct_Type_jni; - jniMethod_ctx_AsStruct_Long = (*env)->GetMethodID(env, clazz, "ctxAsStructLong", "(J)J"); - if (jniMethod_ctx_AsStruct_Long == NULL) { - LOGS("ERROR: Java method ctxAsStructLong not found found !\n"); - return 1; - } - ctx->ctx_AsStruct_Long = &ctx_AsStruct_Long_jni; - jniMethod_ctx_AsStruct_Float = (*env)->GetMethodID(env, clazz, "ctxAsStructFloat", "(J)J"); - if (jniMethod_ctx_AsStruct_Float == NULL) { - LOGS("ERROR: Java method ctxAsStructFloat not found found !\n"); - return 1; - } - ctx->ctx_AsStruct_Float = &ctx_AsStruct_Float_jni; - jniMethod_ctx_AsStruct_Unicode = (*env)->GetMethodID(env, clazz, "ctxAsStructUnicode", "(J)J"); - if (jniMethod_ctx_AsStruct_Unicode == NULL) { - LOGS("ERROR: Java method ctxAsStructUnicode not found found !\n"); - return 1; - } - ctx->ctx_AsStruct_Unicode = &ctx_AsStruct_Unicode_jni; - jniMethod_ctx_AsStruct_Tuple = (*env)->GetMethodID(env, clazz, "ctxAsStructTuple", "(J)J"); - if (jniMethod_ctx_AsStruct_Tuple == NULL) { - LOGS("ERROR: Java method ctxAsStructTuple not found found !\n"); - return 1; - } - ctx->ctx_AsStruct_Tuple = &ctx_AsStruct_Tuple_jni; - jniMethod_ctx_AsStruct_List = (*env)->GetMethodID(env, clazz, "ctxAsStructList", "(J)J"); - if (jniMethod_ctx_AsStruct_List == NULL) { - LOGS("ERROR: Java method ctxAsStructList not found found !\n"); - return 1; - } - ctx->ctx_AsStruct_List = &ctx_AsStruct_List_jni; - jniMethod_ctx_Type_GetBuiltinShape = (*env)->GetMethodID(env, clazz, "ctxTypeGetBuiltinShape", "(J)I"); - if (jniMethod_ctx_Type_GetBuiltinShape == NULL) { - LOGS("ERROR: Java method ctxTypeGetBuiltinShape not found found !\n"); - return 1; - } - ctx->ctx_Type_GetBuiltinShape = &ctx_Type_GetBuiltinShape_jni; - jniMethod_ctx_New = (*env)->GetMethodID(env, clazz, "ctxNew", "(JJ)J"); - if (jniMethod_ctx_New == NULL) { - LOGS("ERROR: Java method ctxNew not found found !\n"); - return 1; - } - ctx->ctx_New = &ctx_New_jni; - jniMethod_ctx_Repr = (*env)->GetMethodID(env, clazz, "ctxRepr", "(J)J"); - if (jniMethod_ctx_Repr == NULL) { - LOGS("ERROR: Java method ctxRepr not found found !\n"); - return 1; - } - ctx->ctx_Repr = &ctx_Repr_jni; - jniMethod_ctx_Str = (*env)->GetMethodID(env, clazz, "ctxStr", "(J)J"); - if (jniMethod_ctx_Str == NULL) { - LOGS("ERROR: Java method ctxStr not found found !\n"); - return 1; - } - ctx->ctx_Str = &ctx_Str_jni; - jniMethod_ctx_ASCII = (*env)->GetMethodID(env, clazz, "ctxASCII", "(J)J"); - if (jniMethod_ctx_ASCII == NULL) { - LOGS("ERROR: Java method ctxASCII not found found !\n"); - return 1; - } - ctx->ctx_ASCII = &ctx_ASCII_jni; - jniMethod_ctx_Bytes = (*env)->GetMethodID(env, clazz, "ctxBytes", "(J)J"); - if (jniMethod_ctx_Bytes == NULL) { - LOGS("ERROR: Java method ctxBytes not found found !\n"); - return 1; - } - ctx->ctx_Bytes = &ctx_Bytes_jni; - jniMethod_ctx_RichCompare = (*env)->GetMethodID(env, clazz, "ctxRichCompare", "(JJI)J"); - if (jniMethod_ctx_RichCompare == NULL) { - LOGS("ERROR: Java method ctxRichCompare not found found !\n"); - return 1; - } - ctx->ctx_RichCompare = &ctx_RichCompare_jni; - jniMethod_ctx_RichCompareBool = (*env)->GetMethodID(env, clazz, "ctxRichCompareBool", "(JJI)I"); - if (jniMethod_ctx_RichCompareBool == NULL) { - LOGS("ERROR: Java method ctxRichCompareBool not found found !\n"); - return 1; - } - ctx->ctx_RichCompareBool = &ctx_RichCompareBool_jni; - jniMethod_ctx_Hash = (*env)->GetMethodID(env, clazz, "ctxHash", "(J)J"); - if (jniMethod_ctx_Hash == NULL) { - LOGS("ERROR: Java method ctxHash not found found !\n"); - return 1; - } - ctx->ctx_Hash = &ctx_Hash_jni; - jniMethod_ctx_Bytes_Check = (*env)->GetMethodID(env, clazz, "ctxBytesCheck", "(J)I"); - if (jniMethod_ctx_Bytes_Check == NULL) { - LOGS("ERROR: Java method ctxBytesCheck not found found !\n"); - return 1; - } - ctx->ctx_Bytes_Check = &ctx_Bytes_Check_jni; - jniMethod_ctx_Bytes_Size = (*env)->GetMethodID(env, clazz, "ctxBytesSize", "(J)J"); - if (jniMethod_ctx_Bytes_Size == NULL) { - LOGS("ERROR: Java method ctxBytesSize not found found !\n"); - return 1; - } - ctx->ctx_Bytes_Size = &ctx_Bytes_Size_jni; - jniMethod_ctx_Bytes_GET_SIZE = (*env)->GetMethodID(env, clazz, "ctxBytesGETSIZE", "(J)J"); - if (jniMethod_ctx_Bytes_GET_SIZE == NULL) { - LOGS("ERROR: Java method ctxBytesGETSIZE not found found !\n"); - return 1; - } - ctx->ctx_Bytes_GET_SIZE = &ctx_Bytes_GET_SIZE_jni; - jniMethod_ctx_Bytes_AsString = (*env)->GetMethodID(env, clazz, "ctxBytesAsString", "(J)J"); - if (jniMethod_ctx_Bytes_AsString == NULL) { - LOGS("ERROR: Java method ctxBytesAsString not found found !\n"); - return 1; - } - ctx->ctx_Bytes_AsString = &ctx_Bytes_AsString_jni; - jniMethod_ctx_Bytes_AS_STRING = (*env)->GetMethodID(env, clazz, "ctxBytesASSTRING", "(J)J"); - if (jniMethod_ctx_Bytes_AS_STRING == NULL) { - LOGS("ERROR: Java method ctxBytesASSTRING not found found !\n"); - return 1; - } - ctx->ctx_Bytes_AS_STRING = &ctx_Bytes_AS_STRING_jni; - jniMethod_ctx_Bytes_FromString = (*env)->GetMethodID(env, clazz, "ctxBytesFromString", "(J)J"); - if (jniMethod_ctx_Bytes_FromString == NULL) { - LOGS("ERROR: Java method ctxBytesFromString not found found !\n"); - return 1; - } - ctx->ctx_Bytes_FromString = &ctx_Bytes_FromString_jni; - jniMethod_ctx_Bytes_FromStringAndSize = (*env)->GetMethodID(env, clazz, "ctxBytesFromStringAndSize", "(JJ)J"); - if (jniMethod_ctx_Bytes_FromStringAndSize == NULL) { - LOGS("ERROR: Java method ctxBytesFromStringAndSize not found found !\n"); - return 1; - } - ctx->ctx_Bytes_FromStringAndSize = &ctx_Bytes_FromStringAndSize_jni; - jniMethod_ctx_Unicode_FromString = (*env)->GetMethodID(env, clazz, "ctxUnicodeFromString", "(J)J"); - if (jniMethod_ctx_Unicode_FromString == NULL) { - LOGS("ERROR: Java method ctxUnicodeFromString not found found !\n"); - return 1; - } - ctx->ctx_Unicode_FromString = &ctx_Unicode_FromString_jni; - jniMethod_ctx_Unicode_Check = (*env)->GetMethodID(env, clazz, "ctxUnicodeCheck", "(J)I"); - if (jniMethod_ctx_Unicode_Check == NULL) { - LOGS("ERROR: Java method ctxUnicodeCheck not found found !\n"); - return 1; - } - ctx->ctx_Unicode_Check = &ctx_Unicode_Check_jni; - jniMethod_ctx_Unicode_AsASCIIString = (*env)->GetMethodID(env, clazz, "ctxUnicodeAsASCIIString", "(J)J"); - if (jniMethod_ctx_Unicode_AsASCIIString == NULL) { - LOGS("ERROR: Java method ctxUnicodeAsASCIIString not found found !\n"); - return 1; - } - ctx->ctx_Unicode_AsASCIIString = &ctx_Unicode_AsASCIIString_jni; - jniMethod_ctx_Unicode_AsLatin1String = (*env)->GetMethodID(env, clazz, "ctxUnicodeAsLatin1String", "(J)J"); - if (jniMethod_ctx_Unicode_AsLatin1String == NULL) { - LOGS("ERROR: Java method ctxUnicodeAsLatin1String not found found !\n"); - return 1; - } - ctx->ctx_Unicode_AsLatin1String = &ctx_Unicode_AsLatin1String_jni; - jniMethod_ctx_Unicode_AsUTF8String = (*env)->GetMethodID(env, clazz, "ctxUnicodeAsUTF8String", "(J)J"); - if (jniMethod_ctx_Unicode_AsUTF8String == NULL) { - LOGS("ERROR: Java method ctxUnicodeAsUTF8String not found found !\n"); - return 1; - } - ctx->ctx_Unicode_AsUTF8String = &ctx_Unicode_AsUTF8String_jni; - jniMethod_ctx_Unicode_AsUTF8AndSize = (*env)->GetMethodID(env, clazz, "ctxUnicodeAsUTF8AndSize", "(JJ)J"); - if (jniMethod_ctx_Unicode_AsUTF8AndSize == NULL) { - LOGS("ERROR: Java method ctxUnicodeAsUTF8AndSize not found found !\n"); - return 1; - } - ctx->ctx_Unicode_AsUTF8AndSize = &ctx_Unicode_AsUTF8AndSize_jni; - jniMethod_ctx_Unicode_FromWideChar = (*env)->GetMethodID(env, clazz, "ctxUnicodeFromWideChar", "(JJ)J"); - if (jniMethod_ctx_Unicode_FromWideChar == NULL) { - LOGS("ERROR: Java method ctxUnicodeFromWideChar not found found !\n"); - return 1; - } - ctx->ctx_Unicode_FromWideChar = &ctx_Unicode_FromWideChar_jni; - jniMethod_ctx_Unicode_DecodeFSDefault = (*env)->GetMethodID(env, clazz, "ctxUnicodeDecodeFSDefault", "(J)J"); - if (jniMethod_ctx_Unicode_DecodeFSDefault == NULL) { - LOGS("ERROR: Java method ctxUnicodeDecodeFSDefault not found found !\n"); - return 1; - } - ctx->ctx_Unicode_DecodeFSDefault = &ctx_Unicode_DecodeFSDefault_jni; - jniMethod_ctx_Unicode_DecodeFSDefaultAndSize = (*env)->GetMethodID(env, clazz, "ctxUnicodeDecodeFSDefaultAndSize", "(JJ)J"); - if (jniMethod_ctx_Unicode_DecodeFSDefaultAndSize == NULL) { - LOGS("ERROR: Java method ctxUnicodeDecodeFSDefaultAndSize not found found !\n"); - return 1; - } - ctx->ctx_Unicode_DecodeFSDefaultAndSize = &ctx_Unicode_DecodeFSDefaultAndSize_jni; - jniMethod_ctx_Unicode_EncodeFSDefault = (*env)->GetMethodID(env, clazz, "ctxUnicodeEncodeFSDefault", "(J)J"); - if (jniMethod_ctx_Unicode_EncodeFSDefault == NULL) { - LOGS("ERROR: Java method ctxUnicodeEncodeFSDefault not found found !\n"); - return 1; - } - ctx->ctx_Unicode_EncodeFSDefault = &ctx_Unicode_EncodeFSDefault_jni; - jniMethod_ctx_Unicode_ReadChar = (*env)->GetMethodID(env, clazz, "ctxUnicodeReadChar", "(JJ)I"); - if (jniMethod_ctx_Unicode_ReadChar == NULL) { - LOGS("ERROR: Java method ctxUnicodeReadChar not found found !\n"); - return 1; - } - ctx->ctx_Unicode_ReadChar = &ctx_Unicode_ReadChar_jni; - jniMethod_ctx_Unicode_DecodeASCII = (*env)->GetMethodID(env, clazz, "ctxUnicodeDecodeASCII", "(JJJ)J"); - if (jniMethod_ctx_Unicode_DecodeASCII == NULL) { - LOGS("ERROR: Java method ctxUnicodeDecodeASCII not found found !\n"); - return 1; - } - ctx->ctx_Unicode_DecodeASCII = &ctx_Unicode_DecodeASCII_jni; - jniMethod_ctx_Unicode_DecodeLatin1 = (*env)->GetMethodID(env, clazz, "ctxUnicodeDecodeLatin1", "(JJJ)J"); - if (jniMethod_ctx_Unicode_DecodeLatin1 == NULL) { - LOGS("ERROR: Java method ctxUnicodeDecodeLatin1 not found found !\n"); - return 1; - } - ctx->ctx_Unicode_DecodeLatin1 = &ctx_Unicode_DecodeLatin1_jni; - jniMethod_ctx_Unicode_FromEncodedObject = (*env)->GetMethodID(env, clazz, "ctxUnicodeFromEncodedObject", "(JJJ)J"); - if (jniMethod_ctx_Unicode_FromEncodedObject == NULL) { - LOGS("ERROR: Java method ctxUnicodeFromEncodedObject not found found !\n"); - return 1; - } - ctx->ctx_Unicode_FromEncodedObject = &ctx_Unicode_FromEncodedObject_jni; - jniMethod_ctx_Unicode_Substring = (*env)->GetMethodID(env, clazz, "ctxUnicodeSubstring", "(JJJ)J"); - if (jniMethod_ctx_Unicode_Substring == NULL) { - LOGS("ERROR: Java method ctxUnicodeSubstring not found found !\n"); - return 1; - } - ctx->ctx_Unicode_Substring = &ctx_Unicode_Substring_jni; - jniMethod_ctx_List_Check = (*env)->GetMethodID(env, clazz, "ctxListCheck", "(J)I"); - if (jniMethod_ctx_List_Check == NULL) { - LOGS("ERROR: Java method ctxListCheck not found found !\n"); - return 1; - } - ctx->ctx_List_Check = &ctx_List_Check_jni; - jniMethod_ctx_List_New = (*env)->GetMethodID(env, clazz, "ctxListNew", "(J)J"); - if (jniMethod_ctx_List_New == NULL) { - LOGS("ERROR: Java method ctxListNew not found found !\n"); - return 1; - } - ctx->ctx_List_New = &ctx_List_New_jni; - jniMethod_ctx_List_Append = (*env)->GetMethodID(env, clazz, "ctxListAppend", "(JJ)I"); - if (jniMethod_ctx_List_Append == NULL) { - LOGS("ERROR: Java method ctxListAppend not found found !\n"); - return 1; - } - ctx->ctx_List_Append = &ctx_List_Append_jni; - jniMethod_ctx_Dict_Check = (*env)->GetMethodID(env, clazz, "ctxDictCheck", "(J)I"); - if (jniMethod_ctx_Dict_Check == NULL) { - LOGS("ERROR: Java method ctxDictCheck not found found !\n"); - return 1; - } - ctx->ctx_Dict_Check = &ctx_Dict_Check_jni; - jniMethod_ctx_Dict_New = (*env)->GetMethodID(env, clazz, "ctxDictNew", "()J"); - if (jniMethod_ctx_Dict_New == NULL) { - LOGS("ERROR: Java method ctxDictNew not found found !\n"); - return 1; - } - ctx->ctx_Dict_New = &ctx_Dict_New_jni; - jniMethod_ctx_Dict_Keys = (*env)->GetMethodID(env, clazz, "ctxDictKeys", "(J)J"); - if (jniMethod_ctx_Dict_Keys == NULL) { - LOGS("ERROR: Java method ctxDictKeys not found found !\n"); - return 1; - } - ctx->ctx_Dict_Keys = &ctx_Dict_Keys_jni; - jniMethod_ctx_Dict_Copy = (*env)->GetMethodID(env, clazz, "ctxDictCopy", "(J)J"); - if (jniMethod_ctx_Dict_Copy == NULL) { - LOGS("ERROR: Java method ctxDictCopy not found found !\n"); - return 1; - } - ctx->ctx_Dict_Copy = &ctx_Dict_Copy_jni; - jniMethod_ctx_Tuple_Check = (*env)->GetMethodID(env, clazz, "ctxTupleCheck", "(J)I"); - if (jniMethod_ctx_Tuple_Check == NULL) { - LOGS("ERROR: Java method ctxTupleCheck not found found !\n"); - return 1; - } - ctx->ctx_Tuple_Check = &ctx_Tuple_Check_jni; - jniMethod_ctx_Slice_Unpack = (*env)->GetMethodID(env, clazz, "ctxSliceUnpack", "(JJJJ)I"); - if (jniMethod_ctx_Slice_Unpack == NULL) { - LOGS("ERROR: Java method ctxSliceUnpack not found found !\n"); - return 1; - } - ctx->ctx_Slice_Unpack = &ctx_Slice_Unpack_jni; - jniMethod_ctx_Import_ImportModule = (*env)->GetMethodID(env, clazz, "ctxImportImportModule", "(J)J"); - if (jniMethod_ctx_Import_ImportModule == NULL) { - LOGS("ERROR: Java method ctxImportImportModule not found found !\n"); - return 1; - } - ctx->ctx_Import_ImportModule = &ctx_Import_ImportModule_jni; - jniMethod_ctx_Capsule_New = (*env)->GetMethodID(env, clazz, "ctxCapsuleNew", "(JJJ)J"); - if (jniMethod_ctx_Capsule_New == NULL) { - LOGS("ERROR: Java method ctxCapsuleNew not found found !\n"); - return 1; - } - ctx->ctx_Capsule_New = &ctx_Capsule_New_jni; - jniMethod_ctx_Capsule_Get = (*env)->GetMethodID(env, clazz, "ctxCapsuleGet", "(JIJ)J"); - if (jniMethod_ctx_Capsule_Get == NULL) { - LOGS("ERROR: Java method ctxCapsuleGet not found found !\n"); - return 1; - } - ctx->ctx_Capsule_Get = &ctx_Capsule_Get_jni; - jniMethod_ctx_Capsule_IsValid = (*env)->GetMethodID(env, clazz, "ctxCapsuleIsValid", "(JJ)I"); - if (jniMethod_ctx_Capsule_IsValid == NULL) { - LOGS("ERROR: Java method ctxCapsuleIsValid not found found !\n"); - return 1; - } - ctx->ctx_Capsule_IsValid = &ctx_Capsule_IsValid_jni; - jniMethod_ctx_Capsule_Set = (*env)->GetMethodID(env, clazz, "ctxCapsuleSet", "(JIJ)I"); - if (jniMethod_ctx_Capsule_Set == NULL) { - LOGS("ERROR: Java method ctxCapsuleSet not found found !\n"); - return 1; - } - ctx->ctx_Capsule_Set = &ctx_Capsule_Set_jni; - jniMethod_ctx_FromPyObject = (*env)->GetMethodID(env, clazz, "ctxFromPyObject", "(J)J"); - if (jniMethod_ctx_FromPyObject == NULL) { - LOGS("ERROR: Java method ctxFromPyObject not found found !\n"); - return 1; - } - ctx->ctx_FromPyObject = &ctx_FromPyObject_jni; - jniMethod_ctx_AsPyObject = (*env)->GetMethodID(env, clazz, "ctxAsPyObject", "(J)J"); - if (jniMethod_ctx_AsPyObject == NULL) { - LOGS("ERROR: Java method ctxAsPyObject not found found !\n"); - return 1; - } - ctx->ctx_AsPyObject = &ctx_AsPyObject_jni; - jniMethod_ctx_ListBuilder_New = (*env)->GetMethodID(env, clazz, "ctxListBuilderNew", "(J)J"); - if (jniMethod_ctx_ListBuilder_New == NULL) { - LOGS("ERROR: Java method ctxListBuilderNew not found found !\n"); - return 1; - } - ctx->ctx_ListBuilder_New = &ctx_ListBuilder_New_jni; - jniMethod_ctx_ListBuilder_Set = (*env)->GetMethodID(env, clazz, "ctxListBuilderSet", "(JJJ)V"); - if (jniMethod_ctx_ListBuilder_Set == NULL) { - LOGS("ERROR: Java method ctxListBuilderSet not found found !\n"); - return 1; - } - ctx->ctx_ListBuilder_Set = &ctx_ListBuilder_Set_jni; - jniMethod_ctx_ListBuilder_Build = (*env)->GetMethodID(env, clazz, "ctxListBuilderBuild", "(J)J"); - if (jniMethod_ctx_ListBuilder_Build == NULL) { - LOGS("ERROR: Java method ctxListBuilderBuild not found found !\n"); - return 1; - } - ctx->ctx_ListBuilder_Build = &ctx_ListBuilder_Build_jni; - jniMethod_ctx_ListBuilder_Cancel = (*env)->GetMethodID(env, clazz, "ctxListBuilderCancel", "(J)V"); - if (jniMethod_ctx_ListBuilder_Cancel == NULL) { - LOGS("ERROR: Java method ctxListBuilderCancel not found found !\n"); - return 1; - } - ctx->ctx_ListBuilder_Cancel = &ctx_ListBuilder_Cancel_jni; - jniMethod_ctx_TupleBuilder_New = (*env)->GetMethodID(env, clazz, "ctxTupleBuilderNew", "(J)J"); - if (jniMethod_ctx_TupleBuilder_New == NULL) { - LOGS("ERROR: Java method ctxTupleBuilderNew not found found !\n"); - return 1; - } - ctx->ctx_TupleBuilder_New = &ctx_TupleBuilder_New_jni; - jniMethod_ctx_TupleBuilder_Set = (*env)->GetMethodID(env, clazz, "ctxTupleBuilderSet", "(JJJ)V"); - if (jniMethod_ctx_TupleBuilder_Set == NULL) { - LOGS("ERROR: Java method ctxTupleBuilderSet not found found !\n"); - return 1; - } - ctx->ctx_TupleBuilder_Set = &ctx_TupleBuilder_Set_jni; - jniMethod_ctx_TupleBuilder_Build = (*env)->GetMethodID(env, clazz, "ctxTupleBuilderBuild", "(J)J"); - if (jniMethod_ctx_TupleBuilder_Build == NULL) { - LOGS("ERROR: Java method ctxTupleBuilderBuild not found found !\n"); - return 1; - } - ctx->ctx_TupleBuilder_Build = &ctx_TupleBuilder_Build_jni; - jniMethod_ctx_TupleBuilder_Cancel = (*env)->GetMethodID(env, clazz, "ctxTupleBuilderCancel", "(J)V"); - if (jniMethod_ctx_TupleBuilder_Cancel == NULL) { - LOGS("ERROR: Java method ctxTupleBuilderCancel not found found !\n"); - return 1; - } - ctx->ctx_TupleBuilder_Cancel = &ctx_TupleBuilder_Cancel_jni; - jniMethod_ctx_Field_Load = (*env)->GetMethodID(env, clazz, "ctxFieldLoad", "(JJ)J"); - if (jniMethod_ctx_Field_Load == NULL) { - LOGS("ERROR: Java method ctxFieldLoad not found found !\n"); - return 1; - } - ctx->ctx_Field_Load = &ctx_Field_Load_jni; - jniMethod_ctx_ReenterPythonExecution = (*env)->GetMethodID(env, clazz, "ctxReenterPythonExecution", "(J)V"); - if (jniMethod_ctx_ReenterPythonExecution == NULL) { - LOGS("ERROR: Java method ctxReenterPythonExecution not found found !\n"); - return 1; - } - ctx->ctx_ReenterPythonExecution = &ctx_ReenterPythonExecution_jni; - jniMethod_ctx_LeavePythonExecution = (*env)->GetMethodID(env, clazz, "ctxLeavePythonExecution", "()J"); - if (jniMethod_ctx_LeavePythonExecution == NULL) { - LOGS("ERROR: Java method ctxLeavePythonExecution not found found !\n"); - return 1; - } - ctx->ctx_LeavePythonExecution = &ctx_LeavePythonExecution_jni; - jniMethod_ctx_Global_Load = (*env)->GetMethodID(env, clazz, "ctxGlobalLoad", "(J)J"); - if (jniMethod_ctx_Global_Load == NULL) { - LOGS("ERROR: Java method ctxGlobalLoad not found found !\n"); - return 1; - } - ctx->ctx_Global_Load = &ctx_Global_Load_jni; - jniMethod_ctx_Dump = (*env)->GetMethodID(env, clazz, "ctxDump", "(J)V"); - if (jniMethod_ctx_Dump == NULL) { - LOGS("ERROR: Java method ctxDump not found found !\n"); - return 1; - } - ctx->ctx_Dump = &ctx_Dump_jni; - jniMethod_ctx_Compile_s = (*env)->GetMethodID(env, clazz, "ctxCompiles", "(JJI)J"); - if (jniMethod_ctx_Compile_s == NULL) { - LOGS("ERROR: Java method ctxCompiles not found found !\n"); - return 1; - } - ctx->ctx_Compile_s = &ctx_Compile_s_jni; - jniMethod_ctx_EvalCode = (*env)->GetMethodID(env, clazz, "ctxEvalCode", "(JJJ)J"); - if (jniMethod_ctx_EvalCode == NULL) { - LOGS("ERROR: Java method ctxEvalCode not found found !\n"); - return 1; - } - ctx->ctx_EvalCode = &ctx_EvalCode_jni; - jniMethod_ctx_ContextVar_New = (*env)->GetMethodID(env, clazz, "ctxContextVarNew", "(JJ)J"); - if (jniMethod_ctx_ContextVar_New == NULL) { - LOGS("ERROR: Java method ctxContextVarNew not found found !\n"); - return 1; - } - ctx->ctx_ContextVar_New = &ctx_ContextVar_New_jni; - jniMethod_ctx_ContextVar_Set = (*env)->GetMethodID(env, clazz, "ctxContextVarSet", "(JJ)J"); - if (jniMethod_ctx_ContextVar_Set == NULL) { - LOGS("ERROR: Java method ctxContextVarSet not found found !\n"); - return 1; - } - ctx->ctx_ContextVar_Set = &ctx_ContextVar_Set_jni; - jniMethod_ctx_SetCallFunction = (*env)->GetMethodID(env, clazz, "ctxSetCallFunction", "(JJ)I"); - if (jniMethod_ctx_SetCallFunction == NULL) { - LOGS("ERROR: Java method ctxSetCallFunction not found found !\n"); - return 1; - } - ctx->ctx_SetCallFunction = &ctx_SetCallFunction_jni; - return 0; -} - -static HPy ctx_Dup_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Dup, HPY_UP(h)); -} - -static void ctx_Close_jni(HPyContext *ctx, HPy h) -{ - DO_UPCALL_VOID(CONTEXT_INSTANCE(ctx), ctx_Close, HPY_UP(h)); -} - -static HPy ctx_Long_FromInt32_t_jni(HPyContext *ctx, int32_t value) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Long_FromInt32_t, INT32_UP(value)); -} - -static HPy ctx_Long_FromUInt32_t_jni(HPyContext *ctx, uint32_t value) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Long_FromUInt32_t, UINT32_UP(value)); -} - -static HPy ctx_Long_FromInt64_t_jni(HPyContext *ctx, int64_t v) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Long_FromInt64_t, LONG_UP(v)); -} - -static HPy ctx_Long_FromUInt64_t_jni(HPyContext *ctx, uint64_t v) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Long_FromUInt64_t, LONG_UP(v)); -} - -static HPy ctx_Long_FromSize_t_jni(HPyContext *ctx, size_t value) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Long_FromSize_t, LONG_UP(value)); -} - -static HPy ctx_Long_FromSsize_t_jni(HPyContext *ctx, HPy_ssize_t value) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Long_FromSsize_t, SIZE_T_UP(value)); -} - -static int32_t ctx_Long_AsInt32_t_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_INT32_T(CONTEXT_INSTANCE(ctx), ctx_Long_AsInt32_t, HPY_UP(h)); -} - -static uint32_t ctx_Long_AsUInt32_t_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_UINT32_T(CONTEXT_INSTANCE(ctx), ctx_Long_AsUInt32_t, HPY_UP(h)); -} - -static uint32_t ctx_Long_AsUInt32_tMask_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_UINT32_T(CONTEXT_INSTANCE(ctx), ctx_Long_AsUInt32_tMask, HPY_UP(h)); -} - -static int64_t ctx_Long_AsInt64_t_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_INT64_T(CONTEXT_INSTANCE(ctx), ctx_Long_AsInt64_t, HPY_UP(h)); -} - -static uint64_t ctx_Long_AsUInt64_t_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_UINT64_T(CONTEXT_INSTANCE(ctx), ctx_Long_AsUInt64_t, HPY_UP(h)); -} - -static uint64_t ctx_Long_AsUInt64_tMask_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_UINT64_T(CONTEXT_INSTANCE(ctx), ctx_Long_AsUInt64_tMask, HPY_UP(h)); -} - -static size_t ctx_Long_AsSize_t_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_SIZE_T(CONTEXT_INSTANCE(ctx), ctx_Long_AsSize_t, HPY_UP(h)); -} - -static HPy_ssize_t ctx_Long_AsSsize_t_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_HPY_SSIZE_T(CONTEXT_INSTANCE(ctx), ctx_Long_AsSsize_t, HPY_UP(h)); -} - -static void *ctx_Long_AsVoidPtr_jni(HPyContext *ctx, HPy h) -{ - return (void *)DO_UPCALL_PTR(CONTEXT_INSTANCE(ctx), ctx_Long_AsVoidPtr, HPY_UP(h)); -} - -static double ctx_Long_AsDouble_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_DOUBLE(CONTEXT_INSTANCE(ctx), ctx_Long_AsDouble, HPY_UP(h)); -} - -static HPy ctx_Float_FromDouble_jni(HPyContext *ctx, double v) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Float_FromDouble, DOUBLE_UP(v)); -} - -static double ctx_Float_AsDouble_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_DOUBLE(CONTEXT_INSTANCE(ctx), ctx_Float_AsDouble, HPY_UP(h)); -} - -static HPy ctx_Bool_FromBool_jni(HPyContext *ctx, bool v) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Bool_FromBool, LONG_UP(v)); -} - -static HPy_ssize_t ctx_Length_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_HPY_SSIZE_T(CONTEXT_INSTANCE(ctx), ctx_Length, HPY_UP(h)); -} - -static int ctx_Number_Check_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_Number_Check, HPY_UP(h)); -} - -static HPy ctx_Add_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Add, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_Subtract_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Subtract, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_Multiply_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Multiply, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_MatrixMultiply_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_MatrixMultiply, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_FloorDivide_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_FloorDivide, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_TrueDivide_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_TrueDivide, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_Remainder_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Remainder, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_Divmod_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Divmod, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_Power_jni(HPyContext *ctx, HPy h1, HPy h2, HPy h3) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Power, HPY_UP(h1), HPY_UP(h2), HPY_UP(h3)); -} - -static HPy ctx_Negative_jni(HPyContext *ctx, HPy h1) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Negative, HPY_UP(h1)); -} - -static HPy ctx_Positive_jni(HPyContext *ctx, HPy h1) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Positive, HPY_UP(h1)); -} - -static HPy ctx_Absolute_jni(HPyContext *ctx, HPy h1) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Absolute, HPY_UP(h1)); -} - -static HPy ctx_Invert_jni(HPyContext *ctx, HPy h1) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Invert, HPY_UP(h1)); -} - -static HPy ctx_Lshift_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Lshift, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_Rshift_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Rshift, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_And_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_And, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_Xor_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Xor, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_Or_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Or, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_Index_jni(HPyContext *ctx, HPy h1) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Index, HPY_UP(h1)); -} - -static HPy ctx_Long_jni(HPyContext *ctx, HPy h1) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Long, HPY_UP(h1)); -} - -static HPy ctx_Float_jni(HPyContext *ctx, HPy h1) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Float, HPY_UP(h1)); -} - -static HPy ctx_InPlaceAdd_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_InPlaceAdd, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_InPlaceSubtract_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_InPlaceSubtract, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_InPlaceMultiply_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_InPlaceMultiply, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_InPlaceMatrixMultiply_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_InPlaceMatrixMultiply, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_InPlaceFloorDivide_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_InPlaceFloorDivide, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_InPlaceTrueDivide_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_InPlaceTrueDivide, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_InPlaceRemainder_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_InPlaceRemainder, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_InPlacePower_jni(HPyContext *ctx, HPy h1, HPy h2, HPy h3) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_InPlacePower, HPY_UP(h1), HPY_UP(h2), HPY_UP(h3)); -} - -static HPy ctx_InPlaceLshift_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_InPlaceLshift, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_InPlaceRshift_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_InPlaceRshift, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_InPlaceAnd_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_InPlaceAnd, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_InPlaceXor_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_InPlaceXor, HPY_UP(h1), HPY_UP(h2)); -} - -static HPy ctx_InPlaceOr_jni(HPyContext *ctx, HPy h1, HPy h2) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_InPlaceOr, HPY_UP(h1), HPY_UP(h2)); -} - -static int ctx_Callable_Check_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_Callable_Check, HPY_UP(h)); -} - -static HPy ctx_CallTupleDict_jni(HPyContext *ctx, HPy callable, HPy args, HPy kw) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_CallTupleDict, HPY_UP(callable), HPY_UP(args), HPY_UP(kw)); -} - -static HPy ctx_Call_jni(HPyContext *ctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Call, HPY_UP(callable), PTR_UP(args), LONG_UP(nargs), HPY_UP(kwnames)); -} - -static HPy ctx_CallMethod_jni(HPyContext *ctx, HPy name, const HPy *args, size_t nargs, HPy kwnames) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_CallMethod, HPY_UP(name), PTR_UP(args), LONG_UP(nargs), HPY_UP(kwnames)); -} - -static void ctx_FatalError_jni(HPyContext *ctx, const char *message) -{ - DO_UPCALL_VOID(CONTEXT_INSTANCE(ctx), ctx_FatalError, PTR_UP(message)); -} - -static void ctx_Err_SetString_jni(HPyContext *ctx, HPy h_type, const char *utf8_message) -{ - DO_UPCALL_VOID(CONTEXT_INSTANCE(ctx), ctx_Err_SetString, HPY_UP(h_type), PTR_UP(utf8_message)); -} - -static void ctx_Err_SetObject_jni(HPyContext *ctx, HPy h_type, HPy h_value) -{ - DO_UPCALL_VOID(CONTEXT_INSTANCE(ctx), ctx_Err_SetObject, HPY_UP(h_type), HPY_UP(h_value)); -} - -static HPy ctx_Err_SetFromErrnoWithFilename_jni(HPyContext *ctx, HPy h_type, const char *filename_fsencoded) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Err_SetFromErrnoWithFilename, HPY_UP(h_type), PTR_UP(filename_fsencoded)); -} - -static void ctx_Err_SetFromErrnoWithFilenameObjects_jni(HPyContext *ctx, HPy h_type, HPy filename1, HPy filename2) -{ - DO_UPCALL_VOID(CONTEXT_INSTANCE(ctx), ctx_Err_SetFromErrnoWithFilenameObjects, HPY_UP(h_type), HPY_UP(filename1), HPY_UP(filename2)); -} - -static int ctx_Err_Occurred_jni(HPyContext *ctx) -{ - return DO_UPCALL_INT0(CONTEXT_INSTANCE(ctx), ctx_Err_Occurred); -} - -static int ctx_Err_ExceptionMatches_jni(HPyContext *ctx, HPy exc) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_Err_ExceptionMatches, HPY_UP(exc)); -} - -static void ctx_Err_NoMemory_jni(HPyContext *ctx) -{ - DO_UPCALL_VOID0(CONTEXT_INSTANCE(ctx), ctx_Err_NoMemory); -} - -static void ctx_Err_Clear_jni(HPyContext *ctx) -{ - DO_UPCALL_VOID0(CONTEXT_INSTANCE(ctx), ctx_Err_Clear); -} - -static HPy ctx_Err_NewException_jni(HPyContext *ctx, const char *utf8_name, HPy base, HPy dict) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Err_NewException, PTR_UP(utf8_name), HPY_UP(base), HPY_UP(dict)); -} - -static HPy ctx_Err_NewExceptionWithDoc_jni(HPyContext *ctx, const char *utf8_name, const char *utf8_doc, HPy base, HPy dict) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Err_NewExceptionWithDoc, PTR_UP(utf8_name), PTR_UP(utf8_doc), HPY_UP(base), HPY_UP(dict)); -} - -static int ctx_Err_WarnEx_jni(HPyContext *ctx, HPy category, const char *utf8_message, HPy_ssize_t stack_level) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_Err_WarnEx, HPY_UP(category), PTR_UP(utf8_message), SIZE_T_UP(stack_level)); -} - -static void ctx_Err_WriteUnraisable_jni(HPyContext *ctx, HPy obj) -{ - DO_UPCALL_VOID(CONTEXT_INSTANCE(ctx), ctx_Err_WriteUnraisable, HPY_UP(obj)); -} - -static int ctx_IsTrue_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_IsTrue, HPY_UP(h)); -} - -static HPy ctx_Type_FromSpec_jni(HPyContext *ctx, HPyType_Spec *spec, HPyType_SpecParam *params) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Type_FromSpec, PTR_UP(spec), PTR_UP(params)); -} - -static HPy ctx_Type_GenericNew_jni(HPyContext *ctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Type_GenericNew, HPY_UP(type), PTR_UP(args), SIZE_T_UP(nargs), HPY_UP(kw)); -} - -static HPy ctx_GetAttr_jni(HPyContext *ctx, HPy obj, HPy name) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_GetAttr, HPY_UP(obj), HPY_UP(name)); -} - -static int ctx_HasAttr_jni(HPyContext *ctx, HPy obj, HPy name) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_HasAttr, HPY_UP(obj), HPY_UP(name)); -} - -static int ctx_HasAttr_s_jni(HPyContext *ctx, HPy obj, const char *utf8_name) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_HasAttr_s, HPY_UP(obj), PTR_UP(utf8_name)); -} - -static int ctx_SetAttr_jni(HPyContext *ctx, HPy obj, HPy name, HPy value) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_SetAttr, HPY_UP(obj), HPY_UP(name), HPY_UP(value)); -} - -static int ctx_SetAttr_s_jni(HPyContext *ctx, HPy obj, const char *utf8_name, HPy value) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_SetAttr_s, HPY_UP(obj), PTR_UP(utf8_name), HPY_UP(value)); -} - -static HPy ctx_GetItem_jni(HPyContext *ctx, HPy obj, HPy key) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_GetItem, HPY_UP(obj), HPY_UP(key)); -} - -static HPy ctx_GetItem_i_jni(HPyContext *ctx, HPy obj, HPy_ssize_t idx) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_GetItem_i, HPY_UP(obj), SIZE_T_UP(idx)); -} - -static int ctx_Contains_jni(HPyContext *ctx, HPy container, HPy key) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_Contains, HPY_UP(container), HPY_UP(key)); -} - -static int ctx_SetItem_jni(HPyContext *ctx, HPy obj, HPy key, HPy value) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_SetItem, HPY_UP(obj), HPY_UP(key), HPY_UP(value)); -} - -static int ctx_SetItem_i_jni(HPyContext *ctx, HPy obj, HPy_ssize_t idx, HPy value) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_SetItem_i, HPY_UP(obj), SIZE_T_UP(idx), HPY_UP(value)); -} - -static int ctx_DelItem_jni(HPyContext *ctx, HPy obj, HPy key) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_DelItem, HPY_UP(obj), HPY_UP(key)); -} - -static int ctx_DelItem_i_jni(HPyContext *ctx, HPy obj, HPy_ssize_t idx) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_DelItem_i, HPY_UP(obj), SIZE_T_UP(idx)); -} - -static int ctx_DelItem_s_jni(HPyContext *ctx, HPy obj, const char *utf8_key) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_DelItem_s, HPY_UP(obj), PTR_UP(utf8_key)); -} - -static HPy ctx_Type_jni(HPyContext *ctx, HPy obj) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Type, HPY_UP(obj)); -} - -static int ctx_TypeCheck_jni(HPyContext *ctx, HPy obj, HPy type) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_TypeCheck, HPY_UP(obj), HPY_UP(type)); -} - -static const char *ctx_Type_GetName_jni(HPyContext *ctx, HPy type) -{ - return (const char *)DO_UPCALL_PTR(CONTEXT_INSTANCE(ctx), ctx_Type_GetName, HPY_UP(type)); -} - -static int ctx_Type_IsSubtype_jni(HPyContext *ctx, HPy sub, HPy type) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_Type_IsSubtype, HPY_UP(sub), HPY_UP(type)); -} - -static int ctx_Is_jni(HPyContext *ctx, HPy obj, HPy other) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_Is, HPY_UP(obj), HPY_UP(other)); -} - -static void *ctx_AsStruct_Object_jni(HPyContext *ctx, HPy h) -{ - return (void *)DO_UPCALL_PTR(CONTEXT_INSTANCE(ctx), ctx_AsStruct_Object, HPY_UP(h)); -} - -static void *ctx_AsStruct_Legacy_jni(HPyContext *ctx, HPy h) -{ - return (void *)DO_UPCALL_PTR(CONTEXT_INSTANCE(ctx), ctx_AsStruct_Legacy, HPY_UP(h)); -} - -static void *ctx_AsStruct_Type_jni(HPyContext *ctx, HPy h) -{ - return (void *)DO_UPCALL_PTR(CONTEXT_INSTANCE(ctx), ctx_AsStruct_Type, HPY_UP(h)); -} - -static void *ctx_AsStruct_Long_jni(HPyContext *ctx, HPy h) -{ - return (void *)DO_UPCALL_PTR(CONTEXT_INSTANCE(ctx), ctx_AsStruct_Long, HPY_UP(h)); -} - -static void *ctx_AsStruct_Float_jni(HPyContext *ctx, HPy h) -{ - return (void *)DO_UPCALL_PTR(CONTEXT_INSTANCE(ctx), ctx_AsStruct_Float, HPY_UP(h)); -} - -static void *ctx_AsStruct_Unicode_jni(HPyContext *ctx, HPy h) -{ - return (void *)DO_UPCALL_PTR(CONTEXT_INSTANCE(ctx), ctx_AsStruct_Unicode, HPY_UP(h)); -} - -static void *ctx_AsStruct_Tuple_jni(HPyContext *ctx, HPy h) -{ - return (void *)DO_UPCALL_PTR(CONTEXT_INSTANCE(ctx), ctx_AsStruct_Tuple, HPY_UP(h)); -} - -static void *ctx_AsStruct_List_jni(HPyContext *ctx, HPy h) -{ - return (void *)DO_UPCALL_PTR(CONTEXT_INSTANCE(ctx), ctx_AsStruct_List, HPY_UP(h)); -} - -static HPyType_BuiltinShape ctx_Type_GetBuiltinShape_jni(HPyContext *ctx, HPy h_type) -{ - return DO_UPCALL_HPYTYPE_BUILTINSHAPE(CONTEXT_INSTANCE(ctx), ctx_Type_GetBuiltinShape, HPY_UP(h_type)); -} - -static HPy ctx_New_jni(HPyContext *ctx, HPy h_type, void **data) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_New, HPY_UP(h_type), PTR_UP(data)); -} - -static HPy ctx_Repr_jni(HPyContext *ctx, HPy obj) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Repr, HPY_UP(obj)); -} - -static HPy ctx_Str_jni(HPyContext *ctx, HPy obj) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Str, HPY_UP(obj)); -} - -static HPy ctx_ASCII_jni(HPyContext *ctx, HPy obj) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_ASCII, HPY_UP(obj)); -} - -static HPy ctx_Bytes_jni(HPyContext *ctx, HPy obj) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Bytes, HPY_UP(obj)); -} - -static HPy ctx_RichCompare_jni(HPyContext *ctx, HPy v, HPy w, int op) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_RichCompare, HPY_UP(v), HPY_UP(w), INT_UP(op)); -} - -static int ctx_RichCompareBool_jni(HPyContext *ctx, HPy v, HPy w, int op) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_RichCompareBool, HPY_UP(v), HPY_UP(w), INT_UP(op)); -} - -static HPy_hash_t ctx_Hash_jni(HPyContext *ctx, HPy obj) -{ - return DO_UPCALL_HPY_HASH_T(CONTEXT_INSTANCE(ctx), ctx_Hash, HPY_UP(obj)); -} - -static int ctx_Bytes_Check_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_Bytes_Check, HPY_UP(h)); -} - -static HPy_ssize_t ctx_Bytes_Size_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_HPY_SSIZE_T(CONTEXT_INSTANCE(ctx), ctx_Bytes_Size, HPY_UP(h)); -} - -static HPy_ssize_t ctx_Bytes_GET_SIZE_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_HPY_SSIZE_T(CONTEXT_INSTANCE(ctx), ctx_Bytes_GET_SIZE, HPY_UP(h)); -} - -static const char *ctx_Bytes_AsString_jni(HPyContext *ctx, HPy h) -{ - return (const char *)DO_UPCALL_PTR(CONTEXT_INSTANCE(ctx), ctx_Bytes_AsString, HPY_UP(h)); -} - -static const char *ctx_Bytes_AS_STRING_jni(HPyContext *ctx, HPy h) -{ - return (const char *)DO_UPCALL_PTR(CONTEXT_INSTANCE(ctx), ctx_Bytes_AS_STRING, HPY_UP(h)); -} - -static HPy ctx_Bytes_FromString_jni(HPyContext *ctx, const char *bytes) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Bytes_FromString, PTR_UP(bytes)); -} - -static HPy ctx_Bytes_FromStringAndSize_jni(HPyContext *ctx, const char *bytes, HPy_ssize_t len) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Bytes_FromStringAndSize, PTR_UP(bytes), SIZE_T_UP(len)); -} - -static HPy ctx_Unicode_FromString_jni(HPyContext *ctx, const char *utf8) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Unicode_FromString, PTR_UP(utf8)); -} - -static int ctx_Unicode_Check_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_Unicode_Check, HPY_UP(h)); -} - -static HPy ctx_Unicode_AsASCIIString_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Unicode_AsASCIIString, HPY_UP(h)); -} - -static HPy ctx_Unicode_AsLatin1String_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Unicode_AsLatin1String, HPY_UP(h)); -} - -static HPy ctx_Unicode_AsUTF8String_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Unicode_AsUTF8String, HPY_UP(h)); -} - -static const char *ctx_Unicode_AsUTF8AndSize_jni(HPyContext *ctx, HPy h, HPy_ssize_t *size) -{ - return (const char *)DO_UPCALL_PTR(CONTEXT_INSTANCE(ctx), ctx_Unicode_AsUTF8AndSize, HPY_UP(h), PTR_UP(size)); -} - -static HPy ctx_Unicode_DecodeFSDefault_jni(HPyContext *ctx, const char *v) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Unicode_DecodeFSDefault, PTR_UP(v)); -} - -static HPy ctx_Unicode_DecodeFSDefaultAndSize_jni(HPyContext *ctx, const char *v, HPy_ssize_t size) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Unicode_DecodeFSDefaultAndSize, PTR_UP(v), SIZE_T_UP(size)); -} - -static HPy ctx_Unicode_EncodeFSDefault_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Unicode_EncodeFSDefault, HPY_UP(h)); -} - -static HPy_UCS4 ctx_Unicode_ReadChar_jni(HPyContext *ctx, HPy h, HPy_ssize_t index) -{ - return DO_UPCALL_HPY_UCS4(CONTEXT_INSTANCE(ctx), ctx_Unicode_ReadChar, HPY_UP(h), SIZE_T_UP(index)); -} - -static HPy ctx_Unicode_DecodeASCII_jni(HPyContext *ctx, const char *ascii, HPy_ssize_t size, const char *errors) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Unicode_DecodeASCII, PTR_UP(ascii), SIZE_T_UP(size), PTR_UP(errors)); -} - -static HPy ctx_Unicode_DecodeLatin1_jni(HPyContext *ctx, const char *latin1, HPy_ssize_t size, const char *errors) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Unicode_DecodeLatin1, PTR_UP(latin1), SIZE_T_UP(size), PTR_UP(errors)); -} - -static HPy ctx_Unicode_FromEncodedObject_jni(HPyContext *ctx, HPy obj, const char *encoding, const char *errors) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Unicode_FromEncodedObject, HPY_UP(obj), PTR_UP(encoding), PTR_UP(errors)); -} - -static HPy ctx_Unicode_Substring_jni(HPyContext *ctx, HPy str, HPy_ssize_t start, HPy_ssize_t end) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Unicode_Substring, HPY_UP(str), SIZE_T_UP(start), SIZE_T_UP(end)); -} - -static int ctx_List_Check_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_List_Check, HPY_UP(h)); -} - -static HPy ctx_List_New_jni(HPyContext *ctx, HPy_ssize_t len) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_List_New, SIZE_T_UP(len)); -} - -static int ctx_List_Append_jni(HPyContext *ctx, HPy h_list, HPy h_item) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_List_Append, HPY_UP(h_list), HPY_UP(h_item)); -} - -static int ctx_Dict_Check_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_Dict_Check, HPY_UP(h)); -} - -static HPy ctx_Dict_New_jni(HPyContext *ctx) -{ - return DO_UPCALL_HPY0(CONTEXT_INSTANCE(ctx), ctx_Dict_New); -} - -static HPy ctx_Dict_Keys_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Dict_Keys, HPY_UP(h)); -} - -static HPy ctx_Dict_Copy_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Dict_Copy, HPY_UP(h)); -} - -static int ctx_Tuple_Check_jni(HPyContext *ctx, HPy h) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_Tuple_Check, HPY_UP(h)); -} - -static int ctx_Slice_Unpack_jni(HPyContext *ctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_Slice_Unpack, HPY_UP(slice), PTR_UP(start), PTR_UP(stop), PTR_UP(step)); -} - -static HPy ctx_Import_ImportModule_jni(HPyContext *ctx, const char *utf8_name) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Import_ImportModule, PTR_UP(utf8_name)); -} - -static HPy ctx_Capsule_New_jni(HPyContext *ctx, void *pointer, const char *utf8_name, HPyCapsule_Destructor *destructor) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Capsule_New, PTR_UP(pointer), PTR_UP(utf8_name), PTR_UP(destructor)); -} - -static void *ctx_Capsule_Get_jni(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, const char *utf8_name) -{ - return (void *)DO_UPCALL_PTR(CONTEXT_INSTANCE(ctx), ctx_Capsule_Get, HPY_UP(capsule), INT_UP(key), PTR_UP(utf8_name)); -} - -static int ctx_Capsule_IsValid_jni(HPyContext *ctx, HPy capsule, const char *utf8_name) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_Capsule_IsValid, HPY_UP(capsule), PTR_UP(utf8_name)); -} - -static int ctx_Capsule_Set_jni(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, void *value) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_Capsule_Set, HPY_UP(capsule), INT_UP(key), PTR_UP(value)); -} - -static HPy ctx_FromPyObject_jni(HPyContext *ctx, cpy_PyObject *obj) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_FromPyObject, PTR_UP(obj)); -} - -static cpy_PyObject *ctx_AsPyObject_jni(HPyContext *ctx, HPy h) -{ - return (cpy_PyObject *)DO_UPCALL_PTR(CONTEXT_INSTANCE(ctx), ctx_AsPyObject, HPY_UP(h)); -} - -static HPy ctx_Field_Load_jni(HPyContext *ctx, HPy source_object, HPyField source_field) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Field_Load, HPY_UP(source_object), HPY_FIELD_UP(source_field)); -} - -static void ctx_ReenterPythonExecution_jni(HPyContext *ctx, HPyThreadState state) -{ - DO_UPCALL_VOID(CONTEXT_INSTANCE(ctx), ctx_ReenterPythonExecution, HPY_THREAD_STATE_UP(state)); -} - -static HPyThreadState ctx_LeavePythonExecution_jni(HPyContext *ctx) -{ - return DO_UPCALL_HPYTHREADSTATE0(CONTEXT_INSTANCE(ctx), ctx_LeavePythonExecution); -} - -static void ctx_Dump_jni(HPyContext *ctx, HPy h) -{ - DO_UPCALL_VOID(CONTEXT_INSTANCE(ctx), ctx_Dump, HPY_UP(h)); -} - -static HPy ctx_Compile_s_jni(HPyContext *ctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Compile_s, PTR_UP(utf8_source), PTR_UP(utf8_filename), INT_UP(kind)); -} - -static HPy ctx_EvalCode_jni(HPyContext *ctx, HPy code, HPy globals, HPy locals) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_EvalCode, HPY_UP(code), HPY_UP(globals), HPY_UP(locals)); -} - -static HPy ctx_ContextVar_New_jni(HPyContext *ctx, const char *name, HPy default_value) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_ContextVar_New, PTR_UP(name), HPY_UP(default_value)); -} - -static HPy ctx_ContextVar_Set_jni(HPyContext *ctx, HPy context_var, HPy value) -{ - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_ContextVar_Set, HPY_UP(context_var), HPY_UP(value)); -} - -static int ctx_SetCallFunction_jni(HPyContext *ctx, HPy h, HPyCallFunction *func) -{ - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctx_SetCallFunction, HPY_UP(h), PTR_UP(func)); -} - diff --git a/graalpython/com.oracle.graal.python.jni/src/ctx_builder.c b/graalpython/com.oracle.graal.python.jni/src/ctx_builder.c deleted file mode 100644 index 0cdc74a7b7..0000000000 --- a/graalpython/com.oracle.graal.python.jni/src/ctx_builder.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* - * Native implementation of HPyTupleBuilder. - * This is written in a way that we could also use the internal functions - * 'builder_*' to implement HPyListBuilder. - */ - - -#include "hpy_jni.h" - -typedef struct { - HPy_ssize_t capacity; // allocated handles - HPy handles[0]; -} _HPyBuilder_s; - -static inline _HPyBuilder_s *_ht2hb(HPyTupleBuilder ht) { - return (_HPyBuilder_s *) (ht)._tup; -} - -static inline HPyTupleBuilder _hb2ht(_HPyBuilder_s *hp) { - return (HPyTupleBuilder) {(intptr_t) (hp)}; -} - -static inline _HPyBuilder_s *_hl2hb(HPyListBuilder ht) { - return (_HPyBuilder_s *) (ht)._lst; -} - -static inline HPyListBuilder _hb2hl(_HPyBuilder_s *hp) { - return (HPyListBuilder) {(intptr_t) (hp)}; -} - -static inline _HPyBuilder_s *builder_new(HPy_ssize_t size) { - _HPyBuilder_s *hb = calloc(1, sizeof(_HPyBuilder_s) + size * sizeof(HPy)); - if (hb == NULL) { - /* delay the MemoryError */ - /* note: it's done this way so that the caller doesn't need to - check if HPyTupleBuilder_New() or every HPyTupleBuilder_Set() - raised. If there is a rare error like a MemoryError somewhere, - further calls to the HPyTupleBuilder are ignored. The final - HPyTupleBuilder_Build() will re-raise the MemoryError and so - it's enough for the caller to check at that point. */ - } else { - hb->capacity = size; - } - return hb; -} -static inline void builder_set(HPyContext *ctx, _HPyBuilder_s *hb, HPy_ssize_t index, HPy h_item) -{ - if (hb != NULL) { - assert(index >= 0 && index < hb->capacity); - assert(HPy_IsNull(hb->handles[index])); - hb->handles[index] = HPy_Dup(ctx, h_item); - } -} - -static inline void builder_cancel(HPyContext *ctx, _HPyBuilder_s *hb) -{ - if (hb == NULL) { - // we don't report the memory error here: the builder - // is being cancelled (so the result of the builder is not being used) - // and likely it's being cancelled during the handling of another error - return; - } - for (HPy_ssize_t i = 0; i < hb->capacity; i++) { - HPy_Close(ctx, hb->handles[i]); - } - free(hb); -} - -_HPy_HIDDEN HPyTupleBuilder -ctx_TupleBuilder_New_jni(HPyContext *ctx, HPy_ssize_t size) -{ - return _hb2ht(builder_new(size)); -} - -_HPy_HIDDEN void -ctx_TupleBuilder_Set_jni(HPyContext *ctx, HPyTupleBuilder builder, - HPy_ssize_t index, HPy h_item) -{ - builder_set(ctx, _ht2hb(builder), index, h_item); -} - -_HPy_HIDDEN HPy -ctx_TupleBuilder_Build_jni(HPyContext *ctx, HPyTupleBuilder builder) -{ - _HPyBuilder_s *hb = _ht2hb(builder); - if (hb == NULL) { - HPyErr_NoMemory(ctx); - return HPy_NULL; - } - HPy res = upcallSequenceFromArray(ctx, hb->handles, hb->capacity, JNI_TRUE, JNI_FALSE); - free(hb); - return res; -} - -_HPy_HIDDEN void -ctx_TupleBuilder_Cancel_jni(HPyContext *ctx, HPyTupleBuilder builder) -{ - builder_cancel(ctx, _ht2hb(builder)); -} - -_HPy_HIDDEN HPyListBuilder -ctx_ListBuilder_New_jni(HPyContext *ctx, HPy_ssize_t size) -{ - return _hb2hl(builder_new(size)); -} - -_HPy_HIDDEN void -ctx_ListBuilder_Set_jni(HPyContext *ctx, HPyListBuilder builder, - HPy_ssize_t index, HPy h_item) -{ - builder_set(ctx, _hl2hb(builder), index, h_item); -} - -_HPy_HIDDEN HPy -ctx_ListBuilder_Build_jni(HPyContext *ctx, HPyListBuilder builder) -{ - _HPyBuilder_s *hb = _hl2hb(builder); - if (hb == NULL) { - HPyErr_NoMemory(ctx); - return HPy_NULL; - } - HPy res = upcallSequenceFromArray(ctx, hb->handles, hb->capacity, JNI_TRUE, JNI_TRUE); - free(hb); - return res; -} - -_HPy_HIDDEN void -ctx_ListBuilder_Cancel_jni(HPyContext *ctx, HPyListBuilder builder) -{ - builder_cancel(ctx, _hl2hb(builder)); -} diff --git a/graalpython/com.oracle.graal.python.jni/src/ctx_call_jni.c b/graalpython/com.oracle.graal.python.jni/src/ctx_call_jni.c deleted file mode 100644 index 9c07c5aa12..0000000000 --- a/graalpython/com.oracle.graal.python.jni/src/ctx_call_jni.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "hpy_jni.h" -#include "com_oracle_graal_python_builtins_objects_cext_hpy_jni_GraalHPyJNITrampolines.h" - -#define TRAMPOLINE(name) Java_com_oracle_graal_python_builtins_objects_cext_hpy_jni_GraalHPyJNITrampolines_ ## name - - -/******************************************************************* - * MANUAL TRAMPOLINES * - *******************************************************************/ - -JNIEXPORT jlong JNICALL TRAMPOLINE(executeDebugKeywords)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong self, jlong args, jlong nargs, jlong kwnames) -{ - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_keywords f = (HPyFunc_keywords)target; - DHPy dh_self = _jlong2dh(dctx, self); - UHPy uh_kwnames = _jlong2h(kwnames); - DHPy dh_kwnames; - HPy_ssize_t n_kwnames; - if (!HPy_IsNull(uh_kwnames)) - { - n_kwnames = HPy_Length(get_info(dctx)->uctx, uh_kwnames); - dh_kwnames = DHPy_open(dctx, uh_kwnames); - } - else - { - n_kwnames = 0; - dh_kwnames = HPy_NULL; - } - assert(nargs >= 0); - assert(n_kwnames >= 0); - jlong nargs_with_kw = nargs + n_kwnames; - _ARR_JLONG2DH(dctx, dh_args, args, nargs_with_kw) - DHPy dh_result = f(dctx, dh_self, dh_args, (size_t)nargs, dh_kwnames); - _ARR_DH_CLOSE(dctx, dh_args, nargs_with_kw) - DHPy_close_and_check(dctx, dh_self); - DHPy_close_and_check(dctx, dh_kwnames); - return from_dh(dctx, dh_result); -} - -JNIEXPORT jint JNICALL TRAMPOLINE(executeDebugGetbufferproc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg1, jlong arg2, jint arg3) { - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_getbufferproc f = (HPyFunc_getbufferproc) target; - DHPy_buffer dbuffer; - DHPy dh_arg1 = _jlong2dh(dctx, arg1); - jint result = f(dctx, dh_arg1, &dbuffer, (int) arg3); - DHPy_close_and_check(dctx, dh_arg1); - _buffer_d2u(dctx, &dbuffer, (UHPy_buffer *) arg2); - DHPy_close(dctx, dbuffer.obj); - return result; -} - -JNIEXPORT void JNICALL TRAMPOLINE(executeDebugReleasebufferproc)(JNIEnv *env, jclass clazz, jlong target, jlong ctx, jlong arg1, jlong arg2) { - HPyContext *dctx = (HPyContext *) ctx; - HPyFunc_releasebufferproc f = (HPyFunc_releasebufferproc) target; - DHPy_buffer dbuf; - _buffer_u2d(dctx, (UHPy_buffer *) arg2, &dbuf); - DHPy dh_arg1 = _jlong2dh(dctx, arg1); - f(dctx, dh_arg1, &dbuf); - DHPy_close_and_check(dctx, dh_arg1); - // TODO(fa): should we use DHPy_close_and_check ? - DHPy_close(dctx, dbuf.obj); -} - -JNIEXPORT void JNICALL TRAMPOLINE(executeDestroyfunc)(JNIEnv *env, jclass clazz, jlong target, jlong dataptr) -{ - HPyFunc_destroyfunc f = (HPyFunc_destroyfunc)target; - f((void *)dataptr); -} - -#undef TRAMPOLINE diff --git a/graalpython/com.oracle.graal.python.jni/src/ctx_tracker.c b/graalpython/com.oracle.graal.python.jni/src/ctx_tracker.c deleted file mode 100644 index 047bcd3643..0000000000 --- a/graalpython/com.oracle.graal.python.jni/src/ctx_tracker.c +++ /dev/null @@ -1,171 +0,0 @@ -/* MIT License - * - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * A manager for HPy handles, allowing handles to be tracked - * and closed as a group. - * - * Note:: - * Calling HPyTracker_New(ctx, n) will ensure that at least n handles - * can be tracked without a call to HPyTracker_Add failing. - * - * If a call to HPyTracker_Add fails, the tracker still guarantees that - * the handle passed to it has been tracked (internally it does this by - * maintaining space for one more handle). - * - * After HPyTracker_Add fails, HPyTracker_Close should be called without - * any further calls to HPyTracker_Add. Calling HPyTracker_Close will close - * all the tracked handles, including the handled passed to the failed call - * to HPyTracker_Add. - * - * Example usage (inside an HPyDef_METH function):: - * - * long i; - * HPy key, value; - * HPyTracker ht; - * - * ht = HPyTracker_New(ctx, 0); // track the key-value pairs - * if (HPy_IsNull(ht)) - * return HPy_NULL; - * - * HPy dict = HPyDict_New(ctx); - * if (HPy_IsNull(dict)) - * goto error; - * - * for (i=0; i<5; i++) { - * key = HPyLong_FromLong(ctx, i); - * if (HPy_IsNull(key)) - * goto error; - * if (HPyTracker_Add(ctx, ht, key) < 0) - * goto error; - * value = HPyLong_FromLong(ctx, i * i); - * if (HPy_IsNull(value)) { - * goto error; - * } - * if (HPyTracker_Add(ctx, ht, value) < 0) - * goto error; - * result = HPy_SetItem(ctx, dict, key, value); - * if (result < 0) - * goto error; - * } - * - * success: - * HPyTracker_Close(ctx, ht); - * return dict; - * - * error: - * HPyTracker_Close(ctx, ht); - * HPy_Close(ctx, dict); - * // HPyErr will already have been set by the error that occurred. - * return HPy_NULL; - */ - -#include "hpy_jni.h" - -static const HPy_ssize_t HPYTRACKER_INITIAL_CAPACITY = 5; - -_HPy_HIDDEN HPyTracker -ctx_Tracker_New_jni(HPyContext *ctx, HPy_ssize_t capacity) -{ - _HPyTracker_s *hp; - if (capacity == 0) { - capacity = HPYTRACKER_INITIAL_CAPACITY; - } - capacity++; // always reserve space for an extra handle, see the docs - - hp = (_HPyTracker_s*)malloc(sizeof(_HPyTracker_s)); - if (hp == NULL) { - HPyErr_NoMemory(ctx); - return _hp2ht(0); - } - hp->handles = (HPy*)calloc(capacity, sizeof(HPy)); - if (hp->handles == NULL) { - free(hp); - HPyErr_NoMemory(ctx); - return _hp2ht(0); - } - hp->capacity = capacity; - hp->length = 0; - return _hp2ht(hp); -} - -static int -tracker_resize(HPyContext *ctx, _HPyTracker_s *hp, HPy_ssize_t capacity) -{ - HPy *new_handles; - capacity++; - - if (capacity <= hp->length) { - // refuse a resize that would either 1) lose handles or 2) not leave - // space for one new handle - HPyErr_SetString(ctx, ctx->h_ValueError, "HPyTracker resize would lose handles"); - return -1; - } - new_handles = (HPy*)realloc(hp->handles, capacity * sizeof(HPy)); - if (new_handles == NULL) { - HPyErr_NoMemory(ctx); - return -1; - } - hp->capacity = capacity; - hp->handles = new_handles; - return 0; -} - -_HPy_HIDDEN int -raw_Tracker_Add(HPyContext *ctx, HPyTracker ht, HPy h) -{ - _HPyTracker_s *hp = _ht2hp(ht); - hp->handles[hp->length++] = h; - if (hp->capacity <= hp->length) { - if (tracker_resize(ctx, hp, hp->capacity * 2 - 1) < 0) - return -1; - } - return 0; -} - -_HPy_HIDDEN int -ctx_Tracker_Add_jni(HPyContext *ctx, HPyTracker ht, HPy h) -{ - uint64_t bits = toBits(h); - if (!isBoxedHandle(bits) || bits < IMMUTABLE_HANDLES) { - return 0; - } - return raw_Tracker_Add(ctx, ht, h); -} - -_HPy_HIDDEN void -ctx_Tracker_ForgetAll_jni(HPyContext *ctx, HPyTracker ht) -{ - _HPyTracker_s *hp = _ht2hp(ht); - hp->length = 0; -} - -_HPy_HIDDEN void -ctx_Tracker_Close_jni(HPyContext *ctx, HPyTracker ht) -{ - _HPyTracker_s *hp = _ht2hp(ht); - upcallBulkClose(ctx, hp->handles, hp->length); - free(hp->handles); - free(hp); -} diff --git a/graalpython/com.oracle.graal.python.jni/src/debug/debug_ctx_not_cpython.c b/graalpython/com.oracle.graal.python.jni/src/debug/debug_ctx_not_cpython.c deleted file mode 100644 index a1a5815413..0000000000 --- a/graalpython/com.oracle.graal.python.jni/src/debug/debug_ctx_not_cpython.c +++ /dev/null @@ -1,40 +0,0 @@ -/* MIT License - * - * Copyright (c) 2022, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -// This is for non-CPython implementations! -// -// If you want to bundle the debug mode into your own version of -// hpy.universal, make sure to compile this file and NOT debug_ctx_cpython.c - -#include "debug_internal.h" - -void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, - HPyFunc_Signature sig, - void *func, void *args) -{ - HPyContext *uctx = get_info(dctx)->uctx; - HPy_FatalError(uctx, - "Something is very wrong! _HPy_CallRealFunctionFromTrampoline() " - "should be used only by the CPython version of hpy.universal"); -} diff --git a/graalpython/com.oracle.graal.python.jni/src/debug/debug_ctx_tracker.c b/graalpython/com.oracle.graal.python.jni/src/debug/debug_ctx_tracker.c deleted file mode 100644 index e635238c1f..0000000000 --- a/graalpython/com.oracle.graal.python.jni/src/debug/debug_ctx_tracker.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "debug_internal.h" -#include "../hpy_jni.h" - -/* ~~~ debug mode implementation of HPyTracker ~~~ - - This is a bit special and it's worth explaining what is going on. - - The HPyTracker functions need their own debug mode implementation because - the debug mode needs to be aware of when a DHPy is closed, for the same - reason for why we need debug_ctx_Close. - - So, in theory here we should have our own implementation of a - DebugHPyTracker which manages a growable list of handles, and which calls - debug_ctx_Close at the end. But, we ALREADY have the logic available, it's - implemented in ctx_tracker.c. - - So, we can share some functions but note that the tracker will not store - universal handles but debug handles. - - Since we already have some special (and faster) implementation for - 'ctx_Tracker_Add' and 'ctx_Tracker_Close', we need to have a separate debug - mode implementation for them. -*/ - -HPyTracker debug_ctx_Tracker_New(HPyContext *dctx, HPy_ssize_t size) -{ - return ctx_Tracker_New_jni(dctx, size); -} - -_HPy_HIDDEN int -debug_ctx_Tracker_Add(HPyContext *dctx, HPyTracker ht, DHPy h) -{ - return raw_Tracker_Add(dctx, ht, h); -} - -void debug_ctx_Tracker_ForgetAll(HPyContext *dctx, HPyTracker ht) -{ - ctx_Tracker_ForgetAll_jni(dctx, ht); -} - -_HPy_HIDDEN void -debug_ctx_Tracker_Close(HPyContext *ctx, HPyTracker ht) -{ - _HPyTracker_s *hp = _ht2hp(ht); - HPy_ssize_t i; - for (i=0; ilength; i++) { - HPy_Close(ctx, hp->handles[i]); - } - free(hp->handles); - free(hp); -} diff --git a/graalpython/com.oracle.graal.python.jni/src/debug/hpy_debug.h b/graalpython/com.oracle.graal.python.jni/src/debug/hpy_debug.h deleted file mode 100644 index aab3701176..0000000000 --- a/graalpython/com.oracle.graal.python.jni/src/debug/hpy_debug.h +++ /dev/null @@ -1,81 +0,0 @@ -/* MIT License - * - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef HPY_DEBUG_H -#define HPY_DEBUG_H - -#include "hpy.h" - -/* - This is the main public API for the debug mode, and it's meant to be used - by hpy.universal implementations (including but not limited to the - CPython's version of hpy.universal which is included in this repo). - - The idea is that for every uctx there is a corresponding unique dctx which - wraps it. - - If you call hpy_debug_get_ctx twice on the same uctx, you get the same - result. - - IMPLEMENTATION NOTE: at the moment of writing, the only known user of the - debug mode is CPython's hpy.universal: in that module, the uctx is a - statically allocated singleton, so for simplicity of implementation - currently we do the same inside debug_ctx.c, with a sanity check to ensure - that we don't call hpy_debug_get_ctx with different uctxs. But this is a - limitation of the current implementation and users should not rely on it. It - is likely that we will need to change it in the future, e.g. if we want to - have per-subinterpreter uctxs. -*/ - -HPyContext * hpy_debug_get_ctx(HPyContext *uctx); -int hpy_debug_ctx_init(HPyContext *dctx, HPyContext *uctx); -void hpy_debug_set_ctx(HPyContext *dctx); - -// convert between debug and universal handles. These are basically -// the same as DHPy_open and DHPy_unwrap but with a different name -// because this is the public-facing API and DHPy/UHPy are only internal -// implementation details. -HPy hpy_debug_open_handle(HPyContext *dctx, HPy uh); -HPy hpy_debug_unwrap_handle(HPyContext *dctx, HPy dh); -void hpy_debug_close_handle(HPyContext *dctx, HPy dh); - -// this is the HPy init function created by HPy_MODINIT. In CPython's version -// of hpy.universal the code is embedded inside the extension, so we can call -// this function directly instead of dlopen it. This is similar to what -// CPython does for its own built-in modules. But we must use the same -// signature as HPy_MODINIT - -#ifdef ___cplusplus -extern "C" -#endif -HPy_EXPORTED_SYMBOL -HPyModuleDef* HPyInit__debug(); - -#ifdef ___cplusplus -extern "C" -#endif -HPy_EXPORTED_SYMBOL -void HPyInitGlobalContext__debug(HPyContext *ctx); - -#endif /* HPY_DEBUG_H */ diff --git a/graalpython/com.oracle.graal.python.jni/src/hpy_jni.c b/graalpython/com.oracle.graal.python.jni/src/hpy_jni.c deleted file mode 100644 index 23a79fc5fb..0000000000 --- a/graalpython/com.oracle.graal.python.jni/src/hpy_jni.c +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "hpy_jni.h" -#include "hpy_log.h" -#include "hpy_native_cache.h" -#include "hpy_trace.h" - -#include -#include -#include -#include -#include -#include - -//************************* -// JNI upcalls - -#include "com_oracle_graal_python_builtins_objects_cext_hpy_jni_GraalHPyJNIContext.h" -#include "hpynative.h" - -#include "autogen_ctx_init_jni.h" -#include "autogen_c_access.h" - -/* definitions for HPyTracker */ -#include "hpy/runtime/ctx_funcs.h" - -#define JNI_HELPER(NAME) Java_com_oracle_graal_python_builtins_objects_cext_hpy_jni_GraalHPyJNIContext_ ## NAME - -_HPy_HIDDEN JNIEnv* jniEnv; - -#define ALL_FIELDS \ - FIELD(hpyHandleTable, CLASS_HPYCONTEXT, SIG_JOBJECTARRAY) \ - FIELD(hpyGlobalsTable, CLASS_HPYCONTEXT, SIG_JOBJECTARRAY) \ - FIELD(nextHandle, CLASS_HPYCONTEXT, SIG_INT) - -#define FIELD(name, clazz, jniSig) static jfieldID jniField_ ## name; -ALL_FIELDS -#undef FIELD - -/* - * This macro specifies custom JNI upcalls. - * Add entries if you want to have (a) an additional upcall that does not - * correspond to an official HPy context function, or (b) if an upcall has a - * different signature then the public one. - */ -#define CUSTOM_UPCALLS \ - UPCALL(ctxGetItems, SIG_HPY SIG_JSTRING, SIG_HPY) \ - UPCALL(ctxSetItems, SIG_HPY SIG_JSTRING SIG_HPY, SIG_INT) \ - UPCALL(ctxGetAttrs, SIG_HPY SIG_JSTRING, SIG_HPY) \ - UPCALL(ctxFieldStore, SIG_HPY SIG_HPYFIELD SIG_HPY, SIG_PTR) \ - UPCALL(ctxGlobalStore, SIG_HPY SIG_HPYGLOBAL, SIG_PTR) \ - UPCALL(ctxContextVarGet, SIG_HPY SIG_HPY SIG_HPY, SIG_HPY) \ - UPCALL(ctxBulkClose, SIG_PTR SIG_INT, SIG_VOID) \ - UPCALL(ctxUnicodeFromJCharArray, SIG_JCHARARRAY, SIG_HPY) \ - UPCALL(ctxSequenceFromArray, SIG_JLONGARRAY SIG_BOOL SIG_BOOL, SIG_HPY) - - -#define UPCALL(name, jniSigArgs, jniSigRet) static jmethodID jniMethod_ ## name; -CUSTOM_UPCALLS -#undef UPCALL - -static jmethodID jniMethod_hpy_debug_get_context; -static jmethodID jniMethod_hpy_trace_get_context; - - -#define MAX_UNCLOSED_HANDLES 32 -static int32_t unclosedHandleTop = 0; -static HPy unclosedHandles[MAX_UNCLOSED_HANDLES]; - -static inline jsize get_handle_table_size(HPyContext *ctx) { - uint64_t size = HANDLE_TABLE_SIZE(ctx->_private); - assert((jsize)size == size); - return (jsize)size; -} - -static uint64_t get_hpy_handle_for_object(HPyContext *ctx, jobject hpyContext, jobject element, bool update_native_cache) { - /* TODO(fa): for now, we fall back to the upcall */ - if (update_native_cache) { - return 0; - } - - jobjectArray hpy_handles = (jobjectArray)(*jniEnv)->GetObjectField(jniEnv, hpyContext, jniField_hpyHandleTable); - if (hpy_handles == NULL) { - LOGS("hpy handle table is NULL") - return 0; - } - - /* try to reuse a closed handle from our native list */ - jsize next_handle; - if (unclosedHandleTop > 0) { - uint64_t recycled = toBits(unclosedHandles[--unclosedHandleTop]); - LOG("%llu", (unsigned long long)recycled) - assert(recycled < INT32_MAX); - next_handle = (jsize) recycled; - } else { - next_handle = (*jniEnv)->GetIntField(jniEnv, hpyContext, jniField_nextHandle); - LOG("%d", next_handle) - jsize s = get_handle_table_size(ctx); - if (next_handle >= s) { - return 0; - } - (*jniEnv)->SetIntField(jniEnv, hpyContext, jniField_nextHandle, next_handle+1); - } - (*jniEnv)->SetObjectArrayElement(jniEnv, hpy_handles, next_handle, element); - (*jniEnv)->DeleteLocalRef(jniEnv, hpy_handles); - /* TODO(fa): update native data pointer cache here (if specified) */ - return boxHandle(next_handle); -} - -static jobject get_object_for_hpy_global(jobject hpyContext, uint64_t bits) { - jobject hpy_globals = (*jniEnv)->GetObjectField(jniEnv, hpyContext, jniField_hpyGlobalsTable); - if (hpy_globals == NULL) { - LOGS("hpy globals is NULL") - return NULL; - } - jobject element = (*jniEnv)->GetObjectArrayElement(jniEnv, (jobjectArray)hpy_globals, (jsize)unboxHandle(bits)); - (*jniEnv)->DeleteLocalRef(jniEnv, hpy_globals); - if (element == NULL) { - LOGS("globals element is NULL") - return NULL; - } - return element; -} - -#define MAX_UNICODE 0x10ffff - -_HPy_HIDDEN HPy ctx_Unicode_FromWideChar_jni(HPyContext *ctx, const wchar_t *u, HPy_ssize_t size) { - if (u == NULL && size != 0) { - return HPy_NULL; - } - - if (sizeof(wchar_t) != sizeof(uint32_t)) { - HPyErr_SetString(ctx, ctx->h_SystemError, "unsupported size of type wchar_t"); - return HPy_NULL; - } - - if (size == -1) { - size = wcslen(u); - } - - if (size > INT32_MAX) { - HPyErr_SetString(ctx, ctx->h_SystemError, "wchar_t array is too large"); - return HPy_NULL; - } - - uint32_t maxchar = 0; - wchar_t ch; - HPy_ssize_t i; - for (i = 0; i < size; i++) { - ch = u[i]; - if (ch > maxchar) { - maxchar = ch; - if (maxchar > MAX_UNICODE) { - HPyErr_SetString(ctx, ctx->h_ValueError, "character is not in range [U+0000; U+10ffff]"); - return HPy_NULL; - } - } - } - - if (maxchar < UINT16_MAX) { - jarray jCharArray = (*jniEnv)->NewCharArray(jniEnv, (jsize) size); - jchar *content = (*jniEnv)->GetPrimitiveArrayCritical(jniEnv, jCharArray, 0); - HPy_ssize_t i; - for (i = 0; i < size; i++) { - content[i] = (jchar) u[i]; - } - (*jniEnv)->ReleasePrimitiveArrayCritical(jniEnv, jCharArray, content, 0); - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctxUnicodeFromJCharArray, jCharArray); - } else { - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Unicode_FromWideChar, PTR_UP(u), SIZE_T_UP(size)); - } -} - -_HPy_HIDDEN HPy ctx_Global_Load_jni(HPyContext *ctx, HPyGlobal global) { - uint64_t bits = toBits(global); - if (bits && isBoxedHandle(bits)) { - jobject hpyContext = graal_hpy_context_get_native_context(ctx)->jni_context; - jobject element = get_object_for_hpy_global(hpyContext, bits); - if (element == NULL) { - return HPy_NULL; - } - - uint64_t new_handle = get_hpy_handle_for_object(ctx, hpyContext, element, false); - (*jniEnv)->DeleteLocalRef(jniEnv, element); - if (new_handle) { - load_global_native_data_pointer(ctx, bits, new_handle); - return toPtr(new_handle); - } - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctx_Global_Load, bits); - } else { - return toPtr(bits); - } -} - -static void ctx_Global_Store_jni(HPyContext *ctx, HPyGlobal *h, HPy v) { - h->_i = DO_UPCALL_INTPTR_T(CONTEXT_INSTANCE(ctx), ctxGlobalStore, HPY_GLOBAL_UP(*h), HPY_UP(v)); -} - -static void ctx_Field_Store_jni(HPyContext *ctx, HPy owner, HPyField *field, HPy value) { - field->_i = DO_UPCALL_INTPTR_T(CONTEXT_INSTANCE(ctx), ctxFieldStore, HPY_UP(owner), HPY_FIELD_UP(*field), HPY_UP(value)); -} - -static const char* getBoxedPrimitiveName(uint64_t bits) { - assert(!isBoxedHandle(bits)); - if (isBoxedInt(bits)) { - return "int"; - } - assert(isBoxedDouble(bits)); - return "float"; -} - -static int ctx_SetItem_s_jni(HPyContext *ctx, HPy target, const char *name, HPy value) { - uint64_t bits = toBits(target); - if (!isBoxedHandle(bits)) { - const size_t buffer_size = 128; -#ifdef _MSC_VER - char *message = (char *)alloca(buffer_size); -#else - char message[buffer_size]; -#endif - snprintf(message, buffer_size, - "'%s' object does not support item assignment", getBoxedPrimitiveName(bits)); - HPyErr_SetString(ctx, ctx->h_TypeError, message); - return -1; - } - jstring jname = (*jniEnv)->NewStringUTF(jniEnv, name); - return DO_UPCALL_INT(CONTEXT_INSTANCE(ctx), ctxSetItems, target, jname, value); -} - -static HPy ctx_GetItem_s_jni(HPyContext *ctx, HPy target, const char *name) { - uint64_t bits = toBits(target); - if (!isBoxedHandle(bits)) { - const size_t buffer_size = 128; -#ifdef _MSC_VER - char *message = (char *)alloca(buffer_size); -#else - char message[buffer_size]; -#endif - snprintf(message, buffer_size, - "'%s' object is not subscriptable", getBoxedPrimitiveName(bits)); - return HPyErr_SetString(ctx, ctx->h_TypeError, message); - } - jstring jname = (*jniEnv)->NewStringUTF(jniEnv, name); - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctxGetItems, target, jname); -} - -static HPy ctx_GetAttr_s_jni(HPyContext *ctx, HPy target, const char *name) { - jstring jname = (*jniEnv)->NewStringUTF(jniEnv, name); - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctxGetAttrs, target, jname); -} - -static int ctx_ContextVar_Get_jni(HPyContext *ctx, HPy var, HPy def, HPy *result) { - /* This uses 'h_Ellipsis' as an error marker assuming that it is rather uncertain that this will be a valid return - value. If 'h_Ellipsis' is returned, this indicates an error and we explicitly check for an error then. */ - HPy err_marker = ctx->h_Ellipsis; - HPy r = DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctxContextVarGet, HPY_UP(var), HPY_UP(def), HPY_UP(err_marker)); - if (toBits(r) == toBits(err_marker) && HPyErr_Occurred(ctx)) { - return -1; - } - *result = r; - return 0; -} - -_HPy_HIDDEN HPy upcallSequenceFromArray(HPyContext *ctx, HPy *items, HPy_ssize_t nitems, bool steal, bool create_list) { - jarray jLongArray = (*jniEnv)->NewLongArray(jniEnv, (jsize) nitems); - (*jniEnv)->SetLongArrayRegion(jniEnv, jLongArray, 0, (jsize) nitems, (const jlong *)items); - return DO_UPCALL_HPY(CONTEXT_INSTANCE(ctx), ctxSequenceFromArray, jLongArray, (jboolean) steal, (jboolean) create_list); -} - -static HPy ctx_Tuple_FromArray_jni(HPyContext *ctx, HPy *items, HPy_ssize_t nitems) { - return upcallSequenceFromArray(ctx, items, nitems, false, JNI_FALSE); -} - -_HPy_HIDDEN void upcallBulkClose(HPyContext *ctx, HPy *items, HPy_ssize_t nitems) { - DO_UPCALL_VOID(CONTEXT_INSTANCE(ctx), ctxBulkClose, items, nitems); -} - -/* Initialize the jmethodID pointers for all the context functions implemented via JNI. */ -JNIEXPORT jlong JNICALL JNI_HELPER(initJNI)(JNIEnv *env, jclass clazz, jobject jbackend, jobject jctx, jlongArray jctx_handles, jintArray ctype_sizes, jintArray cfield_offsets) { - LOG("%s", "hpy_jni.c:initJNI\n"); - int res; - GraalHPyContext *graal_hpy_context = (GraalHPyContext *) calloc(1, sizeof(GraalHPyContext)); - HPyContext *ctx = graal_native_context_get_hpy_context(graal_hpy_context); - ctx->name = "HPy Universal ABI (GraalVM backend, JNI)"; - graal_hpy_context->jni_backend = (*env)->NewGlobalRef(env, jbackend); - graal_hpy_context->jni_context = (*env)->NewGlobalRef(env, jctx); - jniEnv = env; - - if (init_autogen_jni_ctx(env, clazz, ctx, jctx_handles)) { - return PTR_UP(NULL); - } - - assert(sizeof(int32_t) == sizeof(jint)); - int32_t *ctype_sizes_data = (*env)->GetPrimitiveArrayCritical(env, ctype_sizes, 0); - res = fill_c_type_sizes(ctype_sizes_data); - (*env)->ReleasePrimitiveArrayCritical(env, ctype_sizes, ctype_sizes_data, 0); - if (res) { - return PTR_UP(NULL); - } - int32_t *cfield_offsets_data = (*env)->GetPrimitiveArrayCritical(env, cfield_offsets, 0); - res = fill_c_field_offsets(cfield_offsets_data); - (*env)->ReleasePrimitiveArrayCritical(env, cfield_offsets, cfield_offsets_data, 0); - if (res) { - return PTR_UP(NULL); - } - - /* The HPyTracker is backend-specific. For JNI, we stay in native since there is no benefit for - doing an upcall. */ - ctx->ctx_Tracker_New = ctx_Tracker_New_jni; - ctx->ctx_Tracker_Add = ctx_Tracker_Add_jni; - ctx->ctx_Tracker_ForgetAll = ctx_Tracker_ForgetAll_jni; - ctx->ctx_Tracker_Close = ctx_Tracker_Close_jni; - - ctx->ctx_Unicode_FromWideChar = ctx_Unicode_FromWideChar_jni; - - ctx->ctx_Tuple_FromArray = ctx_Tuple_FromArray_jni; - - ctx->ctx_Global_Load = ctx_Global_Load_jni; - ctx->ctx_Global_Store = ctx_Global_Store_jni; - ctx->ctx_Field_Store = ctx_Field_Store_jni; - - ctx->ctx_SetItem_s = ctx_SetItem_s_jni; - ctx->ctx_GetItem_s = ctx_GetItem_s_jni; - - ctx->ctx_ContextVar_Get = ctx_ContextVar_Get_jni; - ctx->ctx_GetAttr_s = ctx_GetAttr_s_jni; - - assert(clazz != NULL); - - jclass jctx_class = (*env)->GetObjectClass(env, jctx); - if (jctx_class == NULL) { - LOGS("ERROR: could not get class of Java HPy context object"); - return PTR_UP(NULL); - } - -#define CLASS_HPYCONTEXT jctx_class - -#define SIG_HPY "J" -#define SIG_HPYGLOBAL "J" -#define SIG_HPYFIELD "J" -#define SIG_PTR "J" -#define SIG_VOID "V" -#define SIG_INT "I" -#define SIG_BOOL "Z" -#define SIG_JSTRING "Ljava/lang/String;" -#define SIG_JCHARARRAY "[C" -#define SIG_JLONGARRAY "[J" -#define SIG_JOBJECTARRAY "[Ljava/lang/Object;" - -#define FIELD(name, clazz, jniSig) \ - jniField_ ## name = (*env)->GetFieldID(env, clazz, #name, jniSig); \ - if (jniField_ ## name == NULL) { \ - LOGS("ERROR: jni field " #name " not found found !\n"); \ - return PTR_UP(NULL); \ - } - -ALL_FIELDS -#undef FIELD - -#define UPCALL(name, jniSigArgs, jniSigRet) \ - jniMethod_ ## name = (*env)->GetMethodID(env, clazz, #name, "(" jniSigArgs ")" jniSigRet); \ - if (jniMethod_ ## name == NULL) { \ - LOGS("ERROR: jni method " #name " not found found !\n"); \ - return PTR_UP(NULL); \ - } - -CUSTOM_UPCALLS -#undef UPCALL - - jniMethod_hpy_debug_get_context = (*env)->GetMethodID(env, clazz, "getHPyDebugContext", "()" SIG_PTR); - if (jniMethod_hpy_debug_get_context == NULL) { - LOGS("ERROR: jni method getHPyDebugContext not found found !\n"); - return PTR_UP(NULL); - } - - jniMethod_hpy_trace_get_context = (*env)->GetMethodID(env, clazz, "getHPyTraceContext", "()" SIG_PTR); - if (jniMethod_hpy_trace_get_context == NULL) { - LOGS("ERROR: jni method getHPyTraceContext not found found !\n"); - return PTR_UP(NULL); - } - - return PTR_UP(ctx); -} - -JNIEXPORT jint JNICALL JNI_HELPER(finalizeJNIContext)(JNIEnv *env, jclass clazz, jlong ctx) { - LOG("%s", "hpy_jni.c:finalizeJNIContext\n"); - // assert(info->magic_number == HPY_TRACE_MAGIC); - GraalHPyContext *native_ctx = graal_hpy_context_get_native_context((HPyContext *) ctx); - (*env)->DeleteGlobalRef(env, (jobject) native_ctx->jni_backend); - (*env)->DeleteGlobalRef(env, (jobject) native_ctx->jni_context); - free((void *)native_ctx); - return 0; -} - -JNIEXPORT jlong JNICALL JNI_HELPER(initJNIDebugContext)(JNIEnv *env, jclass clazz, jlong uctxPointer) { - LOG("%s", "hpy_jni.c:initJNIDebugContext\n"); - HPyContext *uctx = (HPyContext *) uctxPointer; - - HPyContext *dctx = (HPyContext *) malloc(sizeof(HPyContext)); - dctx->name = "HPy Debug Mode ABI"; - dctx->_private = NULL; - dctx->abi_version = HPY_ABI_VERSION; - - hpy_debug_ctx_init(dctx, uctx); - return PTR_UP(dctx); -} - -JNIEXPORT jint JNICALL JNI_HELPER(finalizeJNIDebugContext)(JNIEnv *env, jclass clazz, jlong dctxPointer) { - LOG("%s", "hpy_jni.c:finalizeJNIDebugContext\n"); - HPyContext *dctx = (HPyContext *) dctxPointer; - hpy_debug_ctx_free(dctx); - free(dctx); - return 0; -} - -JNIEXPORT jlong JNICALL JNI_HELPER(initJNIDebugModule)(JNIEnv *env, jclass clazz, jlong uctxPointer) { - LOG("%s", "hpy_jni.c:initJNIDebugModule\n"); - return PTR_UP(HPyInit__debug()); -} - -JNIEXPORT jlong JNICALL JNI_HELPER(initJNITraceContext)(JNIEnv *env, jclass clazz, jlong uctxPointer) { - LOG("%s", "hpy_jni.c:initJNITraceContext\n"); - HPyContext *uctx = (HPyContext *) uctxPointer; - - HPyContext *tctx = (HPyContext *) malloc(sizeof(HPyContext)); - tctx->name = "HPy Trace Mode ABI"; - tctx->_private = NULL; - tctx->abi_version = HPY_ABI_VERSION; - - hpy_trace_ctx_init(tctx, uctx); - return PTR_UP(tctx); -} - -JNIEXPORT jint JNICALL JNI_HELPER(finalizeJNITraceContext)(JNIEnv *env, jclass clazz, jlong tctxPointer) { - LOG("%s", "hpy_jni.c:finalizeJNITraceContext\n"); - HPyContext *tctx = (HPyContext *) tctxPointer; - hpy_trace_ctx_free(tctx); - free(tctx); - return 0; -} - -JNIEXPORT jlong JNICALL JNI_HELPER(initJNITraceModule)(JNIEnv *env, jclass clazz, jlong uctxPointer) { - LOG("%s", "hpy_jni.c:initJNITraceModule\n"); - return PTR_UP(HPyInit__trace()); -} - -JNIEXPORT void JNICALL JNI_HELPER(bulkFreeNativeSpace)(JNIEnv *env, jclass clazz, jlongArray nativeSpacePtrs, jlongArray destroyFuncPtrs, jint n) { - jlong *native_space_ptrs_data = (*env)->GetLongArrayElements(env, nativeSpacePtrs, 0); - jlong *destroy_func_ptrs_data = (*env)->GetLongArrayElements(env, destroyFuncPtrs, 0); - for (jint i=0; i < n; i++) - { - HPyFunc_destroyfunc destroy_func = (HPyFunc_destroyfunc) destroy_func_ptrs_data[i]; - destroy_func((void *)native_space_ptrs_data[i]); - } - (*jniEnv)->ReleaseLongArrayElements(env, nativeSpacePtrs, native_space_ptrs_data, JNI_ABORT); - (*jniEnv)->ReleaseLongArrayElements(env, destroyFuncPtrs, destroy_func_ptrs_data, JNI_ABORT); -} - -JNIEXPORT jint JNICALL JNI_HELPER(strcmp)(JNIEnv *env, jclass clazz, jlong s1, jlong s2) { - return (jint) strcmp((const char *)s1, (const char *)s2); -} - -JNIEXPORT jint JNICALL JNI_HELPER(initJNINativeFastPaths)(JNIEnv *env, jclass clazz, jlong uctxPointer) { - init_native_fast_paths((HPyContext *) uctxPointer); - return 0; -} - -JNIEXPORT jint JNICALL JNI_HELPER(setNativeSpaceFunction)(JNIEnv *env, jclass clazz, jlong uctxPointer, jlong cachePtr) { - LOG("%ld %ld", uctxPointer, cachePtr); - HPyContext *ctx = (HPyContext *) uctxPointer; - ctx->_private = (void *) cachePtr; - return 0; -} - -JNIEXPORT jint JNICALL JNI_HELPER(getErrno)(JNIEnv *env, jclass clazz) { - return (jint) errno; -} - -JNIEXPORT jlong JNICALL JNI_HELPER(getStrerror)(JNIEnv *env, jclass clazz, jint i) { - return PTR_UP(strerror(i)); -} - -HPyContext * hpy_debug_get_ctx(HPyContext *uctx) -{ - HPyContext *dctx = (HPyContext *) DO_UPCALL_PTR_NOARGS(CONTEXT_INSTANCE(uctx), hpy_debug_get_context); - if (uctx == dctx) { - HPy_FatalError(uctx, "hpy_debug_get_ctx: expected an universal ctx, got a debug ctx"); - } - return dctx; -} - -HPyContext * hpy_trace_get_ctx(HPyContext *uctx) -{ - HPyContext *tctx = (HPyContext *) DO_UPCALL_PTR_NOARGS(CONTEXT_INSTANCE(uctx), hpy_trace_get_context); - if (uctx == tctx) { - HPy_FatalError(uctx, "hpy_trace_get_ctx: expected an universal ctx, " - "got a trace ctx"); - } - return tctx; -} diff --git a/graalpython/com.oracle.graal.python.jni/src/hpy_jni.h b/graalpython/com.oracle.graal.python.jni/src/hpy_jni.h deleted file mode 100644 index 585ce6c554..0000000000 --- a/graalpython/com.oracle.graal.python.jni/src/hpy_jni.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef SRC_HPY_JNI_H_ -#define SRC_HPY_JNI_H_ - -#include -#include -#include - -#if defined(_MSC_VER) -# include /* for alloca() */ -#endif - -#include "debug_internal.h" -#include "hpy_native_fast_paths.h" - -#define DO_UPCALL_JINT(jni_ctx, name, ...) (*jniEnv)->CallIntMethod(jniEnv, (jni_ctx), jniMethod_ ## name, __VA_ARGS__) -#define DO_UPCALL_JLONG(jni_ctx, name, ...) (*jniEnv)->CallLongMethod(jniEnv, (jni_ctx), jniMethod_ ## name, __VA_ARGS__) -#define DO_UPCALL_HPY_NOARGS(jni_ctx, name) ((HPy){(HPy_ssize_t)(*jniEnv)->CallLongMethod(jniEnv, (jni_ctx), jniMethod_ ## name)}) -#define DO_UPCALL_HPY(jni_ctx, name, ...) ((HPy){(HPy_ssize_t)(*jniEnv)->CallLongMethod(jniEnv, (jni_ctx), jniMethod_ ## name, __VA_ARGS__)}) -#define DO_UPCALL_HPY0(jni_ctx, name) ((HPy){(HPy_ssize_t)(*jniEnv)->CallLongMethod(jniEnv, (jni_ctx), jniMethod_ ## name)}) -#define DO_UPCALL_HPYTRACKER(jni_ctx, name, ...) ((HPyTracker){(*jniEnv)->CallLongMethod(jniEnv, (jni_ctx), jniMethod_ ## name, __VA_ARGS__)}) -#define DO_UPCALL_HPYTHREADSTATE0(jni_ctx, name) ((HPyThreadState){(*jniEnv)->CallLongMethod(jniEnv, (jni_ctx), jniMethod_ ## name)}) -#define DO_UPCALL_HPYLISTBUILDER(jni_ctx, name, ...) ((HPyListBuilder){(*jniEnv)->CallLongMethod(jniEnv, (jni_ctx), jniMethod_ ## name, __VA_ARGS__)}) -#define DO_UPCALL_PTR(jni_ctx, name, ...) (void*) (*jniEnv)->CallLongMethod(jniEnv, (jni_ctx), jniMethod_ ## name, __VA_ARGS__) -#define DO_UPCALL_PTR_NOARGS(jni_ctx, name) (void*) (*jniEnv)->CallLongMethod(jniEnv, (jni_ctx), jniMethod_ ## name) -#define DO_UPCALL_INTPTR_T(jni_ctx, name, ...) (intptr_t) (*jniEnv)->CallLongMethod(jniEnv, (jni_ctx), jniMethod_ ## name, __VA_ARGS__) -#define DO_UPCALL_SIZE_T(jni_ctx, name, ...) (HPy_ssize_t) (*jniEnv)->CallLongMethod(jniEnv, (jni_ctx), jniMethod_ ## name, __VA_ARGS__) -#define DO_UPCALL_INT0(jni_ctx, name, ...) (int) (*jniEnv)->CallIntMethod(jniEnv, (jni_ctx), jniMethod_ ## name) -#define DO_UPCALL_DOUBLE(jni_ctx, name, ...) (double) (*jniEnv)->CallDoubleMethod(jniEnv, (jni_ctx), jniMethod_ ## name, __VA_ARGS__) -#define DO_UPCALL_VOID(jni_ctx, name, ...) (*jniEnv)->CallVoidMethod(jniEnv, (jni_ctx), jniMethod_ ## name, __VA_ARGS__) -#define DO_UPCALL_VOID0(jni_ctx, name) (*jniEnv)->CallVoidMethod(jniEnv, (jni_ctx), jniMethod_ ## name) -#define DO_UPCALL_HPY_SSIZE_T (HPy_ssize_t) DO_UPCALL_JLONG -#define DO_UPCALL_HPY_HASH_T (HPy_hash_t) DO_UPCALL_JLONG -#define DO_UPCALL_HPY_UCS4 (HPy_UCS4) DO_UPCALL_JINT -#define DO_UPCALL_HPYTYPE_BUILTINSHAPE (HPyType_BuiltinShape) DO_UPCALL_JINT -#define DO_UPCALL_INT (int) DO_UPCALL_JINT -#define DO_UPCALL_INT32_T (int32_t) DO_UPCALL_JINT -#define DO_UPCALL_UINT32_T (uint32_t) DO_UPCALL_JINT -#define DO_UPCALL_INT64_T (int64_t) DO_UPCALL_JLONG -#define DO_UPCALL_UINT64_T (uint64_t) DO_UPCALL_JLONG - -#define HPY_UP(_h) ((jlong)((_h)._i)) -#define PTR_UP(_h) ((jlong)_h) -#define INT_UP(_h) ((jint)_h) -#define INT32_UP(_h) ((jint)_h) -#define UINT32_UP(_h) ((jint)_h) -#define LONG_UP(_h) ((jlong)_h) -#define DOUBLE_UP(_h) ((jdouble)_h) -#define SIZE_T_UP(_h) ((jlong)_h) -#define HPY_TRACKER_UP(_h) ((jlong)((_h)._i)) -#define HPY_LIST_BUILDER_UP(_h) ((jlong)((_h)._lst)) -#define HPY_THREAD_STATE_UP(_h) ((jlong)((_h)._i)) -#define HPY_GLOBAL_UP(_h) ((jlong)((_h)._i)) -#define HPY_FIELD_UP(_h) ((jlong)((_h)._i)) - -static inline HPy _jlong2h(jlong obj) { - return (HPy){(HPy_ssize_t)obj}; -} - -static inline jlong _h2jlong(HPy h) { - return (jlong)(h._i); -} - -static inline DHPy _jlong2dh(HPyContext *dctx, jlong obj) -{ - return DHPy_open(dctx, _jlong2h(obj)); -} - -static inline jlong _dh2jlong(HPyContext *dctx, DHPy dh) -{ - return _h2jlong(DHPy_unwrap(dctx, dh)); -} - -static inline jlong from_dh(HPyContext *dctx, DHPy dh_result) -{ - jlong result = _dh2jlong(dctx, dh_result); - DHPy_close(dctx, dh_result); - return result; -} - -#define _ARR_JLONG2DH(DCTX, DST, ARGS, NARGS) \ - DHPy *DST = (DHPy *)alloca((NARGS) * sizeof(DHPy)); \ - for (HPy_ssize_t i = 0; i < (NARGS); i++) { \ - DST[i] = _jlong2dh(DCTX, ((jlong *)(ARGS))[i]); \ - } \ - -#define _ARR_DH_CLOSE(DCTX, DH_ARR, NARGS) \ - for (HPy_ssize_t i = 0; i < (NARGS); i++) { \ - DHPy_close_and_check((DCTX), (DH_ARR)[i]); \ - } \ - -/* just for better readability */ -typedef HPy_buffer DHPy_buffer; -typedef HPy_buffer UHPy_buffer; - -/* Copies everything from 'src' to 'dest' and unwraps the 'obj' debug handle. */ -static inline void -_buffer_d2u(HPyContext *dctx, const DHPy_buffer *src, UHPy_buffer *dest) -{ - dest->buf = src->buf; - dest->obj = DHPy_unwrap(dctx, src->obj); - dest->len = src->len; - dest->itemsize = src->itemsize; - dest->readonly = src->readonly; - dest->ndim = src->ndim; - dest->format = src->format; - dest->shape = src->shape; - dest->strides = src->strides; - dest->suboffsets = src->suboffsets; - dest->internal = src->internal; -} - -/* Copies everything from 'src' to 'dest' and opens a debug handle for 'obj'. */ -static inline void -_buffer_u2d(HPyContext *dctx, const UHPy_buffer *src, DHPy_buffer *dest) -{ - dest->buf = src->buf; - dest->obj = DHPy_open(dctx, src->obj); - dest->len = src->len; - dest->itemsize = src->itemsize; - dest->readonly = src->readonly; - dest->ndim = src->ndim; - dest->format = src->format; - dest->shape = src->shape; - dest->strides = src->strides; - dest->suboffsets = src->suboffsets; - dest->internal = src->internal; -} - -#define CONTEXT_INSTANCE(_hpy_ctx) ((jobject)(graal_hpy_context_get_native_context(_hpy_ctx)->jni_backend)) - -_HPy_HIDDEN extern JNIEnv* jniEnv; - -_HPy_HIDDEN HPy upcallSequenceFromArray(HPyContext *ctx, HPy *items, HPy_ssize_t nitems, bool steal, bool create_list); - -_HPy_HIDDEN void upcallBulkClose(HPyContext *ctx, HPy *items, HPy_ssize_t nitems); - -_HPy_HIDDEN HPyTracker ctx_Tracker_New_jni(HPyContext *ctx, HPy_ssize_t capacity); - -/* Very much like 'augment_Tracker_Add' but doesn't do special handling for - boxed values and immutable handles */ -_HPy_HIDDEN int raw_Tracker_Add(HPyContext *ctx, HPyTracker ht, HPy h); - -_HPy_HIDDEN int ctx_Tracker_Add_jni(HPyContext *ctx, HPyTracker ht, HPy h); - -_HPy_HIDDEN void ctx_Tracker_ForgetAll_jni(HPyContext *ctx, HPyTracker ht); - -_HPy_HIDDEN void ctx_Tracker_Close_jni(HPyContext *ctx, HPyTracker ht); - -_HPy_HIDDEN int hpy_debug_ctx_init(HPyContext *dctx, HPyContext *uctx); - -_HPy_HIDDEN void hpy_debug_ctx_free(HPyContext *dctx); - -#endif /* SRC_HPY_JNI_H_ */ diff --git a/graalpython/com.oracle.graal.python.jni/src/hpy_native_cache.h b/graalpython/com.oracle.graal.python.jni/src/hpy_native_cache.h deleted file mode 100644 index d91f717a6f..0000000000 --- a/graalpython/com.oracle.graal.python.jni/src/hpy_native_cache.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* - * HPy native cache implementation. - * Currently, the native cache is an array of uint64_t values. - * Layout: - * ----------------------------------------------------------------------- - * | n | hptr_0 | hptr_1 | ... | hptr_n | gptr_0 | gptr_1 | ... | gptr_m | - * ----------------------------------------------------------------------- - * 'n' is the current size of the handle table. - * 'hptr_0' is the native data pointer of the object associated with HPy handle 0. - * 'gptr_0' is the native data pointer of the object associated with HPy global 0. - */ - - -#ifndef SRC_HPY_NATIVE_CACHE_H_ -#define SRC_HPY_NATIVE_CACHE_H_ - -#include "hpy_native_fast_paths.h" -#include "hpy_log.h" - -#define HANDLE_MIRROR_OFFSET 1 -#define HANDLE_DATAPTR_INDEX(bits) (HANDLE_MIRROR_OFFSET + unboxHandle(bits)) -#define GLOBAL_DATAPTR_INDEX(n_ht, bits) (HANDLE_MIRROR_OFFSET + n_ht + unboxHandle(bits)) -#define HANDLE_TABLE_SIZE(cache_ptr) (((uint64_t *)cache_ptr)[0]) - -/* - * Get the native data pointer of an object denoted by a handle from the native - * cache. - */ -static inline void * -get_handle_native_data_pointer(HPyContext *ctx, uint64_t bits) { - void** space = (void**)ctx->_private; - return space[HANDLE_DATAPTR_INDEX(bits)]; -} - - -/* - * Get the native data pointer of an object denoted by an HPyGlobal from the - * native cache. - */ -static inline void * -get_global_native_data_pointer(HPyContext *ctx, uint64_t bits) { - void** space = (void**)ctx->_private; - return space[GLOBAL_DATAPTR_INDEX(HANDLE_TABLE_SIZE(space), bits)]; -} - -/* - * Load the native data pointer of an object denoted by an HPyGlobal into the - * native cache. - */ -static inline void -load_global_native_data_pointer(HPyContext *ctx, uint64_t g_bits, uint64_t h_bits) { - void** space = (void**)ctx->_private; - uint64_t n_handle_table = (uint64_t)space[0]; - void *g_data_ptr = space[GLOBAL_DATAPTR_INDEX(n_handle_table, g_bits)]; - LOG("%llu %llu %p", (unsigned long long)g_bits, (unsigned long long)h_bits, g_data_ptr) - space[HANDLE_DATAPTR_INDEX(h_bits)] = g_data_ptr; -} - -#endif /* SRC_HPY_NATIVE_CACHE_H_ */ diff --git a/graalpython/com.oracle.graal.python.jni/src/hpy_native_fast_paths.c b/graalpython/com.oracle.graal.python.jni/src/hpy_native_fast_paths.c deleted file mode 100644 index 4bff9d56fb..0000000000 --- a/graalpython/com.oracle.graal.python.jni/src/hpy_native_fast_paths.c +++ /dev/null @@ -1,599 +0,0 @@ -/* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "hpy_jni.h" -#include "hpy_log.h" -#include "hpy_native_fast_paths.h" -#include "hpy_native_cache.h" - -#include -#include - -#define MAX_UNCLOSED_HANDLES 32 -static int32_t unclosedHandleTop = 0; -static HPy unclosedHandles[MAX_UNCLOSED_HANDLES]; - -//************************* -// BOXING - -static_assert(sizeof(uint64_t) == sizeof(double), "Assumption necessary for NaN boxing to work"); - -static inline double unboxDouble(uint64_t value) { - double result; - uint64_t unboxed = value - NAN_BOXING_BASE; - memcpy(&result, &unboxed, sizeof(double)); - return result; -} - -static inline uint64_t boxDouble(double value) { - // assumes that value doesn't contain non-standard silent NaNs - uint64_t unboxed; - memcpy(&unboxed, &value, sizeof(double)); - return unboxed + NAN_BOXING_BASE; -} - -//************************* -// direct fast paths that handle certain calls on the native side: - -static void *(*original_AsStruct_Object)(HPyContext *ctx, HPy h); -static HPy (*original_Dup)(HPyContext *ctx, HPy h); -static HPy (*original_Long)(HPyContext *ctx, HPy h); -static HPy (*original_Float_FromDouble)(HPyContext *ctx, double v); -static double (*original_Float_AsDouble)(HPyContext *ctx, HPy h); -static int32_t (*original_Long_AsInt32_t)(HPyContext *ctx, HPy h); -static int64_t (*original_Long_AsInt64_t)(HPyContext *ctx, HPy h); -static uint32_t (*original_Long_AsUInt32_t)(HPyContext *ctx, HPy h); -static size_t (*original_Long_AsSize_t)(HPyContext *ctx, HPy h); -static HPy_ssize_t (*original_Long_AsSsize_t)(HPyContext *ctx, HPy h); -static double (*original_Long_AsDouble)(HPyContext *ctx, HPy h); -static HPy (*original_Long_FromInt32_t)(HPyContext *ctx, int32_t l); -static HPy (*original_Long_FromUInt32_t)(HPyContext *ctx, uint32_t l); -static HPy (*original_Long_FromInt64_t)(HPyContext *ctx, int64_t l); -static HPy (*original_Long_FromUInt64_t)(HPyContext *ctx, uint64_t l); -static HPy (*original_Long_FromSsize_t)(HPyContext *ctx, HPy_ssize_t l); -static HPy (*original_Long_FromSize_t)(HPyContext *ctx, size_t l); -static int (*original_List_Check)(HPyContext *ctx, HPy h); -static int (*original_Number_Check)(HPyContext *ctx, HPy h); -static int (*original_TypeCheck)(HPyContext *ctx, HPy h, HPy type); -static void (*original_Close)(HPyContext *ctx, HPy h); -static void (*original_Global_Store)(HPyContext *ctx, HPyGlobal *global, HPy h); -static HPy (*original_Global_Load)(HPyContext *ctx, HPyGlobal global); -static void (*original_Field_Store)(HPyContext *ctx, HPy target_object, HPyField *target_field, HPy h); -static HPy (*original_Field_Load)(HPyContext *ctx, HPy source_object, HPyField source_field); -static int (*original_Is)(HPyContext *ctx, HPy a, HPy b); -static int (*original_IsTrue)(HPyContext *ctx, HPy h); -static HPy (*original_Type)(HPyContext *ctx, HPy obj); -static HPy (*original_Add)(HPyContext *ctx, HPy h1, HPy h2); -static HPy (*original_Subtract)(HPyContext *ctx, HPy h1, HPy h2); -static HPy (*original_Multiply)(HPyContext *ctx, HPy h1, HPy h2); -static HPy (*original_FloorDivide)(HPyContext *ctx, HPy h1, HPy h2); -static HPy (*original_TrueDivide)(HPyContext *ctx, HPy h1, HPy h2); -static HPy (*original_RichCompare)(HPyContext *ctx, HPy v, HPy w, int op); -static int (*original_RichCompareBool)(HPyContext *ctx, HPy v, HPy w, int op); - -static int augment_Is(HPyContext *ctx, HPy a, HPy b) { - uint64_t bitsA = toBits(a); - uint64_t bitsB = toBits(b); - if (bitsA == bitsB) { - return 1; - } else if (isBoxedHandle(bitsA) && isBoxedHandle(bitsB)) { - // This code assumes that objects pointed by a handle <= SINGLETON_HANDLES_MAX - // always get that same handle - uint64_t unboxedA = unboxHandle(bitsA); - uint64_t unboxedB = unboxHandle(bitsB); - if (unboxedA <= SINGLETON_HANDLES_MAX) { - return 0; - } else if (unboxedB <= SINGLETON_HANDLES_MAX) { - return 0; - } - // This code assumes that space[x] != NULL <=> objects pointed by x has native struct - void *dataA = get_handle_native_data_pointer(ctx, unboxedA); - void *dataB = get_handle_native_data_pointer(ctx, unboxedB); - if (dataA == NULL && dataB == NULL) { - return original_Is(ctx, a, b); - } - return dataA == dataB; - } else { - return 0; - } -} - -static int augment_IsTrue(HPyContext *ctx, HPy h) { - uint64_t bits = toBits(h); - if (isBoxedInt(bits)) { - return unboxInt(bits) != 0; - } else if (isBoxedDouble(bits)) { - return unboxDouble(bits) != 0.0; - } else if (augment_Is(ctx, ctx->h_None, h)) { - return 0; - } - return original_IsTrue(ctx, h); -} - -static void *augment_AsStruct_Object(HPyContext *ctx, HPy h) { - uint64_t bits = toBits(h); - if (isBoxedHandle(bits)) { - return get_handle_native_data_pointer(ctx, bits); - } else { - return NULL; - } -} - -static HPy augment_Long(HPyContext *ctx, HPy h) { - uint64_t bits = toBits(h); - if (isBoxedInt(bits)) { - return h; - } else if (isBoxedDouble(bits)) { - double v = unboxDouble(bits); - return toPtr(boxInt((int) v)); - } - return original_Long(ctx, h); -} - -static HPy augment_Float_FromDouble(HPyContext *ctx, double v) { - return toPtr(boxDouble(v)); -} - -static double augment_Float_AsDouble(HPyContext *ctx, HPy h) { - uint64_t bits = toBits(h); - if (isBoxedDouble(bits)) { - return unboxDouble(bits); - } else if (isBoxedInt(bits)) { - return unboxInt(bits); - } else { - return original_Float_AsDouble(ctx, h); - } -} - -static int32_t augment_Long_AsInt32_t(HPyContext *ctx, HPy h) { - uint64_t bits = toBits(h); - if (isBoxedInt(bits)) { - return unboxInt(bits); - } else { - return original_Long_AsInt32_t(ctx, h); - } -} - -static int64_t augment_Long_AsInt64_t(HPyContext *ctx, HPy h) { - uint64_t bits = toBits(h); - if (isBoxedInt(bits)) { - return unboxInt(bits); - } else { - return original_Long_AsInt64_t(ctx, h); - } -} - -static uint32_t augment_Long_AsUInt32_t(HPyContext *ctx, HPy h) { - uint64_t bits = toBits(h); - if (isBoxedInt(bits)) { - int32_t unboxed = unboxInt(bits); - if (unboxed >= 0) { - return unboxed; - } - } - return original_Long_AsUInt32_t(ctx, h); -} - -static HPy_ssize_t augment_Long_AsSsize_t(HPyContext *ctx, HPy h) { - uint64_t bits = toBits(h); - if (isBoxedInt(bits)) { - int32_t unboxed = unboxInt(bits); - if (unboxed >= 0) { - return unboxed; - } - } - return original_Long_AsSsize_t(ctx, h); -} - -static size_t augment_Long_AsSize_t(HPyContext *ctx, HPy h) { - uint64_t bits = toBits(h); - if (isBoxedInt(bits)) { - int32_t unboxed = unboxInt(bits); - if (unboxed >= 0) { - return unboxed; - } - } - return original_Long_AsSize_t(ctx, h); -} - -static double augment_Long_AsDouble(HPyContext *ctx, HPy h) { - uint64_t bits = toBits(h); - if (isBoxedInt(bits)) { - return unboxInt(bits); - } else { - return original_Long_AsDouble(ctx, h); - } -} - -static HPy augment_Long_FromInt32_t(HPyContext *ctx, int32_t l) { - return toPtr(boxInt(l)); -} - -static HPy augment_Long_FromUInt32_t(HPyContext *ctx, uint32_t l) { - if (isBoxableUnsignedInt(l)) { - return toPtr(boxInt((int32_t) l)); - } else { - return original_Long_FromUInt32_t(ctx, l); - } -} - -static HPy augment_Long_FromInt64_t(HPyContext *ctx, int64_t l) { - if (isBoxableInt(l)) { - return toPtr(boxInt((int32_t) l)); - } else { - return original_Long_FromInt64_t(ctx, l); - } -} - -static HPy augment_Long_FromUInt64_t(HPyContext *ctx, uint64_t l) { - if (isBoxableUnsignedInt(l)) { - return toPtr(boxInt((int32_t) l)); - } else { - return original_Long_FromUInt64_t(ctx, l); - } -} - -static HPy augment_Long_FromSsize_t(HPyContext *ctx, HPy_ssize_t l) { - if (isBoxableInt(l)) { - return toPtr(boxInt((int32_t) l)); - } else { - return original_Long_FromSsize_t(ctx, l); - } -} - -static HPy augment_Long_FromSize_t(HPyContext *ctx, size_t l) { - if (isBoxableUnsignedInt(l)) { - return toPtr(boxInt((int32_t) l)); - } else { - return original_Long_FromSize_t(ctx, l); - } -} - -static void augment_Close(HPyContext *ctx, HPy h) { - uint64_t bits = toBits(h); - if (!bits) { - return; - } else if (isBoxedHandle(bits)) { - if (bits < IMMUTABLE_HANDLES) { - return; - } - if (unclosedHandleTop < MAX_UNCLOSED_HANDLES) { - unclosedHandles[unclosedHandleTop++] = h; - } else { - upcallBulkClose(ctx, unclosedHandles, unclosedHandleTop); - memset(unclosedHandles, 0, sizeof(uint64_t) * unclosedHandleTop); - unclosedHandleTop = 0; - } - } -} - -static HPy augment_Dup(HPyContext *ctx, HPy h) { - uint64_t bits = toBits(h); - if (isBoxedHandle(bits)) { - if (bits < IMMUTABLE_HANDLES) { - return h; - } - return original_Dup(ctx, h); - } else { - return h; - } -} - -static int augment_Number_Check(HPyContext *ctx, HPy obj) { - uint64_t bits = toBits(obj); - if (isBoxedDouble(bits) || isBoxedInt(bits)) { - return true; - } else { - return original_Number_Check(ctx, obj); - } -} - -static int augment_TypeCheck(HPyContext *ctx, HPy obj, HPy type) { - uint64_t bits = toBits(obj); - if (isBoxedInt(bits)) { - return toBits(type) == toBits(ctx->h_LongType) || toBits(type) == toBits(ctx->h_BaseObjectType); - } else if (isBoxedDouble(bits)) { - return toBits(type) == toBits(ctx->h_FloatType) || toBits(type) == toBits(ctx->h_BaseObjectType); - } - return original_TypeCheck(ctx, obj, type); -} - -static int augment_List_Check(HPyContext *ctx, HPy obj) { - uint64_t bits = toBits(obj); - if (isBoxedHandle(bits)) { - return original_List_Check(ctx, obj); - } else { - return false; - } -} - -HPy augment_Global_Load(HPyContext *ctx, HPyGlobal global) { - uint64_t bits = toBits(global); - if (bits && isBoxedHandle(bits)) { - return original_Global_Load(ctx, global); - } else { - return toPtr(bits); - } -} - -void augment_Global_Store(HPyContext *ctx, HPyGlobal *global, HPy h) { - uint64_t bits = toBits(h); - if (bits && isBoxedHandle(bits)) { - original_Global_Store(ctx, global, h); - } else { - global->_i = h._i; - } -} - -HPy augment_Field_Load(HPyContext *ctx, HPy source_object, HPyField source_field) { - uint64_t bits = toBits(source_field); - if (bits && isBoxedHandle(bits)) { - return original_Field_Load(ctx, source_object, source_field); - } else { - return toPtr(bits); - } -} - -void augment_Field_Store(HPyContext *ctx, HPy target_object, HPyField *target_field, HPy h) { - uint64_t bits = toBits(h); - if (bits && isBoxedHandle(bits)) { - original_Field_Store(ctx, target_object, target_field, h); - } else { - target_field->_i = h._i; - } -} - -HPy augment_Type(HPyContext *ctx, HPy obj) { - uint64_t bits = toBits(obj); - if (isBoxedInt(bits)) { - return augment_Dup(ctx, ctx->h_LongType); - } else if (isBoxedDouble(bits)) - return augment_Dup(ctx, ctx->h_FloatType); - if (bits && isBoxedHandle(bits)) { - return original_Type(ctx, obj); - } else { - return toPtr(bits); - } -} - -#define GENERATE_AUGMENTED_BINOP(NAME, OP) \ - static HPy augment_##NAME(HPyContext *ctx, HPy h1, HPy h2) { \ - uint64_t bits1 = toBits(h1); \ - uint64_t bits2 = toBits(h2); \ - if (isBoxedInt(bits1) && isBoxedInt(bits2)) { \ - int64_t i1 = (int64_t) unboxInt(bits1); \ - int64_t i2 = (int64_t) unboxInt(bits2); \ - return augment_Long_FromInt64_t(ctx, i1 OP i2); \ - } else if (isBoxedInt(bits1) && isBoxedDouble(bits2)) { \ - int32_t i1 = unboxInt(bits1); \ - double f2 = unboxDouble(bits2); \ - return augment_Float_FromDouble(ctx, i1 OP f2); \ - } else if (isBoxedDouble(bits1) && isBoxedInt(bits2)) { \ - double f1 = unboxDouble(bits1); \ - int32_t i2 = unboxInt(bits2); \ - return augment_Float_FromDouble(ctx, f1 OP i2); \ - } else if (isBoxedDouble(bits1) && isBoxedDouble(bits2)) { \ - double f1 = unboxDouble(bits1); \ - double f2 = unboxDouble(bits2); \ - return augment_Float_FromDouble(ctx, f1 OP f2); \ - } \ - return original_##NAME(ctx, h1, h2); \ - } - -GENERATE_AUGMENTED_BINOP(Add, +) -GENERATE_AUGMENTED_BINOP(Subtract, -) -GENERATE_AUGMENTED_BINOP(Multiply, *) - -static HPy augment_FloorDivide(HPyContext *ctx, HPy h1, HPy h2) { - uint64_t bits1 = toBits(h1); - uint64_t bits2 = toBits(h2); - if (isBoxedInt(bits1) && isBoxedInt(bits2)) { - int32_t i1 = unboxInt(bits1); - int32_t i2 = unboxInt(bits2); - if (i2 == 0) { - HPyErr_SetString(ctx, ctx->h_ZeroDivisionError, "division by zero"); - return HPy_NULL; - } - return augment_Long_FromInt64_t(ctx, i1 / i2); - } - return original_FloorDivide(ctx, h1, h2); -} - -static HPy augment_TrueDivide(HPyContext *ctx, HPy h1, HPy h2) { - uint64_t bits1 = toBits(h1); - uint64_t bits2 = toBits(h2); - if (isBoxedInt(bits1) && isBoxedInt(bits2)) { - int32_t i2 = unboxInt(bits2); - if (i2 == 0) { - goto div_by_zero; - } - double f1 = (double) unboxInt(bits1); - return augment_Float_FromDouble(ctx, f1 / i2); - } else if (isBoxedInt(bits1) && isBoxedDouble(bits2)) { - int32_t i1 = unboxInt(bits1); - double f2 = unboxDouble(bits2); - if (f2 == 0.0) { - goto div_by_zero; - } - return augment_Float_FromDouble(ctx, i1 / f2); - } else if (isBoxedDouble(bits1) && isBoxedInt(bits2)) { - double f1 = unboxDouble(bits1); - int32_t i2 = unboxInt(bits2); - if (i2 == 0) { - goto div_by_zero; - } - return augment_Float_FromDouble(ctx, f1 / i2); - } else if (isBoxedDouble(bits1) && isBoxedDouble(bits2)) { - double f1 = unboxDouble(bits1); - double f2 = unboxDouble(bits2); - if (f2 == 0.0) { - goto div_by_zero; - } - return augment_Float_FromDouble(ctx, f1 / f2); - } - return original_TrueDivide(ctx, h1, h2); -div_by_zero: - HPyErr_SetString(ctx, ctx->h_ZeroDivisionError, "division by zero"); - return HPy_NULL; -} - -#define HPy_RETURN_RICHCOMPARE_BOOL(ctx, val1, val2, op) \ - do { \ - int result; \ - switch (op) { \ - case HPy_EQ: result = ((val1) == (val2)); break; \ - case HPy_NE: result = ((val1) != (val2)); break; \ - case HPy_LT: result = ((val1) < (val2)); break; \ - case HPy_GT: result = ((val1) > (val2)); break; \ - case HPy_LE: result = ((val1) <= (val2)); break; \ - case HPy_GE: result = ((val1) >= (val2)); break; \ - default: \ - HPy_FatalError(ctx, "Invalid value for HPy_RichCmpOp"); \ - } \ - return result; \ - } while (0) - -static inline int richcompare_boxed_values(HPyContext *ctx, uint64_t vbits, uint64_t wbits, int op) { - if (isBoxedInt(vbits)) { - if (isBoxedInt(wbits)) { - HPy_RETURN_RICHCOMPARE_BOOL(ctx, unboxInt(vbits), unboxInt(wbits), op); - } else { - assert(isBoxedDouble(wbits)); - HPy_RETURN_RICHCOMPARE_BOOL(ctx, unboxInt(vbits), unboxDouble(wbits), op); - } - } else { - assert(isBoxedDouble(vbits)); - if (isBoxedInt(wbits)) { - HPy_RETURN_RICHCOMPARE_BOOL(ctx, unboxDouble(vbits), unboxInt(wbits), op); - } else { - assert(isBoxedDouble(wbits)); - HPy_RETURN_RICHCOMPARE_BOOL(ctx, unboxDouble(vbits), unboxDouble(wbits), op); - } - } -} - -static HPy augment_RichCompare(HPyContext *ctx, HPy v, HPy w, int op) { - uint64_t vbits = toBits(v); - uint64_t wbits = toBits(w); - int result; - if (!isBoxedHandle(vbits) && !isBoxedHandle(wbits)) { - result = richcompare_boxed_values(ctx, vbits, wbits, op); - if (result) - return HPy_Dup(ctx, ctx->h_True); - return HPy_Dup(ctx, ctx->h_False); - } - return original_RichCompare(ctx, v, w, op); -} - -static int augment_RichCompareBool(HPyContext *ctx, HPy v, HPy w, int op) { - uint64_t vbits = toBits(v); - uint64_t wbits = toBits(w); - if (!isBoxedHandle(vbits) && !isBoxedHandle(wbits)) { - return richcompare_boxed_values(ctx, vbits, wbits, op); - } - return original_RichCompareBool(ctx, v, w, op); -} - -void init_native_fast_paths(HPyContext *context) { - LOG("%p", context); - -#define AUGMENT(name) \ - original_ ## name = context->ctx_ ## name; \ - context->ctx_ ## name = augment_ ## name; - - AUGMENT(Float_FromDouble); - AUGMENT(Float_AsDouble); - - AUGMENT(Long); - AUGMENT(Long_AsInt32_t); - AUGMENT(Long_AsInt64_t); - AUGMENT(Long_AsUInt32_t); - AUGMENT(Long_AsDouble); - AUGMENT(Long_AsSsize_t); - AUGMENT(Long_AsSize_t); - AUGMENT(Long_FromInt32_t); - AUGMENT(Long_FromUInt32_t); - AUGMENT(Long_FromInt64_t); - AUGMENT(Long_FromUInt64_t); - AUGMENT(Long_FromSsize_t); - AUGMENT(Long_FromSize_t); - - AUGMENT(Dup); - AUGMENT(Close); - - AUGMENT(AsStruct_Object); - context->ctx_AsStruct_Legacy = augment_AsStruct_Object; - context->ctx_AsStruct_Float = augment_AsStruct_Object; - context->ctx_AsStruct_List = augment_AsStruct_Object; - context->ctx_AsStruct_Long = augment_AsStruct_Object; - context->ctx_AsStruct_Type = augment_AsStruct_Object; - context->ctx_AsStruct_Unicode = augment_AsStruct_Object; - context->ctx_AsStruct_Tuple = augment_AsStruct_Object; - - - AUGMENT(Number_Check); - - AUGMENT(TypeCheck); - - AUGMENT(List_Check); - - AUGMENT(Global_Load); - AUGMENT(Global_Store); - - AUGMENT(Field_Load); - AUGMENT(Field_Store); - - AUGMENT(Is); - AUGMENT(IsTrue); - - AUGMENT(Type); - - AUGMENT(Add); - AUGMENT(Subtract); - AUGMENT(Multiply); - AUGMENT(FloorDivide); - AUGMENT(TrueDivide); - - AUGMENT(RichCompare); - AUGMENT(RichCompareBool); - -#undef AUGMENT -} diff --git a/graalpython/com.oracle.graal.python.jni/src/hpy_native_fast_paths.h b/graalpython/com.oracle.graal.python.jni/src/hpy_native_fast_paths.h deleted file mode 100644 index 7fb7582366..0000000000 --- a/graalpython/com.oracle.graal.python.jni/src/hpy_native_fast_paths.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - - -#ifndef HPY_NATIVE_FAST_PATHS_H_ -#define HPY_NATIVE_FAST_PATHS_H_ - -//************************* -// BOXING - -#define NAN_BOXING_BASE (0x0007000000000000llu) -#define NAN_BOXING_MASK (0xFFFF000000000000llu) -#define NAN_BOXING_INT (0x0001000000000000llu) -#define NAN_BOXING_INT_MASK (0x00000000FFFFFFFFllu) -#define NAN_BOXING_MAX_HANDLE (0x000000007FFFFFFFllu) -#define IMMUTABLE_HANDLES (0x0000000000000100llu) - -// Some singleton Python objects are guaranteed to be always represented by -// those handles, so that we do not have to upcall to unambiguously check if -// a handle represents one of those -#define SINGLETON_HANDLES_MAX (3) - -#define isBoxedDouble(value) ((value) >= NAN_BOXING_BASE) -#define isBoxedHandle(value) ((value) <= NAN_BOXING_MAX_HANDLE) -#define isBoxedInt(value) (((value) & NAN_BOXING_MASK) == NAN_BOXING_INT) - -#define unboxHandle(value) (value) -#define boxHandle(handle) (handle) - -#define isBoxableInt(value) (INT32_MIN < (value) && (value) < INT32_MAX) -#define isBoxableUnsignedInt(value) ((value) < INT32_MAX) -#define unboxInt(value) ((int32_t) ((value) - NAN_BOXING_INT)) -#define boxInt(value) ((((uint64_t) (value)) & NAN_BOXING_INT_MASK) + NAN_BOXING_INT) - -#define toBits(ptr) ((uint64_t) ((ptr)._i)) -#define toPtr(ptr) ((HPy) { (HPy_ssize_t) (ptr) }) - -//************************* -// native HPyTracker implementation - -typedef struct { - HPy_ssize_t capacity; // allocated handles - HPy_ssize_t length; // used handles - HPy *handles; -} _HPyTracker_s; - -static inline _HPyTracker_s *_ht2hp(HPyTracker ht) { - return (_HPyTracker_s *) (ht)._i; -} -static inline HPyTracker _hp2ht(_HPyTracker_s *hp) { - return (HPyTracker) {(HPy_ssize_t) (hp)}; -} - -void init_native_fast_paths(HPyContext *context); - -#endif /* HPY_NATIVE_FAST_PATHS_H_ */ diff --git a/graalpython/com.oracle.graal.python.jni/src/trace/include/hpy_trace.h b/graalpython/com.oracle.graal.python.jni/src/trace/include/hpy_trace.h deleted file mode 100644 index 70d6320239..0000000000 --- a/graalpython/com.oracle.graal.python.jni/src/trace/include/hpy_trace.h +++ /dev/null @@ -1,66 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef HPY_TRACE_H -#define HPY_TRACE_H - -#include "hpy.h" - -/* - This is the main public API for the trace mode, and it's meant to be used - by hpy.universal implementations (including but not limited to the - CPython's version of hpy.universal which is included in this repo). - - The idea is that for every uctx there is a corresponding unique tctx which - wraps it. - - If you call hpy_trace_get_ctx twice on the same uctx, you get the same - result. -*/ - -HPyContext * hpy_trace_get_ctx(HPyContext *uctx); -int hpy_trace_ctx_init(HPyContext *tctx, HPyContext *uctx); -int hpy_trace_ctx_free(HPyContext *tctx); -int hpy_trace_get_nfunc(void); -const char * hpy_trace_get_func_name(int idx); - -// this is the HPy init function created by HPy_MODINIT. In CPython's version -// of hpy.universal the code is embedded inside the extension, so we can call -// this function directly instead of dlopen it. This is similar to what -// CPython does for its own built-in modules. But we must use the same -// signature as HPy_MODINIT - -#ifdef ___cplusplus -extern "C" -#endif -HPy_EXPORTED_SYMBOL -HPyModuleDef* HPyInit__trace(); - -#ifdef ___cplusplus -extern "C" -#endif -HPy_EXPORTED_SYMBOL -void HPyInitGlobalContext__trace(HPyContext *ctx); - -#endif /* HPY_TRACE_H */ diff --git a/graalpython/com.oracle.graal.python.pegparser.generator/asdl/asdl_java.py b/graalpython/com.oracle.graal.python.pegparser.generator/asdl/asdl_java.py index 77b684f9d4..0b1c8e852f 100755 --- a/graalpython/com.oracle.graal.python.pegparser.generator/asdl/asdl_java.py +++ b/graalpython/com.oracle.graal.python.pegparser.generator/asdl/asdl_java.py @@ -1,4 +1,4 @@ -# Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -44,7 +44,6 @@ from asdl import java_file from asdl import model - SST_PACKAGE = 'com.oracle.graal.python.pegparser.sst' AST_PACKAGE = 'com.oracle.graal.python.builtins.modules.ast' @@ -285,7 +284,7 @@ def visit_abstract_class(self, c: model.AbstractClass, emitter: java_file.Emitte def visit_concrete_class(self, c: model.ConcreteClass, emitter: java_file.Emitter): with emitter.define(f'public Object visit({c.full_name} node)', '@Override'): - emitter.println(f'PythonObject o = factory.createPythonObject(state.{c.name.cls_field});') + emitter.println(f'PythonObject o = createPythonObject(state.{c.name.cls_field});') for f in c.fields: self.visit(f, emitter) if c.outer_has_attributes or c.attributes: @@ -338,6 +337,7 @@ def visit_module(self, module: model.Module): @staticmethod def emit_imports(module, emitter): emitter.println() + emitter.println('import com.oracle.truffle.api.nodes.Node;') emitter.println('import com.oracle.graal.python.builtins.objects.PNone;') emitter.println('import com.oracle.graal.python.pegparser.sst.ConstantValue;') top_level_class_names = [t.name.java for t in module.types] @@ -346,8 +346,8 @@ def emit_imports(module, emitter): emitter.println('import com.oracle.graal.python.pegparser.tokenizer.SourceRange;') def emit_constructor(self, emitter: java_file.Emitter): - with emitter.define(f'{self.CLASS_NAME}({AstStateGenerator.CLASS_NAME} state)'): - emitter.println('super(state);') + with emitter.define(f'{self.CLASS_NAME}(Node node, {AstStateGenerator.CLASS_NAME} state)'): + emitter.println('super(node, state);') @staticmethod def visit_enum(c: model.Enum, emitter: java_file.Emitter): diff --git a/graalpython/com.oracle.graal.python.pegparser.generator/asdl/java_file.py b/graalpython/com.oracle.graal.python.pegparser.generator/asdl/java_file.py index 8119ee2fa9..8c37571e8b 100644 --- a/graalpython/com.oracle.graal.python.pegparser.generator/asdl/java_file.py +++ b/graalpython/com.oracle.graal.python.pegparser.generator/asdl/java_file.py @@ -1,4 +1,4 @@ -# Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -42,7 +42,7 @@ from typing import Optional HEADER = """/* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser.test/src/com/oracle/graal/python/pegparser/test/LambdaInFunctionTests.java b/graalpython/com.oracle.graal.python.pegparser.test/src/com/oracle/graal/python/pegparser/test/LambdaInFunctionTests.java index 270463582c..9734ede0f0 100644 --- a/graalpython/com.oracle.graal.python.pegparser.test/src/com/oracle/graal/python/pegparser/test/LambdaInFunctionTests.java +++ b/graalpython/com.oracle.graal.python.pegparser.test/src/com/oracle/graal/python/pegparser/test/LambdaInFunctionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser.test/src/com/oracle/graal/python/pegparser/test/YieldStatementTests.java b/graalpython/com.oracle.graal.python.pegparser.test/src/com/oracle/graal/python/pegparser/test/YieldStatementTests.java index 4c8f52b4bf..974894ae9d 100644 --- a/graalpython/com.oracle.graal.python.pegparser.test/src/com/oracle/graal/python/pegparser/test/YieldStatementTests.java +++ b/graalpython/com.oracle.graal.python.pegparser.test/src/com/oracle/graal/python/pegparser/test/YieldStatementTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/AbstractParser.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/AbstractParser.java index e7ae80ab58..9aeab9237d 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/AbstractParser.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/AbstractParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -52,6 +52,8 @@ import java.util.List; import java.util.function.Supplier; +import org.graalvm.shadowed.com.ibm.icu.text.Normalizer2; + import com.oracle.graal.python.pegparser.sst.ArgTy; import com.oracle.graal.python.pegparser.sst.CmpOpTy; import com.oracle.graal.python.pegparser.sst.ComprehensionTy; @@ -350,7 +352,7 @@ public Token getLastNonWhitespaceToken() { public ExprTy.Name name_token() { Token t = expect(Token.Kind.NAME); if (t != null) { - return factory.createVariable(getText(t), t.sourceRange); + return name_from_token(t); } else { return null; } @@ -504,6 +506,13 @@ public ExprTy.Name name_from_token(Token t) { return null; } String id = getText(t); + for (int i = 0; i < id.length(); i++) { + if (id.charAt(i) > 0xff) { + // If the identifier is not ASCII, normalize it according to PEP 3131 + id = Normalizer2.getNFKCInstance().normalize(id); + break; + } + } return factory.createVariable(id, t.sourceRange); } diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/scope/Scope.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/scope/Scope.java index d0c299cd24..07cde10a2f 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/scope/Scope.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/scope/Scope.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -229,11 +229,15 @@ public boolean isNested() { } public HashMap getSymbolsByType(EnumSet expectedFlags, int start) { + return getSymbolsByType(expectedFlags, EnumSet.noneOf(DefUse.class), start); + } + + public HashMap getSymbolsByType(EnumSet expectedFlags, EnumSet unexpectedFlags, int start) { int i = start; HashMap mapping = new HashMap<>(); for (String key : getSortedSymbols()) { EnumSet keyFlags = getUseOfName(key); - if (!Collections.disjoint(expectedFlags, keyFlags)) { + if (!Collections.disjoint(expectedFlags, keyFlags) && Collections.disjoint(unexpectedFlags, keyFlags)) { mapping.put(key, i++); } } diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/scope/ScopeEnvironment.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/scope/ScopeEnvironment.java index 2005dd65e2..bf816b5b0e 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/scope/ScopeEnvironment.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/scope/ScopeEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -98,6 +98,7 @@ public class ScopeEnvironment { final HashMap blocks = new HashMap<>(); final ErrorCallback errorCallback; final EnumSet futureFeatures; + final HashMap parents = new HashMap<>(); public static ScopeEnvironment analyze(ModTy moduleNode, ErrorCallback errorCallback, EnumSet futureFeatures) { return new ScopeEnvironment(moduleNode, errorCallback, futureFeatures); @@ -128,6 +129,14 @@ public Scope lookupScope(SSTNode node) { return blocks.get(node); } + public Scope lookupParent(Scope scope) { + return parents.get(scope); + } + + public Scope getTopScope() { + return topScope; + } + private void analyzeBlock(Scope scope, HashSet bound, HashSet free, HashSet global) { HashSet local = new HashSet<>(); HashMap scopes = new HashMap<>(); @@ -328,6 +337,7 @@ private void enterBlock(String name, Scope.ScopeType type, SSTNode ast) { if (type == Scope.ScopeType.Annotation) { return; } + env.parents.put(scope, prev); if (prev != null) { prev.children.add(scope); } diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/AliasTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/AliasTy.java index cfd2343286..a492e85003 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/AliasTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/AliasTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ArgTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ArgTy.java index 0ace1cb17e..07c350cef1 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ArgTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ArgTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ArgumentsTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ArgumentsTy.java index 1d783c4a0f..f73083ec50 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ArgumentsTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ArgumentsTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/BoolOpTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/BoolOpTy.java index 0717d0a435..e62e44bcb0 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/BoolOpTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/BoolOpTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/CmpOpTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/CmpOpTy.java index 1b881e99a0..2f154eb844 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/CmpOpTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/CmpOpTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ComprehensionTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ComprehensionTy.java index 4beed845a8..f42a5e1427 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ComprehensionTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ComprehensionTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ExceptHandlerTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ExceptHandlerTy.java index 9efab27d5d..6c0aa13c2f 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ExceptHandlerTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ExceptHandlerTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ExprContextTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ExprContextTy.java index a4b09cfdfb..e6f4f850b1 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ExprContextTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ExprContextTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ExprTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ExprTy.java index 4612ccb74c..1fb5d88c9d 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ExprTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ExprTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/KeywordTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/KeywordTy.java index ef64367a15..32aeca4faf 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/KeywordTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/KeywordTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/MatchCaseTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/MatchCaseTy.java index 1a883ad89d..f7f80b4fd7 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/MatchCaseTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/MatchCaseTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ModTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ModTy.java index a0bd22ed37..6ea70dcabe 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ModTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/ModTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/OperatorTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/OperatorTy.java index 43d5c410fa..15222bba8b 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/OperatorTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/OperatorTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/PatternTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/PatternTy.java index 1dcbb13df8..4b6ff77335 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/PatternTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/PatternTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/SSTreeVisitor.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/SSTreeVisitor.java index 8b22fd364b..9a48161b32 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/SSTreeVisitor.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/SSTreeVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/StmtTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/StmtTy.java index 02b3cdcf05..ac67e6076c 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/StmtTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/StmtTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/TypeIgnoreTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/TypeIgnoreTy.java index a66076b4ac..c5952df203 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/TypeIgnoreTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/TypeIgnoreTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/UnaryOpTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/UnaryOpTy.java index b3805a57b9..03b2e2d6a6 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/UnaryOpTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/UnaryOpTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/WithItemTy.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/WithItemTy.java index 69665b12cb..7a102ea40f 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/WithItemTy.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/sst/WithItemTy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/tokenizer/Tokenizer.java b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/tokenizer/Tokenizer.java index 678cf0a537..d05779be5d 100644 --- a/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/tokenizer/Tokenizer.java +++ b/graalpython/com.oracle.graal.python.pegparser/src/com/oracle/graal/python/pegparser/tokenizer/Tokenizer.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2021, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2021, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2021 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -566,7 +566,7 @@ private static String verifyIdentifier(String tokenString) { if (cp != '_' && !UCharacter.hasBinaryProperty(cp, UProperty.XID_START)) { invalid = 0; } - for (int i = 1; i < invalid;) { + for (int i = Character.charCount(cp); i < invalid;) { cp = tokenString.codePointAt(i); if (!UCharacter.hasBinaryProperty(cp, UProperty.XID_CONTINUE)) { invalid = i; diff --git a/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/ArgumentClinicProcessor.java b/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/ArgumentClinicProcessor.java index 25e10bab85..2bc7b0bbe9 100644 --- a/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/ArgumentClinicProcessor.java +++ b/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/ArgumentClinicProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -83,6 +83,7 @@ public class ArgumentClinicProcessor extends AbstractProcessor { private static final boolean LOGGING = false; private static final String BuiltinAnnotationClass = "com.oracle.graal.python.builtins.Builtin"; + private static final String SlotSignatureAnnotationClass = "com.oracle.graal.python.annotations.Slot.SlotSignature"; private static final String BuiltinsAnnotationClass = "com.oracle.graal.python.builtins.Builtins"; private static final String BUILTINS_BASE_CLASSES_PACKAGE = "com.oracle.graal.python.nodes.function.builtins"; @@ -360,6 +361,9 @@ private static BuiltinAnnotation getBuiltinAnnotation(TypeElement type) throws P int minNumOfPositionalArgs = -1; boolean takesVarArgs = false; AnnotationMirror annot = findAnnotationMirror(type, BuiltinAnnotationClass); + if (annot == null) { + annot = findAnnotationMirror(type, SlotSignatureAnnotationClass); + } if (annot == null) { annot = findAnnotationMirror(type, BuiltinsAnnotationClass); if (annot != null) { diff --git a/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/CApiBuiltinsProcessor.java b/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/CApiBuiltinsProcessor.java index f8635ea096..976ef3488b 100644 --- a/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/CApiBuiltinsProcessor.java +++ b/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/CApiBuiltinsProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -69,7 +69,7 @@ import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.AbstractAnnotationValueVisitor14; -import javax.lang.model.util.ElementFilter; +import javax.tools.Diagnostic.Kind; import javax.tools.StandardLocation; import com.oracle.graal.python.annotations.CApiConstants; @@ -121,8 +121,8 @@ public synchronized void init(ProcessingEnvironment pe) { try { this.trees = Trees.instance(pe); } catch (Throwable t) { - // ECJ does not support this, so we skip the some processing of C API builtins - pe.getMessager().printWarning("The compiler does not support source tree parsing during annotation processing. Regeneration of Python C API builtins will be incorrect."); + // ECJ does not support this, so we skip the processing of C API builtins + pe.getMessager().printMessage(Kind.NOTE, "The compiler does not support source tree parsing during annotation processing. Regeneration of Python C API builtins will be incorrect."); this.trees = null; } } @@ -560,10 +560,8 @@ private void updateResource(String name, List javaBuiltins, Lis /** * Generates the builtin specification in capi.h, which includes only the builtins implemented * in Java code. Additionally, it generates helpers for all "Py_get_" and "Py_set_" builtins. - * - * @param methodFlags */ - private void generateCApiHeader(List javaBuiltins, Map methodFlags) throws IOException { + private void generateCApiHeader(List javaBuiltins) throws IOException { List lines = new ArrayList<>(); lines.add("#define CAPI_BUILTINS \\"); int id = 0; @@ -602,12 +600,6 @@ private void generateCApiHeader(List javaBuiltins, Map a.getValue().compareTo(b.getValue())).forEach(e -> lines.add("#define " + e.getKey() + " " + e.getValue())); updateResource("capi.gen.h", javaBuiltins, lines); } @@ -861,7 +853,6 @@ public boolean process(Set annotations, RoundEnvironment List constants = new ArrayList<>(); List fields = new ArrayList<>(); List structs = new ArrayList<>(); - Map methodFlags = new HashMap<>(); for (var el : re.getElementsAnnotatedWith(CApiConstants.class)) { if (el.getKind() == ElementKind.ENUM) { for (var enumBit : el.getEnclosedElements()) { @@ -869,13 +860,6 @@ public boolean process(Set annotations, RoundEnvironment constants.add(enumBit.getSimpleName().toString()); } } - } else if (el.getKind() == ElementKind.CLASS) { - for (VariableElement field : ElementFilter.fieldsIn(el.getEnclosedElements())) { - Object constantValue = field.getConstantValue(); - if (constantValue instanceof Long longValue) { - methodFlags.put(field.getSimpleName().toString(), longValue); - } - } } else { processingEnv.getMessager().printError(CApiConstants.class.getSimpleName() + " is only applicable for enums.", el); } @@ -910,7 +894,7 @@ public boolean process(Set annotations, RoundEnvironment if (trees != null) { // needs jdk.compiler generateCApiSource(allBuiltins, constants, fields, structs); - generateCApiHeader(javaBuiltins, methodFlags); + generateCApiHeader(javaBuiltins); } generateBuiltinRegistry(javaBuiltins); generateCApiAsserts(allBuiltins); diff --git a/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/ConverterFactory.java b/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/ConverterFactory.java index defc6ddde2..8303cd0f78 100644 --- a/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/ConverterFactory.java +++ b/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/ConverterFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -210,7 +210,8 @@ public static ConverterFactory[] getForClass(TypeElement conversionClass) throws private static ConverterFactory[] forBuiltin(Elements elementUtils, String className) throws ProcessingError { TypeElement type = elementUtils.getTypeElement(CLINIC_PACKAGE + "." + className); if (type == null) { - throw new ProcessingError(null, "Unable to find built-in argument clinic conversion node " + CLINIC_PACKAGE + "." + className); + throw new ProcessingError(null, "Unable to find built-in argument clinic conversion node " + CLINIC_PACKAGE + "." + className + + ". This may be also a sign that Truffle DSL annotation processor failed to process this class."); } return getForClass(type); } diff --git a/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/SlotsMapping.java b/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/SlotsMapping.java index 14ed5b28f2..d9a12cbd5f 100644 --- a/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/SlotsMapping.java +++ b/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/SlotsMapping.java @@ -52,47 +52,75 @@ private static String getSuffix(boolean isComplex) { static String getSlotBaseClass(Slot s) { return switch (s.value()) { case nb_bool -> "TpSlotInquiry.TpSlotInquiryBuiltin"; - case nb_index, nb_int, nb_float, nb_absolute, nb_positive, nb_negative, nb_invert -> "TpSlotUnaryFunc.TpSlotUnaryFuncBuiltin"; + case nb_index, nb_int, nb_float, nb_absolute, nb_positive, nb_negative, nb_invert, + tp_iter, tp_str, tp_repr, am_aiter, am_anext, am_await -> + "TpSlotUnaryFunc.TpSlotUnaryFuncBuiltin"; case nb_add, nb_subtract, nb_multiply, nb_remainder, nb_divmod, nb_lshift, nb_rshift, nb_and, nb_xor, nb_or, nb_floor_divide, nb_true_divide, nb_matrix_multiply -> "TpSlotBinaryOp.TpSlotBinaryOpBuiltin"; + case nb_inplace_add, nb_inplace_subtract, nb_inplace_multiply, nb_inplace_remainder, + nb_inplace_lshift, nb_inplace_rshift, nb_inplace_and, nb_inplace_xor, nb_inplace_or, + nb_inplace_floor_divide, nb_inplace_true_divide, nb_inplace_matrix_multiply, + sq_inplace_concat -> + "TpSlotBinaryOp.TpSlotBinaryIOpBuiltin"; + case nb_power -> "TpSlotNbPower.TpSlotNbPowerBuiltin"; + case nb_inplace_power -> null; // No builtin implementations case sq_concat -> "TpSlotBinaryFunc.TpSlotSqConcat"; case sq_length, mp_length -> "TpSlotLen.TpSlotLenBuiltin" + getSuffix(s.isComplex()); - case sq_item, sq_repeat -> "TpSlotSizeArgFun.TpSlotSizeArgFunBuiltin"; + case sq_item, sq_repeat, sq_inplace_repeat -> "TpSlotSizeArgFun.TpSlotSizeArgFunBuiltin"; case sq_ass_item -> "TpSlotSqAssItem.TpSlotSqAssItemBuiltin"; + case sq_contains -> "TpSlotSqContains.TpSlotSqContainsBuiltin"; case mp_subscript -> "TpSlotBinaryFunc.TpSlotMpSubscript"; case mp_ass_subscript -> "TpSlotMpAssSubscript.TpSlotMpAssSubscriptBuiltin"; case tp_getattro -> "TpSlotGetAttr.TpSlotGetAttrBuiltin"; + case tp_richcompare -> "TpSlotRichCompare.TpSlotRichCmpBuiltin" + getSuffix(s.isComplex()); case tp_descr_get -> "TpSlotDescrGet.TpSlotDescrGetBuiltin" + getSuffix(s.isComplex()); case tp_descr_set -> "TpSlotDescrSet.TpSlotDescrSetBuiltin"; case tp_setattro -> "TpSlotSetAttr.TpSlotSetAttrBuiltin"; + case tp_iternext -> "TpSlotIterNext.TpSlotIterNextBuiltin"; + case tp_hash -> "TpSlotHashFun.TpSlotHashBuiltin"; + case tp_init, tp_call -> "TpSlotVarargs.TpSlotVarargsBuiltin"; + case tp_new -> "TpSlotVarargs.TpSlotNewBuiltin"; }; } static String getSlotNodeBaseClass(Slot s) { return switch (s.value()) { + case tp_richcompare -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.RichCmpBuiltinNode"; case tp_descr_get -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.DescrGetBuiltinNode"; case nb_bool -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotInquiry.NbBoolBuiltinNode"; - case nb_index, nb_int, nb_float, nb_absolute, nb_positive, nb_negative, nb_invert -> "com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode"; + case nb_index, nb_int, nb_float, nb_absolute, nb_positive, nb_negative, nb_invert, + tp_iter, tp_iternext, tp_str, tp_repr, am_aiter, am_await, am_anext -> + "com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode"; case nb_add, nb_subtract, nb_multiply, nb_remainder, nb_divmod, nb_lshift, nb_rshift, nb_and, nb_xor, nb_or, nb_floor_divide, nb_true_divide, nb_matrix_multiply -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode"; + case nb_power, nb_inplace_power -> "com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode"; case sq_concat -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.SqConcatBuiltinNode"; + case nb_inplace_add, nb_inplace_subtract, nb_inplace_multiply, nb_inplace_remainder, + nb_inplace_lshift, nb_inplace_rshift, nb_inplace_and, nb_inplace_xor, nb_inplace_or, + nb_inplace_floor_divide, nb_inplace_true_divide, nb_inplace_matrix_multiply, + sq_inplace_concat -> + "com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode"; case sq_length, mp_length -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode"; case sq_item -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqItemBuiltinNode"; case sq_ass_item -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqAssItem.SqAssItemBuiltinNode"; - case sq_repeat -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqRepeatBuiltinNode"; + case sq_repeat, sq_inplace_repeat -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqRepeatBuiltinNode"; + case sq_contains -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode"; case mp_subscript -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode"; case mp_ass_subscript -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotMpAssSubscript.MpAssSubscriptBuiltinNode"; case tp_getattro -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.GetAttrBuiltinNode"; case tp_descr_set -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrSet.DescrSetBuiltinNode"; case tp_setattro -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotSetAttr.SetAttrBuiltinNode"; + case tp_hash -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode"; + case tp_init, tp_new, tp_call -> "com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode"; }; } static String getUncachedExecuteSignature(SlotKind s) { return switch (s) { case nb_bool -> "boolean executeUncached(Object self)"; + case tp_richcompare -> "Object executeUncached(Object self, Object obj, com.oracle.graal.python.lib.RichCmpOp op)"; case tp_descr_get -> "Object executeUncached(Object self, Object obj, Object type)"; case sq_length, mp_length -> "int executeUncached(Object self)"; default -> throw new AssertionError("Should not reach here: should be always complex"); @@ -108,7 +136,7 @@ static boolean supportsComplex(SlotKind s) { static boolean supportsSimple(SlotKind s) { return switch (s) { - case nb_bool, sq_length, mp_length, tp_descr_get -> true; + case nb_bool, sq_length, mp_length, tp_descr_get, tp_richcompare -> true; default -> false; }; } @@ -116,6 +144,7 @@ static boolean supportsSimple(SlotKind s) { static String getUncachedExecuteCall(SlotKind s) { return switch (s) { case nb_bool -> "executeBool(null, self)"; + case tp_richcompare -> "execute(null, self, obj, op)"; case sq_length, mp_length -> "executeInt(null, self)"; case tp_descr_get -> "execute(null, self, obj, type)"; default -> throw new AssertionError("Should not reach here: should be always complex"); @@ -144,6 +173,30 @@ public static String getExtraCtorArgs(TpSlotData slot) { case nb_floor_divide -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___FLOORDIV__"; case nb_true_divide -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___TRUEDIV__"; case nb_matrix_multiply -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___MATMUL__"; + case nb_inplace_add -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___IADD__"; + case nb_inplace_subtract -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___ISUB__"; + case nb_inplace_multiply -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___IMUL__"; + case nb_inplace_remainder -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___IMOD__"; + case nb_inplace_lshift -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___ILSHIFT__"; + case nb_inplace_rshift -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___IRSHIFT__"; + case nb_inplace_and -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___IAND__"; + case nb_inplace_xor -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___IXOR__"; + case nb_inplace_or -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___IOR__"; + case nb_inplace_floor_divide -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___IFLOORDIV__"; + case nb_inplace_true_divide -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___ITRUEDIV__"; + case nb_inplace_matrix_multiply -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___IMATMUL__"; + case sq_item -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___GETITEM__"; + case sq_repeat -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___MUL__"; + case sq_inplace_concat -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___IADD__"; + case sq_inplace_repeat -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___IMUL__"; + case tp_iter -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__"; + case tp_str -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__"; + case tp_repr -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__"; + case tp_init -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__"; + case tp_call -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__"; + case am_await -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___AWAIT__"; + case am_aiter -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___AITER__"; + case am_anext -> ", com.oracle.graal.python.nodes.SpecialMethodNames.J___ANEXT__"; default -> ""; }; } diff --git a/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/SlotsProcessor.java b/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/SlotsProcessor.java index 885f2ab22f..5e5abd6ea0 100644 --- a/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/SlotsProcessor.java +++ b/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/SlotsProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -63,6 +63,7 @@ import javax.tools.Diagnostic.Kind; import javax.tools.JavaFileObject; +import com.oracle.graal.python.annotations.HashNotImplemented; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.annotations.Slot.Slots; @@ -72,11 +73,27 @@ public class SlotsProcessor extends AbstractProcessor { private static final boolean LOGGING = false; public record TpSlotData(Slot slot, TypeElement enclosingType, TypeElement slotNodeType) { + public boolean isHashNotImplemented() { + return slotNodeType == null; + } + + public static TpSlotData createHashNotImplemented(TypeElement enclosingType) { + return new TpSlotData(null, enclosingType, null); + } + + public String builderCall() { + if (isHashNotImplemented()) { + return ".set(TpSlots.TpSlotMeta.TP_HASH, com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HASH_NOT_IMPLEMENTED)"; + } + return String.format(".set(TpSlots.TpSlotMeta.%s, %s.INSTANCE)", // + slot.value().name().toUpperCase(Locale.ROOT), // + getSlotImplName(slot.value())); + } } @Override public Set getSupportedAnnotationTypes() { - return Set.of(Slot.class.getName()); + return Set.of(Slot.class.getName(), HashNotImplemented.class.getName()); } @Override @@ -109,7 +126,14 @@ private void doProcess(RoundEnvironment roundEnv) throws IOException, Processing private void validate(HashMap> enclosingTypes) throws ProcessingError { var typeCache = new TypeCache(processingEnv); for (Entry> enclosingType : enclosingTypes.entrySet()) { + boolean seenHashNotImplemented = false; + boolean seenHash = false; for (TpSlotData slot : enclosingType.getValue()) { + if (slot.isHashNotImplemented()) { + seenHashNotImplemented = true; + continue; + } + seenHash |= slot.slot.value() == SlotKind.tp_hash; if (slot.slot.isComplex()) { if (!SlotsMapping.supportsComplex(slot.slot().value())) { throw error(slot.slotNodeType, "Slot does not support complex builtins. The support can be added."); @@ -125,14 +149,22 @@ private void validate(HashMap> enclosingTypes) thro throw error(slot.slotNodeType, "Slot does not inherit from expected base class '%s'", baseName); } } + if (seenHash && seenHashNotImplemented) { + throw error(enclosingType.getKey(), "Annotation %s cannot be use when there is also %s(tp_hash). Remove one or the other.", + HashNotImplemented.class.getSimpleName(), + Slot.class.getSimpleName()); + } } } @SuppressWarnings("try") private void writeCode(HashMap> enclosingTypes) throws IOException { - for (Entry> enclosingType : enclosingTypes.entrySet()) { - String pkgName = getPackage(enclosingType.getKey()); - String className = enclosingType.getKey().getSimpleName() + "SlotsGen"; + for (Entry> enclosingTypeAndSlots : enclosingTypes.entrySet()) { + Set slots = enclosingTypeAndSlots.getValue(); + TypeElement enclosingType = enclosingTypeAndSlots.getKey(); + + String pkgName = getPackage(enclosingType); + String className = enclosingType.getSimpleName() + "SlotsGen"; String sourceFile = pkgName + "." + className; log("Generating file '%s'", sourceFile); @@ -146,10 +178,10 @@ private void writeCode(HashMap> enclosingTypes) thr w.writeLn(); w.writeLn("public class %s {", className); try (Block i = w.newIndent()) { - for (TpSlotData slot : enclosingType.getValue()) { + for (TpSlotData slot : slots) { writeSlot(w, slot); } - writeSlotsStaticField(w, enclosingType.getValue()); + writeSlotsStaticField(w, enclosingType, slots); } w.writeLn("}"); } @@ -168,6 +200,9 @@ private void writeImports(CodeWriter w) throws IOException { @SuppressWarnings("try") private void writeSlot(CodeWriter w, TpSlotData slot) throws IOException { + if (slot.isHashNotImplemented()) { + return; + } log("Writing slot node %s", slot.slotNodeType); String slotImplName = getSlotImplName(slot.slot.value()); String genericArg = ""; @@ -202,13 +237,11 @@ private void writeSlot(CodeWriter w, TpSlotData slot) throws IOException { } @SuppressWarnings("try") - private static void writeSlotsStaticField(CodeWriter w, Set slots) throws IOException { + private static void writeSlotsStaticField(CodeWriter w, TypeElement enclosingType, Set slots) throws IOException { w.writeLn("static final TpSlots SLOTS = TpSlots.newBuilder()"); try (Block i3 = w.newIndent()) { String defs = slots.stream().// - map(s -> String.format(".set(TpSlots.TpSlotMeta.%s, %s.INSTANCE)", // - s.slot.value().name().toUpperCase(Locale.ROOT), // - getSlotImplName(s.slot.value()))).// + map(TpSlotData::builderCall).// collect(Collectors.joining("\n")); w.writeLn("%s.", defs); w.writeLn("build();"); @@ -237,6 +270,12 @@ private HashMap> collectEnclosingTypes(RoundEnviron tpSlotDataSet.add(new TpSlotData(slotAnnotation, enclosingType, type)); } } + elements = new HashSet<>(roundEnv.getElementsAnnotatedWithAny(Set.of(HashNotImplemented.class))); + for (Element element : elements) { + TypeElement typeElement = (TypeElement) element; + enclosingTypes.computeIfAbsent(typeElement, key -> new HashSet<>()).// + add(TpSlotData.createHashNotImplemented(typeElement)); + } return enclosingTypes; } diff --git a/graalpython/com.oracle.graal.python.shell/src/com/oracle/graal/python/shell/GraalPythonMain.java b/graalpython/com.oracle.graal.python.shell/src/com/oracle/graal/python/shell/GraalPythonMain.java index f0a6328d1f..81600f12e3 100644 --- a/graalpython/com.oracle.graal.python.shell/src/com/oracle/graal/python/shell/GraalPythonMain.java +++ b/graalpython/com.oracle.graal.python.shell/src/com/oracle/graal/python/shell/GraalPythonMain.java @@ -411,7 +411,7 @@ protected List preprocessArguments(List givenArgs, Map preprocessArguments(List givenArgs, Map exec_list = new ArrayList<>(); sb.append(System.getProperty("java.home")).append(File.separator).append("bin").append(File.separator).append("java"); @@ -745,15 +750,6 @@ protected void launch(Builder contextBuilder) { } } - if (isLLVMToolchainLauncher()) { - if (!hasContextOptionSetViaCommandLine("UseSystemToolchain")) { - contextBuilder.option("python.UseSystemToolchain", "false"); - } - if (!hasContextOptionSetViaCommandLine("NativeModules")) { - contextBuilder.option("python.NativeModules", "false"); - } - } - if (relaunchArgs != null) { Iterator it = origArgs.iterator(); while (it.hasNext()) { @@ -778,9 +774,6 @@ protected void launch(Builder contextBuilder) { contextBuilder.option("python.IntMaxStrDigits", Integer.toString(intMaxStrDigits)); } contextBuilder.option("python.DontWriteBytecodeFlag", Boolean.toString(dontWriteBytecode)); - if (verboseFlag) { - contextBuilder.option("log.python.level", "INFO"); - } contextBuilder.option("python.QuietFlag", Boolean.toString(quietFlag)); contextBuilder.option("python.NoUserSiteFlag", Boolean.toString(noUserSite)); contextBuilder.option("python.NoSiteFlag", Boolean.toString(noSite)); @@ -854,15 +847,40 @@ protected void launch(Builder contextBuilder) { inspectFlag = false; rc = readEvalPrint(context, consoleHandler); } + } catch (RuntimeException e) { + if (e.getMessage() != null && e.getMessage().contains("did not complete all polyglot threads")) { + // Python may end up with stuck threads and code would legitimately expect those to + // simply die with the process. In an embedding (or CPython subinterpreters) this + // is a problem, so Truffle throws an IllegalStateException when closing the + // context if that occurs. But here we have a launcher and usually we do not care + // about this problem during exit. For an example and some discussion, see + // https://discuss.python.org/t/getting-rid-of-daemon-threads/68836/14 where NJS + // brings up getaddrinfo which may just block in native for an arbitrary amount of + // time and prevent us from shutting down the thread. + if (!verboseFlag) { + tryToResetConsoleHandler(consoleHandler); + System.exit(rc); + } + } else { + throw e; + } } catch (IOException e) { rc = 1; e.printStackTrace(); } finally { - consoleHandler.setContext(null); + tryToResetConsoleHandler(consoleHandler); } System.exit(rc); } + private static void tryToResetConsoleHandler(ConsoleHandler consoleHandler) { + try { + consoleHandler.setContext(null); + } catch (Throwable e) { + // pass + } + } + private static boolean getBoolEnv(String var) { return getEnv(var) != null; } @@ -931,54 +949,70 @@ private void findAndApplyVenvCfg(Builder contextBuilder, String executable) { continue; } String name = parts[0].trim(); - if (name.equals("home")) { - try { - Path homeProperty = Paths.get(parts[1].trim()); - Path graalpyHome = homeProperty; - /* - * (tfel): According to PEP 405, the home key is the directory of the Python - * executable from which this virtual environment was created, that is, it - * usually ends with "/bin" on a Unix system. On Windows, the base Python - * should be in the top-level directory or under "\Scripts". To support - * running from Maven artifacts where we don't have a working executable, we - * patched our shipped venv module to set the home path without a "/bin" or - * "\\Scripts" suffix, so we explicitly check for those two subfolder cases - * and otherwise assume the home key is directly pointing to the Python - * home. - */ - if (graalpyHome.endsWith("bin") || graalpyHome.endsWith("Scripts")) { - graalpyHome = graalpyHome.getParent(); - } - contextBuilder.option("python.PythonHome", graalpyHome.toString()); - /* - * First try to resolve symlinked executables, since that may be more - * accurate than assuming the executable in 'home'. - */ - Path baseExecutable = null; + switch (name) { + case "home": try { - Path realPath = executablePath.toRealPath(); - if (!realPath.equals(executablePath.toAbsolutePath())) { - baseExecutable = realPath; + Path homeProperty = Paths.get(parts[1].trim()); + Path graalpyHome = homeProperty; + /* + * (tfel): According to PEP 405, the home key is the directory of the + * Python executable from which this virtual environment was created, + * that is, it usually ends with "/bin" on a Unix system. On Windows, + * the base Python should be in the top-level directory or under + * "\Scripts". To support running from Maven artifacts where we don't + * have a working executable, we patched our shipped venv module to set + * the home path without a "/bin" or "\\Scripts" suffix, so we + * explicitly check for those two subfolder cases and otherwise assume + * the home key is directly pointing to the Python home. + */ + if (graalpyHome.endsWith("bin") || graalpyHome.endsWith("Scripts")) { + graalpyHome = graalpyHome.getParent(); } - } catch (IOException ex) { - // Ignore - } - if (baseExecutable == null) { - baseExecutable = homeProperty.resolve(executablePath.getFileName()); - } - if (Files.exists(baseExecutable)) { - contextBuilder.option("python.BaseExecutable", baseExecutable.toString()); + contextBuilder.option("python.PythonHome", graalpyHome.toString()); /* - * This is needed to support the legacy GraalVM layout where the - * executable is a symlink into the 'languages' directory. + * First try to resolve symlinked executables, since that may be more + * accurate than assuming the executable in 'home'. */ - contextBuilder.option("python.PythonHome", baseExecutable.getParent().getParent().toString()); + Path baseExecutable = null; + try { + Path realPath = executablePath.toRealPath(); + if (!realPath.equals(executablePath.toAbsolutePath())) { + baseExecutable = realPath; + } + } catch (IOException ex) { + // Ignore + } + if (baseExecutable == null) { + baseExecutable = homeProperty.resolve(executablePath.getFileName()); + } + if (Files.exists(baseExecutable)) { + contextBuilder.option("python.BaseExecutable", baseExecutable.toString()); + /* + * This is needed to support the legacy GraalVM layout where the + * executable is a symlink into the 'languages' directory. + */ + contextBuilder.option("python.PythonHome", baseExecutable.getParent().getParent().toString()); + } + } catch (NullPointerException | InvalidPathException ex) { + // NullPointerException covers the possible null result of getParent() + warn("Could not set PYTHONHOME according to the pyvenv.cfg file."); } - } catch (NullPointerException | InvalidPathException ex) { - // NullPointerException covers the possible null result of getParent() - warn("Could not set PYTHONHOME according to the pyvenv.cfg file."); - } - break; + break; + case "venvlauncher_command": + if (!hasContextOptionSetViaCommandLine("VenvlauncherCommand")) { + contextBuilder.option("python.VenvlauncherCommand", parts[1].trim()); + } + break; + case "base-prefix": + if (!hasContextOptionSetViaCommandLine("SysBasePrefix")) { + contextBuilder.option("python.SysBasePrefix", parts[1].trim()); + } + break; + case "base-executable": + if (!hasContextOptionSetViaCommandLine("BaseExecutable")) { + contextBuilder.option("python.BaseExecutable", parts[1].trim()); + } + break; } } } catch (IOException ex) { @@ -1050,9 +1084,6 @@ protected String getLanguageId() { @Override protected void printHelp(OptionCategory maxCategory) { - if (isLLVMToolchainLauncher()) { - System.out.println("GraalPy launcher to use LLVM toolchain and Sulong execution of native extensions.\n"); - } System.out.println("usage: python [option] ... (-c cmd | file) [arg] ...\n" + "Options and arguments (and corresponding environment variables):\n" + "-B : this disables writing .py[co] files on import\n" + @@ -1118,14 +1149,7 @@ protected void printHelp(OptionCategory maxCategory) { " All following arguments are passed to the compiler.\n" + "-LD : run the linker used for generating GraalPython C extensions.\n" + " All following arguments are passed to the linker.\n" + - "\nEnvironment variables specific to the Graal Python launcher:\n" + - "SULONG_LIBRARY_PATH: Specifies the library path for Sulong.\n" + - " This is required when starting subprocesses of python.\n" : "")); - } - - private boolean isLLVMToolchainLauncher() { - String exeName = getResolvedExecutableName(); - return exeName != null && exeName.endsWith("-lt"); + "\nEnvironment variables specific to the Graal Python launcher:\n" : "")); } @Override diff --git a/graalpython/com.oracle.graal.python.test.integration/pom.xml b/graalpython/com.oracle.graal.python.test.integration/pom.xml index bad3f27502..2fbed1cd15 100644 --- a/graalpython/com.oracle.graal.python.test.integration/pom.xml +++ b/graalpython/com.oracle.graal.python.test.integration/pom.xml @@ -165,14 +165,6 @@ Additionally, one can change the polyglot artifacts version with runtime pom - - - org.graalvm.polyglot - llvm-community - ${com.oracle.graal.python.test.polyglot.version} - runtime - pom - org.graalvm.python python-embedding diff --git a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/advanced/MultiContextTest.java b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/advanced/MultiContextTest.java index f9e6c2f1e9..83b09a06c0 100644 --- a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/advanced/MultiContextTest.java +++ b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/advanced/MultiContextTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -57,19 +57,6 @@ public void testSharingWithMemoryview() { } } - @Test - public void testSharingWithCpythonSreAndLLVM() { - // This test is going to use the Sulong backend.This is why we need "sulong:SULONG_NATIVE" - // among the dependencies for GRAALPYTHON_UNIT_TESTS distribution, and - // org.graalvm.polyglot:llvm-community dependency in the pom.xml - Engine engine = Engine.newBuilder().build(); - for (int i = 0; i < 10; i++) { - try (Context context = newContextWithNativeModulesFalse(engine)) { - context.eval("python", "import _cpython_sre\nassert _cpython_sre.ascii_tolower(88) == 120\n"); - } - } - } - @Test public void testTryCatch() { Engine engine = Engine.newBuilder().build(); @@ -90,8 +77,4 @@ public void testTryCatch() { private static Context newContext(Engine engine) { return Context.newBuilder().allowExperimentalOptions(true).allowAllAccess(true).engine(engine).build(); } - - private static Context newContextWithNativeModulesFalse(Engine engine) { - return Context.newBuilder().allowExperimentalOptions(true).allowAllAccess(true).engine(engine).option("python.NativeModules", "false").build(); - } } diff --git a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/advanced/NativeExtTest.java b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/advanced/NativeExtTest.java index 0d8d90e643..53df2d3ed9 100644 --- a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/advanced/NativeExtTest.java +++ b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/advanced/NativeExtTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,6 +46,8 @@ import org.graalvm.polyglot.Engine; import org.graalvm.polyglot.PolyglotException; import org.junit.Assert; +import org.junit.Assume; +import org.junit.BeforeClass; import org.junit.Test; /** @@ -53,20 +55,26 @@ * because we cannot create multiple contexts that would load native extensions. */ public class NativeExtTest { + @BeforeClass + public static void setUpClass() { + Assume.assumeFalse(System.getProperty("os.name").toLowerCase().contains("mac")); + } + @Test public void testSharingErrorWithCpythonSre() throws InterruptedException { // The first context is the one that will use native extensions Engine engine = Engine.newBuilder().build(); - Context cextContext = newContext(engine); + Context cextContext = newContext(engine).option("python.IsolateNativeModules", "true").build(); try { cextContext.eval("python", "import _cpython_sre\nassert _cpython_sre.ascii_tolower(88) == 120\n"); - // Check that second context that tries to load native extension fails - try (Context secondCtx = newContext(engine)) { + // Check that second context that tries to load native extension fails without + // IsolateNativeModules + try (Context secondCtx = newContext(engine).build()) { try { secondCtx.eval("python", "import _cpython_sre\nassert _cpython_sre.ascii_tolower(88) == 120\n"); } catch (PolyglotException ex) { - Assert.assertTrue(ex.getMessage(), ex.getMessage().contains("Option python.NativeModules is set to 'true' and a second GraalPy context attempted")); + Assert.assertTrue(ex.getMessage(), ex.getMessage().contains("Option python.IsolateNativeModules is set to 'false' and a second GraalPy context attempted")); } } @@ -99,7 +107,7 @@ public void testSharingErrorWithCpythonSre() throws InterruptedException { } } - private static Context newContext(Engine engine) { - return Context.newBuilder().allowExperimentalOptions(true).allowAllAccess(true).engine(engine).build(); + private static Context.Builder newContext(Engine engine) { + return Context.newBuilder().allowExperimentalOptions(true).allowAllAccess(true).engine(engine); } } diff --git a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/advanced/ShutdownTest.java b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/advanced/ShutdownTest.java index 453d802402..e687192b92 100644 --- a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/advanced/ShutdownTest.java +++ b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/advanced/ShutdownTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,19 +40,26 @@ */ package com.oracle.graal.python.test.integration.advanced; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + import org.graalvm.polyglot.Context; import org.graalvm.polyglot.PolyglotException; import org.junit.Assert; +import org.junit.Assume; +import org.junit.BeforeClass; import org.junit.Test; import com.oracle.graal.python.test.integration.PythonTests; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; - // See also NativeExtTest public class ShutdownTest extends PythonTests { + @BeforeClass + public static void setUpClass() { + Assume.assumeFalse(System.getProperty("os.name").toLowerCase().contains("mac")); + } + @Test public void testCloseWithBackgroundThreadsRunningSucceeds() { Context context = createContext(); @@ -154,7 +161,7 @@ public void testJavaThreadNotExecutingPythonAnymore() throws InterruptedExceptio } private static Context createContext() { - return Context.newBuilder().allowExperimentalOptions(true).allowAllAccess(true).option("python.NativeModules", "false").build(); + return Context.newBuilder().allowExperimentalOptions(true).allowAllAccess(true).option("python.IsolateNativeModules", "true").build(); } private static void loadNativeExtension(Context context) { diff --git a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/engine/SharedEngineMultithreadingBenchmarkTest.java b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/engine/SharedEngineMultithreadingBenchmarkTest.java index 3c70a77024..3d709be875 100644 --- a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/engine/SharedEngineMultithreadingBenchmarkTest.java +++ b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/engine/SharedEngineMultithreadingBenchmarkTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,14 +45,21 @@ import org.graalvm.polyglot.Engine; import org.graalvm.polyglot.Source; +import org.junit.Assume; +import org.junit.BeforeClass; import org.junit.Test; import com.oracle.graal.python.test.integration.PythonTests; public class SharedEngineMultithreadingBenchmarkTest extends SharedEngineMultithreadingTestBase { + @BeforeClass + public static void setUpClass() { + Assume.assumeFalse(System.getProperty("os.name").toLowerCase().contains("mac")); + } + @Test public void testRichardsInParallelInMultipleContexts() throws Throwable { - try (Engine engine = Engine.newBuilder().allowExperimentalOptions(true).option("python.NativeModules", "false").build()) { + try (Engine engine = Engine.newBuilder().allowExperimentalOptions(true).option("python.IsolateNativeModules", "true").build()) { Source richardsSource = PythonTests.getScriptSource("richards3.py"); Task[] tasks = new Task[THREADS_COUNT]; for (int taskIdx = 0; taskIdx < tasks.length; taskIdx++) { diff --git a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/engine/SharedEngineMultithreadingTestBase.java b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/engine/SharedEngineMultithreadingTestBase.java index 3972dac6d0..da1e4d03f9 100644 --- a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/engine/SharedEngineMultithreadingTestBase.java +++ b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/engine/SharedEngineMultithreadingTestBase.java @@ -69,6 +69,7 @@ public class SharedEngineMultithreadingTestBase extends PythonTests { protected static final int RUNS_COUNT_FACTOR = Integer.getInteger("com.oracle.graal.python.test.SharedEngineMultithreadingRunCountFactor", 4); protected static final int THREADS_COUNT = Runtime.getRuntime().availableProcessors(); private static final boolean LOG = false; + private static final int TIMEOUT = 20; @Rule public CleanupRule cleanup = new CleanupRule(); @@ -117,14 +118,15 @@ protected static void submitAndWaitAll(ExecutorService service, Task[] tasks) th boolean wasTimeout = false; for (Future future : futures) { try { - future.get(2, TimeUnit.MINUTES); + // Under coverage, some of these tests are very slow + future.get(TIMEOUT, TimeUnit.MINUTES); } catch (TimeoutException e) { wasTimeout = true; } } if (wasTimeout) { System.err.println(Utils.getThreadDump()); - throw new AssertionError("One of the tasks did not finish in 2 minutes"); + throw new AssertionError("One of the tasks did not finish in " + TIMEOUT + " minutes"); } log("All %d futures finished...", tasks.length); } diff --git a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/generator/GeneratorTests.java b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/generator/GeneratorTests.java index 4eaf2fd873..689376fde4 100644 --- a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/generator/GeneratorTests.java +++ b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/generator/GeneratorTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -72,7 +72,7 @@ public void desugared() { } @Test - public void testYieldFrom() { + public void testYieldFromSimple() { String source = "def gen1():\n" + " yield 1\n" + " yield 2\n" + @@ -83,4 +83,119 @@ public void testYieldFrom() { "print(list(gen2()))\n"; assertPrints("[1, 2]\n", source); } + + @Test + public void testYieldFromIterable() { + // yield from should extract an iterator from a non-generator argument + String source = "class Foo:\n" + + " def __init__(self, wrapped):\n" + + " self.wrapped = wrapped\n" + + " def __iter__(self):\n" + + " return iter(self.wrapped)\n" + + "def gen():\n" + + " foo = Foo([1,2,3])\n" + + " yield from foo\n" + + "\n" + + "print(list(gen()))\n"; + assertPrints("[1, 2, 3]\n", source); + } + + @Test + public void testYieldFromReturn() { + String source = "def gen1():\n" + + " yield 1\n" + + " yield 2\n" + + " return 3\n" + + "\n" + + "def gen2():\n" + + " final = yield from gen1()\n" + + " yield final\n" + + "\n" + + "print(list(gen2()))\n"; + assertPrints("[1, 2, 3]\n", source); + } + + @Test + public void testYieldFromSend() { + String source = "def gen1(x):\n" + + " yield (yield (yield x))\n" + + "\n" + + "def gen2():\n" + + " yield from gen1(2)\n" + + " yield 8\n" + + "\n" + + "gen = gen2()\n" + + "print(gen.send(None))\n" + + "print(gen.send(4))\n" + + "print(gen.send(6))\n" + + "print(gen.send(42))\n"; + assertPrints("2\n4\n6\n8\n", source); + } + + @Test + public void testYieldFromThrowCaught() { + String source = "def gen1():\n" + + " try:\n" + + " x = 1\n" + + " while True:\n" + + " x = yield x\n" + + " except ValueError:\n" + + " yield 42\n" + + "\n" + + "def gen2():\n" + + " yield from gen1()\n" + + "\n" + + "gen = gen2()\n" + + "print(gen.send(None))\n" + + "print(gen.send(2))\n" + + "print(gen.send(3))\n" + + "print(gen.throw(ValueError))\n"; + assertPrints("1\n2\n3\n42\n", source); + } + + @Test + public void testYieldFromThrowUncaught() { + String source = "def gen1():\n" + + " x = 1\n" + + " while True:\n" + + " x = yield x\n" + + "\n" + + "def gen2():\n" + + " yield from gen1()\n" + + "\n" + + "gen = gen2()\n" + + "print(gen.send(None))\n" + + "print(gen.send(2))\n" + + "print(gen.send(3))\n" + + "try:\n" + + " gen.throw(ValueError)\n" + + " print('error')\n" + + "except ValueError:\n" + + " print('success')\n"; + assertPrints("1\n2\n3\nsuccess\n", source); + } + + @Test + public void testYieldFromClose() { + String source = "def gen1():\n" + + " x = 1\n" + + " try:\n" + + " while True:\n" + + " x = yield x\n" + + " except GeneratorExit:\n" + + " print('gen1 exit')\n" + + "\n" + + "def gen2():\n" + + " try:\n" + + " yield from gen1()\n" + + " except GeneratorExit:\n" + + " print('gen2 exit')\n" + + "\n" + + "gen = gen2()\n" + + "print(gen.send(None))\n" + + "print(gen.send(2))\n" + + "print(gen.send(3))\n" + + "gen.close()\n"; + assertPrints("1\n2\n3\ngen1 exit\ngen2 exit\n", source); + } } diff --git a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/grammar/AsyncTests.java b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/grammar/AsyncTests.java new file mode 100644 index 0000000000..6653b44e2c --- /dev/null +++ b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/grammar/AsyncTests.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.test.integration.grammar; + +import static com.oracle.graal.python.test.integration.PythonTests.assertPrints; +import static com.oracle.graal.python.test.integration.Utils.IS_WINDOWS; +import static org.junit.Assume.assumeFalse; + +import org.junit.Test; + +public class AsyncTests { + @Test + public void nativeCoroutine() { + assumeFalse(IS_WINDOWS); + assumeFalse("TODO: not implemented PGenerator.getYieldFrom(PGenerator.java:204)", Boolean.getBoolean("python.EnableBytecodeDSLInterpreter")); + String source = "import asyncio\n" + + "async def foo():\n" + + " return 42\n" + + "async def main():\n" + + " print(await foo())\n" + + "asyncio.run(main())"; + assertPrints("42\n", source); + } + + @Test + public void asyncWith() { + assumeFalse(IS_WINDOWS); + assumeFalse("TODO: not implemented PGenerator.getYieldFrom(PGenerator.java:204)", Boolean.getBoolean("python.EnableBytecodeDSLInterpreter")); + String source = "import asyncio\n" + + "class AsyncContextManager:\n" + + " async def __aenter__(self):\n" + + " await asyncio.sleep(0.01)\n" + + " print(\"entered\")\n" + + " async def __aexit__(self, exc_type, exc_value, traceback):\n" + + " await asyncio.sleep(0.01)\n" + + " if exc_type:\n" + + " print(\"exited exceptionally\")\n" + + " else:\n" + + " print(\"exited normally\")\n" + + " return True\n" + + "async def main(shouldRaise):\n" + + " async with AsyncContextManager():\n" + + " print(\"inside\")\n" + + " if shouldRaise:\n" + + " raise ValueError\n" + + "asyncio.run(main(%s))"; + assertPrints("entered\ninside\nexited normally\n", String.format(source, "False")); + assertPrints("entered\ninside\nexited exceptionally\n", String.format(source, "True")); + } + + @Test + public void asyncWithExceptional() { + assumeFalse(IS_WINDOWS); + assumeFalse("TODO: not implemented PGenerator.getYieldFrom(PGenerator.java:204)", Boolean.getBoolean("python.EnableBytecodeDSLInterpreter")); + String source = "import asyncio\n" + + "class AsyncContextManager:\n" + + " async def __aenter__(self):\n" + + " await asyncio.sleep(0.01)\n" + + " print(\"entered\")\n" + + " async def __aexit__(self, exc_type, exc_value, traceback):\n" + + " await asyncio.sleep(0.01)\n" + + " print(\"exited\")\n" + + " return False\n" + // don't handle exception + "async def main(shouldRaise):\n" + + " async with AsyncContextManager():\n" + + " print(\"inside\")\n" + + " if shouldRaise:\n" + + " raise ValueError\n" + + "try:\n" + + " asyncio.run(main(%s))\n" + + "except ValueError:\n" + + " print(\"rethrew\")\n"; + assertPrints("entered\ninside\nexited\n", String.format(source, "False")); + assertPrints("entered\ninside\nexited\nrethrew\n", String.format(source, "True")); + } +} diff --git a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/grammar/ClassTests.java b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/grammar/ClassTests.java index 2e279ae577..4818da0cde 100644 --- a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/grammar/ClassTests.java +++ b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/grammar/ClassTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -205,4 +205,21 @@ public void multipleInheritance() { assertPrints("common\n", source); } + @Test + public void classDecorator() { + String source = "def wrapper(cls):\n" + // + " orig_init = cls.__init__\n" + // + " def new_init(self):\n" + // + " print('wrapper')\n" + // + " orig_init(self)\n" + // + " cls.__init__ = new_init\n" + // + " return cls\n" + // + "@wrapper\n" + // + "class Foo:\n" + // + " def __init__(self):\n" + // + " print('Foo')\n" + // + "Foo()\n"; + assertPrints("wrapper\nFoo\n", source); + } + } diff --git a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/grammar/TryTests.java b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/grammar/TryTests.java index 697baf7341..3c4642f998 100644 --- a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/grammar/TryTests.java +++ b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/grammar/TryTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -290,4 +290,49 @@ public void testExceptionState6() { "print(repr(sys.exc_info()[1]))\n"; assertPrints("None\nNone\n", source); } + + @Test + public void testNamedExceptionDeleted() { + String source = "ex = 42\n" + + "try:\n" + + " raise NameError\n" + + "except BaseException as ex:\n" + + " pass\n" + + "try:\n" + + " print(ex)\n" + + " print(\"expected NameError\")\n" + + "except NameError:\n" + + " print(\"hit NameError\")\n"; + assertPrints("hit NameError\n", source); + } + + @Test + public void testNamedExceptionNotDeleted() { + String source = "ex = 42\n" + + "try:\n" + + " print(\"nothing thrown\")\n" + + "except BaseException as ex:\n" + + " pass\n" + + "try:\n" + + " print(ex)\n" + + "except NameError:\n" + + " print(\"hit unexpected NameError\")\n"; + assertPrints("nothing thrown\n42\n", source); + } + + @Test + public void testNamedExceptionDeletedByHandler() { + String source = "ex = 42\n" + + "try:\n" + + " raise NameError\n" + + "except BaseException as ex:\n" + + " print(\"deleting exception\")\n" + + " del ex\n" + + "try:\n" + + " print(ex)\n" + + " print(\"expected NameError\")\n" + + "except NameError:\n" + + " print(\"hit NameError\")\n"; + assertPrints("deleting exception\nhit NameError\n", source); + } } diff --git a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/interop/JavaInteropTest.java b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/interop/JavaInteropTest.java index 68a56f6086..d78d531adb 100644 --- a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/interop/JavaInteropTest.java +++ b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/interop/JavaInteropTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -839,6 +839,46 @@ class Bar(Foo): assertEquals(object.getMetaSimpleName(), "object"); assertFalse(object.hasMetaParents()); } + + public static class MyFunction implements java.util.function.Function { + public String __text_signature__ = "(string) -> str"; + + @Override + public String apply(String s) { + return s; + } + } + + public static class MyFunctionWithCustomName implements java.util.function.Function { + public String __text_signature__ = "(string) -> str"; + public String __name__ = "myfunc"; + + @Override + public String apply(String s) { + return s; + } + } + + public static class MyFunctionWithIncorrectSignature implements java.util.function.Function { + public String __text_signature__ = "[I;java.lang.String;"; + + @Override + public String apply(String s) { + return s; + } + } + + @Test + public void javaExecutablesAsPythonFunctions() { + Value inspectSignature = context.eval("python", "import inspect; inspect.signature"); + assertEquals("", inspectSignature.execute(new MyFunction()).toString()); + + Value signature = context.eval("python", "lambda f: f.__text_signature__"); + assertEquals(new MyFunctionWithIncorrectSignature().__text_signature__, signature.execute(new MyFunctionWithIncorrectSignature()).asString()); + + Value name = context.eval("python", "lambda f: f.__name__"); + assertEquals(new MyFunctionWithCustomName().__name__, name.execute(new MyFunctionWithCustomName()).asString()); + } } @RunWith(Parameterized.class) diff --git a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/runtime/ProfileTests.java b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/runtime/ProfileTests.java index 6824b52b61..279ca064df 100644 --- a/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/runtime/ProfileTests.java +++ b/graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/runtime/ProfileTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,6 +44,7 @@ import java.io.PrintStream; import org.junit.Assert; +import org.junit.Assume; import org.junit.Test; import com.oracle.graal.python.test.integration.PythonTests; @@ -67,6 +68,7 @@ public void profileYield() { @Test public void profileException() { + Assume.assumeFalse("TODO: wrong stacktrace", Boolean.getBoolean("python.EnableBytecodeDSLInterpreter")); String source = "import sys\n" + "def f(frame, event, arg): print(frame, event, arg)\n" + "sys.setprofile(f)\n" + diff --git a/graalpython/com.oracle.graal.python.test.integration/src/org/graalvm/python/embedding/test/integration/GraalPyResourcesUtilsTests.java b/graalpython/com.oracle.graal.python.test.integration/src/org/graalvm/python/embedding/test/integration/GraalPyResourcesUtilsTests.java deleted file mode 100644 index 50e91ed4b8..0000000000 --- a/graalpython/com.oracle.graal.python.test.integration/src/org/graalvm/python/embedding/test/integration/GraalPyResourcesUtilsTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.graalvm.python.embedding.test.integration; - -import org.graalvm.polyglot.Engine; -import org.graalvm.python.embedding.utils.GraalPyResources; -import org.graalvm.python.embedding.utils.VirtualFileSystem; -import org.junit.Test; - -import java.nio.file.Path; - -/** - * Siple copy of GraalPyResourcesTests to test also the deprecated - * org.graalvm.python.embedding.utils pkg - */ -@SuppressWarnings("deprecation") -public class GraalPyResourcesUtilsTests { - - @Test - public void sharedEngine() { - // simply check if we are able to create a context with a shared engine - Engine sharedEngine = Engine.newBuilder().build(); - GraalPyResources.contextBuilder().engine(sharedEngine).build().close(); - GraalPyResources.contextBuilder().engine(sharedEngine).build().close(); - GraalPyResources.contextBuilder(Path.of("test")).engine(sharedEngine).build().close(); - GraalPyResources.contextBuilder(VirtualFileSystem.newBuilder().build()).engine(sharedEngine).build().close(); - } -} diff --git a/graalpython/com.oracle.graal.python.test.integration/src/org/graalvm/python/embedding/test/integration/VirtualFileSystemIntegrationUtilsTest.java b/graalpython/com.oracle.graal.python.test.integration/src/org/graalvm/python/embedding/test/integration/VirtualFileSystemIntegrationUtilsTest.java deleted file mode 100644 index 8033697bc0..0000000000 --- a/graalpython/com.oracle.graal.python.test.integration/src/org/graalvm/python/embedding/test/integration/VirtualFileSystemIntegrationUtilsTest.java +++ /dev/null @@ -1,593 +0,0 @@ -/* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.graalvm.python.embedding.test.integration; - -import org.graalvm.polyglot.Context; -import org.graalvm.polyglot.Context.Builder; -import org.graalvm.polyglot.HostAccess; -import org.graalvm.polyglot.PolyglotException; -import org.graalvm.polyglot.Value; -import org.graalvm.polyglot.io.IOAccess; -import org.graalvm.python.embedding.utils.GraalPyResources; -import org.graalvm.python.embedding.utils.VirtualFileSystem; -import org.junit.Test; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.file.Files; -import java.nio.file.InvalidPathException; -import java.nio.file.Path; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.function.Function; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; - -import static com.oracle.graal.python.test.integration.Utils.IS_WINDOWS; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * Siple copy of VirtualFileSystemIntegrationTest to test also the deprecated - * org.graalvm.python.embedding.utils pkg - */ -@SuppressWarnings("deprecation") -public class VirtualFileSystemIntegrationUtilsTest { - - static final String VFS_UNIX_MOUNT_POINT = "/test_mount_point"; - static final String VFS_WIN_MOUNT_POINT = "X:\\test_win_mount_point"; - static final String VFS_MOUNT_POINT = IS_WINDOWS ? VFS_WIN_MOUNT_POINT : VFS_UNIX_MOUNT_POINT; - - static final String PYTHON = "python"; - - public VirtualFileSystemIntegrationUtilsTest() { - Logger logger = Logger.getLogger(VirtualFileSystem.class.getName()); - for (Handler handler : logger.getHandlers()) { - handler.setLevel(Level.FINE); - } - logger.setLevel(Level.FINE); - } - - @Test - public void defaultValues() throws IOException { - try (VirtualFileSystem fs = VirtualFileSystem.create(); VirtualFileSystem fs2 = VirtualFileSystem.create()) { - assertEquals(fs.getMountPoint(), fs2.getMountPoint()); - assertEquals(IS_WINDOWS ? "X:\\graalpy_vfs" : "/graalpy_vfs", fs.getMountPoint()); - } - } - - @Test - public void mountPoints() throws IOException { - try (VirtualFileSystem vfs = VirtualFileSystem.newBuilder().// - unixMountPoint(VFS_UNIX_MOUNT_POINT).// - windowsMountPoint(VFS_WIN_MOUNT_POINT).build()) { - assertEquals(VFS_MOUNT_POINT, vfs.getMountPoint()); - } - - String multiPathUnixMountPoint = "/test/mount/point"; - String multiPathWinMountPoint = "X:\\test\\win\\mount\\point"; - VirtualFileSystem vfs = VirtualFileSystem.newBuilder().// - unixMountPoint(multiPathUnixMountPoint).// - windowsMountPoint(multiPathWinMountPoint).// - resourceLoadingClass(VirtualFileSystemIntegrationUtilsTest.class).build(); - try (Context ctx = addTestOptions(GraalPyResources.contextBuilder(vfs)).build()) { - ctx.eval(PYTHON, "from os import listdir; listdir('" + (IS_WINDOWS ? multiPathWinMountPoint.replace("\\", "\\\\") : multiPathUnixMountPoint) + "')"); - } - } - - private static void checkExtractedFile(Path extractedFile, String[] expectedContens) throws IOException { - assertTrue(Files.exists(extractedFile)); - List lines = Files.readAllLines(extractedFile); - if (expectedContens != null) { - assertEquals("expected " + expectedContens.length + " lines in extracted file '" + extractedFile + "'", expectedContens.length, lines.size()); - for (String line : expectedContens) { - assertTrue("expected line '" + line + "' in file '" + extractedFile + "' with contents:\n" + expectedContens, lines.contains(line)); - } - } else { - assertEquals("extracted file '" + extractedFile + "' expected to be empty, but had " + lines.size() + " lines", 0, lines.size()); - } - } - - private static void checkException(Class exType, Callable c) { - checkException(exType, c, null); - } - - private static void checkException(Class exType, Callable c, String msg) { - boolean gotEx = false; - try { - c.call(); - } catch (Exception e) { - assertEquals(e.getClass(), exType); - gotEx = true; - } - assertTrue(msg != null ? msg : "expected " + exType.getName(), gotEx); - } - - @Test - public void fsOperations() { - try (Context ctx = createContext(null, null)) { - fsOperations(ctx, "/test_mount_point/"); - } - try (Context ctx = createContext(null, b -> b.currentWorkingDirectory(Path.of(VFS_MOUNT_POINT)))) { - fsOperations(ctx, ""); - } - } - - public void fsOperations(Context ctx, String pathPrefix) { - - // os.path.exists - eval(ctx, "import os; assert os.path.exists('/test_mount_point')", pathPrefix); - eval(ctx, "import os; assert os.path.exists('{pathPrefix}.')", pathPrefix); - eval(ctx, "import os; assert os.path.exists('{pathPrefix}file1')", pathPrefix); - eval(ctx, "import os; assert os.path.exists('{pathPrefix}dir1')", pathPrefix); - eval(ctx, "import os; assert os.path.exists('{pathPrefix}dir1/')", pathPrefix); - eval(ctx, "import os; assert os.path.exists('{pathPrefix}emptydir')", pathPrefix); - eval(ctx, "import os; assert os.path.exists('{pathPrefix}emptydir/')", pathPrefix); - eval(ctx, "import os; assert os.path.exists('{pathPrefix}dir1/file2')", pathPrefix); - eval(ctx, "import os; assert not os.path.exists('{pathPrefix}doesnotexist')", pathPrefix); - eval(ctx, "import os; assert not os.path.exists('{pathPrefix}doesnotexist/')", pathPrefix); - - // pathlib.exists - eval(ctx, "from pathlib import Path; assert Path('{pathPrefix}').exists()", pathPrefix); - eval(ctx, "from pathlib import Path; assert Path('{pathPrefix}file1').exists()", pathPrefix); - eval(ctx, "from pathlib import Path; assert Path('{pathPrefix}dir1').exists()", pathPrefix); - eval(ctx, "from pathlib import Path; assert Path('{pathPrefix}dir1/').exists()", pathPrefix); - eval(ctx, "from pathlib import Path; assert Path('{pathPrefix}emptydir').exists()", pathPrefix); - eval(ctx, "from pathlib import Path; assert Path('{pathPrefix}emptydir/').exists()", pathPrefix); - eval(ctx, "from pathlib import Path; assert not Path('{pathPrefix}doesnotexist').exists()", pathPrefix); - eval(ctx, "from pathlib import Path; assert not Path('{pathPrefix}doesnotexist/').exists()", pathPrefix); - - // path.isfile|isdir - - eval(ctx, "import os; assert os.path.isfile('{pathPrefix}file1')", pathPrefix); - eval(ctx, "import os; assert not os.path.isfile('{pathPrefix}dir1')", pathPrefix); - eval(ctx, "import os; assert not os.path.isfile('{pathPrefix}dir1/')", pathPrefix); - - eval(ctx, "import os; assert not os.path.isfile('/test_mount_point')", pathPrefix); - eval(ctx, "import os; assert os.path.isdir('/test_mount_point')", pathPrefix); - eval(ctx, "import os; assert not os.path.isdir('{pathPrefix}file1')", pathPrefix); - eval(ctx, "import os; assert os.path.isdir('{pathPrefix}dir1')", pathPrefix); - eval(ctx, "import os; assert os.path.isdir('{pathPrefix}dir1/')", pathPrefix); - - // pathlib.is_file|is_dir - - eval(ctx, "from pathlib import Path; assert not Path('/test_mount_point').is_file()", pathPrefix); - eval(ctx, "from pathlib import Path; assert Path('{pathPrefix}file1').is_file()", pathPrefix); - eval(ctx, "from pathlib import Path; assert not Path('{pathPrefix}dir1').is_file()", pathPrefix); - eval(ctx, "from pathlib import Path; assert not Path('{pathPrefix}dir1/').is_file()", pathPrefix); - - eval(ctx, "from pathlib import Path; assert Path('/test_mount_point').is_dir()", pathPrefix); - eval(ctx, "from pathlib import Path; assert not Path('{pathPrefix}file1').is_dir()", pathPrefix); - eval(ctx, "from pathlib import Path; assert Path('{pathPrefix}dir1').is_dir()", pathPrefix); - eval(ctx, "from pathlib import Path; assert Path('{pathPrefix}dir1/').is_dir()", pathPrefix); - - // delete os.remove|rmdir - - eval(ctx, """ - import os - try: - os.remove('{pathPrefix}doesnotexist') - except OSError: - pass - """, pathPrefix); - eval(ctx, """ - import os - try: - os.remove('{pathPrefix}file1') - except OSError: - pass - """, pathPrefix); - eval(ctx, """ - import os - try: - os.rmdir('{pathPrefix}file1') - except OSError: - pass - """, pathPrefix); - eval(ctx, """ - import os - try: - os.remove('{pathPrefix}dir1') - except OSError: - pass - """, pathPrefix); - eval(ctx, """ - import os - try: - os.rmdir('{pathPrefix}dir1') - except OSError: - pass - """, pathPrefix); - eval(ctx, """ - import os - try: - os.rmdir('{pathPrefix}emptydir') - except OSError: - pass - """, pathPrefix); - - // delete pathlib.unlink|rmdir - - eval(ctx, """ - from pathlib import Path - try: - Path('{pathPrefix}doesnotexist').unlink() - except OSError: - pass - """, pathPrefix); - eval(ctx, """ - from pathlib import Path - try: - Path('{pathPrefix}file').unlink() - except OSError: - pass - """, pathPrefix); - eval(ctx, """ - from pathlib import Path - try: - Path('{pathPrefix}file1').rmdir() - except OSError: - pass - """, pathPrefix); - eval(ctx, """ - from pathlib import Path - try: - Path('{pathPrefix}dir1').unlink() - except OSError: - pass - """, pathPrefix); - eval(ctx, """ - from pathlib import Path - try: - Path('{pathPrefix}dir1').rmdir() - except OSError: - pass - """, pathPrefix); - eval(ctx, """ - from pathlib import Path - try: - Path('{pathPrefix}emptydir').rmdir() - except OSError: - pass - """, pathPrefix); - - // delete shutil.rmtree - - eval(ctx, """ - import shutil - try: - shutil.rmtree('{pathPrefix}dir1') - except OSError: - pass - """, pathPrefix); - eval(ctx, """ - import shutil - try: - shutil.rmtree('{pathPrefix}emptydir') - except OSError: - pass - """, pathPrefix); - - // os.listdir - - eval(ctx, """ - from os import listdir - try: - f = listdir('{pathPrefix}doesnotexist') - except FileNotFoundError: - pass - except Error: - assert False, 'expected FileNotFoundError' - f = listdir('{pathPrefix}emptydir') - assert len(f) == 0, 'expected no files' - - f = listdir('/test_mount_point/') - assert len(f) == 7, 'expected 7 files, got ' + str(len(f)) - - assert 'dir1' in f, 'does not contain "dir1"' - assert 'emptydir' in f, 'does not contain "emptydir"' - assert 'file1' in f, 'does not contain "file1"' - assert 'fileslist.txt' in f, 'does not contain "fileslist.txt"' - - f = listdir('{pathPrefix}dir1') - if len(f) != 2: - print('files in {pathPrefix}dir1:') - for ff in f: - print(ff) - assert False, 'expected 3 got ' + str(len(f)) - assert 'file2' in f, 'does not contain "file2"' - assert 'extractme' in f, 'does not contain "extractme"' - """, pathPrefix); - - // os.walk - - eval(ctx, """ - from os import walk - i = 0 - for r, d, f in walk('{pathPrefix}doesnotexist'): - i = i + 1 - assert i == 0 - - for r, d, f in walk('{pathPrefix}emptydir'): - i = i + 1 - assert r == '{pathPrefix}emptydir', 'expected {pathPrefix}emptydir, got' + r - assert len(d) == 0, 'expected no dirs in emptydir' - assert len(f) == 0, 'expected no files in emptydir' - assert i == 1 - - roots = set() - dirs = set() - files = set() - for r, d, f in walk('/test_mount_point'): - roots.add(r) - for ff in f: - files.add(r + "/" + ff) - for dd in d: - dirs.add(r + "/" + dd) - - assert len(roots) == 9, 'expected 10 roots, got ' + str(len(roots)) - assert len(files) == 15, 'expected 15 files, got ' + str(len(files)) - assert len(dirs) == 8, 'expected 8 dirs, got ' + str(len(dirs)) - """, pathPrefix); - - // read file - - eval(ctx, """ - with open("{pathPrefix}file1", "r") as f: - l = f.readlines() - assert len(l) == 2, 'expect 2 lines, got ' + len(l) - assert l[0].startswith("text1"), f'expected "text1", got "{l[0]}"' - assert l[1].startswith("text2"), f'expected "text2", got "{l[1]}"' - - with open("{pathPrefix}dir1/file2", "r") as f: - l = f.readlines() - assert len(l) == 0, 'expect 0 lines from empty file, got ' + str(len(l)) - """, pathPrefix); - - // write file - eval(ctx, """ - try: - f = open("{pathPrefix}file1", "w") - except OSError: - pass - """, pathPrefix); - } - - @Test - public void osChdir() { - try (Context ctx = createContext(null, null)) { - // os.path.exists - eval(ctx, """ - import os - assert not os.path.exists('file1') - os.chdir('/test_mount_point') - assert os.path.exists('file1') - """); - } - } - - @Test - public void fsOperationsCaseInsensitive() { - try (Context ctx = createContext(b -> b.caseInsensitive(true), null)) { - eval(ctx, """ - import os - assert os.path.exists('/test_mount_point/SomeFile') - assert os.path.exists('/test_mount_point/someFile') - assert os.path.exists('/test_mount_point/somefile') - assert not os.path.exists('/test_mount_point/somefile1') - """); - } - } - - private static void eval(Context ctx, String s, String pathPrefix) { - eval(ctx, s.replace("{pathPrefix}", pathPrefix)); - } - - private static void eval(Context ctx, String s) { - String src = patchMountPoint(s); - ctx.eval(PYTHON, src); - } - - private static String patchMountPoint(String src) { - if (IS_WINDOWS) { - return src.replace(VFS_UNIX_MOUNT_POINT, "X:\\\\test_win_mount_point"); - } - return src; - } - - public Context createContext(Function vfsBuilderFunction, Function ctxBuilderFunction) { - VirtualFileSystem.Builder builder = VirtualFileSystem.newBuilder().// - unixMountPoint(VFS_MOUNT_POINT).// - windowsMountPoint(VFS_WIN_MOUNT_POINT).// - extractFilter(p -> p.getFileName().toString().endsWith(".tso")).// - resourceLoadingClass(VirtualFileSystemIntegrationUtilsTest.class); - if (vfsBuilderFunction != null) { - builder = vfsBuilderFunction.apply(builder); - } - VirtualFileSystem fs = builder.build(); - Builder ctxBuilder = addTestOptions(GraalPyResources.contextBuilder(fs)); - if (ctxBuilderFunction != null) { - ctxBuilder = ctxBuilderFunction.apply(ctxBuilder); - } - return ctxBuilder.build(); - } - - @Test - public void vfsBuilderTest() { - try (Context context = addTestOptions(GraalPyResources.contextBuilder()).allowAllAccess(true).allowHostAccess(HostAccess.ALL).build()) { - context.eval(PYTHON, "import java; java.type('java.lang.String')"); - } - - try (Context context = addTestOptions(GraalPyResources.contextBuilder()).allowAllAccess(false).allowHostAccess(HostAccess.NONE).build()) { - context.eval(PYTHON, """ - import java - try: - java.type('java.lang.String'); - except NotImplementedError: - pass - else: - assert False, 'expected NotImplementedError' - """); - } - VirtualFileSystem fs = VirtualFileSystem.newBuilder().// - unixMountPoint(VFS_MOUNT_POINT).// - windowsMountPoint(VFS_WIN_MOUNT_POINT).// - resourceLoadingClass(VirtualFileSystemIntegrationUtilsTest.class).build(); - try (Context context = addTestOptions(GraalPyResources.contextBuilder(fs)).build()) { - context.eval(PYTHON, patchMountPoint("from os import listdir; listdir('/test_mount_point')")); - } - - try (Context context = GraalPyResources.createContext()) { - context.eval(PYTHON, "from os import listdir; listdir('.')"); - } - try (Context context = addTestOptions(GraalPyResources.contextBuilder()).allowIO(IOAccess.NONE).build()) { - boolean gotPE = false; - try { - context.eval(PYTHON, "from os import listdir; listdir('.')"); - } catch (PolyglotException pe) { - gotPE = true; - } - assert gotPE : "expected PolyglotException"; - } - } - - @Test - public void externalResourcesBuilderTest() throws IOException { - Path resourcesDir = Files.createTempDirectory("vfs-test-resources"); - try (VirtualFileSystem fs = VirtualFileSystem.newBuilder().resourceLoadingClass(VirtualFileSystemIntegrationUtilsTest.class).build()) { - // extract VFS - GraalPyResources.extractVirtualFileSystemResources(fs, resourcesDir); - } - // check extracted contents - InputStream stream = VirtualFileSystemIntegrationUtilsTest.class.getResourceAsStream("/org.graalvm.python.vfs/fileslist.txt"); - BufferedReader br = new BufferedReader(new InputStreamReader(stream)); - String line; - while ((line = br.readLine()) != null) { - line = line.substring("/org.graalvm.python.vfs/".length()); - if (line.length() == 0) { - continue; - } - Path extractedFile = resourcesDir.resolve(line); - assert Files.exists(extractedFile); - if (line.endsWith("/")) { - assert Files.isDirectory(extractedFile); - } - } - checkExtractedFile(resourcesDir.resolve(Path.of("file1")), new String[]{"text1", "text2"}); - - // create context with extracted resource dir and check if we can see the extracted file - try (Context context = addTestOptions(GraalPyResources.contextBuilder(resourcesDir)).build()) { - context.eval("python", "import os; assert os.path.exists('" + resourcesDir.resolve("file1").toString().replace("\\", "\\\\") + "')"); - } - } - - @Test - public void vfsMountPointTest() { - if (IS_WINDOWS) { - checkException(IllegalArgumentException.class, () -> VirtualFileSystem.newBuilder().windowsMountPoint("test")); - checkException(IllegalArgumentException.class, () -> VirtualFileSystem.newBuilder().windowsMountPoint("test\\")); - checkException(IllegalArgumentException.class, () -> VirtualFileSystem.newBuilder().windowsMountPoint("\\test\\")); - checkException(IllegalArgumentException.class, () -> VirtualFileSystem.newBuilder().windowsMountPoint("\\test")); - checkException(IllegalArgumentException.class, () -> VirtualFileSystem.newBuilder().windowsMountPoint("X:\\test\\")); - checkException(InvalidPathException.class, () -> VirtualFileSystem.newBuilder().windowsMountPoint("X:\\test|test")); - } else { - checkException(IllegalArgumentException.class, () -> VirtualFileSystem.newBuilder().unixMountPoint("test")); - checkException(IllegalArgumentException.class, () -> VirtualFileSystem.newBuilder().unixMountPoint("test/")); - checkException(IllegalArgumentException.class, () -> VirtualFileSystem.newBuilder().unixMountPoint("/test/")); - checkException(IllegalArgumentException.class, () -> VirtualFileSystem.newBuilder().unixMountPoint("X:\\test")); - checkException(InvalidPathException.class, () -> VirtualFileSystem.newBuilder().unixMountPoint("/test/\0")); - } - } - - @SuppressWarnings("unchecked") - @Test - public void pythonPathsTest() throws IOException { - String defaultMountPoint; - try (VirtualFileSystem vfs = VirtualFileSystem.newBuilder().build()) { - defaultMountPoint = vfs.getMountPoint(); - } - - String getPathsSource = "import sys; [sys.path, sys.executable]"; - try (Context ctx = GraalPyResources.createContext()) { - Value paths = ctx.eval("python", getPathsSource); - - assertEquals(IS_WINDOWS ? "X:\\graalpy_vfs" : "/graalpy_vfs", defaultMountPoint); - checkPaths(paths.as(List.class), defaultMountPoint); - } - - try (Context ctx = GraalPyResources.contextBuilder().build()) { - Value paths = ctx.eval("python", getPathsSource); - checkPaths(paths.as(List.class), defaultMountPoint); - } - VirtualFileSystem vfs = VirtualFileSystem.newBuilder().// - unixMountPoint(VFS_UNIX_MOUNT_POINT).// - windowsMountPoint(VFS_WIN_MOUNT_POINT).build(); - assertEquals(VFS_MOUNT_POINT, vfs.getMountPoint()); - try (Context ctx = GraalPyResources.contextBuilder(vfs).build()) { - Value paths = ctx.eval("python", getPathsSource); - checkPaths(paths.as(List.class), vfs.getMountPoint()); - } - Path resourcesDir = Files.createTempDirectory("python-resources"); - - try (Context ctx = GraalPyResources.contextBuilder(resourcesDir).build()) { - Value paths = ctx.eval("python", getPathsSource); - checkPaths(paths.as(List.class), resourcesDir.toString()); - } - } - - @SuppressWarnings("unchecked") - private static void checkPaths(List l, String pathPrefix) { - // option python.PythonPath - assertTrue(((List) l.get(0)).contains(pathPrefix + File.separator + "src")); - // option python.Executable - assertEquals(l.get(1), pathPrefix + (IS_WINDOWS ? "\\venv\\Scripts\\python.exe" : "/venv/bin/python")); - } - - private static Builder addTestOptions(Builder builder) { - return builder.option("engine.WarnInterpreterOnly", "false"); - } - -} diff --git a/graalpython/com.oracle.graal.python.test/src/META-INF/services/com.oracle.graal.python.builtins.PythonBuiltins b/graalpython/com.oracle.graal.python.test/src/META-INF/services/com.oracle.graal.python.builtins.PythonBuiltins deleted file mode 100644 index 32134f782e..0000000000 --- a/graalpython/com.oracle.graal.python.test/src/META-INF/services/com.oracle.graal.python.builtins.PythonBuiltins +++ /dev/null @@ -1 +0,0 @@ -com.oracle.graal.python.test.advanced.CustomModule diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/MethodFlagsTest.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/MethodFlagsTest.java deleted file mode 100644 index 3a0590fd81..0000000000 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/MethodFlagsTest.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.test.builtin; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.method.PDecoratedMethod; -import com.oracle.graal.python.builtins.objects.type.MethodsFlags; -import com.oracle.graal.python.nodes.SpecialMethodNames; -import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; -import com.oracle.graal.python.test.PythonTests; -import com.oracle.truffle.api.strings.TruffleString; - -public class MethodFlagsTest { - @Before - public void setUp() { - PythonTests.enterContext(); - } - - @After - public void tearDown() { - PythonTests.closeContext(); - } - - private static void assertMethodConsistentWithFlag(PythonBuiltinClassType clazz, long flags, TruffleString methodName) { - Object method = LookupAttributeInMRONode.Dynamic.getUncached().execute(clazz, methodName); - if (method instanceof PDecoratedMethod) { - // Ignore classmethods - method = PNone.NO_VALUE; - } - if ((clazz.getMethodsFlags() & flags) != 0) { - assertNotEquals( - String.format("%s has no method %s even though it sets corresponding method flags;", clazz.name(), methodName), - PNone.NO_VALUE, method); - } else { - assertEquals( - String.format("%s has method %s but it doesn't set the corresponding method flag;", clazz.name(), methodName), - PNone.NO_VALUE, method); - } - } - - @Test - public void testMethodFlagsConsistency() { - for (PythonBuiltinClassType clazz : PythonBuiltinClassType.VALUES) { - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_SUBTRACT, SpecialMethodNames.T___SUB__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_MULTIPLY | MethodsFlags.SQ_REPEAT, SpecialMethodNames.T___MUL__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_REMAINDER, SpecialMethodNames.T___MOD__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_DIVMOD, SpecialMethodNames.T___DIVMOD__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_POWER, SpecialMethodNames.T___POW__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_NEGATIVE, SpecialMethodNames.T___NEG__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_POSITIVE, SpecialMethodNames.T___POS__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_ABSOLUTE, SpecialMethodNames.T___ABS__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_BOOL, SpecialMethodNames.T___BOOL__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INVERT, SpecialMethodNames.T___INVERT__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_LSHIFT, SpecialMethodNames.T___LSHIFT__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_RSHIFT, SpecialMethodNames.T___RSHIFT__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_AND, SpecialMethodNames.T___AND__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_XOR, SpecialMethodNames.T___XOR__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_OR, SpecialMethodNames.T___OR__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INT, SpecialMethodNames.T___INT__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_FLOAT, SpecialMethodNames.T___FLOAT__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INPLACE_ADD | MethodsFlags.SQ_INPLACE_CONCAT, SpecialMethodNames.T___IADD__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INPLACE_SUBTRACT, SpecialMethodNames.T___ISUB__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INPLACE_MULTIPLY | MethodsFlags.SQ_INPLACE_REPEAT, SpecialMethodNames.T___IMUL__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INPLACE_REMAINDER, SpecialMethodNames.T___IMOD__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INPLACE_POWER, SpecialMethodNames.T___IPOW__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INPLACE_LSHIFT, SpecialMethodNames.T___ILSHIFT__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INPLACE_RSHIFT, SpecialMethodNames.T___IRSHIFT__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INPLACE_AND, SpecialMethodNames.T___IAND__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INPLACE_XOR, SpecialMethodNames.T___IXOR__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INPLACE_OR, SpecialMethodNames.T___IOR__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_FLOOR_DIVIDE, SpecialMethodNames.T___FLOORDIV__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_TRUE_DIVIDE, SpecialMethodNames.T___TRUEDIV__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INPLACE_FLOOR_DIVIDE, SpecialMethodNames.T___IFLOORDIV__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INPLACE_TRUE_DIVIDE, SpecialMethodNames.T___ITRUEDIV__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INDEX, SpecialMethodNames.T___INDEX__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_MATRIX_MULTIPLY, SpecialMethodNames.T___MATMUL__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.NB_INPLACE_MATRIX_MULTIPLY, SpecialMethodNames.T___IMATMUL__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.SQ_ITEM | MethodsFlags.MP_SUBSCRIPT, SpecialMethodNames.T___GETITEM__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.SQ_ASS_ITEM | MethodsFlags.MP_ASS_SUBSCRIPT, SpecialMethodNames.T___SETITEM__); - assertMethodConsistentWithFlag(clazz, MethodsFlags.SQ_CONTAINS, SpecialMethodNames.T___CONTAINS__); - } - } -} diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/ConversionNodeTests.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/ConversionNodeTests.java index a8efa356d8..2f710639c4 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/ConversionNodeTests.java +++ b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/ConversionNodeTests.java @@ -49,7 +49,7 @@ import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.function.Signature; import com.oracle.graal.python.nodes.PRootNode; -import com.oracle.graal.python.nodes.call.CallTargetInvokeNode; +import com.oracle.graal.python.nodes.call.CallDispatchers; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentCastNode; import com.oracle.graal.python.runtime.ExecutionContext.CalleeContext; import com.oracle.graal.python.runtime.ExecutionContext.IndirectCalleeContext; @@ -57,11 +57,12 @@ import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.frame.VirtualFrame; public class ConversionNodeTests { - static final Signature SIGNATURE = new Signature(-1, false, -1, false, tsArray("arg"), null); + static final Signature SIGNATURE = new Signature(-1, false, -1, tsArray("arg"), null); protected static Object call(Object arg, ArgumentCastNode castNode) { final PythonContext pythonContext = PythonContext.get(castNode); @@ -96,13 +97,13 @@ public boolean isPythonInternal() { }.getCallTarget(); try { Object[] arguments = PArguments.create(1); - PArguments.setGlobals(arguments, pythonContext.factory().createDict()); + PArguments.setGlobals(arguments, PFactory.createDict(language)); PArguments.setException(arguments, PException.NO_EXCEPTION); PArguments.setArgument(arguments, 0, arg); PythonThreadState threadState = pythonContext.getThreadState(language); Object state = IndirectCalleeContext.enter(threadState, arguments, callTarget); try { - return CallTargetInvokeNode.invokeUncached(callTarget, arguments); + return CallDispatchers.SimpleIndirectInvokeNode.executeUncached(callTarget, arguments); } finally { IndirectCalleeContext.exit(threadState, state); } diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/DirFdConversionNodeTests.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/DirFdConversionNodeTests.java index c50c407a1d..df5386d0be 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/DirFdConversionNodeTests.java +++ b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/DirFdConversionNodeTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -52,10 +52,11 @@ import org.junit.Before; import org.junit.Test; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.PosixModuleBuiltinsFactory; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.test.PythonTests; public class DirFdConversionNodeTests extends ConversionNodeTests { @@ -108,20 +109,20 @@ public void longTooSmall() { @Test public void pintFitsInt() { - Assert.assertEquals(42, call(factory().createInt(BigInteger.valueOf(42)))); + Assert.assertEquals(42, call(PFactory.createInt(PythonLanguage.get(null), BigInteger.valueOf(42)))); } @Test public void pintTooBig() { expectPythonMessage("OverflowError: fd is greater than maximum", () -> { - call(factory().createInt(BigInteger.ONE.shiftLeft(100))); + call(PFactory.createInt(PythonLanguage.get(null), BigInteger.ONE.shiftLeft(100))); }); } @Test public void pintTooSmall() { expectPythonMessage("OverflowError: fd is less than minimum", () -> { - call(factory().createInt(BigInteger.ONE.shiftLeft(100).negate())); + call(PFactory.createInt(PythonLanguage.get(null), BigInteger.ONE.shiftLeft(100).negate())); }); } @@ -162,10 +163,6 @@ protected static int call(Object arg) { return (int) result; } - private static PythonObjectFactory factory() { - return PythonObjectFactory.getUncached(); - } - private static Object evalValue(String source) { return PythonContext.get(null).getEnv().asGuestValue(Context.getCurrent().eval("python", source)); } diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/FileDescriptorConversionNodeTests.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/FileDescriptorConversionNodeTests.java index fcd75590d8..eeac46c197 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/FileDescriptorConversionNodeTests.java +++ b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/FileDescriptorConversionNodeTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -52,10 +52,11 @@ import org.junit.Before; import org.junit.Test; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.PosixModuleBuiltinsFactory; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.test.PythonTests; public class FileDescriptorConversionNodeTests extends ConversionNodeTests { @@ -110,20 +111,20 @@ public void longTooSmall() { @Test public void pintFitsInt() { - Assert.assertEquals(42, call(factory().createInt(BigInteger.valueOf(42)))); + Assert.assertEquals(42, call(PFactory.createInt(PythonLanguage.get(null), BigInteger.valueOf(42)))); } @Test public void pintTooBig() { expectPythonMessage("OverflowError: Python int too large to convert to Java int", () -> { - call(factory().createInt(BigInteger.ONE.shiftLeft(100))); + call(PFactory.createInt(PythonLanguage.get(null), BigInteger.ONE.shiftLeft(100))); }); } @Test public void pintTooSmall() { expectPythonMessage("OverflowError: Python int too large to convert to Java int", () -> { - call(factory().createInt(BigInteger.ONE.shiftLeft(100).negate())); + call(PFactory.createInt(PythonLanguage.get(null), BigInteger.ONE.shiftLeft(100).negate())); }); } @@ -166,10 +167,6 @@ protected static int call(Object arg) { return (int) result; } - private static PythonObjectFactory factory() { - return PythonObjectFactory.getUncached(); - } - private static Object evalValue(String source) { return PythonContext.get(null).getEnv().asGuestValue(Context.getCurrent().eval("python", source)); } diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/PathConversionNodeTests.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/PathConversionNodeTests.java index 4e11a6859f..e42ef940fd 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/PathConversionNodeTests.java +++ b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/PathConversionNodeTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -59,6 +59,7 @@ import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.PosixModuleBuiltins.PosixFd; import com.oracle.graal.python.builtins.modules.PosixModuleBuiltins.PosixPath; import com.oracle.graal.python.builtins.modules.PosixModuleBuiltinsFactory; @@ -67,7 +68,7 @@ import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.runtime.PosixSupportLibrary.Buffer; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.test.PythonTests; import com.oracle.graal.python.util.Function; import com.oracle.truffle.api.strings.TruffleString; @@ -123,7 +124,7 @@ public void noValueForbiddenWithoutFd() { @Test public void string() { Assert.assertEquals("abc", callAndExpectPath(false, false, T_ABC, false)); - Assert.assertEquals("abc", callAndExpectPath(false, false, factory().createString(T_ABC), false)); + Assert.assertEquals("abc", callAndExpectPath(false, false, PFactory.createString(PythonLanguage.get(null), T_ABC), false)); } @Test @@ -135,16 +136,16 @@ public void stringWithZero() { @Test public void bytes() { - Assert.assertEquals("abc", callAndExpectPath(false, false, factory().createBytes("abc".getBytes()), true)); - Assert.assertEquals("abc", callAndExpectPath(false, true, factory().createBytes("abc".getBytes()), true)); - Assert.assertEquals("abc", callAndExpectPath(true, false, factory().createBytes("abc".getBytes()), true)); - Assert.assertEquals("abc", callAndExpectPath(true, true, factory().createBytes("abc".getBytes()), true)); + Assert.assertEquals("abc", callAndExpectPath(false, false, PFactory.createBytes(PythonLanguage.get(null), "abc".getBytes()), true)); + Assert.assertEquals("abc", callAndExpectPath(false, true, PFactory.createBytes(PythonLanguage.get(null), "abc".getBytes()), true)); + Assert.assertEquals("abc", callAndExpectPath(true, false, PFactory.createBytes(PythonLanguage.get(null), "abc".getBytes()), true)); + Assert.assertEquals("abc", callAndExpectPath(true, true, PFactory.createBytes(PythonLanguage.get(null), "abc".getBytes()), true)); } @Test public void bytesWithZero() { expectPythonMessage("ValueError: fun: embedded null character in arg", () -> { - call(false, false, factory().createBytes("a\0c".getBytes())); + call(false, false, PFactory.createBytes(PythonLanguage.get(null), "a\0c".getBytes())); }); } @@ -221,27 +222,27 @@ public void longForbidden() { @Test public void pintFitsInt() { - Assert.assertEquals(42, callAndExpectFd(factory().createInt(BigInteger.valueOf(42)))); + Assert.assertEquals(42, callAndExpectFd(PFactory.createInt(PythonLanguage.get(null), BigInteger.valueOf(42)))); } @Test public void pintTooBig() { expectPythonMessage("OverflowError: fd is greater than maximum", () -> { - call(false, true, factory().createInt(BigInteger.ONE.shiftLeft(100))); + call(false, true, PFactory.createInt(PythonLanguage.get(null), BigInteger.ONE.shiftLeft(100))); }); } @Test public void pintTooSmall() { expectPythonMessage("OverflowError: fd is less than minimum", () -> { - call(false, true, factory().createInt(BigInteger.ONE.shiftLeft(100).negate())); + call(false, true, PFactory.createInt(PythonLanguage.get(null), BigInteger.ONE.shiftLeft(100).negate())); }); } @Test public void pintForbidden() { expectPythonMessage("TypeError: fun: arg should be string, bytes, os.PathLike or None, not int", () -> { - call(true, false, factory().createInt(BigInteger.valueOf(42))); + call(true, false, PFactory.createInt(PythonLanguage.get(null), BigInteger.valueOf(42))); }); } @@ -386,10 +387,6 @@ protected static Object call(boolean nullable, boolean allowFd, Object arg) { return call(arg, PosixModuleBuiltinsFactory.PathConversionNodeGen.create("fun", "arg", nullable, allowFd)); } - private static PythonObjectFactory factory() { - return PythonObjectFactory.getUncached(); - } - private static Object evalValue(String source) { return PythonContext.get(null).getEnv().asGuestValue(Context.getCurrent().eval("python", source)); } diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/objects/TpSlotsTests.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/objects/TpSlotsTests.java index 72754ddb3f..15edba3d06 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/objects/TpSlotsTests.java +++ b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/objects/TpSlotsTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -147,6 +147,7 @@ private static boolean getGroup(TpSlots slots, TpSlotGroup group) { case AS_NUMBER -> slots.has_as_number(); case AS_SEQUENCE -> slots.has_as_sequence(); case AS_MAPPING -> slots.has_as_mapping(); + case AS_ASYNC -> slots.has_as_async(); }; } } diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/objects/cext/CExtContextTest.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/objects/cext/CExtContextTest.java index d5d6adcf6d..ea13747810 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/objects/cext/CExtContextTest.java +++ b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/objects/cext/CExtContextTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -80,8 +80,8 @@ public void testGetBaseName() { } private static class TestCExtContext extends CExtContext { - public TestCExtContext(PythonContext context, Object llvmLibrary) { - super(context, llvmLibrary, false); + public TestCExtContext(PythonContext context, Object library) { + super(context, library); } public static TruffleString getBN(TruffleString s) { diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/objects/dict/PDictTest.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/objects/dict/PDictTest.java index 7219973429..30450f9d61 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/objects/dict/PDictTest.java +++ b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/objects/dict/PDictTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -48,11 +48,12 @@ import org.junit.Before; import org.junit.Test; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageDelItem; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageLen; import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.test.PythonTests; import com.oracle.truffle.api.strings.TruffleString; @@ -82,7 +83,7 @@ static int length(PDict dict) { @Test public void economicMapStorageTransition() { - PDict dict = PythonObjectFactory.getUncached().createDict(); + PDict dict = PFactory.createDict(PythonLanguage.get(null)); dict.setItem(ts("key1"), 42); dict.setItem(11, ts("abc")); assertTrue(dict.getDictStorage() instanceof EconomicMapStorage); @@ -91,7 +92,7 @@ public void economicMapStorageTransition() { @Test public void economicMapStorageSet() { - PDict dict = PythonObjectFactory.getUncached().createDict(); + PDict dict = PFactory.createDict(PythonLanguage.get(null)); dict.setItem(11, ts("abc")); assertTrue(dict.getDictStorage() instanceof EconomicMapStorage); @@ -103,7 +104,7 @@ public void economicMapStorageSet() { @Test public void economicMapStorageDel() { - PDict dict = PythonObjectFactory.getUncached().createDict(); + PDict dict = PFactory.createDict(PythonLanguage.get(null)); dict.setItem(11, ts("abc")); dict.setItem(ts("key1"), 42); dict.setItem(ts("key2"), 24); diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/compiler/CompilerTests.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/compiler/CompilerTests.java index a48efd2999..8759293c4a 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/compiler/CompilerTests.java +++ b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/compiler/CompilerTests.java @@ -51,6 +51,8 @@ import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; @@ -64,6 +66,7 @@ import com.oracle.graal.python.pegparser.Parser; import com.oracle.graal.python.pegparser.sst.ModTy; import com.oracle.graal.python.pegparser.tokenizer.SourceRange; +import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.test.GraalPythonEnvVars; import com.oracle.graal.python.test.PythonTests; @@ -71,6 +74,13 @@ public class CompilerTests extends PythonTests { public CompilerTests() { } + @Before + public void beforeTest() { + // These tests are coupled to the manual bytecode interpreter. They shouldn't run if we're + // using the Bytecode DSL interpreter. + Assume.assumeFalse(PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER); + } + @Rule public TestName name = new TestName(); @Test diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/datatype/PRangeTests.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/datatype/PRangeTests.java index 29ef1d1168..9968028bd0 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/datatype/PRangeTests.java +++ b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/datatype/PRangeTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -33,11 +33,11 @@ import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.range.PIntRange; import com.oracle.graal.python.builtins.objects.range.PRange; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyObjectGetIter; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.nodes.PGuards; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.test.PythonTests; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @@ -64,24 +64,20 @@ public void doInsert(Node child) { public void loopWithOnlyStop() throws UnexpectedResultException { PythonTests.enterContext(); try { - PythonObjectFactory factory = PythonObjectFactory.getUncached(); - PRange range = factory.createIntRange(10); + PythonLanguage language = PythonLanguage.get(null); + PRange range = PFactory.createIntRange(language, 10); int index = 0; - TestRoot testRoot = new TestRoot(PythonLanguage.get(factory)); Object iter = PyObjectGetIter.executeUncached(range); - GetNextNode next = GetNextNode.create(); - testRoot.doInsert(next); - IsBuiltinObjectProfile errorProfile = IsBuiltinObjectProfile.getUncached(); while (true) { try { - int item = next.executeInt(null, iter); + Object next = PyIterNextNode.executeUncached(iter); + int item = PGuards.expectInteger(next); assertEquals(index, item); - } catch (PException e) { - e.expectStopIteration(null, errorProfile); + index++; + } catch (IteratorExhausted e) { break; } - index++; } } finally { PythonTests.closeContext(); @@ -92,24 +88,20 @@ public void loopWithOnlyStop() throws UnexpectedResultException { public void loopWithStep() throws UnexpectedResultException { PythonTests.enterContext(); try { - PythonObjectFactory factory = PythonObjectFactory.getUncached(); - PRange range = PythonObjectFactory.getUncached().createIntRange(0, 10, 2, 5); + PythonLanguage language = PythonLanguage.get(null); + PRange range = PFactory.createIntRange(language, 0, 10, 2, 5); int index = 0; - TestRoot testRoot = new TestRoot(PythonLanguage.get(factory)); Object iter = PyObjectGetIter.executeUncached(range); - GetNextNode next = GetNextNode.create(); - testRoot.doInsert(next); - IsBuiltinObjectProfile errorProfile = IsBuiltinObjectProfile.getUncached(); while (true) { try { - int item = next.executeInt(null, iter); + Object next = PyIterNextNode.executeUncached(iter); + int item = PGuards.expectInteger(next); assertEquals(index, item); - } catch (PException e) { - e.expectStopIteration(null, errorProfile); + index += 2; + } catch (IteratorExhausted e) { break; } - index += 2; } } finally { PythonTests.closeContext(); @@ -120,7 +112,7 @@ public void loopWithStep() throws UnexpectedResultException { public void getItem() { PythonTests.enterContext(); try { - PIntRange range = PythonObjectFactory.getUncached().createIntRange(10); + PIntRange range = PFactory.createIntRange(PythonLanguage.get(null), 10); assertEquals(3, range.getIntItemNormalized(3)); } finally { PythonTests.closeContext(); diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/debug/PythonDebugTest.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/debug/PythonDebugTest.java index a791938d00..e18a7f9ae5 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/debug/PythonDebugTest.java +++ b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/debug/PythonDebugTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -59,6 +59,7 @@ import org.graalvm.polyglot.Context.Builder; import org.graalvm.polyglot.Source; import org.junit.After; +import org.junit.Assume; import org.junit.Before; import org.junit.Test; @@ -92,6 +93,7 @@ public void dispose() { @Test public void testSteppingAsExpected() throws Throwable { + Assume.assumeFalse("TODO: debugger tests are broken on Bytecode DSL", Boolean.getBoolean("python.EnableBytecodeDSLInterpreter")); // test that various elements step as expected, including generators, statement level atomic // expressions, and roots final Source source = Source.newBuilder("python", "" + @@ -184,6 +186,7 @@ public void testSteppingAsExpected() throws Throwable { @Test public void testException() throws Throwable { + Assume.assumeFalse("TODO: debugger tests are broken on Bytecode DSL", Boolean.getBoolean("python.EnableBytecodeDSLInterpreter")); final Source source = Source.newBuilder("python", "" + "try:\n" + " 1 / 0\n" + @@ -207,6 +210,7 @@ public void testException() throws Throwable { @Test public void testInlineEvaluation() throws Throwable { + Assume.assumeFalse("TODO: debugger tests are broken on Bytecode DSL", Boolean.getBoolean("python.EnableBytecodeDSLInterpreter")); final Source source = Source.newBuilder("python", "" + "y = 4\n" + "def foo(x):\n" + @@ -241,6 +245,7 @@ public void testInlineEvaluation() throws Throwable { @Test @SuppressWarnings("try") public void testBreakpointBuiltin() throws Throwable { + Assume.assumeFalse("TODO: debugger tests are broken on Bytecode DSL", Boolean.getBoolean("python.EnableBytecodeDSLInterpreter")); final Source source = Source.newBuilder("python", "" + "def foo():\n" + " a = 1\n" + @@ -262,6 +267,7 @@ public void testBreakpointBuiltin() throws Throwable { @Test public void testConditionalBreakpointInFunction() throws Throwable { + Assume.assumeFalse("TODO: debugger tests are broken on Bytecode DSL", Boolean.getBoolean("python.EnableBytecodeDSLInterpreter")); final Source source = Source.newBuilder("python", "" + "def fun():\n" + " def prod(n):\n" + @@ -307,6 +313,7 @@ public void testConditionalBreakpointInFunction() throws Throwable { @Test public void testConditionalBreakpointGlobal() throws Throwable { + Assume.assumeFalse("TODO: debugger tests are broken on Bytecode DSL", Boolean.getBoolean("python.EnableBytecodeDSLInterpreter")); final Source source = Source.newBuilder("python", "" + "values = []\n" + "for i in range(0, 10):\n" + @@ -330,6 +337,7 @@ public void testConditionalBreakpointGlobal() throws Throwable { @Test public void testReenterArgumentsAndValues() throws Throwable { + Assume.assumeFalse("TODO: debugger tests are broken on Bytecode DSL", Boolean.getBoolean("python.EnableBytecodeDSLInterpreter")); // Test that after a re-enter, arguments are kept and variables are cleared. final Source source = Source.newBuilder("python", "" + "def main():\n" + @@ -384,6 +392,7 @@ public void testReenterArgumentsAndValues() throws Throwable { @Test @SuppressWarnings("deprecation") public void testGettersSetters() throws Throwable { + Assume.assumeFalse("TODO: debugger tests are broken on Bytecode DSL", Boolean.getBoolean("python.EnableBytecodeDSLInterpreter")); final Source source = Source.newBuilder("python", "" + "class GetterOnly:\n" + " def __get__(self):\n" + @@ -453,6 +462,7 @@ public void testGettersSetters() throws Throwable { @Test public void testInspectJavaArray() throws Throwable { + Assume.assumeFalse("TODO: debugger tests are broken on Bytecode DSL", Boolean.getBoolean("python.EnableBytecodeDSLInterpreter")); final Source source = Source.newBuilder("python", "" + "import java\n" + "a_int = java.type('int[]')(3)\n" + @@ -498,6 +508,7 @@ public void testInspectJavaArray() throws Throwable { @Test public void testSourceFileURI() throws Throwable { + Assume.assumeFalse("TODO: debugger tests are broken on Bytecode DSL", Boolean.getBoolean("python.EnableBytecodeDSLInterpreter")); if (System.getProperty("os.name").toLowerCase().contains("mac")) { // on the mac machines we run with symlinked directories and such and it's annoying to // cater for that diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/nodes/MemMoveNodeTests.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/nodes/MemMoveNodeTests.java index c9e582cb0e..bd47cccece 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/nodes/MemMoveNodeTests.java +++ b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/nodes/MemMoveNodeTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -54,7 +54,9 @@ import com.oracle.truffle.api.nodes.RootNode; import org.junit.After; import org.junit.Assert; +import org.junit.Assume; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import java.util.Map; @@ -63,9 +65,14 @@ public class MemMoveNodeTests { private GilNode.UncachedAcquire gil; + @BeforeClass + public static void setUpClass() { + Assume.assumeFalse(System.getProperty("os.name").toLowerCase().contains("mac")); + } + @Before public void setUp() { - PythonTests.enterContext(Map.of("python.NativeModules", "false"), new String[0]); + PythonTests.enterContext(Map.of("python.IsolateNativeModules", "true"), new String[0]); this.gil = GilNode.uncachedAcquire(); CApiContext.ensureCapiWasLoaded("internal"); } diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/nodes/util/CastToJavaUnsignedLongNodeTests.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/nodes/util/CastToJavaUnsignedLongNodeTests.java index 97524bb859..7be63c54d2 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/nodes/util/CastToJavaUnsignedLongNodeTests.java +++ b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/nodes/util/CastToJavaUnsignedLongNodeTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -50,17 +50,16 @@ import org.junit.Before; import org.junit.Test; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.util.CastToJavaUnsignedLongNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.test.PythonTests; public class CastToJavaUnsignedLongNodeTests { - private static PythonObjectFactory factory = PythonObjectFactory.getUncached(); - @Before public void setUp() { PythonTests.enterContext(); @@ -127,11 +126,11 @@ public void nonInteger() { } private static PInt makePInt(long l) { - return factory.createInt(BigInteger.valueOf(l)); + return PFactory.createInt(PythonLanguage.get(null), BigInteger.valueOf(l)); } private static PInt makePInt(String hexString) { - return factory.createInt(new BigInteger(hexString, 16)); + return PFactory.createInt(PythonLanguage.get(null), new BigInteger(hexString, 16)); } private static void expect(PythonBuiltinClassType errorType, Runnable test) { diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/objects/ObjectHashMapTests.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/objects/ObjectHashMapTests.java index 7642257689..fe98a5a63f 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/objects/ObjectHashMapTests.java +++ b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/objects/ObjectHashMapTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -67,9 +67,10 @@ import com.oracle.graal.python.builtins.objects.common.ObjectHashMap; import com.oracle.graal.python.builtins.objects.common.ObjectHashMap.MapCursor; import com.oracle.graal.python.builtins.objects.common.ObjectHashMap.PopNode; +import com.oracle.graal.python.builtins.objects.common.ObjectHashMap.PutUnsafeNode; import com.oracle.graal.python.lib.PyObjectHashNode; import com.oracle.graal.python.lib.PyObjectRichCompareBool; -import com.oracle.graal.python.lib.PyObjectRichCompareBool.Comparison; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; @@ -86,9 +87,9 @@ public static final class DictKey implements TruffleObject { } } - private static final class EqNodeStub extends PyObjectRichCompareBool.EqNode { + private static final class EqNodeStub extends PyObjectRichCompareBool { @Override - protected boolean execute(Frame frame, Node inliningTarget, Object a, Object b, Comparison cmp) { + public boolean execute(Frame frame, Node inliningTarget, Object a, Object b, RichCmpOp cmp) { // Sanity check: we do not use any other keys in the tests assert a instanceof Long || a instanceof DictKey; assert b instanceof Long || b instanceof DictKey; @@ -100,7 +101,7 @@ protected boolean execute(Frame frame, Node inliningTarget, Object a, Object b, @Test public void testCollisionsByPuttingManyKeysWithSameHash() { - ObjectHashMap map = new ObjectHashMap(); + ObjectHashMap map = new ObjectHashMap(true); LinkedHashMap expected = new LinkedHashMap<>(); for (int i = 0; i < 100; i++) { DictKey key = new DictKey(42); @@ -126,7 +127,7 @@ public void testCollisionsByPuttingManyKeysWithSameHash() { @Test public void testCollisionsByPuttingAndRemovingTheSameKey() { - ObjectHashMap map = new ObjectHashMap(); + ObjectHashMap map = new ObjectHashMap(true); LinkedHashMap expected = new LinkedHashMap<>(); DictKey key = new DictKey(42); for (int i = 0; i < 100; i++) { @@ -143,7 +144,7 @@ public void testCollisionsByPuttingAndRemovingTheSameKey() { @Test public void testCollisionsByPuttingAndRemovingTheSameKeys() { - ObjectHashMap map = new ObjectHashMap(); + ObjectHashMap map = new ObjectHashMap(true); LinkedHashMap expected = new LinkedHashMap<>(); DictKey[] keys = new DictKey[]{new DictKey(42), new DictKey(1)}; for (int i = 0; i < 100; i++) { @@ -162,7 +163,7 @@ public void testCollisionsByPuttingAndRemovingTheSameKeys() { @Test public void testLongHashMapStressTest() { - ObjectHashMap map = new ObjectHashMap(); + ObjectHashMap map = new ObjectHashMap(true); // put/remove many random (with fixed seed) keys, check consistency against LinkedHashMap testBasics(map); @@ -373,7 +374,7 @@ private static void remove(ObjectHashMap map, Object key, long hash) { private static void put(ObjectHashMap map, Object key, long hash, Object value) { InlinedCountingConditionProfile uncachedCounting = InlinedCountingConditionProfile.getUncached(); - ObjectHashMap.PutNode.doPutWithRestart(null, null, map, key, hash, value, + PutUnsafeNode.doPutWithRestart(null, null, map, key, hash, value, InlinedBranchProfile.getUncached(), uncachedCounting, uncachedCounting, uncachedCounting, uncachedCounting, InlinedBranchProfile.getUncached(), InlinedBranchProfile.getUncached(), new EqNodeStub()); diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/runtime/PythonModuleTests.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/runtime/PythonModuleTests.java index d702d04fbf..ead733eca1 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/runtime/PythonModuleTests.java +++ b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/runtime/PythonModuleTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -47,6 +47,7 @@ import com.oracle.graal.python.nodes.SpecialMethodNames; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.test.PythonTests; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.RootNode; @@ -91,7 +92,7 @@ public void tearDown() { @Test public void pythonModuleTest() { - PythonModule module = context.factory().createPythonModule(tsLiteral("testModule")); + PythonModule module = PFactory.createPythonModule(context.getLanguage(), tsLiteral("testModule")); assertEquals("testModule", module.getAttribute(T___NAME__).toString()); assertEquals("None", module.getAttribute(T___DOC__).toString()); assertEquals("None", module.getAttribute(T___PACKAGE__).toString()); diff --git a/graalpython/com.oracle.graal.python.test/src/compare_unittests.py b/graalpython/com.oracle.graal.python.test/src/compare_unittests.py deleted file mode 100644 index bc44263b19..0000000000 --- a/graalpython/com.oracle.graal.python.test/src/compare_unittests.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# The Universal Permissive License (UPL), Version 1.0 -# -# Subject to the condition set forth below, permission is hereby granted to any -# person obtaining a copy of this software, associated documentation and/or -# data (collectively the "Software"), free of charge and under any and all -# copyright rights in the Software, and any and all patent rights owned or -# freely licensable by each licensor hereunder covering either (i) the -# unmodified Software as contributed to or provided by such licensor, or (ii) -# the Larger Works (as defined below), to deal in both -# -# (a) the Software, and -# -# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -# one is included with the Software each a "Larger Work" to which the Software -# is contributed by such licensors), -# -# without restriction, including without limitation the rights to copy, create -# derivative works of, display, perform, and distribute the Software and make, -# use, sell, offer for sale, import, export, have made, and have sold the -# Software and the Larger Work(s), and to sublicense the foregoing rights on -# either these or other terms. -# -# This license is subject to the following condition: -# -# The above copyright notice and either this complete permission notice or at a -# minimum a reference to the UPL must be included in all copies or substantial -# portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import sys -import csv -import argparse - -def read_file(filename): - with open(filename) as csvfile: - return {x["unittest"]:x for x in csv.DictReader(csvfile) if x["unittest"] != "TOTAL"} - -# ---------------------------------------------------------------------------------------------------------------------- -# -# main tool -# -# ---------------------------------------------------------------------------------------------------------------------- -def main(prog, args): - parser = argparse.ArgumentParser(prog=prog, - description="Compare the result of two runs of the standard python unittests based on their csv reports.") - parser.add_argument("-v", "--verbose", help="Verbose output.", action="http://github.com/store_true") - parser.add_argument("csvfile1", help="first input csv file") - parser.add_argument("csvfile2", help="first input csv file") - - global flags - flags = parser.parse_args(args=args) - print("comparing {} and {}".format(flags.csvfile1, flags.csvfile2)) - - raw1 = read_file(flags.csvfile1) - raw2 = read_file(flags.csvfile2) - print("number of entries: {} / {}".format(len(raw1.keys()), len(raw2.keys()))) - - result = [] - missing_tests = [] - new_tests = [] - for name, data in raw1.items(): - other_data = raw2.get(name) - if other_data: - result.append({'name':name, 'old_passing':int(data['num_passes']), 'new_passing':int(other_data['num_passes'])}) - else: - missing_tests.append(name) - - for name in raw2.keys(): - if not raw1.get(name): - new_tests.append(name) - - def custom(a): - return (a['new_passing'] - a['old_passing']) * 1000000 + a['old_passing'] - - result = sorted(result, key=custom) - - RED = u"\u001b[31m" - GREEN = u"\u001b[32m" - RESET = u"\u001b[0m" - - for entry in result: - delta = entry['new_passing'] - entry['old_passing'] - if delta != 0: - print("%s%30s: %d (from %d to %d passing tests)" % (GREEN if delta > 0 else RED, entry['name'], delta, entry['old_passing'], entry['new_passing'])) - print(RESET) - -if __name__ == "__main__": - main(sys.argv[0], sys.argv[1:]) diff --git a/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/cext/test/MultiContextCExtTest.java b/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/cext/test/MultiContextCExtTest.java index 86165c3fa0..7a02e794e3 100644 --- a/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/cext/test/MultiContextCExtTest.java +++ b/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/cext/test/MultiContextCExtTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,19 +41,17 @@ package org.graalvm.python.embedding.cext.test; +import static org.graalvm.python.embedding.test.EmbeddingTestUtils.createVenv; +import static org.graalvm.python.embedding.test.EmbeddingTestUtils.deleteDirOnShutdown; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Set; import java.util.logging.Handler; import java.util.logging.LogRecord; @@ -61,18 +59,28 @@ import org.graalvm.polyglot.Engine; import org.graalvm.polyglot.PolyglotException; import org.graalvm.polyglot.Source; -import org.graalvm.python.embedding.tools.exec.SubprocessLog; +import org.graalvm.python.embedding.tools.exec.BuildToolLog; import org.graalvm.python.embedding.tools.vfs.VFSUtils; -import org.graalvm.python.embedding.tools.vfs.VFSUtils.Log; +import org.junit.Assume; +import org.junit.BeforeClass; import org.junit.Test; +import com.oracle.graal.python.runtime.PythonOptions; + public class MultiContextCExtTest { - static final class TestLog extends Handler implements SubprocessLog, Log { + @BeforeClass + public static void setUpClass() { + Assume.assumeFalse(System.getProperty("os.name").toLowerCase().contains("mac")); + } + + static final class TestLog extends Handler implements BuildToolLog { final StringBuilder logCharSequence = new StringBuilder(); final StringBuilder logThrowable = new StringBuilder(); final StringBuilder stderr = new StringBuilder(); final StringBuilder stdout = new StringBuilder(); final StringBuilder info = new StringBuilder(); + final StringBuilder warn = new StringBuilder(); + final StringBuilder debug = new StringBuilder(); final StringBuilder truffleLog = new StringBuilder(); static void println(CharSequence... args) { @@ -81,103 +89,115 @@ static void println(CharSequence... args) { } } - public void log(CharSequence txt) { - println("[log]", txt); - logCharSequence.append(txt); - } - - public void log(CharSequence txt, Throwable t) { - println("[log]", txt); + @Override + public void warning(String txt, Throwable t) { + println("[warning]", txt); println("[throwable]", t.getMessage()); logThrowable.append(txt).append(t.getMessage()); } - public void subProcessErr(CharSequence err) { + @Override + public void error(String s) { + println("[err]", s); + stderr.append(s); + } + + @Override + public void debug(String s) { + println("[debug]", s); + debug.append(s); + } + + @Override + public void subProcessErr(String err) { println("[err]", err); stderr.append(err); } - public void subProcessOut(CharSequence out) { + @Override + public void subProcessOut(String out) { println("[out]", out); stdout.append(out); } + @Override public void info(String s) { println("[info]", s); info.append(s); } @Override - public void publish(LogRecord record) { - var msg = String.format("[%s] %s: %s", record.getLoggerName(), record.getLevel().getName(), String.format(record.getMessage(), record.getParameters())); - println(msg); - truffleLog.append(msg); + public void warning(String s) { + println("[warning]", s); + warn.append(s); } @Override - public void flush() { + public boolean isDebugEnabled() { + return true; } @Override - public void close() { + public boolean isWarningEnabled() { + return true; } - } - private static Path createVenv(TestLog log, String... packages) throws IOException { - var tmpdir = Files.createTempDirectory("graalpytest"); - deleteDirOnShutdown(tmpdir); - var venvdir = tmpdir.resolve("venv"); - try { - VFSUtils.createVenv(venvdir, Arrays.asList(packages), tmpdir.resolve("graalpy.exe"), () -> getClasspath(), "", log, log); - } catch (RuntimeException e) { - System.err.println(getClasspath()); - throw e; + @Override + public boolean isInfoEnabled() { + return true; } - return venvdir; - } - private static void deleteDirOnShutdown(Path tmpdir) { - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - try (var fs = Files.walk(tmpdir)) { - fs.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); - } catch (IOException e) { - } - })); - } + @Override + public boolean isErrorEnabled() { + return true; + } + + @Override + public boolean isSubprocessOutEnabled() { + return true; + } + + @Override + public void publish(LogRecord record) { + var msg = String.format("[%s] %s: %s", record.getLoggerName(), record.getLevel().getName(), String.format(record.getMessage(), record.getParameters())); + println(msg); + truffleLog.append(msg); + } - private static Set getClasspath() { - var sb = new ArrayList(); - var modPath = System.getProperty("jdk.module.path"); - if (modPath != null) { - sb.add(modPath); + @Override + public void flush() { } - var classPath = System.getProperty("java.class.path"); - if (classPath != null) { - sb.add(classPath); + + @Override + public void close() { } - var cp = String.join(File.pathSeparator, sb); - return Set.copyOf(Arrays.stream(cp.split(File.pathSeparator)).toList()); } @Test - public void testCreatingVenvForMulticontext() throws IOException { + public void testCreatingVenvForMulticontext() throws IOException, VFSUtils.PackagesChangedException { + Assume.assumeFalse(PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER); var log = new TestLog(); - Path venv; + Path tmpdir = Files.createTempDirectory("MultiContextCExtTest"); + Path venvDir = tmpdir.resolve("venv"); + deleteDirOnShutdown(tmpdir); String pythonNative; String exe; if (System.getProperty("os.name").toLowerCase().contains("win")) { pythonNative = "python-native.dll"; - venv = createVenv(log, "delvewheel==1.9.0"); - exe = venv.resolve("Scripts").resolve("python.exe").toString().replace('\\', '/'); + createVenv(venvDir, "0.1", log, "delvewheel==1.9.0"); + + exe = venvDir.resolve("Scripts").resolve("python.exe").toString().replace('\\', '/'); } else if (System.getProperty("os.name").toLowerCase().contains("mac")) { pythonNative = "libpython-native.dylib"; - venv = createVenv(log); - exe = venv.resolve("bin").resolve("python").toString(); + createVenv(venvDir, "0.1", log); + + exe = venvDir.resolve("bin").resolve("python").toString(); } else { pythonNative = "libpython-native.so"; - venv = createVenv(log, "patchelf"); - exe = venv.resolve("bin").resolve("python").toString(); + createVenv(venvDir, "0.1", log, "patchelf"); + + exe = venvDir.resolve("bin").resolve("python").toString(); } var engine = Engine.newBuilder("python").logHandler(log).build(); @@ -188,11 +208,11 @@ public void testCreatingVenvForMulticontext() throws IOException { Context c0, c1, c2, c3, c4, c5; contexts.add(c0 = builder.build()); c0.initialize("python"); - c0.eval("python", String.format("__graalpython__.replicate_extensions_in_venv('%s', 2)", venv.toString().replace('\\', '/'))); + c0.eval("python", String.format("__graalpython__.replicate_extensions_in_venv('%s', 2)", venvDir.toString().replace('\\', '/'))); - assertTrue("created a copy of the capi", Files.list(venv).anyMatch((p) -> p.getFileName().toString().startsWith(pythonNative) && p.getFileName().toString().endsWith(".dup0"))); - assertTrue("created another copy of the capi", Files.list(venv).anyMatch((p) -> p.getFileName().toString().startsWith(pythonNative) && p.getFileName().toString().endsWith(".dup1"))); - assertFalse("created no more copies of the capi", Files.list(venv).anyMatch((p) -> p.getFileName().toString().startsWith(pythonNative) && p.getFileName().toString().endsWith(".dup2"))); + assertTrue("created a copy of the capi", Files.list(venvDir).anyMatch((p) -> p.getFileName().toString().startsWith(pythonNative) && p.getFileName().toString().endsWith(".dup0"))); + assertTrue("created another copy of the capi", Files.list(venvDir).anyMatch((p) -> p.getFileName().toString().startsWith(pythonNative) && p.getFileName().toString().endsWith(".dup1"))); + assertFalse("created no more copies of the capi", Files.list(venvDir).anyMatch((p) -> p.getFileName().toString().startsWith(pythonNative) && p.getFileName().toString().endsWith(".dup2"))); builder.option("python.IsolateNativeModules", "true"); contexts.add(c1 = builder.build()); @@ -211,7 +231,7 @@ public void testCreatingVenvForMulticontext() throws IOException { // First one works var r1 = c1.eval(code); assertEquals("tiny_sha3", r1.asString()); - assertFalse("created no more copies of the capi", Files.list(venv).anyMatch((p) -> p.getFileName().toString().startsWith(pythonNative) && p.getFileName().toString().endsWith(".dup2"))); + assertFalse("created no more copies of the capi", Files.list(venvDir).anyMatch((p) -> p.getFileName().toString().startsWith(pythonNative) && p.getFileName().toString().endsWith(".dup2"))); // Second one works because of isolation var r2 = c2.eval(code); assertEquals("tiny_sha3", r2.asString()); @@ -221,10 +241,10 @@ public void testCreatingVenvForMulticontext() throws IOException { // first context is unaffected r1 = c1.eval(code); assertEquals("tiny_sha3", r1.asString()); - assertFalse("created no more copies of the capi", Files.list(venv).anyMatch((p) -> p.getFileName().toString().startsWith(pythonNative) && p.getFileName().toString().endsWith(".dup2"))); + assertFalse("created no more copies of the capi", Files.list(venvDir).anyMatch((p) -> p.getFileName().toString().startsWith(pythonNative) && p.getFileName().toString().endsWith(".dup2"))); // Third one works and triggers a dynamic relocation c3.eval(code); - assertTrue("created another copy of the capi", Files.list(venv).anyMatch((p) -> p.getFileName().toString().startsWith(pythonNative) && p.getFileName().toString().endsWith(".dup2"))); + assertTrue("created another copy of the capi", Files.list(venvDir).anyMatch((p) -> p.getFileName().toString().startsWith(pythonNative) && p.getFileName().toString().endsWith(".dup2"))); // Fourth one does not work because we changed the sys.prefix c4.eval("python", "import sys; sys.prefix = 12"); try { @@ -233,20 +253,14 @@ public void testCreatingVenvForMulticontext() throws IOException { } catch (PolyglotException e) { assertTrue("We rely on sys.prefix", e.getMessage().contains("sys.prefix must be a str")); } - // Fifth one does not work because we don't have the venv configured - try { - c5.eval(code); - fail("should not reach here"); - } catch (PolyglotException e) { - assertTrue("We need a venv", e.getMessage().contains("sys.prefix must point to a venv")); - } - // Using a context without isolation in the same process needs to use LLVM - assertFalse("have not had a context use LLVM, yet", log.truffleLog.toString().contains("as bitcode")); + // Fifth works even without a venv + c5.eval(code); + // Using a context without isolation in the same process does not work try { c0.eval(code); fail("should not reach here"); } catch (PolyglotException e) { - assertTrue("needs LLVM", e.getMessage().contains("LLVM")); + assertTrue("needs IsolateNativeModules", e.getMessage().contains("cannot use native module")); } } finally { for (var c : contexts) { diff --git a/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/test/EmbeddingTestUtils.java b/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/test/EmbeddingTestUtils.java new file mode 100644 index 0000000000..36819a68b0 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/test/EmbeddingTestUtils.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.graalvm.python.embedding.test; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Set; + +import org.graalvm.python.embedding.tools.exec.BuildToolLog; +import org.graalvm.python.embedding.tools.vfs.VFSUtils; +import org.graalvm.python.embedding.tools.vfs.VFSUtils.Launcher; + +public final class EmbeddingTestUtils { + private EmbeddingTestUtils() { + } + + public static void createVenv(Path venvDir, String graalPyVersion, BuildToolLog log, String... packages) throws IOException, VFSUtils.PackagesChangedException { + createVenv(venvDir, graalPyVersion, log, null, null, packages); + } + + public static void createVenv(Path venvDir, String graalPyVersion, BuildToolLog log, Path lockFile, String missingLockFileWarning, String... packages) + throws IOException, VFSUtils.PackagesChangedException { + try { + info(log, "<<<<<< create test venv %s <<<<<<", venvDir); + + Launcher launcher = createLauncher(venvDir); + if (lockFile != null) { + VFSUtils.createVenv(venvDir, Arrays.asList(packages), lockFile, missingLockFileWarning, launcher, graalPyVersion, log); + } else { + VFSUtils.createVenv(venvDir, Arrays.asList(packages), launcher, graalPyVersion, log); + } + } catch (RuntimeException e) { + System.err.println(getClasspath()); + throw e; + } finally { + info(log, ">>>>>> create test venv %s >>>>>>", venvDir); + } + } + + private static void info(BuildToolLog log, String txt, Object... args) { + if (log.isInfoEnabled()) { + log.info(String.format(txt, args)); + } + } + + public static Launcher createLauncher(Path venvDir) { + return new Launcher(venvDir.getParent().resolve(VFSUtils.LAUNCHER_NAME)) { + @Override + public Set computeClassPath() { + return getClasspath(); + } + }; + } + + public static void deleteDirOnShutdown(Path tmpdir) { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + delete(tmpdir); + } catch (IOException e) { + } + })); + } + + public static void delete(Path dir) throws IOException { + try (var fs = Files.walk(dir)) { + fs.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); + } + } + + private static Set getClasspath() { + var sb = new ArrayList(); + var modPath = System.getProperty("jdk.module.path"); + if (modPath != null) { + sb.add(modPath); + } + var classPath = System.getProperty("java.class.path"); + if (classPath != null) { + sb.add(classPath); + } + var cp = String.join(File.pathSeparator, sb); + return Set.copyOf(Arrays.stream(cp.split(File.pathSeparator)).toList()); + } +} diff --git a/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/test/VirtualFileSystemTest.java b/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/test/VirtualFileSystemTest.java index b4b4fc19a9..d4225c11d6 100644 --- a/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/test/VirtualFileSystemTest.java +++ b/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/test/VirtualFileSystemTest.java @@ -171,7 +171,9 @@ public void toRealPath() throws Exception { for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS}) { assertTrue(Files.isSameFile(realFSPath, fs.toRealPath(realFSPath))); withCWD(fs, realFSDir, (fst) -> assertTrue(Files.isSameFile(realFSPath, fst.toRealPath(Path.of("..", realFSPath.getParent().getFileName().toString(), "extractme"))))); - withCWD(fs, VFS_ROOT_PATH, (fst) -> assertTrue(Files.isSameFile(realFSPath, fst.toRealPath(Path.of("..", realFSPath.toString()))))); + if (!IS_WINDOWS) { + withCWD(fs, VFS_ROOT_PATH, (fst) -> assertTrue(Files.isSameFile(realFSPath, fst.toRealPath(Path.of("..", realFSPath.toString()))))); + } } checkException(SecurityException.class, () -> noHostIOVFS.toRealPath(realFSPath), "expected error for no host io fs"); } @@ -227,8 +229,10 @@ public void toAbsolutePath() throws Exception { // absolute path starting with VFS, pointing to real FS // /VFS_ROOT/../real/fs/path/ - p = Path.of(VFS_MOUNT_POINT, "..", realFSPath.toString()); - assertEquals(p, fs.toAbsolutePath(p)); + if (!IS_WINDOWS) { + p = Path.of(VFS_MOUNT_POINT, "..", realFSPath.toString()); + assertEquals(p, fs.toAbsolutePath(p)); + } // absolute path starting with real FS, pointing to VFS // /real/fs/path/../../../VFS_MOUNT_POINT @@ -242,22 +246,41 @@ public void toAbsolutePath() throws Exception { // no CWD set, so relative path starting in real FS, pointing to VFS // ../../../VFS_ROOT Path cwd = Path.of(".").toAbsolutePath(); - p = fs.toAbsolutePath(Path.of(dotdot(cwd.getNameCount()).toString(), MOUNT_POINT_NAME)); - assertTrue(p.isAbsolute()); - assertEquals(VFS_ROOT_PATH, p.normalize()); - - // ../../../VFS_ROOT/../real/fs/path - p = fs.toAbsolutePath(Path.of(dotdot(cwd.getNameCount()).toString(), MOUNT_POINT_NAME, "..", realFSPath.toString())); - assertTrue(p.isAbsolute()); - assertEquals(realFSPath, p.normalize()); - - // CWD is VFS_ROOT, relative path pointing to real FS - // ../real/fs/path - withCWD(fs, VFS_ROOT_PATH, (fst) -> { - Path pp = fst.toAbsolutePath(Path.of("..", realFSPath.toString())); - assertTrue(pp.isAbsolute()); - assertEquals(realFSPath, pp.normalize()); - }); + if (!IS_WINDOWS) { + p = fs.toAbsolutePath(Path.of(dotdot(cwd.getNameCount()).toString(), MOUNT_POINT_NAME)); + assertTrue(p.isAbsolute()); + assertEquals(VFS_ROOT_PATH, p.normalize()); + + // ../../../VFS_ROOT/../real/fs/path + p = fs.toAbsolutePath(Path.of(dotdot(cwd.getNameCount()).toString(), MOUNT_POINT_NAME, "..", realFSPath.toString())); + assertTrue(p.isAbsolute()); + assertEquals(realFSPath, p.normalize()); + + // CWD is VFS_ROOT, relative path pointing to real FS + // ../real/fs/path + withCWD(fs, VFS_ROOT_PATH, (fst) -> { + Path pp = fst.toAbsolutePath(Path.of("..", realFSPath.toString())); + assertTrue(pp.isAbsolute()); + assertEquals(realFSPath, pp.normalize()); + }); + + // CWD is real FS, relative path pointing to VFS + // real/fs/path/../../ + withCWD(fs, realFSPath.getParent(), (fst) -> { + Path pp = fst.toAbsolutePath(Path.of("dir", dotdot(realFSDirDir.getNameCount()), MOUNT_POINT_NAME)); + assertTrue(pp.isAbsolute()); + assertEquals(VFS_ROOT_PATH, pp.normalize()); + }); + + // CWD is real FS, relative path pointing through VFS to real FS + // real/fs/path/../../../VFS + withCWD(fs, realFSPath.getParent(), + (fst) -> { + Path pp = fst.toAbsolutePath(Path.of("dir", dotdot(realFSDirDir.getNameCount()), MOUNT_POINT_NAME, "..", realFSPath.toString())); + assertTrue(pp.isAbsolute()); + assertEquals(realFSPath, pp.normalize()); + }); + } // CWD is VFS_ROOT, relative path pointing through real FS back to VFS // ../some/path/../../VFS_ROOT_PATH @@ -267,23 +290,6 @@ public void toAbsolutePath() throws Exception { assertEquals(VFS_ROOT_PATH, pp.normalize()); }); - // CWD is real FS, relative path pointing to VFS - // real/fs/path/../../ - withCWD(fs, realFSPath.getParent(), (fst) -> { - Path pp = fst.toAbsolutePath(Path.of("dir", dotdot(realFSDirDir.getNameCount()), MOUNT_POINT_NAME)); - assertTrue(pp.isAbsolute()); - assertEquals(VFS_ROOT_PATH, pp.normalize()); - }); - - // CWD is real FS, relative path pointing through VFS to real FS - // real/fs/path/../../../VFS - withCWD(fs, realFSPath.getParent(), - (fst) -> { - Path pp = fst.toAbsolutePath(Path.of("dir", dotdot(realFSDirDir.getNameCount()), MOUNT_POINT_NAME, "..", realFSPath.toString())); - assertTrue(pp.isAbsolute()); - assertEquals(realFSPath, pp.normalize()); - }); - assertEquals(Path.of("extractme").toAbsolutePath(), fs.toAbsolutePath(Path.of("extractme"))); withCWD(fs, realFSPath.getParent(), (fst) -> assertEquals(realFSPath, fst.toAbsolutePath(realFSPath.getFileName()))); @@ -379,7 +385,9 @@ public void checkAccess() throws Exception { for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS}) { fs.checkAccess(realFSPath, Set.of(AccessMode.READ)); withCWD(fs, realFSPath.getParent(), (fst) -> fst.checkAccess(realFSPath.getFileName(), Set.of(AccessMode.READ))); - withCWD(fs, VFS_ROOT_PATH, (fst) -> fst.checkAccess(Path.of("..", realFSPath.toString()), Set.of(AccessMode.READ))); + if (!IS_WINDOWS) { + withCWD(fs, VFS_ROOT_PATH, (fst) -> fst.checkAccess(Path.of("..", realFSPath.toString()), Set.of(AccessMode.READ))); + } } checkException(SecurityException.class, () -> noHostIOVFS.checkAccess(realFSPath, Set.of(AccessMode.READ)), "expected error for no host io fs"); } @@ -440,12 +448,14 @@ public void createDirectory() throws Exception { fs.createDirectory(newDir2.getFileName()); assertTrue(Files.exists(newDir2)); }); - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> { - Path newDir3 = newDir.getParent().resolve("newdir3"); - assertFalse(Files.exists(newDir3)); - fs.createDirectory(Path.of("..", newDir3.toString())); - assertTrue(Files.exists(newDir3)); - }); + if (!IS_WINDOWS) { + withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> { + Path newDir3 = newDir.getParent().resolve("newdir3"); + assertFalse(Files.exists(newDir3)); + fs.createDirectory(Path.of("..", newDir3.toString())); + assertTrue(Files.exists(newDir3)); + }); + } } @Test @@ -479,10 +489,12 @@ public void delete() throws Exception { withCWD(rwHostIOVFS, realFSPath.getParent(), (fs) -> rwHostIOVFS.delete(realFSPath.getFileName())); assertFalse(Files.exists(realFSPath)); - Files.createFile(realFSPath); - assertTrue(Files.exists(realFSPath)); - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> rwHostIOVFS.delete(Path.of("..", realFSPath.toString()))); - assertFalse(Files.exists(realFSPath)); + if (!IS_WINDOWS) { + Files.createFile(realFSPath); + assertTrue(Files.exists(realFSPath)); + withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> rwHostIOVFS.delete(Path.of("..", realFSPath.toString()))); + assertFalse(Files.exists(realFSPath)); + } } private static void deleteVFS(FileSystem fs, String pathPrefix) { @@ -515,13 +527,17 @@ public void newByteChannel() throws Exception { Path realFSPath = Files.createTempDirectory("graalpy.vfs.test").resolve("extractme"); Files.createFile(realFSPath); checkException(SecurityException.class, () -> rHostIOVFS.newByteChannel(realFSPath, Set.of(StandardOpenOption.WRITE)), "cant write into a read-only host FS"); - rwHostIOVFS.newByteChannel(realFSPath, Set.of(StandardOpenOption.WRITE)).write(ByteBuffer.wrap("text".getBytes())); + try (SeekableByteChannel ch = rwHostIOVFS.newByteChannel(realFSPath, Set.of(StandardOpenOption.WRITE))) { + ch.write(ByteBuffer.wrap("text".getBytes())); + } assertTrue(Files.exists(realFSPath)); for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS}) { newByteChannelRealFS(fs, realFSPath, "text"); withCWD(fs, realFSPath.getParent(), (fst) -> newByteChannelRealFS(fs, realFSPath.getFileName(), "text")); - withCWD(fs, VFS_ROOT_PATH, (fst) -> newByteChannelRealFS(fs, Path.of("..", realFSPath.toString()), "text")); + if (!IS_WINDOWS) { + withCWD(fs, VFS_ROOT_PATH, (fst) -> newByteChannelRealFS(fs, Path.of("..", realFSPath.toString()), "text")); + } } } @@ -544,26 +560,28 @@ private static void newByteChannelVFS(FileSystem fs, String pathPrefix) throws I } private static void newByteChannelVFS(FileSystem fs, Path path, Set options) throws IOException { - SeekableByteChannel bch = fs.newByteChannel(path, options); - ByteBuffer buffer = ByteBuffer.allocate(1024); - bch.read(buffer); - String s = new String(buffer.array()); - String[] ss = s.split(System.lineSeparator()); - assertTrue(ss.length >= 2); - assertEquals("text1", ss[0]); - assertEquals("text2", ss[1]); - checkException(NonWritableChannelException.class, () -> bch.write(buffer), "should not be able to write to VFS"); - checkException(NonWritableChannelException.class, () -> bch.truncate(0), "should not be able to write to VFS"); + try (SeekableByteChannel bch = fs.newByteChannel(path, options)) { + ByteBuffer buffer = ByteBuffer.allocate(1024); + bch.read(buffer); + String s = new String(buffer.array()); + String[] ss = s.split(System.lineSeparator()); + assertTrue(ss.length >= 2); + assertEquals("text1", ss[0]); + assertEquals("text2", ss[1]); + checkException(NonWritableChannelException.class, () -> bch.write(buffer), "should not be able to write to VFS"); + checkException(NonWritableChannelException.class, () -> bch.truncate(0), "should not be able to write to VFS"); + } } private static void newByteChannelRealFS(FileSystem fs, Path path, String expectedText) throws IOException { - SeekableByteChannel bch = fs.newByteChannel(path, Set.of(StandardOpenOption.READ)); - ByteBuffer buffer = ByteBuffer.allocate(expectedText.length()); - bch.read(buffer); - String s = new String(buffer.array()); - String[] ss = s.split(System.lineSeparator()); - assertTrue(ss.length >= 1); - assertEquals(expectedText, ss[0]); + try (SeekableByteChannel bch = fs.newByteChannel(path, Set.of(StandardOpenOption.READ))) { + ByteBuffer buffer = ByteBuffer.allocate(expectedText.length()); + bch.read(buffer); + String s = new String(buffer.array()); + String[] ss = s.split(System.lineSeparator()); + assertTrue(ss.length >= 1); + assertEquals(expectedText, ss[0]); + } } private static void checkCanOnlyRead(FileSystem fs, Path path, StandardOpenOption... options) { @@ -590,11 +608,13 @@ public void newDirectoryStream() throws Exception { checkException(NotDirectoryException.class, () -> fs.newDirectoryStream(realFSFile, (p) -> true)); newDirectoryStreamRealFS(fs, realFSDir, realFSFile); withCWD(fs, realFSDir.getParent(), (fst) -> newDirectoryStreamRealFS(fs, realFSDir.getFileName(), realFSFile)); - withCWD(fs, VFS_ROOT_PATH, (fst) -> newDirectoryStreamRealFS(fs, Path.of("..", realFSDir.toString()), realFSFile)); - // from real fs to VFS - withCWD(fs, realFSDir, (fst) -> newDirectoryStreamVFS(fs, Path.of(dotdot(realFSDir.getNameCount()), VFS_MOUNT_POINT).toString())); - // from VFS to real FS - withCWD(fs, VFS_ROOT_PATH, (fst) -> newDirectoryStreamRealFS(fs, Path.of("..", realFSDir.toString()), realFSFile)); + if (!IS_WINDOWS) { + withCWD(fs, VFS_ROOT_PATH, (fst) -> newDirectoryStreamRealFS(fs, Path.of("..", realFSDir.toString()), realFSFile)); + // from real fs to VFS + withCWD(fs, realFSDir, (fst) -> newDirectoryStreamVFS(fs, Path.of(dotdot(realFSDir.getNameCount()), VFS_MOUNT_POINT).toString())); + // from VFS to real FS + withCWD(fs, VFS_ROOT_PATH, (fst) -> newDirectoryStreamRealFS(fs, Path.of("..", realFSDir.toString()), realFSFile)); + } } checkException(SecurityException.class, () -> noHostIOVFS.newDirectoryStream(realFSDir, null), "expected error for no host io fs"); } @@ -645,7 +665,9 @@ public void readAttributes() throws Exception { for (FileSystem fs : new FileSystem[]{rHostIOVFS, rwHostIOVFS}) { assertTrue(((FileTime) fs.readAttributes(realFSPath, "creationTime").get("creationTime")).toMillis() > 0); withCWD(fs, realFSPath.getParent(), (fst) -> assertTrue(((FileTime) fs.readAttributes(realFSPath.getFileName(), "creationTime").get("creationTime")).toMillis() > 0)); - withCWD(fs, VFS_ROOT_PATH, (fst) -> assertTrue(((FileTime) fs.readAttributes(Path.of("..", realFSPath.toString()), "creationTime").get("creationTime")).toMillis() > 0)); + if (!IS_WINDOWS) { + withCWD(fs, VFS_ROOT_PATH, (fst) -> assertTrue(((FileTime) fs.readAttributes(Path.of("..", realFSPath.toString()), "creationTime").get("creationTime")).toMillis() > 0)); + } } checkException(SecurityException.class, () -> noHostIOVFS.readAttributes(realFSPath, "creationTime"), "expected error for no host io fs"); @@ -822,8 +844,10 @@ public void getMimeType() throws Exception { checkException(NullPointerException.class, () -> fs.getMimeType(null)); Assert.assertNull(fs.getMimeType(VFS_ROOT_PATH)); fs.getMimeType(realFSPath); - // whatever the return value, just check it does not fail - withCWD(fs, VFS_ROOT_PATH, (fst) -> fst.getMimeType(Path.of("..", realFSPath.toString()))); + if (!IS_WINDOWS) { + // whatever the return value, just check it does not fail + withCWD(fs, VFS_ROOT_PATH, (fst) -> fst.getMimeType(Path.of("..", realFSPath.toString()))); + } } } @@ -835,8 +859,10 @@ public void getEncoding() throws Exception { checkException(NullPointerException.class, () -> fs.getEncoding(null)); Assert.assertNull(fs.getEncoding(VFS_ROOT_PATH)); fs.getEncoding(realFSPath); - // whatever the return value, just check it does not fail - withCWD(fs, VFS_ROOT_PATH, (fst) -> fst.getEncoding(Path.of("..", realFSPath.toString()))); + if (!IS_WINDOWS) { + // whatever the return value, just check it does not fail + withCWD(fs, VFS_ROOT_PATH, (fst) -> fst.getEncoding(Path.of("..", realFSPath.toString()))); + } } } @@ -853,7 +879,9 @@ public void setAttribute() throws Exception { // just check it does not fail for real FS paths rwHostIOVFS.setAttribute(realFSPath, "creationTime", FileTime.fromMillis(42)); - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fst) -> fst.setAttribute(Path.of("..", realFSPath.toString()), "creationTime", FileTime.fromMillis(43))); + if (!IS_WINDOWS) { + withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fst) -> fst.setAttribute(Path.of("..", realFSPath.toString()), "creationTime", FileTime.fromMillis(43))); + } } @Test @@ -871,9 +899,13 @@ public void isSameFile() throws Exception { assertFalse(fs.isSameFile(realFSDir, VFS_ROOT_PATH)); assertFalse(fs.isSameFile(VFS_ROOT_PATH, realFSDir)); if (fs == noHostIOVFS) { - withCWD(fs, VFS_ROOT_PATH, (fst) -> checkException(SecurityException.class, () -> fst.isSameFile(realFSDir, Path.of("..", realFSDir.toString())))); + if (!IS_WINDOWS) { + withCWD(fs, VFS_ROOT_PATH, (fst) -> checkException(SecurityException.class, () -> fst.isSameFile(realFSDir, Path.of("..", realFSDir.toString())))); + } } else { - withCWD(fs, VFS_ROOT_PATH, (fst) -> assertTrue(fst.isSameFile(realFSDir, Path.of("..", realFSDir.toString())))); + if (!IS_WINDOWS) { + withCWD(fs, VFS_ROOT_PATH, (fst) -> assertTrue(fst.isSameFile(realFSDir, Path.of("..", realFSDir.toString())))); + } withCWD(fs, realFSDir, (fst) -> assertTrue(fs.isSameFile(realFSFile1.getFileName(), realFSFile1.getFileName()))); withCWD(fs, realFSDir, (fst) -> assertFalse(fs.isSameFile(realFSFile1.getFileName(), realFSFile2.getFileName()))); } @@ -901,8 +933,10 @@ public void createLink() throws Exception { assertTrue(Files.exists(link)); Path link2 = realFSDir.resolve("link2"); assertFalse(Files.exists(link2)); - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> rwHostIOVFS.createLink(Path.of("..", link2.toString()), Path.of("..", realFSFile.toString()))); - assertTrue(Files.exists(link2)); + if (!IS_WINDOWS) { + withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> rwHostIOVFS.createLink(Path.of("..", link2.toString()), Path.of("..", realFSFile.toString()))); + assertTrue(Files.exists(link2)); + } checkException(SecurityException.class, () -> rHostIOVFS.createLink(realFSDir.resolve("link3"), realFSFile)); checkException(SecurityException.class, () -> noHostIOVFS.createLink(realFSDir.resolve("link4"), realFSFile)); @@ -931,10 +965,12 @@ public void createAndReadSymbolicLink() throws Exception { rwHostIOVFS.createSymbolicLink(symlink, realFSLinkTarget); checkSymlink(realFSDir, realFSLinkTarget, symlink); - Files.delete(symlink); - assertFalse(Files.exists(symlink)); - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fst) -> fst.createSymbolicLink(Path.of("..", symlink.toString()), realFSLinkTarget)); - checkSymlink(realFSDir, realFSLinkTarget, symlink); + if (!IS_WINDOWS) { + Files.delete(symlink); + assertFalse(Files.exists(symlink)); + withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fst) -> fst.createSymbolicLink(Path.of("..", symlink.toString()), realFSLinkTarget)); + checkSymlink(realFSDir, realFSLinkTarget, symlink); + } } private void checkSymlink(Path dir, Path target, Path symlink) throws Exception { @@ -942,8 +978,10 @@ private void checkSymlink(Path dir, Path target, Path symlink) throws Exception checkException(SecurityException.class, () -> noHostIOVFS.readSymbolicLink(symlink)); for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS}) { assertEquals(target, fs.readSymbolicLink(symlink)); - withCWD(fs, VFS_ROOT_PATH, (fst) -> assertEquals(target, fst.readSymbolicLink(Path.of("..", symlink.toString())))); - withCWD(fs, dir, (fst) -> assertEquals(target, fst.readSymbolicLink(Path.of(dotdot(dir.getNameCount()), "..", VFS_MOUNT_POINT, "..", symlink.toString())))); + if (!IS_WINDOWS) { + withCWD(fs, VFS_ROOT_PATH, (fst) -> assertEquals(target, fst.readSymbolicLink(Path.of("..", symlink.toString())))); + withCWD(fs, dir, (fst) -> assertEquals(target, fst.readSymbolicLink(Path.of(dotdot(dir.getNameCount()), "..", VFS_MOUNT_POINT, "..", symlink.toString())))); + } } } @@ -986,7 +1024,9 @@ public void move() throws Exception { checkException(SecurityException.class, () -> fs.move(VFS_ROOT_PATH.resolve("file1"), VFS_ROOT_PATH.resolve("file2"))); } - rwHostIOVFS.newByteChannel(realFSSource, Set.of(StandardOpenOption.WRITE)).write(ByteBuffer.wrap("moved text".getBytes())); + try (SeekableByteChannel ch = rwHostIOVFS.newByteChannel(realFSSource, Set.of(StandardOpenOption.WRITE))) { + ch.write(ByteBuffer.wrap("moved text".getBytes())); + } assertTrue(Files.exists(realFSSource)); assertFalse(Files.exists(realFSTarget)); rwHostIOVFS.move(realFSSource, realFSTarget); @@ -999,12 +1039,15 @@ public void move() throws Exception { assertTrue(Files.exists(realFSSource2)); assertFalse(Files.exists(realFSTarget2)); - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> fs.move(Path.of("..", realFSSource2.toString()), Path.of("..", realFSTarget2.toString()))); - assertFalse(Files.exists(realFSSource2)); - assertTrue(Files.exists(realFSTarget2)); - newByteChannelRealFS(rwHostIOVFS, realFSSource, "moved text"); + if (!IS_WINDOWS) { + withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> fs.move(Path.of("..", realFSSource2.toString()), Path.of("..", realFSTarget2.toString()))); + assertFalse(Files.exists(realFSSource2)); + assertTrue(Files.exists(realFSTarget2)); + newByteChannelRealFS(rwHostIOVFS, realFSSource, "moved text"); + } - checkException(IOException.class, () -> rHostIOVFS.move(realFSSource2, realFSTarget2)); + Class exCls = IS_WINDOWS ? SecurityException.class : IOException.class; + checkException(exCls, () -> rHostIOVFS.move(realFSSource2, realFSTarget2)); checkException(SecurityException.class, () -> noHostIOVFS.move(realFSSource2, realFSTarget2)); } @@ -1028,7 +1071,9 @@ public void copy() throws Exception { checkException(SecurityException.class, () -> noHostIOVFS.copy(realFSSource, realFSTarget)); Files.createFile(realFSSource); - rwHostIOVFS.newByteChannel(realFSSource, Set.of(StandardOpenOption.WRITE)).write(ByteBuffer.wrap("copied text".getBytes())); + try (SeekableByteChannel ch = rwHostIOVFS.newByteChannel(realFSSource, Set.of(StandardOpenOption.WRITE))) { + ch.write(ByteBuffer.wrap("copied text".getBytes())); + } assertTrue(Files.exists(realFSSource)); rwHostIOVFS.copy(realFSSource, realFSTarget); @@ -1036,11 +1081,13 @@ public void copy() throws Exception { assertTrue(Files.exists(realFSTarget)); newByteChannelRealFS(rwHostIOVFS, realFSTarget, "copied text"); - Files.delete(realFSTarget); - assertFalse(Files.exists(realFSTarget)); - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> fs.copy(Path.of("..", realFSSource.toString()), Path.of("..", realFSTarget.toString()))); - assertTrue(Files.exists(realFSTarget)); - newByteChannelRealFS(rwHostIOVFS, realFSTarget, "copied text"); + if (!IS_WINDOWS) { + Files.delete(realFSTarget); + assertFalse(Files.exists(realFSTarget)); + withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> fs.copy(Path.of("..", realFSSource.toString()), Path.of("..", realFSTarget.toString()))); + assertTrue(Files.exists(realFSTarget)); + newByteChannelRealFS(rwHostIOVFS, realFSTarget, "copied text"); + } Files.delete(realFSTarget); assertFalse(Files.exists(realFSTarget)); @@ -1054,11 +1101,13 @@ public void copy() throws Exception { assertTrue(Files.exists(realFSTarget)); newByteChannelRealFS(rwHostIOVFS, realFSTarget, "text1"); - Files.delete(realFSTarget); - assertFalse(Files.exists(realFSTarget)); - withCWD(rwHostIOVFS, realFSDir, (fs) -> fs.copy(Path.of(dotdot(realFSDir.getNameCount()), VFS_MOUNT_POINT, "file1"), realFSTarget)); - assertTrue(Files.exists(realFSTarget)); - newByteChannelRealFS(rwHostIOVFS, realFSTarget, "text1"); + if (!IS_WINDOWS) { + Files.delete(realFSTarget); + assertFalse(Files.exists(realFSTarget)); + withCWD(rwHostIOVFS, realFSDir, (fs) -> fs.copy(Path.of(dotdot(realFSDir.getNameCount()), VFS_MOUNT_POINT, "file1"), realFSTarget)); + assertTrue(Files.exists(realFSTarget)); + newByteChannelRealFS(rwHostIOVFS, realFSTarget, "text1"); + } Files.delete(realFSTarget); assertFalse(Files.exists(realFSTarget)); @@ -1073,10 +1122,11 @@ public void copy() throws Exception { assertFalse(Files.exists(realFSTarget)); // no host IO - - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> fs.copy(Path.of("file1"), Path.of("..", realFSTarget.toString()))); - assertTrue(Files.exists(realFSTarget)); - newByteChannelRealFS(rwHostIOVFS, realFSTarget, "text1"); + if (!IS_WINDOWS) { + withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> fs.copy(Path.of("file1"), Path.of("..", realFSTarget.toString()))); + assertTrue(Files.exists(realFSTarget)); + newByteChannelRealFS(rwHostIOVFS, realFSTarget, "text1"); + } } diff --git a/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/test/VirtualFileSystemUtilsTest.java b/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/test/VirtualFileSystemUtilsTest.java deleted file mode 100644 index b662bc2b5b..0000000000 --- a/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/test/VirtualFileSystemUtilsTest.java +++ /dev/null @@ -1,1133 +0,0 @@ -/* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.graalvm.python.embedding.test; - -import org.graalvm.polyglot.io.FileSystem; -import org.graalvm.python.embedding.utils.VirtualFileSystem; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Field; -import java.net.URI; -import java.nio.ByteBuffer; -import java.nio.channels.NonWritableChannelException; -import java.nio.channels.SeekableByteChannel; -import java.nio.file.AccessMode; -import java.nio.file.DirectoryStream; -import java.nio.file.Files; -import java.nio.file.LinkOption; -import java.nio.file.NoSuchFileException; -import java.nio.file.NotDirectoryException; -import java.nio.file.NotLinkException; -import java.nio.file.OpenOption; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.nio.file.StandardOpenOption; -import java.nio.file.attribute.FileAttribute; -import java.nio.file.attribute.FileTime; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.BiFunction; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Stream; - -import static com.oracle.graal.python.test.integration.Utils.IS_WINDOWS; -import static org.graalvm.python.embedding.utils.VirtualFileSystem.HostIO.NONE; -import static org.graalvm.python.embedding.utils.VirtualFileSystem.HostIO.READ; -import static org.graalvm.python.embedding.utils.VirtualFileSystem.HostIO.READ_WRITE; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; - -/** - * Siple copy of VirtualFileSystemTest to test also the deprecated - * org.graalvm.python.embedding.utils pkg - */ -public class VirtualFileSystemUtilsTest { - - private static String MOUNT_POINT_NAME = "test_mount_point"; - static final String VFS_UNIX_MOUNT_POINT = "/test_mount_point"; - static final String VFS_WIN_MOUNT_POINT = "X:\\test_mount_point"; - static final String VFS_MOUNT_POINT = IS_WINDOWS ? VFS_WIN_MOUNT_POINT : VFS_UNIX_MOUNT_POINT; - - private static final Path VFS_ROOT_PATH = Path.of(VFS_MOUNT_POINT); - - private FileSystem rwHostIOVFS; - private FileSystem rHostIOVFS; - private FileSystem noHostIOVFS; - - private FileSystem getDelegatingFS(VirtualFileSystem utilsVfs) throws NoSuchFieldException, IllegalAccessException { - Field f = utilsVfs.getClass().getDeclaredField("delegate"); - f.setAccessible(true); - Object vfs = f.get(utilsVfs); - f = vfs.getClass().getDeclaredField("impl"); - f.setAccessible(true); - toBeClosed.add((AutoCloseable) f.get(vfs)); - f = vfs.getClass().getDeclaredField("delegatingFileSystem"); - f.setAccessible(true); - return (FileSystem) f.get(vfs); - } - - public VirtualFileSystemUtilsTest() { - Logger logger = Logger.getLogger(VirtualFileSystem.class.getName()); - for (Handler handler : logger.getHandlers()) { - handler.setLevel(Level.FINE); - } - logger.setLevel(Level.FINE); - } - - private List toBeClosed = new ArrayList<>(); - - @Before - public void initFS() throws Exception { - rwHostIOVFS = getDelegatingFS(VirtualFileSystem.newBuilder().// - allowHostIO(READ_WRITE).// - unixMountPoint(VFS_UNIX_MOUNT_POINT).// - windowsMountPoint(VFS_WIN_MOUNT_POINT).// - extractFilter(p -> p.getFileName().toString().endsWith("extractme")).// - resourceLoadingClass(VirtualFileSystemUtilsTest.class).build()); - rHostIOVFS = getDelegatingFS(VirtualFileSystem.newBuilder().// - allowHostIO(READ).// - unixMountPoint(VFS_UNIX_MOUNT_POINT).// - windowsMountPoint(VFS_WIN_MOUNT_POINT).// - extractFilter(p -> p.getFileName().toString().endsWith("extractme")).// - resourceLoadingClass(VirtualFileSystemUtilsTest.class).build()); - noHostIOVFS = getDelegatingFS(VirtualFileSystem.newBuilder().// - allowHostIO(NONE).// - unixMountPoint(VFS_UNIX_MOUNT_POINT).// - windowsMountPoint(VFS_WIN_MOUNT_POINT).// - extractFilter(p -> p.getFileName().toString().endsWith("extractme")).// - resourceLoadingClass(VirtualFileSystemUtilsTest.class).build()); - } - - @After - public void close() throws Exception { - Iterator it = toBeClosed.iterator(); - while (it.hasNext()) { - it.next().close(); - it.remove(); - } - } - - @Test - public void toRealPath() throws Exception { - // from VFS - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - checkException(NullPointerException.class, () -> fs.toRealPath(null)); - toRealPathVFS(fs, VFS_MOUNT_POINT); - withCWD(fs, VFS_ROOT_PATH, (fst) -> toRealPathVFS(fst, "")); - } - - // from real FS - final Path realFSDir = Files.createTempDirectory("graalpy.vfs.test"); - final Path realFSPath = realFSDir.resolve("extractme"); - realFSPath.toFile().createNewFile(); - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS}) { - assertTrue(Files.isSameFile(realFSPath, fs.toRealPath(realFSPath))); - withCWD(fs, realFSDir, (fst) -> assertTrue(Files.isSameFile(realFSPath, fst.toRealPath(Path.of("..", realFSPath.getParent().getFileName().toString(), "extractme"))))); - withCWD(fs, VFS_ROOT_PATH, (fst) -> assertTrue(Files.isSameFile(realFSPath, fst.toRealPath(Path.of("..", realFSPath.toString()))))); - } - checkException(SecurityException.class, () -> noHostIOVFS.toRealPath(realFSPath), "expected error for no host io fs"); - } - - private static void toRealPathVFS(FileSystem fs, String pathPrefix) throws IOException { - assertEquals(Path.of(VFS_MOUNT_POINT, "dir1"), fs.toRealPath(Path.of(pathPrefix, "dir1"))); - assertEquals(Path.of(VFS_MOUNT_POINT, "SomeFile"), fs.toRealPath(Path.of(pathPrefix, "SomeFile"))); - assertEquals(Path.of(VFS_MOUNT_POINT, "does-not-exist"), fs.toRealPath(Path.of(pathPrefix, "does-not-exist"))); - assertEquals(Path.of(VFS_MOUNT_POINT, "extractme"), fs.toRealPath(Path.of(pathPrefix, "extractme"), LinkOption.NOFOLLOW_LINKS)); - checkExtractedFile(fs.toRealPath(Path.of(pathPrefix, "extractme")), new String[]{"text1", "text2"}); - checkException(NoSuchFileException.class, () -> fs.toRealPath(Path.of(pathPrefix, "does-not-exist", "extractme"))); - } - - @Test - public void toAbsolutePath() throws Exception { - // VFS - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - checkException(NullPointerException.class, () -> fs.toAbsolutePath(null)); - - assertEquals(Path.of(VFS_MOUNT_POINT, "dir1"), fs.toAbsolutePath(Path.of(VFS_MOUNT_POINT, "dir1"))); - assertEquals(Path.of(VFS_MOUNT_POINT, "SomeFile"), fs.toAbsolutePath(Path.of(VFS_MOUNT_POINT, "SomeFile"))); - - if (fs == noHostIOVFS) { - // cwd is by default set to VFS_ROOT/src - assertEquals(Path.of(VFS_MOUNT_POINT, "src", "dir1"), fs.toAbsolutePath(Path.of("dir1"))); - assertEquals(Path.of(VFS_MOUNT_POINT, "src", "SomeFile"), fs.toAbsolutePath(Path.of("SomeFile"))); - assertEquals(Path.of(VFS_MOUNT_POINT, "src", "does-not-exist", "extractme"), fs.toAbsolutePath(Path.of("does-not-exist", "extractme"))); - } else { - // without cwd set, the real FS absolute path is returned given by jdk cwd - assertEquals(Path.of("dir1").toAbsolutePath(), fs.toAbsolutePath(Path.of("dir1"))); - assertEquals(Path.of("SomeFile").toAbsolutePath(), fs.toAbsolutePath(Path.of("SomeFile"))); - assertEquals(Path.of("does-not-exist", "extractme").toAbsolutePath(), fs.toAbsolutePath(Path.of("does-not-exist", "extractme"))); - } - - withCWD(fs, VFS_ROOT_PATH, (fst) -> { - assertEquals(Path.of(VFS_MOUNT_POINT, "extractme"), fst.toAbsolutePath(Path.of("extractme"))); - assertEquals(Path.of(VFS_MOUNT_POINT, "does-not-exist", "extractme"), fst.toAbsolutePath(Path.of("does-not-exist", "extractme"))); - }); - } - - // real FS - Path realFSDir = Files.createTempDirectory("graalpy.vfs.test"); - Path realFSDirDir = realFSDir.resolve("dir"); - Files.createDirectories(realFSDirDir); - Path realFSPath = realFSDir.resolve("extractme"); - realFSPath.toFile().createNewFile(); - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS}) { - // assertEquals(Path.of("extractme").toAbsolutePath(), - // fs.toAbsolutePath(Path.of("extractme"))); - Path p = fs.toAbsolutePath(Path.of("extractme")); - assertTrue(p.isAbsolute()); - assertEquals(Path.of("extractme").toAbsolutePath().normalize(), p.normalize()); - - // absolute path starting with VFS, pointing to real FS - // /VFS_ROOT/../real/fs/path/ - p = Path.of(VFS_MOUNT_POINT, "..", realFSPath.toString()); - assertEquals(p, fs.toAbsolutePath(p)); - - // absolute path starting with real FS, pointing to VFS - // /real/fs/path/../../../VFS_MOUNT_POINT - // XXX return same abs path ??? - p = Path.of(fromPathToFSRoot(realFSDir).toString(), MOUNT_POINT_NAME); - assertEquals(p, fs.toAbsolutePath(p)); - // /real/fs/path/../../../VFS_MOUNT_POINT/../VFS_MOUNT_POINT - p = Path.of(fromPathToFSRoot(realFSDir).toString(), MOUNT_POINT_NAME, "..", MOUNT_POINT_NAME); - assertEquals(p, fs.toAbsolutePath(p)); - - // no CWD set, so relative path starting in real FS, pointing to VFS - // ../../../VFS_ROOT - Path cwd = Path.of(".").toAbsolutePath(); - p = fs.toAbsolutePath(Path.of(dotdot(cwd.getNameCount()).toString(), MOUNT_POINT_NAME)); - assertTrue(p.isAbsolute()); - assertEquals(VFS_ROOT_PATH, p.normalize()); - - // ../../../VFS_ROOT/../real/fs/path - p = fs.toAbsolutePath(Path.of(dotdot(cwd.getNameCount()).toString(), MOUNT_POINT_NAME, "..", realFSPath.toString())); - assertTrue(p.isAbsolute()); - assertEquals(realFSPath, p.normalize()); - - // CWD is VFS_ROOT, relative path pointing to real FS - // ../real/fs/path - withCWD(fs, VFS_ROOT_PATH, (fst) -> { - Path pp = fst.toAbsolutePath(Path.of("..", realFSPath.toString())); - assertTrue(pp.isAbsolute()); - assertEquals(realFSPath, pp.normalize()); - }); - - // CWD is VFS_ROOT, relative path pointing through real FS back to VFS - // ../some/path/../../VFS_ROOT_PATH - withCWD(fs, VFS_ROOT_PATH, (fst) -> { - Path pp = fst.toAbsolutePath(Path.of("..", "some", "path", "..", "..", MOUNT_POINT_NAME)); - assertTrue(pp.isAbsolute()); - assertEquals(VFS_ROOT_PATH, pp.normalize()); - }); - - // CWD is real FS, relative path pointing to VFS - // real/fs/path/../../ - withCWD(fs, realFSPath.getParent(), (fst) -> { - Path pp = fst.toAbsolutePath(Path.of("dir", dotdot(realFSDirDir.getNameCount()), MOUNT_POINT_NAME)); - assertTrue(pp.isAbsolute()); - assertEquals(VFS_ROOT_PATH, pp.normalize()); - }); - - // CWD is real FS, relative path pointing through VFS to real FS - // real/fs/path/../../../VFS - withCWD(fs, realFSPath.getParent(), - (fst) -> { - Path pp = fst.toAbsolutePath(Path.of("dir", dotdot(realFSDirDir.getNameCount()), MOUNT_POINT_NAME, "..", realFSPath.toString())); - assertTrue(pp.isAbsolute()); - assertEquals(realFSPath, pp.normalize()); - }); - - assertEquals(Path.of("extractme").toAbsolutePath(), fs.toAbsolutePath(Path.of("extractme"))); - - withCWD(fs, realFSPath.getParent(), (fst) -> assertEquals(realFSPath, fst.toAbsolutePath(realFSPath.getFileName()))); - } - - // noHostIOVFS sets default CDW to /VFS_MOUNT_POINT/src - assertEquals(realFSPath, noHostIOVFS.toAbsolutePath(realFSPath)); - assertEquals(Path.of(VFS_MOUNT_POINT, "src", "extractme"), noHostIOVFS.toAbsolutePath(Path.of("extractme"))); - - // absolute path starting with real FS, pointing to VFS - // /real/fs/path/../../../VFS_ROOT - Path p = Path.of(realFSDir.toString(), dotdot(realFSDir.getNameCount()), MOUNT_POINT_NAME); - assertEquals(p, noHostIOVFS.toAbsolutePath(p)); - - // no CWD set, relative path starting in real FS, pointing to VFS - // ../../../VFS_ROOT - Path defaultCWD = Path.of(".").toAbsolutePath(); - p = Path.of(dotdot(defaultCWD.getNameCount()), MOUNT_POINT_NAME); - assertEquals(Path.of(VFS_MOUNT_POINT, "src", p.toString()), noHostIOVFS.toAbsolutePath(p)); - } - - @Test - public void parseStringPath() throws Exception { - parsePath(VirtualFileSystemUtilsTest::parseStringPath); - } - - @Test - public void parseURIPath() throws Exception { - parsePath(VirtualFileSystemUtilsTest::parseURIPath); - - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - checkException(NullPointerException.class, () -> fs.parsePath((URI) null)); - checkException(NullPointerException.class, () -> fs.parsePath((String) null)); - checkException(UnsupportedOperationException.class, () -> fs.parsePath(URI.create("http://testvfs.org/")), "only file uri is supported"); - } - } - - public void parsePath(BiFunction parsePath) throws Exception { - // from VFS - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - // check regular resource dir - assertEquals(VFS_ROOT_PATH.resolve("dir1"), parsePath.apply(fs, VFS_MOUNT_POINT + File.separator + "dir1")); - // check regular resource file - assertEquals(VFS_ROOT_PATH.resolve("SomeFile"), parsePath.apply(fs, VFS_MOUNT_POINT + File.separator + "SomeFile")); - // check to be extracted file - Path p = parsePath.apply(fs, VFS_MOUNT_POINT + File.separator + "extractme"); - // wasn't extracted => we do not expect the path to exist on real FS - assertFalse(Files.exists(p)); - assertEquals(VFS_ROOT_PATH.resolve("extractme"), p); - p = parsePath.apply(fs, VFS_MOUNT_POINT + File.separator + "dir1" + File.separator + "extractme"); - assertFalse(Files.exists(p)); - assertEquals(VFS_ROOT_PATH.resolve("dir1" + File.separator + "extractme"), p); - p = parsePath.apply(fs, VFS_MOUNT_POINT + File.separator + "does-not-exist" + File.separator + "extractme"); - assertFalse(Files.exists(p)); - assertEquals(VFS_ROOT_PATH.resolve("does-not-exist" + File.separator + "extractme"), p); - } - - // from real FS - Path realFSPath = Files.createTempDirectory("graalpy.vfs.test").resolve("extractme"); - realFSPath.toFile().createNewFile(); - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - assertEquals(realFSPath, parsePath.apply(fs, realFSPath.toString())); - } - } - - private static Path parseStringPath(FileSystem fs, String p) { - return fs.parsePath(p); - } - - private static Path parseURIPath(FileSystem fs, String p) { - if (IS_WINDOWS) { - return fs.parsePath(URI.create("file:///" + p.replace('\\', '/'))); - } else { - return fs.parsePath(URI.create("file://" + p)); - } - } - - @Test - public void checkAccess() throws Exception { - // from VFS - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - checkException(NullPointerException.class, () -> fs.checkAccess(null, null)); - checkException(NullPointerException.class, () -> fs.checkAccess(VFS_ROOT_PATH.resolve("dir1"), null)); - - checkAccessVFS(fs, VFS_MOUNT_POINT); - withCWD(fs, VFS_ROOT_PATH, (fst) -> checkAccessVFS(fs, "")); - } - - // from real FS - Path realFSPath = Files.createTempDirectory("graalpy.vfs.test").resolve("extractme"); - realFSPath.toFile().createNewFile(); - - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS}) { - fs.checkAccess(realFSPath, Set.of(AccessMode.READ)); - withCWD(fs, realFSPath.getParent(), (fst) -> fst.checkAccess(realFSPath.getFileName(), Set.of(AccessMode.READ))); - withCWD(fs, VFS_ROOT_PATH, (fst) -> fst.checkAccess(Path.of("..", realFSPath.toString()), Set.of(AccessMode.READ))); - } - checkException(SecurityException.class, () -> noHostIOVFS.checkAccess(realFSPath, Set.of(AccessMode.READ)), "expected error for no host io fs"); - } - - private static void checkAccessVFS(FileSystem fs, String pathPrefix) throws IOException { - // check regular resource dir - fs.checkAccess(Path.of(pathPrefix, "dir1"), Set.of(AccessMode.READ)); - // check regular resource file - fs.checkAccess(Path.of(pathPrefix, "SomeFile"), Set.of(AccessMode.READ)); - - // check to be extracted file - fs.checkAccess(Path.of(pathPrefix, "extractme"), Set.of(AccessMode.READ), LinkOption.NOFOLLOW_LINKS); - checkException(SecurityException.class, () -> fs.checkAccess(Path.of(pathPrefix, "extractme"), Set.of(AccessMode.WRITE), LinkOption.NOFOLLOW_LINKS)); - fs.checkAccess(Path.of(pathPrefix, "extractme"), Set.of(AccessMode.READ)); - // even though extracted -> FS is read-only and we are limiting the access to read-only also - // for extracted files - checkException(IOException.class, () -> fs.checkAccess(Path.of(pathPrefix, "extractme"), Set.of(AccessMode.WRITE))); - - checkException(NoSuchFileException.class, () -> fs.checkAccess(Path.of(pathPrefix, "does-not-exits", "extractme"), Set.of(AccessMode.READ), LinkOption.NOFOLLOW_LINKS)); - checkException(NoSuchFileException.class, () -> fs.checkAccess(Path.of(pathPrefix, "does-not-exits", "extractme"), Set.of(AccessMode.READ))); - - checkException(SecurityException.class, () -> fs.checkAccess(Path.of(pathPrefix, "SomeFile"), Set.of(AccessMode.WRITE)), "write access should not be possible with VFS"); - checkException(SecurityException.class, () -> fs.checkAccess(Path.of(pathPrefix, "does-not-exist"), Set.of(AccessMode.WRITE)), "execute access should not be possible with VFS"); - checkException(SecurityException.class, () -> fs.checkAccess(Path.of(pathPrefix, "SomeFile"), Set.of(AccessMode.EXECUTE)), "execute access should not be possible with VFS"); - checkException(SecurityException.class, () -> fs.checkAccess(Path.of(pathPrefix, "does-not-exist"), Set.of(AccessMode.EXECUTE)), "execute access should not be possible with VFS"); - - checkException(NoSuchFileException.class, () -> fs.checkAccess(Path.of(pathPrefix, "does-not-exits"), Set.of(AccessMode.READ)), - "should not be able to access a file which does not exist in VFS"); - checkException(NoSuchFileException.class, () -> fs.checkAccess(Path.of(pathPrefix, "does-not-exits", "extractme"), Set.of(AccessMode.READ)), - "should not be able to access a file which does not exist in VFS"); - } - - @Test - public void createDirectory() throws Exception { - // from VFS - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - Path path = VFS_ROOT_PATH.resolve("new-dir"); - checkException(NullPointerException.class, () -> fs.createDirectory(null)); - checkException(SecurityException.class, () -> fs.createDirectory(path)); - - withCWD(fs, VFS_ROOT_PATH, (fst) -> checkException(SecurityException.class, () -> fst.createDirectory(Path.of("new-dir")), "should not be able to create a directory in VFS")); - } - - // from real FS - Path newDir = Files.createTempDirectory("graalpy.vfs.test").resolve("newdir"); - assertFalse(Files.exists(newDir)); - checkException(SecurityException.class, () -> noHostIOVFS.createDirectory(newDir), "expected error for no host io fs"); - assertFalse(Files.exists(newDir)); - - checkException(SecurityException.class, () -> rHostIOVFS.createDirectory(newDir), "should not be able to create a directory in a read-only FS"); - assertFalse(Files.exists(newDir)); - - rwHostIOVFS.createDirectory(newDir); - assertTrue(Files.exists(newDir)); - withCWD(rwHostIOVFS, newDir.getParent(), (fs) -> { - Path newDir2 = newDir.getParent().resolve("newdir2"); - assertFalse(Files.exists(newDir2)); - fs.createDirectory(newDir2.getFileName()); - assertTrue(Files.exists(newDir2)); - }); - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> { - Path newDir3 = newDir.getParent().resolve("newdir3"); - assertFalse(Files.exists(newDir3)); - fs.createDirectory(Path.of("..", newDir3.toString())); - assertTrue(Files.exists(newDir3)); - }); - } - - @Test - public void delete() throws Exception { - // VFS - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - checkException(NullPointerException.class, () -> fs.delete(null)); - - deleteVFS(fs, VFS_MOUNT_POINT); - withCWD(fs, VFS_ROOT_PATH, (fst) -> deleteVFS(fs, "")); - } - - // real FS - Path realFSPath = Files.createTempDirectory("graalpy.vfs.test").resolve("extractme"); - Files.createFile(realFSPath); - assertTrue(Files.exists(realFSPath)); - - checkException(SecurityException.class, () -> noHostIOVFS.delete(realFSPath), "expected error for no host io fs"); - assertTrue(Files.exists(realFSPath)); - - checkException(SecurityException.class, () -> rHostIOVFS.delete(realFSPath), "should not be able to delete in a read-only FS"); - assertTrue(Files.exists(realFSPath)); - - // Files.createFile(realFSPath); - assertTrue(Files.exists(realFSPath)); - rwHostIOVFS.delete(realFSPath); - assertFalse(Files.exists(realFSPath)); - - Files.createFile(realFSPath); - assertTrue(Files.exists(realFSPath)); - withCWD(rwHostIOVFS, realFSPath.getParent(), (fs) -> rwHostIOVFS.delete(realFSPath.getFileName())); - assertFalse(Files.exists(realFSPath)); - - Files.createFile(realFSPath); - assertTrue(Files.exists(realFSPath)); - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> rwHostIOVFS.delete(Path.of("..", realFSPath.toString()))); - assertFalse(Files.exists(realFSPath)); - } - - private static void deleteVFS(FileSystem fs, String pathPrefix) { - checkException(SecurityException.class, () -> fs.delete(Path.of(pathPrefix, "file1")), "should not be able to delete in VFS"); - checkException(SecurityException.class, () -> fs.delete(Path.of(pathPrefix, "dir1")), "should not be able to delete in VFS"); - checkException(SecurityException.class, () -> fs.delete(Path.of(pathPrefix, "extractme")), "should not be able to delete in VFS"); - } - - @Test - @SuppressWarnings("unchecked") - public void newByteChannel() throws Exception { - // from VFS - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - - checkException(NullPointerException.class, () -> fs.newByteChannel(null, (Set) null, (FileAttribute) null)); - checkException(NullPointerException.class, () -> fs.newByteChannel(null, null)); - checkException(NullPointerException.class, () -> fs.newByteChannel(VFS_ROOT_PATH.resolve("file1"), null)); - checkException(NullPointerException.class, () -> fs.newByteChannel(VFS_ROOT_PATH.resolve("file1"), Set.of(StandardOpenOption.READ), (FileAttribute[]) null)); - - newByteChannelVFS(fs, VFS_MOUNT_POINT); - withCWD(fs, VFS_ROOT_PATH, (fst) -> newByteChannelVFS(fst, "")); - - checkException(NullPointerException.class, () -> fs.newByteChannel(Path.of(VFS_MOUNT_POINT, "does-not-exist"), null)); - withCWD(fs, VFS_ROOT_PATH, (fst) -> checkException(NullPointerException.class, () -> fst.newByteChannel(Path.of("does-not-exist"), null))); - checkException(NullPointerException.class, () -> fs.newByteChannel(Path.of(VFS_MOUNT_POINT, "does-not-exist", "extractme"), null)); - withCWD(fs, VFS_ROOT_PATH, (fst) -> checkException(NullPointerException.class, () -> fst.newByteChannel(Path.of("does-not-exist", "extractme"), null))); - } - - // from real FS - Path realFSPath = Files.createTempDirectory("graalpy.vfs.test").resolve("extractme"); - Files.createFile(realFSPath); - checkException(SecurityException.class, () -> rHostIOVFS.newByteChannel(realFSPath, Set.of(StandardOpenOption.WRITE)), "cant write into a read-only host FS"); - rwHostIOVFS.newByteChannel(realFSPath, Set.of(StandardOpenOption.WRITE)).write(ByteBuffer.wrap("text".getBytes())); - assertTrue(Files.exists(realFSPath)); - - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS}) { - newByteChannelRealFS(fs, realFSPath, "text"); - withCWD(fs, realFSPath.getParent(), (fst) -> newByteChannelRealFS(fs, realFSPath.getFileName(), "text")); - withCWD(fs, VFS_ROOT_PATH, (fst) -> newByteChannelRealFS(fs, Path.of("..", realFSPath.toString()), "text")); - } - } - - private static void newByteChannelVFS(FileSystem fs, String pathPrefix) throws IOException { - Path file1 = Path.of(pathPrefix, "file1"); - Path extractable = Path.of(pathPrefix, "extractme"); - for (StandardOpenOption o : new StandardOpenOption[]{StandardOpenOption.WRITE, StandardOpenOption.READ}) { - if (o == StandardOpenOption.READ) { - newByteChannelVFS(fs, file1, Set.of(o)); - newByteChannelVFS(fs, file1, Set.of(o, LinkOption.NOFOLLOW_LINKS)); - newByteChannelVFS(fs, extractable, Set.of(o)); - checkException(IOException.class, () -> fs.newByteChannel(extractable, Set.of(o, LinkOption.NOFOLLOW_LINKS))); - } else { - checkCanOnlyRead(fs, file1, o); - checkCanOnlyRead(fs, extractable, o); - } - } - checkCanOnlyRead(fs, file1, StandardOpenOption.READ, StandardOpenOption.WRITE); - checkCanOnlyRead(fs, extractable, StandardOpenOption.READ, StandardOpenOption.WRITE); - } - - private static void newByteChannelVFS(FileSystem fs, Path path, Set options) throws IOException { - SeekableByteChannel bch = fs.newByteChannel(path, options); - ByteBuffer buffer = ByteBuffer.allocate(1024); - bch.read(buffer); - String s = new String(buffer.array()); - String[] ss = s.split(System.lineSeparator()); - assertTrue(ss.length >= 2); - assertEquals("text1", ss[0]); - assertEquals("text2", ss[1]); - checkException(NonWritableChannelException.class, () -> bch.write(buffer), "should not be able to write to VFS"); - checkException(NonWritableChannelException.class, () -> bch.truncate(0), "should not be able to write to VFS"); - } - - private static void newByteChannelRealFS(FileSystem fs, Path path, String expectedText) throws IOException { - SeekableByteChannel bch = fs.newByteChannel(path, Set.of(StandardOpenOption.READ)); - ByteBuffer buffer = ByteBuffer.allocate(expectedText.length()); - bch.read(buffer); - String s = new String(buffer.array()); - String[] ss = s.split(System.lineSeparator()); - assertTrue(ss.length >= 1); - assertEquals(expectedText, ss[0]); - } - - private static void checkCanOnlyRead(FileSystem fs, Path path, StandardOpenOption... options) { - checkException(SecurityException.class, () -> fs.newByteChannel(path, Set.of(options)), "should only be able to read from VFS"); - } - - @Test - public void newDirectoryStream() throws Exception { - // from VFS - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - checkException(NullPointerException.class, () -> fs.newDirectoryStream(null, null)); - checkException(NullPointerException.class, () -> fs.newDirectoryStream(VFS_ROOT_PATH.resolve("dir1"), null)); - checkException(NotDirectoryException.class, () -> fs.newDirectoryStream(VFS_ROOT_PATH.resolve("file1"), (p) -> true)); - - newDirectoryStreamVFS(fs, VFS_MOUNT_POINT); - withCWD(fs, VFS_ROOT_PATH, (fst) -> newDirectoryStreamVFS(fst, "")); - } - - // from real FS - Path realFSDir = Files.createTempDirectory("graalpy.vfs.test"); - Path realFSFile = realFSDir.resolve("extractme"); - Files.createFile(realFSFile); - for (FileSystem fs : new FileSystem[]{rHostIOVFS, rwHostIOVFS}) { - checkException(NotDirectoryException.class, () -> fs.newDirectoryStream(realFSFile, (p) -> true)); - newDirectoryStreamRealFS(fs, realFSDir, realFSFile); - withCWD(fs, realFSDir.getParent(), (fst) -> newDirectoryStreamRealFS(fs, realFSDir.getFileName(), realFSFile)); - withCWD(fs, VFS_ROOT_PATH, (fst) -> newDirectoryStreamRealFS(fs, Path.of("..", realFSDir.toString()), realFSFile)); - // from real fs to VFS - withCWD(fs, realFSDir, (fst) -> newDirectoryStreamVFS(fs, Path.of(dotdot(realFSDir.getNameCount()), VFS_MOUNT_POINT).toString())); - // from VFS to real FS - withCWD(fs, VFS_ROOT_PATH, (fst) -> newDirectoryStreamRealFS(fs, Path.of("..", realFSDir.toString()), realFSFile)); - } - checkException(SecurityException.class, () -> noHostIOVFS.newDirectoryStream(realFSDir, null), "expected error for no host io fs"); - } - - private static void newDirectoryStreamVFS(FileSystem fs, String pathPrefix) throws Exception { - DirectoryStream ds = fs.newDirectoryStream(Path.of(pathPrefix, "dir1"), (p) -> true); - Set s = new HashSet<>(); - Iterator it = ds.iterator(); - while (it.hasNext()) { - Path p = it.next(); - s.add(p.toString()); - } - assertEquals(2, s.size()); - String prefix = pathPrefix.isEmpty() ? "" : pathPrefix + File.separator; - assertTrue(s.contains(prefix + "dir1" + File.separator + "extractme")); - assertTrue(s.contains(prefix + "dir1" + File.separator + "file2")); - - ds = fs.newDirectoryStream(Path.of(pathPrefix, "dir1"), (p) -> false); - assertFalse(ds.iterator().hasNext()); - - checkException(NotDirectoryException.class, () -> fs.newDirectoryStream(Path.of(pathPrefix, "file1"), (p) -> true), ""); - checkException(NoSuchFileException.class, () -> fs.newDirectoryStream(Path.of(pathPrefix, "does-not-exist"), (p) -> true), ""); - } - - private static void newDirectoryStreamRealFS(FileSystem fs, Path dir, Path file) throws Exception { - DirectoryStream ds = fs.newDirectoryStream(dir, (p) -> true); - Iterator it = ds.iterator(); - Path pp = it.next(); - assertEquals(dir.resolve(file.getFileName()), pp); - assertFalse(it.hasNext()); - ds = fs.newDirectoryStream(dir, (p) -> false); - it = ds.iterator(); - assertFalse(it.hasNext()); - } - - @Test - public void readAttributes() throws Exception { - // from VFS - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - checkException(NullPointerException.class, () -> fs.readAttributes(null, "creationTime")); - readAttributesVFS(fs, VFS_MOUNT_POINT); - withCWD(fs, VFS_ROOT_PATH, (fst) -> readAttributesVFS(fst, "")); - } - - // from real FS - Path realFSPath = Files.createTempDirectory("graalpy.vfs.test").resolve("extractme"); - Files.createFile(realFSPath); - for (FileSystem fs : new FileSystem[]{rHostIOVFS, rwHostIOVFS}) { - assertTrue(((FileTime) fs.readAttributes(realFSPath, "creationTime").get("creationTime")).toMillis() > 0); - withCWD(fs, realFSPath.getParent(), (fst) -> assertTrue(((FileTime) fs.readAttributes(realFSPath.getFileName(), "creationTime").get("creationTime")).toMillis() > 0)); - withCWD(fs, VFS_ROOT_PATH, (fst) -> assertTrue(((FileTime) fs.readAttributes(Path.of("..", realFSPath.toString()), "creationTime").get("creationTime")).toMillis() > 0)); - - } - checkException(SecurityException.class, () -> noHostIOVFS.readAttributes(realFSPath, "creationTime"), "expected error for no host io fs"); - } - - private static void readAttributesVFS(FileSystem fs, String pathPrefix) throws IOException { - Map attrs = fs.readAttributes(Path.of(pathPrefix, "dir1"), "creationTime"); - assertEquals(FileTime.fromMillis(0), attrs.get("creationTime")); - - attrs = fs.readAttributes(Path.of(pathPrefix, "extractme"), "creationTime,isSymbolicLink,isRegularFile", LinkOption.NOFOLLOW_LINKS); - assertEquals(FileTime.fromMillis(0), attrs.get("creationTime")); - assertTrue((Boolean) attrs.get("isSymbolicLink")); - assertFalse((Boolean) attrs.get("isRegularFile")); // - - attrs = fs.readAttributes(Path.of(pathPrefix, "extractme"), "creationTime,isSymbolicLink,isRegularFile"); - assertNotEquals(FileTime.fromMillis(0), attrs.get("creationTime")); - assertFalse((Boolean) attrs.get("isSymbolicLink")); - assertTrue((Boolean) attrs.get("isRegularFile")); - - checkException(NoSuchFileException.class, () -> fs.readAttributes(Path.of(pathPrefix, "does-not-exist", "extractme"), "creationTime", LinkOption.NOFOLLOW_LINKS)); - checkException(NoSuchFileException.class, () -> fs.readAttributes(Path.of(pathPrefix, "does-not-exist", "extractme"), "creationTime")); - - checkException(NoSuchFileException.class, () -> fs.readAttributes(Path.of(pathPrefix, "does-not-exist"), "creationTime"), ""); - checkException(UnsupportedOperationException.class, () -> fs.readAttributes(Path.of(pathPrefix, "file1"), "unix:creationTime"), ""); - } - - @Test - public void libsExtract() throws Exception { - try (VirtualFileSystem vfs = VirtualFileSystem.newBuilder().// - unixMountPoint(VFS_MOUNT_POINT).// - windowsMountPoint(VFS_WIN_MOUNT_POINT).// - extractFilter(p -> p.getFileName().toString().endsWith(".tso")).// - resourceLoadingClass(VirtualFileSystemUtilsTest.class).build()) { - FileSystem fs = getDelegatingFS(vfs); - Path p = fs.toRealPath(VFS_ROOT_PATH.resolve("site-packages/testpkg/file.tso")); - checkExtractedFile(p, null); - Path extractedRoot = p.getParent().getParent().getParent(); - - checkExtractedFile(extractedRoot.resolve("site-packages/testpkg.libs/file1.tso"), null); - checkExtractedFile(extractedRoot.resolve("site-packages/testpkg.libs/file2.tso"), null); - checkExtractedFile(extractedRoot.resolve("site-packages/testpkg.libs/dir/file1.tso"), null); - checkExtractedFile(extractedRoot.resolve("site-packages/testpkg.libs/dir/file2.tso"), null); - checkExtractedFile(extractedRoot.resolve("site-packages/testpkg.libs/dir/nofilterfile"), null); - checkExtractedFile(extractedRoot.resolve("site-packages/testpkg.libs/dir/dir/file1.tso"), null); - checkExtractedFile(extractedRoot.resolve("site-packages/testpkg.libs/dir/dir/file2.tso"), null); - - p = fs.toRealPath(VFS_ROOT_PATH.resolve("site-packages/testpkg-nolibs/file.tso")); - checkExtractedFile(p, null); - } - } - - private static void checkExtractedFile(Path extractedFile, String[] expectedContens) throws IOException { - assertTrue(Files.exists(extractedFile)); - List lines = Files.readAllLines(extractedFile); - if (expectedContens != null) { - assertEquals("expected " + expectedContens.length + " lines in extracted file '" + extractedFile + "'", expectedContens.length, lines.size()); - for (String line : expectedContens) { - assertTrue("expected line '" + line + "' in file '" + extractedFile + "' with contents:\n" + expectedContens, lines.contains(line)); - } - } else { - assertEquals("extracted file '" + extractedFile + "' expected to be empty, but had " + lines.size() + " lines", 0, lines.size()); - } - } - - @Test - public void noExtractFilter() throws Exception { - try (VirtualFileSystem vfs = VirtualFileSystem.newBuilder().// - unixMountPoint(VFS_MOUNT_POINT).// - windowsMountPoint(VFS_WIN_MOUNT_POINT).// - extractFilter(null).// - resourceLoadingClass(VirtualFileSystemUtilsTest.class).build()) { - FileSystem fs = getDelegatingFS(vfs); - assertEquals(23, checkNotExtracted(fs, VFS_ROOT_PATH)); - } - } - - /** - * Check that all listed files have paths from VFS and do not get extracted if touched by - * toRealPath. - * - * @return amount of all listed files - */ - private static int checkNotExtracted(FileSystem fs, Path dir) throws IOException { - DirectoryStream ds = fs.newDirectoryStream(dir, (p) -> true); - Iterator it = ds.iterator(); - int c = 0; - while (it.hasNext()) { - c++; - Path p = it.next(); - assertTrue(p.toString().startsWith(VFS_MOUNT_POINT)); - assertTrue(fs.toRealPath(p).startsWith(VFS_MOUNT_POINT)); - fs.readAttributes(p, "isDirectory"); - if (Boolean.TRUE.equals((fs.readAttributes(p, "isDirectory").get("isDirectory")))) { - c += checkNotExtracted(fs, p); - } - } - return c; - } - - private interface ExceptionCall { - void call() throws Exception; - } - - private static void checkException(Class exType, ExceptionCall c) { - checkException(exType, c, null); - } - - private static void checkException(Class exType, ExceptionCall c, String msg) { - boolean gotEx = false; - try { - c.call(); - } catch (Exception e) { - if (!exType.isAssignableFrom(e.getClass())) { - e.printStackTrace(); - assertEquals(exType, e.getClass()); - } - gotEx = true; - } - assertTrue(msg != null ? msg : "expected " + exType.getName(), gotEx); - } - - @Test - public void currentWorkingDirectory() throws Exception { - Path realFSDir = Files.createTempDirectory("graalpy.vfs.test"); - Path realFSFile = realFSDir.resolve("extractme"); - Files.createFile(realFSFile); - - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - checkException(NullPointerException.class, () -> fs.setCurrentWorkingDirectory(null), "expected NPE"); - checkException(IllegalArgumentException.class, () -> fs.setCurrentWorkingDirectory(Path.of("dir"))); - - checkException(IllegalArgumentException.class, () -> fs.setCurrentWorkingDirectory(VFS_ROOT_PATH.resolve("file1"))); - - Object oldCwd = getCwd(fs); - try { - Path nonExistingDir = VFS_ROOT_PATH.resolve("does-not-exist"); - fs.setCurrentWorkingDirectory(nonExistingDir); - assertEquals(VFS_ROOT_PATH.resolve("does-not-exist").resolve("dir"), fs.toAbsolutePath(Path.of("dir"))); - - Path vfsDir = VFS_ROOT_PATH.resolve("dir1"); - fs.setCurrentWorkingDirectory(vfsDir); - assertEquals(vfsDir, fs.toAbsolutePath(Path.of("dir")).getParent()); - - if (fs == noHostIOVFS) { - checkException(SecurityException.class, () -> fs.setCurrentWorkingDirectory(realFSFile)); - } else { - checkException(IllegalArgumentException.class, () -> fs.setCurrentWorkingDirectory(realFSFile)); - - nonExistingDir = realFSDir.resolve("does-not-exist"); - fs.setCurrentWorkingDirectory(nonExistingDir); - assertEquals(nonExistingDir, fs.toAbsolutePath(Path.of("dir")).getParent()); - - fs.setCurrentWorkingDirectory(realFSDir); - assertEquals(realFSDir, fs.toAbsolutePath(Path.of("dir")).getParent()); - } - } finally { - resetCWD(fs, oldCwd); - } - } - } - - @Test - public void getTempDirectory() { - assertTrue(Files.exists(rwHostIOVFS.getTempDirectory())); - checkException(SecurityException.class, () -> rHostIOVFS.getTempDirectory()); - checkException(SecurityException.class, () -> noHostIOVFS.getTempDirectory()); - } - - @Test - public void getMimeType() throws Exception { - Path realFSPath = Files.createTempDirectory("graalpy.vfs.test").resolve("extractme"); - Files.createFile(realFSPath); - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - checkException(NullPointerException.class, () -> fs.getMimeType(null)); - Assert.assertNull(fs.getMimeType(VFS_ROOT_PATH)); - fs.getMimeType(realFSPath); - // whatever the return value, just check it does not fail - withCWD(fs, VFS_ROOT_PATH, (fst) -> fst.getMimeType(Path.of("..", realFSPath.toString()))); - } - } - - @Test - public void getEncoding() throws Exception { - Path realFSPath = Files.createTempDirectory("graalpy.vfs.test").resolve("extractme"); - Files.createFile(realFSPath); - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - checkException(NullPointerException.class, () -> fs.getEncoding(null)); - Assert.assertNull(fs.getEncoding(VFS_ROOT_PATH)); - fs.getEncoding(realFSPath); - // whatever the return value, just check it does not fail - withCWD(fs, VFS_ROOT_PATH, (fst) -> fst.getEncoding(Path.of("..", realFSPath.toString()))); - } - } - - @Test - public void setAttribute() throws Exception { - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - checkException(NullPointerException.class, () -> fs.setAttribute(null, null, null)); - checkException(SecurityException.class, () -> fs.setAttribute(VFS_ROOT_PATH, null, null)); - } - Path realFSPath = Files.createTempDirectory("graalpy.vfs.test").resolve("extractme"); - Files.createFile(realFSPath); - checkException(SecurityException.class, () -> rHostIOVFS.setAttribute(realFSPath, "creationTime", FileTime.fromMillis(42))); - checkException(SecurityException.class, () -> noHostIOVFS.setAttribute(realFSPath, "creationTime", FileTime.fromMillis(42))); - - // just check it does not fail for real FS paths - rwHostIOVFS.setAttribute(realFSPath, "creationTime", FileTime.fromMillis(42)); - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fst) -> fst.setAttribute(Path.of("..", realFSPath.toString()), "creationTime", FileTime.fromMillis(43))); - } - - @Test - public void isSameFile() throws Exception { - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - assertFalse(fs.isSameFile(Path.of(VFS_MOUNT_POINT, "src"), Path.of(VFS_MOUNT_POINT, "file1"))); - withCWD(fs, VFS_ROOT_PATH, (fst) -> assertTrue(fst.isSameFile(Path.of("src"), Path.of("src", "..", "src")))); - } - Path realFSDir = Files.createTempDirectory("graalpy.vfs.test"); - Path realFSFile1 = realFSDir.resolve("file1"); - Files.createFile(realFSFile1); - Path realFSFile2 = realFSDir.resolve("file2"); - Files.createFile(realFSFile2); - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - assertFalse(fs.isSameFile(realFSDir, VFS_ROOT_PATH)); - assertFalse(fs.isSameFile(VFS_ROOT_PATH, realFSDir)); - if (fs == noHostIOVFS) { - withCWD(fs, VFS_ROOT_PATH, (fst) -> checkException(SecurityException.class, () -> fst.isSameFile(realFSDir, Path.of("..", realFSDir.toString())))); - } else { - withCWD(fs, VFS_ROOT_PATH, (fst) -> assertTrue(fst.isSameFile(realFSDir, Path.of("..", realFSDir.toString())))); - withCWD(fs, realFSDir, (fst) -> assertTrue(fs.isSameFile(realFSFile1.getFileName(), realFSFile1.getFileName()))); - withCWD(fs, realFSDir, (fst) -> assertFalse(fs.isSameFile(realFSFile1.getFileName(), realFSFile2.getFileName()))); - } - } - } - - @Test - public void createLink() throws Exception { - Path realFSDir = Files.createTempDirectory("graalpy.vfs.test"); - Path realFSFile = realFSDir.resolve("extractme"); - Files.createFile(realFSFile); - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - checkException(NullPointerException.class, () -> fs.createLink(null, null)); - checkException(NullPointerException.class, () -> fs.createLink(VFS_ROOT_PATH, null)); - - // IOException: Cross file system linking is not supported. - checkException(IOException.class, () -> fs.createLink(VFS_ROOT_PATH.resolve("link1"), realFSFile)); - checkException(IOException.class, () -> fs.createLink(realFSDir.resolve("link"), VFS_ROOT_PATH.resolve("file1"))); - - checkException(SecurityException.class, () -> fs.createLink(VFS_ROOT_PATH, VFS_ROOT_PATH.resolve("link"))); - } - Path link = realFSDir.resolve("link1"); - assertFalse(Files.exists(link)); - rwHostIOVFS.createLink(link, realFSFile); - assertTrue(Files.exists(link)); - Path link2 = realFSDir.resolve("link2"); - assertFalse(Files.exists(link2)); - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> rwHostIOVFS.createLink(Path.of("..", link2.toString()), Path.of("..", realFSFile.toString()))); - assertTrue(Files.exists(link2)); - - checkException(SecurityException.class, () -> rHostIOVFS.createLink(realFSDir.resolve("link3"), realFSFile)); - checkException(SecurityException.class, () -> noHostIOVFS.createLink(realFSDir.resolve("link4"), realFSFile)); - } - - @Test - public void createAndReadSymbolicLink() throws Exception { - Path realFSDir = Files.createTempDirectory("graalpy.vfs.test"); - Path realFSLinkTarget = realFSDir.resolve("linkTarget"); - Files.createFile(realFSLinkTarget); - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - checkException(NullPointerException.class, () -> fs.createSymbolicLink(null, null)); - checkException(NullPointerException.class, () -> fs.readSymbolicLink(null)); - - // IOException: Cross file system linking is not supported. - checkException(IOException.class, () -> fs.createSymbolicLink(realFSDir.resolve("symlink2"), VFS_ROOT_PATH)); - checkException(IOException.class, () -> fs.createSymbolicLink(VFS_ROOT_PATH.resolve("link1"), realFSLinkTarget)); - - checkException(SecurityException.class, () -> fs.createSymbolicLink(VFS_ROOT_PATH, VFS_ROOT_PATH.resolve("link"))); - } - checkException(SecurityException.class, () -> rHostIOVFS.createSymbolicLink(realFSDir.resolve("link2"), realFSLinkTarget)); - checkException(SecurityException.class, () -> noHostIOVFS.createSymbolicLink(realFSDir.resolve("link3"), realFSLinkTarget)); - - Path symlink = realFSDir.resolve("symlink1"); - assertFalse(Files.exists(symlink)); - rwHostIOVFS.createSymbolicLink(symlink, realFSLinkTarget); - checkSymlink(realFSDir, realFSLinkTarget, symlink); - - Files.delete(symlink); - assertFalse(Files.exists(symlink)); - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fst) -> fst.createSymbolicLink(Path.of("..", symlink.toString()), realFSLinkTarget)); - checkSymlink(realFSDir, realFSLinkTarget, symlink); - } - - private void checkSymlink(Path dir, Path target, Path symlink) throws Exception { - assertTrue(Files.exists(symlink)); - checkException(SecurityException.class, () -> noHostIOVFS.readSymbolicLink(symlink)); - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS}) { - assertEquals(target, fs.readSymbolicLink(symlink)); - withCWD(fs, VFS_ROOT_PATH, (fst) -> assertEquals(target, fst.readSymbolicLink(Path.of("..", symlink.toString())))); - withCWD(fs, dir, (fst) -> assertEquals(target, fst.readSymbolicLink(Path.of(dotdot(dir.getNameCount()), "..", VFS_MOUNT_POINT, "..", symlink.toString())))); - } - } - - @Test - public void readSymbolicLink() throws Exception { - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - readSymbolicLink(fs, VFS_MOUNT_POINT); - withCWD(fs, VFS_ROOT_PATH, (fst) -> readSymbolicLink(fst, "")); - } - } - - private static void readSymbolicLink(FileSystem fs, String vfsPrefix) throws IOException { - checkException(NotLinkException.class, () -> fs.readSymbolicLink(Path.of(vfsPrefix, "file1"))); - checkException(NoSuchFileException.class, () -> fs.readSymbolicLink(Path.of(vfsPrefix, "does-not-exist"))); - checkExtractedFile(fs.readSymbolicLink(Path.of(vfsPrefix, "extractme")), new String[]{"text1", "text2"}); - } - - @Test - public void move() throws Exception { - Path realFSDir = Files.createTempDirectory("graalpy.vfs.test"); - Path realFSSource = realFSDir.resolve("movesource"); - Files.createFile(realFSSource); - Path realFSTarget = realFSDir.resolve("movetarget"); - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - checkException(NullPointerException.class, () -> fs.move(null, null)); - checkException(NullPointerException.class, () -> fs.move(VFS_ROOT_PATH, null)); - - checkException(SecurityException.class, () -> fs.move(VFS_ROOT_PATH.resolve("file1"), realFSTarget)); - Files.deleteIfExists(realFSTarget); // cleanup, move is nonatomic - - if (fs == noHostIOVFS) { - checkException(SecurityException.class, () -> fs.move(realFSSource, VFS_ROOT_PATH)); - } else { - checkException(IOException.class, () -> fs.move(realFSSource, VFS_ROOT_PATH)); - } - - checkException(SecurityException.class, () -> fs.move(realFSSource, VFS_ROOT_PATH, StandardCopyOption.REPLACE_EXISTING)); - checkException(SecurityException.class, () -> fs.move(realFSSource, VFS_ROOT_PATH.resolve("movetarget"))); - - checkException(SecurityException.class, () -> fs.move(VFS_ROOT_PATH.resolve("file1"), VFS_ROOT_PATH.resolve("file2"))); - } - - rwHostIOVFS.newByteChannel(realFSSource, Set.of(StandardOpenOption.WRITE)).write(ByteBuffer.wrap("moved text".getBytes())); - assertTrue(Files.exists(realFSSource)); - assertFalse(Files.exists(realFSTarget)); - rwHostIOVFS.move(realFSSource, realFSTarget); - assertFalse(Files.exists(realFSSource)); - assertTrue(Files.exists(realFSTarget)); - newByteChannelRealFS(rwHostIOVFS, realFSTarget, "moved text"); - - Path realFSSource2 = realFSTarget; - Path realFSTarget2 = realFSSource; - assertTrue(Files.exists(realFSSource2)); - assertFalse(Files.exists(realFSTarget2)); - - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> fs.move(Path.of("..", realFSSource2.toString()), Path.of("..", realFSTarget2.toString()))); - assertFalse(Files.exists(realFSSource2)); - assertTrue(Files.exists(realFSTarget2)); - newByteChannelRealFS(rwHostIOVFS, realFSSource, "moved text"); - - checkException(IOException.class, () -> rHostIOVFS.move(realFSSource2, realFSTarget2)); - checkException(SecurityException.class, () -> noHostIOVFS.move(realFSSource2, realFSTarget2)); - } - - @Test - public void copy() throws Exception { - Path realFSDir = Files.createTempDirectory("graalpy.vfs.test"); - Path realFSSource = realFSDir.resolve("copysource"); - Path realFSTarget = realFSDir.resolve("target"); - Files.createFile(realFSSource); - assertTrue(Files.exists(realFSSource)); - for (FileSystem fs : new FileSystem[]{rwHostIOVFS, rHostIOVFS, noHostIOVFS}) { - checkException(NullPointerException.class, () -> fs.copy(null, null)); - checkException(NullPointerException.class, () -> fs.copy(VFS_ROOT_PATH, null)); - checkException(SecurityException.class, () -> fs.copy(VFS_ROOT_PATH.resolve("file1"), VFS_ROOT_PATH.resolve("file2"))); - checkException(SecurityException.class, () -> fs.copy(realFSSource, VFS_ROOT_PATH.resolve("file2"))); - checkException(SecurityException.class, () -> fs.copy(VFS_ROOT_PATH.resolve("file1"), VFS_ROOT_PATH.resolve("file2"))); - } - - Files.delete(realFSSource); - checkException(NoSuchFileException.class, () -> rHostIOVFS.copy(realFSSource, realFSTarget)); - checkException(SecurityException.class, () -> noHostIOVFS.copy(realFSSource, realFSTarget)); - - Files.createFile(realFSSource); - rwHostIOVFS.newByteChannel(realFSSource, Set.of(StandardOpenOption.WRITE)).write(ByteBuffer.wrap("copied text".getBytes())); - assertTrue(Files.exists(realFSSource)); - - rwHostIOVFS.copy(realFSSource, realFSTarget); - assertTrue(Files.exists(realFSSource)); - assertTrue(Files.exists(realFSTarget)); - newByteChannelRealFS(rwHostIOVFS, realFSTarget, "copied text"); - - Files.delete(realFSTarget); - assertFalse(Files.exists(realFSTarget)); - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> fs.copy(Path.of("..", realFSSource.toString()), Path.of("..", realFSTarget.toString()))); - assertTrue(Files.exists(realFSTarget)); - newByteChannelRealFS(rwHostIOVFS, realFSTarget, "copied text"); - - Files.delete(realFSTarget); - assertFalse(Files.exists(realFSTarget)); - rwHostIOVFS.copy(VFS_ROOT_PATH.resolve("file1"), realFSTarget); - assertTrue(Files.exists(realFSTarget)); - newByteChannelRealFS(rwHostIOVFS, realFSTarget, "text1"); - - Files.delete(realFSTarget); - assertFalse(Files.exists(realFSTarget)); - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> fs.copy(Path.of("file1"), realFSTarget)); - assertTrue(Files.exists(realFSTarget)); - newByteChannelRealFS(rwHostIOVFS, realFSTarget, "text1"); - - Files.delete(realFSTarget); - assertFalse(Files.exists(realFSTarget)); - withCWD(rwHostIOVFS, realFSDir, (fs) -> fs.copy(Path.of(dotdot(realFSDir.getNameCount()), VFS_MOUNT_POINT, "file1"), realFSTarget)); - assertTrue(Files.exists(realFSTarget)); - newByteChannelRealFS(rwHostIOVFS, realFSTarget, "text1"); - - Files.delete(realFSTarget); - assertFalse(Files.exists(realFSTarget)); - // NoSuchFileException: no such file or directory: '/test_mount_point/does-no-exist' - checkException(NoSuchFileException.class, () -> rwHostIOVFS.copy(VFS_ROOT_PATH.resolve("does-no-exist"), realFSTarget)); - assertFalse(Files.exists(realFSTarget)); - - // read only - - // SecurityException: Operation is not allowed for: realFSPath - checkException(SecurityException.class, () -> rHostIOVFS.copy(VFS_ROOT_PATH.resolve("file1"), realFSTarget)); - assertFalse(Files.exists(realFSTarget)); - - // no host IO - - withCWD(rwHostIOVFS, VFS_ROOT_PATH, (fs) -> fs.copy(Path.of("file1"), Path.of("..", realFSTarget.toString()))); - assertTrue(Files.exists(realFSTarget)); - newByteChannelRealFS(rwHostIOVFS, realFSTarget, "text1"); - - } - - private static String fromPathToFSRoot(Path p) { - String ret = Path.of(p.toString(), dotdot(p.getNameCount())).toString(); - assert ret.contains(".."); - return ret; - } - - private static String dotdot(int n) { - String ret = Path.of(".", Stream.generate(() -> "..").limit(n).toArray(String[]::new)).toString(); - if (ret.startsWith(".")) { - ret = ret.substring(2, ret.length()); - } - return ret; - } - - private interface FSCall { - void call(FileSystem fs) throws Exception; - } - - private static void withCWD(FileSystem fs, Path cwd, FSCall c) throws Exception { - Object prevCwd = getCwd(fs); - fs.setCurrentWorkingDirectory(cwd); - try { - c.call(fs); - } finally { - resetCWD(fs, prevCwd); - } - } - - private static Object getCwd(FileSystem fs) throws IllegalAccessException, NoSuchFieldException { - // need to know if CompositeFileSystem.currentWorkingDirectory is set to null, - // because initial CWD is null and in such case CompositeFileSystem: - // - falls back on jdk CWD - // - and also behaves differently as when CWD is set to a non 'null' value - Field f = fs.getClass().getDeclaredField("currentWorkingDirectory"); - f.setAccessible(true); - return f.get(fs); - } - - private static void resetCWD(FileSystem fs, Object oldCwd) throws NoSuchFieldException, IllegalAccessException { - // calling fs.setCurrentWorkingDirectory(null) is not possible, so use reflection instead - // see also getCwd() - Field f = fs.getClass().getDeclaredField("currentWorkingDirectory"); - f.setAccessible(true); - f.set(fs, oldCwd); - } - -} diff --git a/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/vfs/test/VFSUtilsTest.java b/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/vfs/test/VFSUtilsTest.java new file mode 100644 index 0000000000..d8554d8a00 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/org/graalvm/python/embedding/vfs/test/VFSUtilsTest.java @@ -0,0 +1,745 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.graalvm.python.embedding.vfs.test; + +import org.graalvm.python.embedding.test.EmbeddingTestUtils; +import org.graalvm.python.embedding.tools.exec.BuildToolLog; +import org.graalvm.python.embedding.tools.vfs.VFSUtils; +import org.graalvm.python.embedding.tools.vfs.VFSUtils.PackagesChangedException; +import org.junit.Test; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.graalvm.python.embedding.test.EmbeddingTestUtils.createLauncher; +import static org.graalvm.python.embedding.test.EmbeddingTestUtils.delete; +import static org.graalvm.python.embedding.test.EmbeddingTestUtils.deleteDirOnShutdown; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public class VFSUtilsTest { + + private static final String GRAALPY_VERSION_PREFIX; + private static final String INPUT_PACKAGES_PREFIX; + + static { + try { + Field f = VFSUtils.class.getDeclaredField("GRAALPY_VERSION_PREFIX"); + f.setAccessible(true); + GRAALPY_VERSION_PREFIX = (String) f.get(VFSUtils.class); + f = VFSUtils.class.getDeclaredField("INPUT_PACKAGES_PREFIX"); + f.setAccessible(true); + INPUT_PACKAGES_PREFIX = (String) f.get(VFSUtils.class); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + private static final String PACKAGE_WAS_REMOVED = "A package with transitive dependencies was removed since last install, setting up a clean venv"; + private static final String LOCK_FILE_HEADER = "generated by graalpy tests\nwith a two line header"; + private static final String MISSING_LOCK_FILE_WARNING = "missing lock file"; + private static final CharSequence STALE_VENV = "Stale GraalPy virtual environment, updating to"; + + private static final class TestLog implements BuildToolLog { + private final StringBuilder output = new StringBuilder(); + + private void addLine(String s) { + this.output.append('\n').append(s); + } + + private void clearOutput() { + output.delete(0, output.length()); + } + + public void subProcessOut(String s) { + println("[subout] ", s); + addLine(s.toString()); + } + + public void subProcessErr(String s) { + println("[suberr] ", s); + addLine(s.toString()); + } + + public void info(String s) { + println("[info] ", s); + addLine(s); + } + + public void warning(String s) { + println("[warn] ", s); + addLine(s); + } + + public void warning(String s, Throwable t) { + println("[warn] ", s); + t.printStackTrace(); + addLine(s); + } + + public void error(String s) { + println("[err] ", s); + addLine(s); + } + + @Override + public void debug(String s) { + println("[debug] ", s); + addLine(s); + } + + @Override + public boolean isWarningEnabled() { + return true; + } + + @Override + public boolean isInfoEnabled() { + return true; + } + + @Override + public boolean isErrorEnabled() { + return true; + } + + @Override + public boolean isSubprocessOutEnabled() { + return true; + } + + @Override + public boolean isDebugEnabled() { + return isVerbose(); + } + + public String getOutput() { + return output.toString(); + } + + static void println(String... args) { + if (isVerbose()) { + System.out.println(String.join(" ", args)); + } + } + + private static boolean isVerbose() { + return Boolean.getBoolean("com.oracle.graal.python.test.verbose"); + } + } + + /** + * tests scenarios without lock file logic available, but not used + * + * - packages declared only in plugin config - lock file path is provided, but does not exist + */ + @Test + public void withPackagesOnlyFromPluginConfig() throws IOException, PackagesChangedException { + TestLog log = new TestLog(); + Path tmpDir = Files.createTempDirectory("withPackagesOnlyFromPluginConfig"); + Path venvDir = tmpDir.resolve("venv"); + deleteDirOnShutdown(tmpDir); + + // test with a not existing lock file path + // the maven and gradle plugins always send the default lock file path, no matter if the + // file exists or not + Path lockFile = tmpDir.resolve("lockFile.txt"); + Path contents = venvDir.resolve("contents"); + + // no packages, lock file file does not exist - does nothing + log.clearOutput(); + createVenv(venvDir, "0.1", log, lockFile); + assertFalse(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), false); + assertFalse(log.getOutput().contains("pip install")); + + log.clearOutput(); + + // install packages + log.clearOutput(); + createVenv(venvDir, "0.1", log, lockFile, "hello-world", "tiny-tiny"); + assertTrue(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), true); + assertTrue(log.getOutput().contains("pip install")); + assertTrue(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + checkInstalledPackages(venvDir.resolve("installed.txt"), "hello-world", "tiny-tiny"); + checkVenvContentsFile(contents, "0.1", "hello-world", "tiny-tiny"); + + // install packages again, assert that venv wasn't created again and packages weren't + // installed + log.clearOutput(); + createVenv(venvDir, "0.1", log, lockFile, "hello-world", "tiny-tiny"); + assertTrue(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), false); + assertFalse(log.getOutput().contains("pip install")); + assertFalse(log.getOutput().contains("hello-world")); + assertFalse(log.getOutput().contains("tiny-tiny")); + assertTrue(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + checkInstalledPackages(venvDir.resolve("installed.txt"), "hello-world", "tiny-tiny"); + checkVenvContentsFile(contents, "0.1", "hello-world", "tiny-tiny"); + + // remove tiny-tiny, assert that venv was deleted and created anew as we don't know if there + // were any transitive deps left + log.clearOutput(); + createVenv(venvDir, "0.1", log, lockFile, "hello-world"); + assertTrue(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), true); + assertTrue(log.getOutput().contains(PACKAGE_WAS_REMOVED)); + assertTrue(log.getOutput().contains("pip install")); + assertTrue(log.getOutput().contains("hello-world")); + assertFalse(log.getOutput().contains("tiny-tiny")); + assertTrue(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + checkInstalledPackages(venvDir.resolve("installed.txt"), "hello-world"); + checkVenvContentsFile(contents, "0.1", "hello-world"); + + // install only hello-world again, assert that venv wasn't created and + // packages weren't installed + log.clearOutput(); + createVenv(venvDir, "0.1", log, lockFile, "hello-world==0.2"); + assertTrue(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), false); + assertTrue(log.getOutput().contains("pip install")); + assertTrue(log.getOutput().contains("pip uninstall")); + assertTrue(log.getOutput().contains("hello-world")); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + checkInstalledPackages(venvDir.resolve("installed.txt"), "hello-world"); + checkVenvContentsFile(contents, "0.1", "hello-world==0.2"); + } + + /** + * tests scenarios without lock file logic - e.g. when called from jbang + * + * - packages declared only in plugin config - and lock file path is not provided + */ + @Test + public void withoutLockFile() throws IOException, PackagesChangedException { + TestLog log = new TestLog(); + Path tmpDir = Files.createTempDirectory("withoutLockFile"); + Path venvDir = tmpDir.resolve("venv"); + Path contents = venvDir.resolve("contents"); + deleteDirOnShutdown(tmpDir); + + createVenv(venvDir, "0.1", log); + assertFalse(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), false); + assertFalse(log.getOutput().contains("pip install")); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + + createVenv(venvDir, "0.1", log, "hello-world==0.1"); + assertTrue(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), true); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + checkInstalledPackages(venvDir.resolve("installed.txt"), "hello-world"); + checkVenvContentsFile(contents, "0.1", "hello-world==0.1"); + log.clearOutput(); + + createVenv(venvDir, "0.1", log, "hello-world==0.1", "tiny-tiny"); + assertTrue(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), false); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + checkInstalledPackages(venvDir.resolve("installed.txt"), "hello-world", "tiny-tiny"); + checkVenvContentsFile(contents, "0.1", "hello-world==0.1", "tiny-tiny"); + log.clearOutput(); + + createVenv(venvDir, "0.1", log, "hello-world==0.1"); + assertTrue(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), true); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + checkInstalledPackages(venvDir.resolve("installed.txt"), "hello-world"); + checkVenvContentsFile(contents, "0.1", "hello-world==0.1"); + log.clearOutput(); + } + + @Test + public void lockFile() throws IOException { + TestLog log = new TestLog(); + Path tmpDir = Files.createTempDirectory("emptyLockFile"); + Path venvDir = tmpDir.resolve("venv"); + deleteDirOnShutdown(tmpDir); + + Path lockFile = tmpDir.resolve("graalpy.lock"); + + Files.createFile(lockFile); + + createWithLockFile(venvDir, lockFile, log); + + List validLockFileHeader = createLockFileHeader("0.1", "pkg"); + + List lockFileList; + int headerLineCount = LOCK_FILE_HEADER.split("\n").length; + + // bogus graalPyVersion line + int graalpVersionLineIdx = headerLineCount; + lockFileList = new ArrayList<>(validLockFileHeader); + lockFileList.set(graalpVersionLineIdx, "test"); + createWithLockFile(venvDir, lockFile, log, lockFileList); + + // empty graalPyVersion line + lockFileList = new ArrayList<>(validLockFileHeader); + lockFileList.set(graalpVersionLineIdx, GRAALPY_VERSION_PREFIX); + createWithLockFile(venvDir, lockFile, log, lockFileList); + lockFileList = new ArrayList<>(validLockFileHeader); + lockFileList.set(graalpVersionLineIdx, GRAALPY_VERSION_PREFIX + " "); + createWithLockFile(venvDir, lockFile, log, lockFileList); + + // bogus input packages line + lockFileList = new ArrayList<>(validLockFileHeader); + lockFileList.set(3, "test"); + createWithLockFile(venvDir, lockFile, log, lockFileList); + + // empty input packages line + lockFileList = new ArrayList<>(validLockFileHeader); + lockFileList.set(3, INPUT_PACKAGES_PREFIX); + createWithLockFile(venvDir, lockFile, log, lockFileList); + lockFileList = new ArrayList<>(validLockFileHeader); + lockFileList.set(3, INPUT_PACKAGES_PREFIX + " "); + createWithLockFile(venvDir, lockFile, log, lockFileList); + } + + private static void createWithLockFile(Path venvDir, Path lockFile, TestLog log, List lines) throws IOException { + createWithLockFile(venvDir, lockFile, log, lines.toArray(new String[lines.size()])); + } + + private static void createWithLockFile(Path venvDir, Path lockFile, TestLog log, String... lines) throws IOException { + Files.write(lockFile, new ArrayList<>(Arrays.asList(lines)), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); + checkException(IOException.class, () -> createVenv(venvDir, "0.1", log, lockFile), "Cannot read the lock file from "); + assertFalse(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), false); + assertFalse(log.getOutput().contains("pip install")); + log.clearOutput(); + } + + private static void lock(Path venvDir, Path lockFile, TestLog log, String... packages) throws IOException { + VFSUtils.lockPackages(venvDir, Arrays.asList(packages), lockFile, LOCK_FILE_HEADER, createLauncher(venvDir), "0.1", log); + } + + private static List createLockFileHeader(String graalPyVersion, String... packages) { + List lines = new ArrayList<>(); + for (String s : LOCK_FILE_HEADER.split("\n")) { + lines.add("# " + s); + } + lines.add(GRAALPY_VERSION_PREFIX + graalPyVersion); + lines.add(INPUT_PACKAGES_PREFIX + String.join(",", packages)); + return lines; + } + + @Test + public void installAndLock() throws IOException, PackagesChangedException { + TestLog log = new TestLog(); + Path tmpDir = Files.createTempDirectory("installAndLock"); + Path venvDir = tmpDir.resolve("venv"); + Path contents = venvDir.resolve("contents"); + deleteDirOnShutdown(tmpDir); + + Path lockFile = tmpDir.resolve("graalpy.lock"); + + // install request from plugin config, it pulls in transitive pkgs, and + // we get the missing lock file warning + createVenv(venvDir, "0.1", log, lockFile, "requests"); + assertTrue(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), true); + checkInstalledPackages(venvDir.resolve("installed.txt"), "requests", "charset-normalizer", "idna", "urllib3", "certifi"); + checkVenvContentsFile(contents, "0.1", "requests"); + assertTrue(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + + // lock without version + lock(venvDir, lockFile, log, "requests"); + assertTrue(Files.exists(lockFile)); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + // lock with version + Files.delete(lockFile); + lock(venvDir, lockFile, log, "requests==2.32.2"); + checkLockFile(lockFile, new String[]{"requests==2.32.2"}, "requests==2.32.2", "charset-normalizer", "idna", "urllib3", "certifi"); + checkVenvContentsFile(contents, "0.1", "requests==2.32.2"); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + + // reinstall without exact version declared - fails + checkException(PackagesChangedException.class, () -> createVenv(venvDir, "0.1", log, lockFile, "requests")); + checkVenvCreate(log.getOutput(), false); + assertFalse(log.getOutput().contains("pip install")); + checkInstalledPackages(venvDir.resolve("installed.txt"), "requests==2.32.2", "charset-normalizer", "idna", "urllib3", "certifi"); + checkVenvContentsFile(contents, "0.1", "requests==2.32.2"); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + + // reinstall again - no more warning + delete(venvDir); + createVenv(venvDir, "0.1", log, lockFile, "requests==2.32.2"); + assertTrue(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), true); + checkInstalledPackages(venvDir.resolve("installed.txt"), "requests==2.32.2", "charset-normalizer", "idna", "urllib3", "certifi"); + checkVenvContentsFile(contents, "0.1", "requests==2.32.2"); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + + // reinstall with lower version - ok + Files.delete(lockFile); + createVenv(venvDir, "0.1", log, lockFile, "requests==2.32.1"); + // we changed version from 2.32.2 to 2.32.1, we do not know if the prev version did not + // leave + // any transitive deps, so the venv is deleted and created again + checkVenvCreate(log.getOutput(), true); + assertTrue(log.getOutput().contains("pip install")); + checkInstalledPackages(venvDir.resolve("installed.txt"), "requests==2.32.1", "charset-normalizer", "idna", "urllib3", "certifi"); + checkVenvContentsFile(contents, "0.1", "requests==2.32.1"); + assertTrue(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + // lock + lock(venvDir, lockFile, log, "requests==2.32.1"); + checkLockFile(lockFile, new String[]{"requests==2.32.1"}, "requests==2.32.1", "charset-normalizer", "idna", "urllib3", "certifi"); + checkInstalledPackages(venvDir.resolve("installed.txt"), "requests==2.32.1", "charset-normalizer", "idna", "urllib3", "certifi"); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + + // add tiny-tiny - fails because inconsistent with lock file + assert Files.exists(lockFile); + checkException(PackagesChangedException.class, () -> createVenv(venvDir, "0.1", log, lockFile, "requests==2.32.1", "tiny-tiny==0.2")); + checkVenvCreate(log.getOutput(), false); + assertFalse(log.getOutput().contains("pip install")); + checkInstalledPackages(venvDir.resolve("installed.txt"), "requests==2.32.1", "charset-normalizer", "idna", "urllib3", "certifi"); + checkVenvContentsFile(contents, "0.1", "requests==2.32.1"); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + + // delete lock and try again tiny-tiny - now ok + Files.delete(lockFile); + createVenv(venvDir, "0.1", log, lockFile, "requests==2.32.1", "tiny-tiny==0.2"); + checkVenvCreate(log.getOutput(), false); + assertTrue(log.getOutput().contains("pip install")); + checkInstalledPackages(venvDir.resolve("installed.txt"), "requests==2.32.1", "tiny-tiny==0.2", "charset-normalizer", "idna", "urllib3", "certifi"); + checkVenvContentsFile(contents, "0.1", "requests==2.32.1", "tiny-tiny==0.2"); + assertTrue(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + // lock + lock(venvDir, lockFile, log, "requests==2.32.1", "tiny-tiny==0.2"); + checkLockFile(lockFile, new String[]{"requests==2.32.1", "tiny-tiny==0.2"}, "requests==2.32.1", "tiny-tiny==0.2", "charset-normalizer", "idna", "urllib3", "certifi"); + checkInstalledPackages(venvDir.resolve("installed.txt"), "requests==2.32.1", "tiny-tiny==0.2", "charset-normalizer", "idna", "urllib3", "certifi"); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + + // install again - OK + createVenv(venvDir, "0.1", log, lockFile, "requests==2.32.1", "tiny-tiny==0.2"); + checkVenvCreate(log.getOutput(), false); + assertFalse(log.getOutput().contains("pip install")); + checkInstalledPackages(venvDir.resolve("installed.txt"), "requests==2.32.1", "tiny-tiny==0.2", "charset-normalizer", "idna", "urllib3", "certifi"); + checkVenvContentsFile(contents, "0.1", "requests==2.32.1", "tiny-tiny==0.2"); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + + // update in declared packages requests version back to 2.32.2 - fails + checkException(PackagesChangedException.class, () -> createVenv(venvDir, "0.1", log, lockFile, "requests==2.32.2", "tiny-tiny==0.2")); + checkVenvCreate(log.getOutput(), false); + assertFalse(log.getOutput().contains("pip install")); + checkInstalledPackages(venvDir.resolve("installed.txt"), "requests==2.32.1", "tiny-tiny==0.2", "charset-normalizer", "idna", "urllib3", "certifi"); + checkVenvContentsFile(contents, "0.1", "requests==2.32.1", "tiny-tiny==0.2"); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + + // delete lock and try again new hello-world version - now ok + Files.delete(lockFile); + createVenv(venvDir, "0.1", log, lockFile, "requests==2.32.2", "tiny-tiny==0.2"); + // we changed version from 2.32.2 to 2.32.1, we do not know if the prev version did not + // leave + // any transitive deps, so the venv is deleted and created again + checkVenvCreate(log.getOutput(), true); + assertTrue(log.getOutput().contains("pip install")); + checkInstalledPackages(venvDir.resolve("installed.txt"), "requests==2.32.2", "tiny-tiny==0.2", "charset-normalizer", "idna", "urllib3", "certifi"); + checkVenvContentsFile(contents, "0.1", "requests==2.32.2", "tiny-tiny==0.2"); + assertTrue(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + // lock with new requests version + lock(venvDir, lockFile, log, "requests==2.32.2", "tiny-tiny==0.2"); + checkInstalledPackages(venvDir.resolve("installed.txt"), "requests==2.32.2", "tiny-tiny==0.2", "charset-normalizer", "idna", "urllib3", "certifi"); + checkLockFile(lockFile, new String[]{"requests==2.32.2", "tiny-tiny==0.2"}, "requests==2.32.2", "tiny-tiny==0.2", "charset-normalizer", "idna", "urllib3", "certifi"); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + + // install again - OK + createVenv(venvDir, "0.1", log, lockFile, "requests==2.32.2", "tiny-tiny==0.2"); + checkVenvCreate(log.getOutput(), false); + assertFalse(log.getOutput().contains("pip install")); + checkInstalledPackages(venvDir.resolve("installed.txt"), "requests==2.32.2", "tiny-tiny==0.2", "charset-normalizer", "idna", "urllib3", "certifi"); + checkLockFile(lockFile, new String[]{"requests==2.32.2", "tiny-tiny==0.2"}, "requests==2.32.2", "tiny-tiny==0.2", "charset-normalizer", "idna", "urllib3", "certifi"); + checkVenvContentsFile(contents, "0.1", "requests==2.32.2", "tiny-tiny==0.2"); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + + // remove requests from packages list - fails because it is still in lock + checkException(PackagesChangedException.class, () -> createVenv(venvDir, "0.1", log, lockFile, "tiny-tiny==0.2")); + checkVenvCreate(log.getOutput(), false); + assertFalse(log.getOutput().contains("pip install")); + log.clearOutput(); + // lock only with tiny-tiny + lock(venvDir, lockFile, log, "tiny-tiny==0.2"); + checkVenvCreate(log.getOutput(), true); + checkLockFile(lockFile, new String[]{"tiny-tiny==0.2"}, "tiny-tiny==0.2"); + // requests transitive deps are gone as well + checkInstalledPackages(venvDir.resolve("installed.txt"), "tiny-tiny==0.2"); + checkVenvContentsFile(contents, "0.1", "tiny-tiny==0.2"); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + // try again + createVenv(venvDir, "0.1", log, lockFile, "tiny-tiny==0.2"); + checkVenvCreate(log.getOutput(), false); + assertFalse(log.getOutput().contains("pip install")); + assertTrue(log.getOutput().contains("Virtual environment is up to date with lock file")); + log.clearOutput(); + + // reinstall with new graalpy version + createVenv(venvDir, "0.2", log, lockFile, "tiny-tiny==0.2"); + checkVenvCreate(log.getOutput(), true); + assertTrue(log.getOutput().contains(STALE_VENV)); + assertTrue(log.getOutput().contains("pip install -r")); // lock file is used + checkInstalledPackages(venvDir.resolve("installed.txt"), "tiny-tiny==0.2"); + checkVenvContentsFile(contents, "0.2", "tiny-tiny==0.2"); + assertFalse(log.getOutput().contains(MISSING_LOCK_FILE_WARNING)); + log.clearOutput(); + } + + @Test + public void packageRemoved() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, IOException { + Path tmpDir = Files.createTempDirectory("packageRemoved"); + deleteDirOnShutdown(tmpDir); + + assertFalse(callPackageRemoved(Collections.emptyList(), Collections.emptyList(), Collections.emptyList())); + assertFalse(callPackageRemoved(Arrays.asList("pkg1"), Collections.emptyList(), Collections.emptyList())); + assertFalse(callPackageRemoved(Arrays.asList("pkg1"), Arrays.asList("pkg1"), Arrays.asList("pkg1==1"))); + assertFalse(callPackageRemoved(Arrays.asList("pkg1", "pkg2"), Arrays.asList("pkg1"), Arrays.asList("pkg1==1"))); + assertFalse(callPackageRemoved(Arrays.asList("pkg1", "pkg2"), Arrays.asList("pkg1", "pkg2"), Arrays.asList("pkg1==1", "pkg2==1"))); + + assertFalse(callPackageRemoved(Arrays.asList("pkg1=="), Arrays.asList("pkg1=="), Arrays.asList("pkg1==1"))); + assertFalse(callPackageRemoved(Arrays.asList("==pkg1"), Arrays.asList("==pkg1"), Arrays.asList("pkg1==1"))); + assertFalse(callPackageRemoved(Arrays.asList("pkg1==1"), Arrays.asList("pkg1"), Arrays.asList("pkg1==1"))); + assertFalse(callPackageRemoved(Arrays.asList("pkg1"), Arrays.asList("pkg1"), Arrays.asList("pkg1==1"))); + + assertTrue(callPackageRemoved(Collections.emptyList(), Arrays.asList("pkg"), Arrays.asList("pkg==1"))); + assertTrue(callPackageRemoved(Arrays.asList("pkg2"), Arrays.asList("pkg1"), Arrays.asList("pkg1==1"))); + assertTrue(callPackageRemoved(Arrays.asList("pkg1"), Arrays.asList("pkg1", "pkg2"), Arrays.asList("pkg1==1", "pkg2==1"))); + + assertTrue(callPackageRemoved(Arrays.asList("pkg1"), Arrays.asList("pkg1=="), Arrays.asList("pkg1==1"))); + assertTrue(callPackageRemoved(Arrays.asList("pkg1=="), Arrays.asList("pkg1"), Arrays.asList("pkg1==1"))); + assertTrue(callPackageRemoved(Arrays.asList("==pkg1"), Arrays.asList("pkg1"), Arrays.asList("pkg1==1"))); + + assertTrue(callPackageRemoved(Arrays.asList("pkg1==2"), Arrays.asList("pkg1==1"), Arrays.asList("pkg1==1"))); + assertTrue(callPackageRemoved(Arrays.asList("pkg1==2"), Arrays.asList("pkg1==1", "pkg2==1"), Arrays.asList("pkg1==1", "pkg2==1"))); + assertTrue(callPackageRemoved(Arrays.asList("pkg1==2"), Arrays.asList("pkg1", "pkg2"), Arrays.asList("pkg1==1", "pkg2==1"))); + } + + @Test + public void venvContentsFormat() throws IOException, PackagesChangedException { + TestLog log = new TestLog(); + Path tmpDir = Files.createTempDirectory("installAndLock"); + Path venvDir = tmpDir.resolve("venv"); + Path contents = venvDir.resolve("contents"); + deleteDirOnShutdown(tmpDir); + + Path lockFile = tmpDir.resolve("graalpy.lock"); + + // 1a.) create venv + createVenv(venvDir, "24.2.0", log, lockFile, "hello-world", "tiny-tiny"); + assertTrue(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), true); + checkVenvContentsFile(contents, "24.2.0", "hello-world", "tiny-tiny"); + log.clearOutput(); + // 1b.) and patch venv contents with format as if from graalpy < 25.0.0 + // first line is version, all following lines are packages + Files.write(contents, Arrays.asList("24.2.0", "hello-world", "tiny-tiny"), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); + + // 2.) now again, all we are interested in, is that + // - no error appears due to previous version contents format + // - and contents are back as expected + createVenv(venvDir, "25.0.0", log, lockFile, "hello-world", "tiny-tiny"); + assertTrue(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), true); + checkVenvContentsFile(contents, "25.0.0", "hello-world", "tiny-tiny"); + } + + @Test + public void differentPlatform() throws IOException, PackagesChangedException { + TestLog log = new TestLog(); + Path tmpDir = Files.createTempDirectory("installAndLock"); + Path venvDir = tmpDir.resolve("venv"); + Path contents = venvDir.resolve("contents"); + deleteDirOnShutdown(tmpDir); + + Path lockFile = tmpDir.resolve("graalpy.lock"); + + // 1a.) create venv + createVenv(venvDir, "0.1", log, lockFile, "hello-world"); + assertTrue(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), true); + checkVenvContentsFile(contents, "0.1", "hello-world"); + log.clearOutput(); + // 1b.) and patch venv contents with different platform + List lines = Files.readAllLines(contents).stream().map(l -> l.startsWith("platform=") ? "platform=bogus" : l).collect(Collectors.toList()); + Files.write(contents, lines, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); + + // 2.) now again - venv is removed and newly created + createVenv(venvDir, "0.1", log, lockFile, "hello-world"); + assertTrue(Files.exists(venvDir)); + checkVenvCreate(log.getOutput(), true); + checkVenvContentsFile(contents, "0.1", "hello-world"); + assertTrue(log.getOutput().contains("Reinstalling GraalPy venv created on")); + } + + private static boolean callPackageRemoved(List packages, List contents, List installed) + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Method m = VFSUtils.class.getDeclaredMethod("removedFromPluginPackages", List.class, List.class, List.class); + m.setAccessible(true); + return (boolean) m.invoke(VFSUtils.class, packages, contents, installed); + } + + private interface ExceptionCall { + void call() throws Exception; + } + + private static void checkException(Class cls, ExceptionCall c) { + checkException(cls, c, null); + } + + private static void checkException(Class cls, ExceptionCall c, String msg) { + try { + c.call(); + } catch (Exception e) { + if (e instanceof InvocationTargetException) { + assertEquals(cls, e.getCause().getClass()); + } else { + assertEquals(cls, e.getClass()); + } + if (msg != null) { + assertTrue(e.getMessage().contains(msg)); + } + } + } + + private static void checkVenvCreate(String output, boolean b) { + if (b) { + assertTrue(output.contains("-m venv")); + assertTrue(output.contains("-m ensurepip")); + } else { + assertFalse(output.contains("-m venv")); + assertFalse(output.contains("-m ensurepip")); + } + } + + private static void checkInstalledPackages(Path instaledFile, String... packages) throws IOException { + assertTrue(Files.exists(instaledFile)); + checkPackages(instaledFile, Files.readAllLines(instaledFile), packages); + } + + private static void checkLockFile(Path lockFile, String[] inputPackages, String... installedPackages) throws IOException { + assertTrue(Files.exists(lockFile)); + List lines = Files.readAllLines(lockFile); + List header = createLockFileHeader("0.1", inputPackages); + assertTrue(lines.size() >= header.size()); + for (int i = 0; i < header.size(); i++) { + assertEquals(header.get(i), lines.get(i)); + } + checkPackages(lockFile, lines, installedPackages); + } + + private static void checkPackages(Path file, List linesArg, String... packages) { + List lines = linesArg.stream().filter(line -> !line.trim().startsWith("#") && !line.trim().isEmpty()).toList(); + assertEquals(packages.length, lines.size()); + for (String pkg : packages) { + boolean found = false; + String pkgDef = pkg.indexOf("==") >= 0 ? pkg : pkg + "=="; + for (String line : lines) { + assert line.contains("=="); + if (line.startsWith(pkgDef)) { + found = true; + break; + } + } + if (!found) { + fail("file " + file + " does not contain package " + pkg); + } + } + } + + private static void createVenv(Path venvDir, String graalPyVersion, TestLog log, String... packages) throws IOException, PackagesChangedException { + EmbeddingTestUtils.createVenv(venvDir, graalPyVersion, log, packages); + } + + private static void createVenv(Path venvDir, String graalPyVersion, TestLog log, Path lockFile, String... packages) throws IOException, PackagesChangedException { + EmbeddingTestUtils.createVenv(venvDir, graalPyVersion, log, lockFile, MISSING_LOCK_FILE_WARNING, packages); + } + + private static void checkVenvContentsFile(Path contents, String graalPyVersion, String... packages) throws IOException { + assertTrue(Files.exists(contents)); + List lines = Files.readAllLines(contents); + + Map m = lines.stream().collect(Collectors.toMap( + l -> { + int idx = l.indexOf("="); + return l.substring(0, idx); + }, l -> { + int idx = l.indexOf("="); + return l.substring(idx + 1); + })); + + assertEquals(graalPyVersion, m.get("version")); + assertTrue(m.get("platform").contains(System.getProperty("os.name"))); + assertTrue(m.get("platform").contains(System.getProperty("os.arch"))); + List pkgs = m.get("input_packages") != null ? Arrays.asList(m.get("input_packages").split(",")) : Collections.emptyList(); + assertEquals(packages.length, pkgs.size()); + if (!pkgs.containsAll(Arrays.asList(packages))) { + fail(String.format("expected %s to contain all from %s", pkgs, Arrays.asList(packages))); + } + } +} diff --git a/graalpython/com.oracle.graal.python.test/src/python_unittests.py b/graalpython/com.oracle.graal.python.test/src/python_unittests.py deleted file mode 100644 index 16a88bd53a..0000000000 --- a/graalpython/com.oracle.graal.python.test/src/python_unittests.py +++ /dev/null @@ -1,1079 +0,0 @@ -# Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# The Universal Permissive License (UPL), Version 1.0 -# -# Subject to the condition set forth below, permission is hereby granted to any -# person obtaining a copy of this software, associated documentation and/or -# data (collectively the "Software"), free of charge and under any and all -# copyright rights in the Software, and any and all patent rights owned or -# freely licensable by each licensor hereunder covering either (i) the -# unmodified Software as contributed to or provided by such licensor, or (ii) -# the Larger Works (as defined below), to deal in both -# -# (a) the Software, and -# -# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -# one is included with the Software each a "Larger Work" to which the Software -# is contributed by such licensors), -# -# without restriction, including without limitation the rights to copy, create -# derivative works of, display, perform, and distribute the Software and make, -# use, sell, offer for sale, import, export, have made, and have sold the -# Software and the Larger Work(s), and to sublicense the foregoing rights on -# either these or other terms. -# -# This license is subject to the following condition: -# -# The above copyright notice and either this complete permission notice or at a -# minimum a reference to the UPL must be included in all copies or substantial -# portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import csv -import gzip -import os -import signal -import re -import html -import time -import subprocess -from collections import defaultdict -from json import dumps -from multiprocessing import Pool, TimeoutError -from pprint import pformat - - -import argparse -import sys -from time import gmtime, strftime - -# global CLI flags -flags = None - -# constants -PATH_UNITTESTS = "graalpython/lib-python/3/test/" - -_BASE_NAME = "unittests" -TXT_RESULTS_NAME = "{}.txt.gz".format(_BASE_NAME) -CSV_RESULTS_NAME = "{}.csv".format(_BASE_NAME) -HTML_RESULTS_NAME = "{}.html".format(_BASE_NAME) -LATEST_HTML_NAME = "latest.html" - -TIMEOUT_LINE = "\nTEST TIMED OUT WITH GRAAL PYTHON RUNNER" - -HR = "".join(['-' for _ in range(120)]) - -PTRN_ERROR = re.compile(r'^(?P[A-Z][a-z][a-zA-Z]+):(?P.*)$') -PTRN_UNITTEST = re.compile(r'^#### running: (?Pgraalpython/lib-python/3/test/(?P[\w.]+)).*$', re.DOTALL) -PTRN_NUM_TESTS = re.compile(r'^Ran (?P\d+) test.*$') -PTRN_FAILED = re.compile( - r'^FAILED \((failures=(?P\d+))?(, )?(errors=(?P\d+))?(, )?(skipped=(?P\d+))?\)$') -PTRN_OK = re.compile( - r'^OK \((failures=(?P\d+))?(, )?(errors=(?P\d+))?(, )?(skipped=(?P\d+))?\)$') -PTRN_JAVA_EXCEPTION = re.compile(r'^(?Pcom\.oracle\.[^:]*):(?P.*)') -PTRN_MODULE_NOT_FOUND = re.compile(r'.*ModuleNotFound: \'(?P.*)\'\..*', re.DOTALL) -PTRN_IMPORT_ERROR = re.compile(r".*cannot import name \'(?P.*)\'.*", re.DOTALL) -PTRN_REMOTE_HOST = re.compile(r"(?P[^@]+)@(?P[^:]+):(?P.+)") -PTRN_VALID_CSV_NAME = re.compile(r"unittests-\d{4}-\d{2}-\d{2}.csv") -PTRN_TEST_STATUS_INDIVIDUAL = re.compile(r"(?Ptest[\w_]+ \(.+?\)) ... (?P.+)") -PTRN_TEST_STATUS_ERROR = re.compile(r"(?P.+): (?Ptest[\w_]+ \(.+?\))") - -TEST_TYPES = tuple(sorted(('array','buffer','code','frame','long','memoryview','unicode','exceptions', - 'baseexception','range','builtin','bytes','thread','property','class','dictviews', - 'sys','imp','rlcompleter','types','coroutines','dictcomps','int_literal','mmap', - 'module','numeric_tower','syntax','traceback','typechecks','int','keyword','raise', - 'descr','generators','list','complex','tuple','enumerate','super','float', - 'bool','fstring','dict','iter','string','scope','with','set'))) - -TEST_APP_SCRIPTING = tuple(sorted(('test_json','csv','io','memoryio','bufio','fileio','file','fileinput','tempfile', - 'pickle','pickletester','pickle','picklebuffer','pickletools','codecs','functools', - 'itertools','math','operator','zlib','zipimport_support','zipfile','zipimport','re', - 'zipapp','gzip','bz2','builtin'))) - -TEST_SERVER_SCRIPTING_DS = tuple(sorted(('sqlite3','asyncio','marshal','select','crypt','ssl','uuid','multiprocessing', - 'fork','forkserver','main_handling','spawn','socket','socket','socketserver', - 'signal','mmap','resource','thread','dummy_thread','threading','threading_local', - 'threadsignals','dummy_threading','threadedtempfile','thread','hashlib', - 'pyexpat','locale','_locale','locale','c_locale_coercion','struct') + TEST_APP_SCRIPTING)) - - -USE_CASE_GROUPS = { - 'Python Language and Built-in Types': TEST_TYPES, - 'Application Scripting': TEST_APP_SCRIPTING, - 'Server-Side Scripting and Data Science': TEST_SERVER_SCRIPTING_DS - } - -# ---------------------------------------------------------------------------------------------------------------------- -# -# logging utils -# -# ---------------------------------------------------------------------------------------------------------------------- -def log(msg, *args, **kwargs): - print(msg.format(*args, **kwargs)) - - -def debug(msg, *args, **kwargs): - if flags.verbose: - log(msg, args, kwargs) - - -def file_name(name, current_date_time): - idx = name.index('.') - if idx > 0: - return '{}-{}{}'.format(name[:idx], current_date_time, name[idx:]) - return '{}-{}'.format(name, current_date_time) - -def get_tail(output, count=15): - lines = output.split("\n") - start = max(0, len(lines) - count) - return '\n'.join(lines[start:]) - -TIMEOUT = 60 * 20 # 20 mins per unittest wait time max ... - -# ---------------------------------------------------------------------------------------------------------------------- -# -# exec utils -# -# ---------------------------------------------------------------------------------------------------------------------- -def _run_cmd(cmd, timeout=TIMEOUT, capture_on_failure=True): - if isinstance(cmd, str): - cmd = cmd.split(" ") - assert isinstance(cmd, (list, tuple)) - - cmd_string = ' '.join(cmd) - log("[EXEC] starting '{}' ...".format(cmd_string)) - - expired = False - - start_time = time.monotonic() - # os.setsid is used to create a process group, to be able to call os.killpg upon timeout - proc = subprocess.Popen(cmd, preexec_fn=os.setsid, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - try: - output = proc.communicate(timeout=timeout)[0] - except subprocess.TimeoutExpired as e: - delta = time.monotonic() - start_time - os.killpg(proc.pid, signal.SIGKILL) - output = proc.communicate()[0] - msg = "TimeoutExpired: {:.3f}s".format(delta) - tail = get_tail(output.decode('utf-8', 'ignore')) - log("[ERR] timeout '{}' after {:.3f}s, killing process group {}, last lines of output:\n{}\n{}", cmd_string, delta, proc.pid, tail, HR) - expired = True - else: - delta = time.monotonic() - start_time - log("[EXEC] finished '{}' with exit code {} in {:.3f}s", cmd_string, proc.returncode, delta) - msg = "Finished: {:.3f}s".format(delta) - - output = output.decode("utf-8", "ignore") - if expired: - output += TIMEOUT_LINE - return proc.returncode == 0, output, msg - - -def scp(results_file_path, destination_path, destination_name=None): - dst_path = destination_name if destination_name else os.path.basename(results_file_path) - remote_dst = os.path.join(destination_path, dst_path) - cmd = ['scp', results_file_path, remote_dst] - return _run_cmd(cmd)[0] - - -def _run_unittest(test_path, timeout, with_cpython=False): - if with_cpython: - exe = os.environ.get("PYTHON3_HOME", None) - if exe: - exe = os.path.join(exe, "python") - else: - exe = "python3" - cmd = [exe, test_path, "-v"] - else: - cmd = ["mx", "python3", "--python.CatchAllExceptions=true", test_path, "-v"] - _, output, msg = _run_cmd(cmd, timeout) - output = ''' -############################################################## -#### running: {} -{} -{} -'''.format(test_path, output, msg) - return output - - - -def run_unittests(unittests, timeout, with_cpython=False): - assert isinstance(unittests, (list, tuple)) - num_unittests = len(unittests) - log("[EXEC] running {} unittests ... ", num_unittests) - log("[EXEC] timeout per unittest: {} seconds", timeout) - - start_time = time.monotonic() - pool = Pool(processes=(os.cpu_count() // 4) or 1) # to account for hyperthreading and some additional overhead - - out = [] - def callback(result): - out.append(result) - log("[PROGRESS] {} / {}: \t {:.1f}%", len(out), num_unittests, len(out) * 100 / num_unittests) - - # schedule all unittest runs - for ut in unittests: - pool.apply_async(_run_unittest, args=(ut, timeout, with_cpython), callback=callback) - - pool.close() - pool.join() - pool.terminate() - log("[STATS] processed {} unittests in {:.3f}s", num_unittests, time.monotonic() - start_time) - return out - - -def get_unittests(base_tests_path, limit=None, sort=True, skip_tests=None): - def _sorter(iterable): - return sorted(iterable) if sort else iterable - unittests = [os.path.join(base_tests_path, name) - for name in _sorter(os.listdir(base_tests_path)) - if name.startswith("test_")] - if skip_tests: - log("[INFO] skipping unittests: {}", skip_tests) - cnt = len(unittests) - unittests = [t for t in unittests if t not in skip_tests] - log("[INFO] running {} of {} unittests", len(unittests), cnt) - return unittests[:limit] if limit else unittests - - -def get_remote_host(scp_path): - match = re.match(PTRN_REMOTE_HOST, scp_path) - return match.group('user'), match.group('host'), match.group('path') - - -def ssh_ls(scp_path): - user, host, path = get_remote_host(scp_path) - cmd = ['ssh', '{}@{}'.format(user, host), 'ls', '-1', path] - return [f for f in _run_cmd(cmd)[1].splitlines() if f] - - -def read_csv(path): - rows = [] - with open(path, "r") as CSV_FILE: - reader = csv.reader(CSV_FILE) - headers = next(reader)[1:] - for row in reader: - rows.append(row) - return rows - - -class TestStatus(object): - ERROR = 'error' - FAIL = 'fail' - SKIPPED = 'skipped' - OK = 'ok' - - -# ---------------------------------------------------------------------------------------------------------------------- -# -# result (output processing) -# -# ---------------------------------------------------------------------------------------------------------------------- -class StatEntry(object): - def __init__(self): - self.num_tests = -1 - # reported stats - self._num_errors = -1 - self._num_fails = -1 - self._num_skipped = -1 - # tracked stats - self._tracked = False - - def _reset(self): - self._num_fails = 0 - self._num_errors = 0 - self._num_skipped = 0 - - def all_ok(self): - self._reset() - - @property - def num_errors(self): - return self._num_errors - - @num_errors.setter - def num_errors(self, value): - if not self._tracked: - self._num_errors = value - - @property - def num_fails(self): - return self._num_fails - - @num_fails.setter - def num_fails(self, value): - if not self._tracked: - self._num_fails = value - - @property - def num_skipped(self): - return self._num_skipped - - @num_skipped.setter - def num_skipped(self, value): - if not self._tracked: - self._num_skipped = value - - @property - def num_passes(self): - if self.num_tests > 0: - return self.num_tests - (self._num_fails + self._num_errors + self._num_skipped) - return -1 - - def update(self, test_detailed_stats): - if len(test_detailed_stats) > 0: - self._tracked = True - self._reset() - for test, stats in test_detailed_stats.items(): - stats = {s.lower() for s in stats} - if TestStatus.ERROR in stats: - self._num_errors += 1 - elif TestStatus.FAIL in stats: - self._num_fails += 1 - else: - for s in stats: - if s.startswith(TestStatus.SKIPPED): - self._num_skipped += 1 - break - - -def process_output(output_lines): - if isinstance(output_lines, str): - output_lines = output_lines.split("\n") - - current_unittest_path = None - unittests = [] - # stats tracked per unittest - unittest_tests = defaultdict(list) - error_messages = defaultdict(dict) - java_exceptions = defaultdict(set) - stats = defaultdict(StatEntry) - - for line in output_lines: - match = re.match(PTRN_UNITTEST, line) - if match: - current_unittest_path = match.group('unittest_path') - unittest = match.group('unittest') - unittests.append(unittest) - unittest_tests.clear() - continue - - # extract python reported python error messages - match = re.match(PTRN_ERROR, line) - if match: - error_message = (match.group('error'), match.group('message')) - if not error_message[0] == 'Directory' and not error_message[0] == 'Components': - error_message_dict = error_messages[unittests[-1]] - d = error_message_dict.get(error_message) - if not d: - d = 0 - error_message_dict[error_message] = d + 1 - continue - - # extract java exceptions - match = re.match(PTRN_JAVA_EXCEPTION, line) - if match: - java_exceptions[unittests[-1]].add((match.group('exception'), match.group('message'))) - continue - - # stats - # tracking stats - match = re.match(PTRN_TEST_STATUS_INDIVIDUAL, line) - if not match: - match = re.match(PTRN_TEST_STATUS_ERROR, line) - if match: - name = match.group('name') - status = match.group('status') - unittest_tests[name].append(status) - continue - - if line.strip() == 'OK': - stats[unittests[-1]].all_ok() - continue - - match = re.match(PTRN_OK, line) - if match: - fails = match.group('failures') - errs = match.group('errors') - skipped = match.group('skipped') - - stats[unittests[-1]].num_fails = int(fails) if fails else 0 - stats[unittests[-1]].num_errors = int(errs) if errs else 0 - stats[unittests[-1]].num_skipped = int(skipped) if skipped else 0 - continue - - match = re.match(PTRN_NUM_TESTS, line) - if match: - stats[unittests[-1]].num_tests = int(match.group('num_tests')) - stats[unittests[-1]].update(unittest_tests) - unittest_tests.clear() - continue - - match = re.match(PTRN_FAILED, line) - if match: - fails = match.group('failures') - errs = match.group('errors') - skipped = match.group('skipped') - if not fails and not errs and not skipped: - continue - - stats[unittests[-1]].num_fails = int(fails) if fails else 0 - stats[unittests[-1]].num_errors = int(errs) if errs else 0 - stats[unittests[-1]].num_skipped = int(skipped) if skipped else 0 - continue - - if line.strip() == TIMEOUT_LINE.strip(): - if current_unittest_path is None or len(unittests) == 0: - # we timed out here before even running something - continue - ran_tests = {} - fails = 0 - errs = 0 - ok = 0 - skip = 0 - for test,status in unittest_tests.items(): - status = " ".join(status).lower() - ran_tests[test.strip()] = status - if "skipped" in status: - skip += 1 - elif "fail" in status: - fails += 1 - elif "ok" in status: - ok += 1 - else: - errs += 1 - - tagfile = ".".join([os.path.splitext(unittests[-1])[0], "txt"]) - prefix = os.path.splitext(current_unittest_path)[0].replace("/", ".") - import glob - candidates = glob.glob("**/" + tagfile, recursive=True) - for candidate in candidates: - with open(candidate) as f: - for tagline in f.readlines(): - tagline = tagline.replace(prefix, "__main__") # account different runner for tagged and this - tagline = tagline.replace("*", "").strip() - tstcls, tst = tagline.rsplit(".", 1) - test = "{} ({})".format(tst, tstcls) - if test not in ran_tests: - ran_tests[test] = "ok" - # count the tagged test we didn't get to as an additional passing test - ok += 1 - else: - status = ran_tests[test] - if "error" in status or "fail" in status: - # interesting: it's tagged but failed here - log("{} did not pass here but is tagged as passing", test) - - stats[unittests[-1]].num_tests = ok + fails + errs + skip - stats[unittests[-1]].num_fails = fails - stats[unittests[-1]].num_errors = errs - stats[unittests[-1]].num_skipped = skip - unittest_tests.clear() - continue - - return unittests, error_messages, java_exceptions, stats - - -# ---------------------------------------------------------------------------------------------------------------------- -# -# python error processing -# -# ---------------------------------------------------------------------------------------------------------------------- -def process_errors(unittests, error_messages, err=None, msg_processor=None): - if isinstance(err, str): - err = {err,} - - def _err_filter(item): - if not err: - return True - return item[0] in err - - def _processor(msg): - if not msg_processor: - return msg - return msg_processor(msg) - - missing_modules = defaultdict(lambda: 0) - for ut in unittests: - errors = error_messages[ut] - for name in map(_processor, (msg for err, msg in filter(_err_filter, errors))): - missing_modules[name] = missing_modules[name] + 1 - - return missing_modules - - -def get_missing_module(msg): - match = re.match(PTRN_MODULE_NOT_FOUND, msg) - return match.group('module') if match else None - - -def get_cannot_import_module(msg): - match = re.match(PTRN_IMPORT_ERROR, msg) - return match.group('module') if match else None - - -# ---------------------------------------------------------------------------------------------------------------------- -# -# csv reporting -# -# ---------------------------------------------------------------------------------------------------------------------- -class Col(object): - UNITTEST = 'unittest' - NUM_TESTS = 'num_tests' - NUM_FAILS = 'num_fails' - NUM_ERRORS = 'num_errors' - NUM_SKIPPED = 'num_skipped' - NUM_PASSES = 'num_passes' - PYTHON_ERRORS = 'python_errors' - CPY_NUM_TESTS = 'cpy_num_tests' - CPY_NUM_FAILS = 'cpy_num_fails' - CPY_NUM_ERRORS = 'cpy_num_errors' - CPY_NUM_SKIPPED = 'cpy_num_skipped' - CPY_NUM_PASSES = 'cpy_num_passes' - - -CSV_HEADER = [ - Col.UNITTEST, - Col.NUM_TESTS, - Col.NUM_FAILS, - Col.NUM_ERRORS, - Col.NUM_SKIPPED, - Col.NUM_PASSES, - Col.CPY_NUM_TESTS, - Col.CPY_NUM_FAILS, - Col.CPY_NUM_ERRORS, - Col.CPY_NUM_SKIPPED, - Col.CPY_NUM_PASSES, - Col.PYTHON_ERRORS -] - - -class Stat(object): - # unittest level aggregates - UT_TOTAL = "ut_total" # all the unittests - UT_RUNS = 'ut_runs' # all unittests which could run - UT_PASS = 'ut_pass' # all unittests which pass - UT_PERCENT_RUNS = "ut_percent_runs" # all unittests which could run even with failures (percent) - UT_PERCENT_PASS = "ut_percent_pass" # all unittests which could run with no failures (percent) - # test level aggregates - TEST_RUNS = "test_runs" # total number of tests that could be loaded and run even with failures - TEST_PASS = "test_pass" # number of tests which ran - TEST_PERCENT_PASS = "test_percent_pass" # percentage of tests which pass from all running tests (all unittests) - - -def save_as_txt(report_path, results): - with gzip.open(report_path, 'wb') as TXT: - output = '\n'.join(results) - TXT.write(bytes(output, 'utf-8')) - return output - - -def save_as_csv(report_path, unittests, error_messages, java_exceptions, stats, cpy_stats=None): - rows = [] - with open(report_path, 'w') as CSV: - totals = { - Col.NUM_TESTS: 0, - Col.NUM_FAILS: 0, - Col.NUM_ERRORS: 0, - Col.NUM_SKIPPED: 0, - Col.NUM_PASSES: 0, - } - total_not_run_at_all = 0 - total_pass_all = 0 - - for unittest in unittests: - unittest_stats = stats[unittest] - cpy_unittest_stats = cpy_stats[unittest] if cpy_stats else None - unittest_errmsg = error_messages[unittest] - if not unittest_errmsg: - unittest_errmsg = java_exceptions[unittest] - if not unittest_errmsg: - unittest_errmsg = {} - - rows.append({ - Col.UNITTEST: unittest, - # graalpython stats - Col.NUM_TESTS: unittest_stats.num_tests, - Col.NUM_FAILS: unittest_stats.num_fails, - Col.NUM_ERRORS: unittest_stats.num_errors, - Col.NUM_SKIPPED: unittest_stats.num_skipped, - Col.NUM_PASSES: unittest_stats.num_passes, - # cpython stats - Col.CPY_NUM_TESTS: cpy_unittest_stats.num_tests if cpy_unittest_stats else None, - Col.CPY_NUM_FAILS: cpy_unittest_stats.num_fails if cpy_unittest_stats else None, - Col.CPY_NUM_ERRORS: cpy_unittest_stats.num_errors if cpy_unittest_stats else None, - Col.CPY_NUM_SKIPPED: cpy_unittest_stats.num_skipped if cpy_unittest_stats else None, - Col.CPY_NUM_PASSES: cpy_unittest_stats.num_passes if cpy_unittest_stats else None, - # errors - Col.PYTHON_ERRORS: dumps(list(unittest_errmsg.items())), - }) - - # update totals that ran in some way - if unittest_stats.num_tests > 0: - totals[Col.NUM_TESTS] += unittest_stats.num_tests - totals[Col.NUM_FAILS] += unittest_stats.num_fails - totals[Col.NUM_ERRORS] += unittest_stats.num_errors - totals[Col.NUM_SKIPPED] += unittest_stats.num_skipped - totals[Col.NUM_PASSES] += unittest_stats.num_passes - if unittest_stats.num_tests == unittest_stats.num_passes: - total_pass_all += 1 - else: - total_not_run_at_all += 1 - - # unittest stats - totals[Stat.UT_TOTAL] = len(unittests) - totals[Stat.UT_RUNS] = len(unittests) - total_not_run_at_all - totals[Stat.UT_PASS] = total_pass_all - ut_total_f = float(totals[Stat.UT_TOTAL]) - totals[Stat.UT_PERCENT_RUNS] = float(totals[Stat.UT_RUNS]) / ut_total_f * 100.0 if ut_total_f > 0.0 else 0.0 - totals[Stat.UT_PERCENT_PASS] = float(totals[Stat.UT_PASS]) / ut_total_f * 100.0 if ut_total_f > 0.0 else 0.0 - # test stats - totals[Stat.TEST_RUNS] = totals[Col.NUM_TESTS] - totals[Stat.TEST_PASS] = totals[Col.NUM_PASSES] - totals[Stat.TEST_PERCENT_PASS] = float(totals[Stat.TEST_PASS]) / float(totals[Stat.TEST_RUNS]) * 100.0 \ - if totals[Stat.TEST_RUNS] else 0 - - writer = csv.DictWriter(CSV, fieldnames=CSV_HEADER) - writer.writeheader() - for row in rows: - writer.writerow(row) - writer.writerow({ - Col.UNITTEST: 'TOTAL', - Col.NUM_TESTS: totals[Col.NUM_TESTS], - Col.NUM_FAILS: totals[Col.NUM_FAILS], - Col.NUM_ERRORS: totals[Col.NUM_ERRORS], - Col.NUM_SKIPPED: totals[Col.NUM_SKIPPED], - Col.NUM_PASSES: totals[Col.NUM_PASSES], - Col.PYTHON_ERRORS: 'Could run {0}/{1} unittests ({2:.2f}%). Unittests which pass completely: {3:.2f}%. ' - 'Of the ones which ran, could run: {4}/{5} tests ({6:.2f}%)'.format( - totals[Stat.UT_RUNS], totals[Stat.UT_TOTAL], - totals[Stat.UT_PERCENT_RUNS], totals[Stat.UT_PERCENT_PASS], - totals[Stat.TEST_PASS], totals[Stat.TEST_PASS], - totals[Stat.TEST_PERCENT_PASS]) - }) - - return rows, totals - - -HTML_TEMPLATE = ''' - - - - - - - - {title} - - - - - - - - - - - {content} - - - - {scripts} - - -''' - - -def save_as_html(report_name, rows, totals, missing_modules, cannot_import_modules, java_issues, current_date): - def grid(*components): - def _fmt(cmp): - if isinstance(cmp, tuple): - return '
{}
'.format(cmp[1], cmp[0]) - return '
{}
'.format(cmp) - return ''' -
-
- {} -
-
- '''.format('\n'.join([_fmt(cmp) for cmp in components])) - - def progress_bar(value, color='success'): - return ''' -
-
- {value:.2f}% Complete -
-
- '''.format(color=color, value=value) - - def fluid_div(title, div_content): - return ''' -
-
-
-

{title}

-
- {content} -
-
- '''.format(title=title, content=div_content) - - def ul(title, items): - return fluid_div(title, '
    {}
'.format('\n'.join([ - '
  • {}
  • '.format(itm) for itm in items - ]))) - - def table(tid, tcols, trows): - _thead = ''' - -   - {columns} - - '''.format(columns='\n'.join(['{}'.format(c) for c in tcols])) - - def format_val(row, k): - value = row[k] - if k == Col.PYTHON_ERRORS: - return "(click to expand)" - elif k == Col.UNITTEST: - _class = "text-info" - elif k == Col.NUM_PASSES and value > 0: - _class = "text-success" - elif k in [Col.NUM_ERRORS, Col.NUM_FAILS] and value > 0: - _class = "text-danger" - elif k == Col.NUM_SKIPPED and value > 0: - _class = "text-warning" - elif k == Col.NUM_TESTS: - _class = "text-dark" - else: - _class = "text-danger" if value and value < 0 else "text-muted" - return '{}'.format(_class, value) - - _tbody = '\n'.join([ - '{i}{vals}'.format( - errors = html.escape(row[Col.PYTHON_ERRORS], quote=True), # put the errors data into a data attribute - cls='info' if i % 2 == 0 else '', i=i, - vals=' '.join(['{}'.format(format_val(row, k)) for k in tcols])) - for i, row in enumerate(trows)]) - - _table = ''' - - {thead}{tbody} -
    - '''.format(tid=tid, tclass='', thead=_thead, tbody=_tbody) - - return fluid_div('cPython unittests run statistics', _table) - - scripts = ''' - - - - ''' - - missing_modules_info = ul('missing modules', [ - '{} imported by {} unittests'.format(name, cnt) - for cnt, name in sorted(((cnt, name) for name, cnt in missing_modules.items()), reverse=True) - ]) - - cannot_import_modules_info = ul('modules which could not be imported', [ - '{} could not be imported by {} unittests'.format(name, cnt) - for cnt, name in sorted(((cnt, name) for name, cnt in cannot_import_modules.items()), reverse=True) - ]) - - java_issues_info = ul('Java issues', [ - '{} caused by {} unittests'.format(name, cnt) - for cnt, name in sorted(((cnt, name) for name, cnt in java_issues.items()), reverse=True) - ]) - - modules_dnf = ul('Unittests that did not finish', [ - '{}'.format(r[Col.UNITTEST]) - for r in rows if r[Col.NUM_ERRORS] == -1 - ]) - - usecase_scores = dict() - for usecase_name, usecase_modules in USE_CASE_GROUPS.items(): - score_sum = 0 - for m in usecase_modules: - for r in rows: - if ("test_" + m + ".py") == r[Col.UNITTEST]: - if r[Col.NUM_PASSES] > 0 and r[Col.NUM_TESTS] > 0: - score_sum += r[Col.NUM_PASSES] / r[Col.NUM_TESTS] - usecase_scores[usecase_name] = score_sum / len(usecase_modules) - - - use_case_stats_info = ul("Summary per Use Case", - [ grid((progress_bar(avg_score * 100, color="info"), 3), '{}'.format(usecase_name)) + - grid(", ".join(USE_CASE_GROUPS[usecase_name])) for usecase_name, avg_score in usecase_scores.items()]) - - total_stats_info = ul("Summary", [ - grid('# total unittests: {}'.format(totals[Stat.UT_TOTAL])), - grid((progress_bar(totals[Stat.UT_PERCENT_RUNS], color="info"), 3), - '# unittest which run: {}'.format(totals[Stat.UT_RUNS])), - grid((progress_bar(totals[Stat.UT_PERCENT_PASS], color="success"), 3), - '# unittest which pass: {}'.format(totals[Stat.UT_PASS])), - grid('# tests which run: {}'.format(totals[Stat.TEST_RUNS])), - grid((progress_bar(totals[Stat.TEST_PERCENT_PASS], color="info"), 3), - '# tests which pass: {}'.format(totals[Stat.TEST_PASS])), - ]) - - table_stats = table('stats', CSV_HEADER, rows) - - content = '
    '.join([use_case_stats_info, - total_stats_info, - table_stats, - missing_modules_info, - cannot_import_modules_info, - java_issues_info, - modules_dnf]) - - report = HTML_TEMPLATE.format( - title='GraalPython Unittests Stats', - bootstrap_version='3.3.7', - bootstrap_css_integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u', - bootstrap_theme_css_integrity='sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp', - bootstrap_js_integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa', - fontawesome_version='4.7.0', - jquery_version='3.2.1', - datatables_version='1.10.15', - navbar_links='', - scripts=scripts.format(table_id='stats', datatables_version='1.10.15'), - content=content, - current_date_time=current_date) - - with open(report_name, 'w') as HTML: - HTML.write(report) - -def generate_latest(output_name, html_report_path): - contents = ''' - - - - -''' - with open(output_name, 'w') as HTML: - HTML.write(contents) - -# ---------------------------------------------------------------------------------------------------------------------- -# -# main tool -# -# ---------------------------------------------------------------------------------------------------------------------- -def main(prog, args): - parser = argparse.ArgumentParser(prog=prog, - description="Run the standard python unittests.") - parser.add_argument("-v", "--verbose", help="Verbose output.", action="http://github.com/store_true") - parser.add_argument("-n", "--no_cpython", help="Do not run the tests with cpython (for comparison).", - action="http://github.com/store_true") - parser.add_argument("-l", "--limit", help="Limit the number of unittests to run.", default=None, type=int) - parser.add_argument("-t", "--tests_path", help="Unittests path.", default=PATH_UNITTESTS) - parser.add_argument("-T", "--timeout", help="Timeout per unittest run (seconds).", default=TIMEOUT, type=int) - parser.add_argument("-o", "--only_tests", help="Run only these unittests (comma sep values).", default=None) - parser.add_argument("-s", "--skip_tests", help="Run all unittests except (comma sep values)." - "the only_tets option takes precedence", default=None) - parser.add_argument("-r", "--regression_running_tests", help="Regression threshold for running tests.", type=float, - default=None) - parser.add_argument("--no_latest", help="Don't generate latest.html file.", action="http://github.com/store_true") - parser.add_argument("-g", "--gate", help="Run in gate mode (Skip cpython runs; Do not upload results; " - "Detect regressions).", action="http://github.com/store_true") - parser.add_argument("path", help="Path to store the csv output and logs to.", nargs='?', default=None) - - global flags - flags = parser.parse_args(args=args) - - current_date = strftime("%Y-%m-%d", gmtime()) - - log("[INFO] current date : {}", current_date) - log("[INFO] unittests path : {}", flags.tests_path) - if flags.path: - log("[INFO] results (save) path : {}", flags.path) - else: - log("[INFO] results will not be saved remotely") - - if flags.gate: - log("[INFO] running in gate mode") - if not flags.regression_running_tests: - log("[WARNING] --regression_running_tests not set while in gate mode. " - "Regression detection will not be performed") - - def _fmt(t): - t = t.strip() - return os.path.join(flags.tests_path, t if t.endswith(".py") else t + ".py") - - if flags.only_tests: - only_tests = set([_fmt(test) for test in flags.only_tests.split(",")]) - unittests = [t for t in get_unittests(flags.tests_path) if t in only_tests] - else: - skip_tests = set([_fmt(test) for test in flags.skip_tests.split(",")]) if flags.skip_tests else None - unittests = get_unittests(flags.tests_path, limit=flags.limit, skip_tests=skip_tests) - - # get cpython stats - if not flags.gate and not flags.no_cpython: - log(HR) - log("[INFO] get cpython stats") - cpy_results = run_unittests(unittests, 60 * 5, with_cpython=True) - cpy_stats = process_output('\n'.join(cpy_results))[-1] - # handle the timeout - timeout = flags.timeout if flags.timeout else None - else: - cpy_stats = None - # handle the timeout - timeout = flags.timeout if flags.timeout else 60 * 5 # 5 minutes if no value specified (in gate mode only) - - # get graalpython stats - log(HR) - log("[INFO] get graalpython stats") - results = run_unittests(unittests, timeout, with_cpython=False) - txt_report_path = file_name(TXT_RESULTS_NAME, current_date) - output = save_as_txt(txt_report_path, results) - - unittests, error_messages, java_exceptions, stats = process_output(output) - - csv_report_path = file_name(CSV_RESULTS_NAME, current_date) - rows, totals = save_as_csv(csv_report_path, unittests, error_messages, java_exceptions, stats, cpy_stats=cpy_stats) - - log("[INFO] totals: {!r}", totals) - - missing_modules = process_errors(unittests, error_messages, 'ModuleNotFoundError', - msg_processor=get_missing_module) - log("[MISSING MODULES] \n{}", pformat(dict(missing_modules))) - - cannot_import_modules = process_errors(unittests, error_messages, err='ImportError', - msg_processor=get_cannot_import_module) - log("[CANNOT IMPORT MODULES] \n{}", pformat(dict(cannot_import_modules))) - - java_issues = process_errors(unittests, java_exceptions) - log("[JAVA ISSUES] \n{}", pformat(dict(java_issues))) - - html_report_path = file_name(HTML_RESULTS_NAME, current_date) - if not flags.gate: - save_as_html(html_report_path, rows, totals, missing_modules, cannot_import_modules, java_issues, current_date) - - if not flags.gate and flags.path: - log("[SAVE] saving results to {} ... ", flags.path) - scp(txt_report_path, flags.path) - scp(csv_report_path, flags.path) - scp(html_report_path, flags.path) - if not flags.no_latest: - generate_latest(LATEST_HTML_NAME, html_report_path) - scp(LATEST_HTML_NAME, flags.path) - - gate_failed = False - if flags.gate and flags.regression_running_tests: - log("[REGRESSION] detecting regression, acceptance threshold = {}%".format( - flags.regression_running_tests * 100)) - csv_files = sorted(f for f in ssh_ls(flags.path) if PTRN_VALID_CSV_NAME.match(f)) - last_csv = csv_files[-1] - # log('\n'.join(csv_files)) - # read the remote csv and extract stats - log("[REGRESSION] comparing against: {}".format(last_csv)) - scp('{}/{}'.format(flags.path, last_csv), '.', destination_name=last_csv) - rows = read_csv(last_csv) - prev_totals = { - Col.NUM_TESTS: int(rows[-1][1]), - Col.NUM_FAILS: int(rows[-1][2]), - Col.NUM_ERRORS: int(rows[-1][3]), - Col.NUM_SKIPPED: int(rows[-1][4]), - Col.NUM_PASSES: int(rows[-1][5]), - } - log("[INFO] previous totals (from {}): {!r}", last_csv, prev_totals) - if float(totals[Col.NUM_TESTS]) < float(prev_totals[Col.NUM_TESTS]) * (1.0 - flags.regression_running_tests): - log("[REGRESSION] REGRESSION DETECTED, passed {} tests vs {} from {}".format( - totals[Col.NUM_TESTS], prev_totals[Col.NUM_TESTS], last_csv)) - gate_failed = True - else: - log("[REGRESSION] no regression detected") - - log("[DONE]") - if flags.gate and gate_failed: - exit(1) - - -if __name__ == "__main__": - main(sys.argv[0], sys.argv[1:]) diff --git a/graalpython/com.oracle.graal.python.test/src/runner.py b/graalpython/com.oracle.graal.python.test/src/runner.py index 2561c9389c..0feda7a8b9 100644 --- a/graalpython/com.oracle.graal.python.test/src/runner.py +++ b/graalpython/com.oracle.graal.python.test/src/runner.py @@ -890,7 +890,7 @@ class Config: @classmethod @lru_cache - def parse_config(cls, config_path): + def parse_config(cls, config_path: Path): with open(config_path, 'rb') as f: config_dict = tomllib.load(f) settings = config_dict.get('settings', {}) @@ -898,6 +898,11 @@ def parse_config(cls, config_path): tags_dir = None if config_tags_dir := settings.get('tags_dir'): tags_dir = (config_path.parent / config_tags_dir).resolve() + # Temporary hack for Bytecode DSL development in master branch: + if IS_GRAALPY and __graalpython__.is_bytecode_dsl_interpreter and tags_dir: + new_tags_dir = (config_path.parent / (config_tags_dir + '_bytecode_dsl')).resolve() + if new_tags_dir.exists(): + tags_dir = new_tags_dir return cls( configdir=config_path.parent.resolve(), rootdir=config_path.parent.parent.resolve(), diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/__init__.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/__init__.py index 27a2e407ac..12e142b5c4 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/__init__.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/__init__.py @@ -53,7 +53,6 @@ DIR = Path(__file__).parent.absolute() GRAALPYTHON = sys.implementation.name == "graalpy" -RUNS_ON_LLVM = GRAALPYTHON and __graalpython__.ext_mode == 'llvm' def assert_raises(err, fn, *args, **kwargs): raised = False @@ -764,13 +763,11 @@ def CPyExtHeapType(name, bases=(object), code='', slots=None, **kwargs): {code} - PyType_Slot slots[] = {{ - {slots} - }}; - - PyType_Spec spec = {{ "{name}", sizeof({name}Object), 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, slots }}; - static PyObject* create(PyObject* unused, PyObject* bases) {{ + PyType_Slot slots[] = {{ + {slots} + }}; + PyType_Spec spec = {{ "{name}", sizeof({name}Object), 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, slots }}; {ready_code} PyObject* type = PyType_FromSpecWithBases(&spec, bases); if (type == NULL) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/module_with_exiting_functions.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/module_with_exiting_functions.py new file mode 100644 index 0000000000..99b5e47fd4 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/module_with_exiting_functions.py @@ -0,0 +1,68 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import sys +import time + +from tests.cpyext import CPyExtType + + +ExitObject = CPyExtType( + "ExitObjext", + """ + static PyObject *test_FatalError(PyObject *self, PyObject *arg) { + Py_FatalError(PyUnicode_AsUTF8(arg)); + return NULL; + } + + static PyObject* test_assert_failure(PyObject *self, PyObject *arg) { + _PyObject_AssertFailed(arg, "0", PyUnicode_AsUTF8(arg), "filename", 0, "function"); + return NULL; + } + + """, + tp_methods=''' + {"Py_FatalError", (PyCFunction)test_FatalError, METH_O, NULL}, + {"_PyObject_ASSERT_WITH_MSG", (PyCFunction)test_assert_failure, METH_O, NULL} + ''' + ) + + +if __name__ == "__main__": + getattr(ExitObject(), sys.argv[1])(sys.argv[2]) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_abstract.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_abstract.py index b54690cba3..73cb07e16a 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_abstract.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_abstract.py @@ -40,8 +40,10 @@ import array import collections import mmap +import os import sys import unittest +from unittest import skipIf from . import CPyExtTestCase, CPyExtFunction, CPyExtType, unhandled_error_compare diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_bool.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_bool.py index c295ba3dc5..0574540ceb 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_bool.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_bool.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -47,7 +47,7 @@ class DummyNonInt(): class TestPyBool(CPyExtTestCase): # (tfel): This test actually checks that the wrapped booleans that are - # stored as sulong globals are singletons + # stored as native globals are singletons test_PyBools_areSingleton = CPyExtFunction( lambda args: 1, lambda: ( diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_ctypes.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_ctypes.py index 9a35def6ce..be89b8ce89 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_ctypes.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_ctypes.py @@ -39,6 +39,7 @@ import ctypes import os.path import struct +import sys from tests.cpyext import CPyExtTestCase, CPyExtType @@ -225,3 +226,27 @@ class MyLargeStruct(ctypes.Structure): assert result.num7 == 42 finally: os.chdir(original_cwd) + + +def test_void_p(): + assert ctypes.c_void_p(True).value == ctypes.c_void_p(1).value + assert ctypes.c_void_p(False).value == ctypes.c_void_p(0).value + assert ctypes.c_void_p(2**128 - 1).value == ctypes.c_void_p(2**64 - 1).value + try: + ctypes.c_void_p(2**128 - 1) + except TypeError as e: + assert "cannot be converted to pointer" in str(e) + + +def test_meson_windows_detect_native_arch() -> str: + if sys.platform != 'win32': + return + process_arch = ctypes.c_ushort() + native_arch = ctypes.c_ushort() + kernel32 = ctypes.windll.kernel32 + process = ctypes.c_void_p(kernel32.GetCurrentProcess()) + try: + if kernel32.IsWow64Process2(process, ctypes.byref(process_arch), ctypes.byref(native_arch)): + assert native_arch.value == 0x8664, "only amd64 supported by GraalPy on Windows" + except AttributeError as e: + assert "Unknown identifier: IsWow64Process2" in str(e) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_fatal_exit.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_fatal_exit.py new file mode 100644 index 0000000000..0a27547b92 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_fatal_exit.py @@ -0,0 +1,72 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import os +import signal +import subprocess +from pathlib import Path + +import sys + + +def call_in_subprocess(method, argument): + dir = Path(__file__).parent + module_path = dir / 'module_with_exiting_functions.py' + env = dict(os.environ) + env['PYTHONPATH'] = str(dir.parent.parent) + args = [sys.executable] + if sys.implementation.name == 'graalpy': + args += ['--experimental-options', '--python.EnableDebuggingBuiltins'] + args += [str(module_path), method, argument] + return subprocess.run(args, env=env, capture_output=True, text=True) + + +def test_fatal_error(): + proc = call_in_subprocess("Py_FatalError", "my fatal error") + assert proc.returncode != 0 + assert "my fatal error" in proc.stderr, proc.stderr + + +def test_assert_failed(): + proc = call_in_subprocess("_PyObject_ASSERT_WITH_MSG", "some assert failed") + assert proc.returncode != 0 + assert "some assert failed" in proc.stderr, proc.stderr + assert "refcount" in proc.stderr, proc.stderr + assert "object type" in proc.stderr, proc.stderr + assert "object type name" in proc.stderr, proc.stderr diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py index 0dbd303bee..d05f53d74d 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -40,7 +40,7 @@ import unittest from . import CPyExtType, CPyExtTestCase, CPyExtFunction, CPyExtFunctionOutVars, unhandled_error_compare, \ - is_native_object, RUNS_ON_LLVM + is_native_object def _float_compare(x, y): @@ -212,8 +212,6 @@ def test_PyOS_double_to_string(self): assert tester.PyOS_double_to_string_test(190.08) == '190.080000' def test_PyOS_string_to_double(self): - if RUNS_ON_LLVM: - return TestPyOS_String_To_Double = CPyExtType( "TestPyOS_String_To_Double", ''' diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_functions.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_functions.py index 4cda51bf9f..337ace6d7e 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_functions.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_functions.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -41,7 +41,7 @@ import sys import unittest -from . import CPyExtType, CPyExtTestCase, CPyExtFunction, unhandled_error_compare, CPyExtHeapType, RUNS_ON_LLVM +from . import CPyExtType, CPyExtTestCase, CPyExtFunction, unhandled_error_compare, CPyExtHeapType DIR = os.path.dirname(__file__) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_gc.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_gc.py index d381537528..f4844f1a77 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_gc.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_gc.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -44,7 +44,7 @@ import unittest from unittest import skipIf -from . import CPyExtType, RUNS_ON_LLVM +from . import CPyExtType GRAALPY = sys.implementation.name == 'graalpy' @@ -220,8 +220,6 @@ def _trigger_gc(self): gc.collect() def test_cycle_with_native_objects(self): - if RUNS_ON_LLVM: - return TestCycle0 = CPyExtType("TestCycle0", ''' #define N 16 @@ -896,6 +894,6 @@ def test_module_globals(self): self._trigger_gc() ################################################################################## -@skipIf(not (GRAALPY) or RUNS_ON_LLVM, "Internal GraalPy RSS function") +@skipIf(not GRAALPY, "Internal GraalPy RSS function") def test_current_rss_monitor(): assert __graalpython__.get_current_rss() > 0 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_misc.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_misc.py index 3aeba43711..8ab72ded57 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_misc.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_misc.py @@ -359,14 +359,12 @@ def test_graalpy_version(): {"get_version_num", (PyCFunction)get_version_num, METH_NOARGS | METH_STATIC, ""} ''', ) - expected_version = __graalpython__.get_graalvm_version().removesuffix('-dev') - assert tester.get_version_str() == expected_version - parts = [int(v) for v in expected_version.split('.')] + [0] - expected_num = 0 - for i in range(3): - expected_num <<= 8 - expected_num |= parts[i] - assert tester.get_version_num() == expected_num + version = sys.implementation.version + assert tester.get_version_str() == f'{version.major}.{version.minor}.{version.micro}' + assert tester.get_version_num() == sys.implementation.hexversion + # This is an anti-backport trap. The commit that changed the hexversion format should not be backported because + # existing projects might already contain tests for the next feature release in the old format (pybind11 does) + assert version.major >= 25 def test_unicode_docstring(): diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_module.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_module.py index fb5ea5527f..e0a89a85bf 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_module.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_module.py @@ -1,4 +1,4 @@ -# Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -54,6 +54,22 @@ def _reference_add_object(args): args[0].__dict__[args[1]] = args[2] return 0 + +def _reference_get_filename(args): + if not isinstance(args[0], ModuleType): + raise TypeError + file = getattr(args[0], '__file__', None) + if isinstance(file, str): + return file + raise SystemError + + +module_with_file = ModuleType("module") +module_with_file.__file__ = 'file.py' +module_with_broken_file = ModuleType("module") +module_with_broken_file.__file__ = 1 + + class TestPyModule(CPyExtTestCase): test_PyModule_Check = CPyExtFunction( @@ -175,3 +191,31 @@ class TestPyModule(CPyExtTestCase): arguments=["PyObject* m", "const char* k", "PyObject* v"], cmpfunc=unhandled_error_compare ) + + test_PyModule_GetFilenameObject = CPyExtFunction( + _reference_get_filename, + lambda: ( + (module_with_file,), + (module_with_broken_file,), + (ModuleType("no-file"),), + (1,), + ), + resultspec="O", + argspec='O', + arguments=["PyObject* m"], + cmpfunc=unhandled_error_compare + ) + + test_PyModule_GetFilename = CPyExtFunction( + _reference_get_filename, + lambda: ( + (module_with_file,), + (module_with_broken_file,), + (ModuleType("no-file"),), + (1,), + ), + resultspec="s", + argspec='O', + arguments=["PyObject* m"], + cmpfunc=unhandled_error_compare + ) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_object.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_object.py index 46e643967d..f85ca7d266 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_object.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_object.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -886,7 +886,33 @@ class Foo(TpBasicsize2Type, TpBasicsize3Type): assert foo.get_value(i) == vvv, "Failed" vvv += 1 - def test_new_inherited_from_dominant_base(self): + def test_tp_new_bug_to_bug_compatibility(self): + # msimacek: `update_one_slot` in CPython has a bug regarding unwrappping `tp_new` slots from wrapper methods. + # See the comments in `TpSlots.updateSlots` method for the mechanism. + # This test checks various corner cases arising from that. They don't all use C ext, but I'd like to keep + # all the cases in one place + class X: + pass + + class Y(int): + def __new__(cls, value): + raise AssertionError + + class Z(Y): + pass + + X.__new__ = int.__new__ + Z.__new__ = int.__new__ + + # X() runs object.__new__, ignoring the reassignment + x = X() + assert isinstance(x, X) + # Z() runs int.__new__. It also ignored the reassignment, but since tp_new was and still is set to slot_tp_new, + # it will do the call through dict, which ends up doing the right thing in this case + z = Z(1) + assert isinstance(z, int) + + # The bug can also manifest in multiple-inheritance. A variant of this case appears in pandas DominantBase = CPyExtType( 'DominantBase', ''' @@ -904,8 +930,8 @@ def test_new_inherited_from_dominant_base(self): class Subclass(WeakBase, DominantBase): pass - # In CPython 3.10, Subclass.__new__ is WeakBase.__new__, but Subclass.tp_new is DominantBase.tp_new - + # In CPython, Subclass.__new__ is WeakBase.__new__, but Subclass.tp_new is DominantBase.tp_new + assert Subclass.__new__.__self__ is WeakBase assert Subclass() is Ellipsis def test_descrget(self): diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_pystate.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_pystate.py index 5fe1c61976..319cbd9019 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_pystate.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_pystate.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -111,4 +111,4 @@ def other_thread(): SetAsyncExcCaller.trigger_ex(t.ident, Exception("test my message")) t.join() - assert "test my message" in str(caught_ex) + assert "test my message" in str(caught_ex), str(caught_ex) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_shutdown.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_shutdown.py index 1606809563..111d06fb28 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_shutdown.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_shutdown.py @@ -51,6 +51,8 @@ ARGS = [] if sys.implementation.name == 'graalpy': ARGS = ['--experimental-options', '--python.EnableDebuggingBuiltins'] + if not __graalpython__.is_native and __graalpython__.is_bytecode_dsl_interpreter: + ARGS += ['--vm.Dpython.EnableBytecodeDSLInterpreter=true'] COMMAND = [sys.executable, *ARGS, str(MODULE_PATH)] diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_structseq.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_structseq.py index 6f92f37932..4d65183658 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_structseq.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_structseq.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -48,6 +48,7 @@ def test_properties(self): static PyStructSequence_Field typeinfo_fields[] = { {"element0", "The first element."}, {"element1", "The second element."}, + {"element2", "The third element."}, {NULL, NULL,} }; @@ -69,11 +70,18 @@ def test_properties(self): ) assert TestPyStructSequence.__doc__ == "Information about some custom struct type" - tester = TestPyStructSequence(("hello", "world")) + tester = TestPyStructSequence(("hello", "world"), {"element2": 1}) assert hasattr(tester, "element0") assert hasattr(tester, "element1") assert tester.element0 == "hello" assert tester.element1 == "world" + assert tester.element2 == 1 + assert len(tester) == 2 + assert tuple(tester) == ("hello", "world") + assert repr(tester) == "TestPyStructSequenceTypes.TestPyStructSequence(element0='hello', element1='world')" + assert tester.__repr__() == "TestPyStructSequenceTypes.TestPyStructSequence(element0='hello', element1='world')" + assert tester.__reduce__() == (TestPyStructSequence, (('hello', 'world'), {'element2': 1})) + assert tester.__reduce__.__qualname__ == "TestPyStructSequence.__reduce__" def test_structseq_newtype(self): TestPyStructSequenceNewType = CPyExtType("TestPyStructSequenceNewType", """ diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tp_slots.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tp_slots.py index 28af6b6bd9..fddd7ca153 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tp_slots.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tp_slots.py @@ -36,10 +36,12 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -import operator +import itertools import sys +import operator from . import CPyExtType, CPyExtHeapType, compile_module_from_string, assert_raises, compile_module_from_file +from .test_indexed_slots import cmembers def get_delegate(o): @@ -293,14 +295,14 @@ def test_concat_vs_add(): x = SqAdd() assert x + x is x - # TODO: assert _operator.concat(x, x) is x when _operator.concat is implemented + assert operator.concat(x, x) is x assert x.__add__(x) is x class SqAddManaged(SqAdd): pass x = SqAddManaged() assert x + x is x assert x.__add__(x) is x - # TODO: assert _operator.concat(x, x) is x when _operator.concat is implemented + assert operator.concat(x, x) is x SqAddAndNbAdd = CPyExtHeapType("SqAddAndNbAdd", slots= [ @@ -314,7 +316,313 @@ class SqAddManaged(SqAdd): pass x = SqAddAndNbAdd() y = SqAddAndNbAdd() assert x + y is y - # TODO: assert _operator.concat(x, x) is x when _operator.concat is implemented + assert operator.concat(x, y) is x + + SqAddAndNbAddNoImplemented = CPyExtHeapType("SqAddAndNbAddNoImplemented", + slots= [ + '{Py_sq_concat, &concat}', + '{Py_nb_add, &myadd}', + ], + code= + 'PyObject* concat(PyObject* a, PyObject *b) { Py_INCREF(a); return a; }' + + 'PyObject* myadd(PyObject* a, PyObject *b) { Py_RETURN_NOTIMPLEMENTED; }') + x = SqAddAndNbAddNoImplemented() + assert x + 1 is x + + +def test_inplace_fallback(): + WithSlot = CPyExtHeapType( + "NbAdd1", + slots=[ + '{Py_nb_add, &nb_add}', + ], + code=''' + PyObject* nb_add(PyObject* a, PyObject *b) { return PyUnicode_FromString("add1"); } + ''', + ) + WithInplaceSlot = CPyExtHeapType( + "NbInplaceAdd1", + slots=[ + '{Py_nb_add, &nb_add}', + '{Py_nb_inplace_add, &nb_inplace_add}', + ], + code=''' + PyObject* nb_add(PyObject* a, PyObject *b) { return PyUnicode_FromString("add2"); } + PyObject* nb_inplace_add(PyObject* a, PyObject *b) { return PyUnicode_FromString("inplace_add"); } + ''', + ) + x = WithSlot() + y = WithInplaceSlot() + x += y + assert x == "add1" + x = WithSlot() + y += x + assert y == "inplace_add" + x = object() + y = WithInplaceSlot() + x += y + assert x == "add2" + + +def test_sq_inplace_concat_vs_nb_inplace_add(): + SqInplaceConcat = CPyExtHeapType( + "SqInplaceConcat", + slots=[ + '{Py_sq_concat, &concat}', + '{Py_sq_inplace_concat, &inplace_concat}', + ], + code=''' + PyObject* concat(PyObject* a, PyObject *b) { return PyUnicode_FromString("concat"); } + PyObject* inplace_concat(PyObject* a, PyObject *b) { return PyUnicode_FromString("inplace_concat"); } + ''', + ) + x = SqInplaceConcat() + x += 1 + assert x == "inplace_concat" + x = SqInplaceConcat() + assert operator.iconcat(x, []) == "inplace_concat" + + SqInplaceConcatAndNbInplaceAdd = CPyExtHeapType( + "SqInplaceConcatAndNbInplaceAdd", + slots=['{Py_sq_inplace_concat, &inplace_concat}', '{Py_nb_inplace_add, &inplace_add}'], + code=''' + PyObject* inplace_concat(PyObject* a, PyObject *b) { return PyUnicode_FromString("inplace_concat"); } + PyObject* inplace_add(PyObject* a, PyObject *b) { return PyUnicode_FromString("inplace_add"); } + ''', + ) + + x = SqInplaceConcatAndNbInplaceAdd() + x += 1 + assert x == "inplace_add" + x = SqInplaceConcatAndNbInplaceAdd() + assert operator.iconcat(x, 1) == "inplace_concat" + + SqInplaceConcatAndNbInplaceAddNotImplemented = CPyExtHeapType( + "InplaceConcatAddNotImpl", + slots=['{Py_sq_inplace_concat, &inplace_concat}', '{Py_nb_inplace_add, &inplace_add}'], + code=''' + PyObject* inplace_concat(PyObject* a, PyObject *b) { return PyUnicode_FromString("inplace_concat"); } + PyObject* inplace_add(PyObject* a, PyObject *b) { Py_RETURN_NOTIMPLEMENTED; } + ''', + ) + + x = SqInplaceConcatAndNbInplaceAddNotImplemented() + x += 1 + assert x == "inplace_concat" + + class InplaceConcatSubclass(SqInplaceConcat): + pass + + x = InplaceConcatSubclass() + assert operator.iconcat(x, 1) == "inplace_concat" + + SqConcat = CPyExtHeapType( + "SqConcat", + slots=['{Py_sq_concat, &concat}'], + code='PyObject* concat(PyObject* a, PyObject *b) { return PyUnicode_FromString("concat"); }', + ) + + x = SqConcat() + x += 1 + assert x == "concat" + x = SqConcat() + assert operator.iconcat(x, 1) == "concat" + + NbInplaceAdd = CPyExtHeapType( + "NbInplaceAdd", + slots=['{Py_nb_inplace_add, &inplace_add}'], + code='PyObject* inplace_add(PyObject* a, PyObject *b) { return PyUnicode_FromString("inplace_add"); }', + ) + + x = NbInplaceAdd() + assert_raises(TypeError, operator.iconcat, x, 1) + assert_raises(TypeError, operator.iconcat, x, []) + + SequenceWithNbInplaceAdd = CPyExtHeapType( + "SequenceWithNbInplaceAdd", + slots=['{Py_nb_inplace_add, &inplace_add}', '{Py_sq_item, &item}'], + code=''' + PyObject* inplace_add(PyObject* a, PyObject *b) { return PyUnicode_FromString("inplace_add"); } + PyObject* item(PyObject* a, PyObject *b) { return PyUnicode_FromString("item"); } + ''', + ) + + x = SequenceWithNbInplaceAdd() + assert_raises(TypeError, operator.iconcat, x, 1) + assert operator.iconcat(x, []) == "inplace_add" + +CallRepeatHelper = CPyExtType( + "CallRepeatHelper", + code=''' + PyObject* call_repeat(PyObject* unused, PyObject* args) { + PyObject* obj; + Py_ssize_t times; + if (!PyArg_ParseTuple(args, "On", &obj, ×)) + return NULL; + return PySequence_Repeat(obj, times); + } + PyObject* call_inplace_repeat(PyObject* unused, PyObject* args) { + PyObject* obj; + Py_ssize_t times; + if (!PyArg_ParseTuple(args, "On", &obj, ×)) + return NULL; + return PySequence_InPlaceRepeat(obj, times); + } + ''', + tp_methods=''' + {"PySequence_Repeat", (PyCFunction)call_repeat, METH_VARARGS | METH_STATIC, ""}, + {"PySequence_InPlaceRepeat", (PyCFunction)call_inplace_repeat, METH_VARARGS | METH_STATIC, ""} + ''' +) + + +def test_repeat_vs_multiply(): + SqRepeat = CPyExtHeapType( + "SqRepeat", + slots=['{Py_sq_repeat, &repeat}'], + code='PyObject* repeat(PyObject* a, Py_ssize_t times) { return PyUnicode_FromString("repeat"); }', + ) + + x = SqRepeat() + assert x * 2 == "repeat" + assert 2 * x == "repeat" + assert CallRepeatHelper.PySequence_Repeat(x, 2) == "repeat" + assert x.__mul__(2) == "repeat" + assert x.__rmul__(2) == "repeat" + assert_raises(TypeError, operator.mul, x, x) + + class SqRepeatManaged(SqRepeat): pass + + x = SqRepeatManaged() + assert x * 2 == "repeat" + assert 2 * x == "repeat" + assert CallRepeatHelper.PySequence_Repeat(x, 2) == "repeat" + assert x.__mul__(2) == "repeat" + assert x.__rmul__(2) == "repeat" + assert_raises(TypeError, operator.mul, x, x) + + SqRepeatAndNbMultiply = CPyExtHeapType( + "SqRepeatAndNbMultiply", + slots=[ + '{Py_sq_repeat, &repeat}', + '{Py_nb_multiply, &mymultiply}', + ], + code=''' + PyObject* repeat(PyObject* a, Py_ssize_t times) { return PyUnicode_FromString("repeat"); } + PyObject* mymultiply(PyObject* a, PyObject *b) { return PyUnicode_FromString("multiply"); } + ''', + ) + + x = SqRepeatAndNbMultiply() + assert x * 2 == "multiply" + assert 2 * x == "multiply" + assert CallRepeatHelper.PySequence_Repeat(x, 2) == "repeat" + + SqRepeatAndNbMultiplyNoImplemented = CPyExtHeapType( + "RepeatAndMulNotImpl", + slots=[ + '{Py_sq_repeat, &repeat}', + '{Py_nb_multiply, &mymultiply}', + ], + code=''' + PyObject* repeat(PyObject* a, Py_ssize_t times) { return PyUnicode_FromString("repeat"); } + PyObject* mymultiply(PyObject* a, PyObject *b) { Py_RETURN_NOTIMPLEMENTED; } + ''', + ) + x = SqRepeatAndNbMultiplyNoImplemented() + assert x * 2 == "repeat" + + +def test_sq_inplace_repeat_vs_nb_inplace_multiply(): + SqInplaceRepeat = CPyExtHeapType( + "SqInplaceRepeat", + slots=[ + '{Py_sq_repeat, &repeat}', + '{Py_sq_inplace_repeat, &inplace_repeat}' + ], + code=''' + PyObject* repeat(PyObject* a, PyObject *b) { return PyUnicode_FromString("repeat"); } + PyObject* inplace_repeat(PyObject* a, Py_ssize_t times) { return PyUnicode_FromString("inplace_repeat"); } + ''', + ) + x = SqInplaceRepeat() + x *= 1 + assert x == "inplace_repeat" + x = SqInplaceRepeat() + assert CallRepeatHelper.PySequence_InPlaceRepeat(x, 1) == "inplace_repeat" + + x = 1 + x *= SqInplaceRepeat() + assert x == "repeat" + + SqInplaceRepeatAndNbInplaceMultiply = CPyExtHeapType( + "SqInplaceRepeatAndNbInMul", + slots=['{Py_sq_inplace_repeat, &inplace_repeat}', '{Py_nb_inplace_multiply, &inplace_multiply}'], + code=''' + PyObject* inplace_repeat(PyObject* a, Py_ssize_t times) { return PyUnicode_FromString("inplace_repeat"); } + PyObject* inplace_multiply(PyObject* a, PyObject* b) { return PyUnicode_FromString("inplace_multiply"); } + ''', + ) + + x = SqInplaceRepeatAndNbInplaceMultiply() + x *= 1 + assert x == "inplace_multiply" + x = SqInplaceRepeatAndNbInplaceMultiply() + assert CallRepeatHelper.PySequence_InPlaceRepeat(x, 1) == "inplace_repeat" + + SqInplaceRepeatAndNbInplaceMultiplyNotImplemented = CPyExtHeapType( + "InplaceRepeatAndMulNotImpl", + slots=['{Py_sq_inplace_repeat, &inplace_repeat}', '{Py_nb_inplace_multiply, &inplace_multiply}'], + code=''' + PyObject* inplace_repeat(PyObject* a, Py_ssize_t times) { return PyUnicode_FromString("inplace_repeat"); } + PyObject* inplace_multiply(PyObject* a, PyObject *b) { Py_RETURN_NOTIMPLEMENTED; } + ''', + ) + + x = SqInplaceRepeatAndNbInplaceMultiplyNotImplemented() + x *= 1 + assert x == "inplace_repeat" + + class InplaceRepeatSubclass(SqInplaceRepeat): + pass + + x = InplaceRepeatSubclass() + assert CallRepeatHelper.PySequence_InPlaceRepeat(x, 1) == "inplace_repeat" + + SqRepeat = CPyExtHeapType( + "SqRepeat2", + slots=['{Py_sq_repeat, &repeat}'], + code='PyObject* repeat(PyObject* a, PyObject *b) { return PyUnicode_FromString("repeat"); }', + ) + + x = SqRepeat() + x *= 1 + assert x == "repeat" + x = SqRepeat() + assert CallRepeatHelper.PySequence_InPlaceRepeat(x, 1) == "repeat" + + NbInplaceMultiply = CPyExtHeapType( + "NbInplaceMultiply", + slots=['{Py_nb_inplace_multiply, &inplace_multiply}'], + code='PyObject* inplace_multiply(PyObject* a, PyObject *b) { return PyUnicode_FromString("inplace_multiply"); }', + ) + + x = NbInplaceMultiply() + assert_raises(TypeError, CallRepeatHelper.PySequence_InPlaceRepeat, x, 1) + assert_raises(TypeError, CallRepeatHelper.PySequence_InPlaceRepeat, x, []) + + SequenceWithNbInplaceMultiply = CPyExtHeapType( + "SequenceWithNbInplaceMultiply", + slots=['{Py_nb_inplace_multiply, &inplace_multiply}', '{Py_sq_item, &item}'], + code=''' + PyObject* inplace_multiply(PyObject* a, PyObject *b) { return PyUnicode_FromString("inplace_multiply"); } + PyObject* item(PyObject* a, PyObject *b) { return PyUnicode_FromString("item"); } + ''', + ) + + x = SequenceWithNbInplaceMultiply() + assert_raises(TypeError, CallRepeatHelper.PySequence_InPlaceRepeat, x, []) + assert CallRepeatHelper.PySequence_InPlaceRepeat(x, 1) == "inplace_multiply" def test_incompatible_slots_assignment(): @@ -504,8 +812,8 @@ class InheritsHash(TypeWithHash): def assert_has_no_hash(obj): assert_raises(TypeError, hash, obj) - assert type(obj).__hash__ is None - assert TypeWithoutHash.has_hash_not_implemented(obj) + assert type(obj).__hash__ is None, f"{type(obj).__hash__=}, {TypeWithoutHash.has_hash_not_implemented(obj)=}" + assert TypeWithoutHash.has_hash_not_implemented(obj), f"{type(obj).__hash__=}, {TypeWithoutHash.has_hash_not_implemented(obj)=}" assert_has_no_hash(TypeWithoutHash()) @@ -531,13 +839,27 @@ class DisablesHash2(TypeWithHash): assert_has_no_hash(DisablesHash2()) - # TODO GR-55196 - # TypeWithoutHashExplicit = CPyExtType( - # "TypeWithoutHashExplicit", - # tp_hash='PyObject_HashNotImplemented', - # ) - # - # assert_has_no_hash(TypeWithoutHashExplicit()) + TypeWithoutHashExplicit = CPyExtType( + "TypeWithoutHashExplicit", + tp_hash='PyObject_HashNotImplemented', + code = ''' + // static hashfunc myglobal = PyObject_HashNotImplemented; + // typedef struct { hashfunc x; } _mystruct_t; + // static _mystruct_t mystruct = { PyObject_HashNotImplemented }; + ''', + ready_code = ''' + // printf("TypeWithoutHashExplicitType.tp_hash=%p, PyObject_HashNotImplemented=%p, myglobal=%p, mystruct.x=%p\\n", TypeWithoutHashExplicitType.tp_hash, &PyObject_HashNotImplemented, myglobal, mystruct.x); + // printf("TypeWithoutHashExplicitType.tp_as_mapping=%p, TypeWithoutHashExplicit_mapping_methods=%p\\n", TypeWithoutHashExplicitType.tp_as_mapping, &TypeWithoutHashExplicit_mapping_methods); + // printf("offsetof(PyTypeObject, tp_hash)=%p, tp_as_mapping=%p\\n", offsetof(PyTypeObject, tp_hash), offsetof(PyTypeObject, tp_as_mapping)); + // For some reason MSVC initializes tp_hash to some different pointer that also seems to point to PyObject_HashNotImplemented (some dynamic linking issue?) + // This happens on both CPython 3.11 and GraalPy. The printouts above can help debug the issue in the future. + #if defined(_MSC_VER) + TypeWithoutHashExplicitType.tp_hash=PyObject_HashNotImplemented; + #endif + ''' + ) + + assert_has_no_hash(TypeWithoutHashExplicit()) def test_attr_update(): @@ -637,6 +959,47 @@ def test_PyType_Modified_doesnt_change_slots(): assert tester.call_PySequence_GetItem(1) == 'sq_item' +class DelegateSlot: + def __set_name__(self, owner, name): + self.name = name + + def __get__(self, obj, objtype=None): + return getattr(obj.delegate, self.name) + + +class DelegateInplaceSlot(DelegateSlot): + def __get__(self, obj, objtype=None): + method = getattr(obj.delegate, self.name, None) + if method is None: + method = getattr(obj.delegate, self.name.replace('__i', '__')) + + def wrapper(*args): + self.delegate = method(*args) + return self + + return wrapper + + +native_slot_proxy_template = ''' +static PyObject* get_delegate(PyObject* self) { + return ((ProxyObject*)self)->delegate; +} +static void set_delegate(PyObject* self, PyObject* delegate) { + Py_XSETREF(((ProxyObject*)self)->delegate, delegate); +} +static PyObject* proxy_tp_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) { + PyObject* delegate; + if (!PyArg_UnpackTuple(args, "NativeSlotProxy", 0, 1, &delegate)) + return NULL; + ProxyObject* obj = (ProxyObject*)type->tp_alloc(type, 0); + if (!obj) + return NULL; + obj->delegate = Py_NewRef(delegate); // leaked + return (PyObject*)obj; +} +''' + + def test_nb_slot_calls(): slots = [ ('proxy_nb_binary_slot', 'nb_add'), @@ -680,22 +1043,7 @@ def test_nb_slot_calls(): cmembers='PyObject* delegate;', code=r''' typedef NativeNbSlotProxyObject ProxyObject; - static PyObject* get_delegate(PyObject* self) { - return ((ProxyObject*)self)->delegate; - } - static void set_delegate(PyObject* self, PyObject* delegate) { - Py_XSETREF(((ProxyObject*)self)->delegate, delegate); - } - static PyObject* proxy_tp_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) { - PyObject* delegate; - if (!PyArg_UnpackTuple(args, "NativeNbSlotProxy", 0, 1, &delegate)) - return NULL; - ProxyObject* obj = (ProxyObject*)type->tp_alloc(type, 0); - if (!obj) - return NULL; - obj->delegate = Py_NewRef(delegate); // leaked - return (PyObject*)obj; - } + ''' + native_slot_proxy_template + r''' static PyTypeObject NativeNbSlotProxyType; #define proxy_nb_unary_slot(slot) \ static PyObject* proxy_##slot(PyObject *a) { \ @@ -754,92 +1102,59 @@ def test_nb_slot_calls(): **{slot: f'proxy_{slot}' for _, slot in slots}, ) - def _unary_op(op): - def fn(a): - return op(a.delegate) - - return fn - - def _binary_op(op): - def fn(a, b): - return op(a.delegate, b) - - return fn - - def _binary_op_r(op): - def fn(a, b): - return op(b, a.delegate) - - return fn - - def _binary_op_inplace(op): - def fn(a, b): - a.delegate = op(a.delegate, b) - return a - - return fn - class PureSlotProxy: def __init__(self, delegate): self.delegate = delegate - __add__ = _binary_op(operator.add) - __radd__ = _binary_op_r(operator.add) - __iadd__ = _binary_op_inplace(operator.add) - __sub__ = _binary_op(operator.sub) - __rsub__ = _binary_op_r(operator.sub) - __isub__ = _binary_op_inplace(operator.sub) - __mul__ = _binary_op(operator.mul) - __rmul__ = _binary_op_r(operator.mul) - __imul__ = _binary_op_inplace(operator.mul) - __mod__ = _binary_op(operator.mod) - __rmod__ = _binary_op_r(operator.mod) - __imod__ = _binary_op_inplace(operator.mod) - __floordiv__ = _binary_op(operator.floordiv) - __rfloordiv__ = _binary_op_r(operator.floordiv) - __ifloordiv__ = _binary_op_inplace(operator.floordiv) - __truediv__ = _binary_op(operator.truediv) - __rtruediv__ = _binary_op_r(operator.truediv) - __itruediv__ = _binary_op_inplace(operator.truediv) - __divmod__ = _binary_op(divmod) - __rdivmod__ = _binary_op_r(divmod) - - def __pow__(self, power, modulo=None): - return pow(self.delegate, power, modulo) - - def __rpow__(self, other): - return other ** self.delegate - - def __ipow__(self, other): - self.delegate = self.delegate ** other - return self - - __pos__ = _unary_op(operator.pos) - __neg__ = _unary_op(operator.neg) - __abs__ = _unary_op(abs) - __bool__ = _unary_op(bool) - __invert__ = _unary_op(operator.invert) - __index__ = _unary_op(operator.index) - __int__ = _unary_op(int) - __float__ = _unary_op(float) - __lshift__ = _binary_op(operator.lshift) - __rlshift__ = _binary_op_r(operator.lshift) - __ilshift__ = _binary_op_inplace(operator.lshift) - __rshift__ = _binary_op(operator.rshift) - __rrshift__ = _binary_op_r(operator.rshift) - __irshift__ = _binary_op_inplace(operator.rshift) - __and__ = _binary_op(operator.and_) - __rand__ = _binary_op_r(operator.and_) - __iand__ = _binary_op_inplace(operator.and_) - __or__ = _binary_op(operator.or_) - __ror__ = _binary_op_r(operator.or_) - __ior__ = _binary_op_inplace(operator.or_) - __xor__ = _binary_op(operator.xor) - __rxor__ = _binary_op_r(operator.xor) - __ixor__ = _binary_op_inplace(operator.xor) - __matmul__ = _binary_op(operator.matmul) - __rmatmul__ = _binary_op_r(operator.matmul) - __imatmul__ = _binary_op_inplace(operator.matmul) + __add__ = DelegateSlot() + __radd__ = DelegateSlot() + __iadd__ = DelegateInplaceSlot() + __sub__ = DelegateSlot() + __rsub__ = DelegateSlot() + __isub__ = DelegateInplaceSlot() + __mul__ = DelegateSlot() + __rmul__ = DelegateSlot() + __imul__ = DelegateInplaceSlot() + __mod__ = DelegateSlot() + __rmod__ = DelegateSlot() + __imod__ = DelegateInplaceSlot() + __floordiv__ = DelegateSlot() + __rfloordiv__ = DelegateSlot() + __ifloordiv__ = DelegateInplaceSlot() + __truediv__ = DelegateSlot() + __rtruediv__ = DelegateSlot() + __itruediv__ = DelegateInplaceSlot() + __divmod__ = DelegateSlot() + __rdivmod__ = DelegateSlot() + __pow__ = DelegateSlot() + __rpow__ = DelegateSlot() + __ipow__ = DelegateInplaceSlot() + __pos__ = DelegateSlot() + __neg__ = DelegateSlot() + __abs__ = DelegateSlot() + __bool__ = DelegateSlot() + __invert__ = DelegateSlot() + __index__ = DelegateSlot() + __int__ = DelegateSlot() + __float__ = DelegateSlot() + __lshift__ = DelegateSlot() + __rlshift__ = DelegateSlot() + __ilshift__ = DelegateInplaceSlot() + __rshift__ = DelegateSlot() + __rrshift__ = DelegateSlot() + __irshift__ = DelegateInplaceSlot() + __and__ = DelegateSlot() + __rand__ = DelegateSlot() + __iand__ = DelegateInplaceSlot() + __or__ = DelegateSlot() + __ror__ = DelegateSlot() + __ior__ = DelegateInplaceSlot() + __xor__ = DelegateSlot() + __rxor__ = DelegateSlot() + __ixor__ = DelegateInplaceSlot() + __matmul__ = DelegateSlot() + __rmatmul__ = DelegateSlot() + __imatmul__ = DelegateInplaceSlot() class ObjWithMatmul: def __matmul__(self, other): @@ -859,13 +1174,12 @@ def __rmatmul__(self, other): assert 2 % obj == 2 assert divmod(obj, 2) == (1, 1) assert divmod(2, obj) == (0, 2) - # TODO fix on graalpy - # assert obj ** 2 == 9 - # assert 2 ** obj == 8 - # assert pow(obj, 2, 2) == 1 - # if isinstance(obj.delegate, int): # pow doesn't call __rpow__ - # assert pow(2, obj, 2) == 0 - # assert pow(2, 2, obj) == 1 + assert obj ** 2 == 9 + assert 2 ** obj == 8 + assert pow(obj, 2, 2) == 1 + if isinstance(obj.delegate, int): # pow doesn't call __rpow__ + assert pow(2, obj, 2) == 0 + assert pow(2, 2, obj) == 1 assert -obj == -3 assert +obj == 3 assert abs(obj) == 3 @@ -905,10 +1219,9 @@ def __rmatmul__(self, other): obj = NativeNbSlotProxy(PureSlotProxy(3)) obj %= 2 assert obj.delegate.delegate == 1 - # TODO fix on graalpy - # obj = NativeNbSlotProxy(PureSlotProxy(3)) - # obj **= 2 - # assert obj.delegate.delegate == 9 + obj = NativeNbSlotProxy(PureSlotProxy(3)) + obj **= 2 + assert obj.delegate.delegate == 9 obj = NativeNbSlotProxy(PureSlotProxy(3)) obj <<= 2 assert obj.delegate.delegate == 12 @@ -930,10 +1243,9 @@ def __rmatmul__(self, other): obj = NativeNbSlotProxy(PureSlotProxy(3)) obj /= 2 assert obj.delegate.delegate == 1.5 - # TODO fix on graalpy - # obj = NativeNbSlotProxy(PureSlotProxy(ObjWithMatmul())) - # obj @= 1 - # assert obj.delegate.delegate == '@' + obj = NativeNbSlotProxy(PureSlotProxy(ObjWithMatmul())) + obj @= 1 + assert obj.delegate.delegate == '@' def test_sq_slot_calls(): @@ -942,22 +1254,7 @@ def test_sq_slot_calls(): cmembers='PyObject* delegate;', code=r''' typedef NativeSqSlotProxyObject ProxyObject; - static PyObject* get_delegate(PyObject* self) { - return ((ProxyObject*)self)->delegate; - } - static void set_delegate(PyObject* self, PyObject* delegate) { - Py_XSETREF(((ProxyObject*)self)->delegate, delegate); - } - static PyObject* proxy_tp_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) { - PyObject* delegate; - if (!PyArg_UnpackTuple(args, "NativeSqSlotProxy", 0, 1, &delegate)) - return NULL; - ProxyObject* obj = (ProxyObject*)type->tp_alloc(type, 0); - if (!obj) - return NULL; - obj->delegate = Py_NewRef(delegate); // leaked - return (PyObject*)obj; - } + ''' + native_slot_proxy_template + r''' static Py_ssize_t proxy_sq_length(PyObject* self) { PyObject* delegate = get_delegate(self); return Py_TYPE(delegate)->tp_as_sequence->sq_length(delegate); @@ -1015,27 +1312,17 @@ class PureSlotProxy: def __init__(self, delegate): self.delegate = delegate - def __len__(self): - return len(self.delegate) - - def __getitem__(self, item): - return self.delegate[item] - - def __setitem__(self, key, value): - self.delegate[key] = value - - def __delitem__(self, key): - del self.delegate[key] - - def __contains__(self, item): - return item in self.delegate + __len__ = DelegateSlot() + __getitem__ = DelegateSlot() + __setitem__ = DelegateSlot() + __delitem__ = DelegateSlot() + __contains__ = DelegateSlot() for obj in [NativeSqSlotProxy([1]), NativeSqSlotProxy(PureSlotProxy([1]))]: assert len(obj) == 1 assert bool(obj) - # TODO fix on graalpy - # assert 1 in obj - # assert 2 not in obj + assert 1 in obj + assert 2 not in obj assert obj[0] == 1 assert_raises(IndexError, operator.getitem, obj, 1) @@ -1061,30 +1348,27 @@ def __contains__(self, item): obj = NativeSqSlotProxy([1]) assert obj + [2] == [1, 2] - # TODO fix on graalpy - # obj += [2] - # assert obj.delegate == [1, 2] + obj += [2] + assert obj.delegate == [1, 2] obj = NativeSqSlotProxy([1]) assert obj * 2 == [1, 1] - # TODO fix on graalpy - # obj *= 2 - # assert obj.delegate == [1, 1] + obj *= 2 + assert obj.delegate == [1, 1] obj = NativeSqSlotProxy([1]) assert_raises(TypeError, operator.mul, obj, "a") assert_raises(OverflowError, operator.mul, obj, 1 << 65) - # TODO fix on graalpy - # try: - # obj *= "a" - # except TypeError: - # pass - # else: - # assert False - # try: - # obj *= 1 << 65 - # except OverflowError: - # pass - # else: - # assert False + try: + obj *= "a" + except TypeError: + pass + else: + assert False + try: + obj *= 1 << 65 + except OverflowError: + pass + else: + assert False assert get_delegate(obj) == [1] @@ -1094,19 +1378,7 @@ def test_mp_slot_calls(): cmembers='PyObject* delegate;', code=r''' typedef NativeMpSlotProxyObject ProxyObject; - static PyObject* get_delegate(PyObject* self) { - return ((ProxyObject*)self)->delegate; - } - static PyObject* proxy_tp_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) { - PyObject* delegate; - if (!PyArg_UnpackTuple(args, "NativeMpSlotProxy", 0, 1, &delegate)) - return NULL; - ProxyObject* obj = (ProxyObject*)type->tp_alloc(type, 0); - if (!obj) - return NULL; - obj->delegate = Py_NewRef(delegate); // leaked - return (PyObject*)obj; - } + ''' + native_slot_proxy_template + r''' static Py_ssize_t proxy_mp_length(PyObject* self) { PyObject* delegate = get_delegate(self); return Py_TYPE(delegate)->tp_as_mapping->mp_length(delegate); @@ -1131,17 +1403,11 @@ class PureSlotProxy: def __init__(self, delegate): self.delegate = delegate - def __len__(self): - return len(self.delegate) - - def __getitem__(self, item): - return self.delegate[item] - - def __setitem__(self, key, value): - self.delegate[key] = value - - def __delitem__(self, key): - del self.delegate[key] + __len__ = DelegateSlot() + __getitem__ = DelegateSlot() + __setitem__ = DelegateSlot() + __delitem__ = DelegateSlot() + __contains__ = DelegateSlot() for obj in [NativeMpSlotProxy({'a': 1}), NativeMpSlotProxy(PureSlotProxy({'a': 1}))]: assert len(obj) == 1 @@ -1157,3 +1423,329 @@ def __delitem__(self, key): assert get_delegate(obj) == {'a': 1} del obj['a'] assert not bool(obj) + + +def test_tp_iter_iternext_calls(): + NativeSlotProxy = CPyExtType( + name='TpIterSlotProxy', + cmembers='PyObject* delegate;', + code=r''' + typedef TpIterSlotProxyObject ProxyObject; + ''' + native_slot_proxy_template + r''' + static PyObject* proxy_tp_iter(PyObject* self) { + PyObject* delegate = get_delegate(self); + return Py_TYPE(delegate)->tp_iter(delegate); + } + static PyObject* proxy_tp_iternext(PyObject* self) { + PyObject* delegate = get_delegate(self); + return Py_TYPE(delegate)->tp_iternext(delegate); + } + ''', + tp_new='proxy_tp_new', + tp_members='{"delegate", T_OBJECT, offsetof(ProxyObject, delegate), 0, NULL}', + tp_iter='proxy_tp_iter', + tp_iternext='proxy_tp_iternext', + ) + + class PureSlotProxy: + def __init__(self, delegate): + self.delegate = delegate + + __iter__ = DelegateSlot() + __next__ = DelegateSlot() + + for obj in [NativeSlotProxy([1]), NativeSlotProxy(PureSlotProxy([1]))]: + assert isinstance(iter(obj), type(iter([]))) + + for obj in [NativeSlotProxy(iter([1])), NativeSlotProxy(PureSlotProxy(iter([1])))]: + assert next(obj) == 1 + assert_raises(StopIteration, next, obj) + + +def test_tp_iternext_not_implemented(): + class ManagedTypeWithVanishingNext: + def __next__(self): + del type(self).__next__ + return True + + NativeTypeWithVanishingNext = CPyExtHeapType( + name='TypeWithVanishingNext', + code=r''' + static PyObject* tp_iternext(TypeWithVanishingNextObject* self) { + if (PyObject_DelAttrString((PyObject*)Py_TYPE(self), "__next__") < 0) + return NULL; + Py_RETURN_TRUE; + } + ''', + slots=['{Py_tp_iternext, tp_iternext}'], + ) + + tester = CPyExtType( + 'IterableTester', + r''' + PyObject* iter_check(PyObject* unused, PyObject* obj) { + return PyBool_FromLong(PyIter_Check(obj)); + } + PyObject* not_impl_check(PyObject* unused, PyObject* obj) { + return PyBool_FromLong(Py_TYPE(obj)->tp_iternext == _PyObject_NextNotImplemented); + } + ''', + tp_methods=''' + {"PyIter_Check", iter_check, METH_O | METH_STATIC, ""}, + {"has_not_implemented_iternext", not_impl_check, METH_O | METH_STATIC, ""} + ''', + ) + + for TypeWithVanishingNext in (ManagedTypeWithVanishingNext, NativeTypeWithVanishingNext): + + class Iterable: + def __iter__(self): + return TypeWithVanishingNext() + + try: + # We need to use a builtin that stores the iterator inside without rechecking it + i = itertools.takewhile(lambda x: x, Iterable()) + assert next(i) is True + next(i) + except TypeError as e: + # We need to check the message, because it's not the one from `next`, but from _PyObject_NextNotImplemented + assert str(e).endswith("is not iterable") + else: + assert False + + i = TypeWithVanishingNext() + try: + next(i) + except TypeError as e: + # Different message, now from `next` directly + assert str(e).endswith("is not an iterator") + + assert not tester.PyIter_Check(i) + assert tester.has_not_implemented_iternext(i) + + NativeTypeWithNotImplementedNext = CPyExtHeapType( + name='TypeWithNotImplNext', + slots=['{Py_tp_iternext, _PyObject_NextNotImplemented}'], + ) + i = NativeTypeWithNotImplementedNext() + assert not tester.PyIter_Check(i) + assert tester.has_not_implemented_iternext(i) + try: + next(i) + except TypeError as e: + assert str(e).endswith("is not an iterator") + + +def test_tp_str_repr_calls(): + NativeSlotProxy = CPyExtType( + name='TpStrSlotProxy', + cmembers='PyObject* delegate;', + code=r''' + typedef TpStrSlotProxyObject ProxyObject; + ''' + native_slot_proxy_template + r''' + static PyObject* proxy_tp_str(PyObject* self) { + PyObject* delegate = get_delegate(self); + return Py_TYPE(delegate)->tp_str(delegate); + } + static PyObject* proxy_tp_repr(PyObject* self) { + PyObject* delegate = get_delegate(self); + return Py_TYPE(delegate)->tp_repr(delegate); + } + ''', + tp_new='proxy_tp_new', + tp_members='{"delegate", T_OBJECT, offsetof(ProxyObject, delegate), 0, NULL}', + tp_str='proxy_tp_str', + tp_repr='proxy_tp_repr', + ) + + class PureSlotProxy: + def __init__(self, delegate): + self.delegate = delegate + + __str__ = DelegateSlot() + __repr__ = DelegateSlot() + + for obj in [NativeSlotProxy("a\nb"), NativeSlotProxy(PureSlotProxy("a\nb"))]: + assert str(obj) == "a\nb" + assert repr(obj) == repr("a\nb") + + +def test_tp_init_calls(): + NativeSlotProxy = CPyExtType( + name='TpInitSlotProxy', + cmembers='PyObject* delegate;', + code=r''' + typedef TpInitSlotProxyObject ProxyObject; + ''' + native_slot_proxy_template + r''' + int proxy_tp_init(PyObject* self, PyObject* args, PyObject* kwargs) { + PyObject* delegate = get_delegate(self); + return Py_TYPE(delegate)->tp_init(delegate, args, kwargs); + } + ''', + tp_new='proxy_tp_new', + tp_members='{"delegate", T_OBJECT, offsetof(ProxyObject, delegate), 0, NULL}', + tp_init='proxy_tp_init', + ) + + class PureSlotProxy: + def __new__(cls, delegate): + self = object.__new__(cls) + self.delegate = delegate + return self + + def __init__(self, delegate, *args, **kwargs): + self.delegate.__init__(*args, **kwargs) + + obj = NativeSlotProxy([1]) + # Empty because list.__init__ will first clear the storage, which will also clear the argument + assert obj.delegate == [] + assert obj.__init__({2}) is None + assert obj.delegate == [2] + assert_raises(TypeError, NativeSlotProxy, ([1],), {'a': 1}) + + obj = NativeSlotProxy(PureSlotProxy([1])) + assert obj.delegate.delegate == [] + + +def test_tp_new_calls(): + TpNewTester = CPyExtType( + name='TpNewTester', + code=r''' + PyObject* call_tp_new(PyObject* ignored, PyObject* args, PyObject* kwargs) { + PyTypeObject* cls = (PyTypeObject*)PyTuple_GET_ITEM(args, 0); + args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); + if (!args) + return NULL; + PyObject* res = cls->tp_new(cls, args, kwargs); + Py_DECREF(args); + return res; + } + ''', + tp_methods='{"call_tp_new", (PyCFunction)call_tp_new, METH_VARARGS | METH_KEYWORDS | METH_STATIC, NULL}', + ) + assert TpNewTester.call_tp_new(str, 1) == "1" + assert TpNewTester.call_tp_new(str, 'skål'.encode('utf-8'), 'ascii', errors='replace') == "sk��l" + + +def test_disallow_instantiation(): + UninstantiableType = CPyExtType( + name='UninstantiableType', + tp_flags='Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION', + ) + assert_raises(TypeError, UninstantiableType) + + +def test_tp_call_calls(): + NativeSlotProxy = CPyExtType( + name='TpCallSlotProxy', + cmembers='PyObject* delegate;', + code=r''' + typedef TpCallSlotProxyObject ProxyObject; + ''' + native_slot_proxy_template + r''' + PyObject* proxy_tp_call(PyObject* self, PyObject* args, PyObject* kwargs) { + PyObject* delegate = get_delegate(self); + return Py_TYPE(delegate)->tp_call(delegate, args, kwargs); + } + ''', + tp_new='proxy_tp_new', + tp_members='{"delegate", T_OBJECT, offsetof(ProxyObject, delegate), 0, NULL}', + tp_call='proxy_tp_call', + ) + + class PureSlotProxy: + def __new__(cls, delegate): + self = object.__new__(cls) + self.delegate = delegate + return self + + def __call__(self, *args, **kwargs): + return self.delegate(*args, **kwargs) + + for obj in [NativeSlotProxy(len), PureSlotProxy(NativeSlotProxy(len))]: + assert obj([1, 2, 3]) == 3 + assert obj.__call__([1, 2, 3]) == 3 + assert_raises(TypeError, obj) + assert_raises(TypeError, obj, 1, 2) + assert_raises(TypeError, obj, obj=[]) + + for obj in [NativeSlotProxy(dict), PureSlotProxy(NativeSlotProxy(dict))]: + assert obj(a=1) == {'a': 1} + assert obj.__call__({'b': 2}, a=1) == {'a': 1, 'b': 2} + + +def test_richcmp(): + MyNativeIntSubType = CPyExtType("MyNativeIntSubTypeForRichCmpTest", + ready_code = "MyNativeIntSubTypeForRichCmpTestType.tp_new = PyLong_Type.tp_new;", + tp_base='&PyLong_Type', + struct_base='PyLongObject base;') + assert MyNativeIntSubType(42) == 42 + assert MyNativeIntSubType(42) == MyNativeIntSubType(42) + + RichCmpMockType = CPyExtType("RichCmpMock", + cmembers="int results[Py_GE+1];", + code=''' + static PyTypeObject RichCmpMockType; + + static PyObject* set_values(PyObject* self, PyObject* values) { + RichCmpMockObject* richCmp = (RichCmpMockObject*) self; + for (int i = 0; i <= Py_GE; i++) { + richCmp->results[i] = (int) PyLong_AsLong(PyTuple_GET_ITEM(values, i)); + } + Py_RETURN_NONE; + } + + static PyObject *custom_type_richcmp(PyObject *v, PyObject *w, int op) { + if (!PyObject_TypeCheck(v, &RichCmpMockType)) Py_RETURN_NOTIMPLEMENTED; + RichCmpMockObject* richCmp = (RichCmpMockObject*) v; + if (richCmp->results[op] == 0) { + Py_RETURN_FALSE; + } else if (richCmp->results[op] == 1) { + Py_RETURN_TRUE; + } else { + Py_RETURN_NOTIMPLEMENTED; + } + }; + ''', + tp_methods='{"set_values", (PyCFunction)set_values, METH_O, NULL}', + tp_richcompare='custom_type_richcmp') + + def create_mock(lt=-1, le=-1, eq=-1, ne=-1, gt=-1, ge=-1): + mock = RichCmpMockType() + mock.set_values(tuple([lt, le, eq, ne, gt, ge])) + return mock + + def expect_type_error(code): + try: + code() + except TypeError as e: + assert "not supported between instances " in str(e) + + def test_cmp(op_lambda, rop_lambda, op_name, rop_name): + assert op_lambda(create_mock(**{op_name: 1}), "whatever") + assert op_lambda(create_mock(**{op_name: 1}), create_mock(**{rop_name: 0, op_name: 0})) + assert not op_lambda(create_mock(**{op_name: 0}), "whatever") + expect_type_error(lambda: op_lambda(create_mock(), "whatever")) + + if rop_lambda: + assert rop_lambda("whatever", create_mock(**{op_name: 1})) + assert rop_lambda(create_mock(), create_mock(**{op_name: 1})) + assert not rop_lambda(create_mock(**{rop_name: 0}), create_mock(**{op_name: 1})) + + import operator + test_cmp(operator.lt, operator.gt, "lt", "gt") + test_cmp(operator.le, operator.ge, "le", "ge") + test_cmp(operator.gt, operator.lt, "gt", "lt") + test_cmp(operator.ge, operator.le, "ge", "le") + test_cmp(operator.eq, operator.ne, "eq", "ne") + test_cmp(operator.ne, None, "ne", "eq") + + test_cmp(lambda a,b: a.__lt__(b), lambda a,b: a.__gt__(b), "lt", "gt") + test_cmp(lambda a,b: a.__le__(b), lambda a,b: a.__ge__(b), "le", "ge") + test_cmp(lambda a,b: a.__gt__(b), lambda a,b: a.__lt__(b), "gt", "lt") + test_cmp(lambda a,b: a.__ge__(b), lambda a,b: a.__le__(b), "ge", "le") + test_cmp(lambda a,b: a.__eq__(b), lambda a,b: a.__ne__(b), "eq", "ne") + test_cmp(lambda a,b: a.__ne__(b), None, "ne", "eq") + + assert create_mock(ne=1) == create_mock(eq=1) + assert create_mock(ne=1, eq=0) != create_mock(ne=0, eq=1) + assert not create_mock(ne=1, eq=0) == create_mock(ne=0, eq=1) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py index 3570a698fb..8442ad72a9 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -67,6 +67,13 @@ def _reference_setitem(args): return tuple(t) +def _reference_resize(args): + original = args[0] + newsize = args[1] + return original[:newsize] + (None,) * (newsize - len(original)) + return tuple(result) + + class MyStr(str): def __init__(self, s): @@ -151,14 +158,30 @@ class TestPyTuple(CPyExtTestCase): ((1, 2, 3), -1, []), ((1, 2, 3), 3, str), ), - code="""PyObject* wrap_PyTuple_SetItem(PyObject* original, Py_ssize_t index, PyObject* value) { + code=""" + PyObject* wrap_PyTuple_SetItem(PyObject* original, Py_ssize_t index, PyObject* value) { Py_ssize_t size = PyTuple_Size(original); if (size < 0) return NULL; PyObject* tuple = PyTuple_New(size); if (!tuple) return NULL; - for (int i = 0; i < size; i++) { + for (int i = 0; i < size / 2; i++) { + PyObject* item = PyTuple_GetItem(original, i); + if (!item) { + Py_DECREF(tuple); + return NULL; + } + Py_INCREF(item); + PyTuple_SET_ITEM(tuple, i, item); + } + + #ifdef GRAALVM_PYTHON + // test that we also have it as API function on GraalPy + #undef PyTuple_SET_ITEM + #endif + + for (int i = size / 2; i < size; i++) { PyObject* item = PyTuple_GetItem(original, i); if (!item) { Py_DECREF(tuple); @@ -167,6 +190,7 @@ class TestPyTuple(CPyExtTestCase): Py_INCREF(item); PyTuple_SET_ITEM(tuple, i, item); } + Py_INCREF(value); if (PyTuple_SetItem(tuple, index, value) < 0) { Py_DECREF(tuple); @@ -242,6 +266,35 @@ class TestPyTuple(CPyExtTestCase): cmpfunc=unhandled_error_compare ) + # _PyTuple_Resize + test_PyTuple_Resize = CPyExtFunction( + _reference_resize, + lambda: ( + ((1, 2, 3), 1), + ((), 1), + ((1, 2, 3), 5), + ), + code=""" + PyObject* wrap_PyTuple_Resize(PyObject* original, int newsize) { + int size = PyTuple_Size(original); + PyObject *freshTuple = PyTuple_New(size); + for (int i = 0; i < size; ++i) { + PyTuple_SET_ITEM(freshTuple, i, Py_NewRef(PyTuple_GetItem(original, i))); + } + _PyTuple_Resize(&freshTuple, newsize); + for (int i = size; i < newsize; i++) { + PyTuple_SET_ITEM(freshTuple, i, Py_NewRef(Py_None)); + } + return freshTuple; + } + """, + resultspec="O", + argspec='Oi', + arguments=["PyObject* original", "Py_ssize_t newsize"], + callfunction="wrap_PyTuple_Resize", + cmpfunc=unhandled_error_compare, + ) + class TestNativeSubclass(unittest.TestCase): def _verify(self, t): diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_weakref.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_weakref.py index 7963f1aabb..a4ffb3f1bc 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_weakref.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_weakref.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,10 +37,12 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import gc +import time import unittest import weakref -from . import CPyExtType, assert_raises +from . import CPyExtFunction, CPyExtType, assert_raises TestWeakRefHelper = CPyExtType( 'TestWeakRefHelper', @@ -95,3 +97,47 @@ class Bar(clazz): x = Bar() y = weakref.ref(x) assert type(y) == weakref.ReferenceType + + def clear_ref_arguments(): + class Foo(): + pass + f = Foo() + log = [] + wr = weakref.ref(f, lambda wr: log.append("cb called")) + return ((f, wr, log),) + + def clear_ref_equivalent(args): + # Ignore args. There is no clearref in python, so + # the equivalent is a weakref that never had a callback + # in the first place + class Foo(): + pass + f = Foo() + return weakref.ref(f), [] + + def compare_cleared_weakref(cresult, presult): + cwr, clog = cresult + pwr, plog = presult + for i in range(3): + gc.collect() + time.sleep(1) + assert cwr() is None + assert pwr() is None + assert not clog + assert not plog + return True + + test_PyWeakref_ClearRef = CPyExtFunction( + clear_ref_equivalent, + clear_ref_arguments, + code=""" + PyObject* wrap_PyWeakref_ClearRef(PyObject *o, PyObject* weakref, PyObject* log) { + _PyWeakref_ClearRef((PyWeakReference *)weakref); + return Py_BuildValue("OO", weakref, log); + } + """, + argspec='OOO', + arguments=["PyObject* o", "PyObject* weakref", "PyObject* log"], + callfunction="wrap_PyWeakref_ClearRef", + cmpfunc=compare_cleared_weakref, + ) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/check_home_pom.xml b/graalpython/com.oracle.graal.python.test/src/tests/standalone/check_home_pom.xml index 37b5a27ec3..b8ae79cddc 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/check_home_pom.xml +++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/check_home_pom.xml @@ -72,14 +72,14 @@ SOFTWARE. ${env.GRAALPY_VERSION} - - - process-graalpy-resources + + + diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/check_packages_pom.xml b/graalpython/com.oracle.graal.python.test/src/tests/standalone/check_packages_pom.xml index fd3468edcc..9e380b16be 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/check_packages_pom.xml +++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/check_packages_pom.xml @@ -72,16 +72,16 @@ SOFTWARE. ${env.GRAALPY_VERSION} - - - - - process-graalpy-resources + + + + + diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/check_plugin_configuration.xml b/graalpython/com.oracle.graal.python.test/src/tests/standalone/check_plugin_configuration.xml new file mode 100644 index 0000000000..90d0557729 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/check_plugin_configuration.xml @@ -0,0 +1,88 @@ + + + + 4.0.0 + + org.apache.maven.plugin.my.unit + project-check-packages + 1.0-SNAPSHOT + jar + Test MyMojo + + + + org.graalvm.polyglot + python-community + ${env.GRAALPY_VERSION} + pom + + + org.graalvm.python + python-launcher + ${env.GRAALPY_VERSION} + + + + + + + org.graalvm.python + graalpy-maven-plugin + ${env.GRAALPY_VERSION} + + + + process-graalpy-resources + + + + termcolor + + + + + + + + diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_gradle_plugin.py b/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_gradle_plugin.py index 52d95fc704..be30a2d94b 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_gradle_plugin.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_gradle_plugin.py @@ -46,6 +46,10 @@ from tests.standalone import util from tests.standalone.util import TemporaryTestDirectory, Logger +MISSING_FILE_WARNING = "The list of installed Python packages does not match the packages specified in the graalpy-maven-plugin configuration" +PACKAGES_CHANGED_ERROR = "packages and their version constraints in graalpy-maven-plugin configuration are different then previously used to generate the lock file" +VENV_UPTODATE = "Virtual environment is up to date with lock file, skipping install" + def append(file, txt): with open(file, "a") as f: f.write(txt) @@ -92,6 +96,9 @@ def native_image_with_bogus_include(self): def native_image_with_exlude_email(self): pass + def lock_packages_config(self, community, pkgs, lock_file): + pass + def generate_app(self, target_dir): shutil.copytree(self.test_prj_path, target_dir) for root, dirs, files in os.walk(target_dir): @@ -126,15 +133,20 @@ def check_gradle_generated_app(self, community): build_file = os.path.join(target_dir, self.build_file_name) append(build_file, self.packages_termcolor(community)) - gradlew_cmd = util.get_gradle_wrapper(target_dir, self.env) log = Logger() # build + gradlew_cmd = util.get_gradle_wrapper(target_dir, self.env, verbose=False) + cmd = gradlew_cmd + ["build"] out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir, logger=log) util.check_ouput("BUILD SUCCESS", out, logger=log) + util.check_ouput("Virtual filesystem is deployed to default resources directory", out, logger=log) + util.check_ouput("This can cause conflicts if used with other Java libraries that also deploy GraalPy virtual filesystem", out, logger=log) self.check_filelist(target_dir, log) + gradlew_cmd = util.get_gradle_wrapper(target_dir, self.env) + cmd = gradlew_cmd + ["nativeCompile"] out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir, logger=log) util.check_ouput("BUILD SUCCESS", out, logger=log) @@ -179,6 +191,90 @@ def check_gradle_generated_app(self, community): util.check_ouput("hello java", out, logger=log) self.check_filelist(target_dir2, log) + @unittest.skipUnless(util.is_maven_plugin_test_enabled, "ENABLE_MAVEN_PLUGIN_UNITTESTS is not true") + def check_lock_packages(self, community): + with util.TemporaryTestDirectory() as tmpdir: + + target_dir = os.path.join(str(tmpdir), "lock_packages" + self.target_dir_name_sufix()) + self.generate_app(target_dir) + build_file = os.path.join(target_dir, self.build_file_name) + + gradlew_cmd = util.get_gradle_wrapper(target_dir, self.env) + + # start with requests package without version + append(build_file, self.lock_packages_config(pkgs=["requests"], lock_file="test-graalpy.lock", community=True)) + + # build + cmd = gradlew_cmd + ["build"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("pip install", out) + util.check_ouput("BUILD SUCCESS", out) + util.check_ouput(MISSING_FILE_WARNING, out, contains=True) + assert not os.path.exists(os.path.join(target_dir, "test-graalpy.lock")) + + # lock without version + cmd = gradlew_cmd + ["graalpyLockPackages"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out, contains=True) + util.check_ouput(MISSING_FILE_WARNING, out, contains=False) + assert os.path.exists(os.path.join(target_dir, "test-graalpy.lock")) + os.remove(os.path.join(target_dir, "test-graalpy.lock")) + + # lock with correct version + log = Logger() + self.copy_build_files(target_dir) + append(build_file, self.lock_packages_config(pkgs=["requests==2.32.3"], lock_file="test-graalpy.lock", community=True)) + cmd = gradlew_cmd + ["graalpyLockPackages"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out, contains=True) + util.check_ouput(MISSING_FILE_WARNING, out, contains=False) + assert os.path.exists(os.path.join(target_dir, "test-graalpy.lock")) + + # add termcolor and build - fails as it is not part of lock file + log = Logger() + self.copy_build_files(target_dir) + append(build_file, self.lock_packages_config(pkgs=["requests==2.32.3", "termcolor==2.2"], lock_file="test-graalpy.lock", community=True)) + cmd = gradlew_cmd + ["build"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out, contains=False) + util.check_ouput(PACKAGES_CHANGED_ERROR, out) + util.check_ouput(MISSING_FILE_WARNING, out, contains=False) + assert os.path.exists(os.path.join(target_dir, "test-graalpy.lock")) + + # lock with termcolor + log = Logger() + cmd = gradlew_cmd + ["graalpyLockPackages"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out, contains=True) + util.check_ouput(MISSING_FILE_WARNING, out, contains=False) + assert os.path.exists(os.path.join(target_dir, "test-graalpy.lock")) + + # should be able to import requests if installed + util.replace_in_file(os.path.join(target_dir, "src", "main", "java", "org", "example", "GraalPy.java"), + "import hello", + "import requests; import hello") + + # rebuild with lock and exec + cmd = gradlew_cmd + ["build", "run"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out) + util.check_ouput(VENV_UPTODATE, out) + util.check_ouput("hello java", out) + util.check_ouput(MISSING_FILE_WARNING, out, contains=False) + + # run with no packages, only lock file + self.copy_build_files(target_dir) + append(build_file, self.empty_packages()) + + # stop using lock file field and test with default value {project_root}/graalpy.lock + shutil.move(os.path.join(target_dir, "test-graalpy.lock"), os.path.join(target_dir, "graalpy.lock")) + + # clean and rebuild fails + cmd = gradlew_cmd + ["clean", "build", "run"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out, contains=False) + util.check_ouput(MISSING_FILE_WARNING, out, contains=False) + def check_gradle_generated_app_external_resources(self): with TemporaryTestDirectory() as tmpdir: target_dir = os.path.join(str(tmpdir), "generated_gradle_app_external_resources" + self.target_dir_name_sufix()) @@ -234,43 +330,6 @@ def check_gradle_generated_app_external_resources(self): def check_gradle_fail_with_mismatching_graalpy_dep(self): pass # TODO: once the CI job builds enterprise - def check_gradle_gen_launcher_and_venv(self, community): - with TemporaryTestDirectory() as tmpdir: - target_dir = os.path.join(str(tmpdir), "gradle_gen_launcher_and_venv" + self.target_dir_name_sufix()) - self.generate_app(target_dir) - - build_file = os.path.join(target_dir, self.build_file_name) - - gradle_cmd = util.get_gradle_wrapper(target_dir, self.env) - - append(build_file, self.packages_termcolor_ujson(community)) - - cmd = gradle_cmd + ["graalPyResources"] - out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) - util.check_ouput("-m venv", out) - util.check_ouput("-m ensurepip",out) - util.check_ouput("ujson", out) - util.check_ouput("termcolor", out) - - # run again and assert that we do not regenerate the venv - cmd = gradle_cmd + ["graalPyResources"] - out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) - util.check_ouput("-m venv", out, False) - util.check_ouput("-m ensurepip", out, False) - util.check_ouput("ujson", out, False) - util.check_ouput("termcolor", out, False) - - # remove ujson pkg from plugin config and check if unistalled - self.copy_build_files(target_dir) - append(build_file, self.packages_termcolor(community)) - - cmd = gradle_cmd + ["graalPyResources"] - out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) - util.check_ouput("-m venv", out, False) - util.check_ouput("-m ensurepip", out, False) - util.check_ouput("Uninstalling ujson", out) - util.check_ouput("termcolor", out, False) - def check_tagfile(self, home, expected, log=''): with open(os.path.join(home, "tagfile")) as f: lines = f.readlines() @@ -284,7 +343,7 @@ def check_gradle_check_home_warning(self, community): build_file = os.path.join(target_dir, self.build_file_name) gradle_cmd = util.get_gradle_wrapper(target_dir, self.env) - process_resources_cmd = gradle_cmd + ["--stacktrace", "graalPyResources"] + process_resources_cmd = gradle_cmd + ["--stacktrace", "graalPyInstallPackages"] # 1. process-resources with no pythonHome config - no warning printed log = Logger() @@ -362,11 +421,17 @@ def check_gradle_empty_packages(self): append(build_file, self.empty_packages()) gradle_cmd = util.get_gradle_wrapper(target_dir, self.env) - cmd = gradle_cmd + ["graalPyResources"] + cmd = gradle_cmd + ["graalPyInstallPackages"] out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) util.check_ouput("BUILD SUCCESS", out) assert return_code == 0, out + cmd = gradle_cmd + ["graalpyLockPackages"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out, contains=False) + util.check_ouput("In order to run the graalPyLockPackages task there have to be python packages declared in the graalpy-gradle-plugin configuration.", out) + assert not os.path.exists(os.path.join(target_dir, "graalpy.lock")) + def check_gradle_python_resources_dir_deprecation(self): with TemporaryTestDirectory() as tmpdir: @@ -386,7 +451,7 @@ def check_gradle_python_resources_dir_deprecation(self): ''') gradle_cmd = util.get_gradle_wrapper(target_dir, self.env) - cmd = gradle_cmd + ["graalPyResources"] + cmd = gradle_cmd + ["graalPyInstallPackages"] out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) util.check_ouput("Property 'pythonResourcesDirectory' is deprecated and will be removed. Use property 'externalDirectory' instead.", out) assert return_code == 0, out @@ -411,9 +476,9 @@ def check_gradle_python_resources_dir_and_external_dir_error(self): ''') gradle_cmd = util.get_gradle_wrapper(target_dir, self.env) - cmd = gradle_cmd + ["graalPyResources"] + cmd = gradle_cmd + ["graalPyInstallPackages"] out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) - util.check_ouput("Cannot set both 'externalDirectory' and 'resourcesDirectory' at the same time", out) + util.check_ouput("Cannot set both 'externalDirectory' and 'resourceDirectory' at the same time", out) assert return_code != 0, out @@ -478,6 +543,8 @@ def check_gradle_namespaced_vfs(self): app1_gradle_cmd = util.get_gradle_wrapper(app1_dir, self.env) out, return_code = util.run_cmd(app1_gradle_cmd + ['publishToMavenLocal'], self.env, cwd=app1_dir) + util.check_ouput("Virtual filesystem is deployed to default resources directory", out, contains=False) + util.check_ouput("This can cause conflicts if used with other Java libraries that also deploy GraalPy virtual filesystem", out, contains=False) assert return_code == 0, out app2_gradle_cmd = util.get_gradle_wrapper(app2_dir, self.env) @@ -508,12 +575,12 @@ def test_gradle_generated_app(self): self.check_gradle_generated_app(community=True) @unittest.skipUnless(util.is_gradle_plugin_test_enabled, "ENABLE_GRADLE_PLUGIN_UNITTESTS is not true") - def test_gradle_generated_app_external_resources(self): - self.check_gradle_generated_app_external_resources() + def test_gradle_lock_packages(self): + self.check_lock_packages(community=True) @unittest.skipUnless(util.is_gradle_plugin_test_enabled, "ENABLE_GRADLE_PLUGIN_UNITTESTS is not true") - def test_gradle_gen_launcher_and_venv(self): - self.check_gradle_gen_launcher_and_venv(community=True) + def test_gradle_generated_app_external_resources(self): + self.check_gradle_generated_app_external_resources() @unittest.skipUnless(util.is_gradle_plugin_test_enabled, "ENABLE_GRADLE_PLUGIN_UNITTESTS is not true") def test_gradle_check_home_warning(self): @@ -567,6 +634,17 @@ def packages_termcolor(self, community): }} """) + def lock_packages_config(self, community, pkgs, lock_file=None): + lf = f"graalPyLockFile = file(\"{lock_file}\")" if lock_file else "" + packages = "packages = [\"" + "\",\"".join(pkgs) + "\"]" + return textwrap.dedent(f""" + graalPy {{ + {packages} + {lf} + {_community_as_property(community)} + }} + """) + def packages_termcolor_ujson(self, community): return textwrap.dedent(f""" graalPy {{ @@ -681,14 +759,14 @@ def setUpClass(cls): def test_gradle_generated_app(self): self.check_gradle_generated_app(community=True) + @unittest.skipUnless(util.is_gradle_plugin_test_enabled, "ENABLE_GRADLE_PLUGIN_UNITTESTS is not true") + def test_gradle_lock_packages(self): + self.check_lock_packages(community=True) + @unittest.skipUnless(util.is_gradle_plugin_long_running_test_enabled, "ENABLE_GRADLE_PLUGIN_LONG_RUNNING_UNITTESTS is not true") def test_gradle_generated_app_external_resources(self): self.check_gradle_generated_app_external_resources() - @unittest.skipUnless(util.is_gradle_plugin_test_enabled, "ENABLE_GRADLE_PLUGIN_UNITTESTS is not true") - def test_gradle_gen_launcher_and_venv(self): - self.check_gradle_gen_launcher_and_venv(community=True) - @unittest.skipUnless(util.is_gradle_plugin_test_enabled, "ENABLE_GRADLE_PLUGIN_UNITTESTS is not true") def test_gradle_check_home_warning(self): self.check_gradle_check_home_warning(community=True) @@ -732,6 +810,19 @@ def copy_build_files(self, target_dir): def empty_plugin(self, community): return f"graalPy {{ {_community_as_property(community) } }}" + def lock_packages_config(self, community, pkgs, lock_file=None): + lf = f"graalPyLockFile = file(\"{lock_file}\")" if lock_file else "" + packages = "" + for p in pkgs: + packages += f" packages.add(\"{p}\")\n" + return textwrap.dedent(f""" + graalPy {{ + {packages} + {lf} + {_community_as_property(community)} + }} + """) + def packages_termcolor(self, community): return textwrap.dedent(f""" graalPy {{ diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_jbang_integration.py b/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_jbang_integration.py index e9f1e02c8f..03e164bef5 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_jbang_integration.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_jbang_integration.py @@ -1,4 +1,4 @@ -# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -340,8 +340,8 @@ def hello(): out, result = run_cmd(command, cwd=work_dir) self.assertTrue(result == 0, f"Execution failed with code {result}\n command: {command}\n stdout: {out}") - self.assertTrue("Uninstalling ujson" in out, f"Expected text:\nUninstalling ujson") - self.assertFalse("Successfully installed termcolor" in out, f"Did not expect text:\nSuccessfully installed termcolor") + self.assertFalse("ujson" in out, f"Did not expect text:\n ujson") + self.assertTrue("Successfully installed termcolor" in out, f"Did not expect text:\nSuccessfully installed termcolor") self.assertTrue("hello java" in out, f"Expected text:\nhello java\nbut in stdout was:\n{out}") # add ujson in additional PIP comment @@ -401,7 +401,8 @@ def test_no_pkgs_but_resource_dir(self): self.assertTrue(result == 0, f"Execution failed with code {result}\n command: {command}\n stdout: {out}") self.assertFalse("[graalpy jbang integration] python packages" in out, f"Did not expect text:\n[graalpy jbang integration] python packages") self.assertTrue("[graalpy jbang integration] python resources directory: python-resources" in out, f"Expected text:\n[graalpy jbang integration] python resources directory: python-resources") - self.assertTrue("-m ensurepip" in out, f"-m ensurepip") + self.assertFalse("-m ensurepip" in out) + self.assertFalse("pip install" in out) @unittest.skipUnless(is_enabled, "ENABLE_JBANG_INTEGRATION_UNITTESTS is not true") def test_two_resource_dirs(self): diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_maven_plugin.py b/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_maven_plugin.py index 4b2cdb5c04..3b7dc1068b 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_maven_plugin.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_maven_plugin.py @@ -48,6 +48,10 @@ from tests.standalone import util from tests.standalone.util import TemporaryTestDirectory, Logger +MISSING_FILE_WARNING = "The list of installed Python packages does not match the packages specified in the graalpy-maven-plugin configuration." +PACKAGES_CHANGED_ERROR = "but packages and their version constraints in graalpy-maven-plugin configuration are different then previously used to generate the lock file" +VENV_UPTODATE = "Virtual environment is up to date with lock file, skipping install" + class MavenPluginTest(util.BuildToolTestBase): def generate_app(self, tmpdir, target_dir, target_name, pom_template=None, group_id="archetype.it", package="it.pkg"): @@ -80,7 +84,7 @@ def generate_app(self, tmpdir, target_dir, target_name, pom_template=None, group os.makedirs(meta_inf_native_image_dir, exist_ok=True) shutil.copy(os.path.join(os.path.dirname(__file__), "native-image.properties"), os.path.join(meta_inf_native_image_dir, "native-image.properties")) - def check_generated_app(self, use_default_vfs_path, use_utils_pkg=False): + def check_generated_app(self, use_default_vfs_path): with util.TemporaryTestDirectory() as tmpdir: target_name = "generated_app_test" if use_default_vfs_path: @@ -100,21 +104,14 @@ def check_generated_app(self, use_default_vfs_path, use_utils_pkg=False): shutil.move(os.path.join(resources_dir, vfs_prefix), os.path.join(resources_dir, util.DEFAULT_VFS_PREFIX)) vfs_prefix = util.DEFAULT_VFS_PREFIX - if use_utils_pkg: - assert use_default_vfs_path - util.replace_in_file(graalpy_main_src, - "import org.graalvm.python.embedding.GraalPyResources;", - "import org.graalvm.python.embedding.utils.GraalPyResources;") - util.replace_in_file(graalpy_main_src, - "import org.graalvm.python.embedding.VirtualFileSystem;", - "import org.graalvm.python.embedding.utils.VirtualFileSystem;") - mvnw_cmd = util.get_mvn_wrapper(target_dir, self.env) # build cmd = mvnw_cmd + ["package", "-Pnative", "-DmainClass=it.pkg.GraalPy"] out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) util.check_ouput("BUILD SUCCESS", out) + util.check_ouput("Virtual filesystem is deployed to default resources directory", out, contains=use_default_vfs_path) + util.check_ouput("This can cause conflicts if used with other Java libraries that also deploy GraalPy virtual filesystem.", out, contains=use_default_vfs_path) # check fileslist.txt fl_path = os.path.join(target_dir, "target", "classes", vfs_prefix, "fileslist.txt") @@ -148,9 +145,6 @@ def check_generated_app(self, use_default_vfs_path, use_utils_pkg=False): util.check_ouput("BUILD SUCCESS", out) util.check_ouput("hello java", out) - if use_utils_pkg: - return # make that test bit less extensive - #GR-51132 - NoClassDefFoundError when running polyglot app in java mode util.check_ouput("java.lang.NoClassDefFoundError", out, False) @@ -160,12 +154,30 @@ def check_generated_app(self, use_default_vfs_path, use_utils_pkg=False): os.rename(target_dir, target_dir2) mvnw_cmd2 = util.get_mvn_wrapper(target_dir2, self.env) # adding new dep triggers launcher without venv regen - util.replace_in_file(os.path.join(target_dir2, "pom.xml"), "", "\nujson") + util.replace_in_file(os.path.join(target_dir2, "pom.xml"), "", "\nujson\n") cmd = mvnw_cmd2 + ["package", "exec:java", "-Dexec.mainClass=it.pkg.GraalPy"] out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir2) util.check_ouput("BUILD SUCCESS", out) util.check_ouput("Deleting GraalPy venv due to changed launcher path", out) util.check_ouput("hello java", out) + util.check_ouput("not compatible with the current platform", out, contains=False) + + # create fake native files and patch contents file in venv + # to trigger native extension built on different platform warning + venv_dir = os.path.join(target_dir2, "target", "classes", "org.graalvm.python.vfs" if use_default_vfs_path else vfs_prefix, "venv") + for suffix in [".so", ".dylib", ".dll"]: + with open(os.path.join(venv_dir, "nativefile" + suffix), "w") as file: + file.write("test") + cmd = mvnw_cmd2 + ["package"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir2) + util.check_ouput("BUILD SUCCESS", out) + + util.replace_in_file(os.path.join(venv_dir, "contents"), "platform=", "platform=test") + cmd = mvnw_cmd2 + ["exec:java", "-Dexec.mainClass=it.pkg.GraalPy"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir2) + util.check_ouput("BUILD SUCCESS", out) + util.check_ouput("hello java", out) + util.check_ouput("not compatible with the current platform", out) @unittest.skipUnless(util.is_maven_plugin_test_enabled, "ENABLE_MAVEN_PLUGIN_UNITTESTS is not true") def test_generated_app(self): @@ -176,8 +188,87 @@ def test_generated_app_with_default_vfs_path(self): self.check_generated_app(use_default_vfs_path=True) @unittest.skipUnless(util.is_maven_plugin_test_enabled, "ENABLE_MAVEN_PLUGIN_UNITTESTS is not true") - def test_generated_app_utils_pkg(self): - self.check_generated_app(use_default_vfs_path=True, use_utils_pkg=True) + def test_lock_file(self): + with util.TemporaryTestDirectory() as tmpdir: + + target_name = "test_lock_file" + target_dir = os.path.join(str(tmpdir), target_name) + self.generate_app(tmpdir, target_dir, target_name) + + mvnw_cmd = util.get_mvn_wrapper(target_dir, self.env) + # run with java asserts on + if self.env.get("MAVEN_OPTS"): + self.env["MAVEN_OPTS"] = self.env.get("MAVEN_OPTS") + " -ea -esa" + else: + self.env["MAVEN_OPTS"] = "-ea -esa" + + # start with requests package without version + util.replace_in_file(os.path.join(target_dir, "pom.xml"), "termcolor==2.2", "requests") + + # build + cmd = mvnw_cmd + ["package", "-DgraalPyLockFile=test-graalpy.lock"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("pip install", out) + util.check_ouput("BUILD SUCCESS", out) + util.check_ouput(MISSING_FILE_WARNING, out, contains=True) + assert not os.path.exists(os.path.join(target_dir, "test-graalpy.lock")) + + # freeze without version + cmd = mvnw_cmd + ["org.graalvm.python:graalpy-maven-plugin:lock-packages", "-DgraalPyLockFile=test-graalpy.lock"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out, contains=True) + util.check_ouput(MISSING_FILE_WARNING, out, contains=False) + assert os.path.exists(os.path.join(target_dir, "test-graalpy.lock")) + os.remove(os.path.join(target_dir, "test-graalpy.lock")) + + # freeze with correct version + util.replace_in_file(os.path.join(target_dir, "pom.xml"), "requests", "requests==2.32.3") + cmd = mvnw_cmd + ["org.graalvm.python:graalpy-maven-plugin:lock-packages", "-DgraalPyLockFile=test-graalpy.lock"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out, contains=True) + util.check_ouput(MISSING_FILE_WARNING, out, contains=False) + assert os.path.exists(os.path.join(target_dir, "test-graalpy.lock")) + + # add termcolor and build - fails as it is not part of lock file + util.replace_in_file(os.path.join(target_dir, "pom.xml"), "", "termcolor==2.2\n") + cmd = mvnw_cmd + ["package", "-DgraalPyLockFile=test-graalpy.lock"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out, contains=False) + util.check_ouput(PACKAGES_CHANGED_ERROR, out) + util.check_ouput(MISSING_FILE_WARNING, out, contains=False) + assert os.path.exists(os.path.join(target_dir, "test-graalpy.lock")) + + # freeze with termcolor + # stop using lock file system property but test also with field in pom.xml + util.replace_in_file(os.path.join(target_dir, "pom.xml"), "", "\ntest-graalpy.lock") + cmd = mvnw_cmd + ["org.graalvm.python:graalpy-maven-plugin:lock-packages"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out, contains=True) + util.check_ouput(MISSING_FILE_WARNING, out, contains=False) + assert os.path.exists(os.path.join(target_dir, "test-graalpy.lock")) + + # should be able to import requests if installed + util.replace_in_file(os.path.join(target_dir, "src", "main", "java", "it", "pkg", "GraalPy.java"), + "import hello", + "import requests; import hello") + + # rebuild with lock file and exec + cmd = mvnw_cmd + ["package", "exec:java", "-Dexec.mainClass=it.pkg.GraalPy"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out) + util.check_ouput(VENV_UPTODATE, out) + util.check_ouput("hello java", out) + util.check_ouput(MISSING_FILE_WARNING, out, contains=False) + + # disable packages config in pom - run with no packages, only lock file + util.replace_in_file(os.path.join(target_dir, "pom.xml"), "", "") + + # clean and rebuild fails + cmd = mvnw_cmd + ["clean", "package"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out, contains=False) + util.check_ouput(MISSING_FILE_WARNING, out, contains=False) @unittest.skipUnless(util.is_maven_plugin_test_enabled, "ENABLE_MAVEN_PLUGIN_UNITTESTS is not true") def test_generated_app_external_resources(self): @@ -249,41 +340,6 @@ def test_fail_without_graalpy_dep(self): out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) util.check_ouput("Missing GraalPy dependency. Please add to your pom either org.graalvm.polyglot:python-community or org.graalvm.polyglot:python", out) - @unittest.skipUnless(util.is_maven_plugin_test_enabled, "ENABLE_MAVEN_PLUGIN_UNITTESTS is not true") - def test_gen_launcher_and_venv(self): - with util.TemporaryTestDirectory() as tmpdir: - target_name = "gen_launcher_and_venv_test" - target_dir = os.path.join(str(tmpdir), target_name) - pom_template = os.path.join(os.path.dirname(__file__), "prepare_venv_pom.xml") - self.generate_app(tmpdir, target_dir, target_name, pom_template) - - mvnw_cmd = util.get_mvn_wrapper(target_dir, self.env) - - cmd = mvnw_cmd + ["process-resources"] - out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) - util.check_ouput("-m venv", out) - util.check_ouput("-m ensurepip",out) - util.check_ouput("ujson", out) - util.check_ouput("termcolor", out) - - # run again and assert that we do not regenerate the venv - cmd = mvnw_cmd + ["process-resources"] - out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) - util.check_ouput("-m venv", out, False) - util.check_ouput("-m ensurepip", out, False) - util.check_ouput("ujson", out, False) - util.check_ouput("termcolor", out, False) - - # remove ujson pkg from plugin config and check if unistalled - util.replace_in_file(os.path.join(target_dir, "pom.xml"), "ujson", "") - - cmd = mvnw_cmd + ["process-resources"] - out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) - util.check_ouput("-m venv", out, False) - util.check_ouput("-m ensurepip", out, False) - util.check_ouput("Uninstalling ujson", out) - util.check_ouput("termcolor", out, False) - @unittest.skipUnless(util.is_maven_plugin_test_enabled, "ENABLE_MAVEN_PLUGIN_UNITTESTS is not true") def test_check_home_warning(self): with util.TemporaryTestDirectory() as tmpdir: @@ -381,12 +437,24 @@ def test_empty_packages(self): out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) util.check_ouput("BUILD SUCCESS", out) + cmd = mvnw_cmd + ["-X", "org.graalvm.python:graalpy-maven-plugin:lock-packages"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out, contains=False) + util.check_ouput("In order to run the lock-packages goal there have to be python packages declared in the graalpy-maven-plugin configuration", out) + assert not os.path.exists(os.path.join(target_dir, "graalpy.lock")) + util.replace_in_file(os.path.join(target_dir, "pom.xml"), "", " ") cmd = mvnw_cmd + ["process-resources"] out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) util.check_ouput("BUILD SUCCESS", out) + cmd = mvnw_cmd + ["org.graalvm.python:graalpy-maven-plugin:lock-packages"] + out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out, contains=False) + util.check_ouput("In order to run the lock-packages goal there have to be python packages declared in the graalpy-maven-plugin configuration", out) + assert not os.path.exists(os.path.join(target_dir, "graalpy.lock")) + @unittest.skipUnless(util.is_maven_plugin_test_enabled, "ENABLE_MAVEN_PLUGIN_UNITTESTS is not true") def test_python_resources_dir_deprecation(self): with util.TemporaryTestDirectory() as tmpdir: @@ -438,6 +506,33 @@ def test_python_resources_dir_and_external_dir_error(self): util.check_ouput("Cannot use and at the same time", out) + @unittest.skipUnless(util.is_maven_plugin_test_enabled, "ENABLE_MAVEN_PLUGIN_UNITTESTS is not true") + def test_java_home_change(self): + with util.TemporaryTestDirectory() as tmpdir: + target_name = "check_home_warning_test" + target_dir = os.path.join(str(tmpdir), target_name) + self.generate_app(tmpdir, target_dir, target_name) + + mvnw_cmd = util.get_mvn_wrapper(target_dir, self.env) + + # build the app + process_resources_cmd = mvnw_cmd + ["package"] + out, return_code = util.run_cmd(process_resources_cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out) + + # update the generated launcher, so that it looks like it's been generated with different Java path + pyenvcfg = os.path.join(target_dir, 'target', 'pyvenv.cfg') + if os.path.exists(pyenvcfg): + util.replace_in_file(pyenvcfg, os.environ['JAVA_HOME'], '/bogus/java/home') + else: + util.replace_in_file(os.path.join(target_dir, 'target', 'graalpy.sh'), os.environ['JAVA_HOME'], '/bogus/java/home') + + util.replace_in_file(os.path.join(target_dir, 'pom.xml'), 'termcolor==2.2', 'termcolor==2') + process_resources_cmd = mvnw_cmd + ["package"] + out, return_code = util.run_cmd(process_resources_cmd, self.env, cwd=target_dir) + util.check_ouput("BUILD SUCCESS", out) + + # Creates two Java apps from given pom templates, the dependencies between them # must be configured in the pom template(s) def _prepare_multi_project(self, tmpdir, app1_pom_template_name, app2_pom_template_name): diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/util.py b/graalpython/com.oracle.graal.python.test/src/tests/standalone/util.py index f652a66bb6..dddc90bb01 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/util.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/util.py @@ -227,12 +227,15 @@ def get_mvn_wrapper(project_dir, env): check_ouput(MAVEN_VERSION, out) return mvn_cmd -def get_gradle_wrapper(project_dir, env): +def get_gradle_wrapper(project_dir, env, verbose=True): gradle_cmd = [os.path.abspath(os.path.join(project_dir, "gradlew" if 'win32' != sys.platform else "gradlew.bat"))] cmd = gradle_cmd + ["--version"] out, return_code = run_cmd(cmd, env, cwd=project_dir) check_ouput(GRADLE_VERSION, out) - return gradle_cmd + if verbose: + return gradle_cmd + ["-i"] + else: + return gradle_cmd def get_gp(): if "PYTHON_STANDALONE_HOME" not in os.environ: @@ -255,7 +258,8 @@ def print_missing_graalpy_msg(graalpy_home=None): sep="\n") def get_graalvm_version(): - graalvmVersion, _ = run_cmd([get_gp(), "-c", "print(__graalpython__.get_graalvm_version(), end='')"], os.environ.copy()) + if not (graalvmVersion := os.environ.get("GRAAL_VERSION")): + graalvmVersion, _ = run_cmd([get_gp(), "-c", "print(__graalpython__.get_graalvm_version(), end='')"], os.environ.copy()) # when JLine is cannot detect a terminal, it prints logging info graalvmVersion = graalvmVersion.split("\n")[-1] # we never test -dev versions here, we always pretend to use release versions diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_ast.py b/graalpython/com.oracle.graal.python.test/src/tests/test_ast.py index e00a48affb..c925dce6bc 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_ast.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_ast.py @@ -1,4 +1,4 @@ -# Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -181,6 +181,9 @@ def test_unparse_bytes_constant_kind(self): exec(compile(tree, '', 'exec'), vars) self.assertEqual("u'abc'", vars['f'].__annotations__['x']) + def test_parse_unicode(self): + self.assertEqual(ast.parse("𝕦𝕟𝕚𝕔𝕠𝕕𝕖").body[0].value.id, 'unicode') + if __name__ == '__main__': unittest.main() diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_dict.py b/graalpython/com.oracle.graal.python.test/src/tests/test_dict.py index c30e983979..e96723941d 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_dict.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_dict.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -172,6 +172,11 @@ def foo(**kwargs): assert foo(a=5, b=6) == {'a': 1, 'b': 1} + d = dict.fromkeys({'a': 1, 'b': 2, 'c': 3}) + assert len(d) == 3 + assert set(d.keys()) == {'a', 'b', 'c'} + assert set(d.values()) == {None} + def test_init(): d = dict(a=1, b=2, c=3) @@ -1267,3 +1272,22 @@ def test_dict_values_eq(): d1 = {1: 1, 2: 2, 4: 4} assert d1.values() != d1.values() +def test_missing_and_not_implemented(): + class MyDict(dict): + def __missing__(self, key): + return NotImplemented + + d = MyDict() + assert d['bogus_key'] == NotImplemented + +def test_removing_attr_from_economic_map(): + class Test: + pass + + o = Test() + o.foo = 1 + o.__dict__[42] = 10 + del o.foo + + assert "foo" not in o.__dict__ + diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_exception.py b/graalpython/com.oracle.graal.python.test/src/tests/test_exception.py index 81064fb042..ae57e10a2d 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_exception.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_exception.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. # Copyright (C) 1996-2017 Python Software Foundation # # Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -196,6 +196,7 @@ def test_raise_none(self): except TypeError: pass + @unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: bug in comment above") def test_generator(self): def gen(): try: @@ -207,6 +208,7 @@ def gen(): self.assertEqual(next(g), 1) self.assertRaises(ZeroDivisionError, lambda: next(g)) + @unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: bug in comment above") def test_generator_nested(self): def gen(): try: @@ -446,6 +448,7 @@ def foo(): self.assertEqual(e.__context__.__context__.args[0], "first") self.assertIsNone(e.__context__.__context__.__context__) + @unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: bug in comment above") def test_implicit_chaining_generator(self): def gen(): try: @@ -485,6 +488,7 @@ def gen(): self.assertEqual(e.__context__.__context__.args[0], "first") self.assertIsNone(e.__context__.__context__.__context__) + @unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: bug in comment above") def test_implicit_chaining_generator_finally(self): def gen(): try: diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_frame_tests.py b/graalpython/com.oracle.graal.python.test/src/tests/test_frame_tests.py index ba73e333b5..4523cb07bc 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_frame_tests.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_frame_tests.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -36,7 +36,7 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. - +import os import sys @@ -46,59 +46,74 @@ def test_lineno(): assert sys._getframe(0).f_lineno == 47 - -# IMPORTANT: DO NOT MOVE! -def test_nested_lineno(): - def test_nested(): - return sys._getframe(0) - - f = test_nested() - assert f.f_lineno == 53 - -# IMPORTANT: DO NOT MOVE! -def test_nested_lineno_return_loc(): - def test_nested(): - f = sys._getframe(0) - if True: - return f - return None - - f = test_nested() - assert f.f_lineno == 63 - -# IMPORTANT: DO NOT MOVE! -def test_nested_lineno_implicit_return(): - f = None - def test_nested(): - nonlocal f - f = sys._getframe(0) - dummy = 42 - - test_nested() - assert f.f_lineno == 75 - -# IMPORTANT: DO NOT MOVE! -def test_nested_lineno_finally(): - def test_nested(): - try: +if not os.environ.get('BYTECODE_DSL_INTERPRETER'): # Blocked by GR-61955 + # IMPORTANT: DO NOT MOVE! + def test_nested_lineno(): + def test_nested(): return sys._getframe(0) - finally: - dummy = 42 - f = test_nested() - assert f.f_lineno == 86, f.f_lineno + f = test_nested() + assert f.f_lineno == 53 + + # IMPORTANT: DO NOT MOVE! + def test_nested_lineno_return_loc(): + def test_nested(): + f = sys._getframe(0) + if True: + return f + return None + + f = test_nested() + assert f.f_lineno == 63 + + # IMPORTANT: DO NOT MOVE! + def test_nested_lineno_implicit_return(): + f = None + def test_nested(): + nonlocal f + f = sys._getframe(0) + dummy = 42 -# IMPORTANT: DO NOT MOVE! -def test_nested_lineno_multiline_return(): - def test_nested(): - f = sys._getframe(0) - if f: - return ( - f) - return None + test_nested() + assert f.f_lineno == 75 + + # IMPORTANT: DO NOT MOVE! + def test_nested_lineno_finally(): + def test_nested(): + try: + return sys._getframe(0) + finally: + dummy = 42 + + f = test_nested() + assert f.f_lineno == 86, f.f_lineno + + # IMPORTANT: DO NOT MOVE! + def test_nested_lineno_multiline_return(): + def test_nested(): + f = sys._getframe(0) + if f: + return ( + f) + return None + + f = test_nested() + assert f.f_lineno == 96 + + # IMPORTANT: DO NOT MOVE! + def test_nested_lineno_raise(): + f = None + def test_nested(): + nonlocal f + f = sys._getframe(0) + raise ValueError("should happen") + raise ArgumentError("should not happen") + try: + test_nested() + except ValueError as e: + assert "should happen" in str(e) + assert f.f_lineno == 109 - f = test_nested() - assert f.f_lineno == 96 def test_read_and_write_locals(): a = 1 @@ -221,3 +236,13 @@ class Foo: # assert e.__traceback__.tb_frame.f_back.f_code == sys._getframe(0).f_back.f_code # assert e.__traceback__.tb_next.tb_next.tb_frame.f_back.f_code == foo.__code__ # assert e.__traceback__.tb_next.tb_frame.f_back.f_code == test_backref_from_traceback.__code__ + + +def test_clearing_globals(): + global foo, junk + foo = 123 + assert "foo" in globals().keys() + assert "junk" not in globals().keys() + junk = globals().clear() + assert "foo" not in globals().keys() + assert "junk" in globals().keys() diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_generators.py b/graalpython/com.oracle.graal.python.test/src/tests/test_generators.py index 00903cc8df..1e6fbb5112 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_generators.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_generators.py @@ -1,8 +1,9 @@ -# Copyright (c) 2018, 2021, Oracle and/or its affiliates. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. # Copyright (C) 1996-2017 Python Software Foundation # # Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 import sys +import os import unittest @@ -10,6 +11,7 @@ class ExceptionTest(unittest.TestCase): # Tests for the issue #23353: check that the currently handled exception # is correctly saved/restored in PyEval_EvalFrameEx(). + @unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: bug in comment above") def test_except_throw(self): def store_raise_exc_generator(): @@ -47,6 +49,7 @@ def store_raise_exc_generator(): self.assertEqual(sys.exc_info(), (None, None, None)) + @unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: bug in comment above") def test_except_next(self): def gen(): self.assertEqual(sys.exc_info()[0], ValueError) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_int.py b/graalpython/com.oracle.graal.python.test/src/tests/test_int.py index e1b4104d77..625a9a8be9 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_int.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_int.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -42,6 +42,8 @@ import array +from tests.util import assert_raises + BIG_NUMBER = 99999937497465632974931 class _NamedIntConstant(int): @@ -118,6 +120,28 @@ def test_bigint_mul(): assert 99999937497465632974931 * (2**100) == 126764980791447734004805377032945185921379990352429056 +def test_pow(): + assert 2 ** 10 == 1024 + assert type(2 ** -1) is float + assert 2 ** -1 == 0.5 + assert_raises(ValueError, pow, 2, 2, 0) + + assert pow(2, 10, 1) == 0 + assert pow(2, 10, 3) == 1 + assert pow(2, 10, -3) == -2 + + assert 18446744073709551616 ** 2 == 340282366920938463463374607431768211456 + assert type(18446744073709551616 ** -1) is float + assert 18446744073709551616 ** -1 == 5.421010862427522e-20 + assert_raises(OverflowError, pow, 2**80000, -1) + assert_raises(OverflowError, pow, 2**80000, -(2**64)) + assert_raises(ZeroDivisionError, pow, 0, -18446744073709551616) + + assert_raises(ValueError, pow, 18446744073709551616, 2, 0) + assert pow(18446744073709551616, 2, 7) == 4 + assert pow(18446744073709551616, 2, -3) == -2 + + def test_int_from_custom(): class CustomInt4(): def __int__(self): @@ -776,6 +800,7 @@ def test_UnsignedLittleEndian(self): def test_SpecialCases(self): self.assertEqual((0).to_bytes(0, 'big'), b'') + self.assertEqual((-1).to_bytes(0, 'big', signed=True), b'') self.assertEqual((1).to_bytes(5, 'big'), b'\x00\x00\x00\x00\x01') self.assertEqual((0).to_bytes(5, 'big'), b'\x00\x00\x00\x00\x00') self.assertEqual((-1).to_bytes(5, 'big', signed=True), diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_interop.py b/graalpython/com.oracle.graal.python.test/src/tests/test_interop.py index 6ea5c7e6f6..63e26b2579 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_interop.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_interop.py @@ -482,7 +482,7 @@ def test_java_class(self): assert isinstance(l, ArrayList) self.assertEqual(getattr(ArrayList, 'class'), l.getClass()) - with self.assertRaisesRegex(TypeError, "ForeignInstantiable.__call__\(\) got an unexpected keyword argument 'kwarg'"): + with self.assertRaisesRegex(TypeError, "__call__\(\) got an unexpected keyword argument 'kwarg'"): ArrayList(kwarg=42) def test_java_exceptions(self): @@ -771,6 +771,14 @@ def test_java_array(self): assert il == [1, 2, 3] # unchanged + def test_dir(self): + from java.util import ArrayList + + l = ArrayList() + self.assertIn('addAll', dir(l)) # a Java method + self.assertIn('extend', dir(l)) # a Python method + self.assertEqual(sorted(dir(l)), dir(l)) + def test_java_list(self): from java.util import ArrayList @@ -931,6 +939,8 @@ def l(*elements): assert [e for e in reversed(al)] == [3,2,1] assert [e for e in al] == [1,2,3] + # AssertionError: "descriptor requires a 'dict' object but received a 'ForeignDict'" does not match "object.__new__(ForeignDict) is not safe, use ForeignDict.__new__()" + @unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: bug in comment above") def test_java_map(self): from java.util import HashMap h = HashMap() @@ -1051,8 +1061,7 @@ def test_java_map(self): # Because it tries to call ForeignDict.__call__, but ForeignDict is not executable/instantiable, # so it resolves to type.__call__, which cannot create a ForeignDict - with self.assertRaisesRegex(TypeError, "descriptor requires a 'dict' object but received a 'ForeignDict'"): - type(h).fromkeys(['a', 'b'], 42) + self.assertRaises(TypeError, lambda: type(h).fromkeys(['a', 'b'], 42)) def test_java_iterator(self): from java.util import ArrayList, LinkedHashSet diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_isinstance.py b/graalpython/com.oracle.graal.python.test/src/tests/test_isinstance.py index d21d298ec8..f36f510ebf 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_isinstance.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_isinstance.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -271,4 +271,24 @@ def call_isinstance(expected, tpl): called_instancecheck = 0 assert isinstance(expected_other, tpl) is True - assert called_instancecheck == 190 \ No newline at end of file + assert called_instancecheck == 190 + + +def test_instancecheck_and_subclass_returns_not_iplemented(): + class MyMetaType(type): + def __instancecheck__(cls, instance): + return NotImplemented + def __subclasscheck__(cls, instance): + return NotImplemented + + class MyMetaTypeInstance(metaclass=MyMetaType): + pass + + class UnrelatedClass(): + pass + + o = UnrelatedClass + # gives: DeprecationWarning: NotImplemented should not be used in a boolean context + # but should still treat NotImplemented as True + assert isinstance(o, MyMetaTypeInstance) + assert issubclass(UnrelatedClass, MyMetaTypeInstance) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_list.py b/graalpython/com.oracle.graal.python.test/src/tests/test_list.py index a2fefd4970..2ae9a7522d 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_list.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_list.py @@ -966,5 +966,31 @@ def test_clear(self): # self.check_refcounts(o1=0, o2=0, o3=0, o4=0) +def test_eq_side_effects(): + class X: + def __eq__(self,other) : + l1[0] = 42 + l2[0] = 11 + return False + + l1 = [X()] + l2 = [0] + assert l1 > l2 # actually comparing 42 > 11 + assert l1 == [42] + assert l2 == [11] + + + class X: + def __eq__(self,other) : + l1.clear() + return False + + l1 = [X()] + l2 = [0] + assert l1 < l2 # l1 cleared -> is smaller than l2 + assert l1 == [] + assert l2 == [0] + + if __name__ == '__main__': unittest.main() diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_parser.py b/graalpython/com.oracle.graal.python.test/src/tests/test_parser.py index 7d523404e8..ebf0768c2c 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_parser.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_parser.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -268,6 +268,14 @@ def test_invalid_return_statement(): assert_raise_syntax_error("return 10", "'return' outside function") assert_raise_syntax_error("class A: return 10\n", "'return' outside function") +def test_outside_of_loop_errors(): + assert_raise_syntax_error("break", "'break' outside loop") + # TODO: parser gives invalid syntax for this one, but should be: "'break' outside loop" + assert_raise_syntax_error("def bar(): break", "") + assert_raise_syntax_error("continue", "'continue' not properly in loop") + # TODO: parser gives invalid syntax for this one, but should be: "'continue' not properly in loop" + assert_raise_syntax_error("def foo(): continue", "") + def test_mangled_class_property(): class P: diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_patmat.py b/graalpython/com.oracle.graal.python.test/src/tests/test_patmat.py index 5e1bf6c4a4..d1b6efe2a1 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_patmat.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_patmat.py @@ -1,4 +1,4 @@ -# Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -36,11 +36,11 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. - +import os import sys, ast, unittest +import inspect -@unittest.skipIf(sys.version_info.minor < 10, "Requires Python 3.10+") def test_guard(): def f(x, g): match x: @@ -62,7 +62,6 @@ def f(x): assert f(1) == 42 assert f(2) == 0 -@unittest.skipIf(sys.version_info.minor < 10, "Requires Python 3.10+") def test_complex_as_binary_op(): src = """ def f(a): @@ -87,7 +86,6 @@ def f(a): assert f(6+3j) == "match add" assert f(-2-3j) == "match sub" -@unittest.skipIf(sys.version_info.minor < 10, "Requires Python 3.10+") def test_long_mapping(): def f(x): match d: @@ -123,3 +121,145 @@ def test(name): assert test('attr1') == {'dyn_match': 1, 'attr2': 2, 'attr3': 3} assert test('attr2') == {'dyn_match': 2, 'attr1': 1, 'attr3': 3} + +def test_multiple_or_pattern_basic(): + match 0: + case 0 | 1 | 2 | 3 | 4 | 5 as x: + assert x == 0 + + match 3: + case ((0 | 1 | 2) as x) | ((3 | 4 | 5) as x): + assert x == 3 + +def test_sequence_pattern(): + match (1, 2): + case (3, 2): + assert False + + match (1, (2, 2)): + case (3, (2, 2)): + assert False + + match (1, 2): + case (3, q): + assert False + + +def test_multiple_or_pattern_advanced(): + match 4: + case (0 as z) | (1 as z) | (2 as z) | (4 as z) | (77 as z): + assert z == 4 + + match 42: + case (0 as z) | (1 as z): + assert z == 1 + case x: + assert x == 42 + + match 2: + case (0 as z) | (1 as z) | (2 as z): + assert z == 2 + case _: + assert False + + match 1: + case (0 as z) | (1 as z) | (2 as z): + assert z == 1 + case _: + assert False + + match 0: + case (0 as z) | (1 as z) | (2 as z): + assert z == 0 + case _: + assert False + + match (1, 2): + case (w, 2) | (2, w): + assert w == 1 + + +def test_multiple_or_pattern_creates_locals(): + match (1, 2): + case (a, 1) | (a, 2): + assert a == 1 + assert a == 1 + + match [1, 2]: + case [a1, 1] | [a1, 2]: + assert a1 == 1 + assert a1 == 1 + + match (1, 2, 2, 3, 2): + case (1, a, b, 4, c) | (1, a, b, 3, c) | (1, a, b, 2, c): + assert a == 2 + assert b == 2 + assert c == 2 + assert a == 2 + assert b == 2 + assert c == 2 + + match (1, 3, 4, 9): + case ((d, e, f, 7) | (d, e, f, 8) | (d, e, f, 6) | (d, e, f, 9)): + assert d == 1 + assert e == 3 + assert f == 4 + assert d == 1 + assert e == 3 + assert f == 4 + + match (1,2,3,4,5,6,7): + case (0,q,w,e,r,t,y) | (q,w,e,r,t,y,7): + assert q == 1 + assert w == 2 + assert e == 3 + assert r == 4 + assert t == 5 + assert y == 6 + assert q == 1 + assert w == 2 + assert e == 3 + assert r == 4 + assert t == 5 + assert y == 6 + + +class TestErrors(unittest.TestCase): + def assert_syntax_error(self, code: str): + with self.assertRaises(SyntaxError): + compile(inspect.cleandoc(code), "", "exec") + + def test_alternative_patterns_bind_different_names_0(self): + self.assert_syntax_error(""" + match ...: + case "a" | a: + pass + """) + + def test_alternative_patterns_bind_different_names_1(self): + self.assert_syntax_error(""" + match ...: + case [a, [b] | [c] | [d]]: + pass + """) + + def test_multiple_or_same_name(self): + self.assert_syntax_error(""" + match 0: + case x | x: + pass + """) + + def test_multiple_or_wildcard(self): + self.assert_syntax_error(""" + match 0: + case * | 1: + pass + """) + + def test_unbound_local_variable(self): + with self.assertRaises(UnboundLocalError): + match (1, 3): + case (a, 1) | (a, 2): + pass + assert a == 1 \ No newline at end of file diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_pdb.py b/graalpython/com.oracle.graal.python.test/src/tests/test_pdb.py index ec6014757b..f66661927d 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_pdb.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_pdb.py @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,8 +37,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import os import doctest import sys +import unittest # Copied from test_doctest @@ -68,6 +70,7 @@ def __exit__(self, *exc): sys.settrace(self.orig_trace) +@unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: FrameSlotTypeException with reparsing") def doctest_pdb_locals(): """ Test that locals get synced after breakpoint @@ -98,6 +101,7 @@ def doctest_pdb_locals(): """ +@unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: FrameSlotTypeException with reparsing") def doctest_pdb_locals_generator(): """ Test that locals get synced after breakpoint in a generator @@ -128,6 +132,7 @@ def doctest_pdb_locals_generator(): """ +@unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: FrameSlotTypeException with reparsing") def doctest_pdb_locals_sync_back(): """ Test that locals set by debugger get propagated back into the frame. @@ -153,5 +158,6 @@ def doctest_pdb_locals_sync_back(): """ +@unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: FrameSlotTypeException with reparsing") def test_run_doctests(): doctest.testmod(sys.modules[__name__], raise_on_error=True) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_posix.py b/graalpython/com.oracle.graal.python.test/src/tests/test_posix.py index 934c2edcdb..b84ffd29b8 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_posix.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_posix.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -879,7 +879,6 @@ def test_sysconf_names(self): self.assertIn('SC_CLK_TCK', os.sysconf_names) def test_sysconf(self): - self.assertGreaterEqual(os.sysconf('SC_CLK_TCK'), 0) with self.assertRaisesRegex(TypeError, 'strings or integers'): os.sysconf(object()) with self.assertRaisesRegex(ValueError, 'unrecognized'): @@ -892,6 +891,17 @@ def test_sysconf(self): else: assert False + # constants taken from POSIX where defined + self.assertGreaterEqual(os.sysconf('SC_ARG_MAX'), 4096) + self.assertGreaterEqual(os.sysconf('SC_CHILD_MAX'), 25) + self.assertGreaterEqual(os.sysconf('SC_LOGIN_NAME_MAX'), 9) + self.assertGreaterEqual(os.sysconf('SC_CLK_TCK'), 0) + self.assertGreaterEqual(os.sysconf('SC_OPEN_MAX'), 20) + self.assertGreaterEqual(os.sysconf('SC_PAGESIZE'), 1) + os.sysconf('SC_SEM_NSEMS_MAX') # returns -1 on my linux box, just check it's there + self.assertGreaterEqual(os.sysconf('SC_PHYS_PAGES'), 1) + self.assertGreaterEqual(os.sysconf('SC_NPROCESSORS_CONF'), 1) + if __name__ == '__main__': unittest.main() diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_repl.py b/graalpython/com.oracle.graal.python.test/src/tests/test_repl.py index 53dab8d43f..457f206f0f 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_repl.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_repl.py @@ -1,4 +1,4 @@ -# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -39,6 +39,7 @@ import sys import platform +import unittest if (sys.platform != 'win32' and (sys.platform != 'linux' or platform.machine() != 'aarch64')) and (sys.implementation.name != 'graalpy' or __graalpython__.posix_module_backend() != 'java'): import os @@ -49,7 +50,23 @@ import termios from textwrap import dedent + # The terminal tests can be flaky + def autoretry(fn): + def decorated(*args, **kwargs): + retries = 3 + while retries: + try: + fn(*args, **kwargs) + return + except Exception: + retries -= 1 + print("Retrying test") + continue + fn(*args, **kwargs) + return decorated + + @autoretry def validate_repl(stdin, python_args=(), ignore_preamble=True): env = os.environ.copy() env['TERM'] = 'ansi' @@ -152,6 +169,7 @@ def test_continuation(): ''')) + @unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: vs in traceback") def test_exceptions(): validate_repl(dedent("""\ >>> 1 / 0 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_slice.py b/graalpython/com.oracle.graal.python.test/src/tests/test_slice.py index acc0cbe28b..7ce131a8d4 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_slice.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_slice.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2022, Oracle and/or its affiliates. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. # Copyright (c) 2013, Regents of the University of California # # All rights reserved. @@ -202,3 +202,35 @@ def test_slice_eq(): assert slice(None, 12345, 10) == slice(None, 12345, 10) assert slice(1, 10000, 10) != slice(None, 10000, 10) assert slice(2, 10000, 10) != slice(2, 10000, 1) + +def test_slice_cmp(): + assert slice(1,2) < slice(2,3,1) + assert slice(2,3,1) > slice(1,2) + assert slice(1,2) <= slice(2,3,1) + assert slice(2,3,1) >= slice(1,2) + assert slice(1, 1, 1.1) < slice(1, 1, 1.2) + assert slice(1, 2.5, 1.1) > slice(1, 0.5, 1.2) + assert slice(1.25, 2.5, 1.1) < slice(42.5, 0.5, 1.2) + assert slice(1, None, 1.1) < slice(1, None, 42.5) + assert slice(1, None, 25.5) > slice(1, None, 1.14) + + try: + slice(1,2) < slice(1,2,1) + except TypeError as e: + assert "'<' not supported between instances of 'NoneType' and 'int'" in str(e) + else: + assert False + + class MyC: + def __eq__(self, other): return False + def __lt__(self, other): return True + def __gt__(self, other): return False + def __le__(self, other): return True + + assert slice(1, MyC()) < slice(1, MyC()) + assert not slice(1, MyC()) > slice(1, MyC()) + assert slice(1, MyC()) <= slice(1, MyC()) + assert slice(1, MyC()) >= slice(1, MyC()) + + interned = slice(1, MyC()) + assert not (interned < interned) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_ssl_java_integration.py b/graalpython/com.oracle.graal.python.test/src/tests/test_ssl_java_integration.py index 32a150e911..38da878874 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_ssl_java_integration.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_ssl_java_integration.py @@ -63,4 +63,9 @@ def test_load_default_verify_keystore(): """) env = os.environ.copy() env['JAVA_TOOL_OPTIONS'] = f"-Djavax.net.ssl.trustStore={curdir}/ssldata/signing_keystore.jks" - subprocess.run([sys.executable, '-c', src], env=env, check=True) + + args = [] + if __graalpython__.is_bytecode_dsl_interpreter: + args += ['--vm.Dpython.EnableBytecodeDSLInterpreter=true'] + + subprocess.run([sys.executable, *args, '-c', src], env=env, check=True) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_startup.py b/graalpython/com.oracle.graal.python.test/src/tests/test_startup.py new file mode 100644 index 0000000000..b17986a53c --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_startup.py @@ -0,0 +1,90 @@ +# Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import unittest +import sys +import re +import subprocess +import platform + +# Both lists should remain as small as possible to avoid adding overhead to startup +expected_nosite_startup_modules = [ + '_frozen_importlib', + '_frozen_importlib_external', + 'builtins', + '__graalpython__', + '_weakref', + 'unicodedata', + '_sre', + '_sysconfig', + 'java', + 'pip_hook', +] + (['_nt'] if platform.system() == 'Windows' else []) + +expected_full_startup_modules = expected_nosite_startup_modules + [ + '_abc', + 'types', + '_weakrefset', + '_py_abc', + 'abc', + 'stat', + '_collections_abc', + 'genericpath', + *(['_winapi', 'ntpath'] if platform.system() == 'Windows' else ['posixpath']), + 'os', + '_sitebuiltins', + '_io', + 'io', + 'site', +] + +class StartupTests(unittest.TestCase): + @unittest.skipUnless(sys.implementation.name == 'graalpy', "GraalPy-specific test") + def test_startup_nosite(self): + result = subprocess.check_output([sys.executable, '--log.level=FINE', '-S', '-v', '-c', 'print("Hello")'], stderr=subprocess.STDOUT, text=True) + assert 'Hello' in result + imports = re.findall("import '(\S+)'", result) + self.assertEqual(expected_nosite_startup_modules, imports) + + @unittest.skipUnless(sys.implementation.name == 'graalpy', "GraalPy-specific test") + def test_startup_full(self): + result = subprocess.check_output([sys.executable, '--log.level=FINE', '-s', '-v', '-c', 'print("Hello")'], stderr=subprocess.STDOUT, text=True) + assert 'Hello' in result + imports = re.findall("import '(\S+)'", result) + self.assertEqual(expected_full_startup_modules, imports) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_string.py b/graalpython/com.oracle.graal.python.test/src/tests/test_string.py index 641f3f8f49..1eda246689 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_string.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_string.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. # Copyright (C) 1996-2017 Python Software Foundation # # Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -1195,3 +1195,12 @@ class S(str): pass def test_literal_with_nonbmp_and_escapes(): # Check that escape processing didn't accidentally break the emoji into surrogates assert len("\\🤗\\") == 3 + + +def test_str_from_mmap(): + import mmap + size = len("GraalPy") + with mmap.mmap(-1, size) as mm: + mm.write(b"GraalPy") + mm.seek(0) + assert str(mm, encoding='utf-8') == 'GraalPy' diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_structseq.py b/graalpython/com.oracle.graal.python.test/src/tests/test_structseq.py index 927b471c34..fe8d6e43b8 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_structseq.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_structseq.py @@ -1,4 +1,4 @@ -# Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_sum.py b/graalpython/com.oracle.graal.python.test/src/tests/test_sum.py index 4e71f08ae8..f46869c541 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_sum.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_sum.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -76,3 +76,39 @@ def test_iterator(): def test_basics(): assert sum([[1, 2], [3, 4]], []) == [1, 2, 3, 4] assert_raises(TypeError, sum, [1,2,3], None) + + +def test_specializations(): + # test sumIntIterator + assert sum([1, 2, 3]) == 6 + assert sum([1, 2, 3], 2) == 8 + assert sum([1, 2 ** 64, 3]) == 2 ** 64 + 4 + assert sum([2 ** 30, 2 ** 30]) == 2 ** 31 + # test sumLongIterator + assert sum([2 ** 32, 2 ** 32]) == 2 ** 33 + assert sum([2 ** 31, -(2 ** 30)]) == 2 ** 30 + assert sum([2 ** 62, 2 ** 62]) == 2 ** 63 + # test sumDoubleIterator + assert sum([1.0, 2.0, 3.1]) == 6.1 + assert sum([2.1], 1.0) == 3.1 + assert sum([2.1], 1) == 3.1 + assert sum([], 2.1) == 2.1 + l = [2.0] + del l[0] # To obtain an empty list with double storage + assert sum(l, 1) == 1 + assert type(sum(l, 1)) is int + # sumGeneric + l = ["a", 1, 2] + del l[0] # To obtain a list of integers with object storage + assert sum(l) == 3 + assert sum(l, 1) == 4 + l = ["a", 1.0, 2.1] + del l[0] # To obtain a list of doubles with object storage + assert sum(l) == 3.1 + assert sum(l, 1) == 4.1 + assert sum([1, 2.1]) == 3.1 + assert sum([1, 2.1], 1) == 4.1 + assert sum([2.1, 1]) == 3.1 + assert sum([2.1, 1], 1.0) == 4.1 + assert sum([], 1) == 1 + assert type(sum([], 1)) is int diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_sys_settrace.py b/graalpython/com.oracle.graal.python.test/src/tests/test_sys_settrace.py index 1216780454..dab08b66ac 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_sys_settrace.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_sys_settrace.py @@ -1,4 +1,4 @@ -# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,6 +37,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import os import unittest import difflib import sys @@ -160,6 +161,7 @@ def test_case(self): return test_case +@unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: FrameSlotTypeException with reparsing") class TraceTests(unittest.TestCase): def trace(self, frame, event, arg): code = frame.f_code diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_threading.py b/graalpython/com.oracle.graal.python.test/src/tests/test_threading.py new file mode 100644 index 0000000000..854a14d7d2 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_threading.py @@ -0,0 +1,62 @@ +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +def test_stuck_thread(): + import sys + import subprocess + + if sys.implementation.name == 'graalpy' and __graalpython__.posix_module_backend() == 'java': + return + if sys.platform == 'win32': + return + + output = subprocess.check_output( + [ + sys.executable, + '-c', + """ +import threading +import select +threading.Thread(target=lambda: select.select([2], [], [])).start() +del threading._shutdown + """ + ] + ) + assert not output, "No output expected" diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_traceback.py b/graalpython/com.oracle.graal.python.test/src/tests/test_traceback.py index b5c6c086f9..2bb294e41e 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_traceback.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_traceback.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -36,8 +36,9 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. - +import os import sys +import unittest def assert_raises(err, fn, *args, **kwargs): @@ -103,6 +104,7 @@ def test(): ) +@unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: correct generator tracebacks") def test_basic_traceback_generator(): def foo(): yield 1 @@ -139,6 +141,7 @@ def reraise(): ) +@unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: bug in comment above") def test_reraise_direct_generator(): def reraise(): try: @@ -398,6 +401,7 @@ def reraise_from_finally(): ) +@unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: bug in comment above") def test_finally_generator(): def test(): try: @@ -422,6 +426,7 @@ def test(): ) +@unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: bug in comment above") def test_reraise_from_finally_generator(): def reraise_from_finally(): try: @@ -486,6 +491,7 @@ def test(): ) +@unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: correct generator tracebacks") def test_generator_throw_existing(): try: raise OverflowError @@ -508,6 +514,7 @@ def test(): ) +@unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: correct generator tracebacks") def test_generator_throw_with_traceback(): try: raise NameError diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_venv.py b/graalpython/com.oracle.graal.python.test/src/tests/test_venv.py index 40dd495b05..6fed074ce1 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_venv.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_venv.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -83,6 +83,7 @@ def test_venv_launcher(self): assert f"Hello {tmpfile}" in out, out assert f'Original "{sys.executable}"' in out, out + @unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: issue with passing Bytecode DSL flag to subprocesses") def test_create_and_use_basic_venv(self): run = None run_output = '' @@ -97,6 +98,7 @@ def test_create_and_use_basic_venv(self): if sys.platform != 'win32': assert self.env_dir in run, run + @unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: issue with passing Bytecode DSL flag to subprocesses") def test_create_and_use_venv_with_pip(self): run = None msg = '' diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_yield_from.py b/graalpython/com.oracle.graal.python.test/src/tests/test_yield_from.py index f57f6aa8c3..0b0799923b 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_yield_from.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_yield_from.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2021, Oracle and/or its affiliates. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. # Copyright (C) 1996-2017 Python Software Foundation # # Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -12,6 +12,7 @@ import unittest import sys +import os class TestPEP380Operation(unittest.TestCase): """ @@ -975,6 +976,7 @@ def g(): # for stack in spam(eggs(gen())): # self.assertTrue('spam' in stack and 'eggs' in stack) + @unittest.skipIf(os.environ.get('BYTECODE_DSL_INTERPRETER'), "TODO: bug in comment above") def test_custom_iterator_return(self): # See issue #15568 class MyIter: diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_asyncgen.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_asyncgen.txt index dc6c580697..e808fd4886 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_asyncgen.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_asyncgen.txt @@ -1,6 +1,8 @@ test.test_asyncgen.AsyncGenAsyncioTest.test_aiter_bad_args @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_asyncgen.AsyncGenAsyncioTest.test_aiter_idempotent @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_asyncgen.AsyncGenAsyncioTest.test_anext_bad_args @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 +test.test_asyncgen.AsyncGenAsyncioTest.test_anext_return_generator @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 +test.test_asyncgen.AsyncGenAsyncioTest.test_anext_return_iterator @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_aclose_after_exhaustion @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_aclose_compatible_with_get_stack @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_aclose_twice_with_different_coros @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_asyncio.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_asyncio.txt index ecc93e08b7..be43c5a205 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_asyncio.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_asyncio.txt @@ -620,6 +620,8 @@ test.test_asyncio.test_ssl.TestSSL.test_create_server_ssl_1 @ darwin-arm64,darwi test.test_asyncio.test_ssl.TestSSL.test_create_server_ssl_over_ssl @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_asyncio.test_ssl.TestSSL.test_flush_before_shutdown @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_asyncio.test_ssl.TestSSL.test_shutdown_cleanly @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 +# transiently fails +!test.test_asyncio.test_ssl.TestSSL.test_shutdown_timeout_handler_leak test.test_asyncio.test_ssl.TestSSL.test_shutdown_timeout_handler_not_set @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_asyncio.test_ssl.TestSSL.test_ssl_connect_accepted_socket @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_asyncio.test_ssl.TestSSL.test_ssl_handshake_connection_lost @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_capi.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_capi.txt index ee94af6946..215d6591c4 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_capi.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_capi.txt @@ -79,6 +79,7 @@ test.test_capi.test_misc.CAPITest.test_heaptype_with_dict @ darwin-arm64,darwin- test.test_capi.test_misc.CAPITest.test_heaptype_with_negative_dict @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_capi.test_misc.CAPITest.test_heaptype_with_setattro @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_capi.test_misc.CAPITest.test_instancemethod @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 +test.test_capi.test_misc.CAPITest.test_mapping_has_key @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_capi.test_misc.CAPITest.test_mapping_keys_values_items @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_capi.test_misc.CAPITest.test_mapping_keys_values_items_bad_arg @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_capi.test_misc.CAPITest.test_memoryview_from_NULL_pointer @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 @@ -125,6 +126,7 @@ test.test_capi.test_misc.Test_testcapi.test_long_as_unsigned_long_long_mask @ da test.test_capi.test_misc.Test_testcapi.test_long_long_and_overflow @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_capi.test_misc.Test_testcapi.test_long_numbits @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_capi.test_misc.Test_testcapi.test_longlong_api @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_mapping_has_key_string @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_capi.test_misc.Test_testcapi.test_py_is_funcs @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_capi.test_misc.Test_testcapi.test_py_is_macros @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_capi.test_misc.Test_testcapi.test_pymem_alloc0 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_cmd_line.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_cmd_line.txt index e53c259b34..9d65f170ce 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_cmd_line.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_cmd_line.txt @@ -21,4 +21,5 @@ test.test_cmd_line.CmdLineTest.test_unbuffered_input @ darwin-arm64,darwin-x86_6 test.test_cmd_line.CmdLineTest.test_unbuffered_output @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_cmd_line.CmdLineTest.test_unmached_quote @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_cmd_line.CmdLineTest.test_verbose @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_cmd_line.CmdLineTest.test_version @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_cmd_line.IgnoreEnvironmentTest.test_ignore_PYTHONPATH @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_concurrent_futures.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_concurrent_futures.txt index faa6b1685b..cdfa1b0505 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_concurrent_futures.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_concurrent_futures.txt @@ -68,7 +68,7 @@ test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTe test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_context_manager_shutdown @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 # Transiently times out GR-52666 !test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_del_shutdown -test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_hang_gh94440 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 +!test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_hang_gh94440 test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_hang_issue12364 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_processes_terminate @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_run_after_shutdown @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_ctypes.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_ctypes.txt index 856a251ad8..d57dc4de19 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_ctypes.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_ctypes.txt @@ -218,6 +218,7 @@ ctypes.test.test_struct_fields.StructFieldsTestCase.test_1_B @ darwin-arm64,darw ctypes.test.test_struct_fields.StructFieldsTestCase.test_2 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 ctypes.test.test_struct_fields.StructFieldsTestCase.test_3 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 ctypes.test.test_struct_fields.StructFieldsTestCase.test_4 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 +ctypes.test.test_struct_fields.StructFieldsTestCase.test_6 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 ctypes.test.test_struct_fields.StructFieldsTestCase.test___get__ @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 ctypes.test.test_struct_fields.StructFieldsTestCase.test___set__ @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 ctypes.test.test_structures.PointerMemberTestCase.test @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_descr.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_descr.txt index 8f3b9670b8..0e35caca5c 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_descr.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_descr.txt @@ -3,6 +3,7 @@ test.test_descr.ClassPropertiesAndMethods.test_abstractmethods @ darwin-arm64,da test.test_descr.ClassPropertiesAndMethods.test_altmro @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_descr.ClassPropertiesAndMethods.test_assign_slice @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_descr.ClassPropertiesAndMethods.test_attr_raise_through_property @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_descr.ClassPropertiesAndMethods.test_bad_new @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_descr.ClassPropertiesAndMethods.test_basic_inheritance @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_descr.ClassPropertiesAndMethods.test_binary_operator_override @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_descr.ClassPropertiesAndMethods.test_bound_method_repr @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 @@ -34,6 +35,7 @@ test.test_descr.ClassPropertiesAndMethods.test_hash_inheritance @ darwin-arm64,d test.test_descr.ClassPropertiesAndMethods.test_imul_bug @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_descr.ClassPropertiesAndMethods.test_init @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_descr.ClassPropertiesAndMethods.test_ipow @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_descr.ClassPropertiesAndMethods.test_ipow_exception_text @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_descr.ClassPropertiesAndMethods.test_ipow_returns_not_implemented @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_descr.ClassPropertiesAndMethods.test_isinst_isclass @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_descr.ClassPropertiesAndMethods.test_keyword_arguments @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 @@ -71,6 +73,7 @@ test.test_descr.ClassPropertiesAndMethods.test_qualname_dict @ darwin-arm64,darw test.test_descr.ClassPropertiesAndMethods.test_recursive_call @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_descr.ClassPropertiesAndMethods.test_repr_as_str @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_descr.ClassPropertiesAndMethods.test_repr_with_module_str_subclass @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_descr.ClassPropertiesAndMethods.test_restored_object_new @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_descr.ClassPropertiesAndMethods.test_rich_comparisons @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_descr.ClassPropertiesAndMethods.test_rmul @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_descr.ClassPropertiesAndMethods.test_set_and_no_get @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_distutils.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_distutils.txt index 19b1141ec4..68a6b0dc32 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_distutils.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_distutils.txt @@ -31,7 +31,9 @@ distutils.tests.test_build_clib.BuildCLibTestCase.test_get_source_files @ darwin distutils.tests.test_build_clib.BuildCLibTestCase.test_run @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 distutils.tests.test_build_ext.BuildExtTestCase.test_check_extensions_list @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 distutils.tests.test_build_ext.BuildExtTestCase.test_compiler_option @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +distutils.tests.test_build_ext.BuildExtTestCase.test_deployment_target_default @ darwin-arm64,darwin-x86_64 distutils.tests.test_build_ext.BuildExtTestCase.test_deployment_target_higher_ok @ darwin-arm64,darwin-x86_64 +distutils.tests.test_build_ext.BuildExtTestCase.test_deployment_target_too_low @ darwin-arm64,darwin-x86_64 distutils.tests.test_build_ext.BuildExtTestCase.test_ext_fullpath @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 distutils.tests.test_build_ext.BuildExtTestCase.test_finalize_options @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 distutils.tests.test_build_ext.BuildExtTestCase.test_get_outputs @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 @@ -42,7 +44,9 @@ distutils.tests.test_build_ext.BuildExtTestCase.test_unicode_module_names @ darw distutils.tests.test_build_ext.BuildExtTestCase.test_user_site @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_check_extensions_list @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_compiler_option @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_deployment_target_default @ darwin-arm64,darwin-x86_64 distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_deployment_target_higher_ok @ darwin-arm64,darwin-x86_64 +distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_deployment_target_too_low @ darwin-arm64,darwin-x86_64 distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_ext_fullpath @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_finalize_options @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_get_outputs @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_exceptions.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_exceptions.txt index e7e3f45312..434a95a1f8 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_exceptions.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_exceptions.txt @@ -1,5 +1,9 @@ +test.test_exceptions.AttributeErrorTests.test_attribute_error_with_bad_name @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_exceptions.AttributeErrorTests.test_attribute_error_with_failing_dict @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_exceptions.AttributeErrorTests.test_attributes @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_exceptions.AttributeErrorTests.test_getattr_error_bad_suggestions_do_not_trigger_for_small_names @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_exceptions.AttributeErrorTests.test_getattr_has_name_and_obj @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_exceptions.AttributeErrorTests.test_getattr_has_name_and_obj_for_method @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_exceptions.AttributeErrorTests.test_getattr_suggestions_do_not_trigger_for_big_dicts @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_exceptions.AttributeErrorTests.test_getattr_suggestions_do_not_trigger_for_long_attributes @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_exceptions.AttributeErrorTests.test_getattr_suggestions_for_same_name @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_getpass.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_getpass.txt index 5f849f2bbf..582a4ea880 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_getpass.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_getpass.txt @@ -7,6 +7,8 @@ test.test_getpass.GetpassRawinputTest.test_trims_trailing_newline @ darwin-arm64 test.test_getpass.GetpassRawinputTest.test_uses_stderr_as_default @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_getpass.GetpassRawinputTest.test_uses_stdin_as_default_input @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_getpass.GetpassRawinputTest.test_uses_stdin_as_different_locale @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_getpass.UnixGetpassTest.test_falls_back_to_fallback_if_termios_raises @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_getpass.UnixGetpassTest.test_falls_back_to_stdin @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 +test.test_getpass.UnixGetpassTest.test_flushes_stream_after_input @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_getpass.UnixGetpassTest.test_resets_termios @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_getpass.UnixGetpassTest.test_uses_tty_directly @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_inspect.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_inspect.txt index 9da002c392..571f2206b1 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_inspect.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_inspect.txt @@ -160,6 +160,7 @@ test.test_inspect.test_inspect.TestPredicates.test_get_slot_members @ darwin-arm test.test_inspect.test_inspect.TestPredicates.test_isabstract @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_inspect.test_inspect.TestPredicates.test_isabstract_during_init_subclass @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_inspect.test_inspect.TestPredicates.test_isclass @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_inspect.test_inspect.TestPredicates.test_iscoroutine @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_inspect.test_inspect.TestPredicates.test_isroutine @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_inspect.test_inspect.TestReload.test_getsource_reload @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_inspect.test_inspect.TestRetrievingSourceCode.test_cleandoc @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_int.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_int.txt index 93b0c35ee7..e91b5f29ae 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_int.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_int.txt @@ -1,6 +1,6 @@ # Transiently fails because it's dependent on timings !test.test_int.IntStrDigitLimitsTests.test_denial_of_service_prevented_int_to_str @ darwin-arm64,linux-aarch64,linux-x86_64 -test.test_int.IntStrDigitLimitsTests.test_denial_of_service_prevented_str_to_int @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +!test.test_int.IntStrDigitLimitsTests.test_denial_of_service_prevented_str_to_int @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_int.IntStrDigitLimitsTests.test_disabled_limit @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_int.IntStrDigitLimitsTests.test_int_from_other_bases @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_int.IntStrDigitLimitsTests.test_max_str_digits @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 @@ -10,7 +10,7 @@ test.test_int.IntStrDigitLimitsTests.test_sign_not_counted @ darwin-arm64,darwin test.test_int.IntStrDigitLimitsTests.test_underscores_ignored @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 # Transiently fails because it's dependent on timings !test.test_int.IntSubclassStrDigitLimitsTests.test_denial_of_service_prevented_int_to_str @ darwin-arm64,linux-aarch64,linux-x86_64 -test.test_int.IntSubclassStrDigitLimitsTests.test_denial_of_service_prevented_str_to_int @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +!test.test_int.IntSubclassStrDigitLimitsTests.test_denial_of_service_prevented_str_to_int @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_int.IntSubclassStrDigitLimitsTests.test_disabled_limit @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_int.IntSubclassStrDigitLimitsTests.test_int_from_other_bases @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_int.IntSubclassStrDigitLimitsTests.test_max_str_digits @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_isinstance.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_isinstance.txt index f94fbaf6de..135a39a8d3 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_isinstance.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_isinstance.txt @@ -5,6 +5,7 @@ test.test_isinstance.TestIsInstanceExceptions.test_isinstance_dont_mask_non_attr test.test_isinstance.TestIsInstanceExceptions.test_mask_attribute_error @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_isinstance.TestIsInstanceIsSubclass.test_infinite_cycle_in_bases @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_isinstance.TestIsInstanceIsSubclass.test_infinite_recursion_in_bases @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_isinstance.TestIsInstanceIsSubclass.test_infinite_recursion_via_bases_tuple @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_isinstance.TestIsInstanceIsSubclass.test_infinitely_many_bases @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_isinstance.TestIsInstanceIsSubclass.test_isinstance_abstract @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_isinstance.TestIsInstanceIsSubclass.test_isinstance_normal @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_itertools.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_itertools.txt index b3ac95e1c7..f92ed2f9e1 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_itertools.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_itertools.txt @@ -31,6 +31,7 @@ test.test_itertools.TestBasicOps.test_islice @ darwin-arm64,darwin-x86_64,linux- test.test_itertools.TestBasicOps.test_map @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_itertools.TestBasicOps.test_pairwise @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_itertools.TestBasicOps.test_pairwise_reenter @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_itertools.TestBasicOps.test_pairwise_reenter2 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_itertools.TestBasicOps.test_permutations @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_itertools.TestBasicOps.test_product @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_itertools.TestBasicOps.test_product_issue_25021 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_lib2to3.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_lib2to3.txt index 0e1ebd6da2..80a0d82a66 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_lib2to3.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_lib2to3.txt @@ -1,4 +1,4 @@ -lib2to3.tests.test_all_fixers.Test_all.test_all_project_files @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 +lib2to3.tests.test_all_fixers.Test_all.test_all_project_files @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 lib2to3.tests.test_fixers.Test_apply.test_1 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 lib2to3.tests.test_fixers.Test_apply.test_2 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 lib2to3.tests.test_fixers.Test_apply.test_3 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 @@ -609,7 +609,7 @@ lib2to3.tests.test_pytree.TestPatterns.test_basic_patterns @ darwin-arm64,darwin lib2to3.tests.test_pytree.TestPatterns.test_generate_matches @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 lib2to3.tests.test_pytree.TestPatterns.test_has_key_example @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 lib2to3.tests.test_pytree.TestPatterns.test_wildcard @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 -lib2to3.tests.test_refactor.TestRefactoringTool.test_bom @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_bom @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 lib2to3.tests.test_refactor.TestRefactoringTool.test_crlf_newlines @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 lib2to3.tests.test_refactor.TestRefactoringTool.test_crlf_unchanged @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 lib2to3.tests.test_refactor.TestRefactoringTool.test_detect_future_features @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_mmap.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_mmap.txt index 40372a8428..2370950aa3 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_mmap.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_mmap.txt @@ -1,7 +1,7 @@ test.test_mmap.LargeMmapTests.test_large_offset @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_mmap.MmapTests.test_anonymous @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_mmap.MmapTests.test_bad_file_desc @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 -test.test_mmap.MmapTests.test_basic @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 +test.test_mmap.MmapTests.test_basic @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_mmap.MmapTests.test_concat_repeat_exception @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_mmap.MmapTests.test_context_manager @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_mmap.MmapTests.test_context_manager_exception @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_multiprocessing_spawn.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_multiprocessing_spawn.txt index 544fab8935..83747affb1 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_multiprocessing_spawn.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_multiprocessing_spawn.txt @@ -199,6 +199,8 @@ test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_map_chunks test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_map_no_failfast @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_starmap @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_starmap_async @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 +# transiently fails +!test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_terminate test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_traceback @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_multiprocessing_spawn.test_threads.WithThreadsTestProcess.test_active_children @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_multiprocessing_spawn.test_threads.WithThreadsTestProcess.test_args_argument @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_pathlib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_pathlib.txt index e9c42657d6..6e4258d86c 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_pathlib.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_pathlib.txt @@ -375,6 +375,7 @@ test.test_pathlib.WindowsPathTest.test_expanduser @ win32-AMD64 test.test_pathlib.WindowsPathTest.test_expanduser_common @ win32-AMD64 test.test_pathlib.WindowsPathTest.test_glob_dotdot @ win32-AMD64 test.test_pathlib.WindowsPathTest.test_glob_long_symlink @ win32-AMD64 +test.test_pathlib.WindowsPathTest.test_glob_many_open_files @ win32-AMD64 test.test_pathlib.WindowsPathTest.test_glob_permissions @ win32-AMD64 test.test_pathlib.WindowsPathTest.test_is_block_device_false @ win32-AMD64 test.test_pathlib.WindowsPathTest.test_is_char_device_false @ win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_strptime.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_strptime.txt index 019ffaf499..220ef38651 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_strptime.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_strptime.txt @@ -35,7 +35,8 @@ test.test_strptime.StrptimeTests.test_percent @ darwin-arm64,darwin-x86_64,linux test.test_strptime.StrptimeTests.test_second @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_strptime.StrptimeTests.test_strptime_exception_context @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_strptime.StrptimeTests.test_time @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 -test.test_strptime.StrptimeTests.test_timezone @ darwin-arm64,darwin-x86_64,win32-AMD64 +# Seems to be dependent on the actual time/date/timezone of the machine, at least on GraalPy. Needs investigation +!test.test_strptime.StrptimeTests.test_timezone test.test_strptime.StrptimeTests.test_unconverteddata @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_strptime.StrptimeTests.test_year @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_strptime.TimeRETests.test_blankpattern @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_tarfile.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_tarfile.txt index 10a7620240..ccb59a6b7f 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_tarfile.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_tarfile.txt @@ -253,7 +253,7 @@ test.test_tarfile.GzipWriteTest.test_fileobj_no_close @ darwin-arm64,darwin-x86_ test.test_tarfile.GzipWriteTest.test_filter @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_tarfile.GzipWriteTest.test_gettarinfo_pathlike_name @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_tarfile.GzipWriteTest.test_link_size @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 -test.test_tarfile.GzipWriteTest.test_open_nonwritable_fileobj @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 +test.test_tarfile.GzipWriteTest.test_open_nonwritable_fileobj @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_tarfile.GzipWriteTest.test_ordered_recursion @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_tarfile.GzipWriteTest.test_pathnames @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_tarfile.GzipWriteTest.test_symlink_size @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 @@ -261,12 +261,12 @@ test.test_tarfile.GzipWriteTest.test_tar_size @ darwin-arm64,darwin-x86_64,linux test.test_tarfile.HardlinkTest.test_add_hardlink @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_tarfile.HardlinkTest.test_add_twice @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_tarfile.HardlinkTest.test_dereference_hardlink @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 -test.test_tarfile.LimitsTest.test_gnu_limits @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 -test.test_tarfile.LimitsTest.test_pax_limits @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 -test.test_tarfile.LimitsTest.test_ustar_limits @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 -test.test_tarfile.ListTest.test_list @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 -test.test_tarfile.ListTest.test_list_members @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 -test.test_tarfile.LzmaAppendTest.test_append_compressed @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 +test.test_tarfile.LimitsTest.test_gnu_limits @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_tarfile.LimitsTest.test_pax_limits @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_tarfile.LimitsTest.test_ustar_limits @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_tarfile.ListTest.test_list @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_tarfile.ListTest.test_list_members @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_tarfile.LzmaAppendTest.test_append_compressed @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_tarfile.LzmaCreateTest.test_create @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_tarfile.LzmaCreateTest.test_create_existing @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_tarfile.LzmaCreateTest.test_create_existing_taropen @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_threading.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_threading.txt index 1367661d2c..fdd233cba0 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_threading.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_threading.txt @@ -75,7 +75,8 @@ test.test_threading.ExceptHookTests.test_custom_excepthook_fail @ darwin-arm64,d test.test_threading.ExceptHookTests.test_excepthook @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ExceptHookTests.test_original_excepthook @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ExceptHookTests.test_system_exit @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 -test.test_threading.InterruptMainTests.test_can_interrupt_tight_loops @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +# Transient on Darwin (at least) +!test.test_threading.InterruptMainTests.test_can_interrupt_tight_loops @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.InterruptMainTests.test_interrupt_main_noerror @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.LockTests.test_acquire_contended @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.LockTests.test_acquire_destroy @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 @@ -123,24 +124,22 @@ test.test_threading.SemaphoreTests.test_repr @ darwin-arm64,darwin-x86_64,linux- test.test_threading.SemaphoreTests.test_try_acquire @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.SemaphoreTests.test_try_acquire_contended @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.SemaphoreTests.test_with @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 -# GR-48555 race condition when exitting right after join -!test.test_threading.ThreadJoinOnShutdown.test_1_join_on_shutdown @ darwin-arm64 -!test.test_threading.ThreadJoinOnShutdown.test_4_daemon_threads @ darwin-arm64,linux-aarch64,linux-x86_64 +# Can transiently fail with java.lang.AssertionError: The TruffleContext must be entered +!test.test_threading.ThreadJoinOnShutdown.test_1_join_on_shutdown @ darwin-arm64,linux-aarch64,linux-x86_64 +test.test_threading.ThreadJoinOnShutdown.test_4_daemon_threads @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 test.test_threading.ThreadTests.test_BoundedSemaphore_limit @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ThreadTests.test_args_argument @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ThreadTests.test_boolean_target @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ThreadTests.test_daemon_param @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ThreadTests.test_enumerate_after_join @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 -# GR-48555 race condition when exitting right after join -!test.test_threading.ThreadTests.test_finalization_shutdown @ darwin-arm64,linux-aarch64,linux-x86_64 -!test.test_threading.ThreadTests.test_finalize_with_trace @ darwin-arm64,linux-aarch64,linux-x86_64 +test.test_threading.ThreadTests.test_finalization_shutdown @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_threading.ThreadTests.test_finalize_with_trace @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ThreadTests.test_foreign_thread @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ThreadTests.test_getprofile @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ThreadTests.test_gettrace @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ThreadTests.test_ident_of_no_threading_threads @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 -!test.test_threading.ThreadTests.test_import_from_another_thread @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 -# GR-48555 race condition when exitting right after join -!test.test_threading.ThreadTests.test_join_nondaemon_on_shutdown @ darwin-arm64,linux-aarch64,linux-x86_64 +test.test_threading.ThreadTests.test_import_from_another_thread @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_threading.ThreadTests.test_join_nondaemon_on_shutdown @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ThreadTests.test_leak_without_join @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ThreadTests.test_limbo_cleanup @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ThreadTests.test_main_thread @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 @@ -156,9 +155,8 @@ test.test_threading.ThreadingExceptionTests.test_daemonize_active_thread @ darwi test.test_threading.ThreadingExceptionTests.test_joining_current_thread @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ThreadingExceptionTests.test_joining_inactive_thread @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ThreadingExceptionTests.test_multithread_modify_file_noerror @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 -# GR-48555 race condition when exitting right after join -!test.test_threading.ThreadingExceptionTests.test_print_exception @ darwin-arm64,linux-aarch64,linux-x86_64 -!test.test_threading.ThreadingExceptionTests.test_print_exception_stderr_is_none_1 @ darwin-arm64,linux-aarch64,linux-x86_64 -!test.test_threading.ThreadingExceptionTests.test_print_exception_stderr_is_none_2 @ darwin-arm64,linux-aarch64,linux-x86_64 +test.test_threading.ThreadingExceptionTests.test_print_exception @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_threading.ThreadingExceptionTests.test_print_exception_stderr_is_none_1 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_threading.ThreadingExceptionTests.test_print_exception_stderr_is_none_2 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.ThreadingExceptionTests.test_start_thread_again @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading.TimerTests.test_init_immutable_default_args @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_threading_local.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_threading_local.txt index f39b63413c..f8ac86ecd6 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_threading_local.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_threading_local.txt @@ -1,5 +1,4 @@ -# GR-48555: transient "The language did not complete all polyglot threads but should have" -!DocTestCase._threading_local @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +DocTestCase._threading_local @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading_local.PyThreadingLocalTest.test_arguments @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading_local.PyThreadingLocalTest.test_derived @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_threading_local.PyThreadingLocalTest.test_derived_cycle_dealloc @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_unicode_identifiers.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_unicode_identifiers.txt new file mode 100644 index 0000000000..ee5433ef45 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_unicode_identifiers.txt @@ -0,0 +1,2 @@ +test.test_unicode_identifiers.PEP3131Test.test_invalid @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_unicode_identifiers.PEP3131Test.test_non_bmp_normalized @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_unittest.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_unittest.txt index 1da46bb72b..b884443c5b 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_unittest.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_unittest.txt @@ -510,6 +510,8 @@ unittest.test.testmock.testasync.AsyncMockAssert.test_awaits_asserts_with_spec_a unittest.test.testmock.testasync.AsyncMockTest.test_future_isfuture @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 unittest.test.testmock.testasync.AsyncMockTest.test_isawaitable @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 unittest.test.testmock.testasync.AsyncMockTest.test_iscoroutinefunction_default @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +unittest.test.testmock.testasync.AsyncMockTest.test_iscoroutinefunction_function @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +unittest.test.testmock.testasync.AsyncMockTest.test_iscoroutinefunction_normal_function @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 unittest.test.testmock.testasync.AsyncPatchCMTest.test_async_def_cm @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 unittest.test.testmock.testasync.AsyncPatchCMTest.test_is_AsyncMock_cm @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 unittest.test.testmock.testasync.AsyncPatchCMTest.test_is_async_cm @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 @@ -589,6 +591,7 @@ unittest.test.testmock.testhelpers.SpecSignatureTest.test_create_autospec_keywor unittest.test.testmock.testhelpers.SpecSignatureTest.test_create_autospec_none @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 unittest.test.testmock.testhelpers.SpecSignatureTest.test_create_autospec_return_value @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 unittest.test.testmock.testhelpers.SpecSignatureTest.test_descriptors @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +unittest.test.testmock.testhelpers.SpecSignatureTest.test_function @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 unittest.test.testmock.testhelpers.SpecSignatureTest.test_function_as_instance_attribute @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 unittest.test.testmock.testhelpers.SpecSignatureTest.test_inherit @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 unittest.test.testmock.testhelpers.SpecSignatureTest.test_magic_methods @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 @@ -801,6 +804,7 @@ unittest.test.testmock.testpatch.PatchTest.test_autospec_name @ darwin-arm64,dar unittest.test.testmock.testpatch.PatchTest.test_autospec_staticmethod @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 unittest.test.testmock.testpatch.PatchTest.test_autospec_staticmethod_signature @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 unittest.test.testmock.testpatch.PatchTest.test_autospec_with_new @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +unittest.test.testmock.testpatch.PatchTest.test_autospec_with_object @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 unittest.test.testmock.testpatch.PatchTest.test_callable_spec_as_list @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 unittest.test.testmock.testpatch.PatchTest.test_cant_set_kwargs_when_passing_a_mock @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 unittest.test.testmock.testpatch.PatchTest.test_create_and_specs @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_weakref.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_weakref.txt index 5e7ea67812..56f3526cc9 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_weakref.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_weakref.txt @@ -10,7 +10,7 @@ test.test_weakref.MappingTestCase.test_make_weak_valued_dict_misc @ darwin-arm64 test.test_weakref.MappingTestCase.test_make_weak_valued_dict_repr @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_weakref.MappingTestCase.test_threaded_weak_key_dict_copy @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_weakref.MappingTestCase.test_threaded_weak_value_dict_copy @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 -test.test_weakref.MappingTestCase.test_threaded_weak_value_dict_deepcopy @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64 +test.test_weakref.MappingTestCase.test_threaded_weak_value_dict_deepcopy @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_weakref.MappingTestCase.test_threaded_weak_valued_consistency @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_weakref.MappingTestCase.test_threaded_weak_valued_pop @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_weakref.MappingTestCase.test_threaded_weak_valued_setdefault @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 @@ -53,6 +53,8 @@ test.test_weakref.ReferencesTestCase.test_set_callback_attribute @ darwin-arm64, test.test_weakref.ReferencesTestCase.test_sf_bug_840829 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_weakref.ReferencesTestCase.test_shared_ref_without_callback @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_weakref.ReferencesTestCase.test_trashcan_16602 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +# transiently fails +!test.test_weakref.SubclassableWeakrefTestCase.test_subclass_refs test.test_weakref.SubclassableWeakrefTestCase.test_subclass_refs_with_cycle @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_weakref.SubclassableWeakrefTestCase.test_subclass_refs_with_slots @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_weakref.WeakKeyDictionaryTestCase.test_bool @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_zipfile.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_zipfile.txt index 83ce6fe2b5..9332f85274 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_zipfile.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_zipfile.txt @@ -156,6 +156,7 @@ test.test_zipfile.OtherTests.test_unsupported_version @ darwin-arm64,darwin-x86_ test.test_zipfile.OtherTests.test_write_unicode_filenames @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_zipfile.OtherTests.test_writestr_extended_local_header_issue1202 @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_zipfile.OtherTests.test_zipfile_with_short_extra_field @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 +test.test_zipfile.PyZipFileTests.test_write_filtered_python_package @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_zipfile.PyZipFileTests.test_write_non_pyfile @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_zipfile.PyZipFileTests.test_write_pathlike @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_zipfile.PyZipFileTests.test_write_pyfile @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test__locale.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test__locale.txt new file mode 100644 index 0000000000..d7efaa61ba --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test__locale.txt @@ -0,0 +1,2 @@ +test.test__locale._LocaleTests.test_float_parsing @ linux-x86_64 +test.test__locale._LocaleTests.test_lc_numeric_localeconv @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_abc.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_abc.txt new file mode 100644 index 0000000000..7c0fed706c --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_abc.txt @@ -0,0 +1,36 @@ +test.test_abc.test_factory..TestABC.test_ABC_has___slots__ @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_ABC_helper @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_abstractclassmethod_basics @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_abstractmethod_basics @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_abstractmethod_integration @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_abstractproperty_basics @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_abstractstaticmethod_basics @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_all_new_methods_are_called @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_customdescriptors_with_abstractmethod @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_descriptors_with_abstractmethod @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_isinstance_invalidation @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_issubclass_bad_arguments @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_metaclass_abc @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_object_new_with_many_abstractmethods @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_object_new_with_one_abstractmethod @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_register_as_class_deco @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_register_non_class @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_registration_basics @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_registration_builtins @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_registration_edge_cases @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_registration_transitiveness @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_subclasshook @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_tricky_new_works @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_update_as_decorator @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_update_del @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_update_del_implementation @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_update_implementation @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_update_layered_implementation @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_update_multi_inheritance @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_update_new_abstractmethods @ linux-x86_64 +test.test_abc.test_factory..TestABC.test_update_non_abc @ linux-x86_64 +test.test_abc.test_factory..TestABCWithInitSubclass.test_positional_only_and_kwonlyargs_with_init_subclass @ linux-x86_64 +test.test_abc.test_factory..TestABCWithInitSubclass.test_works_with_init_subclass @ linux-x86_64 +test.test_abc.test_factory..TestLegacyAPI.test_abstractclassmethod_basics @ linux-x86_64 +test.test_abc.test_factory..TestLegacyAPI.test_abstractproperty_basics @ linux-x86_64 +test.test_abc.test_factory..TestLegacyAPI.test_abstractstaticmethod_basics @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_abstract_numbers.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_abstract_numbers.txt new file mode 100644 index 0000000000..5ef53c818f --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_abstract_numbers.txt @@ -0,0 +1,3 @@ +test.test_abstract_numbers.TestNumbers.test_complex @ linux-x86_64 +test.test_abstract_numbers.TestNumbers.test_float @ linux-x86_64 +test.test_abstract_numbers.TestNumbers.test_int @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_argparse.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_argparse.txt new file mode 100644 index 0000000000..c1f78cf360 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_argparse.txt @@ -0,0 +1,1706 @@ +test.test_argparse.StdStreamTest.test_skip_invalid_stderr @ linux-x86_64 +test.test_argparse.StdStreamTest.test_skip_invalid_stdout @ linux-x86_64 +test.test_argparse.TestActionExtend.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestActionExtend.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestActionExtend.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestActionExtend.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestActionExtend.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestActionExtend.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestActionExtend.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestActionExtend.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestActionExtend.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestActionExtend.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestActionExtend.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestActionExtend.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestActionRegistration.test @ linux-x86_64 +test.test_argparse.TestActionUserDefined.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestActionUserDefined.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestActionUserDefined.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestActionUserDefined.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestActionUserDefined.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestActionUserDefined.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestActionUserDefined.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestActionUserDefined.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestActionUserDefined.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestActionUserDefined.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestActionUserDefined.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestActionUserDefined.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestActionsReturned.test_dest @ linux-x86_64 +test.test_argparse.TestActionsReturned.test_misc @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_1_metavar_length0 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_1_metavar_length1 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_1_metavar_length2 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_1_metavar_length3 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_1_metavar_string @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_2_metavar_length0 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_2_metavar_length1 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_2_metavar_length2 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_2_metavar_length3 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_2_metavar_string @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_3_metavar_length0 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_3_metavar_length1 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_3_metavar_length2 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_3_metavar_length3 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_3_metavar_string @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_None_metavar_length0 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_None_metavar_length1 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_None_metavar_length2 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_None_metavar_length3 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_None_metavar_string @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_oneormore_metavar_length0 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_oneormore_metavar_length1 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_oneormore_metavar_length2 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_oneormore_metavar_length3 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_oneormore_metavar_string @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_optional_metavar_length0 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_optional_metavar_length1 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_optional_metavar_length2 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_optional_metavar_length3 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_optional_metavar_string @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_parser_metavar_length0 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_parser_metavar_length1 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_parser_metavar_length2 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_parser_metavar_length3 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_parser_metavar_string @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_remainder_metavar_length0 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_remainder_metavar_length1 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_remainder_metavar_length2 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_remainder_metavar_length3 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_remainder_metavar_string @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_zeroormore_metavar_length0 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_zeroormore_metavar_length1 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_zeroormore_metavar_length2 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_zeroormore_metavar_length3 @ linux-x86_64 +test.test_argparse.TestAddArgumentMetavar.test_nargs_zeroormore_metavar_string @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_alias_help @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_alias_invocation @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_dest @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_error_alias_invocation @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_help @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_help_alternate_prefix_chars @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_help_blank @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_help_extra_prefix_chars @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_help_non_breaking_spaces @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_optional_subparsers @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_parse_args @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_parse_args_failures @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_parse_known_args @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_parser_command_help @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_required_subparsers_default @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_required_subparsers_no_destination_error @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_required_subparsers_via_attribute @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_required_subparsers_via_kwarg @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_subparser1_help @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_subparser2_help @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_subparser_title_help @ linux-x86_64 +test.test_argparse.TestAddSubparsers.test_wrong_argument_subparsers_no_destination_error @ linux-x86_64 +test.test_argparse.TestArgumentError.test_argument_error @ linux-x86_64 +test.test_argparse.TestArgumentTypeError.test_argument_type_error @ linux-x86_64 +test.test_argparse.TestArgumentsFromFile.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFile.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFile.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFile.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFile.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFile.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFile.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFile.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFile.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFile.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFile.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFile.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFileConverter.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFileConverter.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFileConverter.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFileConverter.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFileConverter.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFileConverter.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFileConverter.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFileConverter.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFileConverter.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFileConverter.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFileConverter.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestArgumentsFromFileConverter.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalAction.test_const @ linux-x86_64 +test.test_argparse.TestBooleanOptionalAction.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalAction.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalAction.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalAction.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalAction.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalAction.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalAction.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalAction.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalAction.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalAction.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalAction.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalAction.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalActionRequired.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalActionRequired.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalActionRequired.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalActionRequired.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalActionRequired.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalActionRequired.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalActionRequired.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalActionRequired.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalActionRequired.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalActionRequired.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalActionRequired.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestBooleanOptionalActionRequired.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestConflictHandling.test_bad_type @ linux-x86_64 +test.test_argparse.TestConflictHandling.test_conflict_error @ linux-x86_64 +test.test_argparse.TestConflictHandling.test_resolve_error @ linux-x86_64 +test.test_argparse.TestConflictHandling.test_subparser_conflict @ linux-x86_64 +test.test_argparse.TestConstActionsMissingConstKwarg.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestConstActionsMissingConstKwarg.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestConstActionsMissingConstKwarg.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestConstActionsMissingConstKwarg.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestConstActionsMissingConstKwarg.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestConstActionsMissingConstKwarg.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestConstActionsMissingConstKwarg.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestConstActionsMissingConstKwarg.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestConstActionsMissingConstKwarg.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestConstActionsMissingConstKwarg.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestConstActionsMissingConstKwarg.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestConstActionsMissingConstKwarg.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestDefaultSuppress.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestDefaultSuppress.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestDefaultSuppress.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestDefaultSuppress.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestDefaultSuppress.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestDefaultSuppress.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestDefaultSuppress.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestDefaultSuppress.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestDefaultSuppress.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestDefaultSuppress.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestDefaultSuppress.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestDefaultSuppress.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGrouping.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGrouping.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGrouping.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGrouping.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGrouping.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGrouping.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGrouping.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGrouping.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGrouping.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGrouping.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGrouping.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGrouping.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGroupingPrefix.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGroupingPrefix.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGroupingPrefix.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGroupingPrefix.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGroupingPrefix.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGroupingPrefix.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGroupingPrefix.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGroupingPrefix.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGroupingPrefix.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGroupingPrefix.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGroupingPrefix.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestDisallowLongAbbreviationAllowsShortGroupingPrefix.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestEmptyAndSpaceContainingArguments.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestEmptyAndSpaceContainingArguments.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestEmptyAndSpaceContainingArguments.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestEmptyAndSpaceContainingArguments.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestEmptyAndSpaceContainingArguments.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestEmptyAndSpaceContainingArguments.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestEmptyAndSpaceContainingArguments.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestEmptyAndSpaceContainingArguments.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestEmptyAndSpaceContainingArguments.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestEmptyAndSpaceContainingArguments.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestEmptyAndSpaceContainingArguments.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestEmptyAndSpaceContainingArguments.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestEncoding.test_argparse_module_encoding @ linux-x86_64 +test.test_argparse.TestEncoding.test_test_argparse_module_encoding @ linux-x86_64 +test.test_argparse.TestExitOnError.test_exit_on_error_with_bad_args @ linux-x86_64 +test.test_argparse.TestExitOnError.test_exit_on_error_with_good_args @ linux-x86_64 +test.test_argparse.TestFileTypeDefaults.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeDefaults.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeDefaults.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeDefaults.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeDefaults.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeDefaults.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeDefaults.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeDefaults.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeDefaults.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeDefaults.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeDefaults.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeDefaults.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeMissingInitialization.test @ linux-x86_64 +test.test_argparse.TestFileTypeOpenArgs.test_open_args @ linux-x86_64 +test.test_argparse.TestFileTypeR.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeR.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeR.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeR.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeR.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeR.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeR.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeR.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeR.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeR.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeR.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeR.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeRB.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeRB.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeRB.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeRB.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeRB.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeRB.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeRB.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeRB.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeRB.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeRB.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeRB.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeRB.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeRepr.test_r @ linux-x86_64 +test.test_argparse.TestFileTypeRepr.test_r_1_replace @ linux-x86_64 +test.test_argparse.TestFileTypeRepr.test_r_latin @ linux-x86_64 +test.test_argparse.TestFileTypeRepr.test_w_big5_ignore @ linux-x86_64 +test.test_argparse.TestFileTypeRepr.test_wb_1 @ linux-x86_64 +test.test_argparse.TestFileTypeW.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeW.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeW.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeW.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeW.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeW.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeW.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeW.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeW.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeW.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeW.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeW.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeWB.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeWB.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeWB.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeWB.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeWB.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeWB.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeWB.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeWB.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeWB.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeWB.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeWB.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeWB.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeX.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeX.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeX.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeX.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeX.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeX.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeX.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeX.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeX.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeX.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeX.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeX.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeXB.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeXB.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeXB.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeXB.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeXB.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeXB.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeXB.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeXB.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeXB.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeXB.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestFileTypeXB.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestFileTypeXB.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestGetDefault.test_get_default @ linux-x86_64 +test.test_argparse.TestHelpAlternatePrefixChars.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpAlternatePrefixChars.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpAlternatePrefixChars.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpAlternatePrefixChars.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpAlternatePrefixChars.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpAlternatePrefixChars.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpArgumentDefaults.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpArgumentDefaults.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpArgumentDefaults.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpArgumentDefaults.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpArgumentDefaults.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpArgumentDefaults.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpBiggerOptionalGroups.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpBiggerOptionalGroups.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpBiggerOptionalGroups.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpBiggerOptionalGroups.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpBiggerOptionalGroups.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpBiggerOptionalGroups.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpBiggerOptionals.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpBiggerOptionals.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpBiggerOptionals.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpBiggerOptionals.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpBiggerOptionals.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpBiggerOptionals.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpBiggerPositionals.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpBiggerPositionals.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpBiggerPositionals.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpBiggerPositionals.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpBiggerPositionals.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpBiggerPositionals.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpMetavarTypeFormatter.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpMetavarTypeFormatter.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpMetavarTypeFormatter.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpMetavarTypeFormatter.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpMetavarTypeFormatter.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpMetavarTypeFormatter.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpNoHelpOptional.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpNoHelpOptional.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpNoHelpOptional.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpNoHelpOptional.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpNoHelpOptional.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpNoHelpOptional.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpNone.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpNone.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpNone.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpNone.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpNone.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpNone.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpOnlyUserGroups.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpOnlyUserGroups.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpOnlyUserGroups.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpOnlyUserGroups.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpOnlyUserGroups.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpOnlyUserGroups.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpRawDescription.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpRawDescription.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpRawDescription.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpRawDescription.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpRawDescription.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpRawDescription.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpRawText.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpRawText.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpRawText.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpRawText.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpRawText.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpRawText.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpReformatting.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpReformatting.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpReformatting.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpReformatting.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpReformatting.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpReformatting.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpRequiredOptional.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpRequiredOptional.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpRequiredOptional.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpRequiredOptional.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpRequiredOptional.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpRequiredOptional.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpSubparsersOrdering.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpSubparsersOrdering.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpSubparsersOrdering.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpSubparsersOrdering.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpSubparsersOrdering.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpSubparsersOrdering.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpSubparsersWithHelpOrdering.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpSubparsersWithHelpOrdering.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpSubparsersWithHelpOrdering.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpSubparsersWithHelpOrdering.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpSubparsersWithHelpOrdering.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpSubparsersWithHelpOrdering.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpSuppressOptional.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpSuppressOptional.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpSuppressOptional.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpSuppressOptional.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpSuppressOptional.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpSuppressOptional.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpSuppressOptionalGroup.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpSuppressOptionalGroup.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpSuppressOptionalGroup.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpSuppressOptionalGroup.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpSuppressOptionalGroup.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpSuppressOptionalGroup.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpSuppressPositional.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpSuppressPositional.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpSuppressPositional.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpSuppressPositional.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpSuppressPositional.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpSuppressPositional.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpSuppressUsage.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpSuppressUsage.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpSuppressUsage.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpSuppressUsage.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpSuppressUsage.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpSuppressUsage.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpTupleMetavar.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpTupleMetavar.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpTupleMetavar.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpTupleMetavar.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpTupleMetavar.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpTupleMetavar.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpUsage.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpUsage.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpUsage.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpUsage.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpUsage.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpUsage.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProg.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProg.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProg.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProg.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProg.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProg.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProgOptionsWrap.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProgOptionsWrap.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProgOptionsWrap.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProgOptionsWrap.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProgOptionsWrap.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProgOptionsWrap.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProgPositionalsWrap.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProgPositionalsWrap.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProgPositionalsWrap.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProgPositionalsWrap.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProgPositionalsWrap.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpUsageLongProgPositionalsWrap.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsOnlyWrap.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsOnlyWrap.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsOnlyWrap.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsOnlyWrap.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsOnlyWrap.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsOnlyWrap.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsPositionalsWrap.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsPositionalsWrap.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsPositionalsWrap.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsPositionalsWrap.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsPositionalsWrap.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsPositionalsWrap.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsWrap.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsWrap.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsWrap.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsWrap.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsWrap.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpUsageOptionalsWrap.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpUsagePositionalsOnlyWrap.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpUsagePositionalsOnlyWrap.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpUsagePositionalsOnlyWrap.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpUsagePositionalsOnlyWrap.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpUsagePositionalsOnlyWrap.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpUsagePositionalsOnlyWrap.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpUsagePositionalsWrap.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpUsagePositionalsWrap.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpUsagePositionalsWrap.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpUsagePositionalsWrap.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpUsagePositionalsWrap.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpUsagePositionalsWrap.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageWithParentheses.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpUsageWithParentheses.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageWithParentheses.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpUsageWithParentheses.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpUsageWithParentheses.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpUsageWithParentheses.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansion.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansion.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansion.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansion.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansion.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansion.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansionNoArguments.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansionNoArguments.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansionNoArguments.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansionNoArguments.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansionNoArguments.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansionNoArguments.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansionUsageSupplied.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansionUsageSupplied.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansionUsageSupplied.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansionUsageSupplied.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansionUsageSupplied.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpVariableExpansionUsageSupplied.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpVersionAction.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpVersionAction.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpVersionAction.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpVersionAction.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpVersionAction.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpVersionAction.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpVersionActionSuppress.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpVersionActionSuppress.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpVersionActionSuppress.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpVersionActionSuppress.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpVersionActionSuppress.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpVersionActionSuppress.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpWrappingLongNames.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpWrappingLongNames.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpWrappingLongNames.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpWrappingLongNames.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpWrappingLongNames.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpWrappingLongNames.test_print_usage @ linux-x86_64 +test.test_argparse.TestHelpWrappingShortNames.test_format_help @ linux-x86_64 +test.test_argparse.TestHelpWrappingShortNames.test_format_usage @ linux-x86_64 +test.test_argparse.TestHelpWrappingShortNames.test_print_file_help @ linux-x86_64 +test.test_argparse.TestHelpWrappingShortNames.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestHelpWrappingShortNames.test_print_help @ linux-x86_64 +test.test_argparse.TestHelpWrappingShortNames.test_print_usage @ linux-x86_64 +test.test_argparse.TestImportStar.test @ linux-x86_64 +test.test_argparse.TestImportStar.test_all_exports_everything_but_modules @ linux-x86_64 +test.test_argparse.TestIntermixedArgs.test_basic @ linux-x86_64 +test.test_argparse.TestIntermixedArgs.test_exclusive @ linux-x86_64 +test.test_argparse.TestIntermixedArgs.test_exclusive_incompatible @ linux-x86_64 +test.test_argparse.TestIntermixedArgs.test_remainder @ linux-x86_64 +test.test_argparse.TestIntermixedMessageContentError.test_missing_argument_name_in_message @ linux-x86_64 +test.test_argparse.TestInvalidArgumentConstructors.test_invalid_action @ linux-x86_64 +test.test_argparse.TestInvalidArgumentConstructors.test_invalid_keyword_arguments @ linux-x86_64 +test.test_argparse.TestInvalidArgumentConstructors.test_invalid_option_strings @ linux-x86_64 +test.test_argparse.TestInvalidArgumentConstructors.test_invalid_type @ linux-x86_64 +test.test_argparse.TestInvalidArgumentConstructors.test_missing_destination @ linux-x86_64 +test.test_argparse.TestInvalidArgumentConstructors.test_more_than_one_argument_actions @ linux-x86_64 +test.test_argparse.TestInvalidArgumentConstructors.test_multiple_dest @ linux-x86_64 +test.test_argparse.TestInvalidArgumentConstructors.test_no_argument_actions @ linux-x86_64 +test.test_argparse.TestInvalidArgumentConstructors.test_no_argument_no_const_actions @ linux-x86_64 +test.test_argparse.TestInvalidArgumentConstructors.test_parsers_action_missing_params @ linux-x86_64 +test.test_argparse.TestInvalidArgumentConstructors.test_required_const_actions @ linux-x86_64 +test.test_argparse.TestInvalidArgumentConstructors.test_required_positional @ linux-x86_64 +test.test_argparse.TestInvalidArgumentConstructors.test_user_defined_action @ linux-x86_64 +test.test_argparse.TestInvalidNargs.test_nargs_alphabetic @ linux-x86_64 +test.test_argparse.TestInvalidNargs.test_nargs_zero @ linux-x86_64 +test.test_argparse.TestMessageContentError.test_missing_argument_name_in_message @ linux-x86_64 +test.test_argparse.TestMessageContentError.test_optional_optional_not_in_message @ linux-x86_64 +test.test_argparse.TestMessageContentError.test_optional_positional_not_in_message @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressed.test_failures_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressed.test_failures_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressed.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressed.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressed.test_successes_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressed.test_successes_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressed.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressed.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressedParent.test_failures_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressedParent.test_failures_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressedParent.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressedParent.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressedParent.test_successes_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressedParent.test_successes_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressedParent.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveFirstSuppressedParent.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveGroupErrors.test_empty_group @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveGroupErrors.test_help @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveGroupErrors.test_invalid_add_argument @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveGroupErrors.test_invalid_add_argument_group @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveGroupErrorsParent.test_empty_group @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveGroupErrorsParent.test_help @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveGroupErrorsParent.test_invalid_add_argument @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveGroupErrorsParent.test_invalid_add_argument_group @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveInGroup.test_failures_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveInGroup.test_failures_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveInGroup.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveInGroup.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveInGroup.test_successes_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveInGroup.test_successes_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveInGroup.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveInGroup.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLong.test_failures_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLong.test_failures_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLong.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLong.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLong.test_successes_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLong.test_successes_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLong.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLong.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLongParent.test_failures_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLongParent.test_failures_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLongParent.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLongParent.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLongParent.test_successes_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLongParent.test_successes_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLongParent.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveLongParent.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressed.test_failures_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressed.test_failures_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressed.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressed.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressed.test_successes_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressed.test_successes_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressed.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressed.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressedParent.test_failures_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressedParent.test_failures_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressedParent.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressedParent.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressedParent.test_successes_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressedParent.test_successes_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressedParent.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveManySuppressedParent.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveNested.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveNested.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveNested.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveNested.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositional.test_failures_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositional.test_failures_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositional.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositional.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositional.test_successes_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositional.test_successes_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositional.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositional.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositionalParent.test_failures_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositionalParent.test_failures_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositionalParent.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositionalParent.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositionalParent.test_successes_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositionalParent.test_successes_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositionalParent.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalAndPositionalParent.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixed.test_failures_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixed.test_failures_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixed.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixed.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixed.test_successes_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixed.test_successes_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixed.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixed.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixedParent.test_failures_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixedParent.test_failures_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixedParent.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixedParent.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixedParent.test_successes_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixedParent.test_successes_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixedParent.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsAndPositionalsMixedParent.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixed.test_failures_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixed.test_failures_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixed.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixed.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixed.test_successes_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixed.test_successes_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixed.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixed.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixedParent.test_failures_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixedParent.test_failures_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixedParent.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixedParent.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixedParent.test_successes_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixedParent.test_successes_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixedParent.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveOptionalsMixedParent.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimple.test_failures_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimple.test_failures_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimple.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimple.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimple.test_successes_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimple.test_successes_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimple.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimple.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimpleParent.test_failures_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimpleParent.test_failures_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimpleParent.test_help_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimpleParent.test_help_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimpleParent.test_successes_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimpleParent.test_successes_when_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimpleParent.test_usage_when_not_required @ linux-x86_64 +test.test_argparse.TestMutuallyExclusiveSimpleParent.test_usage_when_required @ linux-x86_64 +test.test_argparse.TestNamespace.test_constructor @ linux-x86_64 +test.test_argparse.TestNamespace.test_equality @ linux-x86_64 +test.test_argparse.TestNamespace.test_equality_returns_notimplemented @ linux-x86_64 +test.test_argparse.TestNamespaceContainsSimple.test_empty @ linux-x86_64 +test.test_argparse.TestNamespaceContainsSimple.test_non_empty @ linux-x86_64 +test.test_argparse.TestNargsRemainder.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestNargsRemainder.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestNargsRemainder.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestNargsRemainder.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestNargsRemainder.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestNargsRemainder.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestNargsRemainder.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestNargsRemainder.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestNargsRemainder.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestNargsRemainder.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestNargsRemainder.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestNargsRemainder.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestNargsZeroOrMore.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestNargsZeroOrMore.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestNargsZeroOrMore.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestNargsZeroOrMore.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestNargsZeroOrMore.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestNargsZeroOrMore.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestNargsZeroOrMore.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestNargsZeroOrMore.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestNargsZeroOrMore.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestNargsZeroOrMore.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestNargsZeroOrMore.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestNargsZeroOrMore.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionLike.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionLike.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionLike.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionLike.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionLike.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionLike.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionLike.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionLike.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionLike.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionLike.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionLike.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionLike.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppend.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppend.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppend.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppend.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppend.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppend.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppend.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppend.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppend.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppend.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppend.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppend.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConst.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConst.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConst.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConst.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConst.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConst.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConst.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConst.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConst.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConst.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConst.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConst.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConstWithDefault.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConstWithDefault.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConstWithDefault.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConstWithDefault.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConstWithDefault.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConstWithDefault.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConstWithDefault.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConstWithDefault.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConstWithDefault.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConstWithDefault.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConstWithDefault.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendConstWithDefault.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendWithDefault.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendWithDefault.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendWithDefault.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendWithDefault.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendWithDefault.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendWithDefault.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendWithDefault.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendWithDefault.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendWithDefault.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendWithDefault.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendWithDefault.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionAppendWithDefault.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionCount.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionCount.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionCount.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionCount.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionCount.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionCount.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionCount.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionCount.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionCount.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionCount.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionCount.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionCount.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStore.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStore.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStore.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStore.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStore.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStore.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStore.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStore.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStore.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStore.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStore.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStore.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreConst.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreConst.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreConst.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreConst.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreConst.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreConst.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreConst.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreConst.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreConst.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreConst.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreConst.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreConst.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreFalse.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreFalse.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreFalse.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreFalse.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreFalse.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreFalse.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreFalse.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreFalse.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreFalse.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreFalse.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreFalse.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreFalse.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreTrue.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreTrue.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreTrue.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreTrue.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreTrue.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreTrue.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreTrue.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreTrue.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreTrue.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreTrue.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreTrue.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsActionStoreTrue.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAllowLongAbbreviation.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAllowLongAbbreviation.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAllowLongAbbreviation.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAllowLongAbbreviation.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAllowLongAbbreviation.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAllowLongAbbreviation.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAllowLongAbbreviation.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAllowLongAbbreviation.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAllowLongAbbreviation.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAllowLongAbbreviation.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAllowLongAbbreviation.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAllowLongAbbreviation.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlmostNumericAndPositionals.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlmostNumericAndPositionals.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlmostNumericAndPositionals.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlmostNumericAndPositionals.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlmostNumericAndPositionals.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlmostNumericAndPositionals.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlmostNumericAndPositionals.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlmostNumericAndPositionals.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlmostNumericAndPositionals.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlmostNumericAndPositionals.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlmostNumericAndPositionals.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlmostNumericAndPositionals.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixChars.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixChars.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixChars.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixChars.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixChars.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixChars.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixChars.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixChars.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixChars.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixChars.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixChars.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixChars.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsAddedHelp.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsAddedHelp.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsAddedHelp.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsAddedHelp.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsAddedHelp.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsAddedHelp.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsAddedHelp.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsAddedHelp.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsAddedHelp.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsAddedHelp.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsAddedHelp.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsAddedHelp.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsMultipleShortArgs.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsMultipleShortArgs.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsMultipleShortArgs.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsMultipleShortArgs.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsMultipleShortArgs.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsMultipleShortArgs.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsMultipleShortArgs.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsMultipleShortArgs.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsMultipleShortArgs.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsMultipleShortArgs.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsMultipleShortArgs.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsAlternatePrefixCharsMultipleShortArgs.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsChoices.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsChoices.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsChoices.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsChoices.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsChoices.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsChoices.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsChoices.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsChoices.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsChoices.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsChoices.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsChoices.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsChoices.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDefault.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDefault.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDefault.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDefault.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDefault.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDefault.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDefault.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDefault.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDefault.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDefault.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDefault.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDefault.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDest.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDest.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDest.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDest.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDest.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDest.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDest.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDest.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDest.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDest.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDest.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDest.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviation.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviation.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviation.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviation.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviation.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviation.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviation.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviation.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviation.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviation.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviation.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviation.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviationPrefixChars.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviationPrefixChars.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviationPrefixChars.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviationPrefixChars.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviationPrefixChars.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviationPrefixChars.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviationPrefixChars.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviationPrefixChars.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviationPrefixChars.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviationPrefixChars.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviationPrefixChars.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDisallowLongAbbreviationPrefixChars.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDash.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDash.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDash.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDash.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDash.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDash.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDash.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDash.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDash.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDash.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDash.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDash.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPartialMatch.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPartialMatch.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPartialMatch.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPartialMatch.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPartialMatch.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPartialMatch.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPartialMatch.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPartialMatch.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPartialMatch.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPartialMatch.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPartialMatch.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPartialMatch.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPrefixMatch.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPrefixMatch.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPrefixMatch.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPrefixMatch.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPrefixMatch.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPrefixMatch.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPrefixMatch.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPrefixMatch.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPrefixMatch.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPrefixMatch.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPrefixMatch.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsDoubleDashPrefixMatch.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsHelpVersionActions.test_alternate_help_version @ linux-x86_64 +test.test_argparse.TestOptionalsHelpVersionActions.test_help_version_extra_arguments @ linux-x86_64 +test.test_argparse.TestOptionalsHelpVersionActions.test_no_help @ linux-x86_64 +test.test_argparse.TestOptionalsHelpVersionActions.test_version @ linux-x86_64 +test.test_argparse.TestOptionalsHelpVersionActions.test_version_action @ linux-x86_64 +test.test_argparse.TestOptionalsHelpVersionActions.test_version_format @ linux-x86_64 +test.test_argparse.TestOptionalsHelpVersionActions.test_version_no_help @ linux-x86_64 +test.test_argparse.TestOptionalsNargs1.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs1.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs1.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs1.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs1.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs1.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs1.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs1.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs1.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs1.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs1.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs1.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs3.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs3.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs3.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs3.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs3.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs3.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs3.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs3.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs3.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs3.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs3.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargs3.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsDefault.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsDefault.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsDefault.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsDefault.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsDefault.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsDefault.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsDefault.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsDefault.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsDefault.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsDefault.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsDefault.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsDefault.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOneOrMore.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOneOrMore.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOneOrMore.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOneOrMore.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOneOrMore.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOneOrMore.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOneOrMore.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOneOrMore.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOneOrMore.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOneOrMore.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOneOrMore.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOneOrMore.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOptional.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOptional.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOptional.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOptional.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOptional.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOptional.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOptional.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOptional.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOptional.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOptional.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOptional.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsOptional.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsZeroOrMore.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsZeroOrMore.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsZeroOrMore.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsZeroOrMore.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsZeroOrMore.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsZeroOrMore.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsZeroOrMore.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsZeroOrMore.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsZeroOrMore.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsZeroOrMore.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsZeroOrMore.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNargsZeroOrMore.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumeric.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumeric.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumeric.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumeric.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumeric.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumeric.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumeric.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumeric.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumeric.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumeric.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumeric.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumeric.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumericAndPositionals.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumericAndPositionals.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumericAndPositionals.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumericAndPositionals.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumericAndPositionals.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumericAndPositionals.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumericAndPositionals.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumericAndPositionals.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumericAndPositionals.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumericAndPositionals.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumericAndPositionals.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsNumericAndPositionals.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsRequired.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsRequired.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsRequired.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsRequired.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsRequired.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsRequired.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsRequired.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsRequired.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsRequired.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsRequired.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsRequired.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsRequired.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsShortLong.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsShortLong.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsShortLong.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsShortLong.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsShortLong.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsShortLong.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsShortLong.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsShortLong.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsShortLong.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsShortLong.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsShortLong.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsShortLong.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDash.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDash.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDash.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDash.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDash.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDash.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDash.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDash.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDash.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDash.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDash.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDash.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashAmbiguous.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashAmbiguous.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashAmbiguous.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashAmbiguous.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashAmbiguous.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashAmbiguous.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashAmbiguous.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashAmbiguous.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashAmbiguous.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashAmbiguous.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashAmbiguous.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashAmbiguous.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashCombined.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashCombined.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashCombined.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashCombined.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashCombined.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashCombined.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashCombined.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashCombined.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashCombined.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashCombined.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashCombined.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashCombined.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashLong.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashLong.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashLong.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashLong.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashLong.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashLong.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashLong.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashLong.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashLong.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashLong.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashLong.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashLong.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashSubsetAmbiguous.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashSubsetAmbiguous.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashSubsetAmbiguous.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashSubsetAmbiguous.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashSubsetAmbiguous.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashSubsetAmbiguous.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashSubsetAmbiguous.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashSubsetAmbiguous.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashSubsetAmbiguous.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashSubsetAmbiguous.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashSubsetAmbiguous.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDashSubsetAmbiguous.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDoubleDash.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDoubleDash.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDoubleDash.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDoubleDash.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDoubleDash.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDoubleDash.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDoubleDash.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDoubleDash.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDoubleDash.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDoubleDash.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDoubleDash.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestOptionalsSingleDoubleDash.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestParentParsers.test_conflicting_parents @ linux-x86_64 +test.test_argparse.TestParentParsers.test_conflicting_parents_mutex @ linux-x86_64 +test.test_argparse.TestParentParsers.test_groups_parents @ linux-x86_64 +test.test_argparse.TestParentParsers.test_multiple_parents @ linux-x86_64 +test.test_argparse.TestParentParsers.test_multiple_parents_mutex @ linux-x86_64 +test.test_argparse.TestParentParsers.test_parent_help @ linux-x86_64 +test.test_argparse.TestParentParsers.test_same_argument_name_parents @ linux-x86_64 +test.test_argparse.TestParentParsers.test_single_granparent_mutex @ linux-x86_64 +test.test_argparse.TestParentParsers.test_single_parent @ linux-x86_64 +test.test_argparse.TestParentParsers.test_single_parent_mutex @ linux-x86_64 +test.test_argparse.TestParentParsers.test_subparser_parents @ linux-x86_64 +test.test_argparse.TestParentParsers.test_subparser_parents_mutex @ linux-x86_64 +test.test_argparse.TestParseKnownArgs.test_arguments_list @ linux-x86_64 +test.test_argparse.TestParseKnownArgs.test_arguments_list_positional @ linux-x86_64 +test.test_argparse.TestParseKnownArgs.test_arguments_tuple @ linux-x86_64 +test.test_argparse.TestParseKnownArgs.test_arguments_tuple_positional @ linux-x86_64 +test.test_argparse.TestParseKnownArgs.test_mixed @ linux-x86_64 +test.test_argparse.TestParseKnownArgs.test_optionals @ linux-x86_64 +test.test_argparse.TestParserDefault42.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestParserDefault42.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestParserDefault42.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestParserDefault42.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestParserDefault42.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestParserDefault42.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestParserDefault42.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestParserDefault42.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestParserDefault42.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestParserDefault42.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestParserDefault42.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestParserDefault42.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestParserDefaultSuppress.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestParserDefaultSuppress.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestParserDefaultSuppress.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestParserDefaultSuppress.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestParserDefaultSuppress.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestParserDefaultSuppress.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestParserDefaultSuppress.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestParserDefaultSuppress.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestParserDefaultSuppress.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestParserDefaultSuppress.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestParserDefaultSuppress.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestParserDefaultSuppress.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsActionAppend.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsActionAppend.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsActionAppend.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsActionAppend.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsActionAppend.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsActionAppend.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsActionAppend.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsActionAppend.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsActionAppend.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsActionAppend.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsActionAppend.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsActionAppend.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesInt.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesInt.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesInt.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesInt.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesInt.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesInt.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesInt.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesInt.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesInt.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesInt.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesInt.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesInt.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesString.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesString.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesString.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesString.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesString.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesString.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesString.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesString.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesString.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesString.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesString.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsChoicesString.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsGroups.test_group_first @ linux-x86_64 +test.test_argparse.TestPositionalsGroups.test_interleaved_groups @ linux-x86_64 +test.test_argparse.TestPositionalsGroups.test_nongroup_first @ linux-x86_64 +test.test_argparse.TestPositionalsNargs1.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs1.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs1.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs1.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs1.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs1.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs1.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs1.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs1.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs1.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs1.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs1.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2None.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2None.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2None.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2None.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2None.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2None.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2None.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2None.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2None.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2None.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2None.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2None.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2OneOrMore.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2OneOrMore.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2OneOrMore.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2OneOrMore.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2OneOrMore.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2OneOrMore.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2OneOrMore.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2OneOrMore.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2OneOrMore.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2OneOrMore.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2OneOrMore.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2OneOrMore.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2Optional.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2Optional.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2Optional.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2Optional.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2Optional.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2Optional.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2Optional.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2Optional.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2Optional.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2Optional.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2Optional.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2Optional.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2ZeroOrMore.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2ZeroOrMore.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2ZeroOrMore.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2ZeroOrMore.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2ZeroOrMore.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2ZeroOrMore.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2ZeroOrMore.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2ZeroOrMore.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2ZeroOrMore.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2ZeroOrMore.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2ZeroOrMore.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargs2ZeroOrMore.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone1.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone1.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone1.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone1.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone1.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone1.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone1.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone1.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone1.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone1.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone1.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNone1.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneNone.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneNone.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneNone.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneNone.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneNone.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneNone.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneNone.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneNone.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneNone.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneNone.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneNone.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneNone.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore1.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore1.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore1.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore1.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore1.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore1.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore1.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore1.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore1.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore1.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore1.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOneOrMore1.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional1.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional1.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional1.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional1.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional1.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional1.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional1.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional1.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional1.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional1.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional1.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneOptional1.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore1.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore1.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore1.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore1.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore1.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore1.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore1.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore1.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore1.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore1.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore1.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsNoneZeroOrMore1.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore1.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore1.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore1.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore1.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore1.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore1.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore1.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore1.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore1.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore1.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore1.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMore1.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMoreNone.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMoreNone.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMoreNone.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMoreNone.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMoreNone.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMoreNone.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMoreNone.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMoreNone.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMoreNone.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMoreNone.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMoreNone.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOneOrMoreNone.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional1.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional1.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional1.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional1.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional1.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional1.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional1.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional1.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional1.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional1.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional1.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptional1.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalConvertedDefault.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalConvertedDefault.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalConvertedDefault.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalConvertedDefault.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalConvertedDefault.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalConvertedDefault.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalConvertedDefault.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalConvertedDefault.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalConvertedDefault.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalConvertedDefault.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalConvertedDefault.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalConvertedDefault.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalDefault.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalDefault.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalDefault.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalDefault.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalDefault.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalDefault.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalDefault.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalDefault.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalDefault.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalDefault.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalDefault.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalDefault.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalNone.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalNone.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalNone.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalNone.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalNone.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalNone.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalNone.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalNone.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalNone.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalNone.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalNone.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalNone.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOneOrMore.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOneOrMore.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOneOrMore.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOneOrMore.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOneOrMore.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOneOrMore.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOneOrMore.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOneOrMore.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOneOrMore.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOneOrMore.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOneOrMore.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOneOrMore.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOptional.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOptional.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOptional.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOptional.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOptional.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOptional.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOptional.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOptional.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOptional.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOptional.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOptional.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalOptional.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalZeroOrMore.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalZeroOrMore.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalZeroOrMore.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalZeroOrMore.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalZeroOrMore.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalZeroOrMore.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalZeroOrMore.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalZeroOrMore.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalZeroOrMore.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalZeroOrMore.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalZeroOrMore.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsOptionalZeroOrMore.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore1.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore1.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore1.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore1.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore1.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore1.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore1.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore1.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore1.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore1.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore1.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMore1.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreDefault.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreDefault.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreDefault.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreDefault.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreDefault.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreDefault.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreDefault.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreDefault.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreDefault.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreDefault.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreDefault.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreDefault.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreNone.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreNone.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreNone.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreNone.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreNone.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreNone.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreNone.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreNone.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreNone.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreNone.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreNone.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPositionalsNargsZeroOrMoreNone.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPrefixCharacterOnlyArguments.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPrefixCharacterOnlyArguments.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPrefixCharacterOnlyArguments.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPrefixCharacterOnlyArguments.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPrefixCharacterOnlyArguments.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPrefixCharacterOnlyArguments.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestPrefixCharacterOnlyArguments.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestPrefixCharacterOnlyArguments.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPrefixCharacterOnlyArguments.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestPrefixCharacterOnlyArguments.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestPrefixCharacterOnlyArguments.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestPrefixCharacterOnlyArguments.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestSetDefaults.test_set_defaults_no_args @ linux-x86_64 +test.test_argparse.TestSetDefaults.test_set_defaults_on_parent_and_subparser @ linux-x86_64 +test.test_argparse.TestSetDefaults.test_set_defaults_parents @ linux-x86_64 +test.test_argparse.TestSetDefaults.test_set_defaults_same_as_add_argument @ linux-x86_64 +test.test_argparse.TestSetDefaults.test_set_defaults_same_as_add_argument_group @ linux-x86_64 +test.test_argparse.TestSetDefaults.test_set_defaults_subparsers @ linux-x86_64 +test.test_argparse.TestSetDefaults.test_set_defaults_with_args @ linux-x86_64 +test.test_argparse.TestShortColumns.test_format_help @ linux-x86_64 +test.test_argparse.TestShortColumns.test_format_usage @ linux-x86_64 +test.test_argparse.TestShortColumns.test_print_file_help @ linux-x86_64 +test.test_argparse.TestShortColumns.test_print_file_usage @ linux-x86_64 +test.test_argparse.TestShortColumns.test_print_help @ linux-x86_64 +test.test_argparse.TestShortColumns.test_print_usage @ linux-x86_64 +test.test_argparse.TestStrings.test_argument @ linux-x86_64 +test.test_argparse.TestStrings.test_namespace @ linux-x86_64 +test.test_argparse.TestStrings.test_namespace_kwargs_and_starkwargs_notidentifier @ linux-x86_64 +test.test_argparse.TestStrings.test_namespace_starkwargs_identifier @ linux-x86_64 +test.test_argparse.TestStrings.test_namespace_starkwargs_notidentifier @ linux-x86_64 +test.test_argparse.TestStrings.test_optional @ linux-x86_64 +test.test_argparse.TestStrings.test_parser @ linux-x86_64 +test.test_argparse.TestTypeCallable.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestTypeCallable.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestTypeCallable.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestTypeCallable.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestTypeCallable.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestTypeCallable.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestTypeCallable.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestTypeCallable.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestTypeCallable.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestTypeCallable.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestTypeCallable.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestTypeCallable.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestTypeClassicClass.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestTypeClassicClass.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestTypeClassicClass.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestTypeClassicClass.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestTypeClassicClass.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestTypeClassicClass.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestTypeClassicClass.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestTypeClassicClass.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestTypeClassicClass.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestTypeClassicClass.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestTypeClassicClass.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestTypeClassicClass.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestTypeFunctionCallOnlyOnce.test_type_function_call_only_once @ linux-x86_64 +test.test_argparse.TestTypeFunctionCalledOnDefault.test_issue_15906 @ linux-x86_64 +test.test_argparse.TestTypeFunctionCalledOnDefault.test_no_double_type_conversion_of_default @ linux-x86_64 +test.test_argparse.TestTypeFunctionCalledOnDefault.test_type_function_call_with_non_string_default @ linux-x86_64 +test.test_argparse.TestTypeFunctionCalledOnDefault.test_type_function_call_with_string_default @ linux-x86_64 +test.test_argparse.TestTypeRegistration.test @ linux-x86_64 +test.test_argparse.TestTypeUserDefined.test_failures_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestTypeUserDefined.test_failures_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestTypeUserDefined.test_failures_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestTypeUserDefined.test_failures_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestTypeUserDefined.test_failures_one_group_listargs @ linux-x86_64 +test.test_argparse.TestTypeUserDefined.test_failures_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestTypeUserDefined.test_successes_many_groups_listargs @ linux-x86_64 +test.test_argparse.TestTypeUserDefined.test_successes_many_groups_sysargs @ linux-x86_64 +test.test_argparse.TestTypeUserDefined.test_successes_no_groups_listargs @ linux-x86_64 +test.test_argparse.TestTypeUserDefined.test_successes_no_groups_sysargs @ linux-x86_64 +test.test_argparse.TestTypeUserDefined.test_successes_one_group_listargs @ linux-x86_64 +test.test_argparse.TestTypeUserDefined.test_successes_one_group_sysargs @ linux-x86_64 +test.test_argparse.TestWrappingMetavar.test_help_with_metavar @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_array.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_array.txt new file mode 100644 index 0000000000..ef892153ba --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_array.txt @@ -0,0 +1,731 @@ +test.test_array.ArrayReconstructorTest.test_error @ linux-x86_64 +test.test_array.ArrayReconstructorTest.test_numbers @ linux-x86_64 +test.test_array.ArrayReconstructorTest.test_unicode @ linux-x86_64 +test.test_array.ByteTest.test_add @ linux-x86_64 +test.test_array.ByteTest.test_assignment @ linux-x86_64 +test.test_array.ByteTest.test_buffer @ linux-x86_64 +test.test_array.ByteTest.test_buffer_info @ linux-x86_64 +test.test_array.ByteTest.test_bug_782369 @ linux-x86_64 +test.test_array.ByteTest.test_byteswap @ linux-x86_64 +test.test_array.ByteTest.test_cmp @ linux-x86_64 +test.test_array.ByteTest.test_constructor @ linux-x86_64 +test.test_array.ByteTest.test_constructor_with_iterable_argument @ linux-x86_64 +test.test_array.ByteTest.test_copy @ linux-x86_64 +test.test_array.ByteTest.test_count @ linux-x86_64 +test.test_array.ByteTest.test_coveritertraverse @ linux-x86_64 +test.test_array.ByteTest.test_create_from_bytes @ linux-x86_64 +test.test_array.ByteTest.test_deepcopy @ linux-x86_64 +test.test_array.ByteTest.test_delitem @ linux-x86_64 +test.test_array.ByteTest.test_delslice @ linux-x86_64 +test.test_array.ByteTest.test_exhausted_iterator @ linux-x86_64 +test.test_array.ByteTest.test_exhausted_reverse_iterator @ linux-x86_64 +test.test_array.ByteTest.test_extend @ linux-x86_64 +test.test_array.ByteTest.test_extended_getslice @ linux-x86_64 +test.test_array.ByteTest.test_extended_set_del_slice @ linux-x86_64 +test.test_array.ByteTest.test_extslice @ linux-x86_64 +test.test_array.ByteTest.test_filewrite @ linux-x86_64 +test.test_array.ByteTest.test_fromarray @ linux-x86_64 +test.test_array.ByteTest.test_frombytearray @ linux-x86_64 +test.test_array.ByteTest.test_fromfile_ioerror @ linux-x86_64 +test.test_array.ByteTest.test_getitem @ linux-x86_64 +test.test_array.ByteTest.test_getslice @ linux-x86_64 +test.test_array.ByteTest.test_iadd @ linux-x86_64 +test.test_array.ByteTest.test_imul @ linux-x86_64 +test.test_array.ByteTest.test_index @ linux-x86_64 +test.test_array.ByteTest.test_initialize_with_unicode @ linux-x86_64 +test.test_array.ByteTest.test_insert @ linux-x86_64 +test.test_array.ByteTest.test_iterationcontains @ linux-x86_64 +test.test_array.ByteTest.test_iterator_pickle @ linux-x86_64 +test.test_array.ByteTest.test_len @ linux-x86_64 +test.test_array.ByteTest.test_mul @ linux-x86_64 +test.test_array.ByteTest.test_overflow @ linux-x86_64 +test.test_array.ByteTest.test_pickle @ linux-x86_64 +test.test_array.ByteTest.test_pickle_for_empty_array @ linux-x86_64 +test.test_array.ByteTest.test_pop @ linux-x86_64 +test.test_array.ByteTest.test_reduce_ex @ linux-x86_64 +test.test_array.ByteTest.test_remove @ linux-x86_64 +test.test_array.ByteTest.test_repr @ linux-x86_64 +test.test_array.ByteTest.test_reverse @ linux-x86_64 +test.test_array.ByteTest.test_reverse_iterator @ linux-x86_64 +test.test_array.ByteTest.test_setitem @ linux-x86_64 +test.test_array.ByteTest.test_setslice @ linux-x86_64 +test.test_array.ByteTest.test_str @ linux-x86_64 +test.test_array.ByteTest.test_subclass_with_kwargs @ linux-x86_64 +test.test_array.ByteTest.test_subclassing @ linux-x86_64 +test.test_array.ByteTest.test_tofrombytes @ linux-x86_64 +test.test_array.ByteTest.test_tofromfile @ linux-x86_64 +test.test_array.ByteTest.test_tofromlist @ linux-x86_64 +test.test_array.ByteTest.test_type_error @ linux-x86_64 +test.test_array.DoubleTest.test_add @ linux-x86_64 +test.test_array.DoubleTest.test_alloc_overflow @ linux-x86_64 +test.test_array.DoubleTest.test_assignment @ linux-x86_64 +test.test_array.DoubleTest.test_buffer @ linux-x86_64 +test.test_array.DoubleTest.test_buffer_info @ linux-x86_64 +test.test_array.DoubleTest.test_bug_782369 @ linux-x86_64 +test.test_array.DoubleTest.test_byteswap @ linux-x86_64 +test.test_array.DoubleTest.test_cmp @ linux-x86_64 +test.test_array.DoubleTest.test_constructor @ linux-x86_64 +test.test_array.DoubleTest.test_constructor_with_iterable_argument @ linux-x86_64 +test.test_array.DoubleTest.test_copy @ linux-x86_64 +test.test_array.DoubleTest.test_count @ linux-x86_64 +test.test_array.DoubleTest.test_coveritertraverse @ linux-x86_64 +test.test_array.DoubleTest.test_create_from_bytes @ linux-x86_64 +test.test_array.DoubleTest.test_deepcopy @ linux-x86_64 +test.test_array.DoubleTest.test_delitem @ linux-x86_64 +test.test_array.DoubleTest.test_delslice @ linux-x86_64 +test.test_array.DoubleTest.test_exhausted_iterator @ linux-x86_64 +test.test_array.DoubleTest.test_exhausted_reverse_iterator @ linux-x86_64 +test.test_array.DoubleTest.test_extend @ linux-x86_64 +test.test_array.DoubleTest.test_extended_getslice @ linux-x86_64 +test.test_array.DoubleTest.test_extended_set_del_slice @ linux-x86_64 +test.test_array.DoubleTest.test_extslice @ linux-x86_64 +test.test_array.DoubleTest.test_filewrite @ linux-x86_64 +test.test_array.DoubleTest.test_fromarray @ linux-x86_64 +test.test_array.DoubleTest.test_frombytearray @ linux-x86_64 +test.test_array.DoubleTest.test_fromfile_ioerror @ linux-x86_64 +test.test_array.DoubleTest.test_getitem @ linux-x86_64 +test.test_array.DoubleTest.test_getslice @ linux-x86_64 +test.test_array.DoubleTest.test_iadd @ linux-x86_64 +test.test_array.DoubleTest.test_imul @ linux-x86_64 +test.test_array.DoubleTest.test_index @ linux-x86_64 +test.test_array.DoubleTest.test_initialize_with_unicode @ linux-x86_64 +test.test_array.DoubleTest.test_insert @ linux-x86_64 +test.test_array.DoubleTest.test_iterationcontains @ linux-x86_64 +test.test_array.DoubleTest.test_iterator_pickle @ linux-x86_64 +test.test_array.DoubleTest.test_len @ linux-x86_64 +test.test_array.DoubleTest.test_mul @ linux-x86_64 +test.test_array.DoubleTest.test_nan @ linux-x86_64 +test.test_array.DoubleTest.test_pickle @ linux-x86_64 +test.test_array.DoubleTest.test_pickle_for_empty_array @ linux-x86_64 +test.test_array.DoubleTest.test_pop @ linux-x86_64 +test.test_array.DoubleTest.test_reduce_ex @ linux-x86_64 +test.test_array.DoubleTest.test_remove @ linux-x86_64 +test.test_array.DoubleTest.test_repr @ linux-x86_64 +test.test_array.DoubleTest.test_reverse @ linux-x86_64 +test.test_array.DoubleTest.test_reverse_iterator @ linux-x86_64 +test.test_array.DoubleTest.test_setitem @ linux-x86_64 +test.test_array.DoubleTest.test_setslice @ linux-x86_64 +test.test_array.DoubleTest.test_str @ linux-x86_64 +test.test_array.DoubleTest.test_subclass_with_kwargs @ linux-x86_64 +test.test_array.DoubleTest.test_subclassing @ linux-x86_64 +test.test_array.DoubleTest.test_tofrombytes @ linux-x86_64 +test.test_array.DoubleTest.test_tofromfile @ linux-x86_64 +test.test_array.DoubleTest.test_tofromlist @ linux-x86_64 +test.test_array.FloatTest.test_add @ linux-x86_64 +test.test_array.FloatTest.test_assignment @ linux-x86_64 +test.test_array.FloatTest.test_buffer @ linux-x86_64 +test.test_array.FloatTest.test_buffer_info @ linux-x86_64 +test.test_array.FloatTest.test_bug_782369 @ linux-x86_64 +test.test_array.FloatTest.test_byteswap @ linux-x86_64 +test.test_array.FloatTest.test_cmp @ linux-x86_64 +test.test_array.FloatTest.test_constructor @ linux-x86_64 +test.test_array.FloatTest.test_constructor_with_iterable_argument @ linux-x86_64 +test.test_array.FloatTest.test_copy @ linux-x86_64 +test.test_array.FloatTest.test_count @ linux-x86_64 +test.test_array.FloatTest.test_coveritertraverse @ linux-x86_64 +test.test_array.FloatTest.test_create_from_bytes @ linux-x86_64 +test.test_array.FloatTest.test_deepcopy @ linux-x86_64 +test.test_array.FloatTest.test_delitem @ linux-x86_64 +test.test_array.FloatTest.test_delslice @ linux-x86_64 +test.test_array.FloatTest.test_exhausted_iterator @ linux-x86_64 +test.test_array.FloatTest.test_exhausted_reverse_iterator @ linux-x86_64 +test.test_array.FloatTest.test_extend @ linux-x86_64 +test.test_array.FloatTest.test_extended_getslice @ linux-x86_64 +test.test_array.FloatTest.test_extended_set_del_slice @ linux-x86_64 +test.test_array.FloatTest.test_extslice @ linux-x86_64 +test.test_array.FloatTest.test_filewrite @ linux-x86_64 +test.test_array.FloatTest.test_fromarray @ linux-x86_64 +test.test_array.FloatTest.test_frombytearray @ linux-x86_64 +test.test_array.FloatTest.test_fromfile_ioerror @ linux-x86_64 +test.test_array.FloatTest.test_getitem @ linux-x86_64 +test.test_array.FloatTest.test_getslice @ linux-x86_64 +test.test_array.FloatTest.test_iadd @ linux-x86_64 +test.test_array.FloatTest.test_imul @ linux-x86_64 +test.test_array.FloatTest.test_index @ linux-x86_64 +test.test_array.FloatTest.test_initialize_with_unicode @ linux-x86_64 +test.test_array.FloatTest.test_insert @ linux-x86_64 +test.test_array.FloatTest.test_iterationcontains @ linux-x86_64 +test.test_array.FloatTest.test_iterator_pickle @ linux-x86_64 +test.test_array.FloatTest.test_len @ linux-x86_64 +test.test_array.FloatTest.test_mul @ linux-x86_64 +test.test_array.FloatTest.test_nan @ linux-x86_64 +test.test_array.FloatTest.test_pickle @ linux-x86_64 +test.test_array.FloatTest.test_pickle_for_empty_array @ linux-x86_64 +test.test_array.FloatTest.test_pop @ linux-x86_64 +test.test_array.FloatTest.test_reduce_ex @ linux-x86_64 +test.test_array.FloatTest.test_remove @ linux-x86_64 +test.test_array.FloatTest.test_repr @ linux-x86_64 +test.test_array.FloatTest.test_reverse @ linux-x86_64 +test.test_array.FloatTest.test_reverse_iterator @ linux-x86_64 +test.test_array.FloatTest.test_setitem @ linux-x86_64 +test.test_array.FloatTest.test_setslice @ linux-x86_64 +test.test_array.FloatTest.test_str @ linux-x86_64 +test.test_array.FloatTest.test_subclass_with_kwargs @ linux-x86_64 +test.test_array.FloatTest.test_subclassing @ linux-x86_64 +test.test_array.FloatTest.test_tofrombytes @ linux-x86_64 +test.test_array.FloatTest.test_tofromfile @ linux-x86_64 +test.test_array.FloatTest.test_tofromlist @ linux-x86_64 +test.test_array.IntTest.test_add @ linux-x86_64 +test.test_array.IntTest.test_assignment @ linux-x86_64 +test.test_array.IntTest.test_buffer @ linux-x86_64 +test.test_array.IntTest.test_buffer_info @ linux-x86_64 +test.test_array.IntTest.test_bug_782369 @ linux-x86_64 +test.test_array.IntTest.test_byteswap @ linux-x86_64 +test.test_array.IntTest.test_cmp @ linux-x86_64 +test.test_array.IntTest.test_constructor @ linux-x86_64 +test.test_array.IntTest.test_constructor_with_iterable_argument @ linux-x86_64 +test.test_array.IntTest.test_copy @ linux-x86_64 +test.test_array.IntTest.test_count @ linux-x86_64 +test.test_array.IntTest.test_coveritertraverse @ linux-x86_64 +test.test_array.IntTest.test_create_from_bytes @ linux-x86_64 +test.test_array.IntTest.test_deepcopy @ linux-x86_64 +test.test_array.IntTest.test_delitem @ linux-x86_64 +test.test_array.IntTest.test_delslice @ linux-x86_64 +test.test_array.IntTest.test_exhausted_iterator @ linux-x86_64 +test.test_array.IntTest.test_exhausted_reverse_iterator @ linux-x86_64 +test.test_array.IntTest.test_extend @ linux-x86_64 +test.test_array.IntTest.test_extended_getslice @ linux-x86_64 +test.test_array.IntTest.test_extended_set_del_slice @ linux-x86_64 +test.test_array.IntTest.test_extslice @ linux-x86_64 +test.test_array.IntTest.test_filewrite @ linux-x86_64 +test.test_array.IntTest.test_fromarray @ linux-x86_64 +test.test_array.IntTest.test_frombytearray @ linux-x86_64 +test.test_array.IntTest.test_fromfile_ioerror @ linux-x86_64 +test.test_array.IntTest.test_getitem @ linux-x86_64 +test.test_array.IntTest.test_getslice @ linux-x86_64 +test.test_array.IntTest.test_iadd @ linux-x86_64 +test.test_array.IntTest.test_imul @ linux-x86_64 +test.test_array.IntTest.test_index @ linux-x86_64 +test.test_array.IntTest.test_initialize_with_unicode @ linux-x86_64 +test.test_array.IntTest.test_insert @ linux-x86_64 +test.test_array.IntTest.test_iterationcontains @ linux-x86_64 +test.test_array.IntTest.test_iterator_pickle @ linux-x86_64 +test.test_array.IntTest.test_len @ linux-x86_64 +test.test_array.IntTest.test_mul @ linux-x86_64 +test.test_array.IntTest.test_overflow @ linux-x86_64 +test.test_array.IntTest.test_pickle @ linux-x86_64 +test.test_array.IntTest.test_pickle_for_empty_array @ linux-x86_64 +test.test_array.IntTest.test_pop @ linux-x86_64 +test.test_array.IntTest.test_reduce_ex @ linux-x86_64 +test.test_array.IntTest.test_remove @ linux-x86_64 +test.test_array.IntTest.test_repr @ linux-x86_64 +test.test_array.IntTest.test_reverse @ linux-x86_64 +test.test_array.IntTest.test_reverse_iterator @ linux-x86_64 +test.test_array.IntTest.test_setitem @ linux-x86_64 +test.test_array.IntTest.test_setslice @ linux-x86_64 +test.test_array.IntTest.test_str @ linux-x86_64 +test.test_array.IntTest.test_subclass_with_kwargs @ linux-x86_64 +test.test_array.IntTest.test_subclassing @ linux-x86_64 +test.test_array.IntTest.test_tofrombytes @ linux-x86_64 +test.test_array.IntTest.test_tofromfile @ linux-x86_64 +test.test_array.IntTest.test_tofromlist @ linux-x86_64 +test.test_array.IntTest.test_type_error @ linux-x86_64 +test.test_array.LargeArrayTest.test_access @ linux-x86_64 +test.test_array.LargeArrayTest.test_append @ linux-x86_64 +test.test_array.LargeArrayTest.test_count @ linux-x86_64 +test.test_array.LargeArrayTest.test_example_data @ linux-x86_64 +test.test_array.LargeArrayTest.test_extend @ linux-x86_64 +test.test_array.LargeArrayTest.test_frombytes @ linux-x86_64 +test.test_array.LargeArrayTest.test_fromlist @ linux-x86_64 +test.test_array.LargeArrayTest.test_index @ linux-x86_64 +test.test_array.LargeArrayTest.test_insert @ linux-x86_64 +test.test_array.LargeArrayTest.test_pop @ linux-x86_64 +test.test_array.LargeArrayTest.test_remove @ linux-x86_64 +test.test_array.LargeArrayTest.test_reverse @ linux-x86_64 +test.test_array.LargeArrayTest.test_slice @ linux-x86_64 +test.test_array.LargeArrayTest.test_tolist @ linux-x86_64 +test.test_array.LongLongTest.test_add @ linux-x86_64 +test.test_array.LongLongTest.test_assignment @ linux-x86_64 +test.test_array.LongLongTest.test_buffer @ linux-x86_64 +test.test_array.LongLongTest.test_buffer_info @ linux-x86_64 +test.test_array.LongLongTest.test_bug_782369 @ linux-x86_64 +test.test_array.LongLongTest.test_byteswap @ linux-x86_64 +test.test_array.LongLongTest.test_cmp @ linux-x86_64 +test.test_array.LongLongTest.test_constructor @ linux-x86_64 +test.test_array.LongLongTest.test_constructor_with_iterable_argument @ linux-x86_64 +test.test_array.LongLongTest.test_copy @ linux-x86_64 +test.test_array.LongLongTest.test_count @ linux-x86_64 +test.test_array.LongLongTest.test_coveritertraverse @ linux-x86_64 +test.test_array.LongLongTest.test_create_from_bytes @ linux-x86_64 +test.test_array.LongLongTest.test_deepcopy @ linux-x86_64 +test.test_array.LongLongTest.test_delitem @ linux-x86_64 +test.test_array.LongLongTest.test_delslice @ linux-x86_64 +test.test_array.LongLongTest.test_exhausted_iterator @ linux-x86_64 +test.test_array.LongLongTest.test_exhausted_reverse_iterator @ linux-x86_64 +test.test_array.LongLongTest.test_extend @ linux-x86_64 +test.test_array.LongLongTest.test_extended_getslice @ linux-x86_64 +test.test_array.LongLongTest.test_extended_set_del_slice @ linux-x86_64 +test.test_array.LongLongTest.test_extslice @ linux-x86_64 +test.test_array.LongLongTest.test_filewrite @ linux-x86_64 +test.test_array.LongLongTest.test_fromarray @ linux-x86_64 +test.test_array.LongLongTest.test_frombytearray @ linux-x86_64 +test.test_array.LongLongTest.test_fromfile_ioerror @ linux-x86_64 +test.test_array.LongLongTest.test_getitem @ linux-x86_64 +test.test_array.LongLongTest.test_getslice @ linux-x86_64 +test.test_array.LongLongTest.test_iadd @ linux-x86_64 +test.test_array.LongLongTest.test_imul @ linux-x86_64 +test.test_array.LongLongTest.test_index @ linux-x86_64 +test.test_array.LongLongTest.test_initialize_with_unicode @ linux-x86_64 +test.test_array.LongLongTest.test_insert @ linux-x86_64 +test.test_array.LongLongTest.test_iterationcontains @ linux-x86_64 +test.test_array.LongLongTest.test_iterator_pickle @ linux-x86_64 +test.test_array.LongLongTest.test_len @ linux-x86_64 +test.test_array.LongLongTest.test_mul @ linux-x86_64 +test.test_array.LongLongTest.test_overflow @ linux-x86_64 +test.test_array.LongLongTest.test_pickle @ linux-x86_64 +test.test_array.LongLongTest.test_pickle_for_empty_array @ linux-x86_64 +test.test_array.LongLongTest.test_pop @ linux-x86_64 +test.test_array.LongLongTest.test_reduce_ex @ linux-x86_64 +test.test_array.LongLongTest.test_remove @ linux-x86_64 +test.test_array.LongLongTest.test_repr @ linux-x86_64 +test.test_array.LongLongTest.test_reverse @ linux-x86_64 +test.test_array.LongLongTest.test_reverse_iterator @ linux-x86_64 +test.test_array.LongLongTest.test_setitem @ linux-x86_64 +test.test_array.LongLongTest.test_setslice @ linux-x86_64 +test.test_array.LongLongTest.test_str @ linux-x86_64 +test.test_array.LongLongTest.test_subclass_with_kwargs @ linux-x86_64 +test.test_array.LongLongTest.test_subclassing @ linux-x86_64 +test.test_array.LongLongTest.test_tofrombytes @ linux-x86_64 +test.test_array.LongLongTest.test_tofromfile @ linux-x86_64 +test.test_array.LongLongTest.test_tofromlist @ linux-x86_64 +test.test_array.LongLongTest.test_type_error @ linux-x86_64 +test.test_array.LongTest.test_add @ linux-x86_64 +test.test_array.LongTest.test_assignment @ linux-x86_64 +test.test_array.LongTest.test_buffer @ linux-x86_64 +test.test_array.LongTest.test_buffer_info @ linux-x86_64 +test.test_array.LongTest.test_bug_782369 @ linux-x86_64 +test.test_array.LongTest.test_byteswap @ linux-x86_64 +test.test_array.LongTest.test_cmp @ linux-x86_64 +test.test_array.LongTest.test_constructor @ linux-x86_64 +test.test_array.LongTest.test_constructor_with_iterable_argument @ linux-x86_64 +test.test_array.LongTest.test_copy @ linux-x86_64 +test.test_array.LongTest.test_count @ linux-x86_64 +test.test_array.LongTest.test_coveritertraverse @ linux-x86_64 +test.test_array.LongTest.test_create_from_bytes @ linux-x86_64 +test.test_array.LongTest.test_deepcopy @ linux-x86_64 +test.test_array.LongTest.test_delitem @ linux-x86_64 +test.test_array.LongTest.test_delslice @ linux-x86_64 +test.test_array.LongTest.test_exhausted_iterator @ linux-x86_64 +test.test_array.LongTest.test_exhausted_reverse_iterator @ linux-x86_64 +test.test_array.LongTest.test_extend @ linux-x86_64 +test.test_array.LongTest.test_extended_getslice @ linux-x86_64 +test.test_array.LongTest.test_extended_set_del_slice @ linux-x86_64 +test.test_array.LongTest.test_extslice @ linux-x86_64 +test.test_array.LongTest.test_filewrite @ linux-x86_64 +test.test_array.LongTest.test_fromarray @ linux-x86_64 +test.test_array.LongTest.test_frombytearray @ linux-x86_64 +test.test_array.LongTest.test_fromfile_ioerror @ linux-x86_64 +test.test_array.LongTest.test_getitem @ linux-x86_64 +test.test_array.LongTest.test_getslice @ linux-x86_64 +test.test_array.LongTest.test_iadd @ linux-x86_64 +test.test_array.LongTest.test_imul @ linux-x86_64 +test.test_array.LongTest.test_index @ linux-x86_64 +test.test_array.LongTest.test_initialize_with_unicode @ linux-x86_64 +test.test_array.LongTest.test_insert @ linux-x86_64 +test.test_array.LongTest.test_iterationcontains @ linux-x86_64 +test.test_array.LongTest.test_iterator_pickle @ linux-x86_64 +test.test_array.LongTest.test_len @ linux-x86_64 +test.test_array.LongTest.test_mul @ linux-x86_64 +test.test_array.LongTest.test_overflow @ linux-x86_64 +test.test_array.LongTest.test_pickle @ linux-x86_64 +test.test_array.LongTest.test_pickle_for_empty_array @ linux-x86_64 +test.test_array.LongTest.test_pop @ linux-x86_64 +test.test_array.LongTest.test_reduce_ex @ linux-x86_64 +test.test_array.LongTest.test_remove @ linux-x86_64 +test.test_array.LongTest.test_repr @ linux-x86_64 +test.test_array.LongTest.test_reverse @ linux-x86_64 +test.test_array.LongTest.test_reverse_iterator @ linux-x86_64 +test.test_array.LongTest.test_setitem @ linux-x86_64 +test.test_array.LongTest.test_setslice @ linux-x86_64 +test.test_array.LongTest.test_str @ linux-x86_64 +test.test_array.LongTest.test_subclass_with_kwargs @ linux-x86_64 +test.test_array.LongTest.test_subclassing @ linux-x86_64 +test.test_array.LongTest.test_tofrombytes @ linux-x86_64 +test.test_array.LongTest.test_tofromfile @ linux-x86_64 +test.test_array.LongTest.test_tofromlist @ linux-x86_64 +test.test_array.LongTest.test_type_error @ linux-x86_64 +test.test_array.MiscTest.test_empty @ linux-x86_64 +test.test_array.ShortTest.test_add @ linux-x86_64 +test.test_array.ShortTest.test_assignment @ linux-x86_64 +test.test_array.ShortTest.test_buffer @ linux-x86_64 +test.test_array.ShortTest.test_buffer_info @ linux-x86_64 +test.test_array.ShortTest.test_bug_782369 @ linux-x86_64 +test.test_array.ShortTest.test_byteswap @ linux-x86_64 +test.test_array.ShortTest.test_cmp @ linux-x86_64 +test.test_array.ShortTest.test_constructor @ linux-x86_64 +test.test_array.ShortTest.test_constructor_with_iterable_argument @ linux-x86_64 +test.test_array.ShortTest.test_copy @ linux-x86_64 +test.test_array.ShortTest.test_count @ linux-x86_64 +test.test_array.ShortTest.test_coveritertraverse @ linux-x86_64 +test.test_array.ShortTest.test_create_from_bytes @ linux-x86_64 +test.test_array.ShortTest.test_deepcopy @ linux-x86_64 +test.test_array.ShortTest.test_delitem @ linux-x86_64 +test.test_array.ShortTest.test_delslice @ linux-x86_64 +test.test_array.ShortTest.test_exhausted_iterator @ linux-x86_64 +test.test_array.ShortTest.test_exhausted_reverse_iterator @ linux-x86_64 +test.test_array.ShortTest.test_extend @ linux-x86_64 +test.test_array.ShortTest.test_extended_getslice @ linux-x86_64 +test.test_array.ShortTest.test_extended_set_del_slice @ linux-x86_64 +test.test_array.ShortTest.test_extslice @ linux-x86_64 +test.test_array.ShortTest.test_filewrite @ linux-x86_64 +test.test_array.ShortTest.test_fromarray @ linux-x86_64 +test.test_array.ShortTest.test_frombytearray @ linux-x86_64 +test.test_array.ShortTest.test_fromfile_ioerror @ linux-x86_64 +test.test_array.ShortTest.test_getitem @ linux-x86_64 +test.test_array.ShortTest.test_getslice @ linux-x86_64 +test.test_array.ShortTest.test_iadd @ linux-x86_64 +test.test_array.ShortTest.test_imul @ linux-x86_64 +test.test_array.ShortTest.test_index @ linux-x86_64 +test.test_array.ShortTest.test_initialize_with_unicode @ linux-x86_64 +test.test_array.ShortTest.test_insert @ linux-x86_64 +test.test_array.ShortTest.test_iterationcontains @ linux-x86_64 +test.test_array.ShortTest.test_iterator_pickle @ linux-x86_64 +test.test_array.ShortTest.test_len @ linux-x86_64 +test.test_array.ShortTest.test_mul @ linux-x86_64 +test.test_array.ShortTest.test_overflow @ linux-x86_64 +test.test_array.ShortTest.test_pickle @ linux-x86_64 +test.test_array.ShortTest.test_pickle_for_empty_array @ linux-x86_64 +test.test_array.ShortTest.test_pop @ linux-x86_64 +test.test_array.ShortTest.test_reduce_ex @ linux-x86_64 +test.test_array.ShortTest.test_remove @ linux-x86_64 +test.test_array.ShortTest.test_repr @ linux-x86_64 +test.test_array.ShortTest.test_reverse @ linux-x86_64 +test.test_array.ShortTest.test_reverse_iterator @ linux-x86_64 +test.test_array.ShortTest.test_setitem @ linux-x86_64 +test.test_array.ShortTest.test_setslice @ linux-x86_64 +test.test_array.ShortTest.test_str @ linux-x86_64 +test.test_array.ShortTest.test_subclass_with_kwargs @ linux-x86_64 +test.test_array.ShortTest.test_subclassing @ linux-x86_64 +test.test_array.ShortTest.test_tofrombytes @ linux-x86_64 +test.test_array.ShortTest.test_tofromfile @ linux-x86_64 +test.test_array.ShortTest.test_tofromlist @ linux-x86_64 +test.test_array.ShortTest.test_type_error @ linux-x86_64 +test.test_array.UnicodeTest.test_add @ linux-x86_64 +test.test_array.UnicodeTest.test_buffer @ linux-x86_64 +test.test_array.UnicodeTest.test_buffer_info @ linux-x86_64 +test.test_array.UnicodeTest.test_bug_782369 @ linux-x86_64 +test.test_array.UnicodeTest.test_byteswap @ linux-x86_64 +test.test_array.UnicodeTest.test_cmp @ linux-x86_64 +test.test_array.UnicodeTest.test_constructor @ linux-x86_64 +test.test_array.UnicodeTest.test_constructor_with_iterable_argument @ linux-x86_64 +test.test_array.UnicodeTest.test_copy @ linux-x86_64 +test.test_array.UnicodeTest.test_count @ linux-x86_64 +test.test_array.UnicodeTest.test_coveritertraverse @ linux-x86_64 +test.test_array.UnicodeTest.test_create_from_bytes @ linux-x86_64 +test.test_array.UnicodeTest.test_deepcopy @ linux-x86_64 +test.test_array.UnicodeTest.test_delitem @ linux-x86_64 +test.test_array.UnicodeTest.test_exhausted_iterator @ linux-x86_64 +test.test_array.UnicodeTest.test_exhausted_reverse_iterator @ linux-x86_64 +test.test_array.UnicodeTest.test_extend @ linux-x86_64 +test.test_array.UnicodeTest.test_extended_getslice @ linux-x86_64 +test.test_array.UnicodeTest.test_extended_set_del_slice @ linux-x86_64 +test.test_array.UnicodeTest.test_filewrite @ linux-x86_64 +test.test_array.UnicodeTest.test_fromarray @ linux-x86_64 +test.test_array.UnicodeTest.test_fromfile_ioerror @ linux-x86_64 +test.test_array.UnicodeTest.test_getitem @ linux-x86_64 +test.test_array.UnicodeTest.test_getslice @ linux-x86_64 +test.test_array.UnicodeTest.test_iadd @ linux-x86_64 +test.test_array.UnicodeTest.test_imul @ linux-x86_64 +test.test_array.UnicodeTest.test_index @ linux-x86_64 +test.test_array.UnicodeTest.test_initialize_with_unicode @ linux-x86_64 +test.test_array.UnicodeTest.test_insert @ linux-x86_64 +test.test_array.UnicodeTest.test_issue17223 @ linux-x86_64 +test.test_array.UnicodeTest.test_iterator_pickle @ linux-x86_64 +test.test_array.UnicodeTest.test_len @ linux-x86_64 +test.test_array.UnicodeTest.test_mul @ linux-x86_64 +test.test_array.UnicodeTest.test_pickle @ linux-x86_64 +test.test_array.UnicodeTest.test_pickle_for_empty_array @ linux-x86_64 +test.test_array.UnicodeTest.test_pop @ linux-x86_64 +test.test_array.UnicodeTest.test_reduce_ex @ linux-x86_64 +test.test_array.UnicodeTest.test_remove @ linux-x86_64 +test.test_array.UnicodeTest.test_repr @ linux-x86_64 +test.test_array.UnicodeTest.test_reverse @ linux-x86_64 +test.test_array.UnicodeTest.test_reverse_iterator @ linux-x86_64 +test.test_array.UnicodeTest.test_setitem @ linux-x86_64 +test.test_array.UnicodeTest.test_setslice @ linux-x86_64 +test.test_array.UnicodeTest.test_str @ linux-x86_64 +test.test_array.UnicodeTest.test_subclass_with_kwargs @ linux-x86_64 +test.test_array.UnicodeTest.test_tofrombytes @ linux-x86_64 +test.test_array.UnicodeTest.test_tofromfile @ linux-x86_64 +test.test_array.UnicodeTest.test_tofromlist @ linux-x86_64 +test.test_array.UnicodeTest.test_unicode @ linux-x86_64 +test.test_array.UnsignedByteTest.test_add @ linux-x86_64 +test.test_array.UnsignedByteTest.test_assignment @ linux-x86_64 +test.test_array.UnsignedByteTest.test_buffer @ linux-x86_64 +test.test_array.UnsignedByteTest.test_buffer_info @ linux-x86_64 +test.test_array.UnsignedByteTest.test_bug_782369 @ linux-x86_64 +test.test_array.UnsignedByteTest.test_bytes_extend @ linux-x86_64 +test.test_array.UnsignedByteTest.test_byteswap @ linux-x86_64 +test.test_array.UnsignedByteTest.test_cmp @ linux-x86_64 +test.test_array.UnsignedByteTest.test_constructor @ linux-x86_64 +test.test_array.UnsignedByteTest.test_constructor_with_iterable_argument @ linux-x86_64 +test.test_array.UnsignedByteTest.test_copy @ linux-x86_64 +test.test_array.UnsignedByteTest.test_count @ linux-x86_64 +test.test_array.UnsignedByteTest.test_coveritertraverse @ linux-x86_64 +test.test_array.UnsignedByteTest.test_create_from_bytes @ linux-x86_64 +test.test_array.UnsignedByteTest.test_deepcopy @ linux-x86_64 +test.test_array.UnsignedByteTest.test_delitem @ linux-x86_64 +test.test_array.UnsignedByteTest.test_delslice @ linux-x86_64 +test.test_array.UnsignedByteTest.test_exhausted_iterator @ linux-x86_64 +test.test_array.UnsignedByteTest.test_exhausted_reverse_iterator @ linux-x86_64 +test.test_array.UnsignedByteTest.test_extend @ linux-x86_64 +test.test_array.UnsignedByteTest.test_extended_getslice @ linux-x86_64 +test.test_array.UnsignedByteTest.test_extended_set_del_slice @ linux-x86_64 +test.test_array.UnsignedByteTest.test_extslice @ linux-x86_64 +test.test_array.UnsignedByteTest.test_filewrite @ linux-x86_64 +test.test_array.UnsignedByteTest.test_fromarray @ linux-x86_64 +test.test_array.UnsignedByteTest.test_frombytearray @ linux-x86_64 +test.test_array.UnsignedByteTest.test_fromfile_ioerror @ linux-x86_64 +test.test_array.UnsignedByteTest.test_getitem @ linux-x86_64 +test.test_array.UnsignedByteTest.test_getslice @ linux-x86_64 +test.test_array.UnsignedByteTest.test_iadd @ linux-x86_64 +test.test_array.UnsignedByteTest.test_imul @ linux-x86_64 +test.test_array.UnsignedByteTest.test_index @ linux-x86_64 +test.test_array.UnsignedByteTest.test_initialize_with_unicode @ linux-x86_64 +test.test_array.UnsignedByteTest.test_insert @ linux-x86_64 +test.test_array.UnsignedByteTest.test_iterationcontains @ linux-x86_64 +test.test_array.UnsignedByteTest.test_iterator_pickle @ linux-x86_64 +test.test_array.UnsignedByteTest.test_len @ linux-x86_64 +test.test_array.UnsignedByteTest.test_mul @ linux-x86_64 +test.test_array.UnsignedByteTest.test_overflow @ linux-x86_64 +test.test_array.UnsignedByteTest.test_pickle @ linux-x86_64 +test.test_array.UnsignedByteTest.test_pickle_for_empty_array @ linux-x86_64 +test.test_array.UnsignedByteTest.test_pop @ linux-x86_64 +test.test_array.UnsignedByteTest.test_reduce_ex @ linux-x86_64 +test.test_array.UnsignedByteTest.test_remove @ linux-x86_64 +test.test_array.UnsignedByteTest.test_repr @ linux-x86_64 +test.test_array.UnsignedByteTest.test_reverse @ linux-x86_64 +test.test_array.UnsignedByteTest.test_reverse_iterator @ linux-x86_64 +test.test_array.UnsignedByteTest.test_setitem @ linux-x86_64 +test.test_array.UnsignedByteTest.test_setslice @ linux-x86_64 +test.test_array.UnsignedByteTest.test_str @ linux-x86_64 +test.test_array.UnsignedByteTest.test_subclass_with_kwargs @ linux-x86_64 +test.test_array.UnsignedByteTest.test_subclassing @ linux-x86_64 +test.test_array.UnsignedByteTest.test_tofrombytes @ linux-x86_64 +test.test_array.UnsignedByteTest.test_tofromfile @ linux-x86_64 +test.test_array.UnsignedByteTest.test_tofromlist @ linux-x86_64 +test.test_array.UnsignedByteTest.test_type_error @ linux-x86_64 +test.test_array.UnsignedIntTest.test_add @ linux-x86_64 +test.test_array.UnsignedIntTest.test_assignment @ linux-x86_64 +test.test_array.UnsignedIntTest.test_buffer @ linux-x86_64 +test.test_array.UnsignedIntTest.test_buffer_info @ linux-x86_64 +test.test_array.UnsignedIntTest.test_bug_782369 @ linux-x86_64 +test.test_array.UnsignedIntTest.test_bytes_extend @ linux-x86_64 +test.test_array.UnsignedIntTest.test_byteswap @ linux-x86_64 +test.test_array.UnsignedIntTest.test_cmp @ linux-x86_64 +test.test_array.UnsignedIntTest.test_constructor @ linux-x86_64 +test.test_array.UnsignedIntTest.test_constructor_with_iterable_argument @ linux-x86_64 +test.test_array.UnsignedIntTest.test_copy @ linux-x86_64 +test.test_array.UnsignedIntTest.test_count @ linux-x86_64 +test.test_array.UnsignedIntTest.test_coveritertraverse @ linux-x86_64 +test.test_array.UnsignedIntTest.test_create_from_bytes @ linux-x86_64 +test.test_array.UnsignedIntTest.test_deepcopy @ linux-x86_64 +test.test_array.UnsignedIntTest.test_delitem @ linux-x86_64 +test.test_array.UnsignedIntTest.test_delslice @ linux-x86_64 +test.test_array.UnsignedIntTest.test_exhausted_iterator @ linux-x86_64 +test.test_array.UnsignedIntTest.test_exhausted_reverse_iterator @ linux-x86_64 +test.test_array.UnsignedIntTest.test_extend @ linux-x86_64 +test.test_array.UnsignedIntTest.test_extended_getslice @ linux-x86_64 +test.test_array.UnsignedIntTest.test_extended_set_del_slice @ linux-x86_64 +test.test_array.UnsignedIntTest.test_extslice @ linux-x86_64 +test.test_array.UnsignedIntTest.test_filewrite @ linux-x86_64 +test.test_array.UnsignedIntTest.test_fromarray @ linux-x86_64 +test.test_array.UnsignedIntTest.test_frombytearray @ linux-x86_64 +test.test_array.UnsignedIntTest.test_fromfile_ioerror @ linux-x86_64 +test.test_array.UnsignedIntTest.test_getitem @ linux-x86_64 +test.test_array.UnsignedIntTest.test_getslice @ linux-x86_64 +test.test_array.UnsignedIntTest.test_iadd @ linux-x86_64 +test.test_array.UnsignedIntTest.test_imul @ linux-x86_64 +test.test_array.UnsignedIntTest.test_index @ linux-x86_64 +test.test_array.UnsignedIntTest.test_initialize_with_unicode @ linux-x86_64 +test.test_array.UnsignedIntTest.test_insert @ linux-x86_64 +test.test_array.UnsignedIntTest.test_iterationcontains @ linux-x86_64 +test.test_array.UnsignedIntTest.test_iterator_pickle @ linux-x86_64 +test.test_array.UnsignedIntTest.test_len @ linux-x86_64 +test.test_array.UnsignedIntTest.test_mul @ linux-x86_64 +test.test_array.UnsignedIntTest.test_overflow @ linux-x86_64 +test.test_array.UnsignedIntTest.test_pickle @ linux-x86_64 +test.test_array.UnsignedIntTest.test_pickle_for_empty_array @ linux-x86_64 +test.test_array.UnsignedIntTest.test_pop @ linux-x86_64 +test.test_array.UnsignedIntTest.test_reduce_ex @ linux-x86_64 +test.test_array.UnsignedIntTest.test_remove @ linux-x86_64 +test.test_array.UnsignedIntTest.test_repr @ linux-x86_64 +test.test_array.UnsignedIntTest.test_reverse @ linux-x86_64 +test.test_array.UnsignedIntTest.test_reverse_iterator @ linux-x86_64 +test.test_array.UnsignedIntTest.test_setitem @ linux-x86_64 +test.test_array.UnsignedIntTest.test_setslice @ linux-x86_64 +test.test_array.UnsignedIntTest.test_str @ linux-x86_64 +test.test_array.UnsignedIntTest.test_subclass_with_kwargs @ linux-x86_64 +test.test_array.UnsignedIntTest.test_subclassing @ linux-x86_64 +test.test_array.UnsignedIntTest.test_tofrombytes @ linux-x86_64 +test.test_array.UnsignedIntTest.test_tofromfile @ linux-x86_64 +test.test_array.UnsignedIntTest.test_tofromlist @ linux-x86_64 +test.test_array.UnsignedIntTest.test_type_error @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_add @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_assignment @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_buffer @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_buffer_info @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_bug_782369 @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_bytes_extend @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_byteswap @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_cmp @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_constructor @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_constructor_with_iterable_argument @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_copy @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_count @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_coveritertraverse @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_create_from_bytes @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_deepcopy @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_delitem @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_delslice @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_exhausted_iterator @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_exhausted_reverse_iterator @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_extend @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_extended_getslice @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_extended_set_del_slice @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_extslice @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_filewrite @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_fromarray @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_frombytearray @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_fromfile_ioerror @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_getitem @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_getslice @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_iadd @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_imul @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_index @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_initialize_with_unicode @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_insert @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_iterationcontains @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_iterator_pickle @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_len @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_mul @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_overflow @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_pickle @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_pickle_for_empty_array @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_pop @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_reduce_ex @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_remove @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_repr @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_reverse @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_reverse_iterator @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_setitem @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_setslice @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_str @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_subclass_with_kwargs @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_subclassing @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_tofrombytes @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_tofromfile @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_tofromlist @ linux-x86_64 +test.test_array.UnsignedLongLongTest.test_type_error @ linux-x86_64 +test.test_array.UnsignedLongTest.test_add @ linux-x86_64 +test.test_array.UnsignedLongTest.test_assignment @ linux-x86_64 +test.test_array.UnsignedLongTest.test_buffer @ linux-x86_64 +test.test_array.UnsignedLongTest.test_buffer_info @ linux-x86_64 +test.test_array.UnsignedLongTest.test_bug_782369 @ linux-x86_64 +test.test_array.UnsignedLongTest.test_bytes_extend @ linux-x86_64 +test.test_array.UnsignedLongTest.test_byteswap @ linux-x86_64 +test.test_array.UnsignedLongTest.test_cmp @ linux-x86_64 +test.test_array.UnsignedLongTest.test_constructor @ linux-x86_64 +test.test_array.UnsignedLongTest.test_constructor_with_iterable_argument @ linux-x86_64 +test.test_array.UnsignedLongTest.test_copy @ linux-x86_64 +test.test_array.UnsignedLongTest.test_count @ linux-x86_64 +test.test_array.UnsignedLongTest.test_coveritertraverse @ linux-x86_64 +test.test_array.UnsignedLongTest.test_create_from_bytes @ linux-x86_64 +test.test_array.UnsignedLongTest.test_deepcopy @ linux-x86_64 +test.test_array.UnsignedLongTest.test_delitem @ linux-x86_64 +test.test_array.UnsignedLongTest.test_delslice @ linux-x86_64 +test.test_array.UnsignedLongTest.test_exhausted_iterator @ linux-x86_64 +test.test_array.UnsignedLongTest.test_exhausted_reverse_iterator @ linux-x86_64 +test.test_array.UnsignedLongTest.test_extend @ linux-x86_64 +test.test_array.UnsignedLongTest.test_extended_getslice @ linux-x86_64 +test.test_array.UnsignedLongTest.test_extended_set_del_slice @ linux-x86_64 +test.test_array.UnsignedLongTest.test_extslice @ linux-x86_64 +test.test_array.UnsignedLongTest.test_filewrite @ linux-x86_64 +test.test_array.UnsignedLongTest.test_fromarray @ linux-x86_64 +test.test_array.UnsignedLongTest.test_frombytearray @ linux-x86_64 +test.test_array.UnsignedLongTest.test_fromfile_ioerror @ linux-x86_64 +test.test_array.UnsignedLongTest.test_getitem @ linux-x86_64 +test.test_array.UnsignedLongTest.test_getslice @ linux-x86_64 +test.test_array.UnsignedLongTest.test_iadd @ linux-x86_64 +test.test_array.UnsignedLongTest.test_imul @ linux-x86_64 +test.test_array.UnsignedLongTest.test_index @ linux-x86_64 +test.test_array.UnsignedLongTest.test_initialize_with_unicode @ linux-x86_64 +test.test_array.UnsignedLongTest.test_insert @ linux-x86_64 +test.test_array.UnsignedLongTest.test_iterationcontains @ linux-x86_64 +test.test_array.UnsignedLongTest.test_iterator_pickle @ linux-x86_64 +test.test_array.UnsignedLongTest.test_len @ linux-x86_64 +test.test_array.UnsignedLongTest.test_mul @ linux-x86_64 +test.test_array.UnsignedLongTest.test_overflow @ linux-x86_64 +test.test_array.UnsignedLongTest.test_pickle @ linux-x86_64 +test.test_array.UnsignedLongTest.test_pickle_for_empty_array @ linux-x86_64 +test.test_array.UnsignedLongTest.test_pop @ linux-x86_64 +test.test_array.UnsignedLongTest.test_reduce_ex @ linux-x86_64 +test.test_array.UnsignedLongTest.test_remove @ linux-x86_64 +test.test_array.UnsignedLongTest.test_repr @ linux-x86_64 +test.test_array.UnsignedLongTest.test_reverse @ linux-x86_64 +test.test_array.UnsignedLongTest.test_reverse_iterator @ linux-x86_64 +test.test_array.UnsignedLongTest.test_setitem @ linux-x86_64 +test.test_array.UnsignedLongTest.test_setslice @ linux-x86_64 +test.test_array.UnsignedLongTest.test_str @ linux-x86_64 +test.test_array.UnsignedLongTest.test_subclass_with_kwargs @ linux-x86_64 +test.test_array.UnsignedLongTest.test_subclassing @ linux-x86_64 +test.test_array.UnsignedLongTest.test_tofrombytes @ linux-x86_64 +test.test_array.UnsignedLongTest.test_tofromfile @ linux-x86_64 +test.test_array.UnsignedLongTest.test_tofromlist @ linux-x86_64 +test.test_array.UnsignedLongTest.test_type_error @ linux-x86_64 +test.test_array.UnsignedShortTest.test_add @ linux-x86_64 +test.test_array.UnsignedShortTest.test_assignment @ linux-x86_64 +test.test_array.UnsignedShortTest.test_buffer @ linux-x86_64 +test.test_array.UnsignedShortTest.test_buffer_info @ linux-x86_64 +test.test_array.UnsignedShortTest.test_bug_782369 @ linux-x86_64 +test.test_array.UnsignedShortTest.test_bytes_extend @ linux-x86_64 +test.test_array.UnsignedShortTest.test_byteswap @ linux-x86_64 +test.test_array.UnsignedShortTest.test_cmp @ linux-x86_64 +test.test_array.UnsignedShortTest.test_constructor @ linux-x86_64 +test.test_array.UnsignedShortTest.test_constructor_with_iterable_argument @ linux-x86_64 +test.test_array.UnsignedShortTest.test_copy @ linux-x86_64 +test.test_array.UnsignedShortTest.test_count @ linux-x86_64 +test.test_array.UnsignedShortTest.test_coveritertraverse @ linux-x86_64 +test.test_array.UnsignedShortTest.test_create_from_bytes @ linux-x86_64 +test.test_array.UnsignedShortTest.test_deepcopy @ linux-x86_64 +test.test_array.UnsignedShortTest.test_delitem @ linux-x86_64 +test.test_array.UnsignedShortTest.test_delslice @ linux-x86_64 +test.test_array.UnsignedShortTest.test_exhausted_iterator @ linux-x86_64 +test.test_array.UnsignedShortTest.test_exhausted_reverse_iterator @ linux-x86_64 +test.test_array.UnsignedShortTest.test_extend @ linux-x86_64 +test.test_array.UnsignedShortTest.test_extended_getslice @ linux-x86_64 +test.test_array.UnsignedShortTest.test_extended_set_del_slice @ linux-x86_64 +test.test_array.UnsignedShortTest.test_extslice @ linux-x86_64 +test.test_array.UnsignedShortTest.test_filewrite @ linux-x86_64 +test.test_array.UnsignedShortTest.test_fromarray @ linux-x86_64 +test.test_array.UnsignedShortTest.test_frombytearray @ linux-x86_64 +test.test_array.UnsignedShortTest.test_fromfile_ioerror @ linux-x86_64 +test.test_array.UnsignedShortTest.test_getitem @ linux-x86_64 +test.test_array.UnsignedShortTest.test_getslice @ linux-x86_64 +test.test_array.UnsignedShortTest.test_iadd @ linux-x86_64 +test.test_array.UnsignedShortTest.test_imul @ linux-x86_64 +test.test_array.UnsignedShortTest.test_index @ linux-x86_64 +test.test_array.UnsignedShortTest.test_initialize_with_unicode @ linux-x86_64 +test.test_array.UnsignedShortTest.test_insert @ linux-x86_64 +test.test_array.UnsignedShortTest.test_iterationcontains @ linux-x86_64 +test.test_array.UnsignedShortTest.test_iterator_pickle @ linux-x86_64 +test.test_array.UnsignedShortTest.test_len @ linux-x86_64 +test.test_array.UnsignedShortTest.test_mul @ linux-x86_64 +test.test_array.UnsignedShortTest.test_overflow @ linux-x86_64 +test.test_array.UnsignedShortTest.test_pickle @ linux-x86_64 +test.test_array.UnsignedShortTest.test_pickle_for_empty_array @ linux-x86_64 +test.test_array.UnsignedShortTest.test_pop @ linux-x86_64 +test.test_array.UnsignedShortTest.test_reduce_ex @ linux-x86_64 +test.test_array.UnsignedShortTest.test_remove @ linux-x86_64 +test.test_array.UnsignedShortTest.test_repr @ linux-x86_64 +test.test_array.UnsignedShortTest.test_reverse @ linux-x86_64 +test.test_array.UnsignedShortTest.test_reverse_iterator @ linux-x86_64 +test.test_array.UnsignedShortTest.test_setitem @ linux-x86_64 +test.test_array.UnsignedShortTest.test_setslice @ linux-x86_64 +test.test_array.UnsignedShortTest.test_str @ linux-x86_64 +test.test_array.UnsignedShortTest.test_subclass_with_kwargs @ linux-x86_64 +test.test_array.UnsignedShortTest.test_subclassing @ linux-x86_64 +test.test_array.UnsignedShortTest.test_tofrombytes @ linux-x86_64 +test.test_array.UnsignedShortTest.test_tofromfile @ linux-x86_64 +test.test_array.UnsignedShortTest.test_tofromlist @ linux-x86_64 +test.test_array.UnsignedShortTest.test_type_error @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ast.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ast.txt new file mode 100644 index 0000000000..0ea7b15035 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ast.txt @@ -0,0 +1,136 @@ +test.test_ast.ASTHelpers_Test.test_bad_integer @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_copy_location @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_dump @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_dump_incomplete @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_dump_indent @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_elif_stmt_start_position @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_elif_stmt_start_position_with_else @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_fix_missing_locations @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_get_docstring @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_get_docstring_none @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_increment_lineno @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_increment_lineno_on_module @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_iter_child_nodes @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_iter_fields @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_level_as_none @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_literal_eval @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_literal_eval_complex @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_literal_eval_malformed_dict_nodes @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_literal_eval_malformed_lineno @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_literal_eval_syntax_errors @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_literal_eval_trailing_ws @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_multi_line_docstring_col_offset_and_lineno_issue16806 @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_parse @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_parse_in_error @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_recursion_direct @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_recursion_indirect @ linux-x86_64 +test.test_ast.ASTHelpers_Test.test_starred_expr_end_position_within_call @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_assert @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_assign @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_attribute @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_augassign @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_boolop @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_call @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_classdef @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_compare @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_delete @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_dict @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_dictcomp @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_expr @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_for @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_funcdef @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_generatorexp @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_global @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_if @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_ifexp @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_import @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_importfrom @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_lambda @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_list @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_listcomp @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_match_validation_pattern @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_module @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_nameconstant @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_nonlocal @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_num @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_raise @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_set @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_setcomp @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_starred @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_subscript @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_try @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_try_star @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_tuple @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_unaryop @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_while @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_with @ linux-x86_64 +test.test_ast.ASTValidatorTests.test_yield @ linux-x86_64 +test.test_ast.AST_Tests.test_AST_garbage_collection @ linux-x86_64 +test.test_ast.AST_Tests.test_AST_objects @ linux-x86_64 +test.test_ast.AST_Tests.test_alias @ linux-x86_64 +test.test_ast.AST_Tests.test_arguments @ linux-x86_64 +test.test_ast.AST_Tests.test_assignment_expression_feature_version @ linux-x86_64 +test.test_ast.AST_Tests.test_ast_asdl_signature @ linux-x86_64 +test.test_ast.AST_Tests.test_ast_validation @ linux-x86_64 +test.test_ast.AST_Tests.test_base_classes @ linux-x86_64 +test.test_ast.AST_Tests.test_classattrs @ linux-x86_64 +test.test_ast.AST_Tests.test_compilation_of_ast_nodes_with_default_end_position_values @ linux-x86_64 +test.test_ast.AST_Tests.test_constant_as_name @ linux-x86_64 +test.test_ast.AST_Tests.test_debug_f_string_feature_version @ linux-x86_64 +test.test_ast.AST_Tests.test_empty_yield_from @ linux-x86_64 +test.test_ast.AST_Tests.test_field_attr_existence @ linux-x86_64 +test.test_ast.AST_Tests.test_field_attr_writable @ linux-x86_64 +test.test_ast.AST_Tests.test_from_import @ linux-x86_64 +test.test_ast.AST_Tests.test_invalid_constant @ linux-x86_64 +test.test_ast.AST_Tests.test_invalid_identifier @ linux-x86_64 +test.test_ast.AST_Tests.test_invalid_sum @ linux-x86_64 +test.test_ast.AST_Tests.test_isinstance @ linux-x86_64 +test.test_ast.AST_Tests.test_issue18374_binop_col_offset @ linux-x86_64 +test.test_ast.AST_Tests.test_issue39579_dotted_name_end_col_offset @ linux-x86_64 +test.test_ast.AST_Tests.test_module @ linux-x86_64 +test.test_ast.AST_Tests.test_no_fields @ linux-x86_64 +test.test_ast.AST_Tests.test_nodeclasses @ linux-x86_64 +test.test_ast.AST_Tests.test_non_interned_future_from_ast @ linux-x86_64 +test.test_ast.AST_Tests.test_none_checks @ linux-x86_64 +test.test_ast.AST_Tests.test_null_bytes @ linux-x86_64 +test.test_ast.AST_Tests.test_parenthesized_with_feature_version @ linux-x86_64 +test.test_ast.AST_Tests.test_pickling @ linux-x86_64 +test.test_ast.AST_Tests.test_positional_only_feature_version @ linux-x86_64 +test.test_ast.AST_Tests.test_precedence_enum @ linux-x86_64 +test.test_ast.AST_Tests.test_realtype @ linux-x86_64 +test.test_ast.AST_Tests.test_slice @ linux-x86_64 +test.test_ast.AST_Tests.test_snippets @ linux-x86_64 +test.test_ast.AST_Tests.test_subclasses @ linux-x86_64 +test.test_ast.ConstantTests.test_assign_to_constant @ linux-x86_64 +test.test_ast.ConstantTests.test_get_docstring @ linux-x86_64 +test.test_ast.ConstantTests.test_literal_eval @ linux-x86_64 +test.test_ast.ConstantTests.test_string_kind @ linux-x86_64 +test.test_ast.ConstantTests.test_validation @ linux-x86_64 +test.test_ast.ConstantTests.test_values @ linux-x86_64 +test.test_ast.EndPositionTests.test_attribute_spaces @ linux-x86_64 +test.test_ast.EndPositionTests.test_binop @ linux-x86_64 +test.test_ast.EndPositionTests.test_boolop @ linux-x86_64 +test.test_ast.EndPositionTests.test_call @ linux-x86_64 +test.test_ast.EndPositionTests.test_call_noargs @ linux-x86_64 +test.test_ast.EndPositionTests.test_class_def @ linux-x86_64 +test.test_ast.EndPositionTests.test_class_kw @ linux-x86_64 +test.test_ast.EndPositionTests.test_comprehensions @ linux-x86_64 +test.test_ast.EndPositionTests.test_continued_str @ linux-x86_64 +test.test_ast.EndPositionTests.test_displays @ linux-x86_64 +test.test_ast.EndPositionTests.test_fstring @ linux-x86_64 +test.test_ast.EndPositionTests.test_fstring_multi_line @ linux-x86_64 +test.test_ast.EndPositionTests.test_func_def @ linux-x86_64 +test.test_ast.EndPositionTests.test_import_from_multi_line @ linux-x86_64 +test.test_ast.EndPositionTests.test_lambda @ linux-x86_64 +test.test_ast.EndPositionTests.test_multi_line_str @ linux-x86_64 +test.test_ast.EndPositionTests.test_redundant_parenthesis @ linux-x86_64 +test.test_ast.EndPositionTests.test_slices @ linux-x86_64 +test.test_ast.EndPositionTests.test_source_segment_endings @ linux-x86_64 +test.test_ast.EndPositionTests.test_source_segment_missing_info @ linux-x86_64 +test.test_ast.EndPositionTests.test_source_segment_multi @ linux-x86_64 +test.test_ast.EndPositionTests.test_source_segment_tabs @ linux-x86_64 +test.test_ast.EndPositionTests.test_suites @ linux-x86_64 +test.test_ast.EndPositionTests.test_trailers_with_redundant_parenthesis @ linux-x86_64 +test.test_ast.EndPositionTests.test_tuples @ linux-x86_64 +test.test_ast.EndPositionTests.test_yield_await @ linux-x86_64 +test.test_ast.NodeVisitorTests.test_old_constant_nodes @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_asynchat.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_asynchat.txt new file mode 100644 index 0000000000..28ec009e04 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_asynchat.txt @@ -0,0 +1,25 @@ +test.test_asynchat.TestAsynchat.test_close_when_done @ linux-x86_64 +test.test_asynchat.TestAsynchat.test_empty_line @ linux-x86_64 +test.test_asynchat.TestAsynchat.test_line_terminator1 @ linux-x86_64 +test.test_asynchat.TestAsynchat.test_line_terminator2 @ linux-x86_64 +test.test_asynchat.TestAsynchat.test_line_terminator3 @ linux-x86_64 +test.test_asynchat.TestAsynchat.test_none_terminator @ linux-x86_64 +test.test_asynchat.TestAsynchat.test_numeric_terminator1 @ linux-x86_64 +test.test_asynchat.TestAsynchat.test_numeric_terminator2 @ linux-x86_64 +test.test_asynchat.TestAsynchat.test_push @ linux-x86_64 +test.test_asynchat.TestAsynchat.test_simple_producer @ linux-x86_64 +test.test_asynchat.TestAsynchat.test_string_producer @ linux-x86_64 +test.test_asynchat.TestAsynchatMocked.test_blockingioerror @ linux-x86_64 +test.test_asynchat.TestAsynchat_WithPoll.test_close_when_done @ linux-x86_64 +test.test_asynchat.TestAsynchat_WithPoll.test_empty_line @ linux-x86_64 +test.test_asynchat.TestAsynchat_WithPoll.test_line_terminator1 @ linux-x86_64 +test.test_asynchat.TestAsynchat_WithPoll.test_line_terminator2 @ linux-x86_64 +test.test_asynchat.TestAsynchat_WithPoll.test_line_terminator3 @ linux-x86_64 +test.test_asynchat.TestAsynchat_WithPoll.test_none_terminator @ linux-x86_64 +test.test_asynchat.TestAsynchat_WithPoll.test_numeric_terminator1 @ linux-x86_64 +test.test_asynchat.TestAsynchat_WithPoll.test_numeric_terminator2 @ linux-x86_64 +test.test_asynchat.TestAsynchat_WithPoll.test_push @ linux-x86_64 +test.test_asynchat.TestAsynchat_WithPoll.test_simple_producer @ linux-x86_64 +test.test_asynchat.TestAsynchat_WithPoll.test_string_producer @ linux-x86_64 +test.test_asynchat.TestHelperFunctions.test_find_prefix_at_end @ linux-x86_64 +test.test_asynchat.TestNotConnected.test_disallow_negative_terminator @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_asyncio.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_asyncio.txt new file mode 100644 index 0000000000..e38bc5688a --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_asyncio.txt @@ -0,0 +1,657 @@ +test.test_asyncio.test_base_events.BaseEventLoopTests.test__add_callback_cancelled_handle @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test__add_callback_handle @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test__run_once @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test__run_once_cancelled_event_cleanup @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test__run_once_schedule_handle @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_call_later @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_call_later_negative_delays @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_call_soon @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_call_soon_non_callable @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_check_thread @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_close @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_create_named_task_with_custom_factory @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_create_named_task_with_default_factory @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_create_task @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_create_task_error_closes_coro @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_default_exc_handler_broken @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_default_exc_handler_callback @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_not_implemented @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_run_forever_keyboard_interrupt @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_run_forever_pre_stopped @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_run_once @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_run_until_complete_baseexception @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_run_until_complete_loop @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_run_until_complete_type_error @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_set_debug @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_set_default_executor @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_set_default_executor_error @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_set_exc_handler_broken @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_set_exc_handler_custom @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_set_exc_handler_invalid @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_set_task_factory @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_set_task_factory_invalid @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_single_selecter_event_callback_after_stopping @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_subprocess_exec_invalid_args @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_subprocess_shell_invalid_args @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopTests.test_time_and_call_at @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_accept_connection_exception @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_accept_connection_retry @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_call_coroutine @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_connection_host_port_sock @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_connection_no_host_port_sock @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_connection_no_ssl_server_hostname_errors @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_connection_ssl_server_hostname_errors @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_connection_ssl_timeout_for_plain_socket @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_connection_wrong_sock @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_datagram_endpoint_addr_error @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_datagram_endpoint_noaddr_nofamily @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_datagram_endpoint_setblk_err @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_datagram_endpoint_sock @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_datagram_endpoint_sock_sockopts @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_datagram_endpoint_wrong_sock @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_server_host_port_sock @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_server_no_host_port_sock @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_server_ssl_timeout_for_plain_socket @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_server_wrong_sock @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_getnameinfo @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventTests.test_ipaddr_info @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventTests.test_ipaddr_info_no_inet_pton @ linux-x86_64 +test.test_asyncio.test_base_events.BaseEventTests.test_port_parameter_types @ linux-x86_64 +test.test_asyncio.test_base_events.BaseLoopSockSendfileTests.test_blocking_socket @ linux-x86_64 +test.test_asyncio.test_base_events.BaseLoopSockSendfileTests.test_negative_count @ linux-x86_64 +test.test_asyncio.test_base_events.BaseLoopSockSendfileTests.test_negative_offset @ linux-x86_64 +test.test_asyncio.test_base_events.BaseLoopSockSendfileTests.test_nonbinary_file @ linux-x86_64 +test.test_asyncio.test_base_events.BaseLoopSockSendfileTests.test_nonstream_socket @ linux-x86_64 +test.test_asyncio.test_base_events.BaseLoopSockSendfileTests.test_notint_count @ linux-x86_64 +test.test_asyncio.test_base_events.BaseLoopSockSendfileTests.test_notint_offset @ linux-x86_64 +test.test_asyncio.test_base_events.RunningLoopTests.test_running_loop_within_a_loop @ linux-x86_64 +test.test_asyncio.test_base_events.TestSelectorUtils.test_set_nodelay @ linux-x86_64 +test.test_asyncio.test_events.AbstractEventLoopTests.test_not_implemented @ linux-x86_64 +test.test_asyncio.test_events.HandleTests.test_callback_with_exception @ linux-x86_64 +test.test_asyncio.test_events.HandleTests.test_coroutine_like_object_debug_formatting @ linux-x86_64 +test.test_asyncio.test_events.HandleTests.test_handle @ linux-x86_64 +test.test_asyncio.test_events.HandleTests.test_handle_repr @ linux-x86_64 +test.test_asyncio.test_events.HandleTests.test_handle_repr_debug @ linux-x86_64 +test.test_asyncio.test_events.HandleTests.test_handle_source_traceback @ linux-x86_64 +test.test_asyncio.test_events.HandleTests.test_handle_weakref @ linux-x86_64 +test.test_asyncio.test_events.PolicyTests.test_event_loop_policy @ linux-x86_64 +test.test_asyncio.test_events.PolicyTests.test_get_event_loop @ linux-x86_64 +test.test_asyncio.test_events.PolicyTests.test_get_event_loop_after_set_none @ linux-x86_64 +test.test_asyncio.test_events.PolicyTests.test_get_event_loop_calls_set_event_loop @ linux-x86_64 +test.test_asyncio.test_events.PolicyTests.test_get_event_loop_policy @ linux-x86_64 +test.test_asyncio.test_events.PolicyTests.test_get_event_loop_thread @ linux-x86_64 +test.test_asyncio.test_events.PolicyTests.test_new_event_loop @ linux-x86_64 +test.test_asyncio.test_events.PolicyTests.test_set_event_loop @ linux-x86_64 +test.test_asyncio.test_events.PolicyTests.test_set_event_loop_policy @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_add_fds_after_closing @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_bidirectional_pty @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_call_later @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_call_soon @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_call_soon_threadsafe @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_call_soon_threadsafe_same_thread @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_close @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_close_running_event_loop @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_internal_fds @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_prompt_cancellation @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_reader_callback @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_remove_fds_after_closing @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_run_in_executor @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_run_in_executor_cancel @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_run_until_complete @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_write_pipe @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_write_pipe_disconnect_on_close @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_write_pty @ linux-x86_64 +test.test_asyncio.test_events.SelectEventLoopTests.test_writer_callback @ linux-x86_64 +test.test_asyncio.test_events.TestAbstractServer.test_close @ linux-x86_64 +test.test_asyncio.test_events.TestAbstractServer.test_get_loop @ linux-x86_64 +test.test_asyncio.test_events.TestAbstractServer.test_wait_closed @ linux-x86_64 +test.test_asyncio.test_events.TestCGetEventLoop.test_get_event_loop_new_process @ linux-x86_64 +test.test_asyncio.test_events.TestCGetEventLoop.test_get_event_loop_returns_running_loop @ linux-x86_64 +test.test_asyncio.test_events.TestCGetEventLoop.test_get_event_loop_returns_running_loop2 @ linux-x86_64 +test.test_asyncio.test_events.TestPyGetEventLoop.test_get_event_loop_new_process @ linux-x86_64 +test.test_asyncio.test_events.TestPyGetEventLoop.test_get_event_loop_returns_running_loop @ linux-x86_64 +test.test_asyncio.test_events.TestPyGetEventLoop.test_get_event_loop_returns_running_loop2 @ linux-x86_64 +test.test_asyncio.test_events.TimerTests.test_hash @ linux-x86_64 +test.test_asyncio.test_events.TimerTests.test_timer @ linux-x86_64 +test.test_asyncio.test_events.TimerTests.test_timer_comparison @ linux-x86_64 +test.test_asyncio.test_events.TimerTests.test_timer_repr @ linux-x86_64 +test.test_asyncio.test_events.TimerTests.test_timer_repr_debug @ linux-x86_64 +test.test_asyncio.test_events.TimerTests.test_when @ linux-x86_64 +test.test_asyncio.test_futures.DuckTests.test_ensure_future @ linux-x86_64 +test.test_asyncio.test_futures.DuckTests.test_wrap_future @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureDoneCallbackTests.test_callbacks_invoked_on_set_exception @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureDoneCallbackTests.test_callbacks_invoked_on_set_result @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureDoneCallbackTests.test_callbacks_remove_first_and_second_callback @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureDoneCallbackTests.test_callbacks_remove_first_callback @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureDoneCallbackTests.test_callbacks_remove_third_callback @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureDoneCallbackTests.test_remove_done_callback @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureDoneCallbackTests.test_remove_done_callbacks_list_clear @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureDoneCallbackTests.test_remove_done_callbacks_list_mutation @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureDoneCallbackTests.test_schedule_callbacks_list_mutation_1 @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureDoneCallbackTests.test_schedule_callbacks_list_mutation_2 @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureInheritanceTests.test_inherit_without_calling_super_init @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_cancel @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_constructor_positional @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_constructor_use_global_loop @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_constructor_use_running_loop @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_constructor_without_loop @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_copy_state @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_exception @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_exception_class @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_future_cancel_message_getter @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_future_cancel_message_setter @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_future_del_collect @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_future_iter_throw @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_future_repr @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_future_source_traceback @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_future_stop_iteration_args @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_generic_alias @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_initial_state @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_isfuture @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_iter @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_log_traceback @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_result @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_set_result_unless_cancelled @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_tb_logger_abandoned @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_tb_logger_exception_result_retrieved @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_tb_logger_exception_retrieved @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_tb_logger_not_called_after_cancel @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_tb_logger_result_retrieved @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_tb_logger_result_unretrieved @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_uninitialized @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_wrap_future @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_wrap_future_cancel @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_wrap_future_cancel2 @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_wrap_future_future @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_wrap_future_use_global_loop @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_wrap_future_use_running_loop @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_wrap_future_without_loop @ linux-x86_64 +test.test_asyncio.test_futures.PyFutureTests.test_yield_from_twice @ linux-x86_64 +test.test_asyncio.test_locks.EventTests.test_clear @ linux-x86_64 +test.test_asyncio.test_locks.EventTests.test_repr @ linux-x86_64 +test.test_asyncio.test_locks.LockTests.test_lock @ linux-x86_64 +test.test_asyncio.test_locks.LockTests.test_lock_doesnt_accept_loop_parameter @ linux-x86_64 +test.test_asyncio.test_locks.LockTests.test_release_not_acquired @ linux-x86_64 +test.test_asyncio.test_locks.SemaphoreTests.test_initial_value_zero @ linux-x86_64 +test.test_asyncio.test_locks.SemaphoreTests.test_release_not_acquired @ linux-x86_64 +test.test_asyncio.test_locks.SemaphoreTests.test_semaphore @ linux-x86_64 +test.test_asyncio.test_locks.SemaphoreTests.test_semaphore_value @ linux-x86_64 +test.test_asyncio.test_pep492.CoroutineTests.test_iscoroutine @ linux-x86_64 +test.test_asyncio.test_pep492.CoroutineTests.test_iscoroutinefunction @ linux-x86_64 +test.test_asyncio.test_pep492.CoroutineTests.test_types_coroutine @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_close @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_close_self_pipe @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_create_server @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_create_server_cancel @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_ctor @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_datagram_loop_reading @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_datagram_loop_reading_aborted @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_datagram_loop_reading_data @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_datagram_loop_reading_no_data @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_datagram_loop_writing @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_datagram_loop_writing_aborted @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_loop_self_reading @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_loop_self_reading_exception @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_loop_self_reading_fut @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_make_datagram_transport @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_make_socket_transport @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_process_events @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_stop_serving @ linux-x86_64 +test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_write_to_self @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test__loop_writing_closing @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test__loop_writing_error_received @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test__loop_writing_error_received_connection @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test__loop_writing_exception @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test_fatal_error_connected @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test_sendto @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test_sendto_buffer @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test_sendto_buffer_bytearray @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test_sendto_buffer_memoryview @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test_sendto_bytearray @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test_sendto_closing @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test_sendto_connected_addr @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test_sendto_error_received @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test_sendto_error_received_connected @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test_sendto_exception @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test_sendto_memoryview @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test_sendto_no_data @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorDatagramTransportTests.test_sendto_str @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_abort @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_call_connection_lost @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_close @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_close_buffer @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_close_invalid_sockobj @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_close_protocol_connection_lost_once @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_close_write_fut @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_ctor @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_dont_pause_writing @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_fatal_error @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_fatal_error_2 @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_force_close @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_force_close_idempotent @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_force_close_protocol_connection_lost_once @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_loop_reading @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_loop_reading_aborted @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_loop_reading_aborted_closing @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_loop_reading_aborted_is_fatal @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_loop_reading_conn_reset_lost @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_loop_reading_data @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_loop_reading_exception @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_loop_reading_no_data @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_loop_writing @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_loop_writing_closing @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_loop_writing_err @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_loop_writing_force_close @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_loop_writing_stop @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_pause_reading_connection_made @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_pause_resume_reading @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_pause_resume_writing @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_pause_writing_2write @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_pause_writing_3write @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_write @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_write_eof @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_write_eof_buffer @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_write_eof_buffer_write_pipe @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_write_eof_duplex_pipe @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_write_eof_write_pipe @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_write_more @ linux-x86_64 +test.test_asyncio.test_proactor_events.ProactorSocketTransportTests.test_write_no_data @ linux-x86_64 +test.test_asyncio.test_protocols.ProtocolsAbsTests.test_base_protocol @ linux-x86_64 +test.test_asyncio.test_protocols.ProtocolsAbsTests.test_buffered_protocol @ linux-x86_64 +test.test_asyncio.test_protocols.ProtocolsAbsTests.test_datagram_protocol @ linux-x86_64 +test.test_asyncio.test_protocols.ProtocolsAbsTests.test_protocol @ linux-x86_64 +test.test_asyncio.test_protocols.ProtocolsAbsTests.test_subprocess_protocol @ linux-x86_64 +test.test_asyncio.test_runners.RunTests.test_asyncio_run_debug @ linux-x86_64 +test.test_asyncio.test_runners.RunTests.test_asyncio_run_from_running_loop @ linux-x86_64 +test.test_asyncio.test_runners.RunTests.test_asyncio_run_only_coro @ linux-x86_64 +test.test_asyncio.test_runners.RunnerTests.test_custom_factory @ linux-x86_64 +test.test_asyncio.test_runners.RunnerTests.test_debug @ linux-x86_64 +test.test_asyncio.test_runners.RunnerTests.test_double_close @ linux-x86_64 +test.test_asyncio.test_runners.RunnerTests.test_explicit_close @ linux-x86_64 +test.test_asyncio.test_runners.RunnerTests.test_non_debug @ linux-x86_64 +test.test_asyncio.test_runners.RunnerTests.test_second_with_block_raises @ linux-x86_64 +test.test_asyncio.test_runners.RunnerTests.test_set_event_loop_called_once @ linux-x86_64 +test.test_asyncio.test_runners.RunnerTests.test_signal_install_not_supported_ok @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_add_reader @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_add_reader_existing @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_add_reader_existing_writer @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_add_writer @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_add_writer_existing @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_close @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_close_no_selector @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_make_socket_transport @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_make_ssl_transport_without_ssl_error @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_process_events_read @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_process_events_read_cancelled @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_process_events_write @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_process_events_write_cancelled @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_read_from_self_exception @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_read_from_self_tryagain @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_remove_reader @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_remove_reader_read_write @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_remove_reader_unknown @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_remove_writer @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_remove_writer_read_write @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_remove_writer_unknown @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_write_to_self_exception @ linux-x86_64 +test.test_asyncio.test_selector_events.BaseSelectorEventLoopTests.test_write_to_self_tryagain @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_fatal_error_connected @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_fatal_error_connected_custom_error @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_read_ready @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_read_ready_err @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_read_ready_oserr @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_read_ready_tryagain @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_buffer @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_buffer_bytearray @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_buffer_memoryview @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_bytearray @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_closing @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_connected_addr @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_error_received @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_error_received_connected @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_exception @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_memoryview @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_no_data @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_ready @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_ready_closing @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_ready_error_received @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_ready_error_received_connection @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_ready_exception @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_ready_no_data @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_ready_tryagain @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_str @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorDatagramTransportTests.test_sendto_tryagain @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportBufferedProtocolTests.test_buffer_updated_error @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportBufferedProtocolTests.test_ctor @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportBufferedProtocolTests.test_get_buffer_error @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportBufferedProtocolTests.test_get_buffer_zerosized @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportBufferedProtocolTests.test_proto_type_switch @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportBufferedProtocolTests.test_read_eof_received_error @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportBufferedProtocolTests.test_read_ready @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportBufferedProtocolTests.test_read_ready_conn_reset @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportBufferedProtocolTests.test_read_ready_eof @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportBufferedProtocolTests.test_read_ready_eof_keep_open @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportBufferedProtocolTests.test_read_ready_err @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportBufferedProtocolTests.test_read_ready_tryagain @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportBufferedProtocolTests.test_read_ready_tryagain_interrupted @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_ctor @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_ctor_with_waiter @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_data_received_error @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_pause_reading_connection_made @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_pause_resume_reading @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_read_eof_received_error @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_read_ready @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_read_ready_conn_reset @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_read_ready_eof @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_read_ready_eof_keep_open @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_read_ready_err @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_read_ready_tryagain @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_read_ready_tryagain_interrupted @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_transport_close_remove_writer @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_buffer @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_bytearray @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_closing @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_eof @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_eof_buffer @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_exception @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_memoryview @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_no_data @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_partial @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_partial_bytearray @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_partial_memoryview @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_partial_none @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_ready @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_ready_closing @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_ready_exception @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_ready_no_data @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_ready_partial @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_ready_partial_none @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_ready_tryagain @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_str @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorSocketTransportTests.test_write_tryagain @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorTransportTests.test__add_reader @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorTransportTests.test_abort @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorTransportTests.test_close @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorTransportTests.test_close_write_buffer @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorTransportTests.test_connection_lost @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorTransportTests.test_ctor @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorTransportTests.test_fatal_error @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorTransportTests.test_fatal_error_custom_exception @ linux-x86_64 +test.test_asyncio.test_selector_events.SelectorTransportTests.test_force_close @ linux-x86_64 +test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_sock_accept @ linux-x86_64 +test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_unix_sock_client_ops @ linux-x86_64 +test.test_asyncio.test_ssl.TestSSL.test_ssl_connect_accepted_socket @ linux-x86_64 +test.test_asyncio.test_sslproto.SelectorStartTLSTests.test_buf_feed_data @ linux-x86_64 +test.test_asyncio.test_sslproto.SslProtoHandshakeTests.test_close_during_handshake @ linux-x86_64 +test.test_asyncio.test_sslproto.SslProtoHandshakeTests.test_connection_lost @ linux-x86_64 +test.test_asyncio.test_sslproto.SslProtoHandshakeTests.test_data_received_after_closing @ linux-x86_64 +test.test_asyncio.test_sslproto.SslProtoHandshakeTests.test_eof_received_waiter @ linux-x86_64 +test.test_asyncio.test_sslproto.SslProtoHandshakeTests.test_fatal_error_no_name_error @ linux-x86_64 +test.test_asyncio.test_sslproto.SslProtoHandshakeTests.test_get_extra_info_on_closed_connection @ linux-x86_64 +test.test_asyncio.test_sslproto.SslProtoHandshakeTests.test_handshake_timeout_negative @ linux-x86_64 +test.test_asyncio.test_sslproto.SslProtoHandshakeTests.test_handshake_timeout_zero @ linux-x86_64 +test.test_asyncio.test_sslproto.SslProtoHandshakeTests.test_set_new_app_protocol @ linux-x86_64 +test.test_asyncio.test_sslproto.SslProtoHandshakeTests.test_write_after_closing @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test_IncompleteReadError_pickleable @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test_LimitOverrunError_pickleable @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test___repr__ @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test___repr__data @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test___repr__eof @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test___repr__exception @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test___repr__nondefault_limit @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test___repr__transport @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test___repr__waiter @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test_exception @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test_feed_empty_data @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test_feed_nonempty_data @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test_invalid_limit @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test_streamreader_constructor_use_global_loop @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test_streamreader_constructor_use_running_loop @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test_streamreader_constructor_without_loop @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test_streamreaderprotocol_constructor_use_global_loop @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test_streamreaderprotocol_constructor_use_running_loop @ linux-x86_64 +test.test_asyncio.test_streams.StreamTests.test_streamreaderprotocol_constructor_without_loop @ linux-x86_64 +!test.test_asyncio.test_subprocess.SubprocessSafeWatcherTests.test_shell @ linux-x86_64 +test.test_asyncio.test_subprocess.SubprocessTransportTests.test_proc_exited @ linux-x86_64 +test.test_asyncio.test_subprocess.SubprocessTransportTests.test_subprocess_repr @ linux-x86_64 +test.test_asyncio.test_tasks.CIntrospectionTests.test__enter_task @ linux-x86_64 +test.test_asyncio.test_tasks.CIntrospectionTests.test__enter_task_failure @ linux-x86_64 +test.test_asyncio.test_tasks.CIntrospectionTests.test__leave_task @ linux-x86_64 +test.test_asyncio.test_tasks.CIntrospectionTests.test__leave_task_failure1 @ linux-x86_64 +test.test_asyncio.test_tasks.CIntrospectionTests.test__leave_task_failure2 @ linux-x86_64 +test.test_asyncio.test_tasks.CIntrospectionTests.test__register_task_1 @ linux-x86_64 +test.test_asyncio.test_tasks.CIntrospectionTests.test__register_task_2 @ linux-x86_64 +test.test_asyncio.test_tasks.CIntrospectionTests.test__register_task_3 @ linux-x86_64 +test.test_asyncio.test_tasks.CIntrospectionTests.test__unregister_task @ linux-x86_64 +test.test_asyncio.test_tasks.CIntrospectionTests.test__unregister_task_not_registered @ linux-x86_64 +test.test_asyncio.test_tasks.CoroutineGatherTests.test_cancellation_broadcast @ linux-x86_64 +test.test_asyncio.test_tasks.CoroutineGatherTests.test_constructor_use_global_loop @ linux-x86_64 +test.test_asyncio.test_tasks.CoroutineGatherTests.test_constructor_use_running_loop @ linux-x86_64 +test.test_asyncio.test_tasks.CoroutineGatherTests.test_constructor_without_loop @ linux-x86_64 +test.test_asyncio.test_tasks.CoroutineGatherTests.test_duplicate_coroutines @ linux-x86_64 +test.test_asyncio.test_tasks.CoroutineGatherTests.test_exception_marking @ linux-x86_64 +test.test_asyncio.test_tasks.CoroutineGatherTests.test_issue46672 @ linux-x86_64 +test.test_asyncio.test_tasks.CoroutineGatherTests.test_one_exception @ linux-x86_64 +test.test_asyncio.test_tasks.CoroutineGatherTests.test_result_exception_success @ linux-x86_64 +test.test_asyncio.test_tasks.CoroutineGatherTests.test_return_exceptions @ linux-x86_64 +test.test_asyncio.test_tasks.CoroutineGatherTests.test_success @ linux-x86_64 +test.test_asyncio.test_tasks.FutureGatherTests.test_constructor_empty_sequence_use_global_loop @ linux-x86_64 +test.test_asyncio.test_tasks.FutureGatherTests.test_constructor_empty_sequence_use_running_loop @ linux-x86_64 +test.test_asyncio.test_tasks.FutureGatherTests.test_constructor_empty_sequence_without_loop @ linux-x86_64 +test.test_asyncio.test_tasks.FutureGatherTests.test_constructor_heterogenous_futures @ linux-x86_64 +test.test_asyncio.test_tasks.FutureGatherTests.test_constructor_homogenous_futures @ linux-x86_64 +test.test_asyncio.test_tasks.FutureGatherTests.test_one_cancellation @ linux-x86_64 +test.test_asyncio.test_tasks.FutureGatherTests.test_one_exception @ linux-x86_64 +test.test_asyncio.test_tasks.FutureGatherTests.test_result_exception_one_cancellation @ linux-x86_64 +test.test_asyncio.test_tasks.FutureGatherTests.test_result_exception_success @ linux-x86_64 +test.test_asyncio.test_tasks.FutureGatherTests.test_return_exceptions @ linux-x86_64 +test.test_asyncio.test_tasks.FutureGatherTests.test_success @ linux-x86_64 +test.test_asyncio.test_tasks.GenericTaskTests.test_future_subclass @ linux-x86_64 +test.test_asyncio.test_tasks.PyCurrentLoopTests.test_current_task_no_running_loop @ linux-x86_64 +test.test_asyncio.test_tasks.PyCurrentLoopTests.test_current_task_no_running_loop_implicit @ linux-x86_64 +test.test_asyncio.test_tasks.PyCurrentLoopTests.test_current_task_with_implicit_loop @ linux-x86_64 +test.test_asyncio.test_tasks.PyIntrospectionTests.test__enter_task @ linux-x86_64 +test.test_asyncio.test_tasks.PyIntrospectionTests.test__enter_task_failure @ linux-x86_64 +test.test_asyncio.test_tasks.PyIntrospectionTests.test__leave_task @ linux-x86_64 +test.test_asyncio.test_tasks.PyIntrospectionTests.test__leave_task_failure1 @ linux-x86_64 +test.test_asyncio.test_tasks.PyIntrospectionTests.test__leave_task_failure2 @ linux-x86_64 +test.test_asyncio.test_tasks.PyIntrospectionTests.test__register_task_1 @ linux-x86_64 +test.test_asyncio.test_tasks.PyIntrospectionTests.test__register_task_2 @ linux-x86_64 +test.test_asyncio.test_tasks.PyIntrospectionTests.test__register_task_3 @ linux-x86_64 +test.test_asyncio.test_tasks.PyIntrospectionTests.test__unregister_task @ linux-x86_64 +test.test_asyncio.test_tasks.PyIntrospectionTests.test__unregister_task_not_registered @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_bare_create_named_task @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_bare_create_task @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_coroutine_non_gen_function @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_coroutine_non_gen_function_return_future @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_create_task_with_async_function @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_create_task_with_asynclike_function @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_create_task_with_noncoroutine @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_current_task @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_ensure_future_coroutine @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_ensure_future_error_msg @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_ensure_future_future @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_ensure_future_neither @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_ensure_future_task @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_gather_shield @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_generic_alias @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_get_coro @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_iscoroutinefunction @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_log_traceback @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_other_loop_future @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_shield_cancel_inner @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_shield_cancel_outer @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_shield_coroutine_use_global_loop @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_shield_coroutine_use_running_loop @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_shield_coroutine_without_loop @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_shield_effect @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_shield_exception @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_shield_gather @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_shield_result @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_shield_shortcut @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_step_result_future @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_subclasses_ctask_cfuture @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_task_awaits_on_itself @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_task_cancel_message_getter @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_task_cancel_message_setter @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_task_cancel_waiter_future @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_task_class @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_task_del_collect @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_task_repr_name_not_str @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_task_repr_wait_for @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_task_set_methods @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_bare_create_named_task @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_bare_create_task @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_coroutine_non_gen_function @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_coroutine_non_gen_function_return_future @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_create_task_with_async_function @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_create_task_with_asynclike_function @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_create_task_with_noncoroutine @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_current_task @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_ensure_future_coroutine @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_ensure_future_error_msg @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_ensure_future_future @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_ensure_future_neither @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_ensure_future_task @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_gather_shield @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_generic_alias @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_get_coro @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_iscoroutinefunction @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_log_traceback @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_other_loop_future @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_shield_cancel_inner @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_shield_cancel_outer @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_shield_coroutine_use_global_loop @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_shield_coroutine_use_running_loop @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_shield_coroutine_without_loop @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_shield_effect @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_shield_exception @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_shield_gather @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_shield_result @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_shield_shortcut @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_step_result_future @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_task_awaits_on_itself @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_task_cancel_message_getter @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_task_cancel_message_setter @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_task_cancel_waiter_future @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_task_class @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_task_del_collect @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_task_repr_name_not_str @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_task_repr_wait_for @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_task_set_methods @ linux-x86_64 +test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_task_source_traceback @ linux-x86_64 +test.test_asyncio.test_timeouts.TimeoutTests.test_timeout_not_entered @ linux-x86_64 +test.test_asyncio.test_transports.TransportTests.test_ctor_extra_is_none @ linux-x86_64 +test.test_asyncio.test_transports.TransportTests.test_dgram_not_implemented @ linux-x86_64 +test.test_asyncio.test_transports.TransportTests.test_flowcontrol_mixin_set_write_limits @ linux-x86_64 +test.test_asyncio.test_transports.TransportTests.test_get_extra_info @ linux-x86_64 +test.test_asyncio.test_transports.TransportTests.test_not_implemented @ linux-x86_64 +test.test_asyncio.test_transports.TransportTests.test_subprocess_transport_not_implemented @ linux-x86_64 +test.test_asyncio.test_transports.TransportTests.test_writelines @ linux-x86_64 +test.test_asyncio.test_unix_events.AbstractChildWatcherTests.test_not_implemented @ linux-x86_64 +test.test_asyncio.test_unix_events.BaseChildWatcherTests.test_not_implemented @ linux-x86_64 +test.test_asyncio.test_unix_events.FastChildWatcherTests.test_close @ linux-x86_64 +test.test_asyncio.test_unix_events.FastChildWatcherTests.test_create_watcher @ linux-x86_64 +test.test_asyncio.test_unix_events.FastChildWatcherTests.test_remove_child_handler @ linux-x86_64 +test.test_asyncio.test_unix_events.FastChildWatcherTests.test_set_loop @ linux-x86_64 +test.test_asyncio.test_unix_events.FastChildWatcherTests.test_set_loop_race_condition @ linux-x86_64 +test.test_asyncio.test_unix_events.FastChildWatcherTests.test_sigchld @ linux-x86_64 +test.test_asyncio.test_unix_events.FastChildWatcherTests.test_sigchld_child_reaped_elsewhere @ linux-x86_64 +test.test_asyncio.test_unix_events.FastChildWatcherTests.test_sigchld_race_condition @ linux-x86_64 +test.test_asyncio.test_unix_events.FastChildWatcherTests.test_sigchld_remove_handler @ linux-x86_64 +test.test_asyncio.test_unix_events.FastChildWatcherTests.test_sigchld_replace_handler @ linux-x86_64 +test.test_asyncio.test_unix_events.FastChildWatcherTests.test_sigchld_two_children @ linux-x86_64 +test.test_asyncio.test_unix_events.FastChildWatcherTests.test_sigchld_two_children_terminating_together @ linux-x86_64 +test.test_asyncio.test_unix_events.FastChildWatcherTests.test_sigchld_unhandled_exception @ linux-x86_64 +test.test_asyncio.test_unix_events.FastChildWatcherTests.test_sigchld_unknown_pid_during_registration @ linux-x86_64 +test.test_asyncio.test_unix_events.FastChildWatcherTests.test_sigchld_unknown_status @ linux-x86_64 +test.test_asyncio.test_unix_events.PolicyTests.test_child_watcher_replace_mainloop_existing @ linux-x86_64 +test.test_asyncio.test_unix_events.PolicyTests.test_get_child_watcher_after_set @ linux-x86_64 +test.test_asyncio.test_unix_events.PolicyTests.test_get_child_watcher_thread @ linux-x86_64 +test.test_asyncio.test_unix_events.PolicyTests.test_get_default_child_watcher @ linux-x86_64 +test.test_asyncio.test_unix_events.SafeChildWatcherTests.test_close @ linux-x86_64 +test.test_asyncio.test_unix_events.SafeChildWatcherTests.test_create_watcher @ linux-x86_64 +test.test_asyncio.test_unix_events.SafeChildWatcherTests.test_remove_child_handler @ linux-x86_64 +test.test_asyncio.test_unix_events.SafeChildWatcherTests.test_set_loop @ linux-x86_64 +test.test_asyncio.test_unix_events.SafeChildWatcherTests.test_set_loop_race_condition @ linux-x86_64 +test.test_asyncio.test_unix_events.SafeChildWatcherTests.test_sigchld @ linux-x86_64 +test.test_asyncio.test_unix_events.SafeChildWatcherTests.test_sigchld_child_reaped_elsewhere @ linux-x86_64 +test.test_asyncio.test_unix_events.SafeChildWatcherTests.test_sigchld_race_condition @ linux-x86_64 +test.test_asyncio.test_unix_events.SafeChildWatcherTests.test_sigchld_remove_handler @ linux-x86_64 +test.test_asyncio.test_unix_events.SafeChildWatcherTests.test_sigchld_replace_handler @ linux-x86_64 +test.test_asyncio.test_unix_events.SafeChildWatcherTests.test_sigchld_two_children @ linux-x86_64 +test.test_asyncio.test_unix_events.SafeChildWatcherTests.test_sigchld_two_children_terminating_together @ linux-x86_64 +test.test_asyncio.test_unix_events.SafeChildWatcherTests.test_sigchld_unhandled_exception @ linux-x86_64 +test.test_asyncio.test_unix_events.SafeChildWatcherTests.test_sigchld_unknown_pid_during_registration @ linux-x86_64 +test.test_asyncio.test_unix_events.SafeChildWatcherTests.test_sigchld_unknown_status @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_add_signal_handler @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_add_signal_handler_coroutine_error @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_add_signal_handler_install_error @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_add_signal_handler_install_error2 @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_add_signal_handler_install_error3 @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_add_signal_handler_setup_error @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_check_signal @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_close @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_close_on_finalizing @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_handle_signal_cancelled_handler @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_handle_signal_no_handler @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_remove_signal_handler @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_remove_signal_handler_2 @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_remove_signal_handler_cleanup_error @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_remove_signal_handler_error @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopSignalTests.test_remove_signal_handler_error2 @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopUnixSocketTests.test_create_unix_connection_nopath_nosock @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopUnixSocketTests.test_create_unix_connection_nossl_serverhost @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopUnixSocketTests.test_create_unix_connection_path_inetsock @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopUnixSocketTests.test_create_unix_connection_path_sock @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopUnixSocketTests.test_create_unix_connection_ssl_noserverhost @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopUnixSocketTests.test_create_unix_connection_ssl_timeout_with_plain_sock @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopUnixSocketTests.test_create_unix_server_bind_error @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopUnixSocketTests.test_create_unix_server_existing_path_nonsock @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopUnixSocketTests.test_create_unix_server_nopath_nosock @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopUnixSocketTests.test_create_unix_server_path_dgram @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopUnixSocketTests.test_create_unix_server_path_inetsock @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopUnixSocketTests.test_create_unix_server_ssl_bool @ linux-x86_64 +test.test_asyncio.test_unix_events.SelectorEventLoopUnixSocketTests.test_create_unix_server_ssl_timeout_with_plain_sock @ linux-x86_64 +test.test_asyncio.test_unix_events.TestFunctional.test_add_reader_invalid_argument @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test__call_connection_lost @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test__call_connection_lost_with_err @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test__close @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test__read_ready @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test__read_ready_blocked @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test__read_ready_eof @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test__read_ready_error @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test_close @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test_close_already_closing @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test_ctor @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test_pause_reading @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test_pause_reading_on_closed_pipe @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test_pause_reading_on_paused_pipe @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test_resume_reading @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test_resume_reading_on_closed_pipe @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixReadPipeTransportTests.test_resume_reading_on_paused_pipe @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test__call_connection_lost @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test__call_connection_lost_with_err @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test__read_ready @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test__write_ready @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test__write_ready_again @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test__write_ready_closing @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test__write_ready_empty @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test__write_ready_err @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test__write_ready_partial @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test_abort @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test_can_write_eof @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test_close @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test_close_closing @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test_ctor @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test_write @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test_write_again @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test_write_buffer @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test_write_close @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test_write_eof @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test_write_eof_pending @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test_write_err @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test_write_no_data @ linux-x86_64 +test.test_asyncio.test_unix_events.UnixWritePipeTransportTests.test_write_partial @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_asyncore.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_asyncore.txt new file mode 100644 index 0000000000..8159384918 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_asyncore.txt @@ -0,0 +1,51 @@ +test.test_asyncore.DispatcherTests.test_basic @ linux-x86_64 +test.test_asyncore.DispatcherTests.test_log @ linux-x86_64 +test.test_asyncore.DispatcherTests.test_log_info @ linux-x86_64 +test.test_asyncore.DispatcherTests.test_repr @ linux-x86_64 +test.test_asyncore.DispatcherTests.test_strerror @ linux-x86_64 +test.test_asyncore.DispatcherTests.test_unhandled @ linux-x86_64 +test.test_asyncore.DispatcherWithSendTests.test_send @ linux-x86_64 +test.test_asyncore.FileWrapperTest.test_close_twice @ linux-x86_64 +test.test_asyncore.FileWrapperTest.test_dispatcher @ linux-x86_64 +test.test_asyncore.FileWrapperTest.test_recv @ linux-x86_64 +test.test_asyncore.FileWrapperTest.test_send @ linux-x86_64 +test.test_asyncore.HelperFunctionTests.test_closeall @ linux-x86_64 +test.test_asyncore.HelperFunctionTests.test_closeall_default @ linux-x86_64 +test.test_asyncore.HelperFunctionTests.test_compact_traceback @ linux-x86_64 +test.test_asyncore.HelperFunctionTests.test_readwriteexc @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv4Select.test_bind @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv4Select.test_connection_attributes @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv4Select.test_create_socket @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv4Select.test_handle_accept @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv4Select.test_handle_accepted @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv4Select.test_handle_close @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv4Select.test_handle_close_after_conn_broken @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv4Select.test_handle_connect @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv4Select.test_handle_error @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv4Select.test_handle_read @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv4Select.test_handle_write @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv4Select.test_quick_connect @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv4Select.test_set_reuse_addr @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv6Select.test_bind @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv6Select.test_connection_attributes @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv6Select.test_create_socket @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv6Select.test_handle_accept @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv6Select.test_handle_accepted @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv6Select.test_handle_close @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv6Select.test_handle_close_after_conn_broken @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv6Select.test_handle_connect @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv6Select.test_handle_error @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv6Select.test_handle_read @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv6Select.test_handle_write @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv6Select.test_quick_connect @ linux-x86_64 +test.test_asyncore.TestAPI_UseIPv6Select.test_set_reuse_addr @ linux-x86_64 +test.test_asyncore.TestAPI_UseUnixSocketsSelect.test_connection_attributes @ linux-x86_64 +test.test_asyncore.TestAPI_UseUnixSocketsSelect.test_create_socket @ linux-x86_64 +test.test_asyncore.TestAPI_UseUnixSocketsSelect.test_handle_accept @ linux-x86_64 +test.test_asyncore.TestAPI_UseUnixSocketsSelect.test_handle_accepted @ linux-x86_64 +test.test_asyncore.TestAPI_UseUnixSocketsSelect.test_handle_close @ linux-x86_64 +test.test_asyncore.TestAPI_UseUnixSocketsSelect.test_handle_close_after_conn_broken @ linux-x86_64 +test.test_asyncore.TestAPI_UseUnixSocketsSelect.test_handle_connect @ linux-x86_64 +test.test_asyncore.TestAPI_UseUnixSocketsSelect.test_handle_error @ linux-x86_64 +test.test_asyncore.TestAPI_UseUnixSocketsSelect.test_handle_read @ linux-x86_64 +test.test_asyncore.TestAPI_UseUnixSocketsSelect.test_handle_write @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_atexit.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_atexit.txt new file mode 100644 index 0000000000..a9abb7e8ef --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_atexit.txt @@ -0,0 +1 @@ +test.test_atexit.FunctionalTest.test_shutdown @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_augassign.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_augassign.txt new file mode 100644 index 0000000000..a052d1cb02 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_augassign.txt @@ -0,0 +1,7 @@ +test.test_augassign.AugAssignTest.testBasic @ linux-x86_64 +test.test_augassign.AugAssignTest.testCustomMethods1 @ linux-x86_64 +test.test_augassign.AugAssignTest.testCustomMethods2 @ linux-x86_64 +test.test_augassign.AugAssignTest.testInDict @ linux-x86_64 +test.test_augassign.AugAssignTest.testInList @ linux-x86_64 +test.test_augassign.AugAssignTest.testSequences @ linux-x86_64 +test.test_augassign.AugAssignTest.test_with_unpacking @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_base64.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_base64.txt new file mode 100644 index 0000000000..a0f858836c --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_base64.txt @@ -0,0 +1,36 @@ +test.test_base64.BaseXYTestCase.test_ErrorHeritage @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_RFC4648_test_cases @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_a85_padding @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_a85decode @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_a85decode_errors @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_a85encode @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b16decode @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b16encode @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b32decode @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b32decode_casefold @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b32decode_error @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b32encode @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b32hexdecode @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b32hexdecode_error @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b32hexdecode_other_types @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b32hexencode @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b32hexencode_other_types @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b64decode @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b64decode_invalid_chars @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b64decode_padding_error @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b64encode @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b85_padding @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b85decode @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b85decode_errors @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_b85encode @ linux-x86_64 +test.test_base64.BaseXYTestCase.test_decode_nonascii_str @ linux-x86_64 +test.test_base64.LegacyBase64TestCase.test_decode @ linux-x86_64 +test.test_base64.LegacyBase64TestCase.test_decodebytes @ linux-x86_64 +test.test_base64.LegacyBase64TestCase.test_encode @ linux-x86_64 +test.test_base64.LegacyBase64TestCase.test_encodebytes @ linux-x86_64 +test.test_base64.TestMain.test_decode @ linux-x86_64 +test.test_base64.TestMain.test_encode_decode @ linux-x86_64 +test.test_base64.TestMain.test_encode_file @ linux-x86_64 +test.test_base64.TestMain.test_encode_from_stdin @ linux-x86_64 +test.test_base64.TestMain.test_prints_usage_with_help_flag @ linux-x86_64 +test.test_base64.TestMain.test_prints_usage_with_invalid_flag @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_baseexception.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_baseexception.txt new file mode 100644 index 0000000000..9c96347c99 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_baseexception.txt @@ -0,0 +1,11 @@ +test.test_baseexception.ExceptionClassTests.test_builtins_new_style @ linux-x86_64 +test.test_baseexception.ExceptionClassTests.test_inheritance @ linux-x86_64 +test.test_baseexception.ExceptionClassTests.test_interface_multi_arg @ linux-x86_64 +test.test_baseexception.ExceptionClassTests.test_interface_no_arg @ linux-x86_64 +test.test_baseexception.ExceptionClassTests.test_interface_single_arg @ linux-x86_64 +test.test_baseexception.ExceptionClassTests.test_setstate_refcount_no_crash @ linux-x86_64 +test.test_baseexception.UsageTests.test_catch_BaseException_instance @ linux-x86_64 +test.test_baseexception.UsageTests.test_catch_non_BaseException @ linux-x86_64 +test.test_baseexception.UsageTests.test_catch_string @ linux-x86_64 +test.test_baseexception.UsageTests.test_raise_new_style_non_exception @ linux-x86_64 +test.test_baseexception.UsageTests.test_raise_string @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bdb.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bdb.txt new file mode 100644 index 0000000000..041d0880ae --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bdb.txt @@ -0,0 +1,30 @@ +test.test_bdb.BreakpointTestCase.test_bp_after_last_statement @ linux-x86_64 +test.test_bdb.BreakpointTestCase.test_bp_condition @ linux-x86_64 +test.test_bdb.BreakpointTestCase.test_bp_exception_on_condition_evaluation @ linux-x86_64 +test.test_bdb.BreakpointTestCase.test_bp_ignore_count @ linux-x86_64 +test.test_bdb.BreakpointTestCase.test_bp_on_non_existent_module @ linux-x86_64 +test.test_bdb.BreakpointTestCase.test_clear_at_no_bp @ linux-x86_64 +test.test_bdb.BreakpointTestCase.test_clear_two_bp_on_same_line @ linux-x86_64 +test.test_bdb.BreakpointTestCase.test_disabled_temporary_bp @ linux-x86_64 +test.test_bdb.BreakpointTestCase.test_ignore_count_on_disabled_bp @ linux-x86_64 +test.test_bdb.BreakpointTestCase.test_load_bps_from_previous_Bdb_instance @ linux-x86_64 +test.test_bdb.BreakpointTestCase.test_temporary_bp @ linux-x86_64 +test.test_bdb.IssuesTestCase.test_step_at_return_with_no_trace_in_caller @ linux-x86_64 +test.test_bdb.RunTestCase.test_run_step @ linux-x86_64 +test.test_bdb.RunTestCase.test_runeval_step @ linux-x86_64 +test.test_bdb.StateTestCase.test_down @ linux-x86_64 +test.test_bdb.StateTestCase.test_next @ linux-x86_64 +test.test_bdb.StateTestCase.test_next_in_caller_frame @ linux-x86_64 +test.test_bdb.StateTestCase.test_next_on_plain_statement @ linux-x86_64 +test.test_bdb.StateTestCase.test_next_over_import @ linux-x86_64 +test.test_bdb.StateTestCase.test_return @ linux-x86_64 +test.test_bdb.StateTestCase.test_return_in_caller_frame @ linux-x86_64 +test.test_bdb.StateTestCase.test_skip @ linux-x86_64 +test.test_bdb.StateTestCase.test_skip_with_no_name_module @ linux-x86_64 +test.test_bdb.StateTestCase.test_step @ linux-x86_64 +test.test_bdb.StateTestCase.test_step_next_on_last_statement @ linux-x86_64 +test.test_bdb.StateTestCase.test_until @ linux-x86_64 +test.test_bdb.StateTestCase.test_until_in_caller_frame @ linux-x86_64 +test.test_bdb.StateTestCase.test_until_with_too_large_count @ linux-x86_64 +test.test_bdb.StateTestCase.test_up @ linux-x86_64 +test.test_bdb.TestRegressions.test_format_stack_entry_no_lineno @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bigmem.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bigmem.txt new file mode 100644 index 0000000000..d45ef8543c --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bigmem.txt @@ -0,0 +1,161 @@ +test.test_bigmem.BytearrayTest.test_capitalize @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_center @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_compare @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_concat @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_contains @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_count @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_decode @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_endswith @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_expandtabs @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_find @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_index @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_isalnum @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_isalpha @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_isdigit @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_islower @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_isspace @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_istitle @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_isupper @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_join @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_ljust @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_lower @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_lstrip @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_repeat @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_replace @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_rfind @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_rindex @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_rjust @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_rstrip @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_slice_and_getitem @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_split_small @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_splitlines @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_startswith @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_strip @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_swapcase @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_title @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_translate @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_upper @ linux-x86_64 +test.test_bigmem.BytearrayTest.test_zfill @ linux-x86_64 +test.test_bigmem.BytesTest.test_capitalize @ linux-x86_64 +test.test_bigmem.BytesTest.test_center @ linux-x86_64 +test.test_bigmem.BytesTest.test_compare @ linux-x86_64 +test.test_bigmem.BytesTest.test_concat @ linux-x86_64 +test.test_bigmem.BytesTest.test_contains @ linux-x86_64 +test.test_bigmem.BytesTest.test_count @ linux-x86_64 +test.test_bigmem.BytesTest.test_decode @ linux-x86_64 +test.test_bigmem.BytesTest.test_endswith @ linux-x86_64 +test.test_bigmem.BytesTest.test_expandtabs @ linux-x86_64 +test.test_bigmem.BytesTest.test_find @ linux-x86_64 +test.test_bigmem.BytesTest.test_hash @ linux-x86_64 +test.test_bigmem.BytesTest.test_index @ linux-x86_64 +test.test_bigmem.BytesTest.test_isalnum @ linux-x86_64 +test.test_bigmem.BytesTest.test_isalpha @ linux-x86_64 +test.test_bigmem.BytesTest.test_isdigit @ linux-x86_64 +test.test_bigmem.BytesTest.test_islower @ linux-x86_64 +test.test_bigmem.BytesTest.test_isspace @ linux-x86_64 +test.test_bigmem.BytesTest.test_istitle @ linux-x86_64 +test.test_bigmem.BytesTest.test_isupper @ linux-x86_64 +test.test_bigmem.BytesTest.test_join @ linux-x86_64 +test.test_bigmem.BytesTest.test_ljust @ linux-x86_64 +test.test_bigmem.BytesTest.test_lower @ linux-x86_64 +test.test_bigmem.BytesTest.test_repeat @ linux-x86_64 +test.test_bigmem.BytesTest.test_replace @ linux-x86_64 +test.test_bigmem.BytesTest.test_rfind @ linux-x86_64 +test.test_bigmem.BytesTest.test_rindex @ linux-x86_64 +test.test_bigmem.BytesTest.test_rjust @ linux-x86_64 +test.test_bigmem.BytesTest.test_slice_and_getitem @ linux-x86_64 +test.test_bigmem.BytesTest.test_split_large @ linux-x86_64 +test.test_bigmem.BytesTest.test_split_small @ linux-x86_64 +test.test_bigmem.BytesTest.test_splitlines @ linux-x86_64 +test.test_bigmem.BytesTest.test_startswith @ linux-x86_64 +test.test_bigmem.BytesTest.test_strip @ linux-x86_64 +test.test_bigmem.BytesTest.test_swapcase @ linux-x86_64 +test.test_bigmem.BytesTest.test_title @ linux-x86_64 +test.test_bigmem.BytesTest.test_translate @ linux-x86_64 +test.test_bigmem.BytesTest.test_upper @ linux-x86_64 +test.test_bigmem.BytesTest.test_zfill @ linux-x86_64 +test.test_bigmem.DictTest.test_dict @ linux-x86_64 +test.test_bigmem.ListTest.test_append @ linux-x86_64 +test.test_bigmem.ListTest.test_compare @ linux-x86_64 +test.test_bigmem.ListTest.test_concat_large @ linux-x86_64 +test.test_bigmem.ListTest.test_concat_small @ linux-x86_64 +test.test_bigmem.ListTest.test_contains @ linux-x86_64 +test.test_bigmem.ListTest.test_count @ linux-x86_64 +test.test_bigmem.ListTest.test_extend_large @ linux-x86_64 +test.test_bigmem.ListTest.test_extend_small @ linux-x86_64 +test.test_bigmem.ListTest.test_hash @ linux-x86_64 +test.test_bigmem.ListTest.test_index @ linux-x86_64 +test.test_bigmem.ListTest.test_index_and_slice @ linux-x86_64 +test.test_bigmem.ListTest.test_inplace_concat_large @ linux-x86_64 +test.test_bigmem.ListTest.test_inplace_concat_small @ linux-x86_64 +test.test_bigmem.ListTest.test_inplace_repeat_large @ linux-x86_64 +test.test_bigmem.ListTest.test_inplace_repeat_small @ linux-x86_64 +test.test_bigmem.ListTest.test_insert @ linux-x86_64 +test.test_bigmem.ListTest.test_pop @ linux-x86_64 +test.test_bigmem.ListTest.test_remove @ linux-x86_64 +test.test_bigmem.ListTest.test_repeat_large @ linux-x86_64 +test.test_bigmem.ListTest.test_repeat_small @ linux-x86_64 +test.test_bigmem.ListTest.test_repr_large @ linux-x86_64 +test.test_bigmem.ListTest.test_repr_small @ linux-x86_64 +test.test_bigmem.ListTest.test_reverse @ linux-x86_64 +test.test_bigmem.ListTest.test_sort @ linux-x86_64 +test.test_bigmem.StrTest.test_capitalize @ linux-x86_64 +test.test_bigmem.StrTest.test_center @ linux-x86_64 +test.test_bigmem.StrTest.test_compare @ linux-x86_64 +test.test_bigmem.StrTest.test_concat @ linux-x86_64 +test.test_bigmem.StrTest.test_contains @ linux-x86_64 +test.test_bigmem.StrTest.test_count @ linux-x86_64 +test.test_bigmem.StrTest.test_encode @ linux-x86_64 +test.test_bigmem.StrTest.test_encode_ascii @ linux-x86_64 +test.test_bigmem.StrTest.test_encode_raw_unicode_escape @ linux-x86_64 +test.test_bigmem.StrTest.test_encode_utf32 @ linux-x86_64 +test.test_bigmem.StrTest.test_encode_utf7 @ linux-x86_64 +test.test_bigmem.StrTest.test_endswith @ linux-x86_64 +test.test_bigmem.StrTest.test_expandtabs @ linux-x86_64 +test.test_bigmem.StrTest.test_find @ linux-x86_64 +test.test_bigmem.StrTest.test_format @ linux-x86_64 +test.test_bigmem.StrTest.test_index @ linux-x86_64 +test.test_bigmem.StrTest.test_isalnum @ linux-x86_64 +test.test_bigmem.StrTest.test_isalpha @ linux-x86_64 +test.test_bigmem.StrTest.test_isdigit @ linux-x86_64 +test.test_bigmem.StrTest.test_islower @ linux-x86_64 +test.test_bigmem.StrTest.test_isspace @ linux-x86_64 +test.test_bigmem.StrTest.test_istitle @ linux-x86_64 +test.test_bigmem.StrTest.test_isupper @ linux-x86_64 +test.test_bigmem.StrTest.test_join @ linux-x86_64 +test.test_bigmem.StrTest.test_ljust @ linux-x86_64 +test.test_bigmem.StrTest.test_lower @ linux-x86_64 +test.test_bigmem.StrTest.test_lstrip @ linux-x86_64 +test.test_bigmem.StrTest.test_repeat @ linux-x86_64 +test.test_bigmem.StrTest.test_replace @ linux-x86_64 +test.test_bigmem.StrTest.test_repr_large @ linux-x86_64 +test.test_bigmem.StrTest.test_repr_small @ linux-x86_64 +test.test_bigmem.StrTest.test_rfind @ linux-x86_64 +test.test_bigmem.StrTest.test_rindex @ linux-x86_64 +test.test_bigmem.StrTest.test_rjust @ linux-x86_64 +test.test_bigmem.StrTest.test_rstrip @ linux-x86_64 +test.test_bigmem.StrTest.test_split_large @ linux-x86_64 +test.test_bigmem.StrTest.test_split_small @ linux-x86_64 +test.test_bigmem.StrTest.test_splitlines @ linux-x86_64 +test.test_bigmem.StrTest.test_startswith @ linux-x86_64 +test.test_bigmem.StrTest.test_strip @ linux-x86_64 +test.test_bigmem.StrTest.test_swapcase @ linux-x86_64 +test.test_bigmem.StrTest.test_title @ linux-x86_64 +test.test_bigmem.StrTest.test_translate @ linux-x86_64 +test.test_bigmem.StrTest.test_unicode_repr @ linux-x86_64 +test.test_bigmem.StrTest.test_unicode_repr_wide @ linux-x86_64 +test.test_bigmem.StrTest.test_upper @ linux-x86_64 +test.test_bigmem.StrTest.test_zfill @ linux-x86_64 +test.test_bigmem.TupleTest.test_compare @ linux-x86_64 +test.test_bigmem.TupleTest.test_concat_large @ linux-x86_64 +test.test_bigmem.TupleTest.test_concat_small @ linux-x86_64 +test.test_bigmem.TupleTest.test_contains @ linux-x86_64 +test.test_bigmem.TupleTest.test_from_2G_generator @ linux-x86_64 +test.test_bigmem.TupleTest.test_from_almost_2G_generator @ linux-x86_64 +test.test_bigmem.TupleTest.test_hash @ linux-x86_64 +test.test_bigmem.TupleTest.test_index_and_slice @ linux-x86_64 +test.test_bigmem.TupleTest.test_repeat_large @ linux-x86_64 +test.test_bigmem.TupleTest.test_repeat_large_2 @ linux-x86_64 +test.test_bigmem.TupleTest.test_repeat_small @ linux-x86_64 +test.test_bigmem.TupleTest.test_repr_large @ linux-x86_64 +test.test_bigmem.TupleTest.test_repr_small @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_binascii.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_binascii.txt new file mode 100644 index 0000000000..5d7c43d458 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_binascii.txt @@ -0,0 +1,28 @@ +test.test_binascii.ArrayBinASCIITest.test_b2a_base64_newline @ linux-x86_64 +test.test_binascii.ArrayBinASCIITest.test_base64valid @ linux-x86_64 +test.test_binascii.ArrayBinASCIITest.test_c_contiguity @ linux-x86_64 +test.test_binascii.ArrayBinASCIITest.test_crc32 @ linux-x86_64 +test.test_binascii.ArrayBinASCIITest.test_crc_hqx @ linux-x86_64 +test.test_binascii.ArrayBinASCIITest.test_exceptions @ linux-x86_64 +test.test_binascii.ArrayBinASCIITest.test_hex @ linux-x86_64 +test.test_binascii.BinASCIITest.test_b2a_base64_newline @ linux-x86_64 +test.test_binascii.BinASCIITest.test_base64valid @ linux-x86_64 +test.test_binascii.BinASCIITest.test_c_contiguity @ linux-x86_64 +test.test_binascii.BinASCIITest.test_crc32 @ linux-x86_64 +test.test_binascii.BinASCIITest.test_crc_hqx @ linux-x86_64 +test.test_binascii.BinASCIITest.test_exceptions @ linux-x86_64 +test.test_binascii.BinASCIITest.test_hex @ linux-x86_64 +test.test_binascii.BytearrayBinASCIITest.test_b2a_base64_newline @ linux-x86_64 +test.test_binascii.BytearrayBinASCIITest.test_base64valid @ linux-x86_64 +test.test_binascii.BytearrayBinASCIITest.test_c_contiguity @ linux-x86_64 +test.test_binascii.BytearrayBinASCIITest.test_crc32 @ linux-x86_64 +test.test_binascii.BytearrayBinASCIITest.test_crc_hqx @ linux-x86_64 +test.test_binascii.BytearrayBinASCIITest.test_exceptions @ linux-x86_64 +test.test_binascii.BytearrayBinASCIITest.test_hex @ linux-x86_64 +test.test_binascii.MemoryviewBinASCIITest.test_b2a_base64_newline @ linux-x86_64 +test.test_binascii.MemoryviewBinASCIITest.test_base64valid @ linux-x86_64 +test.test_binascii.MemoryviewBinASCIITest.test_c_contiguity @ linux-x86_64 +test.test_binascii.MemoryviewBinASCIITest.test_crc32 @ linux-x86_64 +test.test_binascii.MemoryviewBinASCIITest.test_crc_hqx @ linux-x86_64 +test.test_binascii.MemoryviewBinASCIITest.test_exceptions @ linux-x86_64 +test.test_binascii.MemoryviewBinASCIITest.test_hex @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_binop.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_binop.txt new file mode 100644 index 0000000000..f464c4d476 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_binop.txt @@ -0,0 +1,12 @@ +test.test_binop.FallbackBlockingTests.test_fallback_ne_blocking @ linux-x86_64 +test.test_binop.FallbackBlockingTests.test_fallback_rmethod_blocking @ linux-x86_64 +test.test_binop.OperationOrderTests.test_comparison_orders @ linux-x86_64 +test.test_binop.RatTestCase.test_add @ linux-x86_64 +test.test_binop.RatTestCase.test_constructor @ linux-x86_64 +test.test_binop.RatTestCase.test_div @ linux-x86_64 +test.test_binop.RatTestCase.test_eq @ linux-x86_64 +test.test_binop.RatTestCase.test_floordiv @ linux-x86_64 +test.test_binop.RatTestCase.test_gcd @ linux-x86_64 +test.test_binop.RatTestCase.test_mul @ linux-x86_64 +test.test_binop.RatTestCase.test_sub @ linux-x86_64 +test.test_binop.RatTestCase.test_true_div @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bisect.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bisect.txt new file mode 100644 index 0000000000..f52cf5eb45 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bisect.txt @@ -0,0 +1,21 @@ +test.test_bisect.TestBisectPython.test_backcompatibility @ linux-x86_64 +test.test_bisect.TestBisectPython.test_insort @ linux-x86_64 +test.test_bisect.TestBisectPython.test_insort_keynotNone @ linux-x86_64 +test.test_bisect.TestBisectPython.test_keyword_args @ linux-x86_64 +test.test_bisect.TestBisectPython.test_large_pyrange @ linux-x86_64 +test.test_bisect.TestBisectPython.test_large_range @ linux-x86_64 +test.test_bisect.TestBisectPython.test_lookups_with_key_function @ linux-x86_64 +test.test_bisect.TestBisectPython.test_negative_lo @ linux-x86_64 +test.test_bisect.TestBisectPython.test_optionalSlicing @ linux-x86_64 +test.test_bisect.TestBisectPython.test_precomputed @ linux-x86_64 +test.test_bisect.TestBisectPython.test_random @ linux-x86_64 +test.test_bisect.TestDocExamplePython.test_colors @ linux-x86_64 +test.test_bisect.TestDocExamplePython.test_grades @ linux-x86_64 +test.test_bisect.TestErrorHandlingPython.test_arg_parsing @ linux-x86_64 +test.test_bisect.TestErrorHandlingPython.test_cmp_err @ linux-x86_64 +test.test_bisect.TestErrorHandlingPython.test_get_only @ linux-x86_64 +test.test_bisect.TestErrorHandlingPython.test_len_only @ linux-x86_64 +test.test_bisect.TestErrorHandlingPython.test_non_sequence @ linux-x86_64 +test.test_bisect.TestInsortPython.test_backcompatibility @ linux-x86_64 +test.test_bisect.TestInsortPython.test_listDerived @ linux-x86_64 +test.test_bisect.TestInsortPython.test_vsBuiltinSort @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bool.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bool.txt new file mode 100644 index 0000000000..7f82eb32fc --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bool.txt @@ -0,0 +1,30 @@ +test.test_bool.BoolTest.test_blocked @ linux-x86_64 +test.test_bool.BoolTest.test_bool_called_at_least_once @ linux-x86_64 +test.test_bool.BoolTest.test_bool_new @ linux-x86_64 +test.test_bool.BoolTest.test_boolean @ linux-x86_64 +test.test_bool.BoolTest.test_callable @ linux-x86_64 +test.test_bool.BoolTest.test_complex @ linux-x86_64 +test.test_bool.BoolTest.test_contains @ linux-x86_64 +test.test_bool.BoolTest.test_convert @ linux-x86_64 +test.test_bool.BoolTest.test_convert_to_bool @ linux-x86_64 +test.test_bool.BoolTest.test_fileclosed @ linux-x86_64 +test.test_bool.BoolTest.test_float @ linux-x86_64 +test.test_bool.BoolTest.test_format @ linux-x86_64 +test.test_bool.BoolTest.test_from_bytes @ linux-x86_64 +test.test_bool.BoolTest.test_hasattr @ linux-x86_64 +test.test_bool.BoolTest.test_int @ linux-x86_64 +test.test_bool.BoolTest.test_isinstance @ linux-x86_64 +test.test_bool.BoolTest.test_issubclass @ linux-x86_64 +test.test_bool.BoolTest.test_keyword_args @ linux-x86_64 +test.test_bool.BoolTest.test_marshal @ linux-x86_64 +test.test_bool.BoolTest.test_math @ linux-x86_64 +test.test_bool.BoolTest.test_operator @ linux-x86_64 +test.test_bool.BoolTest.test_pickle @ linux-x86_64 +test.test_bool.BoolTest.test_picklevalues @ linux-x86_64 +test.test_bool.BoolTest.test_real_and_imag @ linux-x86_64 +test.test_bool.BoolTest.test_repr @ linux-x86_64 +test.test_bool.BoolTest.test_sane_len @ linux-x86_64 +test.test_bool.BoolTest.test_str @ linux-x86_64 +test.test_bool.BoolTest.test_string @ linux-x86_64 +test.test_bool.BoolTest.test_subclass @ linux-x86_64 +test.test_bool.BoolTest.test_types @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_buffer.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_buffer.txt new file mode 100644 index 0000000000..e63458e0f4 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_buffer.txt @@ -0,0 +1,35 @@ +test.test_buffer.TestBufferProtocol.test_issue_7385 @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_memoryview_array @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_memoryview_cast @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_memoryview_cast_zero_shape @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_memoryview_cast_zero_strides @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_memoryview_check_released @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_memoryview_compare_multidim_zero_shape @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_memoryview_compare_zero_shape @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_memoryview_getbuffer_undefined @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_memoryview_index @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_memoryview_redirect @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_memoryview_repr @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_memoryview_sequence @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_memoryview_serializing @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_memoryview_tolist @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_ndarray_cmp_contig @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_ndarray_fortran @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_ndarray_hash @ linux-x86_64 +!test.test_buffer.TestBufferProtocol.test_ndarray_index_getitem_multidim @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_ndarray_index_invalid @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_ndarray_index_null_strides @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_ndarray_index_scalar @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_ndarray_linked_list @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_ndarray_memoryview_from_buffer @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_ndarray_offset @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_ndarray_random_invalid @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_ndarray_re_export @ linux-x86_64 +!test.test_buffer.TestBufferProtocol.test_ndarray_slice_assign_multidim @ linux-x86_64 +!test.test_buffer.TestBufferProtocol.test_ndarray_slice_multidim @ linux-x86_64 +!test.test_buffer.TestBufferProtocol.test_ndarray_slice_redundant_suboffsets @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_ndarray_slice_zero_shape @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_ndarray_tolist_null_strides @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_ndarray_zero_shape @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_ndarray_zero_strides @ linux-x86_64 +test.test_buffer.TestBufferProtocol.test_py_buffer_to_contiguous @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bufio.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bufio.txt new file mode 100644 index 0000000000..5e4e38c7ee --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bufio.txt @@ -0,0 +1,4 @@ +test.test_bufio.CBufferSizeTest.test_nullpat @ linux-x86_64 +test.test_bufio.CBufferSizeTest.test_primepat @ linux-x86_64 +test.test_bufio.PyBufferSizeTest.test_nullpat @ linux-x86_64 +test.test_bufio.PyBufferSizeTest.test_primepat @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_builtin.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_builtin.txt new file mode 100644 index 0000000000..7cbb95d21b --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_builtin.txt @@ -0,0 +1,87 @@ +DocTestCase.builtins.zip @ linux-x86_64 +test.test_builtin.BuiltinTest.test_abs @ linux-x86_64 +test.test_builtin.BuiltinTest.test_all @ linux-x86_64 +test.test_builtin.BuiltinTest.test_any @ linux-x86_64 +test.test_builtin.BuiltinTest.test_ascii @ linux-x86_64 +test.test_builtin.BuiltinTest.test_bin @ linux-x86_64 +test.test_builtin.BuiltinTest.test_bug_27936 @ linux-x86_64 +test.test_builtin.BuiltinTest.test_bytearray_extend_error @ linux-x86_64 +test.test_builtin.BuiltinTest.test_bytearray_join_with_custom_iterator @ linux-x86_64 +test.test_builtin.BuiltinTest.test_bytearray_translate @ linux-x86_64 +test.test_builtin.BuiltinTest.test_callable @ linux-x86_64 +test.test_builtin.BuiltinTest.test_chr @ linux-x86_64 +test.test_builtin.BuiltinTest.test_cmp @ linux-x86_64 +test.test_builtin.BuiltinTest.test_construct_singletons @ linux-x86_64 +test.test_builtin.BuiltinTest.test_delattr @ linux-x86_64 +test.test_builtin.BuiltinTest.test_dir @ linux-x86_64 +test.test_builtin.BuiltinTest.test_divmod @ linux-x86_64 +test.test_builtin.BuiltinTest.test_eval @ linux-x86_64 +test.test_builtin.BuiltinTest.test_exec @ linux-x86_64 +test.test_builtin.BuiltinTest.test_exec_redirected @ linux-x86_64 +test.test_builtin.BuiltinTest.test_filter @ linux-x86_64 +test.test_builtin.BuiltinTest.test_filter_dealloc @ linux-x86_64 +test.test_builtin.BuiltinTest.test_filter_pickle @ linux-x86_64 +test.test_builtin.BuiltinTest.test_format @ linux-x86_64 +test.test_builtin.BuiltinTest.test_general_eval @ linux-x86_64 +test.test_builtin.BuiltinTest.test_getattr @ linux-x86_64 +test.test_builtin.BuiltinTest.test_hasattr @ linux-x86_64 +test.test_builtin.BuiltinTest.test_hash @ linux-x86_64 +test.test_builtin.BuiltinTest.test_hex @ linux-x86_64 +test.test_builtin.BuiltinTest.test_id @ linux-x86_64 +test.test_builtin.BuiltinTest.test_import @ linux-x86_64 +test.test_builtin.BuiltinTest.test_input @ linux-x86_64 +test.test_builtin.BuiltinTest.test_isinstance @ linux-x86_64 +test.test_builtin.BuiltinTest.test_issubclass @ linux-x86_64 +test.test_builtin.BuiltinTest.test_iter @ linux-x86_64 +test.test_builtin.BuiltinTest.test_len @ linux-x86_64 +test.test_builtin.BuiltinTest.test_map @ linux-x86_64 +test.test_builtin.BuiltinTest.test_map_pickle @ linux-x86_64 +test.test_builtin.BuiltinTest.test_max @ linux-x86_64 +test.test_builtin.BuiltinTest.test_min @ linux-x86_64 +test.test_builtin.BuiltinTest.test_neg @ linux-x86_64 +test.test_builtin.BuiltinTest.test_next @ linux-x86_64 +test.test_builtin.BuiltinTest.test_oct @ linux-x86_64 +test.test_builtin.BuiltinTest.test_open @ linux-x86_64 +test.test_builtin.BuiltinTest.test_open_default_encoding @ linux-x86_64 +test.test_builtin.BuiltinTest.test_open_non_inheritable @ linux-x86_64 +test.test_builtin.BuiltinTest.test_ord @ linux-x86_64 +test.test_builtin.BuiltinTest.test_pow @ linux-x86_64 +test.test_builtin.BuiltinTest.test_repr @ linux-x86_64 +test.test_builtin.BuiltinTest.test_round @ linux-x86_64 +test.test_builtin.BuiltinTest.test_round_large @ linux-x86_64 +test.test_builtin.BuiltinTest.test_setattr @ linux-x86_64 +test.test_builtin.BuiltinTest.test_sum @ linux-x86_64 +test.test_builtin.BuiltinTest.test_type @ linux-x86_64 +test.test_builtin.BuiltinTest.test_vars @ linux-x86_64 +test.test_builtin.BuiltinTest.test_zip @ linux-x86_64 +test.test_builtin.BuiltinTest.test_zip_bad_iterable @ linux-x86_64 +test.test_builtin.BuiltinTest.test_zip_pickle @ linux-x86_64 +test.test_builtin.BuiltinTest.test_zip_pickle_strict @ linux-x86_64 +test.test_builtin.BuiltinTest.test_zip_pickle_strict_fail @ linux-x86_64 +test.test_builtin.BuiltinTest.test_zip_strict @ linux-x86_64 +test.test_builtin.BuiltinTest.test_zip_strict_error_handling @ linux-x86_64 +test.test_builtin.BuiltinTest.test_zip_strict_error_handling_stopiteration @ linux-x86_64 +test.test_builtin.BuiltinTest.test_zip_strict_iterators @ linux-x86_64 +test.test_builtin.TestBreakpoint.test_breakpoint @ linux-x86_64 +test.test_builtin.TestBreakpoint.test_breakpoint_with_args_and_keywords @ linux-x86_64 +test.test_builtin.TestBreakpoint.test_breakpoint_with_breakpointhook_reset @ linux-x86_64 +test.test_builtin.TestBreakpoint.test_breakpoint_with_breakpointhook_set @ linux-x86_64 +test.test_builtin.TestBreakpoint.test_breakpoint_with_passthru_error @ linux-x86_64 +test.test_builtin.TestBreakpoint.test_envar_good_path_builtin @ linux-x86_64 +test.test_builtin.TestBreakpoint.test_envar_good_path_empty_string @ linux-x86_64 +test.test_builtin.TestBreakpoint.test_envar_good_path_noop_0 @ linux-x86_64 +test.test_builtin.TestBreakpoint.test_envar_good_path_other @ linux-x86_64 +test.test_builtin.TestBreakpoint.test_envar_ignored_when_hook_is_set @ linux-x86_64 +test.test_builtin.TestBreakpoint.test_envar_unimportable @ linux-x86_64 +test.test_builtin.TestSorted.test_bad_arguments @ linux-x86_64 +test.test_builtin.TestSorted.test_baddecorator @ linux-x86_64 +test.test_builtin.TestSorted.test_basic @ linux-x86_64 +test.test_builtin.TestSorted.test_inputtypes @ linux-x86_64 +test.test_builtin.TestType.test_bad_args @ linux-x86_64 +test.test_builtin.TestType.test_bad_slots @ linux-x86_64 +test.test_builtin.TestType.test_namespace_order @ linux-x86_64 +test.test_builtin.TestType.test_new_type @ linux-x86_64 +test.test_builtin.TestType.test_type_doc @ linux-x86_64 +test.test_builtin.TestType.test_type_name @ linux-x86_64 +test.test_builtin.TestType.test_type_nokwargs @ linux-x86_64 +test.test_builtin.TestType.test_type_qualname @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bytes.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bytes.txt new file mode 100644 index 0000000000..ad3d40a2d2 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bytes.txt @@ -0,0 +1,269 @@ +test.test_bytes.AssortedBytesTest.test_compare_bytes_to_bytearray @ linux-x86_64 +test.test_bytes.AssortedBytesTest.test_doc @ linux-x86_64 +test.test_bytes.AssortedBytesTest.test_format @ linux-x86_64 +test.test_bytes.AssortedBytesTest.test_from_bytearray @ linux-x86_64 +test.test_bytes.AssortedBytesTest.test_literal @ linux-x86_64 +test.test_bytes.AssortedBytesTest.test_repr_str @ linux-x86_64 +test.test_bytes.AssortedBytesTest.test_return_self @ linux-x86_64 +test.test_bytes.AssortedBytesTest.test_rsplit_bytearray @ linux-x86_64 +test.test_bytes.AssortedBytesTest.test_split_bytearray @ linux-x86_64 +test.test_bytes.AssortedBytesTest.test_to_str @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_additional_rsplit @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_additional_split @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_capitalize @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_center @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_count @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_expandtabs @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_find @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_find_periodic_pattern @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_find_shift_table_overflow @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_fixtype @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_index @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_isalnum @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_isalpha @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_isascii @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_isdigit @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_islower @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_isspace @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_istitle @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_isupper @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_ljust @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_lower @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_removeprefix @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_removesuffix @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_replace @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_rfind @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_rindex @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_rjust @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_rsplit @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_split @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_splitlines @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_strip @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_strip_whitespace @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_swapcase @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_title @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_upper @ linux-x86_64 +test.test_bytes.ByteArrayAsStringTest.test_zfill @ linux-x86_64 +test.test_bytes.ByteArraySubclassTest.test_basic @ linux-x86_64 +test.test_bytes.ByteArraySubclassTest.test_copy @ linux-x86_64 +test.test_bytes.ByteArraySubclassTest.test_fromhex @ linux-x86_64 +test.test_bytes.ByteArraySubclassTest.test_init_override @ linux-x86_64 +test.test_bytes.ByteArraySubclassTest.test_join @ linux-x86_64 +test.test_bytes.ByteArraySubclassTest.test_pickle @ linux-x86_64 +test.test_bytes.ByteArraySubclassWithSlotsTest.test_basic @ linux-x86_64 +test.test_bytes.ByteArraySubclassWithSlotsTest.test_copy @ linux-x86_64 +test.test_bytes.ByteArraySubclassWithSlotsTest.test_fromhex @ linux-x86_64 +test.test_bytes.ByteArraySubclassWithSlotsTest.test_join @ linux-x86_64 +test.test_bytes.ByteArraySubclassWithSlotsTest.test_pickle @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_alloc @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_append @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_basics @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_bytearray_api @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_center @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_clear @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_compare @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_compare_to_str @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_concat @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_constructor_exceptions @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_constructor_type_errors @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_constructor_value_errors @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_contains @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_copied @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_copy @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_count @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_decode @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_del_expand @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_delitem @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_empty_sequence @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_encoding @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_endswith @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_exhausted_iterator @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_extend @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_extended_getslice @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_extended_set_del_slice @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_fifo_overrun @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_find @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_find_etc_raise_correct_error_messages @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_from_buffer @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_from_index @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_from_int @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_from_iterable @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_from_list @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_from_mutating_list @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_from_ssize @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_from_tuple @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_fromhex @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_getitem_error @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_getslice @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_hex @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_hex_separator_basics @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_hex_separator_five_bytes @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_hex_separator_six_bytes @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_iconcat @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_imod @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_index @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_init_alloc @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_insert @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_integer_arguments_out_of_byte_range @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_irepeat @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_irepeat_1char @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_iterator_length_hint @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_iterator_pickling @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_join @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_ljust @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_maketrans @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_mod @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_nohash @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_none_arguments @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_nosort @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_ord @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_partition @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_partition_bytearray_doesnt_share_nullstring @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_partition_int_error @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_partition_string_error @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_pickling @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_pop @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_regexps @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_remove @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_repeat @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_repeat_1char @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_repeat_after_setslice @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_replace @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_replace_int_error @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_reverse @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_reversed @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_rfind @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_rindex @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_rjust @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_rmod @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_rpartition @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_rsplit_unicodewhitespace @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_setitem @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_setitem_error @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_setslice @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_setslice_extend @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_setslice_trap @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_split_int_error @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_split_string_error @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_split_unicodewhitespace @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_sq_item @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_startswith @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_strip_bytearray @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_strip_int_error @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_strip_string_error @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_translate @ linux-x86_64 +test.test_bytes.ByteArrayTest.test_xjust_int_error @ linux-x86_64 +test.test_bytes.BytearrayPEP3137Test.test_returns_new_copy @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_additional_rsplit @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_additional_split @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_capitalize @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_center @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_count @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_expandtabs @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_find @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_find_periodic_pattern @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_find_shift_table_overflow @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_fixtype @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_index @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_isalnum @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_isalpha @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_isascii @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_isdigit @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_islower @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_isspace @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_istitle @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_isupper @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_ljust @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_lower @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_removeprefix @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_removesuffix @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_replace @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_rfind @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_rindex @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_rjust @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_rsplit @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_split @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_splitlines @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_strip @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_strip_whitespace @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_swapcase @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_title @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_upper @ linux-x86_64 +test.test_bytes.BytesAsStringTest.test_zfill @ linux-x86_64 +test.test_bytes.BytesSubclassTest.test_basic @ linux-x86_64 +test.test_bytes.BytesSubclassTest.test_copy @ linux-x86_64 +test.test_bytes.BytesSubclassTest.test_fromhex @ linux-x86_64 +test.test_bytes.BytesSubclassTest.test_join @ linux-x86_64 +test.test_bytes.BytesSubclassTest.test_pickle @ linux-x86_64 +test.test_bytes.BytesTest.test__bytes__ @ linux-x86_64 +test.test_bytes.BytesTest.test_basics @ linux-x86_64 +test.test_bytes.BytesTest.test_buffer_is_readonly @ linux-x86_64 +test.test_bytes.BytesTest.test_bytes_blocking @ linux-x86_64 +test.test_bytes.BytesTest.test_center @ linux-x86_64 +test.test_bytes.BytesTest.test_compare @ linux-x86_64 +test.test_bytes.BytesTest.test_compare_to_str @ linux-x86_64 +test.test_bytes.BytesTest.test_concat @ linux-x86_64 +test.test_bytes.BytesTest.test_constructor_exceptions @ linux-x86_64 +test.test_bytes.BytesTest.test_constructor_type_errors @ linux-x86_64 +test.test_bytes.BytesTest.test_constructor_value_errors @ linux-x86_64 +test.test_bytes.BytesTest.test_contains @ linux-x86_64 +test.test_bytes.BytesTest.test_copy @ linux-x86_64 +test.test_bytes.BytesTest.test_count @ linux-x86_64 +test.test_bytes.BytesTest.test_custom @ linux-x86_64 +test.test_bytes.BytesTest.test_decode @ linux-x86_64 +test.test_bytes.BytesTest.test_empty_sequence @ linux-x86_64 +test.test_bytes.BytesTest.test_encoding @ linux-x86_64 +test.test_bytes.BytesTest.test_endswith @ linux-x86_64 +test.test_bytes.BytesTest.test_extended_getslice @ linux-x86_64 +test.test_bytes.BytesTest.test_find @ linux-x86_64 +test.test_bytes.BytesTest.test_find_etc_raise_correct_error_messages @ linux-x86_64 +test.test_bytes.BytesTest.test_from_buffer @ linux-x86_64 +test.test_bytes.BytesTest.test_from_index @ linux-x86_64 +test.test_bytes.BytesTest.test_from_int @ linux-x86_64 +test.test_bytes.BytesTest.test_from_iterable @ linux-x86_64 +test.test_bytes.BytesTest.test_from_list @ linux-x86_64 +test.test_bytes.BytesTest.test_from_mutating_list @ linux-x86_64 +test.test_bytes.BytesTest.test_from_ssize @ linux-x86_64 +test.test_bytes.BytesTest.test_from_tuple @ linux-x86_64 +test.test_bytes.BytesTest.test_fromhex @ linux-x86_64 +test.test_bytes.BytesTest.test_getitem_error @ linux-x86_64 +test.test_bytes.BytesTest.test_getslice @ linux-x86_64 +test.test_bytes.BytesTest.test_hex @ linux-x86_64 +test.test_bytes.BytesTest.test_hex_separator_basics @ linux-x86_64 +test.test_bytes.BytesTest.test_hex_separator_five_bytes @ linux-x86_64 +test.test_bytes.BytesTest.test_hex_separator_six_bytes @ linux-x86_64 +test.test_bytes.BytesTest.test_imod @ linux-x86_64 +test.test_bytes.BytesTest.test_index @ linux-x86_64 +test.test_bytes.BytesTest.test_integer_arguments_out_of_byte_range @ linux-x86_64 +test.test_bytes.BytesTest.test_iterator_pickling @ linux-x86_64 +test.test_bytes.BytesTest.test_join @ linux-x86_64 +test.test_bytes.BytesTest.test_ljust @ linux-x86_64 +test.test_bytes.BytesTest.test_maketrans @ linux-x86_64 +test.test_bytes.BytesTest.test_mod @ linux-x86_64 +test.test_bytes.BytesTest.test_none_arguments @ linux-x86_64 +test.test_bytes.BytesTest.test_ord @ linux-x86_64 +test.test_bytes.BytesTest.test_partition @ linux-x86_64 +test.test_bytes.BytesTest.test_partition_int_error @ linux-x86_64 +test.test_bytes.BytesTest.test_partition_string_error @ linux-x86_64 +test.test_bytes.BytesTest.test_pickling @ linux-x86_64 +test.test_bytes.BytesTest.test_repeat @ linux-x86_64 +test.test_bytes.BytesTest.test_repeat_1char @ linux-x86_64 +test.test_bytes.BytesTest.test_replace @ linux-x86_64 +test.test_bytes.BytesTest.test_replace_int_error @ linux-x86_64 +test.test_bytes.BytesTest.test_reversed @ linux-x86_64 +test.test_bytes.BytesTest.test_rfind @ linux-x86_64 +test.test_bytes.BytesTest.test_rindex @ linux-x86_64 +test.test_bytes.BytesTest.test_rjust @ linux-x86_64 +test.test_bytes.BytesTest.test_rmod @ linux-x86_64 +test.test_bytes.BytesTest.test_rpartition @ linux-x86_64 +test.test_bytes.BytesTest.test_rsplit_unicodewhitespace @ linux-x86_64 +test.test_bytes.BytesTest.test_split_int_error @ linux-x86_64 +test.test_bytes.BytesTest.test_split_string_error @ linux-x86_64 +test.test_bytes.BytesTest.test_split_unicodewhitespace @ linux-x86_64 +test.test_bytes.BytesTest.test_sq_item @ linux-x86_64 +test.test_bytes.BytesTest.test_startswith @ linux-x86_64 +test.test_bytes.BytesTest.test_strip_bytearray @ linux-x86_64 +test.test_bytes.BytesTest.test_strip_int_error @ linux-x86_64 +test.test_bytes.BytesTest.test_strip_string_error @ linux-x86_64 +test.test_bytes.BytesTest.test_translate @ linux-x86_64 +test.test_bytes.BytesTest.test_xjust_int_error @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bz2.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bz2.txt new file mode 100644 index 0000000000..207a85ee3c --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_bz2.txt @@ -0,0 +1,94 @@ +test.test_bz2.BZ2CompressorTest.testCompress @ linux-x86_64 +test.test_bz2.BZ2CompressorTest.testCompress4G @ linux-x86_64 +test.test_bz2.BZ2CompressorTest.testCompressChunks10 @ linux-x86_64 +test.test_bz2.BZ2CompressorTest.testCompressEmptyString @ linux-x86_64 +test.test_bz2.BZ2CompressorTest.testPickle @ linux-x86_64 +test.test_bz2.BZ2DecompressorTest.testDecompress @ linux-x86_64 +test.test_bz2.BZ2DecompressorTest.testDecompress4G @ linux-x86_64 +test.test_bz2.BZ2DecompressorTest.testDecompressChunks10 @ linux-x86_64 +test.test_bz2.BZ2DecompressorTest.testDecompressUnusedData @ linux-x86_64 +test.test_bz2.BZ2DecompressorTest.testDecompressorChunksMaxsize @ linux-x86_64 +test.test_bz2.BZ2DecompressorTest.testEOFError @ linux-x86_64 +test.test_bz2.BZ2DecompressorTest.testPickle @ linux-x86_64 +test.test_bz2.BZ2DecompressorTest.test_Constructor @ linux-x86_64 +test.test_bz2.BZ2DecompressorTest.test_decompressor_inputbuf_1 @ linux-x86_64 +test.test_bz2.BZ2DecompressorTest.test_decompressor_inputbuf_2 @ linux-x86_64 +test.test_bz2.BZ2DecompressorTest.test_decompressor_inputbuf_3 @ linux-x86_64 +test.test_bz2.BZ2DecompressorTest.test_failure @ linux-x86_64 +test.test_bz2.BZ2FileTest.testAppend @ linux-x86_64 +test.test_bz2.BZ2FileTest.testBadArgs @ linux-x86_64 +test.test_bz2.BZ2FileTest.testClosedIteratorDeadlock @ linux-x86_64 +test.test_bz2.BZ2FileTest.testContextProtocol @ linux-x86_64 +test.test_bz2.BZ2FileTest.testDecompressLimited @ linux-x86_64 +test.test_bz2.BZ2FileTest.testFileno @ linux-x86_64 +test.test_bz2.BZ2FileTest.testIterator @ linux-x86_64 +test.test_bz2.BZ2FileTest.testIteratorMultiStream @ linux-x86_64 +test.test_bz2.BZ2FileTest.testMixedIterationAndReads @ linux-x86_64 +test.test_bz2.BZ2FileTest.testMultiStreamOrdering @ linux-x86_64 +test.test_bz2.BZ2FileTest.testOpenBytesFilename @ linux-x86_64 +test.test_bz2.BZ2FileTest.testOpenNonexistent @ linux-x86_64 +test.test_bz2.BZ2FileTest.testOpenPathLikeFilename @ linux-x86_64 +test.test_bz2.BZ2FileTest.testPeek @ linux-x86_64 +test.test_bz2.BZ2FileTest.testPeekBytesIO @ linux-x86_64 +test.test_bz2.BZ2FileTest.testRead @ linux-x86_64 +test.test_bz2.BZ2FileTest.testRead0 @ linux-x86_64 +test.test_bz2.BZ2FileTest.testRead100 @ linux-x86_64 +test.test_bz2.BZ2FileTest.testReadBadFile @ linux-x86_64 +test.test_bz2.BZ2FileTest.testReadBytesIO @ linux-x86_64 +test.test_bz2.BZ2FileTest.testReadChunk10 @ linux-x86_64 +test.test_bz2.BZ2FileTest.testReadChunk10MultiStream @ linux-x86_64 +test.test_bz2.BZ2FileTest.testReadInto @ linux-x86_64 +test.test_bz2.BZ2FileTest.testReadLine @ linux-x86_64 +test.test_bz2.BZ2FileTest.testReadLineMultiStream @ linux-x86_64 +test.test_bz2.BZ2FileTest.testReadLines @ linux-x86_64 +test.test_bz2.BZ2FileTest.testReadLinesMultiStream @ linux-x86_64 +test.test_bz2.BZ2FileTest.testReadMonkeyMultiStream @ linux-x86_64 +test.test_bz2.BZ2FileTest.testReadMultiStream @ linux-x86_64 +test.test_bz2.BZ2FileTest.testReadMultiStreamTrailingJunk @ linux-x86_64 +test.test_bz2.BZ2FileTest.testReadTrailingJunk @ linux-x86_64 +test.test_bz2.BZ2FileTest.testReadable @ linux-x86_64 +test.test_bz2.BZ2FileTest.testReadlinesNoNewline @ linux-x86_64 +test.test_bz2.BZ2FileTest.testSeekBackwards @ linux-x86_64 +test.test_bz2.BZ2FileTest.testSeekBackwardsAcrossStreams @ linux-x86_64 +test.test_bz2.BZ2FileTest.testSeekBackwardsBytesIO @ linux-x86_64 +test.test_bz2.BZ2FileTest.testSeekBackwardsFromEnd @ linux-x86_64 +test.test_bz2.BZ2FileTest.testSeekBackwardsFromEndAcrossStreams @ linux-x86_64 +test.test_bz2.BZ2FileTest.testSeekForward @ linux-x86_64 +test.test_bz2.BZ2FileTest.testSeekForwardAcrossStreams @ linux-x86_64 +test.test_bz2.BZ2FileTest.testSeekForwardBytesIO @ linux-x86_64 +test.test_bz2.BZ2FileTest.testSeekPostEnd @ linux-x86_64 +test.test_bz2.BZ2FileTest.testSeekPostEndMultiStream @ linux-x86_64 +test.test_bz2.BZ2FileTest.testSeekPostEndTwice @ linux-x86_64 +test.test_bz2.BZ2FileTest.testSeekPostEndTwiceMultiStream @ linux-x86_64 +test.test_bz2.BZ2FileTest.testSeekPreStart @ linux-x86_64 +test.test_bz2.BZ2FileTest.testSeekPreStartMultiStream @ linux-x86_64 +test.test_bz2.BZ2FileTest.testSeekable @ linux-x86_64 +test.test_bz2.BZ2FileTest.testThreading @ linux-x86_64 +test.test_bz2.BZ2FileTest.testWritable @ linux-x86_64 +test.test_bz2.BZ2FileTest.testWrite @ linux-x86_64 +test.test_bz2.BZ2FileTest.testWriteBytesIO @ linux-x86_64 +test.test_bz2.BZ2FileTest.testWriteChunks10 @ linux-x86_64 +test.test_bz2.BZ2FileTest.testWriteLines @ linux-x86_64 +test.test_bz2.BZ2FileTest.testWriteMethodsOnReadOnlyFile @ linux-x86_64 +test.test_bz2.BZ2FileTest.testWriteNonDefaultCompressLevel @ linux-x86_64 +test.test_bz2.BZ2FileTest.test_issue44439 @ linux-x86_64 +test.test_bz2.BZ2FileTest.test_read_truncated @ linux-x86_64 +test.test_bz2.CompressDecompressTest.testCompress @ linux-x86_64 +test.test_bz2.CompressDecompressTest.testCompressEmptyString @ linux-x86_64 +test.test_bz2.CompressDecompressTest.testDecompress @ linux-x86_64 +test.test_bz2.CompressDecompressTest.testDecompressBadData @ linux-x86_64 +test.test_bz2.CompressDecompressTest.testDecompressEmpty @ linux-x86_64 +test.test_bz2.CompressDecompressTest.testDecompressIncomplete @ linux-x86_64 +test.test_bz2.CompressDecompressTest.testDecompressMultiStream @ linux-x86_64 +test.test_bz2.CompressDecompressTest.testDecompressMultiStreamTrailingJunk @ linux-x86_64 +test.test_bz2.CompressDecompressTest.testDecompressToEmptyString @ linux-x86_64 +test.test_bz2.CompressDecompressTest.testDecompressTrailingJunk @ linux-x86_64 +test.test_bz2.OpenTest.test_bad_params @ linux-x86_64 +test.test_bz2.OpenTest.test_binary_modes @ linux-x86_64 +test.test_bz2.OpenTest.test_encoding @ linux-x86_64 +test.test_bz2.OpenTest.test_encoding_error_handler @ linux-x86_64 +test.test_bz2.OpenTest.test_fileobj @ linux-x86_64 +test.test_bz2.OpenTest.test_implicit_binary_modes @ linux-x86_64 +test.test_bz2.OpenTest.test_newline @ linux-x86_64 +test.test_bz2.OpenTest.test_text_modes @ linux-x86_64 +test.test_bz2.OpenTest.test_x_mode @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_calendar.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_calendar.txt new file mode 100644 index 0000000000..2073a0d353 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_calendar.txt @@ -0,0 +1,71 @@ +test.test_calendar.CalendarTestCase.test_days @ linux-x86_64 +test.test_calendar.CalendarTestCase.test_enumerate_weekdays @ linux-x86_64 +test.test_calendar.CalendarTestCase.test_illegal_weekday_reported @ linux-x86_64 +test.test_calendar.CalendarTestCase.test_isleap @ linux-x86_64 +test.test_calendar.CalendarTestCase.test_itermonthdays @ linux-x86_64 +test.test_calendar.CalendarTestCase.test_itermonthdays2 @ linux-x86_64 +test.test_calendar.CalendarTestCase.test_itermonthdays3 @ linux-x86_64 +test.test_calendar.CalendarTestCase.test_itermonthdays4 @ linux-x86_64 +test.test_calendar.CalendarTestCase.test_iterweekdays @ linux-x86_64 +test.test_calendar.CalendarTestCase.test_locale_calendar_formatweekday @ linux-x86_64 +test.test_calendar.CalendarTestCase.test_locale_calendars @ linux-x86_64 +test.test_calendar.CalendarTestCase.test_locale_html_calendar_custom_css_class_month_name @ linux-x86_64 +test.test_calendar.CalendarTestCase.test_locale_html_calendar_custom_css_class_weekday @ linux-x86_64 +test.test_calendar.CalendarTestCase.test_months @ linux-x86_64 +test.test_calendar.CalendarTestCase.test_setfirstweekday @ linux-x86_64 +test.test_calendar.CommandLineTestCase.test_help @ linux-x86_64 +test.test_calendar.CommandLineTestCase.test_html_output_current_year @ linux-x86_64 +test.test_calendar.CommandLineTestCase.test_html_output_year_css @ linux-x86_64 +test.test_calendar.CommandLineTestCase.test_html_output_year_encoding @ linux-x86_64 +test.test_calendar.CommandLineTestCase.test_illegal_arguments @ linux-x86_64 +test.test_calendar.CommandLineTestCase.test_option_encoding @ linux-x86_64 +test.test_calendar.CommandLineTestCase.test_option_lines @ linux-x86_64 +test.test_calendar.CommandLineTestCase.test_option_locale @ linux-x86_64 +test.test_calendar.CommandLineTestCase.test_option_months @ linux-x86_64 +test.test_calendar.CommandLineTestCase.test_option_spacing @ linux-x86_64 +test.test_calendar.CommandLineTestCase.test_option_type @ linux-x86_64 +test.test_calendar.CommandLineTestCase.test_option_width @ linux-x86_64 +test.test_calendar.CommandLineTestCase.test_output_current_year @ linux-x86_64 +test.test_calendar.CommandLineTestCase.test_output_month @ linux-x86_64 +test.test_calendar.CommandLineTestCase.test_output_year @ linux-x86_64 +test.test_calendar.LeapdaysTestCase.test_no_leapdays @ linux-x86_64 +test.test_calendar.LeapdaysTestCase.test_no_leapdays_upper_boundary @ linux-x86_64 +test.test_calendar.LeapdaysTestCase.test_no_range @ linux-x86_64 +test.test_calendar.LeapdaysTestCase.test_one_leapday_lower_boundary @ linux-x86_64 +test.test_calendar.LeapdaysTestCase.test_several_leapyears_in_range @ linux-x86_64 +test.test_calendar.MiscTestCase.test__all__ @ linux-x86_64 +test.test_calendar.MondayTestCase.test_april @ linux-x86_64 +test.test_calendar.MondayTestCase.test_december @ linux-x86_64 +test.test_calendar.MondayTestCase.test_february @ linux-x86_64 +test.test_calendar.MonthRangeTestCase.test_december @ linux-x86_64 +test.test_calendar.MonthRangeTestCase.test_february_leap @ linux-x86_64 +test.test_calendar.MonthRangeTestCase.test_february_nonleap @ linux-x86_64 +test.test_calendar.MonthRangeTestCase.test_illegal_month_reported @ linux-x86_64 +test.test_calendar.MonthRangeTestCase.test_january @ linux-x86_64 +test.test_calendar.MonthRangeTestCase.test_thirteenth_month @ linux-x86_64 +test.test_calendar.MonthRangeTestCase.test_zeroth_month @ linux-x86_64 +test.test_calendar.OutputTestCase.test_format @ linux-x86_64 +test.test_calendar.OutputTestCase.test_formatmonth @ linux-x86_64 +test.test_calendar.OutputTestCase.test_formatmonthname_with_year @ linux-x86_64 +test.test_calendar.OutputTestCase.test_formatmonthname_without_year @ linux-x86_64 +test.test_calendar.OutputTestCase.test_formatweekheader_long @ linux-x86_64 +test.test_calendar.OutputTestCase.test_formatweekheader_short @ linux-x86_64 +test.test_calendar.OutputTestCase.test_output @ linux-x86_64 +test.test_calendar.OutputTestCase.test_output_htmlcalendar_encoding_ascii @ linux-x86_64 +test.test_calendar.OutputTestCase.test_output_htmlcalendar_encoding_utf8 @ linux-x86_64 +test.test_calendar.OutputTestCase.test_output_textcalendar @ linux-x86_64 +test.test_calendar.OutputTestCase.test_prmonth @ linux-x86_64 +test.test_calendar.OutputTestCase.test_prweek @ linux-x86_64 +test.test_calendar.OutputTestCase.test_pryear @ linux-x86_64 +test.test_calendar.OutputTestCase.test_yeardatescalendar @ linux-x86_64 +test.test_calendar.OutputTestCase.test_yeardayscalendar @ linux-x86_64 +test.test_calendar.SundayTestCase.test_april @ linux-x86_64 +test.test_calendar.SundayTestCase.test_december @ linux-x86_64 +test.test_calendar.SundayTestCase.test_february @ linux-x86_64 +test.test_calendar.TestSubClassingCase.test_format_year @ linux-x86_64 +test.test_calendar.TestSubClassingCase.test_format_year_head @ linux-x86_64 +test.test_calendar.TestSubClassingCase.test_formatmonth @ linux-x86_64 +test.test_calendar.TestSubClassingCase.test_formatmonthname @ linux-x86_64 +test.test_calendar.TestSubClassingCase.test_formatweek @ linux-x86_64 +test.test_calendar.TestSubClassingCase.test_formatweek_head @ linux-x86_64 +test.test_calendar.TimegmTestCase.test_timegm @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_call.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_call.txt new file mode 100644 index 0000000000..f0f74964cc --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_call.txt @@ -0,0 +1,66 @@ +test.test_call.FastCallTests.test_fastcall @ linux-x86_64 +test.test_call.FastCallTests.test_fastcall_clearing_dict @ linux-x86_64 +test.test_call.FastCallTests.test_vectorcall @ linux-x86_64 +test.test_call.FastCallTests.test_vectorcall_dict @ linux-x86_64 +test.test_call.FunctionCalls.test_frames_are_popped_after_failed_calls @ linux-x86_64 +test.test_call.FunctionCalls.test_kwargs_order @ linux-x86_64 +test.test_call.TestCallingConventions.test_fastcall @ linux-x86_64 +test.test_call.TestCallingConventions.test_fastcall_ext @ linux-x86_64 +test.test_call.TestCallingConventions.test_fastcall_keywords @ linux-x86_64 +test.test_call.TestCallingConventions.test_fastcall_keywords_ext @ linux-x86_64 +test.test_call.TestCallingConventions.test_noargs @ linux-x86_64 +test.test_call.TestCallingConventions.test_noargs_ext @ linux-x86_64 +test.test_call.TestCallingConventions.test_o @ linux-x86_64 +test.test_call.TestCallingConventions.test_o_ext @ linux-x86_64 +test.test_call.TestCallingConventions.test_varargs @ linux-x86_64 +test.test_call.TestCallingConventions.test_varargs_ext @ linux-x86_64 +test.test_call.TestCallingConventions.test_varargs_keywords @ linux-x86_64 +test.test_call.TestCallingConventions.test_varargs_keywords_ext @ linux-x86_64 +test.test_call.TestCallingConventionsClass.test_fastcall @ linux-x86_64 +test.test_call.TestCallingConventionsClass.test_fastcall_ext @ linux-x86_64 +test.test_call.TestCallingConventionsClass.test_fastcall_keywords @ linux-x86_64 +test.test_call.TestCallingConventionsClass.test_fastcall_keywords_ext @ linux-x86_64 +test.test_call.TestCallingConventionsClass.test_noargs @ linux-x86_64 +test.test_call.TestCallingConventionsClass.test_noargs_ext @ linux-x86_64 +test.test_call.TestCallingConventionsClass.test_o @ linux-x86_64 +test.test_call.TestCallingConventionsClass.test_o_ext @ linux-x86_64 +test.test_call.TestCallingConventionsClass.test_varargs @ linux-x86_64 +test.test_call.TestCallingConventionsClass.test_varargs_ext @ linux-x86_64 +test.test_call.TestCallingConventionsClass.test_varargs_keywords @ linux-x86_64 +test.test_call.TestCallingConventionsClass.test_varargs_keywords_ext @ linux-x86_64 +test.test_call.TestCallingConventionsClassInstance.test_fastcall @ linux-x86_64 +test.test_call.TestCallingConventionsClassInstance.test_fastcall_ext @ linux-x86_64 +test.test_call.TestCallingConventionsClassInstance.test_fastcall_keywords @ linux-x86_64 +test.test_call.TestCallingConventionsClassInstance.test_fastcall_keywords_ext @ linux-x86_64 +test.test_call.TestCallingConventionsClassInstance.test_noargs @ linux-x86_64 +test.test_call.TestCallingConventionsClassInstance.test_noargs_ext @ linux-x86_64 +test.test_call.TestCallingConventionsClassInstance.test_o @ linux-x86_64 +test.test_call.TestCallingConventionsClassInstance.test_o_ext @ linux-x86_64 +test.test_call.TestCallingConventionsClassInstance.test_varargs @ linux-x86_64 +test.test_call.TestCallingConventionsClassInstance.test_varargs_ext @ linux-x86_64 +test.test_call.TestCallingConventionsClassInstance.test_varargs_keywords @ linux-x86_64 +test.test_call.TestCallingConventionsClassInstance.test_varargs_keywords_ext @ linux-x86_64 +test.test_call.TestCallingConventionsInstance.test_fastcall @ linux-x86_64 +test.test_call.TestCallingConventionsInstance.test_fastcall_ext @ linux-x86_64 +test.test_call.TestCallingConventionsInstance.test_fastcall_keywords @ linux-x86_64 +test.test_call.TestCallingConventionsInstance.test_fastcall_keywords_ext @ linux-x86_64 +test.test_call.TestCallingConventionsInstance.test_noargs @ linux-x86_64 +test.test_call.TestCallingConventionsInstance.test_noargs_ext @ linux-x86_64 +test.test_call.TestCallingConventionsInstance.test_o @ linux-x86_64 +test.test_call.TestCallingConventionsInstance.test_o_ext @ linux-x86_64 +test.test_call.TestCallingConventionsInstance.test_varargs @ linux-x86_64 +test.test_call.TestCallingConventionsInstance.test_varargs_ext @ linux-x86_64 +test.test_call.TestCallingConventionsInstance.test_varargs_keywords @ linux-x86_64 +test.test_call.TestCallingConventionsInstance.test_varargs_keywords_ext @ linux-x86_64 +test.test_call.TestCallingConventionsStatic.test_fastcall @ linux-x86_64 +test.test_call.TestCallingConventionsStatic.test_fastcall_ext @ linux-x86_64 +test.test_call.TestCallingConventionsStatic.test_fastcall_keywords @ linux-x86_64 +test.test_call.TestCallingConventionsStatic.test_fastcall_keywords_ext @ linux-x86_64 +test.test_call.TestCallingConventionsStatic.test_noargs @ linux-x86_64 +test.test_call.TestCallingConventionsStatic.test_noargs_ext @ linux-x86_64 +test.test_call.TestCallingConventionsStatic.test_o @ linux-x86_64 +test.test_call.TestCallingConventionsStatic.test_o_ext @ linux-x86_64 +test.test_call.TestCallingConventionsStatic.test_varargs @ linux-x86_64 +test.test_call.TestCallingConventionsStatic.test_varargs_ext @ linux-x86_64 +test.test_call.TestCallingConventionsStatic.test_varargs_keywords @ linux-x86_64 +test.test_call.TestCallingConventionsStatic.test_varargs_keywords_ext @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_capi.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_capi.txt new file mode 100644 index 0000000000..cf2abd1c77 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_capi.txt @@ -0,0 +1,150 @@ +test.test_capi.test_codecs.CAPITest.test_decodeutf8 @ linux-x86_64 +test.test_capi.test_codecs.CAPITest.test_decodeutf8stateful @ linux-x86_64 +test.test_capi.test_eval_code_ex.PyEval_EvalCodeExTests.test_simple @ linux-x86_64 +test.test_capi.test_eval_code_ex.PyEval_EvalCodeExTests.test_with_args @ linux-x86_64 +test.test_capi.test_eval_code_ex.PyEval_EvalCodeExTests.test_with_closure @ linux-x86_64 +test.test_capi.test_eval_code_ex.PyEval_EvalCodeExTests.test_with_default @ linux-x86_64 +test.test_capi.test_eval_code_ex.PyEval_EvalCodeExTests.test_with_kwarg_default @ linux-x86_64 +test.test_capi.test_getargs.Boolean_TestCase.test_p @ linux-x86_64 +test.test_capi.test_getargs.Bytes_TestCase.test_c @ linux-x86_64 +test.test_capi.test_getargs.Bytes_TestCase.test_w_star @ linux-x86_64 +test.test_capi.test_getargs.Bytes_TestCase.test_y @ linux-x86_64 +test.test_capi.test_getargs.Bytes_TestCase.test_y_hash @ linux-x86_64 +test.test_capi.test_getargs.Bytes_TestCase.test_y_star @ linux-x86_64 +test.test_capi.test_getargs.Float_TestCase.test_D @ linux-x86_64 +test.test_capi.test_getargs.Float_TestCase.test_d @ linux-x86_64 +test.test_capi.test_getargs.Float_TestCase.test_f @ linux-x86_64 +test.test_capi.test_getargs.Float_TestCase.test_f_rounding @ linux-x86_64 +test.test_capi.test_getargs.KeywordOnly_TestCase.test_invalid_keyword @ linux-x86_64 +test.test_capi.test_getargs.KeywordOnly_TestCase.test_keyword_args @ linux-x86_64 +test.test_capi.test_getargs.KeywordOnly_TestCase.test_mixed_args @ linux-x86_64 +test.test_capi.test_getargs.KeywordOnly_TestCase.test_optional_args @ linux-x86_64 +test.test_capi.test_getargs.KeywordOnly_TestCase.test_positional_args @ linux-x86_64 +test.test_capi.test_getargs.KeywordOnly_TestCase.test_required_args @ linux-x86_64 +test.test_capi.test_getargs.KeywordOnly_TestCase.test_surrogate_keyword @ linux-x86_64 +test.test_capi.test_getargs.KeywordOnly_TestCase.test_too_many_args @ linux-x86_64 +test.test_capi.test_getargs.Keywords_TestCase.test_invalid_keyword @ linux-x86_64 +test.test_capi.test_getargs.Keywords_TestCase.test_keyword_args @ linux-x86_64 +test.test_capi.test_getargs.Keywords_TestCase.test_kwargs @ linux-x86_64 +test.test_capi.test_getargs.Keywords_TestCase.test_mixed_args @ linux-x86_64 +test.test_capi.test_getargs.Keywords_TestCase.test_optional_args @ linux-x86_64 +test.test_capi.test_getargs.Keywords_TestCase.test_positional_args @ linux-x86_64 +test.test_capi.test_getargs.Keywords_TestCase.test_required_args @ linux-x86_64 +test.test_capi.test_getargs.Keywords_TestCase.test_surrogate_keyword @ linux-x86_64 +test.test_capi.test_getargs.Keywords_TestCase.test_too_many_args @ linux-x86_64 +test.test_capi.test_getargs.LongLong_TestCase.test_K @ linux-x86_64 +test.test_capi.test_getargs.LongLong_TestCase.test_L @ linux-x86_64 +test.test_capi.test_getargs.Object_TestCase.test_S @ linux-x86_64 +test.test_capi.test_getargs.Object_TestCase.test_Y @ linux-x86_64 +test.test_capi.test_getargs.ParseTupleAndKeywords_Test.test_bad_use @ linux-x86_64 +test.test_capi.test_getargs.ParseTupleAndKeywords_Test.test_nested_tuple @ linux-x86_64 +test.test_capi.test_getargs.ParseTupleAndKeywords_Test.test_parse_tuple_and_keywords @ linux-x86_64 +test.test_capi.test_getargs.ParseTupleAndKeywords_Test.test_positional_only @ linux-x86_64 +test.test_capi.test_getargs.PositionalOnlyAndKeywords_TestCase.test_empty_keyword @ linux-x86_64 +test.test_capi.test_getargs.PositionalOnlyAndKeywords_TestCase.test_mixed_args @ linux-x86_64 +test.test_capi.test_getargs.PositionalOnlyAndKeywords_TestCase.test_optional_args @ linux-x86_64 +test.test_capi.test_getargs.PositionalOnlyAndKeywords_TestCase.test_positional_args @ linux-x86_64 +test.test_capi.test_getargs.PositionalOnlyAndKeywords_TestCase.test_required_args @ linux-x86_64 +test.test_capi.test_getargs.Signed_TestCase.test_h @ linux-x86_64 +test.test_capi.test_getargs.Signed_TestCase.test_i @ linux-x86_64 +test.test_capi.test_getargs.Signed_TestCase.test_l @ linux-x86_64 +test.test_capi.test_getargs.Signed_TestCase.test_n @ linux-x86_64 +test.test_capi.test_getargs.SkipitemTest.test_skipitem @ linux-x86_64 +test.test_capi.test_getargs.SkipitemTest.test_skipitem_with_suffix @ linux-x86_64 +test.test_capi.test_getargs.String_TestCase.test_C @ linux-x86_64 +test.test_capi.test_getargs.String_TestCase.test_gh_99240_clear_args @ linux-x86_64 +test.test_capi.test_getargs.String_TestCase.test_s @ linux-x86_64 +test.test_capi.test_getargs.String_TestCase.test_s_hash @ linux-x86_64 +test.test_capi.test_getargs.String_TestCase.test_s_hash_int @ linux-x86_64 +test.test_capi.test_getargs.String_TestCase.test_s_star @ linux-x86_64 +test.test_capi.test_getargs.String_TestCase.test_z @ linux-x86_64 +test.test_capi.test_getargs.String_TestCase.test_z_hash @ linux-x86_64 +test.test_capi.test_getargs.String_TestCase.test_z_star @ linux-x86_64 +test.test_capi.test_getargs.Test_testcapi.test_L_code @ linux-x86_64 +test.test_capi.test_getargs.Test_testcapi.test_k_code @ linux-x86_64 +test.test_capi.test_getargs.Test_testcapi.test_s_code @ linux-x86_64 +test.test_capi.test_getargs.Tuple_TestCase.test_args @ linux-x86_64 +test.test_capi.test_getargs.Tuple_TestCase.test_tuple @ linux-x86_64 +test.test_capi.test_getargs.Unsigned_TestCase.test_B @ linux-x86_64 +test.test_capi.test_getargs.Unsigned_TestCase.test_H @ linux-x86_64 +test.test_capi.test_getargs.Unsigned_TestCase.test_I @ linux-x86_64 +test.test_capi.test_getargs.Unsigned_TestCase.test_b @ linux-x86_64 +test.test_capi.test_getargs.Unsigned_TestCase.test_k @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_c_type_with_ipow @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_c_type_with_matrix_multiplication @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_export_symbols @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_getitem_with_error @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_heaptype_with_buffer @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_heaptype_with_dict @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_heaptype_with_negative_dict @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_heaptype_with_setattro @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_instancemethod @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_mapping_has_key @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_mapping_keys_values_items @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_mapping_keys_values_items_bad_arg @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_memoryview_from_NULL_pointer @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_multiple_inheritance_ctypes_with_weakref_or_dict @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_null_type_doc @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_pynumber_tobase @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_pyobject_bytes_from_null @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_pyobject_repr_from_null @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_pyobject_str_from_null @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_return_null_without_error @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_return_result_with_error @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_sequence_del_slice @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_sequence_set_slice @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_subprocess_fork_exec @ linux-x86_64 +test.test_capi.test_misc.CAPITest.test_sys_getobject @ linux-x86_64 +test.test_capi.test_misc.Test_FrameAPI.test_frame_fback_api @ linux-x86_64 +test.test_capi.test_misc.Test_FrameAPI.test_frame_getters @ linux-x86_64 +test.test_capi.test_misc.Test_ModuleStateAccess.test_get_module_bad_def @ linux-x86_64 +test.test_capi.test_misc.Test_ModuleStateAccess.test_get_module_static_in_mro @ linux-x86_64 +test.test_capi.test_misc.Test_ModuleStateAccess.test_subclass_get_module @ linux-x86_64 +test.test_capi.test_misc.Test_ModuleStateAccess.test_subclass_get_module_with_super @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_buildvalue_issue38913 @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_config @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_datetime_capi @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_decref_doesnt_leak @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_dict_iteration @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_empty_argparse @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_from_contiguous @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_gc_control @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_get_statictype_slots @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_get_type_name @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_get_type_qualname @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_incref_decref_API @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_incref_doesnt_leak @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_lazy_hash_inheritance @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_list_api @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_long_and_overflow @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_long_api @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_long_as_double @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_long_as_size_t @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_long_as_unsigned_long_long_mask @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_long_long_and_overflow @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_long_numbits @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_longlong_api @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_mapping_has_key_string @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_py_is_funcs @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_py_is_macros @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_pymem_alloc0 @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_pythread_tss_key_state @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_set_type_size @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_sizeof_c_types @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_string_from_format @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_string_to_double @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_structseq_newtype_doesnt_leak @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_type_from_ephemeral_spec @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_unicode_compare_with_ascii @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_with_docstring @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_xdecref_doesnt_leak @ linux-x86_64 +test.test_capi.test_misc.Test_testcapi.test_xincref_doesnt_leak @ linux-x86_64 +test.test_capi.test_structmembers.ReadWriteTests.test_bad_assignments @ linux-x86_64 +test.test_capi.test_structmembers.ReadWriteTests.test_bool @ linux-x86_64 +test.test_capi.test_structmembers.ReadWriteTests.test_byte @ linux-x86_64 +test.test_capi.test_structmembers.ReadWriteTests.test_inplace_string @ linux-x86_64 +test.test_capi.test_structmembers.ReadWriteTests.test_int @ linux-x86_64 +test.test_capi.test_structmembers.ReadWriteTests.test_long @ linux-x86_64 +test.test_capi.test_structmembers.ReadWriteTests.test_longlong @ linux-x86_64 +test.test_capi.test_structmembers.ReadWriteTests.test_py_ssize_t @ linux-x86_64 +test.test_capi.test_structmembers.ReadWriteTests.test_short @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cgi.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cgi.txt new file mode 100644 index 0000000000..6fa6fd178b --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cgi.txt @@ -0,0 +1,23 @@ +test.test_cgi.CgiTests.testQSAndFormData @ linux-x86_64 +test.test_cgi.CgiTests.testQSAndFormDataFile @ linux-x86_64 +test.test_cgi.CgiTests.testQSAndUrlEncode @ linux-x86_64 +test.test_cgi.CgiTests.test_all @ linux-x86_64 +test.test_cgi.CgiTests.test_field_storage_multipart_no_content_length @ linux-x86_64 +test.test_cgi.CgiTests.test_fieldstorage_as_context_manager @ linux-x86_64 +test.test_cgi.CgiTests.test_fieldstorage_invalid @ linux-x86_64 +test.test_cgi.CgiTests.test_fieldstorage_multipart @ linux-x86_64 +test.test_cgi.CgiTests.test_fieldstorage_multipart_leading_whitespace @ linux-x86_64 +test.test_cgi.CgiTests.test_fieldstorage_multipart_maxline @ linux-x86_64 +test.test_cgi.CgiTests.test_fieldstorage_multipart_non_ascii @ linux-x86_64 +test.test_cgi.CgiTests.test_fieldstorage_multipart_w3c @ linux-x86_64 +test.test_cgi.CgiTests.test_fieldstorage_part_content_length @ linux-x86_64 +test.test_cgi.CgiTests.test_fieldstorage_properties @ linux-x86_64 +test.test_cgi.CgiTests.test_fieldstorage_readline @ linux-x86_64 +test.test_cgi.CgiTests.test_log @ linux-x86_64 +test.test_cgi.CgiTests.test_max_num_fields @ linux-x86_64 +test.test_cgi.CgiTests.test_parse_header @ linux-x86_64 +test.test_cgi.CgiTests.test_parse_multipart @ linux-x86_64 +test.test_cgi.CgiTests.test_parse_multipart_invalid_encoding @ linux-x86_64 +test.test_cgi.CgiTests.test_parse_multipart_without_content_length @ linux-x86_64 +test.test_cgi.CgiTests.test_separator @ linux-x86_64 +test.test_cgi.CgiTests.test_strict @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cgitb.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cgitb.txt new file mode 100644 index 0000000000..f892768c30 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cgitb.txt @@ -0,0 +1,6 @@ +test.test_cgitb.TestCgitb.test_blanks @ linux-x86_64 +test.test_cgitb.TestCgitb.test_fonts @ linux-x86_64 +test.test_cgitb.TestCgitb.test_html @ linux-x86_64 +test.test_cgitb.TestCgitb.test_syshook_no_logdir_default_format @ linux-x86_64 +test.test_cgitb.TestCgitb.test_syshook_no_logdir_text_format @ linux-x86_64 +test.test_cgitb.TestCgitb.test_text @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_charmapcodec.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_charmapcodec.txt new file mode 100644 index 0000000000..e1157a4ea6 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_charmapcodec.txt @@ -0,0 +1,4 @@ +test.test_charmapcodec.CharmapCodecTest.test_constructorx @ linux-x86_64 +test.test_charmapcodec.CharmapCodecTest.test_constructory @ linux-x86_64 +test.test_charmapcodec.CharmapCodecTest.test_encodex @ linux-x86_64 +test.test_charmapcodec.CharmapCodecTest.test_maptoundefined @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_class.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_class.txt new file mode 100644 index 0000000000..2e9f8bfd28 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_class.txt @@ -0,0 +1,15 @@ +test.test_class.ClassTests.testBadTypeReturned @ linux-x86_64 +test.test_class.ClassTests.testBinaryOps @ linux-x86_64 +test.test_class.ClassTests.testClassWithExtCall @ linux-x86_64 +test.test_class.ClassTests.testConstructorErrorMessages @ linux-x86_64 +test.test_class.ClassTests.testForExceptionsRaisedInInstanceGetattr2 @ linux-x86_64 +test.test_class.ClassTests.testGetSetAndDel @ linux-x86_64 +test.test_class.ClassTests.testHashComparisonOfMethods @ linux-x86_64 +test.test_class.ClassTests.testHashStuff @ linux-x86_64 +test.test_class.ClassTests.testInit @ linux-x86_64 +test.test_class.ClassTests.testListAndDictOps @ linux-x86_64 +test.test_class.ClassTests.testMisc @ linux-x86_64 +test.test_class.ClassTests.testSFBug532646 @ linux-x86_64 +test.test_class.ClassTests.testSetattrNonStringName @ linux-x86_64 +test.test_class.ClassTests.testSetattrWrapperNameIntern @ linux-x86_64 +test.test_class.ClassTests.testUnaryOps @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cmath.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cmath.txt new file mode 100644 index 0000000000..4205cc32e6 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cmath.txt @@ -0,0 +1,31 @@ +test.test_cmath.CMathTests.testAtanSign @ linux-x86_64 +test.test_cmath.CMathTests.testAtanhSign @ linux-x86_64 +test.test_cmath.CMathTests.testTanhSign @ linux-x86_64 +test.test_cmath.CMathTests.test_abs @ linux-x86_64 +test.test_cmath.CMathTests.test_abs_overflows @ linux-x86_64 +test.test_cmath.CMathTests.test_cmath_matches_math @ linux-x86_64 +test.test_cmath.CMathTests.test_constants @ linux-x86_64 +test.test_cmath.CMathTests.test_infinity_and_nan_constants @ linux-x86_64 +test.test_cmath.CMathTests.test_input_type @ linux-x86_64 +test.test_cmath.CMathTests.test_isfinite @ linux-x86_64 +test.test_cmath.CMathTests.test_isinf @ linux-x86_64 +test.test_cmath.CMathTests.test_isnan @ linux-x86_64 +test.test_cmath.CMathTests.test_phase @ linux-x86_64 +test.test_cmath.CMathTests.test_polar @ linux-x86_64 +test.test_cmath.CMathTests.test_rect @ linux-x86_64 +test.test_cmath.CMathTests.test_specific_values @ linux-x86_64 +test.test_cmath.CMathTests.test_user_object @ linux-x86_64 +test.test_cmath.IsCloseTests.test_asymmetry @ linux-x86_64 +test.test_cmath.IsCloseTests.test_complex_near_zero @ linux-x86_64 +test.test_cmath.IsCloseTests.test_complex_values @ linux-x86_64 +test.test_cmath.IsCloseTests.test_decimals @ linux-x86_64 +test.test_cmath.IsCloseTests.test_eight_decimal_places @ linux-x86_64 +test.test_cmath.IsCloseTests.test_fractions @ linux-x86_64 +test.test_cmath.IsCloseTests.test_identical @ linux-x86_64 +test.test_cmath.IsCloseTests.test_identical_infinite @ linux-x86_64 +test.test_cmath.IsCloseTests.test_inf_ninf_nan @ linux-x86_64 +test.test_cmath.IsCloseTests.test_integers @ linux-x86_64 +test.test_cmath.IsCloseTests.test_near_zero @ linux-x86_64 +test.test_cmath.IsCloseTests.test_negative_tolerances @ linux-x86_64 +test.test_cmath.IsCloseTests.test_reject_complex_tolerances @ linux-x86_64 +test.test_cmath.IsCloseTests.test_zero_tolerance @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cmd.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cmd.txt new file mode 100644 index 0000000000..ee3bcdeeca --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cmd.txt @@ -0,0 +1,3 @@ +DocTestCase.test.test_cmd.samplecmdclass @ linux-x86_64 +test.test_cmd.TestAlternateInput.test_file_with_missing_final_nl @ linux-x86_64 +test.test_cmd.TestAlternateInput.test_input_reset_at_EOF @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cmd_line.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cmd_line.txt new file mode 100644 index 0000000000..87863ffbb0 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cmd_line.txt @@ -0,0 +1,22 @@ +test.test_cmd_line.CmdLineTest.test_builtin_input @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_closed_stdout @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_coding @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_del___main__ @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_directories @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_empty_PYTHONPATH_issue16309 @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_help_env @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_isolatedmode @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_large_PYTHONPATH @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_non_ascii @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_optimize @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_output_newline @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_run_code @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_run_module @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_run_module_bug1764407 @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_site_flag @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_stdin_readline @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_unbuffered_input @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_unbuffered_output @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_unmached_quote @ linux-x86_64 +test.test_cmd_line.CmdLineTest.test_verbose @ linux-x86_64 +test.test_cmd_line.IgnoreEnvironmentTest.test_ignore_PYTHONPATH @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cmd_line_script.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cmd_line_script.txt new file mode 100644 index 0000000000..e074744d28 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cmd_line_script.txt @@ -0,0 +1,18 @@ +test.test_cmd_line_script.CmdLineTest.test_consistent_sys_path_for_direct_execution @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_consistent_sys_path_for_module_execution @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_dash_m_bad_pyc @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_dash_m_error_code_is_one @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_dash_m_errors @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_dash_m_init_traceback @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_dash_m_main_traceback @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_directory_error @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_hint_when_triying_to_import_a_py_file @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_issue20500_exit_with_exception_value @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_issue20884 @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_issue8202_dash_c_file_ignored @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_nonexisting_script @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_package_error @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_package_recursion @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_pep_409_verbiage @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_script_as_dev_fd @ linux-x86_64 +test.test_cmd_line_script.CmdLineTest.test_zipfile_error @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_code.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_code.txt new file mode 100644 index 0000000000..b5a1216d25 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_code.txt @@ -0,0 +1,4 @@ +test.test_code.CodeTest.test_constructor @ linux-x86_64 +test.test_code.CodeTest.test_qualname @ linux-x86_64 +test.test_code.CodeTest.test_replace @ linux-x86_64 +test.test_code.CodeTest.test_shrinking_localsplus @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_code_module.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_code_module.txt new file mode 100644 index 0000000000..4be9d93892 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_code_module.txt @@ -0,0 +1,7 @@ +test.test_code_module.TestInteractiveConsole.test_banner @ linux-x86_64 +test.test_code_module.TestInteractiveConsole.test_console_stderr @ linux-x86_64 +test.test_code_module.TestInteractiveConsole.test_exit_msg @ linux-x86_64 +test.test_code_module.TestInteractiveConsole.test_ps1 @ linux-x86_64 +test.test_code_module.TestInteractiveConsole.test_ps2 @ linux-x86_64 +test.test_code_module.TestInteractiveConsole.test_syntax_error @ linux-x86_64 +test.test_code_module.TestInteractiveConsole.test_sysexcepthook @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codeccallbacks.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codeccallbacks.txt new file mode 100644 index 0000000000..3eda050da2 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codeccallbacks.txt @@ -0,0 +1,18 @@ +test.test_codeccallbacks.CodecCallbackTest.test_backslashescape @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_badandgoodbackslashreplaceexceptions @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_badandgoodignoreexceptions @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_badandgoodnamereplaceexceptions @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_badandgoodreplaceexceptions @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_badandgoodstrictexceptions @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_badandgoodsurrogateescapeexceptions @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_badandgoodsurrogatepassexceptions @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_badandgoodxmlcharrefreplaceexceptions @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_badlookupcall @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_badregistercall @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_bug828737 @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_charmapencode @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_fake_error_class @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_lookup @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_translatehelper @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_unknownhandler @ linux-x86_64 +test.test_codeccallbacks.CodecCallbackTest.test_xmlcharrefreplace @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_cn.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_cn.txt new file mode 100644 index 0000000000..27e059842b --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_cn.txt @@ -0,0 +1,19 @@ +test.test_codecencodings_cn.Test_GB18030.test_chunkcoding @ linux-x86_64 +test.test_codecencodings_cn.Test_GB18030.test_incrementaldecoder @ linux-x86_64 +test.test_codecencodings_cn.Test_GB18030.test_incrementalencoder @ linux-x86_64 +test.test_codecencodings_cn.Test_GB18030.test_streamwriter @ linux-x86_64 +test.test_codecencodings_cn.Test_GB18030.test_streamwriter_reset_no_pending @ linux-x86_64 +test.test_codecencodings_cn.Test_GB2312.test_chunkcoding @ linux-x86_64 +test.test_codecencodings_cn.Test_GB2312.test_errorhandle @ linux-x86_64 +test.test_codecencodings_cn.Test_GB2312.test_incrementaldecoder @ linux-x86_64 +test.test_codecencodings_cn.Test_GB2312.test_incrementalencoder @ linux-x86_64 +test.test_codecencodings_cn.Test_GB2312.test_streamwriter @ linux-x86_64 +test.test_codecencodings_cn.Test_GB2312.test_streamwriter_reset_no_pending @ linux-x86_64 +test.test_codecencodings_cn.Test_GB2312.test_xmlcharrefreplace @ linux-x86_64 +test.test_codecencodings_cn.Test_GBK.test_chunkcoding @ linux-x86_64 +test.test_codecencodings_cn.Test_GBK.test_errorhandle @ linux-x86_64 +test.test_codecencodings_cn.Test_GBK.test_incrementaldecoder @ linux-x86_64 +test.test_codecencodings_cn.Test_GBK.test_incrementalencoder @ linux-x86_64 +test.test_codecencodings_cn.Test_GBK.test_streamwriter @ linux-x86_64 +test.test_codecencodings_cn.Test_GBK.test_streamwriter_reset_no_pending @ linux-x86_64 +test.test_codecencodings_cn.Test_GBK.test_xmlcharrefreplace @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_hk.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_hk.txt new file mode 100644 index 0000000000..0aceba9f63 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_hk.txt @@ -0,0 +1,2 @@ +test.test_codecencodings_hk.Test_Big5HKSCS.test_streamwriter_reset_no_pending @ linux-x86_64 +test.test_codecencodings_hk.Test_Big5HKSCS.test_xmlcharrefreplace @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_iso2022.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_iso2022.txt new file mode 100644 index 0000000000..5b8ed6a51c --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_iso2022.txt @@ -0,0 +1,8 @@ +test.test_codecencodings_iso2022.Test_ISO2022_JP.test_chunkcoding @ linux-x86_64 +test.test_codecencodings_iso2022.Test_ISO2022_JP.test_streamwriter_reset_no_pending @ linux-x86_64 +test.test_codecencodings_iso2022.Test_ISO2022_JP.test_xmlcharrefreplace @ linux-x86_64 +test.test_codecencodings_iso2022.Test_ISO2022_JP2.test_chunkcoding @ linux-x86_64 +test.test_codecencodings_iso2022.Test_ISO2022_JP2.test_streamwriter_reset_no_pending @ linux-x86_64 +test.test_codecencodings_iso2022.Test_ISO2022_JP2.test_xmlcharrefreplace @ linux-x86_64 +test.test_codecencodings_iso2022.Test_ISO2022_KR.test_streamwriter_reset_no_pending @ linux-x86_64 +test.test_codecencodings_iso2022.Test_ISO2022_KR.test_xmlcharrefreplace @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_jp.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_jp.txt new file mode 100644 index 0000000000..c84d3693cf --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_jp.txt @@ -0,0 +1,23 @@ +test.test_codecencodings_jp.Test_CP932.test_chunkcoding @ linux-x86_64 +test.test_codecencodings_jp.Test_CP932.test_errorhandle @ linux-x86_64 +test.test_codecencodings_jp.Test_CP932.test_incrementaldecoder @ linux-x86_64 +test.test_codecencodings_jp.Test_CP932.test_incrementalencoder @ linux-x86_64 +test.test_codecencodings_jp.Test_CP932.test_streamwriter @ linux-x86_64 +test.test_codecencodings_jp.Test_CP932.test_streamwriter_reset_no_pending @ linux-x86_64 +test.test_codecencodings_jp.Test_CP932.test_xmlcharrefreplace @ linux-x86_64 +test.test_codecencodings_jp.Test_EUC_JP_COMPAT.test_chunkcoding @ linux-x86_64 +test.test_codecencodings_jp.Test_EUC_JP_COMPAT.test_incrementaldecoder @ linux-x86_64 +test.test_codecencodings_jp.Test_EUC_JP_COMPAT.test_incrementalencoder @ linux-x86_64 +test.test_codecencodings_jp.Test_EUC_JP_COMPAT.test_streamwriter @ linux-x86_64 +test.test_codecencodings_jp.Test_EUC_JP_COMPAT.test_streamwriter_reset_no_pending @ linux-x86_64 +test.test_codecencodings_jp.Test_EUC_JP_COMPAT.test_xmlcharrefreplace @ linux-x86_64 +test.test_codecencodings_jp.Test_SJISX0213.test_chunkcoding @ linux-x86_64 +test.test_codecencodings_jp.Test_SJISX0213.test_incrementaldecoder @ linux-x86_64 +test.test_codecencodings_jp.Test_SJISX0213.test_streamwriter_reset_no_pending @ linux-x86_64 +test.test_codecencodings_jp.Test_SJISX0213.test_xmlcharrefreplace @ linux-x86_64 +test.test_codecencodings_jp.Test_SJIS_COMPAT.test_chunkcoding @ linux-x86_64 +test.test_codecencodings_jp.Test_SJIS_COMPAT.test_incrementaldecoder @ linux-x86_64 +test.test_codecencodings_jp.Test_SJIS_COMPAT.test_incrementalencoder @ linux-x86_64 +test.test_codecencodings_jp.Test_SJIS_COMPAT.test_streamwriter @ linux-x86_64 +test.test_codecencodings_jp.Test_SJIS_COMPAT.test_streamwriter_reset_no_pending @ linux-x86_64 +test.test_codecencodings_jp.Test_SJIS_COMPAT.test_xmlcharrefreplace @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_kr.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_kr.txt new file mode 100644 index 0000000000..382ca971e8 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_kr.txt @@ -0,0 +1,16 @@ +test.test_codecencodings_kr.Test_CP949.test_chunkcoding @ linux-x86_64 +test.test_codecencodings_kr.Test_CP949.test_errorhandle @ linux-x86_64 +test.test_codecencodings_kr.Test_CP949.test_incrementaldecoder @ linux-x86_64 +test.test_codecencodings_kr.Test_CP949.test_incrementalencoder @ linux-x86_64 +test.test_codecencodings_kr.Test_CP949.test_streamwriter @ linux-x86_64 +test.test_codecencodings_kr.Test_CP949.test_streamwriter_reset_no_pending @ linux-x86_64 +test.test_codecencodings_kr.Test_CP949.test_xmlcharrefreplace @ linux-x86_64 +test.test_codecencodings_kr.Test_EUCKR.test_streamwriter_reset_no_pending @ linux-x86_64 +test.test_codecencodings_kr.Test_EUCKR.test_xmlcharrefreplace @ linux-x86_64 +test.test_codecencodings_kr.Test_JOHAB.test_chunkcoding @ linux-x86_64 +test.test_codecencodings_kr.Test_JOHAB.test_errorhandle @ linux-x86_64 +test.test_codecencodings_kr.Test_JOHAB.test_incrementaldecoder @ linux-x86_64 +test.test_codecencodings_kr.Test_JOHAB.test_incrementalencoder @ linux-x86_64 +test.test_codecencodings_kr.Test_JOHAB.test_streamwriter @ linux-x86_64 +test.test_codecencodings_kr.Test_JOHAB.test_streamwriter_reset_no_pending @ linux-x86_64 +test.test_codecencodings_kr.Test_JOHAB.test_xmlcharrefreplace @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_tw.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_tw.txt new file mode 100644 index 0000000000..7a6a5a5e84 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecencodings_tw.txt @@ -0,0 +1,7 @@ +test.test_codecencodings_tw.Test_Big5.test_chunkcoding @ linux-x86_64 +test.test_codecencodings_tw.Test_Big5.test_errorhandle @ linux-x86_64 +test.test_codecencodings_tw.Test_Big5.test_incrementaldecoder @ linux-x86_64 +test.test_codecencodings_tw.Test_Big5.test_incrementalencoder @ linux-x86_64 +test.test_codecencodings_tw.Test_Big5.test_streamwriter @ linux-x86_64 +test.test_codecencodings_tw.Test_Big5.test_streamwriter_reset_no_pending @ linux-x86_64 +test.test_codecencodings_tw.Test_Big5.test_xmlcharrefreplace @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecmaps_cn.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecmaps_cn.txt new file mode 100644 index 0000000000..4f4a7348a3 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecmaps_cn.txt @@ -0,0 +1,7 @@ +test.test_codecmaps_cn.TestGB18030Map.test_errorhandle @ linux-x86_64 +test.test_codecmaps_cn.TestGB18030Map.test_mapping_supplemental @ linux-x86_64 +test.test_codecmaps_cn.TestGB2312Map.test_errorhandle @ linux-x86_64 +test.test_codecmaps_cn.TestGB2312Map.test_mapping_file @ linux-x86_64 +test.test_codecmaps_cn.TestGB2312Map.test_mapping_supplemental @ linux-x86_64 +test.test_codecmaps_cn.TestGBKMap.test_errorhandle @ linux-x86_64 +test.test_codecmaps_cn.TestGBKMap.test_mapping_supplemental @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecmaps_hk.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecmaps_hk.txt new file mode 100644 index 0000000000..cf96d766b8 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecmaps_hk.txt @@ -0,0 +1,3 @@ +test.test_codecmaps_hk.TestBig5HKSCSMap.test_errorhandle @ linux-x86_64 +test.test_codecmaps_hk.TestBig5HKSCSMap.test_mapping_file @ linux-x86_64 +test.test_codecmaps_hk.TestBig5HKSCSMap.test_mapping_supplemental @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecmaps_jp.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecmaps_jp.txt new file mode 100644 index 0000000000..4a82aad223 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecmaps_jp.txt @@ -0,0 +1,9 @@ +test.test_codecmaps_jp.TestCP932Map.test_errorhandle @ linux-x86_64 +test.test_codecmaps_jp.TestEUCJISX0213Map.test_errorhandle @ linux-x86_64 +test.test_codecmaps_jp.TestEUCJISX0213Map.test_mapping_supplemental @ linux-x86_64 +test.test_codecmaps_jp.TestEUCJPCOMPATMap.test_errorhandle @ linux-x86_64 +test.test_codecmaps_jp.TestEUCJPCOMPATMap.test_mapping_supplemental @ linux-x86_64 +test.test_codecmaps_jp.TestSJISCOMPATMap.test_errorhandle @ linux-x86_64 +test.test_codecmaps_jp.TestSJISCOMPATMap.test_mapping_supplemental @ linux-x86_64 +test.test_codecmaps_jp.TestSJISX0213Map.test_errorhandle @ linux-x86_64 +test.test_codecmaps_jp.TestSJISX0213Map.test_mapping_supplemental @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecmaps_kr.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecmaps_kr.txt new file mode 100644 index 0000000000..b8671dd8fd --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecmaps_kr.txt @@ -0,0 +1,9 @@ +test.test_codecmaps_kr.TestCP949Map.test_errorhandle @ linux-x86_64 +test.test_codecmaps_kr.TestCP949Map.test_mapping_file @ linux-x86_64 +test.test_codecmaps_kr.TestCP949Map.test_mapping_supplemental @ linux-x86_64 +test.test_codecmaps_kr.TestEUCKRMap.test_errorhandle @ linux-x86_64 +test.test_codecmaps_kr.TestEUCKRMap.test_mapping_file @ linux-x86_64 +test.test_codecmaps_kr.TestEUCKRMap.test_mapping_supplemental @ linux-x86_64 +test.test_codecmaps_kr.TestJOHABMap.test_errorhandle @ linux-x86_64 +test.test_codecmaps_kr.TestJOHABMap.test_mapping_file @ linux-x86_64 +test.test_codecmaps_kr.TestJOHABMap.test_mapping_supplemental @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecmaps_tw.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecmaps_tw.txt new file mode 100644 index 0000000000..0555dea346 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecmaps_tw.txt @@ -0,0 +1,5 @@ +test.test_codecmaps_tw.TestBIG5Map.test_errorhandle @ linux-x86_64 +test.test_codecmaps_tw.TestBIG5Map.test_mapping_file @ linux-x86_64 +test.test_codecmaps_tw.TestBIG5Map.test_mapping_supplemental @ linux-x86_64 +test.test_codecmaps_tw.TestCP950Map.test_errorhandle @ linux-x86_64 +test.test_codecmaps_tw.TestCP950Map.test_mapping_supplemental @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecs.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecs.txt new file mode 100644 index 0000000000..786d2cffcf --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codecs.txt @@ -0,0 +1,184 @@ +test.test_codecs.ASCIITest.test_decode @ linux-x86_64 +test.test_codecs.ASCIITest.test_decode_error @ linux-x86_64 +test.test_codecs.ASCIITest.test_encode @ linux-x86_64 +test.test_codecs.ASCIITest.test_encode_error @ linux-x86_64 +test.test_codecs.ASCIITest.test_encode_surrogateescape_error @ linux-x86_64 +test.test_codecs.BasicUnicodeTest.test_encoding_map_type_initialized @ linux-x86_64 +test.test_codecs.CharmapTest.test_decode_with_int2int_map @ linux-x86_64 +test.test_codecs.CharmapTest.test_decode_with_int2str_map @ linux-x86_64 +test.test_codecs.CharmapTest.test_decode_with_string_map @ linux-x86_64 +test.test_codecs.CodecNameNormalizationTest.test_codecs_lookup @ linux-x86_64 +test.test_codecs.CodecNameNormalizationTest.test_encodings_normalize_encoding @ linux-x86_64 +test.test_codecs.CodecsModuleTest.test_all @ linux-x86_64 +test.test_codecs.CodecsModuleTest.test_decode @ linux-x86_64 +test.test_codecs.CodecsModuleTest.test_encode @ linux-x86_64 +test.test_codecs.CodecsModuleTest.test_file_closes_if_lookup_error_raised @ linux-x86_64 +test.test_codecs.CodecsModuleTest.test_getdecoder @ linux-x86_64 +test.test_codecs.CodecsModuleTest.test_getencoder @ linux-x86_64 +test.test_codecs.CodecsModuleTest.test_getreader @ linux-x86_64 +test.test_codecs.CodecsModuleTest.test_getwriter @ linux-x86_64 +test.test_codecs.CodecsModuleTest.test_lookup @ linux-x86_64 +test.test_codecs.CodecsModuleTest.test_lookup_issue1813 @ linux-x86_64 +test.test_codecs.CodecsModuleTest.test_open @ linux-x86_64 +test.test_codecs.CodecsModuleTest.test_register @ linux-x86_64 +test.test_codecs.CodecsModuleTest.test_undefined @ linux-x86_64 +test.test_codecs.CodecsModuleTest.test_unregister @ linux-x86_64 +test.test_codecs.EncodedFileTest.test_basic @ linux-x86_64 +test.test_codecs.EscapeDecodeTest.test_empty @ linux-x86_64 +test.test_codecs.EscapeDecodeTest.test_errors @ linux-x86_64 +test.test_codecs.EscapeDecodeTest.test_raw @ linux-x86_64 +test.test_codecs.EscapeEncodeTest.test_escape_encode @ linux-x86_64 +test.test_codecs.ExceptionChainingTest.test_init_override_is_not_wrapped @ linux-x86_64 +test.test_codecs.ExceptionChainingTest.test_instance_attribute_is_not_wrapped @ linux-x86_64 +test.test_codecs.ExceptionChainingTest.test_multiple_args_is_not_wrapped @ linux-x86_64 +test.test_codecs.ExceptionChainingTest.test_new_override_is_not_wrapped @ linux-x86_64 +test.test_codecs.ExceptionChainingTest.test_non_str_arg_is_not_wrapped @ linux-x86_64 +test.test_codecs.ExceptionChainingTest.test_unflagged_non_text_codec_handling @ linux-x86_64 +test.test_codecs.IDNACodecTest.test_builtin_decode @ linux-x86_64 +test.test_codecs.IDNACodecTest.test_builtin_decode_length_limit @ linux-x86_64 +test.test_codecs.IDNACodecTest.test_builtin_encode @ linux-x86_64 +test.test_codecs.IDNACodecTest.test_errors @ linux-x86_64 +test.test_codecs.IDNACodecTest.test_incremental_decode @ linux-x86_64 +test.test_codecs.IDNACodecTest.test_incremental_encode @ linux-x86_64 +test.test_codecs.IDNACodecTest.test_stream @ linux-x86_64 +test.test_codecs.Latin1Test.test_decode @ linux-x86_64 +test.test_codecs.Latin1Test.test_encode @ linux-x86_64 +test.test_codecs.Latin1Test.test_encode_errors @ linux-x86_64 +test.test_codecs.Latin1Test.test_encode_surrogateescape_error @ linux-x86_64 +test.test_codecs.NameprepTest.test_nameprep @ linux-x86_64 +test.test_codecs.PunycodeTest.test_decode @ linux-x86_64 +test.test_codecs.PunycodeTest.test_decode_invalid @ linux-x86_64 +test.test_codecs.PunycodeTest.test_encode @ linux-x86_64 +test.test_codecs.RawUnicodeEscapeTest.test_bug1098990_a @ linux-x86_64 +test.test_codecs.RawUnicodeEscapeTest.test_bug1098990_b @ linux-x86_64 +test.test_codecs.RawUnicodeEscapeTest.test_bug1175396 @ linux-x86_64 +test.test_codecs.RawUnicodeEscapeTest.test_empty @ linux-x86_64 +test.test_codecs.RawUnicodeEscapeTest.test_escape_encode @ linux-x86_64 +test.test_codecs.RawUnicodeEscapeTest.test_mixed_readline_and_read @ linux-x86_64 +test.test_codecs.RawUnicodeEscapeTest.test_raw_encode @ linux-x86_64 +test.test_codecs.RawUnicodeEscapeTest.test_readlinequeue @ linux-x86_64 +test.test_codecs.Rot13Test.test_decode @ linux-x86_64 +test.test_codecs.Rot13Test.test_encode @ linux-x86_64 +test.test_codecs.Rot13Test.test_incremental_decode @ linux-x86_64 +test.test_codecs.Rot13Test.test_incremental_encode @ linux-x86_64 +test.test_codecs.Rot13UtilTest.test_rot13_func @ linux-x86_64 +test.test_codecs.StreamReaderTest.test_copy @ linux-x86_64 +test.test_codecs.StreamReaderTest.test_pickle @ linux-x86_64 +test.test_codecs.StreamReaderTest.test_readlines @ linux-x86_64 +test.test_codecs.StreamReaderWriterTest.test_copy @ linux-x86_64 +test.test_codecs.StreamReaderWriterTest.test_pickle @ linux-x86_64 +test.test_codecs.StreamRecoderTest.test_seeking_read @ linux-x86_64 +test.test_codecs.StreamRecoderTest.test_seeking_write @ linux-x86_64 +test.test_codecs.StreamWriterTest.test_copy @ linux-x86_64 +test.test_codecs.StreamWriterTest.test_pickle @ linux-x86_64 +test.test_codecs.SurrogateEscapeTest.test_ascii @ linux-x86_64 +test.test_codecs.SurrogateEscapeTest.test_charmap @ linux-x86_64 +test.test_codecs.SurrogateEscapeTest.test_latin1 @ linux-x86_64 +test.test_codecs.SurrogateEscapeTest.test_utf8 @ linux-x86_64 +test.test_codecs.TransformCodecTest.test_aliases @ linux-x86_64 +test.test_codecs.TransformCodecTest.test_quopri_stateless @ linux-x86_64 +test.test_codecs.TransformCodecTest.test_uu_invalid @ linux-x86_64 +test.test_codecs.UTF16BETest.test_bug1098990_a @ linux-x86_64 +test.test_codecs.UTF16BETest.test_bug1098990_b @ linux-x86_64 +test.test_codecs.UTF16BETest.test_bug1175396 @ linux-x86_64 +test.test_codecs.UTF16BETest.test_mixed_readline_and_read @ linux-x86_64 +test.test_codecs.UTF16BETest.test_nonbmp @ linux-x86_64 +test.test_codecs.UTF16BETest.test_partial @ linux-x86_64 +test.test_codecs.UTF16BETest.test_readline @ linux-x86_64 +test.test_codecs.UTF16BETest.test_readlinequeue @ linux-x86_64 +test.test_codecs.UTF16ExTest.test_bad_args @ linux-x86_64 +test.test_codecs.UTF16LETest.test_bug1098990_a @ linux-x86_64 +test.test_codecs.UTF16LETest.test_bug1098990_b @ linux-x86_64 +test.test_codecs.UTF16LETest.test_bug1175396 @ linux-x86_64 +test.test_codecs.UTF16LETest.test_mixed_readline_and_read @ linux-x86_64 +test.test_codecs.UTF16LETest.test_nonbmp @ linux-x86_64 +test.test_codecs.UTF16LETest.test_partial @ linux-x86_64 +test.test_codecs.UTF16LETest.test_readline @ linux-x86_64 +test.test_codecs.UTF16LETest.test_readlinequeue @ linux-x86_64 +test.test_codecs.UTF16Test.test_bug1098990_a @ linux-x86_64 +test.test_codecs.UTF16Test.test_bug1098990_b @ linux-x86_64 +test.test_codecs.UTF16Test.test_bug1175396 @ linux-x86_64 +test.test_codecs.UTF16Test.test_bug691291 @ linux-x86_64 +test.test_codecs.UTF16Test.test_errors @ linux-x86_64 +test.test_codecs.UTF16Test.test_handlers @ linux-x86_64 +test.test_codecs.UTF16Test.test_mixed_readline_and_read @ linux-x86_64 +test.test_codecs.UTF16Test.test_partial @ linux-x86_64 +test.test_codecs.UTF16Test.test_readline @ linux-x86_64 +test.test_codecs.UTF16Test.test_readlinequeue @ linux-x86_64 +test.test_codecs.UTF32BETest.test_bug1098990_a @ linux-x86_64 +test.test_codecs.UTF32BETest.test_bug1098990_b @ linux-x86_64 +test.test_codecs.UTF32BETest.test_bug1175396 @ linux-x86_64 +test.test_codecs.UTF32BETest.test_errors @ linux-x86_64 +test.test_codecs.UTF32BETest.test_issue8941 @ linux-x86_64 +test.test_codecs.UTF32BETest.test_mixed_readline_and_read @ linux-x86_64 +test.test_codecs.UTF32BETest.test_partial @ linux-x86_64 +test.test_codecs.UTF32BETest.test_readline @ linux-x86_64 +test.test_codecs.UTF32BETest.test_readlinequeue @ linux-x86_64 +test.test_codecs.UTF32BETest.test_simple @ linux-x86_64 +test.test_codecs.UTF32LETest.test_bug1098990_a @ linux-x86_64 +test.test_codecs.UTF32LETest.test_bug1098990_b @ linux-x86_64 +test.test_codecs.UTF32LETest.test_bug1175396 @ linux-x86_64 +test.test_codecs.UTF32LETest.test_errors @ linux-x86_64 +test.test_codecs.UTF32LETest.test_issue8941 @ linux-x86_64 +test.test_codecs.UTF32LETest.test_mixed_readline_and_read @ linux-x86_64 +test.test_codecs.UTF32LETest.test_partial @ linux-x86_64 +test.test_codecs.UTF32LETest.test_readline @ linux-x86_64 +test.test_codecs.UTF32LETest.test_readlinequeue @ linux-x86_64 +test.test_codecs.UTF32LETest.test_simple @ linux-x86_64 +test.test_codecs.UTF32Test.test_badbom @ linux-x86_64 +test.test_codecs.UTF32Test.test_bug1098990_a @ linux-x86_64 +test.test_codecs.UTF32Test.test_bug1098990_b @ linux-x86_64 +test.test_codecs.UTF32Test.test_bug1175396 @ linux-x86_64 +test.test_codecs.UTF32Test.test_errors @ linux-x86_64 +test.test_codecs.UTF32Test.test_handlers @ linux-x86_64 +test.test_codecs.UTF32Test.test_issue8941 @ linux-x86_64 +test.test_codecs.UTF32Test.test_mixed_readline_and_read @ linux-x86_64 +test.test_codecs.UTF32Test.test_partial @ linux-x86_64 +test.test_codecs.UTF32Test.test_readline @ linux-x86_64 +test.test_codecs.UTF32Test.test_readlinequeue @ linux-x86_64 +test.test_codecs.UTF7Test.test_ascii @ linux-x86_64 +test.test_codecs.UTF7Test.test_bug1098990_a @ linux-x86_64 +test.test_codecs.UTF7Test.test_bug1098990_b @ linux-x86_64 +test.test_codecs.UTF7Test.test_bug1175396 @ linux-x86_64 +test.test_codecs.UTF7Test.test_mixed_readline_and_read @ linux-x86_64 +test.test_codecs.UTF7Test.test_readlinequeue @ linux-x86_64 +test.test_codecs.UTF8SigTest.test_bom @ linux-x86_64 +test.test_codecs.UTF8SigTest.test_bug1098990_a @ linux-x86_64 +test.test_codecs.UTF8SigTest.test_bug1098990_b @ linux-x86_64 +test.test_codecs.UTF8SigTest.test_bug1175396 @ linux-x86_64 +test.test_codecs.UTF8SigTest.test_bug1601501 @ linux-x86_64 +test.test_codecs.UTF8SigTest.test_decode_error @ linux-x86_64 +test.test_codecs.UTF8SigTest.test_decoder_state @ linux-x86_64 +test.test_codecs.UTF8SigTest.test_incremental_errors @ linux-x86_64 +test.test_codecs.UTF8SigTest.test_incremental_surrogatepass @ linux-x86_64 +test.test_codecs.UTF8SigTest.test_mixed_readline_and_read @ linux-x86_64 +test.test_codecs.UTF8SigTest.test_partial @ linux-x86_64 +test.test_codecs.UTF8SigTest.test_readline @ linux-x86_64 +test.test_codecs.UTF8SigTest.test_readlinequeue @ linux-x86_64 +test.test_codecs.UTF8SigTest.test_stream_bare @ linux-x86_64 +test.test_codecs.UTF8SigTest.test_stream_bom @ linux-x86_64 +test.test_codecs.UTF8Test.test_bug1098990_a @ linux-x86_64 +test.test_codecs.UTF8Test.test_bug1098990_b @ linux-x86_64 +test.test_codecs.UTF8Test.test_bug1175396 @ linux-x86_64 +test.test_codecs.UTF8Test.test_decode_error @ linux-x86_64 +test.test_codecs.UTF8Test.test_decoder_state @ linux-x86_64 +test.test_codecs.UTF8Test.test_incremental_errors @ linux-x86_64 +test.test_codecs.UTF8Test.test_incremental_surrogatepass @ linux-x86_64 +test.test_codecs.UTF8Test.test_mixed_readline_and_read @ linux-x86_64 +test.test_codecs.UTF8Test.test_partial @ linux-x86_64 +test.test_codecs.UTF8Test.test_readline @ linux-x86_64 +test.test_codecs.UTF8Test.test_readlinequeue @ linux-x86_64 +test.test_codecs.UnicodeEscapeTest.test_bug1098990_a @ linux-x86_64 +test.test_codecs.UnicodeEscapeTest.test_bug1098990_b @ linux-x86_64 +test.test_codecs.UnicodeEscapeTest.test_bug1175396 @ linux-x86_64 +test.test_codecs.UnicodeEscapeTest.test_empty @ linux-x86_64 +test.test_codecs.UnicodeEscapeTest.test_escape_encode @ linux-x86_64 +test.test_codecs.UnicodeEscapeTest.test_incremental_surrogatepass @ linux-x86_64 +test.test_codecs.UnicodeEscapeTest.test_mixed_readline_and_read @ linux-x86_64 +test.test_codecs.UnicodeEscapeTest.test_partial @ linux-x86_64 +test.test_codecs.UnicodeEscapeTest.test_raw_decode @ linux-x86_64 +test.test_codecs.UnicodeEscapeTest.test_raw_encode @ linux-x86_64 +test.test_codecs.UnicodeEscapeTest.test_readline @ linux-x86_64 +test.test_codecs.UnicodeEscapeTest.test_readlinequeue @ linux-x86_64 +test.test_codecs.WithStmtTest.test_encodedfile @ linux-x86_64 +test.test_codecs.WithStmtTest.test_streamreaderwriter @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codeop.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codeop.txt new file mode 100644 index 0000000000..bdcc9a323a --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_codeop.txt @@ -0,0 +1,6 @@ +test.test_codeop.CodeopTests.test_filename @ linux-x86_64 +test.test_codeop.CodeopTests.test_invalid @ linux-x86_64 +test.test_codeop.CodeopTests.test_invalid_exec @ linux-x86_64 +test.test_codeop.CodeopTests.test_syntax_errors @ linux-x86_64 +test.test_codeop.CodeopTests.test_valid @ linux-x86_64 +test.test_codeop.CodeopTests.test_warning @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_collections.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_collections.txt new file mode 100644 index 0000000000..2ab93367cf --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_collections.txt @@ -0,0 +1,101 @@ +DocTestCase.collections.Counter @ linux-x86_64 +DocTestCase.collections.Counter.__add__ @ linux-x86_64 +DocTestCase.collections.Counter.__and__ @ linux-x86_64 +DocTestCase.collections.Counter.__iadd__ @ linux-x86_64 +DocTestCase.collections.Counter.__iand__ @ linux-x86_64 +DocTestCase.collections.Counter.__init__ @ linux-x86_64 +DocTestCase.collections.Counter.__ior__ @ linux-x86_64 +DocTestCase.collections.Counter.__isub__ @ linux-x86_64 +DocTestCase.collections.Counter.__or__ @ linux-x86_64 +DocTestCase.collections.Counter.__sub__ @ linux-x86_64 +DocTestCase.collections.Counter.elements @ linux-x86_64 +DocTestCase.collections.Counter.most_common @ linux-x86_64 +DocTestCase.collections.Counter.subtract @ linux-x86_64 +DocTestCase.collections.Counter.update @ linux-x86_64 +DocTestCase.collections.namedtuple @ linux-x86_64 +test.test_collections.TestChainMap.test_basics @ linux-x86_64 +test.test_collections.TestChainMap.test_bool @ linux-x86_64 +test.test_collections.TestChainMap.test_constructor @ linux-x86_64 +test.test_collections.TestChainMap.test_dict_coercion @ linux-x86_64 +test.test_collections.TestChainMap.test_iter_not_calling_getitem_on_maps @ linux-x86_64 +test.test_collections.TestChainMap.test_missing @ linux-x86_64 +test.test_collections.TestChainMap.test_new_child @ linux-x86_64 +test.test_collections.TestChainMap.test_order_preservation @ linux-x86_64 +test.test_collections.TestChainMap.test_ordering @ linux-x86_64 +test.test_collections.TestChainMap.test_union_operators @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_ByteString @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_Mapping @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_MutableMapping @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_MutableMapping_subclass @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_MutableSequence @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_MutableSequence_mixins @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_MutableSet @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_Sequence @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_Sequence_mixins @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_Set @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_Set_from_iterable @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_Set_interoperability_with_real_sets @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_arithmetic_Set @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_equality_Set @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_hash_Set @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_illegal_patma_flags @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_isdisjoint_Set @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_issue16373 @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_issue26915 @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_issue8750 @ linux-x86_64 +test.test_collections.TestCollectionABCs.test_issue_5647 @ linux-x86_64 +test.test_collections.TestCounter.test_basics @ linux-x86_64 +test.test_collections.TestCounter.test_conversions @ linux-x86_64 +test.test_collections.TestCounter.test_copy_subclass @ linux-x86_64 +test.test_collections.TestCounter.test_copying @ linux-x86_64 +test.test_collections.TestCounter.test_eq @ linux-x86_64 +test.test_collections.TestCounter.test_ge @ linux-x86_64 +test.test_collections.TestCounter.test_gt @ linux-x86_64 +test.test_collections.TestCounter.test_helper_function @ linux-x86_64 +test.test_collections.TestCounter.test_init @ linux-x86_64 +test.test_collections.TestCounter.test_inplace_operations @ linux-x86_64 +test.test_collections.TestCounter.test_invariant_for_the_in_operator @ linux-x86_64 +test.test_collections.TestCounter.test_le @ linux-x86_64 +test.test_collections.TestCounter.test_lt @ linux-x86_64 +test.test_collections.TestCounter.test_multiset_operations @ linux-x86_64 +test.test_collections.TestCounter.test_multiset_operations_equivalent_to_set_operations @ linux-x86_64 +test.test_collections.TestCounter.test_order_preservation @ linux-x86_64 +test.test_collections.TestCounter.test_repr_nonsortable @ linux-x86_64 +test.test_collections.TestCounter.test_subtract @ linux-x86_64 +test.test_collections.TestCounter.test_total @ linux-x86_64 +test.test_collections.TestCounter.test_unary @ linux-x86_64 +test.test_collections.TestCounter.test_update @ linux-x86_64 +test.test_collections.TestNamedTuple.test_copy @ linux-x86_64 +test.test_collections.TestNamedTuple.test_defaults @ linux-x86_64 +test.test_collections.TestNamedTuple.test_factory @ linux-x86_64 +test.test_collections.TestNamedTuple.test_factory_doc_attr @ linux-x86_64 +test.test_collections.TestNamedTuple.test_field_doc @ linux-x86_64 +test.test_collections.TestNamedTuple.test_instance @ linux-x86_64 +test.test_collections.TestNamedTuple.test_keyword_only_arguments @ linux-x86_64 +test.test_collections.TestNamedTuple.test_match_args @ linux-x86_64 +test.test_collections.TestNamedTuple.test_module_parameter @ linux-x86_64 +test.test_collections.TestNamedTuple.test_name_conflicts @ linux-x86_64 +test.test_collections.TestNamedTuple.test_name_fixer @ linux-x86_64 +test.test_collections.TestNamedTuple.test_namedtuple_subclass_issue_24931 @ linux-x86_64 +test.test_collections.TestNamedTuple.test_non_generic_subscript @ linux-x86_64 +test.test_collections.TestNamedTuple.test_odd_sizes @ linux-x86_64 +test.test_collections.TestNamedTuple.test_pickle @ linux-x86_64 +test.test_collections.TestNamedTuple.test_readonly @ linux-x86_64 +test.test_collections.TestNamedTuple.test_repr @ linux-x86_64 +test.test_collections.TestNamedTuple.test_tupleness @ linux-x86_64 +test.test_collections.TestOneTrickPonyABCs.test_Callable @ linux-x86_64 +test.test_collections.TestOneTrickPonyABCs.test_Collection @ linux-x86_64 +test.test_collections.TestOneTrickPonyABCs.test_Container @ linux-x86_64 +test.test_collections.TestOneTrickPonyABCs.test_Generator @ linux-x86_64 +test.test_collections.TestOneTrickPonyABCs.test_Hashable @ linux-x86_64 +test.test_collections.TestOneTrickPonyABCs.test_Iterable @ linux-x86_64 +test.test_collections.TestOneTrickPonyABCs.test_Iterator @ linux-x86_64 +test.test_collections.TestOneTrickPonyABCs.test_Reversible @ linux-x86_64 +test.test_collections.TestOneTrickPonyABCs.test_Sized @ linux-x86_64 +test.test_collections.TestOneTrickPonyABCs.test_direct_subclassing @ linux-x86_64 +test.test_collections.TestOneTrickPonyABCs.test_registration @ linux-x86_64 +test.test_collections.TestUserObjects.test_dict_copy @ linux-x86_64 +test.test_collections.TestUserObjects.test_dict_protocol @ linux-x86_64 +test.test_collections.TestUserObjects.test_list_copy @ linux-x86_64 +test.test_collections.TestUserObjects.test_list_protocol @ linux-x86_64 +test.test_collections.TestUserObjects.test_str_protocol @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_colorsys.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_colorsys.txt new file mode 100644 index 0000000000..c49849b173 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_colorsys.txt @@ -0,0 +1,7 @@ +test.test_colorsys.ColorsysTest.test_hls_nearwhite @ linux-x86_64 +test.test_colorsys.ColorsysTest.test_hls_roundtrip @ linux-x86_64 +test.test_colorsys.ColorsysTest.test_hls_values @ linux-x86_64 +test.test_colorsys.ColorsysTest.test_hsv_roundtrip @ linux-x86_64 +test.test_colorsys.ColorsysTest.test_hsv_values @ linux-x86_64 +test.test_colorsys.ColorsysTest.test_yiq_roundtrip @ linux-x86_64 +test.test_colorsys.ColorsysTest.test_yiq_values @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_compare.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_compare.txt new file mode 100644 index 0000000000..c58480cadc --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_compare.txt @@ -0,0 +1,16 @@ +test.test_compare.ComparisonFullTest.test_bytes @ linux-x86_64 +test.test_compare.ComparisonFullTest.test_comp_classes_different @ linux-x86_64 +test.test_compare.ComparisonFullTest.test_comp_classes_same @ linux-x86_64 +test.test_compare.ComparisonFullTest.test_mappings @ linux-x86_64 +test.test_compare.ComparisonFullTest.test_numbers @ linux-x86_64 +test.test_compare.ComparisonFullTest.test_objects @ linux-x86_64 +test.test_compare.ComparisonFullTest.test_sequences @ linux-x86_64 +test.test_compare.ComparisonFullTest.test_sets @ linux-x86_64 +test.test_compare.ComparisonFullTest.test_str_subclass @ linux-x86_64 +test.test_compare.ComparisonSimpleTest.test_comparisons @ linux-x86_64 +test.test_compare.ComparisonSimpleTest.test_id_comparisons @ linux-x86_64 +test.test_compare.ComparisonSimpleTest.test_issue_1393 @ linux-x86_64 +test.test_compare.ComparisonSimpleTest.test_ne_defaults_to_not_eq @ linux-x86_64 +test.test_compare.ComparisonSimpleTest.test_ne_high_priority @ linux-x86_64 +test.test_compare.ComparisonSimpleTest.test_ne_low_priority @ linux-x86_64 +test.test_compare.ComparisonSimpleTest.test_other_delegation @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_compile.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_compile.txt new file mode 100644 index 0000000000..b4ce94500b --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_compile.txt @@ -0,0 +1,53 @@ +test.test_compile.TestExpressionStackSize.test_and @ linux-x86_64 +test.test_compile.TestExpressionStackSize.test_and_or @ linux-x86_64 +test.test_compile.TestExpressionStackSize.test_binop @ linux-x86_64 +test.test_compile.TestExpressionStackSize.test_chained_comparison @ linux-x86_64 +test.test_compile.TestExpressionStackSize.test_func_and @ linux-x86_64 +test.test_compile.TestExpressionStackSize.test_or @ linux-x86_64 +test.test_compile.TestExpressionStackSize.test_stack_3050 @ linux-x86_64 +test.test_compile.TestExpressionStackSize.test_stack_3050_2 @ linux-x86_64 +test.test_compile.TestSourcePositions.test_multiline_assert_rewritten_as_method_call @ linux-x86_64 +test.test_compile.TestSourcePositions.test_simple_assignment @ linux-x86_64 +test.test_compile.TestSourcePositions.test_weird_attribute_position_regressions @ linux-x86_64 +test.test_compile.TestSpecifics.test_annotation_limit @ linux-x86_64 +test.test_compile.TestSpecifics.test_apply_static_swaps @ linux-x86_64 +test.test_compile.TestSpecifics.test_apply_static_swaps_2 @ linux-x86_64 +test.test_compile.TestSpecifics.test_apply_static_swaps_3 @ linux-x86_64 +test.test_compile.TestSpecifics.test_argument_handling @ linux-x86_64 +test.test_compile.TestSpecifics.test_argument_order @ linux-x86_64 +test.test_compile.TestSpecifics.test_bad_single_statement @ linux-x86_64 +test.test_compile.TestSpecifics.test_big_dict_literal @ linux-x86_64 +test.test_compile.TestSpecifics.test_compile_filename @ linux-x86_64 +test.test_compile.TestSpecifics.test_dict_evaluation_order @ linux-x86_64 +test.test_compile.TestSpecifics.test_duplicate_global_local @ linux-x86_64 +test.test_compile.TestSpecifics.test_empty @ linux-x86_64 +test.test_compile.TestSpecifics.test_encoding @ linux-x86_64 +test.test_compile.TestSpecifics.test_exec_with_general_mapping_for_locals @ linux-x86_64 +test.test_compile.TestSpecifics.test_extended_arg @ linux-x86_64 +test.test_compile.TestSpecifics.test_float_literals @ linux-x86_64 +test.test_compile.TestSpecifics.test_for_distinct_code_objects @ linux-x86_64 +test.test_compile.TestSpecifics.test_import @ linux-x86_64 +test.test_compile.TestSpecifics.test_indentation @ linux-x86_64 +test.test_compile.TestSpecifics.test_lambda_doc @ linux-x86_64 +test.test_compile.TestSpecifics.test_literals_with_leading_zeroes @ linux-x86_64 +test.test_compile.TestSpecifics.test_mangling @ linux-x86_64 +test.test_compile.TestSpecifics.test_no_ending_newline @ linux-x86_64 +test.test_compile.TestSpecifics.test_none_assignment @ linux-x86_64 +test.test_compile.TestSpecifics.test_none_keyword_arg @ linux-x86_64 +test.test_compile.TestSpecifics.test_null_terminated @ linux-x86_64 +test.test_compile.TestSpecifics.test_other_newlines @ linux-x86_64 +test.test_compile.TestSpecifics.test_path_like_objects @ linux-x86_64 +test.test_compile.TestSpecifics.test_sequence_unpacking_error @ linux-x86_64 +test.test_compile.TestSpecifics.test_single_statement @ linux-x86_64 +test.test_compile.TestSpecifics.test_stack_overflow @ linux-x86_64 +test.test_compile.TestSpecifics.test_subscripts @ linux-x86_64 +test.test_compile.TestSpecifics.test_syntax_error @ linux-x86_64 +test.test_compile.TestSpecifics.test_unary_minus @ linux-x86_64 +test.test_compile.TestStackSizeStability.test_async_for @ linux-x86_64 +test.test_compile.TestStackSizeStability.test_async_for_else @ linux-x86_64 +test.test_compile.TestStackSizeStability.test_if @ linux-x86_64 +test.test_compile.TestStackSizeStability.test_if_else @ linux-x86_64 +test.test_compile.TestStackSizeStability.test_try_except_star_as @ linux-x86_64 +test.test_compile.TestStackSizeStability.test_try_except_star_finally @ linux-x86_64 +test.test_compile.TestStackSizeStability.test_try_except_star_qualified @ linux-x86_64 +test.test_compile.TestStackSizeStability.test_while_else @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_compileall.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_compileall.txt new file mode 100644 index 0000000000..f847d5d87c --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_compileall.txt @@ -0,0 +1,121 @@ +test.test_compileall.CommandLineTestsNoSourceEpoch.test_compiles_as_much_as_possible @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_d_compile_error @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_d_runtime_error @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_force @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_hardlink @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_hardlink_bad_args @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_ignore_symlink_destination @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_include_bad_file @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_include_file_no_arg @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_include_file_with_arg @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_include_on_stdin @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_invalid_arg_produces_message @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_legacy_paths @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_multiple_dirs @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_multiple_optimization_levels @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_multiple_runs @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_no_args_compiles_path @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_no_args_respects_force_flag @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_no_args_respects_quiet_flag @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_pep3147_paths_normal @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_pyc_invalidation_mode @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_quiet @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_recursion_control @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_recursion_limit @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_regexp @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_silent @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_symlink_loop @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_workers @ linux-x86_64 +test.test_compileall.CommandLineTestsNoSourceEpoch.test_workers_available_cores @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_compiles_as_much_as_possible @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_d_compile_error @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_d_runtime_error @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_force @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_hardlink @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_hardlink_bad_args @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_ignore_symlink_destination @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_include_bad_file @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_include_file_no_arg @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_include_file_with_arg @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_include_on_stdin @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_invalid_arg_produces_message @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_legacy_paths @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_multiple_dirs @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_multiple_optimization_levels @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_multiple_runs @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_no_args_compiles_path @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_no_args_respects_force_flag @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_no_args_respects_quiet_flag @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_pep3147_paths_normal @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_pyc_invalidation_mode @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_quiet @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_recursion_control @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_recursion_limit @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_regexp @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_silent @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_symlink_loop @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_workers @ linux-x86_64 +test.test_compileall.CommandLineTestsWithSourceEpoch.test_workers_available_cores @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_dir_maxlevels @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_dir_pathlike @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_dir_pathlike_prependdir @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_dir_pathlike_stripdir @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_file_encoding_fallback @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_file_pathlike @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_file_pathlike_ddir @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_file_pathlike_prependdir @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_file_pathlike_stripdir @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_files @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_missing_multiprocessing @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_one_worker @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_path @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_pool_called @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_workers_cpu_count @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_compile_workers_non_positive @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_ignore_symlink_destination @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_larger_than_32_bit_times @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_multiple_optimization_levels @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_no_pycache_in_non_package @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_optimize @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_prepend_only @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_strip_prepend_and_ddir @ linux-x86_64 +test.test_compileall.CompileallTestsWithSourceEpoch.test_year_2038_mtime_compilation @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_dir_maxlevels @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_dir_pathlike @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_dir_pathlike_prependdir @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_dir_pathlike_stripdir @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_file_encoding_fallback @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_file_pathlike @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_file_pathlike_ddir @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_file_pathlike_prependdir @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_file_pathlike_stripdir @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_files @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_missing_multiprocessing @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_one_worker @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_path @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_pool_called @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_workers_cpu_count @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_compile_workers_non_positive @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_ignore_symlink_destination @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_larger_than_32_bit_times @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_magic_number @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_mtime @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_multiple_optimization_levels @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_no_pycache_in_non_package @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_optimize @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_prepend_only @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_strip_prepend_and_ddir @ linux-x86_64 +test.test_compileall.CompileallTestsWithoutSourceEpoch.test_year_2038_mtime_compilation @ linux-x86_64 +test.test_compileall.EncodingTest.test_error @ linux-x86_64 +test.test_compileall.HardlinkDedupTestsNoSourceEpoch.test_bad_args @ linux-x86_64 +test.test_compileall.HardlinkDedupTestsNoSourceEpoch.test_disabled @ linux-x86_64 +test.test_compileall.HardlinkDedupTestsNoSourceEpoch.test_duplicated_levels @ linux-x86_64 +test.test_compileall.HardlinkDedupTestsNoSourceEpoch.test_hardlink @ linux-x86_64 +test.test_compileall.HardlinkDedupTestsNoSourceEpoch.test_only_two_levels @ linux-x86_64 +test.test_compileall.HardlinkDedupTestsNoSourceEpoch.test_recompilation @ linux-x86_64 +test.test_compileall.HardlinkDedupTestsWithSourceEpoch.test_bad_args @ linux-x86_64 +test.test_compileall.HardlinkDedupTestsWithSourceEpoch.test_disabled @ linux-x86_64 +test.test_compileall.HardlinkDedupTestsWithSourceEpoch.test_duplicated_levels @ linux-x86_64 +test.test_compileall.HardlinkDedupTestsWithSourceEpoch.test_hardlink @ linux-x86_64 +test.test_compileall.HardlinkDedupTestsWithSourceEpoch.test_only_two_levels @ linux-x86_64 +test.test_compileall.HardlinkDedupTestsWithSourceEpoch.test_recompilation @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_complex.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_complex.txt new file mode 100644 index 0000000000..dd274d7f37 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_complex.txt @@ -0,0 +1,29 @@ +test.test_complex.ComplexTest.test___complex__ @ linux-x86_64 +test.test_complex.ComplexTest.test_abs @ linux-x86_64 +test.test_complex.ComplexTest.test_boolcontext @ linux-x86_64 +test.test_complex.ComplexTest.test_conjugate @ linux-x86_64 +test.test_complex.ComplexTest.test_constructor @ linux-x86_64 +test.test_complex.ComplexTest.test_constructor_special_numbers @ linux-x86_64 +test.test_complex.ComplexTest.test_divmod @ linux-x86_64 +test.test_complex.ComplexTest.test_divmod_zero_division @ linux-x86_64 +test.test_complex.ComplexTest.test_floordiv @ linux-x86_64 +test.test_complex.ComplexTest.test_floordiv_zero_division @ linux-x86_64 +test.test_complex.ComplexTest.test_format @ linux-x86_64 +test.test_complex.ComplexTest.test_getnewargs @ linux-x86_64 +test.test_complex.ComplexTest.test_hash @ linux-x86_64 +test.test_complex.ComplexTest.test_mod @ linux-x86_64 +test.test_complex.ComplexTest.test_mod_zero_division @ linux-x86_64 +test.test_complex.ComplexTest.test_neg @ linux-x86_64 +test.test_complex.ComplexTest.test_negated_imaginary_literal @ linux-x86_64 +test.test_complex.ComplexTest.test_negative_zero_repr_str @ linux-x86_64 +test.test_complex.ComplexTest.test_overflow @ linux-x86_64 +test.test_complex.ComplexTest.test_plus_minus_0j @ linux-x86_64 +test.test_complex.ComplexTest.test_pow @ linux-x86_64 +test.test_complex.ComplexTest.test_pow_with_small_integer_exponents @ linux-x86_64 +test.test_complex.ComplexTest.test_repr_roundtrip @ linux-x86_64 +test.test_complex.ComplexTest.test_repr_str @ linux-x86_64 +test.test_complex.ComplexTest.test_richcompare @ linux-x86_64 +test.test_complex.ComplexTest.test_richcompare_boundaries @ linux-x86_64 +test.test_complex.ComplexTest.test_truediv @ linux-x86_64 +test.test_complex.ComplexTest.test_truediv_zero_division @ linux-x86_64 +test.test_complex.ComplexTest.test_underscores @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_concurrent_futures.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_concurrent_futures.txt new file mode 100644 index 0000000000..fb441d2e0f --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_concurrent_futures.txt @@ -0,0 +1,112 @@ +test.test_concurrent_futures.test_as_completed.ProcessPoolForkAsCompletedTest.test_correct_timeout_exception_msg @ linux-x86_64 +test.test_concurrent_futures.test_as_completed.ProcessPoolSpawnAsCompletedTest.test_correct_timeout_exception_msg @ linux-x86_64 +test.test_concurrent_futures.test_as_completed.ProcessPoolSpawnAsCompletedTest.test_duplicate_futures @ linux-x86_64 +test.test_concurrent_futures.test_as_completed.ProcessPoolSpawnAsCompletedTest.test_no_timeout @ linux-x86_64 +test.test_concurrent_futures.test_as_completed.ProcessPoolSpawnAsCompletedTest.test_zero_timeout @ linux-x86_64 +test.test_concurrent_futures.test_as_completed.ThreadPoolAsCompletedTest.test_correct_timeout_exception_msg @ linux-x86_64 +test.test_concurrent_futures.test_as_completed.ThreadPoolAsCompletedTest.test_duplicate_futures @ linux-x86_64 +test.test_concurrent_futures.test_as_completed.ThreadPoolAsCompletedTest.test_no_timeout @ linux-x86_64 +test.test_concurrent_futures.test_as_completed.ThreadPoolAsCompletedTest.test_zero_timeout @ linux-x86_64 +test.test_concurrent_futures.test_deadlock.ProcessPoolSpawnExecutorDeadlockTest.test_crash_at_task_unpickle @ linux-x86_64 +test.test_concurrent_futures.test_deadlock.ProcessPoolSpawnExecutorDeadlockTest.test_error_at_task_pickle @ linux-x86_64 +test.test_concurrent_futures.test_deadlock.ProcessPoolSpawnExecutorDeadlockTest.test_error_at_task_unpickle @ linux-x86_64 +test.test_concurrent_futures.test_deadlock.ProcessPoolSpawnExecutorDeadlockTest.test_error_during_func_exec_on_worker @ linux-x86_64 +test.test_concurrent_futures.test_deadlock.ProcessPoolSpawnExecutorDeadlockTest.test_error_during_result_pickle_on_worker @ linux-x86_64 +test.test_concurrent_futures.test_deadlock.ProcessPoolSpawnExecutorDeadlockTest.test_error_during_result_unpickle_in_result_handler @ linux-x86_64 +test.test_concurrent_futures.test_deadlock.ProcessPoolSpawnExecutorDeadlockTest.test_exit_at_task_unpickle @ linux-x86_64 +test.test_concurrent_futures.test_deadlock.ProcessPoolSpawnExecutorDeadlockTest.test_exit_during_func_exec_on_worker @ linux-x86_64 +test.test_concurrent_futures.test_deadlock.ProcessPoolSpawnExecutorDeadlockTest.test_exit_during_result_pickle_on_worker @ linux-x86_64 +test.test_concurrent_futures.test_deadlock.ProcessPoolSpawnExecutorDeadlockTest.test_exit_during_result_unpickle_in_result_handler @ linux-x86_64 +test.test_concurrent_futures.test_deadlock.ProcessPoolSpawnExecutorDeadlockTest.test_gh105829_should_not_deadlock_if_wakeup_pipe_full @ linux-x86_64 +test.test_concurrent_futures.test_deadlock.ProcessPoolSpawnExecutorDeadlockTest.test_shutdown_deadlock_pickle @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_cancel @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_cancelled @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_done @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_done_callback_already_cancelled @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_done_callback_already_failed @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_done_callback_already_successful @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_done_callback_raises @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_done_callback_raises_already_succeeded @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_done_callback_with_cancel @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_done_callback_with_exception @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_done_callback_with_result @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_exception_with_success @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_exception_with_timeout @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_multiple_set_exception @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_multiple_set_result @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_repr @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_result_with_cancel @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_result_with_success @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_result_with_timeout @ linux-x86_64 +test.test_concurrent_futures.test_future.FutureTests.test_running @ linux-x86_64 +test.test_concurrent_futures.test_init.ProcessPoolSpawnFailingInitializerTest.test_initializer @ linux-x86_64 +test.test_concurrent_futures.test_init.ProcessPoolSpawnInitializerTest.test_initializer @ linux-x86_64 +test.test_concurrent_futures.test_init.ThreadPoolFailingInitializerTest.test_initializer @ linux-x86_64 +test.test_concurrent_futures.test_init.ThreadPoolInitializerTest.test_initializer @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolForkProcessPoolExecutorTest.test_max_tasks_per_child @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolForkProcessPoolExecutorTest.test_max_tasks_per_child_defaults_to_spawn_context @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolForkProcessPoolExecutorTest.test_max_workers_negative @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_idle_process_reuse_multiple @ linux-x86_64 +!test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_idle_process_reuse_one @ linux-x86_64 +!test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_killed_child @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_map @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_map_chunksize @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_map_exception @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_map_timeout @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_max_tasks_early_shutdown @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_max_tasks_per_child @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_max_tasks_per_child_defaults_to_spawn_context @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_max_workers_negative @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_saturation @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_shutdown_race_issue12456 @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_submit @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_submit_keyword @ linux-x86_64 +test.test_concurrent_futures.test_process_pool.ProcessPoolSpawnProcessPoolExecutorTest.test_traceback @ linux-x86_64 +test.test_concurrent_futures.test_shutdown.ProcessPoolForkProcessPoolShutdownTest.test_run_after_shutdown @ linux-x86_64 +test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_cancel_futures @ linux-x86_64 +test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_context_manager_shutdown @ linux-x86_64 +test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_hang_gh94440 @ linux-x86_64 +test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_hang_issue12364 @ linux-x86_64 +test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_processes_terminate @ linux-x86_64 +test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_run_after_shutdown @ linux-x86_64 +test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_shutdown_no_wait @ linux-x86_64 +!test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_submit_after_interpreter_shutdown @ linux-x86_64 +test.test_concurrent_futures.test_shutdown.ThreadPoolShutdownTest.test_cancel_futures @ linux-x86_64 +test.test_concurrent_futures.test_shutdown.ThreadPoolShutdownTest.test_context_manager_shutdown @ linux-x86_64 +!test.test_concurrent_futures.test_shutdown.ThreadPoolShutdownTest.test_hang_gh94440 @ linux-x86_64 +test.test_concurrent_futures.test_shutdown.ThreadPoolShutdownTest.test_hang_issue12364 @ linux-x86_64 +test.test_concurrent_futures.test_shutdown.ThreadPoolShutdownTest.test_run_after_shutdown @ linux-x86_64 +test.test_concurrent_futures.test_shutdown.ThreadPoolShutdownTest.test_shutdown_no_wait @ linux-x86_64 +test.test_concurrent_futures.test_shutdown.ThreadPoolShutdownTest.test_submit_after_interpreter_shutdown @ linux-x86_64 +!test.test_concurrent_futures.test_shutdown.ThreadPoolShutdownTest.test_thread_names_assigned @ linux-x86_64 +!test.test_concurrent_futures.test_shutdown.ThreadPoolShutdownTest.test_thread_names_default @ linux-x86_64 +test.test_concurrent_futures.test_shutdown.ThreadPoolShutdownTest.test_threads_terminate @ linux-x86_64 +test.test_concurrent_futures.test_thread_pool.ThreadPoolExecutorTest.test_default_workers @ linux-x86_64 +test.test_concurrent_futures.test_thread_pool.ThreadPoolExecutorTest.test_executor_map_current_future_cancel @ linux-x86_64 +!test.test_concurrent_futures.test_thread_pool.ThreadPoolExecutorTest.test_idle_thread_reuse @ linux-x86_64 +test.test_concurrent_futures.test_thread_pool.ThreadPoolExecutorTest.test_map @ linux-x86_64 +test.test_concurrent_futures.test_thread_pool.ThreadPoolExecutorTest.test_map_exception @ linux-x86_64 +test.test_concurrent_futures.test_thread_pool.ThreadPoolExecutorTest.test_map_submits_without_iteration @ linux-x86_64 +test.test_concurrent_futures.test_thread_pool.ThreadPoolExecutorTest.test_map_timeout @ linux-x86_64 +test.test_concurrent_futures.test_thread_pool.ThreadPoolExecutorTest.test_max_workers_negative @ linux-x86_64 +test.test_concurrent_futures.test_thread_pool.ThreadPoolExecutorTest.test_saturation @ linux-x86_64 +test.test_concurrent_futures.test_thread_pool.ThreadPoolExecutorTest.test_shutdown_race_issue12456 @ linux-x86_64 +test.test_concurrent_futures.test_thread_pool.ThreadPoolExecutorTest.test_submit @ linux-x86_64 +test.test_concurrent_futures.test_thread_pool.ThreadPoolExecutorTest.test_submit_keyword @ linux-x86_64 +test.test_concurrent_futures.test_wait.ProcessPoolSpawnWaitTest.test_20369 @ linux-x86_64 +test.test_concurrent_futures.test_wait.ProcessPoolSpawnWaitTest.test_all_completed @ linux-x86_64 +test.test_concurrent_futures.test_wait.ProcessPoolSpawnWaitTest.test_first_completed @ linux-x86_64 +test.test_concurrent_futures.test_wait.ProcessPoolSpawnWaitTest.test_first_completed_some_already_completed @ linux-x86_64 +test.test_concurrent_futures.test_wait.ProcessPoolSpawnWaitTest.test_first_exception @ linux-x86_64 +test.test_concurrent_futures.test_wait.ProcessPoolSpawnWaitTest.test_first_exception_one_already_failed @ linux-x86_64 +test.test_concurrent_futures.test_wait.ProcessPoolSpawnWaitTest.test_first_exception_some_already_complete @ linux-x86_64 +test.test_concurrent_futures.test_wait.ProcessPoolSpawnWaitTest.test_timeout @ linux-x86_64 +test.test_concurrent_futures.test_wait.ThreadPoolWaitTests.test_20369 @ linux-x86_64 +test.test_concurrent_futures.test_wait.ThreadPoolWaitTests.test_all_completed @ linux-x86_64 +test.test_concurrent_futures.test_wait.ThreadPoolWaitTests.test_first_completed @ linux-x86_64 +test.test_concurrent_futures.test_wait.ThreadPoolWaitTests.test_first_completed_some_already_completed @ linux-x86_64 +test.test_concurrent_futures.test_wait.ThreadPoolWaitTests.test_first_exception @ linux-x86_64 +test.test_concurrent_futures.test_wait.ThreadPoolWaitTests.test_first_exception_one_already_failed @ linux-x86_64 +test.test_concurrent_futures.test_wait.ThreadPoolWaitTests.test_first_exception_some_already_complete @ linux-x86_64 +test.test_concurrent_futures.test_wait.ThreadPoolWaitTests.test_pending_calls_race @ linux-x86_64 +test.test_concurrent_futures.test_wait.ThreadPoolWaitTests.test_timeout @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_configparser.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_configparser.txt new file mode 100644 index 0000000000..811985b72d --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_configparser.txt @@ -0,0 +1,337 @@ +test.test_configparser.BlatantOverrideConvertersTestCase.test_converters_at_init @ linux-x86_64 +test.test_configparser.BlatantOverrideConvertersTestCase.test_inheritance @ linux-x86_64 +test.test_configparser.BlatantOverrideConvertersTestCase.test_instance_assignment @ linux-x86_64 +test.test_configparser.CompatibleTestCase.test_comment_handling @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_add_section_default @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_basic @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_basic_from_dict @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_boolean @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_case_sensitivity @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_case_sensitivity_mapping_access @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_clear @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_default_case_sensitivity @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_defaults_keyword @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_interpolation_missing_value @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_invalid_multiline_value @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_items @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_parse_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_popitem @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_query_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_read_returns_file_list @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_read_returns_file_list_with_bytestring_path @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_safe_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_set_malformatted_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_set_nonstring_types @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_set_string_types @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_setitem @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_weird_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCase.test_write @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_basic @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_basic_from_dict @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_boolean @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_case_sensitivity @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_case_sensitivity_basic @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_case_sensitivity_conflicts @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_case_sensitivity_mapping_access @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_clear @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_default_case_sensitivity @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_endless_loop @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_extended_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_invalid_multiline_value @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_other_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_parse_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_popitem @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_query_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_read_returns_file_list @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_read_returns_file_list_with_bytestring_path @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_set_string_types @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_setitem @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_strange_options @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_weird_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseExtendedInterpolation.test_write @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseInvalidInterpolationType.test_error_on_wrong_type_for_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_add_section_default @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_basic @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_basic_from_dict @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_boolean @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_case_sensitivity @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_case_sensitivity_mapping_access @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_clear @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_default_case_sensitivity @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_defaults_keyword @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_interpolation_missing_value @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_invalid_multiline_value @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_items @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_parse_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_popitem @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_query_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_read_returns_file_list @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_read_returns_file_list_with_bytestring_path @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_set_malformatted_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_set_nonstring_types @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_set_string_types @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_setitem @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_weird_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseLegacyInterpolation.test_write @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_basic @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_basic_from_dict @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_boolean @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_case_sensitivity @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_case_sensitivity_mapping_access @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_clear @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_default_case_sensitivity @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_empty_case @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_invalid_multiline_value @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_no_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_none_as_default_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_parse_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_popitem @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_query_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_read_returns_file_list @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_read_returns_file_list_with_bytestring_path @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_set_string_types @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_setitem @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_weird_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoInterpolation.test_write @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_add_section_default @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_basic @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_basic_from_dict @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_boolean @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_case_sensitivity @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_case_sensitivity_mapping_access @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_clear @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_default_case_sensitivity @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_defaults_keyword @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_interpolation_missing_value @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_items @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_parse_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_popitem @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_query_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_read_returns_file_list @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_read_returns_file_list_with_bytestring_path @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_safe_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_set_malformatted_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_set_nonstring_types @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_set_string_types @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_setitem @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_weird_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNoValue.test_write @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_add_section_default @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_basic @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_basic_from_dict @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_boolean @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_case_sensitivity @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_case_sensitivity_mapping_access @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_clear @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_default_case_sensitivity @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_defaults_keyword @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_interpolation_missing_value @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_invalid_multiline_value @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_items @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_parse_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_popitem @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_query_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_read_returns_file_list @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_read_returns_file_list_with_bytestring_path @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_safe_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_set_malformatted_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_set_nonstring_types @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_set_string_types @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_setitem @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_weird_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDefaultSection.test_write @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_add_section_default @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_basic @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_basic_from_dict @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_boolean @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_case_sensitivity @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_case_sensitivity_mapping_access @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_clear @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_default_case_sensitivity @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_defaults_keyword @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_interpolation_missing_value @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_invalid_multiline_value @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_items @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_parse_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_popitem @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_query_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_safe_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_set_malformatted_interpolation @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_set_nonstring_types @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_set_string_types @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_setitem @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_weird_errors @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseNonStandardDelimiters.test_write @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseTrickyFile.test_cfgparser_dot_3 @ linux-x86_64 +test.test_configparser.ConfigParserTestCaseTrickyFile.test_unicode_failure @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_basic @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_basic_from_dict @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_boolean @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_case_sensitivity @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_case_sensitivity_mapping_access @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_clear @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_converters @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_default_case_sensitivity @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_invalid_multiline_value @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_parse_errors @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_popitem @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_query_errors @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_read_returns_file_list @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_read_returns_file_list_with_bytestring_path @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_set_string_types @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_setitem @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_weird_errors @ linux-x86_64 +test.test_configparser.ConvertersTestCase.test_write @ linux-x86_64 +test.test_configparser.CopyTestCase.test_basic @ linux-x86_64 +test.test_configparser.CopyTestCase.test_basic_from_dict @ linux-x86_64 +test.test_configparser.CopyTestCase.test_boolean @ linux-x86_64 +test.test_configparser.CopyTestCase.test_case_sensitivity @ linux-x86_64 +test.test_configparser.CopyTestCase.test_case_sensitivity_mapping_access @ linux-x86_64 +test.test_configparser.CopyTestCase.test_clear @ linux-x86_64 +test.test_configparser.CopyTestCase.test_default_case_sensitivity @ linux-x86_64 +test.test_configparser.CopyTestCase.test_invalid_multiline_value @ linux-x86_64 +test.test_configparser.CopyTestCase.test_parse_errors @ linux-x86_64 +test.test_configparser.CopyTestCase.test_popitem @ linux-x86_64 +test.test_configparser.CopyTestCase.test_query_errors @ linux-x86_64 +test.test_configparser.CopyTestCase.test_read_returns_file_list @ linux-x86_64 +test.test_configparser.CopyTestCase.test_read_returns_file_list_with_bytestring_path @ linux-x86_64 +test.test_configparser.CopyTestCase.test_set_string_types @ linux-x86_64 +test.test_configparser.CopyTestCase.test_setitem @ linux-x86_64 +test.test_configparser.CopyTestCase.test_weird_errors @ linux-x86_64 +test.test_configparser.CopyTestCase.test_write @ linux-x86_64 +test.test_configparser.CoverageOneHundredTestCase.test_duplicate_option_error @ linux-x86_64 +test.test_configparser.CoverageOneHundredTestCase.test_inconsistent_converters_state @ linux-x86_64 +test.test_configparser.CoverageOneHundredTestCase.test_interpolation_depth_error @ linux-x86_64 +test.test_configparser.CoverageOneHundredTestCase.test_interpolation_validation @ linux-x86_64 +test.test_configparser.CoverageOneHundredTestCase.test_legacyinterpolation_deprecation @ linux-x86_64 +test.test_configparser.CoverageOneHundredTestCase.test_parsing_error @ linux-x86_64 +test.test_configparser.CoverageOneHundredTestCase.test_readfp_deprecation @ linux-x86_64 +test.test_configparser.CoverageOneHundredTestCase.test_safeconfigparser_deprecation @ linux-x86_64 +test.test_configparser.CoverageOneHundredTestCase.test_sectionproxy_repr @ linux-x86_64 +test.test_configparser.ExceptionContextTestCase.test_get_basic_interpolation @ linux-x86_64 +test.test_configparser.ExceptionContextTestCase.test_get_extended_interpolation @ linux-x86_64 +test.test_configparser.ExceptionContextTestCase.test_missing_options @ linux-x86_64 +test.test_configparser.ExceptionContextTestCase.test_missing_section @ linux-x86_64 +test.test_configparser.ExceptionContextTestCase.test_remove_option @ linux-x86_64 +test.test_configparser.ExceptionPicklingTestCase.test_duplicateoptionerror @ linux-x86_64 +test.test_configparser.ExceptionPicklingTestCase.test_duplicatesectionerror @ linux-x86_64 +test.test_configparser.ExceptionPicklingTestCase.test_error @ linux-x86_64 +test.test_configparser.ExceptionPicklingTestCase.test_interpolationdeptherror @ linux-x86_64 +test.test_configparser.ExceptionPicklingTestCase.test_interpolationerror @ linux-x86_64 +test.test_configparser.ExceptionPicklingTestCase.test_interpolationmissingoptionerror @ linux-x86_64 +test.test_configparser.ExceptionPicklingTestCase.test_interpolationsyntaxerror @ linux-x86_64 +test.test_configparser.ExceptionPicklingTestCase.test_missingsectionheadererror @ linux-x86_64 +test.test_configparser.ExceptionPicklingTestCase.test_nooptionerror @ linux-x86_64 +test.test_configparser.ExceptionPicklingTestCase.test_nosectionerror @ linux-x86_64 +test.test_configparser.ExceptionPicklingTestCase.test_parsingerror @ linux-x86_64 +test.test_configparser.InlineCommentStrippingTestCase.test_stripping @ linux-x86_64 +test.test_configparser.Issue7005TestCase.test_none_as_value_stringified @ linux-x86_64 +test.test_configparser.Issue7005TestCase.test_none_as_value_stringified_raw @ linux-x86_64 +test.test_configparser.MiscTestCase.test__all__ @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_basic @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_basic_from_dict @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_boolean @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_case_sensitivity @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_case_sensitivity_mapping_access @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_clear @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_default_case_sensitivity @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_dominating_multiline_values @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_invalid_multiline_value @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_parse_errors @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_popitem @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_query_errors @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_read_returns_file_list @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_read_returns_file_list_with_bytestring_path @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_set_string_types @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_setitem @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_weird_errors @ linux-x86_64 +test.test_configparser.MultilineValuesTestCase.test_write @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_basic @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_basic_from_dict @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_boolean @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_case_sensitivity @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_case_sensitivity_mapping_access @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_clear @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_default_case_sensitivity @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_defaults_keyword @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_interpolation @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_invalid_multiline_value @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_items @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_parse_errors @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_popitem @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_query_errors @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_read_returns_file_list @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_read_returns_file_list_with_bytestring_path @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_set_nonstring_types @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_set_string_types @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_setitem @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_weird_errors @ linux-x86_64 +test.test_configparser.RawConfigParserTestCase.test_write @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_basic @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_basic_from_dict @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_boolean @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_case_sensitivity @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_case_sensitivity_mapping_access @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_clear @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_default_case_sensitivity @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_defaults_keyword @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_interpolation @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_invalid_multiline_value @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_items @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_parse_errors @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_popitem @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_query_errors @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_set_nonstring_types @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_set_string_types @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_setitem @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_weird_errors @ linux-x86_64 +test.test_configparser.RawConfigParserTestCaseNonStandardDelimiters.test_write @ linux-x86_64 +test.test_configparser.RawConfigParserTestSambaConf.test_reading @ linux-x86_64 +test.test_configparser.ReadFileTestCase.test_file @ linux-x86_64 +test.test_configparser.ReadFileTestCase.test_iterable @ linux-x86_64 +test.test_configparser.ReadFileTestCase.test_readline_generator @ linux-x86_64 +test.test_configparser.ReadFileTestCase.test_source_as_bytes @ linux-x86_64 +test.test_configparser.SortedTestCase.test_basic @ linux-x86_64 +test.test_configparser.SortedTestCase.test_basic_from_dict @ linux-x86_64 +test.test_configparser.SortedTestCase.test_boolean @ linux-x86_64 +test.test_configparser.SortedTestCase.test_case_sensitivity @ linux-x86_64 +test.test_configparser.SortedTestCase.test_case_sensitivity_mapping_access @ linux-x86_64 +test.test_configparser.SortedTestCase.test_clear @ linux-x86_64 +test.test_configparser.SortedTestCase.test_default_case_sensitivity @ linux-x86_64 +test.test_configparser.SortedTestCase.test_defaults_keyword @ linux-x86_64 +test.test_configparser.SortedTestCase.test_interpolation @ linux-x86_64 +test.test_configparser.SortedTestCase.test_invalid_multiline_value @ linux-x86_64 +test.test_configparser.SortedTestCase.test_items @ linux-x86_64 +test.test_configparser.SortedTestCase.test_parse_errors @ linux-x86_64 +test.test_configparser.SortedTestCase.test_popitem @ linux-x86_64 +test.test_configparser.SortedTestCase.test_query_errors @ linux-x86_64 +test.test_configparser.SortedTestCase.test_read_returns_file_list @ linux-x86_64 +test.test_configparser.SortedTestCase.test_read_returns_file_list_with_bytestring_path @ linux-x86_64 +test.test_configparser.SortedTestCase.test_set_nonstring_types @ linux-x86_64 +test.test_configparser.SortedTestCase.test_set_string_types @ linux-x86_64 +test.test_configparser.SortedTestCase.test_setitem @ linux-x86_64 +test.test_configparser.SortedTestCase.test_sorted @ linux-x86_64 +test.test_configparser.SortedTestCase.test_weird_errors @ linux-x86_64 +test.test_configparser.SortedTestCase.test_write @ linux-x86_64 +test.test_configparser.StrictTestCase.test_basic @ linux-x86_64 +test.test_configparser.StrictTestCase.test_basic_from_dict @ linux-x86_64 +test.test_configparser.StrictTestCase.test_boolean @ linux-x86_64 +test.test_configparser.StrictTestCase.test_case_sensitivity @ linux-x86_64 +test.test_configparser.StrictTestCase.test_case_sensitivity_mapping_access @ linux-x86_64 +test.test_configparser.StrictTestCase.test_clear @ linux-x86_64 +test.test_configparser.StrictTestCase.test_default_case_sensitivity @ linux-x86_64 +test.test_configparser.StrictTestCase.test_invalid_multiline_value @ linux-x86_64 +test.test_configparser.StrictTestCase.test_parse_errors @ linux-x86_64 +test.test_configparser.StrictTestCase.test_popitem @ linux-x86_64 +test.test_configparser.StrictTestCase.test_query_errors @ linux-x86_64 +test.test_configparser.StrictTestCase.test_read_returns_file_list @ linux-x86_64 +test.test_configparser.StrictTestCase.test_read_returns_file_list_with_bytestring_path @ linux-x86_64 +test.test_configparser.StrictTestCase.test_set_string_types @ linux-x86_64 +test.test_configparser.StrictTestCase.test_setitem @ linux-x86_64 +test.test_configparser.StrictTestCase.test_weird_errors @ linux-x86_64 +test.test_configparser.StrictTestCase.test_write @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_contains.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_contains.txt new file mode 100644 index 0000000000..9e8dfde5ae --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_contains.txt @@ -0,0 +1,4 @@ +test.test_contains.TestContains.test_block_fallback @ linux-x86_64 +test.test_contains.TestContains.test_builtin_sequence_types @ linux-x86_64 +test.test_contains.TestContains.test_common_tests @ linux-x86_64 +test.test_contains.TestContains.test_nonreflexive @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_context.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_context.txt new file mode 100644 index 0000000000..cba6f09333 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_context.txt @@ -0,0 +1,15 @@ +test.test_context.ContextTest.test_context_copy_1 @ linux-x86_64 +test.test_context.ContextTest.test_context_get_context_1 @ linux-x86_64 +test.test_context.ContextTest.test_context_getset_1 @ linux-x86_64 +test.test_context.ContextTest.test_context_getset_2 @ linux-x86_64 +test.test_context.ContextTest.test_context_getset_3 @ linux-x86_64 +test.test_context.ContextTest.test_context_getset_5 @ linux-x86_64 +test.test_context.ContextTest.test_context_run_1 @ linux-x86_64 +test.test_context.ContextTest.test_context_run_2 @ linux-x86_64 +test.test_context.ContextTest.test_context_run_3 @ linux-x86_64 +test.test_context.ContextTest.test_context_run_5 @ linux-x86_64 +test.test_context.ContextTest.test_context_run_6 @ linux-x86_64 +test.test_context.ContextTest.test_context_run_7 @ linux-x86_64 +test.test_context.ContextTest.test_context_subclassing_1 @ linux-x86_64 +test.test_context.ContextTest.test_context_threads_1 @ linux-x86_64 +test.test_context.ContextTest.test_context_typerrors_1 @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_contextlib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_contextlib.txt new file mode 100644 index 0000000000..e80bfd6a73 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_contextlib.txt @@ -0,0 +1,85 @@ +test.test_contextlib.ClosingTestCase.test_closing @ linux-x86_64 +test.test_contextlib.ClosingTestCase.test_closing_error @ linux-x86_64 +test.test_contextlib.ClosingTestCase.test_instance_docs @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_contextmanager_attribs @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_contextmanager_do_not_unchain_non_stopiteration_exceptions @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_contextmanager_doc_attrib @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_contextmanager_except @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_contextmanager_except_pep479 @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_contextmanager_except_stopiter @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_contextmanager_finally @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_contextmanager_no_reraise @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_contextmanager_non_normalised @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_contextmanager_plain @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_contextmanager_traceback @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_contextmanager_trap_no_yield @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_contextmanager_trap_second_yield @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_contextmanager_trap_yield_after_throw @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_contextmanager_wrap_runtimeerror @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_instance_docstring_given_cm_docstring @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_keywords @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_param_errors @ linux-x86_64 +test.test_contextlib.ContextManagerTestCase.test_recursive @ linux-x86_64 +test.test_contextlib.FileContextTestCase.testWithOpen @ linux-x86_64 +test.test_contextlib.LockContextTestCase.testWithBoundedSemaphore @ linux-x86_64 +test.test_contextlib.LockContextTestCase.testWithCondition @ linux-x86_64 +test.test_contextlib.LockContextTestCase.testWithLock @ linux-x86_64 +test.test_contextlib.LockContextTestCase.testWithRLock @ linux-x86_64 +test.test_contextlib.LockContextTestCase.testWithSemaphore @ linux-x86_64 +test.test_contextlib.NullcontextTestCase.test_nullcontext @ linux-x86_64 +test.test_contextlib.TestAbstractContextManager.test_enter @ linux-x86_64 +test.test_contextlib.TestAbstractContextManager.test_exit_is_abstract @ linux-x86_64 +test.test_contextlib.TestAbstractContextManager.test_structural_subclassing @ linux-x86_64 +test.test_contextlib.TestChdir.test_exception @ linux-x86_64 +test.test_contextlib.TestChdir.test_reentrant @ linux-x86_64 +test.test_contextlib.TestChdir.test_simple @ linux-x86_64 +test.test_contextlib.TestContextDecorator.test_contextdecorator @ linux-x86_64 +test.test_contextlib.TestContextDecorator.test_contextdecorator_as_mixin @ linux-x86_64 +test.test_contextlib.TestContextDecorator.test_contextdecorator_with_exception @ linux-x86_64 +test.test_contextlib.TestContextDecorator.test_contextmanager_as_decorator @ linux-x86_64 +test.test_contextlib.TestContextDecorator.test_decorating_method @ linux-x86_64 +test.test_contextlib.TestContextDecorator.test_decorator @ linux-x86_64 +test.test_contextlib.TestContextDecorator.test_decorator_with_exception @ linux-x86_64 +test.test_contextlib.TestContextDecorator.test_instance_docs @ linux-x86_64 +test.test_contextlib.TestContextDecorator.test_typo_enter @ linux-x86_64 +test.test_contextlib.TestContextDecorator.test_typo_exit @ linux-x86_64 +test.test_contextlib.TestExitStack.test_body_exception_suppress @ linux-x86_64 +test.test_contextlib.TestExitStack.test_callback @ linux-x86_64 +test.test_contextlib.TestExitStack.test_close @ linux-x86_64 +test.test_contextlib.TestExitStack.test_dont_reraise_RuntimeError @ linux-x86_64 +test.test_contextlib.TestExitStack.test_enter_context @ linux-x86_64 +test.test_contextlib.TestExitStack.test_enter_context_errors @ linux-x86_64 +test.test_contextlib.TestExitStack.test_excessive_nesting @ linux-x86_64 +test.test_contextlib.TestExitStack.test_exit_exception_chaining_reference @ linux-x86_64 +test.test_contextlib.TestExitStack.test_exit_exception_chaining_suppress @ linux-x86_64 +test.test_contextlib.TestExitStack.test_exit_exception_non_suppressing @ linux-x86_64 +test.test_contextlib.TestExitStack.test_exit_exception_traceback @ linux-x86_64 +test.test_contextlib.TestExitStack.test_exit_exception_with_existing_context @ linux-x86_64 +test.test_contextlib.TestExitStack.test_exit_raise @ linux-x86_64 +test.test_contextlib.TestExitStack.test_exit_suppress @ linux-x86_64 +test.test_contextlib.TestExitStack.test_instance_bypass @ linux-x86_64 +test.test_contextlib.TestExitStack.test_instance_docs @ linux-x86_64 +test.test_contextlib.TestExitStack.test_no_resources @ linux-x86_64 +test.test_contextlib.TestExitStack.test_pop_all @ linux-x86_64 +test.test_contextlib.TestExitStack.test_push @ linux-x86_64 +test.test_contextlib.TestRedirectStderr.test_cm_is_reentrant @ linux-x86_64 +test.test_contextlib.TestRedirectStderr.test_cm_is_reusable @ linux-x86_64 +test.test_contextlib.TestRedirectStderr.test_enter_result_is_target @ linux-x86_64 +test.test_contextlib.TestRedirectStderr.test_instance_docs @ linux-x86_64 +test.test_contextlib.TestRedirectStderr.test_no_redirect_in_init @ linux-x86_64 +test.test_contextlib.TestRedirectStderr.test_redirect_to_string_io @ linux-x86_64 +test.test_contextlib.TestRedirectStdout.test_cm_is_reentrant @ linux-x86_64 +test.test_contextlib.TestRedirectStdout.test_cm_is_reusable @ linux-x86_64 +test.test_contextlib.TestRedirectStdout.test_enter_result_is_target @ linux-x86_64 +test.test_contextlib.TestRedirectStdout.test_instance_docs @ linux-x86_64 +test.test_contextlib.TestRedirectStdout.test_no_redirect_in_init @ linux-x86_64 +test.test_contextlib.TestRedirectStdout.test_redirect_to_string_io @ linux-x86_64 +test.test_contextlib.TestSuppress.test_cm_is_reentrant @ linux-x86_64 +test.test_contextlib.TestSuppress.test_exact_exception @ linux-x86_64 +test.test_contextlib.TestSuppress.test_exception_hierarchy @ linux-x86_64 +test.test_contextlib.TestSuppress.test_instance_docs @ linux-x86_64 +test.test_contextlib.TestSuppress.test_multiple_exception_args @ linux-x86_64 +test.test_contextlib.TestSuppress.test_no_args @ linux-x86_64 +test.test_contextlib.TestSuppress.test_no_exception @ linux-x86_64 +test.test_contextlib.TestSuppress.test_no_result_from_enter @ linux-x86_64 +test.test_contextlib.TestSuppress.test_other_exception @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_contextlib_async.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_contextlib_async.txt new file mode 100644 index 0000000000..0e63035340 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_contextlib_async.txt @@ -0,0 +1,21 @@ +test.test_contextlib_async.AclosingTestCase.test_instance_docs @ linux-x86_64 +test.test_contextlib_async.AsyncContextManagerTestCase.test_contextmanager_attribs @ linux-x86_64 +test.test_contextlib_async.AsyncContextManagerTestCase.test_contextmanager_doc_attrib @ linux-x86_64 +test.test_contextlib_async.TestAbstractAsyncContextManager.test_exit_is_abstract @ linux-x86_64 +test.test_contextlib_async.TestAbstractAsyncContextManager.test_structural_subclassing @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_body_exception_suppress @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_callback @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_dont_reraise_RuntimeError @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_enter_context @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_enter_context_errors @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_excessive_nesting @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_exit_exception_chaining_reference @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_exit_exception_chaining_suppress @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_exit_exception_non_suppressing @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_exit_exception_with_existing_context @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_exit_raise @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_exit_suppress @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_instance_bypass @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_instance_docs @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_no_resources @ linux-x86_64 +test.test_contextlib_async.TestAsyncExitStack.test_push @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_copy.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_copy.txt new file mode 100644 index 0000000000..13c1eac947 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_copy.txt @@ -0,0 +1,74 @@ +test.test_copy.TestCopy.test_copy_atomic @ linux-x86_64 +test.test_copy.TestCopy.test_copy_basic @ linux-x86_64 +test.test_copy.TestCopy.test_copy_bytearray @ linux-x86_64 +test.test_copy.TestCopy.test_copy_cant @ linux-x86_64 +test.test_copy.TestCopy.test_copy_copy @ linux-x86_64 +test.test_copy.TestCopy.test_copy_dict @ linux-x86_64 +test.test_copy.TestCopy.test_copy_frozenset @ linux-x86_64 +test.test_copy.TestCopy.test_copy_function @ linux-x86_64 +test.test_copy.TestCopy.test_copy_inst_copy @ linux-x86_64 +test.test_copy.TestCopy.test_copy_inst_getinitargs @ linux-x86_64 +test.test_copy.TestCopy.test_copy_inst_getnewargs @ linux-x86_64 +test.test_copy.TestCopy.test_copy_inst_getnewargs_ex @ linux-x86_64 +test.test_copy.TestCopy.test_copy_inst_getstate @ linux-x86_64 +test.test_copy.TestCopy.test_copy_inst_getstate_setstate @ linux-x86_64 +test.test_copy.TestCopy.test_copy_inst_setstate @ linux-x86_64 +test.test_copy.TestCopy.test_copy_inst_vanilla @ linux-x86_64 +test.test_copy.TestCopy.test_copy_list @ linux-x86_64 +test.test_copy.TestCopy.test_copy_list_subclass @ linux-x86_64 +test.test_copy.TestCopy.test_copy_reduce @ linux-x86_64 +test.test_copy.TestCopy.test_copy_reduce_ex @ linux-x86_64 +test.test_copy.TestCopy.test_copy_registry @ linux-x86_64 +test.test_copy.TestCopy.test_copy_set @ linux-x86_64 +test.test_copy.TestCopy.test_copy_slots @ linux-x86_64 +test.test_copy.TestCopy.test_copy_tuple @ linux-x86_64 +test.test_copy.TestCopy.test_copy_tuple_subclass @ linux-x86_64 +!test.test_copy.TestCopy.test_copy_weakkeydict @ linux-x86_64 +test.test_copy.TestCopy.test_copy_weakref @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_atomic @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_basic @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_bound_method @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_cant @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_deepcopy @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_dict @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_dict_subclass @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_dont_memo_immutable @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_empty_tuple @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_function @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_inst_deepcopy @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_inst_getinitargs @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_inst_getnewargs @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_inst_getnewargs_ex @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_inst_getstate @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_inst_getstate_setstate @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_inst_setstate @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_inst_vanilla @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_issubclass @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_keepalive @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_list @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_list_subclass @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_memo @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_reduce @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_reduce_ex @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_reflexive_dict @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_reflexive_inst @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_reflexive_list @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_reflexive_tuple @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_registry @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_slots @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_tuple @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_tuple_of_immutables @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_tuple_subclass @ linux-x86_64 +!test.test_copy.TestCopy.test_deepcopy_weakkeydict @ linux-x86_64 +test.test_copy.TestCopy.test_deepcopy_weakref @ linux-x86_64 +test.test_copy.TestCopy.test_exceptions @ linux-x86_64 +test.test_copy.TestCopy.test_getstate_exc @ linux-x86_64 +test.test_copy.TestCopy.test_reconstruct_nostate @ linux-x86_64 +test.test_copy.TestCopy.test_reconstruct_reflexive @ linux-x86_64 +test.test_copy.TestCopy.test_reconstruct_state @ linux-x86_64 +test.test_copy.TestCopy.test_reconstruct_state_setstate @ linux-x86_64 +test.test_copy.TestCopy.test_reconstruct_string @ linux-x86_64 +test.test_copy.TestCopy.test_reduce_4tuple @ linux-x86_64 +test.test_copy.TestCopy.test_reduce_5tuple @ linux-x86_64 +test.test_copy.TestCopy.test_reduce_6tuple @ linux-x86_64 +test.test_copy.TestCopy.test_reduce_6tuple_none @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_copyreg.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_copyreg.txt new file mode 100644 index 0000000000..3d90ddb1df --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_copyreg.txt @@ -0,0 +1,6 @@ +test.test_copyreg.CopyRegTestCase.test_bool @ linux-x86_64 +test.test_copyreg.CopyRegTestCase.test_class @ linux-x86_64 +test.test_copyreg.CopyRegTestCase.test_extension_registry @ linux-x86_64 +test.test_copyreg.CopyRegTestCase.test_noncallable_constructor @ linux-x86_64 +test.test_copyreg.CopyRegTestCase.test_noncallable_reduce @ linux-x86_64 +test.test_copyreg.CopyRegTestCase.test_slotnames @ linux-x86_64 diff --git a/graalpython/lib-graalpython/modules/hpy.egg-info/dependency_links.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cppext.txt similarity index 100% rename from graalpython/lib-graalpython/modules/hpy.egg-info/dependency_links.txt rename to graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_cppext.txt diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_crypt.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_crypt.txt new file mode 100644 index 0000000000..48e58c8afc --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_crypt.txt @@ -0,0 +1,6 @@ +test.test_crypt.CryptTestCase.test_crypt @ linux-x86_64 +test.test_crypt.CryptTestCase.test_invalid_rounds @ linux-x86_64 +test.test_crypt.CryptTestCase.test_methods @ linux-x86_64 +test.test_crypt.CryptTestCase.test_salt @ linux-x86_64 +test.test_crypt.CryptTestCase.test_saltedcrypt @ linux-x86_64 +test.test_crypt.CryptTestCase.test_sha2_rounds @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_csv.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_csv.txt new file mode 100644 index 0000000000..1855d81e76 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_csv.txt @@ -0,0 +1,110 @@ +test.test_csv.KeyOrderingTest.test_ordered_dict_reader @ linux-x86_64 +test.test_csv.KeyOrderingTest.test_ordering_for_the_dict_reader_and_writer @ linux-x86_64 +test.test_csv.MiscTestCase.test__all__ @ linux-x86_64 +test.test_csv.MiscTestCase.test_subclassable @ linux-x86_64 +test.test_csv.TestArrayWrites.test_char_write @ linux-x86_64 +test.test_csv.TestArrayWrites.test_double_write @ linux-x86_64 +test.test_csv.TestArrayWrites.test_float_write @ linux-x86_64 +test.test_csv.TestArrayWrites.test_int_write @ linux-x86_64 +test.test_csv.TestDialectExcel.test_blankline @ linux-x86_64 +test.test_csv.TestDialectExcel.test_dubious_quote @ linux-x86_64 +test.test_csv.TestDialectExcel.test_empty_fields @ linux-x86_64 +test.test_csv.TestDialectExcel.test_inline_quote @ linux-x86_64 +test.test_csv.TestDialectExcel.test_inline_quotes @ linux-x86_64 +test.test_csv.TestDialectExcel.test_lone_quote @ linux-x86_64 +test.test_csv.TestDialectExcel.test_newlines @ linux-x86_64 +test.test_csv.TestDialectExcel.test_null @ linux-x86_64 +test.test_csv.TestDialectExcel.test_quote_and_quote @ linux-x86_64 +test.test_csv.TestDialectExcel.test_quote_fieldsep @ linux-x86_64 +test.test_csv.TestDialectExcel.test_quoted @ linux-x86_64 +test.test_csv.TestDialectExcel.test_quoted_nl @ linux-x86_64 +test.test_csv.TestDialectExcel.test_quoted_quote @ linux-x86_64 +test.test_csv.TestDialectExcel.test_quoted_quotes @ linux-x86_64 +test.test_csv.TestDialectExcel.test_quotes @ linux-x86_64 +test.test_csv.TestDialectExcel.test_quotes_and_more @ linux-x86_64 +test.test_csv.TestDialectExcel.test_simple @ linux-x86_64 +test.test_csv.TestDialectExcel.test_simple_writer @ linux-x86_64 +test.test_csv.TestDialectExcel.test_single @ linux-x86_64 +test.test_csv.TestDialectExcel.test_single_quoted_quote @ linux-x86_64 +test.test_csv.TestDialectExcel.test_single_writer @ linux-x86_64 +test.test_csv.TestDialectExcel.test_singlequoted @ linux-x86_64 +test.test_csv.TestDialectExcel.test_singlequoted_left_empty @ linux-x86_64 +test.test_csv.TestDialectExcel.test_singlequoted_right_empty @ linux-x86_64 +test.test_csv.TestDialectExcel.test_space_and_quote @ linux-x86_64 +test.test_csv.TestDialectRegistry.test_bad_dialect @ linux-x86_64 +test.test_csv.TestDialectRegistry.test_dialect_apply @ linux-x86_64 +test.test_csv.TestDialectRegistry.test_incomplete_dialect @ linux-x86_64 +test.test_csv.TestDialectRegistry.test_register_kwargs @ linux-x86_64 +test.test_csv.TestDialectRegistry.test_register_kwargs_override @ linux-x86_64 +test.test_csv.TestDialectRegistry.test_registry @ linux-x86_64 +test.test_csv.TestDialectRegistry.test_registry_badargs @ linux-x86_64 +test.test_csv.TestDialectRegistry.test_space_dialect @ linux-x86_64 +test.test_csv.TestDialectUnix.test_simple_reader @ linux-x86_64 +test.test_csv.TestDialectUnix.test_simple_writer @ linux-x86_64 +test.test_csv.TestDialectValidity.test_delimiter @ linux-x86_64 +test.test_csv.TestDialectValidity.test_escapechar @ linux-x86_64 +test.test_csv.TestDialectValidity.test_invalid_chars @ linux-x86_64 +test.test_csv.TestDialectValidity.test_lineterminator @ linux-x86_64 +test.test_csv.TestDialectValidity.test_quoting @ linux-x86_64 +test.test_csv.TestDictFields.test_read_dict_fieldnames_chain @ linux-x86_64 +test.test_csv.TestDictFields.test_read_dict_fieldnames_from_file @ linux-x86_64 +test.test_csv.TestDictFields.test_read_dict_fields @ linux-x86_64 +test.test_csv.TestDictFields.test_read_dict_no_fieldnames @ linux-x86_64 +test.test_csv.TestDictFields.test_read_long @ linux-x86_64 +test.test_csv.TestDictFields.test_read_long_with_rest @ linux-x86_64 +test.test_csv.TestDictFields.test_read_long_with_rest_no_fieldnames @ linux-x86_64 +test.test_csv.TestDictFields.test_read_multi @ linux-x86_64 +test.test_csv.TestDictFields.test_read_semi_sep @ linux-x86_64 +test.test_csv.TestDictFields.test_read_short @ linux-x86_64 +test.test_csv.TestDictFields.test_read_with_blanks @ linux-x86_64 +test.test_csv.TestDictFields.test_typo_in_extrasaction_raises_error @ linux-x86_64 +test.test_csv.TestDictFields.test_write_field_not_in_field_names_ignore @ linux-x86_64 +test.test_csv.TestDictFields.test_write_field_not_in_field_names_raise @ linux-x86_64 +test.test_csv.TestDictFields.test_write_fields_not_in_fieldnames @ linux-x86_64 +test.test_csv.TestDictFields.test_write_multiple_dict_rows @ linux-x86_64 +test.test_csv.TestDictFields.test_write_no_fields @ linux-x86_64 +test.test_csv.TestDictFields.test_write_simple_dict @ linux-x86_64 +test.test_csv.TestDictFields.test_writeheader_return_value @ linux-x86_64 +test.test_csv.TestEscapedExcel.test_escape_fieldsep @ linux-x86_64 +test.test_csv.TestEscapedExcel.test_read_escape_fieldsep @ linux-x86_64 +test.test_csv.TestQuotedEscapedExcel.test_read_escape_fieldsep @ linux-x86_64 +test.test_csv.TestQuotedEscapedExcel.test_write_escape_fieldsep @ linux-x86_64 +test.test_csv.TestSniffer.test_delimiters @ linux-x86_64 +test.test_csv.TestSniffer.test_doublequote @ linux-x86_64 +test.test_csv.TestSniffer.test_guess_quote_and_delimiter @ linux-x86_64 +test.test_csv.TestSniffer.test_has_header @ linux-x86_64 +test.test_csv.TestSniffer.test_has_header_regex_special_delimiter @ linux-x86_64 +test.test_csv.TestSniffer.test_has_header_strings @ linux-x86_64 +test.test_csv.TestSniffer.test_issue43625 @ linux-x86_64 +test.test_csv.TestSniffer.test_sniff @ linux-x86_64 +test.test_csv.TestUnicode.test_unicode_read @ linux-x86_64 +test.test_csv.TestUnicode.test_unicode_write @ linux-x86_64 +test.test_csv.Test_Csv.test_read_bigfield @ linux-x86_64 +test.test_csv.Test_Csv.test_read_delimiter @ linux-x86_64 +test.test_csv.Test_Csv.test_read_eof @ linux-x86_64 +test.test_csv.Test_Csv.test_read_eol @ linux-x86_64 +test.test_csv.Test_Csv.test_read_escape @ linux-x86_64 +test.test_csv.Test_Csv.test_read_linenum @ linux-x86_64 +test.test_csv.Test_Csv.test_read_nul @ linux-x86_64 +test.test_csv.Test_Csv.test_read_oddinputs @ linux-x86_64 +test.test_csv.Test_Csv.test_read_quoting @ linux-x86_64 +test.test_csv.Test_Csv.test_read_skipinitialspace @ linux-x86_64 +test.test_csv.Test_Csv.test_reader_arg_valid @ linux-x86_64 +test.test_csv.Test_Csv.test_reader_attrs @ linux-x86_64 +test.test_csv.Test_Csv.test_reader_dialect_attrs @ linux-x86_64 +test.test_csv.Test_Csv.test_reader_kw_attrs @ linux-x86_64 +test.test_csv.Test_Csv.test_roundtrip_escaped_unquoted_newlines @ linux-x86_64 +test.test_csv.Test_Csv.test_roundtrip_quoteed_newlines @ linux-x86_64 +test.test_csv.Test_Csv.test_write_arg_valid @ linux-x86_64 +test.test_csv.Test_Csv.test_write_bigfield @ linux-x86_64 +test.test_csv.Test_Csv.test_write_escape @ linux-x86_64 +test.test_csv.Test_Csv.test_write_iterable @ linux-x86_64 +test.test_csv.Test_Csv.test_write_lineterminator @ linux-x86_64 +test.test_csv.Test_Csv.test_write_quoting @ linux-x86_64 +test.test_csv.Test_Csv.test_writer_arg_valid @ linux-x86_64 +test.test_csv.Test_Csv.test_writer_attrs @ linux-x86_64 +test.test_csv.Test_Csv.test_writer_dialect_attrs @ linux-x86_64 +test.test_csv.Test_Csv.test_writer_kw_attrs @ linux-x86_64 +test.test_csv.Test_Csv.test_writerows @ linux-x86_64 +test.test_csv.Test_Csv.test_writerows_errors @ linux-x86_64 +test.test_csv.Test_Csv.test_writerows_with_none @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ctypes.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ctypes.txt new file mode 100644 index 0000000000..936392b758 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ctypes.txt @@ -0,0 +1,247 @@ +ctypes.test.test_anon.AnonTest.test_anon_nonmember @ linux-x86_64 +ctypes.test.test_anon.AnonTest.test_anon_nonseq @ linux-x86_64 +ctypes.test.test_array_in_pointer.Test.test @ linux-x86_64 +ctypes.test.test_array_in_pointer.Test.test_2 @ linux-x86_64 +ctypes.test.test_arrays.ArrayTestCase.test_bad_subclass @ linux-x86_64 +ctypes.test.test_arrays.ArrayTestCase.test_bpo36504_signed_int_overflow @ linux-x86_64 +ctypes.test.test_arrays.ArrayTestCase.test_cache @ linux-x86_64 +ctypes.test.test_arrays.ArrayTestCase.test_classcache @ linux-x86_64 +ctypes.test.test_arrays.ArrayTestCase.test_empty_element_array @ linux-x86_64 +ctypes.test.test_arrays.ArrayTestCase.test_empty_element_struct @ linux-x86_64 +ctypes.test.test_arrays.ArrayTestCase.test_from_address @ linux-x86_64 +ctypes.test.test_arrays.ArrayTestCase.test_numeric_arrays @ linux-x86_64 +ctypes.test.test_arrays.ArrayTestCase.test_simple @ linux-x86_64 +ctypes.test.test_arrays.ArrayTestCase.test_subclass @ linux-x86_64 +ctypes.test.test_arrays.ArrayTestCase.test_zero_length @ linux-x86_64 +ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase.test_callbacks @ linux-x86_64 +ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase.test_callbacks_2 @ linux-x86_64 +ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase.test_longlong_callbacks @ linux-x86_64 +ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase.test_pointers @ linux-x86_64 +ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase.test_recursive_as_param @ linux-x86_64 +ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase.test_shorts @ linux-x86_64 +ctypes.test.test_as_parameter.AsParamPropertyWrapperTestCase.test_wchar_parm @ linux-x86_64 +ctypes.test.test_as_parameter.AsParamWrapperTestCase.test_callbacks @ linux-x86_64 +ctypes.test.test_as_parameter.AsParamWrapperTestCase.test_callbacks_2 @ linux-x86_64 +ctypes.test.test_as_parameter.AsParamWrapperTestCase.test_longlong_callbacks @ linux-x86_64 +ctypes.test.test_as_parameter.AsParamWrapperTestCase.test_pointers @ linux-x86_64 +ctypes.test.test_as_parameter.AsParamWrapperTestCase.test_recursive_as_param @ linux-x86_64 +ctypes.test.test_as_parameter.AsParamWrapperTestCase.test_shorts @ linux-x86_64 +ctypes.test.test_as_parameter.AsParamWrapperTestCase.test_wchar_parm @ linux-x86_64 +ctypes.test.test_as_parameter.BasicWrapTestCase.test_callbacks @ linux-x86_64 +ctypes.test.test_as_parameter.BasicWrapTestCase.test_callbacks_2 @ linux-x86_64 +ctypes.test.test_as_parameter.BasicWrapTestCase.test_longlong_callbacks @ linux-x86_64 +ctypes.test.test_as_parameter.BasicWrapTestCase.test_pointers @ linux-x86_64 +ctypes.test.test_as_parameter.BasicWrapTestCase.test_recursive_as_param @ linux-x86_64 +ctypes.test.test_as_parameter.BasicWrapTestCase.test_shorts @ linux-x86_64 +ctypes.test.test_as_parameter.BasicWrapTestCase.test_wchar_parm @ linux-x86_64 +ctypes.test.test_bitfields.BitFieldTest.test_c_wchar @ linux-x86_64 +ctypes.test.test_bitfields.BitFieldTest.test_mixed_1 @ linux-x86_64 +ctypes.test.test_bitfields.BitFieldTest.test_mixed_2 @ linux-x86_64 +ctypes.test.test_bitfields.BitFieldTest.test_mixed_3 @ linux-x86_64 +ctypes.test.test_bitfields.BitFieldTest.test_mixed_4 @ linux-x86_64 +ctypes.test.test_bitfields.BitFieldTest.test_multi_bitfields_size @ linux-x86_64 +ctypes.test.test_bitfields.BitFieldTest.test_nonint_types @ linux-x86_64 +ctypes.test.test_bitfields.BitFieldTest.test_single_bitfield_size @ linux-x86_64 +ctypes.test.test_bitfields.BitFieldTest.test_uint32 @ linux-x86_64 +ctypes.test.test_buffers.StringBufferTestCase.test_buffer @ linux-x86_64 +ctypes.test.test_buffers.StringBufferTestCase.test_buffer_interface @ linux-x86_64 +ctypes.test.test_buffers.StringBufferTestCase.test_create_unicode_buffer_non_bmp @ linux-x86_64 +ctypes.test.test_bytes.BytesTest.test_c_char_p @ linux-x86_64 +ctypes.test.test_bytes.BytesTest.test_c_wchar @ linux-x86_64 +ctypes.test.test_bytes.BytesTest.test_c_wchar_p @ linux-x86_64 +ctypes.test.test_bytes.BytesTest.test_struct @ linux-x86_64 +ctypes.test.test_bytes.BytesTest.test_struct_W @ linux-x86_64 +ctypes.test.test_byteswap.Test.test_endian_double @ linux-x86_64 +ctypes.test.test_byteswap.Test.test_endian_float @ linux-x86_64 +ctypes.test.test_byteswap.Test.test_endian_int @ linux-x86_64 +ctypes.test.test_byteswap.Test.test_endian_longlong @ linux-x86_64 +ctypes.test.test_byteswap.Test.test_endian_other @ linux-x86_64 +ctypes.test.test_byteswap.Test.test_endian_short @ linux-x86_64 +ctypes.test.test_byteswap.Test.test_slots @ linux-x86_64 +ctypes.test.test_byteswap.Test.test_struct_field_alignment @ linux-x86_64 +ctypes.test.test_byteswap.Test.test_struct_fields_unsupported_byte_order @ linux-x86_64 +ctypes.test.test_byteswap.Test.test_unaligned_native_struct_fields @ linux-x86_64 +ctypes.test.test_byteswap.Test.test_unaligned_nonnative_struct_fields @ linux-x86_64 +ctypes.test.test_byteswap.Test.test_union_fields_unsupported_byte_order @ linux-x86_64 +ctypes.test.test_callbacks.Callbacks.test_issue12483 @ linux-x86_64 +ctypes.test.test_callbacks.Callbacks.test_unsupported_restype_1 @ linux-x86_64 +ctypes.test.test_callbacks.Callbacks.test_unsupported_restype_2 @ linux-x86_64 +ctypes.test.test_callbacks.SampleCallbacksTestCase.test_callback_register_double @ linux-x86_64 +ctypes.test.test_callbacks.SampleCallbacksTestCase.test_callback_register_int @ linux-x86_64 +ctypes.test.test_callbacks.SampleCallbacksTestCase.test_integrate @ linux-x86_64 +ctypes.test.test_callbacks.SampleCallbacksTestCase.test_issue_8959_a @ linux-x86_64 +ctypes.test.test_cast.Test.test_address2pointer @ linux-x86_64 +ctypes.test.test_cast.Test.test_array2pointer @ linux-x86_64 +ctypes.test.test_cast.Test.test_bad_type_arg @ linux-x86_64 +ctypes.test.test_cast.Test.test_char_p @ linux-x86_64 +ctypes.test.test_cast.Test.test_other @ linux-x86_64 +ctypes.test.test_cast.Test.test_p2a_objects @ linux-x86_64 +ctypes.test.test_cast.Test.test_wchar_p @ linux-x86_64 +ctypes.test.test_delattr.TestCase.test_chararray @ linux-x86_64 +ctypes.test.test_delattr.TestCase.test_simple @ linux-x86_64 +ctypes.test.test_delattr.TestCase.test_struct @ linux-x86_64 +ctypes.test.test_find.FindLibraryLinux.test_find_library_with_gcc @ linux-x86_64 +ctypes.test.test_find.FindLibraryLinux.test_find_library_with_ld @ linux-x86_64 +ctypes.test.test_find.FindLibraryLinux.test_find_on_libpath @ linux-x86_64 +ctypes.test.test_find.Test_OpenGL_libs.test_gl @ linux-x86_64 +ctypes.test.test_find.Test_OpenGL_libs.test_shell_injection @ linux-x86_64 +ctypes.test.test_frombuffer.Test.test_abstract @ linux-x86_64 +ctypes.test.test_frombuffer.Test.test_fortran_contiguous @ linux-x86_64 +ctypes.test.test_frombuffer.Test.test_from_buffer_copy @ linux-x86_64 +ctypes.test.test_frombuffer.Test.test_from_buffer_copy_with_offset @ linux-x86_64 +ctypes.test.test_frombuffer.Test.test_from_buffer_memoryview @ linux-x86_64 +ctypes.test.test_frombuffer.Test.test_from_buffer_with_offset @ linux-x86_64 +ctypes.test.test_funcptr.CFuncPtrTestCase.test_abstract @ linux-x86_64 +ctypes.test.test_funcptr.CFuncPtrTestCase.test_basic @ linux-x86_64 +ctypes.test.test_funcptr.CFuncPtrTestCase.test_dllfunctions @ linux-x86_64 +ctypes.test.test_functions.FunctionTestCase.test_callbacks @ linux-x86_64 +ctypes.test.test_functions.FunctionTestCase.test_callbacks_2 @ linux-x86_64 +ctypes.test.test_functions.FunctionTestCase.test_doubleresult @ linux-x86_64 +ctypes.test.test_functions.FunctionTestCase.test_errors @ linux-x86_64 +ctypes.test.test_functions.FunctionTestCase.test_floatresult @ linux-x86_64 +ctypes.test.test_functions.FunctionTestCase.test_intresult @ linux-x86_64 +ctypes.test.test_functions.FunctionTestCase.test_longlong_callbacks @ linux-x86_64 +ctypes.test.test_functions.FunctionTestCase.test_longlongresult @ linux-x86_64 +ctypes.test.test_functions.FunctionTestCase.test_mro @ linux-x86_64 +ctypes.test.test_functions.FunctionTestCase.test_pointers @ linux-x86_64 +ctypes.test.test_functions.FunctionTestCase.test_shorts @ linux-x86_64 +ctypes.test.test_functions.FunctionTestCase.test_stringresult @ linux-x86_64 +ctypes.test.test_functions.FunctionTestCase.test_wchar_parm @ linux-x86_64 +ctypes.test.test_functions.FunctionTestCase.test_wchar_result @ linux-x86_64 +ctypes.test.test_init.InitTest.test_get @ linux-x86_64 +ctypes.test.test_internals.ObjectsTestCase.test_embedded_structs @ linux-x86_64 +ctypes.test.test_internals.ObjectsTestCase.test_ints @ linux-x86_64 +ctypes.test.test_internals.ObjectsTestCase.test_ptr_struct @ linux-x86_64 +ctypes.test.test_internals.ObjectsTestCase.test_simple_struct @ linux-x86_64 +ctypes.test.test_internals.ObjectsTestCase.test_xxx @ linux-x86_64 +ctypes.test.test_keeprefs.ArrayTestCase.test_cint_array @ linux-x86_64 +ctypes.test.test_keeprefs.PointerTestCase.test_p_cint @ linux-x86_64 +ctypes.test.test_keeprefs.SimpleTestCase.test_ccharp @ linux-x86_64 +ctypes.test.test_keeprefs.SimpleTestCase.test_cint @ linux-x86_64 +ctypes.test.test_keeprefs.StructureTestCase.test_ccharp_struct @ linux-x86_64 +ctypes.test.test_keeprefs.StructureTestCase.test_cint_struct @ linux-x86_64 +ctypes.test.test_keeprefs.StructureTestCase.test_struct_struct @ linux-x86_64 +ctypes.test.test_libc.LibTest.test_qsort @ linux-x86_64 +ctypes.test.test_libc.LibTest.test_sqrt @ linux-x86_64 +ctypes.test.test_loading.LoaderTest.test_find @ linux-x86_64 +ctypes.test.test_loading.LoaderTest.test_load @ linux-x86_64 +ctypes.test.test_loading.LoaderTest.test_load_version @ linux-x86_64 +ctypes.test.test_memfunctions.MemFunctionsTest.test_cast @ linux-x86_64 +ctypes.test.test_memfunctions.MemFunctionsTest.test_memmove @ linux-x86_64 +ctypes.test.test_memfunctions.MemFunctionsTest.test_memset @ linux-x86_64 +ctypes.test.test_memfunctions.MemFunctionsTest.test_wstring_at @ linux-x86_64 +ctypes.test.test_numbers.NumberTestCase.test_bool_values @ linux-x86_64 +ctypes.test.test_numbers.NumberTestCase.test_byref @ linux-x86_64 +ctypes.test.test_numbers.NumberTestCase.test_char_from_address @ linux-x86_64 +ctypes.test.test_numbers.NumberTestCase.test_default_init @ linux-x86_64 +ctypes.test.test_numbers.NumberTestCase.test_float_from_address @ linux-x86_64 +ctypes.test.test_numbers.NumberTestCase.test_float_overflow @ linux-x86_64 +ctypes.test.test_numbers.NumberTestCase.test_floats @ linux-x86_64 +ctypes.test.test_numbers.NumberTestCase.test_from_param @ linux-x86_64 +ctypes.test.test_numbers.NumberTestCase.test_init @ linux-x86_64 +ctypes.test.test_numbers.NumberTestCase.test_int_from_address @ linux-x86_64 +ctypes.test.test_numbers.NumberTestCase.test_integers @ linux-x86_64 +ctypes.test.test_numbers.NumberTestCase.test_signed_values @ linux-x86_64 +ctypes.test.test_numbers.NumberTestCase.test_sizes @ linux-x86_64 +ctypes.test.test_numbers.NumberTestCase.test_typeerror @ linux-x86_64 +ctypes.test.test_objects.TestCase.test @ linux-x86_64 +ctypes.test.test_parameters.SimpleTypesTestCase.test_abstract @ linux-x86_64 +ctypes.test.test_parameters.SimpleTypesTestCase.test_array_pointers @ linux-x86_64 +ctypes.test.test_parameters.SimpleTypesTestCase.test_byref_pointer @ linux-x86_64 +ctypes.test.test_parameters.SimpleTypesTestCase.test_byref_pointerpointer @ linux-x86_64 +ctypes.test.test_parameters.SimpleTypesTestCase.test_cstrings @ linux-x86_64 +ctypes.test.test_parameters.SimpleTypesTestCase.test_cw_strings @ linux-x86_64 +ctypes.test.test_parameters.SimpleTypesTestCase.test_int_pointers @ linux-x86_64 +ctypes.test.test_parameters.SimpleTypesTestCase.test_subclasses @ linux-x86_64 +ctypes.test.test_parameters.SimpleTypesTestCase.test_subclasses_c_wchar_p @ linux-x86_64 +ctypes.test.test_pickling.PickleTest_0.test_unpickable @ linux-x86_64 +ctypes.test.test_pickling.PickleTest_0.test_wchar @ linux-x86_64 +ctypes.test.test_pickling.PickleTest_1.test_unpickable @ linux-x86_64 +ctypes.test.test_pickling.PickleTest_1.test_wchar @ linux-x86_64 +ctypes.test.test_pickling.PickleTest_2.test_unpickable @ linux-x86_64 +ctypes.test.test_pickling.PickleTest_2.test_wchar @ linux-x86_64 +ctypes.test.test_pickling.PickleTest_3.test_unpickable @ linux-x86_64 +ctypes.test.test_pickling.PickleTest_3.test_wchar @ linux-x86_64 +ctypes.test.test_pickling.PickleTest_4.test_unpickable @ linux-x86_64 +ctypes.test.test_pickling.PickleTest_4.test_wchar @ linux-x86_64 +ctypes.test.test_pickling.PickleTest_5.test_unpickable @ linux-x86_64 +ctypes.test.test_pickling.PickleTest_5.test_wchar @ linux-x86_64 +ctypes.test.test_pointers.PointersTestCase.test_abstract @ linux-x86_64 +ctypes.test.test_pointers.PointersTestCase.test_basic @ linux-x86_64 +ctypes.test.test_pointers.PointersTestCase.test_basics @ linux-x86_64 +ctypes.test.test_pointers.PointersTestCase.test_bug_1467852 @ linux-x86_64 +ctypes.test.test_pointers.PointersTestCase.test_callbacks_with_pointers @ linux-x86_64 +ctypes.test.test_pointers.PointersTestCase.test_change_pointers @ linux-x86_64 +ctypes.test.test_pointers.PointersTestCase.test_charpp @ linux-x86_64 +ctypes.test.test_pointers.PointersTestCase.test_from_address @ linux-x86_64 +ctypes.test.test_pointers.PointersTestCase.test_pass_pointers @ linux-x86_64 +ctypes.test.test_pointers.PointersTestCase.test_pointer_crash @ linux-x86_64 +ctypes.test.test_pointers.PointersTestCase.test_pointer_type_name @ linux-x86_64 +ctypes.test.test_prototypes.ArrayTest.test @ linux-x86_64 +ctypes.test.test_prototypes.CharPointersTestCase.test_POINTER_c_char_arg @ linux-x86_64 +ctypes.test.test_prototypes.CharPointersTestCase.test_c_char_p_arg @ linux-x86_64 +ctypes.test.test_prototypes.CharPointersTestCase.test_c_void_p_arg @ linux-x86_64 +ctypes.test.test_prototypes.CharPointersTestCase.test_c_void_p_arg_with_c_wchar_p @ linux-x86_64 +ctypes.test.test_prototypes.WCharPointersTestCase.test_POINTER_c_wchar_arg @ linux-x86_64 +ctypes.test.test_prototypes.WCharPointersTestCase.test_c_wchar_p_arg @ linux-x86_64 +ctypes.test.test_python_api.PythonAPITestCase.test_PyBytes_FromStringAndSize @ linux-x86_64 +!ctypes.test.test_python_api.PythonAPITestCase.test_PyOS_snprintf @ linux-x86_64 +ctypes.test.test_returnfuncptrs.ReturnFuncPtrTestCase.test_from_dll @ linux-x86_64 +ctypes.test.test_returnfuncptrs.ReturnFuncPtrTestCase.test_from_dll_refcount @ linux-x86_64 +ctypes.test.test_simplesubclasses.Test.test_compare @ linux-x86_64 +ctypes.test.test_simplesubclasses.Test.test_int_struct @ linux-x86_64 +ctypes.test.test_sizes.SizesTestCase.test_16 @ linux-x86_64 +ctypes.test.test_sizes.SizesTestCase.test_32 @ linux-x86_64 +ctypes.test.test_sizes.SizesTestCase.test_64 @ linux-x86_64 +ctypes.test.test_sizes.SizesTestCase.test_8 @ linux-x86_64 +ctypes.test.test_sizes.SizesTestCase.test_size_t @ linux-x86_64 +ctypes.test.test_sizes.SizesTestCase.test_ssize_t @ linux-x86_64 +ctypes.test.test_slicing.SlicesTestCase.test_char_array @ linux-x86_64 +ctypes.test.test_slicing.SlicesTestCase.test_getslice_cint @ linux-x86_64 +ctypes.test.test_slicing.SlicesTestCase.test_setslice_cint @ linux-x86_64 +ctypes.test.test_stringptr.StringPtrTestCase.test__c_char_p @ linux-x86_64 +ctypes.test.test_stringptr.StringPtrTestCase.test_functions @ linux-x86_64 +ctypes.test.test_strings.StringArrayTestCase.test_c_buffer_raw @ linux-x86_64 +ctypes.test.test_strings.StringArrayTestCase.test_c_buffer_value @ linux-x86_64 +ctypes.test.test_strings.StringArrayTestCase.test_param_1 @ linux-x86_64 +ctypes.test.test_strings.StringArrayTestCase.test_param_2 @ linux-x86_64 +ctypes.test.test_strings.WStringArrayTestCase.test_nonbmp @ linux-x86_64 +ctypes.test.test_strings.WStringTestCase.test_wchar @ linux-x86_64 +ctypes.test.test_struct_fields.StructFieldsTestCase.test_1_A @ linux-x86_64 +ctypes.test.test_struct_fields.StructFieldsTestCase.test_1_B @ linux-x86_64 +ctypes.test.test_struct_fields.StructFieldsTestCase.test_2 @ linux-x86_64 +ctypes.test.test_struct_fields.StructFieldsTestCase.test_3 @ linux-x86_64 +ctypes.test.test_struct_fields.StructFieldsTestCase.test_4 @ linux-x86_64 +ctypes.test.test_struct_fields.StructFieldsTestCase.test___get__ @ linux-x86_64 +ctypes.test.test_struct_fields.StructFieldsTestCase.test___set__ @ linux-x86_64 +ctypes.test.test_structures.PointerMemberTestCase.test @ linux-x86_64 +ctypes.test.test_structures.PointerMemberTestCase.test_none_to_pointer_fields @ linux-x86_64 +ctypes.test.test_structures.StructureTestCase.test_38368 @ linux-x86_64 +ctypes.test.test_structures.StructureTestCase.test_abstract_class @ linux-x86_64 +ctypes.test.test_structures.StructureTestCase.test_conflicting_initializers @ linux-x86_64 +ctypes.test.test_structures.StructureTestCase.test_empty @ linux-x86_64 +ctypes.test.test_structures.StructureTestCase.test_fields @ linux-x86_64 +ctypes.test.test_structures.StructureTestCase.test_huge_field_name @ linux-x86_64 +ctypes.test.test_structures.StructureTestCase.test_initializers @ linux-x86_64 +ctypes.test.test_structures.StructureTestCase.test_invalid_field_types @ linux-x86_64 +ctypes.test.test_structures.StructureTestCase.test_invalid_name @ linux-x86_64 +ctypes.test.test_structures.StructureTestCase.test_keyword_initializers @ linux-x86_64 +ctypes.test.test_structures.StructureTestCase.test_methods @ linux-x86_64 +ctypes.test.test_structures.StructureTestCase.test_struct_alignment @ linux-x86_64 +ctypes.test.test_structures.StructureTestCase.test_structures_with_wchar @ linux-x86_64 +ctypes.test.test_structures.StructureTestCase.test_unions @ linux-x86_64 +ctypes.test.test_structures.TestRecursiveStructure.test_contains_itself @ linux-x86_64 +ctypes.test.test_structures.TestRecursiveStructure.test_vice_versa @ linux-x86_64 +ctypes.test.test_unaligned_structures.TestStructures.test_native @ linux-x86_64 +ctypes.test.test_unaligned_structures.TestStructures.test_swapped @ linux-x86_64 +ctypes.test.test_unicode.StringTestCase.test_buffers @ linux-x86_64 +ctypes.test.test_unicode.StringTestCase.test_embedded_null @ linux-x86_64 +ctypes.test.test_unicode.StringTestCase.test_func @ linux-x86_64 +ctypes.test.test_unicode.StringTestCase.test_wcslen @ linux-x86_64 +ctypes.test.test_unicode.UnicodeTestCase.test_embedded_null @ linux-x86_64 +ctypes.test.test_unicode.UnicodeTestCase.test_wcslen @ linux-x86_64 +ctypes.test.test_values.PythonValuesTestCase.test_undefined @ linux-x86_64 +ctypes.test.test_values.ValuesTestCase.test_undefined @ linux-x86_64 +ctypes.test.test_varsize_struct.VarSizeTest.test_array_invalid_length @ linux-x86_64 +ctypes.test.test_varsize_struct.VarSizeTest.test_zerosized_array @ linux-x86_64 +ctypes.test.test_wintypes.WinTypesTest.test_variant_bool @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dataclasses.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dataclasses.txt new file mode 100644 index 0000000000..7fe7338fcf --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dataclasses.txt @@ -0,0 +1,211 @@ +test.test_dataclasses.TestAbstract.test_abc_implementation @ linux-x86_64 +test.test_dataclasses.TestAbstract.test_maintain_abc @ linux-x86_64 +test.test_dataclasses.TestCase.test_0_field_compare @ linux-x86_64 +test.test_dataclasses.TestCase.test_1_field_compare @ linux-x86_64 +test.test_dataclasses.TestCase.test_alternate_classmethod_constructor @ linux-x86_64 +test.test_dataclasses.TestCase.test_class_attrs @ linux-x86_64 +test.test_dataclasses.TestCase.test_class_marker @ linux-x86_64 +test.test_dataclasses.TestCase.test_class_var @ linux-x86_64 +test.test_dataclasses.TestCase.test_class_var_default_factory @ linux-x86_64 +test.test_dataclasses.TestCase.test_class_var_frozen @ linux-x86_64 +test.test_dataclasses.TestCase.test_class_var_no_default @ linux-x86_64 +test.test_dataclasses.TestCase.test_class_var_with_default @ linux-x86_64 +test.test_dataclasses.TestCase.test_classvar_default_factory @ linux-x86_64 +test.test_dataclasses.TestCase.test_clean_traceback_from_fields_exception @ linux-x86_64 +test.test_dataclasses.TestCase.test_compare_subclasses @ linux-x86_64 +test.test_dataclasses.TestCase.test_dataclasses_pickleable @ linux-x86_64 +test.test_dataclasses.TestCase.test_dataclasses_qualnames @ linux-x86_64 +test.test_dataclasses.TestCase.test_default_factory @ linux-x86_64 +test.test_dataclasses.TestCase.test_default_factory_derived @ linux-x86_64 +test.test_dataclasses.TestCase.test_default_factory_not_called_if_value_given @ linux-x86_64 +test.test_dataclasses.TestCase.test_default_factory_with_no_init @ linux-x86_64 +test.test_dataclasses.TestCase.test_deliberately_mutable_defaults @ linux-x86_64 +test.test_dataclasses.TestCase.test_disallowed_mutable_defaults @ linux-x86_64 +test.test_dataclasses.TestCase.test_dont_include_other_annotations @ linux-x86_64 +test.test_dataclasses.TestCase.test_dynamic_class_creation @ linux-x86_64 +test.test_dataclasses.TestCase.test_dynamic_class_creation_using_field @ linux-x86_64 +test.test_dataclasses.TestCase.test_eq_order @ linux-x86_64 +test.test_dataclasses.TestCase.test_field_default @ linux-x86_64 +test.test_dataclasses.TestCase.test_field_default_default_factory_error @ linux-x86_64 +test.test_dataclasses.TestCase.test_field_metadata_custom_mapping @ linux-x86_64 +test.test_dataclasses.TestCase.test_field_metadata_default @ linux-x86_64 +test.test_dataclasses.TestCase.test_field_metadata_mapping @ linux-x86_64 +test.test_dataclasses.TestCase.test_field_named_BUILTINS_frozen @ linux-x86_64 +test.test_dataclasses.TestCase.test_field_named_like_builtin @ linux-x86_64 +test.test_dataclasses.TestCase.test_field_named_like_builtin_frozen @ linux-x86_64 +test.test_dataclasses.TestCase.test_field_named_object @ linux-x86_64 +test.test_dataclasses.TestCase.test_field_named_object_frozen @ linux-x86_64 +test.test_dataclasses.TestCase.test_field_named_self @ linux-x86_64 +test.test_dataclasses.TestCase.test_field_no_default @ linux-x86_64 +test.test_dataclasses.TestCase.test_field_order @ linux-x86_64 +test.test_dataclasses.TestCase.test_field_recursive_repr @ linux-x86_64 +test.test_dataclasses.TestCase.test_field_repr @ linux-x86_64 +test.test_dataclasses.TestCase.test_function_annotations @ linux-x86_64 +test.test_dataclasses.TestCase.test_generic_dataclasses @ linux-x86_64 +test.test_dataclasses.TestCase.test_generic_dynamic @ linux-x86_64 +test.test_dataclasses.TestCase.test_generic_extending @ linux-x86_64 +test.test_dataclasses.TestCase.test_hash_field_rules @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_asdict @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_asdict_builtin_containers @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_asdict_builtin_object_containers @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_asdict_copy_values @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_asdict_factory @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_asdict_namedtuple @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_asdict_namedtuple_derived @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_asdict_namedtuple_key @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_asdict_nested @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_asdict_raises_on_classes @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_astuple @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_astuple_builtin_containers @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_astuple_builtin_object_containers @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_astuple_copy_values @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_astuple_factory @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_astuple_namedtuple @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_astuple_nested @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_astuple_raises_on_classes @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_fields_exception @ linux-x86_64 +test.test_dataclasses.TestCase.test_helper_fields_with_class_instance @ linux-x86_64 +test.test_dataclasses.TestCase.test_init_false_no_default @ linux-x86_64 +test.test_dataclasses.TestCase.test_init_in_order @ linux-x86_64 +test.test_dataclasses.TestCase.test_init_var @ linux-x86_64 +test.test_dataclasses.TestCase.test_init_var_default_factory @ linux-x86_64 +test.test_dataclasses.TestCase.test_init_var_inheritance @ linux-x86_64 +test.test_dataclasses.TestCase.test_init_var_no_default @ linux-x86_64 +test.test_dataclasses.TestCase.test_init_var_preserve_type @ linux-x86_64 +test.test_dataclasses.TestCase.test_init_var_with_default @ linux-x86_64 +test.test_dataclasses.TestCase.test_intermediate_non_dataclass @ linux-x86_64 +test.test_dataclasses.TestCase.test_is_dataclass @ linux-x86_64 +test.test_dataclasses.TestCase.test_is_dataclass_genericalias @ linux-x86_64 +test.test_dataclasses.TestCase.test_is_dataclass_when_getattr_always_returns @ linux-x86_64 +test.test_dataclasses.TestCase.test_items_in_dicts @ linux-x86_64 +test.test_dataclasses.TestCase.test_missing_default @ linux-x86_64 +test.test_dataclasses.TestCase.test_missing_default_factory @ linux-x86_64 +test.test_dataclasses.TestCase.test_missing_repr @ linux-x86_64 +test.test_dataclasses.TestCase.test_named_init_params @ linux-x86_64 +test.test_dataclasses.TestCase.test_no_fields @ linux-x86_64 +test.test_dataclasses.TestCase.test_no_fields_but_member_variable @ linux-x86_64 +test.test_dataclasses.TestCase.test_no_options @ linux-x86_64 +test.test_dataclasses.TestCase.test_no_unhashable_default @ linux-x86_64 +test.test_dataclasses.TestCase.test_not_in_compare @ linux-x86_64 +test.test_dataclasses.TestCase.test_not_in_repr @ linux-x86_64 +test.test_dataclasses.TestCase.test_not_other_dataclass @ linux-x86_64 +test.test_dataclasses.TestCase.test_not_tuple @ linux-x86_64 +test.test_dataclasses.TestCase.test_one_field_no_default @ linux-x86_64 +test.test_dataclasses.TestCase.test_overwrite_fields_in_derived_class @ linux-x86_64 +test.test_dataclasses.TestCase.test_overwrite_hash @ linux-x86_64 +test.test_dataclasses.TestCase.test_post_init @ linux-x86_64 +test.test_dataclasses.TestCase.test_post_init_classmethod @ linux-x86_64 +test.test_dataclasses.TestCase.test_post_init_not_auto_added @ linux-x86_64 +test.test_dataclasses.TestCase.test_post_init_staticmethod @ linux-x86_64 +test.test_dataclasses.TestCase.test_post_init_super @ linux-x86_64 +test.test_dataclasses.TestCase.test_recursive_annotation @ linux-x86_64 +test.test_dataclasses.TestCase.test_simple_compare @ linux-x86_64 +test.test_dataclasses.TestCase.test_two_fields_one_default @ linux-x86_64 +test.test_dataclasses.TestDescriptors.test_default_value @ linux-x86_64 +test.test_dataclasses.TestDescriptors.test_getting_field_calls_get @ linux-x86_64 +test.test_dataclasses.TestDescriptors.test_init_calls_set @ linux-x86_64 +test.test_dataclasses.TestDescriptors.test_lookup_on_class @ linux-x86_64 +test.test_dataclasses.TestDescriptors.test_lookup_on_instance @ linux-x86_64 +test.test_dataclasses.TestDescriptors.test_no_default_value @ linux-x86_64 +test.test_dataclasses.TestDescriptors.test_non_descriptor @ linux-x86_64 +test.test_dataclasses.TestDescriptors.test_set_name @ linux-x86_64 +test.test_dataclasses.TestDescriptors.test_setting_field_calls_set @ linux-x86_64 +test.test_dataclasses.TestDescriptors.test_setting_uninitialized_descriptor_field @ linux-x86_64 +test.test_dataclasses.TestDocString.test_docstring_list_field @ linux-x86_64 +test.test_dataclasses.TestDocString.test_docstring_list_field_with_default_factory @ linux-x86_64 +test.test_dataclasses.TestDocString.test_docstring_no_fields @ linux-x86_64 +test.test_dataclasses.TestDocString.test_docstring_one_field @ linux-x86_64 +test.test_dataclasses.TestDocString.test_docstring_one_field_with_default @ linux-x86_64 +test.test_dataclasses.TestDocString.test_docstring_one_field_with_default_none @ linux-x86_64 +test.test_dataclasses.TestDocString.test_docstring_three_fields @ linux-x86_64 +test.test_dataclasses.TestDocString.test_docstring_two_fields @ linux-x86_64 +test.test_dataclasses.TestDocString.test_existing_docstring_not_overridden @ linux-x86_64 +test.test_dataclasses.TestEq.test_no_eq @ linux-x86_64 +test.test_dataclasses.TestEq.test_overwriting_eq @ linux-x86_64 +test.test_dataclasses.TestFieldNoAnnotation.test_field_without_annotation @ linux-x86_64 +test.test_dataclasses.TestFieldNoAnnotation.test_field_without_annotation_but_annotation_in_base @ linux-x86_64 +test.test_dataclasses.TestFieldNoAnnotation.test_field_without_annotation_but_annotation_in_base_not_dataclass @ linux-x86_64 +test.test_dataclasses.TestFrozen.test_frozen @ linux-x86_64 +test.test_dataclasses.TestFrozen.test_frozen_hash @ linux-x86_64 +test.test_dataclasses.TestFrozen.test_inherit @ linux-x86_64 +test.test_dataclasses.TestFrozen.test_inherit_from_normal_class @ linux-x86_64 +test.test_dataclasses.TestFrozen.test_inherit_frozen_from_nonfrozen @ linux-x86_64 +test.test_dataclasses.TestFrozen.test_inherit_nonfrozen_from_empty @ linux-x86_64 +test.test_dataclasses.TestFrozen.test_inherit_nonfrozen_from_empty_frozen @ linux-x86_64 +test.test_dataclasses.TestFrozen.test_inherit_nonfrozen_from_frozen @ linux-x86_64 +test.test_dataclasses.TestFrozen.test_non_frozen_normal_derived @ linux-x86_64 +test.test_dataclasses.TestFrozen.test_overwriting_frozen @ linux-x86_64 +test.test_dataclasses.TestHash.test_0_field_hash @ linux-x86_64 +test.test_dataclasses.TestHash.test_1_field_hash @ linux-x86_64 +test.test_dataclasses.TestHash.test_eq_only @ linux-x86_64 +test.test_dataclasses.TestHash.test_hash_no_args @ linux-x86_64 +test.test_dataclasses.TestHash.test_hash_rules @ linux-x86_64 +test.test_dataclasses.TestHash.test_unsafe_hash @ linux-x86_64 +test.test_dataclasses.TestInit.test_base_has_init @ linux-x86_64 +test.test_dataclasses.TestInit.test_inherit_from_protocol @ linux-x86_64 +test.test_dataclasses.TestInit.test_no_init @ linux-x86_64 +test.test_dataclasses.TestInit.test_overwriting_init @ linux-x86_64 +test.test_dataclasses.TestKeywordArgs.test_KW_ONLY @ linux-x86_64 +test.test_dataclasses.TestKeywordArgs.test_KW_ONLY_as_string @ linux-x86_64 +test.test_dataclasses.TestKeywordArgs.test_KW_ONLY_twice @ linux-x86_64 +test.test_dataclasses.TestKeywordArgs.test_defaults @ linux-x86_64 +test.test_dataclasses.TestKeywordArgs.test_field_marked_as_kwonly @ linux-x86_64 +test.test_dataclasses.TestKeywordArgs.test_make_dataclass @ linux-x86_64 +test.test_dataclasses.TestKeywordArgs.test_match_args @ linux-x86_64 +test.test_dataclasses.TestKeywordArgs.test_no_classvar_kwarg @ linux-x86_64 +test.test_dataclasses.TestKeywordArgs.test_post_init @ linux-x86_64 +test.test_dataclasses.TestMakeDataclass.test_base @ linux-x86_64 +test.test_dataclasses.TestMakeDataclass.test_base_dataclass @ linux-x86_64 +test.test_dataclasses.TestMakeDataclass.test_class_var @ linux-x86_64 +test.test_dataclasses.TestMakeDataclass.test_duplicate_field_names @ linux-x86_64 +test.test_dataclasses.TestMakeDataclass.test_funny_class_names_names @ linux-x86_64 +test.test_dataclasses.TestMakeDataclass.test_init_var @ linux-x86_64 +test.test_dataclasses.TestMakeDataclass.test_invalid_type_specification @ linux-x86_64 +test.test_dataclasses.TestMakeDataclass.test_keyword_field_names @ linux-x86_64 +test.test_dataclasses.TestMakeDataclass.test_no_mutate_namespace @ linux-x86_64 +test.test_dataclasses.TestMakeDataclass.test_no_types @ linux-x86_64 +test.test_dataclasses.TestMakeDataclass.test_non_identifier_field_names @ linux-x86_64 +test.test_dataclasses.TestMakeDataclass.test_other_params @ linux-x86_64 +test.test_dataclasses.TestMakeDataclass.test_simple @ linux-x86_64 +test.test_dataclasses.TestMakeDataclass.test_underscore_field_names @ linux-x86_64 +test.test_dataclasses.TestMatchArgs.test_bpo_43764 @ linux-x86_64 +test.test_dataclasses.TestMatchArgs.test_explicit_match_args @ linux-x86_64 +test.test_dataclasses.TestMatchArgs.test_make_dataclasses @ linux-x86_64 +test.test_dataclasses.TestMatchArgs.test_match_args @ linux-x86_64 +test.test_dataclasses.TestMatchArgs.test_match_args_argument @ linux-x86_64 +test.test_dataclasses.TestOrdering.test_functools_total_ordering @ linux-x86_64 +test.test_dataclasses.TestOrdering.test_no_order @ linux-x86_64 +test.test_dataclasses.TestOrdering.test_overwriting_order @ linux-x86_64 +test.test_dataclasses.TestReplace.test @ linux-x86_64 +test.test_dataclasses.TestReplace.test_classvar @ linux-x86_64 +test.test_dataclasses.TestReplace.test_frozen @ linux-x86_64 +test.test_dataclasses.TestReplace.test_initvar_is_specified @ linux-x86_64 +test.test_dataclasses.TestReplace.test_initvar_with_default_value @ linux-x86_64 +test.test_dataclasses.TestReplace.test_invalid_field_name @ linux-x86_64 +test.test_dataclasses.TestReplace.test_invalid_object @ linux-x86_64 +test.test_dataclasses.TestReplace.test_no_init @ linux-x86_64 +test.test_dataclasses.TestReplace.test_recursive_repr @ linux-x86_64 +test.test_dataclasses.TestReplace.test_recursive_repr_indirection @ linux-x86_64 +test.test_dataclasses.TestReplace.test_recursive_repr_indirection_two @ linux-x86_64 +test.test_dataclasses.TestReplace.test_recursive_repr_misc_attrs @ linux-x86_64 +test.test_dataclasses.TestReplace.test_recursive_repr_two_attrs @ linux-x86_64 +test.test_dataclasses.TestRepr.test_no_repr @ linux-x86_64 +test.test_dataclasses.TestRepr.test_overwriting_repr @ linux-x86_64 +test.test_dataclasses.TestRepr.test_repr @ linux-x86_64 +test.test_dataclasses.TestSlots.test_add_slots_when_slots_exists @ linux-x86_64 +test.test_dataclasses.TestSlots.test_derived_added_field @ linux-x86_64 +test.test_dataclasses.TestSlots.test_frozen_pickle @ linux-x86_64 +test.test_dataclasses.TestSlots.test_frozen_slots_pickle_custom_state @ linux-x86_64 +test.test_dataclasses.TestSlots.test_generated_slots @ linux-x86_64 +test.test_dataclasses.TestSlots.test_returns_new_class @ linux-x86_64 +test.test_dataclasses.TestSlots.test_simple @ linux-x86_64 +test.test_dataclasses.TestSlots.test_slots_with_default_factory_no_init @ linux-x86_64 +test.test_dataclasses.TestSlots.test_slots_with_default_no_init @ linux-x86_64 +test.test_dataclasses.TestSlots.test_weakref_slot_make_dataclass @ linux-x86_64 +test.test_dataclasses.TestSlots.test_weakref_slot_without_slot @ linux-x86_64 +test.test_dataclasses.TestStringAnnotations.test_classvar @ linux-x86_64 +test.test_dataclasses.TestStringAnnotations.test_classvar_module_level_import @ linux-x86_64 +test.test_dataclasses.TestStringAnnotations.test_initvar @ linux-x86_64 +test.test_dataclasses.TestStringAnnotations.test_isnt_classvar @ linux-x86_64 +test.test_dataclasses.TestStringAnnotations.test_isnt_initvar @ linux-x86_64 +test.test_dataclasses.TestStringAnnotations.test_text_annotations @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dbm.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dbm.txt new file mode 100644 index 0000000000..c60e90da92 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dbm.txt @@ -0,0 +1,14 @@ +test.test_dbm.TestCase_dumb.test_anydbm_access @ linux-x86_64 +test.test_dbm.TestCase_dumb.test_anydbm_creation @ linux-x86_64 +test.test_dbm.TestCase_dumb.test_anydbm_creation_n_file_exists_with_invalid_contents @ linux-x86_64 +test.test_dbm.TestCase_dumb.test_anydbm_keys @ linux-x86_64 +test.test_dbm.TestCase_dumb.test_anydbm_modification @ linux-x86_64 +test.test_dbm.TestCase_dumb.test_anydbm_not_existing @ linux-x86_64 +test.test_dbm.TestCase_dumb.test_anydbm_read @ linux-x86_64 +test.test_dbm.TestCase_dumb.test_empty_value @ linux-x86_64 +test.test_dbm.TestCase_dumb.test_error @ linux-x86_64 +test.test_dbm.TestCase_dumb.test_keys @ linux-x86_64 +test.test_dbm.TestCase_dumb.test_open_with_bytes @ linux-x86_64 +test.test_dbm.TestCase_dumb.test_open_with_pathlib_path @ linux-x86_64 +test.test_dbm.TestCase_dumb.test_open_with_pathlib_path_bytes @ linux-x86_64 +test.test_dbm.WhichDBTestCase.test_whichdb @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dbm_dumb.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dbm_dumb.txt new file mode 100644 index 0000000000..8cb718bcaf --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dbm_dumb.txt @@ -0,0 +1,24 @@ +test.test_dbm_dumb.DumbDBMTestCase.test_check_closed @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_close_twice @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_context_manager @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_create_new @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_dumbdbm_creation @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_dumbdbm_creation_mode @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_dumbdbm_keys @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_dumbdbm_modification @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_dumbdbm_read @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_eval @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_invalid_flag @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_line_endings @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_missing_data @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_missing_index @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_nonascii_filename @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_open_with_bytes_path @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_open_with_pathlib_bytes_path @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_open_with_pathlib_path @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_random @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_readonly_files @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_str_read @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_str_write_contains @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_write_contains @ linux-x86_64 +test.test_dbm_dumb.DumbDBMTestCase.test_write_write_read @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_decimal.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_decimal.txt new file mode 100644 index 0000000000..8a06c4ae72 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_decimal.txt @@ -0,0 +1,372 @@ +DocTestCase.decimal @ linux-x86_64 +DocTestCase.decimal.Context.abs @ linux-x86_64 +DocTestCase.decimal.Context.add @ linux-x86_64 +DocTestCase.decimal.Context.canonical @ linux-x86_64 +DocTestCase.decimal.Context.compare @ linux-x86_64 +DocTestCase.decimal.Context.compare_signal @ linux-x86_64 +DocTestCase.decimal.Context.compare_total @ linux-x86_64 +DocTestCase.decimal.Context.copy_abs @ linux-x86_64 +DocTestCase.decimal.Context.copy_decimal @ linux-x86_64 +DocTestCase.decimal.Context.copy_negate @ linux-x86_64 +DocTestCase.decimal.Context.copy_sign @ linux-x86_64 +DocTestCase.decimal.Context.create_decimal_from_float @ linux-x86_64 +DocTestCase.decimal.Context.divide @ linux-x86_64 +DocTestCase.decimal.Context.divide_int @ linux-x86_64 +DocTestCase.decimal.Context.divmod @ linux-x86_64 +DocTestCase.decimal.Context.exp @ linux-x86_64 +DocTestCase.decimal.Context.fma @ linux-x86_64 +DocTestCase.decimal.Context.is_canonical @ linux-x86_64 +DocTestCase.decimal.Context.is_finite @ linux-x86_64 +DocTestCase.decimal.Context.is_infinite @ linux-x86_64 +DocTestCase.decimal.Context.is_nan @ linux-x86_64 +DocTestCase.decimal.Context.is_normal @ linux-x86_64 +DocTestCase.decimal.Context.is_qnan @ linux-x86_64 +DocTestCase.decimal.Context.is_signed @ linux-x86_64 +DocTestCase.decimal.Context.is_snan @ linux-x86_64 +DocTestCase.decimal.Context.is_subnormal @ linux-x86_64 +DocTestCase.decimal.Context.is_zero @ linux-x86_64 +DocTestCase.decimal.Context.ln @ linux-x86_64 +DocTestCase.decimal.Context.log10 @ linux-x86_64 +DocTestCase.decimal.Context.logb @ linux-x86_64 +DocTestCase.decimal.Context.logical_and @ linux-x86_64 +DocTestCase.decimal.Context.logical_invert @ linux-x86_64 +DocTestCase.decimal.Context.logical_or @ linux-x86_64 +DocTestCase.decimal.Context.logical_xor @ linux-x86_64 +DocTestCase.decimal.Context.max @ linux-x86_64 +DocTestCase.decimal.Context.max_mag @ linux-x86_64 +DocTestCase.decimal.Context.min @ linux-x86_64 +DocTestCase.decimal.Context.min_mag @ linux-x86_64 +DocTestCase.decimal.Context.minus @ linux-x86_64 +DocTestCase.decimal.Context.multiply @ linux-x86_64 +DocTestCase.decimal.Context.next_minus @ linux-x86_64 +DocTestCase.decimal.Context.next_plus @ linux-x86_64 +DocTestCase.decimal.Context.next_toward @ linux-x86_64 +DocTestCase.decimal.Context.normalize @ linux-x86_64 +DocTestCase.decimal.Context.number_class @ linux-x86_64 +DocTestCase.decimal.Context.plus @ linux-x86_64 +DocTestCase.decimal.Context.power @ linux-x86_64 +DocTestCase.decimal.Context.quantize @ linux-x86_64 +DocTestCase.decimal.Context.radix @ linux-x86_64 +DocTestCase.decimal.Context.remainder @ linux-x86_64 +DocTestCase.decimal.Context.remainder_near @ linux-x86_64 +DocTestCase.decimal.Context.rotate @ linux-x86_64 +DocTestCase.decimal.Context.same_quantum @ linux-x86_64 +DocTestCase.decimal.Context.scaleb @ linux-x86_64 +DocTestCase.decimal.Context.shift @ linux-x86_64 +DocTestCase.decimal.Context.sqrt @ linux-x86_64 +DocTestCase.decimal.Context.subtract @ linux-x86_64 +DocTestCase.decimal.Context.to_eng_string @ linux-x86_64 +DocTestCase.decimal.Context.to_integral_exact @ linux-x86_64 +DocTestCase.decimal.Context.to_integral_value @ linux-x86_64 +DocTestCase.decimal.Decimal.__new__ @ linux-x86_64 +DocTestCase.decimal.Decimal.__round__ @ linux-x86_64 +DocTestCase.decimal.Decimal.as_integer_ratio @ linux-x86_64 +DocTestCase.decimal.Decimal.from_float @ linux-x86_64 +DocTestCase.decimal.localcontext @ linux-x86_64 +test.test_decimal.PyArithmeticOperatorsTest.test_addition @ linux-x86_64 +test.test_decimal.PyArithmeticOperatorsTest.test_copy_sign @ linux-x86_64 +test.test_decimal.PyArithmeticOperatorsTest.test_division @ linux-x86_64 +test.test_decimal.PyArithmeticOperatorsTest.test_floor_div_module @ linux-x86_64 +test.test_decimal.PyArithmeticOperatorsTest.test_floor_division @ linux-x86_64 +test.test_decimal.PyArithmeticOperatorsTest.test_module @ linux-x86_64 +test.test_decimal.PyArithmeticOperatorsTest.test_multiplication @ linux-x86_64 +test.test_decimal.PyArithmeticOperatorsTest.test_nan_comparisons @ linux-x86_64 +test.test_decimal.PyArithmeticOperatorsTest.test_powering @ linux-x86_64 +test.test_decimal.PyArithmeticOperatorsTest.test_subtraction @ linux-x86_64 +test.test_decimal.PyArithmeticOperatorsTest.test_unary_operators @ linux-x86_64 +test.test_decimal.PyContextAPItests.test__clamp @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_abs @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_add @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_compare @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_compare_signal @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_compare_total @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_compare_total_mag @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_copy @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_copy_abs @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_copy_decimal @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_copy_negate @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_copy_sign @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_divide @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_divide_int @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_divmod @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_equality_with_other_types @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_exp @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_fma @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_is_finite @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_is_infinite @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_is_nan @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_is_normal @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_is_qnan @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_is_signed @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_is_snan @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_is_subnormal @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_is_zero @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_ln @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_log10 @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_logb @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_logical_and @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_logical_invert @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_logical_or @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_logical_xor @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_max @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_max_mag @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_min @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_min_mag @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_minus @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_multiply @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_next_minus @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_next_plus @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_next_toward @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_none_args @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_normalize @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_number_class @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_pickle @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_plus @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_power @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_quantize @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_remainder @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_remainder_near @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_rotate @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_same_quantum @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_scaleb @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_shift @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_sqrt @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_subtract @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_to_eng_string @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_to_integral_exact @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_to_integral_value @ linux-x86_64 +test.test_decimal.PyContextAPItests.test_to_sci_string @ linux-x86_64 +test.test_decimal.PyContextFlags.test_flag_comparisons @ linux-x86_64 +test.test_decimal.PyContextFlags.test_flags_irrelevant @ linux-x86_64 +test.test_decimal.PyContextFlags.test_float_comparison @ linux-x86_64 +test.test_decimal.PyContextFlags.test_float_operation @ linux-x86_64 +test.test_decimal.PyContextFlags.test_float_operation_default @ linux-x86_64 +test.test_decimal.PyContextInputValidation.test_invalid_context @ linux-x86_64 +test.test_decimal.PyContextSubclassing.test_context_subclassing @ linux-x86_64 +test.test_decimal.PyContextWithStatement.test_local_context_kwargs_does_not_overwrite_existing_argument @ linux-x86_64 +test.test_decimal.PyContextWithStatement.test_localcontext @ linux-x86_64 +test.test_decimal.PyContextWithStatement.test_localcontext_kwargs @ linux-x86_64 +test.test_decimal.PyContextWithStatement.test_localcontextarg @ linux-x86_64 +test.test_decimal.PyContextWithStatement.test_nested_with_statements @ linux-x86_64 +test.test_decimal.PyContextWithStatement.test_with_statements_gc1 @ linux-x86_64 +test.test_decimal.PyContextWithStatement.test_with_statements_gc2 @ linux-x86_64 +test.test_decimal.PyContextWithStatement.test_with_statements_gc3 @ linux-x86_64 +test.test_decimal.PyCoverage.test_adjusted @ linux-x86_64 +test.test_decimal.PyCoverage.test_canonical @ linux-x86_64 +test.test_decimal.PyCoverage.test_context_repr @ linux-x86_64 +test.test_decimal.PyCoverage.test_copy @ linux-x86_64 +test.test_decimal.PyCoverage.test_create_decimal @ linux-x86_64 +test.test_decimal.PyCoverage.test_divmod @ linux-x86_64 +test.test_decimal.PyCoverage.test_implicit_context @ linux-x86_64 +test.test_decimal.PyCoverage.test_int @ linux-x86_64 +test.test_decimal.PyCoverage.test_power @ linux-x86_64 +test.test_decimal.PyCoverage.test_quantize @ linux-x86_64 +test.test_decimal.PyCoverage.test_radix @ linux-x86_64 +test.test_decimal.PyCoverage.test_rop @ linux-x86_64 +test.test_decimal.PyCoverage.test_round @ linux-x86_64 +test.test_decimal.PyExplicitConstructionTest.test_explicit_context_create_decimal @ linux-x86_64 +test.test_decimal.PyExplicitConstructionTest.test_explicit_context_create_from_float @ linux-x86_64 +test.test_decimal.PyExplicitConstructionTest.test_explicit_empty @ linux-x86_64 +test.test_decimal.PyExplicitConstructionTest.test_explicit_from_Decimal @ linux-x86_64 +test.test_decimal.PyExplicitConstructionTest.test_explicit_from_None @ linux-x86_64 +test.test_decimal.PyExplicitConstructionTest.test_explicit_from_bool @ linux-x86_64 +test.test_decimal.PyExplicitConstructionTest.test_explicit_from_float @ linux-x86_64 +test.test_decimal.PyExplicitConstructionTest.test_explicit_from_int @ linux-x86_64 +test.test_decimal.PyExplicitConstructionTest.test_explicit_from_list @ linux-x86_64 +test.test_decimal.PyExplicitConstructionTest.test_explicit_from_string @ linux-x86_64 +test.test_decimal.PyExplicitConstructionTest.test_explicit_from_tuples @ linux-x86_64 +test.test_decimal.PyExplicitConstructionTest.test_unicode_digits @ linux-x86_64 +test.test_decimal.PyFormatTest.test_decimal_from_float_argument_type @ linux-x86_64 +test.test_decimal.PyFormatTest.test_formatting @ linux-x86_64 +test.test_decimal.PyFormatTest.test_n_format @ linux-x86_64 +test.test_decimal.PyFormatTest.test_negative_zero_bad_format @ linux-x86_64 +test.test_decimal.PyFormatTest.test_negative_zero_format_directed_rounding @ linux-x86_64 +test.test_decimal.PyFormatTest.test_wide_char_separator_decimal_point @ linux-x86_64 +test.test_decimal.PyFunctionality.test_py_alternate_formatting @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_abs @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_add @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_and @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_base @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_clamp @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_class @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_compare @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_comparetotal @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_comparetotmag @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_copy @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_copyabs @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_copynegate @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_copysign @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddAbs @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddAdd @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddAnd @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddBase @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddCanonical @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddClass @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddCompare @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddCompareSig @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddCompareTotal @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddCompareTotalMag @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddCopy @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddCopyAbs @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddCopyNegate @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddCopySign @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddDivide @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddDivideInt @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddEncode @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddFMA @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddInvert @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddLogB @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddMax @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddMaxMag @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddMin @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddMinMag @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddMinus @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddMultiply @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddNextMinus @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddNextPlus @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddNextToward @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddOr @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddPlus @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddQuantize @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddReduce @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddRemainder @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddRemainderNear @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddRotate @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddSameQuantum @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddScaleB @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddShift @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddSubtract @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddToIntegral @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ddXor @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_decDouble @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_decQuad @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_decSingle @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_divide @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_divideint @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqAbs @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqAdd @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqAnd @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqBase @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqCanonical @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqClass @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqCompare @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqCompareSig @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqCompareTotal @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqCompareTotalMag @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqCopy @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqCopyAbs @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqCopyNegate @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqCopySign @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqDivide @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqDivideInt @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqEncode @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqFMA @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqInvert @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqLogB @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqMax @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqMaxMag @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqMin @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqMinMag @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqMinus @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqMultiply @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqNextMinus @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqNextPlus @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqNextToward @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqOr @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqPlus @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqQuantize @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqReduce @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqRemainder @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqRemainderNear @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqRotate @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqSameQuantum @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqScaleB @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqShift @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqSubtract @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqToIntegral @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dqXor @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dsBase @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_dsEncode @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_exp @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_extra @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_fma @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_inexact @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_invert @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_ln @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_log10 @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_logb @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_max @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_maxmag @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_min @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_minmag @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_minus @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_multiply @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_nextminus @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_nextplus @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_nexttoward @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_or @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_plus @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_power @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_powersqrt @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_quantize @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_randomBound32 @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_randoms @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_reduce @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_remainder @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_remainderNear @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_rescale @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_rotate @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_rounding @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_samequantum @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_scaleb @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_shift @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_squareroot @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_subtract @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_testall @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_tointegral @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_tointegralx @ linux-x86_64 +test.test_decimal.PyIBMTestCases.test_xor @ linux-x86_64 +test.test_decimal.PyImplicitConstructionTest.test_implicit_from_Decimal @ linux-x86_64 +test.test_decimal.PyImplicitConstructionTest.test_implicit_from_None @ linux-x86_64 +test.test_decimal.PyImplicitConstructionTest.test_implicit_from_float @ linux-x86_64 +test.test_decimal.PyImplicitConstructionTest.test_implicit_from_int @ linux-x86_64 +test.test_decimal.PyImplicitConstructionTest.test_implicit_from_string @ linux-x86_64 +test.test_decimal.PyImplicitConstructionTest.test_rop @ linux-x86_64 +test.test_decimal.PyPythonAPItests.test_abc @ linux-x86_64 +test.test_decimal.PyPythonAPItests.test_complex @ linux-x86_64 +test.test_decimal.PyPythonAPItests.test_create_decimal_from_float @ linux-x86_64 +test.test_decimal.PyPythonAPItests.test_exception_hierarchy @ linux-x86_64 +test.test_decimal.PyPythonAPItests.test_from_float @ linux-x86_64 +test.test_decimal.PyPythonAPItests.test_int @ linux-x86_64 +test.test_decimal.PyPythonAPItests.test_named_parameters @ linux-x86_64 +test.test_decimal.PyPythonAPItests.test_pickle @ linux-x86_64 +test.test_decimal.PyPythonAPItests.test_quantize @ linux-x86_64 +test.test_decimal.PyPythonAPItests.test_trunc @ linux-x86_64 +test.test_decimal.PySpecialContexts.test_context_templates @ linux-x86_64 +test.test_decimal.PySpecialContexts.test_default_context @ linux-x86_64 +test.test_decimal.PyThreadingTest.test_threading @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_as_integer_ratio @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_as_nonzero @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_as_tuple @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_comparison_operators @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_conversions_from_int @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_copy_and_deepcopy_methods @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_decimal_complex_comparison @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_decimal_float_comparison @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_decimal_fraction_comparison @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_eval_round_trip @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_hash_method @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_hash_method_nan @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_implicit_context @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_min_and_max_methods @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_nan_to_float @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_none_args @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_snan_to_float @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_subclassing @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_tonum_methods @ linux-x86_64 +test.test_decimal.PyUsabilityTest.test_tostring_methods @ linux-x86_64 +test.test_decimal.PyWhitebox.test_py__round @ linux-x86_64 +test.test_decimal.PyWhitebox.test_py_decimal_id @ linux-x86_64 +test.test_decimal.PyWhitebox.test_py_exact_power @ linux-x86_64 +test.test_decimal.PyWhitebox.test_py_immutability_operations @ linux-x86_64 +test.test_decimal.PyWhitebox.test_py_rescale @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_decorators.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_decorators.txt new file mode 100644 index 0000000000..fe2c3b183a --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_decorators.txt @@ -0,0 +1,16 @@ +test.test_decorators.TestClassDecorators.test_double @ linux-x86_64 +test.test_decorators.TestClassDecorators.test_order @ linux-x86_64 +test.test_decorators.TestClassDecorators.test_simple @ linux-x86_64 +test.test_decorators.TestDecorators.test_argforms @ linux-x86_64 +test.test_decorators.TestDecorators.test_bound_function_inside_classmethod @ linux-x86_64 +test.test_decorators.TestDecorators.test_dbcheck @ linux-x86_64 +test.test_decorators.TestDecorators.test_dotted @ linux-x86_64 +test.test_decorators.TestDecorators.test_double @ linux-x86_64 +test.test_decorators.TestDecorators.test_errors @ linux-x86_64 +test.test_decorators.TestDecorators.test_eval_order @ linux-x86_64 +test.test_decorators.TestDecorators.test_expressions @ linux-x86_64 +test.test_decorators.TestDecorators.test_memoize @ linux-x86_64 +test.test_decorators.TestDecorators.test_order @ linux-x86_64 +test.test_decorators.TestDecorators.test_single @ linux-x86_64 +test.test_decorators.TestDecorators.test_staticmethod @ linux-x86_64 +test.test_decorators.TestDecorators.test_wrapped_classmethod_inside_classmethod @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_defaultdict.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_defaultdict.txt new file mode 100644 index 0000000000..0180d51c34 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_defaultdict.txt @@ -0,0 +1,10 @@ +test.test_defaultdict.TestDefaultDict.test_basic @ linux-x86_64 +test.test_defaultdict.TestDefaultDict.test_callable_arg @ linux-x86_64 +test.test_defaultdict.TestDefaultDict.test_copy @ linux-x86_64 +test.test_defaultdict.TestDefaultDict.test_deep_copy @ linux-x86_64 +test.test_defaultdict.TestDefaultDict.test_keyerror_without_factory @ linux-x86_64 +test.test_defaultdict.TestDefaultDict.test_missing @ linux-x86_64 +test.test_defaultdict.TestDefaultDict.test_pickling @ linux-x86_64 +test.test_defaultdict.TestDefaultDict.test_repr @ linux-x86_64 +test.test_defaultdict.TestDefaultDict.test_shallow_copy @ linux-x86_64 +test.test_defaultdict.TestDefaultDict.test_union @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_deque.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_deque.txt new file mode 100644 index 0000000000..7349540e6c --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_deque.txt @@ -0,0 +1,73 @@ +DocTestCase.test.test_deque.__test__.libreftest @ linux-x86_64 +test.test_deque.TestBasic.test_add @ linux-x86_64 +test.test_deque.TestBasic.test_basics @ linux-x86_64 +test.test_deque.TestBasic.test_big_queue_popleft @ linux-x86_64 +test.test_deque.TestBasic.test_big_queue_popright @ linux-x86_64 +test.test_deque.TestBasic.test_big_stack_left @ linux-x86_64 +test.test_deque.TestBasic.test_big_stack_right @ linux-x86_64 +test.test_deque.TestBasic.test_clear @ linux-x86_64 +test.test_deque.TestBasic.test_comparisons @ linux-x86_64 +test.test_deque.TestBasic.test_contains @ linux-x86_64 +test.test_deque.TestBasic.test_contains_count_stop_crashes @ linux-x86_64 +test.test_deque.TestBasic.test_copy @ linux-x86_64 +test.test_deque.TestBasic.test_copy_method @ linux-x86_64 +test.test_deque.TestBasic.test_count @ linux-x86_64 +test.test_deque.TestBasic.test_deepcopy @ linux-x86_64 +test.test_deque.TestBasic.test_delitem @ linux-x86_64 +test.test_deque.TestBasic.test_extend @ linux-x86_64 +test.test_deque.TestBasic.test_extendleft @ linux-x86_64 +test.test_deque.TestBasic.test_gc_doesnt_blowup @ linux-x86_64 +test.test_deque.TestBasic.test_getitem @ linux-x86_64 +test.test_deque.TestBasic.test_hash @ linux-x86_64 +test.test_deque.TestBasic.test_iadd @ linux-x86_64 +test.test_deque.TestBasic.test_imul @ linux-x86_64 +test.test_deque.TestBasic.test_index @ linux-x86_64 +test.test_deque.TestBasic.test_index_bug_24913 @ linux-x86_64 +test.test_deque.TestBasic.test_init @ linux-x86_64 +test.test_deque.TestBasic.test_insert @ linux-x86_64 +test.test_deque.TestBasic.test_insert_bug_26194 @ linux-x86_64 +test.test_deque.TestBasic.test_iterator_pickle @ linux-x86_64 +test.test_deque.TestBasic.test_len @ linux-x86_64 +test.test_deque.TestBasic.test_long_steadystate_queue_popleft @ linux-x86_64 +test.test_deque.TestBasic.test_long_steadystate_queue_popright @ linux-x86_64 +test.test_deque.TestBasic.test_maxlen @ linux-x86_64 +test.test_deque.TestBasic.test_maxlen_attribute @ linux-x86_64 +test.test_deque.TestBasic.test_maxlen_zero @ linux-x86_64 +test.test_deque.TestBasic.test_mul @ linux-x86_64 +test.test_deque.TestBasic.test_pickle @ linux-x86_64 +test.test_deque.TestBasic.test_pickle_recursive @ linux-x86_64 +test.test_deque.TestBasic.test_remove @ linux-x86_64 +test.test_deque.TestBasic.test_repr @ linux-x86_64 +test.test_deque.TestBasic.test_reverse @ linux-x86_64 +test.test_deque.TestBasic.test_reversed @ linux-x86_64 +test.test_deque.TestBasic.test_reversed_new @ linux-x86_64 +test.test_deque.TestBasic.test_rotate @ linux-x86_64 +test.test_deque.TestBasic.test_roundtrip_iter_init @ linux-x86_64 +test.test_deque.TestBasic.test_setitem @ linux-x86_64 +test.test_deque.TestBasic.test_underflow @ linux-x86_64 +test.test_deque.TestSequence.test_addmul @ linux-x86_64 +test.test_deque.TestSequence.test_constructors @ linux-x86_64 +test.test_deque.TestSequence.test_contains @ linux-x86_64 +test.test_deque.TestSequence.test_contains_fake @ linux-x86_64 +test.test_deque.TestSequence.test_contains_order @ linux-x86_64 +test.test_deque.TestSequence.test_count @ linux-x86_64 +test.test_deque.TestSequence.test_getitem @ linux-x86_64 +test.test_deque.TestSequence.test_getitemoverwriteiter @ linux-x86_64 +test.test_deque.TestSequence.test_getslice @ linux-x86_64 +test.test_deque.TestSequence.test_iadd @ linux-x86_64 +test.test_deque.TestSequence.test_imul @ linux-x86_64 +test.test_deque.TestSequence.test_index @ linux-x86_64 +test.test_deque.TestSequence.test_len @ linux-x86_64 +test.test_deque.TestSequence.test_minmax @ linux-x86_64 +test.test_deque.TestSequence.test_pickle @ linux-x86_64 +test.test_deque.TestSequence.test_repeat @ linux-x86_64 +test.test_deque.TestSequence.test_subscript @ linux-x86_64 +test.test_deque.TestSequence.test_truth @ linux-x86_64 +test.test_deque.TestSubclass.test_basics @ linux-x86_64 +test.test_deque.TestSubclass.test_copy_pickle @ linux-x86_64 +test.test_deque.TestSubclass.test_pickle_recursive @ linux-x86_64 +test.test_deque.TestSubclass.test_strange_subclass @ linux-x86_64 +test.test_deque.TestSubclassWithKwargs.test_subclass_with_kwargs @ linux-x86_64 +test.test_deque.TestVariousIteratorArgs.test_constructor @ linux-x86_64 +test.test_deque.TestVariousIteratorArgs.test_iter_with_altered_data @ linux-x86_64 +test.test_deque.TestVariousIteratorArgs.test_runtime_error_on_empty_deque @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_descr.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_descr.txt new file mode 100644 index 0000000000..e254f464db --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_descr.txt @@ -0,0 +1,126 @@ +test.test_descr.AAAPTypesLongInitTest.test_pytype_long_ready @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_abstractmethods @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_altmro @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_assign_slice @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_attr_raise_through_property @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_basic_inheritance @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_binary_operator_override @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_bound_method_repr @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_bpo25750 @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_buffer_inheritance @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_builtin_bases @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_builtin_function_or_method @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_carloverre @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_carloverre_multi_inherit_valid @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_classic @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_classic_comparisons @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_classmethods @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_consistency_with_epg @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_copy_setstate @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_deepcopy_recursive @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_diamond_inheritance @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_dict_constructors @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_dir @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_doc_descriptor @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_dynamics @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_errors @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_evil_type_name @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_ex5_from_c3_switch @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_file_fault @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_funny_new @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_getattr_hooks @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_hash_inheritance @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_imul_bug @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_init @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_ipow @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_ipow_exception_text @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_ipow_returns_not_implemented @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_isinst_isclass @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_keyword_arguments @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_keywords @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_load_attr_extended_arg @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_metaclass @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_method_wrapper @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_methods @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_mixing_slot_wrappers @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_module_subclasses @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_monotonicity @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_mro_disagreement @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_multiple_inheritance @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_mutable_bases @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_mutable_bases_catch_mro_conflict @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_mutable_bases_with_failing_mro @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_mutable_names @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_newslots @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_no_ipow @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_not_implemented @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_object_class @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_object_class_assignment_between_heaptypes_and_nonheaptypes @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_object_new @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_object_new_and_init_with_parameters @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_overloading @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_proxy_call @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_proxy_super @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_python_dicts @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_python_lists @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_qualname @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_qualname_dict @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_recursive_call @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_repr_with_module_str_subclass @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_rich_comparisons @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_rmul @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_set_and_no_get @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_set_class @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_set_dict @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_set_doc @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_slices @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_slot_shadows_class_variable @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_slots @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_slots_descriptor @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_slots_multiple_inheritance @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_slots_special @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_slots_special2 @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_slots_trash @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_special_method_lookup @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_special_unbound_method_types @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_specials @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_staticmethods @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_str_of_str_subclass @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_str_operations @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_str_subclass_as_dict_key @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_subclass_propagation @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_subclass_right_op @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_subclassing_does_not_duplicate_dict_descriptors @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_supers @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_type___getattribute__ @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_uninitialized_modules @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_unsubclassable_types @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_vicious_descriptor_nonsense @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_weakref_segfault @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_wrapper_segfault @ linux-x86_64 +test.test_descr.ClassPropertiesAndMethods.test_wrong_class_slot_wrapper @ linux-x86_64 +test.test_descr.DictProxyTests.test_dict_type_with_metaclass @ linux-x86_64 +test.test_descr.DictProxyTests.test_iter_items @ linux-x86_64 +test.test_descr.DictProxyTests.test_iter_keys @ linux-x86_64 +test.test_descr.DictProxyTests.test_iter_values @ linux-x86_64 +test.test_descr.DictProxyTests.test_repr @ linux-x86_64 +test.test_descr.MiscTests.test_type_lookup_mro_reference @ linux-x86_64 +test.test_descr.MroTest.test_incomplete_extend @ linux-x86_64 +test.test_descr.MroTest.test_incomplete_set_bases_on_self @ linux-x86_64 +test.test_descr.MroTest.test_incomplete_super @ linux-x86_64 +test.test_descr.MroTest.test_reent_set_bases_on_base @ linux-x86_64 +test.test_descr.MroTest.test_reent_set_bases_on_direct_base @ linux-x86_64 +test.test_descr.MroTest.test_reent_set_bases_tp_base_cycle @ linux-x86_64 +test.test_descr.MroTest.test_tp_subclasses_cycle_error_return_path @ linux-x86_64 +test.test_descr.MroTest.test_tp_subclasses_cycle_in_update_slots @ linux-x86_64 +test.test_descr.OperatorsTest.test_complexes @ linux-x86_64 +test.test_descr.OperatorsTest.test_dicts @ linux-x86_64 +test.test_descr.OperatorsTest.test_explicit_reverse_methods @ linux-x86_64 +test.test_descr.OperatorsTest.test_floats @ linux-x86_64 +test.test_descr.OperatorsTest.test_ints @ linux-x86_64 +test.test_descr.OperatorsTest.test_lists @ linux-x86_64 +test.test_descr.OperatorsTest.test_wrap_lenfunc_bad_cast @ linux-x86_64 +test.test_descr.PicklingTests.test_issue24097 @ linux-x86_64 +test.test_descr.PicklingTests.test_pickle_slots @ linux-x86_64 +test.test_descr.PicklingTests.test_reduce @ linux-x86_64 +test.test_descr.PicklingTests.test_reduce_copying @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_descrtut.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_descrtut.txt new file mode 100644 index 0000000000..a34b61d3d2 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_descrtut.txt @@ -0,0 +1,7 @@ +DocTestCase.test.test_descrtut.__test__.tut1 @ linux-x86_64 +DocTestCase.test.test_descrtut.__test__.tut2 @ linux-x86_64 +DocTestCase.test.test_descrtut.__test__.tut4 @ linux-x86_64 +DocTestCase.test.test_descrtut.__test__.tut5 @ linux-x86_64 +DocTestCase.test.test_descrtut.__test__.tut6 @ linux-x86_64 +DocTestCase.test.test_descrtut.__test__.tut7 @ linux-x86_64 +DocTestCase.test.test_descrtut.__test__.tut8 @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dict.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dict.txt new file mode 100644 index 0000000000..5f57dca657 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dict.txt @@ -0,0 +1,90 @@ +test.test_dict.DictTest.test_bad_key @ linux-x86_64 +test.test_dict.DictTest.test_bool @ linux-x86_64 +test.test_dict.DictTest.test_clear @ linux-x86_64 +test.test_dict.DictTest.test_constructor @ linux-x86_64 +test.test_dict.DictTest.test_contains @ linux-x86_64 +test.test_dict.DictTest.test_copy @ linux-x86_64 +test.test_dict.DictTest.test_copy_fuzz @ linux-x86_64 +test.test_dict.DictTest.test_copy_maintains_tracking @ linux-x86_64 +test.test_dict.DictTest.test_copy_noncompact @ linux-x86_64 +test.test_dict.DictTest.test_dict_contain_use_after_free @ linux-x86_64 +test.test_dict.DictTest.test_dict_copy_order @ linux-x86_64 +test.test_dict.DictTest.test_dictitems_contains_use_after_free @ linux-x86_64 +test.test_dict.DictTest.test_dictview_mixed_set_operations @ linux-x86_64 +test.test_dict.DictTest.test_dictview_set_operations_on_items @ linux-x86_64 +test.test_dict.DictTest.test_dictview_set_operations_on_keys @ linux-x86_64 +test.test_dict.DictTest.test_empty_presized_dict_in_freelist @ linux-x86_64 +test.test_dict.DictTest.test_eq @ linux-x86_64 +test.test_dict.DictTest.test_equal_operator_modifying_operand @ linux-x86_64 +test.test_dict.DictTest.test_errors_in_view_containment_check @ linux-x86_64 +test.test_dict.DictTest.test_fromkeys @ linux-x86_64 +test.test_dict.DictTest.test_fromkeys_operator_modifying_dict_operand @ linux-x86_64 +test.test_dict.DictTest.test_fromkeys_operator_modifying_set_operand @ linux-x86_64 +test.test_dict.DictTest.test_get @ linux-x86_64 +test.test_dict.DictTest.test_getitem @ linux-x86_64 +test.test_dict.DictTest.test_init_use_after_free @ linux-x86_64 +test.test_dict.DictTest.test_instance_dict_getattr_str_subclass @ linux-x86_64 +test.test_dict.DictTest.test_invalid_keyword_arguments @ linux-x86_64 +test.test_dict.DictTest.test_itemiterator_pickling @ linux-x86_64 +test.test_dict.DictTest.test_items @ linux-x86_64 +test.test_dict.DictTest.test_items_symmetric_difference @ linux-x86_64 +test.test_dict.DictTest.test_iterator_pickling @ linux-x86_64 +test.test_dict.DictTest.test_keys @ linux-x86_64 +test.test_dict.DictTest.test_keys_contained @ linux-x86_64 +test.test_dict.DictTest.test_len @ linux-x86_64 +test.test_dict.DictTest.test_literal_constructor @ linux-x86_64 +test.test_dict.DictTest.test_merge_and_mutate @ linux-x86_64 +test.test_dict.DictTest.test_merge_operator @ linux-x86_64 +test.test_dict.DictTest.test_missing @ linux-x86_64 +test.test_dict.DictTest.test_mutating_iteration @ linux-x86_64 +test.test_dict.DictTest.test_mutating_lookup @ linux-x86_64 +test.test_dict.DictTest.test_object_set_item_single_instance_non_str_key @ linux-x86_64 +test.test_dict.DictTest.test_pop @ linux-x86_64 +test.test_dict.DictTest.test_popitem @ linux-x86_64 +test.test_dict.DictTest.test_reentrant_insertion @ linux-x86_64 +test.test_dict.DictTest.test_repr @ linux-x86_64 +test.test_dict.DictTest.test_resize1 @ linux-x86_64 +test.test_dict.DictTest.test_resize2 @ linux-x86_64 +test.test_dict.DictTest.test_reverse_iterator_for_empty_dict @ linux-x86_64 +test.test_dict.DictTest.test_reverse_iterator_for_shared_shared_dicts @ linux-x86_64 +test.test_dict.DictTest.test_reversed @ linux-x86_64 +test.test_dict.DictTest.test_reverseitemiterator_pickling @ linux-x86_64 +test.test_dict.DictTest.test_reverseiterator_pickling @ linux-x86_64 +test.test_dict.DictTest.test_reversevaluesiterator_pickling @ linux-x86_64 +test.test_dict.DictTest.test_setdefault @ linux-x86_64 +test.test_dict.DictTest.test_setitem_atomic_at_resize @ linux-x86_64 +test.test_dict.DictTest.test_str_nonstr @ linux-x86_64 +test.test_dict.DictTest.test_string_keys_can_track_values @ linux-x86_64 +test.test_dict.DictTest.test_tuple_keyerror @ linux-x86_64 +test.test_dict.DictTest.test_update @ linux-x86_64 +test.test_dict.DictTest.test_values @ linux-x86_64 +test.test_dict.DictTest.test_valuesiterator_pickling @ linux-x86_64 +test.test_dict.DictTest.test_views_mapping @ linux-x86_64 +test.test_dict.GeneralMappingTests.test_bool @ linux-x86_64 +test.test_dict.GeneralMappingTests.test_constructor @ linux-x86_64 +test.test_dict.GeneralMappingTests.test_get @ linux-x86_64 +test.test_dict.GeneralMappingTests.test_getitem @ linux-x86_64 +test.test_dict.GeneralMappingTests.test_items @ linux-x86_64 +test.test_dict.GeneralMappingTests.test_keys @ linux-x86_64 +test.test_dict.GeneralMappingTests.test_len @ linux-x86_64 +test.test_dict.GeneralMappingTests.test_pop @ linux-x86_64 +test.test_dict.GeneralMappingTests.test_popitem @ linux-x86_64 +test.test_dict.GeneralMappingTests.test_read @ linux-x86_64 +test.test_dict.GeneralMappingTests.test_setdefault @ linux-x86_64 +test.test_dict.GeneralMappingTests.test_update @ linux-x86_64 +test.test_dict.GeneralMappingTests.test_values @ linux-x86_64 +test.test_dict.GeneralMappingTests.test_write @ linux-x86_64 +test.test_dict.SubclassMappingTests.test_bool @ linux-x86_64 +test.test_dict.SubclassMappingTests.test_constructor @ linux-x86_64 +test.test_dict.SubclassMappingTests.test_get @ linux-x86_64 +test.test_dict.SubclassMappingTests.test_getitem @ linux-x86_64 +test.test_dict.SubclassMappingTests.test_items @ linux-x86_64 +test.test_dict.SubclassMappingTests.test_keys @ linux-x86_64 +test.test_dict.SubclassMappingTests.test_len @ linux-x86_64 +test.test_dict.SubclassMappingTests.test_pop @ linux-x86_64 +test.test_dict.SubclassMappingTests.test_popitem @ linux-x86_64 +test.test_dict.SubclassMappingTests.test_read @ linux-x86_64 +test.test_dict.SubclassMappingTests.test_setdefault @ linux-x86_64 +test.test_dict.SubclassMappingTests.test_update @ linux-x86_64 +test.test_dict.SubclassMappingTests.test_values @ linux-x86_64 +test.test_dict.SubclassMappingTests.test_write @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dictcomps.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dictcomps.txt new file mode 100644 index 0000000000..915c156532 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dictcomps.txt @@ -0,0 +1,9 @@ +test.test_dictcomps.DictComprehensionTest.test_assignment_idiom_in_comprehensions @ linux-x86_64 +test.test_dictcomps.DictComprehensionTest.test_basics @ linux-x86_64 +test.test_dictcomps.DictComprehensionTest.test_evaluation_order @ linux-x86_64 +test.test_dictcomps.DictComprehensionTest.test_global_visibility @ linux-x86_64 +test.test_dictcomps.DictComprehensionTest.test_illegal_assignment @ linux-x86_64 +test.test_dictcomps.DictComprehensionTest.test_local_visibility @ linux-x86_64 +test.test_dictcomps.DictComprehensionTest.test_scope_isolation @ linux-x86_64 +test.test_dictcomps.DictComprehensionTest.test_scope_isolation_from_global @ linux-x86_64 +test.test_dictcomps.DictComprehensionTest.test_star_expression @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dictviews.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dictviews.txt new file mode 100644 index 0000000000..9ae7a102fa --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dictviews.txt @@ -0,0 +1,15 @@ +test.test_dictviews.DictSetTest.test_abc_registry @ linux-x86_64 +test.test_dictviews.DictSetTest.test_compare_error @ linux-x86_64 +test.test_dictviews.DictSetTest.test_constructors_not_callable @ linux-x86_64 +test.test_dictviews.DictSetTest.test_copy @ linux-x86_64 +test.test_dictviews.DictSetTest.test_dict_items @ linux-x86_64 +test.test_dictviews.DictSetTest.test_dict_keys @ linux-x86_64 +test.test_dictviews.DictSetTest.test_dict_mixed_keys_items @ linux-x86_64 +test.test_dictviews.DictSetTest.test_dict_repr @ linux-x86_64 +test.test_dictviews.DictSetTest.test_dict_values @ linux-x86_64 +test.test_dictviews.DictSetTest.test_items_set_operations @ linux-x86_64 +test.test_dictviews.DictSetTest.test_keys_set_operations @ linux-x86_64 +test.test_dictviews.DictSetTest.test_pickle @ linux-x86_64 +test.test_dictviews.DictSetTest.test_recursive_repr @ linux-x86_64 +test.test_dictviews.DictSetTest.test_set_operations_with_iterator @ linux-x86_64 +test.test_dictviews.DictSetTest.test_set_operations_with_noniterable @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_difflib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_difflib.txt new file mode 100644 index 0000000000..6d92dc085b --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_difflib.txt @@ -0,0 +1,51 @@ +DocTestCase.difflib.Differ @ linux-x86_64 +DocTestCase.difflib.Differ._fancy_replace @ linux-x86_64 +DocTestCase.difflib.Differ._qformat @ linux-x86_64 +DocTestCase.difflib.Differ.compare @ linux-x86_64 +DocTestCase.difflib.IS_CHARACTER_JUNK @ linux-x86_64 +DocTestCase.difflib.IS_LINE_JUNK @ linux-x86_64 +DocTestCase.difflib.SequenceMatcher @ linux-x86_64 +DocTestCase.difflib.SequenceMatcher.find_longest_match @ linux-x86_64 +DocTestCase.difflib.SequenceMatcher.get_grouped_opcodes @ linux-x86_64 +DocTestCase.difflib.SequenceMatcher.get_matching_blocks @ linux-x86_64 +DocTestCase.difflib.SequenceMatcher.get_opcodes @ linux-x86_64 +DocTestCase.difflib.SequenceMatcher.ratio @ linux-x86_64 +DocTestCase.difflib.SequenceMatcher.set_seq1 @ linux-x86_64 +DocTestCase.difflib.SequenceMatcher.set_seq2 @ linux-x86_64 +DocTestCase.difflib.SequenceMatcher.set_seqs @ linux-x86_64 +DocTestCase.difflib.context_diff @ linux-x86_64 +DocTestCase.difflib.get_close_matches @ linux-x86_64 +DocTestCase.difflib.ndiff @ linux-x86_64 +DocTestCase.difflib.restore @ linux-x86_64 +DocTestCase.difflib.unified_diff @ linux-x86_64 +test.test_difflib.TestAutojunk.test_one_insert_homogenous_sequence @ linux-x86_64 +test.test_difflib.TestBytes.test_byte_content @ linux-x86_64 +test.test_difflib.TestBytes.test_byte_filenames @ linux-x86_64 +test.test_difflib.TestBytes.test_mixed_types_content @ linux-x86_64 +test.test_difflib.TestBytes.test_mixed_types_dates @ linux-x86_64 +test.test_difflib.TestBytes.test_mixed_types_filenames @ linux-x86_64 +test.test_difflib.TestFindLongest.test_default_args @ linux-x86_64 +test.test_difflib.TestFindLongest.test_longest_match_with_popular_chars @ linux-x86_64 +test.test_difflib.TestJunkAPIs.test_is_character_junk_false @ linux-x86_64 +test.test_difflib.TestJunkAPIs.test_is_character_junk_true @ linux-x86_64 +test.test_difflib.TestJunkAPIs.test_is_line_junk_REDOS @ linux-x86_64 +test.test_difflib.TestJunkAPIs.test_is_line_junk_false @ linux-x86_64 +test.test_difflib.TestJunkAPIs.test_is_line_junk_true @ linux-x86_64 +test.test_difflib.TestOutputFormat.test_no_trailing_tab_on_empty_filedate @ linux-x86_64 +test.test_difflib.TestOutputFormat.test_range_format_context @ linux-x86_64 +test.test_difflib.TestOutputFormat.test_range_format_unified @ linux-x86_64 +test.test_difflib.TestOutputFormat.test_tab_delimiter @ linux-x86_64 +test.test_difflib.TestSFbugs.test_added_tab_hint @ linux-x86_64 +test.test_difflib.TestSFbugs.test_comparing_empty_lists @ linux-x86_64 +test.test_difflib.TestSFbugs.test_hint_indented_properly_with_tabs @ linux-x86_64 +test.test_difflib.TestSFbugs.test_matching_blocks_cache @ linux-x86_64 +test.test_difflib.TestSFbugs.test_mdiff_catch_stop_iteration @ linux-x86_64 +test.test_difflib.TestSFbugs.test_ratio_for_null_seqn @ linux-x86_64 +test.test_difflib.TestSFpatches.test_html_diff @ linux-x86_64 +test.test_difflib.TestSFpatches.test_make_file_default_charset @ linux-x86_64 +test.test_difflib.TestSFpatches.test_make_file_iso88591_charset @ linux-x86_64 +test.test_difflib.TestSFpatches.test_make_file_usascii_charset_with_nonascii_input @ linux-x86_64 +test.test_difflib.TestSFpatches.test_recursion_limit @ linux-x86_64 +test.test_difflib.TestWithAscii.test_bjunk @ linux-x86_64 +test.test_difflib.TestWithAscii.test_one_delete @ linux-x86_64 +test.test_difflib.TestWithAscii.test_one_insert @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_distutils.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_distutils.txt new file mode 100644 index 0000000000..cc19b39312 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_distutils.txt @@ -0,0 +1,210 @@ +DocTestCase.distutils.versionpredicate.VersionPredicate @ linux-x86_64 +DocTestCase.distutils.versionpredicate.split_provision @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_check_archive_formats @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_make_archive @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_make_archive_bztar @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_make_archive_cwd @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_make_archive_gztar @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_make_archive_owner_group @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_make_archive_tar @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_make_archive_xztar @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_make_tarball @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_make_tarball_bzip2 @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_make_tarball_extended @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_make_tarball_gzip @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_make_tarball_latin1 @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_make_tarball_xz @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_make_zipfile @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_make_zipfile_no_zlib @ linux-x86_64 +distutils.tests.test_archive_util.ArchiveUtilTestCase.test_tarfile_vs_tar @ linux-x86_64 +distutils.tests.test_bdist.BuildTestCase.test_formats @ linux-x86_64 +distutils.tests.test_bdist.BuildTestCase.test_skip_build @ linux-x86_64 +distutils.tests.test_bdist_dumb.BuildDumbTestCase.test_simple_built @ linux-x86_64 +distutils.tests.test_build.BuildTestCase.test_finalize_options @ linux-x86_64 +distutils.tests.test_build_clib.BuildCLibTestCase.test_build_libraries @ linux-x86_64 +distutils.tests.test_build_clib.BuildCLibTestCase.test_check_library_dist @ linux-x86_64 +distutils.tests.test_build_clib.BuildCLibTestCase.test_finalize_options @ linux-x86_64 +distutils.tests.test_build_clib.BuildCLibTestCase.test_get_source_files @ linux-x86_64 +distutils.tests.test_build_clib.BuildCLibTestCase.test_run @ linux-x86_64 +distutils.tests.test_build_ext.BuildExtTestCase.test_check_extensions_list @ linux-x86_64 +distutils.tests.test_build_ext.BuildExtTestCase.test_compiler_option @ linux-x86_64 +distutils.tests.test_build_ext.BuildExtTestCase.test_ext_fullpath @ linux-x86_64 +distutils.tests.test_build_ext.BuildExtTestCase.test_finalize_options @ linux-x86_64 +distutils.tests.test_build_ext.BuildExtTestCase.test_get_outputs @ linux-x86_64 +distutils.tests.test_build_ext.BuildExtTestCase.test_get_source_files @ linux-x86_64 +distutils.tests.test_build_ext.BuildExtTestCase.test_optional_extension @ linux-x86_64 +distutils.tests.test_build_ext.BuildExtTestCase.test_solaris_enable_shared @ linux-x86_64 +distutils.tests.test_build_ext.BuildExtTestCase.test_unicode_module_names @ linux-x86_64 +distutils.tests.test_build_ext.BuildExtTestCase.test_user_site @ linux-x86_64 +distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_check_extensions_list @ linux-x86_64 +distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_compiler_option @ linux-x86_64 +distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_ext_fullpath @ linux-x86_64 +distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_finalize_options @ linux-x86_64 +distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_get_outputs @ linux-x86_64 +distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_get_source_files @ linux-x86_64 +distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_optional_extension @ linux-x86_64 +distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_solaris_enable_shared @ linux-x86_64 +distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_unicode_module_names @ linux-x86_64 +distutils.tests.test_build_ext.ParallelBuildExtTestCase.test_user_site @ linux-x86_64 +distutils.tests.test_build_py.BuildPyTestCase.test_byte_compile @ linux-x86_64 +distutils.tests.test_build_py.BuildPyTestCase.test_byte_compile_optimized @ linux-x86_64 +distutils.tests.test_build_py.BuildPyTestCase.test_dir_in_package_data @ linux-x86_64 +distutils.tests.test_build_py.BuildPyTestCase.test_dont_write_bytecode @ linux-x86_64 +distutils.tests.test_build_py.BuildPyTestCase.test_empty_package_dir @ linux-x86_64 +distutils.tests.test_build_py.BuildPyTestCase.test_package_data @ linux-x86_64 +distutils.tests.test_build_scripts.BuildScriptsTestCase.test_build @ linux-x86_64 +distutils.tests.test_build_scripts.BuildScriptsTestCase.test_default_settings @ linux-x86_64 +distutils.tests.test_build_scripts.BuildScriptsTestCase.test_version_int @ linux-x86_64 +distutils.tests.test_check.CheckTestCase.test_check_all @ linux-x86_64 +distutils.tests.test_check.CheckTestCase.test_check_metadata @ linux-x86_64 +distutils.tests.test_clean.cleanTestCase.test_simple_run @ linux-x86_64 +distutils.tests.test_cmd.CommandTestCase.test_debug_print @ linux-x86_64 +distutils.tests.test_cmd.CommandTestCase.test_dump_options @ linux-x86_64 +distutils.tests.test_cmd.CommandTestCase.test_ensure_dirname @ linux-x86_64 +distutils.tests.test_cmd.CommandTestCase.test_ensure_filename @ linux-x86_64 +distutils.tests.test_cmd.CommandTestCase.test_ensure_string @ linux-x86_64 +distutils.tests.test_cmd.CommandTestCase.test_ensure_string_list @ linux-x86_64 +distutils.tests.test_cmd.CommandTestCase.test_make_file @ linux-x86_64 +distutils.tests.test_config.PyPIRCCommandTestCase.test_config_interpolation @ linux-x86_64 +distutils.tests.test_config.PyPIRCCommandTestCase.test_server_empty_registration @ linux-x86_64 +distutils.tests.test_config.PyPIRCCommandTestCase.test_server_registration @ linux-x86_64 +distutils.tests.test_config_cmd.ConfigTestCase.test_clean @ linux-x86_64 +distutils.tests.test_config_cmd.ConfigTestCase.test_dump_file @ linux-x86_64 +distutils.tests.test_config_cmd.ConfigTestCase.test_finalize_options @ linux-x86_64 +distutils.tests.test_config_cmd.ConfigTestCase.test_search_cpp @ linux-x86_64 +distutils.tests.test_core.CoreTestCase.test_debug_mode @ linux-x86_64 +distutils.tests.test_core.CoreTestCase.test_run_setup_defines_subclass @ linux-x86_64 +distutils.tests.test_core.CoreTestCase.test_run_setup_preserves_sys_argv @ linux-x86_64 +distutils.tests.test_core.CoreTestCase.test_run_setup_provides_file @ linux-x86_64 +distutils.tests.test_core.CoreTestCase.test_run_setup_uses_current_dir @ linux-x86_64 +distutils.tests.test_cygwinccompiler.CygwinCCompilerTestCase.test_check_config_h @ linux-x86_64 +distutils.tests.test_cygwinccompiler.CygwinCCompilerTestCase.test_get_msvcr @ linux-x86_64 +distutils.tests.test_cygwinccompiler.CygwinCCompilerTestCase.test_get_versions @ linux-x86_64 +distutils.tests.test_dep_util.DepUtilTestCase.test_newer @ linux-x86_64 +distutils.tests.test_dep_util.DepUtilTestCase.test_newer_group @ linux-x86_64 +distutils.tests.test_dep_util.DepUtilTestCase.test_newer_pairwise @ linux-x86_64 +distutils.tests.test_dir_util.DirUtilTestCase.test_copy_tree_exception_in_listdir @ linux-x86_64 +distutils.tests.test_dir_util.DirUtilTestCase.test_copy_tree_skips_nfs_temp_files @ linux-x86_64 +distutils.tests.test_dir_util.DirUtilTestCase.test_copy_tree_verbosity @ linux-x86_64 +distutils.tests.test_dir_util.DirUtilTestCase.test_create_tree_verbosity @ linux-x86_64 +distutils.tests.test_dir_util.DirUtilTestCase.test_ensure_relative @ linux-x86_64 +distutils.tests.test_dir_util.DirUtilTestCase.test_mkpath_remove_tree_verbosity @ linux-x86_64 +distutils.tests.test_dir_util.DirUtilTestCase.test_mkpath_with_custom_mode @ linux-x86_64 +distutils.tests.test_dist.DistributionTestCase.test_announce @ linux-x86_64 +distutils.tests.test_dist.DistributionTestCase.test_command_packages_cmdline @ linux-x86_64 +distutils.tests.test_dist.DistributionTestCase.test_command_packages_configfile @ linux-x86_64 +distutils.tests.test_dist.DistributionTestCase.test_command_packages_unspecified @ linux-x86_64 +distutils.tests.test_dist.DistributionTestCase.test_empty_options @ linux-x86_64 +distutils.tests.test_dist.DistributionTestCase.test_finalize_options @ linux-x86_64 +distutils.tests.test_dist.DistributionTestCase.test_find_config_files_disable @ linux-x86_64 +distutils.tests.test_dist.DistributionTestCase.test_get_command_packages @ linux-x86_64 +distutils.tests.test_dist.DistributionTestCase.test_venv_install_options @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_classifier @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_classifier_invalid_type @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_custom_pydistutils @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_download_url @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_fix_help_options @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_keywords @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_keywords_invalid_type @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_long_description @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_obsoletes @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_obsoletes_illegal @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_obsoletes_to_list @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_platforms @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_platforms_invalid_types @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_provides @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_provides_illegal @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_read_metadata @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_requires @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_requires_illegal @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_requires_to_list @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_show_help @ linux-x86_64 +distutils.tests.test_dist.MetadataTestCase.test_simple_metadata @ linux-x86_64 +distutils.tests.test_extension.ExtensionTestCase.test_extension_init @ linux-x86_64 +distutils.tests.test_extension.ExtensionTestCase.test_read_setup_file @ linux-x86_64 +distutils.tests.test_file_util.FileUtilTestCase.test_copy_file_hard_link @ linux-x86_64 +distutils.tests.test_file_util.FileUtilTestCase.test_copy_file_hard_link_failure @ linux-x86_64 +distutils.tests.test_file_util.FileUtilTestCase.test_move_file_exception_unpacking_rename @ linux-x86_64 +distutils.tests.test_file_util.FileUtilTestCase.test_move_file_exception_unpacking_unlink @ linux-x86_64 +distutils.tests.test_file_util.FileUtilTestCase.test_move_file_verbosity @ linux-x86_64 +distutils.tests.test_filelist.FileListTestCase.test_debug_print @ linux-x86_64 +distutils.tests.test_filelist.FileListTestCase.test_exclude_pattern @ linux-x86_64 +distutils.tests.test_filelist.FileListTestCase.test_glob_to_re @ linux-x86_64 +distutils.tests.test_filelist.FileListTestCase.test_include_pattern @ linux-x86_64 +distutils.tests.test_filelist.FileListTestCase.test_process_template @ linux-x86_64 +distutils.tests.test_filelist.FileListTestCase.test_process_template_line @ linux-x86_64 +distutils.tests.test_filelist.FileListTestCase.test_remove_duplicates @ linux-x86_64 +distutils.tests.test_filelist.FileListTestCase.test_set_allfiles @ linux-x86_64 +distutils.tests.test_filelist.FileListTestCase.test_translate_pattern @ linux-x86_64 +distutils.tests.test_filelist.FindAllTestCase.test_basic_discovery @ linux-x86_64 +distutils.tests.test_filelist.FindAllTestCase.test_missing_symlink @ linux-x86_64 +distutils.tests.test_filelist.FindAllTestCase.test_non_local_discovery @ linux-x86_64 +distutils.tests.test_install.InstallTestCase.test_debug_mode @ linux-x86_64 +distutils.tests.test_install.InstallTestCase.test_finalize_options @ linux-x86_64 +distutils.tests.test_install.InstallTestCase.test_handle_extra_path @ linux-x86_64 +distutils.tests.test_install.InstallTestCase.test_home_installation_scheme @ linux-x86_64 +distutils.tests.test_install.InstallTestCase.test_record @ linux-x86_64 +distutils.tests.test_install.InstallTestCase.test_user_site @ linux-x86_64 +distutils.tests.test_install_data.InstallDataTestCase.test_simple_run @ linux-x86_64 +distutils.tests.test_install_headers.InstallHeadersTestCase.test_simple_run @ linux-x86_64 +distutils.tests.test_install_lib.InstallLibTestCase.test_byte_compile @ linux-x86_64 +distutils.tests.test_install_lib.InstallLibTestCase.test_dont_write_bytecode @ linux-x86_64 +distutils.tests.test_install_lib.InstallLibTestCase.test_finalize_options @ linux-x86_64 +distutils.tests.test_install_lib.InstallLibTestCase.test_get_inputs @ linux-x86_64 +distutils.tests.test_install_lib.InstallLibTestCase.test_get_outputs @ linux-x86_64 +distutils.tests.test_install_scripts.InstallScriptsTestCase.test_default_settings @ linux-x86_64 +distutils.tests.test_install_scripts.InstallScriptsTestCase.test_installation @ linux-x86_64 +distutils.tests.test_log.TestLog.test_non_ascii @ linux-x86_64 +distutils.tests.test_register.RegisterTestCase.test_check_metadata_deprecated @ linux-x86_64 +distutils.tests.test_register.RegisterTestCase.test_create_pypirc @ linux-x86_64 +distutils.tests.test_register.RegisterTestCase.test_list_classifiers @ linux-x86_64 +distutils.tests.test_register.RegisterTestCase.test_password_not_in_file @ linux-x86_64 +distutils.tests.test_register.RegisterTestCase.test_password_reset @ linux-x86_64 +distutils.tests.test_register.RegisterTestCase.test_registering @ linux-x86_64 +distutils.tests.test_register.RegisterTestCase.test_show_response @ linux-x86_64 +distutils.tests.test_sdist.SDistTestCase.test_add_defaults @ linux-x86_64 +distutils.tests.test_sdist.SDistTestCase.test_check_metadata_deprecated @ linux-x86_64 +distutils.tests.test_sdist.SDistTestCase.test_finalize_options @ linux-x86_64 +distutils.tests.test_sdist.SDistTestCase.test_get_file_list @ linux-x86_64 +distutils.tests.test_sdist.SDistTestCase.test_invalid_template_unknown_command @ linux-x86_64 +distutils.tests.test_sdist.SDistTestCase.test_invalid_template_wrong_arguments @ linux-x86_64 +distutils.tests.test_sdist.SDistTestCase.test_make_distribution @ linux-x86_64 +distutils.tests.test_sdist.SDistTestCase.test_manifest_comments @ linux-x86_64 +distutils.tests.test_sdist.SDistTestCase.test_manifest_marker @ linux-x86_64 +distutils.tests.test_sdist.SDistTestCase.test_manual_manifest @ linux-x86_64 +distutils.tests.test_sdist.SDistTestCase.test_metadata_check_option @ linux-x86_64 +distutils.tests.test_sdist.SDistTestCase.test_prune_file_list @ linux-x86_64 +distutils.tests.test_sdist.SDistTestCase.test_show_formats @ linux-x86_64 +distutils.tests.test_spawn.SpawnTestCase.test_find_executable @ linux-x86_64 +distutils.tests.test_spawn.SpawnTestCase.test_spawn @ linux-x86_64 +distutils.tests.test_spawn.SpawnTestCase.test_spawn_missing_exe @ linux-x86_64 +distutils.tests.test_sysconfig.SysconfigTestCase.test_customize_compiler_before_get_config_vars @ linux-x86_64 +distutils.tests.test_sysconfig.SysconfigTestCase.test_get_config_h_filename @ linux-x86_64 +distutils.tests.test_sysconfig.SysconfigTestCase.test_get_config_vars @ linux-x86_64 +distutils.tests.test_sysconfig.SysconfigTestCase.test_get_python_lib @ linux-x86_64 +distutils.tests.test_sysconfig.SysconfigTestCase.test_parse_makefile_base @ linux-x86_64 +distutils.tests.test_sysconfig.SysconfigTestCase.test_parse_makefile_literal_dollar @ linux-x86_64 +distutils.tests.test_sysconfig.SysconfigTestCase.test_srcdir_independent_of_cwd @ linux-x86_64 +distutils.tests.test_sysconfig.SysconfigTestCase.test_sysconfig_compiler_vars @ linux-x86_64 +distutils.tests.test_sysconfig.SysconfigTestCase.test_sysconfig_module @ linux-x86_64 +distutils.tests.test_text_file.TextFileTestCase.test_class @ linux-x86_64 +distutils.tests.test_unixccompiler.UnixCCompilerTestCase.test_runtime_libdir_option @ linux-x86_64 +distutils.tests.test_upload.uploadTestCase.test_finalize_options @ linux-x86_64 +distutils.tests.test_upload.uploadTestCase.test_saved_password @ linux-x86_64 +distutils.tests.test_upload.uploadTestCase.test_upload @ linux-x86_64 +distutils.tests.test_upload.uploadTestCase.test_upload_correct_cr @ linux-x86_64 +distutils.tests.test_upload.uploadTestCase.test_upload_fails @ linux-x86_64 +distutils.tests.test_upload.uploadTestCase.test_wrong_exception_order @ linux-x86_64 +distutils.tests.test_util.UtilTestCase.test_change_root @ linux-x86_64 +distutils.tests.test_util.UtilTestCase.test_check_environ @ linux-x86_64 +distutils.tests.test_util.UtilTestCase.test_check_environ_getpwuid @ linux-x86_64 +distutils.tests.test_util.UtilTestCase.test_convert_path @ linux-x86_64 +distutils.tests.test_util.UtilTestCase.test_dont_write_bytecode @ linux-x86_64 +distutils.tests.test_util.UtilTestCase.test_get_platform @ linux-x86_64 +distutils.tests.test_util.UtilTestCase.test_grok_environment_error @ linux-x86_64 +distutils.tests.test_util.UtilTestCase.test_rfc822_escape @ linux-x86_64 +distutils.tests.test_util.UtilTestCase.test_split_quoted @ linux-x86_64 +distutils.tests.test_util.UtilTestCase.test_strtobool @ linux-x86_64 +distutils.tests.test_version.VersionTestCase.test_cmp @ linux-x86_64 +distutils.tests.test_version.VersionTestCase.test_cmp_strict @ linux-x86_64 +distutils.tests.test_version.VersionTestCase.test_prerelease @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_doctest.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_doctest.txt new file mode 100644 index 0000000000..36c97d04a7 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_doctest.txt @@ -0,0 +1,17 @@ +DocTestCase.doctest.DebugRunner @ linux-x86_64 +DocTestCase.doctest.DocTestCase.debug @ linux-x86_64 +DocTestCase.doctest.DocTestRunner @ linux-x86_64 +DocTestCase.doctest._TestClass @ linux-x86_64 +DocTestCase.doctest._TestClass.__init__ @ linux-x86_64 +DocTestCase.doctest._TestClass.get @ linux-x86_64 +DocTestCase.doctest._TestClass.square @ linux-x86_64 +DocTestCase.doctest.__test__.blank lines @ linux-x86_64 +DocTestCase.doctest.__test__.bool-int equivalence @ linux-x86_64 +DocTestCase.doctest.__test__.ellipsis @ linux-x86_64 +DocTestCase.doctest.__test__.string @ linux-x86_64 +DocTestCase.doctest.__test__.whitespace normalization @ linux-x86_64 +DocTestCase.doctest._ellipsis_match @ linux-x86_64 +DocTestCase.doctest.script_from_examples @ linux-x86_64 +DocTestCase.doctest.set_unittest_reportflags @ linux-x86_64 +test.test_doctest.TestDocTestFinder.test_empty_namespace_package @ linux-x86_64 +test.test_doctest.TestDocTestFinder.test_issue35753 @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_doctest2.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_doctest2.txt new file mode 100644 index 0000000000..cc5fc9cb5d --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_doctest2.txt @@ -0,0 +1 @@ +test.test_doctest2.Test.test_testmod @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_docxmlrpc.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_docxmlrpc.txt new file mode 100644 index 0000000000..8e10b69988 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_docxmlrpc.txt @@ -0,0 +1,9 @@ +test.test_docxmlrpc.DocXMLRPCHTTPGETServer.test_annotations @ linux-x86_64 +test.test_docxmlrpc.DocXMLRPCHTTPGETServer.test_autolink_dotted_methods @ linux-x86_64 +test.test_docxmlrpc.DocXMLRPCHTTPGETServer.test_autolinking @ linux-x86_64 +test.test_docxmlrpc.DocXMLRPCHTTPGETServer.test_get_css @ linux-x86_64 +test.test_docxmlrpc.DocXMLRPCHTTPGETServer.test_invalid_get_response @ linux-x86_64 +test.test_docxmlrpc.DocXMLRPCHTTPGETServer.test_lambda @ linux-x86_64 +test.test_docxmlrpc.DocXMLRPCHTTPGETServer.test_server_title_escape @ linux-x86_64 +test.test_docxmlrpc.DocXMLRPCHTTPGETServer.test_system_methods @ linux-x86_64 +test.test_docxmlrpc.DocXMLRPCHTTPGETServer.test_valid_get_response @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dynamic.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dynamic.txt new file mode 100644 index 0000000000..b075cbad44 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dynamic.txt @@ -0,0 +1,11 @@ +test.test_dynamic.RebindBuiltinsTests.test_cannot_change_globals_or_builtins_with_eval @ linux-x86_64 +test.test_dynamic.RebindBuiltinsTests.test_cannot_change_globals_or_builtins_with_exec @ linux-x86_64 +test.test_dynamic.RebindBuiltinsTests.test_cannot_replace_builtins_dict_between_calls @ linux-x86_64 +test.test_dynamic.RebindBuiltinsTests.test_cannot_replace_builtins_dict_while_active @ linux-x86_64 +test.test_dynamic.RebindBuiltinsTests.test_eval_gives_lambda_custom_globals @ linux-x86_64 +test.test_dynamic.RebindBuiltinsTests.test_globals_shadow_builtins @ linux-x86_64 +test.test_dynamic.RebindBuiltinsTests.test_load_global_specialization_failure_keeps_oparg @ linux-x86_64 +test.test_dynamic.RebindBuiltinsTests.test_modify_builtins @ linux-x86_64 +test.test_dynamic.RebindBuiltinsTests.test_modify_builtins_from_leaf_function @ linux-x86_64 +test.test_dynamic.RebindBuiltinsTests.test_modify_builtins_while_generator_active @ linux-x86_64 +test.test_dynamic.TestTracing.test_after_specialization @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dynamicclassattribute.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dynamicclassattribute.txt new file mode 100644 index 0000000000..9532001425 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_dynamicclassattribute.txt @@ -0,0 +1,11 @@ +test.test_dynamicclassattribute.PropertySubclassTests.test_docstring_copy @ linux-x86_64 +test.test_dynamicclassattribute.PropertySubclassTests.test_property_new_getter_new_docstring @ linux-x86_64 +test.test_dynamicclassattribute.PropertySubclassTests.test_property_setter_copies_getter_docstring @ linux-x86_64 +test.test_dynamicclassattribute.PropertyTests.test_abstract_virtual @ linux-x86_64 +test.test_dynamicclassattribute.PropertyTests.test_property___isabstractmethod__descriptor @ linux-x86_64 +test.test_dynamicclassattribute.PropertyTests.test_property_decorator_baseclass @ linux-x86_64 +test.test_dynamicclassattribute.PropertyTests.test_property_decorator_baseclass_doc @ linux-x86_64 +test.test_dynamicclassattribute.PropertyTests.test_property_decorator_doc @ linux-x86_64 +test.test_dynamicclassattribute.PropertyTests.test_property_decorator_subclass @ linux-x86_64 +test.test_dynamicclassattribute.PropertyTests.test_property_decorator_subclass_doc @ linux-x86_64 +test.test_dynamicclassattribute.PropertyTests.test_property_getter_doc_override @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_email.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_email.txt new file mode 100644 index 0000000000..15505206c9 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_email.txt @@ -0,0 +1,1659 @@ +test.test_email.test__encoded_words.TestDecode.test_b_case_ignored @ linux-x86_64 +test.test_email.test__encoded_words.TestDecode.test_b_invalid_bytes_ignored_with_defect @ linux-x86_64 +test.test_email.test__encoded_words.TestDecode.test_b_invalid_bytes_incorrect_padding @ linux-x86_64 +test.test_email.test__encoded_words.TestDecode.test_b_padding_defect @ linux-x86_64 +test.test_email.test__encoded_words.TestDecode.test_b_undecodable_bytes_ignored_with_defect @ linux-x86_64 +test.test_email.test__encoded_words.TestDecode.test_non_trivial_q @ linux-x86_64 +test.test_email.test__encoded_words.TestDecode.test_nonnull_lang @ linux-x86_64 +test.test_email.test__encoded_words.TestDecode.test_q_case_ignored @ linux-x86_64 +test.test_email.test__encoded_words.TestDecode.test_q_escaped_bytes_preserved @ linux-x86_64 +test.test_email.test__encoded_words.TestDecode.test_q_nonascii @ linux-x86_64 +test.test_email.test__encoded_words.TestDecode.test_simple_b @ linux-x86_64 +test.test_email.test__encoded_words.TestDecode.test_simple_q @ linux-x86_64 +test.test_email.test__encoded_words.TestDecode.test_unknown_8bit_charset @ linux-x86_64 +test.test_email.test__encoded_words.TestDecode.test_unknown_charset @ linux-x86_64 +test.test_email.test__encoded_words.TestDecode.test_wrong_format_input_raises @ linux-x86_64 +test.test_email.test__encoded_words.TestDecodeB.test_invalid_character @ linux-x86_64 +test.test_email.test__encoded_words.TestDecodeB.test_invalid_character_and_bad_padding @ linux-x86_64 +test.test_email.test__encoded_words.TestDecodeB.test_invalid_length @ linux-x86_64 +test.test_email.test__encoded_words.TestDecodeB.test_missing_padding @ linux-x86_64 +test.test_email.test__encoded_words.TestDecodeB.test_simple @ linux-x86_64 +test.test_email.test__encoded_words.TestDecodeQ.test_no_encoded @ linux-x86_64 +test.test_email.test__encoded_words.TestDecodeQ.test_run_of_encoded @ linux-x86_64 +test.test_email.test__encoded_words.TestDecodeQ.test_spaces @ linux-x86_64 +test.test_email.test__encoded_words.TestEncode.test_auto_b_if_enough_unsafe @ linux-x86_64 +test.test_email.test__encoded_words.TestEncode.test_auto_b_if_long_unsafe @ linux-x86_64 +test.test_email.test__encoded_words.TestEncode.test_auto_q @ linux-x86_64 +test.test_email.test__encoded_words.TestEncode.test_auto_q_if_long_mostly_safe @ linux-x86_64 +test.test_email.test__encoded_words.TestEncode.test_auto_q_if_short_mostly_safe @ linux-x86_64 +test.test_email.test__encoded_words.TestEncode.test_b @ linux-x86_64 +test.test_email.test__encoded_words.TestEncode.test_lang @ linux-x86_64 +test.test_email.test__encoded_words.TestEncode.test_q @ linux-x86_64 +test.test_email.test__encoded_words.TestEncode.test_unknown_8bit @ linux-x86_64 +test.test_email.test__encoded_words.TestEncode.test_utf8_default @ linux-x86_64 +test.test_email.test__encoded_words.TestEncodeB.test_padding @ linux-x86_64 +test.test_email.test__encoded_words.TestEncodeB.test_simple @ linux-x86_64 +test.test_email.test__encoded_words.TestEncodeQ.test_all_safe @ linux-x86_64 +test.test_email.test__encoded_words.TestEncodeQ.test_run_of_encodables @ linux-x86_64 +test.test_email.test__encoded_words.TestEncodeQ.test_spaces @ linux-x86_64 +test.test_email.test__header_value_parser.TestFolding.test_address_list_folding_at_commas @ linux-x86_64 +test.test_email.test__header_value_parser.TestFolding.test_address_list_with_unicode_names @ linux-x86_64 +test.test_email.test__header_value_parser.TestFolding.test_address_list_with_unicode_names_in_quotes @ linux-x86_64 +test.test_email.test__header_value_parser.TestFolding.test_ews_combined_before_wrap @ linux-x86_64 +test.test_email.test__header_value_parser.TestFolding.test_long_filename_attachment @ linux-x86_64 +test.test_email.test__header_value_parser.TestFolding.test_one_ew_on_each_of_two_wrapped_lines @ linux-x86_64 +test.test_email.test__header_value_parser.TestFolding.test_overlong_encodeable_is_wrapped @ linux-x86_64 +test.test_email.test__header_value_parser.TestFolding.test_simple_address @ linux-x86_64 +test.test_email.test__header_value_parser.TestFolding.test_simple_unstructured_folded @ linux-x86_64 +test.test_email.test__header_value_parser.TestFolding.test_simple_unstructured_no_folds @ linux-x86_64 +test.test_email.test__header_value_parser.TestFolding.test_split_at_whitespace_after_header_before_long_token @ linux-x86_64 +test.test_email.test__header_value_parser.TestFolding.test_split_at_whitespace_before_long_token @ linux-x86_64 +test.test_email.test__header_value_parser.TestFolding.test_unstructured_with_unicode_no_folds @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test__wsp_splitter_one_word @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test__wsp_splitter_two_words @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test__wsp_splitter_ws_runs @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_encoded_word_inside_quotes @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_addr_spec_dot_atom @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_addr_spec_ends_at_special @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_addr_spec_multiple_domains @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_addr_spec_normal @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_addr_spec_quoted_strings_in_atom_list @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_addr_spec_with_cfws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_addr_spec_with_doamin_literal @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_addr_spec_with_qouoted_string_and_cfws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_complex @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_empty_group @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_ends_at_special @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_group @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_invalid_mailbox_invalid @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_list_CFWS @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_list_group_and_mailboxes @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_list_group_empty @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_list_group_simple @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_list_mailboxes_complex @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_list_mailboxes_invalid_addresses @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_list_mailboxes_simple @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_list_mailboxes_two_simple @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_quoted_local_part @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_quoted_strings_in_atom_list @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_rfc2047_display_name @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_address_simple @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_angle_addr_empty @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_angle_addr_ends_at_special @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_angle_addr_internal_cfws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_angle_addr_missing_closing_angle @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_angle_addr_missing_closing_angle_with_cfws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_angle_addr_no_angle_before_special_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_angle_addr_no_angle_raise @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_angle_addr_no_angle_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_angle_addr_obs_route @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_angle_addr_qs_and_domain_literal @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_angle_addr_qs_only_quotes @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_angle_addr_simple @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_angle_addr_special_after_angle_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_angle_addr_with_cfws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atext_all_atext @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atext_following_wsp_preserved @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atext_non_printables @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atext_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atext_two_words_gets_first @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atext_up_to_special @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atom_atom_ends_at_noncfws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atom_atom_ends_at_special @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atom_header_ends_in_comment @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atom_no_atom @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atom_no_atom_before_special @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atom_non_printable_in_atext @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atom_non_printable_in_comment @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atom_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atom_rfc2047_atom @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atom_with_comments_and_wsp @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atom_with_multiple_comments @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_atom_with_wsp @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_bare_quoted_string_empty_quotes @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_bare_quoted_string_end_dquote_mid_word @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_bare_quoted_string_following_wsp_preserved @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_bare_quoted_string_missing_endquotes @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_bare_quoted_string_multiple_words @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_bare_quoted_string_multiple_words_wsp_preserved @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_bare_quoted_string_must_start_with_dquote @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_bare_quoted_string_no_end_dquote @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_bare_quoted_string_non_printables @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_bare_quoted_string_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_bare_quoted_string_only_quotes @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_bare_quoted_string_quoted_dquote @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_cfws_ends_at_non_leader @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_cfws_ends_at_non_printable @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_cfws_header_ends_in_comment @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_cfws_multiple_nested_comments @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_cfws_non_printable_in_comment @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_cfws_only_comment @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_cfws_only_mixed @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_cfws_only_ws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_comment_empty_comment @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_comment_end_paren_mid_word @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_comment_following_wsp_preserved @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_comment_missing_end_of_nesting @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_comment_multiple_nesting @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_comment_multiple_words @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_comment_multiple_words_wsp_preserved @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_comment_must_start_with_paren @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_comment_nested_comment @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_comment_nested_comment_wsp @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_comment_no_end_paren @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_comment_non_printable @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_comment_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_comment_qs_in_nested_comment @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_comment_quoted_parens @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_display_name_complex1 @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_display_name_complex2 @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_display_name_ending_with_obsolete @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_display_name_for_invalid_address_field @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_display_name_obsolete @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_display_name_pharse_must_start_with_word @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_display_name_simple @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_domain_domain_literal_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_domain_domain_literal_with_cfws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_domain_domain_literal_with_cfws_ends_at_special @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_domain_domain_with_cfws_ends_at_special @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_domain_literal_bad_dtext_char_before_special_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_domain_literal_no_start_char_before_special_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_domain_literal_no_start_char_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_domain_literal_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_domain_literal_with_internal_ws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_domain_literal_with_surrounding_cfws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_domain_no_atom_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_domain_no_non_cfws_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_domain_obsolete @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_domain_regular_domain_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_domain_with_cfws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_leading_dot_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_no_atom_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_rfc2047_atom @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_space_ends_dot_atom @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_text @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_text_lone_atom_is_valid @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_text_raises_on_leading_dot @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_text_raises_on_leading_non_atext @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_text_raises_on_trailing_dot @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_text_trailing_text_preserved @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_text_trailing_ws_preserved @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_trailing_dot_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_two_dots_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_with_comments_and_wsp @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dot_atom_with_wsp @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dtext_all_dtext @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dtext_close_bracket_mid_word @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dtext_following_wsp_preserved @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dtext_non_printables @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dtext_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dtext_open_bracket_mid_word @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dtext_two_words_gets_first @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dtext_up_to_close_bracket_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dtext_up_to_open_bracket_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dtext_with_qp @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dtext_wsp_before_close_bracket_preserved @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_dtext_wsp_before_open_bracket_preserved @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_encoded_word_gets_first @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_encoded_word_gets_first_even_if_no_space @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_encoded_word_internal_spaces @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_encoded_word_invalid_cte @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_encoded_word_lang_default_is_blank @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_encoded_word_leading_internal_space @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_encoded_word_missing_end_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_encoded_word_missing_middle_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_encoded_word_missing_start_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_encoded_word_non_printable_defect @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_encoded_word_quopri_utf_escape_follows_cte @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_encoded_word_sets_extra_attributes @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_encoded_word_valid_ew @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_fws_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_fws_space @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_fws_ws_run @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_group_cfws_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_group_empty @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_group_list_cfws_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_group_list_comment_only_invalid @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_group_list_mailbox_list @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_group_list_obs_group_list @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_group_missing_final_semicol @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_group_mixed_list @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_group_null_addr_spec @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_group_one_invalid @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_group_single_mailbox @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_complex_obsolete_1 @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_complex_obsolete_invalid @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_double_dot_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_leading_dot @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_leading_dot_after_ws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_no_part_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_quoted_strings_in_atom_list @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_quoted_with_cfws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_quoted_with_whitespace @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_simple @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_simple_obsolete @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_simple_quoted @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_special_instead_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_trailing_dot @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_trailing_dot_with_ws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_unicode_defect @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_valid_and_invalid_qp_in_atom_list @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_with_cfws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_with_dot @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_with_quoted_dot @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_local_part_with_whitespace @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_mailbox_addr_spec_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_mailbox_angle_addr_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_mailbox_ends_at_special @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_mailbox_list_empty_list_element @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_mailbox_list_junk_after_valid_address @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_mailbox_list_only_empty_elements @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_mailbox_list_single_addr @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_mailbox_list_two_complex @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_mailbox_list_two_name_addr @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_mailbox_list_two_simple_addr @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_mailbox_list_unparseable_mailbox_null @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_mailbox_name_addr @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_mailbox_quoted_strings_in_atom_list @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_msg_id_empty @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_msg_id_invalid_expected_msg_id_not_found @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_msg_id_no_angle_end @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_msg_id_no_angle_start @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_msg_id_no_id_right_part @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_msg_id_non_folding_literal_domain @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_msg_id_obsolete_domain_part @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_msg_id_obsolete_local @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_msg_id_valid @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_name_addr_angle_addr_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_name_addr_atom_name @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_name_addr_atom_name_with_cfws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_name_addr_ends_at_special @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_name_addr_name_with_cfws_and_dots @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_name_addr_no_angle_after_display_name_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_name_addr_no_content_before_special_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_name_addr_no_content_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_name_addr_qs_name @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_name_addr_with_route @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_obs_route_complex @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_obs_route_no_route_before_end_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_obs_route_no_route_before_special_raises @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_obs_route_no_route_before_special_raises2 @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_obs_route_simple @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_phrase_complex @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_phrase_ending_with_obsolete @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_phrase_obsolete @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_phrase_pharse_must_start_with_word @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_phrase_simple @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qcontent_all_printables @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qcontent_close_paren_mid_word @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qcontent_following_wsp_preserved @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qcontent_non_printables @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qcontent_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qcontent_two_words_gets_first @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qcontent_up_to_dquote_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qcontent_wsp_before_close_paren_preserved @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qp_ctext_all_printables @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qp_ctext_close_paren_mid_word @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qp_ctext_following_wsp_preserved @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qp_ctext_non_printables @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qp_ctext_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qp_ctext_open_paren_mid_word @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qp_ctext_two_words_gets_first @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qp_ctext_up_to_close_paren_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qp_ctext_up_to_open_paren_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qp_ctext_wsp_before_close_paren_preserved @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_qp_ctext_wsp_before_open_paren_preserved @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_quoted_string_header_ends_in_comment @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_quoted_string_header_ends_in_qcontent @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_quoted_string_internal_ws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_quoted_string_no_quoted_string @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_quoted_string_non_printable_in_comment @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_quoted_string_non_printable_in_qcontent @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_quoted_string_only @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_quoted_string_qs_ends_at_noncfws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_quoted_string_with_comments_and_wsp @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_quoted_string_with_multiple_comments @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_quoted_string_with_wsp @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_ew_with_internal_leading_ws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_ew_with_internal_ws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_ew_without_leading_whitespace @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_ew_without_trailing_whitespace @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_invalid_base64_character @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_invalid_base64_character_and_bad_padding @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_invalid_base64_length @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_invalid_ew @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_invalid_ew2 @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_invalid_ew_cte @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_leading_and_trailing_whitespace @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_leading_whitespace @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_missing_base64_padding @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_no_whitespace_between_ews @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_normal_phrase @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_normal_phrase_with_whitespace @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_null @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_one_ew_trailing_ws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_one_valid_ew_no_ws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_one_valid_ew_trailing_text @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_one_word @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_phrase_with_ew_in_middle_of_text @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_phrase_with_ew_with_leading_ws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_phrase_with_two_ew @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_phrase_with_two_ew_extra_ws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_phrase_with_two_ew_trailing_ws @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_trailing_whitespace @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_two_ew_extra_ws_trailing_text @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_undecodable_bytes @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_undecodable_bytes_in_EW @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_unstructured_without_trailing_whitespace_hang_case @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_word_all_CFWS @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_word_atom_yields_atom @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_word_ends_at_dot @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_get_word_qs_yields_qs @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_invalid_content_disposition @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_invalid_content_transfer_encoding @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_parse_invalid_message_id @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_parse_message_id_with_remaining @ linux-x86_64 +test.test_email.test__header_value_parser.TestParser.test_parse_valid_message_id @ linux-x86_64 +test.test_email.test__header_value_parser.TestTokens.test_EWWhiteSpaceTerminal @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_parameters.test_value_duplicate_and_missing_split_value @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_parameters.test_value_duplicate_in_split_value @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_parameters.test_value_duplicate_key @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_parameters.test_value_duplicate_key_with_split_value @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_parameters.test_value_duplicate_key_with_split_value_other_order @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_parameters.test_value_duplicate_with_broken_split_value @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_parameters.test_value_extra_dquote @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_parameters.test_value_missing_split_value @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_parameters.test_value_multiple_keys @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_parameters.test_value_simple @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_parameters.test_value_split_value @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_version.test_value_RFC_2045_2 @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_version.test_value_RFC_2045_3 @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_version.test_value_RFC_2045_4 @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_version.test_value_empty @ linux-x86_64 +test.test_email.test__header_value_parser.Test_parse_mime_version.test_value_rfc_2045_1 @ linux-x86_64 +test.test_email.test_asian_codecs.TestEmailAsianCodecs.test_japanese_codecs @ linux-x86_64 +test.test_email.test_asian_codecs.TestEmailAsianCodecs.test_payload_encoding @ linux-x86_64 +test.test_email.test_asian_codecs.TestEmailAsianCodecs.test_payload_encoding_utf8 @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_get_content_key_full_type @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_get_content_key_maintype_only @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_get_content_key_null_key @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_get_content_key_order_full_type @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_get_content_key_order_maintype_only @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_get_content_key_order_null_key @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_get_content_raises_if_unknown_mimetype_and_no_default @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_calls_clear_content @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_base_full_path @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_base_name @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_base_qualname @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_base_type @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_full_path @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_name @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_null_key @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_order_base_full_path @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_order_base_name @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_order_base_qualname @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_order_base_type @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_order_full_path @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_order_name @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_order_null_key @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_order_qualname @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_order_str_full_path @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_order_str_name @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_order_str_type @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_order_type @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_qualname @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_str_full_path @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_str_name @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_str_type @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_key_type @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_raises_if_called_on_multipart @ linux-x86_64 +test.test_email.test_contentmanager.TestContentManager.test_set_content_raises_if_unknown_type_and_no_default @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_cid_receiver_application_octet_stream @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_cid_receiver_image_jpeg @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_cid_receiver_message_external_body @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_cid_receiver_message_rfc822 @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_cid_receiver_text_html @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_cid_receiver_text_plain @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_disposition_inline_receiver_application_octet_stream @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_disposition_inline_receiver_image_jpeg @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_disposition_inline_receiver_message_external_body @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_disposition_inline_receiver_message_rfc822 @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_disposition_inline_receiver_text_html @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_disposition_inline_receiver_text_plain @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_get_message_non_rfc822_or_external_body_yields_bytes @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_get_message_rfc822_and_external_body @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_get_non_text @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_get_non_text_invalid_keyword @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_get_raises_on_multipart @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_get_text_html @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_get_text_invalid_keyword @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_get_text_plain @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_get_text_plain_bad_utf8_quoted_printable @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_get_text_plain_bad_utf8_quoted_printable_ignore_errors @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_get_text_plain_latin1 @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_get_text_plain_latin1_quoted_printable @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_get_text_plain_utf8_base64 @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_get_text_plain_utf8_base64_recoverable_bad_CTE_data @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_header_receiver_application_octet_stream @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_header_receiver_image_jpeg @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_header_receiver_message_external_body @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_header_receiver_message_rfc822 @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_header_receiver_text_html @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_header_receiver_text_plain @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_non_ascii_filename_receiver_application_octet_stream @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_non_ascii_filename_receiver_image_jpeg @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_non_ascii_filename_receiver_message_external_body @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_non_ascii_filename_receiver_message_rfc822 @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_non_ascii_filename_receiver_text_html @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_non_ascii_filename_receiver_text_plain @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_params_receiver_application_octet_stream @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_params_receiver_image_jpeg @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_params_receiver_message_external_body @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_params_receiver_message_rfc822 @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_params_receiver_text_html @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_params_receiver_text_plain @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_application_octet_stream_with_8bit_cte @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_content_bytes_cte_7bit @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_disposition_attachment @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_disposition_foo @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_disposition_inline @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_filename @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_filename_and_disposition_inline @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_headers_from_header_objects @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_headers_from_strings @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_headers_with_defective_header_header_raises @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_headers_with_defective_string_header_raises @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_headers_with_invalid_duplicate_header_header_raises @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_headers_with_invalid_duplicate_string_header_raises @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_image_jpg @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_message @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_message_invalid_cte_raises @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_message_with_non_ascii_and_coercion_to_7bit @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_non_ascii_filename @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_text_11_lines_long_line_maximal_non_ascii_heuristics @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_text_11_lines_long_line_minimal_non_ascii_heuristics @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_text_11_lines_maximal_non_ascii_heuristics @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_text_charset_latin_1 @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_text_html @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_text_long_line_maximal_non_ascii_heuristics @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_text_long_line_minimal_non_ascii_heuristics @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_text_maximal_non_ascii_heuristics @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_text_non_ascii_with_charset_ascii_raises @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_text_non_ascii_with_cte_7bit_and_charset_ascii_raises @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_text_non_ascii_with_cte_7bit_raises @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_text_plain @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_text_plain_long_line_heuristics @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_text_plain_null @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_text_short_line_minimal_non_ascii_heuristics @ linux-x86_64 +test.test_email.test_contentmanager.TestRawDataManager.test_set_video_mpeg_with_binary_cte @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectCapture.test_bad_padding_in_base64_payload @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectCapture.test_first_line_is_continuation_header @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectCapture.test_invalid_chars_in_base64_payload @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectCapture.test_invalid_length_of_base64_payload @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectCapture.test_lying_multipart @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectCapture.test_missing_ending_boundary @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectCapture.test_missing_header_body_separator @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectCapture.test_missing_start_boundary @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectCapture.test_multipart_invalid_cte @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectCapture.test_multipart_no_boundary @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectCapture.test_multipart_no_cte_no_defect @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectCapture.test_multipart_valid_cte_no_defect @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectCapture.test_same_boundary_inner_outer @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectDetection.test_bad_padding_in_base64_payload @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectDetection.test_first_line_is_continuation_header @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectDetection.test_invalid_chars_in_base64_payload @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectDetection.test_invalid_length_of_base64_payload @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectDetection.test_lying_multipart @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectDetection.test_missing_ending_boundary @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectDetection.test_missing_header_body_separator @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectDetection.test_missing_start_boundary @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectDetection.test_multipart_invalid_cte @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectDetection.test_multipart_no_boundary @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectDetection.test_multipart_no_cte_no_defect @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectDetection.test_multipart_valid_cte_no_defect @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectDetection.test_same_boundary_inner_outer @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectRaising.test_bad_padding_in_base64_payload @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectRaising.test_first_line_is_continuation_header @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectRaising.test_invalid_chars_in_base64_payload @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectRaising.test_invalid_length_of_base64_payload @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectRaising.test_lying_multipart @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectRaising.test_missing_header_body_separator @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectRaising.test_missing_start_boundary @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectRaising.test_multipart_invalid_cte @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectRaising.test_multipart_no_boundary @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectRaising.test_multipart_no_cte_no_defect @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectRaising.test_multipart_valid_cte_no_defect @ linux-x86_64 +test.test_email.test_defect_handling.TestDefectRaising.test_same_boundary_inner_outer @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_8bit_in_base64_body @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_8bit_in_quopri_body @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_8bit_in_uuencode_body @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_8bit_multipart @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_bytes_feedparser @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_bytes_generator @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_bytes_generator_b_encoding_linesep @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_bytes_generator_handles_None_body @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_bytes_generator_with_unix_from @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_crlf_flatten @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_decoded_generator_emits_unicode_body @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_del_rfc2231_params_with_8bit @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_generator_b_encoding_linesep @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_generator_handles_8bit @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_get_8bit_header @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_get_all_with_8bit_headers @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_get_content_type_with_8bit @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_get_params_with_8bit @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_get_payload_with_8bit_cte_header @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_get_rfc2231_params_with_8bit @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_invalid_8bit_in_non_8bit_cte_uses_replace @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_items_with_8bit_headers @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_known_8bit_CTE @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_message_from_binary_file @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_print_8bit_headers @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_set_rfc2231_params_with_8bit @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_str_generator_should_not_mutate_msg_when_handling_8bit @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_string_generator_reencodes_to_quopri_when_appropriate @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_unknown_8bit_CTE @ linux-x86_64 +test.test_email.test_email.Test8BitBytesHandling.test_values_with_8bit_headers @ linux-x86_64 +test.test_email.test_email.TestBase64.test_decode @ linux-x86_64 +test.test_email.test_email.TestBase64.test_encode @ linux-x86_64 +test.test_email.test_email.TestBase64.test_header_encode @ linux-x86_64 +test.test_email.test_email.TestBase64.test_len @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_MIME_digest @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_MIME_digest_with_part_headers @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_content_type @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_dsn @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_long_header @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_message_delivery_status @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_message_external_body_idempotent @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_message_signed_idempotent @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_mixed_with_image @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_more_rfc2231_parameters @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_multipart_no_parts @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_multipart_one_part @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_multipart_report @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_nested_multipart_mixeds @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_no_start_boundary @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_parse_text_message @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_parse_untyped_message @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_parser @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_preamble_epilogue @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_rfc2231_charset @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_simple_multipart @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentCRLF.test_text_plain_in_a_multipart_digest @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_MIME_digest @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_MIME_digest_with_part_headers @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_content_type @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_dsn @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_long_header @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_message_delivery_status @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_message_external_body_idempotent @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_message_signed_idempotent @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_mixed_with_image @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_more_rfc2231_parameters @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_multipart_no_parts @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_multipart_one_part @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_multipart_report @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_nested_multipart_mixeds @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_no_start_boundary @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_parse_text_message @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_parse_untyped_message @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_parser @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_preamble_epilogue @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_rfc2231_charset @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_simple_multipart @ linux-x86_64 +test.test_email.test_email.TestBytesGeneratorIdempotentNL.test_text_plain_in_a_multipart_digest @ linux-x86_64 +test.test_email.test_email.TestCharset.test_body_encode @ linux-x86_64 +test.test_email.test_email.TestCharset.test_codec_encodeable @ linux-x86_64 +test.test_email.test_email.TestCharset.test_unicode_charset_name @ linux-x86_64 +test.test_email.test_email.TestEncoders.test_EncodersEncode_base64 @ linux-x86_64 +test.test_email.test_email.TestEncoders.test_default_cte @ linux-x86_64 +test.test_email.test_email.TestEncoders.test_encode7or8bit @ linux-x86_64 +test.test_email.test_email.TestEncoders.test_encode_empty_payload @ linux-x86_64 +test.test_email.test_email.TestEncoders.test_qp_encode_latin1 @ linux-x86_64 +test.test_email.test_email.TestEncoders.test_qp_encode_non_latin1 @ linux-x86_64 +test.test_email.test_email.TestFeedParsers.test_empty_header_name_handled @ linux-x86_64 +test.test_email.test_email.TestFeedParsers.test_long_lines @ linux-x86_64 +test.test_email.test_email.TestFeedParsers.test_newlines @ linux-x86_64 +test.test_email.test_email.TestFromMangling.test_dont_mangle_from @ linux-x86_64 +test.test_email.test_email.TestFromMangling.test_mangle_from_in_preamble_and_epilog @ linux-x86_64 +test.test_email.test_email.TestFromMangling.test_mangled_from @ linux-x86_64 +test.test_email.test_email.TestFromMangling.test_mangled_from_with_bad_bytes @ linux-x86_64 +test.test_email.test_email.TestFromMangling.test_multipart_with_bad_bytes_in_cte @ linux-x86_64 +test.test_email.test_email.TestHeader.test_bad_8bit_header @ linux-x86_64 +test.test_email.test_email.TestHeader.test_base64_splittable @ linux-x86_64 +test.test_email.test_email.TestHeader.test_broken_base64_header @ linux-x86_64 +test.test_email.test_email.TestHeader.test_empty_header_encode @ linux-x86_64 +test.test_email.test_email.TestHeader.test_encode_preserves_leading_ws_on_value @ linux-x86_64 +test.test_email.test_email.TestHeader.test_encoded_adjacent_nonencoded @ linux-x86_64 +test.test_email.test_email.TestHeader.test_escaped_8bit_header @ linux-x86_64 +test.test_email.test_email.TestHeader.test_explicit_maxlinelen @ linux-x86_64 +test.test_email.test_email.TestHeader.test_flatten_header_with_no_value @ linux-x86_64 +test.test_email.test_email.TestHeader.test_header_ctor_default_args @ linux-x86_64 +test.test_email.test_email.TestHeader.test_header_handles_binary_unknown8bit @ linux-x86_64 +test.test_email.test_email.TestHeader.test_header_needs_no_decoding @ linux-x86_64 +test.test_email.test_email.TestHeader.test_long @ linux-x86_64 +test.test_email.test_email.TestHeader.test_make_header_handles_binary_unknown8bit @ linux-x86_64 +test.test_email.test_email.TestHeader.test_modify_returned_list_does_not_change_header @ linux-x86_64 +test.test_email.test_email.TestHeader.test_multilingual @ linux-x86_64 +test.test_email.test_email.TestHeader.test_quopri_splittable @ linux-x86_64 +test.test_email.test_email.TestHeader.test_shift_jis_charset @ linux-x86_64 +test.test_email.test_email.TestHeader.test_simple @ linux-x86_64 +test.test_email.test_email.TestHeader.test_simple_surprise @ linux-x86_64 +test.test_email.test_email.TestHeader.test_string_charset @ linux-x86_64 +test.test_email.test_email.TestHeader.test_us_ascii_header @ linux-x86_64 +test.test_email.test_email.TestHeader.test_utf8_shortest @ linux-x86_64 +test.test_email.test_email.TestHeader.test_whitespace_header @ linux-x86_64 +test.test_email.test_email.TestHeader.test_whitespace_keeper @ linux-x86_64 +test.test_email.test_email.TestHeaderRegistry.test_HeaderRegistry @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_MIME_digest @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_MIME_digest_with_part_headers @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_content_type @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_dsn @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_long_header @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_message_delivery_status @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_message_external_body_idempotent @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_message_signed_idempotent @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_mixed_with_image @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_more_rfc2231_parameters @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_multipart_no_parts @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_multipart_one_part @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_multipart_report @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_nested_multipart_mixeds @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_no_start_boundary @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_parse_text_message @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_parse_untyped_message @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_parser @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_preamble_epilogue @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_rfc2231_charset @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_simple_multipart @ linux-x86_64 +test.test_email.test_email.TestIdempotent.test_text_plain_in_a_multipart_digest @ linux-x86_64 +test.test_email.test_email.TestIterators.test_body_line_iterator @ linux-x86_64 +test.test_email.test_email.TestIterators.test_pushCR_LF @ linux-x86_64 +test.test_email.test_email.TestIterators.test_push_random @ linux-x86_64 +test.test_email.test_email.TestIterators.test_typed_subpart_iterator @ linux-x86_64 +test.test_email.test_email.TestIterators.test_typed_subpart_iterator_default_type @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_another_long_almost_unsplittable_header @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_another_long_multiline_header @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_header_encode_with_different_output_charset @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_header_splitter @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_last_split_chunk_does_not_fit @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_leading_splittable_in_the_middle_just_before_overlong_last_part @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_8bit_header @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_8bit_header_no_charset @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_field_name @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_header_encode @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_header_encode_with_different_output_charset @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_header_encode_with_tab_continuation @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_header_encode_with_tab_continuation_is_just_a_hint @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_header_with_multiple_sequential_split_chars @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_header_with_whitespace_runs @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_line_after_append @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_lines_with_different_header @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_nonstring @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_received_header @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_rfc2047_header_with_embedded_fws @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_run_with_semi_header_splitter @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_to_header @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_long_unbreakable_lines_with_continuation @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_multiline_with_overlong_last_part_followed_by_split_point @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_multiline_with_overlong_parts_separated_by_two_split_points @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_multiple_splittable_leading_char_followed_by_overlong_unsplittable @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_no_semis_header_splitter @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_no_split_long_header @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_overlong_last_part_followed_by_split_point @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_shorter_line_with_append @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_split_long_continuation @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_splittable_leading_char_followed_by_overlong_unsplittable @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_splitter_split_on_punctuation_only_if_fws @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_splitter_split_on_punctuation_only_if_fws_with_header @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_splitting_first_line_only_is_long @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_splitting_multiple_long_lines @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_string_headerinst_eq @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_trailing_splittable_on_overlong_unsplittable @ linux-x86_64 +test.test_email.test_email.TestLongHeaders.test_trailing_splittable_on_overlong_unsplittable_with_leading_splittable @ linux-x86_64 +test.test_email.test_email.TestMIMEApplication.test_binary_body_with_encode_7or8bit @ linux-x86_64 +test.test_email.test_email.TestMIMEApplication.test_binary_body_with_encode_base64 @ linux-x86_64 +test.test_email.test_email.TestMIMEApplication.test_binary_body_with_encode_noop @ linux-x86_64 +test.test_email.test_email.TestMIMEApplication.test_binary_body_with_encode_quopri @ linux-x86_64 +test.test_email.test_email.TestMIMEApplication.test_binary_body_with_unicode_linend_encode_noop @ linux-x86_64 +test.test_email.test_email.TestMIMEApplication.test_body @ linux-x86_64 +test.test_email.test_email.TestMIMEApplication.test_headers @ linux-x86_64 +test.test_email.test_email.TestMIMEAudio.test_add_header @ linux-x86_64 +test.test_email.test_email.TestMIMEAudio.test_checkSetMinor @ linux-x86_64 +test.test_email.test_email.TestMIMEAudio.test_encoding @ linux-x86_64 +test.test_email.test_email.TestMIMEAudio.test_guess_minor_type @ linux-x86_64 +test.test_email.test_email.TestMIMEImage.test_add_header @ linux-x86_64 +test.test_email.test_email.TestMIMEImage.test_checkSetMinor @ linux-x86_64 +test.test_email.test_email.TestMIMEImage.test_encoding @ linux-x86_64 +test.test_email.test_email.TestMIMEImage.test_guess_minor_type @ linux-x86_64 +test.test_email.test_email.TestMIMEMessage.test_bad_multipart @ linux-x86_64 +test.test_email.test_email.TestMIMEMessage.test_default_multipart_constructor @ linux-x86_64 +test.test_email.test_email.TestMIMEMessage.test_default_type @ linux-x86_64 +test.test_email.test_email.TestMIMEMessage.test_default_type_non_parsed @ linux-x86_64 +test.test_email.test_email.TestMIMEMessage.test_default_type_with_explicit_container_type @ linux-x86_64 +test.test_email.test_email.TestMIMEMessage.test_dsn @ linux-x86_64 +test.test_email.test_email.TestMIMEMessage.test_epilogue @ linux-x86_64 +test.test_email.test_email.TestMIMEMessage.test_generate @ linux-x86_64 +test.test_email.test_email.TestMIMEMessage.test_mime_attachments_in_constructor @ linux-x86_64 +test.test_email.test_email.TestMIMEMessage.test_multipart_custom_policy @ linux-x86_64 +test.test_email.test_email.TestMIMEMessage.test_multipart_default_policy @ linux-x86_64 +test.test_email.test_email.TestMIMEMessage.test_no_nl_preamble @ linux-x86_64 +test.test_email.test_email.TestMIMEMessage.test_parse_message_rfc822 @ linux-x86_64 +test.test_email.test_email.TestMIMEMessage.test_type_error @ linux-x86_64 +test.test_email.test_email.TestMIMEMessage.test_valid_argument @ linux-x86_64 +test.test_email.test_email.TestMIMEText.test_7bit_input @ linux-x86_64 +test.test_email.test_email.TestMIMEText.test_7bit_input_no_charset @ linux-x86_64 +test.test_email.test_email.TestMIMEText.test_charset @ linux-x86_64 +test.test_email.test_email.TestMIMEText.test_payload @ linux-x86_64 +test.test_email.test_email.TestMIMEText.test_types @ linux-x86_64 +test.test_email.test_email.TestMIMEText.test_utf8_input @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test__contains__ @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_add_header_with_name_only_param @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_add_header_with_no_value @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_as_bytes @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_as_bytes_policy @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_as_string @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_as_string_policy @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_ascii_add_header @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_ascii_add_header_with_tspecial @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_attach_when_payload_is_string @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_bad_param @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_binary_base64_payload @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_binary_quopri_payload @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_bogus_filename @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_broken_unicode_payload @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_byte_message_rfc822_only @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_decoded_generator @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_del_nonexistent_param @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_del_param @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_del_param_on_nonexistent_header @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_del_param_on_other_header @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_embedded_header_via_Header_rejected @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_embedded_header_via_string_rejected @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_field_containment @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_all @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_boundary @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_charsets @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_disposition @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_maintype_error @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_maintype_from_message_explicit @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_maintype_from_message_implicit @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_maintype_from_message_text_plain_explicit @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_maintype_from_message_text_plain_implicit @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_maintype_missing @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_maintype_missing_with_default_type @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_subtype_error @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_subtype_from_message_explicit @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_subtype_from_message_implicit @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_subtype_from_message_text_plain_explicit @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_subtype_from_message_text_plain_implicit @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_subtype_missing @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_subtype_missing_with_default_type @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_type_from_message_explicit @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_type_from_message_implicit @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_type_from_message_text_plain_explicit @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_type_from_message_text_plain_implicit @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_type_missing @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_content_type_missing_with_default_type @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_decoded_payload @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_filename @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_filename_with_name_parameter @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_param @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_param_funky_continuation_lines @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_param_liberal @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_param_with_quotes @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_param_with_semis_in_quotes @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_params @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_get_payload_n_raises_on_non_multipart @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_getset_charset @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_make_boundary @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_message_rfc822_only @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_missing_boundary @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_missing_filename @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_noascii_add_header @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_nonascii_add_header_via_triple @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_nonascii_add_header_with_tspecial @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_nonascii_as_string_without_content_type_and_cte @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_nonascii_as_string_without_cte @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_questionable_bytes_payload @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_replace_header @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_set_boundary @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_set_charset_from_string @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_set_param @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_set_payload_to_list @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_set_payload_with_8bit_data_and_charset @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_set_payload_with_8bit_data_and_charset_body_encoding_none @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_set_payload_with_charset @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_set_payload_with_non_ascii_and_charset_body_encoding_none @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_set_type @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_set_type_on_other_header @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_unicode_body_defaults_to_utf8_encoding @ linux-x86_64 +test.test_email.test_email.TestMessageAPI.test_unicode_header_defaults_to_utf8_encoding @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_BytesGenerator_linend @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_BytesGenerator_linend_with_non_ascii @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_Generator_linend @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test__all__ @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_accepts_any_charset_like_object @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_charset_richcomparisons @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_charsets_case_insensitive @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_custom_message_does_not_require_arguments @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_escape_backslashes @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_escape_dump @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_formataddr_does_not_quote_parens_in_quoted_string @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_formatdate @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_formatdate_localtime @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_formatdate_usegmt @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_get_body_encoding_with_bogus_charset @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_get_body_encoding_with_uppercase_charset @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_getaddresses @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_getaddresses_embedded_comment @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_getaddresses_header_obj @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_getaddresses_nasty @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_invalid_charset_like_object_raises_error @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_make_msgid_collisions @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_make_msgid_default_domain @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_make_msgid_domain @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_make_msgid_idstring @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_message_from_file @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_message_from_file_with_class @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_message_from_string @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_message_from_string_with_class @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_mime_classes_policy_argument @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_mktime_tz @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_multiline_from_comment @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_name_with_dot @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_noquote_dump @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_parseaddr_empty @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_parseaddr_multiple_domains @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_parseaddr_preserves_quoted_pairs_in_addresses @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_parseaddr_preserves_spaces_in_local_part @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_parsedate_acceptable_to_time_functions @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_parsedate_accepts_time_with_dots @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_parsedate_compact @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_parsedate_dot_time_delimiter @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_parsedate_no_dayofweek @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_parsedate_no_seconds @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_parsedate_no_space_before_negative_offset @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_parsedate_no_space_before_positive_offset @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_parsedate_returns_None_for_invalid_strings @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_parsedate_rfc_850 @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_parsedate_y2k @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_partial_falls_inside_message_delivery_status @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_quote_dump @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_quotes_unicode_names @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_unicode_address_raises_error @ linux-x86_64 +test.test_email.test_email.TestMiscellaneous.test_utils_quote_unquote @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_boundary_in_non_multipart @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_boundary_with_leading_space @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_boundary_without_trailing_newline @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_double_boundary @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_empty_multipart_idempotent @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_hierarchy @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_message_external_body @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_mimebase_custom_policy @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_mimebase_default_policy @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_nested_inner_contains_outer_boundary @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_nested_with_same_boundary @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_no_parts_in_a_multipart_with_empty_epilogue @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_no_parts_in_a_multipart_with_none_epilogue @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_one_part_in_a_multipart @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_seq_parts_in_a_multipart_with_empty_epilogue @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_seq_parts_in_a_multipart_with_empty_preamble @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_seq_parts_in_a_multipart_with_nl_epilogue @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_seq_parts_in_a_multipart_with_none_epilogue @ linux-x86_64 +test.test_email.test_email.TestMultipart.test_seq_parts_in_a_multipart_with_none_preamble @ linux-x86_64 +test.test_email.test_email.TestNonConformant.test_first_line_is_continuation_header @ linux-x86_64 +test.test_email.test_email.TestNonConformant.test_invalid_content_type @ linux-x86_64 +test.test_email.test_email.TestNonConformant.test_lying_multipart @ linux-x86_64 +test.test_email.test_email.TestNonConformant.test_missing_header_body_separator @ linux-x86_64 +test.test_email.test_email.TestNonConformant.test_missing_start_boundary @ linux-x86_64 +test.test_email.test_email.TestNonConformant.test_multipart_invalid_cte @ linux-x86_64 +test.test_email.test_email.TestNonConformant.test_multipart_no_boundary @ linux-x86_64 +test.test_email.test_email.TestNonConformant.test_multipart_no_cte_no_defect @ linux-x86_64 +test.test_email.test_email.TestNonConformant.test_multipart_valid_cte_no_defect @ linux-x86_64 +test.test_email.test_email.TestNonConformant.test_no_separating_blank_line @ linux-x86_64 +test.test_email.test_email.TestNonConformant.test_no_start_boundary @ linux-x86_64 +test.test_email.test_email.TestNonConformant.test_parse_missing_minor_type @ linux-x86_64 +test.test_email.test_email.TestNonConformant.test_same_boundary_inner_outer @ linux-x86_64 +test.test_email.test_email.TestNonMultipart.test_attach_raises_exception @ linux-x86_64 +test.test_email.test_email.TestNonMultipart.test_nonmultipart_is_not_multipart @ linux-x86_64 +test.test_email.test_email.TestParsers.test_CRLFLF_at_end_of_part @ linux-x86_64 +test.test_email.test_email.TestParsers.test_bytes_header_parser @ linux-x86_64 +test.test_email.test_email.TestParsers.test_bytes_parser_does_not_close_file @ linux-x86_64 +test.test_email.test_email.TestParsers.test_bytes_parser_on_exception_does_not_close_file @ linux-x86_64 +test.test_email.test_email.TestParsers.test_crlf_flatten @ linux-x86_64 +test.test_email.test_email.TestParsers.test_crlf_separation @ linux-x86_64 +test.test_email.test_email.TestParsers.test_header_parser @ linux-x86_64 +test.test_email.test_email.TestParsers.test_header_parser_multipart_is_valid @ linux-x86_64 +test.test_email.test_email.TestParsers.test_multipart_digest_with_extra_mime_headers @ linux-x86_64 +test.test_email.test_email.TestParsers.test_parser_does_not_close_file @ linux-x86_64 +test.test_email.test_email.TestParsers.test_parser_on_exception_does_not_close_file @ linux-x86_64 +test.test_email.test_email.TestParsers.test_rfc2822_header_syntax @ linux-x86_64 +test.test_email.test_email.TestParsers.test_rfc2822_one_character_header @ linux-x86_64 +test.test_email.test_email.TestParsers.test_rfc2822_space_not_allowed_in_header @ linux-x86_64 +test.test_email.test_email.TestParsers.test_strip_line_feed_and_carriage_return_in_headers @ linux-x86_64 +test.test_email.test_email.TestParsers.test_three_lines @ linux-x86_64 +test.test_email.test_email.TestParsers.test_whitespace_continuation @ linux-x86_64 +test.test_email.test_email.TestParsers.test_whitespace_continuation_last_header @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_body_quopri_len @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_false_quoting @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_lowercase_quoting @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_multiple_spaces @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_null_line_null_word @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_null_word @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_one_line @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_one_line_cr @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_one_line_crnl @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_one_line_lf @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_one_line_nl @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_one_line_one_word @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_one_line_one_word_eol @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_one_line_trailing_spaces @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_one_long_line @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_one_space @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_one_word @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_one_word_eol @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_quoted_word @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_soft_line_break @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_two_lines @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_two_lines_eol @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_two_lines_trailing_spaces @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_decode_uppercase_quoting @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_maxlinelen_too_small @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_null @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_null_lines @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_one_line @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_one_line_crlf @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_one_line_eol @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_one_line_eol_after_non_ascii @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_one_line_one_space @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_one_line_trailing_spaces @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_one_line_trailing_tab @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_one_long_line @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_one_long_string @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_one_space @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_one_very_long_line @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_one_word_trailing_spaces @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_one_word_trailing_tab @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_quoted_equals @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_shortest_maxlinelen @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_trailing_space_at_maxlinelen @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_trailing_space_before_maxlinelen @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_trailing_space_beyond_maxlinelen @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_two_lines_one_space @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_encode_whitespace_lines @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_header_decode_non_ascii @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_header_decode_null @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_header_decode_one_word @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_header_decode_re_bug_18380 @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_header_decode_two_lines @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_header_encode_alt_charset @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_header_encode_non_ascii @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_header_encode_null @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_header_encode_one_word @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_header_encode_two_lines @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_header_quopri_len @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_quopri_body_check @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_quopri_header_check @ linux-x86_64 +test.test_email.test_email.TestQuopri.test_quote_unquote_idempotent @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_multiline_header @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_rfc2047_B_bad_padding @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_rfc2047_Q_invalid_digits @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_rfc2047_missing_whitespace @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_rfc2047_multiline @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_rfc2047_rfc2047_1 @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_rfc2047_rfc2047_2 @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_rfc2047_rfc2047_3 @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_rfc2047_rfc2047_4 @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_rfc2047_rfc2047_5a @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_rfc2047_rfc2047_5b @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_rfc2047_rfc2047_6 @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_rfc2047_rfc2047_7 @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_rfc2047_with_whitespace @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_whitespace_keeper_unicode @ linux-x86_64 +test.test_email.test_email.TestRFC2047.test_whitespace_keeper_unicode_2 @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_del_param @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_get_param @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_bad_character_in_charset @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_bad_character_in_encoding @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_bad_character_in_filename @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_bad_encoding_in_charset @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_bad_encoding_in_filename @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_encoded_then_unencoded_segments @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_get_content_charset @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_missing_tick @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_missing_tick_with_encoded_non_ascii @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_no_extended_values @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_no_language_or_charset @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_no_language_or_charset_in_boundary @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_no_language_or_charset_in_charset @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_no_language_or_charset_in_filename @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_no_language_or_charset_in_filename_encoded @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_parse_extra_quoting @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_parse_rfc_quoting @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_partly_encoded @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_partly_nonencoded @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_single_tick_in_filename @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_single_tick_in_filename_extended @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_tick_attack @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_tick_attack_extended @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_unencoded_then_encoded_segments @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_rfc2231_unknown_encoding @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_set_param @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_set_param_requote @ linux-x86_64 +test.test_email.test_email.TestRFC2231.test_should_not_hang_on_invalid_ew_messages @ linux-x86_64 +test.test_email.test_email.TestSigned.test_long_headers_as_string @ linux-x86_64 +test.test_email.test_email.TestSigned.test_long_headers_as_string_maxheaderlen @ linux-x86_64 +test.test_email.test_email.TestSigned.test_long_headers_flatten @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_compat32_max_line_length_does_not_fold_when_none @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_crlf_control_via_policy @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_cte_type_7bit_handles_unknown_8bit @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_cte_type_7bit_transforms_8bit_cte @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_flatten_linesep_overrides_policy @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_max_line_length_policy_0 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_max_line_length_policy_100 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_max_line_length_policy_20 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_max_line_length_policy_40 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_max_line_length_with_refold_all_folds_0 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_max_line_length_with_refold_all_folds_100 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_max_line_length_with_refold_all_folds_20 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_max_line_length_with_refold_all_folds_40 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_max_line_length_with_refold_none_does_not_fold_0 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_max_line_length_with_refold_none_does_not_fold_100 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_max_line_length_with_refold_none_does_not_fold_20 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_max_line_length_with_refold_none_does_not_fold_40 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_maxheaderlen_parameter_0 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_maxheaderlen_parameter_100 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_maxheaderlen_parameter_20 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_maxheaderlen_parameter_40 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_maxheaderlen_parm_overrides_policy_0 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_maxheaderlen_parm_overrides_policy_100 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_maxheaderlen_parm_overrides_policy_20 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_maxheaderlen_parm_overrides_policy_40 @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_rfc2231_wrapping @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_rfc2231_wrapping_switches_to_default_len_if_too_narrow @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_set_mangle_from_via_policy @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_smtp_policy @ linux-x86_64 +test.test_email.test_generator.TestBytesGenerator.test_smtputf8_policy @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_compat32_max_line_length_does_not_fold_when_none @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_crlf_control_via_policy @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_flatten_linesep_overrides_policy @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_max_line_length_policy_0 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_max_line_length_policy_100 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_max_line_length_policy_20 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_max_line_length_policy_40 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_max_line_length_with_refold_all_folds_0 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_max_line_length_with_refold_all_folds_100 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_max_line_length_with_refold_all_folds_20 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_max_line_length_with_refold_all_folds_40 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_max_line_length_with_refold_none_does_not_fold_0 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_max_line_length_with_refold_none_does_not_fold_100 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_max_line_length_with_refold_none_does_not_fold_20 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_max_line_length_with_refold_none_does_not_fold_40 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_maxheaderlen_parameter_0 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_maxheaderlen_parameter_100 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_maxheaderlen_parameter_20 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_maxheaderlen_parameter_40 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_maxheaderlen_parm_overrides_policy_0 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_maxheaderlen_parm_overrides_policy_100 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_maxheaderlen_parm_overrides_policy_20 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_maxheaderlen_parm_overrides_policy_40 @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_rfc2231_wrapping @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_rfc2231_wrapping_switches_to_default_len_if_too_narrow @ linux-x86_64 +test.test_email.test_generator.TestGenerator.test_set_mangle_from_via_policy @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_address_addr_spec_and_domain_raises @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_address_addr_spec_and_username_and_domain_raises @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_address_addr_spec_and_username_raises @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_address_comparison @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_address_display_name_ro @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_address_domain_ro @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_address_from_addr_spec @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_address_from_username_domain @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_address_username_ro @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_address_with_no_display_name @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_bad_addr_sepc_raises @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_crlf_in_constructor_args_raises @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_display_name_blanks_not_quoted @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_display_name_only @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_display_name_quoting @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_domain_only @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_empty_group @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_empty_group_list @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_group_addresses_ro @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_group_comparison @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_group_display_name_ro @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_group_with_addresses @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_group_with_addresses_no_display_name @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_group_with_one_address_no_display_name @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_il8n @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_non_ascii_username_in_addr_spec_raises @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_null_address @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_null_group @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_quoting @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_set_message_header_from_address @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_set_message_header_from_group @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_space_in_addr_spec_username_raises @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressAndGroup.test_username_only @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_address_only @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_empty @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_escaped_escapes_in_local_part @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_escaped_quoted_strings_in_local_part @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_name_and_address @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_name_with_dot @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_quoted_backslashes_in_name @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_quoted_local_part @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_quoted_parens_in_name @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_quoted_strings_in_local_part @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_read_only @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_rfc2047_atom_in_phrase_is_decoded @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_rfc2047_atom_in_quoted_string_is_decoded @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_rfc2047_atom_is_decoded @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_spaces_around_dots_in_local_part_removed @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_address_spaces_in_unquoted_local_part_collapsed @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_addresses_read_only @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_addresses_types @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_complex_address_list @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_group_address_only @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_group_empty @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_group_escaped_escapes_in_local_part @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_group_escaped_quoted_strings_in_local_part @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_group_name_and_address @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_group_name_with_dot @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_group_quoted_backslashes_in_name @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_group_quoted_local_part @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_group_quoted_parens_in_name @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_group_quoted_strings_in_local_part @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_group_rfc2047_atom_in_phrase_is_decoded @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_group_rfc2047_atom_in_quoted_string_is_decoded @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_group_rfc2047_atom_is_decoded @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_group_spaces_around_dots_in_local_part_removed @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_group_spaces_in_unquoted_local_part_collapsed @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_groups_read_only @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_groups_types @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_set_from_Address @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_set_from_Address_and_Group_list @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_set_from_Address_list @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_set_from_Group_list @ linux-x86_64 +test.test_email.test_headerregistry.TestAddressHeader.test_simple_address_list @ linux-x86_64 +test.test_email.test_headerregistry.TestBaseHeaderFeatures.test_defects_is_tuple @ linux-x86_64 +test.test_email.test_headerregistry.TestBaseHeaderFeatures.test_defects_read_only @ linux-x86_64 +test.test_email.test_headerregistry.TestBaseHeaderFeatures.test_has_name @ linux-x86_64 +test.test_email.test_headerregistry.TestBaseHeaderFeatures.test_name_read_only @ linux-x86_64 +test.test_email.test_headerregistry.TestBaseHeaderFeatures.test_str @ linux-x86_64 +test.test_email.test_headerregistry.TestBaseHeaderFeatures.test_substr @ linux-x86_64 +test.test_email.test_headerregistry.TestContentDisposition.test_value_RFC_2183_1 @ linux-x86_64 +test.test_email.test_headerregistry.TestContentDisposition.test_value_RFC_2183_2 @ linux-x86_64 +test.test_email.test_headerregistry.TestContentDisposition.test_value_invalid_parameter_value_with_fws_between_ew @ linux-x86_64 +test.test_email.test_headerregistry.TestContentDisposition.test_value_invalid_value @ linux-x86_64 +test.test_email.test_headerregistry.TestContentDisposition.test_value_invalid_value_with_params @ linux-x86_64 +test.test_email.test_headerregistry.TestContentDisposition.test_value_no_value @ linux-x86_64 +test.test_email.test_headerregistry.TestContentDisposition.test_value_parameter_value_with_fws_between_tokens @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTransferEncoding.test_value_RFC_2183_1 @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTransferEncoding.test_value_junk_after_cte @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTransferEncoding.test_value_no_value @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_RFC_2045_1 @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_RFC_2045_2 @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_RFC_2045_3 @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_bad_params @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_capitalized_charset @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_capitalized_charset_param_name_and_comment @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_cfws_in_content_type @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_charset_param @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_double_quotes_inside_quotes @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_junk_text_in_content_type @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_lots_of_mime_params @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_mixed_case_content_type @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_no_slash_in_content_type @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_no_subtype_in_content_type @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_non_ascii_in_params @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_non_ascii_rfc2231_value @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_param_value_with_tspecials @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_param_with_extra_quoted_whitespace @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_quotes_inside_rfc2231_value @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_bad_character_in_charset_parameter_value @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_encoded_charset @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_encoded_no_charset @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_encoded_no_double_quotes @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_encoded_then_unencoded_segments @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_encoded_with_double_quotes @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_folded_segments_correctly_formatted @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_no_language_or_charset @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_nonascii_in_charset_of_charset_parameter_value @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_partly_encoded @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_partly_encoded_2 @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_quoted_unencoded_then_encoded_segments @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_segmented_normal_values @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_single_quote_in_non_encoded_value @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_single_quote_in_value_with_charset_and_lang @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_single_quote_inside_double_quotes @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_unencoded_then_encoded_segments @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_unknown_charset_treated_as_ascii @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_rfc2231_utf8_in_supposedly_ascii_charset_parameter_value @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_semis_inside_quotes @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_single_quotes_inside_quotes @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_spaces_around_param_equals @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_spaces_around_semis @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_spaces_in_content_type @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_too_many_slashes_in_content_type @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_unknown_charset @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_unknown_content_type @ linux-x86_64 +test.test_email.test_headerregistry.TestContentTypeHeader.test_value_unquoted_param_value @ linux-x86_64 +test.test_email.test_headerregistry.TestDateHeader.test_date_header_properties @ linux-x86_64 +test.test_email.test_headerregistry.TestDateHeader.test_datetime_read_only @ linux-x86_64 +test.test_email.test_headerregistry.TestDateHeader.test_invalid_date_format @ linux-x86_64 +test.test_email.test_headerregistry.TestDateHeader.test_invalid_date_value @ linux-x86_64 +test.test_email.test_headerregistry.TestDateHeader.test_no_value_is_defect @ linux-x86_64 +test.test_email.test_headerregistry.TestDateHeader.test_parse_date @ linux-x86_64 +test.test_email.test_headerregistry.TestDateHeader.test_resent_date_header_properties @ linux-x86_64 +test.test_email.test_headerregistry.TestDateHeader.test_set_date_header_from_datetime @ linux-x86_64 +test.test_email.test_headerregistry.TestDateHeader.test_set_from_datetime @ linux-x86_64 +test.test_email.test_headerregistry.TestFolding.test_address_display_names @ linux-x86_64 +test.test_email.test_headerregistry.TestFolding.test_fold_address_list @ linux-x86_64 +test.test_email.test_headerregistry.TestFolding.test_fold_date_header @ linux-x86_64 +test.test_email.test_headerregistry.TestFolding.test_fold_overlong_words_using_RFC2047 @ linux-x86_64 +test.test_email.test_headerregistry.TestFolding.test_fold_unstructured_short @ linux-x86_64 +test.test_email.test_headerregistry.TestFolding.test_fold_unstructured_single_word @ linux-x86_64 +test.test_email.test_headerregistry.TestFolding.test_fold_unstructured_with_commas @ linux-x86_64 +test.test_email.test_headerregistry.TestFolding.test_fold_unstructured_with_overlong_word @ linux-x86_64 +test.test_email.test_headerregistry.TestFolding.test_fold_unstructured_with_slightly_long_word @ linux-x86_64 +test.test_email.test_headerregistry.TestFolding.test_fold_unstructured_with_two_overlong_words @ linux-x86_64 +test.test_email.test_headerregistry.TestFolding.test_long_unstructured @ linux-x86_64 +test.test_email.test_headerregistry.TestFolding.test_message_id_header_is_not_folded @ linux-x86_64 +test.test_email.test_headerregistry.TestFolding.test_short_unstructured @ linux-x86_64 +test.test_email.test_headerregistry.TestFolding.test_unstructured_short_max_line_length @ linux-x86_64 +test.test_email.test_headerregistry.TestHeaderRegistry.test_arbitrary_name_unstructured @ linux-x86_64 +test.test_email.test_headerregistry.TestHeaderRegistry.test_dont_use_default_map @ linux-x86_64 +test.test_email.test_headerregistry.TestHeaderRegistry.test_map_to_type @ linux-x86_64 +test.test_email.test_headerregistry.TestHeaderRegistry.test_name_case_ignored @ linux-x86_64 +test.test_email.test_headerregistry.TestHeaderRegistry.test_override_default_base_class @ linux-x86_64 +test.test_email.test_headerregistry.TestHeaderRegistry.test_override_default_class @ linux-x86_64 +test.test_email.test_headerregistry.TestHeaderRegistry.test_override_default_class_only_overrides_default @ linux-x86_64 +test.test_email.test_headerregistry.TestMIMEVersionHeader.test_MIME_Version_1_1 @ linux-x86_64 +test.test_email.test_headerregistry.TestMIMEVersionHeader.test_MIME_Version_2_1 @ linux-x86_64 +test.test_email.test_headerregistry.TestMIMEVersionHeader.test_MIME_Version_2_x @ linux-x86_64 +test.test_email.test_headerregistry.TestMIMEVersionHeader.test_MIME_Version_RFC_2045_1 @ linux-x86_64 +test.test_email.test_headerregistry.TestMIMEVersionHeader.test_MIME_Version_RFC_2045_2 @ linux-x86_64 +test.test_email.test_headerregistry.TestMIMEVersionHeader.test_MIME_Version_RFC_2045_3 @ linux-x86_64 +test.test_email.test_headerregistry.TestMIMEVersionHeader.test_MIME_Version_RFC_2045_4 @ linux-x86_64 +test.test_email.test_headerregistry.TestMIMEVersionHeader.test_MIME_Version_foo @ linux-x86_64 +test.test_email.test_headerregistry.TestMIMEVersionHeader.test_MIME_Version_leading_trailing_whitespace_ignored @ linux-x86_64 +test.test_email.test_headerregistry.TestMIMEVersionHeader.test_MIME_Version_missing @ linux-x86_64 +test.test_email.test_headerregistry.TestMIMEVersionHeader.test_MIME_Version_non_comment_garbage_after @ linux-x86_64 +test.test_email.test_headerregistry.TestMIMEVersionHeader.test_MIME_Version_non_comment_garbage_before @ linux-x86_64 +test.test_email.test_headerregistry.TestMIMEVersionHeader.test_MIME_Version_non_comment_garbage_inside @ linux-x86_64 +test.test_email.test_headerregistry.TestMIMEVersionHeader.test_MIME_Version_two_periods @ linux-x86_64 +test.test_email.test_headerregistry.TestMIMEVersionHeader.test_MIME_Version_whitespace @ linux-x86_64 +test.test_email.test_headerregistry.TestUnstructuredHeader.test_value_rfc2047_gb2312_base64 @ linux-x86_64 +test.test_email.test_headerregistry.TestUnstructuredHeader.test_value_rfc2047_quopri_with_regular_text @ linux-x86_64 +test.test_email.test_headerregistry.TestUnstructuredHeader.test_value_rfc2047_simple_nonascii_quopri @ linux-x86_64 +test.test_email.test_headerregistry.TestUnstructuredHeader.test_value_rfc2047_simple_quopri @ linux-x86_64 +test.test_email.test_inversion.TestInversion.test_body_base64_text @ linux-x86_64 +test.test_email.test_inversion.TestInversion.test_body_plain_text @ linux-x86_64 +test.test_email.test_inversion.TestInversion.test_body_qp_text @ linux-x86_64 +test.test_email.test_inversion.TestInversion.test_input_header_with_invalid_date @ linux-x86_64 +test.test_email.test_inversion.TestInversion.test_input_header_with_one_space_body @ linux-x86_64 +test.test_email.test_message.Test.test_error_on_setitem_if_max_count_exceeded @ linux-x86_64 +test.test_email.test_message.Test.test_rfc2043_auto_decoded_and_emailmessage_used @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_alternative_alternative_ @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_alternative_mixed_raises @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_alternative_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_alternative_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_alternative_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_alternative_related_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_mixed_alternative_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_mixed_mixed_ @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_mixed_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_mixed_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_mixed_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_mixed_related_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_related_alternative_raises @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_related_mixed_raises @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_related_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_related_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_related_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_add_related_related_ @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_as_string_allows_maxheaderlen @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_as_string_unixform @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_as_string_uses_max_header_length_by_default @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_content_empty_message @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_content_html_text_attachment_inline_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_content_html_text_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_content_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_content_mime_non_text @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_content_mixed_alternative_plain_related @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_content_mixed_related_alternative_plain_html @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_content_mixed_related_alternative_plain_html_wrong_order @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_content_mixed_text_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_content_non_mime_plain @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_content_plain_html_alternative @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_content_plain_html_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_content_plain_html_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_content_related @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_content_related_with_start @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_empty_message @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_html_text_attachment_inline_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_html_text_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_mime_non_text @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_mixed_alternative_plain_related @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_mixed_related_alternative_plain_html @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_mixed_related_alternative_plain_html_wrong_order @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_mixed_text_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_non_mime_plain @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_plain_html_alternative @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_plain_html_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_plain_html_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_related @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_clear_related_with_start @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_default_content_manager_for_add_comes_from_policy @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_folding_with_utf8_encoding_1 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_folding_with_utf8_encoding_2 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_folding_with_utf8_encoding_3 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_folding_with_utf8_encoding_4 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_folding_with_utf8_encoding_5 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_folding_with_utf8_encoding_6 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_folding_with_utf8_encoding_7 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_folding_with_utf8_encoding_8 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_empty_message @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_html_text_attachment_inline_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_html_text_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_malformed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_mime_non_text @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_mixed_alternative_plain_related @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_mixed_related_alternative_plain_html @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_mixed_related_alternative_plain_html_wrong_order @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_mixed_text_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_non_mime_plain @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_plain_html_alternative @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_plain_html_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_plain_html_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_related @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_body_related_with_start @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_content_default_cm_comes_from_policy @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_get_content_with_cm @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_is_attachment @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachment_empty_message @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachment_html_text_attachment_inline_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachment_html_text_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachment_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachment_mime_non_text @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachment_mixed_alternative_plain_related @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachment_mixed_related_alternative_plain_html @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachment_mixed_related_alternative_plain_html_wrong_order @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachment_mixed_text_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachment_non_mime_plain @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachment_plain_html_alternative @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachment_plain_html_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachment_plain_html_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachment_related @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachment_related_with_start @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_attachments_mutation @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_parts_empty_message @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_parts_html_text_attachment_inline_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_parts_html_text_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_parts_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_parts_mime_non_text @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_parts_mixed_alternative_plain_related @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_parts_mixed_related_alternative_plain_html @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_parts_mixed_related_alternative_plain_html_wrong_order @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_parts_mixed_text_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_parts_non_mime_plain @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_parts_plain_html_alternative @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_parts_plain_html_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_parts_plain_html_mixed @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_parts_related @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_iter_parts_related_with_start @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_alternative_alternative_ @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_alternative_mixed_raises @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_alternative_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_alternative_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_alternative_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_alternative_related_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_mixed_alternative_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_mixed_mixed_ @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_mixed_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_mixed_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_mixed_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_mixed_related_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_related_alternative_raises @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_related_mixed_raises @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_related_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_related_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_related_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_related_related_ @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_alternative_alternative_ @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_alternative_mixed_raises @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_alternative_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_alternative_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_alternative_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_alternative_related_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_mixed_alternative_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_mixed_mixed_ @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_mixed_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_mixed_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_mixed_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_mixed_related_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_related_alternative_raises @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_related_mixed_raises @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_related_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_related_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_related_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_make_with_boundary_related_related_ @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_policy_on_part_made_by_make_comes_from_message @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_set_content_adds_MIME_Version @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_set_content_default_cm_comes_from_policy @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_set_content_does_not_duplicate_MIME_Version @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_set_content_with_cm @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_str_defaults_to_policy_max_line_length @ linux-x86_64 +test.test_email.test_message.TestEmailMessage.test_str_defaults_to_utf8 @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_alternative_alternative_ @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_alternative_mixed_raises @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_alternative_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_alternative_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_alternative_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_alternative_related_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_mixed_alternative_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_mixed_mixed_ @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_mixed_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_mixed_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_mixed_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_mixed_related_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_related_alternative_raises @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_related_mixed_raises @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_related_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_related_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_related_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_add_related_related_ @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_content_empty_message @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_content_html_text_attachment_inline_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_content_html_text_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_content_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_content_mime_non_text @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_content_mixed_alternative_plain_related @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_content_mixed_related_alternative_plain_html @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_content_mixed_related_alternative_plain_html_wrong_order @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_content_mixed_text_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_content_non_mime_plain @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_content_plain_html_alternative @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_content_plain_html_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_content_plain_html_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_content_related @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_content_related_with_start @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_empty_message @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_html_text_attachment_inline_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_html_text_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_mime_non_text @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_mixed_alternative_plain_related @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_mixed_related_alternative_plain_html @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_mixed_related_alternative_plain_html_wrong_order @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_mixed_text_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_non_mime_plain @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_plain_html_alternative @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_plain_html_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_plain_html_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_related @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_clear_related_with_start @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_default_content_manager_for_add_comes_from_policy @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_body_empty_message @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_body_html_text_attachment_inline_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_body_html_text_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_body_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_body_mime_non_text @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_body_mixed_alternative_plain_related @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_body_mixed_related_alternative_plain_html @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_body_mixed_related_alternative_plain_html_wrong_order @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_body_mixed_text_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_body_non_mime_plain @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_body_plain_html_alternative @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_body_plain_html_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_body_plain_html_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_body_related @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_body_related_with_start @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_content_default_cm_comes_from_policy @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_get_content_with_cm @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_is_attachment @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachment_empty_message @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachment_html_text_attachment_inline_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachment_html_text_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachment_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachment_mime_non_text @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachment_mixed_alternative_plain_related @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachment_mixed_related_alternative_plain_html @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachment_mixed_related_alternative_plain_html_wrong_order @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachment_mixed_text_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachment_non_mime_plain @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachment_plain_html_alternative @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachment_plain_html_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachment_plain_html_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachment_related @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachment_related_with_start @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_attachments_mutation @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_parts_empty_message @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_parts_html_text_attachment_inline_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_parts_html_text_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_parts_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_parts_mime_non_text @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_parts_mixed_alternative_plain_related @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_parts_mixed_related_alternative_plain_html @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_parts_mixed_related_alternative_plain_html_wrong_order @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_parts_mixed_text_message_rfc822 @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_parts_non_mime_plain @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_parts_plain_html_alternative @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_parts_plain_html_attachment_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_parts_plain_html_mixed @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_parts_related @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_iter_parts_related_with_start @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_alternative_alternative_ @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_alternative_mixed_raises @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_alternative_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_alternative_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_alternative_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_alternative_related_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_mixed_alternative_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_mixed_mixed_ @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_mixed_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_mixed_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_mixed_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_mixed_related_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_related_alternative_raises @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_related_mixed_raises @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_related_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_related_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_related_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_related_related_ @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_alternative_alternative_ @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_alternative_mixed_raises @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_alternative_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_alternative_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_alternative_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_alternative_related_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_mixed_alternative_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_mixed_mixed_ @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_mixed_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_mixed_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_mixed_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_mixed_related_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_related_alternative_raises @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_related_mixed_raises @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_related_no_content_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_related_none_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_related_plain_succeeds @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_make_with_boundary_related_related_ @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_policy_on_part_made_by_make_comes_from_message @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_set_content_default_cm_comes_from_policy @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_set_content_does_not_add_MIME_Version @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_set_content_with_cm @ linux-x86_64 +test.test_email.test_message.TestMIMEPart.test_string_payload_with_multipart_content_type @ linux-x86_64 +test.test_email.test_parser.TestBytesParser.test_custom_message_factory_on_policy @ linux-x86_64 +test.test_email.test_parser.TestBytesParser.test_factory_arg_overrides_policy @ linux-x86_64 +test.test_email.test_parser.TestBytesParser.test_only_split_on_cr_lf @ linux-x86_64 +test.test_email.test_parser.TestCustomMessage.test_custom_message_gets_policy_if_possible_from_file @ linux-x86_64 +test.test_email.test_parser.TestCustomMessage.test_custom_message_gets_policy_if_possible_from_string @ linux-x86_64 +test.test_email.test_parser.TestParser.test_custom_message_factory_on_policy @ linux-x86_64 +test.test_email.test_parser.TestParser.test_factory_arg_overrides_policy @ linux-x86_64 +test.test_email.test_parser.TestParser.test_only_split_on_cr_lf @ linux-x86_64 +test.test_email.test_pickleable.TestPickleCopyHeader.test_deepcopy_date @ linux-x86_64 +test.test_email.test_pickleable.TestPickleCopyHeader.test_deepcopy_from @ linux-x86_64 +test.test_email.test_pickleable.TestPickleCopyHeader.test_deepcopy_subject @ linux-x86_64 +test.test_email.test_pickleable.TestPickleCopyHeader.test_deepcopy_to @ linux-x86_64 +test.test_email.test_pickleable.TestPickleCopyHeader.test_pickle_date @ linux-x86_64 +test.test_email.test_pickleable.TestPickleCopyHeader.test_pickle_from @ linux-x86_64 +test.test_email.test_pickleable.TestPickleCopyHeader.test_pickle_subject @ linux-x86_64 +test.test_email.test_pickleable.TestPickleCopyHeader.test_pickle_to @ linux-x86_64 +test.test_email.test_pickleable.TestPickleCopyMessage.test_deepcopy_created @ linux-x86_64 +test.test_email.test_pickleable.TestPickleCopyMessage.test_deepcopy_parsed @ linux-x86_64 +test.test_email.test_pickleable.TestPickleCopyMessage.test_pickle_created @ linux-x86_64 +test.test_email.test_pickleable.TestPickleCopyMessage.test_pickle_parsed @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_abc @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_adding_default_policies_preserves_default_factory @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_all_attributes_covered @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_clone_copies_factory @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_default_header_factory @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_defaults @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_each_Policy_gets_unique_factory @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_fold_zero_max_line_length @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_handle_defect_raises_on_strict @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_handle_defect_registers_defect @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_new_factory_overrides_default @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_non_ascii_chars_do_not_cause_inf_loop @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_overridden_register_defect_still_raises @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_overridden_register_defect_works @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_policy_addition @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_policy_is_immutable @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_register_defect @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_reject_non_policy_keyword_when_called @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_set_policy_attrs_when_cloned @ linux-x86_64 +test.test_email.test_policy.PolicyAPITests.test_short_maxlen_error @ linux-x86_64 +test.test_email.test_policy.TestConcretePolicies.test_header_store_parse_rejects_newlines @ linux-x86_64 +test.test_email.test_policy.TestPolicyPropagation.test_bytes_parser @ linux-x86_64 +test.test_email.test_policy.TestPolicyPropagation.test_message_from_binary_file @ linux-x86_64 +test.test_email.test_policy.TestPolicyPropagation.test_message_from_bytes @ linux-x86_64 +test.test_email.test_policy.TestPolicyPropagation.test_message_from_file @ linux-x86_64 +test.test_email.test_policy.TestPolicyPropagation.test_message_from_string @ linux-x86_64 +test.test_email.test_policy.TestPolicyPropagation.test_message_policy_propagates_to_generator @ linux-x86_64 +test.test_email.test_policy.TestPolicyPropagation.test_message_policy_used_by_as_string @ linux-x86_64 +test.test_email.test_policy.TestPolicyPropagation.test_parser @ linux-x86_64 +test.test_email.test_policy.TestPolicyPropagation.test_parser_propagates_policy_to_message @ linux-x86_64 +test.test_email.test_policy.TestPolicyPropagation.test_parser_propagates_policy_to_sub_messages @ linux-x86_64 +test.test_email.test_utils.DateTimeTests.test_aware_datetime @ linux-x86_64 +test.test_email.test_utils.DateTimeTests.test_naive_datetime @ linux-x86_64 +test.test_email.test_utils.DateTimeTests.test_parsedate_to_datetime @ linux-x86_64 +test.test_email.test_utils.DateTimeTests.test_parsedate_to_datetime_naive @ linux-x86_64 +test.test_email.test_utils.DateTimeTests.test_parsedate_to_datetime_with_invalid_raises_valueerror @ linux-x86_64 +test.test_email.test_utils.DateTimeTests.test_usegmt @ linux-x86_64 +test.test_email.test_utils.DateTimeTests.test_usegmt_with_naive_datetime_raises @ linux-x86_64 +test.test_email.test_utils.DateTimeTests.test_usegmt_with_non_utc_datetime_raises @ linux-x86_64 +test.test_email.test_utils.LocaltimeTests.test_localtime_daylight_false_dst_false @ linux-x86_64 +test.test_email.test_utils.LocaltimeTests.test_localtime_daylight_false_dst_true @ linux-x86_64 +test.test_email.test_utils.LocaltimeTests.test_localtime_daylight_true_dst_false @ linux-x86_64 +test.test_email.test_utils.LocaltimeTests.test_localtime_daylight_true_dst_true @ linux-x86_64 +test.test_email.test_utils.LocaltimeTests.test_localtime_epoch_notz_daylight_false @ linux-x86_64 +test.test_email.test_utils.LocaltimeTests.test_localtime_epoch_notz_daylight_true @ linux-x86_64 +test.test_email.test_utils.LocaltimeTests.test_localtime_epoch_utc_daylight_false @ linux-x86_64 +test.test_email.test_utils.LocaltimeTests.test_localtime_epoch_utc_daylight_true @ linux-x86_64 +test.test_email.test_utils.LocaltimeTests.test_localtime_is_tz_aware_daylight_false @ linux-x86_64 +test.test_email.test_utils.LocaltimeTests.test_localtime_is_tz_aware_daylight_true @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ensurepip.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ensurepip.txt new file mode 100644 index 0000000000..4c357b2ef0 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ensurepip.txt @@ -0,0 +1,30 @@ +test.test_ensurepip.TestBootstrap.test_altinstall_default_pip_conflict @ linux-x86_64 +test.test_ensurepip.TestBootstrap.test_basic_bootstrapping @ linux-x86_64 +test.test_ensurepip.TestBootstrap.test_bootstrapping_with_alt_install @ linux-x86_64 +test.test_ensurepip.TestBootstrap.test_bootstrapping_with_default_pip @ linux-x86_64 +test.test_ensurepip.TestBootstrap.test_bootstrapping_with_regular_install @ linux-x86_64 +test.test_ensurepip.TestBootstrap.test_bootstrapping_with_root @ linux-x86_64 +test.test_ensurepip.TestBootstrap.test_bootstrapping_with_upgrade @ linux-x86_64 +test.test_ensurepip.TestBootstrap.test_bootstrapping_with_user @ linux-x86_64 +test.test_ensurepip.TestBootstrap.test_bootstrapping_with_verbosity_1 @ linux-x86_64 +test.test_ensurepip.TestBootstrap.test_bootstrapping_with_verbosity_2 @ linux-x86_64 +test.test_ensurepip.TestBootstrap.test_bootstrapping_with_verbosity_3 @ linux-x86_64 +test.test_ensurepip.TestBootstrap.test_pip_config_file_disabled @ linux-x86_64 +test.test_ensurepip.TestBootstrap.test_pip_environment_variables_removed @ linux-x86_64 +test.test_ensurepip.TestBootstrappingMainFunction.test_basic_bootstrapping @ linux-x86_64 +test.test_ensurepip.TestBootstrappingMainFunction.test_bootstrap_version @ linux-x86_64 +test.test_ensurepip.TestBootstrappingMainFunction.test_bootstrapping_error_code @ linux-x86_64 +test.test_ensurepip.TestPackages.test_get_packages_no_dir @ linux-x86_64 +test.test_ensurepip.TestPackages.test_get_packages_with_dir @ linux-x86_64 +test.test_ensurepip.TestPackages.test_version @ linux-x86_64 +test.test_ensurepip.TestUninstall.test_pip_config_file_disabled @ linux-x86_64 +test.test_ensurepip.TestUninstall.test_pip_environment_variables_removed @ linux-x86_64 +test.test_ensurepip.TestUninstall.test_uninstall @ linux-x86_64 +test.test_ensurepip.TestUninstall.test_uninstall_skipped_when_not_installed @ linux-x86_64 +test.test_ensurepip.TestUninstall.test_uninstall_skipped_with_warning_for_wrong_version @ linux-x86_64 +test.test_ensurepip.TestUninstall.test_uninstall_with_verbosity_1 @ linux-x86_64 +test.test_ensurepip.TestUninstall.test_uninstall_with_verbosity_2 @ linux-x86_64 +test.test_ensurepip.TestUninstall.test_uninstall_with_verbosity_3 @ linux-x86_64 +test.test_ensurepip.TestUninstallationMainFunction.test_basic_uninstall @ linux-x86_64 +test.test_ensurepip.TestUninstallationMainFunction.test_uninstall_error_code @ linux-x86_64 +test.test_ensurepip.TestUninstallationMainFunction.test_uninstall_version @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_enum.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_enum.txt new file mode 100644 index 0000000000..be63ac457f --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_enum.txt @@ -0,0 +1,586 @@ +DocTestCase.enum.Enum @ linux-x86_64 +DocTestCase.enum._simple_enum @ linux-x86_64 +DocTestCase.enum._test_simple_enum @ linux-x86_64 +DocTestCase.enum.bin @ linux-x86_64 +test.test_enum.MiscTestCase.test__all__ @ linux-x86_64 +test.test_enum.MiscTestCase.test_doc_1 @ linux-x86_64 +test.test_enum.MiscTestCase.test_doc_2 @ linux-x86_64 +test.test_enum.MiscTestCase.test_doc_3 @ linux-x86_64 +test.test_enum.MiscTestCase.test_doc_4 @ linux-x86_64 +test.test_enum.OldTestFlag.test_aliases @ linux-x86_64 +test.test_enum.OldTestFlag.test_and @ linux-x86_64 +test.test_enum.OldTestFlag.test_auto_number @ linux-x86_64 +test.test_enum.OldTestFlag.test_auto_number_garbage @ linux-x86_64 +test.test_enum.OldTestFlag.test_bool @ linux-x86_64 +test.test_enum.OldTestFlag.test_boundary @ linux-x86_64 +test.test_enum.OldTestFlag.test_contains_er @ linux-x86_64 +test.test_enum.OldTestFlag.test_duplicate_auto @ linux-x86_64 +test.test_enum.OldTestFlag.test_init_subclass @ linux-x86_64 +test.test_enum.OldTestFlag.test_iter @ linux-x86_64 +test.test_enum.OldTestFlag.test_member_contains @ linux-x86_64 +test.test_enum.OldTestFlag.test_member_iter @ linux-x86_64 +test.test_enum.OldTestFlag.test_member_length @ linux-x86_64 +test.test_enum.OldTestFlag.test_multiple_mixin @ linux-x86_64 +test.test_enum.OldTestFlag.test_number_reset_and_order_cleanup @ linux-x86_64 +test.test_enum.OldTestFlag.test_or @ linux-x86_64 +test.test_enum.OldTestFlag.test_pickle @ linux-x86_64 +test.test_enum.OldTestFlag.test_programatic_function_from_dict @ linux-x86_64 +test.test_enum.OldTestFlag.test_programatic_function_iterable @ linux-x86_64 +test.test_enum.OldTestFlag.test_programatic_function_string @ linux-x86_64 +test.test_enum.OldTestFlag.test_programatic_function_string_list @ linux-x86_64 +test.test_enum.OldTestFlag.test_programatic_function_string_with_start @ linux-x86_64 +test.test_enum.OldTestFlag.test_unique_composite @ linux-x86_64 +test.test_enum.OldTestFlag.test_xor @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_aliases @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_and @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_bool @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_boundary @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_contains_er @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_format @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_global_enum_str @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_global_repr_conform1 @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_global_repr_keep @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_invert @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_iter @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_member_contains @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_member_iter @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_member_length @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_multiple_mixin @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_or @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_programatic_function_from_dict @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_programatic_function_from_empty_list @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_programatic_function_from_empty_tuple @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_programatic_function_iterable @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_programatic_function_string @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_programatic_function_string_list @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_programatic_function_string_with_start @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_type @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_unique_composite @ linux-x86_64 +test.test_enum.OldTestIntFlag.test_xor @ linux-x86_64 +test.test_enum.TestConvert.test_convert_complex @ linux-x86_64 +test.test_enum.TestConvert.test_convert_int @ linux-x86_64 +test.test_enum.TestConvert.test_convert_raise @ linux-x86_64 +test.test_enum.TestConvert.test_convert_repr_and_str @ linux-x86_64 +test.test_enum.TestConvert.test_convert_str @ linux-x86_64 +test.test_enum.TestConvert.test_convert_uncomparable @ linux-x86_64 +test.test_enum.TestConvert.test_convert_value_lookup_priority @ linux-x86_64 +test.test_enum.TestEmptyAndNonLatinStrings.test_empty_string @ linux-x86_64 +test.test_enum.TestEmptyAndNonLatinStrings.test_non_latin_character_string @ linux-x86_64 +test.test_enum.TestEmptyAndNonLatinStrings.test_non_latin_number_string @ linux-x86_64 +test.test_enum.TestHelpers.test_dunder @ linux-x86_64 +test.test_enum.TestHelpers.test_is_descriptor @ linux-x86_64 +test.test_enum.TestHelpers.test_is_private @ linux-x86_64 +test.test_enum.TestHelpers.test_iter_bits_lsb @ linux-x86_64 +test.test_enum.TestHelpers.test_sunder @ linux-x86_64 +test.test_enum.TestIntEnum.test_attribute_deletion @ linux-x86_64 +test.test_enum.TestIntEnum.test_bad_new_super @ linux-x86_64 +test.test_enum.TestIntEnum.test_basics @ linux-x86_64 +test.test_enum.TestIntEnum.test_bool_is_true @ linux-x86_64 +test.test_enum.TestIntEnum.test_changing_member_fails @ linux-x86_64 +test.test_enum.TestIntEnum.test_contains_er @ linux-x86_64 +test.test_enum.TestIntEnum.test_copy @ linux-x86_64 +test.test_enum.TestIntEnum.test_copy_member @ linux-x86_64 +test.test_enum.TestIntEnum.test_dir_on_class @ linux-x86_64 +test.test_enum.TestIntEnum.test_dir_on_item @ linux-x86_64 +test.test_enum.TestIntEnum.test_dir_on_sub_with_behavior_including_instance_dict_on_super @ linux-x86_64 +test.test_enum.TestIntEnum.test_dir_on_sub_with_behavior_on_super @ linux-x86_64 +test.test_enum.TestIntEnum.test_dir_with_added_behavior @ linux-x86_64 +test.test_enum.TestIntEnum.test_enum_in_enum_out @ linux-x86_64 +test.test_enum.TestIntEnum.test_format @ linux-x86_64 +test.test_enum.TestIntEnum.test_format_specs @ linux-x86_64 +test.test_enum.TestIntEnum.test_hash @ linux-x86_64 +test.test_enum.TestIntEnum.test_inherited_repr @ linux-x86_64 +test.test_enum.TestIntEnum.test_invalid_names @ linux-x86_64 +test.test_enum.TestIntEnum.test_multiple_superclasses_repr @ linux-x86_64 +test.test_enum.TestIntEnum.test_object_str_override @ linux-x86_64 +test.test_enum.TestIntEnum.test_overridden_format @ linux-x86_64 +test.test_enum.TestIntEnum.test_overridden_str @ linux-x86_64 +test.test_enum.TestIntEnum.test_overridden_str_format @ linux-x86_64 +test.test_enum.TestIntEnum.test_overridden_str_format_inherited @ linux-x86_64 +test.test_enum.TestIntEnum.test_programmatic_function_from_dict @ linux-x86_64 +test.test_enum.TestIntEnum.test_programmatic_function_iterable @ linux-x86_64 +test.test_enum.TestIntEnum.test_programmatic_function_string @ linux-x86_64 +test.test_enum.TestIntEnum.test_programmatic_function_string_list @ linux-x86_64 +test.test_enum.TestIntEnum.test_repr @ linux-x86_64 +test.test_enum.TestIntEnum.test_repr_override @ linux-x86_64 +test.test_enum.TestIntEnum.test_reversed_iteration_order @ linux-x86_64 +test.test_enum.TestIntEnum.test_str @ linux-x86_64 +test.test_enum.TestIntFlag.test_attribute_deletion @ linux-x86_64 +test.test_enum.TestIntFlag.test_bad_new_super @ linux-x86_64 +test.test_enum.TestIntFlag.test_basics @ linux-x86_64 +test.test_enum.TestIntFlag.test_bool_is_true @ linux-x86_64 +test.test_enum.TestIntFlag.test_changing_member_fails @ linux-x86_64 +test.test_enum.TestIntFlag.test_closed_invert_expectations @ linux-x86_64 +test.test_enum.TestIntFlag.test_contains_er @ linux-x86_64 +test.test_enum.TestIntFlag.test_copy @ linux-x86_64 +test.test_enum.TestIntFlag.test_copy_member @ linux-x86_64 +test.test_enum.TestIntFlag.test_default_missing_with_wrong_type_value @ linux-x86_64 +test.test_enum.TestIntFlag.test_dir_on_class @ linux-x86_64 +test.test_enum.TestIntFlag.test_dir_on_item @ linux-x86_64 +test.test_enum.TestIntFlag.test_dir_on_sub_with_behavior_including_instance_dict_on_super @ linux-x86_64 +test.test_enum.TestIntFlag.test_dir_on_sub_with_behavior_on_super @ linux-x86_64 +test.test_enum.TestIntFlag.test_dir_with_added_behavior @ linux-x86_64 +test.test_enum.TestIntFlag.test_enum_in_enum_out @ linux-x86_64 +test.test_enum.TestIntFlag.test_format @ linux-x86_64 +test.test_enum.TestIntFlag.test_format_specs @ linux-x86_64 +test.test_enum.TestIntFlag.test_hash @ linux-x86_64 +test.test_enum.TestIntFlag.test_inherited_repr @ linux-x86_64 +test.test_enum.TestIntFlag.test_invalid_names @ linux-x86_64 +test.test_enum.TestIntFlag.test_multiple_superclasses_repr @ linux-x86_64 +test.test_enum.TestIntFlag.test_object_str_override @ linux-x86_64 +test.test_enum.TestIntFlag.test_open_invert_expectations @ linux-x86_64 +test.test_enum.TestIntFlag.test_overridden_format @ linux-x86_64 +test.test_enum.TestIntFlag.test_overridden_str @ linux-x86_64 +test.test_enum.TestIntFlag.test_overridden_str_format @ linux-x86_64 +test.test_enum.TestIntFlag.test_overridden_str_format_inherited @ linux-x86_64 +test.test_enum.TestIntFlag.test_programmatic_function_from_dict @ linux-x86_64 +test.test_enum.TestIntFlag.test_programmatic_function_iterable @ linux-x86_64 +test.test_enum.TestIntFlag.test_programmatic_function_string @ linux-x86_64 +test.test_enum.TestIntFlag.test_programmatic_function_string_list @ linux-x86_64 +test.test_enum.TestIntFlag.test_repr @ linux-x86_64 +test.test_enum.TestIntFlag.test_repr_override @ linux-x86_64 +test.test_enum.TestIntFlag.test_reversed_iteration_order @ linux-x86_64 +test.test_enum.TestIntFlag.test_str @ linux-x86_64 +test.test_enum.TestInternals.test_auto_garbage_corrected_ok @ linux-x86_64 +test.test_enum.TestInternals.test_auto_garbage_ok @ linux-x86_64 +test.test_enum.TestInternals.test_auto_name @ linux-x86_64 +test.test_enum.TestInternals.test_auto_name_inherit @ linux-x86_64 +test.test_enum.TestInternals.test_auto_number @ linux-x86_64 +test.test_enum.TestInternals.test_auto_order @ linux-x86_64 +test.test_enum.TestInternals.test_auto_order_wierd @ linux-x86_64 +test.test_enum.TestInternals.test_dunder @ linux-x86_64 +test.test_enum.TestInternals.test_duplicate_auto @ linux-x86_64 +test.test_enum.TestInternals.test_is_private @ linux-x86_64 +test.test_enum.TestInternals.test_multiple_auto_on_line @ linux-x86_64 +test.test_enum.TestInternals.test_sunder @ linux-x86_64 +test.test_enum.TestMinimalDate.test_attribute_deletion @ linux-x86_64 +test.test_enum.TestMinimalDate.test_bad_new_super @ linux-x86_64 +test.test_enum.TestMinimalDate.test_basics @ linux-x86_64 +test.test_enum.TestMinimalDate.test_bool_is_true @ linux-x86_64 +test.test_enum.TestMinimalDate.test_changing_member_fails @ linux-x86_64 +test.test_enum.TestMinimalDate.test_contains_er @ linux-x86_64 +test.test_enum.TestMinimalDate.test_copy @ linux-x86_64 +test.test_enum.TestMinimalDate.test_copy_member @ linux-x86_64 +test.test_enum.TestMinimalDate.test_dir_on_class @ linux-x86_64 +test.test_enum.TestMinimalDate.test_dir_on_item @ linux-x86_64 +test.test_enum.TestMinimalDate.test_dir_on_sub_with_behavior_including_instance_dict_on_super @ linux-x86_64 +test.test_enum.TestMinimalDate.test_dir_on_sub_with_behavior_on_super @ linux-x86_64 +test.test_enum.TestMinimalDate.test_dir_with_added_behavior @ linux-x86_64 +test.test_enum.TestMinimalDate.test_enum_in_enum_out @ linux-x86_64 +test.test_enum.TestMinimalDate.test_format @ linux-x86_64 +test.test_enum.TestMinimalDate.test_format_specs @ linux-x86_64 +test.test_enum.TestMinimalDate.test_hash @ linux-x86_64 +test.test_enum.TestMinimalDate.test_inherited_repr @ linux-x86_64 +test.test_enum.TestMinimalDate.test_invalid_names @ linux-x86_64 +test.test_enum.TestMinimalDate.test_multiple_superclasses_repr @ linux-x86_64 +test.test_enum.TestMinimalDate.test_object_str_override @ linux-x86_64 +test.test_enum.TestMinimalDate.test_overridden_format @ linux-x86_64 +test.test_enum.TestMinimalDate.test_overridden_str @ linux-x86_64 +test.test_enum.TestMinimalDate.test_overridden_str_format @ linux-x86_64 +test.test_enum.TestMinimalDate.test_overridden_str_format_inherited @ linux-x86_64 +test.test_enum.TestMinimalDate.test_programmatic_function_from_dict @ linux-x86_64 +test.test_enum.TestMinimalDate.test_programmatic_function_iterable @ linux-x86_64 +test.test_enum.TestMinimalDate.test_programmatic_function_string @ linux-x86_64 +test.test_enum.TestMinimalDate.test_programmatic_function_string_list @ linux-x86_64 +test.test_enum.TestMinimalDate.test_repr @ linux-x86_64 +test.test_enum.TestMinimalDate.test_repr_override @ linux-x86_64 +test.test_enum.TestMinimalDate.test_reversed_iteration_order @ linux-x86_64 +test.test_enum.TestMinimalDate.test_str @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_attribute_deletion @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_bad_new_super @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_basics @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_bool_is_true @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_changing_member_fails @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_contains_er @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_copy @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_copy_member @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_dir_on_class @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_dir_on_item @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_dir_on_sub_with_behavior_including_instance_dict_on_super @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_dir_on_sub_with_behavior_on_super @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_dir_with_added_behavior @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_enum_in_enum_out @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_format @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_format_specs @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_hash @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_inherited_repr @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_invalid_names @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_multiple_superclasses_repr @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_object_str_override @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_overridden_format @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_overridden_str @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_overridden_str_format @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_overridden_str_format_inherited @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_programmatic_function_from_dict @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_programmatic_function_iterable @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_programmatic_function_string @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_programmatic_function_string_list @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_repr @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_repr_override @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_reversed_iteration_order @ linux-x86_64 +test.test_enum.TestMinimalFloat.test_str @ linux-x86_64 +test.test_enum.TestMixedDate.test_attribute_deletion @ linux-x86_64 +test.test_enum.TestMixedDate.test_bad_new_super @ linux-x86_64 +test.test_enum.TestMixedDate.test_basics @ linux-x86_64 +test.test_enum.TestMixedDate.test_bool_is_true @ linux-x86_64 +test.test_enum.TestMixedDate.test_changing_member_fails @ linux-x86_64 +test.test_enum.TestMixedDate.test_contains_er @ linux-x86_64 +test.test_enum.TestMixedDate.test_dir_on_class @ linux-x86_64 +test.test_enum.TestMixedDate.test_dir_on_item @ linux-x86_64 +test.test_enum.TestMixedDate.test_dir_on_sub_with_behavior_including_instance_dict_on_super @ linux-x86_64 +test.test_enum.TestMixedDate.test_dir_on_sub_with_behavior_on_super @ linux-x86_64 +test.test_enum.TestMixedDate.test_dir_with_added_behavior @ linux-x86_64 +test.test_enum.TestMixedDate.test_enum_in_enum_out @ linux-x86_64 +test.test_enum.TestMixedDate.test_format @ linux-x86_64 +test.test_enum.TestMixedDate.test_format_specs @ linux-x86_64 +test.test_enum.TestMixedDate.test_hash @ linux-x86_64 +test.test_enum.TestMixedDate.test_inherited_repr @ linux-x86_64 +test.test_enum.TestMixedDate.test_invalid_names @ linux-x86_64 +test.test_enum.TestMixedDate.test_multiple_superclasses_repr @ linux-x86_64 +test.test_enum.TestMixedDate.test_object_str_override @ linux-x86_64 +test.test_enum.TestMixedDate.test_overridden_format @ linux-x86_64 +test.test_enum.TestMixedDate.test_overridden_str @ linux-x86_64 +test.test_enum.TestMixedDate.test_overridden_str_format @ linux-x86_64 +test.test_enum.TestMixedDate.test_overridden_str_format_inherited @ linux-x86_64 +test.test_enum.TestMixedDate.test_programmatic_function_from_dict @ linux-x86_64 +test.test_enum.TestMixedDate.test_programmatic_function_iterable @ linux-x86_64 +test.test_enum.TestMixedDate.test_programmatic_function_string @ linux-x86_64 +test.test_enum.TestMixedDate.test_programmatic_function_string_list @ linux-x86_64 +test.test_enum.TestMixedDate.test_repr @ linux-x86_64 +test.test_enum.TestMixedDate.test_repr_override @ linux-x86_64 +test.test_enum.TestMixedDate.test_reversed_iteration_order @ linux-x86_64 +test.test_enum.TestMixedDate.test_str @ linux-x86_64 +test.test_enum.TestMixedFloat.test_attribute_deletion @ linux-x86_64 +test.test_enum.TestMixedFloat.test_bad_new_super @ linux-x86_64 +test.test_enum.TestMixedFloat.test_basics @ linux-x86_64 +test.test_enum.TestMixedFloat.test_bool_is_true @ linux-x86_64 +test.test_enum.TestMixedFloat.test_changing_member_fails @ linux-x86_64 +test.test_enum.TestMixedFloat.test_contains_er @ linux-x86_64 +test.test_enum.TestMixedFloat.test_dir_on_class @ linux-x86_64 +test.test_enum.TestMixedFloat.test_dir_on_item @ linux-x86_64 +test.test_enum.TestMixedFloat.test_dir_on_sub_with_behavior_including_instance_dict_on_super @ linux-x86_64 +test.test_enum.TestMixedFloat.test_dir_on_sub_with_behavior_on_super @ linux-x86_64 +test.test_enum.TestMixedFloat.test_dir_with_added_behavior @ linux-x86_64 +test.test_enum.TestMixedFloat.test_enum_in_enum_out @ linux-x86_64 +test.test_enum.TestMixedFloat.test_format @ linux-x86_64 +test.test_enum.TestMixedFloat.test_format_specs @ linux-x86_64 +test.test_enum.TestMixedFloat.test_hash @ linux-x86_64 +test.test_enum.TestMixedFloat.test_inherited_repr @ linux-x86_64 +test.test_enum.TestMixedFloat.test_invalid_names @ linux-x86_64 +test.test_enum.TestMixedFloat.test_multiple_superclasses_repr @ linux-x86_64 +test.test_enum.TestMixedFloat.test_object_str_override @ linux-x86_64 +test.test_enum.TestMixedFloat.test_overridden_format @ linux-x86_64 +test.test_enum.TestMixedFloat.test_overridden_str @ linux-x86_64 +test.test_enum.TestMixedFloat.test_overridden_str_format @ linux-x86_64 +test.test_enum.TestMixedFloat.test_overridden_str_format_inherited @ linux-x86_64 +test.test_enum.TestMixedFloat.test_programmatic_function_from_dict @ linux-x86_64 +test.test_enum.TestMixedFloat.test_programmatic_function_iterable @ linux-x86_64 +test.test_enum.TestMixedFloat.test_programmatic_function_string @ linux-x86_64 +test.test_enum.TestMixedFloat.test_programmatic_function_string_list @ linux-x86_64 +test.test_enum.TestMixedFloat.test_repr @ linux-x86_64 +test.test_enum.TestMixedFloat.test_repr_override @ linux-x86_64 +test.test_enum.TestMixedFloat.test_reversed_iteration_order @ linux-x86_64 +test.test_enum.TestMixedFloat.test_str @ linux-x86_64 +test.test_enum.TestMixedInt.test_attribute_deletion @ linux-x86_64 +test.test_enum.TestMixedInt.test_bad_new_super @ linux-x86_64 +test.test_enum.TestMixedInt.test_basics @ linux-x86_64 +test.test_enum.TestMixedInt.test_bool_is_true @ linux-x86_64 +test.test_enum.TestMixedInt.test_changing_member_fails @ linux-x86_64 +test.test_enum.TestMixedInt.test_contains_er @ linux-x86_64 +test.test_enum.TestMixedInt.test_dir_on_class @ linux-x86_64 +test.test_enum.TestMixedInt.test_dir_on_item @ linux-x86_64 +test.test_enum.TestMixedInt.test_dir_on_sub_with_behavior_including_instance_dict_on_super @ linux-x86_64 +test.test_enum.TestMixedInt.test_dir_on_sub_with_behavior_on_super @ linux-x86_64 +test.test_enum.TestMixedInt.test_dir_with_added_behavior @ linux-x86_64 +test.test_enum.TestMixedInt.test_enum_in_enum_out @ linux-x86_64 +test.test_enum.TestMixedInt.test_format @ linux-x86_64 +test.test_enum.TestMixedInt.test_format_specs @ linux-x86_64 +test.test_enum.TestMixedInt.test_hash @ linux-x86_64 +test.test_enum.TestMixedInt.test_inherited_repr @ linux-x86_64 +test.test_enum.TestMixedInt.test_invalid_names @ linux-x86_64 +test.test_enum.TestMixedInt.test_multiple_superclasses_repr @ linux-x86_64 +test.test_enum.TestMixedInt.test_object_str_override @ linux-x86_64 +test.test_enum.TestMixedInt.test_overridden_format @ linux-x86_64 +test.test_enum.TestMixedInt.test_overridden_str @ linux-x86_64 +test.test_enum.TestMixedInt.test_overridden_str_format @ linux-x86_64 +test.test_enum.TestMixedInt.test_overridden_str_format_inherited @ linux-x86_64 +test.test_enum.TestMixedInt.test_programmatic_function_from_dict @ linux-x86_64 +test.test_enum.TestMixedInt.test_programmatic_function_iterable @ linux-x86_64 +test.test_enum.TestMixedInt.test_programmatic_function_string @ linux-x86_64 +test.test_enum.TestMixedInt.test_programmatic_function_string_list @ linux-x86_64 +test.test_enum.TestMixedInt.test_repr @ linux-x86_64 +test.test_enum.TestMixedInt.test_repr_override @ linux-x86_64 +test.test_enum.TestMixedInt.test_reversed_iteration_order @ linux-x86_64 +test.test_enum.TestMixedInt.test_str @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_attribute_deletion @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_bad_new_super @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_basics @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_bool_is_true @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_changing_member_fails @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_closed_invert_expectations @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_contains_er @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_default_missing_with_wrong_type_value @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_dir_on_class @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_dir_on_item @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_dir_on_sub_with_behavior_including_instance_dict_on_super @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_dir_on_sub_with_behavior_on_super @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_dir_with_added_behavior @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_enum_in_enum_out @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_format @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_format_specs @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_hash @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_inherited_repr @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_invalid_names @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_multiple_superclasses_repr @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_object_str_override @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_open_invert_expectations @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_overridden_format @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_overridden_str @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_overridden_str_format @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_overridden_str_format_inherited @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_programmatic_function_from_dict @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_programmatic_function_iterable @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_programmatic_function_string @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_programmatic_function_string_list @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_repr @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_repr_override @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_reversed_iteration_order @ linux-x86_64 +test.test_enum.TestMixedIntFlag.test_str @ linux-x86_64 +test.test_enum.TestMixedStr.test_attribute_deletion @ linux-x86_64 +test.test_enum.TestMixedStr.test_bad_new_super @ linux-x86_64 +test.test_enum.TestMixedStr.test_basics @ linux-x86_64 +test.test_enum.TestMixedStr.test_bool_is_true @ linux-x86_64 +test.test_enum.TestMixedStr.test_changing_member_fails @ linux-x86_64 +test.test_enum.TestMixedStr.test_contains_er @ linux-x86_64 +test.test_enum.TestMixedStr.test_dir_on_class @ linux-x86_64 +test.test_enum.TestMixedStr.test_dir_on_item @ linux-x86_64 +test.test_enum.TestMixedStr.test_dir_on_sub_with_behavior_including_instance_dict_on_super @ linux-x86_64 +test.test_enum.TestMixedStr.test_dir_on_sub_with_behavior_on_super @ linux-x86_64 +test.test_enum.TestMixedStr.test_dir_with_added_behavior @ linux-x86_64 +test.test_enum.TestMixedStr.test_enum_in_enum_out @ linux-x86_64 +test.test_enum.TestMixedStr.test_format @ linux-x86_64 +test.test_enum.TestMixedStr.test_format_specs @ linux-x86_64 +test.test_enum.TestMixedStr.test_hash @ linux-x86_64 +test.test_enum.TestMixedStr.test_inherited_repr @ linux-x86_64 +test.test_enum.TestMixedStr.test_invalid_names @ linux-x86_64 +test.test_enum.TestMixedStr.test_multiple_superclasses_repr @ linux-x86_64 +test.test_enum.TestMixedStr.test_object_str_override @ linux-x86_64 +test.test_enum.TestMixedStr.test_overridden_format @ linux-x86_64 +test.test_enum.TestMixedStr.test_overridden_str @ linux-x86_64 +test.test_enum.TestMixedStr.test_overridden_str_format @ linux-x86_64 +test.test_enum.TestMixedStr.test_overridden_str_format_inherited @ linux-x86_64 +test.test_enum.TestMixedStr.test_programmatic_function_from_dict @ linux-x86_64 +test.test_enum.TestMixedStr.test_programmatic_function_iterable @ linux-x86_64 +test.test_enum.TestMixedStr.test_programmatic_function_string @ linux-x86_64 +test.test_enum.TestMixedStr.test_programmatic_function_string_list @ linux-x86_64 +test.test_enum.TestMixedStr.test_repr @ linux-x86_64 +test.test_enum.TestMixedStr.test_repr_override @ linux-x86_64 +test.test_enum.TestMixedStr.test_reversed_iteration_order @ linux-x86_64 +test.test_enum.TestMixedStr.test_str @ linux-x86_64 +test.test_enum.TestOrder.test_enum_has_extra_members @ linux-x86_64 +test.test_enum.TestOrder.test_enum_has_extra_members_with_aliases @ linux-x86_64 +test.test_enum.TestOrder.test_order_has_extra_members @ linux-x86_64 +test.test_enum.TestOrder.test_order_has_extra_members_with_aliases @ linux-x86_64 +test.test_enum.TestOrder.test_same_members @ linux-x86_64 +test.test_enum.TestOrder.test_same_members_with_aliases @ linux-x86_64 +test.test_enum.TestOrder.test_same_members_wrong_order @ linux-x86_64 +test.test_enum.TestPlainEnum.test_attribute_deletion @ linux-x86_64 +test.test_enum.TestPlainEnum.test_bad_new_super @ linux-x86_64 +test.test_enum.TestPlainEnum.test_basics @ linux-x86_64 +test.test_enum.TestPlainEnum.test_bool_is_true @ linux-x86_64 +test.test_enum.TestPlainEnum.test_changing_member_fails @ linux-x86_64 +test.test_enum.TestPlainEnum.test_contains_er @ linux-x86_64 +test.test_enum.TestPlainEnum.test_dir_on_class @ linux-x86_64 +test.test_enum.TestPlainEnum.test_dir_on_item @ linux-x86_64 +test.test_enum.TestPlainEnum.test_dir_on_sub_with_behavior_including_instance_dict_on_super @ linux-x86_64 +test.test_enum.TestPlainEnum.test_dir_on_sub_with_behavior_on_super @ linux-x86_64 +test.test_enum.TestPlainEnum.test_dir_with_added_behavior @ linux-x86_64 +test.test_enum.TestPlainEnum.test_enum_in_enum_out @ linux-x86_64 +test.test_enum.TestPlainEnum.test_format @ linux-x86_64 +test.test_enum.TestPlainEnum.test_format_specs @ linux-x86_64 +test.test_enum.TestPlainEnum.test_hash @ linux-x86_64 +test.test_enum.TestPlainEnum.test_inherited_repr @ linux-x86_64 +test.test_enum.TestPlainEnum.test_invalid_names @ linux-x86_64 +test.test_enum.TestPlainEnum.test_multiple_superclasses_repr @ linux-x86_64 +test.test_enum.TestPlainEnum.test_object_str_override @ linux-x86_64 +test.test_enum.TestPlainEnum.test_overridden_format @ linux-x86_64 +test.test_enum.TestPlainEnum.test_overridden_str @ linux-x86_64 +test.test_enum.TestPlainEnum.test_overridden_str_format @ linux-x86_64 +test.test_enum.TestPlainEnum.test_overridden_str_format_inherited @ linux-x86_64 +test.test_enum.TestPlainEnum.test_programmatic_function_from_dict @ linux-x86_64 +test.test_enum.TestPlainEnum.test_programmatic_function_iterable @ linux-x86_64 +test.test_enum.TestPlainEnum.test_programmatic_function_string @ linux-x86_64 +test.test_enum.TestPlainEnum.test_programmatic_function_string_list @ linux-x86_64 +test.test_enum.TestPlainEnum.test_repr @ linux-x86_64 +test.test_enum.TestPlainEnum.test_repr_override @ linux-x86_64 +test.test_enum.TestPlainEnum.test_reversed_iteration_order @ linux-x86_64 +test.test_enum.TestPlainEnum.test_str @ linux-x86_64 +test.test_enum.TestPlainFlag.test_attribute_deletion @ linux-x86_64 +test.test_enum.TestPlainFlag.test_bad_new_super @ linux-x86_64 +test.test_enum.TestPlainFlag.test_basics @ linux-x86_64 +test.test_enum.TestPlainFlag.test_bool_is_true @ linux-x86_64 +test.test_enum.TestPlainFlag.test_changing_member_fails @ linux-x86_64 +test.test_enum.TestPlainFlag.test_closed_invert_expectations @ linux-x86_64 +test.test_enum.TestPlainFlag.test_contains_er @ linux-x86_64 +test.test_enum.TestPlainFlag.test_default_missing_with_wrong_type_value @ linux-x86_64 +test.test_enum.TestPlainFlag.test_dir_on_class @ linux-x86_64 +test.test_enum.TestPlainFlag.test_dir_on_item @ linux-x86_64 +test.test_enum.TestPlainFlag.test_dir_on_sub_with_behavior_including_instance_dict_on_super @ linux-x86_64 +test.test_enum.TestPlainFlag.test_dir_on_sub_with_behavior_on_super @ linux-x86_64 +test.test_enum.TestPlainFlag.test_dir_with_added_behavior @ linux-x86_64 +test.test_enum.TestPlainFlag.test_enum_in_enum_out @ linux-x86_64 +test.test_enum.TestPlainFlag.test_format @ linux-x86_64 +test.test_enum.TestPlainFlag.test_format_specs @ linux-x86_64 +test.test_enum.TestPlainFlag.test_hash @ linux-x86_64 +test.test_enum.TestPlainFlag.test_inherited_repr @ linux-x86_64 +test.test_enum.TestPlainFlag.test_invalid_names @ linux-x86_64 +test.test_enum.TestPlainFlag.test_multiple_superclasses_repr @ linux-x86_64 +test.test_enum.TestPlainFlag.test_object_str_override @ linux-x86_64 +test.test_enum.TestPlainFlag.test_open_invert_expectations @ linux-x86_64 +test.test_enum.TestPlainFlag.test_overridden_format @ linux-x86_64 +test.test_enum.TestPlainFlag.test_overridden_str @ linux-x86_64 +test.test_enum.TestPlainFlag.test_overridden_str_format @ linux-x86_64 +test.test_enum.TestPlainFlag.test_overridden_str_format_inherited @ linux-x86_64 +test.test_enum.TestPlainFlag.test_programmatic_function_from_dict @ linux-x86_64 +test.test_enum.TestPlainFlag.test_programmatic_function_iterable @ linux-x86_64 +test.test_enum.TestPlainFlag.test_programmatic_function_string @ linux-x86_64 +test.test_enum.TestPlainFlag.test_programmatic_function_string_list @ linux-x86_64 +test.test_enum.TestPlainFlag.test_repr @ linux-x86_64 +test.test_enum.TestPlainFlag.test_repr_override @ linux-x86_64 +test.test_enum.TestPlainFlag.test_reversed_iteration_order @ linux-x86_64 +test.test_enum.TestPlainFlag.test_str @ linux-x86_64 +test.test_enum.TestSpecial.test_bool @ linux-x86_64 +test.test_enum.TestSpecial.test_comparisons @ linux-x86_64 +test.test_enum.TestSpecial.test_conflicting_types_resolved_in_new @ linux-x86_64 +test.test_enum.TestSpecial.test_custom_flag_bitwise @ linux-x86_64 +test.test_enum.TestSpecial.test_default_missing_no_chained_exception @ linux-x86_64 +test.test_enum.TestSpecial.test_duplicate_name_error @ linux-x86_64 +test.test_enum.TestSpecial.test_duplicate_values_give_unique_enum_items @ linux-x86_64 +test.test_enum.TestSpecial.test_dynamic_members_with_static_methods @ linux-x86_64 +test.test_enum.TestSpecial.test_empty_globals @ linux-x86_64 +test.test_enum.TestSpecial.test_enum_function_with_qualname @ linux-x86_64 +test.test_enum.TestSpecial.test_enum_of_generic_aliases @ linux-x86_64 +test.test_enum.TestSpecial.test_enum_of_types @ linux-x86_64 +test.test_enum.TestSpecial.test_enum_of_types_with_nonmember @ linux-x86_64 +test.test_enum.TestSpecial.test_enum_with_value_name @ linux-x86_64 +test.test_enum.TestSpecial.test_equality @ linux-x86_64 +test.test_enum.TestSpecial.test_exclude_methods @ linux-x86_64 +test.test_enum.TestSpecial.test_extending @ linux-x86_64 +test.test_enum.TestSpecial.test_extending2 @ linux-x86_64 +test.test_enum.TestSpecial.test_extending3 @ linux-x86_64 +test.test_enum.TestSpecial.test_flag_with_custom_new @ linux-x86_64 +test.test_enum.TestSpecial.test_floatenum_fromhex @ linux-x86_64 +test.test_enum.TestSpecial.test_flufl_enum @ linux-x86_64 +test.test_enum.TestSpecial.test_getattr_dunder @ linux-x86_64 +test.test_enum.TestSpecial.test_getattr_getitem @ linux-x86_64 +test.test_enum.TestSpecial.test_ignore @ linux-x86_64 +test.test_enum.TestSpecial.test_inherited_data_type @ linux-x86_64 +test.test_enum.TestSpecial.test_inherited_new_from_enhanced_enum @ linux-x86_64 +test.test_enum.TestSpecial.test_inherited_new_from_mixed_enum @ linux-x86_64 +test.test_enum.TestSpecial.test_init @ linux-x86_64 +test.test_enum.TestSpecial.test_init_exception @ linux-x86_64 +test.test_enum.TestSpecial.test_int_flags_copy @ linux-x86_64 +test.test_enum.TestSpecial.test_intenum_from_bytes @ linux-x86_64 +test.test_enum.TestSpecial.test_intenum_transitivity @ linux-x86_64 +test.test_enum.TestSpecial.test_introspection @ linux-x86_64 +test.test_enum.TestSpecial.test_iteration_order @ linux-x86_64 +test.test_enum.TestSpecial.test_member_from_member_access @ linux-x86_64 +test.test_enum.TestSpecial.test_missing_override @ linux-x86_64 +test.test_enum.TestSpecial.test_missing_value_error @ linux-x86_64 +test.test_enum.TestSpecial.test_mixed_enum_in_call_1 @ linux-x86_64 +test.test_enum.TestSpecial.test_mixed_enum_in_call_2 @ linux-x86_64 +test.test_enum.TestSpecial.test_multiple_inherited_mixin @ linux-x86_64 +test.test_enum.TestSpecial.test_multiple_mixin @ linux-x86_64 +test.test_enum.TestSpecial.test_multiple_mixin_inherited @ linux-x86_64 +test.test_enum.TestSpecial.test_multiple_mixin_mro @ linux-x86_64 +test.test_enum.TestSpecial.test_multiple_mixin_with_common_data_type @ linux-x86_64 +test.test_enum.TestSpecial.test_namedtuple_as_value @ linux-x86_64 +test.test_enum.TestSpecial.test_nested_classes_in_enum_are_members @ linux-x86_64 +test.test_enum.TestSpecial.test_nested_classes_in_enum_with_member @ linux-x86_64 +test.test_enum.TestSpecial.test_nested_classes_in_enum_with_nonmember @ linux-x86_64 +test.test_enum.TestSpecial.test_no_duplicates @ linux-x86_64 +test.test_enum.TestSpecial.test_no_such_enum_member @ linux-x86_64 +test.test_enum.TestSpecial.test_nonhash_value @ linux-x86_64 +test.test_enum.TestSpecial.test_ordered_mixin @ linux-x86_64 +test.test_enum.TestSpecial.test_pickle_by_name @ linux-x86_64 +test.test_enum.TestSpecial.test_pickle_enum @ linux-x86_64 +test.test_enum.TestSpecial.test_pickle_enum_function @ linux-x86_64 +test.test_enum.TestSpecial.test_pickle_enum_function_with_module @ linux-x86_64 +test.test_enum.TestSpecial.test_pickle_explodes @ linux-x86_64 +test.test_enum.TestSpecial.test_pickle_float @ linux-x86_64 +test.test_enum.TestSpecial.test_pickle_int @ linux-x86_64 +test.test_enum.TestSpecial.test_pickle_nested_class @ linux-x86_64 +test.test_enum.TestSpecial.test_private_variable_is_normal_attribute @ linux-x86_64 +test.test_enum.TestSpecial.test_programmatic_function_string_list_with_start @ linux-x86_64 +test.test_enum.TestSpecial.test_programmatic_function_string_with_start @ linux-x86_64 +test.test_enum.TestSpecial.test_programmatic_function_type @ linux-x86_64 +test.test_enum.TestSpecial.test_programmatic_function_type_from_subclass @ linux-x86_64 +test.test_enum.TestSpecial.test_programmatic_function_type_from_subclass_with_start @ linux-x86_64 +test.test_enum.TestSpecial.test_programmatic_function_type_with_start @ linux-x86_64 +test.test_enum.TestSpecial.test_repr_and_str_with_no_init_mixin @ linux-x86_64 +test.test_enum.TestSpecial.test_repr_with_dataclass @ linux-x86_64 +test.test_enum.TestSpecial.test_repr_with_init_mixin @ linux-x86_64 +test.test_enum.TestSpecial.test_reserved_sunder_error @ linux-x86_64 +test.test_enum.TestSpecial.test_strenum @ linux-x86_64 +test.test_enum.TestSpecial.test_string_enum @ linux-x86_64 +test.test_enum.TestSpecial.test_subclass_duplicate_name @ linux-x86_64 +test.test_enum.TestSpecial.test_subclass_duplicate_name_dynamic @ linux-x86_64 +test.test_enum.TestSpecial.test_subclasses_with_direct_pickle_support @ linux-x86_64 +test.test_enum.TestSpecial.test_subclasses_with_getnewargs @ linux-x86_64 +test.test_enum.TestSpecial.test_subclasses_with_getnewargs_ex @ linux-x86_64 +test.test_enum.TestSpecial.test_subclasses_with_reduce @ linux-x86_64 +test.test_enum.TestSpecial.test_subclasses_with_reduce_ex @ linux-x86_64 +test.test_enum.TestSpecial.test_subclasses_without_direct_pickle_support @ linux-x86_64 +test.test_enum.TestSpecial.test_subclassing @ linux-x86_64 +test.test_enum.TestSpecial.test_too_many_data_types @ linux-x86_64 +test.test_enum.TestSpecial.test_tuple_subclass @ linux-x86_64 +test.test_enum.TestSpecial.test_value_backup_assign @ linux-x86_64 +test.test_enum.TestSpecial.test_wrong_enum_in_call @ linux-x86_64 +test.test_enum.TestSpecial.test_wrong_enum_in_mixed_call @ linux-x86_64 +test.test_enum.TestSpecial.test_wrong_inheritance_order @ linux-x86_64 +test.test_enum.TestStdLib.test_inspect_classify_class_attrs @ linux-x86_64 +test.test_enum.TestStdLib.test_inspect_getmembers @ linux-x86_64 +test.test_enum.TestStdLib.test_pydoc @ linux-x86_64 +test.test_enum.TestStdLib.test_test_simple_enum @ linux-x86_64 +test.test_enum.TestStrEnum.test_attribute_deletion @ linux-x86_64 +test.test_enum.TestStrEnum.test_bad_new_super @ linux-x86_64 +test.test_enum.TestStrEnum.test_basics @ linux-x86_64 +test.test_enum.TestStrEnum.test_bool_is_true @ linux-x86_64 +test.test_enum.TestStrEnum.test_changing_member_fails @ linux-x86_64 +test.test_enum.TestStrEnum.test_contains_er @ linux-x86_64 +test.test_enum.TestStrEnum.test_copy @ linux-x86_64 +test.test_enum.TestStrEnum.test_copy_member @ linux-x86_64 +test.test_enum.TestStrEnum.test_dir_on_class @ linux-x86_64 +test.test_enum.TestStrEnum.test_dir_on_item @ linux-x86_64 +test.test_enum.TestStrEnum.test_dir_on_sub_with_behavior_including_instance_dict_on_super @ linux-x86_64 +test.test_enum.TestStrEnum.test_dir_on_sub_with_behavior_on_super @ linux-x86_64 +test.test_enum.TestStrEnum.test_dir_with_added_behavior @ linux-x86_64 +test.test_enum.TestStrEnum.test_enum_in_enum_out @ linux-x86_64 +test.test_enum.TestStrEnum.test_format @ linux-x86_64 +test.test_enum.TestStrEnum.test_format_specs @ linux-x86_64 +test.test_enum.TestStrEnum.test_hash @ linux-x86_64 +test.test_enum.TestStrEnum.test_inherited_repr @ linux-x86_64 +test.test_enum.TestStrEnum.test_invalid_names @ linux-x86_64 +test.test_enum.TestStrEnum.test_multiple_superclasses_repr @ linux-x86_64 +test.test_enum.TestStrEnum.test_object_str_override @ linux-x86_64 +test.test_enum.TestStrEnum.test_overridden_format @ linux-x86_64 +test.test_enum.TestStrEnum.test_overridden_str @ linux-x86_64 +test.test_enum.TestStrEnum.test_overridden_str_format @ linux-x86_64 +test.test_enum.TestStrEnum.test_overridden_str_format_inherited @ linux-x86_64 +test.test_enum.TestStrEnum.test_programmatic_function_from_dict @ linux-x86_64 +test.test_enum.TestStrEnum.test_programmatic_function_iterable @ linux-x86_64 +test.test_enum.TestStrEnum.test_programmatic_function_string @ linux-x86_64 +test.test_enum.TestStrEnum.test_programmatic_function_string_list @ linux-x86_64 +test.test_enum.TestStrEnum.test_repr @ linux-x86_64 +test.test_enum.TestStrEnum.test_repr_override @ linux-x86_64 +test.test_enum.TestStrEnum.test_reversed_iteration_order @ linux-x86_64 +test.test_enum.TestStrEnum.test_str @ linux-x86_64 +test.test_enum.TestUnique.test_unique_clean @ linux-x86_64 +test.test_enum.TestUnique.test_unique_dirty @ linux-x86_64 +test.test_enum.TestUnique.test_unique_with_name @ linux-x86_64 +test.test_enum.TestVerify.test_composite @ linux-x86_64 +test.test_enum.TestVerify.test_continuous @ linux-x86_64 +test.test_enum.TestVerify.test_negative_alias @ linux-x86_64 +test.test_enum.TestVerify.test_unique_clean @ linux-x86_64 +test.test_enum.TestVerify.test_unique_dirty @ linux-x86_64 +test.test_enum.TestVerify.test_unique_with_name @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_enumerate.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_enumerate.txt new file mode 100644 index 0000000000..ec427b036a --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_enumerate.txt @@ -0,0 +1,78 @@ +test.test_enumerate.EnumerateStartTestCase.test_argumentcheck @ linux-x86_64 +test.test_enumerate.EnumerateStartTestCase.test_basicfunction @ linux-x86_64 +test.test_enumerate.EnumerateStartTestCase.test_exception_propagation @ linux-x86_64 +test.test_enumerate.EnumerateStartTestCase.test_getitemseqn @ linux-x86_64 +test.test_enumerate.EnumerateStartTestCase.test_illformediterable @ linux-x86_64 +test.test_enumerate.EnumerateStartTestCase.test_iteratorgenerator @ linux-x86_64 +test.test_enumerate.EnumerateStartTestCase.test_iteratorseqn @ linux-x86_64 +test.test_enumerate.EnumerateStartTestCase.test_kwargs @ linux-x86_64 +test.test_enumerate.EnumerateStartTestCase.test_noniterable @ linux-x86_64 +test.test_enumerate.EnumerateStartTestCase.test_pickle @ linux-x86_64 +test.test_enumerate.EnumerateTestCase.test_argumentcheck @ linux-x86_64 +test.test_enumerate.EnumerateTestCase.test_basicfunction @ linux-x86_64 +test.test_enumerate.EnumerateTestCase.test_exception_propagation @ linux-x86_64 +test.test_enumerate.EnumerateTestCase.test_getitemseqn @ linux-x86_64 +test.test_enumerate.EnumerateTestCase.test_illformediterable @ linux-x86_64 +test.test_enumerate.EnumerateTestCase.test_iteratorgenerator @ linux-x86_64 +test.test_enumerate.EnumerateTestCase.test_iteratorseqn @ linux-x86_64 +test.test_enumerate.EnumerateTestCase.test_kwargs @ linux-x86_64 +test.test_enumerate.EnumerateTestCase.test_noniterable @ linux-x86_64 +test.test_enumerate.EnumerateTestCase.test_pickle @ linux-x86_64 +test.test_enumerate.SubclassTestCase.test_argumentcheck @ linux-x86_64 +test.test_enumerate.SubclassTestCase.test_basicfunction @ linux-x86_64 +test.test_enumerate.SubclassTestCase.test_exception_propagation @ linux-x86_64 +test.test_enumerate.SubclassTestCase.test_getitemseqn @ linux-x86_64 +test.test_enumerate.SubclassTestCase.test_illformediterable @ linux-x86_64 +test.test_enumerate.SubclassTestCase.test_iteratorgenerator @ linux-x86_64 +test.test_enumerate.SubclassTestCase.test_iteratorseqn @ linux-x86_64 +test.test_enumerate.SubclassTestCase.test_kwargs @ linux-x86_64 +test.test_enumerate.SubclassTestCase.test_noniterable @ linux-x86_64 +test.test_enumerate.SubclassTestCase.test_pickle @ linux-x86_64 +test.test_enumerate.TestBig.test_argumentcheck @ linux-x86_64 +test.test_enumerate.TestBig.test_basicfunction @ linux-x86_64 +test.test_enumerate.TestBig.test_exception_propagation @ linux-x86_64 +test.test_enumerate.TestBig.test_getitemseqn @ linux-x86_64 +test.test_enumerate.TestBig.test_illformediterable @ linux-x86_64 +test.test_enumerate.TestBig.test_iteratorgenerator @ linux-x86_64 +test.test_enumerate.TestBig.test_iteratorseqn @ linux-x86_64 +test.test_enumerate.TestBig.test_kwargs @ linux-x86_64 +test.test_enumerate.TestBig.test_noniterable @ linux-x86_64 +test.test_enumerate.TestBig.test_pickle @ linux-x86_64 +test.test_enumerate.TestEmpty.test_argumentcheck @ linux-x86_64 +test.test_enumerate.TestEmpty.test_basicfunction @ linux-x86_64 +test.test_enumerate.TestEmpty.test_exception_propagation @ linux-x86_64 +test.test_enumerate.TestEmpty.test_getitemseqn @ linux-x86_64 +test.test_enumerate.TestEmpty.test_illformediterable @ linux-x86_64 +test.test_enumerate.TestEmpty.test_iteratorgenerator @ linux-x86_64 +test.test_enumerate.TestEmpty.test_iteratorseqn @ linux-x86_64 +test.test_enumerate.TestEmpty.test_kwargs @ linux-x86_64 +test.test_enumerate.TestEmpty.test_noniterable @ linux-x86_64 +test.test_enumerate.TestEmpty.test_pickle @ linux-x86_64 +test.test_enumerate.TestLongStart.test_argumentcheck @ linux-x86_64 +test.test_enumerate.TestLongStart.test_basicfunction @ linux-x86_64 +test.test_enumerate.TestLongStart.test_exception_propagation @ linux-x86_64 +test.test_enumerate.TestLongStart.test_getitemseqn @ linux-x86_64 +test.test_enumerate.TestLongStart.test_illformediterable @ linux-x86_64 +test.test_enumerate.TestLongStart.test_iteratorgenerator @ linux-x86_64 +test.test_enumerate.TestLongStart.test_iteratorseqn @ linux-x86_64 +test.test_enumerate.TestLongStart.test_kwargs @ linux-x86_64 +test.test_enumerate.TestLongStart.test_noniterable @ linux-x86_64 +test.test_enumerate.TestLongStart.test_pickle @ linux-x86_64 +test.test_enumerate.TestReversed.test_args @ linux-x86_64 +test.test_enumerate.TestReversed.test_bug1229429 @ linux-x86_64 +test.test_enumerate.TestReversed.test_gc @ linux-x86_64 +test.test_enumerate.TestReversed.test_len @ linux-x86_64 +test.test_enumerate.TestReversed.test_objmethods @ linux-x86_64 +test.test_enumerate.TestReversed.test_pickle @ linux-x86_64 +test.test_enumerate.TestReversed.test_range_optimization @ linux-x86_64 +test.test_enumerate.TestReversed.test_simple @ linux-x86_64 +test.test_enumerate.TestStart.test_argumentcheck @ linux-x86_64 +test.test_enumerate.TestStart.test_basicfunction @ linux-x86_64 +test.test_enumerate.TestStart.test_exception_propagation @ linux-x86_64 +test.test_enumerate.TestStart.test_getitemseqn @ linux-x86_64 +test.test_enumerate.TestStart.test_illformediterable @ linux-x86_64 +test.test_enumerate.TestStart.test_iteratorgenerator @ linux-x86_64 +test.test_enumerate.TestStart.test_iteratorseqn @ linux-x86_64 +test.test_enumerate.TestStart.test_kwargs @ linux-x86_64 +test.test_enumerate.TestStart.test_noniterable @ linux-x86_64 +test.test_enumerate.TestStart.test_pickle @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_eof.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_eof.txt new file mode 100644 index 0000000000..926aeaddb9 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_eof.txt @@ -0,0 +1,6 @@ +test.test_eof.EOFTestCase.test_EOFS @ linux-x86_64 +test.test_eof.EOFTestCase.test_EOFS_with_file @ linux-x86_64 +test.test_eof.EOFTestCase.test_EOF_single_quote @ linux-x86_64 +test.test_eof.EOFTestCase.test_eof_with_line_continuation @ linux-x86_64 +test.test_eof.EOFTestCase.test_line_continuation_EOF @ linux-x86_64 +test.test_eof.EOFTestCase.test_line_continuation_EOF_from_file_bpo2180 @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_errno.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_errno.txt new file mode 100644 index 0000000000..413ccd9bf2 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_errno.txt @@ -0,0 +1,3 @@ +test.test_errno.ErrnoAttributeTests.test_for_improper_attributes @ linux-x86_64 +test.test_errno.ErrnoAttributeTests.test_using_errorcode @ linux-x86_64 +test.test_errno.ErrorcodeTests.test_attributes_in_errorcode @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_except_star.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_except_star.txt new file mode 100644 index 0000000000..6bec5e2be3 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_except_star.txt @@ -0,0 +1 @@ +test.test_except_star.TestInvalidExceptStar.test_mixed_except_and_except_star_is_syntax_error @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_exception_group.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_exception_group.txt new file mode 100644 index 0000000000..b765dab392 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_exception_group.txt @@ -0,0 +1,47 @@ +test.test_exception_group.BadConstructorArgs.test_bad_EG_construction__bad_excs_sequence @ linux-x86_64 +test.test_exception_group.BadConstructorArgs.test_bad_EG_construction__bad_message @ linux-x86_64 +test.test_exception_group.BadConstructorArgs.test_bad_EG_construction__nested_non_exceptions @ linux-x86_64 +test.test_exception_group.BadConstructorArgs.test_bad_EG_construction__too_many_args @ linux-x86_64 +test.test_exception_group.ExceptionGroupFields.test_basics_ExceptionGroup_fields @ linux-x86_64 +test.test_exception_group.ExceptionGroupFields.test_fields_are_readonly @ linux-x86_64 +test.test_exception_group.ExceptionGroupSplitTests.test_basics_split_by_predicate__match @ linux-x86_64 +test.test_exception_group.ExceptionGroupSplitTests.test_basics_split_by_predicate__no_match @ linux-x86_64 +test.test_exception_group.ExceptionGroupSplitTests.test_basics_split_by_predicate__passthrough @ linux-x86_64 +test.test_exception_group.ExceptionGroupSplitTests.test_basics_split_by_type__match @ linux-x86_64 +test.test_exception_group.ExceptionGroupSplitTests.test_basics_split_by_type__no_match @ linux-x86_64 +test.test_exception_group.ExceptionGroupSplitTests.test_basics_split_by_type__passthrough @ linux-x86_64 +test.test_exception_group.ExceptionGroupSubgroupTests.test_basics_subgroup_by_predicate__match @ linux-x86_64 +test.test_exception_group.ExceptionGroupSubgroupTests.test_basics_subgroup_by_predicate__no_match @ linux-x86_64 +test.test_exception_group.ExceptionGroupSubgroupTests.test_basics_subgroup_by_predicate__passthrough @ linux-x86_64 +test.test_exception_group.ExceptionGroupSubgroupTests.test_basics_subgroup_by_type__match @ linux-x86_64 +test.test_exception_group.ExceptionGroupSubgroupTests.test_basics_subgroup_by_type__no_match @ linux-x86_64 +test.test_exception_group.ExceptionGroupSubgroupTests.test_basics_subgroup_by_type__passthrough @ linux-x86_64 +test.test_exception_group.ExceptionGroupSubgroupTests.test_basics_subgroup_split__bad_arg_type @ linux-x86_64 +test.test_exception_group.InstanceCreation.test_BEG_and_E_subclass_does_not_wrap_base_exceptions @ linux-x86_64 +test.test_exception_group.InstanceCreation.test_BEG_and_specific_subclass_can_wrap_any_nonbase_exception @ linux-x86_64 +test.test_exception_group.InstanceCreation.test_BEG_subclass_wraps_anything @ linux-x86_64 +test.test_exception_group.InstanceCreation.test_BEG_wraps_BaseException__creates_BEG @ linux-x86_64 +test.test_exception_group.InstanceCreation.test_BEG_wraps_Exceptions__creates_EG @ linux-x86_64 +test.test_exception_group.InstanceCreation.test_EG_and_specific_subclass_can_wrap_any_nonbase_exception @ linux-x86_64 +test.test_exception_group.InstanceCreation.test_EG_subclass_does_not_wrap_base_exceptions @ linux-x86_64 +test.test_exception_group.InstanceCreation.test_EG_subclass_wraps_non_base_exceptions @ linux-x86_64 +test.test_exception_group.InstanceCreation.test_EG_wraps_BaseException__raises_TypeError @ linux-x86_64 +test.test_exception_group.InstanceCreation.test_EG_wraps_Exceptions__creates_EG @ linux-x86_64 +test.test_exception_group.LeafGeneratorTest.test_leaf_generator @ linux-x86_64 +test.test_exception_group.NestedExceptionGroupBasicsTest.test_iteration_full_tracebacks @ linux-x86_64 +test.test_exception_group.NestedExceptionGroupBasicsTest.test_nested_exception_group_tracebacks @ linux-x86_64 +test.test_exception_group.NestedExceptionGroupBasicsTest.test_nested_group_chaining @ linux-x86_64 +test.test_exception_group.NestedExceptionGroupBasicsTest.test_nested_group_matches_template @ linux-x86_64 +test.test_exception_group.NestedExceptionGroupSplitTest.test_split_BaseExceptionGroup @ linux-x86_64 +test.test_exception_group.NestedExceptionGroupSplitTest.test_split_by_type @ linux-x86_64 +test.test_exception_group.NestedExceptionGroupSplitTest.test_split_copies_notes @ linux-x86_64 +test.test_exception_group.NestedExceptionGroupSplitTest.test_split_does_not_copy_non_sequence_notes @ linux-x86_64 +test.test_exception_group.NestedExceptionGroupSubclassSplitTest.test_split_BaseExceptionGroup_subclass_no_derive_new_override @ linux-x86_64 +test.test_exception_group.NestedExceptionGroupSubclassSplitTest.test_split_ExceptionGroup_subclass_derive_and_new_overrides @ linux-x86_64 +test.test_exception_group.NestedExceptionGroupSubclassSplitTest.test_split_ExceptionGroup_subclass_no_derive_no_new_override @ linux-x86_64 +test.test_exception_group.StrAndReprTests.test_BaseExceptionGroup @ linux-x86_64 +test.test_exception_group.StrAndReprTests.test_ExceptionGroup @ linux-x86_64 +test.test_exception_group.StrAndReprTests.test_custom_exception @ linux-x86_64 +test.test_exception_group.TestExceptionGroupTypeHierarchy.test_exception_group_is_generic_type @ linux-x86_64 +test.test_exception_group.TestExceptionGroupTypeHierarchy.test_exception_group_types @ linux-x86_64 +test.test_exception_group.TestExceptionGroupTypeHierarchy.test_exception_is_not_generic_type @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_exception_hierarchy.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_exception_hierarchy.txt new file mode 100644 index 0000000000..4fb44e89eb --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_exception_hierarchy.txt @@ -0,0 +1,15 @@ +test.test_exception_hierarchy.AttributesTest.test_blockingioerror @ linux-x86_64 +test.test_exception_hierarchy.AttributesTest.test_posix_error @ linux-x86_64 +test.test_exception_hierarchy.AttributesTest.test_windows_error @ linux-x86_64 +test.test_exception_hierarchy.ExplicitSubclassingTest.test_errno_mapping @ linux-x86_64 +test.test_exception_hierarchy.ExplicitSubclassingTest.test_init_kwdargs @ linux-x86_64 +test.test_exception_hierarchy.ExplicitSubclassingTest.test_init_new_overridden @ linux-x86_64 +test.test_exception_hierarchy.ExplicitSubclassingTest.test_init_overridden @ linux-x86_64 +test.test_exception_hierarchy.ExplicitSubclassingTest.test_init_standalone @ linux-x86_64 +test.test_exception_hierarchy.ExplicitSubclassingTest.test_new_kwdargs @ linux-x86_64 +test.test_exception_hierarchy.ExplicitSubclassingTest.test_new_overridden @ linux-x86_64 +test.test_exception_hierarchy.HierarchyTest.test_builtin_errors @ linux-x86_64 +test.test_exception_hierarchy.HierarchyTest.test_errno_mapping @ linux-x86_64 +test.test_exception_hierarchy.HierarchyTest.test_select_error @ linux-x86_64 +test.test_exception_hierarchy.HierarchyTest.test_socket_errors @ linux-x86_64 +test.test_exception_hierarchy.HierarchyTest.test_try_except @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_exception_variations.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_exception_variations.txt new file mode 100644 index 0000000000..49f8f650d1 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_exception_variations.txt @@ -0,0 +1,16 @@ +test.test_exception_variations.ExceptStarTestCases.test_try_finally_no_exception @ linux-x86_64 +test.test_exception_variations.ExceptTestCases.test_nested @ linux-x86_64 +test.test_exception_variations.ExceptTestCases.test_nested_else @ linux-x86_64 +test.test_exception_variations.ExceptTestCases.test_nested_exception_in_else @ linux-x86_64 +test.test_exception_variations.ExceptTestCases.test_nested_exception_in_except @ linux-x86_64 +test.test_exception_variations.ExceptTestCases.test_nested_exception_in_finally_no_exception @ linux-x86_64 +test.test_exception_variations.ExceptTestCases.test_nested_exception_in_finally_with_exception @ linux-x86_64 +test.test_exception_variations.ExceptTestCases.test_try_except @ linux-x86_64 +test.test_exception_variations.ExceptTestCases.test_try_except_else @ linux-x86_64 +test.test_exception_variations.ExceptTestCases.test_try_except_else_finally @ linux-x86_64 +test.test_exception_variations.ExceptTestCases.test_try_except_else_finally_no_exception @ linux-x86_64 +test.test_exception_variations.ExceptTestCases.test_try_except_else_no_exception @ linux-x86_64 +test.test_exception_variations.ExceptTestCases.test_try_except_finally @ linux-x86_64 +test.test_exception_variations.ExceptTestCases.test_try_except_finally_no_exception @ linux-x86_64 +test.test_exception_variations.ExceptTestCases.test_try_except_no_exception @ linux-x86_64 +test.test_exception_variations.ExceptTestCases.test_try_finally_no_exception @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_exceptions.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_exceptions.txt new file mode 100644 index 0000000000..fa0dd83249 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_exceptions.txt @@ -0,0 +1,54 @@ +test.test_exceptions.AttributeErrorTests.test_attribute_error_with_failing_dict @ linux-x86_64 +test.test_exceptions.AttributeErrorTests.test_getattr_error_bad_suggestions_do_not_trigger_for_small_names @ linux-x86_64 +test.test_exceptions.AttributeErrorTests.test_getattr_suggestions_do_not_trigger_for_big_dicts @ linux-x86_64 +test.test_exceptions.AttributeErrorTests.test_getattr_suggestions_do_not_trigger_for_long_attributes @ linux-x86_64 +test.test_exceptions.AttributeErrorTests.test_getattr_suggestions_for_same_name @ linux-x86_64 +test.test_exceptions.ExceptionTests.testAttributes @ linux-x86_64 +test.test_exceptions.ExceptionTests.testChainingAttrs @ linux-x86_64 +test.test_exceptions.ExceptionTests.testChainingDescriptors @ linux-x86_64 +!test.test_exceptions.ExceptionTests.testInfiniteRecursion @ linux-x86_64 +test.test_exceptions.ExceptionTests.testInvalidAttrs @ linux-x86_64 +test.test_exceptions.ExceptionTests.testInvalidTraceback @ linux-x86_64 +test.test_exceptions.ExceptionTests.testKeywordArgs @ linux-x86_64 +test.test_exceptions.ExceptionTests.testNoneClearsTracebackAttr @ linux-x86_64 +test.test_exceptions.ExceptionTests.testRaising @ linux-x86_64 +test.test_exceptions.ExceptionTests.testSyntaxErrorMessage @ linux-x86_64 +test.test_exceptions.ExceptionTests.testSyntaxErrorMissingParens @ linux-x86_64 +test.test_exceptions.ExceptionTests.testWithTraceback @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_WindowsError @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_assert_shadowing @ linux-x86_64 +!test.test_exceptions.ExceptionTests.test_badisinstance @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_context_of_exception_in_else_and_finally @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_context_of_exception_in_except_and_finally @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_context_of_exception_in_try_and_finally @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_errno_ENOTDIR @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_error_offset_continuation_characters @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_exception_cleanup_names @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_exception_cleanup_names2 @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_exception_target_in_nested_scope @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_generator_doesnt_retain_old_exc2 @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_generator_finalizing_and_exc_info @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_generator_leaking2 @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_generator_leaking3 @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_memory_error_subclasses @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_notes @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_raise_does_not_create_context_chain_cycle @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_str @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_unhandled @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_unicode_change_attributes @ linux-x86_64 +test.test_exceptions.ExceptionTests.test_unicode_errors_no_object @ linux-x86_64 +test.test_exceptions.ImportErrorTests.test_attributes @ linux-x86_64 +test.test_exceptions.ImportErrorTests.test_copy_pickle @ linux-x86_64 +test.test_exceptions.ImportErrorTests.test_non_str_argument @ linux-x86_64 +test.test_exceptions.ImportErrorTests.test_reset_attributes @ linux-x86_64 +test.test_exceptions.NameErrorTests.test_issue45826 @ linux-x86_64 +test.test_exceptions.NameErrorTests.test_issue45826_focused @ linux-x86_64 +test.test_exceptions.NameErrorTests.test_name_error_bad_suggestions_do_not_trigger_for_small_names @ linux-x86_64 +test.test_exceptions.NameErrorTests.test_name_error_suggestions_do_not_trigger_for_long_names @ linux-x86_64 +test.test_exceptions.NameErrorTests.test_name_error_suggestions_do_not_trigger_for_too_many_locals @ linux-x86_64 +test.test_exceptions.NameErrorTests.test_name_error_with_custom_exceptions @ linux-x86_64 +test.test_exceptions.NameErrorTests.test_unbound_local_error_doesn_not_match @ linux-x86_64 +test.test_exceptions.PEP626Tests.test_lineno_after_raise_in_with_exit @ linux-x86_64 +test.test_exceptions.PEP626Tests.test_lineno_after_raise_simple @ linux-x86_64 +test.test_exceptions.PEP626Tests.test_lineno_in_finally_normal @ linux-x86_64 +test.test_exceptions.SyntaxErrorTests.test_attributes_old_constructor @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_faulthandler.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_faulthandler.txt new file mode 100644 index 0000000000..a40d51f103 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_faulthandler.txt @@ -0,0 +1,4 @@ +test.test_faulthandler.FaultHandlerTests.test_cancel_later_without_dump_traceback_later @ linux-x86_64 +test.test_faulthandler.FaultHandlerTests.test_disable @ linux-x86_64 +test.test_faulthandler.FaultHandlerTests.test_is_enabled @ linux-x86_64 +test.test_faulthandler.FaultHandlerTests.test_sys_xoptions @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fcntl.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fcntl.txt new file mode 100644 index 0000000000..fb90c674c4 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fcntl.txt @@ -0,0 +1,3 @@ +test.test_fcntl.TestFcntl.test_flock @ linux-x86_64 +test.test_fcntl.TestFcntl.test_lockf_exclusive @ linux-x86_64 +test.test_fcntl.TestFcntl.test_lockf_share @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_file.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_file.txt new file mode 100644 index 0000000000..323b57ee68 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_file.txt @@ -0,0 +1,30 @@ +test.test_file.CAutoFileTests.testAttributes @ linux-x86_64 +test.test_file.CAutoFileTests.testErrors @ linux-x86_64 +test.test_file.CAutoFileTests.testMethods @ linux-x86_64 +test.test_file.CAutoFileTests.testReadWhenWriting @ linux-x86_64 +test.test_file.CAutoFileTests.testReadinto @ linux-x86_64 +test.test_file.CAutoFileTests.testReadinto_text @ linux-x86_64 +test.test_file.CAutoFileTests.testWritelinesIntegers @ linux-x86_64 +test.test_file.CAutoFileTests.testWritelinesIntegersUserList @ linux-x86_64 +test.test_file.CAutoFileTests.testWritelinesNonString @ linux-x86_64 +test.test_file.CAutoFileTests.testWritelinesUserList @ linux-x86_64 +test.test_file.COtherFileTests.testBadModeArgument @ linux-x86_64 +test.test_file.COtherFileTests.testIteration @ linux-x86_64 +test.test_file.COtherFileTests.testModeStrings @ linux-x86_64 +test.test_file.COtherFileTests.testSetBufferSize @ linux-x86_64 +test.test_file.COtherFileTests.testTruncateOnWindows @ linux-x86_64 +test.test_file.PyAutoFileTests.testAttributes @ linux-x86_64 +test.test_file.PyAutoFileTests.testErrors @ linux-x86_64 +test.test_file.PyAutoFileTests.testMethods @ linux-x86_64 +test.test_file.PyAutoFileTests.testReadWhenWriting @ linux-x86_64 +test.test_file.PyAutoFileTests.testReadinto @ linux-x86_64 +test.test_file.PyAutoFileTests.testReadinto_text @ linux-x86_64 +test.test_file.PyAutoFileTests.testWritelinesIntegers @ linux-x86_64 +test.test_file.PyAutoFileTests.testWritelinesIntegersUserList @ linux-x86_64 +test.test_file.PyAutoFileTests.testWritelinesNonString @ linux-x86_64 +test.test_file.PyAutoFileTests.testWritelinesUserList @ linux-x86_64 +test.test_file.PyOtherFileTests.testBadModeArgument @ linux-x86_64 +test.test_file.PyOtherFileTests.testIteration @ linux-x86_64 +test.test_file.PyOtherFileTests.testModeStrings @ linux-x86_64 +test.test_file.PyOtherFileTests.testSetBufferSize @ linux-x86_64 +test.test_file.PyOtherFileTests.testTruncateOnWindows @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_filecmp.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_filecmp.txt new file mode 100644 index 0000000000..627be31d25 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_filecmp.txt @@ -0,0 +1,9 @@ +test.test_filecmp.DirCompareTestCase.test_cmpfiles @ linux-x86_64 +test.test_filecmp.DirCompareTestCase.test_default_ignores @ linux-x86_64 +test.test_filecmp.DirCompareTestCase.test_dircmp @ linux-x86_64 +test.test_filecmp.DirCompareTestCase.test_dircmp_subdirs_type @ linux-x86_64 +test.test_filecmp.DirCompareTestCase.test_report_full_closure @ linux-x86_64 +test.test_filecmp.DirCompareTestCase.test_report_partial_closure @ linux-x86_64 +test.test_filecmp.FileCompareTestCase.test_cache_clear @ linux-x86_64 +test.test_filecmp.FileCompareTestCase.test_different @ linux-x86_64 +test.test_filecmp.FileCompareTestCase.test_matching @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fileinput.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fileinput.txt new file mode 100644 index 0000000000..d7b8216335 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fileinput.txt @@ -0,0 +1,57 @@ +test.test_fileinput.BufferSizesTests.test_buffer_sizes @ linux-x86_64 +test.test_fileinput.FileInputTests.test_close_on_exception @ linux-x86_64 +test.test_fileinput.FileInputTests.test_context_manager @ linux-x86_64 +test.test_fileinput.FileInputTests.test_detached_stdin_binary_mode @ linux-x86_64 +test.test_fileinput.FileInputTests.test_empty_files_list_specified_to_constructor @ linux-x86_64 +test.test_fileinput.FileInputTests.test_file_hook_backward_compatibility @ linux-x86_64 +test.test_fileinput.FileInputTests.test_file_opening_hook @ linux-x86_64 +test.test_fileinput.FileInputTests.test_fileno @ linux-x86_64 +test.test_fileinput.FileInputTests.test_fileno_when_ValueError_raised @ linux-x86_64 +test.test_fileinput.FileInputTests.test_files_that_dont_end_with_newline @ linux-x86_64 +test.test_fileinput.FileInputTests.test_inplace_binary_write_mode @ linux-x86_64 +test.test_fileinput.FileInputTests.test_inplace_encoding_errors @ linux-x86_64 +test.test_fileinput.FileInputTests.test_invalid_opening_mode @ linux-x86_64 +test.test_fileinput.FileInputTests.test_iteration_buffering @ linux-x86_64 +test.test_fileinput.FileInputTests.test_nextfile_oserror_deleting_backup @ linux-x86_64 +test.test_fileinput.FileInputTests.test_pathlib_file @ linux-x86_64 +test.test_fileinput.FileInputTests.test_pathlib_file_inplace @ linux-x86_64 +test.test_fileinput.FileInputTests.test_readline @ linux-x86_64 +test.test_fileinput.FileInputTests.test_readline_binary_mode @ linux-x86_64 +test.test_fileinput.FileInputTests.test_readline_buffering @ linux-x86_64 +test.test_fileinput.FileInputTests.test_readline_os_chmod_raises_OSError @ linux-x86_64 +test.test_fileinput.FileInputTests.test_readline_os_fstat_raises_OSError @ linux-x86_64 +test.test_fileinput.FileInputTests.test_stdin_binary_mode @ linux-x86_64 +test.test_fileinput.FileInputTests.test_zero_byte_files @ linux-x86_64 +test.test_fileinput.MiscTest.test_all @ linux-x86_64 +test.test_fileinput.Test_fileinput_close.test_state_is_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_close.test_state_is_not_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_filelineno.test_state_is_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_filelineno.test_state_is_not_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_filename.test_state_is_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_filename.test_state_is_not_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_fileno.test_state_is_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_fileno.test_state_is_not_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_input.test_state_is_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_input.test_state_is_not_None_and_state_file_is_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_input.test_state_is_not_None_and_state_file_is_not_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_isfirstline.test_state_is_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_isfirstline.test_state_is_not_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_isstdin.test_state_is_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_isstdin.test_state_is_not_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_lineno.test_state_is_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_lineno.test_state_is_not_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_nextfile.test_state_is_None @ linux-x86_64 +test.test_fileinput.Test_fileinput_nextfile.test_state_is_not_None @ linux-x86_64 +test.test_fileinput.Test_hook_compressed.test_binary_mode_encoding @ linux-x86_64 +test.test_fileinput.Test_hook_compressed.test_blah_ext @ linux-x86_64 +test.test_fileinput.Test_hook_compressed.test_bz2_ext_builtin @ linux-x86_64 +test.test_fileinput.Test_hook_compressed.test_bz2_ext_fake @ linux-x86_64 +test.test_fileinput.Test_hook_compressed.test_empty_string @ linux-x86_64 +test.test_fileinput.Test_hook_compressed.test_gz_ext_builtin @ linux-x86_64 +test.test_fileinput.Test_hook_compressed.test_gz_ext_fake @ linux-x86_64 +test.test_fileinput.Test_hook_compressed.test_gz_with_encoding_fake @ linux-x86_64 +test.test_fileinput.Test_hook_compressed.test_no_ext @ linux-x86_64 +test.test_fileinput.Test_hook_compressed.test_text_mode_encoding @ linux-x86_64 +test.test_fileinput.Test_hook_encoded.test @ linux-x86_64 +test.test_fileinput.Test_hook_encoded.test_errors @ linux-x86_64 +test.test_fileinput.Test_hook_encoded.test_modes @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fileio.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fileio.txt new file mode 100644 index 0000000000..fb618fca01 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fileio.txt @@ -0,0 +1,87 @@ +test.test_fileio.CAutoFileTests.testAttributes @ linux-x86_64 +test.test_fileio.CAutoFileTests.testBlksize @ linux-x86_64 +test.test_fileio.CAutoFileTests.testErrnoOnClose @ linux-x86_64 +test.test_fileio.CAutoFileTests.testErrnoOnClosedFileno @ linux-x86_64 +test.test_fileio.CAutoFileTests.testErrnoOnClosedIsatty @ linux-x86_64 +test.test_fileio.CAutoFileTests.testErrnoOnClosedRead @ linux-x86_64 +test.test_fileio.CAutoFileTests.testErrnoOnClosedReadable @ linux-x86_64 +test.test_fileio.CAutoFileTests.testErrnoOnClosedReadall @ linux-x86_64 +test.test_fileio.CAutoFileTests.testErrnoOnClosedReadinto @ linux-x86_64 +test.test_fileio.CAutoFileTests.testErrnoOnClosedSeek @ linux-x86_64 +test.test_fileio.CAutoFileTests.testErrnoOnClosedSeekable @ linux-x86_64 +test.test_fileio.CAutoFileTests.testErrnoOnClosedTell @ linux-x86_64 +test.test_fileio.CAutoFileTests.testErrnoOnClosedTruncate @ linux-x86_64 +test.test_fileio.CAutoFileTests.testErrnoOnClosedWritable @ linux-x86_64 +test.test_fileio.CAutoFileTests.testErrnoOnClosedWrite @ linux-x86_64 +test.test_fileio.CAutoFileTests.testErrors @ linux-x86_64 +test.test_fileio.CAutoFileTests.testMethods @ linux-x86_64 +test.test_fileio.CAutoFileTests.testOpenDirFD @ linux-x86_64 +test.test_fileio.CAutoFileTests.testOpendir @ linux-x86_64 +test.test_fileio.CAutoFileTests.testReadintoByteArray @ linux-x86_64 +test.test_fileio.CAutoFileTests.testRepr @ linux-x86_64 +test.test_fileio.CAutoFileTests.testReprNoCloseFD @ linux-x86_64 +test.test_fileio.CAutoFileTests.testSeekTell @ linux-x86_64 +test.test_fileio.CAutoFileTests.testWritelinesError @ linux-x86_64 +test.test_fileio.CAutoFileTests.testWritelinesList @ linux-x86_64 +test.test_fileio.CAutoFileTests.testWritelinesUserList @ linux-x86_64 +test.test_fileio.CAutoFileTests.test_none_args @ linux-x86_64 +test.test_fileio.CAutoFileTests.test_reject @ linux-x86_64 +test.test_fileio.COtherFileTests.testAbles @ linux-x86_64 +test.test_fileio.COtherFileTests.testAppend @ linux-x86_64 +test.test_fileio.COtherFileTests.testBadModeArgument @ linux-x86_64 +test.test_fileio.COtherFileTests.testBytesOpen @ linux-x86_64 +test.test_fileio.COtherFileTests.testConstructorHandlesNULChars @ linux-x86_64 +test.test_fileio.COtherFileTests.testInvalidFd @ linux-x86_64 +test.test_fileio.COtherFileTests.testInvalidInit @ linux-x86_64 +test.test_fileio.COtherFileTests.testInvalidModeStrings @ linux-x86_64 +test.test_fileio.COtherFileTests.testModeStrings @ linux-x86_64 +test.test_fileio.COtherFileTests.testTruncate @ linux-x86_64 +test.test_fileio.COtherFileTests.testTruncateOnWindows @ linux-x86_64 +test.test_fileio.COtherFileTests.testUnclosedFDOnException @ linux-x86_64 +test.test_fileio.COtherFileTests.testUnicodeOpen @ linux-x86_64 +test.test_fileio.COtherFileTests.testUtf8BytesOpen @ linux-x86_64 +test.test_fileio.COtherFileTests.testWarnings @ linux-x86_64 +test.test_fileio.COtherFileTests.test_open_code @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testAttributes @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testBlksize @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testErrnoOnClose @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testErrnoOnClosedFileno @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testErrnoOnClosedIsatty @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testErrnoOnClosedRead @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testErrnoOnClosedReadable @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testErrnoOnClosedReadall @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testErrnoOnClosedReadinto @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testErrnoOnClosedSeek @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testErrnoOnClosedSeekable @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testErrnoOnClosedTell @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testErrnoOnClosedTruncate @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testErrnoOnClosedWritable @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testErrnoOnClosedWrite @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testErrors @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testMethods @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testOpenDirFD @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testOpendir @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testReadintoByteArray @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testRepr @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testReprNoCloseFD @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testSeekTell @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testWritelinesError @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testWritelinesList @ linux-x86_64 +test.test_fileio.PyAutoFileTests.testWritelinesUserList @ linux-x86_64 +test.test_fileio.PyAutoFileTests.test_none_args @ linux-x86_64 +test.test_fileio.PyAutoFileTests.test_reject @ linux-x86_64 +test.test_fileio.PyOtherFileTests.testAbles @ linux-x86_64 +test.test_fileio.PyOtherFileTests.testAppend @ linux-x86_64 +test.test_fileio.PyOtherFileTests.testBadModeArgument @ linux-x86_64 +test.test_fileio.PyOtherFileTests.testBytesOpen @ linux-x86_64 +test.test_fileio.PyOtherFileTests.testConstructorHandlesNULChars @ linux-x86_64 +test.test_fileio.PyOtherFileTests.testInvalidInit @ linux-x86_64 +test.test_fileio.PyOtherFileTests.testInvalidModeStrings @ linux-x86_64 +test.test_fileio.PyOtherFileTests.testModeStrings @ linux-x86_64 +test.test_fileio.PyOtherFileTests.testTruncate @ linux-x86_64 +test.test_fileio.PyOtherFileTests.testTruncateOnWindows @ linux-x86_64 +test.test_fileio.PyOtherFileTests.testUnclosedFDOnException @ linux-x86_64 +test.test_fileio.PyOtherFileTests.testUnicodeOpen @ linux-x86_64 +test.test_fileio.PyOtherFileTests.testUtf8BytesOpen @ linux-x86_64 +test.test_fileio.PyOtherFileTests.testWarnings @ linux-x86_64 +test.test_fileio.PyOtherFileTests.test_open_code @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_float.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_float.txt new file mode 100644 index 0000000000..b1065333ca --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_float.txt @@ -0,0 +1,51 @@ +test.test_float.FormatFunctionsTestCase.test_getformat @ linux-x86_64 +test.test_float.FormatTestCase.test_format @ linux-x86_64 +test.test_float.FormatTestCase.test_format_testfile @ linux-x86_64 +test.test_float.FormatTestCase.test_issue35560 @ linux-x86_64 +test.test_float.FormatTestCase.test_issue5864 @ linux-x86_64 +test.test_float.GeneralFloatCases.test_error_message @ linux-x86_64 +test.test_float.GeneralFloatCases.test_float @ linux-x86_64 +test.test_float.GeneralFloatCases.test_float_ceil @ linux-x86_64 +test.test_float.GeneralFloatCases.test_float_containment @ linux-x86_64 +test.test_float.GeneralFloatCases.test_float_floor @ linux-x86_64 +test.test_float.GeneralFloatCases.test_float_memoryview @ linux-x86_64 +test.test_float.GeneralFloatCases.test_float_mod @ linux-x86_64 +test.test_float.GeneralFloatCases.test_float_pow @ linux-x86_64 +test.test_float.GeneralFloatCases.test_float_with_comma @ linux-x86_64 +test.test_float.GeneralFloatCases.test_floatasratio @ linux-x86_64 +test.test_float.GeneralFloatCases.test_floatconversion @ linux-x86_64 +test.test_float.GeneralFloatCases.test_hash @ linux-x86_64 +test.test_float.GeneralFloatCases.test_is_integer @ linux-x86_64 +test.test_float.GeneralFloatCases.test_keyword_args @ linux-x86_64 +test.test_float.GeneralFloatCases.test_noargs @ linux-x86_64 +test.test_float.GeneralFloatCases.test_non_numeric_input_types @ linux-x86_64 +test.test_float.GeneralFloatCases.test_underscores @ linux-x86_64 +test.test_float.HexFloatTestCase.test_ends @ linux-x86_64 +test.test_float.HexFloatTestCase.test_from_hex @ linux-x86_64 +test.test_float.HexFloatTestCase.test_invalid_inputs @ linux-x86_64 +test.test_float.HexFloatTestCase.test_roundtrip @ linux-x86_64 +test.test_float.HexFloatTestCase.test_subclass @ linux-x86_64 +test.test_float.HexFloatTestCase.test_whitespace @ linux-x86_64 +test.test_float.IEEEFormatTestCase.test_double_specials_do_unpack @ linux-x86_64 +test.test_float.IEEEFormatTestCase.test_float_specials_do_unpack @ linux-x86_64 +test.test_float.IEEEFormatTestCase.test_serialized_float_rounding @ linux-x86_64 +test.test_float.InfNanTest.test_inf_as_str @ linux-x86_64 +test.test_float.InfNanTest.test_inf_from_str @ linux-x86_64 +test.test_float.InfNanTest.test_inf_signs @ linux-x86_64 +test.test_float.InfNanTest.test_nan_as_str @ linux-x86_64 +test.test_float.InfNanTest.test_nan_from_str @ linux-x86_64 +test.test_float.InfNanTest.test_nan_signs @ linux-x86_64 +test.test_float.PackTests.test_pack @ linux-x86_64 +test.test_float.PackTests.test_roundtrip @ linux-x86_64 +test.test_float.PackTests.test_unpack @ linux-x86_64 +test.test_float.ReprTestCase.test_repr @ linux-x86_64 +test.test_float.ReprTestCase.test_short_repr @ linux-x86_64 +test.test_float.RoundTestCase.test_None_ndigits @ linux-x86_64 +test.test_float.RoundTestCase.test_format_specials @ linux-x86_64 +test.test_float.RoundTestCase.test_inf_nan @ linux-x86_64 +test.test_float.RoundTestCase.test_inf_nan_ndigits @ linux-x86_64 +test.test_float.RoundTestCase.test_large_n @ linux-x86_64 +test.test_float.RoundTestCase.test_matches_float_format @ linux-x86_64 +test.test_float.RoundTestCase.test_overflow @ linux-x86_64 +test.test_float.RoundTestCase.test_previous_round_bugs @ linux-x86_64 +test.test_float.RoundTestCase.test_small_n @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_flufl.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_flufl.txt new file mode 100644 index 0000000000..adab1d3902 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_flufl.txt @@ -0,0 +1 @@ +test.test_flufl.FLUFLTests.test_guido_as_bdfl @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fnmatch.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fnmatch.txt new file mode 100644 index 0000000000..9e89c85e12 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fnmatch.txt @@ -0,0 +1,17 @@ +test.test_fnmatch.FilterTestCase.test_case @ linux-x86_64 +test.test_fnmatch.FilterTestCase.test_filter @ linux-x86_64 +test.test_fnmatch.FilterTestCase.test_mix_bytes_str @ linux-x86_64 +test.test_fnmatch.FilterTestCase.test_sep @ linux-x86_64 +test.test_fnmatch.FnmatchTestCase.test_bytes @ linux-x86_64 +test.test_fnmatch.FnmatchTestCase.test_case @ linux-x86_64 +test.test_fnmatch.FnmatchTestCase.test_char_set @ linux-x86_64 +test.test_fnmatch.FnmatchTestCase.test_fnmatch @ linux-x86_64 +test.test_fnmatch.FnmatchTestCase.test_fnmatchcase @ linux-x86_64 +test.test_fnmatch.FnmatchTestCase.test_mix_bytes_str @ linux-x86_64 +test.test_fnmatch.FnmatchTestCase.test_range @ linux-x86_64 +test.test_fnmatch.FnmatchTestCase.test_sep @ linux-x86_64 +test.test_fnmatch.FnmatchTestCase.test_sep_in_char_set @ linux-x86_64 +test.test_fnmatch.FnmatchTestCase.test_sep_in_range @ linux-x86_64 +test.test_fnmatch.FnmatchTestCase.test_slow_fnmatch @ linux-x86_64 +test.test_fnmatch.FnmatchTestCase.test_warnings @ linux-x86_64 +test.test_fnmatch.TranslateTestCase.test_translate @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_format.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_format.txt new file mode 100644 index 0000000000..d90ff3ebf4 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_format.txt @@ -0,0 +1,12 @@ +test.test_format.FormatTest.test_bytes_and_bytearray_format @ linux-x86_64 +test.test_format.FormatTest.test_common_format @ linux-x86_64 +test.test_format.FormatTest.test_g_format_has_no_trailing_zeros @ linux-x86_64 +test.test_format.FormatTest.test_locale @ linux-x86_64 +test.test_format.FormatTest.test_non_ascii @ linux-x86_64 +test.test_format.FormatTest.test_nul @ linux-x86_64 +test.test_format.FormatTest.test_precision @ linux-x86_64 +test.test_format.FormatTest.test_str_format @ linux-x86_64 +test.test_format.FormatTest.test_with_a_commas_and_an_underscore_in_format_specifier @ linux-x86_64 +test.test_format.FormatTest.test_with_an_underscore_and_a_comma_in_format_specifier @ linux-x86_64 +test.test_format.FormatTest.test_with_two_commas_in_format_specifier @ linux-x86_64 +test.test_format.FormatTest.test_with_two_underscore_in_format_specifier @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fractions.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fractions.txt new file mode 100644 index 0000000000..a2b7acbed6 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fractions.txt @@ -0,0 +1,33 @@ +test.test_fractions.FractionTest.testApproximateCos1 @ linux-x86_64 +test.test_fractions.FractionTest.testApproximatePi @ linux-x86_64 +test.test_fractions.FractionTest.testArithmetic @ linux-x86_64 +test.test_fractions.FractionTest.testBigComplexComparisons @ linux-x86_64 +test.test_fractions.FractionTest.testBigFloatComparisons @ linux-x86_64 +test.test_fractions.FractionTest.testBoolGuarateesBoolReturn @ linux-x86_64 +test.test_fractions.FractionTest.testComparisons @ linux-x86_64 +test.test_fractions.FractionTest.testComparisonsDummyFloat @ linux-x86_64 +test.test_fractions.FractionTest.testComparisonsDummyRational @ linux-x86_64 +test.test_fractions.FractionTest.testConversions @ linux-x86_64 +test.test_fractions.FractionTest.testFromDecimal @ linux-x86_64 +test.test_fractions.FractionTest.testFromFloat @ linux-x86_64 +test.test_fractions.FractionTest.testFromString @ linux-x86_64 +test.test_fractions.FractionTest.testHash @ linux-x86_64 +test.test_fractions.FractionTest.testImmutable @ linux-x86_64 +test.test_fractions.FractionTest.testInit @ linux-x86_64 +test.test_fractions.FractionTest.testInitFromDecimal @ linux-x86_64 +test.test_fractions.FractionTest.testInitFromFloat @ linux-x86_64 +test.test_fractions.FractionTest.testIntGuaranteesIntReturn @ linux-x86_64 +test.test_fractions.FractionTest.testLargeArithmetic @ linux-x86_64 +test.test_fractions.FractionTest.testLimitDenominator @ linux-x86_64 +test.test_fractions.FractionTest.testMixedArithmetic @ linux-x86_64 +test.test_fractions.FractionTest.testMixedEqual @ linux-x86_64 +test.test_fractions.FractionTest.testMixedLess @ linux-x86_64 +test.test_fractions.FractionTest.testMixedLessEqual @ linux-x86_64 +test.test_fractions.FractionTest.testMixingWithDecimal @ linux-x86_64 +test.test_fractions.FractionTest.testRound @ linux-x86_64 +test.test_fractions.FractionTest.testStringification @ linux-x86_64 +test.test_fractions.FractionTest.testSupportsInt @ linux-x86_64 +test.test_fractions.FractionTest.test_as_integer_ratio @ linux-x86_64 +test.test_fractions.FractionTest.test_copy_deepcopy_pickle @ linux-x86_64 +test.test_fractions.FractionTest.test_int_subclass @ linux-x86_64 +test.test_fractions.FractionTest.test_slots @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_frame.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_frame.txt new file mode 100644 index 0000000000..ba0e568adc --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_frame.txt @@ -0,0 +1,5 @@ +test.test_frame.ClearTest.test_clear_does_not_clear_specials @ linux-x86_64 +test.test_frame.ClearTest.test_lineno_with_tracing @ linux-x86_64 +test.test_frame.FrameAttrsTest.test_f_lineno_del_segfault @ linux-x86_64 +test.test_frame.FrameAttrsTest.test_locals @ linux-x86_64 +test.test_frame.ReprTest.test_repr @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_frozen.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_frozen.txt new file mode 100644 index 0000000000..9b6e502a8f --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_frozen.txt @@ -0,0 +1,3 @@ +test.test_frozen.TestFrozen.test_frozen @ linux-x86_64 +test.test_frozen.TestFrozen.test_frozen_submodule_in_unfrozen_package @ linux-x86_64 +test.test_frozen.TestFrozen.test_unfrozen_submodule_in_frozen_package @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fstring.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fstring.txt new file mode 100644 index 0000000000..a47c1e7c43 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_fstring.txt @@ -0,0 +1,66 @@ +test.test_fstring.TestCase.test__format__lookup @ linux-x86_64 +test.test_fstring.TestCase.test_arguments @ linux-x86_64 +test.test_fstring.TestCase.test_assignment @ linux-x86_64 +test.test_fstring.TestCase.test_ast @ linux-x86_64 +test.test_fstring.TestCase.test_ast_compile_time_concat @ linux-x86_64 +test.test_fstring.TestCase.test_ast_line_numbers @ linux-x86_64 +test.test_fstring.TestCase.test_ast_line_numbers_duplicate_expression @ linux-x86_64 +test.test_fstring.TestCase.test_ast_line_numbers_multiple_formattedvalues @ linux-x86_64 +test.test_fstring.TestCase.test_ast_line_numbers_nested @ linux-x86_64 +test.test_fstring.TestCase.test_ast_numbers_fstring_with_formatting @ linux-x86_64 +test.test_fstring.TestCase.test_backslash_char @ linux-x86_64 +test.test_fstring.TestCase.test_backslashes_in_string_part @ linux-x86_64 +test.test_fstring.TestCase.test_call @ linux-x86_64 +test.test_fstring.TestCase.test_closure @ linux-x86_64 +test.test_fstring.TestCase.test_comments @ linux-x86_64 +test.test_fstring.TestCase.test_compile_time_concat @ linux-x86_64 +test.test_fstring.TestCase.test_compile_time_concat_errors @ linux-x86_64 +test.test_fstring.TestCase.test_conversions @ linux-x86_64 +test.test_fstring.TestCase.test_debug_conversion @ linux-x86_64 +test.test_fstring.TestCase.test_del @ linux-x86_64 +test.test_fstring.TestCase.test_dict @ linux-x86_64 +test.test_fstring.TestCase.test_docstring @ linux-x86_64 +test.test_fstring.TestCase.test_double_braces @ linux-x86_64 +test.test_fstring.TestCase.test_empty_format_specifier @ linux-x86_64 +test.test_fstring.TestCase.test_equal_equal @ linux-x86_64 +test.test_fstring.TestCase.test_errors @ linux-x86_64 +test.test_fstring.TestCase.test_expressions_with_triple_quoted_strings @ linux-x86_64 +test.test_fstring.TestCase.test_filename_in_syntaxerror @ linux-x86_64 +test.test_fstring.TestCase.test_format_specifier_expressions @ linux-x86_64 +test.test_fstring.TestCase.test_global @ linux-x86_64 +test.test_fstring.TestCase.test_if_conditional @ linux-x86_64 +test.test_fstring.TestCase.test_invalid_string_prefixes @ linux-x86_64 +test.test_fstring.TestCase.test_invalid_syntax_error_message @ linux-x86_64 +test.test_fstring.TestCase.test_lambda @ linux-x86_64 +test.test_fstring.TestCase.test_leading_trailing_spaces @ linux-x86_64 +test.test_fstring.TestCase.test_literal @ linux-x86_64 +test.test_fstring.TestCase.test_literal_eval @ linux-x86_64 +test.test_fstring.TestCase.test_locals @ linux-x86_64 +test.test_fstring.TestCase.test_loop @ linux-x86_64 +test.test_fstring.TestCase.test_many_expressions @ linux-x86_64 +test.test_fstring.TestCase.test_misformed_unicode_character_name @ linux-x86_64 +test.test_fstring.TestCase.test_mismatched_braces @ linux-x86_64 +test.test_fstring.TestCase.test_mismatched_parens @ linux-x86_64 +test.test_fstring.TestCase.test_missing_expression @ linux-x86_64 +test.test_fstring.TestCase.test_missing_format_spec @ linux-x86_64 +test.test_fstring.TestCase.test_missing_variable @ linux-x86_64 +test.test_fstring.TestCase.test_multiple_vars @ linux-x86_64 +test.test_fstring.TestCase.test_nested_fstrings @ linux-x86_64 +test.test_fstring.TestCase.test_newlines_before_syntax_error @ linux-x86_64 +test.test_fstring.TestCase.test_newlines_in_expressions @ linux-x86_64 +test.test_fstring.TestCase.test_no_backslashes_in_expression_part @ linux-x86_64 +test.test_fstring.TestCase.test_no_escapes_for_braces @ linux-x86_64 +test.test_fstring.TestCase.test_not_equal @ linux-x86_64 +test.test_fstring.TestCase.test_parens_in_expressions @ linux-x86_64 +test.test_fstring.TestCase.test_shadowed_global @ linux-x86_64 +test.test_fstring.TestCase.test_side_effect_order @ linux-x86_64 +test.test_fstring.TestCase.test_str_format_differences @ linux-x86_64 +test.test_fstring.TestCase.test_syntax_error_for_starred_expressions @ linux-x86_64 +test.test_fstring.TestCase.test_unterminated_string @ linux-x86_64 +test.test_fstring.TestCase.test_walrus @ linux-x86_64 +test.test_fstring.TestCase.test_with_a_commas_and_an_underscore_in_format_specifier @ linux-x86_64 +test.test_fstring.TestCase.test_with_an_underscore_and_a_comma_in_format_specifier @ linux-x86_64 +test.test_fstring.TestCase.test_with_two_commas_in_format_specifier @ linux-x86_64 +test.test_fstring.TestCase.test_with_two_underscore_in_format_specifier @ linux-x86_64 +test.test_fstring.TestCase.test_yield @ linux-x86_64 +test.test_fstring.TestCase.test_yield_send @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ftplib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ftplib.txt new file mode 100644 index 0000000000..f96e315943 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ftplib.txt @@ -0,0 +1,93 @@ +test.test_ftplib.MiscTestCase.test__all__ @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_abort @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_acct @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_all_errors @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_cwd @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_delete @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_dir @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_encoding_param @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_exceptions @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_getwelcome @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_line_too_long @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_login @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_makepasv @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_makepasv_issue43285_security_disabled @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_makepasv_issue43285_security_enabled_default @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_makeport @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_mkd @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_mlsd @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_nlst @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_parse257 @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_pwd @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_quit @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_rename @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_retrbinary @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_retrbinary_rest @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_retrlines @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_retrlines_too_long @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_rmd @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_sanitize @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_set_pasv @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_size @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_source_address @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_source_address_passive_connection @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_storbinary @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_storbinary_rest @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_storlines @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_storlines_too_long @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_voidcmd @ linux-x86_64 +test.test_ftplib.TestFTPClass.test_with_statement @ linux-x86_64 +test.test_ftplib.TestIPv6Environment.test_af @ linux-x86_64 +test.test_ftplib.TestIPv6Environment.test_makepasv @ linux-x86_64 +test.test_ftplib.TestIPv6Environment.test_makeport @ linux-x86_64 +test.test_ftplib.TestIPv6Environment.test_transfer @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClass.test_auth_issued_twice @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClass.test_ccc @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClass.test_context @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClass.test_control_connection @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClass.test_data_connection @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClass.test_login @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_abort @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_acct @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_all_errors @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_cwd @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_delete @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_dir @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_encoding_param @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_exceptions @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_getwelcome @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_line_too_long @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_login @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_makepasv @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_makepasv_issue43285_security_disabled @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_makepasv_issue43285_security_enabled_default @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_makeport @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_mkd @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_mlsd @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_nlst @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_parse257 @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_pwd @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_quit @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_rename @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_retrbinary @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_retrbinary_rest @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_retrlines @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_retrlines_too_long @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_rmd @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_sanitize @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_set_pasv @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_size @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_source_address @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_source_address_passive_connection @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_storbinary @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_storbinary_rest @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_storlines @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_storlines_too_long @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_voidcmd @ linux-x86_64 +test.test_ftplib.TestTLS_FTPClassMixin.test_with_statement @ linux-x86_64 +test.test_ftplib.TestTimeouts.testTimeoutConnect @ linux-x86_64 +test.test_ftplib.TestTimeouts.testTimeoutDefault @ linux-x86_64 +test.test_ftplib.TestTimeouts.testTimeoutDifferentOrder @ linux-x86_64 +test.test_ftplib.TestTimeouts.testTimeoutDirectAccess @ linux-x86_64 +test.test_ftplib.TestTimeouts.testTimeoutNone @ linux-x86_64 +test.test_ftplib.TestTimeouts.testTimeoutValue @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_funcattrs.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_funcattrs.txt new file mode 100644 index 0000000000..22e952bf33 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_funcattrs.txt @@ -0,0 +1,30 @@ +test.test_funcattrs.ArbitraryFunctionAttrTest.test_delete_unknown_attr @ linux-x86_64 +test.test_funcattrs.ArbitraryFunctionAttrTest.test_set_attr @ linux-x86_64 +test.test_funcattrs.ArbitraryFunctionAttrTest.test_unset_attr @ linux-x86_64 +test.test_funcattrs.BuiltinFunctionPropertiesTest.test_builtin__qualname__ @ linux-x86_64 +test.test_funcattrs.CellTest.test_comparison @ linux-x86_64 +test.test_funcattrs.FunctionDictsTest.test_delete___dict__ @ linux-x86_64 +test.test_funcattrs.FunctionDictsTest.test_func_as_dict_key @ linux-x86_64 +test.test_funcattrs.FunctionDictsTest.test_setting_dict_to_invalid @ linux-x86_64 +test.test_funcattrs.FunctionDictsTest.test_setting_dict_to_valid @ linux-x86_64 +test.test_funcattrs.FunctionDictsTest.test_unassigned_dict @ linux-x86_64 +test.test_funcattrs.FunctionDocstringTest.test_delete_docstring @ linux-x86_64 +test.test_funcattrs.FunctionDocstringTest.test_set_docstring_attr @ linux-x86_64 +test.test_funcattrs.FunctionPropertiesTest.test___closure__ @ linux-x86_64 +test.test_funcattrs.FunctionPropertiesTest.test___code__ @ linux-x86_64 +test.test_funcattrs.FunctionPropertiesTest.test___globals__ @ linux-x86_64 +test.test_funcattrs.FunctionPropertiesTest.test___name__ @ linux-x86_64 +test.test_funcattrs.FunctionPropertiesTest.test_blank_func_defaults @ linux-x86_64 +test.test_funcattrs.FunctionPropertiesTest.test_cell_new @ linux-x86_64 +test.test_funcattrs.FunctionPropertiesTest.test_copying___code__ @ linux-x86_64 +test.test_funcattrs.FunctionPropertiesTest.test_dir_includes_correct_attrs @ linux-x86_64 +test.test_funcattrs.FunctionPropertiesTest.test_duplicate_function_equality @ linux-x86_64 +test.test_funcattrs.FunctionPropertiesTest.test_empty_cell @ linux-x86_64 +test.test_funcattrs.FunctionPropertiesTest.test_func_default_args @ linux-x86_64 +test.test_funcattrs.FunctionPropertiesTest.test_module @ linux-x86_64 +test.test_funcattrs.FunctionPropertiesTest.test_set_cell @ linux-x86_64 +test.test_funcattrs.InstancemethodAttrTest.test___class__ @ linux-x86_64 +test.test_funcattrs.InstancemethodAttrTest.test___func__ @ linux-x86_64 +test.test_funcattrs.InstancemethodAttrTest.test___func___non_method @ linux-x86_64 +test.test_funcattrs.InstancemethodAttrTest.test___self__ @ linux-x86_64 +test.test_funcattrs.StaticMethodAttrsTest.test_func_attribute @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_functools.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_functools.txt new file mode 100644 index 0000000000..0f23b8017c --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_functools.txt @@ -0,0 +1,243 @@ +test.test_functools.TestCachedProperty.test_access_from_class @ linux-x86_64 +test.test_functools.TestCachedProperty.test_cached @ linux-x86_64 +test.test_functools.TestCachedProperty.test_cached_attribute_name_differs_from_func_name @ linux-x86_64 +test.test_functools.TestCachedProperty.test_doc @ linux-x86_64 +test.test_functools.TestCachedProperty.test_immutable_dict @ linux-x86_64 +test.test_functools.TestCachedProperty.test_object_with_slots @ linux-x86_64 +test.test_functools.TestCachedProperty.test_reuse_different_names @ linux-x86_64 +test.test_functools.TestCachedProperty.test_reuse_same_name @ linux-x86_64 +test.test_functools.TestCachedProperty.test_set_name_not_called @ linux-x86_64 +test.test_functools.TestCachedProperty.test_threaded @ linux-x86_64 +test.test_functools.TestCmpToKeyC.test_bad_cmp @ linux-x86_64 +test.test_functools.TestCmpToKeyC.test_cmp_to_key @ linux-x86_64 +test.test_functools.TestCmpToKeyC.test_cmp_to_key_arguments @ linux-x86_64 +test.test_functools.TestCmpToKeyC.test_hash @ linux-x86_64 +test.test_functools.TestCmpToKeyC.test_obj_field @ linux-x86_64 +test.test_functools.TestCmpToKeyC.test_sort_int @ linux-x86_64 +test.test_functools.TestCmpToKeyC.test_sort_int_str @ linux-x86_64 +test.test_functools.TestCmpToKeyPy.test_bad_cmp @ linux-x86_64 +test.test_functools.TestCmpToKeyPy.test_cmp_to_key @ linux-x86_64 +test.test_functools.TestCmpToKeyPy.test_cmp_to_key_arguments @ linux-x86_64 +test.test_functools.TestCmpToKeyPy.test_hash @ linux-x86_64 +test.test_functools.TestCmpToKeyPy.test_obj_field @ linux-x86_64 +test.test_functools.TestCmpToKeyPy.test_sort_int @ linux-x86_64 +test.test_functools.TestCmpToKeyPy.test_sort_int_str @ linux-x86_64 +test.test_functools.TestLRUC.test_copy @ linux-x86_64 +test.test_functools.TestLRUC.test_deepcopy @ linux-x86_64 +test.test_functools.TestLRUC.test_kwargs_order @ linux-x86_64 +test.test_functools.TestLRUC.test_lru @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_bug_35780 @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_bug_36650 @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_cache_decoration @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_cache_parameters @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_cache_threaded @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_cache_threaded2 @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_cache_threaded3 @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_cache_typed_is_not_recursive @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_hash_only_once @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_method @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_no_args @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_reentrancy_with_len @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_star_arg_handling @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_type_error @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_with_exceptions @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_with_keyword_args @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_with_keyword_args_maxsize_none @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_with_maxsize_negative @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_with_maxsize_none @ linux-x86_64 +test.test_functools.TestLRUC.test_lru_with_types @ linux-x86_64 +test.test_functools.TestLRUC.test_need_for_rlock @ linux-x86_64 +test.test_functools.TestLRUC.test_pickle @ linux-x86_64 +test.test_functools.TestLRUPy.test_copy @ linux-x86_64 +test.test_functools.TestLRUPy.test_deepcopy @ linux-x86_64 +test.test_functools.TestLRUPy.test_kwargs_order @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_bug_35780 @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_bug_36650 @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_cache_decoration @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_cache_parameters @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_cache_threaded @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_cache_threaded2 @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_cache_threaded3 @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_cache_typed_is_not_recursive @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_hash_only_once @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_method @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_no_args @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_reentrancy_with_len @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_star_arg_handling @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_type_error @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_with_exceptions @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_with_keyword_args @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_with_keyword_args_maxsize_none @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_with_maxsize_negative @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_with_maxsize_none @ linux-x86_64 +test.test_functools.TestLRUPy.test_lru_with_types @ linux-x86_64 +test.test_functools.TestLRUPy.test_need_for_rlock @ linux-x86_64 +test.test_functools.TestLRUPy.test_pickle @ linux-x86_64 +test.test_functools.TestPartialC.test_arg_combinations @ linux-x86_64 +test.test_functools.TestPartialC.test_argument_checking @ linux-x86_64 +test.test_functools.TestPartialC.test_attributes @ linux-x86_64 +test.test_functools.TestPartialC.test_attributes_unwritable @ linux-x86_64 +test.test_functools.TestPartialC.test_basic_examples @ linux-x86_64 +test.test_functools.TestPartialC.test_copy @ linux-x86_64 +test.test_functools.TestPartialC.test_deepcopy @ linux-x86_64 +test.test_functools.TestPartialC.test_error_propagation @ linux-x86_64 +test.test_functools.TestPartialC.test_keystr_replaces_value @ linux-x86_64 +test.test_functools.TestPartialC.test_keyword @ linux-x86_64 +test.test_functools.TestPartialC.test_kw_combinations @ linux-x86_64 +test.test_functools.TestPartialC.test_kwargs_copy @ linux-x86_64 +test.test_functools.TestPartialC.test_manually_adding_non_string_keyword @ linux-x86_64 +test.test_functools.TestPartialC.test_nested_optimization @ linux-x86_64 +test.test_functools.TestPartialC.test_nested_partial_with_attribute @ linux-x86_64 +test.test_functools.TestPartialC.test_no_side_effects @ linux-x86_64 +test.test_functools.TestPartialC.test_pickle @ linux-x86_64 +test.test_functools.TestPartialC.test_positional @ linux-x86_64 +test.test_functools.TestPartialC.test_protection_of_callers_dict_argument @ linux-x86_64 +!test.test_functools.TestPartialC.test_recursive_pickle @ linux-x86_64 +test.test_functools.TestPartialC.test_recursive_repr @ linux-x86_64 +test.test_functools.TestPartialC.test_repr @ linux-x86_64 +test.test_functools.TestPartialC.test_setstate @ linux-x86_64 +test.test_functools.TestPartialC.test_setstate_errors @ linux-x86_64 +test.test_functools.TestPartialC.test_setstate_refcount @ linux-x86_64 +test.test_functools.TestPartialC.test_setstate_subclasses @ linux-x86_64 +test.test_functools.TestPartialC.test_with_bound_and_unbound_methods @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_arg_combinations @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_argument_checking @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_attributes @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_attributes_unwritable @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_basic_examples @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_copy @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_deepcopy @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_error_propagation @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_keystr_replaces_value @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_keyword @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_kw_combinations @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_kwargs_copy @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_manually_adding_non_string_keyword @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_nested_partial_with_attribute @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_no_side_effects @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_pickle @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_positional @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_protection_of_callers_dict_argument @ linux-x86_64 +!test.test_functools.TestPartialCSubclass.test_recursive_pickle @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_recursive_repr @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_repr @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_setstate @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_setstate_errors @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_setstate_refcount @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_setstate_subclasses @ linux-x86_64 +test.test_functools.TestPartialCSubclass.test_with_bound_and_unbound_methods @ linux-x86_64 +test.test_functools.TestPartialMethod.test_abstract @ linux-x86_64 +test.test_functools.TestPartialMethod.test_arg_combinations @ linux-x86_64 +test.test_functools.TestPartialMethod.test_bound_method_introspection @ linux-x86_64 +test.test_functools.TestPartialMethod.test_descriptors @ linux-x86_64 +test.test_functools.TestPartialMethod.test_invalid_args @ linux-x86_64 +test.test_functools.TestPartialMethod.test_nested @ linux-x86_64 +test.test_functools.TestPartialMethod.test_over_partial @ linux-x86_64 +test.test_functools.TestPartialMethod.test_overriding_keywords @ linux-x86_64 +test.test_functools.TestPartialMethod.test_positional_only @ linux-x86_64 +test.test_functools.TestPartialMethod.test_repr @ linux-x86_64 +test.test_functools.TestPartialMethod.test_unbound_method_retrieval @ linux-x86_64 +test.test_functools.TestPartialPy.test_arg_combinations @ linux-x86_64 +test.test_functools.TestPartialPy.test_argument_checking @ linux-x86_64 +test.test_functools.TestPartialPy.test_attributes @ linux-x86_64 +test.test_functools.TestPartialPy.test_basic_examples @ linux-x86_64 +test.test_functools.TestPartialPy.test_copy @ linux-x86_64 +test.test_functools.TestPartialPy.test_deepcopy @ linux-x86_64 +test.test_functools.TestPartialPy.test_error_propagation @ linux-x86_64 +test.test_functools.TestPartialPy.test_keyword @ linux-x86_64 +test.test_functools.TestPartialPy.test_kw_combinations @ linux-x86_64 +test.test_functools.TestPartialPy.test_kwargs_copy @ linux-x86_64 +test.test_functools.TestPartialPy.test_nested_optimization @ linux-x86_64 +test.test_functools.TestPartialPy.test_nested_partial_with_attribute @ linux-x86_64 +test.test_functools.TestPartialPy.test_no_side_effects @ linux-x86_64 +test.test_functools.TestPartialPy.test_pickle @ linux-x86_64 +test.test_functools.TestPartialPy.test_positional @ linux-x86_64 +test.test_functools.TestPartialPy.test_protection_of_callers_dict_argument @ linux-x86_64 +!test.test_functools.TestPartialPy.test_recursive_pickle @ linux-x86_64 +test.test_functools.TestPartialPy.test_recursive_repr @ linux-x86_64 +test.test_functools.TestPartialPy.test_repr @ linux-x86_64 +test.test_functools.TestPartialPy.test_setstate @ linux-x86_64 +test.test_functools.TestPartialPy.test_setstate_errors @ linux-x86_64 +test.test_functools.TestPartialPy.test_setstate_refcount @ linux-x86_64 +test.test_functools.TestPartialPy.test_setstate_subclasses @ linux-x86_64 +test.test_functools.TestPartialPy.test_with_bound_and_unbound_methods @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_arg_combinations @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_argument_checking @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_attributes @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_basic_examples @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_copy @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_deepcopy @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_error_propagation @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_keyword @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_kw_combinations @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_kwargs_copy @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_nested_optimization @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_nested_partial_with_attribute @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_no_side_effects @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_pickle @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_positional @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_protection_of_callers_dict_argument @ linux-x86_64 +!test.test_functools.TestPartialPySubclass.test_recursive_pickle @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_recursive_repr @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_repr @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_setstate @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_setstate_errors @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_setstate_refcount @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_setstate_subclasses @ linux-x86_64 +test.test_functools.TestPartialPySubclass.test_with_bound_and_unbound_methods @ linux-x86_64 +test.test_functools.TestReduceC.test_iterator_usage @ linux-x86_64 +test.test_functools.TestReduceC.test_reduce @ linux-x86_64 +test.test_functools.TestReducePy.test_iterator_usage @ linux-x86_64 +test.test_functools.TestReducePy.test_reduce @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_abstractmethod_register @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_annotations @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_c3_abc @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_cache_invalidation @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_callable_register @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_classmethod_register @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_classmethod_type_ann_register @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_compose_mro @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_double_wrapped_methods @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_false_meta @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_invalid_positional_argument @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_invalid_registrations @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_method_register @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_method_wrapping_attributes @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_mro @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_mro_conflicts @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_register_abc @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_register_decorator @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_register_genericalias @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_register_genericalias_annotation @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_register_genericalias_decorator @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_simple_overloads @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_staticmethod_register @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_staticmethod_type_ann_register @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_type_ann_register @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_union @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_union_None @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_union_conflict @ linux-x86_64 +test.test_functools.TestSingleDispatch.test_wrapping_attributes @ linux-x86_64 +test.test_functools.TestTotalOrdering.test_no_operations_defined @ linux-x86_64 +test.test_functools.TestTotalOrdering.test_notimplemented @ linux-x86_64 +test.test_functools.TestTotalOrdering.test_pickle @ linux-x86_64 +test.test_functools.TestTotalOrdering.test_total_ordering_for_metaclasses_issue_44605 @ linux-x86_64 +test.test_functools.TestTotalOrdering.test_total_ordering_ge @ linux-x86_64 +test.test_functools.TestTotalOrdering.test_total_ordering_gt @ linux-x86_64 +test.test_functools.TestTotalOrdering.test_total_ordering_le @ linux-x86_64 +test.test_functools.TestTotalOrdering.test_total_ordering_lt @ linux-x86_64 +test.test_functools.TestTotalOrdering.test_total_ordering_no_overwrite @ linux-x86_64 +test.test_functools.TestTotalOrdering.test_type_error_when_not_implemented @ linux-x86_64 +test.test_functools.TestUpdateWrapper.test_builtin_update @ linux-x86_64 +test.test_functools.TestUpdateWrapper.test_default_update @ linux-x86_64 +test.test_functools.TestUpdateWrapper.test_default_update_doc @ linux-x86_64 +test.test_functools.TestUpdateWrapper.test_missing_attributes @ linux-x86_64 +test.test_functools.TestUpdateWrapper.test_no_update @ linux-x86_64 +test.test_functools.TestUpdateWrapper.test_selective_update @ linux-x86_64 +test.test_functools.TestWraps.test_builtin_update @ linux-x86_64 +test.test_functools.TestWraps.test_default_update @ linux-x86_64 +test.test_functools.TestWraps.test_default_update_doc @ linux-x86_64 +test.test_functools.TestWraps.test_missing_attributes @ linux-x86_64 +test.test_functools.TestWraps.test_no_update @ linux-x86_64 +test.test_functools.TestWraps.test_selective_update @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_future_stmt.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_future_stmt.txt new file mode 100644 index 0000000000..882a010086 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_future_stmt.txt @@ -0,0 +1,27 @@ +test.test_future_stmt.test_future.AnnotationsFutureTestCase.test_annotation_with_complex_target @ linux-x86_64 +test.test_future_stmt.test_future.AnnotationsFutureTestCase.test_annotations_forbidden @ linux-x86_64 +test.test_future_stmt.test_future.AnnotationsFutureTestCase.test_annotations_symbol_table_pass @ linux-x86_64 +test.test_future_stmt.test_future.AnnotationsFutureTestCase.test_get_type_hints_on_func_with_variadic_arg @ linux-x86_64 +test.test_future_stmt.test_future.FutureTest.test_badfuture10 @ linux-x86_64 +test.test_future_stmt.test_future.FutureTest.test_badfuture3 @ linux-x86_64 +test.test_future_stmt.test_future.FutureTest.test_badfuture4 @ linux-x86_64 +test.test_future_stmt.test_future.FutureTest.test_badfuture5 @ linux-x86_64 +test.test_future_stmt.test_future.FutureTest.test_badfuture6 @ linux-x86_64 +test.test_future_stmt.test_future.FutureTest.test_badfuture8 @ linux-x86_64 +test.test_future_stmt.test_future.FutureTest.test_badfuture9 @ linux-x86_64 +test.test_future_stmt.test_future.FutureTest.test_ensure_flags_dont_clash @ linux-x86_64 +test.test_future_stmt.test_future.FutureTest.test_future1 @ linux-x86_64 +test.test_future_stmt.test_future.FutureTest.test_future2 @ linux-x86_64 +test.test_future_stmt.test_future.FutureTest.test_future_multiple_features @ linux-x86_64 +test.test_future_stmt.test_future.FutureTest.test_future_multiple_imports @ linux-x86_64 +test.test_future_stmt.test_future.FutureTest.test_future_single_import @ linux-x86_64 +test.test_future_stmt.test_future.FutureTest.test_parserhack @ linux-x86_64 +test.test_future_stmt.test_future.FutureTest.test_unicode_literals_exec @ linux-x86_64 +test.test_future_stmt.test_future_flags.FutureTest.test_attributes @ linux-x86_64 +test.test_future_stmt.test_future_flags.FutureTest.test_names @ linux-x86_64 +test.test_future_stmt.test_future_multiple_features.TestMultipleFeatures.test_print_function @ linux-x86_64 +test.test_future_stmt.test_future_multiple_features.TestMultipleFeatures.test_unicode_literals @ linux-x86_64 +test.test_future_stmt.test_future_multiple_imports.Tests.test_unicode_literals @ linux-x86_64 +test.test_future_stmt.test_future_single_import.TestFuture.test_floor_div_operator @ linux-x86_64 +test.test_future_stmt.test_future_single_import.TestFuture.test_nested_scopes @ linux-x86_64 +test.test_future_stmt.test_future_single_import.TestFuture.test_true_div_as_default @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_gc.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_gc.txt new file mode 100644 index 0000000000..060f29052b --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_gc.txt @@ -0,0 +1,4 @@ +test.test_gc.GCTests.test_bug21435 @ linux-x86_64 +test.test_gc.GCTests.test_trash_weakref_clear @ linux-x86_64 +test.test_gc.GCTests.test_trashcan @ linux-x86_64 +test.test_gc.PythonFinalizationTests.test_ast_fini @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_generator_stop.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_generator_stop.txt new file mode 100644 index 0000000000..15823559d7 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_generator_stop.txt @@ -0,0 +1,2 @@ +test.test_generator_stop.TestPEP479.test_stopiteration_wrapping @ linux-x86_64 +test.test_generator_stop.TestPEP479.test_stopiteration_wrapping_context @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_generators.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_generators.txt new file mode 100644 index 0000000000..9b87a9580c --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_generators.txt @@ -0,0 +1,19 @@ +DocTestCase.test.test_generators.__test__.conjoin @ linux-x86_64 +DocTestCase.test.test_generators.__test__.coroutine @ linux-x86_64 +DocTestCase.test.test_generators.__test__.fun @ linux-x86_64 +DocTestCase.test.test_generators.__test__.pep @ linux-x86_64 +DocTestCase.test.test_generators.__test__.refleaks @ linux-x86_64 +DocTestCase.test.test_generators.__test__.syntax @ linux-x86_64 +DocTestCase.test.test_generators.__test__.tut @ linux-x86_64 +DocTestCase.test.test_generators.__test__.weakref @ linux-x86_64 +test.test_generators.ExceptionTest.test_except_throw_bad_exception @ linux-x86_64 +test.test_generators.ExceptionTest.test_return_stopiteration @ linux-x86_64 +test.test_generators.ExceptionTest.test_return_tuple @ linux-x86_64 +test.test_generators.ExceptionTest.test_stopiteration_error @ linux-x86_64 +test.test_generators.ExceptionTest.test_tutorial_stopiteration @ linux-x86_64 +test.test_generators.GeneratorStackTraceTest.test_send_with_yield_from @ linux-x86_64 +test.test_generators.GeneratorStackTraceTest.test_throw_with_yield_from @ linux-x86_64 +test.test_generators.GeneratorTest.test_copy @ linux-x86_64 +test.test_generators.GeneratorTest.test_pickle @ linux-x86_64 +test.test_generators.GeneratorTest.test_send_non_none_to_new_gen @ linux-x86_64 +test.test_generators.GeneratorThrowTest.test_throw_after_none_exc_type @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_genericalias.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_genericalias.txt new file mode 100644 index 0000000000..597b9f718e --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_genericalias.txt @@ -0,0 +1,29 @@ +test.test_genericalias.BaseTest.test_calling_next_twice_raises_stopiteration @ linux-x86_64 +test.test_genericalias.BaseTest.test_class_methods @ linux-x86_64 +test.test_genericalias.BaseTest.test_copy @ linux-x86_64 +test.test_genericalias.BaseTest.test_del_iter @ linux-x86_64 +test.test_genericalias.BaseTest.test_dir @ linux-x86_64 +test.test_genericalias.BaseTest.test_equality @ linux-x86_64 +test.test_genericalias.BaseTest.test_exposed_type @ linux-x86_64 +test.test_genericalias.BaseTest.test_generic_subclass @ linux-x86_64 +test.test_genericalias.BaseTest.test_instantiate @ linux-x86_64 +test.test_genericalias.BaseTest.test_isinstance @ linux-x86_64 +test.test_genericalias.BaseTest.test_issubclass @ linux-x86_64 +test.test_genericalias.BaseTest.test_iter_creates_starred_tuple @ linux-x86_64 +test.test_genericalias.BaseTest.test_no_chaining @ linux-x86_64 +test.test_genericalias.BaseTest.test_no_kwargs @ linux-x86_64 +test.test_genericalias.BaseTest.test_parameter_chaining @ linux-x86_64 +test.test_genericalias.BaseTest.test_parameters @ linux-x86_64 +test.test_genericalias.BaseTest.test_pickle @ linux-x86_64 +test.test_genericalias.BaseTest.test_repr @ linux-x86_64 +test.test_genericalias.BaseTest.test_subclassing @ linux-x86_64 +test.test_genericalias.BaseTest.test_subclassing_types_genericalias @ linux-x86_64 +test.test_genericalias.BaseTest.test_type_generic @ linux-x86_64 +test.test_genericalias.BaseTest.test_type_subclass_generic @ linux-x86_64 +test.test_genericalias.BaseTest.test_unbound_methods @ linux-x86_64 +test.test_genericalias.BaseTest.test_union @ linux-x86_64 +test.test_genericalias.BaseTest.test_union_generic @ linux-x86_64 +test.test_genericalias.BaseTest.test_unpack @ linux-x86_64 +test.test_genericalias.BaseTest.test_unsubscriptable @ linux-x86_64 +test.test_genericalias.TypeIterationTests.test_cannot_iterate @ linux-x86_64 +test.test_genericalias.TypeIterationTests.test_is_not_instance_of_iterable @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_genericclass.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_genericclass.txt new file mode 100644 index 0000000000..dbcbd8dee2 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_genericclass.txt @@ -0,0 +1,21 @@ +test.test_genericclass.TestClassGetitem.test_class_getitem @ linux-x86_64 +test.test_genericclass.TestClassGetitem.test_class_getitem_classmethod @ linux-x86_64 +test.test_genericclass.TestClassGetitem.test_class_getitem_errors @ linux-x86_64 +test.test_genericclass.TestClassGetitem.test_class_getitem_errors_2 @ linux-x86_64 +test.test_genericclass.TestClassGetitem.test_class_getitem_format @ linux-x86_64 +test.test_genericclass.TestClassGetitem.test_class_getitem_inheritance @ linux-x86_64 +test.test_genericclass.TestClassGetitem.test_class_getitem_inheritance_2 @ linux-x86_64 +test.test_genericclass.TestClassGetitem.test_class_getitem_metaclass @ linux-x86_64 +test.test_genericclass.TestClassGetitem.test_class_getitem_metaclass_first @ linux-x86_64 +test.test_genericclass.TestClassGetitem.test_class_getitem_patched @ linux-x86_64 +test.test_genericclass.TestClassGetitem.test_class_getitem_with_builtins @ linux-x86_64 +test.test_genericclass.TestClassGetitem.test_class_getitem_with_metaclass @ linux-x86_64 +test.test_genericclass.TestMROEntry.test_mro_entry @ linux-x86_64 +test.test_genericclass.TestMROEntry.test_mro_entry_errors @ linux-x86_64 +test.test_genericclass.TestMROEntry.test_mro_entry_errors_2 @ linux-x86_64 +test.test_genericclass.TestMROEntry.test_mro_entry_metaclass @ linux-x86_64 +test.test_genericclass.TestMROEntry.test_mro_entry_none @ linux-x86_64 +test.test_genericclass.TestMROEntry.test_mro_entry_signature @ linux-x86_64 +test.test_genericclass.TestMROEntry.test_mro_entry_type_call @ linux-x86_64 +test.test_genericclass.TestMROEntry.test_mro_entry_with_builtins @ linux-x86_64 +test.test_genericclass.TestMROEntry.test_mro_entry_with_builtins_2 @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_genericpath.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_genericpath.txt new file mode 100644 index 0000000000..123bc7545c --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_genericpath.txt @@ -0,0 +1,24 @@ +test.test_genericpath.PathLikeTests.test_path_commonprefix @ linux-x86_64 +test.test_genericpath.PathLikeTests.test_path_exists @ linux-x86_64 +test.test_genericpath.PathLikeTests.test_path_getctime @ linux-x86_64 +test.test_genericpath.PathLikeTests.test_path_getmtime @ linux-x86_64 +test.test_genericpath.PathLikeTests.test_path_getsize @ linux-x86_64 +test.test_genericpath.PathLikeTests.test_path_isdir @ linux-x86_64 +test.test_genericpath.PathLikeTests.test_path_isfile @ linux-x86_64 +test.test_genericpath.PathLikeTests.test_path_samefile @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_commonprefix @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_exists @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_exists_fd @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_filetime @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_getsize @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_invalid_paths @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_isdir @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_isfile @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_no_argument @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_samefile @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_samefile_on_link @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_samefile_on_symlink @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_sameopenfile @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_samestat @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_samestat_on_link @ linux-x86_64 +test.test_genericpath.TestGenericTest.test_samestat_on_symlink @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_genexps.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_genexps.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_getopt.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_getopt.txt new file mode 100644 index 0000000000..8cd52c58d6 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_getopt.txt @@ -0,0 +1,8 @@ +DocTestCase.test.test_getopt.test_libref_examples @ linux-x86_64 +test.test_getopt.GetoptTests.test_do_longs @ linux-x86_64 +test.test_getopt.GetoptTests.test_do_shorts @ linux-x86_64 +test.test_getopt.GetoptTests.test_getopt @ linux-x86_64 +test.test_getopt.GetoptTests.test_gnu_getopt @ linux-x86_64 +test.test_getopt.GetoptTests.test_issue4629 @ linux-x86_64 +test.test_getopt.GetoptTests.test_long_has_args @ linux-x86_64 +test.test_getopt.GetoptTests.test_short_has_arg @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_getpass.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_getpass.txt new file mode 100644 index 0000000000..581d65f3a0 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_getpass.txt @@ -0,0 +1,14 @@ +test.test_getpass.GetpassGetuserTest.test_username_falls_back_to_pwd @ linux-x86_64 +test.test_getpass.GetpassGetuserTest.test_username_priorities_of_env_values @ linux-x86_64 +test.test_getpass.GetpassGetuserTest.test_username_takes_username_from_env @ linux-x86_64 +test.test_getpass.GetpassRawinputTest.test_flushes_stream_after_prompt @ linux-x86_64 +test.test_getpass.GetpassRawinputTest.test_raises_on_empty_input @ linux-x86_64 +test.test_getpass.GetpassRawinputTest.test_trims_trailing_newline @ linux-x86_64 +test.test_getpass.GetpassRawinputTest.test_uses_stderr_as_default @ linux-x86_64 +test.test_getpass.GetpassRawinputTest.test_uses_stdin_as_default_input @ linux-x86_64 +test.test_getpass.GetpassRawinputTest.test_uses_stdin_as_different_locale @ linux-x86_64 +test.test_getpass.UnixGetpassTest.test_falls_back_to_fallback_if_termios_raises @ linux-x86_64 +test.test_getpass.UnixGetpassTest.test_falls_back_to_stdin @ linux-x86_64 +test.test_getpass.UnixGetpassTest.test_flushes_stream_after_input @ linux-x86_64 +test.test_getpass.UnixGetpassTest.test_resets_termios @ linux-x86_64 +test.test_getpass.UnixGetpassTest.test_uses_tty_directly @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_gettext.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_gettext.txt new file mode 100644 index 0000000000..34862ff8fe --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_gettext.txt @@ -0,0 +1,43 @@ +test.test_gettext.GNUTranslationParsingTest.test_ignore_comments_in_headers_issue36239 @ linux-x86_64 +test.test_gettext.GNUTranslationParsingTest.test_plural_form_error_issue17898 @ linux-x86_64 +test.test_gettext.GNUTranslationsClassPluralFormsTestCase.test_plural_context_forms @ linux-x86_64 +test.test_gettext.GNUTranslationsClassPluralFormsTestCase.test_plural_context_forms_null_translations @ linux-x86_64 +test.test_gettext.GNUTranslationsClassPluralFormsTestCase.test_plural_forms @ linux-x86_64 +test.test_gettext.GNUTranslationsClassPluralFormsTestCase.test_plural_forms_null_translations @ linux-x86_64 +test.test_gettext.GNUTranslationsClassPluralFormsTestCase.test_plural_wrong_context_forms @ linux-x86_64 +test.test_gettext.GNUTranslationsPluralFormsTestCase.test_plural_context_forms @ linux-x86_64 +test.test_gettext.GNUTranslationsPluralFormsTestCase.test_plural_forms @ linux-x86_64 +test.test_gettext.GNUTranslationsPluralFormsTestCase.test_plural_wrong_context_forms @ linux-x86_64 +test.test_gettext.GNUTranslationsWithDomainPluralFormsTestCase.test_plural_context_forms @ linux-x86_64 +test.test_gettext.GNUTranslationsWithDomainPluralFormsTestCase.test_plural_context_forms_wrong_domain @ linux-x86_64 +test.test_gettext.GNUTranslationsWithDomainPluralFormsTestCase.test_plural_forms @ linux-x86_64 +test.test_gettext.GNUTranslationsWithDomainPluralFormsTestCase.test_plural_forms_wrong_domain @ linux-x86_64 +test.test_gettext.GNUTranslationsWithDomainPluralFormsTestCase.test_plural_wrong_context_forms @ linux-x86_64 +test.test_gettext.GettextCacheTestCase.test_cache @ linux-x86_64 +test.test_gettext.GettextTestCase1.test_double_quotes @ linux-x86_64 +test.test_gettext.GettextTestCase1.test_multiline_strings @ linux-x86_64 +test.test_gettext.GettextTestCase1.test_some_translations @ linux-x86_64 +test.test_gettext.GettextTestCase1.test_some_translations_with_context @ linux-x86_64 +test.test_gettext.GettextTestCase1.test_the_alternative_interface @ linux-x86_64 +test.test_gettext.GettextTestCase1.test_triple_double_quotes @ linux-x86_64 +test.test_gettext.GettextTestCase1.test_triple_single_quotes @ linux-x86_64 +test.test_gettext.GettextTestCase2.test_bad_major_version @ linux-x86_64 +test.test_gettext.GettextTestCase2.test_bad_minor_version @ linux-x86_64 +test.test_gettext.GettextTestCase2.test_bindtextdomain @ linux-x86_64 +test.test_gettext.GettextTestCase2.test_double_quotes @ linux-x86_64 +test.test_gettext.GettextTestCase2.test_multiline_strings @ linux-x86_64 +test.test_gettext.GettextTestCase2.test_some_translations @ linux-x86_64 +test.test_gettext.GettextTestCase2.test_some_translations_with_context @ linux-x86_64 +test.test_gettext.GettextTestCase2.test_some_translations_with_context_and_domain @ linux-x86_64 +test.test_gettext.GettextTestCase2.test_textdomain @ linux-x86_64 +test.test_gettext.GettextTestCase2.test_triple_double_quotes @ linux-x86_64 +test.test_gettext.GettextTestCase2.test_triple_single_quotes @ linux-x86_64 +test.test_gettext.MiscTestCase.test__all__ @ linux-x86_64 +test.test_gettext.UnicodeTranslationsPluralTest.test_unicode_context_msgid @ linux-x86_64 +test.test_gettext.UnicodeTranslationsPluralTest.test_unicode_msgid @ linux-x86_64 +test.test_gettext.UnicodeTranslationsPluralTest.test_unicode_msgstr @ linux-x86_64 +test.test_gettext.UnicodeTranslationsPluralTest.test_unicode_msgstr_with_context @ linux-x86_64 +test.test_gettext.UnicodeTranslationsTest.test_unicode_context_msgstr @ linux-x86_64 +test.test_gettext.UnicodeTranslationsTest.test_unicode_msgid @ linux-x86_64 +test.test_gettext.UnicodeTranslationsTest.test_unicode_msgstr @ linux-x86_64 +test.test_gettext.WeirdMetadataTest.test_weird_metadata @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_glob.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_glob.txt new file mode 100644 index 0000000000..25bb39a632 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_glob.txt @@ -0,0 +1,14 @@ +test.test_glob.GlobTests.test_escape @ linux-x86_64 +test.test_glob.GlobTests.test_glob_broken_symlinks @ linux-x86_64 +test.test_glob.GlobTests.test_glob_bytes_directory_with_trailing_slash @ linux-x86_64 +test.test_glob.GlobTests.test_glob_directory_names @ linux-x86_64 +test.test_glob.GlobTests.test_glob_directory_with_trailing_slash @ linux-x86_64 +test.test_glob.GlobTests.test_glob_empty_pattern @ linux-x86_64 +test.test_glob.GlobTests.test_glob_literal @ linux-x86_64 +test.test_glob.GlobTests.test_glob_many_open_files @ linux-x86_64 +test.test_glob.GlobTests.test_glob_nested_directory @ linux-x86_64 +test.test_glob.GlobTests.test_glob_one_directory @ linux-x86_64 +test.test_glob.GlobTests.test_glob_symlinks @ linux-x86_64 +test.test_glob.GlobTests.test_hidden_glob @ linux-x86_64 +test.test_glob.GlobTests.test_recursive_glob @ linux-x86_64 +!test.test_glob.SymlinkLoopGlobTests.test_selflink @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_global.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_global.txt new file mode 100644 index 0000000000..2238dcc5f3 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_global.txt @@ -0,0 +1,4 @@ +test.test_global.GlobalTests.test1 @ linux-x86_64 +test.test_global.GlobalTests.test2 @ linux-x86_64 +test.test_global.GlobalTests.test3 @ linux-x86_64 +test.test_global.GlobalTests.test4 @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_grammar.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_grammar.txt new file mode 100644 index 0000000000..92ca68e163 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_grammar.txt @@ -0,0 +1,67 @@ +test.test_grammar.GrammarTests.test_additive_ops @ linux-x86_64 +test.test_grammar.GrammarTests.test_annotations_inheritance @ linux-x86_64 +test.test_grammar.GrammarTests.test_assert @ linux-x86_64 +test.test_grammar.GrammarTests.test_assert_failures @ linux-x86_64 +test.test_grammar.GrammarTests.test_async_await @ linux-x86_64 +test.test_grammar.GrammarTests.test_atoms @ linux-x86_64 +test.test_grammar.GrammarTests.test_binary_mask_ops @ linux-x86_64 +test.test_grammar.GrammarTests.test_break_continue_loop @ linux-x86_64 +test.test_grammar.GrammarTests.test_break_in_finally @ linux-x86_64 +test.test_grammar.GrammarTests.test_break_in_finally_after_return @ linux-x86_64 +test.test_grammar.GrammarTests.test_break_stmt @ linux-x86_64 +test.test_grammar.GrammarTests.test_classdef @ linux-x86_64 +test.test_grammar.GrammarTests.test_comparison @ linux-x86_64 +test.test_grammar.GrammarTests.test_comparison_is_literal @ linux-x86_64 +test.test_grammar.GrammarTests.test_comprehension_specials @ linux-x86_64 +test.test_grammar.GrammarTests.test_continue_in_finally @ linux-x86_64 +test.test_grammar.GrammarTests.test_continue_in_finally_after_return @ linux-x86_64 +test.test_grammar.GrammarTests.test_continue_stmt @ linux-x86_64 +test.test_grammar.GrammarTests.test_del_stmt @ linux-x86_64 +test.test_grammar.GrammarTests.test_dictcomps @ linux-x86_64 +test.test_grammar.GrammarTests.test_eval_input @ linux-x86_64 +test.test_grammar.GrammarTests.test_expr_stmt @ linux-x86_64 +test.test_grammar.GrammarTests.test_for @ linux-x86_64 +test.test_grammar.GrammarTests.test_former_statements_refer_to_builtins @ linux-x86_64 +test.test_grammar.GrammarTests.test_funcdef @ linux-x86_64 +test.test_grammar.GrammarTests.test_genexps @ linux-x86_64 +test.test_grammar.GrammarTests.test_global @ linux-x86_64 +test.test_grammar.GrammarTests.test_if @ linux-x86_64 +test.test_grammar.GrammarTests.test_if_else_expr @ linux-x86_64 +test.test_grammar.GrammarTests.test_import @ linux-x86_64 +test.test_grammar.GrammarTests.test_lambdef @ linux-x86_64 +test.test_grammar.GrammarTests.test_listcomps @ linux-x86_64 +test.test_grammar.GrammarTests.test_matrix_mul @ linux-x86_64 +test.test_grammar.GrammarTests.test_multiplicative_ops @ linux-x86_64 +test.test_grammar.GrammarTests.test_nonlocal @ linux-x86_64 +test.test_grammar.GrammarTests.test_paren_evaluation @ linux-x86_64 +test.test_grammar.GrammarTests.test_pass_stmt @ linux-x86_64 +test.test_grammar.GrammarTests.test_raise @ linux-x86_64 +test.test_grammar.GrammarTests.test_return @ linux-x86_64 +test.test_grammar.GrammarTests.test_return_in_finally @ linux-x86_64 +test.test_grammar.GrammarTests.test_selectors @ linux-x86_64 +test.test_grammar.GrammarTests.test_shift_ops @ linux-x86_64 +test.test_grammar.GrammarTests.test_simple_stmt @ linux-x86_64 +test.test_grammar.GrammarTests.test_suite @ linux-x86_64 +test.test_grammar.GrammarTests.test_test @ linux-x86_64 +test.test_grammar.GrammarTests.test_try @ linux-x86_64 +test.test_grammar.GrammarTests.test_unary_ops @ linux-x86_64 +test.test_grammar.GrammarTests.test_var_annot_basic_semantics @ linux-x86_64 +test.test_grammar.GrammarTests.test_var_annot_basics @ linux-x86_64 +test.test_grammar.GrammarTests.test_var_annot_in_module @ linux-x86_64 +test.test_grammar.GrammarTests.test_var_annot_module_semantics @ linux-x86_64 +test.test_grammar.GrammarTests.test_var_annot_rhs @ linux-x86_64 +test.test_grammar.GrammarTests.test_var_annot_simple_exec @ linux-x86_64 +test.test_grammar.GrammarTests.test_var_annot_syntax_errors @ linux-x86_64 +test.test_grammar.GrammarTests.test_while @ linux-x86_64 +test.test_grammar.GrammarTests.test_with_statement @ linux-x86_64 +test.test_grammar.TokenTests.test_backslash @ linux-x86_64 +test.test_grammar.TokenTests.test_bad_numerical_literals @ linux-x86_64 +test.test_grammar.TokenTests.test_ellipsis @ linux-x86_64 +test.test_grammar.TokenTests.test_end_of_numerical_literals @ linux-x86_64 +test.test_grammar.TokenTests.test_eof_error @ linux-x86_64 +test.test_grammar.TokenTests.test_float_exponent_tokenization @ linux-x86_64 +test.test_grammar.TokenTests.test_floats @ linux-x86_64 +test.test_grammar.TokenTests.test_long_integers @ linux-x86_64 +test.test_grammar.TokenTests.test_plain_integers @ linux-x86_64 +test.test_grammar.TokenTests.test_string_literals @ linux-x86_64 +test.test_grammar.TokenTests.test_underscore_literals @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_graphlib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_graphlib.txt new file mode 100644 index 0000000000..54dd30a3ef --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_graphlib.txt @@ -0,0 +1,15 @@ +test.test_graphlib.TestTopologicalSort.test_add_dependencies_for_same_node_incrementally @ linux-x86_64 +test.test_graphlib.TestTopologicalSort.test_calls_before_prepare @ linux-x86_64 +test.test_graphlib.TestTopologicalSort.test_cycle @ linux-x86_64 +test.test_graphlib.TestTopologicalSort.test_done @ linux-x86_64 +test.test_graphlib.TestTopologicalSort.test_empty @ linux-x86_64 +test.test_graphlib.TestTopologicalSort.test_graph_with_iterables @ linux-x86_64 +test.test_graphlib.TestTopologicalSort.test_invalid_nodes_in_done @ linux-x86_64 +test.test_graphlib.TestTopologicalSort.test_is_active @ linux-x86_64 +test.test_graphlib.TestTopologicalSort.test_no_dependencies @ linux-x86_64 +test.test_graphlib.TestTopologicalSort.test_not_hashable_nodes @ linux-x86_64 +test.test_graphlib.TestTopologicalSort.test_order_of_insertion_does_not_matter_between_groups @ linux-x86_64 +test.test_graphlib.TestTopologicalSort.test_prepare_multiple_times @ linux-x86_64 +test.test_graphlib.TestTopologicalSort.test_simple_cases @ linux-x86_64 +test.test_graphlib.TestTopologicalSort.test_static_order_does_not_change_with_the_hash_seed @ linux-x86_64 +test.test_graphlib.TestTopologicalSort.test_the_node_multiple_times @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_gzip.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_gzip.txt new file mode 100644 index 0000000000..e77957a1c2 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_gzip.txt @@ -0,0 +1,61 @@ +test.test_gzip.TestCommandLine.test_compress_fast_best_are_exclusive @ linux-x86_64 +test.test_gzip.TestCommandLine.test_compress_infile_outfile @ linux-x86_64 +test.test_gzip.TestCommandLine.test_compress_infile_outfile_default @ linux-x86_64 +test.test_gzip.TestCommandLine.test_decompress_cannot_have_flags_compression @ linux-x86_64 +test.test_gzip.TestCommandLine.test_decompress_infile_outfile @ linux-x86_64 +test.test_gzip.TestCommandLine.test_decompress_infile_outfile_error @ linux-x86_64 +test.test_gzip.TestGzip.test_1647484 @ linux-x86_64 +test.test_gzip.TestGzip.test_append @ linux-x86_64 +test.test_gzip.TestGzip.test_bad_gzip_file @ linux-x86_64 +test.test_gzip.TestGzip.test_buffered_reader @ linux-x86_64 +test.test_gzip.TestGzip.test_compress @ linux-x86_64 +test.test_gzip.TestGzip.test_compress_correct_level @ linux-x86_64 +test.test_gzip.TestGzip.test_compress_mtime @ linux-x86_64 +test.test_gzip.TestGzip.test_compresslevel_metadata @ linux-x86_64 +test.test_gzip.TestGzip.test_decompress @ linux-x86_64 +test.test_gzip.TestGzip.test_decompress_limited @ linux-x86_64 +test.test_gzip.TestGzip.test_decompress_missing_trailer @ linux-x86_64 +test.test_gzip.TestGzip.test_decompress_truncated_trailer @ linux-x86_64 +test.test_gzip.TestGzip.test_exclusive_write @ linux-x86_64 +test.test_gzip.TestGzip.test_fileobj_from_fdopen @ linux-x86_64 +test.test_gzip.TestGzip.test_fileobj_mode @ linux-x86_64 +test.test_gzip.TestGzip.test_gzip_BadGzipFile_exception @ linux-x86_64 +test.test_gzip.TestGzip.test_io_on_closed_object @ linux-x86_64 +test.test_gzip.TestGzip.test_issue44439 @ linux-x86_64 +test.test_gzip.TestGzip.test_many_append @ linux-x86_64 +test.test_gzip.TestGzip.test_metadata @ linux-x86_64 +test.test_gzip.TestGzip.test_metadata_ascii_name @ linux-x86_64 +test.test_gzip.TestGzip.test_mode @ linux-x86_64 +test.test_gzip.TestGzip.test_mtime @ linux-x86_64 +test.test_gzip.TestGzip.test_non_seekable_file @ linux-x86_64 +test.test_gzip.TestGzip.test_paddedfile_getattr @ linux-x86_64 +test.test_gzip.TestGzip.test_peek @ linux-x86_64 +test.test_gzip.TestGzip.test_prepend_error @ linux-x86_64 +test.test_gzip.TestGzip.test_read @ linux-x86_64 +test.test_gzip.TestGzip.test_read1 @ linux-x86_64 +test.test_gzip.TestGzip.test_read_large @ linux-x86_64 +test.test_gzip.TestGzip.test_read_truncated @ linux-x86_64 +test.test_gzip.TestGzip.test_read_with_extra @ linux-x86_64 +test.test_gzip.TestGzip.test_readline @ linux-x86_64 +test.test_gzip.TestGzip.test_readlines @ linux-x86_64 +test.test_gzip.TestGzip.test_seek_read @ linux-x86_64 +test.test_gzip.TestGzip.test_seek_whence @ linux-x86_64 +test.test_gzip.TestGzip.test_seek_write @ linux-x86_64 +test.test_gzip.TestGzip.test_textio_readlines @ linux-x86_64 +test.test_gzip.TestGzip.test_with_open @ linux-x86_64 +test.test_gzip.TestGzip.test_write @ linux-x86_64 +test.test_gzip.TestGzip.test_write_array @ linux-x86_64 +test.test_gzip.TestGzip.test_write_bytearray @ linux-x86_64 +test.test_gzip.TestGzip.test_write_incompatible_type @ linux-x86_64 +test.test_gzip.TestGzip.test_write_memoryview @ linux-x86_64 +test.test_gzip.TestGzip.test_write_read_with_pathlike_file @ linux-x86_64 +test.test_gzip.TestGzip.test_zero_padded_file @ linux-x86_64 +test.test_gzip.TestOpen.test_bad_params @ linux-x86_64 +test.test_gzip.TestOpen.test_binary_modes @ linux-x86_64 +test.test_gzip.TestOpen.test_encoding @ linux-x86_64 +test.test_gzip.TestOpen.test_encoding_error_handler @ linux-x86_64 +test.test_gzip.TestOpen.test_fileobj @ linux-x86_64 +test.test_gzip.TestOpen.test_implicit_binary_modes @ linux-x86_64 +test.test_gzip.TestOpen.test_newline @ linux-x86_64 +test.test_gzip.TestOpen.test_pathlike_file @ linux-x86_64 +test.test_gzip.TestOpen.test_text_modes @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_hash.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_hash.txt new file mode 100644 index 0000000000..fc1493c22c --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_hash.txt @@ -0,0 +1,11 @@ +test.test_hash.HashBuiltinsTestCase.test_hashes @ linux-x86_64 +test.test_hash.HashDistributionTestCase.test_hash_distribution @ linux-x86_64 +test.test_hash.HashEqualityTestCase.test_coerced_floats @ linux-x86_64 +test.test_hash.HashEqualityTestCase.test_coerced_integers @ linux-x86_64 +test.test_hash.HashEqualityTestCase.test_numeric_literals @ linux-x86_64 +test.test_hash.HashEqualityTestCase.test_unaligned_buffers @ linux-x86_64 +test.test_hash.HashInheritanceTestCase.test_default_hash @ linux-x86_64 +test.test_hash.HashInheritanceTestCase.test_error_hash @ linux-x86_64 +test.test_hash.HashInheritanceTestCase.test_fixed_hash @ linux-x86_64 +test.test_hash.HashInheritanceTestCase.test_hashable @ linux-x86_64 +test.test_hash.HashInheritanceTestCase.test_not_hashable @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_hashlib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_hashlib.txt new file mode 100644 index 0000000000..e8465ffd8b --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_hashlib.txt @@ -0,0 +1,63 @@ +test.test_hashlib.HashLibTestCase.test_algorithms_available @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_algorithms_guaranteed @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_blocksize_name @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_blocksize_name_blake2 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_blocksize_name_sha3 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_blake2b_0 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_blake2b_1 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_blake2s_0 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_blake2s_1 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_md5_0 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_md5_1 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_md5_2 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha1_0 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha1_1 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha1_2 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha1_3 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha224_0 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha224_1 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha224_2 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha224_3 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha256_0 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha256_1 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha256_2 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha256_3 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha384_0 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha384_1 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha384_2 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha384_3 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha3_224_0 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha3_224_vector @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha3_256_0 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha3_256_vector @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha3_384_0 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha3_384_vector @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha3_512_0 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha3_512_vector @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha512_0 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha512_1 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha512_2 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_case_sha512_3 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_digest_length_overflow @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_extra_sha3 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_get_builtin_constructor @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_get_fips_mode @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_gil @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_hash_array @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_hash_disallow_instantiation @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_hexdigest @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_large_update @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_name_attribute @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_new_upper_to_lower @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_no_unicode @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_no_unicode_blake2 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_no_unicode_sha3 @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_readonly_types @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_threaded_hashing @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_unknown_hash @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_usedforsecurity_false @ linux-x86_64 +test.test_hashlib.HashLibTestCase.test_usedforsecurity_true @ linux-x86_64 +test.test_hashlib.KDFTests.test_file_digest @ linux-x86_64 +test.test_hashlib.KDFTests.test_normalized_name @ linux-x86_64 +test.test_hashlib.KDFTests.test_pbkdf2_hmac_c @ linux-x86_64 +test.test_hashlib.KDFTests.test_pbkdf2_hmac_py @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_heapq.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_heapq.txt new file mode 100644 index 0000000000..3f3973edf0 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_heapq.txt @@ -0,0 +1,25 @@ +DocTestCase.merge @ linux-x86_64 +test.test_heapq.TestErrorHandlingPython.test_arg_parsing @ linux-x86_64 +test.test_heapq.TestErrorHandlingPython.test_cmp_err @ linux-x86_64 +test.test_heapq.TestErrorHandlingPython.test_comparison_operator_modifiying_heap @ linux-x86_64 +test.test_heapq.TestErrorHandlingPython.test_comparison_operator_modifiying_heap_two_heaps @ linux-x86_64 +test.test_heapq.TestErrorHandlingPython.test_heappop_mutating_heap @ linux-x86_64 +test.test_heapq.TestErrorHandlingPython.test_heappush_mutating_heap @ linux-x86_64 +test.test_heapq.TestErrorHandlingPython.test_iterable_args @ linux-x86_64 +test.test_heapq.TestErrorHandlingPython.test_len_only @ linux-x86_64 +test.test_heapq.TestErrorHandlingPython.test_non_sequence @ linux-x86_64 +test.test_heapq.TestHeapPython.test_comparison_operator @ linux-x86_64 +test.test_heapq.TestHeapPython.test_empty_merges @ linux-x86_64 +test.test_heapq.TestHeapPython.test_heapify @ linux-x86_64 +test.test_heapq.TestHeapPython.test_heappop_max @ linux-x86_64 +test.test_heapq.TestHeapPython.test_heappushpop @ linux-x86_64 +test.test_heapq.TestHeapPython.test_heapsort @ linux-x86_64 +test.test_heapq.TestHeapPython.test_merge @ linux-x86_64 +test.test_heapq.TestHeapPython.test_merge_stability @ linux-x86_64 +test.test_heapq.TestHeapPython.test_naive_nbest @ linux-x86_64 +test.test_heapq.TestHeapPython.test_nbest @ linux-x86_64 +test.test_heapq.TestHeapPython.test_nbest_with_pushpop @ linux-x86_64 +test.test_heapq.TestHeapPython.test_nlargest @ linux-x86_64 +test.test_heapq.TestHeapPython.test_nsmallest @ linux-x86_64 +test.test_heapq.TestHeapPython.test_push_pop @ linux-x86_64 +test.test_heapq.TestModules.test_py_functions @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_hmac.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_hmac.txt new file mode 100644 index 0000000000..b08a530204 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_hmac.txt @@ -0,0 +1,26 @@ +test.test_hmac.CompareDigestTestCase.test_hmac_compare_digest @ linux-x86_64 +test.test_hmac.CompareDigestTestCase.test_openssl_compare_digest @ linux-x86_64 +test.test_hmac.ConstructorTestCase.test_dot_new_with_str_key @ linux-x86_64 +test.test_hmac.ConstructorTestCase.test_internal_types @ linux-x86_64 +test.test_hmac.ConstructorTestCase.test_normal @ linux-x86_64 +test.test_hmac.ConstructorTestCase.test_with_bytearray @ linux-x86_64 +test.test_hmac.ConstructorTestCase.test_with_memoryview_msg @ linux-x86_64 +test.test_hmac.ConstructorTestCase.test_with_sha256_module @ linux-x86_64 +test.test_hmac.ConstructorTestCase.test_with_str_key @ linux-x86_64 +test.test_hmac.ConstructorTestCase.test_withmodule @ linux-x86_64 +test.test_hmac.ConstructorTestCase.test_withtext @ linux-x86_64 +test.test_hmac.CopyTestCase.test_attributes_old @ linux-x86_64 +test.test_hmac.CopyTestCase.test_equality @ linux-x86_64 +test.test_hmac.CopyTestCase.test_equality_new @ linux-x86_64 +test.test_hmac.CopyTestCase.test_realcopy_hmac @ linux-x86_64 +test.test_hmac.CopyTestCase.test_realcopy_old @ linux-x86_64 +test.test_hmac.SanityTestCase.test_exercise_all_methods @ linux-x86_64 +test.test_hmac.TestVectorsTestCase.test_legacy_block_size_warnings @ linux-x86_64 +test.test_hmac.TestVectorsTestCase.test_md5_vectors @ linux-x86_64 +test.test_hmac.TestVectorsTestCase.test_sha224_rfc4231 @ linux-x86_64 +test.test_hmac.TestVectorsTestCase.test_sha256_rfc4231 @ linux-x86_64 +test.test_hmac.TestVectorsTestCase.test_sha384_rfc4231 @ linux-x86_64 +test.test_hmac.TestVectorsTestCase.test_sha512_rfc4231 @ linux-x86_64 +test.test_hmac.TestVectorsTestCase.test_sha_vectors @ linux-x86_64 +test.test_hmac.TestVectorsTestCase.test_with_digestmod_no_default @ linux-x86_64 +test.test_hmac.TestVectorsTestCase.test_with_fallback @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_html.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_html.txt new file mode 100644 index 0000000000..965d834712 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_html.txt @@ -0,0 +1,2 @@ +test.test_html.HtmlTests.test_escape @ linux-x86_64 +test.test_html.HtmlTests.test_unescape @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_htmlparser.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_htmlparser.txt new file mode 100644 index 0000000000..ce4295f5bb --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_htmlparser.txt @@ -0,0 +1,46 @@ +test.test_htmlparser.AttributesTestCase.test_adjacent_attributes @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_attr_entity_replacement @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_attr_funky_names @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_attr_funky_names2 @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_attr_nonascii @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_attr_syntax @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_attr_values @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_comma_between_attributes @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_end_tag_in_attribute_value @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_entities_in_attribute_value @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_entityrefs_in_attributes @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_javascript_attribute_value @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_malformed_adjacent_attributes @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_malformed_attributes @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_missing_attribute_value @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_weird_chars_in_unquoted_attribute_values @ linux-x86_64 +test.test_htmlparser.AttributesTestCase.test_with_unquoted_attributes @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_EOF_in_charref @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_bad_nesting @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_bare_ampersands @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_bare_pointy_brackets @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_broken_comments @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_broken_condcoms @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_broken_invalid_end_tag @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_buffer_artefacts @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_cdata_content @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_cdata_with_closing_tags @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_comments @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_condcoms @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_convert_charrefs @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_convert_charrefs_dropped_text @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_correct_detection_of_start_tags @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_declaration_junk_chars @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_get_starttag_text @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_illegal_declarations @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_invalid_end_tags @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_malformatted_charref @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_processing_instruction_only @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_simple_html @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_slashes_in_starttag @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_startendtag @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_starttag_end_boundary @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_starttag_junk_chars @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_tolerant_parsing @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_unclosed_entityref @ linux-x86_64 +test.test_htmlparser.HTMLParserTestCase.test_valid_doctypes @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_http_cookiejar.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_http_cookiejar.txt new file mode 100644 index 0000000000..7a783ce34a --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_http_cookiejar.txt @@ -0,0 +1,77 @@ +test.test_http_cookiejar.CookieTests.test_Cookie_iterator @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_bad_cookie_header @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_custom_secure_protocols @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_default_path @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_default_path_with_query @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_domain_allow @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_domain_block @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_domain_match @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_domain_mirror @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_domain_return_ok @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_escape_path @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_evil_local_domain @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_evil_local_domain_2 @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_evil_nonlocal_domain @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_expires @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_is_HDN @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_localhost_domain @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_localhost_domain_contents @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_localhost_domain_contents_2 @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_missing_final_slash @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_missing_value @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_no_return_comment @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_ns_parser @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_ns_parser_special_names @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_parse_ns_headers @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_path_mirror @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_path_prefix_match @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_port_mirror @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_quote_cookie_value @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_reach @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_request_host @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_request_path @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_request_port @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_rfc2109_handling @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_secure @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_secure_block @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_strict_domain @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_two_component_domain_ns @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_two_component_domain_rfc2965 @ linux-x86_64 +test.test_http_cookiejar.CookieTests.test_wrong_domain @ linux-x86_64 +test.test_http_cookiejar.DateTimeTests.test_http2time @ linux-x86_64 +test.test_http_cookiejar.DateTimeTests.test_http2time_formats @ linux-x86_64 +test.test_http_cookiejar.DateTimeTests.test_http2time_garbage @ linux-x86_64 +test.test_http_cookiejar.DateTimeTests.test_http2time_redos_regression_actually_completes @ linux-x86_64 +test.test_http_cookiejar.DateTimeTests.test_iso2time @ linux-x86_64 +test.test_http_cookiejar.DateTimeTests.test_iso2time_formats @ linux-x86_64 +test.test_http_cookiejar.DateTimeTests.test_iso2time_garbage @ linux-x86_64 +test.test_http_cookiejar.DateTimeTests.test_iso2time_performance_regression @ linux-x86_64 +test.test_http_cookiejar.DateTimeTests.test_time2isoz @ linux-x86_64 +test.test_http_cookiejar.DateTimeTests.test_time2netscape @ linux-x86_64 +test.test_http_cookiejar.FileCookieJarTests.test_bad_magic @ linux-x86_64 +test.test_http_cookiejar.FileCookieJarTests.test_constructor_with_none @ linux-x86_64 +test.test_http_cookiejar.FileCookieJarTests.test_constructor_with_other_types @ linux-x86_64 +test.test_http_cookiejar.FileCookieJarTests.test_constructor_with_path_like @ linux-x86_64 +test.test_http_cookiejar.FileCookieJarTests.test_constructor_with_str @ linux-x86_64 +test.test_http_cookiejar.FileCookieJarTests.test_cookie_files_are_truncated @ linux-x86_64 +test.test_http_cookiejar.FileCookieJarTests.test_lwp_filepermissions @ linux-x86_64 +test.test_http_cookiejar.FileCookieJarTests.test_lwp_valueless_cookie @ linux-x86_64 +test.test_http_cookiejar.FileCookieJarTests.test_mozilla_filepermissions @ linux-x86_64 +test.test_http_cookiejar.HeaderTests.test_join_header_words @ linux-x86_64 +test.test_http_cookiejar.HeaderTests.test_parse_ns_headers @ linux-x86_64 +test.test_http_cookiejar.HeaderTests.test_parse_ns_headers_special_names @ linux-x86_64 +test.test_http_cookiejar.HeaderTests.test_parse_ns_headers_version @ linux-x86_64 +test.test_http_cookiejar.HeaderTests.test_roundtrip @ linux-x86_64 +test.test_http_cookiejar.HeaderTests.test_split_header_words @ linux-x86_64 +test.test_http_cookiejar.LWPCookieTests.test_empty_path @ linux-x86_64 +test.test_http_cookiejar.LWPCookieTests.test_ietf_example_1 @ linux-x86_64 +test.test_http_cookiejar.LWPCookieTests.test_ietf_example_2 @ linux-x86_64 +test.test_http_cookiejar.LWPCookieTests.test_intranet_domains_2965 @ linux-x86_64 +test.test_http_cookiejar.LWPCookieTests.test_intranet_domains_ns @ linux-x86_64 +test.test_http_cookiejar.LWPCookieTests.test_mozilla @ linux-x86_64 +test.test_http_cookiejar.LWPCookieTests.test_netscape_example_1 @ linux-x86_64 +test.test_http_cookiejar.LWPCookieTests.test_netscape_example_2 @ linux-x86_64 +test.test_http_cookiejar.LWPCookieTests.test_netscape_misc @ linux-x86_64 +test.test_http_cookiejar.LWPCookieTests.test_rejection @ linux-x86_64 +test.test_http_cookiejar.LWPCookieTests.test_session_cookies @ linux-x86_64 +test.test_http_cookiejar.LWPCookieTests.test_url_encoding @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_http_cookies.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_http_cookies.txt new file mode 100644 index 0000000000..8ae953096f --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_http_cookies.txt @@ -0,0 +1,27 @@ +DocTestCase.http.cookies @ linux-x86_64 +test.test_http_cookies.CookieTests.test_basic @ linux-x86_64 +test.test_http_cookies.CookieTests.test_comment_quoting @ linux-x86_64 +test.test_http_cookies.CookieTests.test_extended_encode @ linux-x86_64 +test.test_http_cookies.CookieTests.test_extra_spaces @ linux-x86_64 +test.test_http_cookies.CookieTests.test_illegal_chars @ linux-x86_64 +test.test_http_cookies.CookieTests.test_invalid_cookies @ linux-x86_64 +test.test_http_cookies.CookieTests.test_load @ linux-x86_64 +test.test_http_cookies.CookieTests.test_pickle @ linux-x86_64 +test.test_http_cookies.CookieTests.test_quoted_meta @ linux-x86_64 +test.test_http_cookies.CookieTests.test_samesite_attrs @ linux-x86_64 +test.test_http_cookies.CookieTests.test_secure_httponly_false_if_not_present @ linux-x86_64 +test.test_http_cookies.CookieTests.test_secure_httponly_true_if_have_value @ linux-x86_64 +test.test_http_cookies.CookieTests.test_secure_httponly_true_if_present @ linux-x86_64 +test.test_http_cookies.CookieTests.test_set_secure_httponly_attrs @ linux-x86_64 +test.test_http_cookies.CookieTests.test_special_attrs @ linux-x86_64 +test.test_http_cookies.MorselTests.test_copy @ linux-x86_64 +test.test_http_cookies.MorselTests.test_defaults @ linux-x86_64 +test.test_http_cookies.MorselTests.test_eq @ linux-x86_64 +test.test_http_cookies.MorselTests.test_pickle @ linux-x86_64 +test.test_http_cookies.MorselTests.test_repr @ linux-x86_64 +test.test_http_cookies.MorselTests.test_reserved_keys @ linux-x86_64 +test.test_http_cookies.MorselTests.test_set_properties @ linux-x86_64 +test.test_http_cookies.MorselTests.test_setdefault @ linux-x86_64 +test.test_http_cookies.MorselTests.test_setitem @ linux-x86_64 +test.test_http_cookies.MorselTests.test_setter @ linux-x86_64 +test.test_http_cookies.MorselTests.test_update @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_httplib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_httplib.txt new file mode 100644 index 0000000000..85b1040c95 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_httplib.txt @@ -0,0 +1,111 @@ +test.test_httplib.BasicTest.test_bad_status_repr @ linux-x86_64 +test.test_httplib.BasicTest.test_blocksize_request @ linux-x86_64 +test.test_httplib.BasicTest.test_blocksize_send @ linux-x86_64 +test.test_httplib.BasicTest.test_chunked @ linux-x86_64 +test.test_httplib.BasicTest.test_chunked_extension @ linux-x86_64 +test.test_httplib.BasicTest.test_chunked_head @ linux-x86_64 +test.test_httplib.BasicTest.test_chunked_missing_end @ linux-x86_64 +test.test_httplib.BasicTest.test_chunked_sync @ linux-x86_64 +test.test_httplib.BasicTest.test_chunked_trailers @ linux-x86_64 +test.test_httplib.BasicTest.test_content_length_sync @ linux-x86_64 +test.test_httplib.BasicTest.test_dir_with_added_behavior_on_status @ linux-x86_64 +test.test_httplib.BasicTest.test_early_eof @ linux-x86_64 +test.test_httplib.BasicTest.test_epipe @ linux-x86_64 +test.test_httplib.BasicTest.test_error_leak @ linux-x86_64 +test.test_httplib.BasicTest.test_host_port @ linux-x86_64 +test.test_httplib.BasicTest.test_incomplete_read @ linux-x86_64 +test.test_httplib.BasicTest.test_mixed_reads @ linux-x86_64 +test.test_httplib.BasicTest.test_negative_content_length @ linux-x86_64 +test.test_httplib.BasicTest.test_overflowing_chunked_line @ linux-x86_64 +test.test_httplib.BasicTest.test_overflowing_header_limit_after_100 @ linux-x86_64 +test.test_httplib.BasicTest.test_overflowing_header_line @ linux-x86_64 +test.test_httplib.BasicTest.test_overflowing_status_line @ linux-x86_64 +test.test_httplib.BasicTest.test_partial_readintos @ linux-x86_64 +test.test_httplib.BasicTest.test_partial_readintos_incomplete_body @ linux-x86_64 +test.test_httplib.BasicTest.test_partial_readintos_no_content_length @ linux-x86_64 +test.test_httplib.BasicTest.test_partial_readintos_past_end @ linux-x86_64 +test.test_httplib.BasicTest.test_partial_reads @ linux-x86_64 +test.test_httplib.BasicTest.test_partial_reads_incomplete_body @ linux-x86_64 +test.test_httplib.BasicTest.test_partial_reads_no_content_length @ linux-x86_64 +test.test_httplib.BasicTest.test_partial_reads_past_end @ linux-x86_64 +test.test_httplib.BasicTest.test_putrequest_override_domain_validation @ linux-x86_64 +test.test_httplib.BasicTest.test_putrequest_override_encoding @ linux-x86_64 +test.test_httplib.BasicTest.test_putrequest_override_host_validation @ linux-x86_64 +test.test_httplib.BasicTest.test_read1_bound_content_length @ linux-x86_64 +test.test_httplib.BasicTest.test_read1_content_length @ linux-x86_64 +test.test_httplib.BasicTest.test_read_head @ linux-x86_64 +test.test_httplib.BasicTest.test_readinto_chunked @ linux-x86_64 +test.test_httplib.BasicTest.test_readinto_chunked_head @ linux-x86_64 +test.test_httplib.BasicTest.test_readinto_head @ linux-x86_64 +test.test_httplib.BasicTest.test_readline_bound_content_length @ linux-x86_64 +test.test_httplib.BasicTest.test_readlines_content_length @ linux-x86_64 +test.test_httplib.BasicTest.test_response_fileno @ linux-x86_64 +test.test_httplib.BasicTest.test_response_headers @ linux-x86_64 +test.test_httplib.BasicTest.test_send @ linux-x86_64 +test.test_httplib.BasicTest.test_send_file @ linux-x86_64 +test.test_httplib.BasicTest.test_send_iter @ linux-x86_64 +test.test_httplib.BasicTest.test_send_type_error @ linux-x86_64 +test.test_httplib.BasicTest.test_send_updating_file @ linux-x86_64 +test.test_httplib.BasicTest.test_simple_httpstatus @ linux-x86_64 +test.test_httplib.BasicTest.test_status_lines @ linux-x86_64 +test.test_httplib.BasicTest.test_too_many_headers @ linux-x86_64 +test.test_httplib.ExtendedReadTest.test_peek @ linux-x86_64 +test.test_httplib.ExtendedReadTest.test_peek_0 @ linux-x86_64 +test.test_httplib.ExtendedReadTest.test_read1 @ linux-x86_64 +test.test_httplib.ExtendedReadTest.test_read1_0 @ linux-x86_64 +test.test_httplib.ExtendedReadTest.test_read1_bounded @ linux-x86_64 +test.test_httplib.ExtendedReadTest.test_read1_unbounded @ linux-x86_64 +test.test_httplib.ExtendedReadTest.test_readline @ linux-x86_64 +test.test_httplib.ExtendedReadTestChunked.test_peek @ linux-x86_64 +test.test_httplib.ExtendedReadTestChunked.test_peek_0 @ linux-x86_64 +test.test_httplib.ExtendedReadTestChunked.test_read1 @ linux-x86_64 +test.test_httplib.ExtendedReadTestChunked.test_read1_0 @ linux-x86_64 +test.test_httplib.ExtendedReadTestChunked.test_read1_bounded @ linux-x86_64 +test.test_httplib.ExtendedReadTestChunked.test_read1_unbounded @ linux-x86_64 +test.test_httplib.ExtendedReadTestChunked.test_readline @ linux-x86_64 +test.test_httplib.HTTPResponseTest.test_getting_header @ linux-x86_64 +test.test_httplib.HTTPResponseTest.test_getting_header_defaultint @ linux-x86_64 +test.test_httplib.HTTPResponseTest.test_getting_nonexistent_header_with_iterable_default @ linux-x86_64 +test.test_httplib.HTTPResponseTest.test_getting_nonexistent_header_with_string_default @ linux-x86_64 +test.test_httplib.HTTPResponseTest.test_getting_nonexistent_header_without_default @ linux-x86_64 +test.test_httplib.HTTPSTest.test_attributes @ linux-x86_64 +test.test_httplib.HTTPSTest.test_host_port @ linux-x86_64 +test.test_httplib.HTTPSTest.test_local_bad_hostname @ linux-x86_64 +test.test_httplib.HTTPSTest.test_local_good_hostname @ linux-x86_64 +test.test_httplib.HTTPSTest.test_local_unknown_cert @ linux-x86_64 +test.test_httplib.HeaderTests.test_auto_headers @ linux-x86_64 +test.test_httplib.HeaderTests.test_content_length_0 @ linux-x86_64 +test.test_httplib.HeaderTests.test_headers_debuglevel @ linux-x86_64 +test.test_httplib.HeaderTests.test_invalid_headers @ linux-x86_64 +test.test_httplib.HeaderTests.test_ipv6host_header @ linux-x86_64 +test.test_httplib.HeaderTests.test_malformed_headers_coped_with @ linux-x86_64 +test.test_httplib.HeaderTests.test_parse_all_octets @ linux-x86_64 +test.test_httplib.HeaderTests.test_putheader @ linux-x86_64 +test.test_httplib.HttpMethodTests.test_invalid_method_names @ linux-x86_64 +test.test_httplib.OfflineTest.test_all @ linux-x86_64 +test.test_httplib.OfflineTest.test_client_constants @ linux-x86_64 +test.test_httplib.OfflineTest.test_responses @ linux-x86_64 +test.test_httplib.PersistenceTest.test_100_close @ linux-x86_64 +test.test_httplib.PersistenceTest.test_disconnected @ linux-x86_64 +test.test_httplib.PersistenceTest.test_reuse_reconnect @ linux-x86_64 +test.test_httplib.RequestBodyTest.test_ascii_body @ linux-x86_64 +test.test_httplib.RequestBodyTest.test_binary_file_body @ linux-x86_64 +test.test_httplib.RequestBodyTest.test_bytes_body @ linux-x86_64 +test.test_httplib.RequestBodyTest.test_latin1_body @ linux-x86_64 +test.test_httplib.RequestBodyTest.test_list_body @ linux-x86_64 +test.test_httplib.RequestBodyTest.test_manual_content_length @ linux-x86_64 +test.test_httplib.RequestBodyTest.test_text_file_body @ linux-x86_64 +test.test_httplib.SourceAddressTest.testHTTPConnectionSourceAddress @ linux-x86_64 +test.test_httplib.SourceAddressTest.testHTTPSConnectionSourceAddress @ linux-x86_64 +test.test_httplib.TimeoutTest.testTimeoutAttribute @ linux-x86_64 +test.test_httplib.TransferEncodingTest.test_empty_body @ linux-x86_64 +test.test_httplib.TransferEncodingTest.test_endheaders_chunked @ linux-x86_64 +test.test_httplib.TransferEncodingTest.test_explicit_headers @ linux-x86_64 +test.test_httplib.TransferEncodingTest.test_request @ linux-x86_64 +test.test_httplib.TunnelTests.test_connect_put_request @ linux-x86_64 +test.test_httplib.TunnelTests.test_connect_with_tunnel @ linux-x86_64 +test.test_httplib.TunnelTests.test_disallow_set_tunnel_after_connect @ linux-x86_64 +test.test_httplib.TunnelTests.test_set_tunnel_host_port_headers @ linux-x86_64 +test.test_httplib.TunnelTests.test_tunnel_connect_single_send_connection_setup @ linux-x86_64 +test.test_httplib.TunnelTests.test_tunnel_debuglog @ linux-x86_64 +test.test_httplib.TunnelTests.test_tunnel_leak @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_httpservers.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_httpservers.txt new file mode 100644 index 0000000000..291d42ff2a --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_httpservers.txt @@ -0,0 +1,74 @@ +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_close_connection @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_date_time_string @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_extra_space @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_header_buffering_of_send_error @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_header_buffering_of_send_header @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_header_buffering_of_send_response_only @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_header_length @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_header_unbuffered_when_continue @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_html_escape_on_error @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_http_0_9 @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_http_1_0 @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_http_1_1 @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_request_length @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_too_many_headers @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_unprintable_not_logged @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_with_continue_1_0 @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_with_continue_1_1 @ linux-x86_64 +test.test_httpservers.BaseHTTPRequestHandlerTestCase.test_with_continue_rejected @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_command @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_error_content_length @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_handler @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_head_via_send_error @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_header_close @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_header_keep_alive @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_internal_key_error @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_latin1_header @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_major_version_number_too_long @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_minor_version_number_too_long @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_request_line_trimming @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_return_custom_status @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_return_explain_error @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_return_header_keep_alive @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_send_blank @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_send_error @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_version_bogus @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_version_digits @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_version_invalid @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_version_none @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_version_none_get @ linux-x86_64 +test.test_httpservers.BaseHTTPServerTestCase.test_version_signs_and_underscores @ linux-x86_64 +test.test_httpservers.CGIHTTPServerTestCase.test_accept @ linux-x86_64 +test.test_httpservers.CGIHTTPServerTestCase.test_authorization @ linux-x86_64 +test.test_httpservers.CGIHTTPServerTestCase.test_cgi_path_in_sub_directories @ linux-x86_64 +test.test_httpservers.CGIHTTPServerTestCase.test_headers_and_content @ linux-x86_64 +test.test_httpservers.CGIHTTPServerTestCase.test_invaliduri @ linux-x86_64 +test.test_httpservers.CGIHTTPServerTestCase.test_issue19435 @ linux-x86_64 +test.test_httpservers.CGIHTTPServerTestCase.test_nested_cgi_path_issue21323 @ linux-x86_64 +test.test_httpservers.CGIHTTPServerTestCase.test_no_leading_slash @ linux-x86_64 +test.test_httpservers.CGIHTTPServerTestCase.test_os_environ_is_not_altered @ linux-x86_64 +test.test_httpservers.CGIHTTPServerTestCase.test_post @ linux-x86_64 +test.test_httpservers.CGIHTTPServerTestCase.test_query_with_continuous_slashes @ linux-x86_64 +test.test_httpservers.CGIHTTPServerTestCase.test_query_with_multiple_question_mark @ linux-x86_64 +test.test_httpservers.CGIHTTPServerTestCase.test_url_collapse_path @ linux-x86_64 +test.test_httpservers.CGIHTTPServerTestCase.test_urlquote_decoding_in_cgi_check @ linux-x86_64 +test.test_httpservers.MiscTestCase.test_all @ linux-x86_64 +test.test_httpservers.RequestHandlerLoggingTestCase.test_err @ linux-x86_64 +test.test_httpservers.ScriptTestCase.test_server_test_ipv4 @ linux-x86_64 +test.test_httpservers.ScriptTestCase.test_server_test_ipv6 @ linux-x86_64 +test.test_httpservers.ScriptTestCase.test_server_test_localhost @ linux-x86_64 +test.test_httpservers.ScriptTestCase.test_server_test_unspec @ linux-x86_64 +test.test_httpservers.SimpleHTTPRequestHandlerTestCase.test_query_arguments @ linux-x86_64 +test.test_httpservers.SimpleHTTPRequestHandlerTestCase.test_start_with_double_slash @ linux-x86_64 +test.test_httpservers.SimpleHTTPRequestHandlerTestCase.test_windows_colon @ linux-x86_64 +test.test_httpservers.SimpleHTTPServerTestCase.test_browser_cache @ linux-x86_64 +test.test_httpservers.SimpleHTTPServerTestCase.test_browser_cache_file_changed @ linux-x86_64 +test.test_httpservers.SimpleHTTPServerTestCase.test_browser_cache_with_If_None_Match_header @ linux-x86_64 +test.test_httpservers.SimpleHTTPServerTestCase.test_get @ linux-x86_64 +test.test_httpservers.SimpleHTTPServerTestCase.test_get_dir_redirect_location_domain_injection_bug @ linux-x86_64 +test.test_httpservers.SimpleHTTPServerTestCase.test_head @ linux-x86_64 +test.test_httpservers.SimpleHTTPServerTestCase.test_html_escape_filename @ linux-x86_64 +test.test_httpservers.SimpleHTTPServerTestCase.test_invalid_requests @ linux-x86_64 +test.test_httpservers.SimpleHTTPServerTestCase.test_last_modified @ linux-x86_64 +test.test_httpservers.SimpleHTTPServerTestCase.test_path_without_leading_slash @ linux-x86_64 +test.test_httpservers.SimpleHTTPServerTestCase.test_undecodable_parameter @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_imaplib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_imaplib.txt new file mode 100644 index 0000000000..93471d4ee8 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_imaplib.txt @@ -0,0 +1,87 @@ +test.test_imaplib.NewIMAPSSLTests.test_EOF_without_complete_welcome_message @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_aborted_authentication @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_bad_auth_name @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_enable_UTF8_True_append @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_enable_UTF8_raises_error_if_not_supported @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_enable_raises_error_if_no_capability @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_enable_raises_error_if_not_AUTH @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_imaplib_timeout_functionality_test @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_invalid_authentication @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_line_termination @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_linetoolong @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_login @ linux-x86_64 +!test.test_imaplib.NewIMAPSSLTests.test_login_cram_md5_bytes @ linux-x86_64 +!test.test_imaplib.NewIMAPSSLTests.test_login_cram_md5_plain_text @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_logout @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_lsub @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_search_disallows_charset_in_utf8_mode @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_simple_with_statement @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_ssl_verified @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_unselect @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_valid_authentication_bytes @ linux-x86_64 +!test.test_imaplib.NewIMAPSSLTests.test_valid_authentication_plain_text @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_with_statement @ linux-x86_64 +test.test_imaplib.NewIMAPSSLTests.test_with_statement_logout @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_EOF_without_complete_welcome_message @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_aborted_authentication @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_bad_auth_name @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_enable_UTF8_True_append @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_enable_UTF8_raises_error_if_not_supported @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_enable_raises_error_if_no_capability @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_enable_raises_error_if_not_AUTH @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_imaplib_timeout_functionality_test @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_invalid_authentication @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_line_termination @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_linetoolong @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_login @ linux-x86_64 +!test.test_imaplib.NewIMAPTests.test_login_cram_md5_bytes @ linux-x86_64 +!test.test_imaplib.NewIMAPTests.test_login_cram_md5_plain_text @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_logout @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_lsub @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_search_disallows_charset_in_utf8_mode @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_simple_with_statement @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_unselect @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_valid_authentication_bytes @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_valid_authentication_plain_text @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_with_statement @ linux-x86_64 +test.test_imaplib.NewIMAPTests.test_with_statement_logout @ linux-x86_64 +test.test_imaplib.TestImaplib.test_Internaldate2tuple @ linux-x86_64 +test.test_imaplib.TestImaplib.test_Internaldate2tuple_issue10941 @ linux-x86_64 +test.test_imaplib.TestImaplib.test_imap4_host_default_value @ linux-x86_64 +test.test_imaplib.TestImaplib.test_that_Time2Internaldate_returns_a_result @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_aborted_authentication @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_bad_auth_name @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_bracket_flags @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_connect @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_enable_UTF8_True_append @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_enable_UTF8_raises_error_if_not_supported @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_enable_raises_error_if_no_capability @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_enable_raises_error_if_not_AUTH @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_invalid_authentication @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_issue5949 @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_line_termination @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_linetoolong @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_login_cram_md5 @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_search_disallows_charset_in_utf8_mode @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_simple_with_statement @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_valid_authentication @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_with_statement @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTests.test_with_statement_logout @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_aborted_authentication @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_bad_auth_name @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_bracket_flags @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_connect @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_enable_UTF8_True_append @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_enable_UTF8_raises_error_if_not_supported @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_enable_raises_error_if_no_capability @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_enable_raises_error_if_not_AUTH @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_invalid_authentication @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_issue5949 @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_line_termination @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_linetoolong @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_login_cram_md5 @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_search_disallows_charset_in_utf8_mode @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_simple_with_statement @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_valid_authentication @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_with_statement @ linux-x86_64 +test.test_imaplib.ThreadedNetworkedTestsSSL.test_with_statement_logout @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_imghdr.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_imghdr.txt new file mode 100644 index 0000000000..97068cb373 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_imghdr.txt @@ -0,0 +1,11 @@ +test.test_imghdr.TestImghdr.test_bad_args @ linux-x86_64 +test.test_imghdr.TestImghdr.test_closed_file @ linux-x86_64 +test.test_imghdr.TestImghdr.test_data @ linux-x86_64 +test.test_imghdr.TestImghdr.test_file_pos @ linux-x86_64 +test.test_imghdr.TestImghdr.test_invalid_headers @ linux-x86_64 +test.test_imghdr.TestImghdr.test_missing_file @ linux-x86_64 +test.test_imghdr.TestImghdr.test_output_stream @ linux-x86_64 +test.test_imghdr.TestImghdr.test_pathlike_filename @ linux-x86_64 +test.test_imghdr.TestImghdr.test_register_test @ linux-x86_64 +test.test_imghdr.TestImghdr.test_string_data @ linux-x86_64 +test.test_imghdr.TestImghdr.test_unseekable @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_imp.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_imp.txt new file mode 100644 index 0000000000..49e7590894 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_imp.txt @@ -0,0 +1,18 @@ +test.test_imp.ImportTests.test_bug7732 @ linux-x86_64 +test.test_imp.ImportTests.test_find_and_load_checked_pyc @ linux-x86_64 +test.test_imp.ImportTests.test_find_module_encoding @ linux-x86_64 +test.test_imp.ImportTests.test_import_encoded_module @ linux-x86_64 +test.test_imp.ImportTests.test_issue1267 @ linux-x86_64 +test.test_imp.ImportTests.test_issue3594 @ linux-x86_64 +test.test_imp.ImportTests.test_issue5604 @ linux-x86_64 +test.test_imp.ImportTests.test_issue9319 @ linux-x86_64 +test.test_imp.ImportTests.test_issue_35321 @ linux-x86_64 +test.test_imp.ImportTests.test_load_source @ linux-x86_64 +test.test_imp.ImportTests.test_multiple_calls_to_get_data @ linux-x86_64 +test.test_imp.ImportTests.test_pyc_invalidation_mode_from_cmdline @ linux-x86_64 +test.test_imp.PEP3147Tests.test_cache_from_source @ linux-x86_64 +test.test_imp.PEP3147Tests.test_source_from_cache @ linux-x86_64 +test.test_imp.ReloadTests.test_builtin @ linux-x86_64 +test.test_imp.ReloadTests.test_extension @ linux-x86_64 +test.test_imp.ReloadTests.test_source @ linux-x86_64 +test.test_imp.ReloadTests.test_with_deleted_parent @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_import.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_import.txt new file mode 100644 index 0000000000..66ccc2507c --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_import.txt @@ -0,0 +1,66 @@ +test.test_import.CircularImportTests.test_binding @ linux-x86_64 +test.test_import.CircularImportTests.test_circular_from_import @ linux-x86_64 +test.test_import.CircularImportTests.test_crossreference1 @ linux-x86_64 +test.test_import.CircularImportTests.test_crossreference2 @ linux-x86_64 +test.test_import.CircularImportTests.test_direct @ linux-x86_64 +test.test_import.CircularImportTests.test_indirect @ linux-x86_64 +test.test_import.CircularImportTests.test_rebinding @ linux-x86_64 +test.test_import.CircularImportTests.test_subpackage @ linux-x86_64 +test.test_import.CircularImportTests.test_unwritable_module @ linux-x86_64 +test.test_import.FilePermissionTests.test_cached_mode_issue_2051 @ linux-x86_64 +test.test_import.FilePermissionTests.test_cached_readonly @ linux-x86_64 +test.test_import.FilePermissionTests.test_creation_mode @ linux-x86_64 +test.test_import.FilePermissionTests.test_pyc_always_writable @ linux-x86_64 +test.test_import.ImportTests.test_bogus_fromlist @ linux-x86_64 +test.test_import.ImportTests.test_case_sensitivity @ linux-x86_64 +!test.test_import.ImportTests.test_concurrency @ linux-x86_64 +test.test_import.ImportTests.test_double_const @ linux-x86_64 +test.test_import.ImportTests.test_failing_import_sticks @ linux-x86_64 +test.test_import.ImportTests.test_failing_reload @ linux-x86_64 +test.test_import.ImportTests.test_file_to_source @ linux-x86_64 +test.test_import.ImportTests.test_from_import_AttributeError @ linux-x86_64 +test.test_import.ImportTests.test_from_import_message_for_existing_module @ linux-x86_64 +test.test_import.ImportTests.test_from_import_message_for_nonexistent_module @ linux-x86_64 +test.test_import.ImportTests.test_from_import_missing_attr_has_name @ linux-x86_64 +test.test_import.ImportTests.test_from_import_missing_attr_has_name_and_path @ linux-x86_64 +test.test_import.ImportTests.test_from_import_missing_attr_path_is_canonical @ linux-x86_64 +test.test_import.ImportTests.test_from_import_missing_attr_raises_ImportError @ linux-x86_64 +test.test_import.ImportTests.test_from_import_missing_module_raises_ModuleNotFoundError @ linux-x86_64 +test.test_import.ImportTests.test_from_import_star_invalid_type @ linux-x86_64 +test.test_import.ImportTests.test_import @ linux-x86_64 +test.test_import.ImportTests.test_import_by_filename @ linux-x86_64 +test.test_import.ImportTests.test_import_in_del_does_not_crash @ linux-x86_64 +test.test_import.ImportTests.test_import_name_binding @ linux-x86_64 +test.test_import.ImportTests.test_import_raises_ModuleNotFoundError @ linux-x86_64 +test.test_import.ImportTests.test_issue31286 @ linux-x86_64 +test.test_import.ImportTests.test_module_with_large_stack @ linux-x86_64 +test.test_import.ImportTests.test_timestamp_overflow @ linux-x86_64 +test.test_import.ImportTracebackTests.test_broken_from @ linux-x86_64 +test.test_import.ImportTracebackTests.test_broken_parent @ linux-x86_64 +test.test_import.ImportTracebackTests.test_broken_parent_from @ linux-x86_64 +test.test_import.ImportTracebackTests.test_broken_submodule @ linux-x86_64 +test.test_import.ImportTracebackTests.test_exec_failure @ linux-x86_64 +test.test_import.ImportTracebackTests.test_exec_failure_nested @ linux-x86_64 +test.test_import.ImportTracebackTests.test_nonexistent_module @ linux-x86_64 +test.test_import.ImportTracebackTests.test_nonexistent_module_nested @ linux-x86_64 +test.test_import.ImportTracebackTests.test_syntax_error @ linux-x86_64 +test.test_import.OverridingImportBuiltinTests.test_override_builtin @ linux-x86_64 +test.test_import.PathsTests.test_trailing_slash @ linux-x86_64 +test.test_import.PycRewritingTests.test_basics @ linux-x86_64 +test.test_import.PycRewritingTests.test_module_without_source @ linux-x86_64 +test.test_import.PycacheTests.test___cached__ @ linux-x86_64 +test.test_import.PycacheTests.test___cached___legacy_pyc @ linux-x86_64 +test.test_import.PycacheTests.test_import_pyc_path @ linux-x86_64 +test.test_import.PycacheTests.test_missing_source @ linux-x86_64 +test.test_import.PycacheTests.test_missing_source_legacy @ linux-x86_64 +test.test_import.PycacheTests.test_package___cached__ @ linux-x86_64 +test.test_import.PycacheTests.test_package___cached___from_pyc @ linux-x86_64 +test.test_import.PycacheTests.test_recompute_pyc_same_second @ linux-x86_64 +test.test_import.PycacheTests.test_unwritable_directory @ linux-x86_64 +test.test_import.RelativeImportTests.test_absolute_import_without_future @ linux-x86_64 +test.test_import.RelativeImportTests.test_import_from_non_package @ linux-x86_64 +test.test_import.RelativeImportTests.test_import_from_unloaded_package @ linux-x86_64 +test.test_import.RelativeImportTests.test_issue3221 @ linux-x86_64 +test.test_import.RelativeImportTests.test_parentless_import_shadowed_by_global @ linux-x86_64 +test.test_import.RelativeImportTests.test_relimport_star @ linux-x86_64 +test.test_import.TestSymbolicallyLinkedPackage.test_symlinked_dir_importable @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_importlib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_importlib.txt new file mode 100644 index 0000000000..f26069aba6 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_importlib.txt @@ -0,0 +1,1405 @@ +test.test_importlib.builtin.test_finder.Frozen_FindSpecTests.test_failure @ linux-x86_64 +test.test_importlib.builtin.test_finder.Frozen_FindSpecTests.test_module @ linux-x86_64 +test.test_importlib.builtin.test_finder.Frozen_FinderTests.test_failure @ linux-x86_64 +test.test_importlib.builtin.test_finder.Frozen_FinderTests.test_module @ linux-x86_64 +test.test_importlib.builtin.test_finder.Source_FindSpecTests.test_failure @ linux-x86_64 +test.test_importlib.builtin.test_finder.Source_FindSpecTests.test_module @ linux-x86_64 +test.test_importlib.builtin.test_finder.Source_FinderTests.test_failure @ linux-x86_64 +test.test_importlib.builtin.test_finder.Source_FinderTests.test_module @ linux-x86_64 +test.test_importlib.builtin.test_loader.Frozen_InspectLoaderTests.test_get_code @ linux-x86_64 +test.test_importlib.builtin.test_loader.Frozen_InspectLoaderTests.test_get_source @ linux-x86_64 +test.test_importlib.builtin.test_loader.Frozen_InspectLoaderTests.test_is_package @ linux-x86_64 +test.test_importlib.builtin.test_loader.Frozen_InspectLoaderTests.test_not_builtin @ linux-x86_64 +test.test_importlib.builtin.test_loader.Frozen_LoaderTests.test_already_imported @ linux-x86_64 +test.test_importlib.builtin.test_loader.Frozen_LoaderTests.test_module @ linux-x86_64 +test.test_importlib.builtin.test_loader.Frozen_LoaderTests.test_module_reuse @ linux-x86_64 +test.test_importlib.builtin.test_loader.Frozen_LoaderTests.test_unloadable @ linux-x86_64 +test.test_importlib.builtin.test_loader.Source_InspectLoaderTests.test_get_code @ linux-x86_64 +test.test_importlib.builtin.test_loader.Source_InspectLoaderTests.test_get_source @ linux-x86_64 +test.test_importlib.builtin.test_loader.Source_InspectLoaderTests.test_is_package @ linux-x86_64 +test.test_importlib.builtin.test_loader.Source_InspectLoaderTests.test_not_builtin @ linux-x86_64 +test.test_importlib.builtin.test_loader.Source_LoaderTests.test_already_imported @ linux-x86_64 +test.test_importlib.builtin.test_loader.Source_LoaderTests.test_module @ linux-x86_64 +test.test_importlib.builtin.test_loader.Source_LoaderTests.test_module_reuse @ linux-x86_64 +test.test_importlib.builtin.test_loader.Source_LoaderTests.test_unloadable @ linux-x86_64 +test.test_importlib.extension.test_finder.Frozen_FinderTests.test_failure @ linux-x86_64 +test.test_importlib.extension.test_finder.Frozen_FinderTests.test_module @ linux-x86_64 +test.test_importlib.extension.test_finder.Source_FinderTests.test_failure @ linux-x86_64 +test.test_importlib.extension.test_finder.Source_FinderTests.test_module @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_LoaderTests.test_equality @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_LoaderTests.test_inequality @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_LoaderTests.test_is_package @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_LoaderTests.test_load_module_API @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_LoaderTests.test_module @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_LoaderTests.test_module_reuse @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_LoaderTests.test_unloadable @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_MultiPhaseExtensionModuleTests.test_bad_modules @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_MultiPhaseExtensionModuleTests.test_functionality @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_MultiPhaseExtensionModuleTests.test_load_short_name @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_MultiPhaseExtensionModuleTests.test_load_submodule @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_MultiPhaseExtensionModuleTests.test_load_twice @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_MultiPhaseExtensionModuleTests.test_module @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_MultiPhaseExtensionModuleTests.test_nonascii @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_MultiPhaseExtensionModuleTests.test_nonmodule @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_MultiPhaseExtensionModuleTests.test_nonmodule_with_methods @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_MultiPhaseExtensionModuleTests.test_null_slots @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_MultiPhaseExtensionModuleTests.test_reload @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_MultiPhaseExtensionModuleTests.test_try_registration @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_MultiPhaseExtensionModuleTests.test_unloadable @ linux-x86_64 +test.test_importlib.extension.test_loader.Frozen_MultiPhaseExtensionModuleTests.test_unloadable_nonascii @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_LoaderTests.test_equality @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_LoaderTests.test_inequality @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_LoaderTests.test_is_package @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_LoaderTests.test_load_module_API @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_LoaderTests.test_module @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_LoaderTests.test_module_reuse @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_LoaderTests.test_unloadable @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_MultiPhaseExtensionModuleTests.test_bad_modules @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_MultiPhaseExtensionModuleTests.test_functionality @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_MultiPhaseExtensionModuleTests.test_load_short_name @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_MultiPhaseExtensionModuleTests.test_load_submodule @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_MultiPhaseExtensionModuleTests.test_load_twice @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_MultiPhaseExtensionModuleTests.test_module @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_MultiPhaseExtensionModuleTests.test_nonascii @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_MultiPhaseExtensionModuleTests.test_nonmodule @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_MultiPhaseExtensionModuleTests.test_nonmodule_with_methods @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_MultiPhaseExtensionModuleTests.test_null_slots @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_MultiPhaseExtensionModuleTests.test_reload @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_MultiPhaseExtensionModuleTests.test_try_registration @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_MultiPhaseExtensionModuleTests.test_unloadable @ linux-x86_64 +test.test_importlib.extension.test_loader.Source_MultiPhaseExtensionModuleTests.test_unloadable_nonascii @ linux-x86_64 +test.test_importlib.extension.test_path_hook.Frozen_PathHookTests.test_success @ linux-x86_64 +test.test_importlib.extension.test_path_hook.Source_PathHookTests.test_success @ linux-x86_64 +test.test_importlib.frozen.test_finder.Frozen_FindSpecTests.test_failure @ linux-x86_64 +test.test_importlib.frozen.test_finder.Frozen_FindSpecTests.test_module @ linux-x86_64 +test.test_importlib.frozen.test_finder.Frozen_FindSpecTests.test_not_using_frozen @ linux-x86_64 +test.test_importlib.frozen.test_finder.Frozen_FindSpecTests.test_package @ linux-x86_64 +test.test_importlib.frozen.test_finder.Frozen_FindSpecTests.test_path_ignored @ linux-x86_64 +test.test_importlib.frozen.test_finder.Frozen_FindSpecTests.test_target_ignored @ linux-x86_64 +test.test_importlib.frozen.test_finder.Frozen_FinderTests.test_failure @ linux-x86_64 +test.test_importlib.frozen.test_finder.Frozen_FinderTests.test_module @ linux-x86_64 +test.test_importlib.frozen.test_finder.Frozen_FinderTests.test_module_in_package @ linux-x86_64 +test.test_importlib.frozen.test_finder.Frozen_FinderTests.test_package @ linux-x86_64 +test.test_importlib.frozen.test_finder.Source_FindSpecTests.test_failure @ linux-x86_64 +test.test_importlib.frozen.test_finder.Source_FindSpecTests.test_module @ linux-x86_64 +test.test_importlib.frozen.test_finder.Source_FindSpecTests.test_not_using_frozen @ linux-x86_64 +test.test_importlib.frozen.test_finder.Source_FindSpecTests.test_package @ linux-x86_64 +test.test_importlib.frozen.test_finder.Source_FindSpecTests.test_path_ignored @ linux-x86_64 +test.test_importlib.frozen.test_finder.Source_FindSpecTests.test_target_ignored @ linux-x86_64 +test.test_importlib.frozen.test_finder.Source_FinderTests.test_failure @ linux-x86_64 +test.test_importlib.frozen.test_finder.Source_FinderTests.test_module @ linux-x86_64 +test.test_importlib.frozen.test_finder.Source_FinderTests.test_module_in_package @ linux-x86_64 +test.test_importlib.frozen.test_finder.Source_FinderTests.test_package @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_ExecModuleTests.test_lacking_parent @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_ExecModuleTests.test_module @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_ExecModuleTests.test_module_repr @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_ExecModuleTests.test_module_repr_indirect @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_ExecModuleTests.test_package @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_ExecModuleTests.test_unloadable @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_InspectLoaderTests.test_failure @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_InspectLoaderTests.test_get_code @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_InspectLoaderTests.test_get_source @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_InspectLoaderTests.test_is_package @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_LoaderTests.test_lacking_parent @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_LoaderTests.test_module @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_LoaderTests.test_module_repr @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_LoaderTests.test_module_reuse @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_LoaderTests.test_package @ linux-x86_64 +test.test_importlib.frozen.test_loader.Frozen_LoaderTests.test_unloadable @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_ExecModuleTests.test_lacking_parent @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_ExecModuleTests.test_module @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_ExecModuleTests.test_module_repr @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_ExecModuleTests.test_module_repr_indirect @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_ExecModuleTests.test_package @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_ExecModuleTests.test_unloadable @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_InspectLoaderTests.test_failure @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_InspectLoaderTests.test_get_code @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_InspectLoaderTests.test_get_source @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_InspectLoaderTests.test_is_package @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_LoaderTests.test_lacking_parent @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_LoaderTests.test_module @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_LoaderTests.test_module_repr @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_LoaderTests.test_module_reuse @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_LoaderTests.test_package @ linux-x86_64 +test.test_importlib.frozen.test_loader.Source_LoaderTests.test_unloadable @ linux-x86_64 +test.test_importlib.import_.test___loader__.Frozen_LoaderAttributeTests.test___loader___is_None @ linux-x86_64 +test.test_importlib.import_.test___loader__.Frozen_LoaderAttributeTests.test___loader___missing @ linux-x86_64 +test.test_importlib.import_.test___loader__.Frozen_SpecLoaderAttributeTests.test___loader__ @ linux-x86_64 +test.test_importlib.import_.test___loader__.Source_LoaderAttributeTests.test___loader___is_None @ linux-x86_64 +test.test_importlib.import_.test___loader__.Source_LoaderAttributeTests.test___loader___missing @ linux-x86_64 +test.test_importlib.import_.test___loader__.Source_SpecLoaderAttributeTests.test___loader__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP302.test_None_as___package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP302.test_bad__package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP302.test_bunk__package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP302.test_spec_fallback @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP302.test_using___name__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP302.test_using___package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP302.test_warn_when_package_and_spec_disagree @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP302.test_warn_when_using___name__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP451.test_None_as___package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP451.test_bad__package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP451.test_bunk__package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP451.test_spec_fallback @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP451.test_using___name__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP451.test_using___package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP451.test_warn_when_package_and_spec_disagree @ linux-x86_64 +test.test_importlib.import_.test___package__.Frozen_Using__package__PEP451.test_warn_when_using___name__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Setting__package__PEP302.test_package @ linux-x86_64 +test.test_importlib.import_.test___package__.Setting__package__PEP302.test_submodule @ linux-x86_64 +test.test_importlib.import_.test___package__.Setting__package__PEP302.test_top_level @ linux-x86_64 +test.test_importlib.import_.test___package__.Setting__package__PEP451.test_package @ linux-x86_64 +test.test_importlib.import_.test___package__.Setting__package__PEP451.test_submodule @ linux-x86_64 +test.test_importlib.import_.test___package__.Setting__package__PEP451.test_top_level @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP302.test_None_as___package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP302.test_bad__package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP302.test_bunk__package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP302.test_spec_fallback @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP302.test_using___name__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP302.test_using___package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP302.test_warn_when_package_and_spec_disagree @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP302.test_warn_when_using___name__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP451.test_None_as___package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP451.test_bad__package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP451.test_bunk__package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP451.test_spec_fallback @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP451.test_using___name__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP451.test_using___package__ @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP451.test_warn_when_package_and_spec_disagree @ linux-x86_64 +test.test_importlib.import_.test___package__.Source_Using__package__PEP451.test_warn_when_using___name__ @ linux-x86_64 +test.test_importlib.import_.test_api.Frozen_OldAPITests.test_blocked_fromlist @ linux-x86_64 +test.test_importlib.import_.test_api.Frozen_OldAPITests.test_fromlist_load_error_propagates @ linux-x86_64 +test.test_importlib.import_.test_api.Frozen_OldAPITests.test_name_requires_rparition @ linux-x86_64 +test.test_importlib.import_.test_api.Frozen_OldAPITests.test_negative_level @ linux-x86_64 +test.test_importlib.import_.test_api.Frozen_OldAPITests.test_nonexistent_fromlist_entry @ linux-x86_64 +test.test_importlib.import_.test_api.Frozen_OldAPITests.test_raises_ModuleNotFoundError @ linux-x86_64 +test.test_importlib.import_.test_api.Frozen_SpecAPITests.test_blocked_fromlist @ linux-x86_64 +test.test_importlib.import_.test_api.Frozen_SpecAPITests.test_fromlist_load_error_propagates @ linux-x86_64 +test.test_importlib.import_.test_api.Frozen_SpecAPITests.test_name_requires_rparition @ linux-x86_64 +test.test_importlib.import_.test_api.Frozen_SpecAPITests.test_negative_level @ linux-x86_64 +test.test_importlib.import_.test_api.Frozen_SpecAPITests.test_nonexistent_fromlist_entry @ linux-x86_64 +test.test_importlib.import_.test_api.Frozen_SpecAPITests.test_raises_ModuleNotFoundError @ linux-x86_64 +test.test_importlib.import_.test_api.Source_OldAPITests.test_blocked_fromlist @ linux-x86_64 +test.test_importlib.import_.test_api.Source_OldAPITests.test_fromlist_load_error_propagates @ linux-x86_64 +test.test_importlib.import_.test_api.Source_OldAPITests.test_name_requires_rparition @ linux-x86_64 +test.test_importlib.import_.test_api.Source_OldAPITests.test_negative_level @ linux-x86_64 +test.test_importlib.import_.test_api.Source_OldAPITests.test_nonexistent_fromlist_entry @ linux-x86_64 +test.test_importlib.import_.test_api.Source_OldAPITests.test_raises_ModuleNotFoundError @ linux-x86_64 +test.test_importlib.import_.test_api.Source_SpecAPITests.test_blocked_fromlist @ linux-x86_64 +test.test_importlib.import_.test_api.Source_SpecAPITests.test_fromlist_load_error_propagates @ linux-x86_64 +test.test_importlib.import_.test_api.Source_SpecAPITests.test_name_requires_rparition @ linux-x86_64 +test.test_importlib.import_.test_api.Source_SpecAPITests.test_negative_level @ linux-x86_64 +test.test_importlib.import_.test_api.Source_SpecAPITests.test_nonexistent_fromlist_entry @ linux-x86_64 +test.test_importlib.import_.test_api.Source_SpecAPITests.test_raises_ModuleNotFoundError @ linux-x86_64 +test.test_importlib.import_.test_caching.Frozen_UseCache.test_None_in_cache @ linux-x86_64 +test.test_importlib.import_.test_caching.Frozen_UseCache.test_using_cache @ linux-x86_64 +test.test_importlib.import_.test_caching.ImportlibUseCache.test_None_in_cache @ linux-x86_64 +test.test_importlib.import_.test_caching.ImportlibUseCache.test_using_cache @ linux-x86_64 +test.test_importlib.import_.test_caching.ImportlibUseCache.test_using_cache_after_loader @ linux-x86_64 +test.test_importlib.import_.test_caching.ImportlibUseCache.test_using_cache_for_assigning_to_attribute @ linux-x86_64 +test.test_importlib.import_.test_caching.ImportlibUseCache.test_using_cache_for_fromlist @ linux-x86_64 +test.test_importlib.import_.test_caching.Source_UseCache.test_None_in_cache @ linux-x86_64 +test.test_importlib.import_.test_caching.Source_UseCache.test_using_cache @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Frozen_HandlingFromlist.test_empty_string @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Frozen_HandlingFromlist.test_fromlist_as_tuple @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Frozen_HandlingFromlist.test_invalid_type @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Frozen_HandlingFromlist.test_invalid_type_in_all @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Frozen_HandlingFromlist.test_module_from_package @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Frozen_HandlingFromlist.test_module_from_package_triggers_ModuleNotFoundError @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Frozen_HandlingFromlist.test_nonexistent_from_package @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Frozen_HandlingFromlist.test_nonexistent_in_all @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Frozen_HandlingFromlist.test_nonexistent_object @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Frozen_HandlingFromlist.test_object @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Frozen_HandlingFromlist.test_star_in_all @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Frozen_HandlingFromlist.test_star_with_others @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Frozen_HandlingFromlist.test_using_star @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Frozen_ReturnValue.test_return_from_from_import @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Frozen_ReturnValue.test_return_from_import @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Source_HandlingFromlist.test_empty_string @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Source_HandlingFromlist.test_fromlist_as_tuple @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Source_HandlingFromlist.test_invalid_type @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Source_HandlingFromlist.test_invalid_type_in_all @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Source_HandlingFromlist.test_module_from_package @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Source_HandlingFromlist.test_module_from_package_triggers_ModuleNotFoundError @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Source_HandlingFromlist.test_nonexistent_from_package @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Source_HandlingFromlist.test_nonexistent_in_all @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Source_HandlingFromlist.test_nonexistent_object @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Source_HandlingFromlist.test_object @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Source_HandlingFromlist.test_star_in_all @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Source_HandlingFromlist.test_star_with_others @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Source_HandlingFromlist.test_using_star @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Source_ReturnValue.test_return_from_from_import @ linux-x86_64 +test.test_importlib.import_.test_fromlist.Source_ReturnValue.test_return_from_import @ linux-x86_64 +test.test_importlib.import_.test_meta_path.Frozen_CallSignaturePEP302.test_no_path @ linux-x86_64 +test.test_importlib.import_.test_meta_path.Frozen_CallSignaturePEP302.test_with_path @ linux-x86_64 +test.test_importlib.import_.test_meta_path.Frozen_CallSignaturePEP451.test_no_path @ linux-x86_64 +test.test_importlib.import_.test_meta_path.Frozen_CallSignaturePEP451.test_with_path @ linux-x86_64 +test.test_importlib.import_.test_meta_path.Frozen_CallingOrder.test_continuing @ linux-x86_64 +test.test_importlib.import_.test_meta_path.Frozen_CallingOrder.test_empty @ linux-x86_64 +test.test_importlib.import_.test_meta_path.Frozen_CallingOrder.test_first_called @ linux-x86_64 +test.test_importlib.import_.test_meta_path.Source_CallSignaturePEP302.test_no_path @ linux-x86_64 +test.test_importlib.import_.test_meta_path.Source_CallSignaturePEP302.test_with_path @ linux-x86_64 +test.test_importlib.import_.test_meta_path.Source_CallSignaturePEP451.test_no_path @ linux-x86_64 +test.test_importlib.import_.test_meta_path.Source_CallSignaturePEP451.test_with_path @ linux-x86_64 +test.test_importlib.import_.test_meta_path.Source_CallingOrder.test_continuing @ linux-x86_64 +test.test_importlib.import_.test_meta_path.Source_CallingOrder.test_empty @ linux-x86_64 +test.test_importlib.import_.test_meta_path.Source_CallingOrder.test_first_called @ linux-x86_64 +test.test_importlib.import_.test_packages.Frozen_ParentModuleTests.test_bad_parent @ linux-x86_64 +test.test_importlib.import_.test_packages.Frozen_ParentModuleTests.test_import_parent @ linux-x86_64 +test.test_importlib.import_.test_packages.Frozen_ParentModuleTests.test_module_not_package @ linux-x86_64 +test.test_importlib.import_.test_packages.Frozen_ParentModuleTests.test_module_not_package_but_side_effects @ linux-x86_64 +test.test_importlib.import_.test_packages.Frozen_ParentModuleTests.test_raising_parent_after_double_relative_importing_child @ linux-x86_64 +test.test_importlib.import_.test_packages.Frozen_ParentModuleTests.test_raising_parent_after_importing_child @ linux-x86_64 +test.test_importlib.import_.test_packages.Frozen_ParentModuleTests.test_raising_parent_after_relative_importing_child @ linux-x86_64 +test.test_importlib.import_.test_packages.Source_ParentModuleTests.test_bad_parent @ linux-x86_64 +test.test_importlib.import_.test_packages.Source_ParentModuleTests.test_import_parent @ linux-x86_64 +test.test_importlib.import_.test_packages.Source_ParentModuleTests.test_module_not_package @ linux-x86_64 +test.test_importlib.import_.test_packages.Source_ParentModuleTests.test_module_not_package_but_side_effects @ linux-x86_64 +test.test_importlib.import_.test_packages.Source_ParentModuleTests.test_raising_parent_after_double_relative_importing_child @ linux-x86_64 +test.test_importlib.import_.test_packages.Source_ParentModuleTests.test_raising_parent_after_importing_child @ linux-x86_64 +test.test_importlib.import_.test_packages.Source_ParentModuleTests.test_raising_parent_after_relative_importing_child @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindModuleTests.test_None_on_sys_path @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindModuleTests.test_deleted_cwd @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindModuleTests.test_empty_list @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindModuleTests.test_empty_path_hooks @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindModuleTests.test_failure @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindModuleTests.test_finder_with_find_loader @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindModuleTests.test_finder_with_find_module @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindModuleTests.test_finder_with_find_spec @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindModuleTests.test_invalidate_caches_clear_out_None @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindModuleTests.test_invalidate_caches_clear_out_relative_path @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindModuleTests.test_invalidate_caches_finders @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindModuleTests.test_path @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindModuleTests.test_path_hooks @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindModuleTests.test_path_importer_cache_empty_string @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindModuleTests.test_sys_path @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindSpecTests.test_None_on_sys_path @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindSpecTests.test_deleted_cwd @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindSpecTests.test_empty_list @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindSpecTests.test_empty_path_hooks @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindSpecTests.test_failure @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindSpecTests.test_finder_with_find_loader @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindSpecTests.test_finder_with_find_module @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindSpecTests.test_finder_with_find_spec @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindSpecTests.test_invalidate_caches_clear_out_None @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindSpecTests.test_invalidate_caches_clear_out_relative_path @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindSpecTests.test_invalidate_caches_finders @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindSpecTests.test_path @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindSpecTests.test_path_hooks @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindSpecTests.test_path_importer_cache_empty_string @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_FindSpecTests.test_sys_path @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_PathEntryFinderTests.test_finder_with_failing_find_module @ linux-x86_64 +test.test_importlib.import_.test_path.Frozen_PathEntryFinderTests.test_finder_with_failing_find_spec @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindModuleTests.test_None_on_sys_path @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindModuleTests.test_deleted_cwd @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindModuleTests.test_empty_list @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindModuleTests.test_empty_path_hooks @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindModuleTests.test_failure @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindModuleTests.test_finder_with_find_loader @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindModuleTests.test_finder_with_find_module @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindModuleTests.test_finder_with_find_spec @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindModuleTests.test_invalidate_caches_clear_out_None @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindModuleTests.test_invalidate_caches_clear_out_relative_path @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindModuleTests.test_invalidate_caches_finders @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindModuleTests.test_path @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindModuleTests.test_path_hooks @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindModuleTests.test_path_importer_cache_empty_string @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindModuleTests.test_sys_path @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindSpecTests.test_None_on_sys_path @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindSpecTests.test_deleted_cwd @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindSpecTests.test_empty_list @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindSpecTests.test_empty_path_hooks @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindSpecTests.test_failure @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindSpecTests.test_finder_with_find_loader @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindSpecTests.test_finder_with_find_module @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindSpecTests.test_finder_with_find_spec @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindSpecTests.test_invalidate_caches_clear_out_None @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindSpecTests.test_invalidate_caches_clear_out_relative_path @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindSpecTests.test_invalidate_caches_finders @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindSpecTests.test_path @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindSpecTests.test_path_hooks @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindSpecTests.test_path_importer_cache_empty_string @ linux-x86_64 +test.test_importlib.import_.test_path.Source_FindSpecTests.test_sys_path @ linux-x86_64 +test.test_importlib.import_.test_path.Source_PathEntryFinderTests.test_finder_with_failing_find_module @ linux-x86_64 +test.test_importlib.import_.test_path.Source_PathEntryFinderTests.test_finder_with_failing_find_spec @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Frozen_RelativeImports.test_attr_from_module @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Frozen_RelativeImports.test_deep_import @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Frozen_RelativeImports.test_empty_name_w_level_0 @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Frozen_RelativeImports.test_import_from_different_package @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Frozen_RelativeImports.test_import_relative_import_no_fromlist @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Frozen_RelativeImports.test_module_from_module @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Frozen_RelativeImports.test_module_to_package @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Frozen_RelativeImports.test_package_to_module @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Frozen_RelativeImports.test_package_to_package @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Frozen_RelativeImports.test_relative_import_no_globals @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Frozen_RelativeImports.test_relative_import_no_package @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Frozen_RelativeImports.test_relative_import_no_package_exists_absolute @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Frozen_RelativeImports.test_too_high_from_module @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Frozen_RelativeImports.test_too_high_from_package @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Source_RelativeImports.test_attr_from_module @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Source_RelativeImports.test_deep_import @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Source_RelativeImports.test_empty_name_w_level_0 @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Source_RelativeImports.test_import_from_different_package @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Source_RelativeImports.test_import_relative_import_no_fromlist @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Source_RelativeImports.test_module_from_module @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Source_RelativeImports.test_module_to_package @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Source_RelativeImports.test_package_to_module @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Source_RelativeImports.test_package_to_package @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Source_RelativeImports.test_relative_import_no_globals @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Source_RelativeImports.test_relative_import_no_package @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Source_RelativeImports.test_relative_import_no_package_exists_absolute @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Source_RelativeImports.test_too_high_from_module @ linux-x86_64 +test.test_importlib.import_.test_relative_imports.Source_RelativeImports.test_too_high_from_package @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_bad_syntax @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_checked_hash_based_pyc @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_equality @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_file_from_empty_string_dir @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_get_filename_API @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_inequality @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_lacking_parent @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_load_module_API @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_module @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_module_reuse @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_overridden_checked_hash_based_pyc @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_overridden_unchecked_hash_based_pyc @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_package @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_state_after_failure @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_timestamp_overflow @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_unchecked_hash_based_pyc @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SimpleTest.test_unloadable @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP302.test_bad_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP302.test_bad_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP302.test_empty_file @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP302.test_magic_only @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP302.test_no_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP302.test_non_code_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP302.test_old_timestamp @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP302.test_partial_flags @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP302.test_partial_hash @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP302.test_partial_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP302.test_partial_size @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP302.test_partial_timestamp @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP302.test_read_only_bytecode @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP451.test_bad_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP451.test_bad_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP451.test_empty_file @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP451.test_magic_only @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP451.test_no_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP451.test_non_code_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP451.test_old_timestamp @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP451.test_partial_flags @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP451.test_partial_hash @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP451.test_partial_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP451.test_partial_size @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP451.test_partial_timestamp @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourceLoaderBadBytecodeTestPEP451.test_read_only_bytecode @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP302.test_bad_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP302.test_empty_file @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP302.test_magic_only @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP302.test_no_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP302.test_non_code_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP302.test_partial_flags @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP302.test_partial_hash @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP302.test_partial_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP302.test_partial_size @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP302.test_partial_timestamp @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP451.test_bad_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP451.test_empty_file @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP451.test_magic_only @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP451.test_no_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP451.test_non_code_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP451.test_partial_flags @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP451.test_partial_hash @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP451.test_partial_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP451.test_partial_size @ linux-x86_64 +test.test_importlib.source.test_file_loader.Frozen_SourcelessLoaderBadBytecodeTestPEP451.test_partial_timestamp @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_bad_syntax @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_checked_hash_based_pyc @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_equality @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_file_from_empty_string_dir @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_get_filename_API @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_inequality @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_lacking_parent @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_load_module_API @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_module @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_module_reuse @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_overridden_checked_hash_based_pyc @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_overridden_unchecked_hash_based_pyc @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_package @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_state_after_failure @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_timestamp_overflow @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_unchecked_hash_based_pyc @ linux-x86_64 +test.test_importlib.source.test_file_loader.SourceDateEpoch_SimpleTest.test_unloadable @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_bad_syntax @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_checked_hash_based_pyc @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_equality @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_file_from_empty_string_dir @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_get_filename_API @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_inequality @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_lacking_parent @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_load_module_API @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_module @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_module_reuse @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_overridden_checked_hash_based_pyc @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_overridden_unchecked_hash_based_pyc @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_package @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_state_after_failure @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_timestamp_overflow @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_unchecked_hash_based_pyc @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SimpleTest.test_unloadable @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP302.test_bad_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP302.test_bad_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP302.test_empty_file @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP302.test_magic_only @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP302.test_no_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP302.test_non_code_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP302.test_old_timestamp @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP302.test_partial_flags @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP302.test_partial_hash @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP302.test_partial_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP302.test_partial_size @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP302.test_partial_timestamp @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP302.test_read_only_bytecode @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP451.test_bad_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP451.test_bad_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP451.test_empty_file @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP451.test_magic_only @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP451.test_no_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP451.test_non_code_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP451.test_old_timestamp @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP451.test_partial_flags @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP451.test_partial_hash @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP451.test_partial_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP451.test_partial_size @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP451.test_partial_timestamp @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourceLoaderBadBytecodeTestPEP451.test_read_only_bytecode @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP302.test_bad_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP302.test_empty_file @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP302.test_magic_only @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP302.test_no_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP302.test_non_code_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP302.test_partial_flags @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP302.test_partial_hash @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP302.test_partial_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP302.test_partial_size @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP302.test_partial_timestamp @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP451.test_bad_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP451.test_empty_file @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP451.test_magic_only @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP451.test_no_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP451.test_non_code_marshal @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP451.test_partial_flags @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP451.test_partial_hash @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP451.test_partial_magic @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP451.test_partial_size @ linux-x86_64 +test.test_importlib.source.test_file_loader.Source_SourcelessLoaderBadBytecodeTestPEP451.test_partial_timestamp @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP302.test_dir_removal_handling @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP302.test_empty_string_for_dir @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP302.test_failure @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP302.test_ignore_file @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP302.test_invalidate_caches @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP302.test_module @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP302.test_module_in_package @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP302.test_no_read_directory @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP302.test_package @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP302.test_package_in_package @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP302.test_package_over_module @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP420.test_dir_removal_handling @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP420.test_empty_string_for_dir @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP420.test_failure @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP420.test_ignore_file @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP420.test_invalidate_caches @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP420.test_module @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP420.test_module_in_package @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP420.test_no_read_directory @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP420.test_package @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP420.test_package_in_package @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP420.test_package_over_module @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP451.test_dir_removal_handling @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP451.test_empty_string_for_dir @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP451.test_failure @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP451.test_ignore_file @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP451.test_invalidate_caches @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP451.test_module @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP451.test_module_in_package @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP451.test_no_read_directory @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP451.test_package @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP451.test_package_in_package @ linux-x86_64 +test.test_importlib.source.test_finder.Frozen_FinderTestsPEP451.test_package_over_module @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP302.test_dir_removal_handling @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP302.test_empty_string_for_dir @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP302.test_failure @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP302.test_ignore_file @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP302.test_invalidate_caches @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP302.test_module @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP302.test_module_in_package @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP302.test_no_read_directory @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP302.test_package @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP302.test_package_in_package @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP302.test_package_over_module @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP420.test_dir_removal_handling @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP420.test_empty_string_for_dir @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP420.test_failure @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP420.test_ignore_file @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP420.test_invalidate_caches @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP420.test_module @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP420.test_module_in_package @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP420.test_no_read_directory @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP420.test_package @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP420.test_package_in_package @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP420.test_package_over_module @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP451.test_dir_removal_handling @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP451.test_empty_string_for_dir @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP451.test_failure @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP451.test_ignore_file @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP451.test_invalidate_caches @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP451.test_module @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP451.test_module_in_package @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP451.test_no_read_directory @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP451.test_package @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP451.test_package_in_package @ linux-x86_64 +test.test_importlib.source.test_finder.Source_FinderTestsPEP451.test_package_over_module @ linux-x86_64 +test.test_importlib.source.test_path_hook.Frozen_PathHookTest.test_empty_string @ linux-x86_64 +test.test_importlib.source.test_path_hook.Frozen_PathHookTest.test_empty_string_legacy @ linux-x86_64 +test.test_importlib.source.test_path_hook.Frozen_PathHookTest.test_success @ linux-x86_64 +test.test_importlib.source.test_path_hook.Frozen_PathHookTest.test_success_legacy @ linux-x86_64 +test.test_importlib.source.test_path_hook.Source_PathHookTest.test_empty_string @ linux-x86_64 +test.test_importlib.source.test_path_hook.Source_PathHookTest.test_empty_string_legacy @ linux-x86_64 +test.test_importlib.source.test_path_hook.Source_PathHookTest.test_success @ linux-x86_64 +test.test_importlib.source.test_path_hook.Source_PathHookTest.test_success_legacy @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_EncodingTestPEP302.test_bom @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_EncodingTestPEP302.test_bom_and_utf_8 @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_EncodingTestPEP302.test_bom_conflict @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_EncodingTestPEP302.test_default_encoding @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_EncodingTestPEP302.test_encoding_on_first_line @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_EncodingTestPEP302.test_encoding_on_second_line @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_EncodingTestPEP302.test_non_obvious_encoding @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_EncodingTestPEP451.test_bom @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_EncodingTestPEP451.test_bom_and_utf_8 @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_EncodingTestPEP451.test_bom_conflict @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_EncodingTestPEP451.test_default_encoding @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_EncodingTestPEP451.test_encoding_on_first_line @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_EncodingTestPEP451.test_encoding_on_second_line @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_EncodingTestPEP451.test_non_obvious_encoding @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_LineEndingTestPEP302.test_cr @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_LineEndingTestPEP302.test_crlf @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_LineEndingTestPEP302.test_lf @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_LineEndingTestPEP451.test_cr @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_LineEndingTestPEP451.test_crlf @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Frozen_LineEndingTestPEP451.test_lf @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_EncodingTestPEP302.test_bom @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_EncodingTestPEP302.test_bom_and_utf_8 @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_EncodingTestPEP302.test_bom_conflict @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_EncodingTestPEP302.test_default_encoding @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_EncodingTestPEP302.test_encoding_on_first_line @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_EncodingTestPEP302.test_encoding_on_second_line @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_EncodingTestPEP302.test_non_obvious_encoding @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_EncodingTestPEP451.test_bom @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_EncodingTestPEP451.test_bom_and_utf_8 @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_EncodingTestPEP451.test_bom_conflict @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_EncodingTestPEP451.test_default_encoding @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_EncodingTestPEP451.test_encoding_on_first_line @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_EncodingTestPEP451.test_encoding_on_second_line @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_EncodingTestPEP451.test_non_obvious_encoding @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_LineEndingTestPEP302.test_cr @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_LineEndingTestPEP302.test_crlf @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_LineEndingTestPEP302.test_lf @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_LineEndingTestPEP451.test_cr @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_LineEndingTestPEP451.test_crlf @ linux-x86_64 +test.test_importlib.source.test_source_encoding.Source_LineEndingTestPEP451.test_lf @ linux-x86_64 +test.test_importlib.test_abc.Frozen_ExecutionLoader.test_subclasses @ linux-x86_64 +test.test_importlib.test_abc.Frozen_ExecutionLoader.test_superclasses @ linux-x86_64 +test.test_importlib.test_abc.Frozen_ExecutionLoaderGetCodeTests.test_get_code @ linux-x86_64 +test.test_importlib.test_abc.Frozen_ExecutionLoaderGetCodeTests.test_get_code_no_path @ linux-x86_64 +test.test_importlib.test_abc.Frozen_ExecutionLoaderGetCodeTests.test_get_code_source_is_None @ linux-x86_64 +test.test_importlib.test_abc.Frozen_ExecutionLoaderGetCodeTests.test_get_code_source_not_found @ linux-x86_64 +test.test_importlib.test_abc.Frozen_FileLoader.test_subclasses @ linux-x86_64 +test.test_importlib.test_abc.Frozen_FileLoader.test_superclasses @ linux-x86_64 +test.test_importlib.test_abc.Frozen_InspectLoader.test_subclasses @ linux-x86_64 +test.test_importlib.test_abc.Frozen_InspectLoader.test_superclasses @ linux-x86_64 +test.test_importlib.test_abc.Frozen_InspectLoaderDefaultsTests.test_get_source @ linux-x86_64 +test.test_importlib.test_abc.Frozen_InspectLoaderDefaultsTests.test_is_package @ linux-x86_64 +test.test_importlib.test_abc.Frozen_InspectLoaderGetCodeTests.test_get_code @ linux-x86_64 +test.test_importlib.test_abc.Frozen_InspectLoaderGetCodeTests.test_get_code_source_is_None @ linux-x86_64 +test.test_importlib.test_abc.Frozen_InspectLoaderGetCodeTests.test_get_code_source_not_found @ linux-x86_64 +test.test_importlib.test_abc.Frozen_InspectLoaderLoadModuleTests.test_get_code_ImportError @ linux-x86_64 +test.test_importlib.test_abc.Frozen_InspectLoaderLoadModuleTests.test_get_code_None @ linux-x86_64 +test.test_importlib.test_abc.Frozen_InspectLoaderLoadModuleTests.test_module_returned @ linux-x86_64 +test.test_importlib.test_abc.Frozen_InspectLoaderSourceToCodeTests.test_source_to_code_bytes @ linux-x86_64 +test.test_importlib.test_abc.Frozen_InspectLoaderSourceToCodeTests.test_source_to_code_no_path @ linux-x86_64 +test.test_importlib.test_abc.Frozen_InspectLoaderSourceToCodeTests.test_source_to_code_path @ linux-x86_64 +test.test_importlib.test_abc.Frozen_InspectLoaderSourceToCodeTests.test_source_to_code_source @ linux-x86_64 +test.test_importlib.test_abc.Frozen_LoaderDefaultsTests.test_create_module @ linux-x86_64 +test.test_importlib.test_abc.Frozen_LoaderDefaultsTests.test_load_module @ linux-x86_64 +test.test_importlib.test_abc.Frozen_LoaderDefaultsTests.test_module_repr @ linux-x86_64 +test.test_importlib.test_abc.Frozen_LoaderLoadModuleTests.test_fresh @ linux-x86_64 +test.test_importlib.test_abc.Frozen_LoaderLoadModuleTests.test_reload @ linux-x86_64 +test.test_importlib.test_abc.Frozen_MetaPathFinder.test_subclasses @ linux-x86_64 +test.test_importlib.test_abc.Frozen_MetaPathFinder.test_superclasses @ linux-x86_64 +test.test_importlib.test_abc.Frozen_MetaPathFinderDefaultsTests.test_find_module @ linux-x86_64 +test.test_importlib.test_abc.Frozen_MetaPathFinderDefaultsTests.test_invalidate_caches @ linux-x86_64 +test.test_importlib.test_abc.Frozen_MetaPathFinderFindModuleTests.test_find_module @ linux-x86_64 +test.test_importlib.test_abc.Frozen_MetaPathFinderFindModuleTests.test_find_spec_with_explicit_target @ linux-x86_64 +test.test_importlib.test_abc.Frozen_MetaPathFinderFindModuleTests.test_no_spec @ linux-x86_64 +test.test_importlib.test_abc.Frozen_MetaPathFinderFindModuleTests.test_spec @ linux-x86_64 +test.test_importlib.test_abc.Frozen_PathEntryFinder.test_subclasses @ linux-x86_64 +test.test_importlib.test_abc.Frozen_PathEntryFinder.test_superclasses @ linux-x86_64 +test.test_importlib.test_abc.Frozen_PathEntryFinderDefaultsTests.test_find_loader @ linux-x86_64 +test.test_importlib.test_abc.Frozen_PathEntryFinderDefaultsTests.test_invalidate_caches @ linux-x86_64 +test.test_importlib.test_abc.Frozen_PathEntryFinderFindLoaderTests.test_no_spec @ linux-x86_64 +test.test_importlib.test_abc.Frozen_PathEntryFinderFindLoaderTests.test_spec_with_loader @ linux-x86_64 +test.test_importlib.test_abc.Frozen_PathEntryFinderFindLoaderTests.test_spec_with_portions @ linux-x86_64 +test.test_importlib.test_abc.Frozen_ResourceLoader.test_subclasses @ linux-x86_64 +test.test_importlib.test_abc.Frozen_ResourceLoader.test_superclasses @ linux-x86_64 +test.test_importlib.test_abc.Frozen_ResourceLoaderDefaultsTests.test_get_data @ linux-x86_64 +test.test_importlib.test_abc.Frozen_ResourceReaderDefaultsTests.test_contents @ linux-x86_64 +test.test_importlib.test_abc.Frozen_ResourceReaderDefaultsTests.test_is_resource @ linux-x86_64 +test.test_importlib.test_abc.Frozen_ResourceReaderDefaultsTests.test_open_resource @ linux-x86_64 +test.test_importlib.test_abc.Frozen_ResourceReaderDefaultsTests.test_resource_path @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceLoader.test_subclasses @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceLoader.test_superclasses @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceLoaderBytecodeTests.test_code_bad_magic @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceLoaderBytecodeTests.test_code_bad_timestamp @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceLoaderBytecodeTests.test_code_with_everything @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceLoaderBytecodeTests.test_dont_write_bytecode @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceLoaderBytecodeTests.test_no_bytecode @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceLoaderBytecodeTests.test_no_set_data @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceLoaderBytecodeTests.test_set_data_raises_exceptions @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceLoaderGetSourceTests.test_decoded_source @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceLoaderGetSourceTests.test_default_encoding @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceLoaderGetSourceTests.test_universal_newlines @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceOnlyLoaderTests.test_get_code @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceOnlyLoaderTests.test_get_source @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceOnlyLoaderTests.test_get_source_encoding @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceOnlyLoaderTests.test_is_package @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceOnlyLoaderTests.test_load_module @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceOnlyLoaderTests.test_package_settings @ linux-x86_64 +test.test_importlib.test_abc.Frozen_SourceOnlyLoaderTests.test_source_to_code @ linux-x86_64 +test.test_importlib.test_abc.Source_ExecutionLoader.test_subclasses @ linux-x86_64 +test.test_importlib.test_abc.Source_ExecutionLoader.test_superclasses @ linux-x86_64 +test.test_importlib.test_abc.Source_ExecutionLoaderGetCodeTests.test_get_code @ linux-x86_64 +test.test_importlib.test_abc.Source_ExecutionLoaderGetCodeTests.test_get_code_no_path @ linux-x86_64 +test.test_importlib.test_abc.Source_ExecutionLoaderGetCodeTests.test_get_code_source_is_None @ linux-x86_64 +test.test_importlib.test_abc.Source_ExecutionLoaderGetCodeTests.test_get_code_source_not_found @ linux-x86_64 +test.test_importlib.test_abc.Source_FileLoader.test_subclasses @ linux-x86_64 +test.test_importlib.test_abc.Source_FileLoader.test_superclasses @ linux-x86_64 +test.test_importlib.test_abc.Source_InspectLoader.test_subclasses @ linux-x86_64 +test.test_importlib.test_abc.Source_InspectLoader.test_superclasses @ linux-x86_64 +test.test_importlib.test_abc.Source_InspectLoaderDefaultsTests.test_get_source @ linux-x86_64 +test.test_importlib.test_abc.Source_InspectLoaderDefaultsTests.test_is_package @ linux-x86_64 +test.test_importlib.test_abc.Source_InspectLoaderGetCodeTests.test_get_code @ linux-x86_64 +test.test_importlib.test_abc.Source_InspectLoaderGetCodeTests.test_get_code_source_is_None @ linux-x86_64 +test.test_importlib.test_abc.Source_InspectLoaderGetCodeTests.test_get_code_source_not_found @ linux-x86_64 +test.test_importlib.test_abc.Source_InspectLoaderLoadModuleTests.test_get_code_ImportError @ linux-x86_64 +test.test_importlib.test_abc.Source_InspectLoaderLoadModuleTests.test_get_code_None @ linux-x86_64 +test.test_importlib.test_abc.Source_InspectLoaderLoadModuleTests.test_module_returned @ linux-x86_64 +test.test_importlib.test_abc.Source_InspectLoaderSourceToCodeTests.test_source_to_code_bytes @ linux-x86_64 +test.test_importlib.test_abc.Source_InspectLoaderSourceToCodeTests.test_source_to_code_no_path @ linux-x86_64 +test.test_importlib.test_abc.Source_InspectLoaderSourceToCodeTests.test_source_to_code_path @ linux-x86_64 +test.test_importlib.test_abc.Source_InspectLoaderSourceToCodeTests.test_source_to_code_source @ linux-x86_64 +test.test_importlib.test_abc.Source_LoaderDefaultsTests.test_create_module @ linux-x86_64 +test.test_importlib.test_abc.Source_LoaderDefaultsTests.test_load_module @ linux-x86_64 +test.test_importlib.test_abc.Source_LoaderDefaultsTests.test_module_repr @ linux-x86_64 +test.test_importlib.test_abc.Source_LoaderLoadModuleTests.test_fresh @ linux-x86_64 +test.test_importlib.test_abc.Source_LoaderLoadModuleTests.test_reload @ linux-x86_64 +test.test_importlib.test_abc.Source_MetaPathFinder.test_subclasses @ linux-x86_64 +test.test_importlib.test_abc.Source_MetaPathFinder.test_superclasses @ linux-x86_64 +test.test_importlib.test_abc.Source_MetaPathFinderDefaultsTests.test_find_module @ linux-x86_64 +test.test_importlib.test_abc.Source_MetaPathFinderDefaultsTests.test_invalidate_caches @ linux-x86_64 +test.test_importlib.test_abc.Source_MetaPathFinderFindModuleTests.test_find_module @ linux-x86_64 +test.test_importlib.test_abc.Source_MetaPathFinderFindModuleTests.test_find_spec_with_explicit_target @ linux-x86_64 +test.test_importlib.test_abc.Source_MetaPathFinderFindModuleTests.test_no_spec @ linux-x86_64 +test.test_importlib.test_abc.Source_MetaPathFinderFindModuleTests.test_spec @ linux-x86_64 +test.test_importlib.test_abc.Source_PathEntryFinder.test_subclasses @ linux-x86_64 +test.test_importlib.test_abc.Source_PathEntryFinder.test_superclasses @ linux-x86_64 +test.test_importlib.test_abc.Source_PathEntryFinderDefaultsTests.test_find_loader @ linux-x86_64 +test.test_importlib.test_abc.Source_PathEntryFinderDefaultsTests.test_invalidate_caches @ linux-x86_64 +test.test_importlib.test_abc.Source_PathEntryFinderFindLoaderTests.test_no_spec @ linux-x86_64 +test.test_importlib.test_abc.Source_PathEntryFinderFindLoaderTests.test_spec_with_loader @ linux-x86_64 +test.test_importlib.test_abc.Source_PathEntryFinderFindLoaderTests.test_spec_with_portions @ linux-x86_64 +test.test_importlib.test_abc.Source_ResourceLoader.test_subclasses @ linux-x86_64 +test.test_importlib.test_abc.Source_ResourceLoader.test_superclasses @ linux-x86_64 +test.test_importlib.test_abc.Source_ResourceLoaderDefaultsTests.test_get_data @ linux-x86_64 +test.test_importlib.test_abc.Source_ResourceReaderDefaultsTests.test_contents @ linux-x86_64 +test.test_importlib.test_abc.Source_ResourceReaderDefaultsTests.test_is_resource @ linux-x86_64 +test.test_importlib.test_abc.Source_ResourceReaderDefaultsTests.test_open_resource @ linux-x86_64 +test.test_importlib.test_abc.Source_ResourceReaderDefaultsTests.test_resource_path @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceLoader.test_subclasses @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceLoader.test_superclasses @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceLoaderBytecodeTests.test_code_bad_magic @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceLoaderBytecodeTests.test_code_bad_timestamp @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceLoaderBytecodeTests.test_code_with_everything @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceLoaderBytecodeTests.test_dont_write_bytecode @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceLoaderBytecodeTests.test_no_bytecode @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceLoaderBytecodeTests.test_no_set_data @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceLoaderBytecodeTests.test_set_data_raises_exceptions @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceLoaderGetSourceTests.test_decoded_source @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceLoaderGetSourceTests.test_default_encoding @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceLoaderGetSourceTests.test_universal_newlines @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceOnlyLoaderTests.test_get_code @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceOnlyLoaderTests.test_get_source @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceOnlyLoaderTests.test_get_source_encoding @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceOnlyLoaderTests.test_is_package @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceOnlyLoaderTests.test_load_module @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceOnlyLoaderTests.test_package_settings @ linux-x86_64 +test.test_importlib.test_abc.Source_SourceOnlyLoaderTests.test_source_to_code @ linux-x86_64 +test.test_importlib.test_api.FrozenImportlibTests.test_no_frozen_importlib @ linux-x86_64 +test.test_importlib.test_api.Frozen_FindLoaderPEP302Tests.test_nothing @ linux-x86_64 +test.test_importlib.test_api.Frozen_FindLoaderPEP302Tests.test_success @ linux-x86_64 +test.test_importlib.test_api.Frozen_FindLoaderPEP302Tests.test_success_path @ linux-x86_64 +test.test_importlib.test_api.Frozen_FindLoaderPEP302Tests.test_sys_modules @ linux-x86_64 +test.test_importlib.test_api.Frozen_FindLoaderPEP302Tests.test_sys_modules_loader_is_None @ linux-x86_64 +test.test_importlib.test_api.Frozen_FindLoaderPEP302Tests.test_sys_modules_loader_is_not_set @ linux-x86_64 +test.test_importlib.test_api.Frozen_FindLoaderPEP451Tests.test_nothing @ linux-x86_64 +test.test_importlib.test_api.Frozen_FindLoaderPEP451Tests.test_success @ linux-x86_64 +test.test_importlib.test_api.Frozen_FindLoaderPEP451Tests.test_success_path @ linux-x86_64 +test.test_importlib.test_api.Frozen_FindLoaderPEP451Tests.test_sys_modules @ linux-x86_64 +test.test_importlib.test_api.Frozen_FindLoaderPEP451Tests.test_sys_modules_loader_is_None @ linux-x86_64 +test.test_importlib.test_api.Frozen_FindLoaderPEP451Tests.test_sys_modules_loader_is_not_set @ linux-x86_64 +test.test_importlib.test_api.Frozen_ImportModuleTests.test_absolute_import_with_package @ linux-x86_64 +test.test_importlib.test_api.Frozen_ImportModuleTests.test_absolute_package_import @ linux-x86_64 +test.test_importlib.test_api.Frozen_ImportModuleTests.test_deep_relative_package_import @ linux-x86_64 +test.test_importlib.test_api.Frozen_ImportModuleTests.test_loaded_once @ linux-x86_64 +test.test_importlib.test_api.Frozen_ImportModuleTests.test_module_import @ linux-x86_64 +test.test_importlib.test_api.Frozen_ImportModuleTests.test_relative_import_wo_package @ linux-x86_64 +test.test_importlib.test_api.Frozen_ImportModuleTests.test_shallow_relative_package_import @ linux-x86_64 +test.test_importlib.test_api.Frozen_InvalidateCacheTests.test_method_called @ linux-x86_64 +test.test_importlib.test_api.Frozen_InvalidateCacheTests.test_method_lacking @ linux-x86_64 +test.test_importlib.test_api.Frozen_ReloadTests.test_module_missing_spec @ linux-x86_64 +test.test_importlib.test_api.Frozen_ReloadTests.test_module_replaced @ linux-x86_64 +test.test_importlib.test_api.Frozen_ReloadTests.test_reload_loader_replaced @ linux-x86_64 +test.test_importlib.test_api.Frozen_ReloadTests.test_reload_location_changed @ linux-x86_64 +test.test_importlib.test_api.Frozen_ReloadTests.test_reload_missing_loader @ linux-x86_64 +test.test_importlib.test_api.Frozen_ReloadTests.test_reload_modules @ linux-x86_64 +test.test_importlib.test_api.Frozen_ReloadTests.test_reload_namespace_changed @ linux-x86_64 +test.test_importlib.test_api.Frozen_ReloadTests.test_reload_submodule @ linux-x86_64 +test.test_importlib.test_api.Frozen_StartupTests.test_everyone_has___loader__ @ linux-x86_64 +test.test_importlib.test_api.Frozen_StartupTests.test_everyone_has___spec__ @ linux-x86_64 +test.test_importlib.test_api.Source_FindLoaderPEP302Tests.test_nothing @ linux-x86_64 +test.test_importlib.test_api.Source_FindLoaderPEP302Tests.test_success @ linux-x86_64 +test.test_importlib.test_api.Source_FindLoaderPEP302Tests.test_success_path @ linux-x86_64 +test.test_importlib.test_api.Source_FindLoaderPEP302Tests.test_sys_modules @ linux-x86_64 +test.test_importlib.test_api.Source_FindLoaderPEP302Tests.test_sys_modules_loader_is_None @ linux-x86_64 +test.test_importlib.test_api.Source_FindLoaderPEP302Tests.test_sys_modules_loader_is_not_set @ linux-x86_64 +test.test_importlib.test_api.Source_FindLoaderPEP451Tests.test_nothing @ linux-x86_64 +test.test_importlib.test_api.Source_FindLoaderPEP451Tests.test_success @ linux-x86_64 +test.test_importlib.test_api.Source_FindLoaderPEP451Tests.test_success_path @ linux-x86_64 +test.test_importlib.test_api.Source_FindLoaderPEP451Tests.test_sys_modules @ linux-x86_64 +test.test_importlib.test_api.Source_FindLoaderPEP451Tests.test_sys_modules_loader_is_None @ linux-x86_64 +test.test_importlib.test_api.Source_FindLoaderPEP451Tests.test_sys_modules_loader_is_not_set @ linux-x86_64 +test.test_importlib.test_api.Source_ImportModuleTests.test_absolute_import_with_package @ linux-x86_64 +test.test_importlib.test_api.Source_ImportModuleTests.test_absolute_package_import @ linux-x86_64 +test.test_importlib.test_api.Source_ImportModuleTests.test_deep_relative_package_import @ linux-x86_64 +test.test_importlib.test_api.Source_ImportModuleTests.test_loaded_once @ linux-x86_64 +test.test_importlib.test_api.Source_ImportModuleTests.test_module_import @ linux-x86_64 +test.test_importlib.test_api.Source_ImportModuleTests.test_relative_import_wo_package @ linux-x86_64 +test.test_importlib.test_api.Source_ImportModuleTests.test_shallow_relative_package_import @ linux-x86_64 +test.test_importlib.test_api.Source_InvalidateCacheTests.test_method_called @ linux-x86_64 +test.test_importlib.test_api.Source_InvalidateCacheTests.test_method_lacking @ linux-x86_64 +test.test_importlib.test_api.Source_ReloadTests.test_module_missing_spec @ linux-x86_64 +test.test_importlib.test_api.Source_ReloadTests.test_module_replaced @ linux-x86_64 +test.test_importlib.test_api.Source_ReloadTests.test_reload_loader_replaced @ linux-x86_64 +test.test_importlib.test_api.Source_ReloadTests.test_reload_location_changed @ linux-x86_64 +test.test_importlib.test_api.Source_ReloadTests.test_reload_missing_loader @ linux-x86_64 +test.test_importlib.test_api.Source_ReloadTests.test_reload_modules @ linux-x86_64 +test.test_importlib.test_api.Source_ReloadTests.test_reload_namespace_changed @ linux-x86_64 +test.test_importlib.test_api.Source_ReloadTests.test_reload_submodule @ linux-x86_64 +test.test_importlib.test_api.Source_StartupTests.test_everyone_has___loader__ @ linux-x86_64 +test.test_importlib.test_api.Source_StartupTests.test_everyone_has___spec__ @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesNoReaderTests.test_spec_path_joinpath @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesTests.test_child_path_is @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesTests.test_child_path_iter @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesTests.test_child_path_name @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesTests.test_child_path_open @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesTests.test_open_invalid_mode @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesTests.test_orphan_path_invalid @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesTests.test_orphan_path_is @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesTests.test_orphan_path_iter @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesTests.test_orphan_path_name @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesTests.test_orphan_path_open @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesTests.test_spec_path_is @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesTests.test_spec_path_iter @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesTests.test_spec_path_name @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesTests.test_spec_path_open @ linux-x86_64 +test.test_importlib.test_compatibilty_files.CompatibilityFilesTests.test_wrap_spec @ linux-x86_64 +test.test_importlib.test_contents.ContentsDiskTests.test_contents @ linux-x86_64 +test.test_importlib.test_contents.ContentsNamespaceTests.test_contents @ linux-x86_64 +test.test_importlib.test_contents.ContentsZipTests.test_contents @ linux-x86_64 +test.test_importlib.test_files.OpenDiskTests.test_read_bytes @ linux-x86_64 +test.test_importlib.test_files.OpenDiskTests.test_read_text @ linux-x86_64 +test.test_importlib.test_files.OpenDiskTests.test_traversable @ linux-x86_64 +test.test_importlib.test_files.OpenNamespaceTests.test_read_bytes @ linux-x86_64 +test.test_importlib.test_files.OpenNamespaceTests.test_read_text @ linux-x86_64 +test.test_importlib.test_files.OpenNamespaceTests.test_traversable @ linux-x86_64 +test.test_importlib.test_files.OpenZipTests.test_read_bytes @ linux-x86_64 +test.test_importlib.test_files.OpenZipTests.test_read_text @ linux-x86_64 +test.test_importlib.test_files.OpenZipTests.test_traversable @ linux-x86_64 +test.test_importlib.test_lazy.LazyLoaderFactoryTests.test_init @ linux-x86_64 +test.test_importlib.test_lazy.LazyLoaderFactoryTests.test_validation @ linux-x86_64 +test.test_importlib.test_lazy.LazyLoaderTests.test_attr_unchanged @ linux-x86_64 +test.test_importlib.test_lazy.LazyLoaderTests.test_delete_eventual_attr @ linux-x86_64 +test.test_importlib.test_lazy.LazyLoaderTests.test_delete_preexisting_attr @ linux-x86_64 +test.test_importlib.test_lazy.LazyLoaderTests.test_e2e @ linux-x86_64 +test.test_importlib.test_lazy.LazyLoaderTests.test_init @ linux-x86_64 +test.test_importlib.test_lazy.LazyLoaderTests.test_module_already_in_sys @ linux-x86_64 +test.test_importlib.test_lazy.LazyLoaderTests.test_module_substitution_error @ linux-x86_64 +test.test_importlib.test_lazy.LazyLoaderTests.test_mutated_attr @ linux-x86_64 +test.test_importlib.test_lazy.LazyLoaderTests.test_mutated_preexisting_attr @ linux-x86_64 +test.test_importlib.test_lazy.LazyLoaderTests.test_new_attr @ linux-x86_64 +test.test_importlib.test_locks.Frozen_DeadlockAvoidanceTests.test_deadlock @ linux-x86_64 +test.test_importlib.test_locks.Frozen_DeadlockAvoidanceTests.test_no_deadlock @ linux-x86_64 +test.test_importlib.test_locks.Frozen_LifetimeTests.test_lock_lifetime @ linux-x86_64 +test.test_importlib.test_locks.Frozen_ModuleLockAsRLockTests.test_acquire_contended @ linux-x86_64 +test.test_importlib.test_locks.Frozen_ModuleLockAsRLockTests.test_acquire_destroy @ linux-x86_64 +test.test_importlib.test_locks.Frozen_ModuleLockAsRLockTests.test_acquire_release @ linux-x86_64 +test.test_importlib.test_locks.Frozen_ModuleLockAsRLockTests.test_constructor @ linux-x86_64 +test.test_importlib.test_locks.Frozen_ModuleLockAsRLockTests.test_different_thread @ linux-x86_64 +test.test_importlib.test_locks.Frozen_ModuleLockAsRLockTests.test_reacquire @ linux-x86_64 +test.test_importlib.test_locks.Frozen_ModuleLockAsRLockTests.test_release_unacquired @ linux-x86_64 +test.test_importlib.test_locks.Frozen_ModuleLockAsRLockTests.test_thread_leak @ linux-x86_64 +test.test_importlib.test_locks.Frozen_ModuleLockAsRLockTests.test_weakref_exists @ linux-x86_64 +test.test_importlib.test_locks.Source_DeadlockAvoidanceTests.test_deadlock @ linux-x86_64 +test.test_importlib.test_locks.Source_DeadlockAvoidanceTests.test_no_deadlock @ linux-x86_64 +!test.test_importlib.test_locks.Source_LifetimeTests.test_all_locks @ linux-x86_64 +test.test_importlib.test_locks.Source_LifetimeTests.test_lock_lifetime @ linux-x86_64 +test.test_importlib.test_locks.Source_ModuleLockAsRLockTests.test_acquire_contended @ linux-x86_64 +test.test_importlib.test_locks.Source_ModuleLockAsRLockTests.test_acquire_destroy @ linux-x86_64 +test.test_importlib.test_locks.Source_ModuleLockAsRLockTests.test_acquire_release @ linux-x86_64 +test.test_importlib.test_locks.Source_ModuleLockAsRLockTests.test_constructor @ linux-x86_64 +test.test_importlib.test_locks.Source_ModuleLockAsRLockTests.test_different_thread @ linux-x86_64 +test.test_importlib.test_locks.Source_ModuleLockAsRLockTests.test_reacquire @ linux-x86_64 +test.test_importlib.test_locks.Source_ModuleLockAsRLockTests.test_release_unacquired @ linux-x86_64 +test.test_importlib.test_locks.Source_ModuleLockAsRLockTests.test_thread_leak @ linux-x86_64 +test.test_importlib.test_locks.Source_ModuleLockAsRLockTests.test_weakref_exists @ linux-x86_64 +test.test_importlib.test_main.BasicTests.test_for_name_does_not_exist @ linux-x86_64 +test.test_importlib.test_main.BasicTests.test_invalid_inputs_to_from_name @ linux-x86_64 +test.test_importlib.test_main.BasicTests.test_new_style_classes @ linux-x86_64 +test.test_importlib.test_main.BasicTests.test_package_not_found_mentions_metadata @ linux-x86_64 +test.test_importlib.test_main.BasicTests.test_retrieves_version_of_self @ linux-x86_64 +test.test_importlib.test_main.DirectoryTest.test_egg @ linux-x86_64 +test.test_importlib.test_main.DirectoryTest.test_egg_info @ linux-x86_64 +test.test_importlib.test_main.DiscoveryTests.test_invalid_usage @ linux-x86_64 +test.test_importlib.test_main.DiscoveryTests.test_package_discovery @ linux-x86_64 +test.test_importlib.test_main.FileSystem.test_unicode_dir_on_sys_path @ linux-x86_64 +test.test_importlib.test_main.ImportTests.test_entrypoint_with_colon_in_name @ linux-x86_64 +test.test_importlib.test_main.ImportTests.test_import_nonexistent_module @ linux-x86_64 +test.test_importlib.test_main.ImportTests.test_resolve @ linux-x86_64 +test.test_importlib.test_main.ImportTests.test_resolve_without_attr @ linux-x86_64 +test.test_importlib.test_main.MissingSysPath.test_discovery @ linux-x86_64 +test.test_importlib.test_main.NameNormalizationTests.test_dashes_in_dist_name_found_as_underscores @ linux-x86_64 +test.test_importlib.test_main.NameNormalizationTests.test_dist_name_found_as_any_case @ linux-x86_64 +test.test_importlib.test_main.NameNormalizationTests.test_unique_distributions @ linux-x86_64 +test.test_importlib.test_main.NonASCIITests.test_metadata_loads @ linux-x86_64 +test.test_importlib.test_main.NonASCIITests.test_metadata_loads_egg_info @ linux-x86_64 +test.test_importlib.test_main.PackagesDistributionsPrebuiltTest.test_packages_distributions_example @ linux-x86_64 +test.test_importlib.test_main.PackagesDistributionsPrebuiltTest.test_packages_distributions_example2 @ linux-x86_64 +test.test_importlib.test_main.PackagesDistributionsTest.test_packages_distributions_neither_toplevel_nor_files @ linux-x86_64 +test.test_importlib.test_main.TestEntryPoints.test_attr @ linux-x86_64 +test.test_importlib.test_main.TestEntryPoints.test_entry_point_pickleable @ linux-x86_64 +test.test_importlib.test_main.TestEntryPoints.test_hashable @ linux-x86_64 +test.test_importlib.test_main.TestEntryPoints.test_immutable @ linux-x86_64 +test.test_importlib.test_main.TestEntryPoints.test_json_dump @ linux-x86_64 +test.test_importlib.test_main.TestEntryPoints.test_module @ linux-x86_64 +test.test_importlib.test_main.TestEntryPoints.test_positional_args @ linux-x86_64 +test.test_importlib.test_main.TestEntryPoints.test_repr @ linux-x86_64 +test.test_importlib.test_main.TestEntryPoints.test_sortable @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_as_json @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_as_json_egg_info @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_as_json_odd_case @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_entry_points @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_entry_points_allows_no_attributes @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_entry_points_by_index @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_entry_points_dict_construction @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_entry_points_distribution @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_entry_points_groups_get @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_entry_points_groups_getitem @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_entry_points_missing_group @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_entry_points_missing_name @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_entry_points_unique_packages_normalized @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_file_hash_repr @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_files_dist_info @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_files_egg_info @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_for_name_does_not_exist @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_for_top_level @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_metadata_for_this_package @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_more_complex_deps_requires_text @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_name_normalization @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_prefix_not_matched @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_read_text @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_requires_dist_info @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_requires_egg_info @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_requires_egg_info_empty @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_requires_egg_info_file @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_retrieves_version_of_distinfo_pkg @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_retrieves_version_of_self @ linux-x86_64 +test.test_importlib.test_metadata_api.APITests.test_version_egg_info_file @ linux-x86_64 +test.test_importlib.test_metadata_api.InvalidateCache.test_invalidate_cache @ linux-x86_64 +test.test_importlib.test_metadata_api.LegacyDots.test_name_normalization @ linux-x86_64 +test.test_importlib.test_metadata_api.LegacyDots.test_name_normalization_versionless_egg_info @ linux-x86_64 +test.test_importlib.test_metadata_api.OffSysPathTests.test_distribution_at_pathlib @ linux-x86_64 +test.test_importlib.test_metadata_api.OffSysPathTests.test_distribution_at_str @ linux-x86_64 +test.test_importlib.test_metadata_api.OffSysPathTests.test_find_distributions_specified_path @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.CombinedNamespacePackages.test_imports @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.DynamicPathCalculation.test_project3_fails @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.DynamicPathCalculation.test_project3_succeeds @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.DynamicPathNamespacePackage.test_dynamic_path @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.LegacySupport.test_non_namespace_package_takes_precedence @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.LoaderTests.test_loader_abc @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.LoaderTests.test_namespace_loader_consistency @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.LoaderTests.test_namespace_origin_consistency @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.LoaderTests.test_path_indexable @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.ModuleAndNamespacePackageInSameDir.test_module_before_namespace_package @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.ReloadTests.test_cant_import_other @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.ReloadTests.test_dynamic_path @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.ReloadTests.test_simple_package @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.SeparatedNamespacePackages.test_imports @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.SeparatedNamespacePackagesCreatedWhileRunning.test_invalidate_caches @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.SeparatedNestedZipNamespacePackages.test_imports @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.SeparatedOverlappingNamespacePackages.test_first_path_wins @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.SeparatedOverlappingNamespacePackages.test_first_path_wins_again @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.SeparatedOverlappingNamespacePackages.test_first_path_wins_importing_second_first @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.SeparatedZipNamespacePackages.test_imports @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.SingleNamespacePackage.test_cant_import_other @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.SingleNamespacePackage.test_module_repr @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.SingleNamespacePackage.test_simple_package @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.SingleNestedZipNamespacePackage.test_cant_import_other @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.SingleNestedZipNamespacePackage.test_simple_package @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.SingleZipNamespacePackage.test_cant_import_other @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.SingleZipNamespacePackage.test_simple_package @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.ZipWithMissingDirectory.test_missing_directory @ linux-x86_64 +test.test_importlib.test_namespace_pkgs.ZipWithMissingDirectory.test_present_directory @ linux-x86_64 +test.test_importlib.test_open.CommonBinaryTests.test_extant_path @ linux-x86_64 +test.test_importlib.test_open.CommonBinaryTests.test_importing_module_as_side_effect @ linux-x86_64 +test.test_importlib.test_open.CommonBinaryTests.test_missing_path @ linux-x86_64 +test.test_importlib.test_open.CommonBinaryTests.test_non_package_by_name @ linux-x86_64 +test.test_importlib.test_open.CommonBinaryTests.test_non_package_by_package @ linux-x86_64 +test.test_importlib.test_open.CommonBinaryTests.test_package_name @ linux-x86_64 +test.test_importlib.test_open.CommonBinaryTests.test_package_object @ linux-x86_64 +test.test_importlib.test_open.CommonBinaryTests.test_pathlib_path @ linux-x86_64 +test.test_importlib.test_open.CommonBinaryTests.test_string_path @ linux-x86_64 +test.test_importlib.test_open.CommonBinaryTests.test_useless_loader @ linux-x86_64 +test.test_importlib.test_open.CommonTextTests.test_extant_path @ linux-x86_64 +test.test_importlib.test_open.CommonTextTests.test_importing_module_as_side_effect @ linux-x86_64 +test.test_importlib.test_open.CommonTextTests.test_missing_path @ linux-x86_64 +test.test_importlib.test_open.CommonTextTests.test_non_package_by_name @ linux-x86_64 +test.test_importlib.test_open.CommonTextTests.test_non_package_by_package @ linux-x86_64 +test.test_importlib.test_open.CommonTextTests.test_package_name @ linux-x86_64 +test.test_importlib.test_open.CommonTextTests.test_package_object @ linux-x86_64 +test.test_importlib.test_open.CommonTextTests.test_pathlib_path @ linux-x86_64 +test.test_importlib.test_open.CommonTextTests.test_string_path @ linux-x86_64 +test.test_importlib.test_open.CommonTextTests.test_useless_loader @ linux-x86_64 +test.test_importlib.test_open.OpenDiskNamespaceTests.test_open_binary @ linux-x86_64 +test.test_importlib.test_open.OpenDiskNamespaceTests.test_open_binary_FileNotFoundError @ linux-x86_64 +test.test_importlib.test_open.OpenDiskNamespaceTests.test_open_text_FileNotFoundError @ linux-x86_64 +test.test_importlib.test_open.OpenDiskNamespaceTests.test_open_text_default_encoding @ linux-x86_64 +test.test_importlib.test_open.OpenDiskNamespaceTests.test_open_text_given_encoding @ linux-x86_64 +test.test_importlib.test_open.OpenDiskNamespaceTests.test_open_text_with_errors @ linux-x86_64 +test.test_importlib.test_open.OpenDiskTests.test_open_binary @ linux-x86_64 +test.test_importlib.test_open.OpenDiskTests.test_open_binary_FileNotFoundError @ linux-x86_64 +test.test_importlib.test_open.OpenDiskTests.test_open_text_FileNotFoundError @ linux-x86_64 +test.test_importlib.test_open.OpenDiskTests.test_open_text_default_encoding @ linux-x86_64 +test.test_importlib.test_open.OpenDiskTests.test_open_text_given_encoding @ linux-x86_64 +test.test_importlib.test_open.OpenDiskTests.test_open_text_with_errors @ linux-x86_64 +test.test_importlib.test_open.OpenZipTests.test_open_binary @ linux-x86_64 +test.test_importlib.test_open.OpenZipTests.test_open_binary_FileNotFoundError @ linux-x86_64 +test.test_importlib.test_open.OpenZipTests.test_open_text_FileNotFoundError @ linux-x86_64 +test.test_importlib.test_open.OpenZipTests.test_open_text_default_encoding @ linux-x86_64 +test.test_importlib.test_open.OpenZipTests.test_open_text_given_encoding @ linux-x86_64 +test.test_importlib.test_open.OpenZipTests.test_open_text_with_errors @ linux-x86_64 +test.test_importlib.test_path.CommonTests.test_extant_path @ linux-x86_64 +test.test_importlib.test_path.CommonTests.test_importing_module_as_side_effect @ linux-x86_64 +test.test_importlib.test_path.CommonTests.test_missing_path @ linux-x86_64 +test.test_importlib.test_path.CommonTests.test_non_package_by_name @ linux-x86_64 +test.test_importlib.test_path.CommonTests.test_non_package_by_package @ linux-x86_64 +test.test_importlib.test_path.CommonTests.test_package_name @ linux-x86_64 +test.test_importlib.test_path.CommonTests.test_package_object @ linux-x86_64 +test.test_importlib.test_path.CommonTests.test_pathlib_path @ linux-x86_64 +test.test_importlib.test_path.CommonTests.test_string_path @ linux-x86_64 +test.test_importlib.test_path.CommonTests.test_useless_loader @ linux-x86_64 +test.test_importlib.test_path.PathDiskTests.test_natural_path @ linux-x86_64 +test.test_importlib.test_path.PathDiskTests.test_reading @ linux-x86_64 +test.test_importlib.test_path.PathMemoryTests.test_reading @ linux-x86_64 +test.test_importlib.test_path.PathZipTests.test_reading @ linux-x86_64 +test.test_importlib.test_path.PathZipTests.test_remove_in_context_manager @ linux-x86_64 +test.test_importlib.test_pkg_import.TestImport.test_package_import__semantics @ linux-x86_64 +test.test_importlib.test_read.CommonBinaryTests.test_extant_path @ linux-x86_64 +test.test_importlib.test_read.CommonBinaryTests.test_importing_module_as_side_effect @ linux-x86_64 +test.test_importlib.test_read.CommonBinaryTests.test_missing_path @ linux-x86_64 +test.test_importlib.test_read.CommonBinaryTests.test_non_package_by_name @ linux-x86_64 +test.test_importlib.test_read.CommonBinaryTests.test_non_package_by_package @ linux-x86_64 +test.test_importlib.test_read.CommonBinaryTests.test_package_name @ linux-x86_64 +test.test_importlib.test_read.CommonBinaryTests.test_package_object @ linux-x86_64 +test.test_importlib.test_read.CommonBinaryTests.test_pathlib_path @ linux-x86_64 +test.test_importlib.test_read.CommonBinaryTests.test_string_path @ linux-x86_64 +test.test_importlib.test_read.CommonBinaryTests.test_useless_loader @ linux-x86_64 +test.test_importlib.test_read.CommonTextTests.test_extant_path @ linux-x86_64 +test.test_importlib.test_read.CommonTextTests.test_importing_module_as_side_effect @ linux-x86_64 +test.test_importlib.test_read.CommonTextTests.test_missing_path @ linux-x86_64 +test.test_importlib.test_read.CommonTextTests.test_non_package_by_name @ linux-x86_64 +test.test_importlib.test_read.CommonTextTests.test_non_package_by_package @ linux-x86_64 +test.test_importlib.test_read.CommonTextTests.test_package_name @ linux-x86_64 +test.test_importlib.test_read.CommonTextTests.test_package_object @ linux-x86_64 +test.test_importlib.test_read.CommonTextTests.test_pathlib_path @ linux-x86_64 +test.test_importlib.test_read.CommonTextTests.test_string_path @ linux-x86_64 +test.test_importlib.test_read.CommonTextTests.test_useless_loader @ linux-x86_64 +test.test_importlib.test_read.ReadDiskTests.test_read_bytes @ linux-x86_64 +test.test_importlib.test_read.ReadDiskTests.test_read_text_default_encoding @ linux-x86_64 +test.test_importlib.test_read.ReadDiskTests.test_read_text_given_encoding @ linux-x86_64 +test.test_importlib.test_read.ReadDiskTests.test_read_text_with_errors @ linux-x86_64 +test.test_importlib.test_read.ReadNamespaceTests.test_read_bytes @ linux-x86_64 +test.test_importlib.test_read.ReadNamespaceTests.test_read_text_default_encoding @ linux-x86_64 +test.test_importlib.test_read.ReadNamespaceTests.test_read_text_given_encoding @ linux-x86_64 +test.test_importlib.test_read.ReadNamespaceTests.test_read_text_with_errors @ linux-x86_64 +test.test_importlib.test_read.ReadZipTests.test_read_bytes @ linux-x86_64 +test.test_importlib.test_read.ReadZipTests.test_read_submodule_resource @ linux-x86_64 +test.test_importlib.test_read.ReadZipTests.test_read_submodule_resource_by_name @ linux-x86_64 +test.test_importlib.test_read.ReadZipTests.test_read_text_default_encoding @ linux-x86_64 +test.test_importlib.test_read.ReadZipTests.test_read_text_given_encoding @ linux-x86_64 +test.test_importlib.test_read.ReadZipTests.test_read_text_with_errors @ linux-x86_64 +test.test_importlib.test_reader.MultiplexedPathTest.test_init_file @ linux-x86_64 +test.test_importlib.test_reader.MultiplexedPathTest.test_init_no_paths @ linux-x86_64 +test.test_importlib.test_reader.MultiplexedPathTest.test_is_dir @ linux-x86_64 +test.test_importlib.test_reader.MultiplexedPathTest.test_is_file @ linux-x86_64 +test.test_importlib.test_reader.MultiplexedPathTest.test_iterdir @ linux-x86_64 +test.test_importlib.test_reader.MultiplexedPathTest.test_iterdir_duplicate @ linux-x86_64 +test.test_importlib.test_reader.MultiplexedPathTest.test_join_path @ linux-x86_64 +test.test_importlib.test_reader.MultiplexedPathTest.test_name @ linux-x86_64 +test.test_importlib.test_reader.MultiplexedPathTest.test_open_file @ linux-x86_64 +test.test_importlib.test_reader.MultiplexedPathTest.test_repr @ linux-x86_64 +test.test_importlib.test_reader.NamespaceReaderTest.test_files @ linux-x86_64 +test.test_importlib.test_reader.NamespaceReaderTest.test_init_error @ linux-x86_64 +test.test_importlib.test_reader.NamespaceReaderTest.test_resource_path @ linux-x86_64 +test.test_importlib.test_resource.DeletingZipsTest.test_entered_path_does_not_keep_open @ linux-x86_64 +test.test_importlib.test_resource.DeletingZipsTest.test_is_file_does_not_keep_open @ linux-x86_64 +test.test_importlib.test_resource.DeletingZipsTest.test_is_file_failure_does_not_keep_open @ linux-x86_64 +test.test_importlib.test_resource.DeletingZipsTest.test_iterdir_does_not_keep_open @ linux-x86_64 +test.test_importlib.test_resource.DeletingZipsTest.test_read_binary_does_not_keep_open @ linux-x86_64 +test.test_importlib.test_resource.DeletingZipsTest.test_read_text_does_not_keep_open @ linux-x86_64 +test.test_importlib.test_resource.ResourceCornerCaseTests.test_package_has_no_reader_fallback @ linux-x86_64 +test.test_importlib.test_resource.ResourceDiskTests.test_is_dir @ linux-x86_64 +test.test_importlib.test_resource.ResourceDiskTests.test_is_file_exists @ linux-x86_64 +test.test_importlib.test_resource.ResourceDiskTests.test_is_file_missing @ linux-x86_64 +test.test_importlib.test_resource.ResourceFromNamespaceTest01.test_is_submodule_resource @ linux-x86_64 +test.test_importlib.test_resource.ResourceFromNamespaceTest01.test_read_submodule_resource_by_name @ linux-x86_64 +test.test_importlib.test_resource.ResourceFromNamespaceTest01.test_submodule_contents @ linux-x86_64 +test.test_importlib.test_resource.ResourceFromNamespaceTest01.test_submodule_contents_by_name @ linux-x86_64 +test.test_importlib.test_resource.ResourceFromZipsTest01.test_is_submodule_resource @ linux-x86_64 +test.test_importlib.test_resource.ResourceFromZipsTest01.test_read_submodule_resource_by_name @ linux-x86_64 +test.test_importlib.test_resource.ResourceFromZipsTest01.test_submodule_contents @ linux-x86_64 +test.test_importlib.test_resource.ResourceFromZipsTest01.test_submodule_contents_by_name @ linux-x86_64 +test.test_importlib.test_resource.ResourceFromZipsTest02.test_unrelated_contents @ linux-x86_64 +test.test_importlib.test_resource.ResourceLoaderTests.test_is_dir @ linux-x86_64 +test.test_importlib.test_resource.ResourceLoaderTests.test_is_file @ linux-x86_64 +test.test_importlib.test_resource.ResourceLoaderTests.test_resource_contents @ linux-x86_64 +test.test_importlib.test_resource.ResourceLoaderTests.test_resource_missing @ linux-x86_64 +test.test_importlib.test_resource.ResourceZipTests.test_is_dir @ linux-x86_64 +test.test_importlib.test_resource.ResourceZipTests.test_is_file_exists @ linux-x86_64 +test.test_importlib.test_resource.ResourceZipTests.test_is_file_missing @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_file_location_default @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_file_location_default_bad_suffix @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_file_location_default_without_location @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_file_location_loader_no_location @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_file_location_loader_no_location_bad_get_filename @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_file_location_loader_no_location_no_get_filename @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_file_location_path_like_arg @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_file_location_relative_path @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_file_location_smsl_default @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_file_location_smsl_default_bad_is_package @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_file_location_smsl_default_no_is_package @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_file_location_smsl_default_not_package @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_file_location_smsl_empty @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_file_location_smsl_none @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_file_location_smsl_not_empty @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_loader_default @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_loader_default_with_bad_is_package @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_loader_default_with_file_loader @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_loader_is_package_false @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_loader_is_package_false_with_fileloader @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_loader_is_package_true @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_loader_is_package_true_with_fileloader @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_loader_is_package_with_loader_false @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_loader_is_package_with_loader_true @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_loader_origin @ linux-x86_64 +test.test_importlib.test_spec.Frozen_FactoryTests.test_spec_from_loader_origin_and_is_package @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleReprTests.test_module___loader___module_repr @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleReprTests.test_module___loader___module_repr_bad @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleReprTests.test_module___spec__ @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleReprTests.test_module___spec___location @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleReprTests.test_module___spec___no_origin @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleReprTests.test_module___spec___no_origin_no_loader @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleReprTests.test_module_no_file @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleReprTests.test_module_no_file_no_loader @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleReprTests.test_module_no_name @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleReprTests.test_module_with_file @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecMethodsTests.test_exec @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecMethodsTests.test_load @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecMethodsTests.test_load_failed @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecMethodsTests.test_load_failed_removed @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecMethodsTests.test_load_legacy @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecMethodsTests.test_load_legacy_attributes @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecMethodsTests.test_load_legacy_attributes_immutable @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecMethodsTests.test_load_replaced @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecMethodsTests.test_reload @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecMethodsTests.test_reload_extra_attributes @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecMethodsTests.test_reload_init_module_attrs @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecMethodsTests.test_reload_legacy @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecMethodsTests.test_reload_modified @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_cached_no_origin @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_cached_set @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_cached_source @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_cached_source_missing_cache_tag @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_cached_source_unknown_suffix @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_cached_sourceless @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_cached_with_origin_not_location @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_default @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_default_is_package_false @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_default_is_package_true @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_default_no_loader @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_equality @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_equality_location @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_has_location_setter @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_inequality @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_inequality_incomplete @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_package @ linux-x86_64 +test.test_importlib.test_spec.Frozen_ModuleSpecTests.test_package_is_package @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_file_location_default @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_file_location_default_bad_suffix @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_file_location_default_without_location @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_file_location_loader_no_location @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_file_location_loader_no_location_bad_get_filename @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_file_location_loader_no_location_no_get_filename @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_file_location_path_like_arg @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_file_location_relative_path @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_file_location_smsl_default @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_file_location_smsl_default_bad_is_package @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_file_location_smsl_default_no_is_package @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_file_location_smsl_default_not_package @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_file_location_smsl_empty @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_file_location_smsl_none @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_file_location_smsl_not_empty @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_loader_default @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_loader_default_with_bad_is_package @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_loader_default_with_file_loader @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_loader_is_package_false @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_loader_is_package_false_with_fileloader @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_loader_is_package_true @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_loader_is_package_true_with_fileloader @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_loader_is_package_with_loader_false @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_loader_is_package_with_loader_true @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_loader_origin @ linux-x86_64 +test.test_importlib.test_spec.Source_FactoryTests.test_spec_from_loader_origin_and_is_package @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleReprTests.test_module___loader___module_repr @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleReprTests.test_module___loader___module_repr_bad @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleReprTests.test_module___spec__ @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleReprTests.test_module___spec___location @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleReprTests.test_module___spec___no_origin @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleReprTests.test_module___spec___no_origin_no_loader @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleReprTests.test_module_no_file @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleReprTests.test_module_no_file_no_loader @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleReprTests.test_module_no_name @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleReprTests.test_module_with_file @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecMethodsTests.test_exec @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecMethodsTests.test_load @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecMethodsTests.test_load_failed @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecMethodsTests.test_load_failed_removed @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecMethodsTests.test_load_legacy @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecMethodsTests.test_load_legacy_attributes @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecMethodsTests.test_load_legacy_attributes_immutable @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecMethodsTests.test_load_replaced @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecMethodsTests.test_reload @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecMethodsTests.test_reload_extra_attributes @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecMethodsTests.test_reload_init_module_attrs @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecMethodsTests.test_reload_legacy @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecMethodsTests.test_reload_modified @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_cached_no_origin @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_cached_set @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_cached_source @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_cached_source_missing_cache_tag @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_cached_source_unknown_suffix @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_cached_sourceless @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_cached_with_origin_not_location @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_default @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_default_is_package_false @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_default_is_package_true @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_default_no_loader @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_equality @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_equality_location @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_has_location_setter @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_inequality @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_inequality_incomplete @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_package @ linux-x86_64 +test.test_importlib.test_spec.Source_ModuleSpecTests.test_package_is_package @ linux-x86_64 +test.test_importlib.test_threaded_import.ThreadedImportTests.test_circular_imports @ linux-x86_64 +test.test_importlib.test_threaded_import.ThreadedImportTests.test_concurrent_futures_circular_import @ linux-x86_64 +test.test_importlib.test_threaded_import.ThreadedImportTests.test_import_hangers @ linux-x86_64 +test.test_importlib.test_threaded_import.ThreadedImportTests.test_multiprocessing_pool_circular_import @ linux-x86_64 +test.test_importlib.test_threaded_import.ThreadedImportTests.test_parallel_meta_path @ linux-x86_64 +test.test_importlib.test_threaded_import.ThreadedImportTests.test_parallel_module_init @ linux-x86_64 +test.test_importlib.test_threaded_import.ThreadedImportTests.test_parallel_path_hooks @ linux-x86_64 +test.test_importlib.test_threaded_import.ThreadedImportTests.test_side_effect_import @ linux-x86_64 +test.test_importlib.test_util.Frozen_DecodeSourceBytesTests.test_specified_encoding @ linux-x86_64 +test.test_importlib.test_util.Frozen_DecodeSourceBytesTests.test_universal_newlines @ linux-x86_64 +test.test_importlib.test_util.Frozen_DecodeSourceBytesTests.test_ut8_default @ linux-x86_64 +test.test_importlib.test_util.Frozen_FindSpecTests.test_find_relative_module @ linux-x86_64 +test.test_importlib.test_util.Frozen_FindSpecTests.test_find_relative_module_missing_package @ linux-x86_64 +test.test_importlib.test_util.Frozen_FindSpecTests.test_find_submodule @ linux-x86_64 +test.test_importlib.test_util.Frozen_FindSpecTests.test_find_submodule_in_module @ linux-x86_64 +test.test_importlib.test_util.Frozen_FindSpecTests.test_find_submodule_parent_already_imported @ linux-x86_64 +test.test_importlib.test_util.Frozen_FindSpecTests.test_nothing @ linux-x86_64 +test.test_importlib.test_util.Frozen_FindSpecTests.test_success @ linux-x86_64 +test.test_importlib.test_util.Frozen_FindSpecTests.test_sys_modules @ linux-x86_64 +test.test_importlib.test_util.Frozen_FindSpecTests.test_sys_modules_loader_is_None @ linux-x86_64 +test.test_importlib.test_util.Frozen_FindSpecTests.test_sys_modules_spec_is_None @ linux-x86_64 +test.test_importlib.test_util.Frozen_FindSpecTests.test_sys_modules_spec_is_not_set @ linux-x86_64 +test.test_importlib.test_util.Frozen_FindSpecTests.test_sys_modules_without___loader__ @ linux-x86_64 +test.test_importlib.test_util.Frozen_MagicNumberTests.test_incorporates_rn @ linux-x86_64 +test.test_importlib.test_util.Frozen_MagicNumberTests.test_length @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleForLoaderTests.test_attributes_set @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleForLoaderTests.test_decorator_attrs @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleForLoaderTests.test_false_module @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleForLoaderTests.test_new_module @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleForLoaderTests.test_new_module_failure @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleForLoaderTests.test_reload @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleForLoaderTests.test_reload_failure @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleForLoaderTests.test_warning @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleFromSpecTests.test___cached__ @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleFromSpecTests.test___file__ @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleFromSpecTests.test___loader__ @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleFromSpecTests.test___name__ @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleFromSpecTests.test___package__ @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleFromSpecTests.test___path__ @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleFromSpecTests.test___spec__ @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleFromSpecTests.test_create_module @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleFromSpecTests.test_create_module_returns_None @ linux-x86_64 +test.test_importlib.test_util.Frozen_ModuleFromSpecTests.test_no_create_module @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_cache_from_source @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_cache_from_source_cwd @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_cache_from_source_debug_override @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_cache_from_source_debug_override_optimization_both_set @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_cache_from_source_no_cache_tag @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_cache_from_source_no_dot @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_cache_from_source_optimization_None @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_cache_from_source_optimization_empty_string @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_cache_from_source_optimization_set @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_cache_from_source_override @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_cache_from_source_path_like_arg @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_cache_from_source_respects_pycache_prefix @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_cache_from_source_respects_pycache_prefix_relative @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_source_from_cache @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_source_from_cache_bad_path @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_source_from_cache_inside_pycache_prefix @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_source_from_cache_missing_optimization @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_source_from_cache_no__pycache__ @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_source_from_cache_no_cache_tag @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_source_from_cache_no_slash @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_source_from_cache_not_opt @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_source_from_cache_optimized_bytecode @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_source_from_cache_outside_pycache_prefix @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_source_from_cache_path_like_arg @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_source_from_cache_too_few_dots @ linux-x86_64 +test.test_importlib.test_util.Frozen_PEP3147Tests.test_source_from_cache_too_many_dots @ linux-x86_64 +test.test_importlib.test_util.Frozen_ResolveNameTests.test_absolute @ linux-x86_64 +test.test_importlib.test_util.Frozen_ResolveNameTests.test_absolute_within_package @ linux-x86_64 +test.test_importlib.test_util.Frozen_ResolveNameTests.test_escape @ linux-x86_64 +test.test_importlib.test_util.Frozen_ResolveNameTests.test_in_package @ linux-x86_64 +test.test_importlib.test_util.Frozen_ResolveNameTests.test_no_package @ linux-x86_64 +test.test_importlib.test_util.Frozen_ResolveNameTests.test_other_package @ linux-x86_64 +test.test_importlib.test_util.Frozen_SetLoaderTests.test_attribute_is_None @ linux-x86_64 +test.test_importlib.test_util.Frozen_SetLoaderTests.test_no_attribute @ linux-x86_64 +test.test_importlib.test_util.Frozen_SetLoaderTests.test_not_reset @ linux-x86_64 +test.test_importlib.test_util.Frozen_SetPackageTests.test_decorator_attrs @ linux-x86_64 +test.test_importlib.test_util.Frozen_SetPackageTests.test_leaving_alone @ linux-x86_64 +test.test_importlib.test_util.Frozen_SetPackageTests.test_package @ linux-x86_64 +test.test_importlib.test_util.Frozen_SetPackageTests.test_setting_if_missing @ linux-x86_64 +test.test_importlib.test_util.Frozen_SetPackageTests.test_submodule @ linux-x86_64 +test.test_importlib.test_util.Frozen_SetPackageTests.test_top_level @ linux-x86_64 +test.test_importlib.test_util.Source_DecodeSourceBytesTests.test_specified_encoding @ linux-x86_64 +test.test_importlib.test_util.Source_DecodeSourceBytesTests.test_universal_newlines @ linux-x86_64 +test.test_importlib.test_util.Source_DecodeSourceBytesTests.test_ut8_default @ linux-x86_64 +test.test_importlib.test_util.Source_FindSpecTests.test_find_relative_module @ linux-x86_64 +test.test_importlib.test_util.Source_FindSpecTests.test_find_relative_module_missing_package @ linux-x86_64 +test.test_importlib.test_util.Source_FindSpecTests.test_find_submodule @ linux-x86_64 +test.test_importlib.test_util.Source_FindSpecTests.test_find_submodule_in_module @ linux-x86_64 +test.test_importlib.test_util.Source_FindSpecTests.test_find_submodule_parent_already_imported @ linux-x86_64 +test.test_importlib.test_util.Source_FindSpecTests.test_nothing @ linux-x86_64 +test.test_importlib.test_util.Source_FindSpecTests.test_success @ linux-x86_64 +test.test_importlib.test_util.Source_FindSpecTests.test_sys_modules @ linux-x86_64 +test.test_importlib.test_util.Source_FindSpecTests.test_sys_modules_loader_is_None @ linux-x86_64 +test.test_importlib.test_util.Source_FindSpecTests.test_sys_modules_spec_is_None @ linux-x86_64 +test.test_importlib.test_util.Source_FindSpecTests.test_sys_modules_spec_is_not_set @ linux-x86_64 +test.test_importlib.test_util.Source_FindSpecTests.test_sys_modules_without___loader__ @ linux-x86_64 +test.test_importlib.test_util.Source_MagicNumberTests.test_incorporates_rn @ linux-x86_64 +test.test_importlib.test_util.Source_MagicNumberTests.test_length @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleForLoaderTests.test_attributes_set @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleForLoaderTests.test_decorator_attrs @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleForLoaderTests.test_false_module @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleForLoaderTests.test_new_module @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleForLoaderTests.test_new_module_failure @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleForLoaderTests.test_reload @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleForLoaderTests.test_reload_failure @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleForLoaderTests.test_warning @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleFromSpecTests.test___cached__ @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleFromSpecTests.test___file__ @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleFromSpecTests.test___loader__ @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleFromSpecTests.test___name__ @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleFromSpecTests.test___package__ @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleFromSpecTests.test___path__ @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleFromSpecTests.test___spec__ @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleFromSpecTests.test_create_module @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleFromSpecTests.test_create_module_returns_None @ linux-x86_64 +test.test_importlib.test_util.Source_ModuleFromSpecTests.test_no_create_module @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_cache_from_source @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_cache_from_source_cwd @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_cache_from_source_debug_override @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_cache_from_source_debug_override_optimization_both_set @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_cache_from_source_no_cache_tag @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_cache_from_source_no_dot @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_cache_from_source_optimization_None @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_cache_from_source_optimization_empty_string @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_cache_from_source_optimization_set @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_cache_from_source_override @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_cache_from_source_path_like_arg @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_cache_from_source_respects_pycache_prefix @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_cache_from_source_respects_pycache_prefix_relative @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_source_from_cache @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_source_from_cache_bad_path @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_source_from_cache_inside_pycache_prefix @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_source_from_cache_missing_optimization @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_source_from_cache_no__pycache__ @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_source_from_cache_no_cache_tag @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_source_from_cache_no_slash @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_source_from_cache_not_opt @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_source_from_cache_optimized_bytecode @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_source_from_cache_outside_pycache_prefix @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_source_from_cache_path_like_arg @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_source_from_cache_too_few_dots @ linux-x86_64 +test.test_importlib.test_util.Source_PEP3147Tests.test_source_from_cache_too_many_dots @ linux-x86_64 +test.test_importlib.test_util.Source_ResolveNameTests.test_absolute @ linux-x86_64 +test.test_importlib.test_util.Source_ResolveNameTests.test_absolute_within_package @ linux-x86_64 +test.test_importlib.test_util.Source_ResolveNameTests.test_escape @ linux-x86_64 +test.test_importlib.test_util.Source_ResolveNameTests.test_in_package @ linux-x86_64 +test.test_importlib.test_util.Source_ResolveNameTests.test_no_package @ linux-x86_64 +test.test_importlib.test_util.Source_ResolveNameTests.test_other_package @ linux-x86_64 +test.test_importlib.test_util.Source_SetLoaderTests.test_attribute_is_None @ linux-x86_64 +test.test_importlib.test_util.Source_SetLoaderTests.test_no_attribute @ linux-x86_64 +test.test_importlib.test_util.Source_SetLoaderTests.test_not_reset @ linux-x86_64 +test.test_importlib.test_util.Source_SetPackageTests.test_decorator_attrs @ linux-x86_64 +test.test_importlib.test_util.Source_SetPackageTests.test_leaving_alone @ linux-x86_64 +test.test_importlib.test_util.Source_SetPackageTests.test_package @ linux-x86_64 +test.test_importlib.test_util.Source_SetPackageTests.test_setting_if_missing @ linux-x86_64 +test.test_importlib.test_util.Source_SetPackageTests.test_submodule @ linux-x86_64 +test.test_importlib.test_util.Source_SetPackageTests.test_top_level @ linux-x86_64 +test.test_importlib.test_zip.TestEgg.test_case_insensitive @ linux-x86_64 +test.test_importlib.test_zip.TestEgg.test_files @ linux-x86_64 +test.test_importlib.test_zip.TestEgg.test_missing_metadata @ linux-x86_64 +test.test_importlib.test_zip.TestEgg.test_normalized_name @ linux-x86_64 +test.test_importlib.test_zip.TestEgg.test_one_distribution @ linux-x86_64 +test.test_importlib.test_zip.TestEgg.test_zip_entry_points @ linux-x86_64 +test.test_importlib.test_zip.TestEgg.test_zip_version @ linux-x86_64 +test.test_importlib.test_zip.TestEgg.test_zip_version_does_not_match @ linux-x86_64 +test.test_importlib.test_zip.TestZip.test_case_insensitive @ linux-x86_64 +test.test_importlib.test_zip.TestZip.test_files @ linux-x86_64 +test.test_importlib.test_zip.TestZip.test_missing_metadata @ linux-x86_64 +test.test_importlib.test_zip.TestZip.test_one_distribution @ linux-x86_64 +test.test_importlib.test_zip.TestZip.test_zip_entry_points @ linux-x86_64 +test.test_importlib.test_zip.TestZip.test_zip_version @ linux-x86_64 +test.test_importlib.test_zip.TestZip.test_zip_version_does_not_match @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_index.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_index.txt new file mode 100644 index 0000000000..b12815a266 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_index.txt @@ -0,0 +1,55 @@ +test.test_index.BaseTestCase.test_basic @ linux-x86_64 +test.test_index.BaseTestCase.test_error @ linux-x86_64 +test.test_index.BaseTestCase.test_index_returns_int_subclass @ linux-x86_64 +test.test_index.BaseTestCase.test_int_subclass_with_index @ linux-x86_64 +test.test_index.BaseTestCase.test_slice @ linux-x86_64 +test.test_index.BaseTestCase.test_subclasses @ linux-x86_64 +test.test_index.BaseTestCase.test_wrappers @ linux-x86_64 +test.test_index.ByteArrayTestCase.test_error @ linux-x86_64 +test.test_index.ByteArrayTestCase.test_index @ linux-x86_64 +test.test_index.ByteArrayTestCase.test_repeat @ linux-x86_64 +test.test_index.ByteArrayTestCase.test_slice @ linux-x86_64 +test.test_index.ByteArrayTestCase.test_slice_bug7532 @ linux-x86_64 +test.test_index.ByteArrayTestCase.test_subclasses @ linux-x86_64 +test.test_index.ByteArrayTestCase.test_wrappers @ linux-x86_64 +test.test_index.BytesTestCase.test_error @ linux-x86_64 +test.test_index.BytesTestCase.test_index @ linux-x86_64 +test.test_index.BytesTestCase.test_repeat @ linux-x86_64 +test.test_index.BytesTestCase.test_slice @ linux-x86_64 +test.test_index.BytesTestCase.test_slice_bug7532 @ linux-x86_64 +test.test_index.BytesTestCase.test_subclasses @ linux-x86_64 +test.test_index.BytesTestCase.test_wrappers @ linux-x86_64 +test.test_index.ListTestCase.test_error @ linux-x86_64 +test.test_index.ListTestCase.test_index @ linux-x86_64 +test.test_index.ListTestCase.test_inplace_repeat @ linux-x86_64 +test.test_index.ListTestCase.test_repeat @ linux-x86_64 +test.test_index.ListTestCase.test_setdelitem @ linux-x86_64 +test.test_index.ListTestCase.test_slice @ linux-x86_64 +test.test_index.ListTestCase.test_slice_bug7532 @ linux-x86_64 +test.test_index.ListTestCase.test_subclasses @ linux-x86_64 +test.test_index.ListTestCase.test_wrappers @ linux-x86_64 +test.test_index.NewSeqTestCase.test_error @ linux-x86_64 +test.test_index.NewSeqTestCase.test_index @ linux-x86_64 +test.test_index.NewSeqTestCase.test_repeat @ linux-x86_64 +test.test_index.NewSeqTestCase.test_slice @ linux-x86_64 +test.test_index.NewSeqTestCase.test_slice_bug7532 @ linux-x86_64 +test.test_index.NewSeqTestCase.test_subclasses @ linux-x86_64 +test.test_index.NewSeqTestCase.test_wrappers @ linux-x86_64 +test.test_index.OverflowTestCase.test_getitem @ linux-x86_64 +test.test_index.OverflowTestCase.test_large_longs @ linux-x86_64 +test.test_index.OverflowTestCase.test_sequence_repeat @ linux-x86_64 +test.test_index.RangeTestCase.test_range @ linux-x86_64 +test.test_index.StringTestCase.test_error @ linux-x86_64 +test.test_index.StringTestCase.test_index @ linux-x86_64 +test.test_index.StringTestCase.test_repeat @ linux-x86_64 +test.test_index.StringTestCase.test_slice @ linux-x86_64 +test.test_index.StringTestCase.test_slice_bug7532 @ linux-x86_64 +test.test_index.StringTestCase.test_subclasses @ linux-x86_64 +test.test_index.StringTestCase.test_wrappers @ linux-x86_64 +test.test_index.TupleTestCase.test_error @ linux-x86_64 +test.test_index.TupleTestCase.test_index @ linux-x86_64 +test.test_index.TupleTestCase.test_repeat @ linux-x86_64 +test.test_index.TupleTestCase.test_slice @ linux-x86_64 +test.test_index.TupleTestCase.test_slice_bug7532 @ linux-x86_64 +test.test_index.TupleTestCase.test_subclasses @ linux-x86_64 +test.test_index.TupleTestCase.test_wrappers @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_inspect.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_inspect.txt new file mode 100644 index 0000000000..9828c57e4a --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_inspect.txt @@ -0,0 +1,231 @@ +test.test_inspect.test_inspect.IsTestBase.test__all__ @ linux-x86_64 +test.test_inspect.test_inspect.TestBlockComments.test_class_async_method @ linux-x86_64 +test.test_inspect.test_inspect.TestBlockComments.test_class_method @ linux-x86_64 +test.test_inspect.test_inspect.TestBlockComments.test_toplevel_class @ linux-x86_64 +test.test_inspect.test_inspect.TestBoundArguments.test_signature_bound_arguments_apply_defaults @ linux-x86_64 +test.test_inspect.test_inspect.TestBoundArguments.test_signature_bound_arguments_arguments_type @ linux-x86_64 +test.test_inspect.test_inspect.TestBoundArguments.test_signature_bound_arguments_equality @ linux-x86_64 +test.test_inspect.test_inspect.TestBoundArguments.test_signature_bound_arguments_pickle @ linux-x86_64 +test.test_inspect.test_inspect.TestBoundArguments.test_signature_bound_arguments_repr @ linux-x86_64 +test.test_inspect.test_inspect.TestBoundArguments.test_signature_bound_arguments_unhashable @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_class_decorator @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_class_definition_in_multiline_comment @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_class_definition_in_multiline_string_definition @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_class_inside_conditional @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_findsource_code_in_linecache @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_findsource_with_out_of_bounds_lineno @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_findsource_without_filename @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_getsource_on_method @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_method_in_dynamic_class @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_multiline_sig @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_multiple_children_classes @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_nested_class @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_nested_class_definition @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_nested_class_definition_indented_string @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_nested_class_definition_inside_async_function @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_nested_class_definition_inside_function @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_nested_func @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_one_liner_dedent_non_name @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_one_liner_followed_by_non_name @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_with_comment @ linux-x86_64 +test.test_inspect.test_inspect.TestBuggyCases.test_with_comment_instead_of_docstring @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_argspec_api_ignores_wrapped @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_classify_DynamicClassAttribute @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_classify_VirtualAttribute @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_classify_VirtualAttribute_multi_classes @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_classify_builtin_types @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_classify_class_attrs_with_buggy_dir @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_classify_metaclass_class_attribute @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_classify_newstyle @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_classify_overrides_bool @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_get_annotations_with_stock_annotations @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_get_annotations_with_stringized_annotations @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_getfullargspec @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_getfullargspec_definition_order_preserved_on_kwonly @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_getfullargspec_signature_annos @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_getfullargspec_signature_attr @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_getmembers_VirtualAttribute @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_getmembers_descriptors @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_getmembers_method @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_getmembers_static @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_getmembers_with_buggy_dir @ linux-x86_64 +test.test_inspect.test_inspect.TestClassesAndFunctions.test_newstyle_mro @ linux-x86_64 +test.test_inspect.test_inspect.TestDecorators.test_replacing_decorator @ linux-x86_64 +test.test_inspect.test_inspect.TestFormatAnnotation.test_typing_replacement @ linux-x86_64 +test.test_inspect.test_inspect.TestGetClosureVars.test_builtins_as_dict @ linux-x86_64 +test.test_inspect.test_inspect.TestGetClosureVars.test_builtins_as_module @ linux-x86_64 +test.test_inspect.test_inspect.TestGetClosureVars.test_builtins_fallback @ linux-x86_64 +test.test_inspect.test_inspect.TestGetClosureVars.test_generator_closure @ linux-x86_64 +test.test_inspect.test_inspect.TestGetClosureVars.test_getclosurevars_empty @ linux-x86_64 +test.test_inspect.test_inspect.TestGetClosureVars.test_getclosurevars_error @ linux-x86_64 +test.test_inspect.test_inspect.TestGetClosureVars.test_method_closure @ linux-x86_64 +test.test_inspect.test_inspect.TestGetClosureVars.test_name_resolution @ linux-x86_64 +test.test_inspect.test_inspect.TestGetClosureVars.test_nonlocal_vars @ linux-x86_64 +test.test_inspect.test_inspect.TestGetCoroutineState.test_closed_after_immediate_exception @ linux-x86_64 +test.test_inspect.test_inspect.TestGetCoroutineState.test_easy_debugging @ linux-x86_64 +test.test_inspect.test_inspect.TestGetGeneratorState.test_closed_after_exhaustion @ linux-x86_64 +test.test_inspect.test_inspect.TestGetGeneratorState.test_closed_after_immediate_exception @ linux-x86_64 +test.test_inspect.test_inspect.TestGetGeneratorState.test_easy_debugging @ linux-x86_64 +test.test_inspect.test_inspect.TestGetGeneratorState.test_running @ linux-x86_64 +test.test_inspect.test_inspect.TestGetGeneratorState.test_suspended @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_basic @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_classAttribute @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_classVirtualAttribute @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_class_as_property @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_custom___getattr__ @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_custom___getattribute__ @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_custom_object_dict @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_descriptor @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_descriptor_raises_AttributeError @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_dict_as_property @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_inherited @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_inherited_classattribute @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_inherited_slots @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_instance_attr @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_metaclass @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_metaclass_dict_as_property @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_metaclass_with_descriptor @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_metaclass_with_metaclass_with_dict_as_property @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_module @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_mro_as_property @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_no_dict_no_slots @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_no_dict_no_slots_instance_member @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_property @ linux-x86_64 +test.test_inspect.test_inspect.TestGetattrStatic.test_slots @ linux-x86_64 +test.test_inspect.test_inspect.TestGetcallargsFunctions.test_multiple_features @ linux-x86_64 +test.test_inspect.test_inspect.TestGetcallargsFunctions.test_plain @ linux-x86_64 +test.test_inspect.test_inspect.TestGetcallargsFunctions.test_varargs @ linux-x86_64 +test.test_inspect.test_inspect.TestGetcallargsFunctions.test_varkw @ linux-x86_64 +test.test_inspect.test_inspect.TestGetcallargsFunctions.test_varkw_only @ linux-x86_64 +test.test_inspect.test_inspect.TestGetcallargsMethods.test_multiple_features @ linux-x86_64 +test.test_inspect.test_inspect.TestGetcallargsMethods.test_plain @ linux-x86_64 +test.test_inspect.test_inspect.TestGetcallargsMethods.test_varargs @ linux-x86_64 +test.test_inspect.test_inspect.TestGetcallargsMethods.test_varkw @ linux-x86_64 +test.test_inspect.test_inspect.TestGetcallargsMethods.test_varkw_only @ linux-x86_64 +test.test_inspect.test_inspect.TestGetcallargsUnboundMethods.test_multiple_features @ linux-x86_64 +test.test_inspect.test_inspect.TestGetcallargsUnboundMethods.test_plain @ linux-x86_64 +test.test_inspect.test_inspect.TestGetcallargsUnboundMethods.test_varargs @ linux-x86_64 +test.test_inspect.test_inspect.TestGetcallargsUnboundMethods.test_varkw @ linux-x86_64 +test.test_inspect.test_inspect.TestGetcallargsUnboundMethods.test_varkw_only @ linux-x86_64 +test.test_inspect.test_inspect.TestGetsourceInteractive.test_getclasses_interactive @ linux-x86_64 +test.test_inspect.test_inspect.TestGettingSourceOfToplevelFrames.test_range_toplevel_frame @ linux-x86_64 +test.test_inspect.test_inspect.TestGettingSourceOfToplevelFrames.test_range_traceback_toplevel_frame @ linux-x86_64 +test.test_inspect.test_inspect.TestInterpreterStack.test__all__ @ linux-x86_64 +test.test_inspect.test_inspect.TestInterpreterStack.test_abuse_done @ linux-x86_64 +test.test_inspect.test_inspect.TestInterpreterStack.test_frame @ linux-x86_64 +test.test_inspect.test_inspect.TestInterpreterStack.test_previous_frame @ linux-x86_64 +test.test_inspect.test_inspect.TestInterpreterStack.test_stack @ linux-x86_64 +test.test_inspect.test_inspect.TestInterpreterStack.test_trace @ linux-x86_64 +test.test_inspect.test_inspect.TestIsDataDescriptor.test_custom_descriptors @ linux-x86_64 +test.test_inspect.test_inspect.TestIsDataDescriptor.test_functions @ linux-x86_64 +test.test_inspect.test_inspect.TestIsDataDescriptor.test_property @ linux-x86_64 +test.test_inspect.test_inspect.TestIsDataDescriptor.test_slot @ linux-x86_64 +test.test_inspect.test_inspect.TestMain.test_builtins @ linux-x86_64 +test.test_inspect.test_inspect.TestMain.test_custom_getattr @ linux-x86_64 +test.test_inspect.test_inspect.TestMain.test_only_source @ linux-x86_64 +test.test_inspect.test_inspect.TestMain.test_qualname_source @ linux-x86_64 +test.test_inspect.test_inspect.TestNoEOL.test_class @ linux-x86_64 +test.test_inspect.test_inspect.TestOneliners.test_anonymous @ linux-x86_64 +test.test_inspect.test_inspect.TestOneliners.test_lambda_in_list @ linux-x86_64 +test.test_inspect.test_inspect.TestOneliners.test_manyargs @ linux-x86_64 +test.test_inspect.test_inspect.TestOneliners.test_oneline_lambda @ linux-x86_64 +test.test_inspect.test_inspect.TestOneliners.test_onelinefunc @ linux-x86_64 +test.test_inspect.test_inspect.TestOneliners.test_threeline_lambda @ linux-x86_64 +test.test_inspect.test_inspect.TestOneliners.test_twoline_indented_lambda @ linux-x86_64 +test.test_inspect.test_inspect.TestOneliners.test_twolinefunc @ linux-x86_64 +test.test_inspect.test_inspect.TestParameterObject.test_signature_parameter_equality @ linux-x86_64 +test.test_inspect.test_inspect.TestParameterObject.test_signature_parameter_hashable @ linux-x86_64 +test.test_inspect.test_inspect.TestParameterObject.test_signature_parameter_immutability @ linux-x86_64 +test.test_inspect.test_inspect.TestParameterObject.test_signature_parameter_kinds @ linux-x86_64 +test.test_inspect.test_inspect.TestParameterObject.test_signature_parameter_object @ linux-x86_64 +test.test_inspect.test_inspect.TestParameterObject.test_signature_parameter_positional_only @ linux-x86_64 +test.test_inspect.test_inspect.TestParameterObject.test_signature_parameter_replace @ linux-x86_64 +test.test_inspect.test_inspect.TestPredicates.test__all__ @ linux-x86_64 +test.test_inspect.test_inspect.TestPredicates.test_get_slot_members @ linux-x86_64 +test.test_inspect.test_inspect.TestPredicates.test_isabstract @ linux-x86_64 +test.test_inspect.test_inspect.TestPredicates.test_isabstract_during_init_subclass @ linux-x86_64 +test.test_inspect.test_inspect.TestPredicates.test_isclass @ linux-x86_64 +test.test_inspect.test_inspect.TestPredicates.test_isroutine @ linux-x86_64 +test.test_inspect.test_inspect.TestReload.test_getsource_reload @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_cleandoc @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_finddoc @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getclasses @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getcomments @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getdoc_inherited @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getfile @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getfile_broken_repr @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getfile_builtin_class @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getfile_builtin_function_or_method @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getfile_builtin_module @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getframeinfo_get_first_line @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getfunctions @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getmodule @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getmodule_file_not_found @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getmodule_recursion @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getsource @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getsource_on_code_object @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_getsourcefile @ linux-x86_64 +test.test_inspect.test_inspect.TestRetrievingSourceCode.test_proceed_with_fake_filename @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureBind.test_signature_bind_args_and_kwargs @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureBind.test_signature_bind_args_and_varargs @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureBind.test_signature_bind_arguments @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureBind.test_signature_bind_empty @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureBind.test_signature_bind_just_args @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureBind.test_signature_bind_just_kwargs @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureBind.test_signature_bind_kwonly @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureBind.test_signature_bind_positional_only @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureBind.test_signature_bind_posonly_kwargs @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureBind.test_signature_bind_var @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureBind.test_signature_bind_vararg_name @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureBind.test_signature_bind_varargs_order @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureBind.test_signature_bind_with_self_arg @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureDefinitions.test_python_function_override_signature @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signater_parameters_is_ordered @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_annotations_with_local_namespaces @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_definition_order_preserved_on_kwonly @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_equality @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_eval_str @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_from_callable_builtin_obj @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_from_callable_class @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_from_callable_python_obj @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_from_functionlike_object @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_functionlike_class @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_hashable @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_immutability @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_none_annotation @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_object @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_object_pickle @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_callable_objects @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_class @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_classmethod @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_complex_args @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_decorated @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_derived_classes @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_fake_partialmethod @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_generic_subclass @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_lambdas @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_mangled_parameters @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_method @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_mocks @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_noarg @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_non_function @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_noncallable_mocks @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_partial @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_partialmethod @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_staticmethod @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_subclass @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_wargs @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_on_wkwonly @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_replace_anno @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_replaced @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_str @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_str_positional_only @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_without_self @ linux-x86_64 +test.test_inspect.test_inspect.TestSignatureObject.test_signature_wrapped_bound_method @ linux-x86_64 +test.test_inspect.test_inspect.TestSignaturePrivateHelpers.test_signature_strip_non_python_syntax @ linux-x86_64 +test.test_inspect.test_inspect.TestUnwrap.test_cycle @ linux-x86_64 +test.test_inspect.test_inspect.TestUnwrap.test_recursion_limit @ linux-x86_64 +test.test_inspect.test_inspect.TestUnwrap.test_stop @ linux-x86_64 +test.test_inspect.test_inspect.TestUnwrap.test_unhashable @ linux-x86_64 +test.test_inspect.test_inspect.TestUnwrap.test_unwrap_one @ linux-x86_64 +test.test_inspect.test_inspect.TestUnwrap.test_unwrap_several @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_int.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_int.txt new file mode 100644 index 0000000000..a7c86661c0 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_int.txt @@ -0,0 +1,36 @@ +!test.test_int.IntStrDigitLimitsTests.test_denial_of_service_prevented_int_to_str @ linux-x86_64 +test.test_int.IntStrDigitLimitsTests.test_denial_of_service_prevented_str_to_int @ linux-x86_64 +test.test_int.IntStrDigitLimitsTests.test_disabled_limit @ linux-x86_64 +test.test_int.IntStrDigitLimitsTests.test_int_from_other_bases @ linux-x86_64 +test.test_int.IntStrDigitLimitsTests.test_max_str_digits @ linux-x86_64 +test.test_int.IntStrDigitLimitsTests.test_max_str_digits_edge_cases @ linux-x86_64 +test.test_int.IntStrDigitLimitsTests.test_power_of_two_bases_unlimited @ linux-x86_64 +test.test_int.IntStrDigitLimitsTests.test_sign_not_counted @ linux-x86_64 +test.test_int.IntStrDigitLimitsTests.test_underscores_ignored @ linux-x86_64 +!test.test_int.IntSubclassStrDigitLimitsTests.test_denial_of_service_prevented_int_to_str @ linux-x86_64 +test.test_int.IntSubclassStrDigitLimitsTests.test_denial_of_service_prevented_str_to_int @ linux-x86_64 +test.test_int.IntSubclassStrDigitLimitsTests.test_disabled_limit @ linux-x86_64 +test.test_int.IntSubclassStrDigitLimitsTests.test_int_from_other_bases @ linux-x86_64 +test.test_int.IntSubclassStrDigitLimitsTests.test_max_str_digits @ linux-x86_64 +test.test_int.IntSubclassStrDigitLimitsTests.test_max_str_digits_edge_cases @ linux-x86_64 +test.test_int.IntSubclassStrDigitLimitsTests.test_power_of_two_bases_unlimited @ linux-x86_64 +test.test_int.IntSubclassStrDigitLimitsTests.test_sign_not_counted @ linux-x86_64 +test.test_int.IntSubclassStrDigitLimitsTests.test_underscores_ignored @ linux-x86_64 +test.test_int.IntTestCases.test_basic @ linux-x86_64 +test.test_int.IntTestCases.test_error_message @ linux-x86_64 +test.test_int.IntTestCases.test_int_base_bad_types @ linux-x86_64 +test.test_int.IntTestCases.test_int_base_indexable @ linux-x86_64 +test.test_int.IntTestCases.test_int_base_limits @ linux-x86_64 +test.test_int.IntTestCases.test_int_memoryview @ linux-x86_64 +test.test_int.IntTestCases.test_int_returns_int_subclass @ linux-x86_64 +test.test_int.IntTestCases.test_int_subclass_with_index @ linux-x86_64 +test.test_int.IntTestCases.test_int_subclass_with_int @ linux-x86_64 +test.test_int.IntTestCases.test_intconversion @ linux-x86_64 +test.test_int.IntTestCases.test_invalid_signs @ linux-x86_64 +test.test_int.IntTestCases.test_issue31619 @ linux-x86_64 +test.test_int.IntTestCases.test_keyword_args @ linux-x86_64 +test.test_int.IntTestCases.test_no_args @ linux-x86_64 +test.test_int.IntTestCases.test_non_numeric_input_types @ linux-x86_64 +test.test_int.IntTestCases.test_string_float @ linux-x86_64 +test.test_int.IntTestCases.test_underscores @ linux-x86_64 +test.test_int.IntTestCases.test_unicode @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_int_literal.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_int_literal.txt new file mode 100644 index 0000000000..6228e00732 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_int_literal.txt @@ -0,0 +1,6 @@ +test.test_int_literal.TestHexOctBin.test_bin_baseline @ linux-x86_64 +test.test_int_literal.TestHexOctBin.test_bin_unsigned @ linux-x86_64 +test.test_int_literal.TestHexOctBin.test_hex_baseline @ linux-x86_64 +test.test_int_literal.TestHexOctBin.test_hex_unsigned @ linux-x86_64 +test.test_int_literal.TestHexOctBin.test_oct_baseline @ linux-x86_64 +test.test_int_literal.TestHexOctBin.test_oct_unsigned @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_io.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_io.txt new file mode 100644 index 0000000000..fba4892118 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_io.txt @@ -0,0 +1,523 @@ +test.test_io.CBufferedRWPairTest.test_close_and_closed @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_constructor @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_constructor_max_buffer_size_removal @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_constructor_with_not_readable @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_constructor_with_not_writeable @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_detach @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_isatty @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_peek @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_read @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_read1 @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_readable @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_reader_close_error_on_close @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_reader_writer_close_error_on_close @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_readinto @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_readlines @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_seekable @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_uninitialized @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_weakref_clearing @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_write @ linux-x86_64 +test.test_io.CBufferedRWPairTest.test_writeable @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_args_error @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_buffering @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_close_error_on_close @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_constructor @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_context_manager @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_detach @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_detach_flush @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_fileno @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_flush @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_flush_and_peek @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_flush_and_read @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_flush_and_readinto @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_flush_and_write @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_flush_error_on_close @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_interleaved_read_write @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_interleaved_readline_write @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_invalid_args @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_max_buffer_size_removal @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_misbehaved_io @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_multi_close @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_no_extraneous_read @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_nonnormalized_close_error_on_close @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_read @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_read1 @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_read1_arbitrary @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_read_all @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_read_and_write @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_read_non_blocking @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_read_on_closed @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_read_past_eof @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_readinto @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_readinto1 @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_readinto1_array @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_readinto_array @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_readlines @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_readonly_attributes @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_repr @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_seek_and_tell @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_slow_close_from_thread @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_threads @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_truncate @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_truncate_after_read_or_write @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_truncate_after_write @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_uninitialized @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_write @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_write_after_readahead @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_write_and_rewind @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_write_error_on_close @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_write_non_blocking @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_write_overflow @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_write_rewind_write @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_writelines @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_writelines_error @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_writelines_userlist @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_writes @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_writes_and_flushes @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_writes_and_peek @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_writes_and_read1s @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_writes_and_readintos @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_writes_and_reads @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_writes_and_seeks @ linux-x86_64 +test.test_io.CBufferedRandomTest.test_writes_and_truncates @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_args_error @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_bad_readinto_type @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_bad_readinto_value @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_buffering @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_close_error_on_close @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_constructor @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_context_manager @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_detach @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_fileno @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_flush_error_on_close @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_initialization @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_invalid_args @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_misbehaved_io @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_misbehaved_io_read @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_multi_close @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_no_extraneous_read @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_nonnormalized_close_error_on_close @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_read @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_read1 @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_read1_arbitrary @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_read_all @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_read_non_blocking @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_read_on_closed @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_read_past_eof @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_readinto @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_readinto1 @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_readinto1_array @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_readinto_array @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_readlines @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_readonly_attributes @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_repr @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_threads @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_truncate_on_read_only @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_uninitialized @ linux-x86_64 +test.test_io.CBufferedReaderTest.test_unseekable @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_args_error @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_close_error_on_close @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_constructor @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_context_manager @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_detach @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_detach_flush @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_fileno @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_flush @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_flush_error_on_close @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_initialization @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_invalid_args @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_max_buffer_size_removal @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_misbehaved_io @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_multi_close @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_nonnormalized_close_error_on_close @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_readonly_attributes @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_repr @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_slow_close_from_thread @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_threads @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_truncate @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_truncate_after_write @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_uninitialized @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_unseekable @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_write @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_write_and_rewind @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_write_error_on_close @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_write_non_blocking @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_write_overflow @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_writelines @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_writelines_error @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_writelines_userlist @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_writes @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_writes_and_flushes @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_writes_and_seeks @ linux-x86_64 +test.test_io.CBufferedWriterTest.test_writes_and_truncates @ linux-x86_64 +test.test_io.CIOTest.test_BufferedIOBase_readinto @ linux-x86_64 +test.test_io.CIOTest.test_RawIOBase_read @ linux-x86_64 +test.test_io.CIOTest.test_RawIOBase_readall @ linux-x86_64 +test.test_io.CIOTest.test_append_mode_tell @ linux-x86_64 +test.test_io.CIOTest.test_array_writes @ linux-x86_64 +test.test_io.CIOTest.test_bad_opener_negative_1 @ linux-x86_64 +test.test_io.CIOTest.test_bad_opener_other_negative @ linux-x86_64 +test.test_io.CIOTest.test_buffered_file_io @ linux-x86_64 +test.test_io.CIOTest.test_buffered_readinto_mixin @ linux-x86_64 +test.test_io.CIOTest.test_close_assert @ linux-x86_64 +test.test_io.CIOTest.test_close_flushes @ linux-x86_64 +test.test_io.CIOTest.test_closefd @ linux-x86_64 +test.test_io.CIOTest.test_closefd_attr @ linux-x86_64 +test.test_io.CIOTest.test_fileio_closefd @ linux-x86_64 +test.test_io.CIOTest.test_flush_error_on_close @ linux-x86_64 +test.test_io.CIOTest.test_fspath_support @ linux-x86_64 +test.test_io.CIOTest.test_invalid_newline @ linux-x86_64 +test.test_io.CIOTest.test_invalid_operations @ linux-x86_64 +test.test_io.CIOTest.test_large_file_ops @ linux-x86_64 +test.test_io.CIOTest.test_multi_close @ linux-x86_64 +test.test_io.CIOTest.test_next_nonsizeable @ linux-x86_64 +test.test_io.CIOTest.test_no_closefd_with_filename @ linux-x86_64 +test.test_io.CIOTest.test_nonbuffered_textio @ linux-x86_64 +test.test_io.CIOTest.test_open_handles_NUL_chars @ linux-x86_64 +test.test_io.CIOTest.test_opener @ linux-x86_64 +test.test_io.CIOTest.test_opener_invalid_fd @ linux-x86_64 +test.test_io.CIOTest.test_optional_abilities @ linux-x86_64 +test.test_io.CIOTest.test_raw_bytes_io @ linux-x86_64 +test.test_io.CIOTest.test_raw_file_io @ linux-x86_64 +test.test_io.CIOTest.test_read_closed @ linux-x86_64 +test.test_io.CIOTest.test_readline @ linux-x86_64 +test.test_io.CIOTest.test_readline_nonsizeable @ linux-x86_64 +test.test_io.CIOTest.test_types_have_dict @ linux-x86_64 +test.test_io.CIOTest.test_with_open @ linux-x86_64 +test.test_io.CIncrementalNewlineDecoderTest.test_newline_bytes @ linux-x86_64 +test.test_io.CIncrementalNewlineDecoderTest.test_newline_decoder @ linux-x86_64 +test.test_io.CIncrementalNewlineDecoderTest.test_translate @ linux-x86_64 +test.test_io.CMiscIOTest.test___all__ @ linux-x86_64 +test.test_io.CMiscIOTest.test_abc_inheritance @ linux-x86_64 +test.test_io.CMiscIOTest.test_abc_inheritance_official @ linux-x86_64 +test.test_io.CMiscIOTest.test_abcs @ linux-x86_64 +test.test_io.CMiscIOTest.test_attributes @ linux-x86_64 +test.test_io.CMiscIOTest.test_check_encoding_warning @ linux-x86_64 +test.test_io.CMiscIOTest.test_create_fail @ linux-x86_64 +test.test_io.CMiscIOTest.test_create_writes @ linux-x86_64 +test.test_io.CMiscIOTest.test_daemon_threads_shutdown_stderr_deadlock @ linux-x86_64 +test.test_io.CMiscIOTest.test_daemon_threads_shutdown_stdout_deadlock @ linux-x86_64 +test.test_io.CMiscIOTest.test_io_after_close @ linux-x86_64 +test.test_io.CMiscIOTest.test_nonblock_pipe_write_bigbuf @ linux-x86_64 +test.test_io.CMiscIOTest.test_nonblock_pipe_write_smallbuf @ linux-x86_64 +test.test_io.CMiscIOTest.test_open_allargs @ linux-x86_64 +test.test_io.CMiscIOTest.test_open_pipe_with_append @ linux-x86_64 +test.test_io.CMiscIOTest.test_pickling @ linux-x86_64 +test.test_io.CMiscIOTest.test_readinto_buffer_overflow @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_basic_io @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_bufio_write_through @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_close_error_on_close @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_constructor @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_default_encoding @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_del__CHUNK_SIZE_SystemError @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_detach @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_encoding @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_encoding_errors_reading @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_encoding_errors_writing @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_error_through_destructor @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_errors_property @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_flush_error_on_close @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_illegal_decoder @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_illegal_encoder @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_initialization @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_internal_buffer_size @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_issue1395_1 @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_issue1395_2 @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_issue1395_3 @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_issue1395_4 @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_issue1395_5 @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_issue2282 @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_issue22849 @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_issue25862 @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_line_buffering @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_multi_close @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_multibyte_seek_and_tell @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_newlines @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_newlines_input @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_newlines_output @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_non_text_encoding_codecs_are_rejected @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_nonnormalized_close_error_on_close @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_rawio @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_rawio_write_through @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_read_by_chunk @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_read_byteslike @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_read_nonbytes @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_read_one_by_one @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_readlines @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_readonly_attributes @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_reconfigure_defaults @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_reconfigure_encoding_read @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_reconfigure_line_buffering @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_reconfigure_newline @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_reconfigure_write @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_reconfigure_write_fromascii @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_reconfigure_write_non_seekable @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_reconfigure_write_through @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_repr @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_seek_and_tell @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_seeking @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_seeking_too @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_telling @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_threads_write @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_uninitialized @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_unreadable @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_unseekable @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_writelines @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_writelines_error @ linux-x86_64 +test.test_io.CTextIOWrapperTest.test_writelines_userlist @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_close_and_closed @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_constructor @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_constructor_max_buffer_size_removal @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_constructor_with_not_readable @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_constructor_with_not_writeable @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_detach @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_isatty @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_peek @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_read @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_read1 @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_readable @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_reader_close_error_on_close @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_reader_writer_close_error_on_close @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_readinto @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_readlines @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_seekable @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_uninitialized @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_weakref_clearing @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_write @ linux-x86_64 +test.test_io.PyBufferedRWPairTest.test_writeable @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_buffering @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_close_error_on_close @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_constructor @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_context_manager @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_detach @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_detach_flush @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_fileno @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_flush @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_flush_and_peek @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_flush_and_read @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_flush_and_readinto @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_flush_and_write @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_flush_error_on_close @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_interleaved_read_write @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_interleaved_readline_write @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_invalid_args @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_max_buffer_size_removal @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_misbehaved_io @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_multi_close @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_no_extraneous_read @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_nonnormalized_close_error_on_close @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_read @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_read1 @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_read1_arbitrary @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_read_all @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_read_and_write @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_read_non_blocking @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_read_on_closed @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_read_past_eof @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_readinto @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_readinto1 @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_readinto1_array @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_readinto_array @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_readlines @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_readonly_attributes @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_repr @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_seek_and_tell @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_slow_close_from_thread @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_threads @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_truncate @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_truncate_after_read_or_write @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_truncate_after_write @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_uninitialized @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_write @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_write_after_readahead @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_write_and_rewind @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_write_error_on_close @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_write_non_blocking @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_write_overflow @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_write_rewind_write @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_writelines @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_writelines_error @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_writelines_userlist @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_writes @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_writes_and_flushes @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_writes_and_peek @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_writes_and_read1s @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_writes_and_readintos @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_writes_and_reads @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_writes_and_seeks @ linux-x86_64 +test.test_io.PyBufferedRandomTest.test_writes_and_truncates @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_buffering @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_close_error_on_close @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_constructor @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_context_manager @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_detach @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_fileno @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_flush_error_on_close @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_invalid_args @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_misbehaved_io @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_multi_close @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_no_extraneous_read @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_nonnormalized_close_error_on_close @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_read @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_read1 @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_read1_arbitrary @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_read_all @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_read_non_blocking @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_read_on_closed @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_read_past_eof @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_readinto @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_readinto1 @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_readinto1_array @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_readinto_array @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_readlines @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_readonly_attributes @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_repr @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_threads @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_truncate_on_read_only @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_uninitialized @ linux-x86_64 +test.test_io.PyBufferedReaderTest.test_unseekable @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_close_error_on_close @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_constructor @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_context_manager @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_detach @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_detach_flush @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_fileno @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_flush @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_flush_error_on_close @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_invalid_args @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_max_buffer_size_removal @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_misbehaved_io @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_multi_close @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_nonnormalized_close_error_on_close @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_readonly_attributes @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_repr @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_slow_close_from_thread @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_threads @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_truncate @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_truncate_after_write @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_uninitialized @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_unseekable @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_write @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_write_and_rewind @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_write_error_on_close @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_write_non_blocking @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_write_overflow @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_writelines @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_writelines_error @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_writelines_userlist @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_writes @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_writes_and_flushes @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_writes_and_seeks @ linux-x86_64 +test.test_io.PyBufferedWriterTest.test_writes_and_truncates @ linux-x86_64 +test.test_io.PyIOTest.test_BufferedIOBase_readinto @ linux-x86_64 +test.test_io.PyIOTest.test_RawIOBase_read @ linux-x86_64 +test.test_io.PyIOTest.test_RawIOBase_readall @ linux-x86_64 +test.test_io.PyIOTest.test_append_mode_tell @ linux-x86_64 +test.test_io.PyIOTest.test_array_writes @ linux-x86_64 +test.test_io.PyIOTest.test_bad_opener_negative_1 @ linux-x86_64 +test.test_io.PyIOTest.test_bad_opener_other_negative @ linux-x86_64 +test.test_io.PyIOTest.test_buffered_file_io @ linux-x86_64 +test.test_io.PyIOTest.test_buffered_readinto_mixin @ linux-x86_64 +test.test_io.PyIOTest.test_close_assert @ linux-x86_64 +test.test_io.PyIOTest.test_close_flushes @ linux-x86_64 +test.test_io.PyIOTest.test_closefd @ linux-x86_64 +test.test_io.PyIOTest.test_closefd_attr @ linux-x86_64 +test.test_io.PyIOTest.test_fileio_closefd @ linux-x86_64 +test.test_io.PyIOTest.test_flush_error_on_close @ linux-x86_64 +test.test_io.PyIOTest.test_fspath_support @ linux-x86_64 +test.test_io.PyIOTest.test_invalid_newline @ linux-x86_64 +test.test_io.PyIOTest.test_invalid_operations @ linux-x86_64 +test.test_io.PyIOTest.test_large_file_ops @ linux-x86_64 +test.test_io.PyIOTest.test_multi_close @ linux-x86_64 +test.test_io.PyIOTest.test_next_nonsizeable @ linux-x86_64 +test.test_io.PyIOTest.test_no_closefd_with_filename @ linux-x86_64 +test.test_io.PyIOTest.test_nonbuffered_textio @ linux-x86_64 +test.test_io.PyIOTest.test_open_handles_NUL_chars @ linux-x86_64 +test.test_io.PyIOTest.test_opener @ linux-x86_64 +test.test_io.PyIOTest.test_opener_invalid_fd @ linux-x86_64 +test.test_io.PyIOTest.test_optional_abilities @ linux-x86_64 +test.test_io.PyIOTest.test_raw_bytes_io @ linux-x86_64 +test.test_io.PyIOTest.test_raw_file_io @ linux-x86_64 +test.test_io.PyIOTest.test_read_closed @ linux-x86_64 +test.test_io.PyIOTest.test_readline @ linux-x86_64 +test.test_io.PyIOTest.test_readline_nonsizeable @ linux-x86_64 +test.test_io.PyIOTest.test_types_have_dict @ linux-x86_64 +test.test_io.PyIOTest.test_with_open @ linux-x86_64 +test.test_io.PyIncrementalNewlineDecoderTest.test_newline_bytes @ linux-x86_64 +test.test_io.PyIncrementalNewlineDecoderTest.test_newline_decoder @ linux-x86_64 +test.test_io.PyIncrementalNewlineDecoderTest.test_translate @ linux-x86_64 +test.test_io.PyMiscIOTest.test___all__ @ linux-x86_64 +test.test_io.PyMiscIOTest.test_abc_inheritance @ linux-x86_64 +test.test_io.PyMiscIOTest.test_abc_inheritance_official @ linux-x86_64 +test.test_io.PyMiscIOTest.test_abcs @ linux-x86_64 +test.test_io.PyMiscIOTest.test_attributes @ linux-x86_64 +test.test_io.PyMiscIOTest.test_check_encoding_warning @ linux-x86_64 +test.test_io.PyMiscIOTest.test_create_fail @ linux-x86_64 +test.test_io.PyMiscIOTest.test_create_writes @ linux-x86_64 +test.test_io.PyMiscIOTest.test_io_after_close @ linux-x86_64 +test.test_io.PyMiscIOTest.test_nonblock_pipe_write_bigbuf @ linux-x86_64 +test.test_io.PyMiscIOTest.test_nonblock_pipe_write_smallbuf @ linux-x86_64 +test.test_io.PyMiscIOTest.test_open_allargs @ linux-x86_64 +test.test_io.PyMiscIOTest.test_open_pipe_with_append @ linux-x86_64 +test.test_io.PyMiscIOTest.test_pickling @ linux-x86_64 +test.test_io.PyMiscIOTest.test_removed_u_mode @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_basic_io @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_bufio_write_through @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_close_error_on_close @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_constructor @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_default_encoding @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_detach @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_encoding @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_encoding_errors_reading @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_encoding_errors_writing @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_error_through_destructor @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_errors_property @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_flush_error_on_close @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_illegal_decoder @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_illegal_encoder @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_issue1395_1 @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_issue1395_2 @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_issue1395_3 @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_issue1395_4 @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_issue1395_5 @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_issue2282 @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_issue22849 @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_issue25862 @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_line_buffering @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_multi_close @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_multibyte_seek_and_tell @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_newlines @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_newlines_input @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_newlines_output @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_non_text_encoding_codecs_are_rejected @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_nonnormalized_close_error_on_close @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_rawio @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_rawio_write_through @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_read_by_chunk @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_read_byteslike @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_read_nonbytes @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_read_one_by_one @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_readlines @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_readonly_attributes @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_reconfigure_defaults @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_reconfigure_encoding_read @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_reconfigure_errors @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_reconfigure_line_buffering @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_reconfigure_newline @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_reconfigure_write @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_reconfigure_write_fromascii @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_reconfigure_write_non_seekable @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_reconfigure_write_through @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_repr @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_seek_and_tell @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_seeking @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_seeking_too @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_telling @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_threads_write @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_uninitialized @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_unreadable @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_unseekable @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_writelines @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_writelines_error @ linux-x86_64 +test.test_io.PyTextIOWrapperTest.test_writelines_userlist @ linux-x86_64 +test.test_io.StatefulIncrementalDecoderTest.test_decoder @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ipaddress.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ipaddress.txt new file mode 100644 index 0000000000..57e91a4198 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ipaddress.txt @@ -0,0 +1,204 @@ +test.test_ipaddress.AddressTestCase_v4.test_bad_address_split @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_bad_packed_length @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_empty_address @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_empty_octet @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_floats_rejected @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_format @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_int @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_invalid_characters @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_large_ints_rejected @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_leading_zeros @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_negative_ints_rejected @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_network_passed_as_address @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_not_an_index_issue15559 @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_octet_length @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_octet_limit @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_packed @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_pickle @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v4.test_weakref @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_bad_address_split_v6_leading_colon @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_bad_address_split_v6_not_enough_parts @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_bad_address_split_v6_repeated_double_colon @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_bad_address_split_v6_too_many_colons @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_bad_address_split_v6_too_many_parts @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_bad_address_split_v6_too_many_parts_with_double_colon @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_bad_address_split_v6_trailing_colon @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_bad_packed_length @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_bad_v4_part_in @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_blank_scope_id @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_copy @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_empty_address @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_floats_rejected @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_format @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_int @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_invalid_characters @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_invalid_scope_id_with_percent @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_large_ints_rejected @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_leading_zeros @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_negative_ints_rejected @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_network_passed_as_address @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_not_an_index_issue15559 @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_packed @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_part_length @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_pickle @ linux-x86_64 +test.test_ipaddress.AddressTestCase_v6.test_weakref @ linux-x86_64 +test.test_ipaddress.ComparisonTests.test_containment @ linux-x86_64 +test.test_ipaddress.ComparisonTests.test_foreign_type_equality @ linux-x86_64 +test.test_ipaddress.ComparisonTests.test_foreign_type_ordering @ linux-x86_64 +test.test_ipaddress.ComparisonTests.test_incompatible_versions @ linux-x86_64 +test.test_ipaddress.ComparisonTests.test_mixed_type_equality @ linux-x86_64 +test.test_ipaddress.ComparisonTests.test_mixed_type_key @ linux-x86_64 +test.test_ipaddress.ComparisonTests.test_mixed_type_ordering @ linux-x86_64 +test.test_ipaddress.ComparisonTests.test_same_type_equality @ linux-x86_64 +test.test_ipaddress.ComparisonTests.test_same_type_ordering @ linux-x86_64 +test.test_ipaddress.ComparisonTests.test_scoped_ipv6_equality @ linux-x86_64 +test.test_ipaddress.ComparisonTests.test_v4_with_v6_scoped_equality @ linux-x86_64 +test.test_ipaddress.FactoryFunctionErrors.test_ip_address @ linux-x86_64 +test.test_ipaddress.FactoryFunctionErrors.test_ip_interface @ linux-x86_64 +test.test_ipaddress.FactoryFunctionErrors.test_ip_network @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_address_errors @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_bad_packed_length @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_empty_address @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_floats_rejected @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_int @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_large_ints_rejected @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_leading_zeros @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_negative_ints_rejected @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_netmask_errors @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_netmask_in_tuple_errors @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_no_mask @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_not_an_index_issue15559 @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_packed @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_pickle @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_split_netmask @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v4.test_valid_netmask @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_address_errors @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_bad_packed_length @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_blank_scope_id @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_empty_address @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_floats_rejected @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_int @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_invalid_scope_id_with_percent @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_large_ints_rejected @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_leading_zeros @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_negative_ints_rejected @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_netmask_errors @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_netmask_in_tuple_errors @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_no_mask @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_not_an_index_issue15559 @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_packed @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_pickle @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_split_netmask @ linux-x86_64 +test.test_ipaddress.InterfaceTestCase_v6.test_valid_netmask @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testAddrExclude @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testAddressComparison @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testAddressIntMath @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testCollapsing @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testCompressIPv6Address @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testContains @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testCopyConstructor @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testEmbeddedIpv4 @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testEqual @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testExplodeShortHandIpStr @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testFancySubnetting @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testForceVersion @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testGetBroadcast @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testGetIp @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testGetNetmask @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testGetNetwork @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testGetNum_Addresses @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testGetPrefixlen @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testGetScopeId @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testGetSubnetForSingle128 @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testGetSubnetForSingle32 @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testGetSubnets @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testGetSubnets3 @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testGetSupernet @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testGetSupernet3 @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testGetSupernet4 @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testGetitem @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testHash @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testHosts @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testIPBases @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testIPVersion @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testIPv4Net @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testIPv4NetworkHelpers @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testIPv4Tuple @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testIPv6AddressTooLarge @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testIPv6NetworkHelpers @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testIPv6Tuple @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testIntRepresentation @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testInterfaceComparison @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testInternals @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testInvalidIntToBytes @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testIpFromInt @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testIpFromPacked @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testIpType @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testIpv4Mapped @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testIpv4MappedPrivateCheck @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testMaxPrefixLength @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testNetworkComparison @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testNetworkElementCaching @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testNotEqual @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testNth @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testOverlaps @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testPacked @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testPrivateNetworks @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testRepr @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testReservedIpv4 @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testReservedIpv6 @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testReversePointer @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testSlash0Constructor @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testSlash128Constructor @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testSlash32Constructor @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testStrictNetworks @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testSubnet2 @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testSubnetFailsForLargeCidrDiff @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testSubnetFailsForNegativeCidrDiff @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testSummarizing @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testSupernetFailsForLargeCidrDiff @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testTeredo @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testV4HashIsNotConstant @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testV6HashIsNotConstant @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testWithStar @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testZeroNetmask @ linux-x86_64 +test.test_ipaddress.IpaddrUnitTest.testsixtofour @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_address_errors @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_bad_packed_length @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_empty_address @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_floats_rejected @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_int @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_large_ints_rejected @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_leading_zeros @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_negative_ints_rejected @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_netmask_errors @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_netmask_in_tuple_errors @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_no_mask @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_not_an_index_issue15559 @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_packed @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_pickle @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_split_netmask @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_subnet_of @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_subnet_of_mixed_types @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_supernet_of @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v4.test_valid_netmask @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_address_errors @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_bad_packed_length @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_blank_scope_id @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_empty_address @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_floats_rejected @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_int @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_invalid_scope_id_with_percent @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_large_ints_rejected @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_leading_zeros @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_negative_ints_rejected @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_netmask_errors @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_netmask_in_tuple_errors @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_no_mask @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_not_an_index_issue15559 @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_packed @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_pickle @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_split_netmask @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_subnet_of @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_supernet_of @ linux-x86_64 +test.test_ipaddress.NetworkTestCase_v6.test_valid_netmask @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_isinstance.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_isinstance.txt new file mode 100644 index 0000000000..25d29c2028 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_isinstance.txt @@ -0,0 +1,22 @@ +test.test_isinstance.TestIsInstanceExceptions.test_bases_raises_other_than_attribute_error @ linux-x86_64 +test.test_isinstance.TestIsInstanceExceptions.test_class_has_no_bases @ linux-x86_64 +test.test_isinstance.TestIsInstanceExceptions.test_dont_mask_non_attribute_error @ linux-x86_64 +test.test_isinstance.TestIsInstanceExceptions.test_isinstance_dont_mask_non_attribute_error @ linux-x86_64 +test.test_isinstance.TestIsInstanceExceptions.test_mask_attribute_error @ linux-x86_64 +test.test_isinstance.TestIsInstanceIsSubclass.test_infinite_cycle_in_bases @ linux-x86_64 +test.test_isinstance.TestIsInstanceIsSubclass.test_infinite_recursion_in_bases @ linux-x86_64 +test.test_isinstance.TestIsInstanceIsSubclass.test_infinitely_many_bases @ linux-x86_64 +test.test_isinstance.TestIsInstanceIsSubclass.test_isinstance_abstract @ linux-x86_64 +test.test_isinstance.TestIsInstanceIsSubclass.test_isinstance_normal @ linux-x86_64 +test.test_isinstance.TestIsInstanceIsSubclass.test_isinstance_recursion_limit @ linux-x86_64 +test.test_isinstance.TestIsInstanceIsSubclass.test_isinstance_with_or_union @ linux-x86_64 +test.test_isinstance.TestIsInstanceIsSubclass.test_issubclass_refcount_handling @ linux-x86_64 +test.test_isinstance.TestIsInstanceIsSubclass.test_subclass_abstract @ linux-x86_64 +test.test_isinstance.TestIsInstanceIsSubclass.test_subclass_normal @ linux-x86_64 +test.test_isinstance.TestIsInstanceIsSubclass.test_subclass_recursion_limit @ linux-x86_64 +test.test_isinstance.TestIsInstanceIsSubclass.test_subclass_tuple @ linux-x86_64 +test.test_isinstance.TestIsInstanceIsSubclass.test_subclass_with_union @ linux-x86_64 +test.test_isinstance.TestIsSubclassExceptions.test_dont_mask_non_attribute_error @ linux-x86_64 +test.test_isinstance.TestIsSubclassExceptions.test_dont_mask_non_attribute_error_in_cls_arg @ linux-x86_64 +test.test_isinstance.TestIsSubclassExceptions.test_mask_attribute_error @ linux-x86_64 +test.test_isinstance.TestIsSubclassExceptions.test_mask_attribute_error_in_cls_arg @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_iter.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_iter.txt new file mode 100644 index 0000000000..f613726e1b --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_iter.txt @@ -0,0 +1,51 @@ +test.test_iter.TestCase.test_3720 @ linux-x86_64 +test.test_iter.TestCase.test_builtin_filter @ linux-x86_64 +test.test_iter.TestCase.test_builtin_list @ linux-x86_64 +test.test_iter.TestCase.test_builtin_map @ linux-x86_64 +test.test_iter.TestCase.test_builtin_max_min @ linux-x86_64 +test.test_iter.TestCase.test_builtin_tuple @ linux-x86_64 +test.test_iter.TestCase.test_builtin_zip @ linux-x86_64 +test.test_iter.TestCase.test_countOf @ linux-x86_64 +test.test_iter.TestCase.test_error_iter @ linux-x86_64 +test.test_iter.TestCase.test_exception_function @ linux-x86_64 +test.test_iter.TestCase.test_exception_sequence @ linux-x86_64 +test.test_iter.TestCase.test_extending_list_with_iterator_does_not_segfault @ linux-x86_64 +test.test_iter.TestCase.test_in_and_not_in @ linux-x86_64 +test.test_iter.TestCase.test_indexOf @ linux-x86_64 +test.test_iter.TestCase.test_iter_basic @ linux-x86_64 +test.test_iter.TestCase.test_iter_big_range @ linux-x86_64 +test.test_iter.TestCase.test_iter_callable @ linux-x86_64 +test.test_iter.TestCase.test_iter_class_for @ linux-x86_64 +test.test_iter.TestCase.test_iter_class_iter @ linux-x86_64 +test.test_iter.TestCase.test_iter_dict @ linux-x86_64 +test.test_iter.TestCase.test_iter_empty @ linux-x86_64 +test.test_iter.TestCase.test_iter_file @ linux-x86_64 +test.test_iter.TestCase.test_iter_for_loop @ linux-x86_64 +test.test_iter.TestCase.test_iter_function @ linux-x86_64 +test.test_iter.TestCase.test_iter_function_stop @ linux-x86_64 +test.test_iter.TestCase.test_iter_idempotency @ linux-x86_64 +test.test_iter.TestCase.test_iter_independence @ linux-x86_64 +test.test_iter.TestCase.test_iter_neg_setstate @ linux-x86_64 +test.test_iter.TestCase.test_iter_range @ linux-x86_64 +test.test_iter.TestCase.test_iter_string @ linux-x86_64 +test.test_iter.TestCase.test_iter_tuple @ linux-x86_64 +test.test_iter.TestCase.test_mutating_seq_class_exhausted_iter @ linux-x86_64 +test.test_iter.TestCase.test_mutating_seq_class_iter_pickle @ linux-x86_64 +test.test_iter.TestCase.test_nested_comprehensions_for @ linux-x86_64 +test.test_iter.TestCase.test_nested_comprehensions_iter @ linux-x86_64 +test.test_iter.TestCase.test_new_style_iter_class @ linux-x86_64 +test.test_iter.TestCase.test_seq_class_for @ linux-x86_64 +test.test_iter.TestCase.test_seq_class_iter @ linux-x86_64 +test.test_iter.TestCase.test_sinkstate_callable @ linux-x86_64 +test.test_iter.TestCase.test_sinkstate_dict @ linux-x86_64 +test.test_iter.TestCase.test_sinkstate_enumerate @ linux-x86_64 +test.test_iter.TestCase.test_sinkstate_list @ linux-x86_64 +test.test_iter.TestCase.test_sinkstate_range @ linux-x86_64 +test.test_iter.TestCase.test_sinkstate_sequence @ linux-x86_64 +test.test_iter.TestCase.test_sinkstate_string @ linux-x86_64 +test.test_iter.TestCase.test_sinkstate_tuple @ linux-x86_64 +test.test_iter.TestCase.test_sinkstate_yield @ linux-x86_64 +test.test_iter.TestCase.test_stop_sequence @ linux-x86_64 +test.test_iter.TestCase.test_unicode_join_endcase @ linux-x86_64 +test.test_iter.TestCase.test_unpack_iter @ linux-x86_64 +test.test_iter.TestCase.test_writelines @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_iterlen.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_iterlen.txt new file mode 100644 index 0000000000..42c583084e --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_iterlen.txt @@ -0,0 +1,21 @@ +test.test_iterlen.TestDeque.test_immutable_during_iteration @ linux-x86_64 +test.test_iterlen.TestDeque.test_invariant @ linux-x86_64 +test.test_iterlen.TestDequeReversed.test_immutable_during_iteration @ linux-x86_64 +test.test_iterlen.TestDequeReversed.test_invariant @ linux-x86_64 +test.test_iterlen.TestDictItems.test_immutable_during_iteration @ linux-x86_64 +test.test_iterlen.TestDictItems.test_invariant @ linux-x86_64 +test.test_iterlen.TestDictKeys.test_immutable_during_iteration @ linux-x86_64 +test.test_iterlen.TestDictKeys.test_invariant @ linux-x86_64 +test.test_iterlen.TestDictValues.test_immutable_during_iteration @ linux-x86_64 +test.test_iterlen.TestDictValues.test_invariant @ linux-x86_64 +test.test_iterlen.TestLengthHintExceptions.test_invalid_hint @ linux-x86_64 +test.test_iterlen.TestLengthHintExceptions.test_issue1242657 @ linux-x86_64 +test.test_iterlen.TestList.test_invariant @ linux-x86_64 +test.test_iterlen.TestListReversed.test_invariant @ linux-x86_64 +test.test_iterlen.TestListReversed.test_mutation @ linux-x86_64 +test.test_iterlen.TestRepeat.test_invariant @ linux-x86_64 +test.test_iterlen.TestSet.test_immutable_during_iteration @ linux-x86_64 +test.test_iterlen.TestSet.test_invariant @ linux-x86_64 +test.test_iterlen.TestTuple.test_invariant @ linux-x86_64 +test.test_iterlen.TestXrange.test_invariant @ linux-x86_64 +test.test_iterlen.TestXrangeCustomReversed.test_invariant @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_itertools.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_itertools.txt new file mode 100644 index 0000000000..1788425219 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_itertools.txt @@ -0,0 +1,114 @@ +test.test_itertools.LengthTransparency.test_repeat @ linux-x86_64 +test.test_itertools.LengthTransparency.test_repeat_with_negative_times @ linux-x86_64 +test.test_itertools.RegressionTests.test_issue30347_1 @ linux-x86_64 +test.test_itertools.RegressionTests.test_issue30347_2 @ linux-x86_64 +test.test_itertools.RegressionTests.test_long_chain_of_empty_iterables @ linux-x86_64 +test.test_itertools.RegressionTests.test_sf_793826 @ linux-x86_64 +test.test_itertools.RegressionTests.test_sf_950057 @ linux-x86_64 +test.test_itertools.SubclassWithKwargsTest.test_keywords_in_subclass @ linux-x86_64 +test.test_itertools.TestBasicOps.test_StopIteration @ linux-x86_64 +test.test_itertools.TestBasicOps.test_accumulate @ linux-x86_64 +test.test_itertools.TestBasicOps.test_bug_7244 @ linux-x86_64 +test.test_itertools.TestBasicOps.test_chain @ linux-x86_64 +test.test_itertools.TestBasicOps.test_chain_from_iterable @ linux-x86_64 +test.test_itertools.TestBasicOps.test_chain_reducible @ linux-x86_64 +test.test_itertools.TestBasicOps.test_chain_setstate @ linux-x86_64 +test.test_itertools.TestBasicOps.test_combinations @ linux-x86_64 +test.test_itertools.TestBasicOps.test_combinations_with_replacement @ linux-x86_64 +test.test_itertools.TestBasicOps.test_combinatorics @ linux-x86_64 +test.test_itertools.TestBasicOps.test_compress @ linux-x86_64 +test.test_itertools.TestBasicOps.test_count @ linux-x86_64 +test.test_itertools.TestBasicOps.test_count_with_stride @ linux-x86_64 +test.test_itertools.TestBasicOps.test_cycle @ linux-x86_64 +test.test_itertools.TestBasicOps.test_cycle_copy_pickle @ linux-x86_64 +test.test_itertools.TestBasicOps.test_cycle_setstate @ linux-x86_64 +test.test_itertools.TestBasicOps.test_cycle_unpickle_compat @ linux-x86_64 +test.test_itertools.TestBasicOps.test_dropwhile @ linux-x86_64 +test.test_itertools.TestBasicOps.test_filter @ linux-x86_64 +test.test_itertools.TestBasicOps.test_filterfalse @ linux-x86_64 +test.test_itertools.TestBasicOps.test_groupby @ linux-x86_64 +test.test_itertools.TestBasicOps.test_islice @ linux-x86_64 +test.test_itertools.TestBasicOps.test_map @ linux-x86_64 +test.test_itertools.TestBasicOps.test_pairwise @ linux-x86_64 +test.test_itertools.TestBasicOps.test_pairwise_reenter @ linux-x86_64 +test.test_itertools.TestBasicOps.test_pairwise_reenter2 @ linux-x86_64 +test.test_itertools.TestBasicOps.test_permutations @ linux-x86_64 +test.test_itertools.TestBasicOps.test_product @ linux-x86_64 +test.test_itertools.TestBasicOps.test_product_issue_25021 @ linux-x86_64 +test.test_itertools.TestBasicOps.test_product_pickling @ linux-x86_64 +test.test_itertools.TestBasicOps.test_repeat @ linux-x86_64 +test.test_itertools.TestBasicOps.test_repeat_with_negative_times @ linux-x86_64 +test.test_itertools.TestBasicOps.test_starmap @ linux-x86_64 +test.test_itertools.TestBasicOps.test_takewhile @ linux-x86_64 +test.test_itertools.TestBasicOps.test_tee @ linux-x86_64 +test.test_itertools.TestBasicOps.test_tee_concurrent @ linux-x86_64 +test.test_itertools.TestBasicOps.test_tee_del_backward @ linux-x86_64 +test.test_itertools.TestBasicOps.test_tee_reenter @ linux-x86_64 +test.test_itertools.TestBasicOps.test_zip @ linux-x86_64 +test.test_itertools.TestBasicOps.test_zip_longest_bad_iterable @ linux-x86_64 +test.test_itertools.TestBasicOps.test_zip_longest_pickling @ linux-x86_64 +test.test_itertools.TestBasicOps.test_ziplongest @ linux-x86_64 +test.test_itertools.TestExamples.test_accumulate @ linux-x86_64 +test.test_itertools.TestExamples.test_accumulate_reducible @ linux-x86_64 +test.test_itertools.TestExamples.test_accumulate_reducible_none @ linux-x86_64 +test.test_itertools.TestExamples.test_chain @ linux-x86_64 +test.test_itertools.TestExamples.test_chain_from_iterable @ linux-x86_64 +test.test_itertools.TestExamples.test_combinations @ linux-x86_64 +test.test_itertools.TestExamples.test_combinations_with_replacement @ linux-x86_64 +test.test_itertools.TestExamples.test_compress @ linux-x86_64 +test.test_itertools.TestExamples.test_count @ linux-x86_64 +test.test_itertools.TestExamples.test_cycle @ linux-x86_64 +test.test_itertools.TestExamples.test_dropwhile @ linux-x86_64 +test.test_itertools.TestExamples.test_filter @ linux-x86_64 +test.test_itertools.TestExamples.test_filterfalse @ linux-x86_64 +test.test_itertools.TestExamples.test_groupby @ linux-x86_64 +test.test_itertools.TestExamples.test_islice @ linux-x86_64 +test.test_itertools.TestExamples.test_map @ linux-x86_64 +test.test_itertools.TestExamples.test_permutations @ linux-x86_64 +test.test_itertools.TestExamples.test_product @ linux-x86_64 +test.test_itertools.TestExamples.test_repeat @ linux-x86_64 +test.test_itertools.TestExamples.test_stapmap @ linux-x86_64 +test.test_itertools.TestExamples.test_takewhile @ linux-x86_64 +test.test_itertools.TestExamples.test_zip @ linux-x86_64 +test.test_itertools.TestExamples.test_zip_longest @ linux-x86_64 +test.test_itertools.TestGC.test_accumulate @ linux-x86_64 +test.test_itertools.TestGC.test_chain @ linux-x86_64 +test.test_itertools.TestGC.test_chain_from_iterable @ linux-x86_64 +test.test_itertools.TestGC.test_combinations @ linux-x86_64 +test.test_itertools.TestGC.test_combinations_with_replacement @ linux-x86_64 +test.test_itertools.TestGC.test_compress @ linux-x86_64 +test.test_itertools.TestGC.test_count @ linux-x86_64 +test.test_itertools.TestGC.test_cycle @ linux-x86_64 +test.test_itertools.TestGC.test_dropwhile @ linux-x86_64 +test.test_itertools.TestGC.test_filter @ linux-x86_64 +test.test_itertools.TestGC.test_filterfalse @ linux-x86_64 +test.test_itertools.TestGC.test_groupby @ linux-x86_64 +test.test_itertools.TestGC.test_islice @ linux-x86_64 +test.test_itertools.TestGC.test_issue2246 @ linux-x86_64 +test.test_itertools.TestGC.test_map @ linux-x86_64 +test.test_itertools.TestGC.test_pairwise @ linux-x86_64 +test.test_itertools.TestGC.test_permutations @ linux-x86_64 +test.test_itertools.TestGC.test_product @ linux-x86_64 +test.test_itertools.TestGC.test_repeat @ linux-x86_64 +test.test_itertools.TestGC.test_starmap @ linux-x86_64 +test.test_itertools.TestGC.test_takewhile @ linux-x86_64 +test.test_itertools.TestGC.test_zip @ linux-x86_64 +test.test_itertools.TestGC.test_zip_longest @ linux-x86_64 +test.test_itertools.TestPurePythonRoughEquivalents.test_islice_recipe @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_accumulate @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_chain @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_compress @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_cycle @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_dropwhile @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_filter @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_filterfalse @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_groupby @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_islice @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_map @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_pairwise @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_product @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_starmap @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_takewhile @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_tee @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_zip @ linux-x86_64 +test.test_itertools.TestVariousIteratorArgs.test_ziplongest @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_json.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_json.txt new file mode 100644 index 0000000000..253411101d --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_json.txt @@ -0,0 +1,162 @@ +DocTestCase.json @ linux-x86_64 +DocTestCase.json.encoder.JSONEncoder.encode @ linux-x86_64 +test.test_json.TestCTest.test_cjson @ linux-x86_64 +test.test_json.TestPyTest.test_pyjson @ linux-x86_64 +test.test_json.test_decode.TestCDecode.test_decimal @ linux-x86_64 +test.test_json.test_decode.TestCDecode.test_decoder_optimizations @ linux-x86_64 +test.test_json.test_decode.TestCDecode.test_empty_objects @ linux-x86_64 +test.test_json.test_decode.TestCDecode.test_extra_data @ linux-x86_64 +test.test_json.test_decode.TestCDecode.test_float @ linux-x86_64 +test.test_json.test_decode.TestCDecode.test_invalid_escape @ linux-x86_64 +test.test_json.test_decode.TestCDecode.test_invalid_input_type @ linux-x86_64 +test.test_json.test_decode.TestCDecode.test_keys_reuse @ linux-x86_64 +test.test_json.test_decode.TestCDecode.test_limit_int @ linux-x86_64 +test.test_json.test_decode.TestCDecode.test_negative_index @ linux-x86_64 +test.test_json.test_decode.TestCDecode.test_object_pairs_hook @ linux-x86_64 +test.test_json.test_decode.TestCDecode.test_string_with_utf8_bom @ linux-x86_64 +test.test_json.test_decode.TestPyDecode.test_decimal @ linux-x86_64 +test.test_json.test_decode.TestPyDecode.test_decoder_optimizations @ linux-x86_64 +test.test_json.test_decode.TestPyDecode.test_empty_objects @ linux-x86_64 +test.test_json.test_decode.TestPyDecode.test_extra_data @ linux-x86_64 +test.test_json.test_decode.TestPyDecode.test_float @ linux-x86_64 +test.test_json.test_decode.TestPyDecode.test_invalid_escape @ linux-x86_64 +test.test_json.test_decode.TestPyDecode.test_invalid_input_type @ linux-x86_64 +test.test_json.test_decode.TestPyDecode.test_keys_reuse @ linux-x86_64 +test.test_json.test_decode.TestPyDecode.test_limit_int @ linux-x86_64 +test.test_json.test_decode.TestPyDecode.test_negative_index @ linux-x86_64 +test.test_json.test_decode.TestPyDecode.test_object_pairs_hook @ linux-x86_64 +test.test_json.test_decode.TestPyDecode.test_string_with_utf8_bom @ linux-x86_64 +test.test_json.test_default.TestCDefault.test_default @ linux-x86_64 +test.test_json.test_default.TestCDefault.test_ordereddict @ linux-x86_64 +test.test_json.test_default.TestPyDefault.test_default @ linux-x86_64 +test.test_json.test_default.TestPyDefault.test_ordereddict @ linux-x86_64 +test.test_json.test_dump.TestCDump.test_dump @ linux-x86_64 +test.test_json.test_dump.TestCDump.test_dump_skipkeys @ linux-x86_64 +test.test_json.test_dump.TestCDump.test_dumps @ linux-x86_64 +test.test_json.test_dump.TestCDump.test_encode_evil_dict @ linux-x86_64 +test.test_json.test_dump.TestCDump.test_encode_mutated @ linux-x86_64 +test.test_json.test_dump.TestCDump.test_encode_truefalse @ linux-x86_64 +test.test_json.test_dump.TestCDump.test_large_list @ linux-x86_64 +test.test_json.test_dump.TestPyDump.test_dump @ linux-x86_64 +test.test_json.test_dump.TestPyDump.test_dump_skipkeys @ linux-x86_64 +test.test_json.test_dump.TestPyDump.test_dumps @ linux-x86_64 +test.test_json.test_dump.TestPyDump.test_encode_evil_dict @ linux-x86_64 +test.test_json.test_dump.TestPyDump.test_encode_mutated @ linux-x86_64 +test.test_json.test_dump.TestPyDump.test_encode_truefalse @ linux-x86_64 +test.test_json.test_encode_basestring_ascii.TestCEncodeBasestringAscii.test_encode_basestring_ascii @ linux-x86_64 +test.test_json.test_encode_basestring_ascii.TestCEncodeBasestringAscii.test_ordered_dict @ linux-x86_64 +test.test_json.test_encode_basestring_ascii.TestCEncodeBasestringAscii.test_sorted_dict @ linux-x86_64 +test.test_json.test_encode_basestring_ascii.TestPyEncodeBasestringAscii.test_encode_basestring_ascii @ linux-x86_64 +test.test_json.test_encode_basestring_ascii.TestPyEncodeBasestringAscii.test_ordered_dict @ linux-x86_64 +test.test_json.test_encode_basestring_ascii.TestPyEncodeBasestringAscii.test_sorted_dict @ linux-x86_64 +test.test_json.test_enum.TestCEnum.test_dict_keys @ linux-x86_64 +test.test_json.test_enum.TestCEnum.test_dict_values @ linux-x86_64 +test.test_json.test_enum.TestCEnum.test_floats @ linux-x86_64 +test.test_json.test_enum.TestCEnum.test_ints @ linux-x86_64 +test.test_json.test_enum.TestCEnum.test_list @ linux-x86_64 +test.test_json.test_enum.TestCEnum.test_weird_floats @ linux-x86_64 +test.test_json.test_enum.TestPyEnum.test_dict_keys @ linux-x86_64 +test.test_json.test_enum.TestPyEnum.test_dict_values @ linux-x86_64 +test.test_json.test_enum.TestPyEnum.test_floats @ linux-x86_64 +test.test_json.test_enum.TestPyEnum.test_ints @ linux-x86_64 +test.test_json.test_enum.TestPyEnum.test_list @ linux-x86_64 +test.test_json.test_enum.TestPyEnum.test_weird_floats @ linux-x86_64 +test.test_json.test_fail.TestCFail.test_extra_data @ linux-x86_64 +test.test_json.test_fail.TestCFail.test_failures @ linux-x86_64 +test.test_json.test_fail.TestCFail.test_linecol @ linux-x86_64 +test.test_json.test_fail.TestCFail.test_non_string_keys_dict @ linux-x86_64 +test.test_json.test_fail.TestCFail.test_not_serializable @ linux-x86_64 +test.test_json.test_fail.TestCFail.test_truncated_input @ linux-x86_64 +test.test_json.test_fail.TestCFail.test_unexpected_data @ linux-x86_64 +test.test_json.test_fail.TestPyFail.test_extra_data @ linux-x86_64 +test.test_json.test_fail.TestPyFail.test_failures @ linux-x86_64 +test.test_json.test_fail.TestPyFail.test_linecol @ linux-x86_64 +test.test_json.test_fail.TestPyFail.test_not_serializable @ linux-x86_64 +test.test_json.test_fail.TestPyFail.test_truncated_input @ linux-x86_64 +test.test_json.test_fail.TestPyFail.test_unexpected_data @ linux-x86_64 +test.test_json.test_float.TestCFloat.test_allow_nan @ linux-x86_64 +test.test_json.test_float.TestCFloat.test_floats @ linux-x86_64 +test.test_json.test_float.TestCFloat.test_ints @ linux-x86_64 +test.test_json.test_float.TestCFloat.test_out_of_range @ linux-x86_64 +test.test_json.test_float.TestPyFloat.test_allow_nan @ linux-x86_64 +test.test_json.test_float.TestPyFloat.test_floats @ linux-x86_64 +test.test_json.test_float.TestPyFloat.test_ints @ linux-x86_64 +test.test_json.test_float.TestPyFloat.test_out_of_range @ linux-x86_64 +test.test_json.test_indent.TestCIndent.test_indent @ linux-x86_64 +test.test_json.test_indent.TestCIndent.test_indent0 @ linux-x86_64 +test.test_json.test_indent.TestPyIndent.test_indent @ linux-x86_64 +test.test_json.test_indent.TestPyIndent.test_indent0 @ linux-x86_64 +test.test_json.test_pass1.TestCPass1.test_parse @ linux-x86_64 +test.test_json.test_pass1.TestPyPass1.test_parse @ linux-x86_64 +test.test_json.test_pass2.TestCPass2.test_parse @ linux-x86_64 +test.test_json.test_pass2.TestPyPass2.test_parse @ linux-x86_64 +test.test_json.test_pass3.TestCPass3.test_parse @ linux-x86_64 +test.test_json.test_pass3.TestPyPass3.test_parse @ linux-x86_64 +test.test_json.test_recursion.TestCRecursion.test_defaultrecursion @ linux-x86_64 +test.test_json.test_recursion.TestCRecursion.test_dictrecursion @ linux-x86_64 +test.test_json.test_recursion.TestCRecursion.test_endless_recursion @ linux-x86_64 +test.test_json.test_recursion.TestCRecursion.test_highly_nested_objects_decoding @ linux-x86_64 +test.test_json.test_recursion.TestCRecursion.test_highly_nested_objects_encoding @ linux-x86_64 +test.test_json.test_recursion.TestCRecursion.test_listrecursion @ linux-x86_64 +test.test_json.test_recursion.TestPyRecursion.test_defaultrecursion @ linux-x86_64 +test.test_json.test_recursion.TestPyRecursion.test_dictrecursion @ linux-x86_64 +test.test_json.test_recursion.TestPyRecursion.test_endless_recursion @ linux-x86_64 +test.test_json.test_recursion.TestPyRecursion.test_highly_nested_objects_decoding @ linux-x86_64 +test.test_json.test_recursion.TestPyRecursion.test_highly_nested_objects_encoding @ linux-x86_64 +test.test_json.test_recursion.TestPyRecursion.test_listrecursion @ linux-x86_64 +test.test_json.test_scanstring.TestCScanstring.test_bad_escapes @ linux-x86_64 +test.test_json.test_scanstring.TestCScanstring.test_overflow @ linux-x86_64 +test.test_json.test_scanstring.TestPyScanstring.test_bad_escapes @ linux-x86_64 +test.test_json.test_scanstring.TestPyScanstring.test_overflow @ linux-x86_64 +test.test_json.test_scanstring.TestPyScanstring.test_scanstring @ linux-x86_64 +test.test_json.test_scanstring.TestPyScanstring.test_surrogates @ linux-x86_64 +test.test_json.test_separators.TestCSeparators.test_illegal_separators @ linux-x86_64 +test.test_json.test_separators.TestCSeparators.test_separators @ linux-x86_64 +test.test_json.test_separators.TestPySeparators.test_illegal_separators @ linux-x86_64 +test.test_json.test_separators.TestPySeparators.test_separators @ linux-x86_64 +test.test_json.test_speedups.TestDecode.test_bad_bool_args @ linux-x86_64 +test.test_json.test_speedups.TestDecode.test_make_scanner @ linux-x86_64 +test.test_json.test_speedups.TestEncode.test_bad_bool_args @ linux-x86_64 +test.test_json.test_speedups.TestEncode.test_bad_markers_argument_to_encoder @ linux-x86_64 +test.test_json.test_speedups.TestEncode.test_bad_str_encoder @ linux-x86_64 +test.test_json.test_speedups.TestEncode.test_make_encoder @ linux-x86_64 +test.test_json.test_speedups.TestEncode.test_unsortable_keys @ linux-x86_64 +test.test_json.test_speedups.TestSpeedups.test_encode_basestring_ascii @ linux-x86_64 +test.test_json.test_speedups.TestSpeedups.test_scanstring @ linux-x86_64 +test.test_json.test_tool.TestTool.test_broken_pipe_error @ linux-x86_64 +test.test_json.test_tool.TestTool.test_compact @ linux-x86_64 +test.test_json.test_tool.TestTool.test_ensure_ascii_default @ linux-x86_64 +test.test_json.test_tool.TestTool.test_help_flag @ linux-x86_64 +test.test_json.test_tool.TestTool.test_indent @ linux-x86_64 +test.test_json.test_tool.TestTool.test_infile_outfile @ linux-x86_64 +test.test_json.test_tool.TestTool.test_infile_stdout @ linux-x86_64 +test.test_json.test_tool.TestTool.test_jsonlines @ linux-x86_64 +test.test_json.test_tool.TestTool.test_no_ensure_ascii_flag @ linux-x86_64 +test.test_json.test_tool.TestTool.test_no_indent @ linux-x86_64 +test.test_json.test_tool.TestTool.test_non_ascii_infile @ linux-x86_64 +test.test_json.test_tool.TestTool.test_sort_keys_flag @ linux-x86_64 +test.test_json.test_tool.TestTool.test_stdin_stdout @ linux-x86_64 +test.test_json.test_tool.TestTool.test_tab @ linux-x86_64 +test.test_json.test_tool.TestTool.test_writing_in_place @ linux-x86_64 +test.test_json.test_unicode.TestCUnicode.test_big_unicode_decode @ linux-x86_64 +test.test_json.test_unicode.TestCUnicode.test_big_unicode_encode @ linux-x86_64 +test.test_json.test_unicode.TestCUnicode.test_bytes_decode @ linux-x86_64 +test.test_json.test_unicode.TestCUnicode.test_bytes_encode @ linux-x86_64 +test.test_json.test_unicode.TestCUnicode.test_encoding3 @ linux-x86_64 +test.test_json.test_unicode.TestCUnicode.test_encoding4 @ linux-x86_64 +test.test_json.test_unicode.TestCUnicode.test_encoding5 @ linux-x86_64 +test.test_json.test_unicode.TestCUnicode.test_encoding6 @ linux-x86_64 +test.test_json.test_unicode.TestCUnicode.test_object_pairs_hook_with_unicode @ linux-x86_64 +test.test_json.test_unicode.TestCUnicode.test_unicode_decode @ linux-x86_64 +test.test_json.test_unicode.TestCUnicode.test_unicode_preservation @ linux-x86_64 +test.test_json.test_unicode.TestPyUnicode.test_big_unicode_decode @ linux-x86_64 +test.test_json.test_unicode.TestPyUnicode.test_big_unicode_encode @ linux-x86_64 +test.test_json.test_unicode.TestPyUnicode.test_bytes_decode @ linux-x86_64 +test.test_json.test_unicode.TestPyUnicode.test_bytes_encode @ linux-x86_64 +test.test_json.test_unicode.TestPyUnicode.test_encoding3 @ linux-x86_64 +test.test_json.test_unicode.TestPyUnicode.test_encoding4 @ linux-x86_64 +test.test_json.test_unicode.TestPyUnicode.test_encoding5 @ linux-x86_64 +test.test_json.test_unicode.TestPyUnicode.test_encoding6 @ linux-x86_64 +test.test_json.test_unicode.TestPyUnicode.test_object_pairs_hook_with_unicode @ linux-x86_64 +test.test_json.test_unicode.TestPyUnicode.test_unicode_decode @ linux-x86_64 +test.test_json.test_unicode.TestPyUnicode.test_unicode_preservation @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_keyword.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_keyword.txt new file mode 100644 index 0000000000..3fe1b825db --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_keyword.txt @@ -0,0 +1,11 @@ +test.test_keyword.Test_iskeyword.test_all_keywords_fail_to_be_used_as_names @ linux-x86_64 +test.test_keyword.Test_iskeyword.test_all_soft_keywords_can_be_used_as_names @ linux-x86_64 +test.test_keyword.Test_iskeyword.test_async_and_await_are_keywords @ linux-x86_64 +test.test_keyword.Test_iskeyword.test_changing_the_kwlist_does_not_affect_iskeyword @ linux-x86_64 +test.test_keyword.Test_iskeyword.test_changing_the_softkwlist_does_not_affect_issoftkeyword @ linux-x86_64 +test.test_keyword.Test_iskeyword.test_keywords_are_sorted @ linux-x86_64 +test.test_keyword.Test_iskeyword.test_match_and_case_are_soft_keywords @ linux-x86_64 +test.test_keyword.Test_iskeyword.test_none_value_is_not_a_keyword @ linux-x86_64 +test.test_keyword.Test_iskeyword.test_softkeywords_are_sorted @ linux-x86_64 +test.test_keyword.Test_iskeyword.test_true_is_a_keyword @ linux-x86_64 +test.test_keyword.Test_iskeyword.test_uppercase_true_is_not_a_keyword @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_keywordonlyarg.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_keywordonlyarg.txt new file mode 100644 index 0000000000..159e8d8ca3 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_keywordonlyarg.txt @@ -0,0 +1,11 @@ +test.test_keywordonlyarg.KeywordOnlyArgTestCase.testFunctionCall @ linux-x86_64 +test.test_keywordonlyarg.KeywordOnlyArgTestCase.testKwDefaults @ linux-x86_64 +test.test_keywordonlyarg.KeywordOnlyArgTestCase.testRaiseErrorFuncallWithUnexpectedKeywordArgument @ linux-x86_64 +test.test_keywordonlyarg.KeywordOnlyArgTestCase.testSyntaxErrorForFunctionCall @ linux-x86_64 +test.test_keywordonlyarg.KeywordOnlyArgTestCase.testSyntaxErrorForFunctionDefinition @ linux-x86_64 +test.test_keywordonlyarg.KeywordOnlyArgTestCase.testSyntaxForManyArguments @ linux-x86_64 +test.test_keywordonlyarg.KeywordOnlyArgTestCase.testTooManyPositionalErrorMessage @ linux-x86_64 +test.test_keywordonlyarg.KeywordOnlyArgTestCase.test_default_evaluation_order @ linux-x86_64 +test.test_keywordonlyarg.KeywordOnlyArgTestCase.test_issue13343 @ linux-x86_64 +test.test_keywordonlyarg.KeywordOnlyArgTestCase.test_kwonly_methods @ linux-x86_64 +test.test_keywordonlyarg.KeywordOnlyArgTestCase.test_mangling @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_largefile.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_largefile.txt new file mode 100644 index 0000000000..81ba48509d --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_largefile.txt @@ -0,0 +1,10 @@ +test.test_largefile.CLargeFileTest.test_lseek @ linux-x86_64 +test.test_largefile.CLargeFileTest.test_osstat @ linux-x86_64 +test.test_largefile.CLargeFileTest.test_seek_read @ linux-x86_64 +test.test_largefile.CLargeFileTest.test_seekable @ linux-x86_64 +test.test_largefile.CLargeFileTest.test_truncate @ linux-x86_64 +test.test_largefile.PyLargeFileTest.test_lseek @ linux-x86_64 +test.test_largefile.PyLargeFileTest.test_osstat @ linux-x86_64 +test.test_largefile.PyLargeFileTest.test_seek_read @ linux-x86_64 +test.test_largefile.PyLargeFileTest.test_seekable @ linux-x86_64 +test.test_largefile.PyLargeFileTest.test_truncate @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_lib2to3.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_lib2to3.txt new file mode 100644 index 0000000000..97122e8d46 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_lib2to3.txt @@ -0,0 +1,660 @@ +lib2to3.tests.test_fixers.Test_apply.test_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_5 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_6 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_call @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_complex_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_complex_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_complex_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_dotted_name @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_extreme @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_space_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_space_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_subscript @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_unchanged_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_unchanged_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_unchanged_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_unchanged_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_unchanged_5 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_unchanged_6 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_unchanged_6b @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_unchanged_7 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_unchanged_8 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_unchanged_9 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_apply.test_weird_comments @ linux-x86_64 +lib2to3.tests.test_fixers.Test_asserts.test_deprecated_names @ linux-x86_64 +lib2to3.tests.test_fixers.Test_asserts.test_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_asserts.test_variants @ linux-x86_64 +lib2to3.tests.test_fixers.Test_basestring.test_basestring @ linux-x86_64 +lib2to3.tests.test_fixers.Test_buffer.test_buffer @ linux-x86_64 +lib2to3.tests.test_fixers.Test_buffer.test_slicing @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_01 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_02 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_03 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_04 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_05 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_06 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_07 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_08 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_09 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_10 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_11 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_12 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_13 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_14 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_15 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_16 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_17 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_18 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_19 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_20 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_21 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_22 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_23 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_24 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_25 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_26 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_27 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_28 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_29 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_30 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_31 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_32 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_prefix_preservation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_trailing_comment @ linux-x86_64 +lib2to3.tests.test_fixers.Test_dict.test_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_bare_except @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_bare_except_and_else_finally @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_list_unpack @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_multi_class @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_multi_fixed_excepts_before_bare_except @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_one_line_suites @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_prefix_preservation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_simple @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_simple_no_space_before_target @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_tuple_unpack @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_unchanged_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_unchanged_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_unchanged_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_weird_target_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_weird_target_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_except.test_weird_target_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exec.test_basic @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exec.test_complex_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exec.test_complex_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exec.test_prefix_preservation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exec.test_unchanged_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exec.test_unchanged_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exec.test_unchanged_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exec.test_unchanged_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exec.test_with_globals @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exec.test_with_globals_locals @ linux-x86_64 +lib2to3.tests.test_fixers.Test_execfile.test_conversion @ linux-x86_64 +lib2to3.tests.test_fixers.Test_execfile.test_spacing @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exitfunc.test_comments @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exitfunc.test_complex_expression @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exitfunc.test_in_a_function @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exitfunc.test_names_import @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exitfunc.test_no_sys_import @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exitfunc.test_simple @ linux-x86_64 +lib2to3.tests.test_fixers.Test_exitfunc.test_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_filter.test_filter_basic @ linux-x86_64 +lib2to3.tests.test_fixers.Test_filter.test_filter_nochange @ linux-x86_64 +lib2to3.tests.test_fixers.Test_filter.test_filter_trailers @ linux-x86_64 +lib2to3.tests.test_fixers.Test_filter.test_future_builtins @ linux-x86_64 +lib2to3.tests.test_fixers.Test_filter.test_prefix_preservation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_funcattrs.test @ linux-x86_64 +lib2to3.tests.test_fixers.Test_funcattrs.test_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_future.test_future @ linux-x86_64 +lib2to3.tests.test_fixers.Test_future.test_run_order @ linux-x86_64 +lib2to3.tests.test_fixers.Test_getcwdu.test_basic @ linux-x86_64 +lib2to3.tests.test_fixers.Test_getcwdu.test_comment @ linux-x86_64 +lib2to3.tests.test_fixers.Test_getcwdu.test_indentation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_getcwdu.test_multilation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_getcwdu.test_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_has_key.test_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_has_key.test_10 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_has_key.test_11 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_has_key.test_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_has_key.test_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_has_key.test_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_has_key.test_5 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_has_key.test_6 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_has_key.test_7 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_has_key.test_8 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_has_key.test_9 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_eq_expression @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_eq_reverse @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_eq_simple @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_is_expression @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_is_not_expression @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_is_not_reverse @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_is_not_simple @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_is_reverse @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_is_simple @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_ne_expression @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_ne_reverse @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_ne_simple @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_sort_list_call @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_sort_simple_expr @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_sort_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_type_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_while @ linux-x86_64 +lib2to3.tests.test_fixers.Test_idioms.test_while_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_already_relative_import @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_comments_and_indent @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_dotted_from @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_dotted_import @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_dotted_import_as @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_files_checked @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_from @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_from_as @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_import @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_import_as @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_import_from_package @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_in_package @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_local_and_absolute @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_not_in_package @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_prefix @ linux-x86_64 +lib2to3.tests.test_fixers.Test_import.test_with_absolute_import_enabled @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports.test_import_from @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports.test_import_from_as @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports.test_import_module @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports.test_import_module_as @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports.test_import_module_usage @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports.test_multiple_imports @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports.test_multiple_imports_as @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports.test_star @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports2.test_import_from @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports2.test_import_from_as @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports2.test_import_module @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports2.test_import_module_as @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports2.test_import_module_usage @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports2.test_star @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports_fixer_order.test_after_local_imports_refactoring @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports_fixer_order.test_import_from @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports_fixer_order.test_import_from_as @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports_fixer_order.test_import_module @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports_fixer_order.test_import_module_as @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports_fixer_order.test_import_module_usage @ linux-x86_64 +lib2to3.tests.test_fixers.Test_imports_fixer_order.test_star @ linux-x86_64 +lib2to3.tests.test_fixers.Test_input.test_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_input.test_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_input.test_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_input.test_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_input.test_idempotency @ linux-x86_64 +lib2to3.tests.test_fixers.Test_input.test_prefix_preservation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_input.test_trailing_comment @ linux-x86_64 +lib2to3.tests.test_fixers.Test_intern.test @ linux-x86_64 +lib2to3.tests.test_fixers.Test_intern.test_prefix_preservation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_intern.test_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_isinstance.test_prefix_preservation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_isinstance.test_remove_multiple_items @ linux-x86_64 +lib2to3.tests.test_fixers.Test_isinstance.test_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_itertools.test_0 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_itertools.test_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_itertools.test_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_itertools.test_qualified @ linux-x86_64 +lib2to3.tests.test_fixers.Test_itertools.test_run_order @ linux-x86_64 +lib2to3.tests.test_fixers.Test_itertools.test_space_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_itertools.test_space_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_itertools_imports.test_comments @ linux-x86_64 +lib2to3.tests.test_fixers.Test_itertools_imports.test_ifilter_and_zip_longest @ linux-x86_64 +lib2to3.tests.test_fixers.Test_itertools_imports.test_import_as @ linux-x86_64 +lib2to3.tests.test_fixers.Test_itertools_imports.test_import_star @ linux-x86_64 +lib2to3.tests.test_fixers.Test_itertools_imports.test_none @ linux-x86_64 +lib2to3.tests.test_fixers.Test_itertools_imports.test_reduced @ linux-x86_64 +lib2to3.tests.test_fixers.Test_itertools_imports.test_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_long.test_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_long.test_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_long.test_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_long.test_prefix_preservation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_long.test_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_map.test_None_with_multiple_arguments @ linux-x86_64 +lib2to3.tests.test_fixers.Test_map.test_future_builtins @ linux-x86_64 +lib2to3.tests.test_fixers.Test_map.test_map_basic @ linux-x86_64 +lib2to3.tests.test_fixers.Test_map.test_map_nochange @ linux-x86_64 +lib2to3.tests.test_fixers.Test_map.test_map_trailers @ linux-x86_64 +lib2to3.tests.test_fixers.Test_map.test_prefix_preservation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_map.test_trailing_comment @ linux-x86_64 +lib2to3.tests.test_fixers.Test_metaclass.test_comments @ linux-x86_64 +lib2to3.tests.test_fixers.Test_metaclass.test_meta @ linux-x86_64 +lib2to3.tests.test_fixers.Test_metaclass.test_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_methodattrs.test @ linux-x86_64 +lib2to3.tests.test_fixers.Test_methodattrs.test_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_ne.test_basic @ linux-x86_64 +lib2to3.tests.test_fixers.Test_ne.test_chained @ linux-x86_64 +lib2to3.tests.test_fixers.Test_ne.test_no_spaces @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_5 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_6 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_assign_to_next @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_assign_to_next_in_list @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_assign_to_next_in_tuple @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_builtin_assign @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_builtin_assign_in_list @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_builtin_assign_in_tuple @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_method_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_method_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_method_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_method_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_method_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_noncall_access_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_noncall_access_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_noncall_access_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_prefix_preservation_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_prefix_preservation_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_prefix_preservation_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_prefix_preservation_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_prefix_preservation_5 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_prefix_preservation_6 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_assign_list_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_assign_list_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_assign_simple @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_assign_tuple_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_assign_tuple_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_for_simple @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_for_tuple_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_for_tuple_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_funcdef_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_funcdef_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_global_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_global_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_import_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_import_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_import_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_import_from_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_import_from_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_import_from_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_next.test_shadowing_import_from_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_nonzero.test_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_nonzero.test_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_nonzero.test_unchanged_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_nonzero.test_unchanged_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_nonzero.test_unchanged_func @ linux-x86_64 +lib2to3.tests.test_fixers.Test_numliterals.test_comments_and_spacing @ linux-x86_64 +lib2to3.tests.test_fixers.Test_numliterals.test_long_hex @ linux-x86_64 +lib2to3.tests.test_fixers.Test_numliterals.test_long_int_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_numliterals.test_long_int_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_numliterals.test_octal_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_numliterals.test_unchanged_complex_bare @ linux-x86_64 +lib2to3.tests.test_fixers.Test_numliterals.test_unchanged_complex_float @ linux-x86_64 +lib2to3.tests.test_fixers.Test_numliterals.test_unchanged_complex_int @ linux-x86_64 +lib2to3.tests.test_fixers.Test_numliterals.test_unchanged_exp @ linux-x86_64 +lib2to3.tests.test_fixers.Test_numliterals.test_unchanged_float @ linux-x86_64 +lib2to3.tests.test_fixers.Test_numliterals.test_unchanged_hex @ linux-x86_64 +lib2to3.tests.test_fixers.Test_numliterals.test_unchanged_int @ linux-x86_64 +lib2to3.tests.test_fixers.Test_numliterals.test_unchanged_octal @ linux-x86_64 +lib2to3.tests.test_fixers.Test_operator.test_bare_isCallable @ linux-x86_64 +lib2to3.tests.test_fixers.Test_operator.test_bare_operator_irepeat @ linux-x86_64 +lib2to3.tests.test_fixers.Test_operator.test_bare_operator_isMappingType @ linux-x86_64 +lib2to3.tests.test_fixers.Test_operator.test_bare_operator_isNumberType @ linux-x86_64 +lib2to3.tests.test_fixers.Test_operator.test_bare_operator_isSequenceType @ linux-x86_64 +lib2to3.tests.test_fixers.Test_operator.test_bare_operator_repeat @ linux-x86_64 +lib2to3.tests.test_fixers.Test_operator.test_bare_sequenceIncludes @ linux-x86_64 +lib2to3.tests.test_fixers.Test_operator.test_operator_irepeat @ linux-x86_64 +lib2to3.tests.test_fixers.Test_operator.test_operator_isCallable @ linux-x86_64 +lib2to3.tests.test_fixers.Test_operator.test_operator_isMappingType @ linux-x86_64 +lib2to3.tests.test_fixers.Test_operator.test_operator_isNumberType @ linux-x86_64 +lib2to3.tests.test_fixers.Test_operator.test_operator_isSequenceType @ linux-x86_64 +lib2to3.tests.test_fixers.Test_operator.test_operator_repeat @ linux-x86_64 +lib2to3.tests.test_fixers.Test_operator.test_operator_sequenceIncludes @ linux-x86_64 +lib2to3.tests.test_fixers.Test_paren.test_0 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_paren.test_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_paren.test_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_paren.test_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_paren.test_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_paren.test_5 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_paren.test_6 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_paren.test_unchanged_0 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_paren.test_unchanged_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_paren.test_unchanged_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_paren.test_unchanged_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_paren.test_unchanged_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_5 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_idempotency @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_idempotency_print_as_function @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_no_trailing_comma @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_prefix_preservation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_spaces_before_file @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_trailing_comma_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_trailing_comma_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_trailing_comma_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_tuple @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_vargs_without_trailing_comma @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_with_future_print_function @ linux-x86_64 +lib2to3.tests.test_fixers.Test_print.test_with_trailing_comma @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_None_value @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_basic @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_prefix_preservation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_string_exc @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_string_exc_val @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_string_exc_val_tb @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_tb_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_tb_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_tb_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_tb_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_tb_5 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_tb_6 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_tuple_detection @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_tuple_exc_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_tuple_exc_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_tuple_value @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raise.test_with_comments @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raw_input.test_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raw_input.test_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raw_input.test_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raw_input.test_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raw_input.test_5 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raw_input.test_6 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raw_input.test_8 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_raw_input.test_prefix_preservation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_reduce.test_bug_7253 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_reduce.test_call_with_lambda @ linux-x86_64 +lib2to3.tests.test_fixers.Test_reduce.test_simple_call @ linux-x86_64 +lib2to3.tests.test_fixers.Test_reduce.test_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_reload.test @ linux-x86_64 +lib2to3.tests.test_fixers.Test_reload.test_comment @ linux-x86_64 +lib2to3.tests.test_fixers.Test_reload.test_space @ linux-x86_64 +lib2to3.tests.test_fixers.Test_reload.test_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_renames.test_import_from @ linux-x86_64 +lib2to3.tests.test_fixers.Test_renames.test_import_from_as @ linux-x86_64 +lib2to3.tests.test_fixers.Test_renames.test_import_module_usage @ linux-x86_64 +lib2to3.tests.test_fixers.Test_repr.test_complex @ linux-x86_64 +lib2to3.tests.test_fixers.Test_repr.test_nested @ linux-x86_64 +lib2to3.tests.test_fixers.Test_repr.test_nested_tuples @ linux-x86_64 +lib2to3.tests.test_fixers.Test_repr.test_prefix_preservation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_repr.test_simple_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_repr.test_simple_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_repr.test_tuple @ linux-x86_64 +lib2to3.tests.test_fixers.Test_set_literal.test_basic @ linux-x86_64 +lib2to3.tests.test_fixers.Test_set_literal.test_comments @ linux-x86_64 +lib2to3.tests.test_fixers.Test_set_literal.test_listcomps @ linux-x86_64 +lib2to3.tests.test_fixers.Test_set_literal.test_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_set_literal.test_whitespace @ linux-x86_64 +lib2to3.tests.test_fixers.Test_standarderror.test @ linux-x86_64 +lib2to3.tests.test_fixers.Test_sys_exc.test_0 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_sys_exc.test_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_sys_exc.test_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_sys_exc.test_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_sys_exc.test_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_sys_exc.test_5 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_tb_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_tb_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_tb_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_tb_4 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_tb_5 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_tb_6 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_tb_7 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_tb_8 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_untouched_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_untouched_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_untouched_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_warn_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_warn_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_throw.test_warn_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_docstring @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_keywords @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_lambda_nested @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_lambda_nested_multi_use @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_lambda_no_change @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_lambda_one_tuple @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_lambda_parens_single_arg @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_lambda_simple @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_lambda_simple_multi_use @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_lambda_simple_reverse @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_multi_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_multi_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_semicolon @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_unchanged_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_unchanged_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_unchanged_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_tuple_params.test_varargs @ linux-x86_64 +lib2to3.tests.test_fixers.Test_unicode.test_bytes_literal_escape_u @ linux-x86_64 +lib2to3.tests.test_fixers.Test_unicode.test_native_literal_escape_u @ linux-x86_64 +lib2to3.tests.test_fixers.Test_unicode.test_native_unicode_literal_escape_u @ linux-x86_64 +lib2to3.tests.test_fixers.Test_unicode.test_unichr @ linux-x86_64 +lib2to3.tests.test_fixers.Test_unicode.test_unicode_call @ linux-x86_64 +lib2to3.tests.test_fixers.Test_unicode.test_unicode_literal_1 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_unicode.test_unicode_literal_2 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_unicode.test_unicode_literal_3 @ linux-x86_64 +lib2to3.tests.test_fixers.Test_unicode.test_unicode_literal_escape_u @ linux-x86_64 +lib2to3.tests.test_fixers.Test_unicode.test_whitespace @ linux-x86_64 +lib2to3.tests.test_fixers.Test_urllib.test_import_from @ linux-x86_64 +lib2to3.tests.test_fixers.Test_urllib.test_import_from_as @ linux-x86_64 +lib2to3.tests.test_fixers.Test_urllib.test_import_module @ linux-x86_64 +lib2to3.tests.test_fixers.Test_urllib.test_import_module_as @ linux-x86_64 +lib2to3.tests.test_fixers.Test_urllib.test_import_module_usage @ linux-x86_64 +lib2to3.tests.test_fixers.Test_urllib.test_indented @ linux-x86_64 +lib2to3.tests.test_fixers.Test_urllib.test_single_import @ linux-x86_64 +lib2to3.tests.test_fixers.Test_urllib.test_star @ linux-x86_64 +lib2to3.tests.test_fixers.Test_xrange.test_in_consuming_context @ linux-x86_64 +lib2to3.tests.test_fixers.Test_xrange.test_in_contains_test @ linux-x86_64 +lib2to3.tests.test_fixers.Test_xrange.test_prefix_preservation @ linux-x86_64 +lib2to3.tests.test_fixers.Test_xrange.test_range_in_for @ linux-x86_64 +lib2to3.tests.test_fixers.Test_xrange.test_single_arg @ linux-x86_64 +lib2to3.tests.test_fixers.Test_xrange.test_three_args @ linux-x86_64 +lib2to3.tests.test_fixers.Test_xrange.test_two_args @ linux-x86_64 +lib2to3.tests.test_fixers.Test_xrange.test_wrap_in_list @ linux-x86_64 +lib2to3.tests.test_fixers.Test_xrange.test_xrange_in_for @ linux-x86_64 +lib2to3.tests.test_fixers.Test_xrange_with_reduce.test_double_transform @ linux-x86_64 +lib2to3.tests.test_fixers.Test_xreadlines.test_attr_ref @ linux-x86_64 +lib2to3.tests.test_fixers.Test_xreadlines.test_call @ linux-x86_64 +lib2to3.tests.test_fixers.Test_xreadlines.test_unchanged @ linux-x86_64 +lib2to3.tests.test_fixers.Test_zip.test_future_builtins @ linux-x86_64 +lib2to3.tests.test_fixers.Test_zip.test_zip_basic @ linux-x86_64 +lib2to3.tests.test_fixers.Test_zip.test_zip_nochange @ linux-x86_64 +lib2to3.tests.test_fixers.Test_zip.test_zip_trailers @ linux-x86_64 +lib2to3.tests.test_parser.TestAsyncAwait.test_async_for @ linux-x86_64 +lib2to3.tests.test_parser.TestAsyncAwait.test_async_generator @ linux-x86_64 +lib2to3.tests.test_parser.TestAsyncAwait.test_async_var @ linux-x86_64 +lib2to3.tests.test_parser.TestAsyncAwait.test_async_with @ linux-x86_64 +lib2to3.tests.test_parser.TestAsyncAwait.test_await_expr @ linux-x86_64 +lib2to3.tests.test_parser.TestClassDef.test_new_syntax @ linux-x86_64 +lib2to3.tests.test_parser.TestDriver.test_formfeed @ linux-x86_64 +lib2to3.tests.test_parser.TestExcept.test_new @ linux-x86_64 +lib2to3.tests.test_parser.TestExcept.test_old @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_1 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_10 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_11 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_12 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_13 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_14 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_15 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_16 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_17 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_18 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_19 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_2 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_20 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_21 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_3 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_4 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_5 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_6 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_7 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_8 @ linux-x86_64 +lib2to3.tests.test_parser.TestFunctionAnnotations.test_9 @ linux-x86_64 +lib2to3.tests.test_parser.TestIdentifier.test_non_ascii_identifiers @ linux-x86_64 +lib2to3.tests.test_parser.TestLiterals.test_multiline_bytes_literals @ linux-x86_64 +lib2to3.tests.test_parser.TestLiterals.test_multiline_bytes_tripquote_literals @ linux-x86_64 +lib2to3.tests.test_parser.TestLiterals.test_multiline_str_literals @ linux-x86_64 +lib2to3.tests.test_parser.TestMatrixMultiplication.test_matrix_multiplication_operator @ linux-x86_64 +lib2to3.tests.test_parser.TestNamedAssignments.test_named_assignment_generator @ linux-x86_64 +lib2to3.tests.test_parser.TestNamedAssignments.test_named_assignment_if @ linux-x86_64 +lib2to3.tests.test_parser.TestNamedAssignments.test_named_assignment_listcomp @ linux-x86_64 +lib2to3.tests.test_parser.TestNamedAssignments.test_named_assignment_while @ linux-x86_64 +lib2to3.tests.test_parser.TestNumericLiterals.test_new_binary_notation @ linux-x86_64 +lib2to3.tests.test_parser.TestNumericLiterals.test_new_octal_notation @ linux-x86_64 +lib2to3.tests.test_parser.TestParserIdempotency.test_all_project_files @ linux-x86_64 +lib2to3.tests.test_parser.TestParserIdempotency.test_extended_unpacking @ linux-x86_64 +lib2to3.tests.test_parser.TestPgen2Caching.test_load_grammar_from_pickle @ linux-x86_64 +!lib2to3.tests.test_parser.TestPgen2Caching.test_load_grammar_from_subprocess @ linux-x86_64 +lib2to3.tests.test_parser.TestPgen2Caching.test_load_grammar_from_txt_file @ linux-x86_64 +lib2to3.tests.test_parser.TestPgen2Caching.test_load_packaged_grammar @ linux-x86_64 +lib2to3.tests.test_parser.TestPickleableException.test_ParseError @ linux-x86_64 +lib2to3.tests.test_parser.TestPositionalOnlyArgs.test_all_markers @ linux-x86_64 +lib2to3.tests.test_parser.TestPositionalOnlyArgs.test_all_with_args_and_kwargs @ linux-x86_64 +lib2to3.tests.test_parser.TestPositionalOnlyArgs.test_lambda_soup @ linux-x86_64 +lib2to3.tests.test_parser.TestPositionalOnlyArgs.test_one_pos_only_arg @ linux-x86_64 +lib2to3.tests.test_parser.TestPositionalOnlyArgs.test_only_positional_or_keyword @ linux-x86_64 +lib2to3.tests.test_parser.TestRaiseChanges.test_2x_style_1 @ linux-x86_64 +lib2to3.tests.test_parser.TestRaiseChanges.test_2x_style_2 @ linux-x86_64 +lib2to3.tests.test_parser.TestRaiseChanges.test_2x_style_3 @ linux-x86_64 +lib2to3.tests.test_parser.TestRaiseChanges.test_2x_style_invalid_1 @ linux-x86_64 +lib2to3.tests.test_parser.TestRaiseChanges.test_3x_style @ linux-x86_64 +lib2to3.tests.test_parser.TestRaiseChanges.test_3x_style_invalid_1 @ linux-x86_64 +lib2to3.tests.test_parser.TestRaiseChanges.test_3x_style_invalid_2 @ linux-x86_64 +lib2to3.tests.test_parser.TestRaiseChanges.test_3x_style_invalid_3 @ linux-x86_64 +lib2to3.tests.test_parser.TestRaiseChanges.test_3x_style_invalid_4 @ linux-x86_64 +lib2to3.tests.test_parser.TestSetLiteral.test_1 @ linux-x86_64 +lib2to3.tests.test_parser.TestSetLiteral.test_2 @ linux-x86_64 +lib2to3.tests.test_parser.TestSetLiteral.test_3 @ linux-x86_64 +lib2to3.tests.test_parser.TestSetLiteral.test_4 @ linux-x86_64 +lib2to3.tests.test_parser.TestStringLiterals.test_lit @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_argument_unpacking_1 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_argument_unpacking_2 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_argument_unpacking_3 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_complex_double_star_expression @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_complex_star_expression @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_dict_display_1 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_dict_display_2 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_double_star_dict_literal @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_double_star_dict_literal_after_keywords @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_double_star_expression @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_list_display @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_mid_positional_star @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_set_display @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_star_expression @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_1 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_2 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_3 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_4 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_5 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_6 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_7 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_8 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_9 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_lambda_1 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_lambda_2 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_lambda_3 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_lambda_4 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_lambda_5 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_lambda_6 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_lambda_7 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_lambda_8 @ linux-x86_64 +lib2to3.tests.test_parser.TestUnpackingGeneralizations.test_trailing_commas_lambda_9 @ linux-x86_64 +lib2to3.tests.test_parser.TestVarAnnotations.test_1 @ linux-x86_64 +lib2to3.tests.test_parser.TestVarAnnotations.test_2 @ linux-x86_64 +lib2to3.tests.test_parser.TestVarAnnotations.test_3 @ linux-x86_64 +lib2to3.tests.test_parser.TestVarAnnotations.test_4 @ linux-x86_64 +lib2to3.tests.test_parser.TestVarAnnotations.test_5 @ linux-x86_64 +lib2to3.tests.test_parser.TestVarAnnotations.test_6 @ linux-x86_64 +lib2to3.tests.test_parser.TestYieldFrom.test_yield_from @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_changed @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_depth @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_get_suffix @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_instantiate_base @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_leaf @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_leaf_constructor_prefix @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_leaf_equality @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_leaf_next_sibling @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_leaf_prefix @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_leaf_prev_sibling @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_leaf_repr @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_leaf_str @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_leaf_str_numeric_value @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_leaves @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_node @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_node_append_child @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_node_constructor_prefix @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_node_equality @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_node_insert_child @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_node_next_sibling @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_node_prefix @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_node_prev_sibling @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_node_recursive_equality @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_node_repr @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_node_set_child @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_node_str @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_post_order @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_pre_order @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_remove @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_remove_parentless @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_replace @ linux-x86_64 +lib2to3.tests.test_pytree.TestNodes.test_replace_with_list @ linux-x86_64 +lib2to3.tests.test_pytree.TestPatterns.test_basic_patterns @ linux-x86_64 +lib2to3.tests.test_pytree.TestPatterns.test_generate_matches @ linux-x86_64 +lib2to3.tests.test_pytree.TestPatterns.test_has_key_example @ linux-x86_64 +lib2to3.tests.test_pytree.TestPatterns.test_wildcard @ linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_detect_future_features @ linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_exec_function_option @ linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_explicit @ linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_fixer_loading @ linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_fixer_loading_helpers @ linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_get_headnode_dict @ linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_naughty_fixers @ linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_print_function_option @ linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_refactor_dir @ linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_refactor_docstring @ linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_refactor_file @ linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_refactor_file_write_unchanged_file @ linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_refactor_stdin @ linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_refactor_string @ linux-x86_64 +lib2to3.tests.test_refactor.TestRefactoringTool.test_write_unchanged_files_option @ linux-x86_64 +lib2to3.tests.test_util.Test_Attr.test @ linux-x86_64 +lib2to3.tests.test_util.Test_Attr.test_returns @ linux-x86_64 +lib2to3.tests.test_util.Test_Call.test @ linux-x86_64 +lib2to3.tests.test_util.Test_Name.test @ linux-x86_64 +lib2to3.tests.test_util.Test_does_tree_import.test_in_function @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_class_def @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_for @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_for_nested @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_from_import @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_from_import_as @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_from_import_as_with_package @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_from_import_with_package @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_function_def @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_if @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_if_nested @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_import_as @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_import_as_with_package @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_invalid_assignments @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_list_assignment @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_simple_assignment @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_simple_import @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_simple_import_with_package @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_try_except @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_try_except_finally @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_try_except_finally_nested @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_try_except_nested @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_tuple_assignment @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_while @ linux-x86_64 +lib2to3.tests.test_util.Test_find_binding.test_while_nested @ linux-x86_64 +lib2to3.tests.test_util.Test_find_indentation.test_nothing @ linux-x86_64 +lib2to3.tests.test_util.Test_find_indentation.test_simple @ linux-x86_64 +lib2to3.tests.test_util.Test_is_list.test_invalid @ linux-x86_64 +lib2to3.tests.test_util.Test_is_list.test_valid @ linux-x86_64 +lib2to3.tests.test_util.Test_is_tuple.test_invalid @ linux-x86_64 +lib2to3.tests.test_util.Test_is_tuple.test_valid @ linux-x86_64 +lib2to3.tests.test_util.Test_touch_import.test_after_docstring @ linux-x86_64 +lib2to3.tests.test_util.Test_touch_import.test_after_imports @ linux-x86_64 +lib2to3.tests.test_util.Test_touch_import.test_beginning @ linux-x86_64 +lib2to3.tests.test_util.Test_touch_import.test_from_import @ linux-x86_64 +lib2to3.tests.test_util.Test_touch_import.test_name_import @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_linecache.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_linecache.txt new file mode 100644 index 0000000000..36349d56b2 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_linecache.txt @@ -0,0 +1,24 @@ +test.test_linecache.BadUnicode_NoDeclaration.test_getline @ linux-x86_64 +test.test_linecache.BadUnicode_NoDeclaration.test_getlines @ linux-x86_64 +test.test_linecache.BadUnicode_WithDeclaration.test_getline @ linux-x86_64 +test.test_linecache.BadUnicode_WithDeclaration.test_getlines @ linux-x86_64 +test.test_linecache.EmptyFile.test_getline @ linux-x86_64 +test.test_linecache.EmptyFile.test_getlines @ linux-x86_64 +test.test_linecache.GoodUnicode.test_getline @ linux-x86_64 +test.test_linecache.GoodUnicode.test_getlines @ linux-x86_64 +test.test_linecache.LineCacheInvalidationTests.test_checkcache_for_deleted_file @ linux-x86_64 +test.test_linecache.LineCacheInvalidationTests.test_checkcache_for_modified_file @ linux-x86_64 +test.test_linecache.LineCacheInvalidationTests.test_checkcache_with_no_parameter @ linux-x86_64 +test.test_linecache.LineCacheTests.test_checkcache @ linux-x86_64 +test.test_linecache.LineCacheTests.test_clearcache @ linux-x86_64 +test.test_linecache.LineCacheTests.test_getline @ linux-x86_64 +test.test_linecache.LineCacheTests.test_lazycache_already_cached @ linux-x86_64 +test.test_linecache.LineCacheTests.test_lazycache_bad_filename @ linux-x86_64 +test.test_linecache.LineCacheTests.test_lazycache_check @ linux-x86_64 +test.test_linecache.LineCacheTests.test_lazycache_no_globals @ linux-x86_64 +test.test_linecache.LineCacheTests.test_lazycache_provide_after_failed_lookup @ linux-x86_64 +test.test_linecache.LineCacheTests.test_lazycache_smoke @ linux-x86_64 +test.test_linecache.LineCacheTests.test_memoryerror @ linux-x86_64 +test.test_linecache.LineCacheTests.test_no_ending_newline @ linux-x86_64 +test.test_linecache.SingleEmptyLine.test_getline @ linux-x86_64 +test.test_linecache.SingleEmptyLine.test_getlines @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_list.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_list.txt new file mode 100644 index 0000000000..8cf804c93f --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_list.txt @@ -0,0 +1,54 @@ +test.test_list.ListTest.test_addmul @ linux-x86_64 +test.test_list.ListTest.test_append @ linux-x86_64 +test.test_list.ListTest.test_basic @ linux-x86_64 +test.test_list.ListTest.test_clear @ linux-x86_64 +test.test_list.ListTest.test_constructor_exception_handling @ linux-x86_64 +test.test_list.ListTest.test_constructors @ linux-x86_64 +test.test_list.ListTest.test_contains @ linux-x86_64 +test.test_list.ListTest.test_contains_fake @ linux-x86_64 +test.test_list.ListTest.test_contains_order @ linux-x86_64 +test.test_list.ListTest.test_copy @ linux-x86_64 +test.test_list.ListTest.test_count @ linux-x86_64 +test.test_list.ListTest.test_count_index_remove_crashes @ linux-x86_64 +test.test_list.ListTest.test_delitem @ linux-x86_64 +test.test_list.ListTest.test_delslice @ linux-x86_64 +test.test_list.ListTest.test_equal_operator_modifying_operand @ linux-x86_64 +test.test_list.ListTest.test_exhausted_iterator @ linux-x86_64 +test.test_list.ListTest.test_extend @ linux-x86_64 +test.test_list.ListTest.test_extendedslicing @ linux-x86_64 +test.test_list.ListTest.test_getitem @ linux-x86_64 +test.test_list.ListTest.test_getitem_error @ linux-x86_64 +test.test_list.ListTest.test_getitemoverwriteiter @ linux-x86_64 +test.test_list.ListTest.test_getslice @ linux-x86_64 +test.test_list.ListTest.test_iadd @ linux-x86_64 +test.test_list.ListTest.test_identity @ linux-x86_64 +test.test_list.ListTest.test_imul @ linux-x86_64 +test.test_list.ListTest.test_index @ linux-x86_64 +test.test_list.ListTest.test_init @ linux-x86_64 +test.test_list.ListTest.test_insert @ linux-x86_64 +test.test_list.ListTest.test_iterator_pickle @ linux-x86_64 +test.test_list.ListTest.test_keyword_args @ linux-x86_64 +test.test_list.ListTest.test_len @ linux-x86_64 +test.test_list.ListTest.test_list_resize_overflow @ linux-x86_64 +test.test_list.ListTest.test_minmax @ linux-x86_64 +test.test_list.ListTest.test_no_comdat_folding @ linux-x86_64 +test.test_list.ListTest.test_overflow @ linux-x86_64 +test.test_list.ListTest.test_pickle @ linux-x86_64 +test.test_list.ListTest.test_pop @ linux-x86_64 +test.test_list.ListTest.test_remove @ linux-x86_64 +test.test_list.ListTest.test_repeat @ linux-x86_64 +test.test_list.ListTest.test_repr @ linux-x86_64 +!test.test_list.ListTest.test_repr_deep @ linux-x86_64 +test.test_list.ListTest.test_repr_large @ linux-x86_64 +test.test_list.ListTest.test_reverse @ linux-x86_64 +test.test_list.ListTest.test_reversed @ linux-x86_64 +test.test_list.ListTest.test_reversed_pickle @ linux-x86_64 +test.test_list.ListTest.test_set_subscript @ linux-x86_64 +test.test_list.ListTest.test_setitem @ linux-x86_64 +test.test_list.ListTest.test_setitem_error @ linux-x86_64 +test.test_list.ListTest.test_setslice @ linux-x86_64 +test.test_list.ListTest.test_slice @ linux-x86_64 +test.test_list.ListTest.test_sort @ linux-x86_64 +test.test_list.ListTest.test_step_overflow @ linux-x86_64 +test.test_list.ListTest.test_subscript @ linux-x86_64 +test.test_list.ListTest.test_truth @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_listcomps.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_listcomps.txt new file mode 100644 index 0000000000..bcd126d9d0 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_listcomps.txt @@ -0,0 +1 @@ +DocTestCase.test.test_listcomps.__test__.doctests @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_locale.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_locale.txt new file mode 100644 index 0000000000..6b7019e95f --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_locale.txt @@ -0,0 +1,59 @@ +test.test_locale.NormalizeTest.test_c @ linux-x86_64 +test.test_locale.NormalizeTest.test_devanagari_modifier @ linux-x86_64 +test.test_locale.NormalizeTest.test_empty @ linux-x86_64 +test.test_locale.NormalizeTest.test_english @ linux-x86_64 +test.test_locale.NormalizeTest.test_euc_encoding @ linux-x86_64 +test.test_locale.NormalizeTest.test_euro_modifier @ linux-x86_64 +test.test_locale.NormalizeTest.test_hyphenated_encoding @ linux-x86_64 +test.test_locale.NormalizeTest.test_japanese @ linux-x86_64 +test.test_locale.NormalizeTest.test_latin_modifier @ linux-x86_64 +test.test_locale.NormalizeTest.test_locale_alias @ linux-x86_64 +test.test_locale.NormalizeTest.test_valencia_modifier @ linux-x86_64 +test.test_locale.TestCDelocalizeTest.test_atof @ linux-x86_64 +test.test_locale.TestCDelocalizeTest.test_atoi @ linux-x86_64 +test.test_locale.TestCDelocalizeTest.test_delocalize @ linux-x86_64 +test.test_locale.TestCLocalize.test_localize @ linux-x86_64 +test.test_locale.TestCNumberFormatting.test_grouping @ linux-x86_64 +test.test_locale.TestCNumberFormatting.test_grouping_and_padding @ linux-x86_64 +test.test_locale.TestEnUSDelocalize.test_atof @ linux-x86_64 +test.test_locale.TestEnUSDelocalize.test_atoi @ linux-x86_64 +test.test_locale.TestEnUSDelocalize.test_delocalize @ linux-x86_64 +test.test_locale.TestEnUSLocalize.test_localize @ linux-x86_64 +test.test_locale.TestEnUSNumberFormatting.test_complex_formatting @ linux-x86_64 +test.test_locale.TestEnUSNumberFormatting.test_currency @ linux-x86_64 +test.test_locale.TestEnUSNumberFormatting.test_format_deprecation @ linux-x86_64 +test.test_locale.TestEnUSNumberFormatting.test_grouping @ linux-x86_64 +test.test_locale.TestEnUSNumberFormatting.test_grouping_and_padding @ linux-x86_64 +test.test_locale.TestEnUSNumberFormatting.test_integer_grouping @ linux-x86_64 +test.test_locale.TestEnUSNumberFormatting.test_integer_grouping_and_padding @ linux-x86_64 +test.test_locale.TestEnUSNumberFormatting.test_padding @ linux-x86_64 +test.test_locale.TestEnUSNumberFormatting.test_simple @ linux-x86_64 +test.test_locale.TestFormatPatternArg.test_onlyOnePattern @ linux-x86_64 +test.test_locale.TestFrFRNumberFormatting.test_currency @ linux-x86_64 +test.test_locale.TestFrFRNumberFormatting.test_decimal_point @ linux-x86_64 +test.test_locale.TestFrFRNumberFormatting.test_grouping @ linux-x86_64 +test.test_locale.TestFrFRNumberFormatting.test_grouping_and_padding @ linux-x86_64 +test.test_locale.TestFrFRNumberFormatting.test_integer_grouping @ linux-x86_64 +test.test_locale.TestFrFRNumberFormatting.test_integer_grouping_and_padding @ linux-x86_64 +test.test_locale.TestLocaleFormatString.test_mapping @ linux-x86_64 +test.test_locale.TestLocaleFormatString.test_percent_escape @ linux-x86_64 +test.test_locale.TestMiscellaneous.test_defaults_UTF8 @ linux-x86_64 +test.test_locale.TestMiscellaneous.test_getencoding @ linux-x86_64 +test.test_locale.TestMiscellaneous.test_getpreferredencoding @ linux-x86_64 +test.test_locale.TestMiscellaneous.test_getsetlocale_issue1813 @ linux-x86_64 +test.test_locale.TestMiscellaneous.test_invalid_iterable_in_localetuple @ linux-x86_64 +test.test_locale.TestMiscellaneous.test_invalid_locale_format_in_localetuple @ linux-x86_64 +test.test_locale.TestMiscellaneous.test_setlocale_category @ linux-x86_64 +test.test_locale.TestMiscellaneous.test_strcoll_3303 @ linux-x86_64 +test.test_locale.TestNumberFormatting.test_complex_formatting @ linux-x86_64 +test.test_locale.TestNumberFormatting.test_format_deprecation @ linux-x86_64 +test.test_locale.TestNumberFormatting.test_grouping @ linux-x86_64 +test.test_locale.TestNumberFormatting.test_grouping_and_padding @ linux-x86_64 +test.test_locale.TestNumberFormatting.test_integer_grouping @ linux-x86_64 +test.test_locale.TestNumberFormatting.test_integer_grouping_and_padding @ linux-x86_64 +test.test_locale.TestNumberFormatting.test_padding @ linux-x86_64 +test.test_locale.TestNumberFormatting.test_simple @ linux-x86_64 +test.test_locale.TestfrFRDelocalizeTest.test_atof @ linux-x86_64 +test.test_locale.TestfrFRDelocalizeTest.test_atoi @ linux-x86_64 +test.test_locale.TestfrFRDelocalizeTest.test_delocalize @ linux-x86_64 +test.test_locale.TestfrFRLocalize.test_localize @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_logging.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_logging.txt new file mode 100644 index 0000000000..351d580133 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_logging.txt @@ -0,0 +1,216 @@ +test.test_logging.BasicConfigTest.test_critical @ linux-x86_64 +test.test_logging.BasicConfigTest.test_datefmt @ linux-x86_64 +test.test_logging.BasicConfigTest.test_debug @ linux-x86_64 +test.test_logging.BasicConfigTest.test_encoding @ linux-x86_64 +test.test_logging.BasicConfigTest.test_encoding_errors @ linux-x86_64 +test.test_logging.BasicConfigTest.test_encoding_errors_default @ linux-x86_64 +test.test_logging.BasicConfigTest.test_encoding_errors_none @ linux-x86_64 +test.test_logging.BasicConfigTest.test_error @ linux-x86_64 +test.test_logging.BasicConfigTest.test_filemode @ linux-x86_64 +test.test_logging.BasicConfigTest.test_filename @ linux-x86_64 +test.test_logging.BasicConfigTest.test_force @ linux-x86_64 +test.test_logging.BasicConfigTest.test_format @ linux-x86_64 +test.test_logging.BasicConfigTest.test_handlers @ linux-x86_64 +test.test_logging.BasicConfigTest.test_incompatible @ linux-x86_64 +test.test_logging.BasicConfigTest.test_info @ linux-x86_64 +test.test_logging.BasicConfigTest.test_level @ linux-x86_64 +test.test_logging.BasicConfigTest.test_log @ linux-x86_64 +test.test_logging.BasicConfigTest.test_no_kwargs @ linux-x86_64 +test.test_logging.BasicConfigTest.test_stream @ linux-x86_64 +test.test_logging.BasicConfigTest.test_strformatstyle @ linux-x86_64 +test.test_logging.BasicConfigTest.test_stringtemplatestyle @ linux-x86_64 +test.test_logging.BasicConfigTest.test_style @ linux-x86_64 +test.test_logging.BasicConfigTest.test_warning @ linux-x86_64 +test.test_logging.BasicFilterTest.test_callable_filter @ linux-x86_64 +test.test_logging.BasicFilterTest.test_empty_filter @ linux-x86_64 +test.test_logging.BasicFilterTest.test_filter @ linux-x86_64 +test.test_logging.BufferingFormatterTest.test_custom @ linux-x86_64 +test.test_logging.BufferingFormatterTest.test_default @ linux-x86_64 +test.test_logging.BuiltinLevelsTest.test_flat @ linux-x86_64 +test.test_logging.BuiltinLevelsTest.test_issue27935 @ linux-x86_64 +test.test_logging.BuiltinLevelsTest.test_nested_explicit @ linux-x86_64 +test.test_logging.BuiltinLevelsTest.test_nested_inherited @ linux-x86_64 +test.test_logging.BuiltinLevelsTest.test_nested_with_virtual_parent @ linux-x86_64 +test.test_logging.BuiltinLevelsTest.test_regression_22386 @ linux-x86_64 +test.test_logging.BuiltinLevelsTest.test_regression_29220 @ linux-x86_64 +test.test_logging.ChildLoggerTest.test_child_loggers @ linux-x86_64 +test.test_logging.ConfigDictTest.test_90195 @ linux-x86_64 +test.test_logging.ConfigDictTest.test_baseconfig @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config0_ok @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config11_ok @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config12_failure @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config13_failure @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config14_ok @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config15_ok @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config17_ok @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config1_ok @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config2_failure @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config2a_failure @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config2b_failure @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config3_failure @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config4_ok @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config4a_ok @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config5_ok @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config6_failure @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config7_ok @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config_10_ok @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config_8_ok @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config_8a_ok @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config_9_ok @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config_callable_filter_works @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config_filter_method_works @ linux-x86_64 +test.test_logging.ConfigDictTest.test_config_filter_works @ linux-x86_64 +test.test_logging.ConfigDictTest.test_custom_formatter_class_with_validate @ linux-x86_64 +test.test_logging.ConfigDictTest.test_custom_formatter_class_with_validate2 @ linux-x86_64 +test.test_logging.ConfigDictTest.test_custom_formatter_class_with_validate2_with_wrong_fmt @ linux-x86_64 +test.test_logging.ConfigDictTest.test_custom_formatter_class_with_validate3 @ linux-x86_64 +test.test_logging.ConfigDictTest.test_custom_formatter_function_with_validate @ linux-x86_64 +test.test_logging.ConfigDictTest.test_invalid_type_raises @ linux-x86_64 +!test.test_logging.ConfigDictTest.test_listen_config_10_ok @ linux-x86_64 +!test.test_logging.ConfigDictTest.test_listen_config_1_ok @ linux-x86_64 +!test.test_logging.ConfigDictTest.test_listen_verify @ linux-x86_64 +test.test_logging.ConfigDictTest.test_namedtuple @ linux-x86_64 +test.test_logging.ConfigDictTest.test_out_of_order @ linux-x86_64 +test.test_logging.ConfigDictTest.test_out_of_order_with_dollar_style @ linux-x86_64 +test.test_logging.ConfigFileTest.test_config0_ok @ linux-x86_64 +test.test_logging.ConfigFileTest.test_config0_using_cp_ok @ linux-x86_64 +test.test_logging.ConfigFileTest.test_config1_ok @ linux-x86_64 +test.test_logging.ConfigFileTest.test_config2_failure @ linux-x86_64 +test.test_logging.ConfigFileTest.test_config3_failure @ linux-x86_64 +test.test_logging.ConfigFileTest.test_config4_ok @ linux-x86_64 +test.test_logging.ConfigFileTest.test_config5_ok @ linux-x86_64 +test.test_logging.ConfigFileTest.test_config6_ok @ linux-x86_64 +test.test_logging.ConfigFileTest.test_config7_ok @ linux-x86_64 +test.test_logging.ConfigFileTest.test_config8_ok @ linux-x86_64 +test.test_logging.ConfigFileTest.test_config_set_handler_names @ linux-x86_64 +test.test_logging.ConfigFileTest.test_defaults_do_no_interpolation @ linux-x86_64 +test.test_logging.ConfigFileTest.test_exception_if_confg_file_is_empty @ linux-x86_64 +test.test_logging.ConfigFileTest.test_exception_if_confg_file_is_invalid @ linux-x86_64 +test.test_logging.ConfigFileTest.test_exception_if_config_file_does_not_exist @ linux-x86_64 +test.test_logging.ConfigFileTest.test_logger_disabling @ linux-x86_64 +test.test_logging.CustomLevelsAndFiltersTest.test_handler_filter @ linux-x86_64 +test.test_logging.CustomLevelsAndFiltersTest.test_logger_filter @ linux-x86_64 +test.test_logging.CustomLevelsAndFiltersTest.test_specific_filters @ linux-x86_64 +test.test_logging.DatagramHandlerTest.test_output @ linux-x86_64 +test.test_logging.EncodingTest.test_encoding_cyrillic_unicode @ linux-x86_64 +test.test_logging.EncodingTest.test_encoding_plain_file @ linux-x86_64 +test.test_logging.ExceptionTest.test_formatting @ linux-x86_64 +test.test_logging.FileHandlerTest.test_delay @ linux-x86_64 +test.test_logging.FileHandlerTest.test_emit_after_closing_in_write_mode @ linux-x86_64 +test.test_logging.FormatterTest.test_braces @ linux-x86_64 +test.test_logging.FormatterTest.test_default_msec_format_none @ linux-x86_64 +test.test_logging.FormatterTest.test_defaults_parameter @ linux-x86_64 +test.test_logging.FormatterTest.test_dollars @ linux-x86_64 +test.test_logging.FormatterTest.test_format_validate @ linux-x86_64 +test.test_logging.FormatterTest.test_invalid_style @ linux-x86_64 +test.test_logging.FormatterTest.test_issue_89047 @ linux-x86_64 +test.test_logging.FormatterTest.test_percent @ linux-x86_64 +test.test_logging.FormatterTest.test_time @ linux-x86_64 +test.test_logging.HTTPHandlerTest.test_output @ linux-x86_64 +test.test_logging.HandlerTest.test_builtin_handlers @ linux-x86_64 +test.test_logging.HandlerTest.test_name @ linux-x86_64 +test.test_logging.HandlerTest.test_path_objects @ linux-x86_64 +test.test_logging.HandlerTest.test_race @ linux-x86_64 +test.test_logging.IPv6SysLogHandlerTest.test_output @ linux-x86_64 +test.test_logging.IPv6SysLogHandlerTest.test_udp_reconnection @ linux-x86_64 +test.test_logging.LastResortTest.test_last_resort @ linux-x86_64 +test.test_logging.LogRecordFactoryTest.test_logrecord_class @ linux-x86_64 +test.test_logging.LogRecordTest.test_dict_arg @ linux-x86_64 +test.test_logging.LogRecordTest.test_multiprocessing @ linux-x86_64 +test.test_logging.LogRecordTest.test_optional @ linux-x86_64 +test.test_logging.LogRecordTest.test_str_rep @ linux-x86_64 +test.test_logging.LoggerAdapterTest.test_critical @ linux-x86_64 +test.test_logging.LoggerAdapterTest.test_exception @ linux-x86_64 +test.test_logging.LoggerAdapterTest.test_exception_excinfo @ linux-x86_64 +test.test_logging.LoggerAdapterTest.test_has_handlers @ linux-x86_64 +test.test_logging.LoggerAdapterTest.test_is_enabled_for @ linux-x86_64 +test.test_logging.LoggerAdapterTest.test_nested @ linux-x86_64 +test.test_logging.LoggerTest.test_caching @ linux-x86_64 +test.test_logging.LoggerTest.test_exception @ linux-x86_64 +test.test_logging.LoggerTest.test_find_caller_with_stack_info @ linux-x86_64 +test.test_logging.LoggerTest.test_find_caller_with_stacklevel @ linux-x86_64 +test.test_logging.LoggerTest.test_has_handlers @ linux-x86_64 +test.test_logging.LoggerTest.test_has_handlers_no_propagate @ linux-x86_64 +test.test_logging.LoggerTest.test_invalid_names @ linux-x86_64 +test.test_logging.LoggerTest.test_is_enabled_for @ linux-x86_64 +test.test_logging.LoggerTest.test_is_enabled_for_disabled_logger @ linux-x86_64 +test.test_logging.LoggerTest.test_log_invalid_level_no_raise @ linux-x86_64 +test.test_logging.LoggerTest.test_log_invalid_level_with_raise @ linux-x86_64 +test.test_logging.LoggerTest.test_make_record_with_extra_no_overwrite @ linux-x86_64 +test.test_logging.LoggerTest.test_make_record_with_extra_overwrite @ linux-x86_64 +test.test_logging.LoggerTest.test_pickling @ linux-x86_64 +test.test_logging.LoggerTest.test_root_logger_aliases @ linux-x86_64 +test.test_logging.LoggerTest.test_set_invalid_level @ linux-x86_64 +test.test_logging.ManagerTest.test_manager_loggerclass @ linux-x86_64 +test.test_logging.ManagerTest.test_set_log_record_factory @ linux-x86_64 +test.test_logging.MemoryHandlerTest.test_flush @ linux-x86_64 +test.test_logging.MemoryHandlerTest.test_flush_on_close @ linux-x86_64 +test.test_logging.MemoryHandlerTest.test_race_between_set_target_and_flush @ linux-x86_64 +test.test_logging.MemoryTest.test_persistent_loggers @ linux-x86_64 +test.test_logging.MiscTestCase.test__all__ @ linux-x86_64 +test.test_logging.ModuleLevelMiscTest.test_critical @ linux-x86_64 +test.test_logging.ModuleLevelMiscTest.test_debug @ linux-x86_64 +test.test_logging.ModuleLevelMiscTest.test_disable @ linux-x86_64 +test.test_logging.ModuleLevelMiscTest.test_error @ linux-x86_64 +test.test_logging.ModuleLevelMiscTest.test_get_level_names_mapping @ linux-x86_64 +test.test_logging.ModuleLevelMiscTest.test_info @ linux-x86_64 +test.test_logging.ModuleLevelMiscTest.test_log @ linux-x86_64 +test.test_logging.ModuleLevelMiscTest.test_recursion_error @ linux-x86_64 +test.test_logging.ModuleLevelMiscTest.test_set_logger_class @ linux-x86_64 +test.test_logging.ModuleLevelMiscTest.test_subclass_logger_cache @ linux-x86_64 +test.test_logging.ModuleLevelMiscTest.test_warning @ linux-x86_64 +test.test_logging.QueueHandlerTest.test_formatting @ linux-x86_64 +test.test_logging.QueueHandlerTest.test_queue_handler @ linux-x86_64 +test.test_logging.QueueHandlerTest.test_queue_listener @ linux-x86_64 +test.test_logging.QueueHandlerTest.test_queue_listener_with_StreamHandler @ linux-x86_64 +test.test_logging.QueueHandlerTest.test_queue_listener_with_multiple_handlers @ linux-x86_64 +test.test_logging.QueueListenerTest.test_calls_task_done_after_stop @ linux-x86_64 +test.test_logging.QueueListenerTest.test_handle_called_with_mp_queue @ linux-x86_64 +test.test_logging.QueueListenerTest.test_handle_called_with_queue_queue @ linux-x86_64 +test.test_logging.QueueListenerTest.test_no_messages_in_queue_after_stop @ linux-x86_64 +test.test_logging.RotatingFileHandlerTest.test_file_created @ linux-x86_64 +test.test_logging.RotatingFileHandlerTest.test_namer_rotator_inheritance @ linux-x86_64 +test.test_logging.RotatingFileHandlerTest.test_rollover_filenames @ linux-x86_64 +test.test_logging.RotatingFileHandlerTest.test_rotator @ linux-x86_64 +test.test_logging.RotatingFileHandlerTest.test_should_not_rollover @ linux-x86_64 +test.test_logging.RotatingFileHandlerTest.test_should_rollover @ linux-x86_64 +test.test_logging.SMTPHandlerTest.test_basic @ linux-x86_64 +test.test_logging.ShutdownTest.test_no_failure @ linux-x86_64 +test.test_logging.ShutdownTest.test_with_ioerror_in_acquire @ linux-x86_64 +test.test_logging.ShutdownTest.test_with_ioerror_in_close @ linux-x86_64 +test.test_logging.ShutdownTest.test_with_ioerror_in_flush @ linux-x86_64 +test.test_logging.ShutdownTest.test_with_other_error_in_acquire_with_raise @ linux-x86_64 +test.test_logging.ShutdownTest.test_with_other_error_in_acquire_without_raise @ linux-x86_64 +test.test_logging.ShutdownTest.test_with_other_error_in_close_with_raise @ linux-x86_64 +test.test_logging.ShutdownTest.test_with_other_error_in_close_without_raise @ linux-x86_64 +test.test_logging.ShutdownTest.test_with_other_error_in_flush_with_raise @ linux-x86_64 +test.test_logging.ShutdownTest.test_with_other_error_in_flush_without_raise @ linux-x86_64 +test.test_logging.ShutdownTest.test_with_valueerror_in_acquire @ linux-x86_64 +test.test_logging.ShutdownTest.test_with_valueerror_in_close @ linux-x86_64 +test.test_logging.ShutdownTest.test_with_valueerror_in_flush @ linux-x86_64 +test.test_logging.SocketHandlerTest.test_noserver @ linux-x86_64 +test.test_logging.SocketHandlerTest.test_output @ linux-x86_64 +test.test_logging.StreamHandlerTest.test_can_represent_stream_with_int_name @ linux-x86_64 +test.test_logging.StreamHandlerTest.test_error_handling @ linux-x86_64 +test.test_logging.StreamHandlerTest.test_stream_setting @ linux-x86_64 +test.test_logging.SysLogHandlerTest.test_output @ linux-x86_64 +test.test_logging.SysLogHandlerTest.test_udp_reconnection @ linux-x86_64 +test.test_logging.TimedRotatingFileHandlerTest.test_compute_files_to_delete @ linux-x86_64 +test.test_logging.TimedRotatingFileHandlerTest.test_compute_rollover_D @ linux-x86_64 +test.test_logging.TimedRotatingFileHandlerTest.test_compute_rollover_H @ linux-x86_64 +test.test_logging.TimedRotatingFileHandlerTest.test_compute_rollover_M @ linux-x86_64 +test.test_logging.TimedRotatingFileHandlerTest.test_compute_rollover_MIDNIGHT @ linux-x86_64 +test.test_logging.TimedRotatingFileHandlerTest.test_compute_rollover_S @ linux-x86_64 +test.test_logging.TimedRotatingFileHandlerTest.test_compute_rollover_W0 @ linux-x86_64 +test.test_logging.TimedRotatingFileHandlerTest.test_compute_rollover_daily_attime @ linux-x86_64 +test.test_logging.TimedRotatingFileHandlerTest.test_compute_rollover_weekly_attime @ linux-x86_64 +test.test_logging.TimedRotatingFileHandlerTest.test_invalid @ linux-x86_64 +test.test_logging.TimedRotatingFileHandlerTest.test_rollover @ linux-x86_64 +test.test_logging.TimedRotatingFileHandlerTest.test_should_not_rollover @ linux-x86_64 +test.test_logging.UnixDatagramHandlerTest.test_output @ linux-x86_64 +test.test_logging.UnixSocketHandlerTest.test_noserver @ linux-x86_64 +test.test_logging.UnixSocketHandlerTest.test_output @ linux-x86_64 +test.test_logging.UnixSysLogHandlerTest.test_output @ linux-x86_64 +test.test_logging.UnixSysLogHandlerTest.test_udp_reconnection @ linux-x86_64 +test.test_logging.WarningsTest.test_warnings @ linux-x86_64 +test.test_logging.WarningsTest.test_warnings_no_handlers @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_long.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_long.txt new file mode 100644 index 0000000000..0f67c14d7a --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_long.txt @@ -0,0 +1,34 @@ +test.test_long.LongTest.test__format__ @ linux-x86_64 +test.test_long.LongTest.test_access_to_nonexistent_digit_0 @ linux-x86_64 +test.test_long.LongTest.test_as_integer_ratio @ linux-x86_64 +test.test_long.LongTest.test_big_lshift @ linux-x86_64 +test.test_long.LongTest.test_big_rshift @ linux-x86_64 +test.test_long.LongTest.test_bit_count @ linux-x86_64 +test.test_long.LongTest.test_bit_length @ linux-x86_64 +test.test_long.LongTest.test_bitop_identities @ linux-x86_64 +test.test_long.LongTest.test_conversion @ linux-x86_64 +test.test_long.LongTest.test_division @ linux-x86_64 +test.test_long.LongTest.test_float_conversion @ linux-x86_64 +test.test_long.LongTest.test_float_overflow @ linux-x86_64 +test.test_long.LongTest.test_floordiv @ linux-x86_64 +test.test_long.LongTest.test_format @ linux-x86_64 +test.test_long.LongTest.test_from_bytes @ linux-x86_64 +test.test_long.LongTest.test_huge_rshift @ linux-x86_64 +test.test_long.LongTest.test_karatsuba @ linux-x86_64 +test.test_long.LongTest.test_logs @ linux-x86_64 +test.test_long.LongTest.test_long @ linux-x86_64 +test.test_long.LongTest.test_lshift_of_zero @ linux-x86_64 +test.test_long.LongTest.test_medium_lshift @ linux-x86_64 +test.test_long.LongTest.test_medium_rshift @ linux-x86_64 +test.test_long.LongTest.test_mixed_compares @ linux-x86_64 +test.test_long.LongTest.test_mod_division @ linux-x86_64 +test.test_long.LongTest.test_nan_inf @ linux-x86_64 +test.test_long.LongTest.test_negative_shift_count @ linux-x86_64 +test.test_long.LongTest.test_round @ linux-x86_64 +test.test_long.LongTest.test_shift_bool @ linux-x86_64 +test.test_long.LongTest.test_small_ints @ linux-x86_64 +test.test_long.LongTest.test_small_lshift @ linux-x86_64 +test.test_long.LongTest.test_small_rshift @ linux-x86_64 +test.test_long.LongTest.test_square @ linux-x86_64 +test.test_long.LongTest.test_to_bytes @ linux-x86_64 +test.test_long.LongTest.test_true_division @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_longexp.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_longexp.txt new file mode 100644 index 0000000000..c5c0fdea81 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_longexp.txt @@ -0,0 +1 @@ +test.test_longexp.LongExpText.test_longexp @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_lzma.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_lzma.txt new file mode 100644 index 0000000000..00c3f5d4f1 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_lzma.txt @@ -0,0 +1,112 @@ +test.test_lzma.CompressDecompressFunctionTestCase.test_bad_args @ linux-x86_64 +test.test_lzma.CompressDecompressFunctionTestCase.test_decompress_bad_input @ linux-x86_64 +test.test_lzma.CompressDecompressFunctionTestCase.test_decompress_good_input @ linux-x86_64 +test.test_lzma.CompressDecompressFunctionTestCase.test_decompress_incomplete_input @ linux-x86_64 +test.test_lzma.CompressDecompressFunctionTestCase.test_decompress_memlimit @ linux-x86_64 +test.test_lzma.CompressDecompressFunctionTestCase.test_decompress_multistream @ linux-x86_64 +test.test_lzma.CompressDecompressFunctionTestCase.test_decompress_multistream_trailing_junk @ linux-x86_64 +test.test_lzma.CompressDecompressFunctionTestCase.test_decompress_trailing_junk @ linux-x86_64 +test.test_lzma.CompressDecompressFunctionTestCase.test_roundtrip @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_bad_filter_spec @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_compressor_bigmem @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_after_eof @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_alone @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_auto @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_bad_input @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_bigmem @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_bug_28275 @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_chunks @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_chunks_empty @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_chunks_maxsize @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_inputbuf_1 @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_inputbuf_2 @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_inputbuf_3 @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_memlimit @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_multistream @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_raw_1 @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_raw_2 @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_raw_3 @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_raw_4 @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_unused_data @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_decompressor_xz @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_roundtrip_alone @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_roundtrip_chunks @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_roundtrip_empty_chunks @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_roundtrip_raw @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_roundtrip_raw_empty @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_roundtrip_xz @ linux-x86_64 +test.test_lzma.CompressorDecompressorTestCase.test_simple_bad_args @ linux-x86_64 +test.test_lzma.FileTestCase.test_close @ linux-x86_64 +test.test_lzma.FileTestCase.test_closed @ linux-x86_64 +test.test_lzma.FileTestCase.test_decompress_limited @ linux-x86_64 +test.test_lzma.FileTestCase.test_fileno @ linux-x86_64 +test.test_lzma.FileTestCase.test_init @ linux-x86_64 +test.test_lzma.FileTestCase.test_init_bad_check @ linux-x86_64 +test.test_lzma.FileTestCase.test_init_bad_filter_spec @ linux-x86_64 +test.test_lzma.FileTestCase.test_init_bad_mode @ linux-x86_64 +test.test_lzma.FileTestCase.test_init_bad_preset @ linux-x86_64 +test.test_lzma.FileTestCase.test_init_mode @ linux-x86_64 +test.test_lzma.FileTestCase.test_init_with_PathLike_filename @ linux-x86_64 +test.test_lzma.FileTestCase.test_init_with_filename @ linux-x86_64 +test.test_lzma.FileTestCase.test_init_with_preset_and_filters @ linux-x86_64 +test.test_lzma.FileTestCase.test_init_with_x_mode @ linux-x86_64 +test.test_lzma.FileTestCase.test_issue21872 @ linux-x86_64 +test.test_lzma.FileTestCase.test_issue44439 @ linux-x86_64 +test.test_lzma.FileTestCase.test_iterator @ linux-x86_64 +test.test_lzma.FileTestCase.test_peek @ linux-x86_64 +test.test_lzma.FileTestCase.test_peek_bad_args @ linux-x86_64 +test.test_lzma.FileTestCase.test_read @ linux-x86_64 +test.test_lzma.FileTestCase.test_read1 @ linux-x86_64 +test.test_lzma.FileTestCase.test_read1_0 @ linux-x86_64 +test.test_lzma.FileTestCase.test_read1_10 @ linux-x86_64 +test.test_lzma.FileTestCase.test_read1_bad_args @ linux-x86_64 +test.test_lzma.FileTestCase.test_read1_multistream @ linux-x86_64 +test.test_lzma.FileTestCase.test_read_0 @ linux-x86_64 +test.test_lzma.FileTestCase.test_read_10 @ linux-x86_64 +test.test_lzma.FileTestCase.test_read_bad_args @ linux-x86_64 +test.test_lzma.FileTestCase.test_read_bad_data @ linux-x86_64 +test.test_lzma.FileTestCase.test_read_from_file @ linux-x86_64 +test.test_lzma.FileTestCase.test_read_incomplete @ linux-x86_64 +test.test_lzma.FileTestCase.test_read_multistream @ linux-x86_64 +test.test_lzma.FileTestCase.test_read_multistream_buffer_size_aligned @ linux-x86_64 +test.test_lzma.FileTestCase.test_read_multistream_trailing_junk @ linux-x86_64 +test.test_lzma.FileTestCase.test_read_trailing_junk @ linux-x86_64 +test.test_lzma.FileTestCase.test_read_truncated @ linux-x86_64 +test.test_lzma.FileTestCase.test_readable @ linux-x86_64 +test.test_lzma.FileTestCase.test_readline @ linux-x86_64 +test.test_lzma.FileTestCase.test_readlines @ linux-x86_64 +test.test_lzma.FileTestCase.test_seek_backward @ linux-x86_64 +test.test_lzma.FileTestCase.test_seek_backward_across_streams @ linux-x86_64 +test.test_lzma.FileTestCase.test_seek_backward_relative_to_end @ linux-x86_64 +test.test_lzma.FileTestCase.test_seek_bad_args @ linux-x86_64 +test.test_lzma.FileTestCase.test_seek_forward @ linux-x86_64 +test.test_lzma.FileTestCase.test_seek_forward_across_streams @ linux-x86_64 +test.test_lzma.FileTestCase.test_seek_forward_relative_to_current @ linux-x86_64 +test.test_lzma.FileTestCase.test_seek_forward_relative_to_end @ linux-x86_64 +test.test_lzma.FileTestCase.test_seek_past_end @ linux-x86_64 +test.test_lzma.FileTestCase.test_seek_past_start @ linux-x86_64 +test.test_lzma.FileTestCase.test_seekable @ linux-x86_64 +test.test_lzma.FileTestCase.test_tell @ linux-x86_64 +test.test_lzma.FileTestCase.test_tell_bad_args @ linux-x86_64 +test.test_lzma.FileTestCase.test_writable @ linux-x86_64 +test.test_lzma.FileTestCase.test_write @ linux-x86_64 +test.test_lzma.FileTestCase.test_write_10 @ linux-x86_64 +test.test_lzma.FileTestCase.test_write_append @ linux-x86_64 +test.test_lzma.FileTestCase.test_write_append_to_file @ linux-x86_64 +test.test_lzma.FileTestCase.test_write_bad_args @ linux-x86_64 +test.test_lzma.FileTestCase.test_write_to_file @ linux-x86_64 +test.test_lzma.FileTestCase.test_writelines @ linux-x86_64 +test.test_lzma.MiscellaneousTestCase.test__decode_filter_properties @ linux-x86_64 +test.test_lzma.MiscellaneousTestCase.test__encode_filter_properties @ linux-x86_64 +test.test_lzma.MiscellaneousTestCase.test_filter_properties_roundtrip @ linux-x86_64 +test.test_lzma.MiscellaneousTestCase.test_is_check_supported @ linux-x86_64 +test.test_lzma.OpenTestCase.test_bad_params @ linux-x86_64 +test.test_lzma.OpenTestCase.test_binary_modes @ linux-x86_64 +test.test_lzma.OpenTestCase.test_encoding @ linux-x86_64 +test.test_lzma.OpenTestCase.test_encoding_error_handler @ linux-x86_64 +test.test_lzma.OpenTestCase.test_filename @ linux-x86_64 +test.test_lzma.OpenTestCase.test_format_and_filters @ linux-x86_64 +test.test_lzma.OpenTestCase.test_newline @ linux-x86_64 +test.test_lzma.OpenTestCase.test_text_modes @ linux-x86_64 +test.test_lzma.OpenTestCase.test_with_pathlike_filename @ linux-x86_64 +test.test_lzma.OpenTestCase.test_x_mode @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_mailbox.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_mailbox.txt new file mode 100644 index 0000000000..ea9aa189f9 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_mailbox.txt @@ -0,0 +1,362 @@ +test.test_mailbox.MaildirTestCase.test_empty_maildir @ linux-x86_64 +test.test_mailbox.MaildirTestCase.test_nonempty_maildir_both @ linux-x86_64 +test.test_mailbox.MaildirTestCase.test_nonempty_maildir_cur @ linux-x86_64 +test.test_mailbox.MaildirTestCase.test_nonempty_maildir_new @ linux-x86_64 +test.test_mailbox.MiscTestCase.test__all__ @ linux-x86_64 +test.test_mailbox.TestBabyl.test_add @ linux-x86_64 +test.test_mailbox.TestBabyl.test_add_8bit_body @ linux-x86_64 +test.test_mailbox.TestBabyl.test_add_StringIO_warns @ linux-x86_64 +test.test_mailbox.TestBabyl.test_add_binary_file @ linux-x86_64 +test.test_mailbox.TestBabyl.test_add_binary_nonascii_file @ linux-x86_64 +test.test_mailbox.TestBabyl.test_add_doesnt_rewrite @ linux-x86_64 +test.test_mailbox.TestBabyl.test_add_invalid_8bit_bytes_header @ linux-x86_64 +test.test_mailbox.TestBabyl.test_add_nonascii_StringIO_raises @ linux-x86_64 +test.test_mailbox.TestBabyl.test_add_nonascii_string_header_raises @ linux-x86_64 +test.test_mailbox.TestBabyl.test_add_text_file_warns @ linux-x86_64 +test.test_mailbox.TestBabyl.test_add_that_raises_leaves_mailbox_empty @ linux-x86_64 +test.test_mailbox.TestBabyl.test_clear @ linux-x86_64 +test.test_mailbox.TestBabyl.test_close @ linux-x86_64 +test.test_mailbox.TestBabyl.test_contains @ linux-x86_64 +test.test_mailbox.TestBabyl.test_delitem @ linux-x86_64 +test.test_mailbox.TestBabyl.test_discard @ linux-x86_64 +test.test_mailbox.TestBabyl.test_dump_message @ linux-x86_64 +test.test_mailbox.TestBabyl.test_flush @ linux-x86_64 +test.test_mailbox.TestBabyl.test_get @ linux-x86_64 +test.test_mailbox.TestBabyl.test_get_bytes @ linux-x86_64 +test.test_mailbox.TestBabyl.test_get_file @ linux-x86_64 +test.test_mailbox.TestBabyl.test_get_file_can_be_closed_twice @ linux-x86_64 +test.test_mailbox.TestBabyl.test_get_message @ linux-x86_64 +test.test_mailbox.TestBabyl.test_get_string @ linux-x86_64 +test.test_mailbox.TestBabyl.test_getitem @ linux-x86_64 +test.test_mailbox.TestBabyl.test_invalid_nonascii_header_as_string @ linux-x86_64 +test.test_mailbox.TestBabyl.test_items @ linux-x86_64 +test.test_mailbox.TestBabyl.test_iter @ linux-x86_64 +test.test_mailbox.TestBabyl.test_iteritems @ linux-x86_64 +test.test_mailbox.TestBabyl.test_iterkeys @ linux-x86_64 +test.test_mailbox.TestBabyl.test_itervalues @ linux-x86_64 +test.test_mailbox.TestBabyl.test_keys @ linux-x86_64 +test.test_mailbox.TestBabyl.test_labels @ linux-x86_64 +test.test_mailbox.TestBabyl.test_len @ linux-x86_64 +test.test_mailbox.TestBabyl.test_lock_unlock @ linux-x86_64 +test.test_mailbox.TestBabyl.test_permissions_after_flush @ linux-x86_64 +test.test_mailbox.TestBabyl.test_pop @ linux-x86_64 +test.test_mailbox.TestBabyl.test_popitem @ linux-x86_64 +test.test_mailbox.TestBabyl.test_popitem_and_flush_twice @ linux-x86_64 +test.test_mailbox.TestBabyl.test_remove @ linux-x86_64 +test.test_mailbox.TestBabyl.test_set_item @ linux-x86_64 +test.test_mailbox.TestBabyl.test_update @ linux-x86_64 +test.test_mailbox.TestBabyl.test_values @ linux-x86_64 +test.test_mailbox.TestBabylMessage.test_all_eMM_attributes_exist @ linux-x86_64 +test.test_mailbox.TestBabylMessage.test_become_message @ linux-x86_64 +test.test_mailbox.TestBabylMessage.test_explain_to @ linux-x86_64 +test.test_mailbox.TestBabylMessage.test_initialize_incorrectly @ linux-x86_64 +test.test_mailbox.TestBabylMessage.test_initialize_with_binary_file @ linux-x86_64 +test.test_mailbox.TestBabylMessage.test_initialize_with_eMM @ linux-x86_64 +test.test_mailbox.TestBabylMessage.test_initialize_with_file @ linux-x86_64 +test.test_mailbox.TestBabylMessage.test_initialize_with_nothing @ linux-x86_64 +test.test_mailbox.TestBabylMessage.test_initialize_with_string @ linux-x86_64 +test.test_mailbox.TestBabylMessage.test_labels @ linux-x86_64 +test.test_mailbox.TestBabylMessage.test_visible @ linux-x86_64 +test.test_mailbox.TestFakeMailBox.test_closing_fd @ linux-x86_64 +test.test_mailbox.TestMH.test_add @ linux-x86_64 +test.test_mailbox.TestMH.test_add_8bit_body @ linux-x86_64 +test.test_mailbox.TestMH.test_add_StringIO_warns @ linux-x86_64 +test.test_mailbox.TestMH.test_add_and_remove_folders @ linux-x86_64 +test.test_mailbox.TestMH.test_add_binary_file @ linux-x86_64 +test.test_mailbox.TestMH.test_add_binary_nonascii_file @ linux-x86_64 +test.test_mailbox.TestMH.test_add_invalid_8bit_bytes_header @ linux-x86_64 +test.test_mailbox.TestMH.test_add_nonascii_StringIO_raises @ linux-x86_64 +test.test_mailbox.TestMH.test_add_nonascii_string_header_raises @ linux-x86_64 +test.test_mailbox.TestMH.test_add_text_file_warns @ linux-x86_64 +test.test_mailbox.TestMH.test_add_that_raises_leaves_mailbox_empty @ linux-x86_64 +test.test_mailbox.TestMH.test_clear @ linux-x86_64 +test.test_mailbox.TestMH.test_close @ linux-x86_64 +test.test_mailbox.TestMH.test_contains @ linux-x86_64 +test.test_mailbox.TestMH.test_delitem @ linux-x86_64 +test.test_mailbox.TestMH.test_discard @ linux-x86_64 +test.test_mailbox.TestMH.test_dump_message @ linux-x86_64 +test.test_mailbox.TestMH.test_flush @ linux-x86_64 +test.test_mailbox.TestMH.test_get @ linux-x86_64 +test.test_mailbox.TestMH.test_get_bytes @ linux-x86_64 +test.test_mailbox.TestMH.test_get_file @ linux-x86_64 +test.test_mailbox.TestMH.test_get_file_can_be_closed_twice @ linux-x86_64 +test.test_mailbox.TestMH.test_get_folder @ linux-x86_64 +test.test_mailbox.TestMH.test_get_message @ linux-x86_64 +test.test_mailbox.TestMH.test_get_string @ linux-x86_64 +test.test_mailbox.TestMH.test_getitem @ linux-x86_64 +test.test_mailbox.TestMH.test_invalid_nonascii_header_as_string @ linux-x86_64 +test.test_mailbox.TestMH.test_issue2625 @ linux-x86_64 +test.test_mailbox.TestMH.test_issue7627 @ linux-x86_64 +test.test_mailbox.TestMH.test_items @ linux-x86_64 +test.test_mailbox.TestMH.test_iter @ linux-x86_64 +test.test_mailbox.TestMH.test_iteritems @ linux-x86_64 +test.test_mailbox.TestMH.test_iterkeys @ linux-x86_64 +test.test_mailbox.TestMH.test_itervalues @ linux-x86_64 +test.test_mailbox.TestMH.test_keys @ linux-x86_64 +test.test_mailbox.TestMH.test_len @ linux-x86_64 +test.test_mailbox.TestMH.test_list_folders @ linux-x86_64 +test.test_mailbox.TestMH.test_lock_unlock @ linux-x86_64 +test.test_mailbox.TestMH.test_pack @ linux-x86_64 +test.test_mailbox.TestMH.test_pop @ linux-x86_64 +test.test_mailbox.TestMH.test_popitem @ linux-x86_64 +test.test_mailbox.TestMH.test_popitem_and_flush_twice @ linux-x86_64 +test.test_mailbox.TestMH.test_remove @ linux-x86_64 +test.test_mailbox.TestMH.test_sequences @ linux-x86_64 +test.test_mailbox.TestMH.test_set_item @ linux-x86_64 +test.test_mailbox.TestMH.test_update @ linux-x86_64 +test.test_mailbox.TestMH.test_values @ linux-x86_64 +test.test_mailbox.TestMHMessage.test_all_eMM_attributes_exist @ linux-x86_64 +test.test_mailbox.TestMHMessage.test_become_message @ linux-x86_64 +test.test_mailbox.TestMHMessage.test_explain_to @ linux-x86_64 +test.test_mailbox.TestMHMessage.test_initialize_incorrectly @ linux-x86_64 +test.test_mailbox.TestMHMessage.test_initialize_with_binary_file @ linux-x86_64 +test.test_mailbox.TestMHMessage.test_initialize_with_eMM @ linux-x86_64 +test.test_mailbox.TestMHMessage.test_initialize_with_file @ linux-x86_64 +test.test_mailbox.TestMHMessage.test_initialize_with_nothing @ linux-x86_64 +test.test_mailbox.TestMHMessage.test_initialize_with_string @ linux-x86_64 +test.test_mailbox.TestMHMessage.test_sequences @ linux-x86_64 +test.test_mailbox.TestMMDF.test_add @ linux-x86_64 +test.test_mailbox.TestMMDF.test_add_8bit_body @ linux-x86_64 +test.test_mailbox.TestMMDF.test_add_StringIO_warns @ linux-x86_64 +test.test_mailbox.TestMMDF.test_add_and_close @ linux-x86_64 +test.test_mailbox.TestMMDF.test_add_binary_file @ linux-x86_64 +test.test_mailbox.TestMMDF.test_add_binary_nonascii_file @ linux-x86_64 +test.test_mailbox.TestMMDF.test_add_doesnt_rewrite @ linux-x86_64 +test.test_mailbox.TestMMDF.test_add_from_bytes @ linux-x86_64 +test.test_mailbox.TestMMDF.test_add_from_string @ linux-x86_64 +test.test_mailbox.TestMMDF.test_add_invalid_8bit_bytes_header @ linux-x86_64 +test.test_mailbox.TestMMDF.test_add_mbox_or_mmdf_message @ linux-x86_64 +test.test_mailbox.TestMMDF.test_add_nonascii_StringIO_raises @ linux-x86_64 +test.test_mailbox.TestMMDF.test_add_nonascii_string_header_raises @ linux-x86_64 +test.test_mailbox.TestMMDF.test_add_text_file_warns @ linux-x86_64 +test.test_mailbox.TestMMDF.test_add_that_raises_leaves_mailbox_empty @ linux-x86_64 +test.test_mailbox.TestMMDF.test_clear @ linux-x86_64 +test.test_mailbox.TestMMDF.test_close @ linux-x86_64 +test.test_mailbox.TestMMDF.test_contains @ linux-x86_64 +test.test_mailbox.TestMMDF.test_delitem @ linux-x86_64 +test.test_mailbox.TestMMDF.test_discard @ linux-x86_64 +test.test_mailbox.TestMMDF.test_dump_message @ linux-x86_64 +test.test_mailbox.TestMMDF.test_flush @ linux-x86_64 +test.test_mailbox.TestMMDF.test_get @ linux-x86_64 +test.test_mailbox.TestMMDF.test_get_bytes @ linux-x86_64 +test.test_mailbox.TestMMDF.test_get_bytes_from @ linux-x86_64 +test.test_mailbox.TestMMDF.test_get_file @ linux-x86_64 +test.test_mailbox.TestMMDF.test_get_file_can_be_closed_twice @ linux-x86_64 +test.test_mailbox.TestMMDF.test_get_message @ linux-x86_64 +test.test_mailbox.TestMMDF.test_get_string @ linux-x86_64 +test.test_mailbox.TestMMDF.test_get_string_from @ linux-x86_64 +test.test_mailbox.TestMMDF.test_getitem @ linux-x86_64 +test.test_mailbox.TestMMDF.test_invalid_nonascii_header_as_string @ linux-x86_64 +test.test_mailbox.TestMMDF.test_items @ linux-x86_64 +test.test_mailbox.TestMMDF.test_iter @ linux-x86_64 +test.test_mailbox.TestMMDF.test_iteritems @ linux-x86_64 +test.test_mailbox.TestMMDF.test_iterkeys @ linux-x86_64 +test.test_mailbox.TestMMDF.test_itervalues @ linux-x86_64 +test.test_mailbox.TestMMDF.test_keys @ linux-x86_64 +test.test_mailbox.TestMMDF.test_len @ linux-x86_64 +test.test_mailbox.TestMMDF.test_lock_unlock @ linux-x86_64 +test.test_mailbox.TestMMDF.test_open_close_open @ linux-x86_64 +test.test_mailbox.TestMMDF.test_permissions_after_flush @ linux-x86_64 +test.test_mailbox.TestMMDF.test_pop @ linux-x86_64 +test.test_mailbox.TestMMDF.test_popitem @ linux-x86_64 +test.test_mailbox.TestMMDF.test_popitem_and_flush_twice @ linux-x86_64 +test.test_mailbox.TestMMDF.test_relock @ linux-x86_64 +test.test_mailbox.TestMMDF.test_remove @ linux-x86_64 +test.test_mailbox.TestMMDF.test_set_item @ linux-x86_64 +test.test_mailbox.TestMMDF.test_update @ linux-x86_64 +test.test_mailbox.TestMMDF.test_values @ linux-x86_64 +test.test_mailbox.TestMMDFMessage.test_all_eMM_attributes_exist @ linux-x86_64 +test.test_mailbox.TestMMDFMessage.test_become_message @ linux-x86_64 +test.test_mailbox.TestMMDFMessage.test_explain_to @ linux-x86_64 +test.test_mailbox.TestMMDFMessage.test_flags @ linux-x86_64 +test.test_mailbox.TestMMDFMessage.test_from @ linux-x86_64 +test.test_mailbox.TestMMDFMessage.test_initialize_incorrectly @ linux-x86_64 +test.test_mailbox.TestMMDFMessage.test_initialize_with_binary_file @ linux-x86_64 +test.test_mailbox.TestMMDFMessage.test_initialize_with_eMM @ linux-x86_64 +test.test_mailbox.TestMMDFMessage.test_initialize_with_file @ linux-x86_64 +test.test_mailbox.TestMMDFMessage.test_initialize_with_nothing @ linux-x86_64 +test.test_mailbox.TestMMDFMessage.test_initialize_with_string @ linux-x86_64 +test.test_mailbox.TestMMDFMessage.test_initialize_with_unixfrom @ linux-x86_64 +test.test_mailbox.TestMailboxSuperclass.test_notimplemented @ linux-x86_64 +test.test_mailbox.TestMaildir.test_add @ linux-x86_64 +test.test_mailbox.TestMaildir.test_add_8bit_body @ linux-x86_64 +test.test_mailbox.TestMaildir.test_add_MM @ linux-x86_64 +test.test_mailbox.TestMaildir.test_add_StringIO_warns @ linux-x86_64 +test.test_mailbox.TestMaildir.test_add_and_remove_folders @ linux-x86_64 +test.test_mailbox.TestMaildir.test_add_binary_file @ linux-x86_64 +test.test_mailbox.TestMaildir.test_add_binary_nonascii_file @ linux-x86_64 +test.test_mailbox.TestMaildir.test_add_invalid_8bit_bytes_header @ linux-x86_64 +test.test_mailbox.TestMaildir.test_add_nonascii_StringIO_raises @ linux-x86_64 +test.test_mailbox.TestMaildir.test_add_nonascii_string_header_raises @ linux-x86_64 +test.test_mailbox.TestMaildir.test_add_text_file_warns @ linux-x86_64 +test.test_mailbox.TestMaildir.test_add_that_raises_leaves_mailbox_empty @ linux-x86_64 +test.test_mailbox.TestMaildir.test_clean @ linux-x86_64 +test.test_mailbox.TestMaildir.test_clear @ linux-x86_64 +test.test_mailbox.TestMaildir.test_close @ linux-x86_64 +test.test_mailbox.TestMaildir.test_consistent_factory @ linux-x86_64 +test.test_mailbox.TestMaildir.test_contains @ linux-x86_64 +test.test_mailbox.TestMaildir.test_create_tmp @ linux-x86_64 +test.test_mailbox.TestMaildir.test_delitem @ linux-x86_64 +test.test_mailbox.TestMaildir.test_directory_in_folder @ linux-x86_64 +test.test_mailbox.TestMaildir.test_discard @ linux-x86_64 +test.test_mailbox.TestMaildir.test_dump_message @ linux-x86_64 +test.test_mailbox.TestMaildir.test_file_permissions @ linux-x86_64 +test.test_mailbox.TestMaildir.test_flush @ linux-x86_64 +test.test_mailbox.TestMaildir.test_folder @ linux-x86_64 +test.test_mailbox.TestMaildir.test_folder_file_perms @ linux-x86_64 +test.test_mailbox.TestMaildir.test_get @ linux-x86_64 +test.test_mailbox.TestMaildir.test_get_MM @ linux-x86_64 +test.test_mailbox.TestMaildir.test_get_bytes @ linux-x86_64 +test.test_mailbox.TestMaildir.test_get_file @ linux-x86_64 +test.test_mailbox.TestMaildir.test_get_file_can_be_closed_twice @ linux-x86_64 +test.test_mailbox.TestMaildir.test_get_folder @ linux-x86_64 +test.test_mailbox.TestMaildir.test_get_message @ linux-x86_64 +test.test_mailbox.TestMaildir.test_get_string @ linux-x86_64 +test.test_mailbox.TestMaildir.test_getitem @ linux-x86_64 +test.test_mailbox.TestMaildir.test_initialize_existing @ linux-x86_64 +test.test_mailbox.TestMaildir.test_initialize_new @ linux-x86_64 +test.test_mailbox.TestMaildir.test_invalid_nonascii_header_as_string @ linux-x86_64 +test.test_mailbox.TestMaildir.test_items @ linux-x86_64 +test.test_mailbox.TestMaildir.test_iter @ linux-x86_64 +test.test_mailbox.TestMaildir.test_iteritems @ linux-x86_64 +test.test_mailbox.TestMaildir.test_iterkeys @ linux-x86_64 +test.test_mailbox.TestMaildir.test_itervalues @ linux-x86_64 +test.test_mailbox.TestMaildir.test_keys @ linux-x86_64 +test.test_mailbox.TestMaildir.test_len @ linux-x86_64 +test.test_mailbox.TestMaildir.test_list_folders @ linux-x86_64 +test.test_mailbox.TestMaildir.test_lock_unlock @ linux-x86_64 +test.test_mailbox.TestMaildir.test_lookup @ linux-x86_64 +test.test_mailbox.TestMaildir.test_pop @ linux-x86_64 +test.test_mailbox.TestMaildir.test_popitem @ linux-x86_64 +test.test_mailbox.TestMaildir.test_popitem_and_flush_twice @ linux-x86_64 +test.test_mailbox.TestMaildir.test_refresh @ linux-x86_64 +test.test_mailbox.TestMaildir.test_refresh_after_safety_period @ linux-x86_64 +test.test_mailbox.TestMaildir.test_remove @ linux-x86_64 +test.test_mailbox.TestMaildir.test_reread @ linux-x86_64 +test.test_mailbox.TestMaildir.test_set_MM @ linux-x86_64 +test.test_mailbox.TestMaildir.test_set_item @ linux-x86_64 +test.test_mailbox.TestMaildir.test_update @ linux-x86_64 +test.test_mailbox.TestMaildir.test_values @ linux-x86_64 +test.test_mailbox.TestMaildirMessage.test_all_eMM_attributes_exist @ linux-x86_64 +test.test_mailbox.TestMaildirMessage.test_become_message @ linux-x86_64 +test.test_mailbox.TestMaildirMessage.test_date @ linux-x86_64 +test.test_mailbox.TestMaildirMessage.test_explain_to @ linux-x86_64 +test.test_mailbox.TestMaildirMessage.test_flags @ linux-x86_64 +test.test_mailbox.TestMaildirMessage.test_info @ linux-x86_64 +test.test_mailbox.TestMaildirMessage.test_info_and_flags @ linux-x86_64 +test.test_mailbox.TestMaildirMessage.test_initialize_incorrectly @ linux-x86_64 +test.test_mailbox.TestMaildirMessage.test_initialize_with_binary_file @ linux-x86_64 +test.test_mailbox.TestMaildirMessage.test_initialize_with_eMM @ linux-x86_64 +test.test_mailbox.TestMaildirMessage.test_initialize_with_file @ linux-x86_64 +test.test_mailbox.TestMaildirMessage.test_initialize_with_nothing @ linux-x86_64 +test.test_mailbox.TestMaildirMessage.test_initialize_with_string @ linux-x86_64 +test.test_mailbox.TestMaildirMessage.test_subdir @ linux-x86_64 +test.test_mailbox.TestMbox.test_add @ linux-x86_64 +test.test_mailbox.TestMbox.test_add_8bit_body @ linux-x86_64 +test.test_mailbox.TestMbox.test_add_StringIO_warns @ linux-x86_64 +test.test_mailbox.TestMbox.test_add_and_close @ linux-x86_64 +test.test_mailbox.TestMbox.test_add_binary_file @ linux-x86_64 +test.test_mailbox.TestMbox.test_add_binary_nonascii_file @ linux-x86_64 +test.test_mailbox.TestMbox.test_add_doesnt_rewrite @ linux-x86_64 +test.test_mailbox.TestMbox.test_add_from_bytes @ linux-x86_64 +test.test_mailbox.TestMbox.test_add_from_string @ linux-x86_64 +test.test_mailbox.TestMbox.test_add_invalid_8bit_bytes_header @ linux-x86_64 +test.test_mailbox.TestMbox.test_add_mbox_or_mmdf_message @ linux-x86_64 +test.test_mailbox.TestMbox.test_add_nonascii_StringIO_raises @ linux-x86_64 +test.test_mailbox.TestMbox.test_add_nonascii_string_header_raises @ linux-x86_64 +test.test_mailbox.TestMbox.test_add_text_file_warns @ linux-x86_64 +test.test_mailbox.TestMbox.test_add_that_raises_leaves_mailbox_empty @ linux-x86_64 +test.test_mailbox.TestMbox.test_clear @ linux-x86_64 +test.test_mailbox.TestMbox.test_close @ linux-x86_64 +test.test_mailbox.TestMbox.test_contains @ linux-x86_64 +test.test_mailbox.TestMbox.test_delitem @ linux-x86_64 +test.test_mailbox.TestMbox.test_discard @ linux-x86_64 +test.test_mailbox.TestMbox.test_dump_message @ linux-x86_64 +test.test_mailbox.TestMbox.test_file_perms @ linux-x86_64 +test.test_mailbox.TestMbox.test_flush @ linux-x86_64 +test.test_mailbox.TestMbox.test_get @ linux-x86_64 +test.test_mailbox.TestMbox.test_get_bytes @ linux-x86_64 +test.test_mailbox.TestMbox.test_get_bytes_from @ linux-x86_64 +test.test_mailbox.TestMbox.test_get_file @ linux-x86_64 +test.test_mailbox.TestMbox.test_get_file_can_be_closed_twice @ linux-x86_64 +test.test_mailbox.TestMbox.test_get_message @ linux-x86_64 +test.test_mailbox.TestMbox.test_get_string @ linux-x86_64 +test.test_mailbox.TestMbox.test_get_string_from @ linux-x86_64 +test.test_mailbox.TestMbox.test_getitem @ linux-x86_64 +test.test_mailbox.TestMbox.test_invalid_nonascii_header_as_string @ linux-x86_64 +test.test_mailbox.TestMbox.test_items @ linux-x86_64 +test.test_mailbox.TestMbox.test_iter @ linux-x86_64 +test.test_mailbox.TestMbox.test_iteritems @ linux-x86_64 +test.test_mailbox.TestMbox.test_iterkeys @ linux-x86_64 +test.test_mailbox.TestMbox.test_itervalues @ linux-x86_64 +test.test_mailbox.TestMbox.test_keys @ linux-x86_64 +test.test_mailbox.TestMbox.test_len @ linux-x86_64 +test.test_mailbox.TestMbox.test_lock_unlock @ linux-x86_64 +test.test_mailbox.TestMbox.test_message_separator @ linux-x86_64 +test.test_mailbox.TestMbox.test_open_close_open @ linux-x86_64 +test.test_mailbox.TestMbox.test_permissions_after_flush @ linux-x86_64 +test.test_mailbox.TestMbox.test_pop @ linux-x86_64 +test.test_mailbox.TestMbox.test_popitem @ linux-x86_64 +test.test_mailbox.TestMbox.test_popitem_and_flush_twice @ linux-x86_64 +test.test_mailbox.TestMbox.test_relock @ linux-x86_64 +test.test_mailbox.TestMbox.test_remove @ linux-x86_64 +test.test_mailbox.TestMbox.test_set_item @ linux-x86_64 +test.test_mailbox.TestMbox.test_terminating_newline @ linux-x86_64 +test.test_mailbox.TestMbox.test_update @ linux-x86_64 +test.test_mailbox.TestMbox.test_values @ linux-x86_64 +test.test_mailbox.TestMboxMessage.test_all_eMM_attributes_exist @ linux-x86_64 +test.test_mailbox.TestMboxMessage.test_become_message @ linux-x86_64 +test.test_mailbox.TestMboxMessage.test_explain_to @ linux-x86_64 +test.test_mailbox.TestMboxMessage.test_flags @ linux-x86_64 +test.test_mailbox.TestMboxMessage.test_from @ linux-x86_64 +test.test_mailbox.TestMboxMessage.test_initialize_incorrectly @ linux-x86_64 +test.test_mailbox.TestMboxMessage.test_initialize_with_binary_file @ linux-x86_64 +test.test_mailbox.TestMboxMessage.test_initialize_with_eMM @ linux-x86_64 +test.test_mailbox.TestMboxMessage.test_initialize_with_file @ linux-x86_64 +test.test_mailbox.TestMboxMessage.test_initialize_with_nothing @ linux-x86_64 +test.test_mailbox.TestMboxMessage.test_initialize_with_string @ linux-x86_64 +test.test_mailbox.TestMboxMessage.test_initialize_with_unixfrom @ linux-x86_64 +test.test_mailbox.TestMessage.test_all_eMM_attributes_exist @ linux-x86_64 +test.test_mailbox.TestMessage.test_become_message @ linux-x86_64 +test.test_mailbox.TestMessage.test_explain_to @ linux-x86_64 +test.test_mailbox.TestMessage.test_initialize_incorrectly @ linux-x86_64 +test.test_mailbox.TestMessage.test_initialize_with_binary_file @ linux-x86_64 +test.test_mailbox.TestMessage.test_initialize_with_eMM @ linux-x86_64 +test.test_mailbox.TestMessage.test_initialize_with_file @ linux-x86_64 +test.test_mailbox.TestMessage.test_initialize_with_nothing @ linux-x86_64 +test.test_mailbox.TestMessage.test_initialize_with_string @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_babyl_to_babyl @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_babyl_to_maildir @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_babyl_to_mboxmmdf @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_babyl_to_mh @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_maildir_to_babyl @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_maildir_to_maildir @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_maildir_to_mboxmmdf @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_maildir_to_mh @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_mboxmmdf_to_babyl @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_mboxmmdf_to_maildir @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_mboxmmdf_to_mboxmmdf @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_mboxmmdf_to_mh @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_mh_to_babyl @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_mh_to_maildir @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_mh_to_mboxmmdf @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_mh_to_mh @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_plain_to_x @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_type_specific_attributes_removed_on_conversion @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_x_from_bytes @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_x_to_invalid @ linux-x86_64 +test.test_mailbox.TestMessageConversion.test_x_to_plain @ linux-x86_64 +test.test_mailbox.TestPartialFile.test_close @ linux-x86_64 +test.test_mailbox.TestPartialFile.test_initialize @ linux-x86_64 +test.test_mailbox.TestPartialFile.test_iteration @ linux-x86_64 +test.test_mailbox.TestPartialFile.test_read @ linux-x86_64 +test.test_mailbox.TestPartialFile.test_readline @ linux-x86_64 +test.test_mailbox.TestPartialFile.test_readlines @ linux-x86_64 +test.test_mailbox.TestPartialFile.test_seek_and_tell @ linux-x86_64 +test.test_mailbox.TestProxyFile.test_close @ linux-x86_64 +test.test_mailbox.TestProxyFile.test_initialize @ linux-x86_64 +test.test_mailbox.TestProxyFile.test_iteration @ linux-x86_64 +test.test_mailbox.TestProxyFile.test_read @ linux-x86_64 +test.test_mailbox.TestProxyFile.test_readline @ linux-x86_64 +test.test_mailbox.TestProxyFile.test_readlines @ linux-x86_64 +test.test_mailbox.TestProxyFile.test_seek_and_tell @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_mailcap.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_mailcap.txt new file mode 100644 index 0000000000..dde8262ec9 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_mailcap.txt @@ -0,0 +1,9 @@ +test.test_mailcap.FindmatchTest.test_findmatch @ linux-x86_64 +test.test_mailcap.FindmatchTest.test_test @ linux-x86_64 +test.test_mailcap.FindmatchTest.test_unsafe_mailcap_input @ linux-x86_64 +test.test_mailcap.GetcapsTest.test_mock_getcaps @ linux-x86_64 +test.test_mailcap.GetcapsTest.test_system_mailcap @ linux-x86_64 +test.test_mailcap.HelperFunctionTest.test_listmailcapfiles @ linux-x86_64 +test.test_mailcap.HelperFunctionTest.test_lookup @ linux-x86_64 +test.test_mailcap.HelperFunctionTest.test_readmailcapfile @ linux-x86_64 +test.test_mailcap.HelperFunctionTest.test_subst @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_marshal.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_marshal.txt new file mode 100644 index 0000000000..109e56ef41 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_marshal.txt @@ -0,0 +1,46 @@ +test.test_marshal.BufferTestCase.test_array @ linux-x86_64 +test.test_marshal.BufferTestCase.test_bytearray @ linux-x86_64 +test.test_marshal.BufferTestCase.test_memoryview @ linux-x86_64 +test.test_marshal.BugsTestCase.test_bad_reader @ linux-x86_64 +test.test_marshal.BugsTestCase.test_bug_5888452 @ linux-x86_64 +test.test_marshal.BugsTestCase.test_deterministic_sets @ linux-x86_64 +test.test_marshal.BugsTestCase.test_eof @ linux-x86_64 +test.test_marshal.BugsTestCase.test_exact_type_match @ linux-x86_64 +test.test_marshal.BugsTestCase.test_fuzz @ linux-x86_64 +test.test_marshal.BugsTestCase.test_large_marshal @ linux-x86_64 +test.test_marshal.BugsTestCase.test_loads_recursion @ linux-x86_64 +test.test_marshal.BugsTestCase.test_loads_reject_unicode_strings @ linux-x86_64 +test.test_marshal.BugsTestCase.test_multiple_dumps_and_loads @ linux-x86_64 +test.test_marshal.BugsTestCase.test_patch_873224 @ linux-x86_64 +test.test_marshal.BugsTestCase.test_recursion_limit @ linux-x86_64 +test.test_marshal.BugsTestCase.test_version_argument @ linux-x86_64 +test.test_marshal.CodeTestCase.test_different_filenames @ linux-x86_64 +test.test_marshal.CodeTestCase.test_many_codeobjects @ linux-x86_64 +test.test_marshal.CompatibilityTestCase.test0To3 @ linux-x86_64 +test.test_marshal.CompatibilityTestCase.test1To3 @ linux-x86_64 +test.test_marshal.CompatibilityTestCase.test2To3 @ linux-x86_64 +test.test_marshal.CompatibilityTestCase.test3To3 @ linux-x86_64 +test.test_marshal.ContainerTestCase.test_dict @ linux-x86_64 +test.test_marshal.ContainerTestCase.test_list @ linux-x86_64 +test.test_marshal.ContainerTestCase.test_sets @ linux-x86_64 +test.test_marshal.ContainerTestCase.test_tuple @ linux-x86_64 +test.test_marshal.ExceptionTestCase.test_exceptions @ linux-x86_64 +test.test_marshal.FloatTestCase.test_floats @ linux-x86_64 +test.test_marshal.InstancingTestCase.testBytes @ linux-x86_64 +test.test_marshal.InstancingTestCase.testDict @ linux-x86_64 +test.test_marshal.InstancingTestCase.testFloat @ linux-x86_64 +test.test_marshal.InstancingTestCase.testFrozenSet @ linux-x86_64 +test.test_marshal.InstancingTestCase.testInt @ linux-x86_64 +test.test_marshal.InstancingTestCase.testList @ linux-x86_64 +test.test_marshal.InstancingTestCase.testRecursion @ linux-x86_64 +test.test_marshal.InstancingTestCase.testSet @ linux-x86_64 +test.test_marshal.InstancingTestCase.testStr @ linux-x86_64 +test.test_marshal.InstancingTestCase.testTuple @ linux-x86_64 +test.test_marshal.IntTestCase.test_bool @ linux-x86_64 +test.test_marshal.IntTestCase.test_int64 @ linux-x86_64 +test.test_marshal.IntTestCase.test_ints @ linux-x86_64 +test.test_marshal.InterningTestCase.testIntern @ linux-x86_64 +test.test_marshal.InterningTestCase.testNoIntern @ linux-x86_64 +test.test_marshal.StringTestCase.test_bytes @ linux-x86_64 +test.test_marshal.StringTestCase.test_string @ linux-x86_64 +test.test_marshal.StringTestCase.test_unicode @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_math.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_math.txt new file mode 100644 index 0000000000..d1a42e7a68 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_math.txt @@ -0,0 +1,70 @@ +DocFileCase.ieee754_txt @ linux-x86_64 +test.test_math.IsCloseTests.test_asymmetry @ linux-x86_64 +test.test_math.IsCloseTests.test_decimals @ linux-x86_64 +test.test_math.IsCloseTests.test_eight_decimal_places @ linux-x86_64 +test.test_math.IsCloseTests.test_fractions @ linux-x86_64 +test.test_math.IsCloseTests.test_identical @ linux-x86_64 +test.test_math.IsCloseTests.test_identical_infinite @ linux-x86_64 +test.test_math.IsCloseTests.test_inf_ninf_nan @ linux-x86_64 +test.test_math.IsCloseTests.test_integers @ linux-x86_64 +test.test_math.IsCloseTests.test_near_zero @ linux-x86_64 +test.test_math.IsCloseTests.test_negative_tolerances @ linux-x86_64 +test.test_math.IsCloseTests.test_zero_tolerance @ linux-x86_64 +test.test_math.MathTests.testAcos @ linux-x86_64 +test.test_math.MathTests.testAcosh @ linux-x86_64 +test.test_math.MathTests.testAsin @ linux-x86_64 +test.test_math.MathTests.testAsinh @ linux-x86_64 +test.test_math.MathTests.testAtan @ linux-x86_64 +test.test_math.MathTests.testAtan2 @ linux-x86_64 +test.test_math.MathTests.testAtanh @ linux-x86_64 +test.test_math.MathTests.testCeil @ linux-x86_64 +test.test_math.MathTests.testComb @ linux-x86_64 +test.test_math.MathTests.testConstants @ linux-x86_64 +test.test_math.MathTests.testCopysign @ linux-x86_64 +test.test_math.MathTests.testCos @ linux-x86_64 +test.test_math.MathTests.testCosh @ linux-x86_64 +test.test_math.MathTests.testDegrees @ linux-x86_64 +test.test_math.MathTests.testDist @ linux-x86_64 +test.test_math.MathTests.testExp @ linux-x86_64 +test.test_math.MathTests.testFabs @ linux-x86_64 +test.test_math.MathTests.testFactorial @ linux-x86_64 +test.test_math.MathTests.testFactorialNonIntegers @ linux-x86_64 +test.test_math.MathTests.testFloor @ linux-x86_64 +test.test_math.MathTests.testFmod @ linux-x86_64 +test.test_math.MathTests.testFrexp @ linux-x86_64 +test.test_math.MathTests.testFsum @ linux-x86_64 +test.test_math.MathTests.testGcd @ linux-x86_64 +test.test_math.MathTests.testHypot @ linux-x86_64 +test.test_math.MathTests.testIsfinite @ linux-x86_64 +test.test_math.MathTests.testIsinf @ linux-x86_64 +test.test_math.MathTests.testIsnan @ linux-x86_64 +test.test_math.MathTests.testIsqrt @ linux-x86_64 +test.test_math.MathTests.testLdexp @ linux-x86_64 +test.test_math.MathTests.testLog @ linux-x86_64 +test.test_math.MathTests.testLog10 @ linux-x86_64 +test.test_math.MathTests.testLog1p @ linux-x86_64 +test.test_math.MathTests.testLog2 @ linux-x86_64 +test.test_math.MathTests.testLog2Exact @ linux-x86_64 +test.test_math.MathTests.testModf @ linux-x86_64 +test.test_math.MathTests.testPerm @ linux-x86_64 +test.test_math.MathTests.testPow @ linux-x86_64 +test.test_math.MathTests.testRadians @ linux-x86_64 +test.test_math.MathTests.testRemainder @ linux-x86_64 +test.test_math.MathTests.testSin @ linux-x86_64 +test.test_math.MathTests.testSinh @ linux-x86_64 +test.test_math.MathTests.testSqrt @ linux-x86_64 +test.test_math.MathTests.testTan @ linux-x86_64 +test.test_math.MathTests.testTanh @ linux-x86_64 +test.test_math.MathTests.testTanhSign @ linux-x86_64 +test.test_math.MathTests.test_inf_constant @ linux-x86_64 +test.test_math.MathTests.test_input_exceptions @ linux-x86_64 +test.test_math.MathTests.test_issue39871 @ linux-x86_64 +test.test_math.MathTests.test_lcm @ linux-x86_64 +test.test_math.MathTests.test_math_dist_leak @ linux-x86_64 +test.test_math.MathTests.test_mtestfile @ linux-x86_64 +test.test_math.MathTests.test_nan_constant @ linux-x86_64 +test.test_math.MathTests.test_nextafter @ linux-x86_64 +test.test_math.MathTests.test_prod @ linux-x86_64 +test.test_math.MathTests.test_testfile @ linux-x86_64 +test.test_math.MathTests.test_trunc @ linux-x86_64 +test.test_math.MathTests.test_ulp @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_memoryio.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_memoryio.txt new file mode 100644 index 0000000000..dc8498f942 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_memoryio.txt @@ -0,0 +1,157 @@ +test.test_memoryio.CBytesIOTest.testInit @ linux-x86_64 +test.test_memoryio.CBytesIOTest.testRead @ linux-x86_64 +test.test_memoryio.CBytesIOTest.testReadNoArgs @ linux-x86_64 +test.test_memoryio.CBytesIOTest.testSeek @ linux-x86_64 +test.test_memoryio.CBytesIOTest.testTell @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_bytes_array @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_detach @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_flags @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_flush @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_getstate @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_getvalue @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_init @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_instance_dict_leak @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_issue5449 @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_iterator @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_overseek @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_pickling @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_read @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_read1 @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_readinto @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_readline @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_readlines @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_relative_seek @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_seek @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_setstate @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_subclassing @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_tell @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_truncate @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_unicode @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_write @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_writelines @ linux-x86_64 +test.test_memoryio.CBytesIOTest.test_writelines_error @ linux-x86_64 +test.test_memoryio.CStringIOPickleTest.test_issue5265 @ linux-x86_64 +test.test_memoryio.CStringIOPickleTest.test_newline_argument @ linux-x86_64 +test.test_memoryio.CStringIOPickleTest.test_newline_cr @ linux-x86_64 +test.test_memoryio.CStringIOPickleTest.test_newline_crlf @ linux-x86_64 +test.test_memoryio.CStringIOPickleTest.test_newline_default @ linux-x86_64 +test.test_memoryio.CStringIOPickleTest.test_newline_empty @ linux-x86_64 +test.test_memoryio.CStringIOPickleTest.test_newline_lf @ linux-x86_64 +test.test_memoryio.CStringIOPickleTest.test_newline_none @ linux-x86_64 +test.test_memoryio.CStringIOPickleTest.test_newlines_property @ linux-x86_64 +test.test_memoryio.CStringIOPickleTest.test_relative_seek @ linux-x86_64 +test.test_memoryio.CStringIOPickleTest.test_textio_properties @ linux-x86_64 +test.test_memoryio.CStringIOTest.testInit @ linux-x86_64 +test.test_memoryio.CStringIOTest.testRead @ linux-x86_64 +test.test_memoryio.CStringIOTest.testReadNoArgs @ linux-x86_64 +test.test_memoryio.CStringIOTest.testSeek @ linux-x86_64 +test.test_memoryio.CStringIOTest.testTell @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_detach @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_flags @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_flush @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_getstate @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_getvalue @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_init @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_instance_dict_leak @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_issue5265 @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_iterator @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_newline_argument @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_newline_cr @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_newline_crlf @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_newline_default @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_newline_empty @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_newline_lf @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_newline_none @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_newlines_property @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_overseek @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_pickling @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_read @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_readline @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_readlines @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_relative_seek @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_seek @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_setstate @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_subclassing @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_tell @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_textio_properties @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_truncate @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_widechar @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_write @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_writelines @ linux-x86_64 +test.test_memoryio.CStringIOTest.test_writelines_error @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.testInit @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.testRead @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.testReadNoArgs @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.testSeek @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.testTell @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_bytes_array @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_detach @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_flags @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_flush @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_getvalue @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_init @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_instance_dict_leak @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_issue5449 @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_iterator @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_overseek @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_pickling @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_read @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_read1 @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_readinto @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_readline @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_readlines @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_relative_seek @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_seek @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_subclassing @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_tell @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_truncate @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_unicode @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_write @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_writelines @ linux-x86_64 +test.test_memoryio.PyBytesIOTest.test_writelines_error @ linux-x86_64 +test.test_memoryio.PyStringIOPickleTest.test_issue5265 @ linux-x86_64 +test.test_memoryio.PyStringIOPickleTest.test_newline_argument @ linux-x86_64 +test.test_memoryio.PyStringIOPickleTest.test_newline_cr @ linux-x86_64 +test.test_memoryio.PyStringIOPickleTest.test_newline_crlf @ linux-x86_64 +test.test_memoryio.PyStringIOPickleTest.test_newline_default @ linux-x86_64 +test.test_memoryio.PyStringIOPickleTest.test_newline_empty @ linux-x86_64 +test.test_memoryio.PyStringIOPickleTest.test_newline_lf @ linux-x86_64 +test.test_memoryio.PyStringIOPickleTest.test_newline_none @ linux-x86_64 +test.test_memoryio.PyStringIOPickleTest.test_newlines_property @ linux-x86_64 +test.test_memoryio.PyStringIOPickleTest.test_relative_seek @ linux-x86_64 +test.test_memoryio.PyStringIOPickleTest.test_textio_properties @ linux-x86_64 +test.test_memoryio.PyStringIOTest.testInit @ linux-x86_64 +test.test_memoryio.PyStringIOTest.testRead @ linux-x86_64 +test.test_memoryio.PyStringIOTest.testReadNoArgs @ linux-x86_64 +test.test_memoryio.PyStringIOTest.testSeek @ linux-x86_64 +test.test_memoryio.PyStringIOTest.testTell @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_detach @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_flags @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_flush @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_getvalue @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_init @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_instance_dict_leak @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_issue5265 @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_iterator @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_newline_argument @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_newline_cr @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_newline_crlf @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_newline_default @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_newline_empty @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_newline_lf @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_newline_none @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_newlines_property @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_overseek @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_pickling @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_read @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_readline @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_readlines @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_relative_seek @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_seek @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_subclassing @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_tell @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_textio_properties @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_truncate @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_write @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_writelines @ linux-x86_64 +test.test_memoryio.PyStringIOTest.test_writelines_error @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_memoryview.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_memoryview.txt new file mode 100644 index 0000000000..70524bce56 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_memoryview.txt @@ -0,0 +1,107 @@ +test.test_memoryview.ArrayMemorySliceSliceTest.test_attributes_writable @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceSliceTest.test_compare @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceSliceTest.test_contextmanager @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceSliceTest.test_delitem @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceSliceTest.test_getbuf_fail @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceSliceTest.test_getitem @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceSliceTest.test_hash_writable @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceSliceTest.test_issue22668 @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceSliceTest.test_iter @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceSliceTest.test_release @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceSliceTest.test_reversed @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceSliceTest.test_setitem_writable @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceSliceTest.test_tobytes @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceSliceTest.test_toreadonly @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceTest.test_attributes_writable @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceTest.test_compare @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceTest.test_contextmanager @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceTest.test_delitem @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceTest.test_getbuf_fail @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceTest.test_getitem @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceTest.test_hash_writable @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceTest.test_issue22668 @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceTest.test_iter @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceTest.test_release @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceTest.test_reversed @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceTest.test_setitem_writable @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceTest.test_tobytes @ linux-x86_64 +test.test_memoryview.ArrayMemorySliceTest.test_toreadonly @ linux-x86_64 +test.test_memoryview.ArrayMemoryviewTest.test_array_assign @ linux-x86_64 +test.test_memoryview.ArrayMemoryviewTest.test_attributes_writable @ linux-x86_64 +test.test_memoryview.ArrayMemoryviewTest.test_compare @ linux-x86_64 +test.test_memoryview.ArrayMemoryviewTest.test_contextmanager @ linux-x86_64 +test.test_memoryview.ArrayMemoryviewTest.test_delitem @ linux-x86_64 +test.test_memoryview.ArrayMemoryviewTest.test_getbuf_fail @ linux-x86_64 +test.test_memoryview.ArrayMemoryviewTest.test_getitem @ linux-x86_64 +test.test_memoryview.ArrayMemoryviewTest.test_hash_writable @ linux-x86_64 +test.test_memoryview.ArrayMemoryviewTest.test_issue22668 @ linux-x86_64 +test.test_memoryview.ArrayMemoryviewTest.test_iter @ linux-x86_64 +test.test_memoryview.ArrayMemoryviewTest.test_release @ linux-x86_64 +test.test_memoryview.ArrayMemoryviewTest.test_reversed @ linux-x86_64 +test.test_memoryview.ArrayMemoryviewTest.test_setitem_writable @ linux-x86_64 +test.test_memoryview.ArrayMemoryviewTest.test_tobytes @ linux-x86_64 +test.test_memoryview.ArrayMemoryviewTest.test_toreadonly @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_attributes_readonly @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_attributes_writable @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_compare @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_contextmanager @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_delitem @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_getbuf_fail @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_getbuffer @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_getitem @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_hash @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_hash_writable @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_issue22668 @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_iter @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_release @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_reversed @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_setitem_readonly @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_setitem_writable @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_tobytes @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_tolist @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_toreadonly @ linux-x86_64 +test.test_memoryview.BytesMemorySliceSliceTest.test_writable_readonly @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_attributes_readonly @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_attributes_writable @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_compare @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_contextmanager @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_delitem @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_getbuf_fail @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_getbuffer @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_getitem @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_hash @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_hash_writable @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_issue22668 @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_iter @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_release @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_reversed @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_setitem_readonly @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_setitem_writable @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_tobytes @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_tolist @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_toreadonly @ linux-x86_64 +test.test_memoryview.BytesMemorySliceTest.test_writable_readonly @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_attributes_readonly @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_attributes_writable @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_compare @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_constructor @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_contextmanager @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_delitem @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_getbuf_fail @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_getbuffer @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_getitem @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_hash @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_hash_writable @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_issue22668 @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_iter @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_release @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_reversed @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_setitem_readonly @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_setitem_writable @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_tobytes @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_tolist @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_toreadonly @ linux-x86_64 +test.test_memoryview.BytesMemoryviewTest.test_writable_readonly @ linux-x86_64 +test.test_memoryview.OtherTest.test_copy @ linux-x86_64 +test.test_memoryview.OtherTest.test_memoryview_hex @ linux-x86_64 +test.test_memoryview.OtherTest.test_pickle @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_metaclass.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_metaclass.txt new file mode 100644 index 0000000000..2b9509c9f5 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_metaclass.txt @@ -0,0 +1 @@ +DocTestCase.test.test_metaclass.__test__.doctests @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_mimetypes.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_mimetypes.txt new file mode 100644 index 0000000000..e71077bf05 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_mimetypes.txt @@ -0,0 +1,20 @@ +test.test_mimetypes.MimeTypesTestCase.test_case_sensitivity @ linux-x86_64 +test.test_mimetypes.MimeTypesTestCase.test_data_urls @ linux-x86_64 +test.test_mimetypes.MimeTypesTestCase.test_default_data @ linux-x86_64 +test.test_mimetypes.MimeTypesTestCase.test_encoding @ linux-x86_64 +test.test_mimetypes.MimeTypesTestCase.test_file_parsing @ linux-x86_64 +test.test_mimetypes.MimeTypesTestCase.test_filename_with_url_delimiters @ linux-x86_64 +test.test_mimetypes.MimeTypesTestCase.test_guess_all_types @ linux-x86_64 +test.test_mimetypes.MimeTypesTestCase.test_guess_known_extensions @ linux-x86_64 +test.test_mimetypes.MimeTypesTestCase.test_init_reinitializes @ linux-x86_64 +test.test_mimetypes.MimeTypesTestCase.test_init_stability @ linux-x86_64 +test.test_mimetypes.MimeTypesTestCase.test_keywords_args_api @ linux-x86_64 +test.test_mimetypes.MimeTypesTestCase.test_non_standard_types @ linux-x86_64 +test.test_mimetypes.MimeTypesTestCase.test_path_like_ob @ linux-x86_64 +test.test_mimetypes.MimeTypesTestCase.test_preferred_extension @ linux-x86_64 +test.test_mimetypes.MimeTypesTestCase.test_read_mime_types @ linux-x86_64 +test.test_mimetypes.MimetypesCliTestCase.test_guess_extension @ linux-x86_64 +test.test_mimetypes.MimetypesCliTestCase.test_guess_type @ linux-x86_64 +test.test_mimetypes.MimetypesCliTestCase.test_help_option @ linux-x86_64 +test.test_mimetypes.MimetypesCliTestCase.test_invalid_option @ linux-x86_64 +test.test_mimetypes.MiscTestCase.test__all__ @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_minidom.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_minidom.txt new file mode 100644 index 0000000000..e05f7b0085 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_minidom.txt @@ -0,0 +1,128 @@ +test.test_minidom.MinidomTest.testAAA @ linux-x86_64 +test.test_minidom.MinidomTest.testAAB @ linux-x86_64 +test.test_minidom.MinidomTest.testAddAttr @ linux-x86_64 +test.test_minidom.MinidomTest.testAltNewline @ linux-x86_64 +test.test_minidom.MinidomTest.testAppendChild @ linux-x86_64 +test.test_minidom.MinidomTest.testAppendChildFragment @ linux-x86_64 +test.test_minidom.MinidomTest.testAttrListItem @ linux-x86_64 +test.test_minidom.MinidomTest.testAttrListItemNS @ linux-x86_64 +test.test_minidom.MinidomTest.testAttrListItems @ linux-x86_64 +test.test_minidom.MinidomTest.testAttrListKeys @ linux-x86_64 +test.test_minidom.MinidomTest.testAttrListKeysNS @ linux-x86_64 +test.test_minidom.MinidomTest.testAttrListLength @ linux-x86_64 +test.test_minidom.MinidomTest.testAttrListValues @ linux-x86_64 +test.test_minidom.MinidomTest.testAttrList__getitem__ @ linux-x86_64 +test.test_minidom.MinidomTest.testAttrList__setitem__ @ linux-x86_64 +test.test_minidom.MinidomTest.testAttrModeSetsNonOptionalAttrs @ linux-x86_64 +test.test_minidom.MinidomTest.testAttrModeSetsParamsAsAttrs @ linux-x86_64 +test.test_minidom.MinidomTest.testAttributeRepr @ linux-x86_64 +test.test_minidom.MinidomTest.testBug0777884 @ linux-x86_64 +test.test_minidom.MinidomTest.testBug1433694 @ linux-x86_64 +test.test_minidom.MinidomTest.testChangeAttr @ linux-x86_64 +test.test_minidom.MinidomTest.testChildNodes @ linux-x86_64 +test.test_minidom.MinidomTest.testCloneAttributeDeep @ linux-x86_64 +test.test_minidom.MinidomTest.testCloneAttributeShallow @ linux-x86_64 +test.test_minidom.MinidomTest.testCloneDocumentDeep @ linux-x86_64 +test.test_minidom.MinidomTest.testCloneDocumentShallow @ linux-x86_64 +test.test_minidom.MinidomTest.testCloneDocumentTypeDeepNotOk @ linux-x86_64 +test.test_minidom.MinidomTest.testCloneDocumentTypeDeepOk @ linux-x86_64 +test.test_minidom.MinidomTest.testCloneDocumentTypeShallowNotOk @ linux-x86_64 +test.test_minidom.MinidomTest.testCloneDocumentTypeShallowOk @ linux-x86_64 +test.test_minidom.MinidomTest.testCloneElementDeep @ linux-x86_64 +test.test_minidom.MinidomTest.testCloneElementShallow @ linux-x86_64 +test.test_minidom.MinidomTest.testCloneNodeEntity @ linux-x86_64 +test.test_minidom.MinidomTest.testClonePIDeep @ linux-x86_64 +test.test_minidom.MinidomTest.testClonePIShallow @ linux-x86_64 +test.test_minidom.MinidomTest.testComment @ linux-x86_64 +test.test_minidom.MinidomTest.testContext @ linux-x86_64 +test.test_minidom.MinidomTest.testCreateAttributeNS @ linux-x86_64 +test.test_minidom.MinidomTest.testCreateElementNS @ linux-x86_64 +test.test_minidom.MinidomTest.testDeepcopiedDocument @ linux-x86_64 +test.test_minidom.MinidomTest.testDeleteAttr @ linux-x86_64 +test.test_minidom.MinidomTest.testDocRemoveChild @ linux-x86_64 +test.test_minidom.MinidomTest.testDocumentAsyncAttr @ linux-x86_64 +test.test_minidom.MinidomTest.testDocumentElement @ linux-x86_64 +test.test_minidom.MinidomTest.testElement @ linux-x86_64 +test.test_minidom.MinidomTest.testElementReprAndStr @ linux-x86_64 +test.test_minidom.MinidomTest.testElementReprAndStrUnicode @ linux-x86_64 +test.test_minidom.MinidomTest.testElementReprAndStrUnicodeNS @ linux-x86_64 +test.test_minidom.MinidomTest.testEmptyXMLNSValue @ linux-x86_64 +test.test_minidom.MinidomTest.testExceptionOnSpacesInXMLNSValue @ linux-x86_64 +test.test_minidom.MinidomTest.testFirstChild @ linux-x86_64 +test.test_minidom.MinidomTest.testGetAttrLength @ linux-x86_64 +test.test_minidom.MinidomTest.testGetAttrList @ linux-x86_64 +test.test_minidom.MinidomTest.testGetAttrValues @ linux-x86_64 +test.test_minidom.MinidomTest.testGetAttribute @ linux-x86_64 +test.test_minidom.MinidomTest.testGetAttributeNS @ linux-x86_64 +test.test_minidom.MinidomTest.testGetAttributeNode @ linux-x86_64 +test.test_minidom.MinidomTest.testGetElementsByTagName @ linux-x86_64 +test.test_minidom.MinidomTest.testGetElementsByTagNameNS @ linux-x86_64 +test.test_minidom.MinidomTest.testGetEmptyNodeListFromElementsByTagNameNS @ linux-x86_64 +test.test_minidom.MinidomTest.testHasAttribute @ linux-x86_64 +test.test_minidom.MinidomTest.testHasChildNodes @ linux-x86_64 +test.test_minidom.MinidomTest.testImportDocumentDeep @ linux-x86_64 +test.test_minidom.MinidomTest.testImportDocumentShallow @ linux-x86_64 +test.test_minidom.MinidomTest.testImportDocumentTypeDeep @ linux-x86_64 +test.test_minidom.MinidomTest.testImportDocumentTypeShallow @ linux-x86_64 +test.test_minidom.MinidomTest.testInsertBefore @ linux-x86_64 +test.test_minidom.MinidomTest.testInsertBeforeFragment @ linux-x86_64 +test.test_minidom.MinidomTest.testLegalChildren @ linux-x86_64 +test.test_minidom.MinidomTest.testNamedNodeMapSetItem @ linux-x86_64 +test.test_minidom.MinidomTest.testNodeListItem @ linux-x86_64 +test.test_minidom.MinidomTest.testNonZero @ linux-x86_64 +test.test_minidom.MinidomTest.testNormalize @ linux-x86_64 +test.test_minidom.MinidomTest.testNormalizeCombineAndNextSibling @ linux-x86_64 +test.test_minidom.MinidomTest.testNormalizeDeleteAndCombine @ linux-x86_64 +test.test_minidom.MinidomTest.testNormalizeDeleteWithNextSibling @ linux-x86_64 +test.test_minidom.MinidomTest.testNormalizeDeleteWithPrevSibling @ linux-x86_64 +test.test_minidom.MinidomTest.testNormalizeDeleteWithTwoNonTextSiblings @ linux-x86_64 +test.test_minidom.MinidomTest.testNormalizeRecursion @ linux-x86_64 +test.test_minidom.MinidomTest.testParents @ linux-x86_64 +test.test_minidom.MinidomTest.testParse @ linux-x86_64 +test.test_minidom.MinidomTest.testParseAttributeNamespaces @ linux-x86_64 +test.test_minidom.MinidomTest.testParseAttributes @ linux-x86_64 +test.test_minidom.MinidomTest.testParseElement @ linux-x86_64 +test.test_minidom.MinidomTest.testParseElementNamespaces @ linux-x86_64 +test.test_minidom.MinidomTest.testParseFromBinaryFile @ linux-x86_64 +test.test_minidom.MinidomTest.testParseFromTextFile @ linux-x86_64 +test.test_minidom.MinidomTest.testParseProcessingInstructions @ linux-x86_64 +test.test_minidom.MinidomTest.testParseString @ linux-x86_64 +test.test_minidom.MinidomTest.testPatch1094164 @ linux-x86_64 +test.test_minidom.MinidomTest.testPickledDocument @ linux-x86_64 +test.test_minidom.MinidomTest.testProcessingInstruction @ linux-x86_64 +test.test_minidom.MinidomTest.testProcessingInstructionNameError @ linux-x86_64 +test.test_minidom.MinidomTest.testProcessingInstructionRepr @ linux-x86_64 +test.test_minidom.MinidomTest.testRemoveAttr @ linux-x86_64 +test.test_minidom.MinidomTest.testRemoveAttrNS @ linux-x86_64 +test.test_minidom.MinidomTest.testRemoveAttributeNode @ linux-x86_64 +test.test_minidom.MinidomTest.testRemoveNamedItem @ linux-x86_64 +test.test_minidom.MinidomTest.testRemoveNamedItemNS @ linux-x86_64 +test.test_minidom.MinidomTest.testRenameAttribute @ linux-x86_64 +test.test_minidom.MinidomTest.testRenameElement @ linux-x86_64 +test.test_minidom.MinidomTest.testRenameOther @ linux-x86_64 +test.test_minidom.MinidomTest.testReplaceChildFragment @ linux-x86_64 +test.test_minidom.MinidomTest.testReplaceWholeText @ linux-x86_64 +test.test_minidom.MinidomTest.testSchemaType @ linux-x86_64 +test.test_minidom.MinidomTest.testSerializeCommentNodeWithDoubleHyphen @ linux-x86_64 +test.test_minidom.MinidomTest.testSetAttrValueandNodeValue @ linux-x86_64 +test.test_minidom.MinidomTest.testSetIdAttribute @ linux-x86_64 +test.test_minidom.MinidomTest.testSetIdAttributeNS @ linux-x86_64 +test.test_minidom.MinidomTest.testSetIdAttributeNode @ linux-x86_64 +test.test_minidom.MinidomTest.testSiblings @ linux-x86_64 +test.test_minidom.MinidomTest.testStandalone @ linux-x86_64 +test.test_minidom.MinidomTest.testTextNodeRepr @ linux-x86_64 +test.test_minidom.MinidomTest.testTextRepr @ linux-x86_64 +test.test_minidom.MinidomTest.testTooManyDocumentElements @ linux-x86_64 +test.test_minidom.MinidomTest.testUnlink @ linux-x86_64 +test.test_minidom.MinidomTest.testUserData @ linux-x86_64 +test.test_minidom.MinidomTest.testWholeText @ linux-x86_64 +test.test_minidom.MinidomTest.testWriteText @ linux-x86_64 +test.test_minidom.MinidomTest.testWriteXML @ linux-x86_64 +test.test_minidom.MinidomTest.test_cdata_parsing @ linux-x86_64 +test.test_minidom.MinidomTest.test_minidom_attribute_order @ linux-x86_64 +test.test_minidom.MinidomTest.test_toprettyxml_preserves_content_of_text_node @ linux-x86_64 +test.test_minidom.MinidomTest.test_toprettyxml_with_adjacent_text_nodes @ linux-x86_64 +test.test_minidom.MinidomTest.test_toprettyxml_with_attributes_ordered @ linux-x86_64 +test.test_minidom.MinidomTest.test_toprettyxml_with_cdata @ linux-x86_64 +test.test_minidom.MinidomTest.test_toprettyxml_with_text_nodes @ linux-x86_64 +test.test_minidom.MinidomTest.test_toxml_with_attributes_ordered @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_mmap.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_mmap.txt new file mode 100644 index 0000000000..f941254fe9 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_mmap.txt @@ -0,0 +1,22 @@ +test.test_mmap.LargeMmapTests.test_large_offset @ linux-x86_64 +test.test_mmap.MmapTests.test_anonymous @ linux-x86_64 +test.test_mmap.MmapTests.test_bad_file_desc @ linux-x86_64 +test.test_mmap.MmapTests.test_basic @ linux-x86_64 +test.test_mmap.MmapTests.test_concat_repeat_exception @ linux-x86_64 +test.test_mmap.MmapTests.test_context_manager @ linux-x86_64 +test.test_mmap.MmapTests.test_context_manager_exception @ linux-x86_64 +test.test_mmap.MmapTests.test_double_close @ linux-x86_64 +test.test_mmap.MmapTests.test_empty_file @ linux-x86_64 +test.test_mmap.MmapTests.test_entire_file @ linux-x86_64 +test.test_mmap.MmapTests.test_extended_set_del_slice @ linux-x86_64 +test.test_mmap.MmapTests.test_find_does_not_access_beyond_buffer @ linux-x86_64 +test.test_mmap.MmapTests.test_find_end @ linux-x86_64 +test.test_mmap.MmapTests.test_length_0_large_offset @ linux-x86_64 +test.test_mmap.MmapTests.test_length_0_offset @ linux-x86_64 +test.test_mmap.MmapTests.test_offset @ linux-x86_64 +test.test_mmap.MmapTests.test_prot_readonly @ linux-x86_64 +test.test_mmap.MmapTests.test_read_all @ linux-x86_64 +test.test_mmap.MmapTests.test_read_invalid_arg @ linux-x86_64 +test.test_mmap.MmapTests.test_subclass @ linux-x86_64 +test.test_mmap.MmapTests.test_tougher_find @ linux-x86_64 +test.test_mmap.MmapTests.test_write_returning_the_number_of_bytes_written @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_module.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_module.txt new file mode 100644 index 0000000000..284e45ea81 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_module.txt @@ -0,0 +1,34 @@ +test.test_module.ModuleTests.test_annotations_are_created_correctly @ linux-x86_64 +test.test_module.ModuleTests.test_annotations_getset_raises @ linux-x86_64 +test.test_module.ModuleTests.test_ascii_docstring @ linux-x86_64 +test.test_module.ModuleTests.test_descriptor_errors_propagate @ linux-x86_64 +test.test_module.ModuleTests.test_dont_clear_dict @ linux-x86_64 +test.test_module.ModuleTests.test_lazy_create_annotations @ linux-x86_64 +test.test_module.ModuleTests.test_missing_getattr @ linux-x86_64 +test.test_module.ModuleTests.test_module_dir @ linux-x86_64 +test.test_module.ModuleTests.test_module_dir_errors @ linux-x86_64 +test.test_module.ModuleTests.test_module_getattr @ linux-x86_64 +test.test_module.ModuleTests.test_module_getattr_errors @ linux-x86_64 +test.test_module.ModuleTests.test_module_getattr_tricky @ linux-x86_64 +test.test_module.ModuleTests.test_module_repr_builtin @ linux-x86_64 +test.test_module.ModuleTests.test_module_repr_minimal @ linux-x86_64 +test.test_module.ModuleTests.test_module_repr_source @ linux-x86_64 +test.test_module.ModuleTests.test_module_repr_with_bare_loader @ linux-x86_64 +test.test_module.ModuleTests.test_module_repr_with_bare_loader_and_filename @ linux-x86_64 +test.test_module.ModuleTests.test_module_repr_with_bare_loader_but_no_name @ linux-x86_64 +test.test_module.ModuleTests.test_module_repr_with_filename_only @ linux-x86_64 +test.test_module.ModuleTests.test_module_repr_with_full_loader @ linux-x86_64 +test.test_module.ModuleTests.test_module_repr_with_full_loader_and_filename @ linux-x86_64 +test.test_module.ModuleTests.test_module_repr_with_full_loader_but_no_name @ linux-x86_64 +test.test_module.ModuleTests.test_module_repr_with_loader_as_None @ linux-x86_64 +test.test_module.ModuleTests.test_module_repr_with_name @ linux-x86_64 +test.test_module.ModuleTests.test_module_repr_with_name_and_filename @ linux-x86_64 +test.test_module.ModuleTests.test_no_docstring @ linux-x86_64 +test.test_module.ModuleTests.test_reinit @ linux-x86_64 +test.test_module.ModuleTests.test_repeated_attribute_pops @ linux-x86_64 +test.test_module.ModuleTests.test_setting_annotations @ linux-x86_64 +test.test_module.ModuleTests.test_subclass_with_slots @ linux-x86_64 +test.test_module.ModuleTests.test_unicode_docstring @ linux-x86_64 +test.test_module.ModuleTests.test_uninitialized @ linux-x86_64 +test.test_module.ModuleTests.test_uninitialized_missing_getattr @ linux-x86_64 +test.test_module.ModuleTests.test_weakref @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_multibytecodec.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_multibytecodec.txt new file mode 100644 index 0000000000..ae4b98b3c1 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_multibytecodec.txt @@ -0,0 +1,10 @@ +test.test_multibytecodec.TestStateful.test_encode @ linux-x86_64 +test.test_multibytecodec.Test_ISO2022.test_bug1572832 @ linux-x86_64 +test.test_multibytecodec.Test_IncrementalDecoder.test_dbcs @ linux-x86_64 +test.test_multibytecodec.Test_IncrementalDecoder.test_dbcs_keep_buffer @ linux-x86_64 +test.test_multibytecodec.Test_IncrementalEncoder.test_issue5640 @ linux-x86_64 +test.test_multibytecodec.Test_IncrementalEncoder.test_stateless @ linux-x86_64 +test.test_multibytecodec.Test_MultibyteCodec.test_codingspec @ linux-x86_64 +test.test_multibytecodec.Test_StreamWriter.test_gb18030 @ linux-x86_64 +test.test_multibytecodec.Test_StreamWriter.test_streamwriter_strwrite @ linux-x86_64 +test.test_multibytecodec.Test_StreamWriter.test_utf_8 @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_multiprocessing_spawn.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_multiprocessing_spawn.txt new file mode 100644 index 0000000000..cc75ee9221 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_multiprocessing_spawn.txt @@ -0,0 +1,192 @@ +test.test_multiprocessing_spawn.test_misc.MiscTestCase.test__all__ @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.MiscTestCase.test_spawn_sys_executable_none_allows_import @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.OtherTest.test_answer_challenge_auth_failure @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.OtherTest.test_deliver_challenge_auth_failure @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.SemLockTests.test_semlock_subclass @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestForkAwareThreadLock.test_lock @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestIgnoreEINTR.test_ignore @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestIgnoreEINTR.test_ignore_listener @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestInternalDecorators.test_only_run_in_spawn_testsuite @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestInvalidFamily.test_invalid_family @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestInvalidHandle.test_invalid_handles @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestNamedResource.test_global_named_resource_spawn @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestNoForkBomb.test_noforkbomb @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestPoolNotLeakOnFailure.test_release_unused_processes @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestResourceTracker.test_resource_tracker @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestResourceTracker.test_resource_tracker_reused @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestResourceTracker.test_too_long_name_resource @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSimpleQueue.test_close @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSimpleQueue.test_empty @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestStartMethod.test_get_all @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestStartMethod.test_nested_startmethod @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestStdinBadfiledescriptor.test_flushing @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestStdinBadfiledescriptor.test_pool_in_process @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestStdinBadfiledescriptor.test_queue_in_process @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSyncManagerTypes.test_array @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSyncManagerTypes.test_barrier @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSyncManagerTypes.test_bounded_semaphore @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSyncManagerTypes.test_condition @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSyncManagerTypes.test_dict @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSyncManagerTypes.test_event @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSyncManagerTypes.test_joinable_queue @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSyncManagerTypes.test_list @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSyncManagerTypes.test_namespace @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSyncManagerTypes.test_pool @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSyncManagerTypes.test_queue @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSyncManagerTypes.test_rlock @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSyncManagerTypes.test_semaphore @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestSyncManagerTypes.test_value @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestTimeouts.test_timeout @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestWait.test_neg_timeout @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestWait.test_wait @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestWait.test_wait_slow @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestWait.test_wait_socket @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestWait.test_wait_socket_slow @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc.TestWait.test_wait_timeout @ linux-x86_64 +test.test_multiprocessing_spawn.test_misc._TestImportStar.test_import @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestArray.test_array @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestArray.test_array_from_size @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestArray.test_getobj_getlock_obj @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestArray.test_rawarray @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestCondition.test_notify @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestCondition.test_notify_all @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestCondition.test_notify_n @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestCondition.test_timeout @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestConnection.test_connection @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestConnection.test_context @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestConnection.test_duplex_false @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestConnection.test_sendbytes @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestConnection.test_spawn_close @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestEvent.test_event @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestEvent.test_repr @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestListener.test_abstract_socket @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestListener.test_context @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestListener.test_multiple_bind @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestListenerClient.test_issue14725 @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestListenerClient.test_issue16955 @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestListenerClient.test_listener_client @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestLock.test_lock @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestLock.test_lock_context @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestLock.test_rlock @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestLogging.test_enable_logging @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestLogging.test_level @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestManagerRestart.test_rapid_restart @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPoll.test_boundaries @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPoll.test_dont_merge @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPoll.test_empty_string @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPoll.test_strings @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPollEintr.test_poll_eintr @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_apply @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_async @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_async_timeout @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_context @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_empty_iterable @ linux-x86_64 +!test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_enter @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_imap @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_imap_handle_iterable_exception @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_imap_unordered @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_imap_unordered_handle_iterable_exception @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_make_pool @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_map @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_map_async @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_map_async_callbacks @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_map_chunksize @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_map_handle_iterable_exception @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_map_no_failfast @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_starmap @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_starmap_async @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_terminate @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_traceback @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPool.test_wrapped_exception @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPoolWorkerErrors.test_async_error_callback @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPoolWorkerErrors.test_unpickleable_result @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPoolWorkerLifetime.test_pool_maxtasksperchild_invalid @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPoolWorkerLifetime.test_pool_worker_lifetime @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPoolWorkerLifetime.test_pool_worker_lifetime_early_close @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestPoolWorkerLifetime.test_worker_finalization_via_atexit_handler_of_multiprocessing @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_active_children @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_args_argument @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_child_fd_inflation @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_cpu_count @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_current @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_daemon_argument @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_error_on_stdio_flush_1 @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_error_on_stdio_flush_2 @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_kill @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_parent_process @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_parent_process_attributes @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_process @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_recursion @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_sentinel @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_set_executable @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_terminate @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestProcess.test_wait_for_threads @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestQueue.test_closed_queue_put_get_exceptions @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestQueue.test_fork @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestQueue.test_get @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestQueue.test_no_import_lock_contention @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestQueue.test_put @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestQueue.test_qsize @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestQueue.test_queue_feeder_donot_stop_onexc @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestQueue.test_queue_feeder_on_queue_feeder_error @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestQueue.test_task_done @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestQueue.test_timeout @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestSemaphore.test_bounded_semaphore @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestSemaphore.test_semaphore @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestSemaphore.test_timeout @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestSubclassingProcess.test_stderr_flush @ linux-x86_64 +test.test_multiprocessing_spawn.test_processes.WithProcessesTestSubclassingProcess.test_subclassing @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestCondition.test_notify @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestCondition.test_notify_all @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestCondition.test_notify_n @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestCondition.test_timeout @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestConnection.test_connection @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestConnection.test_context @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestConnection.test_duplex_false @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestConnection.test_spawn_close @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestEvent.test_event @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestEvent.test_repr @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestListenerClient.test_issue14725 @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestListenerClient.test_issue16955 @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestListenerClient.test_listener_client @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestLock.test_lock_context @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestLock.test_rlock @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestManagerRestart.test_rapid_restart @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPoll.test_boundaries @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPoll.test_dont_merge @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPoll.test_empty_string @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPoll.test_strings @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_apply @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_async @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_async_timeout @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_context @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_empty_iterable @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_enter @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_imap @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_imap_unordered @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_make_pool @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_map @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_map_async @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_map_async_callbacks @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_map_chunksize @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_map_no_failfast @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_starmap @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_starmap_async @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestPool.test_traceback @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestProcess.test_active_children @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestProcess.test_args_argument @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestProcess.test_cpu_count @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestProcess.test_error_on_stdio_flush_1 @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestProcess.test_error_on_stdio_flush_2 @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestProcess.test_process @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestProcess.test_recursion @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestQueue.test_closed_queue_put_get_exceptions @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestQueue.test_fork @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestQueue.test_get @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestQueue.test_no_import_lock_contention @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestQueue.test_put @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestQueue.test_qsize @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestQueue.test_task_done @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestQueue.test_timeout @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestSemaphore.test_bounded_semaphore @ linux-x86_64 +test.test_multiprocessing_spawn.test_threads.WithThreadsTestSemaphore.test_semaphore @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_named_expressions.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_named_expressions.txt new file mode 100644 index 0000000000..eaec897c19 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_named_expressions.txt @@ -0,0 +1,65 @@ +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_01 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_02 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_03 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_04 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_05 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_06 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_07 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_08 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_09 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_10 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_11 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_12 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_13 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_14 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_15 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_16 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_17 @ linux-x86_64 +test.test_named_expressions.NamedExpressionAssignmentTest.test_named_expression_assignment_18 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_01 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_02 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_03 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_04 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_06 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_07 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_08 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_09 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_10 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_11 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_12 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_13 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_14 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_15 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_16 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_17 @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_in_class_body @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_list_comprehension_iterable_expression @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_rebinding_list_comprehension_inner_loop @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_rebinding_set_comprehension_inner_loop @ linux-x86_64 +test.test_named_expressions.NamedExpressionInvalidTest.test_named_expression_invalid_set_comprehension_iterable_expression @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_global_scope @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_global_scope_no_global_keyword @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_nonlocal_scope @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_nonlocal_scope_no_nonlocal_keyword @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_01 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_02 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_03 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_04 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_05 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_06 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_07 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_08 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_09 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_10 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_11 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_17 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_18 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_19 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_20 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_21 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_22 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_23 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_24 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_25 @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_scope_in_genexp @ linux-x86_64 +test.test_named_expressions.NamedExpressionScopeTest.test_named_expression_variable_reuse_in_comprehensions @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_netrc.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_netrc.txt new file mode 100644 index 0000000000..145cb4c1f5 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_netrc.txt @@ -0,0 +1,22 @@ +test.test_netrc.NetrcTestCase.test_comment_after_machine_line @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_comment_after_machine_line_hash_only @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_comment_after_machine_line_no_space @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_comment_at_end_of_machine_line @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_comment_at_end_of_machine_line_no_space @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_comment_at_end_of_machine_line_pass_has_hash @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_comment_before_machine_line @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_comment_before_machine_line_hash_only @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_comment_before_machine_line_no_space @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_invalid_tokens @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_macros @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_optional_tokens @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_security @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_token_value_escape @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_token_value_internal_hash @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_token_value_leading_hash @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_token_value_non_ascii @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_token_value_quotes @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_token_value_trailing_hash @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_token_value_whitespace @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_toplevel_non_ordered_tokens @ linux-x86_64 +test.test_netrc.NetrcTestCase.test_toplevel_tokens @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_nntplib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_nntplib.txt new file mode 100644 index 0000000000..139268cb91 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_nntplib.txt @@ -0,0 +1,71 @@ +test.test_nntplib.CapsAfterLoginNNTPv2Tests.test_caps_only_after_login @ linux-x86_64 +test.test_nntplib.LocalServerTests.test_starttls @ linux-x86_64 +test.test_nntplib.MiscTests.test_decode_header @ linux-x86_64 +test.test_nntplib.MiscTests.test_parse_datetime @ linux-x86_64 +test.test_nntplib.MiscTests.test_parse_overview @ linux-x86_64 +test.test_nntplib.MiscTests.test_parse_overview_fmt @ linux-x86_64 +test.test_nntplib.MiscTests.test_ssl_support @ linux-x86_64 +test.test_nntplib.MiscTests.test_unparse_datetime @ linux-x86_64 +test.test_nntplib.MiscTests.test_unparse_datetime_legacy @ linux-x86_64 +test.test_nntplib.MockSocketTests.test_bad_capabilities @ linux-x86_64 +test.test_nntplib.MockSocketTests.test_bad_welcome @ linux-x86_64 +test.test_nntplib.MockSocketTests.test_login_aborted @ linux-x86_64 +test.test_nntplib.MockSocketTests.test_service_permanently_unavailable @ linux-x86_64 +test.test_nntplib.MockSocketTests.test_service_temporarily_unavailable @ linux-x86_64 +test.test_nntplib.MockSslTests.test_bad_capabilities @ linux-x86_64 +test.test_nntplib.MockSslTests.test_bad_welcome @ linux-x86_64 +test.test_nntplib.MockSslTests.test_login_aborted @ linux-x86_64 +test.test_nntplib.MockSslTests.test_service_permanently_unavailable @ linux-x86_64 +test.test_nntplib.MockSslTests.test_service_temporarily_unavailable @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_article @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_article_file @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_authinfo @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_body @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_body_file @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_caps @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_date @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_description @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_descriptions @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_group @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_head @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_head_file @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_help @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_ihave @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_last @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_list @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_newnews @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_next @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_over @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_post @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_quit @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_stat @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_too_long_lines @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_welcome @ linux-x86_64 +test.test_nntplib.NNTPv1Tests.test_xover @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_article @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_article_file @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_authinfo @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_body @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_body_file @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_caps @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_date @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_description @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_descriptions @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_group @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_head @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_head_file @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_help @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_ihave @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_last @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_list @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_newnews @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_next @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_over @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_post @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_quit @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_stat @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_too_long_lines @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_welcome @ linux-x86_64 +test.test_nntplib.NNTPv2Tests.test_xover @ linux-x86_64 +test.test_nntplib.PublicAPITests.test_module_all_attribute @ linux-x86_64 +test.test_nntplib.SendReaderNNTPv2Tests.test_we_are_in_reader_mode_after_connect @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ntpath.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ntpath.txt new file mode 100644 index 0000000000..edcc20c1fe --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ntpath.txt @@ -0,0 +1,63 @@ +test.test_ntpath.NtCommonTest.test_abspath @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_abspath_issue3426 @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_commonprefix @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_exists @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_exists_fd @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_expandvars @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_expandvars_nonascii @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_filetime @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_getsize @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_import @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_isdir @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_isfile @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_join_errors @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_no_argument @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_nonascii_abspath @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_normcase @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_normpath_issue106242 @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_normpath_issue5827 @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_realpath @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_relpath_errors @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_samefile @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_samefile_on_link @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_samefile_on_symlink @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_sameopenfile @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_samestat @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_samestat_on_link @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_samestat_on_symlink @ linux-x86_64 +test.test_ntpath.NtCommonTest.test_splitdrive @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_abspath @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_basename @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_commonpath @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_dirname @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_expanduser @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_expandvars @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_isabs @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_isdir @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_islink @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_ismount @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_join @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_lexists @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_normcase @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_normpath @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_realpath @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_relpath @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_split @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_splitdrive @ linux-x86_64 +test.test_ntpath.PathLikeTests.test_path_splitext @ linux-x86_64 +test.test_ntpath.TestNtpath.test_commonpath @ linux-x86_64 +test.test_ntpath.TestNtpath.test_commonprefix @ linux-x86_64 +test.test_ntpath.TestNtpath.test_expanduser @ linux-x86_64 +test.test_ntpath.TestNtpath.test_expandvars @ linux-x86_64 +test.test_ntpath.TestNtpath.test_expandvars_nonascii @ linux-x86_64 +test.test_ntpath.TestNtpath.test_isabs @ linux-x86_64 +test.test_ntpath.TestNtpath.test_ismount @ linux-x86_64 +test.test_ntpath.TestNtpath.test_join @ linux-x86_64 +test.test_ntpath.TestNtpath.test_normpath @ linux-x86_64 +test.test_ntpath.TestNtpath.test_realpath_curdir @ linux-x86_64 +test.test_ntpath.TestNtpath.test_realpath_pardir @ linux-x86_64 +test.test_ntpath.TestNtpath.test_relpath @ linux-x86_64 +test.test_ntpath.TestNtpath.test_sameopenfile @ linux-x86_64 +test.test_ntpath.TestNtpath.test_split @ linux-x86_64 +test.test_ntpath.TestNtpath.test_splitdrive @ linux-x86_64 +test.test_ntpath.TestNtpath.test_splitext @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_numeric_tower.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_numeric_tower.txt new file mode 100644 index 0000000000..895b05aa22 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_numeric_tower.txt @@ -0,0 +1,9 @@ +test.test_numeric_tower.ComparisonTest.test_complex @ linux-x86_64 +test.test_numeric_tower.ComparisonTest.test_mixed_comparisons @ linux-x86_64 +test.test_numeric_tower.HashTest.test_binary_floats @ linux-x86_64 +test.test_numeric_tower.HashTest.test_bools @ linux-x86_64 +test.test_numeric_tower.HashTest.test_complex @ linux-x86_64 +test.test_numeric_tower.HashTest.test_decimals @ linux-x86_64 +test.test_numeric_tower.HashTest.test_fractions @ linux-x86_64 +test.test_numeric_tower.HashTest.test_hash_normalization @ linux-x86_64 +test.test_numeric_tower.HashTest.test_integers @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_opcache.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_opcache.txt new file mode 100644 index 0000000000..c97e6aa2c1 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_opcache.txt @@ -0,0 +1,26 @@ +test.test_opcache.TestCallCache.test_too_many_defaults_0 @ linux-x86_64 +test.test_opcache.TestCallCache.test_too_many_defaults_1 @ linux-x86_64 +test.test_opcache.TestCallCache.test_too_many_defaults_2 @ linux-x86_64 +test.test_opcache.TestLoadAttrCache.test_descriptor_added_after_optimization @ linux-x86_64 +test.test_opcache.TestLoadAttrCache.test_load_borrowed_slot_should_not_crash @ linux-x86_64 +test.test_opcache.TestLoadAttrCache.test_load_shadowing_slot_should_raise_type_error @ linux-x86_64 +test.test_opcache.TestLoadAttrCache.test_metaclass_del_descriptor_after_optimization @ linux-x86_64 +test.test_opcache.TestLoadAttrCache.test_metaclass_descriptor_added_after_optimization @ linux-x86_64 +test.test_opcache.TestLoadAttrCache.test_metaclass_descriptor_shadows_class_attribute @ linux-x86_64 +test.test_opcache.TestLoadAttrCache.test_metaclass_getattribute @ linux-x86_64 +test.test_opcache.TestLoadAttrCache.test_metaclass_set_descriptor_after_optimization @ linux-x86_64 +test.test_opcache.TestLoadAttrCache.test_metaclass_swap @ linux-x86_64 +test.test_opcache.TestLoadAttrCache.test_store_borrowed_slot_should_not_crash @ linux-x86_64 +test.test_opcache.TestLoadAttrCache.test_store_shadowing_slot_should_raise_type_error @ linux-x86_64 +test.test_opcache.TestLoadAttrCache.test_type_descriptor_shadows_attribute_getset @ linux-x86_64 +test.test_opcache.TestLoadAttrCache.test_type_descriptor_shadows_attribute_member @ linux-x86_64 +test.test_opcache.TestLoadAttrCache.test_type_descriptor_shadows_attribute_method @ linux-x86_64 +test.test_opcache.TestLoadMethodCache.test_descriptor_added_after_optimization @ linux-x86_64 +test.test_opcache.TestLoadMethodCache.test_metaclass_del_descriptor_after_optimization @ linux-x86_64 +test.test_opcache.TestLoadMethodCache.test_metaclass_descriptor_added_after_optimization @ linux-x86_64 +test.test_opcache.TestLoadMethodCache.test_metaclass_descriptor_shadows_class_attribute @ linux-x86_64 +test.test_opcache.TestLoadMethodCache.test_metaclass_getattribute @ linux-x86_64 +test.test_opcache.TestLoadMethodCache.test_metaclass_set_descriptor_after_optimization @ linux-x86_64 +test.test_opcache.TestLoadMethodCache.test_metaclass_swap @ linux-x86_64 +test.test_opcache.TestLoadMethodCache.test_type_descriptor_shadows_attribute_member @ linux-x86_64 +test.test_opcache.TestLoadMethodCache.test_type_descriptor_shadows_attribute_method @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_opcodes.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_opcodes.txt new file mode 100644 index 0000000000..e3a607ffe1 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_opcodes.txt @@ -0,0 +1,8 @@ +test.test_opcodes.OpcodeTest.test_compare_function_objects @ linux-x86_64 +test.test_opcodes.OpcodeTest.test_default_annotations_exist @ linux-x86_64 +test.test_opcodes.OpcodeTest.test_do_not_recreate_annotations @ linux-x86_64 +test.test_opcodes.OpcodeTest.test_modulo_of_string_subclasses @ linux-x86_64 +test.test_opcodes.OpcodeTest.test_raise_class_exceptions @ linux-x86_64 +test.test_opcodes.OpcodeTest.test_setup_annotations_line @ linux-x86_64 +test.test_opcodes.OpcodeTest.test_try_inside_for_loop @ linux-x86_64 +test.test_opcodes.OpcodeTest.test_use_existing_annotations @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_operator.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_operator.txt new file mode 100644 index 0000000000..b5b42cfeac --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_operator.txt @@ -0,0 +1,94 @@ +test.test_operator.CCOperatorPickleTestCase.test_attrgetter @ linux-x86_64 +test.test_operator.CCOperatorPickleTestCase.test_itemgetter @ linux-x86_64 +test.test_operator.CCOperatorPickleTestCase.test_methodcaller @ linux-x86_64 +test.test_operator.COperatorTestCase.test___all__ @ linux-x86_64 +test.test_operator.COperatorTestCase.test_abs @ linux-x86_64 +test.test_operator.COperatorTestCase.test_add @ linux-x86_64 +test.test_operator.COperatorTestCase.test_attrgetter @ linux-x86_64 +test.test_operator.COperatorTestCase.test_bitwise_and @ linux-x86_64 +test.test_operator.COperatorTestCase.test_bitwise_or @ linux-x86_64 +test.test_operator.COperatorTestCase.test_bitwise_xor @ linux-x86_64 +test.test_operator.COperatorTestCase.test_call @ linux-x86_64 +test.test_operator.COperatorTestCase.test_concat @ linux-x86_64 +test.test_operator.COperatorTestCase.test_contains @ linux-x86_64 +test.test_operator.COperatorTestCase.test_countOf @ linux-x86_64 +test.test_operator.COperatorTestCase.test_delitem @ linux-x86_64 +test.test_operator.COperatorTestCase.test_dunder_is_original @ linux-x86_64 +test.test_operator.COperatorTestCase.test_eq @ linux-x86_64 +test.test_operator.COperatorTestCase.test_floordiv @ linux-x86_64 +test.test_operator.COperatorTestCase.test_ge @ linux-x86_64 +test.test_operator.COperatorTestCase.test_getitem @ linux-x86_64 +test.test_operator.COperatorTestCase.test_gt @ linux-x86_64 +test.test_operator.COperatorTestCase.test_indexOf @ linux-x86_64 +test.test_operator.COperatorTestCase.test_inplace @ linux-x86_64 +test.test_operator.COperatorTestCase.test_invert @ linux-x86_64 +test.test_operator.COperatorTestCase.test_is @ linux-x86_64 +test.test_operator.COperatorTestCase.test_is_not @ linux-x86_64 +test.test_operator.COperatorTestCase.test_itemgetter @ linux-x86_64 +test.test_operator.COperatorTestCase.test_le @ linux-x86_64 +test.test_operator.COperatorTestCase.test_length_hint @ linux-x86_64 +test.test_operator.COperatorTestCase.test_lshift @ linux-x86_64 +test.test_operator.COperatorTestCase.test_lt @ linux-x86_64 +test.test_operator.COperatorTestCase.test_matmul @ linux-x86_64 +test.test_operator.COperatorTestCase.test_methodcaller @ linux-x86_64 +test.test_operator.COperatorTestCase.test_mod @ linux-x86_64 +test.test_operator.COperatorTestCase.test_mul @ linux-x86_64 +test.test_operator.COperatorTestCase.test_ne @ linux-x86_64 +test.test_operator.COperatorTestCase.test_neg @ linux-x86_64 +test.test_operator.COperatorTestCase.test_pos @ linux-x86_64 +test.test_operator.COperatorTestCase.test_pow @ linux-x86_64 +test.test_operator.COperatorTestCase.test_rshift @ linux-x86_64 +test.test_operator.COperatorTestCase.test_setitem @ linux-x86_64 +test.test_operator.COperatorTestCase.test_sub @ linux-x86_64 +test.test_operator.COperatorTestCase.test_truediv @ linux-x86_64 +test.test_operator.COperatorTestCase.test_truth @ linux-x86_64 +test.test_operator.CPyOperatorPickleTestCase.test_attrgetter @ linux-x86_64 +test.test_operator.CPyOperatorPickleTestCase.test_itemgetter @ linux-x86_64 +test.test_operator.CPyOperatorPickleTestCase.test_methodcaller @ linux-x86_64 +test.test_operator.PyCOperatorPickleTestCase.test_attrgetter @ linux-x86_64 +test.test_operator.PyCOperatorPickleTestCase.test_itemgetter @ linux-x86_64 +test.test_operator.PyCOperatorPickleTestCase.test_methodcaller @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test___all__ @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_abs @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_add @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_attrgetter @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_bitwise_and @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_bitwise_or @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_bitwise_xor @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_call @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_concat @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_contains @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_countOf @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_delitem @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_dunder_is_original @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_eq @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_floordiv @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_ge @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_getitem @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_gt @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_indexOf @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_inplace @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_invert @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_is @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_is_not @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_itemgetter @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_le @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_length_hint @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_lshift @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_lt @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_matmul @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_methodcaller @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_mod @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_mul @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_ne @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_neg @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_pos @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_pow @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_rshift @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_setitem @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_sub @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_truediv @ linux-x86_64 +test.test_operator.PyOperatorTestCase.test_truth @ linux-x86_64 +test.test_operator.PyPyOperatorPickleTestCase.test_attrgetter @ linux-x86_64 +test.test_operator.PyPyOperatorPickleTestCase.test_itemgetter @ linux-x86_64 +test.test_operator.PyPyOperatorPickleTestCase.test_methodcaller @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_optparse.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_optparse.txt new file mode 100644 index 0000000000..0185a04eca --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_optparse.txt @@ -0,0 +1,151 @@ +test.test_optparse.MiscTestCase.test__all__ @ linux-x86_64 +test.test_optparse.TestBool.test_bool_default @ linux-x86_64 +test.test_optparse.TestBool.test_bool_false @ linux-x86_64 +test.test_optparse.TestBool.test_bool_flicker_on_and_off @ linux-x86_64 +test.test_optparse.TestBool.test_bool_true @ linux-x86_64 +test.test_optparse.TestCallback.test_callback @ linux-x86_64 +test.test_optparse.TestCallback.test_callback_help @ linux-x86_64 +test.test_optparse.TestCallbackCheckAbbrev.test_abbrev_callback_expansion @ linux-x86_64 +test.test_optparse.TestCallbackExtraArgs.test_callback_extra_args @ linux-x86_64 +test.test_optparse.TestCallbackManyArgs.test_many_args @ linux-x86_64 +test.test_optparse.TestCallbackMeddleArgs.test_callback_meddle_args @ linux-x86_64 +test.test_optparse.TestCallbackMeddleArgs.test_callback_meddle_args_separator @ linux-x86_64 +test.test_optparse.TestCallbackVarArgs.test_consume_separator_stop_at_option @ linux-x86_64 +test.test_optparse.TestCallbackVarArgs.test_positional_arg_and_variable_args @ linux-x86_64 +test.test_optparse.TestCallbackVarArgs.test_stop_at_invalid_option @ linux-x86_64 +test.test_optparse.TestCallbackVarArgs.test_stop_at_option @ linux-x86_64 +test.test_optparse.TestCallbackVarArgs.test_variable_args @ linux-x86_64 +test.test_optparse.TestChoice.test_add_choice_option @ linux-x86_64 +test.test_optparse.TestChoice.test_invalid_choice @ linux-x86_64 +test.test_optparse.TestChoice.test_valid_choice @ linux-x86_64 +test.test_optparse.TestConflict.test_conflict_error @ linux-x86_64 +test.test_optparse.TestConflict.test_conflict_error_group @ linux-x86_64 +test.test_optparse.TestConflict.test_no_such_conflict_handler @ linux-x86_64 +test.test_optparse.TestConflictOverride.test_conflict_override_args @ linux-x86_64 +test.test_optparse.TestConflictOverride.test_conflict_override_help @ linux-x86_64 +test.test_optparse.TestConflictOverride.test_conflict_override_opts @ linux-x86_64 +test.test_optparse.TestConflictResolve.test_conflict_resolve @ linux-x86_64 +test.test_optparse.TestConflictResolve.test_conflict_resolve_help @ linux-x86_64 +test.test_optparse.TestConflictResolve.test_conflict_resolve_long_opt @ linux-x86_64 +test.test_optparse.TestConflictResolve.test_conflict_resolve_long_opts @ linux-x86_64 +test.test_optparse.TestConflictResolve.test_conflict_resolve_short_opt @ linux-x86_64 +test.test_optparse.TestConflictingDefaults.test_conflict_default @ linux-x86_64 +test.test_optparse.TestConflictingDefaults.test_conflict_default_none @ linux-x86_64 +test.test_optparse.TestCount.test_count_interspersed_args @ linux-x86_64 +test.test_optparse.TestCount.test_count_no_interspersed_args @ linux-x86_64 +test.test_optparse.TestCount.test_count_no_such_option @ linux-x86_64 +test.test_optparse.TestCount.test_count_one @ linux-x86_64 +test.test_optparse.TestCount.test_count_option_no_value @ linux-x86_64 +test.test_optparse.TestCount.test_count_override_amount @ linux-x86_64 +test.test_optparse.TestCount.test_count_override_quiet @ linux-x86_64 +test.test_optparse.TestCount.test_count_overriding @ linux-x86_64 +test.test_optparse.TestCount.test_count_overriding_default @ linux-x86_64 +test.test_optparse.TestCount.test_count_three @ linux-x86_64 +test.test_optparse.TestCount.test_count_three_apart @ linux-x86_64 +test.test_optparse.TestCount.test_count_with_default @ linux-x86_64 +test.test_optparse.TestCount.test_empty @ linux-x86_64 +test.test_optparse.TestDefaultValues.test_basic_defaults @ linux-x86_64 +test.test_optparse.TestDefaultValues.test_mixed_defaults_post @ linux-x86_64 +test.test_optparse.TestDefaultValues.test_mixed_defaults_pre @ linux-x86_64 +test.test_optparse.TestDefaultValues.test_process_default @ linux-x86_64 +test.test_optparse.TestExpandDefaults.test_alt_expand @ linux-x86_64 +test.test_optparse.TestExpandDefaults.test_default_none_1 @ linux-x86_64 +test.test_optparse.TestExpandDefaults.test_default_none_2 @ linux-x86_64 +test.test_optparse.TestExpandDefaults.test_float_default @ linux-x86_64 +test.test_optparse.TestExpandDefaults.test_no_default @ linux-x86_64 +test.test_optparse.TestExpandDefaults.test_no_expand @ linux-x86_64 +test.test_optparse.TestExpandDefaults.test_option_default @ linux-x86_64 +test.test_optparse.TestExpandDefaults.test_parser_default_1 @ linux-x86_64 +test.test_optparse.TestExpandDefaults.test_parser_default_2 @ linux-x86_64 +test.test_optparse.TestExtendAddActions.test_extend_add_action @ linux-x86_64 +test.test_optparse.TestExtendAddActions.test_extend_add_action_normal @ linux-x86_64 +test.test_optparse.TestExtendAddTypes.test_filetype_noexist @ linux-x86_64 +test.test_optparse.TestExtendAddTypes.test_filetype_notfile @ linux-x86_64 +test.test_optparse.TestExtendAddTypes.test_filetype_ok @ linux-x86_64 +test.test_optparse.TestHelp.test_help @ linux-x86_64 +test.test_optparse.TestHelp.test_help_description_groups @ linux-x86_64 +test.test_optparse.TestHelp.test_help_long_opts_first @ linux-x86_64 +test.test_optparse.TestHelp.test_help_old_usage @ linux-x86_64 +test.test_optparse.TestHelp.test_help_title_formatter @ linux-x86_64 +test.test_optparse.TestHelp.test_help_unicode @ linux-x86_64 +test.test_optparse.TestHelp.test_help_unicode_description @ linux-x86_64 +test.test_optparse.TestHelp.test_wrap_columns @ linux-x86_64 +test.test_optparse.TestMatchAbbrev.test_match_abbrev @ linux-x86_64 +test.test_optparse.TestMatchAbbrev.test_match_abbrev_error @ linux-x86_64 +test.test_optparse.TestMultipleArgs.test_nargs_invalid_float_value @ linux-x86_64 +test.test_optparse.TestMultipleArgs.test_nargs_long_opt @ linux-x86_64 +test.test_optparse.TestMultipleArgs.test_nargs_required_values @ linux-x86_64 +test.test_optparse.TestMultipleArgs.test_nargs_with_positional_args @ linux-x86_64 +test.test_optparse.TestMultipleArgsAppend.test_nargs_append @ linux-x86_64 +test.test_optparse.TestMultipleArgsAppend.test_nargs_append_const @ linux-x86_64 +test.test_optparse.TestMultipleArgsAppend.test_nargs_append_required_values @ linux-x86_64 +test.test_optparse.TestMultipleArgsAppend.test_nargs_append_simple @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_action_invalid @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_attr_invalid @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_bad_choices_list @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_callback_args_no_tuple @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_callback_kwargs_no_dict @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_callback_not_callable @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_no_callback_args_for_action @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_no_callback_for_action @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_no_callback_kwargs_for_action @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_no_choices_for_type @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_no_choices_list @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_no_const_for_action @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_no_nargs_for_action @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_no_single_dash @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_no_type_for_action @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_opt_string_empty @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_opt_string_long_invalid @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_opt_string_short_invalid @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_opt_string_too_short @ linux-x86_64 +test.test_optparse.TestOptionChecks.test_type_invalid @ linux-x86_64 +test.test_optparse.TestOptionGroup.test_add_group_invalid_arguments @ linux-x86_64 +test.test_optparse.TestOptionGroup.test_add_group_no_group @ linux-x86_64 +test.test_optparse.TestOptionGroup.test_add_group_wrong_parser @ linux-x86_64 +test.test_optparse.TestOptionGroup.test_group_manipulate @ linux-x86_64 +test.test_optparse.TestOptionGroup.test_option_group_create_instance @ linux-x86_64 +test.test_optparse.TestOptionParser.test_add_option_invalid_arguments @ linux-x86_64 +test.test_optparse.TestOptionParser.test_add_option_no_Option @ linux-x86_64 +test.test_optparse.TestOptionParser.test_get_option @ linux-x86_64 +test.test_optparse.TestOptionParser.test_get_option_equals @ linux-x86_64 +test.test_optparse.TestOptionParser.test_has_option @ linux-x86_64 +test.test_optparse.TestOptionParser.test_remove_long_opt @ linux-x86_64 +test.test_optparse.TestOptionParser.test_remove_nonexistent @ linux-x86_64 +test.test_optparse.TestOptionParser.test_remove_short_opt @ linux-x86_64 +test.test_optparse.TestOptionValues.test_basics @ linux-x86_64 +test.test_optparse.TestParseNumber.test_numeric_options @ linux-x86_64 +test.test_optparse.TestParseNumber.test_parse_num_fail @ linux-x86_64 +test.test_optparse.TestParseNumber.test_parse_num_ok @ linux-x86_64 +test.test_optparse.TestProgName.test_custom_progname @ linux-x86_64 +test.test_optparse.TestProgName.test_default_progname @ linux-x86_64 +test.test_optparse.TestStandard.test_abbrev_long_option @ linux-x86_64 +test.test_optparse.TestStandard.test_ambiguous_option @ linux-x86_64 +test.test_optparse.TestStandard.test_combined_single_invalid_option @ linux-x86_64 +test.test_optparse.TestStandard.test_defaults @ linux-x86_64 +test.test_optparse.TestStandard.test_empty @ linux-x86_64 +test.test_optparse.TestStandard.test_hyphen_becomes_positional_arg @ linux-x86_64 +test.test_optparse.TestStandard.test_invalid_integer @ linux-x86_64 +test.test_optparse.TestStandard.test_long_invalid_integer @ linux-x86_64 +test.test_optparse.TestStandard.test_long_option_append @ linux-x86_64 +test.test_optparse.TestStandard.test_long_option_argument_joined @ linux-x86_64 +test.test_optparse.TestStandard.test_long_option_argument_split @ linux-x86_64 +test.test_optparse.TestStandard.test_long_option_short_option @ linux-x86_64 +test.test_optparse.TestStandard.test_no_append_versus_append @ linux-x86_64 +test.test_optparse.TestStandard.test_no_such_option @ linux-x86_64 +test.test_optparse.TestStandard.test_option_argument_joined @ linux-x86_64 +test.test_optparse.TestStandard.test_option_argument_joined_integer @ linux-x86_64 +test.test_optparse.TestStandard.test_option_argument_split @ linux-x86_64 +test.test_optparse.TestStandard.test_option_argument_split_negative_integer @ linux-x86_64 +test.test_optparse.TestStandard.test_option_consumes_optionlike_string @ linux-x86_64 +test.test_optparse.TestStandard.test_required_value @ linux-x86_64 +test.test_optparse.TestStandard.test_short_and_long_option_split @ linux-x86_64 +test.test_optparse.TestStandard.test_short_option_consumes_separator @ linux-x86_64 +test.test_optparse.TestStandard.test_short_option_joined_and_separator @ linux-x86_64 +test.test_optparse.TestStandard.test_short_option_split_long_option_append @ linux-x86_64 +test.test_optparse.TestStandard.test_short_option_split_one_positional_arg @ linux-x86_64 +test.test_optparse.TestStandard.test_shortopt_empty_longopt_append @ linux-x86_64 +test.test_optparse.TestTypeAliases.test_str_aliases_string @ linux-x86_64 +test.test_optparse.TestTypeAliases.test_type_object @ linux-x86_64 +test.test_optparse.TestVersion.test_no_version @ linux-x86_64 +test.test_optparse.TestVersion.test_version @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ordered_dict.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ordered_dict.txt new file mode 100644 index 0000000000..fb2dbeaf46 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ordered_dict.txt @@ -0,0 +1,251 @@ +test.test_ordered_dict.CPythonBuiltinDictTests.test_abc @ linux-x86_64 +test.test_ordered_dict.CPythonBuiltinDictTests.test_clear @ linux-x86_64 +test.test_ordered_dict.CPythonBuiltinDictTests.test_delitem @ linux-x86_64 +test.test_ordered_dict.CPythonBuiltinDictTests.test_delitem_hash_collision @ linux-x86_64 +test.test_ordered_dict.CPythonBuiltinDictTests.test_detect_deletion_during_iteration @ linux-x86_64 +test.test_ordered_dict.CPythonBuiltinDictTests.test_highly_nested @ linux-x86_64 +test.test_ordered_dict.CPythonBuiltinDictTests.test_init @ linux-x86_64 +test.test_ordered_dict.CPythonBuiltinDictTests.test_override_update @ linux-x86_64 +test.test_ordered_dict.CPythonBuiltinDictTests.test_popitem @ linux-x86_64 +test.test_ordered_dict.CPythonBuiltinDictTests.test_reinsert @ linux-x86_64 +test.test_ordered_dict.CPythonBuiltinDictTests.test_setitem @ linux-x86_64 +test.test_ordered_dict.CPythonBuiltinDictTests.test_update @ linux-x86_64 +test.test_ordered_dict.CPythonGeneralMappingTests.test_bool @ linux-x86_64 +test.test_ordered_dict.CPythonGeneralMappingTests.test_constructor @ linux-x86_64 +test.test_ordered_dict.CPythonGeneralMappingTests.test_get @ linux-x86_64 +test.test_ordered_dict.CPythonGeneralMappingTests.test_getitem @ linux-x86_64 +test.test_ordered_dict.CPythonGeneralMappingTests.test_items @ linux-x86_64 +test.test_ordered_dict.CPythonGeneralMappingTests.test_keys @ linux-x86_64 +test.test_ordered_dict.CPythonGeneralMappingTests.test_len @ linux-x86_64 +test.test_ordered_dict.CPythonGeneralMappingTests.test_pop @ linux-x86_64 +test.test_ordered_dict.CPythonGeneralMappingTests.test_popitem @ linux-x86_64 +test.test_ordered_dict.CPythonGeneralMappingTests.test_read @ linux-x86_64 +test.test_ordered_dict.CPythonGeneralMappingTests.test_setdefault @ linux-x86_64 +test.test_ordered_dict.CPythonGeneralMappingTests.test_update @ linux-x86_64 +test.test_ordered_dict.CPythonGeneralMappingTests.test_values @ linux-x86_64 +test.test_ordered_dict.CPythonGeneralMappingTests.test_write @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_468 @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_abc @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_clear @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_copying @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_delitem @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_delitem_hash_collision @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_detect_deletion_during_iteration @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_dict_delitem @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_dict_pop @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_dict_popitem @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_dict_setdefault @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_dict_setitem @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_dict_update @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_equality @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_fromkeys @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_highly_nested @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_init @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_init_calls @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_issue24348 @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_issue24667 @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_iterators @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_iterators_empty @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_iterators_pickling @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_merge_operator @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_move_to_end @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_move_to_end_issue25406 @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_overridden_init @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_override_update @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_pickle_recursive @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_pop @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_popitem @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_popitem_last @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_reduce_not_too_fat @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_reinsert @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_repr @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_repr_recursive @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_repr_recursive_values @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_setdefault @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_setitem @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_sizeof @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_sorted_iterators @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_update @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_views @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictSubclassTests.test_yaml_linkage @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_468 @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_abc @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_clear @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_copying @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_delitem @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_delitem_hash_collision @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_detect_deletion_during_iteration @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_dict_delitem @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_dict_pop @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_dict_popitem @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_dict_setdefault @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_dict_setitem @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_dict_update @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_equality @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_fromkeys @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_highly_nested @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_init @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_init_calls @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_issue24348 @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_issue24667 @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_iterators @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_iterators_empty @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_iterators_pickling @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_merge_operator @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_move_to_end @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_move_to_end_issue25406 @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_overridden_init @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_override_update @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_pickle_recursive @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_pop @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_popitem @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_popitem_last @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_reduce_not_too_fat @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_reinsert @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_repr @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_repr_recursive @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_repr_recursive_values @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_setdefault @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_setitem @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_sizeof @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_sorted_iterators @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_update @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_views @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictTests.test_yaml_linkage @ linux-x86_64 +test.test_ordered_dict.CPythonOrderedDictWithSlotsCopyingTests.test_copying @ linux-x86_64 +test.test_ordered_dict.CPythonSubclassMappingTests.test_bool @ linux-x86_64 +test.test_ordered_dict.CPythonSubclassMappingTests.test_constructor @ linux-x86_64 +test.test_ordered_dict.CPythonSubclassMappingTests.test_get @ linux-x86_64 +test.test_ordered_dict.CPythonSubclassMappingTests.test_getitem @ linux-x86_64 +test.test_ordered_dict.CPythonSubclassMappingTests.test_items @ linux-x86_64 +test.test_ordered_dict.CPythonSubclassMappingTests.test_keys @ linux-x86_64 +test.test_ordered_dict.CPythonSubclassMappingTests.test_len @ linux-x86_64 +test.test_ordered_dict.CPythonSubclassMappingTests.test_pop @ linux-x86_64 +test.test_ordered_dict.CPythonSubclassMappingTests.test_popitem @ linux-x86_64 +test.test_ordered_dict.CPythonSubclassMappingTests.test_read @ linux-x86_64 +test.test_ordered_dict.CPythonSubclassMappingTests.test_setdefault @ linux-x86_64 +test.test_ordered_dict.CPythonSubclassMappingTests.test_update @ linux-x86_64 +test.test_ordered_dict.CPythonSubclassMappingTests.test_values @ linux-x86_64 +test.test_ordered_dict.CPythonSubclassMappingTests.test_write @ linux-x86_64 +test.test_ordered_dict.CSimpleLRUCacheTests.test_add_after_full @ linux-x86_64 +test.test_ordered_dict.CSimpleLRUCacheTests.test_change_order_on_get @ linux-x86_64 +test.test_ordered_dict.CSimpleLRUCacheTests.test_popitem @ linux-x86_64 +test.test_ordered_dict.PurePythonGeneralMappingTests.test_bool @ linux-x86_64 +test.test_ordered_dict.PurePythonGeneralMappingTests.test_constructor @ linux-x86_64 +test.test_ordered_dict.PurePythonGeneralMappingTests.test_get @ linux-x86_64 +test.test_ordered_dict.PurePythonGeneralMappingTests.test_getitem @ linux-x86_64 +test.test_ordered_dict.PurePythonGeneralMappingTests.test_items @ linux-x86_64 +test.test_ordered_dict.PurePythonGeneralMappingTests.test_keys @ linux-x86_64 +test.test_ordered_dict.PurePythonGeneralMappingTests.test_len @ linux-x86_64 +test.test_ordered_dict.PurePythonGeneralMappingTests.test_pop @ linux-x86_64 +test.test_ordered_dict.PurePythonGeneralMappingTests.test_popitem @ linux-x86_64 +test.test_ordered_dict.PurePythonGeneralMappingTests.test_read @ linux-x86_64 +test.test_ordered_dict.PurePythonGeneralMappingTests.test_setdefault @ linux-x86_64 +test.test_ordered_dict.PurePythonGeneralMappingTests.test_update @ linux-x86_64 +test.test_ordered_dict.PurePythonGeneralMappingTests.test_values @ linux-x86_64 +test.test_ordered_dict.PurePythonGeneralMappingTests.test_write @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_468 @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_abc @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_clear @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_copying @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_delitem @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_delitem_hash_collision @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_detect_deletion_during_iteration @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_dict_delitem @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_dict_pop @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_dict_popitem @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_dict_setdefault @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_dict_setitem @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_dict_update @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_equality @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_fromkeys @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_highly_nested @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_init @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_init_calls @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_issue24348 @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_issue24667 @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_iterators @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_iterators_empty @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_merge_operator @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_move_to_end @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_move_to_end_issue25406 @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_overridden_init @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_override_update @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_pickle_recursive @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_pop @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_popitem @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_popitem_last @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_reduce_not_too_fat @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_reinsert @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_repr @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_repr_recursive @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_repr_recursive_values @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_setdefault @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_setitem @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_sizeof @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_sorted_iterators @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_update @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_views @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictSubclassTests.test_yaml_linkage @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_468 @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_abc @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_clear @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_copying @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_delitem @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_delitem_hash_collision @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_detect_deletion_during_iteration @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_dict_delitem @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_dict_pop @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_dict_popitem @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_dict_setdefault @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_dict_setitem @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_dict_update @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_equality @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_fromkeys @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_highly_nested @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_init @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_init_calls @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_issue24348 @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_issue24667 @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_iterators @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_iterators_empty @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_merge_operator @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_move_to_end @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_move_to_end_issue25406 @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_overridden_init @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_override_update @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_pickle_recursive @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_pop @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_popitem @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_popitem_last @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_reduce_not_too_fat @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_reinsert @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_repr @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_repr_recursive @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_repr_recursive_values @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_setdefault @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_setitem @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_sizeof @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_sorted_iterators @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_update @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_views @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictTests.test_yaml_linkage @ linux-x86_64 +test.test_ordered_dict.PurePythonOrderedDictWithSlotsCopyingTests.test_copying @ linux-x86_64 +test.test_ordered_dict.PurePythonSubclassMappingTests.test_bool @ linux-x86_64 +test.test_ordered_dict.PurePythonSubclassMappingTests.test_constructor @ linux-x86_64 +test.test_ordered_dict.PurePythonSubclassMappingTests.test_get @ linux-x86_64 +test.test_ordered_dict.PurePythonSubclassMappingTests.test_getitem @ linux-x86_64 +test.test_ordered_dict.PurePythonSubclassMappingTests.test_items @ linux-x86_64 +test.test_ordered_dict.PurePythonSubclassMappingTests.test_keys @ linux-x86_64 +test.test_ordered_dict.PurePythonSubclassMappingTests.test_len @ linux-x86_64 +test.test_ordered_dict.PurePythonSubclassMappingTests.test_pop @ linux-x86_64 +test.test_ordered_dict.PurePythonSubclassMappingTests.test_popitem @ linux-x86_64 +test.test_ordered_dict.PurePythonSubclassMappingTests.test_read @ linux-x86_64 +test.test_ordered_dict.PurePythonSubclassMappingTests.test_setdefault @ linux-x86_64 +test.test_ordered_dict.PurePythonSubclassMappingTests.test_update @ linux-x86_64 +test.test_ordered_dict.PurePythonSubclassMappingTests.test_values @ linux-x86_64 +test.test_ordered_dict.PurePythonSubclassMappingTests.test_write @ linux-x86_64 +test.test_ordered_dict.PySimpleLRUCacheTests.test_add_after_full @ linux-x86_64 +test.test_ordered_dict.PySimpleLRUCacheTests.test_change_order_on_get @ linux-x86_64 +test.test_ordered_dict.PySimpleLRUCacheTests.test_pop @ linux-x86_64 +test.test_ordered_dict.PySimpleLRUCacheTests.test_popitem @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_os.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_os.txt new file mode 100644 index 0000000000..fd0f9b3ced --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_os.txt @@ -0,0 +1,192 @@ +test.test_os.BlockingTests.test_blocking @ linux-x86_64 +test.test_os.BytesFwalkTests.test_compare_to_walk @ linux-x86_64 +test.test_os.BytesFwalkTests.test_dir_fd @ linux-x86_64 +test.test_os.BytesFwalkTests.test_fd_leak @ linux-x86_64 +test.test_os.BytesFwalkTests.test_file_like_path @ linux-x86_64 +test.test_os.BytesFwalkTests.test_walk_bad_dir @ linux-x86_64 +test.test_os.BytesFwalkTests.test_walk_bottom_up @ linux-x86_64 +test.test_os.BytesFwalkTests.test_walk_prune @ linux-x86_64 +test.test_os.BytesFwalkTests.test_walk_symlink @ linux-x86_64 +test.test_os.BytesFwalkTests.test_walk_topdown @ linux-x86_64 +test.test_os.BytesFwalkTests.test_yields_correct_dir_fd @ linux-x86_64 +test.test_os.BytesWalkTests.test_file_like_path @ linux-x86_64 +test.test_os.BytesWalkTests.test_walk_bad_dir @ linux-x86_64 +test.test_os.BytesWalkTests.test_walk_bottom_up @ linux-x86_64 +test.test_os.BytesWalkTests.test_walk_many_open_files @ linux-x86_64 +test.test_os.BytesWalkTests.test_walk_prune @ linux-x86_64 +test.test_os.BytesWalkTests.test_walk_symlink @ linux-x86_64 +test.test_os.BytesWalkTests.test_walk_topdown @ linux-x86_64 +test.test_os.CPUCountTests.test_cpu_count @ linux-x86_64 +test.test_os.ChownFileTests.test_chown_uid_gid_arguments_must_be_index @ linux-x86_64 +test.test_os.ChownFileTests.test_chown_without_permission @ linux-x86_64 +test.test_os.DevNullTests.test_devnull @ linux-x86_64 +test.test_os.EnvironTests.test___repr__ @ linux-x86_64 +test.test_os.EnvironTests.test_bool @ linux-x86_64 +test.test_os.EnvironTests.test_constructor @ linux-x86_64 +test.test_os.EnvironTests.test_environb @ linux-x86_64 +test.test_os.EnvironTests.test_get @ linux-x86_64 +test.test_os.EnvironTests.test_get_exec_path @ linux-x86_64 +test.test_os.EnvironTests.test_getitem @ linux-x86_64 +test.test_os.EnvironTests.test_ior_operator @ linux-x86_64 +test.test_os.EnvironTests.test_ior_operator_invalid_dicts @ linux-x86_64 +test.test_os.EnvironTests.test_ior_operator_key_value_iterable @ linux-x86_64 +test.test_os.EnvironTests.test_items @ linux-x86_64 +test.test_os.EnvironTests.test_iter_error_when_changing_os_environ @ linux-x86_64 +test.test_os.EnvironTests.test_iter_error_when_changing_os_environ_items @ linux-x86_64 +test.test_os.EnvironTests.test_iter_error_when_changing_os_environ_values @ linux-x86_64 +test.test_os.EnvironTests.test_key_type @ linux-x86_64 +test.test_os.EnvironTests.test_keys @ linux-x86_64 +test.test_os.EnvironTests.test_keyvalue_types @ linux-x86_64 +test.test_os.EnvironTests.test_len @ linux-x86_64 +test.test_os.EnvironTests.test_or_operator @ linux-x86_64 +test.test_os.EnvironTests.test_os_popen_iter @ linux-x86_64 +test.test_os.EnvironTests.test_pop @ linux-x86_64 +test.test_os.EnvironTests.test_popitem @ linux-x86_64 +test.test_os.EnvironTests.test_putenv_unsetenv @ linux-x86_64 +test.test_os.EnvironTests.test_putenv_unsetenv_error @ linux-x86_64 +test.test_os.EnvironTests.test_read @ linux-x86_64 +test.test_os.EnvironTests.test_ror_operator @ linux-x86_64 +test.test_os.EnvironTests.test_setdefault @ linux-x86_64 +test.test_os.EnvironTests.test_update @ linux-x86_64 +test.test_os.EnvironTests.test_update2 @ linux-x86_64 +test.test_os.EnvironTests.test_values @ linux-x86_64 +test.test_os.EnvironTests.test_write @ linux-x86_64 +test.test_os.ExecTests.test_execv_with_bad_arglist @ linux-x86_64 +test.test_os.ExecTests.test_execvpe_with_bad_program @ linux-x86_64 +test.test_os.ExportsTests.test_os_all @ linux-x86_64 +test.test_os.FDInheritanceTests.test_dup @ linux-x86_64 +test.test_os.FDInheritanceTests.test_dup2 @ linux-x86_64 +test.test_os.FDInheritanceTests.test_dup_standard_stream @ linux-x86_64 +test.test_os.FDInheritanceTests.test_get_set_inheritable @ linux-x86_64 +test.test_os.FDInheritanceTests.test_get_set_inheritable_badf @ linux-x86_64 +test.test_os.FDInheritanceTests.test_get_set_inheritable_o_path @ linux-x86_64 +test.test_os.FDInheritanceTests.test_open @ linux-x86_64 +test.test_os.FDInheritanceTests.test_openpty @ linux-x86_64 +test.test_os.FDInheritanceTests.test_pipe @ linux-x86_64 +test.test_os.FSEncodingTests.test_identity @ linux-x86_64 +test.test_os.FSEncodingTests.test_nop @ linux-x86_64 +test.test_os.FileTests.test_access @ linux-x86_64 +test.test_os.FileTests.test_fdopen @ linux-x86_64 +test.test_os.FileTests.test_open_keywords @ linux-x86_64 +test.test_os.FileTests.test_read @ linux-x86_64 +test.test_os.FileTests.test_replace @ linux-x86_64 +test.test_os.FileTests.test_symlink_keywords @ linux-x86_64 +test.test_os.FileTests.test_write @ linux-x86_64 +test.test_os.FwalkTests.test_compare_to_walk @ linux-x86_64 +test.test_os.FwalkTests.test_dir_fd @ linux-x86_64 +test.test_os.FwalkTests.test_fd_leak @ linux-x86_64 +test.test_os.FwalkTests.test_file_like_path @ linux-x86_64 +test.test_os.FwalkTests.test_walk_bad_dir @ linux-x86_64 +test.test_os.FwalkTests.test_walk_bottom_up @ linux-x86_64 +test.test_os.FwalkTests.test_walk_prune @ linux-x86_64 +test.test_os.FwalkTests.test_walk_symlink @ linux-x86_64 +test.test_os.FwalkTests.test_walk_topdown @ linux-x86_64 +test.test_os.FwalkTests.test_yields_correct_dir_fd @ linux-x86_64 +test.test_os.LinkTests.test_link @ linux-x86_64 +test.test_os.LinkTests.test_link_bytes @ linux-x86_64 +test.test_os.LinkTests.test_unicode_name @ linux-x86_64 +test.test_os.MakedirTests.test_exist_ok_existing_directory @ linux-x86_64 +test.test_os.MakedirTests.test_exist_ok_existing_regular_file @ linux-x86_64 +test.test_os.MakedirTests.test_exist_ok_s_isgid_directory @ linux-x86_64 +test.test_os.MakedirTests.test_makedir @ linux-x86_64 +test.test_os.MakedirTests.test_mode @ linux-x86_64 +test.test_os.MiscTests.test_getcwd @ linux-x86_64 +test.test_os.MiscTests.test_getcwd_long_path @ linux-x86_64 +test.test_os.MiscTests.test_getcwdb @ linux-x86_64 +test.test_os.NonLocalSymlinkTests.test_directory_link_nonlocal @ linux-x86_64 +test.test_os.OSErrorTests.test_oserror_filename @ linux-x86_64 +test.test_os.PathTConverterTests.test_path_t_converter @ linux-x86_64 +test.test_os.PathTConverterTests.test_path_t_converter_and_custom_class @ linux-x86_64 +test.test_os.PidTests.test_getppid @ linux-x86_64 +test.test_os.ReadlinkTests.test_bytes @ linux-x86_64 +test.test_os.ReadlinkTests.test_missing_link @ linux-x86_64 +test.test_os.ReadlinkTests.test_not_symlink @ linux-x86_64 +test.test_os.ReadlinkTests.test_pathlike @ linux-x86_64 +test.test_os.ReadlinkTests.test_pathlike_bytes @ linux-x86_64 +test.test_os.RemoveDirsTests.test_remove_all @ linux-x86_64 +test.test_os.RemoveDirsTests.test_remove_nothing @ linux-x86_64 +test.test_os.RemoveDirsTests.test_remove_partial @ linux-x86_64 +test.test_os.StatAttributeTests.test_stat_attributes @ linux-x86_64 +test.test_os.StatAttributeTests.test_stat_attributes_bytes @ linux-x86_64 +test.test_os.StatAttributeTests.test_stat_result_pickle @ linux-x86_64 +test.test_os.StatAttributeTests.test_statvfs_attributes @ linux-x86_64 +test.test_os.StatAttributeTests.test_statvfs_result_pickle @ linux-x86_64 +test.test_os.TestDirEntry.test_uninstantiable @ linux-x86_64 +test.test_os.TestDirEntry.test_unpickable @ linux-x86_64 +test.test_os.TestInvalidFD.test_blocking @ linux-x86_64 +test.test_os.TestInvalidFD.test_dup @ linux-x86_64 +test.test_os.TestInvalidFD.test_dup2 @ linux-x86_64 +test.test_os.TestInvalidFD.test_fchdir @ linux-x86_64 +test.test_os.TestInvalidFD.test_fchmod @ linux-x86_64 +test.test_os.TestInvalidFD.test_fchown @ linux-x86_64 +test.test_os.TestInvalidFD.test_fdatasync @ linux-x86_64 +test.test_os.TestInvalidFD.test_fdopen @ linux-x86_64 +test.test_os.TestInvalidFD.test_fstat @ linux-x86_64 +test.test_os.TestInvalidFD.test_fstatvfs @ linux-x86_64 +test.test_os.TestInvalidFD.test_fsync @ linux-x86_64 +test.test_os.TestInvalidFD.test_ftruncate @ linux-x86_64 +test.test_os.TestInvalidFD.test_inheritable @ linux-x86_64 +test.test_os.TestInvalidFD.test_isatty @ linux-x86_64 +test.test_os.TestInvalidFD.test_lseek @ linux-x86_64 +test.test_os.TestInvalidFD.test_read @ linux-x86_64 +test.test_os.TestInvalidFD.test_tcgetpgrp @ linux-x86_64 +test.test_os.TestInvalidFD.test_ttyname @ linux-x86_64 +test.test_os.TestInvalidFD.test_write @ linux-x86_64 +test.test_os.TestPEP519.test_argument_required @ linux-x86_64 +test.test_os.TestPEP519.test_bad_pathlike @ linux-x86_64 +test.test_os.TestPEP519.test_fsencode_fsdecode @ linux-x86_64 +test.test_os.TestPEP519.test_garbage_in_exception_out @ linux-x86_64 +test.test_os.TestPEP519.test_pathlike @ linux-x86_64 +test.test_os.TestPEP519.test_pathlike_class_getitem @ linux-x86_64 +test.test_os.TestPEP519.test_pathlike_subclasshook @ linux-x86_64 +test.test_os.TestPEP519.test_return_bytes @ linux-x86_64 +test.test_os.TestPEP519.test_return_string @ linux-x86_64 +test.test_os.TestPEP519PurePython.test_argument_required @ linux-x86_64 +test.test_os.TestPEP519PurePython.test_bad_pathlike @ linux-x86_64 +test.test_os.TestPEP519PurePython.test_fsencode_fsdecode @ linux-x86_64 +test.test_os.TestPEP519PurePython.test_garbage_in_exception_out @ linux-x86_64 +test.test_os.TestPEP519PurePython.test_pathlike @ linux-x86_64 +test.test_os.TestPEP519PurePython.test_pathlike_class_getitem @ linux-x86_64 +test.test_os.TestPEP519PurePython.test_pathlike_subclasshook @ linux-x86_64 +test.test_os.TestPEP519PurePython.test_return_bytes @ linux-x86_64 +test.test_os.TestPEP519PurePython.test_return_string @ linux-x86_64 +test.test_os.TestScandir.test_attributes @ linux-x86_64 +test.test_os.TestScandir.test_bad_path_type @ linux-x86_64 +test.test_os.TestScandir.test_broken_symlink @ linux-x86_64 +test.test_os.TestScandir.test_bytes @ linux-x86_64 +test.test_os.TestScandir.test_bytes_like @ linux-x86_64 +test.test_os.TestScandir.test_close @ linux-x86_64 +test.test_os.TestScandir.test_consume_iterator_twice @ linux-x86_64 +test.test_os.TestScandir.test_context_manager @ linux-x86_64 +test.test_os.TestScandir.test_context_manager_close @ linux-x86_64 +test.test_os.TestScandir.test_context_manager_exception @ linux-x86_64 +test.test_os.TestScandir.test_current_directory @ linux-x86_64 +test.test_os.TestScandir.test_empty_path @ linux-x86_64 +test.test_os.TestScandir.test_fd @ linux-x86_64 +test.test_os.TestScandir.test_fspath_protocol @ linux-x86_64 +test.test_os.TestScandir.test_fspath_protocol_bytes @ linux-x86_64 +test.test_os.TestScandir.test_removed_dir @ linux-x86_64 +test.test_os.TestScandir.test_removed_file @ linux-x86_64 +test.test_os.TestScandir.test_repr @ linux-x86_64 +test.test_os.TestScandir.test_uninstantiable @ linux-x86_64 +test.test_os.TestScandir.test_unpickable @ linux-x86_64 +test.test_os.URandomTests.test_urandom_length @ linux-x86_64 +test.test_os.URandomTests.test_urandom_subprocess @ linux-x86_64 +test.test_os.URandomTests.test_urandom_value @ linux-x86_64 +test.test_os.UtimeTests.test_utime @ linux-x86_64 +test.test_os.UtimeTests.test_utime_by_indexed @ linux-x86_64 +test.test_os.UtimeTests.test_utime_by_times @ linux-x86_64 +test.test_os.UtimeTests.test_utime_current @ linux-x86_64 +test.test_os.UtimeTests.test_utime_current_old @ linux-x86_64 +test.test_os.UtimeTests.test_utime_dir_fd @ linux-x86_64 +test.test_os.UtimeTests.test_utime_directory @ linux-x86_64 +test.test_os.UtimeTests.test_utime_fd @ linux-x86_64 +test.test_os.UtimeTests.test_utime_invalid_arguments @ linux-x86_64 +test.test_os.UtimeTests.test_utime_nofollow_symlinks @ linux-x86_64 +test.test_os.WalkTests.test_file_like_path @ linux-x86_64 +test.test_os.WalkTests.test_walk_bad_dir @ linux-x86_64 +test.test_os.WalkTests.test_walk_bottom_up @ linux-x86_64 +test.test_os.WalkTests.test_walk_many_open_files @ linux-x86_64 +test.test_os.WalkTests.test_walk_prune @ linux-x86_64 +test.test_os.WalkTests.test_walk_symlink @ linux-x86_64 +test.test_os.WalkTests.test_walk_topdown @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pathlib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pathlib.txt new file mode 100644 index 0000000000..ccf1fdebe2 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pathlib.txt @@ -0,0 +1,312 @@ +test.test_pathlib.CompatiblePathTest.test_rtruediv @ linux-x86_64 +test.test_pathlib.CompatiblePathTest.test_truediv @ linux-x86_64 +test.test_pathlib.NTFlavourTest.test_parse_parts @ linux-x86_64 +test.test_pathlib.NTFlavourTest.test_parse_parts_common @ linux-x86_64 +test.test_pathlib.NTFlavourTest.test_splitroot @ linux-x86_64 +test.test_pathlib.PathTest.test_absolute_common @ linux-x86_64 +test.test_pathlib.PathTest.test_chmod @ linux-x86_64 +test.test_pathlib.PathTest.test_chmod_follow_symlinks_true @ linux-x86_64 +test.test_pathlib.PathTest.test_complex_symlinks_absolute @ linux-x86_64 +test.test_pathlib.PathTest.test_complex_symlinks_relative @ linux-x86_64 +test.test_pathlib.PathTest.test_complex_symlinks_relative_dot_dot @ linux-x86_64 +test.test_pathlib.PathTest.test_concrete_class @ linux-x86_64 +test.test_pathlib.PathTest.test_cwd @ linux-x86_64 +test.test_pathlib.PathTest.test_empty_path @ linux-x86_64 +test.test_pathlib.PathTest.test_exists @ linux-x86_64 +test.test_pathlib.PathTest.test_expanduser_common @ linux-x86_64 +test.test_pathlib.PathTest.test_glob_common @ linux-x86_64 +test.test_pathlib.PathTest.test_glob_dotdot @ linux-x86_64 +test.test_pathlib.PathTest.test_glob_empty_pattern @ linux-x86_64 +test.test_pathlib.PathTest.test_glob_long_symlink @ linux-x86_64 +test.test_pathlib.PathTest.test_glob_many_open_files @ linux-x86_64 +test.test_pathlib.PathTest.test_glob_permissions @ linux-x86_64 +test.test_pathlib.PathTest.test_hardlink_to @ linux-x86_64 +test.test_pathlib.PathTest.test_is_block_device_false @ linux-x86_64 +test.test_pathlib.PathTest.test_is_char_device_false @ linux-x86_64 +test.test_pathlib.PathTest.test_is_char_device_true @ linux-x86_64 +test.test_pathlib.PathTest.test_is_dir @ linux-x86_64 +test.test_pathlib.PathTest.test_is_fifo_false @ linux-x86_64 +test.test_pathlib.PathTest.test_is_file @ linux-x86_64 +test.test_pathlib.PathTest.test_is_mount @ linux-x86_64 +test.test_pathlib.PathTest.test_is_socket_false @ linux-x86_64 +test.test_pathlib.PathTest.test_is_socket_true @ linux-x86_64 +test.test_pathlib.PathTest.test_is_symlink @ linux-x86_64 +test.test_pathlib.PathTest.test_iterdir @ linux-x86_64 +test.test_pathlib.PathTest.test_iterdir_nodir @ linux-x86_64 +test.test_pathlib.PathTest.test_iterdir_symlink @ linux-x86_64 +test.test_pathlib.PathTest.test_link_to @ linux-x86_64 +test.test_pathlib.PathTest.test_lstat @ linux-x86_64 +test.test_pathlib.PathTest.test_lstat_nosymlink @ linux-x86_64 +test.test_pathlib.PathTest.test_mkdir @ linux-x86_64 +test.test_pathlib.PathTest.test_mkdir_concurrent_parent_creation @ linux-x86_64 +test.test_pathlib.PathTest.test_mkdir_exist_ok @ linux-x86_64 +test.test_pathlib.PathTest.test_mkdir_exist_ok_root @ linux-x86_64 +test.test_pathlib.PathTest.test_mkdir_exist_ok_with_parent @ linux-x86_64 +test.test_pathlib.PathTest.test_mkdir_no_parents_file @ linux-x86_64 +test.test_pathlib.PathTest.test_mkdir_parents @ linux-x86_64 +test.test_pathlib.PathTest.test_mkdir_with_child_file @ linux-x86_64 +test.test_pathlib.PathTest.test_open_common @ linux-x86_64 +test.test_pathlib.PathTest.test_parts_interning @ linux-x86_64 +test.test_pathlib.PathTest.test_pickling_common @ linux-x86_64 +test.test_pathlib.PathTest.test_read_write_bytes @ linux-x86_64 +test.test_pathlib.PathTest.test_read_write_text @ linux-x86_64 +test.test_pathlib.PathTest.test_readlink @ linux-x86_64 +test.test_pathlib.PathTest.test_rename @ linux-x86_64 +test.test_pathlib.PathTest.test_replace @ linux-x86_64 +test.test_pathlib.PathTest.test_resolve_common @ linux-x86_64 +test.test_pathlib.PathTest.test_resolve_dot @ linux-x86_64 +test.test_pathlib.PathTest.test_resolve_nonexist_relative_issue38671 @ linux-x86_64 +test.test_pathlib.PathTest.test_rglob_common @ linux-x86_64 +test.test_pathlib.PathTest.test_rglob_symlink_loop @ linux-x86_64 +test.test_pathlib.PathTest.test_rmdir @ linux-x86_64 +test.test_pathlib.PathTest.test_samefile @ linux-x86_64 +test.test_pathlib.PathTest.test_stat @ linux-x86_64 +test.test_pathlib.PathTest.test_stat_no_follow_symlinks @ linux-x86_64 +test.test_pathlib.PathTest.test_stat_no_follow_symlinks_nosymlink @ linux-x86_64 +test.test_pathlib.PathTest.test_symlink_to @ linux-x86_64 +test.test_pathlib.PathTest.test_touch_common @ linux-x86_64 +test.test_pathlib.PathTest.test_touch_nochange @ linux-x86_64 +test.test_pathlib.PathTest.test_unlink @ linux-x86_64 +test.test_pathlib.PathTest.test_unlink_missing_ok @ linux-x86_64 +test.test_pathlib.PathTest.test_unsupported_flavour @ linux-x86_64 +test.test_pathlib.PathTest.test_with @ linux-x86_64 +test.test_pathlib.PathTest.test_write_text_with_newlines @ linux-x86_64 +test.test_pathlib.PosixFlavourTest.test_parse_parts @ linux-x86_64 +test.test_pathlib.PosixFlavourTest.test_parse_parts_common @ linux-x86_64 +test.test_pathlib.PosixFlavourTest.test_splitroot @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_anchor_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_as_bytes_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_as_posix_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_as_uri @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_as_uri_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_as_uri_non_ascii @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_constructor_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_div @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_div_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_drive_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_eq @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_eq_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_equivalences @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_fspath_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_is_absolute @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_is_relative_to_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_is_reserved @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_join @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_join_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_match @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_match_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_name_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_ordering_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_parent_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_parents_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_parts_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_pickling_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_relative_to_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_repr_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_root @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_root_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_stem_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_str_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_str_subclass_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_suffix_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_suffixes_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_with_name_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_with_stem_common @ linux-x86_64 +test.test_pathlib.PosixPathAsPureTest.test_with_suffix_common @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_absolute @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_absolute_common @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_chmod @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_chmod_follow_symlinks_true @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_complex_symlinks_absolute @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_complex_symlinks_relative @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_complex_symlinks_relative_dot_dot @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_cwd @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_empty_path @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_exists @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_expanduser_common @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_glob @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_glob_common @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_glob_dotdot @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_glob_long_symlink @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_glob_many_open_files @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_glob_permissions @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_hardlink_to @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_is_block_device_false @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_is_char_device_false @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_is_char_device_true @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_is_dir @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_is_fifo_false @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_is_file @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_is_mount @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_is_socket_false @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_is_socket_true @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_is_symlink @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_iterdir @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_iterdir_nodir @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_iterdir_symlink @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_link_to @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_lstat @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_lstat_nosymlink @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_mkdir @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_mkdir_concurrent_parent_creation @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_mkdir_exist_ok @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_mkdir_exist_ok_root @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_mkdir_exist_ok_with_parent @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_mkdir_no_parents_file @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_mkdir_parents @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_mkdir_with_child_file @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_open_common @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_open_mode @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_parts_interning @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_pickling_common @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_read_write_bytes @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_read_write_text @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_readlink @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_rename @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_replace @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_resolve_common @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_resolve_dot @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_resolve_loop @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_resolve_nonexist_relative_issue38671 @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_resolve_root @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_rglob @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_rglob_common @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_rglob_symlink_loop @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_rmdir @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_samefile @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_stat @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_stat_no_follow_symlinks @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_stat_no_follow_symlinks_nosymlink @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_symlink_to @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_touch_common @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_touch_mode @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_touch_nochange @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_unlink @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_unlink_missing_ok @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_with @ linux-x86_64 +test.test_pathlib.PosixPathTest.test_write_text_with_newlines @ linux-x86_64 +test.test_pathlib.PurePathTest.test_anchor_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_as_bytes_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_as_posix_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_as_uri_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_concrete_class @ linux-x86_64 +test.test_pathlib.PurePathTest.test_constructor_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_different_flavours_unequal @ linux-x86_64 +test.test_pathlib.PurePathTest.test_different_flavours_unordered @ linux-x86_64 +test.test_pathlib.PurePathTest.test_div_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_drive_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_eq_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_equivalences @ linux-x86_64 +test.test_pathlib.PurePathTest.test_fspath_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_is_relative_to_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_join_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_match_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_name_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_ordering_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_parent_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_parents_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_parts_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_pickling_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_relative_to_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_repr_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_root_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_stem_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_str_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_str_subclass_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_suffix_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_suffixes_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_with_name_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_with_stem_common @ linux-x86_64 +test.test_pathlib.PurePathTest.test_with_suffix_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_anchor_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_as_bytes_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_as_posix_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_as_uri @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_as_uri_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_as_uri_non_ascii @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_constructor_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_div @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_div_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_drive_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_eq @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_eq_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_equivalences @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_fspath_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_is_absolute @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_is_relative_to_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_is_reserved @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_join @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_join_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_match @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_match_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_name_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_ordering_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_parent_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_parents_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_parts_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_pickling_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_relative_to_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_repr_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_root @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_root_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_stem_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_str_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_str_subclass_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_suffix_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_suffixes_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_with_name_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_with_stem_common @ linux-x86_64 +test.test_pathlib.PurePosixPathTest.test_with_suffix_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_anchor @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_anchor_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_as_bytes_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_as_posix_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_as_uri @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_as_uri_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_constructor_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_div @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_div_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_drive @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_drive_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_eq @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_eq_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_equivalences @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_fspath_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_is_absolute @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_is_relative_to @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_is_relative_to_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_is_reserved @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_join @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_join_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_match_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_name @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_name_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_ordering_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_parent @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_parent_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_parents @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_parents_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_parts @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_parts_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_pickling_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_relative_to @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_relative_to_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_repr_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_root @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_root_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_stem @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_stem_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_str @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_str_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_str_subclass @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_str_subclass_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_suffix @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_suffix_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_suffixes @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_suffixes_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_with_name @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_with_name_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_with_stem @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_with_stem_common @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_with_suffix @ linux-x86_64 +test.test_pathlib.PureWindowsPathTest.test_with_suffix_common @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_patma.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_patma.txt new file mode 100644 index 0000000000..7df6273be0 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_patma.txt @@ -0,0 +1,310 @@ +test.test_patma.TestCompiler.test_refleaks @ linux-x86_64 +test.test_patma.TestInheritance.test_late_registration_mapping @ linux-x86_64 +test.test_patma.TestInheritance.test_late_registration_sequence @ linux-x86_64 +test.test_patma.TestInheritance.test_multiple_inheritance_mapping @ linux-x86_64 +test.test_patma.TestInheritance.test_multiple_inheritance_sequence @ linux-x86_64 +test.test_patma.TestPatma.test_patma_000 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_001 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_002 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_003 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_004 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_005 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_006 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_007 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_008 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_009 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_010 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_011 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_012 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_013 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_014 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_015 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_016 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_017 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_018 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_019 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_020 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_021 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_022 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_023 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_024 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_025 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_026 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_027 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_028 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_029 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_030 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_031 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_032 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_033 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_034 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_035 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_036 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_037 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_038 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_039 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_040 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_041 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_042 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_043 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_044 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_045 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_046 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_047 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_048 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_049 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_050 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_051 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_052 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_053 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_054 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_055 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_056 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_057 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_058 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_059 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_060 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_061 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_062 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_063 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_064 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_065 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_066 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_067 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_068 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_069 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_070 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_071 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_072 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_073 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_074 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_075 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_076 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_077 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_078 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_079 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_080 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_081 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_082 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_083 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_084 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_085 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_086 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_087 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_088 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_089 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_090 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_091 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_092 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_093 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_094 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_095 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_096 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_097 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_098 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_099 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_100 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_101 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_102 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_103 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_104 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_105 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_106 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_107 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_108 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_109 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_110 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_111 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_112 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_113 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_114 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_115 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_116 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_117 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_118 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_119 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_120 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_121 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_122 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_123 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_124 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_125 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_126 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_127 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_128 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_129 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_130 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_131 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_132 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_133 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_134 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_135 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_136 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_137 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_138 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_139 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_140 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_141 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_142 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_143 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_144 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_145 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_146 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_147 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_148 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_149 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_150 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_151 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_152 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_153 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_154 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_155 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_156 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_157 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_158 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_159 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_160 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_161 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_162 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_163 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_164 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_165 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_166 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_167 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_168 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_169 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_170 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_171 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_172 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_173 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_174 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_175 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_176 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_177 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_178 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_179 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_180 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_181 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_182 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_183 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_184 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_185 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_186 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_187 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_188 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_189 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_190 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_191 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_192 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_193 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_194 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_195 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_196 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_197 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_198 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_199 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_200 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_201 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_202 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_203 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_204 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_205 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_206 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_207 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_208 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_209 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_210 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_211 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_212 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_213 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_214 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_215 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_216 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_217 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_218 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_219 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_220 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_221 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_222 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_223 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_224 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_225 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_226 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_227 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_228 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_229 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_230 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_231 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_232 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_233 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_234 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_235 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_236 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_237 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_238 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_239 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_240 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_241 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_242 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_243 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_244 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_245 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_246 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_247 @ linux-x86_64 +test.test_patma.TestPatma.test_patma_248 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_alternative_patterns_bind_different_names_0 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_alternative_patterns_bind_different_names_1 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_attribute_name_repeated_in_class_pattern @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_imaginary_number_required_in_complex_literal_0 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_imaginary_number_required_in_complex_literal_1 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_invalid_syntax_0 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_invalid_syntax_1 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_invalid_syntax_2 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_invalid_syntax_3 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_mapping_pattern_duplicate_key @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_mapping_pattern_duplicate_key_edge_case0 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_mapping_pattern_duplicate_key_edge_case1 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_mapping_pattern_duplicate_key_edge_case2 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_mapping_pattern_duplicate_key_edge_case3 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_mapping_pattern_keys_may_only_match_literals_and_attribute_lookups @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_multiple_assignments_to_name_in_pattern_0 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_multiple_assignments_to_name_in_pattern_1 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_multiple_assignments_to_name_in_pattern_2 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_multiple_assignments_to_name_in_pattern_3 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_multiple_assignments_to_name_in_pattern_4 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_multiple_assignments_to_name_in_pattern_5 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_multiple_starred_names_in_sequence_pattern_0 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_multiple_starred_names_in_sequence_pattern_1 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_name_capture_makes_remaining_patterns_unreachable_0 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_name_capture_makes_remaining_patterns_unreachable_1 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_name_capture_makes_remaining_patterns_unreachable_2 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_name_capture_makes_remaining_patterns_unreachable_3 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_name_capture_makes_remaining_patterns_unreachable_4 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_patterns_may_only_match_literals_and_attribute_lookups_0 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_patterns_may_only_match_literals_and_attribute_lookups_1 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_real_number_required_in_complex_literal_0 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_real_number_required_in_complex_literal_1 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_real_number_required_in_complex_literal_2 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_real_number_required_in_complex_literal_3 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_wildcard_makes_remaining_patterns_unreachable_0 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_wildcard_makes_remaining_patterns_unreachable_1 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_wildcard_makes_remaining_patterns_unreachable_2 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_wildcard_makes_remaining_patterns_unreachable_3 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_wildcard_makes_remaining_patterns_unreachable_4 @ linux-x86_64 +test.test_patma.TestSyntaxErrors.test_wildcard_makes_remaining_patterns_unreachable_5 @ linux-x86_64 +test.test_patma.TestTracing.test_default_capture @ linux-x86_64 +test.test_patma.TestTracing.test_default_wildcard @ linux-x86_64 +test.test_patma.TestTracing.test_no_default @ linux-x86_64 +test.test_patma.TestTracing.test_only_default_capture @ linux-x86_64 +test.test_patma.TestTracing.test_only_default_wildcard @ linux-x86_64 +test.test_patma.TestTracing.test_parser_deeply_nested_patterns @ linux-x86_64 +test.test_patma.TestTracing.test_unreachable_code @ linux-x86_64 +test.test_patma.TestTypeErrors.test_accepts_positional_subpatterns_0 @ linux-x86_64 +test.test_patma.TestTypeErrors.test_accepts_positional_subpatterns_1 @ linux-x86_64 +test.test_patma.TestTypeErrors.test_got_multiple_subpatterns_for_attribute_0 @ linux-x86_64 +test.test_patma.TestTypeErrors.test_got_multiple_subpatterns_for_attribute_1 @ linux-x86_64 +test.test_patma.TestTypeErrors.test_match_args_elements_must_be_strings @ linux-x86_64 +test.test_patma.TestTypeErrors.test_match_args_must_be_a_tuple_0 @ linux-x86_64 +test.test_patma.TestTypeErrors.test_match_args_must_be_a_tuple_1 @ linux-x86_64 +test.test_patma.TestTypeErrors.test_match_args_must_be_a_tuple_2 @ linux-x86_64 +test.test_patma.TestValueErrors.test_mapping_pattern_checks_duplicate_key_1 @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pep646_syntax.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pep646_syntax.txt new file mode 100644 index 0000000000..ea3b529610 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pep646_syntax.txt @@ -0,0 +1 @@ +DocTestCase.test.test_pep646_syntax.__test__.doctests @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pickle.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pickle.txt new file mode 100644 index 0000000000..0b4c0b405c --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pickle.txt @@ -0,0 +1,730 @@ +test.test_pickle.CChainDispatchTableTests.test_class_dispatch_table @ linux-x86_64 +test.test_pickle.CChainDispatchTableTests.test_default_dispatch_table @ linux-x86_64 +test.test_pickle.CChainDispatchTableTests.test_instance_dispatch_table @ linux-x86_64 +test.test_pickle.CDispatchTableTests.test_class_dispatch_table @ linux-x86_64 +test.test_pickle.CDispatchTableTests.test_default_dispatch_table @ linux-x86_64 +test.test_pickle.CDispatchTableTests.test_instance_dispatch_table @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_appends_on_non_lists @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_buffer_callback_error @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_buffers_error @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_builtin_exceptions @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_builtin_functions @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_builtin_types @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_bytearray @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_bytearray_memoization_bug @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_bytes @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_c_methods @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_compat_pickle @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_complex_newobj @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_complex_newobj_ex @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_dict_chunking @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_dynamic_class @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_ellipsis @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_evil_class_mutating_dict @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_evil_pickler_mutating_collection @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_float @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_float_format @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_framed_write_sizes_with_delayed_writer @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_framing_large_objects @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_framing_many_objects @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_getinitargs @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_global_ext1 @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_global_ext2 @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_global_ext4 @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_in_band_buffers @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_inband_accept_default_buffers_argument @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_int_pickling_efficiency @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_ints @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_large_pickles @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_list_chunking @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_local_lookup_error @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_long @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_long1 @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_long4 @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_many_puts_and_gets @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_metaclass @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_misc @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_nested_names @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_newobj_generic @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_newobj_list @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_newobj_list_slots @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_newobj_not_class @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_newobj_overridden_new @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_newobj_proxies @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_newobj_tuple @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_notimplemented @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_oob_buffers @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_oob_buffers_writable_to_readonly @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_optional_frames @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_pickle_to_2x @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_picklebuffer_error @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_proto @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_py_methods @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_dict @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_dict_and_inst @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_dict_key @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_dict_like @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_dict_like_key @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_dict_subclass @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_dict_subclass_and_inst @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_dict_subclass_key @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_frozenset_and_inst @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_frozenset_subclass_and_inst @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_inst @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_inst_state @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_list @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_list_and_inst @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_list_like @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_list_subclass @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_list_subclass_and_inst @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_multi @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_nested_names @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_set @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_set_and_inst @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_set_subclass_and_inst @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_tuple_and_dict @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_tuple_and_dict_key @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_tuple_and_dict_like @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_tuple_and_dict_like_key @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_tuple_and_dict_subclass @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_tuple_and_dict_subclass_key @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_tuple_and_inst @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_tuple_and_inst_state @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_tuple_and_list @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_tuple_and_list_like @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_tuple_and_list_subclass @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_recursive_tuple_subclass_and_inst @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_reduce @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_reduce_bad_iterator @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_reduce_calls_base @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_reduce_ex_called @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_reduce_ex_calls_base @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_reduce_ex_overrides_reduce @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_reduce_overrides_default_reduce_ex @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_roundtrip_equality @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_set_chunking @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_setitems_on_non_dicts @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_short_tuples @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_simple_newobj @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_singleton_types @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_singletons @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_structseq @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_unicode @ linux-x86_64 +test.test_pickle.CDumpPickle_LoadPickle.test_unicode_high_plane @ linux-x86_64 +test.test_pickle.CIdPersPicklerTests.test_protocol0_is_ascii_only @ linux-x86_64 +test.test_pickle.CIdPersPicklerTests.test_return_correct_type @ linux-x86_64 +test.test_pickle.CPersPicklerTests.test_persistence @ linux-x86_64 +test.test_pickle.CPickleTests.test_bad_init @ linux-x86_64 +test.test_pickle.CPickleTests.test_callapi @ linux-x86_64 +test.test_pickle.CPickleTests.test_dump_closed_file @ linux-x86_64 +test.test_pickle.CPickleTests.test_dump_load_oob_buffers @ linux-x86_64 +test.test_pickle.CPickleTests.test_dump_text_file @ linux-x86_64 +test.test_pickle.CPickleTests.test_dumps_loads_oob_buffers @ linux-x86_64 +test.test_pickle.CPickleTests.test_highest_protocol @ linux-x86_64 +test.test_pickle.CPickleTests.test_incomplete_input @ linux-x86_64 +test.test_pickle.CPickleTests.test_load_closed_file @ linux-x86_64 +test.test_pickle.CPickleTests.test_load_from_and_dump_to_file @ linux-x86_64 +test.test_pickle.CPickleTests.test_pickler_bad_file @ linux-x86_64 +test.test_pickle.CPickleTests.test_unpickler_bad_file @ linux-x86_64 +test.test_pickle.CPicklerHookTests.test_pickler_hook @ linux-x86_64 +test.test_pickle.CPicklerTests.test_appends_on_non_lists @ linux-x86_64 +test.test_pickle.CPicklerTests.test_buffer_callback_error @ linux-x86_64 +test.test_pickle.CPicklerTests.test_buffers_error @ linux-x86_64 +test.test_pickle.CPicklerTests.test_builtin_exceptions @ linux-x86_64 +test.test_pickle.CPicklerTests.test_builtin_functions @ linux-x86_64 +test.test_pickle.CPicklerTests.test_builtin_types @ linux-x86_64 +test.test_pickle.CPicklerTests.test_bytearray @ linux-x86_64 +test.test_pickle.CPicklerTests.test_bytearray_memoization_bug @ linux-x86_64 +test.test_pickle.CPicklerTests.test_bytes @ linux-x86_64 +test.test_pickle.CPicklerTests.test_c_methods @ linux-x86_64 +test.test_pickle.CPicklerTests.test_compat_pickle @ linux-x86_64 +test.test_pickle.CPicklerTests.test_complex_newobj @ linux-x86_64 +test.test_pickle.CPicklerTests.test_complex_newobj_ex @ linux-x86_64 +test.test_pickle.CPicklerTests.test_dict_chunking @ linux-x86_64 +test.test_pickle.CPicklerTests.test_dynamic_class @ linux-x86_64 +test.test_pickle.CPicklerTests.test_ellipsis @ linux-x86_64 +test.test_pickle.CPicklerTests.test_evil_class_mutating_dict @ linux-x86_64 +test.test_pickle.CPicklerTests.test_evil_pickler_mutating_collection @ linux-x86_64 +test.test_pickle.CPicklerTests.test_float @ linux-x86_64 +test.test_pickle.CPicklerTests.test_float_format @ linux-x86_64 +test.test_pickle.CPicklerTests.test_framed_write_sizes_with_delayed_writer @ linux-x86_64 +test.test_pickle.CPicklerTests.test_framing_large_objects @ linux-x86_64 +test.test_pickle.CPicklerTests.test_framing_many_objects @ linux-x86_64 +test.test_pickle.CPicklerTests.test_getinitargs @ linux-x86_64 +test.test_pickle.CPicklerTests.test_global_ext1 @ linux-x86_64 +test.test_pickle.CPicklerTests.test_global_ext2 @ linux-x86_64 +test.test_pickle.CPicklerTests.test_global_ext4 @ linux-x86_64 +test.test_pickle.CPicklerTests.test_in_band_buffers @ linux-x86_64 +test.test_pickle.CPicklerTests.test_inband_accept_default_buffers_argument @ linux-x86_64 +test.test_pickle.CPicklerTests.test_int_pickling_efficiency @ linux-x86_64 +test.test_pickle.CPicklerTests.test_ints @ linux-x86_64 +test.test_pickle.CPicklerTests.test_large_pickles @ linux-x86_64 +test.test_pickle.CPicklerTests.test_list_chunking @ linux-x86_64 +test.test_pickle.CPicklerTests.test_local_lookup_error @ linux-x86_64 +test.test_pickle.CPicklerTests.test_long @ linux-x86_64 +test.test_pickle.CPicklerTests.test_long1 @ linux-x86_64 +test.test_pickle.CPicklerTests.test_long4 @ linux-x86_64 +test.test_pickle.CPicklerTests.test_many_puts_and_gets @ linux-x86_64 +test.test_pickle.CPicklerTests.test_metaclass @ linux-x86_64 +test.test_pickle.CPicklerTests.test_misc @ linux-x86_64 +test.test_pickle.CPicklerTests.test_nested_names @ linux-x86_64 +test.test_pickle.CPicklerTests.test_newobj_generic @ linux-x86_64 +test.test_pickle.CPicklerTests.test_newobj_list @ linux-x86_64 +test.test_pickle.CPicklerTests.test_newobj_list_slots @ linux-x86_64 +test.test_pickle.CPicklerTests.test_newobj_not_class @ linux-x86_64 +test.test_pickle.CPicklerTests.test_newobj_overridden_new @ linux-x86_64 +test.test_pickle.CPicklerTests.test_newobj_proxies @ linux-x86_64 +test.test_pickle.CPicklerTests.test_newobj_tuple @ linux-x86_64 +test.test_pickle.CPicklerTests.test_notimplemented @ linux-x86_64 +test.test_pickle.CPicklerTests.test_oob_buffers @ linux-x86_64 +test.test_pickle.CPicklerTests.test_oob_buffers_writable_to_readonly @ linux-x86_64 +test.test_pickle.CPicklerTests.test_optional_frames @ linux-x86_64 +test.test_pickle.CPicklerTests.test_pickle_to_2x @ linux-x86_64 +test.test_pickle.CPicklerTests.test_picklebuffer_error @ linux-x86_64 +test.test_pickle.CPicklerTests.test_proto @ linux-x86_64 +test.test_pickle.CPicklerTests.test_py_methods @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_dict @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_dict_and_inst @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_dict_key @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_dict_like @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_dict_like_key @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_dict_subclass @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_dict_subclass_and_inst @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_dict_subclass_key @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_frozenset_and_inst @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_frozenset_subclass_and_inst @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_inst @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_inst_state @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_list @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_list_and_inst @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_list_like @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_list_subclass @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_list_subclass_and_inst @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_multi @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_nested_names @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_set @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_set_and_inst @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_set_subclass_and_inst @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_tuple_and_dict @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_tuple_and_dict_key @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_tuple_and_dict_like @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_tuple_and_dict_like_key @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_tuple_and_dict_subclass @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_tuple_and_dict_subclass_key @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_tuple_and_inst @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_tuple_and_inst_state @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_tuple_and_list @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_tuple_and_list_like @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_tuple_and_list_subclass @ linux-x86_64 +test.test_pickle.CPicklerTests.test_recursive_tuple_subclass_and_inst @ linux-x86_64 +test.test_pickle.CPicklerTests.test_reduce @ linux-x86_64 +test.test_pickle.CPicklerTests.test_reduce_bad_iterator @ linux-x86_64 +test.test_pickle.CPicklerTests.test_reduce_calls_base @ linux-x86_64 +test.test_pickle.CPicklerTests.test_reduce_ex_called @ linux-x86_64 +test.test_pickle.CPicklerTests.test_reduce_ex_calls_base @ linux-x86_64 +test.test_pickle.CPicklerTests.test_reduce_ex_overrides_reduce @ linux-x86_64 +test.test_pickle.CPicklerTests.test_reduce_overrides_default_reduce_ex @ linux-x86_64 +test.test_pickle.CPicklerTests.test_roundtrip_equality @ linux-x86_64 +test.test_pickle.CPicklerTests.test_set_chunking @ linux-x86_64 +test.test_pickle.CPicklerTests.test_setitems_on_non_dicts @ linux-x86_64 +test.test_pickle.CPicklerTests.test_short_tuples @ linux-x86_64 +test.test_pickle.CPicklerTests.test_simple_newobj @ linux-x86_64 +test.test_pickle.CPicklerTests.test_singleton_types @ linux-x86_64 +test.test_pickle.CPicklerTests.test_singletons @ linux-x86_64 +test.test_pickle.CPicklerTests.test_structseq @ linux-x86_64 +test.test_pickle.CPicklerTests.test_unicode @ linux-x86_64 +test.test_pickle.CPicklerTests.test_unicode_high_plane @ linux-x86_64 +test.test_pickle.CPicklerUnpicklerObjectTests.test_clear_pickler_memo @ linux-x86_64 +test.test_pickle.CPicklerUnpicklerObjectTests.test_issue18339 @ linux-x86_64 +test.test_pickle.CPicklerUnpicklerObjectTests.test_multiple_unpicklings_minimal @ linux-x86_64 +test.test_pickle.CPicklerUnpicklerObjectTests.test_multiple_unpicklings_seekable @ linux-x86_64 +test.test_pickle.CPicklerUnpicklerObjectTests.test_multiple_unpicklings_unseekable @ linux-x86_64 +test.test_pickle.CPicklerUnpicklerObjectTests.test_priming_pickler_memo @ linux-x86_64 +test.test_pickle.CPicklerUnpicklerObjectTests.test_priming_unpickler_memo @ linux-x86_64 +test.test_pickle.CPicklerUnpicklerObjectTests.test_reusing_unpickler_objects @ linux-x86_64 +test.test_pickle.CPicklerUnpicklerObjectTests.test_unpickling_buffering_readline @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_bad_mark @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_bad_newobj @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_bad_newobj_ex @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_bad_reduce @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_bad_stack @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_badly_escaped_string @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_badly_quoted_string @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_binbytes @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_binbytes8 @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_binget @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_binunicode8 @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_bytearray8 @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_compat_unpickle @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_constants @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_correctly_quoted_string @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_dup @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_empty_bytestring @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_frame_readline @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_get @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_large_32b_binbytes8 @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_large_32b_binunicode8 @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_large_32b_bytearray8 @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_load_classic_instance @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_load_from_data0 @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_load_from_data1 @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_load_from_data2 @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_load_from_data3 @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_load_from_data4 @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_load_long_python2_str_as_bytes @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_load_python2_str_as_bytes @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_load_python2_unicode_as_str @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_long_binget @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_maxint64 @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_misc_get @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_negative_32b_binbytes @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_negative_32b_binput @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_negative_32b_binunicode @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_negative_put @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_short_binbytes @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_short_binunicode @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_truncated_data @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_unpickle_from_2x @ linux-x86_64 +test.test_pickle.CUnpicklerTests.test_unpickle_module_race @ linux-x86_64 +test.test_pickle.CompatPickleTests.test_exceptions @ linux-x86_64 +test.test_pickle.CompatPickleTests.test_import @ linux-x86_64 +test.test_pickle.CompatPickleTests.test_import_mapping @ linux-x86_64 +test.test_pickle.CompatPickleTests.test_multiprocessing_exceptions @ linux-x86_64 +test.test_pickle.CompatPickleTests.test_name_mapping @ linux-x86_64 +test.test_pickle.CompatPickleTests.test_reverse_import_mapping @ linux-x86_64 +test.test_pickle.CompatPickleTests.test_reverse_name_mapping @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_appends_on_non_lists @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_buffer_callback_error @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_buffers_error @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_builtin_exceptions @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_builtin_functions @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_builtin_types @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_bytearray @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_bytearray_memoization_bug @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_bytes @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_c_methods @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_compat_pickle @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_complex_newobj @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_complex_newobj_ex @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_dict_chunking @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_dynamic_class @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_ellipsis @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_evil_class_mutating_dict @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_evil_pickler_mutating_collection @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_float @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_float_format @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_framed_write_sizes_with_delayed_writer @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_framing_large_objects @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_framing_many_objects @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_getinitargs @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_global_ext1 @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_global_ext2 @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_global_ext4 @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_in_band_buffers @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_inband_accept_default_buffers_argument @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_int_pickling_efficiency @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_ints @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_large_pickles @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_list_chunking @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_local_lookup_error @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_long @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_long1 @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_long4 @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_many_puts_and_gets @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_metaclass @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_misc @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_nested_names @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_newobj_generic @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_newobj_list @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_newobj_list_slots @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_newobj_not_class @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_newobj_overridden_new @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_newobj_proxies @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_newobj_tuple @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_notimplemented @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_oob_buffers @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_oob_buffers_writable_to_readonly @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_optional_frames @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_pickle_to_2x @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_picklebuffer_error @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_proto @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_py_methods @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_dict @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_dict_and_inst @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_dict_key @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_dict_like @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_dict_like_key @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_dict_subclass @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_dict_subclass_and_inst @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_dict_subclass_key @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_frozenset_and_inst @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_frozenset_subclass_and_inst @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_inst @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_inst_state @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_list @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_list_and_inst @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_list_like @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_list_subclass @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_list_subclass_and_inst @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_multi @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_nested_names @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_set @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_set_and_inst @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_set_subclass_and_inst @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_tuple_and_dict @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_tuple_and_dict_key @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_tuple_and_dict_like @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_tuple_and_dict_like_key @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_tuple_and_dict_subclass @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_tuple_and_dict_subclass_key @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_tuple_and_inst @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_tuple_and_inst_state @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_tuple_and_list @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_tuple_and_list_like @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_tuple_and_list_subclass @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_recursive_tuple_subclass_and_inst @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_reduce @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_reduce_bad_iterator @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_reduce_calls_base @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_reduce_ex_called @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_reduce_ex_calls_base @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_reduce_ex_overrides_reduce @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_reduce_overrides_default_reduce_ex @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_roundtrip_equality @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_set_chunking @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_setitems_on_non_dicts @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_short_tuples @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_simple_newobj @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_singleton_types @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_singletons @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_structseq @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_unicode @ linux-x86_64 +test.test_pickle.DumpPickle_CLoadPickle.test_unicode_high_plane @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_appends_on_non_lists @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_bad_mark @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_bad_newobj @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_bad_newobj_ex @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_bad_reduce @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_bad_stack @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_badly_escaped_string @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_badly_quoted_string @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_binbytes @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_binbytes8 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_binget @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_binunicode8 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_buffer_callback_error @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_buffers_error @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_builtin_exceptions @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_builtin_functions @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_builtin_types @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_bytearray @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_bytearray8 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_bytearray_memoization_bug @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_bytes @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_c_methods @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_compat_pickle @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_compat_unpickle @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_complex_newobj @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_complex_newobj_ex @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_constants @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_correctly_quoted_string @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_dict_chunking @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_dup @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_dynamic_class @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_ellipsis @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_empty_bytestring @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_evil_class_mutating_dict @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_float @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_float_format @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_frame_readline @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_framing_large_objects @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_framing_many_objects @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_get @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_getinitargs @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_global_ext1 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_global_ext2 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_global_ext4 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_in_band_buffers @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_inband_accept_default_buffers_argument @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_int_pickling_efficiency @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_ints @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_large_32b_binbytes8 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_large_32b_binunicode8 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_large_32b_bytearray8 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_large_pickles @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_list_chunking @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_load_classic_instance @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_load_from_data0 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_load_from_data1 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_load_from_data2 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_load_from_data3 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_load_from_data4 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_load_long_python2_str_as_bytes @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_load_python2_str_as_bytes @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_load_python2_unicode_as_str @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_local_lookup_error @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_long @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_long1 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_long4 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_long_binget @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_many_puts_and_gets @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_maxint64 @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_metaclass @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_misc @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_misc_get @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_negative_32b_binbytes @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_negative_32b_binput @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_negative_32b_binunicode @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_negative_put @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_nested_names @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_newobj_generic @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_newobj_list @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_newobj_list_slots @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_newobj_not_class @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_newobj_overridden_new @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_newobj_proxies @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_newobj_tuple @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_notimplemented @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_oob_buffers @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_oob_buffers_writable_to_readonly @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_optional_frames @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_pickle_to_2x @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_picklebuffer_error @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_proto @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_py_methods @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_dict @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_dict_and_inst @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_dict_key @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_dict_like @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_dict_like_key @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_dict_subclass @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_dict_subclass_and_inst @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_dict_subclass_key @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_frozenset_and_inst @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_frozenset_subclass_and_inst @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_inst @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_inst_state @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_list @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_list_and_inst @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_list_like @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_list_subclass @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_list_subclass_and_inst @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_multi @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_nested_names @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_set @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_set_and_inst @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_set_subclass_and_inst @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_tuple_and_dict @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_tuple_and_dict_key @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_tuple_and_dict_like @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_tuple_and_dict_like_key @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_tuple_and_dict_subclass @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_tuple_and_dict_subclass_key @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_tuple_and_inst @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_tuple_and_inst_state @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_tuple_and_list @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_tuple_and_list_like @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_tuple_and_list_subclass @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_recursive_tuple_subclass_and_inst @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_reduce @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_reduce_bad_iterator @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_reduce_calls_base @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_reduce_ex_called @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_reduce_ex_calls_base @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_reduce_ex_overrides_reduce @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_reduce_overrides_default_reduce_ex @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_roundtrip_equality @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_set_chunking @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_setitems_on_non_dicts @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_short_binbytes @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_short_binunicode @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_short_tuples @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_simple_newobj @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_singleton_types @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_singletons @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_structseq @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_truncated_data @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_unicode @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_unicode_high_plane @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_unpickle_from_2x @ linux-x86_64 +test.test_pickle.InMemoryPickleTests.test_unpickle_module_race @ linux-x86_64 +test.test_pickle.PyChainDispatchTableTests.test_class_dispatch_table @ linux-x86_64 +test.test_pickle.PyChainDispatchTableTests.test_default_dispatch_table @ linux-x86_64 +test.test_pickle.PyChainDispatchTableTests.test_instance_dispatch_table @ linux-x86_64 +test.test_pickle.PyDispatchTableTests.test_class_dispatch_table @ linux-x86_64 +test.test_pickle.PyDispatchTableTests.test_default_dispatch_table @ linux-x86_64 +test.test_pickle.PyDispatchTableTests.test_instance_dispatch_table @ linux-x86_64 +test.test_pickle.PyIdPersPicklerTests.test_protocol0_is_ascii_only @ linux-x86_64 +test.test_pickle.PyIdPersPicklerTests.test_return_correct_type @ linux-x86_64 +test.test_pickle.PyPersPicklerTests.test_persistence @ linux-x86_64 +test.test_pickle.PyPickleTests.test_bad_init @ linux-x86_64 +test.test_pickle.PyPickleTests.test_callapi @ linux-x86_64 +test.test_pickle.PyPickleTests.test_dump_closed_file @ linux-x86_64 +test.test_pickle.PyPickleTests.test_dump_load_oob_buffers @ linux-x86_64 +test.test_pickle.PyPickleTests.test_dump_text_file @ linux-x86_64 +test.test_pickle.PyPickleTests.test_dumps_loads_oob_buffers @ linux-x86_64 +test.test_pickle.PyPickleTests.test_highest_protocol @ linux-x86_64 +test.test_pickle.PyPickleTests.test_incomplete_input @ linux-x86_64 +test.test_pickle.PyPickleTests.test_load_closed_file @ linux-x86_64 +test.test_pickle.PyPickleTests.test_load_from_and_dump_to_file @ linux-x86_64 +test.test_pickle.PyPickleTests.test_pickler_bad_file @ linux-x86_64 +test.test_pickle.PyPickleTests.test_unpickler_bad_file @ linux-x86_64 +test.test_pickle.PyPicklerHookTests.test_pickler_hook @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_appends_on_non_lists @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_buffer_callback_error @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_buffers_error @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_builtin_exceptions @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_builtin_functions @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_builtin_types @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_bytearray @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_bytearray_memoization_bug @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_bytes @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_c_methods @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_compat_pickle @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_complex_newobj @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_complex_newobj_ex @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_dict_chunking @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_dynamic_class @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_ellipsis @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_evil_class_mutating_dict @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_evil_pickler_mutating_collection @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_float @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_float_format @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_framed_write_sizes_with_delayed_writer @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_framing_large_objects @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_framing_many_objects @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_getinitargs @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_global_ext1 @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_global_ext2 @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_global_ext4 @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_in_band_buffers @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_inband_accept_default_buffers_argument @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_int_pickling_efficiency @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_ints @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_large_pickles @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_list_chunking @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_local_lookup_error @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_long @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_long1 @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_long4 @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_many_puts_and_gets @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_metaclass @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_misc @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_nested_names @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_newobj_generic @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_newobj_list @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_newobj_list_slots @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_newobj_not_class @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_newobj_overridden_new @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_newobj_proxies @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_newobj_tuple @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_notimplemented @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_oob_buffers @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_oob_buffers_writable_to_readonly @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_optional_frames @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_pickle_to_2x @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_picklebuffer_error @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_proto @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_py_methods @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_dict @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_dict_and_inst @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_dict_key @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_dict_like @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_dict_like_key @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_dict_subclass @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_dict_subclass_and_inst @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_dict_subclass_key @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_frozenset_and_inst @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_frozenset_subclass_and_inst @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_inst @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_inst_state @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_list @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_list_and_inst @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_list_like @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_list_subclass @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_list_subclass_and_inst @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_multi @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_nested_names @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_set @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_set_and_inst @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_set_subclass_and_inst @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_tuple_and_dict @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_tuple_and_dict_key @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_tuple_and_dict_like @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_tuple_and_dict_like_key @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_tuple_and_dict_subclass @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_tuple_and_dict_subclass_key @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_tuple_and_inst @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_tuple_and_inst_state @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_tuple_and_list @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_tuple_and_list_like @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_tuple_and_list_subclass @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_recursive_tuple_subclass_and_inst @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_reduce @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_reduce_bad_iterator @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_reduce_calls_base @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_reduce_ex_called @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_reduce_ex_calls_base @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_reduce_ex_overrides_reduce @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_reduce_overrides_default_reduce_ex @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_roundtrip_equality @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_set_chunking @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_setitems_on_non_dicts @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_short_tuples @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_simple_newobj @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_singleton_types @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_singletons @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_structseq @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_unicode @ linux-x86_64 +test.test_pickle.PyPicklerTests.test_unicode_high_plane @ linux-x86_64 +test.test_pickle.PyPicklerUnpicklerObjectTests.test_clear_pickler_memo @ linux-x86_64 +test.test_pickle.PyPicklerUnpicklerObjectTests.test_multiple_unpicklings_minimal @ linux-x86_64 +test.test_pickle.PyPicklerUnpicklerObjectTests.test_multiple_unpicklings_seekable @ linux-x86_64 +test.test_pickle.PyPicklerUnpicklerObjectTests.test_multiple_unpicklings_unseekable @ linux-x86_64 +test.test_pickle.PyPicklerUnpicklerObjectTests.test_priming_pickler_memo @ linux-x86_64 +test.test_pickle.PyPicklerUnpicklerObjectTests.test_priming_unpickler_memo @ linux-x86_64 +test.test_pickle.PyPicklerUnpicklerObjectTests.test_reusing_unpickler_objects @ linux-x86_64 +test.test_pickle.PyPicklerUnpicklerObjectTests.test_unpickling_buffering_readline @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_bad_mark @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_bad_newobj @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_bad_newobj_ex @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_bad_reduce @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_bad_stack @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_badly_escaped_string @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_badly_quoted_string @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_binbytes @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_binbytes8 @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_binget @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_binunicode8 @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_bytearray8 @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_compat_unpickle @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_constants @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_correctly_quoted_string @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_dup @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_empty_bytestring @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_frame_readline @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_get @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_large_32b_binbytes8 @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_large_32b_binunicode8 @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_large_32b_bytearray8 @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_load_classic_instance @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_load_from_data0 @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_load_from_data1 @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_load_from_data2 @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_load_from_data3 @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_load_from_data4 @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_load_long_python2_str_as_bytes @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_load_python2_str_as_bytes @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_load_python2_unicode_as_str @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_long_binget @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_maxint64 @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_misc_get @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_negative_32b_binbytes @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_negative_32b_binput @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_negative_32b_binunicode @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_negative_put @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_short_binbytes @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_short_binunicode @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_truncated_data @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_unpickle_from_2x @ linux-x86_64 +test.test_pickle.PyUnpicklerTests.test_unpickle_module_race @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_picklebuffer.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_picklebuffer.txt new file mode 100644 index 0000000000..138f7838a6 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_picklebuffer.txt @@ -0,0 +1,8 @@ +test.test_picklebuffer.PickleBufferTest.test_basics @ linux-x86_64 +test.test_picklebuffer.PickleBufferTest.test_constructor_failure @ linux-x86_64 +test.test_picklebuffer.PickleBufferTest.test_ndarray_2d @ linux-x86_64 +test.test_picklebuffer.PickleBufferTest.test_raw @ linux-x86_64 +test.test_picklebuffer.PickleBufferTest.test_raw_ndarray @ linux-x86_64 +test.test_picklebuffer.PickleBufferTest.test_raw_non_contiguous @ linux-x86_64 +test.test_picklebuffer.PickleBufferTest.test_raw_released @ linux-x86_64 +test.test_picklebuffer.PickleBufferTest.test_release @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pickletools.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pickletools.txt new file mode 100644 index 0000000000..0ee57402fc --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pickletools.txt @@ -0,0 +1,132 @@ +DocTestCase.pickletools.__test__.disassembler_memo_test @ linux-x86_64 +DocTestCase.pickletools.__test__.disassembler_test @ linux-x86_64 +DocTestCase.pickletools.read_bytearray8 @ linux-x86_64 +DocTestCase.pickletools.read_bytes1 @ linux-x86_64 +DocTestCase.pickletools.read_bytes4 @ linux-x86_64 +DocTestCase.pickletools.read_bytes8 @ linux-x86_64 +DocTestCase.pickletools.read_decimalnl_long @ linux-x86_64 +DocTestCase.pickletools.read_decimalnl_short @ linux-x86_64 +DocTestCase.pickletools.read_float8 @ linux-x86_64 +DocTestCase.pickletools.read_floatnl @ linux-x86_64 +DocTestCase.pickletools.read_int4 @ linux-x86_64 +DocTestCase.pickletools.read_long1 @ linux-x86_64 +DocTestCase.pickletools.read_long4 @ linux-x86_64 +DocTestCase.pickletools.read_string1 @ linux-x86_64 +DocTestCase.pickletools.read_string4 @ linux-x86_64 +DocTestCase.pickletools.read_stringnl @ linux-x86_64 +DocTestCase.pickletools.read_stringnl_noescape_pair @ linux-x86_64 +DocTestCase.pickletools.read_uint1 @ linux-x86_64 +DocTestCase.pickletools.read_uint2 @ linux-x86_64 +DocTestCase.pickletools.read_uint4 @ linux-x86_64 +DocTestCase.pickletools.read_uint8 @ linux-x86_64 +DocTestCase.pickletools.read_unicodestring1 @ linux-x86_64 +DocTestCase.pickletools.read_unicodestring4 @ linux-x86_64 +DocTestCase.pickletools.read_unicodestring8 @ linux-x86_64 +DocTestCase.pickletools.read_unicodestringnl @ linux-x86_64 +test.test_pickletools.MiscTestCase.test__all__ @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_appends_on_non_lists @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_buffer_callback_error @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_buffers_error @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_builtin_exceptions @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_builtin_functions @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_builtin_types @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_bytearray @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_bytearray_memoization_bug @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_bytes @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_c_methods @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_compat_pickle @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_complex_newobj @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_complex_newobj_ex @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_dict_chunking @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_dynamic_class @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_ellipsis @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_evil_class_mutating_dict @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_float @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_float_format @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_framing_large_objects @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_framing_many_objects @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_getinitargs @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_global_ext1 @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_global_ext2 @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_global_ext4 @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_in_band_buffers @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_inband_accept_default_buffers_argument @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_int_pickling_efficiency @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_ints @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_large_pickles @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_list_chunking @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_local_lookup_error @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_long @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_long1 @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_long4 @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_many_puts_and_gets @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_metaclass @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_misc @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_nested_names @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_newobj_generic @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_newobj_list @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_newobj_list_slots @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_newobj_not_class @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_newobj_overridden_new @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_newobj_proxies @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_newobj_tuple @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_notimplemented @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_oob_buffers @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_oob_buffers_writable_to_readonly @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_optimize_binput_and_memoize @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_optimize_long_binget @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_optional_frames @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_picklebuffer_error @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_proto @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_py_methods @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_dict @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_dict_and_inst @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_dict_key @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_dict_like @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_dict_like_key @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_dict_subclass @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_dict_subclass_and_inst @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_dict_subclass_key @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_frozenset_and_inst @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_frozenset_subclass_and_inst @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_inst @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_inst_state @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_list @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_list_and_inst @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_list_like @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_list_subclass @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_list_subclass_and_inst @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_multi @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_nested_names @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_set @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_set_and_inst @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_set_subclass_and_inst @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_tuple_and_dict @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_tuple_and_dict_key @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_tuple_and_dict_like @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_tuple_and_dict_like_key @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_tuple_and_dict_subclass @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_tuple_and_dict_subclass_key @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_tuple_and_inst @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_tuple_and_inst_state @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_tuple_and_list @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_tuple_and_list_like @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_tuple_and_list_subclass @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_recursive_tuple_subclass_and_inst @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_reduce @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_reduce_bad_iterator @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_reduce_calls_base @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_reduce_ex_called @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_reduce_ex_calls_base @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_reduce_ex_overrides_reduce @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_reduce_overrides_default_reduce_ex @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_roundtrip_equality @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_set_chunking @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_setitems_on_non_dicts @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_short_tuples @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_simple_newobj @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_singleton_types @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_singletons @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_structseq @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_unicode @ linux-x86_64 +test.test_pickletools.OptimizedPickleTests.test_unicode_high_plane @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pipes.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pipes.txt new file mode 100644 index 0000000000..6638e169e7 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pipes.txt @@ -0,0 +1,14 @@ +test.test_pipes.SimplePipeTests.testBadAppendOptions @ linux-x86_64 +test.test_pipes.SimplePipeTests.testBadOpenMode @ linux-x86_64 +test.test_pipes.SimplePipeTests.testBadPrependOptions @ linux-x86_64 +test.test_pipes.SimplePipeTests.testClone @ linux-x86_64 +test.test_pipes.SimplePipeTests.testEmptyPipeline1 @ linux-x86_64 +test.test_pipes.SimplePipeTests.testEmptyPipeline2 @ linux-x86_64 +test.test_pipes.SimplePipeTests.testEmptyPipeline3 @ linux-x86_64 +test.test_pipes.SimplePipeTests.testReadOpenSink @ linux-x86_64 +test.test_pipes.SimplePipeTests.testRepr @ linux-x86_64 +test.test_pipes.SimplePipeTests.testSetDebug @ linux-x86_64 +test.test_pipes.SimplePipeTests.testSimplePipe1 @ linux-x86_64 +test.test_pipes.SimplePipeTests.testSimplePipe2 @ linux-x86_64 +test.test_pipes.SimplePipeTests.testSimplePipe3 @ linux-x86_64 +test.test_pipes.SimplePipeTests.testWriteOpenSource @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pkg.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pkg.txt new file mode 100644 index 0000000000..4c1c41b630 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pkg.txt @@ -0,0 +1,8 @@ +test.test_pkg.TestPkg.test_1 @ linux-x86_64 +test.test_pkg.TestPkg.test_2 @ linux-x86_64 +test.test_pkg.TestPkg.test_3 @ linux-x86_64 +test.test_pkg.TestPkg.test_4 @ linux-x86_64 +test.test_pkg.TestPkg.test_5 @ linux-x86_64 +test.test_pkg.TestPkg.test_6 @ linux-x86_64 +test.test_pkg.TestPkg.test_7 @ linux-x86_64 +test.test_pkg.TestPkg.test_8 @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pkgutil.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pkgutil.txt new file mode 100644 index 0000000000..fc27e3d142 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pkgutil.txt @@ -0,0 +1,26 @@ +test.test_pkgutil.ExtendPathTests.test_iter_importers @ linux-x86_64 +test.test_pkgutil.ExtendPathTests.test_mixed_namespace @ linux-x86_64 +test.test_pkgutil.ExtendPathTests.test_simple @ linux-x86_64 +test.test_pkgutil.ImportlibMigrationTests.test_find_loader_avoids_emulation @ linux-x86_64 +test.test_pkgutil.ImportlibMigrationTests.test_find_loader_missing_module @ linux-x86_64 +test.test_pkgutil.ImportlibMigrationTests.test_get_importer_avoids_emulation @ linux-x86_64 +test.test_pkgutil.ImportlibMigrationTests.test_get_loader_None_in_sys_modules @ linux-x86_64 +test.test_pkgutil.ImportlibMigrationTests.test_get_loader_avoids_emulation @ linux-x86_64 +test.test_pkgutil.ImportlibMigrationTests.test_get_loader_handles_missing_loader_attribute @ linux-x86_64 +test.test_pkgutil.ImportlibMigrationTests.test_get_loader_handles_missing_spec_attribute @ linux-x86_64 +test.test_pkgutil.ImportlibMigrationTests.test_get_loader_handles_spec_attribute_none @ linux-x86_64 +test.test_pkgutil.ImportlibMigrationTests.test_importer_deprecated @ linux-x86_64 +test.test_pkgutil.ImportlibMigrationTests.test_issue44061 @ linux-x86_64 +test.test_pkgutil.ImportlibMigrationTests.test_iter_importers_avoids_emulation @ linux-x86_64 +test.test_pkgutil.ImportlibMigrationTests.test_loader_deprecated @ linux-x86_64 +test.test_pkgutil.NestedNamespacePackageTest.test_nested @ linux-x86_64 +test.test_pkgutil.PkgutilPEP302Tests.test_alreadyloaded @ linux-x86_64 +test.test_pkgutil.PkgutilPEP302Tests.test_getdata_pep302 @ linux-x86_64 +test.test_pkgutil.PkgutilTests.test_getdata_filesys @ linux-x86_64 +test.test_pkgutil.PkgutilTests.test_getdata_zipfile @ linux-x86_64 +test.test_pkgutil.PkgutilTests.test_issue44061_iter_modules @ linux-x86_64 +test.test_pkgutil.PkgutilTests.test_name_resolution @ linux-x86_64 +test.test_pkgutil.PkgutilTests.test_unreadable_dir_on_syspath @ linux-x86_64 +test.test_pkgutil.PkgutilTests.test_walk_packages_raises_on_string_or_bytes_input @ linux-x86_64 +test.test_pkgutil.PkgutilTests.test_walkpackages_filesys @ linux-x86_64 +test.test_pkgutil.PkgutilTests.test_walkpackages_zipfile @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_platform.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_platform.txt new file mode 100644 index 0000000000..d4ee9d3799 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_platform.txt @@ -0,0 +1,26 @@ +test.test_platform.PlatformTest.test_architecture @ linux-x86_64 +test.test_platform.PlatformTest.test_freedesktop_os_release @ linux-x86_64 +test.test_platform.PlatformTest.test_java_ver @ linux-x86_64 +test.test_platform.PlatformTest.test_libc_ver @ linux-x86_64 +test.test_platform.PlatformTest.test_mac_ver @ linux-x86_64 +test.test_platform.PlatformTest.test_machine @ linux-x86_64 +test.test_platform.PlatformTest.test_macos @ linux-x86_64 +test.test_platform.PlatformTest.test_node @ linux-x86_64 +test.test_platform.PlatformTest.test_parse_os_release @ linux-x86_64 +test.test_platform.PlatformTest.test_platform @ linux-x86_64 +test.test_platform.PlatformTest.test_processor @ linux-x86_64 +test.test_platform.PlatformTest.test_release @ linux-x86_64 +test.test_platform.PlatformTest.test_sys_version @ linux-x86_64 +test.test_platform.PlatformTest.test_system @ linux-x86_64 +test.test_platform.PlatformTest.test_system_alias @ linux-x86_64 +test.test_platform.PlatformTest.test_uname @ linux-x86_64 +test.test_platform.PlatformTest.test_uname_asdict @ linux-x86_64 +test.test_platform.PlatformTest.test_uname_cast_to_tuple @ linux-x86_64 +test.test_platform.PlatformTest.test_uname_copy @ linux-x86_64 +test.test_platform.PlatformTest.test_uname_fields @ linux-x86_64 +test.test_platform.PlatformTest.test_uname_pickle @ linux-x86_64 +test.test_platform.PlatformTest.test_uname_processor @ linux-x86_64 +test.test_platform.PlatformTest.test_uname_replace @ linux-x86_64 +test.test_platform.PlatformTest.test_uname_slices @ linux-x86_64 +test.test_platform.PlatformTest.test_version @ linux-x86_64 +test.test_platform.PlatformTest.test_win32_ver @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_plistlib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_plistlib.txt new file mode 100644 index 0000000000..566246ccb4 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_plistlib.txt @@ -0,0 +1,55 @@ +test.test_plistlib.MiscTestCase.test__all__ @ linux-x86_64 +test.test_plistlib.TestBinaryPlistlib.test_cycles @ linux-x86_64 +!test.test_plistlib.TestBinaryPlistlib.test_deep_nesting @ linux-x86_64 +test.test_plistlib.TestBinaryPlistlib.test_dump_duplicates @ linux-x86_64 +test.test_plistlib.TestBinaryPlistlib.test_identity @ linux-x86_64 +test.test_plistlib.TestBinaryPlistlib.test_invalid_binary @ linux-x86_64 +test.test_plistlib.TestBinaryPlistlib.test_large_timestamp @ linux-x86_64 +test.test_plistlib.TestBinaryPlistlib.test_load_int @ linux-x86_64 +test.test_plistlib.TestBinaryPlistlib.test_load_singletons @ linux-x86_64 +test.test_plistlib.TestBinaryPlistlib.test_nonstandard_refs_size @ linux-x86_64 +test.test_plistlib.TestBinaryPlistlib.test_unsupported @ linux-x86_64 +test.test_plistlib.TestKeyedArchive.test_keyed_archive_data @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_appleformatting @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_appleformattingfromliteral @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_bytearray @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_bytes @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_bytesio @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_controlcharacters @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_create @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_dict_members @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_dump_invalid_format @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_indentation_array @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_indentation_dict @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_indentation_dict_mix @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_int @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_integer_notations @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_invalid_type @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_invalid_uid @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_invalidarray @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_invaliddict @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_invalidinteger @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_invalidreal @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_io @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_keys_no_string @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_keysort @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_keysort_bytesio @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_list_members @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_load_invalid_file @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_lone_surrogates @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_modified_uid_huge @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_modified_uid_negative @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_non_bmp_characters @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_nondictroot @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_skipkeys @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_tuple_members @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_uid @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_uid_copy @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_uid_data @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_uid_eq @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_uid_hash @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_uid_index @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_uid_pickle @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_uid_repr @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_xml_encodings @ linux-x86_64 +test.test_plistlib.TestPlistlib.test_xml_plist_with_entity_decl @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_popen.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_popen.txt new file mode 100644 index 0000000000..fde6cabdb8 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_popen.txt @@ -0,0 +1,5 @@ +test.test_popen.PopenTest.test_contextmanager @ linux-x86_64 +test.test_popen.PopenTest.test_iterating @ linux-x86_64 +test.test_popen.PopenTest.test_keywords @ linux-x86_64 +test.test_popen.PopenTest.test_popen @ linux-x86_64 +test.test_popen.PopenTest.test_return_code @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_poplib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_poplib.txt new file mode 100644 index 0000000000..732806d516 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_poplib.txt @@ -0,0 +1,70 @@ +test.test_poplib.TestPOP3Class.test_apop_REDOS @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_apop_normal @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_capa @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_dele @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_exceptions @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_getwelcome @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_list @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_noop @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_pass_ @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_quit @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_retr @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_rpop @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_stat @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_stls @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_stls_capa @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_too_long_lines @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_top @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_uidl @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_user @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_utf8 @ linux-x86_64 +test.test_poplib.TestPOP3Class.test_utf8_raises_if_unsupported @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test__all__ @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_apop_REDOS @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_apop_normal @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_capa @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_context @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_dele @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_exceptions @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_getwelcome @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_list @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_noop @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_pass_ @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_quit @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_retr @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_rpop @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_stat @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_stls @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_stls_capa @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_stls_context @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_too_long_lines @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_top @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_uidl @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_user @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_utf8 @ linux-x86_64 +test.test_poplib.TestPOP3_SSLClass.test_utf8_raises_if_unsupported @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_apop_REDOS @ linux-x86_64 +!test.test_poplib.TestPOP3_TLSClass.test_apop_normal @ linux-x86_64 +!test.test_poplib.TestPOP3_TLSClass.test_capa @ linux-x86_64 +!test.test_poplib.TestPOP3_TLSClass.test_dele @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_exceptions @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_getwelcome @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_list @ linux-x86_64 +!test.test_poplib.TestPOP3_TLSClass.test_noop @ linux-x86_64 +!test.test_poplib.TestPOP3_TLSClass.test_pass_ @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_quit @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_retr @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_rpop @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_stat @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_stls @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_stls_capa @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_stls_context @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_too_long_lines @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_top @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_uidl @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_user @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_utf8 @ linux-x86_64 +test.test_poplib.TestPOP3_TLSClass.test_utf8_raises_if_unsupported @ linux-x86_64 +test.test_poplib.TestTimeouts.testTimeoutDefault @ linux-x86_64 +test.test_poplib.TestTimeouts.testTimeoutNone @ linux-x86_64 +test.test_poplib.TestTimeouts.testTimeoutValue @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_positional_only_arg.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_positional_only_arg.txt new file mode 100644 index 0000000000..842ab43eaa --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_positional_only_arg.txt @@ -0,0 +1,26 @@ +test.test_positional_only_arg.PositionalOnlyTestCase.test_annotations_in_closures @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_change_default_pos_only @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_closures @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_generator @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_invalid_syntax_errors @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_invalid_syntax_errors_async @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_invalid_syntax_lambda @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_lambdas @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_mangling @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_module_function @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_no_standard_args_usage @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_optional_positional_only_args @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_pos_only_call_via_unpacking @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_pos_only_definition @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_positional_only_and_arg_invalid_calls @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_positional_only_and_kwonlyargs_invalid_calls @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_positional_only_and_optional_arg_invalid_calls @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_positional_only_invalid_calls @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_positional_only_with_optional_invalid_calls @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_posonly_methods @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_same_keyword_as_positional_with_kwargs @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_serialization @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_super @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_syntax_for_many_positional_only @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_too_many_arguments @ linux-x86_64 +test.test_positional_only_arg.PositionalOnlyTestCase.test_use_positional_as_keyword @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_posix.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_posix.txt new file mode 100644 index 0000000000..9c175e9b1e --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_posix.txt @@ -0,0 +1,45 @@ +test.test_posix.PosixTester.testNoArgFunctions @ linux-x86_64 +test.test_posix.PosixTester.test_access @ linux-x86_64 +test.test_posix.PosixTester.test_chdir @ linux-x86_64 +test.test_posix.PosixTester.test_chown @ linux-x86_64 +test.test_posix.PosixTester.test_dup @ linux-x86_64 +test.test_posix.PosixTester.test_dup2 @ linux-x86_64 +test.test_posix.PosixTester.test_environ @ linux-x86_64 +test.test_posix.PosixTester.test_fchown @ linux-x86_64 +test.test_posix.PosixTester.test_fs_holes @ linux-x86_64 +test.test_posix.PosixTester.test_fstat @ linux-x86_64 +test.test_posix.PosixTester.test_fstatvfs @ linux-x86_64 +test.test_posix.PosixTester.test_ftruncate @ linux-x86_64 +test.test_posix.PosixTester.test_getcwd_long_pathnames @ linux-x86_64 +test.test_posix.PosixTester.test_getgroups @ linux-x86_64 +test.test_posix.PosixTester.test_lchown @ linux-x86_64 +test.test_posix.PosixTester.test_listdir @ linux-x86_64 +test.test_posix.PosixTester.test_listdir_bytes @ linux-x86_64 +test.test_posix.PosixTester.test_listdir_bytes_like @ linux-x86_64 +test.test_posix.PosixTester.test_listdir_default @ linux-x86_64 +test.test_posix.PosixTester.test_listdir_fd @ linux-x86_64 +test.test_posix.PosixTester.test_oscloexec @ linux-x86_64 +test.test_posix.PosixTester.test_path_error2 @ linux-x86_64 +test.test_posix.PosixTester.test_path_with_null_byte @ linux-x86_64 +test.test_posix.PosixTester.test_path_with_null_character @ linux-x86_64 +test.test_posix.PosixTester.test_pipe @ linux-x86_64 +test.test_posix.PosixTester.test_putenv @ linux-x86_64 +test.test_posix.PosixTester.test_rtld_constants @ linux-x86_64 +test.test_posix.PosixTester.test_stat @ linux-x86_64 +test.test_posix.PosixTester.test_statvfs @ linux-x86_64 +test.test_posix.PosixTester.test_strerror @ linux-x86_64 +test.test_posix.PosixTester.test_truncate @ linux-x86_64 +test.test_posix.PosixTester.test_umask @ linux-x86_64 +test.test_posix.PosixTester.test_utime @ linux-x86_64 +test.test_posix.PosixTester.test_utime_nofollow_symlinks @ linux-x86_64 +test.test_posix.PosixTester.test_utime_with_fd @ linux-x86_64 +test.test_posix.TestPosixDirFd.test_access_dir_fd @ linux-x86_64 +test.test_posix.TestPosixDirFd.test_chmod_dir_fd @ linux-x86_64 +test.test_posix.TestPosixDirFd.test_mkdir_dir_fd @ linux-x86_64 +test.test_posix.TestPosixDirFd.test_open_dir_fd @ linux-x86_64 +test.test_posix.TestPosixDirFd.test_readlink_dir_fd @ linux-x86_64 +test.test_posix.TestPosixDirFd.test_rename_dir_fd @ linux-x86_64 +test.test_posix.TestPosixDirFd.test_stat_dir_fd @ linux-x86_64 +test.test_posix.TestPosixDirFd.test_symlink_dir_fd @ linux-x86_64 +test.test_posix.TestPosixDirFd.test_unlink_dir_fd @ linux-x86_64 +test.test_posix.TestPosixDirFd.test_utime_dir_fd @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_posixpath.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_posixpath.txt new file mode 100644 index 0000000000..5b60611c71 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_posixpath.txt @@ -0,0 +1,77 @@ +test.test_posixpath.PathLikeTests.test_path_abspath @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_basename @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_commonpath @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_dirname @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_expanduser @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_expandvars @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_isabs @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_islink @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_ismount @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_join @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_lexists @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_normcase @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_normpath @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_realpath @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_relpath @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_split @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_splitdrive @ linux-x86_64 +test.test_posixpath.PathLikeTests.test_path_splitext @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_abspath @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_abspath_issue3426 @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_commonprefix @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_exists @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_exists_fd @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_expandvars @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_expandvars_nonascii @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_filetime @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_getsize @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_import @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_isdir @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_isfile @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_join_errors @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_no_argument @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_nonascii_abspath @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_normcase @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_normpath_issue106242 @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_normpath_issue5827 @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_realpath @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_relpath_errors @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_samefile @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_samefile_on_link @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_samefile_on_symlink @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_sameopenfile @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_samestat @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_samestat_on_link @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_samestat_on_symlink @ linux-x86_64 +test.test_posixpath.PosixCommonTest.test_splitdrive @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_basename @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_commonpath @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_dirname @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_expanduser @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_expanduser_home_envvar @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_expanduser_pwd @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_isabs @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_islink @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_ismount @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_ismount_different_device @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_ismount_directory_not_readable @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_ismount_non_existent @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_ismount_symlinks @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_join @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_normpath @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_realpath_basic @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_realpath_curdir @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_realpath_deep_recursion @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_realpath_pardir @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_realpath_relative @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_realpath_repeated_indirect_symlinks @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_realpath_resolve_before_normalizing @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_realpath_resolve_first @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_realpath_resolve_parents @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_realpath_strict @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_realpath_symlink_loops @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_realpath_symlink_loops_strict @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_relpath @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_relpath_bytes @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_split @ linux-x86_64 +test.test_posixpath.PosixPathTest.test_splitext @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pow.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pow.txt new file mode 100644 index 0000000000..e94e243600 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pow.txt @@ -0,0 +1,7 @@ +test.test_pow.PowTest.test_big_exp @ linux-x86_64 +test.test_pow.PowTest.test_bug643260 @ linux-x86_64 +test.test_pow.PowTest.test_bug705231 @ linux-x86_64 +test.test_pow.PowTest.test_negative_exponent @ linux-x86_64 +test.test_pow.PowTest.test_other @ linux-x86_64 +test.test_pow.PowTest.test_powfloat @ linux-x86_64 +test.test_pow.PowTest.test_powint @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pprint.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pprint.txt new file mode 100644 index 0000000000..aa094ccf63 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pprint.txt @@ -0,0 +1,43 @@ +test.test_pprint.QueryTestCase.test_basic @ linux-x86_64 +test.test_pprint.QueryTestCase.test_basic_line_wrap @ linux-x86_64 +test.test_pprint.QueryTestCase.test_bytearray_wrap @ linux-x86_64 +test.test_pprint.QueryTestCase.test_bytes_wrap @ linux-x86_64 +test.test_pprint.QueryTestCase.test_chainmap @ linux-x86_64 +test.test_pprint.QueryTestCase.test_compact @ linux-x86_64 +test.test_pprint.QueryTestCase.test_compact_width @ linux-x86_64 +test.test_pprint.QueryTestCase.test_container_repr_override_called @ linux-x86_64 +test.test_pprint.QueryTestCase.test_counter @ linux-x86_64 +test.test_pprint.QueryTestCase.test_cyclic_dataclass @ linux-x86_64 +test.test_pprint.QueryTestCase.test_dataclass_no_repr @ linux-x86_64 +test.test_pprint.QueryTestCase.test_dataclass_with_repr @ linux-x86_64 +test.test_pprint.QueryTestCase.test_default_dict @ linux-x86_64 +test.test_pprint.QueryTestCase.test_depth @ linux-x86_64 +test.test_pprint.QueryTestCase.test_deque @ linux-x86_64 +test.test_pprint.QueryTestCase.test_empty_dataclass @ linux-x86_64 +test.test_pprint.QueryTestCase.test_empty_simple_namespace @ linux-x86_64 +test.test_pprint.QueryTestCase.test_init @ linux-x86_64 +test.test_pprint.QueryTestCase.test_integer @ linux-x86_64 +test.test_pprint.QueryTestCase.test_knotted @ linux-x86_64 +test.test_pprint.QueryTestCase.test_larger_dataclass @ linux-x86_64 +test.test_pprint.QueryTestCase.test_mapping_proxy @ linux-x86_64 +test.test_pprint.QueryTestCase.test_nested_indentations @ linux-x86_64 +test.test_pprint.QueryTestCase.test_ordered_dict @ linux-x86_64 +test.test_pprint.QueryTestCase.test_recursive_dataclass @ linux-x86_64 +test.test_pprint.QueryTestCase.test_same_as_repr @ linux-x86_64 +test.test_pprint.QueryTestCase.test_set_reprs @ linux-x86_64 +test.test_pprint.QueryTestCase.test_simple_namespace @ linux-x86_64 +test.test_pprint.QueryTestCase.test_simple_namespace_subclass @ linux-x86_64 +test.test_pprint.QueryTestCase.test_small_dataclass @ linux-x86_64 +test.test_pprint.QueryTestCase.test_small_simple_namespace @ linux-x86_64 +test.test_pprint.QueryTestCase.test_sort_dict @ linux-x86_64 +test.test_pprint.QueryTestCase.test_sort_orderable_and_unorderable_values @ linux-x86_64 +test.test_pprint.QueryTestCase.test_sort_unorderable_values @ linux-x86_64 +test.test_pprint.QueryTestCase.test_sorted_dict @ linux-x86_64 +test.test_pprint.QueryTestCase.test_stdout_is_None @ linux-x86_64 +test.test_pprint.QueryTestCase.test_str_wrap @ linux-x86_64 +test.test_pprint.QueryTestCase.test_subclassing @ linux-x86_64 +test.test_pprint.QueryTestCase.test_unreadable @ linux-x86_64 +test.test_pprint.QueryTestCase.test_user_dict @ linux-x86_64 +test.test_pprint.QueryTestCase.test_user_list @ linux-x86_64 +test.test_pprint.QueryTestCase.test_user_string @ linux-x86_64 +test.test_pprint.QueryTestCase.test_width @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_print.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_print.txt new file mode 100644 index 0000000000..2b1cdf08a9 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_print.txt @@ -0,0 +1,9 @@ +test.test_print.TestPrint.test_print @ linux-x86_64 +test.test_print.TestPrint.test_print_flush @ linux-x86_64 +test.test_print.TestPy2MigrationHint.test_normal_string @ linux-x86_64 +test.test_print.TestPy2MigrationHint.test_stream_redirection_hint_for_py2_migration @ linux-x86_64 +test.test_print.TestPy2MigrationHint.test_string_in_loop_on_same_line @ linux-x86_64 +test.test_print.TestPy2MigrationHint.test_string_with_excessive_whitespace @ linux-x86_64 +test.test_print.TestPy2MigrationHint.test_string_with_leading_whitespace @ linux-x86_64 +test.test_print.TestPy2MigrationHint.test_string_with_semicolon @ linux-x86_64 +test.test_print.TestPy2MigrationHint.test_string_with_soft_space @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_profile.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_profile.txt new file mode 100644 index 0000000000..8e9d7009ce --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_profile.txt @@ -0,0 +1,4 @@ +test.test_profile.ProfileTest.test_output_file_when_changing_directory @ linux-x86_64 +test.test_profile.ProfileTest.test_run @ linux-x86_64 +test.test_profile.ProfileTest.test_run_profile_as_module @ linux-x86_64 +test.test_profile.ProfileTest.test_runctx @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_property.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_property.txt new file mode 100644 index 0000000000..3ac5d5740a --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_property.txt @@ -0,0 +1,21 @@ +test.test_property.PropertySubclassTests.test_docstring_copy @ linux-x86_64 +test.test_property.PropertySubclassTests.test_property_new_getter_new_docstring @ linux-x86_64 +test.test_property.PropertySubclassTests.test_property_setter_copies_getter_docstring @ linux-x86_64 +test.test_property.PropertySubclassTests.test_slots_docstring_copy_exception @ linux-x86_64 +test.test_property.PropertyTests.test_property___isabstractmethod__descriptor @ linux-x86_64 +test.test_property.PropertyTests.test_property_builtin_doc_writable @ linux-x86_64 +test.test_property.PropertyTests.test_property_decorator_baseclass @ linux-x86_64 +test.test_property.PropertyTests.test_property_decorator_baseclass_doc @ linux-x86_64 +test.test_property.PropertyTests.test_property_decorator_doc @ linux-x86_64 +test.test_property.PropertyTests.test_property_decorator_doc_writable @ linux-x86_64 +test.test_property.PropertyTests.test_property_decorator_subclass @ linux-x86_64 +test.test_property.PropertyTests.test_property_decorator_subclass_doc @ linux-x86_64 +test.test_property.PropertyTests.test_property_getter_doc_override @ linux-x86_64 +test.test_property.PropertyTests.test_property_set_name_incorrect_args @ linux-x86_64 +test.test_property.PropertyTests.test_property_setname_on_property_subclass @ linux-x86_64 +test.test_property.PropertyUnreachableAttributeNoName.test_del_property @ linux-x86_64 +test.test_property.PropertyUnreachableAttributeNoName.test_get_property @ linux-x86_64 +test.test_property.PropertyUnreachableAttributeNoName.test_set_property @ linux-x86_64 +test.test_property.PropertyUnreachableAttributeWithName.test_del_property @ linux-x86_64 +test.test_property.PropertyUnreachableAttributeWithName.test_get_property @ linux-x86_64 +test.test_property.PropertyUnreachableAttributeWithName.test_set_property @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pstats.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pstats.txt new file mode 100644 index 0000000000..c27c49eb23 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pstats.txt @@ -0,0 +1,8 @@ +test.test_pstats.AddCallersTestCase.test_combine_results @ linux-x86_64 +test.test_pstats.StatsTestCase.test_SortKey_enum @ linux-x86_64 +test.test_pstats.StatsTestCase.test_add @ linux-x86_64 +test.test_pstats.StatsTestCase.test_sort_starts_mix @ linux-x86_64 +test.test_pstats.StatsTestCase.test_sort_stats_enum @ linux-x86_64 +test.test_pstats.StatsTestCase.test_sort_stats_int @ linux-x86_64 +test.test_pstats.StatsTestCase.test_sort_stats_partial @ linux-x86_64 +test.test_pstats.StatsTestCase.test_sort_stats_string @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pty.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pty.txt new file mode 100644 index 0000000000..e69c02a69e --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pty.txt @@ -0,0 +1,4 @@ +test.test_pty.PtyTest.test_master_read @ linux-x86_64 +test.test_pty.PtyTest.test_openpty @ linux-x86_64 +test.test_pty.SmallPtyTests.test__copy_to_each @ linux-x86_64 +test.test_pty.SmallPtyTests.test__restore_tty_mode_normal_return @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pulldom.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pulldom.txt new file mode 100644 index 0000000000..ebcfcbe615 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pulldom.txt @@ -0,0 +1,11 @@ +test.test_pulldom.PullDOMTestCase.test_comment @ linux-x86_64 +test.test_pulldom.PullDOMTestCase.test_end_document @ linux-x86_64 +test.test_pulldom.PullDOMTestCase.test_expandItem @ linux-x86_64 +test.test_pulldom.PullDOMTestCase.test_external_ges_default @ linux-x86_64 +test.test_pulldom.PullDOMTestCase.test_parse @ linux-x86_64 +test.test_pulldom.PullDOMTestCase.test_parse_semantics @ linux-x86_64 +test.test_pulldom.SAX2DOMTestCase.testSAX2DOM @ linux-x86_64 +test.test_pulldom.SAX2DOMTestCase.test_basic @ linux-x86_64 +test.test_pulldom.ThoroughTestCase.test_sax2dom_fail @ linux-x86_64 +test.test_pulldom.ThoroughTestCase.test_thorough_parse @ linux-x86_64 +test.test_pulldom.ThoroughTestCase.test_thorough_sax2dom @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pwd.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pwd.txt new file mode 100644 index 0000000000..2350c4121e --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pwd.txt @@ -0,0 +1,3 @@ +test.test_pwd.PwdTest.test_errors @ linux-x86_64 +test.test_pwd.PwdTest.test_values @ linux-x86_64 +test.test_pwd.PwdTest.test_values_extended @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_py_compile.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_py_compile.txt new file mode 100644 index 0000000000..c1ca96f9c9 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_py_compile.txt @@ -0,0 +1,32 @@ +test.test_py_compile.PyCompileCLITestCase.test_bad_syntax @ linux-x86_64 +test.test_py_compile.PyCompileCLITestCase.test_bad_syntax_with_quiet @ linux-x86_64 +test.test_py_compile.PyCompileCLITestCase.test_file_not_exists @ linux-x86_64 +test.test_py_compile.PyCompileCLITestCase.test_file_not_exists_with_quiet @ linux-x86_64 +test.test_py_compile.PyCompileCLITestCase.test_stdin @ linux-x86_64 +test.test_py_compile.PyCompileCLITestCase.test_with_files @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithSourceEpoch.test_absolute_path @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithSourceEpoch.test_bad_coding @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithSourceEpoch.test_cache_path @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithSourceEpoch.test_cwd @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithSourceEpoch.test_do_not_overwrite_nonregular_files @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithSourceEpoch.test_do_not_overwrite_symlinks @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithSourceEpoch.test_double_dot_no_clobber @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithSourceEpoch.test_exceptions_propagate @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithSourceEpoch.test_invalidation_mode @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithSourceEpoch.test_optimization_path @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithSourceEpoch.test_quiet @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithSourceEpoch.test_relative_path @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithSourceEpoch.test_source_date_epoch @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithoutSourceEpoch.test_absolute_path @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithoutSourceEpoch.test_bad_coding @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithoutSourceEpoch.test_cache_path @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithoutSourceEpoch.test_cwd @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithoutSourceEpoch.test_do_not_overwrite_nonregular_files @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithoutSourceEpoch.test_do_not_overwrite_symlinks @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithoutSourceEpoch.test_double_dot_no_clobber @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithoutSourceEpoch.test_exceptions_propagate @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithoutSourceEpoch.test_invalidation_mode @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithoutSourceEpoch.test_optimization_path @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithoutSourceEpoch.test_quiet @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithoutSourceEpoch.test_relative_path @ linux-x86_64 +test.test_py_compile.PyCompileTestsWithoutSourceEpoch.test_source_date_epoch @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pyclbr.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pyclbr.txt new file mode 100644 index 0000000000..6ea16c12bb --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pyclbr.txt @@ -0,0 +1,6 @@ +test.test_pyclbr.PyclbrTest.test_decorators @ linux-x86_64 +test.test_pyclbr.PyclbrTest.test_easy @ linux-x86_64 +test.test_pyclbr.PyclbrTest.test_nested @ linux-x86_64 +test.test_pyclbr.PyclbrTest.test_others @ linux-x86_64 +test.test_pyclbr.ReadmoduleTests.test_dotted_name_not_a_package @ linux-x86_64 +test.test_pyclbr.ReadmoduleTests.test_module_has_no_spec @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pydoc.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pydoc.txt new file mode 100644 index 0000000000..a19b686d77 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pydoc.txt @@ -0,0 +1,68 @@ +test.test_pydoc.PydocDocTest.test__future__imports @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_allmethods @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_builtin_no_child @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_builtin_on_metaclasses @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_builtin_with_child @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_builtin_with_grandchild @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_builtin_with_more_than_four_children @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_fail_help_cli @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_fail_help_output_redirect @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_getpager_with_stdin_none @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_input_strip @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_is_package_when_is_package @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_is_package_when_not_package @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_issue8225 @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_mixed_case_module_names_are_lower_cased @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_namedtuple_fields @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_namedtuple_public_underscore @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_non_str_name @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_not_ascii @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_not_here @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_splitdoc_with_description @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_stripid @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_synopsis @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_synopsis_sourceless @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_synopsis_sourceless_empty_doc @ linux-x86_64 +test.test_pydoc.PydocDocTest.test_text_enum_member_with_value_zero @ linux-x86_64 +test.test_pydoc.PydocImportTest.test_apropos_empty_doc @ linux-x86_64 +test.test_pydoc.PydocImportTest.test_apropos_with_bad_package @ linux-x86_64 +test.test_pydoc.PydocImportTest.test_apropos_with_unreadable_dir @ linux-x86_64 +test.test_pydoc.PydocImportTest.test_badimport @ linux-x86_64 +test.test_pydoc.PydocImportTest.test_importfile @ linux-x86_64 +test.test_pydoc.PydocImportTest.test_url_search_package_error @ linux-x86_64 +test.test_pydoc.PydocServerTest.test_server @ linux-x86_64 +test.test_pydoc.PydocUrlHandlerTest.test_content_type_err @ linux-x86_64 +test.test_pydoc.PydocUrlHandlerTest.test_url_requests @ linux-x86_64 +test.test_pydoc.PydocWithMetaClasses.test_buggy_dir @ linux-x86_64 +test.test_pydoc.PydocWithMetaClasses.test_resolve_false @ linux-x86_64 +test.test_pydoc.PydocWithMetaClasses.test_virtualClassAttributeWithOneMeta @ linux-x86_64 +test.test_pydoc.PydocWithMetaClasses.test_virtualClassAttributeWithTwoMeta @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_async_annotation @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_async_generator_annotation @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_bound_builtin_method @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_bound_python_method @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_builtin @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_class @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_custom_data_descriptor @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_custom_non_data_descriptor @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_dict_attr_descriptor @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_field_order_for_named_tuples @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_generic_alias @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_getset_descriptor @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_html_for_https_links @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_member_descriptor @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_module @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_namedtuple_field_descriptor @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_property @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_slot_descriptor @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_special_form @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_staticmethod @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_structseq_member_descriptor @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_typing_pydoc @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_unbound_builtin_method @ linux-x86_64 +test.test_pydoc.TestDescriptions.test_unbound_python_method @ linux-x86_64 +test.test_pydoc.TestHelper.test_keywords @ linux-x86_64 +test.test_pydoc.TestInternalUtilities.test_sys_path_adjustment_adds_missing_curdir @ linux-x86_64 +test.test_pydoc.TestInternalUtilities.test_sys_path_adjustment_protects_pydoc_dir @ linux-x86_64 +test.test_pydoc.TestInternalUtilities.test_sys_path_adjustment_removes_argv0_dir @ linux-x86_64 +test.test_pydoc.TestInternalUtilities.test_sys_path_adjustment_when_curdir_already_included @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pyexpat.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pyexpat.txt new file mode 100644 index 0000000000..b7296c43ce --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_pyexpat.txt @@ -0,0 +1,38 @@ +test.test_pyexpat.BufferTextTest.test1 @ linux-x86_64 +test.test_pyexpat.BufferTextTest.test2 @ linux-x86_64 +test.test_pyexpat.BufferTextTest.test3 @ linux-x86_64 +test.test_pyexpat.BufferTextTest.test4 @ linux-x86_64 +test.test_pyexpat.BufferTextTest.test5 @ linux-x86_64 +test.test_pyexpat.BufferTextTest.test6 @ linux-x86_64 +test.test_pyexpat.BufferTextTest.test7 @ linux-x86_64 +test.test_pyexpat.BufferTextTest.test_buffering_enabled @ linux-x86_64 +test.test_pyexpat.BufferTextTest.test_default_to_disabled @ linux-x86_64 +test.test_pyexpat.ChardataBufferTest.test_1000_bytes @ linux-x86_64 +test.test_pyexpat.ChardataBufferTest.test_1025_bytes @ linux-x86_64 +test.test_pyexpat.ChardataBufferTest.test_change_size_1 @ linux-x86_64 +test.test_pyexpat.ChardataBufferTest.test_change_size_2 @ linux-x86_64 +test.test_pyexpat.ChardataBufferTest.test_disabling_buffer @ linux-x86_64 +test.test_pyexpat.ChardataBufferTest.test_unchanged_size @ linux-x86_64 +test.test_pyexpat.ChardataBufferTest.test_wrong_size @ linux-x86_64 +test.test_pyexpat.ErrorMessageTest.test_codes @ linux-x86_64 +test.test_pyexpat.ErrorMessageTest.test_expaterror @ linux-x86_64 +test.test_pyexpat.ForeignDTDTests.test_ignore_use_foreign_dtd @ linux-x86_64 +test.test_pyexpat.ForeignDTDTests.test_use_foreign_dtd @ linux-x86_64 +test.test_pyexpat.InterningTest.test @ linux-x86_64 +test.test_pyexpat.InterningTest.test_issue9402 @ linux-x86_64 +test.test_pyexpat.MalformedInputTest.test1 @ linux-x86_64 +test.test_pyexpat.MalformedInputTest.test2 @ linux-x86_64 +test.test_pyexpat.NamespaceSeparatorTest.test_illegal @ linux-x86_64 +test.test_pyexpat.NamespaceSeparatorTest.test_legal @ linux-x86_64 +test.test_pyexpat.NamespaceSeparatorTest.test_zero_length @ linux-x86_64 +test.test_pyexpat.ParseTest.test_parse_again @ linux-x86_64 +test.test_pyexpat.ParseTest.test_parse_bytes @ linux-x86_64 +test.test_pyexpat.ParseTest.test_parse_file @ linux-x86_64 +test.test_pyexpat.ParseTest.test_parse_str @ linux-x86_64 +test.test_pyexpat.PositionTest.test @ linux-x86_64 +test.test_pyexpat.SetAttributeTest.test_buffer_text @ linux-x86_64 +test.test_pyexpat.SetAttributeTest.test_invalid_attributes @ linux-x86_64 +test.test_pyexpat.SetAttributeTest.test_namespace_prefixes @ linux-x86_64 +test.test_pyexpat.SetAttributeTest.test_ordered_attributes @ linux-x86_64 +test.test_pyexpat.SetAttributeTest.test_specified_attributes @ linux-x86_64 +test.test_pyexpat.sf1296433Test.test_parse_only_xml_data @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_queue.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_queue.txt new file mode 100644 index 0000000000..0c1c8fcfb2 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_queue.txt @@ -0,0 +1,52 @@ +test.test_queue.CFailingQueueTest.test_failing_queue @ linux-x86_64 +test.test_queue.CLifoQueueTest.test_basic @ linux-x86_64 +test.test_queue.CLifoQueueTest.test_negative_timeout_raises_exception @ linux-x86_64 +test.test_queue.CLifoQueueTest.test_nowait @ linux-x86_64 +test.test_queue.CLifoQueueTest.test_queue_join @ linux-x86_64 +test.test_queue.CLifoQueueTest.test_queue_task_done @ linux-x86_64 +test.test_queue.CLifoQueueTest.test_shrinking_queue @ linux-x86_64 +test.test_queue.CPriorityQueueTest.test_basic @ linux-x86_64 +test.test_queue.CPriorityQueueTest.test_negative_timeout_raises_exception @ linux-x86_64 +test.test_queue.CPriorityQueueTest.test_nowait @ linux-x86_64 +test.test_queue.CPriorityQueueTest.test_queue_join @ linux-x86_64 +test.test_queue.CPriorityQueueTest.test_queue_task_done @ linux-x86_64 +test.test_queue.CPriorityQueueTest.test_shrinking_queue @ linux-x86_64 +test.test_queue.CQueueTest.test_basic @ linux-x86_64 +test.test_queue.CQueueTest.test_negative_timeout_raises_exception @ linux-x86_64 +test.test_queue.CQueueTest.test_nowait @ linux-x86_64 +test.test_queue.CQueueTest.test_queue_join @ linux-x86_64 +test.test_queue.CQueueTest.test_queue_task_done @ linux-x86_64 +test.test_queue.CQueueTest.test_shrinking_queue @ linux-x86_64 +test.test_queue.CSimpleQueueTest.test_basic @ linux-x86_64 +test.test_queue.CSimpleQueueTest.test_is_default @ linux-x86_64 +test.test_queue.CSimpleQueueTest.test_many_threads @ linux-x86_64 +test.test_queue.CSimpleQueueTest.test_many_threads_nonblock @ linux-x86_64 +test.test_queue.CSimpleQueueTest.test_many_threads_timeout @ linux-x86_64 +test.test_queue.CSimpleQueueTest.test_negative_timeout_raises_exception @ linux-x86_64 +test.test_queue.CSimpleQueueTest.test_order @ linux-x86_64 +test.test_queue.CSimpleQueueTest.test_reentrancy @ linux-x86_64 +test.test_queue.PyFailingQueueTest.test_failing_queue @ linux-x86_64 +test.test_queue.PyLifoQueueTest.test_basic @ linux-x86_64 +test.test_queue.PyLifoQueueTest.test_negative_timeout_raises_exception @ linux-x86_64 +test.test_queue.PyLifoQueueTest.test_nowait @ linux-x86_64 +test.test_queue.PyLifoQueueTest.test_queue_join @ linux-x86_64 +test.test_queue.PyLifoQueueTest.test_queue_task_done @ linux-x86_64 +test.test_queue.PyLifoQueueTest.test_shrinking_queue @ linux-x86_64 +test.test_queue.PyPriorityQueueTest.test_basic @ linux-x86_64 +test.test_queue.PyPriorityQueueTest.test_negative_timeout_raises_exception @ linux-x86_64 +test.test_queue.PyPriorityQueueTest.test_nowait @ linux-x86_64 +test.test_queue.PyPriorityQueueTest.test_queue_join @ linux-x86_64 +test.test_queue.PyPriorityQueueTest.test_queue_task_done @ linux-x86_64 +test.test_queue.PyPriorityQueueTest.test_shrinking_queue @ linux-x86_64 +test.test_queue.PyQueueTest.test_basic @ linux-x86_64 +test.test_queue.PyQueueTest.test_negative_timeout_raises_exception @ linux-x86_64 +test.test_queue.PyQueueTest.test_nowait @ linux-x86_64 +test.test_queue.PyQueueTest.test_queue_join @ linux-x86_64 +test.test_queue.PyQueueTest.test_queue_task_done @ linux-x86_64 +test.test_queue.PyQueueTest.test_shrinking_queue @ linux-x86_64 +test.test_queue.PySimpleQueueTest.test_basic @ linux-x86_64 +test.test_queue.PySimpleQueueTest.test_many_threads @ linux-x86_64 +test.test_queue.PySimpleQueueTest.test_many_threads_nonblock @ linux-x86_64 +test.test_queue.PySimpleQueueTest.test_many_threads_timeout @ linux-x86_64 +test.test_queue.PySimpleQueueTest.test_negative_timeout_raises_exception @ linux-x86_64 +test.test_queue.PySimpleQueueTest.test_order @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_quopri.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_quopri.txt new file mode 100644 index 0000000000..6333652793 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_quopri.txt @@ -0,0 +1,11 @@ +test.test_quopri.QuopriTestCase.test_decode @ linux-x86_64 +test.test_quopri.QuopriTestCase.test_decode_header @ linux-x86_64 +test.test_quopri.QuopriTestCase.test_decodestring @ linux-x86_64 +test.test_quopri.QuopriTestCase.test_decodestring_double_equals @ linux-x86_64 +test.test_quopri.QuopriTestCase.test_embedded_ws @ linux-x86_64 +test.test_quopri.QuopriTestCase.test_encode @ linux-x86_64 +test.test_quopri.QuopriTestCase.test_encode_header @ linux-x86_64 +test.test_quopri.QuopriTestCase.test_encodestring @ linux-x86_64 +test.test_quopri.QuopriTestCase.test_idempotent_string @ linux-x86_64 +test.test_quopri.QuopriTestCase.test_scriptdecode @ linux-x86_64 +test.test_quopri.QuopriTestCase.test_scriptencode @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_raise.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_raise.txt new file mode 100644 index 0000000000..7fee0280cd --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_raise.txt @@ -0,0 +1,34 @@ +test.test_raise.TestCause.testCauseSyntax @ linux-x86_64 +test.test_raise.TestCause.test_class_cause @ linux-x86_64 +test.test_raise.TestCause.test_erroneous_cause @ linux-x86_64 +test.test_raise.TestCause.test_instance_cause @ linux-x86_64 +test.test_raise.TestCause.test_invalid_cause @ linux-x86_64 +test.test_raise.TestContext.test_3118 @ linux-x86_64 +test.test_raise.TestContext.test_c_exception_context @ linux-x86_64 +test.test_raise.TestContext.test_c_exception_raise @ linux-x86_64 +test.test_raise.TestContext.test_class_context_class_raise @ linux-x86_64 +test.test_raise.TestContext.test_class_context_instance_raise @ linux-x86_64 +test.test_raise.TestContext.test_context_manager @ linux-x86_64 +test.test_raise.TestContext.test_cycle_broken @ linux-x86_64 +test.test_raise.TestContext.test_instance_context_instance_raise @ linux-x86_64 +test.test_raise.TestContext.test_noraise_finally @ linux-x86_64 +test.test_raise.TestContext.test_not_last @ linux-x86_64 +test.test_raise.TestContext.test_raise_finally @ linux-x86_64 +test.test_raise.TestContext.test_reraise_cycle_broken @ linux-x86_64 +test.test_raise.TestRaise.test_assert_with_tuple_arg @ linux-x86_64 +test.test_raise.TestRaise.test_erroneous_exception @ linux-x86_64 +test.test_raise.TestRaise.test_except_reraise @ linux-x86_64 +test.test_raise.TestRaise.test_finally_reraise @ linux-x86_64 +test.test_raise.TestRaise.test_invalid_reraise @ linux-x86_64 +test.test_raise.TestRaise.test_nested_reraise @ linux-x86_64 +test.test_raise.TestRaise.test_new_returns_invalid_instance @ linux-x86_64 +test.test_raise.TestRaise.test_raise_from_None @ linux-x86_64 +test.test_raise.TestRaise.test_reraise @ linux-x86_64 +test.test_raise.TestRaise.test_with_reraise1 @ linux-x86_64 +test.test_raise.TestRaise.test_with_reraise2 @ linux-x86_64 +test.test_raise.TestRemovedFunctionality.test_strings @ linux-x86_64 +test.test_raise.TestRemovedFunctionality.test_tuples @ linux-x86_64 +test.test_raise.TestTraceback.test_accepts_traceback @ linux-x86_64 +test.test_raise.TestTraceback.test_sets_traceback @ linux-x86_64 +test.test_raise.TestTracebackType.test_attrs @ linux-x86_64 +test.test_raise.TestTracebackType.test_constructor @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_random.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_random.txt new file mode 100644 index 0000000000..80ca585573 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_random.txt @@ -0,0 +1,98 @@ +test.test_random.MersenneTwister_TestBasicOps.test_53_bits_per_float @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_autoseed @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_bigrand @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_bigrand_ranges @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_bug_1727780 @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_bug_27706 @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_bug_31478 @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_bug_31482 @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_bug_9025 @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_choice @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_choice_with_numpy @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_choices @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_choices_algorithms @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_choices_infinite_total @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_choices_negative_total @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_choices_subnormal @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_choices_with_all_zero_weights @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_gauss @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_getrandbits @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_guaranteed_stable @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_long_seed @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_mu_sigma_default_args @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_pickling @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_randbelow_logic @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_randbelow_without_getrandbits @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_randbytes @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_randbytes_getrandbits @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_randrange_bug_1590891 @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_randrange_uses_getrandbits @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_rangelimits @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_referenceImplementation @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_sample @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_sample_counts_equivalence @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_sample_distribution @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_sample_inputs @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_sample_on_dicts @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_sample_on_seqsets @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_sample_on_sets @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_sample_with_counts @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_saverestore @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_seed_no_mutate_bug_44018 @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_seed_when_randomness_source_not_found @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_seedargs @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_setstate_first_arg @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_setstate_middle_arg @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_shuffle @ linux-x86_64 +test.test_random.MersenneTwister_TestBasicOps.test_strong_reference_implementation @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_53_bits_per_float @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_autoseed @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_bigrand @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_bigrand_ranges @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_bug_1727780 @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_bug_9025 @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_choice @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_choice_with_numpy @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_choices @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_choices_infinite_total @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_choices_negative_total @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_choices_subnormal @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_choices_with_all_zero_weights @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_gauss @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_getrandbits @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_mu_sigma_default_args @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_pickling @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_randbelow_logic @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_randbytes @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_randrange_argument_handling @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_randrange_errors @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_randrange_nonunit_step @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_randrange_step @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_rangelimits @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_sample @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_sample_distribution @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_sample_inputs @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_sample_on_dicts @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_sample_on_seqsets @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_sample_on_sets @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_sample_with_counts @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_saverestore @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_seed_no_mutate_bug_44018 @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_seed_when_randomness_source_not_found @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_seedargs @ linux-x86_64 +test.test_random.SystemRandom_TestBasicOps.test_shuffle @ linux-x86_64 +test.test_random.TestDistributions.test_avg_std @ linux-x86_64 +test.test_random.TestDistributions.test_betavariate_return_zero @ linux-x86_64 +test.test_random.TestDistributions.test_constant @ linux-x86_64 +test.test_random.TestDistributions.test_gammavariate_alpha_between_zero_and_one @ linux-x86_64 +test.test_random.TestDistributions.test_gammavariate_alpha_equal_one @ linux-x86_64 +test.test_random.TestDistributions.test_gammavariate_alpha_equal_one_equals_expovariate @ linux-x86_64 +test.test_random.TestDistributions.test_gammavariate_alpha_greater_one @ linux-x86_64 +test.test_random.TestDistributions.test_gammavariate_errors @ linux-x86_64 +test.test_random.TestDistributions.test_von_mises_large_kappa @ linux-x86_64 +test.test_random.TestDistributions.test_von_mises_range @ linux-x86_64 +test.test_random.TestDistributions.test_zeroinputs @ linux-x86_64 +test.test_random.TestModule.testMagicConstants @ linux-x86_64 +test.test_random.TestModule.test__all__ @ linux-x86_64 +test.test_random.TestRandomSubclassing.test_random_subclass_with_kwargs @ linux-x86_64 +test.test_random.TestRandomSubclassing.test_subclasses_overriding_methods @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_range.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_range.txt new file mode 100644 index 0000000000..349ae580da --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_range.txt @@ -0,0 +1,25 @@ +test.test_range.RangeTest.test_attributes @ linux-x86_64 +test.test_range.RangeTest.test_comparison @ linux-x86_64 +test.test_range.RangeTest.test_contains @ linux-x86_64 +test.test_range.RangeTest.test_count @ linux-x86_64 +test.test_range.RangeTest.test_empty @ linux-x86_64 +test.test_range.RangeTest.test_exhausted_iterator_pickling @ linux-x86_64 +test.test_range.RangeTest.test_index @ linux-x86_64 +test.test_range.RangeTest.test_invalid_invocation @ linux-x86_64 +test.test_range.RangeTest.test_issue11845 @ linux-x86_64 +test.test_range.RangeTest.test_iterator_pickling @ linux-x86_64 +test.test_range.RangeTest.test_iterator_pickling_overflowing_index @ linux-x86_64 +test.test_range.RangeTest.test_large_exhausted_iterator_pickling @ linux-x86_64 +test.test_range.RangeTest.test_large_operands @ linux-x86_64 +test.test_range.RangeTest.test_large_range @ linux-x86_64 +test.test_range.RangeTest.test_odd_bug @ linux-x86_64 +test.test_range.RangeTest.test_pickling @ linux-x86_64 +test.test_range.RangeTest.test_range @ linux-x86_64 +test.test_range.RangeTest.test_range_iterators @ linux-x86_64 +test.test_range.RangeTest.test_range_iterators_invocation @ linux-x86_64 +test.test_range.RangeTest.test_repr @ linux-x86_64 +test.test_range.RangeTest.test_reverse_iteration @ linux-x86_64 +test.test_range.RangeTest.test_slice @ linux-x86_64 +test.test_range.RangeTest.test_strided_limits @ linux-x86_64 +test.test_range.RangeTest.test_types @ linux-x86_64 +test.test_range.RangeTest.test_user_index_method @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_re.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_re.txt new file mode 100644 index 0000000000..d670732bf2 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_re.txt @@ -0,0 +1,143 @@ +test.test_re.ExternalTests.test_re_benchmarks @ linux-x86_64 +test.test_re.ExternalTests.test_re_tests @ linux-x86_64 +test.test_re.ImplementationTest.test_overlap_table @ linux-x86_64 +test.test_re.ImplementationTest.test_signedness @ linux-x86_64 +test.test_re.PatternReprTests.test_bytes @ linux-x86_64 +test.test_re.PatternReprTests.test_flags_repr @ linux-x86_64 +test.test_re.PatternReprTests.test_inline_flags @ linux-x86_64 +test.test_re.PatternReprTests.test_locale @ linux-x86_64 +test.test_re.PatternReprTests.test_long_pattern @ linux-x86_64 +test.test_re.PatternReprTests.test_multiple_flags @ linux-x86_64 +test.test_re.PatternReprTests.test_quotes @ linux-x86_64 +test.test_re.PatternReprTests.test_single_flag @ linux-x86_64 +test.test_re.PatternReprTests.test_unicode_flag @ linux-x86_64 +test.test_re.PatternReprTests.test_unknown_flags @ linux-x86_64 +test.test_re.PatternReprTests.test_without_flags @ linux-x86_64 +test.test_re.ReTests.test_ASSERT_NOT_mark_bug @ linux-x86_64 +test.test_re.ReTests.test_MARK_PUSH_macro_bug @ linux-x86_64 +test.test_re.ReTests.test_MIN_REPEAT_ONE_mark_bug @ linux-x86_64 +test.test_re.ReTests.test_MIN_UNTIL_mark_bug @ linux-x86_64 +test.test_re.ReTests.test_REPEAT_ONE_mark_bug @ linux-x86_64 +test.test_re.ReTests.test_anyall @ linux-x86_64 +test.test_re.ReTests.test_ascii_and_unicode_flag @ linux-x86_64 +test.test_re.ReTests.test_atomic_grouping @ linux-x86_64 +test.test_re.ReTests.test_backref_group_name_in_exception @ linux-x86_64 +test.test_re.ReTests.test_basic_re_sub @ linux-x86_64 +test.test_re.ReTests.test_big_codesize @ linux-x86_64 +test.test_re.ReTests.test_bigcharset @ linux-x86_64 +test.test_re.ReTests.test_branching @ linux-x86_64 +test.test_re.ReTests.test_bug_113254 @ linux-x86_64 +test.test_re.ReTests.test_bug_114660 @ linux-x86_64 +test.test_re.ReTests.test_bug_117612 @ linux-x86_64 +test.test_re.ReTests.test_bug_1661 @ linux-x86_64 +test.test_re.ReTests.test_bug_16688 @ linux-x86_64 +test.test_re.ReTests.test_bug_20998 @ linux-x86_64 +test.test_re.ReTests.test_bug_2537 @ linux-x86_64 +test.test_re.ReTests.test_bug_29444 @ linux-x86_64 +test.test_re.ReTests.test_bug_34294 @ linux-x86_64 +test.test_re.ReTests.test_bug_3629 @ linux-x86_64 +test.test_re.ReTests.test_bug_418626 @ linux-x86_64 +test.test_re.ReTests.test_bug_448951 @ linux-x86_64 +test.test_re.ReTests.test_bug_449000 @ linux-x86_64 +test.test_re.ReTests.test_bug_449964 @ linux-x86_64 +test.test_re.ReTests.test_bug_527371 @ linux-x86_64 +test.test_re.ReTests.test_bug_581080 @ linux-x86_64 +test.test_re.ReTests.test_bug_612074 @ linux-x86_64 +test.test_re.ReTests.test_bug_6509 @ linux-x86_64 +test.test_re.ReTests.test_bug_6561 @ linux-x86_64 +test.test_re.ReTests.test_bug_725106 @ linux-x86_64 +test.test_re.ReTests.test_bug_725149 @ linux-x86_64 +test.test_re.ReTests.test_bug_764548 @ linux-x86_64 +test.test_re.ReTests.test_bug_817234 @ linux-x86_64 +test.test_re.ReTests.test_bug_926075 @ linux-x86_64 +test.test_re.ReTests.test_bug_931848 @ linux-x86_64 +test.test_re.ReTests.test_bug_gh106052 @ linux-x86_64 +test.test_re.ReTests.test_bug_gh91616 @ linux-x86_64 +test.test_re.ReTests.test_bytes_str_mixing @ linux-x86_64 +test.test_re.ReTests.test_category @ linux-x86_64 +test.test_re.ReTests.test_character_set_errors @ linux-x86_64 +test.test_re.ReTests.test_comments @ linux-x86_64 +test.test_re.ReTests.test_compile @ linux-x86_64 +test.test_re.ReTests.test_constants @ linux-x86_64 +test.test_re.ReTests.test_copying @ linux-x86_64 +test.test_re.ReTests.test_dollar_matches_twice @ linux-x86_64 +test.test_re.ReTests.test_empty_array @ linux-x86_64 +test.test_re.ReTests.test_enum @ linux-x86_64 +test.test_re.ReTests.test_error @ linux-x86_64 +test.test_re.ReTests.test_expand @ linux-x86_64 +test.test_re.ReTests.test_findall_atomic_grouping @ linux-x86_64 +test.test_re.ReTests.test_findall_possessive_quantifiers @ linux-x86_64 +test.test_re.ReTests.test_finditer @ linux-x86_64 +test.test_re.ReTests.test_flags @ linux-x86_64 +test.test_re.ReTests.test_fullmatch_atomic_grouping @ linux-x86_64 +test.test_re.ReTests.test_fullmatch_possessive_quantifiers @ linux-x86_64 +test.test_re.ReTests.test_getattr @ linux-x86_64 +test.test_re.ReTests.test_group @ linux-x86_64 +test.test_re.ReTests.test_group_name_in_exception @ linux-x86_64 +test.test_re.ReTests.test_groupdict @ linux-x86_64 +test.test_re.ReTests.test_ignore_case @ linux-x86_64 +test.test_re.ReTests.test_ignore_case_range @ linux-x86_64 +test.test_re.ReTests.test_ignore_case_set @ linux-x86_64 +test.test_re.ReTests.test_ignore_spaces @ linux-x86_64 +test.test_re.ReTests.test_inline_flags @ linux-x86_64 +test.test_re.ReTests.test_issue17998 @ linux-x86_64 +test.test_re.ReTests.test_keyword_parameters @ linux-x86_64 +test.test_re.ReTests.test_large_search @ linux-x86_64 +test.test_re.ReTests.test_large_subn @ linux-x86_64 +test.test_re.ReTests.test_locale_flag @ linux-x86_64 +test.test_re.ReTests.test_lookahead @ linux-x86_64 +test.test_re.ReTests.test_lookbehind @ linux-x86_64 +test.test_re.ReTests.test_match_getitem @ linux-x86_64 +test.test_re.ReTests.test_match_repr @ linux-x86_64 +test.test_re.ReTests.test_misc_errors @ linux-x86_64 +test.test_re.ReTests.test_multiple_repeat @ linux-x86_64 +test.test_re.ReTests.test_named_unicode_escapes @ linux-x86_64 +test.test_re.ReTests.test_not_literal @ linux-x86_64 +test.test_re.ReTests.test_nothing_to_repeat @ linux-x86_64 +test.test_re.ReTests.test_other_escapes @ linux-x86_64 +test.test_re.ReTests.test_pattern_compare @ linux-x86_64 +test.test_re.ReTests.test_pattern_compare_bytes @ linux-x86_64 +test.test_re.ReTests.test_pickling @ linux-x86_64 +test.test_re.ReTests.test_possessive_quantifiers @ linux-x86_64 +test.test_re.ReTests.test_possible_set_operations @ linux-x86_64 +test.test_re.ReTests.test_qualified_re_split @ linux-x86_64 +test.test_re.ReTests.test_qualified_re_sub @ linux-x86_64 +test.test_re.ReTests.test_re_escape @ linux-x86_64 +test.test_re.ReTests.test_re_escape_bytes @ linux-x86_64 +test.test_re.ReTests.test_re_escape_non_ascii @ linux-x86_64 +test.test_re.ReTests.test_re_escape_non_ascii_bytes @ linux-x86_64 +test.test_re.ReTests.test_re_findall @ linux-x86_64 +test.test_re.ReTests.test_re_fullmatch @ linux-x86_64 +test.test_re.ReTests.test_re_groupref @ linux-x86_64 +test.test_re.ReTests.test_re_groupref_exists @ linux-x86_64 +test.test_re.ReTests.test_re_groupref_exists_errors @ linux-x86_64 +test.test_re.ReTests.test_re_groupref_exists_validation_bug @ linux-x86_64 +test.test_re.ReTests.test_re_groupref_overflow @ linux-x86_64 +test.test_re.ReTests.test_re_match @ linux-x86_64 +test.test_re.ReTests.test_re_split @ linux-x86_64 +test.test_re.ReTests.test_re_subn @ linux-x86_64 +test.test_re.ReTests.test_regression_gh94675 @ linux-x86_64 +test.test_re.ReTests.test_repeat_minmax @ linux-x86_64 +test.test_re.ReTests.test_repeat_minmax_overflow @ linux-x86_64 +test.test_re.ReTests.test_scanner @ linux-x86_64 +test.test_re.ReTests.test_scoped_flags @ linux-x86_64 +test.test_re.ReTests.test_search_anchor_at_beginning @ linux-x86_64 +test.test_re.ReTests.test_search_coverage @ linux-x86_64 +test.test_re.ReTests.test_search_dot_unicode @ linux-x86_64 +test.test_re.ReTests.test_search_star_plus @ linux-x86_64 +test.test_re.ReTests.test_special_escapes @ linux-x86_64 +test.test_re.ReTests.test_sre_byte_class_literals @ linux-x86_64 +test.test_re.ReTests.test_sre_byte_literals @ linux-x86_64 +test.test_re.ReTests.test_sre_character_class_literals @ linux-x86_64 +test.test_re.ReTests.test_sre_character_literals @ linux-x86_64 +test.test_re.ReTests.test_stack_overflow @ linux-x86_64 +test.test_re.ReTests.test_string_boundaries @ linux-x86_64 +test.test_re.ReTests.test_sub_template_numeric_escape @ linux-x86_64 +test.test_re.ReTests.test_symbolic_groups @ linux-x86_64 +test.test_re.ReTests.test_symbolic_groups_errors @ linux-x86_64 +test.test_re.ReTests.test_symbolic_refs @ linux-x86_64 +test.test_re.ReTests.test_symbolic_refs_errors @ linux-x86_64 +test.test_re.ReTests.test_template_function_and_flag_is_deprecated @ linux-x86_64 +test.test_re.ReTests.test_unlimited_zero_width_repeat @ linux-x86_64 +test.test_re.ReTests.test_weakref @ linux-x86_64 +test.test_re.ReTests.test_zerowidth @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_reprlib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_reprlib.txt new file mode 100644 index 0000000000..4904ac5122 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_reprlib.txt @@ -0,0 +1,20 @@ +test.test_reprlib.LongReprTest.test_class @ linux-x86_64 +test.test_reprlib.LongReprTest.test_instance @ linux-x86_64 +test.test_reprlib.LongReprTest.test_method @ linux-x86_64 +test.test_reprlib.LongReprTest.test_module @ linux-x86_64 +test.test_reprlib.LongReprTest.test_type @ linux-x86_64 +test.test_reprlib.ReprTests.test_builtin_function @ linux-x86_64 +test.test_reprlib.ReprTests.test_cell @ linux-x86_64 +test.test_reprlib.ReprTests.test_container @ linux-x86_64 +test.test_reprlib.ReprTests.test_descriptors @ linux-x86_64 +test.test_reprlib.ReprTests.test_frozenset @ linux-x86_64 +test.test_reprlib.ReprTests.test_instance @ linux-x86_64 +test.test_reprlib.ReprTests.test_nesting @ linux-x86_64 +test.test_reprlib.ReprTests.test_numbers @ linux-x86_64 +test.test_reprlib.ReprTests.test_range @ linux-x86_64 +test.test_reprlib.ReprTests.test_set_literal @ linux-x86_64 +test.test_reprlib.ReprTests.test_string @ linux-x86_64 +test.test_reprlib.ReprTests.test_tuple @ linux-x86_64 +test.test_reprlib.ReprTests.test_unsortable @ linux-x86_64 +test.test_reprlib.TestRecursiveRepr.test_assigned_attributes @ linux-x86_64 +test.test_reprlib.TestRecursiveRepr.test_recursive_repr @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_resource.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_resource.txt new file mode 100644 index 0000000000..3e0d697fed --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_resource.txt @@ -0,0 +1,4 @@ +test.test_resource.ResourceTest.test_freebsd_contants @ linux-x86_64 +test.test_resource.ResourceTest.test_getrusage @ linux-x86_64 +test.test_resource.ResourceTest.test_linux_constants @ linux-x86_64 +test.test_resource.ResourceTest.test_pagesize @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_richcmp.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_richcmp.txt new file mode 100644 index 0000000000..49ac537d10 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_richcmp.txt @@ -0,0 +1,11 @@ +test.test_richcmp.DictTest.test_dicts @ linux-x86_64 +test.test_richcmp.ListTest.test_badentry @ linux-x86_64 +test.test_richcmp.ListTest.test_coverage @ linux-x86_64 +test.test_richcmp.ListTest.test_goodentry @ linux-x86_64 +test.test_richcmp.MiscTest.test_exception_message @ linux-x86_64 +test.test_richcmp.MiscTest.test_misbehavin @ linux-x86_64 +test.test_richcmp.MiscTest.test_not @ linux-x86_64 +test.test_richcmp.MiscTest.test_recursion @ linux-x86_64 +test.test_richcmp.NumberTest.test_basic @ linux-x86_64 +test.test_richcmp.NumberTest.test_values @ linux-x86_64 +test.test_richcmp.VectorTest.test_mixed @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_rlcompleter.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_rlcompleter.txt new file mode 100644 index 0000000000..2302309974 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_rlcompleter.txt @@ -0,0 +1,7 @@ +test.test_rlcompleter.TestRlcompleter.test_complete @ linux-x86_64 +test.test_rlcompleter.TestRlcompleter.test_duplicate_globals @ linux-x86_64 +test.test_rlcompleter.TestRlcompleter.test_excessive_getattr @ linux-x86_64 +test.test_rlcompleter.TestRlcompleter.test_global_matches @ linux-x86_64 +test.test_rlcompleter.TestRlcompleter.test_namespace @ linux-x86_64 +test.test_rlcompleter.TestRlcompleter.test_property_method_not_called @ linux-x86_64 +test.test_rlcompleter.TestRlcompleter.test_uncreated_attr @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_robotparser.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_robotparser.txt new file mode 100644 index 0000000000..a4258f35d0 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_robotparser.txt @@ -0,0 +1,63 @@ +test.test_robotparser.AnotherInvalidRequestRateTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.AnotherInvalidRequestRateTest.test_good_urls @ linux-x86_64 +test.test_robotparser.AnotherInvalidRequestRateTest.test_site_maps @ linux-x86_64 +test.test_robotparser.CrawlDelayAndCustomAgentTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.CrawlDelayAndCustomAgentTest.test_good_urls @ linux-x86_64 +test.test_robotparser.CrawlDelayAndCustomAgentTest.test_site_maps @ linux-x86_64 +test.test_robotparser.CrawlDelayAndRequestRateTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.CrawlDelayAndRequestRateTest.test_good_urls @ linux-x86_64 +test.test_robotparser.CrawlDelayAndRequestRateTest.test_request_rate @ linux-x86_64 +test.test_robotparser.CrawlDelayAndRequestRateTest.test_site_maps @ linux-x86_64 +test.test_robotparser.DefaultEntryTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.DefaultEntryTest.test_good_urls @ linux-x86_64 +test.test_robotparser.DefaultEntryTest.test_request_rate @ linux-x86_64 +test.test_robotparser.DefaultEntryTest.test_site_maps @ linux-x86_64 +test.test_robotparser.DifferentAgentTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.DifferentAgentTest.test_good_urls @ linux-x86_64 +test.test_robotparser.DifferentAgentTest.test_request_rate @ linux-x86_64 +test.test_robotparser.DifferentAgentTest.test_site_maps @ linux-x86_64 +test.test_robotparser.DisallowQueryStringTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.DisallowQueryStringTest.test_good_urls @ linux-x86_64 +test.test_robotparser.DisallowQueryStringTest.test_site_maps @ linux-x86_64 +test.test_robotparser.EmptyFileTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.EmptyFileTest.test_good_urls @ linux-x86_64 +test.test_robotparser.EmptyFileTest.test_request_rate @ linux-x86_64 +test.test_robotparser.EmptyFileTest.test_site_maps @ linux-x86_64 +test.test_robotparser.EmptyQueryStringTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.EmptyQueryStringTest.test_good_urls @ linux-x86_64 +test.test_robotparser.EmptyQueryStringTest.test_site_maps @ linux-x86_64 +test.test_robotparser.GoogleURLOrderingTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.GoogleURLOrderingTest.test_good_urls @ linux-x86_64 +test.test_robotparser.GoogleURLOrderingTest.test_site_maps @ linux-x86_64 +test.test_robotparser.InvalidCrawlDelayTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.InvalidCrawlDelayTest.test_good_urls @ linux-x86_64 +test.test_robotparser.InvalidCrawlDelayTest.test_site_maps @ linux-x86_64 +test.test_robotparser.InvalidRequestRateTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.InvalidRequestRateTest.test_good_urls @ linux-x86_64 +test.test_robotparser.InvalidRequestRateTest.test_site_maps @ linux-x86_64 +test.test_robotparser.NetworkTestCase.test_basic @ linux-x86_64 +test.test_robotparser.NetworkTestCase.test_can_fetch @ linux-x86_64 +test.test_robotparser.NetworkTestCase.test_read_404 @ linux-x86_64 +test.test_robotparser.PasswordProtectedSiteTestCase.testPasswordProtectedSite @ linux-x86_64 +test.test_robotparser.RejectAllRobotsTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.RejectAllRobotsTest.test_good_urls @ linux-x86_64 +test.test_robotparser.RejectAllRobotsTest.test_site_maps @ linux-x86_64 +test.test_robotparser.SitemapTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.SitemapTest.test_good_urls @ linux-x86_64 +test.test_robotparser.SitemapTest.test_site_maps @ linux-x86_64 +test.test_robotparser.StringFormattingTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.StringFormattingTest.test_good_urls @ linux-x86_64 +test.test_robotparser.StringFormattingTest.test_site_maps @ linux-x86_64 +test.test_robotparser.StringFormattingTest.test_string_formatting @ linux-x86_64 +test.test_robotparser.UseFirstUserAgentWildcardTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.UseFirstUserAgentWildcardTest.test_good_urls @ linux-x86_64 +test.test_robotparser.UseFirstUserAgentWildcardTest.test_site_maps @ linux-x86_64 +test.test_robotparser.UserAgentGoogleMobileTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.UserAgentGoogleMobileTest.test_good_urls @ linux-x86_64 +test.test_robotparser.UserAgentGoogleMobileTest.test_site_maps @ linux-x86_64 +test.test_robotparser.UserAgentOrderingTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.UserAgentOrderingTest.test_good_urls @ linux-x86_64 +test.test_robotparser.UserAgentOrderingTest.test_site_maps @ linux-x86_64 +test.test_robotparser.UserAgentWildcardTest.test_bad_urls @ linux-x86_64 +test.test_robotparser.UserAgentWildcardTest.test_good_urls @ linux-x86_64 +test.test_robotparser.UserAgentWildcardTest.test_site_maps @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_runpy.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_runpy.txt new file mode 100644 index 0000000000..c349484e35 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_runpy.txt @@ -0,0 +1,31 @@ +test.test_runpy.ExecutionLayerTestCase.test_run_code @ linux-x86_64 +test.test_runpy.ExecutionLayerTestCase.test_run_module_code @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_explicit_relative_import @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_invalid_names @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_library_module @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_main_relative_import @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_package_imported_no_warning @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_pkgutil_walk_packages @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_run_module @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_run_module_alter_sys @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_run_module_in_namespace_package @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_run_name @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_run_namespace_package @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_run_namespace_package_in_namespace_package @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_run_package @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_run_package_alter_sys @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_run_package_in_namespace_package @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_run_package_init_exceptions @ linux-x86_64 +test.test_runpy.RunModuleTestCase.test_submodule_imported_warning @ linux-x86_64 +test.test_runpy.RunPathTestCase.test_basic_script @ linux-x86_64 +test.test_runpy.RunPathTestCase.test_basic_script_no_suffix @ linux-x86_64 +test.test_runpy.RunPathTestCase.test_basic_script_with_path_object @ linux-x86_64 +test.test_runpy.RunPathTestCase.test_directory @ linux-x86_64 +test.test_runpy.RunPathTestCase.test_directory_compiled @ linux-x86_64 +test.test_runpy.RunPathTestCase.test_directory_error @ linux-x86_64 +test.test_runpy.RunPathTestCase.test_encoding @ linux-x86_64 +test.test_runpy.RunPathTestCase.test_main_recursion_error @ linux-x86_64 +test.test_runpy.RunPathTestCase.test_script_compiled @ linux-x86_64 +test.test_runpy.RunPathTestCase.test_zipfile @ linux-x86_64 +test.test_runpy.RunPathTestCase.test_zipfile_compiled @ linux-x86_64 +test.test_runpy.RunPathTestCase.test_zipfile_error @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sax.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sax.txt new file mode 100644 index 0000000000..771246e9aa --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sax.txt @@ -0,0 +1,175 @@ +test.test_sax.BytesXmlgenTest.test_1463026_1 @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_1463026_1_empty @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_1463026_2 @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_1463026_2_empty @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_1463026_3 @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_1463026_3_empty @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_5027_1 @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_5027_2 @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_no_close_file @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_xmlgen_attr_escape @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_xmlgen_basic @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_xmlgen_basic_empty @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_xmlgen_content @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_xmlgen_content_empty @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_xmlgen_content_escape @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_xmlgen_fragment @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_xmlgen_ignorable @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_xmlgen_ignorable_empty @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_xmlgen_ns @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_xmlgen_ns_empty @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_xmlgen_pi @ linux-x86_64 +test.test_sax.BytesXmlgenTest.test_xmlgen_unencodable @ linux-x86_64 +test.test_sax.CDATAHandlerTest.test_handlers @ linux-x86_64 +test.test_sax.ErrorReportingTest.test_expat_incomplete @ linux-x86_64 +test.test_sax.ErrorReportingTest.test_expat_inpsource_location @ linux-x86_64 +test.test_sax.ErrorReportingTest.test_sax_parse_exception_str @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_attrs_empty @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_attrs_wattr @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_binary_file @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_binary_file_bytes_name @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_binary_file_int_name @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_binary_file_nonascii @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_dtdhandler @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_entityresolver_default @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_entityresolver_enabled @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_external_dtd_default @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_external_dtd_enabled @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_incremental @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_incremental_reset @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_inpsource_byte_stream @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_inpsource_character_stream @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_inpsource_filename @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_inpsource_sysid @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_inpsource_sysid_nonascii @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_locator_noinfo @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_locator_withinfo @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_locator_withinfo_nonascii @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_nsattrs_empty @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_nsattrs_wattr @ linux-x86_64 +test.test_sax.ExpatReaderTest.test_expat_text_file @ linux-x86_64 +test.test_sax.LexicalHandlerTest.test_handlers @ linux-x86_64 +test.test_sax.MakeParserTest.test_make_parser2 @ linux-x86_64 +test.test_sax.MakeParserTest.test_make_parser3 @ linux-x86_64 +test.test_sax.MakeParserTest.test_make_parser4 @ linux-x86_64 +test.test_sax.MakeParserTest.test_make_parser5 @ linux-x86_64 +test.test_sax.ParseTest.test_parseString_text @ linux-x86_64 +test.test_sax.ParseTest.test_parse_close_source @ linux-x86_64 +test.test_sax.ParseTest.test_parse_path_object @ linux-x86_64 +test.test_sax.PrepareInputSourceTest.test_binary_file @ linux-x86_64 +test.test_sax.PrepareInputSourceTest.test_byte_stream @ linux-x86_64 +test.test_sax.PrepareInputSourceTest.test_character_stream @ linux-x86_64 +test.test_sax.PrepareInputSourceTest.test_path_objects @ linux-x86_64 +test.test_sax.PrepareInputSourceTest.test_string @ linux-x86_64 +test.test_sax.PrepareInputSourceTest.test_system_id @ linux-x86_64 +test.test_sax.PrepareInputSourceTest.test_text_file @ linux-x86_64 +test.test_sax.SaxutilsTest.test_double_quoteattr @ linux-x86_64 +test.test_sax.SaxutilsTest.test_escape_all @ linux-x86_64 +test.test_sax.SaxutilsTest.test_escape_basic @ linux-x86_64 +test.test_sax.SaxutilsTest.test_escape_extra @ linux-x86_64 +test.test_sax.SaxutilsTest.test_make_parser @ linux-x86_64 +test.test_sax.SaxutilsTest.test_quoteattr_basic @ linux-x86_64 +test.test_sax.SaxutilsTest.test_single_double_quoteattr @ linux-x86_64 +test.test_sax.SaxutilsTest.test_single_quoteattr @ linux-x86_64 +test.test_sax.SaxutilsTest.test_unescape_all @ linux-x86_64 +test.test_sax.SaxutilsTest.test_unescape_amp_extra @ linux-x86_64 +test.test_sax.SaxutilsTest.test_unescape_basic @ linux-x86_64 +test.test_sax.SaxutilsTest.test_unescape_extra @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_1463026_1 @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_1463026_1_empty @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_1463026_2 @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_1463026_2_empty @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_1463026_3 @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_1463026_3_empty @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_5027_1 @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_5027_2 @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_no_close_file @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_xmlgen_attr_escape @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_xmlgen_basic @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_xmlgen_basic_empty @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_xmlgen_content @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_xmlgen_content_empty @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_xmlgen_content_escape @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_xmlgen_encoding @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_xmlgen_encoding_bytes @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_xmlgen_fragment @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_xmlgen_ignorable @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_xmlgen_ignorable_empty @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_xmlgen_ns @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_xmlgen_ns_empty @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_xmlgen_pi @ linux-x86_64 +test.test_sax.StreamReaderWriterXmlgenTest.test_xmlgen_unencodable @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_1463026_1 @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_1463026_1_empty @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_1463026_2 @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_1463026_2_empty @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_1463026_3 @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_1463026_3_empty @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_5027_1 @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_5027_2 @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_no_close_file @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_xmlgen_attr_escape @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_xmlgen_basic @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_xmlgen_basic_empty @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_xmlgen_content @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_xmlgen_content_empty @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_xmlgen_content_escape @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_xmlgen_encoding @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_xmlgen_encoding_bytes @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_xmlgen_fragment @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_xmlgen_ignorable @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_xmlgen_ignorable_empty @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_xmlgen_ns @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_xmlgen_ns_empty @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_xmlgen_pi @ linux-x86_64 +test.test_sax.StreamWriterXmlgenTest.test_xmlgen_unencodable @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_1463026_1 @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_1463026_1_empty @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_1463026_2 @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_1463026_2_empty @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_1463026_3 @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_1463026_3_empty @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_5027_1 @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_5027_2 @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_no_close_file @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_xmlgen_attr_escape @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_xmlgen_basic @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_xmlgen_basic_empty @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_xmlgen_content @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_xmlgen_content_empty @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_xmlgen_content_escape @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_xmlgen_encoding @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_xmlgen_encoding_bytes @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_xmlgen_fragment @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_xmlgen_ignorable @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_xmlgen_ignorable_empty @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_xmlgen_ns @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_xmlgen_ns_empty @ linux-x86_64 +test.test_sax.StringXmlgenTest.test_xmlgen_pi @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_1463026_1 @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_1463026_1_empty @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_1463026_2 @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_1463026_2_empty @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_1463026_3 @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_1463026_3_empty @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_5027_1 @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_5027_2 @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_no_close_file @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_xmlgen_attr_escape @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_xmlgen_basic @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_xmlgen_basic_empty @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_xmlgen_content @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_xmlgen_content_empty @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_xmlgen_content_escape @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_xmlgen_fragment @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_xmlgen_ignorable @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_xmlgen_ignorable_empty @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_xmlgen_ns @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_xmlgen_ns_empty @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_xmlgen_pi @ linux-x86_64 +test.test_sax.WriterXmlgenTest.test_xmlgen_unencodable @ linux-x86_64 +test.test_sax.XMLFilterBaseTest.test_filter_basic @ linux-x86_64 +test.test_sax.XmlReaderTest.test_attrs_empty @ linux-x86_64 +test.test_sax.XmlReaderTest.test_attrs_wattr @ linux-x86_64 +test.test_sax.XmlReaderTest.test_nsattrs_empty @ linux-x86_64 +test.test_sax.XmlReaderTest.test_nsattrs_wattr @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sched.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sched.txt new file mode 100644 index 0000000000..f448880c0e --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sched.txt @@ -0,0 +1,11 @@ +test.test_sched.TestCase.test_args_kwargs @ linux-x86_64 +test.test_sched.TestCase.test_cancel @ linux-x86_64 +test.test_sched.TestCase.test_cancel_concurrent @ linux-x86_64 +test.test_sched.TestCase.test_cancel_correct_event @ linux-x86_64 +test.test_sched.TestCase.test_empty @ linux-x86_64 +test.test_sched.TestCase.test_enter @ linux-x86_64 +test.test_sched.TestCase.test_enter_concurrent @ linux-x86_64 +test.test_sched.TestCase.test_enterabs @ linux-x86_64 +test.test_sched.TestCase.test_priority @ linux-x86_64 +test.test_sched.TestCase.test_queue @ linux-x86_64 +test.test_sched.TestCase.test_run_non_blocking @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_scope.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_scope.txt new file mode 100644 index 0000000000..bade6f95c8 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_scope.txt @@ -0,0 +1,36 @@ +test.test_scope.ScopeTests.testBoundAndFree @ linux-x86_64 +test.test_scope.ScopeTests.testCellIsArgAndEscapes @ linux-x86_64 +test.test_scope.ScopeTests.testCellIsKwonlyArg @ linux-x86_64 +test.test_scope.ScopeTests.testCellIsLocalAndEscapes @ linux-x86_64 +test.test_scope.ScopeTests.testClassAndGlobal @ linux-x86_64 +test.test_scope.ScopeTests.testClassNamespaceOverridesClosure @ linux-x86_64 +test.test_scope.ScopeTests.testComplexDefinitions @ linux-x86_64 +test.test_scope.ScopeTests.testEvalExecFreeVars @ linux-x86_64 +test.test_scope.ScopeTests.testEvalFreeVars @ linux-x86_64 +test.test_scope.ScopeTests.testExtraNesting @ linux-x86_64 +test.test_scope.ScopeTests.testFreeVarInMethod @ linux-x86_64 +test.test_scope.ScopeTests.testFreeingCell @ linux-x86_64 +test.test_scope.ScopeTests.testGlobalInParallelNestedFunctions @ linux-x86_64 +test.test_scope.ScopeTests.testLambdas @ linux-x86_64 +test.test_scope.ScopeTests.testListCompLocalVars @ linux-x86_64 +test.test_scope.ScopeTests.testLocalsClass @ linux-x86_64 +test.test_scope.ScopeTests.testLocalsFunction @ linux-x86_64 +test.test_scope.ScopeTests.testMixedFreevarsAndCellvars @ linux-x86_64 +test.test_scope.ScopeTests.testNearestEnclosingScope @ linux-x86_64 +test.test_scope.ScopeTests.testNestedNonLocal @ linux-x86_64 +test.test_scope.ScopeTests.testNestingGlobalNoFree @ linux-x86_64 +test.test_scope.ScopeTests.testNestingPlusFreeRefToGlobal @ linux-x86_64 +test.test_scope.ScopeTests.testNestingThroughClass @ linux-x86_64 +test.test_scope.ScopeTests.testNonLocalClass @ linux-x86_64 +test.test_scope.ScopeTests.testNonLocalFunction @ linux-x86_64 +test.test_scope.ScopeTests.testNonLocalGenerator @ linux-x86_64 +test.test_scope.ScopeTests.testNonLocalMethod @ linux-x86_64 +test.test_scope.ScopeTests.testRecursion @ linux-x86_64 +test.test_scope.ScopeTests.testScopeOfGlobalStmt @ linux-x86_64 +test.test_scope.ScopeTests.testSimpleAndRebinding @ linux-x86_64 +test.test_scope.ScopeTests.testSimpleNesting @ linux-x86_64 +test.test_scope.ScopeTests.testTopIsNotSignificant @ linux-x86_64 +test.test_scope.ScopeTests.testUnboundLocal @ linux-x86_64 +test.test_scope.ScopeTests.testUnboundLocal_AfterDel @ linux-x86_64 +test.test_scope.ScopeTests.testUnboundLocal_AugAssign @ linux-x86_64 +test.test_scope.ScopeTests.testUnoptimizedNamespaces @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_script_helper.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_script_helper.txt new file mode 100644 index 0000000000..31af69e0f5 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_script_helper.txt @@ -0,0 +1,10 @@ +test.test_script_helper.TestScriptHelper.test_assert_python_failure @ linux-x86_64 +test.test_script_helper.TestScriptHelper.test_assert_python_failure_raises @ linux-x86_64 +test.test_script_helper.TestScriptHelper.test_assert_python_isolated_when_env_not_required @ linux-x86_64 +test.test_script_helper.TestScriptHelper.test_assert_python_not_isolated_when_env_is_required @ linux-x86_64 +test.test_script_helper.TestScriptHelper.test_assert_python_ok @ linux-x86_64 +test.test_script_helper.TestScriptHelper.test_assert_python_ok_raises @ linux-x86_64 +test.test_script_helper.TestScriptHelperEnvironment.test_interpreter_requires_environment_details @ linux-x86_64 +test.test_script_helper.TestScriptHelperEnvironment.test_interpreter_requires_environment_false @ linux-x86_64 +test.test_script_helper.TestScriptHelperEnvironment.test_interpreter_requires_environment_true @ linux-x86_64 +test.test_script_helper.TestScriptHelperEnvironment.test_interpreter_requires_environment_with_pythonhome @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_secrets.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_secrets.txt new file mode 100644 index 0000000000..b10c80f1b9 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_secrets.txt @@ -0,0 +1,11 @@ +test.test_secrets.Compare_Digest_Tests.test_bad_types @ linux-x86_64 +test.test_secrets.Compare_Digest_Tests.test_bool @ linux-x86_64 +test.test_secrets.Compare_Digest_Tests.test_equal @ linux-x86_64 +test.test_secrets.Compare_Digest_Tests.test_unequal @ linux-x86_64 +test.test_secrets.Random_Tests.test_choice @ linux-x86_64 +test.test_secrets.Random_Tests.test_randbelow @ linux-x86_64 +test.test_secrets.Random_Tests.test_randbits @ linux-x86_64 +test.test_secrets.Token_Tests.test_token_bytes @ linux-x86_64 +test.test_secrets.Token_Tests.test_token_defaults @ linux-x86_64 +test.test_secrets.Token_Tests.test_token_hex @ linux-x86_64 +test.test_secrets.Token_Tests.test_token_urlsafe @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_select.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_select.txt new file mode 100644 index 0000000000..878072b3cb --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_select.txt @@ -0,0 +1,4 @@ +test.test_select.SelectTestCase.test_errno @ linux-x86_64 +test.test_select.SelectTestCase.test_error_conditions @ linux-x86_64 +test.test_select.SelectTestCase.test_returned_list_identity @ linux-x86_64 +test.test_select.SelectTestCase.test_select_mutated @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_selectors.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_selectors.txt new file mode 100644 index 0000000000..52f57b21e0 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_selectors.txt @@ -0,0 +1,34 @@ +test.test_selectors.DefaultSelectorTestCase.test_close @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_context_manager @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_empty_select @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_fileno @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_get_key @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_get_map @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_modify @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_register @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_select @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_select_interrupt_noraise @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_select_read_write @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_selector @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_timeout @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_unregister @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_unregister_after_fd_close @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_unregister_after_fd_close_and_reuse @ linux-x86_64 +test.test_selectors.DefaultSelectorTestCase.test_unregister_after_socket_close @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_close @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_context_manager @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_empty_select @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_fileno @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_get_key @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_get_map @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_modify @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_register @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_select @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_select_interrupt_noraise @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_select_read_write @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_selector @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_timeout @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_unregister @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_unregister_after_fd_close @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_unregister_after_fd_close_and_reuse @ linux-x86_64 +test.test_selectors.SelectSelectorTestCase.test_unregister_after_socket_close @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_set.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_set.txt new file mode 100644 index 0000000000..94d682776b --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_set.txt @@ -0,0 +1,486 @@ +test.test_set.TestBasicOpsBytes.test_copy @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_empty_difference @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_empty_difference_rev @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_empty_intersection @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_empty_isdisjoint @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_empty_symmetric_difference @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_empty_union @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_equivalent_equality @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_intersection_empty @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_isdisjoint_empty @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_issue_37219 @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_iteration @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_length @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_pickling @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_repr @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_self_difference @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_self_equality @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_self_intersection @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_self_isdisjoint @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_self_symmetric_difference @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_self_union @ linux-x86_64 +test.test_set.TestBasicOpsBytes.test_union_empty @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_copy @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_empty_difference @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_empty_difference_rev @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_empty_intersection @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_empty_isdisjoint @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_empty_symmetric_difference @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_empty_union @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_equivalent_equality @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_intersection_empty @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_isdisjoint_empty @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_issue_37219 @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_iteration @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_length @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_pickling @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_repr @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_self_difference @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_self_equality @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_self_intersection @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_self_isdisjoint @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_self_symmetric_difference @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_self_union @ linux-x86_64 +test.test_set.TestBasicOpsEmpty.test_union_empty @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_copy @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_empty_difference @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_empty_difference_rev @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_empty_intersection @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_empty_isdisjoint @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_empty_symmetric_difference @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_empty_union @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_equivalent_equality @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_intersection_empty @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_isdisjoint_empty @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_issue_37219 @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_iteration @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_length @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_pickling @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_repr @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_self_difference @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_self_equality @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_self_intersection @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_self_isdisjoint @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_self_symmetric_difference @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_self_union @ linux-x86_64 +test.test_set.TestBasicOpsMixedStringBytes.test_union_empty @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_copy @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_empty_difference @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_empty_difference_rev @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_empty_intersection @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_empty_isdisjoint @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_empty_symmetric_difference @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_empty_union @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_equivalent_equality @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_in @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_intersection_empty @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_isdisjoint_empty @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_issue_37219 @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_iteration @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_length @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_not_in @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_pickling @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_repr @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_self_difference @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_self_equality @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_self_intersection @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_self_isdisjoint @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_self_symmetric_difference @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_self_union @ linux-x86_64 +test.test_set.TestBasicOpsSingleton.test_union_empty @ linux-x86_64 +test.test_set.TestBasicOpsString.test_copy @ linux-x86_64 +test.test_set.TestBasicOpsString.test_empty_difference @ linux-x86_64 +test.test_set.TestBasicOpsString.test_empty_difference_rev @ linux-x86_64 +test.test_set.TestBasicOpsString.test_empty_intersection @ linux-x86_64 +test.test_set.TestBasicOpsString.test_empty_isdisjoint @ linux-x86_64 +test.test_set.TestBasicOpsString.test_empty_symmetric_difference @ linux-x86_64 +test.test_set.TestBasicOpsString.test_empty_union @ linux-x86_64 +test.test_set.TestBasicOpsString.test_equivalent_equality @ linux-x86_64 +test.test_set.TestBasicOpsString.test_intersection_empty @ linux-x86_64 +test.test_set.TestBasicOpsString.test_isdisjoint_empty @ linux-x86_64 +test.test_set.TestBasicOpsString.test_issue_37219 @ linux-x86_64 +test.test_set.TestBasicOpsString.test_iteration @ linux-x86_64 +test.test_set.TestBasicOpsString.test_length @ linux-x86_64 +test.test_set.TestBasicOpsString.test_pickling @ linux-x86_64 +test.test_set.TestBasicOpsString.test_repr @ linux-x86_64 +test.test_set.TestBasicOpsString.test_self_difference @ linux-x86_64 +test.test_set.TestBasicOpsString.test_self_equality @ linux-x86_64 +test.test_set.TestBasicOpsString.test_self_intersection @ linux-x86_64 +test.test_set.TestBasicOpsString.test_self_isdisjoint @ linux-x86_64 +test.test_set.TestBasicOpsString.test_self_symmetric_difference @ linux-x86_64 +test.test_set.TestBasicOpsString.test_self_union @ linux-x86_64 +test.test_set.TestBasicOpsString.test_union_empty @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_copy @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_empty_difference @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_empty_difference_rev @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_empty_intersection @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_empty_isdisjoint @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_empty_symmetric_difference @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_empty_union @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_equivalent_equality @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_intersection_empty @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_isdisjoint_empty @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_issue_37219 @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_iteration @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_length @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_pickling @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_repr @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_self_difference @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_self_equality @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_self_intersection @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_self_isdisjoint @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_self_symmetric_difference @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_self_union @ linux-x86_64 +test.test_set.TestBasicOpsTriple.test_union_empty @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_copy @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_empty_difference @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_empty_difference_rev @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_empty_intersection @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_empty_isdisjoint @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_empty_symmetric_difference @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_empty_union @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_equivalent_equality @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_in @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_intersection_empty @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_isdisjoint_empty @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_issue_37219 @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_iteration @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_length @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_not_in @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_pickling @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_repr @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_self_difference @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_self_equality @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_self_intersection @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_self_isdisjoint @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_self_symmetric_difference @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_self_union @ linux-x86_64 +test.test_set.TestBasicOpsTuple.test_union_empty @ linux-x86_64 +test.test_set.TestBinaryOps.test_eq @ linux-x86_64 +test.test_set.TestBinaryOps.test_intersection_non_overlap @ linux-x86_64 +test.test_set.TestBinaryOps.test_intersection_overlap @ linux-x86_64 +test.test_set.TestBinaryOps.test_intersection_subset @ linux-x86_64 +test.test_set.TestBinaryOps.test_intersection_superset @ linux-x86_64 +test.test_set.TestBinaryOps.test_isdisjoint_non_overlap @ linux-x86_64 +test.test_set.TestBinaryOps.test_isdisjoint_overlap @ linux-x86_64 +test.test_set.TestBinaryOps.test_isdisjoint_subset @ linux-x86_64 +test.test_set.TestBinaryOps.test_isdisjoint_superset @ linux-x86_64 +test.test_set.TestBinaryOps.test_sym_difference_non_overlap @ linux-x86_64 +test.test_set.TestBinaryOps.test_sym_difference_overlap @ linux-x86_64 +test.test_set.TestBinaryOps.test_sym_difference_subset @ linux-x86_64 +test.test_set.TestBinaryOps.test_sym_difference_superset @ linux-x86_64 +test.test_set.TestBinaryOps.test_union_non_overlap @ linux-x86_64 +test.test_set.TestBinaryOps.test_union_overlap @ linux-x86_64 +test.test_set.TestBinaryOps.test_union_subset @ linux-x86_64 +test.test_set.TestBinaryOps.test_union_superset @ linux-x86_64 +test.test_set.TestCopyingEmpty.test_copy @ linux-x86_64 +test.test_set.TestCopyingEmpty.test_deep_copy @ linux-x86_64 +test.test_set.TestCopyingNested.test_copy @ linux-x86_64 +test.test_set.TestCopyingNested.test_deep_copy @ linux-x86_64 +test.test_set.TestCopyingSingleton.test_copy @ linux-x86_64 +test.test_set.TestCopyingSingleton.test_deep_copy @ linux-x86_64 +test.test_set.TestCopyingTriple.test_copy @ linux-x86_64 +test.test_set.TestCopyingTriple.test_deep_copy @ linux-x86_64 +test.test_set.TestCopyingTuple.test_copy @ linux-x86_64 +test.test_set.TestCopyingTuple.test_deep_copy @ linux-x86_64 +test.test_set.TestExceptionPropagation.test_changingSizeWhileIterating @ linux-x86_64 +test.test_set.TestExceptionPropagation.test_instanceWithException @ linux-x86_64 +test.test_set.TestExceptionPropagation.test_instancesWithoutException @ linux-x86_64 +test.test_set.TestFrozenSet.test_and @ linux-x86_64 +test.test_set.TestFrozenSet.test_badcmp @ linux-x86_64 +test.test_set.TestFrozenSet.test_constructor_identity @ linux-x86_64 +test.test_set.TestFrozenSet.test_contains @ linux-x86_64 +test.test_set.TestFrozenSet.test_copy @ linux-x86_64 +test.test_set.TestFrozenSet.test_cyclical_repr @ linux-x86_64 +test.test_set.TestFrozenSet.test_deepcopy @ linux-x86_64 +test.test_set.TestFrozenSet.test_difference @ linux-x86_64 +test.test_set.TestFrozenSet.test_do_not_rehash_dict_keys @ linux-x86_64 +test.test_set.TestFrozenSet.test_equality @ linux-x86_64 +test.test_set.TestFrozenSet.test_frozen_as_dictkey @ linux-x86_64 +test.test_set.TestFrozenSet.test_gc @ linux-x86_64 +test.test_set.TestFrozenSet.test_hash @ linux-x86_64 +test.test_set.TestFrozenSet.test_hash_caching @ linux-x86_64 +test.test_set.TestFrozenSet.test_hash_effectiveness @ linux-x86_64 +test.test_set.TestFrozenSet.test_init @ linux-x86_64 +test.test_set.TestFrozenSet.test_intersection @ linux-x86_64 +test.test_set.TestFrozenSet.test_isdisjoint @ linux-x86_64 +test.test_set.TestFrozenSet.test_iterator_pickling @ linux-x86_64 +test.test_set.TestFrozenSet.test_len @ linux-x86_64 +test.test_set.TestFrozenSet.test_new_or_init @ linux-x86_64 +test.test_set.TestFrozenSet.test_or @ linux-x86_64 +test.test_set.TestFrozenSet.test_pickling @ linux-x86_64 +test.test_set.TestFrozenSet.test_setOfFrozensets @ linux-x86_64 +test.test_set.TestFrozenSet.test_sub @ linux-x86_64 +test.test_set.TestFrozenSet.test_sub_and_super @ linux-x86_64 +test.test_set.TestFrozenSet.test_subclass_with_custom_hash @ linux-x86_64 +test.test_set.TestFrozenSet.test_symmetric_difference @ linux-x86_64 +test.test_set.TestFrozenSet.test_union @ linux-x86_64 +test.test_set.TestFrozenSet.test_uniquification @ linux-x86_64 +test.test_set.TestFrozenSet.test_xor @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_and @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_badcmp @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_constructor_identity @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_contains @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_copy @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_cyclical_repr @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_deepcopy @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_difference @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_do_not_rehash_dict_keys @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_equality @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_frozen_as_dictkey @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_gc @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_hash @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_hash_caching @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_hash_effectiveness @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_init @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_intersection @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_isdisjoint @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_iterator_pickling @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_len @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_nested_empty_constructor @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_new_or_init @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_or @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_pickling @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_setOfFrozensets @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_singleton_empty_frozenset @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_sub @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_sub_and_super @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_subclass_with_custom_hash @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_symmetric_difference @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_union @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_uniquification @ linux-x86_64 +test.test_set.TestFrozenSetSubclass.test_xor @ linux-x86_64 +test.test_set.TestFrozenSetSubclassWithSlots.test_pickling @ linux-x86_64 +test.test_set.TestGraphs.test_cube @ linux-x86_64 +test.test_set.TestGraphs.test_cuboctahedron @ linux-x86_64 +test.test_set.TestIdentities.test_binopsVsSubsets @ linux-x86_64 +test.test_set.TestIdentities.test_commutativity @ linux-x86_64 +test.test_set.TestIdentities.test_exclusion @ linux-x86_64 +test.test_set.TestIdentities.test_summations @ linux-x86_64 +test.test_set.TestMutate.test_add_absent @ linux-x86_64 +test.test_set.TestMutate.test_add_present @ linux-x86_64 +test.test_set.TestMutate.test_add_until_full @ linux-x86_64 +test.test_set.TestMutate.test_clear @ linux-x86_64 +test.test_set.TestMutate.test_discard_absent @ linux-x86_64 +test.test_set.TestMutate.test_discard_present @ linux-x86_64 +test.test_set.TestMutate.test_pop @ linux-x86_64 +test.test_set.TestMutate.test_remove_absent @ linux-x86_64 +test.test_set.TestMutate.test_remove_present @ linux-x86_64 +test.test_set.TestMutate.test_remove_until_empty @ linux-x86_64 +test.test_set.TestMutate.test_update_empty_tuple @ linux-x86_64 +test.test_set.TestMutate.test_update_unit_tuple_non_overlap @ linux-x86_64 +test.test_set.TestMutate.test_update_unit_tuple_overlap @ linux-x86_64 +test.test_set.TestOnlySetsDict.test_difference @ linux-x86_64 +test.test_set.TestOnlySetsDict.test_difference_update @ linux-x86_64 +test.test_set.TestOnlySetsDict.test_difference_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsDict.test_eq_ne @ linux-x86_64 +test.test_set.TestOnlySetsDict.test_ge_gt_le_lt @ linux-x86_64 +test.test_set.TestOnlySetsDict.test_intersection @ linux-x86_64 +test.test_set.TestOnlySetsDict.test_intersection_update @ linux-x86_64 +test.test_set.TestOnlySetsDict.test_intersection_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsDict.test_sym_difference @ linux-x86_64 +test.test_set.TestOnlySetsDict.test_sym_difference_update @ linux-x86_64 +test.test_set.TestOnlySetsDict.test_sym_difference_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsDict.test_union @ linux-x86_64 +test.test_set.TestOnlySetsDict.test_update @ linux-x86_64 +test.test_set.TestOnlySetsDict.test_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsGenerator.test_difference @ linux-x86_64 +test.test_set.TestOnlySetsGenerator.test_difference_update @ linux-x86_64 +test.test_set.TestOnlySetsGenerator.test_difference_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsGenerator.test_eq_ne @ linux-x86_64 +test.test_set.TestOnlySetsGenerator.test_ge_gt_le_lt @ linux-x86_64 +test.test_set.TestOnlySetsGenerator.test_intersection @ linux-x86_64 +test.test_set.TestOnlySetsGenerator.test_intersection_update @ linux-x86_64 +test.test_set.TestOnlySetsGenerator.test_intersection_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsGenerator.test_sym_difference @ linux-x86_64 +test.test_set.TestOnlySetsGenerator.test_sym_difference_update @ linux-x86_64 +test.test_set.TestOnlySetsGenerator.test_sym_difference_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsGenerator.test_union @ linux-x86_64 +test.test_set.TestOnlySetsGenerator.test_update @ linux-x86_64 +test.test_set.TestOnlySetsGenerator.test_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsNumeric.test_difference @ linux-x86_64 +test.test_set.TestOnlySetsNumeric.test_difference_update @ linux-x86_64 +test.test_set.TestOnlySetsNumeric.test_difference_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsNumeric.test_eq_ne @ linux-x86_64 +test.test_set.TestOnlySetsNumeric.test_ge_gt_le_lt @ linux-x86_64 +test.test_set.TestOnlySetsNumeric.test_intersection @ linux-x86_64 +test.test_set.TestOnlySetsNumeric.test_intersection_update @ linux-x86_64 +test.test_set.TestOnlySetsNumeric.test_intersection_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsNumeric.test_sym_difference @ linux-x86_64 +test.test_set.TestOnlySetsNumeric.test_sym_difference_update @ linux-x86_64 +test.test_set.TestOnlySetsNumeric.test_sym_difference_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsNumeric.test_union @ linux-x86_64 +test.test_set.TestOnlySetsNumeric.test_update @ linux-x86_64 +test.test_set.TestOnlySetsNumeric.test_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsOperator.test_difference @ linux-x86_64 +test.test_set.TestOnlySetsOperator.test_difference_update @ linux-x86_64 +test.test_set.TestOnlySetsOperator.test_difference_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsOperator.test_eq_ne @ linux-x86_64 +test.test_set.TestOnlySetsOperator.test_ge_gt_le_lt @ linux-x86_64 +test.test_set.TestOnlySetsOperator.test_intersection @ linux-x86_64 +test.test_set.TestOnlySetsOperator.test_intersection_update @ linux-x86_64 +test.test_set.TestOnlySetsOperator.test_intersection_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsOperator.test_sym_difference @ linux-x86_64 +test.test_set.TestOnlySetsOperator.test_sym_difference_update @ linux-x86_64 +test.test_set.TestOnlySetsOperator.test_sym_difference_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsOperator.test_union @ linux-x86_64 +test.test_set.TestOnlySetsOperator.test_update @ linux-x86_64 +test.test_set.TestOnlySetsOperator.test_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsString.test_difference @ linux-x86_64 +test.test_set.TestOnlySetsString.test_difference_update @ linux-x86_64 +test.test_set.TestOnlySetsString.test_difference_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsString.test_eq_ne @ linux-x86_64 +test.test_set.TestOnlySetsString.test_ge_gt_le_lt @ linux-x86_64 +test.test_set.TestOnlySetsString.test_intersection @ linux-x86_64 +test.test_set.TestOnlySetsString.test_intersection_update @ linux-x86_64 +test.test_set.TestOnlySetsString.test_intersection_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsString.test_sym_difference @ linux-x86_64 +test.test_set.TestOnlySetsString.test_sym_difference_update @ linux-x86_64 +test.test_set.TestOnlySetsString.test_sym_difference_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsString.test_union @ linux-x86_64 +test.test_set.TestOnlySetsString.test_update @ linux-x86_64 +test.test_set.TestOnlySetsString.test_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsTuple.test_difference @ linux-x86_64 +test.test_set.TestOnlySetsTuple.test_difference_update @ linux-x86_64 +test.test_set.TestOnlySetsTuple.test_difference_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsTuple.test_eq_ne @ linux-x86_64 +test.test_set.TestOnlySetsTuple.test_ge_gt_le_lt @ linux-x86_64 +test.test_set.TestOnlySetsTuple.test_intersection @ linux-x86_64 +test.test_set.TestOnlySetsTuple.test_intersection_update @ linux-x86_64 +test.test_set.TestOnlySetsTuple.test_intersection_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsTuple.test_sym_difference @ linux-x86_64 +test.test_set.TestOnlySetsTuple.test_sym_difference_update @ linux-x86_64 +test.test_set.TestOnlySetsTuple.test_sym_difference_update_operator @ linux-x86_64 +test.test_set.TestOnlySetsTuple.test_union @ linux-x86_64 +test.test_set.TestOnlySetsTuple.test_update @ linux-x86_64 +test.test_set.TestOnlySetsTuple.test_update_operator @ linux-x86_64 +test.test_set.TestSet.test_add @ linux-x86_64 +test.test_set.TestSet.test_and @ linux-x86_64 +test.test_set.TestSet.test_badcmp @ linux-x86_64 +test.test_set.TestSet.test_clear @ linux-x86_64 +test.test_set.TestSet.test_constructor_identity @ linux-x86_64 +test.test_set.TestSet.test_contains @ linux-x86_64 +test.test_set.TestSet.test_copy @ linux-x86_64 +test.test_set.TestSet.test_cyclical_repr @ linux-x86_64 +test.test_set.TestSet.test_deepcopy @ linux-x86_64 +test.test_set.TestSet.test_difference @ linux-x86_64 +test.test_set.TestSet.test_difference_update @ linux-x86_64 +test.test_set.TestSet.test_discard @ linux-x86_64 +test.test_set.TestSet.test_do_not_rehash_dict_keys @ linux-x86_64 +test.test_set.TestSet.test_equality @ linux-x86_64 +test.test_set.TestSet.test_gc @ linux-x86_64 +test.test_set.TestSet.test_hash @ linux-x86_64 +test.test_set.TestSet.test_iand @ linux-x86_64 +test.test_set.TestSet.test_init @ linux-x86_64 +test.test_set.TestSet.test_inplace_on_self @ linux-x86_64 +test.test_set.TestSet.test_intersection @ linux-x86_64 +test.test_set.TestSet.test_intersection_update @ linux-x86_64 +test.test_set.TestSet.test_ior @ linux-x86_64 +test.test_set.TestSet.test_isdisjoint @ linux-x86_64 +test.test_set.TestSet.test_isub @ linux-x86_64 +test.test_set.TestSet.test_iterator_pickling @ linux-x86_64 +test.test_set.TestSet.test_ixor @ linux-x86_64 +test.test_set.TestSet.test_len @ linux-x86_64 +test.test_set.TestSet.test_new_or_init @ linux-x86_64 +test.test_set.TestSet.test_or @ linux-x86_64 +test.test_set.TestSet.test_pickling @ linux-x86_64 +test.test_set.TestSet.test_pop @ linux-x86_64 +test.test_set.TestSet.test_remove @ linux-x86_64 +test.test_set.TestSet.test_remove_keyerror_set @ linux-x86_64 +test.test_set.TestSet.test_remove_keyerror_unpacking @ linux-x86_64 +test.test_set.TestSet.test_rich_compare @ linux-x86_64 +test.test_set.TestSet.test_setOfFrozensets @ linux-x86_64 +test.test_set.TestSet.test_set_literal @ linux-x86_64 +test.test_set.TestSet.test_set_literal_evaluation_order @ linux-x86_64 +test.test_set.TestSet.test_set_literal_insertion_order @ linux-x86_64 +test.test_set.TestSet.test_sub @ linux-x86_64 +test.test_set.TestSet.test_sub_and_super @ linux-x86_64 +test.test_set.TestSet.test_subclass_with_custom_hash @ linux-x86_64 +test.test_set.TestSet.test_symmetric_difference @ linux-x86_64 +test.test_set.TestSet.test_symmetric_difference_update @ linux-x86_64 +test.test_set.TestSet.test_union @ linux-x86_64 +test.test_set.TestSet.test_uniquification @ linux-x86_64 +test.test_set.TestSet.test_update @ linux-x86_64 +test.test_set.TestSet.test_xor @ linux-x86_64 +test.test_set.TestSetOfSets.test_constructor @ linux-x86_64 +test.test_set.TestSetSubclass.test_add @ linux-x86_64 +test.test_set.TestSetSubclass.test_and @ linux-x86_64 +test.test_set.TestSetSubclass.test_badcmp @ linux-x86_64 +test.test_set.TestSetSubclass.test_clear @ linux-x86_64 +test.test_set.TestSetSubclass.test_constructor_identity @ linux-x86_64 +test.test_set.TestSetSubclass.test_contains @ linux-x86_64 +test.test_set.TestSetSubclass.test_copy @ linux-x86_64 +test.test_set.TestSetSubclass.test_cyclical_repr @ linux-x86_64 +test.test_set.TestSetSubclass.test_deepcopy @ linux-x86_64 +test.test_set.TestSetSubclass.test_difference @ linux-x86_64 +test.test_set.TestSetSubclass.test_difference_update @ linux-x86_64 +test.test_set.TestSetSubclass.test_discard @ linux-x86_64 +test.test_set.TestSetSubclass.test_do_not_rehash_dict_keys @ linux-x86_64 +test.test_set.TestSetSubclass.test_equality @ linux-x86_64 +test.test_set.TestSetSubclass.test_gc @ linux-x86_64 +test.test_set.TestSetSubclass.test_hash @ linux-x86_64 +test.test_set.TestSetSubclass.test_iand @ linux-x86_64 +test.test_set.TestSetSubclass.test_init @ linux-x86_64 +test.test_set.TestSetSubclass.test_inplace_on_self @ linux-x86_64 +test.test_set.TestSetSubclass.test_intersection @ linux-x86_64 +test.test_set.TestSetSubclass.test_intersection_update @ linux-x86_64 +test.test_set.TestSetSubclass.test_ior @ linux-x86_64 +test.test_set.TestSetSubclass.test_isdisjoint @ linux-x86_64 +test.test_set.TestSetSubclass.test_isub @ linux-x86_64 +test.test_set.TestSetSubclass.test_iterator_pickling @ linux-x86_64 +test.test_set.TestSetSubclass.test_ixor @ linux-x86_64 +test.test_set.TestSetSubclass.test_keywords_in_subclass @ linux-x86_64 +test.test_set.TestSetSubclass.test_len @ linux-x86_64 +test.test_set.TestSetSubclass.test_new_or_init @ linux-x86_64 +test.test_set.TestSetSubclass.test_or @ linux-x86_64 +test.test_set.TestSetSubclass.test_pickling @ linux-x86_64 +test.test_set.TestSetSubclass.test_pop @ linux-x86_64 +test.test_set.TestSetSubclass.test_remove @ linux-x86_64 +test.test_set.TestSetSubclass.test_remove_keyerror_set @ linux-x86_64 +test.test_set.TestSetSubclass.test_remove_keyerror_unpacking @ linux-x86_64 +test.test_set.TestSetSubclass.test_rich_compare @ linux-x86_64 +test.test_set.TestSetSubclass.test_setOfFrozensets @ linux-x86_64 +test.test_set.TestSetSubclass.test_set_literal @ linux-x86_64 +test.test_set.TestSetSubclass.test_set_literal_evaluation_order @ linux-x86_64 +test.test_set.TestSetSubclass.test_set_literal_insertion_order @ linux-x86_64 +test.test_set.TestSetSubclass.test_sub @ linux-x86_64 +test.test_set.TestSetSubclass.test_sub_and_super @ linux-x86_64 +test.test_set.TestSetSubclass.test_subclass_with_custom_hash @ linux-x86_64 +test.test_set.TestSetSubclass.test_symmetric_difference @ linux-x86_64 +test.test_set.TestSetSubclass.test_symmetric_difference_update @ linux-x86_64 +test.test_set.TestSetSubclass.test_union @ linux-x86_64 +test.test_set.TestSetSubclass.test_uniquification @ linux-x86_64 +test.test_set.TestSetSubclass.test_update @ linux-x86_64 +test.test_set.TestSetSubclass.test_xor @ linux-x86_64 +test.test_set.TestSetSubclassWithSlots.test_pickling @ linux-x86_64 +test.test_set.TestSubsetEmptyNonEmpty.test_issubset @ linux-x86_64 +test.test_set.TestSubsetEqualEmpty.test_issubset @ linux-x86_64 +test.test_set.TestSubsetEqualNonEmpty.test_issubset @ linux-x86_64 +test.test_set.TestSubsetNonOverlap.test_issubset @ linux-x86_64 +test.test_set.TestSubsetPartial.test_issubset @ linux-x86_64 +test.test_set.TestUpdateOps.test_difference_method_call @ linux-x86_64 +test.test_set.TestUpdateOps.test_difference_non_overlap @ linux-x86_64 +test.test_set.TestUpdateOps.test_difference_overlap @ linux-x86_64 +test.test_set.TestUpdateOps.test_difference_subset @ linux-x86_64 +test.test_set.TestUpdateOps.test_difference_superset @ linux-x86_64 +test.test_set.TestUpdateOps.test_intersection_method_call @ linux-x86_64 +test.test_set.TestUpdateOps.test_intersection_non_overlap @ linux-x86_64 +test.test_set.TestUpdateOps.test_intersection_overlap @ linux-x86_64 +test.test_set.TestUpdateOps.test_intersection_subset @ linux-x86_64 +test.test_set.TestUpdateOps.test_intersection_superset @ linux-x86_64 +test.test_set.TestUpdateOps.test_sym_difference_method_call @ linux-x86_64 +test.test_set.TestUpdateOps.test_sym_difference_non_overlap @ linux-x86_64 +test.test_set.TestUpdateOps.test_sym_difference_overlap @ linux-x86_64 +test.test_set.TestUpdateOps.test_sym_difference_subset @ linux-x86_64 +test.test_set.TestUpdateOps.test_sym_difference_superset @ linux-x86_64 +test.test_set.TestUpdateOps.test_union_method_call @ linux-x86_64 +test.test_set.TestUpdateOps.test_union_non_overlap @ linux-x86_64 +test.test_set.TestUpdateOps.test_union_overlap @ linux-x86_64 +test.test_set.TestUpdateOps.test_union_subset @ linux-x86_64 +test.test_set.TestUpdateOps.test_union_superset @ linux-x86_64 +test.test_set.TestVariousIteratorArgs.test_constructor @ linux-x86_64 +test.test_set.TestVariousIteratorArgs.test_inline_methods @ linux-x86_64 +test.test_set.TestVariousIteratorArgs.test_inplace_methods @ linux-x86_64 +test.test_set.TestWeirdBugs.test_8420_set_merge @ linux-x86_64 +test.test_set.TestWeirdBugs.test_iter_and_mutate @ linux-x86_64 +test.test_set.TestWeirdBugs.test_merge_and_mutate @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_setcomps.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_setcomps.txt new file mode 100644 index 0000000000..f8ef442fba --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_setcomps.txt @@ -0,0 +1 @@ +DocTestCase.test.test_setcomps.__test__.doctests @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_shelve.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_shelve.txt new file mode 100644 index 0000000000..78ac459080 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_shelve.txt @@ -0,0 +1,182 @@ +test.test_shelve.TestCase.test_ascii_file_shelf @ linux-x86_64 +test.test_shelve.TestCase.test_binary_file_shelf @ linux-x86_64 +test.test_shelve.TestCase.test_bytes_path_file_shelf @ linux-x86_64 +test.test_shelve.TestCase.test_close @ linux-x86_64 +test.test_shelve.TestCase.test_default_protocol @ linux-x86_64 +test.test_shelve.TestCase.test_in_memory_shelf @ linux-x86_64 +test.test_shelve.TestCase.test_keyencoding @ linux-x86_64 +test.test_shelve.TestCase.test_mutable_entry @ linux-x86_64 +test.test_shelve.TestCase.test_open_template @ linux-x86_64 +test.test_shelve.TestCase.test_pathlib_bytes_path_file_shelf @ linux-x86_64 +test.test_shelve.TestCase.test_pathlib_path_file_shelf @ linux-x86_64 +test.test_shelve.TestCase.test_proto2_file_shelf @ linux-x86_64 +test.test_shelve.TestCase.test_with @ linux-x86_64 +test.test_shelve.TestCase.test_writeback_also_writes_immediately @ linux-x86_64 +test.test_shelve.TestProto0File_dumbShelve.test_bool @ linux-x86_64 +test.test_shelve.TestProto0File_dumbShelve.test_constructor @ linux-x86_64 +test.test_shelve.TestProto0File_dumbShelve.test_get @ linux-x86_64 +test.test_shelve.TestProto0File_dumbShelve.test_getitem @ linux-x86_64 +test.test_shelve.TestProto0File_dumbShelve.test_items @ linux-x86_64 +test.test_shelve.TestProto0File_dumbShelve.test_keys @ linux-x86_64 +test.test_shelve.TestProto0File_dumbShelve.test_len @ linux-x86_64 +test.test_shelve.TestProto0File_dumbShelve.test_pop @ linux-x86_64 +test.test_shelve.TestProto0File_dumbShelve.test_popitem @ linux-x86_64 +test.test_shelve.TestProto0File_dumbShelve.test_read @ linux-x86_64 +test.test_shelve.TestProto0File_dumbShelve.test_setdefault @ linux-x86_64 +test.test_shelve.TestProto0File_dumbShelve.test_update @ linux-x86_64 +test.test_shelve.TestProto0File_dumbShelve.test_values @ linux-x86_64 +test.test_shelve.TestProto0File_dumbShelve.test_write @ linux-x86_64 +test.test_shelve.TestProto0MemShelve.test_bool @ linux-x86_64 +test.test_shelve.TestProto0MemShelve.test_constructor @ linux-x86_64 +test.test_shelve.TestProto0MemShelve.test_get @ linux-x86_64 +test.test_shelve.TestProto0MemShelve.test_getitem @ linux-x86_64 +test.test_shelve.TestProto0MemShelve.test_items @ linux-x86_64 +test.test_shelve.TestProto0MemShelve.test_keys @ linux-x86_64 +test.test_shelve.TestProto0MemShelve.test_len @ linux-x86_64 +test.test_shelve.TestProto0MemShelve.test_pop @ linux-x86_64 +test.test_shelve.TestProto0MemShelve.test_popitem @ linux-x86_64 +test.test_shelve.TestProto0MemShelve.test_read @ linux-x86_64 +test.test_shelve.TestProto0MemShelve.test_setdefault @ linux-x86_64 +test.test_shelve.TestProto0MemShelve.test_update @ linux-x86_64 +test.test_shelve.TestProto0MemShelve.test_values @ linux-x86_64 +test.test_shelve.TestProto0MemShelve.test_write @ linux-x86_64 +test.test_shelve.TestProto1File_dumbShelve.test_bool @ linux-x86_64 +test.test_shelve.TestProto1File_dumbShelve.test_constructor @ linux-x86_64 +test.test_shelve.TestProto1File_dumbShelve.test_get @ linux-x86_64 +test.test_shelve.TestProto1File_dumbShelve.test_getitem @ linux-x86_64 +test.test_shelve.TestProto1File_dumbShelve.test_items @ linux-x86_64 +test.test_shelve.TestProto1File_dumbShelve.test_keys @ linux-x86_64 +test.test_shelve.TestProto1File_dumbShelve.test_len @ linux-x86_64 +test.test_shelve.TestProto1File_dumbShelve.test_pop @ linux-x86_64 +test.test_shelve.TestProto1File_dumbShelve.test_popitem @ linux-x86_64 +test.test_shelve.TestProto1File_dumbShelve.test_read @ linux-x86_64 +test.test_shelve.TestProto1File_dumbShelve.test_setdefault @ linux-x86_64 +test.test_shelve.TestProto1File_dumbShelve.test_update @ linux-x86_64 +test.test_shelve.TestProto1File_dumbShelve.test_values @ linux-x86_64 +test.test_shelve.TestProto1File_dumbShelve.test_write @ linux-x86_64 +test.test_shelve.TestProto1MemShelve.test_bool @ linux-x86_64 +test.test_shelve.TestProto1MemShelve.test_constructor @ linux-x86_64 +test.test_shelve.TestProto1MemShelve.test_get @ linux-x86_64 +test.test_shelve.TestProto1MemShelve.test_getitem @ linux-x86_64 +test.test_shelve.TestProto1MemShelve.test_items @ linux-x86_64 +test.test_shelve.TestProto1MemShelve.test_keys @ linux-x86_64 +test.test_shelve.TestProto1MemShelve.test_len @ linux-x86_64 +test.test_shelve.TestProto1MemShelve.test_pop @ linux-x86_64 +test.test_shelve.TestProto1MemShelve.test_popitem @ linux-x86_64 +test.test_shelve.TestProto1MemShelve.test_read @ linux-x86_64 +test.test_shelve.TestProto1MemShelve.test_setdefault @ linux-x86_64 +test.test_shelve.TestProto1MemShelve.test_update @ linux-x86_64 +test.test_shelve.TestProto1MemShelve.test_values @ linux-x86_64 +test.test_shelve.TestProto1MemShelve.test_write @ linux-x86_64 +test.test_shelve.TestProto2File_dumbShelve.test_bool @ linux-x86_64 +test.test_shelve.TestProto2File_dumbShelve.test_constructor @ linux-x86_64 +test.test_shelve.TestProto2File_dumbShelve.test_get @ linux-x86_64 +test.test_shelve.TestProto2File_dumbShelve.test_getitem @ linux-x86_64 +test.test_shelve.TestProto2File_dumbShelve.test_items @ linux-x86_64 +test.test_shelve.TestProto2File_dumbShelve.test_keys @ linux-x86_64 +test.test_shelve.TestProto2File_dumbShelve.test_len @ linux-x86_64 +test.test_shelve.TestProto2File_dumbShelve.test_pop @ linux-x86_64 +test.test_shelve.TestProto2File_dumbShelve.test_popitem @ linux-x86_64 +test.test_shelve.TestProto2File_dumbShelve.test_read @ linux-x86_64 +test.test_shelve.TestProto2File_dumbShelve.test_setdefault @ linux-x86_64 +test.test_shelve.TestProto2File_dumbShelve.test_update @ linux-x86_64 +test.test_shelve.TestProto2File_dumbShelve.test_values @ linux-x86_64 +test.test_shelve.TestProto2File_dumbShelve.test_write @ linux-x86_64 +test.test_shelve.TestProto2MemShelve.test_bool @ linux-x86_64 +test.test_shelve.TestProto2MemShelve.test_constructor @ linux-x86_64 +test.test_shelve.TestProto2MemShelve.test_get @ linux-x86_64 +test.test_shelve.TestProto2MemShelve.test_getitem @ linux-x86_64 +test.test_shelve.TestProto2MemShelve.test_items @ linux-x86_64 +test.test_shelve.TestProto2MemShelve.test_keys @ linux-x86_64 +test.test_shelve.TestProto2MemShelve.test_len @ linux-x86_64 +test.test_shelve.TestProto2MemShelve.test_pop @ linux-x86_64 +test.test_shelve.TestProto2MemShelve.test_popitem @ linux-x86_64 +test.test_shelve.TestProto2MemShelve.test_read @ linux-x86_64 +test.test_shelve.TestProto2MemShelve.test_setdefault @ linux-x86_64 +test.test_shelve.TestProto2MemShelve.test_update @ linux-x86_64 +test.test_shelve.TestProto2MemShelve.test_values @ linux-x86_64 +test.test_shelve.TestProto2MemShelve.test_write @ linux-x86_64 +test.test_shelve.TestProto3File_dumbShelve.test_bool @ linux-x86_64 +test.test_shelve.TestProto3File_dumbShelve.test_constructor @ linux-x86_64 +test.test_shelve.TestProto3File_dumbShelve.test_get @ linux-x86_64 +test.test_shelve.TestProto3File_dumbShelve.test_getitem @ linux-x86_64 +test.test_shelve.TestProto3File_dumbShelve.test_items @ linux-x86_64 +test.test_shelve.TestProto3File_dumbShelve.test_keys @ linux-x86_64 +test.test_shelve.TestProto3File_dumbShelve.test_len @ linux-x86_64 +test.test_shelve.TestProto3File_dumbShelve.test_pop @ linux-x86_64 +test.test_shelve.TestProto3File_dumbShelve.test_popitem @ linux-x86_64 +test.test_shelve.TestProto3File_dumbShelve.test_read @ linux-x86_64 +test.test_shelve.TestProto3File_dumbShelve.test_setdefault @ linux-x86_64 +test.test_shelve.TestProto3File_dumbShelve.test_update @ linux-x86_64 +test.test_shelve.TestProto3File_dumbShelve.test_values @ linux-x86_64 +test.test_shelve.TestProto3File_dumbShelve.test_write @ linux-x86_64 +test.test_shelve.TestProto3MemShelve.test_bool @ linux-x86_64 +test.test_shelve.TestProto3MemShelve.test_constructor @ linux-x86_64 +test.test_shelve.TestProto3MemShelve.test_get @ linux-x86_64 +test.test_shelve.TestProto3MemShelve.test_getitem @ linux-x86_64 +test.test_shelve.TestProto3MemShelve.test_items @ linux-x86_64 +test.test_shelve.TestProto3MemShelve.test_keys @ linux-x86_64 +test.test_shelve.TestProto3MemShelve.test_len @ linux-x86_64 +test.test_shelve.TestProto3MemShelve.test_pop @ linux-x86_64 +test.test_shelve.TestProto3MemShelve.test_popitem @ linux-x86_64 +test.test_shelve.TestProto3MemShelve.test_read @ linux-x86_64 +test.test_shelve.TestProto3MemShelve.test_setdefault @ linux-x86_64 +test.test_shelve.TestProto3MemShelve.test_update @ linux-x86_64 +test.test_shelve.TestProto3MemShelve.test_values @ linux-x86_64 +test.test_shelve.TestProto3MemShelve.test_write @ linux-x86_64 +test.test_shelve.TestProto4File_dumbShelve.test_bool @ linux-x86_64 +test.test_shelve.TestProto4File_dumbShelve.test_constructor @ linux-x86_64 +test.test_shelve.TestProto4File_dumbShelve.test_get @ linux-x86_64 +test.test_shelve.TestProto4File_dumbShelve.test_getitem @ linux-x86_64 +test.test_shelve.TestProto4File_dumbShelve.test_items @ linux-x86_64 +test.test_shelve.TestProto4File_dumbShelve.test_keys @ linux-x86_64 +test.test_shelve.TestProto4File_dumbShelve.test_len @ linux-x86_64 +test.test_shelve.TestProto4File_dumbShelve.test_pop @ linux-x86_64 +test.test_shelve.TestProto4File_dumbShelve.test_popitem @ linux-x86_64 +test.test_shelve.TestProto4File_dumbShelve.test_read @ linux-x86_64 +test.test_shelve.TestProto4File_dumbShelve.test_setdefault @ linux-x86_64 +test.test_shelve.TestProto4File_dumbShelve.test_update @ linux-x86_64 +test.test_shelve.TestProto4File_dumbShelve.test_values @ linux-x86_64 +test.test_shelve.TestProto4File_dumbShelve.test_write @ linux-x86_64 +test.test_shelve.TestProto4MemShelve.test_bool @ linux-x86_64 +test.test_shelve.TestProto4MemShelve.test_constructor @ linux-x86_64 +test.test_shelve.TestProto4MemShelve.test_get @ linux-x86_64 +test.test_shelve.TestProto4MemShelve.test_getitem @ linux-x86_64 +test.test_shelve.TestProto4MemShelve.test_items @ linux-x86_64 +test.test_shelve.TestProto4MemShelve.test_keys @ linux-x86_64 +test.test_shelve.TestProto4MemShelve.test_len @ linux-x86_64 +test.test_shelve.TestProto4MemShelve.test_pop @ linux-x86_64 +test.test_shelve.TestProto4MemShelve.test_popitem @ linux-x86_64 +test.test_shelve.TestProto4MemShelve.test_read @ linux-x86_64 +test.test_shelve.TestProto4MemShelve.test_setdefault @ linux-x86_64 +test.test_shelve.TestProto4MemShelve.test_update @ linux-x86_64 +test.test_shelve.TestProto4MemShelve.test_values @ linux-x86_64 +test.test_shelve.TestProto4MemShelve.test_write @ linux-x86_64 +test.test_shelve.TestProto5File_dumbShelve.test_bool @ linux-x86_64 +test.test_shelve.TestProto5File_dumbShelve.test_constructor @ linux-x86_64 +test.test_shelve.TestProto5File_dumbShelve.test_get @ linux-x86_64 +test.test_shelve.TestProto5File_dumbShelve.test_getitem @ linux-x86_64 +test.test_shelve.TestProto5File_dumbShelve.test_items @ linux-x86_64 +test.test_shelve.TestProto5File_dumbShelve.test_keys @ linux-x86_64 +test.test_shelve.TestProto5File_dumbShelve.test_len @ linux-x86_64 +test.test_shelve.TestProto5File_dumbShelve.test_pop @ linux-x86_64 +test.test_shelve.TestProto5File_dumbShelve.test_popitem @ linux-x86_64 +test.test_shelve.TestProto5File_dumbShelve.test_read @ linux-x86_64 +test.test_shelve.TestProto5File_dumbShelve.test_setdefault @ linux-x86_64 +test.test_shelve.TestProto5File_dumbShelve.test_update @ linux-x86_64 +test.test_shelve.TestProto5File_dumbShelve.test_values @ linux-x86_64 +test.test_shelve.TestProto5File_dumbShelve.test_write @ linux-x86_64 +test.test_shelve.TestProto5MemShelve.test_bool @ linux-x86_64 +test.test_shelve.TestProto5MemShelve.test_constructor @ linux-x86_64 +test.test_shelve.TestProto5MemShelve.test_get @ linux-x86_64 +test.test_shelve.TestProto5MemShelve.test_getitem @ linux-x86_64 +test.test_shelve.TestProto5MemShelve.test_items @ linux-x86_64 +test.test_shelve.TestProto5MemShelve.test_keys @ linux-x86_64 +test.test_shelve.TestProto5MemShelve.test_len @ linux-x86_64 +test.test_shelve.TestProto5MemShelve.test_pop @ linux-x86_64 +test.test_shelve.TestProto5MemShelve.test_popitem @ linux-x86_64 +test.test_shelve.TestProto5MemShelve.test_read @ linux-x86_64 +test.test_shelve.TestProto5MemShelve.test_setdefault @ linux-x86_64 +test.test_shelve.TestProto5MemShelve.test_update @ linux-x86_64 +test.test_shelve.TestProto5MemShelve.test_values @ linux-x86_64 +test.test_shelve.TestProto5MemShelve.test_write @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_shlex.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_shlex.txt new file mode 100644 index 0000000000..764d525fd5 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_shlex.txt @@ -0,0 +1,18 @@ +test.test_shlex.ShlexTest.testCompat @ linux-x86_64 +test.test_shlex.ShlexTest.testEmptyStringHandling @ linux-x86_64 +test.test_shlex.ShlexTest.testJoin @ linux-x86_64 +test.test_shlex.ShlexTest.testJoinRoundtrip @ linux-x86_64 +test.test_shlex.ShlexTest.testPunctuationCharsReadOnly @ linux-x86_64 +test.test_shlex.ShlexTest.testPunctuationInWordChars @ linux-x86_64 +test.test_shlex.ShlexTest.testPunctuationWithPosix @ linux-x86_64 +test.test_shlex.ShlexTest.testPunctuationWithWhitespaceSplit @ linux-x86_64 +test.test_shlex.ShlexTest.testQuote @ linux-x86_64 +test.test_shlex.ShlexTest.testSplitNoneDeprecation @ linux-x86_64 +test.test_shlex.ShlexTest.testSplitPosix @ linux-x86_64 +test.test_shlex.ShlexTest.testSyntaxSplitAmpersandAndPipe @ linux-x86_64 +test.test_shlex.ShlexTest.testSyntaxSplitCustom @ linux-x86_64 +test.test_shlex.ShlexTest.testSyntaxSplitParen @ linux-x86_64 +test.test_shlex.ShlexTest.testSyntaxSplitRedirect @ linux-x86_64 +test.test_shlex.ShlexTest.testSyntaxSplitSemicolon @ linux-x86_64 +test.test_shlex.ShlexTest.testTokenTypes @ linux-x86_64 +test.test_shlex.ShlexTest.testUnicodeHandling @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_shutil.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_shutil.txt new file mode 100644 index 0000000000..a3f4758b9d --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_shutil.txt @@ -0,0 +1,122 @@ +test.test_shutil.PublicAPITests.test_module_all_attribute @ linux-x86_64 +test.test_shutil.TestArchives.test_make_archive @ linux-x86_64 +test.test_shutil.TestArchives.test_make_archive_cwd @ linux-x86_64 +test.test_shutil.TestArchives.test_make_archive_owner_group @ linux-x86_64 +test.test_shutil.TestArchives.test_make_tarball @ linux-x86_64 +test.test_shutil.TestArchives.test_make_tarfile_in_curdir @ linux-x86_64 +test.test_shutil.TestArchives.test_make_tarfile_rootdir_nodir @ linux-x86_64 +test.test_shutil.TestArchives.test_make_zipfile @ linux-x86_64 +test.test_shutil.TestArchives.test_make_zipfile_in_curdir @ linux-x86_64 +test.test_shutil.TestArchives.test_make_zipfile_rootdir_nodir @ linux-x86_64 +test.test_shutil.TestArchives.test_register_archive_format @ linux-x86_64 +test.test_shutil.TestArchives.test_tarfile_vs_tar @ linux-x86_64 +test.test_shutil.TestArchives.test_unpack_archive_bztar @ linux-x86_64 +test.test_shutil.TestArchives.test_unpack_archive_gztar @ linux-x86_64 +test.test_shutil.TestArchives.test_unpack_archive_tar @ linux-x86_64 +test.test_shutil.TestArchives.test_unpack_archive_xztar @ linux-x86_64 +test.test_shutil.TestArchives.test_unpack_archive_zip @ linux-x86_64 +test.test_shutil.TestArchives.test_unpack_registry @ linux-x86_64 +test.test_shutil.TestArchives.test_unzip_zipfile @ linux-x86_64 +test.test_shutil.TestArchives.test_zipfile_vs_zip @ linux-x86_64 +test.test_shutil.TestCopy.test_copy @ linux-x86_64 +test.test_shutil.TestCopy.test_copy2 @ linux-x86_64 +test.test_shutil.TestCopy.test_copy2_dir @ linux-x86_64 +test.test_shutil.TestCopy.test_copy2_symlinks @ linux-x86_64 +test.test_shutil.TestCopy.test_copy_dir @ linux-x86_64 +test.test_shutil.TestCopy.test_copy_return_value @ linux-x86_64 +test.test_shutil.TestCopy.test_copy_symlinks @ linux-x86_64 +test.test_shutil.TestCopy.test_copyfile_copy_dir @ linux-x86_64 +test.test_shutil.TestCopy.test_copyfile_nonexistent_dir @ linux-x86_64 +test.test_shutil.TestCopy.test_copyfile_return_value @ linux-x86_64 +test.test_shutil.TestCopy.test_copyfile_same_file @ linux-x86_64 +test.test_shutil.TestCopy.test_copyfile_symlinks @ linux-x86_64 +test.test_shutil.TestCopy.test_copymode_follow_symlinks @ linux-x86_64 +test.test_shutil.TestCopy.test_copymode_symlink_to_symlink_wo_lchmod @ linux-x86_64 +test.test_shutil.TestCopy.test_copystat_symlinks @ linux-x86_64 +test.test_shutil.TestCopy.test_dont_copy_file_onto_link_to_itself @ linux-x86_64 +test.test_shutil.TestCopy.test_dont_copy_file_onto_symlink_to_itself @ linux-x86_64 +test.test_shutil.TestCopyFile.test_w_dest_close_fails @ linux-x86_64 +test.test_shutil.TestCopyFile.test_w_dest_open_fails @ linux-x86_64 +test.test_shutil.TestCopyFile.test_w_source_close_fails @ linux-x86_64 +test.test_shutil.TestCopyFile.test_w_source_open_fails @ linux-x86_64 +test.test_shutil.TestCopyFileObj.test_content @ linux-x86_64 +test.test_shutil.TestCopyFileObj.test_file_not_closed @ linux-x86_64 +test.test_shutil.TestCopyFileObj.test_file_offset @ linux-x86_64 +test.test_shutil.TestCopyTree.test_copytree_arg_types_of_ignore @ linux-x86_64 +test.test_shutil.TestCopyTree.test_copytree_custom_copy_function @ linux-x86_64 +test.test_shutil.TestCopyTree.test_copytree_dangling_symlinks @ linux-x86_64 +test.test_shutil.TestCopyTree.test_copytree_dirs_exist_ok @ linux-x86_64 +test.test_shutil.TestCopyTree.test_copytree_retains_permissions @ linux-x86_64 +test.test_shutil.TestCopyTree.test_copytree_return_value @ linux-x86_64 +test.test_shutil.TestCopyTree.test_copytree_simple @ linux-x86_64 +test.test_shutil.TestCopyTree.test_copytree_special_func @ linux-x86_64 +test.test_shutil.TestCopyTree.test_copytree_subdirectory @ linux-x86_64 +test.test_shutil.TestCopyTree.test_copytree_symlink_dir @ linux-x86_64 +test.test_shutil.TestCopyTree.test_copytree_symlinks @ linux-x86_64 +test.test_shutil.TestCopyTree.test_copytree_winerror @ linux-x86_64 +test.test_shutil.TestCopyTree.test_copytree_with_exclude @ linux-x86_64 +test.test_shutil.TestGetTerminalSize.test_bad_environ @ linux-x86_64 +test.test_shutil.TestGetTerminalSize.test_does_not_crash @ linux-x86_64 +test.test_shutil.TestGetTerminalSize.test_fallback @ linux-x86_64 +test.test_shutil.TestGetTerminalSize.test_os_environ_first @ linux-x86_64 +test.test_shutil.TestMisc.test_disk_usage @ linux-x86_64 +test.test_shutil.TestMove.test_destinsrc_false_negative @ linux-x86_64 +test.test_shutil.TestMove.test_destinsrc_false_positive @ linux-x86_64 +test.test_shutil.TestMove.test_dont_move_dir_in_itself @ linux-x86_64 +test.test_shutil.TestMove.test_existing_file_inside_dest_dir @ linux-x86_64 +test.test_shutil.TestMove.test_move_as_rename_return_value @ linux-x86_64 +test.test_shutil.TestMove.test_move_dangling_symlink @ linux-x86_64 +test.test_shutil.TestMove.test_move_dir @ linux-x86_64 +test.test_shutil.TestMove.test_move_dir_caseinsensitive @ linux-x86_64 +test.test_shutil.TestMove.test_move_dir_other_fs @ linux-x86_64 +test.test_shutil.TestMove.test_move_dir_sep_to_dir @ linux-x86_64 +test.test_shutil.TestMove.test_move_dir_special_function @ linux-x86_64 +test.test_shutil.TestMove.test_move_dir_symlink @ linux-x86_64 +test.test_shutil.TestMove.test_move_dir_to_dir @ linux-x86_64 +test.test_shutil.TestMove.test_move_dir_to_dir_other_fs @ linux-x86_64 +test.test_shutil.TestMove.test_move_file @ linux-x86_64 +test.test_shutil.TestMove.test_move_file_other_fs @ linux-x86_64 +test.test_shutil.TestMove.test_move_file_special_function @ linux-x86_64 +test.test_shutil.TestMove.test_move_file_symlink @ linux-x86_64 +test.test_shutil.TestMove.test_move_file_symlink_to_dir @ linux-x86_64 +test.test_shutil.TestMove.test_move_file_to_dir @ linux-x86_64 +test.test_shutil.TestMove.test_move_file_to_dir_other_fs @ linux-x86_64 +test.test_shutil.TestMove.test_move_file_to_dir_pathlike_dst @ linux-x86_64 +test.test_shutil.TestMove.test_move_file_to_dir_pathlike_src @ linux-x86_64 +test.test_shutil.TestMove.test_move_return_value @ linux-x86_64 +test.test_shutil.TestRmTree.test_on_error @ linux-x86_64 +test.test_shutil.TestRmTree.test_rmtree_does_not_choke_on_failing_lstat @ linux-x86_64 +test.test_shutil.TestRmTree.test_rmtree_dont_delete_file @ linux-x86_64 +test.test_shutil.TestRmTree.test_rmtree_errors @ linux-x86_64 +test.test_shutil.TestRmTree.test_rmtree_fails_on_symlink @ linux-x86_64 +test.test_shutil.TestRmTree.test_rmtree_on_symlink @ linux-x86_64 +test.test_shutil.TestRmTree.test_rmtree_uses_safe_fd_version_if_available @ linux-x86_64 +test.test_shutil.TestRmTree.test_rmtree_with_dir_fd @ linux-x86_64 +test.test_shutil.TestRmTree.test_rmtree_works_on_bytes @ linux-x86_64 +test.test_shutil.TestRmTree.test_rmtree_works_on_symlinks @ linux-x86_64 +test.test_shutil.TestWhich.test_absolute_cmd @ linux-x86_64 +test.test_shutil.TestWhich.test_basic @ linux-x86_64 +test.test_shutil.TestWhich.test_cwd @ linux-x86_64 +test.test_shutil.TestWhich.test_empty_path @ linux-x86_64 +test.test_shutil.TestWhich.test_empty_path_no_PATH @ linux-x86_64 +test.test_shutil.TestWhich.test_environ_path @ linux-x86_64 +test.test_shutil.TestWhich.test_environ_path_cwd @ linux-x86_64 +test.test_shutil.TestWhich.test_environ_path_empty @ linux-x86_64 +test.test_shutil.TestWhich.test_environ_path_missing @ linux-x86_64 +test.test_shutil.TestWhich.test_non_matching_mode @ linux-x86_64 +test.test_shutil.TestWhich.test_nonexistent_file @ linux-x86_64 +test.test_shutil.TestWhich.test_relative_cmd @ linux-x86_64 +test.test_shutil.TestWhich.test_relative_path @ linux-x86_64 +test.test_shutil.TestWhichBytes.test_absolute_cmd @ linux-x86_64 +test.test_shutil.TestWhichBytes.test_basic @ linux-x86_64 +test.test_shutil.TestWhichBytes.test_cwd @ linux-x86_64 +test.test_shutil.TestWhichBytes.test_empty_path @ linux-x86_64 +test.test_shutil.TestWhichBytes.test_empty_path_no_PATH @ linux-x86_64 +test.test_shutil.TestWhichBytes.test_environ_path @ linux-x86_64 +test.test_shutil.TestWhichBytes.test_environ_path_cwd @ linux-x86_64 +test.test_shutil.TestWhichBytes.test_environ_path_empty @ linux-x86_64 +test.test_shutil.TestWhichBytes.test_environ_path_missing @ linux-x86_64 +test.test_shutil.TestWhichBytes.test_non_matching_mode @ linux-x86_64 +test.test_shutil.TestWhichBytes.test_nonexistent_file @ linux-x86_64 +test.test_shutil.TestWhichBytes.test_relative_cmd @ linux-x86_64 +test.test_shutil.TestWhichBytes.test_relative_path @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_signal.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_signal.txt new file mode 100644 index 0000000000..1325360e70 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_signal.txt @@ -0,0 +1,7 @@ +test.test_signal.GenericTests.test_enums @ linux-x86_64 +test.test_signal.GenericTests.test_functions_module_attr @ linux-x86_64 +test.test_signal.ItimerTest.test_setitimer_tiny @ linux-x86_64 +test.test_signal.PosixTests.test_getsignal @ linux-x86_64 +test.test_signal.PosixTests.test_setting_signal_handler_to_none_raises_error @ linux-x86_64 +test.test_signal.PosixTests.test_valid_signals @ linux-x86_64 +test.test_signal.SiginterruptTest.test_siginterrupt_off @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_site.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_site.txt new file mode 100644 index 0000000000..6439b71adf --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_site.txt @@ -0,0 +1,26 @@ +test.test_site.HelperFunctionsTests.test__getuserbase @ linux-x86_64 +test.test_site.HelperFunctionsTests.test_addpackage @ linux-x86_64 +test.test_site.HelperFunctionsTests.test_addpackage_empty_lines @ linux-x86_64 +test.test_site.HelperFunctionsTests.test_addpackage_import_bad_exec @ linux-x86_64 +test.test_site.HelperFunctionsTests.test_addpackage_import_bad_pth_file @ linux-x86_64 +test.test_site.HelperFunctionsTests.test_addpackage_import_bad_syntax @ linux-x86_64 +test.test_site.HelperFunctionsTests.test_addsitedir @ linux-x86_64 +test.test_site.HelperFunctionsTests.test_get_path @ linux-x86_64 +test.test_site.HelperFunctionsTests.test_getsitepackages @ linux-x86_64 +test.test_site.HelperFunctionsTests.test_getuserbase @ linux-x86_64 +test.test_site.HelperFunctionsTests.test_getusersitepackages @ linux-x86_64 +test.test_site.HelperFunctionsTests.test_init_pathinfo @ linux-x86_64 +test.test_site.HelperFunctionsTests.test_makepath @ linux-x86_64 +test.test_site.HelperFunctionsTests.test_no_home_directory @ linux-x86_64 +test.test_site.HelperFunctionsTests.test_s_option @ linux-x86_64 +test.test_site.HelperFunctionsTests.test_trace @ linux-x86_64 +test.test_site.ImportSideEffectTests.test_abs_paths_cached_None @ linux-x86_64 +test.test_site.ImportSideEffectTests.test_license_exists_at_url @ linux-x86_64 +test.test_site.ImportSideEffectTests.test_no_duplicate_paths @ linux-x86_64 +test.test_site.ImportSideEffectTests.test_setting_copyright @ linux-x86_64 +test.test_site.ImportSideEffectTests.test_setting_help @ linux-x86_64 +test.test_site.ImportSideEffectTests.test_setting_quit @ linux-x86_64 +test.test_site.ImportSideEffectTests.test_sitecustomize_executed @ linux-x86_64 +test.test_site.StartupImportTests.test_startup_interactivehook @ linux-x86_64 +test.test_site.StartupImportTests.test_startup_interactivehook_isolated @ linux-x86_64 +test.test_site.StartupImportTests.test_startup_interactivehook_isolated_explicit @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_slice.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_slice.txt new file mode 100644 index 0000000000..1fa0f1150d --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_slice.txt @@ -0,0 +1,10 @@ +test.test_slice.SliceTest.test_cmp @ linux-x86_64 +test.test_slice.SliceTest.test_constructor @ linux-x86_64 +test.test_slice.SliceTest.test_copy @ linux-x86_64 +test.test_slice.SliceTest.test_deepcopy @ linux-x86_64 +test.test_slice.SliceTest.test_hash @ linux-x86_64 +test.test_slice.SliceTest.test_indices @ linux-x86_64 +test.test_slice.SliceTest.test_members @ linux-x86_64 +test.test_slice.SliceTest.test_pickle @ linux-x86_64 +test.test_slice.SliceTest.test_repr @ linux-x86_64 +test.test_slice.SliceTest.test_setslice_without_getslice @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_smtpd.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_smtpd.txt new file mode 100644 index 0000000000..ca22feab86 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_smtpd.txt @@ -0,0 +1,153 @@ +test.test_smtpd.DebuggingServerTest.test_process_SMTPUTF8_message_with_enable_SMTPUTF8_true @ linux-x86_64 +test.test_smtpd.DebuggingServerTest.test_process_message_with_decode_data_false @ linux-x86_64 +test.test_smtpd.DebuggingServerTest.test_process_message_with_decode_data_true @ linux-x86_64 +test.test_smtpd.DebuggingServerTest.test_process_message_with_enable_SMTPUTF8_true @ linux-x86_64 +test.test_smtpd.MiscTestCase.test__all__ @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_DATA_syntax @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_EHLO @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_EHLO_HELO_duplicate @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_EHLO_bad_syntax @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_EHLO_duplicate @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_EXPN_not_implemented @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_HELO @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_HELO_EHLO_duplicate @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_HELO_NOOP @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_HELO_QUIT @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_HELO_RSET @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_HELO_bad_syntax @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_HELO_duplicate @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_HELO_parameter_rejected_when_extensions_not_enabled @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_HELP @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_HELP_command @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_HELP_command_unknown @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_RCPT_unknown_parameters @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_allows_space_after_colon @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_chevrons @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_command_limit_extended_with_SIZE @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_command_rejects_SMTPUTF8_by_default @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_empty_chevrons @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_invalid_size_parameter @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_missing_address @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_quoted_localpart @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_quoted_localpart_no_angles @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_quoted_localpart_with_size @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_quoted_localpart_with_size_no_angles @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_size_parameter @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_size_parameter_larger_than_default_data_size_limit @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_syntax_EHLO @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_MAIL_syntax_HELO @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_NOOP @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_NOOP_bad_syntax @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_QUIT @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_QUIT_arg_ignored @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_RCPT_lowercase_to_OK @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_RCPT_syntax_EHLO @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_RCPT_syntax_HELO @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_RSET @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_RSET_syntax @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_VRFY @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_VRFY_syntax @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_attribute_deprecations @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_bad_state @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_broken_connect @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_command_too_long @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_data_dialog @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_data_longer_than_default_data_size_limit @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_data_transparency_section_4_5_2 @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_decode_data_and_enable_SMTPUTF8_raises @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_extended_MAIL_allows_space_after_colon @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_manual_status @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_missing_data @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_multiple_RCPT @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_need_MAIL @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_need_RCPT @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_nested_MAIL @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_no_HELO_DATA @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_no_HELO_MAIL @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_no_HELO_RCPT @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_server_accept @ linux-x86_64 +test.test_smtpd.SMTPDChannelIPv6Test.test_unknown_command @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_DATA_syntax @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_EHLO @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_EHLO_HELO_duplicate @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_EHLO_bad_syntax @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_EHLO_duplicate @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_EXPN_not_implemented @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_HELO @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_HELO_EHLO_duplicate @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_HELO_NOOP @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_HELO_QUIT @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_HELO_RSET @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_HELO_bad_syntax @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_HELO_duplicate @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_HELO_parameter_rejected_when_extensions_not_enabled @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_HELP @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_HELP_command @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_HELP_command_unknown @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_RCPT_unknown_parameters @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_allows_space_after_colon @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_chevrons @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_command_limit_extended_with_SIZE @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_command_rejects_SMTPUTF8_by_default @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_empty_chevrons @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_invalid_size_parameter @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_missing_address @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_quoted_localpart @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_quoted_localpart_no_angles @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_quoted_localpart_with_size @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_quoted_localpart_with_size_no_angles @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_size_parameter @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_size_parameter_larger_than_default_data_size_limit @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_syntax_EHLO @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_MAIL_syntax_HELO @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_NOOP @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_NOOP_bad_syntax @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_QUIT @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_QUIT_arg_ignored @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_RCPT_lowercase_to_OK @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_RCPT_syntax_EHLO @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_RCPT_syntax_HELO @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_RSET @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_RSET_syntax @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_VRFY @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_VRFY_syntax @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_attribute_deprecations @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_bad_state @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_broken_connect @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_command_too_long @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_data_dialog @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_data_longer_than_default_data_size_limit @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_data_transparency_section_4_5_2 @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_decode_data_and_enable_SMTPUTF8_raises @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_extended_MAIL_allows_space_after_colon @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_manual_status @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_missing_data @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_multiple_RCPT @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_need_MAIL @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_need_RCPT @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_nested_MAIL @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_no_HELO_DATA @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_no_HELO_MAIL @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_no_HELO_RCPT @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_server_accept @ linux-x86_64 +test.test_smtpd.SMTPDChannelTest.test_unknown_command @ linux-x86_64 +test.test_smtpd.SMTPDChannelTestWithEnableSMTPUTF8True.test_MAIL_command_accepts_SMTPUTF8_when_announced @ linux-x86_64 +test.test_smtpd.SMTPDChannelTestWithEnableSMTPUTF8True.test_MAIL_command_limit_extended_with_SIZE_and_SMTPUTF8 @ linux-x86_64 +test.test_smtpd.SMTPDChannelTestWithEnableSMTPUTF8True.test_multiple_emails_with_extended_command_length @ linux-x86_64 +test.test_smtpd.SMTPDChannelTestWithEnableSMTPUTF8True.test_process_smtputf8_message @ linux-x86_64 +test.test_smtpd.SMTPDChannelTestWithEnableSMTPUTF8True.test_utf8_data @ linux-x86_64 +test.test_smtpd.SMTPDChannelWithDataSizeLimitTest.test_data_limit_dialog @ linux-x86_64 +test.test_smtpd.SMTPDChannelWithDataSizeLimitTest.test_data_limit_dialog_too_much_data @ linux-x86_64 +test.test_smtpd.SMTPDChannelWithDecodeDataFalse.test_ascii_data @ linux-x86_64 +test.test_smtpd.SMTPDChannelWithDecodeDataFalse.test_utf8_data @ linux-x86_64 +test.test_smtpd.SMTPDChannelWithDecodeDataTrue.test_ascii_data @ linux-x86_64 +test.test_smtpd.SMTPDChannelWithDecodeDataTrue.test_utf8_data @ linux-x86_64 +test.test_smtpd.SMTPDServerTest.test_decode_data_and_enable_SMTPUTF8_raises @ linux-x86_64 +test.test_smtpd.SMTPDServerTest.test_process_message_unimplemented @ linux-x86_64 +test.test_smtpd.TestFamilyDetection.test_socket_uses_IPv4 @ linux-x86_64 +test.test_smtpd.TestFamilyDetection.test_socket_uses_IPv6 @ linux-x86_64 +test.test_smtpd.TestMailOptionParsing.test_with_decode_data_false @ linux-x86_64 +test.test_smtpd.TestMailOptionParsing.test_with_decode_data_true @ linux-x86_64 +test.test_smtpd.TestMailOptionParsing.test_with_enable_smtputf8_true @ linux-x86_64 +test.test_smtpd.TestRcptOptionParsing.test_nothing_accepted @ linux-x86_64 +test.test_smtpd.TestRcptOptionParsing.test_params_rejected @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_smtplib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_smtplib.txt new file mode 100644 index 0000000000..c5e3f75ed9 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_smtplib.txt @@ -0,0 +1,82 @@ +test.test_smtplib.BadHELOServerTests.testFailingHELO @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testBasic @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testELHO @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testEXPNNotImplemented @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testHELP @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testNOOP @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testRSET @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testSecondHELO @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testSend @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testSendBinary @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testSendMessage @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testSendMessageMultipleResentRaises @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testSendMessageResent @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testSendMessageWithAddresses @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testSendMessageWithMultipleFrom @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testSendMessageWithSomeAddresses @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testSendMessageWithSpecifiedAddresses @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testSendNeedingDotQuote @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testSendNullSender @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testSourceAddress @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.testVRFY @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.test_issue43124_escape_localhostname @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.test_issue43124_escape_options @ linux-x86_64 +test.test_smtplib.DebuggingServerTests.test_issue43124_putcmd_escapes_newline @ linux-x86_64 +test.test_smtplib.DefaultArgumentsTests.testSendMessage @ linux-x86_64 +test.test_smtplib.DefaultArgumentsTests.testSendMessageWithMailOptions @ linux-x86_64 +test.test_smtplib.LMTPGeneralTests.testBasic1 @ linux-x86_64 +test.test_smtplib.LMTPGeneralTests.testBasic2 @ linux-x86_64 +test.test_smtplib.LMTPGeneralTests.testLocalHostName @ linux-x86_64 +test.test_smtplib.LMTPGeneralTests.testQuoteData @ linux-x86_64 +test.test_smtplib.LMTPGeneralTests.testSourceAddress @ linux-x86_64 +test.test_smtplib.LMTPGeneralTests.testTimeoutDefault @ linux-x86_64 +test.test_smtplib.LMTPGeneralTests.testTimeoutNone @ linux-x86_64 +test.test_smtplib.LMTPGeneralTests.testTimeoutValue @ linux-x86_64 +test.test_smtplib.LMTPGeneralTests.testTimeoutZero @ linux-x86_64 +test.test_smtplib.LMTPGeneralTests.testUnixDomainSocketTimeoutDefault @ linux-x86_64 +test.test_smtplib.LMTPGeneralTests.test_debuglevel @ linux-x86_64 +test.test_smtplib.LMTPGeneralTests.test_debuglevel_2 @ linux-x86_64 +test.test_smtplib.NonConnectingTests.testNonnumericPort @ linux-x86_64 +test.test_smtplib.NonConnectingTests.testNotConnected @ linux-x86_64 +test.test_smtplib.NonConnectingTests.testSockAttributeExists @ linux-x86_64 +test.test_smtplib.SMTPAUTHInitialResponseSimTests.testAUTH_PLAIN_initial_response_auth @ linux-x86_64 +test.test_smtplib.SMTPAUTHInitialResponseSimTests.testAUTH_PLAIN_initial_response_login @ linux-x86_64 +test.test_smtplib.SMTPGeneralTests.testBasic1 @ linux-x86_64 +test.test_smtplib.SMTPGeneralTests.testBasic2 @ linux-x86_64 +test.test_smtplib.SMTPGeneralTests.testLocalHostName @ linux-x86_64 +test.test_smtplib.SMTPGeneralTests.testQuoteData @ linux-x86_64 +test.test_smtplib.SMTPGeneralTests.testSourceAddress @ linux-x86_64 +test.test_smtplib.SMTPGeneralTests.testTimeoutDefault @ linux-x86_64 +test.test_smtplib.SMTPGeneralTests.testTimeoutNone @ linux-x86_64 +test.test_smtplib.SMTPGeneralTests.testTimeoutValue @ linux-x86_64 +test.test_smtplib.SMTPGeneralTests.testTimeoutZero @ linux-x86_64 +test.test_smtplib.SMTPGeneralTests.test_debuglevel @ linux-x86_64 +test.test_smtplib.SMTPGeneralTests.test_debuglevel_2 @ linux-x86_64 +test.test_smtplib.SMTPSimTests.testAUTH_BUGGY @ linux-x86_64 +test.test_smtplib.SMTPSimTests.testAUTH_CRAM_MD5 @ linux-x86_64 +test.test_smtplib.SMTPSimTests.testAUTH_LOGIN @ linux-x86_64 +test.test_smtplib.SMTPSimTests.testAUTH_LOGIN_initial_response_notok @ linux-x86_64 +test.test_smtplib.SMTPSimTests.testAUTH_LOGIN_initial_response_ok @ linux-x86_64 +test.test_smtplib.SMTPSimTests.testAUTH_PLAIN @ linux-x86_64 +test.test_smtplib.SMTPSimTests.testAUTH_multiple @ linux-x86_64 +test.test_smtplib.SMTPSimTests.testBasic @ linux-x86_64 +test.test_smtplib.SMTPSimTests.testEHLO @ linux-x86_64 +test.test_smtplib.SMTPSimTests.testEXPN @ linux-x86_64 +test.test_smtplib.SMTPSimTests.testVRFY @ linux-x86_64 +test.test_smtplib.SMTPSimTests.test_421_from_data_cmd @ linux-x86_64 +test.test_smtplib.SMTPSimTests.test_421_from_mail_cmd @ linux-x86_64 +test.test_smtplib.SMTPSimTests.test_421_from_rcpt_cmd @ linux-x86_64 +test.test_smtplib.SMTPSimTests.test__rest_from_mail_cmd @ linux-x86_64 +test.test_smtplib.SMTPSimTests.test_auth_function @ linux-x86_64 +test.test_smtplib.SMTPSimTests.test_name_field_not_included_in_envelop_addresses @ linux-x86_64 +test.test_smtplib.SMTPSimTests.test_quit_resets_greeting @ linux-x86_64 +test.test_smtplib.SMTPSimTests.test_send_message_error_on_non_ascii_addrs_if_no_smtputf8 @ linux-x86_64 +test.test_smtplib.SMTPSimTests.test_send_unicode_without_SMTPUTF8 @ linux-x86_64 +test.test_smtplib.SMTPSimTests.test_smtputf8_NotSupportedError_if_no_server_support @ linux-x86_64 +test.test_smtplib.SMTPSimTests.test_with_statement @ linux-x86_64 +test.test_smtplib.SMTPSimTests.test_with_statement_QUIT_failure @ linux-x86_64 +test.test_smtplib.SMTPUTF8SimTests.test_send_message_uses_smtputf8_if_addrs_non_ascii @ linux-x86_64 +test.test_smtplib.SMTPUTF8SimTests.test_send_unicode_with_SMTPUTF8_via_low_level_API @ linux-x86_64 +test.test_smtplib.SMTPUTF8SimTests.test_send_unicode_with_SMTPUTF8_via_sendmail @ linux-x86_64 +test.test_smtplib.SMTPUTF8SimTests.test_test_server_supports_extensions @ linux-x86_64 +test.test_smtplib.TooLongLineTests.testLineTooLong @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sndhdr.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sndhdr.txt new file mode 100644 index 0000000000..aa65b146aa --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sndhdr.txt @@ -0,0 +1,2 @@ +test.test_sndhdr.TestFormats.test_data @ linux-x86_64 +test.test_sndhdr.TestFormats.test_pickleable @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_socket.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_socket.txt new file mode 100644 index 0000000000..b01c6cac08 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_socket.txt @@ -0,0 +1,218 @@ +test.test_socket.BasicSocketPairTest.testDefaults @ linux-x86_64 +test.test_socket.BasicSocketPairTest.testRecv @ linux-x86_64 +test.test_socket.BasicSocketPairTest.testSend @ linux-x86_64 +test.test_socket.BasicTCPTest.testDetach @ linux-x86_64 +test.test_socket.BasicTCPTest.testDup @ linux-x86_64 +test.test_socket.BasicTCPTest.testFromFd @ linux-x86_64 +test.test_socket.BasicTCPTest.testOverFlowRecv @ linux-x86_64 +test.test_socket.BasicTCPTest.testOverFlowRecvFrom @ linux-x86_64 +test.test_socket.BasicTCPTest.testRecv @ linux-x86_64 +test.test_socket.BasicTCPTest.testRecvFrom @ linux-x86_64 +test.test_socket.BasicTCPTest.testSendAll @ linux-x86_64 +test.test_socket.BasicTCPTest.testShutdown @ linux-x86_64 +test.test_socket.BasicTCPTest2.testDetach @ linux-x86_64 +test.test_socket.BasicTCPTest2.testDup @ linux-x86_64 +test.test_socket.BasicTCPTest2.testFromFd @ linux-x86_64 +test.test_socket.BasicTCPTest2.testOverFlowRecv @ linux-x86_64 +test.test_socket.BasicTCPTest2.testOverFlowRecvFrom @ linux-x86_64 +test.test_socket.BasicTCPTest2.testRecv @ linux-x86_64 +test.test_socket.BasicTCPTest2.testRecvFrom @ linux-x86_64 +test.test_socket.BasicTCPTest2.testSendAll @ linux-x86_64 +test.test_socket.BasicTCPTest2.testShutdown @ linux-x86_64 +test.test_socket.BasicUDPTest.testRecvFrom @ linux-x86_64 +test.test_socket.BasicUDPTest.testRecvFromNegative @ linux-x86_64 +test.test_socket.BasicUDPTest.testSendtoAndRecv @ linux-x86_64 +test.test_socket.BufferIOTest.testRecvFromIntoArray @ linux-x86_64 +test.test_socket.BufferIOTest.testRecvFromIntoBytearray @ linux-x86_64 +test.test_socket.BufferIOTest.testRecvFromIntoEmptyBuffer @ linux-x86_64 +test.test_socket.BufferIOTest.testRecvFromIntoMemoryview @ linux-x86_64 +test.test_socket.BufferIOTest.testRecvFromIntoSmallBuffer @ linux-x86_64 +test.test_socket.BufferIOTest.testRecvIntoArray @ linux-x86_64 +test.test_socket.BufferIOTest.testRecvIntoBytearray @ linux-x86_64 +test.test_socket.BufferIOTest.testRecvIntoMemoryview @ linux-x86_64 +test.test_socket.ContextManagersTest.testCreateConnectionBase @ linux-x86_64 +test.test_socket.ContextManagersTest.testCreateConnectionClose @ linux-x86_64 +test.test_socket.CreateServerFunctionalTest.test_dual_stack_client_v4 @ linux-x86_64 +test.test_socket.CreateServerFunctionalTest.test_dual_stack_client_v6 @ linux-x86_64 +test.test_socket.CreateServerFunctionalTest.test_tcp4 @ linux-x86_64 +test.test_socket.CreateServerFunctionalTest.test_tcp6 @ linux-x86_64 +test.test_socket.CreateServerTest.test_address @ linux-x86_64 +test.test_socket.CreateServerTest.test_dualstack_ipv6_family @ linux-x86_64 +test.test_socket.CreateServerTest.test_family_and_type @ linux-x86_64 +test.test_socket.CreateServerTest.test_ipv6_only_default @ linux-x86_64 +test.test_socket.CreateServerTest.test_reuse_port @ linux-x86_64 +test.test_socket.FileObjectClassTestCase.testAttributes @ linux-x86_64 +test.test_socket.FileObjectClassTestCase.testCloseAfterMakefile @ linux-x86_64 +test.test_socket.FileObjectClassTestCase.testClosedAttr @ linux-x86_64 +test.test_socket.FileObjectClassTestCase.testFullRead @ linux-x86_64 +test.test_socket.FileObjectClassTestCase.testMakefileAfterMakefileClose @ linux-x86_64 +test.test_socket.FileObjectClassTestCase.testReadAfterTimeout @ linux-x86_64 +test.test_socket.FileObjectClassTestCase.testReadline @ linux-x86_64 +test.test_socket.FileObjectClassTestCase.testRealClose @ linux-x86_64 +test.test_socket.FileObjectClassTestCase.testSmallRead @ linux-x86_64 +test.test_socket.FileObjectClassTestCase.testUnbufferedRead @ linux-x86_64 +test.test_socket.GeneralModuleTests.testCloseException @ linux-x86_64 +test.test_socket.GeneralModuleTests.testCrucialConstants @ linux-x86_64 +test.test_socket.GeneralModuleTests.testCrucialIpProtoConstants @ linux-x86_64 +test.test_socket.GeneralModuleTests.testDefaultTimeout @ linux-x86_64 +test.test_socket.GeneralModuleTests.testGetServBy @ linux-x86_64 +test.test_socket.GeneralModuleTests.testGetSockOpt @ linux-x86_64 +test.test_socket.GeneralModuleTests.testHostnameRes @ linux-x86_64 +test.test_socket.GeneralModuleTests.testIPv4_inet_aton_fourbytes @ linux-x86_64 +test.test_socket.GeneralModuleTests.testIPv4toString @ linux-x86_64 +test.test_socket.GeneralModuleTests.testIPv6toString @ linux-x86_64 +test.test_socket.GeneralModuleTests.testInterpreterCrash @ linux-x86_64 +test.test_socket.GeneralModuleTests.testNewAttributes @ linux-x86_64 +test.test_socket.GeneralModuleTests.testNtoH @ linux-x86_64 +test.test_socket.GeneralModuleTests.testRefCountGetNameInfo @ linux-x86_64 +test.test_socket.GeneralModuleTests.testSendAfterClose @ linux-x86_64 +test.test_socket.GeneralModuleTests.testSendtoErrors @ linux-x86_64 +test.test_socket.GeneralModuleTests.testSetSockOpt @ linux-x86_64 +test.test_socket.GeneralModuleTests.testSockName @ linux-x86_64 +test.test_socket.GeneralModuleTests.testSocketError @ linux-x86_64 +test.test_socket.GeneralModuleTests.testStringToIPv4 @ linux-x86_64 +test.test_socket.GeneralModuleTests.testStringToIPv6 @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_SocketType_is_socketobject @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_addressfamily_enum @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_addressinfo_enum @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_csocket_repr @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_flowinfo @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_getaddrinfo_ipv6_basic @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_getfqdn_filter_localhost @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_getnameinfo @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_getsockaddrarg @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_host_resolution @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_host_resolution_bad_address @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_idna @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_listen_backlog @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_makefile_invalid_mode @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_makefile_mode @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_msgflag_enum @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_name_closed_socketio @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_pickle @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_repr @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_socket_close @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_socket_consistent_sock_type @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_socket_fileno @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_socket_fileno_rejects_float @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_socket_fileno_rejects_invalid_socket @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_socket_fileno_rejects_negative @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_socket_fileno_rejects_other_types @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_socket_fileno_requires_socket_fd @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_socket_fileno_requires_valid_fd @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_socket_methods @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_socketkind_enum @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_str_for_enums @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_unknown_socket_family_repr @ linux-x86_64 +test.test_socket.GeneralModuleTests.test_unusable_closed_socketio @ linux-x86_64 +test.test_socket.InheritanceTest.test_default_inheritable @ linux-x86_64 +test.test_socket.InheritanceTest.test_dup @ linux-x86_64 +test.test_socket.InheritanceTest.test_set_inheritable @ linux-x86_64 +test.test_socket.InheritanceTest.test_socketpair @ linux-x86_64 +test.test_socket.LineBufferedFileObjectClassTestCase.testAttributes @ linux-x86_64 +test.test_socket.LineBufferedFileObjectClassTestCase.testCloseAfterMakefile @ linux-x86_64 +test.test_socket.LineBufferedFileObjectClassTestCase.testClosedAttr @ linux-x86_64 +test.test_socket.LineBufferedFileObjectClassTestCase.testFullRead @ linux-x86_64 +test.test_socket.LineBufferedFileObjectClassTestCase.testMakefileAfterMakefileClose @ linux-x86_64 +test.test_socket.LineBufferedFileObjectClassTestCase.testReadAfterTimeout @ linux-x86_64 +test.test_socket.LineBufferedFileObjectClassTestCase.testReadline @ linux-x86_64 +test.test_socket.LineBufferedFileObjectClassTestCase.testRealClose @ linux-x86_64 +test.test_socket.LineBufferedFileObjectClassTestCase.testSmallRead @ linux-x86_64 +test.test_socket.LineBufferedFileObjectClassTestCase.testUnbufferedRead @ linux-x86_64 +test.test_socket.NetworkConnectionAttributesTest.testFamily @ linux-x86_64 +test.test_socket.NetworkConnectionAttributesTest.testSourceAddress @ linux-x86_64 +test.test_socket.NetworkConnectionAttributesTest.testTimeoutDefault @ linux-x86_64 +test.test_socket.NetworkConnectionAttributesTest.testTimeoutNone @ linux-x86_64 +test.test_socket.NetworkConnectionAttributesTest.testTimeoutValueNamed @ linux-x86_64 +test.test_socket.NetworkConnectionAttributesTest.testTimeoutValueNonamed @ linux-x86_64 +test.test_socket.NetworkConnectionBehaviourTest.testInsideTimeout @ linux-x86_64 +test.test_socket.NetworkConnectionBehaviourTest.testOutsideTimeout @ linux-x86_64 +test.test_socket.NetworkConnectionNoServer.test_connect @ linux-x86_64 +test.test_socket.NetworkConnectionNoServer.test_create_connection @ linux-x86_64 +test.test_socket.NetworkConnectionNoServer.test_create_connection_all_errors @ linux-x86_64 +test.test_socket.NetworkConnectionNoServer.test_create_connection_timeout @ linux-x86_64 +test.test_socket.NonBlockingTCPTests.testAccept @ linux-x86_64 +test.test_socket.NonBlockingTCPTests.testInheritFlagsBlocking @ linux-x86_64 +test.test_socket.NonBlockingTCPTests.testInheritFlagsTimeout @ linux-x86_64 +test.test_socket.NonBlockingTCPTests.testRecv @ linux-x86_64 +test.test_socket.SendfileUsingSendTest.testCount @ linux-x86_64 +test.test_socket.SendfileUsingSendTest.testCountSmall @ linux-x86_64 +test.test_socket.SendfileUsingSendTest.testCountWithOffset @ linux-x86_64 +test.test_socket.SendfileUsingSendTest.testEmptyFileSend @ linux-x86_64 +test.test_socket.SendfileUsingSendTest.testNonBlocking @ linux-x86_64 +test.test_socket.SendfileUsingSendTest.testNonRegularFile @ linux-x86_64 +test.test_socket.SendfileUsingSendTest.testOffset @ linux-x86_64 +test.test_socket.SendfileUsingSendTest.testRegularFile @ linux-x86_64 +test.test_socket.SendfileUsingSendTest.testWithTimeout @ linux-x86_64 +test.test_socket.SendfileUsingSendTest.testWithTimeoutTriggeredSend @ linux-x86_64 +test.test_socket.SendfileUsingSendTest.test_errors @ linux-x86_64 +test.test_socket.SmallBufferedFileObjectClassTestCase.testAttributes @ linux-x86_64 +test.test_socket.SmallBufferedFileObjectClassTestCase.testCloseAfterMakefile @ linux-x86_64 +test.test_socket.SmallBufferedFileObjectClassTestCase.testClosedAttr @ linux-x86_64 +test.test_socket.SmallBufferedFileObjectClassTestCase.testFullRead @ linux-x86_64 +test.test_socket.SmallBufferedFileObjectClassTestCase.testMakefileAfterMakefileClose @ linux-x86_64 +test.test_socket.SmallBufferedFileObjectClassTestCase.testReadAfterTimeout @ linux-x86_64 +test.test_socket.SmallBufferedFileObjectClassTestCase.testReadline @ linux-x86_64 +test.test_socket.SmallBufferedFileObjectClassTestCase.testRealClose @ linux-x86_64 +test.test_socket.SmallBufferedFileObjectClassTestCase.testSmallRead @ linux-x86_64 +test.test_socket.SmallBufferedFileObjectClassTestCase.testUnbufferedRead @ linux-x86_64 +test.test_socket.TCPCloserTest.testClose @ linux-x86_64 +test.test_socket.TCPTimeoutTest.testTCPTimeout @ linux-x86_64 +test.test_socket.TCPTimeoutTest.testTimeoutZero @ linux-x86_64 +test.test_socket.TestExceptions.testExceptionTree @ linux-x86_64 +test.test_socket.TestExceptions.test_setblocking_invalidfd @ linux-x86_64 +test.test_socket.TestLinuxAbstractNamespace.testAutobind @ linux-x86_64 +test.test_socket.TestLinuxAbstractNamespace.testBytearrayName @ linux-x86_64 +test.test_socket.TestLinuxAbstractNamespace.testLinuxAbstractNamespace @ linux-x86_64 +test.test_socket.TestLinuxAbstractNamespace.testMaxName @ linux-x86_64 +test.test_socket.TestLinuxAbstractNamespace.testNameOverflow @ linux-x86_64 +test.test_socket.TestLinuxAbstractNamespace.testStrName @ linux-x86_64 +test.test_socket.TestUnixDomain.testBytesAddr @ linux-x86_64 +test.test_socket.TestUnixDomain.testStrAddr @ linux-x86_64 +test.test_socket.TestUnixDomain.testUnbound @ linux-x86_64 +test.test_socket.UDPTimeoutTest.testTimeoutZero @ linux-x86_64 +test.test_socket.UDPTimeoutTest.testUDPTimeout @ linux-x86_64 +test.test_socket.UnbufferedFileObjectClassTestCase.testAttributes @ linux-x86_64 +test.test_socket.UnbufferedFileObjectClassTestCase.testCloseAfterMakefile @ linux-x86_64 +test.test_socket.UnbufferedFileObjectClassTestCase.testClosedAttr @ linux-x86_64 +test.test_socket.UnbufferedFileObjectClassTestCase.testFullRead @ linux-x86_64 +test.test_socket.UnbufferedFileObjectClassTestCase.testMakefileAfterMakefileClose @ linux-x86_64 +test.test_socket.UnbufferedFileObjectClassTestCase.testMakefileClose @ linux-x86_64 +test.test_socket.UnbufferedFileObjectClassTestCase.testReadAfterTimeout @ linux-x86_64 +test.test_socket.UnbufferedFileObjectClassTestCase.testReadline @ linux-x86_64 +test.test_socket.UnbufferedFileObjectClassTestCase.testRealClose @ linux-x86_64 +test.test_socket.UnbufferedFileObjectClassTestCase.testSmallRead @ linux-x86_64 +test.test_socket.UnbufferedFileObjectClassTestCase.testSmallReadNonBlocking @ linux-x86_64 +test.test_socket.UnbufferedFileObjectClassTestCase.testUnbufferedRead @ linux-x86_64 +test.test_socket.UnbufferedFileObjectClassTestCase.testUnbufferedReadline @ linux-x86_64 +test.test_socket.UnbufferedFileObjectClassTestCase.testWriteNonBlocking @ linux-x86_64 +test.test_socket.UnicodeReadFileObjectClassTestCase.testAttributes @ linux-x86_64 +test.test_socket.UnicodeReadFileObjectClassTestCase.testCloseAfterMakefile @ linux-x86_64 +test.test_socket.UnicodeReadFileObjectClassTestCase.testClosedAttr @ linux-x86_64 +test.test_socket.UnicodeReadFileObjectClassTestCase.testFullRead @ linux-x86_64 +test.test_socket.UnicodeReadFileObjectClassTestCase.testMakefileAfterMakefileClose @ linux-x86_64 +test.test_socket.UnicodeReadFileObjectClassTestCase.testReadAfterTimeout @ linux-x86_64 +test.test_socket.UnicodeReadFileObjectClassTestCase.testReadline @ linux-x86_64 +test.test_socket.UnicodeReadFileObjectClassTestCase.testRealClose @ linux-x86_64 +test.test_socket.UnicodeReadFileObjectClassTestCase.testSmallRead @ linux-x86_64 +test.test_socket.UnicodeReadFileObjectClassTestCase.testUnbufferedRead @ linux-x86_64 +test.test_socket.UnicodeReadWriteFileObjectClassTestCase.testAttributes @ linux-x86_64 +test.test_socket.UnicodeReadWriteFileObjectClassTestCase.testCloseAfterMakefile @ linux-x86_64 +test.test_socket.UnicodeReadWriteFileObjectClassTestCase.testClosedAttr @ linux-x86_64 +test.test_socket.UnicodeReadWriteFileObjectClassTestCase.testFullRead @ linux-x86_64 +test.test_socket.UnicodeReadWriteFileObjectClassTestCase.testMakefileAfterMakefileClose @ linux-x86_64 +test.test_socket.UnicodeReadWriteFileObjectClassTestCase.testReadAfterTimeout @ linux-x86_64 +test.test_socket.UnicodeReadWriteFileObjectClassTestCase.testReadline @ linux-x86_64 +test.test_socket.UnicodeReadWriteFileObjectClassTestCase.testRealClose @ linux-x86_64 +test.test_socket.UnicodeReadWriteFileObjectClassTestCase.testSmallRead @ linux-x86_64 +test.test_socket.UnicodeReadWriteFileObjectClassTestCase.testUnbufferedRead @ linux-x86_64 +test.test_socket.UnicodeWriteFileObjectClassTestCase.testAttributes @ linux-x86_64 +test.test_socket.UnicodeWriteFileObjectClassTestCase.testCloseAfterMakefile @ linux-x86_64 +test.test_socket.UnicodeWriteFileObjectClassTestCase.testClosedAttr @ linux-x86_64 +test.test_socket.UnicodeWriteFileObjectClassTestCase.testFullRead @ linux-x86_64 +test.test_socket.UnicodeWriteFileObjectClassTestCase.testMakefileAfterMakefileClose @ linux-x86_64 +test.test_socket.UnicodeWriteFileObjectClassTestCase.testReadAfterTimeout @ linux-x86_64 +test.test_socket.UnicodeWriteFileObjectClassTestCase.testReadline @ linux-x86_64 +test.test_socket.UnicodeWriteFileObjectClassTestCase.testRealClose @ linux-x86_64 +test.test_socket.UnicodeWriteFileObjectClassTestCase.testSmallRead @ linux-x86_64 +test.test_socket.UnicodeWriteFileObjectClassTestCase.testUnbufferedRead @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_socketserver.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_socketserver.txt new file mode 100644 index 0000000000..2b11afc3a0 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_socketserver.txt @@ -0,0 +1,20 @@ +test.test_socketserver.ErrorHandlerTest.test_sync_handled @ linux-x86_64 +test.test_socketserver.ErrorHandlerTest.test_sync_not_handled @ linux-x86_64 +test.test_socketserver.ErrorHandlerTest.test_threading_handled @ linux-x86_64 +test.test_socketserver.ErrorHandlerTest.test_threading_not_handled @ linux-x86_64 +test.test_socketserver.MiscTestCase.test_all @ linux-x86_64 +test.test_socketserver.MiscTestCase.test_shutdown_request_called_if_verify_request_false @ linux-x86_64 +test.test_socketserver.MiscTestCase.test_threads_reaped @ linux-x86_64 +test.test_socketserver.SocketServerTest.test_TCPServer @ linux-x86_64 +test.test_socketserver.SocketServerTest.test_ThreadingTCPServer @ linux-x86_64 +test.test_socketserver.SocketServerTest.test_ThreadingUDPServer @ linux-x86_64 +test.test_socketserver.SocketServerTest.test_ThreadingUnixDatagramServer @ linux-x86_64 +test.test_socketserver.SocketServerTest.test_ThreadingUnixStreamServer @ linux-x86_64 +test.test_socketserver.SocketServerTest.test_UDPServer @ linux-x86_64 +test.test_socketserver.SocketServerTest.test_UnixDatagramServer @ linux-x86_64 +test.test_socketserver.SocketServerTest.test_UnixStreamServer @ linux-x86_64 +test.test_socketserver.SocketServerTest.test_close_immediately @ linux-x86_64 +test.test_socketserver.SocketServerTest.test_context_manager @ linux-x86_64 +test.test_socketserver.SocketServerTest.test_shutdown @ linux-x86_64 +test.test_socketserver.SocketServerTest.test_tcpserver_bind_leak @ linux-x86_64 +test.test_socketserver.SocketWriterTest.test_basics @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sort.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sort.txt new file mode 100644 index 0000000000..dc83bf1315 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sort.txt @@ -0,0 +1,19 @@ +test.test_sort.TestBase.testStressfully @ linux-x86_64 +test.test_sort.TestBugs.test_bug453523 @ linux-x86_64 +test.test_sort.TestBugs.test_undetected_mutation @ linux-x86_64 +test.test_sort.TestDecorateSortUndecorate.test_baddecorator @ linux-x86_64 +test.test_sort.TestDecorateSortUndecorate.test_decorated @ linux-x86_64 +test.test_sort.TestDecorateSortUndecorate.test_key_with_exception @ linux-x86_64 +test.test_sort.TestDecorateSortUndecorate.test_key_with_mutating_del_and_exception @ linux-x86_64 +test.test_sort.TestDecorateSortUndecorate.test_key_with_mutation @ linux-x86_64 +test.test_sort.TestDecorateSortUndecorate.test_reverse @ linux-x86_64 +test.test_sort.TestDecorateSortUndecorate.test_reverse_stability @ linux-x86_64 +test.test_sort.TestDecorateSortUndecorate.test_stability @ linux-x86_64 +test.test_sort.TestOptimizedCompares.test_none_in_tuples @ linux-x86_64 +test.test_sort.TestOptimizedCompares.test_not_all_tuples @ linux-x86_64 +test.test_sort.TestOptimizedCompares.test_safe_object_compare @ linux-x86_64 +test.test_sort.TestOptimizedCompares.test_unsafe_float_compare @ linux-x86_64 +test.test_sort.TestOptimizedCompares.test_unsafe_latin_compare @ linux-x86_64 +test.test_sort.TestOptimizedCompares.test_unsafe_long_compare @ linux-x86_64 +test.test_sort.TestOptimizedCompares.test_unsafe_object_compare @ linux-x86_64 +test.test_sort.TestOptimizedCompares.test_unsafe_tuple_compare @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_source_encoding.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_source_encoding.txt new file mode 100644 index 0000000000..767bad5431 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_source_encoding.txt @@ -0,0 +1,40 @@ +test.test_source_encoding.BytesSourceEncodingTest.test_crcrcrlf @ linux-x86_64 +test.test_source_encoding.BytesSourceEncodingTest.test_crcrcrlf2 @ linux-x86_64 +test.test_source_encoding.BytesSourceEncodingTest.test_crcrlf @ linux-x86_64 +test.test_source_encoding.BytesSourceEncodingTest.test_crlf @ linux-x86_64 +test.test_source_encoding.BytesSourceEncodingTest.test_default_coding @ linux-x86_64 +test.test_source_encoding.BytesSourceEncodingTest.test_double_coding_line @ linux-x86_64 +test.test_source_encoding.BytesSourceEncodingTest.test_double_coding_same_line @ linux-x86_64 +test.test_source_encoding.BytesSourceEncodingTest.test_first_coding_line @ linux-x86_64 +test.test_source_encoding.BytesSourceEncodingTest.test_first_non_utf8_coding_line @ linux-x86_64 +test.test_source_encoding.BytesSourceEncodingTest.test_second_coding_line @ linux-x86_64 +test.test_source_encoding.BytesSourceEncodingTest.test_second_non_utf8_coding_line @ linux-x86_64 +test.test_source_encoding.BytesSourceEncodingTest.test_third_coding_line @ linux-x86_64 +test.test_source_encoding.BytesSourceEncodingTest.test_utf8_bom @ linux-x86_64 +test.test_source_encoding.BytesSourceEncodingTest.test_utf8_bom_and_utf8_coding_line @ linux-x86_64 +test.test_source_encoding.FileSourceEncodingTest.test_crcrcrlf @ linux-x86_64 +test.test_source_encoding.FileSourceEncodingTest.test_crcrcrlf2 @ linux-x86_64 +test.test_source_encoding.FileSourceEncodingTest.test_crcrlf @ linux-x86_64 +test.test_source_encoding.FileSourceEncodingTest.test_crlf @ linux-x86_64 +test.test_source_encoding.FileSourceEncodingTest.test_default_coding @ linux-x86_64 +test.test_source_encoding.FileSourceEncodingTest.test_double_coding_line @ linux-x86_64 +test.test_source_encoding.FileSourceEncodingTest.test_double_coding_same_line @ linux-x86_64 +test.test_source_encoding.FileSourceEncodingTest.test_first_coding_line @ linux-x86_64 +test.test_source_encoding.FileSourceEncodingTest.test_first_non_utf8_coding_line @ linux-x86_64 +test.test_source_encoding.FileSourceEncodingTest.test_second_coding_line @ linux-x86_64 +test.test_source_encoding.FileSourceEncodingTest.test_second_non_utf8_coding_line @ linux-x86_64 +test.test_source_encoding.FileSourceEncodingTest.test_third_coding_line @ linux-x86_64 +test.test_source_encoding.FileSourceEncodingTest.test_utf8_bom @ linux-x86_64 +test.test_source_encoding.FileSourceEncodingTest.test_utf8_bom_and_utf8_coding_line @ linux-x86_64 +test.test_source_encoding.MiscSourceEncodingTest.test_20731 @ linux-x86_64 +test.test_source_encoding.MiscSourceEncodingTest.test_bad_coding @ linux-x86_64 +test.test_source_encoding.MiscSourceEncodingTest.test_bad_coding2 @ linux-x86_64 +test.test_source_encoding.MiscSourceEncodingTest.test_compilestring @ linux-x86_64 +test.test_source_encoding.MiscSourceEncodingTest.test_error_message @ linux-x86_64 +test.test_source_encoding.MiscSourceEncodingTest.test_exec_valid_coding @ linux-x86_64 +test.test_source_encoding.MiscSourceEncodingTest.test_file_parse @ linux-x86_64 +test.test_source_encoding.MiscSourceEncodingTest.test_issue2301 @ linux-x86_64 +test.test_source_encoding.MiscSourceEncodingTest.test_issue3297 @ linux-x86_64 +test.test_source_encoding.MiscSourceEncodingTest.test_issue4626 @ linux-x86_64 +test.test_source_encoding.MiscSourceEncodingTest.test_issue7820 @ linux-x86_64 +test.test_source_encoding.MiscSourceEncodingTest.test_pep263 @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sqlite3.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sqlite3.txt new file mode 100644 index 0000000000..4f1f57421d --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sqlite3.txt @@ -0,0 +1,416 @@ +test.test_sqlite3.test_backup.BackupTests.test_bad_source_closed_connection @ linux-x86_64 +test.test_sqlite3.test_backup.BackupTests.test_bad_target @ linux-x86_64 +test.test_sqlite3.test_backup.BackupTests.test_bad_target_closed_connection @ linux-x86_64 +test.test_sqlite3.test_backup.BackupTests.test_bad_target_filename @ linux-x86_64 +test.test_sqlite3.test_backup.BackupTests.test_bad_target_in_transaction @ linux-x86_64 +test.test_sqlite3.test_backup.BackupTests.test_bad_target_same_connection @ linux-x86_64 +test.test_sqlite3.test_backup.BackupTests.test_database_source_name @ linux-x86_64 +test.test_sqlite3.test_backup.BackupTests.test_failing_progress @ linux-x86_64 +test.test_sqlite3.test_backup.BackupTests.test_keyword_only_args @ linux-x86_64 +test.test_sqlite3.test_backup.BackupTests.test_modifying_progress @ linux-x86_64 +test.test_sqlite3.test_backup.BackupTests.test_non_callable_progress @ linux-x86_64 +test.test_sqlite3.test_backup.BackupTests.test_progress @ linux-x86_64 +test.test_sqlite3.test_backup.BackupTests.test_progress_all_pages_at_once_1 @ linux-x86_64 +test.test_sqlite3.test_backup.BackupTests.test_progress_all_pages_at_once_2 @ linux-x86_64 +test.test_sqlite3.test_backup.BackupTests.test_simple @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_32bit_rowid @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_closed @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_closed_db_read @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_context_manager @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_context_manager_reraise_exceptions @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_get_empty_slice @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_get_item @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_get_item_error @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_get_slice @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_get_slice_negative_index @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_get_slice_with_skip @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_is_a_blob @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_length @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_mapping_invalid_index_type @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_open_error @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_read @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_read_advance_offset @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_read_at_offset @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_read_error_row_changed @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_read_oversized @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_seek_and_tell @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_seek_error @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_sequence_not_supported @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_set_empty_slice @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_set_item @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_set_item_error @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_set_item_negative_index @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_set_item_with_offset @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_set_slice @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_set_slice_buffer_object @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_set_slice_error @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_set_slice_with_skip @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_write @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_write_advance_offset @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_write_at_offset @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_write_error_length @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_write_error_readonly @ linux-x86_64 +test.test_sqlite3.test_dbapi.BlobTests.test_blob_write_error_row_changed @ linux-x86_64 +test.test_sqlite3.test_dbapi.ClosedConTests.test_closed_call @ linux-x86_64 +test.test_sqlite3.test_dbapi.ClosedConTests.test_closed_con_commit @ linux-x86_64 +test.test_sqlite3.test_dbapi.ClosedConTests.test_closed_con_cursor @ linux-x86_64 +test.test_sqlite3.test_dbapi.ClosedConTests.test_closed_con_rollback @ linux-x86_64 +test.test_sqlite3.test_dbapi.ClosedConTests.test_closed_create_aggregate @ linux-x86_64 +test.test_sqlite3.test_dbapi.ClosedConTests.test_closed_create_function @ linux-x86_64 +test.test_sqlite3.test_dbapi.ClosedConTests.test_closed_cur_execute @ linux-x86_64 +test.test_sqlite3.test_dbapi.ClosedConTests.test_closed_set_authorizer @ linux-x86_64 +test.test_sqlite3.test_dbapi.ClosedConTests.test_closed_set_progress_callback @ linux-x86_64 +test.test_sqlite3.test_dbapi.ClosedCurTests.test_closed @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_close @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_commit @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_commit_after_no_changes @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_connection_bad_limit_category @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_connection_bad_reinit @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_connection_exceptions @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_connection_init_bad_isolation_level @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_connection_init_good_isolation_levels @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_connection_limits @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_cursor @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_drop_unused_refs @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_exceptions @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_failed_open @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_in_transaction @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_in_transaction_ro @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_interrupt @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_interrupt_on_closed_db @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_rollback @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_rollback_after_no_changes @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConnectionTests.test_use_after_close @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConstructorTests.test_binary @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConstructorTests.test_date @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConstructorTests.test_date_from_ticks @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConstructorTests.test_time @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConstructorTests.test_time_from_ticks @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConstructorTests.test_timestamp @ linux-x86_64 +test.test_sqlite3.test_dbapi.ConstructorTests.test_timestamp_from_ticks @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_array_size @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_close @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_column_count @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_cursor_connection @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_cursor_wrong_class @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_arg_float @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_arg_int @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_arg_string @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_arg_string_with_zero_byte @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_dict_mapping @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_dict_mapping_mapping @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_dict_mapping_no_args @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_dict_mapping_too_little_args @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_dict_mapping_unnamed @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_illegal_sql @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_many_iterator @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_many_not_iterable @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_many_select @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_many_sequence @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_many_wrong_sql_arg @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_multiple_statements @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_no_args @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_non_iterable @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_param_list @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_param_sequence @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_param_sequence_bad_len @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_too_many_params @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_with_appended_comments @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_wrong_no_of_args1 @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_wrong_no_of_args2 @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_wrong_no_of_args3 @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_execute_wrong_sql_arg @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_fetch_iter @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_fetchall @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_fetchmany @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_fetchmany_kw_arg @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_fetchone @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_fetchone_no_statement @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_last_row_id_insert_o_r @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_last_row_id_on_ignore @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_last_row_id_on_replace @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_rowcount_execute @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_rowcount_executemany @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_rowcount_prefixed_with_comment @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_rowcount_select @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_rowcount_update_returning @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_rowcount_vaccuum @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_same_query_in_multiple_cursors @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_setinputsizes @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_setoutputsize @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_setoutputsize_no_column @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_total_changes @ linux-x86_64 +test.test_sqlite3.test_dbapi.CursorTests.test_wrong_cursor_callable @ linux-x86_64 +test.test_sqlite3.test_dbapi.ExtensionTests.test_connection_execute @ linux-x86_64 +test.test_sqlite3.test_dbapi.ExtensionTests.test_connection_executemany @ linux-x86_64 +test.test_sqlite3.test_dbapi.ExtensionTests.test_connection_executescript @ linux-x86_64 +test.test_sqlite3.test_dbapi.ExtensionTests.test_cursor_executescript_as_bytes @ linux-x86_64 +test.test_sqlite3.test_dbapi.ExtensionTests.test_cursor_executescript_too_large_script @ linux-x86_64 +test.test_sqlite3.test_dbapi.ExtensionTests.test_cursor_executescript_tx_control @ linux-x86_64 +test.test_sqlite3.test_dbapi.ExtensionTests.test_cursor_executescript_with_null_characters @ linux-x86_64 +test.test_sqlite3.test_dbapi.ExtensionTests.test_cursor_executescript_with_surrogates @ linux-x86_64 +test.test_sqlite3.test_dbapi.ExtensionTests.test_script_error_normal @ linux-x86_64 +test.test_sqlite3.test_dbapi.ExtensionTests.test_script_string_sql @ linux-x86_64 +test.test_sqlite3.test_dbapi.ExtensionTests.test_script_syntax_error @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_api_level @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_complete_statement @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_data_error @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_database_error @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_disallow_instantiation @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_error @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_error_code_on_exception @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_extended_error_code_on_exception @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_integrity_error @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_interface_error @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_internal_error @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_module_constants @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_not_supported_error @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_operational_error @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_param_style @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_programming_error @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_shared_cache_deprecated @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_thread_safety @ linux-x86_64 +test.test_sqlite3.test_dbapi.ModuleTests.test_warning @ linux-x86_64 +test.test_sqlite3.test_dbapi.MultiprocessTests.test_ctx_mgr_rollback_if_commit_failed @ linux-x86_64 +test.test_sqlite3.test_dbapi.OpenTests.test_database_keyword @ linux-x86_64 +test.test_sqlite3.test_dbapi.OpenTests.test_factory_database_arg @ linux-x86_64 +test.test_sqlite3.test_dbapi.OpenTests.test_open_undecodable_uri @ linux-x86_64 +test.test_sqlite3.test_dbapi.OpenTests.test_open_unquoted_uri @ linux-x86_64 +test.test_sqlite3.test_dbapi.OpenTests.test_open_uri @ linux-x86_64 +test.test_sqlite3.test_dbapi.OpenTests.test_open_uri_readonly @ linux-x86_64 +test.test_sqlite3.test_dbapi.OpenTests.test_open_with_path_like_object @ linux-x86_64 +test.test_sqlite3.test_dbapi.OpenTests.test_open_with_undecodable_path @ linux-x86_64 +test.test_sqlite3.test_dbapi.SqliteOnConflictTests.test_on_conflict_abort_raises_with_explicit_transactions @ linux-x86_64 +test.test_sqlite3.test_dbapi.SqliteOnConflictTests.test_on_conflict_abort_raises_without_transactions @ linux-x86_64 +test.test_sqlite3.test_dbapi.SqliteOnConflictTests.test_on_conflict_fail @ linux-x86_64 +test.test_sqlite3.test_dbapi.SqliteOnConflictTests.test_on_conflict_ignore @ linux-x86_64 +test.test_sqlite3.test_dbapi.SqliteOnConflictTests.test_on_conflict_replace @ linux-x86_64 +test.test_sqlite3.test_dbapi.SqliteOnConflictTests.test_on_conflict_rollback_with_explicit_transaction @ linux-x86_64 +test.test_sqlite3.test_dbapi.SqliteOnConflictTests.test_on_conflict_rollback_without_transaction @ linux-x86_64 +test.test_sqlite3.test_dbapi.ThreadTests.test_check_connection_thread @ linux-x86_64 +test.test_sqlite3.test_dbapi.ThreadTests.test_check_cursor_thread @ linux-x86_64 +test.test_sqlite3.test_dbapi.ThreadTests.test_dont_check_same_thread @ linux-x86_64 +test.test_sqlite3.test_dbapi.UninitialisedConnectionTests.test_uninit_operations @ linux-x86_64 +test.test_sqlite3.test_dump.DumpTests.test_dump_autoincrement @ linux-x86_64 +test.test_sqlite3.test_dump.DumpTests.test_table_dump @ linux-x86_64 +test.test_sqlite3.test_dump.DumpTests.test_unorderable_row @ linux-x86_64 +test.test_sqlite3.test_factory.ConnectionFactoryTests.test_connection_factories @ linux-x86_64 +test.test_sqlite3.test_factory.ConnectionFactoryTests.test_connection_factory_as_positional_arg @ linux-x86_64 +test.test_sqlite3.test_factory.ConnectionFactoryTests.test_connection_factory_relayed_call @ linux-x86_64 +test.test_sqlite3.test_factory.CursorFactoryTests.test_invalid_factory @ linux-x86_64 +test.test_sqlite3.test_factory.CursorFactoryTests.test_is_instance @ linux-x86_64 +test.test_sqlite3.test_factory.RowFactoryTests.test_custom_factory @ linux-x86_64 +test.test_sqlite3.test_factory.RowFactoryTests.test_fake_cursor_class @ linux-x86_64 +test.test_sqlite3.test_factory.RowFactoryTests.test_sqlite_row_as_dict @ linux-x86_64 +test.test_sqlite3.test_factory.RowFactoryTests.test_sqlite_row_as_sequence @ linux-x86_64 +test.test_sqlite3.test_factory.RowFactoryTests.test_sqlite_row_as_tuple @ linux-x86_64 +test.test_sqlite3.test_factory.RowFactoryTests.test_sqlite_row_hash_cmp @ linux-x86_64 +test.test_sqlite3.test_factory.RowFactoryTests.test_sqlite_row_index @ linux-x86_64 +test.test_sqlite3.test_factory.RowFactoryTests.test_sqlite_row_index_unicode @ linux-x86_64 +test.test_sqlite3.test_factory.RowFactoryTests.test_sqlite_row_iter @ linux-x86_64 +test.test_sqlite3.test_factory.RowFactoryTests.test_sqlite_row_keys @ linux-x86_64 +test.test_sqlite3.test_factory.RowFactoryTests.test_sqlite_row_slice @ linux-x86_64 +test.test_sqlite3.test_factory.RowFactoryTestsBackwardsCompat.test_is_produced_by_factory @ linux-x86_64 +test.test_sqlite3.test_factory.TextFactoryTests.test_custom @ linux-x86_64 +test.test_sqlite3.test_factory.TextFactoryTests.test_optimized_unicode @ linux-x86_64 +test.test_sqlite3.test_factory.TextFactoryTests.test_string @ linux-x86_64 +test.test_sqlite3.test_factory.TextFactoryTests.test_unicode @ linux-x86_64 +test.test_sqlite3.test_factory.TextFactoryTestsWithEmbeddedZeroBytes.test_bytearray @ linux-x86_64 +test.test_sqlite3.test_factory.TextFactoryTestsWithEmbeddedZeroBytes.test_bytes @ linux-x86_64 +test.test_sqlite3.test_factory.TextFactoryTestsWithEmbeddedZeroBytes.test_custom @ linux-x86_64 +test.test_sqlite3.test_factory.TextFactoryTestsWithEmbeddedZeroBytes.test_string @ linux-x86_64 +test.test_sqlite3.test_hooks.CollationTests.test_collation_is_used @ linux-x86_64 +test.test_sqlite3.test_hooks.CollationTests.test_collation_register_twice @ linux-x86_64 +test.test_sqlite3.test_hooks.CollationTests.test_collation_returns_large_integer @ linux-x86_64 +test.test_sqlite3.test_hooks.CollationTests.test_create_collation_bad_upper @ linux-x86_64 +test.test_sqlite3.test_hooks.CollationTests.test_create_collation_not_ascii @ linux-x86_64 +test.test_sqlite3.test_hooks.CollationTests.test_create_collation_not_callable @ linux-x86_64 +test.test_sqlite3.test_hooks.CollationTests.test_create_collation_not_string @ linux-x86_64 +test.test_sqlite3.test_hooks.CollationTests.test_deregister_collation @ linux-x86_64 +test.test_sqlite3.test_hooks.ProgressTests.test_cancel_operation @ linux-x86_64 +test.test_sqlite3.test_hooks.ProgressTests.test_clear_handler @ linux-x86_64 +test.test_sqlite3.test_hooks.ProgressTests.test_error_in_progress_handler @ linux-x86_64 +test.test_sqlite3.test_hooks.ProgressTests.test_error_in_progress_handler_result @ linux-x86_64 +test.test_sqlite3.test_hooks.ProgressTests.test_opcode_count @ linux-x86_64 +test.test_sqlite3.test_hooks.ProgressTests.test_progress_handler_used @ linux-x86_64 +test.test_sqlite3.test_hooks.TraceCallbackTests.test_clear_trace_callback @ linux-x86_64 +test.test_sqlite3.test_hooks.TraceCallbackTests.test_trace_bad_handler @ linux-x86_64 +test.test_sqlite3.test_hooks.TraceCallbackTests.test_trace_callback_content @ linux-x86_64 +test.test_sqlite3.test_hooks.TraceCallbackTests.test_trace_callback_used @ linux-x86_64 +test.test_sqlite3.test_hooks.TraceCallbackTests.test_trace_too_much_expanded_sql @ linux-x86_64 +test.test_sqlite3.test_hooks.TraceCallbackTests.test_unicode_content @ linux-x86_64 +test.test_sqlite3.test_regression.RecursiveUseOfCursors.test_recursive_cursor_close @ linux-x86_64 +test.test_sqlite3.test_regression.RecursiveUseOfCursors.test_recursive_cursor_init @ linux-x86_64 +test.test_sqlite3.test_regression.RecursiveUseOfCursors.test_recursive_cursor_iter @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_auto_commit @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_bind_mutating_list @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_bpo31770 @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_bpo37347 @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_collation @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_column_name_with_spaces @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_commit_cursor_reset @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_connection_call @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_connection_constructor_call_check @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_convert_timestamp_microsecond_padding @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_cursor_constructor_call_check @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_custom_cursor_object_crash_gh_99886 @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_del_isolation_level_segfault @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_empty_statement @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_executescript_step_through_select @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_invalid_isolation_level_type @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_large_sql @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_null_character @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_on_conflict_rollback @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_pragma_autocommit @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_pragma_schema_version @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_pragma_user_version @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_recursive_cursor_use @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_register_adapter @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_return_empty_bytestring @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_set_isolation_level @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_statement_finalization_on_close_db @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_statement_reset @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_str_subclass @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_surrogates @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_type_map_usage @ linux-x86_64 +test.test_sqlite3.test_regression.RegressionTests.test_workaround_for_buggy_sqlite_transfer_bindings @ linux-x86_64 +test.test_sqlite3.test_transactions.IsolationLevelFromInit.test_isolation_level_begin @ linux-x86_64 +test.test_sqlite3.test_transactions.IsolationLevelFromInit.test_isolation_level_default @ linux-x86_64 +test.test_sqlite3.test_transactions.IsolationLevelFromInit.test_isolation_level_deferred @ linux-x86_64 +test.test_sqlite3.test_transactions.IsolationLevelFromInit.test_isolation_level_exclusive @ linux-x86_64 +test.test_sqlite3.test_transactions.IsolationLevelFromInit.test_isolation_level_immediate @ linux-x86_64 +test.test_sqlite3.test_transactions.IsolationLevelFromInit.test_isolation_level_none @ linux-x86_64 +test.test_sqlite3.test_transactions.IsolationLevelPostInit.test_isolation_level_begin @ linux-x86_64 +test.test_sqlite3.test_transactions.IsolationLevelPostInit.test_isolation_level_default @ linux-x86_64 +test.test_sqlite3.test_transactions.IsolationLevelPostInit.test_isolation_level_deferrred @ linux-x86_64 +test.test_sqlite3.test_transactions.IsolationLevelPostInit.test_isolation_level_exclusive @ linux-x86_64 +test.test_sqlite3.test_transactions.IsolationLevelPostInit.test_isolation_level_immediate @ linux-x86_64 +test.test_sqlite3.test_transactions.IsolationLevelPostInit.test_isolation_level_none @ linux-x86_64 +test.test_sqlite3.test_transactions.RollbackTests.test_no_duplicate_rows_after_rollback_close_cursor @ linux-x86_64 +test.test_sqlite3.test_transactions.RollbackTests.test_no_duplicate_rows_after_rollback_del_cursor @ linux-x86_64 +test.test_sqlite3.test_transactions.RollbackTests.test_no_duplicate_rows_after_rollback_new_query @ linux-x86_64 +test.test_sqlite3.test_transactions.SpecialCommandTests.test_drop_table @ linux-x86_64 +test.test_sqlite3.test_transactions.SpecialCommandTests.test_pragma @ linux-x86_64 +test.test_sqlite3.test_transactions.TransactionTests.test_delete_starts_transaction @ linux-x86_64 +test.test_sqlite3.test_transactions.TransactionTests.test_dml_does_not_auto_commit_before @ linux-x86_64 +test.test_sqlite3.test_transactions.TransactionTests.test_insert_starts_transaction @ linux-x86_64 +test.test_sqlite3.test_transactions.TransactionTests.test_locking @ linux-x86_64 +test.test_sqlite3.test_transactions.TransactionTests.test_multiple_cursors_and_iternext @ linux-x86_64 +test.test_sqlite3.test_transactions.TransactionTests.test_raise_timeout @ linux-x86_64 +test.test_sqlite3.test_transactions.TransactionTests.test_replace_starts_transaction @ linux-x86_64 +test.test_sqlite3.test_transactions.TransactionTests.test_rollback_cursor_consistency @ linux-x86_64 +test.test_sqlite3.test_transactions.TransactionTests.test_toggle_auto_commit @ linux-x86_64 +test.test_sqlite3.test_transactions.TransactionTests.test_update_starts_transaction @ linux-x86_64 +test.test_sqlite3.test_transactions.TransactionalDDL.test_ddl_does_not_autostart_transaction @ linux-x86_64 +test.test_sqlite3.test_transactions.TransactionalDDL.test_immediate_transactional_ddl @ linux-x86_64 +test.test_sqlite3.test_transactions.TransactionalDDL.test_transactional_ddl @ linux-x86_64 +test.test_sqlite3.test_types.BinaryConverterTests.test_binary_input_for_converter @ linux-x86_64 +test.test_sqlite3.test_types.ColNamesTests.test_case_in_converter_name @ linux-x86_64 +test.test_sqlite3.test_types.ColNamesTests.test_col_name @ linux-x86_64 +test.test_sqlite3.test_types.ColNamesTests.test_cursor_description_insert @ linux-x86_64 +test.test_sqlite3.test_types.ColNamesTests.test_cursor_description_no_row @ linux-x86_64 +test.test_sqlite3.test_types.ColNamesTests.test_decl_type_not_used @ linux-x86_64 +test.test_sqlite3.test_types.ColNamesTests.test_none @ linux-x86_64 +test.test_sqlite3.test_types.CommonTableExpressionTests.test_cursor_description_cte @ linux-x86_64 +test.test_sqlite3.test_types.CommonTableExpressionTests.test_cursor_description_cte_multiple_columns @ linux-x86_64 +test.test_sqlite3.test_types.CommonTableExpressionTests.test_cursor_description_cte_simple @ linux-x86_64 +test.test_sqlite3.test_types.DateTimeTests.test_date_time_sub_seconds @ linux-x86_64 +test.test_sqlite3.test_types.DateTimeTests.test_date_time_sub_seconds_floating_point @ linux-x86_64 +test.test_sqlite3.test_types.DateTimeTests.test_sql_timestamp @ linux-x86_64 +test.test_sqlite3.test_types.DateTimeTests.test_sqlite_date @ linux-x86_64 +test.test_sqlite3.test_types.DateTimeTests.test_sqlite_timestamp @ linux-x86_64 +test.test_sqlite3.test_types.DeclTypesTests.test_blob @ linux-x86_64 +test.test_sqlite3.test_types.DeclTypesTests.test_bool @ linux-x86_64 +test.test_sqlite3.test_types.DeclTypesTests.test_convert_zero_sized_blob @ linux-x86_64 +test.test_sqlite3.test_types.DeclTypesTests.test_error_in_conform @ linux-x86_64 +test.test_sqlite3.test_types.DeclTypesTests.test_float @ linux-x86_64 +test.test_sqlite3.test_types.DeclTypesTests.test_foo @ linux-x86_64 +test.test_sqlite3.test_types.DeclTypesTests.test_large_int @ linux-x86_64 +test.test_sqlite3.test_types.DeclTypesTests.test_number1 @ linux-x86_64 +test.test_sqlite3.test_types.DeclTypesTests.test_number2 @ linux-x86_64 +test.test_sqlite3.test_types.DeclTypesTests.test_small_int @ linux-x86_64 +test.test_sqlite3.test_types.DeclTypesTests.test_string @ linux-x86_64 +test.test_sqlite3.test_types.DeclTypesTests.test_unicode @ linux-x86_64 +test.test_sqlite3.test_types.DeclTypesTests.test_unsupported_dict @ linux-x86_64 +test.test_sqlite3.test_types.DeclTypesTests.test_unsupported_seq @ linux-x86_64 +test.test_sqlite3.test_types.ObjectAdaptationTests.test_adapt @ linux-x86_64 +test.test_sqlite3.test_types.ObjectAdaptationTests.test_adapt_alt @ linux-x86_64 +test.test_sqlite3.test_types.ObjectAdaptationTests.test_caster_is_used @ linux-x86_64 +test.test_sqlite3.test_types.ObjectAdaptationTests.test_custom_proto @ linux-x86_64 +test.test_sqlite3.test_types.ObjectAdaptationTests.test_defect_proto @ linux-x86_64 +test.test_sqlite3.test_types.ObjectAdaptationTests.test_defect_self_adapt @ linux-x86_64 +test.test_sqlite3.test_types.ObjectAdaptationTests.test_missing_adapter @ linux-x86_64 +test.test_sqlite3.test_types.ObjectAdaptationTests.test_missing_protocol @ linux-x86_64 +test.test_sqlite3.test_types.SqliteTypeTests.test_blob @ linux-x86_64 +test.test_sqlite3.test_types.SqliteTypeTests.test_float @ linux-x86_64 +test.test_sqlite3.test_types.SqliteTypeTests.test_large_int @ linux-x86_64 +test.test_sqlite3.test_types.SqliteTypeTests.test_small_int @ linux-x86_64 +test.test_sqlite3.test_types.SqliteTypeTests.test_string @ linux-x86_64 +test.test_sqlite3.test_types.SqliteTypeTests.test_string_with_null_character @ linux-x86_64 +test.test_sqlite3.test_types.SqliteTypeTests.test_string_with_surrogates @ linux-x86_64 +test.test_sqlite3.test_types.SqliteTypeTests.test_too_large_int @ linux-x86_64 +test.test_sqlite3.test_types.SqliteTypeTests.test_unicode_execute @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AggregateTests.test_aggr_check_aggr_sum @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AggregateTests.test_aggr_check_param_blob @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AggregateTests.test_aggr_check_param_float @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AggregateTests.test_aggr_check_param_int @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AggregateTests.test_aggr_check_param_none @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AggregateTests.test_aggr_check_param_str @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AggregateTests.test_aggr_check_params_int @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AggregateTests.test_aggr_error_on_create @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AggregateTests.test_aggr_exception_in_finalize @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AggregateTests.test_aggr_exception_in_init @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AggregateTests.test_aggr_exception_in_step @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AggregateTests.test_aggr_no_finalize @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AggregateTests.test_aggr_no_match @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AggregateTests.test_aggr_no_step @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AggregateTests.test_aggr_text @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AuthorizerIllegalTypeTests.test_clear_authorizer @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AuthorizerIllegalTypeTests.test_column_access @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AuthorizerIllegalTypeTests.test_table_access @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AuthorizerLargeIntegerTests.test_clear_authorizer @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AuthorizerLargeIntegerTests.test_column_access @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AuthorizerLargeIntegerTests.test_table_access @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AuthorizerRaiseExceptionTests.test_clear_authorizer @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AuthorizerRaiseExceptionTests.test_column_access @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AuthorizerRaiseExceptionTests.test_table_access @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AuthorizerTests.test_clear_authorizer @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AuthorizerTests.test_column_access @ linux-x86_64 +test.test_sqlite3.test_userfunctions.AuthorizerTests.test_table_access @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_any_arguments @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_empty_blob @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_deterministic @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_deterministic_keyword_only @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_error_on_create @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_exception @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_memory_error @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_non_deterministic @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_overflow_error @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_params @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_ref_count @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_return_blob @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_return_float @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_return_illegal_value @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_return_int @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_return_long_long @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_return_nan @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_return_null @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_return_text @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_return_text_with_null_char @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_return_too_large_int @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_return_unicode @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_func_too_many_args @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_function_destructor_via_gc @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_nan_float @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_non_contiguous_blob @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_return_non_contiguous_blob @ linux-x86_64 +test.test_sqlite3.test_userfunctions.FunctionTests.test_too_large_int @ linux-x86_64 +test.test_sqlite3.test_userfunctions.WindowFunctionTests.test_win_clear_function @ linux-x86_64 +test.test_sqlite3.test_userfunctions.WindowFunctionTests.test_win_error_on_create @ linux-x86_64 +test.test_sqlite3.test_userfunctions.WindowFunctionTests.test_win_error_value_return @ linux-x86_64 +test.test_sqlite3.test_userfunctions.WindowFunctionTests.test_win_exception_in_finalize @ linux-x86_64 +test.test_sqlite3.test_userfunctions.WindowFunctionTests.test_win_exception_in_method @ linux-x86_64 +test.test_sqlite3.test_userfunctions.WindowFunctionTests.test_win_missing_finalize @ linux-x86_64 +test.test_sqlite3.test_userfunctions.WindowFunctionTests.test_win_missing_method @ linux-x86_64 +test.test_sqlite3.test_userfunctions.WindowFunctionTests.test_win_redefine_function @ linux-x86_64 +test.test_sqlite3.test_userfunctions.WindowFunctionTests.test_win_sum_int @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ssl.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ssl.txt new file mode 100644 index 0000000000..2260f5510b --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ssl.txt @@ -0,0 +1,108 @@ +test.test_ssl.BasicSocketTests.test_DER_to_PEM @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_cert_time_to_seconds @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_connect_ex_error @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_empty_cert @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_errors_sslwrap @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_get_default_verify_paths @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_malformed_cert @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_malformed_key @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_parse_cert @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_parse_cert_CVE_2019_5010 @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_private_init @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_purpose_enum @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_read_write_zero @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_server_side @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_str_for_enums @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_timeout @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_unknown_channel_binding @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_unsupported_dtls @ linux-x86_64 +test.test_ssl.BasicSocketTests.test_wrapped_unconnected @ linux-x86_64 +test.test_ssl.ContextTests.test__create_stdlib_context @ linux-x86_64 +test.test_ssl.ContextTests.test_cert_store_stats @ linux-x86_64 +test.test_ssl.ContextTests.test_check_hostname @ linux-x86_64 +test.test_ssl.ContextTests.test_ciphers @ linux-x86_64 +test.test_ssl.ContextTests.test_constructor @ linux-x86_64 +test.test_ssl.ContextTests.test_context_client_server @ linux-x86_64 +test.test_ssl.ContextTests.test_context_custom_class @ linux-x86_64 +test.test_ssl.ContextTests.test_create_default_context @ linux-x86_64 +test.test_ssl.ContextTests.test_get_ca_certs @ linux-x86_64 +test.test_ssl.ContextTests.test_get_ciphers @ linux-x86_64 +test.test_ssl.ContextTests.test_hostname_checks_common_name @ linux-x86_64 +test.test_ssl.ContextTests.test_load_cert_chain @ linux-x86_64 +test.test_ssl.ContextTests.test_load_default_certs @ linux-x86_64 +test.test_ssl.ContextTests.test_load_default_certs_env @ linux-x86_64 +test.test_ssl.ContextTests.test_load_verify_cadata @ linux-x86_64 +test.test_ssl.ContextTests.test_load_verify_locations @ linux-x86_64 +test.test_ssl.ContextTests.test_min_max_version @ linux-x86_64 +test.test_ssl.ContextTests.test_options @ linux-x86_64 +test.test_ssl.ContextTests.test_set_default_verify_paths @ linux-x86_64 +test.test_ssl.ContextTests.test_verify_mode_protocol @ linux-x86_64 +test.test_ssl.MemoryBIOTests.test_buffer_types @ linux-x86_64 +test.test_ssl.MemoryBIOTests.test_eof @ linux-x86_64 +test.test_ssl.MemoryBIOTests.test_error_types @ linux-x86_64 +test.test_ssl.MemoryBIOTests.test_pending @ linux-x86_64 +test.test_ssl.MemoryBIOTests.test_read_write @ linux-x86_64 +test.test_ssl.SSLErrorTests.test_bad_server_hostname @ linux-x86_64 +test.test_ssl.SSLErrorTests.test_str @ linux-x86_64 +test.test_ssl.SSLErrorTests.test_subclass @ linux-x86_64 +test.test_ssl.SSLObjectTests.test_private_init @ linux-x86_64 +test.test_ssl.SSLObjectTests.test_unwrap @ linux-x86_64 +test.test_ssl.SimpleBackgroundTests.test_bio_handshake @ linux-x86_64 +test.test_ssl.SimpleBackgroundTests.test_bio_read_write_data @ linux-x86_64 +test.test_ssl.SimpleBackgroundTests.test_ciphers @ linux-x86_64 +test.test_ssl.SimpleBackgroundTests.test_connect_cadata @ linux-x86_64 +test.test_ssl.SimpleBackgroundTests.test_connect_capath @ linux-x86_64 +test.test_ssl.SimpleBackgroundTests.test_connect_ex @ linux-x86_64 +test.test_ssl.SimpleBackgroundTests.test_connect_fail @ linux-x86_64 +test.test_ssl.SimpleBackgroundTests.test_connect_with_context_fail @ linux-x86_64 +test.test_ssl.SimpleBackgroundTests.test_get_server_certificate @ linux-x86_64 +test.test_ssl.SimpleBackgroundTests.test_get_server_certificate_fail @ linux-x86_64 +test.test_ssl.SimpleBackgroundTests.test_makefile_close @ linux-x86_64 +test.test_ssl.SimpleBackgroundTests.test_non_blocking_connect_ex @ linux-x86_64 +test.test_ssl.SimpleBackgroundTests.test_non_blocking_handshake @ linux-x86_64 +test.test_ssl.SimpleBackgroundTests.test_transport_eof @ linux-x86_64 +test.test_ssl.TestEnumerations.test_alertdescription @ linux-x86_64 +test.test_ssl.TestEnumerations.test_options @ linux-x86_64 +test.test_ssl.TestEnumerations.test_sslerrornumber @ linux-x86_64 +test.test_ssl.TestEnumerations.test_sslmethod @ linux-x86_64 +test.test_ssl.TestEnumerations.test_tlsalerttype @ linux-x86_64 +test.test_ssl.TestEnumerations.test_tlscontenttype @ linux-x86_64 +test.test_ssl.TestEnumerations.test_tlsmessagetype @ linux-x86_64 +test.test_ssl.TestEnumerations.test_tlsversion @ linux-x86_64 +test.test_ssl.TestEnumerations.test_verifyflags @ linux-x86_64 +test.test_ssl.TestEnumerations.test_verifymode @ linux-x86_64 +test.test_ssl.TestPreHandshakeClose.test_https_client_non_tls_response_ignored @ linux-x86_64 +test.test_ssl.TestPreHandshakeClose.test_preauth_data_to_tls_client @ linux-x86_64 +test.test_ssl.TestPreHandshakeClose.test_preauth_data_to_tls_server @ linux-x86_64 +test.test_ssl.ThreadedTests.test_asyncore_server @ linux-x86_64 +test.test_ssl.ThreadedTests.test_check_hostname @ linux-x86_64 +test.test_ssl.ThreadedTests.test_check_hostname_idn @ linux-x86_64 +test.test_ssl.ThreadedTests.test_compression @ linux-x86_64 +test.test_ssl.ThreadedTests.test_compression_disabled @ linux-x86_64 +test.test_ssl.ThreadedTests.test_crl_check @ linux-x86_64 +test.test_ssl.ThreadedTests.test_default_ecdh_curve @ linux-x86_64 +test.test_ssl.ThreadedTests.test_do_handshake_enotconn @ linux-x86_64 +test.test_ssl.ThreadedTests.test_dual_rsa_ecc @ linux-x86_64 +test.test_ssl.ThreadedTests.test_ecc_cert @ linux-x86_64 +test.test_ssl.ThreadedTests.test_getpeercert @ linux-x86_64 +test.test_ssl.ThreadedTests.test_getpeercert_enotconn @ linux-x86_64 +test.test_ssl.ThreadedTests.test_handshake_timeout @ linux-x86_64 +test.test_ssl.ThreadedTests.test_nonblocking_send @ linux-x86_64 +test.test_ssl.ThreadedTests.test_npn_protocols @ linux-x86_64 +test.test_ssl.ThreadedTests.test_read_write_after_close_raises_valuerror @ linux-x86_64 +test.test_ssl.ThreadedTests.test_recv_into_buffer_protocol_len @ linux-x86_64 +test.test_ssl.ThreadedTests.test_recv_send @ linux-x86_64 +test.test_ssl.ThreadedTests.test_recv_zero @ linux-x86_64 +test.test_ssl.ThreadedTests.test_rude_shutdown @ linux-x86_64 +test.test_ssl.ThreadedTests.test_selected_alpn_protocol @ linux-x86_64 +test.test_ssl.ThreadedTests.test_selected_alpn_protocol_if_server_uses_alpn @ linux-x86_64 +test.test_ssl.ThreadedTests.test_sendfile @ linux-x86_64 +test.test_ssl.ThreadedTests.test_server_accept @ linux-x86_64 +test.test_ssl.ThreadedTests.test_shared_ciphers @ linux-x86_64 +test.test_ssl.ThreadedTests.test_socketserver @ linux-x86_64 +test.test_ssl.ThreadedTests.test_ssl_cert_verify_error @ linux-x86_64 +test.test_ssl.ThreadedTests.test_starttls @ linux-x86_64 +test.test_ssl.ThreadedTests.test_tls1_3 @ linux-x86_64 +test.test_ssl.ThreadedTests.test_version_basic @ linux-x86_64 +test.test_ssl.ThreadedTests.test_wrong_cert_tls12 @ linux-x86_64 +test.test_ssl.ThreadedTests.test_wrong_cert_tls13 @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_stat.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_stat.txt new file mode 100644 index 0000000000..99820f262d --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_stat.txt @@ -0,0 +1,5 @@ +test.test_stat.TestFilemodePyStat.test_devices @ linux-x86_64 +test.test_stat.TestFilemodePyStat.test_directory @ linux-x86_64 +test.test_stat.TestFilemodePyStat.test_link @ linux-x86_64 +test.test_stat.TestFilemodePyStat.test_mode @ linux-x86_64 +test.test_stat.TestFilemodePyStat.test_module_attributes @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_statistics.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_statistics.txt new file mode 100644 index 0000000000..e7c8591ed5 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_statistics.txt @@ -0,0 +1,347 @@ +DocTestCase.test.test_statistics.NumericTestCase.assertApproxEqual @ linux-x86_64 +DocTestCase.test.test_statistics._DoNothing @ linux-x86_64 +DocTestCase.test.test_statistics._calc_errors @ linux-x86_64 +DocTestCase.test.test_statistics._nan_equal @ linux-x86_64 +DocTestCase.test.test_statistics.approx_equal @ linux-x86_64 +test.test_statistics.ApproxEqualExactTest.test_exactly_equal_absolute @ linux-x86_64 +test.test_statistics.ApproxEqualExactTest.test_exactly_equal_absolute_decimals @ linux-x86_64 +test.test_statistics.ApproxEqualExactTest.test_exactly_equal_both @ linux-x86_64 +test.test_statistics.ApproxEqualExactTest.test_exactly_equal_decimals @ linux-x86_64 +test.test_statistics.ApproxEqualExactTest.test_exactly_equal_floats @ linux-x86_64 +test.test_statistics.ApproxEqualExactTest.test_exactly_equal_fractions @ linux-x86_64 +test.test_statistics.ApproxEqualExactTest.test_exactly_equal_ints @ linux-x86_64 +test.test_statistics.ApproxEqualExactTest.test_exactly_equal_relative @ linux-x86_64 +test.test_statistics.ApproxEqualInexactTest.test_approx_equal_absolute_decimals @ linux-x86_64 +test.test_statistics.ApproxEqualInexactTest.test_approx_equal_absolute_floats @ linux-x86_64 +test.test_statistics.ApproxEqualInexactTest.test_approx_equal_absolute_fractions @ linux-x86_64 +test.test_statistics.ApproxEqualInexactTest.test_approx_equal_absolute_ints @ linux-x86_64 +test.test_statistics.ApproxEqualInexactTest.test_approx_equal_both1 @ linux-x86_64 +test.test_statistics.ApproxEqualInexactTest.test_approx_equal_both2 @ linux-x86_64 +test.test_statistics.ApproxEqualInexactTest.test_approx_equal_both3 @ linux-x86_64 +test.test_statistics.ApproxEqualInexactTest.test_approx_equal_both4 @ linux-x86_64 +test.test_statistics.ApproxEqualInexactTest.test_approx_equal_relative_decimals @ linux-x86_64 +test.test_statistics.ApproxEqualInexactTest.test_approx_equal_relative_floats @ linux-x86_64 +test.test_statistics.ApproxEqualInexactTest.test_approx_equal_relative_fractions @ linux-x86_64 +test.test_statistics.ApproxEqualInexactTest.test_approx_equal_relative_ints @ linux-x86_64 +test.test_statistics.ApproxEqualInexactTest.test_cross_zero @ linux-x86_64 +test.test_statistics.ApproxEqualSpecialsTest.test_decimal_zeroes @ linux-x86_64 +test.test_statistics.ApproxEqualSpecialsTest.test_float_zeroes @ linux-x86_64 +test.test_statistics.ApproxEqualSpecialsTest.test_inf @ linux-x86_64 +test.test_statistics.ApproxEqualSpecialsTest.test_nan @ linux-x86_64 +test.test_statistics.ApproxEqualSymmetryTest.test_relative_symmetry @ linux-x86_64 +test.test_statistics.ApproxEqualSymmetryTest.test_symmetry @ linux-x86_64 +test.test_statistics.ApproxEqualUnequalTest.test_exactly_unequal_decimals @ linux-x86_64 +test.test_statistics.ApproxEqualUnequalTest.test_exactly_unequal_floats @ linux-x86_64 +test.test_statistics.ApproxEqualUnequalTest.test_exactly_unequal_fractions @ linux-x86_64 +test.test_statistics.ApproxEqualUnequalTest.test_exactly_unequal_ints @ linux-x86_64 +test.test_statistics.CoerceTest.test_bool @ linux-x86_64 +test.test_statistics.CoerceTest.test_decimal @ linux-x86_64 +test.test_statistics.CoerceTest.test_float @ linux-x86_64 +test.test_statistics.CoerceTest.test_fraction @ linux-x86_64 +test.test_statistics.CoerceTest.test_incompatible_types @ linux-x86_64 +test.test_statistics.CoerceTest.test_int @ linux-x86_64 +test.test_statistics.CoerceTest.test_non_numeric_types @ linux-x86_64 +test.test_statistics.ConvertTest.test_decimal @ linux-x86_64 +test.test_statistics.ConvertTest.test_float @ linux-x86_64 +test.test_statistics.ConvertTest.test_fraction @ linux-x86_64 +test.test_statistics.ConvertTest.test_inf @ linux-x86_64 +test.test_statistics.ConvertTest.test_int @ linux-x86_64 +test.test_statistics.ConvertTest.test_invalid_input_type @ linux-x86_64 +test.test_statistics.ConvertTest.test_nan @ linux-x86_64 +test.test_statistics.DecimalToRatioTest.test_infinity @ linux-x86_64 +test.test_statistics.DecimalToRatioTest.test_nan @ linux-x86_64 +test.test_statistics.DecimalToRatioTest.test_negative_exponent @ linux-x86_64 +test.test_statistics.DecimalToRatioTest.test_positive_exponent @ linux-x86_64 +test.test_statistics.DecimalToRatioTest.test_regression_20536 @ linux-x86_64 +test.test_statistics.DecimalToRatioTest.test_sign @ linux-x86_64 +test.test_statistics.DocTests.test_doc_tests @ linux-x86_64 +test.test_statistics.ExactRatioTest.test_decimal @ linux-x86_64 +test.test_statistics.ExactRatioTest.test_decimal_nan @ linux-x86_64 +test.test_statistics.ExactRatioTest.test_float @ linux-x86_64 +test.test_statistics.ExactRatioTest.test_float_nan @ linux-x86_64 +test.test_statistics.ExactRatioTest.test_fraction @ linux-x86_64 +test.test_statistics.ExactRatioTest.test_inf @ linux-x86_64 +test.test_statistics.ExactRatioTest.test_int @ linux-x86_64 +test.test_statistics.FailNegTest.test_error_msg @ linux-x86_64 +test.test_statistics.FailNegTest.test_negatives_raise @ linux-x86_64 +test.test_statistics.FailNegTest.test_pass_through @ linux-x86_64 +test.test_statistics.GlobalsTest.test_check_all @ linux-x86_64 +test.test_statistics.GlobalsTest.test_meta @ linux-x86_64 +test.test_statistics.IsFiniteTest.test_finite @ linux-x86_64 +test.test_statistics.IsFiniteTest.test_infinity @ linux-x86_64 +test.test_statistics.IsFiniteTest.test_nan @ linux-x86_64 +test.test_statistics.StatisticsErrorTest.test_has_exception @ linux-x86_64 +test.test_statistics.SumSpecialValues.test_decimal_basiccontext_mismatched_infs_to_nan @ linux-x86_64 +test.test_statistics.SumSpecialValues.test_decimal_extendedcontext_mismatched_infs_to_nan @ linux-x86_64 +test.test_statistics.SumSpecialValues.test_decimal_inf @ linux-x86_64 +test.test_statistics.SumSpecialValues.test_decimal_snan_raises @ linux-x86_64 +test.test_statistics.SumSpecialValues.test_float_inf @ linux-x86_64 +test.test_statistics.SumSpecialValues.test_float_mismatched_infs @ linux-x86_64 +test.test_statistics.SumSpecialValues.test_nan @ linux-x86_64 +test.test_statistics.SumTortureTest.test_torture @ linux-x86_64 +test.test_statistics.TestApproxEqualErrors.test_bad_rel @ linux-x86_64 +test.test_statistics.TestApproxEqualErrors.test_bad_tol @ linux-x86_64 +test.test_statistics.TestBivariateStatistics.test_small_sample_error @ linux-x86_64 +test.test_statistics.TestBivariateStatistics.test_unequal_size_error @ linux-x86_64 +test.test_statistics.TestCorrelationAndCovariance.test_different_scales @ linux-x86_64 +test.test_statistics.TestCorrelationAndCovariance.test_results @ linux-x86_64 +test.test_statistics.TestFMean.test_basics @ linux-x86_64 +test.test_statistics.TestFMean.test_error_cases @ linux-x86_64 +test.test_statistics.TestFMean.test_special_values @ linux-x86_64 +test.test_statistics.TestFMean.test_weights @ linux-x86_64 +test.test_statistics.TestGeometricMean.test_basics @ linux-x86_64 +test.test_statistics.TestGeometricMean.test_big_and_small @ linux-x86_64 +test.test_statistics.TestGeometricMean.test_mixed_int_and_float @ linux-x86_64 +test.test_statistics.TestGeometricMean.test_special_values @ linux-x86_64 +test.test_statistics.TestGeometricMean.test_various_input_types @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_bad_arg_types @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_decimals_exact @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_doubled_data @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_empty_data @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_floats_exact @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_fractions @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_inf @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_ints @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_invalid_type_error @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_multiply_data_points @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_nan @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_negative_error @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_no_args @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_no_inplace_modifications @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_order_doesnt_matter @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_range_data @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_repeated_single_value @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_single_value @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_singleton_lists @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_type_of_data_collection @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_type_of_data_element @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_types_conserved @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_with_weights @ linux-x86_64 +test.test_statistics.TestHarmonicMean.test_zero @ linux-x86_64 +test.test_statistics.TestLinearRegression.test_constant_input_error @ linux-x86_64 +test.test_statistics.TestLinearRegression.test_proportional @ linux-x86_64 +test.test_statistics.TestLinearRegression.test_results @ linux-x86_64 +test.test_statistics.TestMean.test_bad_arg_types @ linux-x86_64 +test.test_statistics.TestMean.test_big_data @ linux-x86_64 +test.test_statistics.TestMean.test_decimals @ linux-x86_64 +test.test_statistics.TestMean.test_doubled_data @ linux-x86_64 +test.test_statistics.TestMean.test_empty_data @ linux-x86_64 +test.test_statistics.TestMean.test_floats @ linux-x86_64 +test.test_statistics.TestMean.test_fractions @ linux-x86_64 +test.test_statistics.TestMean.test_inf @ linux-x86_64 +test.test_statistics.TestMean.test_ints @ linux-x86_64 +test.test_statistics.TestMean.test_mismatched_infs @ linux-x86_64 +test.test_statistics.TestMean.test_nan @ linux-x86_64 +test.test_statistics.TestMean.test_no_args @ linux-x86_64 +test.test_statistics.TestMean.test_no_inplace_modifications @ linux-x86_64 +test.test_statistics.TestMean.test_order_doesnt_matter @ linux-x86_64 +test.test_statistics.TestMean.test_range_data @ linux-x86_64 +test.test_statistics.TestMean.test_regression_20561 @ linux-x86_64 +test.test_statistics.TestMean.test_regression_25177 @ linux-x86_64 +test.test_statistics.TestMean.test_repeated_single_value @ linux-x86_64 +test.test_statistics.TestMean.test_single_value @ linux-x86_64 +test.test_statistics.TestMean.test_torture_pep @ linux-x86_64 +test.test_statistics.TestMean.test_type_of_data_collection @ linux-x86_64 +test.test_statistics.TestMean.test_type_of_data_element @ linux-x86_64 +test.test_statistics.TestMean.test_types_conserved @ linux-x86_64 +test.test_statistics.TestMedian.test_bad_arg_types @ linux-x86_64 +test.test_statistics.TestMedian.test_empty_data @ linux-x86_64 +test.test_statistics.TestMedian.test_even_decimals @ linux-x86_64 +test.test_statistics.TestMedian.test_even_fractions @ linux-x86_64 +test.test_statistics.TestMedian.test_even_ints @ linux-x86_64 +test.test_statistics.TestMedian.test_no_args @ linux-x86_64 +test.test_statistics.TestMedian.test_no_inplace_modifications @ linux-x86_64 +test.test_statistics.TestMedian.test_odd_decimals @ linux-x86_64 +test.test_statistics.TestMedian.test_odd_fractions @ linux-x86_64 +test.test_statistics.TestMedian.test_odd_ints @ linux-x86_64 +test.test_statistics.TestMedian.test_order_doesnt_matter @ linux-x86_64 +test.test_statistics.TestMedian.test_range_data @ linux-x86_64 +test.test_statistics.TestMedian.test_repeated_single_value @ linux-x86_64 +test.test_statistics.TestMedian.test_single_value @ linux-x86_64 +test.test_statistics.TestMedian.test_type_of_data_collection @ linux-x86_64 +test.test_statistics.TestMedian.test_type_of_data_element @ linux-x86_64 +test.test_statistics.TestMedianDataType.test_types_conserved @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_bad_arg_types @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_data_type_error @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_empty_data @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_even_decimals @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_even_fractions @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_even_ints @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_even_number_repeated @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_interval @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_no_args @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_no_inplace_modifications @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_odd_decimals @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_odd_fractions @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_odd_ints @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_odd_number_repeated @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_order_doesnt_matter @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_range_data @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_repeated_single_value @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_single_value @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_type_of_data_collection @ linux-x86_64 +test.test_statistics.TestMedianGrouped.test_type_of_data_element @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_bad_arg_types @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_empty_data @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_even_decimals @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_even_fractions @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_even_ints @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_no_args @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_no_inplace_modifications @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_odd_decimals @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_odd_fractions @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_odd_ints @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_order_doesnt_matter @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_range_data @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_repeated_single_value @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_single_value @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_type_of_data_collection @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_type_of_data_element @ linux-x86_64 +test.test_statistics.TestMedianHigh.test_types_conserved @ linux-x86_64 +test.test_statistics.TestMedianLow.test_bad_arg_types @ linux-x86_64 +test.test_statistics.TestMedianLow.test_empty_data @ linux-x86_64 +test.test_statistics.TestMedianLow.test_even_decimals @ linux-x86_64 +test.test_statistics.TestMedianLow.test_even_fractions @ linux-x86_64 +test.test_statistics.TestMedianLow.test_even_ints @ linux-x86_64 +test.test_statistics.TestMedianLow.test_no_args @ linux-x86_64 +test.test_statistics.TestMedianLow.test_no_inplace_modifications @ linux-x86_64 +test.test_statistics.TestMedianLow.test_odd_decimals @ linux-x86_64 +test.test_statistics.TestMedianLow.test_odd_fractions @ linux-x86_64 +test.test_statistics.TestMedianLow.test_odd_ints @ linux-x86_64 +test.test_statistics.TestMedianLow.test_order_doesnt_matter @ linux-x86_64 +test.test_statistics.TestMedianLow.test_range_data @ linux-x86_64 +test.test_statistics.TestMedianLow.test_repeated_single_value @ linux-x86_64 +test.test_statistics.TestMedianLow.test_single_value @ linux-x86_64 +test.test_statistics.TestMedianLow.test_type_of_data_collection @ linux-x86_64 +test.test_statistics.TestMedianLow.test_type_of_data_element @ linux-x86_64 +test.test_statistics.TestMedianLow.test_types_conserved @ linux-x86_64 +test.test_statistics.TestMode.test_bad_arg_types @ linux-x86_64 +test.test_statistics.TestMode.test_bimodal_data @ linux-x86_64 +test.test_statistics.TestMode.test_counter_data @ linux-x86_64 +test.test_statistics.TestMode.test_discrete_data @ linux-x86_64 +test.test_statistics.TestMode.test_empty_data @ linux-x86_64 +test.test_statistics.TestMode.test_no_args @ linux-x86_64 +test.test_statistics.TestMode.test_no_inplace_modifications @ linux-x86_64 +test.test_statistics.TestMode.test_nominal_data @ linux-x86_64 +test.test_statistics.TestMode.test_none_data @ linux-x86_64 +test.test_statistics.TestMode.test_order_doesnt_matter @ linux-x86_64 +test.test_statistics.TestMode.test_range_data @ linux-x86_64 +test.test_statistics.TestMode.test_repeated_single_value @ linux-x86_64 +test.test_statistics.TestMode.test_single_value @ linux-x86_64 +test.test_statistics.TestMode.test_type_of_data_collection @ linux-x86_64 +test.test_statistics.TestMode.test_type_of_data_element @ linux-x86_64 +test.test_statistics.TestMode.test_types_conserved @ linux-x86_64 +test.test_statistics.TestMode.test_unique_data @ linux-x86_64 +test.test_statistics.TestModules.test_py_functions @ linux-x86_64 +test.test_statistics.TestMultiMode.test_basics @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_alternative_constructor @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_cdf @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_copy @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_equality @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_hashability @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_instantiation_and_attributes @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_inv_cdf @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_pdf @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_pickle @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_properties @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_quantiles @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_repr @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_same_type_addition_and_subtraction @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_sample_generation @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_slots @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_translation_and_scaling @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_unary_operations @ linux-x86_64 +test.test_statistics.TestNormalDistPython.test_zscore @ linux-x86_64 +test.test_statistics.TestNumericTestCase.test_error_msg_numeric @ linux-x86_64 +test.test_statistics.TestNumericTestCase.test_error_msg_sequence @ linux-x86_64 +test.test_statistics.TestNumericTestCase.test_numerictestcase_is_testcase @ linux-x86_64 +test.test_statistics.TestPStdev.test_bad_arg_types @ linux-x86_64 +test.test_statistics.TestPStdev.test_center_not_at_mean @ linux-x86_64 +test.test_statistics.TestPStdev.test_compare_to_variance @ linux-x86_64 +test.test_statistics.TestPStdev.test_domain_error_regression @ linux-x86_64 +test.test_statistics.TestPStdev.test_empty_data @ linux-x86_64 +test.test_statistics.TestPStdev.test_iter_list_same @ linux-x86_64 +test.test_statistics.TestPStdev.test_no_args @ linux-x86_64 +test.test_statistics.TestPStdev.test_no_inplace_modifications @ linux-x86_64 +test.test_statistics.TestPStdev.test_order_doesnt_matter @ linux-x86_64 +test.test_statistics.TestPStdev.test_range_data @ linux-x86_64 +test.test_statistics.TestPStdev.test_repeated_single_value @ linux-x86_64 +test.test_statistics.TestPStdev.test_shift_data @ linux-x86_64 +test.test_statistics.TestPStdev.test_shift_data_exact @ linux-x86_64 +test.test_statistics.TestPStdev.test_single_value @ linux-x86_64 +test.test_statistics.TestPStdev.test_type_of_data_collection @ linux-x86_64 +test.test_statistics.TestPStdev.test_type_of_data_element @ linux-x86_64 +test.test_statistics.TestPVariance.test_accuracy_bug_20499 @ linux-x86_64 +test.test_statistics.TestPVariance.test_bad_arg_types @ linux-x86_64 +test.test_statistics.TestPVariance.test_decimals @ linux-x86_64 +test.test_statistics.TestPVariance.test_domain_error_regression @ linux-x86_64 +test.test_statistics.TestPVariance.test_empty_data @ linux-x86_64 +test.test_statistics.TestPVariance.test_exact_uniform @ linux-x86_64 +test.test_statistics.TestPVariance.test_fractions @ linux-x86_64 +test.test_statistics.TestPVariance.test_ints @ linux-x86_64 +test.test_statistics.TestPVariance.test_iter_list_same @ linux-x86_64 +test.test_statistics.TestPVariance.test_no_args @ linux-x86_64 +test.test_statistics.TestPVariance.test_no_inplace_modifications @ linux-x86_64 +test.test_statistics.TestPVariance.test_order_doesnt_matter @ linux-x86_64 +test.test_statistics.TestPVariance.test_range_data @ linux-x86_64 +test.test_statistics.TestPVariance.test_repeated_single_value @ linux-x86_64 +test.test_statistics.TestPVariance.test_shift_data @ linux-x86_64 +test.test_statistics.TestPVariance.test_shift_data_exact @ linux-x86_64 +test.test_statistics.TestPVariance.test_single_value @ linux-x86_64 +test.test_statistics.TestPVariance.test_type_of_data_collection @ linux-x86_64 +test.test_statistics.TestPVariance.test_type_of_data_element @ linux-x86_64 +test.test_statistics.TestPVariance.test_types_conserved @ linux-x86_64 +test.test_statistics.TestQuantiles.test_equal_inputs @ linux-x86_64 +test.test_statistics.TestQuantiles.test_equal_sized_groups @ linux-x86_64 +test.test_statistics.TestQuantiles.test_error_cases @ linux-x86_64 +test.test_statistics.TestQuantiles.test_specific_cases @ linux-x86_64 +test.test_statistics.TestQuantiles.test_specific_cases_inclusive @ linux-x86_64 +test.test_statistics.TestSign.testZeroes @ linux-x86_64 +test.test_statistics.TestSqrtHelpers.test_decimal_sqrt_of_frac @ linux-x86_64 +test.test_statistics.TestSqrtHelpers.test_float_sqrt_of_frac @ linux-x86_64 +test.test_statistics.TestSqrtHelpers.test_integer_sqrt_of_frac_rto @ linux-x86_64 +test.test_statistics.TestStdev.test_bad_arg_types @ linux-x86_64 +test.test_statistics.TestStdev.test_center_not_at_mean @ linux-x86_64 +test.test_statistics.TestStdev.test_compare_to_variance @ linux-x86_64 +test.test_statistics.TestStdev.test_domain_error_regression @ linux-x86_64 +test.test_statistics.TestStdev.test_empty_data @ linux-x86_64 +test.test_statistics.TestStdev.test_iter_list_same @ linux-x86_64 +test.test_statistics.TestStdev.test_no_args @ linux-x86_64 +test.test_statistics.TestStdev.test_no_inplace_modifications @ linux-x86_64 +test.test_statistics.TestStdev.test_order_doesnt_matter @ linux-x86_64 +test.test_statistics.TestStdev.test_range_data @ linux-x86_64 +test.test_statistics.TestStdev.test_repeated_single_value @ linux-x86_64 +test.test_statistics.TestStdev.test_shift_data @ linux-x86_64 +test.test_statistics.TestStdev.test_shift_data_exact @ linux-x86_64 +test.test_statistics.TestStdev.test_single_value @ linux-x86_64 +test.test_statistics.TestStdev.test_type_of_data_collection @ linux-x86_64 +test.test_statistics.TestStdev.test_type_of_data_element @ linux-x86_64 +test.test_statistics.TestSum.test_bytes_fail @ linux-x86_64 +test.test_statistics.TestSum.test_compare_with_math_fsum @ linux-x86_64 +test.test_statistics.TestSum.test_decimals @ linux-x86_64 +test.test_statistics.TestSum.test_empty_data @ linux-x86_64 +test.test_statistics.TestSum.test_floats @ linux-x86_64 +test.test_statistics.TestSum.test_fractions @ linux-x86_64 +test.test_statistics.TestSum.test_ints @ linux-x86_64 +test.test_statistics.TestSum.test_mixed_sum @ linux-x86_64 +test.test_statistics.TestSum.test_strings_fail @ linux-x86_64 +test.test_statistics.TestVariance.test_accuracy_bug_20499 @ linux-x86_64 +test.test_statistics.TestVariance.test_bad_arg_types @ linux-x86_64 +test.test_statistics.TestVariance.test_center_not_at_mean @ linux-x86_64 +test.test_statistics.TestVariance.test_decimals @ linux-x86_64 +test.test_statistics.TestVariance.test_domain_error_regression @ linux-x86_64 +test.test_statistics.TestVariance.test_empty_data @ linux-x86_64 +test.test_statistics.TestVariance.test_fractions @ linux-x86_64 +test.test_statistics.TestVariance.test_ints @ linux-x86_64 +test.test_statistics.TestVariance.test_iter_list_same @ linux-x86_64 +test.test_statistics.TestVariance.test_no_args @ linux-x86_64 +test.test_statistics.TestVariance.test_no_inplace_modifications @ linux-x86_64 +test.test_statistics.TestVariance.test_order_doesnt_matter @ linux-x86_64 +test.test_statistics.TestVariance.test_range_data @ linux-x86_64 +test.test_statistics.TestVariance.test_repeated_single_value @ linux-x86_64 +test.test_statistics.TestVariance.test_shift_data @ linux-x86_64 +test.test_statistics.TestVariance.test_shift_data_exact @ linux-x86_64 +test.test_statistics.TestVariance.test_single_value @ linux-x86_64 +test.test_statistics.TestVariance.test_type_of_data_collection @ linux-x86_64 +test.test_statistics.TestVariance.test_type_of_data_element @ linux-x86_64 +test.test_statistics.TestVariance.test_types_conserved @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_strftime.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_strftime.txt new file mode 100644 index 0000000000..74ab95bcf9 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_strftime.txt @@ -0,0 +1,4 @@ +test.test_strftime.StrftimeTest.test_strftime @ linux-x86_64 +test.test_strftime.Y1900Tests.test_y_1900 @ linux-x86_64 +test.test_strftime.Y1900Tests.test_y_after_1900 @ linux-x86_64 +test.test_strftime.Y1900Tests.test_y_before_1900 @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_string.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_string.txt new file mode 100644 index 0000000000..9c816c61b8 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_string.txt @@ -0,0 +1,38 @@ +test.test_string.ModuleTest.test_attrs @ linux-x86_64 +test.test_string.ModuleTest.test_auto_numbering @ linux-x86_64 +test.test_string.ModuleTest.test_basic_formatter @ linux-x86_64 +test.test_string.ModuleTest.test_capwords @ linux-x86_64 +test.test_string.ModuleTest.test_check_unused_args @ linux-x86_64 +test.test_string.ModuleTest.test_conversion_specifiers @ linux-x86_64 +test.test_string.ModuleTest.test_format_keyword_arguments @ linux-x86_64 +test.test_string.ModuleTest.test_index_lookup @ linux-x86_64 +test.test_string.ModuleTest.test_name_lookup @ linux-x86_64 +test.test_string.ModuleTest.test_override_convert_field @ linux-x86_64 +test.test_string.ModuleTest.test_override_format_field @ linux-x86_64 +test.test_string.ModuleTest.test_override_get_value @ linux-x86_64 +test.test_string.ModuleTest.test_override_parse @ linux-x86_64 +test.test_string.ModuleTest.test_vformat_recursion_limit @ linux-x86_64 +test.test_string.TestTemplate.test_SafeTemplate @ linux-x86_64 +test.test_string.TestTemplate.test_braced_override @ linux-x86_64 +test.test_string.TestTemplate.test_braced_override_safe @ linux-x86_64 +test.test_string.TestTemplate.test_delimiter_override @ linux-x86_64 +test.test_string.TestTemplate.test_escapes @ linux-x86_64 +test.test_string.TestTemplate.test_flags_override @ linux-x86_64 +test.test_string.TestTemplate.test_get_identifiers @ linux-x86_64 +test.test_string.TestTemplate.test_idpattern_override @ linux-x86_64 +test.test_string.TestTemplate.test_idpattern_override_inside_outside @ linux-x86_64 +test.test_string.TestTemplate.test_idpattern_override_inside_outside_invalid_unbraced @ linux-x86_64 +test.test_string.TestTemplate.test_invalid_placeholders @ linux-x86_64 +test.test_string.TestTemplate.test_invalid_with_no_lines @ linux-x86_64 +test.test_string.TestTemplate.test_is_valid @ linux-x86_64 +test.test_string.TestTemplate.test_keyword_arguments @ linux-x86_64 +test.test_string.TestTemplate.test_keyword_arguments_safe @ linux-x86_64 +test.test_string.TestTemplate.test_pattern_override @ linux-x86_64 +test.test_string.TestTemplate.test_percents @ linux-x86_64 +test.test_string.TestTemplate.test_regular_templates @ linux-x86_64 +test.test_string.TestTemplate.test_regular_templates_with_braces @ linux-x86_64 +test.test_string.TestTemplate.test_regular_templates_with_non_letters @ linux-x86_64 +test.test_string.TestTemplate.test_regular_templates_with_upper_case @ linux-x86_64 +test.test_string.TestTemplate.test_stringification @ linux-x86_64 +test.test_string.TestTemplate.test_tupleargs @ linux-x86_64 +test.test_string.TestTemplate.test_unicode_values @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_string_literals.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_string_literals.txt new file mode 100644 index 0000000000..b32b52c380 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_string_literals.txt @@ -0,0 +1,17 @@ +test.test_string_literals.TestLiterals.test_eval_bytes_incomplete @ linux-x86_64 +test.test_string_literals.TestLiterals.test_eval_bytes_invalid_escape @ linux-x86_64 +test.test_string_literals.TestLiterals.test_eval_bytes_normal @ linux-x86_64 +test.test_string_literals.TestLiterals.test_eval_bytes_raw @ linux-x86_64 +test.test_string_literals.TestLiterals.test_eval_str_incomplete @ linux-x86_64 +test.test_string_literals.TestLiterals.test_eval_str_invalid_escape @ linux-x86_64 +test.test_string_literals.TestLiterals.test_eval_str_normal @ linux-x86_64 +test.test_string_literals.TestLiterals.test_eval_str_raw @ linux-x86_64 +test.test_string_literals.TestLiterals.test_eval_str_u @ linux-x86_64 +test.test_string_literals.TestLiterals.test_file_iso_8859_1 @ linux-x86_64 +test.test_string_literals.TestLiterals.test_file_latin9 @ linux-x86_64 +test.test_string_literals.TestLiterals.test_file_latin_1 @ linux-x86_64 +test.test_string_literals.TestLiterals.test_file_utf8 @ linux-x86_64 +test.test_string_literals.TestLiterals.test_file_utf_8 @ linux-x86_64 +test.test_string_literals.TestLiterals.test_file_utf_8_error @ linux-x86_64 +test.test_string_literals.TestLiterals.test_template @ linux-x86_64 +test.test_string_literals.TestLiterals.test_uppercase_prefixes @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_stringprep.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_stringprep.txt new file mode 100644 index 0000000000..e2f25ed430 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_stringprep.txt @@ -0,0 +1 @@ +test.test_stringprep.StringprepTests.test @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_strptime.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_strptime.txt new file mode 100644 index 0000000000..19cadf94f5 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_strptime.txt @@ -0,0 +1,42 @@ +test.test_strptime.CacheTests.test_TimeRE_recreation_locale @ linux-x86_64 +test.test_strptime.CacheTests.test_new_localetime @ linux-x86_64 +test.test_strptime.CacheTests.test_regex_cleanup @ linux-x86_64 +test.test_strptime.CacheTests.test_time_re_recreation @ linux-x86_64 +test.test_strptime.CalculationTests.test_week_0 @ linux-x86_64 +test.test_strptime.JulianTests.test_all_julian_days @ linux-x86_64 +test.test_strptime.LocaleTime_Tests.test_am_pm @ linux-x86_64 +test.test_strptime.LocaleTime_Tests.test_date_time @ linux-x86_64 +test.test_strptime.LocaleTime_Tests.test_lang @ linux-x86_64 +test.test_strptime.LocaleTime_Tests.test_month @ linux-x86_64 +test.test_strptime.LocaleTime_Tests.test_timezone @ linux-x86_64 +test.test_strptime.LocaleTime_Tests.test_weekday @ linux-x86_64 +test.test_strptime.Strptime12AMPMTests.test_twelve_noon_midnight @ linux-x86_64 +test.test_strptime.StrptimeTests.test_ValueError @ linux-x86_64 +test.test_strptime.StrptimeTests.test_bad_offset @ linux-x86_64 +test.test_strptime.StrptimeTests.test_caseinsensitive @ linux-x86_64 +test.test_strptime.StrptimeTests.test_date @ linux-x86_64 +test.test_strptime.StrptimeTests.test_date_time @ linux-x86_64 +test.test_strptime.StrptimeTests.test_day @ linux-x86_64 +test.test_strptime.StrptimeTests.test_defaults @ linux-x86_64 +test.test_strptime.StrptimeTests.test_escaping @ linux-x86_64 +test.test_strptime.StrptimeTests.test_feb29_on_leap_year_without_year @ linux-x86_64 +test.test_strptime.StrptimeTests.test_fraction @ linux-x86_64 +test.test_strptime.StrptimeTests.test_hour @ linux-x86_64 +test.test_strptime.StrptimeTests.test_julian @ linux-x86_64 +test.test_strptime.StrptimeTests.test_mar1_comes_after_feb29_even_when_omitting_the_year @ linux-x86_64 +test.test_strptime.StrptimeTests.test_minute @ linux-x86_64 +test.test_strptime.StrptimeTests.test_month @ linux-x86_64 +test.test_strptime.StrptimeTests.test_offset @ linux-x86_64 +test.test_strptime.StrptimeTests.test_percent @ linux-x86_64 +test.test_strptime.StrptimeTests.test_second @ linux-x86_64 +test.test_strptime.StrptimeTests.test_strptime_exception_context @ linux-x86_64 +test.test_strptime.StrptimeTests.test_time @ linux-x86_64 +test.test_strptime.StrptimeTests.test_unconverteddata @ linux-x86_64 +test.test_strptime.StrptimeTests.test_year @ linux-x86_64 +test.test_strptime.TimeRETests.test_blankpattern @ linux-x86_64 +test.test_strptime.TimeRETests.test_locale_data_w_regex_metacharacters @ linux-x86_64 +test.test_strptime.TimeRETests.test_matching_with_escapes @ linux-x86_64 +test.test_strptime.TimeRETests.test_pattern @ linux-x86_64 +test.test_strptime.TimeRETests.test_pattern_escaping @ linux-x86_64 +test.test_strptime.TimeRETests.test_whitespace_substitution @ linux-x86_64 +test.test_strptime.getlang_Tests.test_basic @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_strtod.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_strtod.txt new file mode 100644 index 0000000000..a2fa1b0d6a --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_strtod.txt @@ -0,0 +1,8 @@ +test.test_strtod.StrtodTests.test_bigcomp @ linux-x86_64 +test.test_strtod.StrtodTests.test_boundaries @ linux-x86_64 +test.test_strtod.StrtodTests.test_halfway_cases @ linux-x86_64 +test.test_strtod.StrtodTests.test_large_exponents @ linux-x86_64 +test.test_strtod.StrtodTests.test_parsing @ linux-x86_64 +test.test_strtod.StrtodTests.test_particular @ linux-x86_64 +test.test_strtod.StrtodTests.test_short_halfway_cases @ linux-x86_64 +test.test_strtod.StrtodTests.test_underflow_boundary @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_struct.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_struct.txt new file mode 100644 index 0000000000..5f8800bf43 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_struct.txt @@ -0,0 +1,30 @@ +test.test_struct.StructTest.test_1530559 @ linux-x86_64 +test.test_struct.StructTest.test_705836 @ linux-x86_64 +test.test_struct.StructTest.test_Struct_reinitialization @ linux-x86_64 +test.test_struct.StructTest.test_bool @ linux-x86_64 +test.test_struct.StructTest.test_boundary_error_message @ linux-x86_64 +test.test_struct.StructTest.test_boundary_error_message_with_large_offset @ linux-x86_64 +test.test_struct.StructTest.test_boundary_error_message_with_negative_offset @ linux-x86_64 +test.test_struct.StructTest.test_calcsize @ linux-x86_64 +test.test_struct.StructTest.test_consistence @ linux-x86_64 +test.test_struct.StructTest.test_format_attr @ linux-x86_64 +test.test_struct.StructTest.test_integers @ linux-x86_64 +test.test_struct.StructTest.test_isbigendian @ linux-x86_64 +test.test_struct.StructTest.test_issue29802 @ linux-x86_64 +test.test_struct.StructTest.test_issue35714 @ linux-x86_64 +test.test_struct.StructTest.test_nN_code @ linux-x86_64 +test.test_struct.StructTest.test_new_features @ linux-x86_64 +test.test_struct.StructTest.test_p_code @ linux-x86_64 +test.test_struct.StructTest.test_pack_into @ linux-x86_64 +test.test_struct.StructTest.test_pack_into_fn @ linux-x86_64 +test.test_struct.StructTest.test_trailing_counter @ linux-x86_64 +test.test_struct.StructTest.test_transitiveness @ linux-x86_64 +test.test_struct.StructTest.test_unpack_from @ linux-x86_64 +test.test_struct.StructTest.test_unpack_with_buffer @ linux-x86_64 +test.test_struct.UnpackIteratorTest.test_arbitrary_buffer @ linux-x86_64 +test.test_struct.UnpackIteratorTest.test_construct @ linux-x86_64 +test.test_struct.UnpackIteratorTest.test_half_float @ linux-x86_64 +test.test_struct.UnpackIteratorTest.test_iterate @ linux-x86_64 +test.test_struct.UnpackIteratorTest.test_length_hint @ linux-x86_64 +test.test_struct.UnpackIteratorTest.test_module_func @ linux-x86_64 +test.test_struct.UnpackIteratorTest.test_uninstantiable @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_structseq.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_structseq.txt new file mode 100644 index 0000000000..4476e422b9 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_structseq.txt @@ -0,0 +1,15 @@ +test.test_structseq.StructSeqTest.test_cmp @ linux-x86_64 +test.test_structseq.StructSeqTest.test_concat @ linux-x86_64 +test.test_structseq.StructSeqTest.test_constructor @ linux-x86_64 +test.test_structseq.StructSeqTest.test_contains @ linux-x86_64 +test.test_structseq.StructSeqTest.test_copying @ linux-x86_64 +test.test_structseq.StructSeqTest.test_copying_with_unnamed_fields @ linux-x86_64 +test.test_structseq.StructSeqTest.test_eviltuple @ linux-x86_64 +test.test_structseq.StructSeqTest.test_extended_getslice @ linux-x86_64 +test.test_structseq.StructSeqTest.test_fields @ linux-x86_64 +test.test_structseq.StructSeqTest.test_hash @ linux-x86_64 +test.test_structseq.StructSeqTest.test_pickling @ linux-x86_64 +test.test_structseq.StructSeqTest.test_pickling_with_unnamed_fields @ linux-x86_64 +test.test_structseq.StructSeqTest.test_repeat @ linux-x86_64 +test.test_structseq.StructSeqTest.test_repr @ linux-x86_64 +test.test_structseq.StructSeqTest.test_tuple @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_subclassinit.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_subclassinit.txt new file mode 100644 index 0000000000..1e3a8fc825 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_subclassinit.txt @@ -0,0 +1,17 @@ +test.test_subclassinit.Test.test_errors @ linux-x86_64 +test.test_subclassinit.Test.test_errors_changed_pep487 @ linux-x86_64 +test.test_subclassinit.Test.test_init_subclass @ linux-x86_64 +test.test_subclassinit.Test.test_init_subclass_diamond @ linux-x86_64 +test.test_subclassinit.Test.test_init_subclass_dict @ linux-x86_64 +test.test_subclassinit.Test.test_init_subclass_error @ linux-x86_64 +test.test_subclassinit.Test.test_init_subclass_kwargs @ linux-x86_64 +test.test_subclassinit.Test.test_init_subclass_skipped @ linux-x86_64 +test.test_subclassinit.Test.test_init_subclass_wrong @ linux-x86_64 +test.test_subclassinit.Test.test_set_name @ linux-x86_64 +test.test_subclassinit.Test.test_set_name_error @ linux-x86_64 +test.test_subclassinit.Test.test_set_name_init_subclass @ linux-x86_64 +test.test_subclassinit.Test.test_set_name_lookup @ linux-x86_64 +test.test_subclassinit.Test.test_set_name_metaclass @ linux-x86_64 +test.test_subclassinit.Test.test_set_name_modifying_dict @ linux-x86_64 +test.test_subclassinit.Test.test_set_name_wrong @ linux-x86_64 +test.test_subclassinit.Test.test_type @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_subprocess.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_subprocess.txt new file mode 100644 index 0000000000..747e33cd93 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_subprocess.txt @@ -0,0 +1,170 @@ +test.test_subprocess.ContextManagerTests.test_broken_pipe_cleanup @ linux-x86_64 +test.test_subprocess.ContextManagerTests.test_communicate_stdin @ linux-x86_64 +test.test_subprocess.ContextManagerTests.test_invalid_args @ linux-x86_64 +test.test_subprocess.ContextManagerTests.test_pipe @ linux-x86_64 +test.test_subprocess.ContextManagerTests.test_returncode @ linux-x86_64 +test.test_subprocess.MiscTests.test__all__ @ linux-x86_64 +test.test_subprocess.MiscTests.test_call_keyboardinterrupt_no_kill @ linux-x86_64 +test.test_subprocess.MiscTests.test_context_manager_keyboardinterrupt_no_kill @ linux-x86_64 +test.test_subprocess.MiscTests.test_getoutput @ linux-x86_64 +test.test_subprocess.MiscTests.test_run_keyboardinterrupt_no_kill @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_CalledProcessError_str_non_zero @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_CalledProcessError_str_signal @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_CalledProcessError_str_unknown_signal @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_args_string @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_bytes_program @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_call_string @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_close_fd_0 @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_close_fd_1 @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_close_fd_2 @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_close_fds_0_1 @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_close_fds_0_1_2 @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_close_fds_0_2 @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_close_fds_1_2 @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_communicate_BrokenPipeError_stdin_close @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_communicate_BrokenPipeError_stdin_close_with_timeout @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_communicate_BrokenPipeError_stdin_flush @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_communicate_BrokenPipeError_stdin_write @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_communicate_repeated_call_after_stdout_close @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_exception_bad_args_0 @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_exception_bad_executable @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_exception_cwd @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_exception_errpipe_bad_data @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_exception_errpipe_normal @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_extra_groups_error @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_group_error @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_invalid_args @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_kill @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_kill_dead @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_remapping_std_fds @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_select_unbuffered @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_send_signal @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_send_signal_dead @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_send_signal_race @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_send_signal_race2 @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_shell_sequence @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_shell_string @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_small_errpipe_write_fd @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_specific_shell @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_start_new_session @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_stderr_stdin_are_single_inout_fd @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_stdout_stderr_are_single_inout_fd @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_stdout_stdin_are_single_inout_fd @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_stopped @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_swap_fds @ linux-x86_64 +!test.test_subprocess.POSIXProcessTestCase.test_swap_std_fds_with_one_closed @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_terminate_dead @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_user_error @ linux-x86_64 +test.test_subprocess.POSIXProcessTestCase.test_wait_when_sigchild_ignored @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_bufsize_equal_one_binary_mode @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_bufsize_equal_one_text_mode @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_bufsize_is_none @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_bytes_executable @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_bytes_executable_replaces_shell @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_call_kwargs @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_call_seq @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_call_timeout @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_check_call_nonzero @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_check_call_zero @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_check_output @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_check_output_input_arg @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_check_output_input_none @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_check_output_input_none_encoding_errors @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_check_output_input_none_text @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_check_output_input_none_universal_newlines @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_check_output_nonzero @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_check_output_stderr @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_check_output_stdin_arg @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_check_output_stdin_with_input_arg @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_check_output_stdout_arg @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_class_getitems @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_communicate @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_communicate_eintr @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_communicate_epipe @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_communicate_epipe_only_stdin @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_communicate_errors @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_communicate_pipe_buf @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_communicate_pipe_fd_leak @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_communicate_returns @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_communicate_stderr @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_communicate_stdin @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_communicate_stdout @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_communicate_timeout @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_communicate_timeout_large_output @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_cwd @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_cwd_with_absolute_arg @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_cwd_with_bytes @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_cwd_with_pathlike @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_cwd_with_relative_arg @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_cwd_with_relative_executable @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_double_close_on_error @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_empty_env @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_env @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_executable @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_executable_replaces_shell @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_executable_takes_precedence @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_executable_with_cwd @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_executable_without_cwd @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_failed_child_execute_fd_leak @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_file_not_found_includes_filename @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_file_not_found_with_bad_cwd @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_handles_closed_on_exception @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_invalid_args @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_invalid_bufsize @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_invalid_cmd @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_invalid_env @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_io_buffered_by_default @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_io_unbuffered_works @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_issue8780 @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_leaking_fds_on_error @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_list2cmdline @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_pathlike_executable @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_pathlike_executable_replaces_shell @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_poll @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_repr @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stderr_devnull @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stderr_filedes @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stderr_fileobj @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stderr_none @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stderr_pipe @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stderr_redirect_with_no_stdout_redirect @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stdin_devnull @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stdin_filedes @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stdin_fileobj @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stdin_none @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stdin_pipe @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stdout_devnull @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stdout_filedes @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stdout_filedes_of_stdout @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stdout_fileobj @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stdout_none @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stdout_pipe @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stdout_stderr_file @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_stdout_stderr_pipe @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_threadsafe_wait @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_universal_newlines_and_text @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_universal_newlines_communicate @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_universal_newlines_communicate_encodings @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_universal_newlines_communicate_input_none @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_universal_newlines_communicate_stdin @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_universal_newlines_communicate_stdin_stdout_stderr @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_wait @ linux-x86_64 +test.test_subprocess.ProcessTestCase.test_writes_before_communicate @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_capture_output @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_capture_stderr @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_capture_stdout @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_check @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_check_output_input_arg @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_check_output_stdin_arg @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_check_output_stdin_with_input_arg @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_check_zero @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_encoding_warning @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_returncode @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_run_kwargs @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_run_with_bytes_path_and_arguments @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_run_with_pathlike_path @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_run_with_pathlike_path_and_arguments @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_run_with_shell_timeout_and_capture_output @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_stderr_with_capture_output_arg @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_stdout_with_capture_output_arg @ linux-x86_64 +test.test_subprocess.RunFuncTestCase.test_timeout @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sundry.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sundry.txt new file mode 100644 index 0000000000..c4f66e6af7 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sundry.txt @@ -0,0 +1 @@ +test.test_sundry.TestUntestedModules.test_untested_modules_can_be_imported @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_super.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_super.txt new file mode 100644 index 0000000000..7934a15c8a --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_super.txt @@ -0,0 +1,18 @@ +test.test_super.TestSuper.test___class___classmethod @ linux-x86_64 +test.test_super.TestSuper.test___class___delayed @ linux-x86_64 +test.test_super.TestSuper.test___class___instancemethod @ linux-x86_64 +test.test_super.TestSuper.test___class___new @ linux-x86_64 +test.test_super.TestSuper.test___class___staticmethod @ linux-x86_64 +test.test_super.TestSuper.test___classcell___expected_behaviour @ linux-x86_64 +test.test_super.TestSuper.test___classcell___overwrite @ linux-x86_64 +test.test_super.TestSuper.test_basics_working @ linux-x86_64 +test.test_super.TestSuper.test_cell_as_self @ linux-x86_64 +test.test_super.TestSuper.test_class_getattr_working @ linux-x86_64 +test.test_super.TestSuper.test_class_methods_still_working @ linux-x86_64 +test.test_super.TestSuper.test_obscure_super_errors @ linux-x86_64 +test.test_super.TestSuper.test_subclass_no_override_working @ linux-x86_64 +test.test_super.TestSuper.test_super_in_class_methods_working @ linux-x86_64 +test.test_super.TestSuper.test_super_init_leaks @ linux-x86_64 +test.test_super.TestSuper.test_super_with_closure @ linux-x86_64 +test.test_super.TestSuper.test_unbound_method_transfer_working @ linux-x86_64 +test.test_super.TestSuper.test_various___class___pathologies @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_support.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_support.txt new file mode 100644 index 0000000000..b8d3805bb1 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_support.txt @@ -0,0 +1,41 @@ +test.test_support.TestSupport.test_CleanImport @ linux-x86_64 +test.test_support.TestSupport.test_DirsOnSysPath @ linux-x86_64 +test.test_support.TestSupport.test_HOST @ linux-x86_64 +test.test_support.TestSupport.test_bind_port @ linux-x86_64 +test.test_support.TestSupport.test_captured_stderr @ linux-x86_64 +test.test_support.TestSupport.test_captured_stdin @ linux-x86_64 +test.test_support.TestSupport.test_captured_stdout @ linux-x86_64 +test.test_support.TestSupport.test_change_cwd @ linux-x86_64 +test.test_support.TestSupport.test_change_cwd__chdir_warning @ linux-x86_64 +test.test_support.TestSupport.test_change_cwd__non_existent_dir @ linux-x86_64 +test.test_support.TestSupport.test_change_cwd__non_existent_dir__quiet_true @ linux-x86_64 +test.test_support.TestSupport.test_check__all__ @ linux-x86_64 +test.test_support.TestSupport.test_check_syntax_error @ linux-x86_64 +test.test_support.TestSupport.test_detect_api_mismatch @ linux-x86_64 +test.test_support.TestSupport.test_detect_api_mismatch__ignore @ linux-x86_64 +test.test_support.TestSupport.test_fd_count @ linux-x86_64 +test.test_support.TestSupport.test_find_unused_port @ linux-x86_64 +test.test_support.TestSupport.test_forget @ linux-x86_64 +test.test_support.TestSupport.test_gc_collect @ linux-x86_64 +test.test_support.TestSupport.test_get_attribute @ linux-x86_64 +test.test_support.TestSupport.test_has_strftime_extensions @ linux-x86_64 +test.test_support.TestSupport.test_ignored_deprecations_are_silent @ linux-x86_64 +test.test_support.TestSupport.test_import_fresh_module @ linux-x86_64 +test.test_support.TestSupport.test_import_module @ linux-x86_64 +test.test_support.TestSupport.test_make_bad_fd @ linux-x86_64 +test.test_support.TestSupport.test_parse_memlimit @ linux-x86_64 +test.test_support.TestSupport.test_print_warning @ linux-x86_64 +test.test_support.TestSupport.test_python_is_optimized @ linux-x86_64 +test.test_support.TestSupport.test_rmtree @ linux-x86_64 +test.test_support.TestSupport.test_set_memlimit @ linux-x86_64 +test.test_support.TestSupport.test_sortdict @ linux-x86_64 +test.test_support.TestSupport.test_swap_attr @ linux-x86_64 +test.test_support.TestSupport.test_swap_item @ linux-x86_64 +test.test_support.TestSupport.test_temp_cwd @ linux-x86_64 +test.test_support.TestSupport.test_temp_cwd__name_none @ linux-x86_64 +test.test_support.TestSupport.test_temp_dir @ linux-x86_64 +test.test_support.TestSupport.test_temp_dir__existing_dir__quiet_default @ linux-x86_64 +test.test_support.TestSupport.test_temp_dir__existing_dir__quiet_true @ linux-x86_64 +test.test_support.TestSupport.test_temp_dir__path_none @ linux-x86_64 +test.test_support.TestSupport.test_unlink @ linux-x86_64 +test.test_support.TestSupport.test_unload @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_syntax.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_syntax.txt new file mode 100644 index 0000000000..9daf680aec --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_syntax.txt @@ -0,0 +1,27 @@ +DocTestCase.test.test_syntax @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_assign_call @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_assign_del @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_bad_outdent @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_barry_as_flufl_with_syntax_errors @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_break_outside_loop @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_case_call_does_not_raise_syntax_error @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_continuation_bad_indentation @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_continue_outside_loop @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_curly_brace_after_primary_raises_immediately @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_empty_line_after_linecont @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_error_string_literal @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_except_star_then_except @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_except_then_except_star @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_expression_with_assignment @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_generator_in_function_call @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_global_param_err_first @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_invalid_line_continuation_left_recursive @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_kwargs_last @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_kwargs_last2 @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_kwargs_last3 @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_match_call_does_not_raise_syntax_error @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_no_indent @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_nonlocal_param_err_first @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_return_outside_function @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_unexpected_indent @ linux-x86_64 +test.test_syntax.SyntaxTestCase.test_yield_outside_function @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sys.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sys.txt new file mode 100644 index 0000000000..46b062ae4d --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sys.txt @@ -0,0 +1,39 @@ +test.test_sys.ActiveExceptionTests.test_exc_info_no_exception @ linux-x86_64 +test.test_sys.ActiveExceptionTests.test_exc_info_with_exception_instance @ linux-x86_64 +test.test_sys.ActiveExceptionTests.test_exc_info_with_exception_type @ linux-x86_64 +test.test_sys.ActiveExceptionTests.test_sys_exception_no_exception @ linux-x86_64 +test.test_sys.ActiveExceptionTests.test_sys_exception_with_exception_instance @ linux-x86_64 +test.test_sys.ActiveExceptionTests.test_sys_exception_with_exception_type @ linux-x86_64 +test.test_sys.DisplayHookTest.test_custom_displayhook @ linux-x86_64 +test.test_sys.DisplayHookTest.test_lost_displayhook @ linux-x86_64 +test.test_sys.DisplayHookTest.test_original_displayhook @ linux-x86_64 +test.test_sys.ExceptHookTest.test_excepthook @ linux-x86_64 +test.test_sys.ExceptHookTest.test_excepthook_bytes_filename @ linux-x86_64 +test.test_sys.ExceptHookTest.test_original_excepthook @ linux-x86_64 +test.test_sys.SysModuleTest.test_43581 @ linux-x86_64 +test.test_sys.SysModuleTest.test_attributes @ linux-x86_64 +test.test_sys.SysModuleTest.test_c_locale_surrogateescape @ linux-x86_64 +test.test_sys.SysModuleTest.test_dlopenflags @ linux-x86_64 +test.test_sys.SysModuleTest.test_executable @ linux-x86_64 +test.test_sys.SysModuleTest.test_exit @ linux-x86_64 +test.test_sys.SysModuleTest.test_getdefaultencoding @ linux-x86_64 +test.test_sys.SysModuleTest.test_getfilesystemencoding @ linux-x86_64 +test.test_sys.SysModuleTest.test_getframe @ linux-x86_64 +test.test_sys.SysModuleTest.test_getrecursionlimit @ linux-x86_64 +test.test_sys.SysModuleTest.test_implementation @ linux-x86_64 +test.test_sys.SysModuleTest.test_intern @ linux-x86_64 +test.test_sys.SysModuleTest.test_ioencoding @ linux-x86_64 +test.test_sys.SysModuleTest.test_module_names @ linux-x86_64 +test.test_sys.SysModuleTest.test_no_duplicates_in_meta_path @ linux-x86_64 +test.test_sys.SysModuleTest.test_orig_argv @ linux-x86_64 +test.test_sys.SysModuleTest.test_posix_locale_surrogateescape @ linux-x86_64 +test.test_sys.SysModuleTest.test_recursionlimit_recovery @ linux-x86_64 +test.test_sys.SysModuleTest.test_setrecursionlimit @ linux-x86_64 +test.test_sys.SysModuleTest.test_stdlib_dir @ linux-x86_64 +test.test_sys.SysModuleTest.test_switchinterval @ linux-x86_64 +test.test_sys.SysModuleTest.test_sys_flags @ linux-x86_64 +test.test_sys.SysModuleTest.test_sys_flags_no_instantiation @ linux-x86_64 +test.test_sys.SysModuleTest.test_sys_ignores_cleaning_up_user_data @ linux-x86_64 +test.test_sys.SysModuleTest.test_sys_tracebacklimit @ linux-x86_64 +test.test_sys.SysModuleTest.test_sys_version_info_no_instantiation @ linux-x86_64 +test.test_sys.SysModuleTest.test_thread_info @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sysconfig.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sysconfig.txt new file mode 100644 index 0000000000..620a3a68d6 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_sysconfig.txt @@ -0,0 +1,18 @@ +test.test_sysconfig.MakefileTests.test_parse_makefile @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_EXT_SUFFIX_in_vars @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_get_config_h_filename @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_get_config_vars @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_get_default_scheme @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_get_path @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_get_path_names @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_get_paths @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_get_platform @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_get_preferred_schemes @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_get_scheme_names @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_ldshared_value @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_main @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_nt_venv_scheme @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_posix_venv_scheme @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_srcdir_independent_of_cwd @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_user_similar @ linux-x86_64 +test.test_sysconfig.TestSysConfig.test_venv_scheme @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tabnanny.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tabnanny.txt new file mode 100644 index 0000000000..3612533e2f --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tabnanny.txt @@ -0,0 +1,19 @@ +test.test_tabnanny.TestCheck.test_correct_directory @ linux-x86_64 +test.test_tabnanny.TestCheck.test_correct_directory_verbose @ linux-x86_64 +test.test_tabnanny.TestCheck.test_correct_file @ linux-x86_64 +test.test_tabnanny.TestCheck.test_errored_directory @ linux-x86_64 +test.test_tabnanny.TestCheck.test_when_nannynag_error @ linux-x86_64 +test.test_tabnanny.TestCheck.test_when_nannynag_error_verbose @ linux-x86_64 +test.test_tabnanny.TestCheck.test_when_no_file @ linux-x86_64 +test.test_tabnanny.TestCheck.test_when_tokenize_tokenerror @ linux-x86_64 +test.test_tabnanny.TestCheck.test_when_wrong_indented @ linux-x86_64 +test.test_tabnanny.TestCommandLine.test_double_verbose_mode @ linux-x86_64 +test.test_tabnanny.TestCommandLine.test_quiet_flag @ linux-x86_64 +test.test_tabnanny.TestCommandLine.test_verbose_mode @ linux-x86_64 +test.test_tabnanny.TestCommandLine.test_with_error_free_file @ linux-x86_64 +test.test_tabnanny.TestCommandLine.test_with_errored_file @ linux-x86_64 +test.test_tabnanny.TestErrPrint.test_errprint @ linux-x86_64 +test.test_tabnanny.TestFormatWitnesses.test_format_witnesses @ linux-x86_64 +test.test_tabnanny.TestNannyNag.test_all_methods @ linux-x86_64 +test.test_tabnanny.TestProcessTokens.test_with_correct_code @ linux-x86_64 +test.test_tabnanny.TestProcessTokens.test_with_errored_codes_samples @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tarfile.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tarfile.txt new file mode 100644 index 0000000000..e903613266 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tarfile.txt @@ -0,0 +1,552 @@ +test.test_tarfile.AppendTest.test_empty @ linux-x86_64 +test.test_tarfile.AppendTest.test_empty_fileobj @ linux-x86_64 +test.test_tarfile.AppendTest.test_existing @ linux-x86_64 +test.test_tarfile.AppendTest.test_fileobj @ linux-x86_64 +test.test_tarfile.AppendTest.test_incomplete @ linux-x86_64 +test.test_tarfile.AppendTest.test_invalid @ linux-x86_64 +test.test_tarfile.AppendTest.test_non_existing @ linux-x86_64 +test.test_tarfile.AppendTest.test_null @ linux-x86_64 +test.test_tarfile.AppendTest.test_premature_eof @ linux-x86_64 +test.test_tarfile.AppendTest.test_trailing_garbage @ linux-x86_64 +test.test_tarfile.Bz2AppendTest.test_append_compressed @ linux-x86_64 +test.test_tarfile.Bz2CreateTest.test_create @ linux-x86_64 +test.test_tarfile.Bz2CreateTest.test_create_existing @ linux-x86_64 +test.test_tarfile.Bz2CreateTest.test_create_existing_taropen @ linux-x86_64 +test.test_tarfile.Bz2CreateTest.test_create_pathlike_name @ linux-x86_64 +test.test_tarfile.Bz2CreateTest.test_create_taropen @ linux-x86_64 +test.test_tarfile.Bz2CreateTest.test_create_taropen_pathlike_name @ linux-x86_64 +test.test_tarfile.Bz2CreateTest.test_create_with_compresslevel @ linux-x86_64 +test.test_tarfile.Bz2CreateTest.test_eof_marker @ linux-x86_64 +test.test_tarfile.Bz2CreateTest.test_fileobj_no_close @ linux-x86_64 +test.test_tarfile.Bz2DetectReadTest.test_detect_file @ linux-x86_64 +test.test_tarfile.Bz2DetectReadTest.test_detect_fileobj @ linux-x86_64 +test.test_tarfile.Bz2DetectReadTest.test_detect_stream_bz2 @ linux-x86_64 +test.test_tarfile.Bz2ListTest.test_list @ linux-x86_64 +test.test_tarfile.Bz2ListTest.test_list_members @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_check_members @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_empty_name_attribute @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_empty_tarfile @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_extract_directory @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_extract_hardlink @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_extract_pathlike_name @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_extractall @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_extractall_pathlike_name @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_fail_comp @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_fileobj_with_offset @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_find_members @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_ignore_zeros @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_illegal_mode_arg @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_init_close_fobj @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_int_name_attribute @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_is_tarfile_erroneous @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_is_tarfile_keeps_position @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_is_tarfile_valid @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_length_zero_header @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_next_on_empty_tarfile @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_no_name_attribute @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_non_existent_tarfile @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_null_tarfile @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_parallel_iteration @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_pathlike_name @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_premature_end_of_archive @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_v7_dirtype @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_xstar_type @ linux-x86_64 +test.test_tarfile.Bz2MiscReadTest.test_zlib_error_does_not_leak @ linux-x86_64 +test.test_tarfile.Bz2PartialReadTest.test_partial_input @ linux-x86_64 +test.test_tarfile.Bz2PartialReadTest.test_partial_input_bz2 @ linux-x86_64 +test.test_tarfile.Bz2StreamReadTest.test_compare_members @ linux-x86_64 +test.test_tarfile.Bz2StreamReadTest.test_empty_tarfile @ linux-x86_64 +test.test_tarfile.Bz2StreamReadTest.test_fileobj_regular_file @ linux-x86_64 +test.test_tarfile.Bz2StreamReadTest.test_ignore_zeros @ linux-x86_64 +test.test_tarfile.Bz2StreamReadTest.test_is_tarfile_erroneous @ linux-x86_64 +test.test_tarfile.Bz2StreamReadTest.test_is_tarfile_keeps_position @ linux-x86_64 +test.test_tarfile.Bz2StreamReadTest.test_is_tarfile_valid @ linux-x86_64 +test.test_tarfile.Bz2StreamReadTest.test_length_zero_header @ linux-x86_64 +test.test_tarfile.Bz2StreamReadTest.test_non_existent_tarfile @ linux-x86_64 +test.test_tarfile.Bz2StreamReadTest.test_null_tarfile @ linux-x86_64 +test.test_tarfile.Bz2StreamReadTest.test_premature_end_of_archive @ linux-x86_64 +test.test_tarfile.Bz2StreamReadTest.test_provoke_stream_error @ linux-x86_64 +test.test_tarfile.Bz2StreamReadTest.test_read_through @ linux-x86_64 +test.test_tarfile.Bz2StreamWriteTest.test_eof_marker @ linux-x86_64 +test.test_tarfile.Bz2StreamWriteTest.test_file_mode @ linux-x86_64 +test.test_tarfile.Bz2StreamWriteTest.test_fileobj_no_close @ linux-x86_64 +test.test_tarfile.Bz2StreamWriteTest.test_stream_padding @ linux-x86_64 +test.test_tarfile.Bz2UstarReadTest.test_add_dir_getmember @ linux-x86_64 +test.test_tarfile.Bz2UstarReadTest.test_fileobj_iter @ linux-x86_64 +test.test_tarfile.Bz2UstarReadTest.test_fileobj_link1 @ linux-x86_64 +test.test_tarfile.Bz2UstarReadTest.test_fileobj_link2 @ linux-x86_64 +test.test_tarfile.Bz2UstarReadTest.test_fileobj_readlines @ linux-x86_64 +test.test_tarfile.Bz2UstarReadTest.test_fileobj_regular_file @ linux-x86_64 +test.test_tarfile.Bz2UstarReadTest.test_fileobj_seek @ linux-x86_64 +test.test_tarfile.Bz2UstarReadTest.test_fileobj_symlink1 @ linux-x86_64 +test.test_tarfile.Bz2UstarReadTest.test_fileobj_symlink2 @ linux-x86_64 +test.test_tarfile.Bz2UstarReadTest.test_fileobj_text @ linux-x86_64 +test.test_tarfile.Bz2UstarReadTest.test_issue14160 @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_100_char_name @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_abs_pathnames @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_add_self @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_cwd @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_directory_size @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_eof_marker @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_extractall_symlinks @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_file_size @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_fileobj_no_close @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_filter @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_gettarinfo_pathlike_name @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_link_size @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_open_nonwritable_fileobj @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_ordered_recursion @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_pathnames @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_symlink_size @ linux-x86_64 +test.test_tarfile.Bz2WriteTest.test_tar_size @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_bad_use @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_create_command @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_create_command_compressed @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_create_command_dot_started_filename @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_create_command_dotless_filename @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_create_command_verbose @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_extract_command @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_extract_command_different_directory @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_extract_command_filter @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_extract_command_invalid_file @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_extract_command_verbose @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_list_command @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_list_command_invalid_file @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_list_command_verbose @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_test_command @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_test_command_invalid_file @ linux-x86_64 +test.test_tarfile.CommandLineTest.test_test_command_verbose @ linux-x86_64 +test.test_tarfile.ContextManagerTest.test_basic @ linux-x86_64 +test.test_tarfile.ContextManagerTest.test_closed @ linux-x86_64 +test.test_tarfile.ContextManagerTest.test_eof @ linux-x86_64 +test.test_tarfile.ContextManagerTest.test_exception @ linux-x86_64 +test.test_tarfile.ContextManagerTest.test_fileobj @ linux-x86_64 +test.test_tarfile.ContextManagerTest.test_no_eof @ linux-x86_64 +test.test_tarfile.CreateTest.test_create @ linux-x86_64 +test.test_tarfile.CreateTest.test_create_existing @ linux-x86_64 +test.test_tarfile.CreateTest.test_create_existing_taropen @ linux-x86_64 +test.test_tarfile.CreateTest.test_create_pathlike_name @ linux-x86_64 +test.test_tarfile.CreateTest.test_create_taropen @ linux-x86_64 +test.test_tarfile.CreateTest.test_create_taropen_pathlike_name @ linux-x86_64 +test.test_tarfile.CreateTest.test_eof_marker @ linux-x86_64 +test.test_tarfile.CreateTest.test_fileobj_no_close @ linux-x86_64 +test.test_tarfile.CreateWithXModeTest.test_create @ linux-x86_64 +test.test_tarfile.CreateWithXModeTest.test_create_existing @ linux-x86_64 +test.test_tarfile.CreateWithXModeTest.test_create_pathlike_name @ linux-x86_64 +test.test_tarfile.CreateWithXModeTest.test_create_taropen_pathlike_name @ linux-x86_64 +test.test_tarfile.CreateWithXModeTest.test_eof_marker @ linux-x86_64 +test.test_tarfile.CreateWithXModeTest.test_fileobj_no_close @ linux-x86_64 +test.test_tarfile.DetectReadTest.test_detect_file @ linux-x86_64 +test.test_tarfile.DetectReadTest.test_detect_fileobj @ linux-x86_64 +test.test_tarfile.DeviceHeaderTest.test_eof_marker @ linux-x86_64 +test.test_tarfile.DeviceHeaderTest.test_fileobj_no_close @ linux-x86_64 +test.test_tarfile.DeviceHeaderTest.test_headers_written_only_for_device_files @ linux-x86_64 +test.test_tarfile.GNUReadTest.test_header_offset @ linux-x86_64 +test.test_tarfile.GNUReadTest.test_longname_directory @ linux-x86_64 +test.test_tarfile.GNUReadTest.test_read_longlink @ linux-x86_64 +test.test_tarfile.GNUReadTest.test_read_longname @ linux-x86_64 +test.test_tarfile.GNUReadTest.test_truncated_longname @ linux-x86_64 +test.test_tarfile.GNUUnicodeTest.test_bad_pax_header @ linux-x86_64 +test.test_tarfile.GNUUnicodeTest.test_iso8859_1_filename @ linux-x86_64 +test.test_tarfile.GNUUnicodeTest.test_uname_unicode @ linux-x86_64 +test.test_tarfile.GNUUnicodeTest.test_unicode_argument @ linux-x86_64 +test.test_tarfile.GNUUnicodeTest.test_unicode_filename_error @ linux-x86_64 +test.test_tarfile.GNUUnicodeTest.test_utf7_filename @ linux-x86_64 +test.test_tarfile.GNUUnicodeTest.test_utf8_filename @ linux-x86_64 +test.test_tarfile.GNUWriteTest.test_longlink_1023 @ linux-x86_64 +test.test_tarfile.GNUWriteTest.test_longlink_1024 @ linux-x86_64 +test.test_tarfile.GNUWriteTest.test_longlink_1025 @ linux-x86_64 +test.test_tarfile.GNUWriteTest.test_longname_1023 @ linux-x86_64 +test.test_tarfile.GNUWriteTest.test_longname_1024 @ linux-x86_64 +test.test_tarfile.GNUWriteTest.test_longname_1025 @ linux-x86_64 +test.test_tarfile.GNUWriteTest.test_longnamelink_1023 @ linux-x86_64 +test.test_tarfile.GNUWriteTest.test_longnamelink_1024 @ linux-x86_64 +test.test_tarfile.GNUWriteTest.test_longnamelink_1025 @ linux-x86_64 +test.test_tarfile.GzipAppendTest.test_append_compressed @ linux-x86_64 +test.test_tarfile.GzipBrokenHeaderCorrectException.runTest @ linux-x86_64 +test.test_tarfile.GzipCreateTest.test_create @ linux-x86_64 +test.test_tarfile.GzipCreateTest.test_create_existing @ linux-x86_64 +test.test_tarfile.GzipCreateTest.test_create_existing_taropen @ linux-x86_64 +test.test_tarfile.GzipCreateTest.test_create_pathlike_name @ linux-x86_64 +test.test_tarfile.GzipCreateTest.test_create_taropen @ linux-x86_64 +test.test_tarfile.GzipCreateTest.test_create_taropen_pathlike_name @ linux-x86_64 +test.test_tarfile.GzipCreateTest.test_create_with_compresslevel @ linux-x86_64 +test.test_tarfile.GzipCreateTest.test_eof_marker @ linux-x86_64 +test.test_tarfile.GzipCreateTest.test_fileobj_no_close @ linux-x86_64 +test.test_tarfile.GzipDetectReadTest.test_detect_file @ linux-x86_64 +test.test_tarfile.GzipDetectReadTest.test_detect_fileobj @ linux-x86_64 +test.test_tarfile.GzipListTest.test_list @ linux-x86_64 +test.test_tarfile.GzipListTest.test_list_members @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_bytes_name_attribute @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_check_members @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_empty_name_attribute @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_empty_tarfile @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_extract_directory @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_extract_hardlink @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_extract_pathlike_name @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_extractall @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_extractall_pathlike_name @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_fail_comp @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_fileobj_with_offset @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_find_members @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_ignore_zeros @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_illegal_mode_arg @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_init_close_fobj @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_int_name_attribute @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_is_tarfile_erroneous @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_is_tarfile_keeps_position @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_is_tarfile_valid @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_length_zero_header @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_next_on_empty_tarfile @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_no_name_argument @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_no_name_attribute @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_non_existent_tarfile @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_null_tarfile @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_parallel_iteration @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_pathlike_name @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_premature_end_of_archive @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_v7_dirtype @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_xstar_type @ linux-x86_64 +test.test_tarfile.GzipMiscReadTest.test_zlib_error_does_not_leak @ linux-x86_64 +test.test_tarfile.GzipStreamReadTest.test_compare_members @ linux-x86_64 +test.test_tarfile.GzipStreamReadTest.test_empty_tarfile @ linux-x86_64 +test.test_tarfile.GzipStreamReadTest.test_fileobj_regular_file @ linux-x86_64 +test.test_tarfile.GzipStreamReadTest.test_ignore_zeros @ linux-x86_64 +test.test_tarfile.GzipStreamReadTest.test_is_tarfile_erroneous @ linux-x86_64 +test.test_tarfile.GzipStreamReadTest.test_is_tarfile_keeps_position @ linux-x86_64 +test.test_tarfile.GzipStreamReadTest.test_is_tarfile_valid @ linux-x86_64 +test.test_tarfile.GzipStreamReadTest.test_length_zero_header @ linux-x86_64 +test.test_tarfile.GzipStreamReadTest.test_non_existent_tarfile @ linux-x86_64 +test.test_tarfile.GzipStreamReadTest.test_null_tarfile @ linux-x86_64 +test.test_tarfile.GzipStreamReadTest.test_premature_end_of_archive @ linux-x86_64 +test.test_tarfile.GzipStreamReadTest.test_provoke_stream_error @ linux-x86_64 +test.test_tarfile.GzipStreamReadTest.test_read_through @ linux-x86_64 +test.test_tarfile.GzipStreamWriteTest.test_eof_marker @ linux-x86_64 +test.test_tarfile.GzipStreamWriteTest.test_file_mode @ linux-x86_64 +test.test_tarfile.GzipStreamWriteTest.test_fileobj_no_close @ linux-x86_64 +test.test_tarfile.GzipStreamWriteTest.test_source_directory_not_leaked @ linux-x86_64 +test.test_tarfile.GzipStreamWriteTest.test_stream_padding @ linux-x86_64 +test.test_tarfile.GzipUstarReadTest.test_add_dir_getmember @ linux-x86_64 +test.test_tarfile.GzipUstarReadTest.test_fileobj_iter @ linux-x86_64 +test.test_tarfile.GzipUstarReadTest.test_fileobj_link1 @ linux-x86_64 +test.test_tarfile.GzipUstarReadTest.test_fileobj_link2 @ linux-x86_64 +test.test_tarfile.GzipUstarReadTest.test_fileobj_readlines @ linux-x86_64 +test.test_tarfile.GzipUstarReadTest.test_fileobj_regular_file @ linux-x86_64 +test.test_tarfile.GzipUstarReadTest.test_fileobj_seek @ linux-x86_64 +test.test_tarfile.GzipUstarReadTest.test_fileobj_symlink1 @ linux-x86_64 +test.test_tarfile.GzipUstarReadTest.test_fileobj_symlink2 @ linux-x86_64 +test.test_tarfile.GzipUstarReadTest.test_fileobj_text @ linux-x86_64 +test.test_tarfile.GzipUstarReadTest.test_issue14160 @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_100_char_name @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_abs_pathnames @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_add_self @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_cwd @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_directory_size @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_eof_marker @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_extractall_symlinks @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_file_size @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_fileobj_no_close @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_filter @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_gettarinfo_pathlike_name @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_link_size @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_open_nonwritable_fileobj @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_ordered_recursion @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_pathnames @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_symlink_size @ linux-x86_64 +test.test_tarfile.GzipWriteTest.test_tar_size @ linux-x86_64 +test.test_tarfile.HardlinkTest.test_add_hardlink @ linux-x86_64 +test.test_tarfile.HardlinkTest.test_add_twice @ linux-x86_64 +test.test_tarfile.HardlinkTest.test_dereference_hardlink @ linux-x86_64 +test.test_tarfile.LimitsTest.test_gnu_limits @ linux-x86_64 +test.test_tarfile.LimitsTest.test_pax_limits @ linux-x86_64 +test.test_tarfile.LimitsTest.test_ustar_limits @ linux-x86_64 +test.test_tarfile.ListTest.test_list @ linux-x86_64 +test.test_tarfile.ListTest.test_list_members @ linux-x86_64 +test.test_tarfile.LzmaAppendTest.test_append_compressed @ linux-x86_64 +test.test_tarfile.LzmaCreateTest.test_create @ linux-x86_64 +test.test_tarfile.LzmaCreateTest.test_create_existing @ linux-x86_64 +test.test_tarfile.LzmaCreateTest.test_create_existing_taropen @ linux-x86_64 +test.test_tarfile.LzmaCreateTest.test_create_pathlike_name @ linux-x86_64 +test.test_tarfile.LzmaCreateTest.test_create_taropen @ linux-x86_64 +test.test_tarfile.LzmaCreateTest.test_create_taropen_pathlike_name @ linux-x86_64 +test.test_tarfile.LzmaCreateTest.test_create_with_preset @ linux-x86_64 +test.test_tarfile.LzmaCreateTest.test_eof_marker @ linux-x86_64 +test.test_tarfile.LzmaCreateTest.test_fileobj_no_close @ linux-x86_64 +test.test_tarfile.LzmaDetectReadTest.test_detect_file @ linux-x86_64 +test.test_tarfile.LzmaDetectReadTest.test_detect_fileobj @ linux-x86_64 +test.test_tarfile.LzmaListTest.test_list @ linux-x86_64 +test.test_tarfile.LzmaListTest.test_list_members @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_check_members @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_empty_name_attribute @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_empty_tarfile @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_extract_directory @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_extract_hardlink @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_extract_pathlike_name @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_extractall @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_extractall_pathlike_name @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_fail_comp @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_fileobj_with_offset @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_find_members @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_ignore_zeros @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_illegal_mode_arg @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_init_close_fobj @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_int_name_attribute @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_is_tarfile_erroneous @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_is_tarfile_keeps_position @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_is_tarfile_valid @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_length_zero_header @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_next_on_empty_tarfile @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_no_name_attribute @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_non_existent_tarfile @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_null_tarfile @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_parallel_iteration @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_pathlike_name @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_premature_end_of_archive @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_v7_dirtype @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_xstar_type @ linux-x86_64 +test.test_tarfile.LzmaMiscReadTest.test_zlib_error_does_not_leak @ linux-x86_64 +test.test_tarfile.LzmaStreamReadTest.test_compare_members @ linux-x86_64 +test.test_tarfile.LzmaStreamReadTest.test_empty_tarfile @ linux-x86_64 +test.test_tarfile.LzmaStreamReadTest.test_fileobj_regular_file @ linux-x86_64 +test.test_tarfile.LzmaStreamReadTest.test_ignore_zeros @ linux-x86_64 +test.test_tarfile.LzmaStreamReadTest.test_is_tarfile_erroneous @ linux-x86_64 +test.test_tarfile.LzmaStreamReadTest.test_is_tarfile_keeps_position @ linux-x86_64 +test.test_tarfile.LzmaStreamReadTest.test_is_tarfile_valid @ linux-x86_64 +test.test_tarfile.LzmaStreamReadTest.test_length_zero_header @ linux-x86_64 +test.test_tarfile.LzmaStreamReadTest.test_non_existent_tarfile @ linux-x86_64 +test.test_tarfile.LzmaStreamReadTest.test_null_tarfile @ linux-x86_64 +test.test_tarfile.LzmaStreamReadTest.test_premature_end_of_archive @ linux-x86_64 +test.test_tarfile.LzmaStreamReadTest.test_provoke_stream_error @ linux-x86_64 +test.test_tarfile.LzmaStreamReadTest.test_read_through @ linux-x86_64 +test.test_tarfile.LzmaStreamWriteTest.test_eof_marker @ linux-x86_64 +test.test_tarfile.LzmaStreamWriteTest.test_file_mode @ linux-x86_64 +test.test_tarfile.LzmaStreamWriteTest.test_fileobj_no_close @ linux-x86_64 +test.test_tarfile.LzmaStreamWriteTest.test_stream_padding @ linux-x86_64 +test.test_tarfile.LzmaUstarReadTest.test_add_dir_getmember @ linux-x86_64 +test.test_tarfile.LzmaUstarReadTest.test_fileobj_iter @ linux-x86_64 +test.test_tarfile.LzmaUstarReadTest.test_fileobj_link1 @ linux-x86_64 +test.test_tarfile.LzmaUstarReadTest.test_fileobj_link2 @ linux-x86_64 +test.test_tarfile.LzmaUstarReadTest.test_fileobj_readlines @ linux-x86_64 +test.test_tarfile.LzmaUstarReadTest.test_fileobj_regular_file @ linux-x86_64 +test.test_tarfile.LzmaUstarReadTest.test_fileobj_seek @ linux-x86_64 +test.test_tarfile.LzmaUstarReadTest.test_fileobj_symlink1 @ linux-x86_64 +test.test_tarfile.LzmaUstarReadTest.test_fileobj_symlink2 @ linux-x86_64 +test.test_tarfile.LzmaUstarReadTest.test_fileobj_text @ linux-x86_64 +test.test_tarfile.LzmaUstarReadTest.test_issue14160 @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_100_char_name @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_abs_pathnames @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_add_self @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_cwd @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_directory_size @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_eof_marker @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_extractall_symlinks @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_file_size @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_fileobj_no_close @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_filter @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_gettarinfo_pathlike_name @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_link_size @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_open_nonwritable_fileobj @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_ordered_recursion @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_pathnames @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_symlink_size @ linux-x86_64 +test.test_tarfile.LzmaWriteTest.test_tar_size @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_blktype @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_chrtype @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_conttype @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_dirtype @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_dirtype_with_size @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_fifotype @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_gnusparse @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_gnusparse_00 @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_gnusparse_01 @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_gnusparse_10 @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_lnktype @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_pax_umlauts @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_regtype @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_regtype_oldv7 @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_sparse @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_symtype @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_umlauts @ linux-x86_64 +test.test_tarfile.MemberReadTest.test_find_ustar_longname @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_bytes_name_attribute @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_check_members @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_empty_name_attribute @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_empty_tarfile @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_extract_directory @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_extract_hardlink @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_extract_pathlike_name @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_extractall @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_extractall_pathlike_name @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_fileobj_with_offset @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_find_members @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_ignore_zeros @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_illegal_mode_arg @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_init_close_fobj @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_int_name_attribute @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_is_tarfile_erroneous @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_is_tarfile_keeps_position @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_is_tarfile_valid @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_length_zero_header @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_next_on_empty_tarfile @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_no_name_argument @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_no_name_attribute @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_non_existent_tarfile @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_null_tarfile @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_parallel_iteration @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_pathlike_name @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_premature_end_of_archive @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_v7_dirtype @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_xstar_type @ linux-x86_64 +test.test_tarfile.MiscReadTest.test_zlib_error_does_not_leak @ linux-x86_64 +test.test_tarfile.MiscTest.test__all__ @ linux-x86_64 +test.test_tarfile.MiscTest.test_char_fields @ linux-x86_64 +test.test_tarfile.MiscTest.test_number_field_limits @ linux-x86_64 +test.test_tarfile.MiscTest.test_read_number_fields @ linux-x86_64 +test.test_tarfile.MiscTest.test_useful_error_message_when_modules_missing @ linux-x86_64 +test.test_tarfile.MiscTest.test_write_number_fields @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Data.test_extractall_none_gid @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Data.test_extractall_none_gname @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Data.test_extractall_none_mode @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Data.test_extractall_none_mtime @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Data.test_extractall_none_ownership @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Data.test_extractall_none_uid @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Data.test_extractall_none_uname @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Default.test_extractall_none_gid @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Default.test_extractall_none_gname @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Default.test_extractall_none_mode @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Default.test_extractall_none_mtime @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Default.test_extractall_none_ownership @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Default.test_extractall_none_uid @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Default.test_extractall_none_uname @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_FullyTrusted.test_extractall_none_gid @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_FullyTrusted.test_extractall_none_gname @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_FullyTrusted.test_extractall_none_mode @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_FullyTrusted.test_extractall_none_mtime @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_FullyTrusted.test_extractall_none_ownership @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_FullyTrusted.test_extractall_none_uid @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_FullyTrusted.test_extractall_none_uname @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Tar.test_extractall_none_gid @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Tar.test_extractall_none_gname @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Tar.test_extractall_none_mode @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Tar.test_extractall_none_mtime @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Tar.test_extractall_none_ownership @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Tar.test_extractall_none_uid @ linux-x86_64 +test.test_tarfile.NoneInfoExtractTests_Tar.test_extractall_none_uname @ linux-x86_64 +test.test_tarfile.NoneInfoTests_Misc.test_add @ linux-x86_64 +test.test_tarfile.NoneInfoTests_Misc.test_list @ linux-x86_64 +test.test_tarfile.NumericOwnerTest.test_extract_with_numeric_owner @ linux-x86_64 +test.test_tarfile.NumericOwnerTest.test_extractall_with_numeric_owner @ linux-x86_64 +test.test_tarfile.NumericOwnerTest.test_keyword_only @ linux-x86_64 +test.test_tarfile.PAXUnicodeTest.test_binary_header @ linux-x86_64 +test.test_tarfile.PAXUnicodeTest.test_iso8859_1_filename @ linux-x86_64 +test.test_tarfile.PAXUnicodeTest.test_uname_unicode @ linux-x86_64 +test.test_tarfile.PAXUnicodeTest.test_unicode_argument @ linux-x86_64 +test.test_tarfile.PAXUnicodeTest.test_utf7_filename @ linux-x86_64 +test.test_tarfile.PAXUnicodeTest.test_utf8_filename @ linux-x86_64 +test.test_tarfile.PaxReadTest.test_header_offset @ linux-x86_64 +test.test_tarfile.PaxReadTest.test_longname_directory @ linux-x86_64 +test.test_tarfile.PaxReadTest.test_pax_global_headers @ linux-x86_64 +test.test_tarfile.PaxReadTest.test_pax_number_fields @ linux-x86_64 +test.test_tarfile.PaxReadTest.test_read_longlink @ linux-x86_64 +test.test_tarfile.PaxReadTest.test_read_longname @ linux-x86_64 +test.test_tarfile.PaxReadTest.test_truncated_longname @ linux-x86_64 +test.test_tarfile.PaxWriteTest.test_create_pax_header @ linux-x86_64 +test.test_tarfile.PaxWriteTest.test_longlink_1023 @ linux-x86_64 +test.test_tarfile.PaxWriteTest.test_longlink_1024 @ linux-x86_64 +test.test_tarfile.PaxWriteTest.test_longlink_1025 @ linux-x86_64 +test.test_tarfile.PaxWriteTest.test_longname_1023 @ linux-x86_64 +test.test_tarfile.PaxWriteTest.test_longname_1024 @ linux-x86_64 +test.test_tarfile.PaxWriteTest.test_longname_1025 @ linux-x86_64 +test.test_tarfile.PaxWriteTest.test_longnamelink_1023 @ linux-x86_64 +test.test_tarfile.PaxWriteTest.test_longnamelink_1024 @ linux-x86_64 +test.test_tarfile.PaxWriteTest.test_longnamelink_1025 @ linux-x86_64 +test.test_tarfile.PaxWriteTest.test_pax_extended_header @ linux-x86_64 +test.test_tarfile.PaxWriteTest.test_pax_global_header @ linux-x86_64 +test.test_tarfile.ReplaceTests.test_replace_all @ linux-x86_64 +test.test_tarfile.ReplaceTests.test_replace_deep @ linux-x86_64 +test.test_tarfile.ReplaceTests.test_replace_internal @ linux-x86_64 +test.test_tarfile.ReplaceTests.test_replace_name @ linux-x86_64 +test.test_tarfile.ReplaceTests.test_replace_shallow @ linux-x86_64 +test.test_tarfile.StreamReadTest.test_compare_members @ linux-x86_64 +test.test_tarfile.StreamReadTest.test_empty_tarfile @ linux-x86_64 +test.test_tarfile.StreamReadTest.test_fileobj_regular_file @ linux-x86_64 +test.test_tarfile.StreamReadTest.test_ignore_zeros @ linux-x86_64 +test.test_tarfile.StreamReadTest.test_is_tarfile_erroneous @ linux-x86_64 +test.test_tarfile.StreamReadTest.test_is_tarfile_keeps_position @ linux-x86_64 +test.test_tarfile.StreamReadTest.test_is_tarfile_valid @ linux-x86_64 +test.test_tarfile.StreamReadTest.test_length_zero_header @ linux-x86_64 +test.test_tarfile.StreamReadTest.test_non_existent_tarfile @ linux-x86_64 +test.test_tarfile.StreamReadTest.test_null_tarfile @ linux-x86_64 +test.test_tarfile.StreamReadTest.test_premature_end_of_archive @ linux-x86_64 +test.test_tarfile.StreamReadTest.test_provoke_stream_error @ linux-x86_64 +test.test_tarfile.StreamReadTest.test_read_through @ linux-x86_64 +test.test_tarfile.StreamWriteTest.test_eof_marker @ linux-x86_64 +test.test_tarfile.StreamWriteTest.test_file_mode @ linux-x86_64 +test.test_tarfile.StreamWriteTest.test_fileobj_no_close @ linux-x86_64 +test.test_tarfile.StreamWriteTest.test_stream_padding @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_absolute @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_absolute_hardlink @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_absolute_symlink @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_bad_filter_name @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_benign_file @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_chains @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_change_default_filter_on_class @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_change_default_filter_on_instance @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_change_default_filter_on_subclass @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_change_default_filter_to_string @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_custom_filter @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_data_filter @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_deep_symlink @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_default_filter_warns_not @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_errorlevel @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_fully_trusted_filter @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_parent_symlink @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_parent_symlink2 @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_pipe @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_sly_relative0 @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_sly_relative2 @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_special_files @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_stateful_filter @ linux-x86_64 +test.test_tarfile.TestExtractionFilters.test_tar_filter @ linux-x86_64 +test.test_tarfile.UstarReadTest.test_add_dir_getmember @ linux-x86_64 +test.test_tarfile.UstarReadTest.test_fileobj_iter @ linux-x86_64 +test.test_tarfile.UstarReadTest.test_fileobj_link1 @ linux-x86_64 +test.test_tarfile.UstarReadTest.test_fileobj_link2 @ linux-x86_64 +test.test_tarfile.UstarReadTest.test_fileobj_readlines @ linux-x86_64 +test.test_tarfile.UstarReadTest.test_fileobj_regular_file @ linux-x86_64 +test.test_tarfile.UstarReadTest.test_fileobj_seek @ linux-x86_64 +test.test_tarfile.UstarReadTest.test_fileobj_symlink1 @ linux-x86_64 +test.test_tarfile.UstarReadTest.test_fileobj_symlink2 @ linux-x86_64 +test.test_tarfile.UstarReadTest.test_fileobj_text @ linux-x86_64 +test.test_tarfile.UstarReadTest.test_issue14160 @ linux-x86_64 +test.test_tarfile.UstarUnicodeTest.test_iso8859_1_filename @ linux-x86_64 +test.test_tarfile.UstarUnicodeTest.test_uname_unicode @ linux-x86_64 +test.test_tarfile.UstarUnicodeTest.test_unicode_argument @ linux-x86_64 +test.test_tarfile.UstarUnicodeTest.test_unicode_filename_error @ linux-x86_64 +test.test_tarfile.UstarUnicodeTest.test_unicode_link1 @ linux-x86_64 +test.test_tarfile.UstarUnicodeTest.test_unicode_link2 @ linux-x86_64 +test.test_tarfile.UstarUnicodeTest.test_unicode_longname1 @ linux-x86_64 +test.test_tarfile.UstarUnicodeTest.test_unicode_longname2 @ linux-x86_64 +test.test_tarfile.UstarUnicodeTest.test_unicode_longname3 @ linux-x86_64 +test.test_tarfile.UstarUnicodeTest.test_unicode_longname4 @ linux-x86_64 +test.test_tarfile.UstarUnicodeTest.test_unicode_name1 @ linux-x86_64 +test.test_tarfile.UstarUnicodeTest.test_unicode_name2 @ linux-x86_64 +test.test_tarfile.UstarUnicodeTest.test_utf7_filename @ linux-x86_64 +test.test_tarfile.UstarUnicodeTest.test_utf8_filename @ linux-x86_64 +test.test_tarfile.WriteTest.test_100_char_name @ linux-x86_64 +test.test_tarfile.WriteTest.test_abs_pathnames @ linux-x86_64 +test.test_tarfile.WriteTest.test_add_self @ linux-x86_64 +test.test_tarfile.WriteTest.test_cwd @ linux-x86_64 +test.test_tarfile.WriteTest.test_directory_size @ linux-x86_64 +test.test_tarfile.WriteTest.test_eof_marker @ linux-x86_64 +test.test_tarfile.WriteTest.test_extractall_symlinks @ linux-x86_64 +test.test_tarfile.WriteTest.test_file_size @ linux-x86_64 +test.test_tarfile.WriteTest.test_fileobj_no_close @ linux-x86_64 +test.test_tarfile.WriteTest.test_filter @ linux-x86_64 +test.test_tarfile.WriteTest.test_gettarinfo_pathlike_name @ linux-x86_64 +test.test_tarfile.WriteTest.test_link_size @ linux-x86_64 +test.test_tarfile.WriteTest.test_open_nonwritable_fileobj @ linux-x86_64 +test.test_tarfile.WriteTest.test_ordered_recursion @ linux-x86_64 +test.test_tarfile.WriteTest.test_pathnames @ linux-x86_64 +test.test_tarfile.WriteTest.test_symlink_size @ linux-x86_64 +test.test_tarfile.WriteTest.test_tar_size @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_telnetlib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_telnetlib.txt new file mode 100644 index 0000000000..64870de1a7 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_telnetlib.txt @@ -0,0 +1,19 @@ +test.test_telnetlib.ExpectTests.test_expect @ linux-x86_64 +test.test_telnetlib.GeneralTests.testBasic @ linux-x86_64 +test.test_telnetlib.GeneralTests.testContextManager @ linux-x86_64 +test.test_telnetlib.GeneralTests.testGetters @ linux-x86_64 +test.test_telnetlib.GeneralTests.testTimeoutDefault @ linux-x86_64 +test.test_telnetlib.GeneralTests.testTimeoutNone @ linux-x86_64 +test.test_telnetlib.GeneralTests.testTimeoutOpen @ linux-x86_64 +test.test_telnetlib.GeneralTests.testTimeoutValue @ linux-x86_64 +test.test_telnetlib.OptionTests.test_IAC_commands @ linux-x86_64 +test.test_telnetlib.OptionTests.test_SB_commands @ linux-x86_64 +test.test_telnetlib.OptionTests.test_debug_accepts_str_port @ linux-x86_64 +test.test_telnetlib.OptionTests.test_debuglevel_reads @ linux-x86_64 +test.test_telnetlib.OptionTests.test_debuglevel_write @ linux-x86_64 +test.test_telnetlib.ReadTests.test_read_all @ linux-x86_64 +test.test_telnetlib.ReadTests.test_read_eager @ linux-x86_64 +test.test_telnetlib.ReadTests.test_read_lazy @ linux-x86_64 +test.test_telnetlib.ReadTests.test_read_some @ linux-x86_64 +test.test_telnetlib.ReadTests.test_read_until @ linux-x86_64 +test.test_telnetlib.WriteTests.test_write @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tempfile.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tempfile.txt new file mode 100644 index 0000000000..76c664093e --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tempfile.txt @@ -0,0 +1,94 @@ +test.test_tempfile.TestCandidateTempdirList.test_nonempty_list @ linux-x86_64 +test.test_tempfile.TestCandidateTempdirList.test_wanted_dirs @ linux-x86_64 +test.test_tempfile.TestExports.test_exports @ linux-x86_64 +test.test_tempfile.TestGetCandidateNames.test_retval @ linux-x86_64 +test.test_tempfile.TestGetCandidateNames.test_same_thing @ linux-x86_64 +test.test_tempfile.TestGetDefaultTempdir.test_no_files_left_behind @ linux-x86_64 +test.test_tempfile.TestGetTempDir.test_case_sensitive @ linux-x86_64 +test.test_tempfile.TestGetTempDir.test_directory_exists @ linux-x86_64 +test.test_tempfile.TestGetTempDir.test_directory_writable @ linux-x86_64 +test.test_tempfile.TestGetTempDir.test_same_thing @ linux-x86_64 +test.test_tempfile.TestGetTempPrefix.test_sane_template @ linux-x86_64 +test.test_tempfile.TestGetTempPrefix.test_usable_template @ linux-x86_64 +test.test_tempfile.TestLowLevelInternals.test_infer_return_type_multiples @ linux-x86_64 +test.test_tempfile.TestLowLevelInternals.test_infer_return_type_multiples_and_none @ linux-x86_64 +test.test_tempfile.TestLowLevelInternals.test_infer_return_type_pathlib @ linux-x86_64 +test.test_tempfile.TestLowLevelInternals.test_infer_return_type_pathlike @ linux-x86_64 +test.test_tempfile.TestLowLevelInternals.test_infer_return_type_singles @ linux-x86_64 +test.test_tempfile.TestMkdtemp.test_basic @ linux-x86_64 +test.test_tempfile.TestMkdtemp.test_basic_many @ linux-x86_64 +test.test_tempfile.TestMkdtemp.test_basic_with_bytes_names @ linux-x86_64 +test.test_tempfile.TestMkdtemp.test_choose_directory @ linux-x86_64 +test.test_tempfile.TestMkdtemp.test_collision_with_existing_directory @ linux-x86_64 +test.test_tempfile.TestMkdtemp.test_collision_with_existing_file @ linux-x86_64 +test.test_tempfile.TestMkdtemp.test_for_tempdir_is_bytes_issue40701_api_warts @ linux-x86_64 +test.test_tempfile.TestMkdtemp.test_mode @ linux-x86_64 +test.test_tempfile.TestMkdtemp.test_non_directory @ linux-x86_64 +test.test_tempfile.TestMkdtemp.test_nonexisting_directory @ linux-x86_64 +test.test_tempfile.TestMkdtemp.test_read_only_directory @ linux-x86_64 +test.test_tempfile.TestMkstemp.test_basic @ linux-x86_64 +test.test_tempfile.TestMkstemp.test_basic_with_bytes_names @ linux-x86_64 +test.test_tempfile.TestMkstemp.test_choose_directory @ linux-x86_64 +test.test_tempfile.TestMkstemp.test_for_tempdir_is_bytes_issue40701_api_warts @ linux-x86_64 +test.test_tempfile.TestMkstempInner.test_basic @ linux-x86_64 +test.test_tempfile.TestMkstempInner.test_basic_many @ linux-x86_64 +test.test_tempfile.TestMkstempInner.test_basic_with_bytes_names @ linux-x86_64 +test.test_tempfile.TestMkstempInner.test_collision_with_existing_directory @ linux-x86_64 +test.test_tempfile.TestMkstempInner.test_collision_with_existing_file @ linux-x86_64 +test.test_tempfile.TestMkstempInner.test_file_mode @ linux-x86_64 +test.test_tempfile.TestMkstempInner.test_non_directory @ linux-x86_64 +test.test_tempfile.TestMkstempInner.test_nonexisting_directory @ linux-x86_64 +test.test_tempfile.TestMkstempInner.test_read_only_directory @ linux-x86_64 +test.test_tempfile.TestNamedTemporaryFile.test_bad_encoding @ linux-x86_64 +test.test_tempfile.TestNamedTemporaryFile.test_bad_mode @ linux-x86_64 +test.test_tempfile.TestNamedTemporaryFile.test_basic @ linux-x86_64 +test.test_tempfile.TestNamedTemporaryFile.test_context_manager @ linux-x86_64 +test.test_tempfile.TestNamedTemporaryFile.test_creates_named @ linux-x86_64 +test.test_tempfile.TestNamedTemporaryFile.test_del_on_close @ linux-x86_64 +test.test_tempfile.TestNamedTemporaryFile.test_dis_del_on_close @ linux-x86_64 +test.test_tempfile.TestNamedTemporaryFile.test_iter @ linux-x86_64 +test.test_tempfile.TestNamedTemporaryFile.test_method_lookup @ linux-x86_64 +test.test_tempfile.TestNamedTemporaryFile.test_multiple_close @ linux-x86_64 +test.test_tempfile.TestNamedTemporaryFile.test_unexpected_error @ linux-x86_64 +test.test_tempfile.TestRandomNameSequence.test_get_eight_char_str @ linux-x86_64 +test.test_tempfile.TestRandomNameSequence.test_many @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_basic @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_bound_methods @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_class_getitem @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_context_manager_after_rollover @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_context_manager_before_rollover @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_context_manager_during_rollover @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_del_on_close @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_del_rolled_file @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_del_unrolled_file @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_fileno @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_iobase_interface @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_is_iobase @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_multiple_close_after_rollover @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_multiple_close_before_rollover @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_properties @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_rewrite_small @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_sparse @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_text_mode @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_text_newline_and_encoding @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_truncate_with_size_parameter @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_write_sequential @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_writelines @ linux-x86_64 +test.test_tempfile.TestSpooledTemporaryFile.test_writelines_sequential @ linux-x86_64 +test.test_tempfile.TestTemporaryDirectory.test_cleanup_with_symlink_to_a_directory @ linux-x86_64 +test.test_tempfile.TestTemporaryDirectory.test_context_manager @ linux-x86_64 +test.test_tempfile.TestTemporaryDirectory.test_del_on_shutdown @ linux-x86_64 +test.test_tempfile.TestTemporaryDirectory.test_del_on_shutdown_ignore_errors @ linux-x86_64 +test.test_tempfile.TestTemporaryDirectory.test_exit_on_shutdown @ linux-x86_64 +test.test_tempfile.TestTemporaryDirectory.test_explicit_cleanup @ linux-x86_64 +test.test_tempfile.TestTemporaryDirectory.test_explict_cleanup_ignore_errors @ linux-x86_64 +test.test_tempfile.TestTemporaryDirectory.test_mkdtemp_failure @ linux-x86_64 +test.test_tempfile.TestTemporaryDirectory.test_modes @ linux-x86_64 +test.test_tempfile.TestTemporaryDirectory.test_multiple_close @ linux-x86_64 +test.test_tempfile.TestTemporaryFile.test_bad_encoding @ linux-x86_64 +test.test_tempfile.TestTemporaryFile.test_bad_mode @ linux-x86_64 +test.test_tempfile.TestTemporaryFile.test_basic @ linux-x86_64 +test.test_tempfile.TestTemporaryFile.test_has_no_name @ linux-x86_64 +test.test_tempfile.TestTemporaryFile.test_mode_and_encoding @ linux-x86_64 +test.test_tempfile.TestTemporaryFile.test_multiple_close @ linux-x86_64 +test.test_tempfile.TestTemporaryFile.test_unexpected_error @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_termios.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_termios.txt new file mode 100644 index 0000000000..7735e458a0 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_termios.txt @@ -0,0 +1,18 @@ +test.test_termios.TestFunctions.test_tcdrain @ linux-x86_64 +test.test_termios.TestFunctions.test_tcdrain_errors @ linux-x86_64 +test.test_termios.TestFunctions.test_tcflow @ linux-x86_64 +test.test_termios.TestFunctions.test_tcflow_errors @ linux-x86_64 +test.test_termios.TestFunctions.test_tcflush @ linux-x86_64 +test.test_termios.TestFunctions.test_tcflush_errors @ linux-x86_64 +test.test_termios.TestFunctions.test_tcgetattr @ linux-x86_64 +test.test_termios.TestFunctions.test_tcgetattr_errors @ linux-x86_64 +test.test_termios.TestFunctions.test_tcgetwinsize @ linux-x86_64 +test.test_termios.TestFunctions.test_tcgetwinsize_errors @ linux-x86_64 +test.test_termios.TestFunctions.test_tcsendbreak @ linux-x86_64 +test.test_termios.TestFunctions.test_tcsendbreak_errors @ linux-x86_64 +test.test_termios.TestFunctions.test_tcsetattr @ linux-x86_64 +test.test_termios.TestFunctions.test_tcsetattr_errors @ linux-x86_64 +test.test_termios.TestFunctions.test_tcsetwinsize @ linux-x86_64 +test.test_termios.TestFunctions.test_tcsetwinsize_errors @ linux-x86_64 +test.test_termios.TestModule.test_constants @ linux-x86_64 +test.test_termios.TestModule.test_exception @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_textwrap.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_textwrap.txt new file mode 100644 index 0000000000..32ee862849 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_textwrap.txt @@ -0,0 +1,66 @@ +test.test_textwrap.DedentTestCase.test_dedent_declining @ linux-x86_64 +test.test_textwrap.DedentTestCase.test_dedent_even @ linux-x86_64 +test.test_textwrap.DedentTestCase.test_dedent_nomargin @ linux-x86_64 +test.test_textwrap.DedentTestCase.test_dedent_preserve_internal_tabs @ linux-x86_64 +test.test_textwrap.DedentTestCase.test_dedent_preserve_margin_tabs @ linux-x86_64 +test.test_textwrap.DedentTestCase.test_dedent_uneven @ linux-x86_64 +test.test_textwrap.IndentTestCase.test_indent_all_lines @ linux-x86_64 +test.test_textwrap.IndentTestCase.test_indent_default @ linux-x86_64 +test.test_textwrap.IndentTestCase.test_indent_empty_lines @ linux-x86_64 +test.test_textwrap.IndentTestCase.test_indent_explicit_default @ linux-x86_64 +test.test_textwrap.IndentTestCase.test_indent_no_lines @ linux-x86_64 +test.test_textwrap.IndentTestCase.test_indent_nomargin_all_lines @ linux-x86_64 +test.test_textwrap.IndentTestCase.test_indent_nomargin_default @ linux-x86_64 +test.test_textwrap.IndentTestCase.test_indent_nomargin_explicit_default @ linux-x86_64 +test.test_textwrap.IndentTestCase.test_roundtrip_mixed @ linux-x86_64 +test.test_textwrap.IndentTestCase.test_roundtrip_spaces @ linux-x86_64 +test.test_textwrap.IndentTestCase.test_roundtrip_tabs @ linux-x86_64 +test.test_textwrap.IndentTestCases.test_fill @ linux-x86_64 +test.test_textwrap.IndentTestCases.test_initial_indent @ linux-x86_64 +test.test_textwrap.IndentTestCases.test_subsequent_indent @ linux-x86_64 +test.test_textwrap.LongWordTestCase.test_break_long @ linux-x86_64 +test.test_textwrap.LongWordTestCase.test_max_lines_long @ linux-x86_64 +test.test_textwrap.LongWordTestCase.test_nobreak_long @ linux-x86_64 +test.test_textwrap.LongWordWithHyphensTestCase.test_break_long_words_not_on_hyphen @ linux-x86_64 +test.test_textwrap.LongWordWithHyphensTestCase.test_break_long_words_on_hyphen @ linux-x86_64 +test.test_textwrap.LongWordWithHyphensTestCase.test_break_on_hyphen_but_not_long_words @ linux-x86_64 +test.test_textwrap.LongWordWithHyphensTestCase.test_do_not_break_long_words_or_on_hyphens @ linux-x86_64 +test.test_textwrap.MaxLinesTestCase.test_placeholder @ linux-x86_64 +test.test_textwrap.MaxLinesTestCase.test_placeholder_backtrack @ linux-x86_64 +test.test_textwrap.MaxLinesTestCase.test_simple @ linux-x86_64 +test.test_textwrap.MaxLinesTestCase.test_spaces @ linux-x86_64 +test.test_textwrap.ShortenTestCase.test_empty_string @ linux-x86_64 +test.test_textwrap.ShortenTestCase.test_first_word_too_long_but_placeholder_fits @ linux-x86_64 +test.test_textwrap.ShortenTestCase.test_placeholder @ linux-x86_64 +test.test_textwrap.ShortenTestCase.test_simple @ linux-x86_64 +test.test_textwrap.ShortenTestCase.test_whitespace @ linux-x86_64 +test.test_textwrap.ShortenTestCase.test_width_too_small_for_placeholder @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_bad_width @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_break_on_hyphens @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_drop_whitespace_false @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_drop_whitespace_false_whitespace_only @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_drop_whitespace_false_whitespace_only_with_indent @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_drop_whitespace_leading_whitespace @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_drop_whitespace_whitespace_indent @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_drop_whitespace_whitespace_line @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_drop_whitespace_whitespace_only @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_drop_whitespace_whitespace_only_with_indent @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_em_dash @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_empty_string @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_empty_string_with_initial_indent @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_fix_sentence_endings @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_funky_hyphens @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_funky_parens @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_hyphenated @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_hyphenated_numbers @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_narrow_non_breaking_space @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_no_split_at_umlaut @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_non_breaking_space @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_punct_hyphens @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_simple @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_split @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_umlaut_followed_by_dash @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_unix_options @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_whitespace @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_wrap_short @ linux-x86_64 +test.test_textwrap.WrapTestCase.test_wrap_short_1line @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_thread.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_thread.txt new file mode 100644 index 0000000000..b74b8246e5 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_thread.txt @@ -0,0 +1,20 @@ +test.test_thread.BarrierTest.test_barrier @ linux-x86_64 +test.test_thread.LockTests.test_acquire_contended @ linux-x86_64 +test.test_thread.LockTests.test_acquire_destroy @ linux-x86_64 +test.test_thread.LockTests.test_acquire_release @ linux-x86_64 +test.test_thread.LockTests.test_constructor @ linux-x86_64 +test.test_thread.LockTests.test_different_thread @ linux-x86_64 +test.test_thread.LockTests.test_locked_repr @ linux-x86_64 +test.test_thread.LockTests.test_reacquire @ linux-x86_64 +test.test_thread.LockTests.test_repr @ linux-x86_64 +test.test_thread.LockTests.test_state_after_timeout @ linux-x86_64 +test.test_thread.LockTests.test_thread_leak @ linux-x86_64 +test.test_thread.LockTests.test_timeout @ linux-x86_64 +test.test_thread.LockTests.test_try_acquire @ linux-x86_64 +test.test_thread.LockTests.test_try_acquire_contended @ linux-x86_64 +test.test_thread.LockTests.test_weakref_exists @ linux-x86_64 +test.test_thread.LockTests.test_with @ linux-x86_64 +test.test_thread.ThreadRunningTests.test__count @ linux-x86_64 +test.test_thread.ThreadRunningTests.test_nt_and_posix_stack_size @ linux-x86_64 +test.test_thread.ThreadRunningTests.test_stack_size @ linux-x86_64 +test.test_thread.ThreadRunningTests.test_starting_threads @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_threadedtempfile.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_threadedtempfile.txt new file mode 100644 index 0000000000..5b419df28f --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_threadedtempfile.txt @@ -0,0 +1 @@ +test.test_threadedtempfile.ThreadedTempFileTest.test_main @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_threading.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_threading.txt new file mode 100644 index 0000000000..d5be4bb77f --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_threading.txt @@ -0,0 +1,158 @@ +test.test_threading.AtexitTests.test_atexit_called_once @ linux-x86_64 +test.test_threading.AtexitTests.test_atexit_output @ linux-x86_64 +test.test_threading.BarrierTests.test_abort @ linux-x86_64 +test.test_threading.BarrierTests.test_abort_and_reset @ linux-x86_64 +test.test_threading.BarrierTests.test_action @ linux-x86_64 +test.test_threading.BarrierTests.test_barrier @ linux-x86_64 +test.test_threading.BarrierTests.test_barrier_10 @ linux-x86_64 +test.test_threading.BarrierTests.test_default_timeout @ linux-x86_64 +test.test_threading.BarrierTests.test_repr @ linux-x86_64 +test.test_threading.BarrierTests.test_reset @ linux-x86_64 +test.test_threading.BarrierTests.test_single_thread @ linux-x86_64 +test.test_threading.BarrierTests.test_timeout @ linux-x86_64 +test.test_threading.BarrierTests.test_wait_return @ linux-x86_64 +test.test_threading.BoundedSemaphoreTests.test_acquire @ linux-x86_64 +test.test_threading.BoundedSemaphoreTests.test_acquire_contended @ linux-x86_64 +test.test_threading.BoundedSemaphoreTests.test_acquire_destroy @ linux-x86_64 +test.test_threading.BoundedSemaphoreTests.test_acquire_timeout @ linux-x86_64 +test.test_threading.BoundedSemaphoreTests.test_constructor @ linux-x86_64 +test.test_threading.BoundedSemaphoreTests.test_default_value @ linux-x86_64 +test.test_threading.BoundedSemaphoreTests.test_multirelease @ linux-x86_64 +test.test_threading.BoundedSemaphoreTests.test_release_unacquired @ linux-x86_64 +test.test_threading.BoundedSemaphoreTests.test_repr @ linux-x86_64 +test.test_threading.BoundedSemaphoreTests.test_try_acquire @ linux-x86_64 +test.test_threading.BoundedSemaphoreTests.test_try_acquire_contended @ linux-x86_64 +test.test_threading.BoundedSemaphoreTests.test_with @ linux-x86_64 +test.test_threading.CRLockTests.test__is_owned @ linux-x86_64 +test.test_threading.CRLockTests.test_acquire_contended @ linux-x86_64 +test.test_threading.CRLockTests.test_acquire_destroy @ linux-x86_64 +test.test_threading.CRLockTests.test_acquire_release @ linux-x86_64 +test.test_threading.CRLockTests.test_constructor @ linux-x86_64 +test.test_threading.CRLockTests.test_different_thread @ linux-x86_64 +test.test_threading.CRLockTests.test_locked_repr @ linux-x86_64 +test.test_threading.CRLockTests.test_reacquire @ linux-x86_64 +test.test_threading.CRLockTests.test_recursion_count @ linux-x86_64 +test.test_threading.CRLockTests.test_release_save_unacquired @ linux-x86_64 +test.test_threading.CRLockTests.test_release_unacquired @ linux-x86_64 +test.test_threading.CRLockTests.test_repr @ linux-x86_64 +test.test_threading.CRLockTests.test_thread_leak @ linux-x86_64 +test.test_threading.CRLockTests.test_timeout @ linux-x86_64 +test.test_threading.CRLockTests.test_try_acquire @ linux-x86_64 +test.test_threading.CRLockTests.test_try_acquire_contended @ linux-x86_64 +test.test_threading.CRLockTests.test_weakref_exists @ linux-x86_64 +test.test_threading.CRLockTests.test_with @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test__is_owned @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_acquire_contended @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_acquire_destroy @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_acquire_release @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_constructor @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_different_thread @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_locked_repr @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_reacquire @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_release_save_unacquired @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_release_unacquired @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_repr @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_thread_leak @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_timeout @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_try_acquire @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_try_acquire_contended @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_weakref_exists @ linux-x86_64 +test.test_threading.ConditionAsRLockTests.test_with @ linux-x86_64 +test.test_threading.ConditionTests.test_acquire @ linux-x86_64 +test.test_threading.ConditionTests.test_notify @ linux-x86_64 +test.test_threading.ConditionTests.test_timeout @ linux-x86_64 +test.test_threading.ConditionTests.test_unacquired_notify @ linux-x86_64 +test.test_threading.ConditionTests.test_unacquired_wait @ linux-x86_64 +test.test_threading.ConditionTests.test_waitfor @ linux-x86_64 +test.test_threading.ConditionTests.test_waitfor_timeout @ linux-x86_64 +test.test_threading.EventTests.test_is_set @ linux-x86_64 +test.test_threading.EventTests.test_notify @ linux-x86_64 +test.test_threading.EventTests.test_repr @ linux-x86_64 +test.test_threading.EventTests.test_set_and_clear @ linux-x86_64 +test.test_threading.EventTests.test_timeout @ linux-x86_64 +test.test_threading.ExceptHookTests.test_custom_excepthook @ linux-x86_64 +test.test_threading.ExceptHookTests.test_custom_excepthook_fail @ linux-x86_64 +test.test_threading.ExceptHookTests.test_excepthook @ linux-x86_64 +test.test_threading.ExceptHookTests.test_original_excepthook @ linux-x86_64 +test.test_threading.ExceptHookTests.test_system_exit @ linux-x86_64 +test.test_threading.InterruptMainTests.test_interrupt_main_noerror @ linux-x86_64 +test.test_threading.LockTests.test_acquire_contended @ linux-x86_64 +test.test_threading.LockTests.test_acquire_destroy @ linux-x86_64 +test.test_threading.LockTests.test_acquire_release @ linux-x86_64 +test.test_threading.LockTests.test_constructor @ linux-x86_64 +test.test_threading.LockTests.test_different_thread @ linux-x86_64 +test.test_threading.LockTests.test_locked_repr @ linux-x86_64 +test.test_threading.LockTests.test_reacquire @ linux-x86_64 +test.test_threading.LockTests.test_repr @ linux-x86_64 +test.test_threading.LockTests.test_state_after_timeout @ linux-x86_64 +test.test_threading.LockTests.test_thread_leak @ linux-x86_64 +test.test_threading.LockTests.test_timeout @ linux-x86_64 +test.test_threading.LockTests.test_try_acquire @ linux-x86_64 +test.test_threading.LockTests.test_try_acquire_contended @ linux-x86_64 +test.test_threading.LockTests.test_weakref_exists @ linux-x86_64 +test.test_threading.LockTests.test_with @ linux-x86_64 +test.test_threading.MiscTestCase.test__all__ @ linux-x86_64 +test.test_threading.PyRLockTests.test__is_owned @ linux-x86_64 +test.test_threading.PyRLockTests.test_acquire_contended @ linux-x86_64 +test.test_threading.PyRLockTests.test_acquire_destroy @ linux-x86_64 +test.test_threading.PyRLockTests.test_acquire_release @ linux-x86_64 +test.test_threading.PyRLockTests.test_constructor @ linux-x86_64 +test.test_threading.PyRLockTests.test_different_thread @ linux-x86_64 +test.test_threading.PyRLockTests.test_locked_repr @ linux-x86_64 +test.test_threading.PyRLockTests.test_reacquire @ linux-x86_64 +test.test_threading.PyRLockTests.test_recursion_count @ linux-x86_64 +test.test_threading.PyRLockTests.test_release_save_unacquired @ linux-x86_64 +test.test_threading.PyRLockTests.test_release_unacquired @ linux-x86_64 +test.test_threading.PyRLockTests.test_repr @ linux-x86_64 +test.test_threading.PyRLockTests.test_thread_leak @ linux-x86_64 +test.test_threading.PyRLockTests.test_timeout @ linux-x86_64 +test.test_threading.PyRLockTests.test_try_acquire @ linux-x86_64 +test.test_threading.PyRLockTests.test_try_acquire_contended @ linux-x86_64 +test.test_threading.PyRLockTests.test_weakref_exists @ linux-x86_64 +test.test_threading.PyRLockTests.test_with @ linux-x86_64 +test.test_threading.SemaphoreTests.test_acquire @ linux-x86_64 +test.test_threading.SemaphoreTests.test_acquire_contended @ linux-x86_64 +test.test_threading.SemaphoreTests.test_acquire_destroy @ linux-x86_64 +test.test_threading.SemaphoreTests.test_acquire_timeout @ linux-x86_64 +test.test_threading.SemaphoreTests.test_constructor @ linux-x86_64 +test.test_threading.SemaphoreTests.test_default_value @ linux-x86_64 +test.test_threading.SemaphoreTests.test_multirelease @ linux-x86_64 +test.test_threading.SemaphoreTests.test_release_unacquired @ linux-x86_64 +test.test_threading.SemaphoreTests.test_repr @ linux-x86_64 +test.test_threading.SemaphoreTests.test_try_acquire @ linux-x86_64 +test.test_threading.SemaphoreTests.test_try_acquire_contended @ linux-x86_64 +test.test_threading.SemaphoreTests.test_with @ linux-x86_64 +!test.test_threading.ThreadJoinOnShutdown.test_4_daemon_threads @ linux-x86_64 +test.test_threading.ThreadTests.test_BoundedSemaphore_limit @ linux-x86_64 +test.test_threading.ThreadTests.test_args_argument @ linux-x86_64 +test.test_threading.ThreadTests.test_boolean_target @ linux-x86_64 +test.test_threading.ThreadTests.test_daemon_param @ linux-x86_64 +test.test_threading.ThreadTests.test_enumerate_after_join @ linux-x86_64 +!test.test_threading.ThreadTests.test_finalization_shutdown @ linux-x86_64 +!test.test_threading.ThreadTests.test_finalize_with_trace @ linux-x86_64 +test.test_threading.ThreadTests.test_foreign_thread @ linux-x86_64 +test.test_threading.ThreadTests.test_getprofile @ linux-x86_64 +test.test_threading.ThreadTests.test_gettrace @ linux-x86_64 +test.test_threading.ThreadTests.test_ident_of_no_threading_threads @ linux-x86_64 +!test.test_threading.ThreadTests.test_import_from_another_thread @ linux-x86_64 +!test.test_threading.ThreadTests.test_join_nondaemon_on_shutdown @ linux-x86_64 +test.test_threading.ThreadTests.test_leak_without_join @ linux-x86_64 +test.test_threading.ThreadTests.test_limbo_cleanup @ linux-x86_64 +test.test_threading.ThreadTests.test_main_thread @ linux-x86_64 +test.test_threading.ThreadTests.test_old_threading_api @ linux-x86_64 +test.test_threading.ThreadTests.test_repr_daemon @ linux-x86_64 +test.test_threading.ThreadTests.test_repr_stopped @ linux-x86_64 +test.test_threading.ThreadTests.test_tstate_lock @ linux-x86_64 +test.test_threading.ThreadTests.test_various_ops @ linux-x86_64 +test.test_threading.ThreadTests.test_various_ops_large_stack @ linux-x86_64 +test.test_threading.ThreadTests.test_various_ops_small_stack @ linux-x86_64 +test.test_threading.ThreadingExceptionTests.test_bare_raise_in_brand_new_thread @ linux-x86_64 +test.test_threading.ThreadingExceptionTests.test_daemonize_active_thread @ linux-x86_64 +test.test_threading.ThreadingExceptionTests.test_joining_current_thread @ linux-x86_64 +test.test_threading.ThreadingExceptionTests.test_joining_inactive_thread @ linux-x86_64 +test.test_threading.ThreadingExceptionTests.test_multithread_modify_file_noerror @ linux-x86_64 +!test.test_threading.ThreadingExceptionTests.test_print_exception @ linux-x86_64 +!test.test_threading.ThreadingExceptionTests.test_print_exception_stderr_is_none_1 @ linux-x86_64 +!test.test_threading.ThreadingExceptionTests.test_print_exception_stderr_is_none_2 @ linux-x86_64 +test.test_threading.ThreadingExceptionTests.test_start_thread_again @ linux-x86_64 +test.test_threading.TimerTests.test_init_immutable_default_args @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_threading_local.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_threading_local.txt new file mode 100644 index 0000000000..401bc5f565 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_threading_local.txt @@ -0,0 +1,15 @@ +!DocTestCase._threading_local @ linux-x86_64 +test.test_threading_local.PyThreadingLocalTest.test_arguments @ linux-x86_64 +test.test_threading_local.PyThreadingLocalTest.test_derived @ linux-x86_64 +test.test_threading_local.PyThreadingLocalTest.test_derived_cycle_dealloc @ linux-x86_64 +test.test_threading_local.PyThreadingLocalTest.test_dict_attribute @ linux-x86_64 +test.test_threading_local.PyThreadingLocalTest.test_dict_attribute_subclass @ linux-x86_64 +test.test_threading_local.PyThreadingLocalTest.test_threading_local @ linux-x86_64 +test.test_threading_local.PyThreadingLocalTest.test_threading_local_subclass @ linux-x86_64 +test.test_threading_local.ThreadLocalTest.test_arguments @ linux-x86_64 +test.test_threading_local.ThreadLocalTest.test_derived @ linux-x86_64 +test.test_threading_local.ThreadLocalTest.test_derived_cycle_dealloc @ linux-x86_64 +test.test_threading_local.ThreadLocalTest.test_dict_attribute @ linux-x86_64 +test.test_threading_local.ThreadLocalTest.test_dict_attribute_subclass @ linux-x86_64 +test.test_threading_local.ThreadLocalTest.test_threading_local @ linux-x86_64 +test.test_threading_local.ThreadLocalTest.test_threading_local_subclass @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_threadsignals.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_threadsignals.txt new file mode 100644 index 0000000000..f00fb4dab4 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_threadsignals.txt @@ -0,0 +1,3 @@ +test.test_threadsignals.ThreadSignals.test_lock_acquire_retries_on_intr @ linux-x86_64 +test.test_threadsignals.ThreadSignals.test_rlock_acquire_retries_on_intr @ linux-x86_64 +test.test_threadsignals.ThreadSignals.test_signals @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_time.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_time.txt new file mode 100644 index 0000000000..0f81dc29a6 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_time.txt @@ -0,0 +1,32 @@ +test.test_time.TestAsctime4dyear.test_large_year @ linux-x86_64 +test.test_time.TestAsctime4dyear.test_negative @ linux-x86_64 +test.test_time.TestAsctime4dyear.test_year @ linux-x86_64 +test.test_time.TestLocale.test_bug_3061 @ linux-x86_64 +test.test_time.TestPytime.test_localtime_timezone @ linux-x86_64 +test.test_time.TestPytime.test_short_times @ linux-x86_64 +test.test_time.TestStrftime4dyear.test_large_year @ linux-x86_64 +test.test_time.TestStrftime4dyear.test_negative @ linux-x86_64 +test.test_time.TestStrftime4dyear.test_year @ linux-x86_64 +test.test_time.TimeTestCase.test_asctime @ linux-x86_64 +test.test_time.TimeTestCase.test_asctime_bounding_check @ linux-x86_64 +test.test_time.TimeTestCase.test_conversions @ linux-x86_64 +test.test_time.TimeTestCase.test_ctime @ linux-x86_64 +test.test_time.TimeTestCase.test_ctime_without_arg @ linux-x86_64 +test.test_time.TimeTestCase.test_data_attributes @ linux-x86_64 +test.test_time.TimeTestCase.test_default_values_for_zero @ linux-x86_64 +test.test_time.TimeTestCase.test_epoch @ linux-x86_64 +test.test_time.TimeTestCase.test_get_clock_info @ linux-x86_64 +test.test_time.TimeTestCase.test_insane_timestamps @ linux-x86_64 +test.test_time.TimeTestCase.test_mktime @ linux-x86_64 +test.test_time.TimeTestCase.test_monotonic @ linux-x86_64 +test.test_time.TimeTestCase.test_perf_counter @ linux-x86_64 +test.test_time.TimeTestCase.test_process_time @ linux-x86_64 +test.test_time.TimeTestCase.test_sleep @ linux-x86_64 +test.test_time.TimeTestCase.test_strftime @ linux-x86_64 +test.test_time.TimeTestCase.test_strftime_bounding_check @ linux-x86_64 +test.test_time.TimeTestCase.test_strftime_format_check @ linux-x86_64 +test.test_time.TimeTestCase.test_strptime_bytes @ linux-x86_64 +test.test_time.TimeTestCase.test_strptime_exception_context @ linux-x86_64 +test.test_time.TimeTestCase.test_thread_time @ linux-x86_64 +test.test_time.TimeTestCase.test_time @ linux-x86_64 +test.test_time.TimeTestCase.test_time_ns_type @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_timeit.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_timeit.txt new file mode 100644 index 0000000000..c878cc9509 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_timeit.txt @@ -0,0 +1,39 @@ +test.test_timeit.TestTimeit.test_autorange @ linux-x86_64 +test.test_timeit.TestTimeit.test_autorange_second @ linux-x86_64 +test.test_timeit.TestTimeit.test_autorange_with_callback @ linux-x86_64 +test.test_timeit.TestTimeit.test_main_bad_switch @ linux-x86_64 +test.test_timeit.TestTimeit.test_main_exception @ linux-x86_64 +test.test_timeit.TestTimeit.test_main_exception_fixed_reps @ linux-x86_64 +test.test_timeit.TestTimeit.test_main_fixed_iters @ linux-x86_64 +test.test_timeit.TestTimeit.test_main_fixed_reps @ linux-x86_64 +test.test_timeit.TestTimeit.test_main_help @ linux-x86_64 +test.test_timeit.TestTimeit.test_main_microseconds @ linux-x86_64 +test.test_timeit.TestTimeit.test_main_milliseconds @ linux-x86_64 +test.test_timeit.TestTimeit.test_main_multiple_setups @ linux-x86_64 +test.test_timeit.TestTimeit.test_main_negative_reps @ linux-x86_64 +test.test_timeit.TestTimeit.test_main_seconds @ linux-x86_64 +test.test_timeit.TestTimeit.test_main_setup @ linux-x86_64 +test.test_timeit.TestTimeit.test_main_verbose @ linux-x86_64 +test.test_timeit.TestTimeit.test_main_very_verbose @ linux-x86_64 +test.test_timeit.TestTimeit.test_main_with_time_unit @ linux-x86_64 +test.test_timeit.TestTimeit.test_print_exc @ linux-x86_64 +test.test_timeit.TestTimeit.test_reindent_empty @ linux-x86_64 +test.test_timeit.TestTimeit.test_reindent_multi @ linux-x86_64 +test.test_timeit.TestTimeit.test_reindent_multi_empty @ linux-x86_64 +test.test_timeit.TestTimeit.test_reindent_single @ linux-x86_64 +test.test_timeit.TestTimeit.test_repeat_callable_setup @ linux-x86_64 +test.test_timeit.TestTimeit.test_repeat_callable_stmt @ linux-x86_64 +test.test_timeit.TestTimeit.test_repeat_callable_stmt_and_setup @ linux-x86_64 +test.test_timeit.TestTimeit.test_repeat_few_reps_and_iters @ linux-x86_64 +test.test_timeit.TestTimeit.test_repeat_function_zero_iters @ linux-x86_64 +test.test_timeit.TestTimeit.test_repeat_function_zero_reps @ linux-x86_64 +test.test_timeit.TestTimeit.test_repeat_zero_iters @ linux-x86_64 +test.test_timeit.TestTimeit.test_repeat_zero_reps @ linux-x86_64 +test.test_timeit.TestTimeit.test_timeit_callable_setup @ linux-x86_64 +test.test_timeit.TestTimeit.test_timeit_callable_stmt @ linux-x86_64 +test.test_timeit.TestTimeit.test_timeit_callable_stmt_and_setup @ linux-x86_64 +test.test_timeit.TestTimeit.test_timeit_few_iters @ linux-x86_64 +test.test_timeit.TestTimeit.test_timeit_function_zero_iters @ linux-x86_64 +test.test_timeit.TestTimeit.test_timeit_globals_args @ linux-x86_64 +test.test_timeit.TestTimeit.test_timeit_zero_iters @ linux-x86_64 +test.test_timeit.TestTimeit.test_timer_empty_stmt @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_timeout.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_timeout.txt new file mode 100644 index 0000000000..5807452fbc --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_timeout.txt @@ -0,0 +1,12 @@ +test.test_timeout.CreationTestCase.testBlockingThenTimeout @ linux-x86_64 +test.test_timeout.CreationTestCase.testFloatReturnValue @ linux-x86_64 +test.test_timeout.CreationTestCase.testObjectCreation @ linux-x86_64 +test.test_timeout.CreationTestCase.testRangeCheck @ linux-x86_64 +test.test_timeout.CreationTestCase.testReturnType @ linux-x86_64 +test.test_timeout.CreationTestCase.testTimeoutThenBlocking @ linux-x86_64 +test.test_timeout.CreationTestCase.testTypeCheck @ linux-x86_64 +test.test_timeout.TCPTimeoutTestCase.testAcceptTimeout @ linux-x86_64 +test.test_timeout.TCPTimeoutTestCase.testSend @ linux-x86_64 +test.test_timeout.TCPTimeoutTestCase.testSendall @ linux-x86_64 +test.test_timeout.TCPTimeoutTestCase.testSendto @ linux-x86_64 +test.test_timeout.UDPTimeoutTestCase.testRecvfromTimeout @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tokenize.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tokenize.txt new file mode 100644 index 0000000000..2049643a32 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tokenize.txt @@ -0,0 +1,95 @@ +test.test_tokenize.CTokenizeTest.test_additive @ linux-x86_64 +test.test_tokenize.CTokenizeTest.test_async @ linux-x86_64 +test.test_tokenize.CTokenizeTest.test_comparison @ linux-x86_64 +test.test_tokenize.CTokenizeTest.test_continuation_lines_indentation @ linux-x86_64 +test.test_tokenize.CTokenizeTest.test_float @ linux-x86_64 +test.test_tokenize.CTokenizeTest.test_function @ linux-x86_64 +test.test_tokenize.CTokenizeTest.test_int @ linux-x86_64 +test.test_tokenize.CTokenizeTest.test_invalid_syntax @ linux-x86_64 +test.test_tokenize.CTokenizeTest.test_max_indent @ linux-x86_64 +test.test_tokenize.CTokenizeTest.test_method @ linux-x86_64 +test.test_tokenize.CTokenizeTest.test_multiplicative @ linux-x86_64 +test.test_tokenize.CTokenizeTest.test_selector @ linux-x86_64 +test.test_tokenize.CTokenizeTest.test_string @ linux-x86_64 +test.test_tokenize.CTokenizeTest.test_tabs @ linux-x86_64 +test.test_tokenize.CTokenizeTest.test_unary @ linux-x86_64 +test.test_tokenize.CTokenizerBufferTests.test_newline_at_the_end_of_buffer @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_additive @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_async @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_basic @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_comparison @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_float @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_function @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_implicit_newline @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_int @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_long @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_method @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_multiplicative @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_non_ascii_identifiers @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_selector @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_shift @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_string @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_tabs @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_unary @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_underscore_literals @ linux-x86_64 +test.test_tokenize.GenerateTokensTest.test_unicode @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_bom_no_cookie @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_cookie_first_line_no_bom @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_cookie_second_line_commented_first_line @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_cookie_second_line_empty_first_line @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_cookie_second_line_no_bom @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_cookie_second_line_noncommented_first_line @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_false_encoding @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_filename_in_exception @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_latin1_normalization @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_matched_bom_and_cookie_first_line @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_matched_bom_and_cookie_second_line @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_mismatched_bom_and_cookie_first_line_raises_syntaxerror @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_mismatched_bom_and_cookie_second_line_raises_syntaxerror @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_no_bom_no_encoding_cookie @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_open @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_open_error @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_short_files @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_syntaxerror_latin1 @ linux-x86_64 +test.test_tokenize.TestDetectEncoding.test_utf8_normalization @ linux-x86_64 +test.test_tokenize.TestMisc.test_decistmt @ linux-x86_64 +test.test_tokenize.TestRoundtrip.test_backslash_continuation @ linux-x86_64 +test.test_tokenize.TestRoundtrip.test_continuation @ linux-x86_64 +test.test_tokenize.TestRoundtrip.test_indentation_semantics_retained @ linux-x86_64 +test.test_tokenize.TestRoundtrip.test_random_files @ linux-x86_64 +test.test_tokenize.TestRoundtrip.test_roundtrip @ linux-x86_64 +test.test_tokenize.TestRoundtrip.test_string_concatenation @ linux-x86_64 +test.test_tokenize.TestTokenize.test_comment_at_the_end_of_the_source_without_newline @ linux-x86_64 +test.test_tokenize.TestTokenize.test_exact_type @ linux-x86_64 +test.test_tokenize.TestTokenize.test_oneline_defs @ linux-x86_64 +test.test_tokenize.TestTokenize.test_pathological_trailing_whitespace @ linux-x86_64 +test.test_tokenize.TestTokenize.test_tokenize @ linux-x86_64 +test.test_tokenize.TestTokenizerAdheresToPep0263.test_bad_coding_cookie @ linux-x86_64 +test.test_tokenize.TestTokenizerAdheresToPep0263.test_latin1_coding_cookie_and_utf8_bom @ linux-x86_64 +test.test_tokenize.TestTokenizerAdheresToPep0263.test_no_coding_cookie_and_utf8_bom @ linux-x86_64 +test.test_tokenize.TestTokenizerAdheresToPep0263.test_utf8_coding_cookie_and_no_utf8_bom @ linux-x86_64 +test.test_tokenize.TestTokenizerAdheresToPep0263.test_utf8_coding_cookie_and_utf8_bom @ linux-x86_64 +test.test_tokenize.Test_Tokenize.test__tokenize_decodes_with_specified_encoding @ linux-x86_64 +test.test_tokenize.Test_Tokenize.test__tokenize_does_not_decode_with_encoding_none @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_additive @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_async @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_basic @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_comparison @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_float @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_function @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_implicit_newline @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_int @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_long @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_method @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_multiplicative @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_non_ascii_identifiers @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_selector @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_shift @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_string @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_tabs @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_unary @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_underscore_literals @ linux-x86_64 +test.test_tokenize.TokenizeTest.test_unicode @ linux-x86_64 +test.test_tokenize.UntokenizeTest.test_backslash_continuation @ linux-x86_64 +test.test_tokenize.UntokenizeTest.test_bad_input_order @ linux-x86_64 +test.test_tokenize.UntokenizeTest.test_iter_compat @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tomllib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tomllib.txt new file mode 100644 index 0000000000..5c1232c654 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tomllib.txt @@ -0,0 +1,13 @@ +test.test_tomllib.test_data.TestData.test_invalid @ linux-x86_64 +test.test_tomllib.test_data.TestData.test_valid @ linux-x86_64 +test.test_tomllib.test_error.TestError.test_invalid_char_quotes @ linux-x86_64 +test.test_tomllib.test_error.TestError.test_invalid_parse_float @ linux-x86_64 +test.test_tomllib.test_error.TestError.test_line_and_col @ linux-x86_64 +test.test_tomllib.test_error.TestError.test_missing_value @ linux-x86_64 +test.test_tomllib.test_error.TestError.test_module_name @ linux-x86_64 +test.test_tomllib.test_misc.TestMiscellaneous.test_deepcopy @ linux-x86_64 +test.test_tomllib.test_misc.TestMiscellaneous.test_incorrect_load @ linux-x86_64 +test.test_tomllib.test_misc.TestMiscellaneous.test_inline_array_recursion_limit @ linux-x86_64 +test.test_tomllib.test_misc.TestMiscellaneous.test_inline_table_recursion_limit @ linux-x86_64 +test.test_tomllib.test_misc.TestMiscellaneous.test_load @ linux-x86_64 +test.test_tomllib.test_misc.TestMiscellaneous.test_parse_float @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_traceback.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_traceback.txt new file mode 100644 index 0000000000..40ad824561 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_traceback.txt @@ -0,0 +1,92 @@ +test.test_traceback.LimitTests.test_extract_stack @ linux-x86_64 +test.test_traceback.LimitTests.test_extract_tb @ linux-x86_64 +test.test_traceback.LimitTests.test_format_exception @ linux-x86_64 +test.test_traceback.MiscTest.test_all @ linux-x86_64 +test.test_traceback.MiscTracebackCases.test_extract_stack @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_cause @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_cause_and_context @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_cause_recursive @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_context @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_context_suppression @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_exception_bad__str__ @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_exception_group_basic @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_exception_group_cause @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_exception_group_context_with_context @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_exception_group_depth_limit @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_exception_group_nested @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_exception_group_width_limit @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_exception_group_with_multiple_notes @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_exception_group_with_notes @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_exception_modulename @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_exception_modulename_not_unicode @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_exception_qualname @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_exception_with_invalid_notes @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_exception_with_multiple_notes @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_exception_with_note @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_message_none @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_simple @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_syntax_error_no_lineno @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_syntax_error_offset_at_eol @ linux-x86_64 +test.test_traceback.PyExcReportingTests.test_syntax_error_various_offsets @ linux-x86_64 +test.test_traceback.TestFrame.test_explicit_line @ linux-x86_64 +test.test_traceback.TestFrame.test_len @ linux-x86_64 +test.test_traceback.TestFrame.test_no_line @ linux-x86_64 +test.test_traceback.TestStack.test_custom_format_frame @ linux-x86_64 +test.test_traceback.TestStack.test_dropping_frames @ linux-x86_64 +test.test_traceback.TestStack.test_extract_stack @ linux-x86_64 +test.test_traceback.TestStack.test_extract_stack_limit @ linux-x86_64 +test.test_traceback.TestStack.test_format_locals @ linux-x86_64 +test.test_traceback.TestStack.test_format_smoke @ linux-x86_64 +test.test_traceback.TestStack.test_from_list @ linux-x86_64 +test.test_traceback.TestStack.test_from_list_edited_stack @ linux-x86_64 +test.test_traceback.TestStack.test_locals @ linux-x86_64 +test.test_traceback.TestStack.test_no_locals @ linux-x86_64 +test.test_traceback.TestStack.test_walk_stack @ linux-x86_64 +test.test_traceback.TestStack.test_walk_tb @ linux-x86_64 +test.test_traceback.TestTracebackException.test_cause @ linux-x86_64 +test.test_traceback.TestTracebackException.test_compact_no_cause @ linux-x86_64 +test.test_traceback.TestTracebackException.test_compact_with_cause @ linux-x86_64 +test.test_traceback.TestTracebackException.test_comparison_basic @ linux-x86_64 +test.test_traceback.TestTracebackException.test_comparison_equivalent_exceptions_are_equal @ linux-x86_64 +test.test_traceback.TestTracebackException.test_comparison_params_variations @ linux-x86_64 +test.test_traceback.TestTracebackException.test_context @ linux-x86_64 +test.test_traceback.TestTracebackException.test_from_exception @ linux-x86_64 +test.test_traceback.TestTracebackException.test_limit @ linux-x86_64 +test.test_traceback.TestTracebackException.test_locals @ linux-x86_64 +test.test_traceback.TestTracebackException.test_long_context_chain @ linux-x86_64 +test.test_traceback.TestTracebackException.test_no_locals @ linux-x86_64 +test.test_traceback.TestTracebackException.test_no_refs_to_exception_and_traceback_objects @ linux-x86_64 +test.test_traceback.TestTracebackException.test_smoke @ linux-x86_64 +test.test_traceback.TestTracebackException.test_traceback_header @ linux-x86_64 +test.test_traceback.TestTracebackException.test_unhashable @ linux-x86_64 +test.test_traceback.TestTracebackException_ExceptionGroups.test_comparison @ linux-x86_64 +test.test_traceback.TestTracebackException_ExceptionGroups.test_exception_group_construction @ linux-x86_64 +test.test_traceback.TestTracebackException_ExceptionGroups.test_exception_group_format_exception_only @ linux-x86_64 +test.test_traceback.TestTracebackException_ExceptionGroups.test_max_group_depth @ linux-x86_64 +test.test_traceback.TestTracebackException_ExceptionGroups.test_max_group_width @ linux-x86_64 +test.test_traceback.TracebackCases.test_base_exception @ linux-x86_64 +test.test_traceback.TracebackCases.test_caret @ linux-x86_64 +test.test_traceback.TracebackCases.test_encoded_file @ linux-x86_64 +test.test_traceback.TracebackCases.test_exception_is_None @ linux-x86_64 +test.test_traceback.TracebackCases.test_format_exception_exc @ linux-x86_64 +test.test_traceback.TracebackCases.test_format_exception_only_bad__str__ @ linux-x86_64 +test.test_traceback.TracebackCases.test_format_exception_only_exc @ linux-x86_64 +test.test_traceback.TracebackCases.test_no_caret_with_no_debug_ranges_flag @ linux-x86_64 +test.test_traceback.TracebackCases.test_nocaret @ linux-x86_64 +test.test_traceback.TracebackCases.test_print_exception @ linux-x86_64 +test.test_traceback.TracebackCases.test_print_exception_exc @ linux-x86_64 +test.test_traceback.TracebackCases.test_recursion_error_during_traceback @ linux-x86_64 +test.test_traceback.TracebackCases.test_signatures @ linux-x86_64 +test.test_traceback.TracebackErrorLocationCaretTests.test_basic_caret @ linux-x86_64 +test.test_traceback.TracebackErrorLocationCaretTests.test_byte_offset_multiline @ linux-x86_64 +test.test_traceback.TracebackErrorLocationCaretTests.test_caret_exception_group @ linux-x86_64 +test.test_traceback.TracebackErrorLocationCaretTests.test_caret_in_type_annotation @ linux-x86_64 +test.test_traceback.TracebackErrorLocationCaretTests.test_caret_multiline_expression @ linux-x86_64 +test.test_traceback.TracebackErrorLocationCaretTests.test_caret_multiline_expression_bin_op @ linux-x86_64 +test.test_traceback.TracebackErrorLocationCaretTests.test_traceback_specialization_with_syntax_error @ linux-x86_64 +test.test_traceback.TracebackErrorLocationCaretTests.test_traceback_very_long_line @ linux-x86_64 +test.test_traceback.TracebackFormatTests.test_exception_group_deep_recursion_traceback @ linux-x86_64 +test.test_traceback.TracebackFormatTests.test_format_stack @ linux-x86_64 +test.test_traceback.TracebackFormatTests.test_print_exception_bad_type_python @ linux-x86_64 +test.test_traceback.TracebackFormatTests.test_print_stack @ linux-x86_64 +test.test_traceback.TracebackFormatTests.test_stack_format @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tracemalloc.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tracemalloc.txt new file mode 100644 index 0000000000..d8a82207d5 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tracemalloc.txt @@ -0,0 +1,19 @@ +test.test_tracemalloc.TestCommandLine.test_pymem_alloc0 @ linux-x86_64 +test.test_tracemalloc.TestFilters.test_filter_attributes @ linux-x86_64 +test.test_tracemalloc.TestFilters.test_filter_match @ linux-x86_64 +test.test_tracemalloc.TestFilters.test_filter_match_filename @ linux-x86_64 +test.test_tracemalloc.TestFilters.test_filter_match_filename_joker @ linux-x86_64 +test.test_tracemalloc.TestFilters.test_filter_match_trace @ linux-x86_64 +test.test_tracemalloc.TestSnapshot.test_filter_traces @ linux-x86_64 +test.test_tracemalloc.TestSnapshot.test_filter_traces_domain @ linux-x86_64 +test.test_tracemalloc.TestSnapshot.test_filter_traces_domain_filter @ linux-x86_64 +test.test_tracemalloc.TestSnapshot.test_format_traceback @ linux-x86_64 +test.test_tracemalloc.TestSnapshot.test_slices @ linux-x86_64 +test.test_tracemalloc.TestSnapshot.test_snapshot_group_by_cumulative @ linux-x86_64 +test.test_tracemalloc.TestSnapshot.test_snapshot_group_by_file @ linux-x86_64 +test.test_tracemalloc.TestSnapshot.test_snapshot_group_by_line @ linux-x86_64 +test.test_tracemalloc.TestSnapshot.test_snapshot_group_by_traceback @ linux-x86_64 +test.test_tracemalloc.TestSnapshot.test_statistic_diff_format @ linux-x86_64 +test.test_tracemalloc.TestSnapshot.test_statistic_format @ linux-x86_64 +test.test_tracemalloc.TestSnapshot.test_trace_format @ linux-x86_64 +test.test_tracemalloc.TestTraceback.test_repr @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tty.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tty.txt new file mode 100644 index 0000000000..b0bda1f877 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tty.txt @@ -0,0 +1,2 @@ +test.test_tty.TestTty.test_setcbreak @ linux-x86_64 +test.test_tty.TestTty.test_setraw @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tuple.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tuple.txt new file mode 100644 index 0000000000..01e26e0d6f --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_tuple.txt @@ -0,0 +1,28 @@ +test.test_tuple.TupleTest.test_addmul @ linux-x86_64 +test.test_tuple.TupleTest.test_constructors @ linux-x86_64 +test.test_tuple.TupleTest.test_contains @ linux-x86_64 +test.test_tuple.TupleTest.test_contains_fake @ linux-x86_64 +test.test_tuple.TupleTest.test_contains_order @ linux-x86_64 +test.test_tuple.TupleTest.test_count @ linux-x86_64 +test.test_tuple.TupleTest.test_getitem @ linux-x86_64 +test.test_tuple.TupleTest.test_getitem_error @ linux-x86_64 +test.test_tuple.TupleTest.test_getitemoverwriteiter @ linux-x86_64 +test.test_tuple.TupleTest.test_getslice @ linux-x86_64 +test.test_tuple.TupleTest.test_hash_optional @ linux-x86_64 +test.test_tuple.TupleTest.test_iadd @ linux-x86_64 +test.test_tuple.TupleTest.test_imul @ linux-x86_64 +test.test_tuple.TupleTest.test_index @ linux-x86_64 +test.test_tuple.TupleTest.test_iterator_pickle @ linux-x86_64 +test.test_tuple.TupleTest.test_keyword_args @ linux-x86_64 +test.test_tuple.TupleTest.test_len @ linux-x86_64 +test.test_tuple.TupleTest.test_lexicographic_ordering @ linux-x86_64 +test.test_tuple.TupleTest.test_minmax @ linux-x86_64 +test.test_tuple.TupleTest.test_no_comdat_folding @ linux-x86_64 +test.test_tuple.TupleTest.test_pickle @ linux-x86_64 +test.test_tuple.TupleTest.test_repeat @ linux-x86_64 +test.test_tuple.TupleTest.test_repr @ linux-x86_64 +test.test_tuple.TupleTest.test_repr_large @ linux-x86_64 +test.test_tuple.TupleTest.test_reversed_pickle @ linux-x86_64 +test.test_tuple.TupleTest.test_subscript @ linux-x86_64 +test.test_tuple.TupleTest.test_truth @ linux-x86_64 +test.test_tuple.TupleTest.test_tupleresizebug @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_type_annotations.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_type_annotations.txt new file mode 100644 index 0000000000..1f01fe5fb3 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_type_annotations.txt @@ -0,0 +1,8 @@ +test.test_type_annotations.TestSetupAnnotations.test_blocks @ linux-x86_64 +test.test_type_annotations.TestSetupAnnotations.test_top_level @ linux-x86_64 +test.test_type_annotations.TestSetupAnnotations.test_try @ linux-x86_64 +test.test_type_annotations.TypeAnnotationTests.test_annotations_are_created_correctly @ linux-x86_64 +test.test_type_annotations.TypeAnnotationTests.test_annotations_getset_raises @ linux-x86_64 +test.test_type_annotations.TypeAnnotationTests.test_descriptor_still_works @ linux-x86_64 +test.test_type_annotations.TypeAnnotationTests.test_lazy_create_annotations @ linux-x86_64 +test.test_type_annotations.TypeAnnotationTests.test_setting_annotations @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_type_comments.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_type_comments.txt new file mode 100644 index 0000000000..2ee79ee6b2 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_type_comments.txt @@ -0,0 +1,16 @@ +test.test_type_comments.TypeCommentTests.test_asynccomp @ linux-x86_64 +test.test_type_comments.TypeCommentTests.test_asyncdef @ linux-x86_64 +test.test_type_comments.TypeCommentTests.test_asyncvar @ linux-x86_64 +test.test_type_comments.TypeCommentTests.test_forstmt @ linux-x86_64 +test.test_type_comments.TypeCommentTests.test_fstring @ linux-x86_64 +test.test_type_comments.TypeCommentTests.test_func_type_input @ linux-x86_64 +test.test_type_comments.TypeCommentTests.test_funcdef @ linux-x86_64 +test.test_type_comments.TypeCommentTests.test_ignores @ linux-x86_64 +test.test_type_comments.TypeCommentTests.test_inappropriate_type_comments @ linux-x86_64 +test.test_type_comments.TypeCommentTests.test_longargs @ linux-x86_64 +test.test_type_comments.TypeCommentTests.test_matmul @ linux-x86_64 +test.test_type_comments.TypeCommentTests.test_nonasciidef @ linux-x86_64 +test.test_type_comments.TypeCommentTests.test_redundantdef @ linux-x86_64 +test.test_type_comments.TypeCommentTests.test_underscorednumber @ linux-x86_64 +test.test_type_comments.TypeCommentTests.test_vardecl @ linux-x86_64 +test.test_type_comments.TypeCommentTests.test_withstmt @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_typechecks.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_typechecks.txt new file mode 100644 index 0000000000..1fec90ebed --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_typechecks.txt @@ -0,0 +1,6 @@ +test.test_typechecks.TypeChecksTest.testIsInstanceActual @ linux-x86_64 +test.test_typechecks.TypeChecksTest.testIsInstanceBuiltin @ linux-x86_64 +test.test_typechecks.TypeChecksTest.testIsSubclassActual @ linux-x86_64 +test.test_typechecks.TypeChecksTest.testIsSubclassBuiltin @ linux-x86_64 +test.test_typechecks.TypeChecksTest.testIsSubclassInternal @ linux-x86_64 +test.test_typechecks.TypeChecksTest.testSubclassBehavior @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_types.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_types.txt new file mode 100644 index 0000000000..5b14241ccc --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_types.txt @@ -0,0 +1,99 @@ +test.test_types.ClassCreationTests.test_bad___prepare__ @ linux-x86_64 +test.test_types.ClassCreationTests.test_metaclass_derivation @ linux-x86_64 +test.test_types.ClassCreationTests.test_metaclass_new_error @ linux-x86_64 +test.test_types.ClassCreationTests.test_metaclass_override_callable @ linux-x86_64 +test.test_types.ClassCreationTests.test_metaclass_override_function @ linux-x86_64 +test.test_types.ClassCreationTests.test_new_class_basics @ linux-x86_64 +test.test_types.ClassCreationTests.test_new_class_defaults @ linux-x86_64 +test.test_types.ClassCreationTests.test_new_class_exec_body @ linux-x86_64 +test.test_types.ClassCreationTests.test_new_class_meta @ linux-x86_64 +test.test_types.ClassCreationTests.test_new_class_meta_with_base @ linux-x86_64 +test.test_types.ClassCreationTests.test_new_class_metaclass_keywords @ linux-x86_64 +test.test_types.ClassCreationTests.test_new_class_subclass @ linux-x86_64 +test.test_types.ClassCreationTests.test_new_class_with_mro_entry @ linux-x86_64 +test.test_types.ClassCreationTests.test_new_class_with_mro_entry_error @ linux-x86_64 +test.test_types.ClassCreationTests.test_new_class_with_mro_entry_genericalias @ linux-x86_64 +test.test_types.ClassCreationTests.test_new_class_with_mro_entry_multiple @ linux-x86_64 +test.test_types.ClassCreationTests.test_new_class_with_mro_entry_multiple_2 @ linux-x86_64 +test.test_types.ClassCreationTests.test_new_class_with_mro_entry_none @ linux-x86_64 +test.test_types.ClassCreationTests.test_prepare_class @ linux-x86_64 +test.test_types.ClassCreationTests.test_resolve_bases @ linux-x86_64 +test.test_types.ClassCreationTests.test_resolve_bases_with_mro_entry @ linux-x86_64 +test.test_types.CoroutineTests.test_duck_coro @ linux-x86_64 +test.test_types.CoroutineTests.test_duck_corogen @ linux-x86_64 +test.test_types.CoroutineTests.test_non_gen_values @ linux-x86_64 +test.test_types.CoroutineTests.test_wrapper_object @ linux-x86_64 +test.test_types.CoroutineTests.test_wrong_args @ linux-x86_64 +test.test_types.MappingProxyTests.test_chainmap @ linux-x86_64 +test.test_types.MappingProxyTests.test_constructor @ linux-x86_64 +test.test_types.MappingProxyTests.test_contains @ linux-x86_64 +test.test_types.MappingProxyTests.test_copy @ linux-x86_64 +test.test_types.MappingProxyTests.test_customdict @ linux-x86_64 +test.test_types.MappingProxyTests.test_get @ linux-x86_64 +test.test_types.MappingProxyTests.test_iterators @ linux-x86_64 +test.test_types.MappingProxyTests.test_len @ linux-x86_64 +test.test_types.MappingProxyTests.test_methods @ linux-x86_64 +test.test_types.MappingProxyTests.test_missing @ linux-x86_64 +test.test_types.MappingProxyTests.test_reversed @ linux-x86_64 +test.test_types.MappingProxyTests.test_union @ linux-x86_64 +test.test_types.MappingProxyTests.test_views @ linux-x86_64 +test.test_types.SimpleNamespaceTests.test_as_dict @ linux-x86_64 +test.test_types.SimpleNamespaceTests.test_attrdel @ linux-x86_64 +test.test_types.SimpleNamespaceTests.test_attrget @ linux-x86_64 +test.test_types.SimpleNamespaceTests.test_attrset @ linux-x86_64 +test.test_types.SimpleNamespaceTests.test_constructor @ linux-x86_64 +test.test_types.SimpleNamespaceTests.test_equal @ linux-x86_64 +test.test_types.SimpleNamespaceTests.test_fake_namespace_compare @ linux-x86_64 +test.test_types.SimpleNamespaceTests.test_nested @ linux-x86_64 +test.test_types.SimpleNamespaceTests.test_pickle @ linux-x86_64 +test.test_types.SimpleNamespaceTests.test_recursive @ linux-x86_64 +test.test_types.SimpleNamespaceTests.test_subclass @ linux-x86_64 +test.test_types.SimpleNamespaceTests.test_unbound @ linux-x86_64 +test.test_types.SimpleNamespaceTests.test_underlying_dict @ linux-x86_64 +test.test_types.TypesTests.test_boolean_ops @ linux-x86_64 +test.test_types.TypesTests.test_comparisons @ linux-x86_64 +test.test_types.TypesTests.test_ellipsis_type @ linux-x86_64 +test.test_types.TypesTests.test_float__format__ @ linux-x86_64 +test.test_types.TypesTests.test_float__format__locale @ linux-x86_64 +test.test_types.TypesTests.test_float_constructor @ linux-x86_64 +test.test_types.TypesTests.test_float_to_string @ linux-x86_64 +test.test_types.TypesTests.test_floats @ linux-x86_64 +test.test_types.TypesTests.test_format_spec_errors @ linux-x86_64 +test.test_types.TypesTests.test_int__format__ @ linux-x86_64 +test.test_types.TypesTests.test_int__format__locale @ linux-x86_64 +test.test_types.TypesTests.test_method_wrapper_types @ linux-x86_64 +test.test_types.TypesTests.test_none_type @ linux-x86_64 +test.test_types.TypesTests.test_normal_integers @ linux-x86_64 +test.test_types.TypesTests.test_notimplemented_type @ linux-x86_64 +test.test_types.TypesTests.test_numeric_types @ linux-x86_64 +test.test_types.TypesTests.test_slot_wrapper_types @ linux-x86_64 +test.test_types.TypesTests.test_strings @ linux-x86_64 +test.test_types.TypesTests.test_traceback_and_frame_types @ linux-x86_64 +test.test_types.TypesTests.test_truth_values @ linux-x86_64 +test.test_types.TypesTests.test_type_function @ linux-x86_64 +test.test_types.TypesTests.test_zero_division @ linux-x86_64 +test.test_types.UnionTests.test_bad_instancecheck @ linux-x86_64 +test.test_types.UnionTests.test_bad_subclasscheck @ linux-x86_64 +test.test_types.UnionTests.test_hash @ linux-x86_64 +test.test_types.UnionTests.test_instancecheck_and_subclasscheck @ linux-x86_64 +test.test_types.UnionTests.test_instancecheck_and_subclasscheck_order @ linux-x86_64 +test.test_types.UnionTests.test_or_type_operator_with_Alias @ linux-x86_64 +test.test_types.UnionTests.test_or_type_operator_with_IO @ linux-x86_64 +test.test_types.UnionTests.test_or_type_operator_with_Literal @ linux-x86_64 +test.test_types.UnionTests.test_or_type_operator_with_NamedTuple @ linux-x86_64 +test.test_types.UnionTests.test_or_type_operator_with_NewType @ linux-x86_64 +test.test_types.UnionTests.test_or_type_operator_with_Protocol @ linux-x86_64 +test.test_types.UnionTests.test_or_type_operator_with_SpecialForm @ linux-x86_64 +test.test_types.UnionTests.test_or_type_operator_with_TypeVar @ linux-x86_64 +test.test_types.UnionTests.test_or_type_operator_with_TypedDict @ linux-x86_64 +test.test_types.UnionTests.test_or_type_operator_with_bad_module @ linux-x86_64 +test.test_types.UnionTests.test_or_type_operator_with_forward @ linux-x86_64 +test.test_types.UnionTests.test_or_type_operator_with_genericalias @ linux-x86_64 +test.test_types.UnionTests.test_or_type_repr @ linux-x86_64 +test.test_types.UnionTests.test_or_types_operator @ linux-x86_64 +test.test_types.UnionTests.test_union_args @ linux-x86_64 +test.test_types.UnionTests.test_union_copy @ linux-x86_64 +test.test_types.UnionTests.test_union_parameter_chaining @ linux-x86_64 +test.test_types.UnionTests.test_union_parameter_substitution @ linux-x86_64 +test.test_types.UnionTests.test_union_parameter_substitution_errors @ linux-x86_64 +test.test_types.UnionTests.test_union_pickle @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ucn.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ucn.txt new file mode 100644 index 0000000000..8c47d62fd2 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_ucn.txt @@ -0,0 +1,12 @@ +test.test_ucn.UnicodeNamesTest.test_aliases @ linux-x86_64 +test.test_ucn.UnicodeNamesTest.test_aliases_names_in_pua_range @ linux-x86_64 +test.test_ucn.UnicodeNamesTest.test_ascii_letters @ linux-x86_64 +test.test_ucn.UnicodeNamesTest.test_cjk_unified_ideographs @ linux-x86_64 +test.test_ucn.UnicodeNamesTest.test_errors @ linux-x86_64 +test.test_ucn.UnicodeNamesTest.test_general @ linux-x86_64 +test.test_ucn.UnicodeNamesTest.test_hangul_syllables @ linux-x86_64 +test.test_ucn.UnicodeNamesTest.test_misc_symbols @ linux-x86_64 +test.test_ucn.UnicodeNamesTest.test_named_sequences_full @ linux-x86_64 +test.test_ucn.UnicodeNamesTest.test_named_sequences_names_in_pua_range @ linux-x86_64 +test.test_ucn.UnicodeNamesTest.test_named_sequences_sample @ linux-x86_64 +test.test_ucn.UnicodeNamesTest.test_strict_error_handling @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unary.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unary.txt new file mode 100644 index 0000000000..2be7122090 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unary.txt @@ -0,0 +1,6 @@ +test.test_unary.UnaryOpTestCase.test_bad_types @ linux-x86_64 +test.test_unary.UnaryOpTestCase.test_invert @ linux-x86_64 +test.test_unary.UnaryOpTestCase.test_negation_of_exponentiation @ linux-x86_64 +test.test_unary.UnaryOpTestCase.test_negative @ linux-x86_64 +test.test_unary.UnaryOpTestCase.test_no_overflow @ linux-x86_64 +test.test_unary.UnaryOpTestCase.test_positive @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unicode.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unicode.txt new file mode 100644 index 0000000000..d1f2972e75 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unicode.txt @@ -0,0 +1,112 @@ +test.test_unicode.StringModuleTest.test_formatter_field_name_split @ linux-x86_64 +test.test_unicode.StringModuleTest.test_formatter_parser @ linux-x86_64 +test.test_unicode.StringModuleTest.test_str_subclass_attr @ linux-x86_64 +test.test_unicode.UnicodeTest.test___contains__ @ linux-x86_64 +test.test_unicode.UnicodeTest.test_additional_rsplit @ linux-x86_64 +test.test_unicode.UnicodeTest.test_additional_split @ linux-x86_64 +test.test_unicode.UnicodeTest.test_ascii @ linux-x86_64 +test.test_unicode.UnicodeTest.test_bug1001011 @ linux-x86_64 +test.test_unicode.UnicodeTest.test_bytes_comparison @ linux-x86_64 +test.test_unicode.UnicodeTest.test_capitalize @ linux-x86_64 +test.test_unicode.UnicodeTest.test_casefold @ linux-x86_64 +test.test_unicode.UnicodeTest.test_center @ linux-x86_64 +test.test_unicode.UnicodeTest.test_codecs @ linux-x86_64 +test.test_unicode.UnicodeTest.test_codecs_errors @ linux-x86_64 +test.test_unicode.UnicodeTest.test_codecs_idna @ linux-x86_64 +test.test_unicode.UnicodeTest.test_codecs_utf7 @ linux-x86_64 +test.test_unicode.UnicodeTest.test_codecs_utf8 @ linux-x86_64 +test.test_unicode.UnicodeTest.test_compare @ linux-x86_64 +test.test_unicode.UnicodeTest.test_comparison @ linux-x86_64 +test.test_unicode.UnicodeTest.test_concatenation @ linux-x86_64 +test.test_unicode.UnicodeTest.test_constructor @ linux-x86_64 +test.test_unicode.UnicodeTest.test_constructor_defaults @ linux-x86_64 +test.test_unicode.UnicodeTest.test_constructor_keyword_args @ linux-x86_64 +test.test_unicode.UnicodeTest.test_contains @ linux-x86_64 +test.test_unicode.UnicodeTest.test_conversion @ linux-x86_64 +test.test_unicode.UnicodeTest.test_count @ linux-x86_64 +test.test_unicode.UnicodeTest.test_endswith @ linux-x86_64 +test.test_unicode.UnicodeTest.test_exhausted_iterator @ linux-x86_64 +test.test_unicode.UnicodeTest.test_expandtabs @ linux-x86_64 +test.test_unicode.UnicodeTest.test_extended_getslice @ linux-x86_64 +test.test_unicode.UnicodeTest.test_find @ linux-x86_64 +test.test_unicode.UnicodeTest.test_find_etc_raise_correct_error_messages @ linux-x86_64 +test.test_unicode.UnicodeTest.test_find_periodic_pattern @ linux-x86_64 +test.test_unicode.UnicodeTest.test_find_shift_table_overflow @ linux-x86_64 +test.test_unicode.UnicodeTest.test_fixtype @ linux-x86_64 +test.test_unicode.UnicodeTest.test_floatformatting @ linux-x86_64 +test.test_unicode.UnicodeTest.test_format @ linux-x86_64 +test.test_unicode.UnicodeTest.test_format_auto_numbering @ linux-x86_64 +test.test_unicode.UnicodeTest.test_format_float @ linux-x86_64 +test.test_unicode.UnicodeTest.test_format_huge_item_number @ linux-x86_64 +test.test_unicode.UnicodeTest.test_format_huge_precision @ linux-x86_64 +test.test_unicode.UnicodeTest.test_format_huge_width @ linux-x86_64 +test.test_unicode.UnicodeTest.test_format_map @ linux-x86_64 +test.test_unicode.UnicodeTest.test_format_subclass @ linux-x86_64 +test.test_unicode.UnicodeTest.test_formatting @ linux-x86_64 +test.test_unicode.UnicodeTest.test_formatting_huge_precision @ linux-x86_64 +test.test_unicode.UnicodeTest.test_formatting_huge_width @ linux-x86_64 +test.test_unicode.UnicodeTest.test_formatting_with_enum @ linux-x86_64 +test.test_unicode.UnicodeTest.test_getnewargs @ linux-x86_64 +test.test_unicode.UnicodeTest.test_hash @ linux-x86_64 +test.test_unicode.UnicodeTest.test_index @ linux-x86_64 +test.test_unicode.UnicodeTest.test_inplace_rewrites @ linux-x86_64 +test.test_unicode.UnicodeTest.test_invalid_cb_for_2bytes_seq @ linux-x86_64 +test.test_unicode.UnicodeTest.test_invalid_cb_for_4bytes_seq @ linux-x86_64 +test.test_unicode.UnicodeTest.test_invalid_start_byte @ linux-x86_64 +test.test_unicode.UnicodeTest.test_isalnum @ linux-x86_64 +test.test_unicode.UnicodeTest.test_isalpha @ linux-x86_64 +test.test_unicode.UnicodeTest.test_isascii @ linux-x86_64 +test.test_unicode.UnicodeTest.test_isdecimal @ linux-x86_64 +test.test_unicode.UnicodeTest.test_isdigit @ linux-x86_64 +test.test_unicode.UnicodeTest.test_isidentifier @ linux-x86_64 +test.test_unicode.UnicodeTest.test_islower @ linux-x86_64 +test.test_unicode.UnicodeTest.test_isnumeric @ linux-x86_64 +test.test_unicode.UnicodeTest.test_isprintable @ linux-x86_64 +test.test_unicode.UnicodeTest.test_isspace @ linux-x86_64 +test.test_unicode.UnicodeTest.test_isspace_invariant @ linux-x86_64 +test.test_unicode.UnicodeTest.test_issue18183 @ linux-x86_64 +test.test_unicode.UnicodeTest.test_issue28598_strsubclass_rhs @ linux-x86_64 +test.test_unicode.UnicodeTest.test_issue8271 @ linux-x86_64 +test.test_unicode.UnicodeTest.test_istitle @ linux-x86_64 +test.test_unicode.UnicodeTest.test_isupper @ linux-x86_64 +test.test_unicode.UnicodeTest.test_iteration @ linux-x86_64 +test.test_unicode.UnicodeTest.test_iterators @ linux-x86_64 +test.test_unicode.UnicodeTest.test_iterators_invocation @ linux-x86_64 +test.test_unicode.UnicodeTest.test_join @ linux-x86_64 +test.test_unicode.UnicodeTest.test_literals @ linux-x86_64 +test.test_unicode.UnicodeTest.test_ljust @ linux-x86_64 +test.test_unicode.UnicodeTest.test_lower @ linux-x86_64 +test.test_unicode.UnicodeTest.test_maketrans_translate @ linux-x86_64 +test.test_unicode.UnicodeTest.test_mul @ linux-x86_64 +test.test_unicode.UnicodeTest.test_none_arguments @ linux-x86_64 +test.test_unicode.UnicodeTest.test_partition @ linux-x86_64 +test.test_unicode.UnicodeTest.test_pickle_iterator @ linux-x86_64 +test.test_unicode.UnicodeTest.test_removeprefix @ linux-x86_64 +test.test_unicode.UnicodeTest.test_removesuffix @ linux-x86_64 +test.test_unicode.UnicodeTest.test_repeat_id_preserving @ linux-x86_64 +test.test_unicode.UnicodeTest.test_replace @ linux-x86_64 +test.test_unicode.UnicodeTest.test_repr @ linux-x86_64 +test.test_unicode.UnicodeTest.test_rfind @ linux-x86_64 +test.test_unicode.UnicodeTest.test_rindex @ linux-x86_64 +test.test_unicode.UnicodeTest.test_rjust @ linux-x86_64 +test.test_unicode.UnicodeTest.test_rpartition @ linux-x86_64 +test.test_unicode.UnicodeTest.test_rsplit @ linux-x86_64 +test.test_unicode.UnicodeTest.test_slice @ linux-x86_64 +test.test_unicode.UnicodeTest.test_split @ linux-x86_64 +test.test_unicode.UnicodeTest.test_splitlines @ linux-x86_64 +test.test_unicode.UnicodeTest.test_startswith @ linux-x86_64 +test.test_unicode.UnicodeTest.test_startswith_endswith_errors @ linux-x86_64 +test.test_unicode.UnicodeTest.test_strip @ linux-x86_64 +test.test_unicode.UnicodeTest.test_strip_whitespace @ linux-x86_64 +test.test_unicode.UnicodeTest.test_subclass_add @ linux-x86_64 +test.test_unicode.UnicodeTest.test_subscript @ linux-x86_64 +test.test_unicode.UnicodeTest.test_surrogates @ linux-x86_64 +test.test_unicode.UnicodeTest.test_swapcase @ linux-x86_64 +test.test_unicode.UnicodeTest.test_title @ linux-x86_64 +test.test_unicode.UnicodeTest.test_ucs4 @ linux-x86_64 +test.test_unicode.UnicodeTest.test_unexpected_end_of_data @ linux-x86_64 +test.test_unicode.UnicodeTest.test_unicode_repr @ linux-x86_64 +test.test_unicode.UnicodeTest.test_upper @ linux-x86_64 +test.test_unicode.UnicodeTest.test_utf8_decode_invalid_sequences @ linux-x86_64 +test.test_unicode.UnicodeTest.test_utf8_decode_valid_sequences @ linux-x86_64 +test.test_unicode.UnicodeTest.test_zfill @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unicode_file_functions.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unicode_file_functions.txt new file mode 100644 index 0000000000..9054e05080 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unicode_file_functions.txt @@ -0,0 +1,30 @@ +test.test_unicode_file_functions.UnicodeFileTests.test_directory @ linux-x86_64 +test.test_unicode_file_functions.UnicodeFileTests.test_failures @ linux-x86_64 +test.test_unicode_file_functions.UnicodeFileTests.test_listdir @ linux-x86_64 +test.test_unicode_file_functions.UnicodeFileTests.test_normalize @ linux-x86_64 +test.test_unicode_file_functions.UnicodeFileTests.test_open @ linux-x86_64 +test.test_unicode_file_functions.UnicodeFileTests.test_rename @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFCFileTests.test_directory @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFCFileTests.test_failures @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFCFileTests.test_listdir @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFCFileTests.test_normalize @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFCFileTests.test_open @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFCFileTests.test_rename @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFDFileTests.test_directory @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFDFileTests.test_failures @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFDFileTests.test_listdir @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFDFileTests.test_normalize @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFDFileTests.test_open @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFDFileTests.test_rename @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFKCFileTests.test_directory @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFKCFileTests.test_failures @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFKCFileTests.test_listdir @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFKCFileTests.test_normalize @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFKCFileTests.test_open @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFKCFileTests.test_rename @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFKDFileTests.test_directory @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFKDFileTests.test_failures @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFKDFileTests.test_listdir @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFKDFileTests.test_normalize @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFKDFileTests.test_open @ linux-x86_64 +test.test_unicode_file_functions.UnicodeNFKDFileTests.test_rename @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unicodedata.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unicodedata.txt new file mode 100644 index 0000000000..80b5d020d5 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unicodedata.txt @@ -0,0 +1,21 @@ +test.test_unicodedata.NormalizationTest.test_bug_834676 @ linux-x86_64 +test.test_unicodedata.NormalizationTest.test_edge_cases @ linux-x86_64 +test.test_unicodedata.NormalizationTest.test_normalization @ linux-x86_64 +test.test_unicodedata.UnicodeFunctionsTest.test_category @ linux-x86_64 +test.test_unicodedata.UnicodeFunctionsTest.test_combining @ linux-x86_64 +test.test_unicodedata.UnicodeFunctionsTest.test_decimal @ linux-x86_64 +test.test_unicodedata.UnicodeFunctionsTest.test_decomposition @ linux-x86_64 +test.test_unicodedata.UnicodeFunctionsTest.test_digit @ linux-x86_64 +test.test_unicodedata.UnicodeFunctionsTest.test_east_asian_width @ linux-x86_64 +test.test_unicodedata.UnicodeFunctionsTest.test_east_asian_width_9_0_changes @ linux-x86_64 +test.test_unicodedata.UnicodeFunctionsTest.test_issue10254 @ linux-x86_64 +test.test_unicodedata.UnicodeFunctionsTest.test_issue29456 @ linux-x86_64 +test.test_unicodedata.UnicodeFunctionsTest.test_mirrored @ linux-x86_64 +test.test_unicodedata.UnicodeFunctionsTest.test_numeric @ linux-x86_64 +test.test_unicodedata.UnicodeFunctionsTest.test_pr29 @ linux-x86_64 +test.test_unicodedata.UnicodeMiscTest.test_bug_1704793 @ linux-x86_64 +test.test_unicodedata.UnicodeMiscTest.test_bug_4971 @ linux-x86_64 +test.test_unicodedata.UnicodeMiscTest.test_bug_5828 @ linux-x86_64 +test.test_unicodedata.UnicodeMiscTest.test_decimal_numeric_consistent @ linux-x86_64 +test.test_unicodedata.UnicodeMiscTest.test_digit_numeric_consistent @ linux-x86_64 +test.test_unicodedata.UnicodeMiscTest.test_ucd_510 @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unittest.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unittest.txt new file mode 100644 index 0000000000..4f945bbf80 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unittest.txt @@ -0,0 +1,457 @@ +unittest.test.test_assertions.TestLongMessage.testAlmostEqual @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertDictContainsSubset @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertDictEqual @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertFalse @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertGreater @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertGreaterEqual @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertIn @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertIs @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertIsNone @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertIsNot @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertIsNotNone @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertLess @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertLessEqual @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertMultiLineEqual @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertNotIn @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertNotRegex @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertRaises @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertRaisesRegex @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertRegex @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertSequenceEqual @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertSetEqual @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertTrue @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertWarns @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testAssertWarnsRegex @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testDefault @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testNotAlmostEqual @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.testNotEqual @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.test_baseAssertEqual @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.test_formatMessage_unicode_error @ linux-x86_64 +unittest.test.test_assertions.TestLongMessage.test_formatMsg @ linux-x86_64 +unittest.test.test_assertions.Test_Assertions.testAssertNotRegex @ linux-x86_64 +unittest.test.test_assertions.Test_Assertions.test_AlmostEqual @ linux-x86_64 +unittest.test.test_assertions.Test_Assertions.test_AmostEqualWithDelta @ linux-x86_64 +unittest.test.test_assertions.Test_Assertions.test_assertRaises @ linux-x86_64 +!unittest.test.test_assertions.Test_Assertions.test_assertRaises_frames_survival @ linux-x86_64 +unittest.test.test_async_case.TestAsyncCase.test_base_exception_from_async_method @ linux-x86_64 +unittest.test.test_async_case.TestAsyncCase.test_cleanups_interleave_order @ linux-x86_64 +unittest.test.test_async_case.TestAsyncCase.test_exception_in_setup @ linux-x86_64 +unittest.test.test_async_case.TestAsyncCase.test_exception_in_tear_clean_up @ linux-x86_64 +unittest.test.test_async_case.TestAsyncCase.test_exception_in_tear_down @ linux-x86_64 +unittest.test.test_async_case.TestAsyncCase.test_exception_in_test @ linux-x86_64 +unittest.test.test_async_case.TestAsyncCase.test_full_cycle @ linux-x86_64 +unittest.test.test_async_case.TestAsyncCase.test_setup_get_event_loop @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAddTypeEqualityFunc @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertCountEqual @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertDictContainsSubset @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertDictEqualTruncates @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertEqual @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertEqualSingleLine @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertEqual_diffThreshold @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertEqual_shorten @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertIn @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertIs @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertIsInstance @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertIsNone @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertIsNot @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertLogsDefaults @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertLogsFailureLevelTooHigh @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertLogsFailureLevelTooHigh_FilterInRootLogger @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertLogsFailureMismatchingLogger @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertLogsFailureNoLogs @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertLogsPerLevel @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertLogsPerLogger @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertLogsTwoMatchingMessages @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertLogsUnexpectedException @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertMultiLineEqual @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertMultiLineEqualTruncates @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertNoLogsDefault @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertNoLogsFailureFoundLogs @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertNoLogsFailurePerLevel @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertNoLogsFailurePerLogger @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertNoLogsPerLevel @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertNoLogsPerLogger @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertNoLogsUnexpectedException @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertNoLogsYieldsNone @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertNotIsInstance @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertNotRaisesRegex @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertRaisesCallable @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertRaisesContext @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertRaisesExcValue @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertRaisesNoExceptionType @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertRaisesRefcount @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertRaisesRegex @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertRaisesRegexInvalidRegex @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertRaisesRegexMismatch @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertRaisesRegexNoExceptionType @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertRegex @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertSequenceEqualMaxDiff @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertSetEqual @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertWarnsCallable @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertWarnsContext @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertWarnsModifySysModules @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertWarnsNoExceptionType @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertWarnsRegexCallable @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertWarnsRegexContext @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertWarnsRegexInvalidRegex @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testAssertWarnsRegexNoExceptionType @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testDeepcopy @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testDeprecatedMethodNames @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testEquality @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testEqualityBytesWarning @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testInequality @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testKeyboardInterrupt @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testPickle @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testShortDescriptionWhitespaceTrimming @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testShortDescriptionWithMultiLineDocstring @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testShortDescriptionWithOneLineDocstring @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testShortDescriptionWithoutDocstring @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testSkippingEverywhere @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testSystemExit @ linux-x86_64 +unittest.test.test_case.Test_TestCase.testTruncateMessage @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_call__invoking_an_instance_delegates_to_run @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_countTestCases @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_defaultTestResult @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_deprecation_of_return_val_from_test @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_eq @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_failureException__default @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_failureException__subclassing__explicit_raise @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_failureException__subclassing__implicit_raise @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_hash @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_id @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_init__no_test_name @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_init__test_name__invalid @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_init__test_name__valid @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_ne @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run__returns_given_result @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run__uses_defaultTestResult @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run_call_order__error_in_setUp @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run_call_order__error_in_setUp_default_result @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run_call_order__error_in_tearDown @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run_call_order__error_in_tearDown_default_result @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run_call_order__error_in_test @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run_call_order__error_in_test_default_result @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run_call_order__failure_in_test @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run_call_order__failure_in_test_default_result @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run_call_order__subtests @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run_call_order__subtests_failfast @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run_call_order__subtests_legacy @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run_call_order__subtests_success @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run_call_order__subtests_success_legacy @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_run_call_order_default_result @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_setUp @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_subtests_debug @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_subtests_failfast @ linux-x86_64 +unittest.test.test_case.Test_TestCase.test_tearDown @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_command_line_handling_discover_by_default @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_command_line_handling_discover_by_default_with_options @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_command_line_handling_do_discovery_calls_loader @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_command_line_handling_do_discovery_too_many_arguments @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_command_line_handling_do_discovery_uses_default_loader @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_command_line_handling_parseArgs @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_detect_module_clash @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_discover @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_discover_start_dir_is_package_calls_package_load_tests @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_discover_with_init_module_that_raises_SkipTest_on_import @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_discover_with_init_modules_that_fail_to_import @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_discover_with_module_that_raises_SkipTest_on_import @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_discover_with_modules_that_fail_to_import @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_discovery_failed_discovery @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_discovery_from_dotted_path @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_discovery_from_dotted_path_builtin_modules @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_find_tests @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_find_tests_customize_via_package_pattern @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_find_tests_default_calls_package_load_tests @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_find_tests_socket @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_find_tests_with_package @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_get_name_from_path @ linux-x86_64 +unittest.test.test_discovery.TestDiscovery.test_module_symlink_ok @ linux-x86_64 +unittest.test.test_functiontestcase.Test_FunctionTestCase.test_countTestCases @ linux-x86_64 +unittest.test.test_functiontestcase.Test_FunctionTestCase.test_id @ linux-x86_64 +unittest.test.test_functiontestcase.Test_FunctionTestCase.test_run_call_order__error_in_setUp @ linux-x86_64 +unittest.test.test_functiontestcase.Test_FunctionTestCase.test_run_call_order__error_in_tearDown @ linux-x86_64 +unittest.test.test_functiontestcase.Test_FunctionTestCase.test_run_call_order__error_in_test @ linux-x86_64 +unittest.test.test_functiontestcase.Test_FunctionTestCase.test_run_call_order__failure_in_test @ linux-x86_64 +unittest.test.test_functiontestcase.Test_FunctionTestCase.test_shortDescription__no_docstring @ linux-x86_64 +unittest.test.test_functiontestcase.Test_FunctionTestCase.test_shortDescription__singleline_docstring @ linux-x86_64 +unittest.test.test_loader.TestObsoleteFunctions.test_findTestCases @ linux-x86_64 +unittest.test.test_loader.TestObsoleteFunctions.test_getTestCaseNames @ linux-x86_64 +unittest.test.test_loader.TestObsoleteFunctions.test_makeSuite @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test___init__ @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_getTestCaseNames @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_getTestCaseNames__inheritance @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_getTestCaseNames__no_tests @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_getTestCaseNames__not_a_TestCase @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_getTestCaseNames__testNamePatterns @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_getTestCaseNames__testNamePatterns__attribute_access_regression @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromModule__TestCase_subclass @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromModule__TestCase_subclass_internals @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromModule__faulty_load_tests @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromModule__load_tests @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromModule__no_TestCase_instances @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromModule__no_TestCase_tests @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromModule__not_a_module @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromModule__pattern @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromModule__too_many_positional_args @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromModule__use_load_tests_deprecated_keyword @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromModule__use_load_tests_deprecated_positional @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromModule__use_load_tests_other_bad_keyword @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__callable__TestCase_instance @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__callable__TestCase_instance_ProperSuiteClass @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__callable__TestSuite @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__callable__wrong_type @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__empty_name @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__function_with_different_name_than_method @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__malformed_name @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__module_not_loaded @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__relative_TestCase_subclass @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__relative_TestSuite @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__relative_bad_object @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__relative_empty_name @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__relative_malformed_name @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__relative_not_a_module @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__relative_testmethod @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__relative_testmethod_ProperSuiteClass @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__relative_unknown_name @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__unknown_attr_name_on_module @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__unknown_attr_name_on_package @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromName__unknown_module_name @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__callable__TestCase_instance @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__callable__TestSuite @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__callable__call_staticmethod @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__callable__wrong_type @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__empty_name @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__empty_name_list @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__malformed_name @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__module_not_loaded @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__relative_TestCase_subclass @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__relative_TestSuite @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__relative_bad_object @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__relative_empty_name @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__relative_empty_name_list @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__relative_malformed_name @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__relative_not_a_module @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__relative_testmethod @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__unknown_attr_name @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__unknown_module_name @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__unknown_name_relative_1 @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromNames__unknown_name_relative_2 @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromTestCase @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromTestCase__TestSuite_subclass @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromTestCase__default_method_name @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromTestCase__from_FunctionTestCase @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromTestCase__from_TestCase @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_loadTestsFromTestCase__no_matches @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_partial_functions @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_sortTestMethodsUsing__None @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_sortTestMethodsUsing__default_value @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_sortTestMethodsUsing__getTestCaseNames @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_sortTestMethodsUsing__loadTestsFromModule @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_sortTestMethodsUsing__loadTestsFromName @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_sortTestMethodsUsing__loadTestsFromNames @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_sortTestMethodsUsing__loadTestsFromTestCase @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_suiteClass__default_value @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_suiteClass__loadTestsFromModule @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_suiteClass__loadTestsFromName @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_suiteClass__loadTestsFromNames @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_suiteClass__loadTestsFromTestCase @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_testMethodPrefix__default_value @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_testMethodPrefix__loadTestsFromModule @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_testMethodPrefix__loadTestsFromName @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_testMethodPrefix__loadTestsFromNames @ linux-x86_64 +unittest.test.test_loader.Test_TestLoader.test_testMethodPrefix__loadTestsFromTestCase @ linux-x86_64 +unittest.test.test_program.TestCommandLineArgs.testBufferCatchFailfast @ linux-x86_64 +unittest.test.test_program.TestCommandLineArgs.testCatchBreakInstallsHandler @ linux-x86_64 +unittest.test.test_program.TestCommandLineArgs.testParseArgsAbsolutePathsThatCanBeConverted @ linux-x86_64 +unittest.test.test_program.TestCommandLineArgs.testParseArgsAbsolutePathsThatCannotBeConverted @ linux-x86_64 +unittest.test.test_program.TestCommandLineArgs.testParseArgsFileNames @ linux-x86_64 +unittest.test.test_program.TestCommandLineArgs.testParseArgsFilePaths @ linux-x86_64 +unittest.test.test_program.TestCommandLineArgs.testParseArgsNonExistentFiles @ linux-x86_64 +unittest.test.test_program.TestCommandLineArgs.testParseArgsSelectedTestNames @ linux-x86_64 +unittest.test.test_program.TestCommandLineArgs.testRunTestsOldRunnerClass @ linux-x86_64 +unittest.test.test_program.TestCommandLineArgs.testRunTestsRunnerClass @ linux-x86_64 +unittest.test.test_program.TestCommandLineArgs.testRunTestsRunnerInstance @ linux-x86_64 +unittest.test.test_program.TestCommandLineArgs.testSelectedTestNamesFunctionalTest @ linux-x86_64 +unittest.test.test_program.TestCommandLineArgs.testVerbosity @ linux-x86_64 +unittest.test.test_program.TestCommandLineArgs.testWarning @ linux-x86_64 +unittest.test.test_program.TestCommandLineArgs.test_locals @ linux-x86_64 +unittest.test.test_program.Test_TestProgram.testNoExit @ linux-x86_64 +unittest.test.test_program.Test_TestProgram.test_Exit @ linux-x86_64 +unittest.test.test_program.Test_TestProgram.test_ExitAsDefault @ linux-x86_64 +unittest.test.test_program.Test_TestProgram.test_NonExit @ linux-x86_64 +unittest.test.test_program.Test_TestProgram.test_defaultTest_with_iterable @ linux-x86_64 +unittest.test.test_program.Test_TestProgram.test_defaultTest_with_string @ linux-x86_64 +unittest.test.test_program.Test_TestProgram.test_discovery_from_dotted_path @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferDoClassCleanups @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferDoCleanups @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferDoModuleCleanups @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferOutputAddErrorOrFailure @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferOutputOff @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferOutputStartTestAddSuccess @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferSetUp @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferSetUpModule @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferSetUpModule_DoModuleCleanups @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferSetUp_DoCleanups @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferSetupClass @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferSetupClass_DoClassCleanups @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferTearDown @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferTearDownClass @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferTearDownClass_DoClassCleanups @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferTearDownModule @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferTearDownModule_DoModuleCleanups @ linux-x86_64 +unittest.test.test_result.TestOutputBuffering.testBufferTearDown_DoCleanups @ linux-x86_64 +unittest.test.test_result.Test_OldTestResult.testOldResultWithRunner @ linux-x86_64 +unittest.test.test_result.Test_OldTestResult.testOldTestResult @ linux-x86_64 +unittest.test.test_result.Test_OldTestResult.testOldTestResultClass @ linux-x86_64 +unittest.test.test_result.Test_OldTestResult.testOldTestTesultSetup @ linux-x86_64 +unittest.test.test_result.Test_TestResult.testFailFast @ linux-x86_64 +unittest.test.test_result.Test_TestResult.testFailFastSetByRunner @ linux-x86_64 +unittest.test.test_result.Test_TestResult.testStackFrameTrimming @ linux-x86_64 +unittest.test.test_result.Test_TestResult.test_addError @ linux-x86_64 +unittest.test.test_result.Test_TestResult.test_addError_locals @ linux-x86_64 +unittest.test.test_result.Test_TestResult.test_addFailure @ linux-x86_64 +unittest.test.test_result.Test_TestResult.test_addFailure_filter_traceback_frames @ linux-x86_64 +unittest.test.test_result.Test_TestResult.test_addFailure_filter_traceback_frames_chained_exception_cycle @ linux-x86_64 +unittest.test.test_result.Test_TestResult.test_addFailure_filter_traceback_frames_chained_exception_self_loop @ linux-x86_64 +unittest.test.test_result.Test_TestResult.test_addFailure_filter_traceback_frames_context @ linux-x86_64 +unittest.test.test_result.Test_TestResult.test_addSubTest @ linux-x86_64 +unittest.test.test_result.Test_TestResult.test_addSuccess @ linux-x86_64 +unittest.test.test_result.Test_TestResult.test_init @ linux-x86_64 +unittest.test.test_result.Test_TestResult.test_startTest @ linux-x86_64 +unittest.test.test_result.Test_TestResult.test_startTestRun_stopTestRun @ linux-x86_64 +unittest.test.test_result.Test_TestResult.test_stop @ linux-x86_64 +unittest.test.test_result.Test_TestResult.test_stopTest @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testDotsOutput @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testDotsOutputSubTestMixed @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testDotsOutputSubTestSuccess @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testDotsOutputTearDownFail @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testGetDescriptionWithMultiLineDocstring @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testGetDescriptionWithOneLineDocstring @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testGetDescriptionWithoutDocstring @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testGetDuplicatedNestedSubTestDescriptionWithoutDocstring @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testGetNestedSubTestDescriptionWithoutDocstring @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testGetSubTestDescriptionForFalsyValues @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testGetSubTestDescriptionWithMultiLineDocstring @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testGetSubTestDescriptionWithOneLineDocstring @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstring @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstringAndParams @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testLongOutput @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testLongOutputSubTestMixed @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testLongOutputSubTestSuccess @ linux-x86_64 +unittest.test.test_result.Test_TextTestResult.testLongOutputTearDownFail @ linux-x86_64 +unittest.test.test_runner.TestClassCleanup.test_addClassCleanUp @ linux-x86_64 +unittest.test.test_runner.TestClassCleanup.test_debug_executes_classCleanUp @ linux-x86_64 +unittest.test.test_runner.TestClassCleanup.test_debug_executes_classCleanUp_when_teardown_exception @ linux-x86_64 +unittest.test.test_runner.TestClassCleanup.test_doClassCleanups_with_errors_addClassCleanUp @ linux-x86_64 +unittest.test.test_runner.TestClassCleanup.test_enterClassContext @ linux-x86_64 +unittest.test.test_runner.TestClassCleanup.test_enterClassContext_arg_errors @ linux-x86_64 +unittest.test.test_runner.TestClassCleanup.test_run_class_cleanUp @ linux-x86_64 +unittest.test.test_runner.TestClassCleanup.test_run_class_cleanUp_without_tearDownClass @ linux-x86_64 +unittest.test.test_runner.TestClassCleanup.test_run_nested_test @ linux-x86_64 +unittest.test.test_runner.TestClassCleanup.test_run_with_errors_addClassCleanUp @ linux-x86_64 +unittest.test.test_runner.TestClassCleanup.test_with_errors_addCleanUp @ linux-x86_64 +unittest.test.test_runner.TestClassCleanup.test_with_errors_in_addClassCleanup_and_setUps @ linux-x86_64 +unittest.test.test_runner.TestClassCleanup.test_with_errors_in_tearDownClass @ linux-x86_64 +unittest.test.test_runner.TestCleanUp.testCleanUp @ linux-x86_64 +unittest.test.test_runner.TestCleanUp.testCleanUpWithErrors @ linux-x86_64 +unittest.test.test_runner.TestCleanUp.testCleanupInRun @ linux-x86_64 +unittest.test.test_runner.TestCleanUp.testTestCaseDebugExecutesCleanups @ linux-x86_64 +unittest.test.test_runner.TestCleanUp.test_enterContext @ linux-x86_64 +unittest.test.test_runner.TestCleanUp.test_enterContext_arg_errors @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_addClassCleanup_arg_errors @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_addCleanup_arg_errors @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_addModuleCleanup_arg_errors @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_add_and_do_ModuleCleanup @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_debug_module_cleanUp_when_teardown_exception @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_debug_module_executes_cleanUp @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_doModuleCleanup_with_errors_in_addModuleCleanup @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_enterModuleContext @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_enterModuleContext_arg_errors @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_module_cleanUp_with_multiple_classes @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_run_module_cleanUp @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_run_module_cleanUp_when_teardown_exception @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_run_module_cleanUp_without_teardown @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_run_multiple_module_cleanUp @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_with_errors_in_addClassCleanup @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_with_errors_in_addCleanup @ linux-x86_64 +unittest.test.test_runner.TestModuleCleanUp.test_with_errors_in_addModuleCleanup_and_setUps @ linux-x86_64 +unittest.test.test_runner.Test_TextTestRunner.testBufferAndFailfast @ linux-x86_64 +unittest.test.test_runner.Test_TextTestRunner.testRunnerRegistersResult @ linux-x86_64 +unittest.test.test_runner.Test_TextTestRunner.testSpecifiedStreamUsed @ linux-x86_64 +unittest.test.test_runner.Test_TextTestRunner.testStdErrLookedUpAtInstantiationTime @ linux-x86_64 +unittest.test.test_runner.Test_TextTestRunner.test_init @ linux-x86_64 +unittest.test.test_runner.Test_TextTestRunner.test_locals @ linux-x86_64 +unittest.test.test_runner.Test_TextTestRunner.test_multiple_inheritance @ linux-x86_64 +unittest.test.test_runner.Test_TextTestRunner.test_pickle_unpickle @ linux-x86_64 +unittest.test.test_runner.Test_TextTestRunner.test_resultclass @ linux-x86_64 +unittest.test.test_runner.Test_TextTestRunner.test_startTestRun_stopTestRun_called @ linux-x86_64 +unittest.test.test_runner.Test_TextTestRunner.test_warnings @ linux-x86_64 +unittest.test.test_runner.Test_TextTestRunner.test_works_with_result_without_startTestRun_stopTestRun @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_class_not_setup_or_torndown_when_skipped @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_class_not_torndown_when_setup_fails @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_error_in_setup_module @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_error_in_setupclass @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_error_in_teardown_class @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_error_in_teardown_module @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_setup_class @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_setup_module @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_setup_teardown_order_with_pathological_suite @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_skiptest_in_setupclass @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_skiptest_in_setupmodule @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_suite_debug_executes_setups_and_teardowns @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_suite_debug_propagates_exceptions @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_teardown_class @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_teardown_class_two_classes @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_teardown_module @ linux-x86_64 +unittest.test.test_setups.TestSetups.test_testcase_with_missing_module @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_debug_skipping @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_debug_skipping_class @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_debug_skipping_subtests @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_decorated_skip @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_expected_failure @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_expected_failure_and_fail_in_cleanup @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_expected_failure_and_skip_in_cleanup @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_expected_failure_subtests @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_expected_failure_with_wrapped_class @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_expected_failure_with_wrapped_subclass @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_failure_and_skip_in_cleanup @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_skip_class @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_skip_doesnt_run_setup @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_skip_in_cleanup @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_skip_in_setup @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_skip_non_unittest_class @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_skip_without_reason @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_skipping @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_skipping_and_fail_in_cleanup @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_skipping_decorators @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_skipping_subtests @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_unexpected_success @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_unexpected_success_and_fail_in_cleanup @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_unexpected_success_and_skip_in_cleanup @ linux-x86_64 +unittest.test.test_skipping.Test_TestSkipping.test_unexpected_success_subtests @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_addTest__TestCase @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_addTest__TestSuite @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_addTest__casesuiteclass @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_addTest__noncallable @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_addTest__noniterable @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_addTests @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_addTests__string @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_basetestsuite @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_countTestCases_nested @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_countTestCases_simple @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_countTestCases_zero_nested @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_countTestCases_zero_simple @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_eq @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_function_in_suite @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_init__TestSuite_instances_in_tests @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_init__empty_tests @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_init__tests_from_any_iterable @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_init__tests_optional @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_iter @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_ne @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_overriding_call @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_remove_test_at_index @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_remove_test_at_index_not_indexable @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_run @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_run__empty_suite @ linux-x86_64 +unittest.test.test_suite.Test_TestSuite.test_run__requires_result @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_univnewlines.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_univnewlines.txt new file mode 100644 index 0000000000..bc9f469ab4 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_univnewlines.txt @@ -0,0 +1,34 @@ +test.test_univnewlines.CTestCRLFNewlines.test_read @ linux-x86_64 +test.test_univnewlines.CTestCRLFNewlines.test_readline @ linux-x86_64 +test.test_univnewlines.CTestCRLFNewlines.test_readlines @ linux-x86_64 +test.test_univnewlines.CTestCRLFNewlines.test_seek @ linux-x86_64 +test.test_univnewlines.CTestCRLFNewlines.test_tell @ linux-x86_64 +test.test_univnewlines.CTestCRNewlines.test_read @ linux-x86_64 +test.test_univnewlines.CTestCRNewlines.test_readline @ linux-x86_64 +test.test_univnewlines.CTestCRNewlines.test_readlines @ linux-x86_64 +test.test_univnewlines.CTestCRNewlines.test_seek @ linux-x86_64 +test.test_univnewlines.CTestLFNewlines.test_read @ linux-x86_64 +test.test_univnewlines.CTestLFNewlines.test_readline @ linux-x86_64 +test.test_univnewlines.CTestLFNewlines.test_readlines @ linux-x86_64 +test.test_univnewlines.CTestLFNewlines.test_seek @ linux-x86_64 +test.test_univnewlines.CTestMixedNewlines.test_read @ linux-x86_64 +test.test_univnewlines.CTestMixedNewlines.test_readline @ linux-x86_64 +test.test_univnewlines.CTestMixedNewlines.test_readlines @ linux-x86_64 +test.test_univnewlines.CTestMixedNewlines.test_seek @ linux-x86_64 +test.test_univnewlines.PyTestCRLFNewlines.test_read @ linux-x86_64 +test.test_univnewlines.PyTestCRLFNewlines.test_readline @ linux-x86_64 +test.test_univnewlines.PyTestCRLFNewlines.test_readlines @ linux-x86_64 +test.test_univnewlines.PyTestCRLFNewlines.test_seek @ linux-x86_64 +test.test_univnewlines.PyTestCRLFNewlines.test_tell @ linux-x86_64 +test.test_univnewlines.PyTestCRNewlines.test_read @ linux-x86_64 +test.test_univnewlines.PyTestCRNewlines.test_readline @ linux-x86_64 +test.test_univnewlines.PyTestCRNewlines.test_readlines @ linux-x86_64 +test.test_univnewlines.PyTestCRNewlines.test_seek @ linux-x86_64 +test.test_univnewlines.PyTestLFNewlines.test_read @ linux-x86_64 +test.test_univnewlines.PyTestLFNewlines.test_readline @ linux-x86_64 +test.test_univnewlines.PyTestLFNewlines.test_readlines @ linux-x86_64 +test.test_univnewlines.PyTestLFNewlines.test_seek @ linux-x86_64 +test.test_univnewlines.PyTestMixedNewlines.test_read @ linux-x86_64 +test.test_univnewlines.PyTestMixedNewlines.test_readline @ linux-x86_64 +test.test_univnewlines.PyTestMixedNewlines.test_readlines @ linux-x86_64 +test.test_univnewlines.PyTestMixedNewlines.test_seek @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unpack.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unpack.txt new file mode 100644 index 0000000000..9c5a305397 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unpack.txt @@ -0,0 +1,2 @@ +DocTestCase.test.test_unpack.__test__.doctests @ linux-x86_64 +test.test_unpack.TestCornerCases.test_extended_oparg_not_ignored @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unparse.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unparse.txt new file mode 100644 index 0000000000..56c60efd09 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_unparse.txt @@ -0,0 +1,57 @@ +test.test_unparse.CosmeticTestCase.test_class_bases_and_keywords @ linux-x86_64 +test.test_unparse.CosmeticTestCase.test_docstrings @ linux-x86_64 +test.test_unparse.CosmeticTestCase.test_docstrings_negative_cases @ linux-x86_64 +test.test_unparse.CosmeticTestCase.test_fstrings @ linux-x86_64 +test.test_unparse.CosmeticTestCase.test_lambda_parameters @ linux-x86_64 +test.test_unparse.CosmeticTestCase.test_multiquote_joined_string @ linux-x86_64 +test.test_unparse.CosmeticTestCase.test_simple_expressions_parens @ linux-x86_64 +test.test_unparse.CosmeticTestCase.test_slices @ linux-x86_64 +test.test_unparse.CosmeticTestCase.test_star_expr_assign_target @ linux-x86_64 +test.test_unparse.CosmeticTestCase.test_star_expr_assign_target_multiple @ linux-x86_64 +test.test_unparse.CosmeticTestCase.test_unary_op_factor @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_annotations @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_bytes @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_chained_comparisons @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_class_decorators @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_class_definition @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_del_statement @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_dict_comprehension @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_dict_unpacking_in_dict @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_docstrings @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_elifs @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_empty_set @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_for_else @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_fstrings @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_fstrings_complicated @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_fstrings_special_chars @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_function_arguments @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_function_type @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_huge_float @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_imaginary_literals @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_import_from_level_none @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_integer_parens @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_invalid_fstring_backslash @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_invalid_fstring_value @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_invalid_raise @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_invalid_yield_from @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_lambda_parentheses @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_min_int @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_nan @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_nonlocal @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_raise_from @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_relative_import @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_set_comprehension @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_set_literal @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_shifts @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_slices @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_starred_assignment @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_strings @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_try_except_finally @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_try_except_star_finally @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_type_comments @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_type_ignore @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_unary_parens @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_while_else @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_with_as @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_with_simple @ linux-x86_64 +test.test_unparse.UnparseTestCase.test_with_two_items @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllib.txt new file mode 100644 index 0000000000..4cc01df8a8 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllib.txt @@ -0,0 +1,101 @@ +test.test_urllib.PathName2URLTests.test_converting_drive_letter @ linux-x86_64 +test.test_urllib.PathName2URLTests.test_converting_when_no_drive_letter @ linux-x86_64 +test.test_urllib.PathName2URLTests.test_long_drive_letter @ linux-x86_64 +test.test_urllib.PathName2URLTests.test_roundtrip_pathname2url @ linux-x86_64 +test.test_urllib.PathName2URLTests.test_simple_compare @ linux-x86_64 +test.test_urllib.Pathname_Tests.test_basic @ linux-x86_64 +test.test_urllib.Pathname_Tests.test_quoting @ linux-x86_64 +test.test_urllib.ProxyTests.test_getproxies_environment_keep_no_proxies @ linux-x86_64 +test.test_urllib.ProxyTests.test_proxy_bypass_environment_always_match @ linux-x86_64 +test.test_urllib.ProxyTests.test_proxy_bypass_environment_host_match @ linux-x86_64 +test.test_urllib.ProxyTests.test_proxy_bypass_environment_newline @ linux-x86_64 +test.test_urllib.ProxyTests.test_proxy_cgi_ignore @ linux-x86_64 +test.test_urllib.ProxyTests_withOrderedEnv.test_getproxies_environment_prefer_lowercase @ linux-x86_64 +test.test_urllib.QuotingTests.test_default_quoting @ linux-x86_64 +test.test_urllib.QuotingTests.test_default_safe @ linux-x86_64 +test.test_urllib.QuotingTests.test_never_quote @ linux-x86_64 +test.test_urllib.QuotingTests.test_quote_bytes @ linux-x86_64 +test.test_urllib.QuotingTests.test_quote_plus_with_unicode @ linux-x86_64 +test.test_urllib.QuotingTests.test_quote_with_unicode @ linux-x86_64 +test.test_urllib.QuotingTests.test_quoting_plus @ linux-x86_64 +test.test_urllib.QuotingTests.test_quoting_space @ linux-x86_64 +test.test_urllib.QuotingTests.test_safe @ linux-x86_64 +test.test_urllib.RequestTests.test_default_values @ linux-x86_64 +test.test_urllib.RequestTests.test_with_method_arg @ linux-x86_64 +test.test_urllib.URL2PathNameTests.test_converting_drive_letter @ linux-x86_64 +test.test_urllib.URL2PathNameTests.test_converting_when_no_drive_letter @ linux-x86_64 +test.test_urllib.URL2PathNameTests.test_non_ascii_drive_letter @ linux-x86_64 +test.test_urllib.URL2PathNameTests.test_roundtrip_url2pathname @ linux-x86_64 +test.test_urllib.URL2PathNameTests.test_simple_compare @ linux-x86_64 +test.test_urllib.URLopener_Tests.test_local_file_open @ linux-x86_64 +test.test_urllib.URLopener_Tests.test_quoted_open @ linux-x86_64 +test.test_urllib.URLopener_Tests.test_urlopener_retrieve_file @ linux-x86_64 +test.test_urllib.URLopener_Tests.test_urlopener_retrieve_remote @ linux-x86_64 +test.test_urllib.UnquotingTests.test_unquote_to_bytes @ linux-x86_64 +test.test_urllib.UnquotingTests.test_unquote_with_unicode @ linux-x86_64 +test.test_urllib.UnquotingTests.test_unquoting @ linux-x86_64 +test.test_urllib.UnquotingTests.test_unquoting_badpercent @ linux-x86_64 +test.test_urllib.UnquotingTests.test_unquoting_mixed_case @ linux-x86_64 +test.test_urllib.UnquotingTests.test_unquoting_parts @ linux-x86_64 +test.test_urllib.UnquotingTests.test_unquoting_plus @ linux-x86_64 +test.test_urllib.UnquotingTests.test_unquoting_with_bytes_input @ linux-x86_64 +test.test_urllib.Utility_Tests.test_thishost @ linux-x86_64 +test.test_urllib.urlencode_Tests.test_doseq @ linux-x86_64 +test.test_urllib.urlencode_Tests.test_empty_sequence @ linux-x86_64 +test.test_urllib.urlencode_Tests.test_nonstring_seq_values @ linux-x86_64 +test.test_urllib.urlencode_Tests.test_nonstring_values @ linux-x86_64 +test.test_urllib.urlencode_Tests.test_quoting @ linux-x86_64 +test.test_urllib.urlencode_Tests.test_urlencode_bytes @ linux-x86_64 +test.test_urllib.urlencode_Tests.test_urlencode_encoding @ linux-x86_64 +test.test_urllib.urlencode_Tests.test_urlencode_encoding_doseq @ linux-x86_64 +test.test_urllib.urlencode_Tests.test_urlencode_encoding_safe_parameter @ linux-x86_64 +test.test_urllib.urlencode_Tests.test_using_mapping @ linux-x86_64 +test.test_urllib.urlencode_Tests.test_using_sequence @ linux-x86_64 +test.test_urllib.urlopen_DataTests.test_geturl @ linux-x86_64 +test.test_urllib.urlopen_DataTests.test_info @ linux-x86_64 +test.test_urllib.urlopen_DataTests.test_interface @ linux-x86_64 +test.test_urllib.urlopen_DataTests.test_invalid_base64_data @ linux-x86_64 +test.test_urllib.urlopen_DataTests.test_missing_comma @ linux-x86_64 +test.test_urllib.urlopen_DataTests.test_read_image @ linux-x86_64 +test.test_urllib.urlopen_DataTests.test_read_text @ linux-x86_64 +test.test_urllib.urlopen_DataTests.test_read_text_base64 @ linux-x86_64 +test.test_urllib.urlopen_FileTests.test_close @ linux-x86_64 +test.test_urllib.urlopen_FileTests.test_fileno @ linux-x86_64 +test.test_urllib.urlopen_FileTests.test_getcode @ linux-x86_64 +test.test_urllib.urlopen_FileTests.test_geturl @ linux-x86_64 +test.test_urllib.urlopen_FileTests.test_headers @ linux-x86_64 +test.test_urllib.urlopen_FileTests.test_info @ linux-x86_64 +test.test_urllib.urlopen_FileTests.test_interface @ linux-x86_64 +test.test_urllib.urlopen_FileTests.test_iter @ linux-x86_64 +test.test_urllib.urlopen_FileTests.test_read @ linux-x86_64 +test.test_urllib.urlopen_FileTests.test_readline @ linux-x86_64 +test.test_urllib.urlopen_FileTests.test_readlines @ linux-x86_64 +test.test_urllib.urlopen_FileTests.test_relativelocalfile @ linux-x86_64 +test.test_urllib.urlopen_FileTests.test_status @ linux-x86_64 +test.test_urllib.urlopen_FileTests.test_url @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_URLopener_deprecation @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_cafile_and_context @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_empty_socket @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_file_notexists @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_ftp_cache_pruning @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_invalid_redirect @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_missing_localfile @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_read_0_9 @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_read_1_0 @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_read_1_1 @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_read_bogus @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_redirect_limit_independent @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_url_fragment @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_url_path_with_control_char_rejected @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_url_path_with_newline_header_injection_rejected @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_userpass_inurl @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_userpass_inurl_w_spaces @ linux-x86_64 +test.test_urllib.urlopen_HttpTests.test_willclose @ linux-x86_64 +test.test_urllib.urlretrieve_FileTests.test_basic @ linux-x86_64 +test.test_urllib.urlretrieve_FileTests.test_copy @ linux-x86_64 +test.test_urllib.urlretrieve_FileTests.test_reporthook @ linux-x86_64 +test.test_urllib.urlretrieve_FileTests.test_reporthook_0_bytes @ linux-x86_64 +test.test_urllib.urlretrieve_FileTests.test_reporthook_5_bytes @ linux-x86_64 +test.test_urllib.urlretrieve_FileTests.test_reporthook_8193_bytes @ linux-x86_64 +test.test_urllib.urlretrieve_HttpTests.test_short_content_raises_ContentTooShortError @ linux-x86_64 +test.test_urllib.urlretrieve_HttpTests.test_short_content_raises_ContentTooShortError_without_reporthook @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllib2.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllib2.txt new file mode 100644 index 0000000000..6588b112f7 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllib2.txt @@ -0,0 +1,68 @@ +test.test_urllib2.HandlerTests.test_basic_and_digest_auth_handlers @ linux-x86_64 +test.test_urllib2.HandlerTests.test_basic_auth @ linux-x86_64 +test.test_urllib2.HandlerTests.test_basic_prior_auth_auto_send @ linux-x86_64 +test.test_urllib2.HandlerTests.test_basic_prior_auth_send_after_first_success @ linux-x86_64 +test.test_urllib2.HandlerTests.test_cookie_redirect @ linux-x86_64 +test.test_urllib2.HandlerTests.test_cookies @ linux-x86_64 +test.test_urllib2.HandlerTests.test_errors @ linux-x86_64 +test.test_urllib2.HandlerTests.test_file @ linux-x86_64 +test.test_urllib2.HandlerTests.test_fixpath_in_weirdurls @ linux-x86_64 +test.test_urllib2.HandlerTests.test_ftp @ linux-x86_64 +test.test_urllib2.HandlerTests.test_full_url_deleter @ linux-x86_64 +test.test_urllib2.HandlerTests.test_full_url_setter @ linux-x86_64 +test.test_urllib2.HandlerTests.test_http @ linux-x86_64 +test.test_urllib2.HandlerTests.test_http_body_array @ linux-x86_64 +test.test_urllib2.HandlerTests.test_http_body_empty_seq @ linux-x86_64 +test.test_urllib2.HandlerTests.test_http_body_file @ linux-x86_64 +test.test_urllib2.HandlerTests.test_http_body_fileobj @ linux-x86_64 +test.test_urllib2.HandlerTests.test_http_body_iterable @ linux-x86_64 +test.test_urllib2.HandlerTests.test_http_body_pipe @ linux-x86_64 +test.test_urllib2.HandlerTests.test_http_closed @ linux-x86_64 +test.test_urllib2.HandlerTests.test_http_doubleslash @ linux-x86_64 +test.test_urllib2.HandlerTests.test_http_handler_debuglevel @ linux-x86_64 +test.test_urllib2.HandlerTests.test_invalid_closed @ linux-x86_64 +test.test_urllib2.HandlerTests.test_invalid_redirect @ linux-x86_64 +test.test_urllib2.HandlerTests.test_proxy @ linux-x86_64 +test.test_urllib2.HandlerTests.test_proxy_basic_auth @ linux-x86_64 +test.test_urllib2.HandlerTests.test_proxy_https @ linux-x86_64 +test.test_urllib2.HandlerTests.test_proxy_https_proxy_authorization @ linux-x86_64 +test.test_urllib2.HandlerTests.test_proxy_no_proxy @ linux-x86_64 +test.test_urllib2.HandlerTests.test_proxy_no_proxy_all @ linux-x86_64 +test.test_urllib2.HandlerTests.test_redirect @ linux-x86_64 +test.test_urllib2.HandlerTests.test_redirect_fragment @ linux-x86_64 +test.test_urllib2.HandlerTests.test_relative_redirect @ linux-x86_64 +test.test_urllib2.HandlerTests.test_unsupported_auth_basic_handler @ linux-x86_64 +test.test_urllib2.HandlerTests.test_unsupported_auth_digest_handler @ linux-x86_64 +test.test_urllib2.MiscTests.test_HTTPError_interface @ linux-x86_64 +test.test_urllib2.MiscTests.test_build_opener @ linux-x86_64 +test.test_urllib2.MiscTests.test_gh_98778 @ linux-x86_64 +test.test_urllib2.MiscTests.test_parse_proxy @ linux-x86_64 +test.test_urllib2.MiscTests.test_unsupported_algorithm @ linux-x86_64 +test.test_urllib2.OpenerDirectorTests.test_add_non_handler @ linux-x86_64 +test.test_urllib2.OpenerDirectorTests.test_badly_named_methods @ linux-x86_64 +test.test_urllib2.OpenerDirectorTests.test_handled @ linux-x86_64 +test.test_urllib2.OpenerDirectorTests.test_handler_order @ linux-x86_64 +test.test_urllib2.OpenerDirectorTests.test_http_error @ linux-x86_64 +test.test_urllib2.OpenerDirectorTests.test_processors @ linux-x86_64 +test.test_urllib2.OpenerDirectorTests.test_raise @ linux-x86_64 +test.test_urllib2.RequestHdrsTests.test_password_manager @ linux-x86_64 +test.test_urllib2.RequestHdrsTests.test_password_manager_default_port @ linux-x86_64 +test.test_urllib2.RequestHdrsTests.test_request_headers_dict @ linux-x86_64 +test.test_urllib2.RequestHdrsTests.test_request_headers_methods @ linux-x86_64 +test.test_urllib2.RequestTests.test_data @ linux-x86_64 +test.test_urllib2.RequestTests.test_deleting_data_should_remove_content_length @ linux-x86_64 +test.test_urllib2.RequestTests.test_get_full_url @ linux-x86_64 +test.test_urllib2.RequestTests.test_get_host @ linux-x86_64 +test.test_urllib2.RequestTests.test_get_host_unquote @ linux-x86_64 +test.test_urllib2.RequestTests.test_get_type @ linux-x86_64 +test.test_urllib2.RequestTests.test_method @ linux-x86_64 +test.test_urllib2.RequestTests.test_proxy @ linux-x86_64 +test.test_urllib2.RequestTests.test_selector @ linux-x86_64 +test.test_urllib2.RequestTests.test_setting_data_should_remove_content_length @ linux-x86_64 +test.test_urllib2.RequestTests.test_url_fragment @ linux-x86_64 +test.test_urllib2.RequestTests.test_url_fullurl_get_full_url @ linux-x86_64 +test.test_urllib2.RequestTests.test_wrapped_url @ linux-x86_64 +test.test_urllib2.TrivialTests.test_URLError_reasonstr @ linux-x86_64 +test.test_urllib2.TrivialTests.test___all__ @ linux-x86_64 +test.test_urllib2.TrivialTests.test_parse_http_list @ linux-x86_64 +test.test_urllib2.TrivialTests.test_trivial @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllib2_localnet.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllib2_localnet.txt new file mode 100644 index 0000000000..aeedfebbd1 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllib2_localnet.txt @@ -0,0 +1,21 @@ +test.test_urllib2_localnet.BasicAuthTests.test_basic_auth_httperror @ linux-x86_64 +test.test_urllib2_localnet.ProxyAuthTests.test_proxy_qop_auth_int_works_or_throws_urlerror @ linux-x86_64 +test.test_urllib2_localnet.ProxyAuthTests.test_proxy_qop_auth_works @ linux-x86_64 +test.test_urllib2_localnet.ProxyAuthTests.test_proxy_with_bad_password_raises_httperror @ linux-x86_64 +test.test_urllib2_localnet.ProxyAuthTests.test_proxy_with_no_password_raises_httperror @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_200 @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_200_with_parameters @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_404 @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_basic @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_chunked @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_geturl @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_https @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_https_with_cadefault @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_https_with_cafile @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_info @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_issue16464 @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_iteration @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_line_iteration @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_redirection @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_sending_headers @ linux-x86_64 +test.test_urllib2_localnet.TestUrlopen.test_sending_headers_camel @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllib2net.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllib2net.txt new file mode 100644 index 0000000000..111928a3a2 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllib2net.txt @@ -0,0 +1,10 @@ +test.test_urllib2net.CloseSocketTest.test_close @ linux-x86_64 +test.test_urllib2net.OtherNetworkTests.test_custom_headers @ linux-x86_64 +test.test_urllib2net.OtherNetworkTests.test_file @ linux-x86_64 +!test.test_urllib2net.OtherNetworkTests.test_ftp @ linux-x86_64 +test.test_urllib2net.OtherNetworkTests.test_redirect_url_withfrag @ linux-x86_64 +test.test_urllib2net.OtherNetworkTests.test_urlwithfrag @ linux-x86_64 +test.test_urllib2net.TimeoutTest.test_http_basic @ linux-x86_64 +test.test_urllib2net.TimeoutTest.test_http_default_timeout @ linux-x86_64 +test.test_urllib2net.TimeoutTest.test_http_no_timeout @ linux-x86_64 +test.test_urllib2net.TimeoutTest.test_http_timeout @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllib_response.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllib_response.txt new file mode 100644 index 0000000000..56c0d090df --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllib_response.txt @@ -0,0 +1,4 @@ +test.test_urllib_response.TestResponse.test_addclosehook @ linux-x86_64 +test.test_urllib_response.TestResponse.test_addinfo @ linux-x86_64 +test.test_urllib_response.TestResponse.test_addinfourl @ linux-x86_64 +test.test_urllib_response.TestResponse.test_with @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllibnet.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllibnet.txt new file mode 100644 index 0000000000..88801ca7ee --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urllibnet.txt @@ -0,0 +1,12 @@ +test.test_urllibnet.URLTimeoutTest.testURLread @ linux-x86_64 +test.test_urllibnet.urlopenNetworkTests.test_bad_address @ linux-x86_64 +test.test_urllibnet.urlopenNetworkTests.test_basic @ linux-x86_64 +test.test_urllibnet.urlopenNetworkTests.test_getcode @ linux-x86_64 +test.test_urllibnet.urlopenNetworkTests.test_geturl @ linux-x86_64 +test.test_urllibnet.urlopenNetworkTests.test_info @ linux-x86_64 +test.test_urllibnet.urlopenNetworkTests.test_readlines @ linux-x86_64 +test.test_urllibnet.urlretrieveNetworkTests.test_basic @ linux-x86_64 +test.test_urllibnet.urlretrieveNetworkTests.test_data_header @ linux-x86_64 +test.test_urllibnet.urlretrieveNetworkTests.test_header @ linux-x86_64 +test.test_urllibnet.urlretrieveNetworkTests.test_reporthook @ linux-x86_64 +test.test_urllibnet.urlretrieveNetworkTests.test_specified_path @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urlparse.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urlparse.txt new file mode 100644 index 0000000000..82ef9813da --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_urlparse.txt @@ -0,0 +1,71 @@ +test.test_urlparse.DeprecationTest.test_Quoter_deprecation @ linux-x86_64 +test.test_urlparse.DeprecationTest.test_splitattr_deprecation @ linux-x86_64 +test.test_urlparse.DeprecationTest.test_splithost_deprecation @ linux-x86_64 +test.test_urlparse.DeprecationTest.test_splitnport_deprecation @ linux-x86_64 +test.test_urlparse.DeprecationTest.test_splitpasswd_deprecation @ linux-x86_64 +test.test_urlparse.DeprecationTest.test_splitport_deprecation @ linux-x86_64 +test.test_urlparse.DeprecationTest.test_splitquery_deprecation @ linux-x86_64 +test.test_urlparse.DeprecationTest.test_splittag_deprecation @ linux-x86_64 +test.test_urlparse.DeprecationTest.test_splittype_deprecation @ linux-x86_64 +test.test_urlparse.DeprecationTest.test_splituser_deprecation @ linux-x86_64 +test.test_urlparse.DeprecationTest.test_splitvalue_deprecation @ linux-x86_64 +test.test_urlparse.DeprecationTest.test_to_bytes_deprecation @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_Quoter_repr @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_RFC1808 @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_RFC2368 @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_RFC2396 @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_RFC2732 @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_RFC3986 @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_all @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_anyscheme @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_attributes_bad_port @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_attributes_bad_scheme @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_attributes_without_netloc @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_clear_cache_for_code_coverage @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_default_scheme @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_http_roundtrips @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_invalid_bracketed_hosts @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_issue14072 @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_mixed_types_rejected @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_noslash @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_parse_fragments @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_parse_qs_encoding @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_parse_qs_separator @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_parse_qsl_encoding @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_parse_qsl_max_num_fields @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_parse_qsl_separator @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_port_casting_failure_message @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_portseparator @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_qs @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_qsl @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_quote_errors @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_quote_from_bytes @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_result_pairs @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_roundtrips @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_splitting_bracketed_hosts @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_telurl_params @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_unparse_parse @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_unquote_to_bytes @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_urldefrag @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_urlencode_quote_via @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_urlencode_sequences @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_urljoins @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_urllib_parse_getattr_failure @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_urlsplit_attributes @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_urlsplit_remove_unsafe_bytes @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_urlsplit_scoped_IPv6 @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_urlsplit_strip_url @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_usingsys @ linux-x86_64 +test.test_urlparse.UrlParseTestCase.test_withoutscheme @ linux-x86_64 +test.test_urlparse.Utility_Tests.test_splitattr @ linux-x86_64 +test.test_urlparse.Utility_Tests.test_splithost @ linux-x86_64 +test.test_urlparse.Utility_Tests.test_splitnport @ linux-x86_64 +test.test_urlparse.Utility_Tests.test_splitpasswd @ linux-x86_64 +test.test_urlparse.Utility_Tests.test_splitport @ linux-x86_64 +test.test_urlparse.Utility_Tests.test_splitquery @ linux-x86_64 +test.test_urlparse.Utility_Tests.test_splittag @ linux-x86_64 +test.test_urlparse.Utility_Tests.test_splittype @ linux-x86_64 +test.test_urlparse.Utility_Tests.test_splituser @ linux-x86_64 +test.test_urlparse.Utility_Tests.test_splitvalue @ linux-x86_64 +test.test_urlparse.Utility_Tests.test_to_bytes @ linux-x86_64 +test.test_urlparse.Utility_Tests.test_unwrap @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_userdict.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_userdict.txt new file mode 100644 index 0000000000..d5f657be62 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_userdict.txt @@ -0,0 +1,24 @@ +test.test_userdict.UserDictTest.test_all @ linux-x86_64 +test.test_userdict.UserDictTest.test_bool @ linux-x86_64 +test.test_userdict.UserDictTest.test_clear @ linux-x86_64 +test.test_userdict.UserDictTest.test_constructor @ linux-x86_64 +test.test_userdict.UserDictTest.test_contains @ linux-x86_64 +test.test_userdict.UserDictTest.test_copy @ linux-x86_64 +test.test_userdict.UserDictTest.test_eq @ linux-x86_64 +test.test_userdict.UserDictTest.test_fromkeys @ linux-x86_64 +test.test_userdict.UserDictTest.test_get @ linux-x86_64 +test.test_userdict.UserDictTest.test_getitem @ linux-x86_64 +test.test_userdict.UserDictTest.test_init @ linux-x86_64 +test.test_userdict.UserDictTest.test_items @ linux-x86_64 +test.test_userdict.UserDictTest.test_keys @ linux-x86_64 +test.test_userdict.UserDictTest.test_len @ linux-x86_64 +test.test_userdict.UserDictTest.test_missing @ linux-x86_64 +test.test_userdict.UserDictTest.test_mutatingiteration @ linux-x86_64 +test.test_userdict.UserDictTest.test_pop @ linux-x86_64 +test.test_userdict.UserDictTest.test_popitem @ linux-x86_64 +test.test_userdict.UserDictTest.test_read @ linux-x86_64 +test.test_userdict.UserDictTest.test_repr @ linux-x86_64 +test.test_userdict.UserDictTest.test_setdefault @ linux-x86_64 +test.test_userdict.UserDictTest.test_update @ linux-x86_64 +test.test_userdict.UserDictTest.test_values @ linux-x86_64 +test.test_userdict.UserDictTest.test_write @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_userlist.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_userlist.txt new file mode 100644 index 0000000000..7e870e2ce7 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_userlist.txt @@ -0,0 +1,47 @@ +test.test_userlist.UserListTest.test_add_specials @ linux-x86_64 +test.test_userlist.UserListTest.test_addmul @ linux-x86_64 +test.test_userlist.UserListTest.test_append @ linux-x86_64 +test.test_userlist.UserListTest.test_clear @ linux-x86_64 +test.test_userlist.UserListTest.test_constructor_exception_handling @ linux-x86_64 +test.test_userlist.UserListTest.test_constructors @ linux-x86_64 +test.test_userlist.UserListTest.test_contains @ linux-x86_64 +test.test_userlist.UserListTest.test_contains_fake @ linux-x86_64 +test.test_userlist.UserListTest.test_contains_order @ linux-x86_64 +test.test_userlist.UserListTest.test_copy @ linux-x86_64 +test.test_userlist.UserListTest.test_count @ linux-x86_64 +test.test_userlist.UserListTest.test_delitem @ linux-x86_64 +test.test_userlist.UserListTest.test_delslice @ linux-x86_64 +test.test_userlist.UserListTest.test_exhausted_iterator @ linux-x86_64 +test.test_userlist.UserListTest.test_extend @ linux-x86_64 +test.test_userlist.UserListTest.test_extendedslicing @ linux-x86_64 +test.test_userlist.UserListTest.test_getitem @ linux-x86_64 +test.test_userlist.UserListTest.test_getitem_error @ linux-x86_64 +test.test_userlist.UserListTest.test_getitemoverwriteiter @ linux-x86_64 +test.test_userlist.UserListTest.test_getslice @ linux-x86_64 +test.test_userlist.UserListTest.test_iadd @ linux-x86_64 +test.test_userlist.UserListTest.test_imul @ linux-x86_64 +test.test_userlist.UserListTest.test_index @ linux-x86_64 +test.test_userlist.UserListTest.test_init @ linux-x86_64 +test.test_userlist.UserListTest.test_insert @ linux-x86_64 +test.test_userlist.UserListTest.test_len @ linux-x86_64 +test.test_userlist.UserListTest.test_minmax @ linux-x86_64 +test.test_userlist.UserListTest.test_mixedadd @ linux-x86_64 +test.test_userlist.UserListTest.test_mixedcmp @ linux-x86_64 +test.test_userlist.UserListTest.test_pickle @ linux-x86_64 +test.test_userlist.UserListTest.test_pop @ linux-x86_64 +test.test_userlist.UserListTest.test_radd_specials @ linux-x86_64 +test.test_userlist.UserListTest.test_remove @ linux-x86_64 +test.test_userlist.UserListTest.test_repeat @ linux-x86_64 +test.test_userlist.UserListTest.test_repr @ linux-x86_64 +test.test_userlist.UserListTest.test_reverse @ linux-x86_64 +test.test_userlist.UserListTest.test_reversed @ linux-x86_64 +test.test_userlist.UserListTest.test_set_subscript @ linux-x86_64 +test.test_userlist.UserListTest.test_setitem @ linux-x86_64 +test.test_userlist.UserListTest.test_setitem_error @ linux-x86_64 +test.test_userlist.UserListTest.test_setslice @ linux-x86_64 +test.test_userlist.UserListTest.test_slice @ linux-x86_64 +test.test_userlist.UserListTest.test_slice_type @ linux-x86_64 +test.test_userlist.UserListTest.test_sort @ linux-x86_64 +test.test_userlist.UserListTest.test_subscript @ linux-x86_64 +test.test_userlist.UserListTest.test_truth @ linux-x86_64 +test.test_userlist.UserListTest.test_userlist_copy @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_userstring.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_userstring.txt new file mode 100644 index 0000000000..0defdf79c7 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_userstring.txt @@ -0,0 +1,55 @@ +test.test_userstring.UserStringTest.test___contains__ @ linux-x86_64 +test.test_userstring.UserStringTest.test_additional_rsplit @ linux-x86_64 +test.test_userstring.UserStringTest.test_additional_split @ linux-x86_64 +test.test_userstring.UserStringTest.test_capitalize @ linux-x86_64 +test.test_userstring.UserStringTest.test_center @ linux-x86_64 +test.test_userstring.UserStringTest.test_count @ linux-x86_64 +test.test_userstring.UserStringTest.test_encode_default_args @ linux-x86_64 +test.test_userstring.UserStringTest.test_encode_explicit_none_args @ linux-x86_64 +test.test_userstring.UserStringTest.test_endswith @ linux-x86_64 +test.test_userstring.UserStringTest.test_expandtabs @ linux-x86_64 +test.test_userstring.UserStringTest.test_extended_getslice @ linux-x86_64 +test.test_userstring.UserStringTest.test_find @ linux-x86_64 +test.test_userstring.UserStringTest.test_find_etc_raise_correct_error_messages @ linux-x86_64 +test.test_userstring.UserStringTest.test_find_periodic_pattern @ linux-x86_64 +test.test_userstring.UserStringTest.test_find_shift_table_overflow @ linux-x86_64 +test.test_userstring.UserStringTest.test_fixtype @ linux-x86_64 +test.test_userstring.UserStringTest.test_floatformatting @ linux-x86_64 +test.test_userstring.UserStringTest.test_formatting @ linux-x86_64 +test.test_userstring.UserStringTest.test_hash @ linux-x86_64 +test.test_userstring.UserStringTest.test_index @ linux-x86_64 +test.test_userstring.UserStringTest.test_inplace_rewrites @ linux-x86_64 +test.test_userstring.UserStringTest.test_isalnum @ linux-x86_64 +test.test_userstring.UserStringTest.test_isalpha @ linux-x86_64 +test.test_userstring.UserStringTest.test_isascii @ linux-x86_64 +test.test_userstring.UserStringTest.test_isdigit @ linux-x86_64 +test.test_userstring.UserStringTest.test_islower @ linux-x86_64 +test.test_userstring.UserStringTest.test_isspace @ linux-x86_64 +test.test_userstring.UserStringTest.test_istitle @ linux-x86_64 +test.test_userstring.UserStringTest.test_isupper @ linux-x86_64 +test.test_userstring.UserStringTest.test_join @ linux-x86_64 +test.test_userstring.UserStringTest.test_ljust @ linux-x86_64 +test.test_userstring.UserStringTest.test_lower @ linux-x86_64 +test.test_userstring.UserStringTest.test_mul @ linux-x86_64 +test.test_userstring.UserStringTest.test_none_arguments @ linux-x86_64 +test.test_userstring.UserStringTest.test_partition @ linux-x86_64 +test.test_userstring.UserStringTest.test_removeprefix @ linux-x86_64 +test.test_userstring.UserStringTest.test_removesuffix @ linux-x86_64 +test.test_userstring.UserStringTest.test_replace @ linux-x86_64 +test.test_userstring.UserStringTest.test_rfind @ linux-x86_64 +test.test_userstring.UserStringTest.test_rindex @ linux-x86_64 +test.test_userstring.UserStringTest.test_rjust @ linux-x86_64 +test.test_userstring.UserStringTest.test_rmod @ linux-x86_64 +test.test_userstring.UserStringTest.test_rpartition @ linux-x86_64 +test.test_userstring.UserStringTest.test_rsplit @ linux-x86_64 +test.test_userstring.UserStringTest.test_slice @ linux-x86_64 +test.test_userstring.UserStringTest.test_split @ linux-x86_64 +test.test_userstring.UserStringTest.test_splitlines @ linux-x86_64 +test.test_userstring.UserStringTest.test_startswith @ linux-x86_64 +test.test_userstring.UserStringTest.test_strip @ linux-x86_64 +test.test_userstring.UserStringTest.test_strip_whitespace @ linux-x86_64 +test.test_userstring.UserStringTest.test_subscript @ linux-x86_64 +test.test_userstring.UserStringTest.test_swapcase @ linux-x86_64 +test.test_userstring.UserStringTest.test_title @ linux-x86_64 +test.test_userstring.UserStringTest.test_upper @ linux-x86_64 +test.test_userstring.UserStringTest.test_zfill @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_utf8_mode.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_utf8_mode.txt new file mode 100644 index 0000000000..ca970c16fc --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_utf8_mode.txt @@ -0,0 +1,4 @@ +test.test_utf8_mode.UTF8ModeTests.test_filesystemencoding @ linux-x86_64 +test.test_utf8_mode.UTF8ModeTests.test_io @ linux-x86_64 +test.test_utf8_mode.UTF8ModeTests.test_io_encoding @ linux-x86_64 +test.test_utf8_mode.UTF8ModeTests.test_pyio_encoding @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_utf8source.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_utf8source.txt new file mode 100644 index 0000000000..2dc3b5803f --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_utf8source.txt @@ -0,0 +1,3 @@ +test.test_utf8source.BuiltinCompileTests.test_latin1 @ linux-x86_64 +test.test_utf8source.PEP3120Test.test_badsyntax @ linux-x86_64 +test.test_utf8source.PEP3120Test.test_pep3120 @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_uu.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_uu.txt new file mode 100644 index 0000000000..5fc858b1b3 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_uu.txt @@ -0,0 +1,2 @@ +test.test_uu.UUTest.test_missingbegin @ linux-x86_64 +test.test_uu.UUTest.test_no_directory_traversal @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_uuid.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_uuid.txt new file mode 100644 index 0000000000..7d2d6e6cff --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_uuid.txt @@ -0,0 +1,20 @@ +test.test_uuid.TestInternalsWithoutExtModule.test_find_mac_near_keyword @ linux-x86_64 +test.test_uuid.TestInternalsWithoutExtModule.test_find_under_heading @ linux-x86_64 +test.test_uuid.TestInternalsWithoutExtModule.test_find_under_heading_ipv6 @ linux-x86_64 +test.test_uuid.TestInternalsWithoutExtModule.test_ip_getnode @ linux-x86_64 +test.test_uuid.TestInternalsWithoutExtModule.test_parse_mac @ linux-x86_64 +test.test_uuid.TestInternalsWithoutExtModule.test_parse_mac_aix @ linux-x86_64 +test.test_uuid.TestInternalsWithoutExtModule.test_random_getnode @ linux-x86_64 +test.test_uuid.TestUUIDWithoutExtModule.test_UUID @ linux-x86_64 +test.test_uuid.TestUUIDWithoutExtModule.test_exceptions @ linux-x86_64 +test.test_uuid.TestUUIDWithoutExtModule.test_getnode @ linux-x86_64 +test.test_uuid.TestUUIDWithoutExtModule.test_pickle_roundtrip @ linux-x86_64 +test.test_uuid.TestUUIDWithoutExtModule.test_safe_uuid_enum @ linux-x86_64 +test.test_uuid.TestUUIDWithoutExtModule.test_unpickle_previous_python_versions @ linux-x86_64 +test.test_uuid.TestUUIDWithoutExtModule.test_uuid1 @ linux-x86_64 +test.test_uuid.TestUUIDWithoutExtModule.test_uuid1_eui64 @ linux-x86_64 +test.test_uuid.TestUUIDWithoutExtModule.test_uuid1_time @ linux-x86_64 +test.test_uuid.TestUUIDWithoutExtModule.test_uuid3 @ linux-x86_64 +test.test_uuid.TestUUIDWithoutExtModule.test_uuid4 @ linux-x86_64 +test.test_uuid.TestUUIDWithoutExtModule.test_uuid5 @ linux-x86_64 +test.test_uuid.TestUUIDWithoutExtModule.test_uuid_weakref @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_venv.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_venv.txt new file mode 100644 index 0000000000..04358f1fcc --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_venv.txt @@ -0,0 +1,15 @@ +test.test_venv.BasicTest.test_deactivate_with_strict_bash_opts @ linux-x86_64 +test.test_venv.BasicTest.test_executable @ linux-x86_64 +test.test_venv.BasicTest.test_executable_symlinks @ linux-x86_64 +test.test_venv.BasicTest.test_isolation @ linux-x86_64 +test.test_venv.BasicTest.test_overwrite_existing @ linux-x86_64 +test.test_venv.BasicTest.test_pathsep_error @ linux-x86_64 +test.test_venv.BasicTest.test_prefixes @ linux-x86_64 +test.test_venv.BasicTest.test_prompt @ linux-x86_64 +test.test_venv.BasicTest.test_symlinking @ linux-x86_64 +test.test_venv.BasicTest.test_unoverwritable_fails @ linux-x86_64 +test.test_venv.BasicTest.test_upgrade @ linux-x86_64 +test.test_venv.BasicTest.test_upgrade_dependencies @ linux-x86_64 +test.test_venv.EnsurePipTest.test_devnull @ linux-x86_64 +test.test_venv.EnsurePipTest.test_explicit_no_pip @ linux-x86_64 +test.test_venv.EnsurePipTest.test_no_pip_by_default @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_warnings.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_warnings.txt new file mode 100644 index 0000000000..dabb10b455 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_warnings.txt @@ -0,0 +1,113 @@ +test.test_warnings.BootstrapTest.test_issue_8766 @ linux-x86_64 +test.test_warnings.CCatchWarningTests.test_catch_warnings_defaults @ linux-x86_64 +test.test_warnings.CCatchWarningTests.test_catch_warnings_recording @ linux-x86_64 +test.test_warnings.CCatchWarningTests.test_catch_warnings_reentry_guard @ linux-x86_64 +test.test_warnings.CCatchWarningTests.test_catch_warnings_restore @ linux-x86_64 +test.test_warnings.CCatchWarningTests.test_check_warnings @ linux-x86_64 +test.test_warnings.CCatchWarningTests.test_record_override_showwarning_before @ linux-x86_64 +test.test_warnings.CCatchWarningTests.test_record_override_showwarning_inside @ linux-x86_64 +test.test_warnings.CEnvironmentVariableTests.test_comma_separated_warnings @ linux-x86_64 +test.test_warnings.CEnvironmentVariableTests.test_conflicting_envvar_and_command_line @ linux-x86_64 +test.test_warnings.CEnvironmentVariableTests.test_default_filter_configuration @ linux-x86_64 +test.test_warnings.CEnvironmentVariableTests.test_envvar_and_command_line @ linux-x86_64 +test.test_warnings.CEnvironmentVariableTests.test_nonascii @ linux-x86_64 +test.test_warnings.CEnvironmentVariableTests.test_single_warning @ linux-x86_64 +test.test_warnings.CFilterTests.test_always @ linux-x86_64 +test.test_warnings.CFilterTests.test_always_after_default @ linux-x86_64 +test.test_warnings.CFilterTests.test_append_duplicate @ linux-x86_64 +test.test_warnings.CFilterTests.test_catchwarnings_with_simplefilter_error @ linux-x86_64 +test.test_warnings.CFilterTests.test_catchwarnings_with_simplefilter_ignore @ linux-x86_64 +test.test_warnings.CFilterTests.test_default @ linux-x86_64 +test.test_warnings.CFilterTests.test_error @ linux-x86_64 +test.test_warnings.CFilterTests.test_error_after_default @ linux-x86_64 +test.test_warnings.CFilterTests.test_filterwarnings @ linux-x86_64 +test.test_warnings.CFilterTests.test_filterwarnings_duplicate_filters @ linux-x86_64 +test.test_warnings.CFilterTests.test_ignore @ linux-x86_64 +test.test_warnings.CFilterTests.test_ignore_after_default @ linux-x86_64 +test.test_warnings.CFilterTests.test_inheritance @ linux-x86_64 +test.test_warnings.CFilterTests.test_message_matching @ linux-x86_64 +test.test_warnings.CFilterTests.test_module @ linux-x86_64 +test.test_warnings.CFilterTests.test_module_globals @ linux-x86_64 +test.test_warnings.CFilterTests.test_mutate_filter_list @ linux-x86_64 +test.test_warnings.CFilterTests.test_once @ linux-x86_64 +test.test_warnings.CFilterTests.test_ordering @ linux-x86_64 +test.test_warnings.CFilterTests.test_simplefilter_duplicate_filters @ linux-x86_64 +test.test_warnings.CPublicAPITests.test_module_all_attribute @ linux-x86_64 +test.test_warnings.CWCmdLineTests.test_import_from_module @ linux-x86_64 +test.test_warnings.CWCmdLineTests.test_improper_input @ linux-x86_64 +test.test_warnings.CWarnTests.test_accelerated @ linux-x86_64 +test.test_warnings.CWarnTests.test_bad_str @ linux-x86_64 +test.test_warnings.CWarnTests.test_exec_filename @ linux-x86_64 +test.test_warnings.CWarnTests.test_filename @ linux-x86_64 +test.test_warnings.CWarnTests.test_message @ linux-x86_64 +test.test_warnings.CWarnTests.test_stacklevel @ linux-x86_64 +test.test_warnings.CWarnTests.test_warn_explicit_non_ascii_filename @ linux-x86_64 +test.test_warnings.CWarnTests.test_warn_explicit_type_errors @ linux-x86_64 +test.test_warnings.CWarnTests.test_warn_nonstandard_types @ linux-x86_64 +test.test_warnings.CWarnTests.test_warning_classes @ linux-x86_64 +test.test_warnings.CWarningsDisplayTests.test_formatwarning @ linux-x86_64 +test.test_warnings.CWarningsDisplayTests.test_formatwarning_override @ linux-x86_64 +test.test_warnings.CWarningsDisplayTests.test_showwarning @ linux-x86_64 +test.test_warnings.PyCatchWarningTests.test_catch_warnings_defaults @ linux-x86_64 +test.test_warnings.PyCatchWarningTests.test_catch_warnings_recording @ linux-x86_64 +test.test_warnings.PyCatchWarningTests.test_catch_warnings_reentry_guard @ linux-x86_64 +test.test_warnings.PyCatchWarningTests.test_catch_warnings_restore @ linux-x86_64 +test.test_warnings.PyCatchWarningTests.test_check_warnings @ linux-x86_64 +test.test_warnings.PyCatchWarningTests.test_record_override_showwarning_before @ linux-x86_64 +test.test_warnings.PyCatchWarningTests.test_record_override_showwarning_inside @ linux-x86_64 +test.test_warnings.PyEnvironmentVariableTests.test_comma_separated_warnings @ linux-x86_64 +test.test_warnings.PyEnvironmentVariableTests.test_conflicting_envvar_and_command_line @ linux-x86_64 +test.test_warnings.PyEnvironmentVariableTests.test_default_filter_configuration @ linux-x86_64 +test.test_warnings.PyEnvironmentVariableTests.test_envvar_and_command_line @ linux-x86_64 +test.test_warnings.PyEnvironmentVariableTests.test_nonascii @ linux-x86_64 +test.test_warnings.PyEnvironmentVariableTests.test_single_warning @ linux-x86_64 +test.test_warnings.PyFilterTests.test_always @ linux-x86_64 +test.test_warnings.PyFilterTests.test_always_after_default @ linux-x86_64 +test.test_warnings.PyFilterTests.test_append_duplicate @ linux-x86_64 +test.test_warnings.PyFilterTests.test_catchwarnings_with_simplefilter_error @ linux-x86_64 +test.test_warnings.PyFilterTests.test_catchwarnings_with_simplefilter_ignore @ linux-x86_64 +test.test_warnings.PyFilterTests.test_default @ linux-x86_64 +test.test_warnings.PyFilterTests.test_error @ linux-x86_64 +test.test_warnings.PyFilterTests.test_error_after_default @ linux-x86_64 +test.test_warnings.PyFilterTests.test_filterwarnings @ linux-x86_64 +test.test_warnings.PyFilterTests.test_filterwarnings_duplicate_filters @ linux-x86_64 +test.test_warnings.PyFilterTests.test_ignore @ linux-x86_64 +test.test_warnings.PyFilterTests.test_ignore_after_default @ linux-x86_64 +test.test_warnings.PyFilterTests.test_inheritance @ linux-x86_64 +test.test_warnings.PyFilterTests.test_message_matching @ linux-x86_64 +test.test_warnings.PyFilterTests.test_module @ linux-x86_64 +test.test_warnings.PyFilterTests.test_module_globals @ linux-x86_64 +test.test_warnings.PyFilterTests.test_mutate_filter_list @ linux-x86_64 +test.test_warnings.PyFilterTests.test_once @ linux-x86_64 +test.test_warnings.PyFilterTests.test_ordering @ linux-x86_64 +test.test_warnings.PyFilterTests.test_simplefilter_duplicate_filters @ linux-x86_64 +test.test_warnings.PyPublicAPITests.test_module_all_attribute @ linux-x86_64 +test.test_warnings.PyWCmdLineTests.test_import_from_module @ linux-x86_64 +test.test_warnings.PyWCmdLineTests.test_improper_input @ linux-x86_64 +test.test_warnings.PyWCmdLineTests.test_improper_option @ linux-x86_64 +test.test_warnings.PyWCmdLineTests.test_warnings_bootstrap @ linux-x86_64 +test.test_warnings.PyWarnTests.test_bad_str @ linux-x86_64 +test.test_warnings.PyWarnTests.test_exec_filename @ linux-x86_64 +test.test_warnings.PyWarnTests.test_filename @ linux-x86_64 +test.test_warnings.PyWarnTests.test_message @ linux-x86_64 +test.test_warnings.PyWarnTests.test_pure_python @ linux-x86_64 +test.test_warnings.PyWarnTests.test_stacklevel @ linux-x86_64 +test.test_warnings.PyWarnTests.test_warn_explicit_non_ascii_filename @ linux-x86_64 +test.test_warnings.PyWarnTests.test_warn_explicit_type_errors @ linux-x86_64 +test.test_warnings.PyWarnTests.test_warn_nonstandard_types @ linux-x86_64 +test.test_warnings.PyWarnTests.test_warning_classes @ linux-x86_64 +test.test_warnings.PyWarningsDisplayTests.test_formatwarning @ linux-x86_64 +test.test_warnings.PyWarningsDisplayTests.test_formatwarning_override @ linux-x86_64 +test.test_warnings.PyWarningsDisplayTests.test_showwarning @ linux-x86_64 +test.test_warnings._DeprecatedTest.test_RuntimeError @ linux-x86_64 +test.test_warnings._DeprecatedTest.test_warning @ linux-x86_64 +test.test_warnings._WarningsTests.test_default_action @ linux-x86_64 +test.test_warnings._WarningsTests.test_filename_none @ linux-x86_64 +test.test_warnings._WarningsTests.test_filter @ linux-x86_64 +test.test_warnings._WarningsTests.test_issue31285 @ linux-x86_64 +test.test_warnings._WarningsTests.test_onceregistry @ linux-x86_64 +test.test_warnings._WarningsTests.test_show_warning_output @ linux-x86_64 +test.test_warnings._WarningsTests.test_showwarning_missing @ linux-x86_64 +test.test_warnings._WarningsTests.test_showwarning_not_callable @ linux-x86_64 +test.test_warnings._WarningsTests.test_showwarnmsg_missing @ linux-x86_64 +test.test_warnings._WarningsTests.test_stderr_none @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_wave.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_wave.txt new file mode 100644 index 0000000000..2d35c10018 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_wave.txt @@ -0,0 +1,90 @@ +test.test_wave.MiscTestCase.test__all__ @ linux-x86_64 +test.test_wave.WaveLowLevelTest.test_read_no_chunks @ linux-x86_64 +test.test_wave.WaveLowLevelTest.test_read_no_data_chunk @ linux-x86_64 +test.test_wave.WaveLowLevelTest.test_read_no_fmt_chunk @ linux-x86_64 +test.test_wave.WaveLowLevelTest.test_read_no_fmt_no_data_chunk @ linux-x86_64 +test.test_wave.WaveLowLevelTest.test_read_no_riff_chunk @ linux-x86_64 +test.test_wave.WaveLowLevelTest.test_read_not_wave @ linux-x86_64 +test.test_wave.WaveLowLevelTest.test_read_wrong_form @ linux-x86_64 +test.test_wave.WaveLowLevelTest.test_read_wrong_number_of_channels @ linux-x86_64 +test.test_wave.WaveLowLevelTest.test_read_wrong_sample_width @ linux-x86_64 +test.test_wave.WavePCM16Test.test_close @ linux-x86_64 +test.test_wave.WavePCM16Test.test_context_manager_with_filename @ linux-x86_64 +test.test_wave.WavePCM16Test.test_context_manager_with_open_file @ linux-x86_64 +test.test_wave.WavePCM16Test.test_copy @ linux-x86_64 +test.test_wave.WavePCM16Test.test_incompleted_write @ linux-x86_64 +test.test_wave.WavePCM16Test.test_multiple_writes @ linux-x86_64 +test.test_wave.WavePCM16Test.test_overflowed_write @ linux-x86_64 +test.test_wave.WavePCM16Test.test_read @ linux-x86_64 +test.test_wave.WavePCM16Test.test_read_not_from_start @ linux-x86_64 +test.test_wave.WavePCM16Test.test_read_params @ linux-x86_64 +test.test_wave.WavePCM16Test.test_unseekable_incompleted_write @ linux-x86_64 +test.test_wave.WavePCM16Test.test_unseekable_overflowed_write @ linux-x86_64 +test.test_wave.WavePCM16Test.test_unseekable_read @ linux-x86_64 +test.test_wave.WavePCM16Test.test_unseekable_write @ linux-x86_64 +test.test_wave.WavePCM16Test.test_write @ linux-x86_64 +test.test_wave.WavePCM16Test.test_write_array @ linux-x86_64 +test.test_wave.WavePCM16Test.test_write_bytearray @ linux-x86_64 +test.test_wave.WavePCM16Test.test_write_context_manager_calls_close @ linux-x86_64 +test.test_wave.WavePCM16Test.test_write_memoryview @ linux-x86_64 +test.test_wave.WavePCM16Test.test_write_params @ linux-x86_64 +test.test_wave.WavePCM24Test.test_close @ linux-x86_64 +test.test_wave.WavePCM24Test.test_context_manager_with_filename @ linux-x86_64 +test.test_wave.WavePCM24Test.test_context_manager_with_open_file @ linux-x86_64 +test.test_wave.WavePCM24Test.test_copy @ linux-x86_64 +test.test_wave.WavePCM24Test.test_incompleted_write @ linux-x86_64 +test.test_wave.WavePCM24Test.test_multiple_writes @ linux-x86_64 +test.test_wave.WavePCM24Test.test_overflowed_write @ linux-x86_64 +test.test_wave.WavePCM24Test.test_read @ linux-x86_64 +test.test_wave.WavePCM24Test.test_read_not_from_start @ linux-x86_64 +test.test_wave.WavePCM24Test.test_read_params @ linux-x86_64 +test.test_wave.WavePCM24Test.test_unseekable_incompleted_write @ linux-x86_64 +test.test_wave.WavePCM24Test.test_unseekable_overflowed_write @ linux-x86_64 +test.test_wave.WavePCM24Test.test_unseekable_read @ linux-x86_64 +test.test_wave.WavePCM24Test.test_unseekable_write @ linux-x86_64 +test.test_wave.WavePCM24Test.test_write @ linux-x86_64 +test.test_wave.WavePCM24Test.test_write_array @ linux-x86_64 +test.test_wave.WavePCM24Test.test_write_bytearray @ linux-x86_64 +test.test_wave.WavePCM24Test.test_write_context_manager_calls_close @ linux-x86_64 +test.test_wave.WavePCM24Test.test_write_memoryview @ linux-x86_64 +test.test_wave.WavePCM24Test.test_write_params @ linux-x86_64 +test.test_wave.WavePCM32Test.test_close @ linux-x86_64 +test.test_wave.WavePCM32Test.test_context_manager_with_filename @ linux-x86_64 +test.test_wave.WavePCM32Test.test_context_manager_with_open_file @ linux-x86_64 +test.test_wave.WavePCM32Test.test_copy @ linux-x86_64 +test.test_wave.WavePCM32Test.test_incompleted_write @ linux-x86_64 +test.test_wave.WavePCM32Test.test_multiple_writes @ linux-x86_64 +test.test_wave.WavePCM32Test.test_overflowed_write @ linux-x86_64 +test.test_wave.WavePCM32Test.test_read @ linux-x86_64 +test.test_wave.WavePCM32Test.test_read_not_from_start @ linux-x86_64 +test.test_wave.WavePCM32Test.test_read_params @ linux-x86_64 +test.test_wave.WavePCM32Test.test_unseekable_incompleted_write @ linux-x86_64 +test.test_wave.WavePCM32Test.test_unseekable_overflowed_write @ linux-x86_64 +test.test_wave.WavePCM32Test.test_unseekable_read @ linux-x86_64 +test.test_wave.WavePCM32Test.test_unseekable_write @ linux-x86_64 +test.test_wave.WavePCM32Test.test_write @ linux-x86_64 +test.test_wave.WavePCM32Test.test_write_array @ linux-x86_64 +test.test_wave.WavePCM32Test.test_write_bytearray @ linux-x86_64 +test.test_wave.WavePCM32Test.test_write_context_manager_calls_close @ linux-x86_64 +test.test_wave.WavePCM32Test.test_write_memoryview @ linux-x86_64 +test.test_wave.WavePCM32Test.test_write_params @ linux-x86_64 +test.test_wave.WavePCM8Test.test_close @ linux-x86_64 +test.test_wave.WavePCM8Test.test_context_manager_with_filename @ linux-x86_64 +test.test_wave.WavePCM8Test.test_context_manager_with_open_file @ linux-x86_64 +test.test_wave.WavePCM8Test.test_copy @ linux-x86_64 +test.test_wave.WavePCM8Test.test_incompleted_write @ linux-x86_64 +test.test_wave.WavePCM8Test.test_multiple_writes @ linux-x86_64 +test.test_wave.WavePCM8Test.test_overflowed_write @ linux-x86_64 +test.test_wave.WavePCM8Test.test_read @ linux-x86_64 +test.test_wave.WavePCM8Test.test_read_not_from_start @ linux-x86_64 +test.test_wave.WavePCM8Test.test_read_params @ linux-x86_64 +test.test_wave.WavePCM8Test.test_unseekable_incompleted_write @ linux-x86_64 +test.test_wave.WavePCM8Test.test_unseekable_overflowed_write @ linux-x86_64 +test.test_wave.WavePCM8Test.test_unseekable_read @ linux-x86_64 +test.test_wave.WavePCM8Test.test_unseekable_write @ linux-x86_64 +test.test_wave.WavePCM8Test.test_write @ linux-x86_64 +test.test_wave.WavePCM8Test.test_write_array @ linux-x86_64 +test.test_wave.WavePCM8Test.test_write_bytearray @ linux-x86_64 +test.test_wave.WavePCM8Test.test_write_context_manager_calls_close @ linux-x86_64 +test.test_wave.WavePCM8Test.test_write_memoryview @ linux-x86_64 +test.test_wave.WavePCM8Test.test_write_params @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_weakref.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_weakref.txt new file mode 100644 index 0000000000..03fc77d16a --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_weakref.txt @@ -0,0 +1,86 @@ +DocTestCase.test.test_weakref.__test__.libreftest @ linux-x86_64 +test.test_weakref.FinalizeTestCase.test_arg_errors @ linux-x86_64 +test.test_weakref.FinalizeTestCase.test_finalize @ linux-x86_64 +test.test_weakref.MappingTestCase.test_make_weak_keyed_dict_from_dict @ linux-x86_64 +test.test_weakref.MappingTestCase.test_make_weak_keyed_dict_from_weak_keyed_dict @ linux-x86_64 +test.test_weakref.MappingTestCase.test_make_weak_keyed_dict_repr @ linux-x86_64 +test.test_weakref.MappingTestCase.test_make_weak_valued_dict_from_dict @ linux-x86_64 +test.test_weakref.MappingTestCase.test_make_weak_valued_dict_from_weak_valued_dict @ linux-x86_64 +test.test_weakref.MappingTestCase.test_make_weak_valued_dict_misc @ linux-x86_64 +test.test_weakref.MappingTestCase.test_make_weak_valued_dict_repr @ linux-x86_64 +test.test_weakref.MappingTestCase.test_threaded_weak_key_dict_copy @ linux-x86_64 +test.test_weakref.MappingTestCase.test_threaded_weak_value_dict_copy @ linux-x86_64 +test.test_weakref.MappingTestCase.test_threaded_weak_value_dict_deepcopy @ linux-x86_64 +test.test_weakref.MappingTestCase.test_threaded_weak_valued_consistency @ linux-x86_64 +test.test_weakref.MappingTestCase.test_threaded_weak_valued_pop @ linux-x86_64 +test.test_weakref.MappingTestCase.test_threaded_weak_valued_setdefault @ linux-x86_64 +test.test_weakref.MappingTestCase.test_weak_keyed_delitem @ linux-x86_64 +test.test_weakref.MappingTestCase.test_weak_keyed_dict_popitem @ linux-x86_64 +test.test_weakref.MappingTestCase.test_weak_keyed_dict_setdefault @ linux-x86_64 +test.test_weakref.MappingTestCase.test_weak_keyed_dict_update @ linux-x86_64 +test.test_weakref.MappingTestCase.test_weak_keyed_iters @ linux-x86_64 +test.test_weakref.MappingTestCase.test_weak_valued_delitem @ linux-x86_64 +test.test_weakref.MappingTestCase.test_weak_valued_dict_popitem @ linux-x86_64 +test.test_weakref.MappingTestCase.test_weak_valued_dict_setdefault @ linux-x86_64 +test.test_weakref.MappingTestCase.test_weak_valued_dict_update @ linux-x86_64 +test.test_weakref.MappingTestCase.test_weak_valued_iters @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_basic_callback @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_basic_proxy @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_basic_ref @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_callback_different_classes @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_callback_gcs @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_callback_in_cycle @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_callback_reachable_one_way @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_callbacks_protected @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_constructor_kwargs @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_hashing @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_init @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_multiple_callbacks @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_multiple_selfref_callbacks @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_newstyle_number_ops @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_ordering @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_proxy_bool @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_proxy_deletion @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_proxy_div @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_proxy_index @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_proxy_iter @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_proxy_next @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_proxy_reversed @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_proxy_unicode @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_ref_created_during_del @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_set_callback_attribute @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_sf_bug_840829 @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_shared_ref_without_callback @ linux-x86_64 +test.test_weakref.ReferencesTestCase.test_trashcan_16602 @ linux-x86_64 +test.test_weakref.SubclassableWeakrefTestCase.test_subclass_refs_with_cycle @ linux-x86_64 +test.test_weakref.SubclassableWeakrefTestCase.test_subclass_refs_with_slots @ linux-x86_64 +test.test_weakref.WeakKeyDictionaryTestCase.test_bool @ linux-x86_64 +test.test_weakref.WeakKeyDictionaryTestCase.test_constructor @ linux-x86_64 +test.test_weakref.WeakKeyDictionaryTestCase.test_get @ linux-x86_64 +test.test_weakref.WeakKeyDictionaryTestCase.test_getitem @ linux-x86_64 +test.test_weakref.WeakKeyDictionaryTestCase.test_items @ linux-x86_64 +test.test_weakref.WeakKeyDictionaryTestCase.test_keys @ linux-x86_64 +test.test_weakref.WeakKeyDictionaryTestCase.test_len @ linux-x86_64 +test.test_weakref.WeakKeyDictionaryTestCase.test_pop @ linux-x86_64 +test.test_weakref.WeakKeyDictionaryTestCase.test_popitem @ linux-x86_64 +test.test_weakref.WeakKeyDictionaryTestCase.test_read @ linux-x86_64 +test.test_weakref.WeakKeyDictionaryTestCase.test_setdefault @ linux-x86_64 +test.test_weakref.WeakKeyDictionaryTestCase.test_update @ linux-x86_64 +test.test_weakref.WeakKeyDictionaryTestCase.test_values @ linux-x86_64 +test.test_weakref.WeakKeyDictionaryTestCase.test_write @ linux-x86_64 +test.test_weakref.WeakMethodTestCase.test_alive @ linux-x86_64 +test.test_weakref.WeakMethodTestCase.test_equality @ linux-x86_64 +test.test_weakref.WeakValueDictionaryTestCase.test_bool @ linux-x86_64 +test.test_weakref.WeakValueDictionaryTestCase.test_constructor @ linux-x86_64 +test.test_weakref.WeakValueDictionaryTestCase.test_get @ linux-x86_64 +test.test_weakref.WeakValueDictionaryTestCase.test_getitem @ linux-x86_64 +test.test_weakref.WeakValueDictionaryTestCase.test_items @ linux-x86_64 +test.test_weakref.WeakValueDictionaryTestCase.test_keys @ linux-x86_64 +test.test_weakref.WeakValueDictionaryTestCase.test_len @ linux-x86_64 +test.test_weakref.WeakValueDictionaryTestCase.test_pop @ linux-x86_64 +test.test_weakref.WeakValueDictionaryTestCase.test_popitem @ linux-x86_64 +test.test_weakref.WeakValueDictionaryTestCase.test_read @ linux-x86_64 +test.test_weakref.WeakValueDictionaryTestCase.test_setdefault @ linux-x86_64 +test.test_weakref.WeakValueDictionaryTestCase.test_update @ linux-x86_64 +test.test_weakref.WeakValueDictionaryTestCase.test_values @ linux-x86_64 +test.test_weakref.WeakValueDictionaryTestCase.test_write @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_weakset.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_weakset.txt new file mode 100644 index 0000000000..99e3e83139 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_weakset.txt @@ -0,0 +1,36 @@ +test.test_weakset.TestWeakSet.test_abc @ linux-x86_64 +test.test_weakset.TestWeakSet.test_and @ linux-x86_64 +test.test_weakset.TestWeakSet.test_clear @ linux-x86_64 +test.test_weakset.TestWeakSet.test_constructor_identity @ linux-x86_64 +test.test_weakset.TestWeakSet.test_copy @ linux-x86_64 +test.test_weakset.TestWeakSet.test_copying @ linux-x86_64 +test.test_weakset.TestWeakSet.test_difference @ linux-x86_64 +test.test_weakset.TestWeakSet.test_difference_update @ linux-x86_64 +test.test_weakset.TestWeakSet.test_discard @ linux-x86_64 +test.test_weakset.TestWeakSet.test_eq @ linux-x86_64 +test.test_weakset.TestWeakSet.test_gc @ linux-x86_64 +test.test_weakset.TestWeakSet.test_gt @ linux-x86_64 +test.test_weakset.TestWeakSet.test_hash @ linux-x86_64 +test.test_weakset.TestWeakSet.test_iand @ linux-x86_64 +test.test_weakset.TestWeakSet.test_init @ linux-x86_64 +test.test_weakset.TestWeakSet.test_inplace_on_self @ linux-x86_64 +test.test_weakset.TestWeakSet.test_intersection_update @ linux-x86_64 +test.test_weakset.TestWeakSet.test_ior @ linux-x86_64 +test.test_weakset.TestWeakSet.test_isdisjoint @ linux-x86_64 +test.test_weakset.TestWeakSet.test_isub @ linux-x86_64 +test.test_weakset.TestWeakSet.test_ixor @ linux-x86_64 +test.test_weakset.TestWeakSet.test_lt @ linux-x86_64 +test.test_weakset.TestWeakSet.test_methods @ linux-x86_64 +test.test_weakset.TestWeakSet.test_ne @ linux-x86_64 +test.test_weakset.TestWeakSet.test_new_or_init @ linux-x86_64 +test.test_weakset.TestWeakSet.test_or @ linux-x86_64 +test.test_weakset.TestWeakSet.test_pop @ linux-x86_64 +test.test_weakset.TestWeakSet.test_remove @ linux-x86_64 +test.test_weakset.TestWeakSet.test_repr @ linux-x86_64 +test.test_weakset.TestWeakSet.test_sub @ linux-x86_64 +test.test_weakset.TestWeakSet.test_sub_and_super @ linux-x86_64 +test.test_weakset.TestWeakSet.test_subclass_with_custom_hash @ linux-x86_64 +test.test_weakset.TestWeakSet.test_symmetric_difference_update @ linux-x86_64 +test.test_weakset.TestWeakSet.test_update @ linux-x86_64 +test.test_weakset.TestWeakSet.test_update_set @ linux-x86_64 +test.test_weakset.TestWeakSet.test_xor @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_webbrowser.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_webbrowser.txt new file mode 100644 index 0000000000..9ce63b4ec5 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_webbrowser.txt @@ -0,0 +1,32 @@ +test.test_webbrowser.BackgroundBrowserCommandTest.test_open @ linux-x86_64 +test.test_webbrowser.BrowserRegistrationTest.test_register @ linux-x86_64 +test.test_webbrowser.BrowserRegistrationTest.test_register_default @ linux-x86_64 +test.test_webbrowser.BrowserRegistrationTest.test_register_preferred @ linux-x86_64 +test.test_webbrowser.ChromeCommandTest.test_open @ linux-x86_64 +test.test_webbrowser.ChromeCommandTest.test_open_new @ linux-x86_64 +test.test_webbrowser.ChromeCommandTest.test_open_new_tab @ linux-x86_64 +test.test_webbrowser.ChromeCommandTest.test_open_with_autoraise_false @ linux-x86_64 +test.test_webbrowser.ELinksCommandTest.test_open @ linux-x86_64 +test.test_webbrowser.ELinksCommandTest.test_open_new @ linux-x86_64 +test.test_webbrowser.ELinksCommandTest.test_open_new_tab @ linux-x86_64 +test.test_webbrowser.ELinksCommandTest.test_open_with_autoraise_false @ linux-x86_64 +test.test_webbrowser.GaleonCommandTest.test_open @ linux-x86_64 +test.test_webbrowser.GaleonCommandTest.test_open_new @ linux-x86_64 +test.test_webbrowser.GaleonCommandTest.test_open_new_tab @ linux-x86_64 +test.test_webbrowser.GaleonCommandTest.test_open_with_autoraise_false @ linux-x86_64 +test.test_webbrowser.GenericBrowserCommandTest.test_open @ linux-x86_64 +test.test_webbrowser.ImportTest.test_get @ linux-x86_64 +test.test_webbrowser.ImportTest.test_register @ linux-x86_64 +test.test_webbrowser.ImportTest.test_synthesize @ linux-x86_64 +test.test_webbrowser.MozillaCommandTest.test_open @ linux-x86_64 +test.test_webbrowser.MozillaCommandTest.test_open_new @ linux-x86_64 +test.test_webbrowser.MozillaCommandTest.test_open_new_tab @ linux-x86_64 +test.test_webbrowser.MozillaCommandTest.test_open_with_autoraise_false @ linux-x86_64 +test.test_webbrowser.NetscapeCommandTest.test_open @ linux-x86_64 +test.test_webbrowser.NetscapeCommandTest.test_open_new @ linux-x86_64 +test.test_webbrowser.NetscapeCommandTest.test_open_new_tab @ linux-x86_64 +test.test_webbrowser.NetscapeCommandTest.test_open_with_autoraise_false @ linux-x86_64 +test.test_webbrowser.OperaCommandTest.test_open @ linux-x86_64 +test.test_webbrowser.OperaCommandTest.test_open_new @ linux-x86_64 +test.test_webbrowser.OperaCommandTest.test_open_new_tab @ linux-x86_64 +test.test_webbrowser.OperaCommandTest.test_open_with_autoraise_false @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_with.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_with.txt new file mode 100644 index 0000000000..ddd297e7b9 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_with.txt @@ -0,0 +1,50 @@ +test.test_with.AssignmentTargetTestCase.testMultipleComplexTargets @ linux-x86_64 +test.test_with.AssignmentTargetTestCase.testSingleComplexTarget @ linux-x86_64 +test.test_with.AssignmentTargetTestCase.testWithExtendedTargets @ linux-x86_64 +test.test_with.ExceptionalTestCase.testErrorsInBool @ linux-x86_64 +test.test_with.ExceptionalTestCase.testExceptionNormalized @ linux-x86_64 +test.test_with.ExceptionalTestCase.testMultipleResourcesInSingleStatement @ linux-x86_64 +test.test_with.ExceptionalTestCase.testNestedExceptionAfterInnerStatement @ linux-x86_64 +test.test_with.ExceptionalTestCase.testNestedExceptionBeforeInnerStatement @ linux-x86_64 +test.test_with.ExceptionalTestCase.testNestedSingleStatements @ linux-x86_64 +test.test_with.ExceptionalTestCase.testRaisedGeneratorExit1 @ linux-x86_64 +test.test_with.ExceptionalTestCase.testRaisedGeneratorExit2 @ linux-x86_64 +test.test_with.ExceptionalTestCase.testRaisedStopIteration1 @ linux-x86_64 +test.test_with.ExceptionalTestCase.testRaisedStopIteration2 @ linux-x86_64 +test.test_with.ExceptionalTestCase.testRaisedStopIteration3 @ linux-x86_64 +test.test_with.ExceptionalTestCase.testSingleResource @ linux-x86_64 +test.test_with.ExitSwallowsExceptionTestCase.testExitFalseDoesntSwallowException @ linux-x86_64 +test.test_with.ExitSwallowsExceptionTestCase.testExitTrueSwallowsException @ linux-x86_64 +test.test_with.FailureTestCase.testAssignmentToNoneError @ linux-x86_64 +test.test_with.FailureTestCase.testAssignmentToTupleContainingNoneError @ linux-x86_64 +test.test_with.FailureTestCase.testAssignmentToTupleOnlyContainingNoneError @ linux-x86_64 +test.test_with.FailureTestCase.testEnterAttributeError1 @ linux-x86_64 +test.test_with.FailureTestCase.testEnterAttributeError2 @ linux-x86_64 +test.test_with.FailureTestCase.testEnterThrows @ linux-x86_64 +test.test_with.FailureTestCase.testExitAttributeError @ linux-x86_64 +test.test_with.FailureTestCase.testExitThrows @ linux-x86_64 +test.test_with.FailureTestCase.testNameError @ linux-x86_64 +test.test_with.NestedNonexceptionalTestCase.testMultipleArgBound @ linux-x86_64 +test.test_with.NestedNonexceptionalTestCase.testMultipleArgUnbound @ linux-x86_64 +test.test_with.NestedNonexceptionalTestCase.testSingleArgBoundToMultipleElementTupleError @ linux-x86_64 +test.test_with.NestedNonexceptionalTestCase.testSingleArgBoundToNonTuple @ linux-x86_64 +test.test_with.NestedNonexceptionalTestCase.testSingleArgBoundToSingleElementParenthesizedList @ linux-x86_64 +test.test_with.NestedNonexceptionalTestCase.testSingleArgInlineGeneratorSyntax @ linux-x86_64 +test.test_with.NestedNonexceptionalTestCase.testSingleArgUnbound @ linux-x86_64 +test.test_with.NestedWith.testEnterReturnsTuple @ linux-x86_64 +test.test_with.NestedWith.testExceptionInEnter @ linux-x86_64 +test.test_with.NestedWith.testExceptionInExit @ linux-x86_64 +test.test_with.NestedWith.testExceptionInExprList @ linux-x86_64 +test.test_with.NestedWith.testNoExceptions @ linux-x86_64 +test.test_with.NonLocalFlowControlTestCase.testWithBreak @ linux-x86_64 +test.test_with.NonLocalFlowControlTestCase.testWithContinue @ linux-x86_64 +test.test_with.NonLocalFlowControlTestCase.testWithRaise @ linux-x86_64 +test.test_with.NonLocalFlowControlTestCase.testWithReturn @ linux-x86_64 +test.test_with.NonLocalFlowControlTestCase.testWithYield @ linux-x86_64 +test.test_with.NonexceptionalTestCase.testBoundGenerator @ linux-x86_64 +test.test_with.NonexceptionalTestCase.testInlineGeneratorBoundSyntax @ linux-x86_64 +test.test_with.NonexceptionalTestCase.testInlineGeneratorBoundToDottedVariable @ linux-x86_64 +test.test_with.NonexceptionalTestCase.testInlineGeneratorBoundToExistingVariable @ linux-x86_64 +test.test_with.NonexceptionalTestCase.testInlineGeneratorSyntax @ linux-x86_64 +test.test_with.NonexceptionalTestCase.testNestedSingleStatements @ linux-x86_64 +test.test_with.NonexceptionalTestCase.testUnboundGenerator @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_wsgiref.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_wsgiref.txt new file mode 100644 index 0000000000..cc046fd695 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_wsgiref.txt @@ -0,0 +1,34 @@ +test.test_wsgiref.HandlerTests.testAbstractMethods @ linux-x86_64 +test.test_wsgiref.HandlerTests.testBasicErrorOutput @ linux-x86_64 +test.test_wsgiref.HandlerTests.testBytesData @ linux-x86_64 +test.test_wsgiref.HandlerTests.testCGIEnviron @ linux-x86_64 +test.test_wsgiref.HandlerTests.testClientConnectionTerminations @ linux-x86_64 +test.test_wsgiref.HandlerTests.testCloseOnError @ linux-x86_64 +test.test_wsgiref.HandlerTests.testContentLength @ linux-x86_64 +test.test_wsgiref.HandlerTests.testDontResetInternalStateOnException @ linux-x86_64 +test.test_wsgiref.HandlerTests.testEnviron @ linux-x86_64 +test.test_wsgiref.HandlerTests.testErrorAfterOutput @ linux-x86_64 +test.test_wsgiref.HandlerTests.testHeaderFormats @ linux-x86_64 +test.test_wsgiref.HandlerTests.testPartialWrite @ linux-x86_64 +test.test_wsgiref.HandlerTests.testScheme @ linux-x86_64 +test.test_wsgiref.HeaderTests.testExtras @ linux-x86_64 +test.test_wsgiref.HeaderTests.testMappingInterface @ linux-x86_64 +test.test_wsgiref.HeaderTests.testRequireList @ linux-x86_64 +test.test_wsgiref.IntegrationTests.test_bytes_validation @ linux-x86_64 +test.test_wsgiref.IntegrationTests.test_cp1252_url @ linux-x86_64 +test.test_wsgiref.IntegrationTests.test_environ @ linux-x86_64 +test.test_wsgiref.IntegrationTests.test_plain_hello @ linux-x86_64 +test.test_wsgiref.IntegrationTests.test_request_length @ linux-x86_64 +test.test_wsgiref.IntegrationTests.test_simple_validation_error @ linux-x86_64 +test.test_wsgiref.IntegrationTests.test_status_validation_errors @ linux-x86_64 +test.test_wsgiref.IntegrationTests.test_validated_hello @ linux-x86_64 +test.test_wsgiref.IntegrationTests.test_wsgi_input @ linux-x86_64 +test.test_wsgiref.UtilityTests.testAppURIs @ linux-x86_64 +test.test_wsgiref.UtilityTests.testCrossDefaults @ linux-x86_64 +test.test_wsgiref.UtilityTests.testDefaults @ linux-x86_64 +test.test_wsgiref.UtilityTests.testFileWrapper @ linux-x86_64 +test.test_wsgiref.UtilityTests.testGuessScheme @ linux-x86_64 +test.test_wsgiref.UtilityTests.testHopByHop @ linux-x86_64 +test.test_wsgiref.UtilityTests.testNormalizedShifts @ linux-x86_64 +test.test_wsgiref.UtilityTests.testReqURIs @ linux-x86_64 +test.test_wsgiref.UtilityTests.testSimpleShifts @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_xdrlib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_xdrlib.txt new file mode 100644 index 0000000000..5d7a2df0a3 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_xdrlib.txt @@ -0,0 +1,6 @@ +test.test_xdrlib.ConversionErrorTest.test_double @ linux-x86_64 +test.test_xdrlib.ConversionErrorTest.test_float @ linux-x86_64 +test.test_xdrlib.ConversionErrorTest.test_pack_int @ linux-x86_64 +test.test_xdrlib.ConversionErrorTest.test_pack_uint @ linux-x86_64 +test.test_xdrlib.ConversionErrorTest.test_uhyper @ linux-x86_64 +test.test_xdrlib.XDRTest.test_xdr @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_xml_dom_minicompat.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_xml_dom_minicompat.txt new file mode 100644 index 0000000000..efaf1164e3 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_xml_dom_minicompat.txt @@ -0,0 +1,11 @@ +test.test_xml_dom_minicompat.EmptyNodeListTestCase.test_emptynodelist___add__ @ linux-x86_64 +test.test_xml_dom_minicompat.EmptyNodeListTestCase.test_emptynodelist___radd__ @ linux-x86_64 +test.test_xml_dom_minicompat.EmptyNodeListTestCase.test_emptynodelist_item @ linux-x86_64 +test.test_xml_dom_minicompat.EmptyNodeListTestCase.test_emptynodelist_length @ linux-x86_64 +test.test_xml_dom_minicompat.NodeListTestCase.test_nodelist___add__ @ linux-x86_64 +test.test_xml_dom_minicompat.NodeListTestCase.test_nodelist___radd__ @ linux-x86_64 +test.test_xml_dom_minicompat.NodeListTestCase.test_nodelist_copy @ linux-x86_64 +test.test_xml_dom_minicompat.NodeListTestCase.test_nodelist_deepcopy @ linux-x86_64 +test.test_xml_dom_minicompat.NodeListTestCase.test_nodelist_item @ linux-x86_64 +test.test_xml_dom_minicompat.NodeListTestCase.test_nodelist_length @ linux-x86_64 +test.test_xml_dom_minicompat.NodeListTestCase.test_nodelist_pickle_roundtrip @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_xml_etree.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_xml_etree.txt new file mode 100644 index 0000000000..7a77c4bd33 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_xml_etree.txt @@ -0,0 +1,181 @@ +test.test_xml_etree.BadElementPathTest.test_find_with_error @ linux-x86_64 +test.test_xml_etree.BadElementPathTest.test_find_with_mutating @ linux-x86_64 +test.test_xml_etree.BadElementPathTest.test_findall_with_error @ linux-x86_64 +test.test_xml_etree.BadElementPathTest.test_findall_with_mutating @ linux-x86_64 +test.test_xml_etree.BadElementPathTest.test_findtext_with_error @ linux-x86_64 +test.test_xml_etree.BadElementPathTest.test_findtext_with_falsey_text_attribute @ linux-x86_64 +test.test_xml_etree.BadElementPathTest.test_findtext_with_mutating @ linux-x86_64 +test.test_xml_etree.BadElementPathTest.test_findtext_with_none_text_attribute @ linux-x86_64 +test.test_xml_etree.BadElementTest.test_ass_subscr @ linux-x86_64 +test.test_xml_etree.BadElementTest.test_element_get_tail @ linux-x86_64 +test.test_xml_etree.BadElementTest.test_element_get_text @ linux-x86_64 +test.test_xml_etree.BadElementTest.test_extend_mutable_list @ linux-x86_64 +test.test_xml_etree.BadElementTest.test_extend_mutable_list2 @ linux-x86_64 +test.test_xml_etree.BadElementTest.test_recursive_repr @ linux-x86_64 +test.test_xml_etree.BadElementTest.test_remove_with_mutating @ linux-x86_64 +test.test_xml_etree.BadElementTest.test_subscr @ linux-x86_64 +test.test_xml_etree.BadElementTest.test_treebuilder_end @ linux-x86_64 +test.test_xml_etree.BadElementTest.test_treebuilder_start @ linux-x86_64 +test.test_xml_etree.BasicElementTest.test___copy__ @ linux-x86_64 +test.test_xml_etree.BasicElementTest.test___deepcopy__ @ linux-x86_64 +test.test_xml_etree.BasicElementTest.test___init__ @ linux-x86_64 +test.test_xml_etree.BasicElementTest.test_augmentation_type_errors @ linux-x86_64 +test.test_xml_etree.BasicElementTest.test_copy @ linux-x86_64 +!test.test_xml_etree.BasicElementTest.test_cyclic_gc @ linux-x86_64 +test.test_xml_etree.BasicElementTest.test_get_keyword_args @ linux-x86_64 +test.test_xml_etree.BasicElementTest.test_pickle @ linux-x86_64 +test.test_xml_etree.BasicElementTest.test_pickle_issue18997 @ linux-x86_64 +test.test_xml_etree.BasicElementTest.test_weakref @ linux-x86_64 +test.test_xml_etree.BugsTest.test_39495_treebuilder_start @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_1534630 @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_200708_close @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_200708_newline @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_200709_default_namespace @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_200709_element_comment @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_200709_element_insert @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_200709_iter_comment @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_200709_register_namespace @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_xmltoolkit21 @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_xmltoolkit25 @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_xmltoolkit28 @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_xmltoolkit39 @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_xmltoolkit54 @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_xmltoolkit55 @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_xmltoolkit60 @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_xmltoolkit62 @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_xmltoolkit63 @ linux-x86_64 +test.test_xml_etree.BugsTest.test_bug_xmltoolkitX1 @ linux-x86_64 +test.test_xml_etree.BugsTest.test_expat224_utf8_bug @ linux-x86_64 +test.test_xml_etree.BugsTest.test_expat224_utf8_bug_file @ linux-x86_64 +test.test_xml_etree.BugsTest.test_issue10777 @ linux-x86_64 +test.test_xml_etree.BugsTest.test_issue6233 @ linux-x86_64 +test.test_xml_etree.BugsTest.test_issue6565 @ linux-x86_64 +test.test_xml_etree.BugsTest.test_lost_tail @ linux-x86_64 +test.test_xml_etree.BugsTest.test_lost_text @ linux-x86_64 +test.test_xml_etree.C14NTest.test_c14n_exclusion @ linux-x86_64 +test.test_xml_etree.C14NTest.test_simple_roundtrip @ linux-x86_64 +test.test_xml_etree.ElementFindTest.test_bad_find @ linux-x86_64 +test.test_xml_etree.ElementFindTest.test_find_simple @ linux-x86_64 +test.test_xml_etree.ElementFindTest.test_find_through_ElementTree @ linux-x86_64 +test.test_xml_etree.ElementFindTest.test_find_xpath @ linux-x86_64 +test.test_xml_etree.ElementFindTest.test_findall @ linux-x86_64 +test.test_xml_etree.ElementFindTest.test_findall_different_nsmaps @ linux-x86_64 +test.test_xml_etree.ElementFindTest.test_findall_wildcard @ linux-x86_64 +test.test_xml_etree.ElementFindTest.test_test_find_with_ns @ linux-x86_64 +test.test_xml_etree.ElementIterTest.test_basic @ linux-x86_64 +test.test_xml_etree.ElementIterTest.test_copy @ linux-x86_64 +test.test_xml_etree.ElementIterTest.test_corners @ linux-x86_64 +test.test_xml_etree.ElementIterTest.test_iter_by_tag @ linux-x86_64 +test.test_xml_etree.ElementIterTest.test_pickle @ linux-x86_64 +test.test_xml_etree.ElementSlicingTest.test_delslice @ linux-x86_64 +test.test_xml_etree.ElementSlicingTest.test_getslice_negative_steps @ linux-x86_64 +test.test_xml_etree.ElementSlicingTest.test_getslice_range @ linux-x86_64 +test.test_xml_etree.ElementSlicingTest.test_getslice_single_index @ linux-x86_64 +test.test_xml_etree.ElementSlicingTest.test_getslice_steps @ linux-x86_64 +test.test_xml_etree.ElementSlicingTest.test_setslice_range @ linux-x86_64 +test.test_xml_etree.ElementSlicingTest.test_setslice_single_index @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_attlist_default @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_attrib @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_cdata @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_children @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_copy @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_custom_builder @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_custom_builder_only_end_ns @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_doctype_public @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_dump_attribute_order @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_entity @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_file_init @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_html_empty_elems_serialization @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_indent @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_indent_level @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_indent_space @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_indent_space_caching @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_initialize_parser_without_target @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_interface @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_issue18347 @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_iterparse @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_makeelement @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_methods @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_namespace @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_parsefile @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_parseliteral @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_path_cache @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_processinginstruction @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_qname @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_set_attribute @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_tostring_default_namespace @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_tostring_default_namespace_different_namespace @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_tostring_default_namespace_original_no_namespace @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_tostring_no_xml_declaration @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_tostring_xml_declaration @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_tostring_xml_declaration_cases @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_tostring_xml_declaration_unicode_encoding @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_tostringlist_default_namespace @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_tostringlist_xml_declaration @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_tree_write_attribute_order @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_writefile @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_writestring @ linux-x86_64 +test.test_xml_etree.ElementTreeTest.test_xpath_tokenizer @ linux-x86_64 +test.test_xml_etree.ElementTreeTypeTest.test_Element_subclass_constructor @ linux-x86_64 +test.test_xml_etree.ElementTreeTypeTest.test_Element_subclass_find @ linux-x86_64 +test.test_xml_etree.ElementTreeTypeTest.test_Element_subclass_new_method @ linux-x86_64 +test.test_xml_etree.ElementTreeTypeTest.test_Element_subclass_trivial @ linux-x86_64 +test.test_xml_etree.ElementTreeTypeTest.test_istype @ linux-x86_64 +test.test_xml_etree.IOTest.test_read_from_bytesio @ linux-x86_64 +test.test_xml_etree.IOTest.test_read_from_stringio @ linux-x86_64 +test.test_xml_etree.IOTest.test_read_from_user_binary_reader @ linux-x86_64 +test.test_xml_etree.IOTest.test_read_from_user_text_reader @ linux-x86_64 +test.test_xml_etree.IOTest.test_short_empty_elements @ linux-x86_64 +test.test_xml_etree.IOTest.test_tostringlist_invariant @ linux-x86_64 +test.test_xml_etree.IOTest.test_write_to_binary_file @ linux-x86_64 +test.test_xml_etree.IOTest.test_write_to_binary_file_with_encoding @ linux-x86_64 +test.test_xml_etree.IOTest.test_write_to_bytesio @ linux-x86_64 +test.test_xml_etree.IOTest.test_write_to_filename @ linux-x86_64 +test.test_xml_etree.IOTest.test_write_to_filename_as_unicode @ linux-x86_64 +test.test_xml_etree.IOTest.test_write_to_filename_with_encoding @ linux-x86_64 +test.test_xml_etree.IOTest.test_write_to_stringio @ linux-x86_64 +test.test_xml_etree.IOTest.test_write_to_text_file @ linux-x86_64 +test.test_xml_etree.IOTest.test_write_to_user_binary_writer @ linux-x86_64 +test.test_xml_etree.IOTest.test_write_to_user_text_writer @ linux-x86_64 +test.test_xml_etree.KeywordArgsTest.test_issue14818 @ linux-x86_64 +test.test_xml_etree.ModuleTest.test_all @ linux-x86_64 +test.test_xml_etree.ModuleTest.test_sanity @ linux-x86_64 +test.test_xml_etree.NamespaceParseTest.test_find_with_namespace @ linux-x86_64 +test.test_xml_etree.NoAcceleratorTest.test_correct_import_pyET @ linux-x86_64 +test.test_xml_etree.ParseErrorTest.test_error_code @ linux-x86_64 +test.test_xml_etree.ParseErrorTest.test_error_position @ linux-x86_64 +test.test_xml_etree.ParseErrorTest.test_subclass @ linux-x86_64 +test.test_xml_etree.TreeBuilderTest.test_builder_lookup_errors @ linux-x86_64 +test.test_xml_etree.TreeBuilderTest.test_doctype @ linux-x86_64 +test.test_xml_etree.TreeBuilderTest.test_dummy_builder @ linux-x86_64 +test.test_xml_etree.TreeBuilderTest.test_element_factory @ linux-x86_64 +test.test_xml_etree.TreeBuilderTest.test_element_factory_pure_python_subclass @ linux-x86_64 +test.test_xml_etree.TreeBuilderTest.test_element_factory_subclass @ linux-x86_64 +test.test_xml_etree.TreeBuilderTest.test_late_tail @ linux-x86_64 +test.test_xml_etree.TreeBuilderTest.test_late_tail_mix_pi_comments @ linux-x86_64 +test.test_xml_etree.TreeBuilderTest.test_subclass @ linux-x86_64 +test.test_xml_etree.TreeBuilderTest.test_subclass_comment_pi @ linux-x86_64 +test.test_xml_etree.TreeBuilderTest.test_treebuilder_comment @ linux-x86_64 +test.test_xml_etree.TreeBuilderTest.test_treebuilder_elementfactory_none @ linux-x86_64 +test.test_xml_etree.TreeBuilderTest.test_treebuilder_pi @ linux-x86_64 +test.test_xml_etree.XIncludeTest.test_xinclude @ linux-x86_64 +test.test_xml_etree.XIncludeTest.test_xinclude_default @ linux-x86_64 +test.test_xml_etree.XIncludeTest.test_xinclude_failures @ linux-x86_64 +test.test_xml_etree.XIncludeTest.test_xinclude_repeated @ linux-x86_64 +test.test_xml_etree.XMLParserTest.test_constructor_args @ linux-x86_64 +test.test_xml_etree.XMLParserTest.test_doctype_warning @ linux-x86_64 +test.test_xml_etree.XMLParserTest.test_inherited_doctype @ linux-x86_64 +test.test_xml_etree.XMLParserTest.test_parse_string @ linux-x86_64 +test.test_xml_etree.XMLParserTest.test_subclass @ linux-x86_64 +test.test_xml_etree.XMLParserTest.test_subclass_doctype @ linux-x86_64 +test.test_xml_etree.XMLPullParserTest.test_events @ linux-x86_64 +test.test_xml_etree.XMLPullParserTest.test_events_comment @ linux-x86_64 +test.test_xml_etree.XMLPullParserTest.test_events_pi @ linux-x86_64 +test.test_xml_etree.XMLPullParserTest.test_events_sequence @ linux-x86_64 +test.test_xml_etree.XMLPullParserTest.test_feed_while_iterating @ linux-x86_64 +test.test_xml_etree.XMLPullParserTest.test_ns_events @ linux-x86_64 +test.test_xml_etree.XMLPullParserTest.test_ns_events_start @ linux-x86_64 +test.test_xml_etree.XMLPullParserTest.test_ns_events_start_end @ linux-x86_64 +test.test_xml_etree.XMLPullParserTest.test_simple_xml @ linux-x86_64 +test.test_xml_etree.XMLPullParserTest.test_simple_xml_with_ns @ linux-x86_64 +test.test_xml_etree.XMLPullParserTest.test_unknown_event @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_xml_etree_c.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_xml_etree_c.txt new file mode 100644 index 0000000000..4bfbf45fa6 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_xml_etree_c.txt @@ -0,0 +1,181 @@ +test.test_xml_etree_c.BadElementPathTest.test_find_with_error @ linux-x86_64 +test.test_xml_etree_c.BadElementPathTest.test_find_with_mutating @ linux-x86_64 +test.test_xml_etree_c.BadElementPathTest.test_findall_with_error @ linux-x86_64 +test.test_xml_etree_c.BadElementPathTest.test_findall_with_mutating @ linux-x86_64 +test.test_xml_etree_c.BadElementPathTest.test_findtext_with_error @ linux-x86_64 +test.test_xml_etree_c.BadElementPathTest.test_findtext_with_falsey_text_attribute @ linux-x86_64 +test.test_xml_etree_c.BadElementPathTest.test_findtext_with_mutating @ linux-x86_64 +test.test_xml_etree_c.BadElementPathTest.test_findtext_with_none_text_attribute @ linux-x86_64 +test.test_xml_etree_c.BadElementTest.test_ass_subscr @ linux-x86_64 +test.test_xml_etree_c.BadElementTest.test_element_get_tail @ linux-x86_64 +test.test_xml_etree_c.BadElementTest.test_element_get_text @ linux-x86_64 +test.test_xml_etree_c.BadElementTest.test_extend_mutable_list @ linux-x86_64 +test.test_xml_etree_c.BadElementTest.test_extend_mutable_list2 @ linux-x86_64 +test.test_xml_etree_c.BadElementTest.test_recursive_repr @ linux-x86_64 +test.test_xml_etree_c.BadElementTest.test_remove_with_mutating @ linux-x86_64 +test.test_xml_etree_c.BadElementTest.test_subscr @ linux-x86_64 +test.test_xml_etree_c.BadElementTest.test_treebuilder_end @ linux-x86_64 +test.test_xml_etree_c.BadElementTest.test_treebuilder_start @ linux-x86_64 +test.test_xml_etree_c.BasicElementTest.test___copy__ @ linux-x86_64 +test.test_xml_etree_c.BasicElementTest.test___deepcopy__ @ linux-x86_64 +test.test_xml_etree_c.BasicElementTest.test___init__ @ linux-x86_64 +test.test_xml_etree_c.BasicElementTest.test_augmentation_type_errors @ linux-x86_64 +test.test_xml_etree_c.BasicElementTest.test_copy @ linux-x86_64 +!test.test_xml_etree_c.BasicElementTest.test_cyclic_gc @ linux-x86_64 +test.test_xml_etree_c.BasicElementTest.test_get_keyword_args @ linux-x86_64 +test.test_xml_etree_c.BasicElementTest.test_pickle @ linux-x86_64 +test.test_xml_etree_c.BasicElementTest.test_pickle_issue18997 @ linux-x86_64 +test.test_xml_etree_c.BasicElementTest.test_weakref @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_39495_treebuilder_start @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_1534630 @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_200708_close @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_200708_newline @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_200709_default_namespace @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_200709_element_comment @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_200709_element_insert @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_200709_iter_comment @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_200709_register_namespace @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_xmltoolkit21 @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_xmltoolkit25 @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_xmltoolkit28 @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_xmltoolkit39 @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_xmltoolkit54 @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_xmltoolkit55 @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_xmltoolkit60 @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_xmltoolkit62 @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_xmltoolkit63 @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_bug_xmltoolkitX1 @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_expat224_utf8_bug @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_expat224_utf8_bug_file @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_issue10777 @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_issue6233 @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_issue6565 @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_lost_tail @ linux-x86_64 +test.test_xml_etree_c.BugsTest.test_lost_text @ linux-x86_64 +test.test_xml_etree_c.C14NTest.test_c14n_exclusion @ linux-x86_64 +test.test_xml_etree_c.C14NTest.test_simple_roundtrip @ linux-x86_64 +test.test_xml_etree_c.ElementFindTest.test_bad_find @ linux-x86_64 +test.test_xml_etree_c.ElementFindTest.test_find_simple @ linux-x86_64 +test.test_xml_etree_c.ElementFindTest.test_find_through_ElementTree @ linux-x86_64 +test.test_xml_etree_c.ElementFindTest.test_find_xpath @ linux-x86_64 +test.test_xml_etree_c.ElementFindTest.test_findall @ linux-x86_64 +test.test_xml_etree_c.ElementFindTest.test_findall_different_nsmaps @ linux-x86_64 +test.test_xml_etree_c.ElementFindTest.test_findall_wildcard @ linux-x86_64 +test.test_xml_etree_c.ElementFindTest.test_test_find_with_ns @ linux-x86_64 +test.test_xml_etree_c.ElementIterTest.test_basic @ linux-x86_64 +test.test_xml_etree_c.ElementIterTest.test_copy @ linux-x86_64 +test.test_xml_etree_c.ElementIterTest.test_corners @ linux-x86_64 +test.test_xml_etree_c.ElementIterTest.test_iter_by_tag @ linux-x86_64 +test.test_xml_etree_c.ElementIterTest.test_pickle @ linux-x86_64 +test.test_xml_etree_c.ElementSlicingTest.test_delslice @ linux-x86_64 +test.test_xml_etree_c.ElementSlicingTest.test_getslice_negative_steps @ linux-x86_64 +test.test_xml_etree_c.ElementSlicingTest.test_getslice_range @ linux-x86_64 +test.test_xml_etree_c.ElementSlicingTest.test_getslice_single_index @ linux-x86_64 +test.test_xml_etree_c.ElementSlicingTest.test_getslice_steps @ linux-x86_64 +test.test_xml_etree_c.ElementSlicingTest.test_setslice_range @ linux-x86_64 +test.test_xml_etree_c.ElementSlicingTest.test_setslice_single_index @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_attlist_default @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_attrib @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_cdata @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_children @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_copy @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_custom_builder @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_custom_builder_only_end_ns @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_doctype_public @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_dump_attribute_order @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_entity @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_file_init @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_html_empty_elems_serialization @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_indent @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_indent_level @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_indent_space @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_indent_space_caching @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_initialize_parser_without_target @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_interface @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_issue18347 @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_iterparse @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_makeelement @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_methods @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_namespace @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_parsefile @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_parseliteral @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_path_cache @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_processinginstruction @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_qname @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_set_attribute @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_tostring_default_namespace @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_tostring_default_namespace_different_namespace @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_tostring_default_namespace_original_no_namespace @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_tostring_no_xml_declaration @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_tostring_xml_declaration @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_tostring_xml_declaration_cases @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_tostring_xml_declaration_unicode_encoding @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_tostringlist_default_namespace @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_tostringlist_xml_declaration @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_tree_write_attribute_order @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_writefile @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_writestring @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTest.test_xpath_tokenizer @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTypeTest.test_Element_subclass_constructor @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTypeTest.test_Element_subclass_find @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTypeTest.test_Element_subclass_new_method @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTypeTest.test_Element_subclass_trivial @ linux-x86_64 +test.test_xml_etree_c.ElementTreeTypeTest.test_istype @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_read_from_bytesio @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_read_from_stringio @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_read_from_user_binary_reader @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_read_from_user_text_reader @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_short_empty_elements @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_tostringlist_invariant @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_write_to_binary_file @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_write_to_binary_file_with_encoding @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_write_to_bytesio @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_write_to_filename @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_write_to_filename_as_unicode @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_write_to_filename_with_encoding @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_write_to_stringio @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_write_to_text_file @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_write_to_user_binary_writer @ linux-x86_64 +test.test_xml_etree_c.IOTest.test_write_to_user_text_writer @ linux-x86_64 +test.test_xml_etree_c.KeywordArgsTest.test_issue14818 @ linux-x86_64 +test.test_xml_etree_c.ModuleTest.test_all @ linux-x86_64 +test.test_xml_etree_c.ModuleTest.test_sanity @ linux-x86_64 +test.test_xml_etree_c.NamespaceParseTest.test_find_with_namespace @ linux-x86_64 +test.test_xml_etree_c.NoAcceleratorTest.test_correct_import_pyET @ linux-x86_64 +test.test_xml_etree_c.ParseErrorTest.test_error_code @ linux-x86_64 +test.test_xml_etree_c.ParseErrorTest.test_error_position @ linux-x86_64 +test.test_xml_etree_c.ParseErrorTest.test_subclass @ linux-x86_64 +test.test_xml_etree_c.TreeBuilderTest.test_builder_lookup_errors @ linux-x86_64 +test.test_xml_etree_c.TreeBuilderTest.test_doctype @ linux-x86_64 +test.test_xml_etree_c.TreeBuilderTest.test_dummy_builder @ linux-x86_64 +test.test_xml_etree_c.TreeBuilderTest.test_element_factory @ linux-x86_64 +test.test_xml_etree_c.TreeBuilderTest.test_element_factory_pure_python_subclass @ linux-x86_64 +test.test_xml_etree_c.TreeBuilderTest.test_element_factory_subclass @ linux-x86_64 +test.test_xml_etree_c.TreeBuilderTest.test_late_tail @ linux-x86_64 +test.test_xml_etree_c.TreeBuilderTest.test_late_tail_mix_pi_comments @ linux-x86_64 +test.test_xml_etree_c.TreeBuilderTest.test_subclass @ linux-x86_64 +test.test_xml_etree_c.TreeBuilderTest.test_subclass_comment_pi @ linux-x86_64 +test.test_xml_etree_c.TreeBuilderTest.test_treebuilder_comment @ linux-x86_64 +test.test_xml_etree_c.TreeBuilderTest.test_treebuilder_elementfactory_none @ linux-x86_64 +test.test_xml_etree_c.TreeBuilderTest.test_treebuilder_pi @ linux-x86_64 +test.test_xml_etree_c.XIncludeTest.test_xinclude @ linux-x86_64 +test.test_xml_etree_c.XIncludeTest.test_xinclude_default @ linux-x86_64 +test.test_xml_etree_c.XIncludeTest.test_xinclude_failures @ linux-x86_64 +test.test_xml_etree_c.XIncludeTest.test_xinclude_repeated @ linux-x86_64 +test.test_xml_etree_c.XMLParserTest.test_constructor_args @ linux-x86_64 +test.test_xml_etree_c.XMLParserTest.test_doctype_warning @ linux-x86_64 +test.test_xml_etree_c.XMLParserTest.test_inherited_doctype @ linux-x86_64 +test.test_xml_etree_c.XMLParserTest.test_parse_string @ linux-x86_64 +test.test_xml_etree_c.XMLParserTest.test_subclass @ linux-x86_64 +test.test_xml_etree_c.XMLParserTest.test_subclass_doctype @ linux-x86_64 +test.test_xml_etree_c.XMLPullParserTest.test_events @ linux-x86_64 +test.test_xml_etree_c.XMLPullParserTest.test_events_comment @ linux-x86_64 +test.test_xml_etree_c.XMLPullParserTest.test_events_pi @ linux-x86_64 +test.test_xml_etree_c.XMLPullParserTest.test_events_sequence @ linux-x86_64 +test.test_xml_etree_c.XMLPullParserTest.test_feed_while_iterating @ linux-x86_64 +test.test_xml_etree_c.XMLPullParserTest.test_ns_events @ linux-x86_64 +test.test_xml_etree_c.XMLPullParserTest.test_ns_events_start @ linux-x86_64 +test.test_xml_etree_c.XMLPullParserTest.test_ns_events_start_end @ linux-x86_64 +test.test_xml_etree_c.XMLPullParserTest.test_simple_xml @ linux-x86_64 +test.test_xml_etree_c.XMLPullParserTest.test_simple_xml_with_ns @ linux-x86_64 +test.test_xml_etree_c.XMLPullParserTest.test_unknown_event @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_xmlrpc.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_xmlrpc.txt new file mode 100644 index 0000000000..f9b3ea5fa4 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_xmlrpc.txt @@ -0,0 +1,92 @@ +test.test_xmlrpc.BinaryTestCase.test_decode @ linux-x86_64 +test.test_xmlrpc.BinaryTestCase.test_default @ linux-x86_64 +test.test_xmlrpc.BinaryTestCase.test_string @ linux-x86_64 +test.test_xmlrpc.CGIHandlerTestCase.test_cgi_get @ linux-x86_64 +test.test_xmlrpc.CGIHandlerTestCase.test_cgi_xmlrpc_response @ linux-x86_64 +test.test_xmlrpc.DateTimeTestCase.test_comparison @ linux-x86_64 +test.test_xmlrpc.DateTimeTestCase.test_datetime_datetime @ linux-x86_64 +test.test_xmlrpc.DateTimeTestCase.test_decode @ linux-x86_64 +test.test_xmlrpc.DateTimeTestCase.test_default @ linux-x86_64 +test.test_xmlrpc.DateTimeTestCase.test_repr @ linux-x86_64 +test.test_xmlrpc.DateTimeTestCase.test_time @ linux-x86_64 +test.test_xmlrpc.DateTimeTestCase.test_time_struct @ linux-x86_64 +test.test_xmlrpc.DateTimeTestCase.test_time_tuple @ linux-x86_64 +test.test_xmlrpc.FailingServerTestCase.test_basic @ linux-x86_64 +test.test_xmlrpc.FailingServerTestCase.test_fail_no_info @ linux-x86_64 +test.test_xmlrpc.FailingServerTestCase.test_fail_with_info @ linux-x86_64 +test.test_xmlrpc.FaultTestCase.test_dotted_attribute @ linux-x86_64 +test.test_xmlrpc.FaultTestCase.test_dump_fault @ linux-x86_64 +test.test_xmlrpc.FaultTestCase.test_repr @ linux-x86_64 +test.test_xmlrpc.GzipServerTestCase.test_bad_gzip_request @ linux-x86_64 +test.test_xmlrpc.GzipServerTestCase.test_gzip_request @ linux-x86_64 +test.test_xmlrpc.GzipServerTestCase.test_gzip_response @ linux-x86_64 +test.test_xmlrpc.GzipUtilTestCase.test_gzip_decode_limit @ linux-x86_64 +test.test_xmlrpc.HeadersServerTestCase.test_header @ linux-x86_64 +test.test_xmlrpc.HeadersServerTestCase.test_header_empty @ linux-x86_64 +test.test_xmlrpc.HeadersServerTestCase.test_header_items @ linux-x86_64 +test.test_xmlrpc.HeadersServerTestCase.test_header_many @ linux-x86_64 +test.test_xmlrpc.HelperTestCase.test_escape @ linux-x86_64 +test.test_xmlrpc.KeepaliveServerTestCase1.test_two @ linux-x86_64 +test.test_xmlrpc.KeepaliveServerTestCase2.test_close @ linux-x86_64 +test.test_xmlrpc.KeepaliveServerTestCase2.test_transport @ linux-x86_64 +test.test_xmlrpc.MultiPathServerTestCase.test_empty_path @ linux-x86_64 +test.test_xmlrpc.MultiPathServerTestCase.test_empty_path_fragment @ linux-x86_64 +test.test_xmlrpc.MultiPathServerTestCase.test_empty_path_query @ linux-x86_64 +test.test_xmlrpc.MultiPathServerTestCase.test_invalid_path @ linux-x86_64 +test.test_xmlrpc.MultiPathServerTestCase.test_path1 @ linux-x86_64 +test.test_xmlrpc.MultiPathServerTestCase.test_path2 @ linux-x86_64 +test.test_xmlrpc.MultiPathServerTestCase.test_path3 @ linux-x86_64 +test.test_xmlrpc.MultiPathServerTestCase.test_path_fragment @ linux-x86_64 +test.test_xmlrpc.MultiPathServerTestCase.test_path_query @ linux-x86_64 +test.test_xmlrpc.MultiPathServerTestCase.test_path_query_fragment @ linux-x86_64 +test.test_xmlrpc.MultiPathServerTestCase.test_root_path @ linux-x86_64 +test.test_xmlrpc.ServerProxyTestCase.test_close @ linux-x86_64 +test.test_xmlrpc.ServerProxyTestCase.test_transport @ linux-x86_64 +test.test_xmlrpc.SimpleServerEncodingTestCase.test_server_encoding @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_404 @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_allow_dotted_names_true @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_client_encoding @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_context_manager @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_context_manager_method_error @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_dotted_attribute @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_introspection1 @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_introspection2 @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_introspection3 @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_introspection4 @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_multicall @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_non_existing_multicall @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_nonascii @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_nonascii_methodname @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_partial_post @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_simple1 @ linux-x86_64 +test.test_xmlrpc.SimpleServerTestCase.test_unicode_host @ linux-x86_64 +test.test_xmlrpc.SimpleXMLRPCDispatcherTestCase.test_call_dispatch_func @ linux-x86_64 +test.test_xmlrpc.SimpleXMLRPCDispatcherTestCase.test_call_instance_func @ linux-x86_64 +test.test_xmlrpc.SimpleXMLRPCDispatcherTestCase.test_call_registered_func @ linux-x86_64 +test.test_xmlrpc.SimpleXMLRPCDispatcherTestCase.test_cannot_locate_func @ linux-x86_64 +test.test_xmlrpc.SimpleXMLRPCDispatcherTestCase.test_instance_has_no_func @ linux-x86_64 +test.test_xmlrpc.SimpleXMLRPCDispatcherTestCase.test_registered_func_is_none @ linux-x86_64 +test.test_xmlrpc.UseBuiltinTypesTestCase.test_cgihandler_has_use_builtin_types_flag @ linux-x86_64 +test.test_xmlrpc.UseBuiltinTypesTestCase.test_use_builtin_types @ linux-x86_64 +test.test_xmlrpc.UseBuiltinTypesTestCase.test_xmlrpcserver_has_use_builtin_types_flag @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_bug_1164912 @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_datetime_before_1900 @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_dump_bad_dict @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_dump_bare_datetime @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_dump_big_int @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_dump_big_long @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_dump_bytes @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_dump_double @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_dump_encoding @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_dump_load @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_dump_none @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_dump_recursive_dict @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_dump_recursive_seq @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_get_host_info @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_keepalive_disconnect @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_limit_int @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_load_extension_types @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_load_standard_types @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_loads_unsupported @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_newstyle_class @ linux-x86_64 +test.test_xmlrpc.XMLRPCTestCase.test_ssl_presence @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_yield_from.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_yield_from.txt new file mode 100644 index 0000000000..fd317e5e31 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_yield_from.txt @@ -0,0 +1,32 @@ +test.test_yield_from.TestPEP380Operation.test_attempted_yield_from_loop @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_attempting_to_send_to_non_generator @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_broken_getattr_handling @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_catching_exception_from_subgen_and_returning @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_close_with_cleared_frame @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_conversion_of_sendNone_to_next @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_delegating_close @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_delegating_generators_claim_to_be_running @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_delegating_throw @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_delegating_throw_to_non_generator @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_delegation_of_close_to_non_generator @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_delegation_of_initial_next_to_subgenerator @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_delegation_of_next_call_to_subgenerator @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_delegation_of_next_to_non_generator @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_delegation_of_send @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_delegator_is_visible_to_debugger @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_exception_in_initial_next_call @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_exception_value_crash @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_generator_return_value @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_handing_exception_while_delegating_close @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_handling_exception_while_delegating_send @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_next_and_return_with_value @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_raising_exception_in_delegated_next_call @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_raising_exception_in_initial_next_call @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_returning_value_from_delegated_throw @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_send_and_return_with_value @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_send_tuple_with_custom_generator @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_throwing_GeneratorExit_into_subgen_that_raises @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_throwing_GeneratorExit_into_subgen_that_returns @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_throwing_GeneratorExit_into_subgenerator_that_yields @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_value_attribute_of_StopIteration_exception @ linux-x86_64 +test.test_yield_from.TestPEP380Operation.test_yield_from_empty @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zipapp.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zipapp.txt new file mode 100644 index 0000000000..457627136f --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zipapp.txt @@ -0,0 +1,31 @@ +test.test_zipapp.ZipAppCmdlineTest.test_cmdline_copy @ linux-x86_64 +test.test_zipapp.ZipAppCmdlineTest.test_cmdline_copy_change_main @ linux-x86_64 +test.test_zipapp.ZipAppCmdlineTest.test_cmdline_copy_inplace @ linux-x86_64 +test.test_zipapp.ZipAppCmdlineTest.test_cmdline_create @ linux-x86_64 +test.test_zipapp.ZipAppCmdlineTest.test_info_command @ linux-x86_64 +test.test_zipapp.ZipAppCmdlineTest.test_info_error @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_content_of_copied_archive @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_create_archive @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_create_archive_default_target @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_create_archive_filter_exclude_dir @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_create_archive_with_compression @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_create_archive_with_filter @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_create_archive_with_pathlib @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_create_archive_with_subdirs @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_custom_interpreter @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_default_no_shebang @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_main_and_main_py @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_main_only_written_once @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_main_validation @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_main_written @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_modify_shebang @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_no_main @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_no_shebang_is_not_executable @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_pack_to_fileobj @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_read_from_fileobj @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_read_from_pathobj @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_read_missing_shebang @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_read_shebang @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_remove_shebang @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_shebang_is_executable @ linux-x86_64 +test.test_zipapp.ZipAppTest.test_write_shebang_to_fileobj @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zipfile.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zipfile.txt new file mode 100644 index 0000000000..0b07ed155f --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zipfile.txt @@ -0,0 +1,280 @@ +test.test_zipfile.Bzip2BadCrcTests.test_read_with_bad_crc @ linux-x86_64 +test.test_zipfile.Bzip2BadCrcTests.test_testzip_with_bad_crc @ linux-x86_64 +test.test_zipfile.Bzip2TestZip64InSmallFiles.test_basic @ linux-x86_64 +test.test_zipfile.Bzip2TestZip64InSmallFiles.test_too_many_files @ linux-x86_64 +test.test_zipfile.Bzip2TestZip64InSmallFiles.test_too_many_files_append @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithRandomBinaryFiles.test_open @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithRandomBinaryFiles.test_random_open @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithRandomBinaryFiles.test_read @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_basic @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_compresslevel_basic @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_iterlines @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_low_compression @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_open @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_open_with_pathlike @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_per_file_compresslevel @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_random_open @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_read1 @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_read1_10 @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_read_return_size @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_readline @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_readline_read @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_readlines @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_repr @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_truncated_zipfile @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_writestr_compression @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_writestr_compresslevel @ linux-x86_64 +test.test_zipfile.Bzip2TestsWithSourceFile.test_writing_errors @ linux-x86_64 +test.test_zipfile.Bzip2WriterTests.test_close_after_close @ linux-x86_64 +test.test_zipfile.Bzip2WriterTests.test_issue44439 @ linux-x86_64 +test.test_zipfile.Bzip2WriterTests.test_write_after_close @ linux-x86_64 +test.test_zipfile.CommandLineTest.test_bad_use @ linux-x86_64 +test.test_zipfile.CommandLineTest.test_create_command @ linux-x86_64 +test.test_zipfile.CommandLineTest.test_extract_command @ linux-x86_64 +test.test_zipfile.CommandLineTest.test_list_command @ linux-x86_64 +test.test_zipfile.CommandLineTest.test_test_command @ linux-x86_64 +test.test_zipfile.DecryptionTests.test_bad_password @ linux-x86_64 +test.test_zipfile.DecryptionTests.test_good_password @ linux-x86_64 +test.test_zipfile.DecryptionTests.test_no_password @ linux-x86_64 +test.test_zipfile.DecryptionTests.test_seek_tell @ linux-x86_64 +test.test_zipfile.DecryptionTests.test_unicode_password @ linux-x86_64 +test.test_zipfile.DeflateBadCrcTests.test_read_with_bad_crc @ linux-x86_64 +test.test_zipfile.DeflateBadCrcTests.test_testzip_with_bad_crc @ linux-x86_64 +test.test_zipfile.DeflateTestZip64InSmallFiles.test_basic @ linux-x86_64 +test.test_zipfile.DeflateTestZip64InSmallFiles.test_too_many_files @ linux-x86_64 +test.test_zipfile.DeflateTestZip64InSmallFiles.test_too_many_files_append @ linux-x86_64 +test.test_zipfile.DeflateTestsWithRandomBinaryFiles.test_open @ linux-x86_64 +test.test_zipfile.DeflateTestsWithRandomBinaryFiles.test_random_open @ linux-x86_64 +test.test_zipfile.DeflateTestsWithRandomBinaryFiles.test_read @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_basic @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_compresslevel_basic @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_iterlines @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_low_compression @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_open @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_open_with_pathlike @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_per_file_compression @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_per_file_compresslevel @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_random_open @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_read1 @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_read1_10 @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_read_return_size @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_readline @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_readline_read @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_readlines @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_repr @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_truncated_zipfile @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_writestr_compression @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_writestr_compresslevel @ linux-x86_64 +test.test_zipfile.DeflateTestsWithSourceFile.test_writing_errors @ linux-x86_64 +test.test_zipfile.DeflateWriterTests.test_close_after_close @ linux-x86_64 +test.test_zipfile.DeflateWriterTests.test_issue44439 @ linux-x86_64 +test.test_zipfile.DeflateWriterTests.test_write_after_close @ linux-x86_64 +test.test_zipfile.EncodedMetadataTests.test_cli_with_metadata_encoding @ linux-x86_64 +test.test_zipfile.EncodedMetadataTests.test_cli_with_metadata_encoding_extract @ linux-x86_64 +test.test_zipfile.EncodedMetadataTests.test_read_after_append @ linux-x86_64 +test.test_zipfile.EncodedMetadataTests.test_read_with_incorrect_metadata_encoding @ linux-x86_64 +test.test_zipfile.EncodedMetadataTests.test_read_with_metadata_encoding @ linux-x86_64 +test.test_zipfile.EncodedMetadataTests.test_read_with_unsuitable_metadata_encoding @ linux-x86_64 +test.test_zipfile.EncodedMetadataTests.test_read_without_metadata_encoding @ linux-x86_64 +test.test_zipfile.EncodedMetadataTests.test_write_with_metadata_encoding @ linux-x86_64 +test.test_zipfile.ExtractTests.test_extract @ linux-x86_64 +test.test_zipfile.ExtractTests.test_extract_all @ linux-x86_64 +test.test_zipfile.ExtractTests.test_extract_all_with_target @ linux-x86_64 +test.test_zipfile.ExtractTests.test_extract_all_with_target_pathlike @ linux-x86_64 +test.test_zipfile.ExtractTests.test_extract_hackers_arcnames_common_cases @ linux-x86_64 +test.test_zipfile.ExtractTests.test_extract_hackers_arcnames_posix_only @ linux-x86_64 +test.test_zipfile.ExtractTests.test_extract_with_target @ linux-x86_64 +test.test_zipfile.ExtractTests.test_extract_with_target_pathlike @ linux-x86_64 +test.test_zipfile.ExtractTests.test_sanitize_windows_name @ linux-x86_64 +test.test_zipfile.LzmaBadCrcTests.test_read_with_bad_crc @ linux-x86_64 +test.test_zipfile.LzmaBadCrcTests.test_testzip_with_bad_crc @ linux-x86_64 +test.test_zipfile.LzmaTestZip64InSmallFiles.test_basic @ linux-x86_64 +test.test_zipfile.LzmaTestZip64InSmallFiles.test_too_many_files @ linux-x86_64 +test.test_zipfile.LzmaTestZip64InSmallFiles.test_too_many_files_append @ linux-x86_64 +test.test_zipfile.LzmaTestsWithRandomBinaryFiles.test_open @ linux-x86_64 +test.test_zipfile.LzmaTestsWithRandomBinaryFiles.test_random_open @ linux-x86_64 +test.test_zipfile.LzmaTestsWithRandomBinaryFiles.test_read @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_basic @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_compresslevel_basic @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_iterlines @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_low_compression @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_open @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_open_with_pathlike @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_per_file_compresslevel @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_random_open @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_read1 @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_read1_10 @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_read_return_size @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_readline @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_readline_read @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_readlines @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_repr @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_truncated_zipfile @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_writestr_compression @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_writestr_compresslevel @ linux-x86_64 +test.test_zipfile.LzmaTestsWithSourceFile.test_writing_errors @ linux-x86_64 +test.test_zipfile.LzmaWriterTests.test_close_after_close @ linux-x86_64 +test.test_zipfile.LzmaWriterTests.test_issue44439 @ linux-x86_64 +test.test_zipfile.LzmaWriterTests.test_write_after_close @ linux-x86_64 +test.test_zipfile.OtherTests.test_bad_compression_mode @ linux-x86_64 +test.test_zipfile.OtherTests.test_bad_constructor_mode @ linux-x86_64 +test.test_zipfile.OtherTests.test_bad_open_mode @ linux-x86_64 +test.test_zipfile.OtherTests.test_change_comment_in_empty_archive @ linux-x86_64 +test.test_zipfile.OtherTests.test_change_comment_in_nonempty_archive @ linux-x86_64 +test.test_zipfile.OtherTests.test_close @ linux-x86_64 +test.test_zipfile.OtherTests.test_close_erroneous_file @ linux-x86_64 +test.test_zipfile.OtherTests.test_close_on_exception @ linux-x86_64 +test.test_zipfile.OtherTests.test_closed_zip_raises_ValueError @ linux-x86_64 +test.test_zipfile.OtherTests.test_comments @ linux-x86_64 +test.test_zipfile.OtherTests.test_create_empty_zipinfo_default_attributes @ linux-x86_64 +test.test_zipfile.OtherTests.test_create_empty_zipinfo_repr @ linux-x86_64 +test.test_zipfile.OtherTests.test_create_non_existent_file_for_append @ linux-x86_64 +test.test_zipfile.OtherTests.test_create_zipinfo_before_1980 @ linux-x86_64 +test.test_zipfile.OtherTests.test_damaged_zipfile @ linux-x86_64 +test.test_zipfile.OtherTests.test_decompress_without_3rd_party_library @ linux-x86_64 +test.test_zipfile.OtherTests.test_empty_file_raises_BadZipFile @ linux-x86_64 +test.test_zipfile.OtherTests.test_empty_zipfile @ linux-x86_64 +test.test_zipfile.OtherTests.test_exclusive_create_zip_file @ linux-x86_64 +test.test_zipfile.OtherTests.test_is_zip_erroneous_file @ linux-x86_64 +test.test_zipfile.OtherTests.test_is_zip_valid_file @ linux-x86_64 +test.test_zipfile.OtherTests.test_negative_central_directory_offset_raises_BadZipFile @ linux-x86_64 +test.test_zipfile.OtherTests.test_non_existent_file_raises_OSError @ linux-x86_64 +test.test_zipfile.OtherTests.test_null_byte_in_filename @ linux-x86_64 +test.test_zipfile.OtherTests.test_open_conflicting_handles @ linux-x86_64 +test.test_zipfile.OtherTests.test_open_empty_file @ linux-x86_64 +test.test_zipfile.OtherTests.test_open_non_existent_item @ linux-x86_64 +test.test_zipfile.OtherTests.test_open_via_zip_info @ linux-x86_64 +test.test_zipfile.OtherTests.test_read0 @ linux-x86_64 +test.test_zipfile.OtherTests.test_read_after_write_unicode_filenames @ linux-x86_64 +test.test_zipfile.OtherTests.test_read_unicode_filenames @ linux-x86_64 +test.test_zipfile.OtherTests.test_seek_tell @ linux-x86_64 +test.test_zipfile.OtherTests.test_struct_sizes @ linux-x86_64 +test.test_zipfile.OtherTests.test_unicode_comment @ linux-x86_64 +test.test_zipfile.OtherTests.test_unsupported_compression @ linux-x86_64 +test.test_zipfile.OtherTests.test_unsupported_version @ linux-x86_64 +test.test_zipfile.OtherTests.test_write_unicode_filenames @ linux-x86_64 +test.test_zipfile.OtherTests.test_writestr_extended_local_header_issue1202 @ linux-x86_64 +test.test_zipfile.OtherTests.test_zipfile_with_short_extra_field @ linux-x86_64 +test.test_zipfile.PyZipFileTests.test_write_non_pyfile @ linux-x86_64 +test.test_zipfile.PyZipFileTests.test_write_pathlike @ linux-x86_64 +test.test_zipfile.PyZipFileTests.test_write_pyfile @ linux-x86_64 +test.test_zipfile.PyZipFileTests.test_write_pyfile_bad_syntax @ linux-x86_64 +test.test_zipfile.PyZipFileTests.test_write_python_directory @ linux-x86_64 +test.test_zipfile.PyZipFileTests.test_write_python_directory_filtered @ linux-x86_64 +test.test_zipfile.PyZipFileTests.test_write_python_package @ linux-x86_64 +test.test_zipfile.PyZipFileTests.test_write_with_optimization @ linux-x86_64 +test.test_zipfile.StoredBadCrcTests.test_read_with_bad_crc @ linux-x86_64 +test.test_zipfile.StoredBadCrcTests.test_testzip_with_bad_crc @ linux-x86_64 +test.test_zipfile.StoredTestZip64InSmallFiles.test_absolute_arcnames @ linux-x86_64 +test.test_zipfile.StoredTestZip64InSmallFiles.test_append @ linux-x86_64 +test.test_zipfile.StoredTestZip64InSmallFiles.test_bad_zip64_extra @ linux-x86_64 +test.test_zipfile.StoredTestZip64InSmallFiles.test_basic @ linux-x86_64 +test.test_zipfile.StoredTestZip64InSmallFiles.test_force_zip64 @ linux-x86_64 +test.test_zipfile.StoredTestZip64InSmallFiles.test_generated_valid_zip64_extra @ linux-x86_64 +test.test_zipfile.StoredTestZip64InSmallFiles.test_large_file_exception @ linux-x86_64 +test.test_zipfile.StoredTestZip64InSmallFiles.test_too_many_files @ linux-x86_64 +test.test_zipfile.StoredTestZip64InSmallFiles.test_too_many_files_append @ linux-x86_64 +test.test_zipfile.StoredTestZip64InSmallFiles.test_unseekable_zip_known_filesize @ linux-x86_64 +test.test_zipfile.StoredTestZip64InSmallFiles.test_unseekable_zip_unknown_filesize @ linux-x86_64 +test.test_zipfile.StoredTestZip64InSmallFiles.test_zip64_required_not_allowed_fail @ linux-x86_64 +test.test_zipfile.StoredTestsWithRandomBinaryFiles.test_open @ linux-x86_64 +test.test_zipfile.StoredTestsWithRandomBinaryFiles.test_random_open @ linux-x86_64 +test.test_zipfile.StoredTestsWithRandomBinaryFiles.test_read @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_absolute_arcnames @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_add_file_before_1980 @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_append_to_concatenated_zip_file @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_append_to_non_zip_file @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_append_to_zip_file @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_basic @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_compresslevel_basic @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_ignores_newline_at_end @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_ignores_stuff_appended_past_comments @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_io_on_closed_zipextfile @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_iterlines @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_open @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_open_with_pathlike @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_per_file_compresslevel @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_random_open @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_read1 @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_read1_10 @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_read_concatenated_zip_file @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_read_return_size @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_readline @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_readline_read @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_readlines @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_repr @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_truncated_zipfile @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_write_default_name @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_write_to_readonly @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_writestr_compression @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_writestr_compresslevel @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_writestr_permissions @ linux-x86_64 +test.test_zipfile.StoredTestsWithSourceFile.test_writing_errors @ linux-x86_64 +test.test_zipfile.StoredWriterTests.test_close_after_close @ linux-x86_64 +test.test_zipfile.StoredWriterTests.test_issue44439 @ linux-x86_64 +test.test_zipfile.StoredWriterTests.test_write_after_close @ linux-x86_64 +test.test_zipfile.StripExtraTests.test_multiples @ linux-x86_64 +test.test_zipfile.StripExtraTests.test_no_data @ linux-x86_64 +test.test_zipfile.StripExtraTests.test_too_short @ linux-x86_64 +test.test_zipfile.StripExtraTests.test_with_data @ linux-x86_64 +test.test_zipfile.TestExecutablePrependedZip.test_read_zip64_with_exe_prepended @ linux-x86_64 +test.test_zipfile.TestExecutablePrependedZip.test_read_zip_with_exe_prepended @ linux-x86_64 +test.test_zipfile.TestPath.test_dir_parent @ linux-x86_64 +test.test_zipfile.TestPath.test_encoding_warnings @ linux-x86_64 +test.test_zipfile.TestPath.test_extract_orig_with_implied_dirs @ linux-x86_64 +test.test_zipfile.TestPath.test_filename @ linux-x86_64 +test.test_zipfile.TestPath.test_implied_dirs_performance @ linux-x86_64 +test.test_zipfile.TestPath.test_inheritance @ linux-x86_64 +test.test_zipfile.TestPath.test_is_file_missing @ linux-x86_64 +test.test_zipfile.TestPath.test_iterdir_and_types @ linux-x86_64 +test.test_zipfile.TestPath.test_iterdir_on_file @ linux-x86_64 +test.test_zipfile.TestPath.test_joinpath @ linux-x86_64 +test.test_zipfile.TestPath.test_joinpath_constant_time @ linux-x86_64 +test.test_zipfile.TestPath.test_joinpath_multiple @ linux-x86_64 +test.test_zipfile.TestPath.test_missing_dir_parent @ linux-x86_64 +test.test_zipfile.TestPath.test_mutability @ linux-x86_64 +test.test_zipfile.TestPath.test_open @ linux-x86_64 +test.test_zipfile.TestPath.test_open_binary_invalid_args @ linux-x86_64 +test.test_zipfile.TestPath.test_open_encoding_errors @ linux-x86_64 +test.test_zipfile.TestPath.test_open_encoding_utf16 @ linux-x86_64 +test.test_zipfile.TestPath.test_open_extant_directory @ linux-x86_64 +test.test_zipfile.TestPath.test_open_missing_directory @ linux-x86_64 +test.test_zipfile.TestPath.test_open_write @ linux-x86_64 +test.test_zipfile.TestPath.test_parent @ linux-x86_64 +test.test_zipfile.TestPath.test_pathlike_construction @ linux-x86_64 +test.test_zipfile.TestPath.test_read @ linux-x86_64 +test.test_zipfile.TestPath.test_read_does_not_close @ linux-x86_64 +test.test_zipfile.TestPath.test_root_name @ linux-x86_64 +test.test_zipfile.TestPath.test_root_parent @ linux-x86_64 +test.test_zipfile.TestPath.test_root_unnamed @ linux-x86_64 +test.test_zipfile.TestPath.test_stem @ linux-x86_64 +test.test_zipfile.TestPath.test_subclass @ linux-x86_64 +test.test_zipfile.TestPath.test_subdir_is_dir @ linux-x86_64 +test.test_zipfile.TestPath.test_suffix @ linux-x86_64 +test.test_zipfile.TestPath.test_suffix_no_filename @ linux-x86_64 +test.test_zipfile.TestPath.test_suffixes @ linux-x86_64 +test.test_zipfile.TestPath.test_traverse_pathlike @ linux-x86_64 +test.test_zipfile.TestPath.test_traverse_simplediv @ linux-x86_64 +test.test_zipfile.TestPath.test_traverse_truediv @ linux-x86_64 +test.test_zipfile.TestWithDirectory.test_bug_6050 @ linux-x86_64 +test.test_zipfile.TestWithDirectory.test_create_directory_with_write @ linux-x86_64 +test.test_zipfile.TestWithDirectory.test_extract_dir @ linux-x86_64 +test.test_zipfile.TestWithDirectory.test_mkdir @ linux-x86_64 +test.test_zipfile.TestWithDirectory.test_write_dir @ linux-x86_64 +test.test_zipfile.TestWithDirectory.test_writestr_dir @ linux-x86_64 +test.test_zipfile.TestsWithMultipleOpens.test_different_file @ linux-x86_64 +test.test_zipfile.TestsWithMultipleOpens.test_interleaved @ linux-x86_64 +!test.test_zipfile.TestsWithMultipleOpens.test_many_opens @ linux-x86_64 +test.test_zipfile.TestsWithMultipleOpens.test_read_after_close @ linux-x86_64 +test.test_zipfile.TestsWithMultipleOpens.test_read_after_write @ linux-x86_64 +test.test_zipfile.TestsWithMultipleOpens.test_same_file @ linux-x86_64 +test.test_zipfile.TestsWithMultipleOpens.test_write_after_read @ linux-x86_64 +test.test_zipfile.TestsWithMultipleOpens.test_write_while_reading @ linux-x86_64 +test.test_zipfile.UnseekableTests.test_open_write @ linux-x86_64 +test.test_zipfile.UnseekableTests.test_write @ linux-x86_64 +test.test_zipfile.UnseekableTests.test_writestr @ linux-x86_64 +test.test_zipfile.ZipInfoTests.test_from_dir @ linux-x86_64 +test.test_zipfile.ZipInfoTests.test_from_file @ linux-x86_64 +test.test_zipfile.ZipInfoTests.test_from_file_bytes @ linux-x86_64 +test.test_zipfile.ZipInfoTests.test_from_file_fileno @ linux-x86_64 +test.test_zipfile.ZipInfoTests.test_from_file_pathlike @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zipfile64.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zipfile64.txt new file mode 100644 index 0000000000..d72ab1bdab --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zipfile64.txt @@ -0,0 +1,3 @@ +test.test_zipfile64.OtherTests.testMoreThan64kFiles @ linux-x86_64 +test.test_zipfile64.OtherTests.testMoreThan64kFilesAppend @ linux-x86_64 +test.test_zipfile64.TestsWithSourceFile.testDeflated @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zipimport.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zipimport.txt new file mode 100644 index 0000000000..7e6f56ffc9 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zipimport.txt @@ -0,0 +1,71 @@ +test.test_zipimport.BadFileZipImportTestCase.testBadArgs @ linux-x86_64 +test.test_zipimport.BadFileZipImportTestCase.testEmptyFile @ linux-x86_64 +test.test_zipimport.BadFileZipImportTestCase.testEmptyFilename @ linux-x86_64 +test.test_zipimport.BadFileZipImportTestCase.testFileUnreadable @ linux-x86_64 +test.test_zipimport.BadFileZipImportTestCase.testFilenameTooLong @ linux-x86_64 +test.test_zipimport.BadFileZipImportTestCase.testNoFile @ linux-x86_64 +test.test_zipimport.BadFileZipImportTestCase.testNotZipFile @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.test2038MTime @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testBadMTime @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testBadMagic @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testBadMagic2 @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testBeginningCruftAndComment @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testBoth @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testBytesPath @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testComment @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testDefaultOptimizationLevel @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testDoctestFile @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testDoctestSuite @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testEmptyPy @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testGetCompiledSource @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testGetData @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testGetSource @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testImport_WithStuff @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testImporterAttr @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testInvalidateCaches @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testLargestPossibleComment @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testMixedNamespacePackage @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testNamespacePackage @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testPackage @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testPy @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testPyc @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testSubNamespacePackage @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testSubPackage @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testTraceback @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testUncheckedHashBasedPyc @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testUnencodable @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testZipImporterMethods @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.testZipImporterMethodsInSubDirectory @ linux-x86_64 +test.test_zipimport.CompressedZipImportTestCase.test_checked_hash_based_change_pyc @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.test2038MTime @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testBadMTime @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testBadMagic @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testBadMagic2 @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testBeginningCruftAndComment @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testBoth @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testBytesPath @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testComment @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testDefaultOptimizationLevel @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testDoctestFile @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testDoctestSuite @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testEmptyPy @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testGetCompiledSource @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testGetData @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testGetSource @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testImport_WithStuff @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testImporterAttr @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testInvalidateCaches @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testLargestPossibleComment @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testMixedNamespacePackage @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testNamespacePackage @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testPackage @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testPy @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testPyc @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testSubNamespacePackage @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testSubPackage @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testTraceback @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testUncheckedHashBasedPyc @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testUnencodable @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testZipImporterMethods @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.testZipImporterMethodsInSubDirectory @ linux-x86_64 +test.test_zipimport.UncompressedZipImportTestCase.test_checked_hash_based_change_pyc @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zipimport_support.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zipimport_support.txt new file mode 100644 index 0000000000..890269b8d0 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zipimport_support.txt @@ -0,0 +1,3 @@ +test.test_zipimport_support.ZipSupportTests.test_doctest_main_issue4197 @ linux-x86_64 +test.test_zipimport_support.ZipSupportTests.test_inspect_getsource_issue4223 @ linux-x86_64 +test.test_zipimport_support.ZipSupportTests.test_pdb_issue4201 @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zlib.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zlib.txt new file mode 100644 index 0000000000..b3e3f2bba6 --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zlib.txt @@ -0,0 +1,54 @@ +test.test_zlib.ChecksumTestCase.test_adler32empty @ linux-x86_64 +test.test_zlib.ChecksumTestCase.test_adler32start @ linux-x86_64 +test.test_zlib.ChecksumTestCase.test_crc32_adler32_unsigned @ linux-x86_64 +test.test_zlib.ChecksumTestCase.test_crc32empty @ linux-x86_64 +test.test_zlib.ChecksumTestCase.test_crc32start @ linux-x86_64 +test.test_zlib.ChecksumTestCase.test_penguins @ linux-x86_64 +test.test_zlib.ChecksumTestCase.test_same_as_binascii_crc32 @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_badcompresscopy @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_baddecompresscopy @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_big_compress_buffer @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_big_decompress_buffer @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_clear_unconsumed_tail @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_compresscopy @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_compressincremental @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_compressoptions @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_decompimax @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_decompinc @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_decompincflush @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_decompress_eof @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_decompress_eof_incomplete_stream @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_decompress_incomplete_stream @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_decompress_raw_with_dictionary @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_decompress_unused_data @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_decompresscopy @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_decompressmaxlen @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_decompressmaxlenflush @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_dictionary @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_dictionary_streaming @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_empty_flush @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_flush_custom_length @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_flush_large_length @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_flush_with_freed_input @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_flushes @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_keywords @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_maxlen_custom @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_maxlen_large @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_maxlenmisc @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_odd_flush @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_pair @ linux-x86_64 +test.test_zlib.CompressObjectTestCase.test_wbits @ linux-x86_64 +test.test_zlib.CompressTestCase.test_big_compress_buffer @ linux-x86_64 +test.test_zlib.CompressTestCase.test_big_decompress_buffer @ linux-x86_64 +test.test_zlib.CompressTestCase.test_custom_bufsize @ linux-x86_64 +test.test_zlib.CompressTestCase.test_incomplete_stream @ linux-x86_64 +test.test_zlib.CompressTestCase.test_keywords @ linux-x86_64 +test.test_zlib.CompressTestCase.test_large_bufsize @ linux-x86_64 +test.test_zlib.CompressTestCase.test_speech @ linux-x86_64 +test.test_zlib.CompressTestCase.test_speech128 @ linux-x86_64 +test.test_zlib.ExceptionTestCase.test_badargs @ linux-x86_64 +test.test_zlib.ExceptionTestCase.test_badcompressobj @ linux-x86_64 +test.test_zlib.ExceptionTestCase.test_baddecompressobj @ linux-x86_64 +test.test_zlib.ExceptionTestCase.test_badlevel @ linux-x86_64 +test.test_zlib.ExceptionTestCase.test_decompressobj_badflush @ linux-x86_64 +test.test_zlib.VersionTestCase.test_library_version @ linux-x86_64 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zoneinfo.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zoneinfo.txt new file mode 100644 index 0000000000..cb2fcfcfaa --- /dev/null +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_zoneinfo.txt @@ -0,0 +1,184 @@ +test.test_zoneinfo.test_zoneinfo.CCallingConventionTest.test_clear_cache @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CCallingConventionTest.test_from_file @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTZStrTest.test_extreme_tzstr @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTZStrTest.test_invalid_tzstr @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTZStrTest.test_tzstr_from_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTZStrTest.test_tzstr_localized @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTestModule.test_available_timezones @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTestModule.test_available_timezones_weirdzone @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTestModule.test_dir_contains_all @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTestModule.test_dir_unique @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTestModule.test_exclude_posixrules @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTestModule.test_folder_exclusions @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTestModule.test_getattr_error @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTzPathTest.test_env_variable @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTzPathTest.test_env_variable_relative_paths @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTzPathTest.test_reset_tzpath_kwarg @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTzPathTest.test_reset_tzpath_relative_paths @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTzPathTest.test_tzpath_attribute @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CTzPathTest.test_tzpath_type_error @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CWeirdZoneTest.test_empty_zone @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CWeirdZoneTest.test_fixed_offset_phantom_transition @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CWeirdZoneTest.test_no_tz_str @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CWeirdZoneTest.test_one_transition @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CWeirdZoneTest.test_one_zone_dst @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CWeirdZoneTest.test_tz_before_only @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CWeirdZoneTest.test_zone_very_large_timestamp @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoCacheTest.test_cache_reset_tzpath @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoCacheTest.test_clear_cache_explicit_none @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoCacheTest.test_clear_cache_one_key @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoCacheTest.test_clear_cache_two_keys @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoCacheTest.test_ephemeral_zones @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoCacheTest.test_no_cache @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoCacheTest.test_strong_refs @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoDatetimeSubclassTest.test_bad_keys @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoDatetimeSubclassTest.test_bad_keys_paths @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoDatetimeSubclassTest.test_bad_zones @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoDatetimeSubclassTest.test_fold_mutate @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoDatetimeSubclassTest.test_folds_and_gaps @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoDatetimeSubclassTest.test_folds_from_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoDatetimeSubclassTest.test_fromutc_errors @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoDatetimeSubclassTest.test_key_attribute @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoDatetimeSubclassTest.test_repr @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoDatetimeSubclassTest.test_str @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoDatetimeSubclassTest.test_time_fixed_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoDatetimeSubclassTest.test_time_variable_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoDatetimeSubclassTest.test_unambiguous @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoDatetimeSubclassTest.test_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoPickleTest.test_cache_hit @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoPickleTest.test_cache_miss @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoPickleTest.test_from_file @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoPickleTest.test_no_cache @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoPickleTest.test_pickle_after_from_file @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoSubclassTest.test_bad_keys @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoSubclassTest.test_bad_keys_paths @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoSubclassTest.test_bad_zones @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoSubclassTest.test_folds_and_gaps @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoSubclassTest.test_folds_from_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoSubclassTest.test_fromutc_errors @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoSubclassTest.test_key_attribute @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoSubclassTest.test_repr @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoSubclassTest.test_str @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoSubclassTest.test_subclass_own_cache @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoSubclassTest.test_time_fixed_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoSubclassTest.test_time_variable_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoSubclassTest.test_unambiguous @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoSubclassTest.test_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoTest.test_bad_keys @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoTest.test_bad_keys_paths @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoTest.test_bad_zones @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoTest.test_fold_mutate @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoTest.test_folds_and_gaps @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoTest.test_folds_from_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoTest.test_fromutc_errors @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoTest.test_key_attribute @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoTest.test_repr @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoTest.test_str @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoTest.test_time_fixed_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoTest.test_time_variable_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoTest.test_unambiguous @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoTest.test_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoV1Test.test_bad_keys @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoV1Test.test_bad_keys_paths @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoV1Test.test_bad_zones @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoV1Test.test_folds_and_gaps @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoV1Test.test_folds_from_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoV1Test.test_fromutc_errors @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoV1Test.test_key_attribute @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoV1Test.test_repr @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoV1Test.test_str @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoV1Test.test_time_fixed_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoV1Test.test_time_variable_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoV1Test.test_unambiguous @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CZoneInfoV1Test.test_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CallingConventionTest.test_clear_cache @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.CallingConventionTest.test_from_file @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TZStrTest.test_extreme_tzstr @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TZStrTest.test_invalid_tzstr @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TZStrTest.test_tzstr_from_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TZStrTest.test_tzstr_localized @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TestModule.test_available_timezones @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TestModule.test_available_timezones_weirdzone @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TestModule.test_dir_contains_all @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TestModule.test_dir_unique @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TestModule.test_exclude_posixrules @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TestModule.test_folder_exclusions @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TestModule.test_getattr_error @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TzPathTest.test_env_variable @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TzPathTest.test_env_variable_relative_paths @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TzPathTest.test_reset_tzpath_kwarg @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TzPathTest.test_reset_tzpath_relative_paths @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TzPathTest.test_tzpath_attribute @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.TzPathTest.test_tzpath_type_error @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.WeirdZoneTest.test_empty_zone @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.WeirdZoneTest.test_fixed_offset_phantom_transition @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.WeirdZoneTest.test_no_tz_str @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.WeirdZoneTest.test_one_transition @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.WeirdZoneTest.test_one_zone_dst @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.WeirdZoneTest.test_tz_before_only @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.WeirdZoneTest.test_zone_very_large_timestamp @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoCacheTest.test_cache_reset_tzpath @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoCacheTest.test_clear_cache_explicit_none @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoCacheTest.test_clear_cache_one_key @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoCacheTest.test_clear_cache_two_keys @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoCacheTest.test_ephemeral_zones @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoCacheTest.test_no_cache @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoCacheTest.test_strong_refs @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoDatetimeSubclassTest.test_bad_keys @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoDatetimeSubclassTest.test_bad_keys_paths @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoDatetimeSubclassTest.test_bad_zones @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoDatetimeSubclassTest.test_folds_and_gaps @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoDatetimeSubclassTest.test_folds_from_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoDatetimeSubclassTest.test_fromutc_errors @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoDatetimeSubclassTest.test_key_attribute @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoDatetimeSubclassTest.test_repr @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoDatetimeSubclassTest.test_str @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoDatetimeSubclassTest.test_time_fixed_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoDatetimeSubclassTest.test_time_variable_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoDatetimeSubclassTest.test_unambiguous @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoDatetimeSubclassTest.test_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoPickleTest.test_cache_hit @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoPickleTest.test_cache_miss @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoPickleTest.test_from_file @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoPickleTest.test_no_cache @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoPickleTest.test_pickle_after_from_file @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoSubclassTest.test_bad_keys @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoSubclassTest.test_bad_keys_paths @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoSubclassTest.test_bad_zones @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoSubclassTest.test_folds_and_gaps @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoSubclassTest.test_folds_from_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoSubclassTest.test_fromutc_errors @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoSubclassTest.test_key_attribute @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoSubclassTest.test_repr @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoSubclassTest.test_str @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoSubclassTest.test_subclass_own_cache @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoSubclassTest.test_time_fixed_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoSubclassTest.test_time_variable_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoSubclassTest.test_unambiguous @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoSubclassTest.test_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoTest.test_bad_keys @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoTest.test_bad_keys_paths @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoTest.test_bad_zones @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoTest.test_folds_and_gaps @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoTest.test_folds_from_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoTest.test_fromutc_errors @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoTest.test_key_attribute @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoTest.test_repr @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoTest.test_str @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoTest.test_time_fixed_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoTest.test_time_variable_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoTest.test_unambiguous @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoTest.test_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoV1Test.test_bad_keys @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoV1Test.test_bad_keys_paths @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoV1Test.test_bad_zones @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoV1Test.test_folds_and_gaps @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoV1Test.test_folds_from_utc @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoV1Test.test_fromutc_errors @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoV1Test.test_key_attribute @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoV1Test.test_repr @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoV1Test.test_str @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoV1Test.test_time_fixed_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoV1Test.test_time_variable_offset @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoV1Test.test_unambiguous @ linux-x86_64 +test.test_zoneinfo.test_zoneinfo.ZoneInfoV1Test.test_utc @ linux-x86_64 diff --git a/graalpython/lib-graalpython/modules/hpy/universal.py b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/todo.sh old mode 100644 new mode 100755 similarity index 73% rename from graalpython/lib-graalpython/modules/hpy/universal.py rename to graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/todo.sh index 192503542d..264b146ad3 --- a/graalpython/lib-graalpython/modules/hpy/universal.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/todo.sh @@ -1,4 +1,5 @@ -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. +#!/bin/bash +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,29 +38,21 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from _hpy_universal import * -import _hpy_debug as _debug -import _hpy_trace as _trace +# Lists all the amd64-linux tags that are in the baseline tagged files +# and not here, i.e., the TODO list for Bytecode DSL interpreter -def load_from_spec(spec): - return load(spec.name, spec.origin) +parent_dir=$(dirname "$(readlink -f "$0")") +parent2_dir=$(dirname "$parent_dir") +baseline_dir="$parent2_dir/unittest_tags/" +for path in $(ls $parent_dir/*.txt); do + f=$(basename "$path") + comm -3 <(grep 'linux-x86_64' $baseline_dir/$f | egrep -v '^(#|!)' | sed 's/@.*//' | sort) <(egrep -v '^(#|!)' $f | sed 's/@.*//' | sort) +done -__version = None - - -def get_version(): - global __version - if not __version: - import os.path - import _io - path = os.path.join(os.path.dirname(__file__), "devel", "version.py") - ns = {} - with _io.FileIO(path, "r") as f: - exec(compile(f.readall(), path, "exec"), ns) - __version = (ns["__version__"], ns["__git_revision__"]) - return __version - - -def set_debug(*args): - return None +for path in $(ls $baseline_dir/*.txt); do + f=$(basename "$path") + if [ ! -f "$parent_dir/$f" ]; then + echo "COMPLETE SUITE: $f" + fi +done diff --git a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties index 8fcfded464..0771ed8aaf 100644 --- a/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties +++ b/graalpython/com.oracle.graal.python/src/META-INF/native-image/org.graalvm.python/python-language/native-image.properties @@ -1,6 +1,6 @@ # This file contains native-image arguments needed to build graalpython Args = -H:MaxRuntimeCompileMethods=20000 \ --initialize-at-build-time=com.oracle.graal.python,com.oracle.truffle.regex,jline,org.fusesource \ - --features=com.oracle.graal.python.BouncyCastleFeature,com.oracle.graal.python.JNIFeature \ + --features=com.oracle.graal.python.BouncyCastleFeature \ --add-exports=org.graalvm.nativeimage/org.graalvm.nativeimage.impl=org.graalvm.py \ --add-exports=org.graalvm.nativeimage/org.graalvm.nativeimage.impl=ALL-UNNAMED diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java index b870ff47d4..0d7146f58f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/BouncyCastleFeature.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -62,6 +62,7 @@ public void afterRegistration(AfterRegistrationAccess access) { // Register runtime reflection here, not in a config, so it can be easily disabled String[] reflectiveClasses = new String[]{ + // BouncyCastle looks up the classes below "org.bouncycastle.jcajce.provider.asymmetric.COMPOSITE$Mappings", "org.bouncycastle.jcajce.provider.asymmetric.DH$Mappings", "org.bouncycastle.jcajce.provider.asymmetric.DSA$Mappings", @@ -160,9 +161,37 @@ public void afterRegistration(AfterRegistrationAccess access) { for (String name : reflectiveClasses) { try { - RuntimeReflection.register(Class.forName(name).getConstructor()); - } catch (NoSuchMethodException | SecurityException | ClassNotFoundException e) { - throw new RuntimeException("Could not register " + name + " constructor for reflective access!", e); + RuntimeReflection.register(Class.forName(name)); + RuntimeReflection.register(Class.forName(name).getConstructors()); + } catch (SecurityException | ClassNotFoundException e) { + throw new RuntimeException("Could not register " + name + " for reflective access!", e); + } + } + + // SSLBasicKeyDerivation looks up the classes below reflectively since jdk-25+23 + // See https://github.com/openjdk/jdk/pull/24393 + reflectiveClasses = new String[]{ + "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA256", + "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA384", + "com.sun.crypto.provider.HKDFKeyDerivation$HKDFSHA512", + "sun.security.pkcs11.P11HKDF", + }; + for (String name : reflectiveClasses) { + try { + Class.forName(name); + } catch (SecurityException | ClassNotFoundException e) { + return; + } + } + // For backwards compatibility with older JDKs, we only do this if we found + // all those classes + Security.addProvider(Security.getProvider("SunJCE")); + for (String name : reflectiveClasses) { + try { + RuntimeReflection.register(Class.forName(name)); + RuntimeReflection.register(Class.forName(name).getConstructors()); + } catch (SecurityException | ClassNotFoundException e) { + throw new RuntimeException("Could not register " + name + " for reflective access!", e); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/JNIFeature.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/JNIFeature.java deleted file mode 100644 index 68d162e6d7..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/JNIFeature.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python; - -import com.oracle.graal.python.runtime.PythonImageBuildOptions; -import org.graalvm.nativeimage.hosted.Feature; -import org.graalvm.nativeimage.hosted.RuntimeJNIAccess; - -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNIContext; - -public final class JNIFeature implements Feature { - @Override - public void afterRegistration(AfterRegistrationAccess access) { - if (!PythonImageBuildOptions.WITHOUT_JNI) { - try { - // {{start jni upcall config}} - // @formatter:off - // Checkstyle: stop - // DO NOT EDIT THIS PART! - // This part is automatically generated by hpy.tools.autogen.graalpy.autogen_svm_jni_upcall_config - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxDup", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxClose", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongFromInt32t", int.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongFromUInt32t", int.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongFromInt64t", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongFromUInt64t", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongFromSizet", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongFromSsizet", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongAsInt32t", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongAsUInt32t", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongAsUInt32tMask", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongAsInt64t", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongAsUInt64t", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongAsUInt64tMask", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongAsSizet", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongAsSsizet", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongAsVoidPtr", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLongAsDouble", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxFloatFromDouble", double.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxFloatAsDouble", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxBoolFromBool", boolean.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLength", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxNumberCheck", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxAdd", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxSubtract", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxMultiply", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxMatrixMultiply", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxFloorDivide", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxTrueDivide", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxRemainder", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxDivmod", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxPower", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxNegative", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxPositive", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxAbsolute", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxInvert", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLshift", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxRshift", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxAnd", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxXor", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxOr", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxIndex", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLong", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxFloat", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxInPlaceAdd", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxInPlaceSubtract", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxInPlaceMultiply", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxInPlaceMatrixMultiply", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxInPlaceFloorDivide", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxInPlaceTrueDivide", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxInPlaceRemainder", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxInPlacePower", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxInPlaceLshift", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxInPlaceRshift", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxInPlaceAnd", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxInPlaceXor", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxInPlaceOr", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxCallableCheck", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxCallTupleDict", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxCall", long.class, long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxCallMethod", long.class, long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxFatalError", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxErrSetString", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxErrSetObject", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxErrSetFromErrnoWithFilename", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxErrSetFromErrnoWithFilenameObjects", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxErrOccurred")); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxErrExceptionMatches", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxErrNoMemory")); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxErrClear")); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxErrNewException", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxErrNewExceptionWithDoc", long.class, long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxErrWarnEx", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxErrWriteUnraisable", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxIsTrue", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxTypeFromSpec", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxTypeGenericNew", long.class, long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxGetAttr", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxHasAttr", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxHasAttrs", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxSetAttr", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxSetAttrs", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxGetItem", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxGetItemi", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxContains", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxSetItem", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxSetItemi", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxDelItem", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxDelItemi", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxDelItems", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxType", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxTypeCheck", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxTypeGetName", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxTypeIsSubtype", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxIs", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxAsStructObject", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxAsStructLegacy", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxAsStructType", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxAsStructLong", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxAsStructFloat", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxAsStructUnicode", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxAsStructTuple", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxAsStructList", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxTypeGetBuiltinShape", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxNew", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxRepr", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxStr", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxASCII", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxBytes", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxRichCompare", long.class, long.class, int.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxRichCompareBool", long.class, long.class, int.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxHash", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxBytesCheck", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxBytesSize", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxBytesGETSIZE", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxBytesAsString", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxBytesASSTRING", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxBytesFromString", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxBytesFromStringAndSize", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeFromString", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeCheck", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeAsASCIIString", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeAsLatin1String", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeAsUTF8String", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeAsUTF8AndSize", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeFromWideChar", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeDecodeFSDefault", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeDecodeFSDefaultAndSize", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeEncodeFSDefault", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeReadChar", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeDecodeASCII", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeDecodeLatin1", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeFromEncodedObject", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeSubstring", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxListCheck", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxListNew", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxListAppend", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxDictCheck", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxDictNew")); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxDictKeys", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxDictCopy", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxTupleCheck", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxSliceUnpack", long.class, long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxImportImportModule", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxCapsuleNew", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxCapsuleGet", long.class, int.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxCapsuleIsValid", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxCapsuleSet", long.class, int.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxFromPyObject", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxAsPyObject", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxListBuilderNew", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxListBuilderSet", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxListBuilderBuild", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxListBuilderCancel", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxTupleBuilderNew", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxTupleBuilderSet", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxTupleBuilderBuild", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxTupleBuilderCancel", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxFieldLoad", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxReenterPythonExecution", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxLeavePythonExecution")); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxGlobalLoad", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxDump", long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxCompiles", long.class, long.class, int.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxEvalCode", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxContextVarNew", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxContextVarSet", long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxSetCallFunction", long.class, long.class)); - // @formatter:on - // Checkstyle: resume - // {{end jni upcall config}} - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("getHPyDebugContext")); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("getHPyTraceContext")); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxGetItems", long.class, String.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxSetItems", long.class, String.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxGetAttrs", long.class, String.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxBulkClose", long.class, int.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxUnicodeFromJCharArray", char[].class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxSequenceFromArray", long[].class, boolean.class, boolean.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxContextVarGet", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxFieldStore", long.class, long.class, long.class)); - RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod("ctxGlobalStore", long.class, long.class)); - } catch (NoSuchMethodException e) { - throw new RuntimeException("Could not register method for JNI access!", e); - } - try { - RuntimeJNIAccess.register(GraalHPyContext.class.getDeclaredField("hpyHandleTable")); - RuntimeJNIAccess.register(GraalHPyContext.class.getDeclaredField("hpyGlobalsTable")); - RuntimeJNIAccess.register(GraalHPyContext.class.getDeclaredField("nextHandle")); - } catch (SecurityException | NoSuchFieldException e) { - throw new RuntimeException("Could not register field for JNI access!", e); - } - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java index db34ae3f50..e3889b0893 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java @@ -37,7 +37,6 @@ import java.io.IOException; import java.io.InputStream; import java.lang.invoke.VarHandle; -import java.lang.ref.WeakReference; import java.nio.charset.StandardCharsets; import java.nio.file.InvalidPathException; import java.util.ArrayList; @@ -53,7 +52,6 @@ import java.util.logging.Level; import org.graalvm.home.Version; -import org.graalvm.nativeimage.ImageInfo; import org.graalvm.options.OptionDescriptors; import org.graalvm.options.OptionKey; import org.graalvm.options.OptionValues; @@ -67,27 +65,27 @@ import com.oracle.graal.python.builtins.objects.PythonAbstractObject; import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis; import com.oracle.graal.python.builtins.objects.frame.PFrame; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.tuple.StructSequence; -import com.oracle.graal.python.builtins.objects.tuple.StructSequence.BuiltinTypeDescriptor; -import com.oracle.graal.python.builtins.objects.tuple.StructSequence.Descriptor; -import com.oracle.graal.python.builtins.objects.tuple.StructSequence.DescriptorCallTargets; import com.oracle.graal.python.builtins.objects.type.MroShape; import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; +import com.oracle.graal.python.compiler.BytecodeCodeUnit; import com.oracle.graal.python.compiler.CodeUnit; import com.oracle.graal.python.compiler.CompilationUnit; import com.oracle.graal.python.compiler.Compiler; import com.oracle.graal.python.compiler.RaisePythonExceptionErrorCallback; +import com.oracle.graal.python.compiler.bytecode_dsl.BytecodeDSLCompiler; +import com.oracle.graal.python.compiler.bytecode_dsl.BytecodeDSLCompiler.BytecodeDSLCompilerResult; import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode; +import com.oracle.graal.python.nodes.bytecode_dsl.BytecodeDSLCodeUnit; +import com.oracle.graal.python.nodes.call.CallDispatchers; import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.call.GenericInvokeNode; import com.oracle.graal.python.nodes.exception.TopLevelExceptionHandler; import com.oracle.graal.python.nodes.frame.GetFrameLocalsNode; import com.oracle.graal.python.nodes.frame.MaterializeFrameNode; @@ -107,7 +105,7 @@ import com.oracle.graal.python.runtime.PythonImageBuildOptions; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.Function; import com.oracle.graal.python.util.PythonUtils; import com.oracle.graal.python.util.Supplier; @@ -127,6 +125,7 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Idempotent; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.instrumentation.AllocationReporter; import com.oracle.truffle.api.instrumentation.ProvidedTags; import com.oracle.truffle.api.instrumentation.StandardTags; import com.oracle.truffle.api.interop.InteropLibrary; @@ -311,7 +310,7 @@ private static boolean mimeTypesComplete(ArrayList mimeJavaStrings) { public static final TruffleString[] T_DEFAULT_PYTHON_EXTENSIONS = new TruffleString[]{T_PY_EXTENSION, tsLiteral(".pyc")}; - private static final TruffleLogger LOGGER = TruffleLogger.getLogger(ID, PythonLanguage.class); + public static final TruffleLogger LOGGER = TruffleLogger.getLogger(ID, PythonLanguage.class); private static final LanguageReference REFERENCE = LanguageReference.create(PythonLanguage.class); @@ -363,46 +362,6 @@ public boolean isSingleContext() { @CompilationFinal(dimensions = 1) private final RootCallTarget[] builtinSlotsCallTargets; - /** - * Weak hash map of call targets for builtin functions associated with named tuples generated at - * runtime from C extensions. We hold the cached call targets also weakly, because otherwise we - * would have a cycle from the value (call targets reference builtin nodes which wrap the - * descriptor) to the key. The key should be GC'ed when the corresponding generated named tuple - * class is GC'ed. - */ - private final WeakHashMap> structSequenceTargets = new WeakHashMap<>(); - - /** - * The same as {@link #structSequenceTargets}, but for builtin named tuples. There is a bounded - * statically known number of builtin named tuples. - */ - private final ConcurrentHashMap structSequenceBuiltinTargets = new ConcurrentHashMap<>(); - - public StructSequence.DescriptorCallTargets getOrCreateStructSequenceCallTargets(StructSequence.Descriptor descriptor, - Function factory) { - if (singleContext) { - return factory.apply(descriptor); - } - if (descriptor instanceof BuiltinTypeDescriptor builtinDescriptor) { - // There must be finite set of objects initialized at build time, no need for a weak map - assert !ImageInfo.inImageCode() || builtinDescriptor.wasInitializedAtBuildTime(); - return structSequenceBuiltinTargets.computeIfAbsent(builtinDescriptor, factory); - } - return getOrCreateStructSeqNonBuiltinTargets(descriptor, factory); - } - - private DescriptorCallTargets getOrCreateStructSeqNonBuiltinTargets(Descriptor descriptor, Function factory) { - synchronized (structSequenceTargets) { - WeakReference weakResult = structSequenceTargets.computeIfAbsent(descriptor, d -> new WeakReference<>(factory.apply(d))); - DescriptorCallTargets result = weakResult.get(); - if (result == null) { - result = factory.apply(descriptor); - structSequenceTargets.put(descriptor, new WeakReference<>(result)); - } - return result; - } - } - /** * We cannot initialize call targets in language ctor and the next suitable hook is context * initialization, but that is called multiple times. We use this flag to run the language @@ -410,14 +369,6 @@ private DescriptorCallTargets getOrCreateStructSeqNonBuiltinTargets(Descriptor d */ private volatile boolean isLanguageInitialized; - /** - * A map to retrieve call targets of special slot methods for a given BuiltinMethodDescriptor. - * Used to perform uncached calls to slots. The call targets are not directly part of - * descriptors because that would make them specific to a language instance. We want to have - * them global in order to be able to efficiently compare them in guards. - */ - private final ConcurrentHashMap descriptorCallTargets = new ConcurrentHashMap<>(); - private final Shape emptyShape = Shape.newBuilder().allowImplicitCastIntToDouble(false).allowImplicitCastIntToLong(true).shapeFlags(0).propertyAssumptions(true).build(); @CompilationFinal(dimensions = 1) private final Shape[] builtinTypeInstanceShapes = new Shape[PythonBuiltinClassType.VALUES.length]; @@ -440,6 +391,7 @@ private DescriptorCallTargets getOrCreateStructSeqNonBuiltinTargets(Descriptor d @CompilationFinal(dimensions = 1) private volatile Object[] engineOptionsStorage; @CompilationFinal private volatile OptionValues engineOptions; + @CompilationFinal private AllocationReporter allocationReporter; /** For fast access to the PythonThreadState object by the owning thread. */ private final ContextThreadLocal threadState = locals.createContextThreadLocal(PythonContext.PythonThreadState::new); @@ -481,7 +433,6 @@ protected void finalizeContext(PythonContext context) { context.finalizeContext(); super.finalizeContext(context); // trigger cleanup of stale entries in weak hash maps - structSequenceTargets.size(); indirectCallDataMap.size(); } @@ -496,6 +447,7 @@ protected boolean patchContext(PythonContext context, Env newEnv) { Python3Core.writeInfo("Cannot use preinitialized context."); return false; } + context.resetPerfCounter(); context.initializeHomeAndPrefixPaths(newEnv, getLanguageHome()); Python3Core.writeInfo("Using preinitialized context."); context.patch(newEnv); @@ -521,6 +473,13 @@ protected PythonContext createContext(Env env) { assert areOptionsCompatible(options, PythonOptions.createEngineOptions(env)) : "invalid engine options"; } + if (allocationReporter == null) { + allocationReporter = env.lookup(AllocationReporter.class); + } else { + // GR-61960 + // assert allocationReporter == env.lookup(AllocationReporter.class); + } + return context; } @@ -534,6 +493,11 @@ public T getEngineOption(OptionKey key) { } } + public AllocationReporter getAllocationReporter() { + assert allocationReporter != null; + return allocationReporter; + } + @Override protected OptionDescriptors getOptionDescriptors() { return PythonOptions.DESCRIPTORS; @@ -593,7 +557,7 @@ protected CallTarget parse(ParsingRequest request) { } if (MIME_TYPE_BYTECODE.equals(source.getMimeType())) { byte[] bytes = source.getBytes().toByteArray(); - CodeUnit code = MarshalModuleBuiltins.deserializeCodeUnit(bytes); + CodeUnit code = MarshalModuleBuiltins.deserializeCodeUnit(null, context, bytes); boolean internal = shouldMarkSourceInternal(context); // The original file path should be passed as the name String name = source.getName(); @@ -618,7 +582,18 @@ protected CallTarget parse(ParsingRequest request) { if (internal && !source.isInternal()) { source = Source.newBuilder(source).internal(true).build(); } - PBytecodeRootNode rootNode = PBytecodeRootNode.create(this, code, source); + RootNode rootNode = null; + + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + if (source.hasBytes()) { + // Force a character-based source so that source sections work as expected. + source = Source.newBuilder(source).content(Source.CONTENT_NONE).build(); + } + rootNode = ((BytecodeDSLCodeUnit) code).createRootNode(context, source); + } else { + rootNode = PBytecodeRootNode.create(this, (BytecodeCodeUnit) code, source); + } + return PythonUtils.getOrCreateCallTarget(rootNode); } @@ -657,10 +632,13 @@ public RootCallTarget parse(PythonContext context, Source source, InputType type EnumSet futureFeatures) { RaisePythonExceptionErrorCallback errorCb = new RaisePythonExceptionErrorCallback(source, PythonOptions.isPExceptionWithJavaStacktrace(this)); try { + if (context.getEnv().getOptions().get(PythonOptions.ParserLogFiles)) { + LOGGER.log(Level.FINE, () -> "parse '" + source.getName() + "'"); + } Parser parser = Compiler.createParser(source.getCharacters().toString(), errorCb, type, interactiveTerminal); ModTy mod = (ModTy) parser.parse(); assert mod != null; - return compileForBytecodeInterpreter(context, mod, source, topLevel, optimize, argumentNames, errorCb, futureFeatures); + return compileModule(context, mod, source, topLevel, optimize, argumentNames, errorCb, futureFeatures); } catch (PException e) { if (topLevel) { PythonUtils.getOrCreateCallTarget(new TopLevelExceptionHandler(this, e)).call(); @@ -670,20 +648,19 @@ public RootCallTarget parse(PythonContext context, Source source, InputType type } @TruffleBoundary - public RootCallTarget compileForBytecodeInterpreter(PythonContext context, ModTy mod, Source source, boolean topLevel, int optimize, List argumentNames, + public RootCallTarget compileModule(PythonContext context, ModTy modIn, Source source, boolean topLevel, int optimize, List argumentNames, RaisePythonExceptionErrorCallback errorCallback, int flags) { - return compileForBytecodeInterpreter(context, mod, source, topLevel, optimize, argumentNames, errorCallback, FutureFeature.fromFlags(flags)); + return compileModule(context, modIn, source, topLevel, optimize, argumentNames, errorCallback, FutureFeature.fromFlags(flags)); } @TruffleBoundary - public RootCallTarget compileForBytecodeInterpreter(PythonContext context, ModTy modIn, Source source, boolean topLevel, int optimize, List argumentNames, + public RootCallTarget compileModule(PythonContext context, ModTy modIn, Source source, boolean topLevel, int optimize, List argumentNames, RaisePythonExceptionErrorCallback errorCallback, EnumSet futureFeatures) { RaisePythonExceptionErrorCallback errorCb = errorCallback; if (errorCb == null) { errorCb = new RaisePythonExceptionErrorCallback(source, PythonOptions.isPExceptionWithJavaStacktrace(this)); } try { - Compiler compiler = new Compiler(errorCb); boolean hasArguments = argumentNames != null && !argumentNames.isEmpty(); final ModTy mod; if (hasArguments) { @@ -691,9 +668,14 @@ public RootCallTarget compileForBytecodeInterpreter(PythonContext context, ModTy } else { mod = modIn; } - CompilationUnit cu = compiler.compile(mod, EnumSet.noneOf(Compiler.Flags.class), optimize, futureFeatures); - CodeUnit co = cu.assemble(); - RootNode rootNode = PBytecodeRootNode.create(this, co, source, errorCb); + + RootNode rootNode; + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + rootNode = compileForBytecodeDSLInterpreter(context, mod, source, optimize, errorCb, futureFeatures); + } else { + rootNode = compileForBytecodeInterpreter(mod, source, optimize, errorCb, futureFeatures); + } + if (topLevel) { GilNode gil = GilNode.getUncached(); boolean wasAcquired = gil.acquire(context, rootNode); @@ -718,6 +700,19 @@ public RootCallTarget compileForBytecodeInterpreter(PythonContext context, ModTy } } + private RootNode compileForBytecodeInterpreter(ModTy mod, Source source, int optimize, RaisePythonExceptionErrorCallback errorCallback, EnumSet futureFeatures) { + Compiler compiler = new Compiler(errorCallback); + CompilationUnit cu = compiler.compile(mod, EnumSet.noneOf(Compiler.Flags.class), optimize, futureFeatures); + BytecodeCodeUnit co = cu.assemble(); + return PBytecodeRootNode.create(this, co, source, errorCallback); + } + + private RootNode compileForBytecodeDSLInterpreter(PythonContext context, ModTy mod, Source source, int optimize, + RaisePythonExceptionErrorCallback errorCallback, EnumSet futureFeatures) { + BytecodeDSLCompilerResult result = BytecodeDSLCompiler.compile(this, context, mod, source, optimize, errorCallback, futureFeatures); + return result.rootNode(); + } + private static ModTy transformASTForExecutionWithArguments(List argumentNames, ModTy mod) { NodeFactory nodeFactory = new NodeFactory(); ArgTy[] astArgArray = new ArgTy[argumentNames.size()]; @@ -779,7 +774,7 @@ public ExecutableNode parse(InlineParsingRequest request) { RootCallTarget callTarget = parse(context, request.getSource(), InputType.EVAL, false, 0, false, null, EnumSet.noneOf(FutureFeature.class)); return new ExecutableNode(this) { @Child private GilNode gilNode = GilNode.create(); - @Child private GenericInvokeNode invokeNode = GenericInvokeNode.create(); + @Child private CallDispatchers.SimpleIndirectInvokeNode invokeNode = CallDispatchers.SimpleIndirectInvokeNode.create(); @Child private MaterializeFrameNode materializeFrameNode = MaterializeFrameNode.create(); @Child private GetFrameLocalsNode getFrameLocalsNode = GetFrameLocalsNode.create(); @@ -793,7 +788,7 @@ public Object execute(VirtualFrame frame) { PArguments.setGlobals(arguments, PArguments.getGlobals(frame)); boolean wasAcquired = gilNode.acquire(); try { - return invokeNode.execute(callTarget, arguments); + return invokeNode.executeCached(frame, callTarget, arguments); } finally { gilNode.release(wasAcquired); } @@ -804,8 +799,8 @@ public Object execute(VirtualFrame frame) { @Override protected Object getLanguageView(PythonContext context, Object value) { assert !(value instanceof PythonAbstractObject); - PythonObjectFactory factory = PythonObjectFactory.getUncached(); InteropLibrary interopLib = InteropLibrary.getFactory().getUncached(value); + PythonLanguage language = context.getLanguage(); try { if (interopLib.isBoolean(value)) { if (interopLib.asBoolean(value)) { @@ -814,21 +809,21 @@ protected Object getLanguageView(PythonContext context, Object value) { return context.getFalse(); } } else if (interopLib.isString(value)) { - return factory.createString(interopLib.asTruffleString(value).switchEncodingUncached(TS_ENCODING)); + return PFactory.createString(language, interopLib.asTruffleString(value).switchEncodingUncached(TS_ENCODING)); } else if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) { // TODO: (tfel) once the interop protocol allows us to // distinguish fixed point from floating point reliably, we can // remove this branch - return factory.createInt(interopLib.asLong(value)); + return PFactory.createInt(language, interopLib.asLong(value)); } else if (value instanceof Float || value instanceof Double) { // TODO: (tfel) once the interop protocol allows us to // distinguish fixed point from floating point reliably, we can // remove this branch - return factory.createFloat(interopLib.asDouble(value)); + return PFactory.createFloat(language, interopLib.asDouble(value)); } else if (interopLib.fitsInLong(value)) { - return factory.createInt(interopLib.asLong(value)); + return PFactory.createInt(language, interopLib.asLong(value)); } else if (interopLib.fitsInDouble(value)) { - return factory.createFloat(interopLib.asDouble(value)); + return PFactory.createFloat(language, interopLib.asDouble(value)); } else { return new ForeignLanguageView(value); } @@ -972,7 +967,7 @@ public static Source newSource(PythonContext ctxt, TruffleFile src, String name) } private static Source newSource(PythonContext context, SourceBuilder srcBuilder) throws IOException { - if (getPythonOS() == PLATFORM_WIN32 && ImageInfo.inImageBuildtimeCode()) { + if (getPythonOS() == PLATFORM_WIN32 && context.getEnv().isPreInitialization()) { // canonicalization on windows means something else than on linux and causes issues // with paths srcBuilder.canonicalizePath(false); @@ -1054,16 +1049,22 @@ public Shape getBuiltinTypeInstanceShape(PythonBuiltinClassType type) { Shape shape = builtinTypeInstanceShapes[ordinal]; if (shape == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - Shape.DerivedBuilder shapeBuilder = Shape.newBuilder(getEmptyShape()).addConstantProperty(HiddenAttr.getClassHiddenKey(), type, 0); - if (!type.isBuiltinWithDict()) { - shapeBuilder.shapeFlags(PythonObject.HAS_SLOTS_BUT_NO_DICT_FLAG); - } - shape = shapeBuilder.build(); - builtinTypeInstanceShapes[ordinal] = shape; + shape = createBuiltinShape(type, ordinal); } return shape; } + private Shape createBuiltinShape(PythonBuiltinClassType type, int ordinal) { + Shape shape; + Shape.DerivedBuilder shapeBuilder = Shape.newBuilder(getEmptyShape()).addConstantProperty(HiddenAttr.getClassHiddenKey(), type, 0); + if (!type.isBuiltinWithDict()) { + shapeBuilder.shapeFlags(PythonObject.HAS_SLOTS_BUT_NO_DICT_FLAG); + } + shape = shapeBuilder.build(); + builtinTypeInstanceShapes[ordinal] = shape; + return shape; + } + public RootCallTarget getBuiltinSlotCallTarget(int index) { return builtinSlotsCallTargets[index]; } @@ -1114,11 +1115,16 @@ public RootCallTarget createCachedCallTarget(Function } public RootCallTarget createCachedCallTarget(Function rootNodeFunction, Class nodeClass1, Class nodeClass2, String name) { - // for slot wrappers: the root node may be wrapping a helper wrapper node implementing the - // wrapper logic and the bare slot node itself + // for slot call targets and wrappers: the root node may be wrapping a helper wrapper node + // implementing the slot wrapper logic and the bare slot node itself return createCachedCallTargetUnsafe(rootNodeFunction, true, nodeClass1, nodeClass2, name); } + public RootCallTarget createCachedCallTarget(Function rootNodeFunction, Class nodeClass1, Class nodeClass2, PythonBuiltinClassType type, String name) { + // for slot wrappers: the type is used for validation of "self" type + return createCachedCallTargetUnsafe(rootNodeFunction, true, nodeClass1, nodeClass2, type, name); + } + /** * Caches call targets for external C functions created by extensions at runtime. *

    @@ -1174,28 +1180,12 @@ private RootCallTarget createCachedCallTargetUnsafe(Function { - T boundToObject(PythonBuiltinClassType binding, PythonObjectFactory factory); + T boundToObject(PythonBuiltinClassType binding, PythonLanguage language); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Builtin.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Builtin.java index 18ac9d4ed0..a99c4ccccd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Builtin.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Builtin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -45,10 +45,6 @@ */ PythonOS os() default PythonOS.PLATFORM_ANY; - PythonBuiltinClassType constructsClass() default PythonBuiltinClassType.nil; - - PythonBuiltinClassType[] base() default {}; - int minNumOfPositionalArgs() default 0; int maxNumOfPositionalArgs() default -1; @@ -63,16 +59,12 @@ boolean takesVarArgs() default false; - boolean varArgsMarker() default false; - boolean takesVarKeywordArgs() default false; String[] parameterNames() default {}; String[] keywordOnlyNames() default {}; - boolean isPublic() default true; - boolean isClassmethod() default false; boolean isStaticmethod() default false; @@ -97,15 +89,6 @@ */ boolean declaresExplicitSelf() default false; - /** - * Declares that this builtin needs to reverse the first and second argument it receives. This - * implements the reverse operation wrappers from CPython. This only applies to binary and - * ternary nodes. - * - * @see com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode BuiltinFunctionRootNode - */ - boolean reverseOperation() default false; - String raiseErrorName() default StringLiterals.J_EMPTY_STRING; boolean forceSplitDirectCalls() default false; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/CoreFunctions.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/CoreFunctions.java index fedb82582b..9e9bf4955b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/CoreFunctions.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/CoreFunctions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -40,11 +40,7 @@ */ PythonOS os() default PythonOS.PLATFORM_ANY; - String publicName() default ""; - PythonBuiltinClassType[] extendClasses() default {}; - String pythonFile() default ""; - boolean isEager() default false; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java index 97405a14f7..20b24d7a73 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java @@ -32,15 +32,20 @@ import static com.oracle.graal.python.nodes.BuiltinNames.T_NT; import static com.oracle.graal.python.nodes.BuiltinNames.T_STDERR; import static com.oracle.graal.python.nodes.BuiltinNames.T_SYS; +import static com.oracle.graal.python.nodes.BuiltinNames.T_UNICODEDATA; import static com.oracle.graal.python.nodes.BuiltinNames.T_ZIPIMPORT; +import static com.oracle.graal.python.nodes.BuiltinNames.T__SRE; +import static com.oracle.graal.python.nodes.BuiltinNames.T__SYSCONFIG; import static com.oracle.graal.python.nodes.BuiltinNames.T__WEAKREF; import static com.oracle.graal.python.nodes.BuiltinNames.T___BUILTINS__; +import static com.oracle.graal.python.nodes.BuiltinNames.T___GRAALPYTHON__; import static com.oracle.graal.python.nodes.BuiltinNames.T___IMPORT__; +import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___PACKAGE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___REPR__; import static com.oracle.graal.python.nodes.StringLiterals.J_PY_EXTENSION; import static com.oracle.graal.python.nodes.StringLiterals.T_DOT; import static com.oracle.graal.python.nodes.StringLiterals.T_GRAALPYTHON; +import static com.oracle.graal.python.nodes.StringLiterals.T_JAVA; import static com.oracle.graal.python.nodes.StringLiterals.T_REF; import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; @@ -56,21 +61,14 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.ServiceLoader; import java.util.logging.Level; -import com.oracle.graal.python.builtins.objects.foreign.ForeignExecutableBuiltins; -import com.oracle.graal.python.builtins.objects.foreign.ForeignInstantiableBuiltins; -import com.oracle.graal.python.builtins.objects.foreign.ForeignIterableBuiltins; -import org.graalvm.nativeimage.ImageInfo; - import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.AbcModuleBuiltins; import com.oracle.graal.python.builtins.modules.ArrayModuleBuiltins; import com.oracle.graal.python.builtins.modules.AsyncioModuleBuiltins; import com.oracle.graal.python.builtins.modules.AtexitModuleBuiltins; import com.oracle.graal.python.builtins.modules.BinasciiModuleBuiltins; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors; import com.oracle.graal.python.builtins.modules.BuiltinFunctions; import com.oracle.graal.python.builtins.modules.CmathModuleBuiltins; import com.oracle.graal.python.builtins.modules.CodecsModuleBuiltins; @@ -82,16 +80,12 @@ import com.oracle.graal.python.builtins.modules.FaulthandlerModuleBuiltins; import com.oracle.graal.python.builtins.modules.FcntlModuleBuiltins; import com.oracle.graal.python.builtins.modules.GcModuleBuiltins; -import com.oracle.graal.python.builtins.modules.GraalHPyDebugModuleBuiltins; -import com.oracle.graal.python.builtins.modules.GraalHPyTraceModuleBuiltins; -import com.oracle.graal.python.builtins.modules.GraalHPyUniversalModuleBuiltins; import com.oracle.graal.python.builtins.modules.GraalPythonModuleBuiltins; import com.oracle.graal.python.builtins.modules.ImpModuleBuiltins; import com.oracle.graal.python.builtins.modules.ItertoolsModuleBuiltins; import com.oracle.graal.python.builtins.modules.JArrayModuleBuiltins; import com.oracle.graal.python.builtins.modules.JavaModuleBuiltins; import com.oracle.graal.python.builtins.modules.LocaleModuleBuiltins; -import com.oracle.graal.python.builtins.modules.LsprofModuleBuiltins; import com.oracle.graal.python.builtins.modules.MMapModuleBuiltins; import com.oracle.graal.python.builtins.modules.MarshalModuleBuiltins; import com.oracle.graal.python.builtins.modules.MathModuleBuiltins; @@ -112,6 +106,7 @@ import com.oracle.graal.python.builtins.modules.SelectModuleBuiltins; import com.oracle.graal.python.builtins.modules.SignalModuleBuiltins; import com.oracle.graal.python.builtins.modules.SocketModuleBuiltins; +import com.oracle.graal.python.builtins.modules.StatResultBuiltins; import com.oracle.graal.python.builtins.modules.StringModuleBuiltins; import com.oracle.graal.python.builtins.modules.StructModuleBuiltins; import com.oracle.graal.python.builtins.modules.SysModuleBuiltins; @@ -171,7 +166,6 @@ import com.oracle.graal.python.builtins.modules.functools.PartialBuiltins; import com.oracle.graal.python.builtins.modules.hashlib.Blake2ModuleBuiltins; import com.oracle.graal.python.builtins.modules.hashlib.Blake2bObjectBuiltins; -import com.oracle.graal.python.builtins.modules.hashlib.Blake2sObjectBuiltins; import com.oracle.graal.python.builtins.modules.hashlib.DigestObjectBuiltins; import com.oracle.graal.python.builtins.modules.hashlib.HashObjectBuiltins; import com.oracle.graal.python.builtins.modules.hashlib.HashlibModuleBuiltins; @@ -202,6 +196,8 @@ import com.oracle.graal.python.builtins.modules.json.JSONEncoderBuiltins; import com.oracle.graal.python.builtins.modules.json.JSONModuleBuiltins; import com.oracle.graal.python.builtins.modules.json.JSONScannerBuiltins; +import com.oracle.graal.python.builtins.modules.lsprof.LsprofModuleBuiltins; +import com.oracle.graal.python.builtins.modules.lsprof.ProfilerBuiltins; import com.oracle.graal.python.builtins.modules.lzma.LZMACompressorBuiltins; import com.oracle.graal.python.builtins.modules.lzma.LZMADecompressorBuiltins; import com.oracle.graal.python.builtins.modules.lzma.LZMAModuleBuiltins; @@ -240,6 +236,8 @@ import com.oracle.graal.python.builtins.objects.contextvars.TokenBuiltins; import com.oracle.graal.python.builtins.objects.deque.DequeBuiltins; import com.oracle.graal.python.builtins.objects.deque.DequeIterBuiltins; +import com.oracle.graal.python.builtins.objects.deque.DequeIterCommonBuiltins; +import com.oracle.graal.python.builtins.objects.deque.DequeRevIterBuiltins; import com.oracle.graal.python.builtins.objects.dict.DefaultDictBuiltins; import com.oracle.graal.python.builtins.objects.dict.DictBuiltins; import com.oracle.graal.python.builtins.objects.dict.DictReprBuiltin; @@ -248,6 +246,7 @@ import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.ellipsis.EllipsisBuiltins; import com.oracle.graal.python.builtins.objects.enumerate.EnumerateBuiltins; +import com.oracle.graal.python.builtins.objects.exception.AttributeErrorBuiltins; import com.oracle.graal.python.builtins.objects.exception.BaseExceptionBuiltins; import com.oracle.graal.python.builtins.objects.exception.BaseExceptionGroupBuiltins; import com.oracle.graal.python.builtins.objects.exception.ImportErrorBuiltins; @@ -264,6 +263,9 @@ import com.oracle.graal.python.builtins.objects.floats.PFloat; import com.oracle.graal.python.builtins.objects.foreign.ForeignAbstractClassBuiltins; import com.oracle.graal.python.builtins.objects.foreign.ForeignBooleanBuiltins; +import com.oracle.graal.python.builtins.objects.foreign.ForeignExecutableBuiltins; +import com.oracle.graal.python.builtins.objects.foreign.ForeignInstantiableBuiltins; +import com.oracle.graal.python.builtins.objects.foreign.ForeignIterableBuiltins; import com.oracle.graal.python.builtins.objects.foreign.ForeignNumberBuiltins; import com.oracle.graal.python.builtins.objects.foreign.ForeignObjectBuiltins; import com.oracle.graal.python.builtins.objects.frame.FrameBuiltins; @@ -283,11 +285,12 @@ import com.oracle.graal.python.builtins.objects.ints.IntBuiltins; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.iterator.IteratorBuiltins; -import com.oracle.graal.python.builtins.objects.iterator.PZipBuiltins; import com.oracle.graal.python.builtins.objects.iterator.SentinelIteratorBuiltins; +import com.oracle.graal.python.builtins.objects.iterator.ZipBuiltins; import com.oracle.graal.python.builtins.objects.itertools.AccumulateBuiltins; import com.oracle.graal.python.builtins.objects.itertools.ChainBuiltins; import com.oracle.graal.python.builtins.objects.itertools.CombinationsBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.CombinationsWithReplacementBuiltins; import com.oracle.graal.python.builtins.objects.itertools.CompressBuiltins; import com.oracle.graal.python.builtins.objects.itertools.CountBuiltins; import com.oracle.graal.python.builtins.objects.itertools.CycleBuiltins; @@ -315,6 +318,7 @@ import com.oracle.graal.python.builtins.objects.method.BuiltinClassmethodBuiltins; import com.oracle.graal.python.builtins.objects.method.BuiltinFunctionOrMethodBuiltins; import com.oracle.graal.python.builtins.objects.method.ClassmethodBuiltins; +import com.oracle.graal.python.builtins.objects.method.ClassmethodCommonBuiltins; import com.oracle.graal.python.builtins.objects.method.DecoratedMethodBuiltins; import com.oracle.graal.python.builtins.objects.method.InstancemethodBuiltins; import com.oracle.graal.python.builtins.objects.method.MethodBuiltins; @@ -352,17 +356,18 @@ import com.oracle.graal.python.builtins.objects.struct.StructBuiltins; import com.oracle.graal.python.builtins.objects.struct.StructUnpackIteratorBuiltins; import com.oracle.graal.python.builtins.objects.superobject.SuperBuiltins; -import com.oracle.graal.python.builtins.objects.thread.LockBuiltins; +import com.oracle.graal.python.builtins.objects.thread.CommonLockBuiltins; +import com.oracle.graal.python.builtins.objects.thread.LockTypeBuiltins; import com.oracle.graal.python.builtins.objects.thread.RLockBuiltins; -import com.oracle.graal.python.builtins.objects.thread.ThreadBuiltins; import com.oracle.graal.python.builtins.objects.thread.ThreadLocalBuiltins; import com.oracle.graal.python.builtins.objects.tokenize.TokenizerIterBuiltins; import com.oracle.graal.python.builtins.objects.traceback.TracebackBuiltins; +import com.oracle.graal.python.builtins.objects.tuple.InstantiableStructSequenceBuiltins; +import com.oracle.graal.python.builtins.objects.tuple.StructSequenceBuiltins; import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins; import com.oracle.graal.python.builtins.objects.tuple.TupleGetterBuiltins; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeBuiltins; import com.oracle.graal.python.builtins.objects.types.GenericAliasBuiltins; @@ -373,7 +378,7 @@ import com.oracle.graal.python.nodes.BuiltinNames; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromPythonObjectNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode; -import com.oracle.graal.python.nodes.call.GenericInvokeNode; +import com.oracle.graal.python.nodes.call.CallDispatchers; import com.oracle.graal.python.nodes.object.GetForeignObjectClassNode; import com.oracle.graal.python.nodes.statement.AbstractImportNode; import com.oracle.graal.python.pegparser.FutureFeature; @@ -384,7 +389,7 @@ import com.oracle.graal.python.runtime.exception.ExceptionUtils; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.interop.PythonMapScope; -import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.Supplier; import com.oracle.truffle.api.CallTarget; @@ -393,9 +398,12 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.TruffleFile; +import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.TruffleLogger; +import com.oracle.truffle.api.TruffleOptions; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.strings.TruffleString; @@ -416,40 +424,32 @@ public abstract class Python3Core { private static TruffleString[] initializeCoreFiles() { // Order matters! - List coreFiles = new ArrayList<>(Arrays.asList( - toTruffleStringUncached("__graalpython__"), - toTruffleStringUncached("_weakref"), - toTruffleStringUncached("unicodedata"), - toTruffleStringUncached("_sre"), - toTruffleStringUncached("_sysconfig"), - toTruffleStringUncached("java"), - toTruffleStringUncached("pip_hook"))); - // add service loader defined python file extensions - if (!ImageInfo.inImageRuntimeCode()) { - ServiceLoader providers = ServiceLoader.load(PythonBuiltins.class, Python3Core.class.getClassLoader()); - PythonOS currentOs = PythonOS.getPythonOS(); - for (PythonBuiltins builtin : providers) { - CoreFunctions annotation = builtin.getClass().getAnnotation(CoreFunctions.class); - if (!annotation.pythonFile().isEmpty() && - (annotation.os() == PythonOS.PLATFORM_ANY || annotation.os() == currentOs)) { - coreFiles.add(toTruffleStringUncached(annotation.pythonFile())); - } - } + List coreFiles = List.of( + T___GRAALPYTHON__, + T__WEAKREF, + T_UNICODEDATA, + T__SRE, + T__SYSCONFIG, + T_JAVA, + toTruffleStringUncached("pip_hook")); + if (PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32) { + coreFiles = new ArrayList<>(coreFiles); + coreFiles.add(toTruffleStringUncached("_nt")); } - coreFiles.removeAll(Arrays.asList(new TruffleString[]{null})); - return coreFiles.toArray(new TruffleString[coreFiles.size()]); + + return coreFiles.toArray(new TruffleString[0]); } private final PythonBuiltins[] builtins; - private static final boolean hasProfilerTool; + public static final boolean HAS_PROFILER_TOOL; static { Class c = null; try { c = Class.forName("com.oracle.truffle.tools.profiler.CPUSampler"); } catch (LinkageError | ClassNotFoundException e) { } - hasProfilerTool = c != null; + HAS_PROFILER_TOOL = c != null; c = null; } @@ -469,12 +469,13 @@ private static void filterBuiltins(List builtins) { builtins.removeAll(toRemove); } - private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed, boolean socketIOAllowed) { - List builtins = new ArrayList<>(Arrays.asList(new BuiltinConstructors(), + private static PythonBuiltins[] initializeBuiltins(TruffleLanguage.Env env) { + List builtins = new ArrayList<>(Arrays.asList( new AbcModuleBuiltins(), new BuiltinFunctions(), new DecoratedMethodBuiltins(), new ClassmethodBuiltins(), + new ClassmethodCommonBuiltins(), new StaticmethodBuiltins(), new InstancemethodBuiltins(), new SimpleNamespaceBuiltins(), @@ -504,13 +505,15 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed, new RangeBuiltins(), new SliceBuiltins(), new TupleBuiltins(), + new StructSequenceBuiltins(), + new InstantiableStructSequenceBuiltins(), new StringBuiltins(), new BaseSetBuiltins(), new SetBuiltins(), new FrozenSetBuiltins(), new IteratorBuiltins(), new ReversedBuiltins(), - new PZipBuiltins(), + new ZipBuiltins(), new EnumerateBuiltins(), new MapBuiltins(), new NotImplementedBuiltins(), @@ -549,6 +552,7 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed, new CryptModuleBuiltins(), new ScandirIteratorBuiltins(), new DirEntryBuiltins(), + new StatResultBuiltins(), new ImpModuleBuiltins(), new ArrayModuleBuiltins(), new ArrayBuiltins(), @@ -572,6 +576,7 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed, new GenericAliasIteratorBuiltins(), new com.oracle.graal.python.builtins.objects.types.UnionTypeBuiltins(), // exceptions + new AttributeErrorBuiltins(), new SystemExitBuiltins(), new ImportErrorBuiltins(), new StopIterationBuiltins(), @@ -631,7 +636,9 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed, new CodecsModuleBuiltins(), new CodecsTruffleModuleBuiltins(), new DequeBuiltins(), + new DequeIterCommonBuiltins(), new DequeIterBuiltins(), + new DequeRevIterBuiltins(), new OrderedDictBuiltins(), new OrderedDictKeysBuiltins(), new OrderedDictValuesBuiltins(), @@ -646,9 +653,9 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed, new JSONModuleBuiltins(), new SREModuleBuiltins(), new AstModuleBuiltins(), - PythonImageBuildOptions.WITHOUT_NATIVE_POSIX && (PythonImageBuildOptions.WITHOUT_JAVA_INET || !socketIOAllowed) ? null : new SelectModuleBuiltins(), - PythonImageBuildOptions.WITHOUT_NATIVE_POSIX && (PythonImageBuildOptions.WITHOUT_JAVA_INET || !socketIOAllowed) ? null : new SocketModuleBuiltins(), - PythonImageBuildOptions.WITHOUT_NATIVE_POSIX && (PythonImageBuildOptions.WITHOUT_JAVA_INET || !socketIOAllowed) ? null : new SocketBuiltins(), + PythonImageBuildOptions.WITHOUT_NATIVE_POSIX && (PythonImageBuildOptions.WITHOUT_JAVA_INET || !env.isSocketIOAllowed()) ? null : new SelectModuleBuiltins(), + PythonImageBuildOptions.WITHOUT_NATIVE_POSIX && (PythonImageBuildOptions.WITHOUT_JAVA_INET || !env.isSocketIOAllowed()) ? null : new SocketModuleBuiltins(), + PythonImageBuildOptions.WITHOUT_NATIVE_POSIX && (PythonImageBuildOptions.WITHOUT_JAVA_INET || !env.isSocketIOAllowed()) ? null : new SocketBuiltins(), PythonImageBuildOptions.WITHOUT_PLATFORM_ACCESS ? null : new SignalModuleBuiltins(), new TracebackBuiltins(), new GcModuleBuiltins(), @@ -681,12 +688,12 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed, PythonImageBuildOptions.WITHOUT_DIGEST ? null : new HashObjectBuiltins(), PythonImageBuildOptions.WITHOUT_DIGEST ? null : new ShakeDigestObjectBuiltins(), PythonImageBuildOptions.WITHOUT_DIGEST ? null : new Blake2bObjectBuiltins(), - PythonImageBuildOptions.WITHOUT_DIGEST ? null : new Blake2sObjectBuiltins(), PythonImageBuildOptions.WITHOUT_DIGEST ? null : new HashlibModuleBuiltins(), // itertools new AccumulateBuiltins(), new CombinationsBuiltins(), + new CombinationsWithReplacementBuiltins(), new CompressBuiltins(), new DropwhileBuiltins(), new ChainBuiltins(), @@ -717,9 +724,9 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed, new SimpleQueueBuiltins(), new QueueModuleBuiltins(), new ThreadModuleBuiltins(), - new ThreadBuiltins(), new ThreadLocalBuiltins(), - new LockBuiltins(), + new CommonLockBuiltins(), + new LockTypeBuiltins(), new RLockBuiltins(), new PwdModuleBuiltins(), new ResourceModuleBuiltins(), @@ -780,11 +787,6 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed, new PyCPointerBuiltins(), new CDataBuiltins(), - // _hpy_universal, _hpy_debug, and _hpy_trace - new GraalHPyUniversalModuleBuiltins(), - new GraalHPyDebugModuleBuiltins(), - new GraalHPyTraceModuleBuiltins(), - new StructModuleBuiltins(), new StructBuiltins(), new StructUnpackIteratorBuiltins(), @@ -798,19 +800,15 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed, // _tokenizer new TokenizeModuleBuiltins(), new TokenizerIterBuiltins())); - if (hasProfilerTool) { + if (HAS_PROFILER_TOOL) { builtins.add(new LsprofModuleBuiltins()); - builtins.add(LsprofModuleBuiltins.newProfilerBuiltins()); + builtins.add(new ProfilerBuiltins()); } - if (!PythonImageBuildOptions.WITHOUT_COMPRESSION_LIBRARIES && (nativeAccessAllowed || ImageInfo.inImageBuildtimeCode())) { + if (!PythonImageBuildOptions.WITHOUT_COMPRESSION_LIBRARIES && (env.isNativeAccessAllowed() || env.isPreInitialization())) { builtins.add(new BZ2CompressorBuiltins()); builtins.add(new BZ2DecompressorBuiltins()); builtins.add(new BZ2ModuleBuiltins()); } - ServiceLoader providers = ServiceLoader.load(PythonBuiltins.class, Python3Core.class.getClassLoader()); - for (PythonBuiltins builtin : providers) { - builtins.add(builtin); - } filterBuiltins(builtins); return builtins.toArray(new PythonBuiltins[builtins.size()]); } @@ -842,17 +840,16 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed, private volatile boolean initialized; private final PythonLanguage language; - @CompilationFinal private PythonObjectSlowPathFactory objectFactory; - public Python3Core(PythonLanguage language, boolean isNativeSupportAllowed, boolean socketIOAllowed) { + public Python3Core(PythonLanguage language, TruffleLanguage.Env env) { this.language = language; - this.builtins = initializeBuiltins(isNativeSupportAllowed, socketIOAllowed); + this.builtins = initializeBuiltins(env); this.coreFiles = initializeCoreFiles(); } @CompilerDirectives.ValueType public static class SysModuleState { - private int recursionLimit = ImageInfo.inImageCode() ? NATIVE_REC_LIM : REC_LIM; + private int recursionLimit = TruffleOptions.AOT ? NATIVE_REC_LIM : REC_LIM; private int checkInterval = 100; private double switchInterval = 0.005; @@ -906,11 +903,12 @@ public final PythonLanguage getLanguage() { * multi-context mode. Can be null. */ public final PythonLanguage getLanguage(Node node) { - if (CompilerDirectives.inCompiledCode() && node != null && CompilerDirectives.isPartialEvaluationConstant(node) && node.getRootNode() != null) { - // This will make it PE-constant in multi-context mode - return PythonLanguage.get(node); + // The condition is always true in the interpreter + if (CompilerDirectives.isPartialEvaluationConstant(language)) { + return language; } - return language; + // This will make it PE-constant in multi-context mode + return PythonLanguage.get(node); } /** @@ -924,19 +922,16 @@ public final boolean isCoreInitialized() { * Load the core library and prepare all builtin classes and modules. */ public final void initialize(PythonContext context) { - objectFactory = new PythonObjectSlowPathFactory(context.getAllocationReporter(), context.getLanguage()); initializeJavaCore(); initializeImportlib(); context.applyModuleOptions(); initializePython3Core(context.getCoreHomeOrFail()); - assert SpecialMethodSlot.checkSlotOverrides(this); initialized = true; } private void initializeJavaCore() { initializeTypes(); populateBuiltins(); - SpecialMethodSlot.initializeBuiltinsSpecialMethodSlots(this); publishBuiltinModules(); builtinsModule = builtinModules.get(BuiltinNames.T_BUILTINS); } @@ -979,11 +974,6 @@ private void initializeImportlib() { importFunc = (PFunction) __import__; importlib = bootstrap; - PythonBuiltinClass moduleType = lookupType(PythonBuiltinClassType.PythonModule); - writeNode.execute(moduleType, T___REPR__, readNode.execute(bootstrap, toTruffleStringUncached("_module_repr"))); - - SpecialMethodSlot.reinitializeSpecialMethodSlots(moduleType, getLanguage()); - // see CPython's init_importlib_external callNode.execute(null, null, bootstrap, toTruffleStringUncached("_install_external_importers")); if (!PythonImageBuildOptions.WITHOUT_COMPRESSION_LIBRARIES) { @@ -1040,10 +1030,10 @@ private void initializePython3Core(TruffleString coreHome) { /** * Run post-initialization code that needs a fully working Python environment. This will be run * eagerly when the context is initialized on the JVM or a new context is created on SVM, but is - * omitted when the native image is generated. + * omitted when creating a pre-initialized context. */ - public final void postInitialize() { - if (!ImageInfo.inImageBuildtimeCode() || ImageInfo.inImageRuntimeCode()) { + public final void postInitialize(Env env) { + if (!env.isPreInitialization()) { initialized = false; for (PythonBuiltins builtin : builtins) { @@ -1060,9 +1050,9 @@ public final void postInitialize() { * fallback to another _bz2 implementation (e.g. LLVM or maybe some Java lib). This * needs to be done here and cannot be done in 'initializeBuiltins' because then we * would never include the intrinsified _bz2 module in the native image since native - * access is never allowed during native image build time. + * access is never allowed during context pre-initialization. */ - if (!PythonImageBuildOptions.WITHOUT_COMPRESSION_LIBRARIES && ImageInfo.inImageCode() && !getContext().isNativeAccessAllowed()) { + if (!PythonImageBuildOptions.WITHOUT_COMPRESSION_LIBRARIES && TruffleOptions.AOT && !getContext().isNativeAccessAllowed()) { removeBuiltinModule(BuiltinNames.T_BZ2); } @@ -1083,9 +1073,6 @@ public void run() { } } - // import polyglot decorators and special interop predefined behavior - loadFile(toTruffleStringUncached("_polyglot"), getContext().getCoreHomeOrFail()); - initialized = true; } } @@ -1219,9 +1206,11 @@ private void initializeTypes() { } } // now initialize well-known objects - pyTrue = factory().createInt(PythonBuiltinClassType.Boolean, BigInteger.ONE); - pyFalse = factory().createInt(PythonBuiltinClassType.Boolean, BigInteger.ZERO); - pyNaN = factory().createFloat(Double.NaN); + PythonBuiltinClassType booleanType = PythonBuiltinClassType.Boolean; + Shape booleanShape = booleanType.getInstanceShape(getLanguage()); + pyTrue = PFactory.createInt(getLanguage(), booleanType, booleanShape, BigInteger.ONE); + pyFalse = PFactory.createInt(getLanguage(), booleanType, booleanShape, BigInteger.ZERO); + pyNaN = PFactory.createFloat(getLanguage(), Double.NaN); } private void populateBuiltins() { @@ -1246,11 +1235,12 @@ private void populateBuiltins() { } } - Map> wrapped = new HashMap<>(); for (PythonBuiltinClassType klass : PythonBuiltinClassType.VALUES) { - wrapped.clear(); - TpSlots.addOperatorsToBuiltin(wrapped, this, klass); - PythonBuiltins.addFunctionsToModuleObject(wrapped, lookupType(klass), factory()); + PythonBuiltinClass pbc = lookupType(klass); + TpSlots.addOperatorsToBuiltin(this, klass, pbc); + if (klass.getDoc() != null && pbc.getAttribute(T___DOC__) instanceof PNone) { + pbc.setAttribute(T___DOC__, klass.getDoc()); + } } // core machinery @@ -1272,7 +1262,7 @@ private void addBuiltinModule(TruffleString name, PythonModule module) { private PythonModule createModule(TruffleString name, PythonBuiltins moduleBuiltins) { PythonModule mod = builtinModules.get(name); if (mod == null) { - mod = factory().createPythonModule(name); + mod = PFactory.createPythonModule(getLanguage(), name); if (moduleBuiltins != null) { mod.setBuiltins(moduleBuiltins); } @@ -1283,7 +1273,7 @@ private PythonModule createModule(TruffleString name, PythonBuiltins moduleBuilt private void addBuiltinsTo(PythonObject obj, PythonBuiltins builtinsForObj) { builtinsForObj.addConstantsToModuleObject(obj); - builtinsForObj.addFunctionsToModuleObject(obj, objectFactory); + builtinsForObj.addFunctionsToModuleObject(obj, getLanguage()); } @TruffleBoundary @@ -1309,7 +1299,7 @@ private void loadFile(TruffleString s, TruffleString prefix) { PythonModule mod = lookupBuiltinModule(s); if (mod == null) { // use an anonymous module for the side-effects - mod = factory().createPythonModule(T___ANONYMOUS__); + mod = PFactory.createPythonModule(getLanguage(), T___ANONYMOUS__); } loadFile(s, prefix, mod); } @@ -1319,16 +1309,14 @@ private void loadFile(TruffleString s, TruffleString prefix, PythonModule mod) { LOGGER.log(Level.FINE, () -> "import '" + s + "' # "); return; } + + LOGGER.log(Level.FINE, () -> "import '" + s + "'"); Supplier getCode = () -> { Source source = getInternalSource(s, prefix); return getLanguage().parse(getContext(), source, InputType.FILE, false, 0, false, null, EnumSet.noneOf(FutureFeature.class)); }; RootCallTarget callTarget = (RootCallTarget) getLanguage().cacheCode(s, getCode); - GenericInvokeNode.getUncached().execute(callTarget, PArguments.withGlobals(mod)); - } - - public final PythonObjectSlowPathFactory factory() { - return objectFactory; + CallDispatchers.SimpleIndirectInvokeNode.executeUncached(callTarget, PArguments.withGlobals(mod)); } public final PInt getTrue() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java index 8d586cc758..0b6b90a9b1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java @@ -25,50 +25,6 @@ */ package com.oracle.graal.python.builtins; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.ARRAY_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.ASYNC_GENERATOR_ASEND_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.ASYNC_GENERATOR_ATHROW_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.ASYNC_GENERATOR_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.BOOLEAN_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.BYTES_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.BYTE_ARRAY_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.COMPLEX_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.CONTEXT_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.COROUTINE_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.DEFAULTDICT_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.DEFAULT_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.DEQUE_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.DICTITEMSVIEW_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.DICTKEYSVIEW_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.DICTVALUESVIEW_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.DICT_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.FLOAT_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.FOREIGNNUMBER_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.FROZENSET_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.GENERATOR_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.GENERIC_ALIAS_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.INT_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.LIST_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.MAPPINGPROXY_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.MEMORYVIEW_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.MMAP_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.NONE_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.PYCARRAYTYPE_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.PYCARRAY_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.PYCFUNCPTRTYPE_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.PYCFUNCPTR_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.PYCPOINTERTYPE_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.PYCPOINTER_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.PYCSIMPLETYPE_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.PYCSTRUCTTYPE_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.RANGE_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.SET_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.SIMPLECDATA_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.STRING_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.TUPLE_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.TYPE_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.UNIONTYPE_M_FLAGS; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.UNION_TYPE_M_FLAGS; import static com.oracle.graal.python.nodes.BuiltinNames.J_BUILTINS; import static com.oracle.graal.python.nodes.BuiltinNames.J_DEFAULTDICT; import static com.oracle.graal.python.nodes.BuiltinNames.J_DEQUE; @@ -111,69 +67,207 @@ import java.util.stream.Collectors; import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.HashNotImplemented; import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.builtins.modules.StatResultBuiltins; import com.oracle.graal.python.builtins.modules.WeakRefModuleBuiltins; +import com.oracle.graal.python.builtins.modules.ast.AstBuiltins; +import com.oracle.graal.python.builtins.modules.bz2.BZ2CompressorBuiltins; +import com.oracle.graal.python.builtins.modules.bz2.BZ2DecompressorBuiltins; +import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteIncrementalDecoderBuiltins; +import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteIncrementalEncoderBuiltins; +import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteStreamReaderBuiltins; +import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteStreamWriterBuiltins; +import com.oracle.graal.python.builtins.modules.csv.CSVDialectBuiltins; +import com.oracle.graal.python.builtins.modules.csv.CSVReaderBuiltins; +import com.oracle.graal.python.builtins.modules.ctypes.CArgObjectBuiltins; +import com.oracle.graal.python.builtins.modules.ctypes.CDataBuiltins; import com.oracle.graal.python.builtins.modules.ctypes.CDataTypeSequenceBuiltins; import com.oracle.graal.python.builtins.modules.ctypes.CFieldBuiltins; import com.oracle.graal.python.builtins.modules.ctypes.PyCArrayBuiltins; +import com.oracle.graal.python.builtins.modules.ctypes.PyCArrayTypeBuiltins; import com.oracle.graal.python.builtins.modules.ctypes.PyCFuncPtrBuiltins; +import com.oracle.graal.python.builtins.modules.ctypes.PyCFuncPtrTypeBuiltins; import com.oracle.graal.python.builtins.modules.ctypes.PyCPointerBuiltins; +import com.oracle.graal.python.builtins.modules.ctypes.PyCPointerTypeBuiltins; +import com.oracle.graal.python.builtins.modules.ctypes.PyCSimpleTypeBuiltins; import com.oracle.graal.python.builtins.modules.ctypes.PyCStructTypeBuiltins; import com.oracle.graal.python.builtins.modules.ctypes.SimpleCDataBuiltins; import com.oracle.graal.python.builtins.modules.ctypes.StgDictBuiltins; +import com.oracle.graal.python.builtins.modules.ctypes.StructUnionTypeBuiltins; +import com.oracle.graal.python.builtins.modules.ctypes.StructureBuiltins; +import com.oracle.graal.python.builtins.modules.functools.KeyWrapperBuiltins; import com.oracle.graal.python.builtins.modules.functools.LruCacheWrapperBuiltins; +import com.oracle.graal.python.builtins.modules.functools.PartialBuiltins; +import com.oracle.graal.python.builtins.modules.hashlib.Blake2bObjectBuiltins; +import com.oracle.graal.python.builtins.modules.hashlib.HashObjectBuiltins; +import com.oracle.graal.python.builtins.modules.hashlib.Sha3Builtins; +import com.oracle.graal.python.builtins.modules.io.BufferedIOMixinBuiltins; +import com.oracle.graal.python.builtins.modules.io.BufferedRWPairBuiltins; +import com.oracle.graal.python.builtins.modules.io.BufferedRandomBuiltins; +import com.oracle.graal.python.builtins.modules.io.BufferedReaderBuiltins; +import com.oracle.graal.python.builtins.modules.io.BufferedReaderMixinBuiltins; +import com.oracle.graal.python.builtins.modules.io.BufferedWriterBuiltins; +import com.oracle.graal.python.builtins.modules.io.BytesIOBuiltins; +import com.oracle.graal.python.builtins.modules.io.FileIOBuiltins; +import com.oracle.graal.python.builtins.modules.io.IOBaseBuiltins; +import com.oracle.graal.python.builtins.modules.io.IncrementalNewlineDecoderBuiltins; +import com.oracle.graal.python.builtins.modules.io.StringIOBuiltins; +import com.oracle.graal.python.builtins.modules.io.TextIOWrapperBuiltins; +import com.oracle.graal.python.builtins.modules.json.JSONEncoderBuiltins; +import com.oracle.graal.python.builtins.modules.json.JSONScannerBuiltins; +import com.oracle.graal.python.builtins.modules.lsprof.ProfilerBuiltins; +import com.oracle.graal.python.builtins.modules.lzma.LZMACompressorBuiltins; +import com.oracle.graal.python.builtins.modules.lzma.LZMADecompressorBuiltins; +import com.oracle.graal.python.builtins.modules.multiprocessing.GraalPySemLockBuiltins; +import com.oracle.graal.python.builtins.modules.multiprocessing.SemLockBuiltins; +import com.oracle.graal.python.builtins.modules.pickle.PickleBufferBuiltins; +import com.oracle.graal.python.builtins.modules.pickle.PicklerBuiltins; +import com.oracle.graal.python.builtins.modules.pickle.PicklerMemoProxyBuiltins; +import com.oracle.graal.python.builtins.modules.pickle.UnpicklerBuiltins; +import com.oracle.graal.python.builtins.modules.pickle.UnpicklerMemoProxyBuiltins; import com.oracle.graal.python.builtins.objects.NoneBuiltins; +import com.oracle.graal.python.builtins.objects.NotImplementedBuiltins; import com.oracle.graal.python.builtins.objects.array.ArrayBuiltins; +import com.oracle.graal.python.builtins.objects.asyncio.ANextAwaitableBuiltins; +import com.oracle.graal.python.builtins.objects.asyncio.AsyncGenSendBuiltins; +import com.oracle.graal.python.builtins.objects.asyncio.AsyncGenThrowBuiltins; +import com.oracle.graal.python.builtins.objects.asyncio.AsyncGeneratorBuiltins; +import com.oracle.graal.python.builtins.objects.asyncio.CoroutineWrapperBuiltins; import com.oracle.graal.python.builtins.objects.bool.BoolBuiltins; import com.oracle.graal.python.builtins.objects.bytes.ByteArrayBuiltins; import com.oracle.graal.python.builtins.objects.bytes.BytesBuiltins; import com.oracle.graal.python.builtins.objects.bytes.BytesCommonBuiltins; +import com.oracle.graal.python.builtins.objects.cell.CellBuiltins; +import com.oracle.graal.python.builtins.objects.code.CodeBuiltins; import com.oracle.graal.python.builtins.objects.complex.ComplexBuiltins; import com.oracle.graal.python.builtins.objects.contextvars.ContextBuiltins; +import com.oracle.graal.python.builtins.objects.contextvars.ContextIteratorBuiltins; +import com.oracle.graal.python.builtins.objects.contextvars.ContextVarBuiltins; +import com.oracle.graal.python.builtins.objects.contextvars.TokenBuiltins; import com.oracle.graal.python.builtins.objects.deque.DequeBuiltins; +import com.oracle.graal.python.builtins.objects.deque.DequeIterBuiltins; +import com.oracle.graal.python.builtins.objects.deque.DequeIterCommonBuiltins; +import com.oracle.graal.python.builtins.objects.deque.DequeRevIterBuiltins; import com.oracle.graal.python.builtins.objects.dict.DefaultDictBuiltins; import com.oracle.graal.python.builtins.objects.dict.DictBuiltins; +import com.oracle.graal.python.builtins.objects.dict.DictReprBuiltin; import com.oracle.graal.python.builtins.objects.dict.DictValuesBuiltins; import com.oracle.graal.python.builtins.objects.dict.DictViewBuiltins; +import com.oracle.graal.python.builtins.objects.ellipsis.EllipsisBuiltins; +import com.oracle.graal.python.builtins.objects.enumerate.EnumerateBuiltins; +import com.oracle.graal.python.builtins.objects.exception.AttributeErrorBuiltins; +import com.oracle.graal.python.builtins.objects.exception.BaseExceptionBuiltins; +import com.oracle.graal.python.builtins.objects.exception.BaseExceptionGroupBuiltins; +import com.oracle.graal.python.builtins.objects.exception.ImportErrorBuiltins; +import com.oracle.graal.python.builtins.objects.exception.KeyErrorBuiltins; +import com.oracle.graal.python.builtins.objects.exception.OsErrorBuiltins; +import com.oracle.graal.python.builtins.objects.exception.StopIterationBuiltins; +import com.oracle.graal.python.builtins.objects.exception.SyntaxErrorBuiltins; +import com.oracle.graal.python.builtins.objects.exception.SystemExitBuiltins; +import com.oracle.graal.python.builtins.objects.exception.UnicodeDecodeErrorBuiltins; +import com.oracle.graal.python.builtins.objects.exception.UnicodeEncodeErrorBuiltins; +import com.oracle.graal.python.builtins.objects.exception.UnicodeTranslateErrorBuiltins; import com.oracle.graal.python.builtins.objects.floats.FloatBuiltins; import com.oracle.graal.python.builtins.objects.foreign.ForeignBooleanBuiltins; +import com.oracle.graal.python.builtins.objects.foreign.ForeignExecutableBuiltins; +import com.oracle.graal.python.builtins.objects.foreign.ForeignInstantiableBuiltins; +import com.oracle.graal.python.builtins.objects.foreign.ForeignIterableBuiltins; import com.oracle.graal.python.builtins.objects.foreign.ForeignNumberBuiltins; import com.oracle.graal.python.builtins.objects.foreign.ForeignObjectBuiltins; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; +import com.oracle.graal.python.builtins.objects.frame.FrameBuiltins; +import com.oracle.graal.python.builtins.objects.function.AbstractFunctionBuiltins; import com.oracle.graal.python.builtins.objects.function.FunctionBuiltins; import com.oracle.graal.python.builtins.objects.function.MethodDescriptorBuiltins; import com.oracle.graal.python.builtins.objects.function.WrapperDescriptorBuiltins; +import com.oracle.graal.python.builtins.objects.generator.CoroutineBuiltins; +import com.oracle.graal.python.builtins.objects.generator.GeneratorBuiltins; import com.oracle.graal.python.builtins.objects.getsetdescriptor.GetSetDescriptorTypeBuiltins; import com.oracle.graal.python.builtins.objects.getsetdescriptor.MemberDescriptorBuiltins; import com.oracle.graal.python.builtins.objects.ints.IntBuiltins; +import com.oracle.graal.python.builtins.objects.iterator.IteratorBuiltins; +import com.oracle.graal.python.builtins.objects.iterator.SentinelIteratorBuiltins; +import com.oracle.graal.python.builtins.objects.iterator.ZipBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.AccumulateBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.ChainBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.CombinationsBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.CombinationsWithReplacementBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.CompressBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.CountBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.CycleBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.DropwhileBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.FilterfalseBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.GroupByBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.GrouperBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.IsliceBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.PairwiseBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.PermutationsBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.ProductBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.RepeatBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.StarmapBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.TakewhileBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.TeeBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.TeeDataObjectBuiltins; +import com.oracle.graal.python.builtins.objects.itertools.ZipLongestBuiltins; import com.oracle.graal.python.builtins.objects.list.ListBuiltins; +import com.oracle.graal.python.builtins.objects.map.MapBuiltins; import com.oracle.graal.python.builtins.objects.mappingproxy.MappingproxyBuiltins; import com.oracle.graal.python.builtins.objects.memoryview.MemoryViewBuiltins; +import com.oracle.graal.python.builtins.objects.method.AbstractMethodBuiltins; +import com.oracle.graal.python.builtins.objects.method.BuiltinClassmethodBuiltins; +import com.oracle.graal.python.builtins.objects.method.BuiltinFunctionOrMethodBuiltins; import com.oracle.graal.python.builtins.objects.method.ClassmethodBuiltins; +import com.oracle.graal.python.builtins.objects.method.ClassmethodCommonBuiltins; import com.oracle.graal.python.builtins.objects.method.InstancemethodBuiltins; import com.oracle.graal.python.builtins.objects.method.MethodBuiltins; +import com.oracle.graal.python.builtins.objects.method.MethodWrapperBuiltins; import com.oracle.graal.python.builtins.objects.method.StaticmethodBuiltins; import com.oracle.graal.python.builtins.objects.mmap.MMapBuiltins; import com.oracle.graal.python.builtins.objects.module.ModuleBuiltins; +import com.oracle.graal.python.builtins.objects.namespace.SimpleNamespaceBuiltins; import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins; import com.oracle.graal.python.builtins.objects.ordereddict.OrderedDictBuiltins; +import com.oracle.graal.python.builtins.objects.ordereddict.OrderedDictItemsBuiltins; +import com.oracle.graal.python.builtins.objects.ordereddict.OrderedDictIteratorBuiltins; +import com.oracle.graal.python.builtins.objects.ordereddict.OrderedDictKeysBuiltins; +import com.oracle.graal.python.builtins.objects.ordereddict.OrderedDictValuesBuiltins; +import com.oracle.graal.python.builtins.objects.posix.DirEntryBuiltins; +import com.oracle.graal.python.builtins.objects.posix.ScandirIteratorBuiltins; import com.oracle.graal.python.builtins.objects.property.PropertyBuiltins; +import com.oracle.graal.python.builtins.objects.queue.SimpleQueueBuiltins; +import com.oracle.graal.python.builtins.objects.random.RandomBuiltins; import com.oracle.graal.python.builtins.objects.range.RangeBuiltins; +import com.oracle.graal.python.builtins.objects.referencetype.ReferenceTypeBuiltins; +import com.oracle.graal.python.builtins.objects.reversed.ReversedBuiltins; import com.oracle.graal.python.builtins.objects.set.BaseSetBuiltins; +import com.oracle.graal.python.builtins.objects.set.FrozenSetBuiltins; +import com.oracle.graal.python.builtins.objects.set.SetBuiltins; +import com.oracle.graal.python.builtins.objects.slice.SliceBuiltins; +import com.oracle.graal.python.builtins.objects.socket.SocketBuiltins; +import com.oracle.graal.python.builtins.objects.ssl.MemoryBIOBuiltins; +import com.oracle.graal.python.builtins.objects.ssl.SSLContextBuiltins; +import com.oracle.graal.python.builtins.objects.ssl.SSLErrorBuiltins; import com.oracle.graal.python.builtins.objects.str.StringBuiltins; +import com.oracle.graal.python.builtins.objects.struct.StructBuiltins; +import com.oracle.graal.python.builtins.objects.struct.StructUnpackIteratorBuiltins; import com.oracle.graal.python.builtins.objects.superobject.SuperBuiltins; +import com.oracle.graal.python.builtins.objects.thread.CommonLockBuiltins; +import com.oracle.graal.python.builtins.objects.thread.LockTypeBuiltins; +import com.oracle.graal.python.builtins.objects.thread.RLockBuiltins; import com.oracle.graal.python.builtins.objects.thread.ThreadLocalBuiltins; +import com.oracle.graal.python.builtins.objects.tokenize.TokenizerIterBuiltins; +import com.oracle.graal.python.builtins.objects.traceback.TracebackBuiltins; +import com.oracle.graal.python.builtins.objects.tuple.InstantiableStructSequenceBuiltins; +import com.oracle.graal.python.builtins.objects.tuple.StructSequenceBuiltins; import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins; import com.oracle.graal.python.builtins.objects.tuple.TupleGetterBuiltins; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; -import com.oracle.graal.python.builtins.objects.type.TpSlots.Builder; import com.oracle.graal.python.builtins.objects.type.TypeBuiltins; import com.oracle.graal.python.builtins.objects.types.GenericAliasBuiltins; +import com.oracle.graal.python.builtins.objects.types.GenericAliasIteratorBuiltins; import com.oracle.graal.python.builtins.objects.types.UnionTypeBuiltins; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.TruffleOptions; import com.oracle.truffle.api.interop.TruffleObject; @@ -189,405 +283,954 @@ @ExportLibrary(ReflectionLibrary.class) public enum PythonBuiltinClassType implements TruffleObject { - Boolean("bool", J_BUILTINS, Flags.PUBLIC_DERIVED_WODICT, BOOLEAN_M_FLAGS, BoolBuiltins.SLOTS), - PArray("array", "array", ARRAY_M_FLAGS, ArrayBuiltins.SLOTS), - PArrayIterator("arrayiterator", Flags.PRIVATE_DERIVED_WODICT), - PIterator("iterator", Flags.PRIVATE_DERIVED_WODICT), + PythonObject("object", null, newBuilder().publishInModule(J_BUILTINS).basetype().slots(ObjectBuiltins.SLOTS).doc(""" + The base class of the class hierarchy. + + When called, it accepts no arguments and returns a new featureless + instance that has no instance attributes and cannot be given any. + """)), + PythonClass("type", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(TypeBuiltins.SLOTS).doc(""" + type(object) -> the object's type + type(name, bases, dict, **kwds) -> a new type""")), + PArray("array", PythonObject, newBuilder().publishInModule("array").basetype().slots(ArrayBuiltins.SLOTS)), + PArrayIterator("arrayiterator", PythonObject, newBuilder().disallowInstantiation().slots(IteratorBuiltins.SLOTS)), + PIterator("iterator", PythonObject, newBuilder().disallowInstantiation().slots(IteratorBuiltins.SLOTS)), /** See {@link com.oracle.graal.python.builtins.objects.function.PBuiltinFunction} */ - PBuiltinFunction("method_descriptor", Flags.PRIVATE_DERIVED_WODICT, MethodDescriptorBuiltins.SLOTS), + PBuiltinFunction("method_descriptor", PythonObject, newBuilder().disallowInstantiation().slots(AbstractFunctionBuiltins.SLOTS, MethodDescriptorBuiltins.SLOTS)), /** See {@link com.oracle.graal.python.builtins.objects.method.PBuiltinMethod} */ - PBuiltinFunctionOrMethod("builtin_function_or_method", Flags.PRIVATE_DERIVED_WODICT), + PBuiltinFunctionOrMethod( + "builtin_function_or_method", + PythonObject, + newBuilder().disallowInstantiation().slots(AbstractMethodBuiltins.SLOTS, BuiltinFunctionOrMethodBuiltins.SLOTS)), /** See {@link com.oracle.graal.python.builtins.objects.function.PBuiltinFunction} */ - WrapperDescriptor(J_WRAPPER_DESCRIPTOR, Flags.PRIVATE_DERIVED_WODICT, WrapperDescriptorBuiltins.SLOTS), + WrapperDescriptor(J_WRAPPER_DESCRIPTOR, PythonObject, newBuilder().disallowInstantiation().slots(AbstractFunctionBuiltins.SLOTS, WrapperDescriptorBuiltins.SLOTS)), /** See {@link com.oracle.graal.python.builtins.objects.method.PBuiltinMethod} */ - MethodWrapper("method-wrapper", Flags.PRIVATE_DERIVED_WODICT), + MethodWrapper("method-wrapper", PythonObject, newBuilder().slots(AbstractMethodBuiltins.SLOTS, MethodWrapperBuiltins.SLOTS)), /** See {@link com.oracle.graal.python.builtins.objects.method.PBuiltinMethod} */ - PBuiltinMethod("builtin_method", Flags.PRIVATE_DERIVED_WODICT), - PBuiltinClassMethod("classmethod_descriptor", Flags.PRIVATE_DERIVED_WODICT, ClassmethodBuiltins.SLOTS), - GetSetDescriptor("getset_descriptor", Flags.PRIVATE_DERIVED_WODICT, GetSetDescriptorTypeBuiltins.SLOTS), - MemberDescriptor(J_MEMBER_DESCRIPTOR, Flags.PRIVATE_DERIVED_WODICT, MemberDescriptorBuiltins.SLOTS), - PByteArray("bytearray", J_BUILTINS, BYTE_ARRAY_M_FLAGS, TpSlots.merge(BytesCommonBuiltins.SLOTS, ByteArrayBuiltins.SLOTS)), - PBytes("bytes", J_BUILTINS, BYTES_M_FLAGS, TpSlots.merge(BytesCommonBuiltins.SLOTS, BytesBuiltins.SLOTS)), - PCell("cell", Flags.PRIVATE_DERIVED_WODICT), - PSimpleNamespace("SimpleNamespace", null, "types", Flags.PUBLIC_BASE_WDICT), - PKeyWrapper("KeyWrapper", "_functools", "functools", Flags.PUBLIC_DERIVED_WODICT), - PPartial(J_PARTIAL, "_functools", "functools", Flags.PUBLIC_BASE_WDICT), - PLruListElem("_lru_list_elem", null, "functools", Flags.PUBLIC_DERIVED_WODICT), - PLruCacheWrapper(J_LRU_CACHE_WRAPPER, "_functools", "functools", Flags.PUBLIC_BASE_WDICT, LruCacheWrapperBuiltins.SLOTS), - PDefaultDict(J_DEFAULTDICT, "_collections", "collections", Flags.PUBLIC_BASE_WODICT, DEFAULTDICT_M_FLAGS, DefaultDictBuiltins.SLOTS), - PDeque(J_DEQUE, "_collections", Flags.PUBLIC_BASE_WODICT, DEQUE_M_FLAGS, DequeBuiltins.SLOTS), - PTupleGetter(J_TUPLE_GETTER, "_collections", Flags.PUBLIC_BASE_WODICT, TupleGetterBuiltins.SLOTS), - PDequeIter(J_DEQUE_ITER, "_collections", Flags.PUBLIC_DERIVED_WODICT), - PDequeRevIter(J_DEQUE_REV_ITER, "_collections", Flags.PUBLIC_DERIVED_WODICT), - POrderedDict(J_ORDERED_DICT, "_collections", Flags.PUBLIC_BASE_WDICT, DICT_M_FLAGS, OrderedDictBuiltins.SLOTS), - POrderedDictKeys("odict_keys", Flags.PRIVATE_DERIVED_WODICT, DICTKEYSVIEW_M_FLAGS), - POrderedDictValues("odict_values", Flags.PRIVATE_DERIVED_WODICT, DICTVALUESVIEW_M_FLAGS), - POrderedDictItems("odict_items", Flags.PRIVATE_DERIVED_WODICT, DICTITEMSVIEW_M_FLAGS), - POrderedDictIterator("odict_iterator", Flags.PRIVATE_DERIVED_WODICT), - PComplex("complex", J_BUILTINS, COMPLEX_M_FLAGS, ComplexBuiltins.SLOTS), - PDict("dict", J_BUILTINS, DICT_M_FLAGS, DictBuiltins.SLOTS), - PDictItemIterator(J_DICT_ITEMITERATOR, Flags.PRIVATE_DERIVED_WODICT), - PDictReverseItemIterator(J_DICT_REVERSE_ITEMITERATOR, Flags.PRIVATE_DERIVED_WODICT), - PDictItemsView(J_DICT_ITEMS, Flags.PRIVATE_DERIVED_WODICT, DICTITEMSVIEW_M_FLAGS, DictViewBuiltins.SLOTS), - PDictKeyIterator(J_DICT_KEYITERATOR, Flags.PRIVATE_DERIVED_WODICT), - PDictReverseKeyIterator(J_DICT_REVERSE_KEYITERATOR, Flags.PRIVATE_DERIVED_WODICT), - PDictKeysView(J_DICT_KEYS, Flags.PRIVATE_DERIVED_WODICT, DICTKEYSVIEW_M_FLAGS, DictViewBuiltins.SLOTS), - PDictValueIterator(J_DICT_VALUEITERATOR, Flags.PRIVATE_DERIVED_WODICT), - PDictReverseValueIterator(J_DICT_REVERSE_VALUEITERATOR, Flags.PRIVATE_DERIVED_WODICT), - PDictValuesView(J_DICT_VALUES, Flags.PRIVATE_DERIVED_WODICT, DICTVALUESVIEW_M_FLAGS, DictValuesBuiltins.SLOTS), - PEllipsis("ellipsis", Flags.PRIVATE_DERIVED_WODICT), - PEnumerate("enumerate", J_BUILTINS), - PMap("map", J_BUILTINS), - PFloat("float", J_BUILTINS, FLOAT_M_FLAGS, FloatBuiltins.SLOTS), - PFrame("frame", Flags.PRIVATE_DERIVED_WODICT), - PFrozenSet("frozenset", J_BUILTINS, FROZENSET_M_FLAGS, BaseSetBuiltins.SLOTS), - PFunction("function", Flags.PRIVATE_DERIVED_WDICT, FunctionBuiltins.SLOTS), - PGenerator("generator", Flags.PRIVATE_DERIVED_WODICT, GENERATOR_M_FLAGS), - PCoroutine("coroutine", Flags.PRIVATE_DERIVED_WODICT, COROUTINE_M_FLAGS), - PCoroutineWrapper("coroutine_wrapper", Flags.PRIVATE_DERIVED_WODICT), - PAsyncGenerator("async_generator", Flags.PRIVATE_DERIVED_WODICT, ASYNC_GENERATOR_M_FLAGS), - PInt("int", J_BUILTINS, INT_M_FLAGS, IntBuiltins.SLOTS), - PList("list", J_BUILTINS, LIST_M_FLAGS, ListBuiltins.SLOTS), - PMappingproxy("mappingproxy", Flags.PRIVATE_DERIVED_WODICT, MAPPINGPROXY_M_FLAGS, MappingproxyBuiltins.SLOTS), - PMemoryView("memoryview", J_BUILTINS, Flags.PUBLIC_DERIVED_WODICT, MEMORYVIEW_M_FLAGS, MemoryViewBuiltins.SLOTS), - PAsyncGenASend("async_generator_asend", Flags.PRIVATE_DERIVED_WODICT, ASYNC_GENERATOR_ASEND_M_FLAGS), - PAsyncGenAThrow("async_generator_athrow", Flags.PRIVATE_DERIVED_WODICT, ASYNC_GENERATOR_ATHROW_M_FLAGS), - PAsyncGenAWrappedValue("async_generator_wrapped_value", Flags.PRIVATE_DERIVED_WODICT), - PMethod("method", Flags.PRIVATE_DERIVED_WODICT, MethodBuiltins.SLOTS), - PMMap("mmap", "mmap", MMAP_M_FLAGS, MMapBuiltins.SLOTS), - PNone("NoneType", Flags.PRIVATE_DERIVED_WODICT, NONE_M_FLAGS, NoneBuiltins.SLOTS), - PNotImplemented("NotImplementedType", Flags.PRIVATE_DERIVED_WODICT), - PProperty(J_PROPERTY, J_BUILTINS, Flags.PUBLIC_BASE_WODICT, PropertyBuiltins.SLOTS), - PSimpleQueue(J_SIMPLE_QUEUE, "_queue", Flags.PUBLIC_BASE_WODICT), - PRandom("Random", "_random"), - PRange("range", J_BUILTINS, Flags.PUBLIC_DERIVED_WODICT, RANGE_M_FLAGS, RangeBuiltins.SLOTS), - PReferenceType("ReferenceType", "_weakref"), - PSentinelIterator("callable_iterator", Flags.PRIVATE_DERIVED_WODICT), - PReverseIterator("reversed", J_BUILTINS), - PSet("set", J_BUILTINS, SET_M_FLAGS, BaseSetBuiltins.SLOTS), - PSlice("slice", J_BUILTINS), - PString("str", J_BUILTINS, STRING_M_FLAGS, StringBuiltins.SLOTS), - PTraceback("traceback"), - PTuple("tuple", J_BUILTINS, TUPLE_M_FLAGS, TupleBuiltins.SLOTS), - PythonClass("type", J_BUILTINS, Flags.PUBLIC_BASE_WDICT, TYPE_M_FLAGS, TypeBuiltins.SLOTS), - PythonModule("module", Flags.PRIVATE_BASE_WDICT, ModuleBuiltins.SLOTS), - PythonModuleDef("moduledef", Flags.PRIVATE_DERIVED_WODICT), - PythonObject("object", J_BUILTINS, ObjectBuiltins.SLOTS), - Super("super", J_BUILTINS, SuperBuiltins.SLOTS), - PCode("code", Flags.PRIVATE_DERIVED_WODICT), - PGenericAlias("GenericAlias", J_TYPES, Flags.PUBLIC_BASE_WODICT, GENERIC_ALIAS_M_FLAGS, GenericAliasBuiltins.SLOTS), - PGenericAliasIterator("generic_alias_iterator", Flags.PRIVATE_DERIVED_WODICT), - PUnionType("UnionType", J_TYPES, Flags.PUBLIC_DERIVED_WODICT, UNION_TYPE_M_FLAGS, UnionTypeBuiltins.SLOTS), - PZip("zip", J_BUILTINS), - PThread("start_new_thread", J__THREAD), - PThreadLocal("_local", J__THREAD, ThreadLocalBuiltins.SLOTS), - PLock("LockType", J__THREAD), - PRLock("RLock", J__THREAD), - PSemLock("SemLock", "_multiprocessing"), - PGraalPySemLock("SemLock", "_multiprocessing_graalpy"), - PSocket("socket", J__SOCKET), - PStaticmethod("staticmethod", J_BUILTINS, Flags.PUBLIC_BASE_WDICT, StaticmethodBuiltins.SLOTS), - PClassmethod("classmethod", J_BUILTINS, Flags.PUBLIC_BASE_WDICT, ClassmethodBuiltins.SLOTS), - PInstancemethod("instancemethod", Flags.PUBLIC_BASE_WDICT, InstancemethodBuiltins.SLOTS), - PScandirIterator("ScandirIterator", J_POSIX, Flags.PRIVATE_DERIVED_WODICT), - PDirEntry("DirEntry", J_POSIX, Flags.PUBLIC_DERIVED_WODICT), - LsprofProfiler("Profiler", "_lsprof"), - PStruct("Struct", J__STRUCT), - PStructUnpackIterator("unpack_iterator", J__STRUCT), - Pickler("Pickler", "_pickle"), - PicklerMemoProxy("PicklerMemoProxy", "_pickle"), - UnpicklerMemoProxy("UnpicklerMemoProxy", "_pickle"), - Unpickler("Unpickler", "_pickle"), - PickleBuffer("PickleBuffer", "_pickle"), + PBuiltinMethod("builtin_method", PBuiltinFunctionOrMethod, newBuilder()), + PBuiltinClassMethod("classmethod_descriptor", PythonObject, newBuilder().slots(ClassmethodCommonBuiltins.SLOTS, BuiltinClassmethodBuiltins.SLOTS)), + GetSetDescriptor("getset_descriptor", PythonObject, newBuilder().disallowInstantiation().slots(GetSetDescriptorTypeBuiltins.SLOTS)), + MemberDescriptor(J_MEMBER_DESCRIPTOR, PythonObject, newBuilder().disallowInstantiation().slots(MemberDescriptorBuiltins.SLOTS)), + PByteArray( + "bytearray", + PythonObject, + newBuilder().publishInModule(J_BUILTINS).basetype().slots(BytesCommonBuiltins.SLOTS, ByteArrayBuiltins.SLOTS).doc(""" + bytearray(iterable_of_ints) -> bytearray + bytearray(string, encoding[, errors]) -> bytearray + bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer + bytearray(int) -> bytes array of size given by the parameter initialized with null bytes + bytearray() -> empty bytes array + + Construct a mutable bytearray object from: + - an iterable yielding integers in range(256) + - a text string encoded using the specified encoding + - a bytes or a buffer object + - any object implementing the buffer API. + - an integer""")), + PBytes("bytes", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().slots(BytesCommonBuiltins.SLOTS, BytesBuiltins.SLOTS).doc(""" + bytes(iterable_of_ints) -> bytes + bytes(string, encoding[, errors]) -> bytes + bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer + bytes(int) -> bytes object of size given by the parameter initialized with null bytes + bytes() -> empty bytes object + + Construct an immutable array of bytes from: + - an iterable yielding integers in range(256) + - a text string encoded using the specified encoding + - any object implementing the buffer API. + - an integer""")), + PCell("cell", PythonObject, newBuilder().slots(CellBuiltins.SLOTS)), + PSimpleNamespace("SimpleNamespace", PythonObject, newBuilder().publishInModule("types").basetype().addDict().slots(SimpleNamespaceBuiltins.SLOTS).doc(""" + A simple attribute-based namespace. + + SimpleNamespace(**kwargs)""")), + PKeyWrapper("KeyWrapper", PythonObject, newBuilder().moduleName("functools").publishInModule("_functools").disallowInstantiation().slots(KeyWrapperBuiltins.SLOTS)), + PPartial(J_PARTIAL, PythonObject, newBuilder().moduleName("functools").publishInModule("_functools").basetype().addDict().slots(PartialBuiltins.SLOTS).doc(""" + partial(func, *args, **keywords) - new function with partial application + of the given arguments and keywords. + """)), + PLruListElem("_lru_list_elem", PythonObject, newBuilder().publishInModule("functools").disallowInstantiation()), + PLruCacheWrapper(J_LRU_CACHE_WRAPPER, PythonObject, newBuilder().moduleName("functools").publishInModule("_functools").basetype().addDict().slots(LruCacheWrapperBuiltins.SLOTS).doc(""" + Create a cached callable that wraps another function. + + user_function: the function being cached + + maxsize: 0 for no caching + None for unlimited cache size + n for a bounded cache + + typed: False cache f(3) and f(3.0) as identical calls + True cache f(3) and f(3.0) as distinct calls + + cache_info_type: namedtuple class with the fields: + hits misses currsize maxsize + """)), + PDeque(J_DEQUE, PythonObject, newBuilder().publishInModule("_collections").basetype().slots(DequeBuiltins.SLOTS)), + PTupleGetter(J_TUPLE_GETTER, PythonObject, newBuilder().publishInModule("_collections").basetype().slots(TupleGetterBuiltins.SLOTS)), + PDequeIter(J_DEQUE_ITER, PythonObject, newBuilder().publishInModule("_collections").slots(DequeIterCommonBuiltins.SLOTS, DequeIterBuiltins.SLOTS)), + PDequeRevIter(J_DEQUE_REV_ITER, PythonObject, newBuilder().publishInModule("_collections").slots(DequeIterCommonBuiltins.SLOTS, DequeRevIterBuiltins.SLOTS)), + PComplex("complex", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().slots(ComplexBuiltins.SLOTS).doc(""" + Create a complex number from a real part and an optional imaginary part. + + This is equivalent to (real + imag*1j) where imag defaults to 0.""")), + PDict("dict", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().slots(DictBuiltins.SLOTS, DictReprBuiltin.SLOTS).doc(""" + dict() -> new empty dictionary + dict(mapping) -> new dictionary initialized from a mapping object's + (key, value) pairs + dict(iterable) -> new dictionary initialized as if via: + d = {} + for k, v in iterable: + d[k] = v + dict(**kwargs) -> new dictionary initialized with the name=value pairs + in the keyword argument list. For example: dict(one=1, two=2)""")), + PDefaultDict(J_DEFAULTDICT, PDict, newBuilder().moduleName("collections").publishInModule("_collections").basetype().slots(DefaultDictBuiltins.SLOTS)), + POrderedDict(J_ORDERED_DICT, PDict, newBuilder().publishInModule("_collections").basetype().addDict().slots(OrderedDictBuiltins.SLOTS)), + PDictItemIterator(J_DICT_ITEMITERATOR, PythonObject, newBuilder().disallowInstantiation().slots(IteratorBuiltins.SLOTS)), + PDictReverseItemIterator(J_DICT_REVERSE_ITEMITERATOR, PythonObject, newBuilder().slots(IteratorBuiltins.SLOTS)), + PDictItemsView(J_DICT_ITEMS, PythonObject, newBuilder().disallowInstantiation().slots(DictViewBuiltins.SLOTS, DictReprBuiltin.SLOTS)), + PDictKeyIterator(J_DICT_KEYITERATOR, PythonObject, newBuilder().disallowInstantiation().slots(IteratorBuiltins.SLOTS)), + PDictReverseKeyIterator(J_DICT_REVERSE_KEYITERATOR, PythonObject, newBuilder().slots(IteratorBuiltins.SLOTS)), + PDictKeysView(J_DICT_KEYS, PythonObject, newBuilder().disallowInstantiation().slots(DictViewBuiltins.SLOTS, DictReprBuiltin.SLOTS)), + PDictValueIterator(J_DICT_VALUEITERATOR, PythonObject, newBuilder().disallowInstantiation().slots(IteratorBuiltins.SLOTS)), + PDictReverseValueIterator(J_DICT_REVERSE_VALUEITERATOR, PythonObject, newBuilder().slots(IteratorBuiltins.SLOTS)), + PDictValuesView(J_DICT_VALUES, PythonObject, newBuilder().disallowInstantiation().slots(DictValuesBuiltins.SLOTS, DictReprBuiltin.SLOTS)), + POrderedDictKeys("odict_keys", PDictKeysView, newBuilder().slots(OrderedDictKeysBuiltins.SLOTS)), + POrderedDictValues("odict_values", PDictValuesView, newBuilder().slots(OrderedDictValuesBuiltins.SLOTS)), + POrderedDictItems("odict_items", PDictItemsView, newBuilder().slots(OrderedDictItemsBuiltins.SLOTS)), + POrderedDictIterator("odict_iterator", PythonObject, newBuilder().slots(OrderedDictIteratorBuiltins.SLOTS)), + PEllipsis("ellipsis", PythonObject, newBuilder().slots(EllipsisBuiltins.SLOTS)), + PEnumerate("enumerate", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().slots(EnumerateBuiltins.SLOTS).doc(""" + Return an enumerate object. + + iterable + an object supporting iteration + + The enumerate object yields pairs containing a count (from start, which + defaults to zero) and a value yielded by the iterable argument. + + enumerate is useful for obtaining an indexed list: + (0, seq[0]), (1, seq[1]), (2, seq[2]), ...""")), + PMap("map", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().slots(MapBuiltins.SLOTS).doc(""" + map(func, *iterables) --> map object + + Make an iterator that computes the function using arguments from + each of the iterables. Stops when the shortest iterable is exhausted.""")), + PFloat( + "float", + PythonObject, + newBuilder().publishInModule(J_BUILTINS).basetype().slots(FloatBuiltins.SLOTS).doc(""" + Convert a string or number to a floating point number, if possible.""")), + PFrame("frame", PythonObject, newBuilder().disallowInstantiation().slots(FrameBuiltins.SLOTS)), + PFrozenSet( + "frozenset", + PythonObject, + newBuilder().publishInModule(J_BUILTINS).basetype().slots(BaseSetBuiltins.SLOTS, FrozenSetBuiltins.SLOTS).doc(""" + frozenset() -> empty frozenset object + frozenset(iterable) -> frozenset object + + Build an immutable unordered collection of unique elements.""")), + PFunction("function", PythonObject, newBuilder().addDict().slots(AbstractFunctionBuiltins.SLOTS, FunctionBuiltins.SLOTS)), + PGenerator("generator", PythonObject, newBuilder().disallowInstantiation().slots(GeneratorBuiltins.SLOTS)), + PCoroutine("coroutine", PythonObject, newBuilder().slots(CoroutineBuiltins.SLOTS)), + PCoroutineWrapper("coroutine_wrapper", PythonObject, newBuilder().slots(CoroutineWrapperBuiltins.SLOTS)), + PAsyncGenerator("async_generator", PythonObject, newBuilder().slots(AsyncGeneratorBuiltins.SLOTS)), + PAnextAwaitable("anext_awaitable", PythonObject, newBuilder().slots(ANextAwaitableBuiltins.SLOTS)), + PInt("int", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().slots(IntBuiltins.SLOTS).doc(""" + int([x]) -> integer + int(x, base=10) -> integer + + Convert a number or string to an integer, or return 0 if no arguments + are given. If x is a number, return x.__int__(). For floating point + numbers, this truncates towards zero. + + If x is not a number or if base is given, then x must be a string, + bytes, or bytearray instance representing an integer literal in the + given base. The literal can be preceded by '+' or '-' and be surrounded + by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. + Base 0 means to interpret the base from the string as an integer literal.""")), + Boolean("bool", PInt, newBuilder().publishInModule(J_BUILTINS).slots(BoolBuiltins.SLOTS).doc(""" + bool(x) -> bool + + Returns True when the argument x is true, False otherwise. + The builtins True and False are the only two instances of the class bool. + The class bool is a subclass of the class int, and cannot be subclassed.""")), + PList("list", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().slots(ListBuiltins.SLOTS).doc(""" + Built-in mutable sequence. + + If no argument is given, the constructor creates a new empty list. + The argument must be an iterable if specified.""")), + PMappingproxy("mappingproxy", PythonObject, newBuilder().slots(MappingproxyBuiltins.SLOTS)), + PMemoryView( + "memoryview", + PythonObject, + newBuilder().publishInModule(J_BUILTINS).slots(MemoryViewBuiltins.SLOTS).doc(""" + Create a new memoryview object which references the given object.""")), + PAsyncGenASend("async_generator_asend", PythonObject, newBuilder().slots(AsyncGenSendBuiltins.SLOTS)), + PAsyncGenAThrow("async_generator_athrow", PythonObject, newBuilder().slots(AsyncGenThrowBuiltins.SLOTS)), + PAsyncGenAWrappedValue("async_generator_wrapped_value", PythonObject, newBuilder()), + PMethod("method", PythonObject, newBuilder().slots(AbstractMethodBuiltins.SLOTS, MethodBuiltins.SLOTS).doc(""" + Create a bound instance method object.""")), + PMMap("mmap", PythonObject, newBuilder().publishInModule("mmap").basetype().slots(MMapBuiltins.SLOTS)), + PNone("NoneType", PythonObject, newBuilder().slots(NoneBuiltins.SLOTS)), + PNotImplemented("NotImplementedType", PythonObject, newBuilder().slots(NotImplementedBuiltins.SLOTS)), + PProperty(J_PROPERTY, PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().slots(PropertyBuiltins.SLOTS).doc(""" + Property attribute. + + fget + function to be used for getting an attribute value + fset + function to be used for setting an attribute value + fdel + function to be used for del'ing an attribute + doc + docstring + + Typical use is to define a managed attribute x: + + class C(object): + def getx(self): return self._x + def setx(self, value): self._x = value + def delx(self): del self._x + x = property(getx, setx, delx, "I'm the 'x' property.") + + Decorators make defining new properties or modifying existing ones easy: + + class C(object): + @property + def x(self): + "I am the 'x' property." + return self._x + @x.setter + def x(self, value): + self._x = value + @x.deleter + def x(self): + del self._x""")), + PSimpleQueue( + J_SIMPLE_QUEUE, + PythonObject, + newBuilder().publishInModule("_queue").basetype().slots(SimpleQueueBuiltins.SLOTS).doc(""" + SimpleQueue() + -- + + Simple, unbounded, reentrant FIFO queue.""")), + PRandom("Random", PythonObject, newBuilder().publishInModule("_random").basetype().slots(RandomBuiltins.SLOTS)), + PRange("range", PythonObject, newBuilder().publishInModule(J_BUILTINS).slots(RangeBuiltins.SLOTS).doc(""" + range(stop) -> range object + range(start, stop[, step]) -> range object + + Return an object that produces a sequence of integers from start (inclusive) + to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1. + start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3. + These are exactly the valid indices for a list of 4 elements. + When step is given, it specifies the increment (or decrement).""")), + PReferenceType("ReferenceType", PythonObject, newBuilder().publishInModule("_weakref").basetype().slots(ReferenceTypeBuiltins.SLOTS)), + PSentinelIterator("callable_iterator", PythonObject, newBuilder().disallowInstantiation().slots(SentinelIteratorBuiltins.SLOTS)), + PReverseIterator("reversed", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().slots(ReversedBuiltins.SLOTS).doc(""" + Return a reverse iterator over the values of the given sequence.""")), + PSet("set", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().slots(BaseSetBuiltins.SLOTS, SetBuiltins.SLOTS).doc(""" + set() -> new empty set object + set(iterable) -> new set object + + Build an unordered collection of unique elements.""")), + PSlice("slice", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().slots(SliceBuiltins.SLOTS).doc(""" + slice(stop) + slice(start, stop[, step]) + + Create a slice object. This is used for extended slicing (e.g. a[0:10:2]).""")), + PString("str", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().slots(StringBuiltins.SLOTS).doc(""" + str(object='') -> str + str(bytes_or_buffer[, encoding[, errors]]) -> str + + Create a new string object from the given object. If encoding or + errors is specified, then the object must expose a data buffer + that will be decoded using the given encoding and error handler. + Otherwise, returns the result of object.__str__() (if defined) + or repr(object). + encoding defaults to sys.getdefaultencoding(). + errors defaults to 'strict'.""")), + PTraceback("traceback", PythonObject, newBuilder().basetype().slots(TracebackBuiltins.SLOTS)), + PTuple("tuple", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().slots(TupleBuiltins.SLOTS).doc(""" + Built-in immutable sequence. + + If no argument is given, the constructor returns an empty tuple. + If iterable is specified the tuple is initialized from iterable's items. + + If the argument is a tuple, the return value is the same object.""")), + PythonModule("module", PythonObject, newBuilder().basetype().addDict().slots(ModuleBuiltins.SLOTS).doc(""" + Create a module object. + + The name must be a string; the optional doc argument can have any type.""")), + PythonModuleDef("moduledef", PythonObject, newBuilder()), + Super("super", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().slots(SuperBuiltins.SLOTS).doc(""" + super() -> same as super(__class__, ) + super(type) -> unbound super object + super(type, obj) -> bound super object; requires isinstance(obj, type) + super(type, type2) -> bound super object; requires issubclass(type2, type) + Typical use to call a cooperative superclass method: + class C(B): + def meth(self, arg): + super().meth(arg) + This works for class methods too: + class C(B): + @classmethod + def cmeth(cls, arg): + super().cmeth(arg)""")), + PCode("code", PythonObject, newBuilder().slots(CodeBuiltins.SLOTS)), + PGenericAlias("GenericAlias", PythonObject, newBuilder().publishInModule(J_TYPES).basetype().slots(GenericAliasBuiltins.SLOTS)), + PGenericAliasIterator("generic_alias_iterator", PythonObject, newBuilder().slots(GenericAliasIteratorBuiltins.SLOTS)), + PUnionType("UnionType", PythonObject, newBuilder().publishInModule(J_TYPES).slots(UnionTypeBuiltins.SLOTS)), + PZip( + "zip", + PythonObject, + newBuilder().publishInModule(J_BUILTINS).basetype().slots(ZipBuiltins.SLOTS).doc(""" + zip(*iterables, strict=False) --> Yield tuples until an input is exhausted. + + >>> list(zip('abcdefg', range(3), range(4))) + [('a', 0, 0), ('b', 1, 1), ('c', 2, 2)] + + The zip object yields n-length tuples, where n is the number of iterables + passed as positional arguments to zip(). The i-th element in every tuple + comes from the i-th iterable argument to zip(). This continues until the + shortest argument is exhausted. + + If strict is true and one of the arguments is exhausted before the others, + raise a ValueError.""")), + PThreadLocal("_local", PythonObject, newBuilder().publishInModule(J__THREAD).basetype().slots(ThreadLocalBuiltins.SLOTS)), + PLock("LockType", PythonObject, newBuilder().publishInModule(J__THREAD).disallowInstantiation().slots(CommonLockBuiltins.SLOTS, LockTypeBuiltins.SLOTS)), + PRLock("RLock", PythonObject, newBuilder().publishInModule(J__THREAD).basetype().slots(CommonLockBuiltins.SLOTS, RLockBuiltins.SLOTS)), + PSemLock("SemLock", PythonObject, newBuilder().publishInModule("_multiprocessing").basetype().slots(SemLockBuiltins.SLOTS)), + PGraalPySemLock("SemLock", PythonObject, newBuilder().publishInModule("_multiprocessing_graalpy").basetype().slots(GraalPySemLockBuiltins.SLOTS)), + PSocket("socket", PythonObject, newBuilder().publishInModule(J__SOCKET).basetype().slots(SocketBuiltins.SLOTS)), + PStaticmethod("staticmethod", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(StaticmethodBuiltins.SLOTS).doc(""" + staticmethod(function) -> method + + Convert a function to be a static method. + + A static method does not receive an implicit first argument. + To declare a static method, use this idiom: + + class C: + @staticmethod + def f(arg1, arg2, argN): + ... + + It can be called either on the class (e.g. C.f()) or on an instance + (e.g. C().f()). Both the class and the instance are ignored, and + neither is passed implicitly as the first argument to the method. + + Static methods in Python are similar to those found in Java or C++. + For a more advanced concept, see the classmethod builtin.""")), + PClassmethod("classmethod", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(ClassmethodCommonBuiltins.SLOTS, ClassmethodBuiltins.SLOTS).doc(""" + classmethod(function) -> method + + Convert a function to be a class method. + + A class method receives the class as implicit first argument, + just like an instance method receives the instance. + To declare a class method, use this idiom: + + class C: + @classmethod + def f(cls, arg1, arg2, argN): + ... + + It can be called either on the class (e.g. C.f()) or on an instance + (e.g. C().f()). The instance is ignored except for its class. + If a class method is called for a derived class, the derived class + object is passed as the implied first argument. + + Class methods are different than C++ or Java static methods. + If you want those, see the staticmethod builtin.""")), + PInstancemethod("instancemethod", PythonObject, newBuilder().basetype().addDict().slots(InstancemethodBuiltins.SLOTS).doc(""" + instancemethod(function) + + Bind a function to a class.""")), + PScandirIterator("ScandirIterator", PythonObject, newBuilder().moduleName(J_POSIX).disallowInstantiation().slots(ScandirIteratorBuiltins.SLOTS)), + PDirEntry("DirEntry", PythonObject, newBuilder().publishInModule(J_POSIX).disallowInstantiation().slots(DirEntryBuiltins.SLOTS)), + LsprofProfiler("Profiler", PythonObject, newBuilder().publishInModule("_lsprof").basetype().slots(ProfilerBuiltins.SLOTS)), + PStruct("Struct", PythonObject, newBuilder().publishInModule(J__STRUCT).basetype().slots(StructBuiltins.SLOTS)), + PStructUnpackIterator("unpack_iterator", PythonObject, newBuilder().publishInModule(J__STRUCT).basetype().slots(StructUnpackIteratorBuiltins.SLOTS)), + Pickler("Pickler", PythonObject, newBuilder().publishInModule("_pickle").basetype().slots(PicklerBuiltins.SLOTS)), + PicklerMemoProxy("PicklerMemoProxy", PythonObject, newBuilder().publishInModule("_pickle").basetype().slots(PicklerMemoProxyBuiltins.SLOTS)), + UnpicklerMemoProxy("UnpicklerMemoProxy", PythonObject, newBuilder().publishInModule("_pickle").basetype().slots(UnpicklerMemoProxyBuiltins.SLOTS)), + Unpickler("Unpickler", PythonObject, newBuilder().publishInModule("_pickle").basetype().slots(UnpicklerBuiltins.SLOTS)), + PickleBuffer("PickleBuffer", PythonObject, newBuilder().publishInModule("_pickle").basetype().slots(PickleBufferBuiltins.SLOTS)), + + // Errors and exceptions: + + // everything after BaseException is considered to be an exception + PBaseException("BaseException", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(BaseExceptionBuiltins.SLOTS).doc(""" + Common base class for all exceptions""")), + PBaseExceptionGroup("BaseExceptionGroup", PBaseException, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(BaseExceptionGroupBuiltins.SLOTS).doc(""" + A combination of multiple unrelated exceptions.""")), + SystemExit("SystemExit", PBaseException, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(SystemExitBuiltins.SLOTS)), + KeyboardInterrupt("KeyboardInterrupt", PBaseException, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + GeneratorExit("GeneratorExit", PBaseException, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + Exception("Exception", PBaseException, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + ReferenceError("ReferenceError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + RuntimeError("RuntimeError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + NotImplementedError("NotImplementedError", RuntimeError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + SyntaxError("SyntaxError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(SyntaxErrorBuiltins.SLOTS)), + IndentationError("IndentationError", SyntaxError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(SyntaxErrorBuiltins.SLOTS)), + TabError("TabError", IndentationError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(SyntaxErrorBuiltins.SLOTS)), + SystemError("SystemError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + TypeError("TypeError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + ValueError("ValueError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + StopIteration("StopIteration", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(StopIterationBuiltins.SLOTS)), + StopAsyncIteration("StopAsyncIteration", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + ArithmeticError("ArithmeticError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + FloatingPointError("FloatingPointError", ArithmeticError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + OverflowError("OverflowError", ArithmeticError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + ZeroDivisionError("ZeroDivisionError", ArithmeticError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + AssertionError("AssertionError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + AttributeError("AttributeError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(AttributeErrorBuiltins.SLOTS)), + BufferError("BufferError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + EOFError("EOFError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + ImportError("ImportError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(ImportErrorBuiltins.SLOTS)), + ModuleNotFoundError("ModuleNotFoundError", ImportError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + LookupError("LookupError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + IndexError("IndexError", LookupError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + KeyError("KeyError", LookupError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(KeyErrorBuiltins.SLOTS)), + MemoryError("MemoryError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + NameError("NameError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + UnboundLocalError("UnboundLocalError", NameError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + OSError("OSError", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(OsErrorBuiltins.SLOTS)), + BlockingIOError("BlockingIOError", OSError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + ChildProcessError("ChildProcessError", OSError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + ConnectionError("ConnectionError", OSError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + BrokenPipeError("BrokenPipeError", ConnectionError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + ConnectionAbortedError("ConnectionAbortedError", ConnectionError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + ConnectionRefusedError("ConnectionRefusedError", ConnectionError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + ConnectionResetError("ConnectionResetError", ConnectionError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + FileExistsError("FileExistsError", OSError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + FileNotFoundError("FileNotFoundError", OSError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + InterruptedError("InterruptedError", OSError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + IsADirectoryError("IsADirectoryError", OSError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + NotADirectoryError("NotADirectoryError", OSError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + PermissionError("PermissionError", OSError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + ProcessLookupError("ProcessLookupError", OSError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + TimeoutError("TimeoutError", OSError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + ZLibError("error", Exception, newBuilder().publishInModule("zlib").basetype().addDict()), + CSVError("Error", Exception, newBuilder().publishInModule("_csv").basetype().addDict()), + LZMAError("LZMAError", Exception, newBuilder().publishInModule("_lzma").basetype().addDict()), + StructError("StructError", Exception, newBuilder().publishInModule(J__STRUCT).basetype().addDict()), + PickleError("PickleError", Exception, newBuilder().publishInModule("_pickle").basetype().addDict()), + PicklingError("PicklingError", PickleError, newBuilder().publishInModule("_pickle").basetype().addDict()), + UnpicklingError("UnpicklingError", PickleError, newBuilder().publishInModule("_pickle").basetype().addDict()), + SocketGAIError("gaierror", OSError, newBuilder().publishInModule(J__SOCKET).basetype().addDict()), + SocketHError("herror", OSError, newBuilder().publishInModule(J__SOCKET).basetype().addDict()), + BinasciiError("Error", ValueError, newBuilder().publishInModule("binascii").basetype().addDict()), + BinasciiIncomplete("Incomplete", Exception, newBuilder().publishInModule("binascii").basetype().addDict()), + SSLError("SSLError", OSError, newBuilder().publishInModule(J__SSL).basetype().addDict().slots(SSLErrorBuiltins.SLOTS)), + SSLZeroReturnError("SSLZeroReturnError", SSLError, newBuilder().publishInModule(J__SSL).basetype().addDict()), + SSLWantReadError("SSLWantReadError", SSLError, newBuilder().publishInModule(J__SSL).basetype().addDict()), + SSLWantWriteError("SSLWantWriteError", SSLError, newBuilder().publishInModule(J__SSL).basetype().addDict()), + SSLSyscallError("SSLSyscallError", SSLError, newBuilder().publishInModule(J__SSL).basetype().addDict()), + SSLEOFError("SSLEOFError", SSLError, newBuilder().publishInModule(J__SSL).basetype().addDict()), + SSLCertVerificationError("SSLCertVerificationError", SSLError, newBuilder().publishInModule(J__SSL).basetype().addDict()), + + // todo: all OS errors + + UnicodeError("UnicodeError", ValueError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + UnicodeDecodeError("UnicodeDecodeError", UnicodeError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(UnicodeDecodeErrorBuiltins.SLOTS)), + UnicodeEncodeError("UnicodeEncodeError", UnicodeError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(UnicodeEncodeErrorBuiltins.SLOTS)), + UnicodeTranslateError("UnicodeTranslateError", UnicodeError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(UnicodeTranslateErrorBuiltins.SLOTS)), + RecursionError("RecursionError", RuntimeError, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + + /* + * _io.UnsupportedOperation inherits from ValueError and OSError done currently within + * IOModuleBuiltins class + */ + IOUnsupportedOperation("UnsupportedOperation", OSError, newBuilder().publishInModule("io").basetype().addDict()), + + Empty("Empty", Exception, newBuilder().publishInModule("_queue").basetype().addDict()), + + UnsupportedMessage("UnsupportedMessage", Exception, newBuilder().publishInModule(J_POLYGLOT).basetype().addDict()), + + // warnings + Warning("Warning", Exception, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + BytesWarning("BytesWarning", Warning, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + DeprecationWarning("DeprecationWarning", Warning, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + FutureWarning("FutureWarning", Warning, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + ImportWarning("ImportWarning", Warning, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + PendingDeprecationWarning("PendingDeprecationWarning", Warning, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + ResourceWarning("ResourceWarning", Warning, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + RuntimeWarning("RuntimeWarning", Warning, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + SyntaxWarning("SyntaxWarning", Warning, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + UnicodeWarning("UnicodeWarning", Warning, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + UserWarning("UserWarning", Warning, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), + EncodingWarning("EncodingWarning", Warning, newBuilder().publishInModule(J_BUILTINS).basetype().addDict()), // Foreign - ForeignObject("ForeignObject", J_POLYGLOT, Flags.PUBLIC_BASE_WDICT, ForeignObjectBuiltins.SLOTS), - ForeignNumber("ForeignNumber", J_POLYGLOT, ForeignObject, Flags.PUBLIC_BASE_WDICT, FOREIGNNUMBER_M_FLAGS, ForeignNumberBuiltins.SLOTS), - ForeignBoolean("ForeignBoolean", J_POLYGLOT, ForeignNumber, Flags.PUBLIC_BASE_WDICT, FOREIGNNUMBER_M_FLAGS, ForeignBooleanBuiltins.SLOTS), - ForeignAbstractClass("ForeignAbstractClass", J_POLYGLOT, ForeignObject, Flags.PUBLIC_BASE_WDICT), - ForeignExecutable("ForeignExecutable", J_POLYGLOT, ForeignObject, Flags.PUBLIC_BASE_WDICT), - ForeignInstantiable("ForeignInstantiable", J_POLYGLOT, ForeignObject, Flags.PUBLIC_BASE_WDICT), - ForeignIterable("ForeignIterable", J_POLYGLOT, ForeignObject, Flags.PUBLIC_BASE_WDICT), + ForeignObject("ForeignObject", PythonObject, newBuilder().publishInModule(J_POLYGLOT).basetype().addDict().disallowInstantiation().slots(ForeignObjectBuiltins.SLOTS)), + ForeignNumber( + "ForeignNumber", + ForeignObject, + newBuilder().publishInModule(J_POLYGLOT).basetype().addDict().disallowInstantiation().slots(ForeignNumberBuiltins.SLOTS)), + ForeignBoolean( + "ForeignBoolean", + ForeignNumber, + newBuilder().publishInModule(J_POLYGLOT).basetype().addDict().disallowInstantiation().slots(ForeignBooleanBuiltins.SLOTS)), + ForeignAbstractClass("ForeignAbstractClass", ForeignObject, newBuilder().publishInModule(J_POLYGLOT).basetype().addDict().disallowInstantiation()), + ForeignExecutable("ForeignExecutable", ForeignObject, newBuilder().publishInModule(J_POLYGLOT).basetype().addDict().disallowInstantiation().slots(ForeignExecutableBuiltins.SLOTS)), + ForeignInstantiable("ForeignInstantiable", ForeignObject, newBuilder().publishInModule(J_POLYGLOT).basetype().addDict().slots(ForeignInstantiableBuiltins.SLOTS)), + ForeignIterable("ForeignIterable", ForeignObject, newBuilder().publishInModule(J_POLYGLOT).basetype().addDict().disallowInstantiation().slots(ForeignIterableBuiltins.SLOTS)), // bz2 - BZ2Compressor("BZ2Compressor", "_bz2"), - BZ2Decompressor("BZ2Decompressor", "_bz2"), + BZ2Compressor("BZ2Compressor", PythonObject, newBuilder().publishInModule("_bz2").basetype().slots(BZ2CompressorBuiltins.SLOTS)), + BZ2Decompressor("BZ2Decompressor", PythonObject, newBuilder().publishInModule("_bz2").basetype().slots(BZ2DecompressorBuiltins.SLOTS)), // lzma - PLZMACompressor("LZMACompressor", "_lzma"), - PLZMADecompressor("LZMADecompressor", "_lzma"), + PLZMACompressor("LZMACompressor", PythonObject, newBuilder().publishInModule("_lzma").basetype().slots(LZMACompressorBuiltins.SLOTS)), + PLZMADecompressor("LZMADecompressor", PythonObject, newBuilder().publishInModule("_lzma").basetype().slots(LZMADecompressorBuiltins.SLOTS)), // zlib - ZlibCompress("Compress", "zlib"), - ZlibDecompress("Decompress", "zlib"), + ZlibCompress("Compress", PythonObject, newBuilder().publishInModule("zlib").disallowInstantiation()), + ZlibDecompress("Decompress", PythonObject, newBuilder().publishInModule("zlib").disallowInstantiation()), // io - PIOBase("_IOBase", "_io", Flags.PUBLIC_BASE_WDICT), - PRawIOBase("_RawIOBase", "_io"), - PTextIOBase("_TextIOBase", "_io"), - PBufferedIOBase("_BufferedIOBase", "_io"), - PBufferedReader("BufferedReader", "_io", Flags.PUBLIC_BASE_WDICT), - PBufferedWriter("BufferedWriter", "_io", Flags.PUBLIC_BASE_WDICT), - PBufferedRWPair("BufferedRWPair", "_io", Flags.PUBLIC_BASE_WDICT), - PBufferedRandom("BufferedRandom", "_io", Flags.PUBLIC_BASE_WDICT), - PFileIO("FileIO", "_io", Flags.PUBLIC_BASE_WDICT), - PTextIOWrapper("TextIOWrapper", "_io", Flags.PUBLIC_BASE_WDICT), - PIncrementalNewlineDecoder("IncrementalNewlineDecoder", "_io", Flags.PUBLIC_BASE_WODICT), - PStringIO("StringIO", "_io", Flags.PUBLIC_BASE_WDICT), - PBytesIO("BytesIO", "_io", Flags.PUBLIC_BASE_WDICT), - PBytesIOBuf("_BytesIOBuffer", "_io", Flags.PRIVATE_BASE_WODICT), - - PStatResult("stat_result", "os", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PStatvfsResult("statvfs_result", "os", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PTerminalSize("terminal_size", "os", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PUnameResult("uname_result", J_POSIX, Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PStructTime("struct_time", "time", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PProfilerEntry("profiler_entry", "_lsprof", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PProfilerSubentry("profiler_subentry", "_lsprof", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PStructPasswd("struct_passwd", "pwd", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PStructRusage("struct_rusage", "resource", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PVersionInfo("version_info", "sys", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PWindowsVersion("windowsversion", "sys", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PFlags("flags", "sys", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PFloatInfo("float_info", "sys", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PIntInfo("int_info", "sys", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PHashInfo("hash_info", "sys", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PThreadInfo("thread_info", "sys", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - PUnraisableHookArgs("UnraisableHookArgs", "sys", Flags.PUBLIC_DERIVED_WODICT, TUPLE_M_FLAGS), - - PSSLSession("SSLSession", J__SSL), - PSSLContext("_SSLContext", J__SSL), - PSSLSocket("_SSLSocket", J__SSL), - PMemoryBIO("MemoryBIO", J__SSL), + PIOBase("_IOBase", PythonObject, newBuilder().publishInModule("_io").basetype().addDict().slots(IOBaseBuiltins.SLOTS)), + PRawIOBase("_RawIOBase", PIOBase, newBuilder().publishInModule("_io").basetype().slots(IOBaseBuiltins.SLOTS)), + PTextIOBase("_TextIOBase", PIOBase, newBuilder().publishInModule("_io").basetype().slots(IOBaseBuiltins.SLOTS)), + PBufferedIOBase("_BufferedIOBase", PIOBase, newBuilder().publishInModule("_io").basetype().slots(IOBaseBuiltins.SLOTS)), + PBufferedReader( + "BufferedReader", + PBufferedIOBase, + newBuilder().publishInModule("_io").basetype().addDict().slots(BufferedReaderMixinBuiltins.SLOTS, BufferedIOMixinBuiltins.SLOTS, BufferedReaderBuiltins.SLOTS)), + PBufferedWriter("BufferedWriter", PBufferedIOBase, newBuilder().publishInModule("_io").basetype().addDict().slots(BufferedIOMixinBuiltins.SLOTS, BufferedWriterBuiltins.SLOTS)), + PBufferedRWPair("BufferedRWPair", PBufferedIOBase, newBuilder().publishInModule("_io").basetype().addDict().slots(BufferedRWPairBuiltins.SLOTS)), + PBufferedRandom( + "BufferedRandom", + PBufferedIOBase, + newBuilder().publishInModule("_io").basetype().addDict().slots(BufferedReaderMixinBuiltins.SLOTS, BufferedIOMixinBuiltins.SLOTS, BufferedRandomBuiltins.SLOTS)), + PWindowsConsoleIO("_WindowsConsoleIO", PRawIOBase, newBuilder().moduleName("_io").basetype()), + PFileIO("FileIO", PRawIOBase, newBuilder().publishInModule("_io").basetype().addDict().slots(FileIOBuiltins.SLOTS)), + PTextIOWrapper("TextIOWrapper", PTextIOBase, newBuilder().publishInModule("_io").basetype().addDict().slots(TextIOWrapperBuiltins.SLOTS)), + PIncrementalNewlineDecoder("IncrementalNewlineDecoder", PythonObject, newBuilder().publishInModule("_io").basetype().slots(IncrementalNewlineDecoderBuiltins.SLOTS)), + PStringIO("StringIO", PTextIOBase, newBuilder().publishInModule("_io").basetype().addDict().slots(StringIOBuiltins.SLOTS)), + PBytesIO("BytesIO", PBufferedIOBase, newBuilder().publishInModule("_io").basetype().addDict().slots(BytesIOBuiltins.SLOTS)), + PBytesIOBuf("_BytesIOBuffer", PythonObject, newBuilder().moduleName("_io").basetype()), + + PStatResult( + "stat_result", + PTuple, + newBuilder().publishInModule("os").slots(StructSequenceBuiltins.SLOTS, StatResultBuiltins.SLOTS).doc(""" + stat_result: Result from stat, fstat, or lstat. + + This object may be accessed either as a tuple of + (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) + or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on. + + Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev, + or st_flags, they are available as attributes only. + + See os.stat for more information.""")), + PStatvfsResult("statvfs_result", PTuple, newBuilder().publishInModule("os").slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS).doc(""" + statvfs_result: Result from statvfs or fstatvfs. + + This object may be accessed either as a tuple of + (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax), + or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on. + + See os.statvfs for more information.""")), + PTerminalSize("terminal_size", PTuple, newBuilder().publishInModule("os").slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS).doc(""" + A tuple of (columns, lines) for holding terminal window size""")), + PUnameResult("uname_result", PTuple, newBuilder().publishInModule(J_POSIX).slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS).doc(""" + uname_result: Result from os.uname(). + + This object may be accessed either as a tuple of + (sysname, nodename, release, version, machine), + or via the attributes sysname, nodename, release, version, and machine. + + See os.uname for more information.""")), + PStructTime("struct_time", PTuple, newBuilder().publishInModule("time").slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS).doc(""" + The time value as returned by gmtime(), localtime(), and strptime(), and + accepted by asctime(), mktime() and strftime(). May be considered as a + sequence of 9 integers. + + Note that several fields' values are not the same as those defined by + the C language standard for struct tm. For example, the value of the + field tm_year is the actual year, not year - 1900. See individual + fields' descriptions for details.""")), + PProfilerEntry("profiler_entry", PTuple, newBuilder().publishInModule("_lsprof").slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS)), + PProfilerSubentry("profiler_subentry", PTuple, newBuilder().publishInModule("_lsprof").slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS)), + PStructPasswd("struct_passwd", PTuple, newBuilder().publishInModule("pwd").slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS).doc(""" + pwd.struct_passwd: Results from getpw*() routines. + + This object may be accessed either as a tuple of + (pw_name,pw_passwd,pw_uid,pw_gid,pw_gecos,pw_dir,pw_shell) + or via the object attributes as named in the above tuple.""")), + PStructRusage("struct_rusage", PTuple, newBuilder().publishInModule("resource").slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS).doc(""" + struct_rusage: Result from getrusage. + + This object may be accessed either as a tuple of + (utime,stime,maxrss,ixrss,idrss,isrss,minflt,majflt, + nswap,inblock,oublock,msgsnd,msgrcv,nsignals,nvcsw,nivcsw) + or via the attributes ru_utime, ru_stime, ru_maxrss, and so on.""")), + PVersionInfo("version_info", PTuple, newBuilder().publishInModule("sys").disallowInstantiation().slots(StructSequenceBuiltins.SLOTS).doc(""" + sys.version_info + + Version information as a named tuple.""")), + PWindowsVersion("windowsversion", PTuple, newBuilder().publishInModule("sys").disallowInstantiation().slots(StructSequenceBuiltins.SLOTS).doc(""" + sys.getwindowsversion + + Return info about the running version of Windows as a named tuple.""")), + PFlags("flags", PTuple, newBuilder().publishInModule("sys").disallowInstantiation().slots(StructSequenceBuiltins.SLOTS).doc(""" + sys.flags + + Flags provided through command line arguments or environment vars.""")), + PFloatInfo("float_info", PTuple, newBuilder().publishInModule("sys").slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS).doc(""" + sys.float_info + + A named tuple holding information about the float type. It contains low level + information about the precision and internal representation. Please study + your system's :file:`float.h` for more information.""")), + PIntInfo("int_info", PTuple, newBuilder().publishInModule("sys").slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS).doc(""" + sys.int_info + + A named tuple that holds information about Python's + internal representation of integers. The attributes are read only.""")), + PHashInfo("hash_info", PTuple, newBuilder().publishInModule("sys").slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS).doc(""" + hash_info + + A named tuple providing parameters used for computing + hashes. The attributes are read only.""")), + PThreadInfo("thread_info", PTuple, newBuilder().publishInModule("sys").slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS).doc(""" + sys.thread_info + + A named tuple holding information about the thread implementation.""")), + PUnraisableHookArgs( + "UnraisableHookArgs", + PTuple, + newBuilder().publishInModule("sys").slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS).doc(""" + UnraisableHookArgs + + Type used to pass arguments to sys.unraisablehook.""")), + + PSSLSession("SSLSession", PythonObject, newBuilder().publishInModule(J__SSL).disallowInstantiation()), + PSSLContext("_SSLContext", PythonObject, newBuilder().publishInModule(J__SSL).basetype().slots(SSLContextBuiltins.SLOTS)), + PSSLSocket("_SSLSocket", PythonObject, newBuilder().publishInModule(J__SSL).basetype()), + PMemoryBIO("MemoryBIO", PythonObject, newBuilder().publishInModule(J__SSL).basetype().slots(MemoryBIOBuiltins.SLOTS)), // itertools - PTee("_tee", "itertools", Flags.PUBLIC_DERIVED_WODICT), - PTeeDataObject("_tee_dataobject", "itertools", Flags.PUBLIC_DERIVED_WODICT), - PAccumulate("accumulate", "itertools"), - PCombinations("combinations", "itertools"), - PCombinationsWithReplacement("combinations_with_replacement", "itertools"), - PCompress("compress", "itertools"), - PCycle("cycle", "itertools"), - PDropwhile("dropwhile", "itertools"), - PFilterfalse("filterfalse", "itertools"), - PGroupBy("groupby", "itertools"), - PGrouper("grouper", "itertools", Flags.PUBLIC_DERIVED_WODICT), - PPairwise("pairwise", "itertools"), - PPermutations("permutations", "itertools"), - PProduct("product", "itertools"), - PRepeat("repeat", "itertools"), - PChain("chain", "itertools"), - PCount("count", "itertools"), - PIslice("islice", "itertools"), - PStarmap("starmap", "itertools"), - PTakewhile("takewhile", "itertools"), - PZipLongest("zip_longest", "itertools"), + PTee("_tee", PythonObject, newBuilder().publishInModule("itertools").slots(TeeBuiltins.SLOTS)), + PTeeDataObject("_tee_dataobject", PythonObject, newBuilder().publishInModule("itertools").slots(TeeDataObjectBuiltins.SLOTS)), + PAccumulate("accumulate", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(AccumulateBuiltins.SLOTS).doc(""" + accumulate(iterable) --> accumulate object + + Return series of accumulated sums.""")), + PCombinations("combinations", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(CombinationsBuiltins.SLOTS).doc(""" + combinations(iterable, r) --> combinations object + + Return successive r-length combinations of elements in the iterable. + + combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)""")), + PCombinationsWithReplacement( + "combinations_with_replacement", + PythonObject, + newBuilder().publishInModule("itertools").basetype().slots(CombinationsBuiltins.SLOTS, CombinationsWithReplacementBuiltins.SLOTS).doc(""" + combinations_with_replacement(iterable, r) --> combinations_with_replacement object + + Return successive r-length combinations of elements in the iterable + allowing individual elements to have successive repeats. + combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC""")), + PCompress("compress", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(CompressBuiltins.SLOTS).doc(""" + Make an iterator that filters elements from *data* returning + only those that have a corresponding element in *selectors* that evaluates to + ``True``. Stops when either the *data* or *selectors* iterables has been + exhausted. + Equivalent to:: + + \tdef compress(data, selectors): + \t\t# compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F + \t\treturn (d for d, s in zip(data, selectors) if s)""")), + PCycle("cycle", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(CycleBuiltins.SLOTS).doc(""" + Make an iterator returning elements from the iterable and + saving a copy of each. When the iterable is exhausted, return + elements from the saved copy. Repeats indefinitely. + + Equivalent to : + + def cycle(iterable): + \tsaved = [] + \tfor element in iterable: + \t\tyield element + \t\tsaved.append(element) + \twhile saved: + \t\tfor element in saved: + \t\t\tyield element""")), + PDropwhile("dropwhile", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(DropwhileBuiltins.SLOTS).doc(""" + dropwhile(predicate, iterable) --> dropwhile object + + Drop items from the iterable while predicate(item) is true. + Afterwards, return every element until the iterable is exhausted.""")), + PFilterfalse("filterfalse", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(FilterfalseBuiltins.SLOTS).doc(""" + filterfalse(function or None, sequence) --> filterfalse object + + Return those items of sequence for which function(item) is false. + If function is None, return the items that are false.""")), + PGroupBy("groupby", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(GroupByBuiltins.SLOTS).doc(""" + Make an iterator that returns consecutive keys and groups from the + iterable. The key is a function computing a key value for each + element. If not specified or is None, key defaults to an identity + function and returns the element unchanged. Generally, the + iterable needs to already be sorted on the same key function. + + The returned group is itself an iterator that shares the + underlying iterable with groupby(). Because the source is shared, + when the groupby object is advanced, the previous group is no + longer visible. So, if that data is needed later, it should be + stored as a list: + + \tgroups = [] + \tuniquekeys = [] + \tfor k, g in groupby(data, keyfunc): + \t\tgroups.append(list(g)) # Store group iterator as a list + \t\tuniquekeys.append(k)""")), + PGrouper("grouper", PythonObject, newBuilder().publishInModule("itertools").slots(GrouperBuiltins.SLOTS)), + PPairwise("pairwise", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(PairwiseBuiltins.SLOTS).doc(""" + Return an iterator of overlapping pairs taken from the input iterator. + + s -> (s0,s1), (s1,s2), (s2, s3), ...""")), + PPermutations("permutations", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(PermutationsBuiltins.SLOTS).doc(""" + permutations(iterable[, r]) --> permutations object + + Return successive r-length permutations of elements in the iterable. + + permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)""")), + PProduct("product", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(ProductBuiltins.SLOTS).doc(""" + Cartesian product of input iterables. + + Equivalent to nested for-loops in a generator expression. For example, + ``product(A, B)`` returns the same as ``((x,y) for x in A for y in B)``. + + The nested loops cycle like an odometer with the rightmost element advancing + on every iteration. This pattern creates a lexicographic ordering so that if + the input's iterables are sorted, the product tuples are emitted in sorted + order. + + To compute the product of an iterable with itself, specify the number of + repetitions with the optional *repeat* keyword argument. For example, + ``product(A, repeat=4)`` means the same as ``product(A, A, A, A)``. + + This function is equivalent to the following code, except that the + actual implementation does not build up intermediate results in memory:: + + def product(*args, **kwds): + \t# product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy + \t# product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 + \tpools = map(tuple, args) * kwds.get('repeat', 1) + \tresult = [[]] + \tfor pool in pools: + \t\tresult = [x+[y] for x in result for y in pool] + \tfor prod in result: + \t\tyield tuple(prod)""")), + PRepeat("repeat", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(RepeatBuiltins.SLOTS).doc(""" + repeat(object [,times]) -> create an iterator which returns the object + for the specified number of times. If not specified, returns the object + endlessly.""")), + PChain("chain", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(ChainBuiltins.SLOTS).doc(""" + Return a chain object whose .__next__() method returns elements from the + first iterable until it is exhausted, then elements from the next + iterable, until all of the iterables are exhausted.""")), + PCount("count", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(CountBuiltins.SLOTS)), + PIslice("islice", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(IsliceBuiltins.SLOTS)), + PStarmap("starmap", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(StarmapBuiltins.SLOTS).doc(""" + starmap(function, sequence) --> starmap object + + Return an iterator whose values are returned from the function evaluated + with an argument tuple taken from the given sequence.""")), + PTakewhile("takewhile", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(TakewhileBuiltins.SLOTS).doc(""" + Make an iterator that returns elements from the iterable as + long as the predicate is true. + + Equivalent to : + + def takewhile(predicate, iterable): + \tfor x in iterable: + \t\tif predicate(x): + \t\t\tyield x + \t\telse: + \t\t\tbreak""")), + PZipLongest("zip_longest", PythonObject, newBuilder().publishInModule("itertools").basetype().slots(ZipLongestBuiltins.SLOTS).doc(""" + zip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> zip_longest object + + Return a zip_longest object whose .next() method returns a tuple where + the i-th element comes from the i-th iterable argument. The .next() + method continues until the longest iterable in the argument sequence + is exhausted and then it raises StopIteration. When the shorter iterables + are exhausted, the fillvalue is substituted in their place. The fillvalue + defaults to None or can be specified by a keyword argument.""")), // json - JSONScanner("Scanner", "_json", Flags.PUBLIC_BASE_WODICT), - JSONEncoder("Encoder", "_json", Flags.PUBLIC_BASE_WODICT), + JSONScanner( + "Scanner", + PythonObject, + newBuilder().publishInModule("_json").basetype().slots(JSONScannerBuiltins.SLOTS).doc(""" + JSON scanner object""")), + JSONEncoder( + "Encoder", + PythonObject, + newBuilder().publishInModule("_json").basetype().slots(JSONEncoderBuiltins.SLOTS).doc(""" + _iterencode(obj, _current_indent_level) -> iterable""")), // csv - CSVDialect("Dialect", "_csv", Flags.PUBLIC_BASE_WODICT), - CSVReader("Reader", "_csv", Flags.PUBLIC_BASE_WODICT), - CSVWriter("Writer", "_csv", Flags.PUBLIC_BASE_WODICT), + CSVDialect("Dialect", PythonObject, newBuilder().publishInModule("_csv").basetype().slots(CSVDialectBuiltins.SLOTS)), + CSVReader("Reader", PythonObject, newBuilder().publishInModule("_csv").basetype().disallowInstantiation().slots(CSVReaderBuiltins.SLOTS)), + CSVWriter("Writer", PythonObject, newBuilder().publishInModule("_csv").basetype().disallowInstantiation()), // codecs - PEncodingMap("EncodingMap", Flags.PRIVATE_DERIVED_WODICT), + PEncodingMap("EncodingMap", PythonObject, newBuilder().disallowInstantiation()), // hashlib - MD5Type("md5", "_md5", Flags.PUBLIC_BASE_WODICT), - SHA1Type("sha1", "_sha1", Flags.PUBLIC_BASE_WODICT), - SHA224Type("sha224", "_sha256", Flags.PUBLIC_BASE_WODICT), - SHA256Type("sha256", "_sha256", Flags.PUBLIC_BASE_WODICT), - SHA384Type("sha384", "_sha512", Flags.PUBLIC_BASE_WODICT), - SHA512Type("sha512", "_sha512", Flags.PUBLIC_BASE_WODICT), - Sha3SHA224Type("sha3_224", "_sha3", Flags.PUBLIC_BASE_WODICT), - Sha3SHA256Type("sha3_256", "_sha3", Flags.PUBLIC_BASE_WODICT), - Sha3SHA384Type("sha3_384", "_sha3", Flags.PUBLIC_BASE_WODICT), - Sha3SHA512Type("sha3_512", "_sha3", Flags.PUBLIC_BASE_WODICT), - Sha3Shake128Type("shake_128", "_sha3", Flags.PUBLIC_BASE_WODICT), - Sha3Shake256Type("shake_256", "_sha3", Flags.PUBLIC_BASE_WODICT), - Blake2bType("blake2b", "_blake2", Flags.PUBLIC_BASE_WODICT), - Blake2sType("blake2s", "_blake2", Flags.PUBLIC_BASE_WODICT), - HashlibHash("HASH", "_hashlib", Flags.PUBLIC_BASE_WODICT), - HashlibHashXof("HASHXOF", "_hashlib", Flags.PUBLIC_DERIVED_WODICT), - HashlibHmac("HMAC", "_hashlib", Flags.PUBLIC_BASE_WODICT), - UnsupportedDigestmodError("UnsupportedDigestmodError", "_hashlib", Flags.EXCEPTION), + MD5Type("md5", PythonObject, newBuilder().publishInModule("_md5").basetype().disallowInstantiation()), + SHA1Type("sha1", PythonObject, newBuilder().publishInModule("_sha1").basetype().disallowInstantiation()), + SHA224Type("sha224", PythonObject, newBuilder().publishInModule("_sha256").basetype().disallowInstantiation()), + SHA256Type("sha256", PythonObject, newBuilder().publishInModule("_sha256").basetype().disallowInstantiation()), + SHA384Type("sha384", PythonObject, newBuilder().publishInModule("_sha512").basetype().disallowInstantiation()), + SHA512Type("sha512", PythonObject, newBuilder().publishInModule("_sha512").basetype().disallowInstantiation()), + Sha3SHA224Type("sha3_224", PythonObject, newBuilder().publishInModule("_sha3").basetype().slots(Sha3Builtins.SLOTS)), + Sha3SHA256Type("sha3_256", PythonObject, newBuilder().publishInModule("_sha3").basetype().slots(Sha3Builtins.SLOTS)), + Sha3SHA384Type("sha3_384", PythonObject, newBuilder().publishInModule("_sha3").basetype().slots(Sha3Builtins.SLOTS)), + Sha3SHA512Type("sha3_512", PythonObject, newBuilder().publishInModule("_sha3").basetype().slots(Sha3Builtins.SLOTS)), + Sha3Shake128Type("shake_128", PythonObject, newBuilder().publishInModule("_sha3").basetype().slots(Sha3Builtins.SLOTS)), + Sha3Shake256Type("shake_256", PythonObject, newBuilder().publishInModule("_sha3").basetype().slots(Sha3Builtins.SLOTS)), + Blake2bType("blake2b", PythonObject, newBuilder().publishInModule("_blake2").basetype().slots(Blake2bObjectBuiltins.SLOTS)), + /* Note we reuse the blake2b slots */ + Blake2sType("blake2s", PythonObject, newBuilder().publishInModule("_blake2").basetype().slots(Blake2bObjectBuiltins.SLOTS)), + HashlibHash("HASH", PythonObject, newBuilder().publishInModule("_hashlib").basetype().disallowInstantiation().slots(HashObjectBuiltins.SLOTS)), + HashlibHashXof("HASHXOF", HashlibHash, newBuilder().publishInModule("_hashlib").disallowInstantiation()), + HashlibHmac("HMAC", PythonObject, newBuilder().publishInModule("_hashlib").basetype().disallowInstantiation().slots(HashObjectBuiltins.SLOTS)), + UnsupportedDigestmodError("UnsupportedDigestmodError", ValueError, newBuilder().publishInModule("_hashlib").basetype().addDict()), // _ast (rest of the classes are not builtin, they are generated in AstModuleBuiltins) - AST("AST", "_ast", "ast", Flags.PUBLIC_BASE_WDICT), + AST("AST", PythonObject, newBuilder().moduleName("ast").publishInModule("_ast").basetype().addDict().slots(AstBuiltins.SLOTS)), // _ctype - CArgObject("CArgObject", Flags.PUBLIC_BASE_WODICT), - CThunkObject("CThunkObject", J__CTYPES, Flags.PUBLIC_BASE_WODICT), - StgDict("StgDict", Flags.PRIVATE_DERIVED_WODICT, DICT_M_FLAGS, StgDictBuiltins.SLOTS), - PyCStructType("PyCStructType", J__CTYPES, Flags.PUBLIC_BASE_WODICT, PYCSTRUCTTYPE_M_FLAGS, TpSlots.merge(CDataTypeSequenceBuiltins.SLOTS, PyCStructTypeBuiltins.SLOTS)), + CArgObject("CArgObject", PythonObject, newBuilder().basetype().slots(CArgObjectBuiltins.SLOTS)), + CThunkObject("CThunkObject", PythonObject, newBuilder().publishInModule(J__CTYPES).basetype()), + StgDict("StgDict", PDict, newBuilder().slots(StgDictBuiltins.SLOTS)), + PyCStructType( + "PyCStructType", + PythonClass, + newBuilder().publishInModule(J__CTYPES).basetype().slots(CDataTypeSequenceBuiltins.SLOTS, StructUnionTypeBuiltins.SLOTS, PyCStructTypeBuiltins.SLOTS)), UnionType( "UnionType", - J__CTYPES, - Flags.PUBLIC_BASE_WODICT, - UNIONTYPE_M_FLAGS, - TpSlots.merge(CDataTypeSequenceBuiltins.SLOTS, com.oracle.graal.python.builtins.modules.ctypes.UnionTypeBuiltins.SLOTS)), - PyCPointerType("PyCPointerType", J__CTYPES, Flags.PUBLIC_BASE_WODICT, PYCPOINTERTYPE_M_FLAGS, CDataTypeSequenceBuiltins.SLOTS), - PyCArrayType("PyCArrayType", J__CTYPES, Flags.PUBLIC_BASE_WODICT, PYCARRAYTYPE_M_FLAGS, CDataTypeSequenceBuiltins.SLOTS), - PyCSimpleType("PyCSimpleType", J__CTYPES, Flags.PUBLIC_BASE_WODICT, PYCSIMPLETYPE_M_FLAGS, CDataTypeSequenceBuiltins.SLOTS), - PyCFuncPtrType("PyCFuncPtrType", J__CTYPES, Flags.PUBLIC_BASE_WODICT, PYCFUNCPTRTYPE_M_FLAGS, CDataTypeSequenceBuiltins.SLOTS), - Structure("Structure", J__CTYPES, Flags.PUBLIC_BASE_WODICT), /*- type = PyCStructType */ - Union("Union", J__CTYPES, Flags.PUBLIC_BASE_WODICT), /*- type = UnionType */ - PyCPointer("_Pointer", J__CTYPES, Flags.PUBLIC_BASE_WODICT, PYCPOINTER_M_FLAGS, PyCPointerBuiltins.SLOTS), /*- type = PyCPointerType */ - PyCArray("Array", J__CTYPES, Flags.PUBLIC_BASE_WODICT, PYCARRAY_M_FLAGS, PyCArrayBuiltins.SLOTS), /*- type = PyCArrayType */ - PyCData("_CData", J__CTYPES, Flags.PUBLIC_BASE_WODICT), /*- type = PyCStructType */ - SimpleCData("_SimpleCData", J__CTYPES, Flags.PUBLIC_BASE_WODICT, SIMPLECDATA_M_FLAGS, SimpleCDataBuiltins.SLOTS), /*- type = PyCStructType */ - PyCFuncPtr("PyCFuncPtr", J__CTYPES, Flags.PUBLIC_BASE_WODICT, PYCFUNCPTR_M_FLAGS, PyCFuncPtrBuiltins.SLOTS), /*- type = PyCFuncPtrType */ - CField("CField", J__CTYPES, Flags.PUBLIC_BASE_WODICT, CFieldBuiltins.SLOTS), - DictRemover("DictRemover", J__CTYPES, Flags.PUBLIC_BASE_WODICT), - StructParam("StructParam_Type", J__CTYPES, Flags.PUBLIC_BASE_WODICT), - ArgError("ArgumentError", J__CTYPES, Flags.EXCEPTION), + PythonClass, + newBuilder().publishInModule(J__CTYPES).basetype().slots( + CDataTypeSequenceBuiltins.SLOTS, StructUnionTypeBuiltins.SLOTS, + com.oracle.graal.python.builtins.modules.ctypes.UnionTypeBuiltins.SLOTS)), + PyCPointerType( + "PyCPointerType", + PythonClass, + newBuilder().publishInModule(J__CTYPES).basetype().slots(CDataTypeSequenceBuiltins.SLOTS, PyCPointerTypeBuiltins.SLOTS)), + PyCArrayType( + "PyCArrayType", + PythonClass, + newBuilder().publishInModule(J__CTYPES).basetype().slots(CDataTypeSequenceBuiltins.SLOTS, PyCArrayTypeBuiltins.SLOTS)), + PyCSimpleType( + "PyCSimpleType", + PythonClass, + newBuilder().publishInModule(J__CTYPES).basetype().slots(CDataTypeSequenceBuiltins.SLOTS, PyCPointerTypeBuiltins.SLOTS, PyCSimpleTypeBuiltins.SLOTS)), + PyCFuncPtrType( + "PyCFuncPtrType", + PythonClass, + newBuilder().publishInModule(J__CTYPES).basetype().slots(CDataTypeSequenceBuiltins.SLOTS, PyCFuncPtrTypeBuiltins.SLOTS)), + PyCData("_CData", PythonObject, newBuilder().publishInModule(J__CTYPES).basetype().slots(CDataBuiltins.SLOTS)), /*- type = PyCStructType */ + Structure("Structure", PyCData, newBuilder().publishInModule(J__CTYPES).basetype().slots(StructureBuiltins.SLOTS)), /*- type = PyCStructType */ + Union("Union", PyCData, newBuilder().publishInModule(J__CTYPES).basetype().slots(StructureBuiltins.SLOTS)), /*- type = UnionType */ + PyCPointer("_Pointer", PyCData, newBuilder().publishInModule(J__CTYPES).basetype().slots(PyCPointerBuiltins.SLOTS)), /*- type = PyCPointerType */ + PyCArray("Array", PyCData, newBuilder().publishInModule(J__CTYPES).basetype().slots(PyCArrayBuiltins.SLOTS)), /*- type = PyCArrayType */ + SimpleCData("_SimpleCData", PyCData, newBuilder().publishInModule(J__CTYPES).basetype().slots(SimpleCDataBuiltins.SLOTS)), /*- type = PyCStructType */ + PyCFuncPtr("PyCFuncPtr", PyCData, newBuilder().publishInModule(J__CTYPES).basetype().slots(PyCFuncPtrBuiltins.SLOTS)), /*- type = PyCFuncPtrType */ + CField("CField", PythonObject, newBuilder().publishInModule(J__CTYPES).basetype().slots(CFieldBuiltins.SLOTS)), + DictRemover("DictRemover", PythonObject, newBuilder().publishInModule(J__CTYPES).basetype()), + StructParam("StructParam_Type", PythonObject, newBuilder().publishInModule(J__CTYPES).basetype()), + ArgError("ArgumentError", PBaseException, newBuilder().publishInModule(J__CTYPES).basetype().addDict()), // _multibytecodec - MultibyteCodec("MultibyteCodec", "_multibytecodec", Flags.PUBLIC_BASE_WDICT), - MultibyteIncrementalEncoder("MultibyteIncrementalEncoder", "_multibytecodec", Flags.PUBLIC_BASE_WDICT), - MultibyteIncrementalDecoder("MultibyteIncrementalDecoder", "_multibytecodec", Flags.PUBLIC_BASE_WDICT), - MultibyteStreamReader("MultibyteStreamReader", "_multibytecodec", Flags.PUBLIC_BASE_WDICT), - MultibyteStreamWriter("MultibyteStreamWriter", "_multibytecodec", Flags.PUBLIC_BASE_WDICT), - - // Errors and exceptions: - - // everything after BaseException is considered to be an exception - PBaseException("BaseException", J_BUILTINS, Flags.EXCEPTION), - PBaseExceptionGroup("BaseExceptionGroup", J_BUILTINS, Flags.EXCEPTION), - SystemExit("SystemExit", J_BUILTINS, Flags.EXCEPTION), - KeyboardInterrupt("KeyboardInterrupt", J_BUILTINS, Flags.EXCEPTION), - GeneratorExit("GeneratorExit", J_BUILTINS, Flags.EXCEPTION), - Exception("Exception", J_BUILTINS, Flags.EXCEPTION), - StopIteration("StopIteration", J_BUILTINS, Flags.EXCEPTION), - StopAsyncIteration("StopAsyncIteration", J_BUILTINS, Flags.EXCEPTION), - ArithmeticError("ArithmeticError", J_BUILTINS, Flags.EXCEPTION), - FloatingPointError("FloatingPointError", J_BUILTINS, Flags.EXCEPTION), - OverflowError("OverflowError", J_BUILTINS, Flags.EXCEPTION), - ZeroDivisionError("ZeroDivisionError", J_BUILTINS, Flags.EXCEPTION), - AssertionError("AssertionError", J_BUILTINS, Flags.EXCEPTION), - AttributeError("AttributeError", J_BUILTINS, Flags.EXCEPTION), - BufferError("BufferError", J_BUILTINS, Flags.EXCEPTION), - EOFError("EOFError", J_BUILTINS, Flags.EXCEPTION), - ImportError("ImportError", J_BUILTINS, Flags.EXCEPTION), - ModuleNotFoundError("ModuleNotFoundError", J_BUILTINS, Flags.EXCEPTION), - LookupError("LookupError", J_BUILTINS, Flags.EXCEPTION), - IndexError("IndexError", J_BUILTINS, Flags.EXCEPTION), - KeyError("KeyError", J_BUILTINS, Flags.EXCEPTION), - MemoryError("MemoryError", J_BUILTINS, Flags.EXCEPTION), - NameError("NameError", J_BUILTINS, Flags.EXCEPTION), - UnboundLocalError("UnboundLocalError", J_BUILTINS, Flags.EXCEPTION), - OSError("OSError", J_BUILTINS, Flags.EXCEPTION), - BlockingIOError("BlockingIOError", J_BUILTINS, Flags.EXCEPTION), - ChildProcessError("ChildProcessError", J_BUILTINS, Flags.EXCEPTION), - ConnectionError("ConnectionError", J_BUILTINS, Flags.EXCEPTION), - BrokenPipeError("BrokenPipeError", J_BUILTINS, Flags.EXCEPTION), - ConnectionAbortedError("ConnectionAbortedError", J_BUILTINS, Flags.EXCEPTION), - ConnectionRefusedError("ConnectionRefusedError", J_BUILTINS, Flags.EXCEPTION), - ConnectionResetError("ConnectionResetError", J_BUILTINS, Flags.EXCEPTION), - FileExistsError("FileExistsError", J_BUILTINS, Flags.EXCEPTION), - FileNotFoundError("FileNotFoundError", J_BUILTINS, Flags.EXCEPTION), - InterruptedError("InterruptedError", J_BUILTINS, Flags.EXCEPTION), - IsADirectoryError("IsADirectoryError", J_BUILTINS, Flags.EXCEPTION), - NotADirectoryError("NotADirectoryError", J_BUILTINS, Flags.EXCEPTION), - PermissionError("PermissionError", J_BUILTINS, Flags.EXCEPTION), - ProcessLookupError("ProcessLookupError", J_BUILTINS, Flags.EXCEPTION), - TimeoutError("TimeoutError", J_BUILTINS, Flags.EXCEPTION), - ZLibError("error", "zlib", Flags.EXCEPTION), - CSVError("Error", "_csv", Flags.EXCEPTION), - LZMAError("LZMAError", "_lzma", Flags.EXCEPTION), - StructError("StructError", J__STRUCT, Flags.EXCEPTION), - PickleError("PickleError", "_pickle", Flags.EXCEPTION), - PicklingError("PicklingError", "_pickle", Flags.EXCEPTION), - UnpicklingError("UnpicklingError", "_pickle", Flags.EXCEPTION), - SocketGAIError("gaierror", J__SOCKET, Flags.EXCEPTION), - SocketHError("herror", J__SOCKET, Flags.EXCEPTION), - BinasciiError("Error", "binascii", Flags.EXCEPTION), - BinasciiIncomplete("Incomplete", "binascii", Flags.EXCEPTION), - SSLError("SSLError", J__SSL, Flags.EXCEPTION), - SSLZeroReturnError("SSLZeroReturnError", J__SSL, Flags.EXCEPTION), - SSLWantReadError("SSLWantReadError", J__SSL, Flags.EXCEPTION), - SSLWantWriteError("SSLWantWriteError", J__SSL, Flags.EXCEPTION), - SSLSyscallError("SSLSyscallError", J__SSL, Flags.EXCEPTION), - SSLEOFError("SSLEOFError", J__SSL, Flags.EXCEPTION), - SSLCertVerificationError("SSLCertVerificationError", J__SSL, Flags.EXCEPTION), + MultibyteCodec("MultibyteCodec", PythonObject, newBuilder().publishInModule("_multibytecodec").basetype().addDict().disallowInstantiation()), + MultibyteIncrementalEncoder("MultibyteIncrementalEncoder", PythonObject, newBuilder().publishInModule("_multibytecodec").basetype().addDict().slots(MultibyteIncrementalEncoderBuiltins.SLOTS)), + MultibyteIncrementalDecoder("MultibyteIncrementalDecoder", PythonObject, newBuilder().publishInModule("_multibytecodec").basetype().addDict().slots(MultibyteIncrementalDecoderBuiltins.SLOTS)), + MultibyteStreamReader("MultibyteStreamReader", PythonObject, newBuilder().publishInModule("_multibytecodec").basetype().addDict().slots(MultibyteStreamReaderBuiltins.SLOTS)), + MultibyteStreamWriter("MultibyteStreamWriter", PythonObject, newBuilder().publishInModule("_multibytecodec").basetype().addDict().slots(MultibyteStreamWriterBuiltins.SLOTS)), - // todo: all OS errors - - ReferenceError("ReferenceError", J_BUILTINS, Flags.EXCEPTION), - RuntimeError("RuntimeError", J_BUILTINS, Flags.EXCEPTION), - NotImplementedError("NotImplementedError", J_BUILTINS, Flags.EXCEPTION), - SyntaxError("SyntaxError", J_BUILTINS, Flags.EXCEPTION), - IndentationError("IndentationError", J_BUILTINS, Flags.EXCEPTION), - TabError("TabError", J_BUILTINS, Flags.EXCEPTION), - SystemError("SystemError", J_BUILTINS, Flags.EXCEPTION), - TypeError("TypeError", J_BUILTINS, Flags.EXCEPTION), - ValueError("ValueError", J_BUILTINS, Flags.EXCEPTION), - UnicodeError("UnicodeError", J_BUILTINS, Flags.EXCEPTION), - UnicodeDecodeError("UnicodeDecodeError", J_BUILTINS, Flags.EXCEPTION), - UnicodeEncodeError("UnicodeEncodeError", J_BUILTINS, Flags.EXCEPTION), - UnicodeTranslateError("UnicodeTranslateError", J_BUILTINS, Flags.EXCEPTION), - RecursionError("RecursionError", J_BUILTINS, Flags.EXCEPTION), + // contextvars + ContextVarsToken("Token", PythonObject, newBuilder().publishInModule(J__CONTEXTVARS).slots(TokenBuiltins.SLOTS)), + ContextVarsContext("Context", PythonObject, newBuilder().publishInModule(J__CONTEXTVARS).slots(ContextBuiltins.SLOTS)), + ContextVar("ContextVar", PythonObject, newBuilder().publishInModule(J__CONTEXTVARS).slots(ContextVarBuiltins.SLOTS)), + // CPython uses separate keys, values, items python types for the iterators. + ContextIterator("context_iterator", PythonObject, newBuilder().publishInModule(J__CONTEXTVARS).slots(ContextIteratorBuiltins.SLOTS)), - IOUnsupportedOperation("UnsupportedOperation", "io", Flags.EXCEPTION), + Capsule("PyCapsule", PythonObject, newBuilder().basetype()), - Empty("Empty", "_queue", Flags.EXCEPTION), + PTokenizerIter("TokenizerIter", PythonObject, newBuilder().publishInModule("_tokenize").basetype().slots(TokenizerIterBuiltins.SLOTS)); - UnsupportedMessage("UnsupportedMessage", J_POLYGLOT, Flags.EXCEPTION), + private static TypeBuilder newBuilder() { + return new TypeBuilder(); + } - // warnings - Warning("Warning", J_BUILTINS, Flags.EXCEPTION), - BytesWarning("BytesWarning", J_BUILTINS, Flags.EXCEPTION), - DeprecationWarning("DeprecationWarning", J_BUILTINS, Flags.EXCEPTION), - FutureWarning("FutureWarning", J_BUILTINS, Flags.EXCEPTION), - ImportWarning("ImportWarning", J_BUILTINS, Flags.EXCEPTION), - PendingDeprecationWarning("PendingDeprecationWarning", J_BUILTINS, Flags.EXCEPTION), - ResourceWarning("ResourceWarning", J_BUILTINS, Flags.EXCEPTION), - RuntimeWarning("RuntimeWarning", J_BUILTINS, Flags.EXCEPTION), - SyntaxWarning("SyntaxWarning", J_BUILTINS, Flags.EXCEPTION), - UnicodeWarning("UnicodeWarning", J_BUILTINS, Flags.EXCEPTION), - UserWarning("UserWarning", J_BUILTINS, Flags.EXCEPTION), - EncodingWarning("EncodingWarning", J_BUILTINS, Flags.EXCEPTION), + private static final class TypeBuilder { + private String publishInModule; + private String moduleName; + private boolean basetype; + private boolean addDict; + private boolean disallowInstantiation; + private TpSlots slots; + private String doc; + + public TypeBuilder publishInModule(String publishInModule) { + this.publishInModule = publishInModule; + if (moduleName == null) { + this.moduleName = publishInModule; + } + return this; + } - // contextvars - ContextVarsToken("Token", J__CONTEXTVARS, Flags.PUBLIC_DERIVED_WODICT), - ContextVarsContext("Context", J__CONTEXTVARS, Flags.PUBLIC_DERIVED_WODICT, CONTEXT_M_FLAGS, ContextBuiltins.SLOTS), - ContextVar("ContextVar", J__CONTEXTVARS, Flags.PUBLIC_DERIVED_WODICT), - // CPython uses separate keys, values, items python types for the iterators. - ContextIterator("context_iterator", J__CONTEXTVARS, Flags.PUBLIC_DERIVED_WODICT), + public TypeBuilder moduleName(String moduleName) { + this.moduleName = moduleName; + return this; + } - Capsule("PyCapsule"), + public TypeBuilder basetype() { + this.basetype = true; + return this; + } - PTokenizerIter("TokenizerIter", "_tokenize"), + public TypeBuilder addDict() { + this.addDict = true; + return this; + } - // A marker for @Builtin that is not a class. Must always come last. - nil("nil"); + public TypeBuilder disallowInstantiation() { + this.disallowInstantiation = true; + return this; + } - private static class Flags { + public TypeBuilder slots(TpSlots slots) { + this.slots = slots; + return this; + } - static final Flags EXCEPTION = new Flags(true, true, true); - static final Flags PRIVATE_DERIVED_WDICT = new Flags(false, false, true); - static final Flags PRIVATE_BASE_WDICT = new Flags(false, true, true); - static final Flags PRIVATE_BASE_WODICT = new Flags(false, true, false); - static final Flags PUBLIC_BASE_WDICT = new Flags(true, true, true); - static final Flags PUBLIC_BASE_WODICT = new Flags(true, true, false); - static final Flags PUBLIC_DERIVED_WODICT = new Flags(true, false, false); - static final Flags PRIVATE_DERIVED_WODICT = new Flags(false, false, false); + public TypeBuilder slots(TpSlots slots1, TpSlots slots2) { + this.slots = slots1.copy().overrideIgnoreGroups(slots2).build(); + return this; + } - final boolean isPublic; - final boolean isBaseType; - final boolean isBuiltinWithDict; + public TypeBuilder slots(TpSlots slots1, TpSlots slots2, TpSlots slots3) { + this.slots = slots1.copy().overrideIgnoreGroups(slots2).overrideIgnoreGroups(slots3).build(); + return this; + } - Flags(boolean isPublic, boolean isBaseType, boolean isBuiltinWithDict) { - this.isPublic = isPublic; - this.isBaseType = isBaseType; - this.isBuiltinWithDict = isBuiltinWithDict; + public TypeBuilder doc(String doc) { + this.doc = doc; + return this; } } private final TruffleString name; + private final PythonBuiltinClassType base; private final TruffleString publishInModule; private final TruffleString moduleName; // This is the name qualified by module used for printing. But the actual __qualname__ is just @@ -595,122 +1238,55 @@ private static class Flags { private final TruffleString printName; private final boolean basetype; private final boolean isBuiltinWithDict; + private final boolean disallowInstantiation; + private final TruffleString doc; // initialized in static constructor @CompilationFinal private PythonBuiltinClassType type; - @CompilationFinal private PythonBuiltinClassType base; @CompilationFinal private int weaklistoffset; - /** - * @see #redefinesSlot(SpecialMethodSlot) - */ - private SpecialMethodSlot[] redefinedSlots; - - /** - * Lookup cache for special slots defined in {@link SpecialMethodSlot}. Use - * {@link SpecialMethodSlot} to access the values. Unlike the cache in - * {@link com.oracle.graal.python.builtins.objects.type.PythonManagedClass}, this caches only - * builtin context independent values, most notably instances of {@link BuiltinMethodDescriptor} - * . - */ - private Object[] specialMethodSlots; - /** * The slots defined directly on the builtin class. */ private final TpSlots declaredSlots; /** - * The actual slots including slots inherited from base classes. The value is computed in the - * static ctor. + * The actual slots including slots inherited from base classes */ - @CompilationFinal private TpSlots slots; - private final long methodsFlags; - - PythonBuiltinClassType(String name, String module, Flags flags) { - this(name, module, module, flags); - } - - PythonBuiltinClassType(String name, String module, PythonBuiltinClassType base, Flags flags) { - this(name, module, module, flags); - this.base = base; - } - - PythonBuiltinClassType(String name, String module, Flags flags, TpSlots slots) { - this(name, module, module, flags, DEFAULT_M_FLAGS, slots); - } - - PythonBuiltinClassType(String name, String module, Flags flags, long methodsFlags) { - this(name, module, module, flags, methodsFlags, TpSlots.createEmpty()); - } - - PythonBuiltinClassType(String name, String module, Flags flags, long methodsFlags, TpSlots slots) { - this(name, module, module, flags, methodsFlags, slots); - } - - PythonBuiltinClassType(String name, String module, PythonBuiltinClassType base, Flags flags, long methodsFlags, TpSlots slots) { - this(name, module, module, flags, methodsFlags, slots); - this.base = base; - } - - PythonBuiltinClassType(String name, String publishInModule, String moduleName, Flags flags) { - this(name, publishInModule, moduleName, flags, DEFAULT_M_FLAGS, TpSlots.createEmpty()); - } + private final TpSlots slots; - PythonBuiltinClassType(String name, String publishInModule, String moduleName, Flags flags, TpSlots slots) { - this(name, publishInModule, moduleName, flags, DEFAULT_M_FLAGS, slots); - } - - PythonBuiltinClassType(String name, String publishInModule, String moduleName, Flags flags, long methodsFlags, TpSlots declaredSlots) { + PythonBuiltinClassType(String name, PythonBuiltinClassType base, TypeBuilder builder) { this.name = toTruffleStringUncached(name); - this.publishInModule = toTruffleStringUncached(publishInModule); - this.moduleName = flags.isPublic && moduleName != null ? toTruffleStringUncached(moduleName) : null; - if (moduleName != null && moduleName != J_BUILTINS) { - printName = toTruffleStringUncached(moduleName + "." + name); + this.base = base; + this.publishInModule = toTruffleStringUncached(builder.publishInModule); + this.moduleName = builder.moduleName != null ? toTruffleStringUncached(builder.moduleName) : null; + if (builder.moduleName != null && !J_BUILTINS.equals(builder.moduleName)) { + printName = toTruffleStringUncached(builder.moduleName + "." + name); } else { printName = this.name; } - this.basetype = flags.isBaseType; - this.isBuiltinWithDict = flags.isBuiltinWithDict; - this.methodsFlags = methodsFlags; + this.basetype = builder.basetype; + this.isBuiltinWithDict = builder.addDict; this.weaklistoffset = -1; - this.declaredSlots = declaredSlots; - } - - PythonBuiltinClassType(String name, String module) { - this(name, module, Flags.PUBLIC_BASE_WODICT); - } - - PythonBuiltinClassType(String name, String module, TpSlots slots) { - this(name, module, Flags.PUBLIC_BASE_WODICT, slots); - } - - PythonBuiltinClassType(String name, String module, long methodsFlags) { - this(name, module, Flags.PUBLIC_BASE_WODICT, methodsFlags); - } - - PythonBuiltinClassType(String name, String module, long methodsFlags, TpSlots slots) { - this(name, module, Flags.PUBLIC_BASE_WODICT, methodsFlags, slots); - } - - PythonBuiltinClassType(String name, Flags flags) { - this(name, null, flags); - } - - PythonBuiltinClassType(String name, Flags flags, TpSlots slots) { - this(name, null, flags, slots); - } - - PythonBuiltinClassType(String name, Flags flags, long methodsFlags) { - this(name, null, flags, methodsFlags); - } - - PythonBuiltinClassType(String name, Flags flags, long methodsFlags, TpSlots slots) { - this(name, null, flags, methodsFlags, slots); - } - - PythonBuiltinClassType(String name) { - this(name, null, Flags.PRIVATE_BASE_WODICT); + this.declaredSlots = builder.slots != null ? builder.slots : TpSlots.createEmpty(); + boolean disallowInstantiation = builder.disallowInstantiation; + // logic from type_ready_set_new + // base.base == null is a roundabout way to check for base == object + if (declaredSlots.tp_new() == null && base.base == null) { + disallowInstantiation = true; + } + if (base == null) { + this.slots = declaredSlots; + } else { + var slotBuilder = base.slots.copy(); + slotBuilder.overrideIgnoreGroups(declaredSlots); + if (disallowInstantiation) { + slotBuilder.set(TpSlots.TpSlotMeta.TP_NEW, null); + } + this.slots = slotBuilder.build(); + } + this.disallowInstantiation = disallowInstantiation; + this.doc = toTruffleStringUncached(builder.doc); } public boolean isAcceptableBase() { @@ -737,6 +1313,10 @@ public boolean isBuiltinWithDict() { return isBuiltinWithDict; } + public boolean disallowInstantiation() { + return disallowInstantiation; + } + public TruffleString getPublishInModule() { return publishInModule; } @@ -745,11 +1325,8 @@ public TruffleString getModuleName() { return moduleName; } - /** - * Access the values using methods in {@link SpecialMethodSlot}. - */ - public Object[] getSpecialMethodSlots() { - return specialMethodSlots; + public TruffleString getDoc() { + return doc; } public TpSlots getSlots() { @@ -760,38 +1337,10 @@ public TpSlots getDeclaredSlots() { return declaredSlots; } - public void setSpecialMethodSlots(Object[] slots) { - assert specialMethodSlots == null; // should be assigned only once per VM - specialMethodSlots = slots; - } - - public long getMethodsFlags() { - return methodsFlags; - } - public int getWeaklistoffset() { return weaklistoffset; } - /** - * Returns {@code true} if this method slot is redefined in Python code during initialization. - * Values of such slots cannot be cached in {@link #specialMethodSlots}, because they are not - * context independent. - */ - public boolean redefinesSlot(SpecialMethodSlot slot) { - if (redefinedSlots != null) { - for (SpecialMethodSlot redefSlot : redefinedSlots) { - if (redefSlot == slot) { - return true; - } - } - } - if (base != null) { - return base.redefinesSlot(slot); - } - return false; - } - @Override public String toString() { CompilerAsserts.neverPartOfCompilation(); @@ -799,216 +1348,19 @@ public String toString() { } public final Shape getInstanceShape(PythonLanguage lang) { - if (name == null) { - throw CompilerDirectives.shouldNotReachHere("incorrect use of Python builtin type marker"); - } return lang.getBuiltinTypeInstanceShape(this); } - @CompilationFinal(dimensions = 1) public static final PythonBuiltinClassType[] VALUES = Arrays.copyOf(values(), values().length - 1); + @CompilationFinal(dimensions = 1) public static final PythonBuiltinClassType[] VALUES = Arrays.copyOf(values(), values().length); static { - // fill the overridden slots - SpecialMethodSlot[] repr = new SpecialMethodSlot[]{SpecialMethodSlot.Repr}; - SpecialMethodSlot[] reprAndNew = new SpecialMethodSlot[]{SpecialMethodSlot.Repr, SpecialMethodSlot.New}; - - PythonModule.redefinedSlots = Super.redefinedSlots = repr; - SyntaxError.redefinedSlots = new SpecialMethodSlot[]{SpecialMethodSlot.Str}; - UnicodeEncodeError.redefinedSlots = new SpecialMethodSlot[]{SpecialMethodSlot.Str}; - UnicodeDecodeError.redefinedSlots = new SpecialMethodSlot[]{SpecialMethodSlot.Str}; - UnicodeTranslateError.redefinedSlots = new SpecialMethodSlot[]{SpecialMethodSlot.Str}; - OSError.redefinedSlots = new SpecialMethodSlot[]{SpecialMethodSlot.Str}; - PStructUnpackIterator.redefinedSlots = new SpecialMethodSlot[]{SpecialMethodSlot.Next, SpecialMethodSlot.Iter, SpecialMethodSlot.LengthHint}; - - // These slots actually contain context independent values, but they are initialized in - // StructSequence to artificial PBuiltinFunctions with artificial builtin node factories, - // which are different for each context. We'd have to turn those factories into singletons - // to guarantee their identity across contexts. For the sake of simplicity, we just ignore - // those slots for now. - PStruct.type = PythonClass; - PStructRusage.redefinedSlots = reprAndNew; - PStructPasswd.redefinedSlots = reprAndNew; - PUnameResult.redefinedSlots = reprAndNew; - PUnraisableHookArgs.redefinedSlots = reprAndNew; - PIntInfo.redefinedSlots = reprAndNew; - PHashInfo.redefinedSlots = reprAndNew; - PStructTime.redefinedSlots = reprAndNew; - PProfilerEntry.redefinedSlots = reprAndNew; - PProfilerSubentry.redefinedSlots = reprAndNew; - PThreadInfo.redefinedSlots = reprAndNew; - PStatResult.redefinedSlots = repr; - PStatvfsResult.redefinedSlots = repr; - PFloatInfo.redefinedSlots = reprAndNew; - PVersionInfo.redefinedSlots = repr; - PWindowsVersion.redefinedSlots = repr; - PFlags.redefinedSlots = repr; - PTerminalSize.redefinedSlots = reprAndNew; - PythonObject.type = PythonClass; - PythonObject.base = null; - - PBuiltinMethod.base = PBuiltinFunctionOrMethod; - - Boolean.base = PInt; - - PBaseExceptionGroup.base = PBaseException; - SystemExit.base = PBaseException; - KeyboardInterrupt.base = PBaseException; - GeneratorExit.base = PBaseException; - Exception.base = PBaseException; - StopIteration.base = Exception; - StopAsyncIteration.base = Exception; - ArithmeticError.base = Exception; - FloatingPointError.base = ArithmeticError; - OverflowError.base = ArithmeticError; - ZeroDivisionError.base = ArithmeticError; - AssertionError.base = Exception; - AttributeError.base = Exception; - BufferError.base = Exception; - EOFError.base = Exception; - ImportError.base = Exception; - ModuleNotFoundError.base = ImportError; - LookupError.base = Exception; - IndexError.base = LookupError; - KeyError.base = LookupError; - MemoryError.base = Exception; - NameError.base = Exception; - UnboundLocalError.base = NameError; - OSError.base = Exception; - BlockingIOError.base = OSError; - ChildProcessError.base = OSError; - ConnectionError.base = OSError; - BrokenPipeError.base = ConnectionError; - ConnectionAbortedError.base = ConnectionError; - ConnectionRefusedError.base = ConnectionError; - ConnectionResetError.base = ConnectionError; - FileExistsError.base = OSError; - FileNotFoundError.base = OSError; - InterruptedError.base = OSError; - IsADirectoryError.base = OSError; - NotADirectoryError.base = OSError; - PermissionError.base = OSError; - ProcessLookupError.base = OSError; - TimeoutError.base = OSError; - ZLibError.base = Exception; - CSVError.base = Exception; - LZMAError.base = Exception; - SocketGAIError.base = OSError; - SocketHError.base = OSError; - - SSLError.base = OSError; - SSLZeroReturnError.base = SSLError; - SSLWantReadError.base = SSLError; - SSLWantWriteError.base = SSLError; - SSLSyscallError.base = SSLError; - SSLCertVerificationError.base = SSLError; - SSLEOFError.base = SSLError; - - ReferenceError.base = Exception; - RuntimeError.base = Exception; - NotImplementedError.base = RuntimeError; - SyntaxError.base = Exception; - IndentationError.base = SyntaxError; - TabError.base = IndentationError; - SystemError.base = Exception; - TypeError.base = Exception; - ValueError.base = Exception; - UnicodeError.base = ValueError; - UnicodeDecodeError.base = UnicodeError; - UnicodeEncodeError.base = UnicodeError; - UnicodeTranslateError.base = UnicodeError; - RecursionError.base = RuntimeError; - StructError.base = Exception; - BinasciiError.base = ValueError; - BinasciiIncomplete.base = Exception; - PickleError.base = Exception; - PicklingError.base = PickleError; - UnpicklingError.base = PickleError; - - // warnings - Warning.base = Exception; - BytesWarning.base = Warning; - DeprecationWarning.base = Warning; - FutureWarning.base = Warning; - ImportWarning.base = Warning; - PendingDeprecationWarning.base = Warning; - ResourceWarning.base = Warning; - RuntimeWarning.base = Warning; - SyntaxWarning.base = Warning; - UnicodeWarning.base = Warning; - UserWarning.base = Warning; - EncodingWarning.base = Warning; - - PStatResult.base = PTuple; - PStatvfsResult.base = PTuple; - PTerminalSize.base = PTuple; - PUnameResult.base = PTuple; - PStructTime.base = PTuple; - PProfilerEntry.base = PTuple; - PProfilerSubentry.base = PTuple; - PStructPasswd.base = PTuple; - PStructRusage.base = PTuple; - PVersionInfo.base = PTuple; - PWindowsVersion.base = PTuple; - PFlags.base = PTuple; - PFloatInfo.base = PTuple; - PIntInfo.base = PTuple; - PHashInfo.base = PTuple; - PThreadInfo.base = PTuple; - PUnraisableHookArgs.base = PTuple; - PDefaultDict.base = PDict; - POrderedDict.base = PDict; - POrderedDictKeys.base = PDictKeysView; - POrderedDictValues.base = PDictValuesView; - POrderedDictItems.base = PDictItemsView; - - PArrayIterator.type = PythonClass; - PSocket.type = PythonClass; - - // _io.UnsupportedOperation inherits from ValueError and OSError - // done currently within IOModuleBuiltins class - IOUnsupportedOperation.base = OSError; - - PRawIOBase.base = PIOBase; - PTextIOBase.base = PIOBase; - PBufferedIOBase.base = PIOBase; - PBufferedReader.base = PBufferedIOBase; - PBufferedWriter.base = PBufferedIOBase; - PBufferedRWPair.base = PBufferedIOBase; - PBufferedRandom.base = PBufferedIOBase; - PBytesIO.base = PBufferedIOBase; - PFileIO.base = PRawIOBase; - PTextIOWrapper.base = PTextIOBase; - PStringIO.base = PTextIOBase; - - // hashlib - UnsupportedDigestmodError.base = ValueError; - HashlibHashXof.base = HashlibHash; - - // _ctypes - StgDict.base = PDict; - PyCStructType.base = PythonClass; - UnionType.base = PythonClass; - PyCPointerType.base = PythonClass; - PyCArrayType.base = PythonClass; - PyCSimpleType.base = PythonClass; - PyCFuncPtrType.base = PythonClass; Structure.type = PyCStructType; - Structure.base = PyCData; Union.type = UnionType; - Union.base = PyCData; PyCPointer.type = PyCPointerType; - PyCPointer.base = PyCData; PyCArray.type = PyCArrayType; - PyCArray.base = PyCData; SimpleCData.type = PyCSimpleType; - SimpleCData.base = PyCData; PyCFuncPtr.type = PyCFuncPtrType; - PyCFuncPtr.base = PyCData; - ArgError.base = PBaseException; - - Empty.base = Exception; - UnsupportedMessage.base = Exception; boolean assertionsEnabled = false; assert (assertionsEnabled = true) == true; @@ -1017,11 +1369,6 @@ public final Shape getInstanceShape(PythonLanguage lang) { // check uniqueness assert set.add("" + type.moduleName + "." + type.name) : type.name(); - /* Initialize type.base (defaults to PythonObject unless that's us) */ - if (type.base == null && type != PythonObject) { - type.base = PythonObject; - } - /* * Now the only way base can still be null is if type is PythonObject. */ @@ -1038,23 +1385,6 @@ public final Shape getInstanceShape(PythonLanguage lang) { type.type = PythonClass; } } - - for (PythonBuiltinClassType t : values()) { - initSlots(t); - } - } - - private static void initSlots(PythonBuiltinClassType type) { - if (type.base == null) { - type.slots = type.declaredSlots; - return; - } - if (type.base.getSlots() == null) { - initSlots(type.base); - } - var slots = type.base.slots.copy(); - slots.overrideIgnoreGroups(type.declaredSlots); - type.slots = slots.build(); } /** @@ -1068,10 +1398,6 @@ private static void initSlots(PythonBuiltinClassType type) { * {@link PythonBuiltins} classes annotated with {@link CoreFunctions#extendClasses()} that * contains the {@link PythonBuiltinClassType}. *

    - * If a {@link PythonBuiltinClassType#declaredSlots} should be initialized to a merge of slots - * from multiple {@link CoreFunctions}, use the helper methods, such as - * {@link TpSlots#merge(TpSlots, TpSlots)}. - *

    * Note: this is all done so that the generated slots code is referenced only from the class * that contains the {@link Slot} annotation and that we can initialize the * {@link PythonBuiltinClassType#slots} in static ctor and bake the values into native-image @@ -1121,11 +1447,11 @@ static boolean verifySlotsConventions(PythonBuiltins[] allBuiltins) { assert getSlotsFieldValue(builtins.get(0)) == type.declaredSlots; } else { // Multiple @CoreFunctions => PBCT.declaredSlots must be equal to their merge - Builder builder = TpSlots.newBuilder(); + TpSlots.Builder builder = TpSlots.newBuilder(); for (PythonBuiltins builtin : builtins) { TpSlots slots = getSlotsFieldValue(builtin); if (slots != null) { - builder.merge(slots); + builder.overrideIgnoreGroups(slots); } } assert type.declaredSlots.areEqualTo(builder.build()) : String.format("%s.declaredSlots are not equal to the merge of SLOTS " + @@ -1137,6 +1463,9 @@ static boolean verifySlotsConventions(PythonBuiltins[] allBuiltins) { } private static boolean hasSlotNodes(PythonBuiltins builtin) { + if (builtin.getClass().getAnnotation(HashNotImplemented.class) != null) { + return true; + } for (Class innerClass : builtin.getClass().getDeclaredClasses()) { if (innerClass.getDeclaredAnnotationsByType(Slot.class).length > 0) { return true; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltins.java index 89f6cc235b..5db6d64e43 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -26,86 +26,6 @@ package com.oracle.graal.python.builtins; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ABS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ADD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___AITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___AND__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ANEXT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___AWAIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___BOOL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CONTAINS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___DELATTR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___DELETE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___DELITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___DEL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___DIVMOD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___FLOAT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___FLOORDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETATTRIBUTE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETATTR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GET__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IADD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IAND__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IFLOORDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ILSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IMATMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IMOD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INDEX__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INVERT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IOR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IPOW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IRSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ISUB__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITRUEDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IXOR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LEN__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___MATMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___MOD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___MUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEG__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___OR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___POS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___POW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RADD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RAND__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RDIVMOD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RFLOORDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RLSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RMATMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RMOD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ROR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RPOW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RRSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RSUB__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RTRUEDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RXOR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETATTR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SET__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SUB__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___TRUEDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___XOR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEW__; import static com.oracle.graal.python.nodes.truffle.TruffleStringMigrationHelpers.assertNoJavaString; import static com.oracle.graal.python.nodes.truffle.TruffleStringMigrationHelpers.ensureNoJavaString; import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; @@ -114,20 +34,20 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.builtins.modules.ImpModuleBuiltins.ExecBuiltin; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; -import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.BiConsumer; import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.strings.TruffleString; @@ -160,79 +80,47 @@ public void initialize(Python3Core core) { initializeEachFactoryWith((factory, builtin) -> { CoreFunctions annotation = getClass().getAnnotation(CoreFunctions.class); final boolean declaresExplicitSelf; - PythonBuiltinClassType constructsClass = builtin.constructsClass(); - if ((annotation.defineModule().length() > 0 || annotation.extendsModule().length() > 0) && constructsClass == PythonBuiltinClassType.nil) { + if ((annotation.defineModule().length() > 0 || annotation.extendsModule().length() > 0)) { assert !builtin.isGetter(); assert !builtin.isSetter(); assert annotation.extendClasses().length == 0; // for module functions, explicit self is false by default declaresExplicitSelf = builtin.declaresExplicitSelf(); - } else if (builtin.constructsClass() != PythonBuiltinClassType.nil) { - declaresExplicitSelf = false; } else { declaresExplicitSelf = true; } TruffleString tsName = toTruffleStringUncached(builtin.name()); - RootCallTarget callTarget = core.getLanguage().initBuiltinCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, factory, declaresExplicitSelf), factory.getNodeClass(), + PythonLanguage language = core.getLanguage(); + RootCallTarget callTarget = language.initBuiltinCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, factory, declaresExplicitSelf), factory.getNodeClass(), builtin.name()); Object builtinDoc = builtin.doc().isEmpty() ? PNone.NONE : toTruffleStringUncached(builtin.doc()); int flags = PBuiltinFunction.getFlags(builtin, callTarget); - if (constructsClass != PythonBuiltinClassType.nil) { - assert !builtin.isGetter() && !builtin.isSetter() && !builtin.isClassmethod() && !builtin.isStaticmethod(); - // we explicitly do not make these "staticmethods" here, since CPython also doesn't - // for builtin types - PBuiltinFunction newFunc = core.factory().createBuiltinFunction(T___NEW__, constructsClass, numDefaults(builtin), flags, callTarget); - PBuiltinMethod newMethod = core.factory().createBuiltinMethod(constructsClass, newFunc); - PythonBuiltinClass builtinClass = core.lookupType(constructsClass); - builtinClass.setAttributeUnsafe(T___NEW__, newMethod); - final Object currentBuiltinDoc = builtinClass.getAttribute(T___DOC__); - if (PGuards.isPNone(currentBuiltinDoc)) { - builtinClass.setAttribute(T___DOC__, builtinDoc); - } - } else { - PBuiltinFunction function; - if (isSlotMethod(builtin)) { - // HACK: TODO: we should not see any slots here anymore once all are converted - // to slots, then we can make the slot field in PBuiltinFunction final, for now, - // we patch it in TpSlots#wrapBuiltinSlots - function = core.factory().createWrapperDescriptor(tsName, null, numDefaults(builtin), flags, callTarget, null, null); - } else { - function = core.factory().createBuiltinFunction(tsName, null, numDefaults(builtin), flags, callTarget); - } - function.setAttribute(T___DOC__, builtinDoc); - BoundBuiltinCallable callable = function; - if (builtin.isGetter() || builtin.isSetter()) { - assert !builtin.isClassmethod() && !builtin.isStaticmethod(); - PBuiltinFunction get = builtin.isGetter() ? function : null; - PBuiltinFunction set = builtin.isSetter() ? function : null; - callable = core.factory().createGetSetDescriptor(get, set, tsName, null, builtin.allowsDelete()); - } else if (builtin.isClassmethod()) { - assert !builtin.isStaticmethod(); - callable = core.factory().createBuiltinClassmethodFromCallableObj(function); - } else if (builtin.isStaticmethod()) { - callable = core.factory().createStaticmethodFromCallableObj(function); - } - builtinFunctions.put(toTruffleStringUncached(builtin.name()), callable); + PBuiltinFunction function = PFactory.createBuiltinFunction(language, tsName, null, numDefaults(builtin), flags, callTarget); + function.setAttribute(T___DOC__, builtinDoc); + BoundBuiltinCallable callable = function; + if (builtin.isGetter() || builtin.isSetter()) { + assert !builtin.isClassmethod() && !builtin.isStaticmethod(); + PBuiltinFunction get = builtin.isGetter() ? function : null; + PBuiltinFunction set = builtin.isSetter() ? function : null; + callable = PFactory.createGetSetDescriptor(language, get, set, tsName, null, builtin.allowsDelete()); + } else if (builtin.isClassmethod()) { + assert !builtin.isStaticmethod(); + callable = PFactory.createBuiltinClassmethodFromCallableObj(language, function); + } else if (builtin.isStaticmethod()) { + callable = PFactory.createStaticmethodFromCallableObj(language, function); } + builtinFunctions.put(toTruffleStringUncached(builtin.name()), callable); }); } - // All methods that are really slots in CPython - private static final Set SLOTS = Set.of(J___ABS__, J___ADD__, J___AITER__, J___AND__, J___ANEXT__, J___AWAIT__, J___BOOL__, J___CALL__, J___CONTAINS__, J___DELATTR__, J___DELETE__, - J___DELITEM__, J___DEL__, J___DIVMOD__, J___EQ__, J___FLOAT__, J___FLOORDIV__, J___GETATTRIBUTE__, J___GETATTR__, J___GETITEM__, J___GET__, J___GE__, J___GT__, J___HASH__, - J___IADD__, J___IAND__, J___IFLOORDIV__, J___ILSHIFT__, J___IMATMUL__, J___IMOD__, J___IMUL__, J___INDEX__, J___INIT__, J___INT__, J___INVERT__, J___IOR__, J___IPOW__, - J___IRSHIFT__, J___ISUB__, J___ITER__, J___ITRUEDIV__, J___IXOR__, J___LEN__, J___LE__, J___LSHIFT__, J___LT__, J___MATMUL__, J___MOD__, J___MUL__, J___NEG__, J___NEW__, - J___NEXT__, J___NE__, J___OR__, J___POS__, J___POW__, J___RADD__, J___RAND__, J___RDIVMOD__, J___REPR__, J___RFLOORDIV__, J___RLSHIFT__, J___RMATMUL__, J___RMOD__, J___RMUL__, - J___ROR__, J___RPOW__, J___RRSHIFT__, J___RSHIFT__, J___RSUB__, J___RTRUEDIV__, J___RXOR__, J___SETATTR__, J___SETITEM__, J___SET__, J___STR__, J___SUB__, J___TRUEDIV__, - J___XOR__); - - private static boolean isSlotMethod(Builtin builtin) { - return builtin.name().startsWith("__") && SLOTS.contains(builtin.name()); - } - /** * Run any actions that can only be run in the post-initialization step, that is, if we're * actually going to start running rather than just pre-initializing. + *

    + * See {@link Python3Core#postInitialize(Env)} as postInitialize() is only run under some + * conditions. See also {@link ExecBuiltin}, tough that does not get called if the built-in + * module is actually shadowed by a frozen one, or if the built-in module is actually added to + * sys.modules during context initialization before the importlib exists, etc. */ public void postInitialize(@SuppressWarnings("unused") Python3Core core) { // nothing to do by default @@ -275,10 +163,18 @@ public static int numDefaults(Builtin builtin) { return maxNumPosArgs - builtin.minNumOfPositionalArgs(); } + /** + * May only be used in {@link #initialize} or before. Use {@link PythonObject#setAttribute} + * instead in {@link #postInitialize}. + */ protected final void addBuiltinConstant(String name, Object value) { addBuiltinConstant(toTruffleStringUncached(name), value); } + /** + * May only be used in {@link #initialize} or before. Use {@link PythonObject#setAttribute} + * instead in {@link #postInitialize}. + */ protected final void addBuiltinConstant(TruffleString name, Object value) { builtinConstants.put(name, ensureNoJavaString(value)); } @@ -294,18 +190,18 @@ void addConstantsToModuleObject(PythonObject obj) { } } - void addFunctionsToModuleObject(PythonObject obj, PythonObjectSlowPathFactory factory) { - addFunctionsToModuleObject(builtinFunctions, obj, factory); + void addFunctionsToModuleObject(PythonObject obj, PythonLanguage language) { + addFunctionsToModuleObject(builtinFunctions, obj, language); } - static void addFunctionsToModuleObject(Map> builtinFunctions, PythonObject obj, PythonObjectSlowPathFactory factory) { + static void addFunctionsToModuleObject(Map> builtinFunctions, PythonObject obj, PythonLanguage language) { + assert obj instanceof PythonModule || obj instanceof PythonBuiltinClass : "unexpected object while adding builtins"; for (Entry> entry : builtinFunctions.entrySet()) { Object value; - assert obj instanceof PythonModule || obj instanceof PythonBuiltinClass : "unexpected object while adding builtins"; if (obj instanceof PythonModule) { - value = factory.createBuiltinMethod(obj, (PBuiltinFunction) entry.getValue()); + value = PFactory.createBuiltinMethod(language, obj, (PBuiltinFunction) entry.getValue()); } else { - value = entry.getValue().boundToObject(((PythonBuiltinClass) obj).getType(), factory); + value = entry.getValue().boundToObject(((PythonBuiltinClass) obj).getType(), language); } obj.setAttribute(entry.getKey(), value); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonOS.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonOS.java index 67114eb762..338e50f1ab 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonOS.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonOS.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,25 +45,31 @@ import com.oracle.truffle.api.strings.TruffleString; public enum PythonOS { - PLATFORM_JAVA("java"), - PLATFORM_CYGWIN("cygwin"), - PLATFORM_LINUX("linux"), - PLATFORM_DARWIN("darwin"), - PLATFORM_WIN32("win32"), - PLATFORM_SUNOS("sunos"), - PLATFORM_FREEBSD("freebsd"), - PLATFORM_ANY(null); + PLATFORM_JAVA("java", "Java"), + PLATFORM_CYGWIN("cygwin", "CYGWIN"), + PLATFORM_LINUX("linux", "Linux"), + PLATFORM_DARWIN("darwin", "Darwin"), + PLATFORM_WIN32("win32", "Windows"), + PLATFORM_SUNOS("sunos", "SunOS"), + PLATFORM_FREEBSD("freebsd", "FreeBSD"), + PLATFORM_ANY(null, null); private final TruffleString name; + private final TruffleString uname; - PythonOS(String name) { + PythonOS(String name, String uname) { this.name = toTruffleStringUncached(name); + this.uname = toTruffleStringUncached(uname); } public TruffleString getName() { return name; } + public TruffleString getUname() { + return uname; + } + private static final PythonOS current; static { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AbcModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AbcModuleBuiltins.java index 18b4c9bb56..ac6be1a5ce 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AbcModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AbcModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -58,10 +58,10 @@ import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetSubclassesAsArrayNode; import com.oracle.graal.python.lib.PyObjectLookupAttr; +import com.oracle.graal.python.lib.PyObjectSetAttr; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.DeleteAttributeNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; @@ -70,7 +70,6 @@ import com.oracle.graal.python.runtime.PythonContext; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; @@ -94,8 +93,7 @@ abstract static class AbcInitCollectionFlagsNode extends PythonUnaryBuiltinNode @TruffleBoundary @Specialization static Object init(Object object, - @Bind("this") Node inliningTarget, - @Cached DeleteAttributeNode deleteAttributeNode) { + @Bind("this") Node inliningTarget) { if (TypeNodes.IsTypeNode.executeUncached(object)) { Object flags = PyObjectLookupAttr.executeUncached(object, ABC_TPFLAGS); long val; @@ -105,7 +103,7 @@ static Object init(Object object, return PNone.NONE; } if ((val & COLLECTION_FLAGS) == COLLECTION_FLAGS) { - throw PRaiseNode.raiseUncached(inliningTarget, TypeError, ErrorMessages.ABC_FLAGS_CANNOT_BE_SEQUENCE_AND_MAPPING); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.ABC_FLAGS_CANNOT_BE_SEQUENCE_AND_MAPPING); } long tpFlags = TypeNodes.GetTypeFlagsNode.getUncached().execute(object); tpFlags |= (val & COLLECTION_FLAGS); @@ -117,7 +115,7 @@ static Object init(Object object, type = (PythonAbstractObject) object; } HiddenAttr.WriteNode.executeUncached(type, HiddenAttr.FLAGS, tpFlags); - deleteAttributeNode.execute(null, inliningTarget, object, ABC_TPFLAGS); + PyObjectSetAttr.deleteUncached(object, ABC_TPFLAGS); } return PNone.NONE; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ArrayModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ArrayModuleBuiltins.java index ce713d1aa2..687b9202d3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ArrayModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ArrayModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -27,75 +27,44 @@ import static com.oracle.graal.python.nodes.BuiltinNames.J_ARRAY; import static com.oracle.graal.python.nodes.BuiltinNames.T_ARRAY; -import static com.oracle.graal.python.nodes.ErrorMessages.S_TAKES_AT_LEAST_D_ARGUMENTS_D_GIVEN; -import static com.oracle.graal.python.nodes.ErrorMessages.S_TAKES_AT_MOST_D_ARGUMENTS_D_GIVEN; -import static com.oracle.graal.python.nodes.ErrorMessages.S_TAKES_NO_KEYWORD_ARGS; import static com.oracle.graal.python.nodes.SpecialMethodNames.T_DECODE; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.MemoryError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import java.nio.ByteOrder; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.array.ArrayBuiltins; -import com.oracle.graal.python.builtins.objects.array.ArrayNodes; import com.oracle.graal.python.builtins.objects.array.PArray; import com.oracle.graal.python.builtins.objects.array.PArray.MachineFormat; import com.oracle.graal.python.builtins.objects.bytes.PBytes; -import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; -import com.oracle.graal.python.builtins.objects.common.SequenceNodes; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; -import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.builtins.objects.range.PIntRange; -import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringCheckedNode; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; -import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassExactProfile; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; -import com.oracle.graal.python.nodes.util.SplitArgsNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.runtime.sequence.PSequence; -import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.BufferFormat; -import com.oracle.graal.python.util.OverflowException; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateNodeFactory; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.api.strings.TruffleString; @@ -115,225 +84,6 @@ public void postInitialize(Python3Core core) { arrayModule.setAttribute(tsLiteral("typecodes"), tsLiteral("bBuhHiIlLqQfd")); } - // array.array(typecode[, initializer]) - @Builtin(name = J_ARRAY, minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.PArray, takesVarArgs = true, takesVarKeywordArgs = true, declaresExplicitSelf = true) - @GenerateNodeFactory - abstract static class ArrayNode extends PythonVarargsBuiltinNode { - @Child private SplitArgsNode splitArgsNode; - - @Specialization(guards = "args.length == 1 || args.length == 2") - static Object array2(VirtualFrame frame, Object cls, Object[] args, PKeyword[] kwargs, - @Bind("this") Node inliningTarget, - @Cached InlinedConditionProfile hasInitializerProfile, - @Cached IsBuiltinClassExactProfile isNotSubtypeProfile, - @Cached CastToTruffleStringCheckedNode cast, - @Cached ArrayNodeInternal arrayNodeInternal, - @Cached PRaiseNode.Lazy raise) { - if (isNotSubtypeProfile.profileClass(inliningTarget, cls, PythonBuiltinClassType.PArray)) { - if (kwargs.length != 0) { - throw raise.get(inliningTarget).raise(TypeError, S_TAKES_NO_KEYWORD_ARGS, "array.array()"); - } - } - Object initializer = hasInitializerProfile.profile(inliningTarget, args.length == 2) ? args[1] : PNone.NO_VALUE; - return arrayNodeInternal.execute(frame, inliningTarget, cls, cast.cast(inliningTarget, args[0], ErrorMessages.ARG_1_MUST_BE_UNICODE_NOT_P, args[0]), initializer); - } - - @Fallback - @SuppressWarnings("unused") - Object error(Object cls, Object[] args, PKeyword[] kwargs) { - if (args.length < 2) { - throw raise(TypeError, S_TAKES_AT_LEAST_D_ARGUMENTS_D_GIVEN, T_ARRAY, 2, args.length); - } else { - throw raise(TypeError, S_TAKES_AT_MOST_D_ARGUMENTS_D_GIVEN, T_ARRAY, 3, args.length); - } - } - - @Override - public final Object varArgExecute(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported { - if (splitArgsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - splitArgsNode = insert(SplitArgsNode.create()); - } - return execute(frame, arguments[0], splitArgsNode.executeCached(arguments), keywords); - } - - // multiple non-inlined specializations share nodes - @SuppressWarnings("truffle-interpreted-performance") - @ImportStatic(PGuards.class) - @GenerateInline - @GenerateCached(false) - abstract static class ArrayNodeInternal extends Node { - - public abstract PArray execute(VirtualFrame frame, Node inliningTarget, Object cls, TruffleString typeCode, Object initializer); - - @Specialization(guards = "isNoValue(initializer)") - static PArray array(Node inliningTarget, Object cls, TruffleString typeCode, @SuppressWarnings("unused") PNone initializer, - @Shared @Cached GetFormatCheckedNode getFormatCheckedNode, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - BufferFormat format = getFormatCheckedNode.execute(inliningTarget, typeCode); - return factory.createArray(cls, typeCode, format); - } - - @Specialization - @InliningCutoff - static PArray arrayWithRangeInitializer(Node inliningTarget, Object cls, TruffleString typeCode, PIntRange range, - @Shared @Cached GetFormatCheckedNode getFormatCheckedNode, - @Shared @Cached(inline = false) PythonObjectFactory factory, - @Exclusive @Cached ArrayNodes.PutValueNode putValueNode) { - BufferFormat format = getFormatCheckedNode.execute(inliningTarget, typeCode); - PArray array; - try { - array = factory.createArray(cls, typeCode, format, range.getIntLength()); - } catch (OverflowException e) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); - } - - int start = range.getIntStart(); - int step = range.getIntStep(); - int len = range.getIntLength(); - - for (int index = 0, value = start; index < len; index++, value += step) { - putValueNode.execute(null, inliningTarget, array, index, value); - } - - return array; - } - - @Specialization - static PArray arrayWithBytesInitializer(VirtualFrame frame, Node inliningTarget, Object cls, TruffleString typeCode, PBytesLike bytes, - @Shared @Cached GetFormatCheckedNode getFormatCheckedNode, - @Shared @Cached(inline = false) PythonObjectFactory factory, - @Cached(inline = false) ArrayBuiltins.FromBytesNode fromBytesNode) { - BufferFormat format = getFormatCheckedNode.execute(inliningTarget, typeCode); - PArray array = factory.createArray(cls, typeCode, format); - fromBytesNode.executeWithoutClinic(frame, array, bytes); - return array; - } - - @Specialization(guards = "isString(initializer)") - @InliningCutoff - static PArray arrayWithStringInitializer(VirtualFrame frame, Node inliningTarget, Object cls, TruffleString typeCode, Object initializer, - @Shared @Cached GetFormatCheckedNode getFormatCheckedNode, - @Shared @Cached(inline = false) PythonObjectFactory factory, - @Cached(inline = false) ArrayBuiltins.FromUnicodeNode fromUnicodeNode, - @Cached PRaiseNode.Lazy raise) { - BufferFormat format = getFormatCheckedNode.execute(inliningTarget, typeCode); - if (format != BufferFormat.UNICODE) { - throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.CANNOT_USE_STR_TO_INITIALIZE_ARRAY, typeCode); - } - PArray array = factory.createArray(cls, typeCode, format); - fromUnicodeNode.execute(frame, array, initializer); - return array; - } - - @Specialization - @InliningCutoff - static PArray arrayArrayInitializer(VirtualFrame frame, Node inliningTarget, Object cls, TruffleString typeCode, PArray initializer, - @Shared @Cached GetFormatCheckedNode getFormatCheckedNode, - @Shared @Cached(inline = false) PythonObjectFactory factory, - @Exclusive @Cached ArrayNodes.PutValueNode putValueNode, - @Cached ArrayNodes.GetValueNode getValueNode) { - BufferFormat format = getFormatCheckedNode.execute(inliningTarget, typeCode); - try { - int length = initializer.getLength(); - PArray array = factory.createArray(cls, typeCode, format, length); - for (int i = 0; i < length; i++) { - putValueNode.execute(frame, inliningTarget, array, i, getValueNode.execute(inliningTarget, initializer, i)); - } - return array; - } catch (OverflowException e) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); - } - } - - @Specialization(guards = "!isBytes(initializer)") - @InliningCutoff - static PArray arraySequenceInitializer(VirtualFrame frame, Node inliningTarget, Object cls, TruffleString typeCode, PSequence initializer, - @Shared @Cached GetFormatCheckedNode getFormatCheckedNode, - @Shared @Cached(inline = false) PythonObjectFactory factory, - @Exclusive @Cached ArrayNodes.PutValueNode putValueNode, - @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode, - @Cached SequenceStorageNodes.GetItemScalarNode getItemNode) { - BufferFormat format = getFormatCheckedNode.execute(inliningTarget, typeCode); - SequenceStorage storage = getSequenceStorageNode.execute(inliningTarget, initializer); - int length = storage.length(); - try { - PArray array = factory.createArray(cls, typeCode, format, length); - for (int i = 0; i < length; i++) { - putValueNode.execute(frame, inliningTarget, array, i, getItemNode.execute(inliningTarget, storage, i)); - } - return array; - } catch (OverflowException e) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); - } - } - - @Specialization(guards = {"!isBytes(initializer)", "!isString(initializer)", "!isPSequence(initializer)"}) - @InliningCutoff - static PArray arrayIteratorInitializer(VirtualFrame frame, Node inliningTarget, Object cls, TruffleString typeCode, Object initializer, - @Cached PyObjectGetIter getIter, - @Shared @Cached GetFormatCheckedNode getFormatCheckedNode, - @Shared @Cached(inline = false) PythonObjectFactory factory, - @Exclusive @Cached ArrayNodes.PutValueNode putValueNode, - @Cached(inline = false) GetNextNode nextNode, - @Cached IsBuiltinObjectProfile errorProfile, - @Cached ArrayNodes.SetLengthNode setLengthNode, - @Cached ArrayNodes.EnsureCapacityNode ensureCapacityNode) { - Object iter = getIter.execute(frame, inliningTarget, initializer); - - BufferFormat format = getFormatCheckedNode.execute(inliningTarget, typeCode); - PArray array = factory.createArray(cls, typeCode, format); - - int length = 0; - while (true) { - Object nextValue; - try { - nextValue = nextNode.execute(frame, iter); - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); - break; - } - try { - length = PythonUtils.addExact(length, 1); - ensureCapacityNode.execute(inliningTarget, array, length); - } catch (OverflowException e) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); - } - putValueNode.execute(frame, inliningTarget, array, length - 1, nextValue); - } - - setLengthNode.execute(inliningTarget, array, length); - return array; - } - - @GenerateInline - @GenerateCached(false) - abstract static class GetFormatCheckedNode extends Node { - abstract BufferFormat execute(Node inliningTarget, TruffleString typeCode); - - @Specialization - static BufferFormat get(Node inliningTarget, TruffleString typeCode, - @Cached(inline = false) TruffleString.CodePointLengthNode lengthNode, - @Cached(inline = false) TruffleString.CodePointAtIndexNode atIndexNode, - @Cached PRaiseNode.Lazy raise, - @Cached(value = "createIdentityProfile()", inline = false) ValueProfile valueProfile) { - if (lengthNode.execute(typeCode, TS_ENCODING) != 1) { - throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.ARRAY_ARG_1_MUST_BE_UNICODE); - } - BufferFormat format = BufferFormat.forArray(typeCode, lengthNode, atIndexNode); - if (format == null) { - throw raise.get(inliningTarget).raise(ValueError, ErrorMessages.BAD_TYPECODE); - } - return valueProfile.profile(format); - } - } - } - } - @Builtin(name = "_array_reconstructor", minNumOfPositionalArgs = 4, numOfPositionalOnlyArgs = 4, parameterNames = {"arrayType", "typeCode", "mformatCode", "items"}) @ArgumentClinic(name = "typeCode", conversion = ArgumentClinic.ClinicConversion.TString) @ArgumentClinic(name = "mformatCode", conversion = ArgumentClinic.ClinicConversion.Index) @@ -349,18 +99,20 @@ static Object reconstructCached(VirtualFrame frame, Object arrayType, TruffleStr @Exclusive @Cached PyObjectCallMethodObjArgs callDecode, @Exclusive @Cached ArrayBuiltins.FromBytesNode fromBytesNode, @Exclusive @Cached ArrayBuiltins.FromUnicodeNode fromUnicodeNode, + @Exclusive @Cached TypeNodes.IsTypeNode isTypeNode, @Exclusive @Cached IsSubtypeNode isSubtypeNode, @Exclusive @Cached ArrayBuiltins.ByteSwapNode byteSwapNode, @Exclusive @Cached TruffleString.CodePointLengthNode lengthNode, @Exclusive @Cached TruffleString.CodePointAtIndexNode atIndexNode, - @Exclusive @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Exclusive @Cached PRaiseNode raiseNode) { BufferFormat format = BufferFormat.forArray(typeCode, lengthNode, atIndexNode); if (format == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.BAD_TYPECODE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.BAD_TYPECODE); } - return doReconstruct(frame, inliningTarget, arrayType, typeCode, cachedCode, bytes, callDecode, fromBytesNode, fromUnicodeNode, isSubtypeNode, byteSwapNode, formatProfile.profile(format), - factory, raiseNode); + return doReconstruct(frame, inliningTarget, arrayType, typeCode, cachedCode, bytes, callDecode, fromBytesNode, fromUnicodeNode, isTypeNode, isSubtypeNode, byteSwapNode, + formatProfile.profile(format), + getInstanceShape, raiseNode); } @Specialization(replaces = "reconstructCached") @@ -369,35 +121,41 @@ static Object reconstruct(VirtualFrame frame, Object arrayType, TruffleString ty @Exclusive @Cached PyObjectCallMethodObjArgs callDecode, @Exclusive @Cached ArrayBuiltins.FromBytesNode fromBytesNode, @Exclusive @Cached ArrayBuiltins.FromUnicodeNode fromUnicodeNode, + @Exclusive @Cached TypeNodes.IsTypeNode isTypeNode, @Exclusive @Cached IsSubtypeNode isSubtypeNode, @Exclusive @Cached ArrayBuiltins.ByteSwapNode byteSwapNode, @Exclusive @Cached TruffleString.CodePointLengthNode lengthNode, @Exclusive @Cached TruffleString.CodePointAtIndexNode atIndexNode, - @Exclusive @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Exclusive @Cached PRaiseNode raiseNode) { BufferFormat format = BufferFormat.forArray(typeCode, lengthNode, atIndexNode); if (format == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.BAD_TYPECODE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.BAD_TYPECODE); } - return doReconstruct(frame, inliningTarget, arrayType, typeCode, mformatCode, bytes, callDecode, fromBytesNode, fromUnicodeNode, isSubtypeNode, byteSwapNode, format, factory, raiseNode); + return doReconstruct(frame, inliningTarget, arrayType, typeCode, mformatCode, bytes, callDecode, fromBytesNode, fromUnicodeNode, isTypeNode, isSubtypeNode, byteSwapNode, format, + getInstanceShape, + raiseNode); } private static Object doReconstruct(VirtualFrame frame, Node inliningTarget, Object arrayType, TruffleString typeCode, int mformatCode, PBytes bytes, PyObjectCallMethodObjArgs callDecode, - ArrayBuiltins.FromBytesNode fromBytesNode, ArrayBuiltins.FromUnicodeNode fromUnicodeNode, IsSubtypeNode isSubtypeNode, + ArrayBuiltins.FromBytesNode fromBytesNode, ArrayBuiltins.FromUnicodeNode fromUnicodeNode, TypeNodes.IsTypeNode isTypeNode, IsSubtypeNode isSubtypeNode, ArrayBuiltins.ByteSwapNode byteSwapNode, BufferFormat format, - PythonObjectFactory factory, PRaiseNode.Lazy raiseNode) { - if (!isSubtypeNode.execute(frame, arrayType, PythonBuiltinClassType.PArray)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.N_NOT_SUBTYPE_OF_ARRAY, arrayType); + TypeNodes.GetInstanceShape getInstanceShape, PRaiseNode raiseNode) { + if (!isTypeNode.execute(inliningTarget, arrayType)) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.FIRST_ARGUMENT_MUST_BE_A_TYPE_OBJECT_NOT_P, arrayType); + } + if (!isSubtypeNode.execute(arrayType, PythonBuiltinClassType.PArray)) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.N_NOT_SUBTYPE_OF_ARRAY, arrayType); } MachineFormat machineFormat = MachineFormat.fromCode(mformatCode); if (machineFormat != null) { PArray array; if (machineFormat == MachineFormat.forFormat(format)) { - array = factory.createArray(arrayType, typeCode, machineFormat.format); + array = PFactory.createArray(PythonLanguage.get(inliningTarget), arrayType, getInstanceShape.execute(arrayType), typeCode, machineFormat.format); fromBytesNode.executeWithoutClinic(frame, array, bytes); } else { TruffleString newTypeCode = machineFormat.format == format ? typeCode : machineFormat.format.baseTypeCode; - array = factory.createArray(arrayType, newTypeCode, machineFormat.format); + array = PFactory.createArray(PythonLanguage.get(inliningTarget), arrayType, getInstanceShape.execute(arrayType), newTypeCode, machineFormat.format); if (machineFormat.unicodeEncoding != null) { Object decoded = callDecode.execute(frame, inliningTarget, bytes, T_DECODE, machineFormat.unicodeEncoding); fromUnicodeNode.execute(frame, array, decoded); @@ -410,15 +168,15 @@ private static Object doReconstruct(VirtualFrame frame, Node inliningTarget, Obj } return array; } else { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.THIRD_ARG_MUST_BE_A_VALID_MACHINE_CODE_FMT); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.THIRD_ARG_MUST_BE_A_VALID_MACHINE_CODE_FMT); } } @Specialization(guards = "!isPBytes(value)") @SuppressWarnings("unused") static Object error(Object arrayType, TruffleString typeCode, int mformatCode, Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.FOURTH_ARG_SHOULD_BE_BYTES, value); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.FOURTH_ARG_SHOULD_BE_BYTES, value); } protected static boolean isPBytes(Object obj) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AsyncioModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AsyncioModuleBuiltins.java index 86f6cdf903..c6a9900c1c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AsyncioModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AsyncioModuleBuiltins.java @@ -70,7 +70,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.statement.AbstractImportNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -99,7 +99,7 @@ static Object getCurrentLoop( @Cached PRaiseNode raise) { Object eventLoop = context.getThreadState(context.getLanguage(inliningTarget)).getRunningEventLoop(); if (eventLoop == null) { - throw raise.raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.NO_RUNNING_EVENT_LOOP); + throw raise.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.NO_RUNNING_EVENT_LOOP); } else { return eventLoop; } @@ -189,7 +189,7 @@ public Object enterTask(VirtualFrame frame, PythonModule self, Object loop, Obje if (item == null) { set.execute(frame, inliningTarget, dict, loop, task); } else { - throw raise.raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.CANT_ENTER_TASK_ALREADY_RUNNING, task, item); + throw raise.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.CANT_ENTER_TASK_ALREADY_RUNNING, task, item); } return PNone.NONE; } @@ -210,7 +210,7 @@ public Object leaveTask(VirtualFrame frame, PythonModule self, Object loop, Obje item = PNone.NONE; } if (item != task) { - throw raise.raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.TASK_NOT_ENTERED, task, item); + throw raise.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.TASK_NOT_ENTERED, task, item); } del.execute(frame, inliningTarget, dict, loop); return PNone.NONE; @@ -253,9 +253,8 @@ public Object unregisterTask(VirtualFrame frame, PythonModule self, Object task, @Override public void postInitialize(Python3Core core) { - PythonObjectSlowPathFactory factory = core.factory(); PythonModule self = core.lookupBuiltinModule(T__ASYNCIO); - self.setAttribute(CURRENT_TASKS_ATTR, factory.createDict()); + self.setAttribute(CURRENT_TASKS_ATTR, PFactory.createDict(core.getLanguage())); Object weakref = AbstractImportNode.importModule(WEAKREF); Object weakSetCls = PyObjectGetAttr.executeUncached(weakref, WEAKSET); Object weakSet = CallNode.executeUncached(weakSetCls); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BinasciiModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BinasciiModuleBuiltins.java index e4f0b202a0..aae17200d2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BinasciiModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BinasciiModuleBuiltins.java @@ -54,6 +54,7 @@ import java.util.Base64; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ClinicConverterFactory; import com.oracle.graal.python.builtins.Builtin; @@ -76,7 +77,7 @@ import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -153,9 +154,9 @@ static Object asciiString(TruffleString value, @Specialization(guards = "!isAscii(value, getCodeRangeNode)") static Object nonAsciiString(@SuppressWarnings("unused") TruffleString value, - @Shared("getCodeRange") @Cached @SuppressWarnings("unused") TruffleString.GetCodeRangeNode getCodeRangeNode, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.STRING_ARG_SHOULD_CONTAIN_ONLY_ASCII); + @Bind("this") Node inliningTarget, + @Shared("getCodeRange") @Cached @SuppressWarnings("unused") TruffleString.GetCodeRangeNode getCodeRangeNode) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.STRING_ARG_SHOULD_CONTAIN_ONLY_ASCII); } @Specialization @@ -163,20 +164,19 @@ static Object string(PString value, @Bind("this") Node inliningTarget, @Cached CastToTruffleStringNode cast, @Shared("getCodeRange") @Cached @SuppressWarnings("unused") TruffleString.GetCodeRangeNode getCodeRangeNode, - @Cached InlinedConditionProfile asciiProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached InlinedConditionProfile asciiProfile) { TruffleString ts = cast.execute(inliningTarget, value); if (asciiProfile.profile(inliningTarget, isAscii(ts, getCodeRangeNode))) { return asciiString(ts, getCodeRangeNode); } else { - return nonAsciiString(ts, getCodeRangeNode, raiseNode.get(inliningTarget)); + return nonAsciiString(ts, inliningTarget, getCodeRangeNode); } } @Fallback static Object error(@SuppressWarnings("unused") Object value, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.ARG_SHOULD_BE_BYTES_BUFFER_OR_ASCII_NOT_P, value); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.ARG_SHOULD_BE_BYTES_BUFFER_OR_ASCII_NOT_P, value); } @ClinicConverterFactory @@ -195,10 +195,10 @@ abstract static class A2bBase64Node extends PythonBinaryClinicBuiltinNode { PBytes doConvert(VirtualFrame frame, Object buffer, boolean strictMode, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { try { ByteSequenceStorage storage = b64decode(bufferLib.getInternalOrCopiedByteArray(buffer), bufferLib.getBufferLength(buffer), strictMode); - return factory.createBytes(storage); + return PFactory.createBytes(language, storage); } finally { bufferLib.release(buffer, frame, indirectCallData); } @@ -226,19 +226,19 @@ private ByteSequenceStorage b64decode(byte[] data, int dataLen, boolean strictMo } else if (c == '=') { padding++; } else if (strictMode) { - throw PRaiseNode.raiseUncached(this, BinasciiError, ErrorMessages.ONLY_BASE64_DATA_IS_ALLOWED); + throw PRaiseNode.raiseStatic(this, BinasciiError, ErrorMessages.ONLY_BASE64_DATA_IS_ALLOWED); } } int expectedPadding = 0; if (base64chars % 4 == 1) { - throw PRaiseNode.raiseUncached(this, BinasciiError, ErrorMessages.INVALID_BASE64_ENCODED_STRING); + throw PRaiseNode.raiseStatic(this, BinasciiError, ErrorMessages.INVALID_BASE64_ENCODED_STRING); } else if (base64chars % 4 == 2) { expectedPadding = 2; } else if (base64chars % 4 == 3) { expectedPadding = 1; } if (padding < expectedPadding) { - throw PRaiseNode.raiseUncached(this, BinasciiError, ErrorMessages.INCORRECT_PADDING); + throw PRaiseNode.raiseStatic(this, BinasciiError, ErrorMessages.INCORRECT_PADDING); } // Find the end of the expected padding, if any int decodeLen = lastBase64Char + 1; @@ -262,7 +262,7 @@ private ByteSequenceStorage b64decode(byte[] data, int dataLen, boolean strictMo ByteBuffer result = decoder.decode(ByteBuffer.wrap(data, 0, decodeLen)); return new ByteSequenceStorage(result.array(), result.limit()); } catch (IllegalArgumentException e) { - throw PRaiseNode.raiseUncached(this, BinasciiError, e); + throw PRaiseNode.raiseStatic(this, BinasciiError, e); } } @@ -280,10 +280,10 @@ abstract static class A2bHexNode extends PythonUnaryClinicBuiltinNode { PBytes a2b(VirtualFrame frame, Object buffer, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { try { byte[] bytes = a2b(bufferLib.getInternalOrCopiedByteArray(buffer), bufferLib.getBufferLength(buffer)); - return factory.createBytes(bytes); + return PFactory.createBytes(language, bytes); } finally { bufferLib.release(buffer, frame, indirectCallData); } @@ -292,7 +292,7 @@ PBytes a2b(VirtualFrame frame, Object buffer, @TruffleBoundary private byte[] a2b(byte[] bytes, int length) { if (length % 2 != 0) { - throw PRaiseNode.raiseUncached(this, BinasciiError, ErrorMessages.ODD_LENGTH_STRING); + throw PRaiseNode.raiseStatic(this, BinasciiError, ErrorMessages.ODD_LENGTH_STRING); } byte[] output = new byte[length / 2]; for (int i = 0; i < length / 2; i++) { @@ -309,7 +309,7 @@ private int digitValue(char b) { } else if (b >= 'A' && b <= 'F') { return b - 'A' + 10; } else { - throw PRaiseNode.raiseUncached(this, BinasciiError, ErrorMessages.NON_HEX_DIGIT_FOUND); + throw PRaiseNode.raiseStatic(this, BinasciiError, ErrorMessages.NON_HEX_DIGIT_FOUND); } } @@ -325,28 +325,28 @@ protected ArgumentClinicProvider getArgumentClinic() { @GenerateNodeFactory abstract static class B2aBase64Node extends PythonClinicBuiltinNode { @TruffleBoundary - private PBytes b2a(byte[] data, int lenght, int newline, PythonObjectFactory factory) { + private PBytes b2a(byte[] data, int lenght, int newline, PythonLanguage language) { ByteBuffer encoded; try { encoded = Base64.getEncoder().encode(ByteBuffer.wrap(data, 0, lenght)); } catch (IllegalArgumentException e) { - throw PRaiseNode.raiseUncached(this, BinasciiError, e); + throw PRaiseNode.raiseStatic(this, BinasciiError, e); } if (newline != 0) { byte[] encodedWithNL = Arrays.copyOf(encoded.array(), encoded.limit() + 1); encodedWithNL[encodedWithNL.length - 1] = '\n'; - return factory.createBytes(encodedWithNL); + return PFactory.createBytes(language, encodedWithNL); } - return factory.createBytes(encoded.array(), encoded.limit()); + return PFactory.createBytes(language, encoded.array(), encoded.limit()); } @Specialization(limit = "3") PBytes b2aBuffer(VirtualFrame frame, Object buffer, int newline, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { try { - return b2a(bufferLib.getInternalOrCopiedByteArray(buffer), bufferLib.getBufferLength(buffer), newline, factory); + return b2a(bufferLib.getInternalOrCopiedByteArray(buffer), bufferLib.getBufferLength(buffer), newline, language); } finally { bufferLib.release(buffer, frame, indirectCallData); } @@ -371,28 +371,28 @@ static PBytes b2a(VirtualFrame frame, Object buffer, Object sep, int bytesPerSep @Bind("this") Node inliningTarget, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { if (sep != PNone.NO_VALUE || bytesPerSep != 1) { // TODO implement sep and bytes_per_sep - throw raiseNode.get(inliningTarget).raise(NotImplementedError); + throw raiseNode.raise(inliningTarget, NotImplementedError); } try { - return b2a(bufferLib.getInternalOrCopiedByteArray(buffer), bufferLib.getBufferLength(buffer), factory); + return b2a(bufferLib.getInternalOrCopiedByteArray(buffer), bufferLib.getBufferLength(buffer), language); } finally { bufferLib.release(buffer, frame, indirectCallData); } } @TruffleBoundary - private static PBytes b2a(byte[] bytes, int length, PythonObjectFactory factory) { + private static PBytes b2a(byte[] bytes, int length, PythonLanguage language) { byte[] output = new byte[length * 2]; for (int i = 0; i < length; i++) { int v = bytes[i] & 0xff; output[i * 2] = HEX_DIGITS[v >> 4]; output[i * 2 + 1] = HEX_DIGITS[v & 0xf]; } - return factory.createBytes(output); + return PFactory.createBytes(language, output); } @Override diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java deleted file mode 100644 index 90d03d8aae..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java +++ /dev/null @@ -1,2992 +0,0 @@ -/* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. - * Copyright (c) 2013, Regents of the University of California - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.oracle.graal.python.builtins.modules; - -import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_BYTES_SUBTYPE_NEW; -import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_OBJECT_NEW; -import static com.oracle.graal.python.nodes.BuiltinNames.J_BOOL; -import static com.oracle.graal.python.nodes.BuiltinNames.J_BYTEARRAY; -import static com.oracle.graal.python.nodes.BuiltinNames.J_BYTES; -import static com.oracle.graal.python.nodes.BuiltinNames.J_CLASSMETHOD; -import static com.oracle.graal.python.nodes.BuiltinNames.J_COMPLEX; -import static com.oracle.graal.python.nodes.BuiltinNames.J_DICT; -import static com.oracle.graal.python.nodes.BuiltinNames.J_DICT_ITEMITERATOR; -import static com.oracle.graal.python.nodes.BuiltinNames.J_DICT_ITEMS; -import static com.oracle.graal.python.nodes.BuiltinNames.J_DICT_KEYITERATOR; -import static com.oracle.graal.python.nodes.BuiltinNames.J_DICT_KEYS; -import static com.oracle.graal.python.nodes.BuiltinNames.J_DICT_VALUEITERATOR; -import static com.oracle.graal.python.nodes.BuiltinNames.J_DICT_VALUES; -import static com.oracle.graal.python.nodes.BuiltinNames.J_ENUMERATE; -import static com.oracle.graal.python.nodes.BuiltinNames.J_FLOAT; -import static com.oracle.graal.python.nodes.BuiltinNames.J_FROZENSET; -import static com.oracle.graal.python.nodes.BuiltinNames.J_GETSET_DESCRIPTOR; -import static com.oracle.graal.python.nodes.BuiltinNames.J_INSTANCEMETHOD; -import static com.oracle.graal.python.nodes.BuiltinNames.J_INT; -import static com.oracle.graal.python.nodes.BuiltinNames.J_LIST; -import static com.oracle.graal.python.nodes.BuiltinNames.J_MAP; -import static com.oracle.graal.python.nodes.BuiltinNames.J_MEMBER_DESCRIPTOR; -import static com.oracle.graal.python.nodes.BuiltinNames.J_MEMORYVIEW; -import static com.oracle.graal.python.nodes.BuiltinNames.J_MODULE; -import static com.oracle.graal.python.nodes.BuiltinNames.J_OBJECT; -import static com.oracle.graal.python.nodes.BuiltinNames.J_PROPERTY; -import static com.oracle.graal.python.nodes.BuiltinNames.J_RANGE; -import static com.oracle.graal.python.nodes.BuiltinNames.J_REVERSED; -import static com.oracle.graal.python.nodes.BuiltinNames.J_SET; -import static com.oracle.graal.python.nodes.BuiltinNames.J_STATICMETHOD; -import static com.oracle.graal.python.nodes.BuiltinNames.J_STR; -import static com.oracle.graal.python.nodes.BuiltinNames.J_SUPER; -import static com.oracle.graal.python.nodes.BuiltinNames.J_TUPLE; -import static com.oracle.graal.python.nodes.BuiltinNames.J_TYPE; -import static com.oracle.graal.python.nodes.BuiltinNames.J_WRAPPER_DESCRIPTOR; -import static com.oracle.graal.python.nodes.BuiltinNames.J_ZIP; -import static com.oracle.graal.python.nodes.BuiltinNames.T_EXCEPTION_GROUP; -import static com.oracle.graal.python.nodes.BuiltinNames.T_GETSET_DESCRIPTOR; -import static com.oracle.graal.python.nodes.BuiltinNames.T_LAMBDA_NAME; -import static com.oracle.graal.python.nodes.BuiltinNames.T_MEMBER_DESCRIPTOR; -import static com.oracle.graal.python.nodes.BuiltinNames.T_NOT_IMPLEMENTED; -import static com.oracle.graal.python.nodes.BuiltinNames.T_WRAPPER_DESCRIPTOR; -import static com.oracle.graal.python.nodes.BuiltinNames.T_ZIP; -import static com.oracle.graal.python.nodes.ErrorMessages.ARG_MUST_NOT_BE_ZERO; -import static com.oracle.graal.python.nodes.PGuards.isInteger; -import static com.oracle.graal.python.nodes.PGuards.isNoValue; -import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___ABSTRACTMETHODS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T_JOIN; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T_SORT; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___BYTES__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___COMPLEX__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MRO_ENTRIES__; -import static com.oracle.graal.python.nodes.StringLiterals.T_COMMA_SPACE; -import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; -import static com.oracle.graal.python.nodes.StringLiterals.T_STRICT; -import static com.oracle.graal.python.nodes.StringLiterals.T_UTF8; -import static com.oracle.graal.python.nodes.truffle.TruffleStringMigrationHelpers.assertNoJavaString; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.NotImplementedError; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.OverflowError; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.RuntimeError; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; -import static com.oracle.graal.python.util.PythonUtils.addExact; -import static com.oracle.graal.python.util.PythonUtils.multiplyExact; -import static com.oracle.graal.python.util.PythonUtils.negateExact; -import static com.oracle.graal.python.util.PythonUtils.objectArrayToTruffleStringArray; -import static com.oracle.graal.python.util.PythonUtils.subtractExact; - -import java.math.BigInteger; -import java.util.List; - -import com.oracle.graal.python.annotations.ArgumentClinic; -import com.oracle.graal.python.builtins.Builtin; -import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.Python3Core; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.modules.BuiltinConstructorsFactory.FloatNodeFactory.NonPrimitiveFloatNodeGen; -import com.oracle.graal.python.builtins.modules.BuiltinConstructorsFactory.ObjectNodeFactory.ReportAbstractClassNodeGen; -import com.oracle.graal.python.builtins.modules.WarningsModuleBuiltins.WarnNode; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; -import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; -import com.oracle.graal.python.builtins.objects.bytes.PByteArray; -import com.oracle.graal.python.builtins.objects.bytes.PBytes; -import com.oracle.graal.python.builtins.objects.cell.PCell; -import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; -import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; -import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PCallCapiFunction; -import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes; -import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol; -import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonTransferNode; -import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode; -import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CByteArrayWrapper; -import com.oracle.graal.python.builtins.objects.code.CodeNodes; -import com.oracle.graal.python.builtins.objects.code.PCode; -import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes; -import com.oracle.graal.python.builtins.objects.common.HashingStorage; -import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetObjectArrayNode; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; -import com.oracle.graal.python.builtins.objects.complex.PComplex; -import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis; -import com.oracle.graal.python.builtins.objects.enumerate.PEnumerate; -import com.oracle.graal.python.builtins.objects.floats.FloatUtils; -import com.oracle.graal.python.builtins.objects.floats.PFloat; -import com.oracle.graal.python.builtins.objects.frame.PFrame; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.function.PFunction; -import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.builtins.objects.ints.PInt; -import com.oracle.graal.python.builtins.objects.iterator.PBigRangeIterator; -import com.oracle.graal.python.builtins.objects.iterator.PZip; -import com.oracle.graal.python.builtins.objects.list.PList; -import com.oracle.graal.python.builtins.objects.map.PMap; -import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; -import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; -import com.oracle.graal.python.builtins.objects.namespace.PSimpleNamespace; -import com.oracle.graal.python.builtins.objects.object.ObjectBuiltinsFactory; -import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.builtins.objects.property.PProperty; -import com.oracle.graal.python.builtins.objects.range.PBigRange; -import com.oracle.graal.python.builtins.objects.range.PIntRange; -import com.oracle.graal.python.builtins.objects.range.RangeNodes; -import com.oracle.graal.python.builtins.objects.range.RangeNodes.LenOfIntRangeNodeExact; -import com.oracle.graal.python.builtins.objects.set.PFrozenSet; -import com.oracle.graal.python.builtins.objects.set.PSet; -import com.oracle.graal.python.builtins.objects.str.PString; -import com.oracle.graal.python.builtins.objects.traceback.PTraceback; -import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; -import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.builtins.objects.type.TypeBuiltins; -import com.oracle.graal.python.builtins.objects.type.TypeFlags; -import com.oracle.graal.python.builtins.objects.type.TypeNodes; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.CreateTypeNode; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsAcceptableBaseNode; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.NeedsNativeAllocationNode; -import com.oracle.graal.python.builtins.objects.types.PGenericAlias; -import com.oracle.graal.python.lib.CanBeDoubleNode; -import com.oracle.graal.python.lib.PyBytesCheckNode; -import com.oracle.graal.python.lib.PyCallableCheckNode; -import com.oracle.graal.python.lib.PyComplexCheckExactNode; -import com.oracle.graal.python.lib.PyFloatAsDoubleNode; -import com.oracle.graal.python.lib.PyFloatFromString; -import com.oracle.graal.python.lib.PyLongFromUnicodeObject; -import com.oracle.graal.python.lib.PyMappingCheckNode; -import com.oracle.graal.python.lib.PyMemoryViewFromObject; -import com.oracle.graal.python.lib.PyNumberAsSizeNode; -import com.oracle.graal.python.lib.PyNumberFloatNode; -import com.oracle.graal.python.lib.PyNumberIndexNode; -import com.oracle.graal.python.lib.PyNumberLongNode; -import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; -import com.oracle.graal.python.lib.PyObjectGetAttr; -import com.oracle.graal.python.lib.PyObjectGetIter; -import com.oracle.graal.python.lib.PyObjectIsTrueNode; -import com.oracle.graal.python.lib.PyObjectLookupAttr; -import com.oracle.graal.python.lib.PyObjectSizeNode; -import com.oracle.graal.python.lib.PyObjectStrAsObjectNode; -import com.oracle.graal.python.lib.PySequenceCheckNode; -import com.oracle.graal.python.lib.PySequenceSizeNode; -import com.oracle.graal.python.lib.PySliceNew; -import com.oracle.graal.python.lib.PyUnicodeCheckExactNode; -import com.oracle.graal.python.lib.PyUnicodeCheckNode; -import com.oracle.graal.python.nodes.BuiltinNames; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; -import com.oracle.graal.python.nodes.builtins.ListNodes; -import com.oracle.graal.python.nodes.builtins.TupleNodes; -import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallTernaryNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; -import com.oracle.graal.python.nodes.classes.IsSubtypeNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsAnyBuiltinClassProfile; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassExactProfile; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.util.CannotCastException; -import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; -import com.oracle.graal.python.nodes.util.CastToJavaStringNode; -import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.nodes.util.SplitArgsNode; -import com.oracle.graal.python.runtime.IndirectCallData; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory; -import com.oracle.graal.python.util.OverflowException; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.Assumption; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.GenerateNodeFactory; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.ReportPolymorphism; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.nodes.LoopNode; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedBranchProfile; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; -import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile; -import com.oracle.truffle.api.strings.TruffleString; - -@CoreFunctions(defineModule = BuiltinNames.J_BUILTINS, isEager = true) -public final class BuiltinConstructors extends PythonBuiltins { - - @Override - protected List> getNodeFactories() { - return BuiltinConstructorsFactory.getFactories(); - } - - @Override - public void initialize(Python3Core core) { - super.initialize(core); - addBuiltinConstant(T_NOT_IMPLEMENTED, PNotImplemented.NOT_IMPLEMENTED); - } - - // bytes([source[, encoding[, errors]]]) - @Builtin(name = J_BYTES, minNumOfPositionalArgs = 1, parameterNames = {"$self", "source", "encoding", "errors"}, constructsClass = PythonBuiltinClassType.PBytes, doc = """ - bytes(iterable_of_ints) -> bytes - bytes(string, encoding[, errors]) -> bytes - bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer - bytes(int) -> bytes object of size given by the parameter initialized with null bytes - bytes() -> empty bytes object - - Construct an immutable array of bytes from: - - an iterable yielding integers in range(256) - - a text string encoded using the specified encoding - - any object implementing the buffer API. - - an integer""") - @ArgumentClinic(name = "encoding", conversionClass = BytesNodes.ExpectStringNode.class, args = "\"bytes()\"") - @ArgumentClinic(name = "errors", conversionClass = BytesNodes.ExpectStringNode.class, args = "\"bytes()\"") - @GenerateNodeFactory - @ImportStatic(SpecialMethodSlot.class) - public abstract static class BytesNode extends PythonQuaternaryClinicBuiltinNode { - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return BuiltinConstructorsClinicProviders.BytesNodeClinicProviderGen.INSTANCE; - } - - @SuppressWarnings("unused") - @Specialization(guards = "isNoValue(source)") - static Object doEmpty(Object cls, PNone source, PNone encoding, PNone errors, - @Bind("this") Node inliningTarget, - @Exclusive @Cached CreateBytes createBytes) { - return createBytes.execute(inliningTarget, cls, PythonUtils.EMPTY_BYTE_ARRAY); - } - - @Specialization(guards = "!isNoValue(source)") - static Object doCallBytes(VirtualFrame frame, Object cls, Object source, PNone encoding, PNone errors, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached InlinedConditionProfile hasBytes, - @Cached("create(Bytes)") LookupSpecialMethodSlotNode lookupBytes, - @Cached CallUnaryMethodNode callBytes, - @Cached BytesNodes.ToBytesNode toBytesNode, - @Cached PyBytesCheckNode check, - @Exclusive @Cached BytesNodes.BytesInitNode bytesInitNode, - @Exclusive @Cached CreateBytes createBytes, - @Cached PRaiseNode.Lazy raiseNode) { - Object bytesMethod = lookupBytes.execute(frame, getClassNode.execute(inliningTarget, source), source); - if (hasBytes.profile(inliningTarget, bytesMethod != PNone.NO_VALUE)) { - Object bytes = callBytes.executeObject(frame, bytesMethod, source); - if (check.execute(inliningTarget, bytes)) { - if (cls == PythonBuiltinClassType.PBytes) { - return bytes; - } else { - return createBytes.execute(inliningTarget, cls, toBytesNode.execute(frame, bytes)); - } - } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.RETURNED_NONBYTES, T___BYTES__, bytes); - } - } - return createBytes.execute(inliningTarget, cls, bytesInitNode.execute(frame, inliningTarget, source, encoding, errors)); - } - - @Specialization(guards = {"isNoValue(source) || (!isNoValue(encoding) || !isNoValue(errors))"}) - static Object dontCallBytes(VirtualFrame frame, Object cls, Object source, Object encoding, Object errors, - @Bind("this") Node inliningTarget, - @Exclusive @Cached BytesNodes.BytesInitNode bytesInitNode, - @Exclusive @Cached CreateBytes createBytes) { - return createBytes.execute(inliningTarget, cls, bytesInitNode.execute(frame, inliningTarget, source, encoding, errors)); - } - - @GenerateInline - @GenerateCached(false) - abstract static class CreateBytes extends PNodeWithContext { - abstract Object execute(Node inliningTarget, Object cls, byte[] bytes); - - @Specialization(guards = "!needsNativeAllocationNode.execute(inliningTarget, cls)") - static PBytes doManaged(@SuppressWarnings("unused") Node inliningTarget, Object cls, byte[] bytes, - @SuppressWarnings("unused") @Shared @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, - @Cached(inline = false) PythonObjectFactory factory) { - return factory.createBytes(cls, bytes); - } - - @Specialization(guards = "needsNativeAllocationNode.execute(inliningTarget, cls)") - static Object doNative(@SuppressWarnings("unused") Node inliningTarget, Object cls, byte[] bytes, - @SuppressWarnings("unused") @Shared @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, - @Cached(inline = false) PythonToNativeNode toNative, - @Cached(inline = false) NativeToPythonTransferNode toPython, - @Cached(inline = false) PCallCapiFunction call) { - CByteArrayWrapper wrapper = new CByteArrayWrapper(bytes); - try { - return toPython.execute(call.call(FUN_BYTES_SUBTYPE_NEW, toNative.execute(cls), wrapper, bytes.length)); - } finally { - wrapper.free(); - } - } - } - } - - @Builtin(name = J_BYTEARRAY, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PByteArray, doc = """ - bytearray(iterable_of_ints) -> bytearray - bytearray(string, encoding[, errors]) -> bytearray - bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer - bytearray(int) -> bytes array of size given by the parameter initialized with null bytes - bytearray() -> empty bytes array - - Construct a mutable bytearray object from: - - an iterable yielding integers in range(256) - - a text string encoded using the specified encoding - - a bytes or a buffer object - - any object implementing the buffer API. - - an integer""") - @GenerateNodeFactory - public abstract static class ByteArrayNode extends PythonBuiltinNode { - @Specialization - public PByteArray setEmpty(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PythonObjectFactory factory) { - // data filled in subsequent __init__ call - see BytesCommonBuiltins.InitNode - return factory.createByteArray(cls, PythonUtils.EMPTY_BYTE_ARRAY); - } - - // TODO: native allocation? - } - - // complex([real[, imag]]) - @Builtin(name = J_COMPLEX, minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.PComplex, parameterNames = {"$cls", "real", "imag"}, doc = """ - Create a complex number from a real part and an optional imaginary part. - - This is equivalent to (real + imag*1j) where imag defaults to 0.""") - @GenerateNodeFactory - public abstract static class ComplexNode extends PythonTernaryBuiltinNode { - @Child private LookupAndCallUnaryNode callReprNode; - @Child private LookupAndCallUnaryNode callComplexNode; - @Child private WarnNode warnNode; - - @GenerateInline - @GenerateCached(false) - @GenerateUncached - abstract static class CreateComplexNode extends Node { - public abstract Object execute(Node inliningTarget, Object cls, double real, double imaginary); - - public static Object executeUncached(Object cls, double real, double imaginary) { - return BuiltinConstructorsFactory.ComplexNodeFactory.CreateComplexNodeGen.getUncached().execute(null, cls, real, imaginary); - } - - @Specialization(guards = "!needsNativeAllocationNode.execute(inliningTarget, cls)", limit = "1") - static PComplex doManaged(@SuppressWarnings("unused") Node inliningTarget, Object cls, double real, double imaginary, - @SuppressWarnings("unused") @Cached NeedsNativeAllocationNode needsNativeAllocationNode, - @Cached(inline = false) PythonObjectFactory factory) { - return factory.createComplex(cls, real, imaginary); - } - - @Fallback - static Object doNative(Node inliningTarget, Object cls, double real, double imaginary, - @Cached(inline = false) PCallCapiFunction callCapiFunction, - @Cached(inline = false) PythonToNativeNode toNativeNode, - @Cached(inline = false) NativeToPythonTransferNode toPythonNode, - @Cached(inline = false) ExternalFunctionNodes.DefaultCheckFunctionResultNode checkFunctionResultNode) { - NativeCAPISymbol symbol = NativeCAPISymbol.FUN_COMPLEX_SUBTYPE_FROM_DOUBLES; - Object nativeResult = callCapiFunction.call(symbol, toNativeNode.execute(cls), real, imaginary); - return toPythonNode.execute(checkFunctionResultNode.execute(PythonContext.get(inliningTarget), symbol.getTsName(), nativeResult)); - } - } - - @Specialization(guards = {"isNoValue(real)", "isNoValue(imag)"}) - @SuppressWarnings("unused") - static Object complexFromNone(Object cls, PNone real, PNone imag, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode) { - return createComplexNode.execute(inliningTarget, cls, 0, 0); - } - - @Specialization - static Object complexFromIntInt(Object cls, int real, int imaginary, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode) { - return createComplexNode.execute(inliningTarget, cls, real, imaginary); - } - - @Specialization - static Object complexFromLongLong(Object cls, long real, long imaginary, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode) { - return createComplexNode.execute(inliningTarget, cls, real, imaginary); - } - - @Specialization - static Object complexFromLongLong(Object cls, PInt real, PInt imaginary, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode) { - return createComplexNode.execute(inliningTarget, cls, real.doubleValueWithOverflow(inliningTarget), - imaginary.doubleValueWithOverflow(inliningTarget)); - } - - @Specialization - static Object complexFromDoubleDouble(Object cls, double real, double imaginary, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode) { - return createComplexNode.execute(inliningTarget, cls, real, imaginary); - } - - @Specialization(guards = "isNoValue(imag)") - static Object complexFromDouble(Object cls, double real, @SuppressWarnings("unused") PNone imag, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode) { - return createComplexNode.execute(inliningTarget, cls, real, 0); - } - - @Specialization(guards = "isNoValue(imag)") - Object complexFromDouble(VirtualFrame frame, Object cls, PFloat real, @SuppressWarnings("unused") PNone imag, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode, - @Shared @Cached CanBeDoubleNode canBeDoubleNode, - @Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, - @Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, - @Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, - @Shared("isPrimitive") @Cached IsBuiltinClassExactProfile isPrimitiveProfile, - @Shared("isBuiltinObj") @Cached PyComplexCheckExactNode isBuiltinObjectProfile, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - return complexFromObject(frame, cls, real, imag, inliningTarget, createComplexNode, canBeDoubleNode, asDoubleNode, isComplexType, isResultComplexType, isPrimitiveProfile, - isBuiltinObjectProfile, factory, - raiseNode); - } - - @Specialization(guards = "isNoValue(imag)") - static Object complexFromInt(Object cls, int real, @SuppressWarnings("unused") PNone imag, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode) { - return createComplexNode.execute(inliningTarget, cls, real, 0); - } - - @Specialization(guards = "isNoValue(imag)") - static Object complexFromLong(Object cls, long real, @SuppressWarnings("unused") PNone imag, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode) { - return createComplexNode.execute(inliningTarget, cls, real, 0); - } - - @Specialization(guards = "isNoValue(imag)") - Object complexFromLong(VirtualFrame frame, Object cls, PInt real, @SuppressWarnings("unused") PNone imag, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode, - @Shared @Cached CanBeDoubleNode canBeDoubleNode, - @Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, - @Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, - @Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, - @Shared("isPrimitive") @Cached IsBuiltinClassExactProfile isPrimitiveProfile, - @Shared("isBuiltinObj") @Cached PyComplexCheckExactNode complexCheck, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - return complexFromObject(frame, cls, real, imag, inliningTarget, createComplexNode, canBeDoubleNode, asDoubleNode, isComplexType, isResultComplexType, isPrimitiveProfile, complexCheck, - factory, raiseNode); - } - - @Specialization(guards = {"isNoValue(imag)", "!isNoValue(number)", "!isString(number)"}) - Object complexFromObject(VirtualFrame frame, Object cls, Object number, @SuppressWarnings("unused") PNone imag, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode, - @Shared @Cached CanBeDoubleNode canBeDoubleNode, - @Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, - @Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, - @Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, - @Shared("isPrimitive") @Cached IsBuiltinClassExactProfile isPrimitiveProfile, - @Shared("isBuiltinObj") @Cached PyComplexCheckExactNode complexCheck, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - PComplex value = getComplexNumberFromObject(frame, number, inliningTarget, isComplexType, isResultComplexType, raiseNode); - if (value == null) { - if (canBeDoubleNode.execute(inliningTarget, number)) { - return createComplexNode.execute(inliningTarget, cls, asDoubleNode.execute(frame, inliningTarget, number), 0.0); - } else { - throw raiseFirstArgError(number, raiseNode.get(inliningTarget)); - } - } - if (isPrimitiveProfile.profileClass(inliningTarget, cls, PythonBuiltinClassType.PComplex)) { - if (complexCheck.execute(inliningTarget, value)) { - return value; - } - return factory.createComplex(value.getReal(), value.getImag()); - } - return createComplexNode.execute(inliningTarget, cls, value.getReal(), value.getImag()); - } - - @Specialization - static Object complexFromLongComplex(Object cls, long one, PComplex two, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode) { - return createComplexNode.execute(inliningTarget, cls, one - two.getImag(), two.getReal()); - } - - @Specialization - static Object complexFromPIntComplex(Object cls, PInt one, PComplex two, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode) { - return createComplexNode.execute(inliningTarget, cls, one.doubleValueWithOverflow(inliningTarget) - two.getImag(), two.getReal()); - } - - @Specialization - static Object complexFromDoubleComplex(Object cls, double one, PComplex two, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode) { - return createComplexNode.execute(inliningTarget, cls, one - two.getImag(), two.getReal()); - } - - @Specialization(guards = "!isString(one)") - Object complexFromComplexLong(VirtualFrame frame, Object cls, Object one, long two, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode, - @Shared @Cached CanBeDoubleNode canBeDoubleNode, - @Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, - @Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, - @Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - PComplex value = getComplexNumberFromObject(frame, one, inliningTarget, isComplexType, isResultComplexType, raiseNode); - if (value == null) { - if (canBeDoubleNode.execute(inliningTarget, one)) { - return createComplexNode.execute(inliningTarget, cls, asDoubleNode.execute(frame, inliningTarget, one), two); - } else { - throw raiseFirstArgError(one, raiseNode.get(inliningTarget)); - } - } - return createComplexNode.execute(inliningTarget, cls, value.getReal(), value.getImag() + two); - } - - @Specialization(guards = "!isString(one)") - Object complexFromComplexDouble(VirtualFrame frame, Object cls, Object one, double two, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode, - @Shared @Cached CanBeDoubleNode canBeDoubleNode, - @Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, - @Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, - @Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - PComplex value = getComplexNumberFromObject(frame, one, inliningTarget, isComplexType, isResultComplexType, raiseNode); - if (value == null) { - if (canBeDoubleNode.execute(inliningTarget, one)) { - return createComplexNode.execute(inliningTarget, cls, asDoubleNode.execute(frame, inliningTarget, one), two); - } else { - throw raiseFirstArgError(one, raiseNode.get(inliningTarget)); - } - } - return createComplexNode.execute(inliningTarget, cls, value.getReal(), value.getImag() + two); - } - - @Specialization(guards = "!isString(one)") - Object complexFromComplexPInt(VirtualFrame frame, Object cls, Object one, PInt two, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode, - @Shared @Cached CanBeDoubleNode canBeDoubleNode, - @Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, - @Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, - @Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - PComplex value = getComplexNumberFromObject(frame, one, inliningTarget, isComplexType, isResultComplexType, raiseNode); - if (value == null) { - if (canBeDoubleNode.execute(inliningTarget, one)) { - return createComplexNode.execute(inliningTarget, cls, asDoubleNode.execute(frame, inliningTarget, one), two.doubleValueWithOverflow(this)); - } else { - throw raiseFirstArgError(one, raiseNode.get(inliningTarget)); - } - } - return createComplexNode.execute(inliningTarget, cls, value.getReal(), value.getImag() + two.doubleValueWithOverflow(this)); - } - - @Specialization(guards = "!isString(one)") - Object complexFromComplexComplex(VirtualFrame frame, Object cls, Object one, PComplex two, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode, - @Shared @Cached CanBeDoubleNode canBeDoubleNode, - @Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, - @Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, - @Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - PComplex value = getComplexNumberFromObject(frame, one, inliningTarget, isComplexType, isResultComplexType, raiseNode); - if (value == null) { - if (canBeDoubleNode.execute(inliningTarget, one)) { - return createComplexNode.execute(inliningTarget, cls, asDoubleNode.execute(frame, inliningTarget, one) - two.getImag(), two.getReal()); - } else { - throw raiseFirstArgError(one, raiseNode.get(inliningTarget)); - } - } - return createComplexNode.execute(inliningTarget, cls, value.getReal() - two.getImag(), value.getImag() + two.getReal()); - } - - @Specialization(guards = {"!isString(one)", "!isNoValue(two)", "!isPComplex(two)"}) - @SuppressWarnings("truffle-static-method") - Object complexFromComplexObject(VirtualFrame frame, Object cls, Object one, Object two, - @Bind("this") Node inliningTarget, - @Shared @Cached CreateComplexNode createComplexNode, - @Shared @Cached CanBeDoubleNode canBeDoubleNode, - @Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, - @Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, - @Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - PComplex oneValue = getComplexNumberFromObject(frame, one, inliningTarget, isComplexType, isResultComplexType, raiseNode); - if (canBeDoubleNode.execute(inliningTarget, two)) { - double twoValue = asDoubleNode.execute(frame, inliningTarget, two); - if (oneValue == null) { - if (canBeDoubleNode.execute(inliningTarget, one)) { - return createComplexNode.execute(inliningTarget, cls, asDoubleNode.execute(frame, inliningTarget, one), twoValue); - } else { - throw raiseFirstArgError(one, raiseNode.get(inliningTarget)); - } - } - return createComplexNode.execute(inliningTarget, cls, oneValue.getReal(), oneValue.getImag() + twoValue); - } else { - throw raiseSecondArgError(two, raiseNode.get(inliningTarget)); - } - } - - @Specialization - Object complexFromString(VirtualFrame frame, Object cls, TruffleString real, Object imaginary, - @Bind("this") Node inliningTarget, - @Cached TruffleString.ToJavaStringNode toJavaStringNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - if (imaginary != PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.COMPLEX_CANT_TAKE_ARG); - } - return convertStringToComplex(frame, inliningTarget, toJavaStringNode.execute(real), cls, real, raiseNode); - } - - @Specialization - Object complexFromString(VirtualFrame frame, Object cls, PString real, Object imaginary, - @Bind("this") Node inliningTarget, - @Cached CastToJavaStringNode castToStringNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - if (imaginary != PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.COMPLEX_CANT_TAKE_ARG); - } - return convertStringToComplex(frame, inliningTarget, castToStringNode.execute(real), cls, real, raiseNode); - } - - private Object callComplex(VirtualFrame frame, Object object) { - if (callComplexNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - callComplexNode = insert(LookupAndCallUnaryNode.create(T___COMPLEX__)); - } - return callComplexNode.executeObject(frame, object); - } - - private WarnNode getWarnNode() { - if (warnNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - warnNode = insert(WarnNode.create()); - } - return warnNode; - } - - private static PException raiseFirstArgError(Object x, PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.ARG_MUST_BE_STRING_OR_NUMBER, "complex() first", x); - } - - private static PException raiseSecondArgError(Object x, PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.ARG_MUST_BE_NUMBER, "complex() second", x); - } - - private PComplex getComplexNumberFromObject(VirtualFrame frame, Object object, Node inliningTarget, - PyComplexCheckExactNode isComplexType, PyComplexCheckExactNode isResultComplexType, PRaiseNode.Lazy raiseNode) { - if (isComplexType.execute(inliningTarget, object)) { - return (PComplex) object; - } else { - Object result = callComplex(frame, object); - if (result instanceof PComplex) { - if (!isResultComplexType.execute(inliningTarget, result)) { - getWarnNode().warnFormat(frame, null, PythonBuiltinClassType.DeprecationWarning, 1, - ErrorMessages.WARN_P_RETURNED_NON_P, - object, "__complex__", "complex", result, "complex"); - } - return (PComplex) result; - } else if (result != PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.COMPLEX_RETURNED_NON_COMPLEX, result); - } - if (object instanceof PComplex) { - // the class extending PComplex but doesn't have __complex__ method - return (PComplex) object; - } - return null; - } - } - - @Fallback - @SuppressWarnings("unused") - static Object complexGeneric(Object cls, Object realObj, Object imaginaryObj, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "complex.__new__(X): X", cls); - } - - // Adapted from CPython's complex_subtype_from_string - private Object convertStringToComplex(VirtualFrame frame, Node inliningTarget, String src, Object cls, Object origObj, PRaiseNode.Lazy raiseNode) { - String str = FloatUtils.removeUnicodeAndUnderscores(src); - if (str == null) { - if (callReprNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - callReprNode = insert(LookupAndCallUnaryNode.create(SpecialMethodSlot.Repr)); - } - Object strStr = callReprNode.executeObject(frame, origObj); - if (PGuards.isString(strStr)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.COULD_NOT_CONVERT_STRING_TO_COMPLEX, strStr); - } else { - // During the formatting of "ValueError: invalid literal ..." exception, - // CPython attempts to raise "TypeError: __repr__ returned non-string", - // which gets later overwitten with the original "ValueError", - // but without any message (since the message formatting failed) - throw raiseNode.get(inliningTarget).raise(ValueError); - } - } - Object c = convertStringToComplexOrNull(str, cls); - if (c == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.COMPLEX_ARG_IS_MALFORMED_STR); - } - return c; - } - - // Adapted from CPython's complex_from_string_inner - @TruffleBoundary - private Object convertStringToComplexOrNull(String str, Object cls) { - int len = str.length(); - - // position on first nonblank - int i = FloatUtils.skipAsciiWhitespace(str, 0, len); - - boolean gotBracket; - if (i < len && str.charAt(i) == '(') { - // Skip over possible bracket from repr(). - gotBracket = true; - i = FloatUtils.skipAsciiWhitespace(str, i + 1, len); - } else { - gotBracket = false; - } - - double x, y; - boolean expectJ; - - // first look for forms starting with - FloatUtils.StringToDoubleResult res1 = FloatUtils.stringToDouble(str, i, len); - if (res1 != null) { - // all 4 forms starting with land here - i = res1.position; - char ch = i < len ? str.charAt(i) : '\0'; - if (ch == '+' || ch == '-') { - // j | j - x = res1.value; - FloatUtils.StringToDoubleResult res2 = FloatUtils.stringToDouble(str, i, len); - if (res2 != null) { - // j - y = res2.value; - i = res2.position; - } else { - // j - y = ch == '+' ? 1.0 : -1.0; - i++; - } - expectJ = true; - } else if (ch == 'j' || ch == 'J') { - // j - i++; - y = res1.value; - x = 0; - expectJ = false; - } else { - // - x = res1.value; - y = 0; - expectJ = false; - } - } else { - // not starting with ; must be j or j - char ch = i < len ? str.charAt(i) : '\0'; - if (ch == '+' || ch == '-') { - // j - y = ch == '+' ? 1.0 : -1.0; - i++; - } else { - // j - y = 1.0; - } - x = 0; - expectJ = true; - } - - if (expectJ) { - char ch = i < len ? str.charAt(i) : '\0'; - if (!(ch == 'j' || ch == 'J')) { - return null; - } - i++; - } - - // trailing whitespace and closing bracket - i = FloatUtils.skipAsciiWhitespace(str, i, len); - if (gotBracket) { - // if there was an opening parenthesis, then the corresponding - // closing parenthesis should be right here - if (i >= len || str.charAt(i) != ')') { - return null; - } - i = FloatUtils.skipAsciiWhitespace(str, i + 1, len); - } - - // we should now be at the end of the string - if (i != len) { - return null; - } - return CreateComplexNode.executeUncached(cls, x, y); - } - } - - // dict(**kwarg) - // dict(mapping, **kwarg) - // dict(iterable, **kwarg) - @Builtin(name = J_DICT, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDict, doc = """ - dict() -> new empty dictionary - dict(mapping) -> new dictionary initialized from a mapping object's - (key, value) pairs - dict(iterable) -> new dictionary initialized as if via: - d = {} - for k, v in iterable: - d[k] = v - dict(**kwargs) -> new dictionary initialized with the name=value pairs - in the keyword argument list. For example: dict(one=1, two=2)""") - @GenerateNodeFactory - public abstract static class DictionaryNode extends PythonBuiltinNode { - @Specialization(guards = "isBuiltinDict(cls)") - @SuppressWarnings("unused") - static PDict builtinDict(Object cls, Object[] args, PKeyword[] keywordArgs, - @Shared @Cached PythonObjectFactory factory) { - return factory.createDict(); - } - - @Specialization(replaces = "builtinDict") - @SuppressWarnings("unused") - static PDict dict(Object cls, Object[] args, PKeyword[] keywordArgs, - @Bind("this") Node inliningTarget, - @Cached InlinedConditionProfile orderedProfile, - @Cached IsSubtypeNode isSubtypeNode, - @Shared @Cached PythonObjectFactory factory) { - if (orderedProfile.profile(inliningTarget, isSubtypeNode.execute(cls, PythonBuiltinClassType.POrderedDict))) { - return factory.createOrderedDict(cls); - } - return factory.createDict(cls); - } - - protected static boolean isBuiltinDict(Object cls) { - return cls == PythonBuiltinClassType.PDict; - } - } - - // enumerate(iterable, start=0) - @Builtin(name = J_ENUMERATE, minNumOfPositionalArgs = 2, parameterNames = {"cls", "iterable", "start"}, constructsClass = PythonBuiltinClassType.PEnumerate, doc = """ - Return an enumerate object. - - iterable - an object supporting iteration - - The enumerate object yields pairs containing a count (from start, which - defaults to zero) and a value yielded by the iterable argument. - - enumerate is useful for obtaining an indexed list: - (0, seq[0]), (1, seq[1]), (2, seq[2]), ...""") - @GenerateNodeFactory - public abstract static class EnumerateNode extends PythonBuiltinNode { - - @Specialization - static PEnumerate doNone(VirtualFrame frame, Object cls, Object iterable, @SuppressWarnings("unused") PNone keywordArg, - @Bind("this") Node inliningTarget, - @Shared("getIter") @Cached PyObjectGetIter getIter, - @Shared @Cached PythonObjectFactory factory) { - return factory.createEnumerate(cls, getIter.execute(frame, inliningTarget, iterable), 0); - } - - @Specialization - static PEnumerate doInt(VirtualFrame frame, Object cls, Object iterable, int start, - @Bind("this") Node inliningTarget, - @Shared("getIter") @Cached PyObjectGetIter getIter, - @Shared @Cached PythonObjectFactory factory) { - return factory.createEnumerate(cls, getIter.execute(frame, inliningTarget, iterable), start); - } - - @Specialization - static PEnumerate doLong(VirtualFrame frame, Object cls, Object iterable, long start, - @Bind("this") Node inliningTarget, - @Shared("getIter") @Cached PyObjectGetIter getIter, - @Shared @Cached PythonObjectFactory factory) { - return factory.createEnumerate(cls, getIter.execute(frame, inliningTarget, iterable), start); - } - - @Specialization - static PEnumerate doPInt(VirtualFrame frame, Object cls, Object iterable, PInt start, - @Bind("this") Node inliningTarget, - @Shared("getIter") @Cached PyObjectGetIter getIter, - @Shared @Cached PythonObjectFactory factory) { - return factory.createEnumerate(cls, getIter.execute(frame, inliningTarget, iterable), start); - } - - static boolean isIntegerIndex(Object idx) { - return isInteger(idx) || idx instanceof PInt; - } - - @Specialization(guards = "!isIntegerIndex(start)") - static void enumerate(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") Object iterable, Object start, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, start); - } - } - - // reversed(seq) - @Builtin(name = J_REVERSED, minNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PReverseIterator, doc = "Return a reverse iterator over the values of the given sequence.") - @GenerateNodeFactory - @ImportStatic(SpecialMethodSlot.class) - public abstract static class ReversedNode extends PythonBuiltinNode { - - @Specialization - static PythonObject reversed(@SuppressWarnings("unused") Object cls, PIntRange range, - @Bind("this") Node inliningTarget, - @Cached InlinedBranchProfile overflowProfile, - @Shared @Cached PythonObjectFactory factory) { - int lstart = range.getIntStart(); - int lstep = range.getIntStep(); - int ulen = range.getIntLength(); - try { - int new_stop = subtractExact(lstart, lstep); - int new_start = addExact(new_stop, multiplyExact(ulen, lstep)); - return factory.createIntRangeIterator(new_start, new_stop, negateExact(lstep), ulen); - } catch (OverflowException e) { - overflowProfile.enter(inliningTarget); - return handleOverflow(lstart, lstep, ulen, PythonContext.get(inliningTarget).factory()); - } - } - - @TruffleBoundary - private static PBigRangeIterator handleOverflow(int lstart, int lstep, int ulen, PythonObjectSlowPathFactory factory) { - BigInteger bstart = BigInteger.valueOf(lstart); - BigInteger bstep = BigInteger.valueOf(lstep); - BigInteger blen = BigInteger.valueOf(ulen); - BigInteger new_stop = bstart.subtract(bstep); - BigInteger new_start = new_stop.add(blen.multiply(bstep)); - - return factory.createBigRangeIterator(new_start, new_stop, bstep.negate(), blen); - } - - @Specialization - @TruffleBoundary - PythonObject reversed(@SuppressWarnings("unused") Object cls, PBigRange range) { - BigInteger lstart = range.getBigIntegerStart(); - BigInteger lstep = range.getBigIntegerStep(); - BigInteger ulen = range.getBigIntegerLength(); - - BigInteger new_stop = lstart.subtract(lstep); - BigInteger new_start = new_stop.add(ulen.multiply(lstep)); - - return getContext().factory().createBigRangeIterator(new_start, new_stop, lstep.negate(), ulen); - } - - @Specialization - static PythonObject reversed(Object cls, PString value, - @Bind("this") Node inliningTarget, - @Cached CastToTruffleStringNode castToStringNode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createStringReverseIterator(cls, castToStringNode.execute(inliningTarget, value)); - } - - @Specialization - static PythonObject reversed(Object cls, TruffleString value, - @Shared @Cached PythonObjectFactory factory) { - return factory.createStringReverseIterator(cls, value); - } - - @Specialization(guards = {"!isString(sequence)", "!isPRange(sequence)"}) - static Object reversed(VirtualFrame frame, Object cls, Object sequence, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached("create(Reversed)") LookupSpecialMethodSlotNode lookupReversed, - @Cached CallUnaryMethodNode callReversed, - @Cached PySequenceSizeNode pySequenceSizeNode, - @Cached InlinedConditionProfile noReversedProfile, - @Cached PySequenceCheckNode pySequenceCheck, - @Shared @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - Object sequenceKlass = getClassNode.execute(inliningTarget, sequence); - Object reversed = lookupReversed.execute(frame, sequenceKlass, sequence); - if (noReversedProfile.profile(inliningTarget, reversed == PNone.NO_VALUE)) { - if (!pySequenceCheck.execute(inliningTarget, sequence)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.OBJ_ISNT_REVERSIBLE, sequence); - } else { - int lengthHint = pySequenceSizeNode.execute(frame, inliningTarget, sequence); - return factory.createSequenceReverseIterator(cls, sequence, lengthHint); - } - } else { - return callReversed.executeObject(frame, reversed, sequence); - } - } - } - - // float([x]) - @Builtin(name = J_FLOAT, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PFloat, doc = "Convert a string or number to a floating point number, if possible.") - @GenerateNodeFactory - abstract static class FloatNode extends PythonBinaryBuiltinNode { - - @Child NonPrimitiveFloatNode nonPrimitiveFloatNode; - - @Specialization - Object doIt(VirtualFrame frame, Object cls, Object arg, - @Bind("this") Node inliningTarget, - @Cached IsBuiltinClassExactProfile isPrimitiveFloatProfile, - @Cached PrimitiveFloatNode primitiveFloatNode, - @Cached NeedsNativeAllocationNode needsNativeAllocationNode) { - if (isPrimitiveFloat(inliningTarget, cls, isPrimitiveFloatProfile)) { - return primitiveFloatNode.execute(frame, inliningTarget, arg); - } else { - boolean needsNativeAllocation = needsNativeAllocationNode.execute(inliningTarget, cls); - if (nonPrimitiveFloatNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - nonPrimitiveFloatNode = insert(NonPrimitiveFloatNodeGen.create()); - } - return nonPrimitiveFloatNode.execute(frame, cls, arg, needsNativeAllocation); - } - } - - @GenerateCached(false) - @GenerateInline - @ImportStatic(PGuards.class) - abstract static class PrimitiveFloatNode extends Node { - abstract double execute(VirtualFrame frame, Node inliningTarget, Object arg); - - @Specialization - static double floatFromDouble(double arg) { - return arg; - } - - @Specialization - static double floatFromInt(int arg) { - return arg; - } - - @Specialization - static double floatFromLong(long arg) { - return arg; - } - - @Specialization - static double floatFromBoolean(boolean arg) { - return arg ? 1d : 0d; - } - - @Specialization(guards = "isNoValue(obj)") - static double floatFromNoValue(@SuppressWarnings("unused") PNone obj) { - return 0.0; - } - - @Fallback - @InliningCutoff - static double floatFromObject(VirtualFrame frame, Node inliningTarget, Object obj, - @Cached PyUnicodeCheckExactNode stringCheck, - @Cached PyFloatFromString fromString, - @Cached PyNumberFloatNode pyNumberFloat) { - if (stringCheck.execute(inliningTarget, obj)) { - return fromString.execute(frame, inliningTarget, obj); - } - return pyNumberFloat.execute(frame, inliningTarget, obj); - } - } - - @ImportStatic(PGuards.class) - @GenerateInline(false) // intentionally lazy - abstract static class NonPrimitiveFloatNode extends Node { - abstract Object execute(VirtualFrame frame, Object cls, Object arg, boolean needsNativeAllocation); - - @Specialization(guards = {"!needsNativeAllocation", "isNoValue(obj)"}) - @InliningCutoff - Object floatFromNoneManagedSubclass(Object cls, PNone obj, - @SuppressWarnings("unused") boolean needsNativeAllocation, - @Shared @Cached PythonObjectFactory factory) { - return factory.createFloat(cls, PrimitiveFloatNode.floatFromNoValue(obj)); - } - - @Specialization(guards = "!needsNativeAllocation") - @InliningCutoff - Object floatFromObjectManagedSubclass(VirtualFrame frame, Object cls, Object obj, @SuppressWarnings("unused") boolean needsNativeAllocation, - @Bind("this") @SuppressWarnings("unused") Node inliningTarget, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PrimitiveFloatNode recursiveCallNode) { - return factory.createFloat(cls, recursiveCallNode.execute(frame, inliningTarget, obj)); - } - - // logic similar to float_subtype_new(PyTypeObject *type, PyObject *x) from CPython - // floatobject.c we have to first create a temporary float, then fill it into - // a natively allocated subtype structure - @Specialization(guards = {"needsNativeAllocation", // - "isSubtypeOfFloat(frame, isSubtype, cls)"}, limit = "1") - @InliningCutoff - static Object floatFromObjectNativeSubclass(VirtualFrame frame, Object cls, Object obj, @SuppressWarnings("unused") boolean needsNativeAllocation, - @Bind("this") @SuppressWarnings("unused") Node inliningTarget, - @Cached @SuppressWarnings("unused") IsSubtypeNode isSubtype, - @Cached CExtNodes.FloatSubtypeNew subtypeNew, - @Shared @Cached PrimitiveFloatNode recursiveCallNode) { - return subtypeNew.call(cls, recursiveCallNode.execute(frame, inliningTarget, obj)); - } - - protected static boolean isSubtypeOfFloat(VirtualFrame frame, IsSubtypeNode isSubtypeNode, Object cls) { - return isSubtypeNode.execute(frame, cls, PythonBuiltinClassType.PFloat); - } - } - - protected static boolean isPrimitiveFloat(Node inliningTarget, Object cls, IsBuiltinClassExactProfile isPrimitiveProfile) { - return isPrimitiveProfile.profileClass(inliningTarget, cls, PythonBuiltinClassType.PFloat); - } - } - - // frozenset([iterable]) - @Builtin(name = J_FROZENSET, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PFrozenSet, doc = """ - frozenset() -> empty frozenset object - frozenset(iterable) -> frozenset object - - Build an immutable unordered collection of unique elements.""") - @GenerateNodeFactory - public abstract static class FrozenSetNode extends PythonBinaryBuiltinNode { - - @Specialization(guards = "isNoValue(arg)") - static PFrozenSet frozensetEmpty(Object cls, @SuppressWarnings("unused") PNone arg, - @Shared @Cached PythonObjectFactory factory) { - return factory.createFrozenSet(cls); - } - - @Specialization(guards = "isBuiltinClass.profileIsAnyBuiltinClass(inliningTarget, cls)") - static PFrozenSet frozensetIdentity(@SuppressWarnings("unused") Object cls, PFrozenSet arg, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @Shared("isBuiltinProfile") @SuppressWarnings("unused") @Cached IsAnyBuiltinClassProfile isBuiltinClass) { - return arg; - } - - @Specialization(guards = "!isBuiltinClass.profileIsAnyBuiltinClass(inliningTarget, cls)") - static PFrozenSet subFrozensetIdentity(Object cls, PFrozenSet arg, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @Shared("isBuiltinProfile") @SuppressWarnings("unused") @Cached IsAnyBuiltinClassProfile isBuiltinClass, - @Shared @Cached PythonObjectFactory factory) { - return factory.createFrozenSet(cls, arg.getDictStorage()); - } - - @Specialization(guards = {"!isNoValue(iterable)", "!isPFrozenSet(iterable)"}) - static PFrozenSet frozensetIterable(VirtualFrame frame, Object cls, Object iterable, - @Bind("this") Node inliningTarget, - @Cached HashingCollectionNodes.GetClonedHashingStorageNode getHashingStorageNode, - @Shared @Cached PythonObjectFactory factory) { - HashingStorage storage = getHashingStorageNode.doNoValue(frame, inliningTarget, iterable); - return factory.createFrozenSet(cls, storage); - } - } - - // int(x=0) - // int(x, base=10) - @Builtin(name = J_INT, minNumOfPositionalArgs = 1, parameterNames = {"cls", "x", "base"}, numOfPositionalOnlyArgs = 2, constructsClass = PythonBuiltinClassType.PInt, doc = """ - int([x]) -> integer - int(x, base=10) -> integer - - Convert a number or string to an integer, or return 0 if no arguments - are given. If x is a number, return x.__int__(). For floating point - numbers, this truncates towards zero. - - If x is not a number or if base is given, then x must be a string, - bytes, or bytearray instance representing an integer literal in the - given base. The literal can be preceded by '+' or '-' and be surrounded - by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. - Base 0 means to interpret the base from the string as an integer literal.""") - @GenerateNodeFactory - public abstract static class IntNode extends PythonTernaryBuiltinNode { - - @Specialization - static Object doGeneric(VirtualFrame frame, Object cls, Object x, Object baseObj, - @Bind("this") Node inliningTarget, - @Cached IntNodeInnerNode innerNode, - @Cached IsBuiltinClassExactProfile isPrimitiveIntProfile, - @Cached CreateIntSubclassNode createIntSubclassNode) { - Object result = innerNode.execute(frame, inliningTarget, x, baseObj); - if (isPrimitiveIntProfile.profileClass(inliningTarget, cls, PythonBuiltinClassType.PInt)) { - return result; - } else { - return createIntSubclassNode.execute(inliningTarget, cls, result); - } - } - - @GenerateInline - @GenerateCached(false) - abstract static class CreateIntSubclassNode extends Node { - public abstract Object execute(Node inliningTarget, Object cls, Object intObj); - - @Specialization - static Object doSubclass(Object cls, int value, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createInt(cls, value); - } - - @Specialization - static Object doSubclass(Object cls, long value, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createInt(cls, value); - } - - @Specialization - static Object doSubclass(Object cls, boolean value, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createInt(cls, PInt.intValue(value)); - } - - @Specialization - static Object doSubclass(Object cls, PInt value, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createInt(cls, value.getValue()); - } - } - - @GenerateInline - @GenerateCached(false) - @ImportStatic(PGuards.class) - abstract static class IntNodeInnerNode extends Node { - public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object x, Object base); - - @Specialization(guards = "isNoValue(baseObj)") - static Object doNoBase(VirtualFrame frame, Node inliningTarget, Object x, @SuppressWarnings("unused") Object baseObj, - @Cached InlinedBranchProfile noX, - @Cached PyNumberLongNode pyNumberLongNode) { - if (x == PNone.NO_VALUE) { - noX.enter(inliningTarget); - return 0; - } else { - return pyNumberLongNode.execute(frame, inliningTarget, x); - } - } - - @Fallback - @InliningCutoff - static Object doWithBase(VirtualFrame frame, Node inliningTarget, Object x, Object baseObj, - @Cached InlinedBranchProfile missingArgument, - @Cached InlinedBranchProfile wrongBase, - @Cached InlinedBranchProfile cannotConvert, - @Cached PyNumberAsSizeNode asSizeNode, - @Cached PyUnicodeCheckNode unicodeCheckNode, - @Cached PyLongFromUnicodeObject longFromUnicode, - @Cached BytesNodes.BytesLikeCheck bytesLikeCheck, - @Cached PyNumberLongNode.LongFromBufferNode fromBufferNode, - @Cached PRaiseNode.Lazy raiseNode) { - if (x == PNone.NO_VALUE) { - missingArgument.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.INT_MISSING_STRING_ARGUMENT); - } - int base = asSizeNode.executeLossy(frame, inliningTarget, baseObj); - if ((base != 0 && base < 2) || base > 36) { - wrongBase.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.INT_BASE_MUST_BE_2_AND_36_OR_0); - } - if (unicodeCheckNode.execute(inliningTarget, x)) { - return longFromUnicode.execute(inliningTarget, x, base); - } else if (bytesLikeCheck.execute(inliningTarget, x)) { - return fromBufferNode.execute(frame, x, base); - } - cannotConvert.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.INT_CANT_CONVERT_STRING_WITH_EXPL_BASE); - } - } - } - - // bool([x]) - @Builtin(name = J_BOOL, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.Boolean, base = PythonBuiltinClassType.PInt, doc = """ - bool(x) -> bool - - Returns True when the argument x is true, False otherwise. - The builtins True and False are the only two instances of the class bool. - The class bool is a subclass of the class int, and cannot be subclassed.""") - @GenerateNodeFactory - public abstract static class BoolNode extends PythonBinaryBuiltinNode { - @Specialization - public static boolean bool(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object obj, - @Cached PyObjectIsTrueNode isTrue) { - return isTrue.execute(frame, obj); - } - } - - // list([iterable]) - @Builtin(name = J_LIST, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PList, doc = """ - Built-in mutable sequence. - - If no argument is given, the constructor creates a new empty list. - The argument must be an iterable if specified.""") - @GenerateNodeFactory - public abstract static class ListNode extends PythonVarargsBuiltinNode { - @Specialization - protected PList constructList(Object cls, @SuppressWarnings("unused") Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords, - @Cached PythonObjectFactory factory) { - return factory.createList(cls); - } - } - - // object() - @Builtin(name = J_OBJECT, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PythonObject, doc = """ - The base class of the class hierarchy. - - When called, it accepts no arguments and returns a new featureless - instance that has no instance attributes and cannot be given any. - """) - @GenerateNodeFactory - public abstract static class ObjectNode extends PythonVarargsBuiltinNode { - - @Child private SplitArgsNode splitArgsNode; - @Child private ReportAbstractClassNode reportAbstractClassNode; - - @GenerateInline(false) // Used lazily - abstract static class ReportAbstractClassNode extends PNodeWithContext { - public abstract PException execute(VirtualFrame frame, Object type); - - @Specialization - static PException report(VirtualFrame frame, Object type, - @Bind("this") Node inliningTarget, - @Cached PyObjectCallMethodObjArgs callSort, - @Cached PyObjectCallMethodObjArgs callJoin, - @Cached PyObjectSizeNode sizeNode, - @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode, - @Cached CastToTruffleStringNode cast, - @Cached ListNodes.ConstructListNode constructListNode, - @Cached PRaiseNode raiseNode) { - PList list = constructListNode.execute(frame, readAttributeFromObjectNode.execute(type, T___ABSTRACTMETHODS__)); - int methodCount = sizeNode.execute(frame, inliningTarget, list); - callSort.execute(frame, inliningTarget, list, T_SORT); - TruffleString joined = cast.execute(inliningTarget, callJoin.execute(frame, inliningTarget, T_COMMA_SPACE, T_JOIN, list)); - throw raiseNode.raise(TypeError, ErrorMessages.CANT_INSTANTIATE_ABSTRACT_CLASS_WITH_ABSTRACT_METHODS, type, methodCount > 1 ? "s" : "", joined); - } - } - - @GenerateInline - @GenerateCached(false) - @ImportStatic(SpecialMethodSlot.class) - abstract static class CheckExcessArgsNode extends Node { - abstract void execute(Node inliningTarget, Object type, Object[] args, PKeyword[] kwargs); - - @Specialization(guards = {"args.length == 0", "kwargs.length == 0"}) - @SuppressWarnings("unused") - static void doNothing(Object type, Object[] args, PKeyword[] kwargs) { - } - - @Fallback - @SuppressWarnings("unused") - static void check(Node inliningTarget, Object type, Object[] args, PKeyword[] kwargs, - @Cached(parameters = "Init", inline = false) LookupCallableSlotInMRONode lookupInit, - @Cached(parameters = "New", inline = false) LookupCallableSlotInMRONode lookupNew, - @Cached TypeNodes.CheckCallableIsSpecificBuiltinNode checkSlotIs, - @Cached PRaiseNode.Lazy raiseNode) { - if (!checkSlotIs.execute(inliningTarget, lookupNew.execute(type), BuiltinConstructorsFactory.ObjectNodeFactory.getInstance())) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.NEW_TAKES_ONE_ARG); - } - if (checkSlotIs.execute(inliningTarget, lookupInit.execute(type), ObjectBuiltinsFactory.InitNodeFactory.getInstance())) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.NEW_TAKES_NO_ARGS, type); - } - } - } - - @Override - public final Object varArgExecute(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported { - if (splitArgsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - splitArgsNode = insert(SplitArgsNode.create()); - } - return execute(frame, arguments[0], splitArgsNode.executeCached(arguments), keywords); - } - - @Specialization(guards = {"!self.needsNativeAllocation()"}) - Object doManagedObject(VirtualFrame frame, PythonManagedClass self, Object[] varargs, PKeyword[] kwargs, - @Bind("this") Node inliningTarget, - @Shared @Cached CheckExcessArgsNode checkExcessArgsNode, - @Shared @Cached PythonObjectFactory factory) { - checkExcessArgsNode.execute(inliningTarget, self, varargs, kwargs); - if (self.isAbstractClass()) { - throw reportAbstractClass(frame, self); - } - return factory.createPythonObject(self); - } - - @Specialization - static Object doBuiltinTypeType(PythonBuiltinClassType self, Object[] varargs, PKeyword[] kwargs, - @Bind("this") Node inliningTarget, - @Shared @Cached CheckExcessArgsNode checkExcessArgsNode, - @Shared @Cached PythonObjectFactory factory) { - checkExcessArgsNode.execute(inliningTarget, self, varargs, kwargs); - return factory.createPythonObject(self); - } - - @Specialization(guards = "self.needsNativeAllocation()") - @SuppressWarnings("truffle-static-method") - @InliningCutoff - Object doNativeObjectIndirect(VirtualFrame frame, PythonManagedClass self, Object[] varargs, PKeyword[] kwargs, - @Bind("this") Node inliningTarget, - @Shared @Cached CheckExcessArgsNode checkExcessArgsNode, - @Shared @Cached CallNativeGenericNewNode callNativeGenericNewNode) { - checkExcessArgsNode.execute(inliningTarget, self, varargs, kwargs); - if (self.isAbstractClass()) { - throw reportAbstractClass(frame, self); - } - return callNativeGenericNewNode.execute(inliningTarget, self); - } - - @Specialization(guards = "isNativeClass(self)") - @SuppressWarnings("truffle-static-method") - @InliningCutoff - Object doNativeObjectDirect(VirtualFrame frame, Object self, Object[] varargs, PKeyword[] kwargs, - @Bind("this") Node inliningTarget, - @Shared @Cached CheckExcessArgsNode checkExcessArgsNode, - @Exclusive @Cached TypeNodes.GetTypeFlagsNode getTypeFlagsNode, - @Shared @Cached CallNativeGenericNewNode callNativeGenericNewNode) { - checkExcessArgsNode.execute(inliningTarget, self, varargs, kwargs); - if ((getTypeFlagsNode.execute(self) & TypeFlags.IS_ABSTRACT) != 0) { - throw reportAbstractClass(frame, self); - } - return callNativeGenericNewNode.execute(inliningTarget, self); - } - - @GenerateInline - @GenerateCached(false) - protected abstract static class CallNativeGenericNewNode extends Node { - abstract Object execute(Node inliningTarget, Object cls); - - @Specialization - static Object call(Object cls, - @Cached(inline = false) PythonToNativeNode toNativeNode, - @Cached(inline = false) NativeToPythonTransferNode toPythonNode, - @Cached(inline = false) PCallCapiFunction callCapiFunction) { - return toPythonNode.execute(callCapiFunction.call(FUN_PY_OBJECT_NEW, toNativeNode.execute(cls))); - } - } - - @SuppressWarnings("unused") - @Fallback - Object fallback(Object o, Object[] varargs, PKeyword[] kwargs) { - throw raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "object.__new__(X): X", o); - } - - @InliningCutoff - private PException reportAbstractClass(VirtualFrame frame, Object type) { - if (reportAbstractClassNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - reportAbstractClassNode = insert(ReportAbstractClassNodeGen.create()); - } - return reportAbstractClassNode.execute(frame, type); - } - } - - // range(stop) - // range(start, stop[, step]) - @Builtin(name = J_RANGE, minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 4, constructsClass = PythonBuiltinClassType.PRange, doc = """ - range(stop) -> range object - range(start, stop[, step]) -> range object - - Return an object that produces a sequence of integers from start (inclusive) - to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1. - start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3. - These are exactly the valid indices for a list of 4 elements. - When step is given, it specifies the increment (or decrement).""") - @GenerateNodeFactory - @ReportPolymorphism - public abstract static class RangeNode extends PythonQuaternaryBuiltinNode { - // stop - @Specialization(guards = "isStop(start, stop, step)") - static Object doIntStop(Object cls, int stop, @SuppressWarnings("unused") PNone start, @SuppressWarnings("unused") PNone step, - @Bind("this") Node inliningTarget, - @Shared("exceptionProfile") @Cached InlinedBranchProfile exceptionProfile, - @Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact, - @Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - return doInt(cls, 0, stop, 1, inliningTarget, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode, factory, raiseNode); - } - - @Specialization(guards = "isStop(start, stop, step)") - static Object doPintStop(Object cls, PInt stop, @SuppressWarnings("unused") PNone start, @SuppressWarnings("unused") PNone step, - @Bind("this") Node inliningTarget, - @Shared("lenOfRangeNode") @Cached RangeNodes.LenOfRangeNode lenOfRangeNode, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - return doPint(cls, factory.createInt(0), stop, factory.createInt(1), inliningTarget, lenOfRangeNode, factory, raiseNode); - } - - @Specialization(guards = "isStop(start, stop, step)") - static Object doGenericStop(VirtualFrame frame, Object cls, Object stop, @SuppressWarnings("unused") PNone start, @SuppressWarnings("unused") PNone step, - @Bind("this") Node inliningTarget, - @Shared("exceptionProfile") @Cached InlinedBranchProfile exceptionProfile, - @Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact, - @Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode, - @Shared("cast") @Cached CastToJavaIntExactNode cast, - @Shared("overflowProfile") @Cached IsBuiltinObjectProfile overflowProfile, - @Shared("indexNode") @Cached PyNumberIndexNode indexNode, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - return doGeneric(frame, cls, 0, stop, 1, inliningTarget, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode, cast, overflowProfile, indexNode, factory, raiseNode); - } - - // start stop - @Specialization(guards = "isStartStop(start, stop, step)") - static Object doIntStartStop(Object cls, int start, int stop, @SuppressWarnings("unused") PNone step, - @Bind("this") Node inliningTarget, - @Shared("exceptionProfile") @Cached InlinedBranchProfile exceptionProfile, - @Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact, - @Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - return doInt(cls, start, stop, 1, inliningTarget, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode, factory, raiseNode); - } - - @Specialization(guards = "isStartStop(start, stop, step)") - static Object doPintStartStop(Object cls, PInt start, PInt stop, @SuppressWarnings("unused") PNone step, - @Bind("this") Node inliningTarget, - @Shared("lenOfRangeNode") @Cached RangeNodes.LenOfRangeNode lenOfRangeNode, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - return doPint(cls, start, stop, factory.createInt(1), inliningTarget, lenOfRangeNode, factory, raiseNode); - } - - @Specialization(guards = "isStartStop(start, stop, step)") - static Object doGenericStartStop(VirtualFrame frame, Object cls, Object start, Object stop, @SuppressWarnings("unused") PNone step, - @Bind("this") Node inliningTarget, - @Shared("exceptionProfile") @Cached InlinedBranchProfile exceptionProfile, - @Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact, - @Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode, - @Shared("cast") @Cached CastToJavaIntExactNode cast, - @Shared("overflowProfile") @Cached IsBuiltinObjectProfile overflowProfile, - @Shared("indexNode") @Cached PyNumberIndexNode indexNode, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - return doGeneric(frame, cls, start, stop, 1, inliningTarget, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode, cast, overflowProfile, indexNode, factory, raiseNode); - } - - // start stop step - @Specialization - static Object doInt(@SuppressWarnings("unused") Object cls, int start, int stop, int step, - @Bind("this") Node inliningTarget, - @Shared("exceptionProfile") @Cached InlinedBranchProfile exceptionProfile, - @Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNode, - @Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - if (step == 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ARG_MUST_NOT_BE_ZERO, "range()", 3); - } - try { - int len = lenOfRangeNode.executeInt(inliningTarget, start, stop, step); - return factory.createIntRange(start, stop, step, len); - } catch (OverflowException e) { - exceptionProfile.enter(inliningTarget); - return createBigRangeNode.execute(inliningTarget, start, stop, step); - } - } - - @Specialization - static Object doPint(@SuppressWarnings("unused") Object cls, PInt start, PInt stop, PInt step, - @Bind("this") Node inliningTarget, - @Shared("lenOfRangeNode") @Cached RangeNodes.LenOfRangeNode lenOfRangeNode, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - if (step.isZero()) { - throw raiseNode.get(inliningTarget).raise(ValueError, ARG_MUST_NOT_BE_ZERO, "range()", 3); - } - BigInteger len = lenOfRangeNode.execute(inliningTarget, start.getValue(), stop.getValue(), step.getValue()); - return factory.createBigRange(start, stop, step, factory.createInt(len)); - } - - @Specialization(guards = "isStartStopStep(start, stop, step)") - static Object doGeneric(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object start, Object stop, Object step, - @Bind("this") Node inliningTarget, - @Shared("exceptionProfile") @Cached InlinedBranchProfile exceptionProfile, - @Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact, - @Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode, - @Shared("cast") @Cached CastToJavaIntExactNode cast, - @Shared("overflowProfile") @Cached IsBuiltinObjectProfile overflowProfile, - @Shared("indexNode") @Cached PyNumberIndexNode indexNode, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - Object lstart = indexNode.execute(frame, inliningTarget, start); - Object lstop = indexNode.execute(frame, inliningTarget, stop); - Object lstep = indexNode.execute(frame, inliningTarget, step); - - try { - int istart = cast.execute(inliningTarget, lstart); - int istop = cast.execute(inliningTarget, lstop); - int istep = cast.execute(inliningTarget, lstep); - return doInt(cls, istart, istop, istep, inliningTarget, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode, factory, raiseNode); - } catch (PException e) { - e.expect(inliningTarget, OverflowError, overflowProfile); - return createBigRangeNode.execute(inliningTarget, lstart, lstop, lstep); - } - } - - protected static boolean isStop(Object start, Object stop, Object step) { - return isNoValue(start) && !isNoValue(stop) && isNoValue(step); - } - - protected static boolean isStartStop(Object start, Object stop, Object step) { - return !isNoValue(start) && !isNoValue(stop) && isNoValue(step); - } - - protected static boolean isStartStopStep(Object start, Object stop, Object step) { - return !isNoValue(start) && !isNoValue(stop) && !isNoValue(step); - } - } - - // set([iterable]) - @Builtin(name = J_SET, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PSet, doc = """ - set() -> new empty set object - set(iterable) -> new set object - - Build an unordered collection of unique elements.""") - @GenerateNodeFactory - public abstract static class SetNode extends PythonBuiltinNode { - - @Specialization - public PSet setEmpty(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PythonObjectFactory factory) { - return factory.createSet(cls); - } - - } - - // str(object='') - // str(object=b'', encoding='utf-8', errors='strict') - @Builtin(name = J_STR, minNumOfPositionalArgs = 1, parameterNames = {"cls", "object", "encoding", "errors"}, constructsClass = PythonBuiltinClassType.PString, doc = """ - str(object='') -> str - str(bytes_or_buffer[, encoding[, errors]]) -> str - - Create a new string object from the given object. If encoding or - errors is specified, then the object must expose a data buffer - that will be decoded using the given encoding and error handler. - Otherwise, returns the result of object.__str__() (if defined) - or repr(object). - encoding defaults to sys.getdefaultencoding(). - errors defaults to 'strict'.""") - @GenerateNodeFactory - public abstract static class StrNode extends PythonBuiltinNode { - - public final Object executeWith(Object arg) { - return executeWith(null, PythonBuiltinClassType.PString, arg, PNone.NO_VALUE, PNone.NO_VALUE); - } - - public final Object executeWith(VirtualFrame frame, Object arg) { - return executeWith(frame, PythonBuiltinClassType.PString, arg, PNone.NO_VALUE, PNone.NO_VALUE); - } - - public abstract Object executeWith(VirtualFrame frame, Object cls, Object arg, Object encoding, Object errors); - - @Specialization(guards = {"!needsNativeAllocationNode.execute(inliningTarget, cls)", "isNoValue(arg)"}, limit = "1") - @SuppressWarnings("unused") - static Object strNoArgs(Object cls, PNone arg, Object encoding, Object errors, - @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, - @Exclusive @Cached IsBuiltinClassExactProfile isPrimitiveProfile, - @Shared @Cached PythonObjectFactory factory) { - return asPString(cls, T_EMPTY_STRING, inliningTarget, isPrimitiveProfile, factory); - } - - @Specialization(guards = {"!needsNativeAllocationNode.execute(inliningTarget, cls)", "!isNoValue(obj)", "isNoValue(encoding)", "isNoValue(errors)"}, limit = "1") - static Object strOneArg(VirtualFrame frame, Object cls, Object obj, @SuppressWarnings("unused") PNone encoding, @SuppressWarnings("unused") PNone errors, - @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, - @Exclusive @Cached IsBuiltinClassExactProfile isPrimitiveProfile, - @Exclusive @Cached InlinedConditionProfile isStringProfile, - @Cached CastToTruffleStringNode castToTruffleStringNode, - @Exclusive @Cached PyObjectStrAsObjectNode strNode, - @Shared @Cached PythonObjectFactory factory) { - Object result = strNode.execute(frame, inliningTarget, obj); - - // try to return a primitive if possible - assertNoJavaString(result); - if (isStringProfile.profile(inliningTarget, result instanceof TruffleString)) { - return asPString(cls, (TruffleString) result, inliningTarget, isPrimitiveProfile, factory); - } - - if (isPrimitiveProfile.profileClass(inliningTarget, cls, PythonBuiltinClassType.PString)) { - // PyObjectStrAsObjectNode guarantees that the returned object is an instanceof of - // 'str' - return result; - } else { - try { - return asPString(cls, castToTruffleStringNode.execute(inliningTarget, result), inliningTarget, isPrimitiveProfile, factory); - } catch (CannotCastException e) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw new IllegalStateException("asPstring result not castable to String"); - } - } - } - - @Specialization(guards = {"!needsNativeAllocationNode.execute(inliningTarget, cls)", "!isNoValue(encoding) || !isNoValue(errors)"}, limit = "3") - static Object doBuffer(VirtualFrame frame, Object cls, Object obj, Object encoding, Object errors, - @Bind("this") Node inliningTarget, - @Exclusive @Cached("createFor(this)") IndirectCallData indirectCallData, - @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, - @Exclusive @Cached IsBuiltinClassExactProfile isPrimitiveProfile, - @Exclusive @Cached InlinedConditionProfile isStringProfile, - @Exclusive @Cached InlinedConditionProfile isPStringProfile, - @Exclusive @CachedLibrary("obj") PythonBufferAcquireLibrary acquireLib, - @Exclusive @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Exclusive @Cached("create(T_DECODE)") LookupAndCallTernaryNode callDecodeNode, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - Object buffer; - try { - buffer = acquireLib.acquireReadonly(obj, frame, indirectCallData); - } catch (PException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.NEED_BYTELIKE_OBJ, obj); - } - try { - // TODO(fa): we should directly call '_codecs.decode' - // TODO don't copy, CPython creates a memoryview - PBytes bytesObj = factory.createBytes(bufferLib.getCopiedByteArray(buffer)); - Object en = encoding == PNone.NO_VALUE ? T_UTF8 : encoding; - Object result = assertNoJavaString(callDecodeNode.execute(frame, bytesObj, en, errors)); - if (isStringProfile.profile(inliningTarget, result instanceof TruffleString)) { - return asPString(cls, (TruffleString) result, inliningTarget, isPrimitiveProfile, factory); - } else if (isPStringProfile.profile(inliningTarget, result instanceof PString)) { - return result; - } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.P_S_RETURNED_NON_STRING, bytesObj, "decode", result); - } finally { - bufferLib.release(buffer, frame, indirectCallData); - } - } - - /** - * logic similar to - * {@code unicode_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)} from - * CPython {@code unicodeobject.c} we have to first create a temporary string, then fill it - * into a natively allocated subtype structure - */ - @Specialization(guards = {"needsNativeAllocationNode.execute(inliningTarget, cls)", "isSubtypeOfString(frame, isSubtype, cls)", // - "isNoValue(encoding)", "isNoValue(errors)"}, limit = "1") - static Object doNativeSubclass(VirtualFrame frame, Object cls, Object obj, @SuppressWarnings("unused") Object encoding, @SuppressWarnings("unused") Object errors, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, - @Shared @Cached @SuppressWarnings("unused") IsSubtypeNode isSubtype, - @Exclusive @Cached PyObjectStrAsObjectNode strNode, - @Shared @Cached(neverDefault = true) CExtNodes.StringSubtypeNew subtypeNew) { - if (obj == PNone.NO_VALUE) { - return subtypeNew.call(cls, T_EMPTY_STRING); - } else { - return subtypeNew.call(cls, strNode.execute(frame, inliningTarget, obj)); - } - } - - @Specialization(guards = {"needsNativeAllocationNode.execute(inliningTarget, cls)", "isSubtypeOfString(frame, isSubtype, cls)", // - "!isNoValue(encoding) || !isNoValue(errors)"}, limit = "1") - static Object doNativeSubclassEncodeErr(VirtualFrame frame, Object cls, Object obj, @SuppressWarnings("unused") Object encoding, @SuppressWarnings("unused") Object errors, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @Exclusive @Cached("createFor(this)") IndirectCallData indirectCallData, - @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, - @Shared @Cached @SuppressWarnings("unused") IsSubtypeNode isSubtype, - @Exclusive @Cached IsBuiltinClassExactProfile isPrimitiveProfile, - @Exclusive @Cached InlinedConditionProfile isStringProfile, - @Exclusive @Cached InlinedConditionProfile isPStringProfile, - @Exclusive @CachedLibrary("obj") PythonBufferAcquireLibrary acquireLib, - @Exclusive @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Exclusive @Cached("create(T_DECODE)") LookupAndCallTernaryNode callDecodeNode, - @Shared @Cached(neverDefault = true) CExtNodes.StringSubtypeNew subtypeNew, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - Object buffer; - try { - buffer = acquireLib.acquireReadonly(obj, frame, indirectCallData); - } catch (PException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.NEED_BYTELIKE_OBJ, obj); - } - try { - PBytes bytesObj = factory.createBytes(bufferLib.getCopiedByteArray(buffer)); - Object en = encoding == PNone.NO_VALUE ? T_UTF8 : encoding; - Object result = assertNoJavaString(callDecodeNode.execute(frame, bytesObj, en, errors)); - if (isStringProfile.profile(inliningTarget, result instanceof TruffleString)) { - return subtypeNew.call(cls, asPString(cls, (TruffleString) result, inliningTarget, isPrimitiveProfile, factory)); - } else if (isPStringProfile.profile(inliningTarget, result instanceof PString)) { - return subtypeNew.call(cls, result); - } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.P_S_RETURNED_NON_STRING, bytesObj, "decode", result); - } finally { - bufferLib.release(buffer, frame, indirectCallData); - } - } - - protected static boolean isSubtypeOfString(VirtualFrame frame, IsSubtypeNode isSubtypeNode, Object cls) { - return isSubtypeNode.execute(frame, cls, PythonBuiltinClassType.PString); - } - - private static Object asPString(Object cls, TruffleString str, Node inliningTarget, IsBuiltinClassExactProfile isPrimitiveProfile, - PythonObjectFactory factory) { - if (isPrimitiveProfile.profileClass(inliningTarget, cls, PythonBuiltinClassType.PString)) { - return str; - } else { - return factory.createString(cls, str); - } - } - - @NeverDefault - public static StrNode create() { - return BuiltinConstructorsFactory.StrNodeFactory.create(null); - } - } - - // tuple([iterable]) - @Builtin(name = J_TUPLE, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PTuple, doc = """ - Built-in immutable sequence. - - If no argument is given, the constructor returns an empty tuple. - If iterable is specified the tuple is initialized from iterable's items. - - If the argument is a tuple, the return value is the same object.""") - @GenerateNodeFactory - public abstract static class TupleNode extends PythonBinaryBuiltinNode { - - @Specialization(guards = "!needsNativeAllocationNode.execute(inliningTarget, cls)") - static PTuple constructTuple(VirtualFrame frame, Object cls, Object iterable, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Shared @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, - @Cached TupleNodes.ConstructTupleNode constructTupleNode) { - return constructTupleNode.execute(frame, cls, iterable); - } - - // delegate to tuple_subtype_new(PyTypeObject *type, PyObject *x) - @Specialization(guards = {"needsNativeAllocationNode.execute(inliningTarget, cls)", "isSubtypeOfTuple(frame, isSubtype, cls)"}, limit = "1") - @InliningCutoff - static Object doNative(@SuppressWarnings("unused") VirtualFrame frame, Object cls, Object iterable, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Shared @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, - @Cached @SuppressWarnings("unused") IsSubtypeNode isSubtype, - @Cached CExtNodes.TupleSubtypeNew subtypeNew) { - return subtypeNew.call(cls, iterable); - } - - protected static boolean isSubtypeOfTuple(VirtualFrame frame, IsSubtypeNode isSubtypeNode, Object cls) { - return isSubtypeNode.execute(frame, cls, PythonBuiltinClassType.PTuple); - } - - @Fallback - static PTuple tupleObject(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - } - - // zip(*iterables) - @Builtin(name = J_ZIP, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PZip, doc = """ - zip(*iterables, strict=False) --> Yield tuples until an input is exhausted. - - >>> list(zip('abcdefg', range(3), range(4))) - [('a', 0, 0), ('b', 1, 1), ('c', 2, 2)] - - The zip object yields n-length tuples, where n is the number of iterables - passed as positional arguments to zip(). The i-th element in every tuple - comes from the i-th iterable argument to zip(). This continues until the - shortest argument is exhausted. - - If strict is true and one of the arguments is exhausted before the others, - raise a ValueError.""") - @GenerateNodeFactory - public abstract static class ZipNode extends PythonBuiltinNode { - static boolean isNoneOrEmptyPKeyword(Object value) { - return PGuards.isPNone(value) || (value instanceof PKeyword[] kw && kw.length == 0); - } - - @Specialization(guards = "isNoneOrEmptyPKeyword(kw)") - static PZip zip(VirtualFrame frame, Object cls, Object[] args, @SuppressWarnings("unused") Object kw, - @Bind("this") Node inliningTarget, - @Exclusive @Cached PyObjectGetIter getIter, - @Shared @Cached PythonObjectFactory factory) { - return zip(frame, inliningTarget, cls, args, false, getIter, factory); - } - - @Specialization(guards = "kw.length == 1") - static PZip zip(VirtualFrame frame, Object cls, Object[] args, PKeyword[] kw, - @Bind("this") Node inliningTarget, - @Cached TruffleString.EqualNode eqNode, - @Exclusive @Cached PyObjectGetIter getIter, - @Cached PyObjectIsTrueNode isTrueNode, - @Cached InlinedConditionProfile profile, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - if (profile.profile(inliningTarget, eqNode.execute(kw[0].getName(), T_STRICT, TS_ENCODING))) { - return zip(frame, inliningTarget, cls, args, isTrueNode.execute(frame, kw[0].getValue()), getIter, factory); - } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_IS_AN_INVALID_ARG_FOR_S, kw[0].getName(), T_ZIP); - } - - @Specialization(guards = "kw.length != 1") - static Object zip(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") Object[] args, PKeyword[] kw, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.S_TAKES_AT_MOST_ONE_KEYWORD_ARGUMENT_D_GIVEN, T_ZIP, kw.length); - } - - private static PZip zip(VirtualFrame frame, Node inliningTarget, Object cls, Object[] args, boolean strict, PyObjectGetIter getIter, PythonObjectFactory factory) { - Object[] iterables = new Object[args.length]; - LoopNode.reportLoopCount(inliningTarget, args.length); - for (int i = 0; i < args.length; i++) { - Object item = args[i]; - iterables[i] = getIter.execute(frame, inliningTarget, item); - } - return factory.createZip(cls, iterables, strict); - } - } - - // function(code, globals[, name[, argdefs[, closure]]]) - @Builtin(name = "function", minNumOfPositionalArgs = 3, parameterNames = {"$cls", "code", "globals", "name", "argdefs", - "closure"}, constructsClass = PythonBuiltinClassType.PFunction, isPublic = false) - @GenerateNodeFactory - public abstract static class FunctionNode extends PythonBuiltinNode { - - @Specialization - static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, @SuppressWarnings("unused") PNone defaultArgs, - @SuppressWarnings("unused") PNone closure, - @Shared @Cached PythonObjectFactory factory) { - return factory.createFunction(name, code, globals, null); - } - - @Specialization - static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, @SuppressWarnings("unused") PNone name, @SuppressWarnings("unused") PNone defaultArgs, - PTuple closure, - @Bind("this") Node inliningTarget, - @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createFunction(T_LAMBDA_NAME, code, globals, PCell.toCellArray(getObjectArrayNode.execute(inliningTarget, closure))); - } - - @Specialization - static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, @SuppressWarnings("unused") PNone name, @SuppressWarnings("unused") PNone defaultArgs, - @SuppressWarnings("unused") PNone closure, - @SuppressWarnings("unused") @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createFunction(T_LAMBDA_NAME, code, globals, null); - } - - @Specialization - static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, @SuppressWarnings("unused") PNone defaultArgs, PTuple closure, - @Bind("this") Node inliningTarget, - @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createFunction(name, code, globals, PCell.toCellArray(getObjectArrayNode.execute(inliningTarget, closure))); - } - - @Specialization - static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, @SuppressWarnings("unused") PNone name, PTuple defaultArgs, - @SuppressWarnings("unused") PNone closure, - @Bind("this") Node inliningTarget, - @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode, - @Shared @Cached PythonObjectFactory factory) { - // TODO split defaults of positional args from kwDefaults - return factory.createFunction(code.getName(), code, globals, getObjectArrayNode.execute(inliningTarget, defaultArgs), null, null); - } - - @Specialization - static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, PTuple defaultArgs, @SuppressWarnings("unused") PNone closure, - @Bind("this") Node inliningTarget, - @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode, - @Shared @Cached PythonObjectFactory factory) { - // TODO split defaults of positional args from kwDefaults - return factory.createFunction(name, code, globals, getObjectArrayNode.execute(inliningTarget, defaultArgs), null, null); - } - - @Specialization - static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, PTuple defaultArgs, PTuple closure, - @Bind("this") Node inliningTarget, - @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode, - @Shared @Cached PythonObjectFactory factory) { - // TODO split defaults of positional args from kwDefaults - return factory.createFunction(name, code, globals, getObjectArrayNode.execute(inliningTarget, defaultArgs), null, PCell.toCellArray(getObjectArrayNode.execute(inliningTarget, closure))); - } - - @Fallback - @SuppressWarnings("unused") - static PFunction function(@SuppressWarnings("unused") Object cls, Object code, Object globals, Object name, Object defaultArgs, Object closure, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.FUNC_CONSTRUCTION_NOT_SUPPORTED, cls, code, globals, name, defaultArgs, closure); - } - } - - // builtin-function(method-def, self, module) - @Builtin(name = "method_descriptor", minNumOfPositionalArgs = 3, maxNumOfPositionalArgs = 6, constructsClass = PythonBuiltinClassType.PBuiltinFunction, isPublic = false) - @GenerateNodeFactory - public abstract static class BuiltinFunctionNode extends PythonBuiltinNode { - @Specialization - @SuppressWarnings("unused") - static PFunction function(Object cls, Object method_def, Object def, Object name, Object module, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "method_descriptor"); - } - } - - // type(object, bases, dict) - @Builtin(name = J_TYPE, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, needsFrame = true, constructsClass = PythonBuiltinClassType.PythonClass) - @GenerateNodeFactory - public abstract static class TypeNode extends PythonVarargsBuiltinNode { - @Child private IsSubtypeNode isSubtypeNode; - @Child private IsAcceptableBaseNode isAcceptableBaseNode; - - public abstract Object execute(VirtualFrame frame, Object cls, Object name, Object bases, Object dict, PKeyword[] kwds); - - @Override - public final Object execute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) { - if (arguments.length == 3) { - return execute(frame, self, arguments[0], arguments[1], arguments[2], keywords); - } else { - throw raise(TypeError, ErrorMessages.TAKES_EXACTLY_D_ARGUMENTS_D_GIVEN, "type.__new__", 3, arguments.length); - } - } - - @Override - public Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) { - if (arguments.length == 4) { - return execute(frame, arguments[0], arguments[1], arguments[2], arguments[3], keywords); - } else if (arguments.length == 3) { - return execute(frame, self, arguments[0], arguments[1], arguments[2], keywords); - } else { - throw raise(TypeError, ErrorMessages.TAKES_EXACTLY_D_ARGUMENTS_D_GIVEN, "type.__new__", 3, arguments.length); - } - } - - @Specialization(guards = "isString(wName)") - @SuppressWarnings("truffle-static-method") - Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict namespaceOrig, PKeyword[] kwds, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached("create(New)") LookupCallableSlotInMRONode getNewFuncNode, - @Cached TypeBuiltins.BindNew bindNew, - @Exclusive @Cached IsTypeNode isTypeNode, - @Cached PyObjectLookupAttr lookupMroEntriesNode, - @Cached CastToTruffleStringNode castStr, - @Cached CallNode callNewFuncNode, - @Cached CreateTypeNode createType, - @Cached GetObjectArrayNode getObjectArrayNode) { - // Determine the proper metatype to deal with this - TruffleString name = castStr.execute(inliningTarget, wName); - Object metaclass = cls; - Object winner = calculateMetaclass(frame, inliningTarget, metaclass, bases, getClassNode, isTypeNode, lookupMroEntriesNode, getObjectArrayNode); - if (winner != metaclass) { - Object newFunc = getNewFuncNode.execute(winner); - if (newFunc instanceof PBuiltinMethod && (((PBuiltinMethod) newFunc).getBuiltinFunction().getFunctionRootNode().getCallTarget() == getRootNode().getCallTarget())) { - metaclass = winner; - // the new metaclass has the same __new__ function as we are in, continue - } else { - // Pass it to the winner - return callNewFuncNode.execute(frame, bindNew.execute(frame, inliningTarget, newFunc, winner), new Object[]{winner, name, bases, namespaceOrig}, kwds); - } - } - - return createType.execute(frame, namespaceOrig, name, bases, metaclass, kwds); - } - - @Fallback - Object generic(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") Object name, Object bases, Object namespace, @SuppressWarnings("unused") PKeyword[] kwds) { - if (!(bases instanceof PTuple)) { - throw raise(TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "type.__new__()", 2, "tuple", bases); - } else if (!(namespace instanceof PDict)) { - throw raise(TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "type.__new__()", 3, "dict", bases); - } else { - throw CompilerDirectives.shouldNotReachHere("type fallback reached incorrectly"); - } - } - - private Object calculateMetaclass(VirtualFrame frame, Node inliningTarget, Object cls, PTuple bases, GetClassNode getClassNode, IsTypeNode isTypeNode, - PyObjectLookupAttr lookupMroEntries, GetObjectArrayNode getObjectArrayNode) { - Object winner = cls; - for (Object base : getObjectArrayNode.execute(inliningTarget, bases)) { - if (!isTypeNode.execute(inliningTarget, base) && lookupMroEntries.execute(frame, inliningTarget, base, T___MRO_ENTRIES__) != PNone.NO_VALUE) { - throw raise(TypeError, ErrorMessages.TYPE_DOESNT_SUPPORT_MRO_ENTRY_RESOLUTION); - } - if (!ensureIsAcceptableBaseNode().execute(base)) { - throw raise(TypeError, ErrorMessages.TYPE_IS_NOT_ACCEPTABLE_BASE_TYPE, base); - } - Object typ = getClassNode.execute(inliningTarget, base); - if (isSubType(frame, winner, typ)) { - continue; - } else if (isSubType(frame, typ, winner)) { - winner = typ; - continue; - } - throw raise(TypeError, ErrorMessages.METACLASS_CONFLICT); - } - return winner; - } - - protected boolean isSubType(VirtualFrame frame, Object subclass, Object superclass) { - if (isSubtypeNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - isSubtypeNode = insert(IsSubtypeNode.create()); - } - return isSubtypeNode.execute(frame, subclass, superclass); - } - - @NeverDefault - public static TypeNode create() { - return BuiltinConstructorsFactory.TypeNodeFactory.create(); - } - - @Specialization(guards = {"!isNoValue(bases)", "!isNoValue(dict)"}) - Object typeGeneric(VirtualFrame frame, Object cls, Object name, Object bases, Object dict, PKeyword[] kwds, - @Bind("this") Node inliningTarget, - @Cached TypeNode nextTypeNode, - @Exclusive @Cached IsTypeNode isTypeNode) { - if (!(name instanceof TruffleString || name instanceof PString)) { - throw raise(TypeError, ErrorMessages.MUST_BE_STRINGS_NOT_P, "type() argument 1", name); - } else if (!(bases instanceof PTuple)) { - throw raise(TypeError, ErrorMessages.MUST_BE_STRINGS_NOT_P, "type() argument 2", bases); - } else if (!(dict instanceof PDict)) { - throw raise(TypeError, ErrorMessages.MUST_BE_STRINGS_NOT_P, "type() argument 3", dict); - } else if (!isTypeNode.execute(inliningTarget, cls)) { - // TODO: this is actually allowed, deal with it - throw raise(NotImplementedError, ErrorMessages.CREATING_CLASS_NON_CLS_META_CLS); - } - return nextTypeNode.execute(frame, cls, name, bases, dict, kwds); - } - - private IsAcceptableBaseNode ensureIsAcceptableBaseNode() { - if (isAcceptableBaseNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - isAcceptableBaseNode = insert(IsAcceptableBaseNode.create()); - } - return isAcceptableBaseNode; - } - } - - @Builtin(name = J_MODULE, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PythonModule, isPublic = false, doc = """ - Create a module object. - - The name must be a string; the optional doc argument can have any type.""") - @GenerateNodeFactory - public abstract static class ModuleNode extends PythonBuiltinNode { - @Specialization - @SuppressWarnings("unused") - static Object doType(PythonBuiltinClass self, Object[] varargs, PKeyword[] kwargs, - @Shared @Cached PythonObjectFactory factory) { - return factory.createPythonModule(self.getType()); - } - - @Specialization(guards = "!isPythonBuiltinClass(self)") - @SuppressWarnings("unused") - static Object doManaged(PythonManagedClass self, Object[] varargs, PKeyword[] kwargs, - @Shared @Cached PythonObjectFactory factory) { - return factory.createPythonModule(self); - } - - @Specialization - @SuppressWarnings("unused") - static Object doType(PythonBuiltinClassType self, Object[] varargs, PKeyword[] kwargs, - @Shared @Cached PythonObjectFactory factory) { - return factory.createPythonModule(self); - } - - @Specialization(guards = "isTypeNode.execute(inliningTarget, self)", limit = "1") - @SuppressWarnings("unused") - static Object doNative(PythonAbstractNativeObject self, Object[] varargs, PKeyword[] kwargs, - @Bind("this") Node inliningTarget, - @Cached IsTypeNode isTypeNode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createPythonModule(self); - } - } - - @Builtin(name = "NotImplementedType", minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.PNotImplemented, isPublic = false) - @GenerateNodeFactory - public abstract static class NotImplementedTypeNode extends PythonBuiltinNode { - @SuppressWarnings("unused") - @Specialization - public static PNotImplemented module(Object cls) { - return PNotImplemented.NOT_IMPLEMENTED; - } - } - - @Builtin(name = "ellipsis", minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.PEllipsis, isPublic = false) - @GenerateNodeFactory - public abstract static class EllipsisTypeNode extends PythonBuiltinNode { - @SuppressWarnings("unused") - @Specialization - public static PEllipsis call(Object cls) { - return PEllipsis.INSTANCE; - } - } - - @Builtin(name = "NoneType", minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.PNone, isPublic = false) - @GenerateNodeFactory - public abstract static class NoneTypeNode extends PythonBuiltinNode { - @SuppressWarnings("unused") - @Specialization - public static PNone module(Object cls) { - return PNone.NONE; - } - } - - @Builtin(name = J_DICT_KEYS, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictKeysView, isPublic = false) - @GenerateNodeFactory - public abstract static class DictKeysTypeNode extends PythonBuiltinNode { - @SuppressWarnings("unused") - @Specialization - static Object dictKeys(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, J_DICT_KEYS); - } - } - - @Builtin(name = J_DICT_KEYITERATOR, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictKeyIterator, isPublic = false) - @GenerateNodeFactory - public abstract static class DictKeysIteratorTypeNode extends PythonBuiltinNode { - @SuppressWarnings("unused") - @Specialization - static Object dictKeys(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, J_DICT_KEYITERATOR); - } - } - - @Builtin(name = J_DICT_VALUES, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictValuesView, isPublic = false) - @GenerateNodeFactory - public abstract static class DictValuesTypeNode extends PythonBuiltinNode { - @SuppressWarnings("unused") - @Specialization - static Object dictKeys(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, J_DICT_VALUES); - } - } - - @Builtin(name = J_DICT_VALUEITERATOR, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictValueIterator, isPublic = false) - @GenerateNodeFactory - public abstract static class DictValuesIteratorTypeNode extends PythonBuiltinNode { - @SuppressWarnings("unused") - @Specialization - static Object dictKeys(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, J_DICT_VALUEITERATOR); - } - } - - @Builtin(name = J_DICT_ITEMS, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictItemsView, isPublic = false) - @GenerateNodeFactory - public abstract static class DictItemsTypeNode extends PythonBuiltinNode { - @SuppressWarnings("unused") - @Specialization - static Object dictKeys(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, J_DICT_ITEMS); - } - } - - @Builtin(name = J_DICT_ITEMITERATOR, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDictItemIterator, isPublic = false) - @GenerateNodeFactory - public abstract static class DictItemsIteratorTypeNode extends PythonBuiltinNode { - @SuppressWarnings("unused") - @Specialization - static Object dictKeys(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, J_DICT_ITEMITERATOR); - } - } - - @Builtin(name = "iterator", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PIterator, isPublic = false) - @GenerateNodeFactory - public abstract static class IteratorTypeNode extends PythonBuiltinNode { - @SuppressWarnings("unused") - @Specialization - static Object iterator(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "iterator"); - } - } - - @Builtin(name = "arrayiterator", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PArrayIterator, isPublic = false) - @GenerateNodeFactory - public abstract static class ArrayIteratorTypeNode extends PythonBuiltinNode { - @SuppressWarnings("unused") - @Specialization - static Object iterator(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "arrayiterator"); - } - } - - @Builtin(name = "callable_iterator", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PSentinelIterator, isPublic = false) - @GenerateNodeFactory - public abstract static class CallableIteratorTypeNode extends PythonBuiltinNode { - @SuppressWarnings("unused") - @Specialization - static Object iterator(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "callable_iterator"); - } - } - - @Builtin(name = "generator", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PGenerator, isPublic = false) - @GenerateNodeFactory - public abstract static class GeneratorTypeNode extends PythonBuiltinNode { - @SuppressWarnings("unused") - @Specialization - static Object generator(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "generator"); - } - } - - @Builtin(name = "method", minNumOfPositionalArgs = 3, constructsClass = PythonBuiltinClassType.PMethod, isPublic = false, doc = "Create a bound instance method object.") - @GenerateNodeFactory - public abstract static class MethodTypeNode extends PythonTernaryBuiltinNode { - @Specialization - static Object method(Object cls, PFunction func, Object self, - @Shared @Cached PythonObjectFactory factory) { - return factory.createMethod(cls, self, func); - } - - @Specialization - static Object methodBuiltin(@SuppressWarnings("unused") Object cls, PBuiltinFunction func, Object self, - @Shared @Cached PythonObjectFactory factory) { - return factory.createMethod(self, func); - } - - @Specialization - static Object methodGeneric(@SuppressWarnings("unused") Object cls, Object func, Object self, - @Bind("this") Node inliningTarget, - @Cached PyCallableCheckNode callableCheck, - @Shared @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (callableCheck.execute(inliningTarget, func)) { - return factory.createMethod(self, func); - } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.FIRST_ARG_MUST_BE_CALLABLE_S, ""); - } - } - } - - @Builtin(name = "builtin_function_or_method", minNumOfPositionalArgs = 3, constructsClass = PythonBuiltinClassType.PBuiltinFunctionOrMethod, isPublic = false) - @GenerateNodeFactory - public abstract static class BuiltinMethodTypeNode extends PythonBuiltinNode { - @Specialization - Object method(Object cls, Object self, PBuiltinFunction func, - @Cached PythonObjectFactory factory) { - return factory.createBuiltinMethod(cls, self, func); - } - } - - @Builtin(name = "frame", constructsClass = PythonBuiltinClassType.PFrame, isPublic = false) - @GenerateNodeFactory - public abstract static class FrameTypeNode extends PythonBuiltinNode { - @Specialization - static Object call( - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(RuntimeError, ErrorMessages.CANNOT_CALL_CTOR_OF, "frame type"); - } - } - - @Builtin(name = "TracebackType", constructsClass = PythonBuiltinClassType.PTraceback, isPublic = false, minNumOfPositionalArgs = 5, parameterNames = {"$cls", "tb_next", "tb_frame", "tb_lasti", - "tb_lineno"}) - @ArgumentClinic(name = "tb_lasti", conversion = ArgumentClinic.ClinicConversion.Index) - @ArgumentClinic(name = "tb_lineno", conversion = ArgumentClinic.ClinicConversion.Index) - @GenerateNodeFactory - public abstract static class TracebackTypeNode extends PythonClinicBuiltinNode { - @Specialization - static Object createTraceback(@SuppressWarnings("unused") Object cls, PTraceback next, PFrame pframe, int lasti, int lineno, - @Shared @Cached PythonObjectFactory factory) { - return factory.createTracebackWithLasti(pframe, lineno, lasti, next); - } - - @Specialization - static Object createTraceback(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") PNone next, PFrame pframe, int lasti, int lineno, - @Shared @Cached PythonObjectFactory factory) { - return factory.createTracebackWithLasti(pframe, lineno, lasti, null); - } - - @Specialization(guards = {"!isPTraceback(next)", "!isNone(next)"}) - @SuppressWarnings("unused") - static Object errorNext(Object cls, Object next, Object frame, Object lasti, Object lineno, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.EXPECTED_TRACEBACK_OBJ_OR_NONE, next); - } - - @Specialization(guards = "!isPFrame(frame)") - @SuppressWarnings("unused") - static Object errorFrame(Object cls, Object next, Object frame, Object lasti, Object lineno, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.TRACEBACK_TYPE_ARG_MUST_BE_FRAME, frame); - } - - protected static boolean isPFrame(Object obj) { - return obj instanceof PFrame; - } - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return BuiltinConstructorsClinicProviders.TracebackTypeNodeClinicProviderGen.INSTANCE; - } - } - - @Builtin(name = "code", constructsClass = PythonBuiltinClassType.PCode, isPublic = false, minNumOfPositionalArgs = 16, numOfPositionalOnlyArgs = 18, parameterNames = { - "$cls", "argcount", "posonlyargcount", "kwonlyargcount", "nlocals", "stacksize", "flags", "codestring", - "constants", "names", "varnames", "filename", "name", "qualname", "firstlineno", - "linetable", "exceptiontable", "freevars", "cellvars"}) - @ArgumentClinic(name = "argcount", conversion = ArgumentClinic.ClinicConversion.Int) - @ArgumentClinic(name = "posonlyargcount", conversion = ArgumentClinic.ClinicConversion.Int) - @ArgumentClinic(name = "kwonlyargcount", conversion = ArgumentClinic.ClinicConversion.Int) - @ArgumentClinic(name = "nlocals", conversion = ArgumentClinic.ClinicConversion.Int) - @ArgumentClinic(name = "stacksize", conversion = ArgumentClinic.ClinicConversion.Int) - @ArgumentClinic(name = "flags", conversion = ArgumentClinic.ClinicConversion.Int) - @ArgumentClinic(name = "filename", conversion = ArgumentClinic.ClinicConversion.TString) - @ArgumentClinic(name = "name", conversion = ArgumentClinic.ClinicConversion.TString) - @ArgumentClinic(name = "qualname", conversion = ArgumentClinic.ClinicConversion.TString) - @ArgumentClinic(name = "firstlineno", conversion = ArgumentClinic.ClinicConversion.Int) - @GenerateNodeFactory - public abstract static class CodeConstructorNode extends PythonClinicBuiltinNode { - @Specialization - static PCode call(VirtualFrame frame, @SuppressWarnings("unused") Object cls, int argcount, - int posonlyargcount, int kwonlyargcount, - int nlocals, int stacksize, int flags, - PBytes codestring, PTuple constants, PTuple names, PTuple varnames, - TruffleString filename, TruffleString name, TruffleString qualname, - int firstlineno, PBytes linetable, @SuppressWarnings("unused") PBytes exceptiontable, - PTuple freevars, PTuple cellvars, - @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Cached CodeNodes.CreateCodeNode createCodeNode, - @Cached GetObjectArrayNode getObjectArrayNode, - @Cached CastToTruffleStringNode castToTruffleStringNode) { - byte[] codeBytes = bufferLib.getCopiedByteArray(codestring); - byte[] linetableBytes = bufferLib.getCopiedByteArray(linetable); - - Object[] constantsArr = getObjectArrayNode.execute(inliningTarget, constants); - TruffleString[] namesArr = objectArrayToTruffleStringArray(inliningTarget, getObjectArrayNode.execute(inliningTarget, names), castToTruffleStringNode); - TruffleString[] varnamesArr = objectArrayToTruffleStringArray(inliningTarget, getObjectArrayNode.execute(inliningTarget, varnames), castToTruffleStringNode); - TruffleString[] freevarsArr = objectArrayToTruffleStringArray(inliningTarget, getObjectArrayNode.execute(inliningTarget, freevars), castToTruffleStringNode); - TruffleString[] cellcarsArr = objectArrayToTruffleStringArray(inliningTarget, getObjectArrayNode.execute(inliningTarget, cellvars), castToTruffleStringNode); - - return createCodeNode.execute(frame, argcount, posonlyargcount, kwonlyargcount, - nlocals, stacksize, flags, - codeBytes, constantsArr, namesArr, - varnamesArr, freevarsArr, cellcarsArr, - filename, name, qualname, - firstlineno, linetableBytes); - } - - @Fallback - @SuppressWarnings("unused") - static PCode call(Object cls, Object argcount, Object kwonlyargcount, Object posonlyargcount, - Object nlocals, Object stacksize, Object flags, - Object codestring, Object constants, Object names, Object varnames, - Object filename, Object name, Object qualname, - Object firstlineno, Object linetable, Object exceptiontable, - Object freevars, Object cellvars, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.INVALID_ARGS, "code"); - } - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return BuiltinConstructorsClinicProviders.CodeConstructorNodeClinicProviderGen.INSTANCE; - } - } - - @Builtin(name = "cell", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PCell, isPublic = false) - @GenerateNodeFactory - public abstract static class CellTypeNode extends PythonBinaryBuiltinNode { - @CompilationFinal private Assumption sharedAssumption; - - private Assumption getAssumption() { - if (sharedAssumption == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - sharedAssumption = Truffle.getRuntime().createAssumption("cell is effectively final"); - } - if (CompilerDirectives.inCompiledCode()) { - return sharedAssumption; - } else { - return Truffle.getRuntime().createAssumption("cell is effectively final"); - } - } - - @Specialization - Object newCell(@SuppressWarnings("unused") Object cls, Object contents, - @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, - @Cached InlinedConditionProfile nonEmptyProfile) { - Assumption assumption = getAssumption(); - PCell cell = factory.createCell(assumption); - if (nonEmptyProfile.profile(inliningTarget, !isNoValue(contents))) { - cell.setRef(contents, assumption); - } - return cell; - } - } - - @Builtin(name = "BaseException", constructsClass = PythonBuiltinClassType.PBaseException, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, doc = "Common base class for all exceptions") - @GenerateNodeFactory - public abstract static class BaseExceptionNode extends PythonVarargsBuiltinNode { - @Override - public final Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported { - if (arguments.length == 0) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw VarargsBuiltinDirectInvocationNotSupported.INSTANCE; - } - if (arguments.length == 1) { - return execute(frame, arguments[0], PythonUtils.EMPTY_OBJECT_ARRAY, keywords); - } - Object[] argsWithoutSelf = PythonUtils.arrayCopyOfRange(arguments, 1, arguments.length); - return execute(frame, arguments[0], argsWithoutSelf, keywords); - } - - @Specialization(guards = "!needsNativeAllocationNode.execute(inliningTarget, cls)", limit = "1") - static Object doManaged(Object cls, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") PKeyword[] kwargs, - @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, - @Shared @Cached PythonObjectFactory factory, - @Cached InlinedConditionProfile argsProfile) { - PTuple argsTuple; - if (argsProfile.profile(inliningTarget, args.length == 0)) { - argsTuple = null; - } else { - argsTuple = factory.createTuple(args); - } - return factory.createBaseException(cls, null, argsTuple); - } - - @Specialization(guards = "needsNativeAllocationNode.execute(inliningTarget, cls)", limit = "1") - static Object doNativeSubtype(Object cls, Object[] args, @SuppressWarnings("unused") PKeyword[] kwargs, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, - @Shared @Cached PythonObjectFactory factory, - @Cached PCallCapiFunction callCapiFunction, - @Cached PythonToNativeNode toNativeNode, - @Cached NativeToPythonTransferNode toPythonNode, - @Cached ExternalFunctionNodes.DefaultCheckFunctionResultNode checkFunctionResultNode) { - Object argsTuple = args.length > 0 ? factory.createTuple(args) : factory.createEmptyTuple(); - Object nativeResult = callCapiFunction.call(NativeCAPISymbol.FUN_EXCEPTION_SUBTYPE_NEW, toNativeNode.execute(cls), toNativeNode.execute(argsTuple)); - return toPythonNode.execute(checkFunctionResultNode.execute(PythonContext.get(inliningTarget), NativeCAPISymbol.FUN_EXCEPTION_SUBTYPE_NEW.getTsName(), nativeResult)); - } - } - - @Builtin(name = "BaseExceptionGroup", constructsClass = PythonBuiltinClassType.PBaseExceptionGroup, minNumOfPositionalArgs = 3, doc = "A combination of multiple unrelated exceptions.") - @GenerateNodeFactory - public abstract static class BaseExceptionGroupNode extends PythonTernaryBuiltinNode { - - @Specialization - static Object doManaged(VirtualFrame frame, Object cls, Object messageObj, Object exceptionsObj, - @Bind("this") Node inliningTarget, - @Cached CastToTruffleStringNode castToStringNode, - @Cached PythonObjectFactory factory, - @Cached PySequenceCheckNode sequenceCheckNode, - @Cached TupleNodes.ConstructTupleNode toTupleNode, - @Cached SequenceStorageNodes.ToArrayNode toArrayNode, - @Cached PyObjectGetAttr getAttr, - @Cached InlinedLoopConditionProfile loopConditionProfile, - @Cached GetClassNode getClassNode, - @Cached BuiltinClassProfiles.IsBuiltinClassProfile exceptionProfile, - @Cached BuiltinClassProfiles.IsBuiltinClassProfile baseExceptionProfile, - @Cached TypeNodes.IsSameTypeNode isSameTypeNode, - @Cached PRaiseNode.Lazy raiseNode) { - TruffleString message; - try { - message = castToStringNode.execute(inliningTarget, messageObj); - } catch (CannotCastException ex) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "BaseExceptionGroup", 1, "str", messageObj); - } - if (!sequenceCheckNode.execute(inliningTarget, exceptionsObj)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.SECOND_ARGUMENT_EXCEPTIONS_MUST_BE_A_SEQUENCE); - } - PTuple exceptionsTuple = toTupleNode.execute(frame, exceptionsObj); - Object[] exceptions = toArrayNode.execute(inliningTarget, exceptionsTuple.getSequenceStorage()); - if (exceptions.length == 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.SECOND_ARGUMENT_EXCEPTIONS_MUST_BE_A_NON_EMPTY_SEQUENCE); - } - PythonContext context = PythonContext.get(inliningTarget); - Object exceptionGroupType = getAttr.execute(inliningTarget, context.getBuiltins(), T_EXCEPTION_GROUP); - boolean nestedBaseExceptions = false; - loopConditionProfile.profileCounted(inliningTarget, exceptions.length); - for (int i = 0; loopConditionProfile.inject(inliningTarget, i < exceptions.length); i++) { - Object exceptionType = getClassNode.execute(inliningTarget, exceptions[i]); - if (exceptionProfile.profileClass(inliningTarget, exceptionType, PythonBuiltinClassType.Exception)) { - continue; - } - if (baseExceptionProfile.profileClass(inliningTarget, exceptionType, PythonBuiltinClassType.PBaseException)) { - nestedBaseExceptions = true; - } else { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.ITEM_D_OF_SECOND_ARGUMENT_EXCEPTIONS_IS_NOT_AN_EXCEPTION, i); - } - } - if (isSameTypeNode.execute(inliningTarget, cls, PythonBuiltinClassType.PBaseExceptionGroup)) { - if (!nestedBaseExceptions) { - /* - * All nested exceptions are Exception subclasses, wrap them in an - * ExceptionGroup - */ - cls = exceptionGroupType; - } - } else if (isSameTypeNode.execute(inliningTarget, cls, exceptionGroupType)) { - if (nestedBaseExceptions) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANNOT_NEST_BASE_EXCEPTIONS_IN_AN_EXCEPTION_GROUP); - } - } else { - /* user-defined subclass */ - if (nestedBaseExceptions && exceptionProfile.profileClass(inliningTarget, cls, PythonBuiltinClassType.Exception)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANNOT_NEST_BASE_EXCEPTIONS_IN_N, cls); - } - } - return factory.createBaseExceptionGroup(cls, message, exceptions, new Object[]{messageObj, exceptionsObj}); - } - } - - @Builtin(name = "mappingproxy", constructsClass = PythonBuiltinClassType.PMappingproxy, isPublic = false, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class MappingproxyNode extends PythonBinaryBuiltinNode { - @Specialization(guards = "!isNoValue(obj)") - static Object doMapping(Object klass, Object obj, - @Bind("this") Node inliningTarget, - @Cached PyMappingCheckNode mappingCheckNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - // descrobject.c mappingproxy_check_mapping() - if (!(obj instanceof PList || obj instanceof PTuple) && mappingCheckNode.execute(inliningTarget, obj)) { - return factory.createMappingproxy(klass, obj); - } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_ARG_MUST_BE_S_NOT_P, "mappingproxy()", "mapping", obj); - } - - @Specialization(guards = "isNoValue(none)") - @SuppressWarnings("unused") - static Object doMissing(Object klass, PNone none, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.MISSING_D_REQUIRED_S_ARGUMENT_S_POS, "mappingproxy()", "mapping", 1); - } - } - - abstract static class DescriptorNode extends PythonBuiltinNode { - @TruffleBoundary - protected final void denyInstantiationAfterInitialization(TruffleString name) { - if (getContext().isCoreInitialized()) { - throw PRaiseNode.raiseUncached(this, TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, name); - } - } - - protected static Object ensure(Object value) { - return value == PNone.NO_VALUE ? null : value; - } - } - - @Builtin(name = J_GETSET_DESCRIPTOR, constructsClass = PythonBuiltinClassType.GetSetDescriptor, isPublic = false, minNumOfPositionalArgs = 1, // - parameterNames = {"cls", "fget", "fset", "name", "owner"}) - @GenerateNodeFactory - public abstract static class GetSetDescriptorNode extends DescriptorNode { - @Specialization(guards = "isPythonClass(owner)") - @TruffleBoundary - Object call(@SuppressWarnings("unused") Object clazz, Object get, Object set, TruffleString name, Object owner) { - denyInstantiationAfterInitialization(T_GETSET_DESCRIPTOR); - return PythonObjectFactory.getUncached().createGetSetDescriptor(ensure(get), ensure(set), name, owner); - } - } - - @Builtin(name = J_MEMBER_DESCRIPTOR, constructsClass = PythonBuiltinClassType.MemberDescriptor, isPublic = false, minNumOfPositionalArgs = 1, // - parameterNames = {"cls", "fget", "fset", "name", "owner"}) - @GenerateNodeFactory - public abstract static class MemberDescriptorNode extends DescriptorNode { - @Specialization(guards = "isPythonClass(owner)") - @TruffleBoundary - Object doGeneric(@SuppressWarnings("unused") Object clazz, Object get, Object set, TruffleString name, Object owner) { - denyInstantiationAfterInitialization(T_MEMBER_DESCRIPTOR); - return PythonObjectFactory.getUncached().createGetSetDescriptor(ensure(get), ensure(set), name, owner); - } - } - - @Builtin(name = J_WRAPPER_DESCRIPTOR, constructsClass = PythonBuiltinClassType.WrapperDescriptor, isPublic = false, minNumOfPositionalArgs = 1, // - parameterNames = {"cls", "fget", "fset", "name", "owner"}) - @GenerateNodeFactory - public abstract static class WrapperDescriptorNode extends DescriptorNode { - @Specialization(guards = "isPythonClass(owner)") - @TruffleBoundary - Object doGeneric(@SuppressWarnings("unused") Object clazz, Object get, Object set, TruffleString name, Object owner) { - denyInstantiationAfterInitialization(T_WRAPPER_DESCRIPTOR); - return PythonObjectFactory.getUncached().createGetSetDescriptor(ensure(get), ensure(set), name, owner); - } - } - - // slice(stop) - // slice(start, stop[, step]) - @Builtin(name = "slice", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 4, constructsClass = PythonBuiltinClassType.PSlice, doc = """ - slice(stop) - slice(start, stop[, step]) - - Create a slice object. This is used for extended slicing (e.g. a[0:10:2]).""") - @GenerateNodeFactory - abstract static class SliceNode extends PythonQuaternaryBuiltinNode { - @Specialization(guards = {"isNoValue(second)"}) - @SuppressWarnings("unused") - static Object singleArg(Object cls, Object first, Object second, Object third, - @Bind("this") Node inliningTarget, - @Shared @Cached PySliceNew sliceNode) { - return sliceNode.execute(inliningTarget, PNone.NONE, first, PNone.NONE); - } - - @Specialization(guards = {"!isNoValue(stop)", "isNoValue(step)"}) - @SuppressWarnings("unused") - static Object twoArgs(Object cls, Object start, Object stop, Object step, - @Bind("this") Node inliningTarget, - @Shared @Cached PySliceNew sliceNode) { - return sliceNode.execute(inliningTarget, start, stop, PNone.NONE); - } - - @Fallback - static Object threeArgs(@SuppressWarnings("unused") Object cls, Object start, Object stop, Object step, - @Bind("this") Node inliningTarget, - @Shared @Cached PySliceNew sliceNode) { - return sliceNode.execute(inliningTarget, start, stop, step); - } - } - - // memoryview(obj) - @Builtin(name = J_MEMORYVIEW, minNumOfPositionalArgs = 2, parameterNames = {"$cls", "object"}, constructsClass = PythonBuiltinClassType.PMemoryView, // - doc = "Create a new memoryview object which references the given object.") - @GenerateNodeFactory - public abstract static class MemoryViewNode extends PythonBuiltinNode { - - public abstract PMemoryView execute(VirtualFrame frame, Object cls, Object object); - - public final PMemoryView execute(VirtualFrame frame, Object object) { - return execute(frame, PythonBuiltinClassType.PMemoryView, object); - } - - @Specialization - PMemoryView fromObject(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object object, - @Cached PyMemoryViewFromObject memoryViewFromObject) { - return memoryViewFromObject.execute(frame, object); - } - - @NeverDefault - public static MemoryViewNode create() { - return BuiltinConstructorsFactory.MemoryViewNodeFactory.create(null); - } - } - - // super() - @Builtin(name = J_SUPER, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 3, constructsClass = PythonBuiltinClassType.Super, doc = """ - super() -> same as super(__class__, ) - super(type) -> unbound super object - super(type, obj) -> bound super object; requires isinstance(obj, type) - super(type, type2) -> bound super object; requires issubclass(type2, type) - Typical use to call a cooperative superclass method: - class C(B): - def meth(self, arg): - super().meth(arg) - This works for class methods too: - class C(B): - @classmethod - def cmeth(cls, arg): - super().cmeth(arg)""") - @GenerateNodeFactory - public abstract static class SuperInitNode extends PythonTernaryBuiltinNode { - @Specialization - static Object doObjectIndirect(Object self, @SuppressWarnings("unused") Object type, @SuppressWarnings("unused") Object object, - @Cached PythonObjectFactory factory) { - return factory.createSuperObject(self); - } - } - - @Builtin(name = J_CLASSMETHOD, minNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PClassmethod, doc = """ - classmethod(function) -> method - - Convert a function to be a class method. - - A class method receives the class as implicit first argument, - just like an instance method receives the instance. - To declare a class method, use this idiom: - - class C: - @classmethod - def f(cls, arg1, arg2, argN): - ... - - It can be called either on the class (e.g. C.f()) or on an instance - (e.g. C().f()). The instance is ignored except for its class. - If a class method is called for a derived class, the derived class - object is passed as the implied first argument. - - Class methods are different than C++ or Java static methods. - If you want those, see the staticmethod builtin.""") - @GenerateNodeFactory - public abstract static class ClassmethodNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doObjectIndirect(Object self, @SuppressWarnings("unused") Object callable, - @Cached PythonObjectFactory factory) { - return factory.createClassmethod(self); - } - } - - @Builtin(name = J_INSTANCEMETHOD, minNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PInstancemethod, isPublic = false, doc = "instancemethod(function)\n\nBind a function to a class.") - @GenerateNodeFactory - public abstract static class InstancemethodNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doObjectIndirect(Object self, @SuppressWarnings("unused") Object callable, - @Cached PythonObjectFactory factory) { - return factory.createInstancemethod(self); - } - } - - @Builtin(name = J_STATICMETHOD, minNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PStaticmethod, doc = """ - staticmethod(function) -> method - - Convert a function to be a static method. - - A static method does not receive an implicit first argument. - To declare a static method, use this idiom: - - class C: - @staticmethod - def f(arg1, arg2, argN): - ... - - It can be called either on the class (e.g. C.f()) or on an instance - (e.g. C().f()). Both the class and the instance are ignored, and - neither is passed implicitly as the first argument to the method. - - Static methods in Python are similar to those found in Java or C++. - For a more advanced concept, see the classmethod builtin.""") - @GenerateNodeFactory - public abstract static class StaticmethodNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doObjectIndirect(Object self, @SuppressWarnings("unused") Object callable, - @Cached PythonObjectFactory factory) { - return factory.createStaticmethod(self); - } - } - - @Builtin(name = J_MAP, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PMap, doc = """ - map(func, *iterables) --> map object - - Make an iterator that computes the function using arguments from - each of the iterables. Stops when the shortest iterable is exhausted.""") - @GenerateNodeFactory - public abstract static class MapNode extends PythonVarargsBuiltinNode { - @Specialization - static PMap doit(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode, - @Cached InlinedLoopConditionProfile loopProfile, - @Cached PyObjectGetIter getIter, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "map()"); - } - if (args.length < 2) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MAP_MUST_HAVE_AT_LEAST_TWO_ARGUMENTS); - } - PMap map = factory.createMap(cls); - map.setFunction(args[0]); - Object[] iterators = new Object[args.length - 1]; - loopProfile.profileCounted(inliningTarget, iterators.length); - for (int i = 0; loopProfile.inject(inliningTarget, i < iterators.length); i++) { - iterators[i] = getIter.execute(frame, inliningTarget, args[i + 1]); - } - map.setIterators(iterators); - return map; - } - } - - @Builtin(name = J_PROPERTY, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PProperty, doc = """ - Property attribute. - - fget - function to be used for getting an attribute value - fset - function to be used for setting an attribute value - fdel - function to be used for del'ing an attribute - doc - docstring - - Typical use is to define a managed attribute x: - - class C(object): - def getx(self): return self._x - def setx(self, value): self._x = value - def delx(self): del self._x - x = property(getx, setx, delx, "I'm the 'x' property.") - - Decorators make defining new properties or modifying existing ones easy: - - class C(object): - @property - def x(self): - "I am the 'x' property." - return self._x - @x.setter - def x(self, value): - self._x = value - @x.deleter - def x(self): - del self._x""") - @GenerateNodeFactory - public abstract static class PropertyNode extends PythonVarargsBuiltinNode { - @Specialization - static PProperty doit(Object self, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") PKeyword[] keywords, - @Cached PythonObjectFactory factory) { - return factory.createProperty(self); - } - } - - @Builtin(name = "SimpleNamespace", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, isPublic = false, constructsClass = PythonBuiltinClassType.PSimpleNamespace, doc = "A simple attribute-based namespace.\n" + - "\n" + - "SimpleNamespace(**kwargs)") - @GenerateNodeFactory - public abstract static class SimpleNamespaceNode extends PythonVarargsBuiltinNode { - @Specialization - static PSimpleNamespace doit(Object self, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") PKeyword[] keywords, - @Cached PythonObjectFactory factory) { - return factory.createSimpleNamespace(self); - } - } - - @Builtin(name = "GenericAlias", minNumOfPositionalArgs = 3, constructsClass = PythonBuiltinClassType.PGenericAlias) - @GenerateNodeFactory - abstract static class GenericAliasNode extends PythonTernaryBuiltinNode { - @Specialization - static PGenericAlias doit(Object cls, Object origin, Object arguments, - @Cached PythonObjectFactory factory) { - return factory.createGenericAlias(cls, origin, arguments, false); - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java index 45dcd1c6a2..4eb603c884 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java @@ -27,12 +27,12 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.DeprecationWarning; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.RuntimeError; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.StopIteration; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SyntaxError; import static com.oracle.graal.python.builtins.modules.io.IONodes.T_FLUSH; import static com.oracle.graal.python.builtins.modules.io.IONodes.T_WRITE; import static com.oracle.graal.python.builtins.objects.PNone.NONE; import static com.oracle.graal.python.builtins.objects.PNone.NO_VALUE; -import static com.oracle.graal.python.builtins.objects.PNotImplemented.NOT_IMPLEMENTED; import static com.oracle.graal.python.compiler.RaisePythonExceptionErrorCallback.raiseSyntaxError; import static com.oracle.graal.python.nodes.BuiltinNames.J_ABS; import static com.oracle.graal.python.nodes.BuiltinNames.J_ALL; @@ -75,6 +75,7 @@ import static com.oracle.graal.python.nodes.BuiltinNames.T_BREAKPOINTHOOK; import static com.oracle.graal.python.nodes.BuiltinNames.T_EVAL; import static com.oracle.graal.python.nodes.BuiltinNames.T_EXEC; +import static com.oracle.graal.python.nodes.BuiltinNames.T_NOT_IMPLEMENTED; import static com.oracle.graal.python.nodes.BuiltinNames.T_STDOUT; import static com.oracle.graal.python.nodes.BuiltinNames.T_SYS; import static com.oracle.graal.python.nodes.BuiltinNames.T___BUILTINS__; @@ -84,7 +85,6 @@ import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DICT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___FORMAT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MRO_ENTRIES__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEXT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ROUND__; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; import static com.oracle.graal.python.nodes.StringLiterals.T_FALSE; @@ -109,6 +109,7 @@ import java.util.Arrays; import java.util.EnumSet; import java.util.List; +import java.util.logging.Level; import com.oracle.graal.python.PythonFileDetector; import com.oracle.graal.python.PythonLanguage; @@ -123,6 +124,7 @@ import com.oracle.graal.python.builtins.modules.io.IOModuleBuiltins; import com.oracle.graal.python.builtins.modules.io.IONodes; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.PByteArray; @@ -142,35 +144,43 @@ import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetObjectArrayNode; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.dict.PDict; +import com.oracle.graal.python.builtins.objects.ellipsis.EllipsisBuiltins; +import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis; import com.oracle.graal.python.builtins.objects.frame.PFrame; import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.function.PFunction; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.ints.PInt; +import com.oracle.graal.python.builtins.objects.iterator.PDoubleSequenceIterator; +import com.oracle.graal.python.builtins.objects.iterator.PIntegerSequenceIterator; +import com.oracle.graal.python.builtins.objects.iterator.PLongSequenceIterator; import com.oracle.graal.python.builtins.objects.list.ListBuiltins; import com.oracle.graal.python.builtins.objects.list.ListBuiltins.ListSortNode; import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.object.ObjectNodes; -import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.builtins.objects.type.TypeBuiltins; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotUnaryFunc.CallSlotUnaryNode; import com.oracle.graal.python.compiler.Compiler; import com.oracle.graal.python.compiler.RaisePythonExceptionErrorCallback; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyCallableCheckNode; import com.oracle.graal.python.lib.PyEvalGetGlobals; import com.oracle.graal.python.lib.PyEvalGetLocals; +import com.oracle.graal.python.lib.PyIterCheckNode; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyMappingCheckNode; import com.oracle.graal.python.lib.PyNumberAbsoluteNode; import com.oracle.graal.python.lib.PyNumberAddNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyNumberDivmodNode; import com.oracle.graal.python.lib.PyNumberIndexNode; +import com.oracle.graal.python.lib.PyNumberPowerNode; import com.oracle.graal.python.lib.PyObjectAsciiNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.lib.PyObjectDir; @@ -182,12 +192,14 @@ import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectLookupAttrO; import com.oracle.graal.python.lib.PyObjectReprAsObjectNode; +import com.oracle.graal.python.lib.PyObjectRichCompareBool; import com.oracle.graal.python.lib.PyObjectSetAttrO; import com.oracle.graal.python.lib.PyObjectSetItem; import com.oracle.graal.python.lib.PyObjectSizeNode; import com.oracle.graal.python.lib.PyObjectStrAsObjectNode; import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode; import com.oracle.graal.python.lib.PyUnicodeFSDecoderNode; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.BuiltinNames; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; @@ -198,27 +210,20 @@ import com.oracle.graal.python.nodes.SpecialMethodNames; import com.oracle.graal.python.nodes.StringLiterals; import com.oracle.graal.python.nodes.argument.ReadArgumentNode; -import com.oracle.graal.python.nodes.attributes.DeleteAttributeNode; import com.oracle.graal.python.nodes.attributes.GetAttributeNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; import com.oracle.graal.python.nodes.builtins.ListNodes; import com.oracle.graal.python.nodes.builtins.ListNodes.ConstructListNode; import com.oracle.graal.python.nodes.bytecode.GetAIterNode; import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode; -import com.oracle.graal.python.nodes.call.CallDispatchNode; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode; +import com.oracle.graal.python.nodes.call.CallDispatchers; import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.call.GenericInvokeNode; import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode; import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallTernaryNode; import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; +import com.oracle.graal.python.nodes.call.special.SpecialMethodNotFound; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; -import com.oracle.graal.python.nodes.expression.BinaryArithmetic; -import com.oracle.graal.python.nodes.expression.BinaryComparisonNode; -import com.oracle.graal.python.nodes.expression.BinaryOpNode; -import com.oracle.graal.python.nodes.expression.TernaryArithmetic; import com.oracle.graal.python.nodes.frame.GetFrameLocalsNode; import com.oracle.graal.python.nodes.frame.ReadCallerFrameNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; @@ -230,10 +235,11 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; +import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassExactProfile; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaLongExactNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; @@ -250,11 +256,12 @@ import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.BoolSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.IntSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.CharsetMapping; +import com.oracle.graal.python.util.OverflowException; import com.oracle.graal.python.util.PythonUtils; import com.oracle.graal.python.util.Supplier; import com.oracle.truffle.api.CallTarget; @@ -265,6 +272,7 @@ import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.TruffleLanguage.Env; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.debug.Debugger; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -290,7 +298,6 @@ import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.nodes.UnexpectedResultException; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.profiles.InlinedConditionProfile; @@ -300,7 +307,6 @@ import com.oracle.truffle.api.strings.TruffleString; import com.oracle.truffle.api.strings.TruffleString.Encoding; import com.oracle.truffle.api.strings.TruffleStringBuilder; -import com.oracle.truffle.api.utilities.TriState; @CoreFunctions(defineModule = J_BUILTINS, isEager = true) public final class BuiltinFunctions extends PythonBuiltins { @@ -316,6 +322,8 @@ public void initialize(Python3Core core) { addBuiltinConstant(T_NONE, PNone.NONE); addBuiltinConstant(T_FALSE, false); addBuiltinConstant(T_TRUE, true); + addBuiltinConstant(T_NOT_IMPLEMENTED, PNotImplemented.NOT_IMPLEMENTED); + addBuiltinConstant(EllipsisBuiltins.T_ELLIPSIS, PEllipsis.INSTANCE); super.initialize(core); } @@ -334,7 +342,7 @@ public abstract static class AbsNode extends PythonUnaryBuiltinNode { @Specialization static Object absObject(VirtualFrame frame, Object object, @Cached PyNumberAbsoluteNode absoluteNode) { - return absoluteNode.executeCached(frame, object); + return absoluteNode.execute(frame, object); } } @@ -473,21 +481,19 @@ static boolean doHashColl(VirtualFrame frame, PHashingCollection object, static boolean doObject(VirtualFrame frame, Object object, @Bind("this") Node inliningTarget, @Cached PyObjectGetIter getIter, - @Cached GetNextNode nextNode, - @Cached IsBuiltinObjectProfile errorProfile, + @Cached PyIterNextNode nextNode, @Cached PyObjectIsTrueNode isTrueNode) { Object iterator = getIter.execute(frame, inliningTarget, object); int nbrIter = 0; while (true) { try { - Object next = nextNode.execute(frame, iterator); + Object next = nextNode.execute(frame, inliningTarget, iterator); nbrIter++; if (!isTrueNode.execute(frame, next)) { return false; } - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); + } catch (IteratorExhausted e) { break; } finally { LoopNode.reportLoopCount(inliningTarget, nbrIter); @@ -526,21 +532,19 @@ static boolean doHashColl(VirtualFrame frame, PHashingCollection object, static boolean doObject(VirtualFrame frame, Object object, @Bind("this") Node inliningTarget, @Cached PyObjectGetIter getIter, - @Cached GetNextNode nextNode, - @Cached IsBuiltinObjectProfile errorProfile, + @Cached PyIterNextNode nextNode, @Cached PyObjectIsTrueNode isTrueNode) { Object iterator = getIter.execute(frame, inliningTarget, object); int nbrIter = 0; while (true) { try { - Object next = nextNode.execute(frame, iterator); + Object next = nextNode.execute(frame, inliningTarget, iterator); nbrIter++; if (isTrueNode.execute(frame, next)) { return true; } - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); + } catch (IteratorExhausted e) { break; } finally { LoopNode.reportLoopCount(inliningTarget, nbrIter); @@ -553,7 +557,7 @@ static boolean doObject(VirtualFrame frame, Object object, @GenerateInline @GenerateCached(false) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerTypes.class) abstract static class BinOctHexHelperNode extends Node { @FunctionalInterface @@ -594,13 +598,6 @@ static TruffleString doL(Node inliningTarget, long x, TruffleString prefix, int return buildString(x < 0, prefix, fromJavaStringNode.execute(longToString.convert(Math.abs(x)), TS_ENCODING)); } - @Specialization - @SuppressWarnings("unused") - static TruffleString doD(double x, TruffleString prefix, int radix, LongToString longToString, - @Cached(inline = false) PRaiseNode raise) { - throw raise.raiseIntegerInterpretationError(x); - } - @Specialization static TruffleString doPI(PInt x, TruffleString prefix, int radix, @SuppressWarnings("unused") LongToString longToString, @Shared @Cached(inline = false) TruffleString.FromJavaStringNode fromJavaStringNode) { @@ -608,7 +605,7 @@ static TruffleString doPI(PInt x, TruffleString prefix, int radix, @SuppressWarn return buildString(value.signum() < 0, prefix, fromJavaStringNode.execute(bigToString(radix, PInt.abs(value)), TS_ENCODING)); } - @Specialization(replaces = {"doL", "doD", "doPI"}) + @Specialization(replaces = {"doL", "doPI"}) static TruffleString doO(VirtualFrame frame, Node inliningTarget, Object x, TruffleString prefix, int radix, LongToString longToString, @Exclusive @Cached InlinedConditionProfile isMinLong, @Cached PyNumberIndexNode indexNode, @@ -629,14 +626,13 @@ static TruffleString doO(VirtualFrame frame, Node inliningTarget, Object x, Truf return doPI((PInt) index, prefix, radix, longToString, fromJavaStringNode); } else { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.NotImplementedError, toTruffleStringUncached("bin/oct/hex with native integer subclasses")); + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.NotImplementedError, toTruffleStringUncached("bin/oct/hex with native integer subclasses")); } } } // bin(object) @Builtin(name = J_BIN, minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) @GenerateNodeFactory public abstract static class BinNode extends PythonUnaryBuiltinNode { static final TruffleString T_BIN_PREFIX = tsLiteral("0b"); @@ -656,7 +652,6 @@ private static String longToString(long x) { // oct(object) @Builtin(name = J_OCT, minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) @GenerateNodeFactory public abstract static class OctNode extends PythonUnaryBuiltinNode { static final TruffleString T_OCT_PREFIX = tsLiteral("0o"); @@ -676,7 +671,6 @@ private static String longToString(long x) { // hex(object) @Builtin(name = J_HEX, minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) @GenerateNodeFactory public abstract static class HexNode extends PythonUnaryBuiltinNode { static final TruffleString T_HEX_PREFIX = tsLiteral("0x"); @@ -721,11 +715,11 @@ public abstract static class ChrNode extends PythonUnaryClinicBuiltinNode { static TruffleString charFromInt(int arg, @Bind("this") Node inliningTarget, @Cached TruffleString.FromCodePointNode fromCodePointNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (arg >= 0 && arg <= Character.MAX_CODE_POINT) { return fromCodePointNode.execute(arg, TS_ENCODING, true); } else { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.ARG_NOT_IN_RANGE, "chr()", "0x110000"); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.ARG_NOT_IN_RANGE, "chr()", "0x110000"); } } @@ -788,192 +782,116 @@ static Object doObject(VirtualFrame frame, Object a, Object b, } } - // eval(expression, globals=None, locals=None) - @Builtin(name = J_EVAL, minNumOfPositionalArgs = 1, parameterNames = {"expression", "globals", "locals"}) - @GenerateNodeFactory - public abstract static class EvalNode extends PythonBuiltinNode { - @Child protected CompileNode compileNode; - @Child private GenericInvokeNode invokeNode = GenericInvokeNode.create(); - @Child private GetOrCreateDictNode getOrCreateDictNode; - - final void assertNoFreeVars(Node inliningTarget, PCode code, PRaiseNode.Lazy raiseNode) { - Object[] freeVars = code.getFreeVars(); - if (freeVars.length > 0) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.CODE_OBJ_NO_FREE_VARIABLES, getMode()); - } - } - - protected TruffleString getMode() { - return T_EVAL; - } - - static boolean isMapping(Node inliningTarget, PyMappingCheckNode mappingCheckNode, Object object) { - return mappingCheckNode.execute(inliningTarget, object); - } - - static boolean isAnyNone(Object object) { - return object instanceof PNone; - } - - final PCode createAndCheckCode(VirtualFrame frame, Node inliningTarget, Object source, PRaiseNode.Lazy raiseNode) { - PCode code = getCompileNode().compile(frame, source, T_STRING_SOURCE, getMode(), -1, -1); - assertNoFreeVars(inliningTarget, code, raiseNode); - return code; - } - - private static void inheritGlobals(PFrame callerFrame, Object[] args) { - PArguments.setGlobals(args, callerFrame.getGlobals()); - } - - private static void inheritLocals(Node inliningTarget, PFrame callerFrame, Object[] args, GetFrameLocalsNode getFrameLocalsNode) { - Object callerLocals = getFrameLocalsNode.execute(inliningTarget, callerFrame); - setCustomLocals(args, callerLocals); - } - - private static void setCustomLocals(Object[] args, Object locals) { - PArguments.setSpecialArgument(args, locals); - } - - private void setBuiltinsInGlobals(VirtualFrame frame, Node inliningTarget, PDict globals, HashingCollectionNodes.SetItemNode setBuiltins, PythonModule builtins) { - if (builtins != null) { - PDict builtinsDict = getOrCreateDictNode(builtins); - setBuiltins.execute(frame, inliningTarget, globals, T___BUILTINS__, builtinsDict); - } else { - // This happens during context initialization - return; - } - } - - private void setCustomGlobals(VirtualFrame frame, Node inliningTarget, PDict globals, HashingCollectionNodes.SetItemNode setBuiltins, Object[] args) { - PythonModule builtins = getContext().getBuiltins(); - setBuiltinsInGlobals(frame, inliningTarget, globals, setBuiltins, builtins); - PArguments.setGlobals(args, globals); - } + @GenerateInline + @GenerateCached(false) + abstract static class CreateEvalExecArgumentsNode extends Node { + public abstract Object[] execute(VirtualFrame frame, Node inliningTarget, Object globals, Object locals, TruffleString mode); @Specialization - @SuppressWarnings("truffle-static-method") - Object execInheritGlobalsInheritLocals(VirtualFrame frame, Object source, @SuppressWarnings("unused") PNone globals, @SuppressWarnings("unused") PNone locals, - @Bind("this") Node inliningTarget, + static Object[] inheritGlobals(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") PNone globals, Object locals, TruffleString mode, @Exclusive @Cached ReadCallerFrameNode readCallerFrameNode, - @Exclusive @Cached CodeNodes.GetCodeCallTargetNode getCt, - @Cached GetFrameLocalsNode getFrameLocalsNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - PCode code = createAndCheckCode(frame, inliningTarget, source, raiseNode); + @Exclusive @Cached InlinedConditionProfile haveLocals, + @Exclusive @Cached PyMappingCheckNode mappingCheckNode, + @Exclusive @Cached GetFrameLocalsNode getFrameLocalsNode, + @Exclusive @Cached PRaiseNode raiseNode) { PFrame callerFrame = readCallerFrameNode.executeWith(frame, 0); Object[] args = PArguments.create(); - inheritGlobals(callerFrame, args); - inheritLocals(inliningTarget, callerFrame, args, getFrameLocalsNode); - - return invokeNode.execute(frame, getCt.execute(inliningTarget, code), args); + PArguments.setGlobals(args, callerFrame.getGlobals()); + if (haveLocals.profile(inliningTarget, locals instanceof PNone)) { + Object callerLocals = getFrameLocalsNode.execute(inliningTarget, callerFrame); + setCustomLocals(args, callerLocals); + } else { + if (!mappingCheckNode.execute(inliningTarget, locals)) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.LOCALS_MUST_BE_MAPPING, mode, locals); + } + setCustomLocals(args, locals); + } + return args; } @Specialization - Object execCustomGlobalsGlobalLocals(VirtualFrame frame, Object source, PDict globals, @SuppressWarnings("unused") PNone locals, - @Bind("this") Node inliningTarget, - @Shared @Cached HashingCollectionNodes.SetItemNode setBuiltins, - @Shared("getCt") @Cached CodeNodes.GetCodeCallTargetNode getCt, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - PCode code = createAndCheckCode(frame, inliningTarget, source, raiseNode); + static Object[] customGlobals(VirtualFrame frame, Node inliningTarget, PDict globals, Object locals, TruffleString mode, + @Bind PythonContext context, + @Exclusive @Cached InlinedConditionProfile haveLocals, + @Exclusive @Cached PyMappingCheckNode mappingCheckNode, + @Exclusive @Cached GetOrCreateDictNode getOrCreateDictNode, + @Exclusive @Cached HashingCollectionNodes.SetItemNode setBuiltins, + @Exclusive @Cached PRaiseNode raiseNode) { Object[] args = PArguments.create(); - setCustomGlobals(frame, inliningTarget, globals, setBuiltins, args); - setCustomLocals(args, globals); - RootCallTarget rootCallTarget = getCt.execute(inliningTarget, code); - if (rootCallTarget == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.CANNOT_CREATE_CALL_TARGET, code); + PythonModule builtins = context.getBuiltins(); + // Builtins may be null during context initialization + if (builtins != null) { + PDict builtinsDict = getOrCreateDictNode.execute(inliningTarget, builtins); + setBuiltins.execute(frame, inliningTarget, globals, T___BUILTINS__, builtinsDict); + } + PArguments.setGlobals(args, globals); + if (haveLocals.profile(inliningTarget, locals instanceof PNone)) { + setCustomLocals(args, globals); + } else { + if (!mappingCheckNode.execute(inliningTarget, locals)) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.LOCALS_MUST_BE_MAPPING, mode, locals); + } + setCustomLocals(args, locals); } - return invokeNode.execute(frame, rootCallTarget, args); - } - - @Specialization(guards = {"isMapping(inliningTarget, mappingCheckNode, locals)"}) - @SuppressWarnings("truffle-static-method") - Object execInheritGlobalsCustomLocals(VirtualFrame frame, Object source, @SuppressWarnings("unused") PNone globals, Object locals, - @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Shared @Cached PyMappingCheckNode mappingCheckNode, - @Exclusive @Cached ReadCallerFrameNode readCallerFrameNode, - @Shared("getCt") @Cached CodeNodes.GetCodeCallTargetNode getCt, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - PCode code = createAndCheckCode(frame, inliningTarget, source, raiseNode); - PFrame callerFrame = readCallerFrameNode.executeWith(frame, 0); - Object[] args = PArguments.create(); - inheritGlobals(callerFrame, args); - setCustomLocals(args, locals); - - return invokeNode.execute(frame, getCt.execute(inliningTarget, code), args); + return args; } - @Specialization(guards = {"isMapping(inliningTarget, mappingCheckNode, locals)"}) - @SuppressWarnings("truffle-static-method") - Object execCustomGlobalsCustomLocals(VirtualFrame frame, Object source, PDict globals, Object locals, - @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Shared @Cached PyMappingCheckNode mappingCheckNode, - @Shared @Cached HashingCollectionNodes.SetItemNode setBuiltins, - @Shared("getCt") @Cached CodeNodes.GetCodeCallTargetNode getCt, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - PCode code = createAndCheckCode(frame, inliningTarget, source, raiseNode); - Object[] args = PArguments.create(); - setCustomGlobals(frame, inliningTarget, globals, setBuiltins, args); - setCustomLocals(args, locals); - - return invokeNode.execute(frame, getCt.execute(inliningTarget, code), args); + @Fallback + static Object[] badGlobals(Node inliningTarget, Object globals, @SuppressWarnings("unused") Object locals, TruffleString mode) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.GLOBALS_MUST_BE_DICT, mode, globals); } - @Specialization(guards = {"!isAnyNone(globals)", "!isDict(globals)"}) - @SuppressWarnings({"unused", "truffle-static-method"}) - PNone badGlobals(Object source, Object globals, Object locals, - @Shared("raise") @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.GLOBALS_MUST_BE_DICT, getMode(), globals); + private static void setCustomLocals(Object[] args, Object locals) { + PArguments.setSpecialArgument(args, locals); } + } - @Specialization(guards = {"isAnyNone(globals) || isDict(globals)", "!isAnyNone(locals)", "!isMapping(inliningTarget, mappingCheckNode, locals)"}) - @SuppressWarnings({"unused", "truffle-static-method"}) - PNone badLocals(Object source, PDict globals, Object locals, - @Bind("this") Node inliningTarget, - @Shared @Cached PyMappingCheckNode mappingCheckNode, - @Shared("raise") @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.LOCALS_MUST_BE_MAPPING, getMode(), locals); - } + @GenerateInline + @GenerateCached(false) + abstract static class EvalExecNode extends Node { + abstract Object execute(VirtualFrame frame, Node inliningTarget, Object source, Object globals, Object locals, TruffleString mode, boolean shouldStripLeadingWhitespace); - private CompileNode getCompileNode() { - if (compileNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - compileNode = insert(CompileNode.create(false, shouldStripLeadingWhitespace())); + @Specialization + static Object eval(VirtualFrame frame, Node inliningTarget, Object source, Object globals, Object locals, TruffleString mode, @SuppressWarnings("unused") boolean shouldStripLeadingWhitespace, + @Cached("create(false, shouldStripLeadingWhitespace)") CompileNode compileNode, + @Cached CreateEvalExecArgumentsNode createArguments, + @Cached CodeNodes.GetCodeCallTargetNode getCallTarget, + @Cached CallDispatchers.CallTargetCachedInvokeNode invoke, + @Cached PRaiseNode raiseNode) { + PCode code = compileNode.compile(frame, source, T_STRING_SOURCE, mode, -1, -1); + if (code.getFreeVars().length > 0) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CODE_OBJ_NO_FREE_VARIABLES, mode); } - return compileNode; + Object[] args = createArguments.execute(frame, inliningTarget, globals, locals, mode); + RootCallTarget callTarget = getCallTarget.execute(inliningTarget, code); + return invoke.execute(frame, inliningTarget, callTarget, args); } + } - private PDict getOrCreateDictNode(PythonObject object) { - if (getOrCreateDictNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - getOrCreateDictNode = insert(GetOrCreateDictNode.create()); - } - return getOrCreateDictNode.executeCached(object); - } + // eval(expression, globals=None, locals=None) + @Builtin(name = J_EVAL, minNumOfPositionalArgs = 1, parameterNames = {"expression", "globals", "locals"}) + @GenerateNodeFactory + public abstract static class EvalNode extends PythonBuiltinNode { - protected boolean shouldStripLeadingWhitespace() { - return true; + @Specialization + static Object eval(VirtualFrame frame, Object source, Object globals, Object locals, + @Bind Node inliningTarget, + @Cached EvalExecNode evalNode) { + return evalNode.execute(frame, inliningTarget, source, globals, locals, T_EVAL, true); } } @Builtin(name = J_EXEC, minNumOfPositionalArgs = 1, parameterNames = {"source", "globals", "locals"}) @GenerateNodeFactory - abstract static class ExecNode extends EvalNode { - protected abstract Object executeInternal(VirtualFrame frame); + public abstract static class ExecNode extends PythonBuiltinNode { - @Override - protected TruffleString getMode() { - return T_EXEC; - } - - @Override - public final Object execute(VirtualFrame frame) { - executeInternal(frame); - return PNone.NONE; - } - - @Override - protected boolean shouldStripLeadingWhitespace() { - return false; + @Specialization + static Object exec(VirtualFrame frame, Object source, Object globals, Object locals, + @Bind Node inliningTarget, + @Cached EvalExecNode evalNode) { + evalNode.execute(frame, inliningTarget, source, globals, locals, T_EXEC, false); + return NONE; } } @@ -1039,18 +957,17 @@ protected abstract Object executeInternal(VirtualFrame frame, Object source, Tru Object doCompile(VirtualFrame frame, TruffleString expression, TruffleString filename, TruffleString mode, int flags, boolean dontInherit, int optimize, int featureVersion, @Shared @Cached ReadCallerFrameNode readCallerFrame, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { if (!dontInherit) { PFrame fr = readCallerFrame.executeWith(frame, 0); - PCode code = factory.createCode(fr.getTarget()); + PCode code = PFactory.createCode(language, fr.getTarget()); flags |= code.getFlags() & PyCF_MASK; } - return compile(expression, filename, mode, flags, dontInherit, optimize, featureVersion, factory); + return compile(expression, filename, mode, flags, dontInherit, optimize, featureVersion); } @TruffleBoundary - Object compile(TruffleString expression, TruffleString filename, TruffleString mode, int flags, @SuppressWarnings("unused") boolean dontInherit, int optimize, int featureVersion, - PythonObjectFactory factory) { + Object compile(TruffleString expression, TruffleString filename, TruffleString mode, int flags, @SuppressWarnings("unused") boolean dontInherit, int optimize, int featureVersion) { checkFlags(flags); checkOptimize(optimize, optimize); checkSource(expression); @@ -1060,7 +977,7 @@ Object compile(TruffleString expression, TruffleString filename, TruffleString m InputType type = getParserInputType(mode, flags); if (type == InputType.FUNCTION_TYPE) { if ((flags & PyCF_ONLY_AST) == 0) { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.COMPILE_MODE_FUNC_TYPE_REQUIED_FLAG_ONLY_AST); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.COMPILE_MODE_FUNC_TYPE_REQUIED_FLAG_ONLY_AST); } } if (lstrip && !code.isEmpty()) { @@ -1083,6 +1000,9 @@ Object compile(TruffleString expression, TruffleString filename, TruffleString m if (featureVersion < 7) { compilerFlags.add(AbstractParser.Flags.ASYNC_HACKS); } + if (context.getEnv().getOptions().get(PythonOptions.ParserLogFiles)) { + PythonLanguage.LOGGER.log(Level.FINE, () -> "parse '" + source.getName() + "'"); + } Parser parser = Compiler.createParser(code.toJavaStringUncached(), errorCb, type, compilerFlags, featureVersion); ModTy mod = (ModTy) parser.parse(); errorCb.triggerDeprecationWarnings(); @@ -1107,7 +1027,7 @@ Object compile(TruffleString expression, TruffleString filename, TruffleString m } else { ct = getContext().getLanguage().cacheCode(filename, createCode); } - return wrapRootCallTarget((RootCallTarget) ct, factory); + return wrapRootCallTarget((RootCallTarget) ct); } @Specialization(limit = "3") @@ -1126,8 +1046,7 @@ Object generic(VirtualFrame frame, Object wSource, Object wFilename, TruffleStri @Cached TruffleString.FromByteArrayNode fromByteArrayNode, @Cached TruffleString.SwitchEncodingNode switchEncodingNode, @Shared @Cached ReadCallerFrameNode readCallerFrame, - @Shared @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (wSource instanceof PCode) { return wSource; } @@ -1150,28 +1069,32 @@ Object generic(VirtualFrame frame, Object wSource, Object wFilename, TruffleStri if (!dontInherit) { PFrame fr = readCallerFrame.executeWith(frame, 0); - PCode code = factory.createCode(fr.getTarget()); + PCode code = PFactory.createCode(PythonLanguage.get(inliningTarget), fr.getTarget()); flags |= code.getFlags() & PyCF_MASK; } if (AstModuleBuiltins.isAst(context, wSource)) { - ModTy mod = AstModuleBuiltins.obj2sst(context, wSource, getParserInputType(mode, flags)); + ModTy mod = AstModuleBuiltins.obj2sst(inliningTarget, context, wSource, getParserInputType(mode, flags)); Source source = PythonUtils.createFakeSource(filename); - RootCallTarget rootCallTarget = context.getLanguage(inliningTarget).compileForBytecodeInterpreter(context, mod, source, false, optimize, null, null, flags); - return wrapRootCallTarget(rootCallTarget, factory); + RootCallTarget rootCallTarget = context.getLanguage(inliningTarget).compileModule(context, mod, source, false, optimize, null, null, flags); + return wrapRootCallTarget(rootCallTarget); } - TruffleString source = sourceAsString(frame, inliningTarget, wSource, filename, interopLib, acquireLib, bufferLib, handleDecodingErrorNode, asStrNode, switchEncodingNode, factory, + TruffleString source = sourceAsString(frame, inliningTarget, wSource, filename, interopLib, acquireLib, bufferLib, handleDecodingErrorNode, asStrNode, switchEncodingNode, raiseNode, indirectCallData); checkSource(source); - return compile(source, filename, mode, flags, dontInherit, optimize, featureVersion, factory); + return compile(source, filename, mode, flags, dontInherit, optimize, featureVersion); } - private static PCode wrapRootCallTarget(RootCallTarget rootCallTarget, PythonObjectFactory factory) { + private static PCode wrapRootCallTarget(RootCallTarget rootCallTarget) { RootNode rootNode = rootCallTarget.getRootNode(); - if (rootNode instanceof PBytecodeRootNode) { - ((PBytecodeRootNode) rootNode).triggerDeferredDeprecationWarnings(); + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + if (rootNode instanceof PBytecodeDSLRootNode bytecodeDSLRootNode) { + bytecodeDSLRootNode.triggerDeferredDeprecationWarnings(); + } + } else if (rootNode instanceof PBytecodeRootNode bytecodeRootNode) { + bytecodeRootNode.triggerDeferredDeprecationWarnings(); } - return factory.createCode(rootCallTarget); + return PFactory.createCode(PythonLanguage.get(null), rootCallTarget); } @TruffleBoundary @@ -1184,14 +1107,14 @@ private void checkSource(TruffleString source) throws PException { @TruffleBoundary private void checkOptimize(int optimize, Object kwOptimize) throws PException { if (optimize < -1 || optimize > 2) { - throw PRaiseNode.raiseUncached(this, TypeError, ErrorMessages.INVALID_OPTIMIZE_VALUE, kwOptimize); + throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.INVALID_OPTIMIZE_VALUE, kwOptimize); } } @TruffleBoundary private void checkFlags(int flags) { if ((flags & ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_COMPILE_MASK)) != 0) { - throw PRaiseNode.raiseUncached(this, ValueError, null, NO_VALUE, ErrorMessages.UNRECOGNIZED_FLAGS, PythonUtils.EMPTY_OBJECT_ARRAY); + throw PRaiseNode.raiseStatic(this, ValueError, null, NO_VALUE, ErrorMessages.UNRECOGNIZED_FLAGS, PythonUtils.EMPTY_OBJECT_ARRAY); } } @@ -1207,9 +1130,9 @@ private InputType getParserInputType(TruffleString mode, int flags) { return InputType.FUNCTION_TYPE; } else { if ((flags & PyCF_ONLY_AST) != 0) { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.COMPILE_MODE_MUST_BE_AST_ONLY); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.COMPILE_MODE_MUST_BE_AST_ONLY); } else { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.COMPILE_MODE_MUST_BE); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.COMPILE_MODE_MUST_BE); } } } @@ -1217,7 +1140,7 @@ private InputType getParserInputType(TruffleString mode, int flags) { // modeled after _Py_SourceAsString TruffleString sourceAsString(VirtualFrame frame, Node inliningTarget, Object source, TruffleString filename, InteropLibrary interopLib, PythonBufferAcquireLibrary acquireLib, PythonBufferAccessLibrary bufferLib, CodecsModuleBuiltins.HandleDecodingErrorNode handleDecodingErrorNode, PyObjectStrAsTruffleStringNode asStrNode, - TruffleString.SwitchEncodingNode switchEncodingNode, PythonObjectFactory factory, PRaiseNode.Lazy raiseNode, IndirectCallData indirectCallData) { + TruffleString.SwitchEncodingNode switchEncodingNode, PRaiseNode raiseNode, IndirectCallData indirectCallData) { if (interopLib.isString(source)) { try { return switchEncodingNode.execute(interopLib.asTruffleString(source), TS_ENCODING); @@ -1231,7 +1154,7 @@ TruffleString sourceAsString(VirtualFrame frame, Node inliningTarget, Object sou try { buffer = acquireLib.acquireReadonly(source, frame, indirectCallData); } catch (PException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ARG_D_MUST_BE_S, "compile()", 1, "string, bytes or AST object"); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ARG_D_MUST_BE_S, "compile()", 1, "string, bytes or AST object"); } try { byte[] bytes = bufferLib.getInternalOrCopiedByteArray(source); @@ -1241,7 +1164,7 @@ TruffleString sourceAsString(VirtualFrame frame, Node inliningTarget, Object sou CodecsModuleBuiltins.TruffleDecoder decoder = new CodecsModuleBuiltins.TruffleDecoder(pythonEncodingNameFromJavaName, charset, bytes, bytesLen, CodingErrorAction.REPORT); if (!decoder.decodingStep(true)) { try { - handleDecodingErrorNode.execute(frame, decoder, T_STRICT, factory.createBytes(bytes, bytesLen)); + handleDecodingErrorNode.execute(frame, decoder, T_STRICT, PFactory.createBytes(PythonLanguage.get(inliningTarget), bytes, bytesLen)); throw CompilerDirectives.shouldNotReachHere(); } catch (PException e) { throw raiseInvalidSyntax(filename, "(unicode error) %s", asStrNode.execute(frame, inliningTarget, e.getEscapedException())); @@ -1287,8 +1210,8 @@ abstract static class DelAttrNode extends PythonBinaryBuiltinNode { @Specialization Object delattr(VirtualFrame frame, Object object, Object name, @Bind("this") Node inliningTarget, - @Cached DeleteAttributeNode delNode) { - delNode.execute(frame, inliningTarget, object, name); + @Cached PyObjectSetAttrO setAttr) { + setAttr.execute(frame, inliningTarget, object, name, NO_VALUE); return PNone.NONE; } } @@ -1456,39 +1379,33 @@ public IsInstanceNode createRecursive(byte newDepth) { return BuiltinFunctionsFactory.IsInstanceNodeFactory.create(newDepth); } - private static TriState isInstanceCheckInternal(VirtualFrame frame, Object instance, Object cls, LookupAndCallBinaryNode instanceCheckNode, - PyObjectIsTrueNode castToBooleanNode) { - Object instanceCheckResult = instanceCheckNode.executeObject(frame, cls, instance); - if (instanceCheckResult == NOT_IMPLEMENTED) { - return TriState.UNDEFINED; - } - return TriState.valueOf(castToBooleanNode.execute(frame, instanceCheckResult)); - } - - @Specialization(guards = "isPythonClass(cls)") - static boolean isInstance(VirtualFrame frame, Object instance, Object cls, - @Bind("this") Node inliningTarget, - @Shared("instanceCheck") @Cached("create(InstanceCheck)") LookupAndCallBinaryNode instanceCheckNode, - @Exclusive @Cached PyObjectIsTrueNode castToBooleanNode, - @Cached GetClassNode getClassNode, - @Cached IsSameTypeNode isSameTypeNode, - @Cached IsSubtypeNode isSubtypeNode) { - Object instanceClass = getClassNode.execute(inliningTarget, instance); - return isSameTypeNode.execute(inliningTarget, instanceClass, cls) || isSubtypeNode.execute(frame, instanceClass, cls)// - || isInstanceCheckInternal(frame, instance, cls, instanceCheckNode, castToBooleanNode) == TriState.TRUE; - } - - @Specialization(guards = {"!isPTuple(cls)", "!isPythonClass(cls)"}) + @Specialization(guards = "!isPTuple(cls)") static boolean isInstance(VirtualFrame frame, Object instance, Object cls, - @Bind("this") Node inliningTarget, - @Shared("instanceCheck") @Cached("create(InstanceCheck)") LookupAndCallBinaryNode instanceCheckNode, - @Exclusive @Cached PyObjectIsTrueNode castToBooleanNode, - @Cached TypeBuiltins.InstanceCheckNode typeInstanceCheckNode) { - TriState check = isInstanceCheckInternal(frame, instance, cls, instanceCheckNode, castToBooleanNode); - if (check == TriState.UNDEFINED) { - return typeInstanceCheckNode.executeWith(frame, cls, instance); + @Bind Node inliningTarget, + @Cached GetClassNode getClsClassNode, + @Cached IsBuiltinClassExactProfile classProfile, + @Cached GetClassNode getInstanceClassNode, + @Cached TypeNodes.IsSameTypeNode isSameTypeNode, + @Cached("create(T___INSTANCECHECK__)") LookupAndCallBinaryNode instanceCheckNode, + @Cached PyObjectIsTrueNode isTrueNode, + @Cached TypeNodes.GenericInstanceCheckNode genericInstanceCheckNode, + @Cached InlinedBranchProfile noInstanceCheckProfile) { + if (isSameTypeNode.execute(inliningTarget, getInstanceClassNode.execute(inliningTarget, instance), cls)) { + // Exact match, don't call __instancecheck__ + return true; + } + if (classProfile.profileClass(inliningTarget, getClsClassNode.execute(inliningTarget, cls), PythonBuiltinClassType.PythonClass)) { + // Avoid the lookup and call overhead when we know we're calling + // type.__instancecheck__ + return genericInstanceCheckNode.execute(frame, inliningTarget, instance, cls); + } + try { + Object result = instanceCheckNode.executeObject(frame, cls, instance); + return isTrueNode.execute(frame, result); + } catch (SpecialMethodNotFound ignore) { + noInstanceCheckProfile.enter(inliningTarget); + return genericInstanceCheckNode.execute(frame, inliningTarget, instance, cls); } - return check == TriState.TRUE; } } @@ -1513,14 +1430,25 @@ public IsSubClassNode createRecursive(byte newDepth) { @Specialization(guards = "!isPTuple(cls)") static boolean isSubclass(VirtualFrame frame, Object derived, Object cls, - @Cached("create(Subclasscheck)") LookupAndCallBinaryNode subclassCheckNode, - @Cached PyObjectIsTrueNode castToBooleanNode, - @Cached IsSubtypeNode isSubtypeNode) { - Object instanceCheckResult = subclassCheckNode.executeObject(frame, cls, derived); - if (instanceCheckResult != NOT_IMPLEMENTED) { - return castToBooleanNode.execute(frame, instanceCheckResult); + @Bind Node inliningTarget, + @Cached GetClassNode getClsClassNode, + @Cached IsBuiltinClassExactProfile classProfile, + @Cached("create(T___SUBCLASSCHECK__)") LookupAndCallBinaryNode subclassCheckNode, + @Cached PyObjectIsTrueNode isTrueNode, + @Cached TypeNodes.GenericSubclassCheckNode genericSubclassCheckNode, + @Cached InlinedBranchProfile noInstanceCheckProfile) { + if (classProfile.profileClass(inliningTarget, getClsClassNode.execute(inliningTarget, cls), PythonBuiltinClassType.PythonClass)) { + // Avoid the lookup and call overhead when we know we're calling + // type.__subclasscheck__ + return genericSubclassCheckNode.execute(frame, inliningTarget, derived, cls); + } + try { + Object result = subclassCheckNode.executeObject(frame, cls, derived); + return isTrueNode.execute(frame, result); + } catch (SpecialMethodNotFound ignore) { + noInstanceCheckProfile.enter(inliningTarget); + return genericSubclassCheckNode.execute(frame, inliningTarget, derived, cls); } - return isSubtypeNode.execute(frame, derived, cls); } @NeverDefault @@ -1545,15 +1473,15 @@ static Object iter(VirtualFrame frame, Object object, @SuppressWarnings("unused" static Object iter(Object callable, Object sentinel, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Cached PyCallableCheckNode callableCheck, - @Cached PythonObjectFactory factory) { - return factory.createSentinelIterator(callable, sentinel); + @Bind PythonLanguage language) { + return PFactory.createSentinelIterator(language, callable, sentinel); } @Fallback @SuppressWarnings("unused") static Object iterNotCallable(Object callable, Object sentinel, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.ITER_V_MUST_BE_CALLABLE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.ITER_V_MUST_BE_CALLABLE); } } @@ -1573,103 +1501,76 @@ public int len(VirtualFrame frame, Object obj, @GenerateCached(false) public abstract static class MinMaxNode extends Node { - abstract Object execute(VirtualFrame frame, Node inliningTarget, Object arg1, Object[] args, Object keywordArgIn, Object defaultVal, String name, BinaryComparisonNode comparisonNode); + abstract Object execute(VirtualFrame frame, Node inliningTarget, Object arg1, Object[] args, Object keywordArgIn, Object defaultVal, String name, RichCmpOp op); @Specialization(guards = "args.length == 0") static Object minmaxSequenceWithKey(VirtualFrame frame, Node inliningTarget, Object arg1, @SuppressWarnings("unused") Object[] args, Object keywordArgIn, Object defaultVal, String name, - BinaryComparisonNode compare, + RichCmpOp op, + @Exclusive @Cached PyObjectRichCompareBool compareNode, @Exclusive @Cached PyObjectGetIter getIter, - @Cached(inline = false) GetNextNode nextNode, - @Exclusive @Cached PyObjectIsTrueNode castToBooleanNode, + @Exclusive @Cached PyIterNextNode nextNode, @Exclusive @Cached CallNode.Lazy keyCall, - @Exclusive @Cached InlinedBranchProfile seenNonBoolean, @Exclusive @Cached InlinedConditionProfile keywordArgIsNone, - @Exclusive @Cached IsBuiltinObjectProfile errorProfile1, - @Exclusive @Cached IsBuiltinObjectProfile errorProfile2, @Exclusive @Cached InlinedConditionProfile hasDefaultProfile, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { boolean kwArgsAreNone = keywordArgIsNone.profile(inliningTarget, PGuards.isPNone(keywordArgIn)); Object keywordArg = kwArgsAreNone ? null : keywordArgIn; Object iterator = getIter.execute(frame, inliningTarget, arg1); Object currentValue; try { - currentValue = nextNode.execute(frame, iterator); - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile1); + currentValue = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { if (hasDefaultProfile.profile(inliningTarget, isNoValue(defaultVal))) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.ARG_IS_EMPTY_SEQ, name); + throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.ARG_IS_EMPTY_SEQ, name); } else { return defaultVal; } } Object currentKey = applyKeyFunction(frame, inliningTarget, keywordArg, keyCall, currentValue); int loopCount = 0; - try { - while (true) { - Object nextValue; - try { - nextValue = nextNode.execute(frame, iterator); - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile2); - break; - } + while (true) { + try { + Object nextValue = nextNode.execute(frame, inliningTarget, iterator); Object nextKey = applyKeyFunction(frame, inliningTarget, keywordArg, keyCall, nextValue); - boolean isTrue; - if (!seenNonBoolean.wasEntered(inliningTarget)) { - try { - isTrue = compare.executeBool(frame, nextKey, currentKey); - } catch (UnexpectedResultException e) { - seenNonBoolean.enter(inliningTarget); - isTrue = castToBooleanNode.execute(frame, e.getResult()); - } - } else { - isTrue = castToBooleanNode.execute(frame, compare.executeObject(frame, nextKey, currentKey)); - } + boolean isTrue = compareNode.execute(frame, inliningTarget, nextKey, currentKey, op); if (isTrue) { currentKey = nextKey; currentValue = nextValue; } loopCount++; + } catch (IteratorExhausted e) { + break; + } finally { + LoopNode.reportLoopCount(inliningTarget, loopCount < 0 ? Integer.MAX_VALUE : loopCount); } - } finally { - LoopNode.reportLoopCount(inliningTarget, loopCount < 0 ? Integer.MAX_VALUE : loopCount); } + return currentValue; } @Specialization(guards = {"args.length != 0"}) - static Object minmaxBinaryWithKey(VirtualFrame frame, Node inliningTarget, Object arg1, Object[] args, Object keywordArgIn, Object defaultVal, String name, BinaryComparisonNode compare, + static Object minmaxBinaryWithKey(VirtualFrame frame, Node inliningTarget, Object arg1, Object[] args, Object keywordArgIn, Object defaultVal, String name, + RichCmpOp op, + @Exclusive @Cached PyObjectRichCompareBool compareNode, @Exclusive @Cached CallNode.Lazy keyCall, - @Exclusive @Cached PyObjectIsTrueNode castToBooleanNode, - @Exclusive @Cached InlinedBranchProfile seenNonBoolean, @Exclusive @Cached InlinedConditionProfile keywordArgIsNone, @Exclusive @Cached InlinedConditionProfile moreThanTwo, @Exclusive @Cached InlinedLoopConditionProfile loopProfile, @Exclusive @Cached InlinedConditionProfile hasDefaultProfile, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { boolean kwArgsAreNone = keywordArgIsNone.profile(inliningTarget, PGuards.isPNone(keywordArgIn)); Object keywordArg = kwArgsAreNone ? null : keywordArgIn; if (!hasDefaultProfile.profile(inliningTarget, isNoValue(defaultVal))) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_SPECIFY_DEFAULT_FOR_S, name); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_SPECIFY_DEFAULT_FOR_S, name); } Object currentValue = arg1; Object currentKey = applyKeyFunction(frame, inliningTarget, keywordArg, keyCall, currentValue); Object nextValue = args[0]; Object nextKey = applyKeyFunction(frame, inliningTarget, keywordArg, keyCall, nextValue); - boolean isTrue; - if (!seenNonBoolean.wasEntered(inliningTarget)) { - try { - isTrue = compare.executeBool(frame, nextKey, currentKey); - } catch (UnexpectedResultException e) { - seenNonBoolean.enter(inliningTarget); - isTrue = castToBooleanNode.execute(frame, e.getResult()); - } - } else { - isTrue = castToBooleanNode.execute(frame, compare.executeObject(frame, nextKey, currentKey)); - } + boolean isTrue = compareNode.execute(frame, inliningTarget, nextKey, currentKey, op); if (isTrue) { currentKey = nextKey; currentValue = nextValue; @@ -1680,16 +1581,7 @@ static Object minmaxBinaryWithKey(VirtualFrame frame, Node inliningTarget, Objec for (int i = 0; loopProfile.inject(inliningTarget, i < args.length); i++) { nextValue = args[i]; nextKey = applyKeyFunction(frame, inliningTarget, keywordArg, keyCall, nextValue); - if (!seenNonBoolean.wasEntered(inliningTarget)) { - try { - isTrue = compare.executeBool(frame, nextKey, currentKey); - } catch (UnexpectedResultException e) { - seenNonBoolean.enter(inliningTarget); - isTrue = castToBooleanNode.execute(frame, e.getResult()); - } - } else { - isTrue = castToBooleanNode.execute(frame, compare.executeObject(frame, nextKey, currentKey)); - } + isTrue = compareNode.execute(frame, inliningTarget, nextKey, currentKey, op); if (isTrue) { currentKey = nextKey; currentValue = nextValue; @@ -1715,9 +1607,8 @@ public abstract static class MaxNode extends PythonBuiltinNode { @Specialization static Object max(VirtualFrame frame, Object arg1, Object[] args, Object keywordArgIn, Object defaultVal, @Bind("this") Node inliningTarget, - @Cached MinMaxNode minMaxNode, - @Cached BinaryComparisonNode.GtNode gtNode) { - return minMaxNode.execute(frame, inliningTarget, arg1, args, keywordArgIn, defaultVal, "max", gtNode); + @Cached MinMaxNode minMaxNode) { + return minMaxNode.execute(frame, inliningTarget, arg1, args, keywordArgIn, defaultVal, "max", RichCmpOp.Py_GT); } } @@ -1729,49 +1620,48 @@ public abstract static class MinNode extends PythonBuiltinNode { @Specialization static Object min(VirtualFrame frame, Object arg1, Object[] args, Object keywordArgIn, Object defaultVal, @Bind("this") Node inliningTarget, - @Cached MinMaxNode minMaxNode, - @Cached BinaryComparisonNode.LtNode ltNode) { - return minMaxNode.execute(frame, inliningTarget, arg1, args, keywordArgIn, defaultVal, "min", ltNode); + @Cached MinMaxNode minMaxNode) { + return minMaxNode.execute(frame, inliningTarget, arg1, args, keywordArgIn, defaultVal, "min", RichCmpOp.Py_LT); } } // next(iterator[, default]) - @SuppressWarnings("unused") @Builtin(name = J_NEXT, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2) @GenerateNodeFactory - public abstract static class NextNode extends PythonBinaryBuiltinNode { + abstract static class NextNode extends PythonBinaryBuiltinNode { @Specialization - public Object next(VirtualFrame frame, Object iterator, Object defaultObject, + static Object next(VirtualFrame frame, Object iterator, Object defaultObject, @Bind("this") Node inliningTarget, @Cached InlinedConditionProfile defaultIsNoValue, - @Cached("createNextCall()") LookupAndCallUnaryNode callNode, - @Cached IsBuiltinObjectProfile errorProfile) { - if (defaultIsNoValue.profile(inliningTarget, isNoValue(defaultObject))) { - return callNode.executeObject(frame, iterator); - } else { - try { - return callNode.executeObject(frame, iterator); - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); + @Cached GetObjectSlotsNode getSlots, + @Cached CallSlotTpIterNextNode callIterNext, + @Cached PRaiseNode raiseTypeError, + @Cached PRaiseNode raiseStopIteration, + @Cached IsBuiltinObjectProfile stopIterationProfile) { + TpSlots slots = getSlots.execute(inliningTarget, iterator); + if (!PyIterCheckNode.checkSlots(slots)) { + throw raiseTypeError.raise(inliningTarget, TypeError, ErrorMessages.OBJ_ISNT_ITERATOR, iterator); + } + try { + return callIterNext.execute(frame, inliningTarget, slots.tp_iternext(), iterator); + } catch (IteratorExhausted e) { + if (defaultIsNoValue.profile(inliningTarget, defaultObject == NO_VALUE)) { + throw raiseStopIteration.raise(inliningTarget, StopIteration); + } else { return defaultObject; } - } - } - - @NeverDefault - protected LookupAndCallUnaryNode createNextCall() { - return LookupAndCallUnaryNode.create(T___NEXT__, () -> new LookupAndCallUnaryNode.NoAttributeHandler() { - @Child PRaiseNode raiseNode = PRaiseNode.create(); - - @Override - public Object execute(Object iterator) { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_ISNT_ITERATOR, iterator); + } catch (PException e) { + if (defaultIsNoValue.profile(inliningTarget, defaultObject == NO_VALUE)) { + throw e; + } else { + e.expectStopIteration(inliningTarget, stopIterationProfile); + return defaultObject; } - }); + } } } - // ord(c) +// ord(c) @Builtin(name = J_ORD, minNumOfPositionalArgs = 1) @GenerateNodeFactory @ImportStatic(PGuards.class) @@ -1783,7 +1673,7 @@ static int ord(Object chrObj, @Cached CastToTruffleStringNode castToStringNode, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { TruffleString chr; try { chr = castToStringNode.execute(inliningTarget, chrObj); @@ -1792,7 +1682,7 @@ static int ord(Object chrObj, } int len = codePointLengthNode.execute(chr, TS_ENCODING); if (len != 1) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.EXPECTED_CHARACTER_BUT_STRING_FOUND, "ord()", len); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.EXPECTED_CHARACTER_BUT_STRING_FOUND, "ord()", len); } return codePointAtIndexNode.execute(chr, 0, TS_ENCODING); } @@ -1802,22 +1692,22 @@ static long ord(PBytesLike chr, @Bind("this") Node inliningTarget, @Cached CastToJavaLongExactNode castNode, @Cached SequenceStorageNodes.GetItemNode getItemNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { int len = chr.getSequenceStorage().length(); if (len != 1) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.EXPECTED_CHARACTER_BUT_STRING_FOUND, "ord()", len); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.EXPECTED_CHARACTER_BUT_STRING_FOUND, "ord()", len); } return castNode.execute(inliningTarget, getItemNode.execute(chr.getSequenceStorage(), 0)); } @Specialization(guards = {"!isString(obj)", "!isBytes(obj)"}) static Object ord(@SuppressWarnings("unused") Object obj, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.S_EXPECTED_STRING_OF_LEN_BUT_P, "ord()", "1", "obj"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.S_EXPECTED_STRING_OF_LEN_BUT_P, "ord()", "1", "obj"); } } - // print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False) +// print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False) @Builtin(name = J_PRINT, takesVarArgs = true, keywordOnlyNames = {"sep", "end", "file", "flush"}, doc = "\n" + "print(value, ..., sep=' ', end='\\n', file=sys.stdout, flush=False)\n" + "\n" + @@ -1884,19 +1774,19 @@ PNone printGeneric(VirtualFrame frame, Object[] values, Object sepIn, Object end @Exclusive @Cached CallNode callWrite, @Exclusive @Cached PyObjectCallMethodObjArgs callFlush, @Exclusive @Cached PyObjectStrAsObjectNode strNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleString sep; try { sep = sepIn instanceof PNone ? T_SPACE : castSep.execute(inliningTarget, sepIn); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.SEP_MUST_BE_NONE_OR_STRING, sepIn); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.SEP_MUST_BE_NONE_OR_STRING, sepIn); } TruffleString end; try { end = endIn instanceof PNone ? T_NEWLINE : castEnd.execute(inliningTarget, endIn); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.S_MUST_BE_NONE_OR_STRING, "end", sepIn); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.S_MUST_BE_NONE_OR_STRING, "end", sepIn); } Object file; @@ -1940,7 +1830,7 @@ private Object getStdout() { Object stdout = readStdout.execute(sys, T_STDOUT); if (stdout == NO_VALUE) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(this, RuntimeError, ErrorMessages.LOST_SYSSTDOUT); + throw PRaiseNode.raiseStatic(this, RuntimeError, ErrorMessages.LOST_SYSSTDOUT); } return stdout; } @@ -1962,24 +1852,26 @@ static Object repr(VirtualFrame frame, Object obj, // format(object, [format_spec]) @Builtin(name = J_FORMAT, minNumOfPositionalArgs = 1, parameterNames = {"object", "format_spec"}) @GenerateNodeFactory + @OperationProxy.Proxyable @ImportStatic(PGuards.class) public abstract static class FormatNode extends PythonBinaryBuiltinNode { @Specialization public static Object format(VirtualFrame frame, Object obj, Object formatSpec, @Bind("this") Node inliningTarget, - @Cached("create(Format)") LookupAndCallBinaryNode callFormat, + @Cached("create(T___FORMAT__)") LookupAndCallBinaryNode callFormat, @Cached InlinedConditionProfile formatIsNoValueProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object format = formatIsNoValueProfile.profile(inliningTarget, isNoValue(formatSpec)) ? T_EMPTY_STRING : formatSpec; - Object res = callFormat.executeObject(frame, obj, format); - if (res == NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.TYPE_DOESNT_DEFINE_FORMAT, obj); - } - if (!PGuards.isString(res)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_MUST_RETURN_S_NOT_P, T___FORMAT__, "str", res); + try { + Object res = callFormat.executeObject(frame, obj, format); + if (!PGuards.isString(res)) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_MUST_RETURN_S_NOT_P, T___FORMAT__, "str", res); + } + return res; + } catch (SpecialMethodNotFound ignore) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TYPE_DOESNT_DEFINE_FORMAT, obj); } - return res; } @NeverDefault @@ -2008,11 +1900,11 @@ public abstract static class RoundNode extends PythonBuiltinNode { @Specialization static Object round(VirtualFrame frame, Object x, @SuppressWarnings("unused") PNone n, @Bind("this") Node inliningTarget, - @Cached("create(Round)") LookupAndCallUnaryNode callRound, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Cached("create(T___ROUND__)") LookupAndCallUnaryNode callRound, + @Shared @Cached PRaiseNode raiseNode) { Object result = callRound.executeObject(frame, x); if (result == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.TYPE_DOESNT_DEFINE_METHOD, x, T___ROUND__); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TYPE_DOESNT_DEFINE_METHOD, x, T___ROUND__); } return result; } @@ -2020,13 +1912,13 @@ static Object round(VirtualFrame frame, Object x, @SuppressWarnings("unused") PN @Specialization(guards = "!isPNone(n)") static Object round(VirtualFrame frame, Object x, Object n, @Bind("this") Node inliningTarget, - @Cached("create(Round)") LookupAndCallBinaryNode callRound, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - Object result = callRound.executeObject(frame, x, n); - if (result == NOT_IMPLEMENTED) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.TYPE_DOESNT_DEFINE_METHOD, x, T___ROUND__); + @Cached("create(T___ROUND__)") LookupAndCallBinaryNode callRound, + @Shared @Cached PRaiseNode raiseNode) { + try { + return callRound.executeObject(frame, x, n); + } catch (SpecialMethodNotFound ignore) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TYPE_DOESNT_DEFINE_METHOD, x, T___ROUND__); } - return result; } } @@ -2088,7 +1980,7 @@ public abstract static class BreakPointNode extends PythonBuiltinNode { Object doIt(VirtualFrame frame, Object[] args, PKeyword[] kwargs, @Bind("this") Node inliningTarget, @Cached HashingStorageGetItem getItem, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (getDebuggerSessionCount() > 0) { // we already have a Truffle debugger attached, it'll stop here return PNone.NONE; @@ -2102,7 +1994,7 @@ Object doIt(VirtualFrame frame, Object[] args, PKeyword[] kwargs, Object sysModule = getItem.execute(inliningTarget, sysModules.getDictStorage(), T_SYS); Object breakpointhook = getBreakpointhookNode.execute(sysModule, T_BREAKPOINTHOOK); if (breakpointhook == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.LOST_SYSBREAKPOINTHOOK); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.LOST_SYSBREAKPOINTHOOK); } return callNode.execute(frame, breakpointhook, args, kwargs); } else { @@ -2119,140 +2011,209 @@ private int getDebuggerSessionCount() { @Builtin(name = J_POW, minNumOfPositionalArgs = 2, numOfPositionalOnlyArgs = 0, parameterNames = {"base", "exp", "mod"}) @GenerateNodeFactory public abstract static class PowNode extends PythonTernaryBuiltinNode { - @NeverDefault - static BinaryOpNode binaryPow() { - return BinaryArithmetic.Pow.create(); - } - - @NeverDefault - static LookupAndCallTernaryNode ternaryPow() { - return TernaryArithmetic.Pow.create(); - } @Specialization - Object binary(VirtualFrame frame, Object x, Object y, @SuppressWarnings("unused") PNone z, - @Cached("binaryPow()") BinaryOpNode powNode) { - return powNode.executeObject(frame, x, y); - } - - @Specialization(guards = "!isPNone(z)") Object ternary(VirtualFrame frame, Object x, Object y, Object z, - @Cached("ternaryPow()") LookupAndCallTernaryNode powNode) { - return powNode.execute(frame, x, y, z); + @Cached PyNumberPowerNode power) { + return power.execute(frame, x, y, z); } } // sum(iterable[, start]) @Builtin(name = J_SUM, minNumOfPositionalArgs = 1, parameterNames = {"iterable", "start"}) @GenerateNodeFactory - public abstract static class SumFunctionNode extends PythonBuiltinNode { + public abstract static class SumFunctionNode extends PythonBinaryBuiltinNode { - @Child private LookupAndCallUnaryNode next = LookupAndCallUnaryNode.create(SpecialMethodSlot.Next); - - public static boolean isIntOrNone(Object o) { - return o instanceof Integer || PGuards.isNoValue(o); - } - - @Specialization(guards = "isIntOrNone(startIn)", rewriteOn = UnexpectedResultException.class) - int sumInt(VirtualFrame frame, Object arg1, Object startIn, - @Bind("this") Node inliningTarget, - @Shared @Cached InlinedConditionProfile hasStart, - @Shared @Cached PyNumberAddNode addNode, - @Shared @Cached IsBuiltinObjectProfile errorProfile, - @Shared("getIter") @Cached PyObjectGetIter getIter) throws UnexpectedResultException { - int start = hasStart.profile(inliningTarget, startIn instanceof Integer) ? (Integer) startIn : 0; - return sumIntInternal(frame, inliningTarget, arg1, start, addNode, getIter, errorProfile); - } - - private int sumIntInternal(VirtualFrame frame, Node inliningTarget, Object arg1, int start, PyNumberAddNode add, PyObjectGetIter getIter, - IsBuiltinObjectProfile errorProfile) throws UnexpectedResultException { - Object iterator = getIter.execute(frame, inliningTarget, arg1); - int value = start; - while (true) { - int nextValue; - try { - nextValue = PGuards.expectInteger(next.executeObject(frame, iterator)); - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); - return value; - } catch (UnexpectedResultException e) { - Object newValue = add.execute(frame, inliningTarget, value, e.getResult()); - throw new UnexpectedResultException(iterateGeneric(frame, inliningTarget, iterator, newValue, add, errorProfile)); + @Specialization + Object sum(VirtualFrame frame, Object iterable, Object start, + @Bind Node inliningTarget, + @Cached InlinedConditionProfile defaultStart, + @Cached PRaiseNode raiseNode, + @Cached PyObjectGetIter getIter, + @Cached SumIteratorNode sumIteratorNode) { + if (defaultStart.profile(inliningTarget, start == NO_VALUE)) { + start = 0; + } else if (PGuards.isString(start)) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_SUM_STRINGS); + } else if (start instanceof PBytes) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_SUM_BYTES); + } else if (start instanceof PByteArray) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_SUM_BYTEARRAY); + } + Object iterator = getIter.execute(frame, inliningTarget, iterable); + return sumIteratorNode.execute(frame, inliningTarget, iterator, start); + } + + @GenerateInline + @GenerateCached(false) + @ImportStatic(PGuards.class) + abstract static class SumIteratorNode extends Node { + public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object iterator, Object start); + + @Specialization + static Object sumIntIterator(VirtualFrame frame, Node inliningTarget, PIntegerSequenceIterator iterator, int start, + @Shared @Cached InlinedLoopConditionProfile loopProfilePrimitive, + @Shared @Cached InlinedLoopConditionProfile loopProfileGeneric, + @Shared @Cached InlinedBranchProfile overflowProfile, + @Shared @Cached PyNumberAddNode addNode, + @Shared @Cached InlinedConditionProfile resultFitsInInt) { + long longResult = start; + while (loopProfilePrimitive.profile(inliningTarget, iterator.hasNext())) { + long next = iterator.next(); + try { + longResult = PythonUtils.addExact(longResult, next); + } catch (OverflowException e) { + overflowProfile.enter(inliningTarget); + Object objectResult = addNode.execute(frame, longResult, next); + while (loopProfileGeneric.profile(inliningTarget, iterator.hasNext())) { + objectResult = addNode.execute(frame, objectResult, iterator.next()); + } + return objectResult; + } } - try { - value = add.executeInt(frame, inliningTarget, value, nextValue); - } catch (UnexpectedResultException e) { - throw new UnexpectedResultException(iterateGeneric(frame, inliningTarget, iterator, e.getResult(), add, errorProfile)); + return maybeInt(inliningTarget, resultFitsInInt, longResult); + } + + @Specialization + static Object sumLongIterator(VirtualFrame frame, Node inliningTarget, PLongSequenceIterator iterator, int start, + @Shared @Cached InlinedLoopConditionProfile loopProfilePrimitive, + @Shared @Cached InlinedLoopConditionProfile loopProfileGeneric, + @Shared @Cached InlinedBranchProfile overflowProfile, + @Shared @Cached PyNumberAddNode addNode, + @Shared @Cached InlinedConditionProfile resultFitsInInt) { + long longResult = start; + while (loopProfilePrimitive.profile(inliningTarget, iterator.hasNext())) { + long next = iterator.next(); + try { + longResult = PythonUtils.addExact(longResult, next); + } catch (OverflowException e) { + overflowProfile.enter(inliningTarget); + Object objectResult = addNode.execute(frame, longResult, next); + while (loopProfileGeneric.profile(inliningTarget, iterator.hasNext())) { + objectResult = addNode.execute(frame, objectResult, iterator.next()); + } + return objectResult; + } + } + return maybeInt(inliningTarget, resultFitsInInt, longResult); + } + + @Specialization(guards = "isDouble(start) || isInt(start)") + static Object sumDoubleIterator(Node inliningTarget, PDoubleSequenceIterator iterator, Object start, + @Cached InlinedConditionProfile startIsDouble, + @Shared @Cached InlinedLoopConditionProfile loopProfilePrimitive) { + /* + * Need to make sure we keep start type if the iterator was empty + */ + if (!iterator.hasNext()) { + return start; } + double result = startIsDouble.profile(inliningTarget, start instanceof Double) ? (double) start : (int) start; + while (loopProfilePrimitive.profile(inliningTarget, iterator.hasNext())) { + result += iterator.next(); + } + return result; } - } - @Specialization(rewriteOn = UnexpectedResultException.class) - double sumDoubleDouble(VirtualFrame frame, Object arg1, double start, - @Bind("this") Node inliningTarget, - @Shared @Cached PyNumberAddNode addNode, - @Shared @Cached IsBuiltinObjectProfile errorProfile, - // dummy inline profile, so it can be @Shared, to optimize generated code: - @SuppressWarnings("unused") @Shared @Cached InlinedConditionProfile hasStart, - @Shared("getIter") @Cached PyObjectGetIter getIter, - // dummy raiseNode, so it can be @Shared, to optimize generated code: - @SuppressWarnings("unused") @Shared @Cached PRaiseNode.Lazy raiseNode) throws UnexpectedResultException { - return sumDoubleInternal(frame, inliningTarget, arg1, start, addNode, getIter, errorProfile); - } - - private double sumDoubleInternal(VirtualFrame frame, Node inliningTarget, Object arg1, double start, PyNumberAddNode add, PyObjectGetIter getIter, - IsBuiltinObjectProfile errorProfile) throws UnexpectedResultException { - Object iterator = getIter.execute(frame, inliningTarget, arg1); - double value = start; - while (true) { - double nextValue; + @Fallback + static Object sumGeneric(VirtualFrame frame, Node inliningTarget, Object iterator, Object start, + @Shared @Cached InlinedLoopConditionProfile loopProfilePrimitive, + @Shared @Cached InlinedLoopConditionProfile loopProfileGeneric, + @Cached PyIterNextNode nextNode, + @Shared @Cached PyNumberAddNode addNode, + @Shared @Cached InlinedConditionProfile resultFitsInInt, + @Exclusive @Cached InlinedBranchProfile seenObject, + @Exclusive @Cached InlinedBranchProfile seenInt, + @Exclusive @Cached InlinedBranchProfile seenDouble, + @Exclusive @Cached InlinedBranchProfile genericBranch) { + /* + * Peel the first iteration to see what's the type. + */ + Object next; try { - nextValue = PGuards.expectDouble(next.executeObject(frame, iterator)); - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); - return value; - } catch (UnexpectedResultException e) { - Object newValue = add.execute(frame, inliningTarget, value, e.getResult()); - throw new UnexpectedResultException(iterateGeneric(frame, inliningTarget, iterator, newValue, add, errorProfile)); + next = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { + return start; } - try { - value = add.executeDouble(frame, inliningTarget, value, nextValue); - } catch (UnexpectedResultException e) { - throw new UnexpectedResultException(iterateGeneric(frame, inliningTarget, iterator, e.getResult(), add, errorProfile)); + Object acc = addNode.execute(frame, start, next); + /* + * We try to process integers/longs/doubles as long as we can. Then we always fall + * through to the generic path. `next` and `acc` are always properly set so that the + * generic path can check if there are remaining items and resume if necessary. + */ + if (acc instanceof Integer || acc instanceof Long) { + seenInt.enter(inliningTarget); + long longAcc = acc instanceof Integer ? (int) acc : (long) acc; + boolean exitLoop = false, exhausted = false; + while (loopProfilePrimitive.profile(inliningTarget, !exitLoop)) { + try { + next = nextNode.execute(frame, inliningTarget, iterator); + if (next instanceof Integer nextInt) { + longAcc = PythonUtils.addExact(longAcc, nextInt); + } else if (next instanceof Long nextLong) { + longAcc = PythonUtils.addExact(longAcc, nextLong); + } else { + exitLoop = true; + } + } catch (OverflowException e) { + exitLoop = true; + } catch (IteratorExhausted e) { + exitLoop = true; + exhausted = true; + } + } + if (exhausted) { + return maybeInt(inliningTarget, resultFitsInInt, longAcc); + } + genericBranch.enter(inliningTarget); + acc = longAcc; + } else if (acc instanceof Double doubleAcc) { + seenDouble.enter(inliningTarget); + boolean exitLoop = false, exhausted = false; + while (loopProfilePrimitive.profile(inliningTarget, !exitLoop)) { + try { + next = nextNode.execute(frame, inliningTarget, iterator); + if (next instanceof Double nextDouble) { + doubleAcc += nextDouble; + } else { + exitLoop = true; + } + } catch (IteratorExhausted e) { + exitLoop = true; + exhausted = true; + } + } + if (exhausted) { + return doubleAcc; + } + genericBranch.enter(inliningTarget); + acc = doubleAcc; + } else { + seenObject.enter(inliningTarget); + try { + next = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { + return acc; + } } + boolean exhausted = false; + do { + acc = addNode.execute(frame, acc, next); + try { + next = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { + exhausted = true; + } + } while (loopProfileGeneric.profile(inliningTarget, !exhausted)); + return acc; } - } - - @Specialization(replaces = {"sumInt", "sumDoubleDouble"}) - Object sum(VirtualFrame frame, Object arg1, Object start, - @Bind("this") Node inliningTarget, - @Shared @Cached PyNumberAddNode addNode, - @Shared @Cached IsBuiltinObjectProfile errorProfile, - @Shared("getIter") @Cached PyObjectGetIter getIter, - @Shared @Cached InlinedConditionProfile hasStart, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - if (PGuards.isString(start)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANT_SUM_STRINGS); - } else if (start instanceof PBytes) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANT_SUM_BYTES); - } else if (start instanceof PByteArray) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANT_SUM_BYTEARRAY); - } - Object iterator = getIter.execute(frame, inliningTarget, arg1); - return iterateGeneric(frame, inliningTarget, iterator, hasStart.profile(inliningTarget, start != NO_VALUE) ? start : 0, addNode, errorProfile); - } - private Object iterateGeneric(VirtualFrame frame, Node inliningTarget, Object iterator, Object start, PyNumberAddNode add, IsBuiltinObjectProfile errorProfile) { - Object value = start; - while (true) { - Object nextValue; - try { - nextValue = next.executeObject(frame, iterator); - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); - return value; + private static long maybeInt(Node inliningTarget, InlinedConditionProfile resultFitsInInt, long result) { + if (resultFitsInInt.profile(inliningTarget, PInt.isIntRange(result))) { + return (int) result; + } else { + return result; } - value = add.execute(frame, inliningTarget, value, nextValue); } } } @@ -2303,10 +2264,10 @@ static Object vars(VirtualFrame frame, @SuppressWarnings("unused") PNone none, static Object vars(VirtualFrame frame, Object obj, @Bind("this") Node inliningTarget, @Cached PyObjectLookupAttr lookupAttr, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object dict = lookupAttr.execute(frame, inliningTarget, obj, T___DICT__); if (dict == NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.VARS_ARGUMENT_MUST_HAVE_DICT); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.VARS_ARGUMENT_MUST_HAVE_DICT); } return dict; } @@ -2344,10 +2305,10 @@ abstract static class UpdateBasesNode extends Node { @Specialization static PTuple update(PTuple bases, Object[] arguments, int nargs, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached PyObjectLookupAttr getMroEntries, @Cached CallUnaryMethodNode callMroEntries, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { CompilerAsserts.neverPartOfCompilation(); ArrayList newBases = null; for (int i = 0; i < nargs; i++) { @@ -2370,7 +2331,7 @@ static PTuple update(PTuple bases, Object[] arguments, int nargs, } Object newBase = callMroEntries.executeObject(null, meth, bases); if (!PGuards.isPTuple(newBase)) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.MRO_ENTRIES_MUST_RETURN_TUPLE); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.MRO_ENTRIES_MUST_RETURN_TUPLE); } PTuple newBaseTuple = (PTuple) newBase; if (newBases == null) { @@ -2389,7 +2350,7 @@ static PTuple update(PTuple bases, Object[] arguments, int nargs, if (newBases == null) { return bases; } - return factory.createTuple(newBases.toArray()); + return PFactory.createTuple(language, newBases.toArray()); } } @@ -2405,7 +2366,7 @@ static Object calculate(Object metatype, PTuple bases, @Cached GetClassNode getClass, @Cached IsSubtypeNode isSubType, @Cached IsSubtypeNode isSubTypeReverse, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { CompilerAsserts.neverPartOfCompilation(); /* * Determine the proper metatype to deal with this, and check for metatype conflicts @@ -2424,7 +2385,7 @@ static Object calculate(Object metatype, PTuple bases, } else if (isSubTypeReverse.execute(tmpType, winner)) { winner = tmpType; } else { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.METACLASS_CONFLICT); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.METACLASS_CONFLICT); } } return winner; @@ -2433,7 +2394,6 @@ static Object calculate(Object metatype, PTuple bases, @Builtin(name = J___BUILD_CLASS__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory - @ImportStatic(SpecialMethodSlot.class) public abstract static class BuildClassNode extends PythonVarargsBuiltinNode { private static final TruffleString T_METACLASS = tsLiteral("metaclass"); public static final TruffleString T_BUILD_JAVA_CLASS = tsLiteral("build_java_class"); @@ -2447,12 +2407,13 @@ private static Object buildJavaClass(Object namespace, TruffleString name, Objec } @InliningCutoff - private static Object buildJavaClass(VirtualFrame frame, PythonLanguage language, PFunction function, Object[] arguments, PythonObjectFactory factory, CallDispatchNode callBody, + private static Object buildJavaClass(VirtualFrame frame, Node inliningTarget, PythonLanguage language, PFunction function, Object[] arguments, + CallDispatchers.FunctionCachedInvokeNode invokeBody, TruffleString name) { - PDict ns = factory.createDict(new DynamicObjectStorage(language)); + PDict ns = PFactory.createDict(language, new DynamicObjectStorage(language)); Object[] args = PArguments.create(0); PArguments.setSpecialArgument(args, ns); - callBody.executeCall(frame, function, args); + invokeBody.execute(frame, inliningTarget, function, args); return buildJavaClass(ns, name, arguments[1]); } @@ -2461,41 +2422,42 @@ protected Object doItNonFunction(VirtualFrame frame, Object function, Object[] a @Bind("this") Node inliningTarget, @Cached CastToTruffleStringNode castToTruffleStringNode, @Cached("createFor(this)") IndirectCallData indirectCallData, - @Cached PythonObjectFactory factory, @Cached CalculateMetaclassNode calculateMetaClass, @Cached("create(T___PREPARE__)") GetAttributeNode getPrepare, @Cached PyMappingCheckNode pyMappingCheckNode, - @Cached CallVarargsMethodNode callPrep, - @Cached CallVarargsMethodNode callType, - @Cached CallDispatchNode callBody, + @Cached CallNode callPrep, + @Cached CallNode callType, + @Cached CallDispatchers.FunctionCachedInvokeNode invokeBody, @Cached UpdateBasesNode update, @Cached PyObjectSetItem setOrigBases, @Cached GetClassNode getClass, - @Cached IsBuiltinObjectProfile noAttributeProfile) { + @Cached IsBuiltinObjectProfile noAttributeProfile, + @Cached PRaiseNode raiseNode) { if (arguments.length < 1) { - throw raise(PythonErrorType.TypeError, ErrorMessages.BUILD_CLS_NOT_ENOUGH_ARGS); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.BUILD_CLS_NOT_ENOUGH_ARGS); } if (!PGuards.isFunction(function)) { - throw raise(PythonErrorType.TypeError, ErrorMessages.BUILD_CLS_FUNC_MUST_BE_FUNC); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.BUILD_CLS_FUNC_MUST_BE_FUNC); } TruffleString name; try { name = castToTruffleStringNode.execute(inliningTarget, arguments[0]); } catch (CannotCastException e) { - throw raise(PythonErrorType.TypeError, ErrorMessages.BUILD_CLS_NAME_NOT_STRING); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.BUILD_CLS_NAME_NOT_STRING); } - Object[] basesArray = Arrays.copyOfRange(arguments, 1, arguments.length); - PTuple origBases = factory.createTuple(basesArray); - - PythonContext ctx = PythonContext.get(calculateMetaClass); + PythonContext ctx = PythonContext.get(inliningTarget); Env env = ctx.getEnv(); PythonLanguage language = ctx.getLanguage(inliningTarget); + + Object[] basesArray = Arrays.copyOfRange(arguments, 1, arguments.length); + PTuple origBases = PFactory.createTuple(language, basesArray); + if (arguments.length == 2 && env.isHostObject(arguments[1]) && env.asHostObject(arguments[1]) instanceof Class) { // we want to subclass a Java class - return buildJavaClass(frame, language, (PFunction) function, arguments, factory, callBody, name); + return buildJavaClass(frame, inliningTarget, language, (PFunction) function, arguments, invokeBody, name); } class InitializeBuildClass { @@ -2557,14 +2519,14 @@ class InitializeBuildClass { ns = callPrep.execute(frame, prep, new Object[]{name, init.bases}, init.mkw); } catch (PException p) { p.expectAttributeError(inliningTarget, noAttributeProfile); - ns = factory.createDict(new DynamicObjectStorage(language)); + ns = PFactory.createDict(language, new DynamicObjectStorage(language)); } if (!pyMappingCheckNode.execute(inliningTarget, ns)) { throw raiseNoMapping(init.isClass, init.meta, ns); } Object[] bodyArguments = PArguments.create(0); PArguments.setSpecialArgument(bodyArguments, ns); - callBody.executeCall(frame, (PFunction) function, bodyArguments); + invokeBody.execute(frame, inliningTarget, (PFunction) function, bodyArguments); if (init.bases != origBases) { setOrigBases.execute(frame, inliningTarget, ns, SpecialAttributeNames.T___ORIG_BASES__, origBases); } @@ -2580,31 +2542,32 @@ class InitializeBuildClass { @InliningCutoff private PException raiseNoMapping(boolean isClass, Object meta, Object ns) { if (isClass) { - throw raise(PythonErrorType.TypeError, ErrorMessages.N_PREPARE_MUST_RETURN_MAPPING, meta, ns); + throw PRaiseNode.raiseStatic(this, PythonErrorType.TypeError, ErrorMessages.N_PREPARE_MUST_RETURN_MAPPING, meta, ns); } else { - throw raise(PythonErrorType.TypeError, ErrorMessages.MTCLS_PREPARE_MUST_RETURN_MAPPING, ns); + throw PRaiseNode.raiseStatic(this, PythonErrorType.TypeError, ErrorMessages.MTCLS_PREPARE_MUST_RETURN_MAPPING, ns); } } } - @Builtin(name = "anext", minNumOfPositionalArgs = 1) + @Builtin(name = "anext", minNumOfPositionalArgs = 1, numOfPositionalOnlyArgs = 2, parameterNames = {"aiterator", "default"}) @GenerateNodeFactory - public abstract static class ANext extends PythonUnaryBuiltinNode { + public abstract static class ANext extends PythonBinaryBuiltinNode { @Specialization - public Object doGeneric(VirtualFrame frame, Object asyncIter, + static Object doGeneric(VirtualFrame frame, Object asyncIter, Object defaultValue, @Bind("this") Node inliningTarget, - @Cached(parameters = "ANext") LookupSpecialMethodSlotNode getANext, - @Cached GetClassNode getAsyncIterType, - @Cached PRaiseNode.Lazy raiseNoANext, - @Cached CallUnaryMethodNode callANext, - @Cached TypeNodes.GetNameNode getName) { - // TODO: two argument anext - Object type = getAsyncIterType.execute(inliningTarget, asyncIter); - Object getter = getANext.execute(frame, type, asyncIter); - if (getter == NO_VALUE) { - throw raiseNoANext.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.OBJECT_NOT_ASYNCGEN, getName.execute(inliningTarget, type)); - } - return callANext.executeObject(frame, getter, asyncIter); + @Cached GetObjectSlotsNode getSlots, + @Cached CallSlotUnaryNode callSlot, + @Cached InlinedConditionProfile hasDefault, + @Cached PRaiseNode raiseNoANext) { + TpSlots slots = getSlots.execute(inliningTarget, asyncIter); + if (slots.am_anext() == null) { + throw raiseNoANext.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.OBJECT_NOT_ASYNCGEN, asyncIter); + } + if (hasDefault.profile(inliningTarget, defaultValue == NO_VALUE)) { + return callSlot.execute(frame, inliningTarget, slots.am_anext(), asyncIter); + } else { + return PFactory.createANextAwaitable(PythonLanguage.get(inliningTarget), asyncIter, defaultValue); + } } } @@ -2612,8 +2575,8 @@ public Object doGeneric(VirtualFrame frame, Object asyncIter, @GenerateNodeFactory public abstract static class AIter extends PythonUnaryBuiltinNode { @Specialization - public Object doGeneric(VirtualFrame frame, Object arg, - @Cached(neverDefault = true) GetAIterNode aiter) { + static Object doGeneric(VirtualFrame frame, Object arg, + @Cached GetAIterNode aiter) { return aiter.execute(frame, arg); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CmathModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CmathModuleBuiltins.java index fe32d28808..105027ab46 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CmathModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CmathModuleBuiltins.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2020, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2020 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -10,6 +10,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -27,9 +28,9 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; +import com.oracle.graal.python.nodes.truffle.PythonIntegerAndFloatTypes; import com.oracle.graal.python.nodes.util.CoerceToComplexNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -78,14 +79,14 @@ public void initialize(Python3Core core) { addBuiltinConstant("tau", 2 * Math.PI); addBuiltinConstant("inf", Double.POSITIVE_INFINITY); addBuiltinConstant("nan", Double.NaN); - addBuiltinConstant("infj", core.factory().createComplex(0, Double.POSITIVE_INFINITY)); - addBuiltinConstant("nanj", core.factory().createComplex(0, Double.NaN)); + addBuiltinConstant("infj", PFactory.createComplex(core.getLanguage(), 0, Double.POSITIVE_INFINITY)); + addBuiltinConstant("nanj", PFactory.createComplex(core.getLanguage(), 0, Double.NaN)); super.initialize(core); } - static PComplex specialValue(PythonObjectFactory factory, ComplexValue[][] table, double real, double imag) { + static PComplex specialValue(PythonLanguage language, ComplexValue[][] table, double real, double imag) { ComplexValue v = specialValue(table, real, imag); - return v == null ? null : v.toPComplex(factory); + return v == null ? null : v.toPComplex(language); } static ComplexValue specialValue(ComplexValue[][] table, double real, double imag) { @@ -122,8 +123,8 @@ static class ComplexValue { this.imag = imag; } - PComplex toPComplex(PythonObjectFactory factory) { - return factory.createComplex(real, imag); + PComplex toPComplex(PythonLanguage language) { + return PFactory.createComplex(language, real, imag); } } @@ -166,48 +167,48 @@ static SpecialType ofDouble(double d) { @GenerateInline @GenerateCached(false) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(MathGuards.class) abstract static class CmathComplexUnaryHelperNode extends Node { @FunctionalInterface interface Op { - ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode.Lazy raiseNode); + ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode raiseNode); } abstract PComplex execute(VirtualFrame frame, Node inliningTarget, Object value, Op op); @Specialization static PComplex doL(Node inliningTarget, long value, Op op, - @Shared @Cached(inline = false) PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - return op.compute(inliningTarget, value, 0, raiseNode).toPComplex(factory); + @Bind PythonLanguage language, + @Shared @Cached PRaiseNode raiseNode) { + return op.compute(inliningTarget, value, 0, raiseNode).toPComplex(language); } @Specialization static PComplex doD(Node inliningTarget, double value, Op op, - @Shared @Cached(inline = false) PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - return op.compute(inliningTarget, value, 0, raiseNode).toPComplex(factory); + @Bind PythonLanguage language, + @Shared @Cached PRaiseNode raiseNode) { + return op.compute(inliningTarget, value, 0, raiseNode).toPComplex(language); } @Specialization static PComplex doC(Node inliningTarget, PComplex value, Op op, - @Shared @Cached(inline = false) PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - return op.compute(inliningTarget, value.getReal(), value.getImag(), raiseNode).toPComplex(factory); + @Bind PythonLanguage language, + @Shared @Cached PRaiseNode raiseNode) { + return op.compute(inliningTarget, value.getReal(), value.getImag(), raiseNode).toPComplex(language); } @Specialization static PComplex doGeneral(VirtualFrame frame, Node inliningTarget, Object value, Op op, @Cached CoerceToComplexNode coerceToComplex, - @Shared @Cached(inline = false) PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - return doC(inliningTarget, coerceToComplex.execute(frame, inliningTarget, value), op, factory, raiseNode); + @Bind PythonLanguage language, + @Exclusive @Cached PRaiseNode raiseNode) { + return doC(inliningTarget, coerceToComplex.execute(frame, inliningTarget, value), op, language, raiseNode); } } - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(MathGuards.class) @GenerateInline @GenerateCached(false) @@ -276,7 +277,7 @@ static boolean doIt(VirtualFrame frame, Object o, } @Builtin(name = "phase", minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(MathGuards.class) @GenerateNodeFactory abstract static class PhaseNode extends PythonUnaryBuiltinNode { @@ -305,28 +306,28 @@ static double doGeneral(VirtualFrame frame, Object value, } @Builtin(name = "polar", minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(MathGuards.class) @GenerateNodeFactory abstract static class PolarNode extends PythonUnaryBuiltinNode { @Specialization static PTuple doL(long value, - @Shared @Cached PythonObjectFactory factory) { - return doD(value, factory); + @Bind PythonLanguage language) { + return doD(value, language); } @Specialization static PTuple doD(double value, - @Shared @Cached PythonObjectFactory factory) { - return factory.createTuple(new Object[]{Math.abs(value), value < 0 ? Math.PI : 0}); + @Bind PythonLanguage language) { + return PFactory.createTuple(language, new Object[]{Math.abs(value), value < 0 ? Math.PI : 0}); } @Specialization static PTuple doC(PComplex value, @Shared @Cached ComplexBuiltins.AbsNode absNode, - @Shared @Cached PythonObjectFactory factory) { - return toPolar(value, absNode, factory); + @Bind PythonLanguage language) { + return toPolar(value, absNode, language); } @Specialization @@ -334,18 +335,18 @@ static PTuple doGeneral(VirtualFrame frame, Object value, @Bind("this") Node inliningTarget, @Cached CoerceToComplexNode coerceToComplex, @Shared @Cached ComplexBuiltins.AbsNode absNode, - @Shared @Cached PythonObjectFactory factory) { - return toPolar(coerceToComplex.execute(frame, inliningTarget, value), absNode, factory); + @Bind PythonLanguage language) { + return toPolar(coerceToComplex.execute(frame, inliningTarget, value), absNode, language); } - private static PTuple toPolar(PComplex value, ComplexBuiltins.AbsNode absNode, PythonObjectFactory factory) { + private static PTuple toPolar(PComplex value, ComplexBuiltins.AbsNode absNode, PythonLanguage language) { double r = absNode.executeDouble(value); - return factory.createTuple(new Object[]{r, Math.atan2(value.getImag(), value.getReal())}); + return PFactory.createTuple(language, new Object[]{r, Math.atan2(value.getImag(), value.getReal())}); } } @Builtin(name = "rect", minNumOfPositionalArgs = 2) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(MathGuards.class) @GenerateNodeFactory abstract static class RectNode extends PythonBinaryBuiltinNode { @@ -393,12 +394,12 @@ static PComplex doGeneral(VirtualFrame frame, Object r, Object phi, @TruffleBoundary private static PComplex rect(Node raisingNode, double r, double phi) { - PythonObjectFactory factory = PythonObjectFactory.getUncached(); + PythonLanguage language = PythonLanguage.get(null); // deal with special values if (!Double.isFinite(r) || !Double.isFinite(phi)) { // need to raise an exception if r is a nonzero number and phi is infinite if (r != 0.0 && !Double.isNaN(r) && Double.isInfinite(phi)) { - throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); } // if r is +/-infinity and phi is finite but nonzero then @@ -408,19 +409,19 @@ private static PComplex rect(Node raisingNode, double r, double phi) { double real = Math.copySign(Double.POSITIVE_INFINITY, Math.cos(phi)); double imag = Math.copySign(Double.POSITIVE_INFINITY, Math.sin(phi)); if (r > 0) { - return factory.createComplex(real, imag); + return PFactory.createComplex(language, real, imag); } else { - return factory.createComplex(-real, -imag); + return PFactory.createComplex(language, -real, -imag); } } - return specialValue(factory, SPECIAL_VALUES, r, phi); + return specialValue(language, SPECIAL_VALUES, r, phi); } - return factory.createComplex(r * Math.cos(phi), r * Math.sin(phi)); + return PFactory.createComplex(language, r * Math.cos(phi), r * Math.sin(phi)); } } @Builtin(name = "log", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(MathGuards.class) @GenerateNodeFactory abstract static class LogNode extends PythonBinaryBuiltinNode { @@ -446,15 +447,15 @@ static LogNode create() { @Specialization(guards = "isNoValue(y)") PComplex doComplexNone(PComplex x, @SuppressWarnings("unused") PNone y, - @Shared @Cached PythonObjectFactory factory) { - return log(x, factory); + @Bind PythonLanguage language) { + return log(x, language); } @Specialization PComplex doComplexComplex(VirtualFrame frame, PComplex x, PComplex y, @Shared @Cached ComplexBuiltins.DivNode divNode, - @Shared @Cached PythonObjectFactory factory) { - return divNode.executeComplex(frame, log(x, factory), log(y, factory)); + @Bind PythonLanguage language) { + return divNode.executeComplex(frame, log(x, language), log(y, language)); } @Specialization(guards = "isNoValue(yObj)") @@ -462,9 +463,9 @@ PComplex doGeneral(VirtualFrame frame, Object xObj, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @Shared @Cached CoerceToComplexNode coerceXToComplex, // unused node to avoid mixing shared and non-shared inlined nodes - @SuppressWarnings("unsued") @Shared @Cached CoerceToComplexNode coerceYToComplex, - @Shared @Cached PythonObjectFactory factory) { - return log(coerceXToComplex.execute(frame, inliningTarget, xObj), factory); + @SuppressWarnings("unused") @Shared @Cached CoerceToComplexNode coerceYToComplex, + @Bind PythonLanguage language) { + return log(coerceXToComplex.execute(frame, inliningTarget, xObj), language); } @Specialization(guards = "!isNoValue(yObj)") @@ -473,20 +474,20 @@ PComplex doGeneral(VirtualFrame frame, Object xObj, Object yObj, @Shared @Cached CoerceToComplexNode coerceXToComplex, @Shared @Cached CoerceToComplexNode coerceYToComplex, @Shared @Cached ComplexBuiltins.DivNode divNode, - @Shared @Cached PythonObjectFactory factory) { - PComplex x = log(coerceXToComplex.execute(frame, inliningTarget, xObj), factory); - PComplex y = log(coerceYToComplex.execute(frame, inliningTarget, yObj), factory); + @Bind PythonLanguage language) { + PComplex x = log(coerceXToComplex.execute(frame, inliningTarget, xObj), language); + PComplex y = log(coerceYToComplex.execute(frame, inliningTarget, yObj), language); return divNode.executeComplex(frame, x, y); } - private PComplex log(PComplex z, PythonObjectFactory factory) { - PComplex r = specialValue(factory, SPECIAL_VALUES, z.getReal(), z.getImag()); + private PComplex log(PComplex z, PythonLanguage language) { + PComplex r = specialValue(language, SPECIAL_VALUES, z.getReal(), z.getImag()); if (r != null) { return r; } double real = computeRealPart(z.getReal(), z.getImag()); double imag = Math.atan2(z.getImag(), z.getReal()); - return factory.createComplex(real, imag); + return PFactory.createComplex(language, real, imag); } @TruffleBoundary @@ -502,7 +503,7 @@ private double computeRealPart(double real, double imag) { final double scaleUp = 0x1.0p53; return Math.log(Math.hypot(ax * scaleUp, ay * scaleUp)) - 53 * LN_2; } - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); } double h = Math.hypot(ax, ay); if (0.71 <= h && h <= 1.73) { @@ -515,7 +516,7 @@ private double computeRealPart(double real, double imag) { } @Builtin(name = "log10", minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(MathGuards.class) @GenerateNodeFactory abstract static class Log10Node extends PythonUnaryBuiltinNode { @@ -523,17 +524,17 @@ abstract static class Log10Node extends PythonUnaryBuiltinNode { @Specialization PComplex doComplex(VirtualFrame frame, PComplex z, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { PComplex r = logNode.executeComplex(frame, z, PNone.NO_VALUE); - return factory.createComplex(r.getReal() / LN_10, r.getImag() / LN_10); + return PFactory.createComplex(language, r.getReal() / LN_10, r.getImag() / LN_10); } @Specialization PComplex doGeneral(VirtualFrame frame, Object zObj, @Bind("this") Node inliningTarget, @Cached CoerceToComplexNode coerceXToComplex, - @Shared @Cached PythonObjectFactory factory) { - return doComplex(frame, coerceXToComplex.execute(frame, inliningTarget, zObj), factory); + @Bind PythonLanguage language) { + return doComplex(frame, coerceXToComplex.execute(frame, inliningTarget, zObj), language); } } @@ -561,7 +562,7 @@ static PComplex doIt(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, SqrtNode::compute); } - static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode.Lazy raiseNode) { + static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode raiseNode) { ComplexValue result = specialValue(SPECIAL_VALUES, real, imag); if (result != null) { return result; @@ -615,7 +616,7 @@ static PComplex doIt(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, AcosNode::compute); } - static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode.Lazy raiseNode) { + static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode raiseNode) { ComplexValue result = specialValue(SPECIAL_VALUES, real, imag); if (result != null) { return result; @@ -665,7 +666,7 @@ static PComplex doIt(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, AcoshNode::compute); } - static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode.Lazy raiseNode) { + static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode raiseNode) { ComplexValue result = specialValue(SPECIAL_VALUES, real, imag); if (result != null) { return result; @@ -696,7 +697,7 @@ static PComplex doIt(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, AsinNode::compute); } - static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode.Lazy raiseNode) { + static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode raiseNode) { ComplexValue s = AsinhNode.compute(inliningTarget, -imag, real, raiseNode); return new ComplexValue(s.imag, -s.real); } @@ -726,7 +727,7 @@ static PComplex doIt(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, AsinhNode::compute); } - static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode.Lazy raiseNode) { + static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode raiseNode) { ComplexValue result = specialValue(SPECIAL_VALUES, real, imag); if (result != null) { return result; @@ -762,7 +763,7 @@ static PComplex doIt(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, AtanNode::compute); } - static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode.Lazy raiseNode) { + static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode raiseNode) { ComplexValue s = AtanhNode.compute(inliningTarget, -imag, real, raiseNode); return new ComplexValue(s.imag, -s.real); } @@ -795,7 +796,7 @@ static PComplex doIt(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, AtanhNode::compute); } - static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode.Lazy raiseNode) { + static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode raiseNode) { ComplexValue result = specialValue(SPECIAL_VALUES, real, imag); if (result != null) { return result; @@ -806,7 +807,7 @@ static ComplexValue compute(Node inliningTarget, double real, double imag, PRais return computeWithRealPositive(inliningTarget, real, imag, 1.0, raiseNode); } - private static ComplexValue computeWithRealPositive(Node inliningTarget, double real, double imag, double resultScale, PRaiseNode.Lazy raiseNode) { + private static ComplexValue computeWithRealPositive(Node inliningTarget, double real, double imag, double resultScale, PRaiseNode raiseNode) { double rreal; double rimag; double ay = Math.abs(imag); @@ -816,7 +817,7 @@ private static ComplexValue computeWithRealPositive(Node inliningTarget, double rimag = -Math.copySign(Math.PI / 2.0, -imag); } else if (real == 1.0 && ay < CM_SQRT_DBL_MIN) { if (ay == 0.0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MATH_DOMAIN_ERROR); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); } rreal = -Math.log(Math.sqrt(ay) / Math.sqrt(Math.hypot(ay, 2.0))); rimag = Math.copySign(Math.atan2(2.0, -ay) / 2, imag); @@ -852,7 +853,7 @@ static PComplex doIt(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, ExpNode::compute); } - static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode.Lazy raiseNode) { + static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode raiseNode) { if (!Double.isFinite(real) || !Double.isFinite(imag)) { ComplexValue r; if (Double.isInfinite(real) && Double.isFinite(imag) && imag != 0.0) { @@ -865,7 +866,7 @@ static ComplexValue compute(Node inliningTarget, double real, double imag, PRais r = specialValue(SPECIAL_VALUES, real, imag); } if (Double.isInfinite(imag) && (Double.isFinite(real) || (Double.isInfinite(real) && real > 0))) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MATH_DOMAIN_ERROR); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); } return r; } @@ -881,7 +882,7 @@ static ComplexValue compute(Node inliningTarget, double real, double imag, PRais rimag = l * Math.sin(imag); } if (Double.isInfinite(rreal) || Double.isInfinite(rimag)) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.MATH_RANGE_ERROR); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.MATH_RANGE_ERROR); } return new ComplexValue(rreal, rimag); } @@ -898,7 +899,7 @@ static PComplex doIt(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, CosNode::compute); } - static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode.Lazy raiseNode) { + static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode raiseNode) { return CoshNode.compute(inliningTarget, -imag, real, raiseNode); } } @@ -927,10 +928,10 @@ static PComplex doIt(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, CoshNode::compute); } - static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode.Lazy raiseNode) { + static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode raiseNode) { if (!Double.isFinite(real) || !Double.isFinite(imag)) { if (Double.isInfinite(imag) && !Double.isNaN(real)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MATH_DOMAIN_ERROR); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); } if (Double.isInfinite(real) && Double.isFinite(imag) && imag != 0.0) { double r = Math.copySign(INF, Math.sin(imag)); @@ -950,7 +951,7 @@ static ComplexValue compute(Node inliningTarget, double real, double imag, PRais rimag = Math.sin(imag) * Math.sinh(real); } if (Double.isInfinite(rreal) || Double.isInfinite(rimag)) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.MATH_RANGE_ERROR); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.MATH_RANGE_ERROR); } return new ComplexValue(rreal, rimag); } @@ -967,7 +968,7 @@ static PComplex doIt(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, SinNode::compute); } - static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode.Lazy raiseNode) { + static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode raiseNode) { ComplexValue s = SinhNode.compute(inliningTarget, -imag, real, raiseNode); return new ComplexValue(s.imag, -s.real); } @@ -997,10 +998,10 @@ static PComplex doIt(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, SinhNode::compute); } - static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode.Lazy raiseNode) { + static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode raiseNode) { if (!Double.isFinite(real) || !Double.isFinite(imag)) { if (Double.isInfinite(imag) && !Double.isNaN(real)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MATH_DOMAIN_ERROR); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); } if (Double.isInfinite(real) && Double.isFinite(imag) && imag != 0.0) { double r = Math.copySign(INF, Math.cos(imag)); @@ -1020,7 +1021,7 @@ static ComplexValue compute(Node inliningTarget, double real, double imag, PRais rimag = Math.sin(imag) * Math.cosh(real); } if (Double.isInfinite(rreal) || Double.isInfinite(rimag)) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.MATH_RANGE_ERROR); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.MATH_RANGE_ERROR); } return new ComplexValue(rreal, rimag); } @@ -1037,7 +1038,7 @@ static PComplex doIt(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, TanNode::compute); } - static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode.Lazy raiseNode) { + static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode raiseNode) { ComplexValue s = TanhNode.compute(inliningTarget, -imag, real, raiseNode); return new ComplexValue(s.imag, -s.real); } @@ -1067,10 +1068,10 @@ static PComplex doIt(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, TanhNode::compute); } - static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode.Lazy raiseNode) { + static ComplexValue compute(Node inliningTarget, double real, double imag, PRaiseNode raiseNode) { if (!Double.isFinite(real) || !Double.isFinite(imag)) { if (Double.isInfinite(imag) && Double.isFinite(real)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MATH_DOMAIN_ERROR); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); } if (Double.isInfinite(real) && Double.isFinite(imag) && imag != 0.0) { return new ComplexValue(real > 0 ? 1.0 : -1.0, Math.copySign(0.0, 2.0 * Math.sin(imag) * Math.cos(imag))); @@ -1091,8 +1092,8 @@ static ComplexValue compute(Node inliningTarget, double real, double imag, PRais } } - @Builtin(name = "isclose", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 2, varArgsMarker = true, keywordOnlyNames = {"rel_tol", "abs_tol"}) - @TypeSystemReference(PythonArithmeticTypes.class) + @Builtin(name = "isclose", minNumOfPositionalArgs = 2, parameterNames = {"a", "b"}, keywordOnlyNames = {"rel_tol", "abs_tol"}) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(MathGuards.class) @GenerateNodeFactory abstract static class IsCloseNode extends PythonBuiltinNode { @@ -1103,20 +1104,18 @@ abstract static class IsCloseNode extends PythonBuiltinNode { @Specialization static boolean doCCDD(PComplex a, PComplex b, double relTolObj, double absTolObj, @Bind("this") Node inliningTarget, - @Shared @Cached PythonObjectFactory factory, @Shared @Cached AbsNode absNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - return isClose(inliningTarget, a, b, relTolObj, absTolObj, factory, absNode, raiseNode); + @Shared @Cached PRaiseNode raiseNode) { + return isClose(inliningTarget, a, b, relTolObj, absTolObj, absNode, raiseNode); } @Specialization @SuppressWarnings("unused") static boolean doCCNN(PComplex a, PComplex b, PNone relTolObj, PNone absTolObj, @Bind("this") Node inliningTarget, - @Shared @Cached PythonObjectFactory factory, @Shared @Cached AbsNode absNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - return isClose(inliningTarget, a, b, DEFAULT_REL_TOL, DEFAULT_ABS_TOL, factory, absNode, raiseNode); + @Shared @Cached PRaiseNode raiseNode) { + return isClose(inliningTarget, a, b, DEFAULT_REL_TOL, DEFAULT_ABS_TOL, absNode, raiseNode); } @Specialization @@ -1126,19 +1125,18 @@ static boolean doGeneral(VirtualFrame frame, Object aObj, Object bObj, Object re @Cached CoerceToComplexNode coerceBToComplex, @Cached PyFloatAsDoubleNode relAsDoubleNode, @Cached PyFloatAsDoubleNode absAsDoubleNode, - @Shared @Cached PythonObjectFactory factory, @Shared @Cached AbsNode absNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { PComplex a = coerceAToComplex.execute(frame, inliningTarget, aObj); PComplex b = coerceBToComplex.execute(frame, inliningTarget, bObj); double relTol = PGuards.isNoValue(relTolObj) ? DEFAULT_REL_TOL : relAsDoubleNode.execute(frame, inliningTarget, relTolObj); double absTol = PGuards.isPNone(absTolObj) ? DEFAULT_ABS_TOL : absAsDoubleNode.execute(frame, inliningTarget, absTolObj); - return isClose(inliningTarget, a, b, relTol, absTol, factory, absNode, raiseNode); + return isClose(inliningTarget, a, b, relTol, absTol, absNode, raiseNode); } - private static boolean isClose(Node inliningTarget, PComplex a, PComplex b, double relTol, double absTol, PythonObjectFactory factory, AbsNode absNode, PRaiseNode.Lazy raiseNode) { + private static boolean isClose(Node inliningTarget, PComplex a, PComplex b, double relTol, double absTol, AbsNode absNode, PRaiseNode raiseNode) { if (relTol < 0.0 || absTol < 0.0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.TOLERANCE_MUST_NON_NEGATIVE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.TOLERANCE_MUST_NON_NEGATIVE); } if (a.getReal() == b.getReal() && a.getImag() == b.getImag()) { return true; @@ -1147,7 +1145,7 @@ private static boolean isClose(Node inliningTarget, PComplex a, PComplex b, doub Double.isInfinite(b.getReal()) || Double.isInfinite(b.getImag())) { return false; } - PComplex diff = factory.createComplex(a.getReal() - b.getReal(), a.getImag() - b.getImag()); + PComplex diff = PFactory.createComplex(PythonLanguage.get(inliningTarget), a.getReal() - b.getReal(), a.getImag() - b.getImag()); double len = absNode.executeDouble(diff); return len <= absTol || len <= relTol * absNode.executeDouble(b) || len <= relTol * absNode.executeDouble(a); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CodecsModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CodecsModuleBuiltins.java index a24567c5a2..efa6107b20 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CodecsModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CodecsModuleBuiltins.java @@ -96,6 +96,7 @@ import java.nio.charset.CodingErrorAction; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -136,7 +137,6 @@ import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode; import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryBuiltinNode; @@ -151,7 +151,7 @@ import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.CharsetMapping; @@ -221,7 +221,7 @@ static void handle(Node inliningTarget, TruffleEncoder encoder, TruffleString er @Cached InlinedConditionProfile surrogatepassProfile, @Cached InlinedConditionProfile surrogateescapeProfile, @Cached InlinedConditionProfile xmlcharrefreplaceProfile, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached(inline = false) TruffleString.EqualNode equalNode, // TODO: (blocked by GR-46101) make this CallNode.Lazy @Cached(inline = false) CallNode lazyCallNode) { @@ -239,24 +239,24 @@ static void handle(Node inliningTarget, TruffleEncoder encoder, TruffleString er } else if (xmlcharrefreplaceProfile.profile(inliningTarget, equalNode.execute(T_XMLCHARREFREPLACE, errorAction, TS_ENCODING))) { fixed = xmlcharrefreplace(encoder); } else { - throw raiseNode.get(inliningTarget).raise(LookupError, ErrorMessages.UNKNOWN_ERROR_HANDLER, errorAction); + throw raiseNode.raise(inliningTarget, LookupError, ErrorMessages.UNKNOWN_ERROR_HANDLER, errorAction); } } catch (OutOfMemoryError e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); } if (!fixed) { int start = encoder.getInputPosition(); int end = start + encoder.getErrorLength(); Object exception = lazyCallNode.executeWithoutFrame(UnicodeEncodeError, encoder.getEncodingName(), inputObject, start, end, encoder.getErrorReason()); if (exception instanceof PBaseException) { - throw raiseNode.get(inliningTarget).raiseExceptionObject((PBaseException) exception); + throw raiseNode.raiseExceptionObject(inliningTarget, (PBaseException) exception); } else { // Shouldn't happen unless the user manually replaces the method, which is // really // unexpected and shouldn't be permitted at all, but currently it is CompilerDirectives.transferToInterpreterAndInvalidate(); - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.SHOULD_HAVE_RETURNED_EXCEPTION, UnicodeEncodeError, exception); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.SHOULD_HAVE_RETURNED_EXCEPTION, UnicodeEncodeError, exception); } } } @@ -367,7 +367,7 @@ public Object raise(Node inliningTarget, TruffleDecoder decoder, Object inputObj @Specialization static Object doRaise(Node inliningTarget, TruffleDecoder decoder, Object inputObject, boolean justMakeExcept, @Cached(inline = false) CallNode callNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int start = decoder.getInputPosition(); int end = start + decoder.getErrorLength(); Object exception = callNode.executeWithoutFrame(UnicodeDecodeError, decoder.getEncodingName(), inputObject, start, end, decoder.getErrorReason()); @@ -375,12 +375,12 @@ static Object doRaise(Node inliningTarget, TruffleDecoder decoder, Object inputO return exception; } if (exception instanceof PBaseException) { - throw raiseNode.get(inliningTarget).raiseExceptionObject(exception); + throw raiseNode.raiseExceptionObject(inliningTarget, exception); } else { // Shouldn't happen unless the user manually replaces the method, which is really // unexpected and shouldn't be permitted at all, but currently it is CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, TypeError, ErrorMessages.SHOULD_HAVE_RETURNED_EXCEPTION, UnicodeDecodeError, exception); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.SHOULD_HAVE_RETURNED_EXCEPTION, UnicodeDecodeError, exception); } } } @@ -440,7 +440,7 @@ void doBackslashreplace(TruffleDecoder decoder, @SuppressWarnings("unused") Truf } } catch (OutOfMemoryError e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - PRaiseNode.raiseUncached(this, MemoryError); + PRaiseNode.raiseStatic(this, MemoryError); } } @@ -456,7 +456,7 @@ static void doSurrogatepass(TruffleDecoder decoder, @SuppressWarnings("unused") } } catch (OutOfMemoryError e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); } } @@ -471,7 +471,7 @@ static void doSurrogateescape(TruffleDecoder decoder, @SuppressWarnings("unused" } } catch (OutOfMemoryError e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); } } @@ -486,23 +486,23 @@ static void doCustom(VirtualFrame frame, TruffleDecoder decoder, TruffleString e @Cached PyLongAsIntNode asIntNode, @Exclusive @Cached RaiseDecodingErrorNode raiseDecodingErrorNode, @Cached PyCodecLookupErrorNode lookupErrorNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { Object errorHandler = lookupErrorNode.execute(inliningTarget, errorAction); if (errorHandler == null) { - throw raiseNode.get(inliningTarget).raise(LookupError, UNKNOWN_ERROR_HANDLER, errorAction); + throw raiseNode.raise(inliningTarget, LookupError, UNKNOWN_ERROR_HANDLER, errorAction); } Object exceptionObject = raiseDecodingErrorNode.makeDecodeException(inliningTarget, decoder, inputObject); Object restuple = callNode.execute(frame, errorHandler, exceptionObject); if (!PGuards.isPTuple(restuple)) { - throw raiseNode.get(inliningTarget).raise(TypeError, DECODING_ERROR_HANDLER_MUST_RETURN_STR_INT_TUPLE); + throw raiseNode.raise(inliningTarget, TypeError, DECODING_ERROR_HANDLER_MUST_RETURN_STR_INT_TUPLE); } SequenceStorage storage = ((PTuple) restuple).getSequenceStorage(); Object[] t = getArray.execute(inliningTarget, storage); if (storage.length() != 2) { - throw raiseNode.get(inliningTarget).raise(TypeError, DECODING_ERROR_HANDLER_MUST_RETURN_STR_INT_TUPLE); + throw raiseNode.raise(inliningTarget, TypeError, DECODING_ERROR_HANDLER_MUST_RETURN_STR_INT_TUPLE); } int newpos = asIntNode.execute(null, inliningTarget, t[1]); /*- Copy back the bytes variables, which might have been modified by the callback */ @@ -516,16 +516,16 @@ static void doCustom(VirtualFrame frame, TruffleDecoder decoder, TruffleString e newpos = insize + newpos; } if (newpos < 0 || newpos > insize) { - throw raiseNode.get(inliningTarget).raise(IndexError, POSITION_D_FROM_ERROR_HANDLER_OUT_OF_BOUNDS, newpos); + throw raiseNode.raise(inliningTarget, IndexError, POSITION_D_FROM_ERROR_HANDLER_OUT_OF_BOUNDS, newpos); } if (!custom(decoder, input, insize, newpos)) { - throw raiseNode.get(inliningTarget).raise(SystemError); + throw raiseNode.raise(inliningTarget, SystemError); } } catch (OutOfMemoryError e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); } } @@ -607,14 +607,14 @@ byte[] encode(Object self, TruffleString encoding, TruffleString errors, @Cached CastToJavaStringNode castStr, @Cached TruffleString.EqualNode equalNode, @Cached HandleEncodingErrorNode errorHandler, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached NormalizeEncodingNameNode normalizeEncodingNameNode) { String input = castStr.execute(self); CodingErrorAction errorAction = convertCodingErrorAction(errors, equalNode); TruffleString normalizedEncoding = normalizeEncodingNameNode.execute(inliningTarget, encoding); Charset charset = CharsetMapping.getCharsetNormalized(normalizedEncoding); if (charset == null) { - throw raiseNode.get(inliningTarget).raise(LookupError, ErrorMessages.UNKNOWN_ENCODING, encoding); + throw raiseNode.raise(inliningTarget, LookupError, ErrorMessages.UNKNOWN_ENCODING, encoding); } TruffleEncoder encoder; try { @@ -624,7 +624,7 @@ byte[] encode(Object self, TruffleString encoding, TruffleString errors, } } catch (OutOfMemoryError e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(this, MemoryError); + throw PRaiseNode.raiseStatic(this, MemoryError); } return encoder.getBytes(); } @@ -646,20 +646,19 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(guards = {"isString(self)"}) static Object encode(Object self, TruffleString encoding, TruffleString errors, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached CastToTruffleStringNode castStr, @Cached TruffleString.CodePointLengthNode codePointLengthNode, - @Cached CodecsEncodeToJavaBytesNode encode, - @Cached PythonObjectFactory factory) { + @Cached CodecsEncodeToJavaBytesNode encode) { TruffleString input = castStr.execute(inliningTarget, self); - PBytes bytes = factory.createBytes(encode.execute(self, encoding, errors)); - return factory.createTuple(new Object[]{bytes, codePointLengthNode.execute(input, TS_ENCODING)}); + PBytes bytes = PFactory.createBytes(language, encode.execute(self, encoding, errors)); + return PFactory.createTuple(language, new Object[]{bytes, codePointLengthNode.execute(input, TS_ENCODING)}); } @Fallback static Object encode(Object str, @SuppressWarnings("unused") Object encoding, @SuppressWarnings("unused") Object errors, - @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANT_CONVERT_TO_STR_IMPLICITLY, str); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CANT_CONVERT_TO_STR_IMPLICITLY, str); } } @@ -683,6 +682,7 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(limit = "3") static Object decode(VirtualFrame frame, Object input, TruffleString encoding, TruffleString errors, boolean finalData, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("input") PythonBufferAcquireLibrary acquireLib, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @@ -690,8 +690,7 @@ static Object decode(VirtualFrame frame, Object input, TruffleString encoding, T @Cached NormalizeEncodingNameNode normalizeEncodingNameNode, @Cached InternErrorAction internErrorAction, @Cached HandleDecodingErrorNode errorHandler, - @Cached PRaiseNode raiseNode, - @Cached PythonObjectFactory factory) { + @Cached PRaiseNode raiseNode) { Object buffer = acquireLib.acquireReadonly(input, frame, indirectCallData); try { int len = bufferLib.getBufferLength(buffer); @@ -700,19 +699,19 @@ static Object decode(VirtualFrame frame, Object input, TruffleString encoding, T TruffleString normalizedEncoding = normalizeEncodingNameNode.execute(inliningTarget, encoding); Charset charset = CharsetMapping.getCharsetForDecodingNormalized(normalizedEncoding, bytes, len); if (charset == null) { - throw raiseNode.raise(LookupError, ErrorMessages.UNKNOWN_ENCODING, encoding); + throw raiseNode.raise(inliningTarget, LookupError, ErrorMessages.UNKNOWN_ENCODING, encoding); } TruffleDecoder decoder; try { decoder = new TruffleDecoder(normalizedEncoding, charset, bytes, len, errorAction); while (!decoder.decodingStep(finalData)) { - errorHandler.execute(frame, decoder, internErrorAction.execute(inliningTarget, errors), factory.createBytes(bytes, len)); + errorHandler.execute(frame, decoder, internErrorAction.execute(inliningTarget, errors), PFactory.createBytes(language, bytes, len)); } } catch (OutOfMemoryError e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw raiseNode.raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } - return factory.createTuple(new Object[]{decoder.getString(), decoder.getInputPosition()}); + return PFactory.createTuple(language, new Object[]{decoder.getString(), decoder.getInputPosition()}); } finally { bufferLib.release(buffer, frame, indirectCallData); } @@ -733,26 +732,26 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization Object decodeByteArray(byte[] bytes, TruffleString errors, - @Shared @Cached PythonObjectFactory factory) { - return decodeBytes(bytes, bytes.length, errors, factory); + @Bind PythonLanguage language) { + return decodeBytes(bytes, bytes.length, errors, language); } @Specialization(limit = "3") Object decode(VirtualFrame frame, Object buffer, TruffleString errors, + @Bind PythonLanguage language, @Cached("createFor(this)") IndirectCallData indirectCallData, - @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Shared @Cached PythonObjectFactory factory) { + @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib) { try { int len = bufferLib.getBufferLength(buffer); - return decodeBytes(bufferLib.getInternalOrCopiedByteArray(buffer), len, errors, factory); + return decodeBytes(bufferLib.getInternalOrCopiedByteArray(buffer), len, errors, language); } finally { bufferLib.release(buffer, frame, indirectCallData); } } - private Object decodeBytes(byte[] bytes, int len, TruffleString errors, PythonObjectFactory factory) { + private Object decodeBytes(byte[] bytes, int len, TruffleString errors, PythonLanguage language) { ByteArrayBuffer result = doDecode(bytes, len, errors); - return factory.createTuple(new Object[]{factory.createBytes(result.getInternalBytes(), result.getLength()), len}); + return PFactory.createTuple(language, new Object[]{PFactory.createBytes(language, result.getInternalBytes(), result.getLength()), len}); } @TruffleBoundary @@ -767,7 +766,7 @@ private ByteArrayBuffer doDecode(byte[] bytes, int bytesLen, TruffleString error i++; if (i >= bytesLen) { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.TRAILING_S_IN_STR, "\\"); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.TRAILING_S_IN_STR, "\\"); } chr = (char) bytes[i]; @@ -842,14 +841,14 @@ private ByteArrayBuffer doDecode(byte[] bytes, int bytesLen, TruffleString error } // invalid hexadecimal digits if (T_STRICT.equalsUncached(errors, TS_ENCODING)) { - throw PRaiseNode.raiseUncached(this, ValueError, INVALID_ESCAPE_AT, "\\x", i - 2); + throw PRaiseNode.raiseStatic(this, ValueError, INVALID_ESCAPE_AT, "\\x", i - 2); } if (T_REPLACE.equalsUncached(errors, TS_ENCODING)) { buffer.append('?'); } else if (T_IGNORE.equalsUncached(errors, TS_ENCODING)) { // do nothing } else { - throw PRaiseNode.raiseUncached(this, ValueError, ENCODING_ERROR_WITH_CODE, errors); + throw PRaiseNode.raiseStatic(this, ValueError, ENCODING_ERROR_WITH_CODE, errors); } // skip \x @@ -885,8 +884,8 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization Object encode(PBytes data, @SuppressWarnings("unused") TruffleString errors, @Bind("this") Node inliningTarget, - @Cached GetInternalByteArrayNode getInternalByteArrayNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language, + @Cached GetInternalByteArrayNode getInternalByteArrayNode) { byte[] bytes = getInternalByteArrayNode.execute(inliningTarget, data.getSequenceStorage()); int size = data.getSequenceStorage().length(); ByteArrayBuffer buffer = new ByteArrayBuffer(); @@ -917,16 +916,16 @@ Object encode(PBytes data, @SuppressWarnings("unused") TruffleString errors, } } - return factory.createTuple(new Object[]{ - factory.createBytes(buffer.getByteArray()), + return PFactory.createTuple(language, new Object[]{ + PFactory.createBytes(language, buffer.getByteArray()), size }); } @Fallback static Object encode(Object data, @SuppressWarnings("unused") Object errors, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, BYTESLIKE_OBJ_REQUIRED, data); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, BYTESLIKE_OBJ_REQUIRED, data); } } @@ -981,7 +980,7 @@ static PTuple lookup(VirtualFrame frame, Node inliningTarget, TruffleString enco @Cached InlinedConditionProfile hasTruffleEncodingProfile, @Cached InlinedConditionProfile isTupleProfile, @Cached NormalizeEncodingNameNode normalizeEncodingNameNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleString normalizedEncoding = normalizeEncodingNameNode.execute(inliningTarget, encoding); PythonContext context = PythonContext.get(inliningTarget); ensureRegistryInitialized(context); @@ -991,14 +990,14 @@ static PTuple lookup(VirtualFrame frame, Node inliningTarget, TruffleString enco } if (hasTruffleEncodingProfile.profile(inliningTarget, hasTruffleEncodingNormalized(normalizedEncoding))) { PythonModule codecs = context.lookupBuiltinModule(T__CODECS_TRUFFLE); - result = CodecsTruffleModuleBuiltins.codecsInfo(codecs, encoding, context, context.factory()); + result = CodecsTruffleModuleBuiltins.codecsInfo(codecs, encoding, context); } else { Object[] searchPaths = getSearchPaths(context); for (Object func : searchPaths) { Object obj = callNode.executeObject(func, normalizedEncoding); if (obj != PNone.NONE) { if (isTupleProfile.profile(inliningTarget, !isTupleInstanceCheck(frame, inliningTarget, obj, 4, typeCheck, sizeNode))) { - throw raiseNode.get(inliningTarget).raise(TypeError, CODEC_SEARCH_MUST_RETURN_4); + throw raiseNode.raise(inliningTarget, TypeError, CODEC_SEARCH_MUST_RETURN_4); } result = (PTuple) obj; break; @@ -1009,7 +1008,7 @@ static PTuple lookup(VirtualFrame frame, Node inliningTarget, TruffleString enco putSearchPath(context, normalizedEncoding, result); return result; } - throw raiseNode.get(inliningTarget).raise(LookupError, UNKNOWN_ENCODING, encoding); + throw raiseNode.raise(inliningTarget, LookupError, UNKNOWN_ENCODING, encoding); } @TruffleBoundary @@ -1044,14 +1043,14 @@ abstract static class RegisterNode extends PythonUnaryBuiltinNode { static Object lookup(Object searchFunction, @Bind("this") Node inliningTarget, @Cached PyCallableCheckNode callableCheckNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (callableCheckNode.execute(inliningTarget, searchFunction)) { PythonContext context = PythonContext.get(inliningTarget); ensureRegistryInitialized(context); add(context, searchFunction); return PNone.NONE; } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ARG_MUST_BE_CALLABLE); + throw raiseNode.raise(inliningTarget, TypeError, ARG_MUST_BE_CALLABLE); } } @@ -1156,11 +1155,11 @@ static Object encode(VirtualFrame frame, Object obj, TruffleString encoding, Tru @Cached PyObjectSizeNode sizeNode, @Cached PyObjectTypeCheck typeCheck, @Cached InlinedConditionProfile isTupleProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object encoder = CodecsModuleBuiltins.encoder(frame, encoding, lookupNode, getItemNode); Object result = callEncoderNode.executeObject(encoder, obj, errors); if (isTupleProfile.profile(inliningTarget, !isTupleInstanceCheck(frame, inliningTarget, result, 2, typeCheck, sizeNode))) { - throw raiseNode.get(inliningTarget).raise(TypeError, S_MUST_RETURN_TUPLE, "encoder"); + throw raiseNode.raise(inliningTarget, TypeError, S_MUST_RETURN_TUPLE, "encoder"); } return getResultItemNode.execute(((PTuple) result).getSequenceStorage(), 0); } @@ -1189,11 +1188,11 @@ static Object decode(VirtualFrame frame, Object obj, TruffleString encoding, Tru @Cached PyObjectSizeNode sizeNode, @Cached PyObjectTypeCheck typeCheck, @Cached InlinedConditionProfile isTupleProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object decoder = CodecsModuleBuiltins.decoder(frame, encoding, lookupNode, getItemNode); Object result = callEncoderNode.executeObject(decoder, obj, errors); if (isTupleProfile.profile(inliningTarget, !isTupleInstanceCheck(frame, inliningTarget, result, 2, typeCheck, sizeNode))) { - throw raiseNode.get(inliningTarget).raise(TypeError, S_MUST_RETURN_TUPLE, "decoder"); + throw raiseNode.raise(inliningTarget, TypeError, S_MUST_RETURN_TUPLE, "decoder"); } return getResultItemNode.execute(((PTuple) result).getSequenceStorage(), 0); } @@ -1318,8 +1317,8 @@ abstract static class UTF16EXDecodeNode extends PythonQuaternaryBuiltinNode { @SuppressWarnings("unused") @Specialization static Object encode(VirtualFrame frame, Object obj, Object errors, Object byteorder, Object ffinal, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(NotImplementedError, toTruffleStringUncached("utf_16_ex_decode")); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, toTruffleStringUncached("utf_16_ex_decode")); } } @@ -1390,7 +1389,7 @@ abstract static class UTF32EXDecodeNode extends PythonQuaternaryBuiltinNode { @Specialization @TruffleBoundary Object encode(Object obj, Object errors, Object byteorder, Object ffinal) { - throw PRaiseNode.raiseUncached(this, NotImplementedError, toTruffleStringUncached("utf_32_ex_decode")); + throw PRaiseNode.raiseStatic(this, NotImplementedError, toTruffleStringUncached("utf_32_ex_decode")); } } @@ -1401,7 +1400,7 @@ abstract static class UnicodeInternalEncodeNode extends PythonBinaryBuiltinNode @Specialization @TruffleBoundary Object encode(Object obj, Object errors) { - throw PRaiseNode.raiseUncached(this, NotImplementedError, toTruffleStringUncached("unicode_internal_encode")); + throw PRaiseNode.raiseStatic(this, NotImplementedError, toTruffleStringUncached("unicode_internal_encode")); } } @@ -1412,7 +1411,7 @@ abstract static class UnicodeInternalDecodeNode extends PythonBinaryBuiltinNode @Specialization @TruffleBoundary Object encode(Object obj, Object errors) { - throw PRaiseNode.raiseUncached(this, NotImplementedError, toTruffleStringUncached("unicode_internal_decode")); + throw PRaiseNode.raiseStatic(this, NotImplementedError, toTruffleStringUncached("unicode_internal_decode")); } } @@ -1510,12 +1509,12 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization Object doIt(VirtualFrame frame, TruffleString str, TruffleString errors, Object mapping, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached TruffleString.CodePointLengthNode codePointLengthNode, - @Cached PyUnicodeEncodeCharmapNode encodeCharmapNode, - @Cached PythonObjectFactory factory) { + @Cached PyUnicodeEncodeCharmapNode encodeCharmapNode) { int len = codePointLengthNode.execute(str, TS_ENCODING); - PBytes result = factory.createBytes(encodeCharmapNode.execute(frame, inliningTarget, str, errors, mapping)); - return factory.createTuple(new Object[]{result, len}); + PBytes result = PFactory.createBytes(language, encodeCharmapNode.execute(frame, inliningTarget, str, errors, mapping)); + return PFactory.createTuple(language, new Object[]{result, len}); } } @@ -1536,8 +1535,7 @@ Object doIt(VirtualFrame frame, Object data, TruffleString errors, Object mappin @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("data") PythonBufferAcquireLibrary bufferAcquireLib, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached PyUnicodeDecodeCharmapNode pyUnicodeDecodeCharmapNode, - @Cached PythonObjectFactory factory) { + @Cached PyUnicodeDecodeCharmapNode pyUnicodeDecodeCharmapNode) { Object dataBuffer = bufferAcquireLib.acquireReadonly(data, frame, context, context.getLanguage(inliningTarget), indirectCallData); int len; try { @@ -1546,7 +1544,7 @@ Object doIt(VirtualFrame frame, Object data, TruffleString errors, Object mappin bufferLib.release(dataBuffer, frame, indirectCallData); } TruffleString result = len == 0 ? T_EMPTY_STRING : pyUnicodeDecodeCharmapNode.execute(frame, data, errors, mapping); - return factory.createTuple(new Object[]{result, len}); + return PFactory.createTuple(context.getLanguage(inliningTarget), new Object[]{result, len}); } } @@ -1557,7 +1555,7 @@ abstract static class ReadbufferEncodeNode extends PythonBinaryBuiltinNode { @Specialization @TruffleBoundary Object encode(Object obj, Object errors) { - throw PRaiseNode.raiseUncached(this, NotImplementedError, toTruffleStringUncached("readbuffer_encode")); + throw PRaiseNode.raiseStatic(this, NotImplementedError, toTruffleStringUncached("readbuffer_encode")); } } @@ -1593,7 +1591,7 @@ abstract static class OEMEncodeNode extends PythonBinaryBuiltinNode { @Specialization @TruffleBoundary Object encode(Object obj, Object errors) { - throw PRaiseNode.raiseUncached(this, NotImplementedError, toTruffleStringUncached("oem_encode")); + throw PRaiseNode.raiseStatic(this, NotImplementedError, toTruffleStringUncached("oem_encode")); } } @@ -1603,8 +1601,8 @@ abstract static class OEMDecodeNode extends PythonTernaryBuiltinNode { @SuppressWarnings("unused") @Specialization static Object decode(Object obj, Object errors, Object ffinal, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(NotImplementedError, toTruffleStringUncached("oem_decode")); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, toTruffleStringUncached("oem_decode")); } } @@ -1614,8 +1612,8 @@ abstract static class CodePageEncodeNode extends PythonTernaryBuiltinNode { @SuppressWarnings("unused") @Specialization static Object encode(Object code_page, Object string, Object errors, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(NotImplementedError, toTruffleStringUncached("code_page_encode")); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, toTruffleStringUncached("code_page_encode")); } } @@ -1625,8 +1623,8 @@ abstract static class CodePageDecodeNode extends PythonQuaternaryBuiltinNode { @SuppressWarnings("unused") @Specialization static Object decode(Object code_page, Object obj, Object errors, Object ffinal, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(NotImplementedError, toTruffleStringUncached("code_page_decode")); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, toTruffleStringUncached("code_page_decode")); } } @@ -1648,17 +1646,6 @@ Object doIt(VirtualFrame frame, TruffleString map, } } - @Builtin(name = "EncodingMap", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PEncodingMap, isPublic = false) - @GenerateNodeFactory - abstract static class EncodingMapNode extends PythonBuiltinNode { - @Specialization - @SuppressWarnings("unused") - static Object encodingMap(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "EncodingMap"); - } - } - static class TruffleEncoder { private final TruffleString encodingName; private final CharsetEncoder encoder; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CodecsTruffleModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CodecsTruffleModuleBuiltins.java index ef4afc8854..450d2465f5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CodecsTruffleModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CodecsTruffleModuleBuiltins.java @@ -53,7 +53,6 @@ import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T_DECODE; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INIT__; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import java.util.ArrayList; @@ -80,7 +79,10 @@ import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; import com.oracle.graal.python.builtins.objects.type.PythonClass; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotVarargs; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.lib.PyObjectSetAttr; @@ -91,7 +93,6 @@ import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; @@ -99,7 +100,7 @@ import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; import com.oracle.graal.python.nodes.statement.AbstractImportNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -158,15 +159,13 @@ protected List> getNodeFa } private static PythonClass initClass(TruffleString className, TruffleString superClassName, BuiltinDescr[] descrs, PythonModule codecsTruffleModule, PythonModule codecsModule, - PythonLanguage language, - PythonObjectFactory factory) { + PythonLanguage language) { PythonAbstractClass superClass = (PythonAbstractClass) codecsModule.getAttribute(superClassName); - return initClass(className, superClass, descrs, codecsTruffleModule, language, factory); + return initClass(className, superClass, descrs, codecsTruffleModule, language); } - private static PythonClass initClass(TruffleString className, PythonAbstractClass superClass, BuiltinDescr[] descrs, PythonModule codecsTruffleModule, PythonLanguage language, - PythonObjectFactory factory) { - PythonClass clazz = factory.createPythonClassAndFixupSlots(language, PythonBuiltinClassType.PythonClass, className, superClass, new PythonAbstractClass[]{superClass}); + private static PythonClass initClass(TruffleString className, PythonAbstractClass superClass, BuiltinDescr[] descrs, PythonModule codecsTruffleModule, PythonLanguage language) { + PythonClass clazz = PFactory.createPythonClassAndFixupSlots(language, className, superClass, new PythonAbstractClass[]{superClass}); for (BuiltinDescr d : descrs) { PythonUtils.createMethod(language, clazz, d.nodeFactory(), d.enclosingType ? clazz : null, 1); } @@ -180,42 +179,47 @@ private record BuiltinDescr(NodeFactory nodeFac } @TruffleBoundary - static PTuple codecsInfo(PythonModule self, TruffleString encoding, PythonContext context, PythonObjectFactory factory) { + static PTuple codecsInfo(PythonModule self, TruffleString encoding, PythonContext context) { PythonModule codecsModule = AbstractImportNode.importModule(T_CODECS); CodecsTruffleModuleBuiltins codecsTruffleBuiltins = (CodecsTruffleModuleBuiltins) self.getBuiltins(); if (self.getAttribute(T_TRUFFLE_CODEC) instanceof PNone) { - initCodecClasses(self, codecsModule, context, factory); + initCodecClasses(self, codecsModule, context); } + PythonLanguage language = context.getLanguage(); // encode/decode methods for codecs.CodecInfo - PythonObject truffleCodec = factory.createPythonObject(codecsTruffleBuiltins.truffleCodecClass); + PythonObject truffleCodec = createPythonObject(language, codecsTruffleBuiltins.truffleCodecClass); truffleCodec.setAttribute(T_ATTR_ENCODING, encoding); Object encodeMethod = PyObjectGetAttr.executeUncached(truffleCodec, T_ENCODE); Object decodeMethod = PyObjectGetAttr.executeUncached(truffleCodec, T_DECODE); // incrementalencoder factory function for codecs.CodecInfo - PythonObject tie = factory.createPythonObject(codecsTruffleBuiltins.applyEncodingClass); + PythonObject tie = createPythonObject(language, codecsTruffleBuiltins.applyEncodingClass); tie.setAttribute(T_ATTR_FN, codecsTruffleBuiltins.truffleIncrementalEncoderClass); tie.setAttribute(T_ATTR_ENCODING, encoding); // incrementaldecoder factory function for codecs.CodecInfo - PythonObject tid = factory.createPythonObject(codecsTruffleBuiltins.applyEncodingClass); + PythonObject tid = createPythonObject(language, codecsTruffleBuiltins.applyEncodingClass); tid.setAttribute(T_ATTR_FN, codecsTruffleBuiltins.truffleIncrementalDecoderClass); tid.setAttribute(T_ATTR_ENCODING, encoding); // streamwriter factory function for codecs.CodecInfo - PythonObject sr = factory.createPythonObject(codecsTruffleBuiltins.applyEncodingClass); + PythonObject sr = createPythonObject(language, codecsTruffleBuiltins.applyEncodingClass); sr.setAttribute(T_ATTR_FN, codecsTruffleBuiltins.truffleStreamReaderClass); sr.setAttribute(T_ATTR_ENCODING, encoding); // streamreader factory function for codecs.CodecInfo - PythonObject sw = factory.createPythonObject(codecsTruffleBuiltins.applyEncodingClass); + PythonObject sw = createPythonObject(language, codecsTruffleBuiltins.applyEncodingClass); sw.setAttribute(T_ATTR_FN, codecsTruffleBuiltins.truffleStreamWriterClass); sw.setAttribute(T_ATTR_ENCODING, encoding); // codecs.CodecInfo PythonAbstractClass codecInfoClass = (PythonAbstractClass) codecsModule.getAttribute(T_CODEC_INFO_NAME); - return (PTuple) CallVarargsMethodNode.getUncached().execute(null, codecInfoClass, new Object[]{}, createCodecInfoArgs(encoding, encodeMethod, decodeMethod, tie, tid, sr, sw)); + return (PTuple) CallNode.getUncached().execute(null, codecInfoClass, new Object[]{}, createCodecInfoArgs(encoding, encodeMethod, decodeMethod, tie, tid, sr, sw)); + } + + private static PythonObject createPythonObject(PythonLanguage language, PythonClass cls) { + return PFactory.createPythonObject(language, cls, cls.getInstanceShape()); } private static PKeyword[] createCodecInfoArgs(TruffleString encoding, Object encodeMethod, Object decodeMethod, PythonObject tie, PythonObject tid, PythonObject sr, PythonObject sw) { @@ -234,7 +238,7 @@ private static PKeyword[] createCodecInfoArgs(TruffleString encoding, Object enc * create classes based on types declared in lib/3/codes.py */ // @formatter:off - private static void initCodecClasses(PythonModule codecsTruffleModule, PythonModule codecsModule, PythonContext context, PythonObjectFactory factory) { + private static void initCodecClasses(PythonModule codecsTruffleModule, PythonModule codecsModule, PythonContext context) { // TODO - the incremental codec and reader/writer won't work well with stateful // encodings, like some of the CJK encodings @@ -250,7 +254,7 @@ private static void initCodecClasses(PythonModule codecsTruffleModule, PythonMod new BuiltinDescr[]{ new BuiltinDescr(EncodeNodeFactory.getInstance(), false), new BuiltinDescr(CodecDecodeNodeFactory.getInstance(), true)}, - codecsTruffleModule, language, factory); + codecsTruffleModule, language); // class TruffleIncrementalEncoder(codecs.IncrementalEncoder): // def __init__(self, encoding, *args, **kwargs): @@ -262,7 +266,7 @@ private static void initCodecClasses(PythonModule codecsTruffleModule, PythonMod new BuiltinDescr[]{ new BuiltinDescr(CodecInitNodeFactory.getInstance(), false), new BuiltinDescr(IncrementalEncodeNodeFactory.getInstance(), true)}, - codecsTruffleModule, codecsModule, language, factory); + codecsTruffleModule, codecsModule, language); // class TruffleIncrementalDecoder(codecs.BufferedIncrementalDecoder): // def __init__(self, encoding, *args, **kwargs): @@ -274,7 +278,7 @@ private static void initCodecClasses(PythonModule codecsTruffleModule, PythonMod new BuiltinDescr[]{ new BuiltinDescr(CodecInitNodeFactory.getInstance(), false), new BuiltinDescr(IncrementalDecodeNodeFactory.getInstance(), true)}, - codecsTruffleModule, codecsModule, language, factory); + codecsTruffleModule, codecsModule, language); // class TruffleStreamWriter(codecs.StreamWriter): // def __init__(self, encoding, *args, **kwargs): @@ -286,7 +290,7 @@ private static void initCodecClasses(PythonModule codecsTruffleModule, PythonMod new BuiltinDescr[]{ new BuiltinDescr(CodecInitNodeFactory.getInstance(), false), new BuiltinDescr(EncodeNodeFactory.getInstance(), true)}, - codecsTruffleModule, codecsModule, language, factory); + codecsTruffleModule, codecsModule, language); // class TruffleStreamReader(codecs.StreamReader): // def __init__(self, encoding, *args, **kwargs): @@ -298,7 +302,7 @@ private static void initCodecClasses(PythonModule codecsTruffleModule, PythonMod new BuiltinDescr[]{ new BuiltinDescr(CodecInitNodeFactory.getInstance(), false), new BuiltinDescr(StreamDecodeNodeFactory.getInstance(), true)}, - codecsTruffleModule, codecsModule, language, factory); + codecsTruffleModule, codecsModule, language); // serves as factory function for CodecInfo-s incrementalencoder/decode and streamwriter/reader // class apply_encoding: @@ -306,7 +310,7 @@ private static void initCodecClasses(PythonModule codecsTruffleModule, PythonMod // return self.fn(self.encoding, *args, **kwargs) codecsTruffleBuiltins.applyEncodingClass = initClass(T_APPLY_ENCODING, context.lookupType(PythonBuiltinClassType.PythonObject), new BuiltinDescr[]{new BuiltinDescr(CallApplyNodeFactory.getInstance(), false)}, - codecsTruffleModule, language, factory); + codecsTruffleModule, language); } // @formatter:on @@ -314,22 +318,17 @@ private static void initCodecClasses(PythonModule codecsTruffleModule, PythonMod @GenerateNodeFactory protected abstract static class CodecInitNode extends PythonVarargsBuiltinNode { @Specialization - Object init(VirtualFrame frame, PythonObject self, Object[] args, PKeyword[] kw, + static Object init(VirtualFrame frame, PythonObject self, Object[] args, PKeyword[] kw, @Bind("this") Node inliningTarget, - @Cached PyObjectGetAttr getAttrNode, @Cached PyObjectSetAttr setAttrNode, @Cached GetPythonObjectClassNode getClass, @Cached GetBaseClassNode getBaseClassNode, - @Cached CallNode callNode) { + @Cached GetCachedTpSlotsNode getSlots, + @Cached TpSlotVarargs.CallSlotTpInitNode callInit) { assert args.length > 0; Object base = getBaseClassNode.execute(inliningTarget, getClass.execute(inliningTarget, self)); - Object superInit = getAttrNode.execute(frame, inliningTarget, base, T___INIT__); - Object[] callArgs = new Object[args.length]; - callArgs[0] = self; - if (args.length > 1) { - PythonUtils.arraycopy(args, 1, callArgs, 1, args.length - 1); - } - callNode.execute(frame, superInit, callArgs, kw); + TpSlots baseSlots = getSlots.execute(inliningTarget, base); + callInit.execute(frame, inliningTarget, baseSlots.tp_init(), self, PythonUtils.arrayCopyOfRange(args, 1, args.length), kw); setAttrNode.execute(frame, inliningTarget, self, T_ATTR_ENCODING, args[0]); return PNone.NONE; } @@ -342,7 +341,7 @@ protected abstract static class CallApplyNode extends PythonVarargsBuiltinNode { Object call(VirtualFrame frame, PythonObject self, Object[] args, PKeyword[] kw, @Bind("this") Node inliningTarget, @Cached PyObjectGetAttr getAttrNode, - @Cached CallVarargsMethodNode callNode) { + @Cached CallNode callNode) { Object[] callArgs = new Object[args.length + 1]; callArgs[0] = getAttrNode.execute(frame, inliningTarget, self, T_ATTR_ENCODING); PythonUtils.arraycopy(args, 0, callArgs, 1, args.length); @@ -429,7 +428,7 @@ Object lookup(VirtualFrame frame, TruffleString encoding, TruffleString alternat PTuple codecInfo = lookupNode.execute(frame, inliningTarget, encoding); Object isTextObj = getAttributeNode.execute(frame, inliningTarget, codecInfo, T_IS_TEXT_ENCODING); if (!((isTextObj instanceof Boolean) && (boolean) isTextObj)) { - throw raiseNode.raise(LookupError, IS_NOT_TEXT_ENCODING, encoding, alternateCommand); + throw raiseNode.raise(inliningTarget, LookupError, IS_NOT_TEXT_ENCODING, encoding, alternateCommand); } return codecInfo; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CollectionsModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CollectionsModuleBuiltins.java index 801772f68c..9866cf8ada 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CollectionsModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CollectionsModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,159 +40,18 @@ */ package com.oracle.graal.python.builtins.modules; -import static com.oracle.graal.python.nodes.BuiltinNames.J_DEFAULTDICT; -import static com.oracle.graal.python.nodes.BuiltinNames.J_DEQUE; -import static com.oracle.graal.python.nodes.BuiltinNames.J_DEQUE_ITER; -import static com.oracle.graal.python.nodes.BuiltinNames.J_DEQUE_REV_ITER; -import static com.oracle.graal.python.nodes.BuiltinNames.J_TUPLE_GETTER; - +import java.util.Collections; import java.util.List; -import com.oracle.graal.python.annotations.ArgumentClinic; -import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.deque.DequeIterBuiltins.DequeIterNextNode; -import com.oracle.graal.python.builtins.objects.deque.PDeque; -import com.oracle.graal.python.builtins.objects.deque.PDequeIter; -import com.oracle.graal.python.builtins.objects.dict.PDefaultDict; -import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.lib.PyNumberIndexNode; -import com.oracle.graal.python.nodes.BuiltinNames; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; @CoreFunctions(defineModule = "_collections") public final class CollectionsModuleBuiltins extends PythonBuiltins { @Override protected List> getNodeFactories() { - return CollectionsModuleBuiltinsFactory.getFactories(); - } - - // _collections.deque - @Builtin(name = J_DEQUE, minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.PDeque, takesVarArgs = true, takesVarKeywordArgs = true) - @GenerateNodeFactory - abstract static class DequeNode extends PythonVarargsBuiltinNode { - - @Override - public Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported { - if (arguments.length >= 1) { - return doGeneric(arguments[0], null, null); - } - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw VarargsBuiltinDirectInvocationNotSupported.INSTANCE; - } - - @Specialization - @SuppressWarnings("unused") - PDeque doGeneric(Object cls, Object[] args, PKeyword[] kwargs) { - return factory().createDeque(cls); - } - } - - // _collections._deque_iterator - @Builtin(name = J_DEQUE_ITER, constructsClass = PythonBuiltinClassType.PDequeIter, // - minNumOfPositionalArgs = 2, parameterNames = {"$self", "iterable", "index"}) - @GenerateNodeFactory - abstract static class DequeIterNode extends PythonTernaryBuiltinNode { - - @Specialization - static PDequeIter doGeneric(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object deque, Object indexObj, - @Bind("this") Node inliningTarget, - @Cached InlinedConditionProfile dequeProfile, - @Cached InlinedConditionProfile indexNoneProfile, - @Cached PyNumberIndexNode toIndexNode, - @Cached CastToJavaIntExactNode castToJavaIntExactNode, - @Cached DequeIterNextNode getNextNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!dequeProfile.profile(inliningTarget, deque instanceof PDeque)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.EXPECTED_OBJ_TYPE_S_GOT_P, BuiltinNames.T_DEQUE, deque); - } - PDequeIter dequeIter = factory.createDequeIter((PDeque) deque); - if (indexNoneProfile.profile(inliningTarget, indexObj != PNone.NO_VALUE)) { - int index = castToJavaIntExactNode.execute(inliningTarget, toIndexNode.execute(frame, inliningTarget, indexObj)); - for (int i = 0; i < index; i++) { - getNextNode.execute(dequeIter); - } - } - return dequeIter; - } - } - - // _collections._deque_reverse_iterator - @Builtin(name = J_DEQUE_REV_ITER, constructsClass = PythonBuiltinClassType.PDequeRevIter, // - minNumOfPositionalArgs = 2, parameterNames = {"$self", "iterable", "index"}) - @GenerateNodeFactory - abstract static class DequeRevIterNode extends PythonTernaryBuiltinNode { - @Specialization - static PDequeIter doGeneric(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object deque, Object indexObj, - @Bind("this") Node inliningTarget, - @Cached InlinedConditionProfile dequeProfile, - @Cached InlinedConditionProfile indexNoneProfile, - @Cached PyNumberIndexNode toIndexNode, - @Cached CastToJavaIntExactNode castToJavaIntExactNode, - @Cached DequeIterNextNode getNextNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!dequeProfile.profile(inliningTarget, deque instanceof PDeque)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.EXPECTED_OBJ_TYPE_S_GOT_P, BuiltinNames.T_DEQUE, deque); - } - PDequeIter dequeIter = factory.createDequeRevIter((PDeque) deque); - if (indexNoneProfile.profile(inliningTarget, indexObj != PNone.NO_VALUE)) { - int index = castToJavaIntExactNode.execute(inliningTarget, toIndexNode.execute(frame, inliningTarget, indexObj)); - for (int i = 0; i < index; i++) { - getNextNode.execute(dequeIter); - } - } - return dequeIter; - } - } - - // _collections.defaultdict - @Builtin(name = J_DEFAULTDICT, minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.PDefaultDict, takesVarArgs = true, takesVarKeywordArgs = true) - @GenerateNodeFactory - abstract static class DefaultDictNode extends PythonVarargsBuiltinNode { - @Specialization - @SuppressWarnings("unused") - PDefaultDict doGeneric(Object cls, Object[] args, PKeyword[] kwargs, - @Cached PythonObjectFactory factory) { - return factory.createDefaultDict(cls); - } - } - - // _collections._tuplegetter - @Builtin(name = J_TUPLE_GETTER, parameterNames = {"cls", "index", "doc"}, constructsClass = PythonBuiltinClassType.PTupleGetter) - @ArgumentClinic(name = "index", conversion = ArgumentClinic.ClinicConversion.Index) - @GenerateNodeFactory - abstract static class TupleGetterNode extends PythonTernaryClinicBuiltinNode { - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return CollectionsModuleBuiltinsClinicProviders.TupleGetterNodeClinicProviderGen.INSTANCE; - } - - @Specialization - Object construct(Object cls, int index, Object doc, - @Cached PythonObjectFactory factory) { - return factory.createTupleGetter(cls, index, doc); - } + return Collections.emptyList(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ContextvarsModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ContextvarsModuleBuiltins.java index 23dc550b09..986c74ed29 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ContextvarsModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ContextvarsModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,34 +41,22 @@ package com.oracle.graal.python.builtins.modules; import static com.oracle.graal.python.nodes.BuiltinNames.J__CONTEXTVARS; -import static com.oracle.graal.python.nodes.PGuards.isNoValue; import java.util.List; -import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.objects.contextvars.PContextVar; import com.oracle.graal.python.builtins.objects.contextvars.PContextVarsContext; import com.oracle.graal.python.lib.PyContextCopyCurrent; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; -import com.oracle.truffle.api.strings.TruffleString; @CoreFunctions(defineModule = J__CONTEXTVARS) public final class ContextvarsModuleBuiltins extends PythonBuiltins { @@ -88,46 +76,4 @@ protected static PContextVarsContext copyCtx( return copyCurrent.execute(inliningTarget); } } - - @Builtin(name = "ContextVar", minNumOfPositionalArgs = 2, parameterNames = {"cls", "name", "default"}, constructsClass = PythonBuiltinClassType.ContextVar) - @ArgumentClinic(name = "name", conversion = ArgumentClinic.ClinicConversion.TString) - @GenerateNodeFactory - public abstract static class ContextVarNode extends PythonTernaryClinicBuiltinNode { - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return ContextvarsModuleBuiltinsClinicProviders.ContextVarNodeClinicProviderGen.INSTANCE; - } - - @Specialization - protected static Object constructDef(@SuppressWarnings("unused") Object cls, TruffleString name, Object def, - @Bind("this") Node inliningTarget, - @Cached InlinedConditionProfile noValueProfile, - @Cached PythonObjectFactory factory) { - if (noValueProfile.profile(inliningTarget, isNoValue(def))) { - def = PContextVar.NO_DEFAULT; - } - return factory.createContextVar(name, def); - } - } - - @Builtin(name = "Context", minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.ContextVarsContext) - @GenerateNodeFactory - public abstract static class ContextNode extends PythonUnaryBuiltinNode { - @Specialization - static Object construct(@SuppressWarnings("unused") Object cls, - @Cached PythonObjectFactory factory) { - return factory.createContextVarsContext(); - } - } - - @Builtin(name = "Token", minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.ContextVarsToken) - @GenerateNodeFactory - public abstract static class TokenNode extends PythonUnaryBuiltinNode { - @Specialization - Object construct(@SuppressWarnings("unused") Object cls, - @Cached PRaiseNode raise) { - throw raise.raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.TOKEN_ONLY_BY_CONTEXTVAR); - } - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ErrnoModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ErrnoModuleBuiltins.java index 2972ac9617..47a4fd0c59 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ErrnoModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ErrnoModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -51,8 +51,8 @@ import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum; -import com.oracle.graal.python.lib.PyObjectHashNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.strings.TruffleString; @@ -75,12 +75,12 @@ public void initialize(Python3Core core) { } // publish the dictionary with mapping code -> string name - PDict errorCode = core.factory().createDict(storage); + PDict errorCode = PFactory.createDict(core.getLanguage(), storage); addBuiltinConstant("errorcode", errorCode); } private void addConstant(int number, TruffleString name, EconomicMapStorage storage) { addBuiltinConstant(name, number); - storage.putUncachedWithJavaEq(number, PyObjectHashNode.hash(number), name); + storage.putUncached(number, name); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/FcntlModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/FcntlModuleBuiltins.java index 6e20c9bea8..947eca1ea7 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/FcntlModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/FcntlModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -79,8 +79,9 @@ import com.oracle.graal.python.runtime.PosixConstants.IntConstant; import com.oracle.graal.python.runtime.PosixSupportLibrary; import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException; +import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -152,7 +153,7 @@ PNone lockf(VirtualFrame frame, int fd, int code, Object lenObj, Object startObj @Cached SysModuleBuiltins.AuditNode auditNode, @CachedLibrary("getPosixSupport()") PosixSupportLibrary posix, @Cached PyLongAsLongNode asLongNode, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { auditNode.audit(inliningTarget, "fcntl.lockf", fd, code, lenObj != PNone.NO_VALUE ? lenObj : PNone.NONE, startObj != PNone.NO_VALUE ? startObj : PNone.NONE, whence); int lockType; @@ -163,7 +164,7 @@ PNone lockf(VirtualFrame frame, int fd, int code, Object lenObj, Object startObj } else if ((code & LOCK_EX.value) != 0) { lockType = F_WRLCK.getValueIfDefined(); } else { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.UNRECOGNIZED_LOCKF_ARGUMENT); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.UNRECOGNIZED_LOCKF_ARGUMENT); } long start = 0; if (startObj != PNone.NO_VALUE) { @@ -198,7 +199,8 @@ abstract static class IoctlNode extends PythonClinicBuiltinNode { @Specialization Object ioctl(VirtualFrame frame, int fd, long request, Object arg, boolean mutateArg, @Bind("this") Node inliningTarget, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached("createFor(this)") IndirectCallData indirectCallData, @@ -207,9 +209,8 @@ Object ioctl(VirtualFrame frame, int fd, long request, Object arg, boolean mutat @Cached TruffleString.SwitchEncodingNode switchEncodingNode, @Cached TruffleString.CopyToByteArrayNode copyToByteArrayNode, @Cached GilNode gilNode, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory, @Cached SysModuleBuiltins.AuditNode auditNode) { auditNode.audit(inliningTarget, "fcnt.ioctl", fd, request, arg); @@ -248,7 +249,7 @@ Object ioctl(VirtualFrame frame, int fd, long request, Object arg, boolean mutat } } else { if (len > IOCTL_BUFSZ) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.IOCTL_STRING_ARG_TOO_LONG); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.IOCTL_STRING_ARG_TOO_LONG); } } if (ioctlArg == null) { @@ -260,7 +261,7 @@ Object ioctl(VirtualFrame frame, int fd, long request, Object arg, boolean mutat if (writable && mutateArg) { return ret; } else { - return factory.createBytes(ioctlArg, len); + return PFactory.createBytes(context.getLanguage(inliningTarget), ioctlArg, len); } } finally { if (writeBack) { @@ -284,12 +285,12 @@ Object ioctl(VirtualFrame frame, int fd, long request, Object arg, boolean mutat stringArg = switchEncodingNode.execute(stringArg, utf8); int len = stringArg.byteLength(utf8); if (len > IOCTL_BUFSZ) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.IOCTL_STRING_ARG_TOO_LONG); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.IOCTL_STRING_ARG_TOO_LONG); } byte[] ioctlArg = new byte[len + 1]; copyToByteArrayNode.execute(stringArg, 0, ioctlArg, 0, len, utf8); callIoctlBytes(frame, inliningTarget, fd, request, ioctlArg, true, posixLib, gilNode, constructAndRaiseNode); - return factory.createBytes(ioctlArg, len); + return PFactory.createBytes(context.getLanguage(inliningTarget), ioctlArg, len); } // int arg diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GcModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GcModuleBuiltins.java index c0664e86e4..caa88e7f40 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GcModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GcModuleBuiltins.java @@ -29,6 +29,7 @@ import java.lang.management.ManagementFactory; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; import com.oracle.graal.python.builtins.Builtin; @@ -51,6 +52,7 @@ import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.lib.PyObjectGetIter; @@ -65,7 +67,7 @@ import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode; import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -105,7 +107,7 @@ public void initialize(Python3Core core) { addBuiltinConstant("DEBUG_UNCOLLECTABLE", DEBUG_UNCOLLECTABLE); addBuiltinConstant("DEBUG_SAVEALL", DEBUG_SAVEALL); addBuiltinConstant("DEBUG_LEAK", DEBUG_LEAK); - addBuiltinConstant(CALLBACKS, core.factory().createList()); + addBuiltinConstant(CALLBACKS, PFactory.createList(core.getLanguage())); super.initialize(core); } @@ -127,7 +129,7 @@ static long collect(VirtualFrame frame, PythonModule self, @SuppressWarnings("un @Cached PyObjectGetAttr getAttr, @Cached PyObjectGetIter getIter, @Cached(neverDefault = true) PyIterNextNode next, - @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached CallBinaryMethodNode call, @Cached GilNode gil, @Cached GetThreadStateNode getThreadStateNode, @@ -135,20 +137,28 @@ static long collect(VirtualFrame frame, PythonModule self, @SuppressWarnings("un @Cached CheckPrimitiveFunctionResultNode checkPrimitiveFunctionResultNode) { Object callbacks = getAttr.execute(frame, inliningTarget, self, CALLBACKS); Object iter = getIter.execute(frame, inliningTarget, callbacks); - Object cb = next.execute(frame, iter); TruffleString phase = null; - Object info = null; + Object info; long res = 0; - if (cb != null) { + Object cb; + try { + cb = next.execute(frame, inliningTarget, iter); phase = START; - info = factory.createDict(new PKeyword[]{ + info = PFactory.createDict(language, new PKeyword[]{ new PKeyword(GENERATION, 2), new PKeyword(COLLECTED, 0), new PKeyword(UNCOLLECTABLE, 0), }); - do { - call.executeObject(frame, cb, phase, info); - } while ((cb = next.execute(frame, iter)) != null); + while (true) { + try { + call.executeObject(frame, cb, phase, info); + cb = next.execute(frame, inliningTarget, iter); + } catch (IteratorExhausted e) { + break; + } + } + } catch (IteratorExhausted e) { + // fallthrough } long freedMemory = javaCollect(inliningTarget, gil); PythonContext pythonContext = PythonContext.get(inliningTarget); @@ -161,14 +171,19 @@ static long collect(VirtualFrame frame, PythonModule self, @SuppressWarnings("un } if (phase != null) { phase = STOP; - info = factory.createDict(new PKeyword[]{ + info = PFactory.createDict(language, new PKeyword[]{ new PKeyword(GENERATION, 2), new PKeyword(COLLECTED, freedMemory), new PKeyword(UNCOLLECTABLE, 0), }); iter = getIter.execute(frame, inliningTarget, callbacks); - while ((cb = next.execute(frame, iter)) != null) { - call.executeObject(frame, cb, phase, info); + while (true) { + try { + cb = next.execute(frame, inliningTarget, iter); + call.executeObject(frame, cb, phase, info); + } catch (IteratorExhausted e) { + break; + } } } return res; @@ -287,7 +302,7 @@ static PTuple count() { count += cc; } } - return PythonContext.get(null).factory().createTuple(new Object[]{count, 0, 0}); + return PFactory.createTuple(PythonLanguage.get(null), new Object[]{count, 0, 0}); } } @@ -313,7 +328,7 @@ abstract static class GcGetReferentsNode extends PythonBuiltinNode { static PList getReferents(@SuppressWarnings("unused") Object objects) { // TODO: this is just a dummy implementation; for native objects, this should actually // use 'tp_traverse' - return PythonContext.get(null).factory().createList(); + return PFactory.createList(PythonLanguage.get(null)); } } @@ -324,7 +339,7 @@ abstract static class GcGetReferrersNode extends PythonBuiltinNode { @TruffleBoundary static PList doGeneric(@SuppressWarnings("unused") Object objects) { // dummy implementation - return PythonContext.get(null).factory().createList(); + return PFactory.createList(PythonLanguage.get(null)); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalHPyDebugModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalHPyDebugModuleBuiltins.java deleted file mode 100644 index 7fbf2ab87f..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalHPyDebugModuleBuiltins.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.modules; - -import static com.oracle.graal.python.nodes.StringLiterals.J_DEBUG; -import static com.oracle.graal.python.util.PythonUtils.tsLiteral; - -import java.io.IOException; -import java.util.Collections; -import java.util.List; - -import com.oracle.graal.python.builtins.Builtin; -import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.Python3Core; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ApiInitException; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ImportException; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext; -import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; -import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinNode; -import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.graal.python.util.PythonUtils.PrototypeNodeFactory; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.dsl.GenerateNodeFactory; -import com.oracle.truffle.api.dsl.NodeFactory; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.strings.TruffleString; - -@CoreFunctions(defineModule = GraalHPyDebugModuleBuiltins.J_HPY_DEBUG) -@GenerateNodeFactory -public final class GraalHPyDebugModuleBuiltins extends PythonBuiltins { - - public static final String J_HPY_DEBUG = "_hpy_debug"; - - static final String J_NOT_AVAILABLE = "_not_available"; - - private static final TruffleString T_NEW_GENERATION = tsLiteral("new_generation"); - private static final TruffleString T_GET_OPEN_HANDLES = tsLiteral("get_open_handles"); - private static final TruffleString T_GET_CLOSED_HANDLES = tsLiteral("get_closed_handles"); - private static final TruffleString T_GET_QUEUE_MAX_SIZE = tsLiteral("get_closed_handles_queue_max_size"); - private static final TruffleString T_SET_QUEUE_MAX_SIZE = tsLiteral("set_closed_handles_queue_max_size"); - private static final TruffleString T_GET_DATA_MAX_SIZE = tsLiteral("get_protected_raw_data_max_size"); - private static final TruffleString T_SET_DATA_MAX_SIZE = tsLiteral("set_protected_raw_data_max_size"); - private static final TruffleString T_SET_ON_INVALID_HANDLE = tsLiteral("set_on_invalid_handle"); - private static final TruffleString T_STACK_TRACE_LIMIT = tsLiteral("set_handle_stack_trace_limit"); - - @Override - protected List> getNodeFactories() { - return Collections.emptyList(); - } - - @Override - public void postInitialize(Python3Core core) { - PythonModule hpyDebugModule = core.lookupBuiltinModule(PythonUtils.tsLiteral(J_HPY_DEBUG)); - TruffleString[] keys = new TruffleString[]{T_NEW_GENERATION, T_GET_OPEN_HANDLES, T_GET_CLOSED_HANDLES, T_GET_QUEUE_MAX_SIZE, T_SET_QUEUE_MAX_SIZE, T_GET_DATA_MAX_SIZE, T_SET_DATA_MAX_SIZE, - T_SET_ON_INVALID_HANDLE, T_STACK_TRACE_LIMIT}; - try { - GraalHPyContext hpyContext = GraalHPyContext.ensureHPyWasLoaded(null, core.getContext(), null, null); - PythonModule nativeDebugModule = hpyContext.getHPyDebugModule(); - PDict nativeDebugDict = GetDictIfExistsNode.getUncached().execute(nativeDebugModule); - for (TruffleString tkey : keys) { - hpyDebugModule.setAttribute(tkey, nativeDebugDict.getItem(tkey)); - } - } catch (IOException | ApiInitException | ImportException e) { - /* - * Error case: install "not_available" for everything. So, loading still works, but you - * cannot use it. - */ - PythonBuiltinObject notAvailableObj = createFunction(core, hpyDebugModule); - for (TruffleString tkey : keys) { - hpyDebugModule.setAttribute(tkey, notAvailableObj); - } - } - } - - @Builtin(name = J_NOT_AVAILABLE, autoRegister = false, takesVarArgs = true, takesVarKeywordArgs = true) - static final class NotAvailable extends PythonBuiltinNode { - private static final NodeFactory NODE_FACTORY = new PrototypeNodeFactory<>(new NotAvailable()); - - @Override - public Object execute(VirtualFrame frame) { - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.RuntimeError, ErrorMessages.HPY_S_MODE_NOT_AVAILABLE, J_DEBUG); - } - } - - @TruffleBoundary - static PBuiltinMethod createFunction(Python3Core core, PythonModule module) { - Builtin builtin = NotAvailable.class.getAnnotation(Builtin.class); - RootCallTarget callTarget = core.getLanguage().createCachedCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, NotAvailable.NODE_FACTORY, false), NotAvailable.class, - builtin.name()); - int flags = PBuiltinFunction.getFlags(builtin, callTarget); - TruffleString name = PythonUtils.toTruffleStringUncached(builtin.name()); - PBuiltinFunction fun = core.factory().createBuiltinFunction(name, null, 0, flags, callTarget); - return core.factory().createBuiltinMethod(module, fun); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalHPyTraceModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalHPyTraceModuleBuiltins.java deleted file mode 100644 index 4cd1c216ca..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalHPyTraceModuleBuiltins.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.modules; - -import static com.oracle.graal.python.util.PythonUtils.tsLiteral; - -import java.io.IOException; -import java.util.Collections; -import java.util.List; - -import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.Python3Core; -import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ApiInitException; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ImportException; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext; -import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; -import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.dsl.GenerateNodeFactory; -import com.oracle.truffle.api.dsl.NodeFactory; -import com.oracle.truffle.api.strings.TruffleString; - -@CoreFunctions(defineModule = GraalHPyTraceModuleBuiltins.J_HPY_TRACE) -@GenerateNodeFactory -public final class GraalHPyTraceModuleBuiltins extends PythonBuiltins { - - public static final String J_HPY_TRACE = "_hpy_trace"; - - private static final TruffleString T_GET_DURATIONS = tsLiteral("get_durations"); - private static final TruffleString T_GET_CALL_COUNTS = tsLiteral("get_call_counts"); - private static final TruffleString T_SET_TRACE_FUNCTIONS = tsLiteral("set_trace_functions"); - private static final TruffleString T_GET_FREQUENCY = tsLiteral("get_frequency"); - - @Override - protected List> getNodeFactories() { - return Collections.emptyList(); - } - - @Override - public void postInitialize(Python3Core core) { - PythonModule hpyTraceModule = core.lookupBuiltinModule(PythonUtils.tsLiteral(J_HPY_TRACE)); - TruffleString[] keys = new TruffleString[]{T_GET_DURATIONS, T_GET_CALL_COUNTS, T_SET_TRACE_FUNCTIONS, T_GET_FREQUENCY}; - try { - GraalHPyContext hpyContext = GraalHPyContext.ensureHPyWasLoaded(null, core.getContext(), null, null); - PythonModule nativeTraceModule = hpyContext.getHPyTraceModule(); - PDict nativeTraceDict = GetDictIfExistsNode.getUncached().execute(nativeTraceModule); - for (TruffleString tkey : keys) { - hpyTraceModule.setAttribute(tkey, nativeTraceDict.getItem(tkey)); - } - } catch (IOException | ApiInitException | ImportException e) { - /* - * Error case: install "not_available" for everything. So, loading still works, but you - * cannot use it. - */ - PythonBuiltinObject notAvailableObj = GraalHPyDebugModuleBuiltins.createFunction(core, hpyTraceModule); - for (TruffleString tkey : keys) { - hpyTraceModule.setAttribute(tkey, notAvailableObj); - } - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalHPyUniversalModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalHPyUniversalModuleBuiltins.java deleted file mode 100644 index e6a9ceded9..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalHPyUniversalModuleBuiltins.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.modules; - -import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___ALL__; -import static com.oracle.graal.python.util.PythonUtils.tsLiteral; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.annotations.ArgumentClinic; -import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; -import com.oracle.graal.python.builtins.Builtin; -import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.Python3Core; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.modules.GraalHPyUniversalModuleBuiltinsClinicProviders.HPyUniversalLoadBootstrapNodeClinicProviderGen; -import com.oracle.graal.python.builtins.modules.GraalHPyUniversalModuleBuiltinsClinicProviders.HPyUniversalLoadNodeClinicProviderGen; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ApiInitException; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ImportException; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyMode; -import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.lib.PyObjectGetItem; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PConstructAndRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.SpecialAttributeNames; -import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; -import com.oracle.graal.python.nodes.util.CannotCastException; -import com.oracle.graal.python.nodes.util.CastToJavaStringNode; -import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext; -import com.oracle.graal.python.runtime.IndirectCallData; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.GenerateNodeFactory; -import com.oracle.truffle.api.dsl.NodeFactory; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.strings.TruffleString; - -@CoreFunctions(defineModule = GraalHPyUniversalModuleBuiltins.J_HPY_UNIVERSAL) -@GenerateNodeFactory -public final class GraalHPyUniversalModuleBuiltins extends PythonBuiltins { - - static final String J_HPY_UNIVERSAL = "_hpy_universal"; - private static final TruffleString T_HPY_UNIVERSAL = tsLiteral(J_HPY_UNIVERSAL); - private static final TruffleString T_HPY = tsLiteral("HPY"); - - private static final TruffleString[] ALL_ARRAY; - - static { - List allList = new ArrayList<>(); - for (HPyMode mode : HPyMode.values()) { - allList.add(tsLiteral(mode.name())); - } - allList.add(tsLiteral("load")); - allList.add(tsLiteral("_load_bootstrap")); - ALL_ARRAY = allList.toArray(new TruffleString[0]); - } - - @Override - protected List> getNodeFactories() { - return GraalHPyUniversalModuleBuiltinsFactory.getFactories(); - } - - @Override - public void initialize(Python3Core core) { - for (HPyMode mode : HPyMode.values()) { - addBuiltinConstant(mode.name(), mode.getValue()); - } - super.initialize(core); - } - - @Override - public void postInitialize(Python3Core core) { - PythonModule module = core.lookupBuiltinModule(T_HPY_UNIVERSAL); - module.setAttribute(T___ALL__, core.factory().createTuple(ALL_ARRAY)); - } - - @Builtin(name = "load", parameterNames = {"name", "path", "spec", "debug", "mode"}, minNumOfPositionalArgs = 3) - @GenerateNodeFactory - @ArgumentClinic(name = "name", conversion = ClinicConversion.TString) - @ArgumentClinic(name = "path", conversion = ClinicConversion.TString) - @ArgumentClinic(name = "debug", conversion = ClinicConversion.Boolean, defaultValue = "false") - @ArgumentClinic(name = "mode", conversion = ClinicConversion.Int, defaultValue = "-1") - abstract static class HPyUniversalLoadNode extends PythonClinicBuiltinNode { - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return HPyUniversalLoadNodeClinicProviderGen.INSTANCE; - } - - @Specialization - static Object doGeneric(VirtualFrame frame, TruffleString name, TruffleString path, Object spec, boolean debug, int mode, - @Bind("this") Node inliningTarget, - @Cached("createFor(this)") IndirectCallData indirectCallData, - @Cached TruffleString.EqualNode eqNode, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { - PythonContext context = PythonContext.get(inliningTarget); - PythonLanguage language = context.getLanguage(inliningTarget); - Object state = IndirectCallContext.enter(frame, language, context, indirectCallData); - try { - HPyMode hmode = debug ? HPyMode.MODE_DEBUG : HPyMode.MODE_UNIVERSAL; - // 'mode' just overwrites 'debug' - if (mode > 0) { - hmode = HPyMode.fromValue(mode); - } - return GraalHPyContext.loadHPyModule(inliningTarget, context, name, path, spec, hmode); - } catch (ApiInitException ie) { - throw ie.reraise(frame, inliningTarget, constructAndRaiseNode); - } catch (ImportException ie) { - throw ie.reraise(frame, inliningTarget, constructAndRaiseNode); - } catch (IOException e) { - throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, e, eqNode); - } finally { - IndirectCallContext.exit(frame, language, context, state); - } - } - } - - @Builtin(name = "_load_bootstrap", parameterNames = {"name", "ext_name", "package", "file", "loader", "spec", "env"}) - @GenerateNodeFactory - @ArgumentClinic(name = "name", conversion = ClinicConversion.TString) - @ArgumentClinic(name = "ext_name", conversion = ClinicConversion.TString) - @ArgumentClinic(name = "file", conversion = ClinicConversion.TString) - abstract static class HPyUniversalLoadBootstrapNode extends PythonClinicBuiltinNode { - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return HPyUniversalLoadBootstrapNodeClinicProviderGen.INSTANCE; - } - - @Specialization - static Object doGeneric(VirtualFrame frame, TruffleString name, TruffleString extName, Object pkg, TruffleString file, Object loader, Object spec, Object env, - @Bind("this") Node inliningTarget, - @Cached("createFor(this)") IndirectCallData indirectCallData, - @Cached TruffleString.EqualNode eqNode, - @Cached WriteAttributeToObjectNode writeAttrNode, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode.Lazy raiseNode) { - Object module; - - PythonContext context = PythonContext.get(inliningTarget); - PythonLanguage language = context.getLanguage(inliningTarget); - Object state = IndirectCallContext.enter(frame, language, context, indirectCallData); - try { - HPyMode hmode = getHPyModeFromEnviron(name, env); - module = GraalHPyContext.loadHPyModule(inliningTarget, context, name, file, spec, hmode); - } catch (CannotCastException e) { - // thrown by getHPyModeFromEnviron if value is not a string - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.HPY_MODE_VALUE_MUST_BE_STRING); - } catch (ApiInitException ie) { - throw ie.reraise(frame, inliningTarget, constructAndRaiseNode); - } catch (ImportException ie) { - throw ie.reraise(frame, inliningTarget, constructAndRaiseNode); - } catch (IOException e) { - throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, e, eqNode); - } finally { - IndirectCallContext.exit(frame, language, context, state); - } - - writeAttrNode.execute(module, SpecialAttributeNames.T___FILE__, file); - writeAttrNode.execute(module, SpecialAttributeNames.T___LOADER__, loader); - writeAttrNode.execute(module, SpecialAttributeNames.T___NAME__, extName); - writeAttrNode.execute(module, SpecialAttributeNames.T___PACKAGE__, pkg); - writeAttrNode.execute(spec, ImpModuleBuiltins.T_ORIGIN, file); - writeAttrNode.execute(module, SpecialAttributeNames.T___SPEC__, spec); - return module; - } - - /** - *
    -         *     HPY_MODE := MODE | (MODULE_NAME ':' MODE { ',' MODULE_NAME ':' MODE })
    -         *     MODULE_NAME :=
    -         *     IDENTIFIER MODE := 'debug' | 'trace' | 'universal'
    -         * 
    - */ - @TruffleBoundary - private static HPyMode getHPyModeFromEnviron(TruffleString moduleName, Object env) throws CannotCastException { - Object result; - try { - result = PyObjectGetItem.executeUncached(env, T_HPY); - } catch (PException e) { - e.expect(null, PythonBuiltinClassType.KeyError, IsBuiltinObjectProfile.getUncached()); - // this is not an error; it just means that the key was not present in 'env' - return HPyMode.MODE_UNIVERSAL; - } - - String s = CastToJavaStringNode.getUncached().execute(result); - - int colonIdx = s.indexOf(':'); - if (colonIdx != -1) { - // case 2: modes are specified per module - String[] moduleParts = s.split(","); - String sModuleName = moduleName.toJavaStringUncached(); - for (String modulePars : moduleParts) { - String[] def = modulePars.split(":"); - if (sModuleName.equals(def[0])) { - return HPyMode.valueOf("MODE_" + def[1].toUpperCase()); - } - } - } else { - // case 1: mode was globally specified - return HPyMode.valueOf("MODE_" + s.toUpperCase()); - } - return HPyMode.MODE_UNIVERSAL; - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java index 1e20104ca1..9330b1765c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -53,10 +53,8 @@ import static com.oracle.graal.python.nodes.BuiltinNames.T___MAIN__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T_INSERT; -import static com.oracle.graal.python.nodes.StringLiterals.J_LLVM_LANGUAGE; import static com.oracle.graal.python.nodes.StringLiterals.T_COLON; import static com.oracle.graal.python.nodes.StringLiterals.T_JAVA; -import static com.oracle.graal.python.nodes.StringLiterals.T_LLVM_LANGUAGE; import static com.oracle.graal.python.nodes.StringLiterals.T_NATIVE; import static com.oracle.graal.python.nodes.StringLiterals.T_PATH; import static com.oracle.graal.python.nodes.StringLiterals.T_STRICT; @@ -83,13 +81,6 @@ import java.util.List; import java.util.logging.Level; -import com.oracle.graal.python.nodes.arrow.ArrowArray; -import com.oracle.graal.python.nodes.arrow.ArrowSchema; -import com.oracle.graal.python.nodes.arrow.capsule.CreateArrowPyCapsuleNode; -import com.oracle.graal.python.nodes.arrow.vector.VectorToArrowArrayNode; -import com.oracle.graal.python.nodes.arrow.vector.VectorToArrowSchemaNode; -import org.graalvm.nativeimage.ImageInfo; - import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; @@ -98,10 +89,12 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.modules.GraalPythonModuleBuiltinsFactory.DebugNodeFactory; +import com.oracle.graal.python.builtins.modules.cext.PythonCextCapsuleBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.array.PArray; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; +import com.oracle.graal.python.builtins.objects.capsule.PyCapsule; import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext; import com.oracle.graal.python.builtins.objects.cext.capi.PySequenceArrayWrapper.ToNativeStorageNode; @@ -109,6 +102,7 @@ import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions; import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonObjectReference; import com.oracle.graal.python.builtins.objects.cext.capi.transitions.GetNativeWrapperNode; +import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers; import com.oracle.graal.python.builtins.objects.cext.copying.NativeLibraryLocator; import com.oracle.graal.python.builtins.objects.code.CodeNodes; import com.oracle.graal.python.builtins.objects.code.PCode; @@ -130,19 +124,22 @@ import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.builtins.objects.method.PMethod; import com.oracle.graal.python.builtins.objects.module.PythonModule; +import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.set.PSet; +import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.builtins.objects.str.StringUtils; import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.type.PythonClass; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.CreateTypeNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.arrow.ArrowArray; +import com.oracle.graal.python.nodes.arrow.ArrowSchema; import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetCallTargetNode; import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; @@ -150,13 +147,11 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; import com.oracle.graal.python.nodes.statement.AbstractImportNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.nodes.util.ToNativePrimitiveStorageNode; import com.oracle.graal.python.runtime.ExecutionContext; @@ -166,7 +161,7 @@ import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonExitException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.graal.python.runtime.sequence.storage.NativePrimitiveSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage; @@ -180,6 +175,7 @@ import com.oracle.truffle.api.TruffleFile; import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.TruffleLogger; +import com.oracle.truffle.api.TruffleOptions; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -188,7 +184,6 @@ import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.InvalidArrayIndexException; @@ -198,13 +193,11 @@ import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.api.nodes.LanguageInfo; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeUtil; import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.strings.TruffleString; -import com.oracle.truffle.llvm.api.Toolchain; @CoreFunctions(defineModule = J___GRAALPYTHON__, isEager = true) public final class GraalPythonModuleBuiltins extends PythonBuiltins { @@ -224,7 +217,8 @@ protected List> getNodeFa @Override public void initialize(Python3Core core) { super.initialize(core); - addBuiltinConstant("is_native", ImageInfo.inImageCode()); + addBuiltinConstant("is_native", TruffleOptions.AOT); + addBuiltinConstant("is_bytecode_dsl_interpreter", PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER); PythonContext ctx = core.getContext(); TruffleString encodingOpt = ctx.getLanguage().getEngineOption(PythonOptions.StandardStreamEncoding); TruffleString standardStreamEncoding = null; @@ -259,11 +253,10 @@ public void postInitialize(Python3Core core) { PythonContext context = core.getContext(); PythonModule mod = core.lookupBuiltinModule(T___GRAALPYTHON__); PythonLanguage language = context.getLanguage(); - if (!ImageInfo.inImageBuildtimeCode()) { + if (!context.getEnv().isPreInitialization()) { mod.setAttribute(tsLiteral("home"), context.getLanguageHome()); } - mod.setAttribute(tsLiteral("in_image_buildtime"), ImageInfo.inImageBuildtimeCode()); - mod.setAttribute(tsLiteral("in_image"), ImageInfo.inImageCode()); + mod.setAttribute(tsLiteral("in_preinitialization"), context.getEnv().isPreInitialization()); TruffleString coreHome = context.getCoreHome(); TruffleString stdlibHome = context.getStdlibHome(); TruffleString capiHome = context.getCAPIHome(); @@ -272,14 +265,11 @@ public void postInitialize(Python3Core core) { mod.setAttribute(tsLiteral("core_home"), coreHome); mod.setAttribute(tsLiteral("stdlib_home"), stdlibHome); mod.setAttribute(tsLiteral("capi_home"), capiHome); - mod.setAttribute(tsLiteral("jni_home"), context.getJNIHome()); Object[] arr = convertToObjectArray(PythonOptions.getExecutableList(context)); - PList executableList = PythonObjectFactory.getUncached().createList(arr); + PList executableList = PFactory.createList(language, arr); mod.setAttribute(tsLiteral("executable_list"), executableList); mod.setAttribute(tsLiteral("venvlauncher_command"), context.getOption(PythonOptions.VenvlauncherCommand)); mod.setAttribute(tsLiteral("ForeignType"), core.lookupType(PythonBuiltinClassType.ForeignObject)); - mod.setAttribute(tsLiteral("use_system_toolchain"), context.getOption(PythonOptions.UseSystemToolchain)); - mod.setAttribute(tsLiteral("ext_mode"), context.getOption(PythonOptions.NativeModules) ? T_NATIVE : T_LLVM_LANGUAGE); if (!context.getOption(PythonOptions.EnableDebuggingBuiltins)) { mod.setAttribute(tsLiteral("dump_truffle_ast"), PNone.NO_VALUE); @@ -326,8 +316,8 @@ PNone run() { * other paths through pymain_run_python are handled in GraalPythonMain and the path * prepending is done in PythonLanguage in those other cases */ - assert !ImageInfo.inImageBuildtimeCode(); PythonContext context = getContext(); + assert !context.getEnv().isPreInitialization(); TruffleString inputFilePath = context.getOption(PythonOptions.InputFilePath); PythonModule sysModule = context.getSysModule(); boolean needsMainImporter = !inputFilePath.isEmpty() && getImporter(sysModule, inputFilePath); @@ -441,15 +431,15 @@ public abstract static class ReadFileNode extends PythonUnaryBuiltinNode { @Specialization PBytes doString(VirtualFrame frame, Object filenameObj, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached CastToTruffleStringNode castToTruffleStringNode, @Cached TruffleString.EqualNode eqNode, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { TruffleString filename = castToTruffleStringNode.execute(inliningTarget, filenameObj); - TruffleFile file = getContext().getPublicTruffleFileRelaxed(filename, PythonLanguage.T_DEFAULT_PYTHON_EXTENSIONS); + TruffleFile file = context.getPublicTruffleFileRelaxed(filename, PythonLanguage.T_DEFAULT_PYTHON_EXTENSIONS); byte[] bytes = file.readAllBytes(); - return factory.createBytes(bytes); + return PFactory.createBytes(context.getLanguage(inliningTarget), bytes); } catch (Exception ex) { ErrorAndMessagePair errAndMsg = OSErrorEnum.fromException(ex, eqNode); throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, errAndMsg.oserror.getNumber(), errAndMsg.message); @@ -543,8 +533,8 @@ public abstract static class BuiltinNode extends PythonUnaryBuiltinNode { @Specialization public Object doIt(VirtualFrame frame, PFunction func, @Bind("this") Node inliningTarget, - @Cached PyObjectGetItem getItem, - @Cached PythonObjectFactory factory) { + @Bind PythonContext context, + @Cached PyObjectGetItem getItem) { PFunction builtinFunc = convertToBuiltin(func); PythonObject globals = func.getGlobals(); PythonModule builtinModule; @@ -552,17 +542,21 @@ public Object doIt(VirtualFrame frame, PFunction func, builtinModule = (PythonModule) globals; } else { TruffleString moduleName = (TruffleString) getItem.execute(frame, inliningTarget, globals, T___NAME__); - builtinModule = getContext().lookupBuiltinModule(moduleName); + builtinModule = context.lookupBuiltinModule(moduleName); assert builtinModule != null; } - return factory.createBuiltinMethod(builtinModule, builtinFunc); + return PFactory.createBuiltinMethod(context.getLanguage(inliningTarget), builtinModule, builtinFunc); } @TruffleBoundary public synchronized PFunction convertToBuiltin(PFunction func) { RootNode rootNode = CodeNodes.GetCodeRootNode.executeUncached(func.getCode()); - if (rootNode instanceof PBytecodeRootNode) { - ((PBytecodeRootNode) rootNode).setPythonInternal(true); + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + if (rootNode instanceof PBytecodeDSLRootNode r) { + r.setPythonInternal(true); + } + } else if (rootNode instanceof PBytecodeRootNode r) { + r.setPythonInternal(true); } func.setBuiltin(true); return func; @@ -577,8 +571,12 @@ public Object doIt(PFunction func, @Bind("this") Node inliningTarget, @Cached CodeNodes.GetCodeRootNode getRootNode) { RootNode rootNode = getRootNode.execute(inliningTarget, func.getCode()); - if (rootNode instanceof PBytecodeRootNode) { - ((PBytecodeRootNode) rootNode).setPythonInternal(true); + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + if (rootNode instanceof PBytecodeDSLRootNode r) { + r.setPythonInternal(true); + } + } else if (rootNode instanceof PBytecodeRootNode r) { + r.setPythonInternal(true); } return func; } @@ -594,119 +592,6 @@ public Object doIt(PFunction func) { } } - @Builtin(name = "get_toolchain_tools_for_venv") - @TypeSystemReference(PythonArithmeticTypes.class) - @GenerateNodeFactory - public abstract static class GetToolchainToolsForVenv extends PythonBuiltinNode { - private static final class Tool { - final String name; - final boolean isVariableName; - final Object[] targets; - - public Tool(String name, boolean isVariableName, Object[] targets) { - this.name = name; - this.isVariableName = isVariableName; - this.targets = targets; - } - - static Tool forVariable(String name, Object... targets) { - return new Tool(name, true, targets); - } - - static Tool forBinary(String name, Object... targets) { - return new Tool(name, true, targets); - } - } - - static final Tool[] tools = new Tool[]{ - Tool.forVariable("AR", tsLiteral("ar")), - Tool.forVariable("RANLIB", tsLiteral("ranlib")), - Tool.forVariable("NM", tsLiteral("nm")), - Tool.forVariable("LD", tsLiteral("ld.lld"), tsLiteral("ld"), tsLiteral("lld")), - Tool.forVariable("CC", tsLiteral("clang"), tsLiteral("cc")), - Tool.forVariable("CXX", tsLiteral("clang++"), tsLiteral("c++")), - Tool.forVariable("FC", tsLiteral("graalvm-flang"), tsLiteral("flang-new"), tsLiteral("flang")), - Tool.forBinary("llvm-as", tsLiteral("as")), - Tool.forBinary("clang-cl", tsLiteral("cl")), - Tool.forBinary("clang-cpp", tsLiteral("cpp")), - }; - - @Specialization - @TruffleBoundary - Object getToolPath() { - PythonObjectFactory factory = PythonObjectFactory.getUncached(); - Env env = getContext().getEnv(); - LanguageInfo llvmInfo = env.getInternalLanguages().get(J_LLVM_LANGUAGE); - Toolchain toolchain = env.lookup(llvmInfo, Toolchain.class); - List toolchainPaths = toolchain.getPaths("PATH"); - EconomicMapStorage storage = EconomicMapStorage.create(tools.length); - for (Tool tool : tools) { - String path = null; - if (tool.isVariableName) { - TruffleFile toolPath = toolchain.getToolPath(tool.name); - if (toolPath != null) { - path = toolPath.getAbsoluteFile().getPath(); - } - } else { - for (TruffleFile toolchainPath : toolchainPaths) { - LOGGER.finest(() -> " Testing path " + toolchainPath.getPath() + " for tool " + tool.name); - TruffleFile pathToTest = toolchainPath.resolve(tool.name); - if (pathToTest.exists()) { - path = pathToTest.getAbsoluteFile().getPath(); - break; - } - } - } - if (path != null) { - storage.putUncached(toTruffleStringUncached(path), factory.createTuple(tool.targets)); - } else { - LOGGER.fine("Could not locate tool " + tool.name); - } - } - return factory.createDict(storage); - } - } - - @Builtin(name = "get_toolchain_tool_path", minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) - @GenerateNodeFactory - public abstract static class GetToolPathNode extends PythonUnaryBuiltinNode { - @Specialization - @TruffleBoundary - protected Object getToolPath(TruffleString tool) { - Env env = getContext().getEnv(); - LanguageInfo llvmInfo = env.getInternalLanguages().get(J_LLVM_LANGUAGE); - Toolchain toolchain = env.lookup(llvmInfo, Toolchain.class); - TruffleFile toolPath = toolchain.getToolPath(tool.toJavaStringUncached()); - if (toolPath == null) { - return PNone.NONE; - } - return toTruffleStringUncached(toolPath.toString().replace("\\", "/")); - } - } - - @Builtin(name = "get_toolchain_paths", minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) - @GenerateNodeFactory - public abstract static class GetToolchainPathsNode extends PythonUnaryBuiltinNode { - @Specialization - @TruffleBoundary - protected Object getToolPath(TruffleString tool) { - Env env = getContext().getEnv(); - LanguageInfo llvmInfo = env.getInternalLanguages().get(J_LLVM_LANGUAGE); - Toolchain toolchain = env.lookup(llvmInfo, Toolchain.class); - List toolPaths = toolchain.getPaths(tool.toJavaStringUncached()); - if (toolPaths == null) { - return PNone.NONE; - } - Object[] pathNames = new Object[toolPaths.size()]; - for (int i = 0; i < pathNames.length; i++) { - pathNames[i] = toTruffleStringUncached(toolPaths.get(i).toString().replace("\\", "/")); - } - return PythonObjectFactory.getUncached().createList(pathNames); - } - } - @Builtin(name = "determine_system_toolchain", maxNumOfPositionalArgs = 1) @GenerateNodeFactory public abstract static class DetermineSystemToolchain extends PythonUnaryBuiltinNode { @@ -727,8 +612,8 @@ public abstract static class DetermineSystemToolchain extends PythonUnaryBuiltin @Specialization static PDict doGeneric(@SuppressWarnings("unused") Object unused, - @Cached PythonObjectFactory factory) { - return factory.createDict(fromToolchain()); + @Bind PythonLanguage language) { + return PFactory.createDict(language, fromToolchain()); } @TruffleBoundary @@ -826,13 +711,13 @@ private HashingStorage getStrategy(TruffleString tname, PythonLanguage lang) { case "economicmap": return EconomicMapStorage.create(); default: - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.ValueError, ErrorMessages.UNKNOWN_STORAGE_STRATEGY); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.ValueError, ErrorMessages.UNKNOWN_STORAGE_STRATEGY); } } private void validate(HashingStorage dictStorage) { if (HashingStorageLen.executeUncached(dictStorage) != 0) { - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.ValueError, ErrorMessages.SHOULD_BE_USED_ONLY_NEW_SETS); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.ValueError, ErrorMessages.SHOULD_BE_USED_ONLY_NEW_SETS); } } } @@ -867,25 +752,25 @@ public abstract static class JavaExtendNode extends PythonUnaryBuiltinNode { static Object doIt(Object value, @Bind("this") Node inliningTarget, @CachedLibrary(limit = "3") InteropLibrary lib, - @Cached PRaiseNode.Lazy raiseNode) { - if (ImageInfo.inImageBuildtimeCode()) { + @Cached PRaiseNode raiseNode) { + if (getContext(inliningTarget).getEnv().isPreInitialization()) { CompilerDirectives.transferToInterpreterAndInvalidate(); throw new UnsupportedOperationException(ErrorMessages.CANT_EXTEND_JAVA_CLASS_NOT_JVM.toJavaStringUncached()); } - if (ImageInfo.inImageRuntimeCode()) { + if (TruffleOptions.AOT) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw raiseNode.get(inliningTarget).raise(SystemError, ErrorMessages.CANT_EXTEND_JAVA_CLASS_NOT_JVM); + throw raiseNode.raise(inliningTarget, SystemError, ErrorMessages.CANT_EXTEND_JAVA_CLASS_NOT_JVM); } Env env = PythonContext.get(inliningTarget).getEnv(); if (!isType(value, env, lib)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANT_EXTEND_JAVA_CLASS_NOT_TYPE, value); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_EXTEND_JAVA_CLASS_NOT_TYPE, value); } try { return env.createHostAdapter(new Object[]{value}); } catch (Exception ex) { - throw raiseNode.get(inliningTarget).raise(TypeError, PythonUtils.getMessage(ex), ex); + throw raiseNode.raise(inliningTarget, TypeError, PythonUtils.getMessage(ex), ex); } } @@ -948,18 +833,6 @@ Object doIt(Object value) { @Builtin(name = "which", minNumOfPositionalArgs = 1) @GenerateNodeFactory abstract static class WhichNode extends PythonUnaryBuiltinNode { - @Specialization - @TruffleBoundary - Object which(PBuiltinFunction object) { - RootCallTarget callTarget = object.getCallTarget(); - return toTruffleStringUncached(String.format("%s(%s)", object.getClass().getName(), whichCallTarget(callTarget))); - } - - @Specialization - @TruffleBoundary - Object which(PBuiltinMethod object) { - return toTruffleStringUncached(String.format("%s(%s)", object.getClass().getName(), whichCallTarget(object.getBuiltinFunction().getCallTarget()))); - } private static String whichCallTarget(RootCallTarget callTarget) { RootNode rootNode = callTarget.getRootNode(); @@ -974,8 +847,33 @@ private static String whichCallTarget(RootCallTarget callTarget) { @Specialization @TruffleBoundary - Object which(Object object) { - return toTruffleStringUncached(object.getClass().getName()); + // This is a builtin for debugging, so it also includes things that should never end up in + // python value space + static Object which(Object object) { + if (object == null) { + return "null"; + } + String name = object.getClass().getName(); + Object detail = null; + try { + if (object instanceof PNone) { + detail = "NO_VALUE"; + } else if (object instanceof PBuiltinFunction fn) { + detail = whichCallTarget(fn.getCallTarget()); + } else if (object instanceof PBuiltinMethod fn) { + detail = whichCallTarget(fn.getBuiltinFunction().getCallTarget()); + } else if (object instanceof PSequence sequence && !(object instanceof PString)) { + detail = sequence.getSequenceStorage(); + } else if (object instanceof PArray array) { + detail = array.getSequenceStorage(); + } else if (object instanceof PythonAbstractNativeObject nativeObject) { + detail = PythonUtils.formatPointer(nativeObject.getPtr()); + } + } catch (Throwable t) { + detail = "Detail computation threw exception: " + t; + } + String which = detail != null ? String.format("%s(%s)", name, detail) : name; + return toTruffleStringUncached(which); } } @@ -1052,17 +950,6 @@ static boolean doGeneric(int id) { } } - // This is only used from HPy - @Builtin(name = "PyTruffle_CreateType", minNumOfPositionalArgs = 4) - @GenerateNodeFactory - abstract static class PyTruffle_CreateType extends PythonQuaternaryBuiltinNode { - @Specialization - static PythonClass createType(VirtualFrame frame, TruffleString name, PTuple bases, PDict namespaceOrig, Object metaclass, - @Cached CreateTypeNode createType) { - return createType.execute(frame, namespaceOrig, name, bases, metaclass, PKeyword.EMPTY_KEYWORDS); - } - } - @Builtin(name = "get_graalvm_version", minNumOfPositionalArgs = 0) @GenerateNodeFactory abstract static class GetGraalVmVersion extends PythonBuiltinNode { @@ -1193,7 +1080,7 @@ static Object replicate(TruffleString venvPath, int count, try { NativeLibraryLocator.replicate(context.getEnv().getPublicTruffleFile(venvPath.toJavaStringUncached()), context, count); } catch (IOException | InterruptedException e) { - throw PRaiseNode.raiseUncached(node, PythonBuiltinClassType.ValueError, e); + throw PRaiseNode.raiseStatic(node, PythonBuiltinClassType.ValueError, e); } return PNone.NONE; } @@ -1325,18 +1212,39 @@ Object invokeMember(String member, Object[] arguments) throws UnsupportedMessage } } - @Builtin(name = "export_arrow_vector", minNumOfPositionalArgs = 1) + @Builtin(name = "create_arrow_py_capsule", minNumOfPositionalArgs = 2) @GenerateNodeFactory - public abstract static class ExportArrowVector extends PythonUnaryBuiltinNode { + public abstract static class CreateArrowPyCapsule extends PythonBinaryBuiltinNode { + @Specialization - static PTuple doExport(Object vector, + static PTuple doCreate(long arrowArrayAddr, long arrowSchemaAddr, @Bind("this") Node inliningTarget, - @Cached VectorToArrowArrayNode exportArray, - @Cached VectorToArrowSchemaNode exportSchema, - @Cached CreateArrowPyCapsuleNode createArrowCapsuleNode) { - ArrowArray arrowArray = exportArray.execute(inliningTarget, vector); - ArrowSchema arrowSchema = exportSchema.execute(inliningTarget, vector); - return createArrowCapsuleNode.execute(inliningTarget, arrowArray, arrowSchema); + @Cached PythonCextCapsuleBuiltins.PyCapsuleNewNode pyCapsuleNewNode) { + var ctx = getContext(inliningTarget); + + long arrayDestructor = ctx.arrowSupport.getArrowArrayDestructor(); + var arrayCapsuleName = new CArrayWrappers.CByteArrayWrapper(ArrowArray.CAPSULE_NAME); + PyCapsule arrowArrayCapsule = pyCapsuleNewNode.execute(inliningTarget, arrowArrayAddr, arrayCapsuleName, arrayDestructor); + + long schemaDestructor = ctx.arrowSupport.getArrowSchemaDestructor(); + var schemaCapsuleName = new CArrayWrappers.CByteArrayWrapper(ArrowSchema.CAPSULE_NAME); + PyCapsule arrowSchemaCapsule = pyCapsuleNewNode.execute(inliningTarget, arrowSchemaAddr, schemaCapsuleName, schemaDestructor); + return PFactory.createTuple(ctx.getLanguage(inliningTarget), new Object[]{arrowSchemaCapsule, arrowArrayCapsule}); + } + } + + /** + * Used from datetime module to create new instances of objects that we allow subclassing from + * native. It's necessary, because the __new__ wrapper would reject native subclasses that + * override tp_new. + */ + @Builtin(name = "unsafe_object_new", minNumOfPositionalArgs = 1) + @GenerateNodeFactory + abstract static class UnsafeObjectNewNode extends PythonUnaryBuiltinNode { + @Specialization + static Object create(VirtualFrame frame, Object cls, + @Cached ObjectBuiltins.ObjectNode objectNode) { + return objectNode.execute(frame, cls, PythonUtils.EMPTY_OBJECT_ARRAY, PKeyword.EMPTY_KEYWORDS); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ImpModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ImpModuleBuiltins.java index a8de465698..66145d87a9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ImpModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ImpModuleBuiltins.java @@ -61,8 +61,6 @@ import java.util.List; import java.util.concurrent.locks.ReentrantLock; -import org.graalvm.nativeimage.ImageInfo; - import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; @@ -71,7 +69,6 @@ import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.MemoryViewNode; import com.oracle.graal.python.builtins.modules.MarshalModuleBuiltins.Marshal.MarshalError; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; @@ -84,9 +81,9 @@ import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.CheckFunctionResultNode; import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ApiInitException; import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ImportException; -import com.oracle.graal.python.builtins.objects.code.CodeNodes; import com.oracle.graal.python.builtins.objects.code.PCode; import com.oracle.graal.python.builtins.objects.function.PArguments; +import com.oracle.graal.python.builtins.objects.memoryview.MemoryViewBuiltins.MemoryViewNode; import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; import com.oracle.graal.python.builtins.objects.module.FrozenModules; import com.oracle.graal.python.builtins.objects.module.PythonFrozenModule; @@ -103,7 +100,7 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromPythonObjectNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode; -import com.oracle.graal.python.nodes.call.GenericInvokeNode; +import com.oracle.graal.python.nodes.call.CallDispatchers; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; @@ -117,7 +114,7 @@ import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; @@ -260,8 +257,6 @@ public abstract static class GetMagic extends PythonBuiltinNode { MAGIC_NUMBER_BYTES[3] = '\n'; } - @Child PythonObjectFactory factory = PythonObjectFactory.create(); // GR-47032 - @Specialization(guards = "isSingleContext()") PBytes runCachedSingleContext( @Cached(value = "getMagicNumberPBytes()", weak = true) PBytes magicBytes) { @@ -269,12 +264,13 @@ PBytes runCachedSingleContext( } @Specialization(replaces = "runCachedSingleContext") - PBytes run() { - return factory.createBytes(MAGIC_NUMBER_BYTES); + PBytes run( + @Bind PythonLanguage language) { + return PFactory.createBytes(language, MAGIC_NUMBER_BYTES); } protected PBytes getMagicNumberPBytes() { - return factory.createBytes(MAGIC_NUMBER_BYTES); + return PFactory.createBytes(PythonLanguage.get(this), MAGIC_NUMBER_BYTES); } } @@ -351,7 +347,7 @@ static int doPythonModule(VirtualFrame frame, PythonModule extensionModule, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary(limit = "1") InteropLibrary lib, @Cached ExecModuleNode execModuleNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object nativeModuleDef = extensionModule.getNativeModuleDef(); if (nativeModuleDef == null) { return 0; @@ -368,7 +364,7 @@ static int doPythonModule(VirtualFrame frame, PythonModule extensionModule, PythonContext context = PythonContext.get(inliningTarget); if (!context.hasCApiContext()) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.SystemError, ErrorMessages.CAPI_NOT_YET_INITIALIZED); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.SystemError, ErrorMessages.CAPI_NOT_YET_INITIALIZED); } /* @@ -449,7 +445,7 @@ static Object run(VirtualFrame frame, PythonObject moduleSpec, return builtinModule; } CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, toTruffleStringUncached("_imp.create_builtin")); + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, toTruffleStringUncached("_imp.create_builtin")); } } @@ -459,13 +455,13 @@ public abstract static class ExecBuiltin extends PythonBuiltinNode { @Specialization @TruffleBoundary public Object exec(PythonModule pythonModule) { - final Python3Core core = getContext(); - if (!ImageInfo.inImageBuildtimeCode()) { + final PythonContext context = getContext(); + if (!context.getEnv().isPreInitialization()) { final PythonBuiltins builtins = pythonModule.getBuiltins(); assert builtins != null; // this is a builtin, therefore its builtins must have been // set at this point if (!builtins.isInitialized()) { - doPostInit(core, builtins); + doPostInit(context, builtins); builtins.setInitialized(true); } } @@ -540,12 +536,13 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static Object run(VirtualFrame frame, TruffleString name, Object dataObj, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Cached TruffleString.EqualNode equalNode, @Cached InlinedConditionProfile isCodeObjectProfile, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { FrozenInfo info; if (dataObj != PNone.NONE) { try { @@ -558,7 +555,7 @@ static Object run(VirtualFrame frame, TruffleString name, Object dataObj, raiseFrozenError(frame, FROZEN_INVALID, name, constructAndRaiseNode.get(inliningTarget)); } } else { - FrozenResult result = findFrozen(PythonContext.get(inliningTarget), name, equalNode); + FrozenResult result = findFrozen(context, name, equalNode); FrozenStatus status = result.status; info = result.info; raiseFrozenError(frame, status, name, constructAndRaiseNode.get(inliningTarget)); @@ -567,20 +564,20 @@ static Object run(VirtualFrame frame, TruffleString name, Object dataObj, Object code = null; try { - code = MarshalModuleBuiltins.Marshal.load(info.data, info.size); + code = MarshalModuleBuiltins.Marshal.load(context, info.data, info.size); } catch (MarshalError | NumberFormatException e) { raiseFrozenError(frame, FROZEN_INVALID, name, constructAndRaiseNode.get(inliningTarget)); } if (!isCodeObjectProfile.profile(inliningTarget, code instanceof PCode)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.NOT_A_CODE_OBJECT, name); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.NOT_A_CODE_OBJECT, name); } return code; } } - @Builtin(name = "find_frozen", parameterNames = {"name", "withData"}, minNumOfPositionalArgs = 1, isPublic = false, doc = "find_frozen($module, name, /, *, withdata=False)\n" + + @Builtin(name = "find_frozen", parameterNames = {"name", "withData"}, minNumOfPositionalArgs = 1, doc = "find_frozen($module, name, /, *, withdata=False)\n" + "--\n" + "\n" + "Return info about the corresponding frozen module (if there is one) or None.\n" + @@ -603,12 +600,13 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - Object run(VirtualFrame frame, TruffleString name, boolean withData, + static Object run(VirtualFrame frame, TruffleString name, boolean withData, + @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached MemoryViewNode memoryViewNode, @Cached TruffleString.EqualNode equalNode, - @Cached PConstructAndRaiseNode constructAndRaiseNode, - @Cached PythonObjectFactory factory) { - FrozenResult result = findFrozen(getContext(), name, equalNode); + @Cached PConstructAndRaiseNode constructAndRaiseNode) { + FrozenResult result = findFrozen(context, name, equalNode); FrozenStatus status = result.status; FrozenInfo info = result.info; @@ -624,7 +622,7 @@ Object run(VirtualFrame frame, TruffleString name, boolean withData, PMemoryView data = null; if (withData) { - data = memoryViewNode.execute(frame, factory.createBytes(info.data)); + data = memoryViewNode.execute(frame, PFactory.createBytes(context.getLanguage(inliningTarget), info.data)); } Object[] returnValues = new Object[]{ @@ -633,7 +631,7 @@ Object run(VirtualFrame frame, TruffleString name, boolean withData, info.origName == null ? PNone.NONE : info.origName }; - return factory.createTuple(returnValues); + return PFactory.createTuple(context.getLanguage(inliningTarget), returnValues); } } @@ -689,17 +687,17 @@ public static PythonModule importFrozenModuleObject(Python3Core core, TruffleStr } } - PCode code = (PCode) MarshalModuleBuiltins.Marshal.load(info.data, info.size); + PCode code = (PCode) MarshalModuleBuiltins.Marshal.load(core.getContext(), info.data, info.size); - PythonModule module = globals == null ? core.factory().createPythonModule(name) : globals; + PythonModule module = globals == null ? PFactory.createPythonModule(core.getLanguage(), name) : globals; if (info.isPackage) { /* Set __path__ to the empty list */ - WriteAttributeToPythonObjectNode.getUncached().execute(module, T___PATH__, core.factory().createList()); + WriteAttributeToPythonObjectNode.getUncached().execute(module, T___PATH__, PFactory.createList(core.getLanguage())); } - RootCallTarget callTarget = CodeNodes.GetCodeCallTargetNode.executeUncached(code); - GenericInvokeNode.getUncached().execute(callTarget, PArguments.withGlobals(module)); + RootCallTarget callTarget = code.getRootCallTarget(); + CallDispatchers.SimpleIndirectInvokeNode.executeUncached(callTarget, PArguments.withGlobals(module)); Object origName = info.origName == null ? PNone.NONE : info.origName; WriteAttributeToPythonObjectNode.getUncached().execute(module, T___ORIGNAME__, origName); @@ -767,10 +765,10 @@ public abstract static class SourceHashNode extends PythonBinaryClinicBuiltinNod @Specialization static PBytes run(long magicNumber, Object sourceBuffer, @Bind("this") Node inliningTarget, - @Cached BytesNodes.HashBufferNode hashBufferNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language, + @Cached BytesNodes.HashBufferNode hashBufferNode) { long sourceHash = hashBufferNode.execute(inliningTarget, sourceBuffer); - return factory.createBytes(computeHash(magicNumber, sourceHash)); + return PFactory.createBytes(language, computeHash(magicNumber, sourceHash)); } @TruffleBoundary @@ -814,8 +812,8 @@ public Object run(PCode code, TruffleString path) { public abstract static class ExtensionSuffixesNode extends PythonBuiltinNode { @Specialization Object run( - @Cached PythonObjectFactory factory) { - return factory.createList(new Object[]{PythonContext.get(this).getSoAbi(), T_EXT_SO, T_EXT_PYD}); + @Bind PythonLanguage language) { + return PFactory.createList(language, new Object[]{PythonContext.get(this).getSoAbi(), T_EXT_SO, T_EXT_PYD}); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ItertoolsModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ItertoolsModuleBuiltins.java index c2182724a6..291fc4f1b9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ItertoolsModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ItertoolsModuleBuiltins.java @@ -25,91 +25,37 @@ */ package com.oracle.graal.python.builtins.modules; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.OverflowError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; -import static com.oracle.graal.python.nodes.ErrorMessages.ARG_CANNOT_BE_NEGATIVE; -import static com.oracle.graal.python.nodes.ErrorMessages.EXPECTED_INT_AS_R; -import static com.oracle.graal.python.nodes.ErrorMessages.ISLICE_WRONG_ARGS; -import static com.oracle.graal.python.nodes.ErrorMessages.MUST_BE_NON_NEGATIVE; -import static com.oracle.graal.python.nodes.ErrorMessages.NUMBER_IS_REQUIRED; -import static com.oracle.graal.python.nodes.ErrorMessages.STEP_FOR_ISLICE_MUST_BE; -import static com.oracle.graal.python.nodes.ErrorMessages.S_EXPECTED_GOT_P; -import static com.oracle.graal.python.nodes.ErrorMessages.S_FOR_ISLICE_MUST_BE; import static com.oracle.graal.python.nodes.ErrorMessages.S_MUST_BE_S; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___COPY__; -import java.util.ArrayList; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.IterNode; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.builtins.objects.iterator.IteratorNodes.ToArrayNode; -import com.oracle.graal.python.builtins.objects.itertools.PAccumulate; -import com.oracle.graal.python.builtins.objects.itertools.PChain; -import com.oracle.graal.python.builtins.objects.itertools.PCombinations; -import com.oracle.graal.python.builtins.objects.itertools.PCombinationsWithReplacement; -import com.oracle.graal.python.builtins.objects.itertools.PCompress; -import com.oracle.graal.python.builtins.objects.itertools.PCount; -import com.oracle.graal.python.builtins.objects.itertools.PCycle; -import com.oracle.graal.python.builtins.objects.itertools.PDropwhile; -import com.oracle.graal.python.builtins.objects.itertools.PFilterfalse; -import com.oracle.graal.python.builtins.objects.itertools.PGroupBy; -import com.oracle.graal.python.builtins.objects.itertools.PGrouper; -import com.oracle.graal.python.builtins.objects.itertools.PIslice; -import com.oracle.graal.python.builtins.objects.itertools.PPairwise; -import com.oracle.graal.python.builtins.objects.itertools.PPermutations; -import com.oracle.graal.python.builtins.objects.itertools.PProduct; -import com.oracle.graal.python.builtins.objects.itertools.PRepeat; -import com.oracle.graal.python.builtins.objects.itertools.PStarmap; -import com.oracle.graal.python.builtins.objects.itertools.PTakewhile; import com.oracle.graal.python.builtins.objects.itertools.PTeeDataObject; -import com.oracle.graal.python.builtins.objects.itertools.PZipLongest; -import com.oracle.graal.python.builtins.objects.type.TypeNodes; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode; import com.oracle.graal.python.lib.PyCallableCheckNode; -import com.oracle.graal.python.lib.PyLongAsIntNode; -import com.oracle.graal.python.lib.PyNumberAsSizeNode; -import com.oracle.graal.python.lib.PyNumberCheckNode; -import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyObjectLookupAttr; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode; +import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.util.CannotCastException; -import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; -import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile; -import com.oracle.truffle.api.profiles.LoopConditionProfile; @CoreFunctions(defineModule = "itertools") public final class ItertoolsModuleBuiltins extends PythonBuiltins { @@ -119,382 +65,6 @@ protected List> getNodeFa return ItertoolsModuleBuiltinsFactory.getFactories(); } - @Builtin(name = "accumulate", minNumOfPositionalArgs = 2, varArgsMarker = true, parameterNames = {"cls", "iterable", "func"}, keywordOnlyNames = { - "initial"}, constructsClass = PythonBuiltinClassType.PAccumulate, doc = "accumulate(iterable) --> accumulate object\n\nReturn series of accumulated sums.") - @GenerateNodeFactory - public abstract static class AccumulateNode extends PythonBuiltinNode { - - @Specialization(guards = "isTypeNode.execute(inliningTarget, cls)") - protected static PAccumulate construct(VirtualFrame frame, Object cls, Object iterable, @SuppressWarnings("unused") PNone func, @SuppressWarnings("unused") PNone initial, - @Bind("this") Node inliningTarget, - @Shared("getIter") @Cached PyObjectGetIter getIter, - @SuppressWarnings("unused") @Shared("typeNode") @Cached IsTypeNode isTypeNode, - @Shared @Cached PythonObjectFactory factory) { - return create(frame, inliningTarget, cls, iterable, null, null, getIter, factory); - } - - @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "!isNone(initial)"}) - protected static PAccumulate construct(VirtualFrame frame, Object cls, Object iterable, @SuppressWarnings("unused") PNone func, Object initial, - @Bind("this") Node inliningTarget, - @Shared("getIter") @Cached PyObjectGetIter getIter, - @SuppressWarnings("unused") @Shared("typeNode") @Cached IsTypeNode isTypeNode, - @Shared @Cached PythonObjectFactory factory) { - return create(frame, inliningTarget, cls, iterable, null, initial, getIter, factory); - } - - @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "!isNone(func)"}) - protected static PAccumulate construct(VirtualFrame frame, Object cls, Object iterable, Object func, @SuppressWarnings("unused") PNone initial, - @Bind("this") Node inliningTarget, - @Shared("getIter") @Cached PyObjectGetIter getIter, - @SuppressWarnings("unused") @Shared("typeNode") @Cached IsTypeNode isTypeNode, - @Shared @Cached PythonObjectFactory factory) { - return create(frame, inliningTarget, cls, iterable, func, null, getIter, factory); - } - - @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "!isNone(func)", "!isNone(initial)"}) - protected static PAccumulate construct(VirtualFrame frame, Object cls, Object iterable, Object func, Object initial, - @Bind("this") Node inliningTarget, - @Shared("getIter") @Cached PyObjectGetIter getIter, - @SuppressWarnings("unused") @Shared("typeNode") @Cached IsTypeNode isTypeNode, - @Shared @Cached PythonObjectFactory factory) { - return create(frame, inliningTarget, cls, iterable, func, initial, getIter, factory); - } - - private static PAccumulate create(VirtualFrame frame, Node inliningTarget, Object cls, Object iterable, Object func, Object initial, PyObjectGetIter getIter, PythonObjectFactory factory) { - PAccumulate self = factory.createAccumulate(cls); - self.setIterable(getIter.execute(frame, inliningTarget, iterable)); - self.setFunc(func instanceof PNone ? null : func); - self.setTotal(null); - self.setInitial(initial instanceof PNone ? null : initial); - return self; - } - - @Specialization(guards = "!isTypeNode.execute(inliningTarget, cls)") - @SuppressWarnings("unused") - static Object notype(Object cls, Object iterable, Object func, Object initial, - @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Shared("typeNode") @Cached IsTypeNode isTypeNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - } - - @Builtin(name = "combinations", minNumOfPositionalArgs = 3, constructsClass = PythonBuiltinClassType.PCombinations, parameterNames = {"cls", "iterable", - "r"}, doc = "combinations(iterable, r) --> combinations object\n\n" + - "Return successive r-length combinations of elements in the iterable.\n\n" + - "combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)") - @ArgumentClinic(name = "r", conversion = ArgumentClinic.ClinicConversion.Int) - @GenerateNodeFactory - public abstract static class CombinationsNode extends PythonTernaryClinicBuiltinNode { - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return ItertoolsModuleBuiltinsClinicProviders.CombinationsNodeClinicProviderGen.INSTANCE; - } - - @Specialization - static Object construct(VirtualFrame frame, Object cls, Object iterable, int r, - @Bind("this") Node inliningTarget, - @Cached IsTypeNode isTypeNode, - @Cached ToArrayNode toArrayNode, - @Cached LoopConditionProfile indicesLoopProfile, - @Cached InlinedConditionProfile wrongTypeProfile, - @Cached InlinedConditionProfile negativeProfile, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!wrongTypeProfile.profile(inliningTarget, isTypeNode.execute(inliningTarget, cls))) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - if (negativeProfile.profile(inliningTarget, r < 0)) { - throw raiseNode.get(inliningTarget).raise(ValueError, MUST_BE_NON_NEGATIVE, "r"); - } - - PCombinations self = factory.createCombinations(cls); - self.setPool(toArrayNode.execute(frame, iterable)); - - int[] indices = new int[r]; - indicesLoopProfile.profileCounted(r); - for (int i = 0; indicesLoopProfile.inject(i < r); i++) { - indices[i] = i; - } - self.setIndices(indices); - self.setR(r); - self.setLastResult(null); - self.setStopped(r > self.getPool().length); - - return self; - } - } - - @Builtin(name = "combinations_with_replacement", minNumOfPositionalArgs = 3, constructsClass = PythonBuiltinClassType.PCombinationsWithReplacement, parameterNames = {"cls", "iterable", - "r"}, doc = "combinations_with_replacement(iterable, r) --> combinations_with_replacement object\n\n" + - "Return successive r-length combinations of elements in the iterable\n" + - "allowing individual elements to have successive repeats.\n" + - " combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC") - @ArgumentClinic(name = "r", conversion = ArgumentClinic.ClinicConversion.Int) - @GenerateNodeFactory - public abstract static class CombinationsWithReplacementNode extends PythonTernaryClinicBuiltinNode { - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return ItertoolsModuleBuiltinsClinicProviders.CombinationsWithReplacementNodeClinicProviderGen.INSTANCE; - } - - @Specialization - static Object construct(VirtualFrame frame, Object cls, Object iterable, int r, - @Bind("this") Node inliningTarget, - @Cached IsTypeNode isTypeNode, - @Cached ToArrayNode toArrayNode, - @Cached InlinedConditionProfile wrongTypeProfile, - @Cached InlinedConditionProfile negativeProfile, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!wrongTypeProfile.profile(inliningTarget, isTypeNode.execute(inliningTarget, cls))) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - if (negativeProfile.profile(inliningTarget, r < 0)) { - throw raiseNode.get(inliningTarget).raise(ValueError, MUST_BE_NON_NEGATIVE, "r"); - } - PCombinationsWithReplacement self = factory.createCombinationsWithReplacement(cls); - self.setPool(toArrayNode.execute(frame, iterable)); - self.setR(r); - - self.setIndices(new int[r]); - self.setLastResult(null); - self.setStopped(self.getPool().length == 0 && r > 0); - - return self; - } - } - - @Builtin(name = "compress", minNumOfPositionalArgs = 3, constructsClass = PythonBuiltinClassType.PCompress, parameterNames = {"cls", "data", - "selectors"}, doc = "Make an iterator that filters elements from *data* returning\n" + - "only those that have a corresponding element in *selectors* that evaluates to\n" + - "``True``. Stops when either the *data* or *selectors* iterables has been\n" + - "exhausted.\n" + - "Equivalent to::\n\n" + - "\tdef compress(data, selectors):\n" + - "\t\t# compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F\n" + - "\t\treturn (d for d, s in zip(data, selectors) if s)") - @GenerateNodeFactory - public abstract static class CompressNode extends PythonTernaryBuiltinNode { - @Specialization - static PCompress construct(VirtualFrame frame, Object cls, Object data, Object selectors, - @Bind("this") Node inliningTarget, - @Cached PyObjectGetIter getIter, - @Cached IsTypeNode isTypeNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!isTypeNode.execute(inliningTarget, cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - PCompress self = factory.createCompress(cls); - self.setData(getIter.execute(frame, inliningTarget, data)); - self.setSelectors(getIter.execute(frame, inliningTarget, selectors)); - return self; - } - } - - @Builtin(name = "cycle", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PCycle, doc = "Make an iterator returning elements from the iterable and\n" + - " saving a copy of each. When the iterable is exhausted, return\n" + - " elements from the saved copy. Repeats indefinitely.\n\n" + - " Equivalent to :\n\n" + - " def cycle(iterable):\n" + - " \tsaved = []\n" + - " \tfor element in iterable:\n" + - " \t\tyield element\n" + - " \t\tsaved.append(element)\n" + - " \twhile saved:\n" + - " \t\tfor element in saved:\n" + - " \t\t\tyield element") - @GenerateNodeFactory - public abstract static class CycleNode extends PythonVarargsBuiltinNode { - - @Specialization - static PCycle construct(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode, - @Cached PyObjectGetIter getIter, - @Cached IsTypeNode isTypeNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!isTypeNode.execute(inliningTarget, cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "cycle()"); - } - if (args.length != 1) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_EXPECTED_D_ARGS, "cycle", 1); - } - Object iterable = args[0]; - PCycle self = factory.createCycle(cls); - self.setSaved(new ArrayList<>()); - self.setIterable(getIter.execute(frame, inliningTarget, iterable)); - self.setIndex(0); - self.setFirstpass(false); - return self; - } - } - - @Builtin(name = "dropwhile", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDropwhile, doc = "dropwhile(predicate, iterable) --> dropwhile object\n\n" + - "Drop items from the iterable while predicate(item) is true.\n" + - "Afterwards, return every element until the iterable is exhausted.") - @GenerateNodeFactory - public abstract static class DropwhileNode extends PythonVarargsBuiltinNode { - @Specialization - static PDropwhile construct(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode, - @Cached PyObjectGetIter getIter, - @Cached IsTypeNode isTypeNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!isTypeNode.execute(inliningTarget, cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "dropwhile()"); - } - if (args.length != 2) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_EXPECTED_D_ARGS, "dropwhile", 2); - } - Object predicate = args[0]; - Object iterable = args[1]; - PDropwhile self = factory.createDropwhile(cls); - self.setPredicate(predicate); - self.setIterable(getIter.execute(frame, inliningTarget, iterable)); - self.setDoneDropping(false); - return self; - } - } - - @Builtin(name = "filterfalse", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PFilterfalse, doc = "filterfalse(function or None, sequence) --> filterfalse object\n\n" + - "Return those items of sequence for which function(item) is false.\n" + - "If function is None, return the items that are false.") - @GenerateNodeFactory - public abstract static class FilterFalseNode extends PythonVarargsBuiltinNode { - - @Specialization - static PFilterfalse construct(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode, - @Cached PyObjectGetIter getIter, - @Cached IsTypeNode isTypeNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!isTypeNode.execute(inliningTarget, cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "filterfalse()"); - } - if (args.length != 2) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_EXPECTED_D_ARGS, "filterfalse", 2); - } - Object func = args[0]; - Object sequence = args[1]; - PFilterfalse self = factory.createFilterfalse(cls); - self.setFunc(PGuards.isPNone(func) ? null : func); - self.setSequence(getIter.execute(frame, inliningTarget, sequence)); - return self; - } - } - - @Builtin(name = "groupby", minNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PGroupBy, parameterNames = {"cls", "iterable", - "key"}, doc = "Make an iterator that returns consecutive keys and groups from the\n" + - "iterable. The key is a function computing a key value for each\n" + - "element. If not specified or is None, key defaults to an identity\n" + - "function and returns the element unchanged. Generally, the\n" + - "iterable needs to already be sorted on the same key function.\n\n" + - "The returned group is itself an iterator that shares the\n" + - "underlying iterable with groupby(). Because the source is shared,\n" + - "when the groupby object is advanced, the previous group is no\n" + - "longer visible. So, if that data is needed later, it should be\n" + - "stored as a list:\n\n" + - "\tgroups = []\n" + - "\tuniquekeys = []\n" + - "\tfor k, g in groupby(data, keyfunc):\n" + - "\t\tgroups.append(list(g)) # Store group iterator as a list\n" + - "\t\tuniquekeys.append(k)") - @ArgumentClinic(name = "key", defaultValue = "PNone.NONE") - @GenerateNodeFactory - public abstract static class GroupByNode extends PythonTernaryClinicBuiltinNode { - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return ItertoolsModuleBuiltinsClinicProviders.GroupByNodeClinicProviderGen.INSTANCE; - } - - @Specialization - static PGroupBy construct(VirtualFrame frame, Object cls, Object iterable, Object key, - @Bind("this") Node inliningTarget, - @Cached PyObjectGetIter getIter, - @Cached IsTypeNode isTypeNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!isTypeNode.execute(inliningTarget, cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - PGroupBy self = factory.createGroupBy(cls); - self.setKeyFunc(PGuards.isNone(key) ? null : key); - self.setIt(getIter.execute(frame, inliningTarget, iterable)); - return self; - } - } - - @Builtin(name = "_grouper", minNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PGrouper, parameterNames = {"$self", "parent", "tgtkey"}) - @GenerateNodeFactory - public abstract static class GrouperNode extends PythonTernaryBuiltinNode { - @Specialization - static PGrouper construct(Object cls, Object parent, Object tgtKey, - @Bind("this") Node inliningTarget, - @Cached InlinedConditionProfile wrongTypeProfile, - @Cached InlinedConditionProfile isPGroupByProfile, - @Cached IsTypeNode isTypeNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!wrongTypeProfile.profile(inliningTarget, isTypeNode.execute(inliningTarget, cls))) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - if (!isPGroupByProfile.profile(inliningTarget, parent instanceof PGroupBy)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.INCORRECT_USAGE_OF_INTERNAL_GROUPER); - } - return factory.createGrouper((PGroupBy) parent, tgtKey); - } - } - - @Builtin(name = "takewhile", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PTakewhile, doc = "Make an iterator that returns elements from the iterable as\n" + - "long as the predicate is true.\n\nEquivalent to :\n\ndef takewhile(predicate, iterable):\n\tfor x in iterable:\n\t\tif predicate(x):\n\t\t\tyield x\n" + - "\t\telse:\n\t\t\tbreak") - @GenerateNodeFactory - public abstract static class TakewhileNode extends PythonVarargsBuiltinNode { - @Specialization - static PTakewhile construct(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode, - @Cached PyObjectGetIter getIter, - @Cached IsTypeNode isTypeNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!isTypeNode.execute(inliningTarget, cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "takewhile()"); - } - if (args.length != 2) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_EXPECTED_D_ARGS, "takewhile", 2); - } - Object predicate = args[0]; - Object iterable = args[1]; - PTakewhile self = factory.createTakewhile(cls); - self.setPredicate(predicate); - self.setIterable(getIter.execute(frame, inliningTarget, iterable)); - return self; - } - } - @Builtin(name = "tee", minNumOfPositionalArgs = 1, parameterNames = {"iterable", "n"}) @ArgumentClinic(name = "n", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "2") @GenerateNodeFactory @@ -507,15 +77,15 @@ protected ArgumentClinicProvider getArgumentClinic() { @SuppressWarnings("unused") @Specialization(guards = "n < 0") static Object negativeN(Object iterable, int n, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, S_MUST_BE_S, "n", ">=0"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, S_MUST_BE_S, "n", ">=0"); } @SuppressWarnings("unused") @Specialization(guards = "n == 0") static Object zeroN(Object iterable, int n, - @Shared @Cached PythonObjectFactory factory) { - return factory.createTuple(PythonUtils.EMPTY_OBJECT_ARRAY); + @Bind PythonLanguage language) { + return PFactory.createTuple(language, PythonUtils.EMPTY_OBJECT_ARRAY); } @Specialization(guards = "n > 0") @@ -524,16 +94,16 @@ static Object tee(VirtualFrame frame, Object iterable, int n, @Cached IterNode iterNode, @Cached PyObjectLookupAttr getAttrNode, @Cached PyCallableCheckNode callableCheckNode, - @Cached CallVarargsMethodNode callNode, + @Cached CallNode callNode, @Cached InlinedBranchProfile notCallableProfile, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { Object it = iterNode.execute(frame, iterable, PNone.NO_VALUE); Object copyCallable = getAttrNode.execute(frame, inliningTarget, it, T___COPY__); if (!callableCheckNode.execute(inliningTarget, copyCallable)) { notCallableProfile.enter(inliningTarget); // as in Tee.__NEW__() - PTeeDataObject dataObj = factory.createTeeDataObject(it); - it = factory.createTee(dataObj, 0); + PTeeDataObject dataObj = PFactory.createTeeDataObject(language, it); + it = PFactory.createTee(language, dataObj, 0); } // return tuple([it] + [it.__copy__() for i in range(1, n)]) @@ -542,562 +112,9 @@ static Object tee(VirtualFrame frame, Object iterable, int n, copyCallable = getAttrNode.execute(frame, inliningTarget, it, T___COPY__); for (int i = 1; i < n; i++) { - tupleObjs[i] = callNode.execute(frame, copyCallable, PythonUtils.EMPTY_OBJECT_ARRAY, PKeyword.EMPTY_KEYWORDS); + tupleObjs[i] = callNode.execute(frame, copyCallable); } - return factory.createTuple(tupleObjs); + return PFactory.createTuple(language, tupleObjs); } - } - - @Builtin(name = "_tee_dataobject", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PTeeDataObject) - @GenerateNodeFactory - public abstract static class TeeDataObjectNode extends PythonVarargsBuiltinNode { - @SuppressWarnings("unused") - @Specialization - PTeeDataObject construct(Object cls, Object[] arguments, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Cached IsTypeNode isTypeNode, - @Cached InlinedBranchProfile errorProfile, - @Cached PythonObjectFactory factory) { - if (!isTypeNode.execute(inliningTarget, cls)) { - errorProfile.enter(inliningTarget); - throw raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - return factory.createTeeDataObject(); - } - } - - @Builtin(name = "permutations", minNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PPermutations, parameterNames = {"cls", "iterable", - "r"}, doc = "permutations(iterable[, r]) --> permutations object\n\n" + - "Return successive r-length permutations of elements in the iterable.\n\n" + "permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)") - @ArgumentClinic(name = "r", defaultValue = "PNone.NONE") - @GenerateNodeFactory - public abstract static class PermutationsNode extends PythonTernaryClinicBuiltinNode { - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return ItertoolsModuleBuiltinsClinicProviders.PermutationsNodeClinicProviderGen.INSTANCE; - } - - @Specialization - static Object construct(VirtualFrame frame, Object cls, Object iterable, Object rArg, - @Bind("this") Node inliningTarget, - @Cached InlinedConditionProfile rIsNoneProfile, - @Cached ToArrayNode toArrayNode, - @Cached CastToJavaIntExactNode castToInt, - @Cached InlinedConditionProfile wrongTypeProfile, - @Cached InlinedBranchProfile wrongRprofile, - @Cached InlinedBranchProfile negRprofile, - @Cached InlinedConditionProfile nrProfile, - @Cached InlinedLoopConditionProfile indicesLoopProfile, - @Cached InlinedLoopConditionProfile cyclesLoopProfile, - @Cached IsTypeNode isTypeNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!wrongTypeProfile.profile(inliningTarget, isTypeNode.execute(inliningTarget, cls))) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - int r; - Object[] pool = toArrayNode.execute(frame, iterable); - if (rIsNoneProfile.profile(inliningTarget, PGuards.isNone(rArg))) { - r = pool.length; - } else { - try { - r = castToInt.execute(inliningTarget, rArg); - } catch (CannotCastException e) { - wrongRprofile.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(TypeError, EXPECTED_INT_AS_R); - } - if (r < 0) { - negRprofile.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(ValueError, MUST_BE_NON_NEGATIVE, "r"); - } - } - PPermutations self = factory.createPermutations(cls); - self.setPool(pool); - self.setR(r); - int n = pool.length; - self.setN(n); - int nMinusR = n - r; - if (nrProfile.profile(inliningTarget, nMinusR < 0)) { - self.setStopped(true); - self.setRaisedStopIteration(true); - } else { - self.setStopped(false); - int[] indices = new int[n]; - indicesLoopProfile.profileCounted(inliningTarget, indices.length); - LoopNode.reportLoopCount(inliningTarget, indices.length); - for (int i = 0; indicesLoopProfile.inject(inliningTarget, i < indices.length); i++) { - indices[i] = i; - } - self.setIndices(indices); - int[] cycles = new int[r]; - int idx = 0; - cyclesLoopProfile.profileCounted(inliningTarget, r); - LoopNode.reportLoopCount(inliningTarget, r); - for (int i = n; cyclesLoopProfile.inject(inliningTarget, i > nMinusR); i--) { - cycles[idx++] = i; - } - self.setCycles(cycles); - self.setRaisedStopIteration(false); - self.setStarted(false); - return self; - } - return self; - } - } - - @Builtin(name = "product", minNumOfPositionalArgs = 1, takesVarArgs = true, constructsClass = PythonBuiltinClassType.PProduct, keywordOnlyNames = { - "repeat"}, doc = "Cartesian product of input iterables.\n\n" + - "Equivalent to nested for-loops in a generator expression. For example,\n ``product(A, B)`` returns the same as ``((x,y) for x in A for y in B)``.\n\n" + - "The nested loops cycle like an odometer with the rightmost element advancing\n on every iteration. This pattern creates a lexicographic ordering so that if\n" + - " the input's iterables are sorted, the product tuples are emitted in sorted\n order.\n\nTo compute the product of an iterable with itself, specify the number of\n" + - " repetitions with the optional *repeat* keyword argument. For example,\n ``product(A, repeat=4)`` means the same as ``product(A, A, A, A)``.\n\n" + - "This function is equivalent to the following code, except that the\n actual implementation does not build up intermediate results in memory::\n\n" + - "def product(*args, **kwds):\n\t# product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy\n\t# product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111\n" + - "\tpools = map(tuple, args) * kwds.get('repeat', 1)\n\tresult = [[]]\n\tfor pool in pools:\n\t\tresult = [x+[y] for x in result for y in pool]\n" + - "\tfor prod in result:\n\t\tyield tuple(prod)") - @GenerateNodeFactory - public abstract static class ProductNode extends PythonBuiltinNode { - - @Specialization(guards = "isTypeNode.execute(inliningTarget, cls)") - static Object constructNoneRepeat(VirtualFrame frame, Object cls, Object[] iterables, @SuppressWarnings("unused") PNone repeat, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @Shared @Cached ToArrayNode toArrayNode, - @SuppressWarnings("unused") @Shared("typeNode") @Cached IsTypeNode isTypeNode, - @Shared @Cached PythonObjectFactory factory) { - PProduct self = factory.createProduct(cls); - constructOneRepeat(frame, self, iterables, toArrayNode); - return self; - } - - @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "repeat == 1"}, limit = "1") - static Object constructOneRepeat(VirtualFrame frame, Object cls, Object[] iterables, @SuppressWarnings("unused") int repeat, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @Shared @Cached ToArrayNode toArrayNode, - @SuppressWarnings("unused") @Exclusive @Cached IsTypeNode isTypeNode, - @Shared @Cached PythonObjectFactory factory) { - PProduct self = factory.createProduct(cls); - constructOneRepeat(frame, self, iterables, toArrayNode); - return self; - } - - @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "repeat > 1"}, limit = "1") - static Object construct(VirtualFrame frame, Object cls, Object[] iterables, int repeat, - @Bind("this") Node inliningTarget, - @Shared @Cached ToArrayNode toArrayNode, - @Cached InlinedLoopConditionProfile loopProfile, - @SuppressWarnings("unused") @Exclusive @Cached IsTypeNode isTypeNode, - @Shared @Cached PythonObjectFactory factory) { - Object[][] lists = unpackIterables(frame, iterables, toArrayNode); - Object[][] gears = new Object[lists.length * repeat][]; - loopProfile.profileCounted(inliningTarget, repeat); - LoopNode.reportLoopCount(inliningTarget, repeat); - for (int i = 0; loopProfile.inject(inliningTarget, i < repeat); i++) { - PythonUtils.arraycopy(lists, 0, gears, i * lists.length, lists.length); - } - PProduct self = factory.createProduct(cls); - construct(self, gears); - return self; - } - - @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "repeat == 0"}, limit = "1") - static Object constructNoRepeat(Object cls, @SuppressWarnings("unused") Object[] iterables, @SuppressWarnings("unused") int repeat, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached IsTypeNode isTypeNode, - @Shared @Cached PythonObjectFactory factory) { - PProduct self = factory.createProduct(cls); - self.setGears(new Object[0][]); - self.setIndices(new int[0]); - self.setLst(null); - self.setStopped(false); - return self; - } - - @SuppressWarnings("unused") - @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "repeat < 0"}, limit = "1") - static Object constructNeg(Object cls, Object[] iterables, int repeat, - @Bind("this") Node inliningTarget, - @Exclusive @Cached IsTypeNode isTypeNode, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ARG_CANNOT_BE_NEGATIVE, "repeat"); - } - - private static void constructOneRepeat(VirtualFrame frame, PProduct self, Object[] iterables, ToArrayNode toArrayNode) { - Object[][] gears = unpackIterables(frame, iterables, toArrayNode); - construct(self, gears); - } - - private static void construct(PProduct self, Object[][] gears) { - self.setGears(gears); - for (int i = 0; i < gears.length; i++) { - if (gears[i].length == 0) { - self.setIndices(null); - self.setLst(null); - self.setStopped(true); - return; - } - } - self.setIndices(new int[gears.length]); - self.setLst(null); - self.setStopped(false); - } - - private static Object[][] unpackIterables(VirtualFrame frame, Object[] iterables, ToArrayNode toArrayNode) { - Object[][] lists = new Object[iterables.length][]; - for (int i = 0; i < lists.length; i++) { - lists[i] = toArrayNode.execute(frame, iterables[i]); - } - return lists; - } - - @Specialization(guards = "!isTypeNode.execute(inliningTarget, cls)") - @SuppressWarnings("unused") - static Object construct(Object cls, Object iterables, Object repeat, - @Bind("this") Node inliningTarget, - @Shared("typeNode") @Cached IsTypeNode isTypeNode, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - } - - @Builtin(name = "repeat", minNumOfPositionalArgs = 2, parameterNames = {"$self", "object", - "times"}, constructsClass = PythonBuiltinClassType.PRepeat, doc = "repeat(object [,times]) -> create an iterator which returns the object\n" + - "for the specified number of times. If not specified, returns the object\nendlessly.") - @ArgumentClinic(name = "times", defaultValue = "PNone.NONE", useDefaultForNone = true) - @GenerateNodeFactory - public abstract static class RepeatNode extends PythonTernaryClinicBuiltinNode { - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return ItertoolsModuleBuiltinsClinicProviders.RepeatNodeClinicProviderGen.INSTANCE; - } - - @Specialization(guards = "isTypeNode.execute(inliningTarget, cls)") - static Object constructNone(Object cls, Object object, @SuppressWarnings("unused") PNone times, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Shared("typeNode") @Cached IsTypeNode isTypeNode, - @Shared @Cached PythonObjectFactory factory) { - PRepeat self = factory.createRepeat(cls); - self.setElement(object); - self.setCnt(-1); - return self; - } - - @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "times < 0"}) - static Object constructNeg(Object cls, Object object, @SuppressWarnings("unused") int times, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Shared("typeNode") @Cached IsTypeNode isTypeNode, - @Shared @Cached PythonObjectFactory factory) { - PRepeat self = factory.createRepeat(cls); - self.setElement(object); - self.setCnt(0); - return self; - } - - @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "times >= 0"}) - static Object construct(Object cls, Object object, int times, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Shared("typeNode") @Cached IsTypeNode isTypeNode, - @Shared @Cached PythonObjectFactory factory) { - PRepeat self = factory.createRepeat(cls); - self.setElement(object); - self.setCnt(times); - return self; - } - - @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "times >= 0"}, limit = "1") - static Object construct(VirtualFrame frame, Object cls, Object object, long times, - @Bind("this") Node inliningTarget, - @Cached PyLongAsIntNode asIntNode, - @SuppressWarnings("unused") @Exclusive @Cached IsTypeNode isTypeNode, - @Shared @Cached PythonObjectFactory factory) { - PRepeat self = factory.createRepeat(cls); - self.setElement(object); - self.setCnt(asIntNode.execute(frame, inliningTarget, times)); - return self; - } - - @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "!isNone(times)", "!isInt(times)", "!isLong(times)"}) - @SuppressWarnings("unused") - static Object construct(Object cls, Object object, Object times, - @Bind("this") Node inliningTarget, - @Shared("typeNode") @Cached IsTypeNode isTypeNode, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, S_EXPECTED_GOT_P, "integer", times); - } - - @Specialization(guards = "!isTypeNode.execute(inliningTarget, cls)") - @SuppressWarnings("unused") - static Object notype(Object cls, Object object, Object times, - @Bind("this") Node inliningTarget, - @Shared("typeNode") @Cached IsTypeNode isTypeNode, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - - } - - @Builtin(name = "chain", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PChain, doc = "Return a chain object whose .__next__() method returns elements from the\n" + - "first iterable until it is exhausted, then elements from the next\niterable, until all of the iterables are exhausted.") - @GenerateNodeFactory - public abstract static class ChainNode extends PythonVarargsBuiltinNode { - - @Specialization - static PChain construct(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode, - @Cached PyObjectGetIter getIter, - @Cached IsTypeNode isTypeNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!isTypeNode.execute(inliningTarget, cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "chain()"); - } - PChain self = factory.createChain(cls); - self.setSource(getIter.execute(frame, inliningTarget, factory.createList(args))); - self.setActive(PNone.NONE); - return self; - } - } - - @Builtin(name = "count", minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.PCount, parameterNames = {"cls", "start", "step"}) - @ArgumentClinic(name = "start", defaultValue = "0", useDefaultForNone = true) - @ArgumentClinic(name = "step", defaultValue = "1", useDefaultForNone = true) - @GenerateNodeFactory - public abstract static class CountNode extends PythonTernaryClinicBuiltinNode { - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return ItertoolsModuleBuiltinsClinicProviders.CountNodeClinicProviderGen.INSTANCE; - } - - @Specialization - static Object construct(Object cls, Object start, Object step, - @Bind("this") Node inliningTarget, - @Cached PyNumberCheckNode checkNode, - @Cached IsTypeNode isTypeNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!isTypeNode.execute(inliningTarget, cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - if (!checkNode.execute(inliningTarget, start)) { - throw raiseNode.get(inliningTarget).raise(TypeError, NUMBER_IS_REQUIRED); - } - if (!checkNode.execute(inliningTarget, step)) { - throw raiseNode.get(inliningTarget).raise(TypeError, NUMBER_IS_REQUIRED); - } - PCount self = factory.createCount(cls); - self.setCnt(start); - self.setStep(step); - return self; - } - } - - @Builtin(name = "starmap", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PStarmap, doc = "starmap(function, sequence) --> starmap object\n\n" + - "Return an iterator whose values are returned from the function evaluated\n" + - "with an argument tuple taken from the given sequence.") - @GenerateNodeFactory - public abstract static class StarmapNode extends PythonVarargsBuiltinNode { - @Specialization - static PStarmap construct(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode, - @Cached PyObjectGetIter getIter, - @Cached IsTypeNode isTypeNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!isTypeNode.execute(inliningTarget, cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "starmap()"); - } - if (args.length != 2) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_EXPECTED_D_ARGS, "starmap", 2); - } - Object fun = args[0]; - Object iterable = args[1]; - PStarmap self = factory.createStarmap(cls); - self.setFun(fun); - self.setIterable(getIter.execute(frame, inliningTarget, iterable)); - return self; - } - } - - @Builtin(name = "islice", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PIslice) - @GenerateNodeFactory - public abstract static class IsliceNode extends PythonVarargsBuiltinNode { - @Specialization - static Object constructOne(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode, - @Cached PyObjectGetIter getIter, - @Cached PyNumberAsSizeNode asIntNode, - @Cached InlinedBranchProfile hasStart, - @Cached InlinedBranchProfile hasStop, - @Cached InlinedBranchProfile hasStep, - @Cached InlinedBranchProfile stopNotInt, - @Cached InlinedBranchProfile startNotInt, - @Cached InlinedBranchProfile stopWrongValue, - @Cached InlinedBranchProfile stepWrongValue, - @Cached InlinedBranchProfile wrongValue, - @Cached InlinedBranchProfile overflowBranch, - @Cached InlinedConditionProfile argsLen1, - @Cached InlinedConditionProfile argsLen2, - @Cached InlinedConditionProfile argsLen3, - @Cached InlinedBranchProfile wrongTypeBranch, - @Cached InlinedBranchProfile wrongArgsBranch, - @Cached IsTypeNode isTypeNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!isTypeNode.execute(inliningTarget, cls)) { - wrongTypeBranch.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "islice()"); - } - if (args.length < 2 || args.length > 4) { - wrongArgsBranch.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(TypeError, ISLICE_WRONG_ARGS); - } - int start = 0; - int step = 1; - int stop = -1; - if (argsLen1.profile(inliningTarget, args.length == 2)) { - if (args[1] != PNone.NONE) { - hasStop.enter(inliningTarget); - try { - stop = asIntNode.executeExact(frame, inliningTarget, args[1], OverflowError); - } catch (PException e) { - stopNotInt.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(ValueError, S_FOR_ISLICE_MUST_BE, "Indices"); - } - } - if (stop < -1 || stop > SysModuleBuiltins.MAXSIZE) { - stopWrongValue.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(ValueError, S_FOR_ISLICE_MUST_BE, "Indices"); - } - } else if (argsLen2.profile(inliningTarget, args.length == 3) || argsLen3.profile(inliningTarget, args.length == 4)) { - if (args[1] != PNone.NONE) { - hasStart.enter(inliningTarget); - try { - start = asIntNode.executeExact(frame, inliningTarget, args[1], OverflowError); - } catch (PException e) { - startNotInt.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(ValueError, S_FOR_ISLICE_MUST_BE, "Indices"); - } - } - if (args[2] != PNone.NONE) { - hasStop.enter(inliningTarget); - try { - stop = asIntNode.executeExact(frame, inliningTarget, args[2], OverflowError); - } catch (PException e) { - stopNotInt.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(ValueError, S_FOR_ISLICE_MUST_BE, "Stop argument"); - } - } - if (start < 0 || stop < -1 || start > SysModuleBuiltins.MAXSIZE || stop > SysModuleBuiltins.MAXSIZE) { - wrongValue.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(ValueError, S_FOR_ISLICE_MUST_BE, "Indices"); - } - } - if (argsLen3.profile(inliningTarget, args.length == 4)) { - if (args[3] != PNone.NONE) { - hasStep.enter(inliningTarget); - try { - step = asIntNode.executeExact(frame, inliningTarget, args[3], OverflowError); - } catch (PException e) { - overflowBranch.enter(inliningTarget); - step = -1; - } - } - if (step < 1) { - stepWrongValue.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(ValueError, STEP_FOR_ISLICE_MUST_BE); - } - } - Object iterable = args[0]; - PIslice self = factory.createIslice(cls); - self.setIterable(getIter.execute(frame, inliningTarget, iterable)); - self.setNext(start); - self.setStop(stop); - self.setStep(step); - self.setCnt(0); - return self; - } - } - - @Builtin(name = "zip_longest", minNumOfPositionalArgs = 1, takesVarArgs = true, constructsClass = PythonBuiltinClassType.PZipLongest, keywordOnlyNames = { - "fillvalue"}, doc = "zip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> zip_longest object\n\n" + - "Return a zip_longest object whose .next() method returns a tuple where\n" + - "the i-th element comes from the i-th iterable argument. The .next()\n" + - "method continues until the longest iterable in the argument sequence\n" + - "is exhausted and then it raises StopIteration. When the shorter iterables\n" + - "are exhausted, the fillvalue is substituted in their place. The fillvalue\n" + - "defaults to None or can be specified by a keyword argument.") - @GenerateNodeFactory - public abstract static class ZipLongestNode extends PythonBuiltinNode { - @Specialization - static Object construct(VirtualFrame frame, Object cls, Object[] args, Object fillValueIn, - @Bind("this") Node inliningTarget, - @Cached PyObjectGetIter getIterNode, - @Cached InlinedConditionProfile fillIsNone, - @Cached InlinedLoopConditionProfile loopProfile, - @Cached IsTypeNode isTypeNode, - @Cached InlinedBranchProfile errorProfile, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!isTypeNode.execute(inliningTarget, cls)) { - // Note: @Fallback or other @Specialization generate data-class - errorProfile.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - - Object fillValue = fillValueIn; - if (fillIsNone.profile(inliningTarget, PGuards.isPNone(fillValue))) { - fillValue = null; - } - - PZipLongest self = factory.createZipLongest(cls); - self.setFillValue(fillValue); - self.setNumActive(args.length); - - Object[] itTuple = new Object[args.length]; - loopProfile.profileCounted(inliningTarget, itTuple.length); - LoopNode.reportLoopCount(inliningTarget, itTuple.length); - for (int i = 0; loopProfile.inject(inliningTarget, i < itTuple.length); i++) { - itTuple[i] = getIterNode.execute(frame, inliningTarget, args[i]); - } - self.setItTuple(itTuple); - return self; - } - } - - @Builtin(name = "pairwise", minNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PPairwise, doc = "Return an iterator of overlapping pairs taken from the input iterator.\n\n" + - " s -> (s0,s1), (s1,s2), (s2, s3), ...") - @GenerateNodeFactory - public abstract static class PairwaiseNode extends PythonBinaryBuiltinNode { - @Specialization - static PPairwise construct(VirtualFrame frame, Object cls, Object iterable, - @Bind("this") Node inliningTarget, - @Cached PyObjectGetIter getIter, - @Cached IsTypeNode isTypeNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (!isTypeNode.execute(inliningTarget, cls)) { - // Note: @Fallback or other @Specialization generate data-class - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); - } - - PPairwise self = factory.createPairwise(cls); - self.setIterable(getIter.execute(frame, inliningTarget, iterable)); - return self; - } - } - } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/JArrayModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/JArrayModuleBuiltins.java index 263d6183e9..5f236f1b85 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/JArrayModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/JArrayModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -150,8 +150,8 @@ static Object d(int length, @SuppressWarnings("unused") String typeCode) { @Fallback @SuppressWarnings("unused") static Object error(int length, String typeCode, - @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.INVALID_TYPE_CODE, typeCode); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.INVALID_TYPE_CODE, typeCode); } protected static boolean eq(String a, String b) { @@ -178,7 +178,7 @@ static Object fromTypeCode(int length, Object typeCodeObj, @Specialization(guards = "!isString(classObj)") static Object fromClass(int length, Object classObj, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleLanguage.Env env = PythonContext.get(inliningTarget).getEnv(); if (env.isHostObject(classObj)) { Object clazz = env.asHostObject(classObj); @@ -187,7 +187,7 @@ static Object fromClass(int length, Object classObj, return env.asGuestValue(array); } } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.SECOND_ARG_MUST_BE_STR_OR_JAVA_CLS, classObj); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.SECOND_ARG_MUST_BE_STR_OR_JAVA_CLS, classObj); } @Override @@ -206,7 +206,7 @@ static Object fromSequence(PSequence sequence, Object type, @Shared @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode, @Shared @Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode, @Shared @Cached ZerosNode zerosNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { SequenceStorage storage = getSequenceStorageNode.execute(inliningTarget, sequence); int length = storage.length(); Object array = zerosNode.execute(length, type); @@ -215,7 +215,7 @@ static Object fromSequence(PSequence sequence, Object type, try { lib.writeArrayElement(array, i, value); } catch (UnsupportedTypeException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.TYPE_P_NOT_SUPPORTED_BY_FOREIGN_OBJ, value); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TYPE_P_NOT_SUPPORTED_BY_FOREIGN_OBJ, value); } catch (UnsupportedMessageException | InvalidArrayIndexException e) { throw CompilerDirectives.shouldNotReachHere("failed to set array item"); } @@ -231,7 +231,7 @@ static Object fromIterable(VirtualFrame frame, Object sequence, Object type, @Shared @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode, @Shared @Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode, @Shared @Cached ZerosNode zerosNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { PList list = constructListNode.execute(frame, sequence); return fromSequence(list, type, inliningTarget, lib, getSequenceStorageNode, getItemScalarNode, zerosNode, raiseNode); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/JavaModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/JavaModuleBuiltins.java index 4f9f74f27b..f3a83edf88 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/JavaModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/JavaModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -128,10 +128,10 @@ abstract static class TypeNode extends PythonUnaryBuiltinNode { static Object type(Object name, @Bind("this") Node inliningTarget, @Cached CastToJavaStringNode castToStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Env env = PythonContext.get(inliningTarget).getEnv(); if (!env.isHostLookupAllowed()) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.NotImplementedError, ErrorMessages.HOST_LOOKUP_NOT_ALLOWED); + throw raiseNode.raise(inliningTarget, PythonErrorType.NotImplementedError, ErrorMessages.HOST_LOOKUP_NOT_ALLOWED); } String javaString = castToStringNode.execute(name); Object hostValue; @@ -141,7 +141,7 @@ static Object type(Object name, hostValue = null; } if (hostValue == null) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.KeyError, ErrorMessages.HOST_SYM_NOT_DEFINED, javaString); + throw raiseNode.raise(inliningTarget, PythonErrorType.KeyError, ErrorMessages.HOST_SYM_NOT_DEFINED, javaString); } else { return hostValue; } @@ -149,8 +149,8 @@ static Object type(Object name, @Fallback static Object doError(Object object, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_P, object); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_P, object); } } @@ -161,10 +161,10 @@ abstract static class AddToClassPathNode extends PythonBuiltinNode { static PNone add(Object[] args, @Bind("this") Node inliningTarget, @Cached CastToTruffleStringNode castToString, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Env env = PythonContext.get(inliningTarget).getEnv(); if (!env.isHostLookupAllowed()) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.NotImplementedError, ErrorMessages.HOST_ACCESS_NOT_ALLOWED); + throw raiseNode.raise(inliningTarget, PythonErrorType.NotImplementedError, ErrorMessages.HOST_ACCESS_NOT_ALLOWED); } for (int i = 0; i < args.length; i++) { Object arg = args[i]; @@ -175,9 +175,9 @@ static PNone add(Object[] args, // implicitly env.addToHostClassPath(PythonContext.get(inliningTarget).getPublicTruffleFileRelaxed(entry, T_JAR)); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.CLASSPATH_ARG_MUST_BE_STRING, i + 1, arg); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CLASSPATH_ARG_MUST_BE_STRING, i + 1, arg); } catch (SecurityException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.INVALD_OR_UNREADABLE_CLASSPATH, entry, e); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.INVALD_OR_UNREADABLE_CLASSPATH, entry, e); } } return PNone.NONE; @@ -232,7 +232,7 @@ static boolean check(Object object, Object klass, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared("isForeign1") @Cached IsForeignObjectNode isForeign1, @SuppressWarnings("unused") @Shared("isForeign2") @Cached IsForeignObjectNode isForeign2, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { Env env = PythonContext.get(inliningTarget).getEnv(); try { Object hostKlass = env.asHostObject(klass); @@ -240,7 +240,7 @@ static boolean check(Object object, Object klass, return ((Class) hostKlass).isInstance(object); } } catch (ClassCastException cce) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.KLASS_ARG_IS_NOT_HOST_OBJ, klass); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.KLASS_ARG_IS_NOT_HOST_OBJ, klass); } return false; } @@ -250,7 +250,7 @@ static boolean checkForeign(Object object, Object klass, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared("isForeign1") @Cached IsForeignObjectNode isForeign1, @SuppressWarnings("unused") @Shared("isForeign2") @Cached IsForeignObjectNode isForeign2, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { Env env = PythonContext.get(inliningTarget).getEnv(); try { Object hostObject = env.asHostObject(object); @@ -259,15 +259,15 @@ static boolean checkForeign(Object object, Object klass, return ((Class) hostKlass).isInstance(hostObject); } } catch (ClassCastException cce) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.OBJ_OR_KLASS_ARGS_IS_NOT_HOST_OBJ, object, klass); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.OBJ_OR_KLASS_ARGS_IS_NOT_HOST_OBJ, object, klass); } return false; } @Fallback static boolean fallback(Object object, Object klass, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.UNSUPPORTED_INSTANCEOF, object, klass); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.UNSUPPORTED_INSTANCEOF, object, klass); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/LocaleModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/LocaleModuleBuiltins.java index 4bef0e0f31..24a7747f03 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/LocaleModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/LocaleModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -53,6 +53,7 @@ import java.util.List; import java.util.Locale; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -72,7 +73,7 @@ import com.oracle.graal.python.runtime.exception.PythonErrorType; import com.oracle.graal.python.runtime.locale.LocaleUtils; import com.oracle.graal.python.runtime.locale.PythonLocale; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -117,7 +118,7 @@ public abstract static class LocaleConvNode extends PythonBuiltinNode { @TruffleBoundary static PDict localeconv() { PythonContext ctx = PythonContext.get(null); - PythonObjectFactory factory = ctx.factory(); + PythonLanguage language = ctx.getLanguage(); LinkedHashMap dict = new LinkedHashMap<>(20); final PythonLocale currentPythonLocale = ctx.getCurrentLocale(); @@ -128,7 +129,7 @@ static PDict localeconv() { dict.put("decimal_point", TruffleString.fromCodePointUncached(decimalFormatSymbols.getDecimalSeparator(), TS_ENCODING)); dict.put("thousands_sep", TruffleString.fromCodePointUncached(decimalFormatSymbols.getGroupingSeparator(), TS_ENCODING)); - dict.put("grouping", getDecimalFormatGrouping(factory, numericLocaleNumFormat)); + dict.put("grouping", getDecimalFormatGrouping(language, numericLocaleNumFormat)); // LC_MONETARY Locale monetaryLocale = currentPythonLocale.category(LC_MONETARY); @@ -140,7 +141,7 @@ static PDict localeconv() { dict.put("currency_symbol", toTruffleStringUncached(decimalFormatSymbols.getCurrencySymbol())); dict.put("mon_decimal_point", TruffleString.fromCodePointUncached(decimalFormatSymbols.getMonetaryDecimalSeparator(), TS_ENCODING)); dict.put("mon_thousands_sep", TruffleString.fromCodePointUncached(decimalFormatSymbols.getGroupingSeparator(), TS_ENCODING)); - dict.put("mon_grouping", getDecimalFormatGrouping(factory, monetaryNumFormat)); + dict.put("mon_grouping", getDecimalFormatGrouping(language, monetaryNumFormat)); // TODO: reasonable default, but not the current locale setting dict.put("positive_sign", ""); dict.put("negative_sign", TruffleString.fromCodePointUncached(decimalFormatSymbols.getMinusSign(), TS_ENCODING)); @@ -153,21 +154,21 @@ static PDict localeconv() { dict.put("p_sign_posn", PNone.NONE); dict.put("n_sign_posn", PNone.NONE); - return factory.createDictFromMap(dict); + return PFactory.createDictFromMap(language, dict); } private static DecimalFormatSymbols getDecimalFormatSymbols(Locale locale, NumberFormat numberFormat) { return numberFormat instanceof DecimalFormat decimalFormat ? decimalFormat.getDecimalFormatSymbols() : new DecimalFormatSymbols(locale); } - private static PList getDecimalFormatGrouping(PythonObjectFactory factory, NumberFormat numberFormat) { + private static PList getDecimalFormatGrouping(PythonLanguage language, NumberFormat numberFormat) { if (numberFormat instanceof DecimalFormat decimalFormat) { // TODO: this does not support groupings with variable size groups like in India // Possible approach: decimalFormat.toPattern() gives a generic pattern (e.g., // #,#00.0#) that would have to be parsed to extract the group sizes from it - return factory.createList(new Object[]{decimalFormat.getGroupingSize(), 0}); + return PFactory.createList(language, new Object[]{decimalFormat.getGroupingSize(), 0}); } else { - return factory.createList(); + return PFactory.createList(language); } } } @@ -191,7 +192,7 @@ private static String setCurrent(PythonContext ctx, int category, String posixLo if (newLocale != null) { ctx.setCurrentLocale(current.withCategory(category, newLocale)); } else { - throw PRaiseNode.raiseUncached(nodeForRaise, PythonErrorType.ValueError, ErrorMessages.UNSUPPORTED_LOCALE_SETTING); + throw PRaiseNode.raiseStatic(nodeForRaise, PythonErrorType.ValueError, ErrorMessages.UNSUPPORTED_LOCALE_SETTING); } return LocaleUtils.toPosix(newLocale); } @@ -203,10 +204,10 @@ static TruffleString doGeneric(VirtualFrame frame, Object category, Object posix @Cached CastToTruffleStringNode castToStringNode, @Cached FromJavaStringNode resultAsTruffleStringNode, @Cached ToJavaStringNode toJavaStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { long l = asLongNode.execute(frame, inliningTarget, category); if (!isValidCategory(l)) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.INVALID_LOCALE_CATEGORY); + throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.INVALID_LOCALE_CATEGORY); } TruffleString posixLocaleIDStr = null; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MMapModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MMapModuleBuiltins.java index e576c697c7..b3a25f9bc0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MMapModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MMapModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,50 +40,22 @@ */ package com.oracle.graal.python.builtins.modules; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.OverflowError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; -import static com.oracle.graal.python.runtime.PosixConstants.MAP_ANONYMOUS; -import static com.oracle.graal.python.runtime.PosixConstants.MAP_PRIVATE; -import static com.oracle.graal.python.runtime.PosixConstants.MAP_SHARED; -import static com.oracle.graal.python.runtime.PosixConstants.PROT_READ; -import static com.oracle.graal.python.runtime.PosixConstants.PROT_WRITE; -import static com.oracle.graal.python.runtime.PosixSupportLibrary.ST_SIZE; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; +import java.util.Collections; import java.util.List; -import com.oracle.graal.python.annotations.ArgumentClinic; -import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; -import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.modules.MMapModuleBuiltinsClinicProviders.MMapNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol; import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode; import com.oracle.graal.python.builtins.objects.mmap.PMMap; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PConstructAndRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.runtime.PosixConstants; -import com.oracle.graal.python.runtime.PosixSupport; -import com.oracle.graal.python.runtime.PosixSupportLibrary; -import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @CoreFunctions(defineModule = "mmap") @@ -93,7 +65,7 @@ public final class MMapModuleBuiltins extends PythonBuiltins { @Override protected List> getNodeFactories() { - return MMapModuleBuiltinsFactory.getFactories(); + return Collections.emptyList(); } public MMapModuleBuiltins() { @@ -138,133 +110,4 @@ public void postInitialize(Python3Core core) { CExtNodes.PCallCapiFunction.callUncached(NativeCAPISymbol.FUN_MMAP_INIT_BUFFERPROTOCOL, PythonToNativeNode.executeUncached(PythonBuiltinClassType.PMMap)); }); } - - @Builtin(name = "mmap", minNumOfPositionalArgs = 3, parameterNames = {"cls", "fd", "length", "flags", "prot", "access", "offset"}, constructsClass = PythonBuiltinClassType.PMMap) - @GenerateNodeFactory - // Note: it really should not call fileno on fd as per Python spec - @ArgumentClinic(name = "fd", conversion = ClinicConversion.Int) - @ArgumentClinic(name = "length", conversion = ClinicConversion.LongIndex) - @ArgumentClinic(name = "flags", conversion = ClinicConversion.Int, defaultValue = "FLAGS_DEFAULT") - @ArgumentClinic(name = "prot", conversion = ClinicConversion.Int, defaultValue = "PROT_DEFAULT") - @ArgumentClinic(name = "access", conversion = ClinicConversion.Int, defaultValue = "ACCESS_ARG_DEFAULT") - @ArgumentClinic(name = "offset", conversion = ClinicConversion.Long, defaultValue = "0") - public abstract static class MMapNode extends PythonClinicBuiltinNode { - protected static final int ACCESS_ARG_DEFAULT = PMMap.ACCESS_DEFAULT; - protected static final int FLAGS_DEFAULT = MAP_SHARED.value; - protected static final int PROT_DEFAULT = PROT_WRITE.value | PROT_READ.value; - - private static final int ANONYMOUS_FD = -1; - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return MMapNodeClinicProviderGen.INSTANCE; - } - - // mmap(fileno, length, tagname=None, access=ACCESS_DEFAULT[, offset=0]) - @Specialization(guards = "!isIllegal(fd)") - static PMMap doFile(VirtualFrame frame, Object clazz, int fd, long lengthIn, int flagsIn, int protIn, @SuppressWarnings("unused") int accessIn, long offset, - @Bind("this") Node inliningTarget, - @Cached SysModuleBuiltins.AuditNode auditNode, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixSupport, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (lengthIn < 0) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.MEM_MAPPED_LENGTH_MUST_BE_POSITIVE); - } - if (offset < 0) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.MEM_MAPPED_OFFSET_MUST_BE_POSITIVE); - } - int flags = flagsIn; - int prot = protIn; - int access = accessIn; - switch (access) { - case PMMap.ACCESS_READ: - flags = MAP_SHARED.value; - prot = PROT_READ.value; - break; - case PMMap.ACCESS_WRITE: - flags = MAP_SHARED.value; - prot = PROT_READ.value | PROT_WRITE.value; - break; - case PMMap.ACCESS_COPY: - flags = MAP_PRIVATE.value; - prot = PROT_READ.value | PROT_WRITE.value; - break; - case PMMap.ACCESS_DEFAULT: - // map prot to access type - if (((prot & PROT_READ.value) != 0) && ((prot & PROT_WRITE.value) != 0)) { - // ACCESS_DEFAULT - } else if ((prot & PROT_WRITE.value) != 0) { - access = PMMap.ACCESS_WRITE; - } else { - access = PMMap.ACCESS_READ; - } - break; - default: - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MEM_MAPPED_OFFSET_INVALID_ACCESS); - } - - auditNode.audit(inliningTarget, "mmap.__new__", fd, lengthIn, access, offset); - - // For file mappings we use fstat to validate the length or to initialize the length if - // it is 0 meaning that we should find it out for the user - long length = lengthIn; - PosixSupport posixSupport1 = PosixSupport.get(inliningTarget); - if (fd != ANONYMOUS_FD) { - long[] fstatResult = null; - try { - fstatResult = posixSupport.fstat(posixSupport1, fd); - } catch (PosixException ignored) { - } - if (fstatResult != null && length == 0) { - if (fstatResult[ST_SIZE] == 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.CANNOT_MMAP_AN_EMPTY_FILE); - } - if (offset >= fstatResult[ST_SIZE]) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MMAP_S_IS_GREATER_THAN_FILE_SIZE, "offset"); - } - // Unlike in CPython, this always fits in the long range - length = fstatResult[ST_SIZE] - offset; - } else if (fstatResult != null && (offset > fstatResult[ST_SIZE] || fstatResult[ST_SIZE] - offset < length)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MMAP_S_IS_GREATER_THAN_FILE_SIZE, "length"); - } - } - - // Fixup the flags if we want to use anonymous map - int dupFd; - if (fd == ANONYMOUS_FD) { - dupFd = ANONYMOUS_FD; - flags |= MAP_ANONYMOUS.value; - // TODO: CPython uses mapping to "/dev/zero" on systems that do not support - // MAP_ANONYMOUS, maybe this can be detected and handled by the POSIX layer - } else { - try { - dupFd = posixSupport.dup(posixSupport1, fd); - } catch (PosixException e) { - throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); - } - } - - Object mmapHandle; - try { - mmapHandle = posixSupport.mmap(posixSupport1, length, prot, flags, dupFd, offset); - } catch (PosixException e) { - throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); - } - return factory.createMMap(PythonContext.get(inliningTarget), clazz, mmapHandle, dupFd, length, access); - } - - @Specialization(guards = "isIllegal(fd)") - @SuppressWarnings("unused") - static PMMap doIllegal(Object clazz, int fd, long lengthIn, int flagsIn, int protIn, int accessIn, long offset, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.OSError); - } - - protected static boolean isIllegal(int fd) { - return fd < -1; - } - - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java index 32ddad0ee3..646f9e5f82 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -35,6 +35,11 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; @@ -43,7 +48,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.function.Supplier; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; import com.oracle.graal.python.builtins.Builtin; @@ -73,13 +80,16 @@ import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetInternalObjectArrayNode; import com.oracle.graal.python.builtins.objects.complex.PComplex; import com.oracle.graal.python.builtins.objects.dict.PDict; +import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis; import com.oracle.graal.python.builtins.objects.floats.PFloat; +import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.set.PBaseSet; import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.builtins.objects.str.StringNodes; import com.oracle.graal.python.builtins.objects.str.StringNodes.IsInternedStringNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; +import com.oracle.graal.python.compiler.BytecodeCodeUnit; import com.oracle.graal.python.compiler.CodeUnit; import com.oracle.graal.python.compiler.Compiler; import com.oracle.graal.python.lib.PyComplexCheckExactNode; @@ -95,6 +105,9 @@ import com.oracle.graal.python.lib.PyUnicodeCheckExactNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.bytecode_dsl.BytecodeDSLCodeUnit; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNodeGen; import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; @@ -105,13 +118,19 @@ import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.PythonOptions; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.bytecode.BytecodeConfig; +import com.oracle.truffle.api.bytecode.BytecodeRootNodes; +import com.oracle.truffle.api.bytecode.serialization.BytecodeDeserializer; +import com.oracle.truffle.api.bytecode.serialization.BytecodeSerializer; +import com.oracle.truffle.api.bytecode.serialization.SerializationUtils; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -122,13 +141,14 @@ import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.memory.ByteArraySupport; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.strings.InternalByteArray; import com.oracle.truffle.api.strings.TruffleString; import com.oracle.truffle.api.strings.TruffleString.Encoding; @CoreFunctions(defineModule = "marshal") public final class MarshalModuleBuiltins extends PythonBuiltins { - static final int CURRENT_VERSION = 4; + static final int CURRENT_VERSION = 5; @Override protected List> getNodeFactories() { @@ -150,28 +170,27 @@ protected ArgumentClinicProvider getArgumentClinic() { return DumpNodeClinicProviderGen.INSTANCE; } - @NeverDefault - protected static LookupAndCallBinaryNode createCallWriteNode() { - return LookupAndCallBinaryNode.create(T_WRITE); - } - @Specialization static Object doit(VirtualFrame frame, Object value, Object file, int version, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached("createFor(this)") IndirectCallData indirectCallData, - @Cached("createCallWriteNode()") LookupAndCallBinaryNode callNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - Object savedState = IndirectCallContext.enter(frame, indirectCallData); + @Cached PyObjectCallMethodObjArgs callMethod, + @Cached PRaiseNode raiseNode) { + PythonLanguage language = context.getLanguage(inliningTarget); + PythonContext.PythonThreadState threadState = context.getThreadState(language); + Object savedState = IndirectCallContext.enter(frame, threadState, indirectCallData); + byte[] data; try { - return callNode.executeObject(frame, file, factory.createBytes(Marshal.dump(value, version, PythonContext.get(inliningTarget)))); + data = Marshal.dump(context, value, version); } catch (IOException e) { throw CompilerDirectives.shouldNotReachHere(e); } catch (Marshal.MarshalError me) { - throw raiseNode.get(inliningTarget).raise(me.type, me.message, me.arguments); + throw raiseNode.raise(inliningTarget, me.type, me.message, me.arguments); } finally { - IndirectCallContext.exit(frame, indirectCallData, savedState); + IndirectCallContext.exit(frame, threadState, savedState); } + return callMethod.execute(frame, inliningTarget, file, T_WRITE, PFactory.createBytes(language, data)); } } @@ -187,18 +206,20 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static Object doit(VirtualFrame frame, Object value, int version, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached("createFor(this)") IndirectCallData indirectCallData, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - Object savedState = IndirectCallContext.enter(frame, indirectCallData); + @Cached PRaiseNode raiseNode) { + PythonLanguage language = context.getLanguage(inliningTarget); + PythonContext.PythonThreadState threadState = context.getThreadState(language); + Object savedState = IndirectCallContext.enter(frame, threadState, indirectCallData); try { - return factory.createBytes(Marshal.dump(value, version, PythonContext.get(inliningTarget))); + return PFactory.createBytes(language, Marshal.dump(context, value, version)); } catch (IOException e) { throw CompilerDirectives.shouldNotReachHere(e); } catch (Marshal.MarshalError me) { - throw raiseNode.get(inliningTarget).raise(me.type, me.message, me.arguments); + throw raiseNode.raise(inliningTarget, me.type, me.message, me.arguments); } finally { - IndirectCallContext.exit(frame, indirectCallData, savedState); + IndirectCallContext.exit(frame, threadState, savedState); } } } @@ -214,19 +235,20 @@ protected static LookupAndCallBinaryNode createCallReadNode() { @Specialization static Object doit(VirtualFrame frame, Object file, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached("createCallReadNode()") LookupAndCallBinaryNode callNode, @CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferLib, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object buffer = callNode.executeObject(frame, file, 0); if (!bufferLib.hasBuffer(buffer)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.READ_RETURNED_NOT_BYTES, buffer); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.READ_RETURNED_NOT_BYTES, buffer); } try { - return Marshal.loadFile(file); + return Marshal.loadFile(context, file); } catch (NumberFormatException e) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.BAD_MARSHAL_DATA_S, e.getMessage()); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.BAD_MARSHAL_DATA_S, e.getMessage()); } catch (Marshal.MarshalError me) { - throw raiseNode.get(inliningTarget).raise(me.type, me.message, me.arguments); + throw raiseNode.raise(inliningTarget, me.type, me.message, me.arguments); } } } @@ -239,15 +261,16 @@ abstract static class LoadsNode extends PythonUnaryClinicBuiltinNode { @Specialization static Object doit(VirtualFrame frame, Object buffer, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { - return Marshal.load(bufferLib.getInternalOrCopiedByteArray(buffer), bufferLib.getBufferLength(buffer)); + return Marshal.load(context, bufferLib.getInternalOrCopiedByteArray(buffer), bufferLib.getBufferLength(buffer)); } catch (NumberFormatException e) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.BAD_MARSHAL_DATA_S, e.getMessage()); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.BAD_MARSHAL_DATA_S, e.getMessage()); } catch (Marshal.MarshalError me) { - throw raiseNode.get(inliningTarget).raise(me.type, me.message, me.arguments); + throw raiseNode.raise(inliningTarget, me.type, me.message, me.arguments); } finally { bufferLib.release(buffer, frame, indirectCallData); } @@ -298,6 +321,10 @@ static final class Marshal { private static final char TYPE_GRAALPYTHON_CODE_UNIT = 'U'; private static final char TYPE_BIG_INTEGER = 'B'; private static final char TYPE_ARRAY = ']'; + // These are constants that show up in the Bytecode DSL interpreter. + private static final char TYPE_GRAALPYTHON_DSL_CODE_UNIT = 'D'; + private static final char TYPE_DSL_SOURCE = '$'; + private static final char TYPE_DSL_EMPTY_KEYWORDS = 'k'; private static final char ARRAY_TYPE_OBJECT = 'o'; private static final char ARRAY_TYPE_INT = 'i'; @@ -346,15 +373,15 @@ public final Throwable fillInStackTrace() { } @TruffleBoundary - static byte[] dump(Object value, int version, Python3Core core) throws IOException, MarshalError { - Marshal outMarshal = new Marshal(version, core.getTrue(), core.getFalse()); + static byte[] dump(PythonContext context, Object value, int version) throws IOException, MarshalError { + Marshal outMarshal = new Marshal(context, version, context.getTrue(), context.getFalse()); outMarshal.writeObject(value); - return outMarshal.out.toByteArray(); + return outMarshal.outData.toByteArray(); } @TruffleBoundary - static Object load(byte[] ary, int length) throws NumberFormatException, MarshalError { - Marshal inMarshal = new Marshal(ary, length); + static Object load(PythonContext context, byte[] ary, int length) throws NumberFormatException, MarshalError { + Marshal inMarshal = new Marshal(context, ary, length); Object result = inMarshal.readObject(); if (result == null) { throw new MarshalError(PythonBuiltinClassType.TypeError, ErrorMessages.BAD_MARSHAL_DATA_NULL); @@ -363,8 +390,8 @@ static Object load(byte[] ary, int length) throws NumberFormatException, Marshal } @TruffleBoundary - static Object loadFile(Object file) throws NumberFormatException, MarshalError { - Marshal inMarshal = new Marshal(file); + static Object loadFile(PythonContext context, Object file) throws NumberFormatException, MarshalError { + Marshal inMarshal = new Marshal(context, file); Object result = inMarshal.readObject(); if (result == null) { throw new MarshalError(PythonBuiltinClassType.TypeError, ErrorMessages.BAD_MARSHAL_DATA_NULL); @@ -387,7 +414,7 @@ static final class FileLikeInputStream extends InputStream { this.fileLike = fileLike; this.asSize = PyNumberAsSizeNode.getUncached(); this.singleByteStore = new ByteSequenceStorage(new byte[1]); - this.buffer = PythonObjectFactory.getUncached().createByteArray(singleByteStore); + this.buffer = PFactory.createByteArray(PythonLanguage.get(null), singleByteStore); } @Override @@ -418,11 +445,12 @@ public int read(byte[] b, int off, int len) { } } - private static final PythonObjectFactory factory = PythonObjectFactory.getUncached(); + private final PythonContext context; final HashMap refMap; final ArrayList refList; - final ByteArrayOutputStream out; - final InputStream in; + final ByteArrayOutputStream outData; + final DataOutput out; + final DataInput in; final int version; final PInt pyTrue; final PInt pyFalse; @@ -430,50 +458,88 @@ public int read(byte[] b, int off, int len) { final ByteArraySupport baSupport = ByteArraySupport.littleEndian(); byte[] buffer = new byte[Long.BYTES]; int depth = 0; + /* + * A DSL node needs access to its Source during deserialization, but we do not wish to + * actually encode it in the serialized representation. Instead, we supply a Source to the + * Marshal object and return it when the source is needed. + */ + Source source = null; - Marshal(int version, PInt pyTrue, PInt pyFalse) { + Marshal(PythonContext context, int version, PInt pyTrue, PInt pyFalse) { + this.context = context; this.version = version; this.pyTrue = pyTrue; this.pyFalse = pyFalse; - this.out = new ByteArrayOutputStream(); + this.outData = new ByteArrayOutputStream(); + this.out = new DataOutputStream(outData); this.refMap = new HashMap<>(); this.in = null; this.refList = null; } - Marshal(byte[] in, int length) { - this.in = new ByteArrayInputStream(in, 0, length); - this.refList = new ArrayList<>(); - this.version = -1; - this.pyTrue = null; - this.pyFalse = null; - this.out = null; - this.refMap = null; + Marshal(PythonContext context, int version, PInt pyTrue, PInt pyFalse, DataOutput out) { + this.context = context; + this.version = version; + this.pyTrue = pyTrue; + this.pyFalse = pyFalse; + this.outData = null; + this.out = out; + this.refMap = new HashMap<>(); + this.in = null; + this.refList = null; } - Marshal(Object in) { - this.in = new FileLikeInputStream(in); + Marshal(PythonContext context, byte[] in, int length) { + this(context, new DataInputStream(new ByteArrayInputStream(in, 0, length)), null); + } + + Marshal(PythonContext context, Object in) { + this(context, new DataInputStream(new FileLikeInputStream(in)), null); + } + + Marshal(PythonContext context, DataInput in, Source source) { + this.context = context; + this.in = in; + this.source = source; this.refList = new ArrayList<>(); this.version = -1; this.pyTrue = null; this.pyFalse = null; + this.outData = null; this.out = null; this.refMap = null; } + private PythonLanguage getLanguage() { + return context.getLanguage(); + } + private void writeByte(int v) { - out.write(v); + try { + out.write(v); + } catch (IOException e) { + // The underlying output streams we use should not throw IOExceptions. + throw CompilerDirectives.shouldNotReachHere(); + } } - private int readByte() { - int nextByte; + private void writeBytes(byte[] b, int off, int len) { try { - nextByte = in.read(); + out.write(b, off, len); } catch (IOException e) { + // The underlying output streams we use should not throw IOExceptions. throw CompilerDirectives.shouldNotReachHere(); } - if (nextByte < 0) { + } + + private int readByte() { + int nextByte; + try { + nextByte = in.readUnsignedByte(); + } catch (EOFException e) { throw new MarshalError(PythonBuiltinClassType.EOFError, ErrorMessages.BAD_MARSHAL_DATA_EOF); + } catch (IOException e) { + throw CompilerDirectives.shouldNotReachHere(); } return nextByte; } @@ -517,15 +583,13 @@ private byte[] readNBytes(int sz, byte[] output) { if (sz == 0) { return output; } - int read; try { - read = in.read(output, 0, sz); + in.readFully(output, 0, sz); + } catch (EOFException e) { + throw new MarshalError(PythonBuiltinClassType.EOFError, ErrorMessages.BAD_MARSHAL_DATA_EOF); } catch (IOException e) { throw CompilerDirectives.shouldNotReachHere(); } - if (read < sz) { - throw new MarshalError(PythonBuiltinClassType.EOFError, ErrorMessages.BAD_MARSHAL_DATA_EOF); - } return output; } @@ -536,13 +600,13 @@ private byte[] readBytes() { private void writeInt(int v) { for (int i = 0; i < Integer.SIZE; i += Byte.SIZE) { - out.write((v >> i) & 0xff); + writeByte((v >> i) & 0xff); } } private void writeShort(short v) { for (int i = 0; i < Short.SIZE; i += Byte.SIZE) { - out.write((v >> i) & 0xff); + writeByte((v >> i) & 0xff); } } @@ -556,7 +620,7 @@ private short readShort() { private void writeLong(long v) { for (int i = 0; i < Long.SIZE; i += Byte.SIZE) { - out.write((int) ((v >>> i) & 0xff)); + writeByte((int) ((v >>> i) & 0xff)); } } @@ -582,7 +646,7 @@ private void writeBigInteger(BigInteger v) { } for (int digit : digits) { for (int i = 0; i < Short.SIZE; i += Byte.SIZE) { - out.write((digit >> i) & 0xff); + writeByte((digit >> i) & 0xff); } } } @@ -677,7 +741,7 @@ private void writeObject(Object v) throws IOException { writeByte(TYPE_NOVALUE); } else if (IsSameTypeNode.executeUncached(v, PythonBuiltinClassType.StopIteration)) { writeByte(TYPE_STOPITER); - } else if (IsSameTypeNode.executeUncached(v, PythonBuiltinClassType.PEllipsis)) { + } else if (v == PEllipsis.INSTANCE) { writeByte(TYPE_ELLIPSIS); } else if (v == Boolean.TRUE || v == pyTrue) { writeByte(TYPE_TRUE); @@ -826,6 +890,9 @@ private void writeComplexObject(Object v, int flag) { writeByte(TYPE_ARRAY | flag); writeByte(ARRAY_TYPE_STRING); writeStringArray((TruffleString[]) v); + } else if (v instanceof PKeyword[]) { + assert v == PKeyword.EMPTY_KEYWORDS; + writeByte(TYPE_DSL_EMPTY_KEYWORDS); } else if (v instanceof Object[]) { writeByte(TYPE_ARRAY | flag); writeByte(ARRAY_TYPE_OBJECT); @@ -845,8 +912,16 @@ private void writeComplexObject(Object v, int flag) { } writeBytes(lnotab); } else if (v instanceof CodeUnit) { - writeByte(TYPE_GRAALPYTHON_CODE_UNIT | flag); - writeCodeUnit((CodeUnit) v); + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + writeByte(TYPE_GRAALPYTHON_DSL_CODE_UNIT | flag); + writeBytecodeDSLCodeUnit((BytecodeDSLCodeUnit) v); + } else { + writeByte(TYPE_GRAALPYTHON_CODE_UNIT | flag); + writeBytecodeCodeUnit((BytecodeCodeUnit) v); + } + } else if (v instanceof Source s) { + writeByte(TYPE_DSL_SOURCE | flag); + setSource(s); } else { PythonBufferAcquireLibrary acquireLib = PythonBufferAcquireLibrary.getFactory().getUncached(v); if (acquireLib.hasBuffer(v)) { @@ -967,7 +1042,7 @@ private Object readObject(int type, AddRefAndReturn addRef) throws NumberFormatE case TYPE_STOPITER: return PythonBuiltinClassType.StopIteration; case TYPE_ELLIPSIS: - return PythonBuiltinClassType.PEllipsis; + return PEllipsis.INSTANCE; case TYPE_FALSE: return false; case TYPE_TRUE: @@ -979,17 +1054,17 @@ private Object readObject(int type, AddRefAndReturn addRef) throws NumberFormatE case TYPE_BIG_INTEGER: return readBigInteger(); case TYPE_LONG: - return addRef.run(factory.createInt(readBigInteger())); + return addRef.run(PFactory.createInt(getLanguage(), readBigInteger())); case TYPE_FLOAT: return addRef.run(readDoubleString()); case TYPE_BINARY_FLOAT: return addRef.run(readDouble()); case TYPE_COMPLEX: - return addRef.run(factory.createComplex(readDoubleString(), readDoubleString())); + return addRef.run(PFactory.createComplex(getLanguage(), readDoubleString(), readDoubleString())); case TYPE_BINARY_COMPLEX: - return addRef.run(factory.createComplex(readDouble(), readDouble())); + return addRef.run(PFactory.createComplex(getLanguage(), readDouble(), readDouble())); case TYPE_STRING: - return addRef.run(factory.createBytes(readBytes())); + return addRef.run(PFactory.createBytes(getLanguage(), readBytes())); case TYPE_ASCII_INTERNED: return addRef.run(readAscii(readSize(), true)); case TYPE_ASCII: @@ -1005,24 +1080,24 @@ private Object readObject(int type, AddRefAndReturn addRef) throws NumberFormatE case TYPE_SMALL_TUPLE: int smallTupleSize = readByteSize(); Object[] smallTupleItems = new Object[smallTupleSize]; - Object smallTuple = addRef.run(factory.createTuple(smallTupleItems)); + Object smallTuple = addRef.run(PFactory.createTuple(getLanguage(), smallTupleItems)); readArray(smallTupleItems); return smallTuple; case TYPE_TUPLE: int tupleSize = readSize(); Object[] tupleItems = new Object[tupleSize]; - Object tuple = addRef.run(factory.createTuple(tupleItems)); + Object tuple = addRef.run(PFactory.createTuple(getLanguage(), tupleItems)); readArray(tupleItems); return tuple; case TYPE_LIST: int listSize = readSize(); Object[] listItems = new Object[listSize]; - Object list = addRef.run(factory.createList(listItems)); + Object list = addRef.run(PFactory.createList(getLanguage(), listItems)); readArray(listItems); return list; case TYPE_DICT: HashingStorage store = PDict.createNewStorage(0); - PDict dict = factory.createDict(store); + PDict dict = PFactory.createDict(getLanguage(), store); addRef.run(dict); while (true) { Object key = readObject(); @@ -1042,9 +1117,9 @@ private Object readObject(int type, AddRefAndReturn addRef) throws NumberFormatE HashingStorage setStore = EconomicMapStorage.create(setSz); PBaseSet set; if (type == TYPE_FROZENSET) { - set = factory.createFrozenSet(setStore); + set = PFactory.createFrozenSet(getLanguage(), setStore); } else { - set = factory.createSet(setStore); + set = PFactory.createSet(getLanguage(), setStore); } addRef.run(set); for (int i = 0; i < setSz; i++) { @@ -1059,10 +1134,15 @@ private Object readObject(int type, AddRefAndReturn addRef) throws NumberFormatE case TYPE_GRAALPYTHON_CODE: return addRef.run(readCode()); case TYPE_GRAALPYTHON_CODE_UNIT: - return addRef.run(readCodeUnit()); - case TYPE_ARRAY: { + return addRef.run(readBytecodeCodeUnit()); + case TYPE_GRAALPYTHON_DSL_CODE_UNIT: + return addRef.run(readBytecodeDSLCodeUnit()); + case TYPE_DSL_SOURCE: + return getSource(); + case TYPE_DSL_EMPTY_KEYWORDS: + return PKeyword.EMPTY_KEYWORDS; + case TYPE_ARRAY: return addRef.run(readJavaArray()); - } default: throw new MarshalError(ValueError, ErrorMessages.BAD_MARSHAL_DATA); } @@ -1082,7 +1162,7 @@ private void writeString(TruffleString v) { } InternalByteArray ba = v.switchEncodingUncached(encoding).getInternalByteArrayUncached(encoding); writeSize(ba.getLength()); - out.write(ba.getArray(), ba.getOffset(), ba.getLength()); + writeBytes(ba.getArray(), ba.getOffset(), ba.getLength()); } private TruffleString readString() { @@ -1215,6 +1295,24 @@ private Object[] readObjectArray() { return a; } + private void setSource(Source s) { + if (source == null) { + source = s; + } else if (source != s) { + throw CompilerDirectives.shouldNotReachHere("attempted to serialize with multiple Source objects"); + } + } + + private Source getSource() { + if (source != null) { + return source; + } else { + // This should never happen when deserializing a bytecode DSL code unit, but could + // happen if the user tries to deserialize arbitrary bytes. + throw new MarshalError(ValueError, ErrorMessages.BAD_MARSHAL_DATA); + } + } + private void writeSparseTable(int[][] table) { writeInt(table.length); for (int i = 0; i < table.length; i++) { @@ -1239,6 +1337,21 @@ private int[][] readSparseTable() { } private CodeUnit readCodeUnit() { + int codeUnitType = readByte(); + return switch (codeUnitType) { + case TYPE_GRAALPYTHON_CODE_UNIT -> readBytecodeCodeUnit(); + case TYPE_GRAALPYTHON_DSL_CODE_UNIT -> readBytecodeDSLCodeUnit(); + default -> throw CompilerDirectives.shouldNotReachHere(); + }; + } + + private BytecodeCodeUnit readBytecodeCodeUnit() { + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + throw new MarshalError(ValueError, + PythonUtils.tsLiteral( + "Attempted to deserialize a code object from the manual bytecode interpreter, but the DSL interpreter is enabled. Consider clearing or setting a different pycache folder.")); + } + int fileVersion = readByte(); if (fileVersion != Compiler.BYTECODE_VERSION) { throw new MarshalError(ValueError, ErrorMessages.BYTECODE_VERSION_MISMATCH, Compiler.BYTECODE_VERSION, fileVersion); @@ -1272,13 +1385,57 @@ private CodeUnit readCodeUnit() { byte[] variableShouldUnbox = readBytes(); int[][] generalizeInputsMap = readSparseTable(); int[][] generalizeVarsMap = readSparseTable(); - return new CodeUnit(name, qualname, argCount, kwOnlyArgCount, positionalOnlyArgCount, stacksize, code, srcOffsetTable, - flags, names, varnames, cellvars, freevars, cell2arg, constants, primitiveConstants, exceptionHandlerRanges, conditionProfileCount, - startLine, startColumn, endLine, endColumn, + return new BytecodeCodeUnit(name, qualname, argCount, kwOnlyArgCount, positionalOnlyArgCount, flags, names, varnames, + cellvars, freevars, cell2arg, constants, startLine, startColumn, endLine, endColumn, code, srcOffsetTable, + primitiveConstants, exceptionHandlerRanges, stacksize, conditionProfileCount, outputCanQuicken, variableShouldUnbox, generalizeInputsMap, generalizeVarsMap); } + private BytecodeDSLCodeUnit readBytecodeDSLCodeUnit() { + if (!PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + throw new MarshalError(ValueError, + PythonUtils.tsLiteral( + "Attempted to deserialize a code object from the Bytecode DSL interpreter, but the manual interpreter is enabled. Consider clearing or setting a different pycache folder.")); + } + + byte[] serialized = readBytes(); + TruffleString name = readString(); + TruffleString qualname = readString(); + int argCount = readInt(); + int kwOnlyArgCount = readInt(); + int positionalOnlyArgCount = readInt(); + int flags = readInt(); + TruffleString[] names = readStringArray(); + TruffleString[] varnames = readStringArray(); + TruffleString[] cellvars = readStringArray(); + TruffleString[] freevars = readStringArray(); + int[] cell2arg = readIntArray(); + if (cell2arg.length == 0) { + cell2arg = null; + } + Object[] constants = readObjectArray(); + int startLine = readInt(); + int startColumn = readInt(); + int endLine = readInt(); + int endColumn = readInt(); + int classcellIndex = readInt(); + int selfIndex = readInt(); + + return new BytecodeDSLCodeUnit(name, qualname, argCount, kwOnlyArgCount, positionalOnlyArgCount, flags, names, varnames, cellvars, freevars, cell2arg, constants, + startLine, startColumn, endLine, endColumn, classcellIndex, selfIndex, serialized, null); + } + private void writeCodeUnit(CodeUnit code) throws IOException { + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + writeByte(TYPE_GRAALPYTHON_DSL_CODE_UNIT); + writeBytecodeDSLCodeUnit((BytecodeDSLCodeUnit) code); + } else { + writeByte(TYPE_GRAALPYTHON_CODE_UNIT); + writeBytecodeCodeUnit((BytecodeCodeUnit) code); + } + } + + private void writeBytecodeCodeUnit(BytecodeCodeUnit code) throws IOException { writeByte(Compiler.BYTECODE_VERSION); writeString(code.name); writeString(code.qualname); @@ -1286,7 +1443,7 @@ private void writeCodeUnit(CodeUnit code) throws IOException { writeInt(code.kwOnlyArgCount); writeInt(code.positionalOnlyArgCount); writeInt(code.stacksize); - writeBytes(code.code); + writeBytes(code.getBytecodeForSerialization()); writeBytes(code.srcOffsetTable); writeInt(code.flags); writeStringArray(code.names); @@ -1312,6 +1469,34 @@ private void writeCodeUnit(CodeUnit code) throws IOException { writeSparseTable(code.generalizeVarsMap); } + @SuppressWarnings("unchecked") + private void writeBytecodeDSLCodeUnit(BytecodeDSLCodeUnit code) throws IOException { + byte[] serialized = code.getSerialized(context); + writeBytes(serialized); + writeString(code.name); + writeString(code.qualname); + writeInt(code.argCount); + writeInt(code.kwOnlyArgCount); + writeInt(code.positionalOnlyArgCount); + writeInt(code.flags); + writeStringArray(code.names); + writeStringArray(code.varnames); + writeStringArray(code.cellvars); + writeStringArray(code.freevars); + if (code.cell2arg != null) { + writeIntArray(code.cell2arg); + } else { + writeIntArray(PythonUtils.EMPTY_INT_ARRAY); + } + writeObjectArray(code.constants); + writeInt(code.startLine); + writeInt(code.startColumn); + writeInt(code.endLine); + writeInt(code.endColumn); + writeInt(code.classcellIndex); + writeInt(code.selfIndex); + } + private PCode readCode() { TruffleString fileName = readString(); int flags = readInt(); @@ -1319,14 +1504,13 @@ private PCode readCode() { int codeLen = readSize(); byte[] codeString = new byte[codeLen + Long.BYTES]; try { - in.read(codeString, 0, codeLen); + in.readFully(codeString, 0, codeLen); } catch (IOException e) { throw CompilerDirectives.shouldNotReachHere(); } // get a new ID every time we deserialize the same filename in the same context. We use // slow-path context lookup, since this code is likely dominated by the deserialization // time - PythonContext context = PythonContext.get(null); ByteBuffer.wrap(codeString).putLong(codeLen, context.getDeserializationId(fileName)); int firstLineNo = readInt(); byte[] lnoTab = readBytes(); @@ -1335,27 +1519,71 @@ private PCode readCode() { } @TruffleBoundary - public static byte[] serializeCodeUnit(CodeUnit code) { + public static byte[] serializeCodeUnit(Node node, PythonContext context, CodeUnit code) { try { - Marshal marshal = new Marshal(CURRENT_VERSION, null, null); + Marshal marshal = new Marshal(context, CURRENT_VERSION, null, null); marshal.writeCodeUnit(code); - return marshal.out.toByteArray(); + return marshal.outData.toByteArray(); } catch (IOException e) { throw CompilerDirectives.shouldNotReachHere(e); } catch (Marshal.MarshalError me) { - throw PRaiseNode.getUncached().raise(me.type, me.message, me.arguments); + throw PRaiseNode.raiseStatic(node, me.type, me.message, me.arguments); } } @TruffleBoundary - public static CodeUnit deserializeCodeUnit(byte[] bytes) { + public static CodeUnit deserializeCodeUnit(Node node, PythonContext context, byte[] bytes) { try { - Marshal marshal = new Marshal(bytes, bytes.length); + Marshal marshal = new Marshal(context, bytes, bytes.length); return marshal.readCodeUnit(); } catch (Marshal.MarshalError me) { - throw PRaiseNode.getUncached().raise(me.type, me.message, me.arguments); + throw PRaiseNode.raiseStatic(node, me.type, me.message, me.arguments); } catch (NumberFormatException e) { - throw PRaiseNode.getUncached().raise(ValueError, ErrorMessages.BAD_MARSHAL_DATA_S, e.getMessage()); + throw PRaiseNode.raiseStatic(node, ValueError, ErrorMessages.BAD_MARSHAL_DATA_S, e.getMessage()); + } + } + + public static BytecodeRootNodes deserializeBytecodeNodes(PythonContext context, Source source, byte[] serialized) { + try { + Supplier supplier = () -> SerializationUtils.createDataInput(ByteBuffer.wrap(serialized)); + return PBytecodeDSLRootNodeGen.deserialize(context.getLanguage(), BytecodeConfig.WITH_SOURCE, supplier, new MarshalModuleBuiltins.PBytecodeDSLDeserializer(context, source)); + } catch (IOException e) { + throw CompilerDirectives.shouldNotReachHere("Deserialization error."); + } + } + + public static class PBytecodeDSLSerializer implements BytecodeSerializer { + private final PythonContext pythonContext; + + public PBytecodeDSLSerializer(PythonContext context) { + this.pythonContext = context; + } + + public void serialize(SerializerContext context, DataOutput buffer, Object object) throws IOException { + /* + * NB: Since the deserializer uses a fresh Marshal instance for each object (see below) + * we must also do the same here. Otherwise, the encoding may be different (e.g., a + * reference for an already-emitted object). + */ + new Marshal(pythonContext, CURRENT_VERSION, pythonContext.getTrue(), pythonContext.getFalse(), buffer).writeObject(object); + } + } + + public static class PBytecodeDSLDeserializer implements BytecodeDeserializer { + private final PythonContext pythonContext; + final Source source; + + public PBytecodeDSLDeserializer(PythonContext context, Source source) { + this.pythonContext = context; + this.source = source; + } + + public Object deserialize(DeserializerContext context, DataInput buffer) throws IOException { + /* + * NB: Since a DSL node may reparse multiple times, we cannot reuse a common Marshal + * object across calls (each call may take a different buffer). + */ + return new Marshal(pythonContext, buffer, source).readObject(); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MathModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MathModuleBuiltins.java index 9266b8f0cd..1796bd1994 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MathModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MathModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2014, Regents of the University of California * * All rights reserved. @@ -37,6 +37,7 @@ import java.util.Arrays; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -49,12 +50,14 @@ import com.oracle.graal.python.builtins.objects.ints.IntBuiltins; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyFloatAsDoubleNode; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyLongAsLongAndOverflowNode; import com.oracle.graal.python.lib.PyLongFromDoubleNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyNumberIndexNode; +import com.oracle.graal.python.lib.PyNumberMultiplyNode; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; @@ -64,9 +67,6 @@ import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodNode; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; -import com.oracle.graal.python.nodes.expression.BinaryArithmetic; -import com.oracle.graal.python.nodes.expression.BinaryComparisonNode; -import com.oracle.graal.python.nodes.expression.BinaryOpNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; @@ -76,13 +76,12 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; +import com.oracle.graal.python.nodes.truffle.PythonIntegerAndFloatTypes; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; import com.oracle.graal.python.nodes.util.CastToJavaLongLossyNode; import com.oracle.graal.python.nodes.util.NarrowBigIntegerNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.OverflowException; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; @@ -124,63 +123,63 @@ public MathModuleBuiltins() { addBuiltinConstant("nan", Double.NaN); } - static void checkMathRangeError(boolean con, Node inliningTarget, PRaiseNode.Lazy raiseNode) { + static void checkMathRangeError(boolean con, Node inliningTarget, PRaiseNode raiseNode) { if (con) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.MATH_RANGE_ERROR); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.MATH_RANGE_ERROR); } } - static void checkMathDomainError(boolean con, Node inliningTarget, PRaiseNode.Lazy raiseNode) { + static void checkMathDomainError(boolean con, Node inliningTarget, PRaiseNode raiseNode) { if (con) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MATH_DOMAIN_ERROR); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); } } static void checkMathDomainErrorUncached(boolean con, Node raisingNode) { if (con) { - throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); } } @GenerateInline @GenerateCached(false) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(MathGuards.class) public abstract static class MathUnaryHelperNode extends Node { @FunctionalInterface interface Op { - double compute(Node inliningTarget, double arg, PRaiseNode.Lazy raiseNode); + double compute(Node inliningTarget, double arg, PRaiseNode raiseNode); } abstract double execute(VirtualFrame frame, Node inliningTarget, Object value, Op op); @Specialization static double doL(Node inliningTarget, long value, Op op, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { return computeAndCheckDomain(inliningTarget, value, op, raiseNode); } @Specialization static double doD(Node inliningTarget, double value, Op op, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { return computeAndCheckDomain(inliningTarget, value, op, raiseNode); } @Specialization static double doPI(Node inliningTarget, PInt value, Op op, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { return computeAndCheckDomain(inliningTarget, value.doubleValueWithOverflow(inliningTarget), op, raiseNode); } @Specialization(guards = "!isNumber(value)") static double doGeneral(VirtualFrame frame, Node inliningTarget, Object value, Op op, @Cached PyFloatAsDoubleNode asDoubleNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { return computeAndCheckDomain(inliningTarget, asDoubleNode.execute(frame, inliningTarget, value), op, raiseNode); } - private static double computeAndCheckDomain(Node inliningTarget, double arg, Op op, PRaiseNode.Lazy raiseNode) { + private static double computeAndCheckDomain(Node inliningTarget, double arg, Op op, PRaiseNode raiseNode) { double res = op.compute(inliningTarget, arg, raiseNode); checkMathDomainError(Double.isNaN(res) && !Double.isNaN(arg), inliningTarget, raiseNode); return res; @@ -237,7 +236,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, SqrtNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { checkMathDomainError(value < 0, inliningTarget, raiseNode); return Math.sqrt(value); } @@ -254,7 +253,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, ExpNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { double result = Math.exp(value); checkMathRangeError(Double.isFinite(value) && Double.isInfinite(result), inliningTarget, raiseNode); return result; @@ -272,7 +271,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, Expm1Node::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { double result = Math.expm1(value); checkMathRangeError(Double.isFinite(value) && Double.isInfinite(result), inliningTarget, raiseNode); return result; @@ -351,8 +350,8 @@ private static BigInteger factorialPart(long start, long n) { @Specialization(guards = {"value < 0"}) static long factorialNegativeInt(@SuppressWarnings("unused") int value, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.FACTORIAL_NOT_DEFINED_FOR_NEGATIVE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.FACTORIAL_NOT_DEFINED_FOR_NEGATIVE); } @Specialization(guards = {"0 <= value", "value < SMALL_FACTORIALS.length"}) @@ -362,14 +361,14 @@ static long factorialSmallInt(int value) { @Specialization(guards = {"value >= SMALL_FACTORIALS.length"}) static PInt factorialInt(int value, - @Shared @Cached PythonObjectFactory factory) { - return factory.createInt(factorialPart(1, value)); + @Bind PythonLanguage language) { + return PFactory.createInt(language, factorialPart(1, value)); } @Specialization(guards = {"value < 0"}) static long factorialNegativeLong(@SuppressWarnings("unused") long value, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.FACTORIAL_NOT_DEFINED_FOR_NEGATIVE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.FACTORIAL_NOT_DEFINED_FOR_NEGATIVE); } @Specialization(guards = {"0 <= value", "value < SMALL_FACTORIALS.length"}) @@ -379,8 +378,8 @@ static long factorialSmallLong(long value) { @Specialization(guards = {"value >= SMALL_FACTORIALS.length"}) static PInt factorialLong(long value, - @Shared @Cached PythonObjectFactory factory) { - return factory.createInt(factorialPart(1, value)); + @Bind PythonLanguage language) { + return PFactory.createInt(language, factorialPart(1, value)); } @Fallback @@ -389,14 +388,14 @@ static Object factorialObject(VirtualFrame frame, Object value, @Cached PyLongAsLongAndOverflowNode convert, @Cached PyNumberAsSizeNode asSizeNode, @Cached FactorialNode recursiveNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { return recursiveNode.execute(frame, convert.execute(frame, inliningTarget, value)); } catch (OverflowException e) { if (asSizeNode.executeLossy(frame, inliningTarget, value) >= 0) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.FACTORIAL_ARGUMENT_SHOULD_NOT_EXCEED_D, Long.MAX_VALUE); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.FACTORIAL_ARGUMENT_SHOULD_NOT_EXCEED_D, Long.MAX_VALUE); } else { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.FACTORIAL_NOT_DEFINED_FOR_NEGATIVE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.FACTORIAL_NOT_DEFINED_FOR_NEGATIVE); } } } @@ -404,7 +403,7 @@ static Object factorialObject(VirtualFrame frame, Object value, } @Builtin(name = "comb", minNumOfPositionalArgs = 2) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @GenerateNodeFactory @ImportStatic(MathGuards.class) public abstract static class CombNode extends PythonBinaryBuiltinNode { @@ -412,10 +411,10 @@ public abstract static class CombNode extends PythonBinaryBuiltinNode { @TruffleBoundary private BigInteger calculateComb(BigInteger n, BigInteger k) { if (n.signum() < 0) { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.MUST_BE_NON_NEGATIVE_INTEGER, "n"); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.MUST_BE_NON_NEGATIVE_INTEGER, "n"); } if (k.signum() < 0) { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.MUST_BE_NON_NEGATIVE_INTEGER, "k"); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.MUST_BE_NON_NEGATIVE_INTEGER, "k"); } BigInteger factors = k.min(n.subtract(k)); @@ -439,26 +438,26 @@ private BigInteger calculateComb(BigInteger n, BigInteger k) { @Specialization PInt comb(long n, long k, - @Shared @Cached PythonObjectFactory factory) { - return factory.createInt(calculateComb(PInt.longToBigInteger(n), PInt.longToBigInteger(k))); + @Bind PythonLanguage language) { + return PFactory.createInt(language, calculateComb(PInt.longToBigInteger(n), PInt.longToBigInteger(k))); } @Specialization PInt comb(long n, PInt k, - @Shared @Cached PythonObjectFactory factory) { - return factory.createInt(calculateComb(PInt.longToBigInteger(n), k.getValue())); + @Bind PythonLanguage language) { + return PFactory.createInt(language, calculateComb(PInt.longToBigInteger(n), k.getValue())); } @Specialization PInt comb(PInt n, long k, - @Shared @Cached PythonObjectFactory factory) { - return factory.createInt(calculateComb(n.getValue(), PInt.longToBigInteger(k))); + @Bind PythonLanguage language) { + return PFactory.createInt(language, calculateComb(n.getValue(), PInt.longToBigInteger(k))); } @Specialization PInt comb(PInt n, PInt k, - @Shared @Cached PythonObjectFactory factory) { - return factory.createInt(calculateComb(n.getValue(), k.getValue())); + @Bind PythonLanguage language) { + return PFactory.createInt(language, calculateComb(n.getValue(), k.getValue())); } @Specialization @@ -474,7 +473,7 @@ static Object comb(VirtualFrame frame, Object n, Object k, } @Builtin(name = "perm", minNumOfPositionalArgs = 1, parameterNames = {"n", "k"}) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @GenerateNodeFactory @ImportStatic(MathGuards.class) public abstract static class PermNode extends PythonBinaryBuiltinNode { @@ -482,10 +481,10 @@ public abstract static class PermNode extends PythonBinaryBuiltinNode { @TruffleBoundary private BigInteger calculatePerm(BigInteger n, BigInteger k) { if (n.signum() < 0) { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.MUST_BE_NON_NEGATIVE_INTEGER, "n"); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.MUST_BE_NON_NEGATIVE_INTEGER, "n"); } if (k.signum() < 0) { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.MUST_BE_NON_NEGATIVE_INTEGER, "k"); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.MUST_BE_NON_NEGATIVE_INTEGER, "k"); } if (n.compareTo(k) < 0) { return BigInteger.ZERO; @@ -510,26 +509,26 @@ private BigInteger calculatePerm(BigInteger n, BigInteger k) { @Specialization PInt perm(long n, long k, - @Shared @Cached PythonObjectFactory factory) { - return factory.createInt(calculatePerm(PInt.longToBigInteger(n), PInt.longToBigInteger(k))); + @Bind PythonLanguage language) { + return PFactory.createInt(language, calculatePerm(PInt.longToBigInteger(n), PInt.longToBigInteger(k))); } @Specialization PInt perm(long n, PInt k, - @Shared @Cached PythonObjectFactory factory) { - return factory.createInt(calculatePerm(PInt.longToBigInteger(n), k.getValue())); + @Bind PythonLanguage language) { + return PFactory.createInt(language, calculatePerm(PInt.longToBigInteger(n), k.getValue())); } @Specialization PInt perm(PInt n, long k, - @Shared @Cached PythonObjectFactory factory) { - return factory.createInt(calculatePerm(n.getValue(), PInt.longToBigInteger(k))); + @Bind PythonLanguage language) { + return PFactory.createInt(language, calculatePerm(n.getValue(), PInt.longToBigInteger(k))); } @Specialization PInt perm(PInt n, PInt k, - @Shared @Cached PythonObjectFactory factory) { - return factory.createInt(calculatePerm(n.getValue(), k.getValue())); + @Bind PythonLanguage language) { + return PFactory.createInt(language, calculatePerm(n.getValue(), k.getValue())); } @Specialization @@ -589,15 +588,15 @@ static double fmodDD(double left, double right, @Bind("this") Node inliningTarget, @Cached InlinedConditionProfile infProfile, @Cached InlinedConditionProfile zeroProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { raiseMathDomainError(inliningTarget, Double.isInfinite(left), infProfile, raiseNode); raiseMathDomainError(inliningTarget, right == 0, zeroProfile, raiseNode); return left % right; } - static void raiseMathDomainError(Node inliningTarget, boolean con, InlinedConditionProfile profile, PRaiseNode.Lazy raiseNode) { + static void raiseMathDomainError(Node inliningTarget, boolean con, InlinedConditionProfile profile, PRaiseNode raiseNode) { if (profile.profile(inliningTarget, con)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MATH_DOMAIN_ERROR); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); } } @@ -616,10 +615,10 @@ public abstract static class RemainderNode extends PythonBinaryClinicBuiltinNode @Specialization static double remainderDD(double x, double y, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (Double.isFinite(x) && Double.isFinite(y)) { if (y == 0.0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MATH_DOMAIN_ERROR); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); } double absx = Math.abs(x); double absy = Math.abs(y); @@ -642,7 +641,7 @@ static double remainderDD(double x, double y, return y; } if (Double.isInfinite(x)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MATH_DOMAIN_ERROR); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); } return x; } @@ -701,12 +700,12 @@ public static double[] frexp(double value) { @Specialization static PTuple frexpD(double value, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { Object[] content = new Object[2]; double[] primContent = frexp(value); content[0] = primContent[0]; content[1] = (int) primContent[1]; - return factory.createTuple(content); + return PFactory.createTuple(language, content); } @Override @@ -716,7 +715,7 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Builtin(name = "isnan", minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(MathGuards.class) @GenerateNodeFactory public abstract static class IsNanNode extends PythonUnaryBuiltinNode { @@ -753,11 +752,11 @@ public abstract static class IsCloseNode extends PythonClinicBuiltinNode { @Specialization static boolean isCloseDouble(double a, double b, double rel_tol, double abs_tol, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { double diff; if (rel_tol < 0.0 || abs_tol < 0.0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.TOLERANCE_MUST_NON_NEGATIVE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.TOLERANCE_MUST_NON_NEGATIVE); } if (a == b) { @@ -782,7 +781,7 @@ protected ArgumentClinicProvider getArgumentClinic() { @Builtin(name = "ldexp", minNumOfPositionalArgs = 2, numOfPositionalOnlyArgs = 2, parameterNames = {"x", "i"}) @ArgumentClinic(name = "x", conversion = ArgumentClinic.ClinicConversion.Double) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @GenerateNodeFactory public abstract static class LdexpNode extends PythonBinaryClinicBuiltinNode { @@ -796,9 +795,9 @@ private static int makeInt(long x) { return (int) result; } - private static double exceptInfinity(Node inliningTarget, double result, double arg, PRaiseNode.Lazy raiseNode) { + private static double exceptInfinity(Node inliningTarget, double result, double arg, PRaiseNode raiseNode) { if (Double.isInfinite(result) && !Double.isInfinite(arg)) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.MATH_RANGE_ERROR); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.MATH_RANGE_ERROR); } else { return result; } @@ -807,7 +806,7 @@ private static double exceptInfinity(Node inliningTarget, double result, double @Specialization static double ldexp(double mantissa, long exp, @Bind("this") Node inliningTarget, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { return exceptInfinity(inliningTarget, Math.scalb(mantissa, makeInt(exp)), mantissa, raiseNode); } @@ -818,12 +817,12 @@ static double ldexp(VirtualFrame frame, double mantissa, Object exp, @Cached IsSubtypeNode isSubtypeNode, @Cached PyNumberIndexNode indexNode, @Cached CastToJavaLongLossyNode cast, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (isSubtypeNode.execute(getClassNode.execute(inliningTarget, exp), PythonBuiltinClassType.PInt)) { long longExp = cast.execute(inliningTarget, indexNode.execute(frame, inliningTarget, exp)); return ldexp(mantissa, longExp, inliningTarget, raiseNode); } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.EXPECTED_INT_MESSAGE); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.EXPECTED_INT_MESSAGE); } } @@ -839,17 +838,17 @@ protected ArgumentClinicProvider getArgumentClinic() { public abstract static class ModfNode extends PythonUnaryClinicBuiltinNode { @Specialization static PTuple modfD(double value, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { if (!Double.isFinite(value)) { if (Double.isInfinite(value)) { - return factory.createTuple(new Object[]{Math.copySign(0., value), value}); + return PFactory.createTuple(language, new Object[]{Math.copySign(0., value), value}); } else if (Double.isNaN(value)) { - return factory.createTuple(new Object[]{value, value}); + return PFactory.createTuple(language, new Object[]{value, value}); } } double fraction = value % 1; double integral = value - fraction; - return factory.createTuple(new Object[]{fraction, integral}); + return PFactory.createTuple(language, new Object[]{fraction, integral}); } @Override @@ -866,82 +865,78 @@ public abstract static class FsumNode extends PythonUnaryBuiltinNode { static double doIt(VirtualFrame frame, Object iterable, @Bind("this") Node inliningTarget, @Cached PyObjectGetIter getIter, - @Cached("create(Next)") LookupAndCallUnaryNode callNextNode, + @Cached PyIterNextNode nextNode, @Cached PyFloatAsDoubleNode asDoubleNode, - @Cached IsBuiltinObjectProfile stopProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached InlinedLoopConditionProfile loopProfile, + @Cached PRaiseNode raiseNode) { + /* + * This implementation is taken from CPython. The performance is not good. Should be + * faster. It can be easily replace with much simpler code based on BigDecimal: + * + * BigDecimal result = BigDecimal.ZERO; + * + * in cycle just: result = result.add(BigDecimal.valueof(x); ... The current + * implementation is little bit faster. The testFSum in test_math.py takes in different + * implementations: CPython ~0.6s CurrentImpl: ~14.3s Using BigDecimal: ~15.1 + */ Object iterator = getIter.execute(frame, inliningTarget, iterable); - return fsum(frame, iterator, callNextNode, asDoubleNode, inliningTarget, stopProfile, raiseNode); - } - - /* - * This implementation is taken from CPython. The performance is not good. Should be faster. - * It can be easily replace with much simpler code based on BigDecimal: - * - * BigDecimal result = BigDecimal.ZERO; - * - * in cycle just: result = result.add(BigDecimal.valueof(x); ... The current implementation - * is little bit faster. The testFSum in test_math.py takes in different implementations: - * CPython ~0.6s CurrentImpl: ~14.3s Using BigDecimal: ~15.1 - */ - private static double fsum(VirtualFrame frame, Object iterator, LookupAndCallUnaryNode next, - PyFloatAsDoubleNode asDoubleNode, Node inliningTarget, IsBuiltinObjectProfile stopProfile, PRaiseNode.Lazy raiseNode) { double x, y, t, hi, lo = 0, yr, inf_sum = 0, special_sum = 0, sum; double xsave; int i, j, n = 0, arayLength = 32; double[] p = new double[arayLength]; - while (true) { + boolean exhausted = false; + while (loopProfile.profile(inliningTarget, !exhausted)) { try { - x = asDoubleNode.execute(frame, inliningTarget, next.executeObject(frame, iterator)); - } catch (PException e) { - e.expectStopIteration(inliningTarget, stopProfile); - break; - } - xsave = x; - for (i = j = 0; j < n; j++) { /* for y in partials */ - y = p[j]; - if (Math.abs(x) < Math.abs(y)) { - t = x; - x = y; - y = t; - } - hi = x + y; - yr = hi - x; - lo = y - yr; - if (lo != 0.0) { - p[i++] = lo; + Object next = nextNode.execute(frame, inliningTarget, iterator); + x = asDoubleNode.execute(frame, inliningTarget, next); + xsave = x; + for (i = j = 0; j < n; j++) { /* for y in partials */ + y = p[j]; + if (Math.abs(x) < Math.abs(y)) { + t = x; + x = y; + y = t; + } + hi = x + y; + yr = hi - x; + lo = y - yr; + if (lo != 0.0) { + p[i++] = lo; + } + x = hi; } - x = hi; - } - n = i; - if (x != 0.0) { - if (!Double.isFinite(x)) { - /* - * a nonfinite x could arise either as a result of intermediate overflow, or - * as a result of a nan or inf in the summands - */ - if (Double.isFinite(xsave)) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.INTERMEDIATE_OVERFLOW_IN, "fsum"); - } - if (Double.isInfinite(xsave)) { - inf_sum += xsave; + n = i; + if (x != 0.0) { + if (!Double.isFinite(x)) { + /* + * a nonfinite x could arise either as a result of intermediate + * overflow, or as a result of a nan or inf in the summands + */ + if (Double.isFinite(xsave)) { + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.INTERMEDIATE_OVERFLOW_IN, "fsum"); + } + if (Double.isInfinite(xsave)) { + inf_sum += xsave; + } + special_sum += xsave; + /* reset partials */ + n = 0; + } else if (n >= arayLength) { + arayLength += arayLength; + p = Arrays.copyOf(p, arayLength); + } else { + p[n++] = x; } - special_sum += xsave; - /* reset partials */ - n = 0; - } else if (n >= arayLength) { - arayLength += arayLength; - p = Arrays.copyOf(p, arayLength); - } else { - p[n++] = x; } + } catch (IteratorExhausted e) { + exhausted = true; } } if (special_sum != 0.0) { if (Double.isNaN(inf_sum)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.NEG_INF_PLUS_INF_IN); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NEG_INF_PLUS_INF_IN); } else { sum = special_sum; return sum; @@ -994,11 +989,6 @@ private static int compareAsBigDecimal(double y, double yr) { @GenerateNodeFactory public abstract static class GcdNode extends PythonVarargsBuiltinNode { - @Override - public Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported { - return execute(frame, self, arguments, keywords); - } - @Specialization(guards = {"args.length > 1", "keywords.length == 0"}) public static Object gcd(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] args, @SuppressWarnings("unused") PKeyword[] keywords, @Cached Gcd2Node gdcNode, @@ -1028,11 +1018,11 @@ public static int gcdEmpty(Object self, Object[] args, PKeyword[] keywords) { @Specialization(guards = "keywords.length != 0") @SuppressWarnings("unused") public int gcdKeywords(Object self, Object[] args, PKeyword[] keywords) { - throw raise(PythonBuiltinClassType.TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "gcd()"); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "gcd()"); } } - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(MathGuards.class) public abstract static class Gcd2Node extends Node { @@ -1058,14 +1048,14 @@ static long gcd(long x, long y) { @Specialization static PInt gcd(long x, PInt y, - @Shared("factory") @Cached PythonObjectFactory factory) { - return factory.createInt(op(PInt.longToBigInteger(x), y.getValue())); + @Bind PythonLanguage language) { + return PFactory.createInt(language, op(PInt.longToBigInteger(x), y.getValue())); } @Specialization static PInt gcd(PInt x, long y, - @Shared("factory") @Cached PythonObjectFactory factory) { - return factory.createInt(op(x.getValue(), PInt.longToBigInteger(y))); + @Bind PythonLanguage language) { + return PFactory.createInt(language, op(x.getValue(), PInt.longToBigInteger(y))); } @TruffleBoundary @@ -1075,38 +1065,38 @@ private static BigInteger op(BigInteger x, BigInteger y) { @Specialization PInt gcd(PInt x, PInt y, - @Shared("factory") @Cached PythonObjectFactory factory) { - return factory.createInt(op(x.getValue(), y.getValue())); + @Bind PythonLanguage language) { + return PFactory.createInt(language, op(x.getValue(), y.getValue())); } @Specialization static int gcd(@SuppressWarnings("unused") double x, @SuppressWarnings("unused") double y, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, "float"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, "float"); } @Specialization static int gcd(@SuppressWarnings("unused") long x, @SuppressWarnings("unused") double y, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, "float"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, "float"); } @Specialization static int gcd(@SuppressWarnings("unused") double x, @SuppressWarnings("unused") long y, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, "float"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, "float"); } @Specialization static int gcd(@SuppressWarnings("unused") double x, @SuppressWarnings("unused") PInt y, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, "float"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, "float"); } @Specialization(guards = "!isRecursive") static int gcd(@SuppressWarnings("unused") PInt x, @SuppressWarnings("unused") double y, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, "float"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, "float"); } @Specialization(guards = {"!isRecursive", "!isNumber(x) || !isNumber(y)"}) @@ -1122,7 +1112,7 @@ static Object gcd(VirtualFrame frame, Object x, Object y, @Specialization Object gcdNative(@SuppressWarnings("unused") PythonAbstractNativeObject a, @SuppressWarnings("unused") Object b) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(this, SystemError, ErrorMessages.GCD_FOR_NATIVE_NOT_SUPPORTED); + throw PRaiseNode.raiseStatic(this, SystemError, ErrorMessages.GCD_FOR_NATIVE_NOT_SUPPORTED); } @NeverDefault @@ -1138,26 +1128,22 @@ public static Gcd2Node create(boolean isRecursive) { @Builtin(name = "lcm", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, declaresExplicitSelf = true) @GenerateNodeFactory public abstract static class LcmNode extends PythonVarargsBuiltinNode { - @Override - public Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported { - return execute(frame, self, arguments, keywords); - } @Specialization(guards = {"args.length > 1", "keywords.length == 0"}) - public static Object gcd(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] args, @SuppressWarnings("unused") PKeyword[] keywords, + static Object gcd(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] args, @SuppressWarnings("unused") PKeyword[] keywords, @Bind("this") Node inliningTarget, @Cached LoopConditionProfile profile, + @Cached IsZeroNode isZeroNode, @Shared @Cached PyNumberIndexNode indexNode, @Cached Gcd2Node gcdNode, @Cached IntBuiltins.FloorDivNode floorDivNode, @Cached IntBuiltins.MulNode mulNode, - @Cached BinaryComparisonNode.EqNode eqNode, @Shared @Cached BuiltinFunctions.AbsNode absNode) { Object a = indexNode.execute(frame, inliningTarget, args[0]); profile.profileCounted(args.length); for (int i = 1; profile.inject(i < args.length); i++) { Object b = indexNode.execute(frame, inliningTarget, args[i]); - if ((boolean) eqNode.executeObject(frame, a, 0)) { + if (isZeroNode.execute(inliningTarget, a)) { continue; } Object g = gcdNode.execute(frame, a, b); @@ -1185,14 +1171,47 @@ public static int gcdEmpty(Object self, Object[] args, PKeyword[] keywords) { @Specialization(guards = "keywords.length != 0") @SuppressWarnings("unused") public int gcdKeywords(Object self, Object[] args, PKeyword[] keywords) { - throw raise(PythonBuiltinClassType.TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "gcd()"); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "gcd()"); + } + + // Fast-path from CPython uses identity comparison to 0 as best effort check + @TypeSystemReference(PythonIntegerTypes.class) + @GenerateInline + @GenerateCached(false) + abstract static class IsZeroNode extends Node { + abstract boolean execute(Node inliningTarget, Object value); + + @Specialization(guards = "a == 0") + static boolean isLongZero(long a) { + return true; + } + + @Specialization(guards = "a != 0") + static boolean isLongNonZero(long a) { + return false; + } + + @Specialization(guards = "i.isZero()") + static boolean isPIntZero(PInt i) { + return true; + } + + @Specialization(guards = "!i.isZero()") + static boolean isPIntNonZero(PInt i) { + return false; + } + + @Fallback + static boolean others(Object o) { + return false; + } } } @Builtin(name = "nextafter", minNumOfPositionalArgs = 2, parameterNames = {"start", "direction"}) @ArgumentClinic(name = "start", conversion = ArgumentClinic.ClinicConversion.Double) @ArgumentClinic(name = "direction", conversion = ArgumentClinic.ClinicConversion.Double) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @GenerateNodeFactory @ImportStatic(MathGuards.class) public abstract static class NextAfterNode extends PythonBinaryClinicBuiltinNode { @@ -1210,7 +1229,7 @@ static double nextAfter(double start, double direction) { @Builtin(name = "ulp", minNumOfPositionalArgs = 1, parameterNames = {"x"}) @ArgumentClinic(name = "x", conversion = ArgumentClinic.ClinicConversion.Double) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @GenerateNodeFactory @ImportStatic(MathGuards.class) public abstract static class UlpNode extends PythonUnaryClinicBuiltinNode { @@ -1249,7 +1268,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, AcosNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { checkMathDomainError(Double.isInfinite(value) || -1 > value || value > 1, inliningTarget, raiseNode); return Math.acos(value); } @@ -1283,7 +1302,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, AcoshNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { checkMathDomainError(value < 1, inliningTarget, raiseNode); return MathUtils.acosh(value); } @@ -1300,7 +1319,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, AsinNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { checkMathDomainError(value < -1 || value > 1, inliningTarget, raiseNode); return Math.asin(value); } @@ -1317,7 +1336,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, CosNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { return Math.cos(value); } } @@ -1333,7 +1352,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, CoshNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { double result = Math.cosh(value); checkMathRangeError(Double.isInfinite(result) && Double.isFinite(value), inliningTarget, raiseNode); return result; @@ -1351,7 +1370,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, SinNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { return Math.sin(value); } } @@ -1367,7 +1386,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, SinhNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { double result = Math.sinh(value); checkMathRangeError(Double.isInfinite(result) && Double.isFinite(value), inliningTarget, raiseNode); return result; @@ -1385,7 +1404,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, TanNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { return Math.tan(value); } } @@ -1401,7 +1420,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, TanhNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { return Math.tanh(value); } } @@ -1417,7 +1436,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, AtanNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { return Math.atan(value); } } @@ -1433,7 +1452,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, AtanhNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { double abs = Math.abs(value); checkMathDomainError(abs >= 1.0, inliningTarget, raiseNode); return MathUtils.atanh(value); @@ -1441,7 +1460,7 @@ private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy } @Builtin(name = "asinh", minNumOfPositionalArgs = 1, doc = "Return the inverse hyperbolic sine of x.") - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(MathGuards.class) @GenerateNodeFactory public abstract static class AsinhNode extends PythonUnaryBuiltinNode { @@ -1453,7 +1472,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, AsinhNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { return MathUtils.asinh(value); } @@ -1463,7 +1482,7 @@ public static AsinhNode create() { } @Builtin(name = "isfinite", minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(MathGuards.class) @GenerateNodeFactory public abstract static class IsFiniteNode extends PythonUnaryBuiltinNode { @@ -1492,7 +1511,7 @@ public static boolean isinf(VirtualFrame frame, Object value, } @Builtin(name = "isinf", minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(MathGuards.class) @GenerateNodeFactory public abstract static class IsInfNode extends PythonUnaryBuiltinNode { @@ -1521,7 +1540,7 @@ public static boolean isinf(VirtualFrame frame, Object value, } @Builtin(name = "log", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(MathGuards.class) @GenerateNodeFactory @SuppressWarnings("truffle-static-method") @@ -1548,18 +1567,18 @@ protected static double logBigInteger(BigInteger val) { return blex > 0 ? res + blex * LOG2 : res; } - private static double countBase(double base, Node inliningTarget, InlinedConditionProfile divByZero, PRaiseNode.Lazy raiseNode) { + private static double countBase(double base, Node inliningTarget, InlinedConditionProfile divByZero, PRaiseNode raiseNode) { double logBase = Math.log(base); if (divByZero.profile(inliningTarget, logBase == 0)) { - throw raiseNode.get(inliningTarget).raise(ZeroDivisionError, ErrorMessages.S_DIVISION_BY_ZERO, "float"); + throw raiseNode.raise(inliningTarget, ZeroDivisionError, ErrorMessages.S_DIVISION_BY_ZERO, "float"); } return logBase; } - private static double countBase(BigInteger base, Node inliningTarget, InlinedConditionProfile divByZero, PRaiseNode.Lazy raiseNode) { + private static double countBase(BigInteger base, Node inliningTarget, InlinedConditionProfile divByZero, PRaiseNode raiseNode) { double logBase = logBigInteger(base); if (divByZero.profile(inliningTarget, logBase == 0)) { - throw raiseNode.get(inliningTarget).raise(ZeroDivisionError, ErrorMessages.S_DIVISION_BY_ZERO, "float"); + throw raiseNode.raise(inliningTarget, ZeroDivisionError, ErrorMessages.S_DIVISION_BY_ZERO, "float"); } return logBase; } @@ -1568,7 +1587,7 @@ private static double countBase(BigInteger base, Node inliningTarget, InlinedCon static double log(long value, PNone novalue, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile doNotFit, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { return logDN(value, novalue, inliningTarget, doNotFit, raiseNode); } @@ -1576,7 +1595,7 @@ static double log(long value, PNone novalue, static double logDN(double value, @SuppressWarnings("unused") PNone novalue, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile doNotFit, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { raiseMathError(inliningTarget, doNotFit, value <= 0, raiseNode); return Math.log(value); } @@ -1586,7 +1605,7 @@ static double logDN(double value, @SuppressWarnings("unused") PNone novalue, static double logPIN(PInt value, @SuppressWarnings("unused") PNone novalue, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile doNotFit, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { BigInteger bValue = value.getValue(); raiseMathError(inliningTarget, doNotFit, bValue.compareTo(BigInteger.ZERO) < 0, raiseNode); return logBigInteger(bValue); @@ -1597,7 +1616,7 @@ static double logLL(long value, long base, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile doNotFit, @Shared @Cached InlinedConditionProfile divByZero, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { return logDD(value, base, inliningTarget, doNotFit, divByZero, raiseNode); } @@ -1606,7 +1625,7 @@ static double logDL(double value, long base, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile doNotFit, @Shared @Cached InlinedConditionProfile divByZero, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { return logDD(value, base, inliningTarget, doNotFit, divByZero, raiseNode); } @@ -1615,7 +1634,7 @@ static double logLD(long value, double base, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile doNotFit, @Shared @Cached InlinedConditionProfile divByZero, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { return logDD(value, base, inliningTarget, doNotFit, divByZero, raiseNode); } @@ -1624,7 +1643,7 @@ static double logDD(double value, double base, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile doNotFit, @Shared @Cached InlinedConditionProfile divByZero, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { raiseMathError(inliningTarget, doNotFit, value < 0 || base <= 0, raiseNode); double logBase = countBase(base, inliningTarget, divByZero, raiseNode); return Math.log(value) / logBase; @@ -1636,7 +1655,7 @@ static double logDPI(double value, PInt base, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile doNotFit, @Shared @Cached InlinedConditionProfile divByZero, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { BigInteger bBase = base.getValue(); raiseMathError(inliningTarget, doNotFit, value < 0 || bBase.compareTo(BigInteger.ZERO) <= 0, raiseNode); double logBase = countBase(bBase, inliningTarget, divByZero, raiseNode); @@ -1648,7 +1667,7 @@ static double logPIL(PInt value, long base, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile doNotFit, @Shared @Cached InlinedConditionProfile divByZero, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { return logPID(value, base, inliningTarget, doNotFit, divByZero, raiseNode); } @@ -1658,7 +1677,7 @@ static double logPID(PInt value, double base, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile doNotFit, @Shared @Cached InlinedConditionProfile divByZero, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { BigInteger bValue = value.getValue(); raiseMathError(inliningTarget, doNotFit, bValue.compareTo(BigInteger.ZERO) < 0 || base <= 0, raiseNode); double logBase = countBase(base, inliningTarget, divByZero, raiseNode); @@ -1671,7 +1690,7 @@ static double logLPI(long value, PInt base, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile doNotFit, @Shared @Cached InlinedConditionProfile divByZero, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { BigInteger bBase = base.getValue(); raiseMathError(inliningTarget, doNotFit, value < 0 || bBase.compareTo(BigInteger.ZERO) <= 0, raiseNode); double logBase = countBase(bBase, inliningTarget, divByZero, raiseNode); @@ -1684,7 +1703,7 @@ static double logPIPI(PInt value, PInt base, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile doNotFit, @Shared @Cached InlinedConditionProfile divByZero, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { BigInteger bValue = value.getValue(); BigInteger bBase = base.getValue(); raiseMathError(inliningTarget, doNotFit, bValue.compareTo(BigInteger.ZERO) < 0 || bBase.compareTo(BigInteger.ZERO) <= 0, raiseNode); @@ -1727,9 +1746,9 @@ static double logPIPI(PInt value, PInt base, return executeRecursiveLogNode(frame, value, asDoubleNode.execute(frame, inliningTarget, base)); } - private static void raiseMathError(Node inliningTarget, InlinedConditionProfile doNotFit, boolean con, PRaiseNode.Lazy raiseNode) { + private static void raiseMathError(Node inliningTarget, InlinedConditionProfile doNotFit, boolean con, PRaiseNode raiseNode) { if (doNotFit.profile(inliningTarget, con)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MATH_DOMAIN_ERROR); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); } } @@ -1749,7 +1768,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, Log1pNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { if (value == 0 || value == Double.POSITIVE_INFINITY || Double.isNaN(value)) { return value; } @@ -1785,7 +1804,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, Log2Node::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { checkMathDomainError(value <= 0, inliningTarget, raiseNode); double[] frexpR = FrexpNode.frexp(value); double m = frexpR[0]; @@ -1832,7 +1851,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, Log10Node::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { checkMathDomainError(value <= 0, inliningTarget, raiseNode); return Math.log10(value); } @@ -1861,7 +1880,7 @@ public abstract static class PowNode extends PythonBinaryClinicBuiltinNode { @Specialization static double pow(double left, double right, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { double result = 0; if (!Double.isFinite(left) || !Double.isFinite(right)) { if (Double.isNaN(left)) { @@ -1892,12 +1911,12 @@ static double pow(double left, double right, result = Math.pow(left, right); if (!Double.isFinite(result)) { if (Double.isNaN(result)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MATH_DOMAIN_ERROR); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); } else if (Double.isInfinite(result)) { if (left == 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MATH_DOMAIN_ERROR); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MATH_DOMAIN_ERROR); } else { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.MATH_RANGE_ERROR); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.MATH_RANGE_ERROR); } } } @@ -1919,10 +1938,10 @@ public abstract static class TruncNode extends PythonUnaryBuiltinNode { static Object trunc(VirtualFrame frame, Object obj, @Bind("this") Node inliningTarget, @Cached("create(T___TRUNC__)") LookupAndCallUnaryNode callTrunc, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object result = callTrunc.executeObject(frame, obj); if (result == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.TYPE_DOESNT_DEFINE_METHOD, obj, "__trunc__"); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TYPE_DOESNT_DEFINE_METHOD, obj, "__trunc__"); } return result; } @@ -1956,7 +1975,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, DegreesNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { return value * RAD_TO_DEG; } } @@ -1973,29 +1992,25 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, RadiansNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { return value * DEG_TO_RAD; } } @Builtin(name = "hypot", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, declaresExplicitSelf = true) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @GenerateNodeFactory @ImportStatic(MathGuards.class) public abstract static class HypotNode extends PythonVarargsBuiltinNode { - @Override - public Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported { - return execute(frame, self, arguments, keywords); - } - @Specialization(guards = "arguments.length == 2") public double hypot2(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] arguments, PKeyword[] keywords, @Bind("this") Node inliningTarget, + @Exclusive @Cached PRaiseNode raiseNode, @Exclusive @Cached PyFloatAsDoubleNode xAsDouble, @Exclusive @Cached PyFloatAsDoubleNode yAsDouble) { if (keywords.length != 0) { - throw raise(PythonBuiltinClassType.TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "hypot()"); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "hypot()"); } double x = xAsDouble.execute(frame, inliningTarget, arguments[0]); double y = yAsDouble.execute(frame, inliningTarget, arguments[1]); @@ -2006,9 +2021,10 @@ public double hypot2(VirtualFrame frame, @SuppressWarnings("unused") Object self @SuppressWarnings("truffle-static-method") double hypotGeneric(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] arguments, PKeyword[] keywords, @Bind("this") Node inliningTarget, + @Exclusive @Cached PRaiseNode raiseNode, @Exclusive @Cached PyFloatAsDoubleNode asDoubleNode) { if (keywords.length != 0) { - throw raise(PythonBuiltinClassType.TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "hypot()"); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "hypot()"); } double max = 0.0; boolean foundNan = false; @@ -2113,7 +2129,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, ErfNode::compute); } - private static double compute(Node inliningTarget, double value, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double value, PRaiseNode raiseNode) { double absx, cf; if (Double.isNaN(value)) { @@ -2140,7 +2156,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, ErfcNode::compute); } - private static double compute(Node inliningTarget, double x, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double x, PRaiseNode raiseNode) { double absx, cf; if (Double.isNaN(x)) { @@ -2260,7 +2276,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, GammaNode::compute); } - private static double compute(Node inliningTarget, double x, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double x, PRaiseNode raiseNode) { double absx, r, y, z, sqrtpow; /* special cases */ @@ -2353,7 +2369,7 @@ static double doGeneric(VirtualFrame frame, Object value, return helperNode.execute(frame, inliningTarget, value, LgammaNode::compute); } - private static double compute(Node inliningTarget, double x, PRaiseNode.Lazy raiseNode) { + private static double compute(Node inliningTarget, double x, PRaiseNode raiseNode) { double r; double absx; @@ -2397,7 +2413,7 @@ private static double compute(Node inliningTarget, double x, PRaiseNode.Lazy rai } @Builtin(name = "isqrt", minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) @GenerateNodeFactory @ImportStatic(MathGuards.class) public abstract static class IsqrtNode extends PythonUnaryBuiltinNode { @@ -2406,7 +2422,7 @@ public abstract static class IsqrtNode extends PythonUnaryBuiltinNode { static Object isqrtLong(long x, @Bind("this") Node inliningTarget, @Shared @Cached NarrowBigIntegerNode makeInt, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { raiseIfNegative(inliningTarget, x < 0, raiseNode); return makeInt.execute(inliningTarget, op(PInt.longToBigInteger(x))); } @@ -2415,7 +2431,7 @@ static Object isqrtLong(long x, static Object isqrtPInt(PInt x, @Bind("this") Node inliningTarget, @Shared @Cached NarrowBigIntegerNode makeInt, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { raiseIfNegative(inliningTarget, x.isNegative(), raiseNode); return makeInt.execute(inliningTarget, op(x.getValue())); } @@ -2454,9 +2470,9 @@ private static BigInteger op(BigInteger x) { return result; } - private static void raiseIfNegative(Node inliningTarget, boolean condition, PRaiseNode.Lazy raiseNode) { + private static void raiseIfNegative(Node inliningTarget, boolean condition, PRaiseNode raiseNode) { if (condition) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MUST_BE_NON_NEGATIVE, "isqrt() argument"); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MUST_BE_NON_NEGATIVE, "isqrt() argument"); } } } @@ -2465,28 +2481,27 @@ private static void raiseIfNegative(Node inliningTarget, boolean condition, PRai @GenerateNodeFactory public abstract static class ProdNode extends PythonBuiltinNode { - @Child private LookupAndCallUnaryNode callNextNode = LookupAndCallUnaryNode.create(SpecialMethodSlot.Next); - @Child private BinaryOpNode mul = BinaryArithmetic.Mul.create(); - @Specialization public Object doGeneric(VirtualFrame frame, Object iterable, Object startIn, @Bind("this") Node inliningTarget, - @Cached IsBuiltinObjectProfile errorProfile, @Cached InlinedConditionProfile startIsNoValueProfile, - @Cached PyObjectGetIter getIter) { + @Cached PyObjectGetIter getIter, + @Cached PyIterNextNode nextNode, + @Cached PyNumberMultiplyNode multiplyNode, + @Cached InlinedLoopConditionProfile loopProfile) { Object start = startIsNoValueProfile.profile(inliningTarget, PGuards.isNoValue(startIn)) ? 1 : startIn; Object iterator = getIter.execute(frame, inliningTarget, iterable); - Object value = start; - while (true) { - Object nextValue; + Object acc = start; + boolean exhausted = false; + while (loopProfile.profile(inliningTarget, !exhausted)) { try { - nextValue = callNextNode.executeObject(frame, iterator); - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); - return value; + Object next = nextNode.execute(frame, inliningTarget, iterator); + acc = multiplyNode.execute(frame, acc, next); + } catch (IteratorExhausted e) { + exhausted = true; } - value = mul.executeObject(frame, value, nextValue); } + return acc; } } @@ -2505,13 +2520,13 @@ static double doGeneric(VirtualFrame frame, Object p, Object q, @Cached InlinedConditionProfile infProfile, @Cached InlinedConditionProfile nanProfile, @Cached InlinedConditionProfile trivialProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { // adapted from CPython math_dist_impl and vector_norm Object[] ps = getObjectArray.execute(inliningTarget, tupleCtor.execute(frame, p)); Object[] qs = getObjectArray.execute(inliningTarget, tupleCtor.execute(frame, q)); int len = ps.length; if (len != qs.length) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.BOTH_POINTS_MUST_HAVE_THE_SAME_NUMBER_OF_DIMENSIONS); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.BOTH_POINTS_MUST_HAVE_THE_SAME_NUMBER_OF_DIMENSIONS); } double[] diffs = new double[len]; double max = 0.0; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/NtModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/NtModuleBuiltins.java index 2f003dff72..738f1bb76d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/NtModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/NtModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,6 +47,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; import com.oracle.graal.python.builtins.Builtin; @@ -65,7 +66,7 @@ import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaStringNode; import com.oracle.graal.python.runtime.PosixSupportLibrary; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -123,12 +124,12 @@ abstract static class PathSplitRootNode extends PythonUnaryClinicBuiltinNode { Object splitroot(PosixPath path) { // TODO should call WINAPI PathCchSkipRoot - PythonObjectFactory factory = PythonObjectFactory.getUncached(); + PythonLanguage language = PythonLanguage.get(null); TruffleString pathString = PosixSupportLibrary.getUncached().getPathAsString(getPosixSupport(), path.value); int len = pathString.codePointLengthUncached(TS_ENCODING); int index = pathString.indexOfCodePointUncached(':', 0, len, TS_ENCODING); if (index <= 0) { - return factory.createTuple(new Object[]{T_EMPTY_STRING, pathString}); + return PFactory.createTuple(language, new Object[]{T_EMPTY_STRING, pathString}); } else { index++; int first = pathString.codePointAtIndexUncached(index, TS_ENCODING); @@ -137,7 +138,7 @@ Object splitroot(PosixPath path) { } TruffleString root = pathString.substringUncached(0, index, TS_ENCODING, false); TruffleString rest = pathString.substringUncached(index, len - index, TS_ENCODING, false); - return factory.createTuple(new Object[]{root, rest}); + return PFactory.createTuple(language, new Object[]{root, rest}); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/OperatorModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/OperatorModuleBuiltins.java index 5a0322e8dc..8bf4f26af4 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/OperatorModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/OperatorModuleBuiltins.java @@ -54,13 +54,13 @@ import com.oracle.graal.python.lib.PyNumberMultiplyNode; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyObjectIsTrueNode; -import com.oracle.graal.python.lib.PySequenceConcat; +import com.oracle.graal.python.lib.PySequenceConcatNode; +import com.oracle.graal.python.lib.PySequenceInPlaceConcatNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaStringNode; import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext; @@ -71,7 +71,6 @@ import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; @@ -113,7 +112,18 @@ abstract static class ConcatNode extends PythonBinaryBuiltinNode { @Specialization static Object doObject(VirtualFrame frame, Object left, Object right, @Bind("this") Node inliningTarget, - @Cached PySequenceConcat concatNode) { + @Cached PySequenceConcatNode concatNode) { + return concatNode.execute(frame, inliningTarget, left, right); + } + } + + @Builtin(name = "iconcat", minNumOfPositionalArgs = 2) + @GenerateNodeFactory + abstract static class IConcatNode extends PythonBinaryBuiltinNode { + @Specialization + static Object doObject(VirtualFrame frame, Object left, Object right, + @Bind("this") Node inliningTarget, + @Cached PySequenceInPlaceConcatNode concatNode) { return concatNode.execute(frame, inliningTarget, left, right); } } @@ -123,15 +133,13 @@ static Object doObject(VirtualFrame frame, Object left, Object right, abstract static class MulNode extends PythonBinaryBuiltinNode { @Specialization static Object doObject(VirtualFrame frame, Object left, Object right, - @Bind("this") Node inliningTarget, @Cached PyNumberMultiplyNode mulNode) { - return mulNode.execute(frame, inliningTarget, left, right); + return mulNode.execute(frame, left, right); } } // _compare_digest @Builtin(name = "_compare_digest", minNumOfPositionalArgs = 2) - @TypeSystemReference(PythonArithmeticTypes.class) @GenerateNodeFactory abstract static class CompareDigestNode extends PythonBinaryBuiltinNode { @@ -142,14 +150,14 @@ static boolean compare(VirtualFrame frame, Object left, Object right, @Cached CastToJavaStringNode cast, @CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { String leftString = cast.execute(left); String rightString = cast.execute(right); return tscmp(leftString, rightString); } catch (CannotCastException e) { if (!bufferAcquireLib.hasBuffer(left) || !bufferAcquireLib.hasBuffer(right)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_OR_COMBINATION_OF_TYPES, left, right); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_OR_COMBINATION_OF_TYPES, left, right); } Object savedState = IndirectCallContext.enter(frame, indirectCallData); Object leftBuffer = bufferAcquireLib.acquireReadonly(left); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PolyglotModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PolyglotModuleBuiltins.java index a6656c2793..9f2a8457b8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PolyglotModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PolyglotModuleBuiltins.java @@ -113,12 +113,13 @@ import com.oracle.graal.python.nodes.interop.InteropBehaviorMethod; import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode; import com.oracle.graal.python.nodes.object.GetForeignObjectClassNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; +import com.oracle.graal.python.nodes.statement.AbstractImportNode; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaStringNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.graal.python.runtime.sequence.storage.ArrayBasedSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.EmptySequenceStorage; @@ -161,6 +162,7 @@ public final class PolyglotModuleBuiltins extends PythonBuiltins { private static final TruffleString T_MODIFIABLE = tsLiteral("modifiable"); private static final TruffleString T_INVOKABLE = tsLiteral("invokable"); private static final TruffleString T_INTERNAL = tsLiteral("internal"); + private static final TruffleString T_INTERNAL_POLYGLOT_MODULE = tsLiteral("_polyglot"); @Override protected List> getNodeFactories() { @@ -189,6 +191,9 @@ public void postInitialize(Python3Core core) { super.postInitialize(core); GetForeignObjectClassNode.getUncached().defineSingleTraitClasses(core.getContext()); + + // import polyglot decorators which are defined in Python code + AbstractImportNode.importModule(T_INTERNAL_POLYGLOT_MODULE); } @Builtin(name = "import_value", minNumOfPositionalArgs = 1, parameterNames = {"name"}) @@ -200,7 +205,7 @@ Object importSymbol(TruffleString name, @Cached PForeignToPTypeNode convert) { Env env = getContext().getEnv(); if (!env.isPolyglotBindingsAccessAllowed()) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.NotImplementedError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED); + throw PRaiseNode.raiseStatic(this, PythonErrorType.NotImplementedError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED); } Object object = env.importSymbol(name.toJavaStringUncached()); if (object == null) { @@ -217,19 +222,19 @@ abstract static class EvalInteropNode extends PythonTernaryBuiltinNode { @Specialization Object eval(Object pathObj, Object stringObj, Object languageObj) { if (languageObj instanceof PNone) { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.POLYGLOT_EVAL_MUST_PASS_LANG_AND_STRING_OR_PATH); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.POLYGLOT_EVAL_MUST_PASS_LANG_AND_STRING_OR_PATH); } boolean hasString = !(stringObj instanceof PNone); boolean hasPath = !(pathObj instanceof PNone); if (!hasString && !hasPath || hasString && hasPath) { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.POLYGLOT_EVAL_MUST_PASS_LANG_AND_STRING_OR_PATH); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.POLYGLOT_EVAL_MUST_PASS_LANG_AND_STRING_OR_PATH); } String languageName = toJavaString(languageObj, "language"); String string = hasString ? toJavaString(stringObj, "string") : null; String path = hasPath ? toJavaString(pathObj, "path") : null; Env env = getContext().getEnv(); if (!env.isPolyglotEvalAllowed(null)) { - throw PRaiseNode.raiseUncached(this, RuntimeError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED); + throw PRaiseNode.raiseStatic(this, RuntimeError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED); } Map languages = env.getPublicLanguages(); String mimeType = null; @@ -239,10 +244,10 @@ Object eval(Object pathObj, Object stringObj, Object languageObj) { } LanguageInfo language = languages.get(languageName); if (language == null) { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.POLYGLOT_LANGUAGE_S_NOT_FOUND, languageName); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.POLYGLOT_LANGUAGE_S_NOT_FOUND, languageName); } if (!env.isPolyglotEvalAllowed(language)) { - throw PRaiseNode.raiseUncached(this, RuntimeError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED_FOR_LANGUAGE_S, languageName); + throw PRaiseNode.raiseStatic(this, RuntimeError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED_FOR_LANGUAGE_S, languageName); } try { SourceBuilder builder; @@ -259,9 +264,9 @@ Object eval(Object pathObj, Object stringObj, Object languageObj) { } catch (AbstractTruffleException e) { throw e; } catch (IOException e) { - throw PRaiseNode.raiseUncached(this, OSError, ErrorMessages.S, e); + throw PRaiseNode.raiseStatic(this, OSError, ErrorMessages.S, e); } catch (RuntimeException e) { - throw PRaiseNode.raiseUncached(this, RuntimeError, e); + throw PRaiseNode.raiseStatic(this, RuntimeError, e); } } @@ -269,7 +274,7 @@ private String toJavaString(Object object, String parameterName) { try { return CastToJavaStringNode.getUncached().execute(object); } catch (CannotCastException e) { - throw PRaiseNode.raiseUncached(this, TypeError, ErrorMessages.S_BRACKETS_ARG_S_MUST_BE_S_NOT_P, "polyglot.eval", parameterName, "str", object); + throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.S_BRACKETS_ARG_S_MUST_BE_S_NOT_P, "polyglot.eval", parameterName, "str", object); } } @@ -299,7 +304,7 @@ public abstract static class ExportSymbolNode extends PythonBuiltinNode { Object exportSymbolKeyValue(TruffleString name, Object value) { Env env = getContext().getEnv(); if (!env.isPolyglotBindingsAccessAllowed()) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.NotImplementedError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED); + throw PRaiseNode.raiseStatic(this, PythonErrorType.NotImplementedError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED); } env.exportSymbol(name.toJavaStringUncached(), value); return value; @@ -327,7 +332,7 @@ Object exportSymbolAmbiguous(Object arg1, TruffleString arg2) { Object exportSymbol(PFunction fun, @SuppressWarnings("unused") PNone name) { Env env = getContext().getEnv(); if (!env.isPolyglotBindingsAccessAllowed()) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.NotImplementedError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED); + throw PRaiseNode.raiseStatic(this, PythonErrorType.NotImplementedError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED); } env.exportSymbol(fun.getName().toJavaStringUncached(), fun); return fun; @@ -338,7 +343,7 @@ Object exportSymbol(PFunction fun, @SuppressWarnings("unused") PNone name) { Object exportSymbol(PBuiltinFunction fun, @SuppressWarnings("unused") PNone name) { Env env = getContext().getEnv(); if (!env.isPolyglotBindingsAccessAllowed()) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.NotImplementedError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED); + throw PRaiseNode.raiseStatic(this, PythonErrorType.NotImplementedError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED); } env.exportSymbol(fun.getName().toJavaStringUncached(), fun); return fun; @@ -349,13 +354,13 @@ static Object exportSymbol(VirtualFrame frame, Object fun, @SuppressWarnings("un @Bind("this") Node inliningTarget, @Cached("create(T___NAME__)") GetAttributeNode.GetFixedAttributeNode getNameAttributeNode, @Cached CastToJavaStringNode castToStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object attrNameValue = getNameAttributeNode.executeObject(frame, fun); String methodName; try { methodName = castToStringNode.execute(attrNameValue); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.METHOD_NAME_MUST_BE, attrNameValue); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.METHOD_NAME_MUST_BE, attrNameValue); } export(inliningTarget, methodName, fun); return fun; @@ -363,8 +368,8 @@ static Object exportSymbol(VirtualFrame frame, Object fun, @SuppressWarnings("un @Fallback static Object exportSymbol(Object value, Object name, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.EXPECTED_ARG_TYPES_S_S_BUT_NOT_P_P, "function", "object, str", value, name); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.EXPECTED_ARG_TYPES_S_S_BUT_NOT_P_P, "function", "object, str", value, name); } protected static boolean isModuleMethod(Object o) { @@ -375,7 +380,7 @@ protected static boolean isModuleMethod(Object o) { private static void export(Node raisingNode, String name, Object obj) { Env env = PythonContext.get(raisingNode).getEnv(); if (!env.isPolyglotBindingsAccessAllowed()) { - throw PRaiseNode.raiseUncached(raisingNode, PythonErrorType.NotImplementedError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED); + throw PRaiseNode.raiseStatic(raisingNode, PythonErrorType.NotImplementedError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED); } env.exportSymbol(name, obj); } @@ -402,8 +407,8 @@ static boolean isWhole(double number) { @Specialization(guards = {"!isSupportedNumber(number)"}) static boolean unsupported(PythonAbstractObject number, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ARG_MUST_BE_NUMBER, "given", number); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ARG_MUST_BE_NUMBER, "given", number); } } @@ -627,17 +632,17 @@ public abstract static class GetRegisteredInteropBehaviorNode extends PythonUnar PList get(PythonAbstractObject klass, @Bind("this") Node inliningTarget, @Cached TypeNodes.IsTypeNode isTypeNode, - @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached PRaiseNode raiseNode, @Cached HiddenAttr.ReadNode readHiddenAttrNode) { if (isTypeNode.execute(inliningTarget, klass)) { Object value = readHiddenAttrNode.execute(inliningTarget, klass, HiddenAttr.HOST_INTEROP_BEHAVIOR, null); if (value instanceof InteropBehavior behavior) { - return factory.createList(behavior.getDefinedMethods()); + return PFactory.createList(language, behavior.getDefinedMethods()); } - return factory.createList(); + return PFactory.createList(language); } - throw raiseNode.raise(ValueError, S_ARG_MUST_BE_S_NOT_P, "first", "a type", klass); + throw raiseNode.raise(inliningTarget, ValueError, S_ARG_MUST_BE_S_NOT_P, "first", "a type", klass); } } @@ -681,17 +686,17 @@ void handleArg(Object value, InteropBehaviorMethod method, InteropBehavior inter Signature signature = function.getCode().getSignature(); // validate the function if (function.getKwDefaults().length != 0) { - throw raiseNode.raise(ValueError, S_TAKES_NO_KEYWORD_ARGS, method.name); + throw raiseNode.raise(this, ValueError, S_TAKES_NO_KEYWORD_ARGS, method.name); } else if (function.getCode().getCellVars().length != 0) { - throw raiseNode.raise(ValueError, S_CANNOT_HAVE_S, method.name, "cell vars"); + throw raiseNode.raise(this, ValueError, S_CANNOT_HAVE_S, method.name, "cell vars"); } else if (function.getCode().getFreeVars().length != 0) { - throw raiseNode.raise(ValueError, S_CANNOT_HAVE_S, method.name, "free vars"); + throw raiseNode.raise(this, ValueError, S_CANNOT_HAVE_S, method.name, "free vars"); } else { // check signature if (method.takesVarArgs != signature.takesVarArgs()) { - throw raiseNode.raise(ValueError, method.takesVarArgs ? S_TAKES_VARARGS : S_DOES_NOT_TAKE_VARARGS, method.name); + throw raiseNode.raise(this, ValueError, method.takesVarArgs ? S_TAKES_VARARGS : S_DOES_NOT_TAKE_VARARGS, method.name); } else if (signature.getMaxNumOfPositionalArgs() != method.getNumPositionalArguments()) { - throw raiseNode.raise(ValueError, S_TAKES_EXACTLY_D_ARGS, method.name, method.getNumPositionalArguments(), signature.getMaxNumOfPositionalArgs()); + throw raiseNode.raise(this, ValueError, S_TAKES_EXACTLY_D_ARGS, method.name, method.getNumPositionalArguments(), signature.getMaxNumOfPositionalArgs()); } } } @@ -772,7 +777,7 @@ Object register(PythonAbstractObject receiver, Object is_boolean, Object is_date HiddenAttr.WriteNode.executeUncached(receiver, HiddenAttr.HOST_INTEROP_BEHAVIOR, interopBehavior); return PNone.NONE; } - throw raiseNode.raise(ValueError, S_ARG_MUST_BE_S_NOT_P, "first", "a type", receiver); + throw raiseNode.raise(inliningTarget, ValueError, S_ARG_MUST_BE_S_NOT_P, "first", "a type", receiver); } } @@ -832,10 +837,10 @@ Object register(Object foreignClass, PythonClass pythonClass, boolean allowMetho @Cached ObjectHashMap.PutNode putNode, @Cached ObjectHashMap.GetNode getNode, @Cached PRaiseNode raiseNode) { - foreignClass = checkAndCleanForeignClass(foreignClass, interopLibrary, raiseNode, getContext().getEnv()); + foreignClass = checkAndCleanForeignClass(inliningTarget, foreignClass, interopLibrary, raiseNode, getContext().getEnv()); if (!isClassTypeNode.execute(inliningTarget, pythonClass)) { - throw raiseNode.raise(ValueError, S_ARG_MUST_BE_S_NOT_P, "second", "a python class", pythonClass); + throw raiseNode.raise(inliningTarget, ValueError, S_ARG_MUST_BE_S_NOT_P, "second", "a python class", pythonClass); } // Contains foreignClasses as keys and PythonClass[] as values ObjectHashMap interopTypeRegistry = getContext().interopTypeRegistry; @@ -852,11 +857,11 @@ Object register(Object foreignClass, PythonClass pythonClass, boolean allowMetho // found one or more classes for the key, insert the new class in at first place // The logic for the class lookup should be LIFO if (checkIfAlreadyRegistered(pythonClass, registeredClasses, interopLibrary)) { - throw raiseNode.raise(KeyError, INTEROP_TYPE_ALREADY_REGISTERED, interopLibrary.getMetaQualifiedName(foreignClass)); + throw raiseNode.raise(inliningTarget, KeyError, INTEROP_TYPE_ALREADY_REGISTERED, interopLibrary.getMetaQualifiedName(foreignClass)); } if (!allowMethodOverwrites) { // method overwrite not allowed, check if there is a conflict - checkForMethodConflict(pythonClass, registeredClasses, raiseNode); + checkForMethodConflict(inliningTarget, pythonClass, registeredClasses, raiseNode); } var newClasses = new PythonManagedClass[registeredClasses.length + 1]; newClasses[0] = pythonClass; @@ -884,21 +889,21 @@ private static boolean checkIfAlreadyRegistered(PythonManagedClass pythonManaged return false; } - private static void checkForMethodConflict(PythonManagedClass toCheck, PythonManagedClass[] registeredClasses, PRaiseNode raiseNode) { + private static void checkForMethodConflict(Node inliningTarget, PythonManagedClass toCheck, PythonManagedClass[] registeredClasses, PRaiseNode raiseNode) { for (TruffleString name : toCheck.getAttributeNames()) { if (toCheck.getAttribute(name) instanceof PFunction) { for (PythonManagedClass registeredClass : registeredClasses) { if (registeredClass.getAttribute(name) instanceof PFunction) { - throw raiseNode.raise(PythonBuiltinClassType.AttributeError, INTEROP_TYPE_NOT_MERGABLE, toCheck, registeredClass, name); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, INTEROP_TYPE_NOT_MERGABLE, toCheck, registeredClass, name); } } } } } - private static Object checkAndCleanForeignClass(Object object, InteropLibrary interopLibrary, PRaiseNode raiseNode, Env env) { + private static Object checkAndCleanForeignClass(Node inliningTarget, Object object, InteropLibrary interopLibrary, PRaiseNode raiseNode, Env env) { if (!interopLibrary.isMetaObject(object)) { - throw raiseNode.raise(ValueError, S_ARG_MUST_BE_S_NOT_P, "first", "a class or interface", object); + throw raiseNode.raise(inliningTarget, ValueError, S_ARG_MUST_BE_S_NOT_P, "first", "a class or interface", object); } if (!env.isHostObject(object)) { return object; @@ -939,10 +944,10 @@ Object read(Object receiver, Object key) { } else if (key instanceof Number) { return getInterop().readArrayElement(receiver, ((Number) key).longValue()); } else { - throw PRaiseNode.raiseUncached(this, PythonErrorType.AttributeError, ErrorMessages.UNKNOWN_ATTR, key); + throw PRaiseNode.raiseStatic(this, PythonErrorType.AttributeError, ErrorMessages.UNKNOWN_ATTR, key); } } catch (UnknownIdentifierException | UnsupportedMessageException | InvalidArrayIndexException e) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.AttributeError, e); + throw PRaiseNode.raiseStatic(this, PythonErrorType.AttributeError, e); } } } @@ -961,10 +966,10 @@ Object write(Object receiver, Object key, Object value) { } else if (key instanceof Number) { getInterop().writeArrayElement(receiver, ((Number) key).longValue(), value); } else { - throw PRaiseNode.raiseUncached(this, PythonErrorType.AttributeError, ErrorMessages.UNKNOWN_ATTR, key); + throw PRaiseNode.raiseStatic(this, PythonErrorType.AttributeError, ErrorMessages.UNKNOWN_ATTR, key); } } catch (UnknownIdentifierException | UnsupportedMessageException | UnsupportedTypeException | InvalidArrayIndexException e) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.AttributeError, e); + throw PRaiseNode.raiseStatic(this, PythonErrorType.AttributeError, e); } return PNone.NONE; } @@ -984,10 +989,10 @@ Object remove(Object receiver, Object key) { } else if (key instanceof Number) { getInterop().removeArrayElement(receiver, ((Number) key).longValue()); } else { - throw PRaiseNode.raiseUncached(this, PythonErrorType.AttributeError, ErrorMessages.UNKNOWN_ATTR, key); + throw PRaiseNode.raiseStatic(this, PythonErrorType.AttributeError, ErrorMessages.UNKNOWN_ATTR, key); } } catch (UnknownIdentifierException | UnsupportedMessageException | InvalidArrayIndexException e) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.AttributeError, e); + throw PRaiseNode.raiseStatic(this, PythonErrorType.AttributeError, e); } return PNone.NONE; } @@ -999,11 +1004,11 @@ public abstract static class executeNode extends PythonBuiltinNode { @Specialization static Object exec(Object receiver, Object[] arguments, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { return getInterop().execute(receiver, arguments); } catch (UnsupportedMessageException | UnsupportedTypeException | ArityException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.AttributeError, e); + throw raiseNode.raise(inliningTarget, PythonErrorType.AttributeError, e); } } } @@ -1014,11 +1019,11 @@ public abstract static class newNode extends PythonBuiltinNode { @Specialization static Object instantiate(Object receiver, Object[] arguments, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { return getInterop().instantiate(receiver, arguments); } catch (UnsupportedMessageException | UnsupportedTypeException | ArityException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.AttributeError, e); + throw raiseNode.raise(inliningTarget, PythonErrorType.AttributeError, e); } } } @@ -1030,11 +1035,11 @@ public abstract static class invokeNode extends PythonBuiltinNode { static Object invoke(Object receiver, TruffleString key, Object[] arguments, @Bind("this") Node inliningTarget, @Cached TruffleString.ToJavaStringNode toJavaStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { return getInterop().invokeMember(receiver, toJavaStringNode.execute(key), arguments); } catch (UnsupportedMessageException | UnsupportedTypeException | ArityException | UnknownIdentifierException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.AttributeError, e); + throw raiseNode.raise(inliningTarget, PythonErrorType.AttributeError, e); } } } @@ -1063,11 +1068,11 @@ public abstract static class GetSizeNode extends PythonBuiltinNode { @Specialization static Object getSize(Object receiver, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { return getInterop().getArraySize(receiver); } catch (UnsupportedMessageException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, e); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, e); } } } @@ -1130,18 +1135,18 @@ public abstract static class KeysNode extends PythonBuiltinNode { @Specialization static Object remove(Object receiver, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { return getInterop().getMembers(receiver); } catch (UnsupportedMessageException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, e); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, e); } } } @Builtin(name = "__element_info__", minNumOfPositionalArgs = 3) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerTypes.class) public abstract static class ArrayElementInfoNode extends PythonBuiltinNode { @Specialization static boolean keyInfo(Object receiver, long member, TruffleString info, @@ -1166,7 +1171,6 @@ static boolean keyInfo(Object receiver, long member, TruffleString info, @Builtin(name = "storage", minNumOfPositionalArgs = 1) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) public abstract static class StorageNode extends PythonUnaryBuiltinNode { @Specialization @TruffleBoundary @@ -1179,15 +1183,15 @@ static Object doSequence(PSequence seq, } else if (storage instanceof ArrayBasedSequenceStorage basicStorage) { arrayObject = basicStorage.getInternalArrayObject(); } else { - throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.NotImplementedError, ErrorMessages.GETTING_POLYGLOT_STORAGE_FOR_NATIVE_STORAGE_NOT_IMPLEMENTED); + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.NotImplementedError, ErrorMessages.GETTING_POLYGLOT_STORAGE_FOR_NATIVE_STORAGE_NOT_IMPLEMENTED); } return PythonContext.get(inliningTarget).getEnv().asGuestValue(arrayObject); } @Fallback static Object doError(Object object, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_P, object); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_P, object); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java index 3b62e8c849..67b859e10a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java @@ -45,6 +45,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -68,8 +69,6 @@ import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; import com.oracle.graal.python.builtins.objects.bytes.PBytes; -import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; -import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes; import com.oracle.graal.python.builtins.objects.common.SequenceNodes.LenNode; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemNode; @@ -88,9 +87,12 @@ import com.oracle.graal.python.lib.PyLongAsLongAndOverflowNode; import com.oracle.graal.python.lib.PyLongAsLongNode; import com.oracle.graal.python.lib.PyLongCheckNode; +import com.oracle.graal.python.lib.PyNumberDivmodNode; import com.oracle.graal.python.lib.PyNumberIndexNode; import com.oracle.graal.python.lib.PyOSFSPathNode; import com.oracle.graal.python.lib.PyObjectAsFileDescriptor; +import com.oracle.graal.python.lib.PyObjectGetAttr; +import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyObjectSizeNode; import com.oracle.graal.python.lib.PyUnicodeCheckNode; import com.oracle.graal.python.nodes.ErrorMessages; @@ -98,19 +100,16 @@ import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; -import com.oracle.graal.python.nodes.expression.BinaryArithmetic; -import com.oracle.graal.python.nodes.expression.BinaryOpNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentCastNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; import com.oracle.graal.python.nodes.util.CastToJavaLongLossyNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.GilNode; @@ -128,10 +127,9 @@ import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonExitException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.graal.python.runtime.sequence.storage.LongSequenceStorage; -import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.OverflowException; import com.oracle.truffle.api.CompilerDirectives; @@ -148,7 +146,6 @@ import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; @@ -162,17 +159,6 @@ public final class PosixModuleBuiltins extends PythonBuiltins { static final StructSequence.BuiltinTypeDescriptor STAT_RESULT_DESC = new StructSequence.BuiltinTypeDescriptor( PythonBuiltinClassType.PStatResult, - // @formatter:off The formatter joins these lines making it less readable - "stat_result: Result from stat, fstat, or lstat.\n\n" + - "This object may be accessed either as a tuple of\n" + - " (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n" + - "or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n" + - "\n" + - "Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n" + - "or st_flags, they are available as attributes only.\n" + - "\n" + - "See os.stat for more information.", - // @formatter:on 10, new String[]{ "st_mode", "st_ino", "st_dev", "st_nlink", "st_uid", "st_gid", "st_size", @@ -190,14 +176,6 @@ public final class PosixModuleBuiltins extends PythonBuiltins { static final StructSequence.BuiltinTypeDescriptor STATVFS_RESULT_DESC = new StructSequence.BuiltinTypeDescriptor( PythonBuiltinClassType.PStatvfsResult, - // @formatter:off The formatter joins these lines making it less readable - "statvfs_result: Result from statvfs or fstatvfs.\n\n" + - "This object may be accessed either as a tuple of\n" + - " (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n" + - "or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n" + - "\n" + - "See os.statvfs for more information.", - // @formatter:on 10, new String[]{ "f_bsize", "f_frsize", "f_blocks", "f_bfree", "f_bavail", "f_files", @@ -207,21 +185,12 @@ public final class PosixModuleBuiltins extends PythonBuiltins { private static final StructSequence.BuiltinTypeDescriptor TERMINAL_SIZE_DESC = new StructSequence.BuiltinTypeDescriptor( PythonBuiltinClassType.PTerminalSize, - "A tuple of (columns, lines) for holding terminal window size", 2, new String[]{"columns", "lines"}, new String[]{"width of the terminal window in characters", "height of the terminal window in characters"}); private static final StructSequence.BuiltinTypeDescriptor UNAME_RESULT_DESC = new StructSequence.BuiltinTypeDescriptor( PythonBuiltinClassType.PUnameResult, - // @formatter:off The formatter joins these lines making it less readable - "uname_result: Result from os.uname().\n\n" + - "This object may be accessed either as a tuple of\n" + - " (sysname, nodename, release, version, machine),\n" + - "or via the attributes sysname, nodename, release, version, and machine.\n" + - "\n" + - "See os.uname for more information.", - // @formatter:on 5, new String[]{"sysname", "nodename", "release", "version", "machine"}, new String[]{ @@ -282,9 +251,24 @@ public void initialize(Python3Core core) { haveFunctions.add(tsLiteral("HAVE_FTRUNCATE")); haveFunctions.add(tsLiteral("MS_WINDOWS")); } - addBuiltinConstant("_have_functions", core.factory().createList(haveFunctions.toArray())); - addBuiltinConstant("environ", core.factory().createDict()); - addBuiltinConstant("sysconf_names", core.factory().createDict()); + PythonLanguage language = core.getLanguage(); + addBuiltinConstant("_have_functions", PFactory.createList(language, haveFunctions.toArray())); + addBuiltinConstant("environ", PFactory.createDict(language)); + + LinkedHashMap sysconfigNames = new LinkedHashMap<>(); + for (IntConstant name : PosixConstants.sysconfigNames) { + if (name.defined) { + // add the constant without the leading underscore + String pythonName; + if (name.name.startsWith("_")) { + pythonName = name.name.substring(1); + } else { + pythonName = name.name; + } + sysconfigNames.put(pythonName, name.getValueIfDefined()); + } + } + addBuiltinConstant("sysconf_names", PFactory.createDictFromMap(language, sysconfigNames)); StructSequence.initType(core, STAT_RESULT_DESC); StructSequence.initType(core, STATVFS_RESULT_DESC); @@ -317,11 +301,12 @@ public void postInitialize(Python3Core core) { PosixSupportLibrary posixLib = PosixSupportLibrary.getUncached(); Object posixSupport = core.getContext().getPosixSupport(); + PythonLanguage language = core.getLanguage(); // fill the environ dictionary with the current environment // TODO we should probably use PosixSupportLibrary to get environ Map getenv = core.getContext().getEnv().getEnvironment(); - PDict environ = core.factory().createDict(); + PDict environ = PFactory.createDict(language); String pyenvLauncherKey = "__PYVENV_LAUNCHER__"; for (Entry entry : getenv.entrySet()) { if (entry.getKey().equals("GRAAL_PYTHON_ARGS") && entry.getValue().endsWith("\013")) { @@ -337,7 +322,7 @@ public void postInitialize(Python3Core core) { } key = toTruffleStringUncached(entry.getKey()); } else { - key = core.factory().createBytes(entry.getKey().getBytes()); + key = PFactory.createBytes(language, entry.getKey().getBytes()); } if (pyenvLauncherKey.equals(entry.getKey())) { // On Mac, the CPython launcher uses this env variable to specify the real Python @@ -353,13 +338,13 @@ public void postInitialize(Python3Core core) { if (PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32) { val = value; } else { - val = core.factory().createBytes(value.toJavaStringUncached().getBytes()); + val = PFactory.createBytes(language, value.toJavaStringUncached().getBytes()); } } else { if (PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32) { val = toTruffleStringUncached(entry.getValue()); } else { - val = core.factory().createBytes((entry.getValue().getBytes())); + val = PFactory.createBytes(language, (entry.getValue().getBytes())); } } environ.setItem(key, val); @@ -367,15 +352,6 @@ public void postInitialize(Python3Core core) { if (PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32) { // XXX: Until we fix pip environ.setItem(toTruffleStringUncached("PIP_NO_CACHE_DIR"), toTruffleStringUncached("0")); - // XXX: Until we have working winapi and winreg modules for MSVC discovery - environ.setItem(toTruffleStringUncached("DISTUTILS_USE_SDK"), toTruffleStringUncached("1")); - if (getenv.get("MSSdk") == null) { - String sdkdir = getenv.get("WindowsSdkDir"); - if (sdkdir == null) { - sdkdir = "unset"; - } - environ.setItem(toTruffleStringUncached("MSSdk"), toTruffleStringUncached(sdkdir)); - } } PythonModule posix; if (PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32) { @@ -386,9 +362,6 @@ public void postInitialize(Python3Core core) { Object environAttr = posix.getAttribute(tsLiteral("environ")); ((PDict) environAttr).setDictStorage(environ.getDictStorage()); - PDict sysconfNamesAttr = (PDict) posix.getAttribute(tsLiteral("sysconf_names")); - sysconfNamesAttr.setDictStorage(HashingStorageNodes.HashingStorageCopy.executeUncached(SysconfNode.SYSCONF_NAMES)); - if (posixLib.getBackend(posixSupport).toJavaStringUncached().equals("java")) { posix.setAttribute(toTruffleStringUncached("statvfs"), PNone.NO_VALUE); posix.setAttribute(toTruffleStringUncached("geteuid"), PNone.NO_VALUE); @@ -398,37 +371,6 @@ public void postInitialize(Python3Core core) { } } - @Builtin(name = "stat_result", minNumOfPositionalArgs = 1, parameterNames = {"$cls", "sequence", "dict"}, constructsClass = PythonBuiltinClassType.PStatResult) - @ImportStatic(PosixModuleBuiltins.class) - @GenerateNodeFactory - public abstract static class StatResultNode extends PythonTernaryBuiltinNode { - - @Specialization - public static PTuple generic(VirtualFrame frame, Object cls, Object sequence, Object dict, - @Cached("create(STAT_RESULT_DESC)") StructSequence.NewNode newNode) { - PTuple p = (PTuple) newNode.execute(frame, cls, sequence, dict); - Object[] data = CompilerDirectives.castExact(p.getSequenceStorage(), ObjectSequenceStorage.class).getInternalObjectArray(); - for (int i = 7; i <= 9; i++) { - if (data[i + 3] == PNone.NONE) { - data[i + 3] = data[i]; - } - } - return p; - } - } - - @Builtin(name = "statvfs_result", minNumOfPositionalArgs = 1, parameterNames = {"$cls", "sequence", "dict"}, constructsClass = PythonBuiltinClassType.PStatvfsResult) - @ImportStatic(PosixModuleBuiltins.class) - @GenerateNodeFactory - public abstract static class StatvfsResultNode extends PythonTernaryBuiltinNode { - - @Specialization - public static Object generic(VirtualFrame frame, Object cls, Object sequence, Object dict, - @Cached("create(STATVFS_RESULT_DESC)") StructSequence.NewNode newNode) { - return newNode.execute(frame, cls, sequence, dict); - } - } - @Builtin(name = "putenv", minNumOfPositionalArgs = 2, parameterNames = {"name", "value"}) @ArgumentClinic(name = "name", conversionClass = FsConverterNode.class) @ArgumentClinic(name = "value", conversionClass = FsConverterNode.class) @@ -445,15 +387,16 @@ static PNone putenv(VirtualFrame frame, PBytes nameBytes, PBytes valueBytes, @Bind("this") Node inliningTarget, @Cached BytesNodes.ToBytesNode toBytesNode, @Cached SysModuleBuiltins.AuditNode auditNode, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { // Unlike in other posix builtins, we go through str -> bytes -> byte[] -> String // conversions for emulated backend because the bytes version after fsencode conversion // is subject to sys.audit. byte[] name = toBytesNode.execute(nameBytes); byte[] value = toBytesNode.execute(valueBytes); - PosixSupport posixSupport = PosixSupport.get(inliningTarget); + PosixSupport posixSupport = context.getPosixSupport(); Object nameOpaque = checkNull(inliningTarget, posixLib.createPathFromBytes(posixSupport, name), raiseNode); Object valueOpaque = checkNull(inliningTarget, posixLib.createPathFromBytes(posixSupport, value), raiseNode); checkEqualSign(inliningTarget, name, raiseNode); @@ -466,17 +409,17 @@ static PNone putenv(VirtualFrame frame, PBytes nameBytes, PBytes valueBytes, return PNone.NONE; } - private static Object checkNull(Node inliningTarget, Object value, PRaiseNode.Lazy raiseNode) { + private static Object checkNull(Node inliningTarget, Object value, PRaiseNode raiseNode) { if (value == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.EMBEDDED_NULL_BYTE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.EMBEDDED_NULL_BYTE); } return value; } - private static void checkEqualSign(Node inliningTarget, byte[] bytes, PRaiseNode.Lazy raiseNode) { + private static void checkEqualSign(Node inliningTarget, byte[] bytes, PRaiseNode raiseNode) { for (byte b : bytes) { if (b == '=') { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.ILLEGAL_ENVIRONMENT_VARIABLE_NAME); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.ILLEGAL_ENVIRONMENT_VARIABLE_NAME); } } } @@ -493,27 +436,28 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone putenv(VirtualFrame frame, PBytes nameBytes, + static PNone putenv(VirtualFrame frame, PBytes nameBytes, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached BytesNodes.ToBytesNode toBytesNode, @Cached SysModuleBuiltins.AuditNode auditNode, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { byte[] name = toBytesNode.execute(nameBytes); - Object nameOpaque = checkNull(inliningTarget, posixLib.createPathFromBytes(getPosixSupport(), name), raiseNode); + Object nameOpaque = checkNull(inliningTarget, posixLib.createPathFromBytes(context.getPosixSupport(), name), raiseNode); auditNode.audit(inliningTarget, "os.unsetenv", nameBytes); try { - posixLib.unsetenv(getPosixSupport(), nameOpaque); + posixLib.unsetenv(context.getPosixSupport(), nameOpaque); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } return PNone.NONE; } - private static Object checkNull(Node inliningTarget, Object value, PRaiseNode.Lazy raiseNode) { + private static Object checkNull(Node inliningTarget, Object value, PRaiseNode raiseNode) { if (value == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.EMBEDDED_NULL_BYTE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.EMBEDDED_NULL_BYTE); } return value; } @@ -532,50 +476,53 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static Object execvArgsList(VirtualFrame frame, PosixPath path, PList argv, @Bind("this") Node inliningTarget, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached ToArrayNode toArrayNode, @Shared @Cached ObjectToOpaquePathNode toOpaquePathNode, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, @Shared @Cached GilNode gil, @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - execv(frame, path, argv, argv.getSequenceStorage(), inliningTarget, posixLib, toArrayNode, toOpaquePathNode, auditNode, gil, constructAndRaiseNode, raiseNode); + @Shared @Cached PRaiseNode raiseNode) { + execv(frame, path, argv, argv.getSequenceStorage(), inliningTarget, posixLib, context.getPosixSupport(), toArrayNode, toOpaquePathNode, auditNode, gil, constructAndRaiseNode, raiseNode); throw CompilerDirectives.shouldNotReachHere("execv should not return normally"); } @Specialization static Object execvArgsTuple(VirtualFrame frame, PosixPath path, PTuple argv, @Bind("this") Node inliningTarget, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached ToArrayNode toArrayNode, @Shared @Cached ObjectToOpaquePathNode toOpaquePathNode, @Shared @Cached AuditNode auditNode, @Shared @Cached GilNode gil, @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - execv(frame, path, argv, argv.getSequenceStorage(), inliningTarget, posixLib, toArrayNode, toOpaquePathNode, auditNode, gil, constructAndRaiseNode, raiseNode); + @Shared @Cached PRaiseNode raiseNode) { + execv(frame, path, argv, argv.getSequenceStorage(), inliningTarget, posixLib, context.getPosixSupport(), toArrayNode, toOpaquePathNode, auditNode, gil, constructAndRaiseNode, raiseNode); throw CompilerDirectives.shouldNotReachHere("execv should not return normally"); } @Specialization(guards = {"!isList(argv)", "!isPTuple(argv)"}) @SuppressWarnings("unused") static Object execvInvalidArgs(VirtualFrame frame, PosixPath path, Object argv, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.ARG_D_MUST_BE_S, "execv()", 2, "tuple or list"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.ARG_D_MUST_BE_S, "execv()", 2, "tuple or list"); } private static void execv(VirtualFrame frame, PosixPath path, Object argv, SequenceStorage argvStorage, Node inliningTarget, PosixSupportLibrary posixLib, + PosixSupport posixSupport, SequenceStorageNodes.ToArrayNode toArrayNode, ObjectToOpaquePathNode toOpaquePathNode, SysModuleBuiltins.AuditNode auditNode, GilNode gil, PConstructAndRaiseNode.Lazy constructAndRaiseNode, - PRaiseNode.Lazy raiseNode) { + PRaiseNode raiseNode) { Object[] args = toArrayNode.execute(inliningTarget, argvStorage); if (args.length < 1) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.ARG_MUST_NOT_BE_EMPTY, "execv()", 2); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.ARG_MUST_NOT_BE_EMPTY, "execv()", 2); } Object[] opaqueArgs = new Object[args.length]; for (int i = 0; i < args.length; ++i) { @@ -587,7 +534,7 @@ private static void execv(VirtualFrame frame, PosixPath path, Object argv, Seque gil.release(true); try { - posixLib.execv(PosixSupport.get(inliningTarget), path.value, opaqueArgs); + posixLib.execv(posixSupport, path.value, opaqueArgs); } catch (PosixException e) { gil.acquire(); throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); @@ -602,8 +549,9 @@ private static void execv(VirtualFrame frame, PosixPath path, Object argv, Seque @GenerateNodeFactory public abstract static class GetPidNode extends PythonBuiltinNode { @Specialization - long getPid(@CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { - return posixLib.getpid(getPosixSupport()); + static long getPid(@Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.getpid(context.getPosixSupport()); } } @@ -611,8 +559,9 @@ long getPid(@CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { @GenerateNodeFactory public abstract static class GetUidNode extends PythonBuiltinNode { @Specialization - long getUid(@CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { - return posixLib.getuid(getPosixSupport()); + static long getUid(@Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.getuid(context.getPosixSupport()); } } @@ -620,8 +569,9 @@ long getUid(@CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { @GenerateNodeFactory public abstract static class GetEUidNode extends PythonBuiltinNode { @Specialization - long getUid(@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib) { - return posixLib.geteuid(getPosixSupport()); + static long getUid(@Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.geteuid(context.getPosixSupport()); } } @@ -629,8 +579,9 @@ long getUid(@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib) { @GenerateNodeFactory public abstract static class GetGidNode extends PythonBuiltinNode { @Specialization - long getGid(@CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { - return posixLib.getgid(getPosixSupport()); + static long getGid(@Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.getgid(context.getPosixSupport()); } } @@ -638,8 +589,9 @@ long getGid(@CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { @GenerateNodeFactory public abstract static class GetEGidNode extends PythonBuiltinNode { @Specialization - long getGid(@CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { - return posixLib.getegid(getPosixSupport()); + static long getGid(@Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.getegid(context.getPosixSupport()); } } @@ -647,8 +599,9 @@ long getGid(@CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { @GenerateNodeFactory public abstract static class GetPpidNode extends PythonBuiltinNode { @Specialization - long getPpid(@CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { - return posixLib.getppid(getPosixSupport()); + static long getPpid(@Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.getppid(context.getPosixSupport()); } } @@ -665,17 +618,17 @@ public abstract static class GetLoadAvgNode extends PythonBuiltinNode { */ @TruffleBoundary @Specialization - PTuple getloadavg(@Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory) { + static PTuple getloadavg(@Bind("this") Node inliningTarget, + @Bind PythonLanguage language) { double load = -1.0; // (mq) without native call we can only obtain system load average for the last minute. if (ManagementFactory.getOperatingSystemMXBean() != null) { load = ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage(); } if (load < 0) { - PRaiseNode.raiseUncached(inliningTarget, OSError); + PRaiseNode.raiseStatic(inliningTarget, OSError); } - return factory.createTuple(new Object[]{load, load, load}); + return PFactory.createTuple(language, new Object[]{load, load, load}); } } @@ -689,12 +642,13 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - long getPgid(VirtualFrame frame, long pid, + static long getPgid(VirtualFrame frame, long pid, @Bind("this") Node inliningTarget, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - return posixLib.getpgid(getPosixSupport(), pid); + return posixLib.getpgid(context.getPosixSupport(), pid); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -712,12 +666,13 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - Object setPgid(VirtualFrame frame, long pid, long pgid, + static Object setPgid(VirtualFrame frame, long pid, long pgid, @Bind("this") Node inliningTarget, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - posixLib.setpgid(getPosixSupport(), pid, pgid); + posixLib.setpgid(context.getPosixSupport(), pid, pgid); return PNone.NONE; } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); @@ -729,12 +684,13 @@ Object setPgid(VirtualFrame frame, long pid, long pgid, @GenerateNodeFactory public abstract static class SetPgrpdNode extends PythonBuiltinNode { @Specialization - Object getPpid(VirtualFrame frame, + static Object getPpid(VirtualFrame frame, @Bind("this") Node inliningTarget, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - posixLib.setpgid(getPosixSupport(), 0, 0); + posixLib.setpgid(context.getPosixSupport(), 0, 0); return PNone.NONE; } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); @@ -746,8 +702,9 @@ Object getPpid(VirtualFrame frame, @GenerateNodeFactory public abstract static class GetPgrpNode extends PythonBuiltinNode { @Specialization - long getPpid(@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib) { - return posixLib.getpgrp(getPosixSupport()); + static long getPpid(@Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.getpgrp(context.getPosixSupport()); } } @@ -761,12 +718,13 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - long getSid(VirtualFrame frame, long pid, + static long getSid(VirtualFrame frame, long pid, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - return posixLib.getsid(getPosixSupport(), pid); + return posixLib.getsid(context.getPosixSupport(), pid); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -778,12 +736,13 @@ long getSid(VirtualFrame frame, long pid, public abstract static class SetSidNode extends PythonBuiltinNode { @Specialization - Object setsid(VirtualFrame frame, + static Object setsid(VirtualFrame frame, @Bind("this") Node inliningTarget, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - posixLib.setsid(getPosixSupport()); + posixLib.setsid(context.getPosixSupport()); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -795,14 +754,14 @@ Object setsid(VirtualFrame frame, @GenerateNodeFactory abstract static class GetGroupsNode extends PythonBuiltinNode { @Specialization - Object getgroups(VirtualFrame frame, + static Object getgroups(VirtualFrame frame, @Bind("this") Node inliningTarget, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - long[] groups = posixLib.getgroups(getPosixSupport()); - return factory.createList(new LongSequenceStorage(groups)); + long[] groups = posixLib.getgroups(context.getPosixSupport()); + return PFactory.createList(context.getLanguage(inliningTarget), new LongSequenceStorage(groups)); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -814,16 +773,16 @@ Object getgroups(VirtualFrame frame, public abstract static class OpenPtyNode extends PythonBuiltinNode { @Specialization - Object openpty(VirtualFrame frame, + static Object openpty(VirtualFrame frame, @Bind("this") Node inliningTarget, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - OpenPtyResult result = posixLib.openpty(getPosixSupport()); - posixLib.setInheritable(getPosixSupport(), result.masterFd(), false); - posixLib.setInheritable(getPosixSupport(), result.slaveFd(), false); - return factory.createTuple(new int[]{result.masterFd(), result.slaveFd()}); + OpenPtyResult result = posixLib.openpty(context.getPosixSupport()); + posixLib.setInheritable(context.getPosixSupport(), result.masterFd(), false); + posixLib.setInheritable(context.getPosixSupport(), result.slaveFd(), false); + return PFactory.createTuple(context.getLanguage(inliningTarget), new int[]{result.masterFd(), result.slaveFd()}); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -844,9 +803,10 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - int open(VirtualFrame frame, PosixPath path, int flags, int mode, int dirFd, + static int open(VirtualFrame frame, PosixPath path, int flags, int mode, int dirFd, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached SysModuleBuiltins.AuditNode auditNode, @Cached InlinedBranchProfile errorProfile, @Cached GilNode gil, @@ -860,11 +820,11 @@ int open(VirtualFrame frame, PosixPath path, int flags, int mode, int dirFd, try { while (true) { try { - return posixLib.openat(getPosixSupport(), dirFd, path.value, fixedFlags, mode); + return posixLib.openat(context.getPosixSupport(), dirFd, path.value, fixedFlags, mode); } catch (PosixException e) { errorProfile.enter(inliningTarget); if (e.getErrorCode() == OSErrorEnum.EINTR.getNumber()) { - PythonContext.triggerAsyncActions(this); + PythonContext.triggerAsyncActions(inliningTarget); } else { gil.acquire(); // need GIL to construct OSError throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject); @@ -888,19 +848,19 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone close(VirtualFrame frame, int fd, + static PNone close(VirtualFrame frame, int fd, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached GilNode gil, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - PythonContext ctx = getContext(); - if (ctx.getSharedMultiprocessingData().decrementFDRefCount(fd)) { + if (context.getSharedMultiprocessingData().decrementFDRefCount(fd)) { return PNone.NONE; } gil.release(true); try { - posixLib.close(getPosixSupport(), fd); + posixLib.close(context.getPosixSupport(), fd); } finally { gil.acquire(); } @@ -923,45 +883,46 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PBytes doRead(VirtualFrame frame, int fd, int length, + static PBytes doRead(VirtualFrame frame, int fd, int length, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached InlinedBranchProfile errorProfile1, @Cached InlinedBranchProfile errorProfile2, @Cached GilNode gil, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { if (length < 0) { int error = OSErrorEnum.EINVAL.getNumber(); - throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, error, posixLib.strerror(getPosixSupport(), error)); + throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, error, posixLib.strerror(context.getPosixSupport(), error)); } try { - return read(fd, length, inliningTarget, posixLib, errorProfile1, gil, factory); + return read(fd, length, inliningTarget, posixLib, context.getPosixSupport(), errorProfile1, gil); } catch (PosixException e) { errorProfile2.enter(inliningTarget); throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } } - public PBytes read(int fd, int length, + public static PBytes read(int fd, int length, Node inliningTarget, PosixSupportLibrary posixLib, - InlinedBranchProfile errorProfile, GilNode gil, PythonObjectFactory factory) throws PosixException { + PosixSupport posixSupport, + InlinedBranchProfile errorProfile, GilNode gil) throws PosixException { gil.release(true); try { while (true) { try { - Buffer result = posixLib.read(getPosixSupport(), fd, length); + Buffer result = posixLib.read(posixSupport, fd, length); if (result.length > Integer.MAX_VALUE) { // sanity check that it is safe to cast result.length to int, to be // removed once we support large arrays throw CompilerDirectives.shouldNotReachHere("Posix read() returned more bytes than requested"); } - return factory.createBytes(result.data, 0, (int) result.length); + return PFactory.createBytes(PythonLanguage.get(inliningTarget), result.data, (int) result.length); } catch (PosixException e) { errorProfile.enter(inliningTarget); if (e.getErrorCode() == OSErrorEnum.EINTR.getNumber()) { - PythonContext.triggerAsyncActions(this); + PythonContext.triggerAsyncActions(inliningTarget); } else { throw e; } @@ -989,12 +950,13 @@ static long doWrite(VirtualFrame frame, int fd, Object dataBuffer, @Bind("this") Node inliningTarget, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("dataBuffer") PythonBufferAccessLibrary bufferLib, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached InlinedBranchProfile errorProfile, @Cached GilNode gil, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - return write(fd, bufferLib.getInternalOrCopiedByteArray(dataBuffer), bufferLib.getBufferLength(dataBuffer), inliningTarget, posixLib, errorProfile, gil); + return write(fd, bufferLib.getInternalOrCopiedByteArray(dataBuffer), bufferLib.getBufferLength(dataBuffer), inliningTarget, posixLib, context.getPosixSupport(), errorProfile, gil); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } finally { @@ -1003,13 +965,13 @@ static long doWrite(VirtualFrame frame, int fd, Object dataBuffer, } public static long write(int fd, byte[] dataBytes, - int dataLen, Node inliningTarget, PosixSupportLibrary posixLib, + int dataLen, Node inliningTarget, PosixSupportLibrary posixLib, PosixSupport posixSupport, InlinedBranchProfile errorProfile, GilNode gil) throws PosixException { gil.release(true); try { while (true) { try { - return posixLib.write(PosixSupport.get(inliningTarget), fd, new Buffer(dataBytes, dataLen)); + return posixLib.write(posixSupport, fd, new Buffer(dataBytes, dataLen)); } catch (PosixException e) { errorProfile.enter(inliningTarget); if (e.getErrorCode() == OSErrorEnum.EINTR.getNumber()) { @@ -1036,12 +998,13 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - int dup(VirtualFrame frame, int fd, + static int dup(VirtualFrame frame, int fd, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - return posixLib.dup(getPosixSupport(), fd); + return posixLib.dup(context.getPosixSupport(), fd); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -1061,19 +1024,20 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - int dup2(VirtualFrame frame, int fd, int fd2, boolean inheritable, + static int dup2(VirtualFrame frame, int fd, int fd2, boolean inheritable, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { if (fd < 0 || fd2 < 0) { // CPython does not set errno here and raises a 'random' OSError // (possibly with errno=0 Success) int error = OSErrorEnum.EINVAL.getNumber(); - throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, error, posixLib.strerror(getPosixSupport(), error)); + throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, error, posixLib.strerror(context.getPosixSupport(), error)); } try { - return posixLib.dup2(getPosixSupport(), fd, fd2, inheritable); + return posixLib.dup2(context.getPosixSupport(), fd, fd2, inheritable); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -1091,12 +1055,13 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - boolean getInheritable(VirtualFrame frame, int fd, + static boolean getInheritable(VirtualFrame frame, int fd, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - return posixLib.getInheritable(getPosixSupport(), fd); + return posixLib.getInheritable(context.getPosixSupport(), fd); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -1115,13 +1080,14 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone setInheritable(VirtualFrame frame, int fd, int inheritable, + static PNone setInheritable(VirtualFrame frame, int fd, int inheritable, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { // not sure why inheritable is not a boolean, but that is how they do it in CPython - posixLib.setInheritable(getPosixSupport(), fd, inheritable != 0); + posixLib.setInheritable(context.getPosixSupport(), fd, inheritable != 0); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -1134,23 +1100,23 @@ PNone setInheritable(VirtualFrame frame, int fd, int inheritable, abstract static class PipeNode extends PythonBuiltinNode { @Specialization - PTuple pipe(VirtualFrame frame, + static PTuple pipe(VirtualFrame frame, @Bind("this") Node inliningTarget, @Cached GilNode gil, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { int[] pipe; gil.release(true); try { - pipe = posixLib.pipe(getPosixSupport()); + pipe = posixLib.pipe(context.getPosixSupport()); } catch (PosixException e) { gil.acquire(); // need to acquire the gil to construct the OSError object throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } finally { gil.acquire(); } - return factory.createTuple(new Object[]{pipe[0], pipe[1]}); + return PFactory.createTuple(context.getLanguage(inliningTarget), new Object[]{pipe[0], pipe[1]}); } } @@ -1181,12 +1147,13 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - long lseek(VirtualFrame frame, int fd, long pos, int how, + static long lseek(VirtualFrame frame, int fd, long pos, int how, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - return posixLib.lseek(getPosixSupport(), fd, pos, mapPythonSeekWhenceToPosix(how)); + return posixLib.lseek(context.getPosixSupport(), fd, pos, mapPythonSeekWhenceToPosix(how)); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -1207,8 +1174,8 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static PNone ftruncate(VirtualFrame frame, int fd, long length, @Bind("this") Node inliningTarget, - @Bind("getPosixSupport()") PosixSupport posixSupport, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached SysModuleBuiltins.AuditNode auditNode, @Cached GilNode gil, @Cached InlinedBranchProfile errorProfile, @@ -1218,7 +1185,7 @@ static PNone ftruncate(VirtualFrame frame, int fd, long length, try { gil.release(true); try { - posixLib.ftruncate(posixSupport, fd, length); + posixLib.ftruncate(context.getPosixSupport(), fd, length); } finally { gil.acquire(); } @@ -1249,8 +1216,8 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static PNone truncate(VirtualFrame frame, PosixPath path, long length, @Bind("this") Node inliningTarget, - @Bind("getPosixSupport()") PosixSupport posixSupport, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, @Shared @Cached GilNode gil, @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { @@ -1258,7 +1225,7 @@ static PNone truncate(VirtualFrame frame, PosixPath path, long length, try { gil.release(true); try { - posixLib.truncate(posixSupport, path.value, length); + posixLib.truncate(context.getPosixSupport(), path.value, length); } finally { gil.acquire(); } @@ -1271,13 +1238,13 @@ static PNone truncate(VirtualFrame frame, PosixPath path, long length, @Specialization static PNone ftruncate(VirtualFrame frame, PosixFd fd, long length, @Bind("this") Node inliningTarget, - @Bind("getPosixSupport()") PosixSupport posixSupport, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, @Shared @Cached GilNode gil, @Cached InlinedBranchProfile errorProfile, @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { - return FtruncateNode.ftruncate(frame, fd.fd, length, inliningTarget, posixSupport, posixLib, auditNode, gil, errorProfile, constructAndRaiseNode); + return FtruncateNode.ftruncate(frame, fd.fd, length, inliningTarget, context, posixLib, auditNode, gil, errorProfile, constructAndRaiseNode); } } @@ -1292,19 +1259,20 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone fsync(VirtualFrame frame, int fd, + static PNone fsync(VirtualFrame frame, int fd, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached InlinedBranchProfile errorProfile, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { while (true) { try { - posixLib.fsync(getPosixSupport(), fd); + posixLib.fsync(context.getPosixSupport(), fd); return PNone.NONE; } catch (PosixException e) { errorProfile.enter(inliningTarget); if (e.getErrorCode() == OSErrorEnum.EINTR.getNumber()) { - PythonContext.triggerAsyncActions(this); + PythonContext.triggerAsyncActions(inliningTarget); } else { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -1324,12 +1292,13 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - boolean getBlocking(VirtualFrame frame, int fd, + static boolean getBlocking(VirtualFrame frame, int fd, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - return posixLib.getBlocking(getPosixSupport(), fd); + return posixLib.getBlocking(context.getPosixSupport(), fd); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -1348,12 +1317,13 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone setBlocking(VirtualFrame frame, int fd, boolean blocking, + static PNone setBlocking(VirtualFrame frame, int fd, boolean blocking, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - posixLib.setBlocking(getPosixSupport(), fd, blocking); + posixLib.setBlocking(context.getPosixSupport(), fd, blocking); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -1372,15 +1342,15 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PTuple getTerminalSize(VirtualFrame frame, int fd, + static PTuple getTerminalSize(VirtualFrame frame, int fd, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { // TODO default value should be fileno(stdout) try { - int[] result = posixLib.getTerminalSize(getPosixSupport(), fd); - return factory.createStructSeq(TERMINAL_SIZE_DESC, result[0], result[1]); + int[] result = posixLib.getTerminalSize(context.getPosixSupport(), fd); + return PFactory.createStructSeq(context.getLanguage(inliningTarget), TERMINAL_SIZE_DESC, result[0], result[1]); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -1400,15 +1370,15 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PTuple doStatPath(VirtualFrame frame, PosixPath path, int dirFd, boolean followSymlinks, + static PTuple doStatPath(VirtualFrame frame, PosixPath path, int dirFd, boolean followSymlinks, @Bind("this") Node inliningTarget, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared("positive") @Cached InlinedConditionProfile positiveLongProfile, - @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Shared @Cached PythonObjectFactory factory) { + @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - long[] out = posixLib.fstatat(getPosixSupport(), dirFd, path.value, followSymlinks); - return createStatResult(inliningTarget, factory, positiveLongProfile, out); + long[] out = posixLib.fstatat(context.getPosixSupport(), dirFd, path.value, followSymlinks); + return createStatResult(inliningTarget, context.getLanguage(inliningTarget), positiveLongProfile, out); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject); } @@ -1417,27 +1387,27 @@ PTuple doStatPath(VirtualFrame frame, PosixPath path, int dirFd, boolean followS @Specialization(guards = "!isDefault(dirFd)") @SuppressWarnings("unused") static PTuple doStatFdWithDirFd(PosixFd fd, int dirFd, boolean followSymlinks, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.CANT_SPECIFY_DIRFD_WITHOUT_PATH, "stat"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.CANT_SPECIFY_DIRFD_WITHOUT_PATH, "stat"); } @Specialization(guards = {"isDefault(dirFd)", "!followSymlinks"}) @SuppressWarnings("unused") static PTuple doStatFdWithFollowSymlinks(VirtualFrame frame, PosixFd fd, int dirFd, boolean followSymlinks, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.CANNOT_USE_FD_AND_FOLLOW_SYMLINKS_TOGETHER, "stat"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.CANNOT_USE_FD_AND_FOLLOW_SYMLINKS_TOGETHER, "stat"); } @Specialization(guards = {"isDefault(dirFd)", "followSymlinks"}) - PTuple doStatFd(VirtualFrame frame, PosixFd fd, @SuppressWarnings("unused") int dirFd, @SuppressWarnings("unused") boolean followSymlinks, + static PTuple doStatFd(VirtualFrame frame, PosixFd fd, @SuppressWarnings("unused") int dirFd, @SuppressWarnings("unused") boolean followSymlinks, @Bind("this") Node inliningTarget, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared("positive") @Cached InlinedConditionProfile positiveLongProfile, - @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Shared @Cached PythonObjectFactory factory) { + @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - long[] out = posixLib.fstat(getPosixSupport(), fd.fd); - return createStatResult(inliningTarget, factory, positiveLongProfile, out); + long[] out = posixLib.fstat(context.getPosixSupport(), fd.fd); + return createStatResult(inliningTarget, context.getLanguage(inliningTarget), positiveLongProfile, out); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, fd.originalObject); } @@ -1460,16 +1430,16 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PTuple doStatPath(VirtualFrame frame, PosixPath path, int dirFd, + static PTuple doStatPath(VirtualFrame frame, PosixPath path, int dirFd, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached InlinedConditionProfile positiveLongProfile, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { // TODO we used to return all zeros when the filename was equal to sys.executable - long[] out = posixLib.fstatat(getPosixSupport(), dirFd, path.value, false); - return createStatResult(inliningTarget, factory, positiveLongProfile, out); + long[] out = posixLib.fstatat(context.getPosixSupport(), dirFd, path.value, false); + return createStatResult(inliningTarget, context.getLanguage(inliningTarget), positiveLongProfile, out); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject); } @@ -1487,21 +1457,21 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PTuple doStatFd(VirtualFrame frame, int fd, + static PTuple doStatFd(VirtualFrame frame, int fd, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached InlinedConditionProfile positiveLongProfile, @Cached InlinedBranchProfile errorProfile, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { while (true) { try { - long[] out = posixLib.fstat(getPosixSupport(), fd); - return createStatResult(inliningTarget, factory, positiveLongProfile, out); + long[] out = posixLib.fstat(context.getPosixSupport(), fd); + return createStatResult(inliningTarget, context.getLanguage(inliningTarget), positiveLongProfile, out); } catch (PosixException e) { errorProfile.enter(inliningTarget); if (e.getErrorCode() == OSErrorEnum.EINTR.getNumber()) { - PythonContext.triggerAsyncActions(this); + PythonContext.triggerAsyncActions(inliningTarget); } else { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -1510,12 +1480,12 @@ PTuple doStatFd(VirtualFrame frame, int fd, } } - private static PTuple createStatvfsResult(Node inliningTarget, long[] out, InlinedConditionProfile positiveLongProfile, PythonObjectFactory factory) { + private static PTuple createStatvfsResult(Node inliningTarget, long[] out, InlinedConditionProfile positiveLongProfile, PythonLanguage language) { Object[] res = new Object[out.length]; for (int i = 0; i < out.length; i++) { - res[i] = PInt.createPythonIntFromUnsignedLong(inliningTarget, factory, positiveLongProfile, out[i]); + res[i] = PInt.createPythonIntFromUnsignedLong(inliningTarget, language, positiveLongProfile, out[i]); } - return factory.createStructSeq(STATVFS_RESULT_DESC, res); + return PFactory.createStructSeq(language, STATVFS_RESULT_DESC, res); } @Builtin(name = "statvfs", minNumOfPositionalArgs = 1, parameterNames = {"path"}) @@ -1529,24 +1499,24 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PTuple doStatvfs(VirtualFrame frame, PosixFileHandle posixFileHandle, + static PTuple doStatvfs(VirtualFrame frame, PosixFileHandle posixFileHandle, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached InlinedConditionProfile posixPathProfile, @Cached InlinedConditionProfile positiveLongProfile, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { long[] out; try { if (posixPathProfile.profile(inliningTarget, posixFileHandle instanceof PosixPath)) { - out = posixLib.statvfs(getPosixSupport(), ((PosixPath) posixFileHandle).value); + out = posixLib.statvfs(context.getPosixSupport(), ((PosixPath) posixFileHandle).value); } else { - out = posixLib.fstatvfs(getPosixSupport(), ((PosixFd) posixFileHandle).fd); + out = posixLib.fstatvfs(context.getPosixSupport(), ((PosixFd) posixFileHandle).fd); } } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, posixFileHandle.originalObject); } - return createStatvfsResult(inliningTarget, out, positiveLongProfile, factory); + return createStatvfsResult(inliningTarget, out, positiveLongProfile, context.getLanguage(inliningTarget)); } } @@ -1556,19 +1526,19 @@ PTuple doStatvfs(VirtualFrame frame, PosixFileHandle posixFileHandle, abstract static class FStatvfsNode extends PythonUnaryClinicBuiltinNode { @Specialization - PTuple doStatvfs(VirtualFrame frame, int fd, + static PTuple doStatvfs(VirtualFrame frame, int fd, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached InlinedConditionProfile positiveLongProfile, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { long[] out; try { - out = posixLib.fstatvfs(getPosixSupport(), fd); + out = posixLib.fstatvfs(context.getPosixSupport(), fd); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, fd); } - return createStatvfsResult(inliningTarget, out, positiveLongProfile, factory); + return createStatvfsResult(inliningTarget, out, positiveLongProfile, context.getLanguage(inliningTarget)); } @Override @@ -1583,20 +1553,20 @@ protected ArgumentClinicProvider getArgumentClinic() { abstract static class UnameNode extends PythonBuiltinNode { @Specialization - PTuple uname(VirtualFrame frame, + static PTuple uname(VirtualFrame frame, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - return factory.createStructSeq(UNAME_RESULT_DESC, posixLib.uname(getPosixSupport())); + return PFactory.createStructSeq(context.getLanguage(inliningTarget), UNAME_RESULT_DESC, posixLib.uname(context.getPosixSupport())); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } } } - @Builtin(name = "unlink", minNumOfPositionalArgs = 1, parameterNames = {"path"}, varArgsMarker = true, keywordOnlyNames = {"dir_fd"}) + @Builtin(name = "unlink", minNumOfPositionalArgs = 1, parameterNames = {"path"}, keywordOnlyNames = {"dir_fd"}) @ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"false", "false"}) @ArgumentClinic(name = "dir_fd", conversionClass = DirFdConversionNode.class) @GenerateNodeFactory @@ -1608,14 +1578,15 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone unlink(VirtualFrame frame, PosixPath path, int dirFd, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + static PNone unlink(VirtualFrame frame, PosixPath path, int dirFd, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Bind("this") Node inliningTarget, @Cached SysModuleBuiltins.AuditNode auditNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { auditNode.audit(inliningTarget, "os.remove", path.originalObject, dirFdForAudit(dirFd)); try { - posixLib.unlinkat(getPosixSupport(), dirFd, path.value, false); + posixLib.unlinkat(context.getPosixSupport(), dirFd, path.value, false); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject); } @@ -1623,7 +1594,7 @@ PNone unlink(VirtualFrame frame, PosixPath path, int dirFd, } } - @Builtin(name = "remove", minNumOfPositionalArgs = 1, parameterNames = {"path"}, varArgsMarker = true, keywordOnlyNames = {"dir_fd"}) + @Builtin(name = "remove", minNumOfPositionalArgs = 1, parameterNames = {"path"}, keywordOnlyNames = {"dir_fd"}) @ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"false", "false"}) @ArgumentClinic(name = "dir_fd", conversionClass = DirFdConversionNode.class) @GenerateNodeFactory @@ -1653,12 +1624,13 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone link(VirtualFrame frame, PosixPath src, PosixPath dst, int srcDirFd, int dstDirFd, boolean followSymlinks, + static PNone link(VirtualFrame frame, PosixPath src, PosixPath dst, int srcDirFd, int dstDirFd, boolean followSymlinks, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - posixLib.linkat(getPosixSupport(), srcDirFd, src.value, dstDirFd, dst.value, followSymlinks ? AT_SYMLINK_FOLLOW.value : 0); + posixLib.linkat(context.getPosixSupport(), srcDirFd, src.value, dstDirFd, dst.value, followSymlinks ? AT_SYMLINK_FOLLOW.value : 0); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, src.originalObject, dst.originalObject); } @@ -1680,12 +1652,13 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone symlink(VirtualFrame frame, PosixPath src, PosixPath dst, @SuppressWarnings("unused") boolean targetIsDir, int dirFd, + static PNone symlink(VirtualFrame frame, PosixPath src, PosixPath dst, @SuppressWarnings("unused") boolean targetIsDir, int dirFd, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - posixLib.symlinkat(getPosixSupport(), src.value, dirFd, dst.value); + posixLib.symlinkat(context.getPosixSupport(), src.value, dirFd, dst.value); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, src.originalObject, dst.originalObject); } @@ -1706,14 +1679,15 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone mkdir(VirtualFrame frame, PosixPath path, int mode, int dirFd, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + static PNone mkdir(VirtualFrame frame, PosixPath path, int mode, int dirFd, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Bind("this") Node inliningTarget, @Cached SysModuleBuiltins.AuditNode auditNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { auditNode.audit(inliningTarget, "os.mkdir", path.originalObject, mode, dirFdForAudit(dirFd)); try { - posixLib.mkdirat(getPosixSupport(), dirFd, path.value, mode); + posixLib.mkdirat(context.getPosixSupport(), dirFd, path.value, mode); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject); } @@ -1733,14 +1707,15 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone rmdir(VirtualFrame frame, PosixPath path, int dirFd, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + static PNone rmdir(VirtualFrame frame, PosixPath path, int dirFd, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Bind("this") Node inliningTarget, @Cached SysModuleBuiltins.AuditNode auditNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { auditNode.audit(inliningTarget, "os.rmdir", path.originalObject, dirFdForAudit(dirFd)); try { - posixLib.unlinkat(getPosixSupport(), dirFd, path.value, true); + posixLib.unlinkat(context.getPosixSupport(), dirFd, path.value, true); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject); } @@ -1752,12 +1727,13 @@ PNone rmdir(VirtualFrame frame, PosixPath path, int dirFd, @GenerateNodeFactory abstract static class GetcwdNode extends PythonBuiltinNode { @Specialization - TruffleString getcwd(VirtualFrame frame, + static TruffleString getcwd(VirtualFrame frame, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - return posixLib.getPathAsString(getPosixSupport(), posixLib.getcwd(getPosixSupport())); + return posixLib.getPathAsString(context.getPosixSupport(), posixLib.getcwd(context.getPosixSupport())); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -1768,13 +1744,14 @@ TruffleString getcwd(VirtualFrame frame, @GenerateNodeFactory abstract static class GetcwdbNode extends PythonBuiltinNode { @Specialization - PBytes getcwdb(VirtualFrame frame, + static PBytes getcwdb(VirtualFrame frame, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - return opaquePathToBytes(posixLib.getcwd(getPosixSupport()), posixLib, getPosixSupport(), factory); + Object path = posixLib.getcwd(context.getPosixSupport()); + return opaquePathToBytes(path, posixLib, context.getPosixSupport(), context.getLanguage(inliningTarget)); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -1792,12 +1769,13 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone chdirPath(VirtualFrame frame, PosixPath path, + static PNone chdirPath(VirtualFrame frame, PosixPath path, @Bind("this") Node inliningTarget, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - posixLib.chdir(getPosixSupport(), path.value); + posixLib.chdir(context.getPosixSupport(), path.value); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject); } @@ -1805,12 +1783,13 @@ PNone chdirPath(VirtualFrame frame, PosixPath path, } @Specialization - PNone chdirFd(VirtualFrame frame, PosixFd fd, + static PNone chdirFd(VirtualFrame frame, PosixFd fd, @Bind("this") Node inliningTarget, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - posixLib.fchdir(getPosixSupport(), fd.fd); + posixLib.fchdir(context.getPosixSupport(), fd.fd); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, fd.originalObject); } @@ -1829,19 +1808,20 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone fchdir(VirtualFrame frame, int fd, + static PNone fchdir(VirtualFrame frame, int fd, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached InlinedBranchProfile errorProfile, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { while (true) { try { - posixLib.fchdir(getPosixSupport(), fd); + posixLib.fchdir(context.getPosixSupport(), fd); return PNone.NONE; } catch (PosixException e) { errorProfile.enter(inliningTarget); if (e.getErrorCode() == OSErrorEnum.EINTR.getNumber()) { - PythonContext.triggerAsyncActions(this); + PythonContext.triggerAsyncActions(inliningTarget); } else { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -1861,40 +1841,19 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - boolean isatty(int fd, + static boolean isatty(int fd, @Cached GilNode gil, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { gil.release(true); try { - return posixLib.isatty(getPosixSupport(), fd); + return posixLib.isatty(context.getPosixSupport(), fd); } finally { gil.acquire(); } } } - @Builtin(name = "ScandirIterator", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PScandirIterator, isPublic = false) - @GenerateNodeFactory - abstract static class ScandirIteratorNode extends PythonBuiltinNode { - @Specialization - @SuppressWarnings("unused") - static Object scandirIterator(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "posix.ScandirIterator"); - } - } - - @Builtin(name = "DirEntry", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PDirEntry, isPublic = true) - @GenerateNodeFactory - abstract static class DirEntryNode extends PythonBuiltinNode { - @Specialization - @SuppressWarnings("unused") - static Object dirEntry(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "posix.DirEntry"); - } - } - @Builtin(name = "scandir", minNumOfPositionalArgs = 0, parameterNames = {"path"}) @ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"true", "true"}) @GenerateNodeFactory @@ -1906,30 +1865,30 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PScandirIterator scandirPath(VirtualFrame frame, PosixPath path, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + static PScandirIterator scandirPath(VirtualFrame frame, PosixPath path, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Bind("this") Node inliningTarget, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, - @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Shared @Cached PythonObjectFactory factory) { + @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { auditNode.audit(inliningTarget, "os.scandir", path.originalObject == null ? PNone.NONE : path.originalObject); try { - return factory.createScandirIterator(getContext(), posixLib.opendir(getPosixSupport(), path.value), path, false); + return PFactory.createScandirIterator(context.getLanguage(inliningTarget), context, posixLib.opendir(context.getPosixSupport(), path.value), path, false); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject); } } @Specialization - PScandirIterator scandirFd(VirtualFrame frame, PosixFd fd, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + static PScandirIterator scandirFd(VirtualFrame frame, PosixFd fd, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Bind("this") Node inliningTarget, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, - @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Shared @Cached PythonObjectFactory factory) { + @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { auditNode.audit(inliningTarget, "os.scandir", fd.originalObject); - Object dirStream = dupAndFdopendir(frame, inliningTarget, posixLib, getPosixSupport(), fd, constructAndRaiseNode); - return factory.createScandirIterator(getContext(), dirStream, fd, true); + Object dirStream = dupAndFdopendir(frame, inliningTarget, posixLib, context.getPosixSupport(), fd, constructAndRaiseNode); + return PFactory.createScandirIterator(context.getLanguage(inliningTarget), context, dirStream, fd, true); } } @@ -1944,56 +1903,57 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PList listdirPath(VirtualFrame frame, PosixPath path, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + static PList listdirPath(VirtualFrame frame, PosixPath path, @Bind("this") Node inliningTarget, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, - @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Shared @Cached PythonObjectFactory factory) { + @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { auditNode.audit(inliningTarget, "os.listdir", path.originalObject == null ? PNone.NONE : path.originalObject); try { - return listdir(frame, inliningTarget, posixLib.opendir(getPosixSupport(), path.value), path.wasBufferLike, false, posixLib, constructAndRaiseNode, factory); + return listdir(frame, inliningTarget, posixLib.opendir(context.getPosixSupport(), path.value), path.wasBufferLike, false, posixLib, constructAndRaiseNode, + context.getLanguage(inliningTarget), context.getPosixSupport()); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject); } } @Specialization - PList listdirFd(VirtualFrame frame, PosixFd fd, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + static PList listdirFd(VirtualFrame frame, PosixFd fd, @Bind("this") Node inliningTarget, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, - @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Shared @Cached PythonObjectFactory factory) { + @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { auditNode.audit(inliningTarget, "os.listdir", fd.originalObject); - Object dirStream = dupAndFdopendir(frame, inliningTarget, posixLib, getPosixSupport(), fd, constructAndRaiseNode); - return listdir(frame, inliningTarget, dirStream, false, true, posixLib, constructAndRaiseNode, factory); + Object dirStream = dupAndFdopendir(frame, inliningTarget, posixLib, context.getPosixSupport(), fd, constructAndRaiseNode); + return listdir(frame, inliningTarget, dirStream, false, true, posixLib, constructAndRaiseNode, context.getLanguage(inliningTarget), context.getPosixSupport()); } - private PList listdir(VirtualFrame frame, Node inliningTarget, Object dirStream, boolean produceBytes, boolean needsRewind, PosixSupportLibrary posixLib, - PConstructAndRaiseNode.Lazy constructAndRaiseNode, PythonObjectFactory factory) { + private static PList listdir(VirtualFrame frame, Node inliningTarget, Object dirStream, boolean produceBytes, boolean needsRewind, PosixSupportLibrary posixLib, + PConstructAndRaiseNode.Lazy constructAndRaiseNode, PythonLanguage language, PosixSupport posixSupport) { List list = new ArrayList<>(); try { while (true) { - Object dirEntry = posixLib.readdir(getPosixSupport(), dirStream); + Object dirEntry = posixLib.readdir(posixSupport, dirStream); if (dirEntry == null) { - return factory.createList(listToArray(list)); + return PFactory.createList(language, listToArray(list)); } - Object name = posixLib.dirEntryGetName(getPosixSupport(), dirEntry); + Object name = posixLib.dirEntryGetName(posixSupport, dirEntry); if (produceBytes) { - addToList(list, opaquePathToBytes(name, posixLib, getPosixSupport(), factory)); + addToList(list, opaquePathToBytes(name, posixLib, posixSupport, language)); } else { - addToList(list, posixLib.getPathAsString(getPosixSupport(), name)); + addToList(list, posixLib.getPathAsString(posixSupport, name)); } } } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } finally { if (needsRewind) { - posixLib.rewinddir(getPosixSupport(), dirStream); + posixLib.rewinddir(posixSupport, dirStream); } try { - posixLib.closedir(getPosixSupport(), dirStream); + posixLib.closedir(posixSupport, dirStream); } catch (PosixException e) { // ignored (CPython does not check the return value of closedir) } @@ -2051,7 +2011,7 @@ static long[] times(VirtualFrame frame, PTuple times, @SuppressWarnings("unused" @Exclusive @Cached LenNode lenNode, @Shared @Cached("createNotNormalized()") GetItemNode getItemNode, @Cached ObjectToTimespecNode objectToTimespecNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { return convertToTimespec(frame, inliningTarget, times, lenNode, getItemNode, objectToTimespecNode, raiseNode); } @@ -2061,42 +2021,43 @@ static long[] ns(VirtualFrame frame, @SuppressWarnings("unused") PNone times, PT @Exclusive @Cached LenNode lenNode, @Shared @Cached("createNotNormalized()") GetItemNode getItemNode, @Cached SplitLongToSAndNsNode splitLongToSAndNsNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { return convertToTimespec(frame, inliningTarget, ns, lenNode, getItemNode, splitLongToSAndNsNode, raiseNode); } @Specialization(guards = {"!isPNone(times)", "!isNoValue(ns)"}) @SuppressWarnings("unused") static long[] bothSpecified(VirtualFrame frame, Object times, Object ns, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.YOU_MAY_SPECIFY_EITHER_OR_BUT_NOT_BOTH, "utime", "times", "ns"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.YOU_MAY_SPECIFY_EITHER_OR_BUT_NOT_BOTH, "utime", "times", "ns"); } @Specialization(guards = {"!isPNone(times)", "!isPTuple(times)", "isNoValue(ns)"}) @SuppressWarnings("unused") static long[] timesNotATuple(VirtualFrame frame, Object times, PNone ns, - @Shared @Cached PRaiseNode raiseNode) { - throw timesTupleError(raiseNode); + @Bind("this") Node inliningTarget, + @Cached PRaiseNode raiseNode) { + throw timesTupleError(inliningTarget, raiseNode); } @Specialization(guards = {"!isNoValue(ns)", "!isPTuple(ns)"}) @SuppressWarnings("unused") static long[] nsNotATuple(VirtualFrame frame, PNone times, Object ns, - @Shared @Cached PRaiseNode raiseNode) { + @Bind("this") Node inliningTarget) { // ns can actually also contain objects implementing __divmod__, but CPython produces // this error message - throw raiseNode.raise(TypeError, ErrorMessages.MUST_BE, "utime", "ns", "a tuple of two ints"); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.MUST_BE, "utime", "ns", "a tuple of two ints"); } - private static PException timesTupleError(PRaiseNode raiseNode) { + private static PException timesTupleError(Node inliningTarget, PRaiseNode raiseNode) { // times can actually also contain floats, but CPython produces this error message - throw raiseNode.raise(TypeError, ErrorMessages.MUST_BE_EITHER_OR, "utime", "times", "a tuple of two ints", "None"); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_EITHER_OR, "utime", "times", "a tuple of two ints", "None"); } private static long[] convertToTimespec(VirtualFrame frame, Node inliningTarget, PTuple times, LenNode lenNode, GetItemNode getItemNode, ConvertToTimespecBaseNode convertToTimespecBaseNode, - PRaiseNode.Lazy raiseNode) { + PRaiseNode raiseNode) { if (lenNode.execute(inliningTarget, times) != 2) { - throw timesTupleError(raiseNode.get(inliningTarget)); + throw timesTupleError(inliningTarget, raiseNode); } long[] timespec = new long[4]; convertToTimespecBaseNode.execute(frame, inliningTarget, getItemNode.execute(times.getSequenceStorage(), 0), timespec, 0); @@ -2105,7 +2066,7 @@ private static long[] convertToTimespec(VirtualFrame frame, Node inliningTarget, } } - @Builtin(name = "utime", minNumOfPositionalArgs = 1, parameterNames = {"path", "times"}, varArgsMarker = true, keywordOnlyNames = {"ns", "dir_fd", "follow_symlinks"}) + @Builtin(name = "utime", minNumOfPositionalArgs = 1, parameterNames = {"path", "times"}, keywordOnlyNames = {"ns", "dir_fd", "follow_symlinks"}) @ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"false", "true"}) @ArgumentClinic(name = "dir_fd", conversionClass = DirFdConversionNode.class) @ArgumentClinic(name = "follow_symlinks", conversion = ClinicConversion.Boolean, defaultValue = "true") @@ -2127,12 +2088,13 @@ static PNone utimensat(VirtualFrame frame, PosixPath path, Object times, Object @Bind("this") Node inliningTarget, @Shared @Cached UtimeArgsToTimespecNode timespecNode, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { long[] timespec = timespecNode.execute(frame, times, ns); auditNode.audit(inliningTarget, "os.utime", path.originalObject, checkNone(times), checkNone(ns), dirFdForAudit(dirFd)); try { - posixLib.utimensat(PosixSupport.get(inliningTarget), dirFd, path.value, timespec, followSymlinks); + posixLib.utimensat(context.getPosixSupport(), dirFd, path.value, timespec, followSymlinks); } catch (PosixException e) { // filename is intentionally not included, see CPython's os_utime_impl throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); @@ -2145,12 +2107,13 @@ static PNone utimes(VirtualFrame frame, PosixPath path, Object times, Object ns, @Bind("this") Node inliningTarget, @Shared @Cached UtimeArgsToTimespecNode timespecNode, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { Timeval[] timeval = timespecNode.toTimeval(frame, times, ns); auditNode.audit(inliningTarget, "os.utime", path.originalObject, checkNone(times), checkNone(ns), dirFdForAudit(dirFd)); try { - posixLib.utimes(PosixSupport.get(inliningTarget), path.value, timeval); + posixLib.utimes(context.getPosixSupport(), path.value, timeval); } catch (PosixException e) { // filename is intentionally not included, see CPython's os_utime_impl throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); @@ -2163,12 +2126,13 @@ static PNone lutimes(VirtualFrame frame, PosixPath path, Object times, Object ns @Bind("this") Node inliningTarget, @Shared @Cached UtimeArgsToTimespecNode timespecNode, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { Timeval[] timeval = timespecNode.toTimeval(frame, times, ns); auditNode.audit(inliningTarget, "os.utime", path.originalObject, checkNone(times), checkNone(ns), dirFdForAudit(dirFd)); try { - posixLib.lutimes(PosixSupport.get(inliningTarget), path.value, timeval); + posixLib.lutimes(context.getPosixSupport(), path.value, timeval); } catch (PosixException e) { // filename is intentionally not included, see CPython's os_utime_impl throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); @@ -2179,15 +2143,15 @@ static PNone lutimes(VirtualFrame frame, PosixPath path, Object times, Object ns @Specialization(guards = {"!HAVE_UTIMENSAT.value", "!isDefault(dirFd)", "followSymlinks"}) @SuppressWarnings("unused") static PNone dirFdNotSupported(VirtualFrame frame, PosixPath path, Object times, Object ns, int dirFd, boolean followSymlinks, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(NotImplementedError, ErrorMessages.UNAVAILABLE_ON_THIS_PLATFORM_NO_FUNC, "dir_fd"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, ErrorMessages.UNAVAILABLE_ON_THIS_PLATFORM_NO_FUNC, "dir_fd"); } @Specialization(guards = {"!HAVE_UTIMENSAT.value", "!isDefault(dirFd)", "!followSymlinks"}) @SuppressWarnings("unused") static PNone dirFdAndFollowSymlinksNotSupported(VirtualFrame frame, PosixPath path, Object times, Object ns, int dirFd, boolean followSymlinks, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.UTIME_CANNOT_USE_DIR_FD_AND_FOLLOW_SYMLINKS, "dir_fd"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.UTIME_CANNOT_USE_DIR_FD_AND_FOLLOW_SYMLINKS, "dir_fd"); } @Specialization(guards = {"HAVE_FUTIMENS.value", "isDefault(dirFd)", "followSymlinks"}) @@ -2195,12 +2159,13 @@ static PNone futimens(VirtualFrame frame, PosixFd fd, Object times, Object ns, i @Bind("this") Node inliningTarget, @Shared @Cached UtimeArgsToTimespecNode timespecNode, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { long[] timespec = timespecNode.execute(frame, times, ns); auditNode.audit(inliningTarget, "os.utime", fd.originalObject, checkNone(times), checkNone(ns), dirFdForAudit(dirFd)); try { - posixLib.futimens(PosixSupport.get(inliningTarget), fd.fd, timespec); + posixLib.futimens(context.getPosixSupport(), fd.fd, timespec); } catch (PosixException e) { // filename is intentionally not included, see CPython's os_utime_impl throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); @@ -2213,12 +2178,13 @@ static PNone futimes(VirtualFrame frame, PosixFd fd, Object times, Object ns, in @Bind("this") Node inliningTarget, @Shared @Cached UtimeArgsToTimespecNode timespecNode, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { Timeval[] timeval = timespecNode.toTimeval(frame, times, ns); auditNode.audit(inliningTarget, "os.utime", fd.originalObject, checkNone(times), checkNone(ns), dirFdForAudit(dirFd)); try { - posixLib.futimes(PosixSupport.get(inliningTarget), fd.fd, timeval); + posixLib.futimes(context.getPosixSupport(), fd.fd, timeval); } catch (PosixException e) { // filename is intentionally not included, see CPython's os_utime_impl throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); @@ -2229,15 +2195,15 @@ static PNone futimes(VirtualFrame frame, PosixFd fd, Object times, Object ns, in @Specialization(guards = {"isPNone(times) || isNoValue(ns)", "!isDefault(dirFd)"}) @SuppressWarnings("unused") static PNone fdWithDirFd(VirtualFrame frame, PosixFd fd, Object times, Object ns, int dirFd, boolean followSymlinks, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.CANT_SPECIFY_DIRFD_WITHOUT_PATH, "utime"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.CANT_SPECIFY_DIRFD_WITHOUT_PATH, "utime"); } @Specialization(guards = {"isPNone(times) || isNoValue(ns)", "isDefault(dirFd)", "!followSymlinks"}) @SuppressWarnings("unused") static PNone fdWithFollowSymlinks(VirtualFrame frame, PosixFd fd, Object times, Object ns, int dirFd, boolean followSymlinks, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.CANNOT_USE_FD_AND_FOLLOW_SYMLINKS_TOGETHER, "utime"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.CANNOT_USE_FD_AND_FOLLOW_SYMLINKS_TOGETHER, "utime"); } protected static boolean isDefault(int dirFd) { @@ -2245,7 +2211,7 @@ protected static boolean isDefault(int dirFd) { } } - @Builtin(name = "rename", minNumOfPositionalArgs = 2, parameterNames = {"src", "dst"}, varArgsMarker = true, keywordOnlyNames = {"src_dir_fd", "dst_dir_fd"}) + @Builtin(name = "rename", minNumOfPositionalArgs = 2, parameterNames = {"src", "dst"}, keywordOnlyNames = {"src_dir_fd", "dst_dir_fd"}) @ArgumentClinic(name = "src", conversionClass = PathConversionNode.class, args = {"false", "false"}) @ArgumentClinic(name = "dst", conversionClass = PathConversionNode.class, args = {"false", "false"}) @ArgumentClinic(name = "src_dir_fd", conversionClass = DirFdConversionNode.class) @@ -2259,14 +2225,15 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone rename(VirtualFrame frame, PosixPath src, PosixPath dst, int srcDirFd, int dstDirFd, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + static PNone rename(VirtualFrame frame, PosixPath src, PosixPath dst, int srcDirFd, int dstDirFd, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Bind("this") Node inliningTarget, @Cached SysModuleBuiltins.AuditNode auditNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { auditNode.audit(inliningTarget, "os.rename", src.originalObject, dst.originalObject, dirFdForAudit(srcDirFd), dirFdForAudit(dstDirFd)); try { - posixLib.renameat(getPosixSupport(), srcDirFd, src.value, dstDirFd, dst.value); + posixLib.renameat(context.getPosixSupport(), srcDirFd, src.value, dstDirFd, dst.value); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, src.originalObject, dst.originalObject); } @@ -2274,7 +2241,7 @@ PNone rename(VirtualFrame frame, PosixPath src, PosixPath dst, int srcDirFd, int } } - @Builtin(name = "replace", minNumOfPositionalArgs = 2, parameterNames = {"src", "dst"}, varArgsMarker = true, keywordOnlyNames = {"src_dir_fd", "dst_dir_fd"}) + @Builtin(name = "replace", minNumOfPositionalArgs = 2, parameterNames = {"src", "dst"}, keywordOnlyNames = {"src_dir_fd", "dst_dir_fd"}) @ArgumentClinic(name = "src", conversionClass = PathConversionNode.class, args = {"false", "false"}) @ArgumentClinic(name = "dst", conversionClass = PathConversionNode.class, args = {"false", "false"}) @ArgumentClinic(name = "src_dir_fd", conversionClass = DirFdConversionNode.class) @@ -2291,7 +2258,7 @@ protected ArgumentClinicProvider getArgumentClinic() { } } - @Builtin(name = "access", minNumOfPositionalArgs = 2, parameterNames = {"path", "mode"}, varArgsMarker = true, keywordOnlyNames = {"dir_fd", "effective_ids", "follow_symlinks"}) + @Builtin(name = "access", minNumOfPositionalArgs = 2, parameterNames = {"path", "mode"}, keywordOnlyNames = {"dir_fd", "effective_ids", "follow_symlinks"}) @ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"false", "false"}) @ArgumentClinic(name = "mode", conversion = ClinicConversion.Int) @ArgumentClinic(name = "dir_fd", conversionClass = DirFdConversionNode.class) @@ -2306,9 +2273,10 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - boolean access(PosixPath path, int mode, int dirFd, boolean effectiveIds, boolean followSymlinks, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { - return posixLib.faccessat(getPosixSupport(), dirFd, path.value, mode, effectiveIds, followSymlinks); + static boolean access(PosixPath path, int mode, int dirFd, boolean effectiveIds, boolean followSymlinks, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.faccessat(context.getPosixSupport(), dirFd, path.value, mode, effectiveIds, followSymlinks); } } @@ -2323,14 +2291,15 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone fchmod(VirtualFrame frame, int fd, int mode, + static PNone fchmod(VirtualFrame frame, int fd, int mode, @Bind("this") Node inliningTarget, @Cached SysModuleBuiltins.AuditNode auditNode, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { auditNode.audit(inliningTarget, "os.chmod", fd, mode, -1); try { - posixLib.fchmod(getPosixSupport(), fd, mode); + posixLib.fchmod(context.getPosixSupport(), fd, mode); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, fd); } @@ -2338,7 +2307,7 @@ PNone fchmod(VirtualFrame frame, int fd, int mode, } } - @Builtin(name = "chmod", minNumOfPositionalArgs = 2, parameterNames = {"path", "mode"}, varArgsMarker = true, keywordOnlyNames = {"dir_fd", "follow_symlinks"}) + @Builtin(name = "chmod", minNumOfPositionalArgs = 2, parameterNames = {"path", "mode"}, keywordOnlyNames = {"dir_fd", "follow_symlinks"}) @ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"false", "true"}) @ArgumentClinic(name = "mode", conversion = ClinicConversion.Int) @ArgumentClinic(name = "dir_fd", conversionClass = DirFdConversionNode.class) @@ -2355,19 +2324,20 @@ protected ArgumentClinicProvider getArgumentClinic() { static PNone chmodFollow(VirtualFrame frame, PosixPath path, int mode, int dirFd, boolean followSymlinks, @Bind("this") Node inliningTarget, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { auditNode.audit(inliningTarget, "os.chmod", path.originalObject, mode, dirFdForAudit(dirFd)); try { - posixLib.fchmodat(PosixSupport.get(inliningTarget), dirFd, path.value, mode, followSymlinks); + posixLib.fchmodat(context.getPosixSupport(), dirFd, path.value, mode, followSymlinks); } catch (PosixException e) { // TODO CPython checks for ENOTSUP as well if (e.getErrorCode() == OSErrorEnum.EOPNOTSUPP.getNumber() && !followSymlinks) { if (dirFd != AT_FDCWD.value) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.CANNOT_USE_FD_AND_FOLLOW_SYMLINKS_TOGETHER, "chmod"); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.CANNOT_USE_FD_AND_FOLLOW_SYMLINKS_TOGETHER, "chmod"); } else { - throw raiseNode.get(inliningTarget).raise(NotImplementedError, ErrorMessages.UNAVAILABLE_ON_THIS_PLATFORM, "chmod", "follow_symlinks"); + throw raiseNode.raise(inliningTarget, NotImplementedError, ErrorMessages.UNAVAILABLE_ON_THIS_PLATFORM, "chmod", "follow_symlinks"); } } throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject); @@ -2376,20 +2346,21 @@ static PNone chmodFollow(VirtualFrame frame, PosixPath path, int mode, int dirFd } @Specialization - PNone chmodFollow(VirtualFrame frame, PosixFd fd, int mode, int dirFd, @SuppressWarnings("unused") boolean followSymlinks, + static PNone chmodFollow(VirtualFrame frame, PosixFd fd, int mode, int dirFd, @SuppressWarnings("unused") boolean followSymlinks, @Bind("this") Node inliningTarget, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, // unused node to avoid mixing shared and non-shared inlined nodes - @SuppressWarnings("unused") @Shared @Cached PRaiseNode.Lazy raiseNode) { + @SuppressWarnings("unused") @Shared @Cached PRaiseNode raiseNode) { auditNode.audit(inliningTarget, "os.chmod", fd.originalObject, mode, dirFdForAudit(dirFd)); // Unlike stat and utime which raise CANT_SPECIFY_DIRFD_WITHOUT_PATH or // CANNOT_USE_FD_AND_FOLLOW_SYMLINKS_TOGETHER when an inappropriate combination of // arguments is used, CPython's implementation of chmod simply ignores dir_fd and // follow_symlinks if a fd is specified instead of a path. try { - posixLib.fchmod(getPosixSupport(), fd.fd, mode); + posixLib.fchmod(context.getPosixSupport(), fd.fd, mode); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, fd.originalObject); } @@ -2404,17 +2375,18 @@ PNone chmodFollow(VirtualFrame frame, PosixFd fd, int mode, int dirFd, @Suppress @GenerateNodeFactory abstract static class FChownNode extends PythonTernaryClinicBuiltinNode { @Specialization - Object chown(VirtualFrame frame, int fd, long uid, long gid, + static Object chown(VirtualFrame frame, int fd, long uid, long gid, @Bind("this") Node inliningTarget, @Cached SysModuleBuiltins.AuditNode auditNode, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached GilNode gil, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { auditNode.audit(inliningTarget, "os.chown", fd, uid, gid, -1); try { gil.release(true); try { - posixLib.fchown(getPosixSupport(), fd, uid, gid); + posixLib.fchown(context.getPosixSupport(), fd, uid, gid); } finally { gil.acquire(); } @@ -2437,17 +2409,18 @@ protected ArgumentClinicProvider getArgumentClinic() { @GenerateNodeFactory abstract static class LChownNode extends PythonTernaryClinicBuiltinNode { @Specialization - Object chown(VirtualFrame frame, PosixPath path, long uid, long gid, + static Object chown(VirtualFrame frame, PosixPath path, long uid, long gid, @Bind("this") Node inliningTarget, @Cached SysModuleBuiltins.AuditNode auditNode, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached GilNode gil, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { auditNode.audit(inliningTarget, "os.chown", path.originalObject, uid, gid, -1); try { gil.release(true); try { - posixLib.fchownat(getPosixSupport(), AT_FDCWD.value, path.value, uid, gid, false); + posixLib.fchownat(context.getPosixSupport(), AT_FDCWD.value, path.value, uid, gid, false); } finally { gil.acquire(); } @@ -2475,16 +2448,17 @@ abstract static class ChownNode extends PythonClinicBuiltinNode { static Object chown(VirtualFrame frame, PosixPath path, long uid, long gid, int dirFd, boolean followSymlinks, @Bind("this") Node inliningTarget, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached GilNode gil, @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, // unused node to avoid mixing shared and non-shared inlined nodes - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { auditNode.audit(inliningTarget, "os.chown", path.originalObject, uid, gid, dirFd != AT_FDCWD.value ? dirFd : -1); try { gil.release(true); try { - posixLib.fchownat(PosixSupport.get(inliningTarget), dirFd, path.value, uid, gid, followSymlinks); + posixLib.fchownat(context.getPosixSupport(), dirFd, path.value, uid, gid, followSymlinks); } finally { gil.acquire(); } @@ -2498,21 +2472,22 @@ static Object chown(VirtualFrame frame, PosixPath path, long uid, long gid, int static Object chown(VirtualFrame frame, PosixFd fd, long uid, long gid, int dirFd, boolean followSymlinks, @Bind("this") Node inliningTarget, @Shared @Cached SysModuleBuiltins.AuditNode auditNode, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Shared @Cached GilNode gil, @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { if (dirFd != AT_FDCWD.value) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.CANT_SPECIFY_BOTH_DIR_FD_AND_FD); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.CANT_SPECIFY_BOTH_DIR_FD_AND_FD); } if (followSymlinks) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.CANNOT_USE_FD_AND_FOLLOW_SYMLINKS_TOGETHER, "chown"); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.CANNOT_USE_FD_AND_FOLLOW_SYMLINKS_TOGETHER, "chown"); } auditNode.audit(inliningTarget, "os.chown", fd.originalObject, uid, gid, -1); try { gil.release(true); try { - posixLib.fchown(PosixSupport.get(inliningTarget), fd.fd, uid, gid); + posixLib.fchown(context.getPosixSupport(), fd.fd, uid, gid); } finally { gil.acquire(); } @@ -2528,7 +2503,7 @@ protected ArgumentClinicProvider getArgumentClinic() { } } - @Builtin(name = "readlink", minNumOfPositionalArgs = 1, parameterNames = {"path"}, varArgsMarker = true, keywordOnlyNames = {"dir_fd"}, doc = "readlink(path, *, dir_fd=None) -> path\n" + + @Builtin(name = "readlink", minNumOfPositionalArgs = 1, parameterNames = {"path"}, keywordOnlyNames = {"dir_fd"}, doc = "readlink(path, *, dir_fd=None) -> path\n" + "\nReturn a string representing the path to which the symbolic link points.\n") @ArgumentClinic(name = "path", conversionClass = PathConversionNode.class, args = {"false", "false"}) @ArgumentClinic(name = "dir_fd", conversionClass = DirFdConversionNode.class) @@ -2541,18 +2516,18 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - Object readlinkAsBytes(VirtualFrame frame, PosixPath path, int dirFd, + static Object readlinkAsBytes(VirtualFrame frame, PosixPath path, int dirFd, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached InlinedConditionProfile wasBufferLikeProfile, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - Object link = posixLib.readlinkat(getPosixSupport(), dirFd, path.value); + Object link = posixLib.readlinkat(context.getPosixSupport(), dirFd, path.value); if (wasBufferLikeProfile.profile(inliningTarget, path.wasBufferLike)) { - return opaquePathToBytes(link, posixLib, getPosixSupport(), factory); + return opaquePathToBytes(link, posixLib, context.getPosixSupport(), context.getLanguage(inliningTarget)); } else { - return posixLib.getPathAsString(getPosixSupport(), link); + return posixLib.getPathAsString(context.getPosixSupport(), link); } } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject); @@ -2571,16 +2546,17 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - TruffleString getStrError(int code, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { - return posixLib.strerror(getPosixSupport(), code); + static TruffleString getStrError(int code, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.strerror(context.getPosixSupport(), code); } } - @Builtin(name = "_exit", minNumOfPositionalArgs = 1) + @Builtin(name = "_exit", minNumOfPositionalArgs = 1, parameterNames = {"status"}) + @ArgumentClinic(name = "status", conversion = ClinicConversion.Int) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) - public abstract static class ExitNode extends PythonUnaryBuiltinNode { + public abstract static class ExitNode extends PythonUnaryClinicBuiltinNode { @TruffleBoundary @Specialization Object exit(int status) { @@ -2609,6 +2585,11 @@ protected void perform(Access access) { } throw new ThreadDeath(); } + + @Override + protected ArgumentClinicProvider getArgumentClinic() { + return PosixModuleBuiltinsClinicProviders.ExitNodeClinicProviderGen.INSTANCE; + } } @Builtin(name = "waitpid", minNumOfPositionalArgs = 2, parameterNames = {"pid", "options"}) @@ -2622,23 +2603,23 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PTuple waitpid(VirtualFrame frame, long pid, int options, + static PTuple waitpid(VirtualFrame frame, long pid, int options, @Bind("this") Node inliningTarget, @Cached GilNode gil, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached InlinedBranchProfile errorProfile, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { gil.release(true); try { while (true) { try { - long[] result = posixLib.waitpid(getPosixSupport(), pid, options); - return factory.createTuple(new Object[]{result[0], result[1]}); + long[] result = posixLib.waitpid(context.getPosixSupport(), pid, options); + return PFactory.createTuple(context.getLanguage(inliningTarget), new Object[]{result[0], result[1]}); } catch (PosixException e) { errorProfile.enter(inliningTarget); if (e.getErrorCode() == OSErrorEnum.EINTR.getNumber()) { - PythonContext.triggerAsyncActions(this); + PythonContext.triggerAsyncActions(inliningTarget); } else { gil.acquire(); throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); @@ -2658,31 +2639,32 @@ PTuple waitpid(VirtualFrame frame, long pid, int options, abstract static class WaitstatusToExitcodeNode extends PythonUnaryBuiltinNode { @Specialization static int waitstatusToExitcode(VirtualFrame frame, Object statusObj, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Bind("this") Node inliningTarget, @Cached PyLongAsIntNode longAsInt, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int status = longAsInt.execute(frame, inliningTarget, statusObj); - PosixSupport posixSupport = PosixSupport.get(inliningTarget); + PosixSupport posixSupport = context.getPosixSupport(); if (posixLib.wifexited(posixSupport, status)) { int exitcode = posixLib.wexitstatus(posixSupport, status); if (exitcode < 0) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.INVALID_WEXITSTATUS, exitcode); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.INVALID_WEXITSTATUS, exitcode); } return exitcode; } if (posixLib.wifsignaled(posixSupport, status)) { int signum = posixLib.wtermsig(posixSupport, status); if (signum <= 0) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.INVALID_WTERMSIG, signum); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.INVALID_WTERMSIG, signum); } return -signum; } if (posixLib.wifstopped(posixSupport, status)) { int signum = posixLib.wstopsig(posixSupport, status); - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.PROCESS_STOPPED_BY_DELIVERY_OF_SIGNAL, signum); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.PROCESS_STOPPED_BY_DELIVERY_OF_SIGNAL, signum); } - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.INVALID_WAIT_STATUS, status); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.INVALID_WAIT_STATUS, status); } } @@ -2696,9 +2678,10 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - boolean wcoredump(int status, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { - return posixLib.wcoredump(getPosixSupport(), status); + static boolean wcoredump(int status, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.wcoredump(context.getPosixSupport(), status); } } @@ -2712,9 +2695,10 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - boolean wifcontinued(int status, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { - return posixLib.wifcontinued(getPosixSupport(), status); + static boolean wifcontinued(int status, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.wifcontinued(context.getPosixSupport(), status); } } @@ -2728,9 +2712,10 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - boolean wifstopped(int status, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { - return posixLib.wifstopped(getPosixSupport(), status); + static boolean wifstopped(int status, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.wifstopped(context.getPosixSupport(), status); } } @@ -2744,9 +2729,10 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - boolean wifsignaled(int status, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { - return posixLib.wifsignaled(getPosixSupport(), status); + static boolean wifsignaled(int status, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.wifsignaled(context.getPosixSupport(), status); } } @@ -2760,9 +2746,10 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - boolean wifexited(int status, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { - return posixLib.wifexited(getPosixSupport(), status); + static boolean wifexited(int status, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.wifexited(context.getPosixSupport(), status); } } @@ -2776,9 +2763,10 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - int wexitstatus(int status, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { - return posixLib.wexitstatus(getPosixSupport(), status); + static int wexitstatus(int status, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.wexitstatus(context.getPosixSupport(), status); } } @@ -2793,8 +2781,9 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization int wtermsig(int status, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { - return posixLib.wtermsig(getPosixSupport(), status); + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.wtermsig(context.getPosixSupport(), status); } } @@ -2808,9 +2797,10 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - int wstopsig(int status, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib) { - return posixLib.wstopsig(getPosixSupport(), status); + static int wstopsig(int status, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) { + return posixLib.wstopsig(context.getPosixSupport(), status); } } @@ -2824,11 +2814,12 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - int system(PBytes command, + static int system(PBytes command, @Bind("this") Node inliningTarget, @Cached BytesNodes.ToBytesNode toBytesNode, @Cached SysModuleBuiltins.AuditNode auditNode, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached GilNode gil) { // Unlike in other posix builtins, we go through str -> bytes -> byte[] -> String // conversions for emulated backend because the bytes version after fsencode conversion @@ -2837,8 +2828,8 @@ int system(PBytes command, byte[] bytes = toBytesNode.execute(command); gil.release(true); try { - Object cmdOpaque = posixLib.createPathFromBytes(getPosixSupport(), bytes); - return posixLib.system(getPosixSupport(), cmdOpaque); + Object cmdOpaque = posixLib.createPathFromBytes(context.getPosixSupport(), bytes); + return posixLib.system(context.getPosixSupport(), cmdOpaque); } finally { gil.acquire(); } @@ -2848,20 +2839,20 @@ int system(PBytes command, @Builtin(name = "urandom", minNumOfPositionalArgs = 1, numOfPositionalOnlyArgs = 1, parameterNames = {"size"}) @ArgumentClinic(name = "size", conversion = ClinicConversion.Index) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class URandomNode extends PythonUnaryClinicBuiltinNode { @Specialization(guards = "size >= 0") - PBytes urandom(int size, - @Cached PythonObjectFactory factory) { + static PBytes urandom(int size, + @Bind("this") Node inliningTarget, + @Bind PythonContext context) { byte[] bytes = new byte[size]; - nextBytes(getContext().getSecureRandom(), bytes); - return factory.createBytes(bytes); + nextBytes(context.getSecureRandom(), bytes); + return PFactory.createBytes(context.getLanguage(inliningTarget), bytes); } @Specialization(guards = "size < 0") static Object urandomNeg(@SuppressWarnings("unused") int size, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.NEG_ARG_NOT_ALLOWED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.NEG_ARG_NOT_ALLOWED); } @TruffleBoundary @@ -2885,50 +2876,43 @@ static int getCpuCount() { } } - @Builtin(name = "sysconf", minNumOfPositionalArgs = 1, parameterNames = {"name"}) + @Builtin(name = "sysconf", minNumOfPositionalArgs = 2, parameterNames = {"$self", "name"}, declaresExplicitSelf = true) @GenerateNodeFactory - abstract static class SysconfNode extends PythonUnaryBuiltinNode { + abstract static class SysconfNode extends PythonBinaryBuiltinNode { - public static final TruffleString T_SC_CLK_TCK = tsLiteral("SC_CLK_TCK"); - public static final TruffleString T_SC_NPROCESSORS_ONLN = tsLiteral("SC_NPROCESSORS_ONLN"); - public static final int SC_CLK_TCK = 2; - public static final int SC_NPROCESSORS_ONLN = 84; - public static final EconomicMapStorage SYSCONF_NAMES = EconomicMapStorage.create(); - static { - // TODO populate from constants - SYSCONF_NAMES.putUncachedWithJavaEq(T_SC_CLK_TCK, SC_CLK_TCK); - SYSCONF_NAMES.putUncachedWithJavaEq(T_SC_NPROCESSORS_ONLN, SC_NPROCESSORS_ONLN); - } + private static final TruffleString T_SYSCONF_NAMES = tsLiteral("sysconf_names"); @Specialization - static int sysconf(VirtualFrame frame, Object arg, + static long sysconf(VirtualFrame frame, PythonModule self, Object arg, @Bind("this") Node inliningTarget, @Cached PyLongCheckNode longCheckNode, @Cached PyLongAsIntNode asIntNode, @Cached PyUnicodeCheckNode unicodeCheckNode, - @Cached HashingStorageNodes.HashingStorageGetItem getItem, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PyObjectGetAttr getAttr, + @Cached PyObjectGetItem getItem, + @Cached PRaiseNode raiseNode, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { int id; if (longCheckNode.execute(inliningTarget, arg)) { id = asIntNode.execute(frame, inliningTarget, arg); } else if (unicodeCheckNode.execute(inliningTarget, arg)) { - Object idObj = getItem.execute(frame, inliningTarget, SYSCONF_NAMES, arg); - if (idObj instanceof Integer idInt) { - id = idInt; - } else { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.UNRECOGNIZED_CONF_NAME); + try { + Object sysconfigNamesObject = getAttr.execute(frame, inliningTarget, self, T_SYSCONF_NAMES); + Object idObj = getItem.execute(frame, inliningTarget, sysconfigNamesObject, arg); + id = asIntNode.execute(frame, inliningTarget, idObj); + } catch (PException e) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.UNRECOGNIZED_CONF_NAME); } } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CONFIGURATION_NAMES_MUST_BE_STRINGS_OR_INTEGERS); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CONFIGURATION_NAMES_MUST_BE_STRINGS_OR_INTEGERS); } - if (id == SC_CLK_TCK) { - return 100; // it's 100 on most default kernel configs. TODO: use real value through - // NFI - } else if (id == SC_NPROCESSORS_ONLN) { - return CpuCountNode.getCpuCount(); + try { + return posixLib.sysconf(context.getPosixSupport(), id); + } catch (PosixException e) { + throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } - throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, OSErrorEnum.EINVAL); } } @@ -2943,12 +2927,13 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - int umask(VirtualFrame frame, int mask, + static int umask(VirtualFrame frame, int mask, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - return posixLib.umask(getPosixSupport(), mask); + return posixLib.umask(context.getPosixSupport(), mask); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -2959,12 +2944,13 @@ int umask(VirtualFrame frame, int mask, @GenerateNodeFactory abstract static class CtermId extends PythonBuiltinNode { @Specialization - TruffleString ctermid(VirtualFrame frame, + static TruffleString ctermid(VirtualFrame frame, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - return posixLib.ctermid(getPosixSupport()); + return posixLib.ctermid(context.getPosixSupport()); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -2982,14 +2968,15 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone kill(VirtualFrame frame, long pid, int signal, + static PNone kill(VirtualFrame frame, long pid, int signal, @Bind("this") Node inliningTarget, @Cached SysModuleBuiltins.AuditNode auditNode, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { auditNode.audit(inliningTarget, "kill", pid, signal); try { - posixLib.kill(getPosixSupport(), pid, signal); + posixLib.kill(context.getPosixSupport(), pid, signal); return PNone.NONE; } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); @@ -3010,14 +2997,15 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - PNone kill(VirtualFrame frame, long pid, int signal, + static PNone kill(VirtualFrame frame, long pid, int signal, @Bind("this") Node inliningTarget, @Cached SysModuleBuiltins.AuditNode auditNode, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { auditNode.audit(inliningTarget, "killpg", pid, signal); try { - posixLib.killpg(getPosixSupport(), pid, signal); + posixLib.killpg(context.getPosixSupport(), pid, signal); return PNone.NONE; } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); @@ -3044,7 +3032,7 @@ static Object doTrivial(VirtualFrame frame, Object value, abstract static class RegisterAtForkNode extends PythonBuiltinNode { @Specialization @SuppressWarnings("unused") - Object register(Object before, Object afterInChild, Object afterInParent) { + static Object register(Object before, Object afterInChild, Object afterInParent) { // TODO should we at least call multiprocessing.util.register_after_fork? return PNone.NONE; } @@ -3064,15 +3052,15 @@ public abstract static class StringOrBytesToBytesNode extends Node { @Specialization(guards = "isString(strObj)") static PBytes doString(Node inliningTarget, Object strObj, + @Bind PythonLanguage language, @Cached CastToTruffleStringNode castToStringNode, @Cached(inline = false) TruffleString.SwitchEncodingNode switchEncodingNode, - @Cached(inline = false) TruffleString.CopyToByteArrayNode copyToByteArrayNode, - @Cached(inline = false) PythonObjectFactory factory) { + @Cached(inline = false) TruffleString.CopyToByteArrayNode copyToByteArrayNode) { TruffleString str = castToStringNode.execute(inliningTarget, strObj); TruffleString utf8 = switchEncodingNode.execute(str, Encoding.UTF_8); byte[] bytes = new byte[utf8.byteLength(Encoding.UTF_8)]; copyToByteArrayNode.execute(utf8, 0, bytes, 0, bytes.length, Encoding.UTF_8); - return factory.createBytes(bytes); + return PFactory.createBytes(language, bytes); } @Specialization @@ -3095,23 +3083,25 @@ abstract static class StringOrBytesToOpaquePathNode extends Node { @Specialization(guards = "isString(strObj)") static Object doString(Node inliningTarget, Object strObj, @Cached CastToTruffleStringNode castToStringNode, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, + @Exclusive @Cached PRaiseNode raiseNode) { TruffleString str = castToStringNode.execute(inliningTarget, strObj); - return checkPath(inliningTarget, posixLib.createPathFromString(PosixSupport.get(inliningTarget), str), raiseNode); + return checkPath(inliningTarget, posixLib.createPathFromString(context.getPosixSupport(), str), raiseNode); } @Specialization static Object doBytes(Node inliningTarget, PBytes bytes, @Cached(inline = false) BytesNodes.ToBytesNode toBytesNode, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - return checkPath(inliningTarget, posixLib.createPathFromBytes(PosixSupport.get(inliningTarget), toBytesNode.execute(bytes)), raiseNode); + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, + @Exclusive @Cached PRaiseNode raiseNode) { + return checkPath(inliningTarget, posixLib.createPathFromBytes(context.getPosixSupport(), toBytesNode.execute(bytes)), raiseNode); } - private static Object checkPath(Node inliningTarget, Object path, PRaiseNode.Lazy raiseNode) { + private static Object checkPath(Node inliningTarget, Object path, PRaiseNode raiseNode) { if (path == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.EMBEDDED_NULL_BYTE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.EMBEDDED_NULL_BYTE); } return path; } @@ -3138,10 +3128,10 @@ static Object withCheck(VirtualFrame frame, Node inliningTarget, Object obj, @Su @Exclusive @Cached PyOSFSPathNode fspathNode, @Cached PyObjectSizeNode sizeNode, @Exclusive @Cached StringOrBytesToOpaquePathNode stringOrBytesToOpaquePathNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object stringOrBytes = fspathNode.execute(frame, inliningTarget, obj); if (sizeNode.execute(frame, inliningTarget, obj) == 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.EXECV_ARG2_FIRST_ELEMENT_CANNOT_BE_EMPTY); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.EXECV_ARG2_FIRST_ELEMENT_CANNOT_BE_EMPTY); } return stringOrBytesToOpaquePathNode.execute(inliningTarget, stringOrBytes); } @@ -3161,9 +3151,9 @@ abstract static class ObjectToTimespecNode extends ConvertToTimespecBaseNode { @Specialization static void doDouble(Node inliningTarget, double value, long[] timespec, int offset, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { if (Double.isNaN(value)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.INVALID_VALUE_NAN); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.INVALID_VALUE_NAN); } double denominator = 1000000000.0; @@ -3180,7 +3170,7 @@ static void doDouble(Node inliningTarget, double value, long[] timespec, int off } assert 0.0 <= floatPart && floatPart < denominator; if (!MathGuards.fitLong(intPart)) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.TIMESTAMP_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.TIMESTAMP_OUT_OF_RANGE); } timespec[offset] = (long) intPart; timespec[offset + 1] = (long) floatPart; @@ -3189,7 +3179,7 @@ static void doDouble(Node inliningTarget, double value, long[] timespec, int off @Specialization static void doPFloat(Node inliningTarget, PFloat obj, long[] timespec, int offset, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { doDouble(inliningTarget, obj.getValue(), timespec, offset, raiseNode); } @@ -3208,11 +3198,11 @@ static void doLong(long value, long[] timespec, int offset) { @Specialization(guards = {"!isDouble(value)", "!isPFloat(value)", "!isInteger(value)"}) static void doGeneric(VirtualFrame frame, Node inliningTarget, Object value, long[] timespec, int offset, @Cached PyLongAsLongAndOverflowNode asLongNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { try { timespec[offset] = asLongNode.execute(frame, inliningTarget, value); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.TIMESTAMP_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.TIMESTAMP_OUT_OF_RANGE); } timespec[offset + 1] = 0; } @@ -3223,7 +3213,7 @@ static void doGeneric(VirtualFrame frame, Node inliningTarget, Object value, lon */ @GenerateInline @GenerateCached(false) - @ImportStatic({BinaryArithmetic.class, PGuards.class}) + @ImportStatic(PGuards.class) abstract static class SplitLongToSAndNsNode extends ConvertToTimespecBaseNode { private static final long BILLION = 1000000000; @@ -3241,14 +3231,14 @@ static void doLong(long value, long[] timespec, int offset) { @Specialization(guards = {"!isInteger(value)"}) static void doGeneric(VirtualFrame frame, Node inliningTarget, Object value, long[] timespec, int offset, - @Cached(value = "DivMod.create()", inline = false) BinaryOpNode callDivmod, + @Cached PyNumberDivmodNode divmodNode, @Cached LenNode lenNode, @Cached(value = "createNotNormalized()", inline = false) GetItemNode getItemNode, @Cached PyLongAsLongNode asLongNode, - @Cached PRaiseNode.Lazy raiseNode) { - Object divmod = callDivmod.executeObject(frame, value, BILLION); + @Cached PRaiseNode raiseNode) { + Object divmod = divmodNode.execute(frame, inliningTarget, value, BILLION); if (!PGuards.isPTuple(divmod) || lenNode.execute(inliningTarget, (PSequence) divmod) != 2) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MUST_RETURN_2TUPLE, value, divmod); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_RETURN_2TUPLE, value, divmod); } SequenceStorage storage = ((PTuple) divmod).getSequenceStorage(); timespec[offset] = asLongNode.execute(frame, inliningTarget, getItemNode.execute(storage, 0)); @@ -3260,10 +3250,10 @@ static int dirFdForAudit(int dirFd) { return dirFd == AT_FDCWD.value ? -1 : dirFd; } - public static PTuple createStatResult(Node inliningTarget, PythonObjectFactory factory, InlinedConditionProfile positiveLongProfile, long[] out) { + public static PTuple createStatResult(Node inliningTarget, PythonLanguage language, InlinedConditionProfile positiveLongProfile, long[] out) { Object[] res = new Object[16]; for (int i = 0; i < 7; i++) { - res[i] = PInt.createPythonIntFromUnsignedLong(inliningTarget, factory, positiveLongProfile, out[i]); + res[i] = PInt.createPythonIntFromUnsignedLong(inliningTarget, language, positiveLongProfile, out[i]); } res[6] = out[6]; for (int i = 7; i < 10; i++) { @@ -3271,9 +3261,9 @@ public static PTuple createStatResult(Node inliningTarget, PythonObjectFactory f long nsFraction = out[i + 3]; res[i] = seconds; res[i + 3] = seconds + nsFraction * 1.0e-9; - res[i + 6] = factory.createInt(convertToNanoseconds(seconds, nsFraction)); + res[i + 6] = PFactory.createInt(language, convertToNanoseconds(seconds, nsFraction)); } - return factory.createStructSeq(STAT_RESULT_DESC, res); + return PFactory.createStructSeq(language, STAT_RESULT_DESC, res); } @TruffleBoundary @@ -3284,14 +3274,14 @@ private static BigInteger convertToNanoseconds(long sec, long ns) { return r.add(BigInteger.valueOf(ns)); } - public static PBytes opaquePathToBytes(Object opaquePath, PosixSupportLibrary posixLib, Object posixSupport, PythonObjectFactory factory) { + public static PBytes opaquePathToBytes(Object opaquePath, PosixSupportLibrary posixLib, Object posixSupport, PythonLanguage language) { Buffer buf = posixLib.getPathAsBytes(posixSupport, opaquePath); if (buf.length > Integer.MAX_VALUE) { // sanity check that it is safe to cast result.length to int, to be removed once // we support large arrays throw CompilerDirectives.shouldNotReachHere("Posix path cannot fit into a Java array"); } - return factory.createBytes(buf.data, 0, (int) buf.length); + return PFactory.createBytes(language, buf.data, (int) buf.length); } // ------------------ @@ -3335,43 +3325,43 @@ static int doFdInt(int value) { } @Specialization - int doFdLong(long value, + static int doFdLong(long value, @Bind("this") Node inliningTarget, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { return longToFd(inliningTarget, value, raiseNode); } @Specialization @SuppressWarnings("truffle-static-method") - int doFdPInt(PInt value, + static int doFdPInt(PInt value, @Bind("this") Node inliningTarget, @Exclusive @Cached CastToJavaLongLossyNode castToLongNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { return doFdLong(castToLongNode.execute(inliningTarget, value), inliningTarget, raiseNode); } @Specialization(guards = {"!isPNone(value)", "!canBeInteger(value)"}) @SuppressWarnings("truffle-static-method") - int doIndex(VirtualFrame frame, Object value, + static int doIndex(VirtualFrame frame, Object value, @Bind("this") Node inliningTarget, @Cached PyIndexCheckNode indexCheckNode, @Cached PyNumberIndexNode indexNode, @Exclusive @Cached CastToJavaLongLossyNode castToLongNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (indexCheckNode.execute(inliningTarget, value)) { Object o = indexNode.execute(frame, inliningTarget, value); return doFdLong(castToLongNode.execute(inliningTarget, o), inliningTarget, raiseNode); } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ARG_SHOULD_BE_INT_OR_NONE, value); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ARG_SHOULD_BE_INT_OR_NONE_T, value); } } - private static int longToFd(Node inliningTarget, long value, PRaiseNode.Lazy raiseNode) { + private static int longToFd(Node inliningTarget, long value, PRaiseNode raiseNode) { if (value > Integer.MAX_VALUE) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.FD_IS_GREATER_THAN_MAXIMUM); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.FD_IS_GREATER_THAN_MAXIMUM); } if (value < Integer.MIN_VALUE) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.FD_IS_LESS_THAN_MINIMUM); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.FD_IS_LESS_THAN_MINIMUM); } return (int) value; } @@ -3404,9 +3394,10 @@ public PathConversionNode(String functionName, String argumentName, boolean null @Specialization(guards = "nullable") PosixFileHandle doNone(@SuppressWarnings("unused") PNone value, @Bind("this") Node inliningTarget, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - Object path = posixLib.createPathFromString(PosixSupport.get(inliningTarget), T_DOT); + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, + @Exclusive @Cached PRaiseNode raiseNode) { + Object path = posixLib.createPathFromString(context.getPosixSupport(), T_DOT); return new PosixPath(null, checkPath(inliningTarget, path, raiseNode), false); } @@ -3423,7 +3414,7 @@ static PosixFileHandle doFdInt(int value) { @Specialization(guards = "allowFd") static PosixFileHandle doFdLong(long value, @Bind("this") Node inliningTarget, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { return new PosixFd(value, DirFdConversionNode.longToFd(inliningTarget, value, raiseNode)); } @@ -3431,7 +3422,7 @@ static PosixFileHandle doFdLong(long value, static PosixFileHandle doFdPInt(PInt value, @Bind("this") Node inliningTarget, @Exclusive @Cached CastToJavaLongLossyNode castToLongNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { return new PosixFd(value, DirFdConversionNode.longToFd(inliningTarget, castToLongNode.execute(inliningTarget, value), raiseNode)); } @@ -3440,10 +3431,11 @@ static PosixFileHandle doFdPInt(PInt value, PosixFileHandle doUnicode(Object value, @Bind("this") Node inliningTarget, @Exclusive @Cached CastToTruffleStringNode castToStringNode, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, + @Exclusive @Cached PRaiseNode raiseNode) { TruffleString str = castToStringNode.execute(inliningTarget, value); - Object path = posixLib.createPathFromString(PosixSupport.get(inliningTarget), str); + Object path = posixLib.createPathFromString(context.getPosixSupport(), str); return new PosixPath(value, checkPath(inliningTarget, path, raiseNode), false); } @@ -3452,9 +3444,10 @@ PosixFileHandle doUnicode(Object value, PosixFileHandle doBytes(PBytes value, @Bind("this") Node inliningTarget, @Exclusive @Cached BytesNodes.ToBytesNode toByteArrayNode, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - Object path = posixLib.createPathFromBytes(PosixSupport.get(inliningTarget), toByteArrayNode.execute(value)); + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, + @Exclusive @Cached PRaiseNode raiseNode) { + Object path = posixLib.createPathFromBytes(context.getPosixSupport(), toByteArrayNode.execute(value)); return new PosixPath(value, checkPath(inliningTarget, path, raiseNode), true); } @@ -3466,15 +3459,15 @@ PosixFileHandle doBuffer(VirtualFrame frame, Object value, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("value") PythonBufferAcquireLibrary bufferAcquireLib, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached WarningsModuleBuiltins.WarnNode warningNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { PythonLanguage language = context.getLanguage(inliningTarget); Object buffer = bufferAcquireLib.acquireReadonly(value, frame, context, language, indirectCallData); try { warningNode.warnFormat(frame, null, PythonBuiltinClassType.DeprecationWarning, 1, ErrorMessages.S_S_SHOULD_BE_S_NOT_P, functionNameWithColon, argumentName, getAllowedTypes(), value); - Object path = posixLib.createPathFromBytes(PosixSupport.get(inliningTarget), bufferLib.getCopiedByteArray(value)); + Object path = posixLib.createPathFromBytes(context.getPosixSupport(), bufferLib.getCopiedByteArray(value)); return new PosixPath(value, checkPath(inliningTarget, path, raiseNode), true); } finally { bufferLib.release(buffer, frame, context, language, indirectCallData); @@ -3489,7 +3482,7 @@ PosixFileHandle doIndex(VirtualFrame frame, Object value, @SuppressWarnings("unused") @Exclusive @Cached PyIndexCheckNode indexCheckNode, @Cached PyNumberIndexNode indexNode, @Exclusive @Cached CastToJavaLongLossyNode castToLongNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { Object o = indexNode.execute(frame, inliningTarget, value); return new PosixFd(value, DirFdConversionNode.longToFd(inliningTarget, castToLongNode.execute(inliningTarget, o), raiseNode)); } @@ -3503,22 +3496,23 @@ PosixFileHandle doGeneric(VirtualFrame frame, Object value, @Cached("create(T___FSPATH__)") LookupAndCallUnaryNode callFSPath, @Exclusive @Cached BytesNodes.ToBytesNode toByteArrayNode, @Exclusive @Cached CastToTruffleStringNode castToStringNode, - @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, + @Exclusive @Cached PRaiseNode raiseNode) { Object pathObject = callFSPath.executeObject(frame, value); if (pathObject == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_S_SHOULD_BE_S_NOT_P, functionNameWithColon, argumentName, + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_S_SHOULD_BE_S_NOT_P, functionNameWithColon, argumentName, getAllowedTypes(), value); } // 'pathObject' replaces 'value' as the PosixPath.originalObject for auditing purposes // by design if (pathObject instanceof PBytes) { - return doBytes((PBytes) pathObject, inliningTarget, toByteArrayNode, posixLib, raiseNode); + return doBytes((PBytes) pathObject, inliningTarget, toByteArrayNode, context, posixLib, raiseNode); } if (PGuards.isString(pathObject)) { - return doUnicode(pathObject, inliningTarget, castToStringNode, posixLib, raiseNode); + return doUnicode(pathObject, inliningTarget, castToStringNode, context, posixLib, raiseNode); } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.EXPECTED_FSPATH_TO_RETURN_STR_OR_BYTES, value, pathObject); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.EXPECTED_FSPATH_TO_RETURN_STR_OR_BYTES, value, pathObject); } protected boolean isHandled(Object value) { @@ -3530,9 +3524,9 @@ private String getAllowedTypes() { : allowFd ? "string, bytes, os.PathLike or integer" : nullable ? "string, bytes, os.PathLike or None" : "string, bytes or os.PathLike"; } - private Object checkPath(Node inliningTarget, Object path, PRaiseNode.Lazy raiseNode) { + private Object checkPath(Node inliningTarget, Object path, PRaiseNode raiseNode) { if (path == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.S_EMBEDDED_NULL_CHARACTER_IN_S, functionNameWithColon, argumentName); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.S_EMBEDDED_NULL_CHARACTER_IN_S, functionNameWithColon, argumentName); } return path; } @@ -3634,14 +3628,14 @@ public abstract static class AbstractIdConversionNode extends ArgumentCastNode { @Specialization long doInt(int value, @Bind("this") Node inliningTarget, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { return checkValue(inliningTarget, value, raiseNode); } @Specialization long doLong(long value, @Bind("this") Node inliningTarget, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { return checkValue(inliningTarget, value, raiseNode); } @@ -3651,12 +3645,12 @@ long doGeneric(VirtualFrame frame, Object value, @Bind("this") Node inliningTarget, @Cached PyNumberIndexNode pyNumberIndexNode, @Cached PyLongAsLongNode asLongNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { Object index; try { index = pyNumberIndexNode.execute(frame, inliningTarget, value); } catch (PException ex) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_SHOULD_BE_INTEGER_NOT_P, getIdName(), value); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_SHOULD_BE_INTEGER_NOT_P, getIdName(), value); } /* * We have no means to distinguish overflow/underflow, so we just let any OverflowError @@ -3666,13 +3660,13 @@ long doGeneric(VirtualFrame frame, Object value, return checkValue(inliningTarget, asLongNode.execute(frame, inliningTarget, index), raiseNode); } - private long checkValue(Node inliningTarget, long value, PRaiseNode.Lazy raiseNode) { + private long checkValue(Node inliningTarget, long value, PRaiseNode raiseNode) { // Note that -1 is intentionally allowed if (value < -1) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.S_IS_LESS_THAN_MINIMUM, getIdName()); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.S_IS_LESS_THAN_MINIMUM, getIdName()); } else if (value > MAX_UINT32) { /* uid_t is uint32_t on Linux */ - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.S_IS_GREATER_THAN_MAXIUMUM, getIdName()); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.S_IS_GREATER_THAN_MAXIUMUM, getIdName()); } return value; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java index 36c6a82161..e78b40382a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java @@ -126,13 +126,13 @@ static Object[] doSequence(VirtualFrame frame, Object processArgs, @Cached IsBuiltinObjectProfile isBuiltinClassProfile, @Cached ObjectToOpaquePathNode objectToOpaquePathNode, @Cached("createNotNormalized()") GetItemNode getItemNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { PSequence argsSequence; try { argsSequence = fastConstructListNode.execute(frame, inliningTarget, processArgs); } catch (PException e) { e.expect(inliningTarget, TypeError, isBuiltinClassProfile); - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_MUST_BE_S, "argv", "a tuple"); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_MUST_BE_S, "argv", "a tuple"); } SequenceStorage argsStorage = getSequenceStorageNode.execute(inliningTarget, argsSequence); @@ -142,7 +142,7 @@ static Object[] doSequence(VirtualFrame frame, Object processArgs, SequenceStorage newStorage = getSequenceStorageNode.execute(inliningTarget, argsSequence); if (newStorage != argsStorage || newStorage.length() != len) { // TODO write a test for this - throw raiseNode.get(inliningTarget).raise(RuntimeError, ErrorMessages.ARGS_CHANGED_DURING_ITERATION); + throw raiseNode.raise(inliningTarget, RuntimeError, ErrorMessages.ARGS_CHANGED_DURING_ITERATION); } Object o = getItemNode.execute(argsStorage, i); argsArray[i] = objectToOpaquePathNode.execute(frame, inliningTarget, o, false); @@ -171,7 +171,7 @@ static Object doSequence(VirtualFrame frame, Object env, @Cached ToBytesNode toBytesNode, @Cached PyObjectGetItem getItem, @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { // TODO unlike CPython, this accepts a dict (if the keys are integers (0, 1, ..., len-1) int length = sizeNode.execute(frame, inliningTarget, env); Object[] result = new Object[length]; @@ -180,7 +180,7 @@ static Object doSequence(VirtualFrame frame, Object env, byte[] bytes = toBytesNode.execute(frame, o); Object o1 = posixLib.createPathFromBytes(context.getPosixSupport(), bytes); if (o1 == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.EMBEDDED_NULL_BYTE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.EMBEDDED_NULL_BYTE); } result[i] = o1; } @@ -230,13 +230,13 @@ private static byte[] fsEncode(String s) { return s.getBytes(); } - private static Object createPathFromBytes(Node inliningTarget, byte[] bytes, PosixSupportLibrary posixLib, PRaiseNode.Lazy raiseNode) { + private static Object createPathFromBytes(Node inliningTarget, byte[] bytes, PosixSupportLibrary posixLib, PRaiseNode raiseNode) { Object o = posixLib.createPathFromBytes(PosixSupport.get(inliningTarget), bytes); if (o == null) { // TODO reconsider the contract of PosixSupportLibrary#createPathFromBytes w.r.t. // embedded null checks (we need to review that anyway since PosixSupportLibrary // cannot do Python-specific fsencode) - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.EMBEDDED_NULL_BYTE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.EMBEDDED_NULL_BYTE); } return o; } @@ -259,15 +259,15 @@ static int forkExec(VirtualFrame frame, Object[] args, Object executableList, bo @Cached GilNode gil, @Cached ToBytesNode toBytesNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (!(preexecFn instanceof PNone)) { - throw raiseNode.get(inliningTarget).raise(RuntimeError, ErrorMessages.S_NOT_SUPPORTED, "preexec_fn"); + throw raiseNode.raise(inliningTarget, RuntimeError, ErrorMessages.S_NOT_SUPPORTED, "preexec_fn"); } if (closeFds && errPipeWrite < 3) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.S_MUST_BE_S, "errpipe_write", ">= 3"); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.S_MUST_BE_S, "errpipe_write", ">= 3"); } if (!(fdsToKeepObj instanceof PTuple)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "fork_exec()", 4, "tuple", fdsToKeepObj); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "fork_exec()", 4, "tuple", fdsToKeepObj); } Object[] processArgs = args; int[] fdsToKeep = convertFdSequence(inliningTarget, (PTuple) fdsToKeepObj, tupleGetItem, castToIntNode, raiseNode); @@ -284,7 +284,7 @@ static int forkExec(VirtualFrame frame, Object[] args, Object executableList, bo if (Arrays.equals(bytes, sysExecutable)) { TruffleString[] additionalArgs = PythonOptions.getExecutableList(context); if (length != 1 && additionalArgs.length != 1) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.UNSUPPORTED_USE_OF_SYS_EXECUTABLE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.UNSUPPORTED_USE_OF_SYS_EXECUTABLE); } Object[] extendedArgs = new Object[additionalArgs.length + (processArgs.length == 0 ? 0 : processArgs.length - 1)]; for (int j = 0; j < additionalArgs.length; ++j) { @@ -319,7 +319,7 @@ static int forkExec(VirtualFrame frame, Object[] args, Object executableList, bo * Checks that the tuple contains only valid fds (positive integers fitting into an int) in * ascending order. */ - private static int[] convertFdSequence(Node inliningTarget, PTuple fdSequence, GetItemNode getItemNode, CastToJavaIntExactNode castToIntNode, PRaiseNode.Lazy raiseNode) { + private static int[] convertFdSequence(Node inliningTarget, PTuple fdSequence, GetItemNode getItemNode, CastToJavaIntExactNode castToIntNode, PRaiseNode raiseNode) { SequenceStorage storage = fdSequence.getSequenceStorage(); int len = storage.length(); int[] fds = new int[len]; @@ -334,7 +334,7 @@ private static int[] convertFdSequence(Node inliningTarget, PTuple fdSequence, G } catch (PException | CannotCastException e) { // 'handled' by raise() below } - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.BAD_VALUES_IN_FDS_TO_KEEP); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.BAD_VALUES_IN_FDS_TO_KEEP); } return fds; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PwdModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PwdModuleBuiltins.java index a79a3d1df3..ccf89d943b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PwdModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PwdModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,6 +46,7 @@ import java.util.Arrays; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; import com.oracle.graal.python.builtins.Builtin; @@ -75,7 +76,7 @@ import com.oracle.graal.python.runtime.PosixSupportLibrary.PwdResult; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -93,12 +94,6 @@ public final class PwdModuleBuiltins extends PythonBuiltins { private static final TruffleString T_NOT_AVAILABLE = tsLiteral("NOT_AVAILABLE"); static final StructSequence.BuiltinTypeDescriptor STRUCT_PASSWD_DESC = new StructSequence.BuiltinTypeDescriptor( PythonBuiltinClassType.PStructPasswd, - // @formatter:off The formatter joins these lines making it less readable - "pwd.struct_passwd: Results from getpw*() routines.\n\n" + - "This object may be accessed either as a tuple of\n" + - " (pw_name,pw_passwd,pw_uid,pw_gid,pw_gecos,pw_dir,pw_shell)\n" + - "or via the object attributes as named in the above tuple.", - // @formatter:on 7, new String[]{ "pw_name", "pw_passwd", "pw_uid", "pw_gid", "pw_gecos", "pw_dir", "pw_shell", @@ -126,12 +121,12 @@ public void initialize(Python3Core core) { StructSequence.initType(core, STRUCT_PASSWD_DESC); } - private static Object[] createPwuidObject(Node inliningTarget, PwdResult pwd, PythonObjectFactory factory, InlinedConditionProfile unsignedConversionProfile) { + private static Object[] createPwuidObject(Node inliningTarget, PwdResult pwd, PythonLanguage language, InlinedConditionProfile unsignedConversionProfile) { return new Object[]{ pwd.name, T_NOT_AVAILABLE, - PInt.createPythonIntFromUnsignedLong(inliningTarget, factory, unsignedConversionProfile, pwd.uid), - PInt.createPythonIntFromUnsignedLong(inliningTarget, factory, unsignedConversionProfile, pwd.gid), + PInt.createPythonIntFromUnsignedLong(inliningTarget, language, unsignedConversionProfile, pwd.uid), + PInt.createPythonIntFromUnsignedLong(inliningTarget, language, unsignedConversionProfile, pwd.gid), /* gecos: */ T_EMPTY_STRING, pwd.dir, pwd.shell @@ -144,26 +139,25 @@ public abstract static class GetpwuidNode extends PythonUnaryBuiltinNode { @Specialization static Object doGetpwuid(VirtualFrame frame, Object uidObj, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached UidConversionNode uidConversionNode, @Cached IsBuiltinObjectProfile classProfile, @Cached GilNode gil, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached InlinedConditionProfile unsignedConversionProfile, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { long uid; try { uid = uidConversionNode.executeLong(frame, uidObj); } catch (PException ex) { if (classProfile.profileException(inliningTarget, ex, PythonBuiltinClassType.OverflowError)) { - throw raiseUidNotFound(raiseNode.get(inliningTarget)); + throw raiseUidNotFound(inliningTarget, raiseNode); } throw ex; } PwdResult pwd; try { - PythonContext context = PythonContext.get(inliningTarget); gil.release(true); try { pwd = posixLib.getpwuid(context.getPosixSupport(), uid); @@ -174,13 +168,14 @@ static Object doGetpwuid(VirtualFrame frame, Object uidObj, throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } if (pwd == null) { - throw raiseUidNotFound(raiseNode.get(inliningTarget)); + throw raiseUidNotFound(inliningTarget, raiseNode); } - return factory.createStructSeq(STRUCT_PASSWD_DESC, createPwuidObject(inliningTarget, pwd, factory, unsignedConversionProfile)); + PythonLanguage language = context.getLanguage(inliningTarget); + return PFactory.createStructSeq(language, STRUCT_PASSWD_DESC, createPwuidObject(inliningTarget, pwd, language, unsignedConversionProfile)); } - private static PException raiseUidNotFound(PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.KeyError, ErrorMessages.GETPWUID_NOT_FOUND); + private static PException raiseUidNotFound(Node inliningTarget, PRaiseNode raiseNode) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.KeyError, ErrorMessages.GETPWUID_NOT_FOUND); } } @@ -197,20 +192,20 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static Object doGetpwname(VirtualFrame frame, TruffleString name, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached GilNode gil, @Cached StringOrBytesToOpaquePathNode encodeFSDefault, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached InlinedConditionProfile unsignedConversionProfile, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { // Note: CPython also takes only Strings, not bytes, and then encodes the String // StringOrBytesToOpaquePathNode already checks for embedded '\0' Object nameEncoded = encodeFSDefault.execute(inliningTarget, name); PwdResult pwd; try { gil.release(true); - PythonContext context = PythonContext.get(inliningTarget); try { pwd = posixLib.getpwnam(context.getPosixSupport(), nameEncoded); } finally { @@ -220,9 +215,9 @@ static Object doGetpwname(VirtualFrame frame, TruffleString name, throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } if (pwd == null) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.KeyError, ErrorMessages.GETPWNAM_NAME_NOT_FOUND, name); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.KeyError, ErrorMessages.GETPWNAM_NAME_NOT_FOUND, name); } - return factory.createStructSeq(STRUCT_PASSWD_DESC, createPwuidObject(inliningTarget, pwd, factory, unsignedConversionProfile)); + return PFactory.createStructSeq(language, STRUCT_PASSWD_DESC, createPwuidObject(inliningTarget, pwd, context.getLanguage(inliningTarget), unsignedConversionProfile)); } } @@ -230,24 +225,25 @@ static Object doGetpwname(VirtualFrame frame, TruffleString name, @GenerateNodeFactory public abstract static class GetpwallNode extends PythonBuiltinNode { @Specialization - Object doGetpall(VirtualFrame frame, + static Object doGetpall(VirtualFrame frame, @Bind("this") Node inliningTarget, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached InlinedConditionProfile unsignedConversionProfile, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { // We cannot release the GIL, because the underlying POSIX calls are not thread safe PwdResult[] entries; try { - entries = posixLib.getpwentries(getPosixSupport()); + entries = posixLib.getpwentries(context.getPosixSupport()); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } + PythonLanguage language = context.getLanguage(inliningTarget); Object[] result = new Object[entries.length]; for (int i = 0; i < result.length; i++) { - result[i] = factory.createStructSeq(STRUCT_PASSWD_DESC, createPwuidObject(inliningTarget, entries[i], factory, unsignedConversionProfile)); + result[i] = PFactory.createStructSeq(language, STRUCT_PASSWD_DESC, createPwuidObject(inliningTarget, entries[i], language, unsignedConversionProfile)); } - return factory.createList(result); + return PFactory.createList(language, result); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/QueueModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/QueueModuleBuiltins.java index 60ac362574..76ed5ed096 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/QueueModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/QueueModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,30 +40,22 @@ */ package com.oracle.graal.python.builtins.modules; -import static com.oracle.graal.python.nodes.BuiltinNames.J_SIMPLE_QUEUE; - +import java.util.Collections; import java.util.List; -import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.objects.queue.PSimpleQueue; import com.oracle.graal.python.nodes.BuiltinNames; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; -import com.oracle.truffle.api.dsl.Specialization; @CoreFunctions(defineModule = "_queue") public final class QueueModuleBuiltins extends PythonBuiltins { @Override protected List> getNodeFactories() { - return QueueModuleBuiltinsFactory.getFactories(); + return Collections.emptyList(); } @Override @@ -71,18 +63,4 @@ public void initialize(Python3Core core) { super.initialize(core); addBuiltinConstant(BuiltinNames.T_EMPTY_CLASS_NAME, core.lookupType(PythonBuiltinClassType.Empty)); } - - // _queue.SimpleQueue - @Builtin(name = J_SIMPLE_QUEUE, constructsClass = PythonBuiltinClassType.PSimpleQueue, // - minNumOfPositionalArgs = 1, // - doc = "SimpleQueue()\n--\n\nSimple, unbounded, reentrant FIFO queue.") - @GenerateNodeFactory - abstract static class SimpleQueueNode extends PythonUnaryBuiltinNode { - - @Specialization - static PSimpleQueue doGeneric(Object cls, - @Cached PythonObjectFactory factory) { - return factory.createSimpleQueue(cls); - } - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/RandomModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/RandomModuleBuiltins.java index 810cc61d65..88668696bc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/RandomModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/RandomModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2014, Regents of the University of California * * All rights reserved. @@ -25,49 +25,19 @@ */ package com.oracle.graal.python.builtins.modules; -import static com.oracle.graal.python.util.PythonUtils.tsLiteral; - +import java.util.Collections; import java.util.List; -import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.random.PRandom; -import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.strings.TruffleString; @CoreFunctions(defineModule = "_random") public final class RandomModuleBuiltins extends PythonBuiltins { @Override protected List> getNodeFactories() { - return RandomModuleBuiltinsFactory.getFactories(); - } - - // _random.Random([seed]) - @Builtin(name = "Random", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PRandom, takesVarKeywordArgs = true) - @GenerateNodeFactory - abstract static class PRandomNode extends PythonBuiltinNode { - private static final TruffleString T_SEED = tsLiteral("seed"); - - @Child LookupAndCallBinaryNode setSeed = LookupAndCallBinaryNode.create(T_SEED); - - @Specialization - PRandom random(VirtualFrame frame, Object cls, Object seed, - @Cached PythonObjectFactory factory) { - PRandom random = factory.createRandom(cls); - setSeed.executeObject(frame, random, seed != PNone.NO_VALUE ? seed : PNone.NONE); - return random; - } + return Collections.emptyList(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ReadlineModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ReadlineModuleBuiltins.java index 97c29ed086..61e8a92340 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ReadlineModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ReadlineModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -49,13 +49,11 @@ import java.io.IOException; import java.nio.file.StandardOpenOption; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.module.PythonModule; @@ -88,7 +86,6 @@ protected List> getNodeFa } private static final class LocalData { - private final HashMap bindings = new HashMap<>(); private final List history = new ArrayList<>(); protected Object completer = null; protected boolean autoHistory = true; @@ -130,16 +127,9 @@ PNone setCompleter(PythonModule self, Object callable) { @GenerateNodeFactory abstract static class ParseAndBindNode extends PythonBinaryBuiltinNode { @Specialization - @TruffleBoundary - PNone setCompleter(PythonModule self, TruffleString tspec) { - String spec = tspec.toJavaStringUncached(); - if (spec.startsWith("tab:")) { - LocalData data = self.getModuleState(LocalData.class); - data.bindings.put("tab", spec.split(":")[1].trim()); - return PNone.NONE; - } else { - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.NotImplementedError, toTruffleStringUncached("any other binding than 'tab'")); - } + static PNone parseAndBind(@SuppressWarnings("unused") PythonModule self, @SuppressWarnings("unused") TruffleString tspec) { + // TODO implement + return PNone.NONE; } } @@ -148,8 +138,8 @@ PNone setCompleter(PythonModule self, TruffleString tspec) { abstract static class ReadInitNode extends PythonUnaryBuiltinNode { @Specialization static PNone setCompleter(@SuppressWarnings("unused") PythonModule self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonErrorType.OSError, ErrorMessages.NOT_IMPLEMENTED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.OSError, ErrorMessages.NOT_IMPLEMENTED); } } @@ -174,7 +164,7 @@ TruffleString setCompleter(PythonModule self, int index) { try { return data.history.get(index); } catch (IndexOutOfBoundsException e) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.IndexError, ErrorMessages.INDEX_OUT_OF_BOUNDS); + throw PRaiseNode.raiseStatic(this, PythonErrorType.IndexError, ErrorMessages.INDEX_OUT_OF_BOUNDS); } } } @@ -196,7 +186,7 @@ TruffleString setCompleter(PythonModule self, int index, TruffleString string) { try { return data.history.set(index, string); } catch (IndexOutOfBoundsException e) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.IndexError, ErrorMessages.INDEX_OUT_OF_BOUNDS); + throw PRaiseNode.raiseStatic(this, PythonErrorType.IndexError, ErrorMessages.INDEX_OUT_OF_BOUNDS); } } } @@ -211,7 +201,7 @@ TruffleString setCompleter(PythonModule self, int index) { try { return data.history.remove(index); } catch (IndexOutOfBoundsException e) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.IndexError, ErrorMessages.INDEX_OUT_OF_BOUNDS); + throw PRaiseNode.raiseStatic(this, PythonErrorType.IndexError, ErrorMessages.INDEX_OUT_OF_BOUNDS); } } } @@ -258,7 +248,7 @@ PNone setCompleter(PythonModule self, TruffleString path) { } reader.close(); } catch (IOException e) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.IOError, e); + throw PRaiseNode.raiseStatic(this, PythonErrorType.IOError, e); } return PNone.NONE; } @@ -286,7 +276,7 @@ PNone setCompleter(PythonModule self, TruffleString path) { } writer.close(); } catch (IOException e) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.IOError, e); + throw PRaiseNode.raiseStatic(this, PythonErrorType.IOError, e); } return PNone.NONE; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ResourceModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ResourceModuleBuiltins.java index 1fd1a2df14..e094283568 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ResourceModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ResourceModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,6 +44,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -62,7 +63,8 @@ import com.oracle.graal.python.runtime.PosixSupportLibrary; import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException; import com.oracle.graal.python.runtime.PosixSupportLibrary.RusageResult; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -91,13 +93,6 @@ public final class ResourceModuleBuiltins extends PythonBuiltins { static final StructSequence.BuiltinTypeDescriptor STRUCT_RUSAGE_DESC = new StructSequence.BuiltinTypeDescriptor( PythonBuiltinClassType.PStructRusage, - // @formatter:off The formatter joins these lines making it less readable - "struct_rusage: Result from getrusage.\n\n" + - "This object may be accessed either as a tuple of\n" + - " (utime,stime,maxrss,ixrss,idrss,isrss,minflt,majflt,\n" + - " nswap,inblock,oublock,msgsnd,msgrcv,nsignals,nvcsw,nivcsw)\n" + - "or via the attributes ru_utime, ru_stime, ru_maxrss, and so on.", - // @formatter:on 16, new String[]{ "ru_utime", "ru_stime", "ru_maxrss", @@ -159,22 +154,23 @@ abstract static class GetRuUsageNode extends PythonBuiltinNode { @Specialization static PTuple getruusage(VirtualFrame frame, int who, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode.Lazy raiseNode) { - PosixSupport posixSupport = PosixSupport.get(inliningTarget); + @Cached PRaiseNode raiseNode) { + PosixSupport posixSupport = context.getPosixSupport(); RusageResult rusage; try { rusage = posixLib.getrusage(posixSupport, who); } catch (PosixException e) { if (e.getErrorCode() == OSErrorEnum.EINVAL.getNumber()) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.RUSAGE_INVALID_WHO); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.RUSAGE_INVALID_WHO); } else { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } } - return PythonObjectFactory.getUncached().createStructSeq(STRUCT_RUSAGE_DESC, + return PFactory.createStructSeq(context.getLanguage(inliningTarget), STRUCT_RUSAGE_DESC, rusage.ru_utime(), rusage.ru_stime(), rusage.ru_maxrss(), rusage.ru_ixrss(), rusage.ru_idrss(), rusage.ru_isrss(), rusage.ru_minflt(), rusage.ru_majflt(), rusage.ru_nswap(), rusage.ru_inblock(), rusage.ru_oublock(), @@ -196,9 +192,9 @@ static int getPageSize() { abstract static class GetRLimitNode extends PythonBuiltinNode { @Specialization static PTuple getPageSize(@SuppressWarnings("unused") int which, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { // dummy implementation - report "unrestricted" for everything - return factory.createTuple(new Object[]{RLIM_INFINITY, RLIM_INFINITY}); + return PFactory.createTuple(language, new Object[]{RLIM_INFINITY, RLIM_INFINITY}); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SREModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SREModuleBuiltins.java index f861d643f0..f451ab7bb2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SREModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SREModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -54,41 +54,43 @@ import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.array.PArray; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; +import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; import com.oracle.graal.python.builtins.objects.cext.common.NativePointer; import com.oracle.graal.python.builtins.objects.exception.PBaseException; +import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; +import com.oracle.graal.python.builtins.objects.mmap.PMMap; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.slice.SliceNodes; -import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.lib.PyLongAsIntNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyNumberIndexNode; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectSizeNode; +import com.oracle.graal.python.lib.PyUnicodeCheckNode; import com.oracle.graal.python.nodes.BuiltinNames; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.attributes.GetAttributeNode; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonSenaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -103,7 +105,6 @@ import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.ReportPolymorphism; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ArityException; import com.oracle.truffle.api.interop.ExceptionType; @@ -194,7 +195,7 @@ public static final class TRegexCache { private static final int FLAG_ASCII = 256; @TruffleBoundary - public TRegexCache(Object pattern, int flags) { + public TRegexCache(Node node, Object pattern, int flags) { this.originalPattern = pattern; String patternStr; boolean binary = true; @@ -206,7 +207,7 @@ public TRegexCache(Object pattern, int flags) { try { buffer = PythonBufferAcquireLibrary.getUncached().acquireReadonly(pattern); } catch (PException e) { - throw PRaiseNode.getUncached().raise(TypeError, ErrorMessages.EXPECTED_STR_OR_BYTESLIKE_OBJ); + throw PRaiseNode.raiseStatic(node, TypeError, ErrorMessages.EXPECTED_STR_OR_BYTESLIKE_OBJ); } PythonBufferAccessLibrary bufferLib = PythonBufferAccessLibrary.getUncached(); try { @@ -382,7 +383,7 @@ private String getTRegexOptions(String encoding, PythonMethod pythonMethod, bool } @TruffleBoundary - public Object compile(PythonContext context, PythonMethod method, boolean mustAdvance, TruffleString locale) { + public Object compile(Node node, PythonContext context, PythonMethod method, boolean mustAdvance, TruffleString locale) { String encoding = isBinary() ? ENCODING_LATIN_1 : ENCODING_UTF_32; String options = getTRegexOptions(encoding, method, mustAdvance, locale); InteropLibrary lib = InteropLibrary.getUncached(); @@ -396,7 +397,7 @@ public Object compile(PythonContext context, PythonMethod method, boolean mustAd regexp = compiledRegex; } } catch (RuntimeException e) { - throw handleCompilationError(e, lib, context); + throw handleCompilationError(node, e, lib, context); } if (isLocaleSensitive()) { setLocaleSensitiveRegexp(method, mustAdvance, locale, regexp); @@ -406,7 +407,7 @@ public Object compile(PythonContext context, PythonMethod method, boolean mustAd return regexp; } - private RuntimeException handleCompilationError(RuntimeException e, InteropLibrary lib, PythonContext context) { + private RuntimeException handleCompilationError(Node node, RuntimeException e, InteropLibrary lib, PythonContext context) { try { if (lib.isException(e)) { if (lib.getExceptionType(e) == ExceptionType.PARSE_ERROR) { @@ -415,14 +416,14 @@ private RuntimeException handleCompilationError(RuntimeException e, InteropLibra reason.equalsUncached(T_VALUE_ERROR_LOCALE_FLAG_STR_PATTERN, TS_ENCODING) || reason.equalsUncached(T_VALUE_ERROR_ASCII_UNICODE_INCOMPATIBLE, TS_ENCODING) || reason.equalsUncached(T_VALUE_ERROR_ASCII_LOCALE_INCOMPATIBLE, TS_ENCODING)) { - return PRaiseNode.getUncached().raise(ValueError, reason); + return PRaiseNode.raiseStatic(node, ValueError, reason); } else { SourceSection sourceSection = lib.getSourceLocation(e); int position = sourceSection.getCharIndex(); PythonModule module = context.lookupBuiltinModule(BuiltinNames.T__SRE); Object errorConstructor = PyObjectLookupAttr.executeUncached(module, T_ERROR); PBaseException exception = (PBaseException) CallNode.executeUncached(errorConstructor, reason, originalPattern, position); - return PRaiseNode.getUncached().raiseExceptionObject(exception); + return PRaiseNode.raiseExceptionObject(node, exception); } } } @@ -461,7 +462,6 @@ public int hashCode() { } @Builtin(name = "tregex_init_cache", minNumOfPositionalArgs = 3) - @TypeSystemReference(PythonArithmeticTypes.class) @GenerateNodeFactory abstract static class TRegexInitCache extends PythonTernaryBuiltinNode { @@ -471,14 +471,13 @@ Object call(VirtualFrame frame, PythonObject patternObject, Object pattern, Obje @Cached PyLongAsIntNode flagsToIntNode, @Cached HiddenAttr.WriteNode writeCacheNode) { int flagsStr = flagsToIntNode.execute(frame, inliningTarget, flags); - TRegexCache tRegexCache = new TRegexCache(pattern, flagsStr); + TRegexCache tRegexCache = new TRegexCache(inliningTarget, pattern, flagsStr); writeCacheNode.execute(inliningTarget, patternObject, HiddenAttr.TREGEX_CACHE, tRegexCache); return PNone.NONE; } } @Builtin(name = "tregex_compile", minNumOfPositionalArgs = 3) - @TypeSystemReference(PythonArithmeticTypes.class) @GenerateNodeFactory @ImportStatic(PythonMethod.class) abstract static class TRegexCompile extends PythonTernaryBuiltinNode { @@ -513,7 +512,7 @@ Object localeNonSensitive(PythonObject pattern, PythonMethod method, boolean mus if (tRegex != null) { return tRegex; } else { - return tRegexCache.compile(getContext(), method, mustAdvance, null); + return tRegexCache.compile(this, getContext(), method, mustAdvance, null); } } @@ -532,7 +531,7 @@ Object localeSensitive(VirtualFrame frame, PythonObject pattern, PythonMethod me if (tRegex != null) { return tRegex; } else { - return tRegexCache.compile(getContext(), method, mustAdvance, locale); + return tRegexCache.compile(this, getContext(), method, mustAdvance, locale); } } @@ -558,32 +557,26 @@ abstract static class RECheckInputTypeNode extends Node { public abstract void execute(VirtualFrame frame, Object input, boolean expectBytes); @Specialization - static void check(VirtualFrame frame, Object input, boolean expectBytes, + static void check(Object input, boolean expectBytes, @Bind("this") Node inliningTarget, - @Cached("getSupportedBinaryInputTypes()") PTuple supportedBinaryInputTypes, - @Cached BuiltinFunctions.IsInstanceNode isStringNode, - @Cached BuiltinFunctions.IsInstanceNode isBytesNode, - @Cached InlinedConditionProfile unsupportedInputTypeProfile, - @Cached InlinedConditionProfile unexpectedInputTypeProfile, - @Cached PRaiseNode.Lazy raiseNode) { - boolean isString = (boolean) isStringNode.execute(frame, input, PythonBuiltinClassType.PString); - boolean isBytes = !isString && (boolean) isBytesNode.execute(frame, input, supportedBinaryInputTypes); - if (unsupportedInputTypeProfile.profile(inliningTarget, !isString && !isBytes)) { - throw raiseNode.get(inliningTarget).raise(TypeError, T_UNSUPPORTED_INPUT_TYPE); - } - if (unexpectedInputTypeProfile.profile(inliningTarget, expectBytes != isBytes)) { + @Cached PyUnicodeCheckNode unicodeCheckNode, + @Cached BytesNodes.BytesLikeCheck bytesLikeCheck, + @Cached PRaiseNode unexpectedStrRaise, + @Cached PRaiseNode unexpectedBytesRaise, + @Cached PRaiseNode unexpectedTypeRaise) { + if (unicodeCheckNode.execute(inliningTarget, input)) { if (expectBytes) { - throw raiseNode.get(inliningTarget).raise(TypeError, T_UNEXPECTED_STR); - } else { - throw raiseNode.get(inliningTarget).raise(TypeError, T_UNEXPECTED_BYTES); + throw unexpectedStrRaise.raise(inliningTarget, TypeError, T_UNEXPECTED_STR); } + return; } - } - - @NeverDefault - protected PTuple getSupportedBinaryInputTypes() { - return PythonObjectFactory.getUncached().createTuple(new Object[]{PythonBuiltinClassType.PBytes, PythonBuiltinClassType.PByteArray, PythonBuiltinClassType.PMMap, - PythonBuiltinClassType.PMemoryView, PythonBuiltinClassType.PArray}); + if (bytesLikeCheck.execute(inliningTarget, input) || input instanceof PMMap || input instanceof PMemoryView || input instanceof PArray) { + if (!expectBytes) { + throw unexpectedBytesRaise.raise(inliningTarget, TypeError, T_UNEXPECTED_BYTES); + } + return; + } + throw unexpectedTypeRaise.raise(inliningTarget, TypeError, T_UNSUPPORTED_INPUT_TYPE); } } @@ -598,7 +591,7 @@ abstract static class CreateMatchFromTRegexResultNode extends PNodeWithContext { @Specialization static Object createMatch(VirtualFrame frame, Node inliningTarget, Object pattern, int pos, int endPos, Object regexResult, Object input, - @Cached("lookupMatchConstructor()") Object matchConstructor, + @Cached GetMatchConstructorNode getConstructor, @Cached InlinedConditionProfile matchProfile, @CachedLibrary(limit = "1") InteropLibrary libResult, @Cached PyObjectLookupAttr lookupIndexGroupNode, @@ -606,7 +599,7 @@ static Object createMatch(VirtualFrame frame, Node inliningTarget, Object patter try { if (matchProfile.profile(inliningTarget, (boolean) libResult.readMember(regexResult, "isMatch"))) { Object indexGroup = lookupIndexGroupNode.execute(frame, inliningTarget, pattern, T__PATTERN__INDEXGROUP); - return constructResultNode.execute(frame, matchConstructor, pattern, pos, endPos, regexResult, input, indexGroup); + return constructResultNode.execute(frame, getConstructor.execute(inliningTarget), pattern, pos, endPos, regexResult, input, indexGroup); } else { return PNone.NONE; } @@ -615,16 +608,35 @@ static Object createMatch(VirtualFrame frame, Node inliningTarget, Object patter } } - @TruffleBoundary - @NeverDefault - protected Object lookupMatchConstructor() { - PythonModule module = getContext().lookupBuiltinModule(BuiltinNames.T__SRE); - return PyObjectLookupAttr.executeUncached(module, T_MATCH_CONSTRUCTOR); + @GenerateInline + @GenerateCached(false) + abstract static class GetMatchConstructorNode extends PNodeWithContext { + public abstract Object execute(Node inliningTarget); + + @Specialization(guards = "isSingleContext()") + static Object doSingleContext( + @Cached("lookupMatchConstructor()") Object constructor) { + return constructor; + } + + @Specialization(replaces = "doSingleContext") + static Object doRead( + @Bind PythonContext context, + @Cached ReadAttributeFromObjectNode read) { + PythonModule module = context.lookupBuiltinModule(BuiltinNames.T__SRE); + return read.execute(module, T_MATCH_CONSTRUCTOR); + } + + @TruffleBoundary + @NeverDefault + protected static Object lookupMatchConstructor() { + PythonModule module = PythonContext.get(null).lookupBuiltinModule(BuiltinNames.T__SRE); + return PyObjectLookupAttr.executeUncached(module, T_MATCH_CONSTRUCTOR); + } } } @Builtin(name = "tregex_search", minNumOfPositionalArgs = 6) - @TypeSystemReference(PythonArithmeticTypes.class) @GenerateNodeFactory @ImportStatic(PythonMethod.class) abstract static class TRegexSearch extends PythonSenaryBuiltinNode { @@ -782,7 +794,6 @@ private PyObjectGetItem getGetItemNode() { } @Builtin(name = "tregex_call_exec", minNumOfPositionalArgs = 3) - @TypeSystemReference(PythonArithmeticTypes.class) @GenerateNodeFactory abstract static class TRegexCallExec extends PythonTernaryBuiltinNode { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SSLModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SSLModuleBuiltins.java index e03d62c3fd..c72e2d4d63 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SSLModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SSLModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -67,8 +67,8 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; +import com.oracle.graal.python.runtime.PythonContext; import org.bouncycastle.util.encoders.DecoderException; -import org.graalvm.nativeimage.ImageInfo; import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; @@ -98,7 +98,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.TruffleFile; import com.oracle.truffle.api.TruffleLogger; @@ -163,10 +163,10 @@ protected List> getNodeFa return SSLModuleBuiltinsFactory.getFactories(); } - private static synchronized void loadDefaults() { - if (ImageInfo.inImageBuildtimeCode()) { + private static synchronized void loadDefaults(PythonContext pythonContext) { + if (pythonContext.getEnv().isPreInitialization()) { // The values are dependent on system properties, don't bake them into the image - throw new AssertionError("SSL module initialized at build time"); + throw new AssertionError("SSL module initialized during pre-initialization"); } try { SSLContext context = SSLContext.getInstance("TLS"); @@ -218,11 +218,10 @@ private static boolean tryProtocolAvailability(SSLContext context, SSLProtocol p @Override public void postInitialize(Python3Core core) { super.postInitialize(core); - loadDefaults(); + loadDefaults(core.getContext()); PythonModule module = core.lookupBuiltinModule(T__SSL); - PythonObjectFactory factory = core.factory(); module.setAttribute(tsLiteral("OPENSSL_VERSION_NUMBER"), 0); - PTuple versionInfo = factory.createTuple(new int[]{0, 0, 0, 0, 0}); + PTuple versionInfo = PFactory.createTuple(core.getLanguage(), new int[]{0, 0, 0, 0, 0}); module.setAttribute(tsLiteral("OPENSSL_VERSION_INFO"), versionInfo); module.setAttribute(tsLiteral("OPENSSL_VERSION"), toTruffleStringUncached("GraalVM JSSE")); module.setAttribute(tsLiteral("_DEFAULT_CIPHERS"), T_DEFAULT_CIPHER_STRING); @@ -310,15 +309,15 @@ abstract static class Txt2ObjNode extends PythonBinaryClinicBuiltinNode { static Object txt2obj(TruffleString txt, boolean name, @Bind("this") Node inliningTarget, @Cached TruffleString.EqualNode equalNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { // TODO implement properly if (equalNode.execute(T_OID_TLS_SERVER, txt, TS_ENCODING)) { - return factory.createTuple(new Object[]{129, T_SERVER_AUTH, T_TLS_WEB_SERVER_AUTHENTICATION, txt}); + return PFactory.createTuple(language, new Object[]{129, T_SERVER_AUTH, T_TLS_WEB_SERVER_AUTHENTICATION, txt}); } else if (equalNode.execute(T_OID_TLS_CLIENT, txt, TS_ENCODING)) { - return factory.createTuple(new Object[]{130, T_CLIENT_AUTH, T_TLS_WEB_CLIENT_AUTHENTICATION, txt}); + return PFactory.createTuple(language, new Object[]{130, T_CLIENT_AUTH, T_TLS_WEB_CLIENT_AUTHENTICATION, txt}); } - throw raiseNode.get(inliningTarget).raise(NotImplementedError); + throw raiseNode.raise(inliningTarget, NotImplementedError); } @Override @@ -333,8 +332,8 @@ abstract static class Nid2ObjNode extends PythonUnaryBuiltinNode { @Specialization @SuppressWarnings("unused") static Object nid2obj(Object nid, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(NotImplementedError); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError); } } @@ -343,8 +342,8 @@ static Object nid2obj(Object nid, abstract static class RandStatusNode extends PythonBuiltinNode { @Specialization static Object randStatus( - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(NotImplementedError); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError); } } @@ -354,8 +353,8 @@ abstract static class RandAddNode extends PythonBinaryBuiltinNode { @Specialization @SuppressWarnings("unused") static Object randAdd(Object string, Object entropy, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(NotImplementedError); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError); } } @@ -365,8 +364,8 @@ abstract static class RandBytesNode extends PythonUnaryBuiltinNode { @Specialization @SuppressWarnings("unused") static Object randBytes(Object n, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(NotImplementedError); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError); } } @@ -376,8 +375,8 @@ abstract static class RandPseudoBytesNode extends PythonUnaryBuiltinNode { @Specialization @SuppressWarnings("unused") static Object randPseudoBytes(Object n, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(NotImplementedError); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError); } } @@ -389,11 +388,11 @@ abstract static class GetDefaultVerifyPathsNode extends PythonBuiltinNode { @Specialization Object getDefaultPaths( - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { // there is no default location given by graalpython // in case the env variables SSL_CERT_FILE or SSL_CERT_DIR // are provided, ssl.py#get_default_verify_paths will take care of it - return factory.createTuple(new Object[]{T_SSL_CERT_FILE, T_EMPTY_STRING, T_SSL_CERT_DIR, T_EMPTY_STRING}); + return PFactory.createTuple(language, new Object[]{T_SSL_CERT_FILE, T_EMPTY_STRING, T_SSL_CERT_DIR, T_EMPTY_STRING}); } } @@ -409,8 +408,8 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static Object fail(TruffleString argument, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PermissionError); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PermissionError); } } @@ -438,7 +437,7 @@ private Object decode(TruffleFile file) throws PException { if (!(cert instanceof X509Certificate)) { throw PConstructAndRaiseNode.raiseUncachedSSLError(SSL_ERR_DECODING_PEM_FILE_UNEXPECTED_S, cert.getClass().getName()); } - return CertUtils.decodeCertificate(getContext().factory(), (X509Certificate) certs.get(0)); + return CertUtils.decodeCertificate((X509Certificate) certs.get(0), PythonLanguage.get(null)); } catch (IOException | DecoderException ex) { throw PConstructAndRaiseNode.raiseUncachedSSLError(SSL_CANT_OPEN_FILE_S, ex.toString()); } catch (CertificateException | CRLException ex) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SelectModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SelectModuleBuiltins.java index 1214db605d..28281d1d0d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SelectModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SelectModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,6 +46,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -74,7 +75,7 @@ import com.oracle.graal.python.runtime.PosixSupportLibrary.SelectResult; import com.oracle.graal.python.runtime.PosixSupportLibrary.Timeval; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.graal.python.util.ArrayBuilder; import com.oracle.graal.python.util.IntArrayBuilder; @@ -132,8 +133,8 @@ static PTuple doGeneric(VirtualFrame frame, Object rlist, Object wlist, Object x @Cached InlinedBranchProfile notSelectableBranch, @Cached GilNode gil, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { ObjAndFDList readFDs = seq2set(frame, inliningTarget, rlist, sizeNode, asFileDescriptor, callGetItemNode, constructListNode, raiseNode); ObjAndFDList writeFDs = seq2set(frame, inliningTarget, wlist, sizeNode, asFileDescriptor, callGetItemNode, constructListNode, raiseNode); ObjAndFDList xFDs = seq2set(frame, inliningTarget, xlist, sizeNode, asFileDescriptor, callGetItemNode, constructListNode, raiseNode); @@ -143,7 +144,7 @@ static PTuple doGeneric(VirtualFrame frame, Object rlist, Object wlist, Object x isNotNoneTimeout.enter(inliningTarget); timeoutval = TimeUtils.pyTimeAsTimeval(pyTimeFromObjectNode.execute(frame, inliningTarget, timeout, RoundType.TIMEOUT, SEC_TO_NS)); if (timeoutval.getSeconds() < 0) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.MUST_BE_NON_NEGATIVE, "timeout"); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.MUST_BE_NON_NEGATIVE, "timeout"); } } @@ -161,18 +162,18 @@ static PTuple doGeneric(VirtualFrame frame, Object rlist, Object wlist, Object x // GraalPython hack: if one of the channels is not selectable (can happen only in // the emulated mode), we just return everything. notSelectableBranch.enter(inliningTarget); - return factory.createTuple(new Object[]{rlist, wlist, xlist}); + return PFactory.createTuple(language, new Object[]{rlist, wlist, xlist}); } - return factory.createTuple(new PList[]{ - toList(result.getReadFds(), readFDs, factory), - toList(result.getWriteFds(), writeFDs, factory), - toList(result.getErrorFds(), xFDs, factory)}); + return PFactory.createTuple(language, new PList[]{ + toList(result.getReadFds(), readFDs, language), + toList(result.getWriteFds(), writeFDs, language), + toList(result.getErrorFds(), xFDs, language)}); } /** * Also maps the returned FDs back to their original Python level objects. */ - private static PList toList(boolean[] result, ObjAndFDList fds, PythonObjectFactory factory) { + private static PList toList(boolean[] result, ObjAndFDList fds, PythonLanguage language) { Object[] resultObjs = new Object[result.length]; int resultObjsIdx = 0; for (int i = 0; i < fds.fds.length; i++) { @@ -180,12 +181,12 @@ private static PList toList(boolean[] result, ObjAndFDList fds, PythonObjectFact resultObjs[resultObjsIdx++] = fds.objects[i]; } } - return factory.createList(PythonUtils.arrayCopyOf(resultObjs, resultObjsIdx)); + return PFactory.createList(language, PythonUtils.arrayCopyOf(resultObjs, resultObjsIdx)); } private static ObjAndFDList seq2set(VirtualFrame frame, Node inliningTarget, Object sequence, PyObjectSizeNode sizeNode, PyObjectAsFileDescriptor asFileDescriptor, PyObjectGetItem callGetItemNode, - FastConstructListNode constructListNode, PRaiseNode.Lazy raiseNode) { + FastConstructListNode constructListNode, PRaiseNode raiseNode) { // We cannot assume any size of those two arrays, because the sequence may change as a // side effect of the invocation of fileno. We also need to call PyObjectSizeNode // repeatedly in the loop condition @@ -197,7 +198,7 @@ private static ObjAndFDList seq2set(VirtualFrame frame, Node inliningTarget, Obj objects.add(pythonObject); int fd = asFileDescriptor.execute(frame, inliningTarget, pythonObject); if (fd >= FD_SETSIZE.value) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.FILE_DESCRIPTOR_OUT_OF_RANGE_IN_SELECT); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.FILE_DESCRIPTOR_OUT_OF_RANGE_IN_SELECT); } fds.add(fd); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SignalModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SignalModuleBuiltins.java index 43b55adaa2..47853da8ef 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SignalModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SignalModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -57,8 +57,7 @@ import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; -import org.graalvm.nativeimage.ImageInfo; - +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -90,7 +89,7 @@ import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -163,7 +162,8 @@ public void postInitialize(Python3Core core) { } } - if (PosixSupportLibrary.getUncached().getBackend(core.getContext().getPosixSupport()).equalsUncached(T_JAVA, TS_ENCODING)) { + var context = core.getContext(); + if (PosixSupportLibrary.getUncached().getBackend(context.getPosixSupport()).equalsUncached(T_JAVA, TS_ENCODING)) { for (EmulatedSignal signal : EmulatedSignal.values()) { if (signalModule.getAttribute(signal.name) == PNone.NO_VALUE) { moduleData.signals.put(signal.name(), signal.number); @@ -172,7 +172,7 @@ public void postInitialize(Python3Core core) { } } - core.getContext().registerAsyncAction(() -> { + context.registerAsyncAction(() -> { SignalTriggerAction poll = moduleData.signalQueue.poll(); if (PythonOptions.AUTOMATIC_ASYNC_ACTIONS) { try { @@ -187,7 +187,7 @@ public void postInitialize(Python3Core core) { return poll; }); - if (!ImageInfo.inImageBuildtimeCode() && core.getContext().getOption(PythonOptions.InstallSignalHandlers)) { + if (!context.getEnv().isPreInitialization() && context.getOption(PythonOptions.InstallSignalHandlers)) { Object defaultSigintHandler = signalModule.getAttribute(T_DEFAULT_INT_HANDLER); assert defaultSigintHandler != PNone.NO_VALUE; SignalNode.signal(null, new Signal("INT").getNumber(), defaultSigintHandler, moduleData); @@ -241,7 +241,7 @@ public int frameIndex() { abstract static class ValidSignalsNode extends PythonBuiltinNode { @Specialization static Object validSignals( - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { int signalCount = 0; for (int i = 0; i < Signals.SIGNAL_NAMES.length; i++) { if (Signals.SIGNAL_NAMES[i] != null) { @@ -256,7 +256,7 @@ static Object validSignals( } } - return factory.createTuple(validSignals); + return PFactory.createTuple(language, validSignals); } } @@ -333,8 +333,8 @@ protected ArgumentClinicProvider getArgumentClinic() { abstract static class DefaultIntHandlerNode extends PythonBuiltinNode { @Specialization static Object defaultIntHandler(@SuppressWarnings("unused") Object[] args, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonErrorType.KeyboardInterrupt); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.KeyboardInterrupt); } } @@ -375,7 +375,7 @@ static Object signal(Node raisingNode, int signum, Object handler, ModuleData da data.signalSema.release(); }); } catch (IllegalArgumentException e) { - throw PRaiseNode.raiseUncached(raisingNode, PythonErrorType.ValueError, e); + throw PRaiseNode.raiseStatic(raisingNode, PythonErrorType.ValueError, e); } Object result = handlerToPython(oldHandler, signum, data); data.signalHandlers.put(signum, handler); @@ -392,7 +392,7 @@ private static Object signal(Node raisingNode, int signum, int id, ModuleData da oldHandler = Signals.setSignalHandler(signum, id); } } catch (IllegalArgumentException e) { - throw PRaiseNode.raiseUncached(raisingNode, PythonErrorType.TypeError, ErrorMessages.SIGNAL_MUST_BE_SIGIGN_SIGDFL_OR_CALLABLE_OBJ); + throw PRaiseNode.raiseStatic(raisingNode, PythonErrorType.TypeError, ErrorMessages.SIGNAL_MUST_BE_SIGIGN_SIGDFL_OR_CALLABLE_OBJ); } Object result = handlerToPython(oldHandler, signum, data); data.signalHandlers.remove(signum); @@ -464,14 +464,14 @@ Object doIt(VirtualFrame frame, PythonModule self, int which, Object seconds, Ob @Bind("this") Node inliningTarget, @Cached PyTimeFromObjectNode timeFromObjectNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { ModuleData moduleData = self.getModuleState(ModuleData.class); long usDelay = toMicroseconds(frame, inliningTarget, seconds, timeFromObjectNode); long usInterval = toMicroseconds(frame, inliningTarget, interval, timeFromObjectNode); if (which != ITIMER_REAL) { throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, OSErrorEnum.EINVAL); } - PTuple resultTuple = GetitimerNode.createResultTuple(factory, moduleData); + PTuple resultTuple = GetitimerNode.createResultTuple(language, moduleData); setitimer(moduleData, usDelay, usInterval); return resultTuple; } @@ -532,18 +532,18 @@ protected ArgumentClinicProvider getArgumentClinic() { static Object doIt(VirtualFrame frame, PythonModule self, int which, @Bind("this") Node inliningTarget, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { ModuleData moduleData = self.getModuleState(ModuleData.class); if (which != ITIMER_REAL) { throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, OSErrorEnum.EINVAL); } - return createResultTuple(factory, moduleData); + return createResultTuple(language, moduleData); } - static PTuple createResultTuple(PythonObjectFactory factory, ModuleData moduleData) { + static PTuple createResultTuple(PythonLanguage language, ModuleData moduleData) { long oldInterval = moduleData.itimerInterval; long oldDelay = getOldDelay(moduleData); - return factory.createTuple(new Object[]{oldDelay / (double) SEC_TO_US, oldInterval / (double) SEC_TO_US}); + return PFactory.createTuple(language, new Object[]{oldDelay / (double) SEC_TO_US, oldInterval / (double) SEC_TO_US}); } @TruffleBoundary diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java index f9e39499f6..736785ab08 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -67,6 +67,7 @@ import java.nio.ByteOrder; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -80,7 +81,6 @@ import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum; -import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.socket.SocketNodes; @@ -99,7 +99,6 @@ import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; @@ -116,11 +115,11 @@ import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException; import com.oracle.graal.python.runtime.PosixSupportLibrary.UniversalSockAddr; import com.oracle.graal.python.runtime.PosixSupportLibrary.UniversalSockAddrLibrary; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.TimeUtils; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -153,7 +152,7 @@ static int findProtocolByName(Node raisingNode, String protocolName) { return constant.getValueIfDefined(); } } - throw PRaiseNode.raiseUncached(raisingNode, OSError, ErrorMessages.SERVICE_PROTO_NOT_FOUND); + throw PRaiseNode.raiseStatic(raisingNode, OSError, ErrorMessages.SERVICE_PROTO_NOT_FOUND); } @Override @@ -206,26 +205,6 @@ private void addConstant(PosixConstants.IntConstant constant) { } } - // socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None) - @Builtin(name = "socket", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PSocket) - @GenerateNodeFactory - public abstract static class SocketNode extends PythonVarargsBuiltinNode { - // All the "real" work is done by __init__ - @Specialization - Object socket(Object cls) { - return factory().createSocket(cls); - } - - @Override - public Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported { - if (self == PNone.NO_VALUE && arguments.length > 0) { - return socket(arguments[0]); - } - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw VarargsBuiltinDirectInvocationNotSupported.INSTANCE; - } - } - @Builtin(name = "getdefaulttimeout", minNumOfPositionalArgs = 1, declaresExplicitSelf = true) @GenerateNodeFactory public abstract static class GetDefaultTimeoutNode extends PythonUnaryBuiltinNode { @@ -253,8 +232,9 @@ static Object set(VirtualFrame frame, PythonModule module, Object value, @GenerateNodeFactory public abstract static class GetHostnameNode extends PythonBuiltinNode { @Specialization - TruffleString doGeneric(VirtualFrame frame, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + static TruffleString doGeneric(VirtualFrame frame, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Bind("this") Node inliningTarget, @Cached SysModuleBuiltins.AuditNode auditNode, @Cached GilNode gil, @@ -263,7 +243,7 @@ TruffleString doGeneric(VirtualFrame frame, try { gil.release(true); try { - return posixLib.getPathAsString(getPosixSupport(), posixLib.gethostname(getPosixSupport())); + return posixLib.getPathAsString(context.getPosixSupport(), posixLib.gethostname(context.getPosixSupport())); } finally { gil.acquire(); } @@ -277,8 +257,9 @@ TruffleString doGeneric(VirtualFrame frame, @GenerateNodeFactory public abstract static class GetHostByAddrNode extends PythonUnaryBuiltinNode { @Specialization - Object doGeneric(VirtualFrame frame, Object ip, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + static Object doGeneric(VirtualFrame frame, Object ip, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @CachedLibrary(limit = "1") AddrInfoCursorLibrary addrInfoCursorLib, @CachedLibrary(limit = "1") UniversalSockAddrLibrary sockAddrLibrary, @Bind("this") Node inliningTarget, @@ -288,8 +269,7 @@ Object doGeneric(VirtualFrame frame, Object ip, @Cached SocketNodes.MakeIpAddrNode makeIpAddrNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, @Cached SysModuleBuiltins.AuditNode auditNode, - @Cached GilNode gil, - @Cached PythonObjectFactory factory) { + @Cached GilNode gil) { /* * TODO this uses getnameinfo and getaddrinfo to emulate the legacy gethostbyaddr. We * might want to use the legacy API in the future @@ -298,8 +278,8 @@ Object doGeneric(VirtualFrame frame, Object ip, UniversalSockAddr addr = setIpAddrNode.execute(frame, idnaConverter.execute(frame, ip), AF_UNSPEC.value); int family = sockAddrLibrary.getFamily(addr); try { - Object[] getnameinfoResult = posixLib.getnameinfo(getPosixSupport(), addr, NI_NAMEREQD.value); - TruffleString hostname = posixLib.getPathAsString(getPosixSupport(), getnameinfoResult[0]); + Object[] getnameinfoResult = posixLib.getnameinfo(context.getPosixSupport(), addr, NI_NAMEREQD.value); + TruffleString hostname = posixLib.getPathAsString(context.getPosixSupport(), getnameinfoResult[0]); SequenceStorage storage = new ObjectSequenceStorage(5); @@ -307,7 +287,7 @@ Object doGeneric(VirtualFrame frame, Object ip, AddrInfoCursor cursor; gil.release(true); try { - cursor = posixLib.getaddrinfo(getPosixSupport(), getnameinfoResult[0], posixLib.createPathFromString(getPosixSupport(), T_ZERO), + cursor = posixLib.getaddrinfo(context.getPosixSupport(), getnameinfoResult[0], posixLib.createPathFromString(context.getPosixSupport(), T_ZERO), family, 0, 0, 0); } finally { gil.acquire(); @@ -323,7 +303,8 @@ Object doGeneric(VirtualFrame frame, Object ip, } catch (GetAddrInfoException e1) { // Ignore failing forward lookup and return at least the hostname } - return factory.createTuple(new Object[]{hostname, factory.createList(), factory.createList(storage)}); + PythonLanguage language = context.getLanguage(inliningTarget); + return PFactory.createTuple(language, new Object[]{hostname, PFactory.createList(language), PFactory.createList(language, storage)}); } catch (GetAddrInfoException e) { // TODO convert error code from gaierror to herror throw constructAndRaiseNode.get(inliningTarget).executeWithArgsOnly(frame, SocketHError, new Object[]{1, e.getMessageAsTruffleString()}); @@ -340,21 +321,21 @@ protected static IdnaFromStringOrBytesConverterNode createIdnaConverter() { @GenerateNodeFactory public abstract static class GetHostByNameNode extends PythonUnaryBuiltinNode { @Specialization - TruffleString getHostByName(VirtualFrame frame, Object nameObj, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + static TruffleString getHostByName(VirtualFrame frame, Object nameObj, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @CachedLibrary(limit = "1") UniversalSockAddrLibrary addrLib, @Bind("this") Node inliningTarget, @Cached("createIdnaConverter()") IdnaFromStringOrBytesConverterNode idnaConverter, @Cached SysModuleBuiltins.AuditNode auditNode, @Cached SocketNodes.SetIpAddrNode setIpAddrNode, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { byte[] name = idnaConverter.execute(frame, nameObj); - auditNode.audit(inliningTarget, "socket.gethostbyname", factory.createTuple(new Object[]{nameObj})); + auditNode.audit(inliningTarget, "socket.gethostbyname", PFactory.createTuple(context.getLanguage(inliningTarget), new Object[]{nameObj})); UniversalSockAddr addr = setIpAddrNode.execute(frame, name, AF_INET.value); Inet4SockAddr inet4SockAddr = addrLib.asInet4SockAddr(addr); try { - return posixLib.getPathAsString(getPosixSupport(), posixLib.inet_ntop(getPosixSupport(), AF_INET.value, inet4SockAddr.getAddressAsBytes())); + return posixLib.getPathAsString(context.getPosixSupport(), posixLib.inet_ntop(context.getPosixSupport(), AF_INET.value, inet4SockAddr.getAddressAsBytes())); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } @@ -370,35 +351,36 @@ protected static IdnaFromStringOrBytesConverterNode createIdnaConverter() { @GenerateNodeFactory public abstract static class GetHostByNameExNode extends PythonUnaryBuiltinNode { @Specialization - Object get(VirtualFrame frame, Object nameObj, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + static Object get(VirtualFrame frame, Object nameObj, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @CachedLibrary(limit = "1") UniversalSockAddrLibrary addrLib, @CachedLibrary(limit = "1") AddrInfoCursorLibrary addrInfoCursorLib, @Bind("this") Node inliningTarget, @Cached("createIdnaConverter()") IdnaFromStringOrBytesConverterNode idnaConverter, @Cached SysModuleBuiltins.AuditNode auditNode, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { byte[] name = idnaConverter.execute(frame, nameObj); // The event name is really without the _ex, it's not a copy-paste error - auditNode.audit(inliningTarget, "socket.gethostbyname", factory.createTuple(new Object[]{nameObj})); + auditNode.audit(inliningTarget, "socket.gethostbyname", PFactory.createTuple(context.getLanguage(inliningTarget), new Object[]{nameObj})); /* * TODO this uses getaddrinfo to emulate the legacy gethostbyname. It doesn't support * aliases and multiple addresses. We might want to use the legacy gethostbyname_r API * in the future */ try { - AddrInfoCursor cursor = posixLib.getaddrinfo(getPosixSupport(), posixLib.createPathFromBytes(getPosixSupport(), name), + PosixSupport posixSupport = context.getPosixSupport(); + AddrInfoCursor cursor = posixLib.getaddrinfo(posixSupport, posixLib.createPathFromBytes(posixSupport, name), null, AF_INET.value, 0, 0, AI_CANONNAME.value); try { - TruffleString canonName = posixLib.getPathAsString(getPosixSupport(), addrInfoCursorLib.getCanonName(cursor)); + TruffleString canonName = posixLib.getPathAsString(posixSupport, addrInfoCursorLib.getCanonName(cursor)); Inet4SockAddr inet4SockAddr = addrLib.asInet4SockAddr(addrInfoCursorLib.getSockAddr(cursor)); - TruffleString addr = posixLib.getPathAsString(getPosixSupport(), posixLib.inet_ntop(getPosixSupport(), AF_INET.value, inet4SockAddr.getAddressAsBytes())); + TruffleString addr = posixLib.getPathAsString(posixSupport, posixLib.inet_ntop(posixSupport, AF_INET.value, inet4SockAddr.getAddressAsBytes())); // getaddrinfo doesn't support aliases - PList aliases = factory.createList(); + PList aliases = PFactory.createList(context.getLanguage(inliningTarget)); // we support just one address for now - PList addrs = factory.createList(new Object[]{addr}); - return factory.createTuple(new Object[]{canonName, aliases, addrs}); + PList addrs = PFactory.createList(context.getLanguage(inliningTarget), new Object[]{addr}); + return PFactory.createTuple(context.getLanguage(inliningTarget), new Object[]{canonName, aliases, addrs}); } finally { addrInfoCursorLib.release(cursor); } @@ -424,13 +406,14 @@ public abstract static class GetServByNameNode extends PythonBinaryClinicBuiltin static Object getServByName(TruffleString serviceName, Object protocolNameObj, @Bind("this") Node inliningTarget, @Cached InlinedConditionProfile noneProtocol, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @CachedLibrary(limit = "1") AddrInfoCursorLibrary addrInfoCursorLib, @CachedLibrary(limit = "1") UniversalSockAddrLibrary sockAddrLibrary, @Cached TruffleString.ToJavaStringNode toJavaStringNode, @Cached SysModuleBuiltins.AuditNode auditNode, @Cached GilNode gil, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleString protocolName; if (noneProtocol.profile(inliningTarget, PGuards.isNoValue(protocolNameObj))) { protocolName = null; @@ -454,7 +437,7 @@ static Object getServByName(TruffleString serviceName, Object protocolNameObj, gil.release(true); AddrInfoCursor cursor; try { - PosixSupport posixSupport = PosixSupport.get(inliningTarget); + PosixSupport posixSupport = context.getPosixSupport(); cursor = posixLib.getaddrinfo(posixSupport, null, posixLib.createPathFromString(posixSupport, serviceName), AF_INET.value, 0, protocol, 0); } finally { gil.acquire(); @@ -466,7 +449,7 @@ static Object getServByName(TruffleString serviceName, Object protocolNameObj, addrInfoCursorLib.release(cursor); } } catch (GetAddrInfoException e) { - throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.SERVICE_PROTO_NOT_FOUND); + throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.SERVICE_PROTO_NOT_FOUND); } } @@ -492,7 +475,7 @@ Object getServByPort(int port, Object protocolNameObj, @Cached TruffleString.EqualNode equalNode, @Cached SysModuleBuiltins.AuditNode auditNode, @Cached GilNode gil, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleString protocolName; if (nonProtocol.profile(inliningTarget, PGuards.isNoValue(protocolNameObj))) { protocolName = null; @@ -506,7 +489,7 @@ Object getServByPort(int port, Object protocolNameObj, * the legacy API in the future */ if (port < 0 || port > 0xffff) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.S_PORT_RANGE, "getservbyport"); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.S_PORT_RANGE, "getservbyport"); } auditNode.audit(inliningTarget, "socket.getservbyport", port, protocolName != null ? protocolName : ""); @@ -526,14 +509,14 @@ Object getServByPort(int port, Object protocolNameObj, gil.acquire(); } } catch (GetAddrInfoException e) { - throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.SERVICE_PROTO_NOT_FOUND); + throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.SERVICE_PROTO_NOT_FOUND); } } @TruffleBoundary private void checkName(TruffleString name) { if (name.toJavaStringUncached().matches("^\\d+$")) { - throw PRaiseNode.raiseUncached(this, OSError, ErrorMessages.SERVICE_PROTO_NOT_FOUND); + throw PRaiseNode.raiseStatic(this, OSError, ErrorMessages.SERVICE_PROTO_NOT_FOUND); } } @@ -550,7 +533,8 @@ public abstract static class GetNameInfoNode extends PythonBinaryClinicBuiltinNo @Specialization static Object getNameInfo(VirtualFrame frame, PTuple sockaddr, int flags, @Bind("this") Node inliningTarget, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @CachedLibrary(limit = "1") AddrInfoCursorLibrary addrInfoCursorLib, @CachedLibrary(limit = "1") UniversalSockAddrLibrary sockAddrLibrary, @Cached GilNode gil, @@ -560,12 +544,11 @@ static Object getNameInfo(VirtualFrame frame, PTuple sockaddr, int flags, @Cached SysModuleBuiltins.AuditNode auditNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, @Cached TruffleString.FromLongNode fromLongNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { SequenceStorage addr = sockaddr.getSequenceStorage(); int addrLen = addr.length(); if (addrLen < 2 || addrLen > 4) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ILLEGAL_SOCKET_ADDR_ARG, "getnameinfo()"); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ILLEGAL_SOCKET_ADDR_ARG, "getnameinfo()"); } TruffleString address; int port, flowinfo = 0, scopeid = 0; @@ -573,13 +556,13 @@ static Object getNameInfo(VirtualFrame frame, PTuple sockaddr, int flags, try { address = castAddress.execute(inliningTarget, arg0); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MUST_BE_STR_NOT_P, arg0); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_STR_NOT_P, arg0); } port = asIntNode.execute(frame, inliningTarget, getItem.execute(inliningTarget, addr, 1)); if (addrLen > 2) { flowinfo = asIntNode.execute(frame, inliningTarget, getItem.execute(inliningTarget, addr, 2)); if (flowinfo < 0 || flowinfo > 0xfffff) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.S_FLOWINFO_RANGE, "getnameinfo"); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.S_FLOWINFO_RANGE, "getnameinfo"); } } if (addrLen > 3) { @@ -593,7 +576,7 @@ static Object getNameInfo(VirtualFrame frame, PTuple sockaddr, int flags, int family; // TODO getaddrinfo lock? gil.release(true); - PosixSupport posixSupport = PosixSupport.get(inliningTarget); + PosixSupport posixSupport = context.getPosixSupport(); try { AddrInfoCursor cursor = posixLib.getaddrinfo(posixSupport, posixLib.createPathFromString(posixSupport, address), posixLib.createPathFromString(posixSupport, fromLongNode.execute(port, TS_ENCODING, false)), @@ -602,7 +585,7 @@ static Object getNameInfo(VirtualFrame frame, PTuple sockaddr, int flags, family = addrInfoCursorLib.getFamily(cursor); resolvedAddr = addrInfoCursorLib.getSockAddr(cursor); if (addrInfoCursorLib.next(cursor)) { - throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.SOCKADDR_RESOLVED_TO_MULTIPLE_ADDRESSES); + throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.SOCKADDR_RESOLVED_TO_MULTIPLE_ADDRESSES); } } finally { addrInfoCursorLib.release(cursor); @@ -614,19 +597,19 @@ static Object getNameInfo(VirtualFrame frame, PTuple sockaddr, int flags, UniversalSockAddr queryAddr; if (family == AF_INET.value) { if (addrLen != 2) { - throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.IPV4_MUST_BE_2_TUPLE); + throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.IPV4_MUST_BE_2_TUPLE); } queryAddr = posixLib.createUniversalSockAddrInet4(posixSupport, new Inet4SockAddr(port, sockAddrLibrary.asInet4SockAddr(resolvedAddr).getAddress())); } else if (family == AF_INET6.value) { queryAddr = posixLib.createUniversalSockAddrInet6(posixSupport, new Inet6SockAddr(port, sockAddrLibrary.asInet6SockAddr(resolvedAddr).getAddress(), flowinfo, scopeid)); } else { - throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.UNKNOWN_FAMILY); + throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.UNKNOWN_FAMILY); } Object[] getnameinfo = posixLib.getnameinfo(posixSupport, queryAddr, flags); TruffleString host = posixLib.getPathAsString(posixSupport, getnameinfo[0]); TruffleString service = posixLib.getPathAsString(posixSupport, getnameinfo[1]); - return factory.createTuple(new Object[]{host, service}); + return PFactory.createTuple(context.getLanguage(inliningTarget), new Object[]{host, service}); } catch (GetAddrInfoException e) { throw constructAndRaiseNode.get(inliningTarget).executeWithArgsOnly(frame, SocketGAIError, new Object[]{e.getErrorCode(), e.getMessageAsTruffleString()}); } @@ -635,8 +618,8 @@ static Object getNameInfo(VirtualFrame frame, PTuple sockaddr, int flags, @Fallback @SuppressWarnings("unused") static Object error(Object sockaddr, Object flags, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.GETNAMEINFO_ARG1_MUST_BE_TUPLE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.GETNAMEINFO_ARG1_MUST_BE_TUPLE); } @Override @@ -655,7 +638,8 @@ public abstract static class GetAddrInfoNode extends PythonClinicBuiltinNode { @Specialization static Object getAddrInfo(VirtualFrame frame, Object hostObject, Object portObject, int family, int type, int proto, int flags, @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @CachedLibrary(limit = "1") AddrInfoCursorLibrary cursorLib, @Cached InlinedExactClassProfile profile, @Cached("createIdna()") IdnaFromStringOrBytesConverterNode idna, @@ -668,10 +652,9 @@ static Object getAddrInfo(VirtualFrame frame, Object hostObject, Object portObje @Cached SequenceStorageNodes.AppendNode appendNode, @Cached TruffleString.FromLongNode fromLongNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object host = null; - PosixSupport posixSupport = PosixSupport.get(inliningTarget); + PosixSupport posixSupport = context.getPosixSupport(); if (hostObject != PNone.NONE) { host = posixLib.createPathFromBytes(posixSupport, idna.execute(frame, hostObject)); } @@ -687,7 +670,7 @@ static Object getAddrInfo(VirtualFrame frame, Object hostObject, Object portObje } else if (portObject == PNone.NONE) { port = null; } else { - throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.INT_OR_STRING_EXPECTED); + throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.INT_OR_STRING_EXPECTED); } auditNode.audit(inliningTarget, "socket.getaddrinfo", hostObject, portObjectProfiled, family, type, proto, flags); @@ -712,10 +695,11 @@ static Object getAddrInfo(VirtualFrame frame, Object hostObject, Object portObje if (cursorLib.getCanonName(cursor) != null) { canonName = posixLib.getPathAsString(posixSupport, cursorLib.getCanonName(cursor)); } - PTuple tuple = factory.createTuple(new Object[]{cursorLib.getFamily(cursor), cursorLib.getSockType(cursor), cursorLib.getProtocol(cursor), canonName, addr}); + PTuple tuple = PFactory.createTuple(context.getLanguage(inliningTarget), + new Object[]{cursorLib.getFamily(cursor), cursorLib.getSockType(cursor), cursorLib.getProtocol(cursor), canonName, addr}); storage = appendNode.execute(inliningTarget, storage, tuple, SequenceStorageNodes.ListGeneralizationNode.SUPPLIER); } while (cursorLib.next(cursor)); - return factory.createList(storage); + return PFactory.createList(context.getLanguage(inliningTarget), storage); } finally { cursorLib.release(cursor); } @@ -736,8 +720,9 @@ protected ArgumentClinicProvider getArgumentClinic() { @GenerateNodeFactory abstract static class CloseNode extends PythonUnaryBuiltinNode { @Specialization - Object close(VirtualFrame frame, Object fdObj, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + static Object close(VirtualFrame frame, Object fdObj, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Bind("this") Node inliningTarget, @Cached GilNode gil, @Cached PyLongAsIntNode asIntNode, @@ -746,7 +731,7 @@ Object close(VirtualFrame frame, Object fdObj, try { gil.release(true); try { - posixLib.close(getPosixSupport(), fd); + posixLib.close(context.getPosixSupport(), fd); } finally { gil.acquire(); } @@ -764,8 +749,9 @@ Object close(VirtualFrame frame, Object fdObj, @GenerateNodeFactory abstract static class DupNode extends PythonUnaryBuiltinNode { @Specialization - Object close(VirtualFrame frame, Object fdObj, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + static Object close(VirtualFrame frame, Object fdObj, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Bind("this") Node inliningTarget, @Cached GilNode gil, @Cached PyLongAsIntNode asIntNode, @@ -774,12 +760,12 @@ Object close(VirtualFrame frame, Object fdObj, try { gil.release(true); try { - int dup = posixLib.dup(getPosixSupport(), fd); + int dup = posixLib.dup(context.getPosixSupport(), fd); try { - posixLib.setInheritable(getPosixSupport(), dup, false); + posixLib.setInheritable(context.getPosixSupport(), dup, false); } catch (PosixException e1) { try { - posixLib.close(getPosixSupport(), dup); + posixLib.close(context.getPosixSupport(), dup); } catch (PosixException e2) { // ignore } @@ -801,17 +787,17 @@ abstract static class InetAtoNNode extends PythonUnaryClinicBuiltinNode { @Specialization static PBytes doConvert(TruffleString addr, @Bind("this") Node inliningTarget, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, + @Cached PRaiseNode raiseNode) { try { - PosixSupport posixSupport = PosixSupport.get(inliningTarget); + PosixSupport posixSupport = context.getPosixSupport(); int converted = posixLib.inet_aton(posixSupport, posixLib.createPathFromString(posixSupport, addr)); byte[] bytes = new byte[4]; ByteArraySupport.bigEndian().putInt(bytes, 0, converted); - return factory.createBytes(bytes); + return PFactory.createBytes(context.getLanguage(inliningTarget), bytes); } catch (PosixSupportLibrary.InvalidAddressException e) { - throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.ILLEGAL_IP_ADDR_STRING_TO_INET_ATON); + throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.ILLEGAL_IP_ADDR_STRING_TO_INET_ATON); } } @@ -830,16 +816,17 @@ static TruffleString doGeneric(VirtualFrame frame, Object addr, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("addr") PythonBufferAcquireLibrary bufferAcquireLib, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, + @Cached PRaiseNode raiseNode) { Object buffer = bufferAcquireLib.acquireReadonly(addr, frame, indirectCallData); try { byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); int len = bufferLib.getBufferLength(buffer); if (len != 4) { - throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.PACKED_IP_WRONG_LENGTH, "inet_ntoa"); + throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.PACKED_IP_WRONG_LENGTH, "inet_ntoa"); } - PosixSupport posixSupport = PosixSupport.get(inliningTarget); + PosixSupport posixSupport = context.getPosixSupport(); Object result = posixLib.inet_ntoa(posixSupport, ByteArraySupport.bigEndian().getInt(bytes, 0)); return posixLib.getPathAsString(posixSupport, result); } finally { @@ -856,18 +843,18 @@ abstract static class InetPtoNNode extends PythonBinaryClinicBuiltinNode { @Specialization static PBytes doConvert(VirtualFrame frame, int family, TruffleString addr, @Bind("this") Node inliningTarget, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { - PosixSupport posixSupport = PosixSupport.get(inliningTarget); + PosixSupport posixSupport = context.getPosixSupport(); byte[] bytes = posixLib.inet_pton(posixSupport, family, posixLib.createPathFromString(posixSupport, addr)); - return factory.createBytes(bytes); + return PFactory.createBytes(context.getLanguage(inliningTarget), bytes); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } catch (PosixSupportLibrary.InvalidAddressException e) { - throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.ILLEGAL_IP_ADDR_STRING_TO_INET_PTON); + throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.ILLEGAL_IP_ADDR_STRING_TO_INET_PTON); } } @@ -887,26 +874,27 @@ static TruffleString doGeneric(VirtualFrame frame, int family, Object obj, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("obj") PythonBufferAcquireLibrary bufferAcquireLib, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object buffer = bufferAcquireLib.acquireReadonly(obj, frame, indirectCallData); try { byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); int len = bufferLib.getBufferLength(buffer); if (family == AF_INET.value) { if (len != 4) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.ILLEGAL_LENGTH_OF_PACKED_IP_ADDRS); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.ILLEGAL_LENGTH_OF_PACKED_IP_ADDRS); } } else if (family == AF_INET6.value) { if (len != 16) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.ILLEGAL_LENGTH_OF_PACKED_IP_ADDRS); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.ILLEGAL_LENGTH_OF_PACKED_IP_ADDRS); } } else { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.UNKNOWN_ADDR_FAMILY, family); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.UNKNOWN_ADDR_FAMILY, family); } try { - PosixSupport posixSupport = PosixSupport.get(inliningTarget); + PosixSupport posixSupport = context.getPosixSupport(); Object result = posixLib.inet_ntop(posixSupport, family, bytes); return posixLib.getPathAsString(posixSupport, result); } catch (PosixException e) { @@ -932,10 +920,10 @@ static int convert(VirtualFrame frame, Object xObj, @Bind("this") Node inliningTarget, @Cached PyLongAsIntNode asIntNode, @Cached WarningsModuleBuiltins.WarnNode warnNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int x = asIntNode.execute(frame, inliningTarget, xObj); if (x < 0) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.NTOHS_CANT_CONVERT_NEG_PYTHON_INT); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.NTOHS_CANT_CONVERT_NEG_PYTHON_INT); } if (x > 0xFFFF) { warnNode.warnEx(frame, DeprecationWarning, ErrorMessages.NTOH_PYTHON_STRING_TOO_LARGE_TO_CONVERT, 1); @@ -956,13 +944,13 @@ abstract static class NToHLNode extends PythonUnaryBuiltinNode { static long convert(VirtualFrame frame, Object xObj, @Bind("this") Node inliningTarget, @Cached PyLongAsLongNode asLongNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { long x = asLongNode.execute(frame, inliningTarget, xObj); if (x < 0) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.CANNOT_CONVERT_NEGATIVE_VALUE_TO_UNSIGNED_INT); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.CANNOT_CONVERT_NEGATIVE_VALUE_TO_UNSIGNED_INT); } if (x > 0xFFFFFFFFL) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.INT_LATGER_THAN_32_BITS); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.INT_LATGER_THAN_32_BITS); } int i = (int) x; if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) { diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/advanced/CustomModule.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/StatResultBuiltins.java similarity index 51% rename from graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/advanced/CustomModule.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/StatResultBuiltins.java index cc0aaa6ad0..d4cc52277b 100644 --- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/advanced/CustomModule.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/StatResultBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,28 +38,56 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.test.advanced; +package com.oracle.graal.python.builtins.modules; -import java.util.ArrayList; import java.util.List; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.Python3Core; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.tuple.InstantiableStructSequenceBuiltins; +import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; +import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; -@CoreFunctions(defineModule = "CustomModule") -public class CustomModule extends PythonBuiltins { +@CoreFunctions(extendClasses = PythonBuiltinClassType.PStatResult) +public class StatResultBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = StatResultBuiltinsSlotsGen.SLOTS; @Override protected List> getNodeFactories() { - return new ArrayList<>(); + return StatResultBuiltinsFactory.getFactories(); } - @Override - public void initialize(Python3Core core) { - super.initialize(core); - this.addBuiltinConstant("success", "success"); + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "stat_result", minNumOfPositionalArgs = 1, parameterNames = {"$cls", "sequence", "dict"}) + @GenerateNodeFactory + public abstract static class StatResultNode extends PythonTernaryBuiltinNode { + + @Specialization + public static PTuple generic(VirtualFrame frame, Object cls, Object sequence, Object dict, + @Cached InstantiableStructSequenceBuiltins.NewNode newNode) { + PTuple p = (PTuple) newNode.execute(frame, cls, sequence, dict); + Object[] data = CompilerDirectives.castExact(p.getSequenceStorage(), ObjectSequenceStorage.class).getInternalObjectArray(); + for (int i = 7; i <= 9; i++) { + if (data[i + 3] == PNone.NONE) { + data[i + 3] = data[i]; + } + } + return p; + } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/StringModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/StringModuleBuiltins.java index 14abb5dd33..92086f7152 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/StringModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/StringModuleBuiltins.java @@ -59,7 +59,7 @@ import com.oracle.graal.python.runtime.ExecutionContext; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; @@ -85,8 +85,7 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization PSequenceIterator formatterParser(VirtualFrame frame, TruffleString self, - @Cached("createFor(this)") IndirectCallData indirectCallData, - @Cached PythonObjectFactory factory) { + @Cached("createFor(this)") IndirectCallData indirectCallData) { TemplateFormatter formatter = new TemplateFormatter(self); List parserList; PythonContext context = PythonContext.get(this); @@ -97,16 +96,16 @@ PSequenceIterator formatterParser(VirtualFrame frame, TruffleString self, } finally { ExecutionContext.IndirectCallContext.exit(frame, language, context, state); } - return parserListToIterator(parserList, factory); + return parserListToIterator(parserList, language); } } - private static PSequenceIterator parserListToIterator(List parserList, PythonObjectFactory factory) { + private static PSequenceIterator parserListToIterator(List parserList, PythonLanguage language) { Object[] tuples = new Object[parserList.size()]; for (int i = 0; i < tuples.length; i++) { - tuples[i] = factory.createTuple(parserList.get(i)); + tuples[i] = PFactory.createTuple(language, parserList.get(i)); } - return factory.createSequenceIterator(factory.createList(tuples)); + return PFactory.createSequenceIterator(language, PFactory.createList(language, tuples)); } @Builtin(name = J_FORMATTER_FIELD_NAME_SPLIT, minNumOfPositionalArgs = 1, parameterNames = {"self"}) @@ -120,8 +119,7 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization Object formatterParser(VirtualFrame frame, TruffleString self, - @Cached("createFor(this)") IndirectCallData indirectCallData, - @Cached PythonObjectFactory factory) { + @Cached("createFor(this)") IndirectCallData indirectCallData) { TemplateFormatter formatter = new TemplateFormatter(self); TemplateFormatter.FieldNameSplitResult result; PythonContext context = PythonContext.get(this); @@ -132,7 +130,7 @@ Object formatterParser(VirtualFrame frame, TruffleString self, } finally { ExecutionContext.IndirectCallContext.exit(frame, language, context, state); } - return factory.createTuple(new Object[]{result.first, parserListToIterator(result.parserList, factory)}); + return PFactory.createTuple(language, new Object[]{result.first, parserListToIterator(result.parserList, language)}); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/StructModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/StructModuleBuiltins.java index 55787472b2..49223653ac 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/StructModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/StructModuleBuiltins.java @@ -1,89 +1,31 @@ -/* Copyright (c) 2020, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2020 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 */ package com.oracle.graal.python.builtins.modules; -import static com.oracle.graal.python.nodes.ErrorMessages.ARG_MUST_BE_STR_OR_BYTES; -import static com.oracle.graal.python.nodes.ErrorMessages.BAD_CHR_IN_STRUCT_FMT; -import static com.oracle.graal.python.nodes.ErrorMessages.REPEAT_COUNT_WITHOUT_FMT; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_BOOL; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_CHAR; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_DOUBLE; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_FLOAT; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_HALF_FLOAT; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_INT; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_LONG; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_LONG_LONG; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_PAD_BYTE; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_PASCAL_STRING; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_SHORT; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_SIGNED_CHAR; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_SIZE_T; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_STRING; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_UNSIGNED_CHAR; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_UNSIGNED_INT; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_UNSIGNED_LONG; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_UNSIGNED_LONG_LONG; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_UNSIGNED_SHORT; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_UNSIGNED_SIZE_T; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_VOID_PTR; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_BOOL; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_CHAR; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_DOUBLE; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_FLOAT; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_HALF_FLOAT; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_INT; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_LONG; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_LONG_LONG; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_PAD_BYTE; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_PASCAL_STRING; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_SHORT; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_SIGNED_CHAR; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_SIZE_T; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_STRING; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_UNSIGNED_CHAR; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_UNSIGNED_INT; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_UNSIGNED_LONG; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_UNSIGNED_LONG_LONG; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_UNSIGNED_SHORT; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_UNSIGNED_SIZE_T; -import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_VOID_PTR; import static com.oracle.graal.python.nodes.BuiltinNames.J__STRUCT; import static com.oracle.graal.python.nodes.BuiltinNames.T__STRUCT; -import static com.oracle.graal.python.nodes.ErrorMessages.EMBEDDED_NULL_CHARACTER; import static com.oracle.graal.python.runtime.exception.PythonErrorType.StructError; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; -import java.nio.ByteOrder; import java.util.Arrays; -import java.util.HashSet; import java.util.List; -import java.util.Set; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.PythonOS; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.builtins.objects.str.PString; -import com.oracle.graal.python.builtins.objects.struct.FormatAlignment; -import com.oracle.graal.python.builtins.objects.struct.FormatCode; -import com.oracle.graal.python.builtins.objects.struct.FormatDef; import com.oracle.graal.python.builtins.objects.struct.PStruct; import com.oracle.graal.python.builtins.objects.struct.StructBuiltins; -import com.oracle.graal.python.util.LRUCache; -import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; @@ -92,13 +34,9 @@ import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.graal.python.util.LRUCache; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -140,294 +78,7 @@ public void postInitialize(Python3Core core) { structModule.setModuleState(cache); } - @ImportStatic(PythonUtils.class) - @Builtin(name = "Struct", minNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PStruct) - @GenerateNodeFactory - public abstract static class ConstructStructNode extends PythonBinaryBuiltinNode { - public static final int NUM_BYTES_LIMIT; - - private static final int SHORT_ALIGN = Short.BYTES; - private static final int INT_ALIGN = Integer.BYTES; - private static final int LONG_ALIGN = Long.BYTES; - private static final int FLOAT_ALIGN = Float.BYTES; - private static final int DOUBLE_ALIGN = Double.BYTES; - - private static final char ALIGNMENT_NATIVE_NATIVE = '@'; - private static final char ALIGNMENT_NATIVE_STD = '='; - private static final char ALIGNMENT_LE_STD = '<'; - private static final char ALIGNMENT_BE_STD = '>'; - private static final char ALIGNMENT_NET_BE_STD = '!'; - private static final char DEFAULT_ALIGNMENT = ALIGNMENT_NATIVE_NATIVE; - // format def tables - private static final FormatDef[] FMT_TABLE = new FormatDef[128]; - private static final FormatDef[] FMT_TABLE_NATIVE = new FormatDef[128]; - static { - Set numBytes = new HashSet<>(); - - setFormatDefEntry(FMT_TABLE, FMT_PAD_BYTE, T_LBL_PAD_BYTE, 1, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_SIGNED_CHAR, T_LBL_SIGNED_CHAR, 1, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_UNSIGNED_CHAR, T_LBL_UNSIGNED_CHAR, 1, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_CHAR, T_LBL_CHAR, 1, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_STRING, T_LBL_STRING, 1, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_PASCAL_STRING, T_LBL_PASCAL_STRING, 1, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_SHORT, T_LBL_SHORT, 2, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_UNSIGNED_SHORT, T_LBL_UNSIGNED_SHORT, 2, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_INT, T_LBL_INT, 4, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_UNSIGNED_INT, T_LBL_UNSIGNED_INT, 4, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_LONG, T_LBL_LONG, 4, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_UNSIGNED_LONG, T_LBL_UNSIGNED_LONG, 4, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_LONG_LONG, T_LBL_LONG_LONG, 8, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_UNSIGNED_LONG_LONG, T_LBL_UNSIGNED_LONG_LONG, 8, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_BOOL, T_LBL_BOOL, 1, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_HALF_FLOAT, T_LBL_HALF_FLOAT, 2, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_FLOAT, T_LBL_FLOAT, 4, numBytes); - setFormatDefEntry(FMT_TABLE, FMT_DOUBLE, T_LBL_DOUBLE, 8, numBytes); - - // native format table - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_PAD_BYTE, T_LBL_PAD_BYTE, Byte.BYTES, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_SIGNED_CHAR, T_LBL_SIGNED_CHAR, Byte.BYTES, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_UNSIGNED_CHAR, T_LBL_UNSIGNED_CHAR, Byte.BYTES, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_CHAR, T_LBL_CHAR, Byte.BYTES, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_STRING, T_LBL_STRING, Byte.BYTES, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_PASCAL_STRING, T_LBL_PASCAL_STRING, Byte.BYTES, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_SHORT, T_LBL_SHORT, Short.BYTES, SHORT_ALIGN, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_UNSIGNED_SHORT, T_LBL_UNSIGNED_SHORT, Short.BYTES, SHORT_ALIGN, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_INT, T_LBL_INT, Integer.BYTES, INT_ALIGN, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_UNSIGNED_INT, T_LBL_UNSIGNED_INT, Integer.BYTES, INT_ALIGN, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_LONG, T_LBL_LONG, - PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32 ? Integer.BYTES : Long.BYTES, - PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32 ? INT_ALIGN : LONG_ALIGN, - numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_UNSIGNED_LONG, T_LBL_UNSIGNED_LONG, - PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32 ? Integer.BYTES : Long.BYTES, - PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32 ? INT_ALIGN : LONG_ALIGN, - numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_SIZE_T, T_LBL_SIZE_T, Long.BYTES, LONG_ALIGN, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_UNSIGNED_SIZE_T, T_LBL_UNSIGNED_SIZE_T, Long.BYTES, LONG_ALIGN, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_LONG_LONG, T_LBL_LONG_LONG, Long.BYTES, LONG_ALIGN, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_UNSIGNED_LONG_LONG, T_LBL_UNSIGNED_LONG_LONG, Long.BYTES, LONG_ALIGN, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_BOOL, T_LBL_BOOL, Byte.BYTES, 0, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_HALF_FLOAT, T_LBL_HALF_FLOAT, Float.BYTES / 2, SHORT_ALIGN, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_FLOAT, T_LBL_FLOAT, Float.BYTES, FLOAT_ALIGN, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_DOUBLE, T_LBL_DOUBLE, Double.BYTES, DOUBLE_ALIGN, numBytes); - setFormatDefEntry(FMT_TABLE_NATIVE, FMT_VOID_PTR, T_LBL_VOID_PTR, Long.BYTES, LONG_ALIGN, numBytes); - - NUM_BYTES_LIMIT = numBytes.size(); - } - - static void setFormatDefEntry(FormatDef[] table, char format, TruffleString label, int size, Set numBytes) { - setFormatDefEntry(table, format, label, size, 0, numBytes); - } - - static void setFormatDefEntry(FormatDef[] table, char format, TruffleString label, int size, int alignment, Set numBytes) { - table[format] = new FormatDef(format, label, size, alignment); - numBytes.add(size); - } - - public final PStruct execute(Object format) { - return execute(PythonBuiltinClassType.PStruct, format); - } - - public abstract PStruct execute(Object cls, Object format); - - @Specialization(guards = "isAscii(format, getCodeRangeNode)") - static PStruct struct(@SuppressWarnings("unused") Object cls, TruffleString format, - @Bind("this") Node inliningTarget, - @Shared @Cached TruffleString.CopyToByteArrayNode copyToByteArrayNode, - @Shared @Cached TruffleString.SwitchEncodingNode switchEncodingNode, - @SuppressWarnings("unused") @Shared @Cached TruffleString.GetCodeRangeNode getCodeRangeNode, - @Shared @Cached PythonObjectFactory factory) { - byte[] fmt = PythonUtils.getAsciiBytes(format, copyToByteArrayNode, switchEncodingNode); - return factory.createStruct(createStructInternal(inliningTarget, fmt)); - } - - @Specialization - static PStruct struct(Object cls, PString format, - @Bind("this") Node inliningTarget, - @Cached CastToTruffleStringNode castToTruffleStringNode, - @Shared @Cached TruffleString.CopyToByteArrayNode copyToByteArrayNode, - @Shared @Cached TruffleString.SwitchEncodingNode switchEncodingNode, - @SuppressWarnings("unused") @Shared @Cached TruffleString.GetCodeRangeNode getCodeRangeNode, - @Shared @Cached PythonObjectFactory factory) { - return struct(cls, castToTruffleStringNode.execute(inliningTarget, format), inliningTarget, copyToByteArrayNode, switchEncodingNode, getCodeRangeNode, factory); - } - - @Specialization(limit = "1") - static PStruct struct(@SuppressWarnings("unused") Object cls, PBytes format, - @Bind("this") Node inliningTarget, - @CachedLibrary("format") PythonBufferAccessLibrary bufferLib, - @Shared @Cached PythonObjectFactory factory) { - byte[] fmt = bufferLib.getCopiedByteArray(format); - return factory.createStruct(createStructInternal(inliningTarget, fmt)); - } - - @Specialization(guards = {"!isPBytes(format)", "!isPString(format)", "!isAsciiTruffleString(format, getCodeRangeNode)"}) - static PStruct fallback(@SuppressWarnings("unused") Object cls, Object format, - @SuppressWarnings("unused") @Shared @Cached TruffleString.GetCodeRangeNode getCodeRangeNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(StructError, ARG_MUST_BE_STR_OR_BYTES, "Struct()", format); - } - - protected static boolean isAsciiTruffleString(Object o, TruffleString.GetCodeRangeNode getCodeRangeNode) { - return o instanceof TruffleString && PythonUtils.isAscii((TruffleString) o, getCodeRangeNode); - } - - @TruffleBoundary - private static PStruct.StructInfo createStructInternal(Node raisingNode, byte[] format) { - int size = 0; - int len = 0; - int nCodes = 0; - int num; - - if (containsNullCharacter(format)) { - throw PRaiseNode.raiseUncached(raisingNode, PythonBuiltinClassType.StructError, EMBEDDED_NULL_CHARACTER); - } - - char alignment = DEFAULT_ALIGNMENT; - int start = 0; - - if (format.length > 0 && isAlignment((char) format[0])) { - alignment = (char) format[0]; - start = 1; - } - - final FormatAlignment formatAlignment = whichAlignment(alignment); - FormatDef[] formatTable = (formatAlignment.nativeSizing) ? FMT_TABLE_NATIVE : FMT_TABLE; - - // first pass: validation - for (int i = start; i < format.length; i++) { - char c = (char) format[i]; - if (c == ' ') { - continue; - } else if ('0' <= c && c <= '9') { - num = c - '0'; - while (++i < format.length && '0' <= (c = (char) format[i]) && c <= '9') { - if (num >= Integer.MAX_VALUE / 10 && (num > Integer.MAX_VALUE / 10 || (c - '0') > Integer.MAX_VALUE % 10)) { - throw PRaiseNode.raiseUncached(raisingNode, StructError, ErrorMessages.STRUCT_SIZE_TOO_LONG); - } - num = num * 10 + (c - '0'); - } - if (i == format.length) { - throw PRaiseNode.raiseUncached(raisingNode, StructError, REPEAT_COUNT_WITHOUT_FMT); - } - } else { - num = 1; - } - - FormatDef formatDef = getEntry(raisingNode, c, formatTable); - - switch (c) { - case 's': // fall through - case 'p': - len++; - nCodes++; - break; - case 'x': - break; - default: - len += num; - if (num != 0) { - nCodes++; - } - break; - } - - int itemSize = formatDef.size; - size = align(size, c, formatDef); - if (size == -1) { - throw PRaiseNode.raiseUncached(raisingNode, StructError, ErrorMessages.STRUCT_SIZE_TOO_LONG); - } - - if (num > (Integer.MAX_VALUE - size) / itemSize) { - throw PRaiseNode.raiseUncached(raisingNode, StructError, ErrorMessages.STRUCT_SIZE_TOO_LONG); - } - size += num * itemSize; - } - - // second pass - fill in the codes (no validation needed) - FormatCode[] codes = new FormatCode[nCodes]; - int structSize = size; - int structLen = len; - - int j = 0; - size = 0; - for (int i = start; i < format.length; i++) { - char c = (char) format[i]; - if (c == ' ') { - continue; - } else if ('0' <= c && c <= '9') { - num = c - '0'; - while (++i < format.length && '0' <= (c = (char) format[i]) && c <= '9') { - num = num * 10 + (c - '0'); - } - } else { - num = 1; - } - - FormatDef formatDef = getEntry(raisingNode, c, formatTable); - size = align(size, c, formatDef); - if (c == 's' || c == 'p') { - codes[j++] = new FormatCode(formatDef, size, num, 1); - size += num; - } else if (c == 'x') { - size += num; - } else if (num != 0) { - codes[j++] = new FormatCode(formatDef, size, formatDef.size, num); - size += formatDef.size * num; - } - } - - return new PStruct.StructInfo(format, structSize, structLen, formatAlignment, codes); - } - - private static FormatDef getEntry(Node raisingNode, char format, FormatDef[] table) { - FormatDef formatDef = table[format]; - if (formatDef != null) { - return formatDef; - } - throw PRaiseNode.raiseUncached(raisingNode, StructError, BAD_CHR_IN_STRUCT_FMT, format); - } - - private static boolean isAlignment(char alignment) { - return alignment == ALIGNMENT_LE_STD || - alignment == ALIGNMENT_BE_STD || - alignment == ALIGNMENT_NET_BE_STD || - alignment == ALIGNMENT_NATIVE_STD || - alignment == ALIGNMENT_NATIVE_NATIVE; - } - - private static FormatAlignment whichAlignment(char alignment) { - switch (alignment) { - case ALIGNMENT_LE_STD: - return new FormatAlignment(false, false); - case ALIGNMENT_BE_STD: - case ALIGNMENT_NET_BE_STD: - return new FormatAlignment(true, false); - case ALIGNMENT_NATIVE_STD: - return new FormatAlignment(ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN, false); - case ALIGNMENT_NATIVE_NATIVE: - default: - return new FormatAlignment(ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN, true); - } - } - - private static int align(int size, char c, FormatDef formatDef) { - int extra; - int alignedSize = size; - if (formatDef.format == c) { - if (formatDef.alignment > 0 && alignedSize > 0) { - extra = (formatDef.alignment - 1) - (alignedSize - 1) % (formatDef.alignment); - if (extra > Integer.MAX_VALUE - alignedSize) { - return -1; - } - alignedSize += extra; - } - } - return alignedSize; - } - } - - protected static PStruct getStruct(PythonModule structModule, Object format, ConstructStructNode constructStructNode) { + protected static PStruct getStruct(PythonModule structModule, Object format, StructBuiltins.ConstructStructNode constructStructNode) { LRUStructCache cache = structModule.getModuleState(LRUStructCache.class); PStruct pStruct = cache.get(format); if (pStruct == null) { @@ -441,9 +92,9 @@ protected static PStruct getStruct(PythonModule structModule, Object format, Con @GenerateCached(false) @ImportStatic({Arrays.class}) abstract static class GetStructNode extends PNodeWithContext { - abstract PStruct execute(Node inliningTarget, PythonModule module, Object format, ConstructStructNode constructStructNode); + abstract PStruct execute(Node inliningTarget, PythonModule module, Object format, StructBuiltins.ConstructStructNode constructStructNode); - protected PStruct getStructInternal(PythonModule module, Object format, ConstructStructNode constructStructNode) { + protected PStruct getStructInternal(PythonModule module, Object format, StructBuiltins.ConstructStructNode constructStructNode) { return getStruct(module, format, constructStructNode); } @@ -453,7 +104,7 @@ protected boolean eq(TruffleString s1, TruffleString s2, TruffleString.EqualNode @Specialization(guards = {"isSingleContext()", "eq(format, cachedFormat, eqNode)"}, limit = "1") @SuppressWarnings("unused") - static PStruct doCachedString(PythonModule module, TruffleString format, ConstructStructNode constructStructNode, + static PStruct doCachedString(PythonModule module, TruffleString format, StructBuiltins.ConstructStructNode constructStructNode, @Cached("format") TruffleString cachedFormat, @Cached(inline = false) TruffleString.EqualNode eqNode, @Cached(value = "getStructInternal(module, format, constructStructNode)", weak = true) PStruct cachedStruct) { @@ -462,7 +113,7 @@ static PStruct doCachedString(PythonModule module, TruffleString format, Constru @Specialization(guards = {"isSingleContext()", "equals(bufferLib.getCopiedByteArray(format), cachedFormat)"}, limit = "1") @SuppressWarnings("unused") - static PStruct doCachedBytes(PythonModule module, PBytes format, ConstructStructNode constructStructNode, + static PStruct doCachedBytes(PythonModule module, PBytes format, StructBuiltins.ConstructStructNode constructStructNode, @CachedLibrary("format") PythonBufferAccessLibrary bufferLib, @Cached(value = "bufferLib.getCopiedByteArray(format)", dimensions = 1) byte[] cachedFormat, @Cached(value = "getStructInternal(module, format, constructStructNode)", weak = true) PStruct cachedStruct) { @@ -470,7 +121,7 @@ static PStruct doCachedBytes(PythonModule module, PBytes format, ConstructStruct } @Specialization(replaces = {"doCachedString", "doCachedBytes"}) - static PStruct doGeneric(PythonModule module, Object format, ConstructStructNode constructStructNode) { + static PStruct doGeneric(PythonModule module, Object format, StructBuiltins.ConstructStructNode constructStructNode) { return getStruct(module, format, constructStructNode); } } @@ -481,7 +132,7 @@ abstract static class PackNode extends PythonBuiltinNode { @Specialization static Object pack(VirtualFrame frame, PythonModule self, Object format, Object[] args, @Bind("this") Node inliningTarget, - @Cached ConstructStructNode constructStructNode, + @Cached StructBuiltins.ConstructStructNode constructStructNode, @Cached GetStructNode getStructNode, @Cached StructBuiltins.StructPackNode structPackNode) { PStruct struct = getStructNode.execute(inliningTarget, self, format, constructStructNode); @@ -502,7 +153,7 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static Object packInto(VirtualFrame frame, PythonModule self, Object format, Object buffer, int offset, Object[] args, @Bind("this") Node inliningTarget, - @Cached ConstructStructNode constructStructNode, + @Cached StructBuiltins.ConstructStructNode constructStructNode, @Cached GetStructNode getStructNode, @Cached StructBuiltins.StructPackIntoNode structPackNode) { PStruct struct = getStructNode.execute(inliningTarget, self, format, constructStructNode); @@ -523,7 +174,7 @@ protected ArgumentClinicProvider getArgumentClinic() { static Object unpack(VirtualFrame frame, PythonModule self, Object format, Object buffer, @Bind("this") Node inliningTarget, @Cached GetStructNode getStructNode, - @Cached ConstructStructNode constructStructNode, + @Cached StructBuiltins.ConstructStructNode constructStructNode, @Cached StructBuiltins.StructUnpackNode structUnpackNode) { PStruct struct = getStructNode.execute(inliningTarget, self, format, constructStructNode); return structUnpackNode.execute(frame, struct, buffer); @@ -542,7 +193,7 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static Object iterUnpack(VirtualFrame frame, PythonModule self, Object format, Object buffer, @Bind("this") Node inliningTarget, - @Cached ConstructStructNode constructStructNode, + @Cached StructBuiltins.ConstructStructNode constructStructNode, @Cached GetStructNode getStructNode, @Cached StructBuiltins.StructIterUnpackNode iterUnpackNode) { PStruct struct = getStructNode.execute(inliningTarget, self, format, constructStructNode); @@ -563,7 +214,7 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static Object unpackFrom(VirtualFrame frame, PythonModule self, Object format, Object buffer, int offset, @Bind("this") Node inliningTarget, - @Cached ConstructStructNode constructStructNode, + @Cached StructBuiltins.ConstructStructNode constructStructNode, @Cached GetStructNode getStructNode, @Cached StructBuiltins.StructUnpackFromNode structUnpackNode) { PStruct struct = getStructNode.execute(inliningTarget, self, format, constructStructNode); @@ -577,7 +228,7 @@ abstract static class CalcSizeNode extends PythonBinaryBuiltinNode { @Specialization static Object calcSize(PythonModule self, Object format, @Bind("this") Node inliningTarget, - @Cached ConstructStructNode constructStructNode, + @Cached StructBuiltins.ConstructStructNode constructStructNode, @Cached GetStructNode getStructNode) { PStruct struct = getStructNode.execute(inliningTarget, self, format, constructStructNode); return struct.getSize(); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java index d33bfc47fd..2028255add 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java @@ -41,6 +41,8 @@ package com.oracle.graal.python.builtins.modules; import static com.oracle.graal.python.PythonLanguage.J_GRAALPYTHON_ID; +import static com.oracle.graal.python.PythonLanguage.RELEASE_LEVEL; +import static com.oracle.graal.python.PythonLanguage.RELEASE_SERIAL; import static com.oracle.graal.python.PythonLanguage.T_GRAALPYTHON_ID; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.AttributeError; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.DeprecationWarning; @@ -140,8 +142,6 @@ import java.util.List; import java.util.Set; -import org.graalvm.nativeimage.ImageInfo; - import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; @@ -230,7 +230,7 @@ import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.formatting.IntegerFormatter; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.CharsetMapping; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; @@ -253,6 +253,7 @@ import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleString; @@ -291,27 +292,16 @@ public final class SysModuleBuiltins extends PythonBuiltins { static final StructSequence.BuiltinTypeDescriptor VERSION_INFO_DESC = new StructSequence.BuiltinTypeDescriptor( PythonBuiltinClassType.PVersionInfo, - // @formatter:off The formatter joins these lines making it less readable - "sys.version_info\n" + - "\n" + - "Version information as a named tuple.", - // @formatter:on 5, new String[]{ "major", "minor", "micro", "releaselevel", "serial"}, new String[]{ "Major release number", "Minor release number", "Patch release number", - "'alpha', 'beta', 'candidate', or 'final'", "Serial release number"}, - false); + "'alpha', 'beta', 'candidate', or 'final'", "Serial release number"}); static final StructSequence.BuiltinTypeDescriptor WINDOWS_VER_DESC = new StructSequence.BuiltinTypeDescriptor( PythonBuiltinClassType.PWindowsVersion, - // @formatter:off The formatter joins these lines making it less readable - "sys.getwindowsversion\n" + - "\n" + - "Return info about the running version of Windows as a named tuple.", - // @formatter:on 5, new String[]{ "major", "minor", "build", @@ -323,16 +313,10 @@ public final class SysModuleBuiltins extends PythonBuiltins { "Operating system platform", "Latest Service Pack installed on the system", "Service Pack major version number", "Service Pack minor version number", "Bit mask identifying available product suites", - "System product type", "Diagnostic version number"}, - false); + "System product type", "Diagnostic version number"}); static final StructSequence.BuiltinTypeDescriptor FLAGS_DESC = new StructSequence.BuiltinTypeDescriptor( PythonBuiltinClassType.PFlags, - // @formatter:off The formatter joins these lines making it less readable - "sys.flags\n" + - "\n" + - "Flags provided through command line arguments or environment vars.", - // @formatter:on 18, new String[]{ "debug", @@ -373,18 +357,10 @@ public final class SysModuleBuiltins extends PythonBuiltins { "-X warn_default_encoding", "-P", "-X int_max_str_digits", - }, - false); + }); static final StructSequence.BuiltinTypeDescriptor FLOAT_INFO_DESC = new StructSequence.BuiltinTypeDescriptor( PythonBuiltinClassType.PFloatInfo, - // @formatter:off The formatter joins these lines making it less readable - "sys.float_info\n" + - "\n" + - "A named tuple holding information about the float type. It contains low level\n" + - "information about the precision and internal representation. Please study\n" + - "your system's :file:`float.h` for more information.", - // @formatter:on 11, new String[]{ "max", @@ -413,12 +389,6 @@ public final class SysModuleBuiltins extends PythonBuiltins { static final StructSequence.BuiltinTypeDescriptor INT_INFO_DESC = new StructSequence.BuiltinTypeDescriptor( PythonBuiltinClassType.PIntInfo, - // @formatter:off The formatter joins these lines making it less readable - "sys.int_info\n" + - "\n" + - "A named tuple that holds information about Python's\n" + - "internal representation of integers. The attributes are read only.", - // @formatter:on 4, new String[]{ "bits_per_digit", "sizeof_digit", "default_max_str_digits", "str_digits_check_threshold"}, @@ -430,12 +400,6 @@ public final class SysModuleBuiltins extends PythonBuiltins { static final StructSequence.BuiltinTypeDescriptor HASH_INFO_DESC = new StructSequence.BuiltinTypeDescriptor( PythonBuiltinClassType.PHashInfo, - // @formatter:off The formatter joins these lines making it less readable - "hash_info\n" + - "\n" + - "A named tuple providing parameters used for computing\n" + - "hashes. The attributes are read only.", - // @formatter:on 9, new String[]{ "width", "modulus", "inf", "nan", "imag", "algorithm", "hash_bits", @@ -453,11 +417,6 @@ public final class SysModuleBuiltins extends PythonBuiltins { static final StructSequence.BuiltinTypeDescriptor THREAD_INFO_DESC = new StructSequence.BuiltinTypeDescriptor( PythonBuiltinClassType.PThreadInfo, - // @formatter:off The formatter joins these lines making it less readable - "sys.thread_info\n" + - "\n" + - "A named tuple holding information about the thread implementation.", - // @formatter:on 3, new String[]{ "name", "lock", "version"}, @@ -467,11 +426,6 @@ public final class SysModuleBuiltins extends PythonBuiltins { public static final StructSequence.BuiltinTypeDescriptor UNRAISABLEHOOK_ARGS_DESC = new StructSequence.BuiltinTypeDescriptor( PythonBuiltinClassType.PUnraisableHookArgs, - // @formatter:off The formatter joins these lines making it less readable - "UnraisableHookArgs\n" + - "\n" + - "Type used to pass arguments to sys.unraisablehook.", - // @formatter:on 5, new String[]{ "exc_type", "exc_value", "exc_traceback", @@ -507,21 +461,22 @@ protected List> getNodeFa return SysModuleBuiltinsFactory.getFactories(); } - protected static PSimpleNamespace makeImplementation(PythonObjectFactory factory, PTuple versionInfo, TruffleString gmultiarch) { - final PSimpleNamespace ns = factory.createSimpleNamespace(); + private static PSimpleNamespace makeImplementation(PythonLanguage language, PTuple graalpyVersionInfo, TruffleString gmultiarch) { + final PSimpleNamespace ns = PFactory.createSimpleNamespace(language); ns.setAttribute(tsLiteral("name"), T_GRAALPYTHON_ID); /*- 'cache_tag' must match the format of mx.graalpython/mx_graalpython.py:graalpy_ext */ ns.setAttribute(T_CACHE_TAG, toTruffleStringUncached(J_GRAALPYTHON_ID + PythonLanguage.GRAALVM_MAJOR + PythonLanguage.GRAALVM_MINOR + PythonLanguage.DEV_TAG + "-" + PythonLanguage.MAJOR + PythonLanguage.MINOR)); - ns.setAttribute(T_VERSION, versionInfo); + ns.setAttribute(T_VERSION, graalpyVersionInfo); ns.setAttribute(T__MULTIARCH, gmultiarch); - ns.setAttribute(tsLiteral("hexversion"), PythonLanguage.VERSION_HEX); + ns.setAttribute(tsLiteral("hexversion"), PythonLanguage.GRAALVM_MAJOR << 24 | PythonLanguage.GRAALVM_MINOR << 16 | PythonLanguage.GRAALVM_MICRO << 8 | RELEASE_LEVEL << 4 | RELEASE_SERIAL); return ns; } @Override public void initialize(Python3Core core) { + PythonLanguage language = core.getLanguage(); StructSequence.initType(core, VERSION_INFO_DESC); if (PythonOS.getPythonOS() == PLATFORM_WIN32) { StructSequence.initType(core, WINDOWS_VER_DESC); @@ -536,19 +491,18 @@ public void initialize(Python3Core core) { addBuiltinConstant("abiflags", T_EMPTY_STRING); addBuiltinConstant("byteorder", ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN ? T_LITTLE : T_BIG); addBuiltinConstant("copyright", T_LICENSE); - final PythonObjectFactory factory = PythonObjectFactory.getUncached(); - addBuiltinConstant(T_MODULES, factory.createDict()); - addBuiltinConstant("path", factory.createList()); - addBuiltinConstant("builtin_module_names", factory.createTuple(core.builtinModuleNames())); + addBuiltinConstant(T_MODULES, PFactory.createDict(language)); + addBuiltinConstant("path", PFactory.createList(language)); + addBuiltinConstant("builtin_module_names", PFactory.createTuple(language, core.builtinModuleNames())); addBuiltinConstant("maxsize", MAXSIZE); - final PTuple versionInfo = factory.createStructSeq(VERSION_INFO_DESC, PythonLanguage.MAJOR, PythonLanguage.MINOR, PythonLanguage.MICRO, PythonLanguage.RELEASE_LEVEL_STRING, + final PTuple versionInfo = PFactory.createStructSeq(language, VERSION_INFO_DESC, PythonLanguage.MAJOR, PythonLanguage.MINOR, PythonLanguage.MICRO, PythonLanguage.RELEASE_LEVEL_STRING, PythonLanguage.RELEASE_SERIAL); addBuiltinConstant("version_info", versionInfo); addBuiltinConstant("api_version", PythonLanguage.API_VERSION); addBuiltinConstant("version", toTruffleStringUncached(PythonLanguage.VERSION + " (" + COMPILE_TIME + ")" + "\n[Graal, " + Truffle.getRuntime().getName() + ", Java " + System.getProperty("java.version") + " (" + System.getProperty("os.arch") + ")]")); - addBuiltinConstant("float_info", factory.createStructSeq(FLOAT_INFO_DESC, + addBuiltinConstant("float_info", PFactory.createStructSeq(language, FLOAT_INFO_DESC, Double.MAX_VALUE, // DBL_MAX Double.MAX_EXPONENT + 1, // DBL_MAX_EXP 308, // DBL_MIN_10_EXP @@ -561,8 +515,8 @@ public void initialize(Python3Core core) { 2, // FLT_RADIX 1 // FLT_ROUNDS )); - addBuiltinConstant("int_info", factory.createStructSeq(INT_INFO_DESC, 32, 4, INT_DEFAULT_MAX_STR_DIGITS, INT_MAX_STR_DIGITS_THRESHOLD)); - addBuiltinConstant("hash_info", factory.createStructSeq(HASH_INFO_DESC, + addBuiltinConstant("int_info", PFactory.createStructSeq(language, INT_INFO_DESC, 32, 4, INT_DEFAULT_MAX_STR_DIGITS, INT_MAX_STR_DIGITS_THRESHOLD)); + addBuiltinConstant("hash_info", PFactory.createStructSeq(language, HASH_INFO_DESC, 64, // width HASH_MODULUS, // modulus HASH_INF, // inf @@ -573,7 +527,7 @@ public void initialize(Python3Core core) { 0, // seed_bits 0 // cutoff )); - addBuiltinConstant("thread_info", factory.createStructSeq(THREAD_INFO_DESC, PNone.NONE, PNone.NONE, PNone.NONE)); + addBuiltinConstant("thread_info", PFactory.createStructSeq(language, THREAD_INFO_DESC, PNone.NONE, PNone.NONE, PNone.NONE)); addBuiltinConstant("maxunicode", IntegerFormatter.LIMIT_UNICODE.intValue() - 1); PythonOS os = getPythonOS(); @@ -589,7 +543,10 @@ public void initialize(Python3Core core) { addBuiltinConstant(T_STDOUT, PNone.NONE); addBuiltinConstant(T_STDERR, PNone.NONE); - addBuiltinConstant("implementation", makeImplementation(factory, versionInfo, gmultiarch)); + PTuple graalpyVersion = PFactory.createStructSeq(language, VERSION_INFO_DESC, PythonLanguage.GRAALVM_MAJOR, PythonLanguage.GRAALVM_MINOR, PythonLanguage.GRAALVM_MICRO, + PythonLanguage.RELEASE_LEVEL_STRING, PythonLanguage.RELEASE_SERIAL); + addBuiltinConstant("graalpy_version_info", graalpyVersion); + addBuiltinConstant("implementation", makeImplementation(language, graalpyVersion, gmultiarch)); addBuiltinConstant("hexversion", PythonLanguage.VERSION_HEX); if (os == PLATFORM_WIN32) { @@ -597,9 +554,9 @@ public void initialize(Python3Core core) { } addBuiltinConstant("float_repr_style", "short"); - addBuiltinConstant("meta_path", factory.createList()); - addBuiltinConstant("path_hooks", factory.createList()); - addBuiltinConstant("path_importer_cache", factory.createDict()); + addBuiltinConstant("meta_path", PFactory.createList(language)); + addBuiltinConstant("path_hooks", PFactory.createList(language)); + addBuiltinConstant("path_importer_cache", PFactory.createDict(language)); // default prompt for interactive shell addBuiltinConstant("ps1", ">>> "); @@ -607,7 +564,7 @@ public void initialize(Python3Core core) { addBuiltinConstant("ps2", "... "); // CPython builds for distros report empty strings too, because they are built from // tarballs, not git - addBuiltinConstant("_git", factory.createTuple(new Object[]{T_GRAALPYTHON_ID, T_EMPTY_STRING, T_EMPTY_STRING})); + addBuiltinConstant("_git", PFactory.createTuple(language, new Object[]{T_GRAALPYTHON_ID, T_EMPTY_STRING, T_EMPTY_STRING})); if (PythonOS.getPythonOS() == PLATFORM_WIN32) { addBuiltinConstant("_vpath", ""); @@ -623,12 +580,12 @@ public void postInitialize0(Python3Core core) { super.postInitialize(core); PythonModule sys = core.lookupBuiltinModule(T_SYS); PythonContext context = core.getContext(); + PythonLanguage language = core.getLanguage(); String[] args = context.getEnv().getApplicationArguments(); - final PythonObjectFactory factory = PythonObjectFactory.getUncached(); - sys.setAttribute(tsLiteral("argv"), factory.createList(convertToObjectArray(args))); - sys.setAttribute(tsLiteral("orig_argv"), factory.createList(convertToObjectArray(PythonOptions.getOrigArgv(core.getContext())))); + sys.setAttribute(tsLiteral("argv"), PFactory.createList(language, convertToObjectArray(args))); + sys.setAttribute(tsLiteral("orig_argv"), PFactory.createList(language, convertToObjectArray(PythonOptions.getOrigArgv(core.getContext())))); - sys.setAttribute(tsLiteral("stdlib_module_names"), createStdLibModulesSet(factory)); + sys.setAttribute(tsLiteral("stdlib_module_names"), createStdLibModulesSet(language)); TruffleString prefix = context.getSysPrefix(); for (TruffleString name : SysModuleBuiltins.SYS_PREFIX_ATTRIBUTES) { @@ -646,7 +603,7 @@ public void postInitialize0(Python3Core core) { TruffleString stdlibHome = context.getStdlibHome(); TruffleString capiHome = context.getCAPIHome(); - if (!ImageInfo.inImageBuildtimeCode()) { + if (!context.getEnv().isPreInitialization()) { TruffleString executable = context.getOption(PythonOptions.Executable); TruffleString baseExecutable = context.getOption(PythonOptions.BaseExecutable); sys.setAttribute(tsLiteral("executable"), executable); @@ -654,6 +611,9 @@ public void postInitialize0(Python3Core core) { } sys.setAttribute(tsLiteral("dont_write_bytecode"), context.getOption(PythonOptions.DontWriteBytecodeFlag)); TruffleString pycachePrefix = context.getOption(PythonOptions.PyCachePrefix); + if (pycachePrefix.isEmpty() && PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER && System.getenv("CI") == null) { + pycachePrefix = PythonUtils.toTruffleStringUncached("__bci_dsl_pycache__"); + } sys.setAttribute(tsLiteral("pycache_prefix"), pycachePrefix.isEmpty() ? PNone.NONE : pycachePrefix); sys.setAttribute(tsLiteral("_stdlib_dir"), stdlibHome); @@ -666,7 +626,7 @@ public void postInitialize0(Python3Core core) { } else { warnoptions = PythonUtils.EMPTY_OBJECT_ARRAY; } - sys.setAttribute(tsLiteral("warnoptions"), factory.createList(warnoptions)); + sys.setAttribute(tsLiteral("warnoptions"), PFactory.createList(language, warnoptions)); Env env = context.getEnv(); TruffleString pythonPath = context.getOption(PythonOptions.PythonPath); @@ -695,9 +655,9 @@ public void postInitialize0(Python3Core core) { // include our native modules on the path path[pathIdx++] = toTruffleStringUncached(capiHome + env.getFileNameSeparator() + "modules"); } - PList sysPaths = factory.createList(path); + PList sysPaths = PFactory.createList(language, path); sys.setAttribute(tsLiteral("path"), sysPaths); - sys.setAttribute(tsLiteral("flags"), factory.createStructSeq(SysModuleBuiltins.FLAGS_DESC, + sys.setAttribute(tsLiteral("flags"), PFactory.createStructSeq(language, SysModuleBuiltins.FLAGS_DESC, PInt.intValue(!context.getOption(PythonOptions.PythonOptimizeFlag)), // debug PInt.intValue(context.getOption(PythonOptions.InspectFlag)), // inspect PInt.intValue(context.getOption(PythonOptions.TerminalIsInteractive)), // interactive @@ -723,18 +683,18 @@ public void postInitialize0(Python3Core core) { sys.setAttribute(T___BREAKPOINTHOOK__, sys.getAttribute(T_BREAKPOINTHOOK)); } - private static PFrozenSet createStdLibModulesSet(PythonObjectFactory factory) { + private static PFrozenSet createStdLibModulesSet(PythonLanguage language) { EconomicMapStorage storage = EconomicMapStorage.create(STDLIB_MODULE_NAMES.length); for (String s : STDLIB_MODULE_NAMES) { - storage.putUncachedWithJavaEq(s, PNone.NONE); + storage.putUncached(s, PNone.NONE); } - return factory.createFrozenSet(storage); + return PFactory.createFrozenSet(language, storage); } /** * Like {@link PythonUtils#toTruffleStringArrayUncached(String[])}, but creates an array of * {@link Object}'s. The intended use of this method is in slow-path in calls to methods like - * {@link PythonObjectFactory#createTuple(Object[])}. + * {@link PFactory#createTuple}. */ private static Object[] convertToObjectArray(String[] src) { if (src == null) { @@ -765,8 +725,8 @@ public void postInitialize(Python3Core core) { @TruffleBoundary static void initStd(Python3Core core) { - PythonObjectFactory factory = core.factory(); PythonContext context = core.getContext(); + PythonLanguage language = core.getLanguage(); // wrap std in/out/err GraalPythonModuleBuiltins gp = (GraalPythonModuleBuiltins) core.lookupBuiltinModule(T___GRAALPYTHON__).getBuiltins(); @@ -779,35 +739,35 @@ static void initStd(Python3Core core) { // Note that stdin is always buffered, this only applies to stdout and stderr boolean buffering = !context.getOption(PythonOptions.UnbufferedIO); - PFileIO stdinFileIO = factory.createFileIO(PythonBuiltinClassType.PFileIO); + PFileIO stdinFileIO = PFactory.createFileIO(language); FileIOBuiltins.FileIOInit.internalInit(stdinFileIO, toTruffleStringUncached(""), 0, IOMode.RB); - PBuffered stdinBuffer = factory.createBufferedReader(PythonBuiltinClassType.PBufferedReader); - BufferedReaderBuiltins.BufferedReaderInit.internalInit(stdinBuffer, stdinFileIO, BufferedReaderBuiltins.DEFAULT_BUFFER_SIZE, factory, posixSupport, posixLib); - setWrapper(T_STDIN, T___STDIN__, T_R, stdioEncoding, stdioError, stdinBuffer, sysModule, factory, true); + PBuffered stdinBuffer = PFactory.createBufferedReader(language); + BufferedReaderBuiltins.BufferedReaderInit.internalInit(stdinBuffer, stdinFileIO, BufferedReaderBuiltins.DEFAULT_BUFFER_SIZE, language, posixSupport, posixLib); + setWrapper(T_STDIN, T___STDIN__, T_R, stdioEncoding, stdioError, stdinBuffer, sysModule, language, true); - PFileIO stdoutFileIO = factory.createFileIO(PythonBuiltinClassType.PFileIO); + PFileIO stdoutFileIO = PFactory.createFileIO(language); FileIOBuiltins.FileIOInit.internalInit(stdoutFileIO, toTruffleStringUncached(""), 1, IOMode.WB); - Object stdoutBuffer = createBufferedIO(buffering, factory, stdoutFileIO, posixSupport, posixLib); - setWrapper(T_STDOUT, T___STDOUT__, T_W, stdioEncoding, stdioError, stdoutBuffer, sysModule, factory, buffering); + Object stdoutBuffer = createBufferedIO(buffering, language, stdoutFileIO, posixSupport, posixLib); + setWrapper(T_STDOUT, T___STDOUT__, T_W, stdioEncoding, stdioError, stdoutBuffer, sysModule, language, buffering); - PFileIO stderr = factory.createFileIO(PythonBuiltinClassType.PFileIO); + PFileIO stderr = PFactory.createFileIO(language); FileIOBuiltins.FileIOInit.internalInit(stderr, toTruffleStringUncached(""), 2, IOMode.WB); - Object stderrBuffer = createBufferedIO(buffering, factory, stderr, posixSupport, posixLib); - setWrapper(T_STDERR, T___STDERR__, T_W, stdioEncoding, T_BACKSLASHREPLACE, stderrBuffer, sysModule, factory, buffering); + Object stderrBuffer = createBufferedIO(buffering, language, stderr, posixSupport, posixLib); + setWrapper(T_STDERR, T___STDERR__, T_W, stdioEncoding, T_BACKSLASHREPLACE, stderrBuffer, sysModule, language, buffering); } - private static Object createBufferedIO(boolean buffering, PythonObjectFactory factory, PFileIO fileIo, Object posixSupport, PosixSupportLibrary posixLib) { + private static Object createBufferedIO(boolean buffering, PythonLanguage language, PFileIO fileIo, Object posixSupport, PosixSupportLibrary posixLib) { if (!buffering) { return fileIo; } - PBuffered writer = factory.createBufferedWriter(PythonBuiltinClassType.PBufferedWriter); - BufferedWriterBuiltins.BufferedWriterInit.internalInit(writer, fileIo, BufferedReaderBuiltins.DEFAULT_BUFFER_SIZE, factory, posixSupport, posixLib); + PBuffered writer = PFactory.createBufferedWriter(language); + BufferedWriterBuiltins.BufferedWriterInit.internalInit(writer, fileIo, BufferedReaderBuiltins.DEFAULT_BUFFER_SIZE, language, posixSupport, posixLib); return writer; } private static PTextIO setWrapper(TruffleString name, TruffleString specialName, TruffleString mode, TruffleString encoding, TruffleString error, Object buffer, PythonModule sysModule, - PythonObjectFactory factory, boolean buffering) { - PTextIO textIOWrapper = factory.createTextIO(PythonBuiltinClassType.PTextIOWrapper); + PythonLanguage language, boolean buffering) { + PTextIO textIOWrapper = PFactory.createTextIO(language); TextIOWrapperInitNodeGen.getUncached().execute(null, null, textIOWrapper, buffer, encoding, error, PNone.NONE, /* line_buffering */ buffering, /* write_through */ !buffering); @@ -850,15 +810,15 @@ static PTuple run(VirtualFrame frame, @Cached GetEscapedExceptionNode getEscapedExceptionNode, @Cached GetCaughtExceptionNode getCaughtExceptionNode, @Cached ExceptionNodes.GetTracebackNode getTracebackNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { AbstractTruffleException currentException = getCaughtExceptionNode.execute(frame); assert currentException != PException.NO_EXCEPTION; if (currentException == null) { - return factory.createTuple(new PNone[]{PNone.NONE, PNone.NONE, PNone.NONE}); + return PFactory.createTuple(language, new PNone[]{PNone.NONE, PNone.NONE, PNone.NONE}); } else { Object exceptionObject = getEscapedExceptionNode.execute(inliningTarget, currentException); Object traceback = getTracebackNode.execute(inliningTarget, exceptionObject); - return factory.createTuple(new Object[]{getClassNode.execute(inliningTarget, exceptionObject), exceptionObject, traceback}); + return PFactory.createTuple(language, new Object[]{getClassNode.execute(inliningTarget, exceptionObject), exceptionObject, traceback}); } } } @@ -899,10 +859,10 @@ static PFrame counted(VirtualFrame frame, int num, @Bind("this") Node inliningTarget, @Cached ReadCallerFrameNode readCallerNode, @Cached InlinedConditionProfile callStackDepthProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { PFrame requested = escapeFrame(frame, num, readCallerNode); if (callStackDepthProfile.profile(inliningTarget, requested == null)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.CALL_STACK_NOT_DEEP_ENOUGH); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.CALL_STACK_NOT_DEEP_ENOUGH); } return requested; } @@ -925,13 +885,13 @@ Object currentFrames(VirtualFrame frame, @Cached WarningsModuleBuiltins.WarnNode warnNode, @Cached ReadCallerFrameNode readCallerFrameNode, @Cached HashingStorageSetItem setHashingStorageItem, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { auditNode.audit(inliningTarget, "sys._current_frames"); if (!getLanguage().singleThreadedAssumption.isValid()) { warnNode.warn(frame, RuntimeWarning, ErrorMessages.WARN_CURRENT_FRAMES_MULTITHREADED); } PFrame currentFrame = readCallerFrameNode.executeWith(frame, 0); - PDict result = factory.createDict(); + PDict result = PFactory.createDict(language); result.setDictStorage(setHashingStorageItem.execute(frame, inliningTarget, result.getDictStorage(), PThread.getThreadId(Thread.currentThread()), currentFrame)); return result; } @@ -967,18 +927,18 @@ public abstract static class InternNode extends PythonUnaryBuiltinNode { static Object doPString(Object s, @Bind("this") Node inliningTarget, @Cached StringNodes.InternStringNode internNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { final PString interned = internNode.execute(inliningTarget, s); if (interned == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANNOT_INTERN_P, s); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANNOT_INTERN_P, s); } return interned; } @Fallback static Object doOthers(Object obj, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.S_ARG_MUST_BE_S_NOT_P, "intern()", "str", obj); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.S_ARG_MUST_BE_S_NOT_P, "intern()", "str", obj); } } @@ -1030,7 +990,7 @@ static Object doGeneric(VirtualFrame frame, Object object, @SuppressWarnings("un @Bind("this") Node inliningTarget, @Shared @Cached PyNumberAsSizeNode asSizeNode, @Cached("createWithError()") LookupAndCallUnaryNode callSizeofNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { return checkResult(frame, inliningTarget, asSizeNode, callSizeofNode.executeObject(frame, object), raiseNode); } @@ -1039,7 +999,7 @@ static Object doGeneric(VirtualFrame frame, Object object, Object dflt, @Bind("this") Node inliningTarget, @Shared @Cached PyNumberAsSizeNode asSizeNode, @Cached("createWithoutError()") LookupAndCallUnaryNode callSizeofNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { Object result = callSizeofNode.executeObject(frame, object); if (result == PNone.NO_VALUE) { return dflt; @@ -1047,10 +1007,10 @@ static Object doGeneric(VirtualFrame frame, Object object, Object dflt, return checkResult(frame, inliningTarget, asSizeNode, result, raiseNode); } - private static Object checkResult(VirtualFrame frame, Node inliningTarget, PyNumberAsSizeNode asSizeNode, Object result, PRaiseNode.Lazy raiseNode) { + private static Object checkResult(VirtualFrame frame, Node inliningTarget, PyNumberAsSizeNode asSizeNode, Object result, PRaiseNode raiseNode) { int value = asSizeNode.executeExact(frame, inliningTarget, result); if (value < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.SHOULD_RETURN, "__sizeof__()", ">= 0"); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.SHOULD_RETURN, "__sizeof__()", ">= 0"); } return value; } @@ -1058,11 +1018,12 @@ private static Object checkResult(VirtualFrame frame, Node inliningTarget, PyNum @NeverDefault protected LookupAndCallUnaryNode createWithError() { return LookupAndCallUnaryNode.create(T___SIZEOF__, () -> new NoAttributeHandler() { - @Child private PRaiseNode raiseNode = PRaiseNode.create(); + private final BranchProfile errorProfile = BranchProfile.create(); @Override public Object execute(Object receiver) { - throw raiseNode.raise(TypeError, ErrorMessages.TYPE_DOESNT_DEFINE_METHOD, receiver, T___SIZEOF__); + errorProfile.enter(); + throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.TYPE_DOESNT_DEFINE_METHOD, receiver, T___SIZEOF__); } }); } @@ -1222,11 +1183,11 @@ abstract static class GetAsyncgenHooks extends PythonBuiltinNode { static Object setAsyncgenHooks( @Bind("this") Node inliningTarget, @Bind PythonContext context, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { // TODO: use asyncgen_hooks object PythonContext.PythonThreadState threadState = context.getThreadState(context.getLanguage(inliningTarget)); Object firstiter = threadState.getAsyncgenFirstIter(); - return factory.createTuple(new Object[]{firstiter == null ? PNone.NONE : firstiter, PNone.NONE}); + return PFactory.createTuple(language, new Object[]{firstiter == null ? PNone.NONE : firstiter, PNone.NONE}); } } @@ -1342,10 +1303,10 @@ private void writeUnraisableExc(MaterializedFrame frame, PythonModule sys, Objec Object doit(VirtualFrame frame, PythonModule sys, Object args, @Bind("this") Node inliningTarget, @Cached PyTupleGetItem getItemNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { final Object cls = getObjectClass(args); if (cls != PythonBuiltinClassType.PUnraisableHookArgs) { - throw raiseNode.get(inliningTarget).raise(TypeError, ARG_TYPE_MUST_BE, "sys.unraisablehook", "UnraisableHookArgs"); + throw raiseNode.raise(inliningTarget, TypeError, ARG_TYPE_MUST_BE, "sys.unraisablehook", "UnraisableHookArgs"); } final Object excType = getItemNode.execute(inliningTarget, args, 0); final Object excValue = getItemNode.execute(inliningTarget, args, 1); @@ -1687,10 +1648,10 @@ static Object doHook(VirtualFrame frame, PythonModule sys, Object obj, @Cached CastToTruffleStringNode castToStringNode, @Cached PyUnicodeAsEncodedString pyUnicodeAsEncodedString, @Cached PyUnicodeFromEncodedObject pyUnicodeFromEncodedObject, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { final PythonModule builtins = PythonContext.get(inliningTarget).getBuiltins(); if (builtins == null) { - throw raiseNode.get(inliningTarget).raise(RuntimeError, LOST_S, "builtins module"); + throw raiseNode.raise(inliningTarget, RuntimeError, LOST_S, "builtins module"); } // Print value except if None // After printing, also assign to '_' @@ -1702,7 +1663,7 @@ static Object doHook(VirtualFrame frame, PythonModule sys, Object obj, setAttr.execute(frame, inliningTarget, builtins, T___, PNone.NONE); Object stdOut = objectLookupAttr(frame, inliningTarget, sys, T_STDOUT, lookupAttr); if (PGuards.isPNone(stdOut)) { - throw raiseNode.get(inliningTarget).raise(RuntimeError, LOST_S, "sys.stdout"); + throw raiseNode.raise(inliningTarget, RuntimeError, LOST_S, "sys.stdout"); } Object reprVal = null; @@ -1855,9 +1816,9 @@ static Object setRecLim(VirtualFrame frame, @SuppressWarnings("unused") PythonMo @Bind("this") Node inliningTarget, @Cached PyLongAsIntNode longAsIntNode, @Cached PyFloatCheckExactNode floatCheckExactNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (floatCheckExactNode.execute(inliningTarget, limit)) { - throw raiseNode.get(inliningTarget).raise(TypeError, S_EXPECTED_GOT_P, "integer", limit); + throw raiseNode.raise(inliningTarget, TypeError, S_EXPECTED_GOT_P, "integer", limit); } int newLimit; @@ -1868,7 +1829,7 @@ static Object setRecLim(VirtualFrame frame, @SuppressWarnings("unused") PythonMo } if (newLimit < 1) { - throw raiseNode.get(inliningTarget).raise(ValueError, REC_LIMIT_GREATER_THAN_1); + throw raiseNode.raise(inliningTarget, ValueError, REC_LIMIT_GREATER_THAN_1); } // TODO: check to see if Issue #25274 applies @@ -1908,9 +1869,9 @@ static Object setCheckInterval(VirtualFrame frame, @SuppressWarnings("unused") P @Cached WarningsModuleBuiltins.WarnNode warnNode, @Cached PyLongAsIntNode longAsIntNode, @Cached PyFloatCheckExactNode floatCheckExactNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (floatCheckExactNode.execute(inliningTarget, arg)) { - throw raiseNode.get(inliningTarget).raise(TypeError, S_EXPECTED_GOT_P, "integer", arg); + throw raiseNode.raise(inliningTarget, TypeError, S_EXPECTED_GOT_P, "integer", arg); } try { @@ -1956,10 +1917,10 @@ abstract static class SetSwitchIntervalNode extends PythonBuiltinNode { static Object setCheckInterval(VirtualFrame frame, @SuppressWarnings("unused") PythonModule sys, Object arg, @Bind("this") Node inliningTarget, @Cached PyFloatAsDoubleNode floatAsDoubleNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { double interval = floatAsDoubleNode.execute(frame, inliningTarget, arg); if (interval <= 0.0) { - throw raiseNode.get(inliningTarget).raise(ValueError, SWITCH_INTERVAL_MUST_BE_POSITIVE); + throw raiseNode.raise(inliningTarget, ValueError, SWITCH_INTERVAL_MUST_BE_POSITIVE); } PythonContext.get(inliningTarget).getSysModuleState().setSwitchInterval(FACTOR * interval); return PNone.NONE; @@ -1980,8 +1941,8 @@ abstract static class ExitNode extends PythonBinaryBuiltinNode { @Specialization @SuppressWarnings("unused") static Object exitNoCode(PythonModule sys, PNone status, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raiseSystemExit(PNone.NONE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseSystemExitStatic(inliningTarget, PNone.NONE); } @Specialization(guards = "!isPNone(status)") @@ -1989,15 +1950,14 @@ static Object exit(VirtualFrame frame, @SuppressWarnings("unused") PythonModule @Bind("this") Node inliningTarget, @Cached PyTupleCheckNode tupleCheckNode, @Cached TupleBuiltins.LenNode tupleLenNode, - @Cached PyTupleGetItem getItemNode, - @Shared @Cached PRaiseNode raiseNode) { + @Cached PyTupleGetItem getItemNode) { Object code = status; if (tupleCheckNode.execute(inliningTarget, status)) { if (tupleLenNode.executeInt(frame, status) == 1) { code = getItemNode.execute(inliningTarget, status, 0); } } - throw raiseNode.raiseSystemExit(code); + throw PRaiseNode.raiseSystemExitStatic(inliningTarget, code); } } @@ -2058,14 +2018,15 @@ abstract static class Getwindowsversion extends PythonBuiltinNode { static int PLATFORM = 2; @Specialization - PTuple getVersion(@Cached PythonObjectFactory factory) { + PTuple getVersion( + @Bind PythonLanguage language) { if (CACHED_VERSION_INFO == null) { cacheVersion(); } - return factory.createStructSeq(WINDOWS_VER_DESC, + return PFactory.createStructSeq(language, WINDOWS_VER_DESC, CACHED_VERSION_INFO[0], CACHED_VERSION_INFO[1], CACHED_VERSION_INFO[2], PLATFORM, T_EMPTY_STRING, 0, 0, 0, 1, - factory.createTuple(CACHED_VERSION_INFO)); + PFactory.createTuple(language, CACHED_VERSION_INFO)); } @TruffleBoundary diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java index 8a50577f63..d6a34eb6a1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -49,6 +49,7 @@ import java.lang.ref.WeakReference; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -59,9 +60,8 @@ import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.thread.PLock; -import com.oracle.graal.python.builtins.objects.thread.PRLock; import com.oracle.graal.python.builtins.objects.thread.PThread; -import com.oracle.graal.python.builtins.objects.thread.PThreadLocal; +import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.WriteUnraisableNode; @@ -71,25 +71,25 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonThreadKillException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.TruffleThreadBuilder; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -110,44 +110,14 @@ public void initialize(Python3Core core) { super.initialize(core); } - @Builtin(name = "_local", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PThreadLocal) - @GenerateNodeFactory - abstract static class ThreadLocalNode extends PythonBuiltinNode { - @Specialization - PThreadLocal construct(Object cls, Object[] args, PKeyword[] keywordArgs, - @Cached PythonObjectFactory factory) { - return factory.createThreadLocal(cls, args, keywordArgs); - } - } - @Builtin(name = "allocate_lock", maxNumOfPositionalArgs = 2) @GenerateNodeFactory public abstract static class AllocateLockNode extends PythonBinaryBuiltinNode { @Specialization @SuppressWarnings("unused") PLock construct(Object self, Object unused, - @Cached PythonObjectFactory factory) { - return factory.createLock(PythonBuiltinClassType.PLock); - } - } - - @Builtin(name = "LockType", minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.PLock) - @GenerateNodeFactory - abstract static class ConstructLockNode extends PythonUnaryBuiltinNode { - @Specialization - PLock construct(Object cls, - @Cached PythonObjectFactory factory) { - return factory.createLock(cls); - } - } - - @Builtin(name = "RLock", minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.PRLock) - @GenerateNodeFactory - abstract static class ConstructRLockNode extends PythonUnaryBuiltinNode { - @Specialization - PRLock construct(Object cls, - @Cached PythonObjectFactory factory) { - return factory.createRLock(cls); + @Bind PythonLanguage language) { + return PFactory.createLock(language); } } @@ -183,41 +153,41 @@ long getCount(PythonModule self) { @Builtin(name = "stack_size", minNumOfPositionalArgs = 0, maxNumOfPositionalArgs = 1) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class GetThreadStackSizeNode extends PythonUnaryBuiltinNode { - @Specialization + @Specialization(guards = "isNoValue(stackSize)") long getStackSize(@SuppressWarnings("unused") PNone stackSize) { return getContext().getPythonThreadStackSize(); } - @Specialization - static long getStackSize(long stackSize, + @Fallback + static long getStackSize(VirtualFrame frame, Object stackSizeObj, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PyNumberAsSizeNode asSizeNode, + @Cached PRaiseNode raiseNode) { + int stackSize = asSizeNode.executeExact(frame, inliningTarget, stackSizeObj); if (stackSize < 0) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.SIZE_MUST_BE_D_OR_S, 0, "a positive value"); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.SIZE_MUST_BE_D_OR_S, 0, "a positive value"); } return PythonContext.get(inliningTarget).getAndSetPythonsThreadStackSize(stackSize); } } - @Builtin(name = "start_new_thread", minNumOfPositionalArgs = 3, maxNumOfPositionalArgs = 4, constructsClass = PythonBuiltinClassType.PThread) - @Builtin(name = "start_new", minNumOfPositionalArgs = 3, maxNumOfPositionalArgs = 4) + @Builtin(name = "start_new_thread", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3) + @Builtin(name = "start_new", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3) @GenerateNodeFactory - abstract static class StartNewThreadNode extends PythonBuiltinNode { + abstract static class StartNewThreadNode extends PythonTernaryBuiltinNode { private static final TruffleString IN_THREAD_STARTED_BY = tsLiteral("in thread started by"); @Specialization @SuppressWarnings("try") - long start(VirtualFrame frame, Object cls, Object callable, Object args, Object kwargs, + static long start(VirtualFrame frame, Object callable, Object args, Object kwargs, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached CallNode callNode, @Cached ExecutePositionalStarargsNode getArgsNode, - @Cached ExpandKeywordStarargsNode getKwArgsNode, - @Cached PythonObjectFactory factory) { - PythonContext context = getContext(); + @Cached ExpandKeywordStarargsNode getKwArgsNode) { TruffleLanguage.Env env = context.getEnv(); PythonModule threadModule = context.lookupBuiltinModule(T__THREAD); @@ -252,9 +222,14 @@ long start(VirtualFrame frame, Object cls, Object callable, Object args, Object } }).context(env.getContext()).threadGroup(context.getThreadGroup()); - PThread pThread = factory.createPythonThread(cls, threadBuilder.build()); - pThread.start(); - return pThread.getId(); + Thread thread = threadBuilder.build(); + startThread(thread); + return thread.getId(); + } + + @TruffleBoundary + private static void startThread(Thread thread) { + thread.start(); } } @@ -264,8 +239,9 @@ abstract static class SetSentinelNode extends PythonBuiltinNode { @Specialization @TruffleBoundary Object setSentinel() { - PLock sentinelLock = PythonObjectFactory.getUncached().createLock(); - PythonContext.get(this).setSentinelLockWeakref(new WeakReference<>(sentinelLock)); + PythonContext context = PythonContext.get(null); + PLock sentinelLock = PFactory.createLock(context.getLanguage()); + context.setSentinelLockWeakref(new WeakReference<>(sentinelLock)); return sentinelLock; } } @@ -298,8 +274,8 @@ protected ArgumentClinicProvider getArgumentClinic() { abstract static class ExitThreadNode extends PythonBuiltinNode { @Specialization static Object exit( - @Cached PRaiseNode raiseNode) { - throw raiseNode.raiseSystemExit(PNone.NONE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseSystemExitStatic(inliningTarget, PNone.NONE); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TimeModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TimeModuleBuiltins.java index 46bd74525e..3f9b4a15d2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TimeModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TimeModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -49,8 +49,7 @@ import java.util.List; import java.util.TimeZone; -import org.graalvm.nativeimage.ImageInfo; - +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -85,15 +84,17 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; +import com.oracle.graal.python.nodes.statement.AbstractImportNode; +import com.oracle.graal.python.nodes.truffle.PythonIntegerAndFloatTypes; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaDoubleNode; import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonImageBuildOptions; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.TruffleOptions; import com.oracle.truffle.api.TruffleSafepoint; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -120,15 +121,6 @@ public final class TimeModuleBuiltins extends PythonBuiltins { private static final StructSequence.BuiltinTypeDescriptor STRUCT_TIME_DESC = new StructSequence.BuiltinTypeDescriptor( PythonBuiltinClassType.PStructTime, - // @formatter:off The formatter joins these lines making it less readable - "The time value as returned by gmtime(), localtime(), and strptime(), and\n" + - " accepted by asctime(), mktime() and strftime(). May be considered as a\n" + - " sequence of 9 integers.\n\n" + - " Note that several fields' values are not the same as those defined by\n" + - " the C language standard for struct tm. For example, the value of the\n" + - " field tm_year is the actual year, not year - 1900. See individual\n" + - " fields' descriptions for details.", - // @formatter:on 9, new String[]{ "tm_year", "tm_mon", "tm_mday", "tm_hour", "tm_min", "tm_sec", @@ -153,6 +145,7 @@ public final class TimeModuleBuiltins extends PythonBuiltins { public static final TruffleString T_DAYLIGHT = tsLiteral("daylight"); public static final TruffleString T_TIMEZONE = tsLiteral("timezone"); public static final TruffleString T_ALTZONE = tsLiteral("altzone"); + public static final TruffleString T_POLYGLOT_TIME = tsLiteral("_polyglot_time"); @Override protected List> getNodeFactories() { @@ -183,15 +176,18 @@ public void postInitialize(Python3Core core) { boolean hasDaylightSaving = !noDaylightSavingZone.equalsUncached(daylightSavingZone, TS_ENCODING); if (hasDaylightSaving) { - timeModule.setAttribute(T_TZNAME, core.factory().createTuple(new Object[]{noDaylightSavingZone, daylightSavingZone})); + timeModule.setAttribute(T_TZNAME, PFactory.createTuple(core.getLanguage(), new Object[]{noDaylightSavingZone, daylightSavingZone})); } else { - timeModule.setAttribute(T_TZNAME, core.factory().createTuple(new Object[]{noDaylightSavingZone})); + timeModule.setAttribute(T_TZNAME, PFactory.createTuple(core.getLanguage(), new Object[]{noDaylightSavingZone})); } timeModule.setAttribute(T_DAYLIGHT, PInt.intValue(hasDaylightSaving)); int rawOffsetSeconds = defaultTimeZone.getRawOffset() / -1000; timeModule.setAttribute(T_TIMEZONE, rawOffsetSeconds); timeModule.setAttribute(T_ALTZONE, rawOffsetSeconds - 3600); + + // register_interop_behavior() for time.struct_time + AbstractImportNode.importModule(T_POLYGLOT_TIME); } @TruffleBoundary @@ -265,21 +261,21 @@ static long doNone(VirtualFrame frame, Node inliningTarget, PNone none) { @Specialization static long doLong(Node inliningTarget, long t, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { check(inliningTarget, t, raiseNode); return t; } @Specialization static long doDouble(Node inliningTarget, double t, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { check(inliningTarget, t, raiseNode); return (long) t; } @Specialization(guards = "!isPNone(obj)") static long doObject(VirtualFrame frame, Node inliningTarget, Object obj, - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Cached CastToJavaDoubleNode castToDouble, @Cached PyLongAsLongNode asLongNode) { long t; @@ -296,9 +292,9 @@ private static boolean isValidTime(double t) { return t >= MIN_TIME && t <= MAX_TIME; } - private static void check(Node inliningTarget, double time, PRaiseNode.Lazy raiseNode) { + private static void check(Node inliningTarget, double time, PRaiseNode raiseNode) { if (!isValidTime(time)) { - throw raiseNode.get(inliningTarget).raise(OverflowError, TIMESTAMP_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, OverflowError, TIMESTAMP_OUT_OF_RANGE); } } } @@ -306,15 +302,14 @@ private static void check(Node inliningTarget, double time, PRaiseNode.Lazy rais // time.gmtime([seconds]) @Builtin(name = "gmtime", maxNumOfPositionalArgs = 1) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) public abstract static class PythonGMTimeNode extends PythonBuiltinNode { @Specialization static PTuple gmtime(VirtualFrame frame, Object seconds, @Bind("this") Node inliningTarget, @Cached ToLongTime toLongTime, - @Cached PythonObjectFactory factory) { - return factory.createStructSeq(STRUCT_TIME_DESC, getTimeStruct(GMT, toLongTime.execute(frame, inliningTarget, seconds))); + @Bind PythonLanguage language) { + return PFactory.createStructSeq(language, STRUCT_TIME_DESC, getTimeStruct(GMT, toLongTime.execute(frame, inliningTarget, seconds))); } } @@ -333,7 +328,7 @@ Object tzset() { } TimeZone.setDefault(TimeZone.getTimeZone(tzEnv)); } else { - PRaiseNode.raiseUncached(this, PythonBuiltinClassType.AttributeError, SET_TIMEZONE_ERROR); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.AttributeError, SET_TIMEZONE_ERROR); } return PNone.NONE; } @@ -342,16 +337,15 @@ Object tzset() { // time.localtime([seconds]) @Builtin(name = "localtime", maxNumOfPositionalArgs = 2, declaresExplicitSelf = true) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) public abstract static class PythonLocalTimeNode extends PythonBinaryBuiltinNode { @Specialization static PTuple localtime(VirtualFrame frame, PythonModule module, Object seconds, @Bind("this") Node inliningTarget, @Cached ToLongTime toLongTime, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { ModuleState moduleState = module.getModuleState(ModuleState.class); - return factory.createStructSeq(STRUCT_TIME_DESC, getTimeStruct(moduleState.currentZoneId, toLongTime.execute(frame, inliningTarget, seconds))); + return PFactory.createStructSeq(language, STRUCT_TIME_DESC, getTimeStruct(moduleState.currentZoneId, toLongTime.execute(frame, inliningTarget, seconds))); } } @@ -446,7 +440,6 @@ public long counter() { @Builtin(name = "process_time", minNumOfPositionalArgs = 1, declaresExplicitSelf = true) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class ProcessTimeNode extends PythonBuiltinNode { @Specialization @TruffleBoundary @@ -458,7 +451,6 @@ Object getProcesTime(PythonModule self) { @Builtin(name = "process_time_ns", minNumOfPositionalArgs = 1, declaresExplicitSelf = true) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class ProcessTimeNsNode extends PythonBuiltinNode { @Specialization @TruffleBoundary @@ -470,29 +462,27 @@ Object getProcesNsTime(PythonModule self) { @Builtin(name = "thread_time") @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class ThreadTimeNode extends PythonBuiltinNode { @Specialization @TruffleBoundary Object getProcesTime() { - return !ImageInfo.inImageCode() ? (ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime()) / 1000_000_000.0 : 0; + return !TruffleOptions.AOT ? (ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime()) / 1000_000_000.0 : 0; } } @Builtin(name = "thread_time_ns") @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class ThreadTimeNsNode extends PythonBuiltinNode { @Specialization @TruffleBoundary Object getProcesNsTime() { - return !ImageInfo.inImageCode() ? ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime() : 0; + return !TruffleOptions.AOT ? ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime() : 0; } } @Builtin(name = "sleep", minNumOfPositionalArgs = 2, declaresExplicitSelf = true) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerAndFloatTypes.class) abstract static class SleepNode extends PythonBuiltinNode { // see: https://github.com/python/cpython/blob/master/Modules/timemodule.c#L1741 @@ -517,8 +507,8 @@ Object sleep(PythonModule self, long seconds, @SuppressWarnings("unused") @Specialization(guards = "!isPositive(seconds)") static Object err(PythonModule self, long seconds, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, MUST_BE_NON_NEGATIVE, "sleep length"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, MUST_BE_NON_NEGATIVE, "sleep length"); } @Specialization(guards = "isPositive(seconds)") @@ -541,8 +531,8 @@ Object sleep(PythonModule self, double seconds, @SuppressWarnings("unused") @Specialization(guards = "!isPositive(seconds)") static Object err(PythonModule self, double seconds, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, MUST_BE_NON_NEGATIVE, "sleep length"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, MUST_BE_NON_NEGATIVE, "sleep length"); } @Specialization(guards = "!isInteger(secondsObj)") @@ -624,10 +614,10 @@ private static String timeFormat(int[] date) { protected static int[] checkStructtime(VirtualFrame frame, Node inliningTarget, PTuple time, SequenceStorageNodes.GetInternalObjectArrayNode getInternalObjectArrayNode, PyNumberAsSizeNode asSizeNode, - PRaiseNode.Lazy raiseNode) { + PRaiseNode raiseNode) { Object[] otime = getInternalObjectArrayNode.execute(inliningTarget, time.getSequenceStorage()); if (time.getSequenceStorage().length() != 9) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_ILLEGAL_TIME_TUPLE_ARG, "asctime()"); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_ILLEGAL_TIME_TUPLE_ARG, "asctime()"); } int[] date = new int[9]; for (int i = 0; i < 9; i++) { @@ -636,37 +626,37 @@ protected static int[] checkStructtime(VirtualFrame frame, Node inliningTarget, // This is specific to java if (date[TM_YEAR] < Year.MIN_VALUE || date[TM_YEAR] > Year.MAX_VALUE) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.YEAR_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.YEAR_OUT_OF_RANGE); } if (date[TM_MON] == 0) { date[TM_MON] = 1; } else if (date[TM_MON] < 0 || date[TM_MON] > 12) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MONTH_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MONTH_OUT_OF_RANGE); } if (date[TM_MDAY] == 0) { date[TM_MDAY] = 1; } else if (date[TM_MDAY] < 0 || date[TM_MDAY] > 31) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.DAY_OF_MONTH_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.DAY_OF_MONTH_OUT_OF_RANGE); } if (date[TM_HOUR] < 0 || date[TM_HOUR] > 23) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.HOUR_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.HOUR_OUT_OF_RANGE); } if (date[TM_MIN] < 0 || date[TM_MIN] > 59) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MINUTE_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MINUTE_OUT_OF_RANGE); } if (date[TM_SEC] < 0 || date[TM_SEC] > 61) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.SECONDS_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.SECONDS_OUT_OF_RANGE); } if (date[TM_WDAY] == -1) { date[TM_WDAY] = 6; } else if (date[TM_WDAY] < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.DAY_OF_WEEK_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.DAY_OF_WEEK_OUT_OF_RANGE); } else if (date[TM_WDAY] > 6) { date[TM_WDAY] = date[TM_WDAY] % 7; } @@ -674,7 +664,7 @@ protected static int[] checkStructtime(VirtualFrame frame, Node inliningTarget, if (date[TM_YDAY] == 0) { date[TM_YDAY] = 1; } else if (date[TM_YDAY] < 0 || date[TM_YDAY] > 366) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.DAY_OF_YEAR_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.DAY_OF_YEAR_OUT_OF_RANGE); } if (date[TM_ISDST] < -1) { @@ -939,9 +929,9 @@ static TruffleString formatTime(PythonModule module, TruffleString format, @Supp @Shared("byteIndexOfCp") @Cached TruffleString.ByteIndexOfCodePointNode byteIndexOfCodePointNode, @Shared("ts2js") @Cached TruffleString.ToJavaStringNode toJavaStringNode, @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (byteIndexOfCodePointNode.execute(format, 0, 0, format.byteLength(TS_ENCODING), TS_ENCODING) >= 0) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.EMBEDDED_NULL_CHARACTER); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.EMBEDDED_NULL_CHARACTER); } ModuleState moduleState = module.getModuleState(ModuleState.class); return format(toJavaStringNode.execute(format), getIntLocalTimeStruct(moduleState.currentZoneId, (long) timeSeconds()), fromJavaStringNode); @@ -955,9 +945,9 @@ static TruffleString formatTime(VirtualFrame frame, @SuppressWarnings("unused") @Shared("byteIndexOfCp") @Cached TruffleString.ByteIndexOfCodePointNode byteIndexOfCodePointNode, @Shared("ts2js") @Cached TruffleString.ToJavaStringNode toJavaStringNode, @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (byteIndexOfCodePointNode.execute(format, 0, 0, format.byteLength(TS_ENCODING), TS_ENCODING) >= 0) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.EMBEDDED_NULL_CHARACTER); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.EMBEDDED_NULL_CHARACTER); } int[] date = checkStructtime(frame, inliningTarget, time, getArray, asSizeNode, raiseNode); return format(toJavaStringNode.execute(format), date, fromJavaStringNode); @@ -966,8 +956,8 @@ static TruffleString formatTime(VirtualFrame frame, @SuppressWarnings("unused") @Specialization @SuppressWarnings("unused") static TruffleString formatTime(PythonModule module, TruffleString format, Object time, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.TUPLE_OR_STRUCT_TIME_ARG_REQUIRED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.TUPLE_OR_STRUCT_TIME_ARG_REQUIRED); } } @@ -986,10 +976,10 @@ static double mktime(VirtualFrame frame, PythonModule module, PTuple tuple, @Bind("this") Node inliningTarget, @Cached PyNumberAsSizeNode asSizeNode, @Cached GetObjectArrayNode getObjectArrayNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object[] items = getObjectArrayNode.execute(inliningTarget, tuple); if (items.length != ELEMENT_COUNT) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.FUNC_TAKES_EXACTLY_D_ARGS, ELEMENT_COUNT, items.length); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.FUNC_TAKES_EXACTLY_D_ARGS, ELEMENT_COUNT, items.length); } int[] integers = new int[ELEMENT_COUNT]; for (int i = 0; i < ELEMENT_COUNT; i++) { @@ -1052,15 +1042,15 @@ static TruffleString localtime(VirtualFrame frame, @SuppressWarnings("unused") P @Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray, @Cached PyNumberAsSizeNode asSizeNode, @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { return format(StrfTimeNode.checkStructtime(frame, inliningTarget, time, getArray, asSizeNode, raiseNode), fromJavaStringNode); } @Fallback @SuppressWarnings("unused") static Object localtime(Object module, Object time, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.TUPLE_OR_STRUCT_TIME_ARG_REQUIRED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.TUPLE_OR_STRUCT_TIME_ARG_REQUIRED); } protected static TruffleString format(int[] tm, TruffleString.FromJavaStringNode fromJavaStringNode) { @@ -1108,8 +1098,8 @@ static Object getClockInfo(TruffleString name, @Bind("this") Node inliningTarget, @Cached WriteAttributeToPythonObjectNode writeAttrNode, @Cached TruffleString.EqualNode equalNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { final boolean adjustable; final boolean monotonic; @@ -1121,10 +1111,10 @@ static Object getClockInfo(TruffleString name, adjustable = true; monotonic = false; } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, UNKNOWN_CLOCK); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, UNKNOWN_CLOCK); } - final PSimpleNamespace ns = factory.createSimpleNamespace(); + final PSimpleNamespace ns = PFactory.createSimpleNamespace(language); writeAttrNode.execute(ns, T_ADJUSTABLE, adjustable); writeAttrNode.execute(ns, T_IMPLEMENTATION, name); writeAttrNode.execute(ns, T_MONOTONIC, monotonic); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TokenizeModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TokenizeModuleBuiltins.java index 5edfab4e64..8f9919ff71 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TokenizeModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TokenizeModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,49 +40,20 @@ */ package com.oracle.graal.python.builtins.modules; +import java.util.Collections; import java.util.List; -import com.oracle.graal.python.annotations.ArgumentClinic; -import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; -import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.modules.TokenizeModuleBuiltinsClinicProviders.TokenizerIterNodeClinicProviderGen; -import com.oracle.graal.python.builtins.objects.tokenize.PTokenizerIter; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.strings.TruffleString; @CoreFunctions(defineModule = "_tokenize", isEager = true) public final class TokenizeModuleBuiltins extends PythonBuiltins { @Override protected List> getNodeFactories() { - return TokenizeModuleBuiltinsFactory.getFactories(); + return Collections.emptyList(); } - @Builtin(name = "TokenizerIter", minNumOfPositionalArgs = 2, parameterNames = {"$cls", "source"}, constructsClass = PythonBuiltinClassType.PTokenizerIter) - @ArgumentClinic(name = "source", conversion = ClinicConversion.TString) - @GenerateNodeFactory - abstract static class TokenizerIterNode extends PythonBinaryClinicBuiltinNode { - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return TokenizerIterNodeClinicProviderGen.INSTANCE; - } - - @Specialization - static PTokenizerIter tokenizerIter(Object cls, TruffleString source, - @Cached TruffleString.ToJavaStringNode toJavaStringNode, - @Cached PythonObjectFactory factory) { - return factory.createTokenizerIter(cls, toJavaStringNode.execute(source)); - } - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TracemallocModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TracemallocModuleBuiltins.java index 7ba1ed0fbc..ae552073fa 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TracemallocModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TracemallocModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -52,10 +52,11 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; -import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; @CoreFunctions(defineModule = J__TRACEMALLOC) public final class TracemallocModuleBuiltins extends PythonBuiltins { @@ -75,8 +76,8 @@ public void initialize(Python3Core core) { abstract static class GetObjectTracebackNode extends PythonBuiltinNode { @Specialization static Object getObjectTraceback(Object obj, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.NotImplementedError); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.NotImplementedError); } } @@ -85,8 +86,8 @@ static Object getObjectTraceback(Object obj, abstract static class GetTracesNode extends PythonBuiltinNode { @Specialization static Object getTraces( - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.NotImplementedError); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.NotImplementedError); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/UnicodeDataModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/UnicodeDataModuleBuiltins.java index 354414ca22..b7266e6953 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/UnicodeDataModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/UnicodeDataModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,11 +40,15 @@ */ package com.oracle.graal.python.builtins.modules; +import static com.oracle.graal.python.nodes.BuiltinNames.J_UNICODEDATA; +import static com.oracle.graal.python.nodes.BuiltinNames.T_UNICODEDATA; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; +import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; import java.util.List; +import com.oracle.graal.python.builtins.objects.module.PythonModule; import org.graalvm.shadowed.com.ibm.icu.lang.UCharacter; import org.graalvm.shadowed.com.ibm.icu.lang.UProperty; import org.graalvm.shadowed.com.ibm.icu.text.Normalizer2; @@ -73,14 +77,15 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; -@CoreFunctions(defineModule = "unicodedata") +@CoreFunctions(defineModule = J_UNICODEDATA, isEager = true) public final class UnicodeDataModuleBuiltins extends PythonBuiltins { @Override protected List> getNodeFactories() { return UnicodeDataModuleBuiltinsFactory.getFactories(); } - public static String getUnicodeVersion() { + // Must not be used at image build time because ICU is --initialize-at-run-time + private static String getUnicodeVersion() { VersionInfo version = UCharacter.getUnicodeVersion(); return Integer.toString(version.getMajor()) + '.' + version.getMinor() + '.' + @@ -104,9 +109,10 @@ private static String getUnicodeNameTB(int cp) { } @Override - public void initialize(Python3Core core) { - super.initialize(core); - addBuiltinConstant("unidata_version", getUnicodeVersion()); + public void postInitialize(Python3Core core) { + super.postInitialize(core); + PythonModule self = core.lookupBuiltinModule(T_UNICODEDATA); + self.setAttribute(toTruffleStringUncached("unidata_version"), toTruffleStringUncached(getUnicodeVersion())); } static final int NORMALIZER_FORM_COUNT = 4; @@ -141,7 +147,7 @@ static TruffleString normalize(@SuppressWarnings("unused") TruffleString form, T @Specialization(guards = "getNormalizer(form) == null") TruffleString invalidForm(@SuppressWarnings("unused") TruffleString form, @SuppressWarnings("unused") TruffleString unistr) { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.INVALID_NORMALIZATION_FORM); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.INVALID_NORMALIZATION_FORM); } @TruffleBoundary @@ -173,7 +179,7 @@ boolean isNormalized(@SuppressWarnings("unused") TruffleString form, TruffleStri @Specialization(guards = "getNormalizer(form) == null") TruffleString invalidForm(@SuppressWarnings("unused") TruffleString form, @SuppressWarnings("unused") TruffleString unistr) { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.INVALID_NORMALIZATION_FORM); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.INVALID_NORMALIZATION_FORM); } @Override @@ -192,11 +198,11 @@ public abstract static class NameNode extends PythonBinaryClinicBuiltinNode { static Object name(int cp, Object defaultValue, @Bind("this") Node inliningTarget, @Cached TruffleString.FromJavaStringNode fromJavaStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { String result = getUnicodeName(cp); if (result == null) { if (defaultValue == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.NO_SUCH_NAME); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NO_SUCH_NAME); } return defaultValue; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java index 21648c3b82..24a4dff276 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java @@ -96,7 +96,7 @@ import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode; -import com.oracle.graal.python.lib.PyObjectRichCompareBool; +import com.oracle.graal.python.lib.PyObjectRichCompareBool.CachedPyObjectRichCompareBool; import com.oracle.graal.python.lib.PyObjectSetItem; import com.oracle.graal.python.lib.PyObjectStrAsObjectNode; import com.oracle.graal.python.nodes.ErrorMessages; @@ -122,8 +122,7 @@ import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.formatting.ErrorMessageFormatter; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; @@ -176,9 +175,9 @@ public void initialize(Python3Core core) { // we need to copy the attrs, since they must still be available even if the user `del`s the // attrs addBuiltinConstant("_defaultaction", T_DEFAULT); - PDict onceregistry = core.factory().createDict(); + PDict onceregistry = PFactory.createDict(core.getLanguage()); addBuiltinConstant("_onceregistry", onceregistry); - PList filters = initFilters(core.factory()); + PList filters = initFilters(core.getLanguage()); addBuiltinConstant("filters", filters); ModuleState moduleState = new ModuleState(); moduleState.filtersVersion = 0L; @@ -189,28 +188,26 @@ public void initialize(Python3Core core) { super.initialize(core); } - private static PTuple createFilter(PythonObjectSlowPathFactory factory, PythonBuiltinClassType cat, TruffleString id, Object mod) { - return factory.createTuple(new Object[]{id, PNone.NONE, cat, mod, 0}); + private static PTuple createFilter(PythonLanguage language, PythonBuiltinClassType cat, TruffleString id, Object mod) { + return PFactory.createTuple(language, new Object[]{id, PNone.NONE, cat, mod, 0}); } // init_filters - private static PList initFilters(PythonObjectSlowPathFactory factory) { - return factory.createList(new Object[]{ - createFilter(factory, PythonBuiltinClassType.DeprecationWarning, T_DEFAULT, T___MAIN__), - createFilter(factory, PythonBuiltinClassType.DeprecationWarning, T_IGNORE, PNone.NONE), - createFilter(factory, PythonBuiltinClassType.PendingDeprecationWarning, T_IGNORE, PNone.NONE), - createFilter(factory, PythonBuiltinClassType.ImportWarning, T_IGNORE, PNone.NONE), - createFilter(factory, PythonBuiltinClassType.ResourceWarning, T_IGNORE, PNone.NONE)}); + private static PList initFilters(PythonLanguage language) { + return PFactory.createList(language, new Object[]{ + createFilter(language, PythonBuiltinClassType.DeprecationWarning, T_DEFAULT, T___MAIN__), + createFilter(language, PythonBuiltinClassType.DeprecationWarning, T_IGNORE, PNone.NONE), + createFilter(language, PythonBuiltinClassType.PendingDeprecationWarning, T_IGNORE, PNone.NONE), + createFilter(language, PythonBuiltinClassType.ImportWarning, T_IGNORE, PNone.NONE), + createFilter(language, PythonBuiltinClassType.ResourceWarning, T_IGNORE, PNone.NONE)}); } static final class WarningsModuleNode extends Node { @Child CastToTruffleStringNode castStr; - @Child PRaiseNode raiseNode; - @Child PyObjectRichCompareBool.EqNode eqNode; + @Child CachedPyObjectRichCompareBool eqNode; @Child GetClassNode getClassNode; @Child PyNumberAsSizeNode asSizeNode; @Child PyObjectIsTrueNode isTrueNode; - @Child PythonObjectFactory factory; @Child IsSubClassNode isSubClassNode; @Child GetOrCreateDictNode getDictNode; @Child GetDictFromGlobalsNode getDictFromGlobalsNode; @@ -241,10 +238,10 @@ private PythonContext getContext() { return PythonContext.get(this); } - private PyObjectRichCompareBool.EqNode getEqNode() { + private CachedPyObjectRichCompareBool getEqNode() { if (eqNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - eqNode = insert(PyObjectRichCompareBool.EqNode.create()); + eqNode = insert(CachedPyObjectRichCompareBool.create()); } return eqNode; } @@ -378,24 +375,6 @@ private TruffleString.SubstringNode getSubstringNode() { return substringNode; } - private PRaiseNode getRaise() { - if (raiseNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - reportPolymorphicSpecialize(); - raiseNode = insert(PRaiseNode.create()); - } - return raiseNode; - } - - private PythonObjectFactory getFactory() { - if (factory == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - reportPolymorphicSpecialize(); - factory = insert(PythonObjectFactory.create()); - } - return factory; - } - private IsSubClassNode getIsSubClass() { if (isSubClassNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -476,7 +455,7 @@ private boolean checkMatched(VirtualFrame frame, Object obj, Object arg) { return getEqualNode().execute(objStr, getCastStr().executeCached(arg), TS_ENCODING); } catch (CannotCastException e) { // Python calls PyUnicode_Compare directly, which raises this error - throw getRaise().raise(PythonBuiltinClassType.TypeError, ErrorMessages.CANT_COMPARE, obj, arg); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.CANT_COMPARE, obj, arg); } } catch (CannotCastException e) { Object result = getCallMethodNode().executeCached(frame, obj, T_MATCH, arg); @@ -540,7 +519,7 @@ private static PDict getOnceRegistry(Node node, PythonContext context, PythonMod registry = getStateOnceRegistry(module); } if (!(registry instanceof PDict)) { - throw PRaiseNode.raiseUncached(node, PythonBuiltinClassType.TypeError, ErrorMessages.WARN_ONCE_REG_MUST_BE_DICT, registry); + throw PRaiseNode.raiseStatic(node, PythonBuiltinClassType.TypeError, ErrorMessages.WARN_ONCE_REG_MUST_BE_DICT, registry); } return (PDict) registry; } @@ -556,7 +535,7 @@ private TruffleString getDefaultAction(VirtualFrame frame, PythonModule module) try { return getCastStr().executeCached(defaultAction); } catch (CannotCastException e) { - throw getRaise().raise(PythonBuiltinClassType.TypeError, ErrorMessages.WARN_DEF_ACTION_MUST_BE_STRING, defaultAction); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.WARN_DEF_ACTION_MUST_BE_STRING, defaultAction); } } @@ -571,18 +550,18 @@ private TruffleString getFilter(VirtualFrame frame, PythonModule _warnings, Obje filters = getStateFilters(_warnings); } if (!(filters instanceof PList)) { - throw getRaise().raise(PythonBuiltinClassType.ValueError, ErrorMessages.WARN_FILTERS_MUST_BE_LIST); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.ValueError, ErrorMessages.WARN_FILTERS_MUST_BE_LIST); } SequenceStorage filtersStorage = ((PList) filters).getSequenceStorage(); SequenceStorageNodes.GetItemScalarNode sequenceGetItem = getSequenceGetItemNode(); for (int i = 0; i < filtersStorage.length(); i++) { Object tmpItem = sequenceGetItem.executeCached(filtersStorage, i); if (!(tmpItem instanceof PTuple)) { - throw getRaise().raise(PythonBuiltinClassType.ValueError, ErrorMessages.WARN_FILTERS_IETM_ISNT_5TUPLE, i); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.ValueError, ErrorMessages.WARN_FILTERS_IETM_ISNT_5TUPLE, i); } SequenceStorage tmpStorage = ((PTuple) tmpItem).getSequenceStorage(); if (tmpStorage.length() != 5) { - throw getRaise().raise(PythonBuiltinClassType.ValueError, ErrorMessages.WARN_FILTERS_IETM_ISNT_5TUPLE, i); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.ValueError, ErrorMessages.WARN_FILTERS_IETM_ISNT_5TUPLE, i); } Object actionObj = sequenceGetItem.executeCached(tmpStorage, 0); @@ -592,7 +571,7 @@ private TruffleString getFilter(VirtualFrame frame, PythonModule _warnings, Obje } catch (CannotCastException e) { // CPython does this check after the other __getitem__ calls, but we know it's a // tuple so... - throw getRaise().raise(PythonBuiltinClassType.TypeError, ErrorMessages.ACTION_MUST_BE_STRING, actionObj); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.ACTION_MUST_BE_STRING, actionObj); } Object msg = sequenceGetItem.executeCached(tmpStorage, 1); Object cat = sequenceGetItem.executeCached(tmpStorage, 2); @@ -630,18 +609,18 @@ private boolean alreadyWarnedShouldNotSet(VirtualFrame frame, PythonModule _warn * warnings will be printed. */ private static boolean alreadyWarnedShouldSet(PythonModule _warnings, PDict registry, Object key) { - return alreadyWarned(null, _warnings, registry, key, true, PyObjectRichCompareBool.EqNode.getUncached(), PyObjectCallMethodObjArgs.getUncached(), PyDictGetItem.getUncached(), + return alreadyWarned(null, _warnings, registry, key, true, CachedPyObjectRichCompareBool.getUncached(), PyObjectCallMethodObjArgs.getUncached(), PyDictGetItem.getUncached(), PyObjectSetItem.getUncached(), PyObjectIsTrueNode.getUncached()); } /** * Used on both fast and slow path. */ - private static boolean alreadyWarned(VirtualFrame frame, PythonModule _warnings, PDict registry, Object key, boolean shouldSet, PyObjectRichCompareBool.EqNode eqNode, + private static boolean alreadyWarned(VirtualFrame frame, PythonModule _warnings, PDict registry, Object key, boolean shouldSet, CachedPyObjectRichCompareBool eqNode, PyObjectCallMethodObjArgs callMethod, PyDictGetItem getItem, PyObjectSetItem setItem, PyObjectIsTrueNode isTrueNode) { Object versionObj = getItem.executeCached(frame, registry, T_VERSION); long stateFiltersVersion = getStateFiltersVersion(_warnings); - if (versionObj == null || !eqNode.compareCached(frame, stateFiltersVersion, versionObj)) { + if (versionObj == null || !eqNode.executeEq(frame, stateFiltersVersion, versionObj)) { callMethod.executeCached(frame, registry, T_CLEAR); setItem.executeCached(frame, registry, T_VERSION, stateFiltersVersion); } else { @@ -675,12 +654,12 @@ private TruffleString normalizeModule(TruffleString filename) { } @TruffleBoundary - private static boolean updateRegistry(PythonObjectSlowPathFactory factory, PythonModule _warnings, PDict registry, Object text, Object category, boolean addZero) { + private static boolean updateRegistry(PythonLanguage language, PythonModule _warnings, PDict registry, Object text, Object category, boolean addZero) { PTuple altKey; if (addZero) { - altKey = factory.createTuple(new Object[]{text, category, 0}); + altKey = PFactory.createTuple(language, new Object[]{text, category, 0}); } else { - altKey = factory.createTuple(new Object[]{text, category}); + altKey = PFactory.createTuple(language, new Object[]{text, category}); } return alreadyWarnedShouldSet(_warnings, registry, altKey); } @@ -724,10 +703,8 @@ private static void showWarning(Object filename, int lineno, Object text, Object } @TruffleBoundary - private static void callShowWarning(PythonContext context, Object category, Object text, Object message, + private void callShowWarning(PythonContext context, Object category, Object text, Object message, TruffleString filename, int lineno, TruffleString sourceline, Object sourceIn) { - PRaiseNode raise = PRaiseNode.getUncached(); - Object showFn = getWarningsAttr(context, T__SHOWWARNMSG, sourceIn != null); if (showFn == null) { showWarning(filename, lineno, text, category, sourceline); @@ -735,12 +712,12 @@ private static void callShowWarning(PythonContext context, Object category, Obje } if (!PyCallableCheckNode.executeUncached(showFn)) { - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.WARN_MUST_BE_SET_CALLABLE); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.WARN_MUST_BE_SET_CALLABLE); } Object warnmsgCls = getWarningsAttr(context, T_WARNING_MESSAGE, false); if (warnmsgCls == null) { - throw raise.raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.UNABLE_GET_WARN_MSG); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.RuntimeError, ErrorMessages.UNABLE_GET_WARN_MSG); } Object source = sourceIn == null ? PNone.NONE : sourceIn; @@ -776,7 +753,7 @@ private void warnExplicit(VirtualFrame frame, PythonModule warnings, } else if (registryObj instanceof PDict) { registry = (PDict) registryObj; } else { - throw getRaise().raise(PythonBuiltinClassType.TypeError, ErrorMessages.REGISTRY_MUST_BE_DICT); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.REGISTRY_MUST_BE_DICT); } if (module == null) { @@ -794,7 +771,7 @@ private void warnExplicit(VirtualFrame frame, PythonModule warnings, message = getCallNode().execute(frame, category, message); } - Object key = getFactory().createTuple(new Object[]{text, category, lineno}); + Object key = PFactory.createTuple(PythonLanguage.get(this), new Object[]{text, category, lineno}); if (registry != null) { if (alreadyWarnedShouldNotSet(frame, warnings, registry, key)) { return; @@ -817,22 +794,21 @@ private void warnExplicit(VirtualFrame frame, PythonModule warnings, PythonLanguage language = context.getLanguage(this); Object state = IndirectCallContext.enter(frame, language, context, indirectCallData); try { - warnExplicitPart2(context, this, warnings, filename, lineno, registry, globals, source, category, message, text, key, item[0], action); + warnExplicitPart2(context, warnings, filename, lineno, registry, globals, source, category, message, text, key, item[0], action); } finally { IndirectCallContext.exit(frame, language, context, state); } } @TruffleBoundary - private static void warnExplicitPart2(PythonContext context, Node node, PythonModule warnings, TruffleString filename, int lineno, PDict registry, PDict globals, Object source, + private void warnExplicitPart2(PythonContext context, PythonModule warnings, TruffleString filename, int lineno, PDict registry, PDict globals, Object source, Object category, Object message, Object text, Object key, Object item, TruffleString action) { if (action.equalsUncached(T_ERROR, TS_ENCODING)) { if (!PyExceptionInstanceCheckNode.executeUncached(message)) { - throw PRaiseNode.raiseUncached(node, PythonBuiltinClassType.SystemError, ErrorMessages.EXCEPTION_NOT_BASEEXCEPTION, - PyObjectReprAsTruffleStringNode.executeUncached(message)); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.SystemError, ErrorMessages.EXCEPTION_NOT_BASEEXCEPTION, PyObjectReprAsTruffleStringNode.executeUncached(message)); } else { - throw PRaiseNode.raiseExceptionObject(node, message); + throw PRaiseNode.raiseExceptionObject(this, message); } } @@ -844,17 +820,17 @@ private static void warnExplicitPart2(PythonContext context, Node node, PythonMo boolean alreadyWarned = false; if (action.equalsUncached(T_ONCE, TS_ENCODING)) { if (registry == null) { - PDict currentRegistry = getOnceRegistry(node, context, warnings); - alreadyWarned = updateRegistry(context.factory(), warnings, currentRegistry, text, category, false); + PDict currentRegistry = getOnceRegistry(this, context, warnings); + alreadyWarned = updateRegistry(context.getLanguage(), warnings, currentRegistry, text, category, false); } else { - alreadyWarned = updateRegistry(context.factory(), warnings, registry, text, category, false); + alreadyWarned = updateRegistry(context.getLanguage(), warnings, registry, text, category, false); } } else if (action.equalsUncached(T_MODULE, TS_ENCODING)) { if (registry != null) { - alreadyWarned = updateRegistry(context.factory(), warnings, registry, text, category, false); + alreadyWarned = updateRegistry(context.getLanguage(), warnings, registry, text, category, false); } } else if (!action.equalsUncached(T_DEFAULT, TS_ENCODING)) { - throw PRaiseNode.raiseUncached(node, PythonBuiltinClassType.RuntimeError, ErrorMessages.UNRECOGNIZED_ACTION_IN_WARNINGS, action, + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.RuntimeError, ErrorMessages.UNRECOGNIZED_ACTION_IN_WARNINGS, action, PyObjectReprAsTruffleStringNode.executeUncached(item)); } @@ -867,7 +843,7 @@ private static void warnExplicitPart2(PythonContext context, Node node, PythonMo // to delay it TruffleString sourceline = null; if (globals != null) { - sourceline = getSourceLine(node, globals, lineno); + sourceline = getSourceLine(this, globals, lineno); } callShowWarning(context, category, text, message, filename, lineno, sourceline, source); @@ -898,7 +874,7 @@ private void setupContext(VirtualFrame frame, int stackLevel, TruffleString[] fi registry[0] = getDictGetItemNode().executeCached(frame, globals, T___WARNINGREGISTRY__); if (registry[0] == null) { - registry[0] = getFactory().createDict(); + registry[0] = PFactory.createDict(PythonLanguage.get(this)); getSetItemNode().executeCached(frame, globals, T___WARNINGREGISTRY__, registry[0]); } Object moduleObj = getDictGetItemNode().executeCached(frame, globals, SpecialAttributeNames.T___NAME__); @@ -923,7 +899,7 @@ private Object getCategory(VirtualFrame frame, Object message, Object category) } else if (category == null || category == PNone.NONE) { return PythonBuiltinClassType.UserWarning; } else if (!getIsTypeNode().executeCached(category) || !getIsSubClass().executeBoolean(frame, category, PythonBuiltinClassType.Warning)) { - throw getRaise().raise(PythonBuiltinClassType.TypeError, ErrorMessages.CATEGORY_MUST_BE_WARN_SUBCLS, category); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.CATEGORY_MUST_BE_WARN_SUBCLS, category); } else { return category; } @@ -969,13 +945,13 @@ private static TruffleString getSourceLine(Node node, PDict globals, int lineno) try { src = CastToJavaStringNode.getUncached().execute(source); } catch (CannotCastException e) { - throw PRaiseNode.raiseUncached(node, PythonBuiltinClassType.TypeError, ErrorMessages.EXPECTED_S_NOT_P, "str", source); + throw PRaiseNode.raiseStatic(node, PythonBuiltinClassType.TypeError, ErrorMessages.EXPECTED_S_NOT_P, "str", source); } String[] lines = src.split("\n"); if (lines.length >= lineno) { return toTruffleStringUncached(lines[lineno - 1]); } else { - throw PRaiseNode.raiseUncached(node, PythonBuiltinClassType.IndexError, ErrorMessages.INDEX_OUT_OF_BOUNDS); + throw PRaiseNode.raiseStatic(node, PythonBuiltinClassType.IndexError, ErrorMessages.INDEX_OUT_OF_BOUNDS); } } } @@ -1021,12 +997,12 @@ static Object doWarn(VirtualFrame frame, PythonModule mod, Object message, Objec @Cached("createFor(this)") IndirectCallData indirectCallData, @Cached CastToTruffleStringNode castStr, @Cached WarningsModuleNode moduleFunctionsNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleString filename; try { filename = castStr.execute(inliningTarget, flname); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "warn_explicit()", 3, "str", flname); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "warn_explicit()", 3, "str", flname); } PDict globalsDict; if (globals instanceof PNone) { @@ -1034,7 +1010,7 @@ static Object doWarn(VirtualFrame frame, PythonModule mod, Object message, Objec } else if (globals instanceof PDict) { globalsDict = (PDict) globals; } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.MOD_GLOBALS_MUST_BE_DICT, globals); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.MOD_GLOBALS_MUST_BE_DICT, globals); } // CPython calls get_source_line here. But since that's potentially slow, maybe we can // get away with doing that lazily diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WeakRefModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WeakRefModuleBuiltins.java index 3c5412ca21..0206b92821 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WeakRefModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WeakRefModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,13 +41,10 @@ package com.oracle.graal.python.builtins.modules; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.removeNativeWeakRef; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_weaklistoffset; import static com.oracle.graal.python.nodes.BuiltinNames.J__WEAKREF; import static com.oracle.graal.python.nodes.BuiltinNames.T__WEAKREF; -import static com.oracle.graal.python.nodes.HiddenAttr.WEAKLIST; import static com.oracle.graal.python.nodes.HiddenAttr.WEAK_REF_QUEUE; import static com.oracle.graal.python.nodes.StringLiterals.T_REF; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import java.lang.ref.Reference; @@ -61,45 +58,25 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.PythonAbstractObject; -import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; -import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass; -import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions; -import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.referencetype.PReferenceType; import com.oracle.graal.python.builtins.objects.referencetype.PReferenceType.WeakRefStorage; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; -import com.oracle.graal.python.builtins.objects.type.PythonClass; import com.oracle.graal.python.builtins.objects.type.TypeFlags; import com.oracle.graal.python.builtins.objects.type.TypeNodes; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroNode; -import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.HiddenAttr; -import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.WriteUnraisableNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassExactProfile; -import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.AsyncHandler; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateNodeFactory; -import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @CoreFunctions(defineModule = J__WEAKREF, isEager = true) @@ -245,132 +222,6 @@ public void postInitialize(Python3Core core) { }); } - // ReferenceType constructor - @Builtin(name = "ReferenceType", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PReferenceType) - @GenerateNodeFactory - public abstract static class ReferenceTypeNode extends PythonBuiltinNode { - @Child private CStructAccess.ReadI64Node getTpWeaklistoffsetNode; - - public abstract PReferenceType execute(Object cls, Object object, Object callback); - - @Specialization(guards = "!isNativeObject(object)") - static PReferenceType refType(Object cls, Object object, @SuppressWarnings("unused") PNone none, - @Bind("this") Node inliningTarget, - @Exclusive @Cached GetClassNode getClassNode, - @Cached HiddenAttr.ReadNode readWeaklistNode, - @Cached HiddenAttr.WriteNode writeWeakListNode, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached HiddenAttr.ReadNode readQueueNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - Object obj = object; - if (object instanceof PythonBuiltinClassType tobj) { - obj = PythonContext.get(inliningTarget).getCore().lookupType(tobj); - } - - Object clazz = getClassNode.execute(inliningTarget, obj); - boolean allowed = true; - if (clazz instanceof PythonBuiltinClassType type) { - allowed = type.getWeaklistoffset() != 0; - } - if (!allowed) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANNOT_CREATE_WEAK_REFERENCE_TO, obj); - } - assert obj instanceof PythonAbstractObject; - Object wr = readWeaklistNode.execute(inliningTarget, (PythonAbstractObject) obj, WEAKLIST, null); - if (wr != null) { - return (PReferenceType) wr; // is must be a PReferenceType instance. - } - - PReferenceType ref = factory.createReferenceType(cls, obj, null, getWeakReferenceQueue(inliningTarget, readQueueNode)); - writeWeakListNode.execute(inliningTarget, (PythonAbstractObject) obj, WEAKLIST, ref); - return ref; - } - - @Specialization(guards = {"!isNativeObject(object)", "!isPNone(callback)"}) - static PReferenceType refTypeWithCallback(Object cls, Object object, Object callback, - @Bind("this") Node inliningTarget, - @Exclusive @Cached HiddenAttr.ReadNode readQueueNode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createReferenceType(cls, object, callback, getWeakReferenceQueue(inliningTarget, readQueueNode)); - } - - @Specialization - @SuppressWarnings("truffle-static-method") - PReferenceType refType(Object cls, PythonAbstractNativeObject pythonObject, Object callback, - @Bind("this") Node inliningTarget, - @Exclusive @Cached GetClassNode getClassNode, - @Cached IsBuiltinClassExactProfile profile, - @Cached GetMroNode getMroNode, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached HiddenAttr.ReadNode readQueueNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - Object actualCallback = callback instanceof PNone ? null : callback; - Object clazz = getClassNode.execute(inliningTarget, pythonObject); - - // if the object is a type, a weak ref is allowed - boolean allowed = false; - if (profile.profileClass(inliningTarget, clazz, PythonBuiltinClassType.PythonClass)) { - allowed = true; - } else { - // if the object's type is a native type, we need to consider 'tp_weaklistoffset' - if (PGuards.isNativeClass(clazz) || clazz instanceof PythonClass && ((PythonClass) clazz).needsNativeAllocation()) { - for (Object base : getMroNode.execute(inliningTarget, clazz)) { - if (PGuards.isNativeClass(base)) { - if (getTpWeaklistoffsetNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - getTpWeaklistoffsetNode = insert(CStructAccess.ReadI64Node.create()); - } - long tpWeaklistoffset = getTpWeaklistoffsetNode.readFromObj((PythonNativeClass) base, PyTypeObject__tp_weaklistoffset); - if (tpWeaklistoffset != 0) { - allowed = true; - break; - } - } else if (base instanceof PythonClass /* not PythonBuiltinClass */) { - // any subclass of a normal (non-builtin) class supports weakrefs - allowed = true; - break; - } - } - } - } - if (allowed) { - CApiTransitions.addNativeWeakRef(getContext(), pythonObject); - return factory.createReferenceType(cls, pythonObject, actualCallback, getWeakReferenceQueue(inliningTarget, readQueueNode)); - } else { - return refType(cls, pythonObject, actualCallback, raiseNode.get(inliningTarget)); - } - } - - @Fallback - static PReferenceType refType(@SuppressWarnings("unused") Object cls, Object object, @SuppressWarnings("unused") Object callback, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CREATE_WEAK_REFERENCE_TO, object); - } - - @SuppressWarnings("unchecked") - private static ReferenceQueue getWeakReferenceQueue(Node inliningTarget, HiddenAttr.ReadNode readNode) { - PythonContext context = PythonContext.get(inliningTarget); - Object queueObject = readNode.execute(inliningTarget, context.lookupType(PythonBuiltinClassType.PReferenceType), WEAK_REF_QUEUE, null); - if (queueObject != null) { - return (ReferenceQueue) queueObject; - } else { - if (context.isCoreInitialized()) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw new IllegalStateException("the weak reference queue was modified!"); - } else { - // returning a null reference queue is fine, it just means - // that the finalizer won't run - return null; - } - } - } - - @NeverDefault - public static ReferenceTypeNode create() { - return WeakRefModuleBuiltinsFactory.ReferenceTypeNodeFactory.create(null); - } - } - // getweakrefcount(obj) @Builtin(name = "getweakrefcount", minNumOfPositionalArgs = 1) @GenerateNodeFactory diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WinregModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WinregModuleBuiltins.java index e72c7c79d2..49ab1f7d64 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WinregModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WinregModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,6 +42,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -55,7 +56,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -103,10 +104,10 @@ protected ArgumentClinicProvider getArgumentClinic() { static Object openKey(VirtualFrame frame, Object key, Object subKey, Object reserved, Object access, @Bind("this") Node inliningTarget, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { if (key instanceof Integer intKey) { if (intKey == HKEY_CLASSES_ROOT) { - return factory.createLock(); + return PFactory.createLock(language); } } throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, OSErrorEnum.ENOENT); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstBuiltins.java index 446ae216fa..a036d11eed 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,7 +46,6 @@ import static com.oracle.graal.python.nodes.ErrorMessages.S_CONSTRUCTOR_TAKES_AT_MOST_D_POSITIONAL_ARGUMENT_S; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___DICT__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DICT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.util.PythonUtils.EMPTY_OBJECT_ARRAY; @@ -54,6 +53,10 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -63,6 +66,8 @@ import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.object.PythonObject; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectSetAttrO; import com.oracle.graal.python.nodes.ErrorMessages; @@ -74,7 +79,7 @@ import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; import com.oracle.graal.python.nodes.object.SetDictNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -88,12 +93,29 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.AST) public final class AstBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = AstBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return AstBuiltinsFactory.getFactories(); } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "AST", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class AstNode extends PythonVarargsBuiltinNode { + + @Specialization + static PythonObject generic(Object cls, @SuppressWarnings("unused") Object[] varargs, @SuppressWarnings("unused") PKeyword[] kwargs, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + return PFactory.createPythonObject(language, cls, getInstanceShape.execute(cls)); + } + } + + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory abstract static class InitNode extends PythonVarargsBuiltinNode { @@ -107,26 +129,27 @@ protected Object doIt(VirtualFrame frame, Object self, Object[] args, PKeyword[] @Cached PyObjectLookupAttr lookupAttrNode, @Cached SequenceNodes.GetObjectArrayNode getObjectArrayNode, @Cached PyObjectSetAttrO setAttrNode, - @Cached TruffleString.EqualNode equalNode) { + @Cached TruffleString.EqualNode equalNode, + @Cached PRaiseNode raiseNode) { Object fieldsObj = lookupAttrNode.execute(frame, inliningTarget, self, T__FIELDS); Object[] fields; if (fieldsObj == PNone.NO_VALUE) { fields = EMPTY_OBJECT_ARRAY; } else { if (!(fieldsObj instanceof PSequence)) { - throw raise(TypeError, IS_NOT_A_SEQUENCE, fieldsObj); + throw raiseNode.raise(inliningTarget, TypeError, IS_NOT_A_SEQUENCE, fieldsObj); } fields = getObjectArrayNode.execute(inliningTarget, fieldsObj); } if (fields.length < args.length) { - throw raise(TypeError, S_CONSTRUCTOR_TAKES_AT_MOST_D_POSITIONAL_ARGUMENT_S, self, fields.length, fields.length == 1 ? "" : "s"); + throw raiseNode.raise(inliningTarget, TypeError, S_CONSTRUCTOR_TAKES_AT_MOST_D_POSITIONAL_ARGUMENT_S, self, fields.length, fields.length == 1 ? "" : "s"); } for (int i = 0; i < args.length; ++i) { setAttrNode.execute(frame, inliningTarget, self, fields[i], args[i]); } for (PKeyword kwArg : kwArgs) { if (contains(fields, args.length, kwArg.getName(), equalNode)) { - throw raise(TypeError, P_GOT_MULTIPLE_VALUES_FOR_ARGUMENT_S, self, kwArg.getName()); + throw raiseNode.raise(inliningTarget, TypeError, P_GOT_MULTIPLE_VALUES_FOR_ARGUMENT_S, self, kwArg.getName()); } setAttrNode.execute(frame, inliningTarget, self, kwArg.getName(), kwArg.getValue()); } @@ -166,8 +189,8 @@ static Object dict(PythonObject self, PDict dict, @Specialization(guards = {"!isNoValue(d)", "!isDict(d)"}) @SuppressWarnings("unused") static Object setDict(PythonObject self, Object d, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, d); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, d); } } @@ -180,10 +203,10 @@ static Object doit(VirtualFrame frame, PythonObject self, Object ignored, @Bind("this") Node inliningTarget, @Cached GetClassNode getClassNode, @Cached PyObjectLookupAttr lookupAttr, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { Object clazz = getClassNode.execute(inliningTarget, self); Object dict = lookupAttr.execute(frame, inliningTarget, self, T___DICT__); - return factory.createTuple(new Object[]{clazz, factory.createTuple(EMPTY_OBJECT_ARRAY), dict}); + return PFactory.createTuple(language, new Object[]{clazz, PFactory.createTuple(language, EMPTY_OBJECT_ARRAY), dict}); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstModuleBuiltins.java index ac5040e41c..9c5f7a65b6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,35 +45,29 @@ import static com.oracle.graal.python.builtins.modules.BuiltinFunctions.CompileNode.PyCF_TYPE_COMMENTS; import static com.oracle.graal.python.nodes.ErrorMessages.EXPECTED_S_NODE_GOT_P; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___MATCH_ARGS__; -import static com.oracle.graal.python.util.PythonUtils.EMPTY_OBJECT_ARRAY; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import static com.oracle.truffle.api.CompilerDirectives.shouldNotReachHere; +import java.util.Collections; import java.util.List; -import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; import com.oracle.graal.python.builtins.objects.type.PythonClass; +import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.pegparser.InputType; import com.oracle.graal.python.pegparser.sst.ModTy; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @CoreFunctions(defineModule = AstModuleBuiltins.J__AST, isEager = true) @@ -87,7 +81,7 @@ public final class AstModuleBuiltins extends PythonBuiltins { @Override protected List> getNodeFactories() { - return AstModuleBuiltinsFactory.getFactories(); + return Collections.emptyList(); } @Override @@ -98,7 +92,7 @@ public void initialize(Python3Core core) { addBuiltinConstant("PyCF_ALLOW_TOP_LEVEL_AWAIT", PyCF_ALLOW_TOP_LEVEL_AWAIT); PythonBuiltinClass clsAst = core.lookupType(PythonBuiltinClassType.AST); - PTuple emptyTuple = core.factory().createTuple(EMPTY_OBJECT_ARRAY); + PTuple emptyTuple = PFactory.createEmptyTuple(core.getLanguage()); clsAst.setAttribute(T__FIELDS, emptyTuple); clsAst.setAttribute(T__ATTRIBUTES, emptyTuple); clsAst.setAttribute(T___MATCH_ARGS__, emptyTuple); @@ -108,29 +102,11 @@ public void initialize(Python3Core core) { public void postInitialize(Python3Core core) { super.postInitialize(core); PythonModule astModule = core.lookupBuiltinModule(T__AST); - AstTypeFactory astTypeFactory = new AstTypeFactory(core.getLanguage(), core.factory(), astModule); + AstTypeFactory astTypeFactory = new AstTypeFactory(core.getLanguage(), astModule); AstState state = new AstState(astTypeFactory, core.lookupType(PythonBuiltinClassType.AST)); astModule.setModuleState(state); } - @Builtin(name = "AST", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.AST) - @GenerateNodeFactory - public abstract static class AstNode extends PythonVarargsBuiltinNode { - @Override - public final Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported { - if (self == PNone.NO_VALUE && arguments.length > 0) { - return factory().createPythonObject(arguments[0]); - } - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw VarargsBuiltinDirectInvocationNotSupported.INSTANCE; - } - - @Specialization - PythonObject generic(Object cls, @SuppressWarnings("unused") Object[] varargs, @SuppressWarnings("unused") PKeyword[] kwargs) { - return factory().createPythonObject(cls); - } - } - private static AstState getAstState(PythonContext context) { return context.lookupBuiltinModule(T__AST).getModuleState(AstState.class); } @@ -141,7 +117,7 @@ public static Object sst2Obj(PythonContext context, ModTy mod) { } @TruffleBoundary - public static ModTy obj2sst(PythonContext context, Object obj, InputType type) { + public static ModTy obj2sst(Node node, PythonContext context, Object obj, InputType type) { AstState state = getAstState(context); PythonClass expectedClass; switch (type) { @@ -158,11 +134,12 @@ public static ModTy obj2sst(PythonContext context, Object obj, InputType type) { throw shouldNotReachHere(); } if (!Obj2SstBase.isInstanceOf(obj, expectedClass)) { - throw Obj2SstBase.raiseTypeError(EXPECTED_S_NODE_GOT_P, expectedClass.getName(), obj); + Object[] arguments = new Object[]{expectedClass.getName(), obj}; + throw PRaiseNode.raiseStatic(node, PythonBuiltinClassType.TypeError, EXPECTED_S_NODE_GOT_P, arguments); } - ModTy mod = new Obj2Sst(state).obj2ModTy(obj); - Validator.validateMod(mod); + ModTy mod = new Obj2Sst(node, state).obj2ModTy(obj); + Validator.validateMod(node, mod); return mod; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstState.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstState.java index b416484a6c..29ba5b10cb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstState.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstTypeFactory.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstTypeFactory.java index 89ed1bee7d..00bbb68146 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstTypeFactory.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/AstTypeFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -49,13 +49,12 @@ import static com.oracle.graal.python.util.PythonUtils.convertToObjectArray; import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; import com.oracle.graal.python.builtins.objects.type.PythonClass; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.strings.TruffleString; /** @@ -64,23 +63,21 @@ final class AstTypeFactory { private final PythonLanguage language; - private final PythonObjectFactory factory; private final PythonModule astModule; - AstTypeFactory(PythonLanguage language, PythonObjectFactory factory, PythonModule astModule) { + AstTypeFactory(PythonLanguage language, PythonModule astModule) { this.language = language; - this.factory = factory; this.astModule = astModule; } PythonClass makeType(TruffleString name, PythonAbstractClass base, TruffleString[] fields, TruffleString[] attributes, TruffleString[] optional, TruffleString docString) { - PythonClass newType = factory.createPythonClassAndFixupSlots(language, PythonBuiltinClassType.PythonClass, name, base, new PythonAbstractClass[]{base}); + PythonClass newType = PFactory.createPythonClassAndFixupSlots(language, name, base, new PythonAbstractClass[]{base}); newType.setAttribute(T___MODULE__, T_AST); newType.setAttribute(T___DOC__, docString); - newType.setAttribute(T__FIELDS, factory.createTuple(convertToObjectArray(fields))); - newType.setAttribute(T___MATCH_ARGS__, factory.createTuple(convertToObjectArray(fields))); + newType.setAttribute(T__FIELDS, PFactory.createTuple(language, convertToObjectArray(fields))); + newType.setAttribute(T___MATCH_ARGS__, PFactory.createTuple(language, convertToObjectArray(fields))); if (attributes != null) { - newType.setAttribute(T__ATTRIBUTES, factory.createTuple(convertToObjectArray(attributes))); + newType.setAttribute(T__ATTRIBUTES, PFactory.createTuple(language, convertToObjectArray(attributes))); } for (TruffleString n : optional) { newType.setAttribute(n, PNone.NONE); @@ -90,6 +87,6 @@ PythonClass makeType(TruffleString name, PythonAbstractClass base, TruffleString } PythonObject createSingleton(PythonClass cls) { - return factory.createPythonObject(cls); + return PFactory.createPythonObject(language, cls, cls.getInstanceShape()); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Obj2Sst.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Obj2Sst.java index 0592423a9d..1166363cdf 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Obj2Sst.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Obj2Sst.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,6 +45,7 @@ // Generated from Python.asdl by main_asdl_gen.py package com.oracle.graal.python.builtins.modules.ast; +import com.oracle.truffle.api.nodes.Node; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.pegparser.sst.ConstantValue; import com.oracle.graal.python.pegparser.sst.ModTy; @@ -69,8 +70,8 @@ final class Obj2Sst extends Obj2SstBase { - Obj2Sst(AstState state) { - super(state); + Obj2Sst(Node node, AstState state) { + super(node, state); } ModTy obj2ModTy(Object obj) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Obj2SstBase.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Obj2SstBase.java index 9f41864f94..5396eebd76 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Obj2SstBase.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Obj2SstBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -68,11 +68,12 @@ import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyBytesCheckExactNode; import com.oracle.graal.python.lib.PyComplexCheckExactNode; import com.oracle.graal.python.lib.PyFloatCheckExactNode; import com.oracle.graal.python.lib.PyFrozenSetCheckExactNode; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyLongAsIntNode; import com.oracle.graal.python.lib.PyLongCheckNode; import com.oracle.graal.python.lib.PyObjectGetIter; @@ -84,20 +85,22 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.SpecialMethodNames; import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaBooleanNode; import com.oracle.graal.python.nodes.util.CastToJavaStringNode; import com.oracle.graal.python.pegparser.sst.ConstantValue; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; abstract class Obj2SstBase { final AstState state; + private final Node node; - protected Obj2SstBase(AstState state) { + protected Obj2SstBase(Node node, AstState state) { + this.node = node; this.state = state; } @@ -287,13 +290,12 @@ ConstantValue obj2ConstantValue(Object obj) { boolean isTuple = PyTupleCheckExactNode.executeUncached(obj); if (isTuple || PyFrozenSetCheckExactNode.executeUncached(obj)) { Object iter = PyObjectGetIter.executeUncached(obj); - GetNextNode nextNode = GetNextNode.getUncached(); ArrayList list = new ArrayList<>(); while (true) { try { - list.add(obj2ConstantValue(nextNode.execute(iter))); - } catch (PException e) { - e.expectStopIteration(null, IsBuiltinObjectProfile.getUncached()); + Object item = PyIterNextNode.executeUncached(iter); + list.add(obj2ConstantValue(item)); + } catch (IteratorExhausted e) { break; } } @@ -305,7 +307,7 @@ ConstantValue obj2ConstantValue(Object obj) { throw raiseTypeError(ErrorMessages.GOT_AN_INVALID_TYPE_IN_CONSTANT, obj); } - static PException unexpectedNodeType(TruffleString expected, Object obj) { + protected PException unexpectedNodeType(TruffleString expected, Object obj) { throw raiseTypeError(EXPECTED_SOME_SORT_OF_S_BUT_GOT_S, expected, repr(obj)); } @@ -317,15 +319,15 @@ private static TruffleString repr(Object o) { return PyObjectReprAsTruffleStringNode.executeUncached(o); } - private static PException raise(PythonBuiltinClassType type, TruffleString format, Object... arguments) { - throw PRaiseNode.getUncached().raise(type, format, arguments); + private PException raise(PythonBuiltinClassType type, TruffleString format, Object... arguments) { + throw PRaiseNode.raiseStatic(node, type, format, arguments); } - static PException raiseTypeError(TruffleString format, Object... arguments) { + protected PException raiseTypeError(TruffleString format, Object... arguments) { throw raise(PythonBuiltinClassType.TypeError, format, arguments); } - private static PException raiseValueError(TruffleString format, Object... arguments) { + protected PException raiseValueError(TruffleString format, Object... arguments) { throw raise(PythonBuiltinClassType.ValueError, format, arguments); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Sst2ObjVisitor.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Sst2ObjVisitor.java index d21cebcb1c..e698ae2164 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Sst2ObjVisitor.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Sst2ObjVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -77,7 +77,7 @@ final class Sst2ObjVisitor extends Sst2ObjVisitorBase { @Override public Object visit(ModTy.Module node) { - PythonObject o = factory.createPythonObject(state.clsModule); + PythonObject o = createPythonObject(state.clsModule); o.setAttribute(AstState.T_F_BODY, seq2List(node.body)); o.setAttribute(AstState.T_F_TYPE_IGNORES, seq2List(node.typeIgnores)); return o; @@ -85,21 +85,21 @@ public Object visit(ModTy.Module node) { @Override public Object visit(ModTy.Interactive node) { - PythonObject o = factory.createPythonObject(state.clsInteractive); + PythonObject o = createPythonObject(state.clsInteractive); o.setAttribute(AstState.T_F_BODY, seq2List(node.body)); return o; } @Override public Object visit(ModTy.Expression node) { - PythonObject o = factory.createPythonObject(state.clsExpression); + PythonObject o = createPythonObject(state.clsExpression); o.setAttribute(AstState.T_F_BODY, visitNonNull(node.body)); return o; } @Override public Object visit(ModTy.FunctionType node) { - PythonObject o = factory.createPythonObject(state.clsFunctionType); + PythonObject o = createPythonObject(state.clsFunctionType); o.setAttribute(AstState.T_F_ARGTYPES, seq2List(node.argTypes)); o.setAttribute(AstState.T_F_RETURNS, visitNonNull(node.returns)); return o; @@ -107,7 +107,7 @@ public Object visit(ModTy.FunctionType node) { @Override public Object visit(StmtTy.FunctionDef node) { - PythonObject o = factory.createPythonObject(state.clsFunctionDef); + PythonObject o = createPythonObject(state.clsFunctionDef); o.setAttribute(AstState.T_F_NAME, visitNonNull(node.name)); o.setAttribute(AstState.T_F_ARGS, visitNonNull(node.args)); o.setAttribute(AstState.T_F_BODY, seq2List(node.body)); @@ -120,7 +120,7 @@ public Object visit(StmtTy.FunctionDef node) { @Override public Object visit(StmtTy.AsyncFunctionDef node) { - PythonObject o = factory.createPythonObject(state.clsAsyncFunctionDef); + PythonObject o = createPythonObject(state.clsAsyncFunctionDef); o.setAttribute(AstState.T_F_NAME, visitNonNull(node.name)); o.setAttribute(AstState.T_F_ARGS, visitNonNull(node.args)); o.setAttribute(AstState.T_F_BODY, seq2List(node.body)); @@ -133,7 +133,7 @@ public Object visit(StmtTy.AsyncFunctionDef node) { @Override public Object visit(StmtTy.ClassDef node) { - PythonObject o = factory.createPythonObject(state.clsClassDef); + PythonObject o = createPythonObject(state.clsClassDef); o.setAttribute(AstState.T_F_NAME, visitNonNull(node.name)); o.setAttribute(AstState.T_F_BASES, seq2List(node.bases)); o.setAttribute(AstState.T_F_KEYWORDS, seq2List(node.keywords)); @@ -145,7 +145,7 @@ public Object visit(StmtTy.ClassDef node) { @Override public Object visit(StmtTy.Return node) { - PythonObject o = factory.createPythonObject(state.clsReturn); + PythonObject o = createPythonObject(state.clsReturn); o.setAttribute(AstState.T_F_VALUE, visitNullable(node.value)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -153,7 +153,7 @@ public Object visit(StmtTy.Return node) { @Override public Object visit(StmtTy.Delete node) { - PythonObject o = factory.createPythonObject(state.clsDelete); + PythonObject o = createPythonObject(state.clsDelete); o.setAttribute(AstState.T_F_TARGETS, seq2List(node.targets)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -161,7 +161,7 @@ public Object visit(StmtTy.Delete node) { @Override public Object visit(StmtTy.Assign node) { - PythonObject o = factory.createPythonObject(state.clsAssign); + PythonObject o = createPythonObject(state.clsAssign); o.setAttribute(AstState.T_F_TARGETS, seq2List(node.targets)); o.setAttribute(AstState.T_F_VALUE, visitNonNull(node.value)); o.setAttribute(AstState.T_F_TYPE_COMMENT, visitNullableStringOrByteArray(node.typeComment)); @@ -171,7 +171,7 @@ public Object visit(StmtTy.Assign node) { @Override public Object visit(StmtTy.AugAssign node) { - PythonObject o = factory.createPythonObject(state.clsAugAssign); + PythonObject o = createPythonObject(state.clsAugAssign); o.setAttribute(AstState.T_F_TARGET, visitNonNull(node.target)); o.setAttribute(AstState.T_F_OP, visitNonNull(node.op)); o.setAttribute(AstState.T_F_VALUE, visitNonNull(node.value)); @@ -181,7 +181,7 @@ public Object visit(StmtTy.AugAssign node) { @Override public Object visit(StmtTy.AnnAssign node) { - PythonObject o = factory.createPythonObject(state.clsAnnAssign); + PythonObject o = createPythonObject(state.clsAnnAssign); o.setAttribute(AstState.T_F_TARGET, visitNonNull(node.target)); o.setAttribute(AstState.T_F_ANNOTATION, visitNonNull(node.annotation)); o.setAttribute(AstState.T_F_VALUE, visitNullable(node.value)); @@ -192,7 +192,7 @@ public Object visit(StmtTy.AnnAssign node) { @Override public Object visit(StmtTy.For node) { - PythonObject o = factory.createPythonObject(state.clsFor); + PythonObject o = createPythonObject(state.clsFor); o.setAttribute(AstState.T_F_TARGET, visitNonNull(node.target)); o.setAttribute(AstState.T_F_ITER, visitNonNull(node.iter)); o.setAttribute(AstState.T_F_BODY, seq2List(node.body)); @@ -204,7 +204,7 @@ public Object visit(StmtTy.For node) { @Override public Object visit(StmtTy.AsyncFor node) { - PythonObject o = factory.createPythonObject(state.clsAsyncFor); + PythonObject o = createPythonObject(state.clsAsyncFor); o.setAttribute(AstState.T_F_TARGET, visitNonNull(node.target)); o.setAttribute(AstState.T_F_ITER, visitNonNull(node.iter)); o.setAttribute(AstState.T_F_BODY, seq2List(node.body)); @@ -216,7 +216,7 @@ public Object visit(StmtTy.AsyncFor node) { @Override public Object visit(StmtTy.While node) { - PythonObject o = factory.createPythonObject(state.clsWhile); + PythonObject o = createPythonObject(state.clsWhile); o.setAttribute(AstState.T_F_TEST, visitNonNull(node.test)); o.setAttribute(AstState.T_F_BODY, seq2List(node.body)); o.setAttribute(AstState.T_F_ORELSE, seq2List(node.orElse)); @@ -226,7 +226,7 @@ public Object visit(StmtTy.While node) { @Override public Object visit(StmtTy.If node) { - PythonObject o = factory.createPythonObject(state.clsIf); + PythonObject o = createPythonObject(state.clsIf); o.setAttribute(AstState.T_F_TEST, visitNonNull(node.test)); o.setAttribute(AstState.T_F_BODY, seq2List(node.body)); o.setAttribute(AstState.T_F_ORELSE, seq2List(node.orElse)); @@ -236,7 +236,7 @@ public Object visit(StmtTy.If node) { @Override public Object visit(StmtTy.With node) { - PythonObject o = factory.createPythonObject(state.clsWith); + PythonObject o = createPythonObject(state.clsWith); o.setAttribute(AstState.T_F_ITEMS, seq2List(node.items)); o.setAttribute(AstState.T_F_BODY, seq2List(node.body)); o.setAttribute(AstState.T_F_TYPE_COMMENT, visitNullableStringOrByteArray(node.typeComment)); @@ -246,7 +246,7 @@ public Object visit(StmtTy.With node) { @Override public Object visit(StmtTy.AsyncWith node) { - PythonObject o = factory.createPythonObject(state.clsAsyncWith); + PythonObject o = createPythonObject(state.clsAsyncWith); o.setAttribute(AstState.T_F_ITEMS, seq2List(node.items)); o.setAttribute(AstState.T_F_BODY, seq2List(node.body)); o.setAttribute(AstState.T_F_TYPE_COMMENT, visitNullableStringOrByteArray(node.typeComment)); @@ -256,7 +256,7 @@ public Object visit(StmtTy.AsyncWith node) { @Override public Object visit(StmtTy.Match node) { - PythonObject o = factory.createPythonObject(state.clsMatch); + PythonObject o = createPythonObject(state.clsMatch); o.setAttribute(AstState.T_F_SUBJECT, visitNonNull(node.subject)); o.setAttribute(AstState.T_F_CASES, seq2List(node.cases)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -265,7 +265,7 @@ public Object visit(StmtTy.Match node) { @Override public Object visit(StmtTy.Raise node) { - PythonObject o = factory.createPythonObject(state.clsRaise); + PythonObject o = createPythonObject(state.clsRaise); o.setAttribute(AstState.T_F_EXC, visitNullable(node.exc)); o.setAttribute(AstState.T_F_CAUSE, visitNullable(node.cause)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -274,7 +274,7 @@ public Object visit(StmtTy.Raise node) { @Override public Object visit(StmtTy.Try node) { - PythonObject o = factory.createPythonObject(state.clsTry); + PythonObject o = createPythonObject(state.clsTry); o.setAttribute(AstState.T_F_BODY, seq2List(node.body)); o.setAttribute(AstState.T_F_HANDLERS, seq2List(node.handlers)); o.setAttribute(AstState.T_F_ORELSE, seq2List(node.orElse)); @@ -285,7 +285,7 @@ public Object visit(StmtTy.Try node) { @Override public Object visit(StmtTy.TryStar node) { - PythonObject o = factory.createPythonObject(state.clsTryStar); + PythonObject o = createPythonObject(state.clsTryStar); o.setAttribute(AstState.T_F_BODY, seq2List(node.body)); o.setAttribute(AstState.T_F_HANDLERS, seq2List(node.handlers)); o.setAttribute(AstState.T_F_ORELSE, seq2List(node.orElse)); @@ -296,7 +296,7 @@ public Object visit(StmtTy.TryStar node) { @Override public Object visit(StmtTy.Assert node) { - PythonObject o = factory.createPythonObject(state.clsAssert); + PythonObject o = createPythonObject(state.clsAssert); o.setAttribute(AstState.T_F_TEST, visitNonNull(node.test)); o.setAttribute(AstState.T_F_MSG, visitNullable(node.msg)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -305,7 +305,7 @@ public Object visit(StmtTy.Assert node) { @Override public Object visit(StmtTy.Import node) { - PythonObject o = factory.createPythonObject(state.clsImport); + PythonObject o = createPythonObject(state.clsImport); o.setAttribute(AstState.T_F_NAMES, seq2List(node.names)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -313,7 +313,7 @@ public Object visit(StmtTy.Import node) { @Override public Object visit(StmtTy.ImportFrom node) { - PythonObject o = factory.createPythonObject(state.clsImportFrom); + PythonObject o = createPythonObject(state.clsImportFrom); o.setAttribute(AstState.T_F_MODULE, visitNullable(node.module)); o.setAttribute(AstState.T_F_NAMES, seq2List(node.names)); o.setAttribute(AstState.T_F_LEVEL, visitNullable(node.level)); @@ -323,7 +323,7 @@ public Object visit(StmtTy.ImportFrom node) { @Override public Object visit(StmtTy.Global node) { - PythonObject o = factory.createPythonObject(state.clsGlobal); + PythonObject o = createPythonObject(state.clsGlobal); o.setAttribute(AstState.T_F_NAMES, seq2List(node.names)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -331,7 +331,7 @@ public Object visit(StmtTy.Global node) { @Override public Object visit(StmtTy.Nonlocal node) { - PythonObject o = factory.createPythonObject(state.clsNonlocal); + PythonObject o = createPythonObject(state.clsNonlocal); o.setAttribute(AstState.T_F_NAMES, seq2List(node.names)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -339,7 +339,7 @@ public Object visit(StmtTy.Nonlocal node) { @Override public Object visit(StmtTy.Expr node) { - PythonObject o = factory.createPythonObject(state.clsExpr); + PythonObject o = createPythonObject(state.clsExpr); o.setAttribute(AstState.T_F_VALUE, visitNonNull(node.value)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -347,28 +347,28 @@ public Object visit(StmtTy.Expr node) { @Override public Object visit(StmtTy.Pass node) { - PythonObject o = factory.createPythonObject(state.clsPass); + PythonObject o = createPythonObject(state.clsPass); fillSourceRangeAttributes(o, node.getSourceRange()); return o; } @Override public Object visit(StmtTy.Break node) { - PythonObject o = factory.createPythonObject(state.clsBreak); + PythonObject o = createPythonObject(state.clsBreak); fillSourceRangeAttributes(o, node.getSourceRange()); return o; } @Override public Object visit(StmtTy.Continue node) { - PythonObject o = factory.createPythonObject(state.clsContinue); + PythonObject o = createPythonObject(state.clsContinue); fillSourceRangeAttributes(o, node.getSourceRange()); return o; } @Override public Object visit(ExprTy.BoolOp node) { - PythonObject o = factory.createPythonObject(state.clsBoolOp); + PythonObject o = createPythonObject(state.clsBoolOp); o.setAttribute(AstState.T_F_OP, visitNonNull(node.op)); o.setAttribute(AstState.T_F_VALUES, seq2List(node.values)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -377,7 +377,7 @@ public Object visit(ExprTy.BoolOp node) { @Override public Object visit(ExprTy.NamedExpr node) { - PythonObject o = factory.createPythonObject(state.clsNamedExpr); + PythonObject o = createPythonObject(state.clsNamedExpr); o.setAttribute(AstState.T_F_TARGET, visitNonNull(node.target)); o.setAttribute(AstState.T_F_VALUE, visitNonNull(node.value)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -386,7 +386,7 @@ public Object visit(ExprTy.NamedExpr node) { @Override public Object visit(ExprTy.BinOp node) { - PythonObject o = factory.createPythonObject(state.clsBinOp); + PythonObject o = createPythonObject(state.clsBinOp); o.setAttribute(AstState.T_F_LEFT, visitNonNull(node.left)); o.setAttribute(AstState.T_F_OP, visitNonNull(node.op)); o.setAttribute(AstState.T_F_RIGHT, visitNonNull(node.right)); @@ -396,7 +396,7 @@ public Object visit(ExprTy.BinOp node) { @Override public Object visit(ExprTy.UnaryOp node) { - PythonObject o = factory.createPythonObject(state.clsUnaryOp); + PythonObject o = createPythonObject(state.clsUnaryOp); o.setAttribute(AstState.T_F_OP, visitNonNull(node.op)); o.setAttribute(AstState.T_F_OPERAND, visitNonNull(node.operand)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -405,7 +405,7 @@ public Object visit(ExprTy.UnaryOp node) { @Override public Object visit(ExprTy.Lambda node) { - PythonObject o = factory.createPythonObject(state.clsLambda); + PythonObject o = createPythonObject(state.clsLambda); o.setAttribute(AstState.T_F_ARGS, visitNonNull(node.args)); o.setAttribute(AstState.T_F_BODY, visitNonNull(node.body)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -414,7 +414,7 @@ public Object visit(ExprTy.Lambda node) { @Override public Object visit(ExprTy.IfExp node) { - PythonObject o = factory.createPythonObject(state.clsIfExp); + PythonObject o = createPythonObject(state.clsIfExp); o.setAttribute(AstState.T_F_TEST, visitNonNull(node.test)); o.setAttribute(AstState.T_F_BODY, visitNonNull(node.body)); o.setAttribute(AstState.T_F_ORELSE, visitNonNull(node.orElse)); @@ -424,7 +424,7 @@ public Object visit(ExprTy.IfExp node) { @Override public Object visit(ExprTy.Dict node) { - PythonObject o = factory.createPythonObject(state.clsDict); + PythonObject o = createPythonObject(state.clsDict); o.setAttribute(AstState.T_F_KEYS, seq2List(node.keys)); o.setAttribute(AstState.T_F_VALUES, seq2List(node.values)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -433,7 +433,7 @@ public Object visit(ExprTy.Dict node) { @Override public Object visit(ExprTy.Set node) { - PythonObject o = factory.createPythonObject(state.clsSet); + PythonObject o = createPythonObject(state.clsSet); o.setAttribute(AstState.T_F_ELTS, seq2List(node.elements)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -441,7 +441,7 @@ public Object visit(ExprTy.Set node) { @Override public Object visit(ExprTy.ListComp node) { - PythonObject o = factory.createPythonObject(state.clsListComp); + PythonObject o = createPythonObject(state.clsListComp); o.setAttribute(AstState.T_F_ELT, visitNonNull(node.element)); o.setAttribute(AstState.T_F_GENERATORS, seq2List(node.generators)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -450,7 +450,7 @@ public Object visit(ExprTy.ListComp node) { @Override public Object visit(ExprTy.SetComp node) { - PythonObject o = factory.createPythonObject(state.clsSetComp); + PythonObject o = createPythonObject(state.clsSetComp); o.setAttribute(AstState.T_F_ELT, visitNonNull(node.element)); o.setAttribute(AstState.T_F_GENERATORS, seq2List(node.generators)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -459,7 +459,7 @@ public Object visit(ExprTy.SetComp node) { @Override public Object visit(ExprTy.DictComp node) { - PythonObject o = factory.createPythonObject(state.clsDictComp); + PythonObject o = createPythonObject(state.clsDictComp); o.setAttribute(AstState.T_F_KEY, visitNonNull(node.key)); o.setAttribute(AstState.T_F_VALUE, visitNonNull(node.value)); o.setAttribute(AstState.T_F_GENERATORS, seq2List(node.generators)); @@ -469,7 +469,7 @@ public Object visit(ExprTy.DictComp node) { @Override public Object visit(ExprTy.GeneratorExp node) { - PythonObject o = factory.createPythonObject(state.clsGeneratorExp); + PythonObject o = createPythonObject(state.clsGeneratorExp); o.setAttribute(AstState.T_F_ELT, visitNonNull(node.element)); o.setAttribute(AstState.T_F_GENERATORS, seq2List(node.generators)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -478,7 +478,7 @@ public Object visit(ExprTy.GeneratorExp node) { @Override public Object visit(ExprTy.Await node) { - PythonObject o = factory.createPythonObject(state.clsAwait); + PythonObject o = createPythonObject(state.clsAwait); o.setAttribute(AstState.T_F_VALUE, visitNonNull(node.value)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -486,7 +486,7 @@ public Object visit(ExprTy.Await node) { @Override public Object visit(ExprTy.Yield node) { - PythonObject o = factory.createPythonObject(state.clsYield); + PythonObject o = createPythonObject(state.clsYield); o.setAttribute(AstState.T_F_VALUE, visitNullable(node.value)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -494,7 +494,7 @@ public Object visit(ExprTy.Yield node) { @Override public Object visit(ExprTy.YieldFrom node) { - PythonObject o = factory.createPythonObject(state.clsYieldFrom); + PythonObject o = createPythonObject(state.clsYieldFrom); o.setAttribute(AstState.T_F_VALUE, visitNonNull(node.value)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -502,7 +502,7 @@ public Object visit(ExprTy.YieldFrom node) { @Override public Object visit(ExprTy.Compare node) { - PythonObject o = factory.createPythonObject(state.clsCompare); + PythonObject o = createPythonObject(state.clsCompare); o.setAttribute(AstState.T_F_LEFT, visitNonNull(node.left)); o.setAttribute(AstState.T_F_OPS, seq2List(node.ops)); o.setAttribute(AstState.T_F_COMPARATORS, seq2List(node.comparators)); @@ -512,7 +512,7 @@ public Object visit(ExprTy.Compare node) { @Override public Object visit(ExprTy.Call node) { - PythonObject o = factory.createPythonObject(state.clsCall); + PythonObject o = createPythonObject(state.clsCall); o.setAttribute(AstState.T_F_FUNC, visitNonNull(node.func)); o.setAttribute(AstState.T_F_ARGS, seq2List(node.args)); o.setAttribute(AstState.T_F_KEYWORDS, seq2List(node.keywords)); @@ -522,7 +522,7 @@ public Object visit(ExprTy.Call node) { @Override public Object visit(ExprTy.FormattedValue node) { - PythonObject o = factory.createPythonObject(state.clsFormattedValue); + PythonObject o = createPythonObject(state.clsFormattedValue); o.setAttribute(AstState.T_F_VALUE, visitNonNull(node.value)); o.setAttribute(AstState.T_F_CONVERSION, visitNonNull(node.conversion)); o.setAttribute(AstState.T_F_FORMAT_SPEC, visitNullable(node.formatSpec)); @@ -532,7 +532,7 @@ public Object visit(ExprTy.FormattedValue node) { @Override public Object visit(ExprTy.JoinedStr node) { - PythonObject o = factory.createPythonObject(state.clsJoinedStr); + PythonObject o = createPythonObject(state.clsJoinedStr); o.setAttribute(AstState.T_F_VALUES, seq2List(node.values)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -540,7 +540,7 @@ public Object visit(ExprTy.JoinedStr node) { @Override public Object visit(ExprTy.Constant node) { - PythonObject o = factory.createPythonObject(state.clsConstant); + PythonObject o = createPythonObject(state.clsConstant); o.setAttribute(AstState.T_F_VALUE, visitNonNull(node.value)); o.setAttribute(AstState.T_F_KIND, visitNullableStringOrByteArray(node.kind)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -549,7 +549,7 @@ public Object visit(ExprTy.Constant node) { @Override public Object visit(ExprTy.Attribute node) { - PythonObject o = factory.createPythonObject(state.clsAttribute); + PythonObject o = createPythonObject(state.clsAttribute); o.setAttribute(AstState.T_F_VALUE, visitNonNull(node.value)); o.setAttribute(AstState.T_F_ATTR, visitNonNull(node.attr)); o.setAttribute(AstState.T_F_CTX, visitNonNull(node.context)); @@ -559,7 +559,7 @@ public Object visit(ExprTy.Attribute node) { @Override public Object visit(ExprTy.Subscript node) { - PythonObject o = factory.createPythonObject(state.clsSubscript); + PythonObject o = createPythonObject(state.clsSubscript); o.setAttribute(AstState.T_F_VALUE, visitNonNull(node.value)); o.setAttribute(AstState.T_F_SLICE, visitNonNull(node.slice)); o.setAttribute(AstState.T_F_CTX, visitNonNull(node.context)); @@ -569,7 +569,7 @@ public Object visit(ExprTy.Subscript node) { @Override public Object visit(ExprTy.Starred node) { - PythonObject o = factory.createPythonObject(state.clsStarred); + PythonObject o = createPythonObject(state.clsStarred); o.setAttribute(AstState.T_F_VALUE, visitNonNull(node.value)); o.setAttribute(AstState.T_F_CTX, visitNonNull(node.context)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -578,7 +578,7 @@ public Object visit(ExprTy.Starred node) { @Override public Object visit(ExprTy.Name node) { - PythonObject o = factory.createPythonObject(state.clsName); + PythonObject o = createPythonObject(state.clsName); o.setAttribute(AstState.T_F_ID, visitNonNull(node.id)); o.setAttribute(AstState.T_F_CTX, visitNonNull(node.context)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -587,7 +587,7 @@ public Object visit(ExprTy.Name node) { @Override public Object visit(ExprTy.List node) { - PythonObject o = factory.createPythonObject(state.clsList); + PythonObject o = createPythonObject(state.clsList); o.setAttribute(AstState.T_F_ELTS, seq2List(node.elements)); o.setAttribute(AstState.T_F_CTX, visitNonNull(node.context)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -596,7 +596,7 @@ public Object visit(ExprTy.List node) { @Override public Object visit(ExprTy.Tuple node) { - PythonObject o = factory.createPythonObject(state.clsTuple); + PythonObject o = createPythonObject(state.clsTuple); o.setAttribute(AstState.T_F_ELTS, seq2List(node.elements)); o.setAttribute(AstState.T_F_CTX, visitNonNull(node.context)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -605,7 +605,7 @@ public Object visit(ExprTy.Tuple node) { @Override public Object visit(ExprTy.Slice node) { - PythonObject o = factory.createPythonObject(state.clsSlice); + PythonObject o = createPythonObject(state.clsSlice); o.setAttribute(AstState.T_F_LOWER, visitNullable(node.lower)); o.setAttribute(AstState.T_F_UPPER, visitNullable(node.upper)); o.setAttribute(AstState.T_F_STEP, visitNullable(node.step)); @@ -715,7 +715,7 @@ public Object visitNonNull(CmpOpTy v) { @Override public Object visit(ComprehensionTy node) { - PythonObject o = factory.createPythonObject(state.clsComprehensionTy); + PythonObject o = createPythonObject(state.clsComprehensionTy); o.setAttribute(AstState.T_F_TARGET, visitNonNull(node.target)); o.setAttribute(AstState.T_F_ITER, visitNonNull(node.iter)); o.setAttribute(AstState.T_F_IFS, seq2List(node.ifs)); @@ -725,7 +725,7 @@ public Object visit(ComprehensionTy node) { @Override public Object visit(ExceptHandlerTy.ExceptHandler node) { - PythonObject o = factory.createPythonObject(state.clsExceptHandler); + PythonObject o = createPythonObject(state.clsExceptHandler); o.setAttribute(AstState.T_F_TYPE, visitNullable(node.type)); o.setAttribute(AstState.T_F_NAME, visitNullable(node.name)); o.setAttribute(AstState.T_F_BODY, seq2List(node.body)); @@ -735,7 +735,7 @@ public Object visit(ExceptHandlerTy.ExceptHandler node) { @Override public Object visit(ArgumentsTy node) { - PythonObject o = factory.createPythonObject(state.clsArgumentsTy); + PythonObject o = createPythonObject(state.clsArgumentsTy); o.setAttribute(AstState.T_F_POSONLYARGS, seq2List(node.posOnlyArgs)); o.setAttribute(AstState.T_F_ARGS, seq2List(node.args)); o.setAttribute(AstState.T_F_VARARG, visitNullable(node.varArg)); @@ -748,7 +748,7 @@ public Object visit(ArgumentsTy node) { @Override public Object visit(ArgTy node) { - PythonObject o = factory.createPythonObject(state.clsArgTy); + PythonObject o = createPythonObject(state.clsArgTy); o.setAttribute(AstState.T_F_ARG, visitNonNull(node.arg)); o.setAttribute(AstState.T_F_ANNOTATION, visitNullable(node.annotation)); o.setAttribute(AstState.T_F_TYPE_COMMENT, visitNullableStringOrByteArray(node.typeComment)); @@ -758,7 +758,7 @@ public Object visit(ArgTy node) { @Override public Object visit(KeywordTy node) { - PythonObject o = factory.createPythonObject(state.clsKeywordTy); + PythonObject o = createPythonObject(state.clsKeywordTy); o.setAttribute(AstState.T_F_ARG, visitNullable(node.arg)); o.setAttribute(AstState.T_F_VALUE, visitNonNull(node.value)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -767,7 +767,7 @@ public Object visit(KeywordTy node) { @Override public Object visit(AliasTy node) { - PythonObject o = factory.createPythonObject(state.clsAliasTy); + PythonObject o = createPythonObject(state.clsAliasTy); o.setAttribute(AstState.T_F_NAME, visitNonNull(node.name)); o.setAttribute(AstState.T_F_ASNAME, visitNullable(node.asName)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -776,7 +776,7 @@ public Object visit(AliasTy node) { @Override public Object visit(WithItemTy node) { - PythonObject o = factory.createPythonObject(state.clsWithItemTy); + PythonObject o = createPythonObject(state.clsWithItemTy); o.setAttribute(AstState.T_F_CONTEXT_EXPR, visitNonNull(node.contextExpr)); o.setAttribute(AstState.T_F_OPTIONAL_VARS, visitNullable(node.optionalVars)); return o; @@ -784,7 +784,7 @@ public Object visit(WithItemTy node) { @Override public Object visit(MatchCaseTy node) { - PythonObject o = factory.createPythonObject(state.clsMatchCaseTy); + PythonObject o = createPythonObject(state.clsMatchCaseTy); o.setAttribute(AstState.T_F_PATTERN, visitNonNull(node.pattern)); o.setAttribute(AstState.T_F_GUARD, visitNullable(node.guard)); o.setAttribute(AstState.T_F_BODY, seq2List(node.body)); @@ -793,7 +793,7 @@ public Object visit(MatchCaseTy node) { @Override public Object visit(PatternTy.MatchValue node) { - PythonObject o = factory.createPythonObject(state.clsMatchValue); + PythonObject o = createPythonObject(state.clsMatchValue); o.setAttribute(AstState.T_F_VALUE, visitNonNull(node.value)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -801,7 +801,7 @@ public Object visit(PatternTy.MatchValue node) { @Override public Object visit(PatternTy.MatchSingleton node) { - PythonObject o = factory.createPythonObject(state.clsMatchSingleton); + PythonObject o = createPythonObject(state.clsMatchSingleton); o.setAttribute(AstState.T_F_VALUE, visitNonNull(node.value)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -809,7 +809,7 @@ public Object visit(PatternTy.MatchSingleton node) { @Override public Object visit(PatternTy.MatchSequence node) { - PythonObject o = factory.createPythonObject(state.clsMatchSequence); + PythonObject o = createPythonObject(state.clsMatchSequence); o.setAttribute(AstState.T_F_PATTERNS, seq2List(node.patterns)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -817,7 +817,7 @@ public Object visit(PatternTy.MatchSequence node) { @Override public Object visit(PatternTy.MatchMapping node) { - PythonObject o = factory.createPythonObject(state.clsMatchMapping); + PythonObject o = createPythonObject(state.clsMatchMapping); o.setAttribute(AstState.T_F_KEYS, seq2List(node.keys)); o.setAttribute(AstState.T_F_PATTERNS, seq2List(node.patterns)); o.setAttribute(AstState.T_F_REST, visitNullable(node.rest)); @@ -827,7 +827,7 @@ public Object visit(PatternTy.MatchMapping node) { @Override public Object visit(PatternTy.MatchClass node) { - PythonObject o = factory.createPythonObject(state.clsMatchClass); + PythonObject o = createPythonObject(state.clsMatchClass); o.setAttribute(AstState.T_F_CLS, visitNonNull(node.cls)); o.setAttribute(AstState.T_F_PATTERNS, seq2List(node.patterns)); o.setAttribute(AstState.T_F_KWD_ATTRS, seq2List(node.kwdAttrs)); @@ -838,7 +838,7 @@ public Object visit(PatternTy.MatchClass node) { @Override public Object visit(PatternTy.MatchStar node) { - PythonObject o = factory.createPythonObject(state.clsMatchStar); + PythonObject o = createPythonObject(state.clsMatchStar); o.setAttribute(AstState.T_F_NAME, visitNullable(node.name)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -846,7 +846,7 @@ public Object visit(PatternTy.MatchStar node) { @Override public Object visit(PatternTy.MatchAs node) { - PythonObject o = factory.createPythonObject(state.clsMatchAs); + PythonObject o = createPythonObject(state.clsMatchAs); o.setAttribute(AstState.T_F_PATTERN, visitNullable(node.pattern)); o.setAttribute(AstState.T_F_NAME, visitNullable(node.name)); fillSourceRangeAttributes(o, node.getSourceRange()); @@ -855,7 +855,7 @@ public Object visit(PatternTy.MatchAs node) { @Override public Object visit(PatternTy.MatchOr node) { - PythonObject o = factory.createPythonObject(state.clsMatchOr); + PythonObject o = createPythonObject(state.clsMatchOr); o.setAttribute(AstState.T_F_PATTERNS, seq2List(node.patterns)); fillSourceRangeAttributes(o, node.getSourceRange()); return o; @@ -863,7 +863,7 @@ public Object visit(PatternTy.MatchOr node) { @Override public Object visit(TypeIgnoreTy.TypeIgnore node) { - PythonObject o = factory.createPythonObject(state.clsTypeIgnore); + PythonObject o = createPythonObject(state.clsTypeIgnore); o.setAttribute(AstState.T_F_LINENO, visitNonNull(node.lineNo)); o.setAttribute(AstState.T_F_TAG, visitNonNullStringOrByteArray(node.tag)); return o; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Sst2ObjVisitorBase.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Sst2ObjVisitorBase.java index 9d106b646d..fe054561f2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Sst2ObjVisitorBase.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Sst2ObjVisitorBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,15 +46,17 @@ import static com.oracle.graal.python.builtins.modules.ast.AstState.T_F_LINENO; import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.object.PythonObject; +import com.oracle.graal.python.builtins.objects.type.PythonClass; import com.oracle.graal.python.pegparser.sst.CmpOpTy; import com.oracle.graal.python.pegparser.sst.ConstantValue; import com.oracle.graal.python.pegparser.sst.SSTNode; import com.oracle.graal.python.pegparser.sst.SSTreeVisitor; import com.oracle.graal.python.pegparser.tokenizer.SourceRange; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.strings.TruffleString; @@ -63,10 +65,10 @@ */ abstract class Sst2ObjVisitorBase implements SSTreeVisitor { - final PythonObjectFactory factory; + final PythonLanguage language; Sst2ObjVisitorBase() { - factory = PythonObjectFactory.getUncached(); + language = PythonLanguage.get(null); } static int visitNullable(int i) { @@ -106,11 +108,11 @@ Object visitNonNullStringOrByteArray(Object o) { return toTruffleStringUncached((String) o); } assert o instanceof byte[]; - return factory.createBytes((byte[]) o); + return PFactory.createBytes(language, (byte[]) o); } final Object visitNonNull(ConstantValue v) { - return PythonUtils.pythonObjectFromConstantValue(v, factory); + return PythonUtils.pythonObjectFromConstantValue(v); } abstract Object visitNonNull(CmpOpTy op); @@ -121,41 +123,45 @@ final Object visitNonNull(SSTNode node) { final PList seq2List(String[] seq) { if (seq == null || seq.length == 0) { - return factory.createList(); + return PFactory.createList(language); } Object[] objs = new Object[seq.length]; for (int i = 0; i < objs.length; ++i) { objs[i] = visitNullable(seq[i]); } - return factory.createList(objs); + return PFactory.createList(language, objs); } final PList seq2List(CmpOpTy[] seq) { if (seq == null || seq.length == 0) { - return factory.createList(); + return PFactory.createList(language); } Object[] objs = new Object[seq.length]; for (int i = 0; i < objs.length; ++i) { objs[i] = visitNullable(seq[i]); } - return factory.createList(objs); + return PFactory.createList(language, objs); } final PList seq2List(SSTNode[] seq) { if (seq == null || seq.length == 0) { - return factory.createList(); + return PFactory.createList(language); } Object[] objs = new Object[seq.length]; for (int i = 0; i < objs.length; ++i) { objs[i] = visitNullable(seq[i]); } - return factory.createList(objs); + return PFactory.createList(language, objs); } - static final void fillSourceRangeAttributes(PythonObject o, SourceRange sourceRange) { + static void fillSourceRangeAttributes(PythonObject o, SourceRange sourceRange) { o.setAttribute(T_F_LINENO, sourceRange.startLine); o.setAttribute(T_F_COL_OFFSET, sourceRange.startColumn); o.setAttribute(T_F_END_LINENO, sourceRange.endLine); o.setAttribute(T_F_END_COL_OFFSET, sourceRange.endColumn); } + + protected PythonObject createPythonObject(PythonClass cls) { + return PFactory.createPythonObject(language, cls, cls.getInstanceShape()); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Validator.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Validator.java index 0c6265010d..c6259fbf05 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Validator.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Validator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -93,13 +93,17 @@ import com.oracle.graal.python.pegparser.sst.UnaryOpTy; import com.oracle.graal.python.pegparser.sst.WithItemTy; import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; final class Validator implements SSTreeVisitor { private static final String[] FORBIDDEN_NAMES = {"None", "True", "False"}; - private Validator() { + private final Node node; + + private Validator(Node node) { + this.node = node; } /*- @@ -107,9 +111,9 @@ private Validator() { */ // Equivalent of _PyAST_Validate - entry point of the validation - static void validateMod(ModTy mod) { + static void validateMod(Node node, ModTy mod) { // TODO recursion checks - mod.accept(new Validator()); + mod.accept(new Validator(node)); } @Override @@ -754,7 +758,7 @@ private void validatePatternMatchValue(ExprTy expr) { throw raiseValueError(ErrorMessages.PATTERNS_MAY_ONLY_MATCH_LITERALS_AND_ATTRIBUTE_LOOKUPS); } - private static void validateCapture(String name) { + private void validateCapture(String name) { if (name.equals("_")) { throw raiseValueError(ErrorMessages.CANT_CAPTURE_NAME_UNDERSCORE_IN_PATTERNS); } @@ -1023,7 +1027,7 @@ private void validateAssignList(ExprTy[] targets, ExprContextTy ctx) { } // Equivalent of _validate_nonempty_seq - private static void validateNonEmptySeq(Object[] seq, TruffleString what, TruffleString owner) { + private void validateNonEmptySeq(Object[] seq, TruffleString what, TruffleString owner) { if (seqLen(seq) == 0) { throw raiseValueError(ErrorMessages.EMPTY_S_ON_S, what, owner); } @@ -1049,7 +1053,7 @@ private static int seqLen(Object[] seq) { } // Equivalent of validate_name - private static void validateName(String id) { + private void validateName(String id) { for (String f : FORBIDDEN_NAMES) { if (f.equals(id)) { throw raiseValueError(ErrorMessages.IDENTIFIER_FIELD_CANT_REPRESENT_S_CONSTANT, f); @@ -1062,11 +1066,11 @@ private void validateConstant(@SuppressWarnings("unused") ConstantValue value) { // Already done in Obj2SstBase#obj2ConstantValue() } - private static PException raiseValueError(TruffleString format, Object... args) { - throw PRaiseNode.getUncached().raise(PythonBuiltinClassType.ValueError, format, args); + private PException raiseValueError(TruffleString format, Object... args) { + throw PRaiseNode.raiseStatic(node, PythonBuiltinClassType.ValueError, format, args); } - private static PException raiseTypeError(TruffleString format, Object... args) { - throw PRaiseNode.getUncached().raise(PythonBuiltinClassType.TypeError, format, args); + private PException raiseTypeError(TruffleString format, Object... args) { + throw PRaiseNode.raiseStatic(node, PythonBuiltinClassType.TypeError, format, args); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/BZ2CompressorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/BZ2CompressorBuiltins.java index f63ae127f2..d97282f490 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/BZ2CompressorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/BZ2CompressorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,12 +47,15 @@ import static com.oracle.graal.python.nodes.ErrorMessages.COMPRESSLEVEL_MUST_BE_BETWEEN_1_AND_9; import static com.oracle.graal.python.nodes.ErrorMessages.COMPRESSOR_HAS_BEEN_FLUSHED; import static com.oracle.graal.python.nodes.ErrorMessages.REPEATED_CALL_TO_FLUSH; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltins; @@ -61,8 +64,10 @@ import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; @@ -71,7 +76,7 @@ import com.oracle.graal.python.runtime.NFIBz2Support; import com.oracle.graal.python.runtime.NativeLibrary; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -84,12 +89,28 @@ @CoreFunctions(extendClasses = BZ2Compressor) public final class BZ2CompressorBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = BZ2CompressorBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return BZ2CompressorBuiltinsFactory.getFactories(); } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self", "compresslevel"}) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "BZ2Compressor", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class BZ2CompressorNode extends PythonBuiltinNode { + @Specialization + static BZ2Object.BZ2Compressor doNew(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") Object arg, + @Bind PythonLanguage language) { + // data filled in subsequent __init__ call - see BZ2CompressorBuiltins.InitNode + return PFactory.createBZ2Compressor(language); + } + } + + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "BZ2Compressor", minNumOfPositionalArgs = 1, parameterNames = {"$self", "compresslevel"}) @ArgumentClinic(name = "compresslevel", conversion = ClinicConversion.Int, defaultValue = "9", useDefaultForNone = true) @GenerateNodeFactory public abstract static class InitNode extends PythonBinaryClinicBuiltinNode { @@ -105,14 +126,14 @@ PNone init(BZ2Object.BZ2Compressor self, int compresslevel, @Cached NativeLibrary.InvokeNativeFunction createStream, @Cached NativeLibrary.InvokeNativeFunction compressInit, @Cached GilNode gil, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { gil.release(true); try { NFIBz2Support bz2Support = PythonContext.get(this).getNFIBz2Support(); Object bzst = bz2Support.createStream(createStream); int err = bz2Support.compressInit(bzst, compresslevel, compressInit); if (err != BZ_OK) { - errorHandling(err, raiseNode.get(inliningTarget)); + errorHandling(inliningTarget, err, raiseNode); } self.init(bzst, bz2Support); return PNone.NONE; @@ -124,8 +145,8 @@ PNone init(BZ2Object.BZ2Compressor self, int compresslevel, @SuppressWarnings("unused") @Fallback static Object err(Object self, Object compresslevel, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, COMPRESSLEVEL_MUST_BE_BETWEEN_1_AND_9); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, COMPRESSLEVEL_MUST_BE_BETWEEN_1_AND_9); } } @@ -134,31 +155,32 @@ static Object err(Object self, Object compresslevel, abstract static class CompressNode extends PythonBinaryBuiltinNode { @Specialization(guards = {"!self.isFlushed()"}) - PBytes doNativeBytes(BZ2Object.BZ2Compressor self, PBytesLike data, + static PBytes doNativeBytes(BZ2Object.BZ2Compressor self, PBytesLike data, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached SequenceStorageNodes.GetInternalByteArrayNode toBytes, - @Shared("c") @Cached Bz2Nodes.Bz2NativeCompress compress, - @Shared @Cached PythonObjectFactory factory) { + @Shared("c") @Cached Bz2Nodes.Bz2NativeCompress compress) { byte[] bytes = toBytes.execute(inliningTarget, data.getSequenceStorage()); int len = data.getSequenceStorage().length(); - return factory.createBytes(compress.compress(self, PythonContext.get(this), bytes, len)); + return PFactory.createBytes(context.getLanguage(inliningTarget), compress.compress(self, context, bytes, len)); } @Specialization(guards = {"!self.isFlushed()"}) - PBytes doNativeObject(VirtualFrame frame, BZ2Object.BZ2Compressor self, Object data, + static PBytes doNativeObject(VirtualFrame frame, BZ2Object.BZ2Compressor self, Object data, + @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached BytesNodes.ToBytesNode toBytes, - @Shared("c") @Cached Bz2Nodes.Bz2NativeCompress compress, - @Shared @Cached PythonObjectFactory factory) { + @Shared("c") @Cached Bz2Nodes.Bz2NativeCompress compress) { byte[] bytes = toBytes.execute(frame, data); int len = bytes.length; - return factory.createBytes(compress.compress(self, PythonContext.get(this), bytes, len)); + return PFactory.createBytes(context.getLanguage(inliningTarget), compress.compress(self, context, bytes, len)); } @SuppressWarnings("unused") @Specialization(guards = "self.isFlushed()") static PNone error(BZ2Object.BZ2Compressor self, Object data, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, COMPRESSOR_HAS_BEEN_FLUSHED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, COMPRESSOR_HAS_BEEN_FLUSHED); } } @@ -167,18 +189,19 @@ static PNone error(BZ2Object.BZ2Compressor self, Object data, abstract static class FlushNode extends PythonUnaryBuiltinNode { @Specialization(guards = {"!self.isFlushed()"}) - PBytes doit(BZ2Object.BZ2Compressor self, - @Cached Bz2Nodes.Bz2NativeCompress compress, - @Cached PythonObjectFactory factory) { + static PBytes doit(BZ2Object.BZ2Compressor self, + @Bind("this") Node inliningTarget, + @Bind PythonContext context, + @Cached Bz2Nodes.Bz2NativeCompress compress) { self.setFlushed(); - return factory.createBytes(compress.flush(self, PythonContext.get(this))); + return PFactory.createBytes(context.getLanguage(inliningTarget), compress.flush(self, context)); } @SuppressWarnings("unused") @Specialization(guards = "self.isFlushed()") static PNone error(BZ2Object.BZ2Compressor self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, REPEATED_CALL_TO_FLUSH); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, REPEATED_CALL_TO_FLUSH); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/BZ2DecompressorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/BZ2DecompressorBuiltins.java index 502e057287..2b7a14f087 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/BZ2DecompressorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/BZ2DecompressorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,11 +45,14 @@ import static com.oracle.graal.python.builtins.modules.bz2.Bz2Nodes.BZ_OK; import static com.oracle.graal.python.builtins.modules.bz2.Bz2Nodes.errorHandling; import static com.oracle.graal.python.nodes.ErrorMessages.END_OF_STREAM_ALREADY_REACHED; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltins; @@ -58,19 +61,20 @@ import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.runtime.NFIBz2Support; import com.oracle.graal.python.runtime.NativeLibrary; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; @@ -79,12 +83,28 @@ @CoreFunctions(extendClasses = BZ2Decompressor) public final class BZ2DecompressorBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = BZ2DecompressorBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return BZ2DecompressorBuiltinsFactory.getFactories(); } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self"}) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "BZ2Decompressor", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class BZ2DecompressorNode extends PythonBuiltinNode { + @Specialization + static BZ2Object.BZ2Decompressor doNew(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") Object arg, + @Bind PythonLanguage language) { + // data filled in subsequent __init__ call - see BZ2DecompressorBuiltins.InitNode + return PFactory.createBZ2Decompressor(language); + } + } + + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "BZDecompressor", minNumOfPositionalArgs = 1, parameterNames = {"$self"}) @GenerateNodeFactory public abstract static class InitNode extends PythonUnaryBuiltinNode { @@ -93,12 +113,12 @@ static PNone init(BZ2Object.BZ2Decompressor self, @Bind("this") Node inliningTarget, @Cached NativeLibrary.InvokeNativeFunction createStream, @Cached NativeLibrary.InvokeNativeFunction compressInit, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { NFIBz2Support bz2Support = PythonContext.get(inliningTarget).getNFIBz2Support(); Object bzst = bz2Support.createStream(createStream); int err = bz2Support.decompressInit(bzst, compressInit); if (err != BZ_OK) { - errorHandling(err, raiseNode.get(inliningTarget)); + errorHandling(inliningTarget, err, raiseNode); } self.init(bzst, bz2Support); return PNone.NONE; @@ -118,34 +138,34 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(guards = {"!self.isEOF()"}) static PBytes doNativeBytes(BZ2Object.BZ2Decompressor self, PBytesLike data, int maxLength, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached SequenceStorageNodes.GetInternalByteArrayNode toBytes, - @Exclusive @Cached Bz2Nodes.Bz2NativeDecompress decompress, - @Shared @Cached PythonObjectFactory factory) { + @Exclusive @Cached Bz2Nodes.Bz2NativeDecompress decompress) { synchronized (self) { byte[] bytes = toBytes.execute(inliningTarget, data.getSequenceStorage()); int len = data.getSequenceStorage().length(); - return factory.createBytes(decompress.execute(inliningTarget, self, bytes, len, maxLength)); + return PFactory.createBytes(language, decompress.execute(inliningTarget, self, bytes, len, maxLength)); } } @Specialization(guards = {"!self.isEOF()"}) static PBytes doNativeObject(VirtualFrame frame, BZ2Object.BZ2Decompressor self, Object data, int maxLength, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached BytesNodes.ToBytesNode toBytes, - @Exclusive @Cached Bz2Nodes.Bz2NativeDecompress decompress, - @Shared @Cached PythonObjectFactory factory) { + @Exclusive @Cached Bz2Nodes.Bz2NativeDecompress decompress) { synchronized (self) { byte[] bytes = toBytes.execute(frame, data); int len = bytes.length; - return factory.createBytes(decompress.execute(inliningTarget, self, bytes, len, maxLength)); + return PFactory.createBytes(language, decompress.execute(inliningTarget, self, bytes, len, maxLength)); } } @SuppressWarnings("unused") @Specialization(guards = {"self.isEOF()"}) static Object err(BZ2Object.BZ2Decompressor self, PBytesLike data, int maxLength, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(EOFError, END_OF_STREAM_ALREADY_REACHED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, EOFError, END_OF_STREAM_ALREADY_REACHED); } } @@ -154,8 +174,8 @@ static Object err(BZ2Object.BZ2Decompressor self, PBytesLike data, int maxLength abstract static class UnusedDataNode extends PythonUnaryBuiltinNode { @Specialization static PBytes doit(BZ2Object.BZ2Decompressor self, - @Cached PythonObjectFactory factory) { - return factory.createBytes(self.getUnusedData()); + @Bind PythonLanguage language) { + return PFactory.createBytes(language, self.getUnusedData()); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/BZ2ModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/BZ2ModuleBuiltins.java index 4d72367d0d..6ac3c04334 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/BZ2ModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/BZ2ModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,57 +40,19 @@ */ package com.oracle.graal.python.builtins.modules.bz2; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.BZ2Compressor; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.BZ2Decompressor; - +import java.util.Collections; import java.util.List; -import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.nodes.BuiltinNames; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; -import com.oracle.truffle.api.dsl.Specialization; @CoreFunctions(defineModule = BuiltinNames.J_BZ2) public final class BZ2ModuleBuiltins extends PythonBuiltins { @Override protected List> getNodeFactories() { - return BZ2ModuleBuiltinsFactory.getFactories(); - } - - protected static final int INITIAL_BUFFER_SIZE = 8192; - - @Override - public void initialize(Python3Core core) { - super.initialize(core); - } - - @Builtin(name = "BZ2Compressor", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = BZ2Compressor) - @GenerateNodeFactory - public abstract static class BZ2CompressorNode extends PythonBuiltinNode { - @Specialization - static BZ2Object.BZ2Compressor doNew(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PythonObjectFactory factory) { - // data filled in subsequent __init__ call - see BZ2CompressorBuiltins.InitNode - return factory.createBZ2Compressor(cls); - } - } - - @Builtin(name = "BZ2Decompressor", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = BZ2Decompressor) - @GenerateNodeFactory - public abstract static class BZ2DecompressorNode extends PythonBuiltinNode { - @Specialization - static BZ2Object.BZ2Decompressor doNew(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PythonObjectFactory factory) { - // data filled in subsequent __init__ call - see BZ2DecompressorBuiltins.InitNode - return factory.createBZ2Decompressor(cls); - } + return Collections.emptyList(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/Bz2Nodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/Bz2Nodes.java index dcc065e578..4e3a527479 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/Bz2Nodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/bz2/Bz2Nodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,7 +42,6 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.EOFError; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; -import static com.oracle.graal.python.builtins.modules.bz2.BZ2ModuleBuiltins.INITIAL_BUFFER_SIZE; import static com.oracle.graal.python.nodes.ErrorMessages.COMPRESSED_FILE_ENDED_BEFORE_EOS; import static com.oracle.graal.python.nodes.ErrorMessages.INVALID_DATA_STREAM; import static com.oracle.graal.python.nodes.ErrorMessages.INVALID_PARAMETERS_PASSED_TO_LIBBZIP2; @@ -94,6 +93,8 @@ public class Bz2Nodes { protected static final int BZ_OUTBUFF_FULL = (-8); protected static final int BZ_CONFIG_ERROR = (-9); + protected static final int INITIAL_BUFFER_SIZE = 8192; + @SuppressWarnings("truffle-inlining") // footprint reduction 40 -> 21 public abstract static class Bz2NativeCompress extends Node { @@ -112,12 +113,12 @@ static byte[] nativeCompress(BZ2Object.BZ2Compressor self, PythonContext context @Bind("this") Node inliningTarget, @Cached NativeLibrary.InvokeNativeFunction compress, @Cached GetOutputNativeBufferNode getBuffer, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { NFIBz2Support bz2Support = context.getNFIBz2Support(); Object inGuest = context.getEnv().asGuestValue(bytes); int err = bz2Support.compress(self.getBzs(), inGuest, len, action, INITIAL_BUFFER_SIZE, compress); if (err != BZ_OK) { - errorHandling(err, raiseNode.get(inliningTarget)); + errorHandling(inliningTarget, err, raiseNode); } return getBuffer.execute(inliningTarget, self.getBzs(), context); } @@ -236,7 +237,7 @@ static byte[] nativeInternalDecompress(BZ2Object.BZ2Decompressor self, int maxLe @Cached GetOutputNativeBufferNode getBuffer, @Cached InlinedConditionProfile errProfile, @Cached InlinedBranchProfile ofProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { PythonContext context = PythonContext.get(inliningTarget); NFIBz2Support bz2Support = context.getNFIBz2Support(); Object inGuest = self.getNextInGuest(context); @@ -249,12 +250,12 @@ static byte[] nativeInternalDecompress(BZ2Object.BZ2Decompressor self, int maxLe self.setBzsAvailInReal(bzsAvailInReal); } catch (OverflowException of) { ofProfile.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(SystemError, VALUE_TOO_LARGE_TO_FIT_INTO_INDEX); + throw raiseNode.raise(inliningTarget, SystemError, VALUE_TOO_LARGE_TO_FIT_INTO_INDEX); } if (err == BZ_STREAM_END) { self.setEOF(); } else if (errProfile.profile(inliningTarget, err != BZ_OK)) { - errorHandling(err, raiseNode.get(inliningTarget)); + errorHandling(inliningTarget, err, raiseNode); } return getBuffer.execute(inliningTarget, self.getBzs(), context); } @@ -271,14 +272,14 @@ static byte[] getBuffer(Node inliningTarget, Object bzst, PythonContext context, @Cached(inline = false) NativeLibrary.InvokeNativeFunction getBufferSize, @Cached(inline = false) NativeLibrary.InvokeNativeFunction getBuffer, @Cached InlinedBranchProfile ofProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { NFIBz2Support bz2Support = context.getNFIBz2Support(); int size; try { size = PInt.intValueExact(bz2Support.getOutputBufferSize(bzst, getBufferSize)); } catch (OverflowException of) { ofProfile.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(SystemError, VALUE_TOO_LARGE_TO_FIT_INTO_INDEX); + throw raiseNode.raise(inliningTarget, SystemError, VALUE_TOO_LARGE_TO_FIT_INTO_INDEX); } if (size == 0) { return PythonUtils.EMPTY_BYTE_ARRAY; @@ -291,25 +292,25 @@ static byte[] getBuffer(Node inliningTarget, Object bzst, PythonContext context, } } - protected static void errorHandling(int bzerror, PRaiseNode raise) { + protected static void errorHandling(Node inliningTarget, int bzerror, PRaiseNode raise) { switch (bzerror) { case BZ_PARAM_ERROR: - throw raise.raise(ValueError, INVALID_PARAMETERS_PASSED_TO_LIBBZIP2); + throw raise.raise(inliningTarget, ValueError, INVALID_PARAMETERS_PASSED_TO_LIBBZIP2); case BZ_MEM_ERROR: - throw raise.raise(MemoryError); + throw raise.raise(inliningTarget, MemoryError); case BZ_DATA_ERROR: case BZ_DATA_ERROR_MAGIC: - throw raise.raise(OSError, INVALID_DATA_STREAM); + throw raise.raise(inliningTarget, OSError, INVALID_DATA_STREAM); case BZ_IO_ERROR: - throw raise.raise(OSError, UNKNOWN_IO_ERROR); + throw raise.raise(inliningTarget, OSError, UNKNOWN_IO_ERROR); case BZ_UNEXPECTED_EOF: - throw raise.raise(EOFError, COMPRESSED_FILE_ENDED_BEFORE_EOS); + throw raise.raise(inliningTarget, EOFError, COMPRESSED_FILE_ENDED_BEFORE_EOS); case BZ_SEQUENCE_ERROR: - throw raise.raise(RuntimeError, INVALID_SEQUENCE_OF_COMMANDS); + throw raise.raise(inliningTarget, RuntimeError, INVALID_SEQUENCE_OF_COMMANDS); case BZ_CONFIG_ERROR: - throw raise.raise(ValueError, LIBBZIP2_WAS_NOT_COMPILED_CORRECTLY); + throw raise.raise(inliningTarget, ValueError, LIBBZIP2_WAS_NOT_COMPILED_CORRECTLY); default: - throw raise.raise(OSError, UNRECOGNIZED_ERROR_FROM_LIBBZIP2_D, bzerror); + throw raise.raise(inliningTarget, OSError, UNRECOGNIZED_ERROR_FROM_LIBBZIP2_D, bzerror); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextAbstractBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextAbstractBuiltins.java index d16ba20a8d..ca111c38f4 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextAbstractBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextAbstractBuiltins.java @@ -60,17 +60,10 @@ import static com.oracle.graal.python.nodes.SpecialMethodNames.T_KEYS; import static com.oracle.graal.python.nodes.SpecialMethodNames.T_VALUES; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IADD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IMUL__; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.StrNode; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.TupleNode; -import com.oracle.graal.python.builtins.modules.BuiltinFunctions.AbsNode; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.BinNode; -import com.oracle.graal.python.builtins.modules.BuiltinFunctions.DivModNode; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.HexNode; -import com.oracle.graal.python.builtins.modules.BuiltinFunctions.NextNode; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.OctNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; @@ -81,7 +74,6 @@ import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext; import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.AsCharPointerNode; -import com.oracle.graal.python.builtins.objects.cext.capi.PrimitiveNativeWrapper; import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CStringWrapper; import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.ItemsNode; @@ -95,29 +87,57 @@ import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.builtins.objects.slice.PSlice; +import com.oracle.graal.python.builtins.objects.str.StringBuiltins; +import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins.TupleNode; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotMpAssSubscript.CallSlotMpAssSubscriptNode; -import com.oracle.graal.python.lib.GetNextNode; -import com.oracle.graal.python.lib.PyIndexCheckNode; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyIterCheckNode; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyNumberAddNode; -import com.oracle.graal.python.lib.PyNumberCheckNode; +import com.oracle.graal.python.lib.PyNumberAndNode; +import com.oracle.graal.python.lib.PyNumberDivmodNode; import com.oracle.graal.python.lib.PyNumberFloatNode; +import com.oracle.graal.python.lib.PyNumberFloorDivideNode; +import com.oracle.graal.python.lib.PyNumberInPlaceAddNode; +import com.oracle.graal.python.lib.PyNumberInPlaceAndNode; +import com.oracle.graal.python.lib.PyNumberInPlaceFloorDivideNode; +import com.oracle.graal.python.lib.PyNumberInPlaceLshiftNode; +import com.oracle.graal.python.lib.PyNumberInPlaceMatrixMultiplyNode; +import com.oracle.graal.python.lib.PyNumberInPlaceMultiplyNode; +import com.oracle.graal.python.lib.PyNumberInPlaceOrNode; +import com.oracle.graal.python.lib.PyNumberInPlacePowerNode; +import com.oracle.graal.python.lib.PyNumberInPlaceRemainderNode; +import com.oracle.graal.python.lib.PyNumberInPlaceRshiftNode; +import com.oracle.graal.python.lib.PyNumberInPlaceSubtractNode; +import com.oracle.graal.python.lib.PyNumberInPlaceTrueDivideNode; +import com.oracle.graal.python.lib.PyNumberInPlaceXorNode; import com.oracle.graal.python.lib.PyNumberIndexNode; import com.oracle.graal.python.lib.PyNumberLongNode; +import com.oracle.graal.python.lib.PyNumberLshiftNode; +import com.oracle.graal.python.lib.PyNumberMatrixMultiplyNode; import com.oracle.graal.python.lib.PyNumberMultiplyNode; +import com.oracle.graal.python.lib.PyNumberOrNode; +import com.oracle.graal.python.lib.PyNumberPowerNode; +import com.oracle.graal.python.lib.PyNumberRemainderNode; +import com.oracle.graal.python.lib.PyNumberRshiftNode; +import com.oracle.graal.python.lib.PyNumberSubtractNode; +import com.oracle.graal.python.lib.PyNumberTrueDivideNode; +import com.oracle.graal.python.lib.PyNumberXorNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PySequenceCheckNode; -import com.oracle.graal.python.lib.PySequenceConcat; +import com.oracle.graal.python.lib.PySequenceConcatNode; import com.oracle.graal.python.lib.PySequenceContainsNode; import com.oracle.graal.python.lib.PySequenceDelItemNode; import com.oracle.graal.python.lib.PySequenceGetItemNode; +import com.oracle.graal.python.lib.PySequenceInPlaceConcatNode; +import com.oracle.graal.python.lib.PySequenceInPlaceRepeatNode; import com.oracle.graal.python.lib.PySequenceIterSearchNode; import com.oracle.graal.python.lib.PySequenceSetItemNode; import com.oracle.graal.python.lib.PySequenceSizeNode; @@ -127,19 +147,11 @@ import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode; import com.oracle.graal.python.nodes.builtins.ListNodes.ConstructListNode; import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallTernaryNode; -import com.oracle.graal.python.nodes.expression.BinaryArithmetic; -import com.oracle.graal.python.nodes.expression.BinaryOpNode; -import com.oracle.graal.python.nodes.expression.InplaceArithmetic; -import com.oracle.graal.python.nodes.expression.LookupAndCallInplaceNode; -import com.oracle.graal.python.nodes.expression.TernaryArithmetic; -import com.oracle.graal.python.nodes.expression.UnaryArithmetic; -import com.oracle.graal.python.nodes.expression.UnaryOpNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.truffle.PythonTypes; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.graal.python.runtime.exception.PythonErrorType; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.TruffleLogger; import com.oracle.truffle.api.dsl.Bind; @@ -147,39 +159,15 @@ import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; public final class PythonCextAbstractBuiltins { - /////// PyIndex /////// - - @CApiBuiltin(ret = Int, args = {PyObject}, call = Direct) - abstract static class PyIndex_Check extends CApiUnaryBuiltinNode { - @Specialization - static Object check(Object obj, - @Bind("this") Node inliningTarget, - @Cached PyIndexCheckNode checkNode) { - return checkNode.execute(inliningTarget, obj) ? 1 : 0; - } - } - /////// PyNumber /////// - @CApiBuiltin(ret = Int, args = {PyObject}, call = Direct) - abstract static class PyNumber_Check extends CApiUnaryBuiltinNode { - @Specialization - static Object check(Object obj, - @Bind("this") Node inliningTarget, - @Cached PyNumberCheckNode checkNode) { - return PInt.intValue(checkNode.execute(inliningTarget, obj)); - } - } - @CApiBuiltin(name = "_PyNumber_Index", ret = PyObjectTransfer, args = {PyObject}, call = Direct) @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject}, call = Direct) abstract static class PyNumber_Index extends CApiUnaryBuiltinNode { @@ -187,7 +175,7 @@ abstract static class PyNumber_Index extends CApiUnaryBuiltinNode { static Object index(Object obj, @Bind("this") Node inliningTarget, @Cached PyNumberIndexNode indexNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { checkNonNullArg(inliningTarget, obj, raiseNode); return indexNode.execute(null, inliningTarget, obj); } @@ -204,24 +192,6 @@ static Object nlong(Object object, } } - @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject}, call = Direct) - abstract static class PyNumber_Absolute extends CApiUnaryBuiltinNode { - @Specialization - static Object abs(Object obj, - @Cached AbsNode absNode) { - return absNode.execute(null, obj); - } - } - - @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Direct) - abstract static class PyNumber_Divmod extends CApiBinaryBuiltinNode { - @Specialization - static Object div(Object a, Object b, - @Cached DivModNode divNode) { - return divNode.execute(null, a, b); - } - } - @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, Int}, call = Direct) abstract static class PyNumber_ToBase extends CApiBinaryBuiltinNode { @Specialization(guards = "base == 2") @@ -243,7 +213,7 @@ static Object toBase(Object n, @SuppressWarnings("unused") int base, static Object toBase(Object n, @SuppressWarnings("unused") int base, @Bind("this") Node inliningTarget, @Shared @Cached PyNumberIndexNode indexNode, - @Cached StrNode strNode) { + @Cached StringBuiltins.StrNewNode strNode) { Object i = indexNode.execute(null, inliningTarget, n); if (i instanceof Boolean) { i = ((boolean) i) ? 1 : 0; @@ -261,8 +231,8 @@ static Object toBase(Object n, @SuppressWarnings("unused") int base, @Specialization(guards = "!checkBase(base)") static Object toBase(@SuppressWarnings("unused") Object n, @SuppressWarnings("unused") int base, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, BASE_MUST_BE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, BASE_MUST_BE); } protected boolean checkBase(int base) { @@ -291,177 +261,273 @@ static Object doGeneric(Object object, } } - @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, Int}, call = Ignored) - abstract static class PyTruffleNumber_UnaryOp extends CApiBinaryBuiltinNode { - static int MAX_CACHE_SIZE = UnaryArithmetic.values().length; - - @Specialization(guards = {"cachedOp == op"}, limit = "MAX_CACHE_SIZE") - static Object doIntLikePrimitiveWrapper(Object left, @SuppressWarnings("unused") int op, - @Cached("op") @SuppressWarnings("unused") int cachedOp, - @Cached("createCallNode(op)") UnaryOpNode callNode) { - return callNode.executeCached(null, left); - } - - /** - * This needs to stay in sync with {@code abstract.c: enum e_unaryop}. - */ - static UnaryOpNode createCallNode(int op) { - UnaryArithmetic unaryArithmetic; - switch (op) { - case 0: - unaryArithmetic = UnaryArithmetic.Pos; - break; - case 1: - unaryArithmetic = UnaryArithmetic.Neg; - break; - case 2: - unaryArithmetic = UnaryArithmetic.Invert; - break; - default: - throw CompilerDirectives.shouldNotReachHere("invalid unary operator"); - } - return unaryArithmetic.create(); - } - } - - @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject, Int}, call = Ignored) - abstract static class PyTruffleNumber_BinOp extends CApiTernaryBuiltinNode { - static int MAX_CACHE_SIZE = BinaryArithmetic.values().length; - - @Specialization(guards = {"cachedOp == op"}, limit = "MAX_CACHE_SIZE") - static Object doIntLikePrimitiveWrapper(Object left, Object right, @SuppressWarnings("unused") int op, - @Cached("op") @SuppressWarnings("unused") int cachedOp, - @Cached("createCallNode(op)") BinaryOpNode callNode) { - return callNode.executeObject(null, left, right); - } - - /** - * This needs to stay in sync with {@code abstract.c: enum e_binop}. - */ - static BinaryOpNode createCallNode(int op) { - return getBinaryArithmetic(op).create(); - } - - private static BinaryArithmetic getBinaryArithmetic(int op) { - switch (op) { - case 0: - return BinaryArithmetic.Add; - case 1: - return BinaryArithmetic.Sub; - case 2: - return BinaryArithmetic.Mul; - case 3: - return BinaryArithmetic.TrueDiv; - case 4: - return BinaryArithmetic.LShift; - case 5: - return BinaryArithmetic.RShift; - case 6: - return BinaryArithmetic.Or; - case 7: - return BinaryArithmetic.And; - case 8: - return BinaryArithmetic.Xor; - case 9: - return BinaryArithmetic.FloorDiv; - case 10: - return BinaryArithmetic.Mod; - case 12: - return BinaryArithmetic.MatMul; - default: - throw CompilerDirectives.shouldNotReachHere("invalid binary operator"); - } + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_Add extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberAddNode addNode) { + return addNode.execute(null, o1, o2); } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_Subtract extends CApiBinaryBuiltinNode { + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberSubtractNode subtractNode) { + return subtractNode.execute(null, o1, o2); + } } - @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject, Int}, call = Ignored) - abstract static class PyTruffleNumber_InPlaceBinOp extends CApiTernaryBuiltinNode { - static int MAX_CACHE_SIZE = InplaceArithmetic.values().length; - - @Specialization(guards = {"cachedOp == op"}, limit = "MAX_CACHE_SIZE") - static Object doIntLikePrimitiveWrapper(Object left, Object right, @SuppressWarnings("unused") int op, - @Cached("op") @SuppressWarnings("unused") int cachedOp, - @Cached("createCallNode(op)") LookupAndCallInplaceNode callNode) { - return callNode.execute(null, left, right); - } - - /** - * This needs to stay in sync with {@code abstract.c: enum e_binop}. - */ - static LookupAndCallInplaceNode createCallNode(int op) { - return getInplaceArithmetic(op).create(); - } - - private static InplaceArithmetic getInplaceArithmetic(int op) { - switch (op) { - case 0: - return InplaceArithmetic.IAdd; - case 1: - return InplaceArithmetic.ISub; - case 2: - return InplaceArithmetic.IMul; - case 3: - return InplaceArithmetic.ITrueDiv; - case 4: - return InplaceArithmetic.ILShift; - case 5: - return InplaceArithmetic.IRShift; - case 6: - return InplaceArithmetic.IOr; - case 7: - return InplaceArithmetic.IAnd; - case 8: - return InplaceArithmetic.IXor; - case 9: - return InplaceArithmetic.IFloorDiv; - case 10: - return InplaceArithmetic.IMod; - case 12: - return InplaceArithmetic.IMatMul; - default: - throw CompilerDirectives.shouldNotReachHere("invalid binary operator"); - } + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_Multiply extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberMultiplyNode multiplyNode) { + return multiplyNode.execute(null, o1, o2); } + } + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_Remainder extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberRemainderNode remainderNode) { + return remainderNode.execute(null, o1, o2); + } } - @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject, PyObject}, call = Direct) - abstract static class PyNumber_InPlacePower extends CApiTernaryBuiltinNode { + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_TrueDivide extends CApiBinaryBuiltinNode { - @Specialization(guards = {"o1.isIntLike()", "o2.isIntLike()", "o3.isIntLike()"}) - static Object doIntLikePrimitiveWrapper(PrimitiveNativeWrapper o1, PrimitiveNativeWrapper o2, PrimitiveNativeWrapper o3, - @Shared @Cached("createIPow()") LookupAndCallInplaceNode callNode) { - return callNode.executeTernary(null, o1.getLong(), o2.getLong(), o3.getLong()); + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberTrueDivideNode trueDivideNode) { + return trueDivideNode.execute(null, o1, o2); } + } - @Specialization(replaces = "doIntLikePrimitiveWrapper") - static Object doGeneric(Object o1, Object o2, Object o3, - @Shared @Cached("createIPow()") LookupAndCallInplaceNode callNode) { - return callNode.executeTernary(null, o1, o2, o3); + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_FloorDivide extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberFloorDivideNode floorDivideNode) { + return floorDivideNode.execute(null, o1, o2); } + } - @NeverDefault - static LookupAndCallInplaceNode createIPow() { - return InplaceArithmetic.IPow.create(); + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_Divmod extends CApiBinaryBuiltinNode { + @Specialization + static Object div(Object a, Object b, + @Bind Node inliningTarget, + @Cached PyNumberDivmodNode divmodNode) { + return divmodNode.execute(null, inliningTarget, a, b); } } - @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject, PyObject}, call = Direct) - abstract static class PyNumber_Power extends CApiTernaryBuiltinNode { - @Child private LookupAndCallTernaryNode callNode; + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_And extends CApiBinaryBuiltinNode { @Specialization - Object doGeneric(Object o1, Object o2, Object o3) { - return ensureCallNode().execute(null, o1, o2, o3); + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberAndNode andNode) { + return andNode.execute(null, o1, o2); } + } - private LookupAndCallTernaryNode ensureCallNode() { - if (callNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - callNode = insert(TernaryArithmetic.Pow.create()); - } - return callNode; + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_Or extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberOrNode orNode) { + return orNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_Xor extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberXorNode xorNode) { + return xorNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_Lshift extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberLshiftNode lshiftNode) { + return lshiftNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_Rshift extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberRshiftNode rshiftNode) { + return rshiftNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_MatrixMultiply extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberMatrixMultiplyNode matrixMultiplyNode) { + return matrixMultiplyNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_InPlaceAdd extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberInPlaceAddNode addNode) { + return addNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_InPlaceSubtract extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberInPlaceSubtractNode subtractNode) { + return subtractNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_InPlaceMultiply extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberInPlaceMultiplyNode multiplyNode) { + return multiplyNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_InPlaceRemainder extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberInPlaceRemainderNode remainderNode) { + return remainderNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_InPlaceTrueDivide extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberInPlaceTrueDivideNode trueDivideNode) { + return trueDivideNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_InPlaceFloorDivide extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberInPlaceFloorDivideNode floorDivideNode) { + return floorDivideNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_InPlaceAnd extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberInPlaceAndNode andNode) { + return andNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_InPlaceOr extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberInPlaceOrNode orNode) { + return orNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_InPlaceXor extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberInPlaceXorNode xorNode) { + return xorNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_InPlaceLshift extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberInPlaceLshiftNode lshiftNode) { + return lshiftNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_InPlaceRshift extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberInPlaceRshiftNode rshiftNode) { + return rshiftNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_InPlaceMatrixMultiply extends CApiBinaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, + @Cached PyNumberInPlaceMatrixMultiplyNode matrixMultiplyNode) { + return matrixMultiplyNode.execute(null, o1, o2); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_InPlacePower extends CApiTernaryBuiltinNode { + + @Specialization + static Object doGeneric(Object o1, Object o2, Object o3, + @Cached PyNumberInPlacePowerNode powerNode) { + return powerNode.execute(null, o1, o2, o3); + } + } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject, PyObject}, call = Ignored) + abstract static class PyTrufflePyNumber_Power extends CApiTernaryBuiltinNode { + + @Specialization + Object doGeneric(Object o1, Object o2, Object o3, + @Cached PyNumberPowerNode powerNode) { + return powerNode.execute(null, o1, o2, o3); } } @@ -499,7 +565,7 @@ static Object setItem(Object obj, long key, Object value, @Bind("this") Node inliningTarget, @Cached PySequenceSetItemNode setItemNode) { if ((int) key != key) { - throw PRaiseNode.raiseUncached(inliningTarget, OverflowError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, key); + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, key); } setItemNode.execute(null, inliningTarget, obj, (int) key, value); return 0; @@ -507,7 +573,6 @@ static Object setItem(Object obj, long key, Object value, } @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, Py_ssize_t, Py_ssize_t}, call = Direct) - @TypeSystemReference(PythonTypes.class) abstract static class PySequence_GetSlice extends CApiTernaryBuiltinNode { @Specialization(guards = "checkNode.execute(inliningTarget, obj)", limit = "1") @@ -523,10 +588,9 @@ static Object getSlice(Object obj, long iLow, long iHigh, @Specialization(guards = "!checkNode.execute(inliningTarget, obj)", limit = "1") static Object getSlice(Object obj, @SuppressWarnings("unused") Object key, @SuppressWarnings("unused") Object value, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Exclusive @Cached PySequenceCheckNode checkNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_IS_UNSLICEABLE, obj); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.OBJ_IS_UNSLICEABLE, obj); } } @@ -543,27 +607,15 @@ static int contains(Object haystack, Object needle, @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, Py_ssize_t}, call = Direct) abstract static class PySequence_InPlaceRepeat extends CApiBinaryBuiltinNode { - @Specialization(guards = {"checkNode.execute(inliningTarget, obj)"}, limit = "1") + @Specialization static Object repeat(Object obj, long n, @Bind("this") Node inliningTarget, - @Cached PyObjectLookupAttr lookupNode, - @Cached CallNode callNode, - @Cached("createMul()") PyNumberMultiplyNode mulNode, - @SuppressWarnings("unused") @Exclusive @Cached PySequenceCheckNode checkNode) { - Object imulCallable = lookupNode.execute(null, inliningTarget, obj, T___IMUL__); - if (imulCallable != PNone.NO_VALUE) { - Object ret = callNode.executeWithoutFrame(imulCallable, n); - return ret; + @Cached PRaiseNode raiseNode, + @Cached PySequenceInPlaceRepeatNode repeat) { + if (!PInt.isIntRange(n)) { + throw raiseNode.raise(inliningTarget, OverflowError); } - return mulNode.execute(null, inliningTarget, obj, n); - } - - @Specialization(guards = "!checkNode.execute(inliningTarget, obj)", limit = "1") - static Object repeat(Object obj, @SuppressWarnings("unused") Object n, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached PySequenceCheckNode checkNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_CANT_BE_REPEATED, obj); + return repeat.execute(null, inliningTarget, obj, (int) n); } } @@ -572,7 +624,7 @@ abstract static class PySequence_Concat extends CApiBinaryBuiltinNode { @Specialization Object doIt(Object s1, Object s2, @Bind("this") Node inliningTarget, - @Cached PySequenceConcat pySeqConcat) { + @Cached PySequenceConcatNode pySeqConcat) { return pySeqConcat.execute(null, inliningTarget, s1, s2); } } @@ -580,26 +632,11 @@ Object doIt(Object s1, Object s2, @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Direct) abstract static class PySequence_InPlaceConcat extends CApiBinaryBuiltinNode { - @Specialization(guards = {"checkNode.execute(inliningTarget, s1)"}, limit = "1") + @Specialization static Object concat(Object s1, Object s2, @Bind("this") Node inliningTarget, - @Cached PyObjectLookupAttr lookupNode, - @Cached CallNode callNode, - @Cached PyNumberAddNode addNode, - @SuppressWarnings("unused") @Exclusive @Cached PySequenceCheckNode checkNode) { - Object iaddCallable = lookupNode.execute(null, inliningTarget, s1, T___IADD__); - if (iaddCallable != PNone.NO_VALUE) { - return callNode.executeWithoutFrame(iaddCallable, s2); - } - return addNode.execute(null, inliningTarget, s1, s2); - } - - @Specialization(guards = "!checkNode.execute(inliningTarget, s1)", limit = "1") - static Object concat(Object s1, @SuppressWarnings("unused") Object s2, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached PySequenceCheckNode checkNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_CANT_BE_CONCATENATED, s1); + @Cached PySequenceInPlaceConcatNode concat) { + return concat.execute(null, inliningTarget, s1, s2); } } @@ -610,7 +647,7 @@ static Object run(Object o, long i, @Bind("this") Node inliningTarget, @Cached PySequenceDelItemNode delItemNode) { if ((int) i != i) { - throw PRaiseNode.raiseUncached(inliningTarget, OverflowError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, i); + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, i); } delItemNode.execute(null, inliningTarget, o, (int) i); return 0; @@ -624,7 +661,7 @@ static Object doManaged(Object delegate, long position, @Bind("this") Node inliningTarget, @Cached PySequenceGetItemNode getItemNode) { if ((int) position != position) { - throw PRaiseNode.raiseUncached(inliningTarget, OverflowError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, position); + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, position); } return getItemNode.execute(null, delegate, (int) position); } @@ -649,14 +686,14 @@ static int setSlice(Object sequence, Object iLow, Object iHigh, Object s, @Cached GetObjectSlotsNode getSlotsNode, @Cached CallSlotMpAssSubscriptNode callSetItem, @Cached PySliceNew sliceNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TpSlots slots = getSlotsNode.execute(inliningTarget, sequence); if (slots.mp_ass_subscript() != null) { PSlice slice = sliceNode.execute(inliningTarget, iLow, iHigh, PNone.NONE); callSetItem.execute(null, inliningTarget, slots.mp_ass_subscript(), sequence, slice, s); return 0; } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.P_OBJECT_DOESNT_SUPPORT_SLICE_ASSIGNMENT, sequence); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.P_OBJECT_DOESNT_SUPPORT_SLICE_ASSIGNMENT, sequence); } } } @@ -669,14 +706,14 @@ static int setSlice(Object sequence, Object iLow, Object iHigh, @Cached GetObjectSlotsNode getSlotsNode, @Cached CallSlotMpAssSubscriptNode callSetItem, @Cached PySliceNew sliceNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TpSlots slots = getSlotsNode.execute(inliningTarget, sequence); if (slots.mp_ass_subscript() != null) { PSlice slice = sliceNode.execute(inliningTarget, iLow, iHigh, PNone.NONE); callSetItem.execute(null, inliningTarget, slots.mp_ass_subscript(), sequence, slice, PNone.NO_VALUE); return 0; } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.P_OBJECT_DOESNT_SUPPORT_SLICE_DELETION, sequence); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.P_OBJECT_DOESNT_SUPPORT_SLICE_DELETION, sequence); } } } @@ -809,7 +846,7 @@ static Object values(Object obj, @Cached PyObjectGetAttr getAttrNode, @Cached CallNode callNode, @Shared @Cached ConstructListNode listNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { checkNonNullArg(inliningTarget, obj, raiseNode); Object attr = getAttrNode.execute(inliningTarget, obj, T_VALUES); return listNode.execute(null, callNode.executeWithoutFrame(attr)); @@ -828,12 +865,12 @@ static int doMapping(Object obj, @Cached com.oracle.graal.python.lib.PyObjectSizeNode sizeNode, @Cached IsSameTypeNode isSameType, @Cached GetClassNode getClassNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object cls = getClassNode.execute(inliningTarget, obj); if (isSameType.execute(inliningTarget, cls, PythonBuiltinClassType.PSet) || isSameType.execute(inliningTarget, cls, PythonBuiltinClassType.PFrozenSet) || isSameType.execute(inliningTarget, cls, PythonBuiltinClassType.PDeque)) { - throw raiseNode.get(inliningTarget).raise(TypeError, OBJ_ISNT_MAPPING, obj); + throw raiseNode.raise(inliningTarget, TypeError, OBJ_ISNT_MAPPING, obj); } else { return sizeNode.execute(null, inliningTarget, obj); } @@ -846,17 +883,12 @@ static int doMapping(Object obj, abstract static class PyIter_Next extends CApiUnaryBuiltinNode { @Specialization Object check(Object object, - @Bind("this") Node inliningTarget, - @Cached NextNode nextNode, - @Cached IsBuiltinObjectProfile isClassProfile) { + @Bind Node inliningTarget, + @Cached PyIterNextNode nextNode) { try { - return nextNode.execute(null, object, PNone.NO_VALUE); - } catch (PException e) { - if (isClassProfile.profileException(inliningTarget, e, PythonBuiltinClassType.StopIteration)) { - return getNativeNull(); - } else { - throw e; - } + return nextNode.execute(null, inliningTarget, object); + } catch (IteratorExhausted e) { + return getNativeNull(); } } } @@ -868,19 +900,20 @@ Object send(Object iter, Object arg, @Bind("this") Node inliningTarget, @Cached PyIterCheckNode pyiterCheck, @Cached PyObjectCallMethodObjArgs callMethodNode, - @Cached GetNextNode getNextNode, + @Cached PyIterNextNode nextNode, @Cached IsBuiltinObjectProfile isClassProfile) { - try { - if (arg instanceof PNone && pyiterCheck.execute(inliningTarget, iter)) { - return getNextNode.execute(iter); - } else { - return callMethodNode.execute(null, inliningTarget, iter, T_SEND, arg); + if (arg instanceof PNone && pyiterCheck.execute(inliningTarget, iter)) { + try { + return nextNode.execute(null, inliningTarget, iter); + } catch (IteratorExhausted e) { + return getNativeNull(); } - } catch (PException e) { - if (isClassProfile.profileException(inliningTarget, e, PythonBuiltinClassType.StopIteration)) { + } else { + try { + return callMethodNode.execute(null, inliningTarget, iter, T_SEND, arg); + } catch (PException e) { + e.expectStopIteration(inliningTarget, isClassProfile); return getNativeNull(); - } else { - throw e; } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBuiltins.java index a1e959050a..f88c7a2d80 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBuiltins.java @@ -190,7 +190,7 @@ import com.oracle.graal.python.runtime.exception.ExceptionUtils; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.MroSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.NativeByteSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage; @@ -205,7 +205,6 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -253,26 +252,26 @@ public abstract static class PromoteBorrowedValue extends Node { @Specialization static PString doString(TruffleString str, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createString(str); + @Bind PythonLanguage language) { + return PFactory.createString(language, str); } @Specialization static PythonBuiltinObject doInteger(int i, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createInt(i); + @Bind PythonLanguage language) { + return PFactory.createInt(language, i); } @Specialization static PythonBuiltinObject doLong(long i, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createInt(i); + @Bind PythonLanguage language) { + return PFactory.createInt(language, i); } @Specialization(guards = "!isNaN(d)") static PythonBuiltinObject doDouble(double d, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createFloat(d); + @Bind PythonLanguage language) { + return PFactory.createFloat(language, d); } static boolean isNaN(double d) { @@ -298,12 +297,12 @@ public static PException checkThrowableBeforeNative(Throwable t, String where1, CompilerDirectives.transferToInterpreter(); PythonContext context = PythonContext.get(null); context.ensureGilAfterFailure(); - PBaseException newException = context.factory().createBaseException(RecursionError, ErrorMessages.MAXIMUM_RECURSION_DEPTH_EXCEEDED, EMPTY_OBJECT_ARRAY); + PBaseException newException = PFactory.createBaseException(context.getLanguage(), RecursionError, ErrorMessages.MAXIMUM_RECURSION_DEPTH_EXCEEDED, EMPTY_OBJECT_ARRAY); throw ExceptionUtils.wrapJavaException(soe, null, newException); } if (t instanceof OutOfMemoryError oome) { CompilerDirectives.transferToInterpreter(); - PBaseException newException = PythonContext.get(null).factory().createBaseException(MemoryError); + PBaseException newException = PFactory.createBaseException(PythonLanguage.get(null), MemoryError); throw ExceptionUtils.wrapJavaException(oome, null, newException); } // everything else: log and convert to PException (SystemError) @@ -324,7 +323,7 @@ public static PException checkThrowableBeforeNative(Throwable t, String where1, out.println("ERROR: Native API called without Truffle context. This can happen when called from C-level atexit, C++ global destructor or an unregistered native thread"); } out.flush(); - throw PRaiseNode.raiseUncached(null, SystemError, ErrorMessages.INTERNAL_EXCEPTION_OCCURED); + throw PRaiseNode.raiseStatic(null, SystemError, ErrorMessages.INTERNAL_EXCEPTION_OCCURED); } public abstract static class CApiBuiltinNode extends PNodeWithContext { @@ -375,7 +374,7 @@ protected final CApiContext getCApiContext() { protected final PException badInternalCall(String argName) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(this, SystemError, ErrorMessages.S_S_BAD_ARG_TO_INTERNAL_FUNC, getName(), argName); + throw PRaiseNode.raiseStatic(this, SystemError, ErrorMessages.S_S_BAD_ARG_TO_INTERNAL_FUNC, getName(), argName); } @NonIdempotent @@ -395,25 +394,25 @@ private String getName() { @TruffleBoundary protected PException raiseFallback(Object obj, PythonBuiltinClassType type) { if (obj == PNone.NO_VALUE) { - throw PRaiseNode.raiseUncached(this, SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC_S, getName()); + throw PRaiseNode.raiseStatic(this, SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC_S, getName()); } if (IsSubtypeNode.getUncached().execute(GetClassNode.executeUncached(obj), type)) { - throw PRaiseNode.raiseUncached(this, NotImplementedError, NATIVE_S_SUBTYPES_NOT_IMPLEMENTED, type.getName()); + throw PRaiseNode.raiseStatic(this, NotImplementedError, NATIVE_S_SUBTYPES_NOT_IMPLEMENTED, type.getName()); } else { - throw PRaiseNode.raiseUncached(this, SystemError, ErrorMessages.EXPECTED_S_NOT_P, type.getName(), obj); + throw PRaiseNode.raiseStatic(this, SystemError, ErrorMessages.EXPECTED_S_NOT_P, type.getName(), obj); } } @TruffleBoundary protected PException raiseFallback(Object obj, PythonBuiltinClassType type1, PythonBuiltinClassType type2) { if (obj == PNone.NO_VALUE) { - throw PRaiseNode.raiseUncached(this, SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC_S, getName()); + throw PRaiseNode.raiseStatic(this, SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC_S, getName()); } Object objType = GetClassNode.executeUncached(obj); if (IsSubtypeNode.getUncached().execute(objType, type1) || IsSubtypeNode.getUncached().execute(objType, type2)) { - throw PRaiseNode.raiseUncached(this, NotImplementedError, NATIVE_S_SUBTYPES_NOT_IMPLEMENTED, type1.getName()); + throw PRaiseNode.raiseStatic(this, NotImplementedError, NATIVE_S_SUBTYPES_NOT_IMPLEMENTED, type1.getName()); } else { - throw PRaiseNode.raiseUncached(this, SystemError, ErrorMessages.EXPECTED_S_NOT_P, type1.getName(), obj); + throw PRaiseNode.raiseStatic(this, SystemError, ErrorMessages.EXPECTED_S_NOT_P, type1.getName(), obj); } } @@ -426,18 +425,18 @@ protected final int castToInt(long elementSize) { return (int) elementSize; } CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(this, SystemError, INDEX_OUT_OF_RANGE); + throw PRaiseNode.raiseStatic(this, SystemError, INDEX_OUT_OF_RANGE); } - protected static void checkNonNullArg(Node inliningTarget, Object obj, PRaiseNode.Lazy raiseNode) { + protected static void checkNonNullArg(Node inliningTarget, Object obj, PRaiseNode raiseNode) { if (obj == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(SystemError, ErrorMessages.NULL_ARG_INTERNAL); + throw raiseNode.raise(inliningTarget, SystemError, ErrorMessages.NULL_ARG_INTERNAL); } } - protected static void checkNonNullArg(Node inliningTarget, Object obj1, Object obj2, PRaiseNode.Lazy raiseNode) { + protected static void checkNonNullArg(Node inliningTarget, Object obj1, Object obj2, PRaiseNode raiseNode) { if (obj1 == PNone.NO_VALUE || obj2 == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(SystemError, ErrorMessages.NULL_ARG_INTERNAL); + throw raiseNode.raise(inliningTarget, SystemError, ErrorMessages.NULL_ARG_INTERNAL); } } } @@ -892,9 +891,9 @@ public enum CApiCallPath { */ Direct, /** - * This builtin has an explicit C implementation that can be executed both from native and - * from Sulong - no automatic stub will be generated. Further, there *MUST NOT* be a C API - * builtin that would implement the function in Java. + * This builtin has an explicit C implementation that can be executed both from native - no + * automatic stub will be generated. Further, there *MUST NOT* be a C API builtin that would + * implement the function in Java. */ CImpl, /** @@ -993,7 +992,7 @@ abstract static class PyTruffle_Type extends CApiUnaryBuiltinNode { static Object doI(TruffleString typeName, @Bind("this") Node inliningTarget, @Cached TruffleString.EqualNode eqNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Python3Core core = PythonContext.get(inliningTarget); for (PythonBuiltinClassType type : PythonBuiltinClassType.VALUES) { if (eqNode.execute(type.getName(), typeName, TS_ENCODING)) { @@ -1006,7 +1005,7 @@ static Object doI(TruffleString typeName, return attribute; } } - throw raiseNode.get(inliningTarget).raise(PythonErrorType.KeyError, ErrorMessages.APOSTROPHE_S, typeName); + throw raiseNode.raise(inliningTarget, PythonErrorType.KeyError, ErrorMessages.APOSTROPHE_S, typeName); } } @@ -1143,14 +1142,14 @@ private static Object[] collect(MroSequenceStorage mro, int idx) { abstract static class PyFrame_New extends CApiQuaternaryBuiltinNode { @Specialization static Object newFrame(Object threadState, PCode code, PythonObject globals, Object locals, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { Object frameLocals; if (locals == null || PGuards.isPNone(locals)) { - frameLocals = factory.createDict(); + frameLocals = PFactory.createDict(language); } else { frameLocals = locals; } - return factory.createPFrame(threadState, code, globals, frameLocals); + return PFactory.createPFrame(language, threadState, code, globals, frameLocals); } } @@ -1171,7 +1170,7 @@ static Object wrap(Object bufferStructPointer, Object ownerObj, long lenObj, @Cached CastToJavaIntExactNode castToIntNode, @Cached TruffleString.CodePointLengthNode lengthNode, @Cached TruffleString.CodePointAtIndexNode atIndexNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { int ndim = castToIntNode.execute(inliningTarget, ndimObj); int itemsize = castToIntNode.execute(inliningTarget, itemsizeObj); int len = castToIntNode.execute(inliningTarget, lenObj); @@ -1202,7 +1201,7 @@ static Object wrap(Object bufferStructPointer, Object ownerObj, long lenObj, if (!lib.isNull(bufferStructPointer)) { bufferLifecycleManager = new NativeBufferLifecycleManager.NativeBufferLifecycleManagerFromType(bufferStructPointer); } - return factory.createMemoryView(PythonContext.get(inliningTarget), bufferLifecycleManager, buffer, owner, len, readonly, itemsize, + return PFactory.createMemoryView(language, PythonContext.get(inliningTarget), bufferLifecycleManager, buffer, owner, len, readonly, itemsize, BufferFormat.forMemoryView(format, lengthNode, atIndexNode), format, ndim, bufPointer, 0, shape, strides, suboffsets, flags); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextByteArrayBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextByteArrayBuiltins.java index 8cfbb409bb..fbe4cc493a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextByteArrayBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextByteArrayBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -78,17 +78,17 @@ static Object doNative(PythonAbstractNativeObject obj, @Cached GetPythonObjectClassNode getClassNode, @Cached IsSubtypeNode isSubtypeNode, @Cached CStructAccess.GetElementPtrNode getArray, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (isSubtypeNode.execute(getClassNode.execute(inliningTarget, obj), PythonBuiltinClassType.PByteArray)) { return getArray.getElementPtr(obj.getPtr(), CFields.PyByteArrayObject__ob_start); } - return doError(obj, raiseNode.get(inliningTarget)); + return doError(obj, raiseNode); } @Fallback static Object doError(Object obj, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.EXPECTED_S_P_FOUND, "bytearray", obj); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.EXPECTED_S_P_FOUND, "bytearray", obj); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBytesBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBytesBuiltins.java index e146727e9e..7dd9b9c07f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBytesBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBytesBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -53,13 +53,11 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Py_ssize_t; import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyVarObject__ob_size; -import static com.oracle.graal.python.nodes.ErrorMessages.CANNOT_CONVERT_P_OBJ_TO_S; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ITER__; import java.util.Arrays; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.BytesNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath; @@ -87,17 +85,14 @@ import com.oracle.graal.python.builtins.objects.str.StringBuiltins.ModNode; import com.oracle.graal.python.lib.PyBytesCheckNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; -import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectSizeNode; import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; -import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; import com.oracle.graal.python.nodes.util.CastToByteNode; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.OverflowException; @@ -141,7 +136,7 @@ static long doOther(PythonAbstractNativeObject obj, @TruffleBoundary static long fallback(Object obj, @Bind("this") Node inliningTarget) { - throw PRaiseNode.raiseUncached(inliningTarget, TypeError, ErrorMessages.EXPECTED_BYTES_P_FOUND, obj); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.EXPECTED_BYTES_P_FOUND, obj); } } @@ -176,33 +171,17 @@ static Object fromFormat(TruffleString fmt, Object args, @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject}, call = Direct) abstract static class PyBytes_FromObject extends CApiUnaryBuiltinNode { - @Specialization - static Object fromObject(Object obj, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached IsSubtypeNode isSubtypeNode, - @Cached BytesNode bytesNode, - @Cached PyObjectLookupAttr lookupAttrNode, - @Cached PRaiseNode.Lazy raiseNode) { - if (PGuards.isPBytes(obj)) { - return obj; - } else { - Object klass = getClassNode.execute(inliningTarget, obj); - if (isSubtypeNode.execute(klass, PythonBuiltinClassType.PBytes)) { - return obj; - } else if (isAcceptedSubtype(inliningTarget, obj, klass, isSubtypeNode, lookupAttrNode)) { - return bytesNode.execute(null, PythonBuiltinClassType.PBytes, obj, PNone.NO_VALUE, PNone.NO_VALUE); - } else { - throw raiseNode.get(inliningTarget).raise(TypeError, CANNOT_CONVERT_P_OBJ_TO_S, obj, "bytes"); - } - } + @Specialization(guards = "isBuiltinBytes(bytes)") + static Object bytes(PBytes bytes) { + return bytes; } - private static boolean isAcceptedSubtype(Node inliningTarget, Object obj, Object klass, IsSubtypeNode isSubtypeNode, PyObjectLookupAttr lookupAttrNode) { - return isSubtypeNode.execute(klass, PythonBuiltinClassType.PList) || - isSubtypeNode.execute(klass, PythonBuiltinClassType.PTuple) || - isSubtypeNode.execute(klass, PythonBuiltinClassType.PMemoryView) || - (!isSubtypeNode.execute(klass, PythonBuiltinClassType.PString) && lookupAttrNode.execute(null, inliningTarget, obj, T___ITER__) != PNone.NO_VALUE); + @Fallback + static Object fromObject(Object obj, + @Bind("this") Node inliningTarget, + @Cached BytesNodes.BytesFromObject fromObject) { + byte[] bytes = fromObject.execute(null, obj); + return PFactory.createBytes(PythonLanguage.get(inliningTarget), bytes); } } @@ -217,30 +196,30 @@ abstract static class PyTruffleBytes_FromStringAndSize extends CApiBinaryBuiltin @Specialization static Object doGeneric(PythonNativeWrapper object, long size, + @Bind PythonLanguage language, @Cached NativeToPythonNode asPythonObjectNode, - @Exclusive @Cached BytesNodes.ToBytesNode getByteArrayNode, - @Shared @Cached PythonObjectFactory factory) { + @Exclusive @Cached BytesNodes.ToBytesNode getByteArrayNode) { byte[] ary = getByteArrayNode.execute(null, asPythonObjectNode.execute(object)); if (size >= 0 && size < ary.length) { // cast to int is guaranteed because of 'size < ary.length' - return factory.createBytes(Arrays.copyOf(ary, (int) size)); + return PFactory.createBytes(language, Arrays.copyOf(ary, (int) size)); } else { - return factory.createBytes(ary); + return PFactory.createBytes(language, ary); } } @Specialization(guards = "!isNativeWrapper(nativePointer)") static Object doNativePointer(Object nativePointer, long size, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Exclusive @Cached GetByteArrayNode getByteArrayNode, - @Shared @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { - return factory.createBytes(getByteArrayNode.execute(inliningTarget, nativePointer, size)); + return PFactory.createBytes(language, getByteArrayNode.execute(inliningTarget, nativePointer, size)); } catch (InteropException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.M, e); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.SystemError, ErrorMessages.NEGATIVE_SIZE_PASSED); + throw raiseNode.raise(inliningTarget, PythonErrorType.SystemError, ErrorMessages.NEGATIVE_SIZE_PASSED); } } } @@ -250,30 +229,30 @@ static Object doNativePointer(Object nativePointer, long size, abstract static class PyTruffleByteArray_FromStringAndSize extends CApiBinaryBuiltinNode { @Specialization static Object doGeneric(PythonNativeWrapper object, long size, + @Bind PythonLanguage language, @Cached NativeToPythonNode asPythonObjectNode, - @Exclusive @Cached BytesNodes.ToBytesNode getByteArrayNode, - @Shared @Cached PythonObjectFactory factory) { + @Exclusive @Cached BytesNodes.ToBytesNode getByteArrayNode) { byte[] ary = getByteArrayNode.execute(null, asPythonObjectNode.execute(object)); if (size >= 0 && size < ary.length) { // cast to int is guaranteed because of 'size < ary.length' - return factory.createByteArray(Arrays.copyOf(ary, (int) size)); + return PFactory.createByteArray(language, Arrays.copyOf(ary, (int) size)); } else { - return factory.createByteArray(ary); + return PFactory.createByteArray(language, ary); } } @Specialization(guards = "!isNativeWrapper(nativePointer)") static Object doNativePointer(Object nativePointer, long size, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Exclusive @Cached GetByteArrayNode getByteArrayNode, - @Shared @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { - return factory.createByteArray(getByteArrayNode.execute(inliningTarget, nativePointer, size)); + return PFactory.createByteArray(language, getByteArrayNode.execute(inliningTarget, nativePointer, size)); } catch (InteropException e) { - return raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.M, e); + return raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.M, e); } catch (OverflowException e) { - return raiseNode.get(inliningTarget).raise(PythonErrorType.SystemError, ErrorMessages.NEGATIVE_SIZE_PASSED); + return raiseNode.raise(inliningTarget, PythonErrorType.SystemError, ErrorMessages.NEGATIVE_SIZE_PASSED); } } } @@ -302,8 +281,8 @@ static int resize(PBytesLike self, long newSizeL, @Fallback static int fallback(Object self, @SuppressWarnings("unused") Object o, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, ErrorMessages.EXPECTED_S_NOT_P, "a bytes object", self); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, ErrorMessages.EXPECTED_S_NOT_P, "a bytes object", self); } } @@ -312,43 +291,43 @@ abstract static class PyTruffle_Bytes_EmptyWithCapacity extends CApiUnaryBuiltin @Specialization static PBytes doInt(int size, - @Shared @Cached PythonObjectFactory factory) { - return factory.createBytes(new byte[size]); + @Bind PythonLanguage language) { + return PFactory.createBytes(language, new byte[size]); } @Specialization(rewriteOn = OverflowException.class) static PBytes doLong(long size, - @Shared @Cached PythonObjectFactory factory) throws OverflowException { - return doInt(PInt.intValueExact(size), factory); + @Bind PythonLanguage language) throws OverflowException { + return doInt(PInt.intValueExact(size), language); } @Specialization(replaces = "doLong") static PBytes doLongOvf(long size, @Bind("this") Node inliningTarget, - @Shared @Cached PythonObjectFactory factory, - @Shared("raiseNode") @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Shared("raiseNode") @Cached PRaiseNode raiseNode) { try { - return doInt(PInt.intValueExact(size), factory); + return doInt(PInt.intValueExact(size), language); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raiseNumberTooLarge(IndexError, size); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, size); } } @Specialization(rewriteOn = OverflowException.class) static PBytes doPInt(PInt size, - @Shared @Cached PythonObjectFactory factory) throws OverflowException { - return doInt(size.intValueExact(), factory); + @Bind PythonLanguage language) throws OverflowException { + return doInt(size.intValueExact(), language); } @Specialization(replaces = "doPInt") static PBytes doPIntOvf(PInt size, @Bind("this") Node inliningTarget, - @Shared @Cached PythonObjectFactory factory, - @Shared("raiseNode") @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Shared("raiseNode") @Cached PRaiseNode raiseNode) { try { - return doInt(size.intValueExact(), factory); + return doInt(size.intValueExact(), language); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raiseNumberTooLarge(IndexError, size); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, size); } } } @@ -358,43 +337,43 @@ abstract static class PyTruffle_ByteArray_EmptyWithCapacity extends CApiUnaryBui @Specialization static PByteArray doInt(int size, - @Shared @Cached PythonObjectFactory factory) { - return factory.createByteArray(new byte[size]); + @Bind PythonLanguage language) { + return PFactory.createByteArray(language, new byte[size]); } @Specialization(rewriteOn = OverflowException.class) static PByteArray doLong(long size, - @Shared @Cached PythonObjectFactory factory) throws OverflowException { - return doInt(PInt.intValueExact(size), factory); + @Bind PythonLanguage language) throws OverflowException { + return doInt(PInt.intValueExact(size), language); } @Specialization(replaces = "doLong") static PByteArray doLongOvf(long size, @Bind("this") Node inliningTarget, - @Shared @Cached PythonObjectFactory factory, - @Shared("raiseNode") @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Shared("raiseNode") @Cached PRaiseNode raiseNode) { try { - return doInt(PInt.intValueExact(size), factory); + return doInt(PInt.intValueExact(size), language); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raiseNumberTooLarge(IndexError, size); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, size); } } @Specialization(rewriteOn = OverflowException.class) static PByteArray doPInt(PInt size, - @Shared @Cached PythonObjectFactory factory) throws OverflowException { - return doInt(size.intValueExact(), factory); + @Bind PythonLanguage language) throws OverflowException { + return doInt(size.intValueExact(), language); } @Specialization(replaces = "doPInt") static PByteArray doPIntOvf(PInt size, @Bind("this") Node inliningTarget, - @Shared @Cached PythonObjectFactory factory, - @Shared("raiseNode") @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Shared("raiseNode") @Cached PRaiseNode raiseNode) { try { - return doInt(size.intValueExact(), factory); + return doInt(size.intValueExact(), language); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raiseNumberTooLarge(IndexError, size); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, size); } } } @@ -435,17 +414,17 @@ static Object doNative(PythonAbstractNativeObject obj, @Cached GetPythonObjectClassNode getClassNode, @Cached IsSubtypeNode isSubtypeNode, @Cached CStructAccess.GetElementPtrNode getArray, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (isSubtypeNode.execute(getClassNode.execute(inliningTarget, obj), PythonBuiltinClassType.PBytes)) { return getArray.getElementPtr(obj.getPtr(), CFields.PyBytesObject__ob_sval); } - return doError(obj, raiseNode.get(inliningTarget)); + return doError(obj, raiseNode); } @Fallback static Object doError(Object obj, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.EXPECTED_S_P_FOUND, "bytes", obj); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.EXPECTED_S_P_FOUND, "bytes", obj); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextCEvalBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextCEvalBuiltins.java index 3817f731c0..f8c63811ea 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextCEvalBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextCEvalBuiltins.java @@ -70,7 +70,7 @@ import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.nodes.argument.CreateArgumentsNode; -import com.oracle.graal.python.nodes.call.GenericInvokeNode; +import com.oracle.graal.python.nodes.call.CallDispatchers; import com.oracle.graal.python.nodes.frame.GetCurrentFrameRef; import com.oracle.graal.python.nodes.frame.ReadCallerFrameNode; import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; @@ -157,8 +157,8 @@ static Object doGeneric(PCode code, Object globals, Object locals, @Cached SequenceNodes.GetObjectArrayNode getObjectArrayNode, @Cached CodeNodes.GetCodeSignatureNode getSignatureNode, @Cached CodeNodes.GetCodeCallTargetNode getCallTargetNode, - @Cached CreateArgumentsNode.CreateAndCheckArgumentsNode createAndCheckArgumentsNode, - @Cached GenericInvokeNode invokeNode) { + @Cached CreateArgumentsNode createArgumentsNode, + @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) { Object[] defaults = readNode.readPyObjectArray(defaultValueArrayPtr, defaultValueCount); PKeyword[] kwdefaults = castKwargsNode.execute(inliningTarget, kwdefaultsWrapper); PCell[] closure = null; @@ -177,7 +177,7 @@ static Object doGeneric(PCode code, Object globals, Object locals, // prepare Python frame arguments Object[] userArguments = readNode.readPyObjectArray(argumentArrayPtr, argumentCount); Signature signature = getSignatureNode.execute(inliningTarget, code); - Object[] pArguments = createAndCheckArgumentsNode.execute(inliningTarget, code, userArguments, keywords, signature, null, null, defaults, kwdefaults, false); + Object[] pArguments = createArgumentsNode.execute(inliningTarget, code, userArguments, keywords, signature, null, null, defaults, kwdefaults, false); // set custom locals if (!(locals instanceof PNone)) { @@ -194,7 +194,7 @@ static Object doGeneric(PCode code, Object globals, Object locals, } RootCallTarget rootCallTarget = getCallTargetNode.execute(inliningTarget, code); - return invokeNode.execute(rootCallTarget, pArguments); + return invoke.execute(null, inliningTarget, rootCallTarget, pArguments); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextCapsuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextCapsuleBuiltins.java index 456e9f832f..acf80b9b04 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextCapsuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextCapsuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -55,6 +55,7 @@ import static com.oracle.graal.python.nodes.ErrorMessages.PY_CAPSULE_IMPORT_S_IS_NOT_VALID; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiTernaryBuiltinNode; @@ -66,7 +67,7 @@ import com.oracle.graal.python.nodes.StringLiterals; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; import com.oracle.graal.python.nodes.statement.AbstractImportNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; @@ -100,12 +101,12 @@ public abstract static class PyCapsuleNewNode extends Node { @Specialization static PyCapsule doGeneric(Node inliningTarget, Object pointer, Object namePtr, Object destructor, @CachedLibrary(limit = "1") InteropLibrary interopLibrary, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { if (interopLibrary.isNull(pointer)) { - throw raiseNode.get(inliningTarget).raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT); + throw raiseNode.raise(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT); } - PyCapsule capsule = factory.createCapsuleNativeName(pointer, interopLibrary.isNull(namePtr) ? null : namePtr); + PyCapsule capsule = PFactory.createCapsuleNativeName(language, pointer, interopLibrary.isNull(namePtr) ? null : namePtr); if (!interopLibrary.isNull(destructor)) { capsule.registerDestructor(destructor); } @@ -154,20 +155,19 @@ public abstract static class PyCapsuleGetPointerNode extends Node { @Specialization static Object doCapsule(Node inliningTarget, PyCapsule o, Object name, @Cached PyCapsuleNameMatchesNode nameMatchesNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (o.getPointer() == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetPointer"); + throw raiseNode.raise(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetPointer"); } if (!nameMatchesNode.execute(inliningTarget, name, o.getNamePtr())) { - throw raiseNode.get(inliningTarget).raise(ValueError, CALLED_WITH_INCORRECT_NAME, "PyCapsule_GetPointer"); + throw raiseNode.raise(inliningTarget, ValueError, CALLED_WITH_INCORRECT_NAME, "PyCapsule_GetPointer"); } return o.getPointer(); } @Fallback - static Object doError(Node inliningTarget, @SuppressWarnings("unused") Object o, @SuppressWarnings("unused") Object name, - @Cached PRaiseNode.Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetPointer"); + static Object doError(Node inliningTarget, @SuppressWarnings("unused") Object o, @SuppressWarnings("unused") Object name) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetPointer"); } } @@ -177,17 +177,17 @@ abstract static class PyCapsule_GetName extends CApiUnaryBuiltinNode { @Specialization Object get(PyCapsule o, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (o.getPointer() == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetName"); + throw raiseNode.raise(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetName"); } return o.getNamePtr() == null ? getNULL() : o.getNamePtr(); } @Fallback static Object doit(@SuppressWarnings("unused") Object o, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetName"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetName"); } } @@ -196,9 +196,9 @@ abstract static class PyCapsule_GetDestructor extends CApiUnaryBuiltinNode { @Specialization Object doCapsule(PyCapsule o, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (o.getPointer() == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetDestructor"); + throw raiseNode.raise(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetDestructor"); } if (o.getDestructor() == null) { return getNULL(); @@ -208,8 +208,8 @@ Object doCapsule(PyCapsule o, @Fallback static Object doError(@SuppressWarnings("unused") Object o, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetPointer"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetPointer"); } } @@ -218,9 +218,9 @@ abstract static class PyCapsule_GetContext extends CApiUnaryBuiltinNode { @Specialization Object doCapsule(PyCapsule o, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (o.getPointer() == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetContext"); + throw raiseNode.raise(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetContext"); } if (o.getContext() == null) { return getNULL(); @@ -230,8 +230,8 @@ Object doCapsule(PyCapsule o, @Fallback static Object doError(@SuppressWarnings("unused") Object o, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetPointer"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_GetPointer"); } } @@ -241,13 +241,13 @@ abstract static class PyCapsule_SetPointer extends CApiBinaryBuiltinNode { static int doCapsule(PyCapsule o, Object pointer, @Bind("this") Node inliningTarget, @CachedLibrary(limit = "2") InteropLibrary interopLibrary, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (interopLibrary.isNull(pointer)) { - throw raiseNode.get(inliningTarget).raise(ValueError, CALLED_WITH_NULL_POINTER, "PyCapsule_SetPointer"); + throw raiseNode.raise(inliningTarget, ValueError, CALLED_WITH_NULL_POINTER, "PyCapsule_SetPointer"); } if (o.getPointer() == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetPointer"); + throw raiseNode.raise(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetPointer"); } o.setPointer(pointer); @@ -256,8 +256,8 @@ static int doCapsule(PyCapsule o, Object pointer, @Fallback static Object doError(@SuppressWarnings("unused") Object o, @SuppressWarnings("unused") Object name, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetPointer"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetPointer"); } } @@ -267,9 +267,9 @@ abstract static class PyCapsule_SetName extends CApiBinaryBuiltinNode { static int set(PyCapsule o, Object namePtr, @Bind("this") Node inliningTarget, @CachedLibrary(limit = "1") InteropLibrary lib, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (o.getPointer() == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetName"); + throw raiseNode.raise(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetName"); } o.setNamePtr(lib.isNull(namePtr) ? null : namePtr); return 0; @@ -277,8 +277,8 @@ static int set(PyCapsule o, Object namePtr, @Fallback static Object doError(@SuppressWarnings("unused") Object o, @SuppressWarnings("unused") Object name, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetName"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetName"); } } @@ -288,9 +288,9 @@ abstract static class PyCapsule_SetDestructor extends CApiBinaryBuiltinNode { static int doCapsule(PyCapsule o, Object destructor, @Bind("this") Node inliningTarget, @CachedLibrary(limit = "1") InteropLibrary lib, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (o.getPointer() == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetDestructor"); + throw raiseNode.raise(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetDestructor"); } o.registerDestructor(lib.isNull(destructor) ? null : destructor); return 0; @@ -298,8 +298,8 @@ static int doCapsule(PyCapsule o, Object destructor, @Fallback static Object doError(@SuppressWarnings("unused") Object o, @SuppressWarnings("unused") Object name, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetDestructor"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetDestructor"); } } @@ -308,9 +308,9 @@ abstract static class PyCapsule_SetContext extends CApiBinaryBuiltinNode { @Specialization static int doCapsule(PyCapsule o, Object context, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (o.getPointer() == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetContext"); + throw raiseNode.raise(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetContext"); } o.setContext(context); return 0; @@ -318,8 +318,8 @@ static int doCapsule(PyCapsule o, Object context, @Fallback static Object doError(@SuppressWarnings("unused") Object o, @SuppressWarnings("unused") Object name, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetContext"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, CALLED_WITH_INVALID_PY_CAPSULE_OBJECT, "PyCapsule_SetContext"); } } @@ -334,7 +334,7 @@ static Object doGeneric(Object namePtr, @SuppressWarnings("unused") int noBlock, @Cached TruffleString.IndexOfStringNode indexOfStringNode, @Cached TruffleString.SubstringNode substringNode, @Cached ReadAttributeFromObjectNode getAttrNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleString name = (TruffleString) charPtrToPythonNode.execute(namePtr); TruffleString trace = name; Object object = null; @@ -360,7 +360,7 @@ static Object doGeneric(Object namePtr, @SuppressWarnings("unused") int noBlock, if (capsule != null && PyCapsule_IsValid.doCapsule(capsule, namePtr, inliningTarget, nameMatchesNode) == 1) { return capsule.getPointer(); } else { - throw raiseNode.get(inliningTarget).raise(AttributeError, PY_CAPSULE_IMPORT_S_IS_NOT_VALID, name); + throw raiseNode.raise(inliningTarget, AttributeError, PY_CAPSULE_IMPORT_S_IS_NOT_VALID, name); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextClassBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextClassBuiltins.java index 65c58365f9..d542cf7d3b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextClassBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextClassBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,13 +44,13 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObject; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiUnaryBuiltinNode; import com.oracle.graal.python.builtins.objects.method.PDecoratedMethod; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; @@ -63,10 +63,10 @@ abstract static class PyInstanceMethod_New extends CApiUnaryBuiltinNode { @Specialization static Object staticmethod(Object func, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { checkNonNullArg(inliningTarget, func, raiseNode); - PDecoratedMethod res = factory.createInstancemethod(PythonBuiltinClassType.PInstancemethod); + PDecoratedMethod res = PFactory.createInstancemethod(language); res.setCallable(func); return res; } @@ -77,12 +77,12 @@ abstract static class PyMethod_New extends CApiBinaryBuiltinNode { @Specialization static Object methodNew(Object func, Object self, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { checkNonNullArg(inliningTarget, func, self, raiseNode); // Note: CPython also constructs the object directly, without running the constructor or // checking the inputs - return factory.createMethod(self, func); + return PFactory.createMethod(language, self, func); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextCodeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextCodeBuiltins.java index 4c53354244..cd67388846 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextCodeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextCodeBuiltins.java @@ -117,7 +117,7 @@ static int addr2line(PCode code, int lasti) { if (lasti < 0) { return code.co_firstlineno(); } - return code.bciToLine(code.lastiToBci(lasti)); + return code.lastiToLine(lasti); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextComplexBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextComplexBuiltins.java index 6797e32c2e..000150245d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextComplexBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextComplexBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -50,8 +50,8 @@ import static com.oracle.graal.python.nodes.SpecialMethodNames.T___FLOAT__; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.ComplexNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiUnaryBuiltinNode; @@ -59,6 +59,7 @@ import com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor; import com.oracle.graal.python.builtins.objects.cext.structs.CFields; import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; +import com.oracle.graal.python.builtins.objects.complex.ComplexBuiltins; import com.oracle.graal.python.builtins.objects.complex.PComplex; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.nodes.PRaiseNode; @@ -66,7 +67,7 @@ import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -90,7 +91,7 @@ static int asComplex(PComplex c, Object out, @Specialization(guards = "!isPComplex(obj)") static int doGeneric(Object obj, Object out, - @Cached ComplexNode complexNode, + @Cached ComplexBuiltins.ComplexNewNode complexNode, @Shared @Cached CStructAccess.WriteDoubleNode writeDoubleNode) { PComplex c = (PComplex) complexNode.execute(null, PythonBuiltinClassType.PComplex, obj, PNone.NO_VALUE); writeDoubleNode.write(out, CFields.Py_complex__real, c.getReal()); @@ -122,7 +123,7 @@ static Object asDouble(Object obj, @Cached CallNode callNode, @Cached GetClassNode getClassNode, @Cached IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleString name; if (isComplexSubtypeProfile.profile(inliningTarget, isComplexSubtype(inliningTarget, obj, getClassNode, isSubtypeNode))) { name = T_REAL; @@ -132,7 +133,7 @@ static Object asDouble(Object obj, try { return callNode.executeWithoutFrame(getAttr.execute(null, inliningTarget, obj, name)); } catch (PException e) { - throw raiseNode.get(inliningTarget).raise(TypeError); + throw raiseNode.raise(inliningTarget, TypeError); } } } @@ -173,8 +174,8 @@ abstract static class PyComplex_FromDoubles extends CApiBinaryBuiltinNode { @Specialization static PComplex asDouble(double r, double i, - @Cached PythonObjectFactory factory) { - return factory.createComplex(r, i); + @Bind PythonLanguage language) { + return PFactory.createComplex(language, r, i); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextContextBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextContextBuiltins.java index f586ef8607..18842442b5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextContextBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextContextBuiltins.java @@ -50,6 +50,7 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.VoidNoReturn; import static com.oracle.graal.python.runtime.exception.ExceptionUtils.printPythonLikeStackTrace; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; @@ -65,7 +66,7 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -134,15 +135,15 @@ abstract static class PyContextVar_Set extends CApiBinaryBuiltinNode { static Object doGeneric(Object var, Object val, @Bind("this") Node inliningTarget, @Bind PythonContext pythonContext, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (!(var instanceof PContextVar pvar)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.INSTANCE_OF_CONTEXTVAR_EXPECTED); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.INSTANCE_OF_CONTEXTVAR_EXPECTED); } - PythonContext.PythonThreadState threadState = pythonContext.getThreadState(pythonContext.getLanguage(inliningTarget)); + PythonLanguage language = pythonContext.getLanguage(inliningTarget); + PythonContext.PythonThreadState threadState = pythonContext.getThreadState(language); Object oldValue = pvar.getValue(threadState); pvar.setValue(threadState, val); - return factory.createContextVarsToken(pvar, oldValue); + return PFactory.createContextVarsToken(language, pvar, oldValue); } } @@ -160,8 +161,8 @@ static Object doGeneric( abstract static class PyContext_Copy extends CApiUnaryBuiltinNode { @Specialization static Object doGeneric(PContextVarsContext context, - @Cached PythonObjectFactory factory) { - return factory.copyContextVarsContext(context); + @Bind PythonLanguage language) { + return PFactory.copyContextVarsContext(language, context); } } @@ -169,8 +170,8 @@ static Object doGeneric(PContextVarsContext context, abstract static class PyContext_New extends CApiNullaryBuiltinNode { @Specialization static Object doGeneric( - @Cached PythonObjectFactory factory) { - return factory.createContextVarsContext(); + @Bind PythonLanguage language) { + return PFactory.createContextVarsContext(language); } } @@ -180,7 +181,7 @@ abstract static class PyContext_Enter extends CApiUnaryBuiltinNode { static Object doGeneric(PContextVarsContext context, @Bind("this") Node inliningTarget, @Bind PythonContext pythonContext, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { PythonContext.PythonThreadState threadState = pythonContext.getThreadState(pythonContext.getLanguage(inliningTarget)); context.enter(inliningTarget, threadState, raiseNode); return 0; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDateTimeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDateTimeBuiltins.java index a66ff56b03..86de332a2f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDateTimeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDateTimeBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -66,7 +66,7 @@ import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode; import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode; -import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode; +import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; @@ -81,8 +81,8 @@ public final class PythonCextDateTimeBuiltins { abstract static class PyTruffleDateTimeCAPI_Date_FromDate extends CApiQuaternaryBuiltinNode { @Specialization static Object values(int year, int month, int day, Object type, - @Cached CallVarargsMethodNode call) { - return call.execute(null, type, new Object[]{year, month, day}, PKeyword.EMPTY_KEYWORDS); + @Cached CallNode call) { + return call.execute(null, type, year, month, day); } } @@ -90,8 +90,8 @@ static Object values(int year, int month, int day, Object type, abstract static class PyTruffleDateTimeCAPI_DateTime_FromDateAndTime extends CApi9BuiltinNode { @Specialization static Object values(int year, int month, int day, int hour, int minute, int second, int usecond, Object tzinfo, Object type, - @Cached CallVarargsMethodNode call) { - return call.execute(null, type, new Object[]{year, month, day, hour, minute, second, usecond, tzinfo}, PKeyword.EMPTY_KEYWORDS); + @Cached CallNode call) { + return call.execute(null, type, year, month, day, hour, minute, second, usecond, tzinfo); } } @@ -99,8 +99,8 @@ static Object values(int year, int month, int day, int hour, int minute, int sec abstract static class PyTruffleDateTimeCAPI_Time_FromTime extends CApi6BuiltinNode { @Specialization static Object values(int hour, int minute, int second, int usecond, Object tzinfo, Object type, - @Cached CallVarargsMethodNode call) { - return call.execute(null, type, new Object[]{hour, minute, second, usecond, tzinfo}, PKeyword.EMPTY_KEYWORDS); + @Cached CallNode call) { + return call.execute(null, type, hour, minute, second, usecond, tzinfo); } } @@ -108,9 +108,9 @@ static Object values(int hour, int minute, int second, int usecond, Object tzinf abstract static class PyTruffleDateTimeCAPI_Delta_FromDelta extends CApi5BuiltinNode { @Specialization static Object values(int days, int seconds, int useconds, @SuppressWarnings("unused") int normalize, Object type, - @Cached CallVarargsMethodNode call) { + @Cached CallNode call) { // TODO: "normalize" is ignored for the time being - return call.execute(null, type, new Object[]{days, seconds, useconds}, PKeyword.EMPTY_KEYWORDS); + return call.execute(null, type, days, seconds, useconds); } } @@ -118,8 +118,8 @@ static Object values(int days, int seconds, int useconds, @SuppressWarnings("unu abstract static class PyTruffleDateTimeCAPI_TimeZone_FromTimeZone extends CApiBinaryBuiltinNode { @Specialization Object values(Object offset, Object name, - @Cached CallVarargsMethodNode call) { - return call.execute(null, getCApiContext().timezoneType, new Object[]{offset, name}, PKeyword.EMPTY_KEYWORDS); + @Cached CallNode call) { + return call.execute(null, getCApiContext().timezoneType, offset, name); } } @@ -131,7 +131,7 @@ static Object values(Object type, Object args, Object kwargs, @Cached ExecutePositionalStarargsNode starArgsNode, @Cached ExpandKeywordStarargsNode kwArgsNode, @Cached PyObjectLookupAttr lookupNode, - @Cached CallVarargsMethodNode call) { + @Cached CallNode call) { Object[] callArgs = starArgsNode.executeWith(null, args); PKeyword[] kwds = kwArgsNode.execute(inliningTarget, kwargs); Object fromTSCallable = lookupNode.execute(null, inliningTarget, type, T_FROMTIMESTAMP); @@ -146,10 +146,10 @@ static Object values(Object type, Object args, @Bind("this") Node inliningTarget, @Cached ExecutePositionalStarargsNode starArgsNode, @Cached PyObjectLookupAttr lookupNode, - @Cached CallVarargsMethodNode call) { + @Cached CallNode call) { Object[] callArgs = starArgsNode.executeWith(null, args); Object fromTSCallable = lookupNode.execute(null, inliningTarget, type, T_FROMTIMESTAMP); - return call.execute(null, fromTSCallable, callArgs, PKeyword.EMPTY_KEYWORDS); + return call.execute(null, fromTSCallable, callArgs); } } @@ -157,7 +157,7 @@ static Object values(Object type, Object args, abstract static class PyTruffleDateTimeCAPI_DateTime_FromDateAndTimeAndFold extends CApi10BuiltinNode { @Specialization static Object values(int year, int month, int day, int hour, int minute, int second, int usecond, Object tzinfo, int fold, Object type, - @Cached CallVarargsMethodNode call) { + @Cached CallNode call) { return call.execute(null, type, new Object[]{year, month, day, hour, minute, second, usecond, tzinfo}, new PKeyword[]{new PKeyword(T_FOLD, fold)}); } } @@ -166,7 +166,7 @@ static Object values(int year, int month, int day, int hour, int minute, int sec abstract static class PyTruffleDateTimeCAPI_Time_FromTimeAndFold extends CApi7BuiltinNode { @Specialization static Object values(int hour, int minute, int second, int usecond, Object tzinfo, int fold, Object type, - @Cached CallVarargsMethodNode call) { + @Cached CallNode call) { return call.execute(null, type, new Object[]{hour, minute, second, usecond, tzinfo}, new PKeyword[]{new PKeyword(T_FOLD, fold)}); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDescrBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDescrBuiltins.java index ff8493c9e0..ae83c51388 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDescrBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDescrBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -50,15 +50,16 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyTypeObject; import static com.oracle.graal.python.builtins.objects.cext.common.CExtContext.isClassOrStaticMethod; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApi6BuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApi7BuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiUnaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextTypeBuiltins.CreateGetSetNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextTypeBuiltins.NewClassMethodNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.builtins.objects.mappingproxy.MappingproxyBuiltins; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; @@ -71,7 +72,7 @@ public final class PythonCextDescrBuiltins { abstract static class PyDictProxy_New extends CApiUnaryBuiltinNode { @Specialization static Object values(Object obj, - @Cached BuiltinConstructors.MappingproxyNode mappingNode) { + @Cached MappingproxyBuiltins.MappingproxyNode mappingNode) { return mappingNode.execute(null, PythonBuiltinClassType.PMappingproxy, obj); } } @@ -94,14 +95,14 @@ abstract static class PyTruffleDescr_NewClassMethod extends CApi7BuiltinNode { static Object doNativeCallable(Object methodDefPtr, TruffleString name, Object doc, int flags, Object wrapper, Object methObj, Object type, @Bind("this") Node inliningTarget, @Cached NewClassMethodNode newClassMethodNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { Object func = newClassMethodNode.execute(inliningTarget, methodDefPtr, name, methObj, flags, wrapper, type, doc); if (!isClassOrStaticMethod(flags)) { /* * NewClassMethodNode only wraps method with METH_CLASS and METH_STATIC set but we * need to do so here. */ - func = factory.createClassmethodFromCallableObj(func); + func = PFactory.createClassmethodFromCallableObj(language, func); } return func; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDictBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDictBuiltins.java index 8804ab75a9..f8a2d152f8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDictBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDictBuiltins.java @@ -62,8 +62,8 @@ import java.util.logging.Level; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.StrNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApi5BuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; @@ -100,17 +100,17 @@ import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.list.PList; +import com.oracle.graal.python.builtins.objects.str.StringBuiltins; import com.oracle.graal.python.lib.PyDictDelItem; import com.oracle.graal.python.lib.PyDictSetDefault; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.lib.PyObjectHashNode; -import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.builtins.ListNodes.ConstructListNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.util.CastToJavaLongExactNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.dsl.Bind; @@ -135,8 +135,9 @@ public final class PythonCextDictBuiltins { abstract static class PyDict_New extends CApiNullaryBuiltinNode { @Specialization - static Object run(@Cached PythonObjectFactory factory) { - return factory.createDict(); + static Object run( + @Bind PythonLanguage language) { + return PFactory.createDict(language); } } @@ -288,8 +289,8 @@ abstract static class PyDict_Copy extends CApiUnaryBuiltinNode { static Object copy(PDict dict, @Bind("this") Node inliningTarget, @Cached HashingStorageCopy copyNode, - @Cached PythonObjectFactory factory) { - return factory.createDict(copyNode.execute(inliningTarget, dict.getDictStorage())); + @Bind PythonLanguage language) { + return PFactory.createDict(language, copyNode.execute(inliningTarget, dict.getDictStorage())); } @Fallback @@ -328,9 +329,9 @@ static Object getItem(PDict dict, Object key, @Specialization(guards = "!isDict(obj)") static Object getItem(Object obj, @SuppressWarnings("unused") Object key, - @Cached StrNode strNode, - @Cached PRaiseNode raiseNode) { - return raiseNode.raise(SystemError, BAD_ARG_TO_INTERNAL_FUNC_WAS_S_P, strNode.executeWith(null, obj), obj); + @Bind("this") Node inliningTarget, + @Cached StringBuiltins.StrNewNode strNode) { + return PRaiseNode.raiseStatic(inliningTarget, SystemError, BAD_ARG_TO_INTERNAL_FUNC_WAS_S_P, strNode.executeWith(null, obj), obj); } protected boolean isDict(Object obj) { @@ -392,10 +393,10 @@ static int setItem(PDict dict, Object key, Object value, Object givenHash, @Cached CastToJavaLongExactNode castToLong, @Cached SetItemNode setItemNode, @Cached InlinedBranchProfile wrongHashProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (hashNode.execute(null, inliningTarget, key) != castToLong.execute(inliningTarget, givenHash)) { wrongHashProfile.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.AssertionError, HASH_MISMATCH); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AssertionError, HASH_MISMATCH); } setItemNode.execute(null, inliningTarget, dict, key, value); return 0; @@ -488,8 +489,8 @@ abstract static class PyDict_Keys extends CApiUnaryBuiltinNode { @Specialization static Object keys(PDict dict, @Cached ConstructListNode listNode, - @Cached PythonObjectFactory factory) { - return listNode.execute(null, factory.createDictKeysView(dict)); + @Bind PythonLanguage language) { + return listNode.execute(null, PFactory.createDictKeysView(language, dict)); } @Fallback @@ -503,8 +504,8 @@ abstract static class PyDict_Values extends CApiUnaryBuiltinNode { @Specialization static Object values(PDict dict, @Cached ConstructListNode listNode, - @Cached PythonObjectFactory factory) { - return listNode.execute(null, factory.createDictValuesView(dict)); + @Bind PythonLanguage language) { + return listNode.execute(null, PFactory.createDictValuesView(language, dict)); } @Fallback @@ -519,15 +520,15 @@ abstract static class PyDict_Merge extends CApiTernaryBuiltinNode { @Specialization(guards = {"override != 0"}) static int merge(PDict a, Object b, @SuppressWarnings("unused") int override, @Bind("this") Node inliningTarget, - @Cached PyObjectLookupAttr lookupKeys, - @Cached PyObjectLookupAttr lookupAttr, + @Shared @Cached PyObjectGetAttr getKeys, + @Cached PyObjectGetAttr getUpdate, @Shared @Cached CallNode callNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { // lookup "keys" to raise the right error: - if (lookupKeys.execute(null, inliningTarget, b, T_KEYS) == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(AttributeError, OBJ_P_HAS_NO_ATTR_S, b, T_KEYS); + if (getKeys.execute(null, inliningTarget, b, T_KEYS) == PNone.NO_VALUE) { + throw raiseNode.raise(inliningTarget, AttributeError, OBJ_P_HAS_NO_ATTR_S, b, T_KEYS); } - Object updateCallable = lookupAttr.execute(null, inliningTarget, a, T_UPDATE); + Object updateCallable = getUpdate.execute(null, inliningTarget, a, T_UPDATE); callNode.executeWithoutFrame(updateCallable, new Object[]{b}); return 0; } @@ -559,7 +560,7 @@ static int merge(PDict a, PDict b, @SuppressWarnings("unused") int override, @Specialization(guards = {"override == 0", "!isDict(b)"}) static int merge(PDict a, Object b, @SuppressWarnings("unused") int override, @Bind("this") Node inliningTarget, - @Cached PyObjectGetAttr getAttrNode, + @Shared @Cached PyObjectGetAttr getKeys, @Shared @Cached CallNode callNode, @Cached ConstructListNode listNode, @Cached GetItemNode getKeyNode, @@ -568,7 +569,7 @@ static int merge(PDict a, Object b, @SuppressWarnings("unused") int override, @Cached HashingStorageSetItem setItemA, @Exclusive @Cached InlinedLoopConditionProfile loopProfile, @Cached InlinedBranchProfile noKeyProfile) { - Object attr = getAttrNode.execute(null, inliningTarget, a, T_KEYS); + Object attr = getKeys.execute(null, inliningTarget, a, T_KEYS); PList keys = listNode.execute(null, callNode.execute(null, attr)); SequenceStorage keysStorage = keys.getSequenceStorage(); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java index eebc9919a0..b3780db8a3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java @@ -67,7 +67,6 @@ import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.TypeNode; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.IsInstanceNode; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.IsSubClassNode; import com.oracle.graal.python.builtins.modules.PosixModuleBuiltins.ExitNode; @@ -102,6 +101,7 @@ import com.oracle.graal.python.builtins.objects.traceback.LazyTraceback; import com.oracle.graal.python.builtins.objects.traceback.PTraceback; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TypeBuiltins.TypeNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode; import com.oracle.graal.python.lib.PyDictSetItem; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; @@ -124,7 +124,7 @@ import com.oracle.graal.python.runtime.exception.ExceptionUtils; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -308,11 +308,10 @@ Object run(Object typ, PBaseException val, Object tb) { abstract static class _PyTruffleErr_CreateAndSetException extends CApiBinaryBuiltinNode { @Specialization(guards = "!isExceptionClass(inliningTarget, type, isTypeNode, isSubClassNode)") static Object create(Object type, @SuppressWarnings("unused") Object value, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached IsTypeNode isTypeNode, @SuppressWarnings("unused") @Shared @Cached IsSubClassNode isSubClassNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.SystemError, EXCEPTION_NOT_BASEEXCEPTION, new Object[]{type}); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.SystemError, EXCEPTION_NOT_BASEEXCEPTION, new Object[]{type}); } @Specialization(guards = "isExceptionClass(inliningTarget, type, isTypeNode, isSubClassNode)") @@ -336,6 +335,7 @@ abstract static class PyErr_NewException extends CApiTernaryBuiltinNode { @Specialization static Object newEx(TruffleString name, Object base, Object dict, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached HashingStorageGetItem getItem, @Cached TruffleString.IndexOfCodePointNode indexOfCodepointNode, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @@ -345,19 +345,18 @@ static Object newEx(TruffleString name, Object base, Object dict, @Cached InlinedBranchProfile notDotProfile, @Cached InlinedBranchProfile notModuleProfile, @Cached InlinedConditionProfile baseProfile, - @Cached PythonObjectFactory.Lazy factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (base == PNone.NO_VALUE) { base = PythonErrorType.Exception; } if (dict == PNone.NO_VALUE) { - dict = factory.get(inliningTarget).createDict(); + dict = PFactory.createDict(language); } int length = codePointLengthNode.execute(name, TS_ENCODING); int dotIdx = indexOfCodepointNode.execute(name, '.', 0, length, TS_ENCODING); if (dotIdx < 0) { notDotProfile.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(SystemError, MUST_BE_MODULE_CLASS, "PyErr_NewException", "name"); + throw raiseNode.raise(inliningTarget, SystemError, MUST_BE_MODULE_CLASS, "PyErr_NewException", "name"); } if (getItem.execute(null, inliningTarget, ((PDict) dict).getDictStorage(), base) == null) { notModuleProfile.enter(inliningTarget); @@ -367,7 +366,7 @@ static Object newEx(TruffleString name, Object base, Object dict, if (baseProfile.profile(inliningTarget, base instanceof PTuple)) { bases = (PTuple) base; } else { - bases = factory.get(inliningTarget).createTuple(new Object[]{base}); + bases = PFactory.createTuple(language, new Object[]{base}); } return typeNode.execute(null, PythonBuiltinClassType.PythonClass, substringNode.execute(name, dotIdx + 1, length - dotIdx - 1, TS_ENCODING, false), bases, dict, PKeyword.EMPTY_KEYWORDS); @@ -381,12 +380,12 @@ abstract static class PyErr_NewExceptionWithDoc extends CApiQuaternaryBuiltinNod static Object raise(TruffleString name, Object doc, Object base, Object dict, @Cached PyErr_NewException newExNode, @Cached WriteAttributeToObjectNode writeAtrrNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { if (base == PNone.NO_VALUE) { base = PythonErrorType.Exception; } if (dict == PNone.NO_VALUE) { - dict = factory.createDict(); + dict = PFactory.createDict(language); } Object ex = newExNode.execute(name, base, dict); if (doc != PNone.NO_VALUE) { @@ -406,7 +405,7 @@ Object info( @Cached ExceptionNodes.GetTracebackNode getTracebackNode, @Cached InlinedBranchProfile noExceptionProfile, @Cached GetEscapedExceptionNode getEscapedExceptionNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { AbstractTruffleException currentException = getCaughtExceptionNode.executeFromNative(); if (currentException == null) { noExceptionProfile.enter(inliningTarget); @@ -415,7 +414,7 @@ Object info( assert currentException != PException.NO_EXCEPTION; Object exception = getEscapedExceptionNode.execute(inliningTarget, currentException); Object traceback = noneToNativeNull(inliningTarget, getTracebackNode.execute(inliningTarget, exception)); - return factory.createTuple(new Object[]{getClassNode.execute(inliningTarget, exception), exception, traceback}); + return PFactory.createTuple(language, new Object[]{getClassNode.execute(inliningTarget, exception), exception, traceback}); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFileBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFileBuiltins.java index 4bf832f020..cb78a79e85 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFileBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFileBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,11 +45,11 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Int; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObject; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.StrNode; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.ReprNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiTernaryBuiltinNode; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.str.StringBuiltins; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.StringLiterals; @@ -67,11 +67,11 @@ abstract static class PyFile_WriteObject extends CApiTernaryBuiltinNode { @Specialization static int writeStr(Object obj, Object f, int flags, @Bind("this") Node inliningTarget, - @Cached StrNode strNode, + @Cached StringBuiltins.StrNewNode strNode, @Cached ReprNode reprNode, @Cached PyObjectGetAttr getAttr, @Cached CallNode callNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { checkNonNullArg(inliningTarget, obj, raiseNode); checkNonNullArg(inliningTarget, f, raiseNode); Object value; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFloatBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFloatBuiltins.java index bdbaa62a28..855c106f90 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFloatBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFloatBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -48,10 +48,10 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer; import static com.oracle.graal.python.nodes.ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC_WAS_S_P; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.StrNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiUnaryBuiltinNode; import com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor; +import com.oracle.graal.python.builtins.objects.str.StringBuiltins; import com.oracle.graal.python.lib.PyFloatAsDoubleNode; import com.oracle.graal.python.lib.PyFloatFromString; import com.oracle.graal.python.nodes.PRaiseNode; @@ -73,10 +73,10 @@ static double fromDouble(double d) { @Specialization(guards = "!isDouble(obj)") static Object fromDouble(Object obj, - @Cached StrNode strNode, - @Cached PRaiseNode raiseNode) { + @Bind("this") Node inliningTarget, + @Cached StringBuiltins.StrNewNode strNode) { // cpython PyFloat_FromDouble takes only 'double' - throw raiseNode.raise(SystemError, BAD_ARG_TO_INTERNAL_FUNC_WAS_S_P, strNode.executeWith(null, obj), obj); + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, BAD_ARG_TO_INTERNAL_FUNC_WAS_S_P, strNode.executeWith(null, obj), obj); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFuncBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFuncBuiltins.java index 0aeeef07f6..9835b61b3a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFuncBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextFuncBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,7 +47,7 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiUnaryBuiltinNode; @@ -56,10 +56,10 @@ import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.builtins.objects.method.PDecoratedMethod; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.strings.TruffleString; @@ -69,8 +69,8 @@ public final class PythonCextFuncBuiltins { abstract static class PyStaticMethod_New extends CApiUnaryBuiltinNode { @Specialization static Object staticmethod(Object func, - @Cached PythonObjectFactory factory) { - PDecoratedMethod res = factory.createStaticmethod(PythonBuiltinClassType.PStaticmethod); + @Bind PythonLanguage language) { + PDecoratedMethod res = PFactory.createStaticmethod(language); res.setCallable(func); return res; } @@ -80,8 +80,8 @@ static Object staticmethod(Object func, abstract static class PyClassMethod_New extends CApiUnaryBuiltinNode { @Specialization static Object staticmethod(Object callable, - @Cached PythonObjectFactory factory) { - return factory.createClassmethodFromCallableObj(callable); + @Bind PythonLanguage language) { + return PFactory.createClassmethodFromCallableObj(language, callable); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java index 0b54f33287..bb8895a010 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,10 +44,11 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObject; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.dsl.Cached; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Specialization; public final class PythonCextGenericAliasBuiltins { @@ -56,8 +57,8 @@ public final class PythonCextGenericAliasBuiltins { abstract static class Py_GenericAlias extends CApiBinaryBuiltinNode { @Specialization static Object genericAlias(Object origin, Object args, - @Cached PythonObjectFactory factory) { - return factory.createGenericAlias(origin, args); + @Bind PythonLanguage language) { + return PFactory.createGenericAlias(language, origin, args); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextIterBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextIterBuiltins.java index e9eeca74f2..b08b938c62 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextIterBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextIterBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,13 +45,14 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObject; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.IterNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiUnaryBuiltinNode; import com.oracle.graal.python.builtins.objects.iterator.PSequenceIterator; import com.oracle.graal.python.lib.PyIterCheckNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; @@ -73,8 +74,8 @@ static int check(Object obj, abstract static class PySeqIter_New extends CApiUnaryBuiltinNode { @Specialization static PSequenceIterator call(Object seq, - @Cached PythonObjectFactory factory) { - return factory.createSequenceIterator(seq); + @Bind PythonLanguage language) { + return PFactory.createSequenceIterator(language, seq); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextListBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextListBuiltins.java index 6fdcfc1802..57603cb639 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextListBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextListBuiltins.java @@ -56,6 +56,7 @@ import java.util.Arrays; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; @@ -81,14 +82,12 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.builtins.ListNodes.AppendNode; import com.oracle.graal.python.nodes.builtins.TupleNodes.ConstructTupleNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.NativeObjectSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; -import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; @@ -99,21 +98,21 @@ public final class PythonCextListBuiltins { abstract static class PyList_New extends CApiUnaryBuiltinNode { @Specialization(guards = "size < 0") static Object newListError(long size, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, BAD_ARG_TO_INTERNAL_FUNC_S, size); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, BAD_ARG_TO_INTERNAL_FUNC_S, size); } @SuppressWarnings("unused") @Specialization(guards = "size == 0") static Object newEmptyList(long size, - @Shared @Cached PythonObjectFactory factory) { - return factory.createList(PythonUtils.EMPTY_OBJECT_ARRAY); + @Bind PythonLanguage language) { + return PFactory.createList(language); } @Specialization(guards = "size > 0") static Object newList(long size, - @Shared @Cached PythonObjectFactory factory) { - return factory.createList(array(size)); + @Bind PythonLanguage language) { + return PFactory.createList(language, array(size)); } private static Object[] array(long size) { @@ -133,11 +132,11 @@ static Object doPList(PList list, long key, @Cached ListGeneralizationNode generalizationNode, @Cached SetItemScalarNode setItemNode, @Cached GetItemScalarNode getItemNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { SequenceStorage sequenceStorage = list.getSequenceStorage(); // we must do a bounds-check but we must not normalize the index if (key < 0 || key >= sequenceStorage.length()) { - throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.LIST_INDEX_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.LIST_INDEX_OUT_OF_RANGE); } Object result = getItemNode.execute(inliningTarget, sequenceStorage, (int) key); Object promotedValue = promoteNode.execute(inliningTarget, result); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextLongBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextLongBuiltins.java index 9b935668c4..9552018377 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextLongBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextLongBuiltins.java @@ -59,6 +59,7 @@ import java.math.BigInteger; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApi5BuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; @@ -84,7 +85,7 @@ import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.OverflowException; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; @@ -228,7 +229,7 @@ static Object doGeneric(Object object, int mode, long targetTypeSize, @Cached GetClassNode getClassNode, @Cached ConvertPIntToPrimitiveNode convertPIntToPrimitiveNode, @Cached CastToNativeLongNode castToNativeLongNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { /* * The 'mode' parameter is usually a constant since this function is primarily used @@ -236,7 +237,7 @@ static Object doGeneric(Object object, int mode, long targetTypeSize, * profile the value and even if it is not constant, it is profiled implicitly. */ if (requiredPInt(mode) && !isSubtypeNode.execute(getClassNode.execute(inliningTarget, object), PythonBuiltinClassType.PInt)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.INTEGER_REQUIRED); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.INTEGER_REQUIRED); } // the 'ConvertPIntToPrimitiveNode' uses 'AsNativePrimitive' which does coercion Object coerced = convertPIntToPrimitiveNode.execute(inliningTarget, object, signed(mode), PInt.intValueExact(targetTypeSize), exact(mode)); @@ -275,16 +276,16 @@ static long doSignedLong(long n) { @Specialization(guards = "!isInteger(pointer)", limit = "2") static Object doPointer(Object pointer, @CachedLibrary("pointer") InteropLibrary lib, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { // We capture the native pointer at the time when we create the wrapper if it exists. if (lib.isPointer(pointer)) { try { - return factory.createNativeVoidPtr(pointer, lib.asPointer(pointer)); + return PFactory.createNativeVoidPtr(language, pointer, lib.asPointer(pointer)); } catch (UnsupportedMessageException e) { throw CompilerDirectives.shouldNotReachHere(e); } } - return factory.createNativeVoidPtr(pointer); + return PFactory.createNativeVoidPtr(language, pointer); } } @@ -308,23 +309,23 @@ static Object doUnsignedLongPositive(long n) { @Specialization(guards = "n < 0") static Object doUnsignedLongNegative(long n, - @Shared @Cached PythonObjectFactory factory) { - return factory.createInt(convertToBigInteger(n)); + @Bind PythonLanguage language) { + return PFactory.createInt(language, convertToBigInteger(n)); } @Specialization(guards = "!isInteger(pointer)", limit = "2") static Object doPointer(Object pointer, @CachedLibrary("pointer") InteropLibrary lib, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { // We capture the native pointer at the time when we create the wrapper if it exists. if (lib.isPointer(pointer)) { try { - return factory.createNativeVoidPtr(pointer, lib.asPointer(pointer)); + return PFactory.createNativeVoidPtr(language, pointer, lib.asPointer(pointer)); } catch (UnsupportedMessageException e) { throw CompilerDirectives.shouldNotReachHere(e); } } - return factory.createNativeVoidPtr(pointer); + return PFactory.createNativeVoidPtr(language, pointer); } @TruffleBoundary @@ -352,13 +353,13 @@ static long doPointer(long n) { long doPointer(PInt n, @Bind("this") Node inliningTarget, @Cached InlinedBranchProfile overflowProfile, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { try { return n.longValueExact(); } catch (OverflowException e) { overflowProfile.enter(inliningTarget); try { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "C long"); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "C long"); } catch (PException pe) { ensureTransformExcNode().executeCached(pe); return 0; @@ -374,7 +375,7 @@ static Object doPointer(PythonNativeVoidPtr n) { @Fallback long doGeneric(Object n, @Bind("this") Node inliningTarget, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (asPrimitiveNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); asPrimitiveNode = insert(ConvertPIntToPrimitiveNodeGen.create()); @@ -383,7 +384,7 @@ long doGeneric(Object n, try { return asPrimitiveNode.executeLongCached(n, 0, Long.BYTES); } catch (UnexpectedResultException e) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "C long"); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "C long"); } } catch (PException e) { ensureTransformExcNode().executeCached(e); @@ -402,10 +403,10 @@ private TransformExceptionToNativeNode ensureTransformExcNode() { @CApiBuiltin(ret = Int, args = {PyLongObject, UNSIGNED_CHAR_PTR, SIZE_T, Int, Int}, call = Direct) abstract static class _PyLong_AsByteArray extends CApi5BuiltinNode { - private static void checkSign(Node inliningTarget, boolean negative, int isSigned, PRaiseNode.Lazy raiseNode) { + private static void checkSign(Node inliningTarget, boolean negative, int isSigned, PRaiseNode raiseNode) { if (negative) { if (isSigned == 0) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.MESSAGE_CONVERT_NEGATIVE); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.MESSAGE_CONVERT_NEGATIVE); } } } @@ -415,7 +416,7 @@ static Object get(int value, Object bytes, long n, int littleEndian, int isSigne @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile profile, @Shared @Cached CStructAccess.WriteByteNode write, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { checkSign(inliningTarget, value < 0, isSigned, raiseNode); byte[] array = IntBuiltins.ToBytesNode.fromLong(value, PythonUtils.toIntError(n), littleEndian == 0, isSigned != 0, inliningTarget, profile, raiseNode); write.writeByteArray(bytes, array); @@ -427,7 +428,7 @@ static Object get(long value, Object bytes, long n, int littleEndian, int isSign @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile profile, @Shared @Cached CStructAccess.WriteByteNode write, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { checkSign(inliningTarget, value < 0, isSigned, raiseNode); byte[] array = IntBuiltins.ToBytesNode.fromLong(value, PythonUtils.toIntError(n), littleEndian == 0, isSigned != 0, inliningTarget, profile, raiseNode); write.writeByteArray(bytes, array); @@ -439,7 +440,7 @@ static Object get(PInt value, Object bytes, long n, int littleEndian, int isSign @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile profile, @Shared @Cached CStructAccess.WriteByteNode write, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { checkSign(inliningTarget, value.isNegative(), isSigned, raiseNode); byte[] array = IntBuiltins.ToBytesNode.fromBigInteger(value, PythonUtils.toIntError(n), littleEndian == 0, isSigned != 0, inliningTarget, profile, raiseNode); write.writeByteArray(bytes, array); @@ -464,9 +465,9 @@ static Object convert(Object charPtr, long size, int littleEndian, int signed, @Bind("this") Node inliningTarget, @Cached CStructAccess.ReadByteNode readByteNode, @Cached IntNodes.PyLongFromByteArray fromByteArray, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (size != (int) size) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.BYTE_ARRAY_TOO_LONG_TO_CONVERT_TO_INT); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.BYTE_ARRAY_TOO_LONG_TO_CONVERT_TO_INT); } byte[] bytes = readByteNode.readByteArray(charPtr, (int) size); return fromByteArray.execute(inliningTarget, bytes, littleEndian != 0, signed != 0); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextMemoryViewBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextMemoryViewBuiltins.java index a2c42d09ae..4a3b96e430 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextMemoryViewBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextMemoryViewBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -85,7 +85,7 @@ static Object get(Object obj, int buffertype, byte orderByte, @Cached ContiguousNode contiguousNode, @Cached TruffleString.EqualNode eqNode, @Cached TruffleString.FromCodePointNode fromCodePointNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { assert buffertype == PY_BUF_READ || buffertype == PY_BUF_WRITE; char order = (char) orderByte; assert order == 'C' || order == 'F' || order == 'A'; @@ -94,14 +94,14 @@ static Object get(Object obj, int buffertype, byte orderByte, boolean release = true; try { if (buffertype == PY_BUF_WRITE && mv.isReadOnly()) { - throw raiseNode.get(inliningTarget).raise(BufferError, UNDERLYING_BUFFER_IS_NOT_WRITABLE); + throw raiseNode.raise(inliningTarget, BufferError, UNDERLYING_BUFFER_IS_NOT_WRITABLE); } if ((boolean) contiguousNode.execute(null, mv)) { release = false; return mv; } if (buffertype == PY_BUF_WRITE) { - throw raiseNode.get(inliningTarget).raise(BufferError, WRITABLE_CONTIGUES_FOR_NON_CONTIGUOUS); + throw raiseNode.raise(inliningTarget, BufferError, WRITABLE_CONTIGUES_FOR_NON_CONTIGUOUS); } PMemoryView mvBytes = memoryViewFromObject.execute(null, toBytesNode.execute(null, mv, fromCodePointNode.execute(order, TS_ENCODING, true))); if (eqNode.execute(T_UINT_8_TYPE_CODE, mv.getFormatString(), TS_ENCODING)) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextMethodBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextMethodBuiltins.java index 5529b70771..3860972a83 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextMethodBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextMethodBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -52,6 +52,7 @@ import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___MODULE__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApi9BuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; import com.oracle.graal.python.builtins.objects.PNone; @@ -60,7 +61,7 @@ import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; @@ -90,7 +91,7 @@ final Object execute(Node inliningTarget, Object methodDefPtr, TruffleString nam @Specialization static Object doNativeCallable(Node inliningTarget, Object methodDefPtr, TruffleString name, Object methObj, Object flags, int wrapper, Object self, Object module, Object cls, Object doc, - @Cached(inline = false) PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached CreateFunctionNode createFunctionNode, @Cached HiddenAttr.WriteNode writeHiddenAttrNode, @Cached(inline = false) WriteAttributeToPythonObjectNode writeAttrNode) { @@ -102,9 +103,9 @@ static Object doNativeCallable(Node inliningTarget, Object methodDefPtr, Truffle writeAttrNode.execute(func, T___DOC__, doc); PBuiltinMethod method; if (cls != PNone.NO_VALUE) { - method = factory.createBuiltinMethod(self, func, cls); + method = PFactory.createBuiltinMethod(language, self, func, cls); } else { - method = factory.createBuiltinMethod(self, func); + method = PFactory.createBuiltinMethod(language, self, func); } writeAttrNode.execute(method, T___MODULE__, module); return method; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextModuleBuiltins.java index 7f59cc181f..32091dfcb4 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -53,6 +53,7 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer; import static com.oracle.graal.python.nodes.ErrorMessages.S_NEEDS_S_AS_FIRST_ARG; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__; +import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___FILE__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___PACKAGE__; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; @@ -65,6 +66,7 @@ import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiTernaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiUnaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextMethodBuiltins.CFunctionNewExMethodNode; +import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.CheckPrimitiveFunctionResultNode; import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.ExternalFunctionInvokeNode; import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper; @@ -94,6 +96,7 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; +import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.interop.InteropLibrary; @@ -177,7 +180,7 @@ static Object getName(PythonModule module, Object nameAttr = read.execute(module, T___NAME__); if (!pyUnicodeCheckNode.execute(inliningTarget, nameAttr)) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, SystemError, ErrorMessages.NAMELESS_MODULE); + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, ErrorMessages.NAMELESS_MODULE); } Object promotedName = promoteBorrowedValue.execute(inliningTarget, nameAttr); if (promotedName == null) { @@ -190,7 +193,7 @@ static Object getName(PythonModule module, } static boolean isModuleSubtype(Node inliningTarget, Object obj, GetClassNode getClassNode, IsSubtypeNode isSubtypeNode) { - return isSubtypeNode.execute(null, getClassNode.execute(inliningTarget, obj), PythonBuiltinClassType.PythonModule); + return isSubtypeNode.execute(getClassNode.execute(inliningTarget, obj), PythonBuiltinClassType.PythonModule); } @CApiBuiltin(ret = Int, args = {PyObject, ConstCharPtrAsTruffleString, PyObject}, call = Direct) @@ -209,11 +212,10 @@ static Object addObject(Object m, TruffleString k, Object o, @SuppressWarnings("unused") @Specialization(guards = "!isModuleSubtype(inliningTarget, m, getClassNode, isSubtypeNode)") static Object pop(Object m, Object key, Object defaultValue, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, S_NEEDS_S_AS_FIRST_ARG, "PyModule_AddObjectRef", "module"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, S_NEEDS_S_AS_FIRST_ARG, "PyModule_AddObjectRef", "module"); } } @@ -232,11 +234,10 @@ static Object addObject(Object m, TruffleString k, long o, @Specialization(guards = "!isModuleSubtype(inliningTarget, m, getClassNode, isSubtypeNode)") static Object pop(@SuppressWarnings("unused") Object m, @SuppressWarnings("unused") Object key, @SuppressWarnings("unused") Object defaultValue, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, S_NEEDS_S_AS_FIRST_ARG, "PyModule_AddIntConstant", "module"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, S_NEEDS_S_AS_FIRST_ARG, "PyModule_AddIntConstant", "module"); } } @@ -299,4 +300,26 @@ static int doGeneric(PythonModule self, Object visitFun, Object arg, return 0; } } + + @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject}, call = Direct) + abstract static class PyModule_GetFilenameObject extends CApiUnaryBuiltinNode { + @Specialization + static Object getFilename(PythonModule module, + @Bind Node inliningTarget, + @Cached ReadAttributeFromObjectNode read, + @Cached PyUnicodeCheckNode check, + @Cached PRaiseNode raiseNode) { + Object file = read.execute(module, T___FILE__); + if (file != PNone.NO_VALUE && check.execute(inliningTarget, file)) { + return file; + } + throw raiseNode.raise(inliningTarget, SystemError, ErrorMessages.MODULE_FILENAME_MISSING); + } + + @Fallback + static Object error(@SuppressWarnings("unused") Object module, + @Bind Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC); + } + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextNamespaceBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextNamespaceBuiltins.java index 85cb7bd4f3..3973656710 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextNamespaceBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextNamespaceBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,6 +45,7 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer; import static com.oracle.graal.python.nodes.truffle.TruffleStringMigrationHelpers.assertNoJavaString; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiUnaryBuiltinNode; import com.oracle.graal.python.builtins.objects.common.HashingStorage; @@ -57,7 +58,7 @@ import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.namespace.PSimpleNamespace; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -77,16 +78,15 @@ static Object impDict(PDict dict, @Shared("itNext") @Cached HashingStorageIteratorNext itNext, @Shared("itKey") @Cached HashingStorageIteratorKey itKey, @Shared("itVal") @Cached HashingStorageIteratorValue itValue, - @Shared("dylib") @CachedLibrary(limit = "1") DynamicObjectLibrary dyLib, - @Shared @Cached PythonObjectFactory factory) { + @Shared("dylib") @CachedLibrary(limit = "1") DynamicObjectLibrary dyLib) { HashingStorage storage = dict.getDictStorage(); - return impl(inliningTarget, storage, getIterator, itNext, itKey, itValue, dyLib, factory); + return impl(inliningTarget, storage, getIterator, itNext, itKey, itValue, dyLib); } private static Object impl(Node inliningTarget, HashingStorage storage, HashingStorageGetIterator getIterator, HashingStorageIteratorNext itNext, HashingStorageIteratorKey itKey, HashingStorageIteratorValue itValue, - DynamicObjectLibrary dyLib, PythonObjectFactory factory) { - PSimpleNamespace ns = factory.createSimpleNamespace(); + DynamicObjectLibrary dyLib) { + PSimpleNamespace ns = PFactory.createSimpleNamespace(PythonLanguage.get(inliningTarget)); HashingStorageNodes.HashingStorageIterator it = getIterator.execute(inliningTarget, storage); while (itNext.execute(inliningTarget, storage, it)) { Object key = itKey.execute(inliningTarget, storage, it); @@ -104,10 +104,9 @@ static Object impGeneric(Object dict, @Shared("itNext") @Cached HashingStorageIteratorNext itNext, @Shared("itKey") @Cached HashingStorageIteratorKey itKey, @Shared("itVal") @Cached HashingStorageIteratorValue itValue, - @Shared("dylib") @CachedLibrary(limit = "1") DynamicObjectLibrary dyLib, - @Shared @Cached PythonObjectFactory factory) { + @Shared("dylib") @CachedLibrary(limit = "1") DynamicObjectLibrary dyLib) { HashingStorage hs = initNode.execute(null, dict, PKeyword.EMPTY_KEYWORDS); - return impl(inliningTarget, hs, getIterator, itNext, itKey, itValue, dyLib, factory); + return impl(inliningTarget, hs, getIterator, itNext, itKey, itValue, dyLib); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextObjectBuiltins.java index c1e8add19d..63e79683bd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextObjectBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextObjectBuiltins.java @@ -41,6 +41,7 @@ package com.oracle.graal.python.builtins.modules.cext; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.NotImplementedError; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Direct; import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Ignored; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.ConstCharPtrAsTruffleString; @@ -48,6 +49,7 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Pointer; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObject; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectConstPtr; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectRawPointer; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectWrapper; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyThreadState; @@ -64,8 +66,8 @@ import java.io.PrintWriter; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.BytesNode; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.FormatNode; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.IsInstanceNode; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.IsSubClassNode; @@ -78,11 +80,11 @@ import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiUnaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CastArgsNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CastKwargsNode; -import com.oracle.graal.python.builtins.modules.cext.PythonCextBytesBuiltins.PyBytes_FromObject; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; import com.oracle.graal.python.builtins.objects.bytes.BytesUtils; -import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; +import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.cext.capi.CApiGuards; import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.ResolvePointerNode; import com.oracle.graal.python.builtins.objects.cext.capi.PythonNativeWrapper; @@ -104,6 +106,7 @@ import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins.SetattrNode; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.lib.PyBytesCheckNode; import com.oracle.graal.python.lib.PyCallableCheckNode; import com.oracle.graal.python.lib.PyLongCheckNode; import com.oracle.graal.python.lib.PyObjectAsFileDescriptor; @@ -115,7 +118,6 @@ import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyObjectHashNode; import com.oracle.graal.python.lib.PyObjectIsTrueNode; -import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectLookupAttrO; import com.oracle.graal.python.lib.PyObjectReprAsObjectNode; import com.oracle.graal.python.lib.PyObjectSetItem; @@ -126,16 +128,18 @@ import com.oracle.graal.python.nodes.StringLiterals; import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode; import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.classes.IsSubtypeNode; +import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; +import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; +import com.oracle.graal.python.nodes.object.IsNode; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaStringNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.PosixSupportLibrary; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.graal.python.runtime.sequence.storage.ArrayBasedSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.EmptySequenceStorage; @@ -146,13 +150,14 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; +import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleString; public abstract class PythonCextObjectBuiltins { @@ -432,7 +437,7 @@ static Object asFileDescriptor(Object obj, @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, @Cached TruffleString.EqualNode eqNode, @Cached PyObjectAsFileDescriptor asFileDescriptorNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (!longCheckNode.execute(inliningTarget, obj)) { Object posixSupport = PythonContext.get(inliningTarget).getPosixSupport(); if (eqNode.execute(T_JAVA, posixLib.getBackend(posixSupport), TS_ENCODING)) { @@ -440,7 +445,7 @@ static Object asFileDescriptor(Object obj, * For non Python 'int' objects, we refuse to hand out the fileno field when * using the emulated Posix backend, because it is likely a fake. */ - throw raiseNode.get(inliningTarget).raise(NotImplementedError, ErrorMessages.S_NOT_SUPPORTED_ON_JAVA_POSIX_BACKEND, "PyObject_AsFileDescriptor"); + throw raiseNode.raise(inliningTarget, NotImplementedError, ErrorMessages.S_NOT_SUPPORTED_ON_JAVA_POSIX_BACKEND, "PyObject_AsFileDescriptor"); } } return asFileDescriptorNode.execute(null, inliningTarget, obj); @@ -487,8 +492,8 @@ static int hasAttr(Object obj, Object attr, abstract static class PyObject_HashNotImplemented extends CApiUnaryBuiltinNode { @Specialization static Object unhashable(Object obj, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, UNHASHABLE_TYPE_P, obj); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, UNHASHABLE_TYPE_P, obj); } } @@ -503,55 +508,42 @@ static int isTrue(Object obj, @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject}, call = Direct) abstract static class PyObject_Bytes extends CApiUnaryBuiltinNode { - @Specialization - static Object bytes(PBytesLike bytes) { + @Specialization(guards = "isBuiltinBytes(bytes)") + static Object bytes(PBytes bytes) { return bytes; } - @Specialization(guards = {"!isBytes(bytes)", "isBytesSubtype(inliningTarget, bytes, getClassNode, isSubtypeNode)"}, limit = "1") - static Object bytes(Object bytes, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached GetClassNode getClassNode, - @SuppressWarnings("unused") @Exclusive @Cached IsSubtypeNode isSubtypeNode) { - return bytes; - } - - @Specialization(guards = {"!isBytes(obj)", "!isBytesSubtype(this, obj, getClassNode, isSubtypeNode)", "!isNoValue(obj)", "hasBytes(inliningTarget, obj, lookupAttrNode)"}, limit = "1") - static Object bytes(Object obj, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached GetClassNode getClassNode, - @SuppressWarnings("unused") @Exclusive @Cached IsSubtypeNode isSubtypeNode, - @SuppressWarnings("unused") @Exclusive @Cached PyObjectLookupAttr lookupAttrNode, - @Cached BytesNode bytesNode) { - return bytesNode.execute(null, PythonBuiltinClassType.PBytes, obj, PNone.NO_VALUE, PNone.NO_VALUE); - } - - @Specialization(guards = {"!isBytes(obj)", "!isBytesSubtype(this, obj, getClassNode, isSubtypeNode)", "!isNoValue(obj)", "!hasBytes(inliningTarget, obj, lookupAttrNode)"}, limit = "1") - static Object bytes(Object obj, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached GetClassNode getClassNode, - @SuppressWarnings("unused") @Exclusive @Cached IsSubtypeNode isSubtypeNode, - @SuppressWarnings("unused") @Exclusive @Cached PyObjectLookupAttr lookupAttrNode, - @Cached PyBytes_FromObject fromObjectNode) { - return fromObjectNode.execute(obj); - } - @Specialization(guards = "isNoValue(obj)") static Object bytesNoValue(@SuppressWarnings("unused") Object obj, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { /* * Note: CPython calls PyBytes_FromString("") but we do not directly have it. * Therefore, we directly create the bytes object with string "" here. */ - return factory.createBytes(BytesUtils.NULL_STRING); + return PFactory.createBytes(language, BytesUtils.NULL_STRING); } - protected static boolean hasBytes(Node inliningTarget, Object obj, PyObjectLookupAttr lookupAttrNode) { - return lookupAttrNode.execute(null, inliningTarget, obj, T___BYTES__) != PNone.NO_VALUE; - } - - protected static boolean isBytesSubtype(Node inliningTarget, Object obj, GetClassNode getClassNode, IsSubtypeNode isSubtypeNode) { - return isSubtypeNode.execute(getClassNode.execute(inliningTarget, obj), PythonBuiltinClassType.PBytes); + @Fallback + static Object doGeneric(Object obj, + @Bind("this") Node inliningTarget, + @Cached GetClassNode getClassNode, + @Cached InlinedConditionProfile hasBytes, + @Cached("create(T___BYTES__)") LookupSpecialMethodNode lookupBytes, + @Cached CallUnaryMethodNode callBytes, + @Cached PyBytesCheckNode check, + @Cached BytesNodes.BytesFromObject fromObject, + @Cached PRaiseNode raiseNode) { + Object bytesMethod = lookupBytes.execute(null, getClassNode.execute(inliningTarget, obj), obj); + if (hasBytes.profile(inliningTarget, bytesMethod != PNone.NO_VALUE)) { + Object bytes = callBytes.executeObject(null, bytesMethod, obj); + if (check.execute(inliningTarget, bytes)) { + return bytes; + } else { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.RETURNED_NONBYTES, T___BYTES__, bytes); + } + } + byte[] bytes = fromObject.execute(null, obj); + return PFactory.createBytes(PythonLanguage.get(inliningTarget), bytes); } } @@ -606,8 +598,17 @@ static PNone set(PSequence obj, long size, } } - @CApiBuiltin(ret = Void, args = {PyObjectWrapper}, call = Direct) - abstract static class _PyObject_Dump extends CApiUnaryBuiltinNode { + @CApiBuiltin(ret = Int, args = {PyObjectRawPointer}, call = Ignored) + abstract static class _PyTruffleObject_IsFreed extends CApiUnaryBuiltinNode { + @Specialization + int doGeneric(Object pointer, + @Cached ToPythonWrapperNode toPythonWrapperNode) { + return toPythonWrapperNode.executeWrapper(pointer, false) == null ? 1 : 0; + } + } + + @CApiBuiltin(ret = Void, args = {PyObjectWrapper}, call = Ignored) + abstract static class _PyTruffleObject_Dump extends CApiUnaryBuiltinNode { @Specialization @TruffleBoundary @@ -738,4 +739,13 @@ static Object getDict(Object object, return getDict.execute(inliningTarget, object); } } + + @CApiBuiltin(ret = Int, args = {PyObject, PyObject}, call = Ignored) + abstract static class PyTruffle_Is extends CApiBinaryBuiltinNode { + @Specialization + static int isTrue(Object a, Object b, + @Cached IsNode isNode) { + return isNode.execute(a, b) ? 1 : 0; + } + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPickleBufferBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPickleBufferBuiltins.java index 34e56c14f5..e3e6b1731e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPickleBufferBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPickleBufferBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -65,13 +65,13 @@ abstract static class PyTruffle_PickleBuffer_viewobj extends CApiUnaryBuiltinNod static Object getviewobj(PPickleBuffer object, @Bind("this") Node inliningTarget, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object owner = null; if (object.getView() != null) { owner = bufferLib.getOwner(object.getView()); } if (owner == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.OP_FORBIDDEN_ON_OBJECT, "PickleBuffer"); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.OP_FORBIDDEN_ON_OBJECT, "PickleBuffer"); } return owner; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPyStateBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPyStateBuiltins.java index 3993c3c00d..36a161c79b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPyStateBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPyStateBuiltins.java @@ -72,7 +72,7 @@ import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.OverflowException; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.ThreadLocalAction; @@ -150,12 +150,11 @@ abstract static class PyThreadState_GetDict extends CApiNullaryBuiltinNode { @TruffleBoundary static PDict get( @Bind("this") Node inliningTarget, - @Bind PythonContext context, - @Cached PythonObjectFactory factory) { + @Bind PythonContext context) { PythonThreadState threadState = context.getThreadState(context.getLanguage(inliningTarget)); PDict threadStateDict = threadState.getDict(); if (threadStateDict == null) { - threadStateDict = factory.createDict(); + threadStateDict = PFactory.createDict(context.getLanguage()); threadState.setDict(threadStateDict); } return threadStateDict; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPyThreadBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPyThreadBuiltins.java index df9a34215a..1c813ea024 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPyThreadBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPyThreadBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -49,7 +49,7 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Void; import static com.oracle.graal.python.builtins.objects.ints.PInt.intValue; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiNullaryBuiltinNode; @@ -58,7 +58,7 @@ import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext; import com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor; import com.oracle.graal.python.builtins.objects.thread.PLock; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; @@ -77,7 +77,7 @@ abstract static class PyThread_allocate_lock extends CApiNullaryBuiltinNode { long allocate() { CApiContext context = getCApiContext(); long id = context.lockId.incrementAndGet() ^ LOCK_MASK; - PLock lock = PythonObjectFactory.getUncached().createLock(PythonBuiltinClassType.PLock); + PLock lock = PFactory.createLock(PythonLanguage.get(null)); context.locks.put(id, lock); return id; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPythonRunBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPythonRunBuiltins.java index df7d577fd7..69a83f53f5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPythonRunBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPythonRunBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -69,7 +69,6 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -89,7 +88,7 @@ static Object run(Object source, int type, Object globals, Object locals, @Suppr @SuppressWarnings("unused") @Exclusive @Cached PyMappingCheckNode isMapping, @Cached PyObjectLookupAttr lookupNode, @Cached CallNode callNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { PythonModule builtins = PythonContext.get(inliningTarget).getBuiltins(); Object compileCallable = lookupNode.execute(null, inliningTarget, builtins, T_COMPILE); TruffleString stype; @@ -100,7 +99,7 @@ static Object run(Object source, int type, Object globals, Object locals, @Suppr } else if (type == Py_eval_input) { stype = StringLiterals.T_EVAL; } else { - throw raiseNode.get(inliningTarget).raise(SystemError, BAD_ARG_TO_INTERNAL_FUNC); + throw raiseNode.raise(inliningTarget, SystemError, BAD_ARG_TO_INTERNAL_FUNC); } Object code = callNode.executeWithoutFrame(compileCallable, source, stype, stype); Object execCallable = lookupNode.execute(null, inliningTarget, builtins, type == Py_eval_input ? T_EVAL : T_EXEC); @@ -110,17 +109,16 @@ static Object run(Object source, int type, Object globals, Object locals, @Suppr @Specialization(guards = "!isString(source) || !isDict(globals)") static Object run(@SuppressWarnings("unused") Object source, @SuppressWarnings("unused") int type, @SuppressWarnings("unused") Object globals, @SuppressWarnings("unused") Object locals, @SuppressWarnings("unused") Object flags, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, BAD_ARG_TO_INTERNAL_FUNC); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, BAD_ARG_TO_INTERNAL_FUNC); } @Specialization(guards = {"isString(source)", "isDict(globals)", "!isMapping.execute(inliningTarget, locals)"}, limit = "1") static Object run(@SuppressWarnings("unused") Object source, @SuppressWarnings("unused") int type, @SuppressWarnings("unused") Object globals, Object locals, @SuppressWarnings("unused") Object flags, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached PyMappingCheckNode isMapping, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, P_OBJ_DOES_NOT_SUPPORT_ITEM_ASSIGMENT, locals); + @Bind("this") Node inliningTarget, + @SuppressWarnings("unused") @Exclusive @Cached PyMappingCheckNode isMapping) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, P_OBJ_DOES_NOT_SUPPORT_ITEM_ASSIGMENT, locals); } protected static boolean checkArgs(Object source, Object globals, Object locals, Node inliningTarget, PyMappingCheckNode isMapping) { @@ -133,7 +131,7 @@ abstract static class Py_CompileString extends CApiTernaryBuiltinNode { @Specialization(guards = {"isString(source)", "isString(filename)"}) static Object compile(Object source, Object filename, int type, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached PyObjectLookupAttr lookupNode, @Cached CallNode callNode) { return Py_CompileStringExFlags.compile(source, filename, type, null, -1, inliningTarget, raiseNode, lookupNode, callNode); @@ -142,8 +140,8 @@ static Object compile(Object source, Object filename, int type, @SuppressWarnings("unused") @Specialization(guards = "!isString(source) || !isString(filename)") static Object fail(Object source, Object filename, Object type, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, BAD_ARG_TO_INTERNAL_FUNC); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, BAD_ARG_TO_INTERNAL_FUNC); } } @@ -153,7 +151,7 @@ abstract static class Py_CompileStringExFlags extends CApi5BuiltinNode { static Object compile(Object source, Object filename, int type, @SuppressWarnings("unused") Object flags, int optimizationLevel, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached PyObjectLookupAttr lookupNode, @Cached CallNode callNode) { PythonModule builtins = PythonContext.get(lookupNode).getCore().getBuiltins(); @@ -166,7 +164,7 @@ static Object compile(Object source, Object filename, int type, } else if (type == Py_eval_input) { stype = StringLiterals.T_EVAL; } else { - throw raiseNode.get(inliningTarget).raise(SystemError, BAD_ARG_TO_INTERNAL_FUNC); + throw raiseNode.raise(inliningTarget, SystemError, BAD_ARG_TO_INTERNAL_FUNC); } int defaultFlags = 0; boolean dontInherit = false; @@ -176,8 +174,8 @@ static Object compile(Object source, Object filename, int type, @SuppressWarnings("unused") @Specialization(guards = "!isString(source) || !isString(filename)") static Object fail(Object source, Object filename, Object type, Object flags, Object optimizationLevel, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, BAD_ARG_TO_INTERNAL_FUNC); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, BAD_ARG_TO_INTERNAL_FUNC); } } @@ -188,7 +186,7 @@ static Object compile(Object source, Object filename, int type, @SuppressWarnings("unused") Object flags, int optimizationLevel, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached PyObjectLookupAttr lookupNode, @Cached CallNode callNode) { return Py_CompileStringExFlags.compile(source, filename, type, null, optimizationLevel, inliningTarget, raiseNode, lookupNode, callNode); @@ -197,8 +195,8 @@ static Object compile(Object source, Object filename, int type, @SuppressWarnings("unused") @Specialization(guards = "!isString(source)") static Object fail(Object source, Object filename, Object type, Object flags, Object optimizationLevel, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, BAD_ARG_TO_INTERNAL_FUNC); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, BAD_ARG_TO_INTERNAL_FUNC); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextSetBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextSetBuiltins.java index 6b9cc18e71..52629d244d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextSetBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextSetBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -51,9 +51,8 @@ import static com.oracle.graal.python.nodes.ErrorMessages.EXPECTED_S_NOT_P; import static com.oracle.graal.python.nodes.ErrorMessages.NATIVE_S_SUBTYPES_NOT_IMPLEMENTED; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.FrozenSetNode; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.StrNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiUnaryBuiltinNode; @@ -68,24 +67,24 @@ import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageIteratorNext; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageLen; import com.oracle.graal.python.builtins.objects.ints.PInt; +import com.oracle.graal.python.builtins.objects.set.FrozenSetBuiltins.FrozenSetNode; import com.oracle.graal.python.builtins.objects.set.PBaseSet; import com.oracle.graal.python.builtins.objects.set.PFrozenSet; import com.oracle.graal.python.builtins.objects.set.PSet; import com.oracle.graal.python.builtins.objects.set.SetBuiltins.ClearNode; import com.oracle.graal.python.builtins.objects.set.SetNodes.ConstructSetNode; import com.oracle.graal.python.builtins.objects.set.SetNodes.DiscardNode; +import com.oracle.graal.python.builtins.objects.str.StringBuiltins; import com.oracle.graal.python.lib.PyObjectSizeNode; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.truffle.PythonTypes; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile; @@ -96,13 +95,13 @@ abstract static class PySet_New extends CApiUnaryBuiltinNode { @Specialization(guards = {"!isNone(iterable)", "!isNoValue(iterable)"}) static Object newSet(Object iterable, @Cached ConstructSetNode constructSetNode) { - return constructSetNode.executeWith(null, iterable); + return constructSetNode.execute(null, iterable); } @Specialization static Object newSet(@SuppressWarnings("unused") PNone iterable, - @Cached PythonObjectFactory factory) { - return factory.createSet(); + @Bind PythonLanguage language) { + return PFactory.createSet(language); } } @@ -133,7 +132,6 @@ int fallback(@SuppressWarnings("unused") Object anyset, @SuppressWarnings("unuse } @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, Py_ssize_t}, call = Ignored) - @TypeSystemReference(PythonTypes.class) abstract static class _PyTruffleSet_NextEntry extends CApiBinaryBuiltinNode { @Specialization(guards = "pos < size(inliningTarget, set, sizeNode)") static Object nextEntry(PSet set, long pos, @@ -143,9 +141,8 @@ static Object nextEntry(PSet set, long pos, @Shared @Cached HashingStorageIteratorNext itNext, @Shared @Cached HashingStorageIteratorKey itKey, @Shared @Cached HashingStorageIteratorKeyHash itKeyHash, - @Shared @Cached InlinedLoopConditionProfile loopProfile, - @Shared @Cached PythonObjectFactory.Lazy factory) { - return next(inliningTarget, (int) pos, set.getDictStorage(), getIterator, itNext, itKey, itKeyHash, loopProfile, factory); + @Shared @Cached InlinedLoopConditionProfile loopProfile) { + return next(inliningTarget, (int) pos, set.getDictStorage(), getIterator, itNext, itKey, itKeyHash, loopProfile); } @Specialization(guards = "pos < size(inliningTarget, set, sizeNode)") @@ -156,9 +153,8 @@ static Object nextEntry(PFrozenSet set, long pos, @Shared @Cached HashingStorageIteratorNext itNext, @Shared @Cached HashingStorageIteratorKey itKey, @Shared @Cached HashingStorageIteratorKeyHash itKeyHash, - @Shared @Cached InlinedLoopConditionProfile loopProfile, - @Shared @Cached PythonObjectFactory.Lazy factory) { - return next(inliningTarget, (int) pos, set.getDictStorage(), getIterator, itNext, itKey, itKeyHash, loopProfile, factory); + @Shared @Cached InlinedLoopConditionProfile loopProfile) { + return next(inliningTarget, (int) pos, set.getDictStorage(), getIterator, itNext, itKey, itKeyHash, loopProfile); } @Specialization(guards = {"isPSet(set) || isPFrozenSet(set)", "pos >= size(inliningTarget, set, sizeNode)"}) @@ -170,21 +166,19 @@ static Object nextEntry(@SuppressWarnings("unused") Object set, @SuppressWarning @Specialization(guards = {"!isPSet(anyset)", "!isPFrozenSet(anyset)", "isSetSubtype(inliningTarget, anyset, getClassNode, isSubtypeNode)"}) static Object nextNative(@SuppressWarnings("unused") Object anyset, @SuppressWarnings("unused") Object pos, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.NotImplementedError, NATIVE_S_SUBTYPES_NOT_IMPLEMENTED, "set"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.NotImplementedError, NATIVE_S_SUBTYPES_NOT_IMPLEMENTED, "set"); } @Specialization(guards = {"!isPSet(anyset)", "!isPFrozenSet(anyset)", "!isSetSubtype(inliningTarget, anyset, getClassNode, isSubtypeNode)"}) static Object nextEntry(Object anyset, @SuppressWarnings("unused") Object pos, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Cached StrNode strNode, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, BAD_ARG_TO_INTERNAL_FUNC_WAS_S_P, strNode.executeWith(anyset), anyset); + @Cached StringBuiltins.StrNewNode strNode, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, BAD_ARG_TO_INTERNAL_FUNC_WAS_S_P, strNode.executeWith(anyset), anyset); } protected boolean isSetSubtype(Node inliningTarget, Object obj, GetClassNode getClassNode, IsSubtypeNode isSubtypeNode) { @@ -198,7 +192,7 @@ protected int size(Node inliningTarget, Object set, PyObjectSizeNode sizeNode) { private static Object next(Node inliningTarget, int pos, HashingStorage storage, HashingStorageGetIterator getIterator, HashingStorageIteratorNext itNext, HashingStorageIteratorKey itKey, HashingStorageIteratorKeyHash itKeyHash, - InlinedLoopConditionProfile loopProfile, PythonObjectFactory.Lazy factory) { + InlinedLoopConditionProfile loopProfile) { HashingStorageIterator it = getIterator.execute(inliningTarget, storage); loopProfile.profileCounted(inliningTarget, pos); for (int i = 0; loopProfile.inject(inliningTarget, i <= pos); i++) { @@ -208,7 +202,7 @@ private static Object next(Node inliningTarget, int pos, HashingStorage storage, } Object key = itKey.execute(inliningTarget, storage, it); long hash = itKeyHash.execute(null, inliningTarget, storage, it); - return factory.get(inliningTarget).createTuple(new Object[]{key, hash}); + return PFactory.createTuple(PythonLanguage.get(inliningTarget), new Object[]{key, hash}); } } @@ -237,8 +231,8 @@ static Object newFrozenSet(Object iterable, @SuppressWarnings("unused") @Specialization static Object newFrozenSet(PNone iterable, - @Cached PythonObjectFactory factory) { - return factory.createFrozenSet(PythonBuiltinClassType.PFrozenSet); + @Bind PythonLanguage language) { + return PFactory.createFrozenSet(language); } } @@ -286,8 +280,8 @@ static int add(PBaseSet self, Object o, @Specialization(guards = "!isAnySet(self)") static int add(Object self, @SuppressWarnings("unused") Object o, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, EXPECTED_S_NOT_P, "a set object", self); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, EXPECTED_S_NOT_P, "a set object", self); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextStructSeqBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextStructSeqBuiltins.java index 3e8a392940..b71081e15b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextStructSeqBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextStructSeqBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -67,7 +67,9 @@ import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.tuple.StructSequence; +import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; import com.oracle.graal.python.builtins.objects.type.PythonClass; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.nodes.BuiltinNames; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; @@ -76,7 +78,9 @@ import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -95,7 +99,7 @@ abstract static class PyTruffleStructSequence_InitType2 extends CApiTernaryBuilt @Specialization @TruffleBoundary - static int doGeneric(Object klass, Object fields, int nInSequence, + static int doGeneric(PythonAbstractClass klass, Object fields, int nInSequence, @CachedLibrary(limit = "3") InteropLibrary lib, @Cached CStructAccess.ReadPointerNode readNode, @Cached FromCharPointerNode fromCharPtr) { @@ -120,8 +124,8 @@ static int doGeneric(Object klass, Object fields, int nInSequence, TruffleString[] fieldNames = names.toArray(TruffleString[]::new); TruffleString[] fieldDocs = docs.toArray(TruffleString[]::new); - StructSequence.Descriptor d = new StructSequence.Descriptor(null, nInSequence, fieldNames, fieldDocs); - StructSequence.initType(PythonLanguage.get(readNode), klass, d); + StructSequence.Descriptor d = new StructSequence.Descriptor(nInSequence, fieldNames, fieldDocs); + StructSequence.initType(PythonContext.get(readNode), klass, d); return 0; } } @@ -136,10 +140,10 @@ Object doGeneric(TruffleString typeName, TruffleString typeDoc, Object fields, i @Cached ReadAttributeFromObjectNode readTypeBuiltinNode, @CachedLibrary(limit = "1") DynamicObjectLibrary dylib, @Cached CallNode callTypeNewNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { Object typeBuiltin = readTypeBuiltinNode.execute(getCore().getBuiltins(), BuiltinNames.T_TYPE); - PTuple bases = factory.createTuple(new Object[]{PythonBuiltinClassType.PTuple}); - PDict namespace = factory.createDict(new PKeyword[]{new PKeyword(SpecialAttributeNames.T___DOC__, typeDoc)}); + PTuple bases = PFactory.createTuple(language, new Object[]{PythonBuiltinClassType.PTuple}); + PDict namespace = PFactory.createDict(language, new PKeyword[]{new PKeyword(SpecialAttributeNames.T___DOC__, typeDoc)}); Object cls = callTypeNewNode.executeWithoutFrame(typeBuiltin, typeName, bases, namespace); initNode.execute(cls, fields, nInSequence); if (cls instanceof PythonClass) { @@ -157,17 +161,18 @@ static Object doGeneric(Object cls, @Bind("this") Node inliningTarget, @Cached("createForceType()") ReadAttributeFromObjectNode readRealSizeNode, @Cached CastToJavaIntExactNode castToIntNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached PRaiseNode raiseNode) { try { Object realSizeObj = readRealSizeNode.execute(cls, StructSequence.T_N_FIELDS); if (realSizeObj == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC, EMPTY_OBJECT_ARRAY); + throw raiseNode.raise(inliningTarget, SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC, EMPTY_OBJECT_ARRAY); } else { int realSize = castToIntNode.execute(inliningTarget, realSizeObj); Object[] values = new Object[realSize]; Arrays.fill(values, PNone.NO_VALUE); // Initialize to C NULL - return factory.createTuple(cls, values); + return PFactory.createTuple(language, cls, getInstanceShape.execute(cls), new ObjectSequenceStorage(values)); } } catch (CannotCastException e) { throw CompilerDirectives.shouldNotReachHere("attribute 'n_fields' is expected to be a Java int"); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTracebackBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTracebackBuiltins.java index ada7ed0b0c..556612a663 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTracebackBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTracebackBuiltins.java @@ -46,6 +46,7 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyFrameObject; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Void; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiTernaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiUnaryBuiltinNode; @@ -56,7 +57,7 @@ import com.oracle.graal.python.builtins.objects.traceback.MaterializeLazyTracebackNode; import com.oracle.graal.python.builtins.objects.traceback.PTraceback; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; @@ -72,8 +73,8 @@ abstract static class _PyTraceback_Add extends CApiTernaryBuiltinNode { static Object tbHere(TruffleString funcname, TruffleString filename, int lineno, @Cached PyCode_NewEmpty newCode, @Cached PyTraceBack_Here pyTraceBackHereNode, - @Cached PythonObjectFactory factory) { - PFrame frame = factory.createPFrame(null, newCode.execute(filename, funcname, lineno), factory.createDict(), factory.createDict()); + @Bind PythonLanguage language) { + PFrame frame = PFactory.createPFrame(language, null, newCode.execute(filename, funcname, lineno), PFactory.createDict(language), PFactory.createDict(language)); pyTraceBackHereNode.execute(frame); return PNone.NONE; } @@ -85,8 +86,7 @@ abstract static class PyTraceBack_Here extends CApiUnaryBuiltinNode { static int tbHere(PFrame frame, @Bind("this") Node inliningTarget, @Bind PythonContext context, - @Cached MaterializeLazyTracebackNode materializeLazyTracebackNode, - @Cached PythonObjectFactory factory) { + @Cached MaterializeLazyTracebackNode materializeLazyTracebackNode) { PythonContext.PythonThreadState threadState = context.getThreadState(context.getLanguage(inliningTarget)); AbstractTruffleException currentException = threadState.getCurrentException(); if (currentException != null) { @@ -94,7 +94,7 @@ static int tbHere(PFrame frame, if (threadState.getCurrentTraceback() != null) { currentTraceback = materializeLazyTracebackNode.execute(inliningTarget, threadState.getCurrentTraceback()); } - PTraceback newTraceback = factory.createTraceback(frame, frame.getLine(), currentTraceback); + PTraceback newTraceback = PFactory.createTraceback(PythonLanguage.get(inliningTarget), frame, frame.getLine(), currentTraceback); threadState.setCurrentTraceback(new LazyTraceback(newTraceback)); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTupleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTupleBuiltins.java index b1ae9aa248..54e78caeaf 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTupleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTupleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,9 +45,11 @@ import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Ignored; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObject; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectBorrowed; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectPtr; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Py_ssize_t; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; @@ -58,18 +60,21 @@ import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; +import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.EnsureCapacityNode; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemNode; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemScalarNode; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ListGeneralizationNode; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.SetItemScalarNode; +import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.SetLenNode; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.lib.PySliceNew; import com.oracle.graal.python.lib.PyTupleSizeNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.builtins.TupleNodes.GetNativeTupleStorage; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.NativeObjectSequenceStorage; +import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -86,12 +91,12 @@ abstract static class PyTuple_New extends CApiUnaryBuiltinNode { @Specialization static PTuple doGeneric(long longSize, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode, + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode, @Cached CStructAccess.AllocateNode alloc) { int size = (int) longSize; if (longSize != size) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.MemoryError); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.MemoryError); } /* * Already allocate the tuple with native memory, since it has to be populated from the @@ -99,7 +104,7 @@ static PTuple doGeneric(long longSize, */ Object mem = alloc.alloc((longSize + 1) * CStructAccess.POINTER_SIZE); NativeObjectSequenceStorage storage = NativeObjectSequenceStorage.create(mem, size, size, true); - return factory.createTuple(storage); + return PFactory.createTuple(language, storage); } } @@ -115,7 +120,7 @@ static Object doPTuple(PTuple tuple, long key, @Cached ListGeneralizationNode generalizationNode, @Shared @Cached SetItemScalarNode setItemNode, @Shared @Cached GetItemScalarNode getItemNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { SequenceStorage sequenceStorage = tuple.getSequenceStorage(); int index = checkIndex(inliningTarget, key, sequenceStorage, raiseNode); Object result = getItemNode.execute(inliningTarget, sequenceStorage, index); @@ -137,7 +142,7 @@ static Object doNative(PythonAbstractNativeObject tuple, long key, @Shared("promote") @Cached PromoteBorrowedValue promoteNode, @Shared @Cached SetItemScalarNode setItemNode, @Shared @Cached GetItemScalarNode getItemNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { SequenceStorage sequenceStorage = asNativeStorage.execute(tuple); int index = checkIndex(inliningTarget, key, sequenceStorage, raiseNode); Object result = getItemNode.execute(inliningTarget, sequenceStorage, index); @@ -157,10 +162,10 @@ Object fallback(Object tuple, @SuppressWarnings("unused") Object pos) { throw raiseFallback(tuple, PythonBuiltinClassType.PTuple); } - private static int checkIndex(Node inliningTarget, long key, SequenceStorage sequenceStorage, PRaiseNode.Lazy raiseNode) { + private static int checkIndex(Node inliningTarget, long key, SequenceStorage sequenceStorage, PRaiseNode raiseNode) { // we must do a bounds-check but we must not normalize the index if (key < 0 || key >= sequenceStorage.length()) { - throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.TUPLE_OUT_OF_BOUNDS); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.TUPLE_OUT_OF_BOUNDS); } return (int) key; } @@ -205,4 +210,23 @@ private static Object doGetSlice(SequenceStorage storage, Node inliningTarget, O return getItemNode.execute(null, storage, sliceNode.execute(inliningTarget, iLow, iHigh, PNone.NONE)); } } + + @CApiBuiltin(ret = PyObjectPtr, args = {PyObject, Py_ssize_t, PyObjectPtr}, call = Ignored) + abstract static class PyTruffleTuple_Resize extends CApiTernaryBuiltinNode { + @Specialization + public static Object size(PTuple tuple, long size, Object obItemsPtr, + @Bind("this") Node inliningTarget, + @Cached EnsureCapacityNode ensureCapacityNode, + @Cached SetLenNode setLenNode) { + SequenceStorage store = tuple.getSequenceStorage(); + int newLength = (int) Math.min(size, Integer.MAX_VALUE); + ensureCapacityNode.execute(inliningTarget, store, newLength); + setLenNode.execute(inliningTarget, store, newLength); + if (store instanceof NativeSequenceStorage nativeStore) { + return nativeStore.getPtr(); + } else { + return obItemsPtr; + } + } + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java index 2d0d418396..962ed16f74 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java @@ -42,6 +42,7 @@ import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Direct; import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Ignored; +import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PYOBJECT_HASH_NOT_IMPLEMENTED; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.ConstCharPtrAsTruffleString; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Int; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Pointer; @@ -55,6 +56,7 @@ import static com.oracle.graal.python.nodes.HiddenAttr.METHOD_DEF_PTR; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__; import static com.oracle.graal.python.util.PythonUtils.EMPTY_OBJECT_ARRAY; import com.oracle.graal.python.PythonLanguage; @@ -91,7 +93,6 @@ import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyDictGetItem; @@ -103,7 +104,7 @@ import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.MroSequenceStorage; import com.oracle.graal.python.util.Function; import com.oracle.graal.python.util.PythonUtils; @@ -188,9 +189,10 @@ abstract static class PyTruffle_Compute_Mro extends CApiBinaryBuiltinNode { @Specialization @TruffleBoundary - static Object doIt(PythonNativeClass self, TruffleString className) { - PythonAbstractClass[] doSlowPath = TypeNodes.ComputeMroNode.doSlowPath(self); - return PythonObjectFactory.getUncached().createTuple(new MroSequenceStorage(className, doSlowPath)); + static Object doIt(PythonNativeClass self, TruffleString className, + @Bind("this") Node inliningTarget) { + PythonAbstractClass[] doSlowPath = TypeNodes.ComputeMroNode.doSlowPath(inliningTarget, self); + return PFactory.createTuple(PythonLanguage.get(null), new MroSequenceStorage(className, doSlowPath)); } } @@ -208,40 +210,32 @@ abstract static class PyTruffle_NewTypeDict extends CApiUnaryBuiltinNode { static PDict doGeneric(PythonNativeClass nativeClass) { PythonLanguage language = PythonLanguage.get(null); NativeTypeDictStorage nativeTypeStore = new NativeTypeDictStorage(language.getEmptyShape()); - PDict dict = PythonObjectFactory.getUncached().createDict(new DynamicObjectStorage(nativeTypeStore)); + PDict dict = PFactory.createDict(language, new DynamicObjectStorage(nativeTypeStore)); HiddenAttr.WriteNode.executeUncached(dict, HiddenAttr.INSTANCESHAPE, language.getShapeForClass(nativeClass)); return dict; } } - @CApiBuiltin(ret = ArgDescriptor.Void, args = {PyTypeObject}, call = Ignored) - abstract static class PyTruffle_InitializeOldStyleSlots extends CApiUnaryBuiltinNode { - - @TruffleBoundary - @Specialization - static Object doIt(PythonAbstractNativeObject clazz, - @Bind("this") Node inliningTarget) { - SpecialMethodSlot.reinitializeSpecialMethodSlots(clazz, PythonLanguage.get(inliningTarget)); - return PNone.NO_VALUE; - } - } - @CApiBuiltin(ret = ArgDescriptor.Void, args = {PyTypeObject}, call = Direct) abstract static class PyType_Modified extends CApiUnaryBuiltinNode { - @TruffleBoundary @Specialization - static Object doIt(PythonAbstractNativeObject clazz, + static Object doIt(PythonAbstractClass object, @Bind("this") Node inliningTarget) { - PythonContext context = PythonContext.get(inliningTarget); - CyclicAssumption nativeClassStableAssumption = context.getNativeClassStableAssumption(clazz, false); - if (nativeClassStableAssumption != null) { - nativeClassStableAssumption.invalidate("PyType_Modified(\"" + TypeNodes.GetNameNode.executeUncached(clazz).toJavaStringUncached() + "\") called"); + if (object instanceof PythonAbstractNativeObject clazz) { + PythonContext context = PythonContext.get(inliningTarget); + CyclicAssumption nativeClassStableAssumption = context.getNativeClassStableAssumption(clazz, false); + if (nativeClassStableAssumption != null) { + nativeClassStableAssumption.invalidate("PyType_Modified(\"" + TypeNodes.GetNameNode.executeUncached(clazz).toJavaStringUncached() + "\") called"); + } + MroSequenceStorage mroStorage = TypeNodes.GetMroStorageNode.executeUncached(clazz); + mroStorage.lookupChanged(); + // Reload slots from native, which also invalidates cached slot lookups + clazz.setTpSlots(TpSlots.fromNative(clazz, context)); + } else { + MroSequenceStorage mroStorage = TypeNodes.GetMroStorageNode.executeUncached(object); + mroStorage.lookupChanged(); } - MroSequenceStorage mroStorage = TypeNodes.GetMroStorageNode.executeUncached(clazz); - mroStorage.lookupChanged(); - // Reload slots from native, which also invalidates cached slot lookups - clazz.setTpSlots(TpSlots.fromNative(clazz, context)); return PNone.NO_VALUE; } } @@ -269,7 +263,7 @@ abstract static class NewClassMethodNode extends Node { @Specialization(guards = "isClassOrStaticMethod(flags)") static Object classOrStatic(Node inliningTarget, Object methodDefPtr, TruffleString name, Object methObj, int flags, int wrapper, Object type, Object doc, - @Cached(inline = false) PythonObjectFactory factory, + @Bind PythonLanguage language, @Exclusive @Cached HiddenAttr.WriteNode writeHiddenAttrNode, @Cached(inline = false) WriteAttributeToPythonObjectNode writeAttrNode, @Exclusive @Cached CreateFunctionNode createFunctionNode) { @@ -277,9 +271,9 @@ static Object classOrStatic(Node inliningTarget, Object methodDefPtr, TruffleStr writeHiddenAttrNode.execute(inliningTarget, func, METHOD_DEF_PTR, methodDefPtr); PythonObject function; if ((flags & METH_CLASS) != 0) { - function = factory.createClassmethodFromCallableObj(func); + function = PFactory.createClassmethodFromCallableObj(language, func); } else { - function = factory.createStaticmethodFromCallableObj(func); + function = PFactory.createStaticmethodFromCallableObj(language, func); } writeAttrNode.execute(function, T___NAME__, name); writeAttrNode.execute(function, T___DOC__, doc); @@ -327,6 +321,12 @@ static int addSlot(Object clazz, PDict tpDict, TruffleString memberName, Object // slots declared on the PyTypeObject. However, one could maybe "steal" a manged slot // and stash it into a native type, so we play it safe a check both eventualities in // CreateFunctionNode + if (memberName.equalsUncached(T___HASH__, PythonUtils.TS_ENCODING)) { + if (CApiContext.isIdenticalToSymbol(cfunc, FUN_PYOBJECT_HASH_NOT_IMPLEMENTED)) { + PyDictSetDefault.executeUncached(tpDict, T___HASH__, PNone.NONE); + return 0; + } + } if (HashingStorageGetItem.hasKeyUncached(tpDict.getDictStorage(), memberName)) { // Following typeobject.c:add_operators we skip a slot if we already create a // function for it from another slot that was earlier or if the dict already @@ -358,7 +358,7 @@ public static int addMember(Object clazz, PDict tpDict, TruffleString memberName } // create member descriptor - GetSetDescriptor memberDescriptor = PythonObjectFactory.getUncached().createMemberDescriptor(getterObject, setterObject, memberName, clazz); + GetSetDescriptor memberDescriptor = PFactory.createMemberDescriptor(language, getterObject, setterObject, memberName, clazz); WriteAttributeToPythonObjectNode.getUncached().execute(memberDescriptor, SpecialAttributeNames.T___DOC__, memberDoc); // add member descriptor to tp_dict @@ -376,7 +376,6 @@ abstract static class CreateGetSetNode extends Node { @Specialization @TruffleBoundary static GetSetDescriptor createGetSet(Node inliningTarget, TruffleString name, Object cls, Object getter, Object setter, Object doc, Object closure, - @Cached(inline = false) PythonObjectFactory factory, @CachedLibrary(limit = "2") InteropLibrary interopLibrary) { assert !(doc instanceof CArrayWrapper); // note: 'doc' may be NULL; in this case, we would store 'None' @@ -385,7 +384,7 @@ static GetSetDescriptor createGetSet(Node inliningTarget, TruffleString name, Ob if (!interopLibrary.isNull(getter)) { RootCallTarget getterCT = getterCallTarget(name, language); getter = EnsureExecutableNode.executeUncached(getter, PExternalFunctionWrapper.GETTER); - get = factory.createBuiltinFunction(name, cls, EMPTY_OBJECT_ARRAY, ExternalFunctionNodes.createKwDefaults(getter, closure), 0, getterCT); + get = PFactory.createBuiltinFunction(language, name, cls, EMPTY_OBJECT_ARRAY, ExternalFunctionNodes.createKwDefaults(getter, closure), 0, getterCT); } PBuiltinFunction set = null; @@ -393,11 +392,11 @@ static GetSetDescriptor createGetSet(Node inliningTarget, TruffleString name, Ob if (hasSetter) { RootCallTarget setterCT = setterCallTarget(name, language); setter = EnsureExecutableNode.executeUncached(setter, PExternalFunctionWrapper.SETTER); - set = factory.createBuiltinFunction(name, cls, EMPTY_OBJECT_ARRAY, ExternalFunctionNodes.createKwDefaults(setter, closure), 0, setterCT); + set = PFactory.createBuiltinFunction(language, name, cls, EMPTY_OBJECT_ARRAY, ExternalFunctionNodes.createKwDefaults(setter, closure), 0, setterCT); } // create get-set descriptor - GetSetDescriptor descriptor = factory.createGetSetDescriptor(get, set, name, cls, hasSetter); + GetSetDescriptor descriptor = PFactory.createGetSetDescriptor(language, get, set, name, cls, hasSetter); WriteAttributeToPythonObjectNode.executeUncached(descriptor, T___DOC__, doc); return descriptor; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextUnicodeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextUnicodeBuiltins.java index a5b8e9a05d..d6667c0762 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextUnicodeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextUnicodeBuiltins.java @@ -84,8 +84,8 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.StrNode; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.ChrNode; import com.oracle.graal.python.builtins.modules.CodecsModuleBuiltins; import com.oracle.graal.python.builtins.modules.CodecsModuleBuiltins.CodecsEncodeNode; @@ -103,6 +103,7 @@ import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; +import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext; import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.UnicodeFromFormatNode; import com.oracle.graal.python.builtins.objects.cext.capi.PySequenceArrayWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.UnicodeObjectNodes.UnicodeAsWideCharNode; @@ -122,9 +123,7 @@ import com.oracle.graal.python.builtins.objects.str.StringBuiltins; import com.oracle.graal.python.builtins.objects.str.StringBuiltins.EncodeNode; import com.oracle.graal.python.builtins.objects.str.StringBuiltins.EndsWithNode; -import com.oracle.graal.python.builtins.objects.str.StringBuiltins.EqNode; import com.oracle.graal.python.builtins.objects.str.StringBuiltins.FindNode; -import com.oracle.graal.python.builtins.objects.str.StringBuiltins.LtNode; import com.oracle.graal.python.builtins.objects.str.StringBuiltins.ModNode; import com.oracle.graal.python.builtins.objects.str.StringBuiltins.RFindNode; import com.oracle.graal.python.builtins.objects.str.StringBuiltins.ReplaceNode; @@ -136,6 +135,7 @@ import com.oracle.graal.python.lib.PyTupleGetItem; import com.oracle.graal.python.lib.PyUnicodeCheckExactNode; import com.oracle.graal.python.lib.PyUnicodeFromEncodedObject; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; @@ -143,13 +143,11 @@ import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; -import com.oracle.graal.python.nodes.truffle.PythonTypes; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.OverflowException; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -159,7 +157,6 @@ import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.library.CachedLibrary; @@ -217,7 +214,7 @@ static PString fromObject(PString s, @Specialization(guards = {"!isPStringType(inliningTarget, obj, getClassNode)", "isStringSubtype(inliningTarget, obj, getClassNode, isSubtypeNode)"}) static Object fromObject(Object obj, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @Cached StrNode strNode, + @Cached StringBuiltins.StrNewNode strNode, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode) { return strNode.executeWith(obj); @@ -225,11 +222,10 @@ static Object fromObject(Object obj, @Specialization(guards = {"!isStringSubtype(inliningTarget, obj, getClassNode, isSubtypeNode)"}) static Object fromObject(Object obj, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANT_CONVERT_TO_STR_IMPLICITLY, obj); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CANT_CONVERT_TO_STR_IMPLICITLY, obj); } protected boolean isPStringType(Node inliningTarget, Object obj, GetClassNode getClassNode) { @@ -253,20 +249,18 @@ static Object concat(Object left, Object right, @Specialization(guards = {"!isString(left)", "!isStringSubtype(inliningTarget, left, getClassNode, isSubtypeNode)"}) static Object leftNotString(Object left, @SuppressWarnings("unused") Object right, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.MUST_BE_STR_NOT_P, left); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.MUST_BE_STR_NOT_P, left); } @Specialization(guards = {"!isString(right)", "!isStringSubtype(inliningTarget, right, getClassNode, isSubtypeNode)"}) static Object rightNotString(@SuppressWarnings("unused") Object left, Object right, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.MUST_BE_STR_NOT_P, right); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.MUST_BE_STR_NOT_P, right); } } @@ -299,7 +293,7 @@ static Object doGeneric(Object obj, Object encodingObj, Object errorsObj, errors = (TruffleString) errorsObjProfiled; } if (nullProfile.profile(inliningTarget, obj == PNone.NO_VALUE)) { - throw PRaiseNode.raiseUncached(inliningTarget, SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC); + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC); } return decodeNode.execute(null, inliningTarget, obj, encoding, errors); } @@ -316,8 +310,7 @@ static Object withPString(PString str, @Cached StringNodes.IsInternedStringNode isInternedStringNode, @Cached StringNodes.InternStringNode internNode, @Cached HashingStorageGetItem getItem, - @Cached HashingStorageSetItem setItem, - @Cached PythonObjectFactory.Lazy factory) { + @Cached HashingStorageSetItem setItem) { if (!unicodeCheckExactNode.execute(inliningTarget, str)) { return getNativeNull(inliningTarget); } @@ -330,10 +323,11 @@ static Object withPString(PString str, return str; } TruffleString ts = cast.execute(inliningTarget, str); - PDict dict = getCApiContext(inliningTarget).getInternedUnicode(); + CApiContext cApiContext = getCApiContext(inliningTarget); + PDict dict = cApiContext.getInternedUnicode(); if (dict == null) { - dict = factory.get(inliningTarget).createDict(); - getCApiContext(inliningTarget).setInternedUnicode(dict); + dict = PFactory.createDict(cApiContext.getContext().getLanguage(internNode)); + cApiContext.setInternedUnicode(dict); } Object interned = getItem.execute(inliningTarget, dict.getDictStorage(), ts); if (interned == null) { @@ -362,7 +356,7 @@ static Object find(Object format, Object args, @Cached ModNode modNode, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { checkNonNullArg(inliningTarget, format, args, raiseNode); return modNode.execute(null, format, args); } @@ -372,18 +366,17 @@ static Object find(Object format, @SuppressWarnings("unused") Object args, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { checkNonNullArg(inliningTarget, format, args, raiseNode); - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MUST_BE_STR_NOT_P, format); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_STR_NOT_P, format); } } @CApiBuiltin(ret = Py_ssize_t, args = {PyObject, PY_UCS4, Py_ssize_t, Py_ssize_t, Int}, call = Direct) - @TypeSystemReference(PythonTypes.class) @ImportStatic(PythonCextUnicodeBuiltins.class) abstract static class PyUnicode_FindChar extends CApi5BuiltinNode { @Specialization(guards = {"isString(string) || isStringSubtype(inliningTarget, string, getClassNode, isSubtypeNode)", "direction > 0"}) - static Object find(Object string, Object c, long start, long end, @SuppressWarnings("unused") long direction, + static Object find(Object string, Object c, long start, long end, @SuppressWarnings("unused") int direction, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @Shared @Cached ChrNode chrNode, @Cached FindNode findNode, @@ -393,7 +386,7 @@ static Object find(Object string, Object c, long start, long end, @SuppressWarni } @Specialization(guards = {"isString(string) || isStringSubtype(inliningTarget, string, getClassNode, isSubtypeNode)", "direction <= 0"}) - static Object find(Object string, Object c, long start, long end, @SuppressWarnings("unused") long direction, + static Object find(Object string, Object c, long start, long end, @SuppressWarnings("unused") int direction, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @Shared @Cached ChrNode chrNode, @Cached RFindNode rFindNode, @@ -405,16 +398,14 @@ static Object find(Object string, Object c, long start, long end, @SuppressWarni @Specialization(guards = {"!isTruffleString(string)", "!isStringSubtype(inliningTarget, string, getClassNode, isSubtypeNode)"}) static Object find(Object string, @SuppressWarnings("unused") Object c, @SuppressWarnings("unused") Object start, @SuppressWarnings("unused") Object end, @SuppressWarnings("unused") Object direction, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.MUST_BE_STR_NOT_P, string); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.MUST_BE_STR_NOT_P, string); } } @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, Py_ssize_t, Py_ssize_t}, call = Direct) - @TypeSystemReference(PythonTypes.class) @ImportStatic(PythonCextUnicodeBuiltins.class) abstract static class PyUnicode_Substring extends CApiTernaryBuiltinNode { @Specialization(guards = {"isString(s) || isStringSubtype(s, inliningTarget, getClassNode, isSubtypeNode)"}, limit = "1") @@ -427,7 +418,7 @@ static Object doString(Object s, long start, long end, @SuppressWarnings("unused") @Exclusive @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode) { if (profile.profile(inliningTarget, start < 0 || end < 0)) { - throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.IndexError, ErrorMessages.STRING_INDEX_OUT_OF_RANGE); + throw PRaiseNode.raiseStatic(inliningTarget, IndexError, ErrorMessages.STRING_INDEX_OUT_OF_RANGE); } Object getItemCallable = lookupAttrNode.execute(null, inliningTarget, s, T___GETITEM__); return callNode.executeWithoutFrame(getItemCallable, sliceNode.execute(inliningTarget, start, end, PNone.NONE)); @@ -435,11 +426,10 @@ static Object doString(Object s, long start, long end, @Specialization(guards = {"!isTruffleString(s)", "isStringSubtype(s, inliningTarget, getClassNode, isSubtypeNode)"}, limit = "1") static Object doError(Object s, @SuppressWarnings("unused") Object start, @SuppressWarnings("unused") Object end, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Exclusive @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.MUST_BE_STR_NOT_P, s); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.MUST_BE_STR_NOT_P, s); } protected static boolean isStringSubtype(Object obj, Node n, GetClassNode getClassNode, IsSubtypeNode isSubtypeNode) { @@ -461,11 +451,10 @@ static Object find(Object separator, Object seq, @Specialization(guards = {"!isTruffleString(separator)", "isStringSubtype(inliningTarget, separator, getClassNode, isSubtypeNode)"}) static Object find(Object separator, @SuppressWarnings("unused") Object seq, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.MUST_BE_STR_NOT_P, separator); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.MUST_BE_STR_NOT_P, separator); } } @@ -478,18 +467,17 @@ static Object compare(Object left, Object right, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Cached EqNode eqNode, + @Cached StringBuiltins.StringRichCmpNode eqNode, @Cached PyObjectIsTrueNode isTrue) { - return PInt.intValue(isTrue.execute(null, eqNode.execute(null, left, right))); + return PInt.intValue(isTrue.execute(null, eqNode.execute(null, left, right, RichCmpOp.Py_EQ))); } @Specialization(guards = {"!isAnyString(inliningTarget, left, getClassNode, isSubtypeNode) || !isAnyString(inliningTarget, right, getClassNode, isSubtypeNode)"}) static Object compare(Object left, Object right, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANT_COMPARE, left, right); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CANT_COMPARE, left, right); } } @@ -512,32 +500,30 @@ static Object compare(Object left, Object right, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Cached EqNode eqNode, - @Cached LtNode ltNode, + @Cached StringBuiltins.StringRichCmpNode eqNode, + @Cached StringBuiltins.StringRichCmpNode ltNode, @Cached InlinedConditionProfile eqProfile) { - if (eqProfile.profile(inliningTarget, (boolean) eqNode.execute(null, left, right))) { + if (eqProfile.profile(inliningTarget, (boolean) eqNode.execute(null, left, right, RichCmpOp.Py_EQ))) { return 0; } else { - return (boolean) ltNode.execute(null, left, right) ? -1 : 1; + return (boolean) ltNode.execute(null, left, right, RichCmpOp.Py_LT) ? -1 : 1; } } @Specialization(guards = {"!isAnyString(inliningTarget, left, getClassNode, isSubtypeNode) || !isAnyString(inliningTarget, right, getClassNode, isSubtypeNode)"}) static Object compare(Object left, Object right, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANT_COMPARE, left, right); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CANT_COMPARE, left, right); } } @CApiBuiltin(ret = Py_ssize_t, args = {PyObject, PyObject, Py_ssize_t, Py_ssize_t, Int}, call = Direct) - @TypeSystemReference(PythonTypes.class) @ImportStatic(PythonCextUnicodeBuiltins.class) abstract static class PyUnicode_Tailmatch extends CApi5BuiltinNode { @Specialization(guards = {"isAnyString(inliningTarget, string, getClassNode, isSubtypeNode)", "isAnyString(inliningTarget, substring, getClassNode, isSubtypeNode)", "direction > 0"}) - static int tailmatch(Object string, Object substring, long start, long end, @SuppressWarnings("unused") long direction, + static int tailmatch(Object string, Object substring, long start, long end, @SuppressWarnings("unused") int direction, @Bind("this") Node inliningTarget, @Shared @Cached PyObjectLookupAttr lookupAttrNode, @Shared @Cached PySliceNew sliceNode, @@ -551,7 +537,7 @@ static int tailmatch(Object string, Object substring, long start, long end, @Sup } @Specialization(guards = {"isAnyString(inliningTarget, string, getClassNode, isSubtypeNode)", "isAnyString(inliningTarget, substring, getClassNode, isSubtypeNode)", "direction <= 0"}) - static int tailmatch(Object string, Object substring, long start, long end, @SuppressWarnings("unused") long direction, + static int tailmatch(Object string, Object substring, long start, long end, @SuppressWarnings("unused") int direction, @Bind("this") Node inliningTarget, @Shared @Cached PyObjectLookupAttr lookupAttrNode, @Shared @Cached PySliceNew sliceNode, @@ -567,11 +553,10 @@ static int tailmatch(Object string, Object substring, long start, long end, @Sup @SuppressWarnings("unused") @Specialization(guards = {"!isAnyString(inliningTarget, string, getClassNode, isSubtypeNode) || !isAnyString(inliningTarget, substring, getClassNode, isSubtypeNode)"}) static Object find(Object string, Object substring, Object start, Object end, Object direction, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @Shared @Cached GetClassNode getClassNode, @Shared @Cached IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.MUST_BE_STR_NOT_P, string); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.MUST_BE_STR_NOT_P, string); } } @@ -589,16 +574,14 @@ static Object encode(Object obj, Object encoding, Object errors, @Specialization(guards = {"!isString(obj)", "!isStringSubtype(inliningTarget, obj, getClassNode, isSubtypeNode)"}) static Object encode(@SuppressWarnings("unused") Object obj, @SuppressWarnings("unused") Object encoding, @SuppressWarnings("unused") Object errors, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, BAD_ARG_TYPE_FOR_BUILTIN_OP); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, BAD_ARG_TYPE_FOR_BUILTIN_OP); } } @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject, PyObject, Py_ssize_t}, call = Direct) - @TypeSystemReference(PythonTypes.class) @ImportStatic(PythonCextUnicodeBuiltins.class) abstract static class PyUnicode_Replace extends CApiQuaternaryBuiltinNode { @Specialization(guards = {"isString(s)", "isString(substr)", "isString(replstr)"}) @@ -655,11 +638,10 @@ static Object escape(Object s, @Specialization(guards = {"!isString(obj)", "!isStringSubtype(inliningTarget, obj, getClassNode, isSubtypeNode)"}) static Object escape(@SuppressWarnings("unused") Object obj, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, BAD_ARG_TYPE_FOR_BUILTIN_OP); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, BAD_ARG_TYPE_FOR_BUILTIN_OP); } } @@ -671,19 +653,19 @@ static int doGeneric(Object type, long lindex, @Cached CastToTruffleStringNode castToStringNode, @Cached TruffleString.CodePointLengthNode lengthNode, @Cached TruffleString.CodePointAtIndexNode codepointAtIndexNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { TruffleString s = castToStringNode.execute(inliningTarget, type); int index = PInt.intValueExact(lindex); // avoid StringIndexOutOfBoundsException if (index < 0 || index >= lengthNode.execute(s, TS_ENCODING)) { - throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.STRING_INDEX_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.STRING_INDEX_OUT_OF_RANGE); } return codepointAtIndexNode.execute(s, index, TS_ENCODING); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.STRING_INDEX_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.STRING_INDEX_OUT_OF_RANGE); } } } @@ -692,35 +674,30 @@ static int doGeneric(Object type, long lindex, abstract static class PyTruffleUnicode_New extends CApiQuaternaryBuiltinNode { @Specialization static Object doGeneric(Object ptr, long elements, long elementSize, int isAscii, - @Cached PythonObjectFactory factory) { - return factory.createString(new NativeCharSequence(ptr, (int) elements, (int) elementSize, isAscii != 0)); + @Bind PythonLanguage language) { + return PFactory.createString(language, new NativeCharSequence(ptr, (int) elements, (int) elementSize, isAscii != 0)); } } @CApiBuiltin(ret = PyObjectTransfer, args = {Pointer, Py_ssize_t, Int}, call = Ignored) abstract static class PyTruffleUnicode_FromUCS extends CApiTernaryBuiltinNode { - private static Encoding encodingFromKind(Node inliningTarget, int kind, PRaiseNode.Lazy raiseNode) throws PException { + private static Encoding encodingFromKind(Node inliningTarget, int kind, PRaiseNode raiseNode) throws PException { return switch (kind) { case 1 -> ISO_8859_1; case 2 -> UTF_16; case 4 -> TS_ENCODING; - default -> throw raiseNode.get(inliningTarget).raiseBadInternalCall(); + default -> throw raiseNode.raiseBadInternalCall(inliningTarget); }; } - private static PString asPString(TruffleString ts, SwitchEncodingNode switchEncodingNode, PythonObjectFactory factory) { - return factory.createString(switchEncodingNode.execute(ts, TS_ENCODING)); - } - @Specialization(guards = "ptrLib.isPointer(ptr)") static Object doNative(Object ptr, long byteLength, int kind, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared("ptrLib") @CachedLibrary(limit = "1") InteropLibrary ptrLib, @Cached FromNativePointerNode fromNativePointerNode, @Shared("switchEncodingNode") @Cached SwitchEncodingNode switchEncodingNode, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { try { int iByteLength = PInt.intValueExact(byteLength); Encoding srcEncoding = encodingFromKind(inliningTarget, kind, raiseNode); @@ -730,9 +707,9 @@ static Object doNative(Object ptr, long byteLength, int kind, * For now, we use ISO-8859-1 and UTF-16 but that's not entirely correct. */ TruffleString ts = fromNativePointerNode.execute(ptr, 0, iByteLength, srcEncoding, true); - return asPString(ts, switchEncodingNode, factory); + return PFactory.createString(PythonLanguage.get(inliningTarget), switchEncodingNode.execute(ts, TS_ENCODING)); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } } @@ -743,21 +720,20 @@ static Object doManaged(Object ptr, long byteLength, int kind, @Cached GetByteArrayNode getByteArrayNode, @Cached FromByteArrayNode fromByteArrayNode, @Shared("switchEncodingNode") @Cached SwitchEncodingNode switchEncodingNode, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { try { Encoding srcEncoding = encodingFromKind(inliningTarget, kind, raiseNode); byte[] ucsBytes = getByteArrayNode.execute(inliningTarget, ptr, byteLength); TruffleString ts = fromByteArrayNode.execute(ucsBytes, srcEncoding); - return asPString(ts, switchEncodingNode, factory); + return PFactory.createString(PythonLanguage.get(inliningTarget), switchEncodingNode.execute(ts, TS_ENCODING)); } catch (InteropException e) { /* * This means that we cannot read the array-like foreign object or the foreign * elements cannot be interpreted as bytes. In any case, that's a fatal error. */ - throw raiseNode.get(inliningTarget).raise(SystemError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, SystemError, ErrorMessages.M, e); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } } } @@ -765,34 +741,29 @@ static Object doManaged(Object ptr, long byteLength, int kind, @CApiBuiltin(ret = PyObjectTransfer, args = {Pointer, Py_ssize_t, Int}, call = Ignored) abstract static class PyTruffleUnicode_FromUTF extends CApiTernaryBuiltinNode { - private static Encoding encodingFromKind(Node inliningTarget, int kind, PRaiseNode.Lazy raiseNode) throws PException { + private static Encoding encodingFromKind(Node inliningTarget, int kind, PRaiseNode raiseNode) throws PException { return switch (kind) { case 1 -> UTF_8; case 2 -> UTF_16LE; case 4 -> UTF_32LE; - default -> throw raiseNode.get(inliningTarget).raiseBadInternalCall(); + default -> throw raiseNode.raiseBadInternalCall(inliningTarget); }; } - private static PString asPString(TruffleString ts, SwitchEncodingNode switchEncodingNode, PythonObjectFactory factory) { - return factory.createString(switchEncodingNode.execute(ts, TS_ENCODING)); - } - @Specialization(guards = "ptrLib.isPointer(ptr)") static Object doNative(Object ptr, long byteLength, int kind, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared("ptrLib") @CachedLibrary(limit = "1") InteropLibrary ptrLib, @Cached FromNativePointerNode fromNativePointerNode, @Shared("switchEncodingNode") @Cached SwitchEncodingNode switchEncodingNode, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { try { int iByteLength = PInt.intValueExact(byteLength); Encoding srcEncoding = encodingFromKind(inliningTarget, kind, raiseNode); TruffleString ts = fromNativePointerNode.execute(ptr, 0, iByteLength, srcEncoding, true); - return asPString(ts, switchEncodingNode, factory); + return PFactory.createString(PythonLanguage.get(inliningTarget), switchEncodingNode.execute(ts, TS_ENCODING)); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } } @@ -803,21 +774,20 @@ static Object doManaged(Object ptr, long byteLength, int kind, @Cached GetByteArrayNode getByteArrayNode, @Cached FromByteArrayNode fromByteArrayNode, @Shared("switchEncodingNode") @Cached SwitchEncodingNode switchEncodingNode, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { try { Encoding srcEncoding = encodingFromKind(inliningTarget, kind, raiseNode); byte[] ucsBytes = getByteArrayNode.execute(inliningTarget, ptr, byteLength); TruffleString ts = fromByteArrayNode.execute(ucsBytes, srcEncoding); - return asPString(ts, switchEncodingNode, factory); + return PFactory.createString(PythonLanguage.get(inliningTarget), switchEncodingNode.execute(ts, TS_ENCODING)); } catch (InteropException e) { /* * This means that we cannot read the array-like foreign object or the foreign * elements cannot be interpreted as bytes. In any case, that's a fatal error. */ - throw raiseNode.get(inliningTarget).raise(SystemError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, SystemError, ErrorMessages.M, e); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } } } @@ -826,8 +796,8 @@ static Object doManaged(Object ptr, long byteLength, int kind, abstract static class PyUnicode_FromString extends CApiUnaryBuiltinNode { @Specialization static PString run(TruffleString str, - @Cached PythonObjectFactory factory) { - return factory.createString(str); + @Bind PythonLanguage language) { + return PFactory.createString(language, str); } @Specialization @@ -859,17 +829,17 @@ abstract static class PyTruffleUnicode_DecodeUTF8Stateful extends CApiQuaternary @Specialization static Object doUtf8Decode(Object cByteArray, long size, TruffleString errors, int reportConsumed, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached GetByteArrayNode getByteArrayNode, @Cached CodecsModuleBuiltins.CodecsDecodeNode decode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { - PBytes bytes = factory.createBytes(getByteArrayNode.execute(inliningTarget, cByteArray, size)); + PBytes bytes = PFactory.createBytes(language, getByteArrayNode.execute(inliningTarget, cByteArray, size)); return decode.call(null, bytes, T_UTF8, errors, reportConsumed == 0); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.SystemError, ErrorMessages.INPUT_TOO_LONG); + throw raiseNode.raise(inliningTarget, PythonErrorType.SystemError, ErrorMessages.INPUT_TOO_LONG); } catch (InteropException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.M, e); } } } @@ -880,12 +850,12 @@ abstract static class PyTruffleUnicode_DecodeUTF16Stateful extends CApi5BuiltinN @Specialization static Object decode(Object cByteArray, long size, TruffleString errors, int byteorder, int reportConsumed, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached GetByteArrayNode getByteArrayNode, @Cached CodecsModuleBuiltins.CodecsDecodeNode decode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { - PBytes bytes = factory.createBytes(getByteArrayNode.execute(inliningTarget, cByteArray, size)); + PBytes bytes = PFactory.createBytes(language, getByteArrayNode.execute(inliningTarget, cByteArray, size)); TruffleString encoding; if (byteorder == 0) { encoding = T_UTF_16; @@ -896,9 +866,9 @@ static Object decode(Object cByteArray, long size, TruffleString errors, int byt } return decode.call(null, bytes, encoding, errors, reportConsumed == 0); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.SystemError, ErrorMessages.INPUT_TOO_LONG); + throw raiseNode.raise(inliningTarget, PythonErrorType.SystemError, ErrorMessages.INPUT_TOO_LONG); } catch (InteropException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.M, e); } } } @@ -909,12 +879,12 @@ abstract static class PyTruffleUnicode_DecodeUTF32Stateful extends CApi5BuiltinN @Specialization static Object decode(Object cByteArray, long size, TruffleString errors, int byteorder, int reportConsumed, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached GetByteArrayNode getByteArrayNode, @Cached CodecsModuleBuiltins.CodecsDecodeNode decode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { - PBytes bytes = factory.createBytes(getByteArrayNode.execute(inliningTarget, cByteArray, size)); + PBytes bytes = PFactory.createBytes(language, getByteArrayNode.execute(inliningTarget, cByteArray, size)); TruffleString encoding; if (byteorder == 0) { encoding = T_UTF_32; @@ -925,9 +895,9 @@ static Object decode(Object cByteArray, long size, TruffleString errors, int byt } return decode.call(null, bytes, encoding, errors, reportConsumed == 0); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.SystemError, ErrorMessages.INPUT_TOO_LONG); + throw raiseNode.raise(inliningTarget, PythonErrorType.SystemError, ErrorMessages.INPUT_TOO_LONG); } catch (InteropException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.M, e); } } } @@ -948,10 +918,9 @@ abstract static class PyUnicode_EncodeFSDefault extends CApiUnaryBuiltinNode { static PBytes fromObject(Object s, @Bind("this") Node inliningTarget, @Cached CastToTruffleStringNode castStr, - @Cached EncodeNativeStringNode encode, - @Cached PythonObjectFactory factory) { + @Cached EncodeNativeStringNode encode) { byte[] array = encode.execute(StandardCharsets.UTF_8, castStr.execute(inliningTarget, s), T_REPLACE); - return factory.createBytes(array); + return PFactory.createBytes(PythonLanguage.get(inliningTarget), array); } } @@ -973,10 +942,9 @@ abstract static class PyUnicode_FromWideChar extends CApiBinaryBuiltinNode { Object doInt(Object arr, long size, @Bind("this") Node inliningTarget, @Cached ReadUnicodeArrayNode readArray, - @Cached TruffleString.FromIntArrayUTF32Node fromArray, - @Cached PythonObjectFactory factory) { + @Cached TruffleString.FromIntArrayUTF32Node fromArray) { assert TS_ENCODING == Encoding.UTF_32 : "needs switch_encoding otherwise"; - return factory.createString(fromArray.execute(readArray.execute(inliningTarget, arr, castToInt(size), CStructs.wchar_t.size()))); + return PFactory.createString(PythonLanguage.get(inliningTarget), fromArray.execute(readArray.execute(inliningTarget, arr, castToInt(size), CStructs.wchar_t.size()))); } } @@ -989,22 +957,20 @@ protected NativeEncoderNode(Charset charset) { @Specialization(guards = "isNoValue(errors)") Object doUnicode(Object s, @SuppressWarnings("unused") PNone errors, - @Shared("encodeNode") @Cached EncodeNativeStringNode encodeNativeStringNode, - @Shared @Cached PythonObjectFactory factory) { - return doUnicode(s, T_STRICT, encodeNativeStringNode, factory); + @Shared("encodeNode") @Cached EncodeNativeStringNode encodeNativeStringNode) { + return doUnicode(s, T_STRICT, encodeNativeStringNode); } @Specialization Object doUnicode(Object s, TruffleString errors, - @Shared("encodeNode") @Cached EncodeNativeStringNode encodeNativeStringNode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createBytes(encodeNativeStringNode.execute(charset, s, errors)); + @Shared("encodeNode") @Cached EncodeNativeStringNode encodeNativeStringNode) { + return PFactory.createBytes(PythonLanguage.get(this), encodeNativeStringNode.execute(charset, s, errors)); } @Fallback static Object doUnicode(@SuppressWarnings("unused") Object s, @SuppressWarnings("unused") Object errors, - @Cached PRaiseNode raiseNode) { - return raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); } } @@ -1059,8 +1025,8 @@ static Object doUnicode(PString s, Object sizePtr, @Fallback @SuppressWarnings("unused") static Object doError(Object s, Object sizePtr, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, BAD_ARG_TYPE_FOR_BUILTIN_OP); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, BAD_ARG_TYPE_FOR_BUILTIN_OP); } } @@ -1110,8 +1076,8 @@ static Object doUnicode(PString s, Object sizePtr, @Fallback @SuppressWarnings("unused") static Object doError(Object s, Object sizePtr, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, BAD_ARG_TYPE_FOR_BUILTIN_OP); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, BAD_ARG_TYPE_FOR_BUILTIN_OP); } } @@ -1140,24 +1106,23 @@ static Object doNative(PythonAbstractNativeObject s, } @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, Int}, call = Ignored) - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class PyTruffle_Unicode_AsWideChar extends CApiBinaryBuiltinNode { @Specialization - static Object doUnicode(Object s, long elementSize, + static Object doUnicode(Object s, int elementSize, @Bind("this") Node inliningTarget, @Cached UnicodeAsWideCharNode asWideCharNode, @Cached CastToTruffleStringNode castStr, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { PBytes wchars = asWideCharNode.executeLittleEndian(inliningTarget, castStr.execute(inliningTarget, s), elementSize); if (wchars != null) { return wchars; } else { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.UNSUPPORTED_SIZE_WAS, "wchar", elementSize); + throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.UNSUPPORTED_SIZE_WAS, "wchar", elementSize); } } catch (IllegalArgumentException e) { // TODO - throw raiseNode.get(inliningTarget).raise(PythonErrorType.LookupError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, PythonErrorType.LookupError, ErrorMessages.M, e); } } } @@ -1194,15 +1159,14 @@ static Object doit(Object encoding, Object object, long length, long start, long @Bind("this") Node inliningTarget, @Cached GetByteArrayNode getByteArrayNode, @Cached CallNode callNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { PBytes bytes; try { - bytes = factory.createBytes(getByteArrayNode.execute(inliningTarget, object, length)); + bytes = PFactory.createBytes(PythonLanguage.get(inliningTarget), getByteArrayNode.execute(inliningTarget, object, length)); } catch (InteropException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.M, e); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.SystemError, ErrorMessages.NEGATIVE_SIZE_PASSED); + throw raiseNode.raise(inliningTarget, PythonErrorType.SystemError, ErrorMessages.NEGATIVE_SIZE_PASSED); } return callNode.executeWithoutFrame(UnicodeDecodeError, encoding, bytes, start, end, reason); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextWeakrefBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextWeakrefBuiltins.java index 82fa997873..05d36d63a1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextWeakrefBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextWeakrefBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,15 +44,16 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObject; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectBorrowed; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObjectTransfer; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PYWEAKREFERENCE_PTR; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Void; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.modules.WeakRefModuleBuiltins.ReferenceTypeNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin; import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiUnaryBuiltinNode; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.referencetype.PReferenceType; +import com.oracle.graal.python.builtins.objects.referencetype.ReferenceTypeBuiltins.ReferenceTypeNode; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; @@ -89,4 +90,15 @@ static Object call(Object reference) { return PNone.NONE; } } + + @CApiBuiltin(name = "_PyWeakref_ClearRef", ret = Void, args = {PYWEAKREFERENCE_PTR}, call = Direct) + abstract static class PyWeakref_ClearRef extends CApiUnaryBuiltinNode { + @Specialization + static Object call(Object reference) { + if (reference instanceof PReferenceType ref) { + ref.clearRef(); + } + return PNone.NONE; + } + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecCtxBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecCtxBuiltins.java index d92537ce8c..cae8468c93 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecCtxBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecCtxBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -97,13 +97,13 @@ static Object codecctxErrorsSet(MultibyteStatefulCodecContext self, Object value @Cached TruffleString.EqualNode isEqual, @Cached CastToTruffleStringNode castToStringNode, @Cached PyUnicodeCheckNode unicodeCheckNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (value == PNone.NONE) { - throw raiseNode.get(inliningTarget).raise(AttributeError, CANNOT_DELETE); + throw raiseNode.raise(inliningTarget, AttributeError, CANNOT_DELETE); } if (!unicodeCheckNode.execute(inliningTarget, value)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ERRORS_MUST_BE_A_STRING); + throw raiseNode.raise(inliningTarget, TypeError, ERRORS_MUST_BE_A_STRING); } TruffleString str = castToStringNode.execute(inliningTarget, value); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsCNModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsCNModuleBuiltins.java index 0b9fb8aaaf..8a0a6123e9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsCNModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsCNModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -53,6 +53,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -66,7 +67,7 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -103,15 +104,15 @@ public void initialize(Python3Core core) { @Override public void postInitialize(Python3Core core) { super.postInitialize(core); - PythonObjectFactory factory = core.factory(); + PythonLanguage language = core.getLanguage(); PythonModule codec = core.lookupBuiltinModule(T__CODECS_CN); - registerCodec("gb2312", 0, CodecType.STATELESS, 0, MappingType.DECONLY, MAPPING_LIST, CODEC_LIST, codec, factory); - registerCodec("gbk", 1, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("gb18030", 2, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("hz", 3, CodecType.STATEFUL, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("gbkext", -1, null, 1, MappingType.DECONLY, MAPPING_LIST, null, codec, factory); - registerCodec("gbcommon", -1, null, 2, MappingType.ENCONLY, MAPPING_LIST, null, codec, factory); - registerCodec("gb18030ext", -1, null, 3, MappingType.ENCDEC, MAPPING_LIST, null, codec, factory); + registerCodec("gb2312", 0, CodecType.STATELESS, 0, MappingType.DECONLY, MAPPING_LIST, CODEC_LIST, codec, language); + registerCodec("gbk", 1, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, language); + registerCodec("gb18030", 2, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, language); + registerCodec("hz", 3, CodecType.STATEFUL, -1, null, null, CODEC_LIST, codec, language); + registerCodec("gbkext", -1, null, 1, MappingType.DECONLY, MAPPING_LIST, null, codec, language); + registerCodec("gbcommon", -1, null, 2, MappingType.ENCONLY, MAPPING_LIST, null, codec, language); + registerCodec("gb18030ext", -1, null, 3, MappingType.ENCDEC, MAPPING_LIST, null, codec, language); } @Builtin(name = "getcodec", minNumOfPositionalArgs = 1) @@ -124,20 +125,20 @@ static Object getcodec(Object encoding, @Cached TruffleString.EqualNode isEqual, @Cached PyUnicodeCheckNode unicodeCheckNode, @Cached CastToTruffleStringNode asUTF8Node, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { if (!unicodeCheckNode.execute(inliningTarget, encoding)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ENCODING_NAME_MUST_BE_A_STRING); + throw raiseNode.raise(inliningTarget, TypeError, ENCODING_NAME_MUST_BE_A_STRING); } MultibyteCodec codec = findCodec(CODEC_LIST, asUTF8Node.execute(inliningTarget, encoding), isEqual); if (codec == null) { - throw raiseNode.get(inliningTarget).raise(LookupError, NO_SUCH_CODEC_IS_SUPPORTED); + throw raiseNode.raise(inliningTarget, LookupError, NO_SUCH_CODEC_IS_SUPPORTED); } - PyCapsule codecobj = factory.createCapsuleJavaName(codec, PyMultibyteCodec_CAPSULE_NAME); - return createCodec(inliningTarget, codecobj, factory, raiseNode); + PyCapsule codecobj = PFactory.createCapsuleJavaName(language, codec, PyMultibyteCodec_CAPSULE_NAME); + return createCodec(inliningTarget, codecobj, raiseNode); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsHKModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsHKModuleBuiltins.java index 59f6e9f429..c1a8c13e16 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsHKModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsHKModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -53,6 +53,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -66,7 +67,7 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -99,11 +100,11 @@ public void initialize(Python3Core core) { @Override public void postInitialize(Python3Core core) { super.postInitialize(core); - PythonObjectFactory factory = core.factory(); + PythonLanguage language = core.getLanguage(); PythonModule codec = core.lookupBuiltinModule(T__CODECS_HK); - registerCodec("big5hkscs", 0, CodecType.STATELESS_WINIT, 0, MappingType.DECONLY, MAPPING_LIST, CODEC_LIST, codec, factory); - registerCodec("big5hkscs_bmp", -1, null, 1, MappingType.ENCONLY, MAPPING_LIST, CODEC_LIST, codec, factory); - registerCodec("big5hkscs_nonbmp", -1, null, 2, MappingType.ENCONLY, MAPPING_LIST, CODEC_LIST, codec, factory); + registerCodec("big5hkscs", 0, CodecType.STATELESS_WINIT, 0, MappingType.DECONLY, MAPPING_LIST, CODEC_LIST, codec, language); + registerCodec("big5hkscs_bmp", -1, null, 1, MappingType.ENCONLY, MAPPING_LIST, CODEC_LIST, codec, language); + registerCodec("big5hkscs_nonbmp", -1, null, 2, MappingType.ENCONLY, MAPPING_LIST, CODEC_LIST, codec, language); } @Builtin(name = "getcodec", minNumOfPositionalArgs = 1) @@ -116,20 +117,20 @@ static Object getcodec(Object encoding, @Cached TruffleString.EqualNode isEqual, @Cached PyUnicodeCheckNode unicodeCheckNode, @Cached CastToTruffleStringNode asUTF8Node, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { if (!unicodeCheckNode.execute(inliningTarget, encoding)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ENCODING_NAME_MUST_BE_A_STRING); + throw raiseNode.raise(inliningTarget, TypeError, ENCODING_NAME_MUST_BE_A_STRING); } MultibyteCodec codec = findCodec(CODEC_LIST, asUTF8Node.execute(inliningTarget, encoding), isEqual); if (codec == null) { - throw raiseNode.get(inliningTarget).raise(LookupError, NO_SUCH_CODEC_IS_SUPPORTED); + throw raiseNode.raise(inliningTarget, LookupError, NO_SUCH_CODEC_IS_SUPPORTED); } - PyCapsule codecobj = factory.createCapsuleJavaName(codec, PyMultibyteCodec_CAPSULE_NAME); - return createCodec(inliningTarget, codecobj, factory, raiseNode); + PyCapsule codecobj = PFactory.createCapsuleJavaName(language, codec, PyMultibyteCodec_CAPSULE_NAME); + return createCodec(inliningTarget, codecobj, raiseNode); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsISO2022ModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsISO2022ModuleBuiltins.java index 883ea00440..a6ce7e5163 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsISO2022ModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsISO2022ModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -53,6 +53,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -65,7 +66,7 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -99,16 +100,16 @@ protected List> getNodeFa @Override public void postInitialize(Python3Core core) { super.postInitialize(core); - PythonObjectFactory factory = core.factory(); + PythonLanguage language = core.getLanguage(); PythonModule codec = core.lookupBuiltinModule(T__CODECS_ISO2022); int i = 0; - registerCodec("iso2022_kr", i++, CodecType.ISO2022, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("iso2022_jp", i++, CodecType.ISO2022, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("iso2022_jp_1", i++, CodecType.ISO2022, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("iso2022_jp_2", i++, CodecType.ISO2022, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("iso2022_jp_2004", i++, CodecType.ISO2022, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("iso2022_jp_3", i++, CodecType.ISO2022, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("iso2022_jp_ext", i, CodecType.ISO2022, -1, null, null, CODEC_LIST, codec, factory); + registerCodec("iso2022_kr", i++, CodecType.ISO2022, -1, null, null, CODEC_LIST, codec, language); + registerCodec("iso2022_jp", i++, CodecType.ISO2022, -1, null, null, CODEC_LIST, codec, language); + registerCodec("iso2022_jp_1", i++, CodecType.ISO2022, -1, null, null, CODEC_LIST, codec, language); + registerCodec("iso2022_jp_2", i++, CodecType.ISO2022, -1, null, null, CODEC_LIST, codec, language); + registerCodec("iso2022_jp_2004", i++, CodecType.ISO2022, -1, null, null, CODEC_LIST, codec, language); + registerCodec("iso2022_jp_3", i++, CodecType.ISO2022, -1, null, null, CODEC_LIST, codec, language); + registerCodec("iso2022_jp_ext", i, CodecType.ISO2022, -1, null, null, CODEC_LIST, codec, language); } @Override @@ -126,20 +127,20 @@ static Object getcodec(Object encoding, @Cached TruffleString.EqualNode isEqual, @Cached PyUnicodeCheckNode unicodeCheckNode, @Cached CastToTruffleStringNode asUTF8Node, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { if (!unicodeCheckNode.execute(inliningTarget, encoding)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ENCODING_NAME_MUST_BE_A_STRING); + throw raiseNode.raise(inliningTarget, TypeError, ENCODING_NAME_MUST_BE_A_STRING); } MultibyteCodec codec = findCodec(CODEC_LIST, asUTF8Node.execute(inliningTarget, encoding), isEqual); if (codec == null) { - throw raiseNode.get(inliningTarget).raise(LookupError, NO_SUCH_CODEC_IS_SUPPORTED); + throw raiseNode.raise(inliningTarget, LookupError, NO_SUCH_CODEC_IS_SUPPORTED); } - PyCapsule codecobj = factory.createCapsuleJavaName(codec, PyMultibyteCodec_CAPSULE_NAME); - return createCodec(inliningTarget, codecobj, factory, raiseNode); + PyCapsule codecobj = PFactory.createCapsuleJavaName(language, codec, PyMultibyteCodec_CAPSULE_NAME); + return createCodec(inliningTarget, codecobj, raiseNode); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsJPModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsJPModuleBuiltins.java index 4d1e9d09a1..59352af1c5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsJPModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsJPModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -53,6 +53,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -66,7 +67,7 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -108,29 +109,29 @@ protected List> getNodeFa @Override public void postInitialize(Python3Core core) { super.postInitialize(core); - PythonObjectFactory factory = core.factory(); + PythonLanguage language = core.getLanguage(); PythonModule codec = core.lookupBuiltinModule(T__CODECS_JP); int i = 0; - registerCodec("shift_jis", i++, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("cp932", i++, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("euc_jp", i++, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("shift_jis_2004", i++, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("euc_jis_2004", i++, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("euc_jisx0213", i++, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("shift_jisx0213", i, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, factory); + registerCodec("shift_jis", i++, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, language); + registerCodec("cp932", i++, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, language); + registerCodec("euc_jp", i++, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, language); + registerCodec("shift_jis_2004", i++, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, language); + registerCodec("euc_jis_2004", i++, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, language); + registerCodec("euc_jisx0213", i++, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, language); + registerCodec("shift_jisx0213", i, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, language); i = 0; - registerCodec("jisx0208", -1, null, i++, MappingType.DECONLY, MAPPING_LIST, null, codec, factory); - registerCodec("jisx0212", -1, null, i++, MappingType.DECONLY, MAPPING_LIST, null, codec, factory); - registerCodec("jisxcommon", -1, null, i++, MappingType.ENCONLY, MAPPING_LIST, null, codec, factory); - registerCodec("jisx0213_1_bmp", -1, null, i++, MappingType.DECONLY, MAPPING_LIST, null, codec, factory); - registerCodec("jisx0213_2_bmp", -1, null, i++, MappingType.DECONLY, MAPPING_LIST, null, codec, factory); - registerCodec("jisx0213_bmp", -1, null, i++, MappingType.ENCONLY, MAPPING_LIST, null, codec, factory); - registerCodec("jisx0213_1_emp", -1, null, i++, MappingType.DECONLY, MAPPING_LIST, null, codec, factory); - registerCodec("jisx0213_2_emp", -1, null, i++, MappingType.DECONLY, MAPPING_LIST, null, codec, factory); - registerCodec("jisx0213_emp", -1, null, i++, MappingType.ENCONLY, MAPPING_LIST, null, codec, factory); - registerCodec("jisx0213_pair", -1, null, i++, MappingType.ENCDEC, MAPPING_LIST, null, codec, factory); - registerCodec("cp932ext", -1, null, i, MappingType.ENCDEC, MAPPING_LIST, null, codec, factory); + registerCodec("jisx0208", -1, null, i++, MappingType.DECONLY, MAPPING_LIST, null, codec, language); + registerCodec("jisx0212", -1, null, i++, MappingType.DECONLY, MAPPING_LIST, null, codec, language); + registerCodec("jisxcommon", -1, null, i++, MappingType.ENCONLY, MAPPING_LIST, null, codec, language); + registerCodec("jisx0213_1_bmp", -1, null, i++, MappingType.DECONLY, MAPPING_LIST, null, codec, language); + registerCodec("jisx0213_2_bmp", -1, null, i++, MappingType.DECONLY, MAPPING_LIST, null, codec, language); + registerCodec("jisx0213_bmp", -1, null, i++, MappingType.ENCONLY, MAPPING_LIST, null, codec, language); + registerCodec("jisx0213_1_emp", -1, null, i++, MappingType.DECONLY, MAPPING_LIST, null, codec, language); + registerCodec("jisx0213_2_emp", -1, null, i++, MappingType.DECONLY, MAPPING_LIST, null, codec, language); + registerCodec("jisx0213_emp", -1, null, i++, MappingType.ENCONLY, MAPPING_LIST, null, codec, language); + registerCodec("jisx0213_pair", -1, null, i++, MappingType.ENCDEC, MAPPING_LIST, null, codec, language); + registerCodec("cp932ext", -1, null, i, MappingType.ENCDEC, MAPPING_LIST, null, codec, language); } @Override @@ -148,20 +149,20 @@ static Object getcodec(Object encoding, @Cached TruffleString.EqualNode isEqual, @Cached PyUnicodeCheckNode unicodeCheckNode, @Cached CastToTruffleStringNode asUTF8Node, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { if (!unicodeCheckNode.execute(inliningTarget, encoding)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ENCODING_NAME_MUST_BE_A_STRING); + throw raiseNode.raise(inliningTarget, TypeError, ENCODING_NAME_MUST_BE_A_STRING); } MultibyteCodec codec = findCodec(CODEC_LIST, asUTF8Node.execute(inliningTarget, encoding), isEqual); if (codec == null) { - throw raiseNode.get(inliningTarget).raise(LookupError, NO_SUCH_CODEC_IS_SUPPORTED); + throw raiseNode.raise(inliningTarget, LookupError, NO_SUCH_CODEC_IS_SUPPORTED); } - PyCapsule codecobj = factory.createCapsuleJavaName(codec, PyMultibyteCodec_CAPSULE_NAME); - return createCodec(inliningTarget, codecobj, factory, raiseNode); + PyCapsule codecobj = PFactory.createCapsuleJavaName(language, codec, PyMultibyteCodec_CAPSULE_NAME); + return createCodec(inliningTarget, codecobj, raiseNode); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsKRModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsKRModuleBuiltins.java index 70d50acc4e..33e5a58157 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsKRModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsKRModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -53,6 +53,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -66,7 +67,7 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -96,14 +97,14 @@ protected List> getNodeFa @Override public void postInitialize(Python3Core core) { super.postInitialize(core); - PythonObjectFactory factory = core.factory(); + PythonLanguage language = core.getLanguage(); PythonModule codec = core.lookupBuiltinModule(T__CODECS_KR); - registerCodec("euc_kr", 0, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("cp949", 1, CodecType.STATELESS, 1, MappingType.ENCONLY, MAPPING_LIST, CODEC_LIST, codec, factory); - registerCodec("johab", 2, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, factory); + registerCodec("euc_kr", 0, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, language); + registerCodec("cp949", 1, CodecType.STATELESS, 1, MappingType.ENCONLY, MAPPING_LIST, CODEC_LIST, codec, language); + registerCodec("johab", 2, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, language); - registerCodec("ksx1001", -1, null, 0, MappingType.DECONLY, MAPPING_LIST, null, codec, factory); - registerCodec("cp949ext", -1, null, 2, MappingType.DECONLY, MAPPING_LIST, null, codec, factory); + registerCodec("ksx1001", -1, null, 0, MappingType.DECONLY, MAPPING_LIST, null, codec, language); + registerCodec("cp949ext", -1, null, 2, MappingType.DECONLY, MAPPING_LIST, null, codec, language); } @Override @@ -121,20 +122,20 @@ static Object getcodec(Object encoding, @Cached TruffleString.EqualNode isEqual, @Cached PyUnicodeCheckNode unicodeCheckNode, @Cached CastToTruffleStringNode asUTF8Node, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { if (!unicodeCheckNode.execute(inliningTarget, encoding)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ENCODING_NAME_MUST_BE_A_STRING); + throw raiseNode.raise(inliningTarget, TypeError, ENCODING_NAME_MUST_BE_A_STRING); } MultibyteCodec codec = findCodec(CODEC_LIST, asUTF8Node.execute(inliningTarget, encoding), isEqual); if (codec == null) { - throw raiseNode.get(inliningTarget).raise(LookupError, NO_SUCH_CODEC_IS_SUPPORTED); + throw raiseNode.raise(inliningTarget, LookupError, NO_SUCH_CODEC_IS_SUPPORTED); } - PyCapsule codecobj = factory.createCapsuleJavaName(codec, PyMultibyteCodec_CAPSULE_NAME); - return createCodec(inliningTarget, codecobj, factory, raiseNode); + PyCapsule codecobj = PFactory.createCapsuleJavaName(language, codec, PyMultibyteCodec_CAPSULE_NAME); + return createCodec(inliningTarget, codecobj, raiseNode); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsTWModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsTWModuleBuiltins.java index 0f82419396..283810add0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsTWModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/CodecsTWModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -53,6 +53,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -66,7 +67,7 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -94,11 +95,11 @@ protected List> getNodeFa @Override public void postInitialize(Python3Core core) { super.postInitialize(core); - PythonObjectFactory factory = core.factory(); + PythonLanguage language = core.getLanguage(); PythonModule codec = core.lookupBuiltinModule(T__CODECS_TW); - registerCodec("big5", 0, CodecType.STATELESS, 0, MappingType.ENCDEC, MAPPING_LIST, CODEC_LIST, codec, factory); - registerCodec("cp950", 1, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, factory); - registerCodec("cp950ext", -1, null, 1, MappingType.ENCDEC, MAPPING_LIST, null, codec, factory); + registerCodec("big5", 0, CodecType.STATELESS, 0, MappingType.ENCDEC, MAPPING_LIST, CODEC_LIST, codec, language); + registerCodec("cp950", 1, CodecType.STATELESS, -1, null, null, CODEC_LIST, codec, language); + registerCodec("cp950ext", -1, null, 1, MappingType.ENCDEC, MAPPING_LIST, null, codec, language); } @Override @@ -116,20 +117,20 @@ static Object getcodec(Object encoding, @Cached TruffleString.EqualNode isEqual, @Cached PyUnicodeCheckNode unicodeCheckNode, @Cached CastToTruffleStringNode asUTF8Node, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { if (!unicodeCheckNode.execute(inliningTarget, encoding)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ENCODING_NAME_MUST_BE_A_STRING); + throw raiseNode.raise(inliningTarget, TypeError, ENCODING_NAME_MUST_BE_A_STRING); } MultibyteCodec codec = findCodec(CODEC_LIST, asUTF8Node.execute(inliningTarget, encoding), isEqual); if (codec == null) { - throw raiseNode.get(inliningTarget).raise(LookupError, NO_SUCH_CODEC_IS_SUPPORTED); + throw raiseNode.raise(inliningTarget, LookupError, NO_SUCH_CODEC_IS_SUPPORTED); } - PyCapsule codecobj = factory.createCapsuleJavaName(codec, PyMultibyteCodec_CAPSULE_NAME); - return createCodec(inliningTarget, codecobj, factory, raiseNode); + PyCapsule codecobj = PFactory.createCapsuleJavaName(language, codec, PyMultibyteCodec_CAPSULE_NAME); + return createCodec(inliningTarget, codecobj, raiseNode); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecBuiltins.java index 6995a40711..6a31839447 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -52,6 +52,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -64,7 +65,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -119,16 +120,16 @@ static Object ts(VirtualFrame frame, MultibyteCodecObject self, TruffleString uc @Exclusive @Cached MultibyteCodecUtil.EncodeNode encodeNode, @Shared @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Shared @Cached TruffleString.EqualNode isEqual, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { TruffleString errorcb = internalErrorCallback(errors, isEqual); MultibyteCodecState state = self.codec.encinit(errorcb); int datalen = codePointLengthNode.execute(ucvt, TS_ENCODING); - PBytes r = encodeEmptyInput(datalen, MBENC_FLUSH | MBENC_RESET, factory); + PBytes r = encodeEmptyInput(inliningTarget, datalen, MBENC_FLUSH | MBENC_RESET); if (r == null) { MultibyteEncodeBuffer buf = new MultibyteEncodeBuffer(ucvt); - r = encodeNode.execute(frame, inliningTarget, self.codec, state, buf, errorcb, MBENC_FLUSH | MBENC_RESET, factory); + r = encodeNode.execute(frame, inliningTarget, self.codec, state, buf, errorcb, MBENC_FLUSH | MBENC_RESET); } - return factory.createTuple(new Object[]{r, datalen}); + return PFactory.createTuple(language, new Object[]{r, datalen}); } @Specialization(guards = "!isTruffleString(input)") @@ -140,18 +141,18 @@ static Object notTS(VirtualFrame frame, MultibyteCodecObject self, Object input, @Exclusive @Cached MultibyteCodecUtil.EncodeNode encodeNode, @Shared @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Shared @Cached TruffleString.EqualNode isEqual, - @Shared @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { Object ucvt = input; if (!unicodeCheck.execute(inliningTarget, input)) { ucvt = strNode.execute(frame, inliningTarget, input); if (!unicodeCheck.execute(inliningTarget, ucvt)) { - throw raiseNode.get(inliningTarget).raise(TypeError, COULDN_T_CONVERT_THE_OBJECT_TO_UNICODE); + throw raiseNode.raise(inliningTarget, TypeError, COULDN_T_CONVERT_THE_OBJECT_TO_UNICODE); } } TruffleString str = toTruffleStringNode.execute(inliningTarget, ucvt); - return ts(frame, self, str, errors, inliningTarget, encodeNode, codePointLengthNode, isEqual, factory); + return ts(frame, self, str, errors, inliningTarget, encodeNode, codePointLengthNode, isEqual, language); } } @@ -186,13 +187,13 @@ protected ArgumentClinicProvider getArgumentClinic() { Object decode(VirtualFrame frame, MultibyteCodecObject self, byte[] input, TruffleString errors, @Cached MultibyteCodecUtil.DecodeErrorNode decodeErrorNode, @Cached TruffleString.EqualNode isEqual, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { int datalen = input.length; TruffleString errorcb = internalErrorCallback(errors, isEqual); if (datalen == 0) { - return factory.createTuple(new Object[]{T_EMPTY_STRING, 0}); + return PFactory.createTuple(language, new Object[]{T_EMPTY_STRING, 0}); } MultibyteDecodeBuffer buf = new MultibyteDecodeBuffer(input); MultibyteCodecState state = self.codec.decinit(errorcb); @@ -205,7 +206,7 @@ Object decode(VirtualFrame frame, MultibyteCodecObject self, byte[] input, Truff } } - return factory.createTuple(new Object[]{buf.toTString(), datalen}); + return PFactory.createTuple(language, new Object[]{buf.toTString(), datalen}); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java index b48118e590..a62459db0f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -71,6 +71,7 @@ import java.nio.CharBuffer; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.codecs.CodecsRegistry.PyCodecLookupErrorNode; import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; import com.oracle.graal.python.builtins.objects.bytes.PBytes; @@ -86,7 +87,7 @@ import com.oracle.graal.python.nodes.util.CastToJavaStringNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -170,7 +171,7 @@ static int encerror(VirtualFrame frame, MultibyteCodec codec, MultibyteCodecState state, MultibyteEncodeBuffer buf, Object errors, int e, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached BaseExceptionAttrNode attrNode, @Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray, @Cached PyUnicodeCheckNode unicodeCheckNode, @@ -182,7 +183,7 @@ static int encerror(VirtualFrame frame, MultibyteCodec codec, @Cached(inline = true) CallErrorCallbackNode callErrorCallbackNode, @Cached BytesNodes.ToBytesNode toBytesNode, @Cached EncodeNode encodeNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleString reason = ILLEGAL_MULTIBYTE_SEQUENCE; int esize = e; @@ -196,9 +197,9 @@ static int encerror(VirtualFrame frame, MultibyteCodec codec, esize = buf.getInpos(); break; case MBERR_INTERNAL: - throw raiseNode.get(inliningTarget).raise(RuntimeError, INTERNAL_CODEC_ERROR); + throw raiseNode.raise(inliningTarget, RuntimeError, INTERNAL_CODEC_ERROR); default: - throw raiseNode.get(inliningTarget).raise(RuntimeError, UNKNOWN_RUNTIME_ERROR); + throw raiseNode.raise(inliningTarget, RuntimeError, UNKNOWN_RUNTIME_ERROR); } } @@ -233,10 +234,10 @@ static int encerror(VirtualFrame frame, MultibyteCodec codec, /* use cached exception object if available */ if (buf.excobj == null) { - buf.excobj = factory.createBaseException(UnicodeEncodeError); + buf.excobj = PFactory.createBaseException(language, UnicodeEncodeError); TruffleString encoding = codec.encoding; Object[] args = new Object[]{encoding, buf.toTString(), start, end, reason}; - buf.excobj.setArgs(factory.createTuple(args)); + buf.excobj.setArgs(PFactory.createTuple(language, args)); buf.excobj.setExceptionAttributes(args); } else { attrNode.execute(buf.excobj, start, IDX_START, UNICODE_ERROR_ATTR_FACTORY); @@ -245,7 +246,7 @@ static int encerror(VirtualFrame frame, MultibyteCodec codec, } if (errors == ERROR_STRICT) { - throw raiseNode.get(inliningTarget).raiseExceptionObject(buf.excobj); + throw raiseNode.raiseExceptionObject(inliningTarget, buf.excobj); // PyCodec_StrictErrors(buf.excobj); } @@ -270,18 +271,17 @@ static int encerror(VirtualFrame frame, MultibyteCodec codec, } if (isError) { - throw raiseNode.get(inliningTarget).raise(TypeError, ENCODING_ERROR_HANDLER_MUST_RETURN); + throw raiseNode.raise(inliningTarget, TypeError, ENCODING_ERROR_HANDLER_MUST_RETURN); } PBytes retstr; if (isUnicode) { TruffleString str = toTString.execute(inliningTarget, tobj); int datalen = codePointLengthNode.execute(str, TS_ENCODING); - retstr = encodeEmptyInput(datalen, MBENC_FLUSH, factory); + retstr = encodeEmptyInput(inliningTarget, datalen, MBENC_FLUSH); if (retstr == null) { MultibyteEncodeBuffer tmpbuf = new MultibyteEncodeBuffer(str); - retstr = encodeNode.execute(frame, inliningTarget, codec, state, tmpbuf, ERROR_STRICT, MBENC_FLUSH, - factory); + retstr = encodeNode.execute(frame, inliningTarget, codec, state, tmpbuf, ERROR_STRICT, MBENC_FLUSH); } } else { retstr = (PBytes) tobj; @@ -301,10 +301,10 @@ static int encerror(VirtualFrame frame, MultibyteCodec codec, newpos += buf.getInlen(); } } catch (PException exception) { - throw raiseNode.get(inliningTarget).raise(IndexError, POSITION_D_FROM_ERROR_HANDLER_OUT_OF_BOUNDS, newpos); + throw raiseNode.raise(inliningTarget, IndexError, POSITION_D_FROM_ERROR_HANDLER_OUT_OF_BOUNDS, newpos); } if (newpos < 0 || newpos > buf.getInlen()) { - throw raiseNode.get(inliningTarget).raise(IndexError, POSITION_D_FROM_ERROR_HANDLER_OUT_OF_BOUNDS, newpos); + throw raiseNode.raise(inliningTarget, IndexError, POSITION_D_FROM_ERROR_HANDLER_OUT_OF_BOUNDS, newpos); } buf.setInpos(newpos); @@ -326,7 +326,7 @@ static void decerror(VirtualFrame frame, MultibyteCodec codec, // MultibyteCodecState state, MultibyteDecodeBuffer buf, TruffleString errors, int e, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached BaseExceptionAttrNode attrNode, @Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray, @Cached PyUnicodeCheckNode unicodeCheckNode, @@ -334,7 +334,7 @@ static void decerror(VirtualFrame frame, MultibyteCodec codec, @Cached PyLongAsIntNode asSizeNode, @Cached CastToJavaStringNode toString, @Cached(inline = true) CallErrorCallbackNode callErrorCallbackNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleString reason = ILLEGAL_MULTIBYTE_SEQUENCE; int esize = e; @@ -349,9 +349,9 @@ static void decerror(VirtualFrame frame, MultibyteCodec codec, esize = buf.remaining(); break; case MBERR_INTERNAL: - throw raiseNode.get(inliningTarget).raise(RuntimeError, INTERNAL_CODEC_ERROR); + throw raiseNode.raise(inliningTarget, RuntimeError, INTERNAL_CODEC_ERROR); default: - throw raiseNode.get(inliningTarget).raise(RuntimeError, UNKNOWN_RUNTIME_ERROR); + throw raiseNode.raise(inliningTarget, RuntimeError, UNKNOWN_RUNTIME_ERROR); } } @@ -368,11 +368,11 @@ static void decerror(VirtualFrame frame, MultibyteCodec codec, /* use cached exception object if available */ if (buf.excobj == null) { - buf.excobj = factory.createBaseException(UnicodeDecodeError); - PBytes inbuf = buf.createPBytes(factory); + buf.excobj = PFactory.createBaseException(language, UnicodeDecodeError); + PBytes inbuf = PFactory.createBytes(language, buf.inputBuffer.array(), buf.getInpos()); TruffleString encoding = codec.encoding; Object[] args = new Object[]{encoding, inbuf, buf.getInpos(), start, end, reason}; - buf.excobj.setArgs(factory.createTuple(args)); + buf.excobj.setArgs(PFactory.createTuple(language, args)); buf.excobj.setExceptionAttributes(args); } else { attrNode.execute(buf.excobj, start, IDX_START, UNICODE_ERROR_ATTR_FACTORY); @@ -381,7 +381,7 @@ static void decerror(VirtualFrame frame, MultibyteCodec codec, } if (errors == ERROR_STRICT) { - throw raiseNode.get(inliningTarget).raiseExceptionObject(buf.excobj); + throw raiseNode.raiseExceptionObject(inliningTarget, buf.excobj); // PyCodec_StrictErrors(buf.excobj); } @@ -404,7 +404,7 @@ static void decerror(VirtualFrame frame, MultibyteCodec codec, } if (isError) { - throw raiseNode.get(inliningTarget).raise(TypeError, DECODING_ERROR_HANDLER_MUST_RETURN); + throw raiseNode.raise(inliningTarget, TypeError, DECODING_ERROR_HANDLER_MUST_RETURN); } buf.writeStr(toString.execute(retuni)); @@ -416,20 +416,19 @@ static void decerror(VirtualFrame frame, MultibyteCodec codec, newpos += buf.getInpos(); } } catch (PException ee) { - throw raiseNode.get(inliningTarget).raise(IndexError, POSITION_D_FROM_ERROR_HANDLER_OUT_OF_BOUNDS, newpos); + throw raiseNode.raise(inliningTarget, IndexError, POSITION_D_FROM_ERROR_HANDLER_OUT_OF_BOUNDS, newpos); } if (newpos > buf.getInSize()) { - throw raiseNode.get(inliningTarget).raise(IndexError, POSITION_D_FROM_ERROR_HANDLER_OUT_OF_BOUNDS, newpos); + throw raiseNode.raise(inliningTarget, IndexError, POSITION_D_FROM_ERROR_HANDLER_OUT_OF_BOUNDS, newpos); } buf.setInpos(newpos); } } - protected static PBytes encodeEmptyInput(int len, int flags, - PythonObjectFactory factory) { + protected static PBytes encodeEmptyInput(Node inliningTarget, int len, int flags) { if (len == 0 && (flags & MBENC_RESET) == 0) { - return factory.createEmptyBytes(); + return PFactory.createEmptyBytes(PythonLanguage.get(inliningTarget)); } return null; } @@ -438,22 +437,20 @@ protected static PBytes encodeEmptyInput(int len, int flags, @GenerateCached(false) abstract static class EncodeNode extends Node { - abstract PBytes execute(VirtualFrame frame, Node inliningTarget, MultibyteCodec codec, MultibyteCodecState state, MultibyteEncodeBuffer buf, Object errors, int flags, - PythonObjectFactory factory); + abstract PBytes execute(VirtualFrame frame, Node inliningTarget, MultibyteCodec codec, MultibyteCodecState state, MultibyteEncodeBuffer buf, Object errors, int flags); // multibytecodec_encode @Specialization static PBytes encode(VirtualFrame frame, Node inliningTarget, MultibyteCodec codec, MultibyteCodecState state, MultibyteEncodeBuffer buf, Object errors, int flags, - PythonObjectFactory factory, @Cached(inline = false) EncodeErrorNode encodeErrorNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { // if (buf.inlen == 0 && (flags & MBENC_RESET) == 0) { - // return factory.createBytes(EMPTY_BYTE_ARRAY); + // return PFactory.createBytes(language, EMPTY_BYTE_ARRAY); // } if (buf.getInlen() > (MAXSIZE - 16) / 2) { - throw raiseNode.get(inliningTarget).raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } while (!buf.isFull()) { @@ -486,7 +483,7 @@ static PBytes encode(VirtualFrame frame, Node inliningTarget, MultibyteCodec cod } } - return buf.createPBytes(factory); + return buf.createPBytes(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteDecodeBuffer.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteDecodeBuffer.java index 20edfb8590..265d0c66d8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteDecodeBuffer.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteDecodeBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -48,10 +48,8 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; -import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.exception.PBaseException; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -102,10 +100,6 @@ protected boolean isFull() { return !inputBuffer.hasRemaining(); } - protected PBytes createPBytes(PythonObjectFactory factory) { - return factory.createBytes(inputBuffer.array(), getInpos()); - } - @TruffleBoundary protected void replaceInbuf(byte[] inbuf) { inputBuffer = ByteBuffer.wrap(inbuf); @@ -135,7 +129,7 @@ protected TruffleString toTString() { protected void grow(Node raisingNode) { int newCapacity = 2 * writer.capacity() + 1; if (newCapacity < 0) { - throw PRaiseNode.raiseUncached(raisingNode, MemoryError); + throw PRaiseNode.raiseStatic(raisingNode, MemoryError); } CharBuffer newBuffer = CharBuffer.allocate(newCapacity); writer.flip(); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteEncodeBuffer.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteEncodeBuffer.java index 39e1b48d56..8bcaaaadce 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteEncodeBuffer.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteEncodeBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,10 +46,11 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.exception.PBaseException; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -127,7 +128,7 @@ protected void expandOutputBuffer(int esize, Node raisingNode) { int orgsize = outputBuffer.capacity(); int incsize = esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize; if (orgsize > MAXSIZE - incsize) { - throw PRaiseNode.raiseUncached(raisingNode, MemoryError); + throw PRaiseNode.raiseStatic(raisingNode, MemoryError); } ByteBuffer newBuffer = ByteBuffer.allocate(incsize); outputBuffer.flip(); @@ -138,8 +139,8 @@ protected void expandOutputBuffer(int esize, Node raisingNode) { } @TruffleBoundary - protected PBytes createPBytes(PythonObjectFactory factory) { - outobj = factory.createBytes(outputBuffer.array(), outputBuffer.position()); + protected PBytes createPBytes() { + outobj = PFactory.createBytes(PythonLanguage.get(null), outputBuffer.array(), outputBuffer.position()); return outobj; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteIncrementalDecoderBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteIncrementalDecoderBuiltins.java index 236c749107..e48b04cc2c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteIncrementalDecoderBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteIncrementalDecoderBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -48,16 +48,19 @@ import static com.oracle.graal.python.nodes.ErrorMessages.CODEC_IS_UNEXPECTED_TYPE; import static com.oracle.graal.python.nodes.ErrorMessages.PENDING_BUFFER_OVERFLOW; import static com.oracle.graal.python.nodes.ErrorMessages.PENDING_BUFFER_TOO_LARGE; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.MemoryError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.UnicodeError; +import java.math.BigInteger; import java.util.Arrays; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltins; @@ -67,6 +70,8 @@ import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.PRaiseNode; @@ -79,7 +84,7 @@ import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -93,12 +98,15 @@ @CoreFunctions(extendClasses = MultibyteIncrementalDecoder) public final class MultibyteIncrementalDecoderBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = MultibyteIncrementalDecoderBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return MultibyteIncrementalDecoderBuiltinsFactory.getFactories(); } - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, parameterNames = {"$cls", "errors"}) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, parameterNames = {"$cls", "errors"}) @GenerateNodeFactory protected abstract static class NewNode extends PythonBinaryBuiltinNode { @@ -108,18 +116,19 @@ static Object mbstreamreaderNew(VirtualFrame frame, Object type, Object err, @Cached CastToTruffleStringNode castToStringNode, @Cached PyObjectGetAttr getAttr, @Cached TruffleString.EqualNode isEqual, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { // "|s:IncrementalDecoder" + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached PRaiseNode raiseNode) { // "|s:IncrementalDecoder" TruffleString errors = null; if (err != PNone.NO_VALUE) { errors = castToStringNode.execute(inliningTarget, err); } - MultibyteIncrementalDecoderObject self = factory.createMultibyteIncrementalDecoderObject(type); + MultibyteIncrementalDecoderObject self = PFactory.createMultibyteIncrementalDecoderObject(language, type, getInstanceShape.execute(type)); Object codec = getAttr.execute(frame, inliningTarget, type, StringLiterals.T_CODEC); if (!(codec instanceof MultibyteCodecObject)) { - throw raiseNode.get(inliningTarget).raise(TypeError, CODEC_IS_UNEXPECTED_TYPE); + throw raiseNode.raise(inliningTarget, TypeError, CODEC_IS_UNEXPECTED_TYPE); } self.codec = ((MultibyteCodecObject) codec).codec; @@ -130,7 +139,8 @@ static Object mbstreamreaderNew(VirtualFrame frame, Object type, Object err, } } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self"}) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "MultibyteIncrementalDecoder", minNumOfPositionalArgs = 1, parameterNames = {"$self"}) @GenerateNodeFactory public abstract static class InitNode extends PythonUnaryBuiltinNode { @@ -160,7 +170,7 @@ protected ArgumentClinicProvider getArgumentClinic() { static Object decode(VirtualFrame frame, MultibyteIncrementalDecoderObject self, byte[] input, int end, @Bind("this") Node inliningTarget, @Cached MultibyteCodecUtil.DecodeErrorNode decodeErrorNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { byte[] data = input; int size = input.length; @@ -170,7 +180,7 @@ static Object decode(VirtualFrame frame, MultibyteIncrementalDecoderObject self, byte[] wdata = data; if (self.pendingsize != 0) { if (size > MAXSIZE - self.pendingsize) { - throw raiseNode.get(inliningTarget).raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } wsize = size + self.pendingsize; wdata = new byte[wsize]; @@ -204,11 +214,11 @@ static Object decode(VirtualFrame frame, MultibyteIncrementalDecoderObject self, static int decoderAppendPending(Node inliningTarge, MultibyteStatefulDecoderContext ctx, MultibyteDecodeBuffer buf, - PRaiseNode.Lazy raiseNode) { + PRaiseNode raiseNode) { int npendings = buf.remaining(); if (npendings + ctx.pendingsize > MAXDECPENDING || npendings > MAXSIZE - ctx.pendingsize) { - throw raiseNode.get(inliningTarge).raise(UnicodeError, PENDING_BUFFER_OVERFLOW); + throw raiseNode.raise(inliningTarge, UnicodeError, PENDING_BUFFER_OVERFLOW); } buf.getRemaining(ctx.pending, ctx.pendingsize, npendings); ctx.pendingsize += npendings; @@ -240,12 +250,12 @@ abstract static class GetStateNode extends PythonUnaryBuiltinNode { @Specialization static Object getstate(MultibyteIncrementalDecoderObject self, @Bind("this") Node inliningTarget, - @Cached HiddenAttr.WriteNode writeHiddenAttrNode, - @Cached PythonObjectFactory factory) { - PBytes buffer = factory.createBytes(Arrays.copyOf(self.pending, self.pendingsize)); - PInt statelong = factory.createInt(0); + @Bind PythonLanguage language, + @Cached HiddenAttr.WriteNode writeHiddenAttrNode) { + PBytes buffer = PFactory.createBytes(language, Arrays.copyOf(self.pending, self.pendingsize)); + PInt statelong = PFactory.createInt(language, BigInteger.ZERO); writeHiddenAttrNode.execute(inliningTarget, statelong, HiddenAttr.DECODER_OBJECT, self.state); - return factory.createTuple(new Object[]{buffer, statelong}); + return PFactory.createTuple(language, new Object[]{buffer, statelong}); } } @@ -266,7 +276,7 @@ static Object setstate(VirtualFrame frame, MultibyteIncrementalDecoderObject sel @Cached HiddenAttr.ReadNode readHiddenAttrNode, @Cached BytesNodes.ToBytesNode toBytesNode, @Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object[] array = getArray.execute(inliningTarget, state.getSequenceStorage()); Object buffer = array[0]; Object statelong = array[1]; @@ -274,7 +284,7 @@ static Object setstate(VirtualFrame frame, MultibyteIncrementalDecoderObject sel byte[] bufferstr = toBytesNode.execute(frame, buffer); int buffersize = bufferstr.length; if (buffersize > MAXDECPENDING) { - throw raiseNode.get(inliningTarget).raise(UnicodeError, PENDING_BUFFER_TOO_LARGE); + throw raiseNode.raise(inliningTarget, UnicodeError, PENDING_BUFFER_TOO_LARGE); } self.pendingsize = buffersize; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteIncrementalEncoderBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteIncrementalEncoderBuiltins.java index 8b13e3d60d..b71edd6a1a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteIncrementalEncoderBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteIncrementalEncoderBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -50,8 +50,6 @@ import static com.oracle.graal.python.nodes.ErrorMessages.COULDN_T_CONVERT_THE_OBJECT_TO_STR; import static com.oracle.graal.python.nodes.ErrorMessages.PENDING_BUFFER_OVERFLOW; import static com.oracle.graal.python.nodes.ErrorMessages.PENDING_BUFFER_TOO_LARGE; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.nodes.StringLiterals.T_STRICT; import static com.oracle.graal.python.nodes.StringLiterals.T_UTF8; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; @@ -65,7 +63,11 @@ import java.nio.charset.StandardCharsets; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltins; @@ -74,6 +76,8 @@ import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.ints.IntNodes; import com.oracle.graal.python.builtins.objects.ints.PInt; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.lib.PyObjectStrAsObjectNode; import com.oracle.graal.python.lib.PyUnicodeCheckNode; @@ -87,7 +91,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -107,12 +111,15 @@ public final class MultibyteIncrementalEncoderBuiltins extends PythonBuiltins { private static final int MAXENCPENDING = 2; + public static final TpSlots SLOTS = MultibyteIncrementalEncoderBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return MultibyteIncrementalEncoderBuiltinsFactory.getFactories(); } - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, parameterNames = {"$cls", "errors"}) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, parameterNames = {"$cls", "errors"}) @GenerateNodeFactory protected abstract static class NewNode extends PythonBinaryBuiltinNode { @@ -122,19 +129,20 @@ static Object mbstreamreaderNew(VirtualFrame frame, Object type, Object err, @Cached CastToTruffleStringNode castToStringNode, @Cached PyObjectGetAttr getAttr, @Cached TruffleString.EqualNode isEqual, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { // "|s:IncrementalEncoder" + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached PRaiseNode raiseNode) { // "|s:IncrementalEncoder" TruffleString errors = null; if (err != PNone.NO_VALUE) { errors = castToStringNode.execute(inliningTarget, err); } - MultibyteIncrementalEncoderObject self = factory.createMultibyteIncrementalEncoderObject(type); + MultibyteIncrementalEncoderObject self = PFactory.createMultibyteIncrementalEncoderObject(language, type, getInstanceShape.execute(type)); Object codec = getAttr.execute(frame, inliningTarget, type, StringLiterals.T_CODEC); if (!(codec instanceof MultibyteCodecObject)) { - throw raiseNode.get(inliningTarget).raise(TypeError, CODEC_IS_UNEXPECTED_TYPE); + throw raiseNode.raise(inliningTarget, TypeError, CODEC_IS_UNEXPECTED_TYPE); } self.codec = ((MultibyteCodecObject) codec).codec; @@ -145,7 +153,8 @@ static Object mbstreamreaderNew(VirtualFrame frame, Object type, Object err, } } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self"}) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "MultibyteIncrementalEncoder", minNumOfPositionalArgs = 1, parameterNames = {"$self"}) @GenerateNodeFactory public abstract static class InitNode extends PythonUnaryBuiltinNode { @@ -159,19 +168,17 @@ static PNone init(@SuppressWarnings("unused") MultibyteIncrementalEncoderObject @SuppressWarnings("truffle-inlining") // footprint reduction 44 -> 25 protected abstract static class EncodeStatefulNode extends Node { - abstract Object execute(VirtualFrame frame, MultibyteStatefulEncoderContext ctx, Object unistr, int end, - PythonObjectFactory factory); + abstract Object execute(VirtualFrame frame, MultibyteStatefulEncoderContext ctx, Object unistr, int end); // encoder_encode_stateful @Specialization static Object ts(VirtualFrame frame, MultibyteStatefulEncoderContext ctx, TruffleString ucvt, int end, - PythonObjectFactory factory, @Bind("this") Node inliningTarget, @Exclusive @Cached MultibyteCodecUtil.EncodeNode encodeNode, @Shared @Cached TruffleString.ConcatNode concatNode, @Shared @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Shared @Cached TruffleString.SubstringNode substringNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { TruffleString inbuf = ucvt; TruffleString origpending = null; if (ctx.pending != null) { @@ -183,16 +190,15 @@ static Object ts(VirtualFrame frame, MultibyteStatefulEncoderContext ctx, Truffl int datalen = codePointLengthNode.execute(inbuf, TS_ENCODING); PBytes r; try { - r = encodeEmptyInput(datalen, MBENC_FLUSH | MBENC_RESET, factory); + r = encodeEmptyInput(inliningTarget, datalen, MBENC_FLUSH | MBENC_RESET); if (r == null) { MultibyteEncodeBuffer buf = new MultibyteEncodeBuffer(inbuf); r = encodeNode.execute(frame, inliningTarget, ctx.codec, ctx.state, buf, - ctx.errors, end != 0 ? MBENC_FLUSH | MBENC_RESET : 0, - factory); + ctx.errors, end != 0 ? MBENC_FLUSH | MBENC_RESET : 0); if (buf.getInpos() < datalen) { if (datalen - buf.getInpos() > MAXENCPENDING) { /* normal codecs can't reach here */ - throw raiseNode.get(inliningTarget).raise(UnicodeError, PENDING_BUFFER_OVERFLOW); + throw raiseNode.raise(inliningTarget, UnicodeError, PENDING_BUFFER_OVERFLOW); } ctx.pending = substringNode.execute(inbuf, buf.getInpos(), datalen, TS_ENCODING, false); } @@ -208,7 +214,6 @@ static Object ts(VirtualFrame frame, MultibyteStatefulEncoderContext ctx, Truffl @Specialization(guards = "!isTruffleString(unistr)") static Object notTS(VirtualFrame frame, MultibyteStatefulEncoderContext ctx, Object unistr, int end, - PythonObjectFactory factory, @Bind("this") Node inliningTarget, @Cached PyObjectStrAsObjectNode strNode, @Cached PyUnicodeCheckNode unicodeCheckNode, @@ -217,16 +222,16 @@ static Object notTS(VirtualFrame frame, MultibyteStatefulEncoderContext ctx, Obj @Shared @Cached TruffleString.ConcatNode concatNode, @Shared @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Shared @Cached TruffleString.SubstringNode substringNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { Object ucvt = unistr; if (!unicodeCheckNode.execute(inliningTarget, unistr)) { ucvt = strNode.execute(frame, inliningTarget, unistr); if (!unicodeCheckNode.execute(inliningTarget, unistr)) { - throw raiseNode.get(inliningTarget).raise(TypeError, COULDN_T_CONVERT_THE_OBJECT_TO_STR); + throw raiseNode.raise(inliningTarget, TypeError, COULDN_T_CONVERT_THE_OBJECT_TO_STR); } } TruffleString str = toTruffleStringNode.execute(inliningTarget, ucvt); - return ts(frame, ctx, str, end, factory, inliningTarget, encodeNode, concatNode, codePointLengthNode, substringNode, raiseNode); + return ts(frame, ctx, str, end, inliningTarget, encodeNode, concatNode, codePointLengthNode, substringNode, raiseNode); } } @@ -244,9 +249,8 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static Object encode(VirtualFrame frame, MultibyteStatefulEncoderContext ctx, Object unistr, int end, - @Cached EncodeStatefulNode encodeStatefulNode, - @Cached PythonObjectFactory factory) { - return encodeStatefulNode.execute(frame, ctx, unistr, end, factory); + @Cached EncodeStatefulNode encodeStatefulNode) { + return encodeStatefulNode.execute(frame, ctx, unistr, end); } } @@ -261,7 +265,7 @@ static Object getstate(MultibyteIncrementalEncoderObject self, @Cached HiddenAttr.WriteNode writeHiddenAttrNode, @Cached CodecsModuleBuiltins.CodecsEncodeToJavaBytesNode asUTF8AndSize, @Cached IntNodes.PyLongFromByteArray fromByteArray, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { /* * state made up of 1 byte for buffer size, up to MAXENCPENDING*4 bytes for UTF-8 * encoded buffer (each character can use up to 4 bytes), and required bytes for @@ -276,7 +280,7 @@ static Object getstate(MultibyteIncrementalEncoderObject self, byte[] pendingbuffer = asUTF8AndSize.execute(self.pending, T_UTF8, T_STRICT); int pendingsize = pendingbuffer.length; if (pendingsize > MAXENCPENDING * 4) { - throw raiseNode.get(inliningTarget).raise(UnicodeError, PENDING_BUFFER_TOO_LARGE); + throw raiseNode.raise(inliningTarget, UnicodeError, PENDING_BUFFER_TOO_LARGE); } statebytes[0] = (byte) pendingsize; PythonUtils.arraycopy(pendingbuffer, 0, statebytes, 1, pendingsize); @@ -303,13 +307,13 @@ static Object setstate(MultibyteIncrementalEncoderObject self, PInt statelong, @Bind("this") Node inliningTarget, @Cached HiddenAttr.ReadNode readHiddenAttrNode, @Cached IntNodes.PyLongAsByteArray asByteArray, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int sizeOfStateBytes = 1 + MAXENCPENDING * 4 + MULTIBYTECODECSTATE; byte[] statebytes = asByteArray.execute(inliningTarget, statelong, sizeOfStateBytes, false); if (statebytes[0] > MAXENCPENDING * 4) { - throw raiseNode.get(inliningTarget).raise(UnicodeError, PENDING_BUFFER_TOO_LARGE); + throw raiseNode.raise(inliningTarget, UnicodeError, PENDING_BUFFER_TOO_LARGE); } self.pending = decodeUTF8(statebytes, 1, statebytes[0]); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamReaderBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamReaderBuiltins.java index 3603962382..bca771eabb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamReaderBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamReaderBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,15 +46,17 @@ import static com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteIncrementalDecoderBuiltins.DecodeNode.decoderFeedBuffer; import static com.oracle.graal.python.builtins.modules.cjkcodecs.MultibytecodecModuleBuiltins.MBERR_TOOFEW; import static com.oracle.graal.python.nodes.ErrorMessages.CODEC_IS_UNEXPECTED_TYPE; -import static com.oracle.graal.python.nodes.ErrorMessages.STREAM_FUNCTION_RETURNED_A_NON_BYTES_OBJECT_S; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; +import static com.oracle.graal.python.nodes.ErrorMessages.STREAM_FUNCTION_RETURNED_A_NON_BYTES_OBJECT_P; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltins; @@ -62,6 +64,7 @@ import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.str.StringBuiltins; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyBytesCheckNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; @@ -74,9 +77,8 @@ import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -91,12 +93,15 @@ @CoreFunctions(extendClasses = MultibyteStreamReader) public final class MultibyteStreamReaderBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = MultibyteStreamReaderBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return MultibyteStreamReaderBuiltinsFactory.getFactories(); } - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 2, parameterNames = {"$cls", "stream", "errors"}) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 2, parameterNames = {"$cls", "stream", "errors"}) @GenerateNodeFactory protected abstract static class NewNode extends PythonTernaryBuiltinNode { @@ -106,18 +111,19 @@ static Object mbstreamreaderNew(VirtualFrame frame, Object type, Object stream, @Cached CastToTruffleStringNode castToStringNode, @Cached PyObjectGetAttr getAttr, @Cached TruffleString.EqualNode isEqual, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { // "O|s:StreamReader" + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached PRaiseNode raiseNode) { // "O|s:StreamReader" TruffleString errors = null; if (err != PNone.NO_VALUE) { errors = castToStringNode.execute(inliningTarget, err); } - MultibyteStreamReaderObject self = factory.createMultibyteStreamReaderObject(type); + MultibyteStreamReaderObject self = PFactory.createMultibyteStreamReaderObject(language, type, getInstanceShape.execute(type)); Object codec = getAttr.execute(frame, inliningTarget, type, StringLiterals.T_CODEC); if (!(codec instanceof MultibyteCodecObject)) { - throw raiseNode.get(inliningTarget).raise(TypeError, CODEC_IS_UNEXPECTED_TYPE); + throw raiseNode.raise(inliningTarget, TypeError, CODEC_IS_UNEXPECTED_TYPE); } self.codec = ((MultibyteCodecObject) codec).codec; @@ -129,7 +135,8 @@ static Object mbstreamreaderNew(VirtualFrame frame, Object type, Object stream, } } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self"}) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "MultibyteStreamReader", minNumOfPositionalArgs = 1, parameterNames = {"$self"}) @GenerateNodeFactory public abstract static class InitNode extends PythonUnaryBuiltinNode { @@ -149,12 +156,10 @@ abstract static class IReadNode extends PNodeWithContext { static TruffleString iread(VirtualFrame frame, MultibyteStreamReaderObject self, TruffleString method, long sizehint, @Bind("this") Node inliningTarget, @Cached PyObjectCallMethodObjArgs callMethod, - @Cached GetClassNode getClassNode, @Cached PyBytesCheckNode bytesCheckNode, @Cached BytesNodes.ToBytesNode toBytesNode, - @Cached TypeNodes.GetNameNode getNameNode, @Cached MultibyteCodecUtil.DecodeErrorNode decodeErrorNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (sizehint == 0) { return T_EMPTY_STRING; @@ -169,9 +174,8 @@ static TruffleString iread(VirtualFrame frame, MultibyteStreamReaderObject self, } if (!(cres instanceof PBytes)) { - Object crestType = getClassNode.execute(inliningTarget, cres); - if (!bytesCheckNode.execute(inliningTarget, crestType)) { - throw raiseNode.get(inliningTarget).raise(TypeError, STREAM_FUNCTION_RETURNED_A_NON_BYTES_OBJECT_S, getNameNode.execute(inliningTarget, cres)); + if (!bytesCheckNode.execute(inliningTarget, cres)) { + throw raiseNode.raise(inliningTarget, TypeError, STREAM_FUNCTION_RETURNED_A_NON_BYTES_OBJECT_P, cres); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamWriterBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamWriterBuiltins.java index 22cabe1b6c..6a9caa43ce 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamWriterBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamWriterBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,14 +47,16 @@ import static com.oracle.graal.python.builtins.modules.cjkcodecs.MultibytecodecModuleBuiltins.MBENC_FLUSH; import static com.oracle.graal.python.nodes.ErrorMessages.ARG_MUST_BE_A_SEQUENCE_OBJECT; import static com.oracle.graal.python.nodes.ErrorMessages.CODEC_IS_UNEXPECTED_TYPE; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltins; @@ -62,6 +64,8 @@ import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.common.SequenceNodes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.nodes.PRaiseNode; @@ -71,7 +75,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.dsl.Bind; @@ -87,6 +91,8 @@ @CoreFunctions(extendClasses = MultibyteStreamWriter) public final class MultibyteStreamWriterBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = MultibyteStreamWriterBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return MultibyteStreamWriterBuiltinsFactory.getFactories(); @@ -94,7 +100,8 @@ protected List> getNodeFa private static final TruffleString WRITE = tsLiteral("write"); - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory protected abstract static class NewNode extends PythonBuiltinNode { @@ -104,18 +111,19 @@ static Object mbstreamwriterNew(VirtualFrame frame, Object type, Object stream, @Cached CastToTruffleStringNode castToStringNode, @Cached PyObjectGetAttr getAttr, @Cached TruffleString.EqualNode isEqual, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { // "O|s:StreamWriter" + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached PRaiseNode raiseNode) { // "O|s:StreamWriter" TruffleString errors = null; if (err != PNone.NO_VALUE) { errors = castToStringNode.execute(inliningTarget, err); } - MultibyteStreamWriterObject self = factory.createMultibyteStreamWriterObject(type); + MultibyteStreamWriterObject self = PFactory.createMultibyteStreamWriterObject(language, type, getInstanceShape.execute(type)); Object codec = getAttr.execute(frame, inliningTarget, type, StringLiterals.T_CODEC); if (!(codec instanceof MultibyteCodecObject)) { - throw raiseNode.get(inliningTarget).raise(TypeError, CODEC_IS_UNEXPECTED_TYPE); + throw raiseNode.raise(inliningTarget, TypeError, CODEC_IS_UNEXPECTED_TYPE); } self.codec = ((MultibyteCodecObject) codec).codec; @@ -128,7 +136,8 @@ static Object mbstreamwriterNew(VirtualFrame frame, Object type, Object stream, } } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self"}) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "MultibyteStreamWriter", minNumOfPositionalArgs = 1, parameterNames = {"$self"}) @GenerateNodeFactory public abstract static class InitNode extends PythonUnaryBuiltinNode { @@ -147,10 +156,9 @@ abstract static class WriteNode extends PythonBinaryBuiltinNode { static Object write(VirtualFrame frame, MultibyteStreamWriterObject self, Object strobj, @Bind("this") Node inliningTarget, @Cached MultibyteIncrementalEncoderBuiltins.EncodeStatefulNode encodeStatefulNode, - @Cached PyObjectCallMethodObjArgs callMethod, - @Cached PythonObjectFactory factory) { + @Cached PyObjectCallMethodObjArgs callMethod) { // mbstreamwriter_iwrite - Object str = encodeStatefulNode.execute(frame, self, strobj, 0, factory); + Object str = encodeStatefulNode.execute(frame, self, strobj, 0); callMethod.execute(frame, inliningTarget, self.stream, WRITE, str); return PNone.NONE; } @@ -167,15 +175,14 @@ static Object writelines(VirtualFrame frame, MultibyteStreamWriterObject self, P @Cached MultibyteIncrementalEncoderBuiltins.EncodeStatefulNode encodeStatefulNode, @Cached SequenceNodes.GetSequenceStorageNode getStorage, @Cached SequenceStorageNodes.GetItemNode getItem, - @Cached PyObjectCallMethodObjArgs callMethod, - @Cached PythonObjectFactory factory) { + @Cached PyObjectCallMethodObjArgs callMethod) { SequenceStorage sq = getStorage.execute(inliningTarget, lines); for (int i = 0; i < sq.length(); i++) { /* length can be changed even within this loop */ Object strobj = getItem.execute(sq, i); // mbstreamwriter_iwrite - Object str = encodeStatefulNode.execute(frame, self, strobj, 0, factory); + Object str = encodeStatefulNode.execute(frame, self, strobj, 0); callMethod.execute(frame, inliningTarget, self.stream, WRITE, str); } return PNone.NONE; @@ -184,8 +191,8 @@ static Object writelines(VirtualFrame frame, MultibyteStreamWriterObject self, P // assuming !pySequenceCheck.execute(lines) @Fallback static Object writelines(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object lines, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ARG_MUST_BE_A_SEQUENCE_OBJECT); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ARG_MUST_BE_A_SEQUENCE_OBJECT); } } @@ -199,18 +206,16 @@ static Object reset(VirtualFrame frame, MultibyteStreamWriterObject self, @Bind("this") Node inliningTarget, @Cached PyObjectCallMethodObjArgs callMethod, @Cached TruffleString.CodePointLengthNode codePointLengthNode, - @Cached MultibyteCodecUtil.EncodeNode encodeNode, - @Cached PythonObjectFactory factory) { + @Cached MultibyteCodecUtil.EncodeNode encodeNode) { if (self.pending == null) { return PNone.NONE; } int datalen = codePointLengthNode.execute(self.pending, TS_ENCODING); - PBytes pwrt = encodeEmptyInput(datalen, MBENC_FLUSH | MBENC_RESET, factory); + PBytes pwrt = encodeEmptyInput(inliningTarget, datalen, MBENC_FLUSH | MBENC_RESET); if (pwrt == null) { MultibyteEncodeBuffer buf = new MultibyteEncodeBuffer(self.pending); pwrt = encodeNode.execute(frame, inliningTarget, self.codec, self.state, buf, - self.errors, MBENC_FLUSH | MBENC_RESET, - factory); + self.errors, MBENC_FLUSH | MBENC_RESET); } /* * some pending buffer can be truncated when UnicodeEncodeError is raised on 'strict' diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibytecodecModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibytecodecModuleBuiltins.java index e4dfad8bc4..0089eb2fcb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibytecodecModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibytecodecModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -50,10 +50,10 @@ import java.nio.charset.Charset; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.modules.cjkcodecs.DBCSMap.MappingType; import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteCodec.CodecType; @@ -62,7 +62,7 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.CharsetMapping; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -99,7 +99,7 @@ protected List> getNodeFa protected static void registerCodec(String name, int cidx, CodecType ct, int midx, MappingType mt, DBCSMap[] maps, MultibyteCodec[] codecs, - PythonModule codec, PythonObjectFactory factory) { + PythonModule codec, PythonLanguage language) { TruffleString tsName = toTruffleStringUncached(name); TruffleString normalizedEncoding = CharsetMapping.normalizeUncached(tsName); Charset charset = CharsetMapping.getCharsetNormalized(normalizedEncoding); @@ -110,7 +110,7 @@ protected static void registerCodec(String name, int cidx, CodecType ct, int mid if (midx != -1) { DBCSMap h = maps[midx] = new DBCSMap(name, tsName, charset, mt); codec.setAttribute(toTruffleStringUncached(h.charsetMapName), - factory.createCapsuleJavaName(h, PyMultibyteCodec_CAPSULE_NAME)); + PFactory.createCapsuleJavaName(language, h, PyMultibyteCodec_CAPSULE_NAME)); } } } @@ -127,27 +127,25 @@ abstract static class CreateCodecNode extends PythonUnaryBuiltinNode { @Specialization static Object createCodec(PyCapsule arg, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - return createCodec(inliningTarget, arg, factory, raiseNode); + @Cached PRaiseNode raiseNode) { + return createCodec(inliningTarget, arg, raiseNode); } static Object createCodec(Node inliningTarget, PyCapsule arg, - PythonObjectFactory factory, - PRaiseNode.Lazy raiseNode) { + PRaiseNode raiseNode) { if (!PyCapsule.capsuleJavaNameIs(arg, PyMultibyteCodec_CAPSULE_NAME)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ARGUMENT_TYPE_INVALID); + throw raiseNode.raise(inliningTarget, ValueError, ARGUMENT_TYPE_INVALID); } MultibyteCodec codec; codec = (MultibyteCodec) arg.getPointer(); codec.codecinit(); - return factory.createMultibyteCodecObject(PythonBuiltinClassType.MultibyteCodec, codec); + return PFactory.createMultibyteCodecObject(PythonLanguage.get(inliningTarget), codec); } @Fallback static Object createCodec(@SuppressWarnings("unused") VirtualFrame frame, @SuppressWarnings("unused") Object arg, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ARGUMENT_TYPE_INVALID); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ARGUMENT_TYPE_INVALID); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/CharmapNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/CharmapNodes.java index 3d876912c4..813b5abc0e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/CharmapNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/CharmapNodes.java @@ -83,7 +83,7 @@ import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.ByteArrayBuilder; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -120,11 +120,10 @@ static Object doIt(VirtualFrame frame, Node inliningTarget, TruffleString map, @Cached(inline = false) TruffleString.CodePointLengthNode codePointLengthNode, @Cached(inline = false) TruffleString.CodePointAtIndexNode codePointAtIndexNode, @Cached(inline = false) HashingStorageSetItem setItemNode, - @Cached PRaiseNode.Lazy raiseNode, - @Cached(inline = false) PythonObjectFactory factory) { + @Cached PRaiseNode raiseNode) { int len = Math.min(codePointLengthNode.execute(map, TS_ENCODING), 256); if (len == 0) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); } byte[] level1 = new byte[32]; byte[] level2 = new byte[512]; @@ -134,12 +133,12 @@ static Object doIt(VirtualFrame frame, Node inliningTarget, TruffleString map, Arrays.fill(level1, (byte) 0xFF); Arrays.fill(level2, (byte) 0xFF); if (codePointAtIndexNode.execute(map, 0, TS_ENCODING, ErrorHandling.BEST_EFFORT) != 0) { - return doDict(frame, inliningTarget, map, len, codePointAtIndexNode, setItemNode, factory); + return doDict(frame, inliningTarget, map, len, codePointAtIndexNode, setItemNode); } for (int i = 1; i < len; ++i) { int cp = codePointAtIndexNode.execute(map, i, TS_ENCODING, ErrorHandling.BEST_EFFORT); if (cp == 0 || cp > 0xFFFF) { - return doDict(frame, inliningTarget, map, len, codePointAtIndexNode, setItemNode, factory); + return doDict(frame, inliningTarget, map, len, codePointAtIndexNode, setItemNode); } if (cp == 0xFFFE) { continue; @@ -154,7 +153,7 @@ static Object doIt(VirtualFrame frame, Node inliningTarget, TruffleString map, } } if (count2 >= 0xFF || count3 >= 0xFF) { - return doDict(frame, inliningTarget, map, len, codePointAtIndexNode, setItemNode, factory); + return doDict(frame, inliningTarget, map, len, codePointAtIndexNode, setItemNode); } byte[] level23 = new byte[16 * count2 + 128 * count3]; @@ -176,17 +175,16 @@ static Object doIt(VirtualFrame frame, Node inliningTarget, TruffleString map, int i3 = 128 * (level23[i2] & 0xFF) + o3; level23[l3Start + i3] = (byte) i; } - return factory.createEncodingMap(count2, count3, level1, level23); + return PFactory.createEncodingMap(PythonLanguage.get(inliningTarget), count2, count3, level1, level23); } - private static Object doDict(VirtualFrame frame, Node inliningTarget, TruffleString map, int len, TruffleString.CodePointAtIndexNode codePointAtIndexNode, HashingStorageSetItem setItemNode, - PythonObjectFactory factory) { + private static Object doDict(VirtualFrame frame, Node inliningTarget, TruffleString map, int len, TruffleString.CodePointAtIndexNode codePointAtIndexNode, HashingStorageSetItem setItemNode) { HashingStorage store = PDict.createNewStorage(len); for (int i = 0; i < len; ++i) { int cp = codePointAtIndexNode.execute(map, i, TS_ENCODING, ErrorHandling.BEST_EFFORT); store = setItemNode.execute(frame, inliningTarget, store, cp, i); } - return factory.createDict(store); + return PFactory.createDict(PythonLanguage.get(inliningTarget), store); } } @@ -198,9 +196,9 @@ public abstract static class PyUnicodeEncodeCharmapNode extends Node { @Specialization static byte[] doLatin1(TruffleString src, TruffleString errors, PNone mapping, - @Cached(inline = false) PRaiseNode raiseNode) { + @Bind("this") Node inliningTarget) { // TODO latin1 - throw raiseNode.raise(NotImplementedError, toTruffleStringUncached("latin1")); + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, toTruffleStringUncached("latin1")); } @Fallback @@ -330,7 +328,7 @@ static Object doIt(VirtualFrame frame, Node inliningTarget, int cp, Object mappi @Cached PyLongCheckNode pyLongCheckNode, @Cached PyLongAsLongNode pyLongAsLongNode, @Cached PyBytesCheckNode pyBytesCheckNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object item; try { item = pyObjectGetItemNode.execute(frame, inliningTarget, mapping, cp); @@ -344,14 +342,14 @@ static Object doIt(VirtualFrame frame, Node inliningTarget, int cp, Object mappi if (pyLongCheckNode.execute(inliningTarget, item)) { long value = pyLongAsLongNode.execute(frame, inliningTarget, item); if (value < 0 || value > 255) { - raiseNode.get(inliningTarget).raise(TypeError, CHARACTER_MAPPING_MUST_BE_IN_RANGE_256); + raiseNode.raise(inliningTarget, TypeError, CHARACTER_MAPPING_MUST_BE_IN_RANGE_256); } return value; } if (pyBytesCheckNode.execute(inliningTarget, item)) { return item; } - throw raiseNode.get(inliningTarget).raise(TypeError, CHARACTER_MAPPING_MUST_RETURN_INT_BYTES_OR_NONE_NOT_P, item); + throw raiseNode.raise(inliningTarget, TypeError, CHARACTER_MAPPING_MUST_RETURN_INT_BYTES_OR_NONE_NOT_P, item); } } @@ -465,7 +463,7 @@ static TruffleString decodeGenericMapping(VirtualFrame frame, Object data, Truff @Cached InlinedConditionProfile longValuesProfile, @Cached InlinedConditionProfile strValuesProfile, @Cached InlinedConditionProfile errProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { // equivalent of charmap_decode_mapping PythonContext context = PythonContext.get(inliningTarget); PythonLanguage language = context.getLanguage(inliningTarget); @@ -503,7 +501,7 @@ static TruffleString decodeGenericMapping(VirtualFrame frame, Object data, Truff break; } if (value < 0 || value > Character.MAX_CODE_POINT) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CHARACTER_MAPPING_MUST_BE_IN_RANGE, PInt.toHexString(Character.MAX_CODE_POINT + 1)); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CHARACTER_MAPPING_MUST_BE_IN_RANGE, PInt.toHexString(Character.MAX_CODE_POINT + 1)); } else { appendCodePointNode.execute(tsb, (int) value, 1, true); } @@ -520,7 +518,7 @@ static TruffleString decodeGenericMapping(VirtualFrame frame, Object data, Truff appendStringNode.execute(tsb, castToTruffleStringNode.execute(inliningTarget, item)); } } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CHARACTER_MAPPING_MUST_RETURN_INT_NONE_OR_STR); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CHARACTER_MAPPING_MUST_RETURN_INT_NONE_OR_STR); } } } finally { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/CodecsRegistry.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/CodecsRegistry.java index 205bbde344..66ff758337 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/CodecsRegistry.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/CodecsRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -93,7 +93,7 @@ public abstract static class PyCodecLookupErrorNode extends Node { @Specialization static Object lookup(Node inliningTarget, TruffleString name, @Cached InlinedConditionProfile resultProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { PythonContext context = PythonContext.get(inliningTarget); ensureRegistryInitialized(context); if (name == null) { @@ -101,7 +101,7 @@ static Object lookup(Node inliningTarget, TruffleString name, } Object result = getErrorHandler(context, name); if (resultProfile.profile(inliningTarget, result == null)) { - throw raiseNode.get(inliningTarget).raise(LookupError, UNKNOWN_ERROR_HANDLER, name); + throw raiseNode.raise(inliningTarget, LookupError, UNKNOWN_ERROR_HANDLER, name); } return result; } @@ -124,9 +124,8 @@ static void register(Node inliningTarget, TruffleString name, Object handler, @Specialization(guards = "!callableCheckNode.execute(inliningTarget, handler)") static void registerNoCallable(@SuppressWarnings("unused") Node inliningTarget, @SuppressWarnings("unused") TruffleString name, @SuppressWarnings("unused") Object handler, - @SuppressWarnings("unused") @Cached @Shared("callableCheck") PyCallableCheckNode callableCheckNode, - @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, HANDLER_MUST_BE_CALLABLE); + @SuppressWarnings("unused") @Cached @Shared("callableCheck") PyCallableCheckNode callableCheckNode) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, HANDLER_MUST_BE_CALLABLE); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java index 4b7db4d338..112036bd11 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java @@ -60,6 +60,7 @@ import java.nio.ByteOrder; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.modules.codecs.CodecsRegistry.PyCodecLookupErrorNode; @@ -91,7 +92,7 @@ import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.ValueType; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -257,8 +258,8 @@ static boolean isNeither(Node inliningTarget, Object o, PyObjectTypeCheck pyObje return !isDecode(inliningTarget, o, pyObjectTypeCheck) && !isEncode(inliningTarget, o, pyObjectTypeCheck) && !isTranslate(inliningTarget, o, pyObjectTypeCheck); } - static PException wrongExceptionType(Object o, PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.DONT_KNOW_HOW_TO_HANDLE_P_IN_ERROR_CALLBACK, o); + static PException wrongExceptionType(Node inliningTarget, Object o) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DONT_KNOW_HOW_TO_HANDLE_P_IN_ERROR_CALLBACK, o); } } @@ -267,14 +268,14 @@ static PException wrongExceptionType(Object o, PRaiseNode raiseNode) { abstract static class StrictErrorHandlerNode extends ErrorHandlerBaseNode { @Specialization static Object doException(PBaseException exception, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raiseExceptionObject(exception); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseExceptionObject(inliningTarget, exception); } @Fallback static Object doFallback(@SuppressWarnings("unused") Object o, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CODEC_MUST_PASS_EXCEPTION_INSTANCE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CODEC_MUST_PASS_EXCEPTION_INSTANCE); } } @@ -284,27 +285,26 @@ abstract static class IgnoreErrorHandlerNode extends ErrorHandlerBaseNode { @Specialization(guards = "isDecode(inliningTarget, exception, pyObjectTypeCheck)", limit = "1") static Object doDecodeException(PBaseException exception, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, - @Cached PyUnicodeDecodeErrorGetEndNode getEndNode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createTuple(new Object[]{T_EMPTY_STRING, getEndNode.execute(inliningTarget, exception)}); + @Cached PyUnicodeDecodeErrorGetEndNode getEndNode) { + return PFactory.createTuple(language, new Object[]{T_EMPTY_STRING, getEndNode.execute(inliningTarget, exception)}); } @Specialization(guards = "isEncodeOrTranslate(inliningTarget, exception, pyObjectTypeCheck)", limit = "1") static Object doEncodeOrTranslateException(PBaseException exception, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, - @Cached PyUnicodeEncodeOrTranslateErrorGetEndNode getEndNode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createTuple(new Object[]{T_EMPTY_STRING, getEndNode.execute(inliningTarget, exception)}); + @Cached PyUnicodeEncodeOrTranslateErrorGetEndNode getEndNode) { + return PFactory.createTuple(language, new Object[]{T_EMPTY_STRING, getEndNode.execute(inliningTarget, exception)}); } @Specialization(guards = "isNeither(inliningTarget, o, pyObjectTypeCheck)", limit = "1") static Object doFallback(Object o, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, - @Cached PRaiseNode raiseNode) { - throw wrongExceptionType(o, raiseNode); + @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck) { + throw wrongExceptionType(inliningTarget, o); } } @@ -317,35 +317,34 @@ abstract static class ReplaceErrorHandlerNode extends ErrorHandlerBaseNode { @Specialization(guards = "isDecode(inliningTarget, exception, pyObjectTypeCheck)", limit = "1") static Object doDecodeException(PBaseException exception, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, - @Cached PyUnicodeDecodeErrorGetEndNode getEndNode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createTuple(new Object[]{T_REPLACEMENT, getEndNode.execute(inliningTarget, exception)}); + @Cached PyUnicodeDecodeErrorGetEndNode getEndNode) { + return PFactory.createTuple(language, new Object[]{T_REPLACEMENT, getEndNode.execute(inliningTarget, exception)}); } @Specialization(guards = "isEncodeOrTranslate(inliningTarget, exception, pyObjectTypeCheck)", limit = "1") static Object doEncodeOrTranslateException(PBaseException exception, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, @Cached PyUnicodeEncodeOrTranslateErrorGetStartNode getStartNode, @Cached PyUnicodeEncodeOrTranslateErrorGetEndNode getEndNode, - @Cached TruffleString.RepeatNode repeatNode, - @Shared @Cached PythonObjectFactory factory) { + @Cached TruffleString.RepeatNode repeatNode) { TruffleString replacement = isEncode(inliningTarget, exception, pyObjectTypeCheck) ? T_QUESTIONMARK : T_REPLACEMENT; int start = getStartNode.execute(inliningTarget, exception); int end = getEndNode.execute(inliningTarget, exception); int n = end - start; // CPython raises SystemError for negative values, we return an empty string TruffleString result = n < 1 ? T_EMPTY_STRING : repeatNode.execute(replacement, n, TS_ENCODING); - return factory.createTuple(new Object[]{result, end}); + return PFactory.createTuple(language, new Object[]{result, end}); } @Specialization(guards = "isNeither(inliningTarget, o, pyObjectTypeCheck)", limit = "1") static Object doFallback(Object o, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, - @Cached PRaiseNode raiseNode) { - throw wrongExceptionType(o, raiseNode); + @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck) { + throw wrongExceptionType(inliningTarget, o); } } @@ -356,14 +355,14 @@ abstract static class XmlCharRefReplaceErrorHandlerNode extends ErrorHandlerBase @Specialization(guards = "isEncode(inliningTarget, exception, pyObjectTypeCheck)", limit = "1") static Object doEncode(PBaseException exception, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, @Cached PyUnicodeEncodeOrTranslateErrorGetObjectNode getObjectNode, @Cached PyUnicodeEncodeOrTranslateErrorGetStartNode getStartNode, @Cached PyUnicodeEncodeOrTranslateErrorGetEndNode getEndNode, @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, @Cached TruffleString.FromByteArrayNode fromByteArrayNode, - @Cached TruffleString.SwitchEncodingNode switchEncodingNode, - @Cached PythonObjectFactory factory) { + @Cached TruffleString.SwitchEncodingNode switchEncodingNode) { TruffleString src = getObjectNode.execute(inliningTarget, exception); int start = getStartNode.execute(inliningTarget, exception); int end = getEndNode.execute(inliningTarget, exception); @@ -377,15 +376,14 @@ static Object doEncode(PBaseException exception, pos = appendXmlCharRefReplacement(replacement, pos, codePointAtIndexNode.execute(src, i, TS_ENCODING, ErrorHandling.BEST_EFFORT)); } TruffleString resultAscii = fromByteArrayNode.execute(replacement, Encoding.US_ASCII, false); - return factory.createTuple(new Object[]{switchEncodingNode.execute(resultAscii, TS_ENCODING), end}); + return PFactory.createTuple(language, new Object[]{switchEncodingNode.execute(resultAscii, TS_ENCODING), end}); } @Specialization(guards = "!isEncode(inliningTarget, o, pyObjectTypeCheck)", limit = "1") static Object doFallback(Object o, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, - @Cached PRaiseNode raiseNode) { - throw wrongExceptionType(o, raiseNode); + @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck) { + throw wrongExceptionType(inliningTarget, o); } } @@ -396,6 +394,7 @@ abstract static class BackslashReplaceErrorHandlerNode extends ErrorHandlerBaseN @Specialization(guards = "isDecode(inliningTarget, exception, pyObjectTypeCheck)", limit = "1") static Object doDecodeException(VirtualFrame frame, PBaseException exception, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached("createFor(this)") IndirectCallData indirectCallData, @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, @Cached PyUnicodeDecodeErrorGetObjectNode getObjectNode, @@ -404,13 +403,12 @@ static Object doDecodeException(VirtualFrame frame, PBaseException exception, @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, @CachedLibrary(limit = "3") PythonBufferAccessLibrary accessLib, @Cached @Shared TruffleString.FromByteArrayNode fromByteArrayNode, - @Cached @Shared TruffleString.SwitchEncodingNode switchEncodingNode, - @Shared @Cached PythonObjectFactory factory) { + @Cached @Shared TruffleString.SwitchEncodingNode switchEncodingNode) { int start = getStartNode.execute(inliningTarget, exception); int end = getEndNode.execute(inliningTarget, exception); Object object = getObjectNode.execute(inliningTarget, exception); if (start >= end) { - return factory.createTuple(new Object[]{T_EMPTY_STRING, end}); + return PFactory.createTuple(language, new Object[]{T_EMPTY_STRING, end}); } byte[] replacement = new byte[4 * (end - start)]; int pos = 0; @@ -424,25 +422,25 @@ static Object doDecodeException(VirtualFrame frame, PBaseException exception, accessLib.release(srcBuf, frame, indirectCallData); } TruffleString resultAscii = fromByteArrayNode.execute(replacement, Encoding.US_ASCII, false); - return factory.createTuple(new Object[]{switchEncodingNode.execute(resultAscii, TS_ENCODING), end}); + return PFactory.createTuple(language, new Object[]{switchEncodingNode.execute(resultAscii, TS_ENCODING), end}); } @Specialization(guards = "isEncodeOrTranslate(inliningTarget, exception, pyObjectTypeCheck)", limit = "1") static Object doEncodeOrTranslateException(PBaseException exception, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, @Cached PyUnicodeEncodeOrTranslateErrorGetObjectNode getObjectNode, @Cached PyUnicodeEncodeOrTranslateErrorGetStartNode getStartNode, @Cached PyUnicodeEncodeOrTranslateErrorGetEndNode getEndNode, @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, @Cached @Shared TruffleString.FromByteArrayNode fromByteArrayNode, - @Cached @Shared TruffleString.SwitchEncodingNode switchEncodingNode, - @Shared @Cached PythonObjectFactory factory) { + @Cached @Shared TruffleString.SwitchEncodingNode switchEncodingNode) { int start = getStartNode.execute(inliningTarget, exception); int end = getEndNode.execute(inliningTarget, exception); TruffleString src = getObjectNode.execute(inliningTarget, exception); if (start >= end) { - return factory.createTuple(new Object[]{T_EMPTY_STRING, end}); + return PFactory.createTuple(language, new Object[]{T_EMPTY_STRING, end}); } int len = 0; for (int i = start; i < end; ++i) { @@ -462,15 +460,14 @@ static Object doEncodeOrTranslateException(PBaseException exception, pos = BytesUtils.unicodeNonAsciiEscape(cp, pos, replacement, true); } TruffleString resultAscii = fromByteArrayNode.execute(replacement, Encoding.US_ASCII, false); - return factory.createTuple(new Object[]{switchEncodingNode.execute(resultAscii, TS_ENCODING), end}); + return PFactory.createTuple(language, new Object[]{switchEncodingNode.execute(resultAscii, TS_ENCODING), end}); } @Specialization(guards = "isNeither(inliningTarget, o, pyObjectTypeCheck)", limit = "1") static Object doFallback(Object o, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, - @Cached PRaiseNode raiseNode) { - throw wrongExceptionType(o, raiseNode); + @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck) { + throw wrongExceptionType(inliningTarget, o); } } @@ -481,6 +478,7 @@ abstract static class NameReplaceErrorHandlerNode extends ErrorHandlerBaseNode { @Specialization(guards = "isEncode(inliningTarget, exception, pyObjectTypeCheck)", limit = "1") static Object doEncode(PBaseException exception, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, @Cached PyUnicodeEncodeOrTranslateErrorGetObjectNode getObjectNode, @Cached PyUnicodeEncodeOrTranslateErrorGetStartNode getStartNode, @@ -491,13 +489,12 @@ static Object doEncode(PBaseException exception, @Cached TruffleString.FromJavaStringNode fromJavaStringNode, @Cached TruffleStringBuilder.AppendStringNode appendStringNode, @Cached TruffleStringBuilder.AppendCodePointNode appendCodePointNode, - @Cached TruffleStringBuilder.ToStringNode toStringNode, - @Cached PythonObjectFactory factory) { + @Cached TruffleStringBuilder.ToStringNode toStringNode) { TruffleString src = getObjectNode.execute(inliningTarget, exception); int start = getStartNode.execute(inliningTarget, exception); int end = getEndNode.execute(inliningTarget, exception); if (start >= end) { - return factory.createTuple(new Object[]{T_EMPTY_STRING, start}); + return PFactory.createTuple(language, new Object[]{T_EMPTY_STRING, start}); } TruffleStringBuilder tsb = TruffleStringBuilder.create(TS_ENCODING); byte[] buf = new byte[1 + 1 + 8]; // \UNNNNNNNN @@ -515,15 +512,14 @@ static Object doEncode(PBaseException exception, appendStringNode.execute(tsb, switchEncodingNode.execute(fromByteArrayNode.execute(buf, 0, len, Encoding.US_ASCII, true), TS_ENCODING)); } } - return factory.createTuple(new Object[]{toStringNode.execute(tsb), end}); + return PFactory.createTuple(language, new Object[]{toStringNode.execute(tsb), end}); } @Specialization(guards = "!isEncode(inliningTarget, o, pyObjectTypeCheck)", limit = "1") static Object doFallback(Object o, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, - @Cached PRaiseNode raiseNode) { - throw wrongExceptionType(o, raiseNode); + @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck) { + throw wrongExceptionType(inliningTarget, o); } } @@ -534,6 +530,7 @@ abstract static class SurrogatePassErrorHandlerNode extends ErrorHandlerBaseNode @Specialization(guards = "isEncode(inliningTarget, exception, pyObjectTypeCheck)", limit = "1") static Object doEncode(PBaseException exception, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @SuppressWarnings("unused") @Exclusive @Cached PyObjectTypeCheck pyObjectTypeCheck, @Cached PyUnicodeEncodeOrTranslateErrorGetObjectNode getObjectNode, @Cached PyUnicodeEncodeOrTranslateErrorGetStartNode getStartNode, @@ -541,35 +538,35 @@ static Object doEncode(PBaseException exception, @Cached PyUnicodeEncodeErrorGetEncodingNode getEncodingNode, @Exclusive @Cached GetStandardEncodingNode getStandardEncodingNode, @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { int start = getStartNode.execute(inliningTarget, exception); int end = getEndNode.execute(inliningTarget, exception); TruffleString src = getObjectNode.execute(inliningTarget, exception); TruffleString encodingName = getEncodingNode.execute(inliningTarget, exception); StandardEncoding encoding = getStandardEncodingNode.execute(inliningTarget, encodingName); if (encoding == StandardEncoding.UNKNOWN) { - throw raiseNode.get(inliningTarget).raiseExceptionObject(exception); + throw raiseNode.raiseExceptionObject(inliningTarget, exception); } if (start >= end) { - return factory.createTuple(new Object[]{factory.createBytes(new byte[0]), end}); + return PFactory.createTuple(language, new Object[]{PFactory.createBytes(language, new byte[0]), end}); } byte[] result = new byte[encoding.byteLength * (end - start)]; int pos = 0; for (int i = start; i < end; ++i) { int cp = codePointAtIndexNode.execute(src, i, TS_ENCODING, ErrorHandling.BEST_EFFORT); if (!isSurrogate(cp)) { - throw raiseNode.get(inliningTarget).raiseExceptionObject(exception); + throw raiseNode.raiseExceptionObject(inliningTarget, exception); } encodeCodepoint(encoding, result, pos, cp); pos += encoding.byteLength; } - return factory.createTuple(new Object[]{factory.createBytes(result), end}); + return PFactory.createTuple(language, new Object[]{PFactory.createBytes(language, result), end}); } @Specialization(guards = "isDecode(inliningTarget, exception, pyObjectTypeCheck)", limit = "1") static Object doDecode(VirtualFrame frame, PBaseException exception, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached("createFor(this)") IndirectCallData indirectCallData, @SuppressWarnings("unused") @Exclusive @Cached PyObjectTypeCheck pyObjectTypeCheck, @Cached PyUnicodeDecodeErrorGetObjectNode getObjectNode, @@ -580,15 +577,14 @@ static Object doDecode(VirtualFrame frame, PBaseException exception, @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, @CachedLibrary(limit = "3") PythonBufferAccessLibrary accessLib, @Cached TruffleString.FromCodePointNode fromCodePointNode, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { int start = getStartNode.execute(inliningTarget, exception); getEndNode.execute(inliningTarget, exception); // called for side effects only Object object = getObjectNode.execute(inliningTarget, exception); TruffleString encodingName = getEncodingNode.execute(inliningTarget, exception); StandardEncoding encoding = getStandardEncodingNode.execute(inliningTarget, encodingName); if (encoding == StandardEncoding.UNKNOWN) { - throw raiseNode.get(inliningTarget).raiseExceptionObject(exception); + throw raiseNode.raiseExceptionObject(inliningTarget, exception); } Object srcBuf = acquireLib.acquireReadonly(object, frame, indirectCallData); try { @@ -598,9 +594,9 @@ static Object doDecode(VirtualFrame frame, PBaseException exception, cp = decodeCodepoint(encoding, accessLib.getInternalOrCopiedByteArray(srcBuf), start); } if (!isSurrogate(cp)) { - throw raiseNode.get(inliningTarget).raiseExceptionObject(exception); + throw raiseNode.raiseExceptionObject(inliningTarget, exception); } - return factory.createTuple(new Object[]{fromCodePointNode.execute(cp, TS_ENCODING, true), start + encoding.byteLength}); + return PFactory.createTuple(language, new Object[]{fromCodePointNode.execute(cp, TS_ENCODING, true), start + encoding.byteLength}); } finally { accessLib.release(srcBuf, frame, indirectCallData); } @@ -609,9 +605,8 @@ static Object doDecode(VirtualFrame frame, PBaseException exception, @Specialization(guards = "!isEncodeOrDecode(inliningTarget, o, pyObjectTypeCheck)", limit = "1") static Object doFallback(Object o, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, - @Cached PRaiseNode raiseNode) { - throw wrongExceptionType(o, raiseNode); + @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck) { + throw wrongExceptionType(inliningTarget, o); } private static void encodeCodepoint(StandardEncoding encoding, byte[] result, int pos, int cp) { @@ -671,34 +666,35 @@ abstract static class SurrogateEscapeErrorHandlerNode extends ErrorHandlerBaseNo @Specialization(guards = "isEncode(inliningTarget, exception, pyObjectTypeCheck)", limit = "1") static Object doEncode(PBaseException exception, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @SuppressWarnings("unused") @Exclusive @Cached PyObjectTypeCheck pyObjectTypeCheck, @Cached PyUnicodeEncodeOrTranslateErrorGetObjectNode getObjectNode, @Cached PyUnicodeEncodeOrTranslateErrorGetStartNode getStartNode, @Cached PyUnicodeEncodeOrTranslateErrorGetEndNode getEndNode, @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { int start = getStartNode.execute(inliningTarget, exception); int end = getEndNode.execute(inliningTarget, exception); TruffleString src = getObjectNode.execute(inliningTarget, exception); if (start >= end) { - return factory.createTuple(new Object[]{factory.createBytes(new byte[0]), end}); + return PFactory.createTuple(language, new Object[]{PFactory.createBytes(language, new byte[0]), end}); } byte[] result = new byte[end - start]; int pos = 0; for (int i = start; i < end; ++i) { int cp = codePointAtIndexNode.execute(src, i, TS_ENCODING, ErrorHandling.BEST_EFFORT); if (cp < 0xdc80 || cp > 0xdcff) { - throw raiseNode.get(inliningTarget).raiseExceptionObject(exception); + throw raiseNode.raiseExceptionObject(inliningTarget, exception); } result[pos++] = (byte) (cp - 0xdc00); } - return factory.createTuple(new Object[]{factory.createBytes(result), end}); + return PFactory.createTuple(language, new Object[]{PFactory.createBytes(language, result), end}); } @Specialization(guards = "isDecode(inliningTarget, exception, pyObjectTypeCheck)", limit = "1") static Object doDecode(VirtualFrame frame, PBaseException exception, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached("createFor(this)") IndirectCallData indirectCallData, @SuppressWarnings("unused") @Exclusive @Cached PyObjectTypeCheck pyObjectTypeCheck, @Cached PyUnicodeDecodeErrorGetObjectNode getObjectNode, @@ -708,8 +704,7 @@ static Object doDecode(VirtualFrame frame, PBaseException exception, @CachedLibrary(limit = "3") PythonBufferAccessLibrary accessLib, @Cached TruffleStringBuilder.AppendCodePointNode appendCodePointNode, @Cached TruffleStringBuilder.ToStringNode toStringNode, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { int start = getStartNode.execute(inliningTarget, exception); int end = getEndNode.execute(inliningTarget, exception); Object object = getObjectNode.execute(inliningTarget, exception); @@ -727,9 +722,9 @@ static Object doDecode(VirtualFrame frame, PBaseException exception, consumed++; } if (consumed == 0) { - throw raiseNode.get(inliningTarget).raiseExceptionObject(exception); + throw raiseNode.raiseExceptionObject(inliningTarget, exception); } - return factory.createTuple(new Object[]{toStringNode.execute(tsb), start + consumed}); + return PFactory.createTuple(language, new Object[]{toStringNode.execute(tsb), start + consumed}); } finally { accessLib.release(srcBuf, frame, indirectCallData); } @@ -738,9 +733,8 @@ static Object doDecode(VirtualFrame frame, PBaseException exception, @Specialization(guards = "!isEncodeOrDecode(inliningTarget, o, pyObjectTypeCheck)", limit = "1") static Object doFallback(Object o, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, - @Cached PRaiseNode raiseNode) { - throw wrongExceptionType(o, raiseNode); + @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck) { + throw wrongExceptionType(inliningTarget, o); } } @@ -860,9 +854,9 @@ static DecodingErrorHandlerResult doTuple(Node inliningTarget, PTuple result, @Cached SequenceNodes.GetObjectArrayNode getObjectArrayNode, @Cached CastToTruffleStringCheckedNode castToTruffleStringCheckedNode, @Cached CastToJavaIntExactNode castToJavaIntExactNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (lenNode.execute(inliningTarget, result) != 2) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.DECODING_ERROR_HANDLER_MUST_RETURN_STR_INT_TUPLE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.DECODING_ERROR_HANDLER_MUST_RETURN_STR_INT_TUPLE); } Object[] array = getObjectArrayNode.execute(inliningTarget, result); TruffleString str = castToTruffleStringCheckedNode.cast(inliningTarget, array[0], ErrorMessages.DECODING_ERROR_HANDLER_MUST_RETURN_STR_INT_TUPLE); @@ -871,9 +865,8 @@ static DecodingErrorHandlerResult doTuple(Node inliningTarget, PTuple result, } @Fallback - static DecodingErrorHandlerResult doOther(@SuppressWarnings("unused") Object result, - @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.DECODING_ERROR_HANDLER_MUST_RETURN_STR_INT_TUPLE); + static DecodingErrorHandlerResult doOther(Node inliningTarget, @SuppressWarnings("unused") Object result) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.DECODING_ERROR_HANDLER_MUST_RETURN_STR_INT_TUPLE); } } @@ -894,7 +887,7 @@ static DecodingErrorHandlerResult doIt(VirtualFrame frame, Node inliningTarget, @Cached ParseDecodingErrorHandlerResultNode parseResultNode, @Cached PyUnicodeDecodeErrorGetObjectNode getObjectNode, @Cached PyObjectSizeNode sizeNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { cache.errorHandlerObject = cache.errorHandlerObject == null ? lookupErrorNode.execute(inliningTarget, errors) : cache.errorHandlerObject; cache.exceptionObject = makeDecodeExceptionNode.execute(frame, inliningTarget, cache.exceptionObject, encoding, srcObj, startPos, endPos, reason); Object resultObj = callNode.execute(frame, cache.errorHandlerObject, cache.exceptionObject); @@ -931,9 +924,9 @@ static EncodingErrorHandlerResult doTuple(Node inliningTarget, PTuple result, @Cached CastToJavaIntExactNode castToJavaIntExactNode, @Cached PyUnicodeCheckNode pyUnicodeCheckNode, @Cached PyBytesCheckNode pyBytesCheckNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (lenNode.execute(inliningTarget, result) != 2) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ENCODING_ERROR_HANDLER_MUST_RETURN_STR_BYTES_INT_TUPLE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ENCODING_ERROR_HANDLER_MUST_RETURN_STR_BYTES_INT_TUPLE); } Object[] array = getObjectArrayNode.execute(inliningTarget, result); boolean isUnicode; @@ -942,16 +935,15 @@ static EncodingErrorHandlerResult doTuple(Node inliningTarget, PTuple result, } else if (pyBytesCheckNode.execute(inliningTarget, array[0])) { isUnicode = false; } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ENCODING_ERROR_HANDLER_MUST_RETURN_STR_BYTES_INT_TUPLE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ENCODING_ERROR_HANDLER_MUST_RETURN_STR_BYTES_INT_TUPLE); } int pos = castToJavaIntExactNode.execute(inliningTarget, array[1]); return new EncodingErrorHandlerResult(array[0], pos, isUnicode); } @Fallback - static EncodingErrorHandlerResult doOther(@SuppressWarnings("unused") Object result, - @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.ENCODING_ERROR_HANDLER_MUST_RETURN_STR_BYTES_INT_TUPLE); + static EncodingErrorHandlerResult doOther(Node inliningTarget, @SuppressWarnings("unused") Object result) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ENCODING_ERROR_HANDLER_MUST_RETURN_STR_BYTES_INT_TUPLE); } } @@ -971,7 +963,7 @@ static EncodingErrorHandlerResult doIt(VirtualFrame frame, Node inliningTarget, @Cached(inline = false) CallNode callNode, @Cached ParseEncodingErrorHandlerResultNode parseResultNode, @Cached(inline = false) TruffleString.CodePointLengthNode codePointLengthNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { cache.errorHandlerObject = cache.errorHandlerObject == null ? lookupErrorNode.execute(inliningTarget, errors) : cache.errorHandlerObject; int len = codePointLengthNode.execute(srcObj, TS_ENCODING); cache.exceptionObject = makeEncodeExceptionNode.execute(frame, inliningTarget, cache.exceptionObject, encoding, srcObj, startPos, endPos, reason); @@ -992,18 +984,18 @@ abstract static class RaiseEncodeException extends Node { @Specialization static void doIt(VirtualFrame frame, Node inliningTarget, ErrorHandlerCache cache, TruffleString encoding, TruffleString srcObj, int startPos, int endPos, TruffleString reason, @Cached MakeEncodeExceptionNode makeEncodeExceptionNode, - @Cached(inline = false) PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode) { cache.exceptionObject = makeEncodeExceptionNode.execute(frame, inliningTarget, cache.exceptionObject, encoding, srcObj, startPos, endPos, reason); raiseNode.raiseExceptionObject(cache.exceptionObject); } } - private static int adjustAndCheckPos(int newPos, int len, Node inliningTarget, PRaiseNode.Lazy raiseNode) { + private static int adjustAndCheckPos(int newPos, int len, Node inliningTarget, PRaiseNode raiseNode) { if (newPos < 0) { newPos += len; } if (newPos < 0 || newPos > len) { - throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.POSITION_D_FROM_ERROR_HANDLER_OUT_OF_BOUNDS, newPos); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.POSITION_D_FROM_ERROR_HANDLER_OUT_OF_BOUNDS, newPos); } return newPos; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVDialectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVDialectBuiltins.java index 358b23b4dc..1c3baa3c4b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVDialectBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVDialectBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,37 +41,398 @@ package com.oracle.graal.python.builtins.modules.csv; import static com.oracle.graal.python.builtins.modules.csv.CSVModuleBuiltins.J_ATTR_DELIMITER; -import static com.oracle.graal.python.builtins.modules.csv.CSVModuleBuiltins.J_ATTR_DOUBLEQUOTE; -import static com.oracle.graal.python.builtins.modules.csv.CSVModuleBuiltins.J_ATTR_ESCAPECHAR; -import static com.oracle.graal.python.builtins.modules.csv.CSVModuleBuiltins.J_ATTR_LINETERMINATOR; -import static com.oracle.graal.python.builtins.modules.csv.CSVModuleBuiltins.J_ATTR_QUOTECHAR; -import static com.oracle.graal.python.builtins.modules.csv.CSVModuleBuiltins.J_ATTR_QUOTING; -import static com.oracle.graal.python.builtins.modules.csv.CSVModuleBuiltins.J_ATTR_SKIPINITIALSPACE; -import static com.oracle.graal.python.builtins.modules.csv.CSVModuleBuiltins.J_ATTR_STRICT; import static com.oracle.graal.python.builtins.modules.csv.CSVModuleBuiltins.NOT_SET_CODEPOINT; +import static com.oracle.graal.python.builtins.modules.csv.CSVModuleBuiltins.T__CSV; +import static com.oracle.graal.python.builtins.modules.csv.QuoteStyle.QUOTE_MINIMAL; +import static com.oracle.graal.python.builtins.modules.csv.QuoteStyle.QUOTE_NONE; +import static com.oracle.graal.python.nodes.StringLiterals.J_STRICT; +import static com.oracle.graal.python.nodes.StringLiterals.T_COMMA; +import static com.oracle.graal.python.nodes.StringLiterals.T_CRLF; +import static com.oracle.graal.python.nodes.StringLiterals.T_DOUBLE_QUOTE; +import static com.oracle.graal.python.nodes.StringLiterals.T_STRICT; +import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; +import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; +import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.module.PythonModule; +import com.oracle.graal.python.builtins.objects.str.PString; +import com.oracle.graal.python.builtins.objects.type.PythonClass; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.lib.PyLongAsIntNode; +import com.oracle.graal.python.lib.PyLongCheckExactNode; +import com.oracle.graal.python.lib.PyObjectIsTrueNode; +import com.oracle.graal.python.lib.PyObjectLookupAttr; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.nodes.util.CannotCastException; +import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; +import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @CoreFunctions(extendClasses = PythonBuiltinClassType.CSVDialect) public final class CSVDialectBuiltins extends PythonBuiltins { + private static final String J_ATTR_DOUBLEQUOTE = "doublequote"; + private static final String J_ATTR_ESCAPECHAR = "escapechar"; + private static final String J_ATTR_LINETERMINATOR = "lineterminator"; + private static final String J_ATTR_QUOTING = "quoting"; + private static final String J_ATTR_QUOTECHAR = "quotechar"; + private static final String J_ATTR_SKIPINITIALSPACE = "skipinitialspace"; + private static final String J_ATTR_STRICT = J_STRICT; + private static final TruffleString T_ATTR_SKIPINITIALSPACE = tsLiteral(J_ATTR_SKIPINITIALSPACE); + private static final TruffleString T_ATTR_QUOTECHAR = tsLiteral(J_ATTR_QUOTECHAR); + private static final TruffleString T_ATTR_QUOTING = tsLiteral(J_ATTR_QUOTING); + private static final TruffleString T_ATTR_LINETERMINATOR = tsLiteral(J_ATTR_LINETERMINATOR); + private static final TruffleString T_ATTR_ESCAPECHAR = tsLiteral(J_ATTR_ESCAPECHAR); + private static final TruffleString T_ATTR_DOUBLEQUOTE = tsLiteral(J_ATTR_DOUBLEQUOTE); + private static final TruffleString T_ATTR_DELIMITER = tsLiteral(J_ATTR_DELIMITER); + private static final TruffleString T_ATTR_STRICT = T_STRICT; + private static final TruffleString T_NOT_SET = tsLiteral("NOT_SET"); + + public static final TpSlots SLOTS = CSVDialectBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return CSVDialectBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "CSVDialect", parameterNames = {"class", "dialect", "delimiter", "doublequote", "escapechar", + "lineterminator", "quotechar", + "quoting", "skipinitialspace", "strict"}) + @GenerateNodeFactory + public abstract static class DialectNode extends PythonBuiltinNode { + + @Specialization + @SuppressWarnings("unused") + static Object doCSVDialectWithoutKeywords(PythonBuiltinClassType cls, CSVDialect dialect, PNone delimiter, PNone doublequote, PNone escapechar, + PNone lineterminator, PNone quotechar, PNone quoting, PNone skipinitialspace, PNone strict) { + return dialect; + } + + @Specialization + @SuppressWarnings("unused") + static CSVDialect doStringWithoutKeywords(VirtualFrame frame, PythonBuiltinClassType cls, TruffleString dialectName, PNone delimiter, PNone doublequote, PNone escapechar, + PNone lineterminator, PNone quotechar, PNone quoting, PNone skipinitialspace, PNone strict, + @Bind("this") Node inliningTarget, + @Exclusive @Cached CSVModuleBuiltins.CSVGetDialectNode getDialect) { + PythonModule module = PythonContext.get(inliningTarget).lookupBuiltinModule(T__CSV); + return getDialect.execute(frame, module, dialectName); + } + + @Specialization + static Object doNoDialectObj(VirtualFrame frame, PythonBuiltinClassType cls, @SuppressWarnings("unused") PNone dialectObj, Object delimiterObj, Object doublequoteObj, Object escapecharObj, + Object lineterminatorObj, Object quotecharObj, Object quotingObj, Object skipinitialspaceObj, Object strictObj, + @Bind("this") Node inliningTarget, + @Exclusive @Cached PyObjectIsTrueNode isTrueNode, + @Exclusive @Cached PyLongCheckExactNode pyLongCheckExactNode, + @Exclusive @Cached PyLongAsIntNode pyLongAsIntNode, + @Exclusive @Cached PRaiseNode raiseNode) { + return createCSVDialect(frame, inliningTarget, cls, delimiterObj, doublequoteObj, escapecharObj, lineterminatorObj, + quotecharObj, quotingObj, skipinitialspaceObj, strictObj, isTrueNode, pyLongCheckExactNode, pyLongAsIntNode, raiseNode); + } + + @Specialization + static Object doStringWithKeywords(VirtualFrame frame, PythonBuiltinClassType cls, TruffleString dialectName, Object delimiterObj, Object doublequoteObj, Object escapecharObj, + Object lineterminatorObj, Object quotecharObj, Object quotingObj, Object skipinitialspaceObj, Object strictObj, + @Bind("this") Node inliningTarget, + @Exclusive @Cached CSVModuleBuiltins.CSVGetDialectNode getDialect, + @Exclusive @Cached PyObjectIsTrueNode isTrueNode, + @Exclusive @Cached PyLongCheckExactNode pyLongCheckExactNode, + @Exclusive @Cached PyLongAsIntNode pyLongAsIntNode, + @Exclusive @Cached PRaiseNode raiseNode) { + PythonModule module = PythonContext.get(inliningTarget).lookupBuiltinModule(T__CSV); + CSVDialect dialectObj = getDialect.execute(frame, module, dialectName); + + if (delimiterObj == PNone.NO_VALUE) { + delimiterObj = dialectObj.delimiter; + } + if (doublequoteObj == PNone.NO_VALUE) { + doublequoteObj = dialectObj.doubleQuote; + } + if (escapecharObj == PNone.NO_VALUE) { + escapecharObj = dialectObj.escapeChar; + } + if (lineterminatorObj == PNone.NO_VALUE) { + lineterminatorObj = dialectObj.lineTerminator; + } + if (quotingObj == PNone.NO_VALUE) { + quotingObj = dialectObj.quoting; + } + if (quotecharObj == PNone.NO_VALUE) { + quotecharObj = dialectObj.quoteChar; + } + if (skipinitialspaceObj == PNone.NO_VALUE) { + skipinitialspaceObj = dialectObj.skipInitialSpace; + } + if (strictObj == PNone.NO_VALUE) { + strictObj = dialectObj.strict; + } + + return createCSVDialect(frame, inliningTarget, cls, delimiterObj, doublequoteObj, escapecharObj, lineterminatorObj, + quotecharObj, quotingObj, skipinitialspaceObj, strictObj, isTrueNode, pyLongCheckExactNode, pyLongAsIntNode, raiseNode); + } + + @Specialization + static Object doDialectClassWithKeywords(VirtualFrame frame, PythonBuiltinClassType cls, PythonClass dialectObj, Object delimiterObj, Object doublequoteObj, Object escapecharObj, + Object lineterminatorObj, Object quotecharObj, Object quotingObj, Object skipinitialspaceObj, Object strictObj, + @Bind("this") Node inliningTarget, + @Exclusive @Cached PyObjectLookupAttr getFirstAttributesNode, + @Exclusive @Cached PyObjectLookupAttr getSecondAttributesNode, + @Exclusive @Cached PyObjectLookupAttr getThirdAttributesNode, + @Exclusive @Cached PyObjectIsTrueNode isTrueNode, + @Exclusive @Cached PyLongCheckExactNode pyLongCheckExactNode, + @Exclusive @Cached PyLongAsIntNode pyLongAsIntNode, + @Exclusive @Cached PRaiseNode raiseNode) { + + // We use multiple AttributeNodes to be able to cache all attributes as current + // CACHE_SIZE is 3. + delimiterObj = getAttributeValue(frame, inliningTarget, dialectObj, delimiterObj, T_ATTR_DELIMITER, getFirstAttributesNode); + doublequoteObj = getAttributeValue(frame, inliningTarget, dialectObj, doublequoteObj, T_ATTR_DOUBLEQUOTE, getFirstAttributesNode); + escapecharObj = getAttributeValue(frame, inliningTarget, dialectObj, escapecharObj, T_ATTR_ESCAPECHAR, getFirstAttributesNode); + lineterminatorObj = getAttributeValue(frame, inliningTarget, dialectObj, lineterminatorObj, T_ATTR_LINETERMINATOR, getSecondAttributesNode); + quotecharObj = getAttributeValue(frame, inliningTarget, dialectObj, quotecharObj, T_ATTR_QUOTECHAR, getSecondAttributesNode); + quotingObj = getAttributeValue(frame, inliningTarget, dialectObj, quotingObj, T_ATTR_QUOTING, getSecondAttributesNode); + skipinitialspaceObj = getAttributeValue(frame, inliningTarget, dialectObj, skipinitialspaceObj, T_ATTR_SKIPINITIALSPACE, getThirdAttributesNode); + strictObj = getAttributeValue(frame, inliningTarget, dialectObj, strictObj, T_ATTR_STRICT, getThirdAttributesNode); + + return createCSVDialect(frame, inliningTarget, cls, delimiterObj, doublequoteObj, escapecharObj, lineterminatorObj, + quotecharObj, quotingObj, skipinitialspaceObj, strictObj, isTrueNode, pyLongCheckExactNode, pyLongAsIntNode, raiseNode); + } + + @Specialization + static Object doPStringWithKeywords(VirtualFrame frame, PythonBuiltinClassType cls, PString dialectName, Object delimiterObj, Object doublequoteObj, Object escapecharObj, + Object lineterminatorObj, Object quotecharObj, Object quotingObj, Object skipinitialspaceObj, Object strictObj, + @Bind("this") Node inliningTarget, + @Exclusive @Cached CSVModuleBuiltins.CSVGetDialectNode getDialect, + @Cached CastToTruffleStringNode castToStringNode, + @Exclusive @Cached PyObjectIsTrueNode isTrueNode, + @Exclusive @Cached PyLongCheckExactNode pyLongCheckExactNode, + @Exclusive @Cached PyLongAsIntNode pyLongAsIntNode, + @Exclusive @Cached PRaiseNode raiseNode) { + + TruffleString dialectNameStr = castToStringNode.execute(inliningTarget, dialectName); + PythonModule module = PythonContext.get(inliningTarget).lookupBuiltinModule(T__CSV); + CSVDialect dialectObj = getDialect.execute(frame, module, dialectNameStr); + + if (delimiterObj == PNone.NO_VALUE) { + delimiterObj = dialectObj.delimiter; + } + if (doublequoteObj == PNone.NO_VALUE) { + doublequoteObj = dialectObj.doubleQuote; + } + if (escapecharObj == PNone.NO_VALUE) { + escapecharObj = dialectObj.escapeChar; + } + if (lineterminatorObj == PNone.NO_VALUE) { + lineterminatorObj = dialectObj.lineTerminator; + } + if (quotingObj == PNone.NO_VALUE) { + quotingObj = dialectObj.quoting; + } + if (quotecharObj == PNone.NO_VALUE) { + quotecharObj = dialectObj.quoteChar; + } + if (skipinitialspaceObj == PNone.NO_VALUE) { + skipinitialspaceObj = dialectObj.skipInitialSpace; + } + if (strictObj == PNone.NO_VALUE) { + strictObj = dialectObj.strict; + } + + return createCSVDialect(frame, inliningTarget, cls, delimiterObj, doublequoteObj, escapecharObj, lineterminatorObj, + quotecharObj, quotingObj, skipinitialspaceObj, strictObj, isTrueNode, pyLongCheckExactNode, pyLongAsIntNode, raiseNode); + } + + @Specialization(guards = {"!isCSVDialect(dialectObj)", "!isPythonClass(dialectObj)", "!isString(dialectObj)", "!isPNone(dialectObj)"}) + static Object doGeneric(VirtualFrame frame, Object cls, Object dialectObj, Object delimiterObj, Object doublequoteObj, Object escapecharObj, Object lineterminatorObj, + Object quotecharObj, Object quotingObj, Object skipinitialspaceObj, Object strictObj, + @Bind("this") Node inliningTarget, + @Exclusive @Cached PyObjectLookupAttr getFirstAttributesNode, + @Exclusive @Cached PyObjectLookupAttr getSecondAttributesNode, + @Exclusive @Cached PyObjectLookupAttr getThirdAttributesNode, + @Exclusive @Cached PyObjectIsTrueNode isTrueNode, + @Exclusive @Cached PyLongCheckExactNode pyLongCheckExactNode, + @Exclusive @Cached PyLongAsIntNode pyLongAsIntNode, + @Exclusive @Cached PRaiseNode raiseNode) { + + delimiterObj = getAttributeValue(frame, inliningTarget, dialectObj, delimiterObj, T_ATTR_DELIMITER, getFirstAttributesNode); + doublequoteObj = getAttributeValue(frame, inliningTarget, dialectObj, doublequoteObj, T_ATTR_DOUBLEQUOTE, getFirstAttributesNode); + escapecharObj = getAttributeValue(frame, inliningTarget, dialectObj, escapecharObj, T_ATTR_ESCAPECHAR, getFirstAttributesNode); + lineterminatorObj = getAttributeValue(frame, inliningTarget, dialectObj, lineterminatorObj, T_ATTR_LINETERMINATOR, getSecondAttributesNode); + quotingObj = getAttributeValue(frame, inliningTarget, dialectObj, quotingObj, T_ATTR_QUOTING, getSecondAttributesNode); + quotecharObj = getAttributeValue(frame, inliningTarget, dialectObj, quotecharObj, T_ATTR_QUOTECHAR, getSecondAttributesNode); + skipinitialspaceObj = getAttributeValue(frame, inliningTarget, dialectObj, skipinitialspaceObj, T_ATTR_SKIPINITIALSPACE, getThirdAttributesNode); + strictObj = getAttributeValue(frame, inliningTarget, dialectObj, strictObj, T_ATTR_STRICT, getThirdAttributesNode); + + return createCSVDialect(frame, inliningTarget, cls, delimiterObj, doublequoteObj, escapecharObj, lineterminatorObj, + quotecharObj, quotingObj, skipinitialspaceObj, strictObj, isTrueNode, pyLongCheckExactNode, pyLongAsIntNode, raiseNode); + } + + protected static boolean isCSVDialect(Object dialect) { + return dialect instanceof CSVDialect; + } + + private static Object createCSVDialect(VirtualFrame frame, Node inliningTarget, Object cls, Object delimiterObj, Object doublequoteObj, Object escapecharObj, + Object lineterminatorObj, Object quotecharObj, Object quotingObj, Object skipinitialspaceObj, Object strictObj, + PyObjectIsTrueNode isTrueNode, PyLongCheckExactNode pyLongCheckExactNode, PyLongAsIntNode pyLongAsIntNode, PRaiseNode raiseNode) { + TruffleString delimiter = getChar(inliningTarget, T_ATTR_DELIMITER, delimiterObj, T_COMMA, false); + boolean doubleQuote = getBoolean(frame, doublequoteObj, true, isTrueNode); + TruffleString escapeChar = getChar(inliningTarget, T_ATTR_ESCAPECHAR, escapecharObj, T_NOT_SET, true); + TruffleString lineTerminator = getString(inliningTarget, T_ATTR_LINETERMINATOR, lineterminatorObj, T_CRLF); + TruffleString quoteChar = getChar(inliningTarget, T_ATTR_QUOTECHAR, quotecharObj, T_DOUBLE_QUOTE, true); + QuoteStyle quoting = getQuotingValue(frame, inliningTarget, T_ATTR_QUOTING, quotingObj, QUOTE_MINIMAL, pyLongCheckExactNode, pyLongAsIntNode, raiseNode); + boolean skipInitialSpace = getBoolean(frame, skipinitialspaceObj, false, isTrueNode); + boolean strict = getBoolean(frame, strictObj, false, isTrueNode); + if (quotecharObj == PNone.NONE && quotingObj == PNone.NO_VALUE) { + quoting = QUOTE_NONE; + } + return createCSVDialect(inliningTarget, cls, delimiter, doubleQuote, escapeChar, lineTerminator, quoteChar, quoting, skipInitialSpace, strict); + } + + @TruffleBoundary + private static Object createCSVDialect(Node raisingNode, Object cls, TruffleString delimiter, boolean doubleQuote, TruffleString escapeChar, TruffleString lineTerminator, + TruffleString quoteChar, QuoteStyle quoting, boolean skipInitialSpace, boolean strict) { + if (TruffleString.EqualNode.getUncached().execute(delimiter, T_NOT_SET, TS_ENCODING)) { + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.DELIMITER_MUST_BE_ONE_CHAR_STRING); + } + + if (quoting != QUOTE_NONE && TruffleString.EqualNode.getUncached().execute(quoteChar, T_NOT_SET, TS_ENCODING)) { + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.QUOTECHAR_MUST_BE_SET_IF_QUOTING_ENABLED); + } + + if (lineTerminator == null) { + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.LINETERMINATOR_MUST_BE_SET); + } + + // delimiter cannot be NOT_SET + int delimiterCodePoint = TruffleString.CodePointAtIndexNode.getUncached().execute(delimiter, 0, TS_ENCODING); + int escapeCharCodePoint = TruffleString.EqualNode.getUncached().execute(escapeChar, T_NOT_SET, TS_ENCODING) ? NOT_SET_CODEPOINT + : TruffleString.CodePointAtIndexNode.getUncached().execute(escapeChar, 0, TS_ENCODING); + int quoteCharCodePoint = TruffleString.EqualNode.getUncached().execute(quoteChar, T_NOT_SET, TS_ENCODING) ? NOT_SET_CODEPOINT + : TruffleString.CodePointAtIndexNode.getUncached().execute(quoteChar, 0, TS_ENCODING); + + return PFactory.createCSVDialect(PythonLanguage.get(null), cls, TypeNodes.GetInstanceShape.executeUncached(cls), delimiter, delimiterCodePoint, doubleQuote, + escapeChar, escapeCharCodePoint, lineTerminator, quoteChar, quoteCharCodePoint, quoting, + skipInitialSpace, strict); + } + + private static Object getAttributeValue(VirtualFrame frame, Node inliningTarget, Object dialect, Object inputValue, TruffleString attributeName, PyObjectLookupAttr getAttributeNode) { + if (inputValue != PNone.NO_VALUE) { + return inputValue; + } + return getAttributeNode.execute(frame, inliningTarget, dialect, attributeName); + } + + @TruffleBoundary + private static TruffleString getChar(Node raisingNode, TruffleString name, Object valueObj, TruffleString defaultValue, boolean optional) { + if (valueObj == PNone.NO_VALUE) { + return defaultValue; + } + if (optional && valueObj == PNone.NONE) { + return T_NOT_SET; + } + + TruffleString charValue; + + try { + charValue = CastToTruffleStringNode.executeUncached(valueObj); + } catch (CannotCastException e) { + TruffleString format = optional ? ErrorMessages.S_MUST_BE_STRING_OR_NONE_NOT_S : ErrorMessages.S_MUST_BE_STRING_NOT_S; + throw PRaiseNode.raiseStatic(raisingNode, TypeError, format, name, GetClassNode.executeUncached(valueObj)); + } + + if (optional && TruffleString.EqualNode.getUncached().execute(charValue, T_NOT_SET, TS_ENCODING)) { + return T_NOT_SET; + } + + if (TruffleString.CodePointLengthNode.getUncached().execute(charValue, TS_ENCODING) != 1) { + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.MUST_BE_ONE_CHARACTER_STRING, name); + } + + return charValue; + } + + private static boolean getBoolean(VirtualFrame frame, Object valueObj, boolean defaultValue, PyObjectIsTrueNode isTrueNode) { + if (valueObj == PNone.NO_VALUE) { + return defaultValue; + } + + return isTrueNode.execute(frame, valueObj); + } + + @TruffleBoundary + private static TruffleString getString(Node raisingNode, TruffleString attribute, Object valueObj, TruffleString defaultValue) { + if (valueObj == PNone.NO_VALUE) { + return defaultValue; + } + + if (valueObj == PNone.NONE) { + return null; + } + + TruffleString value; + + try { + value = CastToTruffleStringNode.executeUncached(valueObj); + } catch (CannotCastException e) { + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.MUST_BE_STRING_QUOTED, attribute); + } + + return value; + } + + private static QuoteStyle getQuotingValue(VirtualFrame frame, Node inliningTarget, TruffleString name, Object valueObj, QuoteStyle defaultValue, + PyLongCheckExactNode pyLongCheckExactNode, PyLongAsIntNode pyLongAsIntNode, PRaiseNode raiseNode) { + + if (valueObj == PNone.NO_VALUE) { + return defaultValue; + } + + if (valueObj instanceof QuoteStyle) { + return (QuoteStyle) valueObj; + } + + if (!pyLongCheckExactNode.execute(inliningTarget, valueObj)) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_INTEGER_QUOTED_ATTR, name); + } + + int value = pyLongAsIntNode.execute(frame, inliningTarget, valueObj); + + if (!QuoteStyle.containsOrdinalValue(value)) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.BAD_QUOTING_VALUE); + } + + return QuoteStyle.getQuoteStyle(value); + } + } + @Builtin(name = J_ATTR_DELIMITER, minNumOfPositionalArgs = 1, isGetter = true) @GenerateNodeFactory abstract static class DelimiterNode extends PythonUnaryBuiltinNode { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVModuleBuiltins.java index efd9e7d425..231304a7db 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVModuleBuiltins.java @@ -45,17 +45,11 @@ import static com.oracle.graal.python.builtins.modules.csv.QuoteStyle.QUOTE_NONE; import static com.oracle.graal.python.builtins.modules.csv.QuoteStyle.QUOTE_NONNUMERIC; import static com.oracle.graal.python.builtins.modules.io.IONodes.T_WRITE; -import static com.oracle.graal.python.nodes.StringLiterals.J_STRICT; -import static com.oracle.graal.python.nodes.StringLiterals.T_COMMA; -import static com.oracle.graal.python.nodes.StringLiterals.T_CRLF; -import static com.oracle.graal.python.nodes.StringLiterals.T_DOUBLE_QUOTE; -import static com.oracle.graal.python.nodes.StringLiterals.T_STRICT; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -67,17 +61,13 @@ import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.builtins.objects.str.PString; -import com.oracle.graal.python.builtins.objects.type.PythonClass; import com.oracle.graal.python.lib.PyCallableCheckNode; import com.oracle.graal.python.lib.PyDictDelItem; import com.oracle.graal.python.lib.PyDictGetItem; import com.oracle.graal.python.lib.PyDictSetItem; -import com.oracle.graal.python.lib.PyLongAsIntNode; import com.oracle.graal.python.lib.PyLongAsLongNode; import com.oracle.graal.python.lib.PyLongCheckExactNode; import com.oracle.graal.python.lib.PyObjectGetIter; -import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; @@ -87,15 +77,11 @@ import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; -import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.NodeFactory; @@ -109,26 +95,10 @@ public final class CSVModuleBuiltins extends PythonBuiltins { private static final TruffleString T__DIALECTS = tsLiteral("_dialects"); static final String J_ATTR_DELIMITER = "delimiter"; - private static final TruffleString T_ATTR_DELIMITER = tsLiteral(J_ATTR_DELIMITER); - static final String J_ATTR_DOUBLEQUOTE = "doublequote"; - private static final TruffleString T_ATTR_DOUBLEQUOTE = tsLiteral(J_ATTR_DOUBLEQUOTE); - static final String J_ATTR_ESCAPECHAR = "escapechar"; - private static final TruffleString T_ATTR_ESCAPECHAR = tsLiteral(J_ATTR_ESCAPECHAR); - static final String J_ATTR_LINETERMINATOR = "lineterminator"; - private static final TruffleString T_ATTR_LINETERMINATOR = tsLiteral(J_ATTR_LINETERMINATOR); - static final String J_ATTR_QUOTING = "quoting"; - private static final TruffleString T_ATTR_QUOTING = tsLiteral(J_ATTR_QUOTING); - static final String J_ATTR_QUOTECHAR = "quotechar"; - private static final TruffleString T_ATTR_QUOTECHAR = tsLiteral(J_ATTR_QUOTECHAR); - static final String J_ATTR_SKIPINITIALSPACE = "skipinitialspace"; - private static final TruffleString T_ATTR_SKIPINITIALSPACE = tsLiteral(J_ATTR_SKIPINITIALSPACE); - static final String J_ATTR_STRICT = J_STRICT; - private static final TruffleString T_ATTR_STRICT = T_STRICT; static final String J__CSV = "_csv"; static final TruffleString T__CSV = tsLiteral(J__CSV); - private static final TruffleString T_NOT_SET = tsLiteral("NOT_SET"); static final int NOT_SET_CODEPOINT = -1; long fieldLimit = 128 * 1024; // max parsed field size @@ -146,7 +116,7 @@ public void initialize(Python3Core core) { addBuiltinConstant("QUOTE_ALL", QUOTE_ALL.ordinal()); addBuiltinConstant("QUOTE_NONNUMERIC", QUOTE_NONNUMERIC.ordinal()); addBuiltinConstant("QUOTE_NONE", QUOTE_NONE.ordinal()); - addBuiltinConstant(T__DIALECTS, core.factory().createDict()); + addBuiltinConstant(T__DIALECTS, PFactory.createDict(core.getLanguage())); super.initialize(core); } @@ -163,12 +133,12 @@ static PNone register(VirtualFrame frame, PythonModule module, Object nameObj, O @Cached ReadAttributeFromObjectNode readNode, @Cached CallNode callNode, @Cached PyDictSetItem setItem, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleString name; try { name = nameNode.execute(inliningTarget, nameObj); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.MUST_BE_STRING, "dialect name"); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.MUST_BE_STRING, "dialect name"); } Object result = callNode.execute(frame, PythonBuiltinClassType.CSVDialect, new Object[]{dialectObj}, keywords); @@ -193,7 +163,7 @@ static PNone unregister(VirtualFrame frame, PythonModule module, Object nameObj, @Cached ReadAttributeFromObjectNode readNode, @Cached PyDictDelItem delItem, @Cached HashingStorageGetItem getItem, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { // TODO GR-38165: unchecked cast to PDict PDict dialects = (PDict) readNode.execute(module, T__DIALECTS); @@ -201,7 +171,7 @@ static PNone unregister(VirtualFrame frame, PythonModule module, Object nameObj, if (getItem.hasKey(frame, inliningTarget, (dialects).getDictStorage(), nameObj)) { delItem.execute(frame, inliningTarget, dialects, nameObj); } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.CSVError, ErrorMessages.UNKNOWN_DIALECT); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.CSVError, ErrorMessages.UNKNOWN_DIALECT); } return PNone.NONE; @@ -225,7 +195,7 @@ static CSVDialect get(VirtualFrame frame, PythonModule module, Object nameObj, @Bind("this") Node inliningTarget, @Cached PyDictGetItem getItemNode, @Cached ReadAttributeFromObjectNode readNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { // TODO GR-38165: unchecked cast to PDict PDict dialects = (PDict) readNode.execute(module, T__DIALECTS); @@ -233,7 +203,7 @@ static CSVDialect get(VirtualFrame frame, PythonModule module, Object nameObj, CSVDialect dialect = (CSVDialect) getItemNode.execute(frame, inliningTarget, dialects, nameObj); if (dialect == null) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.CSVError, ErrorMessages.UNKNOWN_DIALECT); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.CSVError, ErrorMessages.UNKNOWN_DIALECT); } return dialect; @@ -262,10 +232,10 @@ static Object createReader(VirtualFrame frame, Object csvfile, Object dialectObj @Bind("this") Node inliningTarget, @Cached PyObjectGetIter getIter, @Cached CallNode callNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { Object inputIter = getIter.execute(frame, inliningTarget, csvfile); CSVDialect dialect = (CSVDialect) callNode.execute(frame, PythonBuiltinClassType.CSVDialect, new Object[]{dialectObj}, kwargs); - return factory.createCSVReader(PythonBuiltinClassType.CSVReader, inputIter, dialect); + return PFactory.createCSVReader(language, inputIter, dialect); } } @@ -278,14 +248,14 @@ static Object createReader(VirtualFrame frame, Object outputFile, Object dialect @Cached CallNode callNode, @Cached PyObjectLookupAttr lookupAttr, @Cached PyCallableCheckNode checkCallable, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { Object write = lookupAttr.execute(frame, inliningTarget, outputFile, T_WRITE); if (write == PNone.NO_VALUE || !checkCallable.execute(inliningTarget, write)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.S_MUST_HAVE_WRITE_METHOD, "argument 1"); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.S_MUST_HAVE_WRITE_METHOD, "argument 1"); } CSVDialect dialect = (CSVDialect) callNode.execute(frame, PythonBuiltinClassType.CSVDialect, new Object[]{dialectObj}, kwargs); - return factory.createCSVWriter(PythonBuiltinClassType.CSVWriter, write, dialect); + return PFactory.createCSVWriter(language, write, dialect); } } @@ -301,13 +271,13 @@ static long getOrSetFieldSizeLimit(VirtualFrame frame, PythonModule self, Object @Bind("this") Node inliningTarget, @Cached PyLongCheckExactNode checkLongNode, @Cached PyLongAsLongNode castToLong, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { CSVModuleBuiltins csvModuleBuiltins = (CSVModuleBuiltins) self.getBuiltins(); long oldLimit = csvModuleBuiltins.fieldLimit; if (newLimit != PNone.NO_VALUE) { if (!checkLongNode.execute(inliningTarget, newLimit)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.MUST_BE_INTEGER, "limit"); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.MUST_BE_INTEGER, "limit"); } csvModuleBuiltins.fieldLimit = castToLong.execute(frame, inliningTarget, newLimit); } @@ -315,316 +285,6 @@ static long getOrSetFieldSizeLimit(VirtualFrame frame, PythonModule self, Object } } - @Builtin(name = "CSVDialect", constructsClass = PythonBuiltinClassType.CSVDialect, parameterNames = {"class", "dialect", "delimiter", "doublequote", "escapechar", "lineterminator", "quotechar", - "quoting", "skipinitialspace", "strict"}) - @GenerateNodeFactory - public abstract static class DialectNode extends PythonBuiltinNode { - - @Specialization - @SuppressWarnings("unused") - static Object doCSVDialectWithoutKeywords(PythonBuiltinClassType cls, CSVDialect dialect, PNone delimiter, PNone doublequote, PNone escapechar, - PNone lineterminator, PNone quotechar, PNone quoting, PNone skipinitialspace, PNone strict) { - return dialect; - } - - @Specialization - @SuppressWarnings("unused") - static CSVDialect doStringWithoutKeywords(VirtualFrame frame, PythonBuiltinClassType cls, TruffleString dialectName, PNone delimiter, PNone doublequote, PNone escapechar, - PNone lineterminator, PNone quotechar, PNone quoting, PNone skipinitialspace, PNone strict, - @Bind("this") Node inliningTarget, - @Exclusive @Cached CSVModuleBuiltins.CSVGetDialectNode getDialect) { - PythonModule module = PythonContext.get(inliningTarget).lookupBuiltinModule(T__CSV); - return getDialect.execute(frame, module, dialectName); - } - - @Specialization - static Object doNoDialectObj(VirtualFrame frame, PythonBuiltinClassType cls, @SuppressWarnings("unused") PNone dialectObj, Object delimiterObj, Object doublequoteObj, Object escapecharObj, - Object lineterminatorObj, Object quotecharObj, Object quotingObj, Object skipinitialspaceObj, Object strictObj, - @Bind("this") Node inliningTarget, - @Exclusive @Cached PyObjectIsTrueNode isTrueNode, - @Exclusive @Cached PyLongCheckExactNode pyLongCheckExactNode, - @Exclusive @Cached PyLongAsIntNode pyLongAsIntNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - return createCSVDialect(frame, inliningTarget, cls, delimiterObj, doublequoteObj, escapecharObj, lineterminatorObj, - quotecharObj, quotingObj, skipinitialspaceObj, strictObj, isTrueNode, pyLongCheckExactNode, pyLongAsIntNode, raiseNode); - } - - @Specialization - static Object doStringWithKeywords(VirtualFrame frame, PythonBuiltinClassType cls, TruffleString dialectName, Object delimiterObj, Object doublequoteObj, Object escapecharObj, - Object lineterminatorObj, Object quotecharObj, Object quotingObj, Object skipinitialspaceObj, Object strictObj, - @Bind("this") Node inliningTarget, - @Exclusive @Cached CSVModuleBuiltins.CSVGetDialectNode getDialect, - @Exclusive @Cached PyObjectIsTrueNode isTrueNode, - @Exclusive @Cached PyLongCheckExactNode pyLongCheckExactNode, - @Exclusive @Cached PyLongAsIntNode pyLongAsIntNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - PythonModule module = PythonContext.get(inliningTarget).lookupBuiltinModule(T__CSV); - CSVDialect dialectObj = getDialect.execute(frame, module, dialectName); - - if (delimiterObj == PNone.NO_VALUE) { - delimiterObj = dialectObj.delimiter; - } - if (doublequoteObj == PNone.NO_VALUE) { - doublequoteObj = dialectObj.doubleQuote; - } - if (escapecharObj == PNone.NO_VALUE) { - escapecharObj = dialectObj.escapeChar; - } - if (lineterminatorObj == PNone.NO_VALUE) { - lineterminatorObj = dialectObj.lineTerminator; - } - if (quotingObj == PNone.NO_VALUE) { - quotingObj = dialectObj.quoting; - } - if (quotecharObj == PNone.NO_VALUE) { - quotecharObj = dialectObj.quoteChar; - } - if (skipinitialspaceObj == PNone.NO_VALUE) { - skipinitialspaceObj = dialectObj.skipInitialSpace; - } - if (strictObj == PNone.NO_VALUE) { - strictObj = dialectObj.strict; - } - - return createCSVDialect(frame, inliningTarget, cls, delimiterObj, doublequoteObj, escapecharObj, lineterminatorObj, - quotecharObj, quotingObj, skipinitialspaceObj, strictObj, isTrueNode, pyLongCheckExactNode, pyLongAsIntNode, raiseNode); - } - - @Specialization - static Object doDialectClassWithKeywords(VirtualFrame frame, PythonBuiltinClassType cls, PythonClass dialectObj, Object delimiterObj, Object doublequoteObj, Object escapecharObj, - Object lineterminatorObj, Object quotecharObj, Object quotingObj, Object skipinitialspaceObj, Object strictObj, - @Bind("this") Node inliningTarget, - @Exclusive @Cached PyObjectLookupAttr getFirstAttributesNode, - @Exclusive @Cached PyObjectLookupAttr getSecondAttributesNode, - @Exclusive @Cached PyObjectLookupAttr getThirdAttributesNode, - @Exclusive @Cached PyObjectIsTrueNode isTrueNode, - @Exclusive @Cached PyLongCheckExactNode pyLongCheckExactNode, - @Exclusive @Cached PyLongAsIntNode pyLongAsIntNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - - // We use multiple AttributeNodes to be able to cache all attributes as current - // CACHE_SIZE is 3. - delimiterObj = getAttributeValue(frame, inliningTarget, dialectObj, delimiterObj, T_ATTR_DELIMITER, getFirstAttributesNode); - doublequoteObj = getAttributeValue(frame, inliningTarget, dialectObj, doublequoteObj, T_ATTR_DOUBLEQUOTE, getFirstAttributesNode); - escapecharObj = getAttributeValue(frame, inliningTarget, dialectObj, escapecharObj, T_ATTR_ESCAPECHAR, getFirstAttributesNode); - lineterminatorObj = getAttributeValue(frame, inliningTarget, dialectObj, lineterminatorObj, T_ATTR_LINETERMINATOR, getSecondAttributesNode); - quotecharObj = getAttributeValue(frame, inliningTarget, dialectObj, quotecharObj, T_ATTR_QUOTECHAR, getSecondAttributesNode); - quotingObj = getAttributeValue(frame, inliningTarget, dialectObj, quotingObj, T_ATTR_QUOTING, getSecondAttributesNode); - skipinitialspaceObj = getAttributeValue(frame, inliningTarget, dialectObj, skipinitialspaceObj, T_ATTR_SKIPINITIALSPACE, getThirdAttributesNode); - strictObj = getAttributeValue(frame, inliningTarget, dialectObj, strictObj, T_ATTR_STRICT, getThirdAttributesNode); - - return createCSVDialect(frame, inliningTarget, cls, delimiterObj, doublequoteObj, escapecharObj, lineterminatorObj, - quotecharObj, quotingObj, skipinitialspaceObj, strictObj, isTrueNode, pyLongCheckExactNode, pyLongAsIntNode, raiseNode); - } - - @Specialization - static Object doPStringWithKeywords(VirtualFrame frame, PythonBuiltinClassType cls, PString dialectName, Object delimiterObj, Object doublequoteObj, Object escapecharObj, - Object lineterminatorObj, Object quotecharObj, Object quotingObj, Object skipinitialspaceObj, Object strictObj, - @Bind("this") Node inliningTarget, - @Exclusive @Cached CSVModuleBuiltins.CSVGetDialectNode getDialect, - @Cached CastToTruffleStringNode castToStringNode, - @Exclusive @Cached PyObjectIsTrueNode isTrueNode, - @Exclusive @Cached PyLongCheckExactNode pyLongCheckExactNode, - @Exclusive @Cached PyLongAsIntNode pyLongAsIntNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - - TruffleString dialectNameStr = castToStringNode.execute(inliningTarget, dialectName); - PythonModule module = PythonContext.get(inliningTarget).lookupBuiltinModule(T__CSV); - CSVDialect dialectObj = getDialect.execute(frame, module, dialectNameStr); - - if (delimiterObj == PNone.NO_VALUE) { - delimiterObj = dialectObj.delimiter; - } - if (doublequoteObj == PNone.NO_VALUE) { - doublequoteObj = dialectObj.doubleQuote; - } - if (escapecharObj == PNone.NO_VALUE) { - escapecharObj = dialectObj.escapeChar; - } - if (lineterminatorObj == PNone.NO_VALUE) { - lineterminatorObj = dialectObj.lineTerminator; - } - if (quotingObj == PNone.NO_VALUE) { - quotingObj = dialectObj.quoting; - } - if (quotecharObj == PNone.NO_VALUE) { - quotecharObj = dialectObj.quoteChar; - } - if (skipinitialspaceObj == PNone.NO_VALUE) { - skipinitialspaceObj = dialectObj.skipInitialSpace; - } - if (strictObj == PNone.NO_VALUE) { - strictObj = dialectObj.strict; - } - - return createCSVDialect(frame, inliningTarget, cls, delimiterObj, doublequoteObj, escapecharObj, lineterminatorObj, - quotecharObj, quotingObj, skipinitialspaceObj, strictObj, isTrueNode, pyLongCheckExactNode, pyLongAsIntNode, raiseNode); - } - - @Specialization(guards = {"!isCSVDialect(dialectObj)", "!isPythonClass(dialectObj)", "!isString(dialectObj)", "!isPNone(dialectObj)"}) - static Object doGeneric(VirtualFrame frame, PythonBuiltinClassType cls, Object dialectObj, Object delimiterObj, Object doublequoteObj, Object escapecharObj, Object lineterminatorObj, - Object quotecharObj, Object quotingObj, Object skipinitialspaceObj, Object strictObj, - @Bind("this") Node inliningTarget, - @Exclusive @Cached PyObjectLookupAttr getFirstAttributesNode, - @Exclusive @Cached PyObjectLookupAttr getSecondAttributesNode, - @Exclusive @Cached PyObjectLookupAttr getThirdAttributesNode, - @Exclusive @Cached PyObjectIsTrueNode isTrueNode, - @Exclusive @Cached PyLongCheckExactNode pyLongCheckExactNode, - @Exclusive @Cached PyLongAsIntNode pyLongAsIntNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - - delimiterObj = getAttributeValue(frame, inliningTarget, dialectObj, delimiterObj, T_ATTR_DELIMITER, getFirstAttributesNode); - doublequoteObj = getAttributeValue(frame, inliningTarget, dialectObj, doublequoteObj, T_ATTR_DOUBLEQUOTE, getFirstAttributesNode); - escapecharObj = getAttributeValue(frame, inliningTarget, dialectObj, escapecharObj, T_ATTR_ESCAPECHAR, getFirstAttributesNode); - lineterminatorObj = getAttributeValue(frame, inliningTarget, dialectObj, lineterminatorObj, T_ATTR_LINETERMINATOR, getSecondAttributesNode); - quotingObj = getAttributeValue(frame, inliningTarget, dialectObj, quotingObj, T_ATTR_QUOTING, getSecondAttributesNode); - quotecharObj = getAttributeValue(frame, inliningTarget, dialectObj, quotecharObj, T_ATTR_QUOTECHAR, getSecondAttributesNode); - skipinitialspaceObj = getAttributeValue(frame, inliningTarget, dialectObj, skipinitialspaceObj, T_ATTR_SKIPINITIALSPACE, getThirdAttributesNode); - strictObj = getAttributeValue(frame, inliningTarget, dialectObj, strictObj, T_ATTR_STRICT, getThirdAttributesNode); - - return createCSVDialect(frame, inliningTarget, cls, delimiterObj, doublequoteObj, escapecharObj, lineterminatorObj, - quotecharObj, quotingObj, skipinitialspaceObj, strictObj, isTrueNode, pyLongCheckExactNode, pyLongAsIntNode, raiseNode); - } - - protected static boolean isCSVDialect(Object dialect) { - return dialect instanceof CSVDialect; - } - - private static Object createCSVDialect(VirtualFrame frame, Node inliningTarget, PythonBuiltinClassType cls, Object delimiterObj, Object doublequoteObj, Object escapecharObj, - Object lineterminatorObj, Object quotecharObj, Object quotingObj, Object skipinitialspaceObj, Object strictObj, - PyObjectIsTrueNode isTrueNode, PyLongCheckExactNode pyLongCheckExactNode, PyLongAsIntNode pyLongAsIntNode, PRaiseNode.Lazy raiseNode) { - TruffleString delimiter = getChar(inliningTarget, T_ATTR_DELIMITER, delimiterObj, T_COMMA, false); - boolean doubleQuote = getBoolean(frame, doublequoteObj, true, isTrueNode); - TruffleString escapeChar = getChar(inliningTarget, T_ATTR_ESCAPECHAR, escapecharObj, T_NOT_SET, true); - TruffleString lineTerminator = getString(inliningTarget, T_ATTR_LINETERMINATOR, lineterminatorObj, T_CRLF); - TruffleString quoteChar = getChar(inliningTarget, T_ATTR_QUOTECHAR, quotecharObj, T_DOUBLE_QUOTE, true); - QuoteStyle quoting = getQuotingValue(frame, inliningTarget, T_ATTR_QUOTING, quotingObj, QUOTE_MINIMAL, pyLongCheckExactNode, pyLongAsIntNode, raiseNode); - boolean skipInitialSpace = getBoolean(frame, skipinitialspaceObj, false, isTrueNode); - boolean strict = getBoolean(frame, strictObj, false, isTrueNode); - if (quotecharObj == PNone.NONE && quotingObj == PNone.NO_VALUE) { - quoting = QUOTE_NONE; - } - return createCSVDialect(inliningTarget, cls, delimiter, doubleQuote, escapeChar, lineTerminator, quoteChar, quoting, skipInitialSpace, strict); - } - - @TruffleBoundary - private static Object createCSVDialect(Node raisingNode, PythonBuiltinClassType cls, TruffleString delimiter, boolean doubleQuote, TruffleString escapeChar, TruffleString lineTerminator, - TruffleString quoteChar, QuoteStyle quoting, boolean skipInitialSpace, boolean strict) { - if (TruffleString.EqualNode.getUncached().execute(delimiter, T_NOT_SET, TS_ENCODING)) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.DELIMITER_MUST_BE_ONE_CHAR_STRING); - } - - if (quoting != QUOTE_NONE && TruffleString.EqualNode.getUncached().execute(quoteChar, T_NOT_SET, TS_ENCODING)) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.QUOTECHAR_MUST_BE_SET_IF_QUOTING_ENABLED); - } - - if (lineTerminator == null) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.LINETERMINATOR_MUST_BE_SET); - } - - // delimiter cannot be NOT_SET - int delimiterCodePoint = TruffleString.CodePointAtIndexNode.getUncached().execute(delimiter, 0, TS_ENCODING); - int escapeCharCodePoint = TruffleString.EqualNode.getUncached().execute(escapeChar, T_NOT_SET, TS_ENCODING) ? NOT_SET_CODEPOINT - : TruffleString.CodePointAtIndexNode.getUncached().execute(escapeChar, 0, TS_ENCODING); - int quoteCharCodePoint = TruffleString.EqualNode.getUncached().execute(quoteChar, T_NOT_SET, TS_ENCODING) ? NOT_SET_CODEPOINT - : TruffleString.CodePointAtIndexNode.getUncached().execute(quoteChar, 0, TS_ENCODING); - - return PythonObjectFactory.getUncached().createCSVDialect(cls, delimiter, delimiterCodePoint, doubleQuote, - escapeChar, escapeCharCodePoint, lineTerminator, quoteChar, quoteCharCodePoint, quoting, - skipInitialSpace, strict); - } - - private static Object getAttributeValue(VirtualFrame frame, Node inliningTarget, Object dialect, Object inputValue, TruffleString attributeName, PyObjectLookupAttr getAttributeNode) { - if (inputValue != PNone.NO_VALUE) { - return inputValue; - } - return getAttributeNode.execute(frame, inliningTarget, dialect, attributeName); - } - - @TruffleBoundary - private static TruffleString getChar(Node raisingNode, TruffleString name, Object valueObj, TruffleString defaultValue, boolean optional) { - if (valueObj == PNone.NO_VALUE) { - return defaultValue; - } - if (optional && valueObj == PNone.NONE) { - return T_NOT_SET; - } - - TruffleString charValue; - - try { - charValue = CastToTruffleStringNode.executeUncached(valueObj); - } catch (CannotCastException e) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, optional ? ErrorMessages.S_MUST_BE_STRING_OR_NONE_NOT_S : ErrorMessages.S_MUST_BE_STRING_NOT_S, name, - GetClassNode.executeUncached(valueObj)); - } - - if (optional && TruffleString.EqualNode.getUncached().execute(charValue, T_NOT_SET, TS_ENCODING)) { - return T_NOT_SET; - } - - if (TruffleString.CodePointLengthNode.getUncached().execute(charValue, TS_ENCODING) != 1) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.MUST_BE_ONE_CHARACTER_STRING, name); - } - - return charValue; - } - - private static boolean getBoolean(VirtualFrame frame, Object valueObj, boolean defaultValue, PyObjectIsTrueNode isTrueNode) { - if (valueObj == PNone.NO_VALUE) { - return defaultValue; - } - - return isTrueNode.execute(frame, valueObj); - } - - @TruffleBoundary - private static TruffleString getString(Node raisingNode, TruffleString attribute, Object valueObj, TruffleString defaultValue) { - if (valueObj == PNone.NO_VALUE) { - return defaultValue; - } - - if (valueObj == PNone.NONE) { - return null; - } - - TruffleString value; - - try { - value = CastToTruffleStringNode.executeUncached(valueObj); - } catch (CannotCastException e) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.MUST_BE_STRING_QUOTED, attribute); - } - - return value; - } - - private static QuoteStyle getQuotingValue(VirtualFrame frame, Node inliningTarget, TruffleString name, Object valueObj, QuoteStyle defaultValue, - PyLongCheckExactNode pyLongCheckExactNode, PyLongAsIntNode pyLongAsIntNode, PRaiseNode.Lazy raiseNode) { - - if (valueObj == PNone.NO_VALUE) { - return defaultValue; - } - - if (valueObj instanceof QuoteStyle) { - return (QuoteStyle) valueObj; - } - - if (!pyLongCheckExactNode.execute(inliningTarget, valueObj)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MUST_BE_INTEGER_QUOTED_ATTR, name); - } - - int value = pyLongAsIntNode.execute(frame, inliningTarget, valueObj); - - if (!QuoteStyle.containsOrdinalValue(value)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.BAD_QUOTING_VALUE); - } - - return QuoteStyle.getQuoteStyle(value); - } - - } - private static final String CSV_DOC = "CSV parsing and writing.\n" + "\n" + "This module provides classes that assist in the reading and writing\n" + diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVReaderBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVReaderBuiltins.java index 8a843a5c27..1e05de1a4b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVReaderBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVReaderBuiltins.java @@ -51,32 +51,34 @@ import static com.oracle.graal.python.builtins.modules.csv.CSVReader.ReaderState.START_RECORD; import static com.oracle.graal.python.builtins.modules.csv.QuoteStyle.QUOTE_NONE; import static com.oracle.graal.python.builtins.modules.csv.QuoteStyle.QUOTE_NONNUMERIC; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.modules.csv.CSVReader.ReaderState; import com.oracle.graal.python.builtins.objects.list.PList; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyNumberFloatNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.builtins.ListNodes.AppendNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -93,13 +95,14 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.CSVReader) public final class CSVReaderBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = CSVReaderBuiltinsSlotsGen.SLOTS; @Override protected List> getNodeFactories() { return CSVReaderBuiltinsFactory.getFactories(); } - @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iter, isComplex = true) @GenerateNodeFactory public abstract static class IterReaderNode extends PythonUnaryBuiltinNode { @Specialization @@ -108,9 +111,9 @@ Object iter(CSVReader self) { } } - @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iternext, isComplex = true) @GenerateNodeFactory - public abstract static class NextReaderNode extends PythonUnaryBuiltinNode { + public abstract static class NextReaderNode extends TpIterNextBuiltin { private static final int EOL = -2; private static final int NEWLINE_CODEPOINT = '\n'; @@ -121,40 +124,37 @@ public abstract static class NextReaderNode extends PythonUnaryBuiltinNode { static Object nextPos(VirtualFrame frame, CSVReader self, @Bind("this") Node inliningTarget, @Cached TruffleString.CreateCodePointIteratorNode createCodePointIteratorNode, - @Cached TruffleStringIterator.NextNode nextNode, + @Cached TruffleStringIterator.NextNode stringNextNode, @Cached TruffleStringBuilder.AppendCodePointNode appendCodePointNode, @Cached TruffleStringBuilder.ToStringNode toStringNode, @Cached PyNumberFloatNode pyNumberFloatNode, @Cached AppendNode appendNode, - @Cached GetNextNode getNextNode, + @Cached PyIterNextNode nextNode, @Cached CastToTruffleStringNode castToStringNode, @Cached GetClassNode getClassNode, - @Cached IsBuiltinObjectProfile isBuiltinClassProfile, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - PList fields = factory.createList(); + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { + PList fields = PFactory.createList(language); CSVModuleBuiltins csvModuleBuiltins = (CSVModuleBuiltins) PythonContext.get(inliningTarget).lookupBuiltinModule(T__CSV).getBuiltins(); self.parseReset(); do { Object lineObj; try { - lineObj = getNextNode.execute(frame, self.inputIter); - } catch (PException e) { - e.expectStopIteration(inliningTarget, isBuiltinClassProfile); + lineObj = nextNode.execute(frame, inliningTarget, self.inputIter); + } catch (IteratorExhausted e) { self.fieldLimit = csvModuleBuiltins.fieldLimit; if (!self.field.isEmpty() || self.state == IN_QUOTED_FIELD) { if (self.dialect.strict) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.CSVError, ErrorMessages.UNEXPECTED_END_OF_DATA); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.CSVError, ErrorMessages.UNEXPECTED_END_OF_DATA); } else { try { parseSaveField(inliningTarget, self, fields, toStringNode, pyNumberFloatNode, appendNode); } catch (AbstractTruffleException ignored) { - throw e; } break; } } - throw raiseNode.get(inliningTarget).raiseStopIteration(); + throw iteratorExhausted(); } self.fieldLimit = csvModuleBuiltins.fieldLimit; @@ -162,13 +162,13 @@ static Object nextPos(VirtualFrame frame, CSVReader self, try { line = castToStringNode.execute(inliningTarget, lineObj); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.CSVError, ErrorMessages.WRONG_ITERATOR_RETURN_TYPE, getClassNode.execute(inliningTarget, lineObj)); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.CSVError, ErrorMessages.WRONG_ITERATOR_RETURN_TYPE, getClassNode.execute(inliningTarget, lineObj)); } self.lineNum++; TruffleStringIterator tsi = createCodePointIteratorNode.execute(line, TS_ENCODING); while (tsi.hasNext()) { - final int codepoint = nextNode.execute(tsi); + final int codepoint = stringNextNode.execute(tsi); parseProcessCodePoint(inliningTarget, self, fields, codepoint, appendCodePointNode, toStringNode, pyNumberFloatNode, appendNode, raiseNode); } parseProcessCodePoint(inliningTarget, self, fields, EOL, appendCodePointNode, toStringNode, pyNumberFloatNode, appendNode, raiseNode); @@ -179,7 +179,7 @@ static Object nextPos(VirtualFrame frame, CSVReader self, @SuppressWarnings("fallthrough") private static void parseProcessCodePoint(Node inliningTarget, CSVReader self, PList fields, int codePoint, AppendCodePointNode appendCodePointNode, ToStringNode toStringNode, - PyNumberFloatNode pyNumberFloatNode, AppendNode appendNode, PRaiseNode.Lazy raiseNode) { + PyNumberFloatNode pyNumberFloatNode, AppendNode appendNode, PRaiseNode raiseNode) { CSVDialect dialect = self.dialect; switch (self.state) { @@ -314,7 +314,7 @@ private static void parseProcessCodePoint(Node inliningTarget, CSVReader self, P self.state = IN_FIELD; } else { /* illegal */ - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.CSVError, ErrorMessages.S_EXPECTED_AFTER_S, dialect.delimiter, dialect.quoteChar); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.CSVError, ErrorMessages.S_EXPECTED_AFTER_S, dialect.delimiter, dialect.quoteChar); } break; @@ -324,7 +324,7 @@ private static void parseProcessCodePoint(Node inliningTarget, CSVReader self, P } else if (codePoint == EOL) { self.state = START_RECORD; } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.CSVError, ErrorMessages.NEWLINE_IN_UNQOUTED_FIELD); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.CSVError, ErrorMessages.NEWLINE_IN_UNQOUTED_FIELD); } break; } @@ -341,11 +341,11 @@ private static void parseSaveField(Node inliningTarget, CSVReader self, PList fi } } - private static void parseAddCodePoint(Node inliningTarget, CSVReader self, int codePoint, TruffleStringBuilder.AppendCodePointNode appendCodePointNode, PRaiseNode.Lazy raise) { + private static void parseAddCodePoint(Node inliningTarget, CSVReader self, int codePoint, TruffleStringBuilder.AppendCodePointNode appendCodePointNode, PRaiseNode raise) { assert TS_ENCODING == TruffleString.Encoding.UTF_32; int cpLen = self.field.byteLength() / 4; // assumes UTF-32 if (cpLen + 1 > self.fieldLimit) { - throw raise.get(inliningTarget).raise(PythonBuiltinClassType.CSVError, ErrorMessages.LARGER_THAN_FIELD_SIZE_LIMIT, self.fieldLimit); + throw raise.raise(inliningTarget, PythonBuiltinClassType.CSVError, ErrorMessages.LARGER_THAN_FIELD_SIZE_LIMIT, self.fieldLimit); } appendCodePointNode.execute(self.field, codePoint, 1, true); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVWriterBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVWriterBuiltins.java index 1a11fd9916..b1987de1f0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVWriterBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVWriterBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -51,7 +51,8 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyNumberCheckNode; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode; @@ -94,23 +95,22 @@ static Object doIt(VirtualFrame frame, CSVWriter self, Object seq, @Cached IsBuiltinObjectProfile errorProfile, @Cached CallUnaryMethodNode callNode, @Cached TruffleString.CreateCodePointIteratorNode createCodePointIteratorNode, - @Cached TruffleStringIterator.NextNode nextNode, + @Cached TruffleStringIterator.NextNode stringNextNode, @Cached TruffleString.ByteIndexOfCodePointNode byteIndexOfCodePointNode, @Cached TruffleStringBuilder.AppendCodePointNode appendCodePointNode, @Cached TruffleStringBuilder.AppendStringNode appendStringNode, @Cached TruffleStringBuilder.ToStringNode toStringNode, @Cached PyObjectStrAsTruffleStringNode objectStrAsTruffleStringNode, @Cached PyNumberCheckNode pyNumberCheckNode, - @Cached GetNextNode getNextNode, - @Cached IsBuiltinObjectProfile isBuiltinClassProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PyIterNextNode nextNode, + @Cached PRaiseNode raiseNode) { Object iter; try { iter = getIter.execute(frame, inliningTarget, seq); } catch (PException e) { e.expect(inliningTarget, PythonBuiltinClassType.TypeError, errorProfile); - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.CSVError, ErrorMessages.EXPECTED_ITERABLE_NOT_S, getClass.execute(inliningTarget, seq)); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.CSVError, ErrorMessages.EXPECTED_ITERABLE_NOT_S, getClass.execute(inliningTarget, seq)); } // Join all fields of passed in sequence in internal buffer. @@ -118,26 +118,26 @@ static Object doIt(VirtualFrame frame, CSVWriter self, Object seq, CSVDialect dialect = self.dialect; boolean first = true; while (true) { + Object field; try { - Object field = getNextNode.execute(frame, iter); - /* If this is not the first field we need a field separator */ - if (!first) { - appendStringNode.execute(sb, dialect.delimiter); - } else { - first = false; - } - joinField(inliningTarget, sb, dialect, field, createCodePointIteratorNode, nextNode, byteIndexOfCodePointNode, appendCodePointNode, appendStringNode, objectStrAsTruffleStringNode, - pyNumberCheckNode, raiseNode); - } catch (PException e) { - e.expectStopIteration(inliningTarget, isBuiltinClassProfile); + field = nextNode.execute(frame, inliningTarget, iter); + } catch (IteratorExhausted e) { break; } + /* If this is not the first field we need a field separator */ + if (!first) { + appendStringNode.execute(sb, dialect.delimiter); + } else { + first = false; + } + joinField(inliningTarget, sb, dialect, field, createCodePointIteratorNode, stringNextNode, byteIndexOfCodePointNode, appendCodePointNode, appendStringNode, + objectStrAsTruffleStringNode, pyNumberCheckNode, raiseNode); } if (!first && sb.isEmpty()) { if (dialect.quoting == QUOTE_NONE) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.CSVError, ErrorMessages.EMPTY_FIELD_RECORD_MUST_BE_QUOTED); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.CSVError, ErrorMessages.EMPTY_FIELD_RECORD_MUST_BE_QUOTED); } - joinAppend(inliningTarget, sb, dialect, null, true, createCodePointIteratorNode, nextNode, byteIndexOfCodePointNode, appendCodePointNode, appendStringNode, raiseNode); + joinAppend(inliningTarget, sb, dialect, null, true, createCodePointIteratorNode, stringNextNode, byteIndexOfCodePointNode, appendCodePointNode, appendStringNode, raiseNode); } appendStringNode.execute(sb, dialect.lineTerminator); return callNode.executeObject(frame, self.write, toStringNode.execute(sb)); @@ -146,7 +146,7 @@ static Object doIt(VirtualFrame frame, CSVWriter self, Object seq, private static void joinField(Node inliningTarget, TruffleStringBuilder sb, CSVDialect dialect, Object field, TruffleString.CreateCodePointIteratorNode createCodePointIteratorNode, TruffleStringIterator.NextNode nextNode, TruffleString.ByteIndexOfCodePointNode byteIndexOfCodePointNode, TruffleStringBuilder.AppendCodePointNode appendCodePointNode, TruffleStringBuilder.AppendStringNode appendStringNode, PyObjectStrAsTruffleStringNode objectStrAsTruffleStringNode, PyNumberCheckNode pyNumberCheckNode, - PRaiseNode.Lazy raiseNode) { + PRaiseNode raiseNode) { boolean quoted; switch (dialect.quoting) { @@ -171,7 +171,7 @@ private static void joinField(Node inliningTarget, TruffleStringBuilder sb, CSVD private static void joinAppend(Node inliningTarget, TruffleStringBuilder sb, CSVDialect dialect, TruffleString field, boolean quoted, TruffleString.CreateCodePointIteratorNode createCodePointIteratorNode, TruffleStringIterator.NextNode nextNode, TruffleString.ByteIndexOfCodePointNode byteIndexOfCodePointNode, - TruffleStringBuilder.AppendCodePointNode appendCodePointNode, TruffleStringBuilder.AppendStringNode appendStringNode, PRaiseNode.Lazy raiseNode) { + TruffleStringBuilder.AppendCodePointNode appendCodePointNode, TruffleStringBuilder.AppendStringNode appendStringNode, PRaiseNode raiseNode) { /* * If we don't already know that the field must be quoted due to dialect settings, check * if the field contains characters due to which it must be quoted. @@ -214,7 +214,7 @@ private static void joinAppend(Node inliningTarget, TruffleStringBuilder sb, CSV } if (wantEscape) { if (dialect.escapeCharCodePoint == NOT_SET_CODEPOINT) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.CSVError, ErrorMessages.ESCAPE_WITHOUT_ESCAPECHAR); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.CSVError, ErrorMessages.ESCAPE_WITHOUT_ESCAPECHAR); } appendStringNode.execute(sb, dialect.escapeChar); } @@ -259,21 +259,17 @@ public abstract static class WriteRowsNode extends PythonBinaryBuiltinNode { Object doIt(VirtualFrame frame, CSVWriter self, Object seq, @Bind("this") Node inliningTarget, @Cached PyObjectGetIter getIter, - @Cached GetNextNode getNext, - @Cached IsBuiltinObjectProfile isBuiltinClassProfile, + @Cached PyIterNextNode nextNode, @Cached WriteRowNode writeRow) { - Object iter, row; - - iter = getIter.execute(frame, inliningTarget, seq); - + Object iter = getIter.execute(frame, inliningTarget, seq); while (true) { + Object row; try { - row = getNext.execute(frame, iter); - writeRow.execute(frame, self, row); - } catch (PException e) { - e.expectStopIteration(inliningTarget, isBuiltinClassProfile); + row = nextNode.execute(frame, inliningTarget, iter); + } catch (IteratorExhausted e) { break; } + writeRow.execute(frame, self, row); } return PNone.NONE; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CArgObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CArgObjectBuiltins.java index 79144207e7..d3df325b45 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CArgObjectBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CArgObjectBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,11 +40,13 @@ */ package com.oracle.graal.python.builtins.modules.ctypes; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -53,9 +55,10 @@ import com.oracle.graal.python.builtins.modules.ctypes.memory.Pointer; import com.oracle.graal.python.builtins.modules.ctypes.memory.PointerNodes; import com.oracle.graal.python.builtins.objects.PythonAbstractObject; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Bind; @@ -72,6 +75,8 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.CArgObject) public final class CArgObjectBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = CArgObjectBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return CArgObjectBuiltinsFactory.getFactories(); @@ -96,7 +101,7 @@ static boolean isLiteralChar(char c) { return c < 128 && isPrintable(c) && c != '\\' && c != '\''; } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { @@ -162,9 +167,9 @@ abstract static class ParamFuncNode extends Node { @Specialization static PyCArgObject paramFunc(CDataObject self, StgDictObject stgDict, - @Cached(inline = false) PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached(inline = false) TruffleString.CodePointAtIndexNode codePointAtIndexNode) { - PyCArgObject parg = factory.createCArgObject(); + PyCArgObject parg = PFactory.createCArgObject(language); switch (stgDict.paramfunc) { // Corresponds to PyCArrayType_paramfunc case PyCArrayTypeParamFunc -> { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataBuiltins.java index a7deaae0c6..01af8e177d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,9 +47,8 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_TRUFFLE_CDATA_INIT_BUFFER_PROTOCOL; import static com.oracle.graal.python.nodes.BuiltinNames.T__CTYPES; import static com.oracle.graal.python.nodes.ErrorMessages.CTYPES_OBJECTS_CONTAINING_POINTERS_CANNOT_BE_PICKLED; -import static com.oracle.graal.python.nodes.ErrorMessages.S_DICT_MUST_BE_A_DICTIONARY_NOT_S; +import static com.oracle.graal.python.nodes.ErrorMessages.P_DICT_MUST_BE_A_DICTIONARY_NOT_P; import static com.oracle.graal.python.nodes.ErrorMessages.UNHASHABLE_TYPE; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.NotImplementedError; @@ -59,6 +58,9 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -73,7 +75,8 @@ import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; @@ -81,12 +84,11 @@ import com.oracle.graal.python.nodes.attributes.GetAttributeNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromPythonObjectNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Bind; @@ -101,6 +103,8 @@ @CoreFunctions(extendClasses = PyCData) public final class CDataBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = CDataBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return CDataBuiltinsFactory.getFactories(); @@ -152,13 +156,13 @@ static Object PyCData_from_outparam(CDataObject self) { } } - @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_hash, isComplex = true) @GenerateNodeFactory - protected abstract static class HashNode extends PythonBuiltinNode { + protected abstract static class HashNode extends HashBuiltinNode { @Specialization static long hash(@SuppressWarnings("unused") CDataObject self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, UNHASHABLE_TYPE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, UNHASHABLE_TYPE); } } @@ -169,30 +173,30 @@ protected abstract static class BaseReduceNode extends PythonUnaryBuiltinNode { @Specialization static Object reduce(VirtualFrame frame, CDataObject self, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached PyObjectStgDictNode pyObjectStgDictNode, @Cached("create(T___DICT__)") GetAttributeNode getAttributeNode, @Cached ReadAttributeFromPythonObjectNode readAttrNode, @Cached PointerNodes.ReadBytesNode readBytesNode, @Cached GetClassNode getClassNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { StgDictObject stgDict = pyObjectStgDictNode.execute(inliningTarget, self); if ((stgDict.flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER)) != 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, CTYPES_OBJECTS_CONTAINING_POINTERS_CANNOT_BE_PICKLED); + throw raiseNode.raise(inliningTarget, ValueError, CTYPES_OBJECTS_CONTAINING_POINTERS_CANNOT_BE_PICKLED); } Object dict = getAttributeNode.executeObject(frame, self); Object[] t1 = new Object[]{dict, null}; - t1[1] = factory.createBytes(readBytesNode.execute(inliningTarget, self.b_ptr, self.b_size)); + t1[1] = PFactory.createBytes(language, readBytesNode.execute(inliningTarget, self.b_ptr, self.b_size)); Object clazz = getClassNode.execute(inliningTarget, self); - Object[] t2 = new Object[]{clazz, factory.createTuple(t1)}; + Object[] t2 = new Object[]{clazz, PFactory.createTuple(language, t1)}; PythonModule ctypes = PythonContext.get(inliningTarget).lookupBuiltinModule(T__CTYPES); Object unpickle = readAttrNode.execute(ctypes, T_UNPICKLE, null); if (unpickle == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, toTruffleStringUncached("unpickle isn't supported yet.")); + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, toTruffleStringUncached("unpickle isn't supported yet.")); } - Object[] t3 = new Object[]{unpickle, factory.createTuple(t2)}; - return factory.createTuple(t3); // "O(O(NN))" + Object[] t3 = new Object[]{unpickle, PFactory.createTuple(language, t2)}; + return PFactory.createTuple(language, t3); // "O(O(NN))" } } @@ -206,15 +210,13 @@ static Object PyCData_setstate(VirtualFrame frame, CDataObject self, PTuple args @Bind("this") Node inliningTarget, @Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray, @Cached("create(T___DICT__)") GetAttributeNode getAttributeNode, - @Cached GetClassNode getClassNode, - @Cached GetNameNode getNameNode, @Cached PyNumberAsSizeNode asSizeNode, @Cached HashingStorageAddAllToOther addAllToOtherNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { SequenceStorage storage = args.getSequenceStorage(); Object[] array = getArray.execute(inliningTarget, storage); if (storage.length() < 3 || !PGuards.isDict(array[0]) || !PGuards.isInteger(array[2])) { - throw raiseNode.get(inliningTarget).raise(TypeError); + throw raiseNode.raise(inliningTarget, TypeError); } PDict dict = (PDict) array[0]; Object data = array[1]; @@ -227,9 +229,7 @@ static Object PyCData_setstate(VirtualFrame frame, CDataObject self, PTuple args memmove(inliningTarget, self.b_ptr, data, len); Object mydict = getAttributeNode.executeObject(frame, self); if (!PGuards.isDict(mydict)) { - throw raiseNode.get(inliningTarget).raise(TypeError, S_DICT_MUST_BE_A_DICTIONARY_NOT_S, - getNameNode.execute(inliningTarget, getClassNode.execute(inliningTarget, self)), - getNameNode.execute(inliningTarget, getClassNode.execute(inliningTarget, mydict))); + throw raiseNode.raise(inliningTarget, TypeError, P_DICT_MUST_BE_A_DICTIONARY_NOT_P, self, mydict); } PDict selfDict = (PDict) mydict; addAllToOtherNode.execute(frame, inliningTarget, dict.getDictStorage(), selfDict); @@ -239,7 +239,7 @@ static Object PyCData_setstate(VirtualFrame frame, CDataObject self, PTuple args @SuppressWarnings("unused") private static void memmove(Node raisingNode, Object dest, Object src, int len) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(raisingNode, NotImplementedError, toTruffleStringUncached("memmove is partially supported.")); // TODO + throw PRaiseNode.raiseStatic(raisingNode, NotImplementedError, toTruffleStringUncached("memmove is partially supported.")); // TODO } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataTypeBuiltins.java index 7e848296df..792672b3f5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataTypeBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -60,13 +60,13 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.IsInstanceNode; import com.oracle.graal.python.builtins.modules.SysModuleBuiltins.AuditNode; import com.oracle.graal.python.builtins.modules.ctypes.CFieldBuiltins.GetFuncNode; @@ -84,6 +84,7 @@ import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem; import com.oracle.graal.python.builtins.objects.dict.PDict; +import com.oracle.graal.python.builtins.objects.memoryview.MemoryViewBuiltins; import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; @@ -99,7 +100,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -156,7 +157,7 @@ static Object CDataType_from_param(VirtualFrame frame, Object type, Object value @Cached PyTypeStgDictNode pyTypeStgDictNode, @Cached PyObjectLookupAttr lookupAttr, @Cached IsInstanceNode isInstanceNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (isInstanceNode.executeWith(frame, value, type)) { return value; } @@ -174,7 +175,7 @@ static Object CDataType_from_param(VirtualFrame frame, Object type, Object value return value; } } - throw raiseNode.get(inliningTarget).raise(TypeError, EXPECTED_P_INSTANCE_INSTEAD_OF_POINTER_TO_P, type, ob != null ? ob : PNone.NONE); + throw raiseNode.raise(inliningTarget, TypeError, EXPECTED_P_INSTANCE_INSTEAD_OF_POINTER_TO_P, type, ob != null ? ob : PNone.NONE); } Object as_parameter = lookupAttr.execute(frame, inliningTarget, value, T__AS_PARAMETER_); @@ -183,7 +184,7 @@ static Object CDataType_from_param(VirtualFrame frame, Object type, Object value return CDataType_from_param(frame, type, as_parameter, inliningTarget, pyTypeStgDictNode, lookupAttr, isInstanceNode, raiseNode); } - throw raiseNode.get(inliningTarget).raise(TypeError, EXPECTED_P_INSTANCE_INSTEAD_OF_P, type, value); + throw raiseNode.raise(inliningTarget, TypeError, EXPECTED_P_INSTANCE_INSTEAD_OF_P, type, value); } } @@ -226,30 +227,30 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static Object CDataType_from_buffer(VirtualFrame frame, Object type, Object obj, int offset, @Bind("this") Node inliningTarget, - @Cached BuiltinConstructors.MemoryViewNode memoryViewNode, + @Cached MemoryViewBuiltins.MemoryViewNode memoryViewNode, @Cached PyTypeStgDictNode pyTypeStgDictNode, @Cached PyCDataAtAddress atAddress, @Cached KeepRefNode keepRefNode, @Cached AuditNode auditNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { StgDictObject dict = pyTypeStgDictNode.checkAbstractClass(inliningTarget, type, raiseNode); PMemoryView mv = memoryViewNode.execute(frame, obj); if (mv.isReadOnly()) { - throw raiseNode.get(inliningTarget).raise(TypeError, UNDERLYING_BUFFER_IS_NOT_WRITABLE); + throw raiseNode.raise(inliningTarget, TypeError, UNDERLYING_BUFFER_IS_NOT_WRITABLE); } if (!mv.isCContiguous()) { - throw raiseNode.get(inliningTarget).raise(TypeError, UNDERLYING_BUFFER_IS_NOT_C_CONTIGUOUS); + throw raiseNode.raise(inliningTarget, TypeError, UNDERLYING_BUFFER_IS_NOT_C_CONTIGUOUS); } if (offset < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, OFFSET_CANNOT_BE_NEGATIVE); + throw raiseNode.raise(inliningTarget, ValueError, OFFSET_CANNOT_BE_NEGATIVE); } if (dict.size > mv.getLength() - offset) { - throw raiseNode.get(inliningTarget).raise(ValueError, BUFFER_SIZE_TOO_SMALL_D_INSTEAD_OF_AT_LEAST_D_BYTES, mv.getLength(), dict.size + offset); + throw raiseNode.raise(inliningTarget, ValueError, BUFFER_SIZE_TOO_SMALL_D_INSTEAD_OF_AT_LEAST_D_BYTES, mv.getLength(), dict.size + offset); } auditNode.audit(inliningTarget, "ctypes.cdata/buffer", mv, mv.getLength(), offset); @@ -282,18 +283,18 @@ static Object CDataType_from_buffer_copy(Object type, Object buffer, int offset, @Cached AuditNode auditNode, @Cached CtypesNodes.GenericPyCDataNewNode pyCDataNewNode, @Cached PyTypeStgDictNode pyTypeStgDictNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { StgDictObject dict = pyTypeStgDictNode.checkAbstractClass(inliningTarget, type, raiseNode); if (offset < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, OFFSET_CANNOT_BE_NEGATIVE); + throw raiseNode.raise(inliningTarget, ValueError, OFFSET_CANNOT_BE_NEGATIVE); } int bufferLen = bufferLib.getBufferLength(buffer); if (dict.size > bufferLen - offset) { - throw raiseNode.get(inliningTarget).raise(ValueError, BUFFER_SIZE_TOO_SMALL_D_INSTEAD_OF_AT_LEAST_D_BYTES, bufferLen, dict.size + offset); + throw raiseNode.raise(inliningTarget, ValueError, BUFFER_SIZE_TOO_SMALL_D_INSTEAD_OF_AT_LEAST_D_BYTES, bufferLen, dict.size + offset); } // This prints the raw pointer in C, so just print 0 @@ -331,17 +332,17 @@ static Object CDataType_in_dll(VirtualFrame frame, Object type, Object dll, Truf @Cached AuditNode auditNode, @Cached PointerNodes.PointerFromLongNode pointerFromLongNode, @Cached CtypesDlSymNode dlSymNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { auditNode.audit(inliningTarget, "ctypes.dlsym", dll, name); Object obj = getAttributeNode.executeObject(frame, dll); if (!longCheckNode.execute(inliningTarget, obj)) { - throw raiseNode.get(inliningTarget).raise(TypeError, THE_HANDLE_ATTRIBUTE_OF_THE_SECOND_ARGUMENT_MUST_BE_AN_INTEGER); + throw raiseNode.raise(inliningTarget, TypeError, THE_HANDLE_ATTRIBUTE_OF_THE_SECOND_ARGUMENT_MUST_BE_AN_INTEGER); } Pointer handlePtr; try { handlePtr = pointerFromLongNode.execute(inliningTarget, obj); } catch (PException e) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.COULD_NOT_CONVERT_THE_HANDLE_ATTRIBUTE_TO_A_POINTER); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.COULD_NOT_CONVERT_THE_HANDLE_ATTRIBUTE_TO_A_POINTER); } Object address = dlSymNode.execute(frame, handlePtr, name, ValueError); if (address instanceof PythonNativeVoidPtr ptr) { @@ -365,7 +366,7 @@ static CDataObject PyCData_AtAddress(Object type, Pointer pointer, @Cached PyTypeCheck pyTypeCheck, @Cached PyTypeStgDictNode pyTypeStgDictNode, @Cached CtypesNodes.CreateCDataObjectNode createCDataObjectNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { // auditNode.audit("ctypes.cdata", buf); // assert(PyType_Check(type)); StgDictObject stgdict = pyTypeStgDictNode.checkAbstractClass(inliningTarget, type, raiseNode); @@ -420,6 +421,7 @@ protected abstract static class PyCDataSetNode extends Node { @Specialization static void PyCData_set(VirtualFrame frame, CDataObject dst, Object type, FieldSet setfunc, Object value, int index, int size, Pointer ptr, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached SetFuncNode setFuncNode, @Cached CallNode callNode, @Cached PyTypeCheck pyTypeCheck, @@ -429,14 +431,13 @@ static void PyCData_set(VirtualFrame frame, CDataObject dst, Object type, FieldS @Cached KeepRefNode keepRefNode, @Cached PointerNodes.MemcpyNode memcpyNode, @Cached PointerNodes.WritePointerNode writePointerNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (!pyTypeCheck.isCDataObject(inliningTarget, dst)) { - throw raiseNode.get(inliningTarget).raise(TypeError, NOT_A_CTYPE_INSTANCE); + throw raiseNode.raise(inliningTarget, TypeError, NOT_A_CTYPE_INSTANCE); } Object result = PyCDataSetInternal(frame, inliningTarget, type, setfunc, value, size, ptr, - factory, + language, pyTypeCheck, setFuncNode, callNode, @@ -455,7 +456,7 @@ static void PyCData_set(VirtualFrame frame, CDataObject dst, Object type, FieldS */ // corresponds to _PyCData_set static Object PyCDataSetInternal(VirtualFrame frame, Node inliningTarget, Object type, FieldSet setfunc, Object value, int size, Pointer ptr, - PythonObjectFactory factory, + PythonLanguage language, PyTypeCheck pyTypeCheck, SetFuncNode setFuncNode, CallNode callNode, @@ -464,7 +465,7 @@ static Object PyCDataSetInternal(VirtualFrame frame, Node inliningTarget, Object PyObjectStgDictNode pyObjectStgDictNode, PointerNodes.MemcpyNode memcpyNode, PointerNodes.WritePointerNode writePointerNode, - PRaiseNode.Lazy raiseNode) { + PRaiseNode raiseNode) { if (setfunc != FieldSet.nil) { return setFuncNode.execute(frame, setfunc, ptr, value, size); } @@ -480,7 +481,7 @@ static Object PyCDataSetInternal(VirtualFrame frame, Node inliningTarget, Object if (PGuards.isPTuple(value)) { Object ob = callNode.execute(frame, type, value); return PyCDataSetInternal(frame, inliningTarget, type, setfunc, ob, size, ptr, - factory, + language, pyTypeCheck, setFuncNode, callNode, @@ -494,14 +495,14 @@ static Object PyCDataSetInternal(VirtualFrame frame, Node inliningTarget, Object writePointerNode.execute(inliningTarget, ptr, Pointer.NULL); return PNone.NONE; } else { - throw raiseNode.get(inliningTarget).raise(TypeError, EXPECTED_P_INSTANCE_GOT_P, type, value); + throw raiseNode.raise(inliningTarget, TypeError, EXPECTED_P_INSTANCE_GOT_P, type, value); } } CDataObject src = (CDataObject) value; if (isInstanceNode.executeWith(frame, value, type)) { memcpyNode.execute(inliningTarget, ptr, src.b_ptr, size); - return GetKeepedObjects(src, factory); + return GetKeepedObjects(src, language); } if (pyTypeCheck.isPyCPointerTypeObject(inliningTarget, type) && pyTypeCheck.isArrayObject(inliningTarget, value)) { @@ -511,12 +512,12 @@ static Object PyCDataSetInternal(VirtualFrame frame, Node inliningTarget, Object assert p2 != null : "Cannot be NULL for pointer types"; if (p1.proto != p2.proto) { - throw raiseNode.get(inliningTarget).raise(TypeError, INCOMPATIBLE_TYPES_P_INSTANCE_INSTEAD_OF_P_INSTANCE, value, type); + throw raiseNode.raise(inliningTarget, TypeError, INCOMPATIBLE_TYPES_P_INSTANCE_INSTEAD_OF_P_INSTANCE, value, type); } writePointerNode.execute(inliningTarget, ptr, src.b_ptr); - Object keep = GetKeepedObjects(src, factory); + Object keep = GetKeepedObjects(src, language); /* * We are assigning an array object to a field which represents a pointer. This has @@ -525,9 +526,9 @@ static Object PyCDataSetInternal(VirtualFrame frame, Node inliningTarget, Object * it's object list. So we create a tuple, containing b_objects list PLUS the array * itself, and return that! */ - return factory.createTuple(new Object[]{keep, value}); + return PFactory.createTuple(language, new Object[]{keep, value}); } - throw raiseNode.get(inliningTarget).raise(TypeError, INCOMPATIBLE_TYPES_P_INSTANCE_INSTEAD_OF_P_INSTANCE, value, type); + throw raiseNode.raise(inliningTarget, TypeError, INCOMPATIBLE_TYPES_P_INSTANCE_INSTEAD_OF_P_INSTANCE, value, type); } } @@ -536,14 +537,14 @@ static Object PyCDataSetInternal(VirtualFrame frame, Node inliningTarget, Object * Code to keep needed objects alive */ - protected static CDataObject PyCData_GetContainer(CDataObject leaf, PythonObjectFactory factory) { + protected static CDataObject PyCData_GetContainer(CDataObject leaf, PythonLanguage language) { CDataObject self = leaf; while (self.b_base != null) { self = self.b_base; } if (self.b_objects == null) { if (self.b_length != 0) { - self.b_objects = factory.createDict(); + self.b_objects = PFactory.createDict(language); } else { self.b_objects = PNone.NONE; } @@ -551,8 +552,8 @@ protected static CDataObject PyCData_GetContainer(CDataObject leaf, PythonObject return self; } - static Object GetKeepedObjects(CDataObject target, PythonObjectFactory factory) { - return PyCData_GetContainer(target, factory).b_objects; + static Object GetKeepedObjects(CDataObject target, PythonLanguage language) { + return PyCData_GetContainer(target, language).b_objects; } /* @@ -585,13 +586,13 @@ static void none(CDataObject target, int index, PNone keep) { @Specialization(guards = "!isNone(keep)") static void KeepRef(VirtualFrame frame, Node inliningTarget, CDataObject target, int index, Object keep, + @Bind PythonLanguage language, @Cached(inline = false) TruffleStringBuilder.AppendStringNode appendStringNode, @Cached(inline = false) TruffleStringBuilder.ToStringNode toStringNode, @Cached(inline = false) TruffleString.FromJavaStringNode fromJavaStringNode, @Cached HashingStorageSetItem setItem, - @Cached(inline = false) PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - CDataObject ob = PyCData_GetContainer(target, factory); + @Cached PRaiseNode raiseNode) { + CDataObject ob = PyCData_GetContainer(target, language); if (!PGuards.isDict(ob.b_objects)) { ob.b_objects = keep; return; @@ -605,7 +606,7 @@ static void KeepRef(VirtualFrame frame, Node inliningTarget, CDataObject target, private static final int MAX_KEY_SIZE = 256; static TruffleString unique_key(Node inliningTarget, CDataObject cdata, int index, - PRaiseNode.Lazy raiseNode, TruffleStringBuilder.AppendStringNode appendStringNode, + PRaiseNode raiseNode, TruffleStringBuilder.AppendStringNode appendStringNode, TruffleStringBuilder.ToStringNode toStringNode, TruffleString.FromJavaStringNode fromJavaStringNode) { assert TS_ENCODING == Encoding.UTF_32; final int bytesPerCodepoint = 4; // assumes utf-32 @@ -617,7 +618,7 @@ static TruffleString unique_key(Node inliningTarget, CDataObject cdata, int inde int bytesLeft = MAX_KEY_SIZE - sb.byteLength() / bytesPerCodepoint - 1; /* Hex format needs 2 characters per byte */ if (bytesLeft < Integer.BYTES * 2) { - throw raiseNode.get(inliningTarget).raise(ValueError, CTYPES_OBJECT_STRUCTURE_TOO_DEEP); + throw raiseNode.raise(inliningTarget, ValueError, CTYPES_OBJECT_STRUCTURE_TOO_DEEP); } appendStringNode.execute(sb, T_COLON); appendStringNode.execute(sb, fromJavaStringNode.execute(toHex(target.b_index), TS_ENCODING)); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataTypeSequenceBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataTypeSequenceBuiltins.java index b760db1fc6..c522f5fee0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataTypeSequenceBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataTypeSequenceBuiltins.java @@ -56,6 +56,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.CoreFunctions; @@ -76,7 +77,7 @@ import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -116,9 +117,9 @@ static Object PyCArrayType_from_ctype(VirtualFrame frame, Object itemtype, int l @Cached IsTypeNode isTypeNode, @Cached GetNameNode getNameNode, @Cached SimpleTruffleStringFormatNode simpleFormatNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - Object key = factory.createTuple(new Object[]{itemtype, length}); + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { + Object key = PFactory.createTuple(language, new Object[]{itemtype, length}); CtypesThreadState ctypes = CtypesThreadState.get(context, context.getLanguage(inliningTarget)); Object result = getItem.execute(frame, inliningTarget, ctypes.cache, key); if (result != null) { @@ -126,11 +127,11 @@ static Object PyCArrayType_from_ctype(VirtualFrame frame, Object itemtype, int l } if (!isTypeNode.execute(inliningTarget, itemtype)) { - throw raiseNode.get(inliningTarget).raise(TypeError, EXPECTED_A_TYPE_OBJECT); + throw raiseNode.raise(inliningTarget, TypeError, EXPECTED_A_TYPE_OBJECT); } TruffleString name = simpleFormatNode.format("%s_Array_%d", getNameNode.execute(inliningTarget, itemtype), length); - PDict dict = factory.createDict(new PKeyword[]{new PKeyword(T__LENGTH_, length), new PKeyword(T__TYPE_, itemtype)}); - PTuple tuple = factory.createTuple(new Object[]{PyCArray}); + PDict dict = PFactory.createDict(language, new PKeyword[]{new PKeyword(T__LENGTH_, length), new PKeyword(T__TYPE_, itemtype)}); + PTuple tuple = PFactory.createTuple(language, new Object[]{PyCArray}); result = callNode.execute(frame, PyCArrayType, name, tuple, dict); HashingStorage newStorage = setItem.execute(frame, inliningTarget, ctypes.cache, key, result); assert newStorage == ctypes.cache; @@ -139,8 +140,8 @@ static Object PyCArrayType_from_ctype(VirtualFrame frame, Object itemtype, int l @Specialization(guards = "length < 0") static Object error(@SuppressWarnings("unused") Object self, int length, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ARRAY_LENGTH_MUST_BE_0_NOT_D, length); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ARRAY_LENGTH_MUST_BE_0_NOT_D, length); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CFieldBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CFieldBuiltins.java index c5d71e14c5..858baed7f6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CFieldBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CFieldBuiltins.java @@ -45,7 +45,6 @@ import static com.oracle.graal.python.nodes.ErrorMessages.CANT_DELETE_ATTRIBUTE; import static com.oracle.graal.python.nodes.ErrorMessages.HAS_NO_STGINFO; import static com.oracle.graal.python.nodes.ErrorMessages.NOT_A_CTYPE_INSTANCE; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.NotImplementedError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; @@ -55,6 +54,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.Builtin; @@ -94,7 +94,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; @@ -153,9 +153,9 @@ static void doit(VirtualFrame frame, CFieldObject self, Object inst, Object valu @Bind("this") Node inliningTarget, @Cached PyTypeCheck pyTypeCheck, @Cached PyCDataSetNode cDataSetNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (!pyTypeCheck.isCDataObject(inliningTarget, inst)) { - throw raiseNode.get(inliningTarget).raise(TypeError, NOT_A_CTYPE_INSTANCE); + throw raiseNode.raise(inliningTarget, TypeError, NOT_A_CTYPE_INSTANCE); } CDataObject dst = (CDataObject) inst; cDataSetNode.execute(frame, dst, self.proto, self.setfunc, value, self.index, self.size, dst.b_ptr.withOffset(self.offset)); @@ -164,8 +164,8 @@ static void doit(VirtualFrame frame, CFieldObject self, Object inst, Object valu @Specialization(guards = "isNoValue(value)") @InliningCutoff static void doit(CFieldObject self, Object inst, Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, CANT_DELETE_ATTRIBUTE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, CANT_DELETE_ATTRIBUTE); } } @@ -180,19 +180,19 @@ static Object doit(CFieldObject self, Object inst, @SuppressWarnings("unused") O @Cached InlinedConditionProfile instIsNoValueProfile, @Cached PyCDataGetNode pyCDataGetNode, @Cached PyTypeCheck pyTypeCheck, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (instIsNoValueProfile.profile(inliningTarget, inst == PNone.NO_VALUE)) { return self; } if (!pyTypeCheck.isCDataObject(inliningTarget, inst)) { - throw raiseNode.get(inliningTarget).raise(TypeError, NOT_A_CTYPE_INSTANCE); + throw raiseNode.raise(inliningTarget, TypeError, NOT_A_CTYPE_INSTANCE); } CDataObject src = (CDataObject) inst; return pyCDataGetNode.execute(inliningTarget, self.proto, self.getfunc, src, self.index, self.size, src.b_ptr.withOffset(self.offset)); } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { @@ -237,17 +237,18 @@ TruffleString PyCField_repr(CFieldObject self, @SuppressWarnings("fallthrough") abstract static class PyCFieldFromDesc extends Node { - abstract CFieldObject execute(Node inliningTarget, Object desc, int index, int bitsize, int pack, boolean big_endian, int[] props, PythonObjectFactory factory); + abstract CFieldObject execute(Node inliningTarget, Object desc, int index, int bitsize, int pack, boolean big_endian, int[] props); @Specialization - static CFieldObject PyCField_FromDesc(Node inliningTarget, Object desc, int index, int bitsize, int pack, boolean big_endian, int[] props, PythonObjectFactory factory, + static CFieldObject PyCField_FromDesc(Node inliningTarget, Object desc, int index, int bitsize, int pack, boolean big_endian, int[] props, + @Bind PythonLanguage language, @Cached PyTypeCheck pyTypeCheck, @Cached PyTypeStgDictNode pyTypeStgDictNode, - @Cached PRaiseNode.Lazy raiseNode) { - CFieldObject self = factory.createCFieldObject(PythonBuiltinClassType.CField); + @Cached PRaiseNode raiseNode) { + CFieldObject self = PFactory.createCFieldObject(language); StgDictObject dict = pyTypeStgDictNode.execute(inliningTarget, desc); if (dict == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, HAS_NO_STGINFO); + throw raiseNode.raise(inliningTarget, TypeError, HAS_NO_STGINFO); } int fieldtype; if (bitsize != 0 /* this is a bitfield request */ @@ -287,7 +288,7 @@ static CFieldObject PyCField_FromDesc(Node inliningTarget, Object desc, int inde if (adict != null && adict.proto != null) { StgDictObject idict = pyTypeStgDictNode.execute(inliningTarget, adict.proto); if (idict == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, HAS_NO_STGINFO); + throw raiseNode.raise(inliningTarget, TypeError, HAS_NO_STGINFO); } if (idict.getfunc == FieldDesc.c.getfunc) { FieldDesc fd = FieldDesc.s; @@ -559,8 +560,7 @@ static Object f_set_sw(VirtualFrame frame, @SuppressWarnings("unused") FieldSet @SuppressWarnings("unused") static Object O_set(@SuppressWarnings("unused") FieldSet setfunc, Pointer ptr, Object value, @SuppressWarnings("unused") int size, @Bind("this") Node inliningTarget, - @Exclusive @Cached PointerNodes.WritePointerNode writePointerNode, - @Shared @Cached PythonObjectFactory factory) { + @Exclusive @Cached PointerNodes.WritePointerNode writePointerNode) { writePointerNode.execute(inliningTarget, ptr, Pointer.pythonObject(value)); return PNone.NONE; } @@ -570,7 +570,7 @@ static Object c_set(@SuppressWarnings("unused") FieldSet setfunc, Pointer ptr, O @Bind("this") Node inliningTarget, @Cached GetInternalByteArrayNode getBytes, @Exclusive @Cached PointerNodes.WriteByteNode writeByteNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (PGuards.isBytes(value)) { PBytesLike bytes = (PBytesLike) value; if (bytes.getSequenceStorage().length() == 1) { @@ -587,7 +587,7 @@ static Object c_set(@SuppressWarnings("unused") FieldSet setfunc, Pointer ptr, O } } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ONE_CHARACTER_BYTES_BYTEARRAY_INTEGER_EXPECTED); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ONE_CHARACTER_BYTES_BYTEARRAY_INTEGER_EXPECTED); } /* u - a single wchar_t character */ @@ -598,14 +598,14 @@ static Object u_set(@SuppressWarnings("unused") FieldSet setfunc, Pointer ptr, O @Shared @Cached TruffleString.SwitchEncodingNode switchEncodingNode, @Shared @Cached TruffleString.GetInternalByteArrayNode getInternalByteArrayNode, @Exclusive @Cached PointerNodes.WriteBytesNode writeBytesNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { // CTYPES_UNICODE + @Exclusive @Cached PRaiseNode raiseNode) { // CTYPES_UNICODE if (!PGuards.isString(value)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.UNICODE_STRING_EXPECTED_INSTEAD_OF_P_INSTANCE, value); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.UNICODE_STRING_EXPECTED_INSTEAD_OF_P_INSTANCE, value); } TruffleString str = switchEncodingNode.execute(toString.execute(inliningTarget, value), WCHAR_T_ENCODING); InternalByteArray bytes = getInternalByteArrayNode.execute(str, WCHAR_T_ENCODING); if (bytes.getLength() != WCHAR_T_SIZE) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ONE_CHARACTER_UNICODE_EXPECTED); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ONE_CHARACTER_UNICODE_EXPECTED); } writeBytesNode.execute(inliningTarget, ptr, bytes.getArray(), bytes.getOffset(), bytes.getLength()); return PNone.NONE; @@ -618,15 +618,15 @@ static Object U_set(@SuppressWarnings("unused") FieldSet setfunc, Pointer ptr, O @Shared @Cached TruffleString.SwitchEncodingNode switchEncodingNode, @Shared @Cached TruffleString.GetInternalByteArrayNode getInternalByteArrayNode, @Exclusive @Cached PointerNodes.WriteBytesNode writeBytesNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { // CTYPES_UNICODE + @Exclusive @Cached PRaiseNode raiseNode) { // CTYPES_UNICODE if (!PGuards.isString(value)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.UNICODE_STRING_EXPECTED_INSTEAD_OF_P_INSTANCE, value); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.UNICODE_STRING_EXPECTED_INSTEAD_OF_P_INSTANCE, value); } TruffleString str = switchEncodingNode.execute(toString.execute(inliningTarget, value), WCHAR_T_ENCODING); InternalByteArray bytes = getInternalByteArrayNode.execute(str, WCHAR_T_ENCODING); if (bytes.getLength() > size) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.STR_TOO_LONG, bytes.getLength(), size); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.STR_TOO_LONG, bytes.getLength(), size); } writeBytesNode.execute(inliningTarget, ptr, bytes.getArray(), bytes.getOffset(), bytes.getLength()); return value; @@ -637,9 +637,9 @@ static Object s_set(@SuppressWarnings("unused") FieldSet setfunc, Pointer ptr, O @Bind("this") Node inliningTarget, @Cached ToBytesWithoutFrameNode getBytes, @Exclusive @Cached PointerNodes.WriteBytesNode writeBytesNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (!PGuards.isPBytes(value)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.EXPECTED_BYTES_P_FOUND, value); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.EXPECTED_BYTES_P_FOUND, value); } byte[] data = getBytes.execute(inliningTarget, value); @@ -650,7 +650,7 @@ static Object s_set(@SuppressWarnings("unused") FieldSet setfunc, Pointer ptr, O */ ++size; } else if (size > length) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.BYTES_TOO_LONG, size, length); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.BYTES_TOO_LONG, size, length); } writeBytesNode.execute(inliningTarget, ptr, data); @@ -664,7 +664,7 @@ static Object z_set(@SuppressWarnings("unused") FieldSet setfunc, Pointer ptr, O @Exclusive @Cached PointerNodes.PointerFromLongNode pointerFromLongNode, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Exclusive @Cached PointerNodes.WritePointerNode writePointerNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (value == PNone.NONE) { writePointerNode.execute(inliningTarget, ptr, Pointer.NULL); return PNone.NONE; @@ -686,20 +686,20 @@ static Object z_set(@SuppressWarnings("unused") FieldSet setfunc, Pointer ptr, O new PointerReference(value, valuePtr, PythonContext.get(inliningTarget).getSharedFinalizer()); return value; } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.BYTES_OR_INT_ADDR_EXPECTED_INSTEAD_OF_P, value); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.BYTES_OR_INT_ADDR_EXPECTED_INSTEAD_OF_P, value); } @Specialization(guards = "setfunc == Z_set") static Object Z_set(@SuppressWarnings("unused") FieldSet setfunc, Pointer ptr, Object value, @SuppressWarnings("unused") int size, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Exclusive @Cached CastToTruffleStringNode toString, @Exclusive @Cached PyLongCheckNode longCheckNode, @Exclusive @Cached PointerNodes.PointerFromLongNode pointerFromLongNode, @Shared @Cached TruffleString.SwitchEncodingNode switchEncodingNode, @Cached TruffleString.CopyToByteArrayNode copyToByteArrayNode, @Exclusive @Cached PointerNodes.WritePointerNode writePointerNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode, - @Shared @Cached PythonObjectFactory factory) { // CTYPES_UNICODE + @Exclusive @Cached PRaiseNode raiseNode) { // CTYPES_UNICODE if (value == PNone.NONE) { writePointerNode.execute(inliningTarget, ptr, Pointer.NULL); return PNone.NONE; @@ -708,7 +708,7 @@ static Object Z_set(@SuppressWarnings("unused") FieldSet setfunc, Pointer ptr, O return PNone.NONE; } if (!PGuards.isString(value)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.UNICODE_STR_OR_INT_ADDR_EXPECTED_INSTEAD_OF_P, value); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.UNICODE_STR_OR_INT_ADDR_EXPECTED_INSTEAD_OF_P, value); } TruffleString str = switchEncodingNode.execute(toString.execute(inliningTarget, value), WCHAR_T_ENCODING); @@ -719,41 +719,37 @@ static Object Z_set(@SuppressWarnings("unused") FieldSet setfunc, Pointer ptr, O /* ptr is a char**, we need to add the indirection */ Pointer valuePtr = Pointer.bytes(bytes); writePointerNode.execute(inliningTarget, ptr, valuePtr); - return createPyMemCapsule(valuePtr, factory); + return createPyMemCapsule(valuePtr, context, inliningTarget); } @Specialization(guards = "setfunc == P_set") static Object P_set(@SuppressWarnings("unused") FieldSet setfunc, Pointer ptr, Object value, @SuppressWarnings("unused") int size, @Bind("this") Node inliningTarget, - @Exclusive @Cached PyLongCheckNode longCheckNode, @Exclusive @Cached PointerNodes.PointerFromLongNode pointerFromLongNode, - @Exclusive @Cached PointerNodes.WritePointerNode writePointerNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PointerNodes.WritePointerNode writePointerNode) { Pointer valuePtr; if (value == PNone.NONE) { valuePtr = Pointer.NULL; - } else if (longCheckNode.execute(inliningTarget, value)) { - valuePtr = pointerFromLongNode.execute(inliningTarget, value); } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANNOT_BE_CONVERTED_TO_POINTER); + valuePtr = pointerFromLongNode.execute(inliningTarget, value); } - writePointerNode.execute(inliningTarget, ptr, valuePtr); return PNone.NONE; } @SuppressWarnings("unused") @Fallback - static Object error(VirtualFrame frame, FieldSet setfunc, Pointer ptr, Object value, int size) { + static Object error(VirtualFrame frame, FieldSet setfunc, Pointer ptr, Object value, int size, + @Bind("this") Node inliningTarget) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.getUncached().raise(NotImplementedError, toTruffleStringUncached("Field setter %s is not supported yet."), setfunc.name()); + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, toTruffleStringUncached("Field setter %s is not supported yet."), setfunc.name()); } private static final byte[] CTYPES_CFIELD_CAPSULE_NAME_PYMEM = PyCapsule.capsuleName("_ctypes/cfield.c pymem"); - private static PyCapsule createPyMemCapsule(Pointer pointer, PythonObjectFactory factory) { - PyCapsule capsule = factory.createCapsuleJavaName(pointer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM); - new PointerReference(capsule, pointer, PythonContext.get(factory).getSharedFinalizer()); + private static PyCapsule createPyMemCapsule(Pointer pointer, PythonContext context, Node inliningTarget) { + PyCapsule capsule = PFactory.createCapsuleJavaName(context.getLanguage(inliningTarget), pointer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM); + new PointerReference(capsule, pointer, context.getSharedFinalizer()); return capsule; } } @@ -879,21 +875,21 @@ static Object l_get_sw(@SuppressWarnings("unused") FieldGet getfunc, Pointer ptr @Specialization(guards = "getfunc == L_get") static Object L_get(@SuppressWarnings("unused") FieldGet getfunc, Pointer ptr, @SuppressWarnings("unused") int size, @Bind("this") Node inliningTarget, - @Shared @Cached PointerNodes.ReadLongNode readLongNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language, + @Shared @Cached PointerNodes.ReadLongNode readLongNode) { long val = readLongNode.execute(inliningTarget, ptr); // GET_BITFIELD(val, size); - return val < 0 ? factory.createInt(PInt.longToUnsignedBigInteger(val)) : val; + return val < 0 ? PFactory.createInt(language, PInt.longToUnsignedBigInteger(val)) : val; } @Specialization(guards = "getfunc == L_get_sw") static Object L_get_sw(@SuppressWarnings("unused") FieldGet getfunc, Pointer ptr, @SuppressWarnings("unused") int size, @Bind("this") Node inliningTarget, - @Shared @Cached PointerNodes.ReadLongNode readLongNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language, + @Shared @Cached PointerNodes.ReadLongNode readLongNode) { long val = SWAP_8(readLongNode.execute(inliningTarget, ptr)); // GET_BITFIELD(val, size); - return val < 0 ? factory.createInt(PInt.longToUnsignedBigInteger(val)) : val; + return val < 0 ? PFactory.createInt(language, PInt.longToUnsignedBigInteger(val)) : val; } @Specialization(guards = "getfunc == d_get") @@ -934,7 +930,7 @@ static Object O_get(@SuppressWarnings("unused") FieldGet getfunc, Pointer ptr, @ @Cached PRaiseNode raiseNode) { Pointer valuePtr = readPointerNode.execute(inliningTarget, ptr); if (valuePtr.isNull()) { - throw raiseNode.raise(ValueError, ErrorMessages.PY_OBJ_IS_NULL); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.PY_OBJ_IS_NULL); } return readPythonObject.execute(inliningTarget, valuePtr); } @@ -942,9 +938,9 @@ static Object O_get(@SuppressWarnings("unused") FieldGet getfunc, Pointer ptr, @ @Specialization(guards = "getfunc == c_get") static Object c_get(@SuppressWarnings("unused") FieldGet getfunc, Pointer ptr, @SuppressWarnings("unused") int size, @Bind("this") Node inliningTarget, - @Shared @Cached PointerNodes.ReadByteNode readByteNode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createBytes(new byte[]{readByteNode.execute(inliningTarget, ptr)}); + @Bind PythonLanguage language, + @Shared @Cached PointerNodes.ReadByteNode readByteNode) { + return PFactory.createBytes(language, new byte[]{readByteNode.execute(inliningTarget, ptr)}); } @Specialization(guards = "getfunc == u_get") @@ -973,17 +969,17 @@ static Object U_get(@SuppressWarnings("unused") FieldGet getfunc, Pointer ptr, i @Specialization(guards = "getfunc == s_get") static Object s_get(@SuppressWarnings("unused") FieldGet getfunc, Pointer ptr, int size, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Shared @Cached PointerNodes.StrLenNode strLenNode, - @Shared @Cached PointerNodes.ReadBytesNode readBytesNode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createBytes(readBytesNode.execute(inliningTarget, ptr, strLenNode.execute(inliningTarget, ptr, size))); + @Shared @Cached PointerNodes.ReadBytesNode readBytesNode) { + return PFactory.createBytes(language, readBytesNode.execute(inliningTarget, ptr, strLenNode.execute(inliningTarget, ptr, size))); } @Specialization(guards = "getfunc == z_get") static Object z_get(@SuppressWarnings("unused") FieldGet getfunc, Pointer ptr, @SuppressWarnings("unused") int size, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Shared @Cached PointerNodes.ReadPointerNode readPointerNode, - @Shared @Cached PythonObjectFactory factory, @Shared @Cached PointerNodes.StrLenNode strLenNode, @Shared @Cached PointerNodes.ReadBytesNode readBytesNode) { // ptr is a char**, we need to deref it to get char* @@ -992,7 +988,7 @@ static Object z_get(@SuppressWarnings("unused") FieldGet getfunc, Pointer ptr, @ return PNone.NONE; } byte[] bytes = readBytesNode.execute(inliningTarget, valuePtr, strLenNode.execute(inliningTarget, valuePtr)); - return factory.createBytes(bytes); + return PFactory.createBytes(language, bytes); } @Specialization(guards = "getfunc == Z_get") @@ -1015,9 +1011,9 @@ static Object Z_get(@SuppressWarnings("unused") FieldGet getfunc, Pointer ptr, @ @Specialization(guards = "getfunc == P_get") static Object P_get(@SuppressWarnings("unused") FieldGet getfunc, Pointer ptr, @SuppressWarnings("unused") int size, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Exclusive @Cached PointerNodes.ReadPointerNode readPointerNode, - @Cached PointerNodes.GetPointerValueAsObjectNode getPointerValueAsObjectNode, - @Shared @Cached PythonObjectFactory factory) { + @Cached PointerNodes.GetPointerValueAsObjectNode getPointerValueAsObjectNode) { Pointer valuePtr = readPointerNode.execute(inliningTarget, ptr); if (valuePtr.isNull()) { return 0L; @@ -1025,9 +1021,9 @@ static Object P_get(@SuppressWarnings("unused") FieldGet getfunc, Pointer ptr, @ Object p = getPointerValueAsObjectNode.execute(inliningTarget, valuePtr); if (p instanceof Long) { long val = (long) p; - return val < 0 ? factory.createInt(PInt.longToUnsignedBigInteger(val)) : val; + return val < 0 ? PFactory.createInt(language, PInt.longToUnsignedBigInteger(val)) : val; } - return factory.createNativeVoidPtr(p); + return PFactory.createNativeVoidPtr(language, p); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CThunkObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CThunkObject.java index 5c8fe53714..307dd8fc86 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CThunkObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CThunkObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -167,7 +167,7 @@ Object execute(Object[] pArgs, memcpyNode.execute(inliningTarget, obj.b_ptr, value, dict.size); arglist[i] = obj; } else { - throw raiseNode.raise(TypeError, CANNOT_BUILD_PARAMETER); + throw raiseNode.raise(inliningTarget, TypeError, CANNOT_BUILD_PARAMETER); // PrintError("Parsing argument %zd\n", i); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesModuleBuiltins.java index fb56f967a4..1a0df16b23 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesModuleBuiltins.java @@ -53,8 +53,8 @@ import static com.oracle.graal.python.nodes.BuiltinNames.J__CTYPES; import static com.oracle.graal.python.nodes.BuiltinNames.T__CTYPES; import static com.oracle.graal.python.nodes.ErrorMessages.ARGUMENT_D; -import static com.oracle.graal.python.nodes.ErrorMessages.BYREF_ARGUMENT_MUST_BE_A_CTYPES_INSTANCE_NOT_S; -import static com.oracle.graal.python.nodes.ErrorMessages.CAST_ARGUMENT_2_MUST_BE_A_POINTER_TYPE_NOT_S; +import static com.oracle.graal.python.nodes.ErrorMessages.BYREF_ARGUMENT_MUST_BE_A_CTYPES_INSTANCE_NOT_P; +import static com.oracle.graal.python.nodes.ErrorMessages.CAST_ARGUMENT_2_MUST_BE_A_POINTER_TYPE_NOT_N; import static com.oracle.graal.python.nodes.ErrorMessages.DON_T_KNOW_HOW_TO_CONVERT_PARAMETER_D; import static com.oracle.graal.python.nodes.ErrorMessages.EXCEPTED_CTYPES_INSTANCE; import static com.oracle.graal.python.nodes.ErrorMessages.FFI_CALL_FAILED; @@ -71,7 +71,6 @@ import static com.oracle.graal.python.nodes.ErrorMessages.TOO_MANY_ARGUMENTS_D_MAXIMUM_IS_D; import static com.oracle.graal.python.nodes.StringLiterals.J_DEFAULT; import static com.oracle.graal.python.nodes.StringLiterals.J_EMPTY_STRING; -import static com.oracle.graal.python.nodes.StringLiterals.J_LLVM_LANGUAGE; import static com.oracle.graal.python.nodes.StringLiterals.J_NFI_LANGUAGE; import static com.oracle.graal.python.nodes.StringLiterals.T_LPAREN; import static com.oracle.graal.python.runtime.PosixConstants.RTLD_GLOBAL; @@ -87,7 +86,6 @@ import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; -import java.io.IOException; import java.util.List; import java.util.logging.Level; @@ -121,9 +119,6 @@ import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol; import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions; import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CByteArrayWrapper; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ApiInitException; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ImportException; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNIContext; import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem; @@ -148,7 +143,6 @@ import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.SpecialMethodNames; import com.oracle.graal.python.nodes.StringLiterals; import com.oracle.graal.python.nodes.attributes.GetAttributeNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; @@ -167,10 +161,8 @@ import com.oracle.graal.python.nodes.util.CastToJavaStringNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; @@ -242,7 +234,7 @@ protected List> getNodeFa @Override public void initialize(Python3Core core) { super.initialize(core); - addBuiltinConstant("_pointer_type_cache", core.factory().createDict()); + addBuiltinConstant("_pointer_type_cache", PFactory.createDict(core.getLanguage())); if (PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32) { addBuiltinConstant("FUNCFLAG_STDCALL", FUNCFLAG_STDCALL); } @@ -259,11 +251,11 @@ public void initialize(Python3Core core) { @Override public void postInitialize(Python3Core core) { super.postInitialize(core); - PythonObjectFactory factory = core.factory(); + PythonLanguage language = core.getLanguage(); PythonModule ctypesModule = core.lookupBuiltinModule(T__CTYPES); - ctypesModule.setAttribute(tsLiteral("_string_at_addr"), factory.createNativeVoidPtr(StringAtFunction.create())); - ctypesModule.setAttribute(tsLiteral("_cast_addr"), factory.createNativeVoidPtr(CastFunction.create())); - ctypesModule.setAttribute(tsLiteral("_wstring_at_addr"), factory.createNativeVoidPtr(WStringAtFunction.create())); + ctypesModule.setAttribute(tsLiteral("_string_at_addr"), PFactory.createNativeVoidPtr(language, StringAtFunction.create())); + ctypesModule.setAttribute(tsLiteral("_cast_addr"), PFactory.createNativeVoidPtr(language, CastFunction.create())); + ctypesModule.setAttribute(tsLiteral("_wstring_at_addr"), PFactory.createNativeVoidPtr(language, WStringAtFunction.create())); int rtldLocal = RTLD_LOCAL.getValueIfDefined(); ctypesModule.setAttribute(tsLiteral("RTLD_LOCAL"), rtldLocal); ctypesModule.setAttribute(tsLiteral("RTLD_GLOBAL"), RTLD_GLOBAL.getValueIfDefined()); @@ -277,29 +269,15 @@ public void postInitialize(Python3Core core) { if (PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32) { PythonModule sysModule = context.getSysModule(); Object loadLibraryMethod = ReadAttributeFromObjectNode.getUncached().execute(ctypesModule, toTruffleStringUncached("LoadLibrary")); - Object pythonLib = CallNode.executeUncached(loadLibraryMethod, toTruffleStringUncached(GraalHPyJNIContext.getJNILibrary()), 0); + Object pythonLib = CallNode.executeUncached(loadLibraryMethod, toTruffleStringUncached(PythonContext.getSupportLibName("python-native")), 0); WriteAttributeToPythonObjectNode.getUncached().execute(sysModule, toTruffleStringUncached("dllhandle"), pythonLib); } - } else if (!PythonOptions.NativeModules.getValue(context.getEnv().getOptions())) { - // If native is not available, we can use the C API support library only if it was - // loaded through LLVM and not NFI. This limitation can be lifted: we can reload the - // library with LLVM here. - try { - Object llvmLibrary = CApiContext.ensureCApiLLVMLibrary(context); - handle = new DLHandler(llvmLibrary, 0, J_EMPTY_STRING, true); - } catch (ApiInitException e) { - throw e.reraise(null, null, PConstructAndRaiseNode.Lazy.getUncached()); - } catch (ImportException e) { - throw e.reraise(null, null, PConstructAndRaiseNode.Lazy.getUncached()); - } catch (IOException e) { - throw PConstructAndRaiseNode.getUncached().raiseOSError(null, e, EqualNode.getUncached()); - } } if (handle != null) { NativeFunction memmove = MemMoveFunction.create(handle, context); - ctypesModule.setAttribute(tsLiteral("_memmove_addr"), factory.createNativeVoidPtr(memmove, memmove.adr)); + ctypesModule.setAttribute(tsLiteral("_memmove_addr"), PFactory.createNativeVoidPtr(language, memmove, memmove.adr)); NativeFunction memset = MemSetFunction.create(handle, context); - ctypesModule.setAttribute(tsLiteral("_memset_addr"), factory.createNativeVoidPtr(memset, memset.adr)); + ctypesModule.setAttribute(tsLiteral("_memset_addr"), PFactory.createNativeVoidPtr(language, memset, memset.adr)); } // If handle == null, and we don't set the attributes, ctypes module is going to fail in // __init__.py on importing those attributes from _ctypes. This way the failure will happen @@ -355,10 +333,6 @@ protected boolean isManaged() { return isManaged; } - protected boolean isLLVM() { - return sym instanceof CallLLVMFunction; - } - protected boolean isManaged(long address) { return adr == address; } @@ -510,9 +484,9 @@ static Object POINTER(VirtualFrame frame, Object cls, @Cached GetNameNode getNameNode, @Cached CastToTruffleStringNode toTruffleStringNode, @Cached SimpleTruffleStringFormatNode formatNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - CtypesThreadState ctypes = CtypesThreadState.get(context, context.getLanguage(inliningTarget)); + @Cached PRaiseNode raiseNode) { + PythonLanguage language = context.getLanguage(inliningTarget); + CtypesThreadState ctypes = CtypesThreadState.get(context, language); Object result = getItem.execute(frame, inliningTarget, ctypes.ptrtype_cache, cls); if (result != null) { return result; @@ -521,17 +495,17 @@ static Object POINTER(VirtualFrame frame, Object cls, if (PGuards.isString(cls)) { TruffleString name = toTruffleStringNode.execute(inliningTarget, cls); TruffleString buf = formatNode.format("LP_%s", name); - Object[] args = new Object[]{buf, PyCPointer, factory.createDict()}; + Object[] args = new Object[]{buf, PyCPointer, PFactory.createDict(language)}; result = callNode.execute(frame, PyCPointerType, args, PKeyword.EMPTY_KEYWORDS); - key = factory.createNativeVoidPtr(result); + key = PFactory.createNativeVoidPtr(language, result); } else if (isTypeNode.execute(inliningTarget, cls)) { TruffleString buf = formatNode.format("LP_%s", getNameNode.execute(inliningTarget, cls)); - PTuple bases = factory.createTuple(new Object[]{PyCPointer}); - Object[] args = new Object[]{buf, bases, factory.createDict(new PKeyword[]{new PKeyword(T__TYPE_, cls)})}; + PTuple bases = PFactory.createTuple(language, new Object[]{PyCPointer}); + Object[] args = new Object[]{buf, bases, PFactory.createDict(language, new PKeyword[]{new PKeyword(T__TYPE_, cls)})}; result = callNode.execute(frame, PyCPointerType, args, PKeyword.EMPTY_KEYWORDS); key = cls; } else { - throw raiseNode.get(inliningTarget).raise(TypeError, MUST_BE_A_CTYPES_TYPE); + throw raiseNode.raise(inliningTarget, TypeError, MUST_BE_A_CTYPES_TYPE); } HashingStorage newStorage = setItem.execute(frame, inliningTarget, ctypes.ptrtype_cache, key, result); assert newStorage == ctypes.ptrtype_cache; @@ -561,7 +535,6 @@ static Object pointer(VirtualFrame frame, Object arg, } } - @ImportStatic(SpecialMethodNames.class) @Builtin(name = J_UNPICKLE, minNumOfPositionalArgs = 2) @GenerateNodeFactory protected abstract static class UnpickleNode extends PythonBinaryBuiltinNode { @@ -569,7 +542,9 @@ protected abstract static class UnpickleNode extends PythonBinaryBuiltinNode { @Specialization Object unpickle(VirtualFrame frame, Object typ, PTuple state, @Cached CallNode callNode, - @Cached("create(New)") LookupAndCallUnaryNode lookupAndCallUnaryNode, + // This shouldn't call the slot directly to make sure the check in the + // wrapper runs + @Cached("create(T___NEW__)") LookupAndCallUnaryNode lookupAndCallUnaryNode, @Cached("create(T___SETSTATE__)") GetAttributeNode setStateAttr) { Object obj = lookupAndCallUnaryNode.executeObject(frame, typ); Object meth = setStateAttr.executeObject(frame, obj); @@ -588,21 +563,21 @@ static Object buffer_info(Object arg, @Bind("this") Node inliningTarget, @Cached PyTypeStgDictNode pyTypeStgDictNode, @Cached PyObjectStgDictNode pyObjectStgDictNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { StgDictObject dict = pyTypeStgDictNode.execute(inliningTarget, arg); if (dict == null) { dict = pyObjectStgDictNode.execute(inliningTarget, arg); } if (dict == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, NOT_A_CTYPES_TYPE_OR_OBJECT); + throw raiseNode.raise(inliningTarget, TypeError, NOT_A_CTYPES_TYPE_OR_OBJECT); } Object[] shape = new Object[dict.ndim]; for (int i = 0; i < dict.ndim; ++i) { shape[i] = dict.shape[i]; } - return factory.createTuple(new Object[]{dict.format, dict.ndim, factory.createTuple(shape)}); + return PFactory.createTuple(language, new Object[]{dict.format, dict.ndim, PFactory.createTuple(language, shape)}); } } @@ -620,16 +595,16 @@ protected ArgumentClinicProvider getArgumentClinic() { static Object resize(CDataObject obj, int size, @Bind("this") Node inliningTarget, @Cached PyObjectStgDictNode pyObjectStgDictNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { StgDictObject dict = pyObjectStgDictNode.execute(inliningTarget, obj); if (dict == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, EXCEPTED_CTYPES_INSTANCE); + throw raiseNode.raise(inliningTarget, TypeError, EXCEPTED_CTYPES_INSTANCE); } if (size < dict.size) { - throw raiseNode.get(inliningTarget).raise(ValueError, MINIMUM_SIZE_IS_D, dict.size); + throw raiseNode.raise(inliningTarget, ValueError, MINIMUM_SIZE_IS_D, dict.size); } if (obj.b_needsfree) { - throw raiseNode.get(inliningTarget).raise(ValueError, MEMORY_CANNOT_BE_RESIZED_BECAUSE_THIS_OBJECT_DOESN_T_OWN_IT); + throw raiseNode.raise(inliningTarget, ValueError, MEMORY_CANNOT_BE_RESIZED_BECAUSE_THIS_OBJECT_DOESN_T_OWN_IT); } obj.b_size = size; return PNone.NONE; @@ -687,16 +662,6 @@ private static Object load(PythonContext context, String src, String name) { return context.getEnv().parseInternal(loadSrc).call(); } - @TruffleBoundary - protected static Object loadLLVMLibrary(PythonContext context, Node nodeForRaise, TruffleString path) throws ImportException, ApiInitException, IOException { - context.ensureLLVMLanguage(nodeForRaise); - if (path.isEmpty()) { - return CApiContext.ensureCApiLLVMLibrary(context); - } - Source loadSrc = Source.newBuilder(J_LLVM_LANGUAGE, context.getPublicTruffleFileRelaxed(path)).build(); - return context.getEnv().parseInternal(loadSrc).call(); - } - @TruffleBoundary private static TruffleString getErrMsg(Exception e) { String errmsg = e != null ? e.getMessage() : null; @@ -712,10 +677,10 @@ static Object py_dl_open(PythonModule self, TruffleString name, int m, @Bind("this") Node inliningTarget, @Cached AuditNode auditNode) { PythonContext context = PythonContext.get(inliningTarget); - PythonObjectSlowPathFactory factory = context.factory(); + PythonLanguage language = context.getLanguage(inliningTarget); auditNode.audit(inliningTarget, "ctypes.dlopen", name); if (name.isEmpty()) { - return factory.createNativeVoidPtr(((CtypesModuleBuiltins) self.getBuiltins()).rtldDefault); + return PFactory.createNativeVoidPtr(language, ((CtypesModuleBuiltins) self.getBuiltins()).rtldDefault); } // The loaded library can link against libpython, so we have to make sure it is loaded @@ -726,13 +691,7 @@ static Object py_dl_open(PythonModule self, TruffleString name, int m, DLHandler handle; Exception exception = null; try { - if (!context.getEnv().isNativeAccessAllowed() && !PythonOptions.NativeModules.getValue(context.getEnv().getOptions())) { - Object handler = loadLLVMLibrary(context, inliningTarget, name); - long adr = PyObjectHashNode.executeUncached(handler); - handle = new DLHandler(handler, adr, name.toJavaStringUncached(), true); - registerAddress(context, handle.adr, handle); - return factory.createNativeVoidPtr(handle); - } else if (context.getEnv().isNativeAccessAllowed()) { + if (context.getEnv().isNativeAccessAllowed()) { CtypesThreadState ctypes = CtypesThreadState.get(context, context.getLanguage()); /*- TODO: (mq) cryptography in macos isn't always compatible with ctypes. @@ -741,13 +700,13 @@ static Object py_dl_open(PythonModule self, TruffleString name, int m, if (!eqNode.execute(name, MACOS_Security_LIB, TS_ENCODING) && !eqNode.execute(name, MACOS_CoreFoundation_LIB, TS_ENCODING)) { handle = loadNFILibrary(context, ctypes.backendType, name.toJavaStringUncached(), mode); registerAddress(context, handle.adr, handle); - return factory.createNativeVoidPtr(handle, handle.adr); + return PFactory.createNativeVoidPtr(language, handle, handle.adr); } } } catch (Exception e) { exception = e; } - throw PRaiseNode.raiseUncached(inliningTarget, OSError, getErrMsg(exception)); + throw PRaiseNode.raiseStatic(inliningTarget, OSError, getErrMsg(exception)); } } @@ -759,13 +718,13 @@ protected abstract static class DlCloseNode extends PythonUnaryBuiltinNode { static Object py_dl_close(Object pointerObj, @Bind("this") Node inliningTarget, @Cached CtypesNodes.HandleFromLongNode handleFromLongNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { DLHandler handle = handleFromLongNode.getDLHandler(inliningTarget, pointerObj); if (handle != null) { handle.isClosed = true; return PNone.NONE; } - throw raiseNode.get(inliningTarget).raise(OSError, T_DL_ERROR); + throw raiseNode.raise(inliningTarget, OSError, T_DL_ERROR); } } @@ -777,32 +736,26 @@ protected abstract static class CtypesDlSymNode extends PNodeWithContext { @Specialization static Object ctypes_dlsym(VirtualFrame frame, Pointer handlePtr, Object n, PythonBuiltinClassType error, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached CtypesNodes.HandleFromPointerNode handleFromPointerNode, @Cached PyObjectHashNode hashNode, @Cached CastToJavaStringNode asString, @CachedLibrary(limit = "1") InteropLibrary ilib, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { DLHandler handle = handleFromPointerNode.getDLHandler(inliningTarget, handlePtr); String name = asString.execute(n); if (handle == null || handle.isClosed) { - throw raiseNode.get(inliningTarget).raise(error, T_DL_ERROR); + throw raiseNode.raise(inliningTarget, error, T_DL_ERROR); } try { Object sym = ilib.readMember(handle.library, name); - boolean isManaged = handle.isManaged; - long adr = isManaged ? hashNode.execute(frame, inliningTarget, sym) : ilib.asPointer(sym); - sym = isManaged ? CallLLVMFunction.create(sym, ilib) : sym; - NativeFunction func = new NativeFunction(sym, adr, name, isManaged); - registerAddress(PythonContext.get(inliningTarget), adr, func); + long adr = ilib.asPointer(sym); + NativeFunction func = new NativeFunction(sym, adr, name, false); + registerAddress(context, adr, func); // PyLong_FromVoidPtr(ptr); - if (!isManaged) { - return factory.createNativeVoidPtr(func, adr); - } else { - return factory.createNativeVoidPtr(func); - } + return PFactory.createNativeVoidPtr(context.getLanguage(inliningTarget), func, adr); } catch (UnsupportedMessageException | UnknownIdentifierException e) { - throw raiseNode.get(inliningTarget).raise(error, e); + throw raiseNode.raise(inliningTarget, error, e); } } } @@ -865,9 +818,9 @@ static Object doBytes(PythonModule self, PBytes path, @Cached ToBytesNode toBytesNode, @CachedLibrary(limit = "1") InteropLibrary ilib, @CachedLibrary(limit = "1") InteropLibrary resultLib, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (!hasDynamicLoaderCache()) { - throw raiseNode.get(inliningTarget).raise(NotImplementedError, S_SYMBOL_IS_MISSING, DYLD_SHARED_CACHE_CONTAINS_PATH); + throw raiseNode.raise(inliningTarget, NotImplementedError, S_SYMBOL_IS_MISSING, DYLD_SHARED_CACHE_CONTAINS_PATH); } CtypesModuleBuiltins builtins = (CtypesModuleBuiltins) self.getBuiltins(); @@ -921,7 +874,7 @@ static Object align_func(Object obj, @Bind("this") Node inliningTarget, @Cached PyTypeStgDictNode pyTypeStgDictNode, @Cached PyObjectStgDictNode pyObjectStgDictNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { StgDictObject dict = pyTypeStgDictNode.execute(inliningTarget, obj); if (dict != null) { return dict.align; @@ -932,7 +885,7 @@ static Object align_func(Object obj, return dict.align; } - throw raiseNode.get(inliningTarget).raise(TypeError, NO_ALIGNMENT_INFO); + throw raiseNode.raise(inliningTarget, TypeError, NO_ALIGNMENT_INFO); } } @@ -945,7 +898,7 @@ static Object doit(Object obj, @Bind("this") Node inliningTarget, @Cached PyTypeCheck pyTypeCheck, @Cached PyTypeStgDictNode pyTypeStgDictNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { StgDictObject dict = pyTypeStgDictNode.execute(inliningTarget, obj); if (dict != null) { return dict.size; @@ -954,7 +907,7 @@ static Object doit(Object obj, if (pyTypeCheck.isCDataObject(inliningTarget, obj)) { return ((CDataObject) obj).b_size; } - throw raiseNode.get(inliningTarget).raise(TypeError, THIS_TYPE_HAS_NO_SIZE); + throw raiseNode.raise(inliningTarget, TypeError, THIS_TYPE_HAS_NO_SIZE); } } @@ -971,14 +924,13 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization Object doit(CDataObject obj, int offset, @Bind("this") Node inliningTarget, - @Exclusive @Cached GetClassNode getClassNode, @Cached PyTypeCheck pyTypeCheck, - @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Exclusive @Cached PRaiseNode raiseNode) { if (!pyTypeCheck.isCDataObject(inliningTarget, obj)) { - return error(null, obj, offset, inliningTarget, getClassNode, raiseNode); + return error(null, obj, offset, inliningTarget, raiseNode); } - PyCArgObject parg = factory.createCArgObject(); + PyCArgObject parg = PFactory.createCArgObject(language); parg.tag = 'P'; parg.pffi_type = FFIType.ffi_type_pointer; parg.obj = obj; @@ -991,11 +943,8 @@ Object doit(CDataObject obj, int offset, @Fallback static Object error(VirtualFrame frame, Object obj, Object off, @Bind("this") Node inliningTarget, - @Exclusive @Cached GetClassNode getClassNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - Object clazz = getClassNode.execute(inliningTarget, obj); - TruffleString name = GetNameNode.executeUncached(clazz); - throw raiseNode.get(inliningTarget).raise(TypeError, BYREF_ARGUMENT_MUST_BE_A_CTYPES_INSTANCE_NOT_S, name); + @Exclusive @Cached PRaiseNode raiseNode) { + throw raiseNode.raise(inliningTarget, TypeError, BYREF_ARGUMENT_MUST_BE_A_CTYPES_INSTANCE_NOT_P, obj); } } @@ -1036,21 +985,21 @@ protected abstract static class AddressOfNode extends PythonUnaryBuiltinNode { @Specialization static Object doit(CDataObject obj, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached PyTypeCheck pyTypeCheck, @Cached AuditNode auditNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (!pyTypeCheck.isCDataObject(inliningTarget, obj)) { - return error(obj, raiseNode.get(inliningTarget)); + return error(obj, raiseNode); } auditNode.audit(inliningTarget, "ctypes.addressof", obj); - return factory.createNativeVoidPtr(obj.b_ptr); + return PFactory.createNativeVoidPtr(language, obj.b_ptr); } @Fallback static Object error(@SuppressWarnings("unused") Object o, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, INVALID_TYPE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, INVALID_TYPE); } } @@ -1082,8 +1031,8 @@ static Object call_function(VirtualFrame frame, Object pointerObj, PTuple argume protected abstract static class FormatErrorNode extends PythonUnaryBuiltinNode { @Specialization static Object doit(@SuppressWarnings("unused") Object errorCode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(NotImplementedError); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError); } } @@ -1153,10 +1102,10 @@ Object _ctypes_callproc(VirtualFrame frame, NativeFunction pProc, Object[] argar @Cached CallNode callNode, @Cached GetResultNode getResultNode, @CachedLibrary(limit = "1") InteropLibrary ilib, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int argcount = argarray.length; if (argcount > CTYPES_MAX_ARGCOUNT) { - throw raiseNode.get(inliningTarget).raise(ArgError, TOO_MANY_ARGUMENTS_D_MAXIMUM_IS_D, argcount, CTYPES_MAX_ARGCOUNT); + throw raiseNode.raise(inliningTarget, ArgError, TOO_MANY_ARGUMENTS_D_MAXIMUM_IS_D, argcount, CTYPES_MAX_ARGCOUNT); } CTypesCallArgument[] args = new CTypesCallArgument[argcount]; @@ -1167,11 +1116,7 @@ Object _ctypes_callproc(VirtualFrame frame, NativeFunction pProc, Object[] argar /* Convert the arguments */ BackendMode mode = BackendMode.NFI; if (pProc.isManaged()) { - if (pProc.isLLVM()) { - mode = BackendMode.LLVM; - } else { - mode = BackendMode.INTRINSIC; - } + mode = BackendMode.INTRINSIC; } for (int i = 0; i < argcount; ++i) { args[i] = new CTypesCallArgument(); @@ -1185,7 +1130,7 @@ Object _ctypes_callproc(VirtualFrame frame, NativeFunction pProc, Object[] argar try { v = callNode.execute(frame, converters[i], arg); } catch (PException e) { - throw raiseNode.get(inliningTarget).raise(ArgError, ARGUMENT_D, i + 1); + throw raiseNode.raise(inliningTarget, ArgError, ARGUMENT_D, i + 1); } } convParamNode.execute(frame, v, i + 1, args[i]); @@ -1208,7 +1153,7 @@ Object _ctypes_callproc(VirtualFrame frame, NativeFunction pProc, Object[] argar if (mode == BackendMode.NFI) { result = callNativeFunction(inliningTarget, pProc, avalues, atypes, rtype, ilib, raiseNode); } else { - result = callManagedFunction(inliningTarget, pProc, avalues, ilib, raiseNode); + result = callManagedFunction(inliningTarget, pProc, avalues, ilib); if (mode == BackendMode.INTRINSIC) { /* * We don't want result conversion for functions implemented in Java, they @@ -1221,18 +1166,18 @@ Object _ctypes_callproc(VirtualFrame frame, NativeFunction pProc, Object[] argar return getResultNode.execute(frame, restype, rtype, result, checker); } - static Object callManagedFunction(Node inliningTarget, NativeFunction pProc, Object[] argarray, InteropLibrary ilib, PRaiseNode.Lazy raiseNode) { + static Object callManagedFunction(Node inliningTarget, NativeFunction pProc, Object[] argarray, InteropLibrary ilib) { try { return ilib.execute(pProc.sym, argarray); } catch (PException e) { throw e; } catch (UnsupportedTypeException | ArityException | UnsupportedMessageException | AbstractTruffleException e) { CompilerDirectives.transferToInterpreter(); - throw PRaiseNode.raiseUncached(inliningTarget, RuntimeError, FFI_CALL_FAILED); + throw PRaiseNode.raiseStatic(inliningTarget, RuntimeError, FFI_CALL_FAILED); } catch (UnsupportedSpecializationException ee) { // TODO: llvm/GR-??? CompilerDirectives.transferToInterpreter(); - throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, toTruffleStringUncached("require backend support.")); + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, toTruffleStringUncached("require backend support.")); } } @@ -1247,7 +1192,7 @@ protected Object getFunction(NativeFunction pProc, String signature) throws Exce * NFI compatible native function calls (temporary replacement) */ Object callNativeFunction(Node inliningTarget, NativeFunction pProc, Object[] avalues, FFIType[] atypes, FFIType restype, - InteropLibrary ilib, PRaiseNode.Lazy raiseNode) { + InteropLibrary ilib, PRaiseNode raiseNode) { Object function; if (pProc.function != null && equals(atypes, pProc.atypes) && restype == pProc.rtype) { function = pProc.function; @@ -1256,7 +1201,7 @@ Object callNativeFunction(Node inliningTarget, NativeFunction pProc, Object[] av try { function = getFunction(pProc, signature.toJavaStringUncached()); } catch (Exception e) { - throw raiseNode.get(inliningTarget).raise(RuntimeError, FFI_PREP_CIF_FAILED); + throw raiseNode.raise(inliningTarget, RuntimeError, FFI_PREP_CIF_FAILED); } pProc.atypes = atypes; pProc.rtype = restype; @@ -1267,7 +1212,7 @@ Object callNativeFunction(Node inliningTarget, NativeFunction pProc, Object[] av return ilib.execute(function, avalues); } catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) { CompilerDirectives.transferToInterpreter(); - throw PRaiseNode.raiseUncached(inliningTarget, RuntimeError, FFI_CALL_FAILED); + throw PRaiseNode.raiseStatic(inliningTarget, RuntimeError, FFI_CALL_FAILED); } } @@ -1413,7 +1358,7 @@ static Object callGetFunc(VirtualFrame frame, Object restype, FFIType rtype, Obj // value for large structs, because NFI still needs to allocate and pass the // buffer for the result to the callee. CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, SystemError, ErrorMessages.RETURNING_STRUCT_BY_VALUE_NOT_SUPPORTED); + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, ErrorMessages.RETURNING_STRUCT_BY_VALUE_NOT_SUPPORTED); } case FFI_TYPE_POINTER -> { // NOTE: we are returning pointer to the result buffer and the result buffer @@ -1488,7 +1433,7 @@ void convParam(VirtualFrame frame, Object obj, int index, CTypesCallArgument pa, @Cached PyObjectStgDictNode pyObjectStgDictNode, @Cached CArgObjectBuiltins.ParamFuncNode paramFuncNode, @Cached ConvParamNode recursive, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (obj instanceof CDataObject cdata) { pa.stgDict = pyObjectStgDictNode.execute(inliningTarget, cdata); PyCArgObject carg = paramFuncNode.execute(inliningTarget, cdata, pa.stgDict); @@ -1521,7 +1466,7 @@ void convParam(VirtualFrame frame, Object obj, int index, CTypesCallArgument pa, pa.valuePointer = Pointer.create(pa.ffi_type, pa.ffi_type.size, asInt.executeExact(frame, inliningTarget, obj), 0); } catch (PException e) { e.expectOverflowError(inliningTarget, profile); - throw raiseNode.get(inliningTarget).raise(OverflowError, INT_TOO_LONG_TO_CONVERT); + throw raiseNode.raise(inliningTarget, OverflowError, INT_TOO_LONG_TO_CONVERT); } return; } @@ -1561,7 +1506,7 @@ void convParam(VirtualFrame frame, Object obj, int index, CTypesCallArgument pa, recursive.execute(frame, arg, index, pa, false); return; } - throw raiseNode.get(inliningTarget).raise(TypeError, DON_T_KNOW_HOW_TO_CONVERT_PARAMETER_D, index); + throw raiseNode.raise(inliningTarget, TypeError, DON_T_KNOW_HOW_TO_CONVERT_PARAMETER_D, index); } } @@ -1641,9 +1586,8 @@ static Object doIntrinsicPointer(Node inliningTarget, CTypesCallArgument arg, @S @Specialization(guards = {"mode == NFI", "isFFIType(arg, FFI_TYPE_STRUCT)"}) @SuppressWarnings("unused") - static Object doNFIStruct(Node inliningTarget, CTypesCallArgument arg, @SuppressWarnings("unused") BackendMode mode, - @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.NotImplementedError, ErrorMessages.PASSING_STRUCTS_BY_VALUE_NOT_SUPPORTED); + static Object doNFIStruct(Node inliningTarget, CTypesCallArgument arg, @SuppressWarnings("unused") BackendMode mode) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.NotImplementedError, ErrorMessages.PASSING_STRUCTS_BY_VALUE_NOT_SUPPORTED); } @Specialization(guards = {"mode == LLVM", "isFFIType(arg, FFI_TYPE_STRUCT)"}) @@ -1731,6 +1675,7 @@ boolean isExecutable() { @ExportMessage Object execute(Object[] arguments, + @Bind("$node") Node inliningTarget, @Cached TruffleString.ToJavaStringNode toJavaStringNode, @CachedLibrary("this.llvmSym") InteropLibrary ilib) { try { @@ -1741,7 +1686,7 @@ Object execute(Object[] arguments, } return ilib.execute(llvmSym, arguments); } catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) { - throw PRaiseNode.getUncached().raise(RuntimeError, e); + throw PRaiseNode.raiseStatic(inliningTarget, RuntimeError, e); } } } @@ -1756,10 +1701,9 @@ static void raiseError(Object arg, @Cached PRaiseNode raiseNode, @Cached IsTypeNode isTypeNode, @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached GetNameNode getNameNode) { + @Cached GetClassNode getClassNode) { Object clazz = isTypeNode.execute(inliningTarget, arg) ? arg : getClassNode.execute(inliningTarget, arg); - throw raiseNode.raise(TypeError, CAST_ARGUMENT_2_MUST_BE_A_POINTER_TYPE_NOT_S, getNameNode.execute(inliningTarget, clazz)); + throw raiseNode.raise(inliningTarget, TypeError, CAST_ARGUMENT_2_MUST_BE_A_POINTER_TYPE_NOT_N, clazz); } } @@ -1815,9 +1759,9 @@ protected abstract static class CastFunctionNode extends Node { @Specialization Object cast(Pointer ptr, Pointer srcObj, Pointer ctypeObj, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached HashingStorageSetItem setItem, @Cached PyTypeCheck pyTypeCheck, - @Cached PythonObjectFactory factory, @Cached CallNode callNode, @Cached CastCheckPtrTypeNode castCheckPtrTypeNode, @Cached PointerNodes.ReadPythonObject readPythonObject, @@ -1838,16 +1782,16 @@ Object cast(Pointer ptr, Pointer srcObj, Pointer ctypeObj, * PyCData_GetContainer will initialize src.b_objects, we need this so it can be * shared */ - PyCData_GetContainer(cdata, factory); + PyCData_GetContainer(cdata, language); if (cdata.b_objects == null) { - cdata.b_objects = factory.createDict(); + cdata.b_objects = PFactory.createDict(language); } result.b_objects = cdata.b_objects; if (PGuards.isDict(result.b_objects)) { // PyLong_FromVoidPtr((void *)src); PDict dict = (PDict) result.b_objects; - Object index = factory.createNativeVoidPtr(cdata); + Object index = PFactory.createNativeVoidPtr(language, cdata); dict.setDictStorage(setItem.execute(null, inliningTarget, dict.getDictStorage(), index, cdata)); } } @@ -1887,10 +1831,10 @@ protected abstract static class MemmoveNode extends Node { @Specialization static Object memmove(Node inliningTarget, Pointer destPtr, Pointer srcPtr, long size, - @Cached PointerNodes.MemcpyNode memcpyNode, - @Cached(inline = false) PythonObjectFactory factory) { + @Bind PythonLanguage language, + @Cached PointerNodes.MemcpyNode memcpyNode) { memcpyNode.execute(inliningTarget, destPtr, srcPtr, (int) size); - return factory.createNativeVoidPtr(destPtr); + return PFactory.createNativeVoidPtr(language, destPtr); } } @@ -1949,9 +1893,9 @@ protected abstract static class MemsetNode extends Node { @Specialization static Object memset(Node inliningTarget, Pointer ptr, int value, long size, + @Bind PythonLanguage language, @Cached PointerNodes.WriteLongNode writeLongNode, - @Cached PointerNodes.WriteByteNode writeByteNode, - @Cached(inline = false) PythonObjectFactory factory) { + @Cached PointerNodes.WriteByteNode writeByteNode) { byte b = (byte) value; long fill = 0; for (int i = 0; i < Long.BYTES * 8; i += 8) { @@ -1969,7 +1913,7 @@ static Object memset(Node inliningTarget, Pointer ptr, int value, long size, for (; i < size; i++) { writeByteNode.execute(inliningTarget, ptr.withOffset(i), b); } - return factory.createNativeVoidPtr(ptr); + return PFactory.createNativeVoidPtr(language, ptr); } } @@ -2027,15 +1971,15 @@ protected abstract static class StringAtFunctionNode extends Node { @Specialization static Object string_at(Pointer ptr, int size, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached PointerNodes.ReadBytesNode read, @Cached PointerNodes.StrLenNode strLenNode, @Cached AuditNode auditNode) { - auditNode.audit(inliningTarget, "ctypes.string_at", factory.createNativeVoidPtr(ptr), size); + auditNode.audit(inliningTarget, "ctypes.string_at", PFactory.createNativeVoidPtr(language, ptr), size); if (size == -1) { size = strLenNode.execute(inliningTarget, ptr); } - return factory.createBytes(read.execute(inliningTarget, ptr, size)); + return PFactory.createBytes(language, read.execute(inliningTarget, ptr, size)); } } @@ -2070,13 +2014,13 @@ protected abstract static class WStringAtFunctionNode extends Node { @Specialization static TruffleString wstring_at(Pointer ptr, int size, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached AuditNode auditNode, @Cached PointerNodes.ReadBytesNode read, @Cached PointerNodes.WCsLenNode wCsLenNode, @Cached TruffleString.FromByteArrayNode fromByteArrayNode, @Cached TruffleString.SwitchEncodingNode switchEncodingNode) { - auditNode.audit(inliningTarget, "ctypes.wstring_at", factory.createNativeVoidPtr(ptr), size); + auditNode.audit(inliningTarget, "ctypes.wstring_at", PFactory.createNativeVoidPtr(language, ptr), size); if (size == -1) { size = wCsLenNode.execute(inliningTarget, ptr); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesNodes.java index 6b706257f4..90ce8009fa 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -57,6 +57,7 @@ import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.truffle.api.strings.TruffleString.Encoding.US_ASCII; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonOS; import com.oracle.graal.python.builtins.modules.ctypes.FFIType.FFI_TYPES; @@ -66,6 +67,7 @@ import com.oracle.graal.python.builtins.objects.cext.common.NativePointer; import com.oracle.graal.python.builtins.objects.cext.structs.CFields; import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; import com.oracle.graal.python.lib.PyObjectTypeCheck; @@ -73,9 +75,10 @@ import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -313,7 +316,7 @@ public abstract static class PyCDataFromBaseObjNode extends Node { @Specialization static CDataObject PyCData_FromBaseObj(Node inliningTarget, Object type, CDataObject base, int index, Pointer adr, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached StgDictBuiltins.PyTypeStgDictNode pyTypeStgDictNode, @Cached CreateCDataObjectNode createCDataObjectNode, @Cached PyCDataMallocBufferNode mallocBufferNode, @@ -344,12 +347,13 @@ public abstract static class CreateCDataObjectNode extends Node { @Specialization static CDataObject doCreate(Node inliningTarget, Object type, Pointer pointer, int size, boolean needsfree, @Cached(inline = false) IsSubtypeNode isSubtypeNode, - @Cached(inline = false) PythonObjectFactory factory) { + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Bind PythonLanguage language) { CDataObject result; if (isSubtypeNode.execute(type, PyCFuncPtr)) { - result = factory.createPyCFuncPtrObject(type, pointer, size, needsfree); + result = PFactory.createPyCFuncPtrObject(language, type, getInstanceShape.execute(type), pointer, size, needsfree); } else { - result = factory.createCDataObject(type, pointer, size, needsfree); + result = PFactory.createCDataObject(language, type, getInstanceShape.execute(type), pointer, size, needsfree); } if (needsfree) { new PointerReference(result, pointer, PythonContext.get(inliningTarget).getSharedFinalizer()); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCArrayTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCArrayTypeBuiltins.java index d5ba1bf969..956b8676c9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCArrayTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCArrayTypeBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -76,9 +76,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.IndirectCallData; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -133,10 +131,9 @@ private static void createGetSet(PythonLanguage language, Object type, NodeFacto l -> new BuiltinFunctionRootNode(l, builtin, factory, true), factory.getNodeClass(), builtin.name()); - PythonObjectSlowPathFactory f = PythonContext.get(null).factory(); int flags = PBuiltinFunction.getFlags(builtin, rawCallTarget); - PBuiltinFunction getter = f.createBuiltinFunction(name, type, 1, flags, rawCallTarget); - GetSetDescriptor callable = f.createGetSetDescriptor(getter, getter, name, type, false); + PBuiltinFunction getter = PFactory.createBuiltinFunction(language, name, type, 1, flags, rawCallTarget); + GetSetDescriptor callable = PFactory.createGetSetDescriptor(language, getter, getter, name, type, false); callable.setAttribute(T___DOC__, toTruffleStringUncached(builtin.doc())); WriteAttributeToObjectNode.getUncached(true).execute(type, name, callable); } @@ -147,10 +144,10 @@ abstract static class CharArrayRawNode extends PythonBinaryBuiltinNode { @Specialization(guards = "isNoValue(value)") static PBytes doGet(CDataObject self, @SuppressWarnings("unused") PNone value, + @Bind PythonLanguage language, @Bind("this") Node inliningTarget, - @Cached PointerNodes.ReadBytesNode read, - @Cached PythonObjectFactory factory) { - return factory.createBytes(read.execute(inliningTarget, self.b_ptr, self.b_size)); + @Cached PointerNodes.ReadBytesNode read) { + return PFactory.createBytes(language, read.execute(inliningTarget, self.b_ptr, self.b_size)); } @Specialization(limit = "3") @@ -160,13 +157,13 @@ static Object doSet(VirtualFrame frame, CDataObject self, Object value, @CachedLibrary("value") PythonBufferAcquireLibrary acquireLib, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Cached PointerNodes.WriteBytesNode writeBytesNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object buffer = acquireLib.acquire(value, BufferFlags.PyBUF_SIMPLE, frame, indirectCallData); try { byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); int len = bufferLib.getBufferLength(buffer); if (len > self.b_size) { - throw raiseNode.get(inliningTarget).raise(ValueError, BYTE_STRING_TOO_LONG); + throw raiseNode.raise(inliningTarget, ValueError, BYTE_STRING_TOO_LONG); } writeBytesNode.execute(inliningTarget, self.b_ptr, bytes, 0, len); return PNone.NONE; @@ -183,10 +180,10 @@ abstract static class CharArrayValueNode extends PythonBinaryBuiltinNode { @Specialization(guards = "isNoValue(value)") static PBytes doGet(CDataObject self, @SuppressWarnings("unused") PNone value, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached PointerNodes.StrLenNode strLenNode, - @Cached PointerNodes.ReadBytesNode read, - @Cached PythonObjectFactory factory) { - return factory.createBytes(read.execute(inliningTarget, self.b_ptr, strLenNode.execute(inliningTarget, self.b_ptr))); + @Cached PointerNodes.ReadBytesNode read) { + return PFactory.createBytes(language, read.execute(inliningTarget, self.b_ptr, strLenNode.execute(inliningTarget, self.b_ptr))); } @Specialization @@ -194,11 +191,11 @@ static Object doSet(CDataObject self, PBytes value, @Bind("this") Node inliningTarget, @Cached GetInternalByteArrayNode getBytes, @Cached PointerNodes.WriteBytesNode writeBytesNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { SequenceStorage storage = value.getSequenceStorage(); int len = storage.length(); if (len > self.b_size) { - throw raiseNode.get(inliningTarget).raise(ValueError, BYTE_STRING_TOO_LONG); + throw raiseNode.raise(inliningTarget, ValueError, BYTE_STRING_TOO_LONG); } byte[] bytes = getBytes.execute(inliningTarget, storage); writeBytesNode.execute(inliningTarget, self.b_ptr, bytes, 0, len); @@ -207,8 +204,8 @@ static Object doSet(CDataObject self, PBytes value, @Fallback static Object error(@SuppressWarnings("unused") Object self, Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, BYTES_EXPECTED_INSTEAD_OF_P_INSTANCE, value); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, BYTES_EXPECTED_INSTEAD_OF_P_INSTANCE, value); } } @@ -235,11 +232,11 @@ static Object doSet(CDataObject self, Object value, @Shared @Cached TruffleString.SwitchEncodingNode switchEncodingNode, @Cached TruffleString.GetInternalByteArrayNode getInternalByteArrayNode, @Cached PointerNodes.WriteBytesNode writeBytesNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleString str = switchEncodingNode.execute(toTruffleStringNode.execute(inliningTarget, value), WCHAR_T_ENCODING); int len = str.byteLength(WCHAR_T_ENCODING); if (len > self.b_size) { - throw raiseNode.get(inliningTarget).raise(ValueError, STRING_TOO_LONG); + throw raiseNode.raise(inliningTarget, ValueError, STRING_TOO_LONG); } InternalByteArray bytes = getInternalByteArrayNode.execute(str, WCHAR_T_ENCODING); writeBytesNode.execute(inliningTarget, self.b_ptr, bytes.getArray(), bytes.getOffset(), bytes.getLength()); @@ -248,8 +245,8 @@ static Object doSet(CDataObject self, Object value, @Fallback static Object error(@SuppressWarnings("unused") Object self, Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, UNICODE_STRING_EXPECTED_INSTEAD_OF_P_INSTANCE, value); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, UNICODE_STRING_EXPECTED_INSTEAD_OF_P_INSTANCE, value); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCSimpleTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCSimpleTypeBuiltins.java index cf3d3e988d..2315806713 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCSimpleTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCSimpleTypeBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -77,15 +77,13 @@ import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NodeFactory; @@ -102,28 +100,28 @@ protected List> getNodeFa } @TruffleBoundary - protected static void addCVoidPFromParam(PythonObjectSlowPathFactory factory, PythonLanguage language, Object type) { + protected static void addCVoidPFromParam(PythonLanguage language, Object type) { NodeFactory rawFactory = CVoidPFromParamNodeFactory.getInstance(); Builtin rawNodeBuiltin = CVoidPFromParamNode.class.getAnnotation(Builtin.class); - addClassMethod(factory, language, type, rawFactory, rawNodeBuiltin); + addClassMethod(language, type, rawFactory, rawNodeBuiltin); } @TruffleBoundary - protected static void addCCharPFromParam(PythonObjectSlowPathFactory factory, PythonLanguage language, Object type) { + protected static void addCCharPFromParam(PythonLanguage language, Object type) { NodeFactory rawFactory = CCharPFromParamNodeFactory.getInstance(); Builtin rawNodeBuiltin = CCharPFromParamNode.class.getAnnotation(Builtin.class); - addClassMethod(factory, language, type, rawFactory, rawNodeBuiltin); + addClassMethod(language, type, rawFactory, rawNodeBuiltin); } @TruffleBoundary - protected static void addCWCharPFromParam(PythonObjectSlowPathFactory factory, PythonLanguage language, Object type) { + protected static void addCWCharPFromParam(PythonLanguage language, Object type) { NodeFactory rawFactory = CWCharPFromParamNodeFactory.getInstance(); Builtin rawNodeBuiltin = CWCharPFromParamNode.class.getAnnotation(Builtin.class); - addClassMethod(factory, language, type, rawFactory, rawNodeBuiltin); + addClassMethod(language, type, rawFactory, rawNodeBuiltin); } @TruffleBoundary - private static void addClassMethod(PythonObjectSlowPathFactory objectFactory, PythonLanguage language, Object type, NodeFactory nodeFactory, Builtin builtin) { + private static void addClassMethod(PythonLanguage language, Object type, NodeFactory nodeFactory, Builtin builtin) { TruffleString name = toTruffleStringUncached(builtin.name()); Object builtinDoc = PNone.NONE; RootCallTarget callTarget = language.createCachedCallTarget( @@ -131,8 +129,8 @@ private static void addClassMethod(PythonObjectSlowPathFactory objectFactory, Py nodeFactory.getNodeClass(), builtin.name()); int flags = PBuiltinFunction.getFlags(builtin, callTarget); - PBuiltinFunction function = objectFactory.createBuiltinFunction(name, type, 1, flags, callTarget); - PDecoratedMethod classMethod = objectFactory.createClassmethodFromCallableObj(function); + PBuiltinFunction function = PFactory.createBuiltinFunction(language, name, type, 1, flags, callTarget); + PDecoratedMethod classMethod = PFactory.createClassmethodFromCallableObj(language, function); function.setAttribute(T___DOC__, builtinDoc); WriteAttributeToObjectNode.getUncached(true).execute(type, name, classMethod); } @@ -159,10 +157,9 @@ static Object c_wchar_p_from_param(VirtualFrame frame, Object type, Object value @Cached PyObjectStgDictNode pyObjectStgDictNode, @Cached CWCharPFromParamNode cwCharPFromParamNode, @Cached PyObjectLookupAttr lookupAttr, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (PGuards.isString(value)) { - PyCArgObject parg = factory.createCArgObject(); + PyCArgObject parg = PFactory.createCArgObject(PythonLanguage.get(inliningTarget)); parg.pffi_type = ffi_type_pointer; parg.tag = 'Z'; parg.valuePointer = Pointer.allocate(parg.pffi_type, parg.pffi_type.size); @@ -195,7 +192,7 @@ static Object c_wchar_p_from_param(VirtualFrame frame, Object type, Object value if (as_parameter != PNone.NO_VALUE) { return cwCharPFromParamNode.execute(frame, type, as_parameter); } - throw raiseNode.get(inliningTarget).raise(TypeError, WRONG_TYPE); + throw raiseNode.raise(inliningTarget, TypeError, WRONG_TYPE); } } @@ -220,9 +217,9 @@ static Object voidPtr(@SuppressWarnings("unused") Object type, Object value, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Exclusive @Cached PyLongCheckNode longCheckNode, @Exclusive @Cached SetFuncNode setFuncNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { /* int, long */ - PyCArgObject parg = factory.createCArgObject(); + PyCArgObject parg = PFactory.createCArgObject(language); parg.pffi_type = ffi_type_pointer; parg.tag = 'P'; parg.valuePointer = Pointer.allocate(parg.pffi_type, parg.pffi_type.size); @@ -234,9 +231,9 @@ static Object voidPtr(@SuppressWarnings("unused") Object type, Object value, @Specialization static Object bytes(@SuppressWarnings("unused") Object type, PBytes value, @Exclusive @Cached SetFuncNode setFuncNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { /* bytes */ - PyCArgObject parg = factory.createCArgObject(); + PyCArgObject parg = PFactory.createCArgObject(language); parg.pffi_type = ffi_type_pointer; parg.tag = 'z'; parg.valuePointer = Pointer.allocate(parg.pffi_type, parg.pffi_type.size); @@ -248,9 +245,9 @@ static Object bytes(@SuppressWarnings("unused") Object type, PBytes value, @Specialization static Object string(@SuppressWarnings("unused") Object type, TruffleString value, @Exclusive @Cached SetFuncNode setFuncNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { /* unicode */ - PyCArgObject parg = factory.createCArgObject(); + PyCArgObject parg = PFactory.createCArgObject(language); parg.pffi_type = ffi_type_pointer; parg.tag = 'Z'; parg.valuePointer = Pointer.allocate(parg.pffi_type, parg.pffi_type.size); @@ -269,8 +266,8 @@ static Object c_void_p_from_param(VirtualFrame frame, Object type, Object value, @Cached CVoidPFromParamNode cVoidPFromParamNode, @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, @Cached PyObjectLookupAttr lookupAttr, - @Shared @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { /* c_void_p instance (or subclass) */ boolean res = isInstanceNode.executeWith(frame, value, type); if (res) { @@ -292,7 +289,7 @@ static Object c_void_p_from_param(VirtualFrame frame, Object type, Object value, } /* function pointer */ if (value instanceof PyCFuncPtrObject func && pyTypeCheck.isPyCFuncPtrObject(inliningTarget, value)) { - PyCArgObject parg = factory.createCArgObject(); + PyCArgObject parg = PFactory.createCArgObject(language); parg.pffi_type = ffi_type_pointer; parg.tag = 'P'; parg.valuePointer = func.b_ptr; @@ -305,7 +302,7 @@ static Object c_void_p_from_param(VirtualFrame frame, Object type, Object value, int code = codePointAtIndexNode.execute((TruffleString) stgd.proto, 0, TS_ENCODING); /* c_char_p, c_wchar_p */ if (code == 'z' || code == 'Z') { - PyCArgObject parg = factory.createCArgObject(); + PyCArgObject parg = PFactory.createCArgObject(language); parg.pffi_type = ffi_type_pointer; parg.tag = 'Z'; parg.obj = value; @@ -319,7 +316,7 @@ static Object c_void_p_from_param(VirtualFrame frame, Object type, Object value, if (as_parameter != PNone.NO_VALUE) { return cVoidPFromParamNode.execute(frame, type, as_parameter); } - throw raiseNode.get(inliningTarget).raise(TypeError, WRONG_TYPE); + throw raiseNode.raise(inliningTarget, TypeError, WRONG_TYPE); } } @@ -338,8 +335,8 @@ static Object none(Object type, PNone value) { @Specialization static Object bytes(@SuppressWarnings("unused") Object type, PBytes value, @Cached SetFuncNode setFuncNode, - @Cached PythonObjectFactory factory) { - PyCArgObject parg = factory.createCArgObject(); + @Bind PythonLanguage language) { + PyCArgObject parg = PFactory.createCArgObject(language); parg.pffi_type = ffi_type_pointer; parg.tag = 'z'; parg.valuePointer = Pointer.allocate(parg.pffi_type, parg.pffi_type.size); @@ -357,7 +354,7 @@ static Object c_char_p_from_param(VirtualFrame frame, Object type, Object value, @Cached PyObjectStgDictNode pyObjectStgDictNode, @Cached CCharPFromParamNode cCharPFromParamNode, @Cached PyObjectLookupAttr lookupAttr, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { boolean res = isInstanceNode.executeWith(frame, value, type); if (res) { return value; @@ -384,7 +381,7 @@ static Object c_char_p_from_param(VirtualFrame frame, Object type, Object value, if (as_parameter != PNone.NO_VALUE) { return cCharPFromParamNode.execute(frame, type, as_parameter); } - throw raiseNode.get(inliningTarget).raise(TypeError, WRONG_TYPE); + throw raiseNode.raise(inliningTarget, TypeError, WRONG_TYPE); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCArrayBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCArrayBuiltins.java index 1fba2fa8cd..b1f802596b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCArrayBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCArrayBuiltins.java @@ -48,8 +48,6 @@ import static com.oracle.graal.python.nodes.ErrorMessages.INDICES_MUST_BE_INTEGERS; import static com.oracle.graal.python.nodes.ErrorMessages.INVALID_INDEX; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; import static com.oracle.graal.python.runtime.exception.PythonErrorType.IndexError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; @@ -58,8 +56,10 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -90,11 +90,11 @@ import com.oracle.graal.python.lib.PyObjectSetItem; import com.oracle.graal.python.lib.PyObjectSizeNode; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; @@ -126,7 +126,8 @@ public void postInitialize(Python3Core core) { core.getContext().registerCApiHook(() -> PCallCapiFunction.callUncached(FUN_PY_TRUFFLE_CDATA_INIT_BUFFER_PROTOCOL, PythonToNativeNode.executeUncached(PyCArray))); } - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory protected abstract static class NewNode extends PythonBuiltinNode { @Specialization @@ -134,15 +135,16 @@ static Object newCData(Object type, @SuppressWarnings("unused") Object[] args, @ @Bind("this") Node inliningTarget, @Cached PyTypeStgDictNode pyTypeStgDictNode, @Cached CtypesNodes.GenericPyCDataNewNode newNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { StgDictObject dict = pyTypeStgDictNode.checkAbstractClass(inliningTarget, type, raiseNode); return newNode.execute(inliningTarget, type, dict); } } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory - protected abstract static class InitNode extends PythonBuiltinNode { + protected abstract static class InitNode extends PythonVarargsBuiltinNode { @Specialization static Object Array_init(VirtualFrame frame, CDataObject self, Object[] args, @SuppressWarnings("unused") PKeyword[] kwds, @@ -165,11 +167,11 @@ static void Array_ass_item(VirtualFrame frame, CDataObject self, int index, Obje @Bind("this") Node inliningTarget, @Cached PyObjectStgDictNode pyObjectStgDictNode, @Cached PyCDataSetNode pyCDataSetNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { StgDictObject stgdict = pyObjectStgDictNode.execute(inliningTarget, self); assert stgdict != null : "Cannot be NULL for array object instances"; if (index < 0 || index >= stgdict.length) { - throw raiseNode.get(inliningTarget).raise(IndexError, INVALID_INDEX); + throw raiseNode.raise(inliningTarget, IndexError, INVALID_INDEX); } int size = stgdict.size / stgdict.length; // self.b_ptr.createStorage(stgdict.ffi_type_pointer, stgdict.size, value); @@ -181,8 +183,8 @@ static void Array_ass_item(VirtualFrame frame, CDataObject self, int index, Obje @SuppressWarnings("unused") @Specialization(guards = "isNoValue(value)") static void error(CDataObject self, int index, PNone value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ARRAY_DOES_NOT_SUPPORT_ITEM_DELETION); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ARRAY_DOES_NOT_SUPPORT_ITEM_DELETION); } } @@ -196,7 +198,7 @@ static void Array_ass_subscript(VirtualFrame frame, CDataObject self, Object ind @Cached PyIndexCheckNode indexCheckNode, @Cached PyNumberAsSizeNode asSint, @Shared @Cached PyCArraySetItemNode setItemNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (indexCheckNode.execute(inliningTarget, indexObj)) { int index = asSint.executeExact(frame, inliningTarget, indexObj, IndexError); if (index < 0) { @@ -204,7 +206,7 @@ static void Array_ass_subscript(VirtualFrame frame, CDataObject self, Object ind } setItemNode.executeIntKey(frame, self, index, value); } else { - throw raiseNode.get(inliningTarget).raise(TypeError, INDICES_MUST_BE_INTEGER); + throw raiseNode.raise(inliningTarget, TypeError, INDICES_MUST_BE_INTEGER); } } @@ -216,14 +218,14 @@ static void Array_ass_subscript(VirtualFrame frame, CDataObject self, PSlice sli @Cached SliceUnpack sliceUnpack, @Cached AdjustIndices adjustIndices, @Shared @Cached PyCArraySetItemNode setItemNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { PSlice.SliceInfo sliceInfo = adjustIndices.execute(inliningTarget, self.b_length, sliceUnpack.execute(inliningTarget, slice)); int start = sliceInfo.start, step = sliceInfo.step; int slicelen = sliceInfo.sliceLength; int otherlen = pySequenceLength.execute(frame, inliningTarget, value); if (otherlen != slicelen) { - throw raiseNode.get(inliningTarget).raise(ValueError, CAN_ONLY_ASSIGN_SEQUENCE_OF_SAME_SIZE); + throw raiseNode.raise(inliningTarget, ValueError, CAN_ONLY_ASSIGN_SEQUENCE_OF_SAME_SIZE); } for (int cur = start, i = 0; i < otherlen; cur += step, i++) { Object item = pySequenceGetItem.execute(frame, inliningTarget, value, i); @@ -234,8 +236,8 @@ static void Array_ass_subscript(VirtualFrame frame, CDataObject self, PSlice sli @SuppressWarnings("unused") @Specialization(guards = "isNoValue(value)") static void error(CDataObject self, Object index, PNone value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ARRAY_DOES_NOT_SUPPORT_ITEM_DELETION); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ARRAY_DOES_NOT_SUPPORT_ITEM_DELETION); } } @@ -245,7 +247,7 @@ abstract static class PyCArrayGetItemNode extends SqItemBuiltinNode { @Specialization static Object doIt(CDataObject self, int index, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached PyCDataGetNode pyCDataGetNode, @Cached PyObjectStgDictNode pyObjectStgDictNode) { checkIndex(inliningTarget, self, index, raiseNode); @@ -260,15 +262,15 @@ static Object getItem(Node inliningTarget, CDataObject self, int index, PyCDataG return pyCDataGetNode.execute(inliningTarget, stgdict.proto, stgdict.getfunc, self, index, size, self.b_ptr.withOffset(offset)); } - private static void checkIndex(Node inliningTarget, CDataObject self, int index, Lazy raiseNode) { + private static void checkIndex(Node inliningTarget, CDataObject self, int index, PRaiseNode raiseNode) { if (index < 0 || index >= self.b_length) { raiseInvalidIndex(inliningTarget, raiseNode); } } @InliningCutoff - private static void raiseInvalidIndex(Node inliningTarget, Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(IndexError, INVALID_INDEX); + private static void raiseInvalidIndex(Node inliningTarget, PRaiseNode raiseNode) { + throw raiseNode.raise(inliningTarget, IndexError, INVALID_INDEX); } } @@ -292,14 +294,14 @@ static Object doInt(CDataObject self, int index, static Object doSlice(CDataObject self, PSlice slice, @CachedLibrary("self") PythonBufferAccessLibrary bufferLib, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Exclusive @Cached PyCDataGetNode pyCDataGetNode, @Exclusive @Cached PyTypeStgDictNode pyTypeStgDictNode, @Exclusive @Cached PyObjectStgDictNode pyObjectStgDictNode, @Cached SliceUnpack sliceUnpack, @Cached AdjustIndices adjustIndices, @Cached TruffleString.FromByteArrayNode fromByteArrayNode, - @Cached TruffleString.SwitchEncodingNode switchEncodingNode, - @Cached PythonObjectFactory factory) { + @Cached TruffleString.SwitchEncodingNode switchEncodingNode) { StgDictObject stgdict = pyObjectStgDictNode.execute(inliningTarget, self); assert stgdict != null : "Cannot be NULL for array object instances"; Object proto = stgdict.proto; @@ -313,17 +315,17 @@ static Object doSlice(CDataObject self, PSlice slice, byte[] ptr = bufferLib.getInternalOrCopiedByteArray(self); if (slicelen <= 0) { - return factory.createEmptyBytes(); + return PFactory.createEmptyBytes(language); } - if (sliceInfo.step == 1) { - return factory.createBytes(ptr, sliceInfo.start, slicelen); + if (sliceInfo.start == 0 && sliceInfo.step == 1) { + return PFactory.createBytes(language, ptr, slicelen); } byte[] dest = new byte[slicelen]; for (int cur = sliceInfo.start, i = 0; i < slicelen; cur += sliceInfo.step, i++) { dest[i] = ptr[cur]; } - return factory.createBytes(dest); + return PFactory.createBytes(language, dest); } if (itemdict.getfunc == FieldDesc.u.getfunc) { // CTYPES_UNICODE byte[] ptr = bufferLib.getInternalOrCopiedByteArray(self); @@ -349,7 +351,7 @@ static Object doSlice(CDataObject self, PSlice slice, for (int cur = sliceInfo.start, i = 0; i < slicelen; cur += sliceInfo.step, i++) { np[i] = doInt(self, cur, inliningTarget, pyCDataGetNode, pyObjectStgDictNode); } - return factory.createList(np); + return PFactory.createList(language, np); } @Specialization(guards = "!isPSlice(item)", replaces = "doInt") @@ -361,9 +363,9 @@ static Object doGeneric(VirtualFrame frame, CDataObject self, Object item, @Cached InlinedConditionProfile negativeIndexProfile, @Exclusive @Cached PyCDataGetNode pyCDataGetNode, @Exclusive @Cached PyObjectStgDictNode pyObjectStgDictNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (!indexCheckNode.execute(inliningTarget, item)) { - throw raiseNode.get(inliningTarget).raise(TypeError, INDICES_MUST_BE_INTEGERS); + throw raiseNode.raise(inliningTarget, TypeError, INDICES_MUST_BE_INTEGERS); } Object idx = indexNode.execute(frame, inliningTarget, item); int index = asSizeNode.executeExact(frame, inliningTarget, idx); @@ -392,8 +394,8 @@ static int Array_length(CDataObject self) { public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode { @Specialization static Object classGetItem(Object cls, Object key, - @Cached PythonObjectFactory factory) { - return factory.createGenericAlias(cls, key); + @Bind PythonLanguage language) { + return PFactory.createGenericAlias(language, cls, key); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCArrayTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCArrayTypeBuiltins.java index d86a887fd2..89ba5e9f88 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCArrayTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCArrayTypeBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -50,7 +50,6 @@ import static com.oracle.graal.python.nodes.ErrorMessages.THE_LENGTH_ATTRIBUTE_MUST_BE_AN_INTEGER; import static com.oracle.graal.python.nodes.ErrorMessages.THE_LENGTH_ATTRIBUTE_MUST_NOT_BE_NEGATIVE; import static com.oracle.graal.python.nodes.ErrorMessages.TYPE_MUST_HAVE_STORAGE_INFO; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.AttributeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.OverflowError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; @@ -60,11 +59,12 @@ import java.util.List; import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.TypeNode; import com.oracle.graal.python.builtins.modules.ctypes.FFIType.FieldDesc; import com.oracle.graal.python.builtins.modules.ctypes.StgDictBuiltins.PyTypeStgDictNode; import com.oracle.graal.python.builtins.objects.PNone; @@ -72,6 +72,8 @@ import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.object.PythonObject; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeBuiltins.TypeNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.nodes.PRaiseNode; @@ -82,7 +84,7 @@ import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; import com.oracle.graal.python.nodes.object.SetDictNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -96,6 +98,8 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PyCArrayType) public final class PyCArrayTypeBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = PyCArrayTypeBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return PyCArrayTypeBuiltinsFactory.getFactories(); @@ -104,7 +108,8 @@ protected List> getNodeFa protected static final TruffleString T__LENGTH_ = tsLiteral("_length_"); @ImportStatic({PyCPointerTypeBuiltins.class, PyCArrayTypeBuiltins.class, SpecialMethodNames.class}) - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory protected abstract static class PyCArrayTypeNewNode extends PythonBuiltinNode { @@ -120,15 +125,15 @@ static Object PyCArrayType_new(VirtualFrame frame, Object type, Object[] args, P @Cached SetDictNode setDict, @Cached HashingStorageAddAllToOther addAllToOtherNode, @Cached PyTypeStgDictNode pyTypeStgDictNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { /* * create the new instance (which is a class, since we are a metatype!) */ Object result = typeNew.execute(frame, type, args[0], args[1], args[2], kwds); Object length_attr = lookupAttrLength.execute(frame, inliningTarget, result, T__LENGTH_); if (length_attr == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(AttributeError, CLASS_MUST_DEFINE_A_LENGTH_ATTRIBUTE); + throw raiseNode.raise(inliningTarget, AttributeError, CLASS_MUST_DEFINE_A_LENGTH_ATTRIBUTE); } int length; @@ -136,26 +141,26 @@ static Object PyCArrayType_new(VirtualFrame frame, Object type, Object[] args, P length = asSizeNode.executeExact(frame, inliningTarget, length_attr); } catch (PException e) { if (e.expectTypeOrOverflowError(inliningTarget, profile)) { - throw raiseNode.get(inliningTarget).raise(OverflowError, THE_LENGTH_ATTRIBUTE_IS_TOO_LARGE); + throw raiseNode.raise(inliningTarget, OverflowError, THE_LENGTH_ATTRIBUTE_IS_TOO_LARGE); } else { - throw raiseNode.get(inliningTarget).raise(TypeError, THE_LENGTH_ATTRIBUTE_MUST_BE_AN_INTEGER); + throw raiseNode.raise(inliningTarget, TypeError, THE_LENGTH_ATTRIBUTE_MUST_BE_AN_INTEGER); } } if (length < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, THE_LENGTH_ATTRIBUTE_MUST_NOT_BE_NEGATIVE); + throw raiseNode.raise(inliningTarget, ValueError, THE_LENGTH_ATTRIBUTE_MUST_NOT_BE_NEGATIVE); } Object type_attr = lookupAttrType.execute(frame, inliningTarget, result, T__TYPE_); if (type_attr == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(AttributeError, CLASS_MUST_DEFINE_A_TYPE_ATTRIBUTE); + throw raiseNode.raise(inliningTarget, AttributeError, CLASS_MUST_DEFINE_A_TYPE_ATTRIBUTE); } - StgDictObject stgdict = factory.createStgDictObject(PythonBuiltinClassType.StgDict); + StgDictObject stgdict = PFactory.createStgDictObject(language); StgDictObject itemdict = pyTypeStgDictNode.execute(inliningTarget, type_attr); if (itemdict == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, TYPE_MUST_HAVE_STORAGE_INFO); + throw raiseNode.raise(inliningTarget, TypeError, TYPE_MUST_HAVE_STORAGE_INFO); } assert itemdict.format != null; @@ -171,7 +176,7 @@ static Object PyCArrayType_new(VirtualFrame frame, Object type, Object[] args, P int itemsize = itemdict.size; if (itemsize != 0 && length > Integer.MAX_VALUE / itemsize) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ARRAY_TOO_LARGE); + throw raiseNode.raise(inliningTarget, OverflowError, ARRAY_TOO_LARGE); } int itemalign = itemdict.align; @@ -193,7 +198,7 @@ static Object PyCArrayType_new(VirtualFrame frame, Object type, Object[] args, P /* replace the class dict by our updated spam dict */ PDict resDict = getDict.execute(result); if (resDict == null) { - resDict = factory.createDictFixedStorage((PythonObject) result); + resDict = PFactory.createDictFixedStorage(language, (PythonObject) result); } addAllToOtherNode.execute(frame, inliningTarget, resDict.getDictStorage(), stgdict); setDict.execute(inliningTarget, (PythonObject) result, stgdict); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCFuncPtrBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCFuncPtrBuiltins.java index 710ced01fa..68691583e6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCFuncPtrBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCFuncPtrBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -60,7 +60,8 @@ import static com.oracle.graal.python.nodes.ErrorMessages.INVALID_RESULT_TYPE_FOR_CALLBACK_FUNCTION; import static com.oracle.graal.python.nodes.ErrorMessages.NOT_ENOUGH_ARGUMENTS; import static com.oracle.graal.python.nodes.ErrorMessages.NULL_STGDICT_UNEXPECTED; -import static com.oracle.graal.python.nodes.ErrorMessages.OUT_PARAMETER_D_MUST_BE_A_POINTER_TYPE_NOT_S; +import static com.oracle.graal.python.nodes.ErrorMessages.N_OUT_PARAMETER_MUST_BE_PASSED_AS_DEFAULT_VALUE; +import static com.oracle.graal.python.nodes.ErrorMessages.OUT_PARAMETER_D_MUST_BE_A_POINTER_TYPE_NOT_N; import static com.oracle.graal.python.nodes.ErrorMessages.PARAMFLAGS_MUST_BE_A_SEQUENCE_OF_INT_STRING_VALUE_TUPLES; import static com.oracle.graal.python.nodes.ErrorMessages.PARAMFLAGS_MUST_BE_A_TUPLE_OR_NONE; import static com.oracle.graal.python.nodes.ErrorMessages.PARAMFLAGS_MUST_HAVE_THE_SAME_LENGTH_AS_ARGTYPES; @@ -68,14 +69,10 @@ import static com.oracle.graal.python.nodes.ErrorMessages.PARAMFLAG_VALUE_D_NOT_SUPPORTED; import static com.oracle.graal.python.nodes.ErrorMessages.REQUIRED_ARGUMENT_S_MISSING; import static com.oracle.graal.python.nodes.ErrorMessages.RESTYPE_MUST_BE_A_TYPE_A_CALLABLE_OR_NONE; -import static com.oracle.graal.python.nodes.ErrorMessages.S_OUT_PARAMETER_MUST_BE_PASSED_AS_DEFAULT_VALUE; import static com.oracle.graal.python.nodes.ErrorMessages.THE_ERRCHECK_ATTRIBUTE_MUST_BE_CALLABLE; import static com.oracle.graal.python.nodes.ErrorMessages.THE_HANDLE_ATTRIBUTE_OF_THE_SECOND_ARGUMENT_MUST_BE_AN_INTEGER; import static com.oracle.graal.python.nodes.ErrorMessages.THIS_FUNCTION_TAKES_AT_LEAST_D_ARGUMENT_S_D_GIVEN; import static com.oracle.graal.python.nodes.ErrorMessages.THIS_FUNCTION_TAKES_D_ARGUMENT_S_D_GIVEN; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.nodes.StringLiterals.J_NFI_LANGUAGE; import static com.oracle.graal.python.runtime.exception.PythonErrorType.AttributeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; @@ -84,8 +81,10 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -134,7 +133,7 @@ import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -181,7 +180,8 @@ public void postInitialize(Python3Core core) { * object (with an integer handle)), paramflags "is|..." - vtable index, method name, creates * callable calling COM vtbl */ - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory protected abstract static class PyCFuncPtrNewNode extends PythonBuiltinNode { @@ -198,7 +198,7 @@ static Object simple(Object type, @SuppressWarnings("unused") Object[] args, @Su @Bind("this") Node inliningTarget, @Exclusive @Cached PyTypeStgDictNode pyTypeStgDictNode, @Exclusive @Cached CtypesNodes.GenericPyCDataNewNode pyCDataNewNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { StgDictObject dict = pyTypeStgDictNode.checkAbstractClass(inliningTarget, type, raiseNode); return pyCDataNewNode.execute(inliningTarget, type, dict); } @@ -217,7 +217,7 @@ static Object usingNativePointer(Object type, Object[] args, @SuppressWarnings(" @Exclusive @Cached PointerNodes.WritePointerNode writePointerNode, @Exclusive @Cached PyTypeStgDictNode pyTypeStgDictNode, @Exclusive @Cached CtypesNodes.GenericPyCDataNewNode pyCDataNewNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { StgDictObject dict = pyTypeStgDictNode.checkAbstractClass(inliningTarget, type, raiseNode); CDataObject cdata = pyCDataNewNode.execute(inliningTarget, type, dict); Pointer value = pointerFromLongNode.execute(inliningTarget, args[0]); @@ -234,15 +234,15 @@ static Object callback(VirtualFrame frame, Object type, Object[] args, @Suppress @Cached PyCallableCheckNode callableCheck, @Exclusive @Cached PyTypeStgDictNode pyTypeStgDictNode, @Exclusive @Cached CtypesNodes.GenericPyCDataNewNode pyCDataNewNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { Object callable = args[0]; if (!callableCheck.execute(inliningTarget, callable)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ARGUMENT_MUST_BE_CALLABLE_OR_INTEGER_FUNCTION_ADDRESS); + throw raiseNode.raise(inliningTarget, TypeError, ARGUMENT_MUST_BE_CALLABLE_OR_INTEGER_FUNCTION_ADDRESS); } StgDictObject dict = pyTypeStgDictNode.checkAbstractClass(inliningTarget, type, raiseNode); if (dict == null || dict.argtypes == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, CANNOT_CONSTRUCT_INSTANCE_OF_THIS_CLASS_NO_ARGTYPES); + throw raiseNode.raise(inliningTarget, TypeError, CANNOT_CONSTRUCT_INSTANCE_OF_THIS_CLASS_NO_ARGTYPES); } CThunkObject thunk = _ctypes_alloc_callback(inliningTarget, callable, dict.argtypes, dict.restype, dict.flags); PyCFuncPtrObject self = (PyCFuncPtrObject) pyCDataNewNode.execute(inliningTarget, type, dict); @@ -255,14 +255,13 @@ static Object callback(VirtualFrame frame, Object type, Object[] args, @Suppress @Specialization(guards = {"args.length > 1", "!isPTuple(args)", "isLong(this, args, longCheckNode)"}, limit = "1") static Object error(@SuppressWarnings("unused") Object type, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") PKeyword[] kwds, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Exclusive @Cached PyLongCheckNode longCheckNode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ARGUMENT_MUST_BE_CALLABLE_OR_INTEGER_FUNCTION_ADDRESS); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ARGUMENT_MUST_BE_CALLABLE_OR_INTEGER_FUNCTION_ADDRESS); } static CThunkObject CThunkObjectNew(int nArgs) { - CThunkObject p = PythonObjectFactory.getUncached().createCThunkObject(PythonBuiltinClassType.CThunkObject, nArgs); + CThunkObject p = PFactory.createCThunkObject(PythonLanguage.get(null), nArgs); p.pcl_write = null; p.pcl_exec = null; @@ -310,7 +309,7 @@ static CThunkObject _ctypes_alloc_callback(Node raisingNode, Object callable, Ob } else { StgDictObject dict = PyTypeStgDictNode.executeUncached(restype); if (dict == null || dict.setfunc == FieldSet.nil) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, INVALID_RESULT_TYPE_FOR_CALLBACK_FUNCTION); + throw PRaiseNode.raiseStatic(raisingNode, TypeError, INVALID_RESULT_TYPE_FOR_CALLBACK_FUNCTION); } thunk.setfunc = dict.setfunc; thunk.ffi_restype = dict.ffi_type_pointer; @@ -355,9 +354,9 @@ Object PyCFuncPtr_get_errcheck(PyCFuncPtrObject self, @SuppressWarnings("unused" static Object PyCFuncPtr_set_errcheck(PyCFuncPtrObject self, Object value, @Bind("this") Node inliningTarget, @Cached PyCallableCheckNode callableCheck, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (value != PNone.NONE && !callableCheck.execute(inliningTarget, value)) { - throw raiseNode.get(inliningTarget).raise(TypeError, THE_ERRCHECK_ATTRIBUTE_MUST_BE_CALLABLE); + throw raiseNode.raise(inliningTarget, TypeError, THE_ERRCHECK_ATTRIBUTE_MUST_BE_CALLABLE); } self.errcheck = value; return PNone.NONE; @@ -391,14 +390,14 @@ static Object PyCFuncPtr_set_restype(VirtualFrame frame, PyCFuncPtrObject self, @Cached PyObjectLookupAttr lookupAttr, @Cached PyTypeStgDictNode pyTypeStgDictNode, @Cached PyCallableCheckNode callableCheck, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (value == PNone.NONE) { self.checker = null; self.restype = null; return PNone.NONE; } if (pyTypeStgDictNode.execute(inliningTarget, value) == null && !callableCheck.execute(inliningTarget, value)) { - throw raiseNode.get(inliningTarget).raise(TypeError, RESTYPE_MUST_BE_A_TYPE_A_CALLABLE_OR_NONE); + throw raiseNode.raise(inliningTarget, TypeError, RESTYPE_MUST_BE_A_TYPE_A_CALLABLE_OR_NONE); } if (!PGuards.isPFunction(value)) { Object checker = lookupAttr.execute(frame, inliningTarget, value, T__CHECK_RETVAL_); @@ -415,19 +414,19 @@ protected abstract static class PointerArgTypesNode extends PythonBinaryBuiltinN @Specialization(guards = {"isNoValue(value)", "self.argtypes != null"}) static Object PyCFuncPtr_get_argtypes(PyCFuncPtrObject self, @SuppressWarnings("unused") PNone value, - @Shared @Cached PythonObjectFactory factory) { - return factory.createTuple(self.argtypes); + @Bind PythonLanguage language) { + return PFactory.createTuple(language, self.argtypes); } @Specialization(guards = {"isNoValue(value)", "self.argtypes == null"}) static Object PyCFuncPtr_get_argtypes(PyCFuncPtrObject self, @SuppressWarnings("unused") PNone value, @Bind("this") Node inliningTarget, @Cached PyObjectStgDictNode pyObjectStgDictNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { StgDictObject dict = pyObjectStgDictNode.execute(inliningTarget, self); assert dict != null : "Cannot be NULL for PyCFuncPtrObject instances"; if (dict.argtypes != null) { - return factory.createTuple(dict.argtypes); + return PFactory.createTuple(language, dict.argtypes); } else { return PNone.NONE; } @@ -445,7 +444,7 @@ static Object PyCFuncPtr_set_argtypes(VirtualFrame frame, PyCFuncPtrObject self, @Bind("this") Node inliningTarget, @Shared @Cached PyObjectLookupAttr lookupAttr, @Shared @Cached GetInternalObjectArrayNode getArray, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { SequenceStorage storage = value.getSequenceStorage(); Object[] ob = getArray.execute(inliningTarget, value.getSequenceStorage()); self.converters = converters_from_argtypes(frame, inliningTarget, ob, storage.length(), raiseNode, lookupAttr); @@ -458,7 +457,7 @@ static Object PyCFuncPtr_set_argtypes(VirtualFrame frame, PyCFuncPtrObject self, @Bind("this") Node inliningTarget, @Shared @Cached PyObjectLookupAttr lookupAttr, @Shared @Cached GetInternalObjectArrayNode getArray, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { SequenceStorage storage = value.getSequenceStorage(); Object[] ob = getArray.execute(inliningTarget, value.getSequenceStorage()); self.converters = converters_from_argtypes(frame, inliningTarget, ob, storage.length(), raiseNode, lookupAttr); @@ -468,13 +467,13 @@ static Object PyCFuncPtr_set_argtypes(VirtualFrame frame, PyCFuncPtrObject self, @Fallback static Object error(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ARGTYPES_MUST_BE_A_SEQUENCE_OF_TYPES); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ARGTYPES_MUST_BE_A_SEQUENCE_OF_TYPES); } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { @@ -490,7 +489,8 @@ TruffleString PyCFuncPtr_repr(CDataObject self, } } - @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_call, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory protected abstract static class PyCFuncPtrCallNode extends PythonVarargsBuiltinNode { @@ -504,12 +504,12 @@ Object PyCFuncPtr_call(VirtualFrame frame, PyCFuncPtrObject self, Object[] inarg @Cached CastToJavaIntExactNode castToJavaIntExactNode, @Cached CastToTruffleStringNode castToTruffleStringNode, @Cached PyTypeStgDictNode pyTypeStgDictNode, - @Cached GetNameNode getNameNode, @Cached PyObjectCallMethodObjArgs callMethodObjArgs, @Cached CallProcNode callProcNode, @Cached TruffleString.EqualNode equalNode, @Cached PointerNodes.ReadPointerNode readPointerNode, - @Cached CtypesNodes.HandleFromPointerNode handleFromPointerNode) { + @Cached CtypesNodes.HandleFromPointerNode handleFromPointerNode, + @Cached PRaiseNode raiseNode) { StgDictObject dict = pyObjectStgDictNode.execute(inliningTarget, self); assert dict != null : "Cannot be NULL for PyCFuncPtrObject instances"; Object restype = self.restype != null ? self.restype : dict.restype; @@ -527,10 +527,10 @@ Object PyCFuncPtr_call(VirtualFrame frame, PyCFuncPtrObject self, Object[] inarg * TODO this happens in a numpy tests that use structs with function pointers: * numpy/core/tests/test_ufunc.py::TestLowlevelAPIAccess::test_loop_access */ - throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, ErrorMessages.CTYPES_FUNCTION_CALL_COULD_NOT_OBTAIN_FUNCTION_POINTER); + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, ErrorMessages.CTYPES_FUNCTION_CALL_COULD_NOT_OBTAIN_FUNCTION_POINTER); } Object[] callargs = _build_callargs(frame, inliningTarget, self, argtypes, inargs, kwds, props, - pyTypeCheck, getArray, castToJavaIntExactNode, castToTruffleStringNode, pyTypeStgDictNode, callNode, getNameNode, equalNode); + pyTypeCheck, getArray, castToJavaIntExactNode, castToTruffleStringNode, pyTypeStgDictNode, callNode, equalNode, raiseNode); int inoutmask = props[pinoutmask_idx]; int outmask = props[poutmask_idx]; int numretvals = props[pnumretvals_idx]; @@ -545,11 +545,11 @@ Object PyCFuncPtr_call(VirtualFrame frame, PyCFuncPtrObject self, Object[] inarg * argtypes tuple. */ if (required > actual) { - throw raise(TypeError, THIS_FUNCTION_TAKES_AT_LEAST_D_ARGUMENT_S_D_GIVEN, + throw raiseNode.raise(inliningTarget, TypeError, THIS_FUNCTION_TAKES_AT_LEAST_D_ARGUMENT_S_D_GIVEN, required, required == 1 ? "" : "s", actual); } } else if (required != actual) { - throw raise(TypeError, THIS_FUNCTION_TAKES_D_ARGUMENT_S_D_GIVEN, + throw raiseNode.raise(inliningTarget, TypeError, THIS_FUNCTION_TAKES_D_ARGUMENT_S_D_GIVEN, required, required == 1 ? "" : "s", actual); } } @@ -575,7 +575,7 @@ Object PyCFuncPtr_call(VirtualFrame frame, PyCFuncPtrObject self, Object[] inarg return _build_result(frame, inliningTarget, result, callargs, outmask, inoutmask, numretvals, callMethodObjArgs); } - protected Object _get_arg(int[] pindex, TruffleString name, Object defval, Object[] inargs, PKeyword[] kwds, TruffleString.EqualNode equalNode) { + protected Object _get_arg(Node inliningTarget, int[] pindex, TruffleString name, Object defval, Object[] inargs, PKeyword[] kwds, TruffleString.EqualNode equalNode, PRaiseNode raiseNode) { if (pindex[0] < inargs.length) { return inargs[pindex[0]++]; } @@ -591,9 +591,9 @@ protected Object _get_arg(int[] pindex, TruffleString name, Object defval, Objec } /* we can't currently emit a better error message */ if (name != null) { - throw raise(TypeError, REQUIRED_ARGUMENT_S_MISSING, name); + throw raiseNode.raise(inliningTarget, TypeError, REQUIRED_ARGUMENT_S_MISSING, name); } else { - throw raise(TypeError, NOT_ENOUGH_ARGUMENTS); + throw raiseNode.raise(inliningTarget, TypeError, NOT_ENOUGH_ARGUMENTS); } } @@ -625,8 +625,7 @@ Object[] _build_callargs(VirtualFrame frame, Node inliningTarget, PyCFuncPtrObje CastToTruffleStringNode castToTruffleStringNode, PyTypeStgDictNode pyTypeStgDictNode, CallNode callNode, - GetNameNode getNameNode, - TruffleString.EqualNode equalNode) { + TruffleString.EqualNode equalNode, PRaiseNode raiseNode) { /* * It's a little bit difficult to determine how many arguments the function call * requires/accepts. For simplicity, we count the consumed args and compare this to the @@ -675,7 +674,7 @@ Object[] _build_callargs(VirtualFrame frame, Node inliningTarget, PyCFuncPtrObje case 0: case PARAMFLAG_FIN: /* 'in' parameter. Copy it from inargs. */ - ob = _get_arg(inargs_index, name, defval, inargs, kwds, equalNode); + ob = _get_arg(inliningTarget, inargs_index, name, defval, inargs, kwds, equalNode, raiseNode); callargs[i] = ob; break; case PARAMFLAG_FOUT: @@ -701,10 +700,10 @@ Object[] _build_callargs(VirtualFrame frame, Node inliningTarget, PyCFuncPtrObje /* * Cannot happen: _validate_paramflags() would not accept such an object */ - throw raise(RuntimeError, NULL_STGDICT_UNEXPECTED); + throw raiseNode.raise(inliningTarget, RuntimeError, NULL_STGDICT_UNEXPECTED); } if (PGuards.isString(dict.proto)) { // TODO Py_TPFLAGS_UNICODE_SUBCLASS - throw raise(TypeError, S_OUT_PARAMETER_MUST_BE_PASSED_AS_DEFAULT_VALUE, getNameNode.execute(inliningTarget, ob)); + throw raiseNode.raise(inliningTarget, TypeError, N_OUT_PARAMETER_MUST_BE_PASSED_AS_DEFAULT_VALUE, ob); } if (pyTypeCheck.isPyCArrayTypeObject(inliningTarget, ob)) { ob = callNode.execute(frame, ob); @@ -721,7 +720,7 @@ Object[] _build_callargs(VirtualFrame frame, Node inliningTarget, PyCFuncPtrObje props[pnumretvals_idx]++; break; default: - throw raise(ValueError, PARAMFLAG_D_NOT_YET_IMPLEMENTED, flag); + throw raiseNode.raise(inliningTarget, ValueError, PARAMFLAG_D_NOT_YET_IMPLEMENTED, flag); } } @@ -737,7 +736,7 @@ Object[] _build_callargs(VirtualFrame frame, Node inliningTarget, PyCFuncPtrObje * When we have default values or named parameters, this error message is * misleading. See unittests/test_paramflags.py */ - throw raise(TypeError, CALL_TAKES_EXACTLY_D_ARGUMENTS_D_GIVEN, inargs_index, actual_args); + throw raiseNode.raise(inliningTarget, TypeError, CALL_TAKES_EXACTLY_D_ARGUMENTS_D_GIVEN, inargs_index, actual_args); } /* @@ -821,7 +820,7 @@ static Object PyCFuncPtr_FromDll(VirtualFrame frame, Object type, Object[] args, @Cached CtypesNodes.GenericPyCDataNewNode pyCDataNewNode, @Cached AuditNode auditNode, @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { // PyArg_ParseTuple(args, "O|O", &tuple, ¶mflags); PTuple tuple = (PTuple) args[0]; Object[] paramflags = null; @@ -837,13 +836,13 @@ static Object PyCFuncPtr_FromDll(VirtualFrame frame, Object type, Object[] args, Object obj = getAttributeNode.execute(frame, inliningTarget, dll, T__HANDLE); if (!longCheckNode.execute(inliningTarget, obj)) { // PyLong_Check - throw raiseNode.get(inliningTarget).raise(TypeError, THE_HANDLE_ATTRIBUTE_OF_THE_SECOND_ARGUMENT_MUST_BE_AN_INTEGER); + throw raiseNode.raise(inliningTarget, TypeError, THE_HANDLE_ATTRIBUTE_OF_THE_SECOND_ARGUMENT_MUST_BE_AN_INTEGER); } Pointer handlePtr; try { handlePtr = pointerFromLongNode.execute(inliningTarget, obj); } catch (PException e) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.COULD_NOT_CONVERT_THE_HANDLE_ATTRIBUTE_TO_A_POINTER); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.COULD_NOT_CONVERT_THE_HANDLE_ATTRIBUTE_TO_A_POINTER); } Object address = dlSymNode.execute(frame, handlePtr, name, AttributeError); _validate_paramflags(inliningTarget, type, paramflags, pyTypeCheck, getArray, pyTypeStgDictNode, codePointAtIndexNode, raiseNode); @@ -866,7 +865,7 @@ static void _validate_paramflags(Node inliningTarget, Object type, Object[] para GetInternalObjectArrayNode getArray, PyTypeStgDictNode pyTypeStgDictNode, TruffleString.CodePointAtIndexNode codePointAtIndexNode, - PRaiseNode.Lazy raiseNode) { + PRaiseNode raiseNode) { StgDictObject dict = pyTypeStgDictNode.checkAbstractClass(inliningTarget, type, raiseNode); Object[] argtypes = dict.argtypes; @@ -875,12 +874,12 @@ static void _validate_paramflags(Node inliningTarget, Object type, Object[] para } if (!PGuards.isPTuple(paramflags)) { - throw raiseNode.get(inliningTarget).raise(TypeError, PARAMFLAGS_MUST_BE_A_TUPLE_OR_NONE); + throw raiseNode.raise(inliningTarget, TypeError, PARAMFLAGS_MUST_BE_A_TUPLE_OR_NONE); } int len = paramflags.length; if (len != dict.argtypes.length) { - throw raiseNode.get(inliningTarget).raise(ValueError, PARAMFLAGS_MUST_HAVE_THE_SAME_LENGTH_AS_ARGTYPES); + throw raiseNode.raise(inliningTarget, ValueError, PARAMFLAGS_MUST_HAVE_THE_SAME_LENGTH_AS_ARGTYPES); } for (int i = 0; i < len; ++i) { @@ -890,7 +889,7 @@ static void _validate_paramflags(Node inliningTarget, Object type, Object[] para int flag = (int) array[0]; if (array.length > 1) { if (!PGuards.isString(array[1])) { - throw raiseNode.get(inliningTarget).raise(TypeError, PARAMFLAGS_MUST_BE_A_SEQUENCE_OF_INT_STRING_VALUE_TUPLES); + throw raiseNode.raise(inliningTarget, TypeError, PARAMFLAGS_MUST_BE_A_SEQUENCE_OF_INT_STRING_VALUE_TUPLES); } } Object typ = argtypes[i]; @@ -904,7 +903,7 @@ static void _validate_paramflags(Node inliningTarget, Object type, Object[] para _check_outarg_type(inliningTarget, typ, i + 1, pyTypeCheck, pyTypeStgDictNode, codePointAtIndexNode, raiseNode); break; default: - throw raiseNode.get(inliningTarget).raise(TypeError, PARAMFLAG_VALUE_D_NOT_SUPPORTED, flag); + throw raiseNode.raise(inliningTarget, TypeError, PARAMFLAG_VALUE_D_NOT_SUPPORTED, flag); } } } @@ -914,7 +913,7 @@ static void _check_outarg_type(Node inliningTarget, Object arg, int index, PyTypeCheck pyTypeCheck, PyTypeStgDictNode pyTypeStgDictNode, TruffleString.CodePointAtIndexNode codePointAtIndexNode, - PRaiseNode.Lazy raiseNode) { + PRaiseNode raiseNode) { if (pyTypeCheck.isPyCPointerTypeObject(inliningTarget, arg)) { return; } @@ -934,7 +933,7 @@ && strchr(PzZ, codePointAtIndexNode.execute((TruffleString) dict.proto, 0, TS_EN return; } - throw raiseNode.get(inliningTarget).raise(TypeError, OUT_PARAMETER_D_MUST_BE_A_POINTER_TYPE_NOT_S, index, GetNameNode.executeUncached(arg)); + throw raiseNode.raise(inliningTarget, TypeError, OUT_PARAMETER_D_MUST_BE_A_POINTER_TYPE_NOT_N, index, arg); } protected static boolean strchr(char[] chars, int code) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCFuncPtrTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCFuncPtrTypeBuiltins.java index b0e2a51ef0..4e6e997408 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCFuncPtrTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCFuncPtrTypeBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,17 +46,18 @@ import static com.oracle.graal.python.nodes.ErrorMessages.CLASS_MUST_DEFINE_FLAGS_WHICH_MUST_BE_AN_INTEGER; import static com.oracle.graal.python.nodes.ErrorMessages.ITEM_D_IN_ARGTYPES_HAS_NO_FROM_PARAM_METHOD; import static com.oracle.graal.python.nodes.ErrorMessages.RESTYPE_MUST_BE_A_TYPE_A_CALLABLE_OR_NONE1; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import java.util.List; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.TypeNode; import com.oracle.graal.python.builtins.modules.ctypes.FFIType.FieldDesc; import com.oracle.graal.python.builtins.modules.ctypes.FFIType.FieldSet; import com.oracle.graal.python.builtins.modules.ctypes.StgDictBuiltins.PyTypeStgDictNode; @@ -68,6 +69,8 @@ import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeBuiltins.TypeNode; import com.oracle.graal.python.lib.PyCallableCheckNode; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.nodes.PGuards; @@ -77,7 +80,7 @@ import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; import com.oracle.graal.python.nodes.object.SetDictNode; import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -92,6 +95,8 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PyCFuncPtrType) public final class PyCFuncPtrTypeBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = PyCFuncPtrTypeBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return PyCFuncPtrTypeBuiltinsFactory.getFactories(); @@ -110,7 +115,8 @@ protected List> getNodeFa private static final TruffleString T_X_BRACES = tsLiteral("X{}"); @ImportStatic(PyCPointerTypeBuiltins.class) - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory protected abstract static class PyCFuncPtrTypeNewNode extends PythonBuiltinNode { @@ -127,9 +133,9 @@ static Object PyCFuncPtrType_new(VirtualFrame frame, Object type, Object[] args, @Cached PyCallableCheckNode callableCheck, @Cached HashingStorageGetItem getItem, @Cached HashingStorageAddAllToOther addAllToOtherNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - StgDictObject stgdict = factory.createStgDictObject(PythonBuiltinClassType.StgDict); + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { + StgDictObject stgdict = PFactory.createStgDictObject(language); stgdict.paramfunc = CArgObjectBuiltins.PyCFuncPtrTypeParamFunc; /* @@ -147,7 +153,7 @@ static Object PyCFuncPtrType_new(VirtualFrame frame, Object type, Object[] args, /* replace the class dict by our updated storage dict */ PDict resDict = getDict.execute(result); if (resDict == null) { - resDict = factory.createDictFixedStorage((PythonObject) result); + resDict = PFactory.createDictFixedStorage(language, (PythonObject) result); } addAllToOtherNode.execute(frame, inliningTarget, resDict.getDictStorage(), stgdict); setDict.execute(inliningTarget, result, stgdict); @@ -159,7 +165,7 @@ static Object PyCFuncPtrType_new(VirtualFrame frame, Object type, Object[] args, Object ob = getItem.execute(inliningTarget, stgdict.getDictStorage(), T_FLAGS_); if (!PGuards.isInteger(ob)) { - throw raiseNode.get(inliningTarget).raise(TypeError, CLASS_MUST_DEFINE_FLAGS_WHICH_MUST_BE_AN_INTEGER); + throw raiseNode.raise(inliningTarget, TypeError, CLASS_MUST_DEFINE_FLAGS_WHICH_MUST_BE_AN_INTEGER); } stgdict.flags = asNumber.execute(inliningTarget, ob) | TYPEFLAG_ISPOINTER; @@ -167,7 +173,7 @@ static Object PyCFuncPtrType_new(VirtualFrame frame, Object type, Object[] args, ob = getItem.execute(inliningTarget, stgdict.getDictStorage(), T_ARGTYPES_); if (ob != null) { if (!PGuards.isPTuple(ob)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ARGTYPES_MUST_BE_A_SEQUENCE_OF_TYPES); + throw raiseNode.raise(inliningTarget, TypeError, ARGTYPES_MUST_BE_A_SEQUENCE_OF_TYPES); } SequenceStorage storage = ((PTuple) ob).getSequenceStorage(); Object[] obtuple = getArray.execute(inliningTarget, storage); @@ -180,7 +186,7 @@ static Object PyCFuncPtrType_new(VirtualFrame frame, Object type, Object[] args, if (!PGuards.isPNone(ob)) { StgDictObject dict = pyTypeStgDictNode.execute(inliningTarget, ob); if (dict == null && !callableCheck.execute(inliningTarget, ob)) { - throw raiseNode.get(inliningTarget).raise(TypeError, RESTYPE_MUST_BE_A_TYPE_A_CALLABLE_OR_NONE1); + throw raiseNode.raise(inliningTarget, TypeError, RESTYPE_MUST_BE_A_TYPE_A_CALLABLE_OR_NONE1); } stgdict.restype = ob; Object checker = lookupAttr.execute(frame, inliningTarget, ob, T__CHECK_RETVAL_); @@ -191,7 +197,7 @@ static Object PyCFuncPtrType_new(VirtualFrame frame, Object type, Object[] args, } static Object[] converters_from_argtypes(VirtualFrame frame, Node inliningTarget, Object[] args, int nArgs, - PRaiseNode.Lazy raiseNode, + PRaiseNode raiseNode, PyObjectLookupAttr lookupAttr) { Object[] converters = new Object[nArgs]; @@ -201,7 +207,7 @@ static Object[] converters_from_argtypes(VirtualFrame frame, Node inliningTarget cnv = lookupAttr.execute(frame, inliningTarget, tp, T_FROM_PARAM); if (cnv == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(TypeError, ITEM_D_IN_ARGTYPES_HAS_NO_FROM_PARAM_METHOD, i + 1); + throw raiseNode.raise(inliningTarget, TypeError, ITEM_D_IN_ARGTYPES_HAS_NO_FROM_PARAM_METHOD, i + 1); } converters[i] = cnv; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCPointerBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCPointerBuiltins.java index fe771d6fd5..4e8546fb23 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCPointerBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCPointerBuiltins.java @@ -51,8 +51,6 @@ import static com.oracle.graal.python.nodes.ErrorMessages.SLICE_START_IS_REQUIRED_FOR_STEP_0; import static com.oracle.graal.python.nodes.ErrorMessages.SLICE_STEP_CANNOT_BE_ZERO; import static com.oracle.graal.python.nodes.ErrorMessages.SLICE_STOP_IS_REQUIRED; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; import static com.oracle.graal.python.runtime.exception.PythonErrorType.IndexError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; @@ -61,8 +59,10 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -90,11 +90,11 @@ import com.oracle.graal.python.lib.PyIndexCheckNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -132,15 +132,15 @@ abstract static class PointerSetContentsNode extends Node { @Specialization static void set(VirtualFrame frame, Node inliningTarget, CDataObject self, Object value, + @Bind PythonLanguage language, @Cached PyTypeCheck pyTypeCheck, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached PyObjectStgDictNode pyObjectStgDictNode, @Cached(inline = false) IsInstanceNode isInstanceNode, @Cached KeepRefNode keepRefNode, - @Cached PointerNodes.WritePointerNode writePointerNode, - @Cached(inline = false) PythonObjectFactory factory) { + @Cached PointerNodes.WritePointerNode writePointerNode) { if (value == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, POINTER_DOES_NOT_SUPPORT_ITEM_DELETION); + throw raiseNode.raise(inliningTarget, TypeError, POINTER_DOES_NOT_SUPPORT_ITEM_DELETION); } StgDictObject stgdict = pyObjectStgDictNode.execute(inliningTarget, self); assert stgdict != null : "Cannot be NULL for pointer instances"; @@ -148,7 +148,7 @@ static void set(VirtualFrame frame, Node inliningTarget, CDataObject self, Objec if (!pyTypeCheck.isCDataObject(inliningTarget, value)) { boolean res = isInstanceNode.executeWith(frame, value, stgdict.proto); if (!res) { - raiseNode.get(inliningTarget).raise(TypeError, EXPECTED_N_INSTEAD_OF_P, stgdict.proto, value); + raiseNode.raise(inliningTarget, TypeError, EXPECTED_N_INSTEAD_OF_P, stgdict.proto, value); } } @@ -162,12 +162,13 @@ static void set(VirtualFrame frame, Node inliningTarget, CDataObject self, Objec */ keepRefNode.execute(frame, inliningTarget, self, 1, value); - Object keep = GetKeepedObjects(dst, factory); + Object keep = GetKeepedObjects(dst, language); keepRefNode.execute(frame, inliningTarget, self, 0, keep); } } - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory protected abstract static class NewNode extends PythonBuiltinNode { @Specialization @@ -175,18 +176,19 @@ static Object Pointer_new(Object type, @SuppressWarnings("unused") Object[] args @Bind("this") Node inliningTarget, @Cached PyTypeStgDictNode pyTypeStgDictNode, @Cached CtypesNodes.GenericPyCDataNewNode pyCDataNewNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { StgDictObject dict = pyTypeStgDictNode.checkAbstractClass(inliningTarget, type, raiseNode); if (dict.proto == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, CANNOT_CREATE_INSTANCE_HAS_NO_TYPE); + throw raiseNode.raise(inliningTarget, TypeError, CANNOT_CREATE_INSTANCE_HAS_NO_TYPE); } return pyCDataNewNode.execute(inliningTarget, type, dict); } } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory - protected abstract static class InitNode extends PythonBuiltinNode { + protected abstract static class InitNode extends PythonVarargsBuiltinNode { @Specialization static Object Pointer_init(VirtualFrame frame, CDataObject self, Object[] args, @SuppressWarnings("unused") PKeyword[] kwds, @@ -209,9 +211,9 @@ static Object get_contents(CDataObject self, @SuppressWarnings("unused") PNone v @Cached PyObjectStgDictNode pyObjectStgDictNode, @Cached CtypesNodes.PyCDataFromBaseObjNode fromBaseObjNode, @Cached PointerNodes.ReadPointerNode readPointerNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (self.b_ptr.isNull()) { - throw raiseNode.get(inliningTarget).raise(ValueError, NULL_POINTER_ACCESS); + throw raiseNode.raise(inliningTarget, ValueError, NULL_POINTER_ACCESS); } StgDictObject stgdict = pyObjectStgDictNode.execute(inliningTarget, self); @@ -252,13 +254,13 @@ static void Pointer_ass_item(VirtualFrame frame, CDataObject self, int index, Ob @Cached PyObjectStgDictNode pyObjectStgDictNode, @Cached PyTypeStgDictNode pyTypeStgDictNode, @Cached PointerNodes.ReadPointerNode readPointerNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (value == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(TypeError, POINTER_DOES_NOT_SUPPORT_ITEM_DELETION); + throw raiseNode.raise(inliningTarget, TypeError, POINTER_DOES_NOT_SUPPORT_ITEM_DELETION); } if (self.b_ptr.isNull()) { - throw raiseNode.get(inliningTarget).raise(ValueError, NULL_POINTER_ACCESS); + throw raiseNode.raise(inliningTarget, ValueError, NULL_POINTER_ACCESS); } StgDictObject stgdict = pyObjectStgDictNode.execute(inliningTarget, self); @@ -288,7 +290,7 @@ static Object Pointer_item(CDataObject self, int index, @Exclusive @Cached PyTypeStgDictNode pyTypeStgDictNode, @Exclusive @Cached PyObjectStgDictNode pyObjectStgDictNode, @Exclusive @Cached PointerNodes.ReadPointerNode readPointerNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (self.b_ptr.isNull()) { raiseNullPtr(inliningTarget, raiseNode); } @@ -308,8 +310,8 @@ static Object Pointer_item(CDataObject self, int index, } @InliningCutoff - private static void raiseNullPtr(Node inliningTarget, Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(ValueError, NULL_POINTER_ACCESS); + private static void raiseNullPtr(Node inliningTarget, PRaiseNode raiseNode) { + throw raiseNode.raise(inliningTarget, ValueError, NULL_POINTER_ACCESS); } } @@ -324,7 +326,7 @@ static Object doInt(CDataObject self, int index, @Exclusive @Cached PyTypeStgDictNode pyTypeStgDictNode, @Exclusive @Cached PyObjectStgDictNode pyObjectStgDictNode, @Exclusive @Cached PointerNodes.ReadPointerNode readPointerNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { return PointerGetItemNode.Pointer_item(self, index, inliningTarget, pyCDataGetNode, pyTypeStgDictNode, pyObjectStgDictNode, readPointerNode, raiseNode); } @@ -332,6 +334,7 @@ static Object doInt(CDataObject self, int index, @Specialization(limit = "1") static Object doSubscript(VirtualFrame frame, CDataObject self, PSlice slice, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @CachedLibrary("self") PythonBufferAccessLibrary bufferLib, @Exclusive @Cached PyCDataGetNode pyCDataGetNode, @Exclusive @Cached PyObjectStgDictNode pyObjectStgDictNode, @@ -340,8 +343,7 @@ static Object doSubscript(VirtualFrame frame, CDataObject self, PSlice slice, @Exclusive @Cached PyNumberAsSizeNode asSizeNode, @Cached TruffleString.FromByteArrayNode fromByteArrayNode, @Cached TruffleString.SwitchEncodingNode switchEncodingNode, - @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { /* * Since pointers have no length, and we want to apply different semantics to negative * indices than normal slicing, we have to dissect the slice object ourselves. @@ -352,19 +354,19 @@ static Object doSubscript(VirtualFrame frame, CDataObject self, PSlice slice, } else { step = asSizeNode.executeExact(frame, inliningTarget, slice.getStep(), ValueError); if (step == 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, SLICE_STEP_CANNOT_BE_ZERO); + throw raiseNode.raise(inliningTarget, ValueError, SLICE_STEP_CANNOT_BE_ZERO); } } if (slice.getStart() == PNone.NONE) { if (step < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, SLICE_START_IS_REQUIRED_FOR_STEP_0); + throw raiseNode.raise(inliningTarget, ValueError, SLICE_START_IS_REQUIRED_FOR_STEP_0); } start = 0; } else { start = asSizeNode.executeExact(frame, inliningTarget, slice.getStart(), ValueError); } if (slice.getStop() == PNone.NONE) { - throw raiseNode.get(inliningTarget).raise(ValueError, SLICE_STOP_IS_REQUIRED); + throw raiseNode.raise(inliningTarget, ValueError, SLICE_STOP_IS_REQUIRED); } stop = asSizeNode.executeExact(frame, inliningTarget, slice.getStop(), ValueError); int len; @@ -387,16 +389,16 @@ static Object doSubscript(VirtualFrame frame, CDataObject self, PSlice slice, byte[] ptr = bufferLib.getInternalOrCopiedByteArray(self); if (len <= 0) { - return factory.createEmptyBytes(); + return PFactory.createEmptyBytes(language); } - if (step == 1) { - return factory.createBytes(ptr, start, len); + if (start == 0 && step == 1) { + return PFactory.createBytes(language, ptr, len); } byte[] dest = new byte[len]; for (int cur = start, i = 0; i < len; cur += step, i++) { dest[i] = ptr[cur]; } - return factory.createBytes(dest); + return PFactory.createBytes(language, dest); } if (itemdict.getfunc == FieldDesc.u.getfunc) { // CTYPES_UNICODE byte[] ptr = bufferLib.getInternalOrCopiedByteArray(self); @@ -419,7 +421,7 @@ static Object doSubscript(VirtualFrame frame, CDataObject self, PSlice slice, for (int cur = start, i = 0; i < len; cur += step, i++) { np[i] = PointerGetItemNode.Pointer_item(self, cur, inliningTarget, pyCDataGetNode, pyTypeStgDictNode, pyObjectStgDictNode, readPointerNode, raiseNode); } - return factory.createList(np); + return PFactory.createList(language, np); } @Specialization(guards = "!isPSlice(item)", replaces = "doInt") @@ -431,12 +433,12 @@ static Object doGeneric(VirtualFrame frame, CDataObject self, Object item, @Exclusive @Cached PointerNodes.ReadPointerNode readPointerNode, @Exclusive @Cached PyNumberAsSizeNode asSizeNode, @Cached PyIndexCheckNode indexCheckNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (indexCheckNode.execute(inliningTarget, item)) { int i = asSizeNode.executeExact(frame, inliningTarget, item, IndexError); return PointerGetItemNode.Pointer_item(self, i, inliningTarget, pyCDataGetNode, pyTypeStgDictNode, pyObjectStgDictNode, readPointerNode, raiseNode); } - throw raiseNode.get(inliningTarget).raise(TypeError, POINTER_INDICES_MUST_BE_INTEGER); + throw raiseNode.raise(inliningTarget, TypeError, POINTER_INDICES_MUST_BE_INTEGER); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCPointerTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCPointerTypeBuiltins.java index 7bfb019725..ce5b44704d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCPointerTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCPointerTypeBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -49,17 +49,19 @@ import static com.oracle.graal.python.nodes.ErrorMessages.EXPECTED_CDATA_INSTANCE; import static com.oracle.graal.python.nodes.ErrorMessages.TYPE_MUST_BE_A_TYPE; import static com.oracle.graal.python.nodes.ErrorMessages.TYPE_MUST_HAVE_STORAGE_INFO; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.nodes.StringLiterals.T_AMPERSAND; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.TypeNode; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.IsInstanceNode; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.IsSubClassNode; import com.oracle.graal.python.builtins.modules.ctypes.CDataTypeBuiltins.CDataTypeFromParamNode; @@ -75,6 +77,8 @@ import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.str.StringUtils; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeBuiltins.TypeNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; @@ -84,7 +88,7 @@ import com.oracle.graal.python.nodes.object.SetDictNode; import com.oracle.graal.python.nodes.util.CastToJavaBooleanNode; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -99,6 +103,8 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PyCPointerType) public final class PyCPointerTypeBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = PyCPointerTypeBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return PyCPointerTypeBuiltinsFactory.getFactories(); @@ -111,7 +117,8 @@ protected List> getNodeFa protected static final TruffleString T_UPPER_T_LEFTBRACE = tsLiteral("T{"); @ImportStatic(PyCPointerTypeBuiltins.class) - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory protected abstract static class PyCPointerTypeNewNode extends PythonBuiltinNode { @@ -128,13 +135,13 @@ static Object PyCPointerType_new(VirtualFrame frame, Object type, Object[] args, @Cached TruffleStringBuilder.AppendStringNode appendStringNode, @Cached TruffleStringBuilder.ToStringNode toStringNode, @Cached StringUtils.SimpleTruffleStringFormatNode formatNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { /* * stgdict items size, align, length contain info about pointers itself, stgdict.proto * has info about the pointed to type! */ - StgDictObject stgdict = factory.createStgDictObject(PythonBuiltinClassType.StgDict); + StgDictObject stgdict = PFactory.createStgDictObject(language); stgdict.size = StgDictObject.VOID_PTR_SIZE; stgdict.align = FieldDesc.P.pffi_type.alignment; stgdict.length = 1; @@ -168,7 +175,7 @@ static Object PyCPointerType_new(VirtualFrame frame, Object type, Object[] args, /* replace the class dict by our updated spam dict */ PDict resDict = getDict.execute(result); if (resDict == null) { - resDict = factory.createDictFixedStorage((PythonObject) result); + resDict = PFactory.createDictFixedStorage(language, (PythonObject) result); } addAllToOtherNode.execute(frame, inliningTarget, resDict.getDictStorage(), stgdict); setDict.execute(inliningTarget, result, stgdict); @@ -185,15 +192,14 @@ protected abstract static class FromParamNode extends PythonBinaryBuiltinNode { /* _byref consumes a refcount to its argument */ static PyCArgObject byref(Node inliningTarget, Object obj, PyTypeCheck pyTypeCheck, - PythonObjectFactory factory, - PRaiseNode.Lazy raiseNode) { + PRaiseNode raiseNode) { if (!pyTypeCheck.isCDataObject(inliningTarget, obj)) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, EXPECTED_CDATA_INSTANCE); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, EXPECTED_CDATA_INSTANCE); } CDataObject cdata = (CDataObject) obj; - PyCArgObject parg = factory.createCArgObject(); + PyCArgObject parg = PFactory.createCArgObject(PythonLanguage.get(inliningTarget)); parg.tag = 'P'; parg.pffi_type = ffi_type_pointer; parg.obj = cdata; @@ -217,15 +223,14 @@ static Object PyCPointerType_from_param(VirtualFrame frame, Object type, Object @Cached PyObjectStgDictNode pyObjectStgDictNode, @Cached PyTypeStgDictNode pyTypeStgDictNode, @Cached CDataTypeFromParamNode fromParamNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { StgDictObject typedict = pyTypeStgDictNode.checkAbstractClass(inliningTarget, type, raiseNode); /* * If we expect POINTER(), but receive a instance, accept it by calling * byref(). */ if (isInstanceNode.executeWith(frame, value, typedict.proto)) { - return byref(inliningTarget, value, pyTypeCheck, factory, raiseNode); + return byref(inliningTarget, value, pyTypeCheck, raiseNode); } if (pyTypeCheck.isPointerObject(inliningTarget, value) || pyTypeCheck.isArrayObject(inliningTarget, value)) { @@ -252,7 +257,7 @@ static Object PyCPointerType_set_type(Object self, TruffleString type, @Cached HashingStorageSetItem setItem, @Cached IsTypeNode isTypeNode, @Cached PyTypeStgDictNode pyTypeStgDictNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { StgDictObject dict = pyTypeStgDictNode.checkAbstractClass(inliningTarget, self, raiseNode); PyCPointerType_SetProto(inliningTarget, dict, type, isTypeNode, pyTypeStgDictNode, raiseNode); dict.setDictStorage(setItem.execute(inliningTarget, dict.getDictStorage(), T__TYPE_, type)); @@ -262,8 +267,8 @@ static Object PyCPointerType_set_type(Object self, TruffleString type, @SuppressWarnings("unused") @Specialization(guards = "!isString(type)") static Object error(Object self, Object type, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, TYPE_MUST_BE_A_TYPE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, TYPE_MUST_BE_A_TYPE); } } @@ -282,12 +287,12 @@ static Object error(Object self, Object type, static void PyCPointerType_SetProto(Node inliningTarget, StgDictObject stgdict, Object proto, IsTypeNode isTypeNode, PyTypeStgDictNode pyTypeStgDictNode, - PRaiseNode.Lazy raiseNode) { + PRaiseNode raiseNode) { if (proto == null || !isTypeNode.execute(inliningTarget, proto)) { - throw raiseNode.get(inliningTarget).raise(TypeError, TYPE_MUST_BE_A_TYPE); + throw raiseNode.raise(inliningTarget, TypeError, TYPE_MUST_BE_A_TYPE); } if (pyTypeStgDictNode.execute(inliningTarget, proto) == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, TYPE_MUST_HAVE_STORAGE_INFO); + throw raiseNode.raise(inliningTarget, TypeError, TYPE_MUST_HAVE_STORAGE_INFO); } stgdict.proto = proto; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCSimpleTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCSimpleTypeBuiltins.java index 56265f5393..7701e9ffbe 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCSimpleTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCSimpleTypeBuiltins.java @@ -42,7 +42,6 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PyCSimpleType; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SimpleCData; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.StgDict; import static com.oracle.graal.python.builtins.modules.ctypes.CDataTypeBuiltins.J_FROM_PARAM; import static com.oracle.graal.python.builtins.modules.ctypes.CDataTypeBuiltins.T__AS_PARAMETER_; import static com.oracle.graal.python.builtins.modules.ctypes.CtypesModuleBuiltins.TYPEFLAG_ISPOINTER; @@ -53,7 +52,6 @@ import static com.oracle.graal.python.nodes.ErrorMessages.TYPE_S_NOT_SUPPORTED; import static com.oracle.graal.python.nodes.ErrorMessages.WHICH_MUST_BE_A_SINGLE_CHARACTER_STRING_CONTAINING_ONE_OF_S; import static com.oracle.graal.python.nodes.ErrorMessages.WRONG_TYPE; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.AttributeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; @@ -63,11 +61,13 @@ import java.util.List; import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.PythonOS; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.TypeNode; import com.oracle.graal.python.builtins.modules.BuiltinFunctions.IsInstanceNode; import com.oracle.graal.python.builtins.modules.ctypes.CFieldBuiltins.SetFuncNode; import com.oracle.graal.python.builtins.modules.ctypes.FFIType.FieldDesc; @@ -82,6 +82,8 @@ import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.str.StringNodes.InternStringNode; import com.oracle.graal.python.builtins.objects.str.StringUtils; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeBuiltins.TypeNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectSetAttr; @@ -95,8 +97,7 @@ import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -124,13 +125,16 @@ public final class PyCSimpleTypeBuiltins extends PythonBuiltins { protected static final TruffleString T_CTYPE_BE = tsLiteral("__ctype_be__"); protected static final TruffleString T_CTYPE_LE = tsLiteral("__ctype_le__"); + public static final TpSlots SLOTS = PyCSimpleTypeBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return PyCSimpleTypeBuiltinsFactory.getFactories(); } @ImportStatic(PyCPointerTypeBuiltins.class) - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory protected abstract static class PyCSimpleTypeNewNode extends PythonBuiltinNode { @@ -153,8 +157,8 @@ static Object PyCSimpleType_new(VirtualFrame frame, Object type, Object[] args, @Cached TruffleString.SwitchEncodingNode switchEncodingNode, @Cached TruffleString.EqualNode eqNode, @Cached TruffleString.FromCharArrayUTF16Node fromCharArrayNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { /* * create the new instance (which is a class, since we are a metatype!) @@ -163,7 +167,7 @@ static Object PyCSimpleType_new(VirtualFrame frame, Object type, Object[] args, Object proto = lookupAttrType.execute(frame, inliningTarget, result, T__TYPE_); if (proto == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(AttributeError, CLASS_MUST_DEFINE_A_TYPE_ATTRIBUTE); + throw raiseNode.raise(inliningTarget, AttributeError, CLASS_MUST_DEFINE_A_TYPE_ATTRIBUTE); } TruffleString proto_str; int proto_len; @@ -171,22 +175,22 @@ static Object PyCSimpleType_new(VirtualFrame frame, Object type, Object[] args, proto_str = toTruffleStringNode.execute(inliningTarget, proto); proto_len = codePointLengthNode.execute(proto_str, TS_ENCODING); } else { - throw raiseNode.get(inliningTarget).raise(TypeError, CLASS_MUST_DEFINE_A_TYPE_STRING_ATTRIBUTE); + throw raiseNode.raise(inliningTarget, TypeError, CLASS_MUST_DEFINE_A_TYPE_STRING_ATTRIBUTE); } if (proto_len != 1) { - throw raiseNode.get(inliningTarget).raise(ValueError, A_TYPE_ATTRIBUTE_WHICH_MUST_BE_A_STRING_OF_LENGTH_1); + throw raiseNode.raise(inliningTarget, ValueError, A_TYPE_ATTRIBUTE_WHICH_MUST_BE_A_STRING_OF_LENGTH_1); } if (indexOfStringNode.execute(T_SIMPLE_TYPE_CHARS, proto_str, 0, SIMPLE_TYPE_CHARS_LENGTH, TS_ENCODING) < 0) { - throw raiseNode.get(inliningTarget).raise(AttributeError, WHICH_MUST_BE_A_SINGLE_CHARACTER_STRING_CONTAINING_ONE_OF_S, T_SIMPLE_TYPE_CHARS); + throw raiseNode.raise(inliningTarget, AttributeError, WHICH_MUST_BE_A_SINGLE_CHARACTER_STRING_CONTAINING_ONE_OF_S, T_SIMPLE_TYPE_CHARS); } char code = (char) codePointAtIndexNode.execute(proto_str, 0, TS_ENCODING); FieldDesc fmt = FFIType._ctypes_get_fielddesc(code); if (fmt == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, TYPE_S_NOT_SUPPORTED, proto_str); + throw raiseNode.raise(inliningTarget, ValueError, TYPE_S_NOT_SUPPORTED, proto_str); } - StgDictObject stgdict = factory.createStgDictObject(StgDict); + StgDictObject stgdict = PFactory.createStgDictObject(language); stgdict.ffi_type_pointer = fmt.pffi_type; stgdict.align = fmt.pffi_type.alignment; @@ -204,7 +208,7 @@ static Object PyCSimpleType_new(VirtualFrame frame, Object type, Object[] args, /* replace the class dict by our updated spam dict */ PDict resDict = getDict.execute(result); if (resDict == null) { - resDict = factory.createDictFixedStorage((PythonObject) result); + resDict = PFactory.createDictFixedStorage(language, (PythonObject) result); } addAllToOtherNode.execute(frame, inliningTarget, resDict.getDictStorage(), stgdict); setDict.execute(inliningTarget, (PythonObject) result, stgdict); @@ -214,18 +218,16 @@ static Object PyCSimpleType_new(VirtualFrame frame, Object type, Object[] args, * PyCSimpleType_from_param generic method. */ PythonContext context = PythonContext.get(inliningTarget); - PythonObjectSlowPathFactory slowPathFactory = context.factory(); if (getBaseClassNode.execute(inliningTarget, result) == context.lookupType(SimpleCData)) { - PythonLanguage language = context.getLanguage(); if (eqNode.execute(T_LOWER_Z, proto_str, TS_ENCODING)) { /* c_char_p */ - LazyPyCSimpleTypeBuiltins.addCCharPFromParam(slowPathFactory, language, result); + LazyPyCSimpleTypeBuiltins.addCCharPFromParam(language, result); stgdict.flags |= TYPEFLAG_ISPOINTER; } else if (eqNode.execute(T_UPPER_Z, proto_str, TS_ENCODING)) { /* c_wchar_p */ - LazyPyCSimpleTypeBuiltins.addCWCharPFromParam(slowPathFactory, language, result); + LazyPyCSimpleTypeBuiltins.addCWCharPFromParam(language, result); stgdict.flags |= TYPEFLAG_ISPOINTER; } else if (eqNode.execute(T_UPPER_P, proto_str, TS_ENCODING)) { /* c_void_p */ - LazyPyCSimpleTypeBuiltins.addCVoidPFromParam(slowPathFactory, language, result); + LazyPyCSimpleTypeBuiltins.addCVoidPFromParam(language, result); stgdict.flags |= TYPEFLAG_ISPOINTER; } else if (eqNode.execute(T_LOWER_S, proto_str, TS_ENCODING) || eqNode.execute(T_UPPER_X, proto_str, TS_ENCODING) || @@ -241,8 +243,7 @@ static Object PyCSimpleType_new(VirtualFrame frame, Object type, Object[] args, toTruffleStringNode, getDict, setDict, - addAllToOtherNode, - factory); + addAllToOtherNode); StgDictObject sw_dict = pyTypeStgDictNode.execute(inliningTarget, swapped); setAttrString.execute(frame, inliningTarget, result, T_CTYPE_BE, swapped); setAttrString.execute(frame, inliningTarget, result, T_CTYPE_LE, result); @@ -262,8 +263,7 @@ private static Object CreateSwappedType(VirtualFrame frame, Node inliningTarget, CastToTruffleStringNode toString, GetDictIfExistsNode getDict, SetDictNode setDict, - HashingStorageAddAllToOther addAllToOther, - PythonObjectFactory factory) { + HashingStorageAddAllToOther addAllToOther) { int argsLen = args.length; Object[] swapped_args = new Object[argsLen]; TruffleString suffix = toString.execute(inliningTarget, internStringNode.execute(inliningTarget, T__BE)); @@ -277,7 +277,8 @@ private static Object CreateSwappedType(VirtualFrame frame, Node inliningTarget, * create the new instance (which is a class, since we are a metatype!) */ Object result = typeNew.execute(frame, type, swapped_args[0], swapped_args[1], swapped_args[2], kwds); - StgDictObject stgdict = factory.createStgDictObject(StgDict); + PythonLanguage language = PythonLanguage.get(inliningTarget); + StgDictObject stgdict = PFactory.createStgDictObject(language); stgdict.ffi_type_pointer = fmt.pffi_type; stgdict.align = fmt.pffi_type.alignment; stgdict.length = 0; @@ -290,7 +291,7 @@ private static Object CreateSwappedType(VirtualFrame frame, Node inliningTarget, /* replace the class dict by our updated spam dict */ PDict resDict = getDict.execute(result); if (resDict == null) { - resDict = factory.createDictFixedStorage((PythonObject) result); + resDict = PFactory.createDictFixedStorage(language, (PythonObject) result); } addAllToOther.execute(frame, inliningTarget, resDict.getDictStorage(), stgdict); setDict.execute(inliningTarget, (PythonObject) result, stgdict); @@ -314,8 +315,7 @@ static Object PyCSimpleType_from_param(VirtualFrame frame, Object type, Object v @Cached PyTypeStgDictNode pyTypeStgDictNode, @Cached PyObjectLookupAttr lookupAsParam, @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { /* * If the value is already an instance of the requested type, we can use it as is */ @@ -333,7 +333,7 @@ static Object PyCSimpleType_from_param(VirtualFrame frame, Object type, Object v FieldDesc fd = FFIType._ctypes_get_fielddesc(code); assert fd != null; - PyCArgObject parg = factory.createCArgObject(); + PyCArgObject parg = PFactory.createCArgObject(PythonLanguage.get(inliningTarget)); parg.tag = code; parg.pffi_type = fd.pffi_type; parg.valuePointer = Pointer.allocate(parg.pffi_type, dict.size); @@ -347,11 +347,11 @@ static Object PyCSimpleType_from_param(VirtualFrame frame, Object type, Object v Object as_parameter = lookupAsParam.execute(frame, inliningTarget, value, T__AS_PARAMETER_); if (as_parameter != PNone.NO_VALUE) { // Py_EnterRecursiveCall("while processing _as_parameter_"); TODO - Object r = PyCSimpleType_from_param(frame, type, as_parameter, inliningTarget, setFuncNode, isInstanceNode, pyTypeStgDictNode, lookupAsParam, codePointAtIndexNode, factory, raiseNode); + Object r = PyCSimpleType_from_param(frame, type, as_parameter, inliningTarget, setFuncNode, isInstanceNode, pyTypeStgDictNode, lookupAsParam, codePointAtIndexNode, raiseNode); // Py_LeaveRecursiveCall(); return r; } - throw raiseNode.get(inliningTarget).raise(TypeError, WRONG_TYPE); + throw raiseNode.raise(inliningTarget, TypeError, WRONG_TYPE); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCStructTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCStructTypeBuiltins.java index 04d9ba26cb..c169e46ab1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCStructTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCStructTypeBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,25 +41,21 @@ package com.oracle.graal.python.builtins.modules.ctypes; import static com.oracle.graal.python.nodes.ErrorMessages.ATTR_NAME_MUST_BE_STRING; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import java.util.List; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; -import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.modules.ctypes.StructUnionTypeBuiltins.PyCStructUnionTypeUpdateStgDict; -import com.oracle.graal.python.builtins.modules.ctypes.StructUnionTypeBuiltins.StructUnionTypeNewNode; import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringCheckedNode; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeBuiltins; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSetAttr.SetAttrBuiltinNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -80,11 +76,6 @@ protected List> getNodeFa return PyCStructTypeBuiltinsFactory.getFactories(); } - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) - @GenerateNodeFactory - protected abstract static class NewNode extends StructUnionTypeNewNode { - } - @Slot(value = SlotKind.tp_setattro, isComplex = true) @GenerateNodeFactory protected abstract static class SetattrNode extends SetAttrBuiltinNode { @@ -92,13 +83,12 @@ protected abstract static class SetattrNode extends SetAttrBuiltinNode { void doStringKey(VirtualFrame frame, Object object, TruffleString key, Object value, @Shared @Cached TypeBuiltins.SetattrNode typeSetAttr, @Shared @Cached TruffleString.EqualNode equalNode, - @Shared @Cached PyCStructUnionTypeUpdateStgDict updateStgDict, - @Shared @Cached PythonObjectFactory factory) { + @Shared @Cached PyCStructUnionTypeUpdateStgDict updateStgDict) { // CPython just delegates to "PyType_Type.tp_setattro" with the comment: /* XXX Should we disallow deleting _fields_? */ typeSetAttr.executeSetAttr(frame, object, key, value); if (equalNode.execute(key, StructUnionTypeBuiltins.T__FIELDS_, TS_ENCODING)) { - updateStgDict.execute(frame, object, value, true, factory); + updateStgDict.execute(frame, object, value, true); } } @@ -109,10 +99,9 @@ void doGeneric(VirtualFrame frame, Object object, Object keyObject, Object value @Cached CastToTruffleStringCheckedNode castKeyToStringNode, @Shared @Cached TypeBuiltins.SetattrNode typeSetAttr, @Shared @Cached TruffleString.EqualNode equalNode, - @Shared @Cached PyCStructUnionTypeUpdateStgDict updateStgDict, - @Shared @Cached PythonObjectFactory factory) { + @Shared @Cached PyCStructUnionTypeUpdateStgDict updateStgDict) { TruffleString key = castKeyToStringNode.cast(inliningTarget, keyObject, ATTR_NAME_MUST_BE_STRING, keyObject); - doStringKey(frame, object, key, value, typeSetAttr, equalNode, updateStgDict, factory); + doStringKey(frame, object, key, value, typeSetAttr, equalNode, updateStgDict); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/SimpleCDataBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/SimpleCDataBuiltins.java index 1b6d2405f8..e427764671 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/SimpleCDataBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/SimpleCDataBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,9 +44,6 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_TRUFFLE_CDATA_INIT_BUFFER_PROTOCOL; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode; import static com.oracle.graal.python.nodes.ErrorMessages.CANT_DELETE_ATTRIBUTE; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; @@ -54,6 +51,7 @@ import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -81,6 +79,7 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -110,13 +109,13 @@ public void postInitialize(Python3Core core) { } static void Simple_set_value(VirtualFrame frame, Node inliningTarget, CDataObject self, Object value, - PRaiseNode.Lazy raiseNode, + PRaiseNode raiseNode, PyObjectStgDictNode pyObjectStgDictNode, SetFuncNode setFuncNode, KeepRefNode keepRefNode) { StgDictObject dict = pyObjectStgDictNode.execute(inliningTarget, self); if (value == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, CANT_DELETE_ATTRIBUTE); + throw raiseNode.raise(inliningTarget, TypeError, CANT_DELETE_ATTRIBUTE); } assert dict != null : "Cannot be NULL for CDataObject instances"; assert dict.setfunc != FieldSet.nil; @@ -125,7 +124,8 @@ static void Simple_set_value(VirtualFrame frame, Node inliningTarget, CDataObjec keepRefNode.execute(frame, inliningTarget, self, 0, result); } - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory protected abstract static class NewNode extends PythonBuiltinNode { @Specialization @@ -133,15 +133,16 @@ static Object newCData(Object type, @SuppressWarnings("unused") Object[] args, @ @Bind("this") Node inliningTarget, @Cached PyTypeStgDictNode pyTypeStgDictNode, @Cached CtypesNodes.GenericPyCDataNewNode pyCDataNewNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { StgDictObject dict = pyTypeStgDictNode.checkAbstractClass(inliningTarget, type, raiseNode); return pyCDataNewNode.execute(inliningTarget, type, dict); } } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory - protected abstract static class InitNode extends PythonBuiltinNode { + protected abstract static class InitNode extends PythonVarargsBuiltinNode { @Specialization static Object Simple_init(VirtualFrame frame, CDataObject self, Object[] args, @SuppressWarnings("unused") PKeyword[] kwds, @@ -149,7 +150,7 @@ static Object Simple_init(VirtualFrame frame, CDataObject self, Object[] args, @ @Cached SetFuncNode setFuncNode, @Cached KeepRefNode keepRefNode, @Cached PyObjectStgDictNode pyObjectStgDictNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (args.length > 0) { Simple_set_value(frame, inliningTarget, self, args[0], raiseNode, pyObjectStgDictNode, setFuncNode, keepRefNode); } @@ -178,7 +179,7 @@ static Object set_value(VirtualFrame frame, CDataObject self, Object value, @Cached SetFuncNode setFuncNode, @Cached KeepRefNode keepRefNode, @Exclusive @Cached PyObjectStgDictNode pyObjectStgDictNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Simple_set_value(frame, inliningTarget, self, value, raiseNode, pyObjectStgDictNode, setFuncNode, keepRefNode); return PNone.NONE; } @@ -229,7 +230,7 @@ static boolean Simple_bool(CDataObject self, } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StgDictBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StgDictBuiltins.java index 5d7f407ed3..cd284528a9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StgDictBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StgDictBuiltins.java @@ -46,7 +46,6 @@ import static com.oracle.graal.python.nodes.ErrorMessages.FIELDS_MUST_BE_A_SEQUENCE; import static com.oracle.graal.python.nodes.ErrorMessages.S_IS_SPECIFIED_IN_ANONYMOUS_BUT_NOT_IN_FIELDS; import static com.oracle.graal.python.nodes.ErrorMessages.UNEXPECTED_TYPE; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SIZEOF__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.AttributeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; @@ -56,6 +55,9 @@ import java.util.List; import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -63,6 +65,7 @@ import com.oracle.graal.python.builtins.modules.ctypes.StgDictBuiltinsFactory.PyTypeStgDictNodeGen; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetInternalObjectArrayNode; +import com.oracle.graal.python.builtins.objects.dict.DictBuiltins; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins; @@ -79,19 +82,16 @@ import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.SpecialMethodNames; import com.oracle.graal.python.nodes.attributes.GetAttributeNode; -import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.util.PythonUtils; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -108,7 +108,7 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.StgDict) public final class StgDictBuiltins extends PythonBuiltins { - public static final TpSlots SLOTS = TpSlots.createEmpty(); + public static final TpSlots SLOTS = StgDictBuiltinsSlotsGen.SLOTS; @Override protected List> getNodeFactories() { @@ -117,25 +117,15 @@ protected List> getNodeFa protected static final TruffleString T__ANONYMOUS_ = tsLiteral("_anonymous_"); - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory - protected abstract static class InitNode extends PythonBuiltinNode { + protected abstract static class InitNode extends PythonVarargsBuiltinNode { @Specialization - Object init(VirtualFrame frame, StgDictObject self, Object[] args, PKeyword[] kwargs, - @Bind("this") Node inliningTarget, - @Cached PyObjectLookupAttr lookup, - @Cached CallNode callNode) { - Object initMethod = lookup.execute(frame, inliningTarget, PythonBuiltinClassType.PDict, SpecialMethodNames.T___INIT__); - Object[] dictArgs; - if (args.length > 0) { - dictArgs = new Object[args.length + 1]; - dictArgs[0] = self; - PythonUtils.arraycopy(args, 0, dictArgs, 1, args.length); - } else { - dictArgs = new Object[]{self}; - } - callNode.execute(frame, initMethod, dictArgs, kwargs); + static Object init(VirtualFrame frame, StgDictObject self, Object[] args, PKeyword[] kwargs, + @Cached DictBuiltins.InitNode dictInit) { + dictInit.execute(frame, self, args, kwargs); self.format = null; self.ndim = 0; self.shape = null; @@ -171,12 +161,12 @@ Object doit(VirtualFrame frame, StgDictObject self, @SuppressWarnings("truffle-inlining") // footprint reduction 112 -> 94 protected abstract static class MakeFieldsNode extends PNodeWithContext { - abstract void execute(VirtualFrame frame, Object type, CFieldObject descr, int index, int offset, PythonObjectFactory factory); + abstract void execute(VirtualFrame frame, Object type, CFieldObject descr, int index, int offset); @TruffleBoundary - private void executeBoundary(Object type, CFieldObject descr, int index, int offset, PythonObjectFactory factory) { + private void executeBoundary(Object type, CFieldObject descr, int index, int offset) { // recursive calls are done as boundary calls to avoid too many deopts - execute(null, type, descr, index, offset, factory); + execute(null, type, descr, index, offset); } /* @@ -185,7 +175,7 @@ private void executeBoundary(Object type, CFieldObject descr, int index, int off * into type. */ @Specialization - static void MakeFields(VirtualFrame frame, Object type, CFieldObject descr, int index, int offset, PythonObjectFactory factory, + static void MakeFields(VirtualFrame frame, Object type, CFieldObject descr, int index, int offset, @Bind("this") Node inliningTarget, @Cached GetClassNode getClassNode, @Cached PyObjectGetAttrO getAttributeNode, @@ -197,10 +187,10 @@ static void MakeFields(VirtualFrame frame, Object type, CFieldObject descr, int @Cached("create(T__FIELDS_)") GetAttributeNode getAttrString, @Cached MakeFieldsNode recursiveNode, @Cached("createFor(this)") IndirectCallData indirectCallData, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object fields = getAttrString.executeObject(frame, descr.proto); if (!sequenceCheckNode.execute(inliningTarget, fields)) { - throw raiseNode.get(inliningTarget).raise(TypeError, FIELDS_MUST_BE_A_SEQUENCE); + throw raiseNode.raise(inliningTarget, TypeError, FIELDS_MUST_BE_A_SEQUENCE); } PythonContext context = PythonContext.get(inliningTarget); @@ -215,18 +205,18 @@ static void MakeFields(VirtualFrame frame, Object type, CFieldObject descr, int Object fname = array[0]; CFieldObject fdescr = (CFieldObject) getAttributeNode.execute(frame, inliningTarget, descr.proto, fname); if (getClassNode.execute(inliningTarget, fdescr) != context.lookupType(CField)) { - throw raiseNode.get(inliningTarget).raise(TypeError, UNEXPECTED_TYPE); + throw raiseNode.raise(inliningTarget, TypeError, UNEXPECTED_TYPE); } if (fdescr.anonymous != 0) { Object state = IndirectCallContext.enter(frame, language, context, indirectCallData); try { - recursiveNode.executeBoundary(type, fdescr, index + fdescr.index, offset + fdescr.offset, context.factory()); + recursiveNode.executeBoundary(type, fdescr, index + fdescr.index, offset + fdescr.offset); } finally { IndirectCallContext.exit(frame, language, context, state); } continue; } - CFieldObject new_descr = factory.createCFieldObject(CField); + CFieldObject new_descr = PFactory.createCFieldObject(language); // assert (Py_TYPE(new_descr) == PythonBuiltinClassType.CField); new_descr.size = fdescr.size; new_descr.offset = fdescr.offset + offset; @@ -252,10 +242,10 @@ static StgDictObject executeUncached(Object type) { return PyTypeStgDictNodeGen.getUncached().execute(null, type); } - protected StgDictObject checkAbstractClass(Node inliningTarget, Object type, PRaiseNode.Lazy raiseNode) { + protected StgDictObject checkAbstractClass(Node inliningTarget, Object type, PRaiseNode raiseNode) { StgDictObject dict = execute(inliningTarget, type); if (dict == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, ABSTRACT_CLASS); + throw raiseNode.raise(inliningTarget, TypeError, ABSTRACT_CLASS); } return dict; } @@ -305,13 +295,13 @@ static StgDictObject PyObject_stgdict(Node inliningTarget, Object self, @SuppressWarnings("truffle-inlining") // footprint reduction 132 -> 115 protected abstract static class MakeAnonFieldsNode extends Node { - abstract void execute(VirtualFrame frame, Object type, PythonObjectFactory factory); + abstract void execute(VirtualFrame frame, Object type); /* * Iterate over the names in the type's _anonymous_ attribute, if present, */ @Specialization - static void MakeAnonFields(VirtualFrame frame, Object type, PythonObjectFactory factory, + static void MakeAnonFields(VirtualFrame frame, Object type, @Bind("this") Node inliningTarget, @Cached PySequenceCheckNode sequenceCheckNode, @Cached PyObjectSizeNode sizeNode, @@ -320,25 +310,25 @@ static void MakeAnonFields(VirtualFrame frame, Object type, PythonObjectFactory @Cached GetClassNode getClassNode, @Cached PyObjectGetAttrO getAttr, @Cached PyObjectLookupAttr lookupAnon, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object anon = lookupAnon.execute(frame, inliningTarget, type, T__ANONYMOUS_); if (PGuards.isPNone(anon)) { return; } if (!sequenceCheckNode.execute(inliningTarget, anon)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ANONYMOUS_MUST_BE_A_SEQUENCE); + throw raiseNode.raise(inliningTarget, TypeError, ANONYMOUS_MUST_BE_A_SEQUENCE); } for (int i = 0; i < sizeNode.execute(frame, inliningTarget, anon); ++i) { Object fname = getItemNode.execute(frame, inliningTarget, anon, i); /* borrowed */ CFieldObject descr = (CFieldObject) getAttr.execute(frame, inliningTarget, type, fname); if (getClassNode.execute(inliningTarget, descr) != CField) { - throw raiseNode.get(inliningTarget).raise(AttributeError, S_IS_SPECIFIED_IN_ANONYMOUS_BUT_NOT_IN_FIELDS, fname); + throw raiseNode.raise(inliningTarget, AttributeError, S_IS_SPECIFIED_IN_ANONYMOUS_BUT_NOT_IN_FIELDS, fname); } descr.anonymous = 1; /* descr is in the field descriptor. */ - makeFieldsNode.execute(frame, type, descr, descr.index, descr.offset, factory); + makeFieldsNode.execute(frame, type, descr, descr.index, descr.offset); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StructUnionTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StructUnionTypeBuiltins.java index ec38eb8b2a..8f571b09e6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StructUnionTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StructUnionTypeBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -49,7 +49,7 @@ import static com.oracle.graal.python.builtins.modules.ctypes.PyCPointerTypeBuiltins.T_UPPER_B; import static com.oracle.graal.python.builtins.modules.ctypes.PyCPointerTypeBuiltins.T_UPPER_T_LEFTBRACE; import static com.oracle.graal.python.builtins.modules.ctypes.StgDictObject.DICTFLAG_FINAL; -import static com.oracle.graal.python.nodes.ErrorMessages.BIT_FIELDS_NOT_ALLOWED_FOR_TYPE_S; +import static com.oracle.graal.python.nodes.ErrorMessages.BIT_FIELDS_NOT_ALLOWED_FOR_TYPE_N; import static com.oracle.graal.python.nodes.ErrorMessages.FIELDS_IS_FINAL; import static com.oracle.graal.python.nodes.ErrorMessages.FIELDS_MUST_BE_A_SEQUENCE_OF_NAME_C_TYPE_PAIRS; import static com.oracle.graal.python.nodes.ErrorMessages.FIELDS_MUST_BE_A_SEQUENCE_OF_PAIRS; @@ -57,7 +57,6 @@ import static com.oracle.graal.python.nodes.ErrorMessages.PACK_MUST_BE_A_NON_NEGATIVE_INTEGER; import static com.oracle.graal.python.nodes.ErrorMessages.SECOND_ITEM_IN_FIELDS_TUPLE_INDEX_D_MUST_BE_A_C_TYPE; import static com.oracle.graal.python.nodes.ErrorMessages.STRUCTURE_OR_UNION_CANNOT_CONTAIN_ITSELF; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.nodes.StringLiterals.T_RBRACE; import static com.oracle.graal.python.runtime.exception.PythonErrorType.AttributeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; @@ -66,11 +65,13 @@ import java.util.List; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.modules.BuiltinConstructors.TypeNode; import com.oracle.graal.python.builtins.modules.ctypes.CFieldBuiltins.PyCFieldFromDesc; import com.oracle.graal.python.builtins.modules.ctypes.CtypesNodes.PyTypeCheck; import com.oracle.graal.python.builtins.modules.ctypes.FFIType.FFI_TYPES; @@ -87,8 +88,9 @@ import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.str.StringUtils; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeBuiltins.TypeNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyObjectLookupAttr; @@ -104,7 +106,7 @@ import com.oracle.graal.python.nodes.object.SetDictNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -123,6 +125,8 @@ }) public final class StructUnionTypeBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = StructUnionTypeBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return StructUnionTypeBuiltinsFactory.getFactories(); @@ -137,7 +141,8 @@ protected List> getNodeFa protected static final TruffleString T__PACK_ = tsLiteral("_pack_"); @ImportStatic(StructUnionTypeBuiltins.class) - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory public abstract static class StructUnionTypeNewNode extends PythonBuiltinNode { @@ -148,6 +153,7 @@ protected boolean isStruct() { @Specialization protected Object StructUnionTypeNew(VirtualFrame frame, Object type, Object[] args, PKeyword[] kwds, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached HashingStorageAddAllToOther addAllToOtherNode, @Cached HashingStorageGetItem getItemResDict, @Cached HashingStorageGetItem getItemStgDict, @@ -156,8 +162,7 @@ protected Object StructUnionTypeNew(VirtualFrame frame, Object type, Object[] ar @Cached GetDictIfExistsNode getDict, @Cached SetDictNode setDict, @Cached GetBaseClassNode getBaseClassNode, - @Cached PyObjectSetAttr setFieldsAttributeNode, - @Cached PythonObjectFactory factory) { + @Cached PyObjectSetAttr setFieldsAttributeNode) { /* * create the new instance (which is a class, since we are a metatype!) */ @@ -165,13 +170,13 @@ protected Object StructUnionTypeNew(VirtualFrame frame, Object type, Object[] ar PDict resDict = getDict.execute(result); if (resDict == null) { - resDict = factory.createDictFixedStorage((PythonObject) result); + resDict = PFactory.createDictFixedStorage(language, (PythonObject) result); } if (getItemResDict.hasKey(inliningTarget, resDict.getDictStorage(), T__ABSTRACT_)) { return result; } - StgDictObject dict = factory.createStgDictObject(PythonBuiltinClassType.StgDict); + StgDictObject dict = PFactory.createStgDictObject(language); if (!isStruct()) { dict.flags |= TYPEFLAG_HASUNION; } @@ -205,7 +210,7 @@ protected Object StructUnionTypeNew(VirtualFrame frame, Object type, Object[] ar @ImportStatic(StructUnionTypeBuiltins.class) @SuppressWarnings("truffle-inlining") // footprint reduction 292 -> 275 protected abstract static class PyCStructUnionTypeUpdateStgDict extends Node { - abstract void execute(VirtualFrame frame, Object type, Object fields, boolean isStruct, PythonObjectFactory factory); + abstract void execute(VirtualFrame frame, Object type, Object fields, boolean isStruct); /* * Retrieve the (optional) _pack_ attribute from a type, the _fields_ attribute, and create @@ -213,12 +218,11 @@ protected abstract static class PyCStructUnionTypeUpdateStgDict extends Node { */ @SuppressWarnings("fallthrough") @Specialization - static void PyCStructUnionType_update_stgdict(VirtualFrame frame, Object type, Object fields, boolean isStruct, PythonObjectFactory factory, + static void PyCStructUnionType_update_stgdict(VirtualFrame frame, Object type, Object fields, boolean isStruct, @Bind("this") Node inliningTarget, @Cached PyTypeCheck pyTypeCheck, @Cached GetInternalObjectArrayNode getArray, @Cached PyCFieldFromDesc cFieldFromDesc, - @Cached GetNameNode getNameNode, @Cached CheckIsSequenceNode isSequenceNode, @Cached PyObjectGetItem getItemNode, @Cached PyObjectSizeNode sizeNode, @@ -235,7 +239,7 @@ static void PyCStructUnionType_update_stgdict(VirtualFrame frame, Object type, O @Cached CastToTruffleStringNode castToTruffleStringNode, @Cached TruffleStringBuilder.AppendStringNode appendStringNode, @Cached TruffleStringBuilder.ToStringNode toStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { /* * HACK Alert: I cannot be bothered to fix ctypes.com, so there has to be a way to use * the old, broken semantics: _fields_ are not extended but replaced in subclasses. @@ -259,7 +263,7 @@ static void PyCStructUnionType_update_stgdict(VirtualFrame frame, Object type, O pack = asSizeNode.executeLossy(frame, inliningTarget, tmp); } catch (PException e) { e.expectTypeOrOverflowError(inliningTarget, isBuiltinClassProfile); - throw raiseNode.get(inliningTarget).raise(ValueError, PACK_MUST_BE_A_NON_NEGATIVE_INTEGER); + throw raiseNode.raise(inliningTarget, ValueError, PACK_MUST_BE_A_NON_NEGATIVE_INTEGER); } } @@ -269,14 +273,14 @@ static void PyCStructUnionType_update_stgdict(VirtualFrame frame, Object type, O len = sizeNode.execute(frame, inliningTarget, fields); } catch (PException e) { e.expectTypeError(inliningTarget, isBuiltinClassProfile); - throw raiseNode.get(inliningTarget).raise(TypeError, FIELDS_MUST_BE_A_SEQUENCE_OF_PAIRS); + throw raiseNode.raise(inliningTarget, TypeError, FIELDS_MUST_BE_A_SEQUENCE_OF_PAIRS); } StgDictObject stgdict = pyTypeStgDictNode.execute(inliningTarget, type); /* If this structure/union is already marked final we cannot assign _fields_ anymore. */ if ((stgdict.flags & DICTFLAG_FINAL) != 0) { /* is final ? */ - throw raiseNode.get(inliningTarget).raise(AttributeError, FIELDS_IS_FINAL); + throw raiseNode.raise(inliningTarget, AttributeError, FIELDS_IS_FINAL); } stgdict.format = null; @@ -321,7 +325,6 @@ static void PyCStructUnionType_update_stgdict(VirtualFrame frame, Object type, O for (int idx = 0; idx < len + 1; idx++) { stgdict.ffi_type_pointer.elements[idx] = new FFIType(); } - */ ffi_ofs = 0; } @@ -346,13 +349,13 @@ static void PyCStructUnionType_update_stgdict(VirtualFrame frame, Object type, O Object pair = getItemNode.execute(frame, inliningTarget, fields, i); // !PyArg_ParseTuple(pair, "UO|i", & name, &desc, &bitsize) if (!PGuards.isPTuple(pair)) { - fieldsError(raiseNode.get(inliningTarget)); + fieldsError(inliningTarget, raiseNode); } SequenceStorage storage = ((PTuple) pair).getSequenceStorage(); Object[] tuple = getArray.execute(inliningTarget, storage); int tupleLen = storage.length(); if (tupleLen < 2 || !PGuards.isString(tuple[0]) || (tupleLen > 2 && !PGuards.isInteger(tuple[2]))) { - fieldsError(raiseNode.get(inliningTarget)); + fieldsError(inliningTarget, raiseNode); } Object name = tuple[0]; Object desc = tuple[1]; @@ -363,7 +366,7 @@ static void PyCStructUnionType_update_stgdict(VirtualFrame frame, Object type, O } StgDictObject dict = pyTypeStgDictNode.execute(inliningTarget, desc); if (dict == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, SECOND_ITEM_IN_FIELDS_TUPLE_INDEX_D_MUST_BE_A_C_TYPE, i); + throw raiseNode.raise(inliningTarget, TypeError, SECOND_ITEM_IN_FIELDS_TUPLE_INDEX_D_MUST_BE_A_C_TYPE, i); } stgdict.ffi_type_pointer.elements[ffi_ofs + i] = dict.ffi_type_pointer; if ((dict.flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER)) != 0) { @@ -389,10 +392,10 @@ static void PyCStructUnionType_update_stgdict(VirtualFrame frame, Object type, O } /* else fall through */ default: - throw raiseNode.get(inliningTarget).raise(TypeError, BIT_FIELDS_NOT_ALLOWED_FOR_TYPE_S, getNameNode.execute(inliningTarget, desc)); + throw raiseNode.raise(inliningTarget, TypeError, BIT_FIELDS_NOT_ALLOWED_FOR_TYPE_N, desc); } if (bitsize <= 0 || bitsize > dict.size * 8) { - throw raiseNode.get(inliningTarget).raise(ValueError, NUMBER_OF_BITS_INVALID_FOR_BIT_FIELD); + throw raiseNode.raise(inliningTarget, ValueError, NUMBER_OF_BITS_INVALID_FOR_BIT_FIELD); } } else { bitsize = 0; @@ -412,7 +415,7 @@ static void PyCStructUnionType_update_stgdict(VirtualFrame frame, Object type, O CFieldObject prop; if (isStruct) { int[] props = new int[]{field_size, bitofs, size, offset, align}; - prop = cFieldFromDesc.execute(inliningTarget, desc, i, bitsize, pack, big_endian, props, factory); + prop = cFieldFromDesc.execute(inliningTarget, desc, i, bitsize, pack, big_endian, props); field_size = props[0]; bitofs = props[1]; size = props[2]; @@ -426,7 +429,7 @@ static void PyCStructUnionType_update_stgdict(VirtualFrame frame, Object type, O offset = 0; align = 0; int[] props = new int[]{field_size, bitofs, size, offset, align}; - prop = cFieldFromDesc.execute(inliningTarget, desc, i, bitsize, pack, big_endian, props, factory); + prop = cFieldFromDesc.execute(inliningTarget, desc, i, bitsize, pack, big_endian, props); field_size = props[0]; bitofs = props[1]; size = props[2]; @@ -516,7 +519,6 @@ static void PyCStructUnionType_update_stgdict(VirtualFrame frame, Object type, O fieldsError(); } Object desc = tuple[1]; - StgDictObject dict = pyTypeStgDictNode.execute(desc); if (dict == null) { throw raise(TypeError, SECOND_ITEM_IN_FIELDS_TUPLE_INDEX_D_MUST_BE_A_C_TYPE, i); @@ -557,19 +559,19 @@ static void PyCStructUnionType_update_stgdict(VirtualFrame frame, Object type, O */ // !PyArg_ParseTuple(pair, "UO|i", & name, &desc, &bitsize) if (!PGuards.isPTuple(pair)) { - fieldsError(raiseNode.get(inliningTarget)); + fieldsError(inliningTarget, raiseNode); } SequenceStorage storage = ((PTuple) pair).getSequenceStorage(); Object[] tuple = getArray.execute(inliningTarget, storage); int tupleLen = storage.length(); if (tupleLen < 2 || !PGuards.isString(tuple[0]) || (tupleLen > 2 && !PGuards.isInteger(tuple[2]))) { - fieldsError(raiseNode.get(inliningTarget)); + fieldsError(inliningTarget, raiseNode); } Object desc = tuple[1]; StgDictObject dict = pyTypeStgDictNode.execute(inliningTarget, desc); /* Possibly this check could be avoided, but see above comment. */ if (dict == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, SECOND_ITEM_IN_FIELDS_TUPLE_INDEX_D_MUST_BE_A_C_TYPE, i); + throw raiseNode.raise(inliningTarget, TypeError, SECOND_ITEM_IN_FIELDS_TUPLE_INDEX_D_MUST_BE_A_C_TYPE, i); } assert (element_index < (ffi_ofs + len)); /* will be used below */ if (!pyTypeCheck.isPyCArrayTypeObject(inliningTarget, desc)) { @@ -579,7 +581,7 @@ static void PyCStructUnionType_update_stgdict(VirtualFrame frame, Object type, O int length = dict.length; StgDictObject edict = pyTypeStgDictNode.execute(inliningTarget, dict.proto); if (edict == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, SECOND_ITEM_IN_FIELDS_TUPLE_INDEX_D_MUST_BE_A_C_TYPE, i); + throw raiseNode.raise(inliningTarget, TypeError, SECOND_ITEM_IN_FIELDS_TUPLE_INDEX_D_MUST_BE_A_C_TYPE, i); } FFIType ffiType = new FFIType( length * edict.ffi_type_pointer.size, @@ -608,15 +610,15 @@ static void PyCStructUnionType_update_stgdict(VirtualFrame frame, Object type, O * We did check that this flag was NOT set above, it must not have been set until now. */ if ((stgdict.flags & DICTFLAG_FINAL) != 0) { - throw raiseNode.get(inliningTarget).raise(AttributeError, STRUCTURE_OR_UNION_CANNOT_CONTAIN_ITSELF); + throw raiseNode.raise(inliningTarget, AttributeError, STRUCTURE_OR_UNION_CANNOT_CONTAIN_ITSELF); } stgdict.flags |= DICTFLAG_FINAL; - makeAnonFieldsNode.execute(frame, type, factory); + makeAnonFieldsNode.execute(frame, type); } - static void fieldsError(PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, FIELDS_MUST_BE_A_SEQUENCE_OF_NAME_C_TYPE_PAIRS); + static void fieldsError(Node inliningTarget, PRaiseNode raiseNode) { + throw raiseNode.raise(inliningTarget, TypeError, FIELDS_MUST_BE_A_SEQUENCE_OF_NAME_C_TYPE_PAIRS); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StructureBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StructureBuiltins.java index b778fed0c6..b87ba9c02b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StructureBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StructureBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,13 +46,13 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_TRUFFLE_CDATA_INIT_BUFFER_PROTOCOL; import static com.oracle.graal.python.nodes.ErrorMessages.DUPLICATE_VALUES_FOR_FIELD_S; import static com.oracle.graal.python.nodes.ErrorMessages.TOO_MANY_INITIALIZERS; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import java.util.List; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -66,12 +66,14 @@ import com.oracle.graal.python.builtins.objects.common.HashingStorageNodesFactory.HashingStorageGetItemNodeGen; import com.oracle.graal.python.builtins.objects.common.KeywordsStorage; import com.oracle.graal.python.builtins.objects.function.PKeyword; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyObjectSetAttr; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext; @@ -90,6 +92,8 @@ @CoreFunctions(extendClasses = {PythonBuiltinClassType.Structure, PythonBuiltinClassType.Union}) public final class StructureBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = StructureBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return StructureBuiltinsFactory.getFactories(); @@ -104,7 +108,8 @@ public void postInitialize(Python3Core core) { }); } - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory protected abstract static class NewNode extends PythonBuiltinNode { @@ -113,15 +118,16 @@ static Object GenericPyCDataNew(Object type, @SuppressWarnings("unused") Object[ @Bind("this") Node inliningTarget, @Cached PyTypeStgDictNode pyTypeStgDictNode, @Cached CtypesNodes.GenericPyCDataNewNode pyCDataNewNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { StgDictObject dict = pyTypeStgDictNode.checkAbstractClass(inliningTarget, type, raiseNode); return pyCDataNewNode.execute(inliningTarget, type, dict); } } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory - protected abstract static class InitNode extends PythonBuiltinNode { + protected abstract static class InitNode extends PythonVarargsBuiltinNode { private static final int RECURSION_LIMIT = 5; @Specialization @@ -136,12 +142,12 @@ static Object Struct_init(VirtualFrame frame, CDataObject self, Object[] args, P @Cached PyTypeStgDictNode pyTypeStgDictNode, @Cached GetBaseClassNode getBaseClassNode, @Cached TruffleString.EqualNode equalNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (args.length > 0) { int res = _init_pos_args(frame, inliningTarget, self, getClassNode.execute(inliningTarget, self), args, kwds, 0, indirectCallData, setAttr, getItemNode, toString, getItem, pyTypeStgDictNode, getBaseClassNode, equalNode, raiseNode, RECURSION_LIMIT); if (res < args.length) { - throw raiseNode.get(inliningTarget).raise(TypeError, TOO_MANY_INITIALIZERS); + throw raiseNode.raise(inliningTarget, TypeError, TOO_MANY_INITIALIZERS); } } @@ -173,7 +179,7 @@ static int _init_pos_args(VirtualFrame frame, Node inliningTarget, Object self, PyTypeStgDictNode pyTypeStgDictNode, GetBaseClassNode getBaseClassNode, EqualNode equalNode, - PRaiseNode.Lazy raiseNode, + PRaiseNode raiseNode, int recursionLimit) { Object fields; int index = idx; @@ -206,9 +212,7 @@ static int _init_pos_args(VirtualFrame frame, Node inliningTarget, Object self, Object val = args[i + index]; if (kwds.length > 0) { if (KeywordsStorage.findStringKey(kwds, name, equalNode) != -1) { - // using execute() instead of raise() because we need to pass raisingNode - // explicitly (raiseNode might be uncached) - throw raiseNode.get(inliningTarget).execute(inliningTarget, TypeError, null, PNone.NO_VALUE, DUPLICATE_VALUES_FOR_FIELD_S, new Object[]{name}); + throw raiseNode.raise(inliningTarget, TypeError, DUPLICATE_VALUES_FOR_FIELD_S, name); } } @@ -225,7 +229,7 @@ static int _init_pos_args_boundary(Object self, Object type, Object[] args, PKey return _init_pos_args(null, null, self, type, args, kwds, idx, indirectCallData, setAttr, getItemNode, CastToTruffleStringNode.getUncached(), HashingStorageGetItemNodeGen.getUncached(), PyTypeStgDictNodeGen.getUncached(), - GetBaseClassNode.getUncached(), TruffleString.EqualNode.getUncached(), PRaiseNode.Lazy.getUncached(), 0); + GetBaseClassNode.getUncached(), TruffleString.EqualNode.getUncached(), PRaiseNode.getUncached(), 0); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/UnionTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/UnionTypeBuiltins.java index 4b494e6811..75e142bd84 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/UnionTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/UnionTypeBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,14 +40,13 @@ */ package com.oracle.graal.python.builtins.modules.ctypes; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import java.util.List; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; @@ -61,7 +60,6 @@ import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -84,7 +82,8 @@ protected List> getNodeFa return UnionTypeBuiltinsFactory.getFactories(); } - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory protected abstract static class NewNode extends StructUnionTypeNewNode { @Override @@ -102,10 +101,9 @@ static void doStringKey(VirtualFrame frame, Object object, TruffleString key, Ob @Exclusive @Cached ObjectNodes.GenericSetAttrNode genericSetAttrNode, @Shared @Cached WriteAttributeToObjectNode write, @Shared @Cached TruffleString.EqualNode equalNode, - @Shared @Cached PyCStructUnionTypeUpdateStgDict updateStgDict, - @Shared @Cached PythonObjectFactory factory) { + @Shared @Cached PyCStructUnionTypeUpdateStgDict updateStgDict) { genericSetAttrNode.execute(inliningTarget, frame, object, key, value, write); - updateStgDictIfNecessary(frame, object, key, value, equalNode, updateStgDict, factory); + updateStgDictIfNecessary(frame, object, key, value, equalNode, updateStgDict); } // @Exclusive to address warning @@ -114,21 +112,20 @@ static void doStringKey(VirtualFrame frame, Object object, TruffleString key, Ob static void doGenericKey(VirtualFrame frame, Object object, Object keyObject, Object value, @Bind("this") Node inliningTarget, @Cached CastToTruffleStringNode castKeyNode, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Exclusive @Cached ObjectNodes.GenericSetAttrNode genericSetAttrNode, @Shared @Cached WriteAttributeToObjectNode write, @Shared @Cached TruffleString.EqualNode equalNode, - @Shared @Cached PyCStructUnionTypeUpdateStgDict updateStgDict, - @Shared @Cached PythonObjectFactory factory) { + @Shared @Cached PyCStructUnionTypeUpdateStgDict updateStgDict) { TruffleString key = GenericSetAttrNode.castAttributeKey(inliningTarget, keyObject, castKeyNode, raiseNode); genericSetAttrNode.execute(inliningTarget, frame, object, key, value, write); - updateStgDictIfNecessary(frame, object, key, value, equalNode, updateStgDict, factory); + updateStgDictIfNecessary(frame, object, key, value, equalNode, updateStgDict); } private static void updateStgDictIfNecessary(VirtualFrame frame, Object object, TruffleString key, Object value, - EqualNode equalNode, PyCStructUnionTypeUpdateStgDict updateStgDict, PythonObjectFactory factory) { + EqualNode equalNode, PyCStructUnionTypeUpdateStgDict updateStgDict) { if (equalNode.execute(key, StructUnionTypeBuiltins.T__FIELDS_, TS_ENCODING)) { - updateStgDict.execute(frame, object, value, false, factory); + updateStgDict.execute(frame, object, value, false); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/memory/PointerNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/memory/PointerNodes.java index f018dbe61e..5ce63f3b5b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/memory/PointerNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/memory/PointerNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,9 +41,12 @@ package com.oracle.graal.python.builtins.modules.ctypes.memory; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.NotImplementedError; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.OverflowError; import static com.oracle.graal.python.builtins.modules.ctypes.CtypesNodes.WCHAR_T_SIZE; import static com.oracle.graal.python.util.PythonUtils.ARRAY_ACCESSOR; +import java.math.BigInteger; + import com.oracle.graal.python.builtins.modules.ctypes.memory.Pointer.ByteArrayStorage; import com.oracle.graal.python.builtins.modules.ctypes.memory.Pointer.LongPointerStorage; import com.oracle.graal.python.builtins.modules.ctypes.memory.Pointer.MemoryBlock; @@ -58,14 +61,15 @@ import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr; import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions; +import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.util.CastToJavaUnsignedLongNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; @@ -671,7 +675,7 @@ static long doMemoryView(Node inliningTarget, MemoryBlock memory, MemoryViewStor throw CompilerDirectives.shouldNotReachHere(e); } } else { - throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, ErrorMessages.MEMORYVIEW_CANNOT_BE_CONVERTED_TO_NATIVE_MEMORY); + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, ErrorMessages.MEMORYVIEW_CANNOT_BE_CONVERTED_TO_NATIVE_MEMORY); } memory.storage = new LongPointerStorage(nativePointer); return nativePointer + offset; @@ -689,7 +693,7 @@ static long doPythonObject(Node inliningTarget, @SuppressWarnings("unused") Memo if (!lib.isPointer(nativeObject)) { lib.toNative(nativeObject); if (!lib.isPointer(nativeObject)) { - throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, ErrorMessages.CANNOT_CONVERT_OBJECT_POINTER_TO_NATIVE); + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, ErrorMessages.CANNOT_CONVERT_OBJECT_POINTER_TO_NATIVE); } } try { @@ -716,7 +720,7 @@ public final Object execute(Node inliningTarget, Pointer ptr) { @Specialization static Object doObjectPointer(Node inliningTarget, @SuppressWarnings("unused") MemoryBlock memory, ObjectPointerStorage storage, int offset) { if (offset != 0) { - throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, ErrorMessages.CANNOT_APPLY_OFFSET_TO_AN_OBJECT_POINTER); + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, ErrorMessages.CANNOT_APPLY_OFFSET_TO_AN_OBJECT_POINTER); } return storage.pointer; } @@ -734,7 +738,7 @@ public final long execute(Node inliningTarget, Pointer ptr) { @Specialization @SuppressWarnings("unused") static long doObjectPointer(Node inliningTarget, MemoryBlock memory, ObjectPointerStorage storage, int offset) { - throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, ErrorMessages.CANNOT_CONVERT_OBJECT_POINTER_TO_NATIVE); + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, ErrorMessages.CANNOT_CONVERT_OBJECT_POINTER_TO_NATIVE); } } @@ -790,11 +794,36 @@ static Pointer doNativeVoidPtr(PythonNativeVoidPtr value) { return Pointer.nativeMemory(pointerObject); } - @Fallback - static Pointer doLong(Node inliningTarget, Object value, - @Cached CastToJavaUnsignedLongNode cast) { - long pointer = cast.execute(inliningTarget, value); - return Pointer.nativeMemory(pointer); + @Specialization + static Pointer doBool(Node inliningTarget, boolean value) { + return Pointer.nativeMemory(value ? 1 : 0); + } + + @Specialization + static Pointer doLong(Node inliningTarget, long value) { + return Pointer.nativeMemory(value); + } + + @Specialization + static Pointer doPInt(Node inliningTarget, PInt value) { + return Pointer.nativeMemory(value.longValue()); + } + + @Specialization + @TruffleBoundary + @InliningCutoff + static Pointer doGeneric(Node inliningTarget, Object value, + @CachedLibrary(limit = "1") InteropLibrary lib) { + if (lib.fitsInBigInteger(value)) { + BigInteger bi; + try { + bi = lib.asBigInteger(value); + return doLong(inliningTarget, bi.longValue()); + } catch (UnsupportedMessageException e) { + // fall through to error + } + } + throw PRaiseNode.raiseStatic(inliningTarget, OverflowError, ErrorMessages.CANNOT_BE_CONVERTED_TO_POINTER); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/FunctoolsModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/FunctoolsModuleBuiltins.java index 80fa1baef0..f8e6e90532 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/FunctoolsModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/FunctoolsModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -49,12 +49,14 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; @@ -65,7 +67,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -100,7 +102,7 @@ public void initialize(Python3Core core) { "\n" + // "cache_info_type: namedtuple class with the fields:\n" + // " hits misses currsize maxsize\n"); - core.lookupBuiltinModule(T_FUNCTOOLS).setModuleState(core.factory().createPythonObject(PythonObject)); + core.lookupBuiltinModule(T_FUNCTOOLS).setModuleState(PFactory.createPythonObject(core.getLanguage(), PythonObject, PythonObject.getInstanceShape(core.getLanguage()))); } // functools.reduce(function, iterable[, initializer]) @@ -118,19 +120,18 @@ public abstract static class ReduceNode extends PythonTernaryBuiltinNode { Object doReduce(VirtualFrame frame, Object function, Object sequence, Object initialIn, @Bind("this") Node inliningTarget, @Cached PyObjectGetIter getIter, - @Cached GetNextNode nextNode, + @Cached PyIterNextNode nextNode, @Cached CallNode callNode, @Cached InlinedConditionProfile initialNoValueProfile, - @Cached IsBuiltinObjectProfile stopIterProfile, @Cached IsBuiltinObjectProfile typeError, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object initial = initialNoValueProfile.profile(inliningTarget, PGuards.isNoValue(initialIn)) ? null : initialIn; Object seqIterator, result = initial; try { seqIterator = getIter.execute(frame, inliningTarget, sequence); } catch (PException pe) { pe.expectTypeError(inliningTarget, typeError); - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, S_ARG_N_MUST_SUPPORT_ITERATION, "reduce()", 2); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, S_ARG_N_MUST_SUPPORT_ITERATION, "reduce()", 2); } Object[] args = new Object[2]; @@ -139,27 +140,26 @@ Object doReduce(VirtualFrame frame, Object function, Object sequence, Object ini while (true) { Object op2; try { - op2 = nextNode.execute(frame, seqIterator); - if (result == null) { - result = op2; - } else { - // Update the args tuple in-place - args[0] = result; - args[1] = op2; - result = callNode.execute(frame, function, args); - } - if (CompilerDirectives.hasNextTier()) { - count++; - } - } catch (PException e) { - e.expectStopIteration(inliningTarget, stopIterProfile); + op2 = nextNode.execute(frame, inliningTarget, seqIterator); + } catch (IteratorExhausted e) { break; } + if (result == null) { + result = op2; + } else { + // Update the args tuple in-place + args[0] = result; + args[1] = op2; + result = callNode.execute(frame, function, args); + } + if (CompilerDirectives.hasNextTier()) { + count++; + } } reportLoopCount(this, count >= 0 ? count : Integer.MAX_VALUE); if (result == null) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, REDUCE_EMPTY_SEQ); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, REDUCE_EMPTY_SEQ); } return result; @@ -172,8 +172,8 @@ Object doReduce(VirtualFrame frame, Object function, Object sequence, Object ini public abstract static class CmpToKeyNode extends PythonUnaryBuiltinNode { @Specialization static Object doConvert(Object myCmp, - @Cached PythonObjectFactory factory) { - return factory.createKeyWrapper(myCmp); + @Bind PythonLanguage language) { + return PFactory.createKeyWrapper(language, myCmp); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/KeyWrapperBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/KeyWrapperBuiltins.java index 7dc439de6a..99a2b88ef6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/KeyWrapperBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/KeyWrapperBuiltins.java @@ -41,39 +41,44 @@ package com.oracle.graal.python.builtins.modules.functools; import static com.oracle.graal.python.nodes.ErrorMessages.OTHER_ARG_MUST_BE_KEY; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__; import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.HashNotImplemented; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare; import com.oracle.graal.python.lib.PyObjectIsTrueNode; +import com.oracle.graal.python.lib.PyObjectRichCompare; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.expression.BinaryComparisonNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; @CoreFunctions(extendClasses = PythonBuiltinClassType.PKeyWrapper) +@HashNotImplemented public final class KeyWrapperBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = KeyWrapperBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return KeyWrapperBuiltinsFactory.getFactories(); @@ -82,100 +87,37 @@ protected List> getNodeFa @Override public void initialize(Python3Core core) { super.initialize(core); - core.lookupType(PythonBuiltinClassType.PKeyWrapper).setAttribute(T___HASH__, PNone.NONE); } - abstract static class WrapperKeyCompareNode extends PythonBinaryBuiltinNode { - @Child private BinaryComparisonNode comparisonNode; - @Child private CallNode callNode; - - protected BinaryComparisonNode ensureComparisonNode() { - if (comparisonNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - comparisonNode = insert(createCmp()); - } - return comparisonNode; - } - - protected CallNode ensureCallNode() { - if (callNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - callNode = insert(CallNode.create()); - } - return callNode; - } - - BinaryComparisonNode createCmp() { - throw CompilerDirectives.shouldNotReachHere(); - } - + @Slot(value = SlotKind.tp_richcompare, isComplex = true) + @GenerateNodeFactory + abstract static class KeyWrapperRichCmpNode extends TpSlotRichCompare.RichCmpBuiltinNode { @Specialization - boolean doCompare(VirtualFrame frame, PKeyWrapper self, PKeyWrapper other, + boolean doCompare(VirtualFrame frame, PKeyWrapper self, PKeyWrapper other, RichCmpOp op, + @Bind("this") Node inliningTarget, + @Cached CallNode callNode, + @Cached PyObjectRichCompare richCompareNode, @Cached PyObjectIsTrueNode isTrueNode) { - final Object cmpResult = ensureCallNode().execute(frame, self.getCmp(), self.getObject(), other.getObject()); - return isTrueNode.execute(frame, ensureComparisonNode().executeObject(frame, cmpResult, 0)); + final Object cmpResult = callNode.execute(frame, self.getCmp(), self.getObject(), other.getObject()); + return isTrueNode.execute(frame, richCompareNode.execute(frame, inliningTarget, cmpResult, 0, op)); } @Fallback @SuppressWarnings("unused") - static boolean fallback(Object self, Object other, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, OTHER_ARG_MUST_BE_KEY); - } - } - - @Builtin(name = J___LE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class KWLeNode extends WrapperKeyCompareNode { - @Override - BinaryComparisonNode createCmp() { - return BinaryComparisonNode.LeNode.create(); - } - } - - @Builtin(name = J___LT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class KWLtNode extends WrapperKeyCompareNode { - @Override - BinaryComparisonNode createCmp() { - return BinaryComparisonNode.LtNode.create(); - } - } - - @Builtin(name = J___GE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class KWGeNode extends WrapperKeyCompareNode { - @Override - BinaryComparisonNode createCmp() { - return BinaryComparisonNode.GeNode.create(); - } - } - - @Builtin(name = J___GT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class KWGtNode extends WrapperKeyCompareNode { - @Override - BinaryComparisonNode createCmp() { - return BinaryComparisonNode.GtNode.create(); - } - } - - @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class KWEqNode extends WrapperKeyCompareNode { - @Override - BinaryComparisonNode createCmp() { - return BinaryComparisonNode.EqNode.create(); + static boolean fallback(Object self, Object other, RichCmpOp op, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, OTHER_ARG_MUST_BE_KEY); } } - @Builtin(name = J___CALL__, minNumOfPositionalArgs = 2, declaresExplicitSelf = true, parameterNames = {"$self", "obj"}) + @Slot(value = SlotKind.tp_call, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 2, parameterNames = {"$self", "obj"}) @GenerateNodeFactory public abstract static class KWCallNode extends PythonBinaryBuiltinNode { @Specialization static Object call(PKeyWrapper self, Object obj, - @Cached PythonObjectFactory factory) { - final PKeyWrapper keyWrapper = factory.createKeyWrapper(self.getCmp()); + @Bind PythonLanguage language) { + final PKeyWrapper keyWrapper = PFactory.createKeyWrapper(language, self.getCmp()); keyWrapper.setObject(obj); return keyWrapper; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/LruCacheWrapperBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/LruCacheWrapperBuiltins.java index 99a8b38fa2..9042a2bbe0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/LruCacheWrapperBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/LruCacheWrapperBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,19 +47,19 @@ import static com.oracle.graal.python.nodes.ErrorMessages.THE_FIRST_ARGUMENT_MUST_BE_CALLABLE; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___DICT__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___QUALNAME__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLEAR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___COPY__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___DEEPCOPY__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -71,6 +71,7 @@ import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.DescrGetBuiltinNode; import com.oracle.graal.python.lib.PyCallableCheckNode; import com.oracle.graal.python.lib.PyIndexCheckNode; @@ -82,7 +83,7 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode; +import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; @@ -93,7 +94,7 @@ import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; import com.oracle.graal.python.nodes.object.SetDictNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -115,22 +116,9 @@ protected List> getNodeFa return LruCacheWrapperBuiltinsFactory.getFactories(); } - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 5, takesVarArgs = true, takesVarKeywordArgs = true, // - constructsClass = PythonBuiltinClassType.PLruCacheWrapper, // - parameterNames = {"$cls", "user_function", "maxsize", "typed", "cache_info_type"}, // - doc = "Create a cached callable that wraps another function.\n" + // - "\n" + // - "user_function: the function being cached\n" + // - "\n" + // - "maxsize: 0 for no caching\n" + // - " None for unlimited cache size\n" + // - " n for a bounded cache\n" + // - "\n" + // - "typed: False cache f(3) and f(3.0) as identical calls\n" + // - " True cache f(3) and f(3.0) as distinct calls\n" + // - "\n" + // - "cache_info_type: namedtuple class with the fields:\n" + // - " hits misses currsize maxsize\n") + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "lru_cache", minNumOfPositionalArgs = 5, takesVarArgs = true, takesVarKeywordArgs = true, // + parameterNames = {"$cls", "user_function", "maxsize", "typed", "cache_info_type"}) @ArgumentClinic(name = "typed", conversion = ClinicConversion.Int) @GenerateNodeFactory protected abstract static class LruCacheNewNode extends PythonClinicBuiltinNode { @@ -147,11 +135,11 @@ static Object lruCacheNew(VirtualFrame frame, Object type, @Cached PyCallableCheckNode callableCheck, @Cached PyIndexCheckNode indexCheck, @Cached PyNumberAsSizeNode numberAsSize, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached PRaiseNode raiseNode) { if (!callableCheck.execute(inliningTarget, func)) { - throw raiseNode.get(inliningTarget).raise(TypeError, THE_FIRST_ARGUMENT_MUST_BE_CALLABLE); + throw raiseNode.raise(inliningTarget, TypeError, THE_FIRST_ARGUMENT_MUST_BE_CALLABLE); } /* select the caching function, and make/inc maxsize_O */ @@ -172,10 +160,11 @@ static Object lruCacheNew(VirtualFrame frame, Object type, wrapper = WrapperType.BOUNDED; } } else { - throw raiseNode.get(inliningTarget).raise(TypeError, MAXSIZE_SHOULD_BE_INTEGER_OR_NONE); + throw raiseNode.raise(inliningTarget, TypeError, MAXSIZE_SHOULD_BE_INTEGER_OR_NONE); } - LruCacheObject obj = factory.createLruCacheObject(type); + PythonContext context = PythonContext.get(inliningTarget); + LruCacheObject obj = PFactory.createLruCacheObject(context.getLanguage(inliningTarget), type, getInstanceShape.execute(type)); obj.root.prev = obj.root; obj.root.next = obj.root; @@ -187,7 +176,7 @@ static Object lruCacheNew(VirtualFrame frame, Object type, obj.misses = obj.hits = 0; obj.maxsize = maxsize; - obj.kwdMark = PythonContext.get(inliningTarget).lookupBuiltinModule(T_FUNCTOOLS).getModuleState(Object.class); + obj.kwdMark = context.lookupBuiltinModule(T_FUNCTOOLS).getModuleState(Object.class); obj.cacheInfoType = cache_info_type; // obj.dict = null; @@ -201,15 +190,9 @@ static Object lruCacheNew(VirtualFrame frame, Object type, public abstract static class CacheInfoNode extends PythonUnaryBuiltinNode { @Specialization static Object info(VirtualFrame frame, LruCacheObject self, - @Cached CallVarargsMethodNode callNode) { - if (self.maxsize == -1) { - return callNode.execute(frame, self.cacheInfoType, - new Object[]{self.hits, self.misses, PNone.NONE, self.cache.size()}, - PKeyword.EMPTY_KEYWORDS); - } - return callNode.execute(frame, self.cacheInfoType, - new Object[]{self.hits, self.misses, self.maxsize, self.cache.size()}, - PKeyword.EMPTY_KEYWORDS); + @Cached CallNode callNode) { + Object maxsize = self.maxsize == -1 ? PNone.NONE : self.maxsize; + return callNode.execute(frame, self.cacheInfoType, self.hits, self.misses, maxsize, self.cache.size()); } } @@ -255,8 +238,8 @@ static Object setDict(LruCacheObject self, PDict mapping, @Specialization(guards = {"!isNoValue(mapping)", "!isDict(mapping)"}) static Object setDict(@SuppressWarnings("unused") LruCacheObject self, Object mapping, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, mapping); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, mapping); } } @@ -271,14 +254,15 @@ Object reduce(VirtualFrame frame, LruCacheObject self, } } - @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_call, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory protected abstract static class PartialCallNode extends PythonVarargsBuiltinNode { // uncached_lru_cache_wrapper @Specialization(guards = "self.isUncached()") static Object uncachedLruCacheWrapper(VirtualFrame frame, LruCacheObject self, Object[] args, PKeyword[] kwds, - @Shared @Cached CallVarargsMethodNode callNode) { + @Shared @Cached CallNode callNode) { self.misses++; return callNode.execute(frame, self.func, args, kwds); } @@ -288,8 +272,7 @@ static Object lruCacheMakeKey(Object kwdMark, Object[] args, PKeyword[] kwds, in Node inliningTarget, GetClassNode getClassNode, PyUnicodeCheckExactNode unicodeCheckExact, - PyLongCheckExactNode longCheckExact, - PythonObjectFactory factory) { + PyLongCheckExactNode longCheckExact) { int kwdsSize = kwds.length; /* short path, key will match args anyway, which is a tuple */ if (typed == 0 && kwdsSize == 0) { @@ -303,7 +286,7 @@ static Object lruCacheMakeKey(Object kwdMark, Object[] args, PKeyword[] kwds, in } } - return factory.createTuple(args); + return PFactory.createTuple(PythonLanguage.get(inliningTarget), args); } int argsLen = args.length; int keySize = args.length; @@ -338,7 +321,7 @@ static Object lruCacheMakeKey(Object kwdMark, Object[] args, PKeyword[] kwds, in } } assert (keyPos == keySize); - return factory.createTuple(keyArray); + return PFactory.createTuple(PythonLanguage.get(inliningTarget), keyArray); } // infinite_lru_cache_wrapper @@ -348,7 +331,7 @@ static Object infiniteLruCacheWrapper(VirtualFrame frame, LruCacheObject self, O long hash, Object cachedItem, ObjectHashMap.PutNode setItem, - CallVarargsMethodNode callNode) { + CallNode callNode) { Object result = cachedItem; if (result != null) { self.hits++; @@ -422,7 +405,7 @@ static Object boundedLruCacheWrapper(VirtualFrame frame, Node inliningTarget, Lr ObjectHashMap.GetNode getItem, ObjectHashMap.PutNode setItem, ObjectHashMap.RemoveNode popItem, - CallVarargsMethodNode callNode) { + CallNode callNode) { if (cachedItem != null) { assert cachedItem instanceof LruListElemObject : "cachedItem should be an LruListElemObject"; LruListElemObject link = (LruListElemObject) cachedItem; @@ -523,7 +506,7 @@ static Object boundedLruCacheWrapper(VirtualFrame frame, Node inliningTarget, Lr @Specialization(guards = "!self.isUncached()") static Object cachedLruCacheWrapper(VirtualFrame frame, LruCacheObject self, Object[] args, PKeyword[] kwds, @Bind("this") Node inliningTarget, - @Shared @Cached CallVarargsMethodNode callNode, + @Shared @Cached CallNode callNode, @Cached PyObjectHashNode hashNode, @Cached ObjectHashMap.GetNode getItem, @Cached ObjectHashMap.PutNode setItem, @@ -531,10 +514,9 @@ static Object cachedLruCacheWrapper(VirtualFrame frame, LruCacheObject self, Obj @Cached PyUnicodeCheckExactNode unicodeCheckExact, @Cached PyLongCheckExactNode longCheckExact, @Cached ObjectHashMap.RemoveNode popItem, - @Cached InlinedConditionProfile profile, - @Cached PythonObjectFactory factory) { + @Cached InlinedConditionProfile profile) { Object key = lruCacheMakeKey(self.kwdMark, args, kwds, self.typed, - inliningTarget, getClassNode, unicodeCheckExact, longCheckExact, factory); + inliningTarget, getClassNode, unicodeCheckExact, longCheckExact); long hash = hashNode.execute(frame, inliningTarget, key); Object cached = getItem.execute(frame, inliningTarget, self.cache, key, hash); if (profile.profile(inliningTarget, self.isInfinite())) { @@ -582,12 +564,11 @@ abstract static class GetNode extends DescrGetBuiltinNode { @Specialization static Object getmethod(LruCacheObject self, Object obj, @SuppressWarnings("unused") Object type, @Bind("this") Node inliningTarget, - @Cached InlinedConditionProfile objIsNoneProfile, - @Cached PythonObjectFactory factory) { + @Cached InlinedConditionProfile objIsNoneProfile) { if (objIsNoneProfile.profile(inliningTarget, obj instanceof PNone)) { return self; } - return factory.createMethod(obj, self); + return PFactory.createMethod(PythonLanguage.get(inliningTarget), obj, self); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PPartial.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PPartial.java index 9dfdb02743..7cc36b701b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PPartial.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PPartial.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,6 +40,7 @@ */ package com.oracle.graal.python.builtins.modules.functools; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageCopy; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageLen; import com.oracle.graal.python.builtins.objects.common.SequenceNodes; @@ -47,7 +48,7 @@ import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; @@ -76,9 +77,9 @@ public Object[] getArgs() { return args; } - public PTuple getArgsTuple(PythonObjectFactory factory) { + public PTuple getArgsTuple(PythonLanguage language) { if (argsTuple == null) { - this.argsTuple = factory.createTuple(args); + this.argsTuple = PFactory.createTuple(language, args); } return argsTuple; } @@ -92,16 +93,16 @@ public PDict getKw() { return kw; } - public PDict getOrCreateKw(PythonObjectFactory factory) { + public PDict getOrCreateKw(PythonLanguage language) { if (kw == null) { - kw = factory.createDict(); + kw = PFactory.createDict(language); } return kw; } - public PDict getKwCopy(Node inliningTarget, PythonObjectFactory factory, HashingStorageCopy copyNode) { + public PDict getKwCopy(Node inliningTarget, PythonLanguage language, HashingStorageCopy copyNode) { assert kw != null; - return factory.createDict(copyNode.execute(inliningTarget, kw.getDictStorage())); + return PFactory.createDict(language, copyNode.execute(inliningTarget, kw.getDictStorage())); } public boolean hasKw(Node inliningTarget, HashingStorageLen lenNode) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java index ec3601c9e1..88ae5ff4ab 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,11 +45,8 @@ import static com.oracle.graal.python.nodes.ErrorMessages.S_ARG_MUST_BE_CALLABLE; import static com.oracle.graal.python.nodes.ErrorMessages.TYPE_S_TAKES_AT_LEAST_ONE_ARGUMENT; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___DICT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__; import static com.oracle.graal.python.nodes.StringLiterals.T_COMMA_SPACE; import static com.oracle.graal.python.nodes.StringLiterals.T_ELLIPSIS; @@ -60,6 +57,10 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -80,6 +81,7 @@ import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.object.ObjectNodes; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyCallableCheckNode; import com.oracle.graal.python.lib.PyDictCheckExactNode; @@ -92,7 +94,7 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode; import com.oracle.graal.python.nodes.builtins.TupleNodes; -import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode; +import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; @@ -104,7 +106,7 @@ import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; import com.oracle.graal.python.nodes.object.SetDictNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -141,16 +143,16 @@ public static Object[] getNewPartialArgs(PPartial partial, Object[] args, Node i return newArgs; } + public static final TpSlots SLOTS = PartialBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return PartialBuiltinsFactory.getFactories(); } // functools.partial(func, /, *args, **keywords) - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, varArgsMarker = true, takesVarArgs = true, // - takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PPartial, // - doc = "partial(func, *args, **keywords) - new function with partial application\n" + // - "of the given arguments and keywords.\n") + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "partial", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory public abstract static class PartialNewNode extends PythonBuiltinNode { protected boolean isPartialWithoutDict(Node inliningTarget, GetDictIfExistsNode getDict, Object[] args, HashingStorageLen lenNode, boolean withKwDict) { @@ -176,19 +178,20 @@ static Object createFromPartialWoDictWoKw(Object cls, Object[] args, PKeyword[] @Exclusive @Cached InlinedConditionProfile hasArgsProfile, @Exclusive @Cached InlinedConditionProfile hasKeywordsProfile, @Exclusive @SuppressWarnings("unused") @Cached HashingStorageLen lenNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { assert args[0] instanceof PPartial; final PPartial function = (PPartial) args[0]; Object[] funcArgs = getNewPartialArgs(function, args, inliningTarget, hasArgsProfile, 1); PDict funcKwDict; if (hasKeywordsProfile.profile(inliningTarget, keywords.length > 0)) { - funcKwDict = factory.createDict(keywords); + funcKwDict = PFactory.createDict(language, keywords); } else { - funcKwDict = factory.createDict(); + funcKwDict = PFactory.createDict(language); } - return factory.createPartial(cls, function.getFn(), funcArgs, funcKwDict); + return PFactory.createPartial(language, cls, getInstanceShape.execute(cls), function.getFn(), funcArgs, funcKwDict); } @Specialization(guards = {"atLeastOneArg(args)", "isPartialWithoutDict(inliningTarget, getDict, args, lenNode, true)", "!withKeywords(keywords)"}, limit = "1") @@ -198,11 +201,12 @@ static Object createFromPartialWoDictWKw(Object cls, Object[] args, @SuppressWar @Exclusive @Cached InlinedConditionProfile hasArgsProfile, @Exclusive @SuppressWarnings("unused") @Cached HashingStorageLen lenNode, @Exclusive @Cached HashingStorageCopy copyNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) { assert args[0] instanceof PPartial; final PPartial function = (PPartial) args[0]; Object[] funcArgs = getNewPartialArgs(function, args, inliningTarget, hasArgsProfile, 1); - return factory.createPartial(cls, function.getFn(), funcArgs, function.getKwCopy(inliningTarget, factory, copyNode)); + return PFactory.createPartial(language, cls, getInstanceShape.execute(cls), function.getFn(), funcArgs, function.getKwCopy(inliningTarget, language, copyNode)); } @Specialization(guards = {"atLeastOneArg(args)", "isPartialWithoutDict(inliningTarget, getDict, args, lenNode, true)", "withKeywords(keywords)"}, limit = "1") @@ -214,16 +218,17 @@ static Object createFromPartialWoDictWKwKw(VirtualFrame frame, Object cls, Objec @Exclusive @SuppressWarnings("unused") @Cached HashingStorageLen lenNode, @Exclusive @Cached HashingStorageCopy copyHashingStorageNode, @Cached HashingStorageAddAllToOther addAllToOtherNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) { assert args[0] instanceof PPartial; final PPartial function = (PPartial) args[0]; Object[] funcArgs = getNewPartialArgs(function, args, inliningTarget, hasArgsProfile, 1); HashingStorage storage = copyHashingStorageNode.execute(inliningTarget, function.getKw().getDictStorage()); - PDict result = factory.createDict(storage); + PDict result = PFactory.createDict(language, storage); addAllToOtherNode.execute(frame, inliningTarget, initNode.execute(frame, PNone.NO_VALUE, keywords), result); - return factory.createPartial(cls, function.getFn(), funcArgs, result); + return PFactory.createPartial(language, cls, getInstanceShape.execute(cls), function.getFn(), funcArgs, result); } @Specialization(guards = {"atLeastOneArg(args)", "!isPartialWithoutDict(getDict, args)"}, limit = "1") @@ -232,28 +237,29 @@ static Object createGeneric(Object cls, Object[] args, PKeyword[] keywords, @SuppressWarnings("unused") @Exclusive @Cached GetDictIfExistsNode getDict, @Exclusive @Cached InlinedConditionProfile hasKeywordsProfile, @Cached PyCallableCheckNode callableCheckNode, - @Shared @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached PRaiseNode raiseNode) { Object function = args[0]; if (!callableCheckNode.execute(inliningTarget, function)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, S_ARG_MUST_BE_CALLABLE, "the first"); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, S_ARG_MUST_BE_CALLABLE, "the first"); } final Object[] funcArgs = PythonUtils.arrayCopyOfRange(args, 1, args.length); PDict funcKwDict; if (hasKeywordsProfile.profile(inliningTarget, keywords.length > 0)) { - funcKwDict = factory.createDict(keywords); + funcKwDict = PFactory.createDict(language, keywords); } else { - funcKwDict = factory.createDict(); + funcKwDict = PFactory.createDict(language); } - return factory.createPartial(cls, function, funcArgs, funcKwDict); + return PFactory.createPartial(language, cls, getInstanceShape.execute(cls), function, funcArgs, funcKwDict); } @Specialization(guards = "!atLeastOneArg(args)") @SuppressWarnings("unused") static Object noCallable(Object cls, Object[] args, PKeyword[] keywords, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, TYPE_S_TAKES_AT_LEAST_ONE_ARGUMENT, "partial"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, TYPE_S_TAKES_AT_LEAST_ONE_ARGUMENT, "partial"); } } @@ -271,8 +277,8 @@ static Object doGet(PPartial self) { public abstract static class PartialArgsNode extends PythonUnaryBuiltinNode { @Specialization static Object doGet(PPartial self, - @Cached PythonObjectFactory factory) { - return self.getArgsTuple(factory); + @Bind PythonLanguage language) { + return self.getArgsTuple(language); } } @@ -297,8 +303,8 @@ static Object setDict(PPartial self, PDict mapping, @Specialization(guards = {"!isNoValue(mapping)", "!isDict(mapping)"}) static Object setDict(@SuppressWarnings("unused") PPartial self, Object mapping, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, mapping); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, mapping); } } @@ -307,8 +313,8 @@ static Object setDict(@SuppressWarnings("unused") PPartial self, Object mapping, public abstract static class PartialKeywordsNode extends PythonUnaryBuiltinNode { @Specialization static Object doGet(PPartial self, - @Cached PythonObjectFactory factory) { - return self.getOrCreateKw(factory); + @Bind PythonLanguage language) { + return self.getOrCreateKw(language); } } @@ -321,7 +327,7 @@ static Object reduce(PPartial self, @Cached GetClassNode getClassNode, @Cached GetDictIfExistsNode getDictIfExistsNode, @Cached GetOrCreateDictNode getOrCreateDictNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { final PDict dict; if (self.getShape().getPropertyCount() > 0) { dict = getOrCreateDictNode.execute(inliningTarget, self); @@ -329,9 +335,9 @@ static Object reduce(PPartial self, dict = getDictIfExistsNode.execute(self); } final Object type = getClassNode.execute(inliningTarget, self); - final PTuple fnTuple = factory.createTuple(new Object[]{self.getFn()}); - final PTuple argsTuple = factory.createTuple(new Object[]{self.getFn(), self.getArgsTuple(factory), self.getKw(), (dict != null) ? dict : PNone.NONE}); - return factory.createTuple(new Object[]{type, fnTuple, argsTuple}); + final PTuple fnTuple = PFactory.createTuple(language, new Object[]{self.getFn()}); + final PTuple argsTuple = PFactory.createTuple(language, new Object[]{self.getFn(), self.getArgsTuple(language), self.getKw(), (dict != null) ? dict : PNone.NONE}); + return PFactory.createTuple(language, new Object[]{type, fnTuple, argsTuple}); } } @@ -352,10 +358,10 @@ static Object setState(VirtualFrame frame, PPartial self, PTuple state, @Cached PyTupleGetItem getItemNode, @Cached TupleNodes.ConstructTupleNode constructTupleNode, @Cached HashingStorageCopy copyStorageNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { if (state.getSequenceStorage().length() != 4) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, INVALID_PARTIAL_STATE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, INVALID_PARTIAL_STATE); } final Object function = getItemNode.execute(inliningTarget, state, 0); @@ -366,7 +372,7 @@ static Object setState(VirtualFrame frame, PPartial self, PTuple state, if (!callableCheckNode.execute(inliningTarget, function) || !PGuards.isPTuple(fnArgs) || (fnKwargs != PNone.NONE && !PGuards.isDict(fnKwargs))) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, INVALID_PARTIAL_STATE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, INVALID_PARTIAL_STATE); } self.setFn(function); @@ -381,9 +387,9 @@ static Object setState(VirtualFrame frame, PPartial self, PTuple state, final PDict fnKwargsDict; if (fnKwargs == PNone.NONE) { - fnKwargsDict = factory.createDict(); + fnKwargsDict = PFactory.createDict(language); } else if (!dictCheckExactNode.execute(inliningTarget, fnKwargs)) { - fnKwargsDict = factory.createDict(copyStorageNode.execute(inliningTarget, ((PDict) fnKwargs).getDictStorage())); + fnKwargsDict = PFactory.createDict(language, copyStorageNode.execute(inliningTarget, ((PDict) fnKwargs).getDictStorage())); } else { fnKwargsDict = (PDict) fnKwargs; } @@ -402,12 +408,13 @@ static Object setState(VirtualFrame frame, PPartial self, PTuple state, @Fallback @SuppressWarnings("unused") static Object fallback(Object self, Object state, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, INVALID_PARTIAL_STATE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, INVALID_PARTIAL_STATE); } } - @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_call, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory protected abstract static class PartialCallNode extends PythonVarargsBuiltinNode { private static int indexOf(PKeyword[] keywords, PKeyword kw) { @@ -427,7 +434,7 @@ protected boolean withKeywords(PKeyword[] keywords) { static Object callWoDict(VirtualFrame frame, PPartial self, Object[] args, PKeyword[] keywords, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile hasArgsProfile, - @Shared @Cached CallVarargsMethodNode callNode, + @Shared @Cached CallNode callNode, @SuppressWarnings("unused") @Shared @Cached HashingStorageLen lenNode) { Object[] callArgs = getNewPartialArgs(self, args, inliningTarget, hasArgsProfile); return callNode.execute(frame, self.getFn(), callArgs, keywords); @@ -438,7 +445,7 @@ static Object callWDictWoKw(VirtualFrame frame, PPartial self, Object[] args, @S @Bind("this") Node inliningTarget, @Shared @Cached ExpandKeywordStarargsNode starargsNode, @Shared @Cached InlinedConditionProfile hasArgsProfile, - @Shared @Cached CallVarargsMethodNode callNode, + @Shared @Cached CallNode callNode, @SuppressWarnings("unused") @Shared @Cached HashingStorageLen lenNode) { Object[] callArgs = getNewPartialArgs(self, args, inliningTarget, hasArgsProfile); return callNode.execute(frame, self.getFn(), callArgs, starargsNode.execute(inliningTarget, self.getKw())); @@ -449,7 +456,7 @@ static Object callWDictWKw(VirtualFrame frame, PPartial self, Object[] args, PKe @Bind("this") Node inliningTarget, @Shared @Cached ExpandKeywordStarargsNode starargsNode, @Shared @Cached InlinedConditionProfile hasArgsProfile, - @Shared @Cached CallVarargsMethodNode callNode, + @Shared @Cached CallNode callNode, @SuppressWarnings("unused") @Shared @Cached HashingStorageLen lenNode) { Object[] callArgs = getNewPartialArgs(self, args, inliningTarget, hasArgsProfile); @@ -473,7 +480,7 @@ static Object callWDictWKw(VirtualFrame frame, PPartial self, Object[] args, PKe } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class PartialReprNode extends PythonUnaryBuiltinNode { private static void reprArgs(VirtualFrame frame, Node inliningTarget, PPartial partial, TruffleStringBuilder sb, PyObjectReprAsTruffleStringNode reprNode, @@ -544,8 +551,8 @@ public static TruffleString repr(VirtualFrame frame, PPartial partial, public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode { @Specialization static Object classGetItem(Object cls, Object key, - @Cached PythonObjectFactory factory) { - return factory.createGenericAlias(cls, key); + @Bind PythonLanguage language) { + return PFactory.createGenericAlias(language, cls, key); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Blake2ModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Blake2ModuleBuiltins.java index 7cef0d745d..019e8a53a2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Blake2ModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Blake2ModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,33 +40,14 @@ */ package com.oracle.graal.python.builtins.modules.hashlib; +import java.util.Collections; import java.util.List; -import com.oracle.graal.python.annotations.ArgumentClinic; -import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.modules.hashlib.Blake2ModuleBuiltinsClinicProviders.BlakeNodeClinicProviderGen; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; @CoreFunctions(defineModule = "_blake2") public final class Blake2ModuleBuiltins extends PythonBuiltins { @@ -82,7 +63,7 @@ public final class Blake2ModuleBuiltins extends PythonBuiltins { @Override protected List> getNodeFactories() { - return Blake2ModuleBuiltinsFactory.getFactories(); + return Collections.emptyList(); } @Override @@ -98,74 +79,4 @@ public void initialize(Python3Core core) { super.initialize(core); } - - @Builtin(name = "blake2b", declaresExplicitSelf = true, minNumOfPositionalArgs = 1, parameterNames = {"$cls", "data"}, keywordOnlyNames = {"digest_size", "key", "salt", "person", "fanout", - "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", - "usedforsecurity"}, constructsClass = PythonBuiltinClassType.Blake2bType) - @Builtin(name = "blake2s", declaresExplicitSelf = true, minNumOfPositionalArgs = 1, parameterNames = {"$cls", "data"}, keywordOnlyNames = {"digest_size", "key", "salt", "person", "fanout", - "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", - "usedforsecurity"}, constructsClass = PythonBuiltinClassType.Blake2sType) - @ArgumentClinic(name = "digest_size", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0") - @ArgumentClinic(name = "key", conversion = ArgumentClinic.ClinicConversion.ReadableBuffer, defaultValue = "PNone.NONE") - @ArgumentClinic(name = "salt", conversion = ArgumentClinic.ClinicConversion.ReadableBuffer, defaultValue = "PNone.NONE") - @ArgumentClinic(name = "person", conversion = ArgumentClinic.ClinicConversion.ReadableBuffer, defaultValue = "PNone.NONE") - @ArgumentClinic(name = "fanout", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "1") - @ArgumentClinic(name = "depth", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "1") - @ArgumentClinic(name = "leaf_size", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0") - @ArgumentClinic(name = "node_offset", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0") - @ArgumentClinic(name = "node_depth", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0") - @ArgumentClinic(name = "inner_size", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0") - @ArgumentClinic(name = "last_node", conversion = ArgumentClinic.ClinicConversion.Boolean, defaultValue = "false") - @ArgumentClinic(name = "usedforsecurity", conversion = ArgumentClinic.ClinicConversion.Boolean, defaultValue = "true") - @GenerateNodeFactory - abstract static class BlakeNode extends PythonClinicBuiltinNode { - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return BlakeNodeClinicProviderGen.INSTANCE; - } - - @Specialization - static Object newDigest(VirtualFrame frame, Object type, Object data, int digestSize, - PNone key, PNone salt, PNone person, int fanout, int depth, int leafSize, int nodeOffset, int nodeDepth, int innerSize, boolean lastNode, boolean usedforsecurity, - @Bind("this") Node inliningTarget, - @Cached HashlibModuleBuiltins.CreateDigestNode createNode, - @Cached PRaiseNode.Lazy raiseNode) { - if (fanout != 1 || depth != 1 || leafSize != 0 || nodeOffset != 0 || nodeDepth != 0 || innerSize != 0 || lastNode) { - throw fail(frame, type, data, digestSize, key, salt, person, fanout, depth, leafSize, nodeOffset, nodeDepth, innerSize, lastNode, usedforsecurity, raiseNode.get(inliningTarget)); - } - PythonBuiltinClassType resultType = null; - if (type instanceof PythonBuiltinClass builtinType) { - resultType = builtinType.getType(); - } else if (type instanceof PythonBuiltinClassType enumType) { - resultType = enumType; - } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.WRONG_TYPE); - } - String javaName; - String pythonName; - int javaDigestSize; - if (resultType == PythonBuiltinClassType.Blake2bType) { - javaName = "BLAKE2B-%d"; - pythonName = "blake2b"; - javaDigestSize = digestSize == 0 ? 512 : digestSize; - } else if (resultType == PythonBuiltinClassType.Blake2sType) { - javaName = "BLAKE2S-%d"; - pythonName = "blake2s"; - javaDigestSize = digestSize == 0 ? 256 : digestSize; - } else { - throw CompilerDirectives.shouldNotReachHere(); - } - javaName = PythonUtils.formatJString(javaName, javaDigestSize); - return createNode.execute(frame, inliningTarget, resultType, pythonName, javaName, data); - } - - @SuppressWarnings("unused") - @Fallback - static PException fail(VirtualFrame frame, Object type, Object data, Object digestSize, - Object key, Object salt, Object person, Object fanout, Object depth, Object leafSize, Object nodeOffset, Object nodeDepth, Object innerSize, Object lastNode, - Object usedforsecurity, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.ValueError, ErrorMessages.ONLY_DIGEST_SIZE_BLAKE_ARGUMENT); - } - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Blake2bObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Blake2bObjectBuiltins.java index 4dda12bda0..bc5de92f4a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Blake2bObjectBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Blake2bObjectBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,15 +43,39 @@ import java.util.ArrayList; import java.util.List; +import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; +import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.graal.python.util.PythonUtils; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; -@CoreFunctions(extendClasses = {PythonBuiltinClassType.Blake2bType}) +@CoreFunctions(extendClasses = {PythonBuiltinClassType.Blake2bType, PythonBuiltinClassType.Blake2sType}) public final class Blake2bObjectBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = Blake2bObjectBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return new ArrayList<>(); @@ -63,6 +87,77 @@ public void initialize(Python3Core core) { addBuiltinConstant("PERSON_SIZE", Blake2ModuleBuiltins.BLAKE2B_PERSONALBYTES); addBuiltinConstant("MAX_KEY_SIZE", Blake2ModuleBuiltins.BLAKE2B_KEYBYTES); addBuiltinConstant("MAX_DIGEST_SIZE", Blake2ModuleBuiltins.BLAKE2B_OUTBYTES); + addBuiltinConstant("SALT_SIZE", Blake2ModuleBuiltins.BLAKE2S_SALTBYTES); + addBuiltinConstant("PERSON_SIZE", Blake2ModuleBuiltins.BLAKE2S_PERSONALBYTES); + addBuiltinConstant("MAX_KEY_SIZE", Blake2ModuleBuiltins.BLAKE2S_KEYBYTES); + addBuiltinConstant("MAX_DIGEST_SIZE", Blake2ModuleBuiltins.BLAKE2S_OUTBYTES); super.initialize(core); } + + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "blake2b", minNumOfPositionalArgs = 1, parameterNames = {"$cls", "data"}, keywordOnlyNames = {"digest_size", "key", "salt", "person", "fanout", + "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", "usedforsecurity"}) + @ArgumentClinic(name = "digest_size", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0") + @ArgumentClinic(name = "key", conversion = ArgumentClinic.ClinicConversion.ReadableBuffer, defaultValue = "PNone.NONE") + @ArgumentClinic(name = "salt", conversion = ArgumentClinic.ClinicConversion.ReadableBuffer, defaultValue = "PNone.NONE") + @ArgumentClinic(name = "person", conversion = ArgumentClinic.ClinicConversion.ReadableBuffer, defaultValue = "PNone.NONE") + @ArgumentClinic(name = "fanout", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "1") + @ArgumentClinic(name = "depth", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "1") + @ArgumentClinic(name = "leaf_size", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0") + @ArgumentClinic(name = "node_offset", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0") + @ArgumentClinic(name = "node_depth", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0") + @ArgumentClinic(name = "inner_size", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0") + @ArgumentClinic(name = "last_node", conversion = ArgumentClinic.ClinicConversion.Boolean, defaultValue = "false") + @ArgumentClinic(name = "usedforsecurity", conversion = ArgumentClinic.ClinicConversion.Boolean, defaultValue = "true") + @GenerateNodeFactory + abstract static class BlakeNode extends PythonClinicBuiltinNode { + @Override + protected ArgumentClinicProvider getArgumentClinic() { + return Blake2bObjectBuiltinsClinicProviders.BlakeNodeClinicProviderGen.INSTANCE; + } + + @Specialization + static Object newDigest(VirtualFrame frame, Object type, Object data, int digestSize, + PNone key, PNone salt, PNone person, int fanout, int depth, int leafSize, int nodeOffset, int nodeDepth, int innerSize, boolean lastNode, boolean usedforsecurity, + @Bind("this") Node inliningTarget, + @Cached HashlibModuleBuiltins.CreateDigestNode createNode, + @Cached PRaiseNode raiseNode) { + if (fanout != 1 || depth != 1 || leafSize != 0 || nodeOffset != 0 || nodeDepth != 0 || innerSize != 0 || lastNode) { + throw fail(frame, type, data, digestSize, key, salt, person, fanout, depth, leafSize, nodeOffset, nodeDepth, innerSize, lastNode, usedforsecurity, raiseNode); + } + PythonBuiltinClassType resultType = null; + if (type instanceof PythonBuiltinClass builtinType) { + resultType = builtinType.getType(); + } else if (type instanceof PythonBuiltinClassType enumType) { + resultType = enumType; + } else { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.WRONG_TYPE); + } + String javaName; + String pythonName; + int javaDigestSize; + if (resultType == PythonBuiltinClassType.Blake2bType) { + javaName = "BLAKE2B-%d"; + pythonName = "blake2b"; + javaDigestSize = digestSize == 0 ? 512 : digestSize; + } else if (resultType == PythonBuiltinClassType.Blake2sType) { + javaName = "BLAKE2S-%d"; + pythonName = "blake2s"; + javaDigestSize = digestSize == 0 ? 256 : digestSize; + } else { + throw CompilerDirectives.shouldNotReachHere(); + } + javaName = PythonUtils.formatJString(javaName, javaDigestSize); + return createNode.execute(frame, inliningTarget, resultType, pythonName, javaName, data); + } + + @SuppressWarnings("unused") + @Fallback + static PException fail(VirtualFrame frame, Object type, Object data, Object digestSize, + Object key, Object salt, Object person, Object fanout, Object depth, Object leafSize, Object nodeOffset, Object nodeDepth, Object innerSize, Object lastNode, + Object usedforsecurity, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.ONLY_DIGEST_SIZE_BLAKE_ARGUMENT); + } + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObject.java index 38f3faef1e..180a253237 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,9 +44,10 @@ import javax.crypto.Mac; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.object.Shape; @@ -199,7 +200,7 @@ private PythonBuiltinClassType determineMainDigestType() { */ abstract void update(byte[] data, int length); - abstract DigestObject copy(PythonObjectFactory factory) throws CloneNotSupportedException; + abstract DigestObject copy() throws CloneNotSupportedException; abstract int getDigestLength(); @@ -263,8 +264,8 @@ private static final class MessageDigestObject extends DigestObjectBase { @Override @TruffleBoundary - DigestObject copy(PythonObjectFactory factory) throws CloneNotSupportedException { - return factory.createDigestObject(getType(), getAlgorithm(), digest.clone()); + DigestObject copy() throws CloneNotSupportedException { + return PFactory.createDigestObject(PythonLanguage.get(null), getType(), getAlgorithm(), digest.clone()); } @Override @@ -302,8 +303,8 @@ private static final class MacDigestObject extends DigestObjectBase { @Override @TruffleBoundary - DigestObject copy(PythonObjectFactory factory) throws CloneNotSupportedException { - return factory.createDigestObject(getType(), getAlgorithm(), mac.clone()); + DigestObject copy() throws CloneNotSupportedException { + return PFactory.createDigestObject(PythonLanguage.get(null), getType(), getAlgorithm(), mac.clone()); } @Override diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObjectBuiltins.java index 80ed174aa8..7cb16c038e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObjectBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObjectBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,6 +42,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -59,7 +60,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.runtime.IndirectCallData; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -89,12 +90,11 @@ abstract static class CopyNode extends PythonUnaryBuiltinNode { @Specialization static DigestObject copy(DigestObject self, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { - return self.copy(factory); + return self.copy(); } catch (CloneNotSupportedException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError); } } } @@ -104,8 +104,8 @@ static DigestObject copy(DigestObject self, abstract static class DigestNode extends PythonUnaryBuiltinNode { @Specialization static PBytes digest(DigestObject self, - @Cached PythonObjectFactory factory) { - return factory.createBytes(self.digest()); + @Bind PythonLanguage language) { + return PFactory.createBytes(language, self.digest()); } } @@ -135,9 +135,9 @@ static PNone update(VirtualFrame frame, DigestObject self, Object buffer, @Bind("this") Node inliningTarget, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (self.wasReset()) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.UPDATING_FINALIZED_DIGEST_IS_NOT_SUPPORTED); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.UPDATING_FINALIZED_DIGEST_IS_NOT_SUPPORTED); } try { self.update(bufferLib.getInternalOrCopiedByteArray(buffer), bufferLib.getBufferLength(buffer)); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashObjectBuiltins.java index f957622dfb..379ab1561c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashObjectBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashObjectBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,14 +42,15 @@ import java.util.List; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; import com.oracle.graal.python.builtins.objects.object.ObjectNodes.GetFullyQualifiedClassNameNode; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; -import com.oracle.graal.python.nodes.SpecialMethodNames; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.truffle.api.dsl.Bind; @@ -63,12 +64,15 @@ @CoreFunctions(extendClasses = {PythonBuiltinClassType.HashlibHash, PythonBuiltinClassType.HashlibHmac}) public final class HashObjectBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = HashObjectBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return HashObjectBuiltinsFactory.getFactories(); } - @Builtin(name = SpecialMethodNames.J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java index 0ff93cf187..473590e5d6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,6 +45,10 @@ import static com.oracle.graal.python.nodes.BuiltinNames.J_SHA3; import static com.oracle.graal.python.nodes.BuiltinNames.T_HASHLIB; import static com.oracle.graal.python.nodes.BuiltinNames.T_SHA3; +import static com.oracle.graal.python.nodes.ErrorMessages.ITERATION_VALUE_IS_TOO_GREAT; +import static com.oracle.graal.python.nodes.ErrorMessages.ITERATION_VALUE_MUST_BE_GREATER_THAN_ZERO; +import static com.oracle.graal.python.nodes.ErrorMessages.KEY_LENGTH_MUST_BE_GREATER_THAN_ZERO; +import static com.oracle.graal.python.nodes.ErrorMessages.UNSUPPORTED_HASH_TYPE; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; @@ -60,6 +64,13 @@ import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; +import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.jcajce.provider.util.DigestFactory; + +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -67,6 +78,7 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.modules.hashlib.HashlibModuleBuiltinsClinicProviders.NewNodeClinicProviderGen; +import com.oracle.graal.python.builtins.modules.hashlib.HashlibModuleBuiltinsClinicProviders.Pbkdf2HmacNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; @@ -74,7 +86,9 @@ import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.ssl.CertUtils; +import com.oracle.graal.python.lib.PyLongAsLongNode; import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromPythonObjectNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; @@ -87,7 +101,8 @@ import com.oracle.graal.python.nodes.util.CastToJavaStringNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.IndirectCallData; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -102,6 +117,7 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleString; import com.oracle.truffle.api.strings.TruffleString.CodeRange; @@ -156,12 +172,13 @@ protected List> getNodeFa public void initialize(Python3Core core) { EconomicMapStorage algos = EconomicMapStorage.create(DIGEST_ALGORITHMS.length); for (var digest : DIGEST_ALGORITHMS) { - algos.putUncachedWithJavaEq(digest, PNone.NONE); + algos.putUncached(digest, PNone.NONE); } - addBuiltinConstant("openssl_md_meth_names", core.factory().createFrozenSet(algos)); + PythonLanguage language = core.getLanguage(); + addBuiltinConstant("openssl_md_meth_names", PFactory.createFrozenSet(language, algos)); EconomicMapStorage storage = EconomicMapStorage.create(); - addBuiltinConstant(J_CONSTRUCTORS, core.factory().createMappingproxy(core.factory().createDict(storage))); + addBuiltinConstant(J_CONSTRUCTORS, PFactory.createMappingproxy(language, PFactory.createDict(language, storage))); core.lookupBuiltinModule(T_HASHLIB).setModuleState(storage); super.initialize(core); } @@ -199,13 +216,13 @@ static Object cmpStrings(Object a, Object b, @Cached TruffleString.GetCodeRangeNode getCodeRangeNode, @Cached CastToTruffleStringNode castA, @Cached CastToTruffleStringNode castB, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { TruffleString tsA = castA.execute(inliningTarget, a); TruffleString tsB = castB.execute(inliningTarget, b); CodeRange crA = getCodeRangeNode.execute(tsA, TS_ENCODING); CodeRange crB = getCodeRangeNode.execute(tsB, TS_ENCODING); if (!(crA.isSubsetOf(CodeRange.ASCII) && crB.isSubsetOf(CodeRange.ASCII))) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.COMPARING_STRINGS_WITH_NON_ASCII); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.COMPARING_STRINGS_WITH_NON_ASCII); } byte[] bytesA = getByteArrayNode.execute(tsA, TS_ENCODING); byte[] bytesB = getByteArrayNode.execute(castB.execute(inliningTarget, b), TS_ENCODING); @@ -218,7 +235,7 @@ static boolean cmpBuffers(VirtualFrame frame, Object a, Object b, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, @CachedLibrary(limit = "1") PythonBufferAccessLibrary accessLib, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (acquireLib.hasBuffer(a) && acquireLib.hasBuffer(b)) { Object bufferA = acquireLib.acquireReadonly(a, frame, indirectCallData); try { @@ -234,7 +251,7 @@ static boolean cmpBuffers(VirtualFrame frame, Object a, Object b, accessLib.release(bufferA, frame, indirectCallData); } } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_OR_COMBINATION_OF_TYPES, a, b); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_OR_COMBINATION_OF_TYPES, a, b); } } @@ -252,10 +269,10 @@ static Object hmacDigest(VirtualFrame frame, PythonModule self, Object key, Obje @Bind("this") Node inliningTarget, @Cached HmacNewNode newNode, @Cached DigestObjectBuiltins.DigestNode digestNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (msg instanceof PNone) { // hmac_digest is a bit more strict - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, msg); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, msg); } Object hmacObject = newNode.execute(frame, self, key, msg, digest); return digestNode.execute(frame, hmacObject); @@ -270,8 +287,8 @@ abstract static class HmacNewNode extends PythonQuaternaryBuiltinNode { @SuppressWarnings("unused") @Specialization static Object hmacNewError(PythonModule self, Object key, Object msg, PNone digest, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.MISSING_D_REQUIRED_S_ARGUMENT_S_POS, "hmac_new", "digestmod", 3); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.MISSING_D_REQUIRED_S_ARGUMENT_S_POS, "hmac_new", "digestmod", 3); } @Specialization(guards = "!isString(digestmod)") @@ -283,16 +300,15 @@ static Object hmacNewFromFunction(VirtualFrame frame, PythonModule self, Object @Shared("concatStr") @Cached TruffleString.ConcatNode concatStr, @Shared("acquireLib") @CachedLibrary(limit = "2") PythonBufferAcquireLibrary acquireLib, @Shared("bufferLib") @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { // cast guaranteed in our initialize EconomicMapStorage constructors = self.getModuleState(EconomicMapStorage.class); Object name = getItemNode.execute(frame, inliningTarget, constructors, digestmod); if (name != null) { assert name instanceof TruffleString; // guaranteed in our initialize - return hmacNew(self, key, msg, name, inliningTarget, castStr, castJStr, concatStr, acquireLib, bufferLib, factory, raiseNode); + return hmacNew(self, key, msg, name, inliningTarget, castStr, castJStr, concatStr, acquireLib, bufferLib, raiseNode); } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.UnsupportedDigestmodError); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.UnsupportedDigestmodError); } } @@ -304,12 +320,11 @@ static Object hmacNew(@SuppressWarnings("unused") PythonModule self, Object keyO @Shared("concatStr") @Cached TruffleString.ConcatNode concatStr, @Shared("acquireLib") @CachedLibrary(limit = "2") PythonBufferAcquireLibrary acquireLib, @Shared("bufferLib") @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { TruffleString digestmod = castStr.execute(inliningTarget, digestmodObj); Object key; if (!acquireLib.hasBuffer(keyObj)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, keyObj); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, keyObj); } else { key = acquireLib.acquireReadonly(keyObj); } @@ -320,15 +335,16 @@ static Object hmacNew(@SuppressWarnings("unused") PythonModule self, Object keyO } else if (acquireLib.hasBuffer(msgObj)) { msg = acquireLib.acquireReadonly(msgObj); } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, msgObj); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, msgObj); } try { byte[] msgBytes = msg == null ? null : bufferLib.getInternalOrCopiedByteArray(msg); int msgLen = msg == null ? 0 : bufferLib.getBufferLength(msg); Mac mac = createMac(digestmod, bufferLib.getInternalOrCopiedByteArray(key), bufferLib.getBufferLength(key), msgBytes, msgLen); - return factory.createDigestObject(PythonBuiltinClassType.HashlibHmac, castJStr.execute(concatStr.execute(HMAC_PREFIX, digestmod, TS_ENCODING, true)), mac); + return PFactory.createDigestObject(PythonLanguage.get(inliningTarget), PythonBuiltinClassType.HashlibHmac, + castJStr.execute(concatStr.execute(HMAC_PREFIX, digestmod, TS_ENCODING, true)), mac); } catch (InvalidKeyException | NoSuchAlgorithmException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.UnsupportedDigestmodError, e); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.UnsupportedDigestmodError, e); } finally { if (msg != null) { bufferLib.release(msg); @@ -362,17 +378,16 @@ abstract static class CreateDigestNode extends Node { @Specialization static Object doIt(VirtualFrame frame, Node inliningTarget, PythonBuiltinClassType type, String pythonName, String javaName, Object value, @Cached("createFor(this)") IndirectCallData indirectCallData, - @Cached(inline = false) PythonObjectFactory factory, @CachedLibrary(limit = "2") PythonBufferAcquireLibrary acquireLib, @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode.Lazy raise) { + @Cached PRaiseNode raise) { Object buffer; if (value instanceof PNone) { buffer = null; } else if (acquireLib.hasBuffer(value)) { buffer = acquireLib.acquireReadonly(value, frame, indirectCallData); } else { - throw raise.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, value); + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, value); } try { byte[] bytes = buffer == null ? null : bufferLib.getInternalOrCopiedByteArray(buffer); @@ -381,9 +396,9 @@ static Object doIt(VirtualFrame frame, Node inliningTarget, PythonBuiltinClassTy try { digest = createDigest(javaName, bytes, bytesLen); } catch (NoSuchAlgorithmException e) { - throw raise.get(inliningTarget).raise(PythonBuiltinClassType.UnsupportedDigestmodError, e); + throw raise.raise(inliningTarget, PythonBuiltinClassType.UnsupportedDigestmodError, e); } - return factory.createDigestObject(type, pythonName, digest); + return PFactory.createDigestObject(PythonLanguage.get(inliningTarget), type, pythonName, digest); } finally { if (buffer != null) { bufferLib.release(buffer, frame, indirectCallData); @@ -452,36 +467,76 @@ static int getFips() { } } - @Builtin(name = "HASH", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.HashlibHash, isPublic = false) + @Builtin(name = "pbkdf2_hmac", minNumOfPositionalArgs = 4, parameterNames = {"hash_name", "password", "salt", "iterations", "dklen"}) @GenerateNodeFactory - abstract static class HashNode extends PythonBuiltinNode { - @Specialization - @SuppressWarnings("unused") - static Object hash(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "_hashlib.HASH"); + @ArgumentClinic(name = "hash_name", conversion = ArgumentClinic.ClinicConversion.TString) + @ArgumentClinic(name = "password", conversion = ArgumentClinic.ClinicConversion.ReadableBuffer) + @ArgumentClinic(name = "salt", conversion = ArgumentClinic.ClinicConversion.ReadableBuffer) + @ArgumentClinic(name = "iterations", conversion = ArgumentClinic.ClinicConversion.Long) + abstract static class Pbkdf2HmacNode extends PythonClinicBuiltinNode { + @Override + protected ArgumentClinicProvider getArgumentClinic() { + return Pbkdf2HmacNodeClinicProviderGen.INSTANCE; } - } - @Builtin(name = "HASHXOF", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.HashlibHashXof, isPublic = false) - @GenerateNodeFactory - abstract static class HashXofNode extends PythonBuiltinNode { - @Specialization - @SuppressWarnings("unused") - static Object hash(Object args, Object kwargs, + @Specialization(limit = "3") + static Object pbkdf2(VirtualFrame frame, TruffleString hashName, Object password, Object salt, long iterations, Object dklenObj, + @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, + @CachedLibrary("password") PythonBufferAccessLibrary passwordLib, + @CachedLibrary("salt") PythonBufferAccessLibrary saltLib, + @Cached PyLongAsLongNode asLongNode, + @Cached InlinedConditionProfile noDklenProfile, + @Cached TruffleString.ToJavaStringNode toJavaStringNode, @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "_hashlib.HASHXOF"); + try { + Digest digest = getDigest(toJavaStringNode.execute(hashName)); + if (digest == null) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.UnsupportedDigestmodError, UNSUPPORTED_HASH_TYPE, hashName); + } + if (iterations < 1) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ITERATION_VALUE_MUST_BE_GREATER_THAN_ZERO); + } + if (iterations > Integer.MAX_VALUE) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.OverflowError, ITERATION_VALUE_IS_TOO_GREAT); + } + long dklen; + if (noDklenProfile.profile(inliningTarget, PGuards.isPNone(dklenObj))) { + dklen = digest.getDigestSize(); + } else { + dklen = asLongNode.execute(frame, inliningTarget, dklenObj); + } + dklen *= Byte.SIZE; + if (dklen < 1) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, KEY_LENGTH_MUST_BE_GREATER_THAN_ZERO); + } + if (dklen > Integer.MAX_VALUE) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.OverflowError, ITERATION_VALUE_IS_TOO_GREAT); + } + byte[] passwordBytes = passwordLib.getInternalOrCopiedExactByteArray(password); + byte[] saltBytes = saltLib.getInternalOrCopiedExactByteArray(salt); + return PFactory.createBytes(language, generate(digest, passwordBytes, saltBytes, (int) iterations, (int) dklen)); + } finally { + passwordLib.release(password); + saltLib.release(salt); + } } - } - @Builtin(name = "HMAC", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.HashlibHmac, isPublic = false) - @GenerateNodeFactory - abstract static class HmacNode extends PythonBuiltinNode { - @Specialization - @SuppressWarnings("unused") - static Object hash(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "_hashlib.HMAC"); + @TruffleBoundary + private static Digest getDigest(String name) { + name = name.toLowerCase(); + return DigestFactory.getDigest(NAME_MAPPINGS.getOrDefault(name, name)); + } + + @TruffleBoundary + private static byte[] generate(Digest digest, byte[] password, byte[] salt, int iterations, int dklen) { + PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator(digest); + generator.init(password, salt, iterations); + CipherParameters cipherParameters = generator.generateDerivedParameters(dklen); + if (!(cipherParameters instanceof KeyParameter keyParameter)) { + throw CompilerDirectives.shouldNotReachHere("unexpected cipher parameters"); + } + return keyParameter.getKey(); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Md5ModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Md5ModuleBuiltins.java index 4dd0f06807..1f11399004 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Md5ModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Md5ModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,8 +46,6 @@ import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.truffle.api.dsl.Bind; @@ -75,15 +73,4 @@ static Object newDigest(VirtualFrame frame, Object buffer, @SuppressWarnings("un return createNode.execute(frame, inliningTarget, PythonBuiltinClassType.MD5Type, "md5", "md5", buffer); } } - - @Builtin(name = "md5", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.MD5Type, isPublic = false) - @GenerateNodeFactory - abstract static class Md5Node extends PythonBuiltinNode { - @Specialization - @SuppressWarnings("unused") - static Object md5(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "_md5.md5"); - } - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha1ModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha1ModuleBuiltins.java index 98e8ef5064..df59db9b2c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha1ModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha1ModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,8 +46,6 @@ import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.truffle.api.dsl.Bind; @@ -75,15 +73,4 @@ static Object newDigest(VirtualFrame frame, Object buffer, @SuppressWarnings("un return createNode.execute(frame, inliningTarget, PythonBuiltinClassType.SHA1Type, "sha1", "sha1", buffer); } } - - @Builtin(name = "sha1", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.SHA1Type, isPublic = false) - @GenerateNodeFactory - abstract static class Sha1Node extends PythonBuiltinNode { - @Specialization - @SuppressWarnings("unused") - static Object sha1(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "_sha1.sha1"); - } - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha256ModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha256ModuleBuiltins.java index 738dfd11c0..08f4c10503 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha256ModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha256ModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,8 +46,6 @@ import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.truffle.api.dsl.Bind; @@ -86,26 +84,4 @@ static Object newDigest(VirtualFrame frame, Object buffer, @SuppressWarnings("un return createNode.execute(frame, inliningTarget, PythonBuiltinClassType.SHA256Type, "sha256", "sha256", buffer); } } - - @Builtin(name = "sha224", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.SHA224Type, isPublic = false) - @GenerateNodeFactory - abstract static class Sha224Node extends PythonBuiltinNode { - @Specialization - @SuppressWarnings("unused") - static Object sha224(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "_sha256.sha224"); - } - } - - @Builtin(name = "sha256", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.SHA256Type, isPublic = false) - @GenerateNodeFactory - abstract static class Sha256Node extends PythonBuiltinNode { - @Specialization - @SuppressWarnings("unused") - static Object sha256(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "_sha256.sha256"); - } - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha3Builtins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha3Builtins.java new file mode 100644 index 0000000000..f27ee6bc67 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha3Builtins.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.builtins.modules.hashlib; + +import java.util.Collections; +import java.util.List; + +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.builtins.CoreFunctions; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinNode; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateNodeFactory; +import com.oracle.truffle.api.dsl.NodeFactory; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; + +@CoreFunctions(extendClasses = { + PythonBuiltinClassType.Sha3SHA224Type, + PythonBuiltinClassType.Sha3SHA256Type, + PythonBuiltinClassType.Sha3SHA384Type, + PythonBuiltinClassType.Sha3SHA512Type, + PythonBuiltinClassType.Sha3Shake128Type, + PythonBuiltinClassType.Sha3Shake256Type, +}) +public class Sha3Builtins extends PythonBuiltins { + + public static final TpSlots SLOTS = Sha3BuiltinsSlotsGen.SLOTS; + + @Override + protected List> getNodeFactories() { + return Collections.emptyList(); + } + + @Slot(value = Slot.SlotKind.tp_new, isComplex = true) + @Slot.SlotSignature(minNumOfPositionalArgs = 1, parameterNames = {"$cls", "string"}, keywordOnlyNames = {"usedforsecurity"}) + @GenerateNodeFactory + abstract static class ShaNode extends PythonBuiltinNode { + @Specialization + static Object newDigest(VirtualFrame frame, Object type, Object buffer, @SuppressWarnings("unused") Object usedForSecurity, + @Bind("this") Node inliningTarget, + @Cached HashlibModuleBuiltins.CreateDigestNode createNode, + @Cached PRaiseNode raiseNode) { + PythonBuiltinClassType resultType; + if (type instanceof PythonBuiltinClass builtinType) { + resultType = builtinType.getType(); + } else if (type instanceof PythonBuiltinClassType enumType) { + resultType = enumType; + } else { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.WRONG_TYPE); + } + return createNode.execute(frame, inliningTarget, resultType, pythonNameFromType(resultType), javaNameFromType(resultType), buffer); + } + + private static String javaNameFromType(PythonBuiltinClassType type) { + switch (type) { + case Sha3SHA224Type: + return "sha3-224"; + case Sha3SHA256Type: + return "sha3-256"; + case Sha3SHA384Type: + return "sha3-384"; + case Sha3SHA512Type: + return "sha3-512"; + case Sha3Shake128Type: + return "SHAKE128"; + case Sha3Shake256Type: + return "SHAKE256"; + default: + throw CompilerDirectives.shouldNotReachHere(); + } + } + + private static String pythonNameFromType(PythonBuiltinClassType type) { + switch (type) { + case Sha3SHA224Type: + return "sha3_224"; + case Sha3SHA256Type: + return "sha3_256"; + case Sha3SHA384Type: + return "sha3_384"; + case Sha3SHA512Type: + return "sha3_512"; + case Sha3Shake128Type: + return "shake_128"; + case Sha3Shake256Type: + return "shake_256"; + default: + throw CompilerDirectives.shouldNotReachHere(); + } + } + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha3ModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha3ModuleBuiltins.java index 66e35129f7..df78c07cdc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha3ModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha3ModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,99 +42,18 @@ import static com.oracle.graal.python.nodes.BuiltinNames.J_SHA3; +import java.util.Collections; import java.util.List; -import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinNode; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; @CoreFunctions(defineModule = J_SHA3) public final class Sha3ModuleBuiltins extends PythonBuiltins { @Override protected List> getNodeFactories() { - return Sha3ModuleBuiltinsFactory.getFactories(); - } - - @Builtin(name = "sha3_224", declaresExplicitSelf = true, minNumOfPositionalArgs = 1, parameterNames = {"$cls", "string"}, keywordOnlyNames = { - "usedforsecurity"}, constructsClass = PythonBuiltinClassType.Sha3SHA224Type) - @Builtin(name = "sha3_256", declaresExplicitSelf = true, minNumOfPositionalArgs = 1, parameterNames = {"$cls", "string"}, keywordOnlyNames = { - "usedforsecurity"}, constructsClass = PythonBuiltinClassType.Sha3SHA256Type) - @Builtin(name = "sha3_384", declaresExplicitSelf = true, minNumOfPositionalArgs = 1, parameterNames = {"$cls", "string"}, keywordOnlyNames = { - "usedforsecurity"}, constructsClass = PythonBuiltinClassType.Sha3SHA384Type) - @Builtin(name = "sha3_512", declaresExplicitSelf = true, minNumOfPositionalArgs = 1, parameterNames = {"$cls", "string"}, keywordOnlyNames = { - "usedforsecurity"}, constructsClass = PythonBuiltinClassType.Sha3SHA512Type) - @Builtin(name = "shake_128", declaresExplicitSelf = true, minNumOfPositionalArgs = 1, parameterNames = {"$cls", "string"}, keywordOnlyNames = { - "usedforsecurity"}, constructsClass = PythonBuiltinClassType.Sha3Shake128Type) - @Builtin(name = "shake_256", declaresExplicitSelf = true, minNumOfPositionalArgs = 1, parameterNames = {"$cls", "string"}, keywordOnlyNames = { - "usedforsecurity"}, constructsClass = PythonBuiltinClassType.Sha3Shake256Type) - @GenerateNodeFactory - abstract static class ShaNode extends PythonBuiltinNode { - @Specialization - static Object newDigest(VirtualFrame frame, Object type, Object buffer, @SuppressWarnings("unused") Object usedForSecurity, - @Bind("this") Node inliningTarget, - @Cached HashlibModuleBuiltins.CreateDigestNode createNode, - @Cached PRaiseNode.Lazy raiseNode) { - PythonBuiltinClassType resultType; - if (type instanceof PythonBuiltinClass builtinType) { - resultType = builtinType.getType(); - } else if (type instanceof PythonBuiltinClassType enumType) { - resultType = enumType; - } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.WRONG_TYPE); - } - return createNode.execute(frame, inliningTarget, resultType, pythonNameFromType(resultType), javaNameFromType(resultType), buffer); - } - - private static String javaNameFromType(PythonBuiltinClassType type) { - switch (type) { - case Sha3SHA224Type: - return "sha3-224"; - case Sha3SHA256Type: - return "sha3-256"; - case Sha3SHA384Type: - return "sha3-384"; - case Sha3SHA512Type: - return "sha3-512"; - case Sha3Shake128Type: - return "SHAKE128"; - case Sha3Shake256Type: - return "SHAKE256"; - default: - throw CompilerDirectives.shouldNotReachHere(); - } - } - - private static String pythonNameFromType(PythonBuiltinClassType type) { - switch (type) { - case Sha3SHA224Type: - return "sha3_224"; - case Sha3SHA256Type: - return "sha3_256"; - case Sha3SHA384Type: - return "sha3_384"; - case Sha3SHA512Type: - return "sha3_512"; - case Sha3Shake128Type: - return "shake_128"; - case Sha3Shake256Type: - return "shake_256"; - default: - throw CompilerDirectives.shouldNotReachHere(); - } - } + return Collections.emptyList(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha512ModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha512ModuleBuiltins.java index bb60193f76..9e6aed5814 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha512ModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Sha512ModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,8 +46,6 @@ import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.truffle.api.dsl.Bind; @@ -86,26 +84,4 @@ static Object newDigest(VirtualFrame frame, Object buffer, @SuppressWarnings("un return createNode.execute(frame, inliningTarget, PythonBuiltinClassType.SHA512Type, "sha512", "sha512", buffer); } } - - @Builtin(name = "sha384", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.SHA384Type, isPublic = false) - @GenerateNodeFactory - abstract static class Sha384Node extends PythonBuiltinNode { - @Specialization - @SuppressWarnings("unused") - static Object sha384(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "_sha512.sha384"); - } - } - - @Builtin(name = "sha512", takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.SHA512Type, isPublic = false) - @GenerateNodeFactory - abstract static class Sha512Node extends PythonBuiltinNode { - @Specialization - @SuppressWarnings("unused") - static Object sha512(Object args, Object kwargs, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, "_sha512.sha512"); - } - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/ShakeDigestObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/ShakeDigestObjectBuiltins.java index 1d736b68e4..7e18f650da 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/ShakeDigestObjectBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/ShakeDigestObjectBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,6 +42,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -57,7 +58,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -94,12 +95,12 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static PBytes digest(DigestObject self, int length, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { if (self.getDigestLength() != length) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.ONLY_DEFAULT_DIGEST_LENGTHS); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.ONLY_DEFAULT_DIGEST_LENGTHS); } - return factory.createBytes(self.digest()); + return PFactory.createBytes(language, self.digest()); } } @@ -116,9 +117,9 @@ protected ArgumentClinicProvider getArgumentClinic() { static TruffleString hexdigest(DigestObject self, int length, @Bind("this") Node inliningTarget, @Cached BytesNodes.ByteToHexNode toHexNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (self.getDigestLength() != length) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.ONLY_DEFAULT_DIGEST_LENGTHS); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.ONLY_DEFAULT_DIGEST_LENGTHS); } byte[] digest = self.digest(); return toHexNode.execute(inliningTarget, digest, digest.length, (byte) 0, 0); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/AbstractBufferedIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/AbstractBufferedIOBuiltins.java index e1d5232967..71f1cc86c9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/AbstractBufferedIOBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/AbstractBufferedIOBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,6 +47,7 @@ import static com.oracle.graal.python.nodes.ErrorMessages.IO_UNINIT; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.modules.io.BufferedIONodes.RawTellIgnoreErrorNode; @@ -66,8 +67,9 @@ import com.oracle.graal.python.runtime.PosixSupportLibrary; import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; @@ -85,25 +87,26 @@ abstract class AbstractBufferedIOBuiltins extends PythonBuiltins { @GenerateCached(false) public abstract static class BufferedInitNode extends PNodeWithContext { - public abstract void execute(VirtualFrame frame, Node inliningTarget, PBuffered self, int bufferSize, PythonObjectFactory factory); + public abstract void execute(VirtualFrame frame, Node inliningTarget, PBuffered self, int bufferSize); @Specialization(guards = "bufferSize > 0") - static void bufferedInit(VirtualFrame frame, Node inliningTarget, PBuffered self, int bufferSize, PythonObjectFactory factory, - @Cached RawTellIgnoreErrorNode rawTellNode) { - init(self, bufferSize, factory); + static void bufferedInit(VirtualFrame frame, Node inliningTarget, PBuffered self, int bufferSize, + @Cached RawTellIgnoreErrorNode rawTellNode, + @Bind PythonLanguage language) { + init(self, bufferSize, language); rawTellNode.execute(frame, inliningTarget, self); } @SuppressWarnings("unused") @Specialization(guards = "bufferSize <= 0") - static void bufferSizeError(PBuffered self, int bufferSize, PythonObjectFactory factory, - @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, BUF_SIZE_POS); + static void bufferSizeError(PBuffered self, int bufferSize, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, BUF_SIZE_POS); } - private static void init(PBuffered self, int bufferSize, PythonObjectFactory factory) { + private static void init(PBuffered self, int bufferSize, PythonLanguage language) { self.initBuffer(bufferSize); - self.setLock(factory.createLock()); + self.setLock(PFactory.createLock(language)); self.setOwner(0); int n; for (n = bufferSize - 1; (n & 1) != 0; n >>= 1) { @@ -112,10 +115,10 @@ private static void init(PBuffered self, int bufferSize, PythonObjectFactory fac self.setBufferMask(mask); } - public static void internalInit(PBuffered self, int bufferSize, PythonObjectFactory factory, + public static void internalInit(PBuffered self, int bufferSize, PythonLanguage language, Object posixSupport, PosixSupportLibrary posixLib) { - init(self, bufferSize, factory); + init(self, bufferSize, language); try { FileIOBuiltins.TellNode.internalTell(self.getFileIORaw(), posixSupport, posixLib); } catch (PosixException e) { @@ -162,11 +165,11 @@ protected ArgumentClinicProvider getArgumentClinic() { @SuppressWarnings("unused") @Specialization(guards = "!self.isOK()") static Object initError(PBuffered self, Object o, - @Cached PRaiseNode raiseNode) { + @Bind("this") Node inliningTarget) { if (self.isDetached()) { - throw raiseNode.raise(ValueError, IO_STREAM_DETACHED); + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_STREAM_DETACHED); } else { - throw raiseNode.raise(ValueError, IO_UNINIT); + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } } } @@ -176,11 +179,11 @@ abstract static class PythonBinaryWithInitErrorBuiltinNode extends PythonBinaryB @SuppressWarnings("unused") @Specialization(guards = "!self.isOK()") static Object initError(PBuffered self, Object buffer, - @Cached PRaiseNode raiseNode) { + @Bind("this") Node inliningTarget) { if (self.isDetached()) { - throw raiseNode.raise(ValueError, IO_STREAM_DETACHED); + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_STREAM_DETACHED); } else { - throw raiseNode.raise(ValueError, IO_UNINIT); + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } } } @@ -189,11 +192,11 @@ abstract static class PythonUnaryWithInitErrorBuiltinNode extends PythonUnaryBui @SuppressWarnings("unused") @Specialization(guards = "!self.isOK()") static Object initError(PBuffered self, - @Cached PRaiseNode raiseNode) { + @Bind("this") Node inliningTarget) { if (self.isDetached()) { - throw raiseNode.raise(ValueError, IO_STREAM_DETACHED); + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_STREAM_DETACHED); } else { - throw raiseNode.raise(ValueError, IO_UNINIT); + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } } } @@ -216,13 +219,13 @@ public final PException raiseEAGAIN(TruffleString message, int written) { @Specialization static PException raise(Node node, Object errno, TruffleString message, int written, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { Object[] args = new Object[]{ errno, message, written }; - PBaseException exception = factory.createBaseException(BlockingIOError, factory.createTuple(args)); + PBaseException exception = PFactory.createBaseException(language, BlockingIOError, PFactory.createTuple(language, args)); final Object[] attrs = OS_ERROR_ATTR_FACTORY.create(); attrs[OsErrorBuiltins.IDX_ERRNO] = errno; attrs[OsErrorBuiltins.IDX_STRERROR] = message; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIOBaseBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIOBaseBuiltins.java index d2c08166f0..150cdc080d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIOBaseBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIOBaseBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -100,8 +100,8 @@ abstract static class DetachNode extends PythonBuiltinNode { */ @Specialization static Object detach(@SuppressWarnings("unused") Object self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, T_DETACH); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, T_DETACH); } } @@ -115,8 +115,8 @@ abstract static class ReadNode extends PythonBuiltinNode { @SuppressWarnings("unused") @Specialization static Object read(Object self, Object args, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, T_READ); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, T_READ); } } @@ -130,8 +130,8 @@ abstract static class Read1Node extends PythonBuiltinNode { @SuppressWarnings("unused") @Specialization static Object read1(Object self, Object args, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, T_READ1); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, T_READ1); } } @@ -153,18 +153,18 @@ Object readinto(VirtualFrame frame, Object self, Object buffer, @Cached PyObjectCallMethodObjArgs callMethod, @Cached InlinedConditionProfile isBytes, @Cached InlinedConditionProfile oversize, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { int len = bufferLib.getBufferLength(buffer); Object data = callMethod.execute(frame, inliningTarget, self, getMethodName(), len); if (isBytes.profile(inliningTarget, !(data instanceof PBytes))) { - throw raiseNode.get(inliningTarget).raise(ValueError, S_SHOULD_RETURN_BYTES, "read()"); + throw raiseNode.raise(inliningTarget, ValueError, S_SHOULD_RETURN_BYTES, "read()"); } // Directly using data as buffer because CPython also accesses the underlying memory // of the bytes object int dataLen = bufferLib.getBufferLength(data); if (oversize.profile(inliningTarget, dataLen > len)) { - throw raiseNode.get(inliningTarget).raise(ValueError, S_RETURNED_TOO_MUCH_DATA, "read()", len, dataLen); + throw raiseNode.raise(inliningTarget, ValueError, S_RETURNED_TOO_MUCH_DATA, "read()", len, dataLen); } bufferLib.readIntoBuffer(data, 0, buffer, 0, dataLen, bufferLib); return dataLen; @@ -219,8 +219,8 @@ abstract static class WriteNode extends PythonBuiltinNode { @SuppressWarnings("unused") @Specialization static Object write(Object self, Object args, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, T_WRITE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, T_WRITE); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIOMixinBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIOMixinBuiltins.java index 16089c404f..7d9617a42d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIOMixinBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIOMixinBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -76,13 +76,14 @@ import static com.oracle.graal.python.nodes.ErrorMessages.IO_UNINIT; import static com.oracle.graal.python.nodes.ErrorMessages.REENTRANT_CALL_INSIDE_S_REPR; import static com.oracle.graal.python.nodes.ErrorMessages.UNSUPPORTED_WHENCE; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.IOUnsupportedOperation; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; import java.util.List; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.modules.io.BufferedIONodes.CheckIsClosedNode; @@ -91,6 +92,7 @@ import com.oracle.graal.python.builtins.modules.io.BufferedIONodes.RawTellNode; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyErrChainExceptions; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; @@ -105,18 +107,15 @@ import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedConditionProfile; @@ -124,6 +123,9 @@ @CoreFunctions(extendClasses = {PBufferedReader, PBufferedWriter, PBufferedRandom}) public final class BufferedIOMixinBuiltins extends AbstractBufferedIOBuiltins { + + public static final TpSlots SLOTS = BufferedIOMixinBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return BufferedIOMixinBuiltinsFactory.getFactories(); @@ -256,7 +258,6 @@ static Object none(@SuppressWarnings("unused") Object self, @SuppressWarnings("u @ArgumentClinic(name = "whence", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "BufferedIOUtil.SEEK_SET", useDefaultForNone = true) @GenerateNodeFactory @ImportStatic(IONodes.class) - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class SeekNode extends PythonTernaryClinicBuiltinNode { @Override @@ -283,17 +284,17 @@ static long doit(VirtualFrame frame, PBuffered self, Object off, int whence, @Specialization(guards = {"self.isOK()", "!isSupportedWhence(whence)"}) static Object whenceError(@SuppressWarnings("unused") PBuffered self, @SuppressWarnings("unused") int off, int whence, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, UNSUPPORTED_WHENCE, whence); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, UNSUPPORTED_WHENCE, whence); } @Specialization(guards = "!self.isOK()") static Object initError(PBuffered self, @SuppressWarnings("unused") int off, @SuppressWarnings("unused") int whence, - @Shared @Cached PRaiseNode raiseNode) { + @Bind("this") Node inliningTarget) { if (self.isDetached()) { - throw raiseNode.raise(ValueError, IO_STREAM_DETACHED); + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_STREAM_DETACHED); } else { - throw raiseNode.raise(ValueError, IO_UNINIT); + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } } } @@ -345,8 +346,8 @@ static Object doit(VirtualFrame frame, PBuffered self, Object pos, @Specialization(guards = {"self.isOK()", "!self.isWritable()"}) static Object notWritable(@SuppressWarnings("unused") PBuffered self, @SuppressWarnings("unused") Object pos, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, T_TRUNCATE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, T_TRUNCATE); } } @@ -401,7 +402,7 @@ static Object doit(VirtualFrame frame, PBuffered self, } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization @@ -413,7 +414,7 @@ static TruffleString repr(VirtualFrame frame, PBuffered self, @Cached IsBuiltinObjectProfile isValueError, @Cached PyObjectReprAsTruffleStringNode repr, @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleString typeName = getNameNode.execute(inliningTarget, getClassNode.execute(inliningTarget, self)); Object nameobj = PNone.NO_VALUE; try { @@ -426,7 +427,7 @@ static TruffleString repr(VirtualFrame frame, PBuffered self, return simpleTruffleStringFormatNode.format("<%s>", typeName); } else { if (!PythonContext.get(inliningTarget).reprEnter(self)) { - throw raiseNode.get(inliningTarget).raise(RuntimeError, REENTRANT_CALL_INSIDE_S_REPR, typeName); + throw raiseNode.raise(inliningTarget, RuntimeError, REENTRANT_CALL_INSIDE_S_REPR, typeName); } else { try { TruffleString name = repr.execute(frame, inliningTarget, nameobj); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIONodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIONodes.java index 1604b1a4dd..37c778a932 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIONodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIONodes.java @@ -73,7 +73,7 @@ import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaLongExactNode; import com.oracle.graal.python.runtime.GilNode; @@ -109,10 +109,10 @@ public CheckIsClosedNode(TruffleString method) { @Specialization boolean isClosedBuffered(VirtualFrame frame, PBuffered self, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached IsClosedNode isClosedNode) { if (isClosedNode.execute(frame, inliningTarget, self)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, messageFmt, method); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, messageFmt, method); } return false; } @@ -155,18 +155,18 @@ static boolean isSeekable(VirtualFrame frame, PBuffered self, @Bind("this") Node inliningTarget, @Cached PyObjectCallMethodObjArgs callMethod, @Cached PyObjectIsTrueNode isTrue, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { assert self.isOK(); Object res = callMethod.execute(frame, inliningTarget, self.getRaw(), T_SEEKABLE); if (!isTrue.execute(frame, res)) { - throw raiseNode.get(inliningTarget).raise(IOUnsupportedOperation, FILE_OR_STREAM_IS_NOT_SEEKABLE); + throw raiseNode.raise(inliningTarget, IOUnsupportedOperation, FILE_OR_STREAM_IS_NOT_SEEKABLE); } return true; } } @ImportStatic(PGuards.class) - @TypeSystemReference(PythonArithmeticTypes.class) + @TypeSystemReference(PythonIntegerTypes.class) @GenerateInline @GenerateCached(false) // PyNumber_AsOff_t @@ -181,7 +181,7 @@ static long doInt(long number, @SuppressWarnings("unused") PythonBuiltinClassTyp @Specialization static long toLong(VirtualFrame frame, Node inliningTarget, Object number, PythonBuiltinClassType err, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached PyNumberIndexNode indexNode, @Cached CastToJavaLongExactNode cast, @Cached IsBuiltinObjectProfile errorProfile) { @@ -190,7 +190,7 @@ static long toLong(VirtualFrame frame, Node inliningTarget, Object number, Pytho return cast.execute(inliningTarget, index); } catch (PException e) { e.expect(inliningTarget, OverflowError, errorProfile); - throw raiseNode.get(inliningTarget).raise(err, CANNOT_FIT_P_IN_OFFSET_SIZE, number); + throw raiseNode.raise(inliningTarget, err, CANNOT_FIT_P_IN_OFFSET_SIZE, number); } catch (CannotCastException e) { throw CompilerDirectives.shouldNotReachHere(); } @@ -218,12 +218,12 @@ public final long executeCached(VirtualFrame frame, PBuffered self) { */ @Specialization static long bufferedRawTell(VirtualFrame frame, Node inliningTarget, PBuffered self, - @Cached PRaiseNode.Lazy lazyRaiseNode, + @Cached PRaiseNode lazyRaiseNode, @Cached PyObjectCallMethodObjArgs callMethod, @Cached AsOffNumberNode asOffNumberNode) { long n = tell(frame, inliningTarget, self.getRaw(), callMethod, asOffNumberNode); if (n < 0) { - throw lazyRaiseNode.get(inliningTarget).raise(OSError, IO_STREAM_INVALID_POS, n); + throw lazyRaiseNode.raise(inliningTarget, OSError, IO_STREAM_INVALID_POS, n); } self.setAbsPos(n); return n; @@ -278,13 +278,13 @@ abstract static class RawSeekNode extends PNodeWithContext { @Specialization static long bufferedRawSeek(VirtualFrame frame, PBuffered self, long target, int whence, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raise, + @Cached PRaiseNode raise, @Cached PyObjectCallMethodObjArgs callMethod, @Cached AsOffNumberNode asOffNumberNode) { Object res = callMethod.execute(frame, inliningTarget, self.getRaw(), T_SEEK, target, whence); long n = asOffNumberNode.execute(frame, inliningTarget, res, ValueError); if (n < 0) { - raise.get(inliningTarget).raise(OSError, IO_STREAM_INVALID_POS, n); + raise.raise(inliningTarget, OSError, IO_STREAM_INVALID_POS, n); } self.setAbsPos(n); return n; @@ -456,7 +456,7 @@ static void normal(Node inliningTarget, PBuffered self, @Specialization(guards = {"!self.isOwn()", "getContext().isFinalizing()"}) static void finalizing(Node inliningTarget, PBuffered self, - @Shared @Cached PRaiseNode.Lazy lazyRaise) { + @Shared @Cached PRaiseNode lazyRaise) { /* * When finalizing, we don't want a deadlock to happen with daemon threads abruptly shut * down while they owned the lock. Therefore, only wait for a grace period (1 s.). Note @@ -464,14 +464,14 @@ static void finalizing(Node inliningTarget, PBuffered self, * written threaded I/O code. */ if (!self.getLock().acquireTimeout(inliningTarget, (long) 1e3)) { - throw lazyRaise.get(inliningTarget).raise(SystemError, SHUTDOWN_POSSIBLY_DUE_TO_DAEMON_THREADS); + throw lazyRaise.raise(inliningTarget, SystemError, SHUTDOWN_POSSIBLY_DUE_TO_DAEMON_THREADS); } } @Specialization(guards = "self.isOwn()") static void error(Node inliningTarget, PBuffered self, - @Shared @Cached PRaiseNode.Lazy lazyRaise) { - throw lazyRaise.get(inliningTarget).raise(RuntimeError, REENTRANT_CALL_INSIDE_P, self); + @Shared @Cached PRaiseNode lazyRaise) { + throw lazyRaise.raise(inliningTarget, RuntimeError, REENTRANT_CALL_INSIDE_P, self); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedRWPairBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedRWPairBuiltins.java index 9cd72d1105..1f8f03e237 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedRWPairBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedRWPairBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,8 +41,6 @@ package com.oracle.graal.python.builtins.modules.io; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PBufferedRWPair; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PBufferedReader; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PBufferedWriter; import static com.oracle.graal.python.builtins.modules.io.IONodes.J_CLOSE; import static com.oracle.graal.python.builtins.modules.io.IONodes.J_CLOSED; import static com.oracle.graal.python.builtins.modules.io.IONodes.J_FLUSH; @@ -69,29 +67,35 @@ import static com.oracle.graal.python.builtins.modules.io.IONodes.T_WRITE; import static com.oracle.graal.python.nodes.ErrorMessages.IO_UNINIT; import static com.oracle.graal.python.nodes.ErrorMessages.THE_S_OBJECT_IS_BEING_GARBAGE_COLLECTED; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.RuntimeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyErrChainExceptions; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.object.IsNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; @@ -106,12 +110,28 @@ @CoreFunctions(extendClasses = PBufferedRWPair) public final class BufferedRWPairBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = BufferedRWPairBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return BufferedRWPairBuiltinsFactory.getFactories(); } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 3, parameterNames = {"$self", "reader", "writer", "buffer_size"}) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "BufferedRWPair", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class BufferedRWPairNode extends PythonBuiltinNode { + @Specialization + static PRWPair doNew(Object cls, @SuppressWarnings("unused") Object arg, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + // data filled in subsequent __init__ call - see BufferedRWPairBuiltins.InitNode + return PFactory.createRWPair(language, cls, getInstanceShape.execute(cls)); + } + } + + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "BufferedRWPair", minNumOfPositionalArgs = 3, parameterNames = {"$self", "reader", "writer", "buffer_size"}) @ArgumentClinic(name = "buffer_size", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "BufferedReaderBuiltins.DEFAULT_BUFFER_SIZE", useDefaultForNone = true) @GenerateNodeFactory public abstract static class InitNode extends PythonQuaternaryClinicBuiltinNode { @@ -128,13 +148,13 @@ static PNone doInit(VirtualFrame frame, PRWPair self, Object reader, Object writ @Cached IOBaseBuiltins.CheckBoolMethodHelperNode checkWritableNode, @Cached BufferedReaderBuiltins.BufferedReaderInit initReaderNode, @Cached BufferedWriterBuiltins.BufferedWriterInit initWriterNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { checkReadableNode.checkReadable(frame, inliningTarget, reader); checkWritableNode.checkWriteable(frame, inliningTarget, writer); - self.setReader(factory.createBufferedReader(PBufferedReader)); - initReaderNode.execute(frame, inliningTarget, self.getReader(), reader, bufferSize, factory); - self.setWriter(factory.createBufferedWriter(PBufferedWriter)); - initWriterNode.execute(frame, inliningTarget, self.getWriter(), writer, bufferSize, factory); + self.setReader(PFactory.createBufferedReader(language)); + initReaderNode.execute(frame, inliningTarget, self.getReader(), reader, bufferSize); + self.setWriter(PFactory.createBufferedWriter(language)); + initWriterNode.execute(frame, inliningTarget, self.getWriter(), writer, bufferSize); return PNone.NONE; } } @@ -148,8 +168,8 @@ protected static boolean isInit(PRWPair self) { @SuppressWarnings("unused") @Specialization(guards = "!isInit(self)") static Object error(VirtualFrame frame, PRWPair self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_UNINIT); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } } @@ -162,8 +182,8 @@ protected static boolean isInit(PRWPair self) { @SuppressWarnings("unused") @Specialization(guards = "!isInit(self)") static Object error(VirtualFrame frame, PRWPair self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_UNINIT); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } } @@ -176,8 +196,8 @@ protected static boolean isInit(PRWPair self) { @SuppressWarnings("unused") @Specialization(guards = "!isInit(self)") static Object error(VirtualFrame frame, PRWPair self, Object arg, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_UNINIT); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } } @@ -190,8 +210,8 @@ protected static boolean isInit(PRWPair self) { @SuppressWarnings("unused") @Specialization(guards = "!isInit(self)") static Object error(VirtualFrame frame, PRWPair self, Object arg, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_UNINIT); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } } @@ -306,7 +326,7 @@ static Object close(VirtualFrame frame, PRWPair self, @Cached InlinedConditionProfile gotException, @Cached InlinedBranchProfile hasException, @Cached PyErrChainExceptions chainExceptions, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { PException writeEx = null; if (self.getWriter() != null) { try { @@ -316,7 +336,7 @@ static Object close(VirtualFrame frame, PRWPair self, writeEx = e; } } else { - writeEx = raiseNode.get(inliningTarget).raise(ValueError, IO_UNINIT); + writeEx = raiseNode.raise(inliningTarget, ValueError, IO_UNINIT); } PException readEx; @@ -331,7 +351,7 @@ static Object close(VirtualFrame frame, PRWPair self, readEx = e; } } else { - readEx = raiseNode.get(inliningTarget).raise(ValueError, IO_UNINIT); + readEx = raiseNode.raise(inliningTarget, ValueError, IO_UNINIT); } hasException.enter(inliningTarget); @@ -380,8 +400,8 @@ static Object doit(VirtualFrame frame, PRWPair self, @SuppressWarnings("unused") @Fallback static Object error(VirtualFrame frame, Object self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(RuntimeError, THE_S_OBJECT_IS_BEING_GARBAGE_COLLECTED, "BufferedRWPair"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, RuntimeError, THE_S_OBJECT_IS_BEING_GARBAGE_COLLECTED, "BufferedRWPair"); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedRandomBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedRandomBuiltins.java index ac9a19e585..987d407e38 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedRandomBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedRandomBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,18 +41,22 @@ package com.oracle.graal.python.builtins.modules.io; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PBufferedRandom; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import java.util.List; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; @@ -65,19 +69,35 @@ @CoreFunctions(extendClasses = PBufferedRandom) public final class BufferedRandomBuiltins extends AbstractBufferedIOBuiltins { + + public static final TpSlots SLOTS = BufferedRandomBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return BufferedRandomBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "BufferedRandom", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class BufferedRandomNode extends PythonBuiltinNode { + @Specialization + static PBuffered doNew(Object cls, @SuppressWarnings("unused") Object arg, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + // data filled in subsequent __init__ call - see BufferedRandomBuiltins.InitNode + return PFactory.createBufferedRandom(language, cls, getInstanceShape.execute(cls)); + } + } + @GenerateCached(false) @GenerateInline public abstract static class BufferedRandomInit extends Node { - public abstract void execute(VirtualFrame frame, Node inliningTarget, PBuffered self, Object raw, int bufferSize, PythonObjectFactory factory); + public abstract void execute(VirtualFrame frame, Node inliningTarget, PBuffered self, Object raw, int bufferSize); @Specialization - static void doInit(VirtualFrame frame, Node inliningTarget, PBuffered self, Object raw, int bufferSize, PythonObjectFactory factory, + static void doInit(VirtualFrame frame, Node inliningTarget, PBuffered self, Object raw, int bufferSize, @Cached IOBaseBuiltins.CheckBoolMethodHelperNode checkSeekableNode, @Cached IOBaseBuiltins.CheckBoolMethodHelperNode checkReadableNode, @Cached IOBaseBuiltins.CheckBoolMethodHelperNode checkWritableNode, @@ -90,7 +110,7 @@ static void doInit(VirtualFrame frame, Node inliningTarget, PBuffered self, Obje checkReadableNode.checkReadable(frame, inliningTarget, raw); checkWritableNode.checkWriteable(frame, inliningTarget, raw); self.setRaw(raw, isFileIO(self, raw, PBufferedRandom, inliningTarget, getSelfClass, getRawClass)); - bufferedInitNode.execute(frame, inliningTarget, self, bufferSize, factory); + bufferedInitNode.execute(frame, inliningTarget, self, bufferSize); self.resetRead(); self.resetWrite(); self.setPos(0); @@ -100,17 +120,17 @@ static void doInit(VirtualFrame frame, Node inliningTarget, PBuffered self, Obje } // BufferedRandom(raw[, buffer_size=DEFAULT_BUFFER_SIZE]) - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 2, parameterNames = {"self", "raw", "buffer_size"}, raiseErrorName = "BufferedRandom") + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "BufferedRandom", minNumOfPositionalArgs = 2, parameterNames = {"self", "raw", "buffer_size"}) @GenerateNodeFactory public abstract static class InitNode extends PythonBuiltinNode { @Specialization static Object doIt(VirtualFrame frame, PBuffered self, Object raw, Object bufferSize, @Bind("this") Node inliningTarget, @Cached InitBufferSizeNode initBufferSizeNode, - @Cached BufferedRandomInit init, - @Cached PythonObjectFactory factory) { + @Cached BufferedRandomInit init) { int size = initBufferSizeNode.execute(frame, inliningTarget, bufferSize); - init.execute(frame, inliningTarget, self, raw, size, factory); + init.execute(frame, inliningTarget, self, raw, size); return PNone.NONE; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedReaderBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedReaderBuiltins.java index 38ae3204f9..428e34fd8a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedReaderBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedReaderBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,20 +43,25 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PBufferedReader; import static com.oracle.graal.python.builtins.modules.io.IONodes.J_FLUSH; import static com.oracle.graal.python.builtins.modules.io.IONodes.T_FLUSH; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; import com.oracle.graal.python.runtime.PosixSupportLibrary; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; @@ -69,19 +74,35 @@ @CoreFunctions(extendClasses = PBufferedReader) public final class BufferedReaderBuiltins extends AbstractBufferedIOBuiltins { + + public static final TpSlots SLOTS = BufferedReaderBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return BufferedReaderBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "BufferedReader", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class BufferedReaderNode extends PythonBuiltinNode { + @Specialization + static PBuffered doNew(Object cls, @SuppressWarnings("unused") Object arg, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + // data filled in subsequent __init__ call - see BufferedReaderBuiltins.InitNode + return PFactory.createBufferedReader(language, cls, getInstanceShape.execute(cls)); + } + } + @GenerateInline @GenerateCached(false) public abstract static class BufferedReaderInit extends Node { - public abstract void execute(VirtualFrame frame, Node inliningTarget, PBuffered self, Object raw, int bufferSize, PythonObjectFactory factory); + public abstract void execute(VirtualFrame frame, Node inliningTarget, PBuffered self, Object raw, int bufferSize); @Specialization - static void doInit(VirtualFrame frame, Node inliningTarget, PBuffered self, Object raw, int bufferSize, PythonObjectFactory factory, + static void doInit(VirtualFrame frame, Node inliningTarget, PBuffered self, Object raw, int bufferSize, @Cached IOBaseBuiltins.CheckBoolMethodHelperNode checkReadableNode, @Cached BufferedInitNode bufferedInitNode, @Cached GetPythonObjectClassNode getSelfClass, @@ -90,34 +111,34 @@ static void doInit(VirtualFrame frame, Node inliningTarget, PBuffered self, Obje self.setDetached(false); checkReadableNode.checkReadable(frame, inliningTarget, raw); self.setRaw(raw, isFileIO(self, raw, PBufferedReader, inliningTarget, getSelfClass, getRawClass)); - bufferedInitNode.execute(frame, inliningTarget, self, bufferSize, factory); + bufferedInitNode.execute(frame, inliningTarget, self, bufferSize); self.resetRead(); self.setOK(true); } - public static void internalInit(PBuffered self, PFileIO raw, int bufferSize, PythonObjectFactory factory, + public static void internalInit(PBuffered self, PFileIO raw, int bufferSize, PythonLanguage language, Object posixSupport, PosixSupportLibrary posixLib) { self.setDetached(false); self.setRaw(raw, true); - BufferedInitNode.internalInit(self, bufferSize, factory, posixSupport, posixLib); + BufferedInitNode.internalInit(self, bufferSize, language, posixSupport, posixLib); self.resetRead(); self.setOK(true); } } // BufferedReader(raw[, buffer_size=DEFAULT_BUFFER_SIZE]) - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 2, parameterNames = {"self", "raw", "buffer_size"}, raiseErrorName = "BufferedReader") + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "BufferedReader", minNumOfPositionalArgs = 2, parameterNames = {"self", "raw", "buffer_size"}) @GenerateNodeFactory public abstract static class InitNode extends PythonBuiltinNode { @Specialization static Object doIt(VirtualFrame frame, PBuffered self, Object raw, Object bufferSize, @Bind("this") Node inliningTarget, @Cached InitBufferSizeNode initBufferSizeNode, - @Cached BufferedReaderInit init, - @Cached PythonObjectFactory factory) { + @Cached BufferedReaderInit init) { int size = initBufferSizeNode.execute(frame, inliningTarget, bufferSize); - init.execute(frame, inliningTarget, self, raw, size, factory); + init.execute(frame, inliningTarget, self, raw, size); return PNone.NONE; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedReaderMixinBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedReaderMixinBuiltins.java index e8f374a893..9b4c6225f9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedReaderMixinBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedReaderMixinBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -62,7 +62,6 @@ import static com.oracle.graal.python.nodes.ErrorMessages.IO_S_INVALID_LENGTH; import static com.oracle.graal.python.nodes.ErrorMessages.IO_S_SHOULD_RETURN_BYTES; import static com.oracle.graal.python.nodes.ErrorMessages.MUST_BE_NON_NEG_OR_NEG_1; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.OSError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; @@ -71,7 +70,10 @@ import java.io.ByteArrayOutputStream; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.modules.io.BufferedIONodes.CheckIsClosedNode; @@ -84,6 +86,8 @@ import com.oracle.graal.python.builtins.objects.bytes.BytesUtils; import com.oracle.graal.python.builtins.objects.bytes.PByteArray; import com.oracle.graal.python.builtins.objects.bytes.PBytes; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.nodes.ErrorMessages; @@ -96,12 +100,11 @@ import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -116,6 +119,9 @@ @CoreFunctions(extendClasses = {PBufferedReader, PBufferedRandom}) public final class BufferedReaderMixinBuiltins extends AbstractBufferedIOBuiltins { + + public static final TpSlots SLOTS = BufferedReaderMixinBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return BufferedReaderMixinBuiltinsFactory.getFactories(); @@ -136,13 +142,13 @@ abstract static class RawReadNode extends PNodeWithContext { // This is the spec way @Specialization static byte[] bufferedreaderRawRead(VirtualFrame frame, Node inliningTarget, PBuffered self, int len, + @Bind PythonLanguage language, @Cached(inline = false) BytesNodes.ToBytesNode toBytes, - @Cached(inline = false) PythonObjectFactory factory, @Cached PyObjectCallMethodObjArgs callMethodReadInto, @Cached PyNumberAsSizeNode asSizeNode, @Cached InlinedConditionProfile osError, - @Cached PRaiseNode.Lazy lazyRaiseNode) { - PByteArray memobj = factory.createByteArray(new byte[len]); + @Cached PRaiseNode lazyRaiseNode) { + PByteArray memobj = PFactory.createByteArray(language, new byte[len]); // TODO _PyIO_trap_eintr [GR-23297] Object res = callMethodReadInto.execute(frame, inliningTarget, self.getRaw(), T_READINTO, memobj); if (res == PNone.NONE) { @@ -153,10 +159,10 @@ static byte[] bufferedreaderRawRead(VirtualFrame frame, Node inliningTarget, PBu try { n = asSizeNode.executeExact(frame, inliningTarget, res, ValueError); } catch (PException e) { - throw lazyRaiseNode.get(inliningTarget).raiseWithCause(OSError, e, ErrorMessages.RAW_READINTO_FAILED); + throw lazyRaiseNode.raiseWithCause(inliningTarget, OSError, e, ErrorMessages.RAW_READINTO_FAILED); } if (osError.profile(inliningTarget, n < 0 || n > len)) { - throw lazyRaiseNode.get(inliningTarget).raise(OSError, IO_S_INVALID_LENGTH, "readinto()", n, len); + throw lazyRaiseNode.raise(inliningTarget, OSError, IO_S_INVALID_LENGTH, "readinto()", n, len); } if (n > 0 && self.getAbsPos() != -1) { self.incAbsPos(n); @@ -250,9 +256,9 @@ public static boolean isReadFast(PBuffered self, int size) { @Specialization(guards = {"self.isOK()", "size == 0"}) Object empty(VirtualFrame frame, PBuffered self, @SuppressWarnings("unused") int size, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { checkIsClosedNode.execute(frame, self); - return factory.createEmptyBytes(); + return PFactory.createEmptyBytes(language); } /* @@ -272,9 +278,9 @@ public static byte[] bufferedreaderReadFast(PBuffered self, int size) { @Specialization(guards = {"self.isOK()", "size > 0", "isReadFast(self, size)"}) Object readFast(VirtualFrame frame, PBuffered self, int size, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { checkIsClosedNode.execute(frame, self); - return factory.createBytes(bufferedreaderReadFast(self, size)); + return PFactory.createBytes(language, bufferedreaderReadFast(self, size)); } /** @@ -284,17 +290,17 @@ Object readFast(VirtualFrame frame, PBuffered self, int size, @SuppressWarnings("truffle-static-method") // checkIsClosedNode Object bufferedreaderReadGeneric(VirtualFrame frame, PBuffered self, int size, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Exclusive @Cached EnterBufferedNode lock, @Cached RawReadNode rawReadNode, @Cached FillBufferNode fillBufferNode, - @Exclusive @Cached FlushAndRewindUnlockedNode flushAndRewindUnlockedNode, - @Shared @Cached PythonObjectFactory factory) { + @Exclusive @Cached FlushAndRewindUnlockedNode flushAndRewindUnlockedNode) { checkIsClosedNode.execute(frame, self); try { lock.enter(inliningTarget, self); int currentSize = safeDowncast(self); if (size <= currentSize) { - return factory.createBytes(bufferedreaderReadFast(self, size)); + return PFactory.createBytes(language, bufferedreaderReadFast(self, size)); } byte[] res = new byte[size]; int remaining = size; @@ -328,7 +334,7 @@ If we had readv() we could do this in one pass. */ if (r == 0 || r == -2) { /* EOF occurred */ if (r == 0 || written > 0) { - return factory.createBytes(PythonUtils.arrayCopyOf(res, written)); + return PFactory.createBytes(language, PythonUtils.arrayCopyOf(res, written)); } return PNone.NONE; } @@ -347,7 +353,7 @@ reads, which could block indefinitely (e.g. on a socket). if (r == 0 || r == -2) { /* EOF occurred */ if (r == 0 || written > 0) { - return factory.createBytes(PythonUtils.arrayCopyOf(res, written)); + return PFactory.createBytes(language, PythonUtils.arrayCopyOf(res, written)); } return PNone.NONE; } @@ -369,7 +375,7 @@ reads, which could block indefinitely (e.g. on a socket). } } - return factory.createBytes(res); + return PFactory.createBytes(language, res); } finally { EnterBufferedNode.leave(self); } @@ -384,6 +390,7 @@ reads, which could block indefinitely (e.g. on a socket). @SuppressWarnings("truffle-static-method") // checkIsClosedNode Object bufferedreaderReadAll(VirtualFrame frame, PBuffered self, @SuppressWarnings("unused") int size, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Exclusive @Cached EnterBufferedNode lock, @Exclusive @Cached FlushAndRewindUnlockedNode flushAndRewindUnlockedNode, @Cached("create(T_READALL)") LookupAttributeInMRONode readallAttr, @@ -393,8 +400,7 @@ Object bufferedreaderReadAll(VirtualFrame frame, PBuffered self, @SuppressWarnin @Cached GetClassNode getClassNode, @Cached PyObjectCallMethodObjArgs callMethod, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Shared @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { checkIsClosedNode.execute(frame, self); try { lock.enter(inliningTarget, self); @@ -418,7 +424,7 @@ Object bufferedreaderReadAll(VirtualFrame frame, PBuffered self, @SuppressWarnin if (hasReadallProfile.profile(inliningTarget, readall != PNone.NO_VALUE)) { Object tmp = dispatchGetattribute.executeObject(frame, readall, self.getRaw()); if (tmp != PNone.NONE && !(tmp instanceof PBytes)) { - throw raiseNode.get(inliningTarget).raise(TypeError, IO_S_SHOULD_RETURN_BYTES, "readall()"); + throw raiseNode.raise(inliningTarget, TypeError, IO_S_SHOULD_RETURN_BYTES, "readall()"); } if (currentSize0Profile.profile(inliningTarget, currentSize != 0)) { if (tmp != PNone.NONE) { @@ -426,9 +432,9 @@ Object bufferedreaderReadAll(VirtualFrame frame, PBuffered self, @SuppressWarnin byte[] res = new byte[data.length + bytesLen]; PythonUtils.arraycopy(data, 0, res, 0, data.length); bufferLib.readIntoByteArray(tmp, 0, res, data.length, bytesLen); - return factory.createBytes(res); + return PFactory.createBytes(language, res); } - return factory.createBytes(data); + return PFactory.createBytes(language, data); } else { return tmp; } @@ -446,7 +452,7 @@ Object bufferedreaderReadAll(VirtualFrame frame, PBuffered self, @SuppressWarnin /* Read until EOF or until read() would block. */ Object r = callMethod.execute(frame, inliningTarget, self.getRaw(), T_READ); if (r != PNone.NONE && !(r instanceof PBytes)) { - throw raiseNode.get(inliningTarget).raise(TypeError, IO_S_SHOULD_RETURN_BYTES, "read()"); + throw raiseNode.raise(inliningTarget, TypeError, IO_S_SHOULD_RETURN_BYTES, "read()"); } if (r != PNone.NONE) { dataLen = bufferLib.getBufferLength(r); @@ -456,7 +462,7 @@ Object bufferedreaderReadAll(VirtualFrame frame, PBuffered self, @SuppressWarnin if (currentSize == 0) { return r; } else { - return factory.createBytes(toByteArray(chunks)); + return PFactory.createBytes(language, toByteArray(chunks)); } } currentSize += dataLen; @@ -472,8 +478,8 @@ Object bufferedreaderReadAll(VirtualFrame frame, PBuffered self, @SuppressWarnin @SuppressWarnings("unused") @Specialization(guards = {"self.isOK()", "!isValidSize(size)"}) static Object initError(VirtualFrame frame, PBuffered self, int size, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, MUST_BE_NON_NEG_OR_NEG_1); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, MUST_BE_NON_NEG_OR_NEG_1); } } @@ -490,10 +496,10 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(guards = "self.isOK()") static PBytes doit(VirtualFrame frame, PBuffered self, int size, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached EnterBufferedNode lock, @Cached("create(T_READ)") CheckIsClosedNode checkIsClosedNode, - @Cached RawReadNode rawReadNode, - @Cached PythonObjectFactory factory) { + @Cached RawReadNode rawReadNode) { checkIsClosedNode.execute(frame, self); int n = size; if (n < 0) { @@ -501,7 +507,7 @@ static PBytes doit(VirtualFrame frame, PBuffered self, int size, } if (n == 0) { - return factory.createEmptyBytes(); + return PFactory.createEmptyBytes(language); } /*- Return up to n bytes. If at least one byte is buffered, we only return buffered bytes. Otherwise, we do one raw read. */ @@ -510,13 +516,13 @@ static PBytes doit(VirtualFrame frame, PBuffered self, int size, if (have > 0) { n = have < n ? have : n; byte[] b = ReadNode.bufferedreaderReadFast(self, n); - return factory.createBytes(b); + return PFactory.createBytes(language, b); } try { lock.enter(inliningTarget, self); self.resetRead(); // _bufferedreader_reset_buf byte[] fill = rawReadNode.execute(frame, inliningTarget, self, n); - return factory.createBytes(fill == BLOCKED ? PythonUtils.EMPTY_BYTE_ARRAY : fill); + return PFactory.createBytes(language, fill == BLOCKED ? PythonUtils.EMPTY_BYTE_ARRAY : fill); } finally { EnterBufferedNode.leave(self); } @@ -748,12 +754,12 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(guards = "self.isOK()") static PBytes doit(VirtualFrame frame, PBuffered self, int size, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached("create(T_READLINE)") CheckIsClosedNode checkIsClosedNode, - @Cached BufferedReadlineNode readlineNode, - @Cached PythonObjectFactory factory) { + @Cached BufferedReadlineNode readlineNode) { checkIsClosedNode.execute(frame, self); byte[] res = readlineNode.execute(frame, inliningTarget, self, size); - return factory.createBytes(res); + return PFactory.createBytes(language, res); } } @@ -796,42 +802,40 @@ static byte[] bufferedreaderPeekUnlocked(VirtualFrame frame, Node inliningTarget @Specialization(guards = "self.isOK()") static Object doit(VirtualFrame frame, PBuffered self, @SuppressWarnings("unused") int size, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached EnterBufferedNode lock, @Cached("create(T_PEEK)") CheckIsClosedNode checkIsClosedNode, @Cached FillBufferNode fillBufferNode, - @Cached FlushAndRewindUnlockedNode flushAndRewindUnlockedNode, - @Cached PythonObjectFactory factory) { + @Cached FlushAndRewindUnlockedNode flushAndRewindUnlockedNode) { checkIsClosedNode.execute(frame, self); try { lock.enter(inliningTarget, self); if (self.isWritable()) { flushAndRewindUnlockedNode.execute(frame, inliningTarget, self); } - return factory.createBytes(bufferedreaderPeekUnlocked(frame, inliningTarget, self, fillBufferNode)); + return PFactory.createBytes(language, bufferedreaderPeekUnlocked(frame, inliningTarget, self, fillBufferNode)); } finally { EnterBufferedNode.leave(self); } } } - @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iternext, isComplex = true) @ImportStatic(IONodes.class) @GenerateNodeFactory abstract static class NextNode extends PythonUnaryWithInitErrorBuiltinNode { @Specialization(guards = "self.isOK()") - static PBytes doit(VirtualFrame frame, PBuffered self, + static Object doit(VirtualFrame frame, PBuffered self, @Bind("this") Node inliningTarget, @Cached("create(T_READLINE)") CheckIsClosedNode checkIsClosedNode, - @Cached BufferedReadlineNode readlineNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached BufferedReadlineNode readlineNode) { checkIsClosedNode.execute(frame, self); byte[] line = readlineNode.execute(frame, inliningTarget, self, -1); if (line.length == 0) { - throw raiseNode.get(inliningTarget).raiseStopIteration(); + throw TpIterNextBuiltin.iteratorExhausted(); } - return factory.createBytes(line); + return PFactory.createBytes(PythonLanguage.get(inliningTarget), line); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedWriterBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedWriterBuiltins.java index ac47b999fe..712c1d9d2c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedWriterBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedWriterBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,20 +41,24 @@ package com.oracle.graal.python.builtins.modules.io; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PBufferedWriter; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import java.util.List; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.modules.io.IOBaseBuiltins.CheckBoolMethodHelperNode; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; import com.oracle.graal.python.runtime.PosixSupportLibrary; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; @@ -67,19 +71,35 @@ @CoreFunctions(extendClasses = PBufferedWriter) public final class BufferedWriterBuiltins extends AbstractBufferedIOBuiltins { + + public static final TpSlots SLOTS = BufferedWriterBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return BufferedWriterBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "BufferedWriter", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class BufferedWriterNode extends PythonBuiltinNode { + @Specialization + static PBuffered doNew(Object cls, @SuppressWarnings("unused") Object arg, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + // data filled in subsequent __init__ call - see BufferedWriterBuiltins.InitNode + return PFactory.createBufferedWriter(language, cls, getInstanceShape.execute(cls)); + } + } + @GenerateInline @GenerateCached(false) public abstract static class BufferedWriterInit extends Node { - public abstract void execute(VirtualFrame frame, Node inliningTarget, PBuffered self, Object raw, int bufferSize, PythonObjectFactory factory); + public abstract void execute(VirtualFrame frame, Node inliningTarget, PBuffered self, Object raw, int bufferSize); @Specialization - static void doInit(VirtualFrame frame, @SuppressWarnings("unused") Node ignored, PBuffered self, Object raw, int bufferSize, PythonObjectFactory factory, + static void doInit(VirtualFrame frame, @SuppressWarnings("unused") Node ignored, PBuffered self, Object raw, int bufferSize, @Bind("this") Node inliningTarget, @Cached CheckBoolMethodHelperNode checkWritableNode, @Cached BufferedInitNode bufferedInitNode, @@ -89,18 +109,18 @@ static void doInit(VirtualFrame frame, @SuppressWarnings("unused") Node ignored, self.setDetached(false); checkWritableNode.checkWriteable(frame, inliningTarget, raw); self.setRaw(raw, isFileIO(self, raw, PBufferedWriter, inliningTarget, getSelfClass, getRawClass)); - bufferedInitNode.execute(frame, inliningTarget, self, bufferSize, factory); + bufferedInitNode.execute(frame, inliningTarget, self, bufferSize); self.resetWrite(); self.setPos(0); self.setOK(true); } - public static void internalInit(PBuffered self, PFileIO raw, int bufferSize, PythonObjectFactory factory, + public static void internalInit(PBuffered self, PFileIO raw, int bufferSize, PythonLanguage language, Object posixSupport, PosixSupportLibrary posixLib) { self.setDetached(false); self.setRaw(raw, true); - BufferedInitNode.internalInit(self, bufferSize, factory, posixSupport, posixLib); + BufferedInitNode.internalInit(self, bufferSize, language, posixSupport, posixLib); self.resetWrite(); self.setPos(0); self.setOK(true); @@ -109,17 +129,17 @@ public static void internalInit(PBuffered self, PFileIO raw, int bufferSize, Pyt } // BufferedWriter(raw[, buffer_size=DEFAULT_BUFFER_SIZE]) - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 2, parameterNames = {"self", "raw", "buffer_size"}, raiseErrorName = "BufferedWriter") + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "BufferedWriter", minNumOfPositionalArgs = 2, parameterNames = {"self", "raw", "buffer_size"}) @GenerateNodeFactory public abstract static class InitNode extends PythonBuiltinNode { @Specialization static Object doIt(VirtualFrame frame, PBuffered self, Object raw, Object bufferSize, @Bind("this") Node inliningTarget, @Cached InitBufferSizeNode initBufferSizeNode, - @Cached BufferedWriterInit init, - @Cached PythonObjectFactory factory) { + @Cached BufferedWriterInit init) { int size = initBufferSizeNode.execute(frame, inliningTarget, bufferSize); - init.execute(frame, inliningTarget, self, raw, size, factory); + init.execute(frame, inliningTarget, self, raw, size); return PNone.NONE; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedWriterNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedWriterNodes.java index baebfde434..30404126c1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedWriterNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedWriterNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -51,6 +51,7 @@ import static com.oracle.graal.python.runtime.exception.PythonErrorType.OSError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; @@ -63,7 +64,7 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -223,11 +224,11 @@ abstract static class RawWriteNode extends PNodeWithContext { */ @Specialization static int bufferedwriterRawWrite(VirtualFrame frame, Node inliningTarget, PBuffered self, byte[] buf, int len, - @Cached(inline = false) PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached PyObjectCallMethodObjArgs callMethod, @Cached PyNumberAsSizeNode asSizeNode, - @Cached PRaiseNode.Lazy lazyRaiseNode) { - PBytes memobj = factory.createBytes(buf, len); + @Cached PRaiseNode lazyRaiseNode) { + PBytes memobj = PFactory.createBytes(language, buf, len); Object res = callMethod.execute(frame, inliningTarget, self.getRaw(), T_WRITE, memobj); if (res == PNone.NONE) { /* @@ -237,7 +238,7 @@ static int bufferedwriterRawWrite(VirtualFrame frame, Node inliningTarget, PBuff } int n = asSizeNode.executeExact(frame, inliningTarget, res, ValueError); if (n < 0 || n > len) { - throw lazyRaiseNode.get(inliningTarget).raise(OSError, IO_S_INVALID_LENGTH, "write()", n, len); + throw lazyRaiseNode.raise(inliningTarget, OSError, IO_S_INVALID_LENGTH, "write()", n, len); } if (n > 0 && self.getAbsPos() != -1) { self.incAbsPos(n); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java index a04992337d..0177ac5eb1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,7 +41,6 @@ package com.oracle.graal.python.builtins.modules.io; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.OverflowError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PBytesIOBuf; import static com.oracle.graal.python.builtins.modules.io.BufferedIOUtil.SEEK_CUR; import static com.oracle.graal.python.builtins.modules.io.BufferedIOUtil.SEEK_END; import static com.oracle.graal.python.builtins.modules.io.BufferedIOUtil.SEEK_SET; @@ -74,15 +73,17 @@ import static com.oracle.graal.python.nodes.ErrorMessages.SECOND_ITEM_OF_STATE_MUST_BE_AN_INTEGER_NOT_P; import static com.oracle.graal.python.nodes.ErrorMessages.THIRD_ITEM_OF_STATE_SHOULD_BE_A_DICT_GOT_A_P; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETSTATE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -97,24 +98,27 @@ import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetInternalObjectArrayNode; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyIndexCheckNode; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyMemoryViewFromObject; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; import com.oracle.graal.python.runtime.IndirectCallData; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.ArrayBuilder; import com.oracle.graal.python.util.PythonUtils; @@ -133,6 +137,8 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PBytesIO) public final class BytesIOBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = BytesIOBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return BytesIOBuiltinsFactory.getFactories(); @@ -142,8 +148,8 @@ abstract static class ClosedCheckPythonUnaryBuiltinNode extends PythonUnaryBuilt @Specialization(guards = "!self.hasBuf()") @SuppressWarnings("unused") static Object closedError(PBytesIO self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } @@ -151,8 +157,8 @@ abstract static class ClosedCheckPythonBinaryBuiltinNode extends PythonBinaryBui @Specialization(guards = "!self.hasBuf()") @SuppressWarnings("unused") static Object closedError(PBytesIO self, Object arg, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } @@ -166,14 +172,30 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(guards = "!self.hasBuf()") @SuppressWarnings("unused") static Object closedError(PBytesIO self, Object arg, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } protected static final byte[] EMPTY_BYTE_ARRAY = PythonUtils.EMPTY_BYTE_ARRAY; - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self", "initial_bytes"}) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "BytesIO", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class BytesIONode extends PythonBuiltinNode { + @Specialization + static PBytesIO doNew(Object cls, @SuppressWarnings("unused") Object arg, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + // data filled in subsequent __init__ call - see BytesIONodeBuiltins.InitNode + PBytesIO bytesIO = PFactory.createBytesIO(language, cls, getInstanceShape.execute(cls)); + bytesIO.setBuf(PFactory.createByteArray(language, PythonUtils.EMPTY_BYTE_ARRAY)); + return bytesIO; + } + } + + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "BytesIO", minNumOfPositionalArgs = 1, parameterNames = {"$self", "initial_bytes"}) @GenerateNodeFactory public abstract static class InitNode extends PythonBinaryBuiltinNode { @@ -181,7 +203,7 @@ public abstract static class InitNode extends PythonBinaryBuiltinNode { @SuppressWarnings("unused") static PNone init(PBytesIO self, PNone initvalue, @Bind("this") Node inliningTarget, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { self.checkExports(inliningTarget, raiseNode); self.setPos(0); return PNone.NONE; @@ -191,7 +213,7 @@ static PNone init(PBytesIO self, PNone initvalue, static PNone init(VirtualFrame frame, PBytesIO self, Object initvalue, @Bind("this") Node inliningTarget, @Cached WriteNode writeNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { /* In case, __init__ is called multiple times. */ self.setStringSize(0); self.setPos(0); @@ -204,9 +226,9 @@ static PNone init(VirtualFrame frame, PBytesIO self, Object initvalue, static PBytes readBytes(PBytesIO self, int size, PythonBufferAccessLibrary bufferLib, - PythonObjectFactory factory) { + PythonLanguage language) { if (size == 0) { - return factory.createEmptyBytes(); + return PFactory.createEmptyBytes(language); } assert (size <= self.getStringSize()); @@ -214,10 +236,10 @@ static PBytes readBytes(PBytesIO self, int size, if (self.getPos() == 0 && bufferLib.hasInternalByteArray(buffer) && self.getExports() == 0 && size > bufferLib.getBufferLength(buffer) / 2) { self.incPos(size); self.markEscaped(); - return factory.createBytes(bufferLib.getInternalByteArray(buffer), size); + return PFactory.createBytes(language, bufferLib.getInternalByteArray(buffer), size); } - PBytes output = factory.createBytes(bufferLib.getCopyOfRange(buffer, self.getPos(), self.getPos() + size)); + PBytes output = PFactory.createBytes(language, bufferLib.getCopyOfRange(buffer, self.getPos(), self.getPos() + size)); self.incPos(size); return output; } @@ -234,8 +256,8 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(guards = "self.hasBuf()") static Object read(PBytesIO self, int len, - @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language, + @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) { int size = len; /* adjust invalid sizes */ int n = self.getStringSize() - self.getPos(); @@ -245,7 +267,7 @@ static Object read(PBytesIO self, int len, size = 0; } } - return readBytes(self, size, bufferLib, factory); + return readBytes(self, size, bufferLib, language); } } @@ -311,10 +333,10 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(guards = "self.hasBuf()") Object readline(PBytesIO self, int size, - @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language, + @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) { int n = scanEOL(self, size, bufferLib); - return readBytes(self, n, bufferLib, factory); + return readBytes(self, n, bufferLib, language); } } @@ -330,8 +352,8 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(guards = "self.hasBuf()") static Object readlines(PBytesIO self, int maxsize, - @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language, + @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) { ArrayBuilder result = new ArrayBuilder<>(); int n; @@ -341,7 +363,7 @@ static Object readlines(PBytesIO self, int maxsize, int size = 0; while ((n = scanEOL(self, -1, buf)) != 0) { self.incPos(n); - PBytes line = factory.createBytes(PythonUtils.arrayCopyOfRange(buf, cur, cur + n)); + PBytes line = PFactory.createBytes(language, PythonUtils.arrayCopyOfRange(buf, cur, cur + n)); result.add(line); size += n; if (maxsize > 0 && size >= maxsize) { @@ -349,7 +371,7 @@ static Object readlines(PBytesIO self, int maxsize, } cur += n; } - return factory.createList(result.toArray(new Object[0])); + return PFactory.createList(language, result.toArray(new Object[0])); } } @@ -397,15 +419,15 @@ abstract static class TruncateNode extends ClosedCheckPythonBinaryBuiltinNode { @Specialization(guards = "self.hasBuf()") static Object truncate(PBytesIO self, int size, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Shared("lib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { self.checkExports(inliningTarget, raiseNode); if (size < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, NEGATIVE_SIZE_VALUE_D, size); + throw raiseNode.raise(inliningTarget, ValueError, NEGATIVE_SIZE_VALUE_D, size); } if (size < self.getStringSize()) { - self.unshareAndResize(bufferLib, factory, size, true); + self.unshareAndResize(bufferLib, language, size, true); self.setStringSize(size); } return size; @@ -414,20 +436,20 @@ static Object truncate(PBytesIO self, int size, @Specialization(guards = "self.hasBuf()") static Object truncate(PBytesIO self, @SuppressWarnings("unused") PNone size, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Shared("lib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - return truncate(self, self.getPos(), inliningTarget, bufferLib, factory, raiseNode); + @Shared @Cached PRaiseNode raiseNode) { + return truncate(self, self.getPos(), inliningTarget, language, bufferLib, raiseNode); } @Specialization(guards = {"self.hasBuf()", "!isPNone(size)"}) static Object truncate(VirtualFrame frame, PBytesIO self, Object size, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached PyNumberAsSizeNode asSizeNode, @Shared("lib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - return truncate(self, asSizeNode.executeExact(frame, inliningTarget, size), inliningTarget, bufferLib, factory, raiseNode); + @Exclusive @Cached PRaiseNode raiseNode) { + return truncate(self, asSizeNode.executeExact(frame, inliningTarget, size), inliningTarget, language, bufferLib, raiseNode); } } @@ -438,11 +460,11 @@ abstract static class WriteNode extends ClosedCheckPythonBinaryBuiltinNode { @Specialization(guards = "self.hasBuf()", limit = "3") static Object doWrite(VirtualFrame frame, PBytesIO self, Object b, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("b") PythonBufferAcquireLibrary acquireLib, @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { self.checkExports(inliningTarget, raiseNode); Object buffer = acquireLib.acquireReadonly(b, frame, indirectCallData); try { @@ -452,7 +474,7 @@ static Object doWrite(VirtualFrame frame, PBytesIO self, Object b, } int pos = self.getPos(); int endpos = pos + len; - self.unshareAndResize(bufferLib, factory, endpos, false); + self.unshareAndResize(bufferLib, language, endpos, false); bufferLib.readIntoBuffer(buffer, 0, self.getBuf(), pos, len, bufferLib); self.setPos(endpos); if (endpos > self.getStringSize()) { @@ -471,19 +493,17 @@ abstract static class WriteLinesNode extends ClosedCheckPythonBinaryBuiltinNode @Specialization(guards = "self.hasBuf()") static Object writeLines(VirtualFrame frame, PBytesIO self, Object lines, @Bind("this") Node inliningTarget, - @Cached GetNextNode getNextNode, @Cached WriteNode writeNode, - @Cached IsBuiltinObjectProfile errorProfile, @Cached PyObjectGetIter getIter, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PyIterNextNode nextNode, + @Cached PRaiseNode raiseNode) { self.checkExports(inliningTarget, raiseNode); Object iter = getIter.execute(frame, inliningTarget, lines); while (true) { Object line; try { - line = getNextNode.execute(frame, iter); - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); + line = nextNode.execute(frame, inliningTarget, iter); + } catch (IteratorExhausted e) { break; } writeNode.execute(frame, self, line); @@ -560,35 +580,35 @@ static Object seek(PBytesIO self, int pos, int whence) { @Specialization(guards = {"self.hasBuf()", "!isSupportedWhence(whence)"}) static Object whenceError(@SuppressWarnings("unused") PBytesIO self, @SuppressWarnings("unused") int pos, int whence, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, INVALID_WHENCE_D_SHOULD_BE_0_1_OR_2, whence); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, INVALID_WHENCE_D_SHOULD_BE_0_1_OR_2, whence); } @SuppressWarnings("unused") @Specialization(guards = {"self.hasBuf()", "isLargePos(pos, self.getPos())", "whence == 1"}) static Object largePos1(PBytesIO self, int pos, int whence, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(OverflowError, NEW_POSITION_TOO_LARGE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, OverflowError, NEW_POSITION_TOO_LARGE); } @SuppressWarnings("unused") @Specialization(guards = {"self.hasBuf()", "isLargePos(pos, self.getStringSize())", "whence == 2"}) static Object largePos2(PBytesIO self, int pos, int whence, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(OverflowError, NEW_POSITION_TOO_LARGE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, OverflowError, NEW_POSITION_TOO_LARGE); } @Specialization(guards = {"self.hasBuf()", "pos < 0", "whence == 0"}) static Object negPos(@SuppressWarnings("unused") PBytesIO self, int pos, @SuppressWarnings("unused") int whence, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, NEGATIVE_SEEK_VALUE_D, pos); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, NEGATIVE_SEEK_VALUE_D, pos); } @SuppressWarnings("unused") @Specialization(guards = "!self.hasBuf()") static Object closedError(PBytesIO self, int pos, int whence, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } @@ -599,12 +619,12 @@ abstract static class GetBufferNode extends ClosedCheckPythonUnaryBuiltinNode { static Object doit(VirtualFrame frame, PBytesIO self, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached PyMemoryViewFromObject memoryViewNode, - @Cached SequenceStorageNodes.SetLenNode setLenNode, - @Cached PythonObjectFactory factory) { - self.unshareIfNecessary(bufferLib, factory); + @Cached SequenceStorageNodes.SetLenNode setLenNode) { + self.unshareIfNecessary(bufferLib, language); setLenNode.execute(inliningTarget, self.getBuf().getSequenceStorage(), self.getStringSize()); - PBytesIOBuffer buf = factory.createBytesIOBuf(PBytesIOBuf, self); + PBytesIOBuffer buf = PFactory.createBytesIOBuf(language, self); return memoryViewNode.execute(frame, buf); } } @@ -614,12 +634,12 @@ static Object doit(VirtualFrame frame, PBytesIO self, abstract static class GetValueNode extends ClosedCheckPythonUnaryBuiltinNode { @Specialization(guards = "self.hasBuf()") static Object doCopy(PBytesIO self, - @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language, + @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) { if (bufferLib.hasInternalByteArray(self.getBuf()) && self.getExports() == 0) { self.markEscaped(); } - return factory.createBytes(bufferLib.getInternalOrCopiedByteArray(self.getBuf()), self.getStringSize()); + return PFactory.createBytes(language, bufferLib.getInternalOrCopiedByteArray(self.getBuf()), self.getStringSize()); } } @@ -629,12 +649,12 @@ abstract static class GetStateNode extends ClosedCheckPythonUnaryBuiltinNode { @Specialization(guards = "self.hasBuf()") static Object doit(VirtualFrame frame, PBytesIO self, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached GetValueNode getValueNode, - @Cached GetOrCreateDictNode getDict, - @Cached PythonObjectFactory factory) { + @Cached GetOrCreateDictNode getDict) { Object initValue = getValueNode.execute(frame, self); Object[] state = new Object[]{initValue, self.getPos(), getDict.execute(inliningTarget, self)}; - return factory.createTuple(state); + return PFactory.createTuple(language, state); } } @@ -650,12 +670,12 @@ static Object doit(VirtualFrame frame, PBytesIO self, PTuple state, @Cached PyNumberAsSizeNode asSizeNode, @Cached GetOrCreateDictNode getDict, @Cached HashingStorageAddAllToOther addAllToOtherNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { self.checkExports(inliningTarget, raiseNode); SequenceStorage storage = state.getSequenceStorage(); Object[] array = getArray.execute(inliningTarget, storage); if (storage.length() < 3) { - return notTuple(self, state, raiseNode.get(inliningTarget)); + return notTuple(self, state, raiseNode); } /* * Reset the object to its default state. This is only needed to handle the case of @@ -674,18 +694,18 @@ static Object doit(VirtualFrame frame, PBytesIO self, PTuple state, * against erroneous (or malicious) inputs. */ if (!indexCheckNode.execute(inliningTarget, array[1])) { - throw raiseNode.get(inliningTarget).raise(TypeError, SECOND_ITEM_OF_STATE_MUST_BE_AN_INTEGER_NOT_P, array[1]); + throw raiseNode.raise(inliningTarget, TypeError, SECOND_ITEM_OF_STATE_MUST_BE_AN_INTEGER_NOT_P, array[1]); } int pos = asSizeNode.executeExact(frame, inliningTarget, array[1]); if (pos < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, POSITION_VALUE_CANNOT_BE_NEGATIVE); + throw raiseNode.raise(inliningTarget, ValueError, POSITION_VALUE_CANNOT_BE_NEGATIVE); } self.setPos(pos); /* Set the dictionary of the instance variables. */ if (!PGuards.isNone(array[2])) { if (!PGuards.isDict(array[2])) { - throw raiseNode.get(inliningTarget).raise(TypeError, THIRD_ITEM_OF_STATE_SHOULD_BE_A_DICT_GOT_A_P, array[2]); + throw raiseNode.raise(inliningTarget, TypeError, THIRD_ITEM_OF_STATE_SHOULD_BE_A_DICT_GOT_A_P, array[2]); } /* * Alternatively, we could replace the internal dictionary completely. However, it @@ -699,8 +719,8 @@ static Object doit(VirtualFrame frame, PBytesIO self, PTuple state, @Specialization(guards = "!isPTuple(state)") static Object notTuple(PBytesIO self, Object state, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, P_SETSTATE_ARGUMENT_SHOULD_BE_D_TUPLE_GOT_P, self, 3, state); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, P_SETSTATE_ARGUMENT_SHOULD_BE_D_TUPLE_GOT_P, self, 3, state); } } @@ -761,28 +781,26 @@ abstract static class CloseNode extends PythonUnaryBuiltinNode { @Specialization static Object close(PBytesIO self, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { self.checkExports(inliningTarget, raiseNode); self.setBuf(null); return PNone.NONE; } } - @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iternext, isComplex = true) @GenerateNodeFactory abstract static class IternextNode extends ClosedCheckPythonUnaryBuiltinNode { @Specialization(guards = "self.hasBuf()") static Object doit(PBytesIO self, - @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) { int n = scanEOL(self, -1, bufferLib); if (n == 0) { - throw raiseNode.get(inliningTarget).raiseStopIteration(); + throw TpIterNextBuiltin.iteratorExhausted(); } - return readBytes(self, n, bufferLib, factory); + return readBytes(self, n, bufferLib, language); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/FileIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/FileIOBuiltins.java index 08cb8802bc..f55c42562f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/FileIOBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/FileIOBuiltins.java @@ -86,8 +86,6 @@ import static com.oracle.graal.python.nodes.ErrorMessages.REENTRANT_CALL_INSIDE_P_REPR; import static com.oracle.graal.python.nodes.ErrorMessages.UNBOUNDED_READ_RETURNED_MORE_BYTES; import static com.oracle.graal.python.nodes.ErrorMessages.UNCLOSED_FILE; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.nodes.StringLiterals.T_FALSE; import static com.oracle.graal.python.nodes.StringLiterals.T_TRUE; import static com.oracle.graal.python.runtime.PosixConstants.AT_FDCWD; @@ -106,7 +104,11 @@ import java.io.ByteArrayOutputStream; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -123,18 +125,20 @@ import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyErrChainExceptions; import com.oracle.graal.python.lib.PyIndexCheckNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.lib.PyObjectLookupAttr; +import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode; import com.oracle.graal.python.lib.PyObjectSetAttr; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; @@ -143,7 +147,6 @@ import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.AsyncHandler; import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.IndirectCallData; @@ -152,7 +155,7 @@ import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -182,6 +185,8 @@ public final class FileIOBuiltins extends PythonBuiltins { private static final int SMALLCHUNK = BUFSIZ; + public static final TpSlots SLOTS = FileIOBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return FileIOBuiltinsFactory.getFactories(); @@ -216,6 +221,19 @@ static void internalClose(VirtualFrame frame, PFileIO self, } } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "FileIO", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class FileIONode extends PythonBuiltinNode { + @Specialization + static PFileIO doNew(Object cls, @SuppressWarnings("unused") Object arg, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + // data filled in subsequent __init__ call - see FileIOBuiltins.InitNode + return PFactory.createFileIO(language, cls, getInstanceShape.execute(cls)); + } + } + @GenerateInline @GenerateCached(false) public abstract static class FileIOInit extends Node { @@ -237,11 +255,11 @@ private static int open(VirtualFrame frame, TruffleString name, int flags, int m PosixSupportLibrary posixLib, GilNode gil, InlinedBranchProfile errorProfile, - PRaiseNode.Lazy raiseNode, + PRaiseNode raiseNode, PConstructAndRaiseNode.Lazy constructAndRaiseNode) { Object path = posixLib.createPathFromString(ctxt.getPosixSupport(), name); if (path == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, EMBEDDED_NULL_BYTE); + throw raiseNode.raise(inliningTarget, ValueError, EMBEDDED_NULL_BYTE); } while (true) { try { @@ -311,7 +329,8 @@ public static void internalInit(PFileIO self, TruffleString name, int fd, IOMode @Specialization(guards = {"!isBadMode(mode)", "!isInvalidMode(mode)"}) static void doInit(VirtualFrame frame, Node inliningTarget, PFileIO self, Object nameobj, IONodes.IOMode mode, boolean closefd, Object opener, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached(inline = false) CallNode callOpener, @Cached PyIndexCheckNode indexCheckNode, @Cached PyNumberAsSizeNode asSizeNode, @@ -326,7 +345,7 @@ static void doInit(VirtualFrame frame, Node inliningTarget, PFileIO self, Object @Cached InlinedConditionProfile errorProfile, @Cached(inline = false) GilNode gil, @Cached(inline = false) TruffleString.FromLongNode fromLongNode, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { if (self.getFD() >= 0) { if (self.isCloseFD()) { @@ -350,35 +369,34 @@ static void doInit(VirtualFrame frame, Node inliningTarget, PFileIO self, Object try { boolean fdIsOwn = false; - PythonContext ctxt = PythonContext.get(inliningTarget); if (fd >= 0) { self.setCloseFD(closefd); - self.setFD(fd, ctxt); + self.setFD(fd, context); } else { self.setCloseFD(true); if (errorProfile.profile(inliningTarget, !closefd)) { - throw raiseNode.get(inliningTarget).raise(ValueError, CANNOT_USE_CLOSEFD); + throw raiseNode.raise(inliningTarget, ValueError, CANNOT_USE_CLOSEFD); } if (opener instanceof PNone) { - self.setFD(open(frame, name, flags, 0666, ctxt, inliningTarget, posixLib, gil, exceptionProfile, raiseNode, constructAndRaiseNode), ctxt); + self.setFD(open(frame, name, flags, 0666, context, inliningTarget, posixLib, gil, exceptionProfile, raiseNode, constructAndRaiseNode), context); } else { Object fdobj = callOpener.execute(frame, opener, nameobj, flags); if (!indexCheckNode.execute(inliningTarget, fdobj)) { - throw raiseNode.get(inliningTarget).raise(TypeError, EXPECTED_INT_FROM_OPENER); + throw raiseNode.raise(inliningTarget, TypeError, EXPECTED_INT_FROM_OPENER); } - self.setFD(asSizeNode.executeExact(frame, inliningTarget, fdobj), ctxt); + self.setFD(asSizeNode.executeExact(frame, inliningTarget, fdobj), context); if (self.getFD() < 0) { /* * The opener returned a negative but didn't set an exception. See issue * #27066 */ - throw raiseNode.get(inliningTarget).raise(ValueError, OPENER_RETURNED_D, self.getFD()); + throw raiseNode.raise(inliningTarget, ValueError, OPENER_RETURNED_D, self.getFD()); } } try { - posixLib.setInheritable(ctxt.getPosixSupport(), self.getFD(), false); + posixLib.setInheritable(context.getPosixSupport(), self.getFD(), false); } catch (PosixException e) { exceptionProfile1.enter(inliningTarget); throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); @@ -390,7 +408,7 @@ static void doInit(VirtualFrame frame, Node inliningTarget, PFileIO self, Object long[] fstatResult; gil.release(true); try { - fstatResult = posixLib.fstat(ctxt.getPosixSupport(), self.getFD()); + fstatResult = posixLib.fstat(context.getPosixSupport(), self.getFD()); } finally { gil.acquire(); } @@ -428,7 +446,7 @@ static void doInit(VirtualFrame frame, Node inliningTarget, PFileIO self, Object try { gil.release(true); try { - long res = posixLib.lseek(ctxt.getPosixSupport(), self.getFD(), 0, mapPythonSeekWhenceToPosix(SEEK_END)); + long res = posixLib.lseek(context.getPosixSupport(), self.getFD(), 0, mapPythonSeekWhenceToPosix(SEEK_END)); self.setSeekable(res >= 0 ? 1 : 0); } finally { gil.acquire(); @@ -460,20 +478,21 @@ static void doInit(VirtualFrame frame, Node inliningTarget, PFileIO self, Object @Specialization(guards = "isInvalidMode(mode)") static void invalidMode(@SuppressWarnings("unused") PFileIO self, @SuppressWarnings("unused") Object nameobj, IONodes.IOMode mode, @SuppressWarnings("unused") boolean closefd, @SuppressWarnings("unused") Object opener, - @Shared @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, INVALID_MODE_S, mode.mode); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, INVALID_MODE_S, mode.mode); } @SuppressWarnings("unused") @Specialization(guards = "isBadMode(mode)") static void badMode(PFileIO self, Object nameobj, IONodes.IOMode mode, boolean closefd, Object opener, - @Shared @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, BAD_MODE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, BAD_MODE); } } // FileIO(name, mode='r', closefd=True, opener=None) - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 2, parameterNames = {"$self", "name", "mode", "closefd", "opener"}) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "FileIO", minNumOfPositionalArgs = 2, parameterNames = {"$self", "name", "mode", "closefd", "opener"}) // "mode" should not have `null` character @ArgumentClinic(name = "mode", conversionClass = IONodes.CreateIOModeNode.class, args = "false") @ArgumentClinic(name = "closefd", conversion = ArgumentClinic.ClinicConversion.Boolean, defaultValue = "true", useDefaultForNone = true) @@ -513,22 +532,21 @@ static Object readall(VirtualFrame frame, PFileIO self, @SuppressWarnings("unuse @Specialization(guards = {"!self.isClosed()", "self.isReadable()", "size == 0"}) static Object none(@SuppressWarnings("unused") PFileIO self, @SuppressWarnings("unused") int size, - @Shared @Cached PythonObjectFactory factory) { - return factory.createEmptyBytes(); + @Bind PythonLanguage language) { + return PFactory.createEmptyBytes(language); } @Specialization(guards = {"!self.isClosed()", "self.isReadable()", "size >= 0"}) static Object read(VirtualFrame frame, PFileIO self, int size, @Bind("this") Node inliningTarget, - @Cached PosixModuleBuiltins.ReadNode posixRead, @Cached InlinedBranchProfile readErrorProfile, @Cached InlinedBranchProfile readErrorProfile2, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached GilNode gil, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Shared @Cached PythonObjectFactory factory) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { - return posixRead.read(self.getFD(), size, inliningTarget, posixLib, readErrorProfile, gil, factory); + return PosixModuleBuiltins.ReadNode.read(self.getFD(), size, inliningTarget, posixLib, context.getPosixSupport(), readErrorProfile, gil); } catch (PosixException e) { if (e.getErrorCode() == EAGAIN.getNumber()) { readErrorProfile2.enter(inliningTarget); @@ -540,14 +558,14 @@ static Object read(VirtualFrame frame, PFileIO self, int size, @Specialization(guards = {"!self.isClosed()", "!self.isReadable()"}) static Object notReadable(@SuppressWarnings("unused") PFileIO self, @SuppressWarnings("unused") int size, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, FILE_NOT_OPEN_FOR_S, "reading"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, FILE_NOT_OPEN_FOR_S, "reading"); } @Specialization(guards = "self.isClosed()") static Object closedError(@SuppressWarnings("unused") PFileIO self, @SuppressWarnings("unused") int size, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } @@ -558,15 +576,14 @@ abstract static class ReadallNode extends PythonUnaryBuiltinNode { @Specialization(guards = "!self.isClosed()") static Object readall(VirtualFrame frame, PFileIO self, @Bind("this") Node inliningTarget, - @Cached PosixModuleBuiltins.ReadNode posixRead, @Cached InlinedBranchProfile readErrorProfile, @Cached SequenceStorageNodes.GetInternalByteArrayNode getBytes, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached InlinedBranchProfile multipleReadsProfile, @Cached GilNode gil, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int bufsize = SMALLCHUNK; boolean mayBeQuick = false; try { @@ -591,7 +608,7 @@ static Object readall(VirtualFrame frame, PFileIO self, int bytesRead = 0; PBytes b; try { - b = posixRead.read(self.getFD(), bufsize, inliningTarget, posixLib, readErrorProfile, gil, factory); + b = PosixModuleBuiltins.ReadNode.read(self.getFD(), bufsize, inliningTarget, posixLib, context.getPosixSupport(), readErrorProfile, gil); bytesRead = b.getSequenceStorage().length(); if (bytesRead == 0 || (mayBeQuick && bytesRead == bufsize - 1)) { return b; @@ -613,13 +630,13 @@ static Object readall(VirtualFrame frame, PFileIO self, // see CPython's function 'fileio.c: new_buffersize' bufsize = bytesRead + Math.max(SMALLCHUNK, bytesRead + 256); if (bufsize <= 0) { - throw raiseNode.get(inliningTarget).raise(OverflowError, UNBOUNDED_READ_RETURNED_MORE_BYTES); + throw raiseNode.raise(inliningTarget, OverflowError, UNBOUNDED_READ_RETURNED_MORE_BYTES); } } int n; try { - b = posixRead.read(self.getFD(), bufsize - bytesRead, inliningTarget, posixLib, readErrorProfile, gil, factory); + b = PosixModuleBuiltins.ReadNode.read(self.getFD(), bufsize - bytesRead, inliningTarget, posixLib, context.getPosixSupport(), readErrorProfile, gil); /* * PosixModuleBuiltins#ReadNode creates PBytes with exact size; */ @@ -642,13 +659,13 @@ static Object readall(VirtualFrame frame, PFileIO self, bytesRead += n; } - return factory.createBytes(toByteArray(result)); + return PFactory.createBytes(PythonLanguage.get(inliningTarget), toByteArray(result)); } @Specialization(guards = "self.isClosed()") static Object closedError(@SuppressWarnings("unused") PFileIO self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } @@ -662,19 +679,18 @@ static Object readinto(VirtualFrame frame, PFileIO self, Object buffer, @Bind("this") Node inliningTarget, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached PosixModuleBuiltins.ReadNode posixRead, @Cached InlinedBranchProfile readErrorProfile, - @CachedLibrary(limit = "1") PosixSupportLibrary posixLib, + @Bind PythonContext context, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached GilNode gil, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { try { int size = bufferLib.getBufferLength(buffer); if (size == 0) { return 0; } try { - PBytes data = posixRead.read(self.getFD(), size, inliningTarget, posixLib, readErrorProfile, gil, factory); + PBytes data = PosixModuleBuiltins.ReadNode.read(self.getFD(), size, inliningTarget, posixLib, context.getPosixSupport(), readErrorProfile, gil); int n = bufferLib.getBufferLength(data); bufferLib.readIntoBuffer(data, 0, buffer, 0, n, bufferLib); return n; @@ -692,15 +708,15 @@ static Object readinto(VirtualFrame frame, PFileIO self, Object buffer, @SuppressWarnings("unused") @Specialization(guards = {"!self.isClosed()", "!self.isReadable()"}) static Object notReadable(PFileIO self, Object buffer, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, FILE_NOT_OPEN_FOR_S, "reading"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, FILE_NOT_OPEN_FOR_S, "reading"); } @SuppressWarnings("unused") @Specialization(guards = "self.isClosed()") static Object closedError(PFileIO self, Object buffer, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } @Override @@ -717,22 +733,23 @@ public abstract static class WriteNode extends PythonBinaryClinicBuiltinNode { @Specialization(limit = "3") static Object write(VirtualFrame frame, PFileIO self, Object buffer, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib, @Cached InlinedBranchProfile errorProfile, @Cached GilNode gil, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { if (self.isClosed()) { - throw raiseNode.get(inliningTarget).raise(ValueError, IO_CLOSED); + throw raiseNode.raise(inliningTarget, ValueError, IO_CLOSED); } if (!self.isWritable()) { - throw raiseNode.get(inliningTarget).raise(IOUnsupportedOperation, FILE_NOT_OPEN_FOR_S, "writing"); + throw raiseNode.raise(inliningTarget, IOUnsupportedOperation, FILE_NOT_OPEN_FOR_S, "writing"); } try { return PosixModuleBuiltins.WriteNode.write(self.getFD(), bufferLib.getInternalOrCopiedByteArray(buffer), bufferLib.getBufferLength(buffer), - inliningTarget, posixLib, errorProfile, gil); + inliningTarget, posixLib, context.getPosixSupport(), errorProfile, gil); } catch (PosixException e) { if (e.getErrorCode() == EAGAIN.getNumber()) { return PNone.NONE; @@ -780,8 +797,8 @@ Object seek(VirtualFrame frame, PFileIO self, long pos, int whence, @Specialization(guards = "self.isClosed()") static Object closedError(@SuppressWarnings("unused") PFileIO self, @SuppressWarnings("unused") Object pos, @SuppressWarnings("unused") int whence, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } protected static long internalSeek(PFileIO self, long pos, int whence, @@ -852,15 +869,15 @@ static Object none(VirtualFrame frame, PFileIO self, @SuppressWarnings("unused") @SuppressWarnings("unused") @Specialization(guards = {"!self.isClosed()", "!self.isWritable()"}) static Object notWritable(PFileIO self, Object posobj, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, FILE_NOT_OPEN_FOR_S, "writing"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, FILE_NOT_OPEN_FOR_S, "writing"); } @SuppressWarnings("unused") @Specialization(guards = "self.isClosed()") static Object closedError(PFileIO self, Object posobj, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } @@ -960,8 +977,8 @@ static Object known(PFileIO self) { @Specialization(guards = "self.isClosed()") static Object closedError(@SuppressWarnings("unused") PFileIO self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } @@ -975,8 +992,8 @@ static Object readable(PFileIO self) { @Specialization(guards = "self.isClosed()") static Object closedError(@SuppressWarnings("unused") PFileIO self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } @@ -990,8 +1007,8 @@ static Object writable(PFileIO self) { @Specialization(guards = "self.isClosed()") static Object closedError(@SuppressWarnings("unused") PFileIO self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } @@ -1005,8 +1022,8 @@ static Object fileno(PFileIO self) { @Specialization(guards = "self.isClosed()") static Object closedError(@SuppressWarnings("unused") PFileIO self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } @@ -1027,8 +1044,8 @@ boolean isatty(@SuppressWarnings("unused") PFileIO self, @Specialization(guards = "self.isClosed()") static boolean closedError(@SuppressWarnings("unused") PFileIO self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } @@ -1124,7 +1141,7 @@ static Object doit(VirtualFrame frame, PFileIO self, Object v, } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { @@ -1139,10 +1156,9 @@ static TruffleString doit(@SuppressWarnings("unused") PFileIO self) { static TruffleString doit(VirtualFrame frame, PFileIO self, @Bind("this") Node inliningTarget, @Cached PyObjectLookupAttr lookupName, - @Cached("create(Repr)") LookupAndCallUnaryNode repr, - @Cached CastToTruffleStringNode castToTruffleStringNode, + @Cached PyObjectReprAsTruffleStringNode repr, @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleString mode = ModeNode.modeString(self); TruffleString closefd = self.isCloseFD() ? T_TRUE : T_FALSE; Object nameobj = lookupName.execute(frame, inliningTarget, self, T_NAME); @@ -1150,10 +1166,10 @@ static TruffleString doit(VirtualFrame frame, PFileIO self, return simpleTruffleStringFormatNode.format("<_io.FileIO fd=%d mode='%s' closefd=%s>", self.getFD(), mode, closefd); } if (!PythonContext.get(inliningTarget).reprEnter(self)) { - throw raiseNode.get(inliningTarget).raise(RuntimeError, REENTRANT_CALL_INSIDE_P_REPR, self); + throw raiseNode.raise(inliningTarget, RuntimeError, REENTRANT_CALL_INSIDE_P_REPR, self); } try { - TruffleString name = castToTruffleStringNode.execute(inliningTarget, repr.executeObject(frame, nameobj)); + TruffleString name = repr.execute(frame, inliningTarget, nameobj); return simpleTruffleStringFormatNode.format("<_io.FileIO name=%s mode='%s' closefd=%s>", name, mode, closefd); } finally { PythonContext.get(inliningTarget).reprLeave(self); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IOBaseBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IOBaseBuiltins.java index c6fe4327e0..5ae86a28df 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IOBaseBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IOBaseBuiltins.java @@ -77,8 +77,6 @@ import static com.oracle.graal.python.nodes.SpecialMethodNames.J_FILENO; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ENTER__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EXIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T_FILENO; import static com.oracle.graal.python.runtime.exception.PythonErrorType.IOUnsupportedOperation; import static com.oracle.graal.python.runtime.exception.PythonErrorType.OSError; @@ -87,7 +85,11 @@ import java.io.ByteArrayOutputStream; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -96,8 +98,12 @@ import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyErrChainExceptions; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.lib.PyObjectGetIter; @@ -115,10 +121,9 @@ import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.IsNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.ArrayBuilder; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.dsl.Bind; @@ -139,6 +144,7 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PIOBase) public final class IOBaseBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = IOBaseBuiltinsSlotsGen.SLOTS; // taken from usr/include/stdio.h public static final int BUFSIZ = 8192; @@ -148,6 +154,18 @@ protected List> getNodeFa return IOBaseBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "_IOBase", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class IOBaseNode extends PythonBuiltinNode { + @Specialization + static PythonObject doGeneric(Object cls, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + return PFactory.createPythonObject(language, cls, getInstanceShape.execute(cls)); + } + } + @Builtin(name = J_CLOSED, minNumOfPositionalArgs = 1, isGetter = true) @GenerateNodeFactory abstract static class ClosedNode extends PythonUnaryBuiltinNode { @@ -200,9 +218,9 @@ abstract static class CheckClosedHelperNode extends Node { static PNone doIt(VirtualFrame frame, Node inliningTarget, PythonObject self, @Cached PyObjectGetAttr getAttr, @Cached PyObjectIsTrueNode isTrueNode, - @Cached PRaiseNode.Lazy lazyRaiseNode) { + @Cached PRaiseNode raiseNode) { if (isTrueNode.execute(frame, getAttr.execute(frame, inliningTarget, self, T_CLOSED))) { - throw lazyRaiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.IO_CLOSED); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.IO_CLOSED); } return PNone.NONE; } @@ -241,14 +259,14 @@ final boolean checkReadable(VirtualFrame frame, Node inliningTarget, Object self static boolean doIt(VirtualFrame frame, Node inliningTarget, Object self, TruffleString method, TruffleString errorMessage, @Cached PyObjectCallMethodObjArgs callMethod, @Cached(inline = false) IsNode isNode, - @Cached PRaiseNode.Lazy lazyRaiseNode) { + @Cached PRaiseNode raiseNode) { CompilerAsserts.partialEvaluationConstant(method); CompilerAsserts.partialEvaluationConstant(errorMessage); Object v = callMethod.execute(frame, inliningTarget, self, method); if (isNode.isTrue(v)) { return true; } - throw unsupported(lazyRaiseNode.get(inliningTarget), errorMessage); + throw unsupported(inliningTarget, raiseNode, errorMessage); } } @@ -323,9 +341,9 @@ abstract static class FlushNode extends PythonUnaryBuiltinNode { static PNone flush(VirtualFrame frame, PythonObject self, @Bind("this") Node inliningTarget, @Cached PyObjectLookupAttr lookup, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (isClosed(inliningTarget, self, frame, lookup)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.IO_CLOSED); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.IO_CLOSED); } return PNone.NONE; } @@ -336,8 +354,9 @@ static PNone flush(VirtualFrame frame, PythonObject self, abstract static class SeekNode extends PythonBuiltinNode { @Specialization static Object seek(@SuppressWarnings("unused") PythonObject self, @SuppressWarnings("unused") Object args, + @Bind("this") Node inliningTarget, @Cached PRaiseNode raiseNode) { - throw unsupported(raiseNode, T_SEEK); + throw unsupported(inliningTarget, raiseNode, T_SEEK); } } @@ -346,8 +365,9 @@ static Object seek(@SuppressWarnings("unused") PythonObject self, @SuppressWarni abstract static class TruncateNode extends PythonBuiltinNode { @Specialization static Object truncate(@SuppressWarnings("unused") PythonObject self, + @Bind("this") Node inliningTarget, @Cached PRaiseNode raiseNode) { - throw unsupported(raiseNode, T_TRUNCATE); + throw unsupported(inliningTarget, raiseNode, T_TRUNCATE); } } @@ -390,8 +410,9 @@ static Object exit(VirtualFrame frame, PythonObject self, abstract static class FilenoNode extends PythonUnaryBuiltinNode { @Specialization static Object fileno(@SuppressWarnings("unused") PythonObject self, + @Bind("this") Node inliningTarget, @Cached PRaiseNode raiseNode) { - throw unsupported(raiseNode, T_FILENO); + throw unsupported(inliningTarget, raiseNode, T_FILENO); } } @@ -407,7 +428,7 @@ static boolean isatty(VirtualFrame frame, PythonObject self, } } - @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iter, isComplex = true) @GenerateNodeFactory abstract static class IterNode extends PythonUnaryBuiltinNode { @Specialization @@ -419,18 +440,17 @@ static PythonObject iter(VirtualFrame frame, PythonObject self, } } - @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iternext, isComplex = true) @GenerateNodeFactory - abstract static class NextNode extends PythonUnaryBuiltinNode { + abstract static class NextNode extends TpIterNextBuiltin { @Specialization static Object next(VirtualFrame frame, PythonObject self, @Bind("this") Node inliningTarget, @Cached PyObjectCallMethodObjArgs callMethod, - @Cached PyObjectSizeNode sizeNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PyObjectSizeNode sizeNode) { Object line = callMethod.execute(frame, inliningTarget, self, T_READLINE); if (sizeNode.execute(frame, inliningTarget, line) <= 0) { - throw raiseNode.get(inliningTarget).raiseStopIteration(); + throw iteratorExhausted(); } return line; } @@ -443,18 +463,16 @@ abstract static class WriteLinesNode extends PythonBinaryBuiltinNode { static Object writeLines(VirtualFrame frame, PythonObject self, Object lines, @Bind("this") Node inliningTarget, @Cached CheckClosedHelperNode checkClosedNode, - @Cached GetNextNode getNextNode, - @Cached IsBuiltinObjectProfile errorProfile, @Cached PyObjectCallMethodObjArgs callMethod, - @Cached PyObjectGetIter getIter) { + @Cached PyObjectGetIter getIter, + @Cached PyIterNextNode nextNode) { checkClosedNode.execute(frame, inliningTarget, self); Object iter = getIter.execute(frame, inliningTarget, lines); while (true) { Object line; try { - line = getNextNode.execute(frame, iter); - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); + line = nextNode.execute(frame, inliningTarget, iter); + } catch (IteratorExhausted e) { break; } callMethod.execute(frame, inliningTarget, self, T_WRITE, line); @@ -480,14 +498,14 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static PBytes readline(VirtualFrame frame, Object self, int limit, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached PyObjectLookupAttr lookupPeek, @Cached CallNode callPeek, @Cached PyObjectCallMethodObjArgs callRead, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Cached InlinedConditionProfile hasPeek, @Cached InlinedConditionProfile isBytes, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { /* For backwards compatibility, a (slowish) readline(). */ Object peek = lookupPeek.execute(frame, inliningTarget, self, T_PEEK); ByteArrayOutputStream buffer = createOutputStream(); @@ -497,7 +515,7 @@ static PBytes readline(VirtualFrame frame, Object self, int limit, Object readahead = callPeek.execute(frame, peek, 1); // TODO _PyIO_trap_eintr [GR-23297] if (isBytes.profile(inliningTarget, !(readahead instanceof PBytes))) { - throw raiseNode.get(inliningTarget).raise(OSError, S_SHOULD_RETURN_BYTES_NOT_P, "peek()", readahead); + throw raiseNode.raise(inliningTarget, OSError, S_SHOULD_RETURN_BYTES_NOT_P, "peek()", readahead); } byte[] buf = bufferLib.getInternalOrCopiedByteArray(readahead); int bufLen = bufferLib.getBufferLength(readahead); @@ -514,7 +532,7 @@ static PBytes readline(VirtualFrame frame, Object self, int limit, Object b = callRead.execute(frame, inliningTarget, self, T_READ, nreadahead); if (isBytes.profile(inliningTarget, !(b instanceof PBytes))) { - throw raiseNode.get(inliningTarget).raise(OSError, S_SHOULD_RETURN_BYTES_NOT_P, "read()", b); + throw raiseNode.raise(inliningTarget, OSError, S_SHOULD_RETURN_BYTES_NOT_P, "read()", b); } byte[] bytes = bufferLib.getInternalOrCopiedByteArray(b); int bytesLen = bufferLib.getBufferLength(b); @@ -528,7 +546,7 @@ static PBytes readline(VirtualFrame frame, Object self, int limit, } } - return factory.createBytes(toByteArray(buffer)); + return PFactory.createBytes(language, toByteArray(buffer)); } } @@ -544,31 +562,30 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static Object withHint(VirtualFrame frame, Object self, int hintIn, @Bind("this") Node inliningTarget, - @Cached GetNextNode next, + @Bind PythonLanguage language, @Cached InlinedConditionProfile isNegativeHintProfile, - @Cached IsBuiltinObjectProfile errorProfile, @Cached PyObjectGetIter getIter, - @Cached PyObjectSizeNode sizeNode, - @Cached PythonObjectFactory factory) { + @Cached PyIterNextNode nextNode, + @Cached PyObjectSizeNode sizeNode) { int hint = isNegativeHintProfile.profile(inliningTarget, hintIn <= 0) ? Integer.MAX_VALUE : hintIn; int length = 0; Object iterator = getIter.execute(frame, inliningTarget, self); ArrayBuilder list = new ArrayBuilder<>(); while (true) { + Object line; try { - Object line = next.execute(frame, iterator); - list.add(line); - int lineLength = sizeNode.execute(frame, inliningTarget, line); - if (lineLength > hint - length) { - break; - } - length += lineLength; - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); + line = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { + break; + } + list.add(line); + int lineLength = sizeNode.execute(frame, inliningTarget, line); + if (lineLength > hint - length) { break; } + length += lineLength; } - return factory.createList(list.toArray(new Object[0])); + return PFactory.createList(language, list.toArray(new Object[0])); } } @@ -585,7 +602,7 @@ private static boolean isClosed(Node inliningTarget, PythonObject self, VirtualF /** * Equivalent of {@code iobase_unsupported}. */ - private static PException unsupported(PRaiseNode raiseNode, TruffleString message) { - throw raiseNode.raise(IOUnsupportedOperation, message); + private static PException unsupported(Node inliningTarget, PRaiseNode raiseNode, TruffleString message) { + throw raiseNode.raise(inliningTarget, IOUnsupportedOperation, message); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IOBaseDictBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IOBaseDictBuiltins.java index c219e42c9c..e4d5253fec 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IOBaseDictBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IOBaseDictBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -94,8 +94,8 @@ static Object doit(PythonObject self, @SuppressWarnings("unused") PNone none, @Specialization static Object setDict(PythonObject self, @SuppressWarnings("unused") Object d, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.AssertionError, ErrorMessages.ATTR_DICT_IS_NOT_WRITABLE, self); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.AssertionError, ErrorMessages.ATTR_DICT_IS_NOT_WRITABLE, self); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IOModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IOModuleBuiltins.java index 6cc698da4d..c1e3d9cb6b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IOModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IOModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,13 +44,7 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.EncodingWarning; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.IOUnsupportedOperation; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.OSError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PBufferedRWPair; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PBufferedRandom; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PBufferedReader; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PBufferedWriter; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PIOBase; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PIncrementalNewlineDecoder; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PTextIOWrapper; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PWindowsConsoleIO; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; import static com.oracle.graal.python.builtins.modules.WarningsModuleBuiltins.T_WARN; import static com.oracle.graal.python.builtins.modules.io.BufferedIOUtil.SEEK_CUR; @@ -75,17 +69,16 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.PythonOS; import com.oracle.graal.python.builtins.modules.WarningsModuleBuiltins; import com.oracle.graal.python.builtins.modules.io.IONodes.IOMode; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; @@ -93,7 +86,6 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryClinicBuiltinNode; @@ -103,12 +95,10 @@ import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.util.PythonUtils; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.ImportStatic; @@ -137,136 +127,24 @@ public void initialize(Python3Core core) { addBuiltinConstant("DEFAULT_BUFFER_SIZE", DEFAULT_BUFFER_SIZE); PythonBuiltinClass unsupportedOpExcType = core.lookupType(IOUnsupportedOperation); PythonBuiltinClass osError = core.lookupType(OSError); - unsupportedOpExcType.setBases(osError, new PythonAbstractClass[]{osError, core.lookupType(ValueError)}); + unsupportedOpExcType.setBases(null, osError, new PythonAbstractClass[]{osError, core.lookupType(ValueError)}); addBuiltinConstant(IOUnsupportedOperation.getName(), unsupportedOpExcType); addBuiltinConstant(BlockingIOError.getName(), core.lookupType(BlockingIOError)); addBuiltinConstant("_warn", core.lookupBuiltinModule(T__WARNINGS).getAttribute(T_WARN)); if (PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32) { addBuiltinConstant("_os", core.lookupBuiltinModule(T_NT)); + addBuiltinConstant("_WindowsConsoleIO", PWindowsConsoleIO); } else { addBuiltinConstant("_os", core.lookupBuiltinModule(T_POSIX)); } } - @Builtin(name = "_IOBase", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PIOBase) - @GenerateNodeFactory - public abstract static class IOBaseNode extends PythonBuiltinNode { - @Specialization - static PythonObject doGeneric(Object cls, - @Cached PythonObjectFactory factory) { - return factory.createPythonObject(cls); - } - } - - @Builtin(name = "FileIO", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PFileIO) - @GenerateNodeFactory - public abstract static class FileIONode extends PythonBuiltinNode { - @Specialization - static PFileIO doNew(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PythonObjectFactory factory) { - // data filled in subsequent __init__ call - see FileIOBuiltins.InitNode - return factory.createFileIO(cls); - } - } - - @Builtin(name = "BufferedReader", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PBufferedReader) - @GenerateNodeFactory - public abstract static class BufferedReaderNode extends PythonBuiltinNode { - @Specialization - static PBuffered doNew(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PythonObjectFactory factory) { - // data filled in subsequent __init__ call - see BufferedReaderBuiltins.InitNode - return factory.createBufferedReader(cls); - } - } - - @Builtin(name = "BufferedWriter", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PBufferedWriter) - @GenerateNodeFactory - public abstract static class BufferedWriterNode extends PythonBuiltinNode { - @Specialization - static PBuffered doNew(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PythonObjectFactory factory) { - // data filled in subsequent __init__ call - see BufferedWriterBuiltins.InitNode - return factory.createBufferedWriter(cls); - } - } - - @Builtin(name = "BufferedRWPair", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PBufferedRWPair) - @GenerateNodeFactory - public abstract static class BufferedRWPairNode extends PythonBuiltinNode { - @Specialization - static PRWPair doNew(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PythonObjectFactory factory) { - // data filled in subsequent __init__ call - see BufferedRWPairBuiltins.InitNode - return factory.createRWPair(cls); - } - } - - @Builtin(name = "BufferedRandom", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PBufferedRandom) - @GenerateNodeFactory - public abstract static class BufferedRandomNode extends PythonBuiltinNode { - @Specialization - static PBuffered doNew(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PythonObjectFactory factory) { - // data filled in subsequent __init__ call - see BufferedRandomBuiltins.InitNode - return factory.createBufferedRandom(cls); - } - } - - @Builtin(name = "TextIOWrapper", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PTextIOWrapper) - @GenerateNodeFactory - public abstract static class TextIOWrapperNode extends PythonBuiltinNode { - @Specialization - static PTextIO doNew(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PythonObjectFactory factory) { - // data filled in subsequent __init__ call - see TextIOWrapperBuiltins.InitNode - return factory.createTextIO(cls); - } - } - - @Builtin(name = "BytesIO", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PBytesIO) - @GenerateNodeFactory - public abstract static class BytesIONode extends PythonBuiltinNode { - @Specialization - static PBytesIO doNew(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PythonObjectFactory factory) { - // data filled in subsequent __init__ call - see BytesIONodeBuiltins.InitNode - PBytesIO bytesIO = factory.createBytesIO(cls); - bytesIO.setBuf(factory.createByteArray(PythonUtils.EMPTY_BYTE_ARRAY)); - return bytesIO; - } - } - - @Builtin(name = "StringIO", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.PStringIO) - @GenerateNodeFactory - public abstract static class StringIONode extends PythonBuiltinNode { - @Specialization - static PStringIO doNew(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PythonObjectFactory factory) { - // data filled in subsequent __init__ call - see StringIONodeBuiltins.InitNode - return factory.createStringIO(cls); - } - } - - @Builtin(name = "IncrementalNewlineDecoder", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PIncrementalNewlineDecoder) - @GenerateNodeFactory - public abstract static class IncrementalNewlineDecoderNode extends PythonBuiltinNode { - @Specialization - static PNLDecoder doNew(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PythonObjectFactory factory) { - // data filled in subsequent __init__ call - see - // IncrementalNewlineDecoderBuiltins.InitNode - return factory.createNLDecoder(cls); - } - } - private static PFileIO createFileIO(VirtualFrame frame, Node inliningTarget, Object file, IONodes.IOMode mode, boolean closefd, Object opener, - PythonObjectFactory factory, FileIOBuiltins.FileIOInit initFileIO) { /* Create the Raw file stream */ mode.text = mode.universal = false; // FileIO doesn't recognize those. - PFileIO fileIO = factory.createFileIO(PythonBuiltinClassType.PFileIO); + PFileIO fileIO = PFactory.createFileIO(PythonLanguage.get(inliningTarget)); initFileIO.execute(frame, inliningTarget, fileIO, file, mode, closefd, opener); return fileIO; } @@ -285,9 +163,8 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static PFileIO openCode(VirtualFrame frame, TruffleString path, @Bind("this") Node inliningTarget, - @Cached FileIOBuiltins.FileIOInit initFileIO, - @Cached PythonObjectFactory factory) { - return createFileIO(frame, inliningTarget, path, IOMode.RB, true, PNone.NONE, factory, initFileIO); + @Cached FileIOBuiltins.FileIOInit initFileIO) { + return createFileIO(frame, inliningTarget, path, IOMode.RB, true, PNone.NONE, initFileIO); } } @@ -319,9 +196,9 @@ protected static Object openText(VirtualFrame frame, Object file, IONodes.IOMode @Cached PyObjectSetAttr setAttrNode, @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, @Exclusive @Cached PyObjectCallMethodObjArgs callClose, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - PFileIO fileIO = createFileIO(frame, inliningTarget, file, mode, closefd, opener, factory, initFileIO); + @Bind PythonLanguage language, + @Exclusive @Cached PRaiseNode raiseNode) { + PFileIO fileIO = createFileIO(frame, inliningTarget, file, mode, closefd, opener, initFileIO); Object result = fileIO; try { /* buffering */ @@ -349,21 +226,21 @@ protected static Object openText(VirtualFrame frame, Object file, IONodes.IOMode buffering = fileIO.getBlksize(); } if (buffering < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, INVALID_BUFFERING_SIZE); + throw raiseNode.raise(inliningTarget, ValueError, INVALID_BUFFERING_SIZE); } /* if not buffering, returns the raw file object */ if (buffering == 0) { - invalidunbuf(file, mode, bufferingValue, encoding, errors, newline, closefd, opener, raiseNode.get(inliningTarget)); + invalidunbuf(file, mode, bufferingValue, encoding, errors, newline, closefd, opener, raiseNode); } /* wraps into a buffered file */ - PBuffered buffer = createBufferedIO.execute(frame, inliningTarget, fileIO, buffering, factory, mode); + PBuffered buffer = createBufferedIO.execute(frame, inliningTarget, fileIO, buffering, mode); result = buffer; /* wraps into a TextIOWrapper */ - PTextIO wrapper = factory.createTextIO(PTextIOWrapper); + PTextIO wrapper = PFactory.createTextIO(language); initTextIO.execute(frame, inliningTarget, wrapper, buffer, encoding, errors == PNone.NONE ? T_STRICT : (TruffleString) errors, newline, line_buffering, false); @@ -385,9 +262,8 @@ protected static PFileIO openBinaryNoBuf(VirtualFrame frame, Object file, IONode @SuppressWarnings("unused") PNone newline, boolean closefd, Object opener, @Bind("this") Node inliningTarget, - @Exclusive @Cached FileIOBuiltins.FileIOInit initFileIO, - @Shared @Cached PythonObjectFactory factory) { - return createFileIO(frame, inliningTarget, file, mode, closefd, opener, factory, initFileIO); + @Exclusive @Cached FileIOBuiltins.FileIOInit initFileIO) { + return createFileIO(frame, inliningTarget, file, mode, closefd, opener, initFileIO); } @Specialization(guards = {"!isXRWA(mode)", "!isUnknown(mode)", "!isTB(mode)", "isValidUniveral(mode)", "isBinary(mode)", "bufferingValue == 1"}) @@ -402,10 +278,9 @@ protected static Object openBinaryB1(VirtualFrame frame, Object file, IONodes.IO @Exclusive @Cached IONodes.CreateBufferedIONode createBufferedIO, @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, @Exclusive @Cached PyObjectCallMethodObjArgs callClose, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { warnNode.warnEx(frame, RuntimeWarning, LINE_BUFFERING_ISNT_SUPPORTED, 1); - return openBinary(frame, file, mode, bufferingValue, encoding, errors, newline, closefd, opener, inliningTarget, initFileIO, createBufferedIO, posixLib, callClose, factory, raiseNode); + return openBinary(frame, file, mode, bufferingValue, encoding, errors, newline, closefd, opener, inliningTarget, initFileIO, createBufferedIO, posixLib, callClose, raiseNode); } @Specialization(guards = {"!isXRWA(mode)", "!isUnknown(mode)", "!isTB(mode)", "isValidUniveral(mode)", "isBinary(mode)", "bufferingValue != 1", "bufferingValue != 0"}) @@ -419,9 +294,8 @@ protected static Object openBinary(VirtualFrame frame, Object file, IONodes.IOMo @Exclusive @Cached IONodes.CreateBufferedIONode createBufferedIO, @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, @Exclusive @Cached PyObjectCallMethodObjArgs callClose, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - PFileIO fileIO = createFileIO(frame, inliningTarget, file, mode, closefd, opener, factory, initFileIO); + @Exclusive @Cached PRaiseNode raiseNode) { + PFileIO fileIO = createFileIO(frame, inliningTarget, file, mode, closefd, opener, initFileIO); try { /* buffering */ boolean isatty = false; @@ -444,7 +318,7 @@ protected static Object openBinary(VirtualFrame frame, Object file, IONodes.IOMo buffering = fileIO.getBlksize(); } if (buffering < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, INVALID_BUFFERING_SIZE); + throw raiseNode.raise(inliningTarget, ValueError, INVALID_BUFFERING_SIZE); } /* if not buffering, returns the raw file object */ @@ -455,7 +329,7 @@ protected static Object openBinary(VirtualFrame frame, Object file, IONodes.IOMo /* wraps into a buffered file */ /* if binary, returns the buffered file */ - return createBufferedIO.execute(frame, inliningTarget, fileIO, buffering, factory, mode); + return createBufferedIO.execute(frame, inliningTarget, fileIO, buffering, mode); } catch (PException e) { callClose.execute(frame, inliningTarget, fileIO, T_CLOSE); throw e; @@ -465,35 +339,35 @@ protected static Object openBinary(VirtualFrame frame, Object file, IONodes.IOMo @SuppressWarnings("unused") @Specialization(guards = "isUnknown(mode)") protected static Object unknownMode(Object file, IONodes.IOMode mode, int bufferingValue, Object encoding, Object errors, Object newline, boolean closefd, Object opener, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, UNKNOWN_MODE_S, mode.mode); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, UNKNOWN_MODE_S, mode.mode); } @SuppressWarnings("unused") @Specialization(guards = "isTB(mode)") protected static Object invalidTB(Object file, IONodes.IOMode mode, int bufferingValue, Object encoding, Object errors, Object newline, boolean closefd, Object opener, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, CAN_T_HAVE_TEXT_AND_BINARY_MODE_AT_ONCE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, CAN_T_HAVE_TEXT_AND_BINARY_MODE_AT_ONCE); } @SuppressWarnings("unused") @Specialization(guards = "!isValidUniveral(mode)") protected static Object invalidUniversal(Object file, IONodes.IOMode mode, int bufferingValue, Object encoding, Object errors, Object newline, boolean closefd, Object opener, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, MODE_U_CANNOT_BE_COMBINED_WITH_X_W_A_OR); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, MODE_U_CANNOT_BE_COMBINED_WITH_X_W_A_OR); } @SuppressWarnings("unused") @Specialization(guards = "isXRWA(mode)") protected static Object invalidxrwa(Object file, IONodes.IOMode mode, int bufferingValue, Object encoding, Object errors, Object newline, boolean closefd, Object opener, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, MUST_HAVE_EXACTLY_ONE_OF_CREATE_READ_WRITE_APPEND_MODE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, MUST_HAVE_EXACTLY_ONE_OF_CREATE_READ_WRITE_APPEND_MODE); } @SuppressWarnings("unused") @Specialization(guards = {"isBinary(mode)", "isAnyNotNone(encoding, errors, newline)"}) protected static Object invalidBinary(Object file, IONodes.IOMode mode, int bufferingValue, Object encoding, Object errors, Object newline, boolean closefd, Object opener, - @Shared @Cached PRaiseNode raiseNode) { + @Bind("this") Node inliningTarget) { String s; if (encoding != PNone.NONE) { s = "encoding"; @@ -502,14 +376,14 @@ protected static Object invalidBinary(Object file, IONodes.IOMode mode, int buff } else { s = "newline"; } - throw raiseNode.raise(ValueError, BINARY_MODE_DOESN_T_TAKE_AN_S_ARGUMENT, s); + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, BINARY_MODE_DOESN_T_TAKE_AN_S_ARGUMENT, s); } @SuppressWarnings("unused") @Specialization(guards = {"!isBinary(mode)", "bufferingValue == 0"}) protected static Object invalidunbuf(Object file, IONodes.IOMode mode, int bufferingValue, Object encoding, Object errors, Object newline, boolean closefd, Object opener, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, CAN_T_HAVE_UNBUFFERED_TEXT_IO); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, CAN_T_HAVE_UNBUFFERED_TEXT_IO); } public static boolean isAnyNotNone(Object encoding, Object errors, Object newline) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IONodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IONodes.java index 717ce49df3..792011dc9c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IONodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IONodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,9 +41,6 @@ package com.oracle.graal.python.builtins.modules.io; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.DeprecationWarning; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PBufferedRandom; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PBufferedReader; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PBufferedWriter; import static com.oracle.graal.python.nodes.ErrorMessages.EMBEDDED_NULL_CHARACTER; import static com.oracle.graal.python.nodes.ErrorMessages.EXPECTED_OBJ_TYPE_S_GOT_P; import static com.oracle.graal.python.nodes.ErrorMessages.INVALID_MODE_S; @@ -53,6 +50,7 @@ import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ClinicConverterFactory; import com.oracle.graal.python.builtins.modules.WarningsModuleBuiltins; import com.oracle.graal.python.builtins.objects.PNone; @@ -67,11 +65,10 @@ import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentCastNode; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -379,21 +376,21 @@ IOMode generic(VirtualFrame frame, Object modeObj, @Cached InlinedBranchProfile errProfile2, @Cached InlinedBranchProfile errProfile3, @Cached WarningsModuleBuiltins.WarnNode warnNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleString mode; try { mode = toString.execute(inliningTarget, modeObj); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); } IOMode m = new IOMode(mode, createCodePointIteratorNode, nextNode); if (m.hasNil) { errProfile1.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(ValueError, EMBEDDED_NULL_CHARACTER); + throw raiseNode.raise(inliningTarget, ValueError, EMBEDDED_NULL_CHARACTER); } if (m.isInvalid) { errProfile2.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(ValueError, INVALID_MODE_S, mode); + throw raiseNode.raise(inliningTarget, ValueError, INVALID_MODE_S, mode); } if (warnUniversal && m.universal) { errProfile3.enter(inliningTarget); @@ -433,11 +430,11 @@ static Object generic(VirtualFrame frame, Object nameobj, @Cached BytesNodes.DecodeUTF8FSPathNode fspath, @Cached PyIndexCheckNode indexCheckNode, @Cached PyNumberAsSizeNode asSizeNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (indexCheckNode.execute(inliningTarget, nameobj)) { int fd = asSizeNode.executeExact(frame, inliningTarget, nameobj); if (fd < 0) { - err(fd, raiseNode.get(inliningTarget)); + err(fd, raiseNode); } return fd; } else { @@ -447,14 +444,14 @@ static Object generic(VirtualFrame frame, Object nameobj, @Specialization(guards = "fd < 0") static int err(int fd, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, OPENER_RETURNED_D, fd); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, OPENER_RETURNED_D, fd); } @Specialization(guards = "fd < 0") static int err(long fd, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, OPENER_RETURNED_D, fd); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, OPENER_RETURNED_D, fd); } @ClinicConverterFactory @@ -467,7 +464,7 @@ public static CastOpenNameNode create() { @GenerateCached(false) @GenerateInline public abstract static class CreateBufferedIONode extends Node { - public abstract PBuffered execute(VirtualFrame frame, Node inliningTarget, PFileIO fileIO, int buffering, PythonObjectFactory factory, IONodes.IOMode mode); + public abstract PBuffered execute(VirtualFrame frame, Node inliningTarget, PFileIO fileIO, int buffering, IONodes.IOMode mode); protected static boolean isRandom(IONodes.IOMode mode) { return mode.updating; @@ -482,26 +479,29 @@ protected static boolean isReading(IONodes.IOMode mode) { } @Specialization(guards = "isRandom(mode)") - static PBuffered createRandom(VirtualFrame frame, Node inliningTarget, PFileIO fileIO, int buffering, PythonObjectFactory factory, @SuppressWarnings("unused") IONodes.IOMode mode, - @Cached BufferedRandomBuiltins.BufferedRandomInit initBuffered) { - PBuffered buffer = factory.createBufferedRandom(PBufferedRandom); - initBuffered.execute(frame, inliningTarget, buffer, fileIO, buffering, factory); + static PBuffered createRandom(VirtualFrame frame, Node inliningTarget, PFileIO fileIO, int buffering, @SuppressWarnings("unused") IONodes.IOMode mode, + @Cached BufferedRandomBuiltins.BufferedRandomInit initBuffered, + @Bind PythonLanguage language) { + PBuffered buffer = PFactory.createBufferedRandom(language); + initBuffered.execute(frame, inliningTarget, buffer, fileIO, buffering); return buffer; } @Specialization(guards = {"!isRandom(mode)", "isWriting(mode)"}) - static PBuffered createWriter(VirtualFrame frame, Node inliningTarget, PFileIO fileIO, int buffering, PythonObjectFactory factory, @SuppressWarnings("unused") IONodes.IOMode mode, - @Cached BufferedWriterBuiltins.BufferedWriterInit initBuffered) { - PBuffered buffer = factory.createBufferedWriter(PBufferedWriter); - initBuffered.execute(frame, inliningTarget, buffer, fileIO, buffering, factory); + static PBuffered createWriter(VirtualFrame frame, Node inliningTarget, PFileIO fileIO, int buffering, @SuppressWarnings("unused") IONodes.IOMode mode, + @Cached BufferedWriterBuiltins.BufferedWriterInit initBuffered, + @Bind PythonLanguage language) { + PBuffered buffer = PFactory.createBufferedWriter(language); + initBuffered.execute(frame, inliningTarget, buffer, fileIO, buffering); return buffer; } @Specialization(guards = {"!isRandom(mode)", "!isWriting(mode)", "isReading(mode)"}) - static PBuffered createWriter(VirtualFrame frame, Node inliningTarget, PFileIO fileIO, int buffering, PythonObjectFactory factory, @SuppressWarnings("unused") IONodes.IOMode mode, - @Cached BufferedReaderBuiltins.BufferedReaderInit initBuffered) { - PBuffered buffer = factory.createBufferedReader(PBufferedReader); - initBuffered.execute(frame, inliningTarget, buffer, fileIO, buffering, factory); + static PBuffered createWriter(VirtualFrame frame, Node inliningTarget, PFileIO fileIO, int buffering, @SuppressWarnings("unused") IONodes.IOMode mode, + @Cached BufferedReaderBuiltins.BufferedReaderInit initBuffered, + @Bind PythonLanguage language) { + PBuffered buffer = PFactory.createBufferedReader(language); + initBuffered.execute(frame, inliningTarget, buffer, fileIO, buffering); return buffer; } } @@ -523,11 +523,11 @@ static TruffleString string(TruffleString s) { @Specialization(guards = "!isString(s)") static TruffleString str(Node inliningTarget, Object s, @Cached CastToTruffleStringNode str, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { return str.execute(inliningTarget, s); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, EXPECTED_OBJ_TYPE_S_GOT_P, "str", s); + throw raiseNode.raise(inliningTarget, TypeError, EXPECTED_OBJ_TYPE_S_GOT_P, "str", s); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java index 02f0006ced..0dd9556917 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -53,7 +53,6 @@ import static com.oracle.graal.python.builtins.modules.io.IONodes.T_SETSTATE; import static com.oracle.graal.python.nodes.ErrorMessages.ILLEGAL_STATE_ARGUMENT; import static com.oracle.graal.python.nodes.ErrorMessages.STATE_ARGUMENT_MUST_BE_A_TUPLE; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import static com.oracle.graal.python.nodes.StringLiterals.T_CR; import static com.oracle.graal.python.nodes.StringLiterals.T_CRLF; import static com.oracle.graal.python.nodes.StringLiterals.T_NEWLINE; @@ -62,7 +61,11 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltins; @@ -70,6 +73,8 @@ import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.common.SequenceNodes; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyIndexCheckNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; @@ -82,11 +87,10 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; @@ -100,6 +104,9 @@ @CoreFunctions(extendClasses = PIncrementalNewlineDecoder) public final class IncrementalNewlineDecoderBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = IncrementalNewlineDecoderBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return IncrementalNewlineDecoderBuiltinsFactory.getFactories(); @@ -110,8 +117,23 @@ protected List> getNodeFa public static final int SEEN_CRLF = 4; public static final int SEEN_ALL = (SEEN_CR | SEEN_LF | SEEN_CRLF); + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "IncrementalNewlineDecoder", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class IncrementalNewlineDecoderNode extends PythonBuiltinNode { + @Specialization + static PNLDecoder doNew(Object cls, @SuppressWarnings("unused") Object arg, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + // data filled in subsequent __init__ call - see + // IncrementalNewlineDecoderBuiltins.InitNode + return PFactory.createNLDecoder(language, cls, getInstanceShape.execute(cls)); + } + } + // BufferedReader(raw[, buffer_size=DEFAULT_BUFFER_SIZE]) - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 2, parameterNames = {"$self", "decoder", "translate", "errors"}) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "IncrementalNewlineDecoder", minNumOfPositionalArgs = 2, parameterNames = {"$self", "decoder", "translate", "errors"}) @ArgumentClinic(name = "translate", conversion = ArgumentClinic.ClinicConversion.Boolean) @ArgumentClinic(name = "errors", conversion = ArgumentClinic.ClinicConversion.TString, defaultValue = "T_STRICT", useDefaultForNone = true) @GenerateNodeFactory @@ -284,35 +306,35 @@ abstract static class GetStateNode extends PythonUnaryBuiltinNode { @Specialization(guards = "!self.hasDecoder()") static Object noDecoder(PNLDecoder self, - @Shared @Cached PythonObjectFactory factory) { - PBytes buffer = factory.createEmptyBytes(); + @Bind PythonLanguage language) { + PBytes buffer = PFactory.createEmptyBytes(language); int flag = self.isPendingCR() ? 1 : 0; - return factory.createTuple(new Object[]{buffer, flag}); + return PFactory.createTuple(language, new Object[]{buffer, flag}); } @Specialization(guards = "self.hasDecoder()") static Object withDecoder(VirtualFrame frame, PNLDecoder self, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached SequenceNodes.GetObjectArrayNode getObjectArrayNode, @Cached PyIndexCheckNode indexCheckNode, @Cached PyNumberAsSizeNode asSizeNode, @Cached PyObjectCallMethodObjArgs callMethod, - @Shared @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object state = callMethod.execute(frame, inliningTarget, self.getDecoder(), T_GETSTATE); if (!(state instanceof PTuple)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ILLEGAL_STATE_ARGUMENT); + throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_STATE_ARGUMENT); } Object[] objects = getObjectArrayNode.execute(inliningTarget, state); if (objects.length != 2 || !indexCheckNode.execute(inliningTarget, objects[1])) { - throw raiseNode.get(inliningTarget).raise(TypeError, ILLEGAL_STATE_ARGUMENT); + throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_STATE_ARGUMENT); } int flag = asSizeNode.executeExact(frame, inliningTarget, objects[1]); flag <<= 1; if (self.isPendingCR()) { flag |= 1; } - return factory.createTuple(new Object[]{objects[0], flag}); + return PFactory.createTuple(language, new Object[]{objects[0], flag}); } } @@ -326,10 +348,10 @@ static Object noDecoder(VirtualFrame frame, PNLDecoder self, PTuple state, @Exclusive @Cached SequenceNodes.GetObjectArrayNode getObjectArrayNode, @Exclusive @Cached PyIndexCheckNode indexCheckNode, @Exclusive @Cached PyNumberAsSizeNode asSizeNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { Object[] objects = getObjectArrayNode.execute(inliningTarget, state); if (objects.length != 2 || !indexCheckNode.execute(inliningTarget, objects[1])) { - throw raiseNode.get(inliningTarget).raise(TypeError, ILLEGAL_STATE_ARGUMENT); + throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_STATE_ARGUMENT); } int flag = asSizeNode.executeExact(frame, inliningTarget, objects[1]); self.setPendingCR((flag & 1) != 0); @@ -339,27 +361,27 @@ static Object noDecoder(VirtualFrame frame, PNLDecoder self, PTuple state, @Specialization(guards = "self.hasDecoder()") static Object withDecoder(VirtualFrame frame, PNLDecoder self, PTuple state, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Exclusive @Cached SequenceNodes.GetObjectArrayNode getObjectArrayNode, @Exclusive @Cached PyIndexCheckNode indexCheckNode, @Exclusive @Cached PyNumberAsSizeNode asSizeNode, @Cached PyObjectCallMethodObjArgs callMethod, - @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { Object[] objects = getObjectArrayNode.execute(inliningTarget, state); if (objects.length != 2 || !indexCheckNode.execute(inliningTarget, objects[1])) { - throw raiseNode.get(inliningTarget).raise(TypeError, ILLEGAL_STATE_ARGUMENT); + throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_STATE_ARGUMENT); } int flag = asSizeNode.executeExact(frame, inliningTarget, objects[1]); self.setPendingCR((flag & 1) != 0); flag >>= 1; - PTuple tuple = factory.createTuple(new Object[]{objects[0], flag}); + PTuple tuple = PFactory.createTuple(language, new Object[]{objects[0], flag}); return callMethod.execute(frame, inliningTarget, self.getDecoder(), T_SETSTATE, tuple); } @Fallback static Object err(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object state, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, STATE_ARGUMENT_MUST_BE_A_TUPLE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, STATE_ARGUMENT_MUST_BE_A_TUPLE); } } @@ -388,7 +410,7 @@ static Object withDecoder(VirtualFrame frame, PNLDecoder self, abstract static class NewlineNode extends PythonBuiltinNode { @Specialization static Object newline(PNLDecoder self, - @Cached PythonObjectFactory factory) { + @Bind("this") Node inliningTarget) { switch (self.getSeenNewline()) { case SEEN_CR: return T_CR; @@ -397,13 +419,13 @@ static Object newline(PNLDecoder self, case SEEN_CRLF: return T_CRLF; case SEEN_CR | SEEN_LF: - return factory.createTuple(new Object[]{T_CR, T_NEWLINE}); + return PFactory.createTuple(PythonLanguage.get(inliningTarget), new Object[]{T_CR, T_NEWLINE}); case SEEN_CR | SEEN_CRLF: - return factory.createTuple(new Object[]{T_CR, T_CRLF}); + return PFactory.createTuple(PythonLanguage.get(inliningTarget), new Object[]{T_CR, T_CRLF}); case SEEN_LF | SEEN_CRLF: - return factory.createTuple(new Object[]{T_NEWLINE, T_CRLF}); + return PFactory.createTuple(PythonLanguage.get(inliningTarget), new Object[]{T_NEWLINE, T_CRLF}); case SEEN_CR | SEEN_LF | SEEN_CRLF: - return factory.createTuple(new Object[]{T_CR, T_NEWLINE, T_CRLF}); + return PFactory.createTuple(PythonLanguage.get(inliningTarget), new Object[]{T_CR, T_NEWLINE, T_CRLF}); default: return PNone.NONE; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/PBytesIO.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/PBytesIO.java index b0efce23a8..225f228bdc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/PBytesIO.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/PBytesIO.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,13 +42,14 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.BufferError; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.bytes.PByteArray; import com.oracle.graal.python.builtins.objects.memoryview.BufferLifecycleManager; import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; @@ -100,9 +101,9 @@ public int getExports() { return exports.getExports().get(); } - public void checkExports(Node inliningTarget, PRaiseNode.Lazy raiseNode) { + public void checkExports(Node inliningTarget, PRaiseNode raiseNode) { if (getExports() != 0) { - throw raiseNode.get(inliningTarget).raise(BufferError, ErrorMessages.EXISTING_EXPORTS_OF_DATA_OBJECT_CANNOT_BE_RE_SIZED); + throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.EXISTING_EXPORTS_OF_DATA_OBJECT_CANNOT_BE_RE_SIZED); } } @@ -120,14 +121,14 @@ public void markEscaped() { * it without copying the first time the program asks for the whole contents. So that a sequence * of writes followed by one getvalue call doesn't have to copy the whole buffer at the end. */ - public void unshareIfNecessary(PythonBufferAccessLibrary bufferLib, PythonObjectFactory factory) { + public void unshareIfNecessary(PythonBufferAccessLibrary bufferLib, PythonLanguage language) { if (escaped || getExports() != 0) { - buf = factory.createByteArray(bufferLib.getCopiedByteArray(buf)); + buf = PFactory.createByteArray(language, bufferLib.getCopiedByteArray(buf)); escaped = false; } } - public void unshareAndResize(PythonBufferAccessLibrary bufferLib, PythonObjectFactory factory, int size, boolean truncate) { + public void unshareAndResize(PythonBufferAccessLibrary bufferLib, PythonLanguage language, int size, boolean truncate) { int origLength = bufferLib.getBufferLength(getBuf()); int alloc; if (truncate && size < origLength / 2) { @@ -135,7 +136,7 @@ public void unshareAndResize(PythonBufferAccessLibrary bufferLib, PythonObjectFa alloc = size; } else if (size < origLength) { /* Within allocated size; quick exit */ - unshareIfNecessary(bufferLib, factory); + unshareIfNecessary(bufferLib, language); return; } else if (size <= origLength * 1.125) { /* Moderate upsize; overallocate similar to list_resize() */ @@ -150,7 +151,7 @@ public void unshareAndResize(PythonBufferAccessLibrary bufferLib, PythonObjectFa } byte[] newBuf = new byte[alloc]; bufferLib.readIntoByteArray(getBuf(), 0, newBuf, 0, Math.min(stringSize, size)); - setBuf(factory.createByteArray(newBuf)); + setBuf(PFactory.createByteArray(language, newBuf)); escaped = false; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/PTextIO.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/PTextIO.java index e0bda2dbdc..200ff15b56 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/PTextIO.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/PTextIO.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -424,12 +424,12 @@ public static Object build(CookieType cookie) { return IntNodes.PyLongFromByteArray.executeUncached(buffer, true, false); } - public static CookieType parse(long v, Node inliningTarget, InlinedConditionProfile overflow, PRaiseNode.Lazy raise) { + public static CookieType parse(long v, Node inliningTarget, InlinedConditionProfile overflow, PRaiseNode raise) { byte[] buffer = IntBuiltins.ToBytesNode.fromLong(v, COOKIE_BUF_LEN, false, false, inliningTarget, overflow, raise); return parse(buffer); } - public static CookieType parse(PInt v, Node inliningTarget, InlinedConditionProfile overflow, PRaiseNode.Lazy raise) { + public static CookieType parse(PInt v, Node inliningTarget, InlinedConditionProfile overflow, PRaiseNode raise) { byte[] buffer = IntBuiltins.ToBytesNode.fromBigInteger(v, COOKIE_BUF_LEN, false, false, inliningTarget, overflow, raise); return parse(buffer); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/RawIOBaseBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/RawIOBaseBuiltins.java index 58547e96d5..36b8db7086 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/RawIOBaseBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/RawIOBaseBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -59,6 +59,7 @@ import java.io.ByteArrayOutputStream; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -76,7 +77,7 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -121,24 +122,24 @@ static Object readall(VirtualFrame frame, Object self, @SuppressWarnings("unused @Specialization(guards = "size >= 0") static Object read(VirtualFrame frame, Object self, int size, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached BytesNodes.ToBytesNode toBytes, @Exclusive @Cached PyObjectCallMethodObjArgs callMethodReadInto, - @Cached PyNumberAsSizeNode asSizeNode, - @Cached PythonObjectFactory factory) { - PByteArray b = factory.createByteArray(new byte[size]); + @Cached PyNumberAsSizeNode asSizeNode) { + PByteArray b = PFactory.createByteArray(language, new byte[size]); Object res = callMethodReadInto.execute(frame, inliningTarget, self, T_READINTO, b); if (res == PNone.NONE) { return res; } int n = asSizeNode.executeExact(frame, inliningTarget, res, ValueError); if (n == 0) { - return factory.createEmptyBytes(); + return PFactory.createEmptyBytes(language); } byte[] bytes = toBytes.execute(b); if (n < size) { - return factory.createBytes(PythonUtils.arrayCopyOf(bytes, n)); + return PFactory.createBytes(language, PythonUtils.arrayCopyOf(bytes, n)); } - return factory.createBytes(bytes); + return PFactory.createBytes(language, bytes); } } @@ -157,8 +158,7 @@ static Object readall(VirtualFrame frame, Object self, @Cached InlinedConditionProfile chunksSize0Profile, @Cached InlinedCountingConditionProfile bytesLen0Profile, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { ByteArrayOutputStream chunks = createOutputStream(); while (true) { Object data = callMethodRead.execute(frame, inliningTarget, self, T_READ, DEFAULT_BUFFER_SIZE); @@ -170,7 +170,7 @@ static Object readall(VirtualFrame frame, Object self, break; } if (!(data instanceof PBytes)) { - throw raiseNode.get(inliningTarget).raise(TypeError, S_SHOULD_RETURN_BYTES, "read()"); + throw raiseNode.raise(inliningTarget, TypeError, S_SHOULD_RETURN_BYTES, "read()"); } byte[] bytes = bufferLib.getInternalOrCopiedByteArray(data); int bytesLen = bufferLib.getBufferLength(data); @@ -180,7 +180,7 @@ static Object readall(VirtualFrame frame, Object self, append(chunks, bytes, bytesLen); } - return factory.createBytes(toByteArray(chunks)); + return PFactory.createBytes(PythonLanguage.get(inliningTarget), toByteArray(chunks)); } } @@ -193,8 +193,8 @@ abstract static class ReadIntoNode extends PythonBuiltinNode { */ @Specialization static Object readinto(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object args, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(NotImplementedError); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError); } } @@ -207,8 +207,8 @@ abstract static class WriteNode extends PythonBuiltinNode { */ @Specialization static Object write(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object args, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(NotImplementedError); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java index b3be129689..497b794864 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,7 +40,6 @@ */ package com.oracle.graal.python.builtins.modules.io; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PIncrementalNewlineDecoder; import static com.oracle.graal.python.builtins.modules.io.BufferedIOUtil.SEEK_CUR; import static com.oracle.graal.python.builtins.modules.io.BufferedIOUtil.SEEK_END; import static com.oracle.graal.python.builtins.modules.io.BufferedIOUtil.SEEK_SET; @@ -74,8 +73,6 @@ import static com.oracle.graal.python.nodes.ErrorMessages.THIRD_ITEM_OF_STATE_MUST_BE_AN_INTEGER_GOT_P; import static com.oracle.graal.python.nodes.ErrorMessages.THIRD_ITEM_OF_STATE_SHOULD_BE_A_DICT_GOT_A_P; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETSTATE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; import static com.oracle.graal.python.nodes.StringLiterals.T_NEWLINE; @@ -87,7 +84,11 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -100,6 +101,9 @@ import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.str.StringNodes.StringReplaceNode; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; import com.oracle.graal.python.lib.PyIndexCheckNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyNumberIndexNode; @@ -108,6 +112,7 @@ import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; @@ -115,9 +120,8 @@ import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectExactProfile; import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Bind; @@ -127,7 +131,6 @@ import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -138,6 +141,8 @@ public final class StringIOBuiltins extends PythonBuiltins { private static final int NIL_CODEPOINT = 0; + public static final TpSlots SLOTS = StringIOBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return StringIOBuiltinsFactory.getFactories(); @@ -146,14 +151,14 @@ protected List> getNodeFa abstract static class ClosedCheckPythonUnaryBuiltinNode extends PythonUnaryBuiltinNode { @Specialization(guards = "!self.isOK()") static Object initError(@SuppressWarnings("unused") PStringIO self, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_UNINIT); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } @Specialization(guards = "self.isClosed()") static Object closedError(@SuppressWarnings("unused") PStringIO self, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } @@ -166,19 +171,19 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(guards = "!self.isOK()") static Object initError(@SuppressWarnings("unused") PStringIO self, @SuppressWarnings("unused") Object arg, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_UNINIT); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } @Specialization(guards = "self.isClosed()") static Object closedError(@SuppressWarnings("unused") PStringIO self, @SuppressWarnings("unused") Object arg, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } static void writeString(VirtualFrame frame, Node inliningTarget, PStringIO self, TruffleString obj, - PRaiseNode.Lazy raiseNode, + PRaiseNode raiseNode, IncrementalNewlineDecoderBuiltins.DecodeNode decodeNode, StringReplaceNode replaceNode, TruffleString.CodePointLengthNode codePointLengthNode, @@ -205,7 +210,7 @@ static void writeString(VirtualFrame frame, Node inliningTarget, PStringIO self, * things like comparing an unsigned and a signed integer. */ if (self.getPos() > Integer.MAX_VALUE - decodedLen) { - throw raiseNode.get(inliningTarget).raise(OverflowError, NEW_POSITION_TOO_LARGE); + throw raiseNode.raise(inliningTarget, OverflowError, NEW_POSITION_TOO_LARGE); } if (self.isAccumulating()) { @@ -259,7 +264,21 @@ static void writeString(VirtualFrame frame, Node inliningTarget, PStringIO self, } } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self", "initial_value", "newline"}) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "StringIO", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class StringIONode extends PythonBuiltinNode { + @Specialization + static PStringIO doNew(Object cls, @SuppressWarnings("unused") Object arg, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + // data filled in subsequent __init__ call - see StringIONodeBuiltins.InitNode + return PFactory.createStringIO(language, cls, getInstanceShape.execute(cls)); + } + } + + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "StringIO", minNumOfPositionalArgs = 1, parameterNames = {"$self", "initial_value", "newline"}) @ArgumentClinic(name = "initial_value", conversion = ArgumentClinic.ClinicConversion.TString, defaultValue = "T_EMPTY_STRING", useDefaultForNone = true) @GenerateNodeFactory public abstract static class InitNode extends PythonTernaryClinicBuiltinNode { @@ -272,7 +291,7 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static PNone init(VirtualFrame frame, PStringIO self, TruffleString initialValue, Object newlineArg, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy lazyRaiseNode, + @Cached PRaiseNode lazyRaiseNode, @Cached IncrementalNewlineDecoderBuiltins.DecodeNode decodeNode, @Cached IncrementalNewlineDecoderBuiltins.InitNode initNode, @Cached StringReplaceNode replaceNode, @@ -283,8 +302,8 @@ static PNone init(VirtualFrame frame, PStringIO self, TruffleString initialValue @Cached TruffleStringBuilder.ToStringNode toStringNode, @Cached TruffleStringBuilder.AppendCodePointNode appendCodePointNode, @Cached IONodes.ToTruffleStringNode toTruffleStringNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { TruffleString newline; if (newlineArg == PNone.NO_VALUE) { @@ -317,7 +336,7 @@ static PNone init(VirtualFrame frame, PStringIO self, TruffleString initialValue } if (self.isReadUniversal()) { - Object incDecoder = factory.createNLDecoder(PIncrementalNewlineDecoder); + Object incDecoder = PFactory.createNLDecoder(language); initNode.execute(frame, incDecoder, self.getDecoder(), self.isReadTranslate(), PNone.NO_VALUE); self.setDecoder(incDecoder); } @@ -435,7 +454,6 @@ static TruffleString readline(PStringIO self, int size, @Builtin(name = J_TRUNCATE, minNumOfPositionalArgs = 1, parameterNames = {"$self", "size"}) @ArgumentClinic(name = "size", defaultValue = "PNone.NONE", useDefaultForNone = true) - @TypeSystemReference(PythonArithmeticTypes.class) @GenerateNodeFactory abstract static class TruncateNode extends ClosedCheckPythonBinaryClinicBuiltinNode { @@ -479,7 +497,7 @@ static Object obj(VirtualFrame frame, PStringIO self, Object arg, @Shared @Cached TruffleString.SubstringNode substringNode, @Shared @Cached TruffleStringBuilder.ToStringNode toStringNode, @Shared @Cached TruffleStringBuilder.AppendStringNode appendStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int size = asSizeNode.executeExact(frame, inliningTarget, indexNode.execute(frame, inliningTarget, arg), OverflowError); if (size >= 0) { if (size < self.getStringSize()) { @@ -487,13 +505,13 @@ static Object obj(VirtualFrame frame, PStringIO self, Object arg, } return size; } - return negSize(self, size, raiseNode.get(inliningTarget)); + return negSize(self, size, raiseNode); } @Specialization(guards = {"self.isOK()", "!self.isClosed()", "size < 0"}) static Object negSize(@SuppressWarnings("unused") PStringIO self, int size, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, NEGATIVE_SIZE_VALUE_D, size); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, NEGATIVE_SIZE_VALUE_D, size); } } @@ -517,7 +535,7 @@ static Object doWrite(VirtualFrame frame, PStringIO self, TruffleString s, @Cached TruffleStringBuilder.AppendStringNode appendStringNode, @Cached TruffleStringBuilder.AppendCodePointNode appendCodePointNode, @Cached TruffleStringBuilder.ToStringNode toStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int size = codePointLengthNode.execute(s, TS_ENCODING); if (size > 0) { writeString(frame, inliningTarget, self, s, raiseNode, decodeNode, replaceNode, codePointLengthNode, @@ -576,32 +594,32 @@ static Object seek(PStringIO self, int pos, int whence) { @SuppressWarnings("unused") @Specialization(guards = {"self.isOK()", "!self.isClosed()", "!isSupportedWhence(whence)"}) static Object whenceError(@SuppressWarnings("unused") PStringIO self, @SuppressWarnings("unused") int pos, int whence, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, INVALID_WHENCE_D_SHOULD_BE_0_1_OR_2, whence); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, INVALID_WHENCE_D_SHOULD_BE_0_1_OR_2, whence); } @Specialization(guards = {"self.isOK()", "!self.isClosed()", "isSupportedWhence(whence)", "pos != 0", "whence != 0"}) static Object largePos1(@SuppressWarnings("unused") PStringIO self, @SuppressWarnings("unused") int pos, @SuppressWarnings("unused") int whence, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(OSError, CAN_T_DO_NONZERO_CUR_RELATIVE_SEEKS); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, OSError, CAN_T_DO_NONZERO_CUR_RELATIVE_SEEKS); } @Specialization(guards = {"self.isOK()", "!self.isClosed()", "pos < 0", "whence == 0"}) static Object negPos(@SuppressWarnings("unused") PStringIO self, int pos, @SuppressWarnings("unused") int whence, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, NEGATIVE_SEEK_VALUE_D, pos); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, NEGATIVE_SEEK_VALUE_D, pos); } @Specialization(guards = "!self.isOK()") static Object initError(@SuppressWarnings("unused") PStringIO self, @SuppressWarnings("unused") int pos, @SuppressWarnings("unused") int whence, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_UNINIT); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } @Specialization(guards = "self.isClosed()") static Object closedError(@SuppressWarnings("unused") PStringIO self, @SuppressWarnings("unused") int pos, @SuppressWarnings("unused") int whence, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } @@ -632,11 +650,11 @@ static Object doit(VirtualFrame frame, PStringIO self, @Bind("this") Node inliningTarget, @Cached GetValueNode getValueNode, @Cached GetOrCreateDictNode getDict, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { Object initValue = getValueNode.execute(frame, self); Object readnl = self.getReadNewline() == null ? PNone.NONE : self.getReadNewline(); Object[] state = new Object[]{initValue, readnl, self.getPos(), getDict.execute(inliningTarget, self)}; - return factory.createTuple(state); + return PFactory.createTuple(language, state); } } @@ -656,11 +674,11 @@ static Object doit(VirtualFrame frame, PStringIO self, PTuple state, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Cached TruffleStringBuilder.AppendStringNode appendStringNode, @Cached HashingStorageAddAllToOther addAllToOtherNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { SequenceStorage storage = state.getSequenceStorage(); Object[] array = getArray.execute(inliningTarget, storage); if (storage.length() < 4) { - return notTuple(self, state, raiseNode.get(inliningTarget)); + return notTuple(self, state, raiseNode); } initNode.execute(frame, self, array[0], array[1]); /* @@ -685,18 +703,18 @@ static Object doit(VirtualFrame frame, PStringIO self, PTuple state, * erroneous (or malicious) inputs. */ if (!indexCheckNode.execute(inliningTarget, array[2])) { - throw raiseNode.get(inliningTarget).raise(TypeError, THIRD_ITEM_OF_STATE_MUST_BE_AN_INTEGER_GOT_P, array[2]); + throw raiseNode.raise(inliningTarget, TypeError, THIRD_ITEM_OF_STATE_MUST_BE_AN_INTEGER_GOT_P, array[2]); } int pos = asSizeNode.executeExact(frame, inliningTarget, array[2]); if (pos < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, POSITION_VALUE_CANNOT_BE_NEGATIVE); + throw raiseNode.raise(inliningTarget, ValueError, POSITION_VALUE_CANNOT_BE_NEGATIVE); } self.setPos(pos); /* Set the dictionary of the instance variables. */ if (!PGuards.isNone(array[3])) { if (!PGuards.isDict(array[3])) { - throw raiseNode.get(inliningTarget).raise(TypeError, THIRD_ITEM_OF_STATE_SHOULD_BE_A_DICT_GOT_A_P, array[3]); + throw raiseNode.raise(inliningTarget, TypeError, THIRD_ITEM_OF_STATE_SHOULD_BE_A_DICT_GOT_A_P, array[3]); } /* * Alternatively, we could replace the internal dictionary completely. However, it @@ -711,14 +729,14 @@ static Object doit(VirtualFrame frame, PStringIO self, PTuple state, @Specialization(guards = {"!self.isClosed()", "!isPTuple(state)"}) static Object notTuple(PStringIO self, Object state, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, P_SETSTATE_ARGUMENT_SHOULD_BE_D_TUPLE_GOT_P, self, 4, state); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, P_SETSTATE_ARGUMENT_SHOULD_BE_D_TUPLE_GOT_P, self, 4, state); } @Specialization(guards = "self.isClosed()") static Object closedError(@SuppressWarnings("unused") PStringIO self, @SuppressWarnings("unused") Object arg, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); } } @@ -788,8 +806,8 @@ static boolean closed(PStringIO self) { @Specialization(guards = "!self.isOK()") static Object initError(@SuppressWarnings("unused") PStringIO self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_UNINIT); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } } @@ -805,7 +823,7 @@ static Object close(PStringIO self) { } } - @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iternext, isComplex = true) @GenerateNodeFactory abstract static class IternextNode extends ClosedCheckPythonUnaryBuiltinNode { @@ -819,12 +837,11 @@ static Object builtin(PStringIO self, @SuppressWarnings("unused") @Exclusive @Cached IsBuiltinObjectExactProfile profile, @Cached TruffleStringBuilder.ToStringNode toStringNode, @Cached FindLineEndingNode findLineEndingNode, - @Cached TruffleString.SubstringNode substringNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Cached TruffleString.SubstringNode substringNode) { self.realize(); TruffleString line = stringioReadline(inliningTarget, self, -1, findLineEndingNode, substringNode, toStringNode); if (line.isEmpty()) { - throw raiseNode.get(inliningTarget).raiseStopIteration(); + throw TpIterNextBuiltin.iteratorExhausted(); } return line; } @@ -838,15 +855,15 @@ static Object slowpath(VirtualFrame frame, PStringIO self, @SuppressWarnings("unused") @Exclusive @Cached IsBuiltinObjectExactProfile profile, @Cached PyObjectCallMethodObjArgs callMethodReadline, @Cached CastToTruffleStringNode toString, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { self.realize(); Object res = callMethodReadline.execute(frame, inliningTarget, self, T_READLINE); if (!PGuards.isString(res)) { - throw raiseNode.get(inliningTarget).raise(OSError, S_SHOULD_HAVE_RETURNED_A_STR_OBJECT_NOT_P, T_READLINE, res); + throw raiseNode.raise(inliningTarget, OSError, S_SHOULD_HAVE_RETURNED_A_STR_OBJECT_NOT_P, T_READLINE, res); } TruffleString line = toString.execute(inliningTarget, res); if (line.isEmpty()) { - throw raiseNode.get(inliningTarget).raiseStopIteration(); + throw TpIterNextBuiltin.iteratorExhausted(); } return line; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOBaseBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOBaseBuiltins.java index 8636fbeb8d..0c2e88189a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOBaseBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOBaseBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -64,10 +64,11 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; @CoreFunctions(extendClasses = PythonBuiltinClassType.PTextIOBase) public final class TextIOBaseBuiltins extends PythonBuiltins { @@ -82,8 +83,8 @@ protected List> getNodeFa abstract static class DetachNode extends PythonBuiltinNode { @Specialization static Object detach(@SuppressWarnings("unused") Object self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, T_DETACH); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, T_DETACH); } } @@ -92,8 +93,8 @@ static Object detach(@SuppressWarnings("unused") Object self, abstract static class ReadNode extends PythonBuiltinNode { @Specialization static Object read(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object args, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, T_READ); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, T_READ); } } @@ -102,8 +103,8 @@ static Object read(@SuppressWarnings("unused") Object self, @SuppressWarnings("u abstract static class ReadlineNode extends PythonBuiltinNode { @Specialization static Object read(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object args, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, T_READLINE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, T_READLINE); } } @@ -112,8 +113,8 @@ static Object read(@SuppressWarnings("unused") Object self, @SuppressWarnings("u abstract static class WriteNode extends PythonBuiltinNode { @Specialization static Object write(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object args, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, T_WRITE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, T_WRITE); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java index 9961cdefa9..d406ab98a0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java @@ -117,9 +117,6 @@ import static com.oracle.graal.python.nodes.ErrorMessages.UNDERLYING_STREAM_IS_NOT_SEEKABLE; import static com.oracle.graal.python.nodes.PGuards.isNoValue; import static com.oracle.graal.python.nodes.PGuards.isPNone; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; import static com.oracle.graal.python.nodes.StringLiterals.T_NEWLINE; import static com.oracle.graal.python.runtime.exception.PythonErrorType.OSError; @@ -129,7 +126,11 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltins; @@ -143,6 +144,9 @@ import com.oracle.graal.python.builtins.objects.str.StringNodes.StringReplaceNode; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; import com.oracle.graal.python.lib.PyErrChainExceptions; import com.oracle.graal.python.lib.PyLongAsLongNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; @@ -151,10 +155,11 @@ import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.lib.PyObjectLookupAttr; +import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode; import com.oracle.graal.python.lib.PyObjectRichCompareBool; import com.oracle.graal.python.lib.PyObjectSizeNode; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; @@ -166,7 +171,7 @@ import com.oracle.graal.python.nodes.util.CastToJavaLongLossyNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Bind; @@ -187,6 +192,8 @@ @CoreFunctions(extendClasses = PTextIOWrapper) public final class TextIOWrapperBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = TextIOWrapperBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return TextIOWrapperBuiltinsFactory.getFactories(); @@ -196,8 +203,8 @@ abstract static class InitCheckPythonUnaryBuiltinNode extends PythonUnaryBuiltin @Specialization(guards = "!self.isOK()") @SuppressWarnings("unused") static Object initError(PTextIO self, - @Exclusive @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_UNINIT); + @Exclusive @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } } @@ -209,8 +216,8 @@ protected static boolean checkAttached(PTextIO self) { @Specialization(guards = {"self.isOK()", "self.isDetached()"}) @SuppressWarnings("unused") static Object attachError(PTextIO self, - @Exclusive @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, DETACHED_BUFFER); + @Exclusive @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, DETACHED_BUFFER); } } @@ -233,8 +240,8 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(guards = "!self.isOK()") @SuppressWarnings("unused") static Object initError(PTextIO self, Object o, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_UNINIT); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } } @@ -246,8 +253,8 @@ protected static boolean checkAttached(PTextIO self) { @Specialization(guards = {"self.isOK()", "self.isDetached()"}) @SuppressWarnings("unused") static Object attachError(PTextIO self, Object o, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, DETACHED_BUFFER); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, DETACHED_BUFFER); } } @@ -260,7 +267,21 @@ protected boolean isOpen(VirtualFrame frame, PTextIO self) { } } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 2, parameterNames = {"$self", "buffer", "encoding", "errors", "newline", "line_buffering", "write_through"}) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "TextIOWrapper", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class TextIOWrapperNode extends PythonBuiltinNode { + @Specialization + static PTextIO doNew(Object cls, @SuppressWarnings("unused") Object arg, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + // data filled in subsequent __init__ call - see TextIOWrapperBuiltins.InitNode + return PFactory.createTextIO(language, cls, getInstanceShape.execute(cls)); + } + } + + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "TextIOWrapper", minNumOfPositionalArgs = 2, parameterNames = {"$self", "buffer", "encoding", "errors", "newline", "line_buffering", "write_through"}) @ArgumentClinic(name = "encoding", conversion = ArgumentClinic.ClinicConversion.TString, defaultValue = "PNone.NONE", useDefaultForNone = true) @ArgumentClinic(name = "errors", conversion = ArgumentClinic.ClinicConversion.TString, defaultValue = "T_STRICT", useDefaultForNone = true) @ArgumentClinic(name = "newline", conversion = ArgumentClinic.ClinicConversion.TString, defaultValue = "PNone.NONE", useDefaultForNone = true) @@ -314,7 +335,7 @@ static Object reconfigure(VirtualFrame frame, PTextIO self, Object encodingObj, Object errorsObj, Object newlineObj, Object lineBufferingObj, Object writeThroughObj, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy lazyRaiseNode, + @Cached PRaiseNode lazyRaiseNode, @Cached IONodes.ToTruffleStringNode toStringNode, @Cached PyObjectCallMethodObjArgs callMethod, @Cached PyObjectIsTrueNode isTrueNode, @@ -354,8 +375,8 @@ static Object reconfigure(VirtualFrame frame, PTextIO self, Object encodingObj, @SuppressWarnings("unused") @Specialization(guards = "!isValid(self, encodingObj, errorsObj, newlineObj)") static Object error(VirtualFrame frame, PTextIO self, Object encodingObj, Object errorsObj, Object newlineObj, Object lineBufferingObj, Object writeThroughObj, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, NOT_POSSIBLE_TO_SET_THE_ENCODING_OR); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, NOT_POSSIBLE_TO_SET_THE_ENCODING_OR); } } @@ -371,8 +392,8 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(guards = {"checkAttached(self)", "isOpen(frame, self)", "!self.hasEncoder()"}) static Object write(@SuppressWarnings("unused") VirtualFrame frame, @SuppressWarnings("unused") PTextIO self, @SuppressWarnings("unused") TruffleString data, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, NOT_WRITABLE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, NOT_WRITABLE); } @Specialization(guards = {"checkAttached(self)", "isOpen(frame, self)", "self.hasEncoder()"}) @@ -386,7 +407,7 @@ static Object write(VirtualFrame frame, PTextIO self, TruffleString data, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Cached TruffleString.IndexOfCodePointNode indexOfCodePointNode, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { boolean haslf = false; boolean needflush = false; TruffleString text = data; @@ -420,7 +441,7 @@ static Object write(VirtualFrame frame, PTextIO self, TruffleString data, Object b = callMethodEncode.execute(frame, inliningTarget, self.getEncoder(), T_ENCODE, text); if (b != text && !(b instanceof PBytes)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ENCODER_SHOULD_RETURN_A_BYTES_OBJECT_NOT_P, b); + throw raiseNode.raise(inliningTarget, TypeError, ENCODER_SHOULD_RETURN_A_BYTES_OBJECT_NOT_P, b); } byte[] encodedText = bufferLib.getInternalOrCopiedByteArray(b); @@ -519,8 +540,8 @@ static TruffleString read(VirtualFrame frame, PTextIO self, int n, @Specialization(guards = {"checkAttached(self)", "isOpen(frame, self)", "!self.hasDecoder()"}) static Object noDecoder(@SuppressWarnings("unused") VirtualFrame frame, @SuppressWarnings("unused") PTextIO self, @SuppressWarnings("unused") int n, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, NOT_READABLE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, NOT_READABLE); } } @@ -675,14 +696,13 @@ static Object seek(VirtualFrame frame, PTextIO self, Object c, int whence, @Cached PyObjectCallMethodObjArgs callMethodFlush, @Cached PyObjectCallMethodObjArgs callMethodSeek, @Cached PyObjectCallMethodObjArgs callMethodRead, - @Cached PyObjectRichCompareBool.EqNode eqNode, + @Cached PyObjectRichCompareBool eqNode, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { checkClosedNode.execute(frame, self); if (!self.isSeekable()) { - throw raiseNode.get(inliningTarget).raise(IOUnsupportedOperation, UNDERLYING_STREAM_IS_NOT_SEEKABLE); + throw raiseNode.raise(inliningTarget, IOUnsupportedOperation, UNDERLYING_STREAM_IS_NOT_SEEKABLE); } Object cookieObj = c; @@ -690,8 +710,8 @@ static Object seek(VirtualFrame frame, PTextIO self, Object c, int whence, switch (whence) { case SEEK_CUR: /* seek relative to current position */ - if (!eqNode.compare(frame, inliningTarget, cookieObj, 0)) { - throw raiseNode.get(inliningTarget).raise(IOUnsupportedOperation, CAN_T_DO_NONZERO_CUR_RELATIVE_SEEKS); + if (!eqNode.execute(frame, inliningTarget, cookieObj, 0, RichCmpOp.Py_EQ)) { + throw raiseNode.raise(inliningTarget, IOUnsupportedOperation, CAN_T_DO_NONZERO_CUR_RELATIVE_SEEKS); } /* @@ -703,8 +723,8 @@ static Object seek(VirtualFrame frame, PTextIO self, Object c, int whence, case SEEK_END: /* seek relative to end of file */ - if (!eqNode.compare(frame, inliningTarget, cookieObj, 0)) { - throw raiseNode.get(inliningTarget).raise(IOUnsupportedOperation, CAN_T_DO_NONZERO_END_RELATIVE_SEEKS); + if (!eqNode.executeEq(frame, inliningTarget, cookieObj, 0)) { + throw raiseNode.raise(inliningTarget, IOUnsupportedOperation, CAN_T_DO_NONZERO_END_RELATIVE_SEEKS); } callMethodFlush.execute(frame, inliningTarget, self, T_FLUSH); @@ -718,7 +738,7 @@ static Object seek(VirtualFrame frame, PTextIO self, Object c, int whence, Object res = callMethodSeek.execute(frame, inliningTarget, self.getBuffer(), T_SEEK, 0, 2); if (self.hasEncoder()) { /* If seek() == 0, we are at the start of stream, otherwise not */ - encoderResetNode.execute(frame, inliningTarget, self, eqNode.compare(frame, inliningTarget, res, 0)); + encoderResetNode.execute(frame, inliningTarget, self, eqNode.executeEq(frame, inliningTarget, res, 0)); } return res; @@ -726,20 +746,20 @@ static Object seek(VirtualFrame frame, PTextIO self, Object c, int whence, break; default: - throw raiseNode.get(inliningTarget).raise(ValueError, INVALID_WHENCE_D_SHOULD_BE_D_D_OR_D, whence, SEEK_SET, SEEK_CUR, SEEK_END); + throw raiseNode.raise(inliningTarget, ValueError, INVALID_WHENCE_D_SHOULD_BE_D_D_OR_D, whence, SEEK_SET, SEEK_CUR, SEEK_END); } Object cookieLong = longNode.execute(frame, inliningTarget, cookieObj); PTextIO.CookieType cookie; if (cookieLong instanceof PInt) { if (((PInt) cookieLong).isNegative()) { - throw raiseNode.get(inliningTarget).raise(ValueError, NEGATIVE_SEEK_POSITION_D, cookieLong); + throw raiseNode.raise(inliningTarget, ValueError, NEGATIVE_SEEK_POSITION_D, cookieLong); } cookie = PTextIO.CookieType.parse((PInt) cookieLong, inliningTarget, overflow, raiseNode); } else { long l = toLong.execute(inliningTarget, cookieLong); if (l < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, NEGATIVE_SEEK_POSITION_D, cookieLong); + throw raiseNode.raise(inliningTarget, ValueError, NEGATIVE_SEEK_POSITION_D, cookieLong); } cookie = PTextIO.CookieType.parse(l, inliningTarget, overflow, raiseNode); } @@ -758,14 +778,14 @@ static Object seek(VirtualFrame frame, PTextIO self, Object c, int whence, self.clearSnapshot(); /* Restore the decoder to its state from the safe start point. */ - decoderSetStateNode.execute(frame, inliningTarget, self, cookie, factory); + decoderSetStateNode.execute(frame, inliningTarget, self, cookie); if (cookie.charsToSkip != 0) { /* Just like _read_chunk, feed the decoder and save a snapshot. */ Object inputChunk = callMethodRead.execute(frame, inliningTarget, self.getBuffer(), T_READ, cookie.bytesToFeed); if (!(inputChunk instanceof PBytes)) { - throw raiseNode.get(inliningTarget).raise(TypeError, UNDERLYING_READ_SHOULD_HAVE_RETURNED_A_BYTES_OBJECT_NOT_S, inputChunk); + throw raiseNode.raise(inliningTarget, TypeError, UNDERLYING_READ_SHOULD_HAVE_RETURNED_A_BYTES_OBJECT_NOT_S, inputChunk); } self.setSnapshotDecFlags(cookie.decFlags); @@ -777,7 +797,7 @@ static Object seek(VirtualFrame frame, PTextIO self, Object c, int whence, /* Skip chars_to_skip of the decoded characters. */ if (decodedLen < cookie.charsToSkip) { - throw raiseNode.get(inliningTarget).raise(OSError, CAN_T_RESTORE_LOGICAL_FILE_POSITION); + throw raiseNode.raise(inliningTarget, OSError, CAN_T_RESTORE_LOGICAL_FILE_POSITION); } self.incDecodedCharsUsed(cookie.charsToSkip); } else { @@ -798,14 +818,14 @@ protected static boolean checkAttached(PTextIO self) { @Specialization(guards = "!self.isOK()") static Object initError(@SuppressWarnings("unused") PTextIO self, @SuppressWarnings("unused") Object o1, @SuppressWarnings("unused") Object o2, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_UNINIT); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } @Specialization(guards = {"self.isOK()", "self.isDetached()"}) static Object attachError(@SuppressWarnings("unused") PTextIO self, @SuppressWarnings("unused") Object o1, @SuppressWarnings("unused") Object o2, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, DETACHED_BUFFER); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, DETACHED_BUFFER); } } @@ -815,11 +835,11 @@ abstract static class TellNode extends ClosedCheckPythonUnaryBuiltinNode { @Specialization(guards = "!self.isSeekable() || !self.isTelling()") static Object error(@SuppressWarnings("unused") VirtualFrame frame, @SuppressWarnings("unused") PTextIO self, - @Cached PRaiseNode raiseNode) { + @Bind("this") Node inliningTarget) { if (!self.isSeekable()) { - throw raiseNode.raise(IOUnsupportedOperation, UNDERLYING_STREAM_IS_NOT_SEEKABLE); + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, UNDERLYING_STREAM_IS_NOT_SEEKABLE); } else { - throw raiseNode.raise(OSError, TELLING_POSITION_DISABLED_BY_NEXT_CALL); + throw PRaiseNode.raiseStatic(inliningTarget, OSError, TELLING_POSITION_DISABLED_BY_NEXT_CALL); } } @@ -892,6 +912,7 @@ static Object didntMove(VirtualFrame frame, PTextIO self, }) static Object tell(VirtualFrame frame, PTextIO self, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Exclusive @Cached TextIOWrapperNodes.WriteFlushNode writeFlushNode, @Cached TextIOWrapperNodes.DecoderSetStateNode decoderSetStateNode, @Cached SequenceNodes.GetObjectArrayNode getObjectArrayNode, @@ -906,8 +927,7 @@ static Object tell(VirtualFrame frame, PTextIO self, @Exclusive @Cached PyLongAsLongNode asLongNode, @Cached PyObjectSizeNode sizeNode, @CachedLibrary(limit = "2") InteropLibrary isString, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { PTextIO.CookieType cookie = getCookie(frame, inliningTarget, self, writeFlushNode, callMethodFlush, callMethodTell, asLongNode); byte[] snapshotNextInput = self.getSnapshotNextInput(); int nextInputLength = self.getSnapshotNextInput().length; @@ -921,8 +941,8 @@ static Object tell(VirtualFrame frame, PTextIO self, assert (skipBack <= nextInputLength); while (skipBytes > 0) { /* Decode up to temptative start point */ - decoderSetStateNode.execute(frame, inliningTarget, self, cookie, factory); - PBytes in = factory.createBytes(snapshotNextInput, skipBytes); + decoderSetStateNode.execute(frame, inliningTarget, self, cookie); + PBytes in = PFactory.createBytes(language, snapshotNextInput, skipBytes); int charsDecoded = decoderDecode(frame, inliningTarget, self, in, callMethodDecode, toString, codePointLengthNode); if (charsDecoded <= decodedCharsUsed) { Object[] state = decoderGetstate(frame, inliningTarget, self, savedState, getObjectArrayNode, callMethodGetState, callMethodSetState, raiseNode); @@ -945,7 +965,7 @@ static Object tell(VirtualFrame frame, PTextIO self, } if (skipBytes <= 0) { skipBytes = 0; - decoderSetStateNode.execute(frame, inliningTarget, self, cookie, factory); + decoderSetStateNode.execute(frame, inliningTarget, self, cookie); } /* Note our initial start point. */ @@ -962,7 +982,7 @@ static Object tell(VirtualFrame frame, PTextIO self, int charsDecoded = 0; byte[] input = PythonUtils.arrayCopyOfRange(snapshotNextInput, skipBytes, nextInputLength); while (input.length > 0) { - PBytes start = factory.createBytes(input, 1); + PBytes start = PFactory.createBytes(language, input, 1); int n = decoderDecode(frame, inliningTarget, self, start, callMethodDecode, toString, codePointLengthNode); /* We got n chars for 1 byte */ charsDecoded += n; @@ -991,7 +1011,7 @@ static Object tell(VirtualFrame frame, PTextIO self, if (!isString.isString(decoded)) { fail(frame, inliningTarget, self, savedState, callMethodSetState); - throw raiseNode.get(inliningTarget).raise(TypeError, DECODER_SHOULD_RETURN_A_STRING_RESULT_NOT_P, decoded); + throw raiseNode.raise(inliningTarget, TypeError, DECODER_SHOULD_RETURN_A_STRING_RESULT_NOT_P, decoded); } charsDecoded += sizeNode.execute(frame, inliningTarget, decoded); @@ -999,7 +1019,7 @@ static Object tell(VirtualFrame frame, PTextIO self, if (charsDecoded < decodedCharsUsed) { fail(frame, inliningTarget, self, savedState, callMethodSetState); - throw raiseNode.get(inliningTarget).raise(OSError, CAN_T_RECONSTRUCT_LOGICAL_FILE_POSITION); + throw raiseNode.raise(inliningTarget, OSError, CAN_T_RECONSTRUCT_LOGICAL_FILE_POSITION); } } callMethodSetState.execute(frame, inliningTarget, self.getDecoder(), T_SETSTATE, savedState); @@ -1018,21 +1038,21 @@ static Object[] decoderGetstate(VirtualFrame frame, Node inliningTarget, PTextIO SequenceNodes.GetObjectArrayNode getArray, PyObjectCallMethodObjArgs callMethodGetState, PyObjectCallMethodObjArgs callMethodSetState, - PRaiseNode.Lazy raiseNode) { + PRaiseNode raiseNode) { Object state = callMethodGetState.execute(frame, inliningTarget, self.getDecoder(), T_GETSTATE); if (!(state instanceof PTuple)) { fail(frame, inliningTarget, self, saved_state, callMethodSetState); - throw raiseNode.get(inliningTarget).raise(TypeError, ILLEGAL_DECODER_STATE); + throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_DECODER_STATE); } Object[] array = getArray.execute(inliningTarget, state); if (array.length < 2) { fail(frame, inliningTarget, self, saved_state, callMethodSetState); - throw raiseNode.get(inliningTarget).raise(TypeError, ILLEGAL_DECODER_STATE); + throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_DECODER_STATE); } if (!(array[0] instanceof PBytes)) { fail(frame, inliningTarget, self, saved_state, callMethodSetState); - throw raiseNode.get(inliningTarget).raise(TypeError, ILLEGAL_DECODER_STATE_THE_FIRST, array[0]); + throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_DECODER_STATE_THE_FIRST, array[0]); } return array; } @@ -1172,10 +1192,10 @@ static Object none(PTextIO self, @SuppressWarnings("unused") PNone none) { static Object chunkSize(VirtualFrame frame, PTextIO self, Object arg, @Bind("this") Node inliningTarget, @Cached PyNumberAsSizeNode asSizeNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int size = asSizeNode.executeExact(frame, inliningTarget, arg, ValueError); if (size <= 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, A_STRICTLY_POSITIVE_INTEGER_IS_REQUIRED); + throw raiseNode.raise(inliningTarget, ValueError, A_STRICTLY_POSITIVE_INTEGER_IS_REQUIRED); } self.setChunkSize(size); return 0; @@ -1183,43 +1203,41 @@ static Object chunkSize(VirtualFrame frame, PTextIO self, Object arg, @Specialization(guards = {"self.isOK()", "!self.isDetached()"}) static Object noDelete(@SuppressWarnings("unused") PTextIO self, @SuppressWarnings("unused") DescriptorDeleteMarker marker, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(AttributeError, CANNOT_DELETE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, CANNOT_DELETE); } @Specialization(guards = "!self.isOK()") static Object initError(@SuppressWarnings("unused") PTextIO self, @SuppressWarnings("unused") Object arg, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, IO_UNINIT); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_UNINIT); } @Specialization(guards = {"self.isOK()", "self.isDetached()"}) static Object attachError(@SuppressWarnings("unused") PTextIO self, @SuppressWarnings("unused") Object arg, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, DETACHED_BUFFER); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, DETACHED_BUFFER); } } - @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iternext, isComplex = true) @GenerateNodeFactory abstract static class IternextNode extends ClosedCheckPythonUnaryBuiltinNode { @Specialization(guards = {"checkAttached(self)", "isOpen(frame, self)"}) - static TruffleString doit(VirtualFrame frame, PTextIO self, - @Bind("this") Node inliningTarget, - @Cached TextIOWrapperNodes.ReadlineNode readlineNode, - @Cached PRaiseNode.Lazy raiseNode) { + static Object doit(VirtualFrame frame, PTextIO self, + @Cached TextIOWrapperNodes.ReadlineNode readlineNode) { self.setTelling(false); TruffleString line = readlineNode.execute(frame, self, -1); if (line.isEmpty()) { self.clearSnapshot(); self.setTelling(self.isSeekable()); - throw raiseNode.get(inliningTarget).raiseStopIteration(); + throw TpIterNextBuiltin.iteratorExhausted(); } return line; } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends InitCheckPythonUnaryBuiltinNode { @@ -1227,13 +1245,13 @@ abstract static class ReprNode extends InitCheckPythonUnaryBuiltinNode { static Object doit(VirtualFrame frame, PTextIO self, @Bind("this") Node inliningTarget, @Cached PyObjectLookupAttr lookup, - @Cached("create(Repr)") LookupAndCallUnaryNode repr, + @Cached PyObjectReprAsTruffleStringNode repr, @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode, @Cached IONodes.ToTruffleStringNode toString, @Cached IsBuiltinObjectProfile isValueError, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (!PythonContext.get(inliningTarget).reprEnter(self)) { - throw raiseNode.get(inliningTarget).raise(RuntimeError, REENTRANT_CALL_INSIDE_P_REPR, self); + throw raiseNode.raise(inliningTarget, RuntimeError, REENTRANT_CALL_INSIDE_P_REPR, self); } try { Object nameobj = PNone.NO_VALUE; @@ -1250,11 +1268,11 @@ static Object doit(VirtualFrame frame, PTextIO self, } return simpleTruffleStringFormatNode.format("<_io.TextIOWrapper mode='%s' encoding='%s'>", toString.execute(inliningTarget, modeobj), self.getEncoding()); } - Object name = repr.executeObject(frame, nameobj); + Object name = repr.execute(frame, inliningTarget, nameobj); if (modeobj == PNone.NO_VALUE) { - return simpleTruffleStringFormatNode.format("<_io.TextIOWrapper name=%s encoding='%s'>", toString.execute(inliningTarget, name), self.getEncoding()); + return simpleTruffleStringFormatNode.format("<_io.TextIOWrapper name=%s encoding='%s'>", name, self.getEncoding()); } - return simpleTruffleStringFormatNode.format("<_io.TextIOWrapper name=%s mode='%s' encoding='%s'>", toString.execute(inliningTarget, name), toString.execute(inliningTarget, modeobj), + return simpleTruffleStringFormatNode.format("<_io.TextIOWrapper name=%s mode='%s' encoding='%s'>", name, toString.execute(inliningTarget, modeobj), self.getEncoding()); } finally { PythonContext.get(inliningTarget).reprLeave(self); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java index 9d0e636a58..bc1b33f72d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java @@ -42,7 +42,6 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.EncodingWarning; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.IOUnsupportedOperation; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PIncrementalNewlineDecoder; import static com.oracle.graal.python.builtins.modules.CodecsTruffleModuleBuiltins.T_INCREMENTALDECODER; import static com.oracle.graal.python.builtins.modules.CodecsTruffleModuleBuiltins.T_INCREMENTALENCODER; import static com.oracle.graal.python.builtins.modules.io.IONodes.T_CLOSED; @@ -77,6 +76,7 @@ import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.CodecsTruffleModuleBuiltins; import com.oracle.graal.python.builtins.modules.CodecsTruffleModuleBuiltins.MakeIncrementalcodecNode; import com.oracle.graal.python.builtins.modules.WarningsModuleBuiltins; @@ -100,7 +100,7 @@ import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -121,7 +121,7 @@ public abstract class TextIOWrapperNodes { public static final TruffleString T_CODECS_OPEN = tsLiteral("codecs.open()"); - protected static void validateNewline(TruffleString str, Node inliningTarget, PRaiseNode.Lazy raise, TruffleString.CodePointLengthNode codePointLengthNode, + protected static void validateNewline(TruffleString str, Node inliningTarget, PRaiseNode raise, TruffleString.CodePointLengthNode codePointLengthNode, TruffleString.CodePointAtIndexNode codePointAtIndexNode) { int len = codePointLengthNode.execute(str, TS_ENCODING); int c = len == 0 ? '\0' : codePointAtIndexNode.execute(str, 0, TS_ENCODING); @@ -129,7 +129,7 @@ protected static void validateNewline(TruffleString str, Node inliningTarget, PR !(c == '\n' && len == 1) && !(c == '\r' && len == 1) && !(c == '\r' && len == 2 && codePointAtIndexNode.execute(str, 1, TS_ENCODING) == '\n')) { - throw raise.get(inliningTarget).raise(ValueError, ILLEGAL_NEWLINE_VALUE_S, str); + throw raise.raise(inliningTarget, ValueError, ILLEGAL_NEWLINE_VALUE_S, str); } } @@ -169,8 +169,8 @@ static void ideal(@SuppressWarnings("unused") PTextIO self) { @Specialization(guards = {"self.isFileIO()", "self.getFileIO().isClosed()"}) static void error(@SuppressWarnings("unused") PTextIO self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.IO_CLOSED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.IO_CLOSED); } @Specialization(guards = "!self.isFileIO()") @@ -178,10 +178,10 @@ static void checkGeneric(VirtualFrame frame, PTextIO self, @Bind("this") Node inliningTarget, @Cached PyObjectGetAttr getAttr, @Cached PyObjectIsTrueNode isTrueNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object res = getAttr.execute(frame, inliningTarget, self.getBuffer(), T_CLOSED); if (isTrueNode.execute(frame, res)) { - error(self, raiseNode.get(inliningTarget)); + error(self, raiseNode); } } } @@ -199,10 +199,10 @@ static void nothingTodo(@SuppressWarnings("unused") PTextIO self) { @Specialization(guards = "self.hasPendingBytes()") static void writeflush(VirtualFrame frame, Node inliningTarget, PTextIO self, - @Cached(inline = false) PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached PyObjectCallMethodObjArgs callMethod) { byte[] pending = self.getAndClearPendingBytes(); - PBytes b = factory.createBytes(pending); + PBytes b = PFactory.createBytes(language, pending); callMethod.execute(frame, inliningTarget, self.getBuffer(), T_WRITE, b); // TODO: check _PyIO_trap_eintr } @@ -504,7 +504,7 @@ static boolean readChunk(VirtualFrame frame, Node inliningTarget, PTextIO self, @Cached(inline = false) TruffleString.CodePointLengthNode codePointLengthNode, @CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { /* * The return value is True unless EOF was reached. The decoded string is placed in * self._decoded_chars (replacing its previous value). The entire input chunk is sent to @@ -524,15 +524,15 @@ static boolean readChunk(VirtualFrame frame, Node inliningTarget, PTextIO self, * with decoder state (b'', decFlags). */ if (!(state instanceof PTuple)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ILLEGAL_DECODER_STATE); + throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_DECODER_STATE); } Object[] array = getArray.execute(inliningTarget, state); if (array.length < 2) { - throw raiseNode.get(inliningTarget).raise(TypeError, ILLEGAL_DECODER_STATE); + throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_DECODER_STATE); } if (!(array[0] instanceof PBytes)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ILLEGAL_DECODER_STATE_THE_FIRST, array[0]); + throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_DECODER_STATE_THE_FIRST, array[0]); } decBuffer = (PBytes) array[0]; @@ -557,7 +557,7 @@ static boolean readChunk(VirtualFrame frame, Node inliningTarget, PTextIO self, try { inputChunkBuf = bufferAcquireLib.acquireReadonly(inputChunk, frame, indirectCallData); } catch (PException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, S_SHOULD_HAVE_RETURNED_A_BYTES_LIKE_OBJECT_NOT_P, (self.isHasRead1() ? T_READ1 : T_READ), inputChunk); + throw raiseNode.raise(inliningTarget, TypeError, S_SHOULD_HAVE_RETURNED_A_BYTES_LIKE_OBJECT_NOT_P, (self.isHasRead1() ? T_READ1 : T_READ), inputChunk); } try { int nbytes = bufferLib.getBufferLength(inputChunkBuf); @@ -598,8 +598,8 @@ static boolean readChunk(VirtualFrame frame, Node inliningTarget, PTextIO self, @Specialization(guards = "!self.hasDecoder()") static boolean error(@SuppressWarnings("unused") PTextIO self, @SuppressWarnings("unused") int size_hint, - @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(IOUnsupportedOperation, NOT_READABLE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, IOUnsupportedOperation, NOT_READABLE); } } @@ -631,10 +631,10 @@ static TruffleString decodeGeneric(VirtualFrame frame, Object decoder, Object o, @GenerateCached(false) protected abstract static class DecoderSetStateNode extends Node { - public abstract void execute(VirtualFrame frame, Node inliningTarget, PTextIO self, PTextIO.CookieType cookie, PythonObjectFactory factory); + public abstract void execute(VirtualFrame frame, Node inliningTarget, PTextIO self, PTextIO.CookieType cookie); @Specialization(guards = "!self.hasDecoder()") - static void nothing(@SuppressWarnings("unused") PTextIO self, @SuppressWarnings("unused") PTextIO.CookieType cookie, @SuppressWarnings("unused") PythonObjectFactory factory) { + static void nothing(@SuppressWarnings("unused") PTextIO self, @SuppressWarnings("unused") PTextIO.CookieType cookie) { // nothing to do. } @@ -650,15 +650,16 @@ protected static boolean isAtInit(PTextIO.CookieType cookie) { } @Specialization(guards = {"self.hasDecoder()", "isAtInit(cookie)"}) - static void atInit(VirtualFrame frame, Node inliningTarget, PTextIO self, @SuppressWarnings("unused") PTextIO.CookieType cookie, @SuppressWarnings("unused") PythonObjectFactory factory, + static void atInit(VirtualFrame frame, Node inliningTarget, PTextIO self, @SuppressWarnings("unused") PTextIO.CookieType cookie, @Exclusive @Cached PyObjectCallMethodObjArgs callMethodReset) { callMethodReset.execute(frame, inliningTarget, self.getDecoder(), T_RESET); } @Specialization(guards = {"self.hasDecoder()", "!isAtInit(cookie)"}) - static void decoderSetstate(VirtualFrame frame, Node inliningTarget, PTextIO self, PTextIO.CookieType cookie, PythonObjectFactory factory, + static void decoderSetstate(VirtualFrame frame, Node inliningTarget, PTextIO self, PTextIO.CookieType cookie, + @Bind PythonLanguage language, @Exclusive @Cached PyObjectCallMethodObjArgs callMethodSetState) { - PTuple tuple = factory.createTuple(new Object[]{factory.createEmptyBytes(), cookie.decFlags}); + PTuple tuple = PFactory.createTuple(language, new Object[]{PFactory.createEmptyBytes(language), cookie.decFlags}); callMethodSetState.execute(frame, inliningTarget, self.getDecoder(), T_SETSTATE, tuple); } @@ -723,10 +724,10 @@ void nothing(@SuppressWarnings("unused") PTextIO self) { static void fixEncoderState(VirtualFrame frame, @SuppressWarnings("unused") Node inliningTarget, PTextIO self, @Cached PyObjectCallMethodObjArgs callMethodTell, @Cached PyObjectCallMethodObjArgs callMethodSetState, - @Cached PyObjectRichCompareBool.EqNode eqNode) { + @Cached PyObjectRichCompareBool eqNode) { self.setEncodingStartOfStream(true); Object cookieObj = callMethodTell.execute(frame, inliningTarget, self.getBuffer(), T_TELL); - if (!eqNode.compare(frame, inliningTarget, cookieObj, 0)) { + if (!eqNode.executeEq(frame, inliningTarget, cookieObj, 0)) { self.setEncodingStartOfStream(false); callMethodSetState.execute(frame, inliningTarget, self.getEncoder(), T_SETSTATE, 0); } @@ -747,15 +748,14 @@ static void setDecoder(VirtualFrame frame, Node inliningTarget, PTextIO self, Ob @Cached(inline = false) MakeIncrementalcodecNode makeIncrementalcodecNode, @Cached InlinedConditionProfile isTrueProfile, @Cached PyObjectCallMethodObjArgs callMethodReadable, - @Cached PyObjectIsTrueNode isTrueNode, - @Cached(inline = false) PythonObjectFactory factory) { + @Cached PyObjectIsTrueNode isTrueNode) { Object res = callMethodReadable.execute(frame, inliningTarget, self.getBuffer(), T_READABLE); if (isTrueProfile.profile(inliningTarget, !isTrueNode.execute(frame, res))) { return; } Object decoder = makeIncrementalcodecNode.execute(frame, codecInfo, errors, T_INCREMENTALDECODER); if (self.isReadUniversal()) { - PNLDecoder incDecoder = factory.createNLDecoder(PIncrementalNewlineDecoder); + PNLDecoder incDecoder = PFactory.createNLDecoder(PythonLanguage.get(inliningTarget)); IncrementalNewlineDecoderBuiltins.InitNode.internalInit(incDecoder, decoder, self.isReadTranslate()); self.setDecoder(incDecoder); } else { @@ -816,7 +816,7 @@ static void init(VirtualFrame frame, Node inliningTarget, PTextIO self, Object b @Cached(inline = false) TruffleString.IndexOfCodePointNode indexOfCodePointNode, @Cached(inline = false) TruffleString.EqualNode equalNode, @Cached(inline = false) WarningsModuleBuiltins.WarnNode warnNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { self.setOK(false); self.setDetached(false); // encoding and newline are processed through arguments clinic and safe to cast. @@ -830,13 +830,13 @@ static void init(VirtualFrame frame, Node inliningTarget, PTextIO self, Object b encoding = null; } else { if (indexOfCodePointNode.execute(encoding, 0, 0, codePointLengthNode.execute(encoding, TS_ENCODING), TS_ENCODING) != -1) { - throw raiseNode.get(inliningTarget).raise(ValueError, EMBEDDED_NULL_CHARACTER); + throw raiseNode.raise(inliningTarget, ValueError, EMBEDDED_NULL_CHARACTER); } } if (newline != null) { if (indexOfCodePointNode.execute(newline, 0, 0, codePointLengthNode.execute(newline, TS_ENCODING), TS_ENCODING) != -1) { - throw raiseNode.get(inliningTarget).raise(ValueError, EMBEDDED_NULL_CHARACTER); + throw raiseNode.raise(inliningTarget, ValueError, EMBEDDED_NULL_CHARACTER); } validateNewline(newline, inliningTarget, raiseNode, codePointLengthNode, codePointAtIndexNode); } @@ -856,7 +856,7 @@ static void init(VirtualFrame frame, Node inliningTarget, PTextIO self, Object b } else if (encoding != null) { self.setEncoding(encoding); } else { - throw raiseNode.get(inliningTarget).raise(OSError, COULD_NOT_DETERMINE_DEFAULT_ENCODING); + throw raiseNode.raise(inliningTarget, OSError, COULD_NOT_DETERMINE_DEFAULT_ENCODING); } /* Check we have been asked for a real text encoding */ diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java index 5aa6922398..8a86eb6741 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2020, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2020 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -12,7 +12,6 @@ import static com.oracle.graal.python.nodes.PGuards.isPFloat; import static com.oracle.graal.python.nodes.PGuards.isPInt; import static com.oracle.graal.python.nodes.PGuards.isString; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__; import static com.oracle.graal.python.nodes.truffle.TruffleStringMigrationHelpers.isJavaString; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; @@ -21,11 +20,15 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.modules.json.JSONEncoderBuiltinsClinicProviders.MakeEncoderClinicProviderGen; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.common.HashingStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetIterator; @@ -38,15 +41,20 @@ import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.floats.FloatBuiltins; import com.oracle.graal.python.builtins.objects.floats.PFloat; +import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.list.ListBuiltins.ListSortNode; import com.oracle.graal.python.builtins.objects.list.PList; +import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.builtins.objects.str.StringNodes; import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyListCheckExactNode; +import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyTupleCheckExactNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; @@ -56,18 +64,17 @@ import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.formatting.FloatFormatter; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; @@ -87,18 +94,65 @@ public final class JSONEncoderBuiltins extends PythonBuiltins { private static final TruffleString T_BRACES = tsLiteral("{}"); private static final TruffleString T_BRACKETS = tsLiteral("[]"); + public static final TpSlots SLOTS = JSONEncoderBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return JSONEncoderBuiltinsFactory.getFactories(); } - @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, parameterNames = {"$self", "obj", "_current_indent_level"}) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "make_encoder", minNumOfPositionalArgs = 10, // + parameterNames = {"$cls", "markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan"}) + @ArgumentClinic(name = "key_separator", conversion = ArgumentClinic.ClinicConversion.TString) + @ArgumentClinic(name = "item_separator", conversion = ArgumentClinic.ClinicConversion.TString) + @ArgumentClinic(name = "sort_keys", conversion = ArgumentClinic.ClinicConversion.Boolean) + @ArgumentClinic(name = "skipkeys", conversion = ArgumentClinic.ClinicConversion.Boolean) + @ArgumentClinic(name = "allow_nan", conversion = ArgumentClinic.ClinicConversion.Boolean) + @GenerateNodeFactory + public abstract static class MakeEncoder extends PythonClinicBuiltinNode { + + @Override + protected ArgumentClinicProvider getArgumentClinic() { + return MakeEncoderClinicProviderGen.INSTANCE; + } + + @Specialization + @TruffleBoundary + PJSONEncoder doNew(Object cls, Object markers, Object defaultFn, Object encoder, Object indent, TruffleString keySeparator, TruffleString itemSeparator, boolean sortKeys, + boolean skipKeys, boolean allowNan) { + if (markers != PNone.NONE && !(markers instanceof PDict)) { + throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.MAKE_ENCODER_ARG_1_MUST_BE_DICT, markers); + } + + PJSONEncoder.FastEncode fastEncode = PJSONEncoder.FastEncode.None; + Object encoderAsFun = encoder; + if (encoder instanceof PBuiltinMethod encoderMethod) { + encoderAsFun = encoderMethod.getFunction(); + } + if (encoderAsFun instanceof PBuiltinFunction function) { + Class nodeClass = function.getNodeClass(); + if (nodeClass != null) { + if (JSONModuleBuiltins.EncodeBaseString.class.isAssignableFrom(nodeClass)) { + fastEncode = PJSONEncoder.FastEncode.FastEncode; + } else if (JSONModuleBuiltins.EncodeBaseStringAscii.class.isAssignableFrom(nodeClass)) { + fastEncode = PJSONEncoder.FastEncode.FastEncodeAscii; + } + } + } + return PFactory.createJSONEncoder(PythonLanguage.get(null), cls, TypeNodes.GetInstanceShape.executeUncached(cls), + markers, defaultFn, encoder, indent, keySeparator, itemSeparator, sortKeys, skipKeys, allowNan, fastEncode); + } + } + + @Slot(value = SlotKind.tp_call, isComplex = true) + @SlotSignature(name = "_iterencode", minNumOfPositionalArgs = 1, parameterNames = {"$self", "obj", "_current_indent_level"}) @ArgumentClinic(name = "_current_indent_level", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0", useDefaultForNone = true) @GenerateNodeFactory public abstract static class CallEncoderNode extends PythonTernaryClinicBuiltinNode { @Child private LookupAndCallUnaryNode callGetItems = LookupAndCallUnaryNode.create(SpecialMethodNames.T_ITEMS); - @Child private LookupAndCallUnaryNode callGetDictIter = LookupAndCallUnaryNode.create(SpecialMethodSlot.Iter); - @Child private LookupAndCallUnaryNode callGetListIter = LookupAndCallUnaryNode.create(SpecialMethodSlot.Iter); + @Child private PyObjectGetIter callGetDictIter = PyObjectGetIter.create(); + @Child private PyObjectGetIter callGetListIter = PyObjectGetIter.create(); @Child private ListSortNode sortList = ListSortNode.create(); @Override @@ -108,8 +162,8 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization protected PTuple call(PJSONEncoder self, Object obj, @SuppressWarnings("unused") int indent, - @Cached PythonObjectFactory factory) { - return factory.createTuple(new Object[]{jsonEncode(self, obj)}); + @Bind PythonLanguage language) { + return PFactory.createTuple(language, new Object[]{jsonEncode(self, obj)}); } @TruffleBoundary @@ -133,7 +187,7 @@ private void appendConst(TruffleStringBuilderUTF32 builder, Object obj) { private void appendFloat(PJSONEncoder encoder, TruffleStringBuilderUTF32 builder, double obj) { if (!Double.isFinite(obj)) { if (!encoder.allowNan) { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.OUT_OF_RANGE_FLOAT_NOT_JSON_COMPLIANT); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.OUT_OF_RANGE_FLOAT_NOT_JSON_COMPLIANT); } if (obj > 0) { builder.appendStringUncached(T_POSITIVE_INFINITY); @@ -164,7 +218,7 @@ private void appendString(PJSONEncoder encoder, TruffleStringBuilderUTF32 builde case None: Object result = CallUnaryMethodNode.getUncached().executeObject(encoder.encoder, obj); if (!isString(result)) { - throw PRaiseNode.raiseUncached(this, TypeError, ErrorMessages.ENCODER_MUST_RETURN_STR, result); + throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.ENCODER_MUST_RETURN_STR, result); } builder.appendStringUncached(CastToTruffleStringNode.executeUncached(result)); break; @@ -229,7 +283,7 @@ private static void endRecursion(PJSONEncoder encoder, Object obj) { private void startRecursion(PJSONEncoder encoder, Object obj) { if (encoder.markers != PNone.NONE) { if (!encoder.tryAddCircular(obj)) { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.CIRCULAR_REFERENCE_DETECTED); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.CIRCULAR_REFERENCE_DETECTED); } } } @@ -265,23 +319,21 @@ private void appendDictSlowPath(PJSONEncoder encoder, TruffleStringBuilderUTF32 if (encoder.sortKeys) { sortList.execute(null, items); } - Object iter = callGetDictIter.executeObject(null, items); + Object iter = callGetDictIter.executeCached(null, items); boolean first = true; while (true) { - Object item; try { - item = GetNextNode.getUncached().execute(null, iter); - } catch (PException e) { - e.expectStopIteration(null, IsBuiltinObjectProfile.getUncached()); + Object item = PyIterNextNode.executeUncached(iter); + if (!(item instanceof PTuple itemTuple) || itemTuple.getSequenceStorage().length() != 2) { + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.ITEMS_MUST_RETURN_2_TUPLES); + } + SequenceStorage sequenceStorage = itemTuple.getSequenceStorage(); + Object key = SequenceStorageNodes.GetItemScalarNode.executeUncached(sequenceStorage, 0); + Object value = SequenceStorageNodes.GetItemScalarNode.executeUncached(sequenceStorage, 1); + first = appendDictEntry(encoder, builder, first, key, value); + } catch (IteratorExhausted e) { break; } - if (!(item instanceof PTuple itemTuple) || itemTuple.getSequenceStorage().length() != 2) { - throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.ITEMS_MUST_RETURN_2_TUPLES); - } - SequenceStorage sequenceStorage = itemTuple.getSequenceStorage(); - Object key = SequenceStorageNodes.GetItemScalarNode.executeUncached(sequenceStorage, 0); - Object value = SequenceStorageNodes.GetItemScalarNode.executeUncached(sequenceStorage, 1); - first = appendDictEntry(encoder, builder, first, key, value); } } @@ -296,7 +348,7 @@ private boolean appendDictEntry(PJSONEncoder encoder, TruffleStringBuilderUTF32 if (encoder.skipKeys) { return true; } - throw PRaiseNode.raiseUncached(this, TypeError, ErrorMessages.KEYS_MUST_BE_STR_INT___NOT_P, key); + throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.KEYS_MUST_BE_STR_INT___NOT_P, key); } builder.appendCodePointUncached('"'); appendSimpleObj(encoder, builder, key); @@ -333,21 +385,19 @@ private void appendList(PJSONEncoder encoder, TruffleStringBuilderUTF32 builder, } private void appendListSlowPath(PJSONEncoder encoder, TruffleStringBuilderUTF32 builder, PSequence list) { - Object iter = callGetListIter.executeObject(null, list); + Object iter = callGetListIter.executeCached(null, list); boolean first = true; while (true) { - Object item; try { - item = GetNextNode.getUncached().execute(null, iter); - } catch (PException e) { - e.expectStopIteration(null, IsBuiltinObjectProfile.getUncached()); + Object item = PyIterNextNode.executeUncached(iter); + if (!first) { + builder.appendStringUncached(encoder.itemSeparator); + } + first = false; + appendListObj(encoder, builder, item); + } catch (IteratorExhausted e) { break; } - if (!first) { - builder.appendStringUncached(encoder.itemSeparator); - } - first = false; - appendListObj(encoder, builder, item); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONModuleBuiltins.java index 7a24558a6f..594537365a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONModuleBuiltins.java @@ -5,13 +5,11 @@ */ package com.oracle.graal.python.builtins.modules.json; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; -import static com.oracle.graal.python.nodes.StringLiterals.T_STRICT; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; -import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -19,31 +17,20 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.modules.json.JSONScannerBuiltins.IntRef; -import com.oracle.graal.python.builtins.modules.json.PJSONEncoder.FastEncode; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToJavaStringCheckedNode; -import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.SpecialAttributeNames; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetFixedAttributeNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; import com.oracle.truffle.api.strings.TruffleStringBuilder; @@ -94,11 +81,11 @@ protected ArgumentClinicProvider getArgumentClinic() { Object call(Object string, int end, boolean strict, @Bind("this") Node inliningTarget, @Cached CastToJavaStringCheckedNode castString, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { IntRef nextIdx = new IntRef(); TruffleString result = JSONScannerBuiltins.scanStringUnicode(castString.cast(inliningTarget, string, ErrorMessages.FIRST_ARG_MUST_BE_STRING_NOT_P, string), end, strict, nextIdx, this); - return factory.createTuple(new Object[]{result, nextIdx.value}); + return PFactory.createTuple(language, new Object[]{result, nextIdx.value}); } } @@ -124,7 +111,7 @@ static TruffleString call(TruffleString string, @Cached TruffleStringBuilder.AppendStringNode appendStringNode, @Cached TruffleString.SubstringNode substringNode, @Cached TruffleStringBuilder.ToStringNode toStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { int len = string.byteLength(TS_ENCODING); // 12.5% overallocated, TruffleStringBuilder.ToStringNode will copy anyway @@ -132,7 +119,7 @@ static TruffleString call(TruffleString string, JSONUtils.appendString(string, createCodePointIteratorNode.execute(string, TS_ENCODING), builder, false, nextNode, appendCodePointNode, appendStringNode, substringNode); return toStringNode.execute(builder); } catch (OutOfMemoryError | NegativeArraySizeException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.OverflowError, ErrorMessages.STR_TOO_LONG_TO_ESCAPE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.OverflowError, ErrorMessages.STR_TOO_LONG_TO_ESCAPE); } } @@ -160,7 +147,7 @@ static TruffleString call(TruffleString string, @Cached TruffleStringBuilder.AppendStringNode appendStringNode, @Cached TruffleString.SubstringNode substringNode, @Cached TruffleStringBuilder.ToStringNode toStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { int len = string.byteLength(TS_ENCODING); // 12.5% overallocated, TruffleStringBuilder.ToStringNode will copy anyway @@ -169,79 +156,8 @@ static TruffleString call(TruffleString string, nextNode, appendCodePointNode, appendStringNode, substringNode); return toStringNode.execute(builder); } catch (OutOfMemoryError | NegativeArraySizeException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.OverflowError, ErrorMessages.STR_TOO_LONG_TO_ESCAPE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.OverflowError, ErrorMessages.STR_TOO_LONG_TO_ESCAPE); } } } - - @Builtin(name = "make_scanner", parameterNames = {"$cls", "context"}, constructsClass = PythonBuiltinClassType.JSONScanner, // - doc = "_iterencode(obj, _current_indent_level) -> iterable") - @GenerateNodeFactory - public abstract static class MakeScanner extends PythonBinaryBuiltinNode { - - @Child private GetFixedAttributeNode getStrict = GetFixedAttributeNode.create(T_STRICT); - @Child private GetFixedAttributeNode getObjectHook = GetFixedAttributeNode.create(tsLiteral("object_hook")); - @Child private GetFixedAttributeNode getObjectPairsHook = GetFixedAttributeNode.create(tsLiteral("object_pairs_hook")); - @Child private GetFixedAttributeNode getParseFloat = GetFixedAttributeNode.create(tsLiteral("parse_float")); - @Child private GetFixedAttributeNode getParseInt = GetFixedAttributeNode.create(tsLiteral("parse_int")); - @Child private GetFixedAttributeNode getParseConstant = GetFixedAttributeNode.create(tsLiteral("parse_constant")); - - @Specialization - public PJSONScanner doNew(VirtualFrame frame, Object cls, Object context, - @Cached PyObjectIsTrueNode castStrict, - @Cached PythonObjectFactory factory) { - - boolean strict = castStrict.execute(frame, getStrict.execute(frame, context)); - Object objectHook = getObjectHook.execute(frame, context); - Object objectPairsHook = getObjectPairsHook.execute(frame, context); - Object parseFloat = getParseFloat.execute(frame, context); - Object parseInt = getParseInt.execute(frame, context); - Object parseConstant = getParseConstant.execute(frame, context); - return factory.createJSONScanner(cls, strict, objectHook, objectPairsHook, parseFloat, parseInt, parseConstant); - } - } - - @Builtin(name = "make_encoder", minNumOfPositionalArgs = 10, // - parameterNames = {"$cls", "markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan"}, // - constructsClass = PythonBuiltinClassType.JSONEncoder, // - doc = "JSON scanner object") - @ArgumentClinic(name = "key_separator", conversion = ArgumentClinic.ClinicConversion.TString) - @ArgumentClinic(name = "item_separator", conversion = ArgumentClinic.ClinicConversion.TString) - @ArgumentClinic(name = "sort_keys", conversion = ArgumentClinic.ClinicConversion.Boolean) - @ArgumentClinic(name = "skipkeys", conversion = ArgumentClinic.ClinicConversion.Boolean) - @ArgumentClinic(name = "allow_nan", conversion = ArgumentClinic.ClinicConversion.Boolean) - @GenerateNodeFactory - public abstract static class MakeEncoder extends PythonClinicBuiltinNode { - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return JSONModuleBuiltinsClinicProviders.MakeEncoderClinicProviderGen.INSTANCE; - } - - @Specialization - @TruffleBoundary - PJSONEncoder doNew(Object cls, Object markers, Object defaultFn, Object encoder, Object indent, TruffleString keySeparator, TruffleString itemSeparator, boolean sortKeys, - boolean skipKeys, boolean allowNan) { - if (markers != PNone.NONE && !(markers instanceof PDict)) { - throw PRaiseNode.raiseUncached(this, TypeError, ErrorMessages.MAKE_ENCODER_ARG_1_MUST_BE_DICT, markers); - } - - FastEncode fastEncode = FastEncode.None; - Object encoderAsFun = encoder; - if (encoder instanceof PBuiltinMethod encoderMethod) { - encoderAsFun = encoderMethod.getFunction(); - } - if (encoderAsFun instanceof PBuiltinFunction function) { - Class nodeClass = function.getNodeClass(); - if (nodeClass != null) { - if (JSONModuleBuiltins.EncodeBaseString.class.isAssignableFrom(nodeClass)) { - fastEncode = FastEncode.FastEncode; - } else if (JSONModuleBuiltins.EncodeBaseStringAscii.class.isAssignableFrom(nodeClass)) { - fastEncode = FastEncode.FastEncodeAscii; - } - } - } - return getContext().factory().createJSONEncoder(cls, markers, defaultFn, encoder, indent, keySeparator, itemSeparator, sortKeys, skipKeys, allowNan, fastEncode); - } - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONScannerBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONScannerBuiltins.java index 97146e249d..94a58f3374 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONScannerBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONScannerBuiltins.java @@ -5,7 +5,7 @@ */ package com.oracle.graal.python.builtins.modules.json; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__; +import static com.oracle.graal.python.nodes.StringLiterals.T_STRICT; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; @@ -14,7 +14,9 @@ import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; @@ -25,31 +27,35 @@ import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.floats.FloatUtils; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyFloatCheckExactNode; import com.oracle.graal.python.lib.PyLongCheckExactNode; import com.oracle.graal.python.lib.PyLongFromUnicodeObject; +import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.attributes.GetAttributeNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.statement.AbstractImportNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.strings.TruffleString; @CoreFunctions(extendClasses = PythonBuiltinClassType.JSONScanner) @@ -61,12 +67,43 @@ static final class IntRef { int value; } + public static final TpSlots SLOTS = JSONScannerBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return JSONScannerBuiltinsFactory.getFactories(); } - @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, parameterNames = {"$self", "string", "idx"}) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "make_scanner", parameterNames = {"$cls", "context"}) + @GenerateNodeFactory + public abstract static class MakeScanner extends PythonBinaryBuiltinNode { + + @Child private GetAttributeNode.GetFixedAttributeNode getStrict = GetAttributeNode.GetFixedAttributeNode.create(T_STRICT); + @Child private GetAttributeNode.GetFixedAttributeNode getObjectHook = GetAttributeNode.GetFixedAttributeNode.create(tsLiteral("object_hook")); + @Child private GetAttributeNode.GetFixedAttributeNode getObjectPairsHook = GetAttributeNode.GetFixedAttributeNode.create(tsLiteral("object_pairs_hook")); + @Child private GetAttributeNode.GetFixedAttributeNode getParseFloat = GetAttributeNode.GetFixedAttributeNode.create(tsLiteral("parse_float")); + @Child private GetAttributeNode.GetFixedAttributeNode getParseInt = GetAttributeNode.GetFixedAttributeNode.create(tsLiteral("parse_int")); + @Child private GetAttributeNode.GetFixedAttributeNode getParseConstant = GetAttributeNode.GetFixedAttributeNode.create(tsLiteral("parse_constant")); + + @Specialization + public PJSONScanner doNew(VirtualFrame frame, Object cls, Object context, + @Cached PyObjectIsTrueNode castStrict, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + + boolean strict = castStrict.execute(frame, getStrict.execute(frame, context)); + Object objectHook = getObjectHook.execute(frame, context); + Object objectPairsHook = getObjectPairsHook.execute(frame, context); + Object parseFloat = getParseFloat.execute(frame, context); + Object parseInt = getParseInt.execute(frame, context); + Object parseConstant = getParseConstant.execute(frame, context); + return PFactory.createJSONScanner(language, cls, getInstanceShape.execute(cls), strict, objectHook, objectPairsHook, parseFloat, parseInt, parseConstant); + } + } + + @Slot(value = SlotKind.tp_call, isComplex = true) + @SlotSignature(name = "scan_once", minNumOfPositionalArgs = 1, parameterNames = {"$self", "string", "idx"}) @ArgumentClinic(name = "string", conversion = ArgumentClinic.ClinicConversion.TString) @ArgumentClinic(name = "idx", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0", useDefaultForNone = true) @GenerateNodeFactory @@ -78,11 +115,6 @@ public abstract static class CallScannerNode extends PythonTernaryClinicBuiltinN @Child private CallUnaryMethodNode callParseConstant = CallUnaryMethodNode.create(); @Child private CallUnaryMethodNode callObjectHook = CallUnaryMethodNode.create(); @Child private CallUnaryMethodNode callObjectPairsHook = CallUnaryMethodNode.create(); - @Child private PythonObjectFactory factory = PythonObjectFactory.create(); - - @CompilationFinal private Shape tupleInstanceShape; - @CompilationFinal private Shape listInstanceShape; - @CompilationFinal private Shape dictInstanceShape; @Override protected ArgumentClinicProvider getArgumentClinic() { @@ -92,21 +124,9 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization protected PTuple call(PJSONScanner self, TruffleString string, int idx, @Cached TruffleString.ToJavaStringNode toJavaStringNode) { - if (tupleInstanceShape == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - tupleInstanceShape = PythonLanguage.get(this).getBuiltinTypeInstanceShape(PythonBuiltinClassType.PTuple); - } - if (listInstanceShape == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - listInstanceShape = PythonLanguage.get(this).getBuiltinTypeInstanceShape(PythonBuiltinClassType.PList); - } - if (dictInstanceShape == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - dictInstanceShape = PythonLanguage.get(this).getBuiltinTypeInstanceShape(PythonBuiltinClassType.PDict); - } IntRef nextIdx = new IntRef(); Object result = scanOnceUnicode(self, toJavaStringNode.execute(string), idx, nextIdx); - return factory.createTuple(new Object[]{result, nextIdx.value}); + return PFactory.createTuple(PythonLanguage.get(this), new Object[]{result, nextIdx.value}); } @TruffleBoundary @@ -120,6 +140,8 @@ private Object parseObjectUnicode(PJSONScanner scanner, String string, int start */ boolean hasPairsHook = scanner.objectPairsHook != PNone.NONE; + PythonLanguage language = PythonLanguage.get(null); + int idx = start; int length = string.length(); @@ -161,7 +183,7 @@ private Object parseObjectUnicode(PJSONScanner scanner, String string, int start idx = nextIdx.value; if (hasPairsHook) { - listStorage.insertItem(listStorage.length(), factory.createTuple(PythonBuiltinClassType.PTuple, tupleInstanceShape, new Object[]{key, val})); + listStorage.insertItem(listStorage.length(), PFactory.createTuple(language, new Object[]{key, val})); } else { HashingStorage newStorage = HashingStorageSetItem.executeUncached(mapStorage, key, val); assert newStorage == mapStorage; @@ -186,11 +208,11 @@ private Object parseObjectUnicode(PJSONScanner scanner, String string, int start nextIdx.value = idx + 1; if (hasPairsHook) { - return callObjectPairsHook.executeObject(scanner.objectPairsHook, factory.createList(PythonBuiltinClassType.PList, listInstanceShape, listStorage)); + return callObjectPairsHook.executeObject(scanner.objectPairsHook, PFactory.createList(language, listStorage)); } /* if object_hook is not None: rval = object_hook(rval) */ - PDict rval = factory.createDict(PythonBuiltinClassType.PDict, dictInstanceShape, mapStorage); + PDict rval = PFactory.createDict(language, mapStorage); if (scanner.objectHook != PNone.NONE) { return callObjectHook.executeObject(scanner.objectHook, rval); } @@ -242,7 +264,7 @@ private Object parseArrayUnicode(PJSONScanner scanner, String string, int start, throw decodeError(this, string, length - 1, ErrorMessages.EXPECTING_VALUE); } nextIdx.value = idx + 1; - return factory.createList(PythonBuiltinClassType.PList, listInstanceShape, storage); + return PFactory.createList(PythonLanguage.get(null), storage); } private static int skipWhitespace(String string, int start, int length) { @@ -367,7 +389,7 @@ private Object scanOnceUnicode(PJSONScanner scanner, String string, int idx, Int * Returns a new PyObject representation of the term. */ if (idx < 0) { - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.ValueError, ErrorMessages.IDX_CANNOT_BE_NEG); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.ValueError, ErrorMessages.IDX_CANNOT_BE_NEG); } int length = string.length(); if (idx >= length) { @@ -449,7 +471,7 @@ static TruffleString scanStringUnicode(String string, int start, boolean strict, StringBuilder builder = null; if (start < 0 || start > string.length()) { - throw PRaiseNode.raiseUncached(raisingNode, PythonBuiltinClassType.ValueError, ErrorMessages.END_IS_OUT_OF_BOUNDS); + throw PRaiseNode.raiseStatic(raisingNode, PythonBuiltinClassType.ValueError, ErrorMessages.END_IS_OUT_OF_BOUNDS); } int idx = start; while (idx < string.length()) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Blake2sObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lsprof/LsprofModuleBuiltins.java similarity index 54% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Blake2sObjectBuiltins.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lsprof/LsprofModuleBuiltins.java index ec1e03d919..6b8b28c029 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/Blake2sObjectBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lsprof/LsprofModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,31 +38,60 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.builtins.modules.hashlib; +package com.oracle.graal.python.builtins.modules.lsprof; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.tuple.StructSequence; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.truffle.api.dsl.NodeFactory; -@CoreFunctions(extendClasses = {PythonBuiltinClassType.Blake2sType}) -public final class Blake2sObjectBuiltins extends PythonBuiltins { +@CoreFunctions(defineModule = "_lsprof") +public final class LsprofModuleBuiltins extends PythonBuiltins { + + static final StructSequence.BuiltinTypeDescriptor PROFILER_ENTRY_DESC = new StructSequence.BuiltinTypeDescriptor( + PythonBuiltinClassType.PProfilerEntry, + 6, + new String[]{ + "code", "callcount", "reccallcount", "totaltime", "inlinetime", "calls" + }, + new String[]{ + "code object or built-in function name", + "how many times this was called", + "how many times called recursively", + "total time in this entry", + "inline time in this entry (not in subcalls)", + "details of the calls" + }); + + static final StructSequence.BuiltinTypeDescriptor PROFILER_SUBENTRY_DESC = new StructSequence.BuiltinTypeDescriptor( + PythonBuiltinClassType.PProfilerSubentry, + 5, + new String[]{ + "code", "callcount", "reccallcount", "totaltime", "inlinetime" + }, + new String[]{ + "called code object or built-in function name", + "how many times this is called", + "how many times this is called recursively", + "total time spent in this call", + "inline time (not in further subcalls)" + }); + @Override protected List> getNodeFactories() { - return new ArrayList<>(); + return Collections.emptyList(); } @Override public void initialize(Python3Core core) { - addBuiltinConstant("SALT_SIZE", Blake2ModuleBuiltins.BLAKE2S_SALTBYTES); - addBuiltinConstant("PERSON_SIZE", Blake2ModuleBuiltins.BLAKE2S_PERSONALBYTES); - addBuiltinConstant("MAX_KEY_SIZE", Blake2ModuleBuiltins.BLAKE2S_KEYBYTES); - addBuiltinConstant("MAX_DIGEST_SIZE", Blake2ModuleBuiltins.BLAKE2S_OUTBYTES); super.initialize(core); + StructSequence.initType(core, PROFILER_ENTRY_DESC); + StructSequence.initType(core, PROFILER_SUBENTRY_DESC); } } diff --git a/graalpython/com.oracle.graal.python.jni/src/hpy_log.h b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lsprof/Profiler.java similarity index 70% rename from graalpython/com.oracle.graal.python.jni/src/hpy_log.h rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lsprof/Profiler.java index f6cf73a214..33dfbaa4de 100644 --- a/graalpython/com.oracle.graal.python.jni/src/hpy_log.h +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lsprof/Profiler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,17 +38,25 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +package com.oracle.graal.python.builtins.modules.lsprof; -#ifndef SRC_HPY_LOG_H_ -#define SRC_HPY_LOG_H_ +import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; +import com.oracle.truffle.api.instrumentation.SourceSectionFilter; +import com.oracle.truffle.api.object.Shape; +import com.oracle.truffle.tools.profiler.CPUSampler; -#ifndef NDEBUG -#include -#define LOG(FORMAT, ...) do { printf("%-15s (%s:%d): %s " FORMAT "\n", __FUNCTION__, __FILE__, __LINE__, #__VA_ARGS__, __VA_ARGS__); fflush(stdout); } while(0); -#define LOGS(FORMAT) do { printf("%-15s (%s:%d): " FORMAT "\n", __FUNCTION__, __FILE__, __LINE__); fflush(stdout); } while(0); -#else -#define LOG(FORMAT, ...) -#define LOGS(FORMAT) -#endif +public class Profiler extends PythonBuiltinObject { + boolean subcalls; + boolean builtins; + double timeunit; + Object externalTimer; + double time; + final CPUSampler sampler; -#endif /* SRC_HPY_LOG_H_ */ + public Profiler(Object cls, Shape instanceShape, CPUSampler sampler) { + super(cls, instanceShape); + this.sampler = sampler; + this.sampler.setFilter(SourceSectionFilter.newBuilder().includeInternal(true).build()); + this.sampler.setPeriod(1); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/LsprofModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lsprof/ProfilerBuiltins.java similarity index 64% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/LsprofModuleBuiltins.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lsprof/ProfilerBuiltins.java index 0c91bb9359..56be758624 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/LsprofModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lsprof/ProfilerBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,9 +38,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.builtins.modules; +package com.oracle.graal.python.builtins.modules.lsprof; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; import java.util.ArrayList; @@ -49,6 +48,10 @@ import java.util.List; import java.util.Map; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -57,126 +60,63 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.list.PList; -import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.tuple.StructSequence; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.InstrumentInfo; -import com.oracle.truffle.api.TruffleLanguage.Env; +import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.instrumentation.SourceSectionFilter; -import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.tools.profiler.CPUSampler; -import com.oracle.truffle.tools.profiler.CPUSampler.Payload; import com.oracle.truffle.tools.profiler.CPUSamplerData; import com.oracle.truffle.tools.profiler.ProfilerNode; import com.oracle.truffle.tools.profiler.impl.CPUSamplerInstrument; -@CoreFunctions(defineModule = "_lsprof") -public final class LsprofModuleBuiltins extends PythonBuiltins { - - static final StructSequence.BuiltinTypeDescriptor PROFILER_ENTRY_DESC = new StructSequence.BuiltinTypeDescriptor( - PythonBuiltinClassType.PProfilerEntry, - null, - 6, - new String[]{ - "code", "callcount", "reccallcount", "totaltime", "inlinetime", "calls" - }, - new String[]{ - "code object or built-in function name", - "how many times this was called", - "how many times called recursively", - "total time in this entry", - "inline time in this entry (not in subcalls)", - "details of the calls" - }); +@CoreFunctions(extendClasses = PythonBuiltinClassType.LsprofProfiler) +public class ProfilerBuiltins extends PythonBuiltins { - static final StructSequence.BuiltinTypeDescriptor PROFILER_SUBENTRY_DESC = new StructSequence.BuiltinTypeDescriptor( - PythonBuiltinClassType.PProfilerSubentry, - null, - 5, - new String[]{ - "code", "callcount", "reccallcount", "totaltime", "inlinetime" - }, - new String[]{ - "called code object or built-in function name", - "how many times this is called", - "how many times this is called recursively", - "total time spent in this call", - "inline time (not in further subcalls)" - }); + public static final TpSlots SLOTS = ProfilerBuiltinsSlotsGen.SLOTS; @Override protected List> getNodeFactories() { - return LsprofModuleBuiltinsFactory.getFactories(); - } - - @Override - public void initialize(Python3Core core) { - super.initialize(core); - StructSequence.initType(core, PROFILER_ENTRY_DESC); - StructSequence.initType(core, PROFILER_SUBENTRY_DESC); - } - - public static PythonBuiltins newProfilerBuiltins() { - return new ProfilerBuiltins(); + return ProfilerBuiltinsFactory.getFactories(); } - @Builtin(name = "Profiler", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PythonBuiltinClassType.LsprofProfiler) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "Profiler", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory abstract static class LsprofNew extends PythonBuiltinNode { @Specialization @TruffleBoundary Profiler doit(Object cls, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") PKeyword[] kwargs) { - Env env = getContext().getEnv(); - Map instruments = env.getInstruments(); - InstrumentInfo instrumentInfo = instruments.get(CPUSamplerInstrument.ID); - if (instrumentInfo != null) { - CPUSampler sampler = env.lookup(instrumentInfo, CPUSampler.class); - if (sampler != null) { - PythonObjectFactory factory = PythonObjectFactory.getUncached(); - return factory.trace(new Profiler(cls, factory.getShape(cls), sampler)); + if (Python3Core.HAS_PROFILER_TOOL) { + // Avoid ClassNotFoundException + PythonContext context = getContext(); + TruffleLanguage.Env env = context.getEnv(); + Map instruments = env.getInstruments(); + InstrumentInfo instrumentInfo = instruments.get(CPUSamplerInstrument.ID); + if (instrumentInfo != null) { + CPUSampler sampler = env.lookup(instrumentInfo, CPUSampler.class); + if (sampler != null) { + return PFactory.createProfiler(context.getLanguage(), cls, TypeNodes.GetInstanceShape.executeUncached(cls), sampler); + } } } - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.NotImplementedError, ErrorMessages.COVERAGE_TRACKER_NOT_AVAILABLE); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.NotImplementedError, ErrorMessages.COVERAGE_TRACKER_NOT_AVAILABLE); } } -} - -class Profiler extends PythonBuiltinObject { - boolean subcalls; - boolean builtins; - double timeunit; - Object externalTimer; - double time; - final CPUSampler sampler; - - public Profiler(Object cls, Shape instanceShape, CPUSampler sampler) { - super(cls, instanceShape); - this.sampler = sampler; - this.sampler.setFilter(SourceSectionFilter.newBuilder().includeInternal(true).build()); - this.sampler.setPeriod(1); - } -} - -@CoreFunctions(extendClasses = PythonBuiltinClassType.LsprofProfiler) -class ProfilerBuiltins extends PythonBuiltins { - @Override - protected List> getNodeFactories() { - return ProfilerBuiltinsFactory.getFactories(); - } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self", "timer", "timeunit", "subcalls", "builtins"}) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "Profiler", minNumOfPositionalArgs = 1, parameterNames = {"$self", "timer", "timeunit", "subcalls", "builtins"}) @GenerateNodeFactory abstract static class Init extends PythonBuiltinNode { @Specialization @@ -282,35 +222,35 @@ static PList doit(Profiler self) { double avgSampleSeconds = self.sampler.getPeriod() / 1000D; List entries = new ArrayList<>(); for (CPUSamplerData data : self.sampler.getDataList()) { - Map>> threads = data.getThreadData(); + Map>> threads = data.getThreadData(); for (Thread thread : threads.keySet()) { - for (ProfilerNode node : threads.get(thread)) { + for (ProfilerNode node : threads.get(thread)) { countNode(entries, node, avgSampleSeconds); } } } self.sampler.close(); - return PythonObjectFactory.getUncached().createList(entries.toArray()); + return PFactory.createList(PythonLanguage.get(null), entries.toArray()); } - private static void countNode(List entries, ProfilerNode node, double avgSampleTime) { - PythonObjectSlowPathFactory factory = PythonContext.get(null).factory(); - Collection> children = node.getChildren(); + private static void countNode(List entries, ProfilerNode node, double avgSampleTime) { + PythonLanguage language = PythonLanguage.get(null); + Collection> children = node.getChildren(); Object[] profilerEntry = getProfilerEntry(node, avgSampleTime); Object[] calls = new Object[children.size()]; int callIdx = 0; - for (ProfilerNode childNode : children) { + for (ProfilerNode childNode : children) { countNode(entries, childNode, avgSampleTime); - calls[callIdx++] = factory.createStructSeq(LsprofModuleBuiltins.PROFILER_SUBENTRY_DESC, getProfilerEntry(childNode, avgSampleTime)); + calls[callIdx++] = PFactory.createStructSeq(language, LsprofModuleBuiltins.PROFILER_SUBENTRY_DESC, getProfilerEntry(childNode, avgSampleTime)); } assert callIdx == calls.length; profilerEntry = Arrays.copyOf(profilerEntry, 6); - profilerEntry[profilerEntry.length - 1] = factory.createList(calls); - entries.add(factory.createStructSeq(LsprofModuleBuiltins.PROFILER_ENTRY_DESC, profilerEntry)); + profilerEntry[profilerEntry.length - 1] = PFactory.createList(language, calls); + entries.add(PFactory.createStructSeq(language, LsprofModuleBuiltins.PROFILER_ENTRY_DESC, profilerEntry)); } - private static Object[] getProfilerEntry(ProfilerNode node, double avgSampleTime) { + private static Object[] getProfilerEntry(ProfilerNode node, double avgSampleTime) { SourceSection sec = node.getSourceSection(); String rootName; if (sec == null) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMACompressorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMACompressorBuiltins.java index 295b43080d..997bb1d206 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMACompressorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMACompressorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -50,14 +50,17 @@ import static com.oracle.graal.python.nodes.ErrorMessages.INTEGRITY_CHECKS_ONLY_SUPPORTED_BY; import static com.oracle.graal.python.nodes.ErrorMessages.MUST_SPECIFY_FILTERS; import static com.oracle.graal.python.nodes.ErrorMessages.REPEATED_CALL_TO_FLUSH; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; import com.oracle.graal.python.annotations.ClinicConverterFactory; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -68,17 +71,19 @@ import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentCastNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.CompilerDirectives.ValueType; import com.oracle.truffle.api.dsl.Bind; @@ -91,24 +96,39 @@ import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @CoreFunctions(extendClasses = PythonBuiltinClassType.PLZMACompressor) public final class LZMACompressorBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = LZMACompressorBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return LZMACompressorBuiltinsFactory.getFactories(); } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self", "format", "check", "preset", "filters"}) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "LZMACompressor", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + abstract static class LZMACompressorNode extends PythonBuiltinNode { + + @Specialization + LZMAObject doNew(Object cls, @SuppressWarnings("unused") Object arg, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + // data filled in subsequent __init__ call - see LZMACompressorBuiltins.InitNode + PythonContext context = getContext(); + return PFactory.createLZMACompressor(context.getLanguage(this), cls, getInstanceShape.execute(cls), context.getNFILZMASupport().isAvailable()); + } + } + + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "LZMACompressor", minNumOfPositionalArgs = 1, parameterNames = {"$self", "format", "check", "preset", "filters"}) @ArgumentClinic(name = "format", conversion = ClinicConversion.Int, defaultValue = "LZMAModuleBuiltins.FORMAT_XZ", useDefaultForNone = true) @ArgumentClinic(name = "check", conversion = ClinicConversion.Int, defaultValue = "-1", useDefaultForNone = true) @ArgumentClinic(name = "preset", conversionClass = ExpectUINT32Node.class, defaultValue = "PNone.NO_VALUE") @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) public abstract static class InitNode extends PythonClinicBuiltinNode { @Override @@ -134,26 +154,26 @@ static PNone init(VirtualFrame frame, LZMACompressor self, int format, int check @Specialization(guards = "badIntegrity(format, check)") @SuppressWarnings("unused") - static PNone integrityError(LZMACompressor self, long format, long check, Object preset, Object filters, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, INTEGRITY_CHECKS_ONLY_SUPPORTED_BY); + static PNone integrityError(LZMACompressor self, int format, int check, Object preset, Object filters, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, INTEGRITY_CHECKS_ONLY_SUPPORTED_BY); } @Specialization(guards = {"!badIntegrity(format, check)", "badPresetFilters(preset, filters)"}) @SuppressWarnings("unused") - static PNone presetError(LZMACompressor self, long format, long check, Object preset, Object filters, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, CANNOT_SPECIFY_PREST_AND_FILTER_CHAIN); + static PNone presetError(LZMACompressor self, int format, int check, Object preset, Object filters, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, CANNOT_SPECIFY_PREST_AND_FILTER_CHAIN); } @Specialization(guards = {"!badIntegrity(format, check)", "!badPresetFilters(preset, filters)", "badRawFilter(format, filters)"}) @SuppressWarnings("unused") - static PNone rawError(LZMACompressor self, long format, long check, Object preset, PNone filters, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, MUST_SPECIFY_FILTERS); + static PNone rawError(LZMACompressor self, int format, int check, Object preset, PNone filters, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, MUST_SPECIFY_FILTERS); } - protected static boolean badIntegrity(long format, long check) { + protected static boolean badIntegrity(int format, int check) { return format != FORMAT_XZ && check != -1 && check != CHECK_NONE; } @@ -165,31 +185,30 @@ protected static boolean badRawFilter(long format, Object filters) { return format == FORMAT_RAW && PGuards.isPNone(filters); } - protected static boolean isValid(long format, long check, Object preset, Object filters) { + protected static boolean isValid(int format, int check, Object preset, Object filters) { return !badIntegrity(format, check) && !badPresetFilters(preset, filters) && !badRawFilter(format, filters); } } @Builtin(name = "compress", minNumOfPositionalArgs = 2) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class CompressNode extends PythonBinaryBuiltinNode { @Specialization(guards = {"!self.isFlushed()"}) static PBytes doBytes(VirtualFrame frame, LZMACompressor self, Object data, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached GetArrayAndLengthHelperNode getArrayAndLengthHelperNode, - @Cached LZMANodes.CompressNode compress, - @Cached PythonObjectFactory factory) { + @Cached LZMANodes.CompressNode compress) { ArrayAndLength aal = getArrayAndLengthHelperNode.execute(frame, inliningTarget, data); - return factory.createBytes(compress.compress(inliningTarget, self, PythonContext.get(inliningTarget), aal.array, aal.length)); + return PFactory.createBytes(language, compress.compress(inliningTarget, self, PythonContext.get(inliningTarget), aal.array, aal.length)); } @SuppressWarnings("unused") @Specialization(guards = "self.isFlushed()") static PNone error(LZMACompressor self, Object data, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, COMPRESSOR_HAS_BEEN_FLUSHED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, COMPRESSOR_HAS_BEEN_FLUSHED); } @ValueType @@ -220,23 +239,22 @@ static ArrayAndLength doObject(VirtualFrame frame, Object data, @Builtin(name = "flush", minNumOfPositionalArgs = 1) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class FlushNode extends PythonUnaryBuiltinNode { @Specialization(guards = {"!self.isFlushed()"}) static PBytes doit(LZMACompressor self, @Bind("this") Node inliningTarget, - @Cached LZMANodes.CompressNode compress, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language, + @Cached LZMANodes.CompressNode compress) { self.setFlushed(); - return factory.createBytes(compress.flush(inliningTarget, self, PythonContext.get(inliningTarget))); + return PFactory.createBytes(language, compress.flush(inliningTarget, self, PythonContext.get(inliningTarget))); } @SuppressWarnings("unused") @Specialization(guards = "self.isFlushed()") static PNone error(LZMACompressor self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, REPEATED_CALL_TO_FLUSH); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, REPEATED_CALL_TO_FLUSH); } } @@ -271,5 +289,4 @@ public static ExpectUINT32Node create(@ClinicConverterFactory.DefaultValue Objec return LZMACompressorBuiltinsFactory.ExpectUINT32NodeGen.create(defaultValue); } } - } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMADecompressorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMADecompressorBuiltins.java index c86554b75e..a031f68df2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMADecompressorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMADecompressorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -52,11 +52,14 @@ import static com.oracle.graal.python.builtins.modules.lzma.LZMAModuleBuiltins.FORMAT_XZ; import static com.oracle.graal.python.builtins.modules.lzma.LZMAModuleBuiltins.T_LZMA_JAVA_ERROR; import static com.oracle.graal.python.nodes.ErrorMessages.ALREADY_AT_END_OF_STREAM; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -67,18 +70,21 @@ import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -87,23 +93,38 @@ import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @CoreFunctions(extendClasses = PythonBuiltinClassType.PLZMADecompressor) public final class LZMADecompressorBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = LZMADecompressorBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return LZMADecompressorBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "LZMADecompressor", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + abstract static class LZMADecompressorNode extends PythonBuiltinNode { + + @Specialization + LZMAObject doNew(Object cls, @SuppressWarnings("unused") Object arg, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + // data filled in subsequent __init__ call - see LZMADecompressorBuiltins.InitNode + PythonContext context = getContext(); + return PFactory.createLZMADecompressor(context.getLanguage(this), cls, getInstanceShape.execute(cls), context.getNFILZMASupport().isAvailable()); + } + } + @ImportStatic(PGuards.class) - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self", "format", "memlimit", "filters"}) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "LZMADecompressor", minNumOfPositionalArgs = 1, parameterNames = {"$self", "format", "memlimit", "filters"}) @ArgumentClinic(name = "format", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "LZMAModuleBuiltins.FORMAT_AUTO", useDefaultForNone = true) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) public abstract static class InitNode extends PythonQuaternaryClinicBuiltinNode { @Override @@ -116,12 +137,12 @@ static PNone notRaw(VirtualFrame frame, LZMADecompressor self, int format, Objec @Bind("this") Node inliningTarget, @Cached CastToJavaIntExactNode cast, @Shared("d") @Cached LZMANodes.LZMADecompressInit decompressInit, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int memlimit; try { memlimit = cast.execute(inliningTarget, memlimitObj); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.INTEGER_REQUIRED); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.INTEGER_REQUIRED); } return doNotRaw(frame, self, format, memlimit, decompressInit); @@ -154,29 +175,29 @@ static PNone raw(VirtualFrame frame, LZMADecompressor self, int format, PNone me @SuppressWarnings("unused") @Specialization(guards = {"isRaw(format)", "!isPNone(memlimit)"}) static PNone rawError(LZMADecompressor self, int format, Object memlimit, Object filters, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.CANNOT_SPECIFY_MEM_LIMIT); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.CANNOT_SPECIFY_MEM_LIMIT); } @SuppressWarnings("unused") @Specialization(guards = "isRaw(format)") static PNone rawFilterError(LZMADecompressor self, int format, Object memlimit, PNone filters, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.MUST_SPECIFY_FILTERS); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.MUST_SPECIFY_FILTERS); } @SuppressWarnings("unused") @Specialization(guards = {"!isRaw(format)", "!isPNone(filters)"}) static PNone rawFilterError(LZMADecompressor self, int format, Object memlimit, Object filters, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.CANNOT_SPECIFY_FILTERS); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.CANNOT_SPECIFY_FILTERS); } @SuppressWarnings("unused") @Specialization(guards = "!validFormat(format)") static PNone invalidFormat(LZMADecompressor self, int format, Object memlimit, Object filters, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.INVALID_CONTAINER_FORMAT, format); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.INVALID_CONTAINER_FORMAT, format); } protected static boolean validFormat(int format) { @@ -194,7 +215,6 @@ protected static boolean isRaw(int format) { @Builtin(name = "decompress", minNumOfPositionalArgs = 2, parameterNames = {"$self", "$data", "max_length"}, needsFrame = true) @ArgumentClinic(name = "max_length", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "-1", useDefaultForNone = true) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class DecompressNode extends PythonTernaryClinicBuiltinNode { @Override @@ -205,37 +225,36 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(guards = {"!self.isEOF()"}) static PBytes doBytes(LZMADecompressor self, PBytesLike data, int maxLength, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached SequenceStorageNodes.GetInternalByteArrayNode toBytes, - @Exclusive @Cached LZMANodes.DecompressNode decompress, - @Shared @Cached PythonObjectFactory factory) { + @Exclusive @Cached LZMANodes.DecompressNode decompress) { byte[] bytes = toBytes.execute(inliningTarget, data.getSequenceStorage()); int len = data.getSequenceStorage().length(); - return factory.createBytes(decompress.execute(inliningTarget, self, bytes, len, maxLength)); + return PFactory.createBytes(language, decompress.execute(inliningTarget, self, bytes, len, maxLength)); } @Specialization(guards = {"!self.isEOF()"}) static PBytes doObject(VirtualFrame frame, LZMADecompressor self, Object data, int maxLength, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached BytesNodes.ToBytesNode toBytes, - @Exclusive @Cached LZMANodes.DecompressNode decompress, - @Shared @Cached PythonObjectFactory factory) { + @Exclusive @Cached LZMANodes.DecompressNode decompress) { byte[] bytes = toBytes.execute(frame, data); int len = bytes.length; - return factory.createBytes(decompress.execute(inliningTarget, self, bytes, len, maxLength)); + return PFactory.createBytes(language, decompress.execute(inliningTarget, self, bytes, len, maxLength)); } @SuppressWarnings("unused") @Specialization(guards = {"self.isEOF()"}) static Object err(LZMADecompressor self, Object data, int maxLength, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(EOFError, ALREADY_AT_END_OF_STREAM); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, EOFError, ALREADY_AT_END_OF_STREAM); } } @Builtin(name = "eof", minNumOfPositionalArgs = 1, parameterNames = {"self"}, isGetter = true) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class EofNode extends PythonUnaryBuiltinNode { @Specialization @@ -247,7 +266,6 @@ boolean doEof(LZMADecompressor self) { @Builtin(name = "needs_input", minNumOfPositionalArgs = 1, parameterNames = {"self"}, isGetter = true) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class NeedsInputNode extends PythonUnaryBuiltinNode { @Specialization @@ -259,7 +277,6 @@ boolean doNeedsInput(LZMADecompressor self) { @Builtin(name = "check", minNumOfPositionalArgs = 1, parameterNames = {"self"}, isGetter = true) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class CheckNode extends PythonUnaryBuiltinNode { @Specialization @@ -269,23 +286,21 @@ int doCheck(LZMADecompressor.Native self) { @Specialization static int doCheck(@SuppressWarnings("unused") LZMADecompressor.Java self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, T_LZMA_JAVA_ERROR); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, T_LZMA_JAVA_ERROR); } } @Builtin(name = "unused_data", minNumOfPositionalArgs = 1, parameterNames = {"self"}, isGetter = true) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class UnusedDataNode extends PythonUnaryBuiltinNode { @Specialization static PBytes doUnusedData(LZMADecompressor self, - @Cached PythonObjectFactory factory) { - return factory.createBytes(self.getUnusedData()); + @Bind PythonLanguage language) { + return PFactory.createBytes(language, self.getUnusedData()); } } - } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMAModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMAModuleBuiltins.java index 045ee97e5d..d6d7208547 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMAModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMAModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,8 +40,6 @@ */ package com.oracle.graal.python.builtins.modules.lzma; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PLZMACompressor; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PLZMADecompressor; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; import static com.oracle.graal.python.runtime.NFILZMASupport.CHECK_CRC32_INDEX; import static com.oracle.graal.python.runtime.NFILZMASupport.CHECK_CRC64_INDEX; @@ -80,6 +78,7 @@ import org.graalvm.shadowed.org.tukaani.xz.XZ; import org.graalvm.shadowed.org.tukaani.xz.XZOutputStream; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -90,21 +89,18 @@ import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; import com.oracle.graal.python.nodes.util.CastToJavaLongLossyNode; import com.oracle.graal.python.runtime.NFILZMASupport; import com.oracle.graal.python.runtime.NativeLibrary; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -260,35 +256,8 @@ public void postInitialize(Python3Core c) { lzmaModule.setAttribute(tsLiteral("MF_HC4"), MF_HC4); } - @Builtin(name = "LZMACompressor", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PLZMACompressor) - @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) - abstract static class LZMACompressorNode extends PythonBuiltinNode { - - @Specialization - LZMAObject doNew(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PythonObjectFactory factory) { - // data filled in subsequent __init__ call - see LZMACompressorBuiltins.InitNode - return factory.createLZMACompressor(cls, getContext().getNFILZMASupport().isAvailable()); - } - } - - @Builtin(name = "LZMADecompressor", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, constructsClass = PLZMADecompressor) - @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) - abstract static class LZMADecompressorNode extends PythonBuiltinNode { - - @Specialization - LZMAObject doNew(Object cls, @SuppressWarnings("unused") Object arg, - @Cached PythonObjectFactory factory) { - // data filled in subsequent __init__ call - see LZMADecompressorBuiltins.InitNode - return factory.createLZMADecompressor(cls, getContext().getNFILZMASupport().isAvailable()); - } - } - @Builtin(name = "is_check_supported", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 1) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class IsCheckSupportedNode extends PythonUnaryBuiltinNode { @Specialization @@ -302,31 +271,29 @@ static boolean doInt(VirtualFrame frame, Object checkID, @Builtin(name = "_encode_filter_properties", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 1) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class EncodeFilterPropertiesNode extends PythonUnaryBuiltinNode { @Specialization static PBytes encode(VirtualFrame frame, Object filter, @Cached LZMANodes.EncodeFilterProperties encodeFilterProperties, - @Cached PythonObjectFactory factory) { - return factory.createBytes(encodeFilterProperties.execute(frame, filter)); + @Bind PythonLanguage language) { + return PFactory.createBytes(language, encodeFilterProperties.execute(frame, filter)); } } @Builtin(name = "_decode_filter_properties", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 2) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class DecodeFilterPropertiesNode extends PythonBinaryBuiltinNode { @Specialization static PDict encode(VirtualFrame frame, Object id, Object encodedProps, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached CastToJavaLongLossyNode toLong, @Cached BytesNodes.ToBytesNode toBytes, - @Cached LZMANodes.DecodeFilterProperties decodeFilterProperties, - @Cached PythonObjectFactory factory) { + @Cached LZMANodes.DecodeFilterProperties decodeFilterProperties) { byte[] bytes = toBytes.execute(frame, encodedProps); - PDict dict = factory.createDict(); + PDict dict = PFactory.createDict(language); decodeFilterProperties.execute(frame, toLong.execute(inliningTarget, id), bytes, dict); return dict; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMANodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMANodes.java index 723990fb85..3519e4e58e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMANodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/lzma/LZMANodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -204,12 +204,12 @@ long l(long l) { @Specialization long ll(long l, @Bind("this") Node inliningTarget, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (l < 0) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.CANT_CONVERT_NEG_INT_TO_UNSIGNED); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.CANT_CONVERT_NEG_INT_TO_UNSIGNED); } if (l > MAX_UINT32 && with32BitLimit) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.VALUE_TOO_LARGE_FOR_UINT32); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.VALUE_TOO_LARGE_FOR_UINT32); } return l; } @@ -219,11 +219,11 @@ long ll(long l, long o(Object o, @Bind("this") Node inliningTarget, @Cached CastToJavaLongExactNode cast, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { try { return ll(cast.execute(inliningTarget, o), inliningTarget, raiseNode); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, INTEGER_REQUIRED); + throw raiseNode.raise(inliningTarget, TypeError, INTEGER_REQUIRED); } } @@ -247,10 +247,10 @@ public abstract static class GetOptionsDict extends Node { static HashingStorage fast(VirtualFrame frame, PDict dict, @Bind("this") Node inliningTarget, @Shared("getItem") @Cached HashingStorageGetItem getItem, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { HashingStorage storage = dict.getDictStorage(); if (!getItem.hasKey(frame, inliningTarget, storage, T_ID)) { - throw raiseNode.get(inliningTarget).raise(ValueError, FILTER_SPECIFIER_MUST_HAVE); + throw raiseNode.raise(inliningTarget, ValueError, FILTER_SPECIFIER_MUST_HAVE); } return storage; } @@ -260,10 +260,10 @@ static HashingStorage slow(VirtualFrame frame, Object object, @Bind("this") Node inliningTarget, @Shared("getItem") @Cached HashingStorageGetItem getItem, @Cached GetDictIfExistsNode getDict, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { PDict dict = getDict.execute(object); if (dict == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, FILTER_SPEC_MUST_BE_DICT); + throw raiseNode.raise(inliningTarget, TypeError, FILTER_SPEC_MUST_BE_DICT); } return fast(frame, dict, inliningTarget, getItem, raiseNode); } @@ -292,23 +292,23 @@ static OptionsState doit(Frame frame, Node inliningTarget, HashingStorage storag @Cached CastToJavaLongLossyNode toLong, @Cached InlinedConditionProfile errProfile, @Cached HashingStorageGetItem getItem, - @Cached PRaiseNode.Lazy raise, + @Cached PRaiseNode raise, @Cached(inline = false) TruffleString.EqualNode equalNode) { Object key = itKey.execute(inliningTarget, storage, it); TruffleString skey = strNode.execute(frame, inliningTarget, key); int idx = getOptionIndex(skey, s, equalNode); if (errProfile.profile(inliningTarget, idx == -1)) { - throw raise.get(inliningTarget).raise(ValueError, ErrorMessages.INVALID_FILTER_SPECIFIED_FOR_FILTER, s.filterType); + throw raise.raise(inliningTarget, ValueError, ErrorMessages.INVALID_FILTER_SPECIFIED_FOR_FILTER, s.filterType); } long l = toLong.execute(inliningTarget, getItem.execute(inliningTarget, s.dictStorage, skey)); if (errProfile.profile(inliningTarget, l < 0)) { - throw raise.get(inliningTarget).raise(OverflowError, ErrorMessages.CANT_CONVERT_NEG_INT_TO_UNSIGNED); + throw raise.raise(inliningTarget, OverflowError, ErrorMessages.CANT_CONVERT_NEG_INT_TO_UNSIGNED); } if (errProfile.profile(inliningTarget, l > MAX_UINT32 && idx > 0) /* * filters are special * case */) { - throw raise.get(inliningTarget).raise(OverflowError, ErrorMessages.VALUE_TOO_LARGE_FOR_UINT32); + throw raise.raise(inliningTarget, OverflowError, ErrorMessages.VALUE_TOO_LARGE_FOR_UINT32); } s.options[idx] = l; return s; @@ -421,7 +421,7 @@ static long[] converter(VirtualFrame frame, Object spec, @Cached GetOptionsDict getOptionsDict, @Cached HashingStorageGetItem getItem, @Cached HashingStorageForEach forEachNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { HashingStorage dict = getOptionsDict.execute(frame, spec); Object idObj = getItem.execute(inliningTarget, dict, T_ID); long id = toLong.execute(inliningTarget, idObj); @@ -451,7 +451,7 @@ static long[] converter(VirtualFrame frame, Object spec, state = new OptionsState("BCJ", BCJOption.values(), options, dict); break; default: - throw raiseNode.get(inliningTarget).raise(ValueError, INVALID_FILTER, id); + throw raiseNode.raise(inliningTarget, ValueError, INVALID_FILTER, id); } options[0] = id; forEachNode.execute(frame, inliningTarget, dict, getOptions, state); @@ -472,11 +472,11 @@ long[][] parseFilter(VirtualFrame frame, Object filterSpecs, @Cached LZMAFilterConverter converter, @Cached SequenceNodes.CheckIsSequenceNode checkIsSequenceNode, @Cached PyObjectSizeNode sizeNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { checkIsSequenceNode.execute(inliningTarget, filterSpecs); int numFilters = sizeNode.execute(frame, inliningTarget, filterSpecs); if (numFilters > LZMA_FILTERS_MAX) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.TOO_MAMNY_FILTERS_LZMA_SUPPORTS_MAX_S, LZMA_FILTERS_MAX); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.TOO_MAMNY_FILTERS_LZMA_SUPPORTS_MAX_S, LZMA_FILTERS_MAX); } long[][] filters = new long[numFilters][0]; for (int i = 0; i < numFilters; i++) { @@ -498,7 +498,7 @@ static void parseFilterChainSpec(VirtualFrame frame, Object lzmast, PythonContex @Cached NativeLibrary.InvokeNativeFunction setFilterSpecDelta, @Cached NativeLibrary.InvokeNativeFunction setFilterSpecBCJ, @Cached LZMAParseFilterChain parseFilterChain, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { long[][] filters = parseFilterChain.execute(frame, filterSpecs); for (int i = 0; i < filters.length; i++) { setFilterOptions(inliningTarget, lzmast, filters[i], i, context, setFilterSpecLZMA, setFilterSpecDelta, setFilterSpecBCJ, raiseNode); @@ -509,7 +509,7 @@ private static void setFilterOptions(Node inliningTarget, Object lzmast, long[] NativeLibrary.InvokeNativeFunction setFilterSpecLZMA, NativeLibrary.InvokeNativeFunction setFilterSpecDelta, NativeLibrary.InvokeNativeFunction setFilterSpecBCJ, - PRaiseNode.Lazy raiseNode) { + PRaiseNode raiseNode) { NFILZMASupport lzmaSupport = context.getNFILZMASupport(); Object opts = context.getEnv().asGuestValue(filter); int err; @@ -521,7 +521,7 @@ private static void setFilterOptions(Node inliningTarget, Object lzmast, long[] err = lzmaSupport.setFilterSpecLZMA(lzmast, fidx, opts, setFilterSpecLZMA); if (err != LZMA_OK) { if (err == LZMA_PRESET_ERROR) { - throw raiseNode.get(inliningTarget).raise(LZMAError, INVALID_COMPRESSION_PRESET, filter[LZMAOption.preset.ordinal()]); + throw raiseNode.raise(inliningTarget, LZMAError, INVALID_COMPRESSION_PRESET, filter[LZMAOption.preset.ordinal()]); } errorHandling(inliningTarget, err, raiseNode); } @@ -546,7 +546,7 @@ private static void setFilterOptions(Node inliningTarget, Object lzmast, long[] } return; } - throw raiseNode.get(inliningTarget).raise(ValueError, INVALID_FILTER, id); + throw raiseNode.raise(inliningTarget, ValueError, INVALID_FILTER, id); } } @@ -559,14 +559,14 @@ protected abstract static class JavaFilterChain extends Node { @Specialization static FilterOptions[] parseFilterChainSpec(VirtualFrame frame, Node inliningTarget, Object filterSpecs, @Cached(inline = false) LZMAParseFilterChain parseFilterChain, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { long[][] filters = parseFilterChain.execute(frame, filterSpecs); FilterOptions[] optionsChain = new FilterOptions[filters.length]; for (int i = 0; i < filters.length; i++) { try { optionsChain[i] = getFilterOptions(filters[i], inliningTarget); } catch (UnsupportedOptionsException e) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.M, e); } } @@ -592,7 +592,7 @@ private static FilterOptions getFilterOptions(long[] longFilter, Node raisingNod try { lzma2Options = new LZMA2Options(filter[1]); } catch (UnsupportedOptionsException e) { - throw PRaiseNode.raiseUncached(raisingNode, LZMAError, INVALID_COMPRESSION_PRESET, filter[LZMAOption.preset.ordinal()]); + throw PRaiseNode.raiseStatic(raisingNode, LZMAError, INVALID_COMPRESSION_PRESET, filter[LZMAOption.preset.ordinal()]); } for (int j = 2; j < filter.length; j++) { setLZMAOption(lzma2Options, j, filter[j]); @@ -643,7 +643,7 @@ private static FilterOptions getFilterOptions(long[] longFilter, Node raisingNod } return sparcOptions; } - throw PRaiseNode.raiseUncached(raisingNode, ValueError, INVALID_FILTER, longFilter[0]); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, INVALID_FILTER, longFilter[0]); } @TruffleBoundary @@ -692,7 +692,7 @@ static void xz(LZMACompressor.Native self, @SuppressWarnings("unused") int forma @Shared("cs") @Cached NativeLibrary.InvokeNativeFunction createStream, @Exclusive @Cached NativeLibrary.InvokeNativeFunction lzmaEasyEncoder, @Shared @Cached InlinedConditionProfile errProfile, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { NFILZMASupport lzmaSupport = PythonContext.get(inliningTarget).getNFILZMASupport(); Object lzmast = lzmaSupport.createStream(createStream); self.init(lzmast, lzmaSupport); @@ -709,7 +709,7 @@ static void xz(VirtualFrame frame, LZMACompressor.Native self, @SuppressWarnings @Exclusive @Cached NativeLibrary.InvokeNativeFunction lzmaStreamEncoder, @Exclusive @Cached NativeFilterChain filterChain, @Shared @Cached InlinedConditionProfile errProfile, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { PythonContext ctxt = PythonContext.get(inliningTarget); NFILZMASupport lzmaSupport = ctxt.getNFILZMASupport(); Object lzmast = lzmaSupport.createStream(createStream); @@ -728,7 +728,7 @@ static void alone(LZMACompressor.Native self, int format, long preset, PNone fil @Shared("cs") @Cached NativeLibrary.InvokeNativeFunction createStream, @Exclusive @Cached NativeLibrary.InvokeNativeFunction lzmaAloneEncoderPreset, @Shared @Cached InlinedConditionProfile errProfile, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { NFILZMASupport lzmaSupport = PythonContext.get(inliningTarget).getNFILZMASupport(); Object lzmast = lzmaSupport.createStream(createStream); self.init(lzmast, lzmaSupport); @@ -746,7 +746,7 @@ static void alone(VirtualFrame frame, LZMACompressor.Native self, int format, lo @Exclusive @Cached NativeLibrary.InvokeNativeFunction lzmaAloneEncoder, @Exclusive @Cached NativeFilterChain filterChain, @Shared @Cached InlinedConditionProfile errProfile, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { PythonContext ctxt = PythonContext.get(inliningTarget); NFILZMASupport lzmaSupport = ctxt.getNFILZMASupport(); Object lzmast = lzmaSupport.createStream(createStream); @@ -766,7 +766,7 @@ static void raw(VirtualFrame frame, LZMACompressor.Native self, int format, long @Exclusive @Cached NativeLibrary.InvokeNativeFunction lzmaRawEncoder, @Exclusive @Cached NativeFilterChain filterChain, @Shared @Cached InlinedConditionProfile errProfile, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { PythonContext ctxt = PythonContext.get(inliningTarget); NFILZMASupport lzmaSupport = ctxt.getNFILZMASupport(); Object lzmast = lzmaSupport.createStream(createStream); @@ -781,11 +781,11 @@ static void raw(VirtualFrame frame, LZMACompressor.Native self, int format, long @Specialization(guards = "format == FORMAT_XZ") static void xz(LZMACompressor.Java self, @SuppressWarnings("unused") int format, long preset, @SuppressWarnings("unused") PNone filters, @Bind("this") Node inliningTarget, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { try { self.lzmaEasyEncoder(parseLZMAOptions(preset)); } catch (IOException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.M, e); } } @@ -793,11 +793,11 @@ static void xz(LZMACompressor.Java self, @SuppressWarnings("unused") int format, static void xz(VirtualFrame frame, LZMACompressor.Java self, @SuppressWarnings("unused") int format, @SuppressWarnings("unused") long preset, Object filters, @Bind("this") Node inliningTarget, @Shared @Cached JavaFilterChain filterChain, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { try { self.lzmaStreamEncoder(filterChain.execute(frame, inliningTarget, filters)); } catch (IOException e) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.M, e); } } @@ -805,11 +805,11 @@ static void xz(VirtualFrame frame, LZMACompressor.Java self, @SuppressWarnings(" @Specialization(guards = "format == FORMAT_ALONE") static void alone(LZMACompressor.Java self, int format, long preset, PNone filters, @Bind("this") Node inliningTarget, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { try { self.lzmaAloneEncoder(parseLZMAOptions(preset)); } catch (IOException e) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.M, e); } } @@ -818,15 +818,15 @@ static void alone(LZMACompressor.Java self, int format, long preset, PNone filte static void alone(VirtualFrame frame, LZMACompressor.Java self, int format, long preset, Object filters, @Bind("this") Node inliningTarget, @Shared @Cached JavaFilterChain filterChain, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { FilterOptions[] optionsChain = filterChain.execute(frame, inliningTarget, filters); if (optionsChain.length != 1 && !(optionsChain[0] instanceof LZMA2Options)) { - throw raiseNode.get(inliningTarget).raise(ValueError, INVALID_FILTER_CHAIN_FOR_FORMAT); + throw raiseNode.raise(inliningTarget, ValueError, INVALID_FILTER_CHAIN_FOR_FORMAT); } try { self.lzmaAloneEncoder((LZMA2Options) optionsChain[0]); } catch (IOException e) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.M, e); } } @@ -835,24 +835,23 @@ static void alone(VirtualFrame frame, LZMACompressor.Java self, int format, long static void raw(VirtualFrame frame, LZMACompressor.Java self, int format, long preset, Object filters, @Bind("this") Node inliningTarget, @Shared @Cached JavaFilterChain filterChain, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { FilterOptions[] optionsChain = filterChain.execute(frame, inliningTarget, filters); if (optionsChain.length != 1 && !(optionsChain[0] instanceof LZMA2Options)) { - throw raiseNode.get(inliningTarget).raise(ValueError, INVALID_FILTER_CHAIN_FOR_FORMAT); + throw raiseNode.raise(inliningTarget, ValueError, INVALID_FILTER_CHAIN_FOR_FORMAT); } try { self.lzmaRawEncoder(optionsChain); } catch (IOException e) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.M, e); } } @Fallback @SuppressWarnings("unused") static void error(VirtualFrame frame, LZMACompressor self, int format, long preset, Object filters, - @Bind("this") Node inliningTarget, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(ValueError, INVALID_CONTAINER_FORMAT, format); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, INVALID_CONTAINER_FORMAT, format); } } @@ -876,7 +875,7 @@ static byte[] nativeCompress(Node inliningTarget, LZMACompressor.Native self, Py @Cached(inline = false) NativeLibrary.InvokeNativeFunction compress, @Cached GetOutputNativeBufferNode getBuffer, @Cached InlinedConditionProfile errProfile, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { NFILZMASupport lzmaSupport = context.getNFILZMASupport(); Object inGuest = context.getEnv().asGuestValue(bytes); int err = lzmaSupport.compress(self.getLzs(), inGuest, len, action, INITIAL_BUFFER_SIZE, compress); @@ -889,26 +888,26 @@ static byte[] nativeCompress(Node inliningTarget, LZMACompressor.Native self, Py @SuppressWarnings("unused") @Specialization(guards = "action == LZMA_RUN") static byte[] javaCompress(Node inliningTarget, LZMACompressor.Java self, PythonContext context, byte[] bytes, int len, int action, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { try { self.write(bytes, 0, len); byte[] result = self.getByteArray(); self.resetBuffer(); return result; } catch (IOException e) { - throw raiseNode.get(inliningTarget).raise(LZMAError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, LZMAError, ErrorMessages.M, e); } } @SuppressWarnings("unused") @Specialization(guards = "action == LZMA_FINISH") static byte[] javaFlush(Node inliningTarget, LZMACompressor.Java self, PythonContext context, byte[] bytes, int len, int action, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { try { self.finish(); return self.getByteArray(); } catch (IOException e) { - throw raiseNode.get(inliningTarget).raise(LZMAError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, LZMAError, ErrorMessages.M, e); } } } @@ -930,7 +929,7 @@ static void auto(LZMADecompressor.Native self, @SuppressWarnings("unused") int f @Shared("cs") @Cached NativeLibrary.InvokeNativeFunction createStream, @Exclusive @Cached NativeLibrary.InvokeNativeFunction lzmaAutoDecoder, @Shared @Cached InlinedConditionProfile errProfile, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { NFILZMASupport lzmaSupport = PythonContext.get(inliningTarget).getNFILZMASupport(); Object lzmast = lzmaSupport.createStream(createStream); self.init(lzmast, lzmaSupport); @@ -947,7 +946,7 @@ static void xz(LZMADecompressor.Native self, @SuppressWarnings("unused") int for @Shared("cs") @Cached NativeLibrary.InvokeNativeFunction createStream, @Exclusive @Cached NativeLibrary.InvokeNativeFunction lzmaStreamDecoder, @Shared @Cached InlinedConditionProfile errProfile, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { NFILZMASupport lzmaSupport = PythonContext.get(inliningTarget).getNFILZMASupport(); Object lzmast = lzmaSupport.createStream(createStream); self.init(lzmast, lzmaSupport); @@ -964,7 +963,7 @@ static void alone(LZMADecompressor.Native self, @SuppressWarnings("unused") int @Shared("cs") @Cached NativeLibrary.InvokeNativeFunction createStream, @Exclusive @Cached NativeLibrary.InvokeNativeFunction lzmaAloneDecoder, @Shared @Cached InlinedConditionProfile errProfile, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { NFILZMASupport lzmaSupport = PythonContext.get(inliningTarget).getNFILZMASupport(); Object lzmast = lzmaSupport.createStream(createStream); self.init(lzmast, lzmaSupport); @@ -985,8 +984,8 @@ public abstract static class LZMARawDecompressInit extends Node { @SuppressWarnings("unused") @Specialization static void rawJava(VirtualFrame frame, LZMADecompressor.Java self, Object filters, - @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, T_LZMA_JAVA_ERROR); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, T_LZMA_JAVA_ERROR); } @Specialization @@ -995,7 +994,7 @@ static void rawNative(VirtualFrame frame, Node inliningTarget, LZMADecompressor. @Cached(inline = false) NativeLibrary.InvokeNativeFunction lzmaRawDecoder, @Cached(inline = false) NativeFilterChain filterChain, @Cached InlinedConditionProfile errProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { PythonContext context = PythonContext.get(inliningTarget); NFILZMASupport lzmaSupport = context.getNFILZMASupport(); Object lzmast = lzmaSupport.createStream(createStream); @@ -1116,7 +1115,7 @@ static byte[] nativeInternalDecompress(Node inliningTarget, LZMADecompressor.Nat @Cached(inline = false) NativeLibrary.InvokeNativeFunction getNextInIndex, @Cached(inline = false) NativeLibrary.InvokeNativeFunction getLzsCheck, @Cached GetOutputNativeBufferNode getBuffer, - @Exclusive @Cached PRaiseNode.Lazy lazyRaiseNode, + @Exclusive @Cached PRaiseNode lazyRaiseNode, @Cached InlinedConditionProfile errProfile) { PythonContext context = PythonContext.get(inliningTarget); NFILZMASupport lzmaSupport = context.getNFILZMASupport(); @@ -1132,7 +1131,7 @@ static byte[] nativeInternalDecompress(Node inliningTarget, LZMADecompressor.Nat self.setLzsAvailIn(lzsAvailIn); self.setLzsAvailOut(lzsAvailOut); } catch (OverflowException of) { - throw lazyRaiseNode.get(inliningTarget).raise(SystemError, VALUE_TOO_LARGE_TO_FIT_INTO_INDEX); + throw lazyRaiseNode.raise(inliningTarget, SystemError, VALUE_TOO_LARGE_TO_FIT_INTO_INDEX); } if (err == LZMA_STREAM_END) { self.setEOF(); @@ -1145,7 +1144,7 @@ static byte[] nativeInternalDecompress(Node inliningTarget, LZMADecompressor.Nat @TruffleBoundary @Specialization static byte[] javaInternalDecompress(Node inliningTarget, LZMADecompressor.Java self, int maxLength, - @Exclusive @Cached PRaiseNode.Lazy lazyRaiseNode) { + @Exclusive @Cached PRaiseNode lazyRaiseNode) { if (maxLength == 0) { return PythonUtils.EMPTY_BYTE_ARRAY; } @@ -1191,7 +1190,7 @@ static byte[] javaInternalDecompress(Node inliningTarget, LZMADecompressor.Java } catch (EOFException eof) { self.setEOF(); } catch (IOException e) { - PRaiseNode.raiseUncached(inliningTarget, OSError, e); + PRaiseNode.raiseStatic(inliningTarget, OSError, e); } byte[] ret = toByteArray(baos); self.decompressedData(ret.length); @@ -1231,13 +1230,13 @@ public abstract static class GetOutputNativeBufferNode extends Node { static byte[] getBuffer(Node inliningTarget, Object lzmast, PythonContext context, @Cached(inline = false) NativeLibrary.InvokeNativeFunction getBufferSize, @Cached(inline = false) NativeLibrary.InvokeNativeFunction getBuffer, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { NFILZMASupport lzmaSupport = context.getNFILZMASupport(); int size; try { size = PInt.intValueExact(lzmaSupport.getOutputBufferSize(lzmast, getBufferSize)); } catch (OverflowException of) { - throw raiseNode.get(inliningTarget).raise(SystemError, VALUE_TOO_LARGE_TO_FIT_INTO_INDEX); + throw raiseNode.raise(inliningTarget, SystemError, VALUE_TOO_LARGE_TO_FIT_INTO_INDEX); } if (size == 0) { return PythonUtils.EMPTY_BYTE_ARRAY; @@ -1298,7 +1297,7 @@ static byte[] encodeNative(VirtualFrame frame, Object filter, @Cached NativeLibrary.InvokeNativeFunction encodeFilter, @Cached NativeLibrary.InvokeNativeFunction deallocateStream, @Cached InlinedConditionProfile errProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { PythonContext ctxt = PythonContext.get(inliningTarget); NFILZMASupport lzmaSupport = ctxt.getNFILZMASupport(); Object lzmast = lzmaSupport.createStream(createStream); @@ -1307,7 +1306,7 @@ static byte[] encodeNative(VirtualFrame frame, Object filter, if (errProfile.profile(inliningTarget, lzret != LZMA_OK)) { lzmaSupport.deallocateStream(lzmast, deallocateStream); if (lzret == LZMA_PRESET_ERROR) { - throw raiseNode.get(inliningTarget).raise(LZMAError, INVALID_COMPRESSION_PRESET, opts[LZMAOption.preset.ordinal()]); + throw raiseNode.raise(inliningTarget, LZMAError, INVALID_COMPRESSION_PRESET, opts[LZMAOption.preset.ordinal()]); } errorHandling(inliningTarget, lzret, raiseNode); } @@ -1319,8 +1318,8 @@ static byte[] encodeNative(VirtualFrame frame, Object filter, @SuppressWarnings("unused") @Specialization(guards = "!useNativeContext()") static byte[] encodeJava(Object filter, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, T_LZMA_JAVA_ERROR); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, T_LZMA_JAVA_ERROR); } } @@ -1340,7 +1339,7 @@ static void decodeNative(VirtualFrame frame, long id, byte[] encoded, PDict dict @Cached NativeLibrary.InvokeNativeFunction decodeFilter, @Cached HashingStorageSetItem setItem, @Cached InlinedConditionProfile errProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { PythonContext ctxt = PythonContext.get(inliningTarget); NFILZMASupport lzmaSupport = ctxt.getNFILZMASupport(); long[] opts = new long[MAX_OPTS_INDEX]; @@ -1350,7 +1349,7 @@ static void decodeNative(VirtualFrame frame, long id, byte[] encoded, PDict dict int lzret = lzmaSupport.decodeFilter(id, encodedProps, len, filter, decodeFilter); if (errProfile.profile(inliningTarget, lzret != LZMA_OK)) { if (lzret == LZMA_ID_ERROR) { - throw raiseNode.get(inliningTarget).raise(LZMAError, INVALID_FILTER, opts[LZMAOption.id.ordinal()]); + throw raiseNode.raise(inliningTarget, LZMAError, INVALID_FILTER, opts[LZMAOption.id.ordinal()]); } errorHandling(inliningTarget, lzret, raiseNode); } @@ -1360,8 +1359,8 @@ static void decodeNative(VirtualFrame frame, long id, byte[] encoded, PDict dict @SuppressWarnings("unused") @Specialization(guards = "!useNativeContext()") static void decodeJava(long id, byte[] encoded, PDict dict, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, T_LZMA_JAVA_ERROR); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, T_LZMA_JAVA_ERROR); } static void buildFilterSpec(VirtualFrame frame, Node inliningTarget, long[] opts, PDict dict, HashingStorageSetItem setItem) { @@ -1435,7 +1434,7 @@ public int getAvailIn() { } } - protected static int errorHandling(Node inliningTarget, int lzret, PRaiseNode.Lazy raiseNode) { + protected static int errorHandling(Node inliningTarget, int lzret, PRaiseNode raiseNode) { switch (lzret) { case LZMA_OK: case LZMA_GET_CHECK: @@ -1443,23 +1442,23 @@ protected static int errorHandling(Node inliningTarget, int lzret, PRaiseNode.La case LZMA_STREAM_END: return 0; case LZMA_UNSUPPORTED_CHECK: - throw raiseNode.get(inliningTarget).raise(LZMAError, ErrorMessages.UNSUPPORTED_INTEGRITY_CHECK); + throw raiseNode.raise(inliningTarget, LZMAError, ErrorMessages.UNSUPPORTED_INTEGRITY_CHECK); case LZMA_MEM_ERROR: - throw raiseNode.get(inliningTarget).raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); case LZMA_MEMLIMIT_ERROR: - throw raiseNode.get(inliningTarget).raise(LZMAError, ErrorMessages.MEM_USAGE_LIMIT_EXCEEDED); + throw raiseNode.raise(inliningTarget, LZMAError, ErrorMessages.MEM_USAGE_LIMIT_EXCEEDED); case LZMA_FORMAT_ERROR: - throw raiseNode.get(inliningTarget).raise(LZMAError, ErrorMessages.INPUT_FMT_NOT_SUPPORTED_BY_DECODER); + throw raiseNode.raise(inliningTarget, LZMAError, ErrorMessages.INPUT_FMT_NOT_SUPPORTED_BY_DECODER); case LZMA_OPTIONS_ERROR: - throw raiseNode.get(inliningTarget).raise(LZMAError, ErrorMessages.INVALID_UNSUPPORTED_OPTIONS); + throw raiseNode.raise(inliningTarget, LZMAError, ErrorMessages.INVALID_UNSUPPORTED_OPTIONS); case LZMA_DATA_ERROR: - throw raiseNode.get(inliningTarget).raise(LZMAError, ErrorMessages.CORRUPT_INPUT_DATA); + throw raiseNode.raise(inliningTarget, LZMAError, ErrorMessages.CORRUPT_INPUT_DATA); case LZMA_BUF_ERROR: - throw raiseNode.get(inliningTarget).raise(LZMAError, ErrorMessages.INSUFFICIENT_BUFFER_SPACE); + throw raiseNode.raise(inliningTarget, LZMAError, ErrorMessages.INSUFFICIENT_BUFFER_SPACE); case LZMA_PROG_ERROR: - throw raiseNode.get(inliningTarget).raise(LZMAError, ErrorMessages.INTERNAL_ERROR); + throw raiseNode.raise(inliningTarget, LZMAError, ErrorMessages.INTERNAL_ERROR); default: - throw raiseNode.get(inliningTarget).raise(LZMAError, ErrorMessages.UNRECOGNIZED_ERROR_FROM_LIBLZMA, lzret); + throw raiseNode.raise(inliningTarget, LZMAError, ErrorMessages.UNRECOGNIZED_ERROR_FROM_LIBLZMA, lzret); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/GraalPySemLockBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/GraalPySemLockBuiltins.java index 45a533e723..e7ccfa245b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/GraalPySemLockBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/GraalPySemLockBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,13 +46,20 @@ import java.util.List; import java.util.concurrent.Semaphore; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.modules.multiprocessing.GraalPySemLockBuiltinsClinicProviders.SemLockNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyFloatAsDoubleNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; @@ -66,7 +73,7 @@ import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonContext.SharedMultiprocessingData; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -80,6 +87,8 @@ @CoreFunctions(extendClasses = {PythonBuiltinClassType.PGraalPySemLock}) public final class GraalPySemLockBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = GraalPySemLockBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return GraalPySemLockBuiltinsFactory.getFactories(); @@ -91,6 +100,52 @@ public void initialize(Python3Core core) { super.initialize(core); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "SemLock", parameterNames = {"cls", "kind", "value", "maxvalue", "name", "unlink"}) + @ArgumentClinic(name = "kind", conversion = ArgumentClinic.ClinicConversion.Int) + @ArgumentClinic(name = "value", conversion = ArgumentClinic.ClinicConversion.Int) + @ArgumentClinic(name = "maxvalue", conversion = ArgumentClinic.ClinicConversion.Int) + @ArgumentClinic(name = "name", conversion = ArgumentClinic.ClinicConversion.TString) + @ArgumentClinic(name = "unlink", conversion = ArgumentClinic.ClinicConversion.IntToBoolean) + @GenerateNodeFactory + abstract static class SemLockNode extends PythonClinicBuiltinNode { + @Specialization + static PGraalPySemLock construct(Object cls, int kind, int value, @SuppressWarnings("unused") int maxValue, TruffleString name, boolean unlink, + @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached PRaiseNode raiseNode) { + if (kind != PGraalPySemLock.RECURSIVE_MUTEX && kind != PGraalPySemLock.SEMAPHORE) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.UNRECOGNIZED_KIND); + } + Semaphore semaphore = newSemaphore(value); + if (!unlink) { + // CPython creates a named semaphore, and if unlink != 0 unlinks + // it directly, so it cannot be accessed by other processes. We + // have to explicitly link it, so we do that here if we + // must. CPython always uses O_CREAT | O_EXCL for creating named + // semaphores, so a conflict raises. + SharedMultiprocessingData multiprocessing = PythonContext.get(inliningTarget).getSharedMultiprocessingData(); + if (multiprocessing.getNamedSemaphore(name) != null) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.FileExistsError, ErrorMessages.SEMAPHORE_NAME_TAKEN, name); + } else { + multiprocessing.putNamedSemaphore(name, semaphore); + } + } + return PFactory.createGraalPySemLock(language, cls, getInstanceShape.execute(cls), name, kind, semaphore); + } + + @TruffleBoundary + private static Semaphore newSemaphore(int value) { + return new Semaphore(value); + } + + @Override + protected ArgumentClinicProvider getArgumentClinic() { + return SemLockNodeClinicProviderGen.INSTANCE; + } + } + @Builtin(name = "_count", minNumOfPositionalArgs = 1) @GenerateNodeFactory abstract static class CountNode extends PythonUnaryBuiltinNode { @@ -240,7 +295,7 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static Object doEnter(@SuppressWarnings("unused") Object handle, int kind, @SuppressWarnings("unused") Object maxvalue, TruffleString name, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { SharedMultiprocessingData multiprocessing = PythonContext.get(inliningTarget).getSharedMultiprocessingData(); Semaphore semaphore = multiprocessing.getNamedSemaphore(name); if (semaphore == null) { @@ -248,7 +303,7 @@ static Object doEnter(@SuppressWarnings("unused") Object handle, int kind, @Supp // provided handle semaphore = newSemaphore(); } - return factory.createGraalPySemLock(PythonBuiltinClassType.PGraalPySemLock, name, kind, semaphore); + return PFactory.createGraalPySemLock(language, name, kind, semaphore); } @TruffleBoundary @@ -263,10 +318,10 @@ abstract static class ReleaseLockNode extends PythonUnaryBuiltinNode { @Specialization static Object doRelease(PGraalPySemLock self, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (self.getKind() == PGraalPySemLock.RECURSIVE_MUTEX) { if (!self.isMine()) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.AssertionError, ErrorMessages.ATTEMP_TO_RELEASE_RECURSIVE_LOCK); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AssertionError, ErrorMessages.ATTEMP_TO_RELEASE_RECURSIVE_LOCK); } if (self.getCount() > 1) { self.decreaseCount(); @@ -288,5 +343,4 @@ static Object exit(PGraalPySemLock self, @SuppressWarnings("unused") Object type return PNone.NONE; } } - } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/MultiprocessingGraalPyModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/MultiprocessingGraalPyModuleBuiltins.java index 308f2b859b..87855c2936 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/MultiprocessingGraalPyModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/MultiprocessingGraalPyModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,11 +47,9 @@ import java.util.concurrent.Semaphore; import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.modules.PosixModuleBuiltins; import com.oracle.graal.python.builtins.objects.PNone; @@ -73,9 +71,7 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaDoubleNode; import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; @@ -85,7 +81,7 @@ import com.oracle.graal.python.runtime.PosixSupportLibrary.Timeval; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonContext.SharedMultiprocessingData; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.ArrayBuilder; @@ -118,54 +114,10 @@ protected List> getNodeFa @Override public void initialize(Python3Core core) { // TODO: add necessary entries to the dict - addBuiltinConstant("flags", core.factory().createDict()); + addBuiltinConstant("flags", PFactory.createDict(core.getLanguage())); super.initialize(core); } - @Builtin(name = "SemLock", parameterNames = {"cls", "kind", "value", "maxvalue", "name", "unlink"}, constructsClass = PythonBuiltinClassType.PGraalPySemLock) - @ArgumentClinic(name = "kind", conversion = ArgumentClinic.ClinicConversion.Int) - @ArgumentClinic(name = "value", conversion = ArgumentClinic.ClinicConversion.Int) - @ArgumentClinic(name = "maxvalue", conversion = ArgumentClinic.ClinicConversion.Int) - @ArgumentClinic(name = "name", conversion = ArgumentClinic.ClinicConversion.TString) - @ArgumentClinic(name = "unlink", conversion = ArgumentClinic.ClinicConversion.IntToBoolean) - @GenerateNodeFactory - abstract static class SemLockNode extends PythonClinicBuiltinNode { - @Specialization - static PGraalPySemLock construct(Object cls, int kind, int value, @SuppressWarnings("unused") int maxValue, TruffleString name, boolean unlink, - @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (kind != PGraalPySemLock.RECURSIVE_MUTEX && kind != PGraalPySemLock.SEMAPHORE) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.UNRECOGNIZED_KIND); - } - Semaphore semaphore = newSemaphore(value); - if (!unlink) { - // CPython creates a named semaphore, and if unlink != 0 unlinks - // it directly, so it cannot be accessed by other processes. We - // have to explicitly link it, so we do that here if we - // must. CPython always uses O_CREAT | O_EXCL for creating named - // semaphores, so a conflict raises. - SharedMultiprocessingData multiprocessing = PythonContext.get(inliningTarget).getSharedMultiprocessingData(); - if (multiprocessing.getNamedSemaphore(name) != null) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.FileExistsError, ErrorMessages.SEMAPHORE_NAME_TAKEN, name); - } else { - multiprocessing.putNamedSemaphore(name, semaphore); - } - } - return factory.createGraalPySemLock(cls, name, kind, semaphore); - } - - @TruffleBoundary - private static Semaphore newSemaphore(int value) { - return new Semaphore(value); - } - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return MultiprocessingGraalPyModuleBuiltinsClinicProviders.SemLockNodeClinicProviderGen.INSTANCE; - } - } - @GenerateNodeFactory @Builtin(name = "sem_unlink", parameterNames = {"name"}) abstract static class SemUnlink extends PythonUnaryBuiltinNode { @@ -218,13 +170,13 @@ long getTid( abstract static class WaitTidNode extends PythonBinaryBuiltinNode { @Specialization PTuple waittid(long id, @SuppressWarnings("unused") int options, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { long tid = convertTid(id); // TODO implement for options - WNOHANG and 0 final SharedMultiprocessingData multiprocessing = getContext().getSharedMultiprocessingData(); Thread thread = multiprocessing.getChildContextThread(tid); if (thread != null && thread.isAlive()) { - return factory.createTuple(new Object[]{0, 0, 0}); + return PFactory.createTuple(language, new Object[]{0, 0, 0}); } PythonContext.ChildContextData data = multiprocessing.getChildContextData(tid); @@ -234,7 +186,7 @@ PTuple waittid(long id, @SuppressWarnings("unused") int options, * clean it. See popen_truffleprocess that calls the _waittid builtin. */ multiprocessing.removeChildContextData(tid); - return factory.createTuple(new Object[]{id, data.wasSignaled() ? data.getExitCode() : 0, data.getExitCode()}); + return PFactory.createTuple(language, new Object[]{id, data.wasSignaled() ? data.getExitCode() : 0, data.getExitCode()}); } } @@ -274,7 +226,7 @@ abstract static class PipeNode extends PythonBuiltinNode { @Specialization PTuple pipe(@Cached GilNode gil, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { int[] pipe; PythonContext ctx = getContext(); SharedMultiprocessingData sharedData = ctx.getSharedMultiprocessingData(); @@ -286,7 +238,7 @@ PTuple pipe(@Cached GilNode gil, } finally { gil.acquire(); } - return factory.createTuple(new Object[]{pipe[0], pipe[1]}); + return PFactory.createTuple(language, new Object[]{pipe[0], pipe[1]}); } } @@ -303,7 +255,7 @@ Object doWrite(int fd, PBytes data, byte[] bytes = bufferLib.getCopiedByteArray(data); sharedData.addPipeData(fd, bytes, () -> { - throw PRaiseNode.raiseUncached(this, OSError, ErrorMessages.BAD_FILE_DESCRIPTOR); + throw PRaiseNode.raiseStatic(this, OSError, ErrorMessages.BAD_FILE_DESCRIPTOR); }, () -> { throw PConstructAndRaiseNode.getUncached().raiseOSError(null, OSErrorEnum.EPIPE); @@ -327,18 +279,18 @@ Object doWrite(long fd, PBytes data, public abstract static class ReadNode extends PythonBinaryBuiltinNode { @Specialization Object doReadInt(int fd, @SuppressWarnings("unused") Object length, - @Shared @Cached GilNode gil, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language, + @Shared @Cached GilNode gil) { SharedMultiprocessingData sharedData = getContext().getSharedMultiprocessingData(); gil.release(true); try { Object data = sharedData.takePipeData(this, fd, () -> { - throw PRaiseNode.raiseUncached(this, OSError, ErrorMessages.BAD_FILE_DESCRIPTOR); + throw PRaiseNode.raiseStatic(this, OSError, ErrorMessages.BAD_FILE_DESCRIPTOR); }); if (data == PNone.NONE) { - return factory.createBytes(PythonUtils.EMPTY_BYTE_ARRAY, 0, 0); + return PFactory.createEmptyBytes(language); } - return factory.createBytes((byte[]) data); + return PFactory.createBytes(language, (byte[]) data); } finally { gil.acquire(); } @@ -346,9 +298,9 @@ Object doReadInt(int fd, @SuppressWarnings("unused") Object length, @Specialization Object doReadLong(long fd, Object length, - @Shared @Cached GilNode gil, - @Shared @Cached PythonObjectFactory factory) { - return doReadInt((int) fd, length, gil, factory); + @Bind PythonLanguage language, + @Shared @Cached GilNode gil) { + return doReadInt((int) fd, length, language, gil); } } @@ -394,6 +346,7 @@ abstract static class SelectNode extends PythonBuiltinNode { @Specialization Object doGeneric(VirtualFrame frame, Object multiprocessingFdsList, Object multiprocessingObjsList, Object posixFileObjsList, Object timeoutObj, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached PosixModuleBuiltins.FileDescriptorConversionNode fdConvertor, @Cached PyObjectSizeNode sizeNode, @Cached PyObjectGetItem getItem, @@ -402,8 +355,7 @@ Object doGeneric(VirtualFrame frame, Object multiprocessingFdsList, Object multi @Cached CastToJavaIntLossyNode castToJava, @Cached CastToJavaDoubleNode castToDouble, @Cached GilNode gil, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PythonObjectFactory factory) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { PythonContext context = getContext(); SharedMultiprocessingData sharedData = context.getSharedMultiprocessingData(); @@ -443,7 +395,7 @@ Object doGeneric(VirtualFrame frame, Object multiprocessingFdsList, Object multi } } - return factory.createList(result.toArray(new Object[0])); + return PFactory.createList(language, result.toArray(new Object[0])); } catch (PosixSupportLibrary.PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } finally { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/MultiprocessingModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/MultiprocessingModuleBuiltins.java index 3b290b2982..afe5cf96f2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/MultiprocessingModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/MultiprocessingModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,28 +40,18 @@ */ package com.oracle.graal.python.builtins.modules.multiprocessing; -import static com.oracle.graal.python.runtime.PosixConstants.O_CREAT; -import static com.oracle.graal.python.runtime.PosixConstants.O_EXCL; - import java.util.List; -import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.runtime.PosixSupport; import com.oracle.graal.python.runtime.PosixSupportLibrary; import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -79,53 +69,6 @@ protected List> getNodeFa return MultiprocessingModuleBuiltinsFactory.getFactories(); } - @Builtin(name = "SemLock", parameterNames = {"$cls", "kind", "value", "maxvalue", "name", "unlink"}, constructsClass = PythonBuiltinClassType.PSemLock) - @ArgumentClinic(name = "kind", conversion = ArgumentClinic.ClinicConversion.Int) - @ArgumentClinic(name = "value", conversion = ArgumentClinic.ClinicConversion.Int) - @ArgumentClinic(name = "maxvalue", conversion = ArgumentClinic.ClinicConversion.Int) - @ArgumentClinic(name = "name", conversion = ArgumentClinic.ClinicConversion.TString) - @ArgumentClinic(name = "unlink", conversion = ArgumentClinic.ClinicConversion.IntToBoolean) - @GenerateNodeFactory - abstract static class SemLockNode extends PythonClinicBuiltinNode { - @Specialization - static PSemLock construct(VirtualFrame frame, Object cls, int kind, int value, int maxValue, TruffleString name, boolean unlink, - @Bind("this") Node inliningTarget, - @Bind("getPosixSupport()") PosixSupport posixSupport, - @CachedLibrary("posixSupport") PosixSupportLibrary posixLib, - @Cached PythonObjectFactory factory, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode.Lazy raiseNode) { - if (kind != PGraalPySemLock.RECURSIVE_MUTEX && kind != PGraalPySemLock.SEMAPHORE) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.UNRECOGNIZED_KIND); - } - Object posixName = posixLib.createPathFromString(posixSupport, name); - long handle; - try { - handle = posixLib.semOpen(posixSupport, posixName, O_CREAT.value | O_EXCL.value, 0600, value); - } catch (PosixException e) { - throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); - } - if (unlink) { - try { - posixLib.semUnlink(posixSupport, posixName); - } catch (PosixException e) { - try { - posixLib.semClose(posixSupport, handle); - } catch (PosixException ex) { - // Ignore, we're already on an error path - } - throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); - } - } - return factory.createSemLock(cls, handle, kind, maxValue, name); - } - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return MultiprocessingModuleBuiltinsClinicProviders.SemLockNodeClinicProviderGen.INSTANCE; - } - } - @GenerateNodeFactory @Builtin(name = "sem_unlink", parameterNames = {"name"}) abstract static class SemUnlink extends PythonUnaryBuiltinNode { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/SemLockBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/SemLockBuiltins.java index 2834d0b355..43607eff8c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/SemLockBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/SemLockBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,17 +44,26 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ENTER__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EXIT__; +import static com.oracle.graal.python.runtime.PosixConstants.O_CREAT; +import static com.oracle.graal.python.runtime.PosixConstants.O_EXCL; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.modules.multiprocessing.SemLockBuiltinsClinicProviders.SemLockNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.thread.PThread; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyFloatAsDoubleNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; @@ -71,7 +80,7 @@ import com.oracle.graal.python.runtime.PosixSupportLibrary; import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException; import com.oracle.graal.python.runtime.PosixSupportLibrary.UnsupportedPosixFeatureException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -84,6 +93,9 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PSemLock) public class SemLockBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = SemLockBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return SemLockBuiltinsFactory.getFactories(); @@ -95,6 +107,55 @@ public void initialize(Python3Core core) { super.initialize(core); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "SemLock", parameterNames = {"$cls", "kind", "value", "maxvalue", "name", "unlink"}) + @ArgumentClinic(name = "kind", conversion = ArgumentClinic.ClinicConversion.Int) + @ArgumentClinic(name = "value", conversion = ArgumentClinic.ClinicConversion.Int) + @ArgumentClinic(name = "maxvalue", conversion = ArgumentClinic.ClinicConversion.Int) + @ArgumentClinic(name = "name", conversion = ArgumentClinic.ClinicConversion.TString) + @ArgumentClinic(name = "unlink", conversion = ArgumentClinic.ClinicConversion.IntToBoolean) + @GenerateNodeFactory + abstract static class SemLockNode extends PythonClinicBuiltinNode { + @Specialization + static PSemLock construct(VirtualFrame frame, Object cls, int kind, int value, int maxValue, TruffleString name, boolean unlink, + @Bind("this") Node inliningTarget, + @Bind("getPosixSupport()") PosixSupport posixSupport, + @CachedLibrary("posixSupport") PosixSupportLibrary posixLib, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, + @Cached PRaiseNode raiseNode) { + if (kind != PGraalPySemLock.RECURSIVE_MUTEX && kind != PGraalPySemLock.SEMAPHORE) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.UNRECOGNIZED_KIND); + } + Object posixName = posixLib.createPathFromString(posixSupport, name); + long handle; + try { + handle = posixLib.semOpen(posixSupport, posixName, O_CREAT.value | O_EXCL.value, 0600, value); + } catch (PosixException e) { + throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); + } + if (unlink) { + try { + posixLib.semUnlink(posixSupport, posixName); + } catch (PosixException e) { + try { + posixLib.semClose(posixSupport, handle); + } catch (PosixException ex) { + // Ignore, we're already on an error path + } + throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); + } + } + return PFactory.createSemLock(language, cls, getInstanceShape.execute(cls), handle, kind, maxValue, name); + } + + @Override + protected ArgumentClinicProvider getArgumentClinic() { + return SemLockNodeClinicProviderGen.INSTANCE; + } + } + @Builtin(name = "handle", minNumOfPositionalArgs = 1, isGetter = true) @GenerateNodeFactory abstract static class HandleNode extends PythonUnaryBuiltinNode { @@ -205,11 +266,11 @@ static PNone release(VirtualFrame frame, PSemLock self, @Bind("this") Node inliningTarget, @Bind("getPosixSupport()") PosixSupport posixSupport, @CachedLibrary("posixSupport") PosixSupportLibrary posixLib, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { if (self.getKind() == PSemLock.RECURSIVE_MUTEX) { if (!self.isMine()) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.AssertionError, ErrorMessages.ATTEMP_TO_RELEASE_RECURSIVE_LOCK); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AssertionError, ErrorMessages.ATTEMP_TO_RELEASE_RECURSIVE_LOCK); } if (self.getCount() > 1) { self.decreaseCount(); @@ -221,7 +282,7 @@ static PNone release(VirtualFrame frame, PSemLock self, try { sval = posixLib.semGetValue(posixSupport, self.getHandle()); if (sval >= self.getMaxValue()) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.SEMAPHORE_RELEASED_TOO_MANY_TIMES); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.SEMAPHORE_RELEASED_TOO_MANY_TIMES); } } catch (UnsupportedPosixFeatureException e) { /* We will only check properly the maxvalue == 1 case */ @@ -229,7 +290,7 @@ static PNone release(VirtualFrame frame, PSemLock self, if (posixLib.semTryWait(posixSupport, self.getHandle())) { /* it was not locked so undo wait and raise */ posixLib.semPost(posixSupport, self.getHandle()); - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.SEMAPHORE_RELEASED_TOO_MANY_TIMES); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.SEMAPHORE_RELEASED_TOO_MANY_TIMES); } } } @@ -294,7 +355,7 @@ int get(VirtualFrame frame, PSemLock self, @Bind("getPosixSupport()") PosixSupport posixSupport, @CachedLibrary("posixSupport") PosixSupportLibrary posixLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { int sval = posixLib.semGetValue(posixSupport, self.getHandle()); /* @@ -309,7 +370,7 @@ int get(VirtualFrame frame, PSemLock self, throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } catch (UnsupportedPosixFeatureException e) { // Not available on Darwin - throw raiseNode.get(inliningTarget).raise(NotImplementedError); + throw raiseNode.raise(inliningTarget, NotImplementedError); } } } @@ -362,7 +423,8 @@ static Object rebuild(VirtualFrame frame, Object cls, @SuppressWarnings("unused" @Bind("this") Node inliningTarget, @Bind("getPosixSupport()") PosixSupport posixSupport, @CachedLibrary("posixSupport") PosixSupportLibrary posixLib, - @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { Object posixName = posixLib.createPathFromString(posixSupport, name); long handle; @@ -371,7 +433,7 @@ static Object rebuild(VirtualFrame frame, Object cls, @SuppressWarnings("unused" } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } - return factory.createSemLock(cls, handle, kind, maxValue, name); + return PFactory.createSemLock(language, cls, getInstanceShape.execute(cls), handle, kind, maxValue, name); } @Override diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/MemoTable.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/MemoTable.java index 595da28de2..4393f54f42 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/MemoTable.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/MemoTable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -173,7 +173,7 @@ private void resize() { if (newLength <= keys.length) { CompilerDirectives.transferToInterpreterAndInvalidate(); // overflow - throw PRaiseNode.raiseUncached(null, PicklingError, ErrorMessages.STRUCT_SIZE_TOO_LONG); + throw PRaiseNode.raiseStatic(null, PicklingError, ErrorMessages.STRUCT_SIZE_TOO_LONG); } MemoIterator iterator = iterator(); // captures the current contents diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PData.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PData.java index ec3f3c30a2..c53e006ed1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PData.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,6 +40,7 @@ */ package com.oracle.graal.python.builtins.modules.pickle; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.tuple.PTuple; @@ -47,7 +48,7 @@ import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.OverflowException; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.dsl.Bind; @@ -97,8 +98,8 @@ public void grow() throws OverflowException { } public abstract static class PDataBaseNode extends PNodeWithContext { - static PException raiseUnderflow(PData self, PRaiseNode raiseNode) { - return raiseNode.raise(PythonBuiltinClassType.UnpicklingError, + static PException raiseUnderflow(PData self, Node inliningTarget, PRaiseNode raiseNode) { + return raiseNode.raise(inliningTarget, PythonBuiltinClassType.UnpicklingError, self.mark ? ErrorMessages.PDATA_UNEXPECTED_MARK_FOUND : ErrorMessages.PDATA_UNPICKLING_STACK_UNDERFLOW); } } @@ -111,9 +112,9 @@ public abstract static class PDataPopNode extends PDataBaseNode { @Specialization static Object pop(PData self, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (self.size <= self.fence) { - throw raiseUnderflow(self, raiseNode.get(inliningTarget)); + throw raiseUnderflow(self, inliningTarget, raiseNode); } return self.data[--self.size]; } @@ -131,12 +132,12 @@ public abstract static class PDataPushNode extends PDataBaseNode { @Specialization static void push(PData self, Object obj, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (self.size == self.data.length) { try { self.grow(); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raiseOverflow(); + throw raiseNode.raiseOverflow(inliningTarget); } } self.data[self.size++] = obj; @@ -155,12 +156,12 @@ public abstract static class PDataPopTupleNode extends PDataBaseNode { @Specialization static PTuple popTuple(PData self, int start, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { int len, i, j; if (start < self.fence) { - throw raiseUnderflow(self, raiseNode.get(inliningTarget)); + throw raiseUnderflow(self, inliningTarget, raiseNode); } len = self.size - start; Object[] items = new Object[len]; @@ -168,7 +169,7 @@ static PTuple popTuple(PData self, int start, items[j] = self.data[i]; } self.size = start; - return factory.createTuple(items); + return PFactory.createTuple(language, items); } public static PDataPopTupleNode create() { @@ -183,7 +184,7 @@ public abstract static class PDataPopListNode extends PDataBaseNode { @Specialization public PList popList(PData self, int start, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { int len, i, j; len = self.size - start; @@ -192,7 +193,7 @@ public PList popList(PData self, int start, items[j] = self.data[i]; } self.size = start; - return factory.createList(items); + return PFactory.createList(language, items); } public static PDataPopListNode create() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickleBuffer.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickleBuffer.java index d9bf079ce6..456c130bd1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickleBuffer.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickleBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,10 +47,12 @@ import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; @ExportLibrary(PythonBufferAcquireLibrary.class) @@ -80,6 +82,7 @@ boolean hasBuffer() { @ExportMessage Object acquire(int flags, + @Bind("$node") Node inliningTarget, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, @Cached PRaiseNode raise) { @@ -88,7 +91,7 @@ Object acquire(int flags, owner = bufferLib.getOwner(view); } if (owner == null) { - throw raise.raise(ValueError, ErrorMessages.OP_FORBIDDEN_ON_OBJECT, "PickleBuffer"); + throw raise.raise(inliningTarget, ValueError, ErrorMessages.OP_FORBIDDEN_ON_OBJECT, "PickleBuffer"); } return acquireLib.acquire(owner, flags); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickler.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickler.java index 5331ccbf86..cd3f372ec6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickler.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickler.java @@ -65,6 +65,7 @@ import org.graalvm.collections.Pair; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PNotImplemented; @@ -87,6 +88,7 @@ import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyCallableCheckNode; import com.oracle.graal.python.lib.PyFloatAsDoubleNode; import com.oracle.graal.python.lib.PyLongAsLongNode; @@ -107,7 +109,7 @@ import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.Consumer; import com.oracle.graal.python.util.NumericSupport; @@ -272,32 +274,32 @@ private void fastMemoRemove(Object object) { } // helper methods - public void setProtocol(Node inliningTarget, PRaiseNode.Lazy raiseNode, int protocol, boolean fixImports) { + public void setProtocol(Node inliningTarget, PRaiseNode raiseNode, int protocol, boolean fixImports) { proto = protocol; if (proto < 0) { proto = PickleUtils.PICKLE_PROTOCOL_HIGHEST; } else if (proto > PickleUtils.PICKLE_PROTOCOL_HIGHEST) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.PICKLE_PROTO_MUST_BE_LE, PickleUtils.PICKLE_PROTOCOL_HIGHEST); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.PICKLE_PROTO_MUST_BE_LE, PickleUtils.PICKLE_PROTOCOL_HIGHEST); } this.bin = (proto > 0) ? 1 : 0; this.fixImports = fixImports && proto < 3; } - public void setOutputStream(VirtualFrame frame, Node inliningTarget, PRaiseNode.Lazy raiseNode, PyObjectLookupAttr lookup, Object file) { + public void setOutputStream(VirtualFrame frame, Node inliningTarget, PRaiseNode raiseNode, PyObjectLookupAttr lookup, Object file) { write = lookup.execute(frame, inliningTarget, file, PickleUtils.T_METHOD_WRITE); if (write == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.FILE_MUST_HAVE_WRITE_ATTR); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.FILE_MUST_HAVE_WRITE_ATTR); } } - public void setBufferCallback(Node inliningTarget, PRaiseNode.Lazy raiseNode, Object callback) { + public void setBufferCallback(Node inliningTarget, PRaiseNode raiseNode, Object callback) { bufferCallback = callback; if (PGuards.isNone(callback) || PGuards.isNoValue(callback)) { bufferCallback = null; } if (bufferCallback != null && proto < 5) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.BUFFCB_NEEDS_PROTO_GE_5); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.BUFFCB_NEEDS_PROTO_GE_5); } } @@ -353,9 +355,9 @@ public void commitFrame() { frameStart = -1; } - public PBytes getString(PythonObjectFactory factory) { + public PBytes getString(PythonLanguage language) { commitFrame(); - return factory.createBytes(outputBuffer, outputLen); + return PFactory.createBytes(language, outputBuffer, outputLen); } // inner nodes @@ -528,7 +530,7 @@ protected void writeBytes(VirtualFrame frame, PPickler pickler, byte[] header, i if (pld == null) { // TODO: It would be better to use a memoryview with a linked original string if // this is possible. - pld = factory().createBytes(data, 0, dataSize); + pld = PFactory.createBytes(PythonLanguage.get(this), data, dataSize); } getCallNode().execute(frame, pickler.write, pld); // Reinitialize the buffer for subsequent calls to _Pickler_Write. @@ -543,9 +545,9 @@ protected void writeBytes(VirtualFrame frame, PPickler pickler, byte[] header, i protected PTuple createTuple(Object... items) { if (items.length == 0) { - return factory().createEmptyTuple(); + return PFactory.createEmptyTuple(PythonLanguage.get(this)); } - return factory().createTuple(items); + return PFactory.createTuple(PythonLanguage.get(this), items); } protected void fastSaveEnter(PPickler pickler, Object obj) { @@ -570,10 +572,11 @@ public abstract static class FlushToFileNode extends BasePickleWriteNode { public abstract void execute(VirtualFrame frame, PPickler pickler); @Specialization - public void flush(VirtualFrame frame, PPickler pickler) { + public void flush(VirtualFrame frame, PPickler pickler, + @Bind PythonLanguage language) { assert pickler.write != null; // This will commit the frame first - PBytes output = pickler.getString(factory()); + PBytes output = pickler.getString(language); call(frame, pickler.write, output); } } @@ -736,16 +739,19 @@ private void saveIteratorBatchedUnrolled(VirtualFrame frame, PPickler pickler, O Object obj; do { // Get first item - final Object firstItem = getNextItem(frame, iterator); - if (firstItem == null) { + final Object firstItem; + try { + firstItem = getNextItem(frame, iterator); + } catch (IteratorExhausted e) { // nothing more to add break; } checkItem.accept(firstItem); // Try to get a second item - obj = getNextItem(frame, iterator); - if (obj == null) { + try { + obj = getNextItem(frame, iterator); + } catch (IteratorExhausted e) { // Only one item to write saveItem.accept(firstItem); write(pickler, opcodeOneItem); @@ -766,8 +772,9 @@ private void saveIteratorBatchedUnrolled(VirtualFrame frame, PPickler pickler, O break; } - obj = getNextItem(frame, iterator); - if (obj == null) { + try { + obj = getNextItem(frame, iterator); + } catch (IteratorExhausted e) { break; } } @@ -798,8 +805,10 @@ private void saveListIteratorBatchUnrolled(VirtualFrame frame, PPickler pickler, private void saveIterator(VirtualFrame frame, PPickler pickler, Object iterator, byte opcode, Consumer itemConsumer) { while (true) { - Object item = getNextItem(frame, iterator); - if (item == null) { + Object item; + try { + item = getNextItem(frame, iterator); + } catch (IteratorExhausted e) { break; } itemConsumer.accept(item); @@ -949,7 +958,7 @@ private void saveReduce(VirtualFrame frame, PythonContext ctx, PPickler pickler, boolean useNewobj = false, useNewobjEx = false; if (!(arguments instanceof PTuple)) { - throw getRaiseNode().raiseBadInternalCall(); + throw raise(PythonBuiltinClassType.SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC); } int size = length(frame, arguments); if (size < 2 || size > 6) { @@ -1054,7 +1063,7 @@ private void saveReduce(VirtualFrame frame, PythonContext ctx, PPickler pickler, callable = callStarArgsAndKwArgs(frame, st.partial, newargs, kwargs); save(frame, pickler, callable, 0); - save(frame, pickler, factory().createEmptyTuple(), 0); + save(frame, pickler, PFactory.createEmptyTuple(PythonLanguage.get(this)), 0); write(pickler, PickleUtils.OPCODE_REDUCE); } } else if (useNewobj) { @@ -1110,7 +1119,7 @@ private void saveReduce(VirtualFrame frame, PythonContext ctx, PPickler pickler, // Save the class and its __new__ arguments save(frame, pickler, cls, 0); - newargtup = getItem(frame, argtup, factory().createIntSlice(1, argtupSize, 1)); + newargtup = getItem(frame, argtup, PFactory.createIntSlice(PythonLanguage.get(this), 1, argtupSize, 1)); save(frame, pickler, newargtup, 0); write(pickler, PickleUtils.OPCODE_NEWOBJ); } else { @@ -1492,8 +1501,10 @@ private void batchSet(VirtualFrame frame, PPickler pickler, Object obj) { i = 0; write(pickler, PickleUtils.OPCODE_MARK); while (true) { - Object item = getNextItem(frame, iterator); - if (item == null) { + Object item; + try { + item = getNextItem(frame, iterator); + } catch (IteratorExhausted e) { break; } save(frame, pickler, item, 0); @@ -1645,7 +1656,7 @@ private void saveList(VirtualFrame frame, PPickler pickler, Object obj) { private void storeTupleElements(VirtualFrame frame, PPickler pickler, Object obj, int len) { // A helper for save_tuple. Push the len elements in tuple t on the stack - assert PyObjectSizeNode.executeUncached(frame, obj) == len; + assert PyObjectSizeNode.executeUncached(obj) == len; for (int i = 0; i < len; i++) { Object element = getItem(frame, obj, i); save(frame, pickler, element, 0); @@ -1738,7 +1749,7 @@ private void saveBytearrayData(VirtualFrame frame, PPickler pickler, Object obj, memoPut(pickler, obj); } - private void saveBytearray(VirtualFrame frame, PythonContext ctx, PPickler pickler, Object obj, IndirectCallData indirectCallData) { + private void saveBytearray(VirtualFrame frame, Node inliningTarget, PythonContext ctx, PPickler pickler, Object obj, IndirectCallData indirectCallData) { Object buffer = getBufferAcquireLibrary().acquireReadonly(obj, frame, indirectCallData); try { if (pickler.proto < 5) { @@ -1750,7 +1761,7 @@ private void saveBytearray(VirtualFrame frame, PythonContext ctx, PPickler pickl reduceValue = createTuple(byteArrayClass, createTuple()); } else { byte[] bytes = getBufferLibrary().getCopiedByteArray(buffer); - reduceValue = createTuple(byteArrayClass, createTuple(factory().createBytes(bytes))); + reduceValue = createTuple(byteArrayClass, createTuple(PFactory.createBytes(ctx.getLanguage(inliningTarget), bytes))); } // save_reduce() will memoize the object automatically. @@ -2026,7 +2037,7 @@ void saveGeneric(VirtualFrame frame, PPickler pickler, Object objArg, int persSa saveTuple(frame, pickler, obj); return; } else if (isBuiltinClass(type, PythonBuiltinClassType.PByteArray)) { - saveBytearray(frame, ctx, pickler, obj, indirectCallData); + saveBytearray(frame, inliningTarget, ctx, pickler, obj, indirectCallData); return; } else if (obj instanceof PPickleBuffer buffer) { savePicklebuffer(frame, pickler, buffer); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PUnpickler.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PUnpickler.java index f3e125de7b..b56af84398 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PUnpickler.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PUnpickler.java @@ -130,6 +130,7 @@ import org.graalvm.collections.Pair; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.BufferFlags; @@ -147,6 +148,7 @@ import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageIteratorValue; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem; import com.oracle.graal.python.builtins.objects.dict.PDict; +import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.ints.IntNodes; import com.oracle.graal.python.builtins.objects.ints.IntNodesFactory; import com.oracle.graal.python.builtins.objects.list.ListBuiltins; @@ -156,7 +158,12 @@ import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; import com.oracle.graal.python.builtins.objects.set.PSet; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotVarargs.CallSlotTpNewNode; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyMemoryViewFromObject; +import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectSetAttrO; @@ -164,13 +171,18 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode; +import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.NumericSupport; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @@ -292,7 +304,7 @@ public void initInternals(VirtualFrame frame, Node inliningTarget, PyObjectLooku this.persFuncSelf = pair.getRight(); } - public void setInputStream(VirtualFrame frame, Node inliningTarget, PRaiseNode.Lazy raiseNode, PyObjectLookupAttr lookup, Object file) { + public void setInputStream(VirtualFrame frame, Node inliningTarget, PRaiseNode raiseNode, PyObjectLookupAttr lookup, Object file) { this.peek = lookup.execute(frame, inliningTarget, file, T_METHOD_PEEK); if (this.peek == PNone.NO_VALUE) { this.peek = null; @@ -304,7 +316,7 @@ public void setInputStream(VirtualFrame frame, Node inliningTarget, PRaiseNode.L this.read = lookup.execute(frame, inliningTarget, file, T_METHOD_READ); this.readline = lookup.execute(frame, inliningTarget, file, T_METHOD_READLINE); if (this.readline == PNone.NO_VALUE || this.read == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.FILE_MUST_HAVE_A_AND_B_ATTRS, T_METHOD_READ, T_METHOD_READLINE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.FILE_MUST_HAVE_A_AND_B_ATTRS, T_METHOD_READ, T_METHOD_READLINE); } } @@ -442,7 +454,7 @@ protected PythonBufferAccessLibrary getBufferAccessLibrary() { } public Object createMemoryViewFromBytes(VirtualFrame frame, byte[] bytes, int n) { - return ensureMemoryViewNode().execute(frame, factory().createByteArray(bytes, n)); + return ensureMemoryViewNode().execute(frame, PFactory.createByteArray(PythonLanguage.get(this), bytes, n)); } public Object createMemoryView(VirtualFrame frame, Object obj) { @@ -757,7 +769,7 @@ protected HashingStorage getClonedHashingStorage(VirtualFrame frame, Object obj) CompilerDirectives.transferToInterpreterAndInvalidate(); getHashingStorageNode = insert(HashingCollectionNodes.GetClonedHashingStorageNode.create()); } - return getHashingStorageNode.doNoValueCached(frame, obj); + return getHashingStorageNode.getForSetsCached(frame, obj); } private void setItem(VirtualFrame frame, Object object, Object key, Object value) { @@ -924,7 +936,7 @@ private void loadFloat(VirtualFrame frame, PUnpickler self) { // TODO: (cbasca) we skip an entire branch from _pickle.c:load_float // TODO: (cbasca) should we return a PFloat ? (same for load_int/long variants) - value = PickleUtils.asciiBytesToDouble(s, getRaiseNode(), PythonBuiltinClassType.OverflowError); + value = PickleUtils.asciiBytesToDouble(this, s, PythonBuiltinClassType.OverflowError); pDataPush(self, value); } @@ -946,7 +958,7 @@ private void loadCountedBinBytes(VirtualFrame frame, PUnpickler self, int nbytes byte[] buffer = new byte[size]; readInto(frame, self, buffer); - Object bytes = factory().createBytes(buffer); + Object bytes = PFactory.createBytes(PythonLanguage.get(this), buffer); pDataPush(self, bytes); } @@ -960,7 +972,7 @@ private void loadCountedByteArray(VirtualFrame frame, PUnpickler self) { byte[] buffer = new byte[size]; readInto(frame, self, buffer); - Object bytearray = factory().createByteArray(buffer); + Object bytearray = PFactory.createByteArray(PythonLanguage.get(this), buffer); pDataPush(self, bytearray); } @@ -969,8 +981,10 @@ private void loadNextBuffer(VirtualFrame frame, PUnpickler self) { throw raise(PythonBuiltinClassType.UnpicklingError, ErrorMessages.PICKLE_STREAM_NO_BUFFERS); } - Object buf = getNextItem(frame, self.buffers); - if (buf == null) { + Object buf; + try { + buf = getNextItem(frame, self.buffers); + } catch (IteratorExhausted e) { throw raise(PythonBuiltinClassType.UnpicklingError, ErrorMessages.NOT_ENOUGH_BUFFERS); } @@ -1008,7 +1022,7 @@ private void loadCountedBinString(VirtualFrame frame, PUnpickler self, int nbyte // Convert Python 2.x strings to bytes if the *encoding* given to the Unpickler was // 'bytes'. Otherwise, convert them to unicode. - final PBytes bytes = factory().createBytes(s.getBytes(size), size); + final PBytes bytes = PFactory.createBytes(PythonLanguage.get(this), s.getBytes(size), size); if (ensureTsEqualNode().execute(self.encoding, T_CODEC_BYTES, TS_ENCODING)) { obj = bytes; } else { @@ -1037,7 +1051,11 @@ private void loadString(VirtualFrame frame, PUnpickler self) { // Use the PyBytes API to decode the string, since that is what is used to encode, and // then coerce the result to Unicode. - bytes = escapeDecode(frame, factory(), s, pStart, len); + if (len == 0) { + bytes = PFactory.createEmptyBytes(PythonLanguage.get(this)); + } else { + bytes = escapeDecode(frame, PythonUtils.arrayCopyOfRange(s, pStart, pStart + len)); + } // Leave the Python 2.x strings as bytes if the *encoding* given to the Unpickler was // 'bytes'. Otherwise, convert them to unicode. @@ -1093,7 +1111,7 @@ private void loadTuple(PUnpickler self) { } private void loadEmptyList(PUnpickler self) { - pDataPush(self, factory().createList()); + pDataPush(self, PFactory.createList(PythonLanguage.get(this))); } private void loadList(PUnpickler self) { @@ -1103,7 +1121,7 @@ private void loadList(PUnpickler self) { } private void loadEmptyDict(PUnpickler self) { - pDataPush(self, factory().createDict()); + pDataPush(self, PFactory.createDict(PythonLanguage.get(this))); } private void loadDict(VirtualFrame frame, PUnpickler self) { @@ -1125,11 +1143,11 @@ private void loadDict(VirtualFrame frame, PUnpickler self) { } self.stack.clear(i); - pDataPush(self, factory().createDict(storage)); + pDataPush(self, PFactory.createDict(PythonLanguage.get(this), storage)); } private void loadEmptySet(PUnpickler self) { - pDataPush(self, factory().createSet()); + pDataPush(self, PFactory.createSet(PythonLanguage.get(this))); } private void loadAddItems(VirtualFrame frame, PUnpickler self) { @@ -1168,25 +1186,24 @@ private void loadAddItems(VirtualFrame frame, PUnpickler self) { private void loadFrozenSet(VirtualFrame frame, PUnpickler self) { int i = marker(self); Object items = pDataPopTuple(self, i); - Object frozenset = factory().createFrozenSet(getClonedHashingStorage(frame, items)); + Object frozenset = PFactory.createFrozenSet(PythonLanguage.get(this), getClonedHashingStorage(frame, items)); pDataPush(self, frozenset); } - private Object instantiate(VirtualFrame frame, Object cls, Object args) { + private Object instantiate(VirtualFrame frame, Node inliningTarget, Object cls, Object args, PyObjectCallMethodObjArgs callMethod) { // Caller must assure args are a tuple. Normally, args come from Pdata_poptuple which // packs objects from the top of the stack into a newly created tuple. assert args instanceof PTuple; if (length(frame, args) == 0 && PGuards.isPythonClass(cls)) { Object func = getLookupAttrNode().executeCached(frame, cls, T___GETINITARGS__); if (func == PNone.NO_VALUE) { - final Object newMethod = lookupAttributeStrict(frame, cls, T___NEW__); - return callNew(frame, newMethod, cls); + return callMethod.execute(frame, inliningTarget, cls, T___NEW__, cls); } } return callStarArgs(frame, cls, args); } - private void loadObj(VirtualFrame frame, PUnpickler self) { + private void loadObj(VirtualFrame frame, Node inliningTarget, PUnpickler self, PyObjectCallMethodObjArgs callMethod) { Object cls, args, obj = null; int i = marker(self); @@ -1197,14 +1214,14 @@ private void loadObj(VirtualFrame frame, PUnpickler self) { args = pDataPopTuple(self, i + 1); cls = pDataPop(self); if (cls != null) { - obj = instantiate(frame, cls, args); + obj = instantiate(frame, inliningTarget, cls, args, callMethod); } assert obj != null; pDataPush(self, obj); } - private void loadInst(VirtualFrame frame, PythonContext ctx, PUnpickler self) { + private void loadInst(VirtualFrame frame, Node inliningTarget, PythonContext ctx, PUnpickler self, PyObjectCallMethodObjArgs callMethod) { Object cls = null; Object obj = null; int i = marker(self); @@ -1230,14 +1247,14 @@ private void loadInst(VirtualFrame frame, PythonContext ctx, PUnpickler self) { assert cls != null; Object args = pDataPopTuple(self, i); if (args != null) { - obj = instantiate(frame, cls, args); + obj = instantiate(frame, inliningTarget, cls, args, callMethod); } assert obj != null; pDataPush(self, obj); } - private void loadNewObj(VirtualFrame frame, PUnpickler self) { + private void loadNewObj(VirtualFrame frame, Node inliningTarget, PUnpickler self, GetCachedTpSlotsNode getSlots, CallSlotTpNewNode callNew, ExecutePositionalStarargsNode expandArgs) { // Stack is ... cls argtuple, and we want to call cls.__new__(cls, *argtuple). Object args = pDataPop(self); if (!(args instanceof PTuple)) { @@ -1249,24 +1266,25 @@ private void loadNewObj(VirtualFrame frame, PUnpickler self) { throw raise(PythonBuiltinClassType.UnpicklingError, ErrorMessages.S_CLASS_ARG_S, "NEWOBJ", "isn't a type object"); } // Call __new__ - final Object tpNew = getLookupAttrNode().executeCached(frame, cls, T___NEW__); - if (tpNew == PNone.NO_VALUE) { + TpSlot newSlot = getSlots.execute(inliningTarget, cls).tp_new(); + if (newSlot == null) { throw raise(PythonBuiltinClassType.UnpicklingError, ErrorMessages.S_CLASS_ARG_S, "NEWOBJ", "has NULL tp_new"); } - Object obj = callNew(frame, tpNew, cls, args); + Object obj = callNew.execute(frame, inliningTarget, newSlot, cls, expandArgs.executeWith(frame, args), PKeyword.EMPTY_KEYWORDS); pDataPush(self, obj); } - private void loadNewObjEx(VirtualFrame frame, PUnpickler self) { + private void loadNewObjEx(VirtualFrame frame, Node inliningTarget, PUnpickler self, GetCachedTpSlotsNode getSlots, CallSlotTpNewNode callNew, ExecutePositionalStarargsNode expandArgs, + ExpandKeywordStarargsNode expandKwargs) { Object kwargs = pDataPop(self); Object args = pDataPop(self); Object cls = pDataPop(self); if (!PGuards.isPythonClass(cls)) { throw raise(PythonBuiltinClassType.UnpicklingError, ErrorMessages.S_CLASS_ARG_MUST_BE_TYPE_NOT_P, "NEWOBJ_EX", cls); } - final Object tpNew = getLookupAttrNode().executeCached(frame, cls, T___NEW__); - if (tpNew == PNone.NO_VALUE) { + TpSlot newSlot = getSlots.execute(inliningTarget, cls).tp_new(); + if (newSlot == null) { throw raise(PythonBuiltinClassType.UnpicklingError, ErrorMessages.S_CLASS_ARG_DOES_NOT_HAVE_S, "NEWOBJ_EX", T___NEW__); } if (!(args instanceof PTuple)) { @@ -1276,7 +1294,7 @@ private void loadNewObjEx(VirtualFrame frame, PUnpickler self) { throw raise(PythonBuiltinClassType.UnpicklingError, ErrorMessages.S_ARG_MUST_BE_S_NOT_P, "NEWOBJ_EX kwargs", "dict", kwargs); } - Object obj = callNew(frame, tpNew, cls, args, kwargs); + Object obj = callNew.execute(frame, inliningTarget, newSlot, cls, expandArgs.executeWith(frame, args), expandKwargs.execute(frame, inliningTarget, kwargs)); pDataPush(self, obj); } @@ -1768,7 +1786,13 @@ private void loadBool(PUnpickler self, boolean bool) { } @Specialization - public Object load(VirtualFrame frame, PUnpickler self) { + public Object load(VirtualFrame frame, PUnpickler self, + @Bind Node inliningTarget, + @Cached GetCachedTpSlotsNode getSlots, + @Cached CallSlotTpNewNode callNew, + @Cached ExecutePositionalStarargsNode expandArgs, + @Cached ExpandKeywordStarargsNode expandKwargs, + @Cached PyObjectCallMethodObjArgs callMethod) { byte s; self.numMarks = 0; @@ -1894,16 +1918,16 @@ public Object load(VirtualFrame frame, PUnpickler self) { loadFrozenSet(frame, self); continue; case OPCODE_OBJ: - loadObj(frame, self); + loadObj(frame, inliningTarget, self, callMethod); continue; case OPCODE_INST: - loadInst(frame, ctx, self); + loadInst(frame, inliningTarget, ctx, self, callMethod); continue; case OPCODE_NEWOBJ: - loadNewObj(frame, self); + loadNewObj(frame, inliningTarget, self, getSlots, callNew, expandArgs); continue; case OPCODE_NEWOBJ_EX: - loadNewObjEx(frame, self); + loadNewObjEx(frame, inliningTarget, self, getSlots, callNew, expandArgs, expandKwargs); continue; case OPCODE_GLOBAL: loadGlobal(frame, ctx, self); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleBufferBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleBufferBuiltins.java index 6f588766b2..1ccee0181d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleBufferBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleBufferBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,20 +44,29 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.buffer.BufferFlags; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; +import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.memoryview.MemoryViewNodes; import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.lib.PyMemoryViewFromObject; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.IndirectCallData; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.BufferFormat; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -70,11 +79,28 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PickleBuffer) public class PickleBufferBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = PickleBufferBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return PickleBufferBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "PickleBuffer", minNumOfPositionalArgs = 2, parameterNames = {"$cls", "object"}) + @GenerateNodeFactory + abstract static class ConstructPickleBufferNode extends PythonBinaryBuiltinNode { + @Specialization(limit = "3") + static PPickleBuffer construct(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object object, + @Bind PythonLanguage language, + @Cached("createFor(this)") IndirectCallData indirectCallData, + @CachedLibrary("object") PythonBufferAcquireLibrary acquireLib) { + Object buffer = acquireLib.acquire(object, BufferFlags.PyBUF_FULL_RO, frame, indirectCallData); + return PFactory.createPickleBuffer(language, buffer); + } + } + // functions @Builtin(name = "raw", minNumOfPositionalArgs = 1, parameterNames = {"$self"}) @GenerateNodeFactory @@ -84,21 +110,21 @@ Object raw(VirtualFrame frame, PPickleBuffer self, @Bind("this") Node inliningTarget, @Cached PyMemoryViewFromObject memoryViewFromObject, @Cached MemoryViewNodes.ReleaseNode releaseNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { final Object view = self.getView(); if (view == null) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.OP_FORBIDDEN_ON_OBJECT, "PickleBuffer"); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.OP_FORBIDDEN_ON_OBJECT, "PickleBuffer"); } PMemoryView mv = memoryViewFromObject.execute(frame, self); // Make it into raw (1-dimensional bytes) memoryview try { if (!mv.isAnyContiguous()) { - throw raiseNode.get(inliningTarget).raise(BufferError, ErrorMessages.CANNOT_EXTRACT_RAW_BUFFER_FROM_NON_CONTIGUOUS); + throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.CANNOT_EXTRACT_RAW_BUFFER_FROM_NON_CONTIGUOUS); } int[] shape = new int[]{mv.getLength()}; int[] strides = new int[]{1}; - return factory.createMemoryView(getContext(), mv.getLifecycleManager(), mv.getBuffer(), mv.getOwner(), mv.getLength(), + return PFactory.createMemoryView(language, getContext(), mv.getLifecycleManager(), mv.getBuffer(), mv.getOwner(), mv.getLength(), mv.isReadOnly(), 1, BufferFormat.UINT_8, BufferFormat.T_UINT_8_TYPE_CODE, 1, mv.getBufferPointer(), mv.getOffset(), shape, strides, null, PMemoryView.FLAG_C | PMemoryView.FLAG_FORTRAN); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleModuleBuiltins.java index 891068b1dc..e242948c39 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,6 +44,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -51,22 +52,17 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.buffer.BufferFlags; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; -import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.runtime.IndirectCallData; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -93,62 +89,8 @@ public void postInitialize(Python3Core core) { HiddenAttr.WriteNode.executeUncached(core.lookupType(PythonBuiltinClassType.Pickler), HiddenAttr.PICKLE_STATE, state); } - // types - @Builtin(name = "PickleBuffer", minNumOfPositionalArgs = 2, parameterNames = {"$cls", "object"}, constructsClass = PythonBuiltinClassType.PickleBuffer) - @GenerateNodeFactory - abstract static class ConstructPickleBufferNode extends PythonBinaryBuiltinNode { - @Specialization(limit = "3") - static PPickleBuffer construct(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object object, - @Cached("createFor(this)") IndirectCallData indirectCallData, - @CachedLibrary("object") PythonBufferAcquireLibrary acquireLib, - @Cached PythonObjectFactory factory) { - Object buffer = acquireLib.acquire(object, BufferFlags.PyBUF_FULL_RO, frame, indirectCallData); - return factory.createPickleBuffer(buffer); - } - } - - @Builtin(name = "Pickler", minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.Pickler, takesVarArgs = true, takesVarKeywordArgs = true, declaresExplicitSelf = true) - @GenerateNodeFactory - abstract static class ConstructPicklerNode extends PythonVarargsBuiltinNode { - @Specialization - PPickler construct(Object cls, @SuppressWarnings("unused") Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords, - @Cached PythonObjectFactory factory) { - return factory.createPickler(cls); - } - } - - @Builtin(name = "PicklerMemoProxy", minNumOfPositionalArgs = 2, parameterNames = {"$cls", "pickler"}, constructsClass = PythonBuiltinClassType.PicklerMemoProxy) - @GenerateNodeFactory - abstract static class ConstructPicklerMemoProxyNode extends PythonBinaryBuiltinNode { - @Specialization - PPicklerMemoProxy construct(Object cls, PPickler pickler, - @Cached PythonObjectFactory factory) { - return factory.createPicklerMemoProxy(pickler, cls); - } - } - - @Builtin(name = "UnpicklerMemoProxy", minNumOfPositionalArgs = 2, parameterNames = {"$cls", "unpickler"}, constructsClass = PythonBuiltinClassType.UnpicklerMemoProxy) - @GenerateNodeFactory - abstract static class ConstructUnpicklerMemoProxyNode extends PythonBinaryBuiltinNode { - @Specialization - PUnpicklerMemoProxy construct(Object cls, PUnpickler unpickler, - @Cached PythonObjectFactory factory) { - return factory.createUnpicklerMemoProxy(unpickler, cls); - } - } - - @Builtin(name = "Unpickler", minNumOfPositionalArgs = 1, constructsClass = PythonBuiltinClassType.Unpickler, takesVarArgs = true, takesVarKeywordArgs = true, declaresExplicitSelf = true) - @GenerateNodeFactory - abstract static class ConstructUnpicklerNode extends PythonVarargsBuiltinNode { - @Specialization - PUnpickler construct(Object cls, @SuppressWarnings("unused") Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords, - @Cached PythonObjectFactory factory) { - return factory.createUnpickler(cls); - } - } - // methods - @Builtin(name = "dump", minNumOfPositionalArgs = 3, declaresExplicitSelf = true, varArgsMarker = true, // + @Builtin(name = "dump", minNumOfPositionalArgs = 3, declaresExplicitSelf = true, // parameterNames = {"$self", "obj", "file", "protocol"}, // keywordOnlyNames = {"fix_imports", "buffer_callback"}) @ArgumentClinic(name = "protocol", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = J_DEFAULT_PICKLE_PROTOCOL, useDefaultForNone = true) @@ -163,12 +105,12 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static Object dump(VirtualFrame frame, @SuppressWarnings("unused") PythonModule self, Object obj, Object file, int protocol, boolean fixImports, Object bufferCallback, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached PPickler.DumpNode dumpNode, @Cached PPickler.FlushToFileNode flushToFileNode, @Cached PyObjectLookupAttr lookup, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - PPickler pickler = factory.createPickler(); + @Cached PRaiseNode raiseNode) { + PPickler pickler = PFactory.createPickler(language); pickler.setProtocol(inliningTarget, raiseNode, protocol, fixImports); pickler.setOutputStream(frame, inliningTarget, raiseNode, lookup, file); pickler.setBufferCallback(inliningTarget, raiseNode, bufferCallback); @@ -178,7 +120,7 @@ static Object dump(VirtualFrame frame, @SuppressWarnings("unused") PythonModule } } - @Builtin(name = "dumps", minNumOfPositionalArgs = 2, declaresExplicitSelf = true, varArgsMarker = true, // + @Builtin(name = "dumps", minNumOfPositionalArgs = 2, declaresExplicitSelf = true, // parameterNames = {"$self", "obj", "protocol"}, // keywordOnlyNames = {"fix_imports", "buffer_callback"}) @ArgumentClinic(name = "protocol", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = J_DEFAULT_PICKLE_PROTOCOL, useDefaultForNone = true) @@ -193,18 +135,18 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static Object dump(VirtualFrame frame, @SuppressWarnings("unused") PythonModule self, Object obj, int protocol, boolean fixImports, Object bufferCallback, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached PPickler.DumpNode dumpNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - PPickler pickler = factory.createPickler(); + @Cached PRaiseNode raiseNode) { + PPickler pickler = PFactory.createPickler(language); pickler.setProtocol(inliningTarget, raiseNode, protocol, fixImports); pickler.setBufferCallback(inliningTarget, raiseNode, bufferCallback); dumpNode.execute(frame, pickler, obj); - return pickler.getString(factory); + return pickler.getString(language); } } - @Builtin(name = "load", minNumOfPositionalArgs = 2, declaresExplicitSelf = true, parameterNames = {"$self", "file"}, varArgsMarker = true, keywordOnlyNames = {"fix_imports", "encoding", "errors", + @Builtin(name = "load", minNumOfPositionalArgs = 2, declaresExplicitSelf = true, parameterNames = {"$self", "file"}, keywordOnlyNames = {"fix_imports", "encoding", "errors", "buffers"}) @ArgumentClinic(name = "fix_imports", conversion = ArgumentClinic.ClinicConversion.Boolean, defaultValue = "true") @ArgumentClinic(name = "encoding", conversion = ArgumentClinic.ClinicConversion.TString, defaultValue = "T_ASCII_UPPERCASE") @@ -220,12 +162,12 @@ protected ArgumentClinicProvider getArgumentClinic() { static Object load(VirtualFrame frame, @SuppressWarnings("unused") PythonModule self, Object file, @SuppressWarnings("unused") boolean fixImports, TruffleString encoding, TruffleString errors, Object buffers, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached PUnpickler.LoadNode loadNode, @Cached PyObjectLookupAttr lookup, @Cached PyObjectGetIter getIter, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - PUnpickler unpickler = factory.createUnpickler(); + @Cached PRaiseNode raiseNode) { + PUnpickler unpickler = PFactory.createUnpickler(language); unpickler.setInputStream(frame, inliningTarget, raiseNode, lookup, file); unpickler.setInputEncoding(encoding, errors); unpickler.setBuffers(frame, inliningTarget, getIter, buffers); @@ -233,7 +175,7 @@ static Object load(VirtualFrame frame, @SuppressWarnings("unused") PythonModule } } - @Builtin(name = "loads", minNumOfPositionalArgs = 2, declaresExplicitSelf = true, varArgsMarker = true, // + @Builtin(name = "loads", minNumOfPositionalArgs = 2, declaresExplicitSelf = true, // parameterNames = {"$self", "data"}, // keywordOnlyNames = {"fix_imports", "encoding", "errors", "buffers"}) @ArgumentClinic(name = "data", conversion = ArgumentClinic.ClinicConversion.ReadableBuffer) @@ -251,12 +193,12 @@ protected ArgumentClinicProvider getArgumentClinic() { static Object loads(VirtualFrame frame, @SuppressWarnings("unused") PythonModule self, Object buffer, boolean fixImports, TruffleString encoding, TruffleString errors, Object buffers, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached("createFor(this)") IndirectCallData indirectCallData, @Cached PUnpickler.LoadNode loadNode, - @Cached PyObjectGetIter getIter, - @Cached PythonObjectFactory factory) { + @Cached PyObjectGetIter getIter) { try { - PUnpickler unpickler = factory.createUnpickler(); + PUnpickler unpickler = PFactory.createUnpickler(language); byte[] data = bufferLib.getCopiedByteArray(buffer); unpickler.setStringInput(data, data.length); unpickler.setInputEncoding(encoding, errors); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleState.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleState.java index 5f8e057b40..9d72cf64e9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleState.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -99,7 +99,7 @@ public abstract static class PickleStateInitNode extends Node { @Specialization void init(PickleState state, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached PyObjectGetAttr getAttr, @Cached PyCallableCheckNode callableCheck) { PythonContext context = PythonContext.get(this); @@ -111,28 +111,28 @@ void init(PickleState state, if (dispatchTable instanceof PDict dispatchTableDict) { state.dispatchTable = dispatchTableDict; } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, "copyreg.dispatch_table", "dict", dispatchTable); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, "copyreg.dispatch_table", "dict", dispatchTable); } var extensionRegistry = getAttr.execute(null, inliningTarget, copyreg, PickleUtils.T_ATTR_EXT_REGISTRY); if (extensionRegistry instanceof PDict extensionRegistryDict) { state.extensionRegistry = extensionRegistryDict; } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, "copyreg._extension_registry", "dict", extensionRegistry); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, "copyreg._extension_registry", "dict", extensionRegistry); } var invertedRegistry = getAttr.execute(null, inliningTarget, copyreg, PickleUtils.T_ATTR_INV_REGISTRY); if (invertedRegistry instanceof PDict invertedRegistryDict) { state.invertedRegistry = invertedRegistryDict; } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, "copyreg._inverted_registry", "dict", invertedRegistry); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, "copyreg._inverted_registry", "dict", invertedRegistry); } var extensionCache = getAttr.execute(null, inliningTarget, copyreg, PickleUtils.T_ATTR_EXT_CACHE); if (extensionCache instanceof PDict extensionCacheDict) { state.extensionCache = extensionCacheDict; } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, "copyreg._extension_cache", "dict", extensionCache); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, "copyreg._extension_cache", "dict", extensionCache); } final Object codecs = importModule(PickleUtils.T_MOD_CODECS); @@ -140,7 +140,7 @@ void init(PickleState state, if (callableCheck.execute(inliningTarget, codecsEncode)) { state.codecsEncode = codecsEncode; } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, "codecs.encode", "callable", codecsEncode); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, "codecs.encode", "callable", codecsEncode); } final Object functools = importModule(PickleUtils.T_MOD_FUNCTOOLS); @@ -152,14 +152,14 @@ void init(PickleState state, if (nameMapping2To3 instanceof PDict nameMapping2To3Dict) { state.nameMapping2To3 = nameMapping2To3Dict; } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, PickleUtils.T_CP_NAME_MAPPING, "dict", nameMapping2To3); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, PickleUtils.T_CP_NAME_MAPPING, "dict", nameMapping2To3); } var importMapping2To3 = getAttr.execute(null, inliningTarget, compatPickle, PickleUtils.T_ATTR_IMPORT_MAPPING); if (importMapping2To3 instanceof PDict importMapping2To3Dict) { state.importMapping2To3 = importMapping2To3Dict; } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, PickleUtils.T_CP_IMPORT_MAPPING, "dict", importMapping2To3); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, PickleUtils.T_CP_IMPORT_MAPPING, "dict", importMapping2To3); } // ... and the 3.x -> 2.x mapping tables @@ -167,13 +167,13 @@ void init(PickleState state, if (nameMapping3To2 instanceof PDict nameMapping3To2Dict) { state.nameMapping3To2 = nameMapping3To2Dict; } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, PickleUtils.T_CP_REVERSE_NAME_MAPPING, "dict", nameMapping3To2); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, PickleUtils.T_CP_REVERSE_NAME_MAPPING, "dict", nameMapping3To2); } var importMapping3To2 = getAttr.execute(null, inliningTarget, compatPickle, PickleUtils.T_ATTR_REVERSE_IMPORT_MAPPING); if (importMapping3To2 instanceof PDict importMapping3To2Dict) { state.importMapping3To2 = importMapping3To2Dict; } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, PickleUtils.T_CP_REVERSE_IMPORT_MAPPING, "dict", + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.S_SHOULD_BE_A_S_NOT_A_P, PickleUtils.T_CP_REVERSE_IMPORT_MAPPING, "dict", importMapping3To2); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleUtils.java index 6fcdb97251..ba48abdb2c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -50,6 +50,7 @@ import org.graalvm.collections.Pair; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.bytes.ByteArrayBuffer; @@ -60,7 +61,7 @@ import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.StringLiterals; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.frame.VirtualFrame; @@ -286,11 +287,11 @@ public static double asciiBytesToDouble(byte[] bytes) { } @TruffleBoundary - public static double asciiBytesToDouble(byte[] bytes, PRaiseNode raiseNode, PythonBuiltinClassType errorType) { + public static double asciiBytesToDouble(Node node, byte[] bytes, PythonBuiltinClassType errorType) { try { return asciiBytesToDouble(bytes); } catch (NumberFormatException nfe) { - throw raiseNode.raise(errorType); + throw PRaiseNode.raiseStatic(node, errorType); } } @@ -373,9 +374,9 @@ public static Pair initMethodRef(VirtualFrame frame, Node inlini } } - public static Object reconstructMethod(PythonObjectFactory factory, Object func, Object self) { + public static Object reconstructMethod(PythonLanguage language, Object func, Object self) { if (self != null) { - return factory.createMethod(self, func); + return PFactory.createMethod(language, self, func); } return func; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java index 5d1039854d..da974d38cc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -50,12 +50,15 @@ import static com.oracle.graal.python.builtins.modules.pickle.PickleUtils.J_METHOD_PERSISTENT_ID; import static com.oracle.graal.python.builtins.modules.pickle.PickleUtils.T_ATTR_DISPATCH_TABLE; import static com.oracle.graal.python.builtins.modules.pickle.PickleUtils.T_METHOD_PERSISTENT_ID; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SIZEOF__; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -69,7 +72,10 @@ import com.oracle.graal.python.builtins.objects.common.SequenceNodes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.dict.PDict; +import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyCallableCheckNode; import com.oracle.graal.python.lib.PyLongAsLongNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; @@ -83,8 +89,9 @@ import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -98,12 +105,28 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.Pickler) public class PicklerBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = PicklerBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return PicklerBuiltinsFactory.getFactories(); } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 2, declaresExplicitSelf = true, parameterNames = {"$self", "file", "protocol", "fix_imports", "buffer_callback"}) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "Pickler", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + abstract static class ConstructPicklerNode extends PythonVarargsBuiltinNode { + @Specialization + PPickler construct(Object cls, @SuppressWarnings("unused") Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + return PFactory.createPickler(language, cls, getInstanceShape.execute(cls)); + } + } + + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "Pickler", minNumOfPositionalArgs = 2, parameterNames = {"$self", "file", "protocol", "fix_imports", "buffer_callback"}) @ArgumentClinic(name = "protocol", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = J_DEFAULT_PICKLE_PROTOCOL, useDefaultForNone = true) @ArgumentClinic(name = "fix_imports", conversion = ArgumentClinic.ClinicConversion.Boolean, defaultValue = "true") @GenerateNodeFactory @@ -117,7 +140,7 @@ protected ArgumentClinicProvider getArgumentClinic() { static Object init(VirtualFrame frame, PPickler self, Object file, int protocol, boolean fixImports, Object bufferCallback, @Bind("this") Node inliningTarget, @Cached PyObjectLookupAttr lookup, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { self.setProtocol(inliningTarget, raiseNode, protocol, fixImports); self.setOutputStream(frame, inliningTarget, raiseNode, lookup, file); self.setBufferCallback(inliningTarget, raiseNode, bufferCallback); @@ -136,9 +159,9 @@ static Object dump(VirtualFrame frame, PPickler self, Object obj, @Bind("this") Node inliningTarget, @Cached PPickler.FlushToFileNode flushToFileNode, @Cached PPickler.DumpNode dumpNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (self.getWrite() == null) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.PicklingError, ErrorMessages.INIT_CALLED_WITH, "Pickler", self); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.PicklingError, ErrorMessages.INIT_CALLED_WITH, "Pickler", self); } self.clearBuffer(); dumpNode.execute(frame, self, obj); @@ -174,10 +197,10 @@ public abstract static class PicklerDispatchTableNode extends PythonBuiltinNode @Specialization(guards = "isNoValue(none)") static Object get(PPickler self, @SuppressWarnings("unused") PNone none, @Bind("this") Node inliningTarget, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { final Object dispatchTable = self.getDispatchTable(); if (dispatchTable == null) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.AttributeError, T_ATTR_DISPATCH_TABLE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, T_ATTR_DISPATCH_TABLE); } return dispatchTable; } @@ -185,10 +208,10 @@ static Object get(PPickler self, @SuppressWarnings("unused") PNone none, @Specialization(guards = "isDeleteMarker(marker)") static Object delete(PPickler self, @SuppressWarnings("unused") Object marker, @Bind("this") Node inliningTarget, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { final Object dispatchTable = self.getDispatchTable(); if (dispatchTable == null) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.AttributeError, T_ATTR_DISPATCH_TABLE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, T_ATTR_DISPATCH_TABLE); } self.setDispatchTable(null); return PNone.NONE; @@ -244,8 +267,8 @@ Object set(VirtualFrame frame, PPickler self, Object value, public abstract static class PicklerMemoNode extends PythonBuiltinNode { @Specialization(guards = "isNoValue(none)") static Object get(PPickler self, @SuppressWarnings("unused") PNone none, - @Cached PythonObjectFactory factory) { - return factory.createPicklerMemoProxy(self); + @Bind PythonLanguage language) { + return PFactory.createPicklerMemoProxy(language, self); } @Specialization(guards = {"!isNoValue(obj)", "!isDeleteMarker(obj)"}) @@ -258,7 +281,7 @@ static Object set(VirtualFrame frame, PPickler self, Object obj, @Cached HashingStorageGetIterator getIter, @Cached HashingStorageIteratorNext iterNext, @Cached HashingStorageIteratorValue iterValue, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { MemoTable newMemo; if (obj instanceof PPicklerMemoProxy) { final PPickler pickler = ((PPicklerMemoProxy) obj).getPickler(); @@ -270,7 +293,7 @@ static Object set(VirtualFrame frame, PPickler self, Object obj, while (iterNext.execute(inliningTarget, dictStorage, it)) { Object value = iterValue.execute(inliningTarget, dictStorage, it); if (!(value instanceof PTuple) || sizeNode.execute(frame, inliningTarget, value) != 2) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.VALUES_MUST_BE_2TUPLES, "memo"); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.VALUES_MUST_BE_2TUPLES, "memo"); } SequenceStorage tupleStorage = getSequenceStorageNode.execute(inliningTarget, value); int memoId = asSizeNode.executeExact(frame, inliningTarget, getItemNode.execute(frame, tupleStorage, 0)); @@ -278,7 +301,7 @@ static Object set(VirtualFrame frame, PPickler self, Object obj, newMemo.set(memoObj, memoId); } } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_MUST_BE_A_OR_B_NOT_C, "memo", "PicklerMemoProxy", "dict", obj); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_MUST_BE_A_OR_B_NOT_C, "memo", "PicklerMemoProxy", "dict", obj); } self.setMemo(newMemo); return PNone.NONE; @@ -291,25 +314,25 @@ public abstract static class PicklerPersistentIdNode extends PythonBuiltinNode { @Specialization(guards = "isNoValue(none)") static Object get(PPickler self, @SuppressWarnings("unused") PNone none, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Exclusive @Cached PRaiseNode raiseNode) { final Object persFunc = self.getPersFunc(); if (persFunc == null) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.AttributeError, T_METHOD_PERSISTENT_ID); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, T_METHOD_PERSISTENT_ID); } - return PickleUtils.reconstructMethod(factory, persFunc, self.getPersFuncSelf()); + return PickleUtils.reconstructMethod(language, persFunc, self.getPersFuncSelf()); } @Specialization(guards = {"!isNoValue(obj)", "!isDeleteMarker(obj)"}) static Object set(PPickler self, Object obj, @Bind("this") Node inliningTarget, @Cached PyCallableCheckNode callableCheck, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (PGuards.isDeleteMarker(obj)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATRIBUTE_DELETION_NOT_SUPPORTED); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATRIBUTE_DELETION_NOT_SUPPORTED); } if (!callableCheck.execute(inliningTarget, obj)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_MUST_BE_A_CALLABLE, T_METHOD_PERSISTENT_ID, "one argument"); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_MUST_BE_A_CALLABLE, T_METHOD_PERSISTENT_ID, "one argument"); } self.setPersFuncSelf(null); self.setPersFunc(obj); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerMemoProxyBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerMemoProxyBuiltins.java index 98b6472d35..8a898b3f55 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerMemoProxyBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerMemoProxyBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,6 +45,10 @@ import java.util.LinkedHashMap; import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -53,11 +57,14 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; @@ -65,11 +72,26 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PicklerMemoProxy) public class PicklerMemoProxyBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = PicklerMemoProxyBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return PicklerMemoProxyBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "PicklerMemoProxy", minNumOfPositionalArgs = 2, parameterNames = {"$cls", "pickler"}) + @GenerateNodeFactory + abstract static class ConstructPicklerMemoProxyNode extends PythonBinaryBuiltinNode { + @Specialization + PPicklerMemoProxy construct(Object cls, PPickler pickler, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + return PFactory.createPicklerMemoProxy(language, pickler, cls, getInstanceShape.execute(cls)); + } + } + @Builtin(name = "clear", minNumOfPositionalArgs = 1, parameterNames = {"$self"}) @GenerateNodeFactory public abstract static class PicklerMemoProxyClearNode extends PythonUnaryBuiltinNode { @@ -82,16 +104,16 @@ Object clear(PPicklerMemoProxy self) { } @TruffleBoundary - public static PDict picklerMemoCopyImpl(PythonContext context, MemoTable memoTable) { - PythonObjectFactory factory = context.factory(); + public static PDict picklerMemoCopyImpl(MemoTable memoTable) { + PythonLanguage language = PythonLanguage.get(null); LinkedHashMap copy = new LinkedHashMap<>(); MemoIterator iterator = memoTable.iterator(); while (iterator.advance()) { copy.put(System.identityHashCode(iterator.key()), - factory.createTuple(new Object[]{iterator.value(), iterator.key()})); + PFactory.createTuple(language, new Object[]{iterator.value(), iterator.key()})); } - return factory.createDictFromMapGeneric(copy); + return PFactory.createDictFromMapGeneric(language, copy); } @Builtin(name = "copy", minNumOfPositionalArgs = 1, parameterNames = {"$self"}) @@ -100,7 +122,7 @@ public abstract static class PicklerMemoProxyCopyNode extends PythonUnaryBuiltin @Specialization Object copy(PPicklerMemoProxy self) { final MemoTable memoTable = self.getPickler().getMemo(); - return picklerMemoCopyImpl(getContext(), memoTable); + return picklerMemoCopyImpl(memoTable); } } @@ -108,12 +130,12 @@ Object copy(PPicklerMemoProxy self) { @GenerateNodeFactory public abstract static class PicklerMemoProxyReduceNode extends PythonUnaryBuiltinNode { @Specialization - Object reduce(PPicklerMemoProxy self, - @Cached PythonObjectFactory factory) { + static Object reduce(PPicklerMemoProxy self, + @Bind PythonLanguage language) { final MemoTable memoTable = self.getPickler().getMemo(); - final PDict dictMemoCopy = picklerMemoCopyImpl(getContext(), memoTable); - final PTuple dictArgs = factory.createTuple(new Object[]{dictMemoCopy}); - return factory.createTuple(new Object[]{PythonBuiltinClassType.PDict, dictArgs}); + final PDict dictMemoCopy = picklerMemoCopyImpl(memoTable); + final PTuple dictArgs = PFactory.createTuple(language, new Object[]{dictMemoCopy}); + return PFactory.createTuple(language, new Object[]{PythonBuiltinClassType.PDict, dictArgs}); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerNodes.java index 6d2c6b00a5..cb5d060406 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerNodes.java @@ -57,10 +57,9 @@ import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; -import com.oracle.graal.python.lib.PyLongFromUnicodeObject; -import com.oracle.graal.python.lib.PyObjectSetItem; import org.graalvm.collections.Pair; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.modules.CodecsModuleBuiltins; @@ -83,10 +82,12 @@ import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.lib.PyIterCheckNode; import com.oracle.graal.python.lib.PyIterNextNode; +import com.oracle.graal.python.lib.PyLongFromUnicodeObject; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode; +import com.oracle.graal.python.lib.PyObjectSetItem; import com.oracle.graal.python.lib.PyObjectSizeNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.HiddenAttr; @@ -95,7 +96,7 @@ import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode; import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNodeGen; import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode; -import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode; +import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.InlineIsBuiltinClassProfile; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; @@ -103,13 +104,13 @@ import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; -import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.strings.TruffleString; public final class PicklerNodes { @@ -126,7 +127,6 @@ abstract static class BasePickleNode extends Node { @SuppressWarnings("FieldMayBeFinal") @Child private PyIterNextNode getNextNode = PyIterNextNode.create(); @Child CastToTruffleStringNode toStringNode = CastToTruffleStringNode.create(); - @Child private PythonObjectFactory objectFactory; @Child private HiddenAttr.ReadNode readHiddenAttributeNode; @Child private IsBuiltinObjectProfile errProfile; @Child private InlineIsBuiltinClassProfile isBuiltinClassProfile; @@ -137,7 +137,7 @@ abstract static class BasePickleNode extends Node { @Child private PyNumberAsSizeNode asSizeNode; @Child private CastToTruffleStringNode castToTruffleStringNode; @Child private SequenceNodes.GetSequenceStorageNode getSequenceStorageNode; - @Child private CallVarargsMethodNode callVarargsMethodNode; + @Child private CallNode callNode; @Child private ExecutePositionalStarargsNode getArgsNode; @Child private ExpandKeywordStarargsNode getKwArgsNode; @Child private PyLongFromUnicodeObject pyLongFromUnicodeObject; @@ -164,30 +164,21 @@ abstract static class BasePickleNode extends Node { @Child private HashingStorageIteratorNext hashingStorageItNext; @Child private HashingStorageIteratorKey hashingStorageItKey; @Child private HashingStorageIteratorValue hashingStorageItValue; - @Child private PRaiseNode raiseNode; - - protected final PRaiseNode getRaiseNode() { - if (raiseNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - if (isAdoptable()) { - raiseNode = insert(PRaiseNode.create()); - } else { - raiseNode = PRaiseNode.getUncached(); - } - } - return raiseNode; - } + private final BranchProfile errorProfile = BranchProfile.create(); protected PException raise(PythonBuiltinClassType type, TruffleString string) { - return getRaiseNode().raise(type, string); + errorProfile.enter(); + return PRaiseNode.raiseStatic(this, type, string); } protected PException raise(PythonBuiltinClassType exceptionType) { - return getRaiseNode().raise(exceptionType); + errorProfile.enter(); + return PRaiseNode.raiseStatic(this, exceptionType); } protected final PException raise(PythonBuiltinClassType type, TruffleString format, Object... arguments) { - return getRaiseNode().raise(type, format, arguments); + errorProfile.enter(); + return PRaiseNode.raiseStatic(this, type, format, arguments); } protected TruffleString.FromByteArrayNode ensureTsFromByteArray() { @@ -318,14 +309,6 @@ protected HashingStorageIteratorValue ensureHashingStorageIteratorValue() { return hashingStorageItValue; } - protected final PythonObjectFactory factory() { - if (objectFactory == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - objectFactory = insert(PythonObjectFactory.create()); - } - return objectFactory; - } - protected int length(VirtualFrame frame, Object object) { if (sizeNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -367,15 +350,15 @@ protected CodecsModuleBuiltins.CodecsEscapeDecodeNode ensureEscapeDecodeNode() { } protected Object unicodeRawDecodeEscape(VirtualFrame frame, byte[] bytes, int len) { - return decode(frame, factory().createBytes(bytes, 0, len), T_CODEC_RAW_UNICODE_ESCAPE); + return decode(frame, PFactory.createBytes(PythonLanguage.get(this), bytes, len), T_CODEC_RAW_UNICODE_ESCAPE); } protected Object decodeASCII(VirtualFrame frame, byte[] bytes, int len, TruffleString errors) { - return decode(frame, factory().createBytes(bytes, 0, len), T_CODEC_ASCII, errors); + return decode(frame, PFactory.createBytes(PythonLanguage.get(this), bytes, len), T_CODEC_ASCII, errors); } protected Object decodeUTF8(VirtualFrame frame, ByteArrayView bytes, int len, TruffleString errors) { - return decode(frame, factory().createBytes(bytes.getBytes(len), 0, len), T_UTF8, errors); + return decode(frame, PFactory.createBytes(PythonLanguage.get(this), bytes.getBytes(len), len), T_UTF8, errors); } protected Object decode(VirtualFrame frame, Object value, TruffleString encoding) { @@ -386,13 +369,6 @@ protected Object decode(VirtualFrame frame, Object value, TruffleString encoding return getItem(frame, ensureCodecsDecodeNode().call(frame, value, encoding, errors, false), 0); } - protected Object escapeDecode(VirtualFrame frame, PythonObjectFactory factory, byte[] data, int offset, int len) { - if (len == 0) { - return factory.createEmptyBytes(); - } - return escapeDecode(frame, PythonUtils.arrayCopyOfRange(data, offset, offset + len)); - } - protected Object escapeDecode(VirtualFrame frame, byte[] data) { return getItem(frame, ensureEscapeDecodeNode().execute(frame, data, T_ERRORS_STRICT), 0); } @@ -409,12 +385,12 @@ protected Object parseInt(TruffleString number) { return pyLongFromUnicodeObject.executeCached(number, 0); } - protected CallVarargsMethodNode ensureCallVarargsNode() { - if (callVarargsMethodNode == null) { + protected CallNode ensureCallNode() { + if (callNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - callVarargsMethodNode = insert(CallVarargsMethodNode.create()); + callNode = insert(CallNode.create()); } - return callVarargsMethodNode; + return callNode; } protected ExecutePositionalStarargsNode ensureGetArgsNode() { @@ -469,25 +445,8 @@ protected Object getClass(Frame frame, Object object) { return cls; } - protected Object callNew(VirtualFrame frame, Object tpNew, Object cls) { - return ensureCallVarargsNode().execute(frame, tpNew, new Object[]{cls}, PKeyword.EMPTY_KEYWORDS); - } - - protected Object callNew(VirtualFrame frame, Object tpNew, Object cls, Object args) { - return callNew(frame, tpNew, cls, args, null); - } - - protected Object callNew(VirtualFrame frame, Object tpNew, Object cls, Object args, Object kwargs) { - final Object[] stargs = ensureGetArgsNode().executeWith(frame, args); - final Object[] newArgs = new Object[stargs.length + 1]; - newArgs[0] = cls; - PythonUtils.arraycopy(stargs, 0, newArgs, 1, stargs.length); - PKeyword[] keywords = kwargs == null ? PKeyword.EMPTY_KEYWORDS : ensureExpandKwArgsNode().executeCached(kwargs); - return ensureCallVarargsNode().execute(frame, tpNew, newArgs, keywords); - } - protected Object call(VirtualFrame frame, Object method, Object... args) { - return ensureCallVarargsNode().execute(frame, method, args, PKeyword.EMPTY_KEYWORDS); + return ensureCallNode().execute(frame, method, args, PKeyword.EMPTY_KEYWORDS); } protected Object callStarArgs(VirtualFrame frame, Object method, Object args) { @@ -496,7 +455,7 @@ protected Object callStarArgs(VirtualFrame frame, Object method, Object args) { protected Object callStarArgsAndKwArgs(VirtualFrame frame, Object method, Object args, Object kwargs) { PKeyword[] keywords = kwargs == null ? PKeyword.EMPTY_KEYWORDS : ensureExpandKwArgsNode().executeCached(kwargs); - return ensureCallVarargsNode().execute(frame, method, ensureGetArgsNode().executeWith(frame, args), keywords); + return ensureCallNode().execute(frame, method, ensureGetArgsNode().executeWith(frame, args), keywords); } protected SequenceStorage getSequenceStorage(Object iterator) { @@ -583,7 +542,7 @@ protected boolean isBuiltinClass(Object cls, PythonBuiltinClassType type) { } public Object getNextItem(VirtualFrame frame, Object iterator) { - return getNextNode.execute(frame, iterator); + return getNextNode.executeCached(frame, iterator); } public Object getItem(VirtualFrame frame, SequenceStorage storage, int i) { @@ -683,7 +642,7 @@ protected Pair get2To3Mapping(VirtualFrame frame, private Pair getMapping(VirtualFrame frame, PDict nameMapping, PDict importMapping, TruffleString nameMappingLabel, TruffleString importMappingLabel, TruffleString moduleName, TruffleString globalName) { - Object key = factory().createTuple(new Object[]{moduleName, globalName}); + Object key = PFactory.createTuple(PythonLanguage.get(this), new Object[]{moduleName, globalName}); Object item = getDictItem(frame, nameMapping, key); if (item != null) { if (!(item instanceof PTuple) || length(frame, item) != 2) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/UnpicklerBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/UnpicklerBuiltins.java index 76f15c478e..031b57d333 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/UnpicklerBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/UnpicklerBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,11 +45,14 @@ import static com.oracle.graal.python.builtins.modules.pickle.PickleUtils.J_METHOD_LOAD; import static com.oracle.graal.python.builtins.modules.pickle.PickleUtils.J_METHOD_PERSISTENT_LOAD; import static com.oracle.graal.python.builtins.modules.pickle.PickleUtils.T_METHOD_PERSISTENT_LOAD; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -62,6 +65,9 @@ import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageIteratorNext; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageIteratorValue; import com.oracle.graal.python.builtins.objects.dict.PDict; +import com.oracle.graal.python.builtins.objects.function.PKeyword; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyCallableCheckNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectGetIter; @@ -75,8 +81,9 @@ import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -89,14 +96,28 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.Unpickler) public class UnpicklerBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = UnpicklerBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return UnpicklerBuiltinsFactory.getFactories(); } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 2, declaresExplicitSelf = true, parameterNames = {"$self", "file"}, varArgsMarker = true, keywordOnlyNames = {"fix_imports", "encoding", - "errors", - "buffers"}) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "Unpickler", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + abstract static class ConstructUnpicklerNode extends PythonVarargsBuiltinNode { + @Specialization + PUnpickler construct(Object cls, @SuppressWarnings("unused") Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + return PFactory.createUnpickler(language, cls, getInstanceShape.execute(cls)); + } + } + + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "Unpickler", minNumOfPositionalArgs = 2, parameterNames = {"$self", "file"}, keywordOnlyNames = {"fix_imports", "encoding", "errors", "buffers"}) @ArgumentClinic(name = "fix_imports", conversion = ArgumentClinic.ClinicConversion.Boolean, defaultValue = "true") @ArgumentClinic(name = "encoding", conversion = ArgumentClinic.ClinicConversion.TString, defaultValue = "T_ASCII_UPPERCASE") @ArgumentClinic(name = "errors", conversion = ArgumentClinic.ClinicConversion.TString, defaultValue = "T_STRICT") @@ -112,7 +133,7 @@ static Object load(VirtualFrame frame, PUnpickler self, Object file, boolean fix @Bind("this") Node inliningTarget, @Cached PyObjectLookupAttr lookup, @Cached PyObjectGetIter getIter, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { self.setInputStream(frame, inliningTarget, raiseNode, lookup, file); self.setInputEncoding(encoding, errors); self.setBuffers(frame, inliningTarget, getIter, buffers); @@ -131,9 +152,9 @@ public abstract static class UnpicklerLoadNode extends PythonUnaryBuiltinNode { static Object load(VirtualFrame frame, PUnpickler self, @Bind("this") Node inliningTarget, @Cached PUnpickler.LoadNode loadNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (self.getRead() == null) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.UnpicklingError, ErrorMessages.INIT_CALLED_WITH, "Unpickler", self); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.UnpicklingError, ErrorMessages.INIT_CALLED_WITH, "Unpickler", self); } return loadNode.execute(frame, self); } @@ -162,25 +183,25 @@ public abstract static class UnpicklerPersistentLoadNode extends PythonBuiltinNo @Specialization(guards = "isNoValue(none)") static Object get(PUnpickler self, @SuppressWarnings("unused") PNone none, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Exclusive @Cached PRaiseNode raiseNode) { final Object persFunc = self.getPersFunc(); if (persFunc == null) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.AttributeError, T_METHOD_PERSISTENT_LOAD); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, T_METHOD_PERSISTENT_LOAD); } - return PickleUtils.reconstructMethod(factory, persFunc, self.getPersFuncSelf()); + return PickleUtils.reconstructMethod(language, persFunc, self.getPersFuncSelf()); } @Specialization(guards = "!isNoValue(obj)") static Object set(PUnpickler self, Object obj, @Bind("this") Node inliningTarget, @Cached PyCallableCheckNode callableCheck, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (PGuards.isDeleteMarker(obj)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATRIBUTE_DELETION_NOT_SUPPORTED); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATRIBUTE_DELETION_NOT_SUPPORTED); } if (!callableCheck.execute(inliningTarget, obj)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_MUST_BE_A_CALLABLE, T_METHOD_PERSISTENT_LOAD, "one argument"); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_MUST_BE_A_CALLABLE, T_METHOD_PERSISTENT_LOAD, "one argument"); } self.setPersFuncSelf(null); self.setPersFunc(obj); @@ -193,8 +214,8 @@ static Object set(PUnpickler self, Object obj, public abstract static class UnpicklerMemoNode extends PythonBuiltinNode { @Specialization(guards = "isNoValue(none)") static Object get(PUnpickler self, @SuppressWarnings("unused") PNone none, - @Cached PythonObjectFactory factory) { - return factory.createUnpicklerMemoProxy(self); + @Bind PythonLanguage language) { + return PFactory.createUnpicklerMemoProxy(language, self); } @Specialization(guards = {"!isNoValue(obj)", "!isDeleteMarker(obj)"}) @@ -206,7 +227,7 @@ static Object set(VirtualFrame frame, PUnpickler self, Object obj, @Cached HashingStorageIteratorNext storageIterNext, @Cached HashingStorageIteratorKey storageIterKey, @Cached HashingStorageIteratorValue storageIterValue, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (obj instanceof PUnpicklerMemoProxy) { final PUnpickler unpickler = ((PUnpicklerMemoProxy) obj).getUnpickler(); self.setMemo(unpickler.getMemoCopy()); @@ -218,16 +239,16 @@ static Object set(VirtualFrame frame, PUnpickler self, Object obj, Object key = storageIterKey.execute(inliningTarget, dictStorage, it); Object value = storageIterValue.execute(inliningTarget, dictStorage, it); if (!PGuards.canBeInteger(key)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.MEMO_KEY_MUST_BE_INT); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.MEMO_KEY_MUST_BE_INT); } final int idx = asSizeNode.executeExact(frame, inliningTarget, key); if (idx < 0) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.MEMO_KEY_MUST_BE_POS_INT); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.MEMO_KEY_MUST_BE_POS_INT); } self.memoPut(idx, value); } } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_MUST_BE_A_OR_B_NOT_C, "memo", "UnpicklerMemoProxy", "dict", obj); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_MUST_BE_A_OR_B_NOT_C, "memo", "UnpicklerMemoProxy", "dict", obj); } return PNone.NONE; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/UnpicklerMemoProxyBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/UnpicklerMemoProxyBuiltins.java index 9e01a285b2..edbe793674 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/UnpicklerMemoProxyBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/UnpicklerMemoProxyBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,6 +44,10 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -52,9 +56,12 @@ import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -64,11 +71,26 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.UnpicklerMemoProxy) public class UnpicklerMemoProxyBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = UnpicklerMemoProxyBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return UnpicklerMemoProxyBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "UnpicklerMemoProxy", minNumOfPositionalArgs = 2, parameterNames = {"$cls", "unpickler"}) + @GenerateNodeFactory + abstract static class ConstructUnpicklerMemoProxyNode extends PythonBinaryBuiltinNode { + @Specialization + PUnpicklerMemoProxy construct(Object cls, PUnpickler unpickler, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + return PFactory.createUnpicklerMemoProxy(language, unpickler, cls, getInstanceShape.execute(cls)); + } + } + @Builtin(name = "clear", minNumOfPositionalArgs = 1, parameterNames = {"$self"}) @GenerateNodeFactory public abstract static class UnpicklerMemoProxyClearNode extends PythonUnaryBuiltinNode { @@ -86,8 +108,8 @@ public abstract static class UnpicklerMemoProxyCopyNode extends PythonUnaryBuilt Object copy(PUnpicklerMemoProxy self, @Bind("this") Node inliningTarget, @Cached HashingStorageSetItem setItem, - @Cached PythonObjectFactory factory) { - return factory.createDict(self.getUnpickler().copyMemoToHashingStorage(inliningTarget, setItem)); + @Bind PythonLanguage language) { + return PFactory.createDict(language, self.getUnpickler().copyMemoToHashingStorage(inliningTarget, setItem)); } } @@ -98,10 +120,10 @@ public abstract static class UnpicklerMemoProxyReduceNode extends PythonUnaryBui Object reduce(PUnpicklerMemoProxy self, @Bind("this") Node inliningTarget, @Cached HashingStorageSetItem setItem, - @Cached PythonObjectFactory factory) { - final PDict dictMemoCopy = factory.createDict(self.getUnpickler().copyMemoToHashingStorage(inliningTarget, setItem)); - final PTuple constructorArgs = factory.createTuple(new Object[]{dictMemoCopy}); - return factory.createTuple(new Object[]{PythonBuiltinClassType.PDict, constructorArgs}); + @Bind PythonLanguage language) { + final PDict dictMemoCopy = PFactory.createDict(language, self.getUnpickler().copyMemoToHashingStorage(inliningTarget, setItem)); + final PTuple constructorArgs = PFactory.createTuple(language, new Object[]{dictMemoCopy}); + return PFactory.createTuple(language, new Object[]{PythonBuiltinClassType.PDict, constructorArgs}); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZLibCompObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZLibCompObject.java index 2254eba7f8..2cd7ea0328 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZLibCompObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZLibCompObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,8 +40,6 @@ */ package com.oracle.graal.python.builtins.modules.zlib; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ZlibCompress; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ZlibDecompress; import static com.oracle.graal.python.builtins.modules.zlib.ZLibModuleBuiltins.MAX_WBITS; import static com.oracle.graal.python.builtins.objects.bytes.BytesUtils.mask; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ZLibError; @@ -51,12 +49,13 @@ import java.util.zip.Deflater; import java.util.zip.Inflater; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.runtime.NFIZlibSupport; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.nodes.Node; @@ -77,7 +76,7 @@ public ZLibCompObject(Object cls, Shape instanceShape) { this.unconsumedTail = null; } - // Note: some IDEs mark this class as inaccessible in PythonObjectFactory, but changing this to + // Note: some IDEs mark this class as inaccessible in PFactory, but changing this to // public will cause a warning: [this-escape] possible 'this' escape before subclass is fully // initialized protected static class NativeZlibCompObject extends ZLibCompObject { @@ -176,7 +175,7 @@ public void setInflaterInput(byte[] data, int length, Node node) { } @TruffleBoundary - public ZLibCompObject copyCompressObj(PythonObjectFactory factory) { + public ZLibCompObject copyCompressObj() { assert canCopy; Deflater deflater = new Deflater(level, wbits < 0 || wbits > (MAX_WBITS + 9)); @@ -184,7 +183,7 @@ public ZLibCompObject copyCompressObj(PythonObjectFactory factory) { if (zdict.length > 0) { deflater.setDictionary(zdict); } - ZLibCompObject obj = factory.createJavaZLibCompObject(ZlibCompress, deflater, level, wbits, strategy, zdict); + ZLibCompObject obj = PFactory.createJavaZLibCompObjectCompress(PythonLanguage.get(null), deflater, level, wbits, strategy, zdict); if (inputData != null) { // feed the new copy of deflater the same input data ((JavaZlibCompObject) obj).setDeflaterInput(inputData, inputLen); @@ -194,14 +193,14 @@ public ZLibCompObject copyCompressObj(PythonObjectFactory factory) { } @TruffleBoundary - public ZLibCompObject copyDecompressObj(PythonObjectFactory factory, Node node) { + public ZLibCompObject copyDecompressObj(Node node) { assert canCopy; boolean isRAW = wbits < 0; Inflater inflater = new Inflater(isRAW || wbits > (MAX_WBITS + 9)); if (isRAW && zdict.length > 0) { inflater.setDictionary(zdict); } - ZLibCompObject obj = factory.createJavaZLibCompObject(ZlibDecompress, inflater, wbits, zdict); + ZLibCompObject obj = PFactory.createJavaZLibCompObjectDecompress(PythonLanguage.get(null), inflater, wbits, zdict); if (inputData != null) { try { ((JavaZlibCompObject) obj).setInflaterInput(inputData, inputLen, node); @@ -243,12 +242,12 @@ private static int gzipHeader(byte[] bytes, Node node) { int idx = 0; // Check header magic if (readShort(bytes, idx, crc) != GZIP_MAGIC) { - throw PRaiseNode.raiseUncached(node, ZLibError, ErrorMessages.NOT_IN_GZIP_FORMAT); + throw PRaiseNode.raiseStatic(node, ZLibError, ErrorMessages.NOT_IN_GZIP_FORMAT); } idx += 2; // Check compression method if (getValue(bytes[idx++], crc) != 8) { - throw PRaiseNode.raiseUncached(node, ZLibError, ErrorMessages.UNSUPPORTED_COMPRESSION_METHOD); + throw PRaiseNode.raiseStatic(node, ZLibError, ErrorMessages.UNSUPPORTED_COMPRESSION_METHOD); } // Read flags int flg = getValue(bytes[idx++], crc); @@ -279,7 +278,7 @@ private static int gzipHeader(byte[] bytes, Node node) { if ((flg & FHCRC) == FHCRC) { int v = (int) crc.getValue() & 0xffff; if (readShort(bytes, idx, crc) != v) { - throw PRaiseNode.raiseUncached(node, ZLibError, ErrorMessages.CORRUPT_GZIP_HEADER); + throw PRaiseNode.raiseStatic(node, ZLibError, ErrorMessages.CORRUPT_GZIP_HEADER); } idx += 2; n += 2; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZLibModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZLibModuleBuiltins.java index 8c7166019e..b0986e0b33 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZLibModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZLibModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,8 +41,6 @@ package com.oracle.graal.python.builtins.modules.zlib; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ZlibCompress; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ZlibDecompress; import static com.oracle.graal.python.builtins.modules.zlib.ZlibNodes.Z_OK; import static com.oracle.graal.python.nodes.ErrorMessages.EXPECTED_BYTESLIKE_GOT_P; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; @@ -59,6 +57,7 @@ import java.util.zip.Deflater; import java.util.zip.Inflater; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ClinicConverterFactory; import com.oracle.graal.python.annotations.ClinicConverterFactory.UseDefaultForNone; @@ -87,14 +86,12 @@ import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentCastNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.NFIZlibSupport; import com.oracle.graal.python.runtime.NativeLibrary; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -108,7 +105,6 @@ import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.NonIdempotent; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.UnsupportedMessageException; @@ -312,8 +308,8 @@ static byte[] doMemView(VirtualFrame frame, PMemoryView bytesLike, @Fallback static byte[] error(@SuppressWarnings("unused") VirtualFrame frame, Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, value); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, value); } @ClinicConverterFactory @@ -389,8 +385,8 @@ static long doJavaObject(VirtualFrame frame, Object data, int value, @Fallback static long error(Object data, @SuppressWarnings("unused") Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, EXPECTED_BYTESLIKE_GOT_P, data); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, EXPECTED_BYTESLIKE_GOT_P, data); } long nativeCrc32(byte[] bytes, int len, int value, @@ -404,7 +400,6 @@ long nativeCrc32(byte[] bytes, int len, int value, // zlib.adler32(data[, value]) @Builtin(name = "adler32", minNumOfPositionalArgs = 1, numOfPositionalOnlyArgs = 2, parameterNames = {"data", "value"}) @ArgumentClinic(name = "value", conversionClass = ZLibModuleBuiltins.ExpectIntNode.class, defaultValue = "PNone.NO_VALUE", useDefaultForNone = true) - @TypeSystemReference(PythonArithmeticTypes.class) @GenerateNodeFactory public abstract static class Adler32Node extends PythonBinaryClinicBuiltinNode { @@ -510,15 +505,15 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static PBytes compress(VirtualFrame frame, Object buffer, int level, int wbits, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached("createFor(this)") IndirectCallData indirectCallData, - @Cached CompressInnerNode innerNode, - @Cached PythonObjectFactory factory) { + @Cached CompressInnerNode innerNode) { try { byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); int len = bufferLib.getBufferLength(buffer); byte[] resultArray = innerNode.execute(inliningTarget, bytes, len, level, wbits); - return factory.createBytes(resultArray); + return PFactory.createBytes(language, resultArray); } finally { bufferLib.release(buffer, frame, indirectCallData); } @@ -574,19 +569,19 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static PBytes decompress(VirtualFrame frame, Object buffer, int wbits, int bufsize, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached("createFor(this)") IndirectCallData indirectCallData, @Cached DecompressInnerNode innerNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { if (bufsize < 0) { - throw raiseNode.get(inliningTarget).raise(ZLibError, ErrorMessages.MUST_BE_NON_NEGATIVE, "bufsize"); + throw raiseNode.raise(inliningTarget, ZLibError, ErrorMessages.MUST_BE_NON_NEGATIVE, "bufsize"); } byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); int len = bufferLib.getBufferLength(buffer); byte[] resultArray = innerNode.execute(inliningTarget, bytes, len, wbits, bufsize); - return factory.createBytes(resultArray); + return PFactory.createBytes(language, resultArray); } finally { bufferLib.release(buffer, frame, indirectCallData); } @@ -624,14 +619,14 @@ static byte[] doJava(Node inliningTarget, byte[] bytes, int length, int wbits, i while (!decompresser.finished()) { int howmany = decompresser.inflate(resultArray); if (howmany == 0 && decompresser.needsInput()) { - throw PRaiseNode.raiseUncached(inliningTarget, ZLibError, ErrorMessages.ERROR_5_WHILE_DECOMPRESSING); + throw PRaiseNode.raiseStatic(inliningTarget, ZLibError, ErrorMessages.ERROR_5_WHILE_DECOMPRESSING); } baos.write(resultArray, 0, howmany); } decompresser.end(); return baos.toByteArray(); } catch (DataFormatException e) { - throw PRaiseNode.raiseUncached(inliningTarget, ZLibError, ErrorMessages.WHILE_PREPARING_TO_S_DATA, "decompress"); + throw PRaiseNode.raiseStatic(inliningTarget, ZLibError, ErrorMessages.WHILE_PREPARING_TO_S_DATA, "decompress"); } } } @@ -667,10 +662,10 @@ protected static boolean isValidWBitRange(int wbits) { @Specialization(guards = {"method == DEFLATED", "useNative()"}) static Object doNative(int level, int method, int wbits, int memLevel, int strategy, byte[] zdict, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached NativeLibrary.InvokeNativeFunction createCompObject, @Cached NativeLibrary.InvokeNativeFunction compressObjInit, - @Cached ZlibNodes.ZlibNativeErrorHandling errorHandling, - @Cached PythonObjectFactory factory) { + @Cached ZlibNodes.ZlibNativeErrorHandling errorHandling) { NFIZlibSupport zlibSupport = PythonContext.get(inliningTarget).getNFIZlibSupport(); Object zst = zlibSupport.createCompObject(createCompObject); @@ -684,7 +679,7 @@ static Object doNative(int level, int method, int wbits, int memLevel, int strat if (err != Z_OK) { errorHandling.execute(inliningTarget, zst, err, zlibSupport, true); } - return factory.createNativeZLibCompObject(ZlibCompress, zst, zlibSupport); + return PFactory.createNativeZLibCompObjectCompress(language, zst, zlibSupport); } /** @@ -703,21 +698,21 @@ static Object doJava(int level, @SuppressWarnings("unused") int method, int wbit if (zdict.length > 0) { deflater.setDictionary(zdict); } - return PythonObjectFactory.getUncached().createJavaZLibCompObject(ZlibCompress, deflater, level, wbits, strategy, zdict); + return PFactory.createJavaZLibCompObjectCompress(PythonLanguage.get(null), deflater, level, wbits, strategy, zdict); } @SuppressWarnings("unused") @Specialization(guards = {"method == DEFLATED", "!useNative()", "!isValidWBitRange(wbits)"}) static Object invalid(int level, int method, int wbits, int memLevel, int strategy, byte[] zdict, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.ValueError, ErrorMessages.INVALID_INITIALIZATION_OPTION); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.INVALID_INITIALIZATION_OPTION); } @SuppressWarnings("unused") @Specialization(guards = {"method != DEFLATED"}) static Object methodErr(int level, int method, int wbits, int memLevel, int strategy, byte[] zdict, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.ValueError, ErrorMessages.ONLY_DEFLATED_ALLOWED_AS_METHOD, DEFLATED, method); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.ONLY_DEFLATED_ALLOWED_AS_METHOD, DEFLATED, method); } } @@ -742,30 +737,30 @@ protected static boolean isValidWBitRange(int wbits) { } @Specialization(guards = {"useNative()"}) - Object doNative(int wbits, byte[] zdict, + static Object doNative(int wbits, byte[] zdict, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached NativeLibrary.InvokeNativeFunction createCompObject, @Cached NativeLibrary.InvokeNativeFunction decompressObjInit, - @Cached ZlibNodes.ZlibNativeErrorHandling errorHandling, - @Cached PythonObjectFactory factory) { - NFIZlibSupport zlibSupport = PythonContext.get(this).getNFIZlibSupport(); + @Cached ZlibNodes.ZlibNativeErrorHandling errorHandling) { + NFIZlibSupport zlibSupport = context.getNFIZlibSupport(); Object zst = zlibSupport.createCompObject(createCompObject); int err; if (zdict.length > 0) { - err = zlibSupport.decompressObjInitWithDict(zst, wbits, PythonContext.get(this).getEnv().asGuestValue(zdict), zdict.length, decompressObjInit); + err = zlibSupport.decompressObjInitWithDict(zst, wbits, context.getEnv().asGuestValue(zdict), zdict.length, decompressObjInit); } else { err = zlibSupport.decompressObjInit(zst, wbits, decompressObjInit); } if (err != Z_OK) { errorHandling.execute(inliningTarget, zst, err, zlibSupport, true); } - return factory.createNativeZLibCompObject(ZlibDecompress, zst, zlibSupport); + return PFactory.createNativeZLibCompObjectDecompress(context.getLanguage(inliningTarget), zst, zlibSupport); } - @CompilerDirectives.TruffleBoundary + @TruffleBoundary @Specialization(guards = {"!useNative()", "isValidWBitRange(wbits)"}) - Object doJava(int wbits, byte[] zdict) { + static Object doJava(int wbits, byte[] zdict) { // wbits < 0: generate a RAW stream, i.e., no wrapping // wbits 25..31: gzip container, i.e., no wrapping // Otherwise: wrap stream with zlib header and trailer @@ -774,18 +769,18 @@ Object doJava(int wbits, byte[] zdict) { if (isRAW && zdict.length > 0) { inflater.setDictionary(zdict); } - PythonObjectFactory factory = PythonObjectFactory.getUncached(); - ZLibCompObject obj = factory.createJavaZLibCompObject(ZlibDecompress, inflater, wbits, zdict); - obj.setUnusedData(factory.createEmptyBytes()); - obj.setUnconsumedTail(factory.createEmptyBytes()); + PythonLanguage language = PythonLanguage.get(null); + ZLibCompObject obj = PFactory.createJavaZLibCompObjectDecompress(language, inflater, wbits, zdict); + obj.setUnusedData(PFactory.createEmptyBytes(language)); + obj.setUnconsumedTail(PFactory.createEmptyBytes(language)); return obj; } @SuppressWarnings("unused") @Specialization(guards = {"!useNative()", "!isValidWBitRange(wbits)"}) static Object invalid(int wbits, byte[] zdict, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.ValueError, ErrorMessages.INVALID_INITIALIZATION_OPTION); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.INVALID_INITIALIZATION_OPTION); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibCompressBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibCompressBuiltins.java index 689b562d9f..d3093d5d81 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibCompressBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibCompressBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -54,6 +54,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -74,12 +75,11 @@ import com.oracle.graal.python.runtime.NFIZlibSupport; import com.oracle.graal.python.runtime.NativeLibrary; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -105,18 +105,18 @@ abstract static class CompressNode extends PythonBinaryClinicBuiltinNode { @Specialization static PBytes compress(VirtualFrame frame, ZLibCompObject self, Object buffer, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached("createFor(this)") IndirectCallData indirectCallData, @Cached CompressInnerNode innerNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { if (!self.isInitialized()) { - throw raiseNode.get(inliningTarget).raise(ZLibError, ERROR_D_S_S, Z_STREAM_ERROR, "while compressing data", "inconsistent stream state"); + throw raiseNode.raise(inliningTarget, ZLibError, ERROR_D_S_S, Z_STREAM_ERROR, "while compressing data", "inconsistent stream state"); } byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); int len = bufferLib.getBufferLength(buffer); - return factory.createBytes(innerNode.execute(inliningTarget, self, bytes, len)); + return PFactory.createBytes(language, innerNode.execute(inliningTarget, self, bytes, len)); } finally { bufferLib.release(buffer, frame, indirectCallData); } @@ -153,44 +153,45 @@ protected ArgumentClinicProvider getArgumentClinic() { @GenerateCached(false) abstract static class BaseCopyNode extends PNodeWithContext { - public abstract Object execute(Node inliningTarget, ZLibCompObject self, PythonContext ctxt, PythonObjectFactory factory); + public abstract Object execute(Node inliningTarget, ZLibCompObject self); @Specialization(guards = "self.isInitialized()") - static Object doNative(Node inliningTarget, ZLibCompObject.NativeZlibCompObject self, PythonContext ctxt, PythonObjectFactory factory, + static Object doNative(Node inliningTarget, ZLibCompObject.NativeZlibCompObject self, + @Bind PythonContext context, @Cached(inline = false) NativeLibrary.InvokeNativeFunction createCompObject, @Cached(inline = false) NativeLibrary.InvokeNativeFunction compressObjCopy, @Cached(inline = false) NativeLibrary.InvokeNativeFunction deallocateStream, @Cached ZlibNodes.ZlibNativeErrorHandling errorHandling) { synchronized (self) { assert self.isInitialized(); - NFIZlibSupport zlibSupport = ctxt.getNFIZlibSupport(); + NFIZlibSupport zlibSupport = context.getNFIZlibSupport(); Object zstNewCopy = zlibSupport.createCompObject(createCompObject); int err = zlibSupport.compressObjCopy(self.getZst(), zstNewCopy, compressObjCopy); if (err != Z_OK) { zlibSupport.deallocateStream(zstNewCopy, deallocateStream); errorHandling.execute(inliningTarget, self.getZst(), err, zlibSupport, false); } - return factory.createNativeZLibCompObject(ZlibCompress, zstNewCopy, zlibSupport); + return PFactory.createNativeZLibCompObjectCompress(context.getLanguage(inliningTarget), zstNewCopy, zlibSupport); } } @Specialization(guards = {"self.isInitialized()", "self.canCopy()"}) - static Object doJava(ZLibCompObject.JavaZlibCompObject self, @SuppressWarnings("unused") PythonContext ctxt, PythonObjectFactory factory) { - return self.copyCompressObj(factory); + static Object doJava(ZLibCompObject.JavaZlibCompObject self) { + return self.copyCompressObj(); } @SuppressWarnings("unused") @Specialization(guards = {"self.isInitialized()", "!self.canCopy()"}) - static PNone error(ZLibCompObject.JavaZlibCompObject self, PythonContext ctxt, PythonObjectFactory factory, - @Cached.Shared @Cached(inline = false) PRaiseNode raise) { - throw raise.raise(NotImplementedError, toTruffleStringUncached("JDK based zlib doesn't support copying")); + static PNone error(ZLibCompObject.JavaZlibCompObject self, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, toTruffleStringUncached("JDK based zlib doesn't support copying")); } @SuppressWarnings("unused") @Specialization(guards = "!self.isInitialized()") - static PNone error(ZLibCompObject self, PythonContext ctxt, PythonObjectFactory factory, - @Cached.Shared @Cached(inline = false) PRaiseNode raise) { - throw raise.raise(ValueError, ErrorMessages.INCONSISTENT_STREAM_STATE); + static PNone error(ZLibCompObject self, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.INCONSISTENT_STREAM_STATE); } } @@ -200,9 +201,8 @@ abstract static class CopyNode extends PythonUnaryBuiltinNode { @Specialization static Object doit(ZLibCompObject self, @Bind("this") Node inliningTarget, - @Cached BaseCopyNode copyNode, - @Cached PythonObjectFactory factory) { - return copyNode.execute(inliningTarget, self, PythonContext.get(inliningTarget), factory); + @Cached BaseCopyNode copyNode) { + return copyNode.execute(inliningTarget, self); } } @@ -217,9 +217,8 @@ abstract static class DeepCopyNode extends PythonBinaryBuiltinNode { @Specialization static Object doit(ZLibCompObject self, @SuppressWarnings("unused") Object memo, @Bind("this") Node inliningTarget, - @Cached BaseCopyNode copyNode, - @Cached PythonObjectFactory factory) { - return copyNode.execute(inliningTarget, self, PythonContext.get(inliningTarget), factory); + @Cached BaseCopyNode copyNode) { + return copyNode.execute(inliningTarget, self); } } @@ -237,8 +236,8 @@ protected ArgumentClinicProvider getArgumentClinic() { @SuppressWarnings("unused") @Specialization(guards = "mode == Z_NO_FLUSH") static PBytes empty(ZLibCompObject self, int mode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createEmptyBytes(); + @Bind PythonLanguage language) { + return PFactory.createEmptyBytes(language); } @Specialization(guards = {"mode != Z_NO_FLUSH", "self.isInitialized()"}) @@ -248,16 +247,15 @@ static PBytes doit(ZLibCompObject.NativeZlibCompObject self, int mode, @Cached ZlibNodes.GetNativeBufferNode getBuffer, @Cached NativeLibrary.InvokeNativeFunction getIsInitialised, @Cached ZlibNodes.NativeDeallocation processDeallocation, - @Cached ZlibNodes.ZlibNativeErrorHandling errorHandling, - @Shared @Cached PythonObjectFactory factory) { + @Cached ZlibNodes.ZlibNativeErrorHandling errorHandling) { synchronized (self) { assert self.isInitialized(); - PythonContext ctxt = PythonContext.get(inliningTarget); - NFIZlibSupport zlibSupport = ctxt.getNFIZlibSupport(); + PythonContext context = PythonContext.get(inliningTarget); + NFIZlibSupport zlibSupport = context.getNFIZlibSupport(); Object lastInput; if (self.lastInput == null) { // all previous input data has been processed or nothing has been compressed. - lastInput = ctxt.getEnv().asGuestValue(PythonUtils.EMPTY_BYTE_ARRAY); + lastInput = context.getEnv().asGuestValue(PythonUtils.EMPTY_BYTE_ARRAY); } else { // pass the last data input to continue processing. // all other needed info, e.g. size and offset, about the last data input is @@ -268,25 +266,25 @@ static PBytes doit(ZLibCompObject.NativeZlibCompObject self, int mode, if (err != Z_OK) { errorHandling.execute(inliningTarget, self.getZst(), err, zlibSupport, false); } - byte[] resultArray = getBuffer.getOutputBuffer(inliningTarget, self.getZst(), ctxt); + byte[] resultArray = getBuffer.getOutputBuffer(inliningTarget, self.getZst(), context); if (zlibSupport.getIsInitialised(self.getZst(), getIsInitialised) == 0) { - processDeallocation.execute(inliningTarget, self, ctxt, factory, true); + processDeallocation.execute(inliningTarget, self, context, true); } - return factory.createBytes(resultArray); + return PFactory.createBytes(context.getLanguage(inliningTarget), resultArray); } } @Specialization(guards = {"mode != Z_NO_FLUSH", "self.isInitialized()"}) static PBytes doit(ZLibCompObject.JavaZlibCompObject self, int mode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createBytes(ZlibNodes.JavaCompressNode.execute(self, mode)); + @Bind PythonLanguage language) { + return PFactory.createBytes(language, ZlibNodes.JavaCompressNode.execute(self, mode)); } @SuppressWarnings("unused") @Specialization(guards = "!self.isInitialized()") static PNone error(ZLibCompObject self, int mode, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ZLibError, ERROR_D_S_S, Z_STREAM_ERROR, "while compressing data", "inconsistent stream state"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ZLibError, ERROR_D_S_S, Z_STREAM_ERROR, "while compressing data", "inconsistent stream state"); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibDecompressBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibDecompressBuiltins.java index 52e0aa4467..b43e5fd4a0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibDecompressBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibDecompressBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -55,6 +55,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; @@ -76,11 +77,10 @@ import com.oracle.graal.python.runtime.NativeLibrary; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -111,21 +111,21 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static PBytes decompress(VirtualFrame frame, ZLibCompObject self, Object buffer, int maxLength, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached("createFor(this)") IndirectCallData indirectCallData, @Cached DecompressInnerNode innerNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { if (!self.isInitialized()) { - throw raiseNode.get(inliningTarget).raise(ZLibError, ERROR_D_S_S, Z_STREAM_ERROR, "while decompressing data", "inconsistent stream state"); + throw raiseNode.raise(inliningTarget, ZLibError, ERROR_D_S_S, Z_STREAM_ERROR, "while decompressing data", "inconsistent stream state"); } if (maxLength < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, S_MUST_BE_GREATER_THAN_ZERO, "max_length"); + throw raiseNode.raise(inliningTarget, ValueError, S_MUST_BE_GREATER_THAN_ZERO, "max_length"); } byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); int len = bufferLib.getBufferLength(buffer); - return factory.createBytes(innerNode.execute(frame, inliningTarget, self, bytes, len, maxLength)); + return PFactory.createBytes(language, innerNode.execute(frame, inliningTarget, self, bytes, len, maxLength)); } finally { bufferLib.release(buffer, frame, indirectCallData); } @@ -146,9 +146,8 @@ static byte[] doNative(Node inliningTarget, ZLibCompObject.NativeZlibCompObject @Specialization static byte[] doJava(VirtualFrame frame, Node inliningTarget, ZLibCompObject.JavaZlibCompObject self, byte[] bytes, int length, int maxLength, - @Cached(inline = false) BytesNodes.ToBytesNode toBytes, - @Cached(inline = false) PythonObjectFactory factory) { - return ZlibNodes.JavaDecompressor.execute(frame, self, bytes, length, maxLength, DEF_BUF_SIZE, inliningTarget, factory, toBytes); + @Cached(inline = false) BytesNodes.ToBytesNode toBytes) { + return ZlibNodes.JavaDecompressor.execute(frame, self, bytes, length, maxLength, DEF_BUF_SIZE, inliningTarget, toBytes); } } } @@ -157,46 +156,47 @@ static byte[] doJava(VirtualFrame frame, Node inliningTarget, ZLibCompObject.Jav @GenerateCached(false) abstract static class BaseCopyNode extends PNodeWithContext { - public abstract Object execute(Node inliningTarget, ZLibCompObject self, PythonContext ctxt, PythonObjectFactory factory); + public abstract Object execute(Node inliningTarget, ZLibCompObject self); @Specialization(guards = "self.isInitialized()") - static Object doNative(Node inliningTarget, ZLibCompObject.NativeZlibCompObject self, PythonContext ctxt, PythonObjectFactory factory, + static Object doNative(Node inliningTarget, ZLibCompObject.NativeZlibCompObject self, + @Bind PythonContext context, @Cached(inline = false) NativeLibrary.InvokeNativeFunction createCompObject, @Cached(inline = false) NativeLibrary.InvokeNativeFunction decompressObjCopy, @Cached(inline = false) NativeLibrary.InvokeNativeFunction deallocateStream, @Cached ZlibNodes.ZlibNativeErrorHandling errorHandling) { synchronized (self) { assert self.isInitialized(); - NFIZlibSupport zlibSupport = ctxt.getNFIZlibSupport(); + NFIZlibSupport zlibSupport = context.getNFIZlibSupport(); Object zstNewCopy = zlibSupport.createCompObject(createCompObject); int err = zlibSupport.decompressObjCopy(self.getZst(), zstNewCopy, decompressObjCopy); if (err != Z_OK) { zlibSupport.deallocateStream(zstNewCopy, deallocateStream); errorHandling.execute(inliningTarget, self.getZst(), err, zlibSupport, false); } - ZLibCompObject copy = factory.createNativeZLibCompObject(ZlibDecompress, zstNewCopy, zlibSupport); + ZLibCompObject copy = PFactory.createNativeZLibCompObjectDecompress(context.getLanguage(inliningTarget), zstNewCopy, zlibSupport); copy.setEof(self.isEof()); return copy; } } @Specialization(guards = {"self.isInitialized()", "self.canCopy()"}) - static Object doJava(Node inliningTarget, ZLibCompObject.JavaZlibCompObject self, @SuppressWarnings("unused") PythonContext ctxt, PythonObjectFactory factory) { - return self.copyDecompressObj(factory, inliningTarget); + static Object doJava(Node inliningTarget, ZLibCompObject.JavaZlibCompObject self) { + return self.copyDecompressObj(inliningTarget); } @SuppressWarnings("unused") @Specialization(guards = {"self.isInitialized()", "!self.canCopy()"}) - static PNone error(ZLibCompObject.JavaZlibCompObject self, PythonContext ctxt, PythonObjectFactory factory, - @Cached.Shared @Cached(inline = false) PRaiseNode raise) { - throw raise.raise(NotImplementedError, toTruffleStringUncached("JDK based zlib doesn't support copying")); + static PNone error(ZLibCompObject.JavaZlibCompObject self, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, toTruffleStringUncached("JDK based zlib doesn't support copying")); } @SuppressWarnings("unused") @Specialization(guards = "!self.isInitialized()") - static PNone error(ZLibCompObject self, PythonContext ctxt, PythonObjectFactory factory, - @Cached.Shared @Cached(inline = false) PRaiseNode raise) { - throw raise.raise(ValueError, INCONSISTENT_STREAM_STATE); + static PNone error(ZLibCompObject self, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, INCONSISTENT_STREAM_STATE); } } @@ -206,9 +206,8 @@ abstract static class CopyNode extends PythonUnaryBuiltinNode { @Specialization static Object doit(ZLibCompObject self, @Bind("this") Node inliningTarget, - @Cached BaseCopyNode copyNode, - @Cached PythonObjectFactory factory) { - return copyNode.execute(inliningTarget, self, PythonContext.get(inliningTarget), factory); + @Cached BaseCopyNode copyNode) { + return copyNode.execute(inliningTarget, self); } } @@ -223,9 +222,8 @@ abstract static class DeepCopyNode extends PythonBinaryBuiltinNode { @Specialization static Object doit(ZLibCompObject self, @SuppressWarnings("unused") Object memo, @Bind("this") Node inliningTarget, - @Cached BaseCopyNode copyNode, - @Cached PythonObjectFactory factory) { - return copyNode.execute(inliningTarget, self, PythonContext.get(inliningTarget), factory); + @Cached BaseCopyNode copyNode) { + return copyNode.execute(inliningTarget, self); } } @@ -242,64 +240,63 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(guards = {"length > 0", "!self.isEof()", "self.isInitialized()"}) static PBytes doit(ZLibCompObject.NativeZlibCompObject self, int length, @Bind("this") Node inliningTarget, + @Bind PythonContext context, @Cached NativeLibrary.InvokeNativeFunction decompressObjFlush, @Cached ZlibNodes.GetNativeBufferNode getBuffer, @Cached NativeLibrary.InvokeNativeFunction getIsInitialised, @Cached ZlibNodes.NativeDeallocation processDeallocation, - @Cached ZlibNodes.ZlibNativeErrorHandling errorHandling, - @Shared @Cached PythonObjectFactory factory) { + @Cached ZlibNodes.ZlibNativeErrorHandling errorHandling) { synchronized (self) { - PythonContext ctxt = PythonContext.get(inliningTarget); assert self.isInitialized(); - NFIZlibSupport zlibSupport = ctxt.getNFIZlibSupport(); + NFIZlibSupport zlibSupport = context.getNFIZlibSupport(); int err = zlibSupport.decompressObjFlush(self.getZst(), length, decompressObjFlush); if (err != Z_OK) { errorHandling.execute(inliningTarget, self.getZst(), err, zlibSupport, false); } - byte[] resultArray = getBuffer.getOutputBuffer(inliningTarget, self.getZst(), ctxt); + byte[] resultArray = getBuffer.getOutputBuffer(inliningTarget, self.getZst(), context); if (zlibSupport.getIsInitialised(self.getZst(), getIsInitialised) == 0) { - processDeallocation.execute(inliningTarget, self, ctxt, factory, false); + processDeallocation.execute(inliningTarget, self, context, false); } - return factory.createBytes(resultArray); + return PFactory.createBytes(context.getLanguage(inliningTarget), resultArray); } } @Specialization(guards = {"length > 0", "!self.isEof()", "self.isInitialized()"}) PBytes doit(VirtualFrame frame, ZLibCompObject.JavaZlibCompObject self, int length, - @Cached BytesNodes.ToBytesNode toBytes, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language, + @Cached BytesNodes.ToBytesNode toBytes) { byte[] res; try { byte[] bytes = toBytes.execute(self.getUnconsumedTail()); - res = ZlibNodes.JavaDecompressor.execute(frame, self, bytes, bytes.length, 0, length, this, factory, toBytes); + res = ZlibNodes.JavaDecompressor.execute(frame, self, bytes, bytes.length, 0, length, this, toBytes); } catch (PException e) { // CPython ignores errors here res = PythonUtils.EMPTY_BYTE_ARRAY; } self.setUninitialized(); - return factory.createBytes(res); + return PFactory.createBytes(language, res); } @SuppressWarnings("unused") @Specialization(guards = {"length > 0", "self.isEof() || !self.isInitialized()"}) static PBytes empty(ZLibCompObject.JavaZlibCompObject self, int length, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { self.setUninitialized(); - return factory.createEmptyBytes(); + return PFactory.createEmptyBytes(language); } @SuppressWarnings("unused") @Specialization(guards = {"length > 0", "self.isEof() || !self.isInitialized()"}) static PBytes empty(ZLibCompObject.NativeZlibCompObject self, int length, - @Shared @Cached PythonObjectFactory factory) { - return factory.createEmptyBytes(); + @Bind PythonLanguage language) { + return PFactory.createEmptyBytes(language); } @SuppressWarnings("unused") @Specialization(guards = "length <= 0") static PBytes error(ZLibCompObject self, int length, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, S_MUST_BE_GREATER_THAN_ZERO, "length"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, S_MUST_BE_GREATER_THAN_ZERO, "length"); } } @@ -309,11 +306,11 @@ abstract static class UnusedDataNode extends PythonUnaryBuiltinNode { @Specialization(guards = "self.isInitialized()") static PBytes doit(ZLibCompObject.NativeZlibCompObject self, @Bind("this") Node inliningTarget, - @Cached ZlibNodes.GetNativeBufferNode getBuffer, - @Cached PythonObjectFactory factory) { + @Bind PythonContext context, + @Cached ZlibNodes.GetNativeBufferNode getBuffer) { synchronized (self) { assert self.isInitialized(); - return factory.createBytes(getBuffer.getUnusedDataBuffer(inliningTarget, self.getZst(), PythonContext.get(inliningTarget))); + return PFactory.createBytes(context.getLanguage(inliningTarget), getBuffer.getUnusedDataBuffer(inliningTarget, self.getZst(), context)); } } @@ -334,11 +331,11 @@ abstract static class UnconsumedTailNode extends PythonUnaryBuiltinNode { @Specialization(guards = "self.isInitialized()") static PBytes doit(ZLibCompObject.NativeZlibCompObject self, @Bind("this") Node inliningTarget, - @Cached ZlibNodes.GetNativeBufferNode getBuffer, - @Cached PythonObjectFactory factory) { + @Bind PythonContext context, + @Cached ZlibNodes.GetNativeBufferNode getBuffer) { synchronized (self) { assert self.isInitialized(); - return factory.createBytes(getBuffer.getUnconsumedTailBuffer(inliningTarget, self.getZst(), PythonContext.get(inliningTarget))); + return PFactory.createBytes(context.getLanguage(inliningTarget), getBuffer.getUnconsumedTailBuffer(inliningTarget, self.getZst(), context)); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibNodes.java index 77dd75769d..65fce92816 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -73,6 +73,7 @@ import java.util.zip.Deflater; import java.util.zip.Inflater; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; @@ -82,11 +83,12 @@ import com.oracle.graal.python.runtime.NFIZlibSupport; import com.oracle.graal.python.runtime.NativeLibrary; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.OverflowException; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -242,6 +244,7 @@ public abstract static class ZlibNativeErrorMsg extends Node { @SuppressWarnings("unused") @Specialization(guards = "err == Z_VERSION_ERROR") static void doVersionError(Object zst, int err, TruffleString msg, NFIZlibSupport zlibSupport, boolean deallocate, + @Bind("this") Node inliningTarget, @Shared("d") @Cached NativeLibrary.InvokeNativeFunction deallocateStream, @Shared("r") @Cached PRaiseNode raise) { /* @@ -249,11 +252,12 @@ static void doVersionError(Object zst, int err, TruffleString msg, NFIZlibSuppor * first, before looking at comp->zst.msg. */ deallocateStream(zst, zlibSupport, deallocateStream, deallocate); - throw raise.raise(ZLibError, ERROR_D_S_S, err, msg, LIBRARY_VERSION_MISMATCH); + throw raise.raise(inliningTarget, ZLibError, ERROR_D_S_S, err, msg, LIBRARY_VERSION_MISMATCH); } @Specialization(guards = "err != Z_VERSION_ERROR") static void doError(Object zst, int err, TruffleString msg, NFIZlibSupport zlibSupport, boolean deallocate, + @Bind("this") Node inliningTarget, @Shared("r") @Cached PRaiseNode raise, @Shared("d") @Cached NativeLibrary.InvokeNativeFunction deallocateStream, @Exclusive @Cached NativeLibrary.InvokeNativeFunction hasStreamErrorMsg, @@ -276,9 +280,9 @@ static void doError(Object zst, int err, TruffleString msg, NFIZlibSupport zlibS } deallocateStream(zst, zlibSupport, deallocateStream, deallocate); if (zmsg == null) { - throw raise.raise(ZLibError, ERROR_D_S, err, msg); + throw raise.raise(inliningTarget, ZLibError, ERROR_D_S, err, msg); } else { - throw raise.raise(ZLibError, ERROR_D_S_S, err, msg, zmsg); + throw raise.raise(inliningTarget, ZLibError, ERROR_D_S_S, err, msg, zmsg); } } } @@ -292,68 +296,72 @@ public abstract static class ZlibFunctionNativeErrorHandling extends Node { @Specialization(guards = "function == DEFLATE_INIT_ERROR") static void deflateInitError(Object zst, @SuppressWarnings("unused") int function, int err, NFIZlibSupport zlibSupport, boolean deallocate, + @Bind("this") Node inliningTarget, @Shared("r") @Cached PRaiseNode raise, @Shared("d") @Cached NativeLibrary.InvokeNativeFunction deallocateStream, @Shared("err") @Cached ZlibNativeErrorMsg zlibError, @Shared("format") @Cached SimpleTruffleStringFormatNode formatNode) { if (err == Z_MEM_ERROR) { deallocateStream(zst, zlibSupport, deallocateStream, deallocate); - throw raise.raise(MemoryError, OUT_OF_MEMORY_WHILE_S_DATA, "compressing"); + throw raise.raise(inliningTarget, MemoryError, OUT_OF_MEMORY_WHILE_S_DATA, "compressing"); } if (err == Z_STREAM_ERROR) { deallocateStream(zst, zlibSupport, deallocateStream, deallocate); - throw raise.raise(ZLibError, ErrorMessages.BAD_COMPRESSION_LEVEL); + throw raise.raise(inliningTarget, ZLibError, ErrorMessages.BAD_COMPRESSION_LEVEL); } zlibError.execute(zst, err, formatNode.format(WHILE_S_DATA, "compressing"), zlibSupport, deallocate); } @Specialization(guards = "function == DEFLATE_OBJ_ERROR") static void deflateObjInitError(Object zst, @SuppressWarnings("unused") int function, int err, NFIZlibSupport zlibSupport, boolean deallocate, + @Bind("this") Node inliningTarget, @Shared("r") @Cached PRaiseNode raise, @Shared("d") @Cached NativeLibrary.InvokeNativeFunction deallocateStream, @Shared("err") @Cached ZlibNativeErrorMsg zlibError, @Shared("format") @Cached SimpleTruffleStringFormatNode formatNode) { if (err == Z_MEM_ERROR) { deallocateStream(zst, zlibSupport, deallocateStream, deallocate); - throw raise.raise(MemoryError, CANT_ALLOCATE_MEMORY_FOR_S_OBJECT, "compression"); + throw raise.raise(inliningTarget, MemoryError, CANT_ALLOCATE_MEMORY_FOR_S_OBJECT, "compression"); } if (err == Z_STREAM_ERROR) { deallocateStream(zst, zlibSupport, deallocateStream, deallocate); - throw raise.raise(ValueError, INVALID_INITIALIZATION_OPTION); + throw raise.raise(inliningTarget, ValueError, INVALID_INITIALIZATION_OPTION); } zlibError.execute(zst, err, formatNode.format(WHILE_CREATING_S_OBJECT, "compression"), zlibSupport, deallocate); } @Specialization(guards = "function == DEFLATE_COPY_ERROR") static void deflateCopyError(Object zst, @SuppressWarnings("unused") int function, int err, NFIZlibSupport zlibSupport, boolean deallocate, + @Bind("this") Node inliningTarget, @Shared("r") @Cached PRaiseNode raise, @Shared("d") @Cached NativeLibrary.InvokeNativeFunction deallocateStream, @Shared("err") @Cached ZlibNativeErrorMsg zlibError, @Shared("format") @Cached SimpleTruffleStringFormatNode formatNode) { if (err == Z_MEM_ERROR) { deallocateStream(zst, zlibSupport, deallocateStream, deallocate); - throw raise.raise(MemoryError, CANT_ALLOCATE_MEMORY_FOR_S_OBJECT, "compression"); + throw raise.raise(inliningTarget, MemoryError, CANT_ALLOCATE_MEMORY_FOR_S_OBJECT, "compression"); } if (err == Z_STREAM_ERROR) { deallocateStream(zst, zlibSupport, deallocateStream, deallocate); - throw raise.raise(ValueError, INCONSISTENT_STREAM_STATE); + throw raise.raise(inliningTarget, ValueError, INCONSISTENT_STREAM_STATE); } zlibError.execute(zst, err, formatNode.format(WHILE_COPYING_S_OBJECT, "compression"), zlibSupport, deallocate); } @Specialization(guards = "function == INFLATE_COPY_ERROR") static void inflateCopyError(Object zst, @SuppressWarnings("unused") int function, int err, NFIZlibSupport zlibSupport, boolean deallocate, + @Bind("this") Node inliningTarget, @Shared("r") @Cached PRaiseNode raise, @Shared("d") @Cached NativeLibrary.InvokeNativeFunction deallocateStream, @Shared("err") @Cached ZlibNativeErrorMsg zlibError, @Shared("format") @Cached SimpleTruffleStringFormatNode formatNode) { if (err == Z_MEM_ERROR) { deallocateStream(zst, zlibSupport, deallocateStream, deallocate); - throw raise.raise(MemoryError, CANT_ALLOCATE_MEMORY_FOR_S_OBJECT, "decompression"); + throw raise.raise(inliningTarget, MemoryError, CANT_ALLOCATE_MEMORY_FOR_S_OBJECT, "decompression"); } if (err == Z_STREAM_ERROR) { deallocateStream(zst, zlibSupport, deallocateStream, deallocate); - throw raise.raise(ValueError, INCONSISTENT_STREAM_STATE); + throw raise.raise(inliningTarget, ValueError, INCONSISTENT_STREAM_STATE); } zlibError.execute(zst, err, formatNode.format(WHILE_COPYING_S_OBJECT, "compression"), zlibSupport, deallocate); } @@ -361,25 +369,27 @@ static void inflateCopyError(Object zst, @SuppressWarnings("unused") int functio @SuppressWarnings("unused") @Specialization(guards = "function == DEFLATE_DICT_ERROR") static void deflateDictError(Object zst, int function, int err, NFIZlibSupport zlibSupport, boolean deallocate, + @Bind("this") Node inliningTarget, @Shared("d") @Cached NativeLibrary.InvokeNativeFunction deallocateStream, @Shared("r") @Cached PRaiseNode raise) { if (err == Z_STREAM_ERROR) { deallocateStream(zst, zlibSupport, deallocateStream, deallocate); - throw raise.raise(ValueError, INVALID_DICTIONARY); + throw raise.raise(inliningTarget, ValueError, INVALID_DICTIONARY); } - throw raise.raise(ValueError, ErrorMessages.DEFLATED_SET_DICT); + throw raise.raise(inliningTarget, ValueError, ErrorMessages.DEFLATED_SET_DICT); } @Specialization(guards = "function == INFLATE_INIT_ERROR") static void inflateInitError(Object zst, @SuppressWarnings("unused") int function, int err, NFIZlibSupport zlibSupport, boolean deallocate, + @Bind("this") Node inliningTarget, @Shared("r") @Cached PRaiseNode raise, @Shared("d") @Cached NativeLibrary.InvokeNativeFunction deallocateStream, @Shared("err") @Cached ZlibNativeErrorMsg zlibError, @Shared("format") @Cached SimpleTruffleStringFormatNode formatNode) { if (err == Z_MEM_ERROR) { deallocateStream(zst, zlibSupport, deallocateStream, deallocate); - throw raise.raise(MemoryError, OUT_OF_MEMORY_WHILE_S_DATA, "decompressing"); + throw raise.raise(inliningTarget, MemoryError, OUT_OF_MEMORY_WHILE_S_DATA, "decompressing"); } zlibError.execute(zst, err, formatNode.format(WHILE_PREPARING_TO_S_DATA, "decompress"), zlibSupport, deallocate); @@ -387,17 +397,18 @@ static void inflateInitError(Object zst, @SuppressWarnings("unused") int functio @Specialization(guards = "function == INFLATE_OBJ_ERROR") static void inflateObjInitError(Object zst, @SuppressWarnings("unused") int function, int err, NFIZlibSupport zlibSupport, boolean deallocate, + @Bind("this") Node inliningTarget, @Shared("r") @Cached PRaiseNode raise, @Shared("d") @Cached NativeLibrary.InvokeNativeFunction deallocateStream, @Shared("err") @Cached ZlibNativeErrorMsg zlibError, @Shared("format") @Cached SimpleTruffleStringFormatNode formatNode) { if (err == Z_MEM_ERROR) { deallocateStream(zst, zlibSupport, deallocateStream, deallocate); - throw raise.raise(MemoryError, CANT_ALLOCATE_MEMORY_FOR_S_OBJECT, "decompression"); + throw raise.raise(inliningTarget, MemoryError, CANT_ALLOCATE_MEMORY_FOR_S_OBJECT, "decompression"); } if (err == Z_STREAM_ERROR) { deallocateStream(zst, zlibSupport, deallocateStream, deallocate); - throw raise.raise(ValueError, INVALID_INITIALIZATION_OPTION); + throw raise.raise(inliningTarget, ValueError, INVALID_INITIALIZATION_OPTION); } zlibError.execute(zst, err, formatNode.format(WHILE_CREATING_S_OBJECT, "decompression"), zlibSupport, deallocate); } @@ -451,16 +462,17 @@ static void inflateFlushError(Object zst, @SuppressWarnings("unused") int functi @SuppressWarnings("unused") @Specialization(guards = "function == MEMORY_ERROR") static void memError(Object zst, int function, int err, NFIZlibSupport zlibSupport, boolean deallocate, + @Bind("this") Node inliningTarget, @Shared("d") @Cached NativeLibrary.InvokeNativeFunction deallocateStream, @Shared("r") @Cached PRaiseNode raise) { deallocateStream(zst, zlibSupport, deallocateStream, deallocate); - throw raise.raise(MemoryError); + throw raise.raise(inliningTarget, MemoryError); } @SuppressWarnings("unused") @Fallback void fallback(Object zst, int function, int err, NFIZlibSupport zlibSupport, boolean deallocate) { - throw PRaiseNode.raiseUncached(this, SystemError, ErrorMessages.UNHANDLED_ERROR); + throw PRaiseNode.raiseStatic(this, SystemError, ErrorMessages.UNHANDLED_ERROR); } } @@ -469,10 +481,10 @@ void fallback(Object zst, int function, int err, NFIZlibSupport zlibSupport, boo @GenerateCached(false) public abstract static class NativeDeallocation extends PNodeWithContext { - public abstract void execute(Node inliningTarget, ZLibCompObject.NativeZlibCompObject self, PythonContext context, PythonObjectFactory factory, boolean isCompressObj); + public abstract void execute(Node inliningTarget, ZLibCompObject.NativeZlibCompObject self, PythonContext context, boolean isCompressObj); @Specialization(guards = "isCompressObj") - static void doCompressObj(ZLibCompObject.NativeZlibCompObject self, PythonContext context, @SuppressWarnings("unused") PythonObjectFactory factory, + static void doCompressObj(ZLibCompObject.NativeZlibCompObject self, PythonContext context, @SuppressWarnings("unused") boolean isCompressObj, @Shared @Cached(inline = false) NativeLibrary.InvokeNativeFunction deallocateStream) { context.getNFIZlibSupport().deallocateStream(self.getZst(), deallocateStream); @@ -481,15 +493,16 @@ static void doCompressObj(ZLibCompObject.NativeZlibCompObject self, PythonContex } @Specialization(guards = "!isCompressObj") - static void doDecompressObj(Node inliningTarget, ZLibCompObject.NativeZlibCompObject self, PythonContext context, PythonObjectFactory factory, + static void doDecompressObj(Node inliningTarget, ZLibCompObject.NativeZlibCompObject self, PythonContext context, @SuppressWarnings("unused") boolean isCompressObj, @Cached GetNativeBufferNode getUnusedDataBuffer, @Cached GetNativeBufferNode getUnconsumedBuffer, @Shared @Cached(inline = false) NativeLibrary.InvokeNativeFunction deallocateStream) { byte[] unusedData = getUnusedDataBuffer.getUnusedDataBuffer(inliningTarget, self.getZst(), context); - self.setUnusedData(factory.createBytes(unusedData)); + PythonLanguage language = context.getLanguage(inliningTarget); + self.setUnusedData(PFactory.createBytes(language, unusedData)); byte[] unconsumed = getUnconsumedBuffer.getUnconsumedTailBuffer(inliningTarget, self.getZst(), context); - self.setUnconsumedTail(factory.createBytes(unconsumed)); + self.setUnconsumedTail(PFactory.createBytes(language, unconsumed)); context.getNFIZlibSupport().deallocateStream(self.getZst(), deallocateStream); self.setEof(true); self.markReleased(); @@ -582,11 +595,11 @@ private static byte[] createByteArray(ZLibCompObject.JavaZlibCompObject self, In // we inflate again with a dictionary bytesWritten = inflater.inflate(result, 0, len); } else { - throw PRaiseNode.raiseUncached(nodeForRaise, ZLibError, WHILE_SETTING_ZDICT); + throw PRaiseNode.raiseStatic(nodeForRaise, ZLibError, WHILE_SETTING_ZDICT); } } } catch (DataFormatException e) { - throw PRaiseNode.raiseUncached(nodeForRaise, ZLibError, e); + throw PRaiseNode.raiseStatic(nodeForRaise, ZLibError, e); } baos.write(result, 0, bytesWritten); } @@ -594,35 +607,36 @@ private static byte[] createByteArray(ZLibCompObject.JavaZlibCompObject self, In } public static byte[] execute(VirtualFrame frame, ZLibCompObject.JavaZlibCompObject self, byte[] bytes, int length, int maxLength, int bufSize, - Node nodeForRaise, PythonObjectFactory factory, BytesNodes.ToBytesNode toBytesNode) { + Node inliningTarget, BytesNodes.ToBytesNode toBytesNode) { Inflater inflater = (Inflater) self.stream; - byte[] result = createByteArray(self, inflater, bytes, length, maxLength, bufSize, nodeForRaise); + byte[] result = createByteArray(self, inflater, bytes, length, maxLength, bufSize, inliningTarget); self.setEof(isFinished(inflater)); byte[] unusedDataBytes = toBytesNode.execute(frame, self.getUnusedData()); int unconsumedTailLen = self.getUnconsumedTail().getSequenceStorage().length(); - saveUnconsumedInput(self, bytes, length, unusedDataBytes, unconsumedTailLen, factory); + saveUnconsumedInput(self, bytes, length, unusedDataBytes, unconsumedTailLen, inliningTarget); return result; } private static void saveUnconsumedInput(ZLibCompObject.JavaZlibCompObject self, byte[] data, int length, - byte[] unusedDataBytes, int unconsumedTailLen, PythonObjectFactory factory) { + byte[] unusedDataBytes, int unconsumedTailLen, Node inliningTarget) { Inflater inflater = (Inflater) self.stream; int unusedLen = getRemaining(inflater); byte[] tail = PythonUtils.arrayCopyOfRange(data, length - unusedLen, length); + PythonLanguage language = PythonLanguage.get(inliningTarget); if (self.isEof()) { if (unconsumedTailLen > 0) { - self.setUnconsumedTail(factory.createEmptyBytes()); + self.setUnconsumedTail(PFactory.createEmptyBytes(language)); } if (unusedDataBytes.length > 0 && tail.length > 0) { byte[] newUnusedData = new byte[unusedDataBytes.length + tail.length]; PythonUtils.arraycopy(unusedDataBytes, 0, newUnusedData, 0, unusedDataBytes.length); PythonUtils.arraycopy(tail, 0, newUnusedData, unusedDataBytes.length, tail.length); - self.setUnusedData(factory.createBytes(newUnusedData)); + self.setUnusedData(PFactory.createBytes(language, newUnusedData)); } else if (tail.length > 0) { - self.setUnusedData(factory.createBytes(tail)); + self.setUnusedData(PFactory.createBytes(language, tail)); } } else { - self.setUnconsumedTail(factory.createBytes(tail)); + self.setUnconsumedTail(PFactory.createBytes(language, tail)); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/NoneBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/NoneBuiltins.java index 1994e9014c..75caf12293 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/NoneBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/NoneBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,20 +40,20 @@ */ package com.oracle.graal.python.builtins.objects; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.nodes.StringLiterals.T_NONE; import java.util.List; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotInquiry.NbBoolBuiltinNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.object.IsForeignObjectNode; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -71,6 +71,17 @@ protected List> getNodeFa return NoneBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "NoneType", minNumOfPositionalArgs = 1) + @GenerateNodeFactory + public abstract static class NoneTypeNode extends PythonBuiltinNode { + @SuppressWarnings("unused") + @Specialization + public static PNone module(Object cls) { + return PNone.NONE; + } + } + @Slot(SlotKind.nb_bool) @GenerateUncached @GenerateNodeFactory @@ -82,7 +93,7 @@ static boolean doNone(Object none) { } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/NotImplementedBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/NotImplementedBuiltins.java index 1386bc75c0..8046682ff2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/NotImplementedBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/NotImplementedBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,16 +42,21 @@ import static com.oracle.graal.python.nodes.BuiltinNames.T_NOT_IMPLEMENTED; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import java.util.List; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; @@ -61,14 +66,27 @@ @SuppressWarnings("unused") public final class NotImplementedBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = NotImplementedBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return NotImplementedBuiltinsFactory.getFactories(); } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "NotImplementedType", minNumOfPositionalArgs = 1) + @GenerateNodeFactory + public abstract static class NotImplementedTypeNode extends PythonBuiltinNode { + @SuppressWarnings("unused") + @Specialization + public static PNotImplemented module(Object cls) { + return PNotImplemented.NOT_IMPLEMENTED; + } + } + + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory - abstract static class ReprNode extends PythonBuiltinNode { + abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization @SuppressWarnings("unused") static TruffleString doit(PNotImplemented self) { @@ -78,7 +96,7 @@ static TruffleString doit(PNotImplemented self) { @Builtin(name = J___REDUCE__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2) @GenerateNodeFactory - public abstract static class ReduceNode extends PythonBuiltinNode { + public abstract static class ReduceNode extends PythonBinaryBuiltinNode { @Specialization @SuppressWarnings("unused") TruffleString doit(PNotImplemented self, Object ignored) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java index bc9233c76e..8b9250444a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java @@ -97,12 +97,15 @@ import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; import com.oracle.graal.python.builtins.objects.type.PythonClass; import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroNode; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyCallableCheckNode; +import com.oracle.graal.python.lib.PyIterCheckNode; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyMappingCheckNode; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyObjectGetIter; @@ -122,13 +125,10 @@ import com.oracle.graal.python.nodes.argument.keywords.MappingToKeywordsNode; import com.oracle.graal.python.nodes.argument.keywords.NonMappingException; import com.oracle.graal.python.nodes.argument.keywords.SameDictKeyException; -import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode; -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode; -import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode; import com.oracle.graal.python.nodes.expression.CastToListExpressionNode.CastToListInteropNode; import com.oracle.graal.python.nodes.interop.GetInteropBehaviorNode; import com.oracle.graal.python.nodes.interop.GetInteropBehaviorValueNode; @@ -153,7 +153,7 @@ import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.OverflowException; import com.oracle.graal.python.util.PythonUtils; @@ -199,10 +199,6 @@ public abstract class PythonAbstractObject extends DynamicObject implements Truf private static final int PRIVATE_PREFIX_LENGTH = T_PRIVATE_PREFIX.codePointLengthUncached(TS_ENCODING); private PythonAbstractObjectNativeWrapper nativeWrapper; - // @ImportStatic doesn't work for this for some reason - protected static final SpecialMethodSlot Iter = SpecialMethodSlot.Iter; - protected static final SpecialMethodSlot Next = SpecialMethodSlot.Next; - protected static final Shape ABSTRACT_SHAPE = Shape.newBuilder().build(); private Object[] indexedSlots; @@ -291,7 +287,7 @@ public boolean hasArrayElements( // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Cached GetObjectSlotsNode getSlotsNode, @Exclusive @Cached PySequenceCheckNode sequenceCheck, @Exclusive @Cached GilNode gil) { @@ -406,7 +402,7 @@ public long getArraySize( // GR-44020: make shared: @Exclusive @Cached CastToJavaLongExactNode toLongNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Exclusive @Cached GilNode gil) throws UnsupportedMessageException { boolean mustRelease = gil.acquire(); try { @@ -441,7 +437,7 @@ public boolean isArrayElementReadable(long idx, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Exclusive @Cached PySequenceSizeNode sequenceSizeNode, @Shared("getBehavior") @Cached GetInteropBehaviorNode getBehavior, @Shared("getValue") @Cached GetInteropBehaviorValueNode getValue, @@ -471,7 +467,7 @@ public boolean isArrayElementModifiable(long idx, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Exclusive @Cached PySequenceSizeNode sequenceSizeNode, @Shared("getBehavior") @Cached GetInteropBehaviorNode getBehavior, @Shared("getValue") @Cached GetInteropBehaviorValueNode getValue, @@ -503,7 +499,7 @@ public boolean isArrayElementInsertable(long idx, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Exclusive @Cached PySequenceSizeNode sequenceSizeNode, @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -533,7 +529,7 @@ public boolean isArrayElementRemovable(long idx, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Exclusive @Cached PySequenceSizeNode sequenceSizeNode, @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -659,7 +655,7 @@ public boolean isExecutable( // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Cached PyCallableCheckNode callableCheck, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { @@ -852,7 +848,7 @@ public boolean isDate( // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -878,7 +874,7 @@ public LocalDate asDate( // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode castToIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached SequenceStorageNodes.GetItemDynamicNode getItemNode, // GR-44020: make shared: @@ -893,7 +889,7 @@ public LocalDate asDate( Object value = getValue.execute(inliningTarget, behavior, method, this); if (value instanceof PTuple tuple) { if (pyTupleSizeNode.execute(inliningTarget, tuple) != 3) { - throw raiseNode.get(inliningTarget).raise(ValueError, S_MUST_BE_A_S_TUPLE, "return value", "3"); + throw raiseNode.raise(inliningTarget, ValueError, S_MUST_BE_A_S_TUPLE, "return value", "3"); } SequenceStorage storage = tuple.getSequenceStorage(); int year = castToIntNode.executeWithThrowSystemError(inliningTarget, getItemNode.execute(inliningTarget, storage, 0), raiseNode); @@ -902,10 +898,10 @@ public LocalDate asDate( try { return createLocalDate(year, month, day); } catch (Exception e) { - throw raiseNode.get(inliningTarget).raise(SystemError, e); + throw raiseNode.raise(inliningTarget, SystemError, e); } } else { - throw raiseNode.get(inliningTarget).raise(TypeError, MUST_BE_TYPE_A_NOT_TYPE_B, "return value", "tuple", value); + throw raiseNode.raise(inliningTarget, TypeError, MUST_BE_TYPE_A_NOT_TYPE_B, "return value", "tuple", value); } } else { @@ -925,7 +921,7 @@ public boolean isTime( // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -951,7 +947,7 @@ public LocalTime asTime( // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode castToIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached SequenceStorageNodes.GetItemDynamicNode getItemNode, // GR-44020: make shared: @@ -966,7 +962,7 @@ public LocalTime asTime( Object value = getValue.execute(inliningTarget, behavior, method, this); if (value instanceof PTuple tuple) { if (pyTupleSizeNode.execute(inliningTarget, tuple) != 4) { - throw raiseNode.get(inliningTarget).raise(ValueError, S_MUST_BE_A_S_TUPLE, "return value", "4"); + throw raiseNode.raise(inliningTarget, ValueError, S_MUST_BE_A_S_TUPLE, "return value", "4"); } SequenceStorage storage = tuple.getSequenceStorage(); int hour = castToIntNode.executeWithThrowSystemError(inliningTarget, getItemNode.execute(inliningTarget, storage, 0), raiseNode); @@ -976,10 +972,10 @@ public LocalTime asTime( try { return createLocalTime(hour, min, sec, micro); } catch (Exception e) { - throw raiseNode.get(inliningTarget).raise(SystemError, e); + throw raiseNode.raise(inliningTarget, SystemError, e); } } else { - throw raiseNode.get(inliningTarget).raise(TypeError, MUST_BE_TYPE_A_NOT_TYPE_B, "return value", "tuple", value); + throw raiseNode.raise(inliningTarget, TypeError, MUST_BE_TYPE_A_NOT_TYPE_B, "return value", "tuple", value); } } else { throw UnsupportedMessageException.create(); @@ -999,7 +995,7 @@ public boolean isTimeZone( // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -1025,7 +1021,7 @@ public ZoneId asTimeZone( // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode castToIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Cached TruffleString.ToJavaStringNode toJavaStringNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) throws UnsupportedMessageException { @@ -1045,10 +1041,10 @@ public ZoneId asTimeZone( return createZoneId(utcDeltaInSeconds); } } catch (Exception e) { - throw raiseNode.get(inliningTarget).raise(SystemError, e); + throw raiseNode.raise(inliningTarget, SystemError, e); } } catch (CannotCastException cce) { - throw raiseNode.get(inliningTarget).raise(TypeError, MUST_BE_TYPE_A_NOT_TYPE_B, "return value", "str or int", value); + throw raiseNode.raise(inliningTarget, TypeError, MUST_BE_TYPE_A_NOT_TYPE_B, "return value", "str or int", value); } } else { throw UnsupportedMessageException.create(); @@ -1087,7 +1083,7 @@ public boolean isDuration( // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -1113,7 +1109,7 @@ public Duration asDuration( // GR-44020: make shared: @Exclusive @Cached CastToJavaLongExactNode castToLongNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached SequenceStorageNodes.GetItemDynamicNode getItemNode, // GR-44020: make shared: @@ -1128,7 +1124,7 @@ public Duration asDuration( Object value = getValue.execute(inliningTarget, behavior, method, this); if (value instanceof PTuple tuple) { if (pyTupleSizeNode.execute(inliningTarget, tuple) != 2) { - throw raiseNode.get(inliningTarget).raise(ValueError, S_MUST_BE_A_S_TUPLE, "return value", "2"); + throw raiseNode.raise(inliningTarget, ValueError, S_MUST_BE_A_S_TUPLE, "return value", "2"); } SequenceStorage storage = tuple.getSequenceStorage(); long sec = castToLongNode.executeWithThrowSystemError(inliningTarget, getItemNode.execute(inliningTarget, storage, 0), raiseNode); @@ -1136,10 +1132,10 @@ public Duration asDuration( try { return createDuration(sec, nano); } catch (Exception e) { - throw raiseNode.get(inliningTarget).raise(SystemError, e); + throw raiseNode.raise(inliningTarget, SystemError, e); } } else { - throw raiseNode.get(inliningTarget).raise(TypeError, MUST_BE_TYPE_A_NOT_TYPE_B, "return value", "tuple", value); + throw raiseNode.raise(inliningTarget, TypeError, MUST_BE_TYPE_A_NOT_TYPE_B, "return value", "tuple", value); } } else { throw UnsupportedMessageException.create(); @@ -1289,26 +1285,16 @@ public abstract static class PExecuteNode extends Node { public abstract Object execute(Object receiver, Object[] arguments) throws UnsupportedMessageException; - @Specialization(guards = {"isBuiltinFunctionOrMethod(receiver)"}) - Object doVarargsBuiltinMethod(Object receiver, Object[] arguments, - @Bind("this") Node inliningTarget, - @Cached CallVarargsMethodNode callVarargsMethodNode, - @Exclusive @Cached ArgumentsFromForeignNode convertArgsNode) { - Object[] convertedArgs = convertArgsNode.execute(inliningTarget, arguments); - return callVarargsMethodNode.execute(null, receiver, convertedArgs, PKeyword.EMPTY_KEYWORDS); - } - private static String POSARGS_MEMBER = "org.graalvm.python.embedding.PositionalArguments.is_positional_arguments"; private static String KWARGS_MEMBER = "org.graalvm.python.embedding.KeywordArguments.is_keyword_arguments"; - @Specialization(replaces = "doVarargsBuiltinMethod") + @Specialization static Object doExecute(Object receiver, Object[] arguments, @Bind("this") Node inliningTarget, @Cached PyCallableCheckNode callableCheck, @Exclusive @Cached CallNode callNode, @Exclusive @Cached ArgumentsFromForeignNode convertArgsNode, @Cached MappingToKeywordsNode toKeywordsNode, - @Cached ExecutePositionalStarargsNode positionalStarargsNode, @CachedLibrary(limit = "1") InteropLibrary iLibKwArgs, @CachedLibrary(limit = "1") InteropLibrary iLibPosArgs, @CachedLibrary(limit = "1") InteropLibrary iLibIterator, @@ -1592,7 +1578,6 @@ public boolean hasMetaParents( @ExportMessage public Object getMetaParents( @Bind("$node") Node inliningTarget, - @Exclusive @Cached PythonObjectFactory factory, @Exclusive @Cached TypeNodes.IsTypeNode isTypeNode, @Exclusive @Cached TypeNodes.GetBaseClassesNode getBaseClassNode, @Exclusive @Cached GilNode gil) throws UnsupportedMessageException { @@ -1601,7 +1586,7 @@ public Object getMetaParents( if (isTypeNode.execute(inliningTarget, this)) { var bases = getBaseClassNode.execute(inliningTarget, this); if (bases.length > 0) { - return factory.createTuple(bases); + return PFactory.createTuple(PythonLanguage.get(inliningTarget), bases); } } throw UnsupportedMessageException.create(); @@ -1673,9 +1658,9 @@ public boolean hasIterator( // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("getClass") @Cached(inline = false) GetClassNode getClassNode, - @Cached(parameters = "Iter") LookupCallableSlotInMRONode lookupIter, + @Cached GetCachedTpSlotsNode getSlots, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -1685,7 +1670,8 @@ public boolean hasIterator( if (behavior != null) { return getValue.executeBoolean(inliningTarget, behavior, method, toBooleanNode, raiseNode, this); } else { - return !(lookupIter.execute(getClassNode.executeCached(this)) instanceof PNone); + TpSlots slots = getSlots.execute(inliningTarget, getClassNode.executeCached(this)); + return slots.tp_iter() != null; } } finally { gil.release(mustRelease); @@ -1728,9 +1714,8 @@ public boolean isIterator( // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, - @Shared("getClass") @Cached(inline = false) GetClassNode getClassNode, - @Cached(parameters = "Next") LookupCallableSlotInMRONode lookupNext, + @Exclusive @Cached PRaiseNode raiseNode, + @Cached PyIterCheckNode checkNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -1740,7 +1725,7 @@ public boolean isIterator( if (behavior != null) { return getValue.executeBoolean(inliningTarget, behavior, method, toBooleanNode, raiseNode, this); } else { - return lookupNext.execute(getClassNode.executeCached(this)) != PNone.NO_VALUE; + return checkNode.execute(inliningTarget, this); } } finally { gil.release(mustRelease); @@ -1756,9 +1741,8 @@ public boolean hasIteratorNextElement( // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, - @Cached GetNextNode getNextNode, - @Exclusive @Cached IsBuiltinObjectProfile exceptionProfile, + @Exclusive @Cached PRaiseNode raiseNode, + @Cached PyIterNextNode nextNode, @Exclusive @Cached GilNode gil, @CachedLibrary("this") InteropLibrary ilib, // GR-44020: make shared: @@ -1777,13 +1761,12 @@ public boolean hasIteratorNextElement( return true; } try { - nextElement = getNextNode.execute(null, this); - writeHiddenAttrNode.execute(inliningTarget, this, HiddenAttr.NEXT_ELEMENT, nextElement); - return true; - } catch (PException e) { - e.expect(inliningTarget, PythonBuiltinClassType.StopIteration, exceptionProfile); + nextElement = nextNode.execute(null, inliningTarget, this); + } catch (IteratorExhausted e) { return false; } + writeHiddenAttrNode.execute(inliningTarget, this, HiddenAttr.NEXT_ELEMENT, nextElement); + return true; } } throw UnsupportedMessageException.create(); @@ -1831,7 +1814,7 @@ public boolean isBoolean(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -1856,7 +1839,7 @@ public boolean isNumber(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -1881,7 +1864,7 @@ public boolean isString(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -1906,7 +1889,7 @@ public boolean fitsInByte(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -1931,7 +1914,7 @@ public boolean fitsInShort(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -1956,7 +1939,7 @@ public boolean fitsInInt(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -1981,7 +1964,7 @@ public boolean fitsInLong(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -2006,7 +1989,7 @@ public boolean fitsInFloat(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -2031,7 +2014,7 @@ public boolean fitsInDouble(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -2056,7 +2039,7 @@ public boolean fitsInBigInteger(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -2081,7 +2064,7 @@ public boolean asBoolean(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) throws UnsupportedMessageException { boolean mustRelease = gil.acquire(); @@ -2106,7 +2089,7 @@ public byte asByte(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaByteNode toByteNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) throws UnsupportedMessageException { boolean mustRelease = gil.acquire(); @@ -2131,7 +2114,7 @@ public short asShort(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaShortNode toShortNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) throws UnsupportedMessageException { boolean mustRelease = gil.acquire(); @@ -2156,7 +2139,7 @@ public int asInt(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode toIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) throws UnsupportedMessageException { boolean mustRelease = gil.acquire(); @@ -2181,7 +2164,7 @@ public long asLong(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaLongExactNode toLongNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) throws UnsupportedMessageException { boolean mustRelease = gil.acquire(); @@ -2206,7 +2189,7 @@ public float asFloat(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaDoubleNode toDoubleNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) throws UnsupportedMessageException { boolean mustRelease = gil.acquire(); @@ -2231,7 +2214,7 @@ public double asDouble(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaDoubleNode toDoubleNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) throws UnsupportedMessageException { boolean mustRelease = gil.acquire(); @@ -2278,7 +2261,7 @@ public String asString(@Bind("$node") Node inliningTarget, @Shared("getValue") @Cached GetInteropBehaviorValueNode getValue, @Cached CastToJavaStringNode toStringNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) throws UnsupportedMessageException { boolean mustRelease = gil.acquire(); @@ -2303,7 +2286,7 @@ public boolean hasHashEntries(@Bind("$node") Node inliningTarget, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -2329,7 +2312,7 @@ public long getHashSize( // GR-44020: make shared: @Exclusive @Cached CastToJavaLongExactNode toLongNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) throws UnsupportedMessageException { boolean mustRelease = gil.acquire(); @@ -2443,7 +2426,7 @@ public boolean isHashEntryReadable(Object key, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -2469,7 +2452,7 @@ public boolean isHashEntryRemovable(Object key, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, // GR-44020: make shared: @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -2515,7 +2498,7 @@ public boolean isHashEntryModifiable(Object key, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("getBehavior") @Cached GetInteropBehaviorNode getBehavior, @Shared("getValue") @Cached GetInteropBehaviorValueNode getValue, // GR-44020: make shared: @@ -2541,7 +2524,7 @@ public boolean isHashEntryInsertable(Object key, // GR-44020: make shared: @Exclusive @Cached CastToJavaBooleanNode toBooleanNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("getBehavior") @Cached GetInteropBehaviorNode getBehavior, @Shared("getValue") @Cached GetInteropBehaviorValueNode getValue, // GR-44020: make shared: @@ -2612,7 +2595,7 @@ public byte readBufferByte(long byteOffset, // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode toIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("bufferLib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) throws UnsupportedMessageException, InvalidBufferOffsetException { if (bufferLib.isBuffer(this)) { int offset = toIntNode.executeWithThrow(inliningTarget, byteOffset, raiseNode, PythonBuiltinClassType.OverflowError); @@ -2628,7 +2611,7 @@ public void writeBufferByte(long byteOffset, byte value, @Bind("$node") Node inl // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode toIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("bufferLib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) throws UnsupportedMessageException, InvalidBufferOffsetException { if (bufferLib.isBuffer(this)) { int offset = toIntNode.executeWithThrow(inliningTarget, byteOffset, raiseNode, PythonBuiltinClassType.OverflowError); @@ -2645,7 +2628,7 @@ public short readBufferShort(ByteOrder order, long byteOffset, // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode toIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("bufferLib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) throws UnsupportedMessageException, InvalidBufferOffsetException { if (bufferLib.isBuffer(this)) { int offset = toIntNode.executeWithThrow(inliningTarget, byteOffset, raiseNode, PythonBuiltinClassType.OverflowError); @@ -2661,7 +2644,7 @@ public void writeBufferShort(ByteOrder order, long byteOffset, short value, @Bin // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode toIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("bufferLib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) throws UnsupportedMessageException, InvalidBufferOffsetException { if (bufferLib.isBuffer(this)) { int offset = toIntNode.executeWithThrow(inliningTarget, byteOffset, raiseNode, PythonBuiltinClassType.OverflowError); @@ -2678,7 +2661,7 @@ public int readBufferInt(ByteOrder order, long byteOffset, // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode toIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("bufferLib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) throws UnsupportedMessageException, InvalidBufferOffsetException { if (bufferLib.isBuffer(this)) { int offset = toIntNode.executeWithThrow(inliningTarget, byteOffset, raiseNode, PythonBuiltinClassType.OverflowError); @@ -2694,7 +2677,7 @@ public void writeBufferInt(ByteOrder order, long byteOffset, int value, @Bind("$ // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode toIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("bufferLib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) throws UnsupportedMessageException, InvalidBufferOffsetException { if (bufferLib.isBuffer(this)) { int offset = toIntNode.executeWithThrow(inliningTarget, byteOffset, raiseNode, PythonBuiltinClassType.OverflowError); @@ -2711,7 +2694,7 @@ public long readBufferLong(ByteOrder order, long byteOffset, // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode toIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("bufferLib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) throws UnsupportedMessageException, InvalidBufferOffsetException { if (bufferLib.isBuffer(this)) { int offset = toIntNode.executeWithThrow(inliningTarget, byteOffset, raiseNode, PythonBuiltinClassType.OverflowError); @@ -2727,7 +2710,7 @@ public void writeBufferLong(ByteOrder order, long byteOffset, long value, @Bind( // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode toIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("bufferLib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) throws UnsupportedMessageException, InvalidBufferOffsetException { if (bufferLib.isBuffer(this)) { int offset = toIntNode.executeWithThrow(inliningTarget, byteOffset, raiseNode, PythonBuiltinClassType.OverflowError); @@ -2744,7 +2727,7 @@ public float readBufferFloat(ByteOrder order, long byteOffset, // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode toIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("bufferLib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) throws UnsupportedMessageException, InvalidBufferOffsetException { if (bufferLib.isBuffer(this)) { int offset = toIntNode.executeWithThrow(inliningTarget, byteOffset, raiseNode, PythonBuiltinClassType.OverflowError); @@ -2761,7 +2744,7 @@ public void writeBufferFloat(ByteOrder order, long byteOffset, float value, // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode toIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("bufferLib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) throws UnsupportedMessageException, InvalidBufferOffsetException { if (bufferLib.isBuffer(this)) { int offset = toIntNode.executeWithThrow(inliningTarget, byteOffset, raiseNode, PythonBuiltinClassType.OverflowError); @@ -2778,7 +2761,7 @@ public double readBufferDouble(ByteOrder order, long byteOffset, // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode toIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("bufferLib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) throws UnsupportedMessageException, InvalidBufferOffsetException { if (bufferLib.isBuffer(this)) { int offset = toIntNode.executeWithThrow(inliningTarget, byteOffset, raiseNode, PythonBuiltinClassType.OverflowError); @@ -2795,7 +2778,7 @@ public void writeBufferDouble(ByteOrder order, long byteOffset, double value, // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode toIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("bufferLib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) throws UnsupportedMessageException, InvalidBufferOffsetException { if (bufferLib.isBuffer(this)) { int offset = toIntNode.executeWithThrow(inliningTarget, byteOffset, raiseNode, PythonBuiltinClassType.OverflowError); @@ -2812,7 +2795,7 @@ public void readBuffer(long byteOffset, byte[] destination, int destinationOffse // GR-44020: make shared: @Exclusive @Cached CastToJavaIntExactNode toIntNode, // GR-44020: make shared: - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Shared("bufferLib") @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) throws UnsupportedMessageException, InvalidBufferOffsetException { if (bufferLib.isBuffer(this)) { if (length < 0 || (destination.length - destinationOffset > length)) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayBuiltins.java index 329a6cbf18..5185e3e890 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayBuiltins.java @@ -39,19 +39,11 @@ import static com.oracle.graal.python.nodes.BuiltinNames.J_EXTEND; import static com.oracle.graal.python.nodes.BuiltinNames.T_ARRAY; import static com.oracle.graal.python.nodes.ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP; +import static com.oracle.graal.python.nodes.ErrorMessages.S_TAKES_AT_LEAST_D_ARGUMENTS_D_GIVEN; +import static com.oracle.graal.python.nodes.ErrorMessages.S_TAKES_AT_MOST_D_ARGUMENTS_D_GIVEN; +import static com.oracle.graal.python.nodes.ErrorMessages.S_TAKES_NO_KEYWORD_ARGS; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DICT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CONTAINS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IADD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE_EX__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.nodes.StringLiterals.T_COMMA_SPACE; import static com.oracle.graal.python.nodes.StringLiterals.T_LBRACKET; import static com.oracle.graal.python.nodes.StringLiterals.T_LPAREN; @@ -63,9 +55,11 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -77,60 +71,67 @@ import com.oracle.graal.python.builtins.objects.array.ArrayNodes.GetValueNode; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; +import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; import com.oracle.graal.python.builtins.objects.common.IndexNodes.NormalizeIndexNode; import com.oracle.graal.python.builtins.objects.common.SequenceNodes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; +import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.module.PythonModule; +import com.oracle.graal.python.builtins.objects.range.PIntRange; import com.oracle.graal.python.builtins.objects.slice.PSlice; import com.oracle.graal.python.builtins.objects.slice.SliceNodes; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringCheckedNode; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.SqConcatBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotMpAssSubscript.MpAssSubscriptBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqItemBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqRepeatBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqAssItem.SqAssItemBuiltinNode; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyIndexCheckNode; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyNumberIndexNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.lib.PyObjectGetIter; -import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.lib.PyObjectLookupAttr; +import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode; +import com.oracle.graal.python.lib.PyObjectRichCompare; import com.oracle.graal.python.lib.PyObjectRichCompareBool; import com.oracle.graal.python.lib.PyObjectSizeNode; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; import com.oracle.graal.python.nodes.builtins.ListNodes; -import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; -import com.oracle.graal.python.nodes.expression.BinaryComparisonNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; +import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassExactProfile; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.BufferFormat; -import com.oracle.graal.python.util.ComparisonOp; import com.oracle.graal.python.util.OverflowException; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; @@ -157,6 +158,7 @@ import com.oracle.truffle.api.profiles.InlinedByteValueProfile; import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.api.strings.TruffleString; import com.oracle.truffle.api.strings.TruffleStringBuilder; import com.oracle.truffle.api.strings.TruffleStringIterator; @@ -172,41 +174,255 @@ protected List> getNodeFa return ArrayBuiltinsFactory.getFactories(); } + // array.array(typecode[, initializer]) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = J_ARRAY, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + abstract static class ArrayNode extends PythonVarargsBuiltinNode { + + @Specialization(guards = "args.length == 1 || args.length == 2") + static Object array2(VirtualFrame frame, Object cls, Object[] args, PKeyword[] kwargs, + @Bind("this") Node inliningTarget, + @Cached InlinedConditionProfile hasInitializerProfile, + @Cached IsBuiltinClassExactProfile isNotSubtypeProfile, + @Cached CastToTruffleStringCheckedNode cast, + @Cached ArrayNodeInternal arrayNodeInternal, + @Cached PRaiseNode raise) { + if (isNotSubtypeProfile.profileClass(inliningTarget, cls, PythonBuiltinClassType.PArray)) { + if (kwargs.length != 0) { + throw raise.raise(inliningTarget, TypeError, S_TAKES_NO_KEYWORD_ARGS, "array.array()"); + } + } + Object initializer = hasInitializerProfile.profile(inliningTarget, args.length == 2) ? args[1] : PNone.NO_VALUE; + return arrayNodeInternal.execute(frame, inliningTarget, cls, cast.cast(inliningTarget, args[0], ErrorMessages.ARG_1_MUST_BE_UNICODE_NOT_P, args[0]), initializer); + } + + @Fallback + @SuppressWarnings("unused") + Object error(Object cls, Object[] args, PKeyword[] kwargs) { + if (args.length < 2) { + throw PRaiseNode.raiseStatic(this, TypeError, S_TAKES_AT_LEAST_D_ARGUMENTS_D_GIVEN, T_ARRAY, 2, args.length); + } else { + throw PRaiseNode.raiseStatic(this, TypeError, S_TAKES_AT_MOST_D_ARGUMENTS_D_GIVEN, T_ARRAY, 3, args.length); + } + } + + // multiple non-inlined specializations share nodes + @SuppressWarnings("truffle-interpreted-performance") + @ImportStatic(PGuards.class) + @GenerateInline + @GenerateCached(false) + abstract static class ArrayNodeInternal extends Node { + + public abstract PArray execute(VirtualFrame frame, Node inliningTarget, Object cls, TruffleString typeCode, Object initializer); + + @Specialization(guards = "isNoValue(initializer)") + static PArray array(Node inliningTarget, Object cls, TruffleString typeCode, @SuppressWarnings("unused") PNone initializer, + @Shared @Cached GetFormatCheckedNode getFormatCheckedNode, + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) { + BufferFormat format = getFormatCheckedNode.execute(inliningTarget, typeCode); + return PFactory.createArray(language, cls, getInstanceShape.execute(cls), typeCode, format); + } + + @Specialization + @InliningCutoff + static PArray arrayWithRangeInitializer(Node inliningTarget, Object cls, TruffleString typeCode, PIntRange range, + @Shared @Cached GetFormatCheckedNode getFormatCheckedNode, + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Exclusive @Cached ArrayNodes.PutValueNode putValueNode) { + BufferFormat format = getFormatCheckedNode.execute(inliningTarget, typeCode); + PArray array; + try { + array = PFactory.createArray(language, cls, getInstanceShape.execute(cls), typeCode, format, range.getIntLength()); + } catch (OverflowException e) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); + } + + int start = range.getIntStart(); + int step = range.getIntStep(); + int len = range.getIntLength(); + + for (int index = 0, value = start; index < len; index++, value += step) { + putValueNode.execute(null, inliningTarget, array, index, value); + } + + return array; + } + + @Specialization + static PArray arrayWithBytesInitializer(VirtualFrame frame, Node inliningTarget, Object cls, TruffleString typeCode, PBytesLike bytes, + @Shared @Cached GetFormatCheckedNode getFormatCheckedNode, + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached(inline = false) ArrayBuiltins.FromBytesNode fromBytesNode) { + BufferFormat format = getFormatCheckedNode.execute(inliningTarget, typeCode); + PArray array = PFactory.createArray(language, cls, getInstanceShape.execute(cls), typeCode, format); + fromBytesNode.executeWithoutClinic(frame, array, bytes); + return array; + } + + @Specialization(guards = "isString(initializer)") + @InliningCutoff + static PArray arrayWithStringInitializer(VirtualFrame frame, Node inliningTarget, Object cls, TruffleString typeCode, Object initializer, + @Shared @Cached GetFormatCheckedNode getFormatCheckedNode, + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached(inline = false) ArrayBuiltins.FromUnicodeNode fromUnicodeNode, + @Cached PRaiseNode raise) { + BufferFormat format = getFormatCheckedNode.execute(inliningTarget, typeCode); + if (format != BufferFormat.UNICODE) { + throw raise.raise(inliningTarget, TypeError, ErrorMessages.CANNOT_USE_STR_TO_INITIALIZE_ARRAY, typeCode); + } + PArray array = PFactory.createArray(language, cls, getInstanceShape.execute(cls), typeCode, format); + fromUnicodeNode.execute(frame, array, initializer); + return array; + } + + @Specialization + @InliningCutoff + static PArray arrayArrayInitializer(VirtualFrame frame, Node inliningTarget, Object cls, TruffleString typeCode, PArray initializer, + @Shared @Cached GetFormatCheckedNode getFormatCheckedNode, + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Exclusive @Cached ArrayNodes.PutValueNode putValueNode, + @Cached ArrayNodes.GetValueNode getValueNode) { + BufferFormat format = getFormatCheckedNode.execute(inliningTarget, typeCode); + try { + int length = initializer.getLength(); + PArray array = PFactory.createArray(language, cls, getInstanceShape.execute(cls), typeCode, format, length); + for (int i = 0; i < length; i++) { + putValueNode.execute(frame, inliningTarget, array, i, getValueNode.execute(inliningTarget, initializer, i)); + } + return array; + } catch (OverflowException e) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); + } + } + + @Specialization(guards = "!isBytes(initializer)") + @InliningCutoff + static PArray arraySequenceInitializer(VirtualFrame frame, Node inliningTarget, Object cls, TruffleString typeCode, PSequence initializer, + @Shared @Cached GetFormatCheckedNode getFormatCheckedNode, + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Exclusive @Cached ArrayNodes.PutValueNode putValueNode, + @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode, + @Cached SequenceStorageNodes.GetItemScalarNode getItemNode) { + BufferFormat format = getFormatCheckedNode.execute(inliningTarget, typeCode); + SequenceStorage storage = getSequenceStorageNode.execute(inliningTarget, initializer); + int length = storage.length(); + try { + PArray array = PFactory.createArray(language, cls, getInstanceShape.execute(cls), typeCode, format, length); + for (int i = 0; i < length; i++) { + putValueNode.execute(frame, inliningTarget, array, i, getItemNode.execute(inliningTarget, storage, i)); + } + return array; + } catch (OverflowException e) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); + } + } + + @Specialization(guards = {"!isBytes(initializer)", "!isString(initializer)", "!isPSequence(initializer)"}) + @InliningCutoff + static PArray arrayIteratorInitializer(VirtualFrame frame, Node inliningTarget, Object cls, TruffleString typeCode, Object initializer, + @Cached PyObjectGetIter getIter, + @Shared @Cached GetFormatCheckedNode getFormatCheckedNode, + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Exclusive @Cached ArrayNodes.PutValueNode putValueNode, + @Cached PyIterNextNode nextNode, + @Cached ArrayNodes.SetLengthNode setLengthNode, + @Cached ArrayNodes.EnsureCapacityNode ensureCapacityNode) { + Object iter = getIter.execute(frame, inliningTarget, initializer); + + BufferFormat format = getFormatCheckedNode.execute(inliningTarget, typeCode); + PArray array = PFactory.createArray(language, cls, getInstanceShape.execute(cls), typeCode, format); + + int length = 0; + while (true) { + try { + Object nextValue = nextNode.execute(frame, inliningTarget, iter); + try { + length = PythonUtils.addExact(length, 1); + ensureCapacityNode.execute(inliningTarget, array, length); + } catch (OverflowException e) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); + } + putValueNode.execute(frame, inliningTarget, array, length - 1, nextValue); + } catch (IteratorExhausted e) { + break; + } + } + + setLengthNode.execute(inliningTarget, array, length); + return array; + } + + @GenerateInline + @GenerateCached(false) + abstract static class GetFormatCheckedNode extends Node { + abstract BufferFormat execute(Node inliningTarget, TruffleString typeCode); + + @Specialization + static BufferFormat get(Node inliningTarget, TruffleString typeCode, + @Cached(inline = false) TruffleString.CodePointLengthNode lengthNode, + @Cached(inline = false) TruffleString.CodePointAtIndexNode atIndexNode, + @Cached PRaiseNode raise, + @Cached(value = "createIdentityProfile()", inline = false) ValueProfile valueProfile) { + if (lengthNode.execute(typeCode, TS_ENCODING) != 1) { + throw raise.raise(inliningTarget, TypeError, ErrorMessages.ARRAY_ARG_1_MUST_BE_UNICODE); + } + BufferFormat format = BufferFormat.forArray(typeCode, lengthNode, atIndexNode); + if (format == null) { + throw raise.raise(inliningTarget, ValueError, ErrorMessages.BAD_TYPECODE); + } + return valueProfile.profile(format); + } + } + } + } + @Slot(value = SlotKind.sq_concat, isComplex = true) @GenerateNodeFactory abstract static class ConcatNode extends SqConcatBuiltinNode { @Specialization(guards = "left.getFormat() == right.getFormat()") Object concat(PArray left, PArray right, @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { try { int newLength = PythonUtils.addExact(left.getLength(), right.getLength()); int itemShift = left.getItemSizeShift(); - PArray newArray = factory.createArray(left.getFormatString(), left.getFormat(), newLength); + PArray newArray = PFactory.createArray(language, left.getFormatString(), left.getFormat(), newLength); bufferLib.readIntoBuffer(left.getBuffer(), 0, newArray.getBuffer(), 0, left.getLength() << itemShift, bufferLib); bufferLib.readIntoBuffer(right.getBuffer(), 0, newArray.getBuffer(), left.getLength() << itemShift, right.getLength() << itemShift, bufferLib); return newArray; } catch (OverflowException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(this, MemoryError); + throw PRaiseNode.raiseStatic(this, MemoryError); } } @Specialization(guards = "left.getFormat() != right.getFormat()") @SuppressWarnings("unused") static Object error(PArray left, PArray right, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, BAD_ARG_TYPE_FOR_BUILTIN_OP); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, BAD_ARG_TYPE_FOR_BUILTIN_OP); } @Fallback static Object error(@SuppressWarnings("unused") Object left, Object right, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CAN_ONLY_APPEND_ARRAY_TO_ARRAY, right); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CAN_ONLY_APPEND_ARRAY_TO_ARRAY, right); } } - @Builtin(name = J___IADD__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.sq_inplace_concat, isComplex = true) @GenerateNodeFactory abstract static class IAddNode extends PythonBinaryBuiltinNode { @Specialization @@ -218,8 +434,8 @@ static Object concat(VirtualFrame frame, PArray left, PArray right, @Fallback static Object error(@SuppressWarnings("unused") Object left, Object right, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CAN_ONLY_EXTEND_ARRAY_WITH_ARRAY, right); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CAN_ONLY_EXTEND_ARRAY_WITH_ARRAY, right); } } @@ -232,7 +448,7 @@ static PArray concat(PArray self, int valueIn, @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, @Cached InlinedBranchProfile negativeSize, @Cached InlinedLoopConditionProfile loopProfile, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { int value = valueIn; if (value < 0) { negativeSize.enter(inliningTarget); @@ -240,7 +456,7 @@ static PArray concat(PArray self, int valueIn, } try { int newLength = Math.max(PythonUtils.multiplyExact(self.getLength(), value), 0); - PArray newArray = factory.createArray(self.getFormatString(), self.getFormat(), newLength); + PArray newArray = PFactory.createArray(language, self.getFormatString(), self.getFormat(), newLength); int segmentLength = self.getBytesLength(); loopProfile.profileCounted(inliningTarget, value); for (int i = 0; loopProfile.inject(inliningTarget, i < value); i++) { @@ -249,7 +465,7 @@ static PArray concat(PArray self, int valueIn, return newArray; } catch (OverflowException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); } } @@ -259,17 +475,16 @@ static PArray doZeroSize(Object self, @SuppressWarnings("unused") int value) { } } - @Builtin(name = J___IMUL__, minNumOfPositionalArgs = 2, numOfPositionalOnlyArgs = 2, parameterNames = {"$self", "value"}) - @ArgumentClinic(name = "value", conversion = ArgumentClinic.ClinicConversion.Index) + @Slot(value = SlotKind.sq_inplace_repeat, isComplex = true) @GenerateNodeFactory - abstract static class IMulNode extends PythonBinaryClinicBuiltinNode { + abstract static class IMulNode extends SqRepeatBuiltinNode { @Specialization static Object concat(PArray self, int value, @Bind("this") Node inliningTarget, @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, @Cached ArrayNodes.EnsureCapacityNode ensureCapacityNode, @Cached ArrayNodes.SetLengthNode setLengthNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { int newLength = Math.max(PythonUtils.multiplyExact(self.getLength(), value), 0); if (newLength != self.getLength()) { @@ -284,227 +499,109 @@ static Object concat(PArray self, int value, return self; } catch (OverflowException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); - } - } - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return ArrayBuiltinsClinicProviders.IMulNodeClinicProviderGen.INSTANCE; - } - } - - @GenerateInline - @GenerateCached(false) - @ImportStatic({BufferFormat.class, PGuards.class}) - abstract static class EqNeHelperNode extends Node { - - abstract Object execute(VirtualFrame frame, Node inliningTarget, Object left, Object right, ComparisonOp op); - - @Specialization(guards = {"left.getFormat() == right.getFormat()", "!isFloatingPoint(left.getFormat())"}) - static boolean eqBytes(PArray left, PArray right, ComparisonOp op, - @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib) { - if (left.getBytesLength() != right.getBytesLength()) { - return op == ComparisonOp.NE; - } - for (int i = 0; i < left.getBytesLength(); i++) { - if (bufferLib.readByte(left.getBuffer(), i) != bufferLib.readByte(right.getBuffer(), i)) { - return op == ComparisonOp.NE; - } - } - return op == ComparisonOp.EQ; - } - - @Specialization(guards = "left.getFormat() != right.getFormat()") - static boolean eqItems(VirtualFrame frame, Node inliningTarget, PArray left, PArray right, ComparisonOp op, - @Cached PyObjectRichCompareBool.EqNode eqNode, - @Exclusive @Cached ArrayNodes.GetValueNode getLeft, - @Exclusive @Cached ArrayNodes.GetValueNode getRight) { - if (left.getLength() != right.getLength()) { - return op == ComparisonOp.NE; + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); } - for (int i = 0; i < left.getLength(); i++) { - if (!eqNode.compare(frame, inliningTarget, getLeft.execute(inliningTarget, left, i), getRight.execute(inliningTarget, right, i))) { - return op == ComparisonOp.NE; - } - } - return op == ComparisonOp.EQ; - } - - // Separate specialization for float/double is needed because of NaN comparisons - @Specialization(guards = {"left.getFormat() == right.getFormat()", "isFloatingPoint(left.getFormat())"}) - static boolean eqDoubles(Node inliningTarget, PArray left, PArray right, ComparisonOp op, - @Exclusive @Cached ArrayNodes.GetValueNode getLeft, - @Exclusive @Cached ArrayNodes.GetValueNode getRight) { - if (left.getLength() != right.getLength()) { - return op == ComparisonOp.NE; - } - for (int i = 0; i < left.getLength(); i++) { - double leftValue = (Double) getLeft.execute(inliningTarget, left, i); - double rightValue = (Double) getRight.execute(inliningTarget, right, i); - if (leftValue != rightValue) { - return op == ComparisonOp.NE; - } - } - return op == ComparisonOp.EQ; - } - - @Specialization(guards = "!isArray(right)") - @SuppressWarnings("unused") - static Object eq(PArray left, Object right, ComparisonOp op) { - return PNotImplemented.NOT_IMPLEMENTED; - } - - @Specialization(guards = "!isArray(left)") - @SuppressWarnings("unused") - static Object error(Object left, Object right, ComparisonOp op, - @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, op.builtinName, J_ARRAY + "." + J_ARRAY, left); } } - @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.tp_richcompare, isComplex = true) @GenerateNodeFactory - abstract static class EqNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object eqBytes(VirtualFrame frame, Object left, Object right, - @Bind("this") Node inliningTarget, - @Cached EqNeHelperNode helperNode) { - return helperNode.execute(frame, inliningTarget, left, right, ComparisonOp.EQ); - } - } - - @Builtin(name = J___NE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class NeNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object eqBytes(VirtualFrame frame, Object left, Object right, - @Bind("this") Node inliningTarget, - @Cached EqNeHelperNode helperNode) { - return helperNode.execute(frame, inliningTarget, left, right, ComparisonOp.NE); - } - } - - @GenerateInline - @GenerateCached(false) @ImportStatic({BufferFormat.class, PGuards.class}) - abstract static class ComparisonHelperNode extends Node { - - abstract Object execute(VirtualFrame frame, Node inliningTarget, Object left, Object right, ComparisonOp op, BinaryComparisonNode compareNode); + abstract static class ArrayRichCmpNode extends TpSlotRichCompare.RichCmpBuiltinNode { @Specialization(guards = "!isFloatingPoint(left.getFormat()) || (left.getFormat() != right.getFormat())") - static boolean cmpItems(VirtualFrame frame, Node inliningTarget, PArray left, PArray right, ComparisonOp op, BinaryComparisonNode compareNode, - @Cached PyObjectRichCompareBool.EqNode eqNode, - @Exclusive @Cached PyObjectIsTrueNode coerceToBooleanNode, + static Object cmpItems(VirtualFrame frame, PArray left, PArray right, RichCmpOp op, + @Bind Node inliningTarget, + @Exclusive @Cached InlinedBranchProfile fullCmpProfile, + @Exclusive @Cached PyObjectRichCompareBool richCmpEqNode, + @Exclusive @Cached PyObjectRichCompare richCmpOpNode, @Exclusive @Cached ArrayNodes.GetValueNode getLeft, - @Exclusive @Cached ArrayNodes.GetValueNode getRight) { + @Exclusive @Cached ArrayNodes.GetValueNode getRight, + @Exclusive @Cached InlinedLoopConditionProfile loopProfile) { + if (left.getLength() != right.getLength() && op.isEqOrNe()) { + // the same fast-path as CPython + return op == RichCmpOp.Py_NE; + } + fullCmpProfile.enter(inliningTarget); int commonLength = Math.min(left.getLength(), right.getLength()); - for (int i = 0; i < commonLength; i++) { + loopProfile.profileCounted(inliningTarget, commonLength); // ignoring the early exit + for (int i = 0; loopProfile.inject(inliningTarget, i < commonLength); i++) { Object leftValue = getLeft.execute(inliningTarget, left, i); Object rightValue = getRight.execute(inliningTarget, right, i); - if (!eqNode.compare(frame, inliningTarget, leftValue, rightValue)) { - return coerceToBooleanNode.execute(frame, compareNode.executeObject(frame, leftValue, rightValue)); + if (!richCmpEqNode.execute(frame, inliningTarget, leftValue, rightValue, RichCmpOp.Py_EQ)) { + if (op == RichCmpOp.Py_EQ) { + return false; + } else if (op == RichCmpOp.Py_NE) { + return true; + } + return richCmpOpNode.execute(frame, inliningTarget, leftValue, rightValue, op); } } - return op.cmpResultToBool(left.getLength() - right.getLength()); + if (op.isEqOrNe()) { + return op.isEq(); + } + return op.compareResultToBool(left.getLength() - right.getLength()); } - // Separate specialization for float/double is needed because of NaN comparisons + // Separate specialization for float/double is needed because, normally in + // PyObjectRichCompareBool we treat NaNs as equals, this is because CPython does identity + // check in PyObjectRichCompareBool. We do not really have identity for doubles, so we + // cannot say if NaNs, which are by definition not equal (PyObjectRichCompare always returns + // false for NaN and Nan), are identical or not. So we choose that all NaNs with equal bit + // patterns are identical. This is however different for arrays, where the identity cannot + // be preserved, so here we know for sure that if we see two NaNs, PyObjectRichCompareBool + // would return false on CPython, and so we do the same. This is tested in CPython tests. @Specialization(guards = {"isFloatingPoint(left.getFormat())", "left.getFormat() == right.getFormat()"}) - static boolean cmpDoubles(VirtualFrame frame, Node inliningTarget, PArray left, PArray right, ComparisonOp op, BinaryComparisonNode compareNode, - @Exclusive @Cached PyObjectIsTrueNode coerceToBooleanNode, + static boolean cmpDoubles(VirtualFrame frame, PArray left, PArray right, RichCmpOp op, + @Bind("$node") Node inliningTarget, + @Exclusive @Cached InlinedBranchProfile fullCmpProfile, @Exclusive @Cached ArrayNodes.GetValueNode getLeft, - @Exclusive @Cached ArrayNodes.GetValueNode getRight) { + @Exclusive @Cached ArrayNodes.GetValueNode getRight, + @Exclusive @Cached InlinedLoopConditionProfile loopProfile) { + if (left.getLength() != right.getLength() && op.isEqOrNe()) { + // the same fast-path as CPython + return op == RichCmpOp.Py_NE; + } + fullCmpProfile.enter(inliningTarget); int commonLength = Math.min(left.getLength(), right.getLength()); - for (int i = 0; i < commonLength; i++) { + loopProfile.profileCounted(inliningTarget, commonLength); // ignoring the early exit + for (int i = 0; loopProfile.inject(inliningTarget, i < commonLength); i++) { double leftValue = (Double) getLeft.execute(inliningTarget, left, i); double rightValue = (Double) getRight.execute(inliningTarget, right, i); if (leftValue != rightValue) { - return coerceToBooleanNode.execute(frame, compareNode.executeObject(frame, leftValue, rightValue)); + return op.compare(leftValue, rightValue); } } - return op.cmpResultToBool(left.getLength() - right.getLength()); + if (op.isEqOrNe()) { + return op.isEq(); + } + return op.compareResultToBool(left.getLength() - right.getLength()); } @Specialization(guards = "!isArray(right)") @SuppressWarnings("unused") - static Object cmp(PArray left, Object right, ComparisonOp op, BinaryComparisonNode compareNode) { + static Object cmp(PArray left, Object right, RichCmpOp op) { return PNotImplemented.NOT_IMPLEMENTED; } @Specialization(guards = "!isArray(left)") @SuppressWarnings("unused") - static Object error(Object left, Object right, ComparisonOp op, BinaryComparisonNode compareNode, - @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, op.builtinName, J_ARRAY + "." + J_ARRAY, left); + static Object error(Object left, Object right, RichCmpOp op, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, op.getPythonName(), J_ARRAY + "." + J_ARRAY, left); } - } - @Builtin(name = J___LT__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.sq_contains, isComplex = true) @GenerateNodeFactory - abstract static class LtNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(VirtualFrame frame, Object left, Object right, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode, - @Cached BinaryComparisonNode.LtNode cmpNode) { - return helperNode.execute(frame, inliningTarget, left, right, ComparisonOp.LT, cmpNode); - } - } - - @Builtin(name = J___GT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class GtNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(VirtualFrame frame, Object left, Object right, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode, - @Cached BinaryComparisonNode.GtNode cmpNode) { - return helperNode.execute(frame, inliningTarget, left, right, ComparisonOp.GT, cmpNode); - } - } - - @Builtin(name = J___LE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class LeNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(VirtualFrame frame, Object left, Object right, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode, - @Cached BinaryComparisonNode.LeNode cmpNode) { - return helperNode.execute(frame, inliningTarget, left, right, ComparisonOp.LE, cmpNode); - } - } - - @Builtin(name = J___GE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class GeNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(VirtualFrame frame, Object left, Object right, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode, - @Cached BinaryComparisonNode.GeNode cmpNode) { - return helperNode.execute(frame, inliningTarget, left, right, ComparisonOp.GE, cmpNode); - } - } - - @Builtin(name = J___CONTAINS__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class ContainsNode extends PythonBinaryBuiltinNode { + abstract static class ContainsNode extends SqContainsBuiltinNode { @Specialization static boolean contains(VirtualFrame frame, PArray self, Object value, @Bind("this") Node inliningTarget, - @Cached PyObjectRichCompareBool.EqNode eqNode, + @Cached PyObjectRichCompareBool eqNode, @Cached ArrayNodes.GetValueNode getValueNode) { for (int i = 0; i < self.getLength(); i++) { - if (eqNode.compare(frame, inliningTarget, getValueNode.execute(inliningTarget, self, i), value)) { + if (eqNode.execute(frame, inliningTarget, getValueNode.execute(inliningTarget, self, i), value, RichCmpOp.Py_EQ)) { return true; } } @@ -512,13 +609,13 @@ static boolean contains(VirtualFrame frame, PArray self, Object value, } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization static TruffleString repr(VirtualFrame frame, PArray self, @Bind("this") Node inliningTarget, - @Cached("create(Repr)") LookupAndCallUnaryNode reprNode, + @Cached PyObjectReprAsTruffleStringNode repr, @Cached InlinedConditionProfile isEmptyProfile, @Cached InlinedConditionProfile isUnicodeProfile, @Cached CastToTruffleStringNode cast, @@ -536,7 +633,7 @@ static TruffleString repr(VirtualFrame frame, PArray self, if (isEmptyProfile.profile(inliningTarget, length != 0)) { if (isUnicodeProfile.profile(inliningTarget, self.getFormat() == BufferFormat.UNICODE)) { appendStringNode.execute(sb, T_COMMA_SPACE); - appendStringNode.execute(sb, cast.execute(inliningTarget, reprNode.executeObject(frame, toUnicodeNode.execute(frame, self)))); + appendStringNode.execute(sb, repr.execute(frame, inliningTarget, toUnicodeNode.execute(frame, self))); } else { appendStringNode.execute(sb, T_COMMA_SPACE); appendStringNode.execute(sb, T_LBRACKET); @@ -545,7 +642,7 @@ static TruffleString repr(VirtualFrame frame, PArray self, appendStringNode.execute(sb, T_COMMA_SPACE); } Object value = getValueNode.execute(inliningTarget, self, i); - appendStringNode.execute(sb, cast.execute(inliningTarget, reprNode.executeObject(frame, value))); + appendStringNode.execute(sb, cast.execute(inliningTarget, repr.execute(frame, inliningTarget, value))); } appendStringNode.execute(sb, T_RBRACKET); } @@ -561,12 +658,12 @@ abstract static class SqItemNode extends SqItemBuiltinNode { @Specialization static Object doIt(PArray self, int index, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached ArrayNodes.GetValueNode getValueNode) { return getItem(inliningTarget, self, index, raiseNode, getValueNode); } - private static Object getItem(Node inliningTarget, PArray self, int index, PRaiseNode.Lazy raiseNode, GetValueNode getValueNode) { + private static Object getItem(Node inliningTarget, PArray self, int index, PRaiseNode raiseNode, GetValueNode getValueNode) { checkBounds(inliningTarget, raiseNode, ErrorMessages.ARRAY_OUT_OF_BOUNDS, index, self.getLength()); return getValueNode.execute(inliningTarget, self, index); } @@ -579,7 +676,7 @@ abstract static class MpSubscriptNode extends MpSubscriptBuiltinNode { static Object doIndex(VirtualFrame frame, PArray self, Object idx, @Bind("this") Node inliningTarget, @Cached PyIndexCheckNode indexCheckNode, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached PyNumberAsSizeNode numberAsSizeNode, @Exclusive @Cached InlinedConditionProfile negativeIndexProfile, @Cached ArrayNodes.GetValueNode getValueNode) { @@ -601,13 +698,13 @@ static Object doSlice(PArray self, PSlice slice, @Exclusive @Cached InlinedConditionProfile simpleStepProfile, @Cached SliceNodes.SliceUnpack sliceUnpack, @Cached SliceNodes.AdjustIndices adjustIndices, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { PSlice.SliceInfo sliceInfo = adjustIndices.execute(inliningTarget, self.getLength(), sliceUnpack.execute(inliningTarget, slice)); int itemShift = itemShiftProfile.profile(inliningTarget, (byte) self.getItemSizeShift()); int itemsize = self.getItemSize(); PArray newArray; try { - newArray = factory.createArray(self.getFormatString(), self.getFormat(), sliceInfo.sliceLength); + newArray = PFactory.createArray(language, self.getFormatString(), self.getFormat(), sliceInfo.sliceLength); } catch (OverflowException e) { // It's a slice of existing array, the length cannot overflow throw CompilerDirectives.shouldNotReachHere(); @@ -624,8 +721,8 @@ static Object doSlice(PArray self, PSlice slice, } @InliningCutoff - private static PException raiseNonIntIndex(Node inliningTarget, Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ARRAY_INDICES_MUST_BE_INTS); + private static PException raiseNonIntIndex(Node inliningTarget, PRaiseNode raiseNode) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ARRAY_INDICES_MUST_BE_INTS); } } @@ -637,7 +734,7 @@ abstract static class SetItemNode extends SqAssItemBuiltinNode { static void setitem(VirtualFrame frame, PArray self, int index, Object value, @Bind("this") Node inliningTarget, @Cached ArrayNodes.PutValueNode putValueNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { checkBounds(inliningTarget, raiseNode, ErrorMessages.ARRAY_ASSIGN_OUT_OF_BOUNDS, index, self.getLength()); putValueNode.execute(frame, inliningTarget, self, index, value); } @@ -646,7 +743,7 @@ static void setitem(VirtualFrame frame, PArray self, int index, Object value, static void delitem(PArray self, int index, @SuppressWarnings("unused") Object value, @Bind("this") Node inliningTarget, @Cached DeleteArraySliceNode deleteSliceNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { checkBounds(inliningTarget, raiseNode, ErrorMessages.ARRAY_ASSIGN_OUT_OF_BOUNDS, index, self.getLength()); self.checkCanResize(inliningTarget, raiseNode); deleteSliceNode.execute(inliningTarget, self, index, 1); @@ -673,7 +770,7 @@ static void delitem(VirtualFrame frame, PArray self, Object idx, @SuppressWarnin @Shared @Cached PyNumberIndexNode indexNode, @Shared @Cached("forArrayAssign()") NormalizeIndexNode normalizeIndexNode, @Shared @Cached DeleteArraySliceNode deleteSliceNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { self.checkCanResize(inliningTarget, raiseNode); int index = normalizeIndexNode.execute(indexNode.execute(frame, inliningTarget, idx), self.getLength()); deleteSliceNode.execute(inliningTarget, self, index, 1); @@ -700,7 +797,7 @@ static void setitem(PArray self, PSlice slice, Object other, @Shared @Cached DeleteArraySliceNode deleteSliceNode, @Cached ArrayNodes.ShiftNode shiftNode, @Cached ArrayNodes.SetLengthNode setLengthNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int length = self.getLength(); PSlice.SliceInfo sliceInfo = adjustIndices.execute(inliningTarget, length, sliceUnpack.execute(inliningTarget, slice)); int start = sliceInfo.start; @@ -714,7 +811,7 @@ static void setitem(PArray self, PSlice slice, Object other, if (other instanceof PArray otherArray) { hasOtherProfile.enter(inliningTarget); if (self.getFormat() != otherArray.getFormat()) { - throw raiseNode.get(inliningTarget).raise(TypeError, BAD_ARG_TYPE_FOR_BUILTIN_OP); + throw raiseNode.raise(inliningTarget, TypeError, BAD_ARG_TYPE_FOR_BUILTIN_OP); } sourceBuffer = otherArray.getBuffer(); needed = otherArray.getLength(); @@ -730,7 +827,7 @@ static void setitem(PArray self, PSlice slice, Object other, needed = 0; } else { otherTypeErrorProfile.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CAN_ONLY_ASSIGN_ARRAY, other); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CAN_ONLY_ASSIGN_ARRAY, other); } if (step == 1) { simpleStepProfile.enter(inliningTarget); @@ -771,19 +868,19 @@ static void setitem(PArray self, PSlice slice, Object other, } } else { wrongLengthProfile.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.ATTEMPT_ASSIGN_ARRAY_OF_SIZE, needed, sliceLength); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.ATTEMPT_ASSIGN_ARRAY_OF_SIZE, needed, sliceLength); } } } - @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iter, isComplex = true) @GenerateNodeFactory abstract static class IterNode extends PythonUnaryBuiltinNode { @Specialization static Object getitem(PArray self, - @Cached PythonObjectFactory factory) { - return factory.createArrayIterator(self); + @Bind PythonLanguage language) { + return PFactory.createArrayIterator(language, self); } } @@ -814,14 +911,14 @@ static Object reduceLegacy(VirtualFrame frame, PArray self, @SuppressWarnings("u @Cached @Exclusive GetClassNode getClassNode, @Cached @Exclusive PyObjectLookupAttr lookupDict, @Cached ToListNode toListNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { Object cls = getClassNode.execute(inliningTarget, self); Object dict = lookupDict.execute(frame, inliningTarget, self, T___DICT__); if (dict == PNone.NO_VALUE) { dict = PNone.NONE; } - PTuple args = factory.createTuple(new Object[]{self.getFormatString(), toListNode.execute(frame, self)}); - return factory.createTuple(new Object[]{cls, args, dict}); + PTuple args = PFactory.createTuple(language, new Object[]{self.getFormatString(), toListNode.execute(frame, self)}); + return PFactory.createTuple(language, new Object[]{cls, args, dict}); } @Specialization(guards = "protocol >= 3") @@ -831,7 +928,7 @@ static Object reduce(VirtualFrame frame, PArray self, @SuppressWarnings("unused" @Cached @Exclusive PyObjectLookupAttr lookupDict, @Cached PyObjectGetAttr getReconstructor, @Cached ToBytesNode toBytesNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { PythonModule arrayModule = PythonContext.get(inliningTarget).lookupBuiltinModule(T_ARRAY); PArray.MachineFormat mformat = PArray.MachineFormat.forFormat(self.getFormat()); assert mformat != null; @@ -841,8 +938,8 @@ static Object reduce(VirtualFrame frame, PArray self, @SuppressWarnings("unused" dict = PNone.NONE; } Object reconstructor = getReconstructor.execute(frame, inliningTarget, arrayModule, T_ARRAY_RECONSTRUCTOR); - PTuple args = factory.createTuple(new Object[]{cls, self.getFormatString(), mformat.code, toBytesNode.execute(frame, self)}); - return factory.createTuple(new Object[]{reconstructor, args, dict}); + PTuple args = PFactory.createTuple(language, new Object[]{cls, self.getFormatString(), mformat.code, toBytesNode.execute(frame, self)}); + return PFactory.createTuple(language, new Object[]{reconstructor, args, dict}); } } @@ -873,8 +970,8 @@ abstract static class BufferInfoNode extends PythonUnaryBuiltinNode { @Specialization static Object bufferinfo(PArray self, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached ArrayNodes.EnsureNativeStorageNode ensureNativeStorageNode, - @Cached PythonObjectFactory factory, @CachedLibrary(limit = "1") InteropLibrary lib) { Object nativePointer = ensureNativeStorageNode.execute(inliningTarget, self).getPtr(); if (!(nativePointer instanceof Long)) { @@ -882,10 +979,10 @@ static Object bufferinfo(PArray self, nativePointer = lib.asPointer(nativePointer); } catch (UnsupportedMessageException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError); + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError); } } - return factory.createTuple(new Object[]{nativePointer, self.getLength()}); + return PFactory.createTuple(language, new Object[]{nativePointer, self.getLength()}); } } @@ -898,7 +995,7 @@ static Object append(VirtualFrame frame, PArray self, Object value, @Cached ArrayNodes.EnsureCapacityNode ensureCapacityNode, @Cached ArrayNodes.SetLengthNode setLengthNode, @Cached ArrayNodes.PutValueNode putValueNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { int index = self.getLength(); int newLength = PythonUtils.addExact(index, 1); @@ -909,7 +1006,7 @@ static Object append(VirtualFrame frame, PArray self, Object value, return PNone.NONE; } catch (OverflowException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); } } } @@ -923,7 +1020,7 @@ static Object extend(PArray self, PArray value, @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, @Exclusive @Cached ArrayNodes.EnsureCapacityNode ensureCapacityNode, @Exclusive @Cached ArrayNodes.SetLengthNode setLengthNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { try { int newLength = PythonUtils.addExact(self.getLength(), value.getLength()); if (newLength != self.getLength()) { @@ -936,7 +1033,7 @@ static Object extend(PArray self, PArray value, return PNone.NONE; } catch (OverflowException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); } } @@ -948,7 +1045,7 @@ static Object extend(VirtualFrame frame, PArray self, PSequence value, @Cached SequenceStorageNodes.GetItemScalarNode getItemNode, @Exclusive @Cached ArrayNodes.EnsureCapacityNode ensureCapacityNode, @Exclusive @Cached ArrayNodes.SetLengthNode setLengthNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { SequenceStorage storage = getSequenceStorageNode.execute(inliningTarget, value); int storageLength = storage.length(); try { @@ -959,7 +1056,7 @@ static Object extend(VirtualFrame frame, PArray self, PSequence value, } } catch (OverflowException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); } int length = self.getLength(); for (int i = 0; i < storageLength; i++) { @@ -976,20 +1073,18 @@ static Object extend(VirtualFrame frame, PArray self, PSequence value, static Object extend(VirtualFrame frame, PArray self, Object value, @Bind("this") Node inliningTarget, @Cached PyObjectGetIter getIter, + @Cached PyIterNextNode nextNode, @Exclusive @Cached ArrayNodes.PutValueNode putValueNode, - @Cached GetNextNode nextNode, - @Cached IsBuiltinObjectProfile errorProfile, @Exclusive @Cached ArrayNodes.EnsureCapacityNode ensureCapacityNode, @Exclusive @Cached ArrayNodes.SetLengthNode setLengthNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { Object iter = getIter.execute(frame, inliningTarget, value); int length = self.getLength(); while (true) { Object nextValue; try { - nextValue = nextNode.execute(frame, iter); - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); + nextValue = nextNode.execute(frame, inliningTarget, iter); + } catch (IteratorExhausted e) { break; } // The whole extend is not atomic, just individual inserts are. That's the same as @@ -1000,7 +1095,7 @@ static Object extend(VirtualFrame frame, PArray self, Object value, ensureCapacityNode.execute(inliningTarget, self, length); } catch (OverflowException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); } putValueNode.execute(frame, inliningTarget, self, length - 1, nextValue); setLengthNode.execute(inliningTarget, self, length); @@ -1012,10 +1107,10 @@ static Object extend(VirtualFrame frame, PArray self, Object value, @Specialization(guards = "self.getFormat() != value.getFormat()") @SuppressWarnings("unused") static Object error(PArray self, PArray value, - @Cached PRaiseNode raiseNode) { + @Bind("this") Node inliningTarget) { // CPython allows extending an array with an arbitrary iterable. Except a differently // formatted array. Weird - throw raiseNode.raise(TypeError, ErrorMessages.CAN_ONLY_EXTEND_WITH_ARRAY_OF_SAME_KIND); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CAN_ONLY_EXTEND_WITH_ARRAY_OF_SAME_KIND); } } @@ -1030,7 +1125,7 @@ static Object insert(VirtualFrame frame, PArray self, int inputIndex, Object val @Cached ArrayNodes.CheckValueNode checkValueNode, @Cached ArrayNodes.PutValueNode putValueNode, @Cached ArrayNodes.ShiftNode shiftNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int index = normalizeIndexNode.execute(inputIndex, self.getLength()); if (index > self.getLength()) { index = self.getLength(); @@ -1058,19 +1153,19 @@ abstract static class RemoveNode extends PythonBinaryBuiltinNode { @Specialization static Object remove(VirtualFrame frame, PArray self, Object value, @Bind("this") Node inliningTarget, - @Cached PyObjectRichCompareBool.EqNode eqNode, + @Cached PyObjectRichCompareBool eqNode, @Cached ArrayNodes.GetValueNode getValueNode, @Cached DeleteArraySliceNode deleteSliceNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { for (int i = 0; i < self.getLength(); i++) { Object item = getValueNode.execute(inliningTarget, self, i); - if (eqNode.compare(frame, inliningTarget, item, value)) { + if (eqNode.execute(frame, inliningTarget, item, value, RichCmpOp.Py_EQ)) { self.checkCanResize(inliningTarget, raiseNode); deleteSliceNode.execute(inliningTarget, self, i, 1); return PNone.NONE; } } - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.ARRAY_REMOVE_X_NOT_IN_ARRAY); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.ARRAY_REMOVE_X_NOT_IN_ARRAY); } } @@ -1084,9 +1179,9 @@ static Object pop(PArray self, int inputIndex, @Cached("forPop()") NormalizeIndexNode normalizeIndexNode, @Cached ArrayNodes.GetValueNode getValueNode, @Cached DeleteArraySliceNode deleteSliceNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (self.getLength() == 0) { - throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.POP_FROM_EMPTY_ARRAY); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.POP_FROM_EMPTY_ARRAY); } int index = normalizeIndexNode.execute(inputIndex, self.getLength()); Object value = getValueNode.execute(inliningTarget, self, index); @@ -1117,14 +1212,14 @@ static Object frombytes(VirtualFrame frame, PArray self, Object buffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached ArrayNodes.EnsureCapacityNode ensureCapacityNode, @Cached ArrayNodes.SetLengthNode setLengthNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { int itemShift = self.getItemSizeShift(); int oldSize = self.getLength(); try { int bufferLength = bufferLib.getBufferLength(buffer); if (!PythonUtils.isDivisible(bufferLength, itemShift)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.BYTES_ARRAY_NOT_MULTIPLE_OF_ARRAY_SIZE); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.BYTES_ARRAY_NOT_MULTIPLE_OF_ARRAY_SIZE); } int newLength = PythonUtils.addExact(oldSize, bufferLength >> itemShift); self.checkCanResize(inliningTarget, raiseNode); @@ -1133,7 +1228,7 @@ static Object frombytes(VirtualFrame frame, PArray self, Object buffer, bufferLib.readIntoBuffer(buffer, 0, self.getBuffer(), oldSize << itemShift, bufferLength, bufferLib); } catch (OverflowException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); } return PNone.NONE; } finally { @@ -1158,9 +1253,9 @@ static Object fromfile(VirtualFrame frame, PArray self, Object file, int n, @Cached PyObjectSizeNode sizeNode, @Cached InlinedConditionProfile nNegativeProfile, @Cached FromBytesNode fromBytesNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (nNegativeProfile.profile(inliningTarget, n < 0)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.NEGATIVE_COUNT); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NEGATIVE_COUNT); } int nbytes = n << self.getItemSizeShift(); Object readResult = callMethod.execute(frame, inliningTarget, file, T_READ, nbytes); @@ -1170,10 +1265,10 @@ static Object fromfile(VirtualFrame frame, PArray self, Object file, int n, // It would make more sense to check this before the frombytes call, but CPython // does it this way if (readLength != nbytes) { - throw raiseNode.get(inliningTarget).raise(EOFError, ErrorMessages.READ_DIDNT_RETURN_ENOUGH_BYTES); + throw raiseNode.raise(inliningTarget, EOFError, ErrorMessages.READ_DIDNT_RETURN_ENOUGH_BYTES); } } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.READ_DIDNT_RETURN_BYTES); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.READ_DIDNT_RETURN_BYTES); } return PNone.NONE; } @@ -1195,7 +1290,7 @@ static Object fromlist(VirtualFrame frame, PArray self, PList list, @Cached ArrayNodes.EnsureCapacityNode ensureCapacityNode, @Cached ArrayNodes.SetLengthNode setLengthNode, @Cached ArrayNodes.PutValueNode putValueNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { SequenceStorage storage = getSequenceStorageNode.execute(inliningTarget, list); int length = storage.length(); @@ -1209,15 +1304,15 @@ static Object fromlist(VirtualFrame frame, PArray self, PList list, return PNone.NONE; } catch (OverflowException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); } } @Fallback @SuppressWarnings("unused") static Object error(Object self, Object arg, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.ARG_MUST_BE_LIST); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.ARG_MUST_BE_LIST); } } @@ -1235,7 +1330,7 @@ static Object fromunicode(VirtualFrame frame, PArray self, TruffleString str, @Cached TruffleString.CreateCodePointIteratorNode createCodePointIteratorNode, @Cached TruffleStringIterator.NextNode nextNode, @Cached TruffleString.FromCodePointNode fromCodePointNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { int length = codePointLengthNode.execute(str, TS_ENCODING); int newLength = PythonUtils.addExact(self.getLength(), length); @@ -1251,15 +1346,15 @@ static Object fromunicode(VirtualFrame frame, PArray self, TruffleString str, return PNone.NONE; } catch (OverflowException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, MemoryError); + throw PRaiseNode.raiseStatic(inliningTarget, MemoryError); } } @Fallback @SuppressWarnings("unused") static Object error(Object self, Object arg, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.FROMUNICODE_ARG_MUST_BE_STR_NOT_P, arg); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.FROMUNICODE_ARG_MUST_BE_STR_NOT_P, arg); } @Override @@ -1274,10 +1369,10 @@ abstract static class ToBytesNode extends PythonUnaryBuiltinNode { @Specialization Object tobytes(PArray self, @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { byte[] bytes = new byte[self.getBytesLength()]; bufferLib.readIntoByteArray(self.getBuffer(), 0, bytes, 0, bytes.length); - return factory.createBytes(bytes); + return PFactory.createBytes(language, bytes); } } @@ -1301,9 +1396,9 @@ static TruffleString tounicode(PArray self, @Cached ArrayNodes.GetValueNode getValueNode, @Cached TruffleStringBuilder.AppendStringNode appendStringNode, @Cached TruffleStringBuilder.ToStringNode toStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (formatProfile.profile(inliningTarget, self.getFormat() != BufferFormat.UNICODE)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MAY_ONLY_BE_CALLED_ON_UNICODE_TYPE_ARRAYS); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MAY_ONLY_BE_CALLED_ON_UNICODE_TYPE_ARRAYS); } TruffleStringBuilder sb = TruffleStringBuilder.create(TS_ENCODING); int length = self.getLength(); @@ -1320,9 +1415,9 @@ abstract static class ToFileNode extends PythonBinaryBuiltinNode { @Specialization static Object tofile(VirtualFrame frame, PArray self, Object file, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, - @Cached PyObjectCallMethodObjArgs callMethod, - @Cached PythonObjectFactory factory) { + @Cached PyObjectCallMethodObjArgs callMethod) { if (self.getLength() > 0) { int remaining = self.getBytesLength(); int blocksize = 64 * 1024; @@ -1335,7 +1430,7 @@ static Object tofile(VirtualFrame frame, PArray self, Object file, buffer = new byte[blocksize]; } bufferLib.readIntoByteArray(self.getBuffer(), i * blocksize, buffer, 0, buffer.length); - callMethod.execute(frame, inliningTarget, file, T_WRITE, factory.createBytes(buffer)); + callMethod.execute(frame, inliningTarget, file, T_WRITE, PFactory.createBytes(language, buffer)); remaining -= blocksize; } } @@ -1397,9 +1492,9 @@ abstract static class IndexNode extends PythonQuaternaryClinicBuiltinNode { @Specialization static int index(VirtualFrame frame, PArray self, Object value, int start, int stop, @Bind("this") Node inliningTarget, - @Cached PyObjectRichCompareBool.EqNode eqNode, + @Cached PyObjectRichCompareBool eqNode, @Cached ArrayNodes.GetValueNode getValueNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int length = self.getLength(); if (start < 0) { start += length; @@ -1411,11 +1506,11 @@ static int index(VirtualFrame frame, PArray self, Object value, int start, int s stop += length; } for (int i = start; i < stop && i < length; i++) { - if (eqNode.compare(frame, inliningTarget, getValueNode.execute(inliningTarget, self, i), value)) { + if (eqNode.execute(frame, inliningTarget, getValueNode.execute(inliningTarget, self, i), value, RichCmpOp.Py_EQ)) { return i; } } - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.ARRAY_INDEX_X_NOT_IN_ARRAY); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.ARRAY_INDEX_X_NOT_IN_ARRAY); } @Override @@ -1430,11 +1525,11 @@ abstract static class CountNode extends PythonBinaryBuiltinNode { @Specialization static int count(VirtualFrame frame, PArray self, Object value, @Bind("this") Node inliningTarget, - @Cached PyObjectRichCompareBool.EqNode eqNode, + @Cached PyObjectRichCompareBool eqNode, @Cached ArrayNodes.GetValueNode getValueNode) { int count = 0; for (int i = 0; i < self.getLength(); i++) { - if (eqNode.compare(frame, inliningTarget, getValueNode.execute(inliningTarget, self, i), value)) { + if (eqNode.execute(frame, inliningTarget, getValueNode.execute(inliningTarget, self, i), value, RichCmpOp.Py_EQ)) { count++; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayNodes.java index 5cbe44a9d6..f4570c743e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -112,7 +112,7 @@ static void ensure(Node inliningTarget, PArray array, int newCapacity, ensureCapacityNode.execute(inliningTarget, array.getSequenceStorage(), internalCapacity); } catch (OverflowException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.MemoryError); + PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.MemoryError); } } } @@ -130,7 +130,7 @@ static void set(Node inliningTarget, PArray array, int newLength, setLenNode.execute(inliningTarget, array.getSequenceStorage(), internalLength); } catch (OverflowException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.MemoryError); + PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.MemoryError); } } } @@ -170,7 +170,7 @@ static void shift(Node inliningTarget, PArray array, int from, int by, setLengthNode.execute(inliningTarget, array, newLength); } catch (OverflowException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.MemoryError); + PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.MemoryError); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/PArray.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/PArray.java index 68462f32e7..7e9ca190ec 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/PArray.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/PArray.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -86,11 +86,11 @@ public PArray(Object clazz, Shape instanceShape, TruffleString formatString, Buf this.storage = new ByteSequenceStorage(EMPTY_BYTE_ARRAY); } - public PArray(Object clazz, Shape instanceShape, TruffleString formatString, BufferFormat format, int length) throws OverflowException { + public PArray(Object clazz, Shape instanceShape, TruffleString formatString, BufferFormat format, int byteSize) { super(clazz, instanceShape); this.formatString = formatString; this.format = format; - this.storage = new ByteSequenceStorage(new byte[PythonUtils.multiplyExact(length, format.bytesize)]); + this.storage = new ByteSequenceStorage(new byte[byteSize]); } public BufferFormat getFormat() { @@ -140,9 +140,9 @@ public AtomicLong getExports() { return exports; } - public void checkCanResize(Node inliningTarget, PRaiseNode.Lazy raiseNode) { + public void checkCanResize(Node inliningTarget, PRaiseNode raiseNode) { if (exports.get() != 0) { - throw raiseNode.get(inliningTarget).raise(BufferError, ErrorMessages.EXPORTS_CANNOT_RESIZE); + throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.EXPORTS_CANNOT_RESIZE); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/ANextAwaitableBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/ANextAwaitableBuiltins.java new file mode 100644 index 0000000000..1e268bfbff --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/ANextAwaitableBuiltins.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.builtins.objects.asyncio; + +import static com.oracle.graal.python.nodes.BuiltinNames.T_CLOSE; +import static com.oracle.graal.python.nodes.BuiltinNames.T_SEND; +import static com.oracle.graal.python.nodes.BuiltinNames.T_THROW; + +import java.util.List; + +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.builtins.CoreFunctions; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.generator.PGenerator; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; +import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; +import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateNodeFactory; +import com.oracle.truffle.api.dsl.NodeFactory; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.strings.TruffleString; + +@CoreFunctions(extendClasses = PythonBuiltinClassType.PAnextAwaitable) +public class ANextAwaitableBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = ANextAwaitableBuiltinsSlotsGen.SLOTS; + + @Override + protected List> getNodeFactories() { + return ANextAwaitableBuiltinsFactory.getFactories(); + } + + // anextawaitable_getiter helper + @GenerateInline + @GenerateCached(false) + abstract static class GetIterNode extends Node { + abstract Object execute(VirtualFrame frame, Node inliningTarget, PANextAwaitable self); + + @Specialization + static Object getIter(VirtualFrame frame, Node inliningTarget, PANextAwaitable self, + @Cached GetAwaitableNode getAwaitableNode) { + Object awaitable = getAwaitableNode.execute(frame, self.getWrapped()); + if (awaitable instanceof PGenerator coroutine && coroutine.getInitialPythonClass() == PythonBuiltinClassType.PCoroutine) { + return PFactory.createCoroutineWrapper(PythonLanguage.get(inliningTarget), coroutine); + } + return awaitable; + } + } + + // anextawaitable_proxy helper + @GenerateInline + @GenerateCached(false) + abstract static class ProxyNode extends Node { + abstract Object execute(VirtualFrame frame, Node inliningTarget, PANextAwaitable self, TruffleString method); + + @Specialization + static Object getIter(VirtualFrame frame, Node inliningTarget, PANextAwaitable self, TruffleString method, + @Cached GetIterNode getIterNode, + @Cached PyObjectCallMethodObjArgs callMethod, + @Cached IsBuiltinObjectProfile stopIterationProfile, + @Cached PRaiseNode raiseNode) { + Object awaitable = getIterNode.execute(frame, inliningTarget, self); + try { + return callMethod.execute(frame, inliningTarget, awaitable, method); + } catch (PException e) { + e.expect(inliningTarget, PythonBuiltinClassType.StopAsyncIteration, stopIterationProfile); + throw raiseNode.raiseStopAsyncIteration(inliningTarget, self.getDefaultValue()); + } + } + } + + @Slot(value = SlotKind.tp_iter, isComplex = true) + @Slot(value = SlotKind.am_aiter, isComplex = true) + @GenerateNodeFactory + abstract static class IterNode extends PythonUnaryBuiltinNode { + @Specialization + static Object iter(PANextAwaitable self) { + return self; + } + } + + @Slot(value = SlotKind.tp_iternext, isComplex = true) + @GenerateNodeFactory + abstract static class IterNextNode extends TpIterNextBuiltin { + @Specialization + static Object next(VirtualFrame frame, PANextAwaitable self, + @Bind Node inliningTarget, + @Cached GetIterNode getIterNode, + @Cached TpSlots.GetObjectSlotsNode getSlots, + @Cached CallSlotTpIterNextNode callIternext, + @Cached IsBuiltinObjectProfile stopIterationProfile, + @Cached PRaiseNode raiseNode) { + Object awaitable = getIterNode.execute(frame, inliningTarget, self); + TpSlots slots = getSlots.execute(inliningTarget, awaitable); + try { + return callIternext.execute(frame, inliningTarget, slots.tp_iternext(), awaitable); + } catch (PException e) { + e.expect(inliningTarget, PythonBuiltinClassType.StopAsyncIteration, stopIterationProfile); + throw raiseNode.raiseStopAsyncIteration(inliningTarget, self.getDefaultValue()); + } + } + } + + @Builtin(name = "send", minNumOfPositionalArgs = 1) + @GenerateNodeFactory + abstract static class SendNode extends PythonUnaryBuiltinNode { + @Specialization + static Object doSend(VirtualFrame frame, PANextAwaitable self, + @Bind Node inliningTarget, + @Cached ProxyNode proxyNode) { + return proxyNode.execute(frame, inliningTarget, self, T_SEND); + } + } + + @Builtin(name = "throw", minNumOfPositionalArgs = 1) + @GenerateNodeFactory + abstract static class ThrowNode extends PythonUnaryBuiltinNode { + @Specialization + static Object doThrow(VirtualFrame frame, PANextAwaitable self, + @Bind Node inliningTarget, + @Cached ProxyNode proxyNode) { + return proxyNode.execute(frame, inliningTarget, self, T_THROW); + } + } + + @Builtin(name = "close", minNumOfPositionalArgs = 1) + @GenerateNodeFactory + abstract static class CloseNode extends PythonUnaryBuiltinNode { + @Specialization + static Object doClose(VirtualFrame frame, PANextAwaitable self, + @Bind Node inliningTarget, + @Cached ProxyNode proxyNode) { + return proxyNode.execute(frame, inliningTarget, self, T_CLOSE); + } + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/AsyncGenSendBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/AsyncGenSendBuiltins.java index db641813be..13c7f2631f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/AsyncGenSendBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/AsyncGenSendBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,18 +41,19 @@ package com.oracle.graal.python.builtins.objects.asyncio; import static com.oracle.graal.python.builtins.objects.asyncio.PAsyncGenASend.AwaitableState; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___AWAIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__; import java.util.List; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.generator.CommonGeneratorBuiltins; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; @@ -72,12 +73,14 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PAsyncGenASend) public final class AsyncGenSendBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = AsyncGenSendBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return AsyncGenSendBuiltinsFactory.getFactories(); } - @Builtin(name = J___AWAIT__, minNumOfPositionalArgs = 1, declaresExplicitSelf = true) + @Slot(value = SlotKind.am_await, isComplex = true) @GenerateNodeFactory public abstract static class Await extends PythonUnaryBuiltinNode { @Specialization @@ -86,9 +89,9 @@ public Object doAwait(PAsyncGenASend self) { } } - @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1, declaresExplicitSelf = true) + @Slot(value = SlotKind.tp_iternext, isComplex = true) @GenerateNodeFactory - public abstract static class Next extends PythonUnaryBuiltinNode { + public abstract static class Next extends TpIterNextBuiltin { @Specialization public Object next(VirtualFrame frame, PAsyncGenASend self, @Cached Send send) { @@ -107,16 +110,15 @@ public Object send(VirtualFrame frame, PAsyncGenASend self, Object sent, @Cached CommonGeneratorBuiltins.SendNode send, @Cached IsBuiltinObjectProfile isStopIteration, @Cached IsBuiltinObjectProfile isGenExit, - @Cached IsBuiltinObjectExactProfile isAsyncGenWrappedValue, - @Cached PRaiseNode raiseStopIteration) { + @Cached IsBuiltinObjectExactProfile isAsyncGenWrappedValue) { Object result; if (self.getState() == AwaitableState.CLOSED) { - throw raiseReuse.raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.CANNOT_REUSE_ASEND); + throw raiseReuse.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.CANNOT_REUSE_ASEND); } if (self.getState() == AwaitableState.INIT) { if (self.receiver.isRunningAsync()) { - throw raiseAlreadyRunning.raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.AGEN_ALREADY_RUNNING); + throw raiseAlreadyRunning.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.AGEN_ALREADY_RUNNING); } if (sent == null || sent == PNone.NONE) { sent = self.message; @@ -131,7 +133,7 @@ public Object send(VirtualFrame frame, PAsyncGenASend self, Object sent, throw handleAGError(self.receiver, e, inliningTarget, isStopIteration, isGenExit); } try { - return unwrapAGYield(self.receiver, result, inliningTarget, isAsyncGenWrappedValue, raiseStopIteration); + return unwrapAGYield(self.receiver, result, inliningTarget, isAsyncGenWrappedValue); } catch (PException e) { self.setState(AwaitableState.CLOSED); throw e; @@ -159,12 +161,11 @@ static PException handleAGError(PAsyncGen self, PException exception, static Object unwrapAGYield(PAsyncGen self, Object result, Node inliningTarget, - IsBuiltinObjectExactProfile isAGWrappedValue, - PRaiseNode raise) { + IsBuiltinObjectExactProfile isAGWrappedValue) { if (isAGWrappedValue.profileObject(inliningTarget, result, PythonBuiltinClassType.PAsyncGenAWrappedValue)) { self.setRunningAsync(false); Object wrapped = ((PAsyncGenWrappedValue) result).getWrapped(); - throw raise.raise(PythonBuiltinClassType.StopIteration, new Object[]{wrapped}); + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.StopIteration, new Object[]{wrapped}); } return result; } @@ -181,12 +182,11 @@ public Object doThrow(VirtualFrame frame, PAsyncGenASend self, Object arg1, Obje @Cached CommonGeneratorBuiltins.ThrowNode throwNode, @Cached IsBuiltinObjectProfile isStopIteration, @Cached IsBuiltinObjectProfile isGeneratorExit, - @Cached IsBuiltinObjectExactProfile isAGWrappedValue, - @Cached PRaiseNode raiseStopIteration) { + @Cached IsBuiltinObjectExactProfile isAGWrappedValue) { Object result; if (self.getState() == AwaitableState.CLOSED) { - throw raiseReuse.raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.CANNOT_REUSE_ASEND); + throw raiseReuse.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.CANNOT_REUSE_ASEND); } try { result = throwNode.execute(frame, self.receiver, arg1, arg2, arg3); @@ -195,7 +195,7 @@ public Object doThrow(VirtualFrame frame, PAsyncGenASend self, Object arg1, Obje throw handleAGError(self.receiver, e, inliningTarget, isStopIteration, isGeneratorExit); } try { - return unwrapAGYield(self.receiver, result, inliningTarget, isAGWrappedValue, raiseStopIteration); + return unwrapAGYield(self.receiver, result, inliningTarget, isAGWrappedValue); } catch (PException e) { self.setState(AwaitableState.CLOSED); throw e; @@ -204,7 +204,7 @@ public Object doThrow(VirtualFrame frame, PAsyncGenASend self, Object arg1, Obje } } - @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1, declaresExplicitSelf = true) + @Slot(value = SlotKind.tp_iter, isComplex = true) @GenerateNodeFactory public abstract static class Iter extends PythonUnaryBuiltinNode { @Specialization diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/AsyncGenThrowBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/AsyncGenThrowBuiltins.java index 5d22de9a24..1cb52d8432 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/AsyncGenThrowBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/AsyncGenThrowBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,18 +43,19 @@ import static com.oracle.graal.python.builtins.objects.asyncio.PAsyncGenASend.AwaitableState; import static com.oracle.graal.python.nodes.ErrorMessages.GENERATOR_IGNORED_EXIT; import static com.oracle.graal.python.nodes.ErrorMessages.SEND_NON_NONE_TO_UNSTARTED_GENERATOR; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___AWAIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__; import java.util.List; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.generator.CommonGeneratorBuiltins; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; @@ -75,12 +76,14 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PAsyncGenAThrow) public final class AsyncGenThrowBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = AsyncGenThrowBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return AsyncGenThrowBuiltinsFactory.getFactories(); } - @Builtin(name = J___AWAIT__, minNumOfPositionalArgs = 1, declaresExplicitSelf = true) + @Slot(value = SlotKind.am_await, isComplex = true) @GenerateNodeFactory public abstract static class Await extends PythonUnaryBuiltinNode { @Specialization @@ -89,7 +92,7 @@ public Object doAwait(PAsyncGenAThrow self) { } } - @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1, declaresExplicitSelf = true) + @Slot(value = SlotKind.tp_iter, isComplex = true) @GenerateNodeFactory public abstract static class Iter extends PythonUnaryBuiltinNode { @Specialization @@ -98,9 +101,9 @@ public Object doIter(PAsyncGenAThrow self) { } } - @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1, declaresExplicitSelf = true) + @Slot(value = SlotKind.tp_iternext, isComplex = true) @GenerateNodeFactory - public abstract static class Next extends PythonUnaryBuiltinNode { + public abstract static class Next extends TpIterNextBuiltin { @Specialization public Object doSend(VirtualFrame frame, PAsyncGenAThrow self, @Cached Send send) { @@ -122,14 +125,13 @@ public Object send(VirtualFrame frame, PAsyncGenAThrow self, Object sent, @Cached IsBuiltinObjectExactProfile isAGWrappedValue, @Cached IsBuiltinObjectProfile isStopAsyncIter, @Cached IsBuiltinObjectProfile isGeneratorExit, - @Cached PRaiseNode raiseIgnoreExit, @Cached PRaiseNode raiseStopIteration, @Cached CommonGeneratorBuiltins.SendNode sendNode) { PAsyncGen gen = self.receiver; Object retval; if (self.getState() == AwaitableState.CLOSED) { - throw raiseReuse.raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.CANNOT_REUSE_ATHROW); + throw raiseReuse.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.CANNOT_REUSE_ATHROW); } // CPython checks for gi_frame_state here, but we don't have gi_frame_state. @@ -137,24 +139,24 @@ public Object send(VirtualFrame frame, PAsyncGenAThrow self, Object sent, // https://github.com/python/cpython/blob/main/Objects/genobject.c#L2082-L2086 if (self.receiver.isFinished()) { self.setState(AwaitableState.CLOSED); - throw raiseStopIteration.raise(PythonBuiltinClassType.StopIteration); + throw raiseStopIteration.raise(inliningTarget, PythonBuiltinClassType.StopIteration); } if (self.getState() == AwaitableState.INIT) { if (gen.isRunningAsync()) { self.setState(AwaitableState.CLOSED); - throw raiseAlreadyRunning.raise(PythonBuiltinClassType.RuntimeError); // todo - // error - // msg + throw raiseAlreadyRunning.raise(inliningTarget, PythonBuiltinClassType.RuntimeError); // todo + // error + // msg } if (gen.isClosed()) { self.setState(AwaitableState.CLOSED); - throw raiseStopAsyncIteraion.raise(PythonBuiltinClassType.StopAsyncIteration); + throw raiseStopAsyncIteraion.raise(inliningTarget, PythonBuiltinClassType.StopAsyncIteration); } if (sent != PNone.NONE) { - throw raiseNonNodeToNewCoro.raise(PythonBuiltinClassType.RuntimeError, SEND_NON_NONE_TO_UNSTARTED_GENERATOR); + throw raiseNonNodeToNewCoro.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, SEND_NON_NONE_TO_UNSTARTED_GENERATOR); } self.setState(AwaitableState.ITER); @@ -167,10 +169,10 @@ public Object send(VirtualFrame frame, PAsyncGenAThrow self, Object sent, try { retval = throwNode.execute(frame, gen, PythonBuiltinClassType.GeneratorExit, PNone.NO_VALUE, PNone.NO_VALUE); } catch (PException e) { - throw checkError(self, gen, e, inliningTarget, isStopAsyncIter, isGeneratorExit, raiseStopIteration); + throw checkError(self, gen, e, inliningTarget, isStopAsyncIter, isGeneratorExit); } if (isAGWrappedValue.profileObject(inliningTarget, retval, PythonBuiltinClassType.PAsyncGenAWrappedValue)) { - throw yieldClose(self, gen, raiseIgnoreExit); + throw yieldClose(inliningTarget, self, gen); } } else { // athrow mode @@ -178,9 +180,9 @@ public Object send(VirtualFrame frame, PAsyncGenAThrow self, Object sent, retval = throwNode.execute(frame, gen, self.arg1, self.arg2, self.arg3); } catch (PException e) { PException exception = AsyncGenSendBuiltins.handleAGError(gen, e, inliningTarget, isStopAsyncIter, isGeneratorExit); - throw checkError(self, gen, exception, inliningTarget, isStopAsyncIter, isGeneratorExit, raiseStopIteration); + throw checkError(self, gen, exception, inliningTarget, isStopAsyncIter, isGeneratorExit); } - return AsyncGenSendBuiltins.unwrapAGYield(gen, retval, inliningTarget, isAGWrappedValue, raiseStopIteration); + return AsyncGenSendBuiltins.unwrapAGYield(gen, retval, inliningTarget, isAGWrappedValue); } } @@ -192,38 +194,36 @@ public Object send(VirtualFrame frame, PAsyncGenAThrow self, Object sent, throw AsyncGenSendBuiltins.handleAGError(gen, e, inliningTarget, isStopAsyncIter, isGeneratorExit); } else { // aclose - throw checkError(self, gen, e, inliningTarget, isStopAsyncIter, isGeneratorExit, raiseStopIteration); + throw checkError(self, gen, e, inliningTarget, isStopAsyncIter, isGeneratorExit); } } if (self.arg1 != null) { - return AsyncGenSendBuiltins.unwrapAGYield(gen, retval, inliningTarget, isAGWrappedValue, raiseStopIteration); + return AsyncGenSendBuiltins.unwrapAGYield(gen, retval, inliningTarget, isAGWrappedValue); } else { // aclose if (isAGWrappedValue.profileObject(inliningTarget, retval, PythonBuiltinClassType.PAsyncGenAWrappedValue)) { - throw yieldClose(self, gen, raiseIgnoreExit); + throw yieldClose(inliningTarget, self, gen); } else { return retval; } } } - static PException yieldClose(PAsyncGenAThrow athrow, PAsyncGen gen, - PRaiseNode raiseIgnoreExit) { + static PException yieldClose(Node inliningTarget, PAsyncGenAThrow athrow, PAsyncGen gen) { gen.setRunningAsync(false); athrow.setState(AwaitableState.CLOSED); - return raiseIgnoreExit.raise(PythonBuiltinClassType.RuntimeError, GENERATOR_IGNORED_EXIT); + return PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.RuntimeError, GENERATOR_IGNORED_EXIT); } static PException checkError(PAsyncGenAThrow athrow, PAsyncGen gen, PException exception, Node inliningTarget, IsBuiltinObjectProfile isStopAsyncIter, - IsBuiltinObjectProfile isGenExit, - PRaiseNode raiseStopIteration) { + IsBuiltinObjectProfile isGenExit) { gen.setRunningAsync(false); athrow.setState(AwaitableState.CLOSED); if (athrow.arg1 == null && (isStopAsyncIter.profileException(inliningTarget, exception, PythonBuiltinClassType.StopAsyncIteration) || isGenExit.profileException(inliningTarget, exception, PythonBuiltinClassType.GeneratorExit))) { - return raiseStopIteration.raise(PythonBuiltinClassType.StopIteration); + return PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.StopIteration); } return exception; } @@ -246,13 +246,11 @@ public Object doThrow(VirtualFrame frame, PAsyncGenAThrow self, Object arg1, Obj @Cached CommonGeneratorBuiltins.ThrowNode throwNode, @Cached IsBuiltinObjectProfile isStopAsyncIteration, @Cached IsBuiltinObjectProfile isGeneratorExit, - @Cached IsBuiltinObjectExactProfile isAGWrappedValue, - @Cached PRaiseNode raiseStopIteration, - @Cached PRaiseNode raiseIgnoredExit) { + @Cached IsBuiltinObjectExactProfile isAGWrappedValue) { Object retval; if (self.getState() == AwaitableState.CLOSED) { - throw raiseReuse.raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.CANNOT_REUSE_ATHROW); + throw raiseReuse.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.CANNOT_REUSE_ATHROW); } try { @@ -264,16 +262,16 @@ public Object doThrow(VirtualFrame frame, PAsyncGenAThrow self, Object arg1, Obj // aclose() if (isStopAsyncIteration.profileException(inliningTarget, e, PythonBuiltinClassType.StopAsyncIteration) || isGeneratorExit.profileException(inliningTarget, e, PythonBuiltinClassType.GeneratorExit)) { - throw raiseStopIteration.raise(PythonBuiltinClassType.StopIteration); + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.StopIteration); } throw e; } } if (self.arg1 != null) { - return AsyncGenSendBuiltins.unwrapAGYield(self.receiver, retval, inliningTarget, isAGWrappedValue, raiseStopIteration); + return AsyncGenSendBuiltins.unwrapAGYield(self.receiver, retval, inliningTarget, isAGWrappedValue); } else { if (isAGWrappedValue.profileObject(inliningTarget, retval, PythonBuiltinClassType.PAsyncGenAWrappedValue)) { - throw Send.yieldClose(self, self.receiver, raiseIgnoredExit); + throw Send.yieldClose(inliningTarget, self, self.receiver); } return retval; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/AsyncGeneratorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/AsyncGeneratorBuiltins.java index 021f85aff3..05ce04d5b1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/AsyncGeneratorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/AsyncGeneratorBuiltins.java @@ -40,25 +40,27 @@ */ package com.oracle.graal.python.builtins.objects.asyncio; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___AITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ANEXT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__; import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.generator.GeneratorBuiltins; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -70,6 +72,9 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PAsyncGenerator) public final class AsyncGeneratorBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = AsyncGeneratorBuiltinsSlotsGen.SLOTS; + private static void callHooks(VirtualFrame frame, PAsyncGen self, PythonContext.PythonThreadState state, CallUnaryMethodNode invokeFirstIter) { Object firstIter = state.getAsyncgenFirstIter(); if (firstIter == null) { @@ -93,9 +98,8 @@ public abstract static class GetCode extends PythonUnaryBuiltinNode { @Specialization static Object getCode(PAsyncGen self, @Bind("this") Node inliningTarget, - @Cached InlinedConditionProfile hasCodeProfile, - @Cached PythonObjectFactory.Lazy factory) { - return self.getOrCreateCode(inliningTarget, hasCodeProfile, factory); + @Cached InlinedConditionProfile hasCodeProfile) { + return self.getOrCreateCode(inliningTarget, hasCodeProfile); } } @@ -136,9 +140,9 @@ static Object aSend(VirtualFrame frame, PAsyncGen self, Object sent, @Bind("this") Node inliningTarget, @Bind PythonContext context, @Cached CallUnaryMethodNode callFirstIter, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { callHooks(frame, self, context.getThreadState(context.getLanguage(inliningTarget)), callFirstIter); - return factory.createAsyncGeneratorASend(self, sent); + return PFactory.createAsyncGeneratorASend(language, self, sent); } } @@ -152,13 +156,13 @@ static Object athrow(VirtualFrame frame, PAsyncGen self, Object arg1, Object arg @Bind("this") Node inliningTarget, @Bind PythonContext context, @Cached CallUnaryMethodNode callFirstIter, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { callHooks(frame, self, context.getThreadState(context.getLanguage(inliningTarget)), callFirstIter); - return factory.createAsyncGeneratorAThrow(self, arg1, arg2, arg3); + return PFactory.createAsyncGeneratorAThrow(language, self, arg1, arg2, arg3); } } - @Builtin(name = J___AITER__, declaresExplicitSelf = true, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.am_aiter, isComplex = true) @GenerateNodeFactory public abstract static class AIter extends PythonUnaryBuiltinNode { @Specialization @@ -167,7 +171,7 @@ static Object aIter(PAsyncGen self) { } } - @Builtin(name = J___ANEXT__, declaresExplicitSelf = true, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.am_anext, isComplex = true) @GenerateNodeFactory public abstract static class ANext extends PythonUnaryBuiltinNode { @Specialization @@ -175,9 +179,9 @@ static Object aNext(VirtualFrame frame, PAsyncGen self, @Bind("this") Node inliningTarget, @Bind PythonContext context, @Cached CallUnaryMethodNode callFirstIter, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { callHooks(frame, self, context.getThreadState(context.getLanguage(inliningTarget)), callFirstIter); - return factory.createAsyncGeneratorASend(self, PNone.NONE); + return PFactory.createAsyncGeneratorASend(language, self, PNone.NONE); } } @@ -189,9 +193,9 @@ Object aClose(VirtualFrame frame, PAsyncGen self, @Bind("this") Node inliningTarget, @Bind PythonContext context, @Cached CallUnaryMethodNode callFirstIter, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { callHooks(frame, self, context.getThreadState(context.getLanguage(inliningTarget)), callFirstIter); - return factory.createAsyncGeneratorAThrow(self, null, PNone.NO_VALUE, PNone.NO_VALUE); + return PFactory.createAsyncGeneratorAThrow(language, self, null, PNone.NO_VALUE, PNone.NO_VALUE); } } @@ -200,8 +204,8 @@ Object aClose(VirtualFrame frame, PAsyncGen self, public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode { @Specialization static Object classGetItem(Object cls, Object key, - @Cached PythonObjectFactory factory) { - return factory.createGenericAlias(cls, key); + @Bind PythonLanguage language) { + return PFactory.createGenericAlias(language, cls, key); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/CoroutineWrapperBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/CoroutineWrapperBuiltins.java index 8e0c35222f..b08ae12088 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/CoroutineWrapperBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/CoroutineWrapperBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,12 +42,16 @@ import java.util.List; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.generator.CommonGeneratorBuiltins; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; @@ -60,12 +64,15 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PCoroutineWrapper) public final class CoroutineWrapperBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = CoroutineWrapperBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return CoroutineWrapperBuiltinsFactory.getFactories(); } - @Builtin(name = "__iter__", minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iter, isComplex = true) @GenerateNodeFactory public abstract static class IterNode extends PythonUnaryBuiltinNode { @Specialization @@ -74,9 +81,9 @@ public Object getIter(PCoroutineWrapper self) { } } - @Builtin(name = "__next__", minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iternext, isComplex = true) @GenerateNodeFactory - public abstract static class NextNode extends PythonUnaryBuiltinNode { + public abstract static class NextNode extends TpIterNextBuiltin { @Specialization public Object doNext(VirtualFrame frame, PCoroutineWrapper self, @Cached CommonGeneratorBuiltins.SendNode send) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/GetAwaitableNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/GetAwaitableNode.java index f48c021293..ddd7993c76 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/GetAwaitableNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/GetAwaitableNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,75 +41,75 @@ package com.oracle.graal.python.builtins.objects.asyncio; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.generator.PGenerator; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotUnaryFunc.CallSlotUnaryNode; import com.oracle.graal.python.lib.PyIterCheckNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; +import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; +import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @GenerateUncached -@ImportStatic(SpecialMethodSlot.class) +@OperationProxy.Proxyable @SuppressWarnings("truffle-inlining") public abstract class GetAwaitableNode extends Node { - public abstract Object execute(Frame frame, Object arg); + public abstract Object execute(VirtualFrame frame, Object arg); @Specialization public static Object doGenerator(PGenerator generator, @Bind("this") Node inliningTarget, - @Exclusive @Cached PRaiseNode.Lazy raise, - @Exclusive @Cached PRaiseNode.Lazy raiseReusedCoro) { + @Exclusive @Cached PRaiseNode raise, + @Exclusive @Cached PRaiseNode raiseReusedCoro) { if (generator.isCoroutine()) { if (generator.getYieldFrom() != null) { - throw raiseReusedCoro.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.CORO_ALREADY_AWAITED); + throw raiseReusedCoro.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.CORO_ALREADY_AWAITED); } else { return generator; } } else { - throw raise.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_BE_USED_AWAIT, "generator"); + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_BE_USED_AWAIT, "generator"); } } - @Specialization - public static Object doGeneric(Frame frame, Object awaitable, + @Fallback + public static Object doGeneric(VirtualFrame frame, Object awaitable, @Bind("this") Node inliningTarget, - @Exclusive @Cached PRaiseNode.Lazy raiseNoAwait, - @Exclusive @Cached PRaiseNode.Lazy raiseNotIter, - @Cached(parameters = "Await") LookupSpecialMethodSlotNode findAwait, - @Cached TypeNodes.GetNameNode getName, + @Exclusive @Cached PRaiseNode raiseNoAwait, + @Exclusive @Cached PRaiseNode raiseNotIter, + @Cached GetCachedTpSlotsNode getSlots, + @Cached CallSlotUnaryNode callSlot, @Cached GetClassNode getAwaitableType, @Cached GetClassNode getIteratorType, - @Cached CallUnaryMethodNode callAwait, @Cached PyIterCheckNode iterCheck) { Object type = getAwaitableType.execute(inliningTarget, awaitable); - Object getter = findAwait.execute(frame, type, awaitable); - if (getter == PNone.NO_VALUE) { - throw raiseNoAwait.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_BE_USED_AWAIT, getName.execute(inliningTarget, type)); + TpSlots slots = getSlots.execute(inliningTarget, type); + if (slots.am_await() == null) { + throw raiseNoAwait.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_BE_USED_AWAIT, type); } - Object iterator = callAwait.executeObject(getter, awaitable); + Object iterator = callSlot.execute(frame, inliningTarget, slots.am_await(), awaitable); if (iterCheck.execute(inliningTarget, iterator)) { return iterator; } Object itType = getIteratorType.execute(inliningTarget, iterator); if (itType == PythonBuiltinClassType.PCoroutine) { - throw raiseNotIter.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.AWAIT_RETURN_COROUTINE); + throw raiseNotIter.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.AWAIT_RETURN_COROUTINE); } else { - throw raiseNotIter.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.AWAIT_RETURN_NON_ITER, getName.execute(inliningTarget, itType)); + throw raiseNotIter.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.AWAIT_RETURN_NON_ITER, itType); } } + @NeverDefault public static GetAwaitableNode create() { return GetAwaitableNodeGen.create(); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/PythonHPyObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/PANextAwaitable.java similarity index 74% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/PythonHPyObject.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/PANextAwaitable.java index a632fa184e..5ef9b47c30 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/PythonHPyObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/PANextAwaitable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,17 +38,26 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.builtins.objects.cext.hpy; +package com.oracle.graal.python.builtins.objects.asyncio; -import com.oracle.graal.python.builtins.objects.object.PythonObject; +import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; import com.oracle.truffle.api.object.Shape; -public final class PythonHPyObject extends PythonObject { +public class PANextAwaitable extends PythonBuiltinObject { + private final Object wrapped; + private final Object defaultValue; - public PythonHPyObject(Object pythonClass, Shape instanceShape, Object hpyNativeSpace) { - super(pythonClass, instanceShape); - if (hpyNativeSpace != null) { - GraalHPyData.setHPyNativeSpace(this, hpyNativeSpace); - } + public PANextAwaitable(Object cls, Shape instanceShape, Object wrapped, Object defaultValue) { + super(cls, instanceShape); + this.wrapped = wrapped; + this.defaultValue = defaultValue; + } + + public Object getWrapped() { + return wrapped; + } + + public Object getDefaultValue() { + return defaultValue; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/PAsyncGen.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/PAsyncGen.java index bfeca4b659..b10e377209 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/PAsyncGen.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/PAsyncGen.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -58,7 +58,7 @@ public static PAsyncGen create(PythonLanguage lang, TruffleString name, TruffleS } private PAsyncGen(PythonLanguage lang, TruffleString name, TruffleString qualname, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, Object[] arguments) { - super(lang, name, qualname, rootNode, callTargets, arguments, PythonBuiltinClassType.PAsyncGenerator, false); + super(lang, name, qualname, arguments, PythonBuiltinClassType.PAsyncGenerator, false, new BytecodeState(rootNode, callTargets)); } public boolean isClosed() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bool/BoolBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bool/BoolBuiltins.java index c418fc27cc..f0f7a60502 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bool/BoolBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bool/BoolBuiltins.java @@ -25,8 +25,7 @@ */ package com.oracle.graal.python.builtins.objects.bool; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__; +import static com.oracle.graal.python.nodes.BuiltinNames.J_BOOL; import static com.oracle.graal.python.nodes.StringLiterals.T_FALSE; import static com.oracle.graal.python.nodes.StringLiterals.T_TRUE; @@ -34,7 +33,7 @@ import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; @@ -42,9 +41,11 @@ import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode; +import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -64,10 +65,26 @@ protected List> getNodeFa return BoolBuiltinsFactory.getFactories(); } - @Builtin(name = J___STR__, minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = J_BOOL, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2) @GenerateNodeFactory - abstract static class StrNode extends PythonBuiltinNode { + public abstract static class BoolNode extends PythonBinaryBuiltinNode { + @Specialization + public static boolean bool(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object obj, + @Cached PyObjectIsTrueNode isTrue) { + return isTrue.execute(frame, obj); + } + } + + @Slot(value = SlotKind.tp_str, isComplex = true) + @TypeSystemReference(PythonIntegerTypes.class) + @GenerateNodeFactory + abstract static class StrNode extends PythonUnaryBuiltinNode { + @Specialization + static TruffleString doBoolean(boolean self) { + return self ? T_TRUE : T_FALSE; + } + @Specialization public static TruffleString doLong(long self) { return self == 1 ? T_TRUE : T_FALSE; @@ -79,13 +96,12 @@ public static TruffleString doPInt(PInt self) { } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class RepNode extends StrNode { } @Slot(value = SlotKind.nb_and, isComplex = true) - @TypeSystemReference(PythonArithmeticTypes.class) @GenerateNodeFactory abstract static class AndNode extends BinaryOpBuiltinNode { @Specialization @@ -101,7 +117,6 @@ static Object doOther(VirtualFrame frame, Object self, Object other, } @Slot(value = SlotKind.nb_or, isComplex = true) - @TypeSystemReference(PythonArithmeticTypes.class) @GenerateNodeFactory abstract static class OrNode extends BinaryOpBuiltinNode { @Specialization @@ -117,7 +132,6 @@ static Object doOther(VirtualFrame frame, Object self, Object other, } @Slot(value = SlotKind.nb_xor, isComplex = true) - @TypeSystemReference(PythonArithmeticTypes.class) @GenerateNodeFactory abstract static class XorNode extends BinaryOpBuiltinNode { @Specialization diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAccessLibrary.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAccessLibrary.java index 2b24992b99..3aa07edd15 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAccessLibrary.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAccessLibrary.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -277,6 +277,21 @@ public final byte[] getInternalOrCopiedByteArray(Object receiver) { } } + /** + * Get a byte array representing the buffer contents. Unlike + * {@link #getInternalOrCopiedByteArray(Object)}, always returns a byte array with length equal + * to the buffer size, making a copy if necessary. Do not write into the byte array. + */ + public final byte[] getInternalOrCopiedExactByteArray(Object receiver) { + if (hasInternalByteArray(receiver)) { + byte[] r = getInternalByteArray(receiver); + if (r.length == getBufferLength(receiver)) { + return r; + } + } + return getCopiedByteArray(receiver); + } + /** * Read a single byte from the buffer. Bounds checks are responsibility of the caller. * diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAcquireLibrary.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAcquireLibrary.java index 3c1edf8028..2aa92be08f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAcquireLibrary.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAcquireLibrary.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -202,7 +202,7 @@ public final Object acquireWritableWithTypeError(Object receiver, String callerN try { return acquireWritable(receiver); } catch (PException e) { - throw PRaiseNode.raiseUncached(this, TypeError, ErrorMessages.S_BRACKETS_ARG_MUST_BE_READ_WRITE_BYTES_LIKE_NOT_P, callerName, receiver); + throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.S_BRACKETS_ARG_MUST_BE_READ_WRITE_BYTES_LIKE_NOT_P, callerName, receiver); } finally { IndirectCallContext.exit(frame, indirectCallData, savedState); } @@ -225,7 +225,7 @@ public final Object acquireWritableWithTypeError(Object receiver, String callerN */ @Abstract public Object acquire(Object receiver, int flags) { - throw PRaiseNode.raiseUncached(this, TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, receiver); + throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, receiver); } /** diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/ByteArrayBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/ByteArrayBuiltins.java index 381fc26369..208253428e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/ByteArrayBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/ByteArrayBuiltins.java @@ -30,19 +30,9 @@ import static com.oracle.graal.python.nodes.BuiltinNames.J_APPEND; import static com.oracle.graal.python.nodes.BuiltinNames.J_BYTEARRAY; import static com.oracle.graal.python.nodes.BuiltinNames.J_EXTEND; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IADD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INIT__; +import static com.oracle.graal.python.runtime.exception.PythonErrorType.MemoryError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; @@ -50,12 +40,14 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.HashNotImplemented; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; @@ -78,19 +70,20 @@ import com.oracle.graal.python.builtins.objects.slice.SliceNodes; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotMpAssSubscript.MpAssSubscriptBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqItemBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqRepeatBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqAssItem.SqAssItemBuiltinNode; import com.oracle.graal.python.lib.PyByteArrayCheckNode; import com.oracle.graal.python.lib.PyIndexCheckNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectGetStateNode; import com.oracle.graal.python.lib.PySliceNew; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.SpecialAttributeNames; import com.oracle.graal.python.nodes.builtins.ListNodes; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; @@ -106,19 +99,18 @@ import com.oracle.graal.python.nodes.util.CastToByteNode; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; -import com.oracle.graal.python.util.ComparisonOp; +import com.oracle.graal.python.util.OverflowException; +import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.NodeFactory; @@ -132,6 +124,7 @@ import com.oracle.truffle.api.strings.TruffleStringBuilder; @CoreFunctions(extendClasses = PythonBuiltinClassType.PByteArray) +@HashNotImplemented public final class ByteArrayBuiltins extends PythonBuiltins { public static final TpSlots SLOTS = ByteArrayBuiltinsSlotsGen.SLOTS; @@ -143,28 +136,24 @@ protected List> getNodeFa return ByteArrayBuiltinsFactory.getFactories(); } - @Override - public void initialize(Python3Core core) { - super.initialize(core); - addBuiltinConstant(SpecialAttributeNames.T___DOC__, // - "bytearray(iterable_of_ints) -> bytearray\n" + // - "bytearray(string, encoding[, errors]) -> bytearray\n" + // - "bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n" + // - "bytearray(int) -> bytes array of size given by the parameter " + // - "initialized with null bytes\n" + // - "bytearray() -> empty bytes array\n" + // - "\n" + // - "Construct a mutable bytearray object from:\n" + // - " - an iterable yielding integers in range(256)\n" + // - " - a text string encoded using the specified encoding\n" + // - " - a bytes or a buffer object\n" + // - " - any object implementing the buffer API.\n" + // - " - an integer"); - addBuiltinConstant(T___HASH__, PNone.NONE); + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = J_BYTEARRAY, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class ByteArrayNode extends PythonBuiltinNode { + @Specialization + public PByteArray setEmpty(Object cls, @SuppressWarnings("unused") Object arg, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + // data filled in subsequent __init__ call - see BytesCommonBuiltins.InitNode + return PFactory.createByteArray(language, cls, getInstanceShape.execute(cls), PythonUtils.EMPTY_BYTE_ARRAY); + } + + // TODO: native allocation? } // bytearray([source[, encoding[, errors]]]) - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self", "source", "encoding", "errors"}) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = J_BYTEARRAY, minNumOfPositionalArgs = 1, parameterNames = {"$self", "source", "encoding", "errors"}) @ArgumentClinic(name = "encoding", conversionClass = BytesNodes.ExpectStringNode.class, args = "\"bytearray()\"") @ArgumentClinic(name = "errors", conversionClass = BytesNodes.ExpectStringNode.class, args = "\"bytearray()\"") @GenerateNodeFactory @@ -185,14 +174,14 @@ static PNone doInit(VirtualFrame frame, PByteArray self, Object source, Object e @Specialization(guards = "isNone(self)") static PNone doInit(@SuppressWarnings("unused") PByteArray self, Object source, @SuppressWarnings("unused") Object encoding, @SuppressWarnings("unused") Object errors, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_CONVERT_P_OBJ_TO_S, source, "bytearray"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CANNOT_CONVERT_P_OBJ_TO_S, source, "bytearray"); } @Specialization(guards = "!isBytes(self)") static PNone doInit(Object self, @SuppressWarnings("unused") Object source, @SuppressWarnings("unused") Object encoding, @SuppressWarnings("unused") Object errors, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___INIT__, "bytearray", self); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___INIT__, "bytearray", self); } } @@ -203,9 +192,7 @@ abstract static class GetitemNode extends SqItemBuiltinNode { static Object doInt(Object self, int key, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @Cached BytesNodes.GetBytesStorage getBytesStorage, - @Cached PRaiseNode.Lazy raiseNode, - @Cached SequenceStorageSqItemNode sqItemNode, - @Cached SequenceStorageNodes.GetItemScalarNode getItemNode) { + @Cached SequenceStorageSqItemNode sqItemNode) { SequenceStorage storage = getBytesStorage.execute(inliningTarget, self); return sqItemNode.execute(inliningTarget, storage, key, ErrorMessages.BYTEARRAY_OUT_OF_BOUNDS); } @@ -219,19 +206,19 @@ static Object doIt(VirtualFrame frame, Object self, Object idx, @Bind("this") Node inliningTarget, @Cached InlinedConditionProfile validProfile, @Cached PyIndexCheckNode indexCheckNode, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached BytesNodes.GetBytesStorage getBytesStorage, @Cached SequenceStorageMpSubscriptNode subscriptNode) { if (!validProfile.profile(inliningTarget, SequenceStorageMpSubscriptNode.isValidIndex(inliningTarget, idx, indexCheckNode))) { throw raiseNonIntIndex(inliningTarget, raiseNode, idx); } return subscriptNode.execute(frame, inliningTarget, getBytesStorage.execute(inliningTarget, self), idx, - ErrorMessages.LIST_INDEX_OUT_OF_RANGE, PythonObjectFactory::createByteArray); + ErrorMessages.LIST_INDEX_OUT_OF_RANGE, PFactory::createByteArray); } @InliningCutoff - private static PException raiseNonIntIndex(Node inliningTarget, PRaiseNode.Lazy raiseNode, Object index) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.OBJ_INDEX_MUST_BE_INT_OR_SLICES, "bytearray", index); + private static PException raiseNonIntIndex(Node inliningTarget, PRaiseNode raiseNode, Object index) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.OBJ_INDEX_MUST_BE_INT_OR_SLICES, "bytearray", index); } } @@ -269,13 +256,13 @@ static void set(VirtualFrame frame, PByteArray self, Object indexObj, Object val @Cached PyNumberAsSizeNode asSizeNode, @Cached("forBytearray()") NormalizeIndexNode normalizeIndexNode, @Cached SequenceStorageNodes.SetItemScalarNode setItemNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (indexCheckNode.execute(inliningTarget, indexObj)) { int index = asSizeNode.executeExact(frame, inliningTarget, indexObj); index = normalizeIndexNode.execute(index, self.getSequenceStorage().length()); setItemNode.execute(inliningTarget, self.getSequenceStorage(), index, value); } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.OBJ_INDEX_MUST_BE_INT_OR_SLICES, "bytearray", indexObj); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.OBJ_INDEX_MUST_BE_INT_OR_SLICES, "bytearray", indexObj); } } @@ -288,7 +275,7 @@ static void doSliceSequence(VirtualFrame frame, PByteArray self, PSlice slice, P @Cached @Shared SliceNodes.CoerceToIntSlice sliceCast, @Cached @Shared SliceNodes.SliceUnpack unpack, @Cached @Shared SliceNodes.AdjustIndices adjustIndices, - @Cached @Shared PRaiseNode.Lazy raiseNode) { + @Cached @Shared PRaiseNode raiseNode) { SequenceStorage storage = self.getSequenceStorage(); int otherLen = getSequenceStorageNode.execute(inliningTarget, value).length(); SliceInfo unadjusted = unpack.execute(inliningTarget, sliceCast.execute(inliningTarget, slice)); @@ -302,6 +289,7 @@ static void doSliceSequence(VirtualFrame frame, PByteArray self, PSlice slice, P @Specialization(guards = {"!isNoValue(value)", "bufferAcquireLib.hasBuffer(value)"}, limit = "3") static void doSliceBuffer(VirtualFrame frame, PByteArray self, PSlice slice, Object value, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("value") PythonBufferAcquireLibrary bufferAcquireLib, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @@ -311,12 +299,11 @@ static void doSliceBuffer(VirtualFrame frame, PByteArray self, PSlice slice, Obj @Cached @Shared SliceNodes.CoerceToIntSlice sliceCast, @Cached @Shared SliceNodes.SliceUnpack unpack, @Cached @Shared SliceNodes.AdjustIndices adjustIndices, - @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { Object buffer = bufferAcquireLib.acquireReadonly(value, frame, indirectCallData); try { // TODO avoid copying if possible. Note that it is possible that value is self - PBytes bytes = factory.createBytes(bufferLib.getCopiedByteArray(value)); + PBytes bytes = PFactory.createBytes(language, bufferLib.getCopiedByteArray(value)); doSliceSequence(frame, self, slice, bytes, inliningTarget, differentLenProfile, getSequenceStorageNode, setItemSliceNode, sliceCast, unpack, adjustIndices, raiseNode); } finally { bufferLib.release(buffer, frame, indirectCallData); @@ -333,7 +320,7 @@ static void doSliceGeneric(VirtualFrame frame, PByteArray self, PSlice slice, Ob @Cached @Shared SliceNodes.SliceUnpack unpack, @Cached @Shared SliceNodes.AdjustIndices adjustIndices, @Cached ListNodes.ConstructListNode constructListNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { PList values = constructListNode.execute(frame, value); doSliceSequence(frame, self, slice, values, inliningTarget, differentLenProfile, getSequenceStorageNode, setItemSliceNode, sliceCast, unpack, adjustIndices, raiseNode); } @@ -342,7 +329,7 @@ static void doSliceGeneric(VirtualFrame frame, PByteArray self, PSlice slice, Ob static void doDelete(VirtualFrame frame, PByteArray self, Object key, @SuppressWarnings("unused") Object value, @Bind("this") Node inliningTarget, @Cached SequenceStorageNodes.DeleteNode deleteNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { self.checkCanResize(inliningTarget, raiseNode); deleteNode.execute(frame, self.getSequenceStorage(), key); } @@ -360,7 +347,7 @@ public abstract static class InsertNode extends PythonTernaryClinicBuiltinNode { static PNone insert(VirtualFrame frame, PByteArray self, int index, int value, @Bind("this") Node inliningTarget, @Shared @Cached CastToByteNode toByteNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { self.checkCanResize(inliningTarget, raiseNode); byte v = toByteNode.execute(frame, value); ByteSequenceStorage target = (ByteSequenceStorage) self.getSequenceStorage(); @@ -374,7 +361,7 @@ static PNone insert(VirtualFrame frame, PByteArray self, int index, int value, @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode, @Cached SequenceStorageNodes.InsertItemNode insertItemNode, @Shared @Cached CastToByteNode toByteNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { self.checkCanResize(inliningTarget, raiseNode); byte v = toByteNode.execute(frame, value); SequenceStorage storage = getSequenceStorageNode.execute(inliningTarget, self); @@ -402,7 +389,7 @@ protected ArgumentClinicProvider getArgumentClinic() { } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { @@ -428,18 +415,16 @@ static Object repr(PByteArray self, } } - @Builtin(name = J___IADD__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.sq_inplace_concat, isComplex = true) @GenerateNodeFactory public abstract static class IAddNode extends PythonBinaryBuiltinNode { @Specialization static PByteArray add(PByteArray self, PBytesLike other, @Bind("this") Node inliningTarget, - @Cached @Shared SequenceStorageNodes.ConcatNode concatNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - self.checkCanResize(inliningTarget, raiseNode); - SequenceStorage res = concatNode.execute(self.getSequenceStorage(), other.getSequenceStorage()); - updateSequenceStorage(self, res); - return self; + @Shared @Cached SequenceStorageNodes.EnsureCapacityNode ensureCapacityNode, + @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, + @Shared @Cached PRaiseNode raiseNode) { + return extendWithBuffer(self, other, inliningTarget, ensureCapacityNode, bufferLib, raiseNode); } @Specialization(guards = "!isBytes(other)", limit = "3") @@ -447,67 +432,52 @@ static PByteArray add(VirtualFrame frame, PByteArray self, Object other, @Bind("this") Node inliningTarget, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("other") PythonBufferAcquireLibrary bufferAcquireLib, - @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Cached @Shared SequenceStorageNodes.ConcatNode concatNode, - @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - Object buffer; + @Shared @Cached SequenceStorageNodes.EnsureCapacityNode ensureCapacityNode, + @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, + @Shared @Cached PRaiseNode raiseNode) { + Object otherBuffer; try { - buffer = bufferAcquireLib.acquireReadonly(other, frame, indirectCallData); + otherBuffer = bufferAcquireLib.acquireReadonly(other, frame, indirectCallData); } catch (PException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANT_CONCAT_P_TO_S, other, "bytearray"); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_CONCAT_P_TO_S, other, "bytearray"); } try { - self.checkCanResize(inliningTarget, raiseNode); - // TODO avoid copying - PBytes bytes = factory.createBytes(bufferLib.getCopiedByteArray(buffer)); - SequenceStorage res = concatNode.execute(self.getSequenceStorage(), bytes.getSequenceStorage()); - updateSequenceStorage(self, res); - return self; + return extendWithBuffer(self, otherBuffer, inliningTarget, ensureCapacityNode, bufferLib, raiseNode); } finally { - bufferLib.release(buffer, frame, indirectCallData); + bufferLib.release(otherBuffer, frame, indirectCallData); } } - private static void updateSequenceStorage(PByteArray array, SequenceStorage s) { - if (array.getSequenceStorage() != s) { - array.setSequenceStorage(s); + private static PByteArray extendWithBuffer(PByteArray self, Object otherBuffer, Node inliningTarget, SequenceStorageNodes.EnsureCapacityNode ensureCapacityNode, + PythonBufferAccessLibrary bufferLib, PRaiseNode raiseNode) { + self.checkCanResize(inliningTarget, raiseNode); + try { + int len = self.getSequenceStorage().length(); + int otherLen = bufferLib.getBufferLength(otherBuffer); + int newLen = PythonUtils.addExact(len, otherLen); + ensureCapacityNode.execute(inliningTarget, self.getSequenceStorage(), newLen); + self.getSequenceStorage().setNewLength(newLen); + bufferLib.readIntoBuffer(otherBuffer, 0, self, len, otherLen, bufferLib); + return self; + } catch (OverflowException e) { + throw raiseNode.raise(inliningTarget, MemoryError); } } } - @Builtin(name = J___IMUL__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.sq_inplace_repeat, isComplex = true) @GenerateNodeFactory - public abstract static class IMulNode extends PythonBinaryBuiltinNode { + public abstract static class IMulNode extends SqRepeatBuiltinNode { @Specialization static Object mul(VirtualFrame frame, PByteArray self, int times, @Bind("this") Node inliningTarget, - @Cached @Shared SequenceStorageNodes.RepeatNode repeatNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Cached SequenceStorageNodes.RepeatNode repeatNode, + @Cached PRaiseNode raiseNode) { self.checkCanResize(inliningTarget, raiseNode); SequenceStorage res = repeatNode.execute(frame, self.getSequenceStorage(), times); self.setSequenceStorage(res); return self; } - - @Specialization - static Object mul(VirtualFrame frame, PByteArray self, Object times, - @Bind("this") Node inliningTarget, - @Cached PyNumberAsSizeNode asSizeNode, - @Cached @Shared SequenceStorageNodes.RepeatNode repeatNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - self.checkCanResize(inliningTarget, raiseNode); - SequenceStorage res = repeatNode.execute(frame, self.getSequenceStorage(), asSizeNode.executeExact(frame, inliningTarget, times)); - self.setSequenceStorage(res); - return self; - } - - @SuppressWarnings("unused") - @Fallback - static Object mul(Object self, Object other, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CANT_MULTIPLY_SEQ_BY_NON_INT, other); - } } @Builtin(name = "remove", minNumOfPositionalArgs = 2) @@ -520,7 +490,7 @@ static PNone remove(VirtualFrame frame, PByteArray self, Object value, @Cached("createCast()") CastToByteNode cast, @Cached SequenceStorageNodes.GetInternalByteArrayNode getBytes, @Cached SequenceStorageNodes.DeleteNode deleteNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { self.checkCanResize(inliningTarget, raiseNode); SequenceStorage storage = self.getSequenceStorage(); int len = storage.length(); @@ -529,22 +499,22 @@ static PNone remove(VirtualFrame frame, PByteArray self, Object value, deleteNode.execute(frame, storage, pos); return PNone.NONE; } - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.NOT_IN_BYTEARRAY); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_IN_BYTEARRAY); } @NeverDefault static CastToByteNode createCast() { - return CastToByteNode.create((val, raiseNode) -> { - throw raiseNode.raise(ValueError, ErrorMessages.BYTE_MUST_BE_IN_RANGE); - }, (val, raiseNode) -> { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, "bytes"); + return CastToByteNode.create((node, val) -> { + throw PRaiseNode.raiseStatic(node, ValueError, ErrorMessages.BYTE_MUST_BE_IN_RANGE); + }, (node, val) -> { + throw PRaiseNode.raiseStatic(node, TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, "bytes"); }); } @Fallback static Object doError(@SuppressWarnings("unused") Object self, Object arg, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, arg); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, arg); } } @@ -557,7 +527,7 @@ static Object popLast(VirtualFrame frame, PByteArray self, @SuppressWarnings("un @Bind("this") Node inliningTarget, @Shared("getItem") @Cached SequenceStorageNodes.GetItemNode getItemNode, @Shared @Cached("createDelete()") SequenceStorageNodes.DeleteNode deleteNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { self.checkCanResize(inliningTarget, raiseNode); SequenceStorage store = self.getSequenceStorage(); Object ret = getItemNode.execute(store, -1); @@ -570,7 +540,7 @@ static Object doIndex(VirtualFrame frame, PByteArray self, Object idx, @Bind("this") Node inliningTarget, @Shared("getItem") @Cached SequenceStorageNodes.GetItemNode getItemNode, @Shared @Cached("createDelete()") SequenceStorageNodes.DeleteNode deleteNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { self.checkCanResize(inliningTarget, raiseNode); SequenceStorage store = self.getSequenceStorage(); Object ret = getItemNode.execute(frame, store, idx); @@ -580,8 +550,8 @@ static Object doIndex(VirtualFrame frame, PByteArray self, Object idx, @Fallback static Object doError(@SuppressWarnings("unused") Object self, Object arg, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, arg); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, arg); } @NeverDefault @@ -604,7 +574,7 @@ static PNone append(VirtualFrame frame, PByteArray byteArray, Object arg, @Bind("this") Node inliningTarget, @Cached("createCast()") CastToByteNode toByteNode, @Cached SequenceStorageNodes.AppendNode appendNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { byteArray.checkCanResize(inliningTarget, raiseNode); appendNode.execute(inliningTarget, byteArray.getSequenceStorage(), toByteNode.execute(frame, arg), BytesNodes.BytesLikeNoGeneralizationNode.SUPPLIER); return PNone.NONE; @@ -612,10 +582,10 @@ static PNone append(VirtualFrame frame, PByteArray byteArray, Object arg, @NeverDefault static CastToByteNode createCast() { - return CastToByteNode.create((val, raiseNode) -> { - throw raiseNode.raise(ValueError, ErrorMessages.BYTE_MUST_BE_IN_RANGE); - }, (val, raiseNode) -> { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, "bytes"); + return CastToByteNode.create((node, val) -> { + throw PRaiseNode.raiseStatic(node, ValueError, ErrorMessages.BYTE_MUST_BE_IN_RANGE); + }, (node, val) -> { + throw PRaiseNode.raiseStatic(node, TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, "bytes"); }); } } @@ -630,7 +600,7 @@ static PNone doBytes(VirtualFrame frame, PByteArray self, PBytesLike source, @Bind("this") Node inliningTarget, @Cached IteratorNodes.GetLength lenNode, @Cached("createExtend()") @Shared SequenceStorageNodes.ExtendNode extendNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { self.checkCanResize(inliningTarget, raiseNode); int len = lenNode.execute(frame, inliningTarget, source); extend(frame, self, source, len, extendNode); @@ -640,6 +610,7 @@ static PNone doBytes(VirtualFrame frame, PByteArray self, PBytesLike source, @Specialization(guards = "!isBytes(source)", limit = "3") static PNone doGeneric(VirtualFrame frame, PByteArray self, Object source, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("source") PythonBufferAcquireLibrary bufferAcquireLib, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @@ -647,8 +618,7 @@ static PNone doGeneric(VirtualFrame frame, PByteArray self, Object source, @Cached BytesNodes.IterableToByteNode iterableToByteNode, @Cached IsBuiltinObjectProfile errorProfile, @Cached("createExtend()") @Shared SequenceStorageNodes.ExtendNode extendNode, - @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { self.checkCanResize(inliningTarget, raiseNode); byte[] b; if (bufferProfile.profile(inliningTarget, bufferAcquireLib.hasBuffer(source))) { @@ -664,10 +634,10 @@ static PNone doGeneric(VirtualFrame frame, PByteArray self, Object source, b = iterableToByteNode.execute(frame, source); } catch (PException e) { e.expect(inliningTarget, TypeError, errorProfile); - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANT_EXTEND_BYTEARRAY_WITH_P, source); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_EXTEND_BYTEARRAY_WITH_P, source); } } - PByteArray bytes = factory.createByteArray(b); + PByteArray bytes = PFactory.createByteArray(language, b); extend(frame, self, bytes, b.length, extendNode); return PNone.NONE; } @@ -691,10 +661,12 @@ public abstract static class CopyNode extends PythonBuiltinNode { @Specialization static PByteArray copy(PByteArray byteArray, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached GetClassNode getClassNode, - @Cached SequenceStorageNodes.ToByteArrayNode toByteArray, - @Cached PythonObjectFactory factory) { - return factory.createByteArray(getClassNode.execute(inliningTarget, byteArray), toByteArray.execute(inliningTarget, byteArray.getSequenceStorage())); + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached SequenceStorageNodes.ToByteArrayNode toByteArray) { + Object cls = getClassNode.execute(inliningTarget, byteArray); + return PFactory.createByteArray(language, cls, getInstanceShape.execute(cls), toByteArray.execute(inliningTarget, byteArray.getSequenceStorage())); } } @@ -722,7 +694,7 @@ static PNone clear(VirtualFrame frame, PByteArray byteArray, @Bind("this") Node inliningTarget, @Cached SequenceStorageNodes.DeleteNode deleteNode, @Cached PySliceNew sliceNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { byteArray.checkCanResize(inliningTarget, raiseNode); deleteNode.execute(frame, byteArray.getSequenceStorage(), sliceNode.execute(inliningTarget, PNone.NONE, PNone.NONE, 1)); return PNone.NONE; @@ -735,28 +707,24 @@ static PNone clear(VirtualFrame frame, PByteArray byteArray, @GenerateNodeFactory public abstract static class FromHexNode extends PythonBinaryClinicBuiltinNode { - @Specialization(guards = "isBuiltinBytesType(inliningTarget, cls, isSameType)") - static PByteArray doBytes(Object cls, TruffleString str, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Shared("isSameType") @Cached IsSameTypeNode isSameType, + @Specialization(guards = "isBuiltinByteArrayType(cls)") + static PByteArray doBytes(@SuppressWarnings("unused") Object cls, TruffleString str, @Shared("hexToBytes") @Cached HexStringToBytesNode hexStringToBytesNode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createByteArray(cls, hexStringToBytesNode.execute(str)); + @Bind PythonLanguage language) { + return PFactory.createByteArray(language, hexStringToBytesNode.execute(str)); } - @Specialization(guards = "!isBuiltinBytesType(inliningTarget, cls, isSameType)") + @Specialization(guards = "!isBuiltinByteArrayType(cls)") static Object doGeneric(VirtualFrame frame, Object cls, TruffleString str, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Shared("isSameType") @Cached IsSameTypeNode isSameType, @Cached CallNode callNode, @Shared("hexToBytes") @Cached HexStringToBytesNode hexStringToBytesNode, - @Shared @Cached PythonObjectFactory factory) { - PByteArray byteArray = factory.createByteArray(hexStringToBytesNode.execute(str)); + @Bind PythonLanguage language) { + PByteArray byteArray = PFactory.createByteArray(language, hexStringToBytesNode.execute(str)); return callNode.execute(frame, cls, byteArray); } - protected static boolean isBuiltinBytesType(Node inliningTarget, Object cls, IsSameTypeNode isSameTypeNode) { - return isSameTypeNode.execute(inliningTarget, PythonBuiltinClassType.PBytes, cls); + protected static boolean isBuiltinByteArrayType(Object cls) { + return cls == PythonBuiltinClassType.PByteArray; } @Override @@ -773,12 +741,12 @@ public abstract static class TranslateNode extends BytesNodes.BaseTranslateNode @Specialization static PByteArray translate(VirtualFrame frame, PByteArray self, Object table, Object delete, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached InlinedConditionProfile isLenTable256Profile, @Cached InlinedBranchProfile hasTable, @Cached InlinedBranchProfile hasDelete, @Cached BytesNodes.ToBytesNode toBytesNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { byte[] bTable = null; if (table != PNone.NONE) { hasTable.enter(inliningTarget); @@ -800,9 +768,9 @@ static PByteArray translate(VirtualFrame frame, PByteArray self, Object table, O } else if (bDelete != null) { result = delete(bSelf, bDelete); } else { - return factory.createByteArray(bSelf); + return PFactory.createByteArray(language, bSelf); } - return factory.createByteArray(result.array); + return PFactory.createByteArray(language, result.array); } } @@ -819,22 +787,22 @@ public static int alloc(PByteArray byteArray) { } } - protected static Object commonReduce(int proto, byte[] bytes, int len, Object clazz, Object dict, - PythonObjectFactory factory, TruffleStringBuilder.AppendCodePointNode appendCodePointNode, TruffleStringBuilder.ToStringNode toStringNode) { + static Object commonReduce(int proto, byte[] bytes, int len, Object clazz, Object dict, + PythonLanguage language, TruffleStringBuilder.AppendCodePointNode appendCodePointNode, TruffleStringBuilder.ToStringNode toStringNode) { TruffleStringBuilder sb = TruffleStringBuilder.create(TS_ENCODING); BytesUtils.repr(sb, bytes, len, appendCodePointNode); TruffleString str = toStringNode.execute(sb); Object contents; if (proto < 3) { - contents = factory.createTuple(new Object[]{str, T_LATIN_1}); + contents = PFactory.createTuple(language, new Object[]{str, T_LATIN_1}); } else { if (len > 0) { - contents = factory.createTuple(new Object[]{str, len}); + contents = PFactory.createTuple(language, new Object[]{str, len}); } else { - contents = factory.createTuple(new Object[0]); + contents = PFactory.createTuple(language, new Object[0]); } } - return factory.createTuple(new Object[]{clazz, contents, dict}); + return PFactory.createTuple(language, new Object[]{clazz, contents, dict}); } @Builtin(name = J___REDUCE__, minNumOfPositionalArgs = 1) @@ -844,28 +812,26 @@ protected abstract static class ReduceNode extends PythonUnaryBuiltinNode { @Specialization static Object reduce(VirtualFrame frame, PByteArray self, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached SequenceStorageNodes.GetInternalByteArrayNode getBytes, @Cached GetClassNode getClassNode, @Cached PyObjectGetStateNode getStateNode, @Cached TruffleStringBuilder.AppendCodePointNode appendCodePointNode, - @Cached TruffleStringBuilder.ToStringNode toStringNode, - @Cached PythonObjectFactory factory) { + @Cached TruffleStringBuilder.ToStringNode toStringNode) { byte[] bytes = getBytes.execute(inliningTarget, self.getSequenceStorage()); int len = self.getSequenceStorage().length(); Object state = getStateNode.execute(frame, inliningTarget, self); Object clazz = getClassNode.execute(inliningTarget, self); - return commonReduce(2, bytes, len, clazz, state, factory, appendCodePointNode, toStringNode); + return commonReduce(2, bytes, len, clazz, state, language, appendCodePointNode, toStringNode); } } - @GenerateInline - @GenerateCached(false) - abstract static class ComparisonHelperNode extends Node { - - abstract Object execute(VirtualFrame frame, Node inliningTarget, Object self, Object other, ComparisonOp op); - + @Slot(value = SlotKind.tp_richcompare, isComplex = true) + @GenerateNodeFactory + abstract static class RichCmpNode extends TpSlotRichCompare.RichCmpBuiltinNode { @Specialization - static boolean cmp(Node inliningTarget, PByteArray self, PBytesLike other, ComparisonOp op, + static boolean cmp(PByteArray self, PBytesLike other, RichCmpOp op, + @Bind("$node") Node inliningTarget, @Exclusive @Cached GetInternalByteArrayNode getArray) { SequenceStorage selfStorage = self.getSequenceStorage(); SequenceStorage otherStorage = other.getSequenceStorage(); @@ -874,7 +840,8 @@ static boolean cmp(Node inliningTarget, PByteArray self, PBytesLike other, Compa @Specialization(guards = {"check.execute(inliningTarget, self)", "acquireLib.hasBuffer(other)"}, limit = "3") @InliningCutoff - static Object cmp(VirtualFrame frame, Node inliningTarget, Object self, Object other, ComparisonOp op, + static Object cmp(VirtualFrame frame, Object self, Object other, RichCmpOp op, + @Bind("$node") Node inliningTarget, @Cached("createFor(this)") IndirectCallData indirectCallData, @SuppressWarnings("unused") @Exclusive @Cached PyByteArrayCheckNode check, @Cached GetBytesStorage getBytesStorage, @@ -893,7 +860,8 @@ static Object cmp(VirtualFrame frame, Node inliningTarget, Object self, Object o @Specialization(guards = {"check.execute(inliningTarget, self)", "!acquireLib.hasBuffer(other)"}) @SuppressWarnings("unused") - static Object cmp(VirtualFrame frame, Node inliningTarget, Object self, Object other, ComparisonOp op, + static Object cmp(VirtualFrame frame, Object self, Object other, RichCmpOp op, + @Bind("$node") Node inliningTarget, @Shared @Cached PyByteArrayCheckNode check, @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib) { return PNotImplemented.NOT_IMPLEMENTED; @@ -902,83 +870,10 @@ static Object cmp(VirtualFrame frame, Node inliningTarget, Object self, Object o @Specialization(guards = "!check.execute(inliningTarget, self)") @InliningCutoff @SuppressWarnings("unused") - static Object error(VirtualFrame frame, Node inliningTarget, Object self, Object other, ComparisonOp op, - @Shared @Cached PyByteArrayCheckNode check, - @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, op.builtinName, J_BYTEARRAY, self); - } - } - - @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class EqNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.EQ); - } - } - - @Builtin(name = J___NE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class NeNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.NE); + static Object error(VirtualFrame frame, Object self, Object other, RichCmpOp op, + @Bind("$node") Node inliningTarget, + @Shared @Cached PyByteArrayCheckNode check) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, op.getPythonName(), J_BYTEARRAY, self); } } - - @Builtin(name = J___LT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class LtNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.LT); - } - } - - @Builtin(name = J___LE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class LeNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.LE); - } - } - - @Builtin(name = J___GT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class GtNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.GT); - } - } - - @Builtin(name = J___GE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class GeNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.GE); - } - } - } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesBuiltins.java index 0bea205499..0c4236a56b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesBuiltins.java @@ -26,29 +26,31 @@ package com.oracle.graal.python.builtins.objects.bytes; import static com.oracle.graal.python.builtins.objects.bytes.BytesNodes.compareByteArrays; +import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_BYTES_SUBTYPE_NEW; import static com.oracle.graal.python.nodes.BuiltinNames.J_BYTES; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___BYTES__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___BYTES__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; +import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; +import com.oracle.graal.python.builtins.objects.bytes.BytesBuiltinsClinicProviders.BytesNewNodeClinicProviderGen; +import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions; +import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.SequenceStorageMpSubscriptNode; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.SequenceStorageSqItemNode; @@ -56,23 +58,31 @@ import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqItemBuiltinNode; import com.oracle.graal.python.lib.PyBytesCheckExactNode; import com.oracle.graal.python.lib.PyBytesCheckNode; import com.oracle.graal.python.lib.PyIndexCheckNode; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.CallNode; +import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; +import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; -import com.oracle.graal.python.util.ComparisonOp; +import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -82,9 +92,11 @@ import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateNodeFactory; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.profiles.InlinedConditionProfile; @@ -99,15 +111,106 @@ protected List> getNodeFa return BytesBuiltinsFactory.getFactories(); } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + // bytes([source[, encoding[, errors]]]) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = J_BYTES, minNumOfPositionalArgs = 1, parameterNames = {"$self", "source", "encoding", "errors"}) + @ArgumentClinic(name = "encoding", conversionClass = BytesNodes.ExpectStringNode.class, args = "\"bytes()\"") + @ArgumentClinic(name = "errors", conversionClass = BytesNodes.ExpectStringNode.class, args = "\"bytes()\"") @GenerateNodeFactory - public abstract static class InitNode extends PythonVarargsBuiltinNode { + public abstract static class BytesNewNode extends PythonQuaternaryClinicBuiltinNode { - @SuppressWarnings("unused") @Override - public Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported { - return PNone.NONE; + protected ArgumentClinicProvider getArgumentClinic() { + return BytesNewNodeClinicProviderGen.INSTANCE; + } + + @SuppressWarnings("unused") + @Specialization(guards = "isNoValue(source)") + static Object doEmpty(Object cls, PNone source, PNone encoding, PNone errors, + @Bind("this") Node inliningTarget, + @Exclusive @Cached CreateBytes createBytes) { + return createBytes.execute(inliningTarget, cls, PythonUtils.EMPTY_BYTE_ARRAY); + } + + @Specialization(guards = "!isNoValue(source)") + static Object doCallBytes(VirtualFrame frame, Object cls, Object source, PNone encoding, PNone errors, + @Bind("this") Node inliningTarget, + @Cached GetClassNode getClassNode, + @Cached InlinedConditionProfile hasBytes, + @Cached("create(T___BYTES__)") LookupSpecialMethodNode lookupBytes, + @Cached CallUnaryMethodNode callBytes, + @Cached BytesNodes.ToBytesNode toBytesNode, + @Cached PyBytesCheckNode check, + @Exclusive @Cached BytesNodes.BytesInitNode bytesInitNode, + @Exclusive @Cached CreateBytes createBytes, + @Cached PRaiseNode raiseNode) { + Object bytesMethod = lookupBytes.execute(frame, getClassNode.execute(inliningTarget, source), source); + if (hasBytes.profile(inliningTarget, bytesMethod != PNone.NO_VALUE)) { + Object bytes = callBytes.executeObject(frame, bytesMethod, source); + if (check.execute(inliningTarget, bytes)) { + if (cls == PythonBuiltinClassType.PBytes) { + return bytes; + } else { + return createBytes.execute(inliningTarget, cls, toBytesNode.execute(frame, bytes)); + } + } else { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.RETURNED_NONBYTES, T___BYTES__, bytes); + } + } + return createBytes.execute(inliningTarget, cls, bytesInitNode.execute(frame, inliningTarget, source, encoding, errors)); + } + + @Specialization(guards = {"isNoValue(source) || (!isNoValue(encoding) || !isNoValue(errors))"}) + static Object dontCallBytes(VirtualFrame frame, Object cls, Object source, Object encoding, Object errors, + @Bind("this") Node inliningTarget, + @Exclusive @Cached BytesNodes.BytesInitNode bytesInitNode, + @Exclusive @Cached CreateBytes createBytes) { + return createBytes.execute(inliningTarget, cls, bytesInitNode.execute(frame, inliningTarget, source, encoding, errors)); + } + + @GenerateInline + @GenerateCached(false) + abstract static class CreateBytes extends PNodeWithContext { + abstract Object execute(Node inliningTarget, Object cls, byte[] bytes); + + @Specialization(guards = "isBuiltinBytes(cls)") + static PBytes doBuiltin(@SuppressWarnings("unused") Object cls, byte[] bytes, + @Bind PythonLanguage language) { + return PFactory.createBytes(language, bytes); + } + + @Specialization(guards = "!needsNativeAllocationNode.execute(inliningTarget, cls)") + static PBytes doManaged(@SuppressWarnings("unused") Node inliningTarget, Object cls, byte[] bytes, + @SuppressWarnings("unused") @Shared @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + return PFactory.createBytes(language, cls, getInstanceShape.execute(cls), bytes); + } + + @Specialization(guards = "needsNativeAllocationNode.execute(inliningTarget, cls)") + static Object doNative(@SuppressWarnings("unused") Node inliningTarget, Object cls, byte[] bytes, + @SuppressWarnings("unused") @Shared @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, + @Cached(inline = false) CApiTransitions.PythonToNativeNode toNative, + @Cached(inline = false) CApiTransitions.NativeToPythonTransferNode toPython, + @Cached(inline = false) CExtNodes.PCallCapiFunction call) { + CArrayWrappers.CByteArrayWrapper wrapper = new CArrayWrappers.CByteArrayWrapper(bytes); + try { + return toPython.execute(call.call(FUN_BYTES_SUBTYPE_NEW, toNative.execute(cls), wrapper, bytes.length)); + } finally { + wrapper.free(); + } + } + + protected static boolean isBuiltinBytes(Object cls) { + return cls == PythonBuiltinClassType.PBytes; + } } + } + + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "bytes", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class InitNode extends PythonVarargsBuiltinNode { @SuppressWarnings("unused") @Specialization @@ -116,6 +219,25 @@ static Object byteDone(VirtualFrame frame, Object self, Object[] arguments, PKey } } + @Slot(value = SlotKind.tp_hash, isComplex = true) + @GenerateNodeFactory + abstract static class HashNode extends HashBuiltinNode { + @Specialization(limit = "3") + static long hash(VirtualFrame frame, Object self, + @Bind("this") Node inliningTarget, + @Cached("createFor(this)") IndirectCallData indirectCallData, + @CachedLibrary("self") PythonBufferAcquireLibrary acquireLib, + @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, + @Cached BytesNodes.HashBufferNode hashBufferNode) { + Object buffer = acquireLib.acquireReadonly(self, frame, indirectCallData); + try { + return hashBufferNode.execute(inliningTarget, buffer); + } finally { + bufferLib.release(buffer, frame, indirectCallData); + } + } + } + @Slot(value = SlotKind.sq_item, isComplex = true) @GenerateNodeFactory abstract static class GetitemNode extends SqItemBuiltinNode { @@ -123,9 +245,7 @@ abstract static class GetitemNode extends SqItemBuiltinNode { static Object doInt(Object self, int key, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @Cached BytesNodes.GetBytesStorage getBytesStorage, - @Cached PRaiseNode.Lazy raiseNode, - @Cached SequenceStorageSqItemNode sqItemNode, - @Cached SequenceStorageNodes.GetItemScalarNode getItemNode) { + @Cached SequenceStorageSqItemNode sqItemNode) { SequenceStorage storage = getBytesStorage.execute(inliningTarget, self); return sqItemNode.execute(inliningTarget, storage, key, ErrorMessages.BYTES_OUT_OF_BOUNDS); } @@ -139,23 +259,23 @@ static Object doIt(VirtualFrame frame, Object self, Object idx, @Bind("this") Node inliningTarget, @Cached InlinedConditionProfile validProfile, @Cached PyIndexCheckNode indexCheckNode, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached BytesNodes.GetBytesStorage getBytesStorage, @Cached SequenceStorageMpSubscriptNode subscriptNode) { if (!validProfile.profile(inliningTarget, SequenceStorageMpSubscriptNode.isValidIndex(inliningTarget, idx, indexCheckNode))) { throw raiseNonIntIndex(inliningTarget, raiseNode, idx); } return subscriptNode.execute(frame, inliningTarget, getBytesStorage.execute(inliningTarget, self), idx, - ErrorMessages.LIST_INDEX_OUT_OF_RANGE, PythonObjectFactory::createBytes); + ErrorMessages.LIST_INDEX_OUT_OF_RANGE, PFactory::createBytes); } @InliningCutoff - private static PException raiseNonIntIndex(Node inliningTarget, PRaiseNode.Lazy raiseNode, Object index) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.OBJ_INDEX_MUST_BE_INT_OR_SLICES, "byte", index); + private static PException raiseNonIntIndex(Node inliningTarget, PRaiseNode raiseNode, Object index) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.OBJ_INDEX_MUST_BE_INT_OR_SLICES, "byte", index); } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization @@ -174,13 +294,13 @@ public abstract static class TranslateNode extends BytesNodes.BaseTranslateNode @Specialization static Object translate(VirtualFrame frame, Object self, Object table, Object delete, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached InlinedConditionProfile isLenTable256Profile, @Cached InlinedBranchProfile hasTable, @Cached InlinedBranchProfile hasDelete, @Cached BytesNodes.ToBytesNode toBytesNode, - @Cached PythonObjectFactory factory, @Cached PyBytesCheckExactNode checkExactNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { byte[] bTable = null; if (table != PNone.NONE) { hasTable.enter(inliningTarget); @@ -202,12 +322,12 @@ static Object translate(VirtualFrame frame, Object self, Object table, Object de } else if (bDelete != null) { result = delete(bSelf, bDelete); } else if (!checkExactNode.execute(inliningTarget, self)) { - return factory.createBytes(bSelf); + return PFactory.createBytes(language, bSelf); } else { return self; } if (result.changed || !checkExactNode.execute(inliningTarget, self)) { - return factory.createBytes(result.array); + return PFactory.createBytes(language, result.array); } return self; } @@ -219,28 +339,24 @@ static Object translate(VirtualFrame frame, Object self, Object table, Object de @GenerateNodeFactory public abstract static class FromHexNode extends PythonBinaryClinicBuiltinNode { - @Specialization(guards = "isBuiltinBytesType(inliningTarget, cls, isSameType)") - static PBytes doBytes(Object cls, TruffleString str, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Shared("isSameType") @Cached TypeNodes.IsSameTypeNode isSameType, + @Specialization(guards = "isBuiltinBytesType(cls)") + static PBytes doBytes(@SuppressWarnings("unused") Object cls, TruffleString str, @Shared("hexToBytes") @Cached BytesNodes.HexStringToBytesNode hexStringToBytesNode, - @Shared @Cached PythonObjectFactory factory) { - return factory.createBytes(cls, hexStringToBytesNode.execute(str)); + @Bind PythonLanguage language) { + return PFactory.createBytes(language, hexStringToBytesNode.execute(str)); } - @Specialization(guards = "!isBuiltinBytesType(inliningTarget, cls, isSameType)") + @Specialization(guards = "!isBuiltinBytesType(cls)") static Object doGeneric(VirtualFrame frame, Object cls, TruffleString str, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Shared("isSameType") @Cached TypeNodes.IsSameTypeNode isSameType, @Cached CallNode callNode, @Shared("hexToBytes") @Cached BytesNodes.HexStringToBytesNode hexStringToBytesNode, - @Shared @Cached PythonObjectFactory factory) { - PBytes bytes = factory.createBytes(hexStringToBytesNode.execute(str)); + @Bind PythonLanguage language) { + PBytes bytes = PFactory.createBytes(language, hexStringToBytesNode.execute(str)); return callNode.execute(frame, cls, bytes); } - protected static boolean isBuiltinBytesType(Node inliningTarget, Object cls, TypeNodes.IsSameTypeNode isSameTypeNode) { - return isSameTypeNode.execute(inliningTarget, PythonBuiltinClassType.PBytes, cls); + protected static boolean isBuiltinBytesType(Object cls) { + return cls == PythonBuiltinClassType.PBytes; } @Override @@ -249,16 +365,15 @@ protected ArgumentClinicProvider getArgumentClinic() { } } - @GenerateInline - @GenerateCached(false) + @Slot(value = SlotKind.tp_richcompare, isComplex = false) + @GenerateNodeFactory + @GenerateUncached // N.B. bytes only allow comparing to bytes, bytearray has its own implementation that uses // buffer API - abstract static class ComparisonHelperNode extends Node { - - abstract Object execute(Node inliningTarget, Object self, Object other, ComparisonOp op); - + abstract static class RichCmpNode extends TpSlotRichCompare.RichCmpBuiltinNode { @Specialization - static boolean cmp(Node inliningTarget, PBytes self, PBytes other, ComparisonOp op, + static boolean cmp(PBytes self, PBytes other, RichCmpOp op, + @Bind("$node") Node inliningTarget, @Exclusive @Cached SequenceStorageNodes.GetInternalByteArrayNode getArray) { SequenceStorage selfStorage = self.getSequenceStorage(); SequenceStorage otherStorage = other.getSequenceStorage(); @@ -266,11 +381,12 @@ static boolean cmp(Node inliningTarget, PBytes self, PBytes other, ComparisonOp } @Fallback - static Object cmp(Node inliningTarget, Object self, Object other, ComparisonOp op, + static Object cmp(Object self, Object other, RichCmpOp op, + @Bind("$node") Node inliningTarget, @SuppressWarnings("unused") @Cached PyBytesCheckNode check, @Cached BytesNodes.GetBytesStorage getBytesStorage, @Exclusive @Cached SequenceStorageNodes.GetInternalByteArrayNode getArray, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (check.execute(inliningTarget, self)) { if (check.execute(inliningTarget, other)) { SequenceStorage selfStorage = getBytesStorage.execute(inliningTarget, self); @@ -280,79 +396,7 @@ static Object cmp(Node inliningTarget, Object self, Object other, ComparisonOp o return PNotImplemented.NOT_IMPLEMENTED; } } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, op.builtinName, J_BYTES, self); - } - } - - @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class EqNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode) { - return helperNode.execute(inliningTarget, self, other, ComparisonOp.EQ); - } - } - - @Builtin(name = J___NE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class NeNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode) { - return helperNode.execute(inliningTarget, self, other, ComparisonOp.NE); - } - } - - @Builtin(name = J___LT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class LtNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode) { - return helperNode.execute(inliningTarget, self, other, ComparisonOp.LT); - } - } - - @Builtin(name = J___LE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class LeNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode) { - return helperNode.execute(inliningTarget, self, other, ComparisonOp.LE); - } - } - - @Builtin(name = J___GT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class GtNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode) { - return helperNode.execute(inliningTarget, self, other, ComparisonOp.GT); - } - } - - @Builtin(name = J___GE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class GeNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object cmp(Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode helperNode) { - return helperNode.execute(inliningTarget, self, other, ComparisonOp.GE); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, op.getPythonName(), J_BYTES, self); } } @@ -362,13 +406,13 @@ abstract static class BytesNode extends PythonUnaryBuiltinNode { @Specialization static Object bytes(Object self, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached PyBytesCheckExactNode check, - @Cached BytesNodes.GetBytesStorage getBytesStorage, - @Cached PythonObjectFactory.Lazy factory) { + @Cached BytesNodes.GetBytesStorage getBytesStorage) { if (check.execute(inliningTarget, self)) { return self; } else { - return factory.get(inliningTarget).createBytes(getBytesStorage.execute(inliningTarget, self)); + return PFactory.createBytes(language, getBytesStorage.execute(inliningTarget, self)); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesCommonBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesCommonBuiltins.java index 6b02e3723a..576b0cbc9d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesCommonBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesCommonBuiltins.java @@ -43,10 +43,7 @@ import static com.oracle.graal.python.nodes.ErrorMessages.METHOD_REQUIRES_A_BYTES_OBJECT_GOT_P; import static com.oracle.graal.python.nodes.ErrorMessages.SEP_MUST_BE_ASCII; import static com.oracle.graal.python.nodes.ErrorMessages.SEP_MUST_BE_LENGTH_1; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CONTAINS__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETNEWARGS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; import static com.oracle.graal.python.nodes.StringLiterals.T_IGNORE; import static com.oracle.graal.python.nodes.StringLiterals.T_REPLACE; @@ -105,6 +102,7 @@ import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqRepeatBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyNumberIndexNode; import com.oracle.graal.python.nodes.ErrorMessages; @@ -124,7 +122,6 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentCastNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext; @@ -133,7 +130,7 @@ import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; import com.oracle.graal.python.runtime.formatting.BytesFormatProcessor; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.OverflowException; @@ -152,7 +149,6 @@ import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; @@ -198,12 +194,12 @@ public static CodingErrorAction toCodingErrorAction(TruffleString errors, Truffl return null; } - public static CodingErrorAction toCodingErrorAction(Node inliningTarget, TruffleString errors, PRaiseNode.Lazy raiseNode, TruffleString.EqualNode eqNode) { + public static CodingErrorAction toCodingErrorAction(Node inliningTarget, TruffleString errors, PRaiseNode raiseNode, TruffleString.EqualNode eqNode) { CodingErrorAction action = toCodingErrorAction(errors, eqNode); if (action != null) { return action; } - throw raiseNode.get(inliningTarget).raise(PythonErrorType.LookupError, ErrorMessages.UNKNOWN_ERROR_HANDLER, errors); + throw raiseNode.raise(inliningTarget, PythonErrorType.LookupError, ErrorMessages.UNKNOWN_ERROR_HANDLER, errors); } @TruffleBoundary @@ -244,10 +240,10 @@ static Object decode(VirtualFrame frame, Object self, TruffleString encoding, Tr @Bind("this") Node inliningTarget, @Cached CodecsModuleBuiltins.DecodeNode decodeNode, @Cached IsInstanceNode isInstanceNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object result = decodeNode.executeWithStrings(frame, self, encoding, errors); if (!isInstanceNode.executeWith(frame, result, PythonBuiltinClassType.PString)) { - throw raiseNode.get(inliningTarget).raise(TypeError, DECODER_RETURNED_P_INSTEAD_OF_BYTES, encoding, result); + throw raiseNode.raise(inliningTarget, TypeError, DECODER_RETURNED_P_INSTEAD_OF_BYTES, encoding, result); } return result; } @@ -277,10 +273,9 @@ static PBytesLike join(VirtualFrame frame, Object self, Object iterable, @Cached GetBytesStorage getBytesStorage, @Cached SequenceStorageNodes.ToByteArrayNode toByteArrayNode, @Cached BytesNodes.BytesJoinNode bytesJoinNode, - @Cached BytesNodes.CreateBytesNode create, - @Cached PythonObjectFactory factory) { + @Cached BytesNodes.CreateBytesNode create) { byte[] res = bytesJoinNode.execute(frame, inliningTarget, toByteArrayNode.execute(inliningTarget, getBytesStorage.execute(inliningTarget, self)), iterable); - return create.execute(inliningTarget, factory, self, res); + return create.execute(inliningTarget, self, res); } } @@ -290,12 +285,11 @@ public abstract static class ConcatNode extends SqConcatBuiltinNode { @Specialization static PBytesLike add(PBytesLike self, PBytesLike other, - @Bind("this") Node node, - @Cached("createWithOverflowError()") @Shared SequenceStorageNodes.ConcatNode concatNode, - @Cached @Exclusive BytesNodes.CreateBytesNode create, - @Shared @Cached PythonObjectFactory factory) { - SequenceStorage res = concatNode.execute(self.getSequenceStorage(), other.getSequenceStorage()); - return create.execute(node, factory, self, res); + @Bind Node inliningTarget, + @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, + @Shared @Cached BytesNodes.CreateBytesNode create, + @Shared @Cached PRaiseNode raiseNode) { + return concatBuffers(self, self, other, inliningTarget, bufferLib, create, raiseNode); } @Specialization(limit = "3") @@ -304,24 +298,35 @@ static PBytesLike add(VirtualFrame frame, Object self, Object other, @Cached("createFor(this)") IndirectCallData indirectCallData, @Cached GetBytesStorage getBytesStorage, @CachedLibrary("other") PythonBufferAcquireLibrary bufferAcquireLib, - @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Cached("createWithOverflowError()") @Shared SequenceStorageNodes.ConcatNode concatNode, - @Cached @Exclusive BytesNodes.CreateBytesNode create, - @Shared @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - Object buffer; + @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, + @Shared @Cached BytesNodes.CreateBytesNode create, + @Shared @Cached PRaiseNode raiseNode) { + Object otherBuffer; try { - buffer = bufferAcquireLib.acquireReadonly(other, frame, indirectCallData); + otherBuffer = bufferAcquireLib.acquireReadonly(other, frame, indirectCallData); } catch (PException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANT_CONCAT_P_TO_S, other, "bytearray"); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_CONCAT_P_TO_P, other, self); } try { - // TODO avoid copying - byte[] bytes = bufferLib.getCopiedByteArray(buffer); - SequenceStorage res = concatNode.execute(getBytesStorage.execute(inliningTarget, self), new ByteSequenceStorage(bytes)); - return create.execute(inliningTarget, factory, self, res); + SequenceStorage selfBuffer = getBytesStorage.execute(inliningTarget, self); + return concatBuffers(self, selfBuffer, otherBuffer, inliningTarget, bufferLib, create, raiseNode); } finally { - bufferLib.release(buffer, frame, indirectCallData); + bufferLib.release(otherBuffer, frame, indirectCallData); + } + } + + private static PBytesLike concatBuffers(Object self, Object selfBuffer, Object otherBuffer, Node inliningTarget, PythonBufferAccessLibrary bufferLib, BytesNodes.CreateBytesNode create, + PRaiseNode raiseNode) { + try { + int len = bufferLib.getBufferLength(selfBuffer); + int otherLen = bufferLib.getBufferLength(otherBuffer); + int newLen = PythonUtils.addExact(len, otherLen); + byte[] newBytes = new byte[newLen]; + bufferLib.readIntoByteArray(selfBuffer, 0, newBytes, 0, len); + bufferLib.readIntoByteArray(otherBuffer, 0, newBytes, len, otherLen); + return create.execute(inliningTarget, self, new ByteSequenceStorage(newBytes)); + } catch (OverflowException e) { + throw raiseNode.raise(inliningTarget, OverflowError); } } } @@ -334,29 +339,9 @@ static PBytesLike mul(VirtualFrame frame, Object self, int times, @Bind("this") Node inliningTarget, @Cached GetBytesStorage getBytesStorage, @Cached("createWithOverflowError()") SequenceStorageNodes.RepeatNode repeatNode, - @Cached BytesNodes.CreateBytesNode create, - @Cached PythonObjectFactory factory) { + @Cached BytesNodes.CreateBytesNode create) { SequenceStorage res = repeatNode.execute(frame, getBytesStorage.execute(inliningTarget, self), times); - return create.execute(inliningTarget, factory, self, res); - } - } - - @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1) - @GenerateNodeFactory - abstract static class HashNode extends PythonUnaryBuiltinNode { - @Specialization(limit = "3") - static long hash(VirtualFrame frame, Object self, - @Bind("this") Node inliningTarget, - @Cached("createFor(this)") IndirectCallData indirectCallData, - @CachedLibrary("self") PythonBufferAcquireLibrary acquireLib, - @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached BytesNodes.HashBufferNode hashBufferNode) { - Object buffer = acquireLib.acquireReadonly(self, frame, indirectCallData); - try { - return hashBufferNode.execute(inliningTarget, buffer); - } finally { - bufferLib.release(buffer, frame, indirectCallData); - } + return create.execute(inliningTarget, self, res); } } @@ -372,8 +357,7 @@ static Object mod(VirtualFrame frame, Object self, Object right, @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached BytesNodes.CreateBytesNode create, - @Cached TupleBuiltins.GetItemNode getTupleItemNode, - @Cached PythonObjectFactory factory) { + @Cached TupleBuiltins.GetItemNode getTupleItemNode) { Object buffer = acquireLib.acquireReadonly(self, frame, indirectCallData); try { byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); @@ -382,7 +366,7 @@ static Object mod(VirtualFrame frame, Object self, Object right, Object savedState = IndirectCallContext.enter(frame, indirectCallData); try { byte[] data = formatter.format(right); - return create.execute(inliningTarget, factory, self, data); + return create.execute(inliningTarget, self, data); } finally { IndirectCallContext.exit(frame, indirectCallData, savedState); } @@ -410,9 +394,9 @@ public static int len(Object self, } } - @Builtin(name = J___CONTAINS__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.sq_contains, isComplex = true) @GenerateNodeFactory - abstract static class ContainsNode extends PythonBinaryBuiltinNode { + abstract static class ContainsNode extends SqContainsBuiltinNode { @Specialization boolean contains(VirtualFrame frame, Object self, Object other, @@ -422,13 +406,13 @@ boolean contains(VirtualFrame frame, Object self, Object other, } } - @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iter, isComplex = true) @GenerateNodeFactory abstract static class IterNode extends PythonUnaryBuiltinNode { @Specialization static PSequenceIterator contains(Object self, - @Cached PythonObjectFactory factory) { - return factory.createSequenceIterator(self); + @Bind PythonLanguage language) { + return PFactory.createSequenceIterator(language, self); } } @@ -454,8 +438,8 @@ boolean doIt(VirtualFrame frame, Object self, Object substrs, int start, int end @Fallback static boolean doGeneric(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object substr, @SuppressWarnings("unused") Object start, @SuppressWarnings("unused") Object end, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, METHOD_REQUIRES_A_BYTES_OBJECT_GOT_P, substr); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, METHOD_REQUIRES_A_BYTES_OBJECT_GOT_P, substr); } protected abstract boolean doIt(byte[] bytes, int len, byte[] prefix, int start, int end); @@ -583,10 +567,10 @@ protected ArgumentClinicProvider getArgumentClinic() { static int index(VirtualFrame frame, Object self, Object arg, int start, int end, @Bind("this") Node inliningTarget, @Cached BytesNodes.FindNode findNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int result = findNode.execute(frame, inliningTarget, self, arg, start, end); if (result == -1) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.SUBSECTION_NOT_FOUND); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.SUBSECTION_NOT_FOUND); } return result; } @@ -608,10 +592,10 @@ protected ArgumentClinicProvider getArgumentClinic() { static int indexWithStartEnd(VirtualFrame frame, Object self, Object arg, int start, int end, @Bind("this") Node inliningTarget, @Cached BytesNodes.FindNode findNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int result = findNode.executeReverse(frame, inliningTarget, self, arg, start, end); if (result == -1) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.SUBSECTION_NOT_FOUND); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.SUBSECTION_NOT_FOUND); } return result; } @@ -624,6 +608,7 @@ public abstract static class PartitionAbstractNode extends PythonBinaryBuiltinNo @SuppressWarnings("truffle-static-method") // TODO: inh PTuple partition(VirtualFrame frame, Object self, Object sep, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("sep") PythonBufferAcquireLibrary acquireLib, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @@ -631,8 +616,7 @@ PTuple partition(VirtualFrame frame, Object self, Object sep, @Cached InlinedConditionProfile notFound, @Cached BytesNodes.ToBytesNode toBytesNode, @Cached BytesNodes.CreateBytesNode createBytesNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { SequenceStorage storage = getBytesStorage.execute(inliningTarget, self); int len = storage.length(); byte[] bytes = toBytesNode.execute(frame, self); @@ -640,34 +624,34 @@ PTuple partition(VirtualFrame frame, Object self, Object sep, try { int lenSep = bufferLib.getBufferLength(sepBuffer); if (lenSep == 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.EMPTY_SEPARATOR); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.EMPTY_SEPARATOR); } byte[] sepBytes = bufferLib.getCopiedByteArray(sepBuffer); int idx = BytesNodes.FindNode.find(bytes, len, sepBytes, 0, bytes.length, isRight()); PBytesLike first, second, third; if (notFound.profile(inliningTarget, idx == -1)) { - second = createBytesNode.execute(inliningTarget, factory, self, PythonUtils.EMPTY_BYTE_ARRAY); + second = createBytesNode.execute(inliningTarget, self, PythonUtils.EMPTY_BYTE_ARRAY); if (isRight()) { - third = createBytesNode.execute(inliningTarget, factory, self, bytes); - first = createBytesNode.execute(inliningTarget, factory, self, PythonUtils.EMPTY_BYTE_ARRAY); + third = createBytesNode.execute(inliningTarget, self, bytes); + first = createBytesNode.execute(inliningTarget, self, PythonUtils.EMPTY_BYTE_ARRAY); } else { - first = createBytesNode.execute(inliningTarget, factory, self, bytes); - third = createBytesNode.execute(inliningTarget, factory, self, PythonUtils.EMPTY_BYTE_ARRAY); + first = createBytesNode.execute(inliningTarget, self, bytes); + third = createBytesNode.execute(inliningTarget, self, PythonUtils.EMPTY_BYTE_ARRAY); } } else { - second = createBytesNode.execute(inliningTarget, factory, self, sepBytes); + second = createBytesNode.execute(inliningTarget, self, sepBytes); if (idx == 0) { - first = createBytesNode.execute(inliningTarget, factory, self, PythonUtils.EMPTY_BYTE_ARRAY); - third = createBytesNode.execute(inliningTarget, factory, self, Arrays.copyOfRange(bytes, lenSep, len)); + first = createBytesNode.execute(inliningTarget, self, PythonUtils.EMPTY_BYTE_ARRAY); + third = createBytesNode.execute(inliningTarget, self, Arrays.copyOfRange(bytes, lenSep, len)); } else if (idx == len - 1) { - first = createBytesNode.execute(inliningTarget, factory, self, Arrays.copyOfRange(bytes, 0, len - lenSep)); - third = createBytesNode.execute(inliningTarget, factory, self, PythonUtils.EMPTY_BYTE_ARRAY); + first = createBytesNode.execute(inliningTarget, self, Arrays.copyOfRange(bytes, 0, len - lenSep)); + third = createBytesNode.execute(inliningTarget, self, PythonUtils.EMPTY_BYTE_ARRAY); } else { - first = createBytesNode.execute(inliningTarget, factory, self, Arrays.copyOfRange(bytes, 0, idx)); - third = createBytesNode.execute(inliningTarget, factory, self, Arrays.copyOfRange(bytes, idx + lenSep, len)); + first = createBytesNode.execute(inliningTarget, self, Arrays.copyOfRange(bytes, 0, idx)); + third = createBytesNode.execute(inliningTarget, self, Arrays.copyOfRange(bytes, idx + lenSep, len)); } } - return factory.createTuple(new Object[]{first, second, third}); + return PFactory.createTuple(language, new Object[]{first, second, third}); } finally { bufferLib.release(sepBuffer, frame, indirectCallData); } @@ -810,14 +794,14 @@ static byte pstring(Object strObj, @Cached CastToTruffleStringNode toStr, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { TruffleString str = toStr.execute(inliningTarget, strObj); if (codePointLengthNode.execute(str, TS_ENCODING) != 1) { - throw raiseNode.get(inliningTarget).raise(ValueError, SEP_MUST_BE_LENGTH_1); + throw raiseNode.raise(inliningTarget, ValueError, SEP_MUST_BE_LENGTH_1); } int cp = codePointAtIndexNode.execute(str, 0, TS_ENCODING); if (cp > 127) { - throw raiseNode.get(inliningTarget).raise(ValueError, SEP_MUST_BE_ASCII); + throw raiseNode.raise(inliningTarget, ValueError, SEP_MUST_BE_ASCII); } return (byte) cp; } @@ -828,17 +812,17 @@ static byte doBuffer(VirtualFrame frame, Object object, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("object") PythonBufferAcquireLibrary bufferAcquireLib, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { PythonContext context = PythonContext.get(inliningTarget); PythonLanguage language = context.getLanguage(inliningTarget); Object buffer = bufferAcquireLib.acquireReadonly(object, frame, context, language, indirectCallData); try { if (bufferLib.getBufferLength(buffer) != 1) { - throw raiseNode.get(inliningTarget).raise(ValueError, SEP_MUST_BE_LENGTH_1); + throw raiseNode.raise(inliningTarget, ValueError, SEP_MUST_BE_LENGTH_1); } byte b = bufferLib.readByte(buffer, 0); if (b < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, SEP_MUST_BE_ASCII); + throw raiseNode.raise(inliningTarget, ValueError, SEP_MUST_BE_ASCII); } return b; } finally { @@ -849,8 +833,8 @@ static byte doBuffer(VirtualFrame frame, Object object, @SuppressWarnings("unused") @Fallback static byte error(VirtualFrame frame, Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.SEP_MUST_BE_STR_OR_BYTES); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.SEP_MUST_BE_STR_OR_BYTES); } @ClinicConverterFactory @@ -902,8 +886,8 @@ static TruffleString hex(Object self, byte sep, int bytesPerSepGroup, @SuppressWarnings("unused") @Fallback static TruffleString err(Object self, Object sep, Object bytesPerSepGroup, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, DESCRIPTOR_NEED_OBJ, "hex", "bytes"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, DESCRIPTOR_NEED_OBJ, "hex", "bytes"); } } @@ -1211,8 +1195,7 @@ PBytesLike bytes(VirtualFrame frame, Object self, Object widthObj, Object fillOb @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, @Cached InlinedBranchProfile hasFill, @Cached PyNumberAsSizeNode asSizeNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int width = asSizeNode.executeExact(frame, inliningTarget, widthObj); SequenceStorage storage = getBytesStorage.execute(inliningTarget, self); int len = storage.length(); @@ -1222,13 +1205,13 @@ PBytesLike bytes(VirtualFrame frame, Object self, Object widthObj, Object fillOb if (fillObj instanceof PBytesLike && bufferLib.getBufferLength(fillObj) == 1) { fillByte = bufferLib.readByte(fillObj, 0); } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.BYTE_STRING_OF_LEN_ONE_ONLY, methodName(), fillObj); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.BYTE_STRING_OF_LEN_ONE_ONLY, methodName(), fillObj); } } if (checkSkip(len, width)) { - return create.execute(inliningTarget, factory, self, copyNode.execute(inliningTarget, storage)); + return create.execute(inliningTarget, self, copyNode.execute(inliningTarget, storage)); } - return create.execute(inliningTarget, factory, self, make(bufferLib.getCopiedByteArray(self), len, width, fillByte)); + return create.execute(inliningTarget, self, make(bufferLib.getCopiedByteArray(self), len, width, fillByte)); } protected String methodName() { @@ -1339,8 +1322,7 @@ static PBytesLike replace(Object self, Object substrBuffer, Object replacementBu @Cached InlinedConditionProfile selfSubAreEmpty, @Cached InlinedConditionProfile selfIsEmpty, @Cached InlinedConditionProfile subIsEmpty, - @Cached BytesNodes.CreateBytesNode create, - @Cached PythonObjectFactory factory) { + @Cached BytesNodes.CreateBytesNode create) { try { SequenceStorage storage = getBytesStorage.execute(inliningTarget, self); int len = storage.length(); @@ -1349,16 +1331,16 @@ static PBytesLike replace(Object self, Object substrBuffer, Object replacementBu byte[] replacementBytes = bufferLib.getCopiedByteArray(replacementBuffer); int maxcount = count < 0 ? Integer.MAX_VALUE : count; if (selfSubAreEmpty.profile(inliningTarget, len == 0 && subBytes.length == 0)) { - return create.execute(inliningTarget, factory, self, replacementBytes); + return create.execute(inliningTarget, self, replacementBytes); } if (selfIsEmpty.profile(inliningTarget, len == 0)) { - return create.execute(inliningTarget, factory, self, PythonUtils.EMPTY_BYTE_ARRAY); + return create.execute(inliningTarget, self, PythonUtils.EMPTY_BYTE_ARRAY); } if (subIsEmpty.profile(inliningTarget, subBytes.length == 0)) { - return create.execute(inliningTarget, factory, self, replaceWithEmptySub(bytes, len, replacementBytes, maxcount)); + return create.execute(inliningTarget, self, replaceWithEmptySub(bytes, len, replacementBytes, maxcount)); } byte[] newBytes = replace(bytes, len, subBytes, replacementBytes, maxcount); - return create.execute(inliningTarget, factory, self, newBytes); + return create.execute(inliningTarget, self, newBytes); } finally { bufferLib.release(substrBuffer); bufferLib.release(replacementBuffer); @@ -1367,8 +1349,8 @@ static PBytesLike replace(Object self, Object substrBuffer, Object replacementBu @Fallback static boolean error(@SuppressWarnings("unused") Object self, Object substr, @SuppressWarnings("unused") Object replacement, @SuppressWarnings("unused") Object count, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, BYTESLIKE_OBJ_REQUIRED, substr); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, BYTESLIKE_OBJ_REQUIRED, substr); } @TruffleBoundary(allowInlining = true) @@ -1437,13 +1419,12 @@ abstract static class LowerNode extends PythonUnaryBuiltinNode { static PBytesLike replace(Object self, @Bind("this") Node node, @Cached BytesNodes.ToBytesNode toBytes, - @Cached BytesNodes.CreateBytesNode create, - @Cached PythonObjectFactory factory) { + @Cached BytesNodes.CreateBytesNode create) { byte[] bytes = toBytes.execute(null, self); for (int i = 0; i < bytes.length; ++i) { bytes[i] = toLower(bytes[i]); } - return create.execute(node, factory, self, bytes); + return create.execute(node, self, bytes); } } @@ -1455,13 +1436,12 @@ abstract static class UpperNode extends PythonUnaryBuiltinNode { static PBytesLike replace(Object self, @Bind("this") Node inliningTarget, @Cached BytesNodes.ToBytesNode toBytes, - @Cached BytesNodes.CreateBytesNode create, - @Cached PythonObjectFactory factory) { + @Cached BytesNodes.CreateBytesNode create) { byte[] bytes = toBytes.execute(null, self); for (int i = 0; i < bytes.length; ++i) { bytes[i] = toUpper(bytes[i]); } - return create.execute(inliningTarget, factory, self, bytes); + return create.execute(inliningTarget, self, bytes); } } @@ -1491,22 +1471,22 @@ static int doInt(int i) { @Specialization static int toInt(long x, @Bind("this") Node inliningTarget, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { try { return PInt.intValueExact(x); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "C long"); + throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "C long"); } } @Specialization static int toInt(PInt x, @Bind("this") Node inliningTarget, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { try { return x.intValueExact(); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "C long"); + throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "C long"); } } @@ -1608,10 +1588,10 @@ PList whitespace(Object self, @SuppressWarnings("unused") byte[] sep, int maxspl @Shared("toBytes") @Cached SequenceStorageNodes.GetInternalByteArrayNode selfToBytesNode, @Shared("append") @Cached ListNodes.AppendNode appendNode, @Shared("create") @Cached BytesNodes.CreateBytesNode createBytesNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { SequenceStorage storage = getBytesStorage.execute(inliningTarget, self); byte[] splitBs = selfToBytesNode.execute(inliningTarget, storage); - return getBytesResult(splitWhitespace(splitBs, storage.length(), adjustMaxSplit(maxsplit)), appendNode, self, inliningTarget, createBytesNode, factory); + return getBytesResult(splitWhitespace(splitBs, storage.length(), adjustMaxSplit(maxsplit)), appendNode, self, inliningTarget, createBytesNode, language); } @Specialization(guards = {"!isWhitespace(sep)", "isSingleSep(sep)"}) @@ -1621,10 +1601,10 @@ PList single(Object self, byte[] sep, int maxsplit, @Shared("toBytes") @Cached SequenceStorageNodes.GetInternalByteArrayNode selfToBytesNode, @Shared("append") @Cached ListNodes.AppendNode appendNode, @Shared("create") @Cached BytesNodes.CreateBytesNode createBytesNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { SequenceStorage storage = getBytesStorage.execute(inliningTarget, self); byte[] splitBs = selfToBytesNode.execute(inliningTarget, storage); - return getBytesResult(splitSingle(splitBs, storage.length(), sep[0], adjustMaxSplit(maxsplit)), appendNode, self, inliningTarget, createBytesNode, factory); + return getBytesResult(splitSingle(splitBs, storage.length(), sep[0], adjustMaxSplit(maxsplit)), appendNode, self, inliningTarget, createBytesNode, language); } @Specialization(guards = {"!isWhitespace(sep)", "!isEmptySep(sep)", "!isSingleSep(sep)"}) @@ -1634,25 +1614,25 @@ PList split(Object self, byte[] sep, int maxsplit, @Shared("toBytes") @Cached SequenceStorageNodes.GetInternalByteArrayNode selfToBytesNode, @Shared("append") @Cached ListNodes.AppendNode appendNode, @Shared("create") @Cached BytesNodes.CreateBytesNode createBytesNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { SequenceStorage storage = getBytesStorage.execute(inliningTarget, self); byte[] splitBs = selfToBytesNode.execute(inliningTarget, storage); - return getBytesResult(splitDelimiter(splitBs, storage.length(), sep, adjustMaxSplit(maxsplit)), appendNode, self, inliningTarget, createBytesNode, factory); + return getBytesResult(splitDelimiter(splitBs, storage.length(), sep, adjustMaxSplit(maxsplit)), appendNode, self, inliningTarget, createBytesNode, language); } @SuppressWarnings("unused") @Specialization(guards = {"isEmptySep(sep)"}) static PList error(Object bytes, byte[] sep, int maxsplit, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonErrorType.ValueError, ErrorMessages.EMPTY_SEPARATOR); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.ValueError, ErrorMessages.EMPTY_SEPARATOR); } private static PList getBytesResult(List bytes, ListNodes.AppendNode appendNode, Object self, Node inliningTarget, BytesNodes.CreateBytesNode createBytesNode, - PythonObjectFactory factory) { - PList result = factory.createList(); + PythonLanguage language) { + PList result = PFactory.createList(language); Iterator it = iterator(bytes); while (hasNext(it)) { - appendNode.execute(result, createBytesNode.execute(inliningTarget, factory, self, next(it))); + appendNode.execute(result, createBytesNode.execute(inliningTarget, self, next(it))); } return result; } @@ -1662,7 +1642,6 @@ private static PList getBytesResult(List bytes, ListNodes.AppendNode app @ArgumentClinic(name = "sep", conversionClass = ExpectByteLikeNode.class, defaultValue = "BytesCommonBuiltins.AbstractSplitNode.WHITESPACE") @ArgumentClinic(name = "maxsplit", conversionClass = ExpectIntNode.class, defaultValue = "Integer.MAX_VALUE") @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class SplitNode extends AbstractSplitNode { protected int find(byte[] bytes, int len, byte[] sep, int start, int end) { @@ -1757,7 +1736,6 @@ protected List splitDelimiter(byte[] bytes, int len, byte[] sep, int max @ArgumentClinic(name = "sep", conversionClass = ExpectByteLikeNode.class, defaultValue = "BytesCommonBuiltins.AbstractSplitNode.WHITESPACE") @ArgumentClinic(name = "maxsplit", conversionClass = ExpectIntNode.class, defaultValue = "Integer.MAX_VALUE") @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class RSplitNode extends AbstractSplitNode { protected int find(byte[] bytes, int len, byte[] sep, int start, int end) { @@ -1864,14 +1842,14 @@ public abstract static class SplitLinesNode extends PythonBinaryBuiltinNode { @Specialization static PList doSplitlines(Object self, Object keependsObj, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached InlinedBranchProfile isPNoneProfile, @Cached InlinedBranchProfile isBooleanProfile, @Cached InlinedConditionProfile keependsProfile, @Cached CastToJavaIntExactNode cast, @Cached BytesNodes.ToBytesNode toBytesNode, @Cached ListNodes.AppendNode appendNode, - @Cached BytesNodes.CreateBytesNode create, - @Cached PythonObjectFactory factory) { + @Cached BytesNodes.CreateBytesNode create) { boolean keepends; if (keependsObj instanceof Boolean b) { isBooleanProfile.enter(inliningTarget); @@ -1884,7 +1862,7 @@ static PList doSplitlines(Object self, Object keependsObj, } keepends = keependsProfile.profile(inliningTarget, keepends); byte[] bytes = toBytesNode.execute(null, self); - PList list = factory.createList(); + PList list = PFactory.createList(language); int sliceStart = 0; for (int i = 0; i < bytes.length; i++) { if (bytes[i] == '\n' || bytes[i] == '\r') { @@ -1896,14 +1874,14 @@ static PList doSplitlines(Object self, Object keependsObj, sliceEnd = i + 1; } byte[] slice = copySlice(bytes, sliceStart, sliceEnd); - appendNode.execute(list, create.execute(inliningTarget, factory, self, slice)); + appendNode.execute(list, create.execute(inliningTarget, self, slice)); sliceStart = i + 1; } } // Process the remaining part if any if (sliceStart != bytes.length) { byte[] slice = copySlice(bytes, sliceStart, bytes.length); - appendNode.execute(list, create.execute(inliningTarget, factory, self, slice)); + appendNode.execute(list, create.execute(inliningTarget, self, slice)); } return list; } @@ -1922,10 +1900,9 @@ abstract static class AStripNode extends PythonBinaryBuiltinNode { PBytesLike strip(VirtualFrame frame, Object self, @SuppressWarnings("unused") PNone bytes, @Bind("this") Node node, @Shared("createByte") @Cached BytesNodes.CreateBytesNode create, - @Shared("toByteSelf") @Cached BytesNodes.ToBytesNode toBytesNode, - @Shared @Cached PythonObjectFactory factory) { + @Shared("toByteSelf") @Cached BytesNodes.ToBytesNode toBytesNode) { byte[] bs = toBytesNode.execute(frame, self); - return create.execute(node, factory, self, getResultBytes(bs, findIndex(bs))); + return create.execute(node, self, getResultBytes(bs, findIndex(bs))); } @Specialization(guards = "!isPNone(object)") @@ -1935,14 +1912,13 @@ PBytesLike strip(VirtualFrame frame, Object self, Object object, @CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Shared("createByte") @Cached BytesNodes.CreateBytesNode create, - @Shared("toByteSelf") @Cached BytesNodes.ToBytesNode selfToBytesNode, - @Shared @Cached PythonObjectFactory factory) { + @Shared("toByteSelf") @Cached BytesNodes.ToBytesNode selfToBytesNode) { Object buffer = bufferAcquireLib.acquireReadonly(object, frame, indirectCallData); try { byte[] stripBs = bufferLib.getInternalOrCopiedByteArray(buffer); int stripBsLen = bufferLib.getBufferLength(buffer); byte[] bs = selfToBytesNode.execute(frame, self); - return create.execute(node, factory, self, getResultBytes(bs, findIndex(bs, stripBs, stripBsLen))); + return create.execute(node, self, getResultBytes(bs, findIndex(bs, stripBs, stripBsLen))); } finally { bufferLib.release(buffer, frame, indirectCallData); } @@ -1951,8 +1927,8 @@ PBytesLike strip(VirtualFrame frame, Object self, Object object, @Fallback @SuppressWarnings("unused") static Object strip(Object self, Object object, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, ErrorMessages.INVALID_ARGS, "lstrip/rstrip"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, ErrorMessages.INVALID_ARGS, "lstrip/rstrip"); } protected abstract int mod(); @@ -2080,13 +2056,13 @@ public abstract static class MakeTransNode extends PythonBuiltinNode { @Specialization static PBytes maketrans(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object from, Object to, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached BytesNodes.ToBytesNode toByteNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { byte[] fromB = toByteNode.execute(frame, from); byte[] toB = toByteNode.execute(frame, to); if (fromB.length != toB.length) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.ARGS_MUST_HAVE_SAME_LENGTH, "maketrans"); + throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.ARGS_MUST_HAVE_SAME_LENGTH, "maketrans"); } byte[] table = new byte[256]; @@ -2099,7 +2075,7 @@ static PBytes maketrans(VirtualFrame frame, @SuppressWarnings("unused") Object c table[value < 0 ? value + 256 : value] = toB[i]; } - return factory.createBytes(table); + return PFactory.createBytes(language, table); } } @@ -2112,17 +2088,16 @@ abstract static class CapitalizeNode extends PythonUnaryBuiltinNode { static PBytesLike capitalize(Object self, @Bind("this") Node inliningTarget, @Cached ToBytesNode toBytesNode, - @Cached BytesNodes.CreateBytesNode create, - @Cached PythonObjectFactory factory) { + @Cached BytesNodes.CreateBytesNode create) { byte[] b = toBytesNode.execute(null, self); if (b.length == 0) { - return create.execute(inliningTarget, factory, self, PythonUtils.EMPTY_BYTE_ARRAY); + return create.execute(inliningTarget, self, PythonUtils.EMPTY_BYTE_ARRAY); } b[0] = toUpper(b[0]); for (int i = 1; i < b.length; i++) { b[i] = toLower(b[i]); } - return create.execute(inliningTarget, factory, self, b); + return create.execute(inliningTarget, self, b); } } @@ -2134,11 +2109,10 @@ abstract static class TitleNode extends PythonUnaryBuiltinNode { static PBytesLike title(Object self, @Bind("this") Node inliningTarget, @Cached ToBytesNode toBytesNode, - @Cached BytesNodes.CreateBytesNode create, - @Cached PythonObjectFactory factory) { + @Cached BytesNodes.CreateBytesNode create) { byte[] b = toBytesNode.execute(null, self); if (b.length == 0) { - return create.execute(inliningTarget, factory, self, PythonUtils.EMPTY_BYTE_ARRAY); + return create.execute(inliningTarget, self, PythonUtils.EMPTY_BYTE_ARRAY); } boolean previousIsCased = false; @@ -2160,7 +2134,7 @@ static PBytesLike title(Object self, b[i] = c; } - return create.execute(inliningTarget, factory, self, b); + return create.execute(inliningTarget, self, b); } } @@ -2172,11 +2146,10 @@ abstract static class SwapCaseNode extends PythonUnaryBuiltinNode { static PBytesLike swapcase(Object self, @Bind("this") Node inliningTarget, @Cached ToBytesNode toBytesNode, - @Cached BytesNodes.CreateBytesNode create, - @Cached PythonObjectFactory factory) { + @Cached BytesNodes.CreateBytesNode create) { byte[] b = toBytesNode.execute(null, self); if (b.length == 0) { - return create.execute(inliningTarget, factory, self, PythonUtils.EMPTY_BYTE_ARRAY); + return create.execute(inliningTarget, self, PythonUtils.EMPTY_BYTE_ARRAY); } for (int i = 0; i < b.length; i++) { if (BytesUtils.isUpper(b[i])) { @@ -2185,7 +2158,7 @@ static PBytesLike swapcase(Object self, b[i] = toUpper(b[i]); } } - return create.execute(inliningTarget, factory, self, b); + return create.execute(inliningTarget, self, b); } } @@ -2205,12 +2178,11 @@ static PBytesLike expandtabs(Object self, int tabsize, @Cached GetBytesStorage getBytesStorage, @Cached GetInternalByteArrayNode getInternalByteArrayNode, @Cached BytesNodes.CreateBytesNode create, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { SequenceStorage storage = getBytesStorage.execute(inliningTarget, self); int len = storage.length(); if (len == 0) { - return create.execute(inliningTarget, factory, self, PythonUtils.EMPTY_BYTE_ARRAY); + return create.execute(inliningTarget, self, PythonUtils.EMPTY_BYTE_ARRAY); } int max = SysModuleBuiltins.MAXSIZE; byte[] b = getInternalByteArrayNode.execute(inliningTarget, storage); @@ -2221,18 +2193,18 @@ static PBytesLike expandtabs(Object self, int tabsize, if (tabsize > 0) { int incr = tabsize - (j % tabsize); if (j > max - incr) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.RESULT_TOO_LONG); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.RESULT_TOO_LONG); } j += incr; } } else { if (j > max - 1) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.RESULT_TOO_LONG); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.RESULT_TOO_LONG); } j++; if (p == N || p == R) { if (i > max - j) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.RESULT_TOO_LONG); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.RESULT_TOO_LONG); } i += j; j = 0; @@ -2240,7 +2212,7 @@ static PBytesLike expandtabs(Object self, int tabsize, } } if (i > max - j) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.RESULT_TOO_LONG); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.RESULT_TOO_LONG); } byte[] q = new byte[i + j]; @@ -2264,7 +2236,7 @@ static PBytesLike expandtabs(Object self, int tabsize, } } - return create.execute(inliningTarget, factory, self, q); + return create.execute(inliningTarget, self, q); } @Override @@ -2283,10 +2255,9 @@ static PBytesLike zfill(Object self, int width, @Bind("this") Node inliningTarget, @Cached GetBytesStorage getBytesStorage, @Cached GetInternalByteArrayNode getInternalByteArrayNode, - @Cached BytesNodes.CreateBytesNode create, - @Cached PythonObjectFactory factory) { + @Cached BytesNodes.CreateBytesNode create) { SequenceStorage storage = getBytesStorage.execute(inliningTarget, self); - return create.execute(inliningTarget, factory, self, zfill(getInternalByteArrayNode.execute(inliningTarget, storage), storage.length(), width)); + return create.execute(inliningTarget, self, zfill(getInternalByteArrayNode.execute(inliningTarget, storage), storage.length(), width)); } private static byte[] zfill(byte[] self, int len, int width) { @@ -2361,9 +2332,9 @@ public abstract static class GetNewargsNode extends PythonUnaryBuiltinNode { @Specialization static PTuple doBytes(Object self, @Bind("this") Node inliningTarget, - @Cached GetBytesStorage getBytesStorage, - @Cached PythonObjectFactory factory) { - return factory.createTuple(new Object[]{factory.createBytes(getBytesStorage.execute(inliningTarget, self))}); + @Bind PythonLanguage language, + @Cached GetBytesStorage getBytesStorage) { + return PFactory.createTuple(language, new Object[]{PFactory.createBytes(language, getBytesStorage.execute(inliningTarget, self))}); } } @@ -2377,8 +2348,7 @@ static PBytesLike remove(VirtualFrame frame, Object self, Object prefix, @CachedLibrary(limit = "1") PythonBufferAcquireLibrary bufferAcquireLib, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Cached BytesNodes.CreateBytesNode create, - @Cached InlinedConditionProfile profile, - @Cached PythonObjectFactory factory) { + @Cached InlinedConditionProfile profile) { Object selfBuffer = bufferAcquireLib.acquireReadonly(self, frame, indirectCallData); Object prefixBuffer = bufferAcquireLib.acquireReadonly(prefix, frame, indirectCallData); @@ -2394,15 +2364,15 @@ static PBytesLike remove(VirtualFrame frame, Object self, Object prefix, for (int i = 0; i < selfBsLen; i++) { if (i < prefixBsLen) { if (selfBs[i] != prefixBs[i]) { - return create.execute(node, factory, self, selfBs); + return create.execute(node, self, selfBs); } } else { result[j++] = selfBs[i]; } } - return create.execute(node, factory, self, result); + return create.execute(node, self, result); } - return create.execute(node, factory, self, selfBs); + return create.execute(node, self, selfBs); } finally { bufferLib.release(selfBuffer, frame, indirectCallData); bufferLib.release(prefixBuffer, frame, indirectCallData); @@ -2420,8 +2390,7 @@ static PBytesLike remove(VirtualFrame frame, Object self, Object suffix, @CachedLibrary(limit = "1") PythonBufferAcquireLibrary bufferAcquireLib, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Cached BytesNodes.CreateBytesNode create, - @Cached InlinedConditionProfile profile, - @Cached PythonObjectFactory factory) { + @Cached InlinedConditionProfile profile) { Object selfBuffer = bufferAcquireLib.acquireReadonly(self, frame, indirectCallData); Object suffixBuffer = bufferAcquireLib.acquireReadonly(suffix, frame, indirectCallData); try { @@ -2436,15 +2405,15 @@ static PBytesLike remove(VirtualFrame frame, Object self, Object suffix, for (int i = selfBsLen - 1, j = 1; i >= 0; i--, j++) { if (i >= selfBsLen - suffixBsLen) { if (selfBs[i] != suffixBs[suffixBsLen - j]) { - return create.execute(node, factory, self, selfBs); + return create.execute(node, self, selfBs); } } else { result[result.length - k++] = selfBs[i]; } } - return create.execute(node, factory, self, result); + return create.execute(node, self, result); } - return create.execute(node, factory, self, selfBs); + return create.execute(node, self, selfBs); } finally { bufferLib.release(selfBuffer, frame, indirectCallData); bufferLib.release(suffixBuffer, frame, indirectCallData); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesNodes.java index c384cd4a50..ff2ea607c0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesNodes.java @@ -58,6 +58,7 @@ import java.util.ArrayList; import java.util.Arrays; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ClinicConverterFactory; import com.oracle.graal.python.annotations.ClinicConverterFactory.ArgumentIndex; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -75,13 +76,16 @@ import com.oracle.graal.python.builtins.objects.iterator.IteratorNodes; import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.builtins.objects.str.StringNodes; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyByteArrayCheckNode; import com.oracle.graal.python.lib.PyBytesCheckNode; import com.oracle.graal.python.lib.PyIndexCheckNode; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyOSFSPathNode; import com.oracle.graal.python.lib.PyObjectGetIter; +import com.oracle.graal.python.lib.PyUnicodeCheckNode; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; @@ -98,11 +102,10 @@ import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.NativeByteSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; -import com.oracle.graal.python.util.ComparisonOp; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -135,33 +138,37 @@ public abstract class BytesNodes { @GenerateCached(false) public abstract static class CreateBytesNode extends Node { - public final PBytesLike execute(Node inliningTarget, PythonObjectFactory factory, Object basedOn, byte[] bytes) { - return execute(inliningTarget, factory, basedOn, new ByteSequenceStorage(bytes)); + public final PBytesLike execute(Node inliningTarget, Object basedOn, byte[] bytes) { + return execute(inliningTarget, basedOn, new ByteSequenceStorage(bytes)); } - public abstract PBytesLike execute(Node inliningTarget, PythonObjectFactory factory, Object basedOn, SequenceStorage bytes); + public abstract PBytesLike execute(Node inliningTarget, Object basedOn, SequenceStorage bytes); @Specialization - static PBytesLike bytes(PythonObjectFactory factory, @SuppressWarnings("unused") PBytes basedOn, SequenceStorage bytes) { - return factory.createBytes(bytes); + static PBytesLike bytes(@SuppressWarnings("unused") PBytes basedOn, SequenceStorage bytes, + @Bind PythonLanguage language) { + return PFactory.createBytes(language, bytes); } @Specialization - static PBytesLike bytearray(PythonObjectFactory factory, @SuppressWarnings("unused") PByteArray basedOn, SequenceStorage bytes) { - return factory.createByteArray(bytes); + static PBytesLike bytearray(@SuppressWarnings("unused") PByteArray basedOn, SequenceStorage bytes, + @Bind PythonLanguage language) { + return PFactory.createByteArray(language, bytes); } @Specialization(guards = "checkBytes.execute(inliningTarget, basedOn)") - static PBytesLike bytes(@SuppressWarnings("unused") Node inliningTarget, PythonObjectFactory factory, @SuppressWarnings("unused") Object basedOn, SequenceStorage bytes, - @SuppressWarnings("unused") @Shared @Cached PyBytesCheckNode checkBytes) { - return factory.createBytes(bytes); + static PBytesLike bytes(@SuppressWarnings("unused") Node inliningTarget, @SuppressWarnings("unused") Object basedOn, SequenceStorage bytes, + @SuppressWarnings("unused") @Shared @Cached PyBytesCheckNode checkBytes, + @Bind PythonLanguage language) { + return PFactory.createBytes(language, bytes); } @Specialization(guards = "!checkBytes.execute(inliningTarget, basedOn)") - static PBytesLike bytearray(@SuppressWarnings("unused") Node inliningTarget, PythonObjectFactory factory, @SuppressWarnings("unused") Object basedOn, SequenceStorage bytes, - @SuppressWarnings("unused") @Shared @Cached PyBytesCheckNode checkBytes) { + static PBytesLike bytearray(@SuppressWarnings("unused") Node inliningTarget, @SuppressWarnings("unused") Object basedOn, SequenceStorage bytes, + @SuppressWarnings("unused") @Shared @Cached PyBytesCheckNode checkBytes, + @Bind PythonLanguage language) { assert PyByteArrayCheckNode.executeUncached(basedOn); - return factory.createByteArray(bytes); + return PFactory.createByteArray(language, bytes); } } @@ -175,19 +182,19 @@ public abstract static class BytesJoinNode extends PNodeWithContext { @Specialization static byte[] join(VirtualFrame frame, Node inliningTarget, byte[] sep, Object iterable, @Cached PyObjectGetIter getIter, - @Cached(inline = false) GetNextNode getNextNode, - @Cached(inline = false) ToBytesNode toBytesNode, - @Cached IsBuiltinObjectProfile errorProfile) { + @Cached PyIterNextNode nextNode, + @Cached(inline = false) ToBytesNode toBytesNode) { ArrayList parts = new ArrayList<>(); int partsTotalSize = 0; Object iterator = getIter.execute(frame, inliningTarget, iterable); while (true) { + Object next; try { - partsTotalSize += append(parts, toBytesNode.execute(frame, getNextNode.execute(frame, iterator))); - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); + next = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { return joinArrays(sep, parts, partsTotalSize); } + partsTotalSize += append(parts, toBytesNode.execute(frame, next)); } } @@ -247,12 +254,12 @@ byte[] doBuffer(VirtualFrame frame, Object object, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("object") PythonBufferAcquireLibrary bufferAcquireLib, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object buffer; try { buffer = bufferAcquireLib.acquireReadonly(object, frame, indirectCallData); } catch (PException e) { - throw raiseNode.get(inliningTarget).raise(errorType, errorMessageFormat, object); + throw raiseNode.raise(inliningTarget, errorType, errorMessageFormat, object); } try { return bufferLib.getCopiedByteArray(buffer); @@ -282,12 +289,12 @@ public abstract static class ToBytesWithoutFrameNode extends Node { static byte[] doBuffer(Node inliningTarget, Object object, @CachedLibrary("object") PythonBufferAcquireLibrary bufferAcquireLib, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object buffer; try { buffer = bufferAcquireLib.acquireReadonly(object); } catch (PException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, EXPECTED_BYTESLIKE_GOT_P, object); + throw raiseNode.raise(inliningTarget, TypeError, EXPECTED_BYTESLIKE_GOT_P, object); } try { return bufferLib.getCopiedByteArray(buffer); @@ -458,7 +465,7 @@ static boolean check(Node inliningTarget, PythonAbstractNativeObject obj, @Cached GetClassNode getClassNode, @Cached(inline = false) IsSubtypeNode isSubtypeNode) { Object type = getClassNode.execute(inliningTarget, obj); - return isSubtypeNode.execute(null, type, PythonBuiltinClassType.PBytes) || isSubtypeNode.execute(null, type, PythonBuiltinClassType.PByteArray); + return isSubtypeNode.execute(type, PythonBuiltinClassType.PBytes) || isSubtypeNode.execute(type, PythonBuiltinClassType.PByteArray); } @Fallback @@ -523,8 +530,8 @@ static Object str(PString str, @Fallback Object doOthers(@SuppressWarnings("unused") VirtualFrame frame, Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, className, argNum, PythonBuiltinClassType.PString, value); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, className, argNum, PythonBuiltinClassType.PString, value); } @ClinicConverterFactory @@ -555,7 +562,8 @@ static byte[] doGeneric(VirtualFrame frame, Object object, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached BytesNodes.IterableToByteNode iterableToByteNode, @Cached IsBuiltinObjectProfile errorProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PyUnicodeCheckNode unicodeCheckNode, + @Cached PRaiseNode raiseNode) { if (bufferAcquireLib.hasBuffer(object)) { // TODO PyBUF_FULL_RO Object buffer = bufferAcquireLib.acquire(object, BufferFlags.PyBUF_ND, frame, indirectCallData); @@ -565,14 +573,14 @@ static byte[] doGeneric(VirtualFrame frame, Object object, bufferLib.release(buffer, frame, indirectCallData); } } - if (!PGuards.isString(object)) { + if (!unicodeCheckNode.execute(inliningTarget, object)) { try { return iterableToByteNode.execute(frame, object); } catch (PException e) { e.expect(inliningTarget, TypeError, errorProfile); } } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANNOT_CONVERT_P_OBJ_TO_S, object, "bytes"); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANNOT_CONVERT_P_OBJ_TO_S, object, "bytes"); } } @@ -600,18 +608,18 @@ static byte[] fromObject(VirtualFrame frame, Node inliningTarget, Object source, @Cached PyNumberAsSizeNode asSizeNode, @Cached(inline = false) BytesFromObject bytesFromObject, // Exclusive as a workaround for GR-44836 - @Cached @Exclusive PRaiseNode.Lazy raiseNode) { + @Cached @Exclusive PRaiseNode raiseNode) { if (indexCheckNode.execute(inliningTarget, source)) { try { int size = asSizeNode.executeExact(frame, inliningTarget, source); if (size < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.NEGATIVE_COUNT); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NEGATIVE_COUNT); } try { return new byte[size]; } catch (OutOfMemoryError error) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw raiseNode.get(inliningTarget).raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } } catch (PException e) { e.expect(inliningTarget, TypeError, errorProfile); @@ -638,18 +646,18 @@ static byte[] fromString(Node inliningTarget, Object source, Object encoding, Ob @Specialization(guards = "isString(source)") @SuppressWarnings("unused") static byte[] fromString(Node inliningTarget, Object source, PNone encoding, Object errors, - @Cached @Shared PRaiseNode.Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.STRING_ARG_WO_ENCODING); + @Cached @Shared PRaiseNode raiseNode) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.STRING_ARG_WO_ENCODING); } @Fallback @SuppressWarnings("unused") public static byte[] error(Node inliningTarget, Object source, Object encoding, Object errors, - @Cached @Shared PRaiseNode.Lazy raiseNode) { + @Cached @Shared PRaiseNode raiseNode) { if (PGuards.isNone(encoding)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ENCODING_ARG_WO_STRING); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ENCODING_ARG_WO_STRING); } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ERRORS_WITHOUT_STR_ARG); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ERRORS_WITHOUT_STR_ARG); } } @@ -681,7 +689,7 @@ static TruffleString negative(Node inliningTarget, byte[] argbuf, int arglen, by @Shared @Cached InlinedConditionProfile earlyExit, @Shared @Cached(inline = false) TruffleString.FromByteArrayNode fromByteArrayNode, @Shared @Cached(inline = false) TruffleString.SwitchEncodingNode switchEncodingNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { if (earlyExit.profile(inliningTarget, arglen == 0)) { return T_EMPTY_STRING; } @@ -689,7 +697,7 @@ static TruffleString negative(Node inliningTarget, byte[] argbuf, int arglen, by /* How many sep characters we'll be inserting. */ int resultlen = (arglen - 1) / absBytesPerSepGroup; if (arglen >= SysModuleBuiltins.MAXSIZE / 2 - resultlen) { - throw raiseNode.get(inliningTarget).raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } resultlen += arglen * 2; @@ -723,7 +731,7 @@ static TruffleString positive(Node inliningTarget, byte[] argbuf, int arglen, by @Shared @Cached InlinedConditionProfile earlyExit, @Shared @Cached(inline = false) TruffleString.FromByteArrayNode fromByteArrayNode, @Shared @Cached(inline = false) TruffleString.SwitchEncodingNode switchEncodingNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { if (earlyExit.profile(inliningTarget, arglen == 0)) { return T_EMPTY_STRING; } @@ -731,7 +739,7 @@ static TruffleString positive(Node inliningTarget, byte[] argbuf, int arglen, by int resultlen = (arglen - 1) / absBytesPerSepGroup; if (arglen >= SysModuleBuiltins.MAXSIZE / 2 - resultlen) { - throw raiseNode.get(inliningTarget).raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } resultlen += arglen * 2; @@ -769,8 +777,7 @@ public abstract static class IterableToByteNode extends Node { static byte[] bytearray(VirtualFrame frame, Object iterable, @Bind("this") Node inliningTarget, @Cached IteratorNodes.GetLength lenghtHintNode, - @Cached GetNextNode getNextNode, - @Cached IsBuiltinObjectProfile stopIterationProfile, + @Cached PyIterNextNode nextNode, @Cached CastToByteNode castToByteNode, @Cached PyObjectGetIter getIter) { Object it = getIter.execute(frame, inliningTarget, iterable); @@ -778,16 +785,17 @@ static byte[] bytearray(VirtualFrame frame, Object iterable, byte[] arr = new byte[len < 16 && len > 0 ? len : 16]; int i = 0; while (true) { + Object next; try { - byte item = castToByteNode.execute(frame, getNextNode.execute(frame, it)); - if (i >= arr.length) { - arr = resize(arr, arr.length * 2); - } - arr[i++] = item; - } catch (PException e) { - e.expectStopIteration(inliningTarget, stopIterationProfile); + next = nextNode.execute(frame, inliningTarget, it); + } catch (IteratorExhausted e) { return resize(arr, i); } + byte item = castToByteNode.execute(frame, next); + if (i >= arr.length) { + arr = resize(arr, arr.length * 2); + } + arr[i++] = item; } } @@ -879,7 +887,7 @@ static byte[] ascii(TruffleString str, @Shared("getCodeRange") @Cached @SuppressWarnings("unused") TruffleString.GetCodeRangeNode getCodeRangeNode, @Cached TruffleString.SwitchEncodingNode switchEncodingNode, @Cached TruffleString.GetInternalByteArrayNode getInternalByteArrayNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { TruffleString ascii = switchEncodingNode.execute(str, Encoding.US_ASCII); InternalByteArray iba = getInternalByteArrayNode.execute(ascii, Encoding.US_ASCII); byte[] bytes = new byte[iba.getLength() / 2]; @@ -892,13 +900,13 @@ static byte[] ascii(TruffleString str, } int top = BytesUtils.digitValue(c); if (top >= 16 || top < 0) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, NON_HEX_NUMBER_IN_FROMHEX, i); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, NON_HEX_NUMBER_IN_FROMHEX, i); } c = i + 1 < iba.getEnd() ? strchar[++i] : 0; int bottom = BytesUtils.digitValue(c); if (bottom >= 16 || bottom < 0) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, NON_HEX_NUMBER_IN_FROMHEX, i); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, NON_HEX_NUMBER_IN_FROMHEX, i); } bytes[n++] = (byte) ((top << 4) | bottom); @@ -915,12 +923,12 @@ static byte[] nonAscii(TruffleString str, @Shared("getCodeRange") @Cached @SuppressWarnings("unused") TruffleString.GetCodeRangeNode getCodeRangeNode, @Cached TruffleString.CreateCodePointIteratorNode createCodePointIteratorNode, @Cached TruffleStringIterator.NextNode nextNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { TruffleStringIterator it = createCodePointIteratorNode.execute(str, TS_ENCODING); int i = 0; while (it.hasNext()) { if (nextNode.execute(it) > 127) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, NON_HEX_NUMBER_IN_FROMHEX, i); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, NON_HEX_NUMBER_IN_FROMHEX, i); } ++i; } @@ -981,10 +989,10 @@ public static int adjustEndIndex(int endIn, int len) { return endIn; } - static boolean compareByteArrays(ComparisonOp op, byte[] selfArray, int selfLength, byte[] otherArray, int otherLength) { + static boolean compareByteArrays(RichCmpOp op, byte[] selfArray, int selfLength, byte[] otherArray, int otherLength) { int compareResult = 0; - if ((op == ComparisonOp.EQ || op == ComparisonOp.NE) && selfLength != otherLength) { - return op == ComparisonOp.NE; + if (op.isEqOrNe() && selfLength != otherLength) { + return op == RichCmpOp.Py_NE; } for (int i = 0; i < Math.min(selfLength, otherLength); i++) { compareResult = Byte.compareUnsigned(selfArray[i], otherArray[i]); @@ -995,15 +1003,15 @@ static boolean compareByteArrays(ComparisonOp op, byte[] selfArray, int selfLeng if (compareResult == 0) { compareResult = Integer.compare(selfLength, otherLength); } - return op.cmpResultToBool(compareResult); + return op.compareResultToBool(compareResult); } @GenerateCached(false) public abstract static class BaseTranslateNode extends PythonBuiltinNode { - static void checkLengthOfTable(Node inliningTarget, byte[] table, InlinedConditionProfile isLenTable256Profile, PRaiseNode.Lazy raiseNode) { + static void checkLengthOfTable(Node inliningTarget, byte[] table, InlinedConditionProfile isLenTable256Profile, PRaiseNode raiseNode) { if (isLenTable256Profile.profile(inliningTarget, table.length != 256)) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.TRANS_TABLE_MUST_BE_256); + throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.TRANS_TABLE_MUST_BE_256); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PByteArray.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PByteArray.java index 039317f973..dc1a8f7e83 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PByteArray.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PByteArray.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2014, Regents of the University of California * * All rights reserved. @@ -94,9 +94,9 @@ public void setExports(long exports) { this.exports = exports; } - public void checkCanResize(Node inliningTarget, PRaiseNode.Lazy raiseNode) { + public void checkCanResize(Node inliningTarget, PRaiseNode raiseNode) { if (exports != 0) { - throw raiseNode.get(inliningTarget).raise(BufferError, ErrorMessages.EXPORTS_CANNOT_RESIZE); + throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.EXPORTS_CANNOT_RESIZE); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytes.java index be372e2f33..64317fe78a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2014, Regents of the University of California * * All rights reserved. @@ -35,12 +35,14 @@ import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.InvalidArrayIndexException; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; @SuppressWarnings("truffle-abstract-export") @@ -99,9 +101,10 @@ public static void removeArrayElement(PBytes self, long key) throws UnsupportedM @ExportMessage Object acquire(int flags, + @Bind("$node") Node inliningTarget, @Cached PRaiseNode raiseNode) { if ((flags & BufferFlags.PyBUF_WRITABLE) != 0) { - throw raiseNode.raise(BufferError, ErrorMessages.OBJ_IS_NOT_WRITABLE); + throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.OBJ_IS_NOT_WRITABLE); } return this; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytesLike.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytesLike.java index 7819c7a3ab..491412d850 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytesLike.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytesLike.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cell/CellBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cell/CellBuiltins.java index 56edf4e0a3..b9dc85f8bb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cell/CellBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cell/CellBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,24 +40,17 @@ */ package com.oracle.graal.python.builtins.objects.cell; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; +import static com.oracle.graal.python.nodes.PGuards.isNoValue; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___EQ__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NE__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -66,14 +59,23 @@ import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.PythonAbstractObject; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare; import com.oracle.graal.python.lib.PyObjectRichCompareBool; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.Assumption; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; @@ -90,194 +92,78 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PCell) public final class CellBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = CellBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return CellBuiltinsFactory.getFactories(); } - @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "cell", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2) @GenerateNodeFactory - public abstract static class EqNode extends PythonBuiltinNode { - @Specialization - static boolean eq(VirtualFrame frame, PCell self, PCell other, - @Bind("this") Node inliningTarget, - @Cached PyObjectRichCompareBool.EqNode eqNode, - @Cached InlinedConditionProfile nonEmptyProfile, - @Cached GetRefNode getRefL, - @Cached GetRefNode getRefR) { - Object left = getRefL.execute(inliningTarget, self); - Object right = getRefR.execute(inliningTarget, other); - if (nonEmptyProfile.profile(inliningTarget, left != null && right != null)) { - return eqNode.compare(frame, inliningTarget, left, right); - } - return left == null && right == null; - } - - @SuppressWarnings("unused") - @Fallback - static Object eq(Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { - if (self instanceof PCell) { - return PNotImplemented.NOT_IMPLEMENTED; - } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___EQ__, "cell", self); - } - } + public abstract static class CellTypeNode extends PythonBinaryBuiltinNode { + @CompilerDirectives.CompilationFinal private Assumption sharedAssumption; - @Builtin(name = J___NE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class NeNode extends PythonBuiltinNode { - @Specialization - static boolean ne(VirtualFrame frame, PCell self, PCell other, - @Bind("this") Node inliningTarget, - @Cached PyObjectRichCompareBool.NeNode neNode, - @Cached InlinedConditionProfile nonEmptyProfile, - @Cached GetRefNode getRefL, - @Cached GetRefNode getRefR) { - Object left = getRefL.execute(inliningTarget, self); - Object right = getRefR.execute(inliningTarget, other); - if (nonEmptyProfile.profile(inliningTarget, left != null && right != null)) { - return neNode.compare(frame, inliningTarget, left, right); + private Assumption getAssumption() { + if (sharedAssumption == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + sharedAssumption = Truffle.getRuntime().createAssumption("cell is effectively final"); } - return left != null || right != null; - } - - @SuppressWarnings("unused") - @Fallback - static Object eq(Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { - if (self instanceof PCell) { - return PNotImplemented.NOT_IMPLEMENTED; + if (CompilerDirectives.inCompiledCode()) { + return sharedAssumption; + } else { + return Truffle.getRuntime().createAssumption("cell is effectively final"); } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___NE__, "cell", self); } - } - @Builtin(name = J___LT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class LtNode extends PythonBuiltinNode { @Specialization - static boolean lt(VirtualFrame frame, PCell self, PCell other, + Object newCell(@SuppressWarnings("unused") Object cls, Object contents, @Bind("this") Node inliningTarget, - @Cached PyObjectRichCompareBool.LtNode ltNode, - @Cached InlinedConditionProfile nonEmptyProfile, - @Cached GetRefNode getRefL, - @Cached GetRefNode getRefR) { - Object left = getRefL.execute(inliningTarget, self); - Object right = getRefR.execute(inliningTarget, other); - if (nonEmptyProfile.profile(inliningTarget, left != null && right != null)) { - return ltNode.compare(frame, inliningTarget, left, right); + @Bind PythonLanguage language, + @Cached InlinedConditionProfile nonEmptyProfile) { + Assumption assumption = getAssumption(); + PCell cell = PFactory.createCell(language, assumption); + if (nonEmptyProfile.profile(inliningTarget, !isNoValue(contents))) { + cell.setRef(contents, assumption); } - return right != null; - } - - @SuppressWarnings("unused") - @Fallback - static Object notImplemented(Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { - if (self instanceof PCell) { - return PNotImplemented.NOT_IMPLEMENTED; - } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___LT__, "cell", self); + return cell; } } - @Builtin(name = J___LE__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.tp_richcompare, isComplex = true) @GenerateNodeFactory - public abstract static class LeNode extends PythonBuiltinNode { + public abstract static class EqNode extends TpSlotRichCompare.RichCmpBuiltinNode { @Specialization - static boolean le(VirtualFrame frame, PCell self, PCell other, + static boolean eq(VirtualFrame frame, PCell self, PCell other, RichCmpOp op, @Bind("this") Node inliningTarget, - @Cached PyObjectRichCompareBool.LeNode leNode, + @Cached PyObjectRichCompareBool richCmpNode, @Cached InlinedConditionProfile nonEmptyProfile, @Cached GetRefNode getRefL, @Cached GetRefNode getRefR) { Object left = getRefL.execute(inliningTarget, self); Object right = getRefR.execute(inliningTarget, other); if (nonEmptyProfile.profile(inliningTarget, left != null && right != null)) { - return leNode.compare(frame, inliningTarget, left, right); + return richCmpNode.execute(frame, inliningTarget, left, right, op); } - return left == null; + return op.compare(right == null, left == null); } @SuppressWarnings("unused") @Fallback - static Object notImplemented(Object self, Object other, + static Object eq(Object self, Object other, RichCmpOp op, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (self instanceof PCell) { return PNotImplemented.NOT_IMPLEMENTED; } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___LE__, "cell", self); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___EQ__, "cell", self); } } - @Builtin(name = J___GT__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory - public abstract static class GtNode extends PythonBuiltinNode { - @Specialization - static boolean gt(VirtualFrame frame, PCell self, PCell other, - @Bind("this") Node inliningTarget, - @Cached PyObjectRichCompareBool.GtNode gtNode, - @Cached InlinedConditionProfile nonEmptyProfile, - @Cached GetRefNode getRefL, - @Cached GetRefNode getRefR) { - Object left = getRefL.execute(inliningTarget, self); - Object right = getRefR.execute(inliningTarget, other); - if (nonEmptyProfile.profile(inliningTarget, left != null && right != null)) { - return gtNode.compare(frame, inliningTarget, left, right); - } - return left != null; - } - - @SuppressWarnings("unused") - @Fallback - static Object notImplemented(Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { - if (self instanceof PCell) { - return PNotImplemented.NOT_IMPLEMENTED; - } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___GT__, "cell", self); - } - } - - @Builtin(name = J___GE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class GeNode extends PythonBuiltinNode { - @Specialization - static boolean ge(VirtualFrame frame, PCell self, PCell other, - @Bind("this") Node inliningTarget, - @Cached PyObjectRichCompareBool.GeNode geNode, - @Cached InlinedConditionProfile nonEmptyProfile, - @Cached GetRefNode getRefL, - @Cached GetRefNode getRefR) { - Object left = getRefL.execute(inliningTarget, self); - Object right = getRefR.execute(inliningTarget, other); - if (nonEmptyProfile.profile(inliningTarget, left != null && right != null)) { - return geNode.compare(frame, inliningTarget, left, right); - } - return right == null; - } - - @SuppressWarnings("unused") - @Fallback - static Object notImplemented(Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { - if (self instanceof PCell) { - return PNotImplemented.NOT_IMPLEMENTED; - } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___GE__, "cell", self); - } - } - - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) - @GenerateNodeFactory - abstract static class ReprNode extends PythonBuiltinNode { + abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization static TruffleString repr(PCell self, @Bind("this") Node inliningTarget, @@ -297,11 +183,11 @@ static TruffleString repr(PCell self, @Fallback static Object eq(Object self, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (self instanceof PCell) { return PNotImplemented.NOT_IMPLEMENTED; } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, "__repr__", "cell", self); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, "__repr__", "cell", self); } } @@ -312,10 +198,10 @@ public abstract static class CellContentsNode extends PythonBuiltinNode { static Object get(PCell self, @SuppressWarnings("unused") PNone none, @Bind("this") Node inliningTarget, @Cached GetRefNode getRef, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object ref = getRef.execute(inliningTarget, self); if (ref == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.IS_EMPTY, "Cell"); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.IS_EMPTY, "Cell"); } return ref; } @@ -350,5 +236,4 @@ Object uncached(PCell self) { return self.getRef(); } } - } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java index f788fa4500..e0f575d679 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,7 +45,6 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.pollReferenceQueue; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___FILE__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___LIBRARY__; -import static com.oracle.graal.python.nodes.StringLiterals.J_LLVM_LANGUAGE; import static com.oracle.graal.python.nodes.StringLiterals.J_NFI_LANGUAGE; import static com.oracle.graal.python.nodes.StringLiterals.T_DASH; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; @@ -70,7 +69,6 @@ import java.util.logging.Level; import org.graalvm.collections.Pair; -import org.graalvm.nativeimage.ImageInfo; import org.graalvm.shadowed.com.ibm.icu.impl.Punycode; import org.graalvm.shadowed.com.ibm.icu.text.StringPrepParseException; @@ -107,13 +105,11 @@ import com.oracle.graal.python.builtins.objects.cext.structs.CStructs; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.frame.PFrame; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.str.StringNodes; import com.oracle.graal.python.builtins.objects.str.StringUtils; import com.oracle.graal.python.builtins.objects.thread.PLock; -import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.object.GetClassNode; @@ -126,9 +122,7 @@ import com.oracle.graal.python.util.Function; import com.oracle.graal.python.util.PythonSystemThreadTask; import com.oracle.graal.python.util.PythonUtils; -import com.oracle.graal.python.util.Supplier; import com.oracle.graal.python.util.SuppressFBWarnings; -import com.oracle.graal.python.util.WeakIdentityHashMap; import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; @@ -347,8 +341,8 @@ public static TruffleLogger getLogger(Class clazz) { return PythonLanguage.getLogger(LOGGER_CAPI_NAME + "." + clazz.getSimpleName()); } - public CApiContext(PythonContext context, Object llvmLibrary, NativeLibraryLocator locator) { - super(context, llvmLibrary, locator != null); + public CApiContext(PythonContext context, Object library, NativeLibraryLocator locator) { + super(context, library); this.nativeSymbolCache = new Object[NativeCAPISymbol.values().length]; this.nativeLibraryLocator = locator; @@ -363,8 +357,7 @@ public CApiContext(PythonContext context, Object llvmLibrary, NativeLibraryLocat if (!CApiContext.nativeSymbolCacheSingleContextUsed && context.getLanguage().isSingleContext()) { assert CApiContext.nativeSymbolCacheSingleContext == null; - // we cannot be in built-time code because this is using pre-initialized contexts - assert !ImageInfo.inImageBuildtimeCode(); + assert !context.getEnv().isPreInitialization(); // this is the first context accessing the static symbol cache CApiContext.nativeSymbolCacheSingleContext = this.nativeSymbolCache; @@ -659,6 +652,29 @@ private static Object[] getSymbolCache(Node caller) { return PythonContext.get(caller).getCApiContext().nativeSymbolCache; } + public static boolean isIdenticalToSymbol(Object obj, NativeCAPISymbol symbol) { + CompilerAsserts.neverPartOfCompilation(); + InteropLibrary objLib = InteropLibrary.getUncached(obj); + objLib.toNative(obj); + try { + return isIdenticalToSymbol(objLib.asPointer(obj), symbol); + } catch (UnsupportedMessageException e) { + throw new RuntimeException(e); + } + } + + public static boolean isIdenticalToSymbol(long ptr, NativeCAPISymbol symbol) { + CompilerAsserts.neverPartOfCompilation(); + Object nativeSymbol = getNativeSymbol(null, symbol); + InteropLibrary lib = InteropLibrary.getUncached(nativeSymbol); + lib.toNative(nativeSymbol); + try { + return lib.asPointer(nativeSymbol) == ptr; + } catch (UnsupportedMessageException e) { + throw new RuntimeException(e); + } + } + public static Object getNativeSymbol(Node caller, NativeCAPISymbol symbol) { Object[] nativeSymbolCache = getSymbolCache(caller); Object result = nativeSymbolCache[symbol.ordinal()]; @@ -678,7 +694,7 @@ private static Object lookupNativeSymbol(Object[] nativeSymbolCache, NativeCAPIS CompilerAsserts.neverPartOfCompilation(); String name = symbol.getName(); try { - Object nativeSymbol = InteropLibrary.getUncached().readMember(PythonContext.get(null).getCApiContext().getLLVMLibrary(), name); + Object nativeSymbol = InteropLibrary.getUncached().readMember(PythonContext.get(null).getCApiContext().getLibrary(), name); nativeSymbol = EnsureExecutableNode.executeUncached(nativeSymbol, symbol); VarHandle.storeStoreFence(); return nativeSymbolCache[symbol.ordinal()] = nativeSymbol; @@ -851,7 +867,7 @@ public long getCurrentRSS() { @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH") // context.get() is never null here void runBackgroundGCTask(PythonContext context) { CompilerAsserts.neverPartOfCompilation(); - if (ImageInfo.inImageBuildtimeCode() // + if (context.getEnv().isPreInitialization() // || context.getOption(PythonOptions.NoAsyncActions) // || !PythonOptions.AUTOMATIC_ASYNC_ACTIONS // || !context.getOption(PythonOptions.BackgroundGCTask)) { @@ -883,14 +899,6 @@ public static CApiContext ensureCapiWasLoaded(String reason) { } } - @TruffleBoundary - public static Object ensureCApiLLVMLibrary(PythonContext context) throws IOException, ImportException, ApiInitException { - assert !PythonOptions.NativeModules.getValue(context.getEnv().getOptions()); - CApiContext cApiContext = ensureCapiWasLoaded(null, context, T_EMPTY_STRING, T_EMPTY_STRING, - " load LLVM library (this is an internal bug, LLVM library should not be loaded when running on native backend)"); - return cApiContext.getLLVMLibrary(); - } - @TruffleBoundary public static CApiContext ensureCapiWasLoaded(Node node, PythonContext context, TruffleString name, TruffleString path) throws IOException, ImportException, ApiInitException { return ensureCapiWasLoaded(node, context, name, path, null); @@ -905,46 +913,36 @@ public static CApiContext ensureCapiWasLoaded(Node node, PythonContext context, TruffleFile homePath = env.getInternalTruffleFile(context.getCAPIHome().toJavaStringUncached()); // e.g. "libpython-native.so" - String libName = context.getLLVMSupportExt("python"); + String libName = PythonContext.getSupportLibName("python-native"); final TruffleFile capiFile = homePath.resolve(libName).getCanonicalFile(); try { SourceBuilder capiSrcBuilder; - boolean useNative = PythonOptions.NativeModules.getValue(env.getOptions()); + boolean useNative = true; boolean isolateNative = PythonOptions.IsolateNativeModules.getValue(env.getOptions()); final NativeLibraryLocator loc; - if (useNative) { - if (!isolateNative) { - useNative = nativeCAPILoaded.compareAndSet(NO_NATIVE_CONTEXT, GLOBAL_NATIVE_CONTEXT); - } else { - useNative = nativeCAPILoaded.compareAndSet(NO_NATIVE_CONTEXT, ISOLATED_NATIVE_CONTEXT) || nativeCAPILoaded.get() == ISOLATED_NATIVE_CONTEXT; - } - if (!useNative) { - String actualReason = "initialize native extensions support"; - if (reason != null) { - actualReason = reason; - } else if (name != null && path != null) { - actualReason = String.format("load a native module '%s' from path '%s'", name.toJavaStringUncached(), path.toJavaStringUncached()); - } - throw new ApiInitException(toTruffleStringUncached( - String.format("Option python.NativeModules is set to 'true' and a second GraalPy context attempted to %s. " + - "At least one context in this process runs with 'IsolateNativeModules' set to false. " + - "Depending on the order of context creation, this means some contexts in the process " + - "cannot use native module, all other contexts must fall back and set python.NativeModules " + - "to 'false' to run native extensions in LLVM mode. This is recommended only " + - "for extensions included in the Python standard library. Running a 3rd party extension in LLVM mode requires " + - "a custom build of the extension and is generally discouraged due to compatibility reasons.", actualReason))); - } - loc = new NativeLibraryLocator(context, capiFile, isolateNative); - context.ensureNFILanguage(node, "NativeModules", "true"); - String dlopenFlags = isolateNative ? "RTLD_LOCAL" : "RTLD_GLOBAL"; - capiSrcBuilder = Source.newBuilder(J_NFI_LANGUAGE, String.format("load(%s) \"%s\"", dlopenFlags, loc.getCapiLibrary()), ""); - LOGGER.config(() -> "loading CAPI from " + loc.getCapiLibrary() + " as native"); + if (!isolateNative) { + useNative = nativeCAPILoaded.compareAndSet(NO_NATIVE_CONTEXT, GLOBAL_NATIVE_CONTEXT); } else { - loc = null; - context.ensureLLVMLanguage(node); - capiSrcBuilder = Source.newBuilder(J_LLVM_LANGUAGE, capiFile); - LOGGER.config(() -> "loading CAPI from " + capiFile + " as bitcode"); + useNative = nativeCAPILoaded.compareAndSet(NO_NATIVE_CONTEXT, ISOLATED_NATIVE_CONTEXT) || nativeCAPILoaded.get() == ISOLATED_NATIVE_CONTEXT; } + if (!useNative) { + String actualReason = "initialize native extensions support"; + if (reason != null) { + actualReason = reason; + } else if (name != null && path != null) { + actualReason = String.format("load a native module '%s' from path '%s'", name.toJavaStringUncached(), path.toJavaStringUncached()); + } + throw new ApiInitException(toTruffleStringUncached( + String.format("Option python.IsolateNativeModules is set to 'false' and a second GraalPy context attempted to %s. " + + "At least one context in this process runs with 'IsolateNativeModules' set to false. " + + "Depending on the order of context creation, this means some contexts in the process " + + "cannot use native module.", actualReason))); + } + loc = new NativeLibraryLocator(context, capiFile, isolateNative); + context.ensureNFILanguage(node, "allowNativeAccess", "true"); + String dlopenFlags = isolateNative ? "RTLD_LOCAL" : "RTLD_GLOBAL"; + capiSrcBuilder = Source.newBuilder(J_NFI_LANGUAGE, String.format("load(%s) \"%s\"", dlopenFlags, loc.getCapiLibrary()), ""); + LOGGER.config(() -> "loading CAPI from " + loc.getCapiLibrary() + " as native"); if (!context.getLanguage().getEngineOption(PythonOptions.ExposeInternalSources)) { capiSrcBuilder.internal(true); } @@ -954,6 +952,7 @@ public static CApiContext ensureCapiWasLoaded(Node node, PythonContext context, Object initFunction = U.readMember(capiLibrary, "initialize_graal_capi"); CApiContext cApiContext = new CApiContext(context, capiLibrary, loc); context.setCApiContext(cApiContext); + try (BuiltinArrayWrapper builtinArrayWrapper = new BuiltinArrayWrapper()) { /* * The GC state needs to be created before the first managed object is sent to @@ -961,40 +960,32 @@ public static CApiContext ensureCapiWasLoaded(Node node, PythonContext context, * then already require the GC state. */ Object gcState = cApiContext.createGCState(); - if (useNative) { - Object signature = env.parseInternal(Source.newBuilder(J_NFI_LANGUAGE, "(ENV,POINTER,POINTER):VOID", "exec").build()).call(); - initFunction = SignatureLibrary.getUncached().bind(signature, initFunction); - U.execute(initFunction, builtinArrayWrapper, gcState); - } else { - assert U.isExecutable(initFunction); - U.execute(initFunction, NativePointer.createNull(), builtinArrayWrapper, gcState); - } + Object signature = env.parseInternal(Source.newBuilder(J_NFI_LANGUAGE, "(ENV,POINTER,POINTER):VOID", "exec").build()).call(); + initFunction = SignatureLibrary.getUncached().bind(signature, initFunction); + U.execute(initFunction, builtinArrayWrapper, gcState); } assert PythonCApiAssertions.assertBuiltins(capiLibrary); cApiContext.pyDateTimeCAPICapsule = PyDateTimeCAPIWrapper.initWrapper(context, cApiContext); context.runCApiHooks(); - if (useNative) { - /* - * C++ libraries sometimes declare global objects that have destructors that - * call Py_DECREF. Those destructors are then called during native shutdown, - * which is after the JVM/SVM shut down and the upcall would segfault. This - * finalizer code rebinds reference operations to native no-ops that don't - * upcall. In normal scenarios we call it during context exit, but when the VM - * is terminated by a signal, the context exit is skipped. For that case we set - * up the shutdown hook. - */ - Object finalizeFunction = U.readMember(capiLibrary, "GraalPy_get_finalize_capi_pointer"); - Object finalizeSignature = env.parseInternal(Source.newBuilder(J_NFI_LANGUAGE, "():POINTER", "exec").build()).call(); - Object finalizingPointer = SignatureLibrary.getUncached().call(finalizeSignature, finalizeFunction); - try { - cApiContext.addNativeFinalizer(context, finalizingPointer); - cApiContext.runBackgroundGCTask(context); - } catch (RuntimeException e) { - // This can happen when other languages restrict multithreading - LOGGER.warning(() -> "didn't register a native finalizer due to: " + e.getMessage()); - } + /* + * C++ libraries sometimes declare global objects that have destructors that call + * Py_DECREF. Those destructors are then called during native shutdown, which is + * after the JVM/SVM shut down and the upcall would segfault. This finalizer code + * rebinds reference operations to native no-ops that don't upcall. In normal + * scenarios we call it during context exit, but when the VM is terminated by a + * signal, the context exit is skipped. For that case we set up the shutdown hook. + */ + Object finalizeFunction = U.readMember(capiLibrary, "GraalPy_get_finalize_capi_pointer"); + Object finalizeSignature = env.parseInternal(Source.newBuilder(J_NFI_LANGUAGE, "():POINTER", "exec").build()).call(); + Object finalizingPointer = SignatureLibrary.getUncached().call(finalizeSignature, finalizeFunction); + try { + cApiContext.addNativeFinalizer(context, finalizingPointer); + cApiContext.runBackgroundGCTask(context); + } catch (RuntimeException e) { + // This can happen when other languages restrict multithreading + LOGGER.warning(() -> "didn't register a native finalizer due to: " + e.getMessage()); } return cApiContext; @@ -1075,51 +1066,40 @@ public static Object loadCExtModule(Node location, PythonContext context, Module Object library; InteropLibrary interopLib; - if (cApiContext.useNativeBackend) { - TruffleFile realPath = context.getPublicTruffleFileRelaxed(spec.path, context.getSoAbi()).getCanonicalFile(); - String loadPath = cApiContext.nativeLibraryLocator.resolve(context, realPath); - getLogger(CApiContext.class).config(String.format("loading module %s (real path: %s) as native", spec.path, loadPath)); - int dlopenFlags = context.getDlopenFlags(); - if (context.getOption(PythonOptions.IsolateNativeModules)) { - if ((dlopenFlags & PosixConstants.RTLD_GLOBAL.value) != 0) { - getLogger(CApiContext.class).warning("The IsolateNativeModules option was specified, but the dlopen flags were set to include RTLD_GLOBAL " + - "(likely via some call to sys.setdlopenflags). This will probably lead to broken isolation and possibly incorrect results and crashing. " + - "You can patch sys.setdlopenflags to trace callers and/or prevent setting the RTLD_GLOBAL flags. " + - "See https://www.graalvm.org/latest/reference-manual/python/Native-Extensions for more details."); - } - dlopenFlags |= PosixConstants.RTLD_LOCAL.value; - } - String loadExpr = String.format("load(%s) \"%s\"", dlopenFlagsToString(dlopenFlags), loadPath); - if (PythonOptions.UsePanama.getValue(context.getEnv().getOptions())) { - loadExpr = "with panama " + loadExpr; - } - try { - Source librarySource = Source.newBuilder(J_NFI_LANGUAGE, loadExpr, "load " + spec.name).build(); - library = context.getEnv().parseInternal(librarySource).call(); - interopLib = InteropLibrary.getUncached(library); - } catch (PException e) { - throw e; - } catch (AbstractTruffleException e) { - if (!realPath.exists() && realPath.toString().contains("org.graalvm.python.vfsx")) { - // file does not exist and it is from VirtualFileSystem - // => we probably failed to extract it due to unconventional libs location - getLogger(CApiContext.class).severe(String.format("could not load module %s (real path: %s) from virtual file system.\n\n" + - "!!! Please try to run with java system property org.graalvm.python.vfs.extractOnStartup=true !!!\n", spec.path, realPath)); - - } - - throw new ImportException(CExtContext.wrapJavaException(e, location), spec.name, spec.path, ErrorMessages.CANNOT_LOAD_M, spec.path, e); + TruffleFile realPath = context.getPublicTruffleFileRelaxed(spec.path, context.getSoAbi()).getCanonicalFile(); + String loadPath = cApiContext.nativeLibraryLocator.resolve(context, realPath); + getLogger(CApiContext.class).config(String.format("loading module %s (real path: %s) as native", spec.path, loadPath)); + int dlopenFlags = context.getDlopenFlags(); + if (context.getOption(PythonOptions.IsolateNativeModules)) { + if ((dlopenFlags & PosixConstants.RTLD_GLOBAL.value) != 0) { + getLogger(CApiContext.class).warning("The IsolateNativeModules option was specified, but the dlopen flags were set to include RTLD_GLOBAL " + + "(likely via some call to sys.setdlopenflags). This will probably lead to broken isolation and possibly incorrect results and crashing. " + + "You can patch sys.setdlopenflags to trace callers and/or prevent setting the RTLD_GLOBAL flags. " + + "See https://www.graalvm.org/latest/reference-manual/python/Native-Extensions for more details."); } - } else { - library = loadLLVMLibrary(location, context, spec.name, spec.path); + dlopenFlags |= PosixConstants.RTLD_LOCAL.value; + } + String loadExpr = String.format("load(%s) \"%s\"", dlopenFlagsToString(dlopenFlags), loadPath); + if (PythonOptions.UsePanama.getValue(context.getEnv().getOptions())) { + loadExpr = "with panama " + loadExpr; + } + try { + Source librarySource = Source.newBuilder(J_NFI_LANGUAGE, loadExpr, "load " + spec.name).build(); + library = context.getEnv().parseInternal(librarySource).call(); interopLib = InteropLibrary.getUncached(library); - try { - if (interopLib.getLanguage(library).toString().startsWith("class com.oracle.truffle.nfi")) { - throw PRaiseNode.raiseUncached(null, PythonBuiltinClassType.SystemError, ErrorMessages.NO_BITCODE_FOUND, spec.path); - } - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(e); + } catch (PException e) { + throw e; + } catch (AbstractTruffleException e) { + if (!realPath.exists() && realPath.toString().contains("org.graalvm.python.vfsx")) { + // file does not exist and it is from VirtualFileSystem + // => we probably failed to extract it due to unconventional libs location + getLogger(CApiContext.class).severe(String.format("could not load module %s (real path: %s) from virtual file system.\n\n" + + "!!! Please try to run with java system property org.graalvm.python.vfs.extractOnStartup=true !!!\n" + + "See also: https://www.graalvm.org/python/docs/#graalpy-troubleshooting", spec.path, realPath)); + } + + throw new ImportException(CExtContext.wrapJavaException(e, location), spec.name, spec.path, ErrorMessages.CANNOT_LOAD_M, spec.path, e); } try { @@ -1134,6 +1114,11 @@ public static Object loadCExtModule(Node location, PythonContext context, Module * know that it's not safe to do upcalls and that native wrappers might have been deallocated. * We need to do it in a VM shutdown hook to make sure C atexit won't crash even if our context * finalization didn't run. + * + * The memory of the shared library may have been re-used if the GraalPy context was shut down + * (cleanly or not), the sources were collected, and NFI's mechanism for unloading libraries + * triggered a dlclose that dropped the refcount of the python-native library to 0. We leak 1 + * byte of memory and this shutdown hook for each context that ever initialized the C API. */ private void addNativeFinalizer(PythonContext context, Object finalizingPointerObj) { final Unsafe unsafe = context.getUnsafe(); @@ -1143,7 +1128,8 @@ private void addNativeFinalizer(PythonContext context, Object finalizingPointerO long finalizingPointer = lib.asPointer(finalizingPointerObj); // We are writing off heap memory and registering a VM shutdown hook, there is no // point in creating this thread via Truffle sandbox at this point - nativeFinalizerRunnable = () -> unsafe.putInt(finalizingPointer, 1); + nativeFinalizerRunnable = () -> unsafe.putByte(finalizingPointer, (byte) 1); + context.registerAtexitHook((c) -> nativeFinalizerRunnable.run()); nativeFinalizerShutdownHook = new Thread(nativeFinalizerRunnable); Runtime.getRuntime().addShutdownHook(nativeFinalizerShutdownHook); } catch (UnsupportedMessageException e) { @@ -1297,7 +1283,7 @@ public Object initCApiModule(Node location, Object sharedLibrary, TruffleString */ Object clazz = GetClassNode.executeUncached(result); if (clazz == PNone.NO_VALUE) { - throw PRaiseNode.raiseUncached(location, PythonBuiltinClassType.SystemError, ErrorMessages.INIT_FUNC_RETURNED_UNINT_OBJ, initFuncName); + throw PRaiseNode.raiseStatic(location, PythonBuiltinClassType.SystemError, ErrorMessages.INIT_FUNC_RETURNED_UNINT_OBJ, initFuncName); } return CreateModuleNodeGen.getUncached().execute(cApiContext, spec, result, sharedLibrary); @@ -1432,13 +1418,13 @@ private static boolean isAvailable(CApiBuiltinExecutable builtin) { if (cApiContext == null) { return false; } - Object llvmLibrary = cApiContext.getLLVMLibrary(); - InteropLibrary lib = InteropLibrary.getUncached(llvmLibrary); - if (!lib.isMemberReadable(llvmLibrary, builtin.name())) { + Object library = cApiContext.getLibrary(); + InteropLibrary lib = InteropLibrary.getUncached(library); + if (!lib.isMemberReadable(library, builtin.name())) { return false; } try { - lib.readMember(llvmLibrary, builtin.name()); + lib.readMember(library, builtin.name()); return true; } catch (UnsupportedMessageException e) { throw CompilerDirectives.shouldNotReachHere(e); @@ -1498,28 +1484,6 @@ public long registerClosure(String nfiSignature, Object executable, Object deleg return pointer; } - /** - * A cache for the wrappers of type slot methods. The key is a weak reference to the owner class - * and the value is a table of wrappers. In order to ensure pointer identity, it is important - * that we use the same wrapper instance as long as the class exists (and the slot wasn't - * updated). Also, the key's type is {@link PythonManagedClass} such that any - * {@link PythonBuiltinClassType} must be resolved, and we do not accidentally have two - * different entries for the same built-in class. - */ - private final WeakIdentityHashMap procWrappers = new WeakIdentityHashMap<>(); - - @TruffleBoundary - public Object getOrCreateProcWrapper(PythonManagedClass owner, SlotMethodDef slot, Supplier supplier) { - PyProcsWrapper[] slotWrappers = procWrappers.computeIfAbsent(owner, key -> new PyProcsWrapper[SlotMethodDef.values().length]); - int idx = slot.ordinal(); - PyProcsWrapper wrapper = slotWrappers[idx]; - if (wrapper == null) { - wrapper = supplier.get(); - slotWrappers[idx] = wrapper; - } - return wrapper; - } - @TruffleBoundary public Object getOrAllocateNativePyMethodDef(PyMethodDefHelper pyMethodDef) { Object pyMethodDefPointer = methodDefinitions.computeIfAbsent(pyMethodDef, PyMethodDefHelper::allocate); @@ -1528,22 +1492,16 @@ public Object getOrAllocateNativePyMethodDef(PyMethodDefHelper pyMethodDef) { } /** - * A table mapping {@link BuiltinMethodDescriptor} or {@link RootCallTarget} to the appropriate - * {@link PyCFunctionWrapper}. This could actually be shared between Python contexts but - * {@link PyCFunctionWrapper} is still a {@link TruffleObject} and so it is assumed to be - * context-specific although our wrapper doesn't contain any data and is just used for executing - * code. + * A table mapping a {@link RootCallTarget} to the appropriate {@link PyCFunctionWrapper}. This + * could actually be shared between Python contexts but {@link PyCFunctionWrapper} is still a + * {@link TruffleObject} and so it is assumed to be context-specific although our wrapper + * doesn't contain any data and is just used for executing code. */ - private final ConcurrentHashMap pyCFunctionWrappers = new ConcurrentHashMap<>(4); - - @TruffleBoundary - public PyCFunctionWrapper getOrCreatePyCFunctionWrapper(BuiltinMethodDescriptor builtinMethodDescriptor, Function cons) { - return pyCFunctionWrappers.computeIfAbsent(builtinMethodDescriptor, k -> cons.apply((BuiltinMethodDescriptor) k)); - } + private final ConcurrentHashMap pyCFunctionWrappers = new ConcurrentHashMap<>(4); @TruffleBoundary public PyCFunctionWrapper getOrCreatePyCFunctionWrapper(RootCallTarget ct, Function cons) { - return pyCFunctionWrappers.computeIfAbsent(ct, k -> cons.apply((RootCallTarget) k)); + return pyCFunctionWrappers.computeIfAbsent(ct, cons); } public static boolean isPointerObject(Object object) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java index 90e9394e37..39b5d321d9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java @@ -184,7 +184,7 @@ public final class CApiFunction { /* - * Functions that are implemented as C code that can be executed both in native and in Sulong: + * Functions that are implemented as C code that can be executed in native */ @CApiBuiltin(name = "PyGILState_Check", ret = Int, args = {}, acquireGil = false, call = CImpl) @CApiBuiltin(name = "PyArg_Parse", ret = Int, args = {PyObject, ConstCharPtrAsTruffleString, VARARGS}, call = CImpl) @@ -296,6 +296,7 @@ public final class CApiFunction { @CApiBuiltin(name = "PyImport_AddModule", ret = PyObject, args = {ConstCharPtrAsTruffleString}, call = CImpl) @CApiBuiltin(name = "PyImport_AddModuleObject", ret = PyObject, args = {PyObject}, call = CImpl) @CApiBuiltin(name = "PyImport_ImportModuleLevel", ret = PyObject, args = {ConstCharPtrAsTruffleString, PyObject, PyObject, PyObject, Int}, call = CImpl) + @CApiBuiltin(name = "PyIndex_Check", ret = Int, args = {PyObject}, call = CImpl) @CApiBuiltin(name = "PyInstanceMethod_Function", ret = PyObject, args = {PyObject}, call = CImpl) @CApiBuiltin(name = "PyInterpreterState_GetDict", ret = PyObject, args = {PyInterpreterState}, call = CImpl) @CApiBuiltin(name = "PyInterpreterState_GetID", ret = INT64_T, args = {PyInterpreterState}, call = CImpl) @@ -345,13 +346,19 @@ public final class CApiFunction { @CApiBuiltin(name = "PyModule_AddStringConstant", ret = Int, args = {PyObject, ConstCharPtrAsTruffleString, ConstCharPtrAsTruffleString}, call = CImpl) @CApiBuiltin(name = "PyModule_AddType", ret = Int, args = {PyObject, PyTypeObject}, call = CImpl) @CApiBuiltin(name = "PyModule_Create2", ret = PyObject, args = {PYMODULEDEF_PTR, Int}, call = CImpl) + @CApiBuiltin(name = "PyModule_FromDefAndSpec2", ret = PyObject, args = {PyModuleDef, PyObject, Int}, call = CImpl) + @CApiBuiltin(name = "PyModule_ExecDef", ret = Int, args = {PyObject, PyModuleDef}, call = CImpl) @CApiBuiltin(name = "PyModule_GetDef", ret = PyModuleDef, args = {PyObject}, call = CImpl) @CApiBuiltin(name = "PyModule_GetDict", ret = PyObject, args = {PyObject}, call = CImpl) + @CApiBuiltin(name = "PyModule_GetFilename", ret = ConstCharPtrAsTruffleString, args = {PyObject}, call = CImpl) @CApiBuiltin(name = "PyModule_GetName", ret = ConstCharPtrAsTruffleString, args = {PyObject}, call = CImpl) @CApiBuiltin(name = "PyModule_GetState", ret = Pointer, args = {PyObject}, call = CImpl) + @CApiBuiltin(name = "PyNumber_Absolute", ret = PyObject, args = {PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_Add", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_And", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_AsSsize_t", ret = Py_ssize_t, args = {PyObject, PyObject}, call = CImpl) + @CApiBuiltin(name = "PyNumber_Check", ret = Int, args = {PyObject}, call = CImpl) + @CApiBuiltin(name = "PyNumber_Divmod", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_FloorDivide", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_InPlaceAdd", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_InPlaceAnd", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @@ -360,6 +367,7 @@ public final class CApiFunction { @CApiBuiltin(name = "PyNumber_InPlaceMatrixMultiply", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_InPlaceMultiply", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_InPlaceOr", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) + @CApiBuiltin(name = "PyNumber_InPlacePower", ret = PyObject, args = {PyObject, PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_InPlaceRemainder", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_InPlaceRshift", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_InPlaceSubtract", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @@ -372,6 +380,7 @@ public final class CApiFunction { @CApiBuiltin(name = "PyNumber_Negative", ret = PyObject, args = {PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_Or", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_Positive", ret = PyObject, args = {PyObject}, call = CImpl) + @CApiBuiltin(name = "PyNumber_Power", ret = PyObject, args = {PyObject, PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_Remainder", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_Rshift", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @CApiBuiltin(name = "PyNumber_Subtract", ret = PyObject, args = {PyObject, PyObject}, call = CImpl) @@ -507,6 +516,7 @@ public final class CApiFunction { @CApiBuiltin(name = "PyUnicode_DecodeLatin1", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = CImpl) @CApiBuiltin(name = "PyUnicode_DecodeLocale", ret = PyObject, args = {ConstCharPtrAsTruffleString, ConstCharPtrAsTruffleString}, call = CImpl) @CApiBuiltin(name = "PyUnicode_DecodeLocaleAndSize", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = CImpl) + @CApiBuiltin(name = "PyUnicode_DecodeRawUnicodeEscape", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = CImpl) @CApiBuiltin(name = "PyUnicode_DecodeUTF16", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString, INT_LIST}, call = CImpl) @CApiBuiltin(name = "PyUnicode_DecodeUTF16Stateful", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString, INT_LIST, PY_SSIZE_T_PTR}, call = CImpl) @CApiBuiltin(name = "PyUnicode_DecodeUTF32", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString, INT_LIST}, call = CImpl) @@ -592,10 +602,13 @@ public final class CApiFunction { @CApiBuiltin(name = "_PyLong_UnsignedLong_Converter", ret = Int, args = {PyObject, Pointer}, call = CImpl) @CApiBuiltin(name = "_PyModule_Add", ret = Int, args = {PyObject, ConstCharPtrAsTruffleString, PyObject}, call = CImpl) @CApiBuiltin(name = "_PyModule_CreateInitialized", ret = PyObject, args = {PYMODULEDEF_PTR, Int}, call = CImpl) + @CApiBuiltin(name = "_PyObject_AssertFailed", ret = VoidNoReturn, args = {PyObject, ConstCharPtrAsTruffleString, ConstCharPtrAsTruffleString, ConstCharPtrAsTruffleString, Int, + ConstCharPtrAsTruffleString}, call = CImpl) @CApiBuiltin(name = "_PyObject_CallFunction_SizeT", ret = PyObject, args = {PyObject, ConstCharPtrAsTruffleString, VARARGS}, call = CImpl) @CApiBuiltin(name = "_PyObject_CallMethodIdObjArgs", ret = PyObject, args = {PyObject, _PY_IDENTIFIER_PTR, VARARGS}, call = CImpl) @CApiBuiltin(name = "_PyObject_CallMethodIdObjArgs", ret = PyObject, args = {PyObject, _PY_IDENTIFIER_PTR, VARARGS}, call = CImpl) @CApiBuiltin(name = "_PyObject_CallMethod_SizeT", ret = PyObject, args = {PyObject, ConstCharPtrAsTruffleString, ConstCharPtrAsTruffleString, VARARGS}, call = CImpl) + @CApiBuiltin(name = "_PyObject_Dump", ret = Void, args = {PyObject}, call = CImpl) @CApiBuiltin(name = "_PyObject_FastCall", ret = PyObject, args = {PyObject, PyObjectConstPtr, Py_ssize_t}, call = CImpl) @CApiBuiltin(name = "_PyObject_GC_New", ret = PyObject, args = {PyTypeObject}, call = CImpl) @CApiBuiltin(name = "_PyObject_GC_NewVar", ret = PyVarObject, args = {PyTypeObject, Py_ssize_t}, call = CImpl) @@ -603,6 +616,7 @@ public final class CApiFunction { @CApiBuiltin(name = "_PyObject_GetAttrId", ret = PyObject, args = {PyObject, _PY_IDENTIFIER_PTR}, call = CImpl) @CApiBuiltin(name = "_PyObject_GetDictPtr", ret = PyObjectPtr, args = {PyObject}, call = CImpl) @CApiBuiltin(name = "_PyObject_GetMethod", ret = Int, args = {PyObject, PyObject, PyObjectPtr}, call = CImpl) + @CApiBuiltin(name = "_PyObject_IsFreed", ret = Int, args = {PyObject}, call = CImpl) @CApiBuiltin(name = "_PyObject_LookupAttr", ret = Int, args = {PyObject, PyObject, PyObjectPtr}, call = CImpl) @CApiBuiltin(name = "_PyObject_LookupAttrId", ret = Int, args = {PyObject, _PY_IDENTIFIER_PTR, PyObjectPtr}, call = CImpl) @CApiBuiltin(name = "_PyObject_New", ret = PyObject, args = {PyTypeObject}, call = CImpl) @@ -615,6 +629,7 @@ public final class CApiFunction { @CApiBuiltin(name = "_PyTrash_cond", ret = Int, args = {PyObject, destructor}, call = CImpl) @CApiBuiltin(name = "_PyTrash_end", ret = Void, args = {PyThreadState}, call = CImpl) @CApiBuiltin(name = "_PyTuple_MaybeUntrack", ret = Void, args = {PyObject}, call = CImpl) + @CApiBuiltin(name = "_PyTuple_Resize", ret = Int, args = {PyObjectPtr, Py_ssize_t}, call = CImpl) @CApiBuiltin(name = "_PyType_Name", ret = ConstCharPtrAsTruffleString, args = {PyTypeObject}, call = CImpl) @CApiBuiltin(name = "_PyUnicode_EqualToASCIIId", ret = Int, args = {PyObject, PY_IDENTIFIER}, call = CImpl) @CApiBuiltin(name = "_PyUnicode_FromId", ret = PyObject, args = {PY_IDENTIFIER}, call = CImpl) @@ -644,6 +659,7 @@ public final class CApiFunction { @CApiBuiltin(name = "_PyUnicode_ToUpperFull", ret = Int, args = {PY_UCS4, PY_UCS4_PTR}, call = CImpl) @CApiBuiltin(name = "_PyUnicode_ToUppercase", ret = PY_UCS4, args = {PY_UCS4}, call = CImpl) @CApiBuiltin(name = "_Py_BuildValue_SizeT", ret = PyObject, args = {ConstCharPtrAsTruffleString, VARARGS}, call = CImpl) + @CApiBuiltin(name = "_Py_BreakPoint", ret = Void, args = {}, call = CImpl) @CApiBuiltin(name = "_Py_CheckFunctionResult", ret = PyObject, args = {PyThreadState, PyObject, PyObject, ConstCharPtrAsTruffleString}, call = CImpl) @CApiBuiltin(name = "_Py_Dealloc", ret = Void, args = {PyObject}, call = CImpl) @CApiBuiltin(name = "_Py_DecRef", ret = Void, args = {PyObject}, call = CImpl) @@ -813,10 +829,6 @@ public final class CApiFunction { @CApiBuiltin(name = "PyMem_SetupDebugHooks", ret = Void, args = {}, call = NotImplemented) @CApiBuiltin(name = "PyMember_GetOne", ret = PyObject, args = {ConstCharPtrAsTruffleString, PyMemberDef}, call = NotImplemented) @CApiBuiltin(name = "PyMember_SetOne", ret = Int, args = {CHAR_PTR, PyMemberDef, PyObject}, call = NotImplemented) - @CApiBuiltin(name = "PyModule_ExecDef", ret = Int, args = {PyObject, PyModuleDef}, call = NotImplemented) - @CApiBuiltin(name = "PyModule_FromDefAndSpec2", ret = PyObject, args = {PyModuleDef, PyObject, Int}, call = NotImplemented) - @CApiBuiltin(name = "PyModule_GetFilename", ret = ConstCharPtrAsTruffleString, args = {PyObject}, call = NotImplemented) - @CApiBuiltin(name = "PyModule_GetFilenameObject", ret = PyObject, args = {PyObject}, call = NotImplemented) @CApiBuiltin(name = "PyODict_DelItem", ret = Int, args = {PyObject, PyObject}, call = NotImplemented) @CApiBuiltin(name = "PyODict_New", ret = PyObject, args = {}, call = NotImplemented) @CApiBuiltin(name = "PyODict_SetItem", ret = Int, args = {PyObject, PyObject, PyObject}, call = NotImplemented) @@ -942,7 +954,6 @@ public final class CApiFunction { @CApiBuiltin(name = "PyUnicode_BuildEncodingMap", ret = PyObject, args = {PyObject}, call = NotImplemented) @CApiBuiltin(name = "PyUnicode_CopyCharacters", ret = Py_ssize_t, args = {PyObject, Py_ssize_t, PyObject, Py_ssize_t, Py_ssize_t}, call = NotImplemented) @CApiBuiltin(name = "PyUnicode_DecodeCharmap", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, PyObject, ConstCharPtrAsTruffleString}, call = NotImplemented) - @CApiBuiltin(name = "PyUnicode_DecodeRawUnicodeEscape", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = NotImplemented) @CApiBuiltin(name = "PyUnicode_DecodeUTF7", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = NotImplemented) @CApiBuiltin(name = "PyUnicode_DecodeUTF7Stateful", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString, PY_SSIZE_T_PTR}, call = NotImplemented) @CApiBuiltin(name = "PyUnicode_DecodeUnicodeEscape", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = NotImplemented) @@ -1098,8 +1109,6 @@ public final class CApiFunction { @CApiBuiltin(name = "_PyOS_IsMainThread", ret = Int, args = {}, call = NotImplemented) @CApiBuiltin(name = "_PyOS_URandom", ret = Int, args = {Pointer, Py_ssize_t}, call = NotImplemented) @CApiBuiltin(name = "_PyOS_URandomNonblock", ret = Int, args = {Pointer, Py_ssize_t}, call = NotImplemented) - @CApiBuiltin(name = "_PyObject_AssertFailed", ret = VoidNoReturn, args = {PyObject, ConstCharPtrAsTruffleString, ConstCharPtrAsTruffleString, ConstCharPtrAsTruffleString, Int, - ConstCharPtrAsTruffleString}, call = NotImplemented) @CApiBuiltin(name = "_PyObject_CallMethod", ret = PyObject, args = {PyObject, PyObject, ConstCharPtrAsTruffleString, VARARGS}, call = NotImplemented) @CApiBuiltin(name = "_PyObject_CallMethodId", ret = PyObject, args = {PyObject, PY_IDENTIFIER, ConstCharPtrAsTruffleString, VARARGS}, call = NotImplemented) @CApiBuiltin(name = "_PyObject_CallMethodId_SizeT", ret = PyObject, args = {PyObject, PY_IDENTIFIER, ConstCharPtrAsTruffleString, VARARGS}, call = NotImplemented) @@ -1113,7 +1122,6 @@ public final class CApiFunction { @CApiBuiltin(name = "_PyObject_GetState", ret = PyObject, args = {PyObject}, call = NotImplemented) @CApiBuiltin(name = "_PyObject_HasLen", ret = Int, args = {PyObject}, call = NotImplemented) @CApiBuiltin(name = "_PyObject_IsAbstract", ret = Int, args = {PyObject}, call = NotImplemented) - @CApiBuiltin(name = "_PyObject_IsFreed", ret = Int, args = {PyObject}, call = NotImplemented) @CApiBuiltin(name = "_PyObject_LookupSpecialId", ret = PyObject, args = {PyObject, PY_IDENTIFIER}, call = NotImplemented) @CApiBuiltin(name = "_PyObject_RealIsInstance", ret = Int, args = {PyObject, PyObject}, call = NotImplemented) @CApiBuiltin(name = "_PyObject_RealIsSubclass", ret = Int, args = {PyObject, PyObject}, call = NotImplemented) @@ -1165,7 +1173,6 @@ public final class CApiFunction { @CApiBuiltin(name = "_PyTime_localtime", ret = Int, args = {TIME_T, TM_PTR}, call = NotImplemented) @CApiBuiltin(name = "_PyTraceMalloc_GetTraceback", ret = PyObject, args = {UNSIGNED_INT, UINTPTR_T}, call = NotImplemented) @CApiBuiltin(name = "_PyTuple_DebugMallocStats", ret = Void, args = {FILE_PTR}, call = NotImplemented) - @CApiBuiltin(name = "_PyTuple_Resize", ret = Int, args = {PyObjectPtr, Py_ssize_t}, call = NotImplemented) @CApiBuiltin(name = "_PyType_CalculateMetaclass", ret = PyTypeObject, args = {PyTypeObject, PyObject}, call = NotImplemented) @CApiBuiltin(name = "_PyType_GetDocFromInternalDoc", ret = PyObject, args = {ConstCharPtrAsTruffleString, ConstCharPtrAsTruffleString}, call = NotImplemented) @CApiBuiltin(name = "_PyType_GetTextSignatureFromInternalDoc", ret = PyObject, args = {ConstCharPtrAsTruffleString, ConstCharPtrAsTruffleString}, call = NotImplemented) @@ -1207,9 +1214,7 @@ public final class CApiFunction { @CApiBuiltin(name = "_PyUnicode_WideCharString_Converter", ret = Int, args = {PyObject, Pointer}, call = NotImplemented) @CApiBuiltin(name = "_PyUnicode_WideCharString_Opt_Converter", ret = Int, args = {PyObject, Pointer}, call = NotImplemented) @CApiBuiltin(name = "_PyUnicode_XStrip", ret = PyObject, args = {PyObject, Int, PyObject}, call = NotImplemented) - @CApiBuiltin(name = "_PyWeakref_ClearRef", ret = Void, args = {PYWEAKREFERENCE_PTR}, call = NotImplemented) @CApiBuiltin(name = "_PyWeakref_GetWeakrefCount", ret = Py_ssize_t, args = {PYWEAKREFERENCE_PTR}, call = NotImplemented) - @CApiBuiltin(name = "_Py_BreakPoint", ret = Void, args = {}, call = NotImplemented) @CApiBuiltin(name = "_Py_CoerceLegacyLocale", ret = Int, args = {Int}, call = NotImplemented) @CApiBuiltin(name = "_Py_DisplaySourceLine", ret = Int, args = {PyObject, PyObject, Int, Int, INT_LIST, PyObjectPtr}, call = NotImplemented) @CApiBuiltin(name = "_Py_FatalErrorFormat", ret = Void, args = {ConstCharPtr, ConstCharPtr, VARARGS}, call = NotImplemented) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiMemberAccessNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiMemberAccessNodes.java index ab5b24922a..ead440a621 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiMemberAccessNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiMemberAccessNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -82,11 +82,10 @@ import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils.PrototypeNodeFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -213,8 +212,6 @@ public abstract static class ReadMemberNode extends PythonUnaryBuiltinNode { @Child private PythonToNativeNode toSulongNode; @Child private CExtAsPythonObjectNode asPythonObjectNode; - @Child private PForeignToPTypeNode fromForeign; - @Child private PRaiseNode raiseNode; @Child private CStructAccess.ReadBaseNode read; @@ -229,13 +226,12 @@ protected ReadMemberNode(int type, int offset, CExtAsPythonObjectNode asPythonOb this.read = getReadNode(type); this.offset = offset; this.asPythonObjectNode = asPythonObjectNode; - if (asPythonObjectNode == null) { - fromForeign = PForeignToPTypeNode.create(); - } } @Specialization - Object doGeneric(@SuppressWarnings("unused") VirtualFrame frame, Object self) { + Object doGeneric(@SuppressWarnings("unused") VirtualFrame frame, Object self, + @Bind("this") Node inliningTarget, + @Cached PRaiseNode raiseNode) { if (read == null) { return PNone.NONE; } else { @@ -243,7 +239,7 @@ Object doGeneric(@SuppressWarnings("unused") VirtualFrame frame, Object self) { assert !(nativeResult instanceof Byte || nativeResult instanceof Short || nativeResult instanceof Float || nativeResult instanceof Character || nativeResult instanceof PException || nativeResult instanceof String) : nativeResult + " " + nativeResult.getClass(); if (type == T_OBJECT_EX && nativeResult == PNone.NO_VALUE) { - throw ensureRaiseNode().raise(PythonBuiltinClassType.AttributeError); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError); } if (type == T_OBJECT && nativeResult == PNone.NO_VALUE) { nativeResult = PNone.NONE; @@ -264,14 +260,6 @@ private PythonToNativeNode ensureToSulongNode() { return toSulongNode; } - private PRaiseNode ensureRaiseNode() { - if (raiseNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - raiseNode = insert(PRaiseNode.create()); - } - return raiseNode; - } - @TruffleBoundary public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, Object owner, TruffleString propertyName, int type, int offset) { CExtAsPythonObjectNode asPythonObjectNode = getReadConverterNode(type); @@ -279,7 +267,7 @@ public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, Ob l -> new BuiltinFunctionRootNode(l, BUILTIN, new PrototypeNodeFactory<>(ReadMemberNodeGen.create(type, offset, asPythonObjectNode)), true), ReadMemberNode.class, BUILTIN.name(), type, offset); int flags = PBuiltinFunction.getFlags(BUILTIN, callTarget); - return PythonObjectFactory.getUncached().createBuiltinFunction(propertyName, owner, 0, flags, callTarget); + return PFactory.createBuiltinFunction(language, propertyName, owner, 0, flags, callTarget); } } @@ -295,8 +283,8 @@ protected ReadOnlyMemberNode(TruffleString propertyName) { @Specialization @SuppressWarnings("unused") Object doGeneric(Object self, Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATTRIBUTE_S_OF_P_OBJECTS_IS_NOT_WRITABLE, propertyName, self); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATTRIBUTE_S_OF_P_OBJECTS_IS_NOT_WRITABLE, propertyName, self); } @TruffleBoundary @@ -305,7 +293,7 @@ public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, Tr l -> new BuiltinFunctionRootNode(l, BUILTIN, new PrototypeNodeFactory<>(ReadOnlyMemberNodeGen.create(propertyName)), true), ReadOnlyMemberNode.class, BUILTIN.name()); int flags = PBuiltinFunction.getFlags(BUILTIN, builtinCt); - return PythonObjectFactory.getUncached().createBuiltinFunction(propertyName, null, 0, flags, builtinCt); + return PFactory.createBuiltinFunction(language, propertyName, null, 0, flags, builtinCt); } } @@ -315,12 +303,12 @@ protected abstract static class BadMemberDescrNode extends PythonBinaryBuiltinNo @Specialization static Object doGeneric(Object self, @SuppressWarnings("unused") Object value, - @Cached PRaiseNode raiseNode) { + @Bind("this") Node inliningTarget) { if (value == DescriptorDeleteMarker.INSTANCE) { // This node is actually only used for T_NONE, so this error message is right. - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.CAN_T_DELETE_NUMERIC_CHAR_ATTRIBUTE); + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CAN_T_DELETE_NUMERIC_CHAR_ATTRIBUTE); } - throw raiseNode.raise(PythonBuiltinClassType.SystemError, ErrorMessages.BAD_MEMBER_DESCR_TYPE_FOR_P, self); + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.SystemError, ErrorMessages.BAD_MEMBER_DESCR_TYPE_FOR_P, self); } @TruffleBoundary @@ -329,7 +317,7 @@ public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, Tr l -> new BuiltinFunctionRootNode(l, BUILTIN, new PrototypeNodeFactory<>(BadMemberDescrNodeGen.create()), true), BadMemberDescrNode.class, BUILTIN.name()); int flags = PBuiltinFunction.getFlags(BUILTIN, builtinCt); - return PythonObjectFactory.getUncached().createBuiltinFunction(propertyName, null, 0, flags, builtinCt); + return PFactory.createBuiltinFunction(language, propertyName, null, 0, flags, builtinCt); } } @@ -495,12 +483,13 @@ abstract static class WriteObjectExNode extends WriteTypeNode { @Specialization static void write(Object pointer, Object newValue, + @Bind("this") Node inliningTarget, @Cached CStructAccess.ReadObjectNode read, @Cached CStructAccess.WriteObjectNewRefNode write, @Cached PRaiseNode raise) { Object current = read.readGeneric(pointer, 0); if (newValue == DescriptorDeleteMarker.INSTANCE && current == PNone.NO_VALUE) { - throw raise.raise(PythonBuiltinClassType.AttributeError); + throw raise.raise(inliningTarget, PythonBuiltinClassType.AttributeError); } write.write(pointer, newValue); } @@ -586,7 +575,7 @@ protected WriteMemberNode(int type, int offset) { @Specialization Object doGeneric(Object self, Object value, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object selfPtr = toSulongNode.execute(self); selfPtr = getElement.readGeneric(selfPtr, offset); @@ -598,12 +587,12 @@ Object doGeneric(Object self, Object value, */ if (type != T_OBJECT && type != T_OBJECT_EX) { if (value == DescriptorDeleteMarker.INSTANCE) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.CAN_T_DELETE_NUMERIC_CHAR_ATTRIBUTE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CAN_T_DELETE_NUMERIC_CHAR_ATTRIBUTE); } } if (type == T_BOOL && !ensureIsSameTypeNode().executeCached(PythonBuiltinClassType.Boolean, ensureGetClassNode().executeCached(value))) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATTRIBUTE_TYPE_VALUE_MUST_BE_BOOL); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATTRIBUTE_TYPE_VALUE_MUST_BE_BOOL); } write.execute(selfPtr, value); @@ -638,7 +627,7 @@ public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, Ob l -> new BuiltinFunctionRootNode(l, BUILTIN, new PrototypeNodeFactory<>(WriteMemberNodeGen.create(type, offset)), true), WriteMemberNode.class, BUILTIN.name(), type, offset); int flags = PBuiltinFunction.getFlags(BUILTIN, callTarget); - return PythonObjectFactory.getUncached().createBuiltinFunction(propertyName, owner, 0, flags, callTarget); + return PFactory.createBuiltinFunction(language, propertyName, owner, 0, flags, callTarget); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java index 37563cd761..c103c5c7c0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java @@ -158,6 +158,7 @@ import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectSizeNode; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.BuiltinNames; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.HiddenAttr; @@ -175,6 +176,7 @@ import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaStringNode; import com.oracle.graal.python.nodes.util.CastToJavaStringNodeGen; @@ -185,9 +187,8 @@ import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.MroSequenceStorage; -import com.oracle.graal.python.util.ComparisonOp; import com.oracle.graal.python.util.Function; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerAsserts; @@ -206,6 +207,7 @@ import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; @@ -348,23 +350,23 @@ public abstract static class FromNativeSubclassNode extends Node { public abstract Double execute(VirtualFrame frame, PythonAbstractNativeObject object); @Specialization - static Double doDouble(VirtualFrame frame, PythonAbstractNativeObject object, + static Double doDouble(PythonAbstractNativeObject object, @Bind("this") Node inliningTarget, @Cached GetPythonObjectClassNode getClass, @Cached IsSubtypeNode isSubtype, @Cached CStructAccess.ReadDoubleNode read) { - if (isFloatSubtype(frame, inliningTarget, object, getClass, isSubtype)) { + if (isFloatSubtype(inliningTarget, object, getClass, isSubtype)) { return read.readFromObj(object, PyFloatObject__ob_fval); } return null; } - public static boolean isFloatSubtype(VirtualFrame frame, Node inliningTarget, Object object, GetClassNode getClass, IsSubtypeNode isSubtype) { - return isSubtype.execute(frame, getClass.execute(inliningTarget, object), PythonBuiltinClassType.PFloat); + public static boolean isFloatSubtype(Node inliningTarget, Object object, GetClassNode getClass, IsSubtypeNode isSubtype) { + return isSubtype.execute(getClass.execute(inliningTarget, object), PythonBuiltinClassType.PFloat); } - public static boolean isFloatSubtype(VirtualFrame frame, Node inliningTarget, PythonAbstractNativeObject object, GetPythonObjectClassNode getClass, IsSubtypeNode isSubtype) { - return isSubtype.execute(frame, getClass.execute(inliningTarget, object), PythonBuiltinClassType.PFloat); + public static boolean isFloatSubtype(Node inliningTarget, PythonAbstractNativeObject object, GetPythonObjectClassNode getClass, IsSubtypeNode isSubtype) { + return isSubtype.execute(getClass.execute(inliningTarget, object), PythonBuiltinClassType.PFloat); } @NeverDefault @@ -405,8 +407,8 @@ static PInt doBoolNativeWrapper(Node inliningTarget, PrimitiveNativeWrapper obje @Specialization(guards = {"!isMaterialized(object)", "object.isInt()"}) static PInt doIntNativeWrapper(PrimitiveNativeWrapper object, - @Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { - PInt materializedInt = factory.createInt(object.getInt()); + @Bind PythonLanguage language) { + PInt materializedInt = PFactory.createInt(language, object.getInt()); object.setMaterializedObject(materializedInt); materializedInt.setNativeWrapper(object); return materializedInt; @@ -414,8 +416,8 @@ static PInt doIntNativeWrapper(PrimitiveNativeWrapper object, @Specialization(guards = {"!isMaterialized(object)", "object.isLong()"}) static PInt doLongNativeWrapper(PrimitiveNativeWrapper object, - @Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { - PInt materializedInt = factory.createInt(object.getLong()); + @Bind PythonLanguage language) { + PInt materializedInt = PFactory.createInt(language, object.getLong()); object.setMaterializedObject(materializedInt); materializedInt.setNativeWrapper(object); return materializedInt; @@ -423,8 +425,8 @@ static PInt doLongNativeWrapper(PrimitiveNativeWrapper object, @Specialization(guards = {"!isMaterialized(object)", "object.isDouble()", "!isNaN(object)"}) static PFloat doDoubleNativeWrapper(PrimitiveNativeWrapper object, - @Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { - PFloat materializedInt = factory.createFloat(object.getDouble()); + @Bind PythonLanguage language) { + PFloat materializedInt = PFactory.createFloat(language, object.getDouble()); materializedInt.setNativeWrapper(object); object.setMaterializedObject(materializedInt); return materializedInt; @@ -550,6 +552,10 @@ public final TruffleString execute(Object charPtr) { return execute(charPtr, true); } + public static TruffleString executeUncached(Object charPtr) { + return FromCharPointerNodeGen.getUncached().execute(charPtr); + } + public abstract TruffleString execute(Object charPtr, boolean copy); @Specialization @@ -612,51 +618,45 @@ static Object getNativeClass(Node inliningTarget, PythonAbstractNativeObject obj @GenerateCached(false) public abstract static class PointerCompareNode extends Node { - public abstract boolean execute(Node inliningTarget, ComparisonOp op, Object a, Object b); - - @Specialization(guards = "op.isEqualityOp()", limit = "2") - static boolean doEqNe(ComparisonOp op, PythonAbstractNativeObject a, PythonAbstractNativeObject b, - @CachedLibrary("a") InteropLibrary aLib, - @CachedLibrary(limit = "3") InteropLibrary bLib) { - return aLib.isIdentical(a, b, bLib) == (op == ComparisonOp.EQ); - } + public abstract boolean execute(Node inliningTarget, RichCmpOp op, Object a, Object b); - @Specialization(guards = {"isNativeObjectOrVoidPointer(a)", "isNativeObjectOrLong(b)"}) - static boolean doGeneric(Node inliningTarget, ComparisonOp op, Object a, Object b, - @CachedLibrary(limit = "1") InteropLibrary interopLibrary, - @Cached InlinedConditionProfile aProfile, - @Cached InlinedConditionProfile bProfile) { + @Specialization + static boolean doGeneric(Node inliningTarget, RichCmpOp op, Object a, Object b, + @Cached NormalizePtrNode normalizeA, + @Cached NormalizePtrNode normalizeB, + @CachedLibrary(limit = "1") InteropLibrary interopLibrary) { CompilerAsserts.partialEvaluationConstant(op); - Object ptrA; - if (aProfile.profile(inliningTarget, a instanceof PythonNativeObject)) { - ptrA = ((PythonNativeObject) a).getPtr(); - } else { - // guaranteed by the guard - assert a instanceof PythonNativeVoidPtr; - ptrA = ((PythonNativeVoidPtr) a).getNativePointer(); - } - Object ptrB; - if (bProfile.profile(inliningTarget, b instanceof PythonNativeObject)) { - ptrB = ((PythonNativeObject) b).getPtr(); - } else { - // guaranteed by the guard - assert b instanceof Long; - ptrB = b; - } + Object ptrA = normalizeA.execute(inliningTarget, a); + Object ptrB = normalizeB.execute(inliningTarget, b); try { Object sym = CApiContext.getNativeSymbol(inliningTarget, FUN_PTR_COMPARE); - return (int) interopLibrary.execute(sym, ptrA, ptrB, op.opCode) != 0; + return (int) interopLibrary.execute(sym, ptrA, ptrB, op.asNative()) != 0; } catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) { throw CompilerDirectives.shouldNotReachHere(e); } } - static boolean isNativeObjectOrVoidPointer(Object object) { - return object instanceof PythonNativeObject || object instanceof PythonNativeVoidPtr; - } + @TypeSystemReference(PythonIntegerTypes.class) + @GenerateInline + @GenerateCached(false) + @GenerateUncached + abstract static class NormalizePtrNode extends Node { + abstract Object execute(Node inliningTarget, Object ptr); + + @Specialization + static Object doLong(long l) { + return l; + } + + @Specialization + static Object doLong(PythonNativeObject o) { + return o.getPtr(); + } - static boolean isNativeObjectOrLong(Object object) { - return object instanceof PythonNativeObject || object instanceof Long; + @Specialization + static Object doLong(PythonNativeVoidPtr o) { + return o.getNativePointer(); + } } } @@ -690,46 +690,46 @@ static PComplex doPComplex(PComplex value) { @Specialization static PComplex doBoolean(boolean value, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createComplex(value ? 1.0 : 0.0, 0.0); + @Bind PythonLanguage language) { + return PFactory.createComplex(language, value ? 1.0 : 0.0, 0.0); } @Specialization static PComplex doInt(int value, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createComplex(value, 0.0); + @Bind PythonLanguage language) { + return PFactory.createComplex(language, value, 0.0); } @Specialization static PComplex doLong(long value, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createComplex(value, 0.0); + @Bind PythonLanguage language) { + return PFactory.createComplex(language, value, 0.0); } @Specialization PComplex doDouble(double value, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createComplex(value, 0.0); + @Bind PythonLanguage language) { + return PFactory.createComplex(language, value, 0.0); } @Specialization static PComplex doPInt(PInt value, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createComplex(value.doubleValue(), 0.0); + @Bind PythonLanguage language) { + return PFactory.createComplex(language, value.doubleValue(), 0.0); } @Specialization static PComplex doPFloat(PFloat value, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createComplex(value.getValue(), 0.0); + @Bind PythonLanguage language) { + return PFactory.createComplex(language, value.getValue(), 0.0); } @Specialization(replaces = {"doPComplex", "doBoolean", "doInt", "doLong", "doDouble", "doPInt", "doPFloat"}) static PComplex runGeneric(Node inliningTarget, Object value, @Cached PyFloatAsDoubleNode asDoubleNode, @Cached(inline = false) LookupAndCallUnaryDynamicNode callComplex, - @Shared @Cached(inline = false) PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { Object result = callComplex.executeObject(value, T___COMPLEX__); // TODO(fa) according to CPython's 'PyComplex_AsCComplex', they still allow subclasses // of PComplex @@ -737,10 +737,10 @@ static PComplex runGeneric(Node inliningTarget, Object value, if (result instanceof PComplex) { return (PComplex) result; } else { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.COMPLEX_RETURNED_NON_COMPLEX, value); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.COMPLEX_RETURNED_NON_COMPLEX, value); } } else { - return factory.createComplex(asDoubleNode.execute(null, inliningTarget, value), 0.0); + return PFactory.createComplex(language, asDoubleNode.execute(null, inliningTarget, value), 0.0); } } } @@ -1148,7 +1148,7 @@ static Object doObject(Frame frame, Object errorValue, PythonBuiltinClassType er private static void raiseNative(Frame frame, Node inliningTarget, PythonBuiltinClassType errType, TruffleString format, Object[] arguments, PRaiseNode raiseNode, TransformExceptionToNativeNode transformExceptionToNativeNode) { try { - throw raiseNode.raise(errType, format, arguments); + throw raiseNode.raise(inliningTarget, errType, format, arguments); } catch (PException p) { transformExceptionToNativeNode.execute(frame, inliningTarget, p); } @@ -1431,7 +1431,6 @@ Object doGeneric(TruffleString f, Object vaList) { CastToJavaStringNode castToJavaStringNode = CastToJavaStringNodeGen.getUncached(); FromCharPointerNode fromCharPointerNode = FromCharPointerNodeGen.getUncached(); InteropLibrary interopLibrary = InteropLibrary.getUncached(); - PRaiseNode raiseNode = PRaiseNode.getUncached(); StringBuilder result = new StringBuilder(); int vaArgIdx = 0; @@ -1453,7 +1452,7 @@ Object doGeneric(TruffleString f, Object vaList) { int prec = getPrec(matcher.group("prec")); assert spec.length() == 1; char la = spec.charAt(0); - PythonContext context = PythonContext.get(raiseNode); + PythonContext context = PythonContext.get(null); switch (la) { case '%': // %% @@ -1461,9 +1460,9 @@ Object doGeneric(TruffleString f, Object vaList) { valid = true; break; case 'c': - int ordinal = getAndCastToInt(interopLibrary, raiseNode, vaList); + int ordinal = getAndCastToInt(interopLibrary, vaList); if (ordinal < 0 || ordinal > 0x110000) { - throw raiseNode.raise(PythonBuiltinClassType.OverflowError, ErrorMessages.CHARACTER_ARG_NOT_IN_RANGE); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.OverflowError, ErrorMessages.CHARACTER_ARG_NOT_IN_RANGE); } result.append((char) ordinal); vaArgIdx++; @@ -1478,12 +1477,12 @@ Object doGeneric(TruffleString f, Object vaList) { case "l": case "z": vaArgIdx++; - result.append(castToLong(interopLibrary, raiseNode, GetNextVaArgNode.executeUncached(vaList))); + result.append(castToLong(interopLibrary, GetNextVaArgNode.executeUncached(vaList))); valid = true; break; } } else { - result.append(getAndCastToInt(interopLibrary, raiseNode, vaList)); + result.append(getAndCastToInt(interopLibrary, vaList)); vaArgIdx++; valid = true; } @@ -1496,19 +1495,19 @@ Object doGeneric(TruffleString f, Object vaList) { case "l": case "z": vaArgIdx++; - result.append(castToLong(interopLibrary, raiseNode, GetNextVaArgNode.executeUncached(vaList))); + result.append(castToLong(interopLibrary, GetNextVaArgNode.executeUncached(vaList))); valid = true; break; } } else { - result.append(Integer.toUnsignedString(getAndCastToInt(interopLibrary, raiseNode, vaList))); + result.append(Integer.toUnsignedString(getAndCastToInt(interopLibrary, vaList))); vaArgIdx++; valid = true; } break; case 'x': // %x - result.append(Integer.toHexString(getAndCastToInt(interopLibrary, raiseNode, vaList))); + result.append(Integer.toHexString(getAndCastToInt(interopLibrary, vaList))); vaArgIdx++; valid = true; break; @@ -1600,7 +1599,7 @@ Object doGeneric(TruffleString f, Object vaList) { // matched) result.append(format, cur, format.length()); } catch (InteropException e) { - throw raiseNode.raise(PythonBuiltinClassType.SystemError, ErrorMessages.ERROR_WHEN_ACCESSING_VAR_ARG_AT_POS, vaArgIdx); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.SystemError, ErrorMessages.ERROR_WHEN_ACCESSING_VAR_ARG_AT_POS, vaArgIdx); } return toTruffleStringUncached(result.toString()); } @@ -1616,7 +1615,7 @@ private static int getPrec(String prec) { * Read an element from the {@code va_list} with the specified type and cast it to a Java * {@code int}. Throws a {@code SystemError} if this is not possible. */ - private static int getAndCastToInt(InteropLibrary lib, PRaiseNode raiseNode, Object vaList) throws InteropException { + private int getAndCastToInt(InteropLibrary lib, Object vaList) throws InteropException { Object value = GetNextVaArgNode.executeUncached(vaList); if (lib.fitsInInt(value)) { try { @@ -1635,14 +1634,14 @@ private static int getAndCastToInt(InteropLibrary lib, PRaiseNode raiseNode, Obj throw shouldNotReachHere(); } } - throw raiseNode.raise(PythonBuiltinClassType.SystemError, ErrorMessages.P_OBJ_CANT_BE_INTEPRETED_AS_INTEGER, value); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.SystemError, ErrorMessages.P_OBJ_CANT_BE_INTEPRETED_AS_INTEGER, value); } /** * Cast a value to a Java {@code long}. Throws a {@code SystemError} if this is not * possible. */ - private static long castToLong(InteropLibrary lib, PRaiseNode raiseNode, Object value) { + private long castToLong(InteropLibrary lib, Object value) { if (lib.fitsInLong(value)) { try { return lib.asLong(value); @@ -1660,7 +1659,7 @@ private static long castToLong(InteropLibrary lib, PRaiseNode raiseNode, Object throw shouldNotReachHere(); } } - throw raiseNode.raise(PythonBuiltinClassType.SystemError, ErrorMessages.P_OBJ_CANT_BE_INTEPRETED_AS_INTEGER, value); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.SystemError, ErrorMessages.P_OBJ_CANT_BE_INTEPRETED_AS_INTEGER, value); } private static Object getPyObject(Object vaList) throws InteropException { @@ -1714,7 +1713,7 @@ public abstract static class CreateModuleNode extends MultiPhaseExtensionModuleI @TruffleBoundary static Object doGeneric(CApiContext capiContext, ModuleSpec moduleSpec, Object moduleDefWrapper, Object library, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached CStructAccess.ReadPointerNode readPointer, @Cached CStructAccess.ReadI64Node readI64, @CachedLibrary(limit = "3") InteropLibrary interopLib, @@ -1727,7 +1726,7 @@ static Object doGeneric(CApiContext capiContext, ModuleSpec moduleSpec, Object m @Cached CStructAccess.ReadI32Node readI32Node, @Cached GetThreadStateNode getThreadStateNode, @Cached TransformExceptionFromNativeNode transformExceptionFromNativeNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { // call to type the pointer Object moduleDef = moduleDefWrapper instanceof PythonAbstractNativeObject ? ((PythonAbstractNativeObject) moduleDefWrapper).getPtr() : moduleDefWrapper; @@ -1749,7 +1748,7 @@ static Object doGeneric(CApiContext capiContext, ModuleSpec moduleSpec, Object m mSize = readI64.read(moduleDef, PyModuleDef__m_size); if (mSize < 0) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.SystemError, ErrorMessages.M_SIZE_CANNOT_BE_NEGATIVE, mName); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.SystemError, ErrorMessages.M_SIZE_CANNOT_BE_NEGATIVE, mName); } // parse slot definitions @@ -1764,7 +1763,7 @@ static Object doGeneric(CApiContext capiContext, ModuleSpec moduleSpec, Object m break loop; case SLOT_PY_MOD_CREATE: if (createFunction != null) { - throw raiseNode.get(inliningTarget).raise(SystemError, ErrorMessages.MODULE_HAS_MULTIPLE_CREATE_SLOTS, mName); + throw raiseNode.raise(inliningTarget, SystemError, ErrorMessages.MODULE_HAS_MULTIPLE_CREATE_SLOTS, mName); } createFunction = readPointerNode.readStructArrayElement(slotDefinitions, i, PyModuleDef_Slot__value); break; @@ -1772,7 +1771,7 @@ static Object doGeneric(CApiContext capiContext, ModuleSpec moduleSpec, Object m hasExecutionSlots = true; break; default: - throw raiseNode.get(inliningTarget).raise(SystemError, ErrorMessages.MODULE_USES_UNKNOW_SLOT_ID, mName, slotId); + throw raiseNode.raise(inliningTarget, SystemError, ErrorMessages.MODULE_USES_UNKNOW_SLOT_ID, mName, slotId); } } } @@ -1805,17 +1804,17 @@ static Object doGeneric(CApiContext capiContext, ModuleSpec moduleSpec, Object m */ if (!(module instanceof PythonModule)) { if (mSize > 0) { - throw raiseNode.get(inliningTarget).raise(SystemError, ErrorMessages.NOT_A_MODULE_OBJECT_BUT_REQUESTS_MODULE_STATE, mName); + throw raiseNode.raise(inliningTarget, SystemError, ErrorMessages.NOT_A_MODULE_OBJECT_BUT_REQUESTS_MODULE_STATE, mName); } if (hasExecutionSlots) { - throw raiseNode.get(inliningTarget).raise(SystemError, ErrorMessages.MODULE_SPECIFIES_EXEC_SLOTS_BUT_DIDNT_CREATE_INSTANCE, mName); + throw raiseNode.raise(inliningTarget, SystemError, ErrorMessages.MODULE_SPECIFIES_EXEC_SLOTS_BUT_DIDNT_CREATE_INSTANCE, mName); } // otherwise CPython is just fine } else { ((PythonModule) module).setNativeModuleDef(moduleDef); } } else { - PythonModule pythonModule = factory.createPythonModule(mName); + PythonModule pythonModule = PFactory.createPythonModule(language, mName); pythonModule.setNativeModuleDef(moduleDef); module = pythonModule; } @@ -1827,7 +1826,7 @@ static Object doGeneric(CApiContext capiContext, ModuleSpec moduleSpec, Object m if (fun == null) { break; } - PBuiltinMethod method = factory.createBuiltinMethod(module, fun); + PBuiltinMethod method = PFactory.createBuiltinMethod(language, module, fun); writeAttrToMethodNode.execute(method, SpecialAttributeNames.T___MODULE__, mName); writeAttrNode.execute(module, fun.getName(), method); } @@ -1920,7 +1919,7 @@ static int doGeneric(CApiContext capiContext, PythonModule module, Object module ErrorMessages.EXECUTION_RAISED_EXCEPTION); break; default: - throw raiseNode.raise(SystemError, ErrorMessages.MODULE_INITIALIZED_WITH_UNKNOWN_SLOT, mName, slotId); + throw raiseNode.raise(inliningTarget, SystemError, ErrorMessages.MODULE_INITIALIZED_WITH_UNKNOWN_SLOT, mName, slotId); } } } catch (UnsupportedMessageException | UnsupportedTypeException | ArityException e) { @@ -1954,7 +1953,7 @@ static PBuiltinFunction doIt(Node inliningTarget, Object methodDef, int element, @Cached(inline = false) CStructAccess.ReadPointerNode readPointerNode, @Cached(inline = false) CStructAccess.ReadI32Node readI32Node, @Cached(inline = false) FromCharPointerNode fromCharPointerNode, - @Cached(inline = false) PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached EnsureExecutableNode ensureCallableNode, @Cached HiddenAttr.WriteNode writeHiddenAttrNode, @Cached(inline = false) WriteAttributeToPythonObjectNode writeAttributeToPythonObjectNode) { @@ -1978,7 +1977,7 @@ static PBuiltinFunction doIt(Node inliningTarget, Object methodDef, int element, RootCallTarget callTarget = PExternalFunctionWrapper.getOrCreateCallTarget(sig, PythonLanguage.get(inliningTarget), methodName, true, CExtContext.isMethStatic(flags)); mlMethObj = ensureCallableNode.execute(inliningTarget, mlMethObj, sig); PKeyword[] kwDefaults = ExternalFunctionNodes.createKwDefaults(mlMethObj); - PBuiltinFunction function = factory.createBuiltinFunction(methodName, null, PythonUtils.EMPTY_OBJECT_ARRAY, kwDefaults, flags, callTarget); + PBuiltinFunction function = PFactory.createBuiltinFunction(language, methodName, null, PythonUtils.EMPTY_OBJECT_ARRAY, kwDefaults, flags, callTarget); writeHiddenAttrNode.execute(inliningTarget, function, METHOD_DEF_PTR, methodDef); // write doc string; we need to directly write to the storage otherwise it is disallowed @@ -2107,18 +2106,18 @@ static PythonObject doPythonCallable(TruffleString name, PythonNativeWrapper cal } doArgAndResultConversion = true; } - PBuiltinFunction function = PExternalFunctionWrapper.createWrapperFunction(name, managedCallable, type, flags, signature, language, context.factory(), doArgAndResultConversion); + PythonObject function = PExternalFunctionWrapper.createWrapperFunction(name, managedCallable, type, flags, signature, language, doArgAndResultConversion); return function != null ? function : castToPythonObject(managedCallable); } @Specialization @TruffleBoundary - static PBuiltinFunction doPyCFunctionWrapper(TruffleString name, PyCFunctionWrapper wrapper, int signature, Object type, int flags) { + static PythonObject doPyCFunctionWrapper(TruffleString name, PyCFunctionWrapper wrapper, int signature, Object type, int flags) { Object delegate = wrapper.getDelegate(); assert !(delegate instanceof PythonAbstractObject); PythonContext context = PythonContext.get(null); PythonLanguage language = context.getLanguage(); - return PExternalFunctionWrapper.createWrapperFunction(name, delegate, type, flags, signature, language, context.factory(), false); + return PExternalFunctionWrapper.createWrapperFunction(name, delegate, type, flags, signature, language, false); } @Specialization(guards = {"!isNativeWrapper(callable)"}) @@ -2167,7 +2166,7 @@ static PythonObject doNativeCallableWithWrapper(TruffleString name, Object calla resolvedCallable = callable; } PythonLanguage language = context.getLanguage(); - PBuiltinFunction function = PExternalFunctionWrapper.createWrapperFunction(name, resolvedCallable, type, flags, signature, language, context.factory(), doArgAndResultConversion); + PythonObject function = PExternalFunctionWrapper.createWrapperFunction(name, resolvedCallable, type, flags, signature, language, doArgAndResultConversion); return function != null ? function : castToPythonObject(resolvedCallable); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java index 18528ad4a6..0f12b96b47 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -56,11 +56,11 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyTypeObject; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Py_ssize_t; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.tsArray; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PythonAbstractObject; @@ -93,31 +93,29 @@ import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.StorageToNativeNode; import com.oracle.graal.python.builtins.objects.floats.PFloat; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.function.Signature; import com.oracle.graal.python.builtins.objects.ints.PInt; +import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotCExtNative; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotNative; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.PRootNode; -import com.oracle.graal.python.nodes.SpecialMethodNames; import com.oracle.graal.python.nodes.argument.ReadIndexedArgumentNode; import com.oracle.graal.python.nodes.argument.ReadVarArgsNode; import com.oracle.graal.python.nodes.argument.ReadVarKeywordsNode; -import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode; +import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode; import com.oracle.graal.python.nodes.object.IsForeignObjectNode; -import com.oracle.graal.python.nodes.truffle.PythonTypes; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.ExecutionContext.CalleeContext; import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext; @@ -126,7 +124,7 @@ import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode; import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.NativeObjectSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; @@ -149,9 +147,11 @@ import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.ImportStatic; +import com.oracle.truffle.api.dsl.InlineSupport.InlineTarget; +import com.oracle.truffle.api.dsl.InlineSupport.RequiredField; +import com.oracle.truffle.api.dsl.InlineSupport.StateField; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ArityException; @@ -187,22 +187,6 @@ public static PKeyword[] createKwDefaults(Object callable, Object closure) { return new PKeyword[]{new PKeyword(KW_CALLABLE, callable), new PKeyword(KW_CLOSURE, closure)}; } - public static Object tryGetHiddenCallable(PBuiltinFunction function) { - if (function.getFunctionRootNode() instanceof MethodDescriptorRoot) { - return getHiddenCallable(function.getKwDefaults()); - } - return null; - } - - public static Object getHiddenCallable(PKeyword[] kwDefaults) { - if (kwDefaults.length >= KEYWORDS_HIDDEN_CALLABLE.length) { - PKeyword kwDefault = kwDefaults[0]; - assert KW_CALLABLE.equalsUncached(kwDefault.getName(), TS_ENCODING) : "invalid keyword defaults"; - return kwDefault.getValue(); - } - throw CompilerDirectives.shouldNotReachHere(); - } - public abstract static class FinishArgNode extends PNodeWithContext { public abstract void execute(Object value); @@ -496,7 +480,6 @@ static RootCallTarget getOrCreateCallTarget(PExternalFunctionWrapper sig, Python case CALL: case INITPROC: case KEYWORDS: - case NEW: /* * If no conversion is requested, this means we directly call a managed function * (without argument conversion). Null indicates this @@ -507,6 +490,13 @@ static RootCallTarget getOrCreateCallTarget(PExternalFunctionWrapper sig, Python nodeKlass = MethKeywordsRoot.class; rootNodeFunction = l -> new MethKeywordsRoot(l, name, isStatic, sig); break; + case NEW: + if (!doArgAndResultConversion) { + return null; + } + nodeKlass = MethNewRoot.class; + rootNodeFunction = l -> new MethNewRoot(l, name, isStatic, sig); + break; case VARARGS: nodeKlass = MethVarargsRoot.class; rootNodeFunction = doArgAndResultConversion ? l -> new MethVarargsRoot(l, name, isStatic, sig) : l -> new MethVarargsRoot(l, name, isStatic); @@ -626,10 +616,10 @@ static RootCallTarget getOrCreateCallTarget(PExternalFunctionWrapper sig, Python return language.createCachedExternalFunWrapperCallTarget(rootNodeFunction, nodeKlass, sig, name, doArgAndResultConversion, isStatic); } - public static PBuiltinFunction createWrapperFunction(TruffleString name, Object callable, Object enclosingType, int flags, int sig, - PythonLanguage language, PythonObjectFactory factory, boolean doArgAndResultConversion) { + public static PythonObject createWrapperFunction(TruffleString name, Object callable, Object enclosingType, int flags, int sig, + PythonLanguage language, boolean doArgAndResultConversion) { return createWrapperFunction(name, callable, enclosingType, flags, PExternalFunctionWrapper.fromValue(sig), - language, factory, doArgAndResultConversion); + language, doArgAndResultConversion); } /** @@ -639,19 +629,17 @@ public static PBuiltinFunction createWrapperFunction(TruffleString name, Object * @param language The Python language object. * @param sig The wrapper/signature ID as defined in {@link PExternalFunctionWrapper}. * @param name The name of the method. - * @param callable A reference denoting executable code. Currently, there are three - * representations for that: (1) a native function pointer, (2) a - * {@link RootCallTarget}, and (3) a {@link BuiltinMethodDescriptor}. + * @param callable A reference denoting executable code. Currently, there are two + * representations for that: a native function pointer or a + * {@link RootCallTarget} * @param enclosingType The type the function belongs to (needed for checking of * {@code self}). - * @param factory Just an instance of {@link PythonObjectFactory} to create the function - * object. * @return A {@link PBuiltinFunction} implementing the semantics of the specified slot * wrapper. */ @TruffleBoundary - public static PBuiltinFunction createWrapperFunction(TruffleString name, Object callable, Object enclosingType, int flags, PExternalFunctionWrapper sig, PythonLanguage language, - PythonObjectFactory factory, boolean doArgAndResultConversion) { + public static PythonObject createWrapperFunction(TruffleString name, Object callable, Object enclosingType, int flags, PExternalFunctionWrapper sig, PythonLanguage language, + boolean doArgAndResultConversion) { LOGGER.finer(() -> PythonUtils.formatJString("ExternalFunctions.createWrapperFunction(%s, %s)", name, callable)); assert !isClosurePointer(PythonContext.get(null), callable, InteropLibrary.getUncached(callable)); if (flags < 0) { @@ -680,16 +668,6 @@ public static PBuiltinFunction createWrapperFunction(TruffleString name, Object numDefaults = PythonBuiltins.numDefaults(builtinFunctionRootNode.getBuiltin()); } kwDefaults = PKeyword.EMPTY_KEYWORDS; - } else if (callable instanceof BuiltinMethodDescriptor builtinMethodDescriptor) { - /* - * If we see a built-in method descriptor here, it was originally retrieved by a - * slot lookup. This means, the slot was already properly registered and therefore - * also its call target. - */ - callTarget = language.getDescriptorCallTarget(builtinMethodDescriptor); - // again: special case for built-in functions - numDefaults = PythonBuiltins.numDefaults(builtinMethodDescriptor.getBuiltinAnnotation()); - kwDefaults = PKeyword.EMPTY_KEYWORDS; } else { callTarget = getOrCreateCallTarget(sig, language, name, doArgAndResultConversion, CExtContext.isMethStatic(flags)); if (callTarget == null) { @@ -708,7 +686,7 @@ public static PBuiltinFunction createWrapperFunction(TruffleString name, Object } Object[] defaults = PBuiltinFunction.generateDefaults(numDefaults); - Object type = (enclosingType == PNone.NO_VALUE || SpecialMethodNames.T___NEW__.equalsUncached(name, TS_ENCODING)) ? null : enclosingType; + Object type = enclosingType == PNone.NO_VALUE ? null : enclosingType; // TODO(fa): this should eventually go away switch (sig) { case NOARGS: @@ -718,24 +696,11 @@ public static PBuiltinFunction createWrapperFunction(TruffleString name, Object case FASTCALL: case FASTCALL_WITH_KEYWORDS: case METHOD: - return factory.createBuiltinFunction(name, type, defaults, kwDefaults, flags, callTarget); - } - return factory.createWrapperDescriptor(name, type, defaults, kwDefaults, flags, callTarget, slot, sig); - } - - /** - * {@link #createWrapperFunction(TruffleString, Object, Object, int, PExternalFunctionWrapper, PythonLanguage, PythonObjectFactory, boolean)}. - */ - @TruffleBoundary - public static PBuiltinFunction createWrapperFunction(TruffleString name, TpSlotCExtNative slot, Object enclosingType, PExternalFunctionWrapper sig, PythonLanguage language, - PythonObjectFactory factory) { - RootCallTarget callTarget = getOrCreateCallTarget(sig, language, name, true, false); - if (callTarget == null) { - return null; + return PFactory.createBuiltinFunction(language, name, type, defaults, kwDefaults, flags, callTarget); + case NEW: + return PFactory.createNewWrapper(language, type, defaults, kwDefaults, callTarget, slot); } - var kwDefaults = ExternalFunctionNodes.createKwDefaults(slot.getCallable()); - Object[] defaults = PBuiltinFunction.generateDefaults(sig.numDefaults); - return factory.createWrapperDescriptor(name, enclosingType, defaults, kwDefaults, 0, callTarget, slot, sig); + return PFactory.createWrapperDescriptor(language, name, type, defaults, kwDefaults, flags, callTarget, slot, sig); } private static boolean isClosurePointer(PythonContext context, Object callable, InteropLibrary lib) { @@ -752,21 +717,15 @@ private static boolean isClosurePointer(PythonContext context, Object callable, private static int getCompareOpCode(PExternalFunctionWrapper sig) { // op codes for binary comparisons (defined in 'object.h') - switch (sig) { - case LT: - return 0; - case LE: - return 1; - case EQ: - return 2; - case NE: - return 3; - case GT: - return 4; - case GE: - return 5; - } - throw CompilerDirectives.shouldNotReachHere(); + return switch (sig) { + case LT -> RichCmpOp.Py_LT.asNative(); + case LE -> RichCmpOp.Py_LE.asNative(); + case EQ -> RichCmpOp.Py_EQ.asNative(); + case NE -> RichCmpOp.Py_NE.asNative(); + case GT -> RichCmpOp.Py_GT.asNative(); + case GE -> RichCmpOp.Py_GE.asNative(); + default -> throw CompilerDirectives.shouldNotReachHere(sig.getName()); + }; } CheckFunctionResultNode createCheckFunctionResultNode() { @@ -811,11 +770,11 @@ public String getSignature() { } private static Signature createSignature(boolean takesVarKeywordArgs, int varArgIndex, TruffleString[] parameters, boolean checkEnclosingType, boolean hidden) { - return new Signature(-1, takesVarKeywordArgs, varArgIndex, false, parameters, KEYWORDS_HIDDEN_CALLABLE, checkEnclosingType, T_EMPTY_STRING, hidden); + return new Signature(-1, takesVarKeywordArgs, varArgIndex, parameters, KEYWORDS_HIDDEN_CALLABLE, checkEnclosingType, T_EMPTY_STRING, hidden); } private static Signature createSignatureWithClosure(boolean takesVarKeywordArgs, int varArgIndex, TruffleString[] parameters, boolean checkEnclosingType, boolean hidden) { - return new Signature(-1, takesVarKeywordArgs, varArgIndex, false, parameters, KEYWORDS_HIDDEN_CALLABLE_AND_CLOSURE, checkEnclosingType, T_EMPTY_STRING, hidden); + return new Signature(-1, takesVarKeywordArgs, varArgIndex, parameters, KEYWORDS_HIDDEN_CALLABLE_AND_CLOSURE, checkEnclosingType, T_EMPTY_STRING, hidden); } static final class MethDirectRoot extends MethodDescriptorRoot { @@ -850,9 +809,6 @@ public static MethDirectRoot create(PythonLanguage lang, TruffleString name, PEx } } - /** - * Like {@link com.oracle.graal.python.nodes.call.FunctionInvokeNode} but invokes a C function. - */ @GenerateUncached @GenerateCached(false) @GenerateInline @@ -879,10 +835,10 @@ static Object invoke(VirtualFrame frame, Node inliningTarget, PythonThreadState return lib.execute(callable, cArguments); } catch (UnsupportedTypeException | UnsupportedMessageException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, TypeError, ErrorMessages.CALLING_NATIVE_FUNC_FAILED, name, e); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CALLING_NATIVE_FUNC_FAILED, name, e); } catch (ArityException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, TypeError, ErrorMessages.CALLING_NATIVE_FUNC_EXPECTED_ARGS, name, e.getExpectedMinArity(), e.getActualArity()); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CALLING_NATIVE_FUNC_EXPECTED_ARGS, name, e.getExpectedMinArity(), e.getActualArity()); } catch (Throwable exception) { /* * Always re-acquire the GIL here. This is necessary because it could happen that C @@ -978,7 +934,7 @@ public abstract static class MethodDescriptorRoot extends PRootNode { private final PExternalFunctionWrapper provider; private final CApiTiming timing; @Child private CalleeContext calleeContext = CalleeContext.create(); - @Child private CallVarargsMethodNode invokeNode; + @Child private CallNode invokeNode; @Child private ExternalFunctionWrapperInvokeNode externalInvokeNode; @Child private ReadIndexedArgumentNode readSelfNode; @Child private ReadIndexedArgumentNode readCallableNode; @@ -1001,7 +957,7 @@ public abstract static class MethodDescriptorRoot extends PRootNode { this.externalInvokeNode = ExternalFunctionWrapperInvokeNode.create(); this.convertArgs = provider.createConvertArgNodes(); } else { - this.invokeNode = CallVarargsMethodNode.create(); + this.invokeNode = CallNode.create(); this.convertArgs = null; } if (!isStatic) { @@ -1127,23 +1083,17 @@ protected final Object readSelf(VirtualFrame frame) { } } - public static final class MethKeywordsRoot extends MethodDescriptorRoot { + public static class MethKeywordsRoot extends MethodDescriptorRoot { private static final Signature SIGNATURE = createSignature(true, 1, tsArray("self"), true, true); - @Child private PythonObjectFactory factory; - @Child private ReadVarArgsNode readVarargsNode; - @Child private ReadVarKeywordsNode readKwargsNode; - @Child private CreateArgsTupleNode createArgsTupleNode; - @Child private ReleaseNativeSequenceStorageNode freeNode; - - private boolean seenNativeArgsTupleStorage; + @Child protected ReadVarArgsNode readVarargsNode; + @Child protected ReadVarKeywordsNode readKwargsNode; + @Child protected CreateArgsTupleNode createArgsTupleNode; + @Child protected ReleaseNativeSequenceStorageNode freeNode; - public MethKeywordsRoot(PythonLanguage language, TruffleString name, boolean isStatic) { - super(language, name, isStatic); - } + protected boolean seenNativeArgsTupleStorage; public MethKeywordsRoot(PythonLanguage language, TruffleString name, boolean isStatic, PExternalFunctionWrapper provider) { super(language, name, isStatic, provider); - this.factory = PythonObjectFactory.create(); this.readVarargsNode = ReadVarArgsNode.create(true); this.readKwargsNode = ReadVarKeywordsNode.create(PythonUtils.EMPTY_TRUFFLESTRING_ARRAY); this.createArgsTupleNode = CreateArgsTupleNodeGen.create(); @@ -1155,7 +1105,8 @@ protected Object[] prepareCArguments(VirtualFrame frame) { Object self = readSelf(frame); Object[] args = readVarargsNode.executeObjectArray(frame); PKeyword[] kwargs = readKwargsNode.executePKeyword(frame); - return new Object[]{self, createArgsTupleNode.execute(factory, args, seenNativeArgsTupleStorage), factory.createDict(kwargs)}; + PythonLanguage language = getLanguage(PythonLanguage.class); + return new Object[]{self, createArgsTupleNode.execute(language, args, seenNativeArgsTupleStorage), PFactory.createDict(language, kwargs)}; } @Override @@ -1177,7 +1128,6 @@ public Signature getSignature() { public static final class MethVarargsRoot extends MethodDescriptorRoot { private static final Signature SIGNATURE = createSignature(false, 1, tsArray("self"), true, true); - @Child private PythonObjectFactory factory; @Child private ReadVarArgsNode readVarargsNode; @Child private CreateArgsTupleNode createArgsTupleNode; @Child private ReleaseNativeSequenceStorageNode freeNode; @@ -1190,7 +1140,6 @@ public MethVarargsRoot(PythonLanguage language, TruffleString name, boolean isSt public MethVarargsRoot(PythonLanguage language, TruffleString name, boolean isStatic, PExternalFunctionWrapper provider) { super(language, name, isStatic, provider); - this.factory = PythonObjectFactory.create(); this.readVarargsNode = ReadVarArgsNode.create(true); this.createArgsTupleNode = CreateArgsTupleNodeGen.create(); this.freeNode = ReleaseNativeSequenceStorageNodeGen.create(); @@ -1200,7 +1149,7 @@ public MethVarargsRoot(PythonLanguage language, TruffleString name, boolean isSt protected Object[] prepareCArguments(VirtualFrame frame) { Object self = readSelf(frame); Object[] args = readVarargsNode.executeObjectArray(frame); - return new Object[]{self, createArgsTupleNode.execute(factory, args, seenNativeArgsTupleStorage)}; + return new Object[]{self, createArgsTupleNode.execute(getLanguage(PythonLanguage.class), args, seenNativeArgsTupleStorage)}; } @Override @@ -1269,6 +1218,25 @@ public Signature getSignature() { } } + public static final class MethNewRoot extends MethKeywordsRoot { + + public MethNewRoot(PythonLanguage language, TruffleString name, boolean isStatic, PExternalFunctionWrapper provider) { + super(language, name, isStatic, provider); + } + + @Override + protected Object[] prepareCArguments(VirtualFrame frame) { + Object methodSelf = readSelf(frame); + Object[] args = readVarargsNode.executeObjectArray(frame); + // TODO checks + Object self = args[0]; + args = PythonUtils.arrayCopyOfRange(args, 1, args.length); + PKeyword[] kwargs = readKwargsNode.executePKeyword(frame); + PythonLanguage language = getLanguage(PythonLanguage.class); + return new Object[]{self, createArgsTupleNode.execute(language, args, seenNativeArgsTupleStorage), PFactory.createDict(language, kwargs)}; + } + } + public static final class MethInquiryRoot extends MethodDescriptorRoot { private static final Signature SIGNATURE = createSignature(false, -1, tsArray("self"), true, false); @@ -1309,7 +1277,7 @@ public MethNoargsRoot(PythonLanguage language, TruffleString name, boolean isSta @Override protected Object[] prepareCArguments(VirtualFrame frame) { - return new Object[]{readSelf(frame), PNone.NONE}; + return new Object[]{readSelf(frame), PNone.NO_VALUE}; } @Override @@ -1358,7 +1326,6 @@ public Signature getSignature() { public static final class MethFastcallWithKeywordsRoot extends MethodDescriptorRoot { private static final Signature SIGNATURE = createSignature(true, 1, tsArray("self"), true, true); - @Child private PythonObjectFactory factory; @Child private ReadVarArgsNode readVarargsNode; @Child private ReadVarKeywordsNode readKwargsNode; @@ -1368,7 +1335,6 @@ public MethFastcallWithKeywordsRoot(PythonLanguage language, TruffleString name, public MethFastcallWithKeywordsRoot(PythonLanguage language, TruffleString name, boolean isStatic, PExternalFunctionWrapper provider) { super(language, name, isStatic, provider); - this.factory = PythonObjectFactory.create(); this.readVarargsNode = ReadVarArgsNode.create(true); this.readKwargsNode = ReadVarKeywordsNode.create(PythonUtils.EMPTY_TRUFFLESTRING_ARRAY); } @@ -1388,7 +1354,7 @@ protected Object[] prepareCArguments(VirtualFrame frame) { fastcallKwnames[i] = kwargs[i].getName(); fastcallArgs[args.length + i] = kwargs[i].getValue(); } - kwnamesTuple = factory.createTuple(fastcallKwnames); + kwnamesTuple = PFactory.createTuple(PythonLanguage.get(this), fastcallKwnames); } return new Object[]{self, new CPyObjectArrayWrapper(fastcallArgs), args.length, kwnamesTuple}; } @@ -1410,7 +1376,6 @@ public Signature getSignature() { public static final class MethMethodRoot extends MethodDescriptorRoot { private static final Signature SIGNATURE = createSignature(true, 1, tsArray("self", "cls"), true, true); - @Child private PythonObjectFactory factory; @Child private ReadIndexedArgumentNode readClsNode; @Child private ReadVarArgsNode readVarargsNode; @Child private ReadVarKeywordsNode readKwargsNode; @@ -1421,7 +1386,6 @@ public MethMethodRoot(PythonLanguage language, TruffleString name, boolean isSta public MethMethodRoot(PythonLanguage language, TruffleString name, boolean isStatic, PExternalFunctionWrapper provider) { super(language, name, isStatic, provider); - this.factory = PythonObjectFactory.create(); this.readClsNode = ReadIndexedArgumentNode.create(1); this.readVarargsNode = ReadVarArgsNode.create(true); this.readKwargsNode = ReadVarKeywordsNode.create(PythonUtils.EMPTY_TRUFFLESTRING_ARRAY); @@ -1440,7 +1404,7 @@ protected Object[] prepareCArguments(VirtualFrame frame) { fastcallKwnames[i] = kwargs[i].getName(); fastcallArgs[args.length + i] = kwargs[i].getValue(); } - return new Object[]{self, cls, new CPyObjectArrayWrapper(fastcallArgs), args.length, factory.createTuple(fastcallKwnames)}; + return new Object[]{self, cls, new CPyObjectArrayWrapper(fastcallArgs), args.length, PFactory.createTuple(PythonLanguage.get(this), fastcallKwnames)}; } @Override @@ -2173,6 +2137,52 @@ private ReadIndexedArgumentNode ensureReadArgNode() { } } + /** + * An inlined node-like object for keeping track of eager native allocation state bit. Should be + * {@code @Cached} and passed into + * {@link CreateArgsTupleNode#execute(Node, PythonLanguage, Object[], EagerTupleState)}. Then + * the {@link #report(Node, PTuple)} method should be called with the tuple after the native + * call returns. + */ + public static final class EagerTupleState { + private final StateField state; + + private static final EagerTupleState UNCACHED = new EagerTupleState(); + + private EagerTupleState() { + this.state = null; + } + + private EagerTupleState(InlineTarget target) { + this.state = target.getState(0, 1); + } + + public boolean isEager(Node inliningTarget) { + if (state == null) { + return false; + } + return state.get(inliningTarget) != 0; + } + + public void report(Node inliningTarget, PTuple tuple) { + if (state != null) { + if (!isEager(inliningTarget) && tuple.getSequenceStorage() instanceof NativeSequenceStorage) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + state.set(inliningTarget, 1); + } + } + } + + public static EagerTupleState inline( + @RequiredField(value = StateField.class, bits = 1) InlineTarget target) { + return new EagerTupleState(target); + } + + public static EagerTupleState getUncached() { + return UNCACHED; + } + } + /** * We need to inflate all primitives in order to avoid memory leaks. Explanation: Primitives * would currently be wrapped into a PrimitiveNativeWrapper. If any of those will receive a @@ -2182,44 +2192,49 @@ private ReadIndexedArgumentNode ensureReadArgNode() { * arguments after the call returned. */ @GenerateInline(false) - abstract static class CreateArgsTupleNode extends Node { - public abstract PTuple execute(PythonObjectFactory factory, Object[] args, boolean eagerNative); + @GenerateUncached + public abstract static class CreateArgsTupleNode extends Node { + public abstract PTuple execute(PythonLanguage language, Object[] args, boolean eagerNative); + + public final PTuple execute(Node inliningTarget, PythonLanguage language, Object[] args, EagerTupleState state) { + return execute(language, args, state.isEager(inliningTarget)); + } @Specialization(guards = {"args.length == cachedLen", "cachedLen <= 8", "!eagerNative"}, limit = "1") @ExplodeLoop(kind = LoopExplosionKind.FULL_UNROLL) - static PTuple doCachedLen(PythonObjectFactory factory, Object[] args, @SuppressWarnings("unused") boolean eagerNative, + static PTuple doCachedLen(PythonLanguage language, Object[] args, @SuppressWarnings("unused") boolean eagerNative, @Cached("args.length") int cachedLen, @Cached("createMaterializeNodes(args.length)") MaterializePrimitiveNode[] materializePrimitiveNodes) { for (int i = 0; i < cachedLen; i++) { - args[i] = materializePrimitiveNodes[i].execute(factory, args[i]); + args[i] = materializePrimitiveNodes[i].execute(language, args[i]); } - return factory.createTuple(args); + return PFactory.createTuple(language, args); } @Specialization(guards = {"args.length == cachedLen", "cachedLen <= 8", "eagerNative"}, limit = "1", replaces = "doCachedLen") @ExplodeLoop(kind = LoopExplosionKind.FULL_UNROLL) - static PTuple doCachedLenEagerNative(PythonObjectFactory factory, Object[] args, @SuppressWarnings("unused") boolean eagerNative, + static PTuple doCachedLenEagerNative(PythonLanguage language, Object[] args, @SuppressWarnings("unused") boolean eagerNative, @Bind("this") Node inliningTarget, @Cached("args.length") int cachedLen, @Cached("createMaterializeNodes(args.length)") MaterializePrimitiveNode[] materializePrimitiveNodes, @Exclusive @Cached StorageToNativeNode storageToNativeNode) { for (int i = 0; i < cachedLen; i++) { - args[i] = materializePrimitiveNodes[i].execute(factory, args[i]); + args[i] = materializePrimitiveNodes[i].execute(language, args[i]); } - return factory.createTuple(storageToNativeNode.execute(inliningTarget, args, cachedLen, true)); + return PFactory.createTuple(language, storageToNativeNode.execute(inliningTarget, args, cachedLen, true)); } @Specialization(replaces = {"doCachedLen", "doCachedLenEagerNative"}) - static PTuple doGeneric(PythonObjectFactory factory, Object[] args, boolean eagerNative, + static PTuple doGeneric(PythonLanguage language, Object[] args, boolean eagerNative, @Bind("this") Node inliningTarget, @Cached MaterializePrimitiveNode materializePrimitiveNode, @Exclusive @Cached StorageToNativeNode storageToNativeNode) { int n = args.length; for (int i = 0; i < n; i++) { - args[i] = materializePrimitiveNode.execute(factory, args[i]); + args[i] = materializePrimitiveNode.execute(language, args[i]); } SequenceStorage storage; if (eagerNative) { @@ -2227,7 +2242,7 @@ static PTuple doGeneric(PythonObjectFactory factory, Object[] args, boolean eage } else { storage = new ObjectSequenceStorage(args); } - return factory.createTuple(storage); + return PFactory.createTuple(language, storage); } static MaterializePrimitiveNode[] createMaterializeNodes(int length) { @@ -2237,14 +2252,6 @@ static MaterializePrimitiveNode[] createMaterializeNodes(int length) { } return materializePrimitiveNodes; } - - static PythonToNativeNode[] createPythonToNativeNodes(int length) { - PythonToNativeNode[] pythonToNativeNodes = new PythonToNativeNode[length]; - for (int i = 0; i < length; i++) { - pythonToNativeNodes[i] = PythonToNativeNodeGen.create(); - } - return pythonToNativeNodes; - } } @GenerateInline(false) @@ -2288,42 +2295,38 @@ static void doObjectGeneric(NativeObjectSequenceStorage storage, * Special helper nodes that materializes any primitive that would leak the wrapper if the * reference is owned by managed code only. */ - @TypeSystemReference(PythonTypes.class) @GenerateInline(false) + @GenerateUncached abstract static class MaterializePrimitiveNode extends Node { - public abstract Object execute(PythonObjectFactory factory, Object object); + public abstract Object execute(PythonLanguage language, Object object); // NOTE: Booleans don't need to be materialized because they are singletons. @Specialization - static PInt doInteger(PythonObjectFactory factory, int i) { - return factory.createInt(i); + static PInt doInteger(PythonLanguage language, int i) { + return PFactory.createInt(language, i); } - @Specialization(replaces = "doInteger") - static PInt doLong(PythonObjectFactory factory, long l) { - return factory.createInt(l); + @Specialization + static PInt doLong(PythonLanguage language, long l) { + return PFactory.createInt(language, l); } @Specialization - static PFloat doDouble(PythonObjectFactory factory, double d) { - return factory.createFloat(d); + static PFloat doDouble(PythonLanguage language, double d) { + return PFactory.createFloat(language, d); } @Specialization - static PString doString(PythonObjectFactory factory, TruffleString s) { - return factory.createString(s); + static PString doString(PythonLanguage language, TruffleString s) { + return PFactory.createString(language, s); } - @Specialization(guards = "!needsMaterialization(object)") - static Object doObject(@SuppressWarnings("unused") PythonObjectFactory factory, Object object) { + @Fallback + static Object doObject(@SuppressWarnings("unused") PythonLanguage language, Object object) { return object; } - - static boolean needsMaterialization(Object object) { - return object instanceof Integer || object instanceof Long || PGuards.isDouble(object) || object instanceof TruffleString; - } } // roughly equivalent to _Py_CheckFunctionResult in Objects/call.c @@ -2456,7 +2459,7 @@ static Object doGeneric(PythonThreadState state, @SuppressWarnings("unused") Tru AbstractTruffleException currentException = state.getCurrentException(); // if no exception occurred, the iterator is exhausted -> raise StopIteration if (currentException == null) { - throw raiseNode.raiseStopIteration(); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.StopIteration); } else { throw clearCurrentExceptionNode.getCurrentExceptionForReraise(inliningTarget, state); } @@ -2596,7 +2599,7 @@ static boolean doGeneric(PythonThreadState threadState, TruffleString name, Obje } } CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, SystemError, ErrorMessages.FUNC_DIDNT_RETURN_INT, name); + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, ErrorMessages.FUNC_DIDNT_RETURN_INT, name); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/NativeCAPISymbol.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/NativeCAPISymbol.java index 946f7150e2..9c03a2b4fd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/NativeCAPISymbol.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/NativeCAPISymbol.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,6 +44,7 @@ import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.ConstCharPtrAsTruffleString; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.INT64_T; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Int; +import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.IterResult; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.LONG_LONG; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PY_SSIZE_T_PTR; import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Pointer; @@ -123,7 +124,6 @@ public enum NativeCAPISymbol implements NativeCExtSymbol { /* Python C API functions */ - FUN_GET_METHODS_FLAGS("get_methods_flags", INT64_T, PyTypeObject), FUN_PTR_COMPARE("truffle_ptr_compare", Int, Pointer, Pointer, Int), FUN_PTR_ADD("truffle_ptr_add", Pointer, Pointer, Py_ssize_t), FUN_PY_TRUFFLE_OBJECT_ARRAY_RELEASE("PyTruffle_ObjectArrayRelease", ArgDescriptor.Void, Pointer, Int), @@ -167,6 +167,7 @@ public enum NativeCAPISymbol implements NativeCExtSymbol { FUN_GRAALPY_GC_COLLECT("GraalPyGC_Collect", Py_ssize_t, Int), FUN_SUBTYPE_TRAVERSE("subtype_traverse", Int, PyObject, Pointer, Pointer), FUN_GRAALPYOBJECT_GC_NOTIFYOWNERSHIPTRANSFER("_GraalPyObject_GC_NotifyOwnershipTransfer", Void, PyObject), + FUN_PY_OBJECT_NEXT_NOT_IMPLEMENTED("_PyObject_NextNotImplemented", IterResult, PyObject), /* PyDateTime_CAPI */ diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PThreadState.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PThreadState.java index aecabf4b00..cf70e5c5be 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PThreadState.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PThreadState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -52,6 +52,7 @@ import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.interop.InteropLibrary; @@ -108,7 +109,7 @@ private static Object allocateCLayout(PythonThreadState threadState) { PythonContext pythonContext = PythonContext.get(null); PDict threadStateDict = threadState.getDict(); if (threadStateDict == null) { - threadStateDict = pythonContext.factory().createDict(); + threadStateDict = PFactory.createDict(pythonContext.getLanguage()); threadState.setDict(threadStateDict); } writePtrNode.write(ptr, CFields.PyThreadState__dict, toNative.execute(threadStateDict)); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyCFunctionWrapper.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyCFunctionWrapper.java index df98a6e15f..5ba82fb1cf 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyCFunctionWrapper.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyCFunctionWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -49,35 +49,23 @@ import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNewRefNode; import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.TransformExceptionToNativeNode; import com.oracle.graal.python.builtins.objects.cext.common.CExtContext; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.BinaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.UnaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.function.Signature; -import com.oracle.graal.python.nodes.argument.CreateArgumentsNode.CreateAndCheckArgumentsNode; +import com.oracle.graal.python.nodes.argument.CreateArgumentsNode; import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode; import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode; -import com.oracle.graal.python.nodes.call.CallTargetInvokeNode; -import com.oracle.graal.python.nodes.call.GenericInvokeNode; -import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode; -import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; +import com.oracle.graal.python.nodes.call.CallDispatchers; import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.interop.ArityException; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; @@ -93,9 +81,8 @@ /** * A wrapper class for managed functions such that they can be called with native function pointers * (like C type {@code PyCFunction}). This is very similar to {@link PyProcsWrapper} but the main - * difference is that this wrapper does not keep a reference to the function object but only to - * either the {@link RootCallTarget} or the {@link BuiltinMethodDescriptor} (in case of built-in - * functions). + * difference is that this wrapper does not keep a reference to the function object but only to the + * {@link RootCallTarget} *

    * Since in C, function pointers are expected to valid the whole time, NFI closure must be kept * alive as long as the context lives. Referencing a function object like {@link PyProcsWrapper} @@ -108,18 +95,6 @@ public abstract class PyCFunctionWrapper implements TruffleObject { protected final RootCallTarget callTarget; protected final Signature signature; protected final TruffleString callTargetName; - /** - * This uses the fact that {@link BuiltinMethodDescriptor} is context independent (but language - * dependent) so it is "more" shareable in the native, and we can use create a - * {@link BuiltinMethodDescriptor} not only for slots but for any builtin. - *

    - * Once {@link BuiltinMethodDescriptor} is phased out, we should reconsider if we need a context - * independent token for builtins for which one can look up a call target in the current - * language or a {@code PBuiltinFunction} in the current context. We can reuse the TpSlots - * mechanism like we reused {@link BuiltinMethodDescriptor} originally intended for slots only, - * but is it worth the effort and complexity? - */ - protected final BuiltinMethodDescriptor builtinMethodDescriptor; protected final CApiTiming timing; private long pointer; @@ -130,27 +105,14 @@ protected PyCFunctionWrapper(RootCallTarget callTarget, Signature signature) { this.signature = signature; String ctName = callTarget.getRootNode().getName(); this.callTargetName = PythonUtils.toTruffleStringUncached(ctName); - this.builtinMethodDescriptor = null; this.timing = CApiTiming.create(false, ctName); } - protected PyCFunctionWrapper(BuiltinMethodDescriptor builtinMethodDescriptor) { - assert builtinMethodDescriptor != null; - this.callTarget = null; - this.signature = null; - this.callTargetName = null; - this.builtinMethodDescriptor = builtinMethodDescriptor; - this.timing = CApiTiming.create(false, builtinMethodDescriptor.getName()); - } - public final RootCallTarget getCallTarget() { return callTarget; } public final Object getDelegate() { - if (builtinMethodDescriptor != null) { - return builtinMethodDescriptor; - } assert callTarget != null; return callTarget; } @@ -199,38 +161,18 @@ private static String toString(Object name, String flagsRepr, long pointer) { @Override @TruffleBoundary public String toString() { - return PyCFunctionWrapper.toString(builtinMethodDescriptor != null ? builtinMethodDescriptor.getName() : callTargetName, getFlagsRepr(), pointer); + return PyCFunctionWrapper.toString(callTargetName, getFlagsRepr(), pointer); } /** * Creates a wrapper for a {@link PBuiltinFunction} that can go to native. The flags are * required to determine the signature. The resulting {@link PyCFunctionWrapper} will not - * reference the built-in function object but will only wrap either its - * {@link BuiltinMethodDescriptor} (if available) or its {@link RootCallTarget}. + * reference the built-in function object but will only wrap its {@link RootCallTarget}. */ @TruffleBoundary public static PyCFunctionWrapper createFromBuiltinFunction(CApiContext cApiContext, PBuiltinFunction builtinFunction) { int flags = builtinFunction.getFlags(); - // try to use the BuiltinMethodDescriptor if available - BuiltinMethodDescriptor builtinMethodDescriptor = BuiltinMethodDescriptor.get(builtinFunction); - if (builtinMethodDescriptor != null) { - /* - * If we create a PyCFunctionWrapper for a BuiltinMethodDescriptor, we need to register - * the call target because it may happen that the wrapper is used to create another - * 'builtin_function_or_method' or 'method_descriptor' in which case we need to have the - * call target available. - */ - if (CExtContext.isMethNoArgs(flags) && builtinMethodDescriptor instanceof UnaryBuiltinDescriptor || - CExtContext.isMethO(flags) && builtinMethodDescriptor instanceof BinaryBuiltinDescriptor) { - cApiContext.getContext().getLanguage().registerBuiltinDescriptorCallTarget(builtinMethodDescriptor, builtinFunction.getCallTarget()); - } - if (CExtContext.isMethNoArgs(flags) && builtinMethodDescriptor instanceof UnaryBuiltinDescriptor) { - return cApiContext.getOrCreatePyCFunctionWrapper(builtinMethodDescriptor, PyCFunctionUnaryWrapper::new); - } else if (CExtContext.isMethO(flags) && builtinMethodDescriptor instanceof BinaryBuiltinDescriptor) { - return cApiContext.getOrCreatePyCFunctionWrapper(builtinMethodDescriptor, PyCFunctionBinaryWrapper::new); - } - } RootCallTarget ct = builtinFunction.getCallTarget(); Signature signature = builtinFunction.getSignature(); if (CExtContext.isMethNoArgs(flags)) { @@ -248,35 +190,6 @@ public static PyCFunctionWrapper createFromBuiltinFunction(CApiContext cApiConte } } - /** - * This is very much like {@link com.oracle.graal.python.nodes.call.CallDispatchNode} but just - * for calling {@link CallTarget call tagets} directly instead of function/method objects. This - * node essentially serves as an inline cache for the invoked call target. This node will - * automatically fall back to a {@link GenericInvokeNode} if the inline cache flows over. - */ - @GenerateUncached - @GenerateInline - @GenerateCached(false) - abstract static class CallTargetDispatchNode extends Node { - - abstract Object execute(Node inliningTarget, CallTarget ct, Object[] pythonArguments); - - @Specialization(guards = "ct == cachedCt", limit = "1") - static Object doCallTargetDirect(@SuppressWarnings("unused") CallTarget ct, Object[] args, - @SuppressWarnings("unused") @Cached(value = "ct", weak = true) CallTarget cachedCt, - @Cached("create(ct, true, false)") CallTargetInvokeNode callNode) { - assert PArguments.isPythonFrame(args); - return callNode.execute(null, null, null, null, args); - } - - @Specialization(replaces = "doCallTargetDirect") - static Object doCallTargetIndirect(CallTarget ct, Object[] args, - @Cached(inline = false) GenericInvokeNode callNode) { - assert PArguments.isPythonFrame(args); - return callNode.execute(ct, args); - } - } - @ExportLibrary(InteropLibrary.class) static final class PyCFunctionUnaryWrapper extends PyCFunctionWrapper { @@ -284,17 +197,12 @@ static final class PyCFunctionUnaryWrapper extends PyCFunctionWrapper { super(callTarget, signature); } - private PyCFunctionUnaryWrapper(BuiltinMethodDescriptor builtinMethodDescriptor) { - super(builtinMethodDescriptor); - } - @ExportMessage Object execute(Object[] arguments, @Bind("$node") Node inliningTarget, @Cached PythonToNativeNewRefNode toNativeNode, - @Cached CallUnaryMethodNode callUnaryNode, - @Cached CreateAndCheckArgumentsNode createArgsNode, - @Cached CallTargetDispatchNode invokeNode, + @Cached CreateArgumentsNode createArgsNode, + @Cached CallDispatchers.CallTargetCachedInvokeNode invokeNode, @Cached NativeToPythonNode toJavaNode, @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, @Exclusive @Cached GilNode gil) throws ArityException { @@ -312,16 +220,9 @@ Object execute(Object[] arguments, try { Object result; Object jArg0 = toJavaNode.execute(arguments[0]); - if (builtinMethodDescriptor != null) { - assert callTarget == null; - result = callUnaryNode.executeObject(null, builtinMethodDescriptor, jArg0); - } else { - assert callTarget != null; - assert callTargetName != null; - Object[] pArgs = createArgsNode.execute(inliningTarget, callTargetName, PythonUtils.EMPTY_OBJECT_ARRAY, PKeyword.EMPTY_KEYWORDS, signature, jArg0, null, - PythonUtils.EMPTY_OBJECT_ARRAY, PKeyword.EMPTY_KEYWORDS, false); - result = invokeNode.execute(inliningTarget, callTarget, pArgs); - } + Object[] pArgs = createArgsNode.execute(inliningTarget, callTargetName, PythonUtils.EMPTY_OBJECT_ARRAY, PKeyword.EMPTY_KEYWORDS, signature, jArg0, null, + PythonUtils.EMPTY_OBJECT_ARRAY, PKeyword.EMPTY_KEYWORDS, false); + result = invokeNode.execute(null, inliningTarget, callTarget, pArgs); return toNativeNode.execute(result); } catch (Throwable t) { throw checkThrowableBeforeNative(t, toString(), ""); @@ -353,17 +254,12 @@ static final class PyCFunctionBinaryWrapper extends PyCFunctionWrapper { super(callTarget, signature); } - private PyCFunctionBinaryWrapper(BuiltinMethodDescriptor builtinMethodDescriptor) { - super(builtinMethodDescriptor); - } - @ExportMessage Object execute(Object[] arguments, @Bind("$node") Node inliningTarget, @Cached PythonToNativeNewRefNode toNativeNode, - @Cached CallBinaryMethodNode callBinaryMethodNode, - @Cached CallTargetDispatchNode invokeNode, - @Cached CreateAndCheckArgumentsNode createArgsNode, + @Cached CallDispatchers.CallTargetCachedInvokeNode invokeNode, + @Cached CreateArgumentsNode createArgsNode, @Cached NativeToPythonNode toJavaNode, @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, @Exclusive @Cached GilNode gil) throws ArityException { @@ -378,17 +274,9 @@ Object execute(Object[] arguments, Object result; Object jArg0 = toJavaNode.execute(arguments[0]); Object jArg1 = toJavaNode.execute(arguments[1]); - if (builtinMethodDescriptor != null) { - assert callTarget == null; - assert builtinMethodDescriptor instanceof BinaryBuiltinDescriptor; - result = callBinaryMethodNode.executeObject(builtinMethodDescriptor, jArg0, jArg1); - } else { - assert callTarget != null; - assert callTargetName != null; - Object[] pArgs = createArgsNode.execute(inliningTarget, callTargetName, new Object[]{jArg1}, PKeyword.EMPTY_KEYWORDS, signature, jArg0, null, - PythonUtils.EMPTY_OBJECT_ARRAY, PKeyword.EMPTY_KEYWORDS, false); - result = invokeNode.execute(inliningTarget, callTarget, pArgs); - } + Object[] pArgs = createArgsNode.execute(inliningTarget, callTargetName, new Object[]{jArg1}, PKeyword.EMPTY_KEYWORDS, signature, jArg0, null, + PythonUtils.EMPTY_OBJECT_ARRAY, PKeyword.EMPTY_KEYWORDS, false); + result = invokeNode.execute(null, inliningTarget, callTarget, pArgs); return toNativeNode.execute(result); } catch (Throwable t) { throw checkThrowableBeforeNative(t, toString(), ""); @@ -439,8 +327,8 @@ Object execute(Object[] arguments, @Bind("$node") Node inliningTarget, @Cached PythonToNativeNewRefNode toNativeNode, @Cached ExecutePositionalStarargsNode posStarargsNode, - @Cached CreateAndCheckArgumentsNode createArgsNode, - @Cached CallTargetDispatchNode invokeNode, + @Cached CreateArgumentsNode createArgsNode, + @Cached CallDispatchers.CallTargetCachedInvokeNode invokeNode, @Cached NativeToPythonNode toJavaNode, @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, @Exclusive @Cached GilNode gil) throws ArityException { @@ -455,13 +343,10 @@ Object execute(Object[] arguments, Object result; Object receiver = toJavaNode.execute(arguments[0]); Object starArgs = toJavaNode.execute(arguments[1]); - // currently, we do not have a BuiltinMethodDescriptor for varargs functions - assert builtinMethodDescriptor == null; - assert callTarget != null; Object[] starArgsArray = posStarargsNode.executeWith(null, starArgs); Object[] pArgs = createArgsNode.execute(inliningTarget, callTargetName, starArgsArray, PKeyword.EMPTY_KEYWORDS, signature, receiver, null, PBuiltinFunction.generateDefaults(numDefaults), PKeyword.EMPTY_KEYWORDS, false); - result = invokeNode.execute(inliningTarget, callTarget, pArgs); + result = invokeNode.execute(null, inliningTarget, callTarget, pArgs); return toNativeNode.execute(result); } catch (Throwable t) { throw checkThrowableBeforeNative(t, toString(), ""); @@ -505,8 +390,8 @@ Object execute(Object[] arguments, @Bind("$node") Node inliningTarget, @Cached PythonToNativeNewRefNode toNativeNode, @Cached ExecutePositionalStarargsNode posStarargsNode, - @Cached CreateAndCheckArgumentsNode createArgsNode, - @Cached CallTargetDispatchNode invokeNode, + @Cached CreateArgumentsNode createArgsNode, + @Cached CallDispatchers.CallTargetCachedInvokeNode invokeNode, @Cached ExpandKeywordStarargsNode expandKwargsNode, @Cached NativeToPythonNode toJavaNode, @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, @@ -522,16 +407,12 @@ Object execute(Object[] arguments, Object receiver = toJavaNode.execute(arguments[0]); Object starArgs = toJavaNode.execute(arguments[1]); Object kwArgs = toJavaNode.execute(arguments[2]); - // currently, we do not have a BuiltinMethodDescriptor for varargs functions - assert builtinMethodDescriptor == null; - assert callTarget != null; - assert callTargetName != null; Object[] starArgsArray = posStarargsNode.executeWith(null, starArgs); PKeyword[] kwArgsArray = expandKwargsNode.execute(inliningTarget, kwArgs); Object[] pArgs = createArgsNode.execute(inliningTarget, callTargetName, starArgsArray, kwArgsArray, signature, receiver, null, PBuiltinFunction.generateDefaults(numDefaults), PKeyword.EMPTY_KEYWORDS, false); - Object result = invokeNode.execute(inliningTarget, callTarget, pArgs); + Object result = invokeNode.execute(null, inliningTarget, callTarget, pArgs); return toNativeNode.execute(result); } catch (Throwable t) { throw checkThrowableBeforeNative(t, toString(), ""); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyDateTimeCAPIWrapper.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyDateTimeCAPIWrapper.java index 159a961e19..88dba50a3c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyDateTimeCAPIWrapper.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyDateTimeCAPIWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -61,6 +61,7 @@ import com.oracle.graal.python.lib.PyObjectSetAttr; import com.oracle.graal.python.nodes.statement.AbstractImportNode; import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.strings.TruffleString; @@ -118,7 +119,7 @@ public static PyCapsule initWrapper(PythonContext context, CApiContext capiConte Object pointerObject = allocatePyDatetimeCAPI(datetimeModule); - PyCapsule capsule = context.factory().createCapsuleJavaName(pointerObject, T_PYDATETIME_CAPSULE_NAME); + PyCapsule capsule = PFactory.createCapsuleJavaName(context.getLanguage(), pointerObject, T_PYDATETIME_CAPSULE_NAME); PyObjectSetAttr.executeUncached(datetimeModule, T_DATETIME_CAPI, capsule); assert PyObjectGetAttr.executeUncached(datetimeModule, T_DATETIME_CAPI) != context.getNativeNull(); return capsule; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyMemoryViewWrapper.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyMemoryViewWrapper.java index 08f3b241f7..7184996c8e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyMemoryViewWrapper.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyMemoryViewWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,7 +40,6 @@ */ package com.oracle.graal.python.builtins.objects.cext.capi; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PTR_ADD; import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyMemoryViewObject__exports; import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyMemoryViewObject__flags; @@ -59,8 +58,6 @@ import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.truffle.api.CompilerDirectives; @@ -91,9 +88,6 @@ private static Object intArrayToNativePySSizeArray(int[] intArray) { @TruffleBoundary private static Object allocate(PMemoryView object) { - if (object.isReleased()) { - throw PRaiseNode.raiseUncached(null, ValueError, ErrorMessages.MEMORYVIEW_FORBIDDEN_RELEASED); - } GetElementPtrNode getElementNode = GetElementPtrNode.getUncached(); CStructAccess.WritePointerNode writePointerNode = CStructAccess.WritePointerNode.getUncached(); CStructAccess.WriteLongNode writeI64Node = CStructAccess.WriteLongNode.getUncached(); @@ -115,31 +109,33 @@ private static Object allocate(PMemoryView object) { Object view = getElementNode.getElementPtr(mem, CFields.PyMemoryViewObject__view); - Object buf = object.getBufferPointer(); - if (buf == null) { - buf = PythonBufferAccessLibrary.getUncached().getNativePointer(object.getBuffer()); + if (object.getBuffer() != null) { + Object buf = object.getBufferPointer(); if (buf == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw shouldNotReachHere("Cannot convert managed object to native storage: " + object.getBuffer().getClass().getSimpleName()); + buf = PythonBufferAccessLibrary.getUncached().getNativePointer(object.getBuffer()); + if (buf == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + throw shouldNotReachHere("Cannot convert managed object to native storage: " + object.getBuffer().getClass().getSimpleName()); + } } - } - if (object.getOffset() != 0) { - if (buf instanceof Long ptr) { - buf = ptr + object.getOffset(); - } else { - InteropLibrary ptrLib = InteropLibrary.getUncached(buf); - if (ptrLib.isPointer(buf)) { - try { - buf = ptrLib.asPointer(buf) + object.getOffset(); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } + if (object.getOffset() != 0) { + if (buf instanceof Long ptr) { + buf = ptr + object.getOffset(); } else { - buf = CExtNodes.PCallCapiFunction.callUncached(FUN_PTR_ADD, buf, (long) object.getOffset()); + InteropLibrary ptrLib = InteropLibrary.getUncached(buf); + if (ptrLib.isPointer(buf)) { + try { + buf = ptrLib.asPointer(buf) + object.getOffset(); + } catch (UnsupportedMessageException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } else { + buf = CExtNodes.PCallCapiFunction.callUncached(FUN_PTR_ADD, buf, (long) object.getOffset()); + } } } + writePointerNode.write(view, CFields.Py_buffer__buf, buf); } - writePointerNode.write(view, CFields.Py_buffer__buf, buf); if (object.getOwner() != null) { writePointerNode.write(view, CFields.Py_buffer__obj, PythonToNativeNewRefNode.executeUncached(object.getOwner())); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyMethodDefHelper.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyMethodDefHelper.java index 1efd919a9f..d42a701ea4 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyMethodDefHelper.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyMethodDefHelper.java @@ -102,7 +102,7 @@ private static Object getMethFromBuiltinFunction(CApiContext cApiContext, PBuilt PKeyword[] kwDefaults = object.getKwDefaults(); for (int i = 0; i < kwDefaults.length; i++) { if (ExternalFunctionNodes.KW_CALLABLE.equals(kwDefaults[i].getName())) { - LOGGER.warning("re-creating PyMethodDef for native function " + object); + // This can happen for slot wrapper methods of native slots return kwDefaults[i].getValue(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyProcsWrapper.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyProcsWrapper.java index 5686c9aebc..2793e15786 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyProcsWrapper.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyProcsWrapper.java @@ -40,10 +40,11 @@ */ package com.oracle.graal.python.builtins.objects.cext.capi; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.checkThrowableBeforeNative; +import static com.oracle.graal.python.util.PythonUtils.EMPTY_OBJECT_ARRAY; import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.cext.capi.PythonNativeWrapper.PythonStructNativeWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming; import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonNode; @@ -51,39 +52,45 @@ import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.TransformExceptionToNativeNode; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.ints.PInt; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotManaged; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.CallSlotBinaryFuncNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.CallSlotBinaryOpNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.CallSlotDescrGet; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrSet.CallSlotDescrSet; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.CallManagedSlotGetAttrNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.CallSlotHashFunNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotInquiry.CallSlotNbBoolNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.CallSlotLenNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotMpAssSubscript.CallSlotMpAssSubscriptNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotNbPower.CallSlotNbInPlacePowerNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotNbPower.CallSlotNbPowerNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.CallSlotRichCmpNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSetAttr.CallManagedSlotSetAttrNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.CallSlotSizeArgFun; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqAssItem.CallSlotSqAssItemNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.CallSlotSqContainsNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotUnaryFunc.CallSlotUnaryNode; -import com.oracle.graal.python.lib.PyObjectHashNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotVarargs.CallSlotTpCallNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotVarargs.CallSlotTpInitNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotVarargs.CallSlotTpNewNode; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode; import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode; import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode; -import com.oracle.graal.python.nodes.call.special.CallTernaryMethodNode; import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.util.CannotCastException; -import com.oracle.graal.python.nodes.util.CastUnsignedToJavaLongHashNode; import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; @@ -300,63 +307,63 @@ protected String getSignature() { @ExportLibrary(InteropLibrary.class) public static final class BinaryOpSlotFuncWrapper extends TpSlotWrapper { - private final BinaryOpSlot binaryOp; + private final ReversibleSlot binaryOp; - public BinaryOpSlotFuncWrapper(TpSlotManaged delegate, BinaryOpSlot binaryOp) { + public BinaryOpSlotFuncWrapper(TpSlotManaged delegate, ReversibleSlot binaryOp) { super(delegate); this.binaryOp = binaryOp; } public static BinaryOpSlotFuncWrapper createAdd(TpSlotManaged delegate) { - return new BinaryOpSlotFuncWrapper(delegate, BinaryOpSlot.NB_ADD); + return new BinaryOpSlotFuncWrapper(delegate, ReversibleSlot.NB_ADD); } public static BinaryOpSlotFuncWrapper createSubtract(TpSlotManaged delegate) { - return new BinaryOpSlotFuncWrapper(delegate, BinaryOpSlot.NB_SUBTRACT); + return new BinaryOpSlotFuncWrapper(delegate, ReversibleSlot.NB_SUBTRACT); } public static BinaryOpSlotFuncWrapper createMultiply(TpSlotManaged delegate) { - return new BinaryOpSlotFuncWrapper(delegate, BinaryOpSlot.NB_MULTIPLY); + return new BinaryOpSlotFuncWrapper(delegate, ReversibleSlot.NB_MULTIPLY); } public static BinaryOpSlotFuncWrapper createRemainder(TpSlotManaged delegate) { - return new BinaryOpSlotFuncWrapper(delegate, BinaryOpSlot.NB_REMAINDER); + return new BinaryOpSlotFuncWrapper(delegate, ReversibleSlot.NB_REMAINDER); } public static BinaryOpSlotFuncWrapper createLShift(TpSlotManaged delegate) { - return new BinaryOpSlotFuncWrapper(delegate, BinaryOpSlot.NB_LSHIFT); + return new BinaryOpSlotFuncWrapper(delegate, ReversibleSlot.NB_LSHIFT); } public static BinaryOpSlotFuncWrapper createRShift(TpSlotManaged delegate) { - return new BinaryOpSlotFuncWrapper(delegate, BinaryOpSlot.NB_RSHIFT); + return new BinaryOpSlotFuncWrapper(delegate, ReversibleSlot.NB_RSHIFT); } public static BinaryOpSlotFuncWrapper createAnd(TpSlotManaged delegate) { - return new BinaryOpSlotFuncWrapper(delegate, BinaryOpSlot.NB_AND); + return new BinaryOpSlotFuncWrapper(delegate, ReversibleSlot.NB_AND); } public static BinaryOpSlotFuncWrapper createXor(TpSlotManaged delegate) { - return new BinaryOpSlotFuncWrapper(delegate, BinaryOpSlot.NB_XOR); + return new BinaryOpSlotFuncWrapper(delegate, ReversibleSlot.NB_XOR); } public static BinaryOpSlotFuncWrapper createOr(TpSlotManaged delegate) { - return new BinaryOpSlotFuncWrapper(delegate, BinaryOpSlot.NB_OR); + return new BinaryOpSlotFuncWrapper(delegate, ReversibleSlot.NB_OR); } public static BinaryOpSlotFuncWrapper createFloorDivide(TpSlotManaged delegate) { - return new BinaryOpSlotFuncWrapper(delegate, BinaryOpSlot.NB_FLOOR_DIVIDE); + return new BinaryOpSlotFuncWrapper(delegate, ReversibleSlot.NB_FLOOR_DIVIDE); } public static BinaryOpSlotFuncWrapper createTrueDivide(TpSlotManaged delegate) { - return new BinaryOpSlotFuncWrapper(delegate, BinaryOpSlot.NB_TRUE_DIVIDE); + return new BinaryOpSlotFuncWrapper(delegate, ReversibleSlot.NB_TRUE_DIVIDE); } public static BinaryOpSlotFuncWrapper createDivMod(TpSlotManaged delegate) { - return new BinaryOpSlotFuncWrapper(delegate, BinaryOpSlot.NB_DIVMOD); + return new BinaryOpSlotFuncWrapper(delegate, ReversibleSlot.NB_DIVMOD); } public static BinaryOpSlotFuncWrapper createMatrixMultiply(TpSlotManaged delegate) { - return new BinaryOpSlotFuncWrapper(delegate, BinaryOpSlot.NB_MATRIX_MULTIPLY); + return new BinaryOpSlotFuncWrapper(delegate, ReversibleSlot.NB_MATRIX_MULTIPLY); } @ExportMessage @@ -500,6 +507,55 @@ protected String getSignature() { } } + @ExportLibrary(InteropLibrary.class) + public static final class IterNextWrapper extends TpSlotWrapper { + + public IterNextWrapper(TpSlotManaged delegate) { + super(delegate); + } + + @Override + public TpSlotWrapper cloneWith(TpSlotManaged slot) { + return new IterNextWrapper(slot); + } + + @ExportMessage + Object execute(Object[] arguments, + @Bind("$node") Node inliningTarget, + @Cached PythonToNativeNewRefNode toNativeNode, + @Cached CallSlotTpIterNextNode callNextNode, + @Cached NativeToPythonNode toJavaNode, + @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, + @Exclusive @Cached GilNode gil) throws ArityException { + boolean mustRelease = gil.acquire(); + CApiTiming.enter(); + try { + try { + Object result; + try { + result = callNextNode.execute(null, inliningTarget, getSlot(), toJavaNode.execute(arguments[0])); + } catch (IteratorExhausted e) { + return PythonContext.get(inliningTarget).getNativeNull(); + } + return toNativeNode.execute(result); + } catch (Throwable t) { + throw checkThrowableBeforeNative(t, "UnaryFuncWrapper", getDelegate()); + } + } catch (PException e) { + transformExceptionToNativeNode.execute(inliningTarget, e); + return PythonContext.get(gil).getNativeNull(); + } finally { + CApiTiming.exit(timing); + gil.release(mustRelease); + } + } + + @Override + protected String getSignature() { + return "(POINTER):POINTER"; + } + } + @ExportLibrary(InteropLibrary.class) public static final class InquiryWrapper extends TpSlotWrapper { public InquiryWrapper(TpSlotManaged delegate) { @@ -545,6 +601,47 @@ public TpSlotWrapper cloneWith(TpSlotManaged slot) { } } + @ExportLibrary(InteropLibrary.class) + public static final class SqContainsWrapper extends TpSlotWrapper { + public SqContainsWrapper(TpSlotManaged delegate) { + super(delegate); + } + + @ExportMessage + Object execute(Object[] arguments, + @Bind("$node") Node inliningTarget, + @Cached CallSlotSqContainsNode callSlotNode, + @Cached NativeToPythonNode toJavaNode, + @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, + @Exclusive @Cached GilNode gil) { + boolean mustRelease = gil.acquire(); + CApiTiming.enter(); + try { + try { + return callSlotNode.execute(null, inliningTarget, getSlot(), toJavaNode.execute(arguments[0]), toJavaNode.execute(arguments[1])); + } catch (Throwable t) { + throw checkThrowableBeforeNative(t, "SqContainsWrapper", getDelegate()); + } + } catch (PException e) { + transformExceptionToNativeNode.execute(inliningTarget, e); + return -1; + } finally { + CApiTiming.exit(timing); + gil.release(mustRelease); + } + } + + @Override + protected String getSignature() { + return "(POINTER,POINTER):SINT32"; + } + + @Override + public TpSlotWrapper cloneWith(TpSlotManaged slot) { + return new SqContainsWrapper(slot); + } + } + @ExportLibrary(InteropLibrary.class) public static final class ObjobjargWrapper extends TpSlotWrapper { @@ -687,113 +784,262 @@ public TpSlotWrapper cloneWith(TpSlotManaged slot) { } @ExportLibrary(InteropLibrary.class) - public static final class InitWrapper extends PyProcsWrapper { + public static final class InitWrapper extends TpSlotWrapper { - public InitWrapper(Object delegate) { + public InitWrapper(TpSlotManaged delegate) { super(delegate); } - @ExportMessage(name = "execute") - static class Execute { + @Override + public TpSlotWrapper cloneWith(TpSlotManaged slot) { + return new InitWrapper(slot); + } - @Specialization(guards = "arguments.length == 3") - static int init(InitWrapper self, Object[] arguments, - @Bind("this") Node inliningTarget, - @Cached ExecutePositionalStarargsNode posStarargsNode, - @Cached ExpandKeywordStarargsNode expandKwargsNode, - @Cached CallVarargsMethodNode callNode, - @Cached NativeToPythonNode toJavaNode, - @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, - @Exclusive @Cached GilNode gil) { - boolean mustRelease = gil.acquire(); - CApiTiming.enter(); + @ExportMessage + int execute(Object[] arguments, + @Bind("$node") Node inliningTarget, + @Cached ExecutePositionalStarargsNode posStarargsNode, + @Cached ExpandKeywordStarargsNode expandKwargsNode, + @Cached CallSlotTpInitNode callSlot, + @Cached NativeToPythonNode toJavaNode, + @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, + @Cached GilNode gil) { + boolean mustRelease = gil.acquire(); + CApiTiming.enter(); + try { try { - try { - // convert args - Object receiver = toJavaNode.execute(arguments[0]); - Object starArgs = toJavaNode.execute(arguments[1]); - Object kwArgs = toJavaNode.execute(arguments[2]); - - Object[] starArgsArray = posStarargsNode.executeWith(null, starArgs); - Object[] pArgs = PythonUtils.prependArgument(receiver, starArgsArray); - PKeyword[] kwArgsArray = expandKwargsNode.execute(inliningTarget, kwArgs); - callNode.execute(null, self.getDelegate(), pArgs, kwArgsArray); - return 0; - } catch (Throwable t) { - throw checkThrowableBeforeNative(t, "InitWrapper", self.getDelegate()); - } - } catch (PException e) { - transformExceptionToNativeNode.execute(inliningTarget, e); - return -1; - } finally { - CApiTiming.exit(self.timing); - gil.release(mustRelease); + // convert args + Object receiver = toJavaNode.execute(arguments[0]); + Object starArgs = toJavaNode.execute(arguments[1]); + Object kwArgs = toJavaNode.execute(arguments[2]); + + Object[] starArgsArray = posStarargsNode.executeWith(null, starArgs); + PKeyword[] kwArgsArray = expandKwargsNode.execute(inliningTarget, kwArgs); + callSlot.execute(null, inliningTarget, getSlot(), receiver, starArgsArray, kwArgsArray); + return 0; + } catch (Throwable t) { + throw checkThrowableBeforeNative(t, "InitWrapper", getDelegate()); } + } catch (PException e) { + transformExceptionToNativeNode.execute(inliningTarget, e); + return -1; + } finally { + CApiTiming.exit(timing); + gil.release(mustRelease); } + } - @Specialization(guards = "arguments.length != 3") - static int error(@SuppressWarnings("unused") InitWrapper self, Object[] arguments) throws ArityException { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw ArityException.create(3, 3, arguments.length); + @Override + protected String getSignature() { + return "(POINTER,POINTER,POINTER):SINT32"; + } + } + + @ExportLibrary(InteropLibrary.class) + public static final class NewWrapper extends TpSlotWrapper { + + public NewWrapper(TpSlotManaged delegate) { + super(delegate); + } + + @Override + public TpSlotWrapper cloneWith(TpSlotManaged slot) { + return new NewWrapper(slot); + } + + @ExportMessage + Object execute(Object[] arguments, + @Bind Node inliningTarget, + @Cached NativeToPythonNode toJavaNode, + @Cached PythonToNativeNewRefNode toNativeNode, + @Cached CallSlotTpNewNode callNew, + @Cached ExecutePositionalStarargsNode posStarargsNode, + @Cached ExpandKeywordStarargsNode expandKwargsNode, + @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, + @Cached GilNode gil) throws ArityException { + boolean mustRelease = gil.acquire(); + try { + try { + // convert args + Object receiver = toJavaNode.execute(arguments[0]); + Object starArgs = toJavaNode.execute(arguments[1]); + Object kwArgs = toJavaNode.execute(arguments[2]); + + Object[] pArgs; + if (starArgs != PNone.NO_VALUE) { + pArgs = posStarargsNode.executeWith(null, starArgs); + } else { + pArgs = EMPTY_OBJECT_ARRAY; + } + PKeyword[] kwArgsArray = expandKwargsNode.execute(inliningTarget, kwArgs); + + Object result = callNew.execute(null, inliningTarget, getSlot(), receiver, pArgs, kwArgsArray); + return toNativeNode.execute(result); + } catch (Throwable t) { + throw checkThrowableBeforeNative(t, "NewWrapper", getDelegate()); + } + } catch (PException e) { + transformExceptionToNativeNode.execute(inliningTarget, e); + return PythonContext.get(inliningTarget).getNativeNull(); + } finally { + gil.release(mustRelease); } } @Override protected String getSignature() { - return "(POINTER,POINTER,POINTER):SINT32"; + return "(POINTER,POINTER,POINTER):POINTER"; } } @ExportLibrary(InteropLibrary.class) - public static final class TernaryFunctionWrapper extends PyProcsWrapper { + public static final class CallWrapper extends TpSlotWrapper { - public TernaryFunctionWrapper(Object delegate) { + public CallWrapper(TpSlotManaged delegate) { super(delegate); } - @ExportMessage(name = "execute") - static class Execute { + @Override + public TpSlotWrapper cloneWith(TpSlotManaged slot) { + return new CallWrapper(slot); + } - @Specialization(guards = "arguments.length == 3") - static Object call(TernaryFunctionWrapper self, Object[] arguments, - @Bind("this") Node inliningTarget, - @Cached ExecutePositionalStarargsNode posStarargsNode, - @Cached ExpandKeywordStarargsNode expandKwargsNode, - @Cached CallVarargsMethodNode callNode, - @Cached NativeToPythonNode toJavaNode, - @Cached PythonToNativeNewRefNode toNativeNode, - @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, - @Exclusive @Cached GilNode gil) { - boolean mustRelease = gil.acquire(); - CApiTiming.enter(); + @ExportMessage + Object execute(Object[] arguments, + @Bind Node inliningTarget, + @Cached ExecutePositionalStarargsNode posStarargsNode, + @Cached ExpandKeywordStarargsNode expandKwargsNode, + @Cached CallSlotTpCallNode callNode, + @Cached NativeToPythonNode toJavaNode, + @Cached PythonToNativeNewRefNode toNativeNode, + @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, + @Cached GilNode gil) { + boolean mustRelease = gil.acquire(); + CApiTiming.enter(); + try { try { - try { - // convert args - Object receiver = toJavaNode.execute(arguments[0]); - Object starArgs = toJavaNode.execute(arguments[1]); - Object kwArgs = toJavaNode.execute(arguments[2]); + // convert args + Object receiver = toJavaNode.execute(arguments[0]); + Object starArgs = toJavaNode.execute(arguments[1]); + Object kwArgs = toJavaNode.execute(arguments[2]); - Object[] starArgsArray = posStarargsNode.executeWith(null, starArgs); - Object[] pArgs = PythonUtils.prependArgument(receiver, starArgsArray); - PKeyword[] kwArgsArray = expandKwargsNode.execute(inliningTarget, kwArgs); - Object result = callNode.execute(null, self.getDelegate(), pArgs, kwArgsArray); - return toNativeNode.execute(result); - } catch (Throwable t) { - throw checkThrowableBeforeNative(t, "TernaryFunctionWrapper", self.getDelegate()); - } - } catch (PException e) { - transformExceptionToNativeNode.execute(inliningTarget, e); - return PythonContext.get(gil).getNativeNull(); - } finally { - CApiTiming.exit(self.timing); - gil.release(mustRelease); + Object[] starArgsArray = posStarargsNode.executeWith(null, starArgs); + PKeyword[] kwArgsArray = expandKwargsNode.execute(inliningTarget, kwArgs); + Object result = callNode.execute(null, inliningTarget, getSlot(), receiver, starArgsArray, kwArgsArray); + return toNativeNode.execute(result); + } catch (Throwable t) { + throw checkThrowableBeforeNative(t, "CallWrapper", getDelegate()); } + } catch (PException e) { + transformExceptionToNativeNode.execute(inliningTarget, e); + return PythonContext.get(gil).getNativeNull(); + } finally { + CApiTiming.exit(timing); + gil.release(mustRelease); } + } - @Specialization(guards = "arguments.length != 3") - static Object error(@SuppressWarnings("unused") TernaryFunctionWrapper self, Object[] arguments) throws ArityException { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw ArityException.create(3, 3, arguments.length); + @Override + protected String getSignature() { + return "(POINTER,POINTER,POINTER):POINTER"; + } + } + + @ExportLibrary(InteropLibrary.class) + public static final class NbPowerWrapper extends TpSlotWrapper { + + public NbPowerWrapper(TpSlotManaged delegate) { + super(delegate); + } + + @Override + public TpSlotWrapper cloneWith(TpSlotManaged slot) { + return new NbPowerWrapper(slot); + } + + @ExportMessage + static Object execute(NbPowerWrapper self, Object[] arguments, + @Bind("$node") Node inliningTarget, + @Cached NativeToPythonNode toJavaNode, + @Cached PythonToNativeNewRefNode toNativeNode, + @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, + @Cached GetClassNode vGetClassNode, + @Cached GetClassNode wGetClassNode, + @Cached IsSameTypeNode isSameTypeNode, + @Cached GetCachedTpSlotsNode wGetSlots, + @Cached CallSlotNbPowerNode callSlot, + @Cached GilNode gil) { + boolean mustRelease = gil.acquire(); + CApiTiming.enter(); + try { + try { + // convert args + Object v = toJavaNode.execute(arguments[0]); + Object w = toJavaNode.execute(arguments[1]); + Object z = toJavaNode.execute(arguments[2]); + Object vType = vGetClassNode.execute(inliningTarget, v); + Object wType = wGetClassNode.execute(inliningTarget, w); + TpSlots wSlots = wGetSlots.execute(inliningTarget, wType); + boolean sameTypes = isSameTypeNode.execute(inliningTarget, vType, wType); + Object result = callSlot.execute(null, inliningTarget, self.getSlot(), v, vType, w, wSlots.nb_power(), wType, z, sameTypes); + return toNativeNode.execute(result); + } catch (Throwable t) { + throw checkThrowableBeforeNative(t, "NbPowerWrapper", self.getDelegate()); + } + } catch (PException e) { + transformExceptionToNativeNode.execute(inliningTarget, e); + return PythonContext.get(gil).getNativeNull(); + } finally { + CApiTiming.exit(self.timing); + gil.release(mustRelease); + } + } + + @Override + protected String getSignature() { + return "(POINTER,POINTER,POINTER):POINTER"; + } + } + + @ExportLibrary(InteropLibrary.class) + public static final class NbInPlacePowerWrapper extends TpSlotWrapper { + + public NbInPlacePowerWrapper(TpSlotManaged delegate) { + super(delegate); + } + + @Override + public TpSlotWrapper cloneWith(TpSlotManaged slot) { + return new NbInPlacePowerWrapper(slot); + } + + @ExportMessage + static Object execute(NbInPlacePowerWrapper self, Object[] arguments, + @Bind("$node") Node inliningTarget, + @Cached NativeToPythonNode toJavaNode, + @Cached PythonToNativeNewRefNode toNativeNode, + @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, + @Cached CallSlotNbInPlacePowerNode callSlot, + @Cached GilNode gil) { + boolean mustRelease = gil.acquire(); + CApiTiming.enter(); + try { + try { + // convert args + Object v = toJavaNode.execute(arguments[0]); + Object w = toJavaNode.execute(arguments[1]); + Object z = toJavaNode.execute(arguments[2]); + Object result = callSlot.execute(null, inliningTarget, self.getSlot(), v, w, z); + return toNativeNode.execute(result); + } catch (Throwable t) { + throw checkThrowableBeforeNative(t, "NbInPlacePowerWrapper", self.getDelegate()); + } + } catch (PException e) { + transformExceptionToNativeNode.execute(inliningTarget, e); + return PythonContext.get(gil).getNativeNull(); + } finally { + CApiTiming.exit(self.timing); + gil.release(mustRelease); } } @@ -804,19 +1050,25 @@ protected String getSignature() { } @ExportLibrary(InteropLibrary.class) - public static final class RichcmpFunctionWrapper extends PyProcsWrapper { + public static final class RichcmpFunctionWrapper extends TpSlotWrapper { - public RichcmpFunctionWrapper(Object delegate) { + public RichcmpFunctionWrapper(TpSlotManaged delegate) { super(delegate); } + @Override + public TpSlotWrapper cloneWith(TpSlotManaged slot) { + return new RichcmpFunctionWrapper(slot); + } + @ExportMessage Object execute(Object[] arguments, @Bind("$node") Node inliningTarget, @Cached NativeToPythonNode toJavaNode, - @Cached CallTernaryMethodNode callNode, + @Cached CallSlotRichCmpNode callNode, @Cached PythonToNativeNewRefNode toNativeNode, @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, + @CachedLibrary(limit = "1") InteropLibrary opInterop, @Exclusive @Cached GilNode gil) throws ArityException { boolean mustRelease = gil.acquire(); CApiTiming.enter(); @@ -829,9 +1081,8 @@ Object execute(Object[] arguments, // convert args Object arg0 = toJavaNode.execute(arguments[0]); Object arg1 = toJavaNode.execute(arguments[1]); - Object arg2 = arguments[2]; - - Object result = callNode.execute(null, getDelegate(), arg0, arg1, arg2); + RichCmpOp op = RichCmpOp.fromNative(opInterop.asInt(arguments[2])); + Object result = callNode.execute(null, inliningTarget, getSlot(), arg0, arg1, op); return toNativeNode.execute(result); } catch (Throwable t) { throw checkThrowableBeforeNative(t, "RichcmpFunctionWrapper", getDelegate()); @@ -968,7 +1219,7 @@ static int doL(Node inliningTarget, long l, return (int) l; } errorBranch.enter(inliningTarget); - throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.IndexError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, l); + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.IndexError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, l); } @Fallback @@ -1042,8 +1293,7 @@ long execute(Object[] arguments, @Cached CallSlotLenNode callSlotNode, @Cached NativeToPythonNode toJavaNode, @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, - @Cached PRaiseNode raiseNode, - @Exclusive @Cached GilNode gil) throws ArityException { + @Cached GilNode gil) throws ArityException { boolean mustRelease = gil.acquire(); CApiTiming.enter(); try { @@ -1077,21 +1327,19 @@ public TpSlotWrapper cloneWith(TpSlotManaged slot) { } @ExportLibrary(InteropLibrary.class) - public static final class HashfuncWrapper extends PyProcsWrapper { + public static final class HashfuncWrapper extends TpSlotWrapper { - public HashfuncWrapper(Object delegate) { + public HashfuncWrapper(TpSlotManaged delegate) { super(delegate); } @ExportMessage long execute(Object[] arguments, - @Bind("$node") Node inliningTarget, - @Cached CallUnaryMethodNode executeNode, - @Cached CastUnsignedToJavaLongHashNode cast, + @Bind Node inliningTarget, + @Cached CallSlotHashFunNode callSlotNode, @Cached NativeToPythonNode toJavaNode, @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, - @Exclusive @Cached GilNode gil, - @Cached PRaiseNode raiseNode) throws ArityException { + @Exclusive @Cached GilNode gil) throws ArityException { boolean mustRelease = gil.acquire(); CApiTiming.enter(); try { @@ -1104,10 +1352,7 @@ long execute(Object[] arguments, throw ArityException.create(1, 2, arguments.length); } try { - Object result = executeNode.executeObject(null, getDelegate(), toJavaNode.execute(arguments[0])); - return PyObjectHashNode.avoidNegative1(cast.execute(inliningTarget, result)); - } catch (CannotCastException e) { - throw raiseNode.raise(TypeError, ErrorMessages.HASH_SHOULD_RETURN_INTEGER); + return callSlotNode.execute(null, inliningTarget, getSlot(), toJavaNode.execute(arguments[0])); } catch (Throwable t) { throw checkThrowableBeforeNative(t, "HashfuncWrapper", getDelegate()); } @@ -1124,6 +1369,11 @@ long execute(Object[] arguments, protected String getSignature() { return "(POINTER):SINT64"; } + + @Override + public TpSlotWrapper cloneWith(TpSlotManaged slot) { + return new HashfuncWrapper(slot); + } } @ExportLibrary(InteropLibrary.class) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/SlotMethodDef.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/SlotMethodDef.java deleted file mode 100644 index 1ecf3c2994..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/SlotMethodDef.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.capi; - -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyAsyncMethods__am_aiter; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyAsyncMethods__am_anext; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyAsyncMethods__am_await; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyNumberMethods__nb_inplace_add; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyNumberMethods__nb_inplace_and; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyNumberMethods__nb_inplace_floor_divide; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyNumberMethods__nb_inplace_lshift; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyNumberMethods__nb_inplace_multiply; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyNumberMethods__nb_inplace_or; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyNumberMethods__nb_inplace_power; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyNumberMethods__nb_inplace_remainder; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyNumberMethods__nb_inplace_rshift; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyNumberMethods__nb_inplace_subtract; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyNumberMethods__nb_inplace_true_divide; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyNumberMethods__nb_inplace_xor; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyNumberMethods__nb_power; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_as_number; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_call; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_hash; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_init; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_iter; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_iternext; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_repr; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_richcompare; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_str; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ANEXT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AWAIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___CALL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IADD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IAND__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IFLOORDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ILSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IMOD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IOR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IPOW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IRSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ISUB__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ITRUEDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IXOR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEXT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___POW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___REPR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___STR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___TRUFFLE_RICHCOMPARE__; - -import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.BinaryFuncWrapper; -import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.HashfuncWrapper; -import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.InitWrapper; -import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.RichcmpFunctionWrapper; -import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.TernaryFunctionWrapper; -import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.UnaryFuncLegacyWrapper; -import com.oracle.graal.python.builtins.objects.cext.structs.CFields; -import com.oracle.graal.python.builtins.objects.type.MethodsFlags; -import com.oracle.graal.python.util.Function; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.strings.TruffleString; - -public enum SlotMethodDef { - TP_CALL(PyTypeObject__tp_call, T___CALL__, TernaryFunctionWrapper::new), - TP_HASH(PyTypeObject__tp_hash, T___HASH__, HashfuncWrapper::new), - TP_INIT(PyTypeObject__tp_init, T___INIT__, InitWrapper::new), - TP_ITER(PyTypeObject__tp_iter, T___ITER__, PyProcsWrapper.UnaryFuncLegacyWrapper::new), - TP_ITERNEXT(PyTypeObject__tp_iternext, T___NEXT__, UnaryFuncLegacyWrapper::new), - TP_REPR(PyTypeObject__tp_repr, T___REPR__, PyProcsWrapper.UnaryFuncLegacyWrapper::new), - TP_RICHCOMPARE(PyTypeObject__tp_richcompare, T___TRUFFLE_RICHCOMPARE__, RichcmpFunctionWrapper::new), - TP_STR(PyTypeObject__tp_str, T___STR__, UnaryFuncLegacyWrapper::new), - - AM_AWAIT(PyAsyncMethods__am_await, T___AWAIT__, UnaryFuncLegacyWrapper::new, MethodsFlags.AM_AWAIT), - AM_AITER(PyAsyncMethods__am_aiter, T___AITER__, UnaryFuncLegacyWrapper::new, MethodsFlags.AM_AITER), - AM_ANEXT(PyAsyncMethods__am_anext, T___ANEXT__, PyProcsWrapper.UnaryFuncLegacyWrapper::new, MethodsFlags.AM_ANEXT), - // (mq) AM_SEND is an internal function and mostly called from within AWAIT, AITER, ANEXT. - /*- AM_SEND(PyAsyncMethods__am_send, ASYNC_AM_SEND, TernaryFunctionWrapper::new, MethodsFlags.AM_SEND), */ - - NB_INPLACE_ADD(PyNumberMethods__nb_inplace_add, T___IADD__, BinaryFuncWrapper::new, MethodsFlags.NB_INPLACE_ADD), - NB_INPLACE_AND(PyNumberMethods__nb_inplace_and, T___IAND__, BinaryFuncWrapper::new, MethodsFlags.NB_INPLACE_AND), - NB_INPLACE_FLOOR_DIVIDE(PyNumberMethods__nb_inplace_floor_divide, T___IFLOORDIV__, BinaryFuncWrapper::new, MethodsFlags.NB_INPLACE_FLOOR_DIVIDE), - NB_INPLACE_LSHIFT(PyNumberMethods__nb_inplace_lshift, T___ILSHIFT__, BinaryFuncWrapper::new, MethodsFlags.NB_INPLACE_LSHIFT), - NB_INPLACE_MULTIPLY(PyNumberMethods__nb_inplace_multiply, T___IMUL__, BinaryFuncWrapper::new, MethodsFlags.NB_INPLACE_MULTIPLY), - NB_INPLACE_OR(PyNumberMethods__nb_inplace_or, T___IOR__, BinaryFuncWrapper::new, MethodsFlags.NB_INPLACE_OR), - NB_INPLACE_POWER(PyNumberMethods__nb_inplace_power, T___IPOW__, TernaryFunctionWrapper::new, MethodsFlags.NB_INPLACE_POWER), - NB_INPLACE_REMAINDER(PyNumberMethods__nb_inplace_remainder, T___IMOD__, BinaryFuncWrapper::new, MethodsFlags.NB_INPLACE_REMAINDER), - NB_INPLACE_RSHIFT(PyNumberMethods__nb_inplace_rshift, T___IRSHIFT__, BinaryFuncWrapper::new, MethodsFlags.NB_INPLACE_RSHIFT), - NB_INPLACE_SUBTRACT(PyNumberMethods__nb_inplace_subtract, T___ISUB__, BinaryFuncWrapper::new, MethodsFlags.NB_INPLACE_SUBTRACT), - NB_INPLACE_TRUE_DIVIDE(PyNumberMethods__nb_inplace_true_divide, T___ITRUEDIV__, BinaryFuncWrapper::new, MethodsFlags.NB_INPLACE_TRUE_DIVIDE), - NB_INPLACE_XOR(PyNumberMethods__nb_inplace_xor, T___IXOR__, BinaryFuncWrapper::new, MethodsFlags.NB_INPLACE_XOR), - NB_POWER(PyNumberMethods__nb_power, T___POW__, TernaryFunctionWrapper::new, MethodsFlags.NB_POWER); - - public final TruffleString methodName; - public final Function wrapperFactory; - public final long methodFlag; - - @CompilationFinal public CFields typeField; - @CompilationFinal public CFields methodsField; - - /** - * Different slot that is C-compatible and maps to the same Python method. - */ - @CompilationFinal public SlotMethodDef overlappingSlot; - - SlotMethodDef(CFields typeField, TruffleString methodName, Function wrapperFactory) { - this(typeField, null, methodName, wrapperFactory, 0); - } - - SlotMethodDef(CFields typeField, TruffleString methodName, Function wrapperFactory, long methodFlag) { - this(typeField, null, methodName, wrapperFactory, methodFlag); - } - - SlotMethodDef(CFields typeField, CFields methodsField, TruffleString methodName, Function wrapperFactory, long methodFlag) { - this.typeField = typeField; - this.methodsField = methodsField; - this.methodName = methodName; - this.wrapperFactory = wrapperFactory; - this.methodFlag = methodFlag; - } - - static { - initGroup( - PyTypeObject__tp_as_number, - NB_INPLACE_ADD, - NB_INPLACE_AND, - NB_INPLACE_FLOOR_DIVIDE, - NB_INPLACE_LSHIFT, - NB_INPLACE_MULTIPLY, - NB_INPLACE_OR, - NB_INPLACE_POWER, - NB_INPLACE_REMAINDER, - NB_INPLACE_RSHIFT, - NB_INPLACE_SUBTRACT, - NB_INPLACE_TRUE_DIVIDE, - NB_INPLACE_XOR, - NB_POWER); - } - - private static void initGroup(CFields typeField, SlotMethodDef... slots) { - for (SlotMethodDef slot : slots) { - assert slot.methodsField == null && slot.typeField != null; - slot.methodsField = slot.typeField; - slot.typeField = typeField; - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ToNativeTypeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ToNativeTypeNode.java index eeb0deee13..ffdcc5b876 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ToNativeTypeNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ToNativeTypeNode.java @@ -55,6 +55,7 @@ import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_vectorcall_offset; import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_weaklistoffset; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.modules.ctypes.StgDictObject; import com.oracle.graal.python.builtins.objects.PNone; @@ -73,11 +74,8 @@ import com.oracle.graal.python.builtins.objects.common.HashingStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageAddAllToOther; import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.method.PDecoratedMethod; -import com.oracle.graal.python.builtins.objects.type.MethodsFlags; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetTpSlotsNode; import com.oracle.graal.python.builtins.objects.type.TpSlots.TpSlotMeta; @@ -93,39 +91,22 @@ import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.GetTypeFlagsNodeGen; import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.SpecialAttributeNames; -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; -import com.oracle.graal.python.nodes.attributes.LookupNativeSlotNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassExactProfile; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.strings.TruffleString; public abstract class ToNativeTypeNode { - private static Object getSlot(PythonManagedClass obj, SlotMethodDef slot) { - return LookupNativeSlotNode.executeUncached(obj, slot); - } - - private static boolean hasAsyncMethods(PythonManagedClass obj) { - return (obj.getMethodsFlags() & MethodsFlags.ASYNC_METHODS) != 0; - } - - private static boolean hasSequenceMethods(PythonManagedClass obj) { - return (obj.getMethodsFlags() & MethodsFlags.SEQUENCE_METHODS) != 0; - } - - private static Object allocatePyAsyncMethods(PythonManagedClass obj, Object nullValue) { + private static Object allocatePyAsyncMethods(TpSlots slots, Object nullValue) { Object mem = CStructAccess.AllocateNode.allocUncached(CStructs.PyAsyncMethods); CStructAccess.WritePointerNode writePointerNode = CStructAccess.WritePointerNode.getUncached(); - writePointerNode.write(mem, CFields.PyAsyncMethods__am_await, getSlot(obj, SlotMethodDef.AM_AWAIT)); - writePointerNode.write(mem, CFields.PyAsyncMethods__am_aiter, getSlot(obj, SlotMethodDef.AM_AITER)); - writePointerNode.write(mem, CFields.PyAsyncMethods__am_anext, getSlot(obj, SlotMethodDef.AM_ANEXT)); - writePointerNode.write(mem, CFields.PyAsyncMethods__am_send, nullValue /*- getValue(obj, SlotMethodDef.AM_SEND) */); + writeGroupSlots(CFields.PyTypeObject__tp_as_async, slots, writePointerNode, mem, nullValue); return mem; } @@ -144,26 +125,10 @@ private static Object allocatePyMappingMethods(TpSlots slots, Object nullValue) return mem; } - private static Object allocatePyNumberMethods(PythonManagedClass obj, TpSlots slots, Object nullValue) { + private static Object allocatePyNumberMethods(TpSlots slots, Object nullValue) { Object mem = CStructAccess.AllocateNode.allocUncached(CStructs.PyNumberMethods); CStructAccess.WritePointerNode writePointerNode = CStructAccess.WritePointerNode.getUncached(); - writeGroupSlots(CFields.PyTypeObject__tp_as_number, slots, writePointerNode, mem, nullValue); - - writePointerNode.write(mem, CFields.PyNumberMethods__nb_inplace_add, getSlot(obj, SlotMethodDef.NB_INPLACE_ADD)); - writePointerNode.write(mem, CFields.PyNumberMethods__nb_inplace_and, getSlot(obj, SlotMethodDef.NB_INPLACE_AND)); - writePointerNode.write(mem, CFields.PyNumberMethods__nb_inplace_floor_divide, getSlot(obj, SlotMethodDef.NB_INPLACE_FLOOR_DIVIDE)); - writePointerNode.write(mem, CFields.PyNumberMethods__nb_inplace_lshift, getSlot(obj, SlotMethodDef.NB_INPLACE_LSHIFT)); - writePointerNode.write(mem, CFields.PyNumberMethods__nb_inplace_matrix_multiply, nullValue); - writePointerNode.write(mem, CFields.PyNumberMethods__nb_inplace_multiply, getSlot(obj, SlotMethodDef.NB_INPLACE_MULTIPLY)); - writePointerNode.write(mem, CFields.PyNumberMethods__nb_inplace_or, getSlot(obj, SlotMethodDef.NB_INPLACE_OR)); - writePointerNode.write(mem, CFields.PyNumberMethods__nb_inplace_power, getSlot(obj, SlotMethodDef.NB_INPLACE_POWER)); - writePointerNode.write(mem, CFields.PyNumberMethods__nb_inplace_remainder, getSlot(obj, SlotMethodDef.NB_INPLACE_REMAINDER)); - writePointerNode.write(mem, CFields.PyNumberMethods__nb_inplace_rshift, getSlot(obj, SlotMethodDef.NB_INPLACE_RSHIFT)); - writePointerNode.write(mem, CFields.PyNumberMethods__nb_inplace_subtract, getSlot(obj, SlotMethodDef.NB_INPLACE_SUBTRACT)); - writePointerNode.write(mem, CFields.PyNumberMethods__nb_inplace_true_divide, getSlot(obj, SlotMethodDef.NB_INPLACE_TRUE_DIVIDE)); - writePointerNode.write(mem, CFields.PyNumberMethods__nb_inplace_xor, getSlot(obj, SlotMethodDef.NB_INPLACE_XOR)); - writePointerNode.write(mem, CFields.PyNumberMethods__nb_power, getSlot(obj, SlotMethodDef.NB_POWER)); return mem; } @@ -186,10 +151,6 @@ private static long lookupSize(PythonManagedClass clazz, CFields member, HiddenA return lookupNativeI64MemberInMRO(clazz, member, hiddenName); } - private static Object lookup(PythonManagedClass obj, SlotMethodDef slot) { - return LookupNativeSlotNode.executeUncached(obj, slot); - } - static void initializeType(PythonClassNativeWrapper obj, Object mem, boolean heaptype) { CompilerAsserts.neverPartOfCompilation(); @@ -205,7 +166,7 @@ static void initializeType(PythonClassNativeWrapper obj, Object mem, boolean hea GetTypeFlagsNode getTypeFlagsNode = GetTypeFlagsNodeGen.getUncached(); PythonContext ctx = PythonContext.get(null); - PythonObjectFactory factory = ctx.factory(); + PythonLanguage language = ctx.getLanguage(); Object nullValue = ctx.getNativeNull(); // make this object immortal @@ -250,9 +211,9 @@ static void initializeType(PythonClassNativeWrapper obj, Object mem, boolean hea } else { weaklistoffset = lookupNativeI64MemberInMRO(clazz, PyTypeObject__tp_weaklistoffset, SpecialAttributeNames.T___WEAKLISTOFFSET__); } - Object asAsync = hasAsyncMethods(clazz) ? allocatePyAsyncMethods(clazz, nullValue) : nullValue; - Object asNumber = IsBuiltinClassExactProfile.profileClassSlowPath(clazz, PythonBuiltinClassType.PythonObject) ? nullValue : allocatePyNumberMethods(clazz, slots, nullValue); - Object asSequence = (slots.has_as_sequence() || hasSequenceMethods(clazz)) ? allocatePySequenceMethods(slots, nullValue) : nullValue; + Object asAsync = slots.has_as_async() ? allocatePyAsyncMethods(slots, nullValue) : nullValue; + Object asNumber = slots.has_as_number() ? allocatePyNumberMethods(slots, nullValue) : nullValue; + Object asSequence = slots.has_as_sequence() ? allocatePySequenceMethods(slots, nullValue) : nullValue; Object asMapping = slots.has_as_mapping() ? allocatePyMappingMethods(slots, nullValue) : nullValue; Object asBuffer = lookup(clazz, PyTypeObject__tp_as_buffer, HiddenAttr.AS_BUFFER); writeI64Node.write(mem, CFields.PyTypeObject__tp_weaklistoffset, weaklistoffset); @@ -260,13 +221,9 @@ static void initializeType(PythonClassNativeWrapper obj, Object mem, boolean hea writeI64Node.write(mem, CFields.PyTypeObject__tp_vectorcall_offset, lookupSize(clazz, PyTypeObject__tp_vectorcall_offset, HiddenAttr.VECTORCALL_OFFSET)); writePtrNode.write(mem, CFields.PyTypeObject__tp_getattr, nullValue); writePtrNode.write(mem, CFields.PyTypeObject__tp_as_async, asAsync); - writePtrNode.write(mem, CFields.PyTypeObject__tp_repr, lookup(clazz, SlotMethodDef.TP_REPR)); writePtrNode.write(mem, CFields.PyTypeObject__tp_as_number, asNumber); writePtrNode.write(mem, CFields.PyTypeObject__tp_as_sequence, asSequence); writePtrNode.write(mem, CFields.PyTypeObject__tp_as_mapping, asMapping); - writePtrNode.write(mem, CFields.PyTypeObject__tp_hash, lookup(clazz, SlotMethodDef.TP_HASH)); - writePtrNode.write(mem, CFields.PyTypeObject__tp_call, lookup(clazz, SlotMethodDef.TP_CALL)); - writePtrNode.write(mem, CFields.PyTypeObject__tp_str, lookup(clazz, SlotMethodDef.TP_STR)); writePtrNode.write(mem, CFields.PyTypeObject__tp_as_buffer, asBuffer); writeI64Node.write(mem, CFields.PyTypeObject__tp_flags, flags); @@ -289,9 +246,6 @@ static void initializeType(PythonClassNativeWrapper obj, Object mem, boolean hea writePtrNode.write(mem, CFields.PyTypeObject__tp_traverse, tpTraverse); writePtrNode.write(mem, CFields.PyTypeObject__tp_is_gc, tpIsGc); - writePtrNode.write(mem, CFields.PyTypeObject__tp_richcompare, lookup(clazz, SlotMethodDef.TP_RICHCOMPARE)); - writePtrNode.write(mem, CFields.PyTypeObject__tp_iter, lookup(clazz, SlotMethodDef.TP_ITER)); - writePtrNode.write(mem, CFields.PyTypeObject__tp_iternext, lookup(clazz, SlotMethodDef.TP_ITERNEXT)); writePtrNode.write(mem, CFields.PyTypeObject__tp_methods, nullValue); writePtrNode.write(mem, CFields.PyTypeObject__tp_members, nullValue); writePtrNode.write(mem, CFields.PyTypeObject__tp_getset, nullValue); @@ -320,23 +274,15 @@ static void initializeType(PythonClassNativeWrapper obj, Object mem, boolean hea // TODO properly implement 'tp_dictoffset' for builtin classes writeI64Node.write(mem, CFields.PyTypeObject__tp_dictoffset, GetDictOffsetNode.executeUncached(clazz)); - writePtrNode.write(mem, CFields.PyTypeObject__tp_init, lookup(clazz, SlotMethodDef.TP_INIT)); writePtrNode.write(mem, CFields.PyTypeObject__tp_alloc, lookup(clazz, PyTypeObject__tp_alloc, HiddenAttr.ALLOC)); - // T___new__ is magically a staticmethod for Python types. The tp_new slot lookup - // expects to get the function - Object newFunction = LookupCallableSlotInMRONode.getUncached(SpecialMethodSlot.New).execute(clazz); - if (newFunction instanceof PDecoratedMethod) { - newFunction = ((PDecoratedMethod) newFunction).getCallable(); - } - writePtrNode.write(mem, CFields.PyTypeObject__tp_new, ManagedMethodWrappers.createKeywords(newFunction)); writePtrNode.write(mem, CFields.PyTypeObject__tp_free, lookup(clazz, PyTypeObject__tp_free, HiddenAttr.FREE)); writePtrNode.write(mem, CFields.PyTypeObject__tp_clear, lookup(clazz, PyTypeObject__tp_clear, HiddenAttr.CLEAR)); if (clazz.basesTuple == null) { - clazz.basesTuple = factory.createTuple(GetBaseClassesNode.executeUncached(clazz)); + clazz.basesTuple = PFactory.createTuple(language, GetBaseClassesNode.executeUncached(clazz)); } writePtrNode.write(mem, CFields.PyTypeObject__tp_bases, toNative.execute(clazz.basesTuple)); if (clazz.mroStore == null) { - clazz.mroStore = factory.createTuple(GetMroStorageNode.executeUncached(clazz)); + clazz.mroStore = PFactory.createTuple(language, GetMroStorageNode.executeUncached(clazz)); } writePtrNode.write(mem, CFields.PyTypeObject__tp_mro, toNative.execute(clazz.mroStore)); writePtrNode.write(mem, CFields.PyTypeObject__tp_cache, nullValue); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/UnicodeObjectNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/UnicodeObjectNodes.java index b1437841b9..5e6d3be1bf 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/UnicodeObjectNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/UnicodeObjectNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,10 +42,11 @@ import java.nio.ByteOrder; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.builtins.objects.str.StringNodes.StringMaterializeNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; @@ -93,7 +94,7 @@ static PBytes doUnicode(TruffleString s, long elementSize, ByteOrder byteOrder) } else { throw new RuntimeException("unsupported wchar size; was: " + elementSize); } - return PythonObjectFactory.getUncached().createBytes(getBytes(s, encoding)); + return PFactory.createBytes(PythonLanguage.get(null), getBytes(s, encoding)); } private static byte[] getBytes(TruffleString s, TruffleString.Encoding encoding) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/ArgDescriptor.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/ArgDescriptor.java index f64ce20174..94eabd5b71 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/ArgDescriptor.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/ArgDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -145,6 +145,7 @@ public enum ArgDescriptor { PyMethodObject(ArgBehavior.PyObject, "PyMethodObject*"), PyInstanceMethodObject(ArgBehavior.PyObject, "PyInstanceMethodObject*"), PyObjectTransfer(ArgBehavior.PyObject, "PyObject*", true), + PyObjectRawPointer(ArgBehavior.Pointer, "PyObject*"), Pointer(ArgBehavior.Pointer, "void*"), Py_ssize_t(ArgBehavior.Int64, "Py_ssize_t"), Py_hash_t(ArgBehavior.Int64, "Py_hash_t"), @@ -278,7 +279,7 @@ public enum ArgDescriptor { PYPRECONFIG_PTR("PyPreConfig*"), PYSTATUS("PyStatus"), PYUNICODE_KIND("enum PyUnicode_Kind"), - PYWEAKREFERENCE_PTR("PyWeakReference*"), + PYWEAKREFERENCE_PTR(ArgBehavior.PyObject, "PyWeakReference*"), PYWIDESTRINGLIST_PTR("PyWideStringList*"), SIZE_T(ArgBehavior.Int64, "size_t"), SIZE_T_PTR("size_t*"), diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/CApiTransitions.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/CApiTransitions.java index 5e86231f34..dd291e4348 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/CApiTransitions.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/CApiTransitions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -104,7 +104,7 @@ import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage.StorageType; @@ -566,7 +566,7 @@ private static void processPyCapsuleReference(PyCapsuleReference reference) { LOGGER.fine(() -> PythonUtils.formatJString("releasing %s", reference.toString())); if (reference.data.getDestructor() != null) { // Our capsule is dead, so create a temporary copy that doesn't have a reference anymore - PyCapsule capsule = PythonObjectFactory.getUncached().createCapsule(reference.data); + PyCapsule capsule = PFactory.createCapsule(PythonLanguage.get(null), reference.data); PCallCapiFunction.callUncached(NativeCAPISymbol.FUN_PY_TRUFFLE_CAPSULE_CALL_DESTRUCTOR, PythonToNativeNode.executeUncached(capsule), capsule.getDestructor()); } } @@ -1065,7 +1065,7 @@ static long doGeneric(Node inliningTarget, PythonAbstractObjectNativeWrapper wra * Python-level MemoryError. */ CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.MemoryError); + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.MemoryError); } finally { gil.release(acquired); } @@ -1895,7 +1895,7 @@ static PythonNativeWrapper doGeneric(Node inliningTarget, long pointer, boolean IdReference lookup = nativeLookupGet(nativeContext, pointer); if (isNativeProfile.profile(inliningTarget, lookup != null)) { Object ref = lookup.get(); - if (ref == null) { + if (strict && ref == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); throw CompilerDirectives.shouldNotReachHere("reference was collected: " + Long.toHexString(pointer)); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/GetNativeWrapperNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/GetNativeWrapperNode.java index 5e40dfd0f5..444b1fdfd0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/GetNativeWrapperNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/GetNativeWrapperNode.java @@ -40,6 +40,7 @@ */ package com.oracle.graal.python.builtins.objects.cext.capi.transitions; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; @@ -61,7 +62,7 @@ import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.object.IsForeignObjectNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -88,9 +89,9 @@ public static PythonNativeWrapper executeUncached(Object value) { @Specialization static PythonAbstractObjectNativeWrapper doString(TruffleString str, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Exclusive @Cached InlinedConditionProfile noWrapperProfile) { - return PythonObjectNativeWrapper.wrap(factory.createString(str), inliningTarget, noWrapperProfile); + return PythonObjectNativeWrapper.wrap(PFactory.createString(language, str), inliningTarget, noWrapperProfile); } @Specialization @@ -174,9 +175,9 @@ static PythonNativeWrapper doSingleton(PythonAbstractObject object, @Specialization static PythonNativeWrapper doPythonClassUncached(PythonManagedClass object, @Bind("this") Node inliningTarget, - @Cached TypeNodes.GetNameNode getNameNode, + @Cached TypeNodes.GetTpNameNode getTpNameNode, @Shared @Cached TruffleString.SwitchEncodingNode switchEncoding) { - return PythonClassNativeWrapper.wrap(object, getNameNode.execute(inliningTarget, object), switchEncoding); + return PythonClassNativeWrapper.wrap(object, getTpNameNode.execute(inliningTarget, object), switchEncoding); } @Specialization diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtCommonNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtCommonNodes.java index 738bcc3494..0d6de96176 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtCommonNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtCommonNodes.java @@ -105,7 +105,7 @@ import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; import com.oracle.graal.python.runtime.exception.PythonExitException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.OverflowException; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CallTarget; @@ -202,18 +202,18 @@ static byte[] doGeneric(Charset charset, Object unicodeObject, TruffleString err @Bind("this") Node inliningTarget, @Cached CastToTruffleStringNode castToTruffleStringNode, @Cached TruffleString.EqualNode eqNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TruffleString str; try { str = castToTruffleStringNode.execute(inliningTarget, unicodeObject); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_MUST_BE_S_NOT_P, "argument", "a string", unicodeObject); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_MUST_BE_S_NOT_P, "argument", "a string", unicodeObject); } try { CodingErrorAction action = BytesCommonBuiltins.toCodingErrorAction(inliningTarget, errors, raiseNode, eqNode); return BytesCommonBuiltins.doEncode(charset, str, action); } catch (CharacterCodingException e) { - throw raiseNode.get(inliningTarget).raise(UnicodeEncodeError, ErrorMessages.M, e); + throw raiseNode.raise(inliningTarget, UnicodeEncodeError, ErrorMessages.M, e); } } } @@ -538,7 +538,7 @@ public abstract static class TransformExceptionFromNativeNode extends Node { /** * Checks the current exception state with respect to flag {@code indicatesError} (and * {@code strict}). - * + * * * @param inliningTarget The processing node (also needed for the source location if a * {@code SystemError} is raised). @@ -605,14 +605,15 @@ private static void checkFunctionResultSlowpath(Node inliningTarget, PythonThrea @TruffleBoundary private static PException raiseNullButNoError(Node node, TruffleString name, TruffleString nullButNoErrorMessage) { - throw PRaiseNode.raiseUncached(node, SystemError, nullButNoErrorMessage, name); + throw PRaiseNode.raiseStatic(node, SystemError, nullButNoErrorMessage, name); } @TruffleBoundary private static PException raiseResultWithError(Node node, TruffleString name, AbstractTruffleException currentException, TruffleString resultWithErrorMessage) { - PBaseException sysExc = PythonObjectFactory.getUncached().createBaseException(SystemError, resultWithErrorMessage, new Object[]{name}); + PythonLanguage language = PythonLanguage.get(null); + PBaseException sysExc = PFactory.createBaseException(language, SystemError, resultWithErrorMessage, new Object[]{name}); sysExc.setCause(GetEscapedExceptionNode.executeUncached(currentException)); - throw PRaiseNode.raiseExceptionObject(node, sysExc, PythonOptions.isPExceptionWithJavaStacktrace(PythonLanguage.get(null))); + throw PRaiseNode.raiseExceptionObject(node, sysExc, PythonOptions.isPExceptionWithJavaStacktrace(language)); } } @@ -696,9 +697,10 @@ static int doIntToUInt32Pos(int value, int signed, int targetTypeSize, boolean e @Specialization(guards = {"targetTypeSize == 4", "signed == 0"}, replaces = "doIntToUInt32Pos") @SuppressWarnings("unused") static int doIntToUInt32(int value, int signed, int targetTypeSize, boolean exact, + @Bind("this") Node inliningTarget, @Shared("raiseNativeNode") @Cached PRaiseNode raiseNativeNode) { if (exact && value < 0) { - throw raiseNegativeValue(raiseNativeNode); + throw raiseNegativeValue(inliningTarget, raiseNativeNode); } return value; } @@ -718,9 +720,10 @@ static long doIntToUInt64Pos(int value, int signed, int targetTypeSize, boolean @Specialization(guards = {"targetTypeSize == 8", "signed == 0"}, replaces = "doIntToUInt64Pos") @SuppressWarnings("unused") static long doIntToUInt64(int value, int signed, int targetTypeSize, boolean exact, + @Bind("this") Node inliningTarget, @Shared("raiseNativeNode") @Cached PRaiseNode raiseNativeNode) { if (exact && value < 0) { - throw raiseNegativeValue(raiseNativeNode); + throw raiseNegativeValue(inliningTarget, raiseNativeNode); } return value; } @@ -740,9 +743,10 @@ static long doLongToUInt64Pos(long value, int signed, int targetTypeSize, boolea @Specialization(guards = {"targetTypeSize == 8", "signed == 0"}, replaces = "doLongToUInt64Pos") @SuppressWarnings("unused") static long doLongToUInt64(long value, int signed, int targetTypeSize, boolean exact, + @Bind("this") Node inliningTarget, @Shared("raiseNativeNode") @Cached PRaiseNode raiseNativeNode) { if (exact && value < 0) { - throw raiseNegativeValue(raiseNativeNode); + throw raiseNegativeValue(inliningTarget, raiseNativeNode); } return value; } @@ -750,33 +754,36 @@ static long doLongToUInt64(long value, int signed, int targetTypeSize, boolean e @Specialization(guards = {"exact", "targetTypeSize == 4", "signed != 0"}) @SuppressWarnings("unused") static int doLongToInt32Exact(long obj, int signed, int targetTypeSize, boolean exact, + @Bind("this") Node inliningTarget, @Shared("raiseNode") @Cached PRaiseNode raiseNode) { try { return PInt.intValueExact(obj); } catch (OverflowException e) { - throw raiseNode.raise(PythonErrorType.OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO_C_TYPE, targetTypeSize); + throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO_C_TYPE, targetTypeSize); } } @Specialization(guards = {"exact", "targetTypeSize == 4", "signed == 0", "obj >= 0"}) @SuppressWarnings("unused") static int doLongToUInt32PosExact(long obj, int signed, int targetTypeSize, boolean exact, + @Bind("this") Node inliningTarget, @Shared("raiseNode") @Cached PRaiseNode raiseNode) { if (Integer.toUnsignedLong((int) obj) == obj) { return (int) obj; } else { - throw raiseNode.raise(PythonErrorType.OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO_C_TYPE, targetTypeSize); + throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO_C_TYPE, targetTypeSize); } } @Specialization(guards = {"exact", "targetTypeSize == 4", "signed == 0"}, replaces = "doLongToUInt32PosExact") @SuppressWarnings("unused") static int doLongToUInt32Exact(long obj, int signed, int targetTypeSize, boolean exact, + @Bind("this") Node inliningTarget, @Shared("raiseNode") @Cached PRaiseNode raiseNode) { if (obj < 0) { - throw raiseNegativeValue(raiseNode); + throw raiseNegativeValue(inliningTarget, raiseNode); } - return doLongToUInt32PosExact(obj, signed, targetTypeSize, exact, raiseNode); + return doLongToUInt32PosExact(obj, signed, targetTypeSize, exact, inliningTarget, raiseNode); } @Specialization(guards = {"!exact", "targetTypeSize == 4"}) @@ -795,40 +802,42 @@ static Object doVoidPtrToI64(PythonNativeVoidPtr obj, int signed, int targetType @SuppressWarnings("unused") @TruffleBoundary static int doPIntTo32Bit(PInt obj, int signed, int targetTypeSize, boolean exact, + @Bind("this") Node inliningTarget, @Shared("raiseNode") @Cached PRaiseNode raiseNode) { try { if (signed != 0) { return obj.intValueExact(); } else if (obj.bitLength() <= 32) { if (obj.isNegative()) { - throw raiseNegativeValue(raiseNode); + throw raiseNegativeValue(inliningTarget, raiseNode); } return obj.intValue(); } } catch (OverflowException e) { // fall through } - throw raiseNode.raise(PythonErrorType.OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO_C_TYPE, targetTypeSize); + throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO_C_TYPE, targetTypeSize); } @Specialization(guards = {"exact", "targetTypeSize == 8"}) @SuppressWarnings("unused") @TruffleBoundary static long doPIntTo64Bit(PInt obj, int signed, int targetTypeSize, boolean exact, + @Bind("this") Node inliningTarget, @Shared("raiseNode") @Cached PRaiseNode raiseNode) { try { if (signed != 0) { return obj.longValueExact(); } else if (obj.bitLength() <= 64) { if (obj.isNegative()) { - throw raiseNegativeValue(raiseNode); + throw raiseNegativeValue(inliningTarget, raiseNode); } return obj.longValue(); } } catch (OverflowException e) { // fall through } - throw raiseNode.raise(PythonErrorType.OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO_C_TYPE, targetTypeSize); + throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO_C_TYPE, targetTypeSize); } @Specialization(guards = {"!exact", "targetTypeSize == 4"}) @@ -863,84 +872,84 @@ static Object doGeneric(Object obj, int signed, int targetTypeSize, boolean exac * 'signed', 'targetTypeSize', and 'exact' are usually constants. */ if (targetTypeSize == 4) { - return toInt32(result, signed, exact, raiseNode); + return toInt32(inliningTarget, result, signed, exact, raiseNode); } else if (targetTypeSize == 8) { - return toInt64(result, signed, exact, raiseNode); + return toInt64(inliningTarget, result, signed, exact, raiseNode); } - throw raiseNode.raise(SystemError, ErrorMessages.UNSUPPORTED_TARGET_SIZE, targetTypeSize); + throw raiseNode.raise(inliningTarget, SystemError, ErrorMessages.UNSUPPORTED_TARGET_SIZE, targetTypeSize); } @Specialization(guards = {"targetTypeSize != 4", "targetTypeSize != 8"}) @SuppressWarnings("unused") static int doUnsupportedTargetSize(Object obj, int signed, int targetTypeSize, boolean exact, - @Shared("raiseNode") @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, ErrorMessages.UNSUPPORTED_TARGET_SIZE, targetTypeSize); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, ErrorMessages.UNSUPPORTED_TARGET_SIZE, targetTypeSize); } - private static PException raiseNegativeValue(PRaiseNode raiseNativeNode) { - throw raiseNativeNode.raise(OverflowError, ErrorMessages.CANNOT_CONVERT_NEGATIVE_VALUE_TO_UNSIGNED_INT); + private static PException raiseNegativeValue(Node inliningTarget, PRaiseNode raiseNativeNode) { + throw raiseNativeNode.raise(inliningTarget, OverflowError, ErrorMessages.CANNOT_CONVERT_NEGATIVE_VALUE_TO_UNSIGNED_INT); } /** * Slow-path conversion of an object to a signed or unsigned 32-bit value. */ - private static int toInt32(Object object, int signed, boolean exact, + private static int toInt32(Node inliningTarget, Object object, int signed, boolean exact, PRaiseNode raiseNode) { if (object instanceof Integer) { int ival = (int) object; if (signed != 0) { return ival; } - return doIntToUInt32(ival, signed, 4, exact, raiseNode); + return doIntToUInt32(ival, signed, 4, exact, inliningTarget, raiseNode); } else if (object instanceof Long) { long lval = (long) object; if (exact) { if (signed != 0) { - return doLongToInt32Exact(lval, 1, 4, true, raiseNode); + return doLongToInt32Exact(lval, 1, 4, true, inliningTarget, raiseNode); } - return doLongToUInt32Exact(lval, signed, 4, true, raiseNode); + return doLongToUInt32Exact(lval, signed, 4, true, inliningTarget, raiseNode); } return doLongToInt32Lossy(lval, 0, 4, false); } else if (object instanceof PInt) { PInt pval = (PInt) object; if (exact) { - return doPIntTo32Bit(pval, signed, 4, true, raiseNode); + return doPIntTo32Bit(pval, signed, 4, true, inliningTarget, raiseNode); } return doPIntToInt32Lossy(pval, signed, 4, false); } else if (object instanceof PythonNativeVoidPtr) { // that's just not possible - throw raiseNode.raise(PythonErrorType.OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO_C_TYPE, 4); + throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO_C_TYPE, 4); } - throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.INDEX_RETURNED_NON_INT, object); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.INDEX_RETURNED_NON_INT, object); } /** * Slow-path conversion of an object to a signed or unsigned 64-bit value. */ - private static Object toInt64(Object object, int signed, boolean exact, + private static Object toInt64(Node inliningTarget, Object object, int signed, boolean exact, PRaiseNode raiseNode) { if (object instanceof Integer) { Integer ival = (Integer) object; if (signed != 0) { return ival.longValue(); } - return doIntToUInt64(ival, signed, 8, exact, raiseNode); + return doIntToUInt64(ival, signed, 8, exact, inliningTarget, raiseNode); } else if (object instanceof Long) { long lval = (long) object; if (signed != 0) { return doLongToInt64(lval, 1, 8, exact); } - return doLongToUInt64(lval, signed, 8, exact, raiseNode); + return doLongToUInt64(lval, signed, 8, exact, inliningTarget, raiseNode); } else if (object instanceof PInt) { PInt pval = (PInt) object; if (exact) { - return doPIntTo64Bit(pval, signed, 8, true, raiseNode); + return doPIntTo64Bit(pval, signed, 8, true, inliningTarget, raiseNode); } return doPIntToInt64Lossy(pval, signed, 8, false); } else if (object instanceof PythonNativeVoidPtr) { return doVoidPtrToI64((PythonNativeVoidPtr) object, signed, 8, exact); } - throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.INDEX_RETURNED_NON_INT, object); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.INDEX_RETURNED_NON_INT, object); } } @@ -948,7 +957,6 @@ private static Object toInt64(Object object, int signed, boolean exact, * This node converts a {@link String} object to a {@link TruffleString} or it converts a * {@code NULL} pointer to {@link PNone#NONE}. This is a very special use case and certainly * only good for reading a member of type - * {@link com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef#HPY_MEMBER_STRING} or * {@link com.oracle.graal.python.builtins.objects.cext.capi.CApiMemberAccessNodes#T_STRING}. */ @GenerateInline(false) // footprint reduction 32 -> 13, inherits non-inlineable execute() @@ -1125,29 +1133,8 @@ static long doUnsignedLongPositive(long n) { @Specialization(guards = "n < 0") static Object doUnsignedLongNegative(long n, - @Shared("factory") @Cached PythonObjectFactory factory) { - return factory.createInt(PInt.longToUnsignedBigInteger(n)); - } - - @Specialization(replaces = {"doUnsignedIntPositive", "doUnsignedInt", "doUnsignedLongPositive", "doUnsignedLongNegative"}) - static Object doGeneric(Object n, - @Shared("factory") @Cached PythonObjectFactory factory) { - if (n instanceof Integer) { - int i = (int) n; - if (i >= 0) { - return i; - } else { - return doUnsignedInt(i); - } - } else if (n instanceof Long) { - long l = (long) n; - if (l >= 0) { - return l; - } else { - return doUnsignedLongNegative(l, factory); - } - } - throw CompilerDirectives.shouldNotReachHere(); + @Bind PythonLanguage language) { + return PFactory.createInt(language, PInt.longToUnsignedBigInteger(n)); } } @@ -1166,10 +1153,10 @@ public abstract static class AsNativeCharNode extends CExtToNativeNode { static byte doGeneric(Object value, @Bind("this") Node inliningTarget, @Cached EncodeNativeStringNode encodeNativeStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { byte[] encoded = encodeNativeStringNode.execute(StandardCharsets.UTF_8, value, T_STRICT); if (encoded.length != 1) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); } return encoded[0]; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtContext.java index 84a7b7b4fa..89e9122fd8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtContext.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,14 +41,12 @@ package com.oracle.graal.python.builtins.objects.cext.common; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; -import static com.oracle.graal.python.nodes.StringLiterals.J_LLVM_LANGUAGE; import static com.oracle.graal.python.nodes.StringLiterals.T_DOT; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; -import java.io.IOException; - +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ImportException; import com.oracle.graal.python.builtins.objects.exception.ExceptionNodes; import com.oracle.graal.python.builtins.objects.exception.PBaseException; @@ -58,14 +56,10 @@ import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.ExceptionUtils; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.TruffleFile; -import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.strings.TruffleString; public abstract class CExtContext { @@ -83,26 +77,20 @@ public abstract class CExtContext { private final PythonContext context; - /** The LLVM bitcode library object representing 'libpython.*.so' or similar. */ - private final Object llvmLibrary; - - /** - * The native API implementation was loaded as native code (as opposed to bitcode via Sulong). - */ - protected final boolean useNativeBackend; + /** The library object representing 'libpython.*.so' or similar. */ + private final Object library; - public CExtContext(PythonContext context, Object llvmLibrary, boolean useNativeBackend) { + public CExtContext(PythonContext context, Object library) { this.context = context; - this.llvmLibrary = llvmLibrary; - this.useNativeBackend = useNativeBackend; + this.library = library; } public final PythonContext getContext() { return context; } - public final Object getLLVMLibrary() { - return llvmLibrary; + public final Object getLibrary() { + return library; } public static boolean isMethVarargs(int flags) { @@ -157,20 +145,6 @@ protected static TruffleString getBaseName(TruffleString name) { return name.substringUncached(idx + 1, len - idx - 1, TS_ENCODING, true); } - public static Object loadLLVMLibrary(Node location, PythonContext context, TruffleString name, TruffleString path) throws ImportException, IOException { - Env env = context.getEnv(); - try { - TruffleString extSuffix = context.getSoAbi(); - TruffleFile realPath = context.getPublicTruffleFileRelaxed(path, extSuffix).getCanonicalFile(); - CallTarget callTarget = env.parseInternal(Source.newBuilder(J_LLVM_LANGUAGE, realPath).build()); - return callTarget.call(); - } catch (SecurityException e) { - throw new ImportException(CExtContext.wrapJavaException(e, location), name, path, ErrorMessages.CANNOT_LOAD_M, path, e); - } catch (RuntimeException e) { - throw reportImportError(e, name, path); - } - } - @TruffleBoundary protected static PException reportImportError(RuntimeException e, TruffleString name, TruffleString path) throws ImportException { StringBuilder sb = new StringBuilder(); @@ -211,7 +185,7 @@ protected static PException reportImportError(RuntimeException e, TruffleString @TruffleBoundary public static PException wrapJavaException(Throwable e, Node raisingNode) { TruffleString message = toTruffleStringUncached(e.getMessage()); - PBaseException excObject = PythonObjectFactory.getUncached().createBaseException(SystemError, message != null ? message : toTruffleStringUncached(e.toString()), + PBaseException excObject = PFactory.createBaseException(PythonLanguage.get(null), SystemError, message != null ? message : toTruffleStringUncached(e.toString()), PythonUtils.EMPTY_OBJECT_ARRAY); return ExceptionUtils.wrapJavaException(e, raisingNode, excObject); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/ElfFile.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/ElfFile.java index 760c5e84ef..ee6c5c0e65 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/ElfFile.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/ElfFile.java @@ -46,32 +46,14 @@ import java.nio.file.StandardOpenOption; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.truffle.api.TruffleFile; -import com.oracle.truffle.api.TruffleLanguage.Env; final class ElfFile extends SharedObject { private final PythonContext context; private final TruffleFile tempfile; private String getPatchelf() { - Env env = context.getEnv(); - var path = env.getEnvironment().getOrDefault("PATH", "").split(env.getPathSeparator()); - var executable = env.getPublicTruffleFile(context.getOption(PythonOptions.Executable).toJavaStringUncached()); - var patchelf = executable.resolveSibling("patchelf"); - var i = 0; - while (!isExecutable(patchelf) && i < path.length) { - patchelf = env.getPublicTruffleFile(path[i++]).resolve("patchelf"); - } - return patchelf.toString(); - } - - private static boolean isExecutable(TruffleFile patchelf) { - try { - return patchelf.isExecutable(); - } catch (SecurityException e) { - return false; - } + return which(context, "patchelf").toString(); } ElfFile(byte[] b, PythonContext context) throws IOException { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/NativeLibraryLocator.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/NativeLibraryLocator.java index f3a111ac63..4366027daf 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/NativeLibraryLocator.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/NativeLibraryLocator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -131,7 +131,8 @@ public String resolve(PythonContext context, TruffleFile original) throws Import try { return resolve(context, original, capiSlot, capiOriginal); } catch (ApiInitException e) { - throw new ImportException(null, toTruffleStringUncached(original.getName()), toTruffleStringUncached(original.getPath()), toTruffleStringUncached(e.getMessage())); + throw new ImportException(null, toTruffleStringUncached(original.getName()), toTruffleStringUncached(original.getPath()), + toTruffleStringUncached(e.getMessage() == null ? "" : e.getMessage())); } } @@ -189,11 +190,31 @@ private static String resolve(PythonContext context, TruffleFile original, int c String newName = copyNameOf(original.getName(), capiSlot); if (original.getAbsoluteFile().startsWith(context.getCoreHome().toJavaStringUncached())) { - // must be relocated to venv + // must be relocated to venv or tmpdir Object sysPrefix = context.getSysModule().getAttribute(T_PREFIX); Object sysBasePrefix = context.getSysModule().getAttribute(T_BASE_PREFIX); if (sysPrefix.equals(sysBasePrefix)) { - throw new ApiInitException(ErrorMessages.SYS_PREFIX_MUST_POINT_TO_A_VENV_FOR_CAPI_ISOLATION); + TruffleFile tempDir; + try { + tempDir = context.getEnv().createTempDirectory(null, null); + } catch (IOException e) { + throw new ApiInitException(ErrorMessages.SYS_PREFIX_MUST_POINT_TO_A_VENV_FOR_CAPI_ISOLATION); + } + context.registerAtexitHook((ctx) -> { + try { + tempDir.delete(); + } catch (IOException e) { + // Nothing we can do at this point + } + }); + copy = tempDir.resolve(newName); + context.registerAtexitHook((ctx) -> { + try { + copy.delete(); + } catch (IOException e) { + // Nothing we can do at this point + } + }); } else { try { var tsSysPrefix = CastToTruffleStringNode.executeUncached(sysPrefix); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/PEFile.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/PEFile.java index c9e3df7010..63cbd39ea3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/PEFile.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/PEFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,7 +46,6 @@ import java.nio.file.StandardOpenOption; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.truffle.api.TruffleFile; final class PEFile extends SharedObject { @@ -66,12 +65,40 @@ public void setId(String newId) throws IOException { // TODO } + private String getDelvewheelPython() { + TruffleFile delvewheel = which(context, "delvewheel.exe"); + if (!delvewheel.exists()) { + delvewheel = which(context, "delvewheel.bat"); + } + if (!delvewheel.exists()) { + delvewheel = which(context, "delvewheel.cmd"); + } + TruffleFile python = delvewheel.resolveSibling("python.exe"); + if (!python.exists()) { + python = delvewheel.resolveSibling("python.bat"); + } + if (!python.exists()) { + python = delvewheel.resolveSibling("python.cmd"); + } + if (!python.exists()) { + python = delvewheel.getParent().resolveSibling("python.exe"); + } + if (!python.exists()) { + python = delvewheel.getParent().resolveSibling("python.bat"); + } + if (!python.exists()) { + python = delvewheel.getParent().resolveSibling("python.cmd"); + } + return python.toString(); + } + @Override public void changeOrAddDependency(String oldName, String newName) throws IOException, InterruptedException { var pb = newProcessBuilder(context); var tempfileWithForwardSlashes = tempfile.toString().replace('\\', '/'); - pb.command(context.getOption(PythonOptions.Executable).toJavaStringUncached(), - "-c", String.format("from delvewheel import _dll_utils; _dll_utils.replace_needed('%s', ['%s'], {'%s': '%s'}, strip=True, verbose=2, test=[])", + String pythonExe = getDelvewheelPython(); + pb.command(pythonExe, "-c", + String.format("from delvewheel import _dll_utils; _dll_utils.replace_needed('%s', ['%s'], {'%s': '%s'}, strip=True, verbose=2, test=[])", tempfileWithForwardSlashes, oldName, oldName, newName)); var proc = pb.start(); if (proc.waitFor() != 0) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/SharedObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/SharedObject.java index 966fc7dfe1..4b6843adb9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/SharedObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/copying/SharedObject.java @@ -44,7 +44,9 @@ import java.io.OutputStream; import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.truffle.api.TruffleFile; +import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.TruffleLogger; import com.oracle.truffle.api.io.TruffleProcessBuilder; @@ -99,4 +101,24 @@ protected static TruffleProcessBuilder newProcessBuilder(PythonContext context) pb.redirectError(pb.createRedirectToStream(new LoggingOutputStream())); return pb; } + + private static boolean isExecutable(TruffleFile executable) { + try { + return executable.isExecutable(); + } catch (SecurityException e) { + return false; + } + } + + protected static TruffleFile which(PythonContext context, String command) { + Env env = context.getEnv(); + var path = env.getEnvironment().getOrDefault("PATH", "").split(env.getPathSeparator()); + var executable = env.getPublicTruffleFile(context.getOption(PythonOptions.Executable).toJavaStringUncached()); + var candidate = executable.resolveSibling(command); + var i = 0; + while (!isExecutable(candidate) && i < path.length) { + candidate = env.getPublicTruffleFile(path[i++]).resolve(command); + } + return candidate; + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyArithmeticNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyArithmeticNode.java deleted file mode 100644 index b8ee9ed5cf..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyArithmeticNode.java +++ /dev/null @@ -1,503 +0,0 @@ -/* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.nodes.call.GenericInvokeNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallTernaryNode; -import com.oracle.graal.python.nodes.expression.BinaryArithmetic; -import com.oracle.graal.python.nodes.expression.BinaryOpNode; -import com.oracle.graal.python.nodes.expression.InplaceArithmetic; -import com.oracle.graal.python.nodes.expression.LookupAndCallInplaceNode; -import com.oracle.graal.python.nodes.expression.TernaryArithmetic; -import com.oracle.graal.python.nodes.expression.UnaryArithmetic; -import com.oracle.graal.python.nodes.expression.UnaryOpNode; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.nodes.Node; - -public abstract class GraalHPyArithmeticNode { - - private GraalHPyArithmeticNode() { - } - - public abstract static class HPyUnaryArithmeticNode extends Node { - - public abstract Object execute(Object object); - - @NeverDefault - public static HPyUnaryArithmeticNode create(UnaryArithmetic operator) { - return new HPyUnaryArithmeticCached(operator); - } - - public static HPyUnaryArithmeticNode getUncached(UnaryArithmetic operator) { - return HPyUnaryArithmeticUncached.UNCACHEDS[operator.ordinal()]; - } - } - - static final class HPyUnaryArithmeticCached extends HPyUnaryArithmeticNode { - @Child private UnaryOpNode opNode; - - private HPyUnaryArithmeticCached(UnaryArithmetic operator) { - opNode = operator.create(); - } - - @Override - public Object execute(Object object) { - return opNode.executeCached(null, object); - } - } - - private static final class HPyUnaryArithmeticUncached extends HPyUnaryArithmeticNode { - final UnaryArithmetic operator; - - public HPyUnaryArithmeticUncached(UnaryArithmetic operator) { - this.operator = operator; - } - - @TruffleBoundary - @Override - public Object execute(Object object) { - Object[] pythonArguments = PArguments.create(1); - PArguments.setArgument(pythonArguments, 0, object); - RootCallTarget callTarget = PythonLanguage.get(null).createCachedCallTarget(operator::createRootNode, operator); - return GenericInvokeNode.invokeUncached(callTarget, pythonArguments); - } - - @Override - public boolean isAdoptable() { - return false; - } - - private static final HPyUnaryArithmeticUncached[] UNCACHEDS; - static { - UnaryArithmetic[] values = UnaryArithmetic.values(); - UNCACHEDS = new HPyUnaryArithmeticUncached[values.length]; - for (int i = 0; i < values.length; i++) { - UNCACHEDS[i] = new HPyUnaryArithmeticUncached(values[i]); - } - } - } - - public abstract static class HPyBinaryArithmeticNode extends Node { - - public abstract Object execute(Object arg0, Object arg1); - - @NeverDefault - public static HPyBinaryArithmeticNode create(BinaryArithmetic operator) { - return new HPyBinaryArithmeticCached(operator); - } - - public static HPyBinaryArithmeticNode getUncached(BinaryArithmetic operator) { - return HPyBinaryArithmeticUncached.UNCACHEDS[operator.ordinal()]; - } - } - - private static final class HPyBinaryArithmeticCached extends HPyBinaryArithmeticNode { - @Child private BinaryOpNode opNode; - - private HPyBinaryArithmeticCached(BinaryArithmetic operator) { - opNode = operator.create(); - } - - @Override - public Object execute(Object arg0, Object arg1) { - return opNode.executeObject(null, arg0, arg1); - } - } - - private static final class HPyBinaryArithmeticUncached extends HPyBinaryArithmeticNode { - final BinaryArithmetic operator; - - public HPyBinaryArithmeticUncached(BinaryArithmetic operator) { - this.operator = operator; - } - - @TruffleBoundary - @Override - public Object execute(Object arg0, Object arg1) { - Object[] pythonArguments = PArguments.create(2); - PArguments.setArgument(pythonArguments, 0, arg0); - PArguments.setArgument(pythonArguments, 1, arg1); - RootCallTarget callTarget = PythonLanguage.get(null).createCachedCallTarget(operator::createRootNode, operator); - return GenericInvokeNode.invokeUncached(callTarget, pythonArguments); - } - - @Override - public boolean isAdoptable() { - return false; - } - - private static final HPyBinaryArithmeticUncached[] UNCACHEDS; - static { - BinaryArithmetic[] values = BinaryArithmetic.values(); - UNCACHEDS = new HPyBinaryArithmeticUncached[values.length]; - for (int i = 0; i < values.length; i++) { - UNCACHEDS[i] = new HPyBinaryArithmeticUncached(values[i]); - } - } - } - - public abstract static class HPyTernaryArithmeticNode extends Node { - - public abstract Object execute(Object arg0, Object arg1, Object arg2); - - @NeverDefault - public static HPyTernaryArithmeticNode create(TernaryArithmetic operator) { - return new HPyTernaryArithmeticCached(operator); - } - - public static HPyTernaryArithmeticNode getUncached(TernaryArithmetic operator) { - return HPyTernaryArithmeticUncached.UNCACHEDS[operator.ordinal()]; - } - } - - private static final class HPyTernaryArithmeticCached extends HPyTernaryArithmeticNode { - @Child private LookupAndCallTernaryNode opNode; - - private HPyTernaryArithmeticCached(TernaryArithmetic operator) { - opNode = operator.create(); - } - - @Override - public Object execute(Object arg0, Object arg1, Object arg2) { - return opNode.execute(null, arg0, arg1, arg2); - } - } - - private static final class HPyTernaryArithmeticUncached extends HPyTernaryArithmeticNode { - final TernaryArithmetic operator; - - public HPyTernaryArithmeticUncached(TernaryArithmetic operator) { - this.operator = operator; - } - - @TruffleBoundary - @Override - public Object execute(Object arg0, Object arg1, Object arg2) { - Object[] pythonArguments = PArguments.create(3); - PArguments.setArgument(pythonArguments, 0, arg0); - PArguments.setArgument(pythonArguments, 1, arg1); - PArguments.setArgument(pythonArguments, 2, arg2); - RootCallTarget callTarget = PythonLanguage.get(null).createCachedCallTarget(operator::createRootNode, operator); - return GenericInvokeNode.invokeUncached(callTarget, pythonArguments); - } - - @Override - public boolean isAdoptable() { - return false; - } - - private static final HPyTernaryArithmeticUncached[] UNCACHEDS; - static { - TernaryArithmetic[] values = TernaryArithmetic.values(); - UNCACHEDS = new HPyTernaryArithmeticUncached[values.length]; - for (int i = 0; i < values.length; i++) { - UNCACHEDS[i] = new HPyTernaryArithmeticUncached(values[i]); - } - } - } - - public abstract static class HPyInplaceArithmeticNode extends Node { - - public abstract Object execute(Object arg0, Object arg1, Object arg2); - - public final Object execute(Object arg0, Object arg1) { - return execute(arg0, arg1, PNone.NO_VALUE); - } - - @NeverDefault - public static HPyInplaceArithmeticNode create(InplaceArithmetic operator) { - return new HPyInplaceArithmeticCached(operator); - } - - public static HPyInplaceArithmeticNode getUncached(InplaceArithmetic operator) { - return HPyInplaceArithmeticUncached.UNCACHEDS[operator.ordinal()]; - } - } - - private static final class HPyInplaceArithmeticCached extends HPyInplaceArithmeticNode { - @Child private LookupAndCallInplaceNode opNode; - - private final boolean isTernary; - - private HPyInplaceArithmeticCached(InplaceArithmetic operator) { - opNode = operator.create(); - this.isTernary = operator.isTernary(); - } - - @Override - public Object execute(Object arg0, Object arg1, Object arg2) { - if (isTernary) { - return opNode.executeTernary(null, arg0, arg1, arg2); - } else { - return opNode.execute(null, arg0, arg1); - } - } - } - - private static final class HPyInplaceArithmeticUncached extends HPyInplaceArithmeticNode { - final InplaceArithmetic operator; - - public HPyInplaceArithmeticUncached(InplaceArithmetic operator) { - this.operator = operator; - } - - @TruffleBoundary - @Override - public Object execute(Object arg0, Object arg1, Object arg2) { - Object[] pythonArguments = PArguments.create(3); - PArguments.setArgument(pythonArguments, 0, arg0); - PArguments.setArgument(pythonArguments, 1, arg1); - PArguments.setArgument(pythonArguments, 2, arg2); - RootCallTarget callTarget = PythonLanguage.get(null).createCachedCallTarget(operator::createRootNode, operator); - return GenericInvokeNode.invokeUncached(callTarget, pythonArguments); - } - - @Override - public boolean isAdoptable() { - return false; - } - - private static final HPyInplaceArithmeticUncached[] UNCACHEDS; - static { - InplaceArithmetic[] values = InplaceArithmetic.values(); - UNCACHEDS = new HPyInplaceArithmeticUncached[values.length]; - for (int i = 0; i < values.length; i++) { - UNCACHEDS[i] = new HPyInplaceArithmeticUncached(values[i]); - } - } - } - -// @NeverDefault -// public static GraalHPyBinaryArithmeticCached create(BinaryArithmetic operator) { -// return new GraalHPyBinaryArithmeticCached(operator); -// } -// -// public static GraalHPyBinaryArithmeticUncached getUncached(BinaryArithmetic operator) { -// return GraalHPyBinaryArithmeticUncached.UNCACHEDS[operator.ordinal()]; -// } -// -// static final class GraalHPyBinaryArithmeticCached extends GraalHPyArithmeticCachedNode { -// @Child private BinaryOpNode opNode; -// -// GraalHPyBinaryArithmeticCached(BinaryArithmetic operator) { -// opNode = operator.create(); -// } -// -// @Override -// void checkArity(Object[] arguments) throws ArityException { -// checkArity(arguments, EXPECTED_ARITY_BINARY); -// } -// -// @Override -// Object doOperator(Object[] arguments) { -// return opNode.executeObject(null, asPythonObjectNode.execute(arguments[1]), -// asPythonObjectNode.execute(arguments[2])); -// } -// } -// -// private static final class GraalHPyBinaryArithmeticUncached extends -// GraalHPyArithmeticUncachedNode { -// final BinaryArithmetic operator; -// -// public GraalHPyBinaryArithmeticUncached(BinaryArithmetic operator) { -// this.operator = operator; -// } -// -// @Override -// void checkArity(Object[] arguments) throws ArityException { -// checkArity(arguments, EXPECTED_ARITY_BINARY); -// } -// -// @Override -// RootCallTarget ensureCallTarget() { -// return PythonLanguage.get(null).createCachedCallTarget(operator::createRootNode, operator); -// } -// -// private static final GraalHPyBinaryArithmeticUncached[] UNCACHEDS; -// static { -// BinaryArithmetic[] values = BinaryArithmetic.values(); -// UNCACHEDS = new GraalHPyBinaryArithmeticUncached[values.length]; -// for (int i = 0; i < values.length; i++) { -// UNCACHEDS[i] = new GraalHPyBinaryArithmeticUncached(values[i]); -// } -// } -// } -// -// @NeverDefault -// public static GraalHPyTernaryArithmeticCached create(TernaryArithmetic operator) { -// return new GraalHPyTernaryArithmeticCached(operator); -// } -// -// public static GraalHPyTernaryArithmeticUncached getUncached(TernaryArithmetic operator) { -// return GraalHPyTernaryArithmeticUncached.UNCACHEDS[operator.ordinal()]; -// } -// -// static final class GraalHPyTernaryArithmeticCached extends GraalHPyArithmeticCachedNode { -// @Child private LookupAndCallTernaryNode opNode; -// -// GraalHPyTernaryArithmeticCached(TernaryArithmetic operator) { -// opNode = operator.create(); -// } -// -// @Override -// void checkArity(Object[] arguments) throws ArityException { -// checkArity(arguments, EXPECTED_ARITY_TERNARY); -// } -// -// @Override -// Object doOperator(Object[] arguments) { -// return opNode.execute(null, asPythonObjectNode.execute(arguments[1]), -// asPythonObjectNode.execute(arguments[2]), asPythonObjectNode.execute(arguments[3])); -// } -// } -// -// private static final class GraalHPyTernaryArithmeticUncached extends -// GraalHPyArithmeticUncachedNode { -// final TernaryArithmetic operator; -// -// public GraalHPyTernaryArithmeticUncached(TernaryArithmetic operator) { -// this.operator = operator; -// } -// -// @Override -// void checkArity(Object[] arguments) throws ArityException { -// checkArity(arguments, EXPECTED_ARITY_TERNARY); -// } -// -// @Override -// RootCallTarget ensureCallTarget() { -// return PythonLanguage.get(null).createCachedCallTarget(operator::createRootNode, operator); -// } -// -// private static final GraalHPyTernaryArithmeticUncached[] UNCACHEDS; -// static { -// TernaryArithmetic[] values = TernaryArithmetic.values(); -// UNCACHEDS = new GraalHPyTernaryArithmeticUncached[values.length]; -// for (int i = 0; i < values.length; i++) { -// UNCACHEDS[i] = new GraalHPyTernaryArithmeticUncached(values[i]); -// } -// } -// } -// -// @NeverDefault -// public static GraalHPyInplaceArithmeticCached create(InplaceArithmetic operator) { -// return new GraalHPyInplaceArithmeticCached(operator); -// } -// -// public static GraalHPyInplaceArithmeticUncached getUncached(InplaceArithmetic operator) { -// return GraalHPyInplaceArithmeticUncached.UNCACHEDS[operator.ordinal()]; -// } -// -// static final class GraalHPyInplaceArithmeticCached extends GraalHPyArithmeticCachedNode { -// @Child private LookupAndCallInplaceNode opNode; -// private final boolean ternary; -// -// GraalHPyInplaceArithmeticCached(InplaceArithmetic operator) { -// opNode = operator.create(); -// ternary = operator.isTernary(); -// } -// -// @Override -// void checkArity(Object[] arguments) throws ArityException { -// GraalHPyInplaceArithmeticCached.checkInplaceArity(arguments, ternary); -// } -// -// private static void checkInplaceArity(Object[] arguments, boolean ternary) throws ArityException -// { -// // we also need to account for the HPy context -// if (ternary && arguments.length != 4) { -// CompilerDirectives.transferToInterpreterAndInvalidate(); -// throw ArityException.create(EXPECTED_ARITY_TERNARY, EXPECTED_ARITY_TERNARY, arguments.length); -// } -// if (!ternary && arguments.length != 3) { -// CompilerDirectives.transferToInterpreterAndInvalidate(); -// throw ArityException.create(EXPECTED_ARITY_BINARY, EXPECTED_ARITY_BINARY, arguments.length); -// } -// } -// -// @Override -// Object doOperator(Object[] arguments) { -// return opNode.execute(null, asPythonObjectNode.execute(arguments[1]), -// asPythonObjectNode.execute(arguments[2])); -// } -// } -// -// private static final class GraalHPyInplaceArithmeticUncached extends -// GraalHPyArithmeticUncachedNode { -// final InplaceArithmetic operator; -// -// public GraalHPyInplaceArithmeticUncached(InplaceArithmetic operator) { -// this.operator = operator; -// } -// -// @Override -// void checkArity(Object[] arguments) throws ArityException { -// GraalHPyInplaceArithmeticCached.checkInplaceArity(arguments, operator.isTernary()); -// } -// -// @Override -// RootCallTarget ensureCallTarget() { -// return PythonLanguage.get(null).createCachedCallTarget(operator::createRootNode, operator); -// } -// -// private static final GraalHPyInplaceArithmeticUncached[] UNCACHEDS; -// static { -// InplaceArithmetic[] values = InplaceArithmetic.values(); -// UNCACHEDS = new GraalHPyInplaceArithmeticUncached[values.length]; -// for (int i = 0; i < values.length; i++) { -// UNCACHEDS[i] = new GraalHPyInplaceArithmeticUncached(values[i]); -// } -// } -// } -// -// static void checkArity(Object[] arguments, int expectedArity) throws ArityException { -// if (arguments.length != expectedArity) { -// CompilerDirectives.transferToInterpreterAndInvalidate(); -// throw ArityException.create(expectedArity, expectedArity, arguments.length); -// } -// } - -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyBoxing.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyBoxing.java deleted file mode 100644 index 1eb6543026..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyBoxing.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -public class GraalHPyBoxing { - - // see the corresponding implementation in hpy_jni.c - - /*- - * This NaN boxing mechanism puts all non-double values into the range - * [0 - NAN_BOXING_BASE[. Boxing a double value adds NAN_BOXING_BASE, and - * unboxing a double value subtracts NAN_BOXING_BASE. - * Therefore, unboxing the non-double values ends up in the range - * [fff9_0000_0000_0000 - ffff_ffff_ffff_ffff], which are non-standard - * quiet NaNs with sign bit - these don't appear in normal calculations. - * - * The range [0 - 7fff_ffff] is currently used for HPy handles, - * and the range [0001_0000_0000_0000 - 0001_0000_ffff_ffff] is currently - * used to represent primitive integers. - * - * There is space left to add other types and extend the bit size of - * handles and integers. - */ - - private static final long NAN_BOXING_BASE = 0x0007_0000_0000_0000L; - private static final long NAN_BOXING_MASK = 0xFFFF_0000_0000_0000L; - private static final long NAN_BOXING_INT = 0x0001_0000_0000_0000L; - - private static final long NAN_BOXING_INT_MASK = 0x00000000FFFFFFFFL; - private static final long NAN_BOXING_MAX_HANDLE = Integer.MAX_VALUE; - - // First N constants in the HPyContext are guaranteed to always get the same handle assigned. - // Note that 0 is HPy_NULL, so in this case we are counting from 1. - public static final int SINGLETON_HANDLE_MAX = 3; - - public static boolean isBoxedDouble(long value) { - return Long.compareUnsigned(value, NAN_BOXING_BASE) >= 0; - } - - public static boolean isBoxedHandle(long value) { - return Long.compareUnsigned(value, NAN_BOXING_MAX_HANDLE) <= 0; - } - - public static boolean isBoxedInt(long value) { - return (value & NAN_BOXING_MASK) == NAN_BOXING_INT; - } - - public static boolean isBoxedNullHandle(long value) { - return value == 0; - } - - public static int unboxHandle(long value) { - return (int) value; - } - - public static long boxHandle(int handle) { - return handle; - } - - public static double unboxDouble(long value) { - return Double.longBitsToDouble(value - NAN_BOXING_BASE); - } - - public static long boxDouble(double value) { - // assumes that value doesn't contain non-standard silent NaNs - assert Long.compareUnsigned(Double.doubleToRawLongBits(value) + NAN_BOXING_BASE, NAN_BOXING_BASE) >= 0; - - long doubleBits = Double.doubleToRawLongBits(value); - return doubleBits + NAN_BOXING_BASE; - } - - public static int unboxInt(long value) { - return (int) (value - NAN_BOXING_INT); - } - - public static long boxInt(int value) { - return (value & NAN_BOXING_INT_MASK) + NAN_BOXING_INT; - } - - public static boolean isBoxablePrimitive(Object value) { - return value instanceof Double || value instanceof Integer; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyBuffer.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyBuffer.java deleted file mode 100644 index 28442bf8a1..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyBuffer.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import static com.oracle.truffle.api.strings.TruffleString.Encoding.UTF_8; - -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.PythonAbstractObject; -import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CIntArrayWrapper; -import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CStringWrapper; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsHandleNode; -import com.oracle.graal.python.builtins.objects.ints.PInt; -import com.oracle.graal.python.builtins.objects.memoryview.CExtPyBuffer; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.interop.UnknownIdentifierException; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.library.ExportLibrary; -import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.api.strings.TruffleString; - -/** - * This class implements an interop object that behaves like {@code HPy_buffer} and is backed by - * {@link CExtPyBuffer}. Therefore, this object is just a view and is read-only. The idea is to use - * this view for releasing a buffer since releasing usually doesn't need all values and so we try to - * avoid to do costly conversions eagerly. - * - * The {@code HPy_buffer} structure: - * - *

    - *     typedef struct {
    - *         void *buf;
    - *         HPy obj;
    - *         HPy_ssize_t len;
    - *         HPy_ssize_t itemsize;
    - *         int readonly;
    - *         int ndim;
    - *         char *format;
    - *         HPy_ssize_t *shape;
    - *         HPy_ssize_t *strides;
    - *         HPy_ssize_t *suboffsets;
    - *         void *internal;
    - * } HPy_buffer;
    - * 
    - */ -@ExportLibrary(InteropLibrary.class) -@SuppressWarnings("static-method") -public final class GraalHPyBuffer implements TruffleObject { - private static final String J_MEMBER_BUF = "buf"; - private static final String J_MEMBER_OBJ = "obj"; - private static final String J_MEMBER_LEN = "len"; - private static final String J_MEMBER_ITEMSIZE = "itemsize"; - private static final String J_MEMBER_READONLY = "readonly"; - private static final String J_MEMBER_NDIM = "ndim"; - private static final String J_MEMBER_FORMAT = "format"; - private static final String J_MEMBER_SHAPE = "shape"; - private static final String J_MEMBER_STRIDES = "strides"; - private static final String J_MEMBER_SUBOFFSETS = "suboffsets"; - private static final String J_MEMBER_INTERNAL = "internal"; - - @CompilationFinal(dimensions = 1) private static final String[] MEMBERS = new String[]{J_MEMBER_BUF, J_MEMBER_OBJ, J_MEMBER_LEN, J_MEMBER_ITEMSIZE, J_MEMBER_READONLY, J_MEMBER_NDIM, - J_MEMBER_FORMAT, J_MEMBER_SHAPE, J_MEMBER_STRIDES, J_MEMBER_SUBOFFSETS, J_MEMBER_INTERNAL}; - - final GraalHPyContext context; - private final CExtPyBuffer buffer; - - private GraalHPyHandle ownerHandle; - Object nativePointer; - - public GraalHPyBuffer(GraalHPyContext context, CExtPyBuffer buffer) { - this.context = context; - this.buffer = buffer; - } - - @ExportMessage - boolean hasMembers() { - return true; - } - - @ExportMessage - Object getMembers(@SuppressWarnings("unused") boolean includeInternal) { - return new PythonAbstractObject.Keys(new Object[]{J_MEMBER_BUF, J_MEMBER_OBJ, J_MEMBER_LEN, J_MEMBER_ITEMSIZE, J_MEMBER_READONLY, - J_MEMBER_NDIM, J_MEMBER_FORMAT, J_MEMBER_SHAPE, J_MEMBER_STRIDES, J_MEMBER_SUBOFFSETS, J_MEMBER_INTERNAL}); - } - - @ExportMessage - boolean isMemberReadable(String key) { - for (int i = 0; i < MEMBERS.length; i++) { - if (MEMBERS[i].equals(key)) { - return true; - } - } - return false; - } - - @ExportMessage - Object readMember(String member, - @Cached HPyAsHandleNode toNativeNode) throws UnknownIdentifierException { - switch (member) { - case J_MEMBER_BUF: - return buffer.getBuf(); - case J_MEMBER_OBJ: - if (ownerHandle == null) { - Object obj = buffer.getObj(); - ownerHandle = toNativeNode.execute(obj != null ? obj : PNone.NO_VALUE); - } - return ownerHandle; - case J_MEMBER_LEN: - return buffer.getLen(); - case J_MEMBER_ITEMSIZE: - return buffer.getItemSize(); - case J_MEMBER_READONLY: - return PInt.intValue(buffer.isReadOnly()); - case J_MEMBER_NDIM: - return buffer.getDims(); - case J_MEMBER_FORMAT: - return buffer.getFormat() != null ? new CStringWrapper(buffer.getFormat().switchEncodingUncached(UTF_8), UTF_8) : toNativeNode.execute(PNone.NO_VALUE); - case J_MEMBER_SHAPE: - return toCArray(toNativeNode, buffer.getShape()); - case J_MEMBER_STRIDES: - return toCArray(toNativeNode, buffer.getStrides()); - case J_MEMBER_SUBOFFSETS: - return toCArray(toNativeNode, buffer.getSuboffsets()); - case J_MEMBER_INTERNAL: - return buffer.getInternal(); - } - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw UnknownIdentifierException.create(member); - } - - private static Object toCArray(HPyAsHandleNode toNativeNode, int[] arr) { - if (arr != null) { - return new CIntArrayWrapper(arr); - } - return toNativeNode.execute(PNone.NO_VALUE); - } - - @ExportMessage - boolean isPointer() { - return nativePointer != null; - } - - @ExportMessage - long asPointer( - @CachedLibrary(limit = "1") InteropLibrary lib) throws UnsupportedMessageException { - return PythonUtils.coerceToLong(nativePointer, lib); - } - - @ExportMessage - void toNative( - @Cached(parameters = "this.context") GraalHPyCAccess.AllocateNode allocateNode, - @Cached(parameters = "this.context") GraalHPyCAccess.WritePointerNode writePointerNode, - @Cached(parameters = "this.context") GraalHPyCAccess.WriteHPyNode writeHPyNode, - @Cached(parameters = "this.context") GraalHPyCAccess.WriteSizeTNode writeSizeTNode, - @Cached(parameters = "this.context") GraalHPyCAccess.WriteI32Node writeI32Node, - @Cached TruffleString.AsNativeNode asNativeNode, - @Cached TruffleString.GetInternalNativePointerNode getInternalNativePointerNode, - @Cached TruffleString.SwitchEncodingNode switchEncodingNode) { - if (nativePointer == null) { - Object nativePointer = allocateNode.malloc(context, HPyContextSignatureType.HPy_buffer); - TruffleString formatUtf8 = switchEncodingNode.execute(buffer.getFormat(), UTF_8); - TruffleString formatNative = asNativeNode.execute(formatUtf8, byteSize -> context.nativeToInteropPointer(allocateNode.malloc(context, byteSize)), UTF_8, true, true); - Object formatPtr = getInternalNativePointerNode.execute(formatNative, UTF_8); - - writePointerNode.write(context, nativePointer, GraalHPyCField.HPy_buffer__buf, buffer.getBuf()); - writeHPyNode.write(context, nativePointer, GraalHPyCField.HPy_buffer__obj, buffer.getObj()); - writeSizeTNode.write(context, nativePointer, GraalHPyCField.HPy_buffer__len, buffer.getLen()); - writeSizeTNode.write(context, nativePointer, GraalHPyCField.HPy_buffer__itemsize, buffer.getItemSize()); - writeI32Node.write(context, nativePointer, GraalHPyCField.HPy_buffer__readonly, PInt.intValue(buffer.isReadOnly())); - writeI32Node.write(context, nativePointer, GraalHPyCField.HPy_buffer__ndim, buffer.getDims()); - writePointerNode.write(context, nativePointer, GraalHPyCField.HPy_buffer__format, formatPtr); - writePointerNode.write(context, nativePointer, GraalHPyCField.HPy_buffer__shape, intArrayToNativeInt64(context, buffer.getShape(), allocateNode, writeSizeTNode)); - writePointerNode.write(context, nativePointer, GraalHPyCField.HPy_buffer__strides, intArrayToNativeInt64(context, buffer.getStrides(), allocateNode, writeSizeTNode)); - writePointerNode.write(context, nativePointer, GraalHPyCField.HPy_buffer__suboffsets, intArrayToNativeInt64(context, buffer.getSuboffsets(), allocateNode, writeSizeTNode)); - writePointerNode.write(context, nativePointer, GraalHPyCField.HPy_buffer__internal, buffer.getInternal()); - this.nativePointer = nativePointer; - } - } - - private static Object intArrayToNativeInt64(GraalHPyContext ctx, int[] data, GraalHPyCAccess.AllocateNode allocateNode, GraalHPyCAccess.WriteSizeTNode writeSizeTNode) { - if (data != null) { - long elemSize = ctx.getCTypeSize(HPyContextSignatureType.HPy_ssize_t); - Object ptr = allocateNode.calloc(ctx, data.length, elemSize); - for (int i = 0; i < data.length; i++) { - writeSizeTNode.execute(ctx, ptr, i * elemSize, data[i]); - } - return ptr; - } - return ctx.getNativeNull(); - } - - void free(GraalHPyContext ctx, GraalHPyCAccess.FreeNode freeNode, GraalHPyCAccess.ReadPointerNode readPointerNode, GraalHPyCAccess.ReadHPyNode readHPyNode) { - if (ownerHandle != null) { - ownerHandle.closeAndInvalidate(context); - } - if (nativePointer != null) { - Object owner = readHPyNode.readAndClose(ctx, nativePointer, GraalHPyCField.HPy_buffer__obj); - assert owner == buffer.getObj(); - Object format = readPointerNode.read(ctx, nativePointer, GraalHPyCField.HPy_buffer__format); - Object shape = readPointerNode.read(ctx, nativePointer, GraalHPyCField.HPy_buffer__shape); - Object suboffsets = readPointerNode.read(ctx, nativePointer, GraalHPyCField.HPy_buffer__suboffsets); - freeNode.free(ctx, format); - freeNode.free(ctx, shape); - freeNode.free(ctx, suboffsets); - freeNode.free(ctx, nativePointer); - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyCAccess.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyCAccess.java deleted file mode 100644 index 5f38920088..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyCAccess.java +++ /dev/null @@ -1,726 +0,0 @@ -/* - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.GraalHPyHandleReference; -import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.nodes.Node; - -public abstract class GraalHPyCAccess { - - private GraalHPyCAccess() { - } - - private abstract static class CStructAccessNode extends Node { - - abstract boolean accepts(HPyContextSignatureType type); - - final boolean accepts(GraalHPyCField field) { - return accepts(field.getType()); - } - - /** - * Use this method to compute the address of a struct field where the struct is one element - * in an array. For example: - * - *
    -         *     HPyType_SpecParam params[] = {
    -         *         {HPyType_SpecParam_Base, ctx->h_LongType},
    -         *         {HPyType_SpecParam_Base, ctx->h_UnicodeType},
    -         *         {0}
    -         *     }
    -         * 
    - * - * Assume you want to read the field {@code object} (the second field of type {@code HPy}) - * of the second array element. The address is then computed by: - * - *
    -         *     long arrElemOffset = getElementPtr(1, GraalHPyCStruct.HPyType_SpecParam.getSize(), GraalHPyCField.HPyType_SpecParam_object)
    -         * 
    - * - * You may later read the value using {@code ReadHPyNode.execute(ctx, base, arrElemOffset)}. - * - * @param idx Index of the element (e.g. a struct type). - * @param elementSize Size of each element. - * @param field Field of the element (e.g. a struct field). - */ - public static long getElementPtr(GraalHPyContext ctx, long idx, long elementSize, GraalHPyCField field) { - return idx * elementSize + ctx.getCFieldOffset(field); - } - - public static long getElementPtr(GraalHPyContext ctx, long idx, HPyContextSignatureType elementType, GraalHPyCField field) { - return idx * ctx.getCTypeSize(elementType) + ctx.getCFieldOffset(field); - } - - } - - public abstract static class AllocateNode extends Node { - - protected abstract Object execute(GraalHPyContext ctx, long size, boolean zero); - - public final Object malloc(GraalHPyContext ctx, long size) { - return execute(ctx, size, false); - } - - public final Object malloc(GraalHPyContext ctx, HPyContextSignatureType ctype) { - return execute(ctx, ctx.getCTypeSize(ctype), false); - } - - public final Object calloc(GraalHPyContext ctx, long count, long size) { - return execute(ctx, count * size, true); - } - - @NeverDefault - public static AllocateNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createAllocateNode(); - } - - public static AllocateNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedAllocateNode(); - } - } - - public abstract static class FreeNode extends Node { - - protected abstract void execute(GraalHPyContext ctx, Object pointer); - - public final void free(GraalHPyContext ctx, Object pointer) { - execute(ctx, pointer); - } - - @NeverDefault - public static FreeNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createFreeNode(); - } - - public static FreeNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedFreeNode(); - } - } - - public abstract static class BulkFreeHandleReferencesNode extends Node { - - protected abstract void execute(GraalHPyContext ctx, GraalHPyHandleReference[] references); - - @NeverDefault - public static BulkFreeHandleReferencesNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createBulkFreeHandleReferencesNode(); - } - } - - public abstract static class IsNullNode extends Node { - - protected abstract boolean execute(GraalHPyContext ctx, Object pointer); - - public static boolean executeUncached(GraalHPyContext ctx, Object pointer) { - return IsNullNode.getUncached(ctx).execute(ctx, pointer); - } - - @NeverDefault - public static IsNullNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createIsNullNode(); - } - - public static IsNullNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedIsNullNode(); - } - } - - public abstract static class GetElementPtrNode extends CStructAccessNode { - - public abstract Object execute(GraalHPyContext ctx, Object pointer, long offset); - - public final Object getElementPtr(GraalHPyContext ctx, Object pointer, GraalHPyCField field) { - // GR-50245 - // assert accepts(field); - return execute(ctx, pointer, ctx.getCFieldOffset(field)); - } - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return true; - } - - @NeverDefault - public static GetElementPtrNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createGetElementPtrNode(); - } - - public static GetElementPtrNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedGetElementPtrNode(); - } - } - - public abstract static class ReadGenericNode extends CStructAccessNode { - - protected abstract Object execute(GraalHPyContext ctx, Object pointer, long offset, HPyContextSignatureType size); - - protected abstract int executeInt(GraalHPyContext ctx, Object pointer, long offset, HPyContextSignatureType size); - - protected abstract long executeLong(GraalHPyContext ctx, Object pointer, long offset, HPyContextSignatureType size); - - @Override - boolean accepts(HPyContextSignatureType type) { - return true; - } - - public final Object read(GraalHPyContext ctx, Object pointer, GraalHPyCField field) { - return execute(ctx, pointer, ctx.getCFieldOffset(field), field.getType()); - } - - public final int readInt(GraalHPyContext ctx, Object pointer, GraalHPyCField field) { - return executeInt(ctx, pointer, ctx.getCFieldOffset(field), field.getType()); - } - - public final long readLong(GraalHPyContext ctx, Object pointer, GraalHPyCField field) { - return executeLong(ctx, pointer, ctx.getCFieldOffset(field), field.getType()); - } - - @NeverDefault - public static ReadGenericNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createReadGenericNode(); - } - - public static ReadGenericNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedReadGenericNode(); - } - } - - public abstract static class ReadI8ArrayNode extends CStructAccessNode { - - protected abstract byte[] execute(GraalHPyContext ctx, Object pointer, long offset, long n); - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return false; - } - - @NeverDefault - public static ReadI8ArrayNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createReadI8ArrayNode(); - } - - public static ReadI8ArrayNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedReadI8ArrayNode(); - } - } - - public abstract static class ReadHPyNode extends CStructAccessNode { - - protected abstract Object execute(GraalHPyContext ctx, Object pointer, long offset, boolean close); - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return false; - } - - public final Object read(GraalHPyContext ctx, Object pointer, long offset) { - return execute(ctx, pointer, offset, false); - } - - /** - * Read an {@code HPy} handle and return the referred object. - */ - public final Object read(GraalHPyContext ctx, Object pointer, GraalHPyCField field) { - // GR-50245 - // assert accepts(field); - return execute(ctx, pointer, ctx.getCFieldOffset(field), false); - } - - /** - * Read and close an {@code HPy} handle and return the referred object. This method is - * mostly useful if some C function returns a handle via an out param. For example, - * any {@code HPyFunc_getbufferproc} function returns a handle in the {@code HPy_buffer} - * struct. - */ - public final Object readAndClose(GraalHPyContext ctx, Object pointer, GraalHPyCField field) { - // GR-50245 - // assert accepts(field); - return execute(ctx, pointer, ctx.getCFieldOffset(field), true); - } - - @NeverDefault - public static ReadHPyNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createReadHPyNode(); - } - - public static ReadHPyNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedReadHPyNode(); - } - } - - public abstract static class ReadHPyFieldNode extends CStructAccessNode { - - protected abstract Object execute(GraalHPyContext ctx, PythonObject owner, Object pointer, long offset, boolean close); - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return false; - } - - public final Object read(GraalHPyContext ctx, PythonObject owner, Object pointer, long offset) { - return execute(ctx, owner, pointer, offset, false); - } - - /** - * Read an {@code HPy} handle and return the referred object. - */ - public final Object read(GraalHPyContext ctx, PythonObject owner, Object pointer, GraalHPyCField field) { - // GR-50245 - // assert accepts(field); - return execute(ctx, owner, pointer, ctx.getCFieldOffset(field), false); - } - - @NeverDefault - public static ReadHPyFieldNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createReadHPyFieldNode(); - } - - public static ReadHPyFieldNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedReadFieldHPyNode(); - } - } - - public abstract static class ReadHPyArrayNode extends CStructAccessNode { - - protected abstract Object[] execute(GraalHPyContext ctx, Object pointer, long offset, long n); - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return false; - } - - @NeverDefault - public static ReadHPyArrayNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createReadHPyArrayNode(); - } - - public static ReadHPyArrayNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedReadHPyArrayNode(); - } - } - - public abstract static class ReadI32Node extends CStructAccessNode { - - protected abstract int execute(GraalHPyContext ctx, Object pointer, long offset); - - public final int read(GraalHPyContext ctx, Object pointer, GraalHPyCField field) { - // GR-50245 - // assert accepts(field); - return execute(ctx, pointer, ctx.getCFieldOffset(field)); - } - - public final long readUnsigned(GraalHPyContext ctx, Object pointer, GraalHPyCField field) { - assert field.getType() == HPyContextSignatureType.Uint32_t; - return execute(ctx, pointer, ctx.getCFieldOffset(field)) & 0xFFFFFFFFL; - } - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return desc.jniType == int.class; - } - - public final int readOffset(GraalHPyContext ctx, Object pointer, long offset) { - return execute(ctx, pointer, offset); - } - - public final int readArrayElement(GraalHPyContext ctx, Object pointer, long element) { - return execute(ctx, pointer, element * Integer.BYTES); - } - - @NeverDefault - public static ReadI32Node create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createReadI32Node(); - } - - public static ReadI32Node getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedReadI32Node(); - } - } - - public abstract static class ReadI64Node extends CStructAccessNode { - - protected abstract long execute(GraalHPyContext ctx, Object pointer, long offset); - - public final long read(GraalHPyContext ctx, Object pointer, GraalHPyCField field) { - // GR-50245 - // assert accepts(field); - return execute(ctx, pointer, ctx.getCFieldOffset(field)); - } - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return desc.jniType == long.class; - } - - @NeverDefault - public static ReadI64Node create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createReadI64Node(); - } - - public static ReadI64Node getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedReadI64Node(); - } - } - - /** - * Note that this node returns a double, not a float, even though it reads only 32 bits. - */ - public abstract static class ReadFloatNode extends CStructAccessNode { - - protected abstract double execute(GraalHPyContext ctx, Object pointer, long offset); - - public final double read(GraalHPyContext ctx, Object pointer, GraalHPyCField field) { - // GR-50245 - // assert accepts(field); - return execute(ctx, pointer, ctx.getCFieldOffset(field)); - } - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return desc.jniType == double.class; - } - - public final double readArrayElement(GraalHPyContext ctx, Object pointer, int element) { - return execute(ctx, pointer, (long) element * Float.BYTES); - } - - @NeverDefault - public static ReadFloatNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createReadFloatNode(); - } - - public static ReadFloatNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedReadFloatNode(); - } - } - - public abstract static class ReadDoubleNode extends CStructAccessNode { - - protected abstract double execute(GraalHPyContext ctx, Object pointer, long offset); - - public final double read(GraalHPyContext ctx, Object pointer, GraalHPyCField field) { - // GR-50245 - // assert accepts(field); - return execute(ctx, pointer, ctx.getCFieldOffset(field)); - } - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return desc.jniType == double.class; - } - - public final double readArrayElement(GraalHPyContext ctx, Object pointer, int element) { - return execute(ctx, pointer, (long) element * Double.BYTES); - } - - @NeverDefault - public static ReadDoubleNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createReadDoubleNode(); - } - - public static ReadDoubleNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedReadDoubleNode(); - } - } - - public abstract static class ReadPointerNode extends CStructAccessNode { - - protected abstract Object execute(GraalHPyContext ctx, Object pointer, long offset); - - public final Object read(GraalHPyContext ctx, Object pointer, GraalHPyCField field) { - // GR-50245 - // assert accepts(field); - return execute(ctx, pointer, ctx.getCFieldOffset(field)); - } - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return "POINTER".equals(desc.nfiType); - } - - public final Object readArrayElement(GraalHPyContext ctx, Object pointer, long element) { - return execute(ctx, pointer, element * ctx.getCTypeSize(HPyContextSignatureType.VoidPtr)); - } - - @NeverDefault - public static ReadPointerNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createReadPointerNode(); - } - - public static ReadPointerNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedReadPointerNode(); - } - } - - public abstract static class WriteDoubleNode extends CStructAccessNode { - - protected abstract void execute(GraalHPyContext ctx, Object pointer, long offset, double value); - - public final void write(GraalHPyContext ctx, Object pointer, GraalHPyCField field, double value) { - // GR-50245 - // assert accepts(field); - execute(ctx, pointer, ctx.getCFieldOffset(field), value); - } - - public final void write(GraalHPyContext ctx, Object pointer, double value) { - execute(ctx, pointer, 0, value); - } - - public final void writeArrayElement(GraalHPyContext ctx, Object pointer, long element, double value) { - execute(ctx, pointer, element * Double.BYTES, value); - } - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return desc == HPyContextSignatureType.CDouble; - } - - @NeverDefault - public static WriteDoubleNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createWriteDoubleNode(); - } - - public static WriteDoubleNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedWriteDoubleNode(); - } - } - - public abstract static class WriteI32Node extends CStructAccessNode { - - protected abstract void execute(GraalHPyContext ctx, Object pointer, long offset, int value); - - public final void write(GraalHPyContext ctx, Object pointer, GraalHPyCField field, int value) { - // GR-50245 - // assert accepts(field); - execute(ctx, pointer, ctx.getCFieldOffset(field), value); - } - - public final void write(GraalHPyContext ctx, Object pointer, int value) { - execute(ctx, pointer, 0, value); - } - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return desc.jniType == int.class; - } - - public final void writeArrayElement(GraalHPyContext ctx, Object pointer, long element, int value) { - execute(ctx, pointer, element * Integer.BYTES, value); - } - - @NeverDefault - public static WriteI32Node create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createWriteI32Node(); - } - - public static WriteI32Node getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedWriteI32Node(); - } - } - - public abstract static class WriteI64Node extends CStructAccessNode { - - protected abstract void execute(GraalHPyContext ctx, Object pointer, long offset, long value); - - public final void write(GraalHPyContext ctx, Object pointer, GraalHPyCField field, long value) { - // GR-50245 - // assert accepts(field); - execute(ctx, pointer, ctx.getCFieldOffset(field), value); - } - - public final void write(GraalHPyContext ctx, Object pointer, long value) { - execute(ctx, pointer, 0, value); - } - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return desc.jniType == long.class; - } - - @NeverDefault - public static WriteI64Node create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createWriteI64Node(); - } - - public static WriteI64Node getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedWriteI64Node(); - } - } - - public abstract static class WriteGenericNode extends CStructAccessNode { - - protected abstract void execute(GraalHPyContext ctx, Object pointer, long offset, HPyContextSignatureType type, Object value); - - protected abstract void execute(GraalHPyContext ctx, Object pointer, long offset, HPyContextSignatureType type, long value); - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return true; - } - - @NeverDefault - public static WriteGenericNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createWriteGenericNode(); - } - - public static WriteGenericNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedWriteGenericNode(); - } - } - - public abstract static class WriteHPyNode extends CStructAccessNode { - - protected abstract void execute(GraalHPyContext ctx, Object pointer, long offset, Object value); - - public final void write(GraalHPyContext ctx, Object pointer, GraalHPyCField field, Object value) { - // GR-50245 - // assert accepts(field); - execute(ctx, pointer, ctx.getCFieldOffset(field), value); - } - - public final void write(GraalHPyContext ctx, Object pointer, Object value) { - execute(ctx, pointer, 0, value); - } - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return desc == HPyContextSignatureType.HPy; - } - - @NeverDefault - public static WriteHPyNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createWriteHPyNode(); - } - - public static WriteHPyNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedWriteHPyNode(); - } - } - - public abstract static class WriteHPyFieldNode extends CStructAccessNode { - - protected abstract void execute(GraalHPyContext ctx, PythonObject owner, Object pointer, long offset, Object value); - - public final void write(GraalHPyContext ctx, PythonObject owner, Object pointer, GraalHPyCField field, Object value) { - // GR-50245 - // assert accepts(field); - execute(ctx, owner, pointer, ctx.getCFieldOffset(field), value); - } - - public final void write(GraalHPyContext ctx, PythonObject owner, Object pointer, Object value) { - execute(ctx, owner, pointer, 0, value); - } - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return desc == HPyContextSignatureType.HPyField; - } - - @NeverDefault - public static WriteHPyFieldNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createWriteHPyFieldNode(); - } - - public static WriteHPyFieldNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedWriteHPyFieldNode(); - } - } - - public abstract static class WritePointerNode extends CStructAccessNode { - - protected abstract void execute(GraalHPyContext ctx, Object basePointer, long offset, Object valuePointer); - - public final void write(GraalHPyContext ctx, Object basePointer, GraalHPyCField field, Object valuePointer) { - // GR-50245 - // assert accepts(field); - execute(ctx, basePointer, ctx.getCFieldOffset(field), valuePointer); - } - - public final void write(GraalHPyContext ctx, Object basePointer, Object valuePointer) { - execute(ctx, basePointer, 0, valuePointer); - } - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return "POINTER".equals(desc.nfiType); - } - - @NeverDefault - public static WritePointerNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createWritePointerNode(); - } - - public static WritePointerNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedWritePointerNode(); - } - } - - public abstract static class WriteSizeTNode extends CStructAccessNode { - - protected abstract void execute(GraalHPyContext ctx, Object basePointer, long offset, long value); - - public final void write(GraalHPyContext ctx, Object basePointer, GraalHPyCField field, long value) { - // GR-50245 - // assert accepts(field); - execute(ctx, basePointer, ctx.getCFieldOffset(field), value); - } - - public final void write(GraalHPyContext ctx, Object basePointer, long value) { - execute(ctx, basePointer, 0, value); - } - - @Override - public final boolean accepts(HPyContextSignatureType desc) { - return desc == HPyContextSignatureType.Size_t || desc == HPyContextSignatureType.HPy_ssize_t; - } - - @NeverDefault - public static WriteSizeTNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createWriteSizeTNode(); - } - - public static WriteSizeTNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedWriteSizeTNode(); - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyCField.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyCField.java deleted file mode 100644 index ca7862c321..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyCField.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.CharPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.ConstCharPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Cpy_PyObjectPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPy; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyFunc_Signature; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPySlot_Slot; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyType_BuiltinShape; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPy_ssize_t; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Int; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Int32_t; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.PyType_SlotPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Uint32_t; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.VoidPtr; - -public enum GraalHPyCField { - HPyType_SpecParam__kind(Int32_t), - HPyType_SpecParam__object(HPy), - HPyType_Spec__name(ConstCharPtr), - HPyType_Spec__basicsize(Int32_t), - HPyType_Spec__itemsize(Int32_t), - HPyType_Spec__flags(Uint32_t), - HPyType_Spec__builtin_shape(HPyType_BuiltinShape), - HPyType_Spec__legacy_slots(PyType_SlotPtr), - HPyType_Spec__defines(VoidPtr), - HPyType_Spec__doc(ConstCharPtr), - HPyDef__kind(Int32_t), - HPyDef__meth__name(ConstCharPtr), - HPyDef__meth__impl(VoidPtr), - HPyDef__meth__signature(HPyFunc_Signature), - HPyDef__meth__doc(ConstCharPtr), - HPyDef__member__name(ConstCharPtr), - HPyDef__member__type(Int), - HPyDef__member__offset(HPy_ssize_t), - HPyDef__member__readonly(Int), - HPyDef__member__doc(ConstCharPtr), - HPyDef__getset__name(ConstCharPtr), - HPyDef__getset__getter_impl(VoidPtr), - HPyDef__getset__setter_impl(VoidPtr), - HPyDef__getset__doc(ConstCharPtr), - HPyDef__getset__closure(VoidPtr), - HPyDef__slot__slot(HPySlot_Slot), - HPyDef__slot__impl(VoidPtr), - PyType_Slot__slot(Int), - PyType_Slot__pfunc(VoidPtr), - HPyCapsule_Destructor__cpy_trampoline(VoidPtr), - HPyCapsule_Destructor__impl(VoidPtr), - HPyCallFunction__impl(VoidPtr), - HPyModuleDef__doc(ConstCharPtr), - HPyModuleDef__size(HPy_ssize_t), - HPyModuleDef__legacy_methods(Cpy_PyObjectPtr), - HPyModuleDef__defines(VoidPtr), - HPyModuleDef__globals(VoidPtr), - PyGetSetDef__name(ConstCharPtr), - PyGetSetDef__get(VoidPtr), - PyGetSetDef__set(VoidPtr), - PyGetSetDef__doc(ConstCharPtr), - PyGetSetDef__closure(VoidPtr), - PyMemberDef__name(ConstCharPtr), - PyMemberDef__type(Int), - PyMemberDef__offset(HPy_ssize_t), - PyMemberDef__flags(Int), - PyMemberDef__doc(ConstCharPtr), - HPy_buffer__buf(VoidPtr), - HPy_buffer__obj(HPy), - HPy_buffer__len(HPy_ssize_t), - HPy_buffer__itemsize(HPy_ssize_t), - HPy_buffer__readonly(Int), - HPy_buffer__ndim(Int), - HPy_buffer__format(CharPtr), - HPy_buffer__shape(HPy_ssize_t), - HPy_buffer__strides(HPy_ssize_t), - HPy_buffer__suboffsets(HPy_ssize_t), - HPy_buffer__internal(VoidPtr); - - private final HPyContextSignatureType type; - - GraalHPyCField(HPyContextSignatureType type) { - this.type = type; - } - - public HPyContextSignatureType getType() { - return type; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContext.java deleted file mode 100644 index 5be72a0746..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContext.java +++ /dev/null @@ -1,1218 +0,0 @@ -/* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -// skip GIL -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import static com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.UNSAFE; -import static com.oracle.graal.python.util.PythonUtils.EMPTY_TRUFFLESTRING_ARRAY; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; -import static com.oracle.graal.python.util.PythonUtils.tsArray; - -import java.io.IOException; -import java.lang.invoke.VarHandle; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import java.util.logging.Level; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext; -import com.oracle.graal.python.builtins.objects.cext.common.CExtContext; -import com.oracle.graal.python.builtins.objects.cext.common.HandleStack; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ApiInitException; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ImportException; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyGetNativeSpacePointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.GraalHPyModuleCreateNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.GraalHPyModuleExecNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNIContext; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMContext; -import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis; -import com.oracle.graal.python.builtins.objects.frame.PFrame; -import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.function.Signature; -import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRootNode; -import com.oracle.graal.python.nodes.call.CallTargetInvokeNode; -import com.oracle.graal.python.nodes.call.GenericInvokeNode; -import com.oracle.graal.python.runtime.AsyncHandler; -import com.oracle.graal.python.runtime.GilNode; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonImageBuildOptions; -import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.runtime.PythonOptions.HPyBackendMode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.util.PythonSystemThreadTask; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.CompilerDirectives.ValueType; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.TruffleLanguage.Env; -import com.oracle.truffle.api.TruffleLogger; -import com.oracle.truffle.api.TruffleSafepoint; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.ArityException; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.interop.UnsupportedTypeException; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.profiles.LoopConditionProfile; -import com.oracle.truffle.api.strings.TruffleString; - -public final class GraalHPyContext extends CExtContext implements TruffleObject { - - // {{start autogen}} - public static final int HPY_ABI_VERSION = 0; - public static final int HPY_ABI_VERSION_MINOR = 0; - public static final String HPY_ABI_TAG = "hpy0"; - // {{end autogen}} - - private static final String J_HPY_INIT = "HPyInit_"; - private static final String J_HPY_MAJOR_VER_FUN = "get_required_hpy_major_version_"; - private static final String J_HPY_MINOR_VER_FUN = "get_required_hpy_minor_version_"; - private static final String LOGGER_HPY_NAME = "hpy"; - private static final String HPY_EXT = ".hpy"; - private static final TruffleLogger LOGGER = GraalHPyContext.getLogger(GraalHPyContext.class); - - public static final long SIZEOF_LONG = java.lang.Long.BYTES; - private static final long NATIVE_ARGUMENT_STACK_SIZE = 1 << 15; // 32 kB stack size - - // "blah.hpy123[-graalpy231-310].so" - private static final Pattern SO_NAME_PATTERN = Pattern.compile(".*" + Pattern.quote(HPY_EXT) + "(\\d+)(?:-[\\w-]+)?\\.so$"); - - public static TruffleLogger getLogger(Class clazz) { - return PythonLanguage.getLogger(LOGGER_HPY_NAME + "." + clazz.getSimpleName()); - } - - @TruffleBoundary - public static GraalHPyContext ensureHPyWasLoaded(Node node, PythonContext context, TruffleString name, TruffleString path) throws IOException, ApiInitException, ImportException { - if (!context.hasHPyContext()) { - /* - * TODO(fa): Currently, you can't have the HPy context without the C API context. This - * should eventually be possible but requires some refactoring. - */ - CApiContext.ensureCapiWasLoaded(node, context, name, path); - - try { - GraalHPyContext hPyContext = context.createHPyContext(GraalHPyLLVMContext.loadLLVMLibrary(context)); - assert hPyContext == context.getHPyContext(); - return hPyContext; - } catch (ApiInitException e) { - throw e; - } catch (Exception e) { - // we don't expect any other exception - throw CompilerDirectives.shouldNotReachHere(e); - } - } - return context.getHPyContext(); - } - - /** - * This method loads an HPy extension module and will initialize the corresponding native - * contexts if necessary. - * - * @param location The node that's requesting this operation. This is required for reporting - * correct source code location in case exceptions occur. - * @param context The Python context object. - * @param name The name of the module to load (also just required for creating appropriate error - * messages). - * @param path The path of the C extension module to load (usually something ending with - * {@code .so} or {@code .pyd} or similar). - * @param mode The mode (e.g. debug or trace) to use when loading the module. - * @return Pointer to the HPy module definition struct. - * @throws IOException If the specified file cannot be loaded. - * @throws ApiInitException If the corresponding native context could not be initialized. - * @throws ImportException If an exception occurred during C extension initialization. - */ - @TruffleBoundary - public static Object loadHPyModule(Node location, PythonContext context, TruffleString name, TruffleString path, Object spec, HPyMode mode) throws IOException, ApiInitException, ImportException { - - /* - * Unfortunately, we need eagerly initialize the HPy context because the ctors of the - * extension may already require some symbols defined in the HPy API or C API. - */ - GraalHPyContext hpyUniversalContext = GraalHPyContext.ensureHPyWasLoaded(location, context, name, path); - GraalHPyNativeContext backend = hpyUniversalContext.backend; - Object llvmLibrary = backend.loadExtensionLibrary(location, context, name, path); - String basename = getBaseName(name).toJavaStringUncached(); - String hpyInitFuncName = J_HPY_INIT + basename; - - // get_required_hpy_major_version_ - String hpyMajorVersionFuncName = J_HPY_MAJOR_VER_FUN + basename; - - // get_required_hpy_minor_version_ - String hpyMinorVersionFuncName = J_HPY_MINOR_VER_FUN + basename; - - HPyABIVersion abiVersion; - try { - abiVersion = backend.getHPyABIVersion(llvmLibrary, hpyMajorVersionFuncName, hpyMinorVersionFuncName); - } catch (Exception e) { - throw PRaiseNode.raiseUncached(location, PythonBuiltinClassType.RuntimeError, ErrorMessages.HPY_ERROR_LOADING_EXT_MODULE, - path, hpyMajorVersionFuncName, hpyMinorVersionFuncName, e.getMessage()); - } - - /* - * For now, we have only one major version but in the future at this point we would decide - * which HPyContext to create. - */ - if (abiVersion.major != HPY_ABI_VERSION || abiVersion.minor > HPY_ABI_VERSION_MINOR) { - throw PRaiseNode.raiseUncached(location, PythonBuiltinClassType.RuntimeError, ErrorMessages.HPY_ABI_VERSION_ERROR, - name, abiVersion.major, abiVersion.minor, HPY_ABI_VERSION, HPY_ABI_VERSION_MINOR); - } - - // Sanity check of the tag in the shared object filename - validateABITag(location, basename, path.toJavaStringUncached(), abiVersion); - - HPyMode saved = hpyUniversalContext.currentMode; - hpyUniversalContext.currentMode = mode; - try { - Object hpyModuleDefPtr = backend.initHPyModule(llvmLibrary, hpyInitFuncName, name, path, mode); - // HPy only supports multi-phase extension module initialization. - assert !(hpyModuleDefPtr instanceof PythonModule); - if (InteropLibrary.getUncached().isNull(hpyModuleDefPtr)) { - throw PRaiseNode.raiseUncached(location, PythonBuiltinClassType.RuntimeError, ErrorMessages.ERROR_LOADING_HPY_EXT_S_S, path, name); - } - - Object module = GraalHPyModuleCreateNodeGen.getUncached().execute(context.getHPyContext(), name, spec, hpyModuleDefPtr); - if (module instanceof PythonModule pythonModule) { - GraalHPyModuleExecNodeGen.getUncached().execute(location, context.getHPyContext(), pythonModule); - } - return module; - } catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) { - throw new ImportException(CExtContext.wrapJavaException(e, location), name, path, ErrorMessages.CANNOT_INITIALIZE_WITH, path, basename, ""); - } finally { - hpyUniversalContext.currentMode = saved; - } - } - - private static void validateABITag(Node location, String shortname, String soname, HPyABIVersion abiVersion) { - // assumes format: "blah.hpy123[-310].so" - Matcher matcher = SO_NAME_PATTERN.matcher(soname); - if (matcher.matches()) { - String abiTagVersion = matcher.group(1); - int abiTag = Integer.parseInt(abiTagVersion); - if (abiTag != abiVersion.major) { - throw PRaiseNode.raiseUncached(location, PythonBuiltinClassType.RuntimeError, ErrorMessages.HPY_ABI_TAG_MISMATCH, - shortname, soname, abiTag, abiVersion.major, abiVersion.minor); - } - // major version fits -> validation successful - return; - } - throw PRaiseNode.raiseUncached(location, PythonBuiltinClassType.RuntimeError, ErrorMessages.HPY_NO_ABI_TAG, - shortname, soname, abiVersion.major, abiVersion.minor); - } - - public Object createArgumentsArray(Object[] args) { - return backend.createArgumentsArray(args); - } - - public void freeArgumentsArray(Object argsArray) { - backend.freeArgumentsArray(argsArray); - } - - public long createNativeArguments(Object[] delegate) { - if (nativeArgumentsStack == 0) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - // we use 'getContext().getUnsafe()' because this will check if native access is allowed - nativeArgumentsStack = getContext().getUnsafe().allocateMemory(NATIVE_ARGUMENT_STACK_SIZE); - nativeArgumentStackTop = nativeArgumentsStack + NATIVE_ARGUMENT_STACK_SIZE; - } - long arraySize = delegate.length * SIZEOF_LONG; - if (nativeArgumentsStack + arraySize > nativeArgumentStackTop) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - String msg = String.format("overflow on native argument stack (requested size: %d bytes)", arraySize); - LOGGER.severe(msg); - throw new InternalError(msg); - } - long arrayPtr = nativeArgumentsStack; - nativeArgumentsStack += arraySize; - - for (int i = 0; i < delegate.length; i++) { - Object element = delegate[i]; - UNSAFE.putLong(arrayPtr + i * SIZEOF_LONG, pythonObjectAsBits(element)); - } - return arrayPtr; - } - - public void freeNativeArgumentsArray(int nargs) { - freeNativeArgumentsUntil(nativeArgumentsStack - nargs * SIZEOF_LONG); - } - - public void freeNativeArgumentsUntil(long basePtr) { - assert basePtr <= nativeArgumentsStack; - for (long cur = basePtr; cur < nativeArgumentsStack; cur += SIZEOF_LONG) { - long h = UNSAFE.getLong(cur); - if (GraalHPyBoxing.isBoxedHandle(h)) { - releaseHPyHandleForObject(GraalHPyBoxing.unboxHandle(h)); - } - } - nativeArgumentsStack = basePtr; - } - - @ValueType - public record HPyABIVersion(int major, int minor) { - } - - public interface HPyUpcall { - String getName(); - } - - /** - * Enum of C types used in the HPy API. These type names need to stay in sync with the - * declarations in 'hpytypes.h'. - */ - public enum LLVMType { - HPyFunc_noargs, - HPyFunc_o, - HPyFunc_varargs, - HPyFunc_keywords, - HPyFunc_unaryfunc, - HPyFunc_binaryfunc, - HPyFunc_ternaryfunc, - HPyFunc_inquiry, - HPyFunc_lenfunc, - HPyFunc_ssizeargfunc, - HPyFunc_ssizessizeargfunc, - HPyFunc_ssizeobjargproc, - HPyFunc_ssizessizeobjargproc, - HPyFunc_objobjargproc, - HPyFunc_freefunc, - HPyFunc_getattrfunc, - HPyFunc_getattrofunc, - HPyFunc_setattrfunc, - HPyFunc_setattrofunc, - HPyFunc_reprfunc, - HPyFunc_hashfunc, - HPyFunc_richcmpfunc, - HPyFunc_getiterfunc, - HPyFunc_iternextfunc, - HPyFunc_descrgetfunc, - HPyFunc_descrsetfunc, - HPyFunc_initproc, - HPyFunc_getter, - HPyFunc_setter, - HPyFunc_objobjproc, - HPyFunc_traverseproc, - HPyFunc_destructor, - HPyFunc_getbufferproc, - HPyFunc_releasebufferproc, - HPyFunc_destroyfunc, - HPyModule_init, - HPyModule_create - } - - public static final int IMMUTABLE_HANDLE_COUNT = 256; - - private Object[] hpyHandleTable; - private int nextHandle = 1; - - private Object[] hpyGlobalsTable = new Object[]{GraalHPyHandle.NULL_HANDLE_DELEGATE}; - private final HandleStack freeStack = new HandleStack(16); - private final GraalHPyNativeContext backend; - - /** - * This field mirrors value of {@link PythonOptions#HPyEnableJNIFastPaths}. We store it in this - * final field because the value is also used in non-PE code paths. - */ - final boolean useNativeFastPaths; - - /** - * This is set to the appropriate mode if an HPy extension is initialized (i.e. - * {@code HPyInit_*} is called) in, e.g., debug mode. The value is then used to create the right - * closures for down calls during module ({@code HPyModule_Create}) and type creation - * ({@code HPyType_FromSpec}). We need this because the debug context is just a wrapper around - * the universal context, so the module and type creation will look as normal. For reference on - * how other implementations do it: - *

    - * CPython stores the HPy context into global C variable {@code _ctx_for_trampolines} defined by - * {@code HPy_MODINIT}. This variable belongs to the HPy extension and the context is loaded - * from it when calling HPy extension functions. - *

    - *

    - * PyPy has a different structure but basically also uses a global state (see file - * {@code interp_hpy.py}). When initializing the module, the appropriate handle manager - * is used. The manager then decides which trampolines are used to call HPy extensions and the - * trampolines pick the appropriate context. - *

    - */ - private HPyMode currentMode = HPyMode.MODE_UNIVERSAL; - - /** - * Few well known Python objects that are also HPyContext constants are guaranteed to always get - * the same handle. - */ - public static final int SINGLETON_HANDLE_NONE = 1; - public static final int SINGLETON_HANDLE_NOT_IMPLEMENTED = 2; - public static final int SINGLETON_HANDLE_ELIPSIS = 3; - - /** - * The global reference queue is a list consisting of {@link GraalHPyHandleReference} objects. - * It is used to keep those objects (which are weak refs) alive until they are enqueued in the - * corresponding reference queue. The list instance referenced by this variable is exclusively - * owned by the main thread (i.e. the main thread may operate on the list without - * synchronization). The HPy reference cleaner thread (see - * {@link GraalHPyReferenceCleanerRunnable}) will consume this instance using an atomic - * {@code getAndSet} operation. At this point, the ownership is transferred to the cleaner - * thread. - */ - public final AtomicReference references = new AtomicReference<>(null); - private ReferenceQueue nativeSpaceReferenceQueue; - @CompilationFinal private RootCallTarget referenceCleanerCallTarget; - - private long nativeSpacePointers; - - private long nativeArgumentsStack = 0; - private long nativeArgumentStackTop = 0; - - private final ScheduledExecutorService scheduler; - - public GraalHPyContext(PythonContext context, Object hpyLibrary) throws ApiInitException { - super(context, hpyLibrary, false /* TODO: provide proper value */); - CompilerAsserts.neverPartOfCompilation(); - PythonLanguage language = context.getLanguage(); - int traceUpcallsInterval = language.getEngineOption(PythonOptions.HPyTraceUpcalls); - Boolean shouldUseNativeFastPaths = language.getEngineOption(PythonOptions.HPyEnableJNIFastPaths); - HPyBackendMode backendMode = language.getEngineOption(PythonOptions.HPyBackend); - - nextHandle = GraalHPyBoxing.SINGLETON_HANDLE_MAX + 1; - hpyHandleTable = new Object[IMMUTABLE_HANDLE_COUNT * 2]; - - // initialize singleton handles - hpyHandleTable[0] = GraalHPyHandle.NULL_HANDLE_DELEGATE; - hpyHandleTable[SINGLETON_HANDLE_NONE] = PNone.NONE; - hpyHandleTable[SINGLETON_HANDLE_NOT_IMPLEMENTED] = PNotImplemented.NOT_IMPLEMENTED; - hpyHandleTable[SINGLETON_HANDLE_ELIPSIS] = PEllipsis.INSTANCE; - - LOGGER.config("Using HPy backend:" + backendMode.name()); - if (backendMode == HPyBackendMode.JNI) { - if (!PythonImageBuildOptions.WITHOUT_JNI) { - this.useNativeFastPaths = shouldUseNativeFastPaths; - backend = new GraalHPyJNIContext(this, traceUpcallsInterval > 0); - } else { - throw new ApiInitException(ErrorMessages.HPY_CANNOT_USE_JNI_BACKEND); - } - } else if (backendMode == HPyBackendMode.NFI) { - throw new ApiInitException(ErrorMessages.HPY_NFI_NOT_YET_IMPLEMENTED); - } else if (backendMode == HPyBackendMode.LLVM) { - // TODO(fa): we currently don't use native fast paths with the LLVM backend - this.useNativeFastPaths = false; - backend = new GraalHPyLLVMContext(this, traceUpcallsInterval > 0); - } else { - throw new ApiInitException(ErrorMessages.HPY_UNKNOWN_BACKEND, TruffleString.fromJavaStringUncached(backendMode.name(), TS_ENCODING)); - } - - backend.initNativeContext(); - - // createMembers already assigns numeric handles to "singletons" - nextHandle = IMMUTABLE_HANDLE_COUNT; - - assert getHPyHandleForObject(PNone.NONE) == SINGLETON_HANDLE_NONE; - assert getHPyHandleForObject(PEllipsis.INSTANCE) == SINGLETON_HANDLE_ELIPSIS; - assert getHPyHandleForObject(PNotImplemented.NOT_IMPLEMENTED) == SINGLETON_HANDLE_NOT_IMPLEMENTED; - - if (traceUpcallsInterval > 0) { - scheduler = Executors.newScheduledThreadPool(1); - startUpcallsDaemon(traceUpcallsInterval); - } else { - scheduler = null; - } - } - - /** - * Reference cleaner action that will be executed by the {@link AsyncHandler}. - */ - private static final class GraalHPyHandleReferenceCleanerAction implements AsyncHandler.AsyncAction { - - private final GraalHPyHandleReference[] nativeObjectReferences; - - public GraalHPyHandleReferenceCleanerAction(GraalHPyHandleReference[] nativeObjectReferences) { - this.nativeObjectReferences = nativeObjectReferences; - } - - @Override - public void execute(PythonContext context) { - Object[] pArguments = PArguments.create(1); - PArguments.setArgument(pArguments, 0, nativeObjectReferences); - GenericInvokeNode.getUncached().execute(context.getHPyContext().getReferenceCleanerCallTarget(), pArguments); - } - } - - private RootCallTarget getReferenceCleanerCallTarget() { - if (referenceCleanerCallTarget == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - RootCallTarget localTarget = PythonUtils.getOrCreateCallTarget(new HPyNativeSpaceCleanerRootNode(getContext())); - VarHandle.storeStoreFence(); - referenceCleanerCallTarget = localTarget; - } - return referenceCleanerCallTarget; - } - - /** - * This is the HPy cleaner thread runnable. It will run in parallel to the main thread, collect - * references from the corresponding reference queue, and eventually call - * {@link HPyNativeSpaceCleanerRootNode}. For this, the cleaner thread consumes the - * {@link #references} list by exchanging it with an empty one (for a description of the - * exchanging process, see also {@link #references}). - */ - static final class GraalHPyReferenceCleanerRunnable extends PythonSystemThreadTask { - private static final TruffleLogger LOGGER = GraalHPyContext.getLogger(GraalHPyReferenceCleanerRunnable.class); - private final ReferenceQueue referenceQueue; - private GraalHPyHandleReference cleanerList; - - GraalHPyReferenceCleanerRunnable(ReferenceQueue referenceQueue) { - super("HPy reference cleaner", LOGGER); - this.referenceQueue = referenceQueue; - } - - @Override - public void doRun() { - PythonContext pythonContext = PythonContext.get(null); - PythonLanguage language = pythonContext.getLanguage(); - GraalHPyContext hPyContext = pythonContext.getHPyContext(); - RootCallTarget callTarget = hPyContext.getReferenceCleanerCallTarget(); - PDict dummyGlobals = pythonContext.factory().createDict(); - boolean isLoggable = LOGGER.isLoggable(Level.FINE); - /* - * Intentionally retrieve the thread state every time since this will kill the thread if - * shutting down. - */ - RootNode location = language.unavailableSafepointLocation; - while (!pythonContext.getThreadState(language).isShuttingDown()) { - Reference reference = TruffleSafepoint.setBlockedThreadInterruptibleFunction(location, ReferenceQueue::remove, referenceQueue); - ArrayList refs = new ArrayList<>(); - do { - if (reference instanceof GraalHPyHandleReference) { - refs.add((GraalHPyHandleReference) reference); - } - // consume all - reference = referenceQueue.poll(); - TruffleSafepoint.poll(location); - } while (reference != null); - - if (isLoggable) { - LOGGER.fine(PythonUtils.formatJString("Collected references: %d", refs.size())); - } - - /* - * To avoid race conditions, we take the whole references list such that we can - * solely process it. At this point, the references list is owned by the main thread - * and this will now transfer ownership to the cleaner thread. The list will be - * replaced by an empty list (which will then be owned by the main thread). - */ - GraalHPyHandleReference refList; - int retries = 0; - do { - /* - * If 'refList' is null then the main is currently updating it. So, we need to - * repeat until we get something. The written empty list will just be lost. - */ - refList = hPyContext.references.getAndSet(null); - } while (refList == null && retries++ < 3); - - if (!refs.isEmpty()) { - try { - Object[] arguments = PArguments.create(3); - PArguments.setGlobals(arguments, dummyGlobals); - PArguments.setException(arguments, PException.NO_EXCEPTION); - PArguments.setCallerFrameInfo(arguments, PFrame.Reference.EMPTY); - PArguments.setArgument(arguments, 0, refs.toArray(new GraalHPyHandleReference[0])); - PArguments.setArgument(arguments, 1, refList); - PArguments.setArgument(arguments, 2, cleanerList); - cleanerList = (GraalHPyHandleReference) CallTargetInvokeNode.invokeUncached(callTarget, arguments); - } catch (PException e) { - /* - * Since the cleaner thread is not running any Python code, we should never - * receive a Python exception. If it happens, consider that to be a problem - * (however, it is not fatal problem). - */ - e.materializeMessage(); - LOGGER.warning("HPy reference cleaner thread received a Python exception: " + e); - } - } - } - } - } - - /** - * Root node that actually runs the destroy functions for the native memory of unreachable - * Python objects. - */ - private static final class HPyNativeSpaceCleanerRootNode extends PRootNode { - private static final Signature SIGNATURE = new Signature(-1, false, -1, false, tsArray("refs"), EMPTY_TRUFFLESTRING_ARRAY); - private static final TruffleLogger LOGGER = GraalHPyContext.getLogger(HPyNativeSpaceCleanerRootNode.class); - - @Child private GraalHPyCAccess.BulkFreeHandleReferencesNode callBulkFree; - - private final LoopConditionProfile loopProfile = LoopConditionProfile.create(); - - HPyNativeSpaceCleanerRootNode(PythonContext context) { - super(context.getLanguage()); - } - - @Override - public Object execute(VirtualFrame frame) { - /* - * This node is not running any Python code in the sense that it does not run any code - * that would run in CPython's interpreter loop. So, we don't need to do a - * calleeContext.enter/exit since we should never get any Python exception. - */ - - GraalHPyHandleReference[] handleReferences = (GraalHPyHandleReference[]) PArguments.getArgument(frame, 0); - GraalHPyHandleReference refList = (GraalHPyHandleReference) PArguments.getArgument(frame, 1); - GraalHPyHandleReference oldRefList = (GraalHPyHandleReference) PArguments.getArgument(frame, 2); - long startTime = 0; - long middleTime = 0; - final int n = handleReferences.length; - boolean loggable = LOGGER.isLoggable(Level.FINE); - - if (loggable) { - startTime = System.currentTimeMillis(); - } - - GraalHPyContext context = PythonContext.get(this).getHPyContext(); - - // mark queued references as cleaned - loopProfile.profileCounted(n); - for (int i = 0; loopProfile.inject(i < n); i++) { - handleReferences[i].cleaned = true; - } - - // remove marked references from the global reference list such that they can die - GraalHPyHandleReference prev = null; - for (GraalHPyHandleReference cur = refList; cur != null; cur = cur.next) { - if (cur.cleaned) { - if (prev != null) { - prev.next = cur.next; - } else { - // new head - refList = cur.next; - } - } else { - prev = cur; - } - } - - /* - * Merge the received reference list into the existing one or just take it if there - * wasn't one before. - */ - if (prev != null) { - // if prev exists, it now points to the tail - prev.next = oldRefList; - } else { - refList = oldRefList; - } - - if (loggable) { - middleTime = System.currentTimeMillis(); - } - - if (callBulkFree == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - callBulkFree = insert(GraalHPyCAccess.BulkFreeHandleReferencesNode.create(context)); - } - callBulkFree.execute(context, handleReferences); - - if (loggable) { - final long countDuration = middleTime - startTime; - final long duration = System.currentTimeMillis() - middleTime; - LOGGER.fine(PythonUtils.formatJString("Cleaned references: %d", n)); - LOGGER.fine(PythonUtils.formatJString("Count duration: %d", countDuration)); - LOGGER.fine(PythonUtils.formatJString("Duration: %d", duration)); - } - return refList; - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - - @Override - public String getName() { - return "hpy_native_reference_cleaner"; - } - - @Override - public boolean isInternal() { - return true; - } - - @Override - public boolean isPythonInternal() { - return true; - } - } - - public void initHPyDebugContext() throws ApiInitException { - backend.initHPyDebugContext(); - } - - public PythonModule getHPyDebugModule() throws ImportException { - return backend.getHPyDebugModule(); - } - - public PythonModule getHPyTraceModule() throws ImportException { - return backend.getHPyTraceModule(); - } - - HPyMode getCurrentMode() { - return currentMode; - } - - public GraalHPyNativeContext getBackend() { - return backend; - } - - @SuppressWarnings("static-method") - public GraalHPyHandle createHandle(Object delegate) { - return GraalHPyHandle.create(delegate); - } - - @SuppressWarnings("static-method") - public GraalHPyHandle createField(Object delegate, int idx) { - return GraalHPyHandle.createField(delegate, idx); - } - - public int createGlobal(Object delegate, int idx) { - assert !GilNode.getUncached().acquire(PythonContext.get(null)) : "Gil not held when creating global"; - final int newIdx; - if (idx <= 0) { - newIdx = allocateHPyGlobal(); - } else { - newIdx = idx; - } - hpyGlobalsTable[newIdx] = delegate; - if (useNativeFastPaths) { - mirrorGlobalNativeSpacePointerToNative(delegate, newIdx); - } - if (LOGGER.isLoggable(Level.FINER)) { - LOGGER.finer(PythonUtils.formatJString("allocating HPy global %d (object: %s)", newIdx, delegate)); - } - return newIdx; - } - - int getEndIndexOfGlobalTable() { - for (int i = hpyGlobalsTable.length - 1; i > 0; i--) { - if (hpyGlobalsTable[i] != null) { - return i + 1; - } - } - return hpyGlobalsTable.length; - } - - @TruffleBoundary - void initBatchGlobals(int startIdx, int nModuleGlobals) { - if (nModuleGlobals == 0) { - return; - } - int gtLen = hpyGlobalsTable.length; - int endIdx = startIdx + nModuleGlobals; - if (endIdx >= gtLen) { - int newSize = endIdx + 1; - LOGGER.fine(() -> PythonUtils.formatJString("resizing HPy globals table to %d", newSize)); - hpyGlobalsTable = Arrays.copyOf(hpyGlobalsTable, newSize); - if (useNativeFastPaths) { - reallocateNativeSpacePointersMirror(hpyHandleTable.length, gtLen); - } - } - Arrays.fill(hpyGlobalsTable, startIdx, endIdx, GraalHPyHandle.NULL_HANDLE_DELEGATE); - if (useNativeFastPaths) { - GraalHPyNativeCache.initGlobalsNativeSpacePointer(nativeSpacePointers, hpyHandleTable.length, startIdx, nModuleGlobals); - } - } - - @TruffleBoundary - private int allocateHPyGlobal() { - int handle = 0; - for (int i = 1; i < hpyGlobalsTable.length; i++) { - if (hpyGlobalsTable[i] == null) { - handle = i; - break; - } - } - if (handle == 0) { - // resize - handle = hpyGlobalsTable.length; - int newSize = Math.max(16, hpyGlobalsTable.length * 2); - LOGGER.fine(() -> "resizing HPy globals table to " + newSize); - hpyGlobalsTable = Arrays.copyOf(hpyGlobalsTable, newSize); - if (useNativeFastPaths) { - reallocateNativeSpacePointersMirror(hpyHandleTable.length, handle); - } - } - return handle; - } - - private int resizeHandleTable() { - CompilerAsserts.neverPartOfCompilation(); - assert nextHandle == hpyHandleTable.length; - int oldSize = hpyHandleTable.length; - int newSize = Math.max(16, hpyHandleTable.length * 2); - LOGGER.fine(() -> "resizing HPy handle table to " + newSize); - hpyHandleTable = Arrays.copyOf(hpyHandleTable, newSize); - if (useNativeFastPaths) { - reallocateNativeSpacePointersMirror(oldSize, hpyGlobalsTable.length); - } - return nextHandle++; - } - - public int getHPyHandleForObject(Object object) { - assert !(object instanceof GraalHPyHandle); - int singletonHandle = getHPyHandleForSingleton(object); - if (singletonHandle != -1) { - return singletonHandle; - } - return getHPyHandleForNonSingleton(object); - } - - public static int getHPyHandleForSingleton(Object object) { - assert !(object instanceof GraalHPyHandle); - return GetHPyHandleForSingleton.doGeneric(object); - } - - /** - * Allocates a handle for the given object. This method is intended to be used by the - * appropriate backend to initialize the context handles (i.e. handles available in - * {@code HPyContext *}; e.g. {@code HPyContext.h_None}). Following properties/restrictions - * apply: - *
      - *
    • This method *MUST NOT* be called after the context initialization was finished.
    • - *
    • The handles are not mirrored to the native cache even if {@link #useNativeFastPaths}. - * This should be done in a bulk operation after all context handles have been allocated.
    • - *
    • {@code object} must not be a singleton handle (i.e. - * {@link #getHPyHandleForSingleton(Object)} must return {@code -1}).
    • - *
    - */ - public int getHPyContextHandle(Object object) { - CompilerAsserts.neverPartOfCompilation(); - assert getHPyHandleForSingleton(object) == -1; - assert freeStack.getTop() == 0; - assert nextHandle < hpyHandleTable.length; - if (nextHandle >= IMMUTABLE_HANDLE_COUNT) { - throw CompilerDirectives.shouldNotReachHere("attempting to create context handle after initialization"); - } - int i = nextHandle++; - assert hpyHandleTable[i] == null; - hpyHandleTable[i] = object; - return i; - } - - public int getHPyHandleForNonSingleton(Object object) { - assert !(object instanceof GraalHPyHandle); - // find free association - - int handle = freeStack.pop(); - if (handle == -1) { - if (nextHandle < hpyHandleTable.length) { - handle = nextHandle++; - } else { - CompilerDirectives.transferToInterpreter(); - handle = resizeHandleTable(); - } - } - - assert 0 <= handle && handle < hpyHandleTable.length; - assert hpyHandleTable[handle] == null; - - hpyHandleTable[handle] = object; - if (useNativeFastPaths) { - mirrorNativeSpacePointerToNative(object, handle); - } - if (LOGGER.isLoggable(Level.FINER)) { - LOGGER.finer(PythonUtils.formatJString("allocating HPy handle %d (object: %s)", handle, object)); - } - return handle; - } - - public Object bitsAsPythonObject(long bits) { - if (GraalHPyBoxing.isBoxedNullHandle(bits)) { - return GraalHPyHandle.NULL_HANDLE_DELEGATE; - } else if (GraalHPyBoxing.isBoxedInt(bits)) { - return GraalHPyBoxing.unboxInt(bits); - } else if (GraalHPyBoxing.isBoxedDouble(bits)) { - return GraalHPyBoxing.unboxDouble(bits); - } - assert GraalHPyBoxing.isBoxedHandle(bits); - return getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(bits)); - } - - public long pythonObjectAsBits(Object object) { - if (GraalHPyBoxing.isBoxablePrimitive(object)) { - if (object instanceof Integer) { - return GraalHPyBoxing.boxInt((Integer) object); - } - assert object instanceof Double; - return GraalHPyBoxing.boxDouble((Double) object); - } else if (object == GraalHPyHandle.NULL_HANDLE_DELEGATE) { - return 0; - } - return getHPyHandleForObject(object); - } - - @GenerateUncached - @GenerateInline(false) - @ImportStatic(PGuards.class) - public abstract static class GetHPyHandleForSingleton extends Node { - public abstract int execute(Object delegateObject); - - @Specialization(guards = "isNoValue(x)") - static int doNoValue(@SuppressWarnings("unused") PNone x) { - return 0; - } - - @Specialization(guards = "!isNoValue(x)") - static int doNone(@SuppressWarnings("unused") PNone x) { - return SINGLETON_HANDLE_NONE; - } - - @Specialization - static int doEllipsis(@SuppressWarnings("unused") PEllipsis x) { - return SINGLETON_HANDLE_ELIPSIS; - } - - @Specialization - static int doNotImplemented(@SuppressWarnings("unused") PNotImplemented x) { - return SINGLETON_HANDLE_NOT_IMPLEMENTED; - } - - @Specialization(guards = "!isSingleton(delegate)") - static int doOthers(@SuppressWarnings("unused") Object delegate) { - return -1; - } - - @Specialization(replaces = {"doNoValue", "doNone", "doEllipsis", "doNotImplemented", "doOthers"}) - static int doGeneric(Object object) { - if (object == PNone.NO_VALUE) { - return 0; - } else if (object == PNone.NONE) { - return SINGLETON_HANDLE_NONE; - } else if (object == PEllipsis.INSTANCE) { - return SINGLETON_HANDLE_ELIPSIS; - } else if (object == PNotImplemented.NOT_IMPLEMENTED) { - return SINGLETON_HANDLE_NOT_IMPLEMENTED; - } - return -1; - } - - static boolean isSingleton(Object object) { - return object == PNone.NONE || object == PEllipsis.INSTANCE || object == PNotImplemented.NOT_IMPLEMENTED; - } - } - - @TruffleBoundary - private void mirrorNativeSpacePointerToNative(Object delegate, int handleID) { - assert useNativeFastPaths; - long l; - if (delegate instanceof PythonObject) { - Object nativeSpace = HPyGetNativeSpacePointerNode.doPythonObject((PythonObject) delegate); - try { - l = nativeSpace instanceof Long ? ((long) nativeSpace) : InteropLibrary.getUncached().asPointer(nativeSpace); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } else { - l = 0; - } - GraalHPyNativeCache.putHandleNativeSpacePointer(nativeSpacePointers, handleID, l); - } - - @TruffleBoundary - private void mirrorGlobalNativeSpacePointerToNative(Object delegate, int globalID) { - assert useNativeFastPaths; - long l; - if (delegate instanceof PythonObject) { - Object nativeSpace = HPyGetNativeSpacePointerNode.doPythonObject((PythonObject) delegate); - try { - l = nativeSpace instanceof Long ? ((long) nativeSpace) : InteropLibrary.getUncached().asPointer(nativeSpace); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } else { - l = 0; - } - GraalHPyNativeCache.putGlobalNativeSpacePointer(nativeSpacePointers, hpyHandleTable.length, globalID, l); - } - - @TruffleBoundary - private void reallocateNativeSpacePointersMirror(int oldHandleTabelSize, int oldGlobalsTableSize) { - assert useNativeFastPaths; - nativeSpacePointers = GraalHPyNativeCache.reallocateNativeCache(nativeSpacePointers, oldHandleTabelSize, hpyHandleTable.length, oldGlobalsTableSize, hpyGlobalsTable.length); - backend.setNativeCache(nativeSpacePointers); - } - - /** - * Allocates a native array (element size is {@link #SIZEOF_LONG} for as many elements as in - * {@link #hpyHandleTable} and writes the native space pointers of all objects in the handle - * table into this array. The pointer of the array is then set to - * {@code ((HPyContext) ctx)->_private} and meant to be used by the {@code ctx_Cast}'s upcall - * stub to avoid an expensive upcall. - */ - @TruffleBoundary - void allocateNativeSpacePointersMirror() { - long arrayPtr = GraalHPyNativeCache.allocateNativeCache(hpyHandleTable.length, hpyGlobalsTable.length); - - // publish pointer value (needed for initialization) - nativeSpacePointers = arrayPtr; - - // write existing values to mirror; start at 1 to omit the NULL handle - for (int i = 1; i < hpyHandleTable.length; i++) { - Object delegate = hpyHandleTable[i]; - if (delegate != null) { - mirrorNativeSpacePointerToNative(delegate, i); - } - } - - // commit pointer value for native usage - backend.setNativeCache(arrayPtr); - } - - public Object getObjectForHPyHandle(int handle) { - // GR-50245 - // assert !GilNode.getUncached().acquire(PythonContext.get(null)) : "Gil not held when - // resolving object from handle"; - assert !GraalHPyBoxing.isBoxedInt(handle) && !GraalHPyBoxing.isBoxedDouble(handle) : "trying to lookup boxed primitive"; - return hpyHandleTable[handle]; - } - - public Object getObjectForHPyGlobal(int handle) { - // GR-50245 - // assert !GilNode.getUncached().acquire(PythonContext.get(null)) : "Gil not held when - // resolving object from global"; - assert !GraalHPyBoxing.isBoxedInt(handle) && !GraalHPyBoxing.isBoxedDouble(handle) : "trying to lookup boxed primitive"; - return hpyGlobalsTable[handle]; - } - - public boolean releaseHPyHandleForObject(int handle) { - // GR-50245 - // assert !GilNode.getUncached().acquire(PythonContext.get(null)) : "Gil not held when - // releasing handle"; - assert handle != 0 : "NULL handle cannot be released"; - assert hpyHandleTable[handle] != null : PythonUtils.formatJString("releasing handle that has already been released: %d", handle); - if (LOGGER.isLoggable(Level.FINER)) { - LOGGER.finer(PythonUtils.formatJString("releasing HPy handle %d (object: %s)", handle, hpyHandleTable[handle])); - } - if (handle < IMMUTABLE_HANDLE_COUNT) { - return false; - } - hpyHandleTable[handle] = null; - freeStack.push(handle); - return true; - } - - /** - * A weak reference to an object that has an associated HPy native space ( - * {@link PythonHPyObject}). - */ - public static final class GraalHPyHandleReference extends WeakReference { - - private final Object nativeSpace; - private final Object destroyFunc; - - boolean cleaned; - private GraalHPyHandleReference next; - - public GraalHPyHandleReference(Object referent, ReferenceQueue q, Object nativeSpace, Object destroyFunc) { - super(referent, q); - this.nativeSpace = nativeSpace; - this.destroyFunc = destroyFunc; - } - - public Object getNativeSpace() { - return nativeSpace; - } - - public Object getDestroyFunc() { - return destroyFunc; - } - - public GraalHPyHandleReference getNext() { - return next; - } - - public void setNext(GraalHPyHandleReference next) { - this.next = next; - } - } - - /** - * Registers an HPy native space of a Python object.
    - * Use this method to register a native memory that is associated with a Python object in order - * to ensure that the native memory will be free'd when the owning Python object dies.
    - * This works by creating a weak reference to the Python object, using a thread that - * concurrently polls the reference queue. If threading is allowed, cleaning will be done fully - * concurrent on a cleaner thread. If not, an async action will be scheduled to free the native - * memory. Hence, the destroy function could also be executed on the cleaner thread. - * - * @param pythonObject The Python object that has associated native memory. - * @param dataPtr The pointer object of the native memory. - * @param destroyFunc The destroy function to call when the Python object is unreachable (may be - * {@code null}; in this case, bare {@code free} will be used). - */ - @TruffleBoundary - public void createHandleReference(Object pythonObject, Object dataPtr, Object destroyFunc) { - GraalHPyHandleReference newHead = new GraalHPyHandleReference(pythonObject, ensureReferenceQueue(), dataPtr, destroyFunc); - references.getAndAccumulate(newHead, (prev, x) -> { - x.next = prev; - return x; - }); - } - - private ReferenceQueue ensureReferenceQueue() { - if (nativeSpaceReferenceQueue == null) { - ReferenceQueue referenceQueue = createReferenceQueue(); - nativeSpaceReferenceQueue = referenceQueue; - return referenceQueue; - } - return nativeSpaceReferenceQueue; - } - - @TruffleBoundary - private ReferenceQueue createReferenceQueue() { - final ReferenceQueue referenceQueue = new ReferenceQueue<>(); - - // lazily register the runnable that concurrently collects the queued references - PythonContext context = getContext(); - Env env = context.getEnv(); - if (env.isCreateThreadAllowed()) { - context.createSystemThread(new GraalHPyReferenceCleanerRunnable(referenceQueue)).start(); - } else { - context.registerAsyncAction(() -> { - Reference reference = null; - if (PythonOptions.AUTOMATIC_ASYNC_ACTIONS) { - try { - reference = referenceQueue.remove(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } else { - referenceQueue.poll(); - } - - ArrayList refs = new ArrayList<>(); - do { - if (reference instanceof GraalHPyHandleReference) { - refs.add((GraalHPyHandleReference) reference); - } - // consume all - reference = referenceQueue.poll(); - } while (reference != null); - - if (!refs.isEmpty()) { - return new GraalHPyHandleReferenceCleanerAction(refs.toArray(new GraalHPyHandleReference[0])); - } - - return null; - }); - } - return referenceQueue; - } - - public int getCTypeSize(HPyContextSignatureType ctype) { - return backend.getCTypeSize(ctype); - } - - public int getCFieldOffset(GraalHPyCField ctype) { - return backend.getCFieldOffset(ctype); - } - - public Object nativeToInteropPointer(Object object) { - return backend.nativeToInteropPointer(object); - } - - public Object getNativeNull() { - return backend.getNativeNull(); - } - - /** - * Join the reference cleaner thread. - */ - public void finalizeContext() { - backend.finalizeNativeContext(); - if (nativeArgumentsStack != 0) { - UNSAFE.freeMemory(nativeArgumentsStack); - nativeArgumentsStack = 0; - } - if (scheduler != null) { - scheduler.shutdown(); - } - } - - private void startUpcallsDaemon(long interval) { - scheduler.scheduleAtFixedRate(() -> { - HPyUpcall[] upcalls = backend.getUpcalls(); - int[] counts = backend.getUpcallCounts(); - StringBuilder sb = new StringBuilder(); - sb.append("========= HPy context upcall counts (").append(backend.getName()).append(')'); - for (int i = 0; i < counts.length; i++) { - if (counts[i] != 0) { - sb.append(String.format(" %40s[%3d]: %d\n", upcalls[i].getName(), i, counts[i])); - } - } - System.out.print(sb); - System.out.flush(); - }, interval, interval, TimeUnit.MILLISECONDS); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContextFunctions.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContextFunctions.java deleted file mode 100644 index dcbf20b84b..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContextFunctions.java +++ /dev/null @@ -1,3711 +0,0 @@ -/* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.OverflowError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.RuntimeWarning; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPyType_BUILTIN_SHAPE_FLOAT; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPyType_BUILTIN_SHAPE_LEGACY; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPyType_BUILTIN_SHAPE_LIST; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPyType_BUILTIN_SHAPE_LONG; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPyType_BUILTIN_SHAPE_OBJECT; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPyType_BUILTIN_SHAPE_TUPLE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPyType_BUILTIN_SHAPE_TYPE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPyType_BUILTIN_SHAPE_UNICODE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyHandle.NULL_HANDLE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyHandle.NULL_HANDLE_DELEGATE; -import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; -import static com.oracle.graal.python.nodes.StringLiterals.T_STRICT; -import static com.oracle.graal.python.nodes.StringLiterals.T_UTF8; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; -import static com.oracle.graal.python.util.PythonUtils.tsLiteral; - -import java.io.PrintWriter; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.nio.charset.CharacterCodingException; -import java.nio.charset.Charset; -import java.nio.charset.CodingErrorAction; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.logging.Level; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.Python3Core; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.modules.CodecsModuleBuiltins; -import com.oracle.graal.python.builtins.modules.SysModuleBuiltins.GetFileSystemEncodingNode; -import com.oracle.graal.python.builtins.modules.WarningsModuleBuiltins.WarnNode; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.bytes.PBytes; -import com.oracle.graal.python.builtins.objects.capsule.PyCapsule; -import com.oracle.graal.python.builtins.objects.capsule.PyCapsuleNameMatchesNode; -import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.FromCharPointerNode; -import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.FromCharPointerNodeGen; -import com.oracle.graal.python.builtins.objects.cext.capi.PySequenceArrayWrapper; -import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonNode; -import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNewRefNode; -import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CByteArrayWrapper; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.AsNativePrimitiveNode; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.ClearCurrentExceptionNode; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.EncodeNativeStringNode; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.ReadUnicodeArrayNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyArithmeticNode.HPyBinaryArithmeticNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyArithmeticNode.HPyInplaceArithmeticNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyArithmeticNode.HPyTernaryArithmeticNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyArithmeticNode.HPyUnaryArithmeticNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyASCIINodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyAbsoluteNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyAddNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyAndNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyAsIndexNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyAsPyObjectNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyBoolFromBoolNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyBuilderCancelNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyBuilderNewNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyBuilderSetNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyBytesAsStringNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyBytesCheckNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyBytesFromStringAndSizeNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyBytesFromStringNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyBytesGetSizeNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyBytesNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyCallMethodNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyCallNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyCallTupleDictNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyCapsuleGetNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyCapsuleIsValidNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyCapsuleNewNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyCapsuleSetNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyCastNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyCloseNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyCompileNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyContainsNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyContextVarGetNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyContextVarNewNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyContextVarSetNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyDelItemNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyDelItemSNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyDictCheckNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyDictCopyNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyDictKeysNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyDictNewNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyDivmodNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyDumpNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyDupNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyErrClearNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyErrExceptionMatchesNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyErrNoMemoryNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyErrOccurredNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyErrSetFromErrnoWithFilenameNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyErrSetFromErrnoWithFilenameObjectsNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyErrSetObjectNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyErrSetStringNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyErrWarnExNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyErrWriteUnraisableNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyEvalCodeNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyFatalErrorNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyFieldLoadNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyFieldStoreNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyFloatAsDoubleNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyFloatFromDoubleNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyFloatNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyFloorDivideNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyFromPyObjectNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyGetAttrNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyGetAttrSNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyGetItemNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyGetItemSNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyGlobalLoadNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyGlobalStoreNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyHasAttrNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyHasAttrSNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyHashNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyImportModuleNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyInPlaceAddNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyInPlaceAndNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyInPlaceFloorDivideNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyInPlaceLshiftNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyInPlaceMatrixMultiplyNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyInPlaceMultiplyNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyInPlaceOrNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyInPlacePowerNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyInPlaceRemainderNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyInPlaceRshiftNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyInPlaceSubtractNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyInPlaceTrueDivideNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyInPlaceXorNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyInvertNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyIsCallableNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyIsNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyIsNumberNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyIsTrueNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLeavePythonExecutionNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLengthNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyListAppendNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyListBuilderBuildNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyListCheckNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyListNewNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLongAsDoubleNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLongAsInt32NodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLongAsInt64NodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLongAsSsizeTNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLongAsUInt32MaskNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLongAsUInt32NodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLongAsUInt64MaskNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLongAsUInt64NodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLongFromInt32NodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLongFromInt64NodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLongFromUInt32NodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLongFromUInt64NodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLongNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyLshiftNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyMatrixMultiplyNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyMultiplyNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyNegativeNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyNewExceptionNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyNewExceptionWithDocNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyNewNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyOrNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyPositiveNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyPowerNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyReenterPythonExecutionNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyRemainderNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyReprNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyRichcompareBoolNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyRichcompareNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyRshiftNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPySetAttrNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPySetAttrSNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPySetCallFunctionNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPySetItemNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPySetItemSNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPySliceUnpackNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyStrNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPySubtractNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyTrackerAddNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyTrackerCleanupNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyTrackerForgetAllNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyTrackerNewNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyTrueDivideNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyTupleBuilderBuildNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyTupleCheckNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyTupleFromArrayNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyTypeCheckNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyTypeFromSpecNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyTypeGenericNewNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyTypeGetBuiltinShapeNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyTypeGetNameNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyTypeIsSubtypeNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyTypeNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyUnicodeAsASCIIStringNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyUnicodeAsLatin1StringNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyUnicodeAsUTF8AndSizeNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyUnicodeAsUTF8StringNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyUnicodeCheckNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyUnicodeDecodeASCIINodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyUnicodeDecodeCharsetAndSizeNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyUnicodeDecodeCharsetNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyUnicodeDecodeLatin1NodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyUnicodeEncodeFSDefaultNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyUnicodeFromEncodedObjectNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyUnicodeFromStringNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyUnicodeFromWcharNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyUnicodeReadCharNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyUnicodeSubstringNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctionsFactory.GraalHPyXorNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsHandleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsPythonObjectNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyCallHelperFunctionNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyCloseAndGetHandleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyCloseHandleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyCreateTypeFromSpecNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyEnsureHandleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyFieldLoadNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyFromCharPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyGetNativeSpacePointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyLongFromLong; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyPackKeywordArgsNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyReadCallFunctionNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyTypeGetNameNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.RecursiveExceptionMatches; -import com.oracle.graal.python.builtins.objects.cext.structs.CStructs; -import com.oracle.graal.python.builtins.objects.code.CodeNodes; -import com.oracle.graal.python.builtins.objects.code.PCode; -import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage; -import com.oracle.graal.python.builtins.objects.common.HashingStorage; -import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageCopy; -import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem; -import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageLen; -import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem; -import com.oracle.graal.python.builtins.objects.common.SequenceNodes; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.NoGeneralizationNode; -import com.oracle.graal.python.builtins.objects.contextvars.PContextVar; -import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.exception.GetEscapedExceptionNode; -import com.oracle.graal.python.builtins.objects.exception.GetUnreifiedExceptionNode; -import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.builtins.objects.ints.PInt; -import com.oracle.graal.python.builtins.objects.list.PList; -import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.builtins.objects.slice.PSlice; -import com.oracle.graal.python.builtins.objects.slice.PSlice.SliceInfo; -import com.oracle.graal.python.builtins.objects.slice.PSlice.SliceInfoLong; -import com.oracle.graal.python.builtins.objects.slice.SliceNodes; -import com.oracle.graal.python.builtins.objects.str.StringBuiltins.StrGetItemNodeWithSlice; -import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.type.PythonClass; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode; -import com.oracle.graal.python.lib.PyCallableCheckNode; -import com.oracle.graal.python.lib.PyDictKeys; -import com.oracle.graal.python.lib.PyExceptionInstanceCheckNode; -import com.oracle.graal.python.lib.PyFloatAsDoubleNode; -import com.oracle.graal.python.lib.PyLongAsDoubleNode; -import com.oracle.graal.python.lib.PyNumberCheckNode; -import com.oracle.graal.python.lib.PyNumberIndexNode; -import com.oracle.graal.python.lib.PyObjectDelItem; -import com.oracle.graal.python.lib.PyObjectGetAttr; -import com.oracle.graal.python.lib.PyObjectGetAttrO; -import com.oracle.graal.python.lib.PyObjectGetItem; -import com.oracle.graal.python.lib.PyObjectGetMethod; -import com.oracle.graal.python.lib.PyObjectIsTrueNode; -import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode; -import com.oracle.graal.python.lib.PyObjectSetAttr; -import com.oracle.graal.python.lib.PyObjectSetAttrO; -import com.oracle.graal.python.lib.PyObjectSetItem; -import com.oracle.graal.python.lib.PySequenceContainsNode; -import com.oracle.graal.python.lib.PyTupleSizeNode; -import com.oracle.graal.python.lib.PyUnicodeFromEncodedObject; -import com.oracle.graal.python.lib.PyUnicodeReadCharNode; -import com.oracle.graal.python.nodes.BuiltinNames; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.SpecialAttributeNames; -import com.oracle.graal.python.nodes.SpecialMethodNames; -import com.oracle.graal.python.nodes.WriteUnraisableNode; -import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode; -import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; -import com.oracle.graal.python.nodes.builtins.ListNodes; -import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.call.GenericInvokeNode; -import com.oracle.graal.python.nodes.call.special.CallTernaryMethodNode; -import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodNode; -import com.oracle.graal.python.nodes.classes.IsSubtypeNode; -import com.oracle.graal.python.nodes.expression.BinaryArithmetic; -import com.oracle.graal.python.nodes.expression.InplaceArithmetic; -import com.oracle.graal.python.nodes.expression.TernaryArithmetic; -import com.oracle.graal.python.nodes.expression.UnaryArithmetic; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; -import com.oracle.graal.python.nodes.object.IsNode; -import com.oracle.graal.python.nodes.statement.AbstractImportNode; -import com.oracle.graal.python.nodes.util.CannotCastException; -import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; -import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.GilNode; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode; -import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.runtime.sequence.PSequence; -import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; -import com.oracle.graal.python.util.CharsetMapping; -import com.oracle.graal.python.util.OverflowException; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.TruffleLogger; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.exception.AbstractTruffleException; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedBranchProfile; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; -import com.oracle.truffle.api.profiles.InlinedExactClassProfile; -import com.oracle.truffle.api.strings.InternalByteArray; -import com.oracle.truffle.api.strings.TruffleString; -import com.oracle.truffle.api.strings.TruffleString.Encoding; - -@SuppressWarnings("truffle-inlining") -public abstract class GraalHPyContextFunctions { - - @Retention(RetentionPolicy.RUNTIME) - public @interface HPyContextFunctions { - HPyContextFunction[] value(); - } - - /** - * Context function implementations are marked with this annotation. It is used to annotate a - * node with the name of the implemented context function. This information is further consumed - * to automatically generate the appropriate upcall path. - */ - @Retention(RetentionPolicy.RUNTIME) - @Repeatable(value = HPyContextFunctions.class) - public @interface HPyContextFunction { - - /** - * Name of this builtin - the name can be omitted, which will use the name of the class that - * this annotation is applied to. - */ - String value() default ""; - } - - public abstract static class GraalHPyContextFunction extends Node { - - public abstract Object execute(Object[] arguments); - - // {{start ctx func factory}} - // @formatter:off - // Checkstyle: stop - // DO NOT EDIT THIS PART! - // This part is automatically generated by hpy.tools.autogen.graalpy.autogen_ctx_function_factory - @NeverDefault - public static GraalHPyContextFunction create(HPyContextMember member) { - return switch (member) { - case CTX_DUP -> GraalHPyDupNodeGen.create(); - case CTX_CLOSE -> GraalHPyCloseNodeGen.create(); - case CTX_POSITIVE -> GraalHPyPositiveNodeGen.create(); - case CTX_NEGATIVE -> GraalHPyNegativeNodeGen.create(); - case CTX_INVERT -> GraalHPyInvertNodeGen.create(); - case CTX_ADD -> GraalHPyAddNodeGen.create(); - case CTX_SUBTRACT -> GraalHPySubtractNodeGen.create(); - case CTX_MULTIPLY -> GraalHPyMultiplyNodeGen.create(); - case CTX_MATRIXMULTIPLY -> GraalHPyMatrixMultiplyNodeGen.create(); - case CTX_FLOORDIVIDE -> GraalHPyFloorDivideNodeGen.create(); - case CTX_TRUEDIVIDE -> GraalHPyTrueDivideNodeGen.create(); - case CTX_REMAINDER -> GraalHPyRemainderNodeGen.create(); - case CTX_DIVMOD -> GraalHPyDivmodNodeGen.create(); - case CTX_AND -> GraalHPyAndNodeGen.create(); - case CTX_XOR -> GraalHPyXorNodeGen.create(); - case CTX_OR -> GraalHPyOrNodeGen.create(); - case CTX_LSHIFT -> GraalHPyLshiftNodeGen.create(); - case CTX_RSHIFT -> GraalHPyRshiftNodeGen.create(); - case CTX_POWER -> GraalHPyPowerNodeGen.create(); - case CTX_INPLACEADD -> GraalHPyInPlaceAddNodeGen.create(); - case CTX_INPLACESUBTRACT -> GraalHPyInPlaceSubtractNodeGen.create(); - case CTX_INPLACEMULTIPLY -> GraalHPyInPlaceMultiplyNodeGen.create(); - case CTX_INPLACEMATRIXMULTIPLY -> GraalHPyInPlaceMatrixMultiplyNodeGen.create(); - case CTX_INPLACEFLOORDIVIDE -> GraalHPyInPlaceFloorDivideNodeGen.create(); - case CTX_INPLACETRUEDIVIDE -> GraalHPyInPlaceTrueDivideNodeGen.create(); - case CTX_INPLACEREMAINDER -> GraalHPyInPlaceRemainderNodeGen.create(); - case CTX_INPLACEPOWER -> GraalHPyInPlacePowerNodeGen.create(); - case CTX_INPLACELSHIFT -> GraalHPyInPlaceLshiftNodeGen.create(); - case CTX_INPLACERSHIFT -> GraalHPyInPlaceRshiftNodeGen.create(); - case CTX_INPLACEAND -> GraalHPyInPlaceAndNodeGen.create(); - case CTX_INPLACEXOR -> GraalHPyInPlaceXorNodeGen.create(); - case CTX_INPLACEOR -> GraalHPyInPlaceOrNodeGen.create(); - case CTX_BOOL_FROMBOOL -> GraalHPyBoolFromBoolNodeGen.create(); - case CTX_LONG_FROMINT32_T -> GraalHPyLongFromInt32NodeGen.create(); - case CTX_LONG_FROMUINT32_T -> GraalHPyLongFromUInt32NodeGen.create(); - case CTX_LONG_FROMINT64_T, CTX_LONG_FROMSSIZE_T -> GraalHPyLongFromInt64NodeGen.create(); - case CTX_LONG_FROMUINT64_T, CTX_LONG_FROMSIZE_T -> GraalHPyLongFromUInt64NodeGen.create(); - case CTX_LONG_ASINT32_T -> GraalHPyLongAsInt32NodeGen.create(); - case CTX_LONG_ASUINT32_T -> GraalHPyLongAsUInt32NodeGen.create(); - case CTX_LONG_ASUINT32_TMASK -> GraalHPyLongAsUInt32MaskNodeGen.create(); - case CTX_LONG_ASINT64_T -> GraalHPyLongAsInt64NodeGen.create(); - case CTX_LONG_ASUINT64_T, CTX_LONG_ASSIZE_T, CTX_LONG_ASVOIDPTR -> GraalHPyLongAsUInt64NodeGen.create(); - case CTX_LONG_ASUINT64_TMASK -> GraalHPyLongAsUInt64MaskNodeGen.create(); - case CTX_LONG_ASSSIZE_T -> GraalHPyLongAsSsizeTNodeGen.create(); - case CTX_LONG_ASDOUBLE -> GraalHPyLongAsDoubleNodeGen.create(); - case CTX_DICT_NEW -> GraalHPyDictNewNodeGen.create(); - case CTX_LIST_NEW -> GraalHPyListNewNodeGen.create(); - case CTX_LIST_APPEND -> GraalHPyListAppendNodeGen.create(); - case CTX_FLOAT_FROMDOUBLE -> GraalHPyFloatFromDoubleNodeGen.create(); - case CTX_FLOAT_ASDOUBLE -> GraalHPyFloatAsDoubleNodeGen.create(); - case CTX_DICT_CHECK -> GraalHPyDictCheckNodeGen.create(); - case CTX_BYTES_CHECK -> GraalHPyBytesCheckNodeGen.create(); - case CTX_UNICODE_CHECK -> GraalHPyUnicodeCheckNodeGen.create(); - case CTX_TUPLE_CHECK -> GraalHPyTupleCheckNodeGen.create(); - case CTX_LIST_CHECK -> GraalHPyListCheckNodeGen.create(); - case CTX_ERR_NOMEMORY -> GraalHPyErrNoMemoryNodeGen.create(); - case CTX_ERR_SETOBJECT -> GraalHPyErrSetObjectNodeGen.create(); - case CTX_ERR_SETSTRING -> GraalHPyErrSetStringNodeGen.create(); - case CTX_ERR_SETFROMERRNOWITHFILENAME -> GraalHPyErrSetFromErrnoWithFilenameNodeGen.create(); - case CTX_ERR_SETFROMERRNOWITHFILENAMEOBJECTS -> GraalHPyErrSetFromErrnoWithFilenameObjectsNodeGen.create(); - case CTX_FATALERROR -> GraalHPyFatalErrorNodeGen.create(); - case CTX_ERR_OCCURRED -> GraalHPyErrOccurredNodeGen.create(); - case CTX_ERR_EXCEPTIONMATCHES -> GraalHPyErrExceptionMatchesNodeGen.create(); - case CTX_ERR_CLEAR -> GraalHPyErrClearNodeGen.create(); - case CTX_ERR_WARNEX -> GraalHPyErrWarnExNodeGen.create(); - case CTX_ERR_WRITEUNRAISABLE -> GraalHPyErrWriteUnraisableNodeGen.create(); - case CTX_UNICODE_ASUTF8STRING -> GraalHPyUnicodeAsUTF8StringNodeGen.create(); - case CTX_UNICODE_ASLATIN1STRING -> GraalHPyUnicodeAsLatin1StringNodeGen.create(); - case CTX_UNICODE_ASASCIISTRING -> GraalHPyUnicodeAsASCIIStringNodeGen.create(); - case CTX_UNICODE_ENCODEFSDEFAULT -> GraalHPyUnicodeEncodeFSDefaultNodeGen.create(); - case CTX_UNICODE_ASUTF8ANDSIZE -> GraalHPyUnicodeAsUTF8AndSizeNodeGen.create(); - case CTX_UNICODE_FROMSTRING -> GraalHPyUnicodeFromStringNodeGen.create(); - case CTX_UNICODE_FROMWIDECHAR -> GraalHPyUnicodeFromWcharNodeGen.create(); - case CTX_UNICODE_DECODEFSDEFAULT -> GraalHPyUnicodeDecodeCharsetNodeGen.create(); - case CTX_UNICODE_DECODEFSDEFAULTANDSIZE -> GraalHPyUnicodeDecodeCharsetAndSizeNodeGen.create(); - case CTX_UNICODE_DECODEASCII -> GraalHPyUnicodeDecodeASCIINodeGen.create(); - case CTX_UNICODE_DECODELATIN1 -> GraalHPyUnicodeDecodeLatin1NodeGen.create(); - case CTX_UNICODE_READCHAR -> GraalHPyUnicodeReadCharNodeGen.create(); - case CTX_ASPYOBJECT -> GraalHPyAsPyObjectNodeGen.create(); - case CTX_BYTES_ASSTRING, CTX_BYTES_AS_STRING -> GraalHPyBytesAsStringNodeGen.create(); - case CTX_BYTES_SIZE, CTX_BYTES_GET_SIZE -> GraalHPyBytesGetSizeNodeGen.create(); - case CTX_BYTES_FROMSTRING -> GraalHPyBytesFromStringNodeGen.create(); - case CTX_BYTES_FROMSTRINGANDSIZE -> GraalHPyBytesFromStringAndSizeNodeGen.create(); - case CTX_ISTRUE -> GraalHPyIsTrueNodeGen.create(); - case CTX_GETATTR -> GraalHPyGetAttrNodeGen.create(); - case CTX_GETATTR_S -> GraalHPyGetAttrSNodeGen.create(); - case CTX_TYPE_FROMSPEC -> GraalHPyTypeFromSpecNodeGen.create(); - case CTX_HASATTR -> GraalHPyHasAttrNodeGen.create(); - case CTX_HASATTR_S -> GraalHPyHasAttrSNodeGen.create(); - case CTX_SETATTR -> GraalHPySetAttrNodeGen.create(); - case CTX_SETATTR_S -> GraalHPySetAttrSNodeGen.create(); - case CTX_GETITEM, CTX_GETITEM_I -> GraalHPyGetItemNodeGen.create(); - case CTX_GETITEM_S -> GraalHPyGetItemSNodeGen.create(); - case CTX_SETITEM, CTX_SETITEM_I -> GraalHPySetItemNodeGen.create(); - case CTX_SETITEM_S -> GraalHPySetItemSNodeGen.create(); - case CTX_DELITEM, CTX_DELITEM_I -> GraalHPyDelItemNodeGen.create(); - case CTX_DELITEM_S -> GraalHPyDelItemSNodeGen.create(); - case CTX_FROMPYOBJECT -> GraalHPyFromPyObjectNodeGen.create(); - case CTX_NEW -> GraalHPyNewNodeGen.create(); - case CTX_ASSTRUCT_OBJECT, CTX_ASSTRUCT_LEGACY, CTX_ASSTRUCT_TYPE, CTX_ASSTRUCT_LONG, CTX_ASSTRUCT_FLOAT, CTX_ASSTRUCT_UNICODE, CTX_ASSTRUCT_TUPLE, CTX_ASSTRUCT_LIST -> GraalHPyCastNodeGen.create(); - case CTX_TYPE_GENERICNEW -> GraalHPyTypeGenericNewNodeGen.create(); - case CTX_ABSOLUTE -> GraalHPyAbsoluteNodeGen.create(); - case CTX_LONG -> GraalHPyLongNodeGen.create(); - case CTX_FLOAT -> GraalHPyFloatNodeGen.create(); - case CTX_STR -> GraalHPyStrNodeGen.create(); - case CTX_REPR -> GraalHPyReprNodeGen.create(); - case CTX_ASCII -> GraalHPyASCIINodeGen.create(); - case CTX_BYTES -> GraalHPyBytesNodeGen.create(); - case CTX_HASH -> GraalHPyHashNodeGen.create(); - case CTX_LENGTH -> GraalHPyLengthNodeGen.create(); - case CTX_RICHCOMPARE -> GraalHPyRichcompareNodeGen.create(); - case CTX_RICHCOMPAREBOOL -> GraalHPyRichcompareBoolNodeGen.create(); - case CTX_INDEX -> GraalHPyAsIndexNodeGen.create(); - case CTX_NUMBER_CHECK -> GraalHPyIsNumberNodeGen.create(); - case CTX_TUPLE_FROMARRAY -> GraalHPyTupleFromArrayNodeGen.create(); - case CTX_TUPLEBUILDER_NEW, CTX_LISTBUILDER_NEW -> GraalHPyBuilderNewNodeGen.create(); - case CTX_TUPLEBUILDER_SET, CTX_LISTBUILDER_SET -> GraalHPyBuilderSetNodeGen.create(); - case CTX_TUPLEBUILDER_BUILD -> GraalHPyTupleBuilderBuildNodeGen.create(); - case CTX_LISTBUILDER_BUILD -> GraalHPyListBuilderBuildNodeGen.create(); - case CTX_TUPLEBUILDER_CANCEL, CTX_LISTBUILDER_CANCEL -> GraalHPyBuilderCancelNodeGen.create(); - case CTX_TRACKER_NEW -> GraalHPyTrackerNewNodeGen.create(); - case CTX_TRACKER_ADD -> GraalHPyTrackerAddNodeGen.create(); - case CTX_TRACKER_CLOSE -> GraalHPyTrackerCleanupNodeGen.create(); - case CTX_TRACKER_FORGETALL -> GraalHPyTrackerForgetAllNodeGen.create(); - case CTX_CALLABLE_CHECK -> GraalHPyIsCallableNodeGen.create(); - case CTX_CALLTUPLEDICT -> GraalHPyCallTupleDictNodeGen.create(); - case CTX_CALL -> GraalHPyCallNodeGen.create(); - case CTX_CALLMETHOD -> GraalHPyCallMethodNodeGen.create(); - case CTX_DUMP -> GraalHPyDumpNodeGen.create(); - case CTX_TYPE -> GraalHPyTypeNodeGen.create(); - case CTX_TYPECHECK -> GraalHPyTypeCheckNodeGen.create(); - case CTX_ERR_NEWEXCEPTIONWITHDOC -> GraalHPyNewExceptionWithDocNodeGen.create(); - case CTX_ERR_NEWEXCEPTION -> GraalHPyNewExceptionNodeGen.create(); - case CTX_IS -> GraalHPyIsNodeGen.create(); - case CTX_IMPORT_IMPORTMODULE -> GraalHPyImportModuleNodeGen.create(); - case CTX_FIELD_STORE -> GraalHPyFieldStoreNodeGen.create(); - case CTX_FIELD_LOAD -> GraalHPyFieldLoadNodeGen.create(); - case CTX_GLOBAL_STORE -> GraalHPyGlobalStoreNodeGen.create(); - case CTX_GLOBAL_LOAD -> GraalHPyGlobalLoadNodeGen.create(); - case CTX_LEAVEPYTHONEXECUTION -> GraalHPyLeavePythonExecutionNodeGen.create(); - case CTX_REENTERPYTHONEXECUTION -> GraalHPyReenterPythonExecutionNodeGen.create(); - case CTX_CONTAINS -> GraalHPyContainsNodeGen.create(); - case CTX_TYPE_ISSUBTYPE -> GraalHPyTypeIsSubtypeNodeGen.create(); - case CTX_TYPE_GETNAME -> GraalHPyTypeGetNameNodeGen.create(); - case CTX_DICT_KEYS -> GraalHPyDictKeysNodeGen.create(); - case CTX_DICT_COPY -> GraalHPyDictCopyNodeGen.create(); - case CTX_CAPSULE_NEW -> GraalHPyCapsuleNewNodeGen.create(); - case CTX_CAPSULE_GET -> GraalHPyCapsuleGetNodeGen.create(); - case CTX_CAPSULE_SET -> GraalHPyCapsuleSetNodeGen.create(); - case CTX_CAPSULE_ISVALID -> GraalHPyCapsuleIsValidNodeGen.create(); - case CTX_CONTEXTVAR_NEW -> GraalHPyContextVarNewNodeGen.create(); - case CTX_CONTEXTVAR_GET -> GraalHPyContextVarGetNodeGen.create(); - case CTX_CONTEXTVAR_SET -> GraalHPyContextVarSetNodeGen.create(); - case CTX_UNICODE_FROMENCODEDOBJECT -> GraalHPyUnicodeFromEncodedObjectNodeGen.create(); - case CTX_UNICODE_SUBSTRING -> GraalHPyUnicodeSubstringNodeGen.create(); - case CTX_SLICE_UNPACK -> GraalHPySliceUnpackNodeGen.create(); - case CTX_TYPE_GETBUILTINSHAPE -> GraalHPyTypeGetBuiltinShapeNodeGen.create(); - case CTX_COMPILE_S -> GraalHPyCompileNodeGen.create(); - case CTX_EVALCODE -> GraalHPyEvalCodeNodeGen.create(); - case CTX_SETCALLFUNCTION -> GraalHPySetCallFunctionNodeGen.create(); - default -> throw CompilerDirectives.shouldNotReachHere(); - }; - } - - public static GraalHPyContextFunction getUncached(HPyContextMember member) { - return switch (member) { - case CTX_DUP -> GraalHPyDupNodeGen.getUncached(); - case CTX_CLOSE -> GraalHPyCloseNodeGen.getUncached(); - case CTX_POSITIVE -> GraalHPyPositiveNodeGen.getUncached(); - case CTX_NEGATIVE -> GraalHPyNegativeNodeGen.getUncached(); - case CTX_INVERT -> GraalHPyInvertNodeGen.getUncached(); - case CTX_ADD -> GraalHPyAddNodeGen.getUncached(); - case CTX_SUBTRACT -> GraalHPySubtractNodeGen.getUncached(); - case CTX_MULTIPLY -> GraalHPyMultiplyNodeGen.getUncached(); - case CTX_MATRIXMULTIPLY -> GraalHPyMatrixMultiplyNodeGen.getUncached(); - case CTX_FLOORDIVIDE -> GraalHPyFloorDivideNodeGen.getUncached(); - case CTX_TRUEDIVIDE -> GraalHPyTrueDivideNodeGen.getUncached(); - case CTX_REMAINDER -> GraalHPyRemainderNodeGen.getUncached(); - case CTX_DIVMOD -> GraalHPyDivmodNodeGen.getUncached(); - case CTX_AND -> GraalHPyAndNodeGen.getUncached(); - case CTX_XOR -> GraalHPyXorNodeGen.getUncached(); - case CTX_OR -> GraalHPyOrNodeGen.getUncached(); - case CTX_LSHIFT -> GraalHPyLshiftNodeGen.getUncached(); - case CTX_RSHIFT -> GraalHPyRshiftNodeGen.getUncached(); - case CTX_POWER -> GraalHPyPowerNodeGen.getUncached(); - case CTX_INPLACEADD -> GraalHPyInPlaceAddNodeGen.getUncached(); - case CTX_INPLACESUBTRACT -> GraalHPyInPlaceSubtractNodeGen.getUncached(); - case CTX_INPLACEMULTIPLY -> GraalHPyInPlaceMultiplyNodeGen.getUncached(); - case CTX_INPLACEMATRIXMULTIPLY -> GraalHPyInPlaceMatrixMultiplyNodeGen.getUncached(); - case CTX_INPLACEFLOORDIVIDE -> GraalHPyInPlaceFloorDivideNodeGen.getUncached(); - case CTX_INPLACETRUEDIVIDE -> GraalHPyInPlaceTrueDivideNodeGen.getUncached(); - case CTX_INPLACEREMAINDER -> GraalHPyInPlaceRemainderNodeGen.getUncached(); - case CTX_INPLACEPOWER -> GraalHPyInPlacePowerNodeGen.getUncached(); - case CTX_INPLACELSHIFT -> GraalHPyInPlaceLshiftNodeGen.getUncached(); - case CTX_INPLACERSHIFT -> GraalHPyInPlaceRshiftNodeGen.getUncached(); - case CTX_INPLACEAND -> GraalHPyInPlaceAndNodeGen.getUncached(); - case CTX_INPLACEXOR -> GraalHPyInPlaceXorNodeGen.getUncached(); - case CTX_INPLACEOR -> GraalHPyInPlaceOrNodeGen.getUncached(); - case CTX_BOOL_FROMBOOL -> GraalHPyBoolFromBoolNodeGen.getUncached(); - case CTX_LONG_FROMINT32_T -> GraalHPyLongFromInt32NodeGen.getUncached(); - case CTX_LONG_FROMUINT32_T -> GraalHPyLongFromUInt32NodeGen.getUncached(); - case CTX_LONG_FROMINT64_T, CTX_LONG_FROMSSIZE_T -> GraalHPyLongFromInt64NodeGen.getUncached(); - case CTX_LONG_FROMUINT64_T, CTX_LONG_FROMSIZE_T -> GraalHPyLongFromUInt64NodeGen.getUncached(); - case CTX_LONG_ASINT32_T -> GraalHPyLongAsInt32NodeGen.getUncached(); - case CTX_LONG_ASUINT32_T -> GraalHPyLongAsUInt32NodeGen.getUncached(); - case CTX_LONG_ASUINT32_TMASK -> GraalHPyLongAsUInt32MaskNodeGen.getUncached(); - case CTX_LONG_ASINT64_T -> GraalHPyLongAsInt64NodeGen.getUncached(); - case CTX_LONG_ASUINT64_T, CTX_LONG_ASSIZE_T, CTX_LONG_ASVOIDPTR -> GraalHPyLongAsUInt64NodeGen.getUncached(); - case CTX_LONG_ASUINT64_TMASK -> GraalHPyLongAsUInt64MaskNodeGen.getUncached(); - case CTX_LONG_ASSSIZE_T -> GraalHPyLongAsSsizeTNodeGen.getUncached(); - case CTX_LONG_ASDOUBLE -> GraalHPyLongAsDoubleNodeGen.getUncached(); - case CTX_DICT_NEW -> GraalHPyDictNewNodeGen.getUncached(); - case CTX_LIST_NEW -> GraalHPyListNewNodeGen.getUncached(); - case CTX_LIST_APPEND -> GraalHPyListAppendNodeGen.getUncached(); - case CTX_FLOAT_FROMDOUBLE -> GraalHPyFloatFromDoubleNodeGen.getUncached(); - case CTX_FLOAT_ASDOUBLE -> GraalHPyFloatAsDoubleNodeGen.getUncached(); - case CTX_DICT_CHECK -> GraalHPyDictCheckNodeGen.getUncached(); - case CTX_BYTES_CHECK -> GraalHPyBytesCheckNodeGen.getUncached(); - case CTX_UNICODE_CHECK -> GraalHPyUnicodeCheckNodeGen.getUncached(); - case CTX_TUPLE_CHECK -> GraalHPyTupleCheckNodeGen.getUncached(); - case CTX_LIST_CHECK -> GraalHPyListCheckNodeGen.getUncached(); - case CTX_ERR_NOMEMORY -> GraalHPyErrNoMemoryNodeGen.getUncached(); - case CTX_ERR_SETOBJECT -> GraalHPyErrSetObjectNodeGen.getUncached(); - case CTX_ERR_SETSTRING -> GraalHPyErrSetStringNodeGen.getUncached(); - case CTX_ERR_SETFROMERRNOWITHFILENAME -> GraalHPyErrSetFromErrnoWithFilenameNodeGen.getUncached(); - case CTX_ERR_SETFROMERRNOWITHFILENAMEOBJECTS -> GraalHPyErrSetFromErrnoWithFilenameObjectsNodeGen.getUncached(); - case CTX_FATALERROR -> GraalHPyFatalErrorNodeGen.getUncached(); - case CTX_ERR_OCCURRED -> GraalHPyErrOccurredNodeGen.getUncached(); - case CTX_ERR_EXCEPTIONMATCHES -> GraalHPyErrExceptionMatchesNodeGen.getUncached(); - case CTX_ERR_CLEAR -> GraalHPyErrClearNodeGen.getUncached(); - case CTX_ERR_WARNEX -> GraalHPyErrWarnExNodeGen.getUncached(); - case CTX_ERR_WRITEUNRAISABLE -> GraalHPyErrWriteUnraisableNodeGen.getUncached(); - case CTX_UNICODE_ASUTF8STRING -> GraalHPyUnicodeAsUTF8StringNodeGen.getUncached(); - case CTX_UNICODE_ASLATIN1STRING -> GraalHPyUnicodeAsLatin1StringNodeGen.getUncached(); - case CTX_UNICODE_ASASCIISTRING -> GraalHPyUnicodeAsASCIIStringNodeGen.getUncached(); - case CTX_UNICODE_ENCODEFSDEFAULT -> GraalHPyUnicodeEncodeFSDefaultNodeGen.getUncached(); - case CTX_UNICODE_ASUTF8ANDSIZE -> GraalHPyUnicodeAsUTF8AndSizeNodeGen.getUncached(); - case CTX_UNICODE_FROMSTRING -> GraalHPyUnicodeFromStringNodeGen.getUncached(); - case CTX_UNICODE_FROMWIDECHAR -> GraalHPyUnicodeFromWcharNodeGen.getUncached(); - case CTX_UNICODE_DECODEFSDEFAULT -> GraalHPyUnicodeDecodeCharsetNodeGen.getUncached(); - case CTX_UNICODE_DECODEFSDEFAULTANDSIZE -> GraalHPyUnicodeDecodeCharsetAndSizeNodeGen.getUncached(); - case CTX_UNICODE_DECODEASCII -> GraalHPyUnicodeDecodeASCIINodeGen.getUncached(); - case CTX_UNICODE_DECODELATIN1 -> GraalHPyUnicodeDecodeLatin1NodeGen.getUncached(); - case CTX_UNICODE_READCHAR -> GraalHPyUnicodeReadCharNodeGen.getUncached(); - case CTX_ASPYOBJECT -> GraalHPyAsPyObjectNodeGen.getUncached(); - case CTX_BYTES_ASSTRING, CTX_BYTES_AS_STRING -> GraalHPyBytesAsStringNodeGen.getUncached(); - case CTX_BYTES_SIZE, CTX_BYTES_GET_SIZE -> GraalHPyBytesGetSizeNodeGen.getUncached(); - case CTX_BYTES_FROMSTRING -> GraalHPyBytesFromStringNodeGen.getUncached(); - case CTX_BYTES_FROMSTRINGANDSIZE -> GraalHPyBytesFromStringAndSizeNodeGen.getUncached(); - case CTX_ISTRUE -> GraalHPyIsTrueNodeGen.getUncached(); - case CTX_GETATTR -> GraalHPyGetAttrNodeGen.getUncached(); - case CTX_GETATTR_S -> GraalHPyGetAttrSNodeGen.getUncached(); - case CTX_TYPE_FROMSPEC -> GraalHPyTypeFromSpecNodeGen.getUncached(); - case CTX_HASATTR -> GraalHPyHasAttrNodeGen.getUncached(); - case CTX_HASATTR_S -> GraalHPyHasAttrSNodeGen.getUncached(); - case CTX_SETATTR -> GraalHPySetAttrNodeGen.getUncached(); - case CTX_SETATTR_S -> GraalHPySetAttrSNodeGen.getUncached(); - case CTX_GETITEM, CTX_GETITEM_I -> GraalHPyGetItemNodeGen.getUncached(); - case CTX_GETITEM_S -> GraalHPyGetItemSNodeGen.getUncached(); - case CTX_SETITEM, CTX_SETITEM_I -> GraalHPySetItemNodeGen.getUncached(); - case CTX_SETITEM_S -> GraalHPySetItemSNodeGen.getUncached(); - case CTX_DELITEM, CTX_DELITEM_I -> GraalHPyDelItemNodeGen.getUncached(); - case CTX_DELITEM_S -> GraalHPyDelItemSNodeGen.getUncached(); - case CTX_FROMPYOBJECT -> GraalHPyFromPyObjectNodeGen.getUncached(); - case CTX_NEW -> GraalHPyNewNodeGen.getUncached(); - case CTX_ASSTRUCT_OBJECT, CTX_ASSTRUCT_LEGACY, CTX_ASSTRUCT_TYPE, CTX_ASSTRUCT_LONG, CTX_ASSTRUCT_FLOAT, CTX_ASSTRUCT_UNICODE, CTX_ASSTRUCT_TUPLE, CTX_ASSTRUCT_LIST -> GraalHPyCastNodeGen.getUncached(); - case CTX_TYPE_GENERICNEW -> GraalHPyTypeGenericNewNodeGen.getUncached(); - case CTX_ABSOLUTE -> GraalHPyAbsoluteNodeGen.getUncached(); - case CTX_LONG -> GraalHPyLongNodeGen.getUncached(); - case CTX_FLOAT -> GraalHPyFloatNodeGen.getUncached(); - case CTX_STR -> GraalHPyStrNodeGen.getUncached(); - case CTX_REPR -> GraalHPyReprNodeGen.getUncached(); - case CTX_ASCII -> GraalHPyASCIINodeGen.getUncached(); - case CTX_BYTES -> GraalHPyBytesNodeGen.getUncached(); - case CTX_HASH -> GraalHPyHashNodeGen.getUncached(); - case CTX_LENGTH -> GraalHPyLengthNodeGen.getUncached(); - case CTX_RICHCOMPARE -> GraalHPyRichcompareNodeGen.getUncached(); - case CTX_RICHCOMPAREBOOL -> GraalHPyRichcompareBoolNodeGen.getUncached(); - case CTX_INDEX -> GraalHPyAsIndexNodeGen.getUncached(); - case CTX_NUMBER_CHECK -> GraalHPyIsNumberNodeGen.getUncached(); - case CTX_TUPLE_FROMARRAY -> GraalHPyTupleFromArrayNodeGen.getUncached(); - case CTX_TUPLEBUILDER_NEW, CTX_LISTBUILDER_NEW -> GraalHPyBuilderNewNodeGen.getUncached(); - case CTX_TUPLEBUILDER_SET, CTX_LISTBUILDER_SET -> GraalHPyBuilderSetNodeGen.getUncached(); - case CTX_TUPLEBUILDER_BUILD -> GraalHPyTupleBuilderBuildNodeGen.getUncached(); - case CTX_LISTBUILDER_BUILD -> GraalHPyListBuilderBuildNodeGen.getUncached(); - case CTX_TUPLEBUILDER_CANCEL, CTX_LISTBUILDER_CANCEL -> GraalHPyBuilderCancelNodeGen.getUncached(); - case CTX_TRACKER_NEW -> GraalHPyTrackerNewNodeGen.getUncached(); - case CTX_TRACKER_ADD -> GraalHPyTrackerAddNodeGen.getUncached(); - case CTX_TRACKER_CLOSE -> GraalHPyTrackerCleanupNodeGen.getUncached(); - case CTX_TRACKER_FORGETALL -> GraalHPyTrackerForgetAllNodeGen.getUncached(); - case CTX_CALLABLE_CHECK -> GraalHPyIsCallableNodeGen.getUncached(); - case CTX_CALLTUPLEDICT -> GraalHPyCallTupleDictNodeGen.getUncached(); - case CTX_CALL -> GraalHPyCallNodeGen.getUncached(); - case CTX_CALLMETHOD -> GraalHPyCallMethodNodeGen.getUncached(); - case CTX_DUMP -> GraalHPyDumpNodeGen.getUncached(); - case CTX_TYPE -> GraalHPyTypeNodeGen.getUncached(); - case CTX_TYPECHECK -> GraalHPyTypeCheckNodeGen.getUncached(); - case CTX_ERR_NEWEXCEPTIONWITHDOC -> GraalHPyNewExceptionWithDocNodeGen.getUncached(); - case CTX_ERR_NEWEXCEPTION -> GraalHPyNewExceptionNodeGen.getUncached(); - case CTX_IS -> GraalHPyIsNodeGen.getUncached(); - case CTX_IMPORT_IMPORTMODULE -> GraalHPyImportModuleNodeGen.getUncached(); - case CTX_FIELD_STORE -> GraalHPyFieldStoreNodeGen.getUncached(); - case CTX_FIELD_LOAD -> GraalHPyFieldLoadNodeGen.getUncached(); - case CTX_GLOBAL_STORE -> GraalHPyGlobalStoreNodeGen.getUncached(); - case CTX_GLOBAL_LOAD -> GraalHPyGlobalLoadNodeGen.getUncached(); - case CTX_LEAVEPYTHONEXECUTION -> GraalHPyLeavePythonExecutionNodeGen.getUncached(); - case CTX_REENTERPYTHONEXECUTION -> GraalHPyReenterPythonExecutionNodeGen.getUncached(); - case CTX_CONTAINS -> GraalHPyContainsNodeGen.getUncached(); - case CTX_TYPE_ISSUBTYPE -> GraalHPyTypeIsSubtypeNodeGen.getUncached(); - case CTX_TYPE_GETNAME -> GraalHPyTypeGetNameNodeGen.getUncached(); - case CTX_DICT_KEYS -> GraalHPyDictKeysNodeGen.getUncached(); - case CTX_DICT_COPY -> GraalHPyDictCopyNodeGen.getUncached(); - case CTX_CAPSULE_NEW -> GraalHPyCapsuleNewNodeGen.getUncached(); - case CTX_CAPSULE_GET -> GraalHPyCapsuleGetNodeGen.getUncached(); - case CTX_CAPSULE_SET -> GraalHPyCapsuleSetNodeGen.getUncached(); - case CTX_CAPSULE_ISVALID -> GraalHPyCapsuleIsValidNodeGen.getUncached(); - case CTX_CONTEXTVAR_NEW -> GraalHPyContextVarNewNodeGen.getUncached(); - case CTX_CONTEXTVAR_GET -> GraalHPyContextVarGetNodeGen.getUncached(); - case CTX_CONTEXTVAR_SET -> GraalHPyContextVarSetNodeGen.getUncached(); - case CTX_UNICODE_FROMENCODEDOBJECT -> GraalHPyUnicodeFromEncodedObjectNodeGen.getUncached(); - case CTX_UNICODE_SUBSTRING -> GraalHPyUnicodeSubstringNodeGen.getUncached(); - case CTX_SLICE_UNPACK -> GraalHPySliceUnpackNodeGen.getUncached(); - case CTX_TYPE_GETBUILTINSHAPE -> GraalHPyTypeGetBuiltinShapeNodeGen.getUncached(); - case CTX_COMPILE_S -> GraalHPyCompileNodeGen.getUncached(); - case CTX_EVALCODE -> GraalHPyEvalCodeNodeGen.getUncached(); - case CTX_SETCALLFUNCTION -> GraalHPySetCallFunctionNodeGen.getUncached(); - default -> throw CompilerDirectives.shouldNotReachHere(); - }; - } - - // @formatter:on - // Checkstyle: resume - // {{end ctx func factory}} - } - - public abstract static class HPyUnaryContextFunction extends GraalHPyContextFunction { - public abstract Object execute(Object arg0); - - @Override - public final Object execute(Object[] args) { - return execute(args[0]); - } - } - - public abstract static class HPyBinaryContextFunction extends GraalHPyContextFunction { - public abstract Object execute(Object arg0, Object arg1); - - @Override - public final Object execute(Object[] args) { - return execute(args[0], args[1]); - } - } - - public abstract static class HPyTernaryContextFunction extends GraalHPyContextFunction { - public abstract Object execute(Object arg0, Object arg1, Object arg2); - - @Override - public final Object execute(Object[] args) { - return execute(args[0], args[1], args[2]); - } - } - - public abstract static class HPyQuaternaryContextFunction extends GraalHPyContextFunction { - public abstract Object execute(Object arg0, Object arg1, Object arg2, Object arg3); - - @Override - public final Object execute(Object[] args) { - return execute(args[0], args[1], args[2], args[3]); - } - } - - public abstract static class HPy5ContextFunction extends GraalHPyContextFunction { - public abstract Object execute(Object arg0, Object arg1, Object arg2, Object arg3, Object arg4); - - @Override - public final Object execute(Object[] args) { - return execute(args[0], args[1], args[2], args[3], args[4]); - } - } - - @HPyContextFunction("ctx_Dup") - @GenerateUncached - public abstract static class GraalHPyDup extends HPyBinaryContextFunction { - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object) { - return object; - } - } - - @HPyContextFunction("ctx_Close") - @GenerateUncached - public abstract static class GraalHPyClose extends HPyBinaryContextFunction { - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object handle, - @Bind("this") Node inliningTarget, - @Cached HPyCloseHandleNode closeHandleNode) { - closeHandleNode.execute(inliningTarget, handle); - return 0; - } - } - - @HPyContextFunction("ctx_Positive") - @GenerateUncached - @ImportStatic(UnaryArithmetic.class) - public abstract static class GraalHPyPositive extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg, - @Cached(parameters = "Pos") HPyUnaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg); - } - } - - @HPyContextFunction("ctx_Negative") - @GenerateUncached - @ImportStatic(UnaryArithmetic.class) - public abstract static class GraalHPyNegative extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg, - @Cached(parameters = "Neg") HPyUnaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg); - } - } - - @HPyContextFunction("ctx_Invert") - @GenerateUncached - @ImportStatic(UnaryArithmetic.class) - public abstract static class GraalHPyInvert extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg, - @Cached(parameters = "Invert") HPyUnaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg); - } - } - - @HPyContextFunction("ctx_Add") - @GenerateUncached - @ImportStatic(BinaryArithmetic.class) - public abstract static class GraalHPyAdd extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "Add") HPyBinaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_Subtract") - @GenerateUncached - @ImportStatic(BinaryArithmetic.class) - public abstract static class GraalHPySubtract extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "Sub") HPyBinaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_Multiply") - @GenerateUncached - @ImportStatic(BinaryArithmetic.class) - public abstract static class GraalHPyMultiply extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "Mul") HPyBinaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_MatrixMultiply") - @GenerateUncached - @ImportStatic(BinaryArithmetic.class) - public abstract static class GraalHPyMatrixMultiply extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "MatMul") HPyBinaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_FloorDivide") - @GenerateUncached - @ImportStatic(BinaryArithmetic.class) - public abstract static class GraalHPyFloorDivide extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "FloorDiv") HPyBinaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_TrueDivide") - @GenerateUncached - @ImportStatic(BinaryArithmetic.class) - public abstract static class GraalHPyTrueDivide extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "TrueDiv") HPyBinaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_Remainder") - @GenerateUncached - @ImportStatic(BinaryArithmetic.class) - public abstract static class GraalHPyRemainder extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "Mod") HPyBinaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_Divmod") - @GenerateUncached - @ImportStatic(BinaryArithmetic.class) - public abstract static class GraalHPyDivmod extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "DivMod") HPyBinaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_And") - @GenerateUncached - @ImportStatic(BinaryArithmetic.class) - public abstract static class GraalHPyAnd extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "And") HPyBinaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_Xor") - @GenerateUncached - @ImportStatic(BinaryArithmetic.class) - public abstract static class GraalHPyXor extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "Xor") HPyBinaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_Or") - @GenerateUncached - @ImportStatic(BinaryArithmetic.class) - public abstract static class GraalHPyOr extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "Or") HPyBinaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_Lshift") - @GenerateUncached - @ImportStatic(BinaryArithmetic.class) - public abstract static class GraalHPyLshift extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "LShift") HPyBinaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_Rshift") - @GenerateUncached - @ImportStatic(BinaryArithmetic.class) - public abstract static class GraalHPyRshift extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "RShift") HPyBinaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_Power") - @GenerateUncached - @ImportStatic(TernaryArithmetic.class) - public abstract static class GraalHPyPower extends HPyQuaternaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, Object arg2, - @Cached(parameters = "Pow") HPyTernaryArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1, arg2); - } - } - - @HPyContextFunction("ctx_InPlaceAdd") - @GenerateUncached - @ImportStatic(InplaceArithmetic.class) - public abstract static class GraalHPyInPlaceAdd extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "IAdd") HPyInplaceArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_InPlaceSubtract") - @GenerateUncached - @ImportStatic(InplaceArithmetic.class) - public abstract static class GraalHPyInPlaceSubtract extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "ISub") HPyInplaceArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_InPlaceMultiply") - @GenerateUncached - @ImportStatic(InplaceArithmetic.class) - public abstract static class GraalHPyInPlaceMultiply extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "IMul") HPyInplaceArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_InPlaceMatrixMultiply") - @GenerateUncached - @ImportStatic(InplaceArithmetic.class) - public abstract static class GraalHPyInPlaceMatrixMultiply extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "IMatMul") HPyInplaceArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_InPlaceFloorDivide") - @GenerateUncached - @ImportStatic(InplaceArithmetic.class) - public abstract static class GraalHPyInPlaceFloorDivide extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "IFloorDiv") HPyInplaceArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_InPlaceTrueDivide") - @GenerateUncached - @ImportStatic(InplaceArithmetic.class) - public abstract static class GraalHPyInPlaceTrueDivide extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "ITrueDiv") HPyInplaceArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_InPlaceRemainder") - @GenerateUncached - @ImportStatic(InplaceArithmetic.class) - public abstract static class GraalHPyInPlaceRemainder extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "IMod") HPyInplaceArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_InPlacePower") - @GenerateUncached - @ImportStatic(InplaceArithmetic.class) - public abstract static class GraalHPyInPlacePower extends HPyQuaternaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, Object arg2, - @Cached(parameters = "IPow") HPyInplaceArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1, arg2); - } - } - - @HPyContextFunction("ctx_InPlaceLshift") - @GenerateUncached - @ImportStatic(InplaceArithmetic.class) - public abstract static class GraalHPyInPlaceLshift extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "ILShift") HPyInplaceArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_InPlaceRshift") - @GenerateUncached - @ImportStatic(InplaceArithmetic.class) - public abstract static class GraalHPyInPlaceRshift extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "IRShift") HPyInplaceArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_InPlaceAnd") - @GenerateUncached - @ImportStatic(InplaceArithmetic.class) - public abstract static class GraalHPyInPlaceAnd extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "IAnd") HPyInplaceArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_InPlaceXor") - @GenerateUncached - @ImportStatic(InplaceArithmetic.class) - public abstract static class GraalHPyInPlaceXor extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "IXor") HPyInplaceArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_InPlaceOr") - @GenerateUncached - @ImportStatic(InplaceArithmetic.class) - public abstract static class GraalHPyInPlaceOr extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg0, Object arg1, - @Cached(parameters = "IOr") HPyInplaceArithmeticNode arithmeticNode) { - return arithmeticNode.execute(arg0, arg1); - } - } - - @HPyContextFunction("ctx_Bool_FromBool") - @GenerateUncached - public abstract static class GraalHPyBoolFromBool extends HPyBinaryContextFunction { - - @Specialization - static PInt doBoolean(GraalHPyContext hpyContext, boolean value) { - Python3Core core = hpyContext.getContext(); - return value ? core.getTrue() : core.getFalse(); - } - - @Specialization - static PInt doByte(GraalHPyContext hpyContext, byte value) { - return doBoolean(hpyContext, value != 0); - } - } - - @HPyContextFunction("ctx_Long_FromInt32_t") - @GenerateUncached - public abstract static class GraalHPyLongFromInt32 extends HPyBinaryContextFunction { - - @Specialization - static Object doInt(@SuppressWarnings("unused") Object hpyContext, int value, - @Bind("this") Node inliningTarget, - @Exclusive @Cached HPyLongFromLong fromLongNode) { - return fromLongNode.execute(inliningTarget, value, true); - } - - @Specialization - static Object doLong(@SuppressWarnings("unused") Object hpyContext, long value, - @Bind("this") Node inliningTarget, - @Exclusive @Cached HPyLongFromLong fromLongNode) { - return fromLongNode.execute(inliningTarget, value, true); - } - } - - @HPyContextFunction("ctx_Long_FromUInt32_t") - @GenerateUncached - public abstract static class GraalHPyLongFromUInt32 extends HPyBinaryContextFunction { - - @Specialization - static Object doInt(@SuppressWarnings("unused") Object hpyContext, int value, - @Bind("this") Node inliningTarget, - @Shared @Cached HPyLongFromLong fromLongNode) { - return fromLongNode.execute(inliningTarget, value, false); - } - - @Specialization - static Object doLong(Object hpyContext, long value, - @Bind("this") Node inliningTarget, - @Shared @Cached HPyLongFromLong fromLongNode) { - return doInt(hpyContext, (int) value, inliningTarget, fromLongNode); - } - } - - @HPyContextFunction("ctx_Long_FromInt64_t") - @HPyContextFunction("ctx_Long_FromSsize_t") - @GenerateUncached - public abstract static class GraalHPyLongFromInt64 extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, long value, - @Bind("this") Node inliningTarget, - @Cached HPyLongFromLong fromLongNode) { - return fromLongNode.execute(inliningTarget, value, true); - } - } - - @HPyContextFunction("ctx_Long_FromUInt64_t") - @HPyContextFunction("ctx_Long_FromSize_t") - @GenerateUncached - public abstract static class GraalHPyLongFromUInt64 extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, long value, - @Bind("this") Node inliningTarget, - @Cached HPyLongFromLong fromLongNode) { - return fromLongNode.execute(inliningTarget, value, false); - } - } - - private static final int SIZEOF_INT32 = 4; - private static final int SIZEOF_INT64 = 8; - private static final int SIZEOF_INTPTR = 8; - - @HPyContextFunction("ctx_Long_AsInt32_t") - @GenerateUncached - public abstract static class GraalHPyLongAsInt32 extends HPyBinaryContextFunction { - @Specialization - static Object doGeneric(@SuppressWarnings("unusued") Object hpyContext, Object object, - @Cached AsNativePrimitiveNode asNativePrimitiveNode) { - return asNativePrimitiveNode.execute(object, 1, SIZEOF_INT32, true); - } - } - - @HPyContextFunction("ctx_Long_AsUInt32_t") - @GenerateUncached - public abstract static class GraalHPyLongAsUInt32 extends HPyBinaryContextFunction { - @Specialization - static Object doGeneric(@SuppressWarnings("unusued") Object hpyContext, Object object, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode raiseNode, - @Cached AsNativePrimitiveNode asNativePrimitiveNode) { - if (!isSubtypeNode.execute(getClassNode.execute(inliningTarget, object), PythonBuiltinClassType.PInt)) { - throw raiseNode.raise(TypeError, ErrorMessages.INTEGER_REQUIRED); - } - return asNativePrimitiveNode.execute(object, 0, SIZEOF_INT32, true); - } - } - - @HPyContextFunction("ctx_Long_AsUInt32_tMask") - @GenerateUncached - public abstract static class GraalHPyLongAsUInt32Mask extends HPyBinaryContextFunction { - @Specialization - static Object doGeneric(@SuppressWarnings("unusued") Object hpyContext, Object object, - @Cached AsNativePrimitiveNode asNativePrimitiveNode) { - return asNativePrimitiveNode.execute(object, 0, SIZEOF_INT32, false); - } - } - - @HPyContextFunction("ctx_Long_AsInt64_t") - @GenerateUncached - public abstract static class GraalHPyLongAsInt64 extends HPyBinaryContextFunction { - @Specialization - static Object doGeneric(@SuppressWarnings("unusued") Object hpyContext, Object object, - @Cached AsNativePrimitiveNode asNativePrimitiveNode) { - return asNativePrimitiveNode.execute(object, 1, SIZEOF_INT64, true); - } - } - - @HPyContextFunction("ctx_Long_AsUInt64_t") - @HPyContextFunction("ctx_Long_AsSize_t") - @HPyContextFunction("ctx_Long_AsVoidPtr") - @GenerateUncached - public abstract static class GraalHPyLongAsUInt64 extends HPyBinaryContextFunction { - @Specialization - static Object doGeneric(@SuppressWarnings("unusued") Object hpyContext, Object object, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode raiseNode, - @Cached AsNativePrimitiveNode asNativePrimitiveNode) { - if (!isSubtypeNode.execute(getClassNode.execute(inliningTarget, object), PythonBuiltinClassType.PInt)) { - throw raiseNode.raise(TypeError, ErrorMessages.INTEGER_REQUIRED); - } - return asNativePrimitiveNode.execute(object, 0, SIZEOF_INT64, true); - } - } - - @HPyContextFunction("ctx_Long_AsUInt64_tMask") - @GenerateUncached - public abstract static class GraalHPyLongAsUInt64Mask extends HPyBinaryContextFunction { - @Specialization - static Object doGeneric(@SuppressWarnings("unusued") Object hpyContext, Object object, - @Cached AsNativePrimitiveNode asNativePrimitiveNode) { - return asNativePrimitiveNode.execute(object, 0, SIZEOF_INT64, false); - } - } - - @HPyContextFunction("ctx_Long_AsSsize_t") - @GenerateUncached - public abstract static class GraalHPyLongAsSsizeT extends HPyBinaryContextFunction { - @Specialization - static Object doGeneric(@SuppressWarnings("unusued") Object hpyContext, Object object, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode raiseNode, - @Cached AsNativePrimitiveNode asNativePrimitiveNode) { - if (!isSubtypeNode.execute(getClassNode.execute(inliningTarget, object), PythonBuiltinClassType.PInt)) { - throw raiseNode.raise(TypeError, ErrorMessages.INTEGER_REQUIRED); - } - return asNativePrimitiveNode.execute(object, 1, SIZEOF_INTPTR, true); - } - } - - @HPyContextFunction("ctx_Long_AsDouble") - @GenerateUncached - public abstract static class GraalHPyLongAsDouble extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object arg, - @Bind("this") Node inliningTarget, - @Cached PyLongAsDoubleNode asDoubleNode) { - return asDoubleNode.execute(inliningTarget, arg); - } - } - - @HPyContextFunction("ctx_Dict_New") - @GenerateUncached - public abstract static class GraalHPyDictNew extends HPyUnaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, - @Cached PythonObjectFactory factory) { - return factory.createDict(); - } - } - - @HPyContextFunction("ctx_List_New") - @GenerateUncached - public abstract static class GraalHPyListNew extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, long len, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode raiseNode) { - try { - Object[] data = new Object[PInt.intValueExact(len)]; - // TODO(fa) maybe this should be NO_VALUE (representing native 'NULL') - Arrays.fill(data, PNone.NONE); - return factory.createList(data); - } catch (OverflowException e) { - throw raiseNode.raise(PythonBuiltinClassType.MemoryError); - } - } - } - - @HPyContextFunction("ctx_List_Append") - @GenerateUncached - public abstract static class GraalHPyListAppend extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object left, Object value, - @Cached ListNodes.AppendNode appendNode, - @Cached PRaiseNode raiseNode) { - if (!PGuards.isList(left)) { - throw raiseNode.raise(SystemError, ErrorMessages.BAD_INTERNAL_CALL); - } - appendNode.execute((PList) left, value); - return 0; - } - } - - @HPyContextFunction("ctx_Float_FromDouble") - @GenerateUncached - public abstract static class GraalHPyFloatFromDouble extends HPyBinaryContextFunction { - - @Specialization - static double doGeneric(@SuppressWarnings("unused") Object hpyContext, double value) { - return value; - } - } - - @HPyContextFunction("ctx_Float_AsDouble") - @GenerateUncached - public abstract static class GraalHPyFloatAsDouble extends HPyBinaryContextFunction { - - @Specialization - static double doGeneric(@SuppressWarnings("unused") Object hpyContext, Object value, - @Bind("this") Node inliningTarget, - @Cached PyFloatAsDoubleNode asDoubleNode) { - return asDoubleNode.execute(null, inliningTarget, value); - } - } - - abstract static class HPyCheckBuiltinType extends HPyBinaryContextFunction { - - abstract PythonBuiltinClassType getExpectedType(); - - } - - @HPyContextFunction("ctx_Dict_Check") - @GenerateUncached - public abstract static class GraalHPyDictCheck extends HPyBinaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached IsSubtypeNode isSubtypeNode) { - return PInt.intValue(isSubtypeNode.execute(getClassNode.execute(inliningTarget, object), PythonBuiltinClassType.PDict)); - } - } - - @HPyContextFunction("ctx_Bytes_Check") - @GenerateUncached - public abstract static class GraalHPyBytesCheck extends HPyBinaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached IsSubtypeNode isSubtypeNode) { - return PInt.intValue(isSubtypeNode.execute(getClassNode.execute(inliningTarget, object), PythonBuiltinClassType.PBytes)); - } - } - - @HPyContextFunction("ctx_Unicode_Check") - @GenerateUncached - public abstract static class GraalHPyUnicodeCheck extends HPyBinaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached IsSubtypeNode isSubtypeNode) { - return PInt.intValue(isSubtypeNode.execute(getClassNode.execute(inliningTarget, object), PythonBuiltinClassType.PString)); - } - } - - @HPyContextFunction("ctx_Tuple_Check") - @GenerateUncached - public abstract static class GraalHPyTupleCheck extends HPyBinaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached IsSubtypeNode isSubtypeNode) { - return PInt.intValue(isSubtypeNode.execute(getClassNode.execute(inliningTarget, object), PythonBuiltinClassType.PTuple)); - } - } - - @HPyContextFunction("ctx_List_Check") - @GenerateUncached - public abstract static class GraalHPyListCheck extends HPyBinaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached IsSubtypeNode isSubtypeNode) { - return PInt.intValue(isSubtypeNode.execute(getClassNode.execute(inliningTarget, object), PythonBuiltinClassType.PList)); - } - } - - @HPyContextFunction("ctx_Err_NoMemory") - @GenerateUncached - public abstract static class GraalHPyErrNoMemory extends HPyUnaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.MemoryError); - } - } - - @HPyContextFunction("ctx_Err_SetObject") - @GenerateUncached - public abstract static class GraalHPyErrSetObject extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object errTypeObj, Object valueObj, - @Bind("this") Node inliningTarget, - @Cached IsSubtypeNode isSubtypeNode, - @Cached IsSubtypeNode isExcValueSubtypeNode, - @Cached GetClassNode getClassNode, - @Cached CallNode callExceptionConstructorNode, - @Cached PyExceptionInstanceCheckNode exceptionCheckNode, - @Cached PRaiseNode raiseNode) { - if (!(PGuards.isPythonClass(errTypeObj) && isSubtypeNode.execute(errTypeObj, PythonBuiltinClassType.PBaseException))) { - return raiseNode.raise(SystemError, ErrorMessages.EXCEPTION_NOT_BASEEXCEPTION, errTypeObj); - } - Object exception; - // If the exception value is already an exception object, just take it. - if (isExcValueSubtypeNode.execute(getClassNode.execute(inliningTarget, valueObj), PythonBuiltinClassType.PBaseException)) { - exception = valueObj; - } else { - exception = callExceptionConstructorNode.executeWithoutFrame(errTypeObj, valueObj); - } - - if (exceptionCheckNode.execute(inliningTarget, exception)) { - throw raiseNode.raiseExceptionObject(exception); - } - // This should really not happen since we did a type check above but in theory, - // the constructor could be broken. - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @HPyContextFunction("ctx_Err_SetString") - @GenerateUncached - public abstract static class GraalHPyErrSetString extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object errTypeObj, Object charPtr, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached IsSubtypeNode isSubtypeNode, - @Cached CallNode callExceptionConstructorNode, - @Cached PyExceptionInstanceCheckNode exceptionCheckNode, - @Cached PRaiseNode raiseNode) { - if (!(PGuards.isPythonClass(errTypeObj) && isSubtypeNode.execute(errTypeObj, PythonBuiltinClassType.PBaseException))) { - return raiseNode.raise(SystemError, ErrorMessages.EXCEPTION_NOT_BASEEXCEPTION, errTypeObj); - } - Object exception = callExceptionConstructorNode.executeWithoutFrame(errTypeObj, fromCharPointerNode.execute(charPtr)); - - if (exceptionCheckNode.execute(isSubtypeNode, exception)) { - throw raiseNode.raiseExceptionObject(exception); - } - // This should really not happen since we did a type check above but in theory, - // the constructor could be broken. - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @HPyContextFunction("ctx_Err_SetFromErrnoWithFilename") - @GenerateUncached - public abstract static class GraalHPyErrSetFromErrnoWithFilename extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object errTypeObj, Object errMessagePtr, - @Bind("this") Node inliningTarget, - @Cached(parameters = "hpyContext") GraalHPyCAccess.IsNullNode isNullNode, - @Cached(parameters = "hpyContext") HPyCallHelperFunctionNode callHelperFunctionNode, - @Cached(parameters = "hpyContext") HPyFromCharPointerNode fromCharPointerNode, - @Cached IsSubtypeNode isSubtypeNode, - @Cached CallNode callExceptionConstructorNode, - @Cached PyExceptionInstanceCheckNode exceptionCheckNode, - @Cached PRaiseNode raiseNode) { - Object i = callHelperFunctionNode.call(hpyContext, GraalHPyNativeSymbol.GRAAL_HPY_GET_ERRNO); - Object message = fromCharPointerNode.execute(hpyContext, callHelperFunctionNode.call(hpyContext, GraalHPyNativeSymbol.GRAAL_HPY_GET_STRERROR, i), true); - if (!isSubtypeNode.execute(errTypeObj, PythonBuiltinClassType.PBaseException)) { - return raiseNode.raise(SystemError, ErrorMessages.EXCEPTION_NOT_BASEEXCEPTION, errTypeObj); - } - Object exception = null; - if (!isNullNode.execute(hpyContext, errMessagePtr)) { - TruffleString filename_fsencoded = fromCharPointerNode.execute(hpyContext, errMessagePtr, true); - exception = callExceptionConstructorNode.executeWithoutFrame(errTypeObj, i, message, filename_fsencoded); - } - - if (exception == null) { - exception = callExceptionConstructorNode.executeWithoutFrame(errTypeObj, i, message); - } - - if (exceptionCheckNode.execute(inliningTarget, exception)) { - throw raiseNode.raiseExceptionObject(exception); - } - // This should really not happen since we did a type check above but in theory, - // the constructor could be broken. - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @HPyContextFunction("ctx_Err_SetFromErrnoWithFilenameObjects") - @GenerateUncached - public abstract static class GraalHPyErrSetFromErrnoWithFilenameObjects extends HPyQuaternaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object errTypeObj, Object filenameObject1, Object filenameObject2, - @Bind("this") Node inliningTarget, - @Cached(parameters = "hpyContext") HPyCallHelperFunctionNode callHelperNode, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached IsSubtypeNode isSubtypeNode, - @Cached CallNode callExceptionConstructorNode, - @Cached PyExceptionInstanceCheckNode exceptionCheckNode, - @Cached PRaiseNode raiseNode) { - Object i = callHelperNode.call(hpyContext, GraalHPyNativeSymbol.GRAAL_HPY_GET_ERRNO); - Object message = fromCharPointerNode.execute(callHelperNode.call(hpyContext, GraalHPyNativeSymbol.GRAAL_HPY_GET_STRERROR, i)); - if (!isSubtypeNode.execute(errTypeObj, PythonBuiltinClassType.PBaseException)) { - return raiseNode.raise(SystemError, ErrorMessages.EXCEPTION_NOT_BASEEXCEPTION, errTypeObj); - } - Object exception = null; - if (filenameObject1 != NULL_HANDLE_DELEGATE) { - if (filenameObject2 != NULL_HANDLE_DELEGATE) { - exception = callExceptionConstructorNode.executeWithoutFrame(errTypeObj, i, message, filenameObject1, 0, filenameObject2); - } else { - exception = callExceptionConstructorNode.executeWithoutFrame(errTypeObj, i, message, filenameObject1); - } - } - - if (exception == null) { - exception = callExceptionConstructorNode.executeWithoutFrame(errTypeObj, i, message); - } - - if (exceptionCheckNode.execute(inliningTarget, exception)) { - throw raiseNode.raiseExceptionObject(exception); - } - // This should really not happen since we did a type check above but in theory, - // the constructor could be broken. - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @HPyContextFunction("ctx_FatalError") - @GenerateUncached - public abstract static class GraalHPyFatalError extends HPyBinaryContextFunction { - @TruffleBoundary - @Specialization - Object doGeneric(GraalHPyContext hpyContext, Object charPtr) { - TruffleString errorMessage; - if (GraalHPyCAccess.IsNullNode.getUncached(hpyContext).execute(hpyContext, charPtr)) { - errorMessage = ErrorMessages.MSG_NOT_SET; - } else { - // we don't need to copy the bytes since we die anyway - errorMessage = FromCharPointerNodeGen.getUncached().execute(charPtr, false); - } - CExtCommonNodes.fatalError(this, hpyContext.getContext(), null, errorMessage, -1); - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @HPyContextFunction("ctx_Err_Occurred") - @GenerateUncached - public abstract static class GraalHPyErrOccurred extends HPyUnaryContextFunction { - - @Specialization - static int doGeneric(GraalHPyContext hpyContext, - @Bind("this") Node inliningTarget, - @Cached GetThreadStateNode getThreadStateNode) { - return getThreadStateNode.execute(inliningTarget, hpyContext.getContext()).getCurrentException() != null ? 1 : 0; - } - } - - @HPyContextFunction("ctx_Err_ExceptionMatches") - @GenerateUncached - public abstract static class GraalHPyErrExceptionMatches extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object exc, - @Bind("this") Node inliningTarget, - @Cached GetThreadStateNode getThreadStateNode, - @Cached GetUnreifiedExceptionNode getUnreifiedExceptionNode, - @Cached RecursiveExceptionMatches exceptionMatches) { - AbstractTruffleException err = getThreadStateNode.execute(inliningTarget, hpyContext.getContext()).getCurrentException(); - if (err == null) { - return 0; - } - if (exc == NULL_HANDLE_DELEGATE) { - return 0; - } - Object exceptionObject = getUnreifiedExceptionNode.execute(inliningTarget, err); - return exceptionMatches.execute(hpyContext, exceptionObject, exc); - } - } - - @HPyContextFunction("ctx_Err_Clear") - @GenerateUncached - public abstract static class GraalHPyErrClear extends HPyUnaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, - @Bind("this") Node inliningTarget, - @Cached GetThreadStateNode getThreadStateNode, - @Cached ClearCurrentExceptionNode clearCurrentExceptionNode) { - PythonThreadState threadState = getThreadStateNode.execute(inliningTarget, hpyContext.getContext()); - clearCurrentExceptionNode.execute(inliningTarget, threadState); - return NULL_HANDLE_DELEGATE; - } - } - - @HPyContextFunction("ctx_Err_WarnEx") - @GenerateUncached - public abstract static class GraalHPyErrWarnEx extends HPyQuaternaryContextFunction { - - @Specialization - static int doGeneric(GraalHPyContext hpyContext, Object categoryArg, Object messageArg, long stackLevel, - @Cached(parameters = "hpyContext") GraalHPyCAccess.IsNullNode isNullNode, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached WarnNode warnNode) { - Object category = categoryArg == NULL_HANDLE_DELEGATE ? RuntimeWarning : categoryArg; - TruffleString message = isNullNode.execute(hpyContext, messageArg) ? T_EMPTY_STRING : fromCharPointerNode.execute(messageArg); - warnNode.warnEx(null, category, message, (int) stackLevel); - return 0; - } - } - - @HPyContextFunction("ctx_Err_WriteUnraisable") - @GenerateUncached - public abstract static class GraalHPyErrWriteUnraisable extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object object, - @Bind("this") Node inliningTarget, - @Cached GetThreadStateNode getThreadStateNode, - @Cached WriteUnraisableNode writeUnraisableNode, - @Cached GetEscapedExceptionNode getEscapedExceptionNode, - @Cached ClearCurrentExceptionNode clearCurrentExceptionNode) { - PythonThreadState threadState = getThreadStateNode.execute(inliningTarget, hpyContext.getContext()); - AbstractTruffleException exception = threadState.getCurrentException(); - clearCurrentExceptionNode.execute(inliningTarget, threadState); - Object exceptionObject = getEscapedExceptionNode.execute(inliningTarget, exception); - writeUnraisableNode.execute(null, exceptionObject, null, (object instanceof PNone) ? PNone.NONE : object); - return 0; // void - } - } - - @HPyContextFunction("ctx_Unicode_AsUTF8String") - @GenerateUncached - public abstract static class GraalHPyUnicodeAsUTF8String extends HPyBinaryContextFunction { - - @Specialization - static PBytes doGeneric(@SuppressWarnings("unused") Object hpyContext, Object unicodeObject, - @Cached EncodeNativeStringNode encodeNativeStringNode, - @Cached PythonObjectFactory factory) { - return factory.createBytes(encodeNativeStringNode.execute(StandardCharsets.UTF_8, unicodeObject, T_STRICT)); - } - } - - @HPyContextFunction("ctx_Unicode_AsLatin1String") - @GenerateUncached - public abstract static class GraalHPyUnicodeAsLatin1String extends HPyBinaryContextFunction { - - @Specialization - static PBytes doGeneric(@SuppressWarnings("unused") Object hpyContext, Object unicodeObject, - @Cached EncodeNativeStringNode encodeNativeStringNode, - @Cached PythonObjectFactory factory) { - return factory.createBytes(encodeNativeStringNode.execute(StandardCharsets.ISO_8859_1, unicodeObject, T_STRICT)); - } - } - - @HPyContextFunction("ctx_Unicode_AsASCIIString") - @GenerateUncached - public abstract static class GraalHPyUnicodeAsASCIIString extends HPyBinaryContextFunction { - - @Specialization - static PBytes doGeneric(@SuppressWarnings("unused") Object hpyContext, Object unicodeObject, - @Cached EncodeNativeStringNode encodeNativeStringNode, - @Cached PythonObjectFactory factory) { - return factory.createBytes(encodeNativeStringNode.execute(StandardCharsets.US_ASCII, unicodeObject, T_STRICT)); - } - } - - @HPyContextFunction("ctx_Unicode_EncodeFSDefault") - @GenerateUncached - public abstract static class GraalHPyUnicodeEncodeFSDefault extends HPyBinaryContextFunction { - @Specialization - static PBytes doGeneric(@SuppressWarnings("unused") Object hpyContext, Object unicodeObject, - @Cached EncodeNativeStringNode encodeNativeStringNode, - @Cached PythonObjectFactory factory) { - return factory.createBytes(encodeNativeStringNode.execute(getFSDefaultCharset(), unicodeObject, T_STRICT)); - } - - @TruffleBoundary - public static Charset getFSDefaultCharset() { - TruffleString normalizedEncoding = CharsetMapping.normalizeUncached(GetFileSystemEncodingNode.getFileSystemEncoding()); - return CharsetMapping.getCharsetNormalized(normalizedEncoding); - } - } - - @HPyContextFunction("ctx_Unicode_AsUTF8AndSize") - @GenerateUncached - public abstract static class GraalHPyUnicodeAsUTF8AndSize extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object unicodeObject, Object sizePtr, - @Bind("this") Node inliningTarget, - @Cached CastToTruffleStringNode castToTruffleStringNode, - @Cached PRaiseNode raiseNode, - @Cached(parameters = "hpyContext") GraalHPyCAccess.WriteSizeTNode writeSizeTNode, - @Cached(parameters = "hpyContext") GraalHPyCAccess.IsNullNode isNullNode, - @Cached TruffleString.SwitchEncodingNode switchEncodingNode, - @Cached TruffleString.GetInternalByteArrayNode getInternalByteArrayNode) { - TruffleString tsUtf8; - try { - tsUtf8 = switchEncodingNode.execute(castToTruffleStringNode.execute(inliningTarget, unicodeObject), Encoding.UTF_8); - } catch (CannotCastException e) { - throw raiseNode.raise(TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); - } - InternalByteArray internalByteArray = getInternalByteArrayNode.execute(tsUtf8, Encoding.UTF_8); - if (!isNullNode.execute(hpyContext, sizePtr)) { - writeSizeTNode.write(hpyContext, sizePtr, internalByteArray.getLength()); - } - return new CByteArrayWrapper(internalByteArray.getArray()); - } - } - - @HPyContextFunction("ctx_Unicode_FromString") - @GenerateUncached - public abstract static class GraalHPyUnicodeFromString extends HPyBinaryContextFunction { - - @Specialization - static TruffleString doGeneric(@SuppressWarnings("unused") Object hpyContext, Object charPtr, - @Cached FromCharPointerNode fromCharPointerNode) { - if (charPtr instanceof TruffleString ts) { - return ts; - } - return fromCharPointerNode.execute(charPtr); - } - } - - @HPyContextFunction("ctx_Unicode_FromWideChar") - @GenerateUncached - public abstract static class GraalHPyUnicodeFromWchar extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object wcharPtr, long len, - @Bind("this") Node inliningTarget, - @Cached ReadUnicodeArrayNode readArray, - @Cached TruffleString.FromIntArrayUTF32Node fromArray) { - try { - return fromArray.execute(readArray.execute(inliningTarget, wcharPtr, PInt.intValueExact(len), CStructs.wchar_t.size())); - } catch (OverflowException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - } - - @HPyContextFunction("ctx_Unicode_DecodeFSDefault") - @GenerateUncached - public abstract static class GraalHPyUnicodeDecodeCharset extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object charPtr, - @Cached(parameters = "hpyContext") HPyFromCharPointerNode fromCharPointerNode) { - return fromCharPointerNode.execute(hpyContext, charPtr, getFSDefault()); - } - - @TruffleBoundary - static Encoding getFSDefault() { - String fileEncoding = System.getProperty("file.encoding"); - if (fileEncoding != null) { - try { - return Encoding.valueOf(fileEncoding.replace('-', '_')); - } catch (IllegalArgumentException e) { - // avoid any fatal Java exceptions; fall through - } - } - // fall back to UTF-8 - return Encoding.UTF_8; - } - } - - @HPyContextFunction("ctx_Unicode_DecodeFSDefaultAndSize") - @GenerateUncached - public abstract static class GraalHPyUnicodeDecodeCharsetAndSize extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object charPtr, long lsize, - @Cached(parameters = "hpyContext") HPyFromCharPointerNode fromCharPointerNode) { - Encoding fsDefault = GraalHPyUnicodeDecodeCharset.getFSDefault(); - try { - return fromCharPointerNode.execute(hpyContext, charPtr, PInt.intValueExact(lsize), fsDefault, true); - } catch (OverflowException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } - } - - @HPyContextFunction("ctx_Unicode_DecodeASCII") - @GenerateUncached - public abstract static class GraalHPyUnicodeDecodeASCII extends HPyQuaternaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object charPtr, long size, Object errorsPtr, - @Cached(parameters = "hpyContext") GraalHPyCAccess.IsNullNode isNullNode, - @Cached(parameters = "hpyContext") HPyFromCharPointerNode fromCharPointerNode, - @Cached(parameters = "hpyContext") GraalHPyCAccess.ReadI8ArrayNode readI8ArrayNode, - @Cached TruffleString.FromJavaStringNode fromJavaStringNode, - @Cached PRaiseNode raiseNode, - @Cached TruffleString.EqualNode equalNode) { - CodingErrorAction errorAction; - if (isNullNode.execute(hpyContext, errorsPtr)) { - errorAction = CodingErrorAction.REPORT; - } else { - TruffleString errors = fromCharPointerNode.execute(hpyContext, errorsPtr, false); - errorAction = CodecsModuleBuiltins.convertCodingErrorAction(errors, equalNode); - } - byte[] bytes = readI8ArrayNode.execute(hpyContext, charPtr, 0, size); - String decoded = decode(StandardCharsets.US_ASCII, errorAction, bytes); - if (decoded != null) { - return fromJavaStringNode.execute(decoded, TS_ENCODING); - } - // TODO: refactor helper nodes for CodecsModuleBuiltins to use them here - throw raiseNode.raise(PythonBuiltinClassType.UnicodeDecodeError, ErrorMessages.MALFORMED_INPUT); - } - - @TruffleBoundary - static String decode(Charset charset, CodingErrorAction errorAction, byte[] bytes) { - try { - return charset.newDecoder().onMalformedInput(errorAction).onUnmappableCharacter(errorAction).decode(ByteBuffer.wrap(bytes)).toString(); - } catch (CharacterCodingException ex) { - return null; - } - } - } - - @HPyContextFunction("ctx_Unicode_DecodeLatin1") - @GenerateUncached - public abstract static class GraalHPyUnicodeDecodeLatin1 extends HPyQuaternaryContextFunction { - - @Specialization - Object doGeneric(GraalHPyContext hpyContext, Object charPtr, long lsize, @SuppressWarnings("unused") Object errorsPtr, - @Cached(parameters = "hpyContext") HPyFromCharPointerNode fromCharPointerNode) { - if (PInt.isIntRange(lsize)) { - /* - * If we have ISO-8859-1, we can just force the encoding and short-circuit the error - * reading etc since there cannot be an invalid byte - */ - return fromCharPointerNode.execute(hpyContext, charPtr, (int) lsize, Encoding.ISO_8859_1, true); - } - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @HPyContextFunction("ctx_Unicode_ReadChar") - @GenerateUncached - public abstract static class GraalHPyUnicodeReadChar extends HPyTernaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object unicodeObject, long index, - @Bind("this") Node inliningTarget, - @Cached PyUnicodeReadCharNode unicodeReadChar) { - return unicodeReadChar.execute(inliningTarget, unicodeObject, index); - } - } - - @HPyContextFunction("ctx_AsPyObject") - @GenerateUncached - public abstract static class GraalHPyAsPyObject extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object, - @Cached PythonToNativeNewRefNode toPyObjectPointerNode) { - return toPyObjectPointerNode.execute(object); - } - } - - @HPyContextFunction("ctx_Bytes_AsString") - @HPyContextFunction("ctx_Bytes_AS_STRING") - @GenerateUncached - public abstract static class GraalHPyBytesAsString extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object, - @Cached PRaiseNode raiseNode) { - if (object instanceof PBytes bytes) { - return PySequenceArrayWrapper.ensureNativeSequence(bytes); - } - throw raiseNode.raise(TypeError, ErrorMessages.EXPECTED_BYTES_P_FOUND, object); - } - } - - @HPyContextFunction("ctx_Bytes_Size") - @HPyContextFunction("ctx_Bytes_GET_SIZE") - @GenerateUncached - public abstract static class GraalHPyBytesGetSize extends HPyBinaryContextFunction { - - @Specialization - static long doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object, - @Bind("this") Node inliningTarget, - @Cached SequenceNodes.LenNode lenNode, - @Cached PRaiseNode raiseNode) { - if (object instanceof PBytes) { - return lenNode.execute(inliningTarget, (PSequence) object); - } - throw raiseNode.raise(TypeError, ErrorMessages.EXPECTED_BYTES_P_FOUND, object); - } - } - - @HPyContextFunction("ctx_Bytes_FromString") - @GenerateUncached - public abstract static class GraalHPyBytesFromString extends HPyBinaryContextFunction { - - @Specialization - static PBytes doGeneric(GraalHPyContext hpyContext, Object charPtr, - @Bind("this") Node inliningTarget, - @Cached CastToJavaIntExactNode castToJavaIntNode, - @Cached(parameters = "hpyContext") HPyCallHelperFunctionNode callHelperNode, - @Cached(parameters = "hpyContext") GraalHPyCAccess.ReadI8ArrayNode readI8ArrayNode, - @Cached PRaiseNode raiseNode, - @Cached PythonObjectFactory factory) { - int size; - try { - size = castToJavaIntNode.execute(inliningTarget, callHelperNode.call(hpyContext, GraalHPyNativeSymbol.GRAAL_HPY_STRLEN, charPtr)); - } catch (PException e) { - throw raiseNode.raise(OverflowError, ErrorMessages.BYTE_STR_IS_TOO_LARGE); - } - byte[] bytes = readI8ArrayNode.execute(hpyContext, charPtr, 0, size); - return factory.createBytes(bytes); - } - } - - @HPyContextFunction("ctx_Bytes_FromStringAndSize") - @GenerateUncached - public abstract static class GraalHPyBytesFromStringAndSize extends HPyTernaryContextFunction { - - @Specialization - static PBytes doGeneric(GraalHPyContext hpyContext, Object charPtr, long lsize, - @Cached(parameters = "hpyContext") GraalHPyCAccess.IsNullNode isNullNode, - @Cached(parameters = "hpyContext") GraalHPyCAccess.ReadI8ArrayNode readI8ArrayNode, - @Cached PRaiseNode raiseNode, - @Cached PythonObjectFactory factory) { - if (isNullNode.execute(hpyContext, charPtr)) { - throw raiseNode.raise(ValueError, ErrorMessages.NULL_CHAR_PASSED); - } - if (lsize < 0) { - throw raiseNode.raise(SystemError, ErrorMessages.NEGATIVE_SIZE_PASSED); - } - if (lsize == 0) { - return factory.createEmptyBytes(); - } - byte[] bytes = readI8ArrayNode.execute(hpyContext, charPtr, 0, lsize); - return factory.createBytes(bytes); - } - } - - @HPyContextFunction("ctx_IsTrue") - @GenerateUncached - public abstract static class GraalHPyIsTrue extends HPyBinaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object, - @Cached PyObjectIsTrueNode isTrueNode) { - return PInt.intValue(isTrueNode.execute(null, object)); - } - } - - @HPyContextFunction("ctx_GetAttr") - @GenerateUncached - public abstract static class GraalHPyGetAttr extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object receiver, Object key, - @Bind("this") Node inliningTarget, - @Cached PyObjectGetAttrO getAttributeNode) { - return getAttributeNode.execute(null, inliningTarget, receiver, key); - } - } - - @HPyContextFunction("ctx_GetAttr_s") - @GenerateUncached - public abstract static class GraalHPyGetAttrS extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object receiver, Object charPtr, - @Bind("this") Node inliningTarget, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached PyObjectGetAttr getAttributeNode) { - return getAttributeNode.execute(inliningTarget, receiver, fromCharPointerNode.execute(charPtr)); - } - } - - @HPyContextFunction("ctx_Type_FromSpec") - @GenerateUncached - public abstract static class GraalHPyTypeFromSpec extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object typeSpecPtr, Object typeSpecParamArrayPtr, - @Cached HPyCreateTypeFromSpecNode createTypeFromSpecNode) { - Object newType = createTypeFromSpecNode.execute(hpyContext, typeSpecPtr, typeSpecParamArrayPtr); - assert PGuards.isClassUncached(newType) : "Object created from type spec is not a type"; - return newType; - } - } - - @HPyContextFunction("ctx_HasAttr") - @GenerateUncached - public abstract static class GraalHPyHasAttr extends HPyTernaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object receiver, Object key, - @Bind("this") Node inliningTarget, - @Cached PyObjectGetAttrO getAttributeNode) { - try { - Object attr = getAttributeNode.execute(null, inliningTarget, receiver, key); - return PInt.intValue(attr != PNone.NO_VALUE); - } catch (PException e) { - return 0; - } - } - } - - @HPyContextFunction("ctx_HasAttr_s") - @GenerateUncached - public abstract static class GraalHPyHasAttrS extends HPyTernaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object receiver, Object charPtr, - @Bind("this") Node inliningTarget, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached PyObjectGetAttr getAttributeNode) { - try { - Object attr = getAttributeNode.execute(inliningTarget, receiver, fromCharPointerNode.execute(charPtr)); - return PInt.intValue(attr != PNone.NO_VALUE); - } catch (PException e) { - return 0; - } - } - } - - @HPyContextFunction("ctx_SetAttr") - @GenerateUncached - public abstract static class GraalHPySetAttr extends HPyQuaternaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object receiver, Object key, Object value, - @Bind("this") Node inliningTarget, - @Cached PyObjectSetAttrO setAttrNode) { - if (value == NULL_HANDLE_DELEGATE) { - setAttrNode.execute(null, inliningTarget, receiver, key, PNone.NO_VALUE); - } else { - setAttrNode.execute(null, inliningTarget, receiver, key, value); - } - return 0; - } - } - - @HPyContextFunction("ctx_SetAttr_s") - @GenerateUncached - public abstract static class GraalHPySetAttrS extends HPyQuaternaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object receiver, Object charPtr, Object value, - @Bind("this") Node inliningTarget, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached PyObjectSetAttr setAttrNode) { - TruffleString key = fromCharPointerNode.execute(charPtr); - if (value == NULL_HANDLE_DELEGATE) { - setAttrNode.execute(inliningTarget, receiver, key, PNone.NO_VALUE); - } else { - setAttrNode.execute(inliningTarget, receiver, key, value); - } - return 0; - } - } - - @HPyContextFunction("ctx_GetItem") - @HPyContextFunction("ctx_GetItem_i") - @GenerateUncached - public abstract static class GraalHPyGetItem extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object receiver, Object key, - @Bind("this") Node inliningTarget, - @Cached PyObjectGetItem getItemNode) { - return getItemNode.execute(null, inliningTarget, receiver, key); - } - } - - @HPyContextFunction("ctx_GetItem_s") - @GenerateUncached - public abstract static class GraalHPyGetItemS extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object receiver, Object charPtr, - @Bind("this") Node inliningTarget, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached PyObjectGetItem getItemNode) { - return getItemNode.execute(null, inliningTarget, receiver, fromCharPointerNode.execute(charPtr)); - } - } - - @HPyContextFunction("ctx_SetItem") - @HPyContextFunction("ctx_SetItem_i") - @GenerateUncached - public abstract static class GraalHPySetItem extends HPyQuaternaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object receiver, Object key, Object value, - @Bind("this") Node inliningTarget, - @Cached PyObjectSetItem setItemNode) { - setItemNode.execute(null, inliningTarget, receiver, key, value); - return 0; - } - } - - @HPyContextFunction("ctx_SetItem_s") - @GenerateUncached - public abstract static class GraalHPySetItemS extends HPyQuaternaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object receiver, Object charPtr, Object value, - @Bind("this") Node inliningTarget, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached PyObjectSetItem setItemNode) { - setItemNode.execute(null, inliningTarget, receiver, fromCharPointerNode.execute(charPtr), value); - return 0; - } - } - - @HPyContextFunction("ctx_DelItem") - @HPyContextFunction("ctx_DelItem_i") - @GenerateUncached - public abstract static class GraalHPyDelItem extends HPyTernaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object receiver, Object key, - @Bind("this") Node inliningTarget, - @Cached PyObjectDelItem delItemNode) { - delItemNode.execute(null, inliningTarget, receiver, key); - return 0; - } - } - - @HPyContextFunction("ctx_DelItem_s") - @GenerateUncached - public abstract static class GraalHPyDelItemS extends HPyTernaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object receiver, Object charPtr, - @Bind("this") Node inliningTarget, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached PyObjectDelItem delItemNode) { - delItemNode.execute(null, inliningTarget, receiver, fromCharPointerNode.execute(charPtr)); - return 0; - } - } - - @HPyContextFunction("ctx_FromPyObject") - @GenerateUncached - public abstract static class GraalHPyFromPyObject extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object object, - @Cached NativeToPythonNode toJavaNode) { - // IMPORTANT: this is not stealing the reference. The CPython implementation - // actually increases the reference count by 1. - return toJavaNode.execute(object); - } - } - - @HPyContextFunction("ctx_New") - @GenerateUncached - public abstract static class GraalHPyNew extends HPyTernaryContextFunction { - private static final TruffleLogger LOGGER = GraalHPyContext.getLogger(GraalHPyNew.class); - public static final String INVALID_BUILT_IN_SHAPE = "invalid built-in shape"; - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object type, Object dataOutVar, - @Bind("this") Node inliningTarget, - @Cached IsTypeNode isTypeNode, - @Cached PRaiseNode.Lazy raiseNode, - @Cached PythonObjectFactory factory, - @Cached(parameters = "hpyContext") GraalHPyCAccess.AllocateNode allocateNode, - @Cached(parameters = "hpyContext") GraalHPyCAccess.WritePointerNode writePointerNode, - @Cached InlinedExactClassProfile classProfile) { - - Object profiledTypeObject = classProfile.profile(inliningTarget, type); - - // check if argument is actually a type - if (!isTypeNode.execute(inliningTarget, profiledTypeObject)) { - return raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.HPY_NEW_ARG_1_MUST_BE_A_TYPE); - } - - Object dataPtr = null; - Object destroyFunc = null; - Object defaultCallFunc = null; - - if (profiledTypeObject instanceof PythonClass clazz) { - // allocate native space - long basicSize = clazz.getBasicSize(); - if (basicSize != -1) { - dataPtr = allocateNode.calloc(hpyContext, 1, basicSize); - destroyFunc = clazz.getHPyDestroyFunc(); - - // write data pointer to out var - writePointerNode.write(hpyContext, dataOutVar, dataPtr); - - if (LOGGER.isLoggable(Level.FINEST)) { - LOGGER.finest(PythonUtils.formatJString("Allocated HPy object with native space of size %d at %s", basicSize, dataPtr)); - } - // TODO(fa): add memory tracing - } - defaultCallFunc = clazz.getHPyDefaultCallFunc(); - } - - int builtinShape = GraalHPyDef.getBuiltinShapeFromHiddenAttribute(profiledTypeObject); - PythonObject pythonObject = createFromBuiltinShape(builtinShape, profiledTypeObject, dataPtr, factory); - - if (destroyFunc != null) { - hpyContext.createHandleReference(pythonObject, dataPtr, destroyFunc != PNone.NO_VALUE ? destroyFunc : null); - } - if (defaultCallFunc != null) { - GraalHPyData.setHPyCallFunction(pythonObject, defaultCallFunc); - } - - return pythonObject; - } - - static PythonObject createFromBuiltinShape(int builtinShape, Object type, Object dataPtr, PythonObjectFactory factory) { - PythonObject result = switch (builtinShape) { - case HPyType_BUILTIN_SHAPE_LEGACY, HPyType_BUILTIN_SHAPE_OBJECT -> factory.createPythonHPyObject(type, dataPtr); - case HPyType_BUILTIN_SHAPE_TYPE -> throw CompilerDirectives.shouldNotReachHere("built-in shape type not yet implemented"); - case HPyType_BUILTIN_SHAPE_LONG -> factory.createInt(type, BigInteger.ZERO); - case HPyType_BUILTIN_SHAPE_FLOAT -> factory.createFloat(type, 0.0); - case HPyType_BUILTIN_SHAPE_UNICODE -> factory.createString(type, T_EMPTY_STRING); - case HPyType_BUILTIN_SHAPE_TUPLE -> factory.createEmptyTuple(type); - case HPyType_BUILTIN_SHAPE_LIST -> factory.createList(type); - default -> throw CompilerDirectives.shouldNotReachHere(INVALID_BUILT_IN_SHAPE); - }; - if (builtinShape != HPyType_BUILTIN_SHAPE_LEGACY && builtinShape != HPyType_BUILTIN_SHAPE_OBJECT) { - GraalHPyData.setHPyNativeSpace(result, dataPtr); - } - return result; - } - } - - @HPyContextFunction("ctx_AsStruct_Object") - @HPyContextFunction("ctx_AsStruct_Legacy") - @HPyContextFunction("ctx_AsStruct_Type") - @HPyContextFunction("ctx_AsStruct_Long") - @HPyContextFunction("ctx_AsStruct_Float") - @HPyContextFunction("ctx_AsStruct_Unicode") - @HPyContextFunction("ctx_AsStruct_Tuple") - @HPyContextFunction("ctx_AsStruct_List") - @GenerateUncached - public abstract static class GraalHPyCast extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object, - @Bind("this") Node inliningTarget, - @Cached HPyGetNativeSpacePointerNode getNativeSpacePointerNode) { - // we can also just return NO_VALUE since that will be interpreter as NULL - return getNativeSpacePointerNode.execute(inliningTarget, object); - } - } - - @HPyContextFunction("ctx_Type_GenericNew") - @GenerateUncached - public abstract static class GraalHPyTypeGenericNew extends HPy5ContextFunction { - - private static final TruffleLogger LOGGER = GraalHPyContext.getLogger(GraalHPyTypeGenericNew.class); - - @Specialization - @SuppressWarnings("unused") - static Object doGeneric(GraalHPyContext hpyContext, Object type, Object args, long nargs, Object kw, - @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, - @Cached(parameters = "hpyContext") GraalHPyCAccess.AllocateNode allocateNode, - @Cached InlinedExactClassProfile classProfile) { - - Object profiledTypeObject = classProfile.profile(inliningTarget, type); - Object dataPtr = null; - Object destroyFunc = null; - - if (type instanceof PythonClass clazz) { - long basicSize = clazz.getBasicSize(); - if (basicSize != -1) { - // we fully control this attribute; if it is there, it's always a long - dataPtr = allocateNode.calloc(hpyContext, 1, basicSize); - destroyFunc = clazz.getHPyDestroyFunc(); - - if (LOGGER.isLoggable(Level.FINEST)) { - LOGGER.finest(PythonUtils.formatJString("Allocated HPy object with native space of size %d at %s", basicSize, dataPtr)); - } - // TODO(fa): add memory tracing - } - } - - int builtinShape = GraalHPyDef.getBuiltinShapeFromHiddenAttribute(profiledTypeObject); - PythonObject pythonObject = GraalHPyNew.createFromBuiltinShape(builtinShape, type, dataPtr, factory); - - if (destroyFunc != null) { - hpyContext.createHandleReference(pythonObject, dataPtr, destroyFunc != PNone.NO_VALUE ? destroyFunc : null); - } - return pythonObject; - } - } - - @HPyContextFunction("ctx_Absolute") - @GenerateUncached - public abstract static class GraalHPyAbsolute extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object arg, - @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode, - @Cached CallUnaryMethodNode callNode) { - Object builtinFunction = readAttributeFromObjectNode.execute(hpyContext.getContext().getBuiltins(), BuiltinNames.T_ABS); - return callNode.executeObject(builtinFunction, arg); - } - } - - @HPyContextFunction("ctx_Long") - @GenerateUncached - public abstract static class GraalHPyLong extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object arg, - @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode, - @Cached CallUnaryMethodNode callNode) { - Object builtinFunction = readAttributeFromObjectNode.execute(hpyContext.getContext().getBuiltins(), BuiltinNames.T_INT); - return callNode.executeObject(builtinFunction, arg); - } - } - - @HPyContextFunction("ctx_Float") - @GenerateUncached - public abstract static class GraalHPyFloat extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object arg, - @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode, - @Cached CallUnaryMethodNode callNode) { - Object builtinFunction = readAttributeFromObjectNode.execute(hpyContext.getContext().getBuiltins(), BuiltinNames.T_FLOAT); - return callNode.executeObject(builtinFunction, arg); - } - } - - @HPyContextFunction("ctx_Str") - @GenerateUncached - public abstract static class GraalHPyStr extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object arg, - @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode, - @Cached CallUnaryMethodNode callNode) { - Object builtinFunction = readAttributeFromObjectNode.execute(hpyContext.getContext().getBuiltins(), BuiltinNames.T_STR); - return callNode.executeObject(builtinFunction, arg); - } - } - - @HPyContextFunction("ctx_Repr") - @GenerateUncached - public abstract static class GraalHPyRepr extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object arg, - @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode, - @Cached CallUnaryMethodNode callNode) { - Object builtinFunction = readAttributeFromObjectNode.execute(hpyContext.getContext().getBuiltins(), BuiltinNames.T_REPR); - return callNode.executeObject(builtinFunction, arg); - } - } - - @HPyContextFunction("ctx_ASCII") - @GenerateUncached - public abstract static class GraalHPyASCII extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object arg, - @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode, - @Cached CallUnaryMethodNode callNode) { - Object builtinFunction = readAttributeFromObjectNode.execute(hpyContext.getContext().getBuiltins(), BuiltinNames.T_ASCII); - return callNode.executeObject(builtinFunction, arg); - } - } - - @HPyContextFunction("ctx_Bytes") - @GenerateUncached - public abstract static class GraalHPyBytes extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object arg, - @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode, - @Cached CallUnaryMethodNode callNode) { - Object builtinFunction = readAttributeFromObjectNode.execute(hpyContext.getContext().getBuiltins(), BuiltinNames.T_BYTES); - return callNode.executeObject(builtinFunction, arg); - } - } - - @HPyContextFunction("ctx_Hash") - @GenerateUncached - public abstract static class GraalHPyHash extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object arg, - @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode, - @Cached CallUnaryMethodNode callNode) { - Object builtinFunction = readAttributeFromObjectNode.execute(hpyContext.getContext().getBuiltins(), BuiltinNames.T_HASH); - return callNode.executeObject(builtinFunction, arg); - } - } - - @HPyContextFunction("ctx_Length") - @GenerateUncached - public abstract static class GraalHPyLength extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object arg, - @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode, - @Cached CallUnaryMethodNode callNode) { - Object builtinFunction = readAttributeFromObjectNode.execute(hpyContext.getContext().getBuiltins(), BuiltinNames.T_LEN); - return callNode.executeObject(builtinFunction, arg); - } - } - - @HPyContextFunction("ctx_RichCompare") - @GenerateUncached - public abstract static class GraalHPyRichcompare extends HPyQuaternaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object receiver, Object arg1, int arg2, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached LookupSpecialMethodNode.Dynamic lookupRichcmp, - @Cached CallTernaryMethodNode callRichcmp) { - Object richcmp = lookupRichcmp.execute(null, inliningTarget, getClassNode.execute(inliningTarget, receiver), SpecialMethodNames.T___TRUFFLE_RICHCOMPARE__, receiver); - return callRichcmp.execute(null, richcmp, receiver, arg1, arg2); - } - } - - @HPyContextFunction("ctx_RichCompareBool") - @GenerateUncached - public abstract static class GraalHPyRichcompareBool extends HPyQuaternaryContextFunction { - - @Specialization - static Object doGeneric(Object ctx, Object receiver, Object arg1, int arg2, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached LookupSpecialMethodNode.Dynamic lookupRichcmp, - @Cached CallTernaryMethodNode callRichcmp, - @Cached PyObjectIsTrueNode isTrueNode) { - Object result = GraalHPyRichcompare.doGeneric(ctx, receiver, arg1, arg2, inliningTarget, getClassNode, lookupRichcmp, callRichcmp); - return PInt.intValue(isTrueNode.execute(null, result)); - } - } - - @HPyContextFunction("ctx_Index") - @GenerateUncached - public abstract static class GraalHPyAsIndex extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object, - @Bind("this") Node inliningTarget, - @Cached PyNumberIndexNode indexNode) { - return indexNode.execute(null, inliningTarget, object); - } - } - - @HPyContextFunction("ctx_Number_Check") - @GenerateUncached - public abstract static class GraalHPyIsNumber extends HPyBinaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object, - @Bind("this") Node inliningTarget, - @Cached PyNumberCheckNode checkNode) { - return PInt.intValue(checkNode.execute(inliningTarget, object)); - } - } - - @HPyContextFunction("ctx_Tuple_FromArray") - @GenerateUncached - public abstract static class GraalHPyTupleFromArray extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object arrayPtr, long nelements, - @Bind("this") Node inliningTarget, - @Cached CastToJavaIntExactNode castToJavaIntExactNode, - @Cached(parameters = "hpyContext") GraalHPyCAccess.ReadHPyArrayNode readHPyArrayNode, - @Cached PythonObjectFactory factory) { - int n; - try { - n = castToJavaIntExactNode.execute(inliningTarget, nelements); - } catch (CannotCastException e) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(castToJavaIntExactNode, PythonBuiltinClassType.MemoryError); - } - - Object[] elements = readHPyArrayNode.execute(hpyContext, arrayPtr, 0, n); - return factory.createTuple(elements); - } - } - - @HPyContextFunction("ctx_TupleBuilder_New") - @HPyContextFunction("ctx_ListBuilder_New") - @GenerateUncached - public abstract static class GraalHPyBuilderNew extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, long lcapacity, - @Cached HPyAsHandleNode asHandleNode) { - int capacity; - if (PInt.isIntRange(lcapacity) && (capacity = (int) lcapacity) >= 0) { - Object[] data = new Object[capacity]; - Arrays.fill(data, PNone.NONE); - return asHandleNode.execute(new ObjectSequenceStorage(data)); - } - return NULL_HANDLE; - } - } - - @HPyContextFunction("ctx_TupleBuilder_Set") - @HPyContextFunction("ctx_ListBuilder_Set") - @GenerateUncached - public abstract static class GraalHPyBuilderSet extends HPyQuaternaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object builderHandle, long lidx, Object value, - @Bind("this") Node inliningTarget, - @Cached HPyAsPythonObjectNode asPythonObjectNode, - @Cached CastToJavaIntExactNode castToJavaIntExactNode, - @Cached SequenceStorageNodes.SetItemDynamicNode setItemNode) { - Object builder = asPythonObjectNode.execute(builderHandle); - if (builder instanceof ObjectSequenceStorage storage) { - try { - int idx = castToJavaIntExactNode.execute(inliningTarget, lidx); - setItemNode.execute(null, NoGeneralizationNode.DEFAULT, storage, idx, value); - } catch (CannotCastException e) { - // fall through - } - return 0; - } - /* - * that's really unexpected since the C signature should enforce a valid builder but - * someone could have messed it up - */ - throw CompilerDirectives.shouldNotReachHere("invalid builder object"); - } - } - - @GenerateCached(false) - abstract static class HPyBuilderBuild extends HPyBinaryContextFunction { - - boolean isTupleBuilder() { - throw CompilerDirectives.shouldNotReachHere(); - } - - @Specialization - Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object builderHandle, - @Bind("this") Node inliningTarget, - @Cached HPyCloseAndGetHandleNode closeAndGetHandleNode, - @Cached PythonObjectFactory factory) { - ObjectSequenceStorage builder = cast(closeAndGetHandleNode.execute(inliningTarget, builderHandle)); - if (builder == null) { - /* - * that's really unexpected since the C signature should enforce a valid builder but - * someone could have messed it up - */ - throw CompilerDirectives.shouldNotReachHere("invalid builder object"); - } - return isTupleBuilder() ? factory.createTuple(builder) : factory.createList(builder); - } - - static ObjectSequenceStorage cast(Object object) { - if (object instanceof ObjectSequenceStorage) { - return (ObjectSequenceStorage) object; - } - return null; - } - } - - @HPyContextFunction("ctx_TupleBuilder_Build") - @GenerateUncached - public abstract static class GraalHPyTupleBuilderBuild extends HPyBuilderBuild { - @Override - final boolean isTupleBuilder() { - return true; - } - } - - @HPyContextFunction("ctx_ListBuilder_Build") - @GenerateUncached - public abstract static class GraalHPyListBuilderBuild extends HPyBuilderBuild { - @Override - final boolean isTupleBuilder() { - return false; - } - } - - @HPyContextFunction("ctx_TupleBuilder_Cancel") - @HPyContextFunction("ctx_ListBuilder_Cancel") - @GenerateUncached - public abstract static class GraalHPyBuilderCancel extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object builderHandle, - @Bind("this") Node inliningTarget, - @Cached HPyCloseAndGetHandleNode closeAndGetHandleNode) { - // be pedantic and also check what we are cancelling - ObjectSequenceStorage builder = HPyBuilderBuild.cast(closeAndGetHandleNode.execute(inliningTarget, builderHandle)); - if (builder == null) { - /* - * that's really unexpected since the C signature should enforce a valid builder but - * someone could have messed it up - */ - throw CompilerDirectives.shouldNotReachHere("invalid builder object"); - } - return 0; - } - } - - @HPyContextFunction("ctx_Tracker_New") - @GenerateUncached - public abstract static class GraalHPyTrackerNew extends HPyBinaryContextFunction { - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, long lcapacity, - @Cached HPyAsHandleNode asHandleNode) { - int capacity; - if (PInt.isIntRange(lcapacity) && (capacity = (int) lcapacity) >= 0) { - return asHandleNode.execute(new GraalHPyTracker(capacity)); - } - return NULL_HANDLE; - } - } - - @HPyContextFunction("ctx_Tracker_Add") - @GenerateUncached - public abstract static class GraalHPyTrackerAdd extends HPyTernaryContextFunction { - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object builderArg, Object item, - @Bind("this") Node inliningTarget, - @Cached HPyAsPythonObjectNode asPythonObjectNode, - @Cached HPyEnsureHandleNode ensureHandleNode) { - GraalHPyTracker builder = cast(asPythonObjectNode.execute(builderArg)); - if (builder == null) { - // that's really unexpected since the C signature should enforce a valid builder - // but someone could have messed it up - throw CompilerDirectives.shouldNotReachHere("invalid builder object"); - } - try { - GraalHPyHandle handle = ensureHandleNode.execute(inliningTarget, item); - if (handle != null) { - builder.add(handle); - } - } catch (OverflowException | OutOfMemoryError e) { - return -1; - } - return 0; - } - - static GraalHPyTracker cast(Object object) { - if (object instanceof GraalHPyTracker) { - return (GraalHPyTracker) object; - } - return null; - } - } - - @HPyContextFunction("ctx_Tracker_Close") - @GenerateUncached - public abstract static class GraalHPyTrackerCleanup extends HPyBinaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object builderHandle, - @Bind("this") Node inliningTarget, - @Cached HPyCloseAndGetHandleNode closeAndGetHandleNode, - @Cached HPyCloseHandleNode closeHandleNode) { - GraalHPyTracker builder = GraalHPyTrackerAdd.cast(closeAndGetHandleNode.execute(inliningTarget, builderHandle)); - if (builder == null) { - // that's really unexpected since the C signature should enforce a valid builder - // but someone could have messed it up - throw CompilerDirectives.shouldNotReachHere("invalid builder object"); - } - builder.free(inliningTarget, closeHandleNode); - return 0; - } - } - - @HPyContextFunction("ctx_Tracker_ForgetAll") - @GenerateUncached - public abstract static class GraalHPyTrackerForgetAll extends HPyBinaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object builderArg, - @Cached HPyAsPythonObjectNode asPythonObjectNode) { - GraalHPyTracker builder = GraalHPyTrackerAdd.cast(asPythonObjectNode.execute(builderArg)); - if (builder == null) { - // that's really unexpected since the C signature should enforce a valid builder - // but someone could have messed it up - throw CompilerDirectives.shouldNotReachHere("invalid builder object"); - } - builder.removeAll(); - return 0; - } - } - - @HPyContextFunction("ctx_Callable_Check") - @GenerateUncached - public abstract static class GraalHPyIsCallable extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object, - @Bind("this") Node inliningTarget, - @Cached PyCallableCheckNode callableCheck) { - return PInt.intValue(callableCheck.execute(inliningTarget, object)); - } - } - - @HPyContextFunction("ctx_CallTupleDict") - @GenerateUncached - public abstract static class GraalHPyCallTupleDict extends HPyQuaternaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object callable, Object argsObject, Object kwargsObject, - @Bind("this") Node inliningTarget, - @Cached ExecutePositionalStarargsNode expandArgsNode, - @Cached HashingStorageLen lenNode, - @Cached ExpandKeywordStarargsNode expandKwargsNode, - @Cached CallNode callNode, - @Cached PRaiseNode raiseNode) { - // check and expand args - Object[] args = castArgs(argsObject, expandArgsNode, raiseNode); - // check and expand kwargs - PKeyword[] keywords = castKwargs(inliningTarget, kwargsObject, lenNode, expandKwargsNode, raiseNode); - return callNode.executeWithoutFrame(callable, args, keywords); - } - - private static Object[] castArgs(Object args, - ExecutePositionalStarargsNode expandArgsNode, - PRaiseNode raiseNode) { - // this indicates that a NULL handle was passed (which is valid) - if (args == PNone.NO_VALUE) { - return PythonUtils.EMPTY_OBJECT_ARRAY; - } - if (PGuards.isPTuple(args)) { - return expandArgsNode.executeWith(null, args); - } - throw raiseNode.raise(TypeError, ErrorMessages.HPY_CALLTUPLEDICT_REQUIRES_ARGS_TUPLE_OR_NULL); - } - - private static PKeyword[] castKwargs(Node inliningTarget, Object kwargs, - HashingStorageLen lenNode, - ExpandKeywordStarargsNode expandKwargsNode, - PRaiseNode raiseNode) { - // this indicates that a NULL handle was passed (which is valid) - if (kwargs == PNone.NO_VALUE || isEmptyDict(inliningTarget, kwargs, lenNode)) { - return PKeyword.EMPTY_KEYWORDS; - } - if (PGuards.isDict(kwargs)) { - return expandKwargsNode.execute(inliningTarget, kwargs); - } - throw raiseNode.raise(TypeError, ErrorMessages.HPY_CALLTUPLEDICT_REQUIRES_KW_DICT_OR_NULL); - } - - private static boolean isEmptyDict(Node inliningTarget, Object delegate, HashingStorageLen lenNode) { - return delegate instanceof PDict && lenNode.execute(inliningTarget, ((PDict) delegate).getDictStorage()) == 0; - } - } - - @HPyContextFunction("ctx_Call") - @GenerateUncached - public abstract static class GraalHPyCall extends HPy5ContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object callable, Object args, long lnargs, Object kwnamesObj, - @Bind("this") Node inliningTarget, - @Cached(parameters = "hpyContext") GraalHPyCAccess.ReadHPyArrayNode readHPyArrayNode, - @Cached PyTupleSizeNode tupleSizeNode, - @Cached HPyPackKeywordArgsNode packKeywordArgsNode, - @Cached PRaiseNode raiseNode) { - - if (!PInt.isIntRange(lnargs)) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_DOES_NOT_SUPPORT_ITEM_ASSIGMENT, 0); - } - int nargs = (int) lnargs; - PTuple kwnames; - int nkw; - if (kwnamesObj instanceof PTuple) { - kwnames = (PTuple) kwnamesObj; - nkw = tupleSizeNode.execute(inliningTarget, kwnames); - } else { - nkw = 0; - kwnames = null; - } - - // positional args are from 'args[0]' ... 'args[nargs - 1]' - Object[] positionalArgs = readHPyArrayNode.execute(hpyContext, args, 0, nargs); - - PKeyword[] keywords; - if (nkw > 0) { - // keyword arg values are from 'args[nargs]' ... 'args[nargs + nkw - 1]' - Object[] kwObjs = readHPyArrayNode.execute(hpyContext, args, nargs, nkw); - keywords = packKeywordArgsNode.execute(inliningTarget, kwObjs, kwnames, nkw); - } else { - keywords = PKeyword.EMPTY_KEYWORDS; - } - - /* - * We use the uncached CallNode for now as a workaround because - * 'AbstractCallMethodNode.callerExceedsMaxSize' assumes that a call node is always - * under a root node. However, in cross-language calls, this may not be the case. - */ - return CallNode.executeUncached(callable, positionalArgs, keywords); - } - } - - @HPyContextFunction("ctx_CallMethod") - @GenerateUncached - @ImportStatic(PGuards.class) - public abstract static class GraalHPyCallMethod extends HPy5ContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, TruffleString name, Object args, long lnargs, Object kwnames, - @Bind("this") Node inliningTarget, - @Cached(parameters = "hpyContext") GraalHPyCAccess.ReadHPyArrayNode readHPyArrayNode, - @Cached PyTupleSizeNode tupleSizeNode, - @Cached HPyPackKeywordArgsNode packKeywordArgsNode, - @Cached PyObjectGetMethod getMethodNode, - @Cached CallNode callNode, - @Cached PRaiseNode raiseNode) { - - if (!PInt.isIntRange(lnargs)) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_DOES_NOT_SUPPORT_ITEM_ASSIGMENT, 0); - } - int nargs = (int) lnargs; - int nkw = kwnames != PNone.NO_VALUE ? tupleSizeNode.execute(inliningTarget, kwnames) : 0; - - // positional args are from 'args[0]' ... 'args[nargs - 1]' (including 'self') - Object[] positionalArgs = readHPyArrayNode.execute(hpyContext, args, 0, nargs); - Object receiver = positionalArgs[0]; - - Object callable = getMethodNode.execute(null, inliningTarget, receiver, name); - - PKeyword[] keywords; - if (nkw > 0) { - // check and expand kwargs - Object[] kwObjs = readHPyArrayNode.execute(hpyContext, args, nargs, nkw); - keywords = packKeywordArgsNode.execute(inliningTarget, kwObjs, (PTuple) kwnames, nkw); - } else { - keywords = PKeyword.EMPTY_KEYWORDS; - } - return callNode.executeWithoutFrame(callable, positionalArgs, keywords); - } - } - - @HPyContextFunction("ctx_Dump") - @GenerateUncached - public abstract static class GraalHPyDump extends HPyBinaryContextFunction { - - @Specialization - @TruffleBoundary - static int doGeneric(GraalHPyContext hpyContext, Object object) { - PythonContext context = hpyContext.getContext(); - Object type = GetClassNode.executeUncached(object); - PrintWriter stderr = new PrintWriter(context.getStandardErr()); - stderr.println("object type : " + type); - stderr.println("object type name: " + GetNameNode.executeUncached(type)); - - // the most dangerous part - stderr.println("object repr : "); - stderr.flush(); - try { - stderr.println(PyObjectReprAsTruffleStringNode.executeUncached(object).toJavaStringUncached()); - stderr.flush(); - } catch (PException | CannotCastException e) { - // errors are ignored at this point - } - return 0; - } - } - - @HPyContextFunction("ctx_Type") - @GenerateUncached - public abstract static class GraalHPyType extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode) { - return getClassNode.execute(inliningTarget, object); - } - } - - @HPyContextFunction("ctx_TypeCheck") - @GenerateUncached - public abstract static class GraalHPyTypeCheck extends HPyTernaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object object, Object type, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached IsSubtypeNode isSubtypeNode) { - return PInt.intValue(isSubtypeNode.execute(getClassNode.execute(inliningTarget, object), type)); - } - } - - @HPyContextFunction("ctx_Err_NewExceptionWithDoc") - @GenerateUncached - public abstract static class GraalHPyNewExceptionWithDoc extends HPy5ContextFunction { - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object namePtr, Object docPtr, Object base, Object dictObj, - @Bind("this") Node inliningTarget, - @Cached(parameters = "hpyContext") GraalHPyCAccess.IsNullNode isNullNode, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached TruffleString.IndexOfCodePointNode indexOfCodepointNode, - @Cached TruffleString.CodePointLengthNode codepointLengthNode, - @Cached TruffleString.SubstringNode substringNode, - @Cached HashingStorageGetItem getHashingStorageItem, - @Cached HashingStorageSetItem setHashingStorageItem, - @Cached CallNode callTypeConstructorNode, - @Cached PRaiseNode raiseNode, - @Cached PythonObjectFactory factory) { - TruffleString doc; - if (!isNullNode.execute(hpyContext, docPtr)) { - doc = fromCharPointerNode.execute(docPtr); - } else { - doc = null; - } - return createNewExceptionWithDoc(inliningTarget, namePtr, base, dictObj, doc, fromCharPointerNode, indexOfCodepointNode, codepointLengthNode, substringNode, - getHashingStorageItem, - setHashingStorageItem, callTypeConstructorNode, raiseNode, factory); - } - - static Object createNewExceptionWithDoc(Node inliningTarget, Object namePtr, Object base, Object dictObj, TruffleString doc, - FromCharPointerNode fromCharPointerNode, - TruffleString.IndexOfCodePointNode indexOfCodepointNode, - TruffleString.CodePointLengthNode codepointLengthNode, - TruffleString.SubstringNode substringNode, - HashingStorageGetItem getHashingStorageItem, - HashingStorageSetItem setHashingStorageItem, - CallNode callTypeConstructorNode, - PRaiseNode raiseNode, - PythonObjectFactory factory) { - - TruffleString name = fromCharPointerNode.execute(namePtr); - int len = codepointLengthNode.execute(name, TS_ENCODING); - int dotIdx = indexOfCodepointNode.execute(name, '.', 0, len, TS_ENCODING); - if (dotIdx < 0) { - throw raiseNode.raise(SystemError, ErrorMessages.NAME_MUST_BE_MOD_CLS); - } - - if (base == PNone.NO_VALUE) { - base = PythonBuiltinClassType.Exception; - } - PDict dict; - HashingStorage dictStorage; - if (dictObj == PNone.NO_VALUE) { - dictStorage = new DynamicObjectStorage(PythonLanguage.get(inliningTarget)); - dict = factory.createDict(dictStorage); - } else { - if (!(dictObj instanceof PDict)) { - /* - * CPython expects a PyDictObject and if not, it raises a - * ErrorMessages.BAD_INTERNAL_CALL. - */ - throw raiseNode.raise(SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC); - } - dict = (PDict) dictObj; - dictStorage = dict.getDictStorage(); - } - - if (!getHashingStorageItem.hasKey(inliningTarget, dictStorage, SpecialAttributeNames.T___MODULE__)) { - dictStorage = setHashingStorageItem.execute(inliningTarget, dictStorage, SpecialAttributeNames.T___MODULE__, substringNode.execute(name, 0, dotIdx, TS_ENCODING, false)); - } - if (doc != null) { - dictStorage = setHashingStorageItem.execute(inliningTarget, dictStorage, SpecialAttributeNames.T___DOC__, doc); - } - dict.setDictStorage(dictStorage); - - PTuple bases; - if (base instanceof PTuple) { - bases = (PTuple) base; - } else { - bases = factory.createTuple(new Object[]{base}); - } - - return callTypeConstructorNode.executeWithoutFrame(PythonBuiltinClassType.PythonClass, substringNode.execute(name, dotIdx + 1, len - dotIdx - 1, TS_ENCODING, false), bases, dict); - } - } - - @HPyContextFunction("ctx_Err_NewException") - @GenerateUncached - public abstract static class GraalHPyNewException extends HPyQuaternaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object namePtr, Object base, Object dictObj, - @Bind("this") Node inliningTarget, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached TruffleString.IndexOfCodePointNode indexOfCodepointNode, - @Cached TruffleString.CodePointLengthNode codepointLengthNode, - @Cached TruffleString.SubstringNode substringNode, - @Cached HashingStorageGetItem getHashingStorageItem, - @Cached HashingStorageSetItem setHashingStorageItem, - @Cached CallNode callTypeConstructorNode, - @Cached PRaiseNode raiseNode, - @Cached PythonObjectFactory factory) { - return GraalHPyNewExceptionWithDoc.createNewExceptionWithDoc(inliningTarget, namePtr, base, dictObj, null, fromCharPointerNode, indexOfCodepointNode, - codepointLengthNode, - substringNode, getHashingStorageItem, setHashingStorageItem, callTypeConstructorNode, raiseNode, factory); - } - } - - @HPyContextFunction("ctx_Is") - @GenerateUncached - public abstract static class GraalHPyIs extends HPyTernaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object left, Object right, - @Cached IsNode isNode) { - return PInt.intValue(isNode.execute(left, right)); - } - } - - @HPyContextFunction("ctx_Import_ImportModule") - @GenerateUncached - public abstract static class GraalHPyImportModule extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object charPtr, - @Cached FromCharPointerNode fromCharPointerNode) { - return AbstractImportNode.importModule(fromCharPointerNode.execute(charPtr)); - } - } - - @HPyContextFunction("ctx_Field_Store") - @GenerateUncached - public abstract static class GraalHPyFieldStore extends HPyQuaternaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, PythonObject owner, Object hpyFieldPtr, Object referent, - @Cached(parameters = "hpyContext") GraalHPyCAccess.WriteHPyFieldNode writeHPyFieldNode) { - writeHPyFieldNode.write(hpyContext, owner, hpyFieldPtr, referent); - return 0; - } - } - - @HPyContextFunction("ctx_Field_Load") - @GenerateUncached - public abstract static class GraalHPyFieldLoad extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, PythonObject owner, Object hpyFieldPtr, - @Bind("this") Node inliningTarget, - @Cached HPyFieldLoadNode hPyFieldLoadNode) { - return hPyFieldLoadNode.execute(inliningTarget, owner, hpyFieldPtr); - } - } - - @HPyContextFunction("ctx_Global_Store") - @GenerateUncached - public abstract static class GraalHPyGlobalStore extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object hpyGlobalPtr, Object value, - @Bind("this") Node inliningTarget, - @Cached(parameters = "hpyContext") GraalHPyCAccess.ReadPointerNode readPointerNode, - @Cached(parameters = "hpyContext") GraalHPyCAccess.WritePointerNode writePointerNode, - @Cached InlinedExactClassProfile typeProfile, - @CachedLibrary(limit = "3") InteropLibrary lib) { - Object hpyGlobal = typeProfile.profile(inliningTarget, readPointerNode.execute(hpyContext, hpyGlobalPtr, 0)); - - int idx = -1; - if (hpyGlobal instanceof GraalHPyHandle) { - // branch profiling with typeProfile - idx = ((GraalHPyHandle) hpyGlobal).getGlobalId(); - } else if (!(hpyGlobal instanceof Long) && lib.isNull(hpyGlobal)) { - // nothing to do - } else { - long bits; - if (hpyGlobal instanceof Long) { - // branch profile due to lib.asPointer usage in else branch - // and typeProfile - bits = (Long) hpyGlobal; - } else { - try { - bits = lib.asPointer(hpyGlobal); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } - if (GraalHPyBoxing.isBoxedHandle(bits)) { - idx = GraalHPyBoxing.unboxHandle(bits); - } - } - - // TODO: (tfel) do not actually allocate the index / free the existing one when - // value can be stored as tagged handle - idx = hpyContext.createGlobal(value, idx); - GraalHPyHandle newHandle = GraalHPyHandle.createGlobal(value, idx); - writePointerNode.execute(hpyContext, hpyGlobalPtr, 0, newHandle); - return 0; - } - } - - @HPyContextFunction("ctx_Global_Load") - @GenerateUncached - public abstract static class GraalHPyGlobalLoad extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object hpyGlobal, - @CachedLibrary(limit = "3") InteropLibrary lib) { - if (hpyGlobal instanceof GraalHPyHandle h) { - // branch profiling with typeProfile - return h.getDelegate(); - } else if (!(hpyGlobal instanceof Long) && lib.isNull(hpyGlobal)) { - // type profile influences first test - return NULL_HANDLE_DELEGATE; - } else { - long bits; - if (hpyGlobal instanceof Long) { - // branch profile due to lib.asPointer usage in else branch - // and typeProfile - bits = (Long) hpyGlobal; - } else { - try { - bits = lib.asPointer(hpyGlobal); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } - if (GraalHPyBoxing.isBoxedHandle(bits)) { - // if asHandleNode wasn't used above, it acts as a branch profile - // here. otherwise we're probably already pulling in a lot of code - // and are a bit too polymorphic - return hpyContext.getObjectForHPyGlobal(GraalHPyBoxing.unboxHandle(bits)); - } else { - // tagged handles can be returned directly - return bits; - } - } - } - } - - @HPyContextFunction("ctx_LeavePythonExecution") - @GenerateUncached - public abstract static class GraalHPyLeavePythonExecution extends HPyUnaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, - @Bind("this") Node inliningTarget, - @Cached GilNode gil) { - PythonContext context = hpyContext.getContext(); - PythonThreadState threadState = context.getThreadState(context.getLanguage(inliningTarget)); - gil.release(context, true); - return threadState; - } - } - - @HPyContextFunction("ctx_ReenterPythonExecution") - @GenerateUncached - public abstract static class GraalHPyReenterPythonExecution extends HPyBinaryContextFunction { - - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, @SuppressWarnings("unused") Object threadState, - @Cached GilNode gil) { - // nothing to do with PThreadState in 'threadState' - gil.acquire(hpyContext.getContext()); - return 0; - } - } - - @HPyContextFunction("ctx_Contains") - @ImportStatic(SpecialMethodSlot.class) - @GenerateUncached - public abstract static class GraalHPyContains extends HPyTernaryContextFunction { - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object container, Object key, - @Bind("this") Node inliningTarget, - @Cached PySequenceContainsNode containsNode) { - return PInt.intValue(containsNode.execute(null, inliningTarget, container, key)); - } - } - - @HPyContextFunction("ctx_Type_IsSubtype") - @GenerateUncached - public abstract static class GraalHPyTypeIsSubtype extends HPyTernaryContextFunction { - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object derived, Object type, - @Cached IsSubtypeNode isSubtype) { - return PInt.intValue(isSubtype.execute(derived, type)); - } - } - - @HPyContextFunction("ctx_Type_GetName") - @GenerateUncached - public abstract static class GraalHPyTypeGetName extends HPyBinaryContextFunction { - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object type, - @Bind("this") Node inliningTarget, - @Cached HPyTypeGetNameNode getName) { - return getName.execute(inliningTarget, hpyContext, type); - } - } - - @HPyContextFunction("ctx_Dict_Keys") - @GenerateUncached - public abstract static class GraalHPyDictKeys extends HPyBinaryContextFunction { - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object dictObj, - @Bind("this") Node inliningTarget, - @Cached PyDictKeys keysNode, - @Cached PRaiseNode.Lazy raiseNode) { - if (dictObj instanceof PDict dict) { - return keysNode.execute(inliningTarget, dict); - } - throw raiseNode.get(inliningTarget).raise(SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC); - } - } - - @HPyContextFunction("ctx_Dict_Copy") - @GenerateUncached - public abstract static class GraalHPyDictCopy extends HPyBinaryContextFunction { - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object dictObj, - @Bind("this") Node inliningTarget, - @Cached HashingStorageCopy copyNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - if (dictObj instanceof PDict dict) { - return factory.createDict(copyNode.execute(inliningTarget, dict.getDictStorage())); - } - throw raiseNode.get(inliningTarget).raise(SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC); - } - } - - // see _HPyCapsule_key in the HPy API - public static final class CapsuleKey { - public static final byte Pointer = 0; - public static final byte Name = 1; - public static final byte Context = 2; - public static final byte Destructor = 3; - } - - @HPyContextFunction("ctx_Capsule_New") - @GenerateUncached - public abstract static class GraalHPyCapsuleNew extends HPyQuaternaryContextFunction { - - @Specialization - static PyCapsule doGeneric(GraalHPyContext hpyContext, Object pointer, Object namePtr, Object dtorPtr, - @Cached(parameters = "hpyContext") GraalHPyCAccess.ReadPointerNode readPointerNode, - @Cached(parameters = "hpyContext") GraalHPyCAccess.IsNullNode isNullNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode raiseNode) { - if (isNullNode.execute(hpyContext, pointer)) { - throw raiseNode.raise(ValueError, ErrorMessages.HPYCAPSULE_NEW_NULL_PTR_ERROR); - } - Object hpyDestructor = null; - if (!isNullNode.execute(hpyContext, dtorPtr)) { - Object cpyTrampoline = readPointerNode.read(hpyContext, dtorPtr, GraalHPyCField.HPyCapsule_Destructor__cpy_trampoline); - hpyDestructor = readPointerNode.read(hpyContext, dtorPtr, GraalHPyCField.HPyCapsule_Destructor__impl); - if (isNullNode.execute(hpyContext, cpyTrampoline) || isNullNode.execute(hpyContext, hpyDestructor)) { - throw raiseNode.raise(ValueError, ErrorMessages.INVALID_HPYCAPSULE_DESTRUCTOR); - } - } - PyCapsule capsule = factory.createCapsuleNativeName(pointer, namePtr); - if (hpyDestructor != null) { - capsule.registerDestructor(hpyDestructor); - } - return capsule; - } - } - - @HPyContextFunction("ctx_Capsule_Get") - @GenerateUncached - public abstract static class GraalHPyCapsuleGet extends HPyQuaternaryContextFunction { - public static final TruffleString INCORRECT_NAME = tsLiteral("HPyCapsule_GetPointer called with incorrect name"); - - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object capsule, int key, Object namePtr, - @Bind("this") Node inliningTarget, - @Cached PyCapsuleNameMatchesNode nameMatchesNode, - @Cached PRaiseNode raiseNode) { - isLegalCapsule(capsule, key, raiseNode); - PyCapsule pyCapsule = (PyCapsule) capsule; - Object result; - switch (key) { - case CapsuleKey.Pointer -> { - if (!nameMatchesNode.execute(inliningTarget, pyCapsule.getNamePtr(), namePtr)) { - throw raiseNode.raise(ValueError, INCORRECT_NAME); - } - result = pyCapsule.getPointer(); - } - case CapsuleKey.Context -> result = pyCapsule.getContext(); - case CapsuleKey.Name -> result = pyCapsule.getNamePtr(); - case CapsuleKey.Destructor -> result = pyCapsule.getDestructor(); - default -> throw CompilerDirectives.shouldNotReachHere("invalid key"); - } - // never allow Java 'null' to be returned - if (result == null) { - return PNone.NO_VALUE; - } - return result; - } - - public static void isLegalCapsule(Object object, int key, PRaiseNode raiseNode) { - if (!(object instanceof PyCapsule) || ((PyCapsule) object).getPointer() == null) { - throw raiseNode.raise(ValueError, getErrorMessage(key)); - } - } - - @TruffleBoundary - public static TruffleString getErrorMessage(int key) { - return switch (key) { - case CapsuleKey.Pointer -> ErrorMessages.CAPSULE_GETPOINTER_WITH_INVALID_CAPSULE; - case CapsuleKey.Context -> ErrorMessages.CAPSULE_GETCONTEXT_WITH_INVALID_CAPSULE; - case CapsuleKey.Name -> ErrorMessages.CAPSULE_GETNAME_WITH_INVALID_CAPSULE; - case CapsuleKey.Destructor -> ErrorMessages.CAPSULE_GETDESTRUCTOR_WITH_INVALID_CAPSULE; - default -> throw CompilerDirectives.shouldNotReachHere("invalid key"); - }; - } - } - - @HPyContextFunction("ctx_Capsule_Set") - @GenerateUncached - public abstract static class GraalHPyCapsuleSet extends HPyQuaternaryContextFunction { - @Specialization - static int doGeneric(GraalHPyContext hpyContext, Object capsule, int key, Object valuePtr, - @Cached(parameters = "hpyContext") GraalHPyCAccess.IsNullNode isNullNode, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached PRaiseNode raiseNode) { - GraalHPyCapsuleGet.isLegalCapsule(capsule, key, raiseNode); - PyCapsule pyCapsule = (PyCapsule) capsule; - switch (key) { - case CapsuleKey.Pointer -> { - if (isNullNode.execute(hpyContext, valuePtr)) { - throw raiseNode.raise(ValueError, ErrorMessages.CAPSULE_SETPOINTER_CALLED_WITH_NULL_POINTER); - } - pyCapsule.setPointer(valuePtr); - } - case CapsuleKey.Context -> pyCapsule.setContext(valuePtr); - case CapsuleKey.Name -> { - // we may assume that the pointer is owned - pyCapsule.setNamePtr(fromCharPointerNode.execute(valuePtr, false)); - } - case CapsuleKey.Destructor -> pyCapsule.registerDestructor(isNullNode.execute(hpyContext, valuePtr) ? null : valuePtr); - default -> throw CompilerDirectives.shouldNotReachHere("invalid key"); - } - return 0; - } - } - - @HPyContextFunction("ctx_Capsule_IsValid") - @GenerateUncached - public abstract static class GraalHPyCapsuleIsValid extends HPyTernaryContextFunction { - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object capsule, Object namePtr, - @Bind("this") Node inliningTarget, - @Cached PyCapsuleNameMatchesNode nameMatchesNode) { - return PInt.intValue(capsule instanceof PyCapsule pyCapsule && nameMatchesNode.execute(inliningTarget, pyCapsule.getNamePtr(), namePtr)); - } - } - - @HPyContextFunction("ctx_ContextVar_New") - @GenerateUncached - public abstract static class GraalHPyContextVarNew extends HPyTernaryContextFunction { - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object namePtr, Object def, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached CallNode callContextvar) { - TruffleString name = fromCharPointerNode.execute(namePtr); - return callContextvar.executeWithoutFrame(PythonBuiltinClassType.ContextVar, name, def); - } - } - - @HPyContextFunction("ctx_ContextVar_Get") - @GenerateUncached - public abstract static class GraalHPyContextVarGet extends HPyQuaternaryContextFunction { - @Specialization - static int doGeneric(GraalHPyContext hpyContext, Object var, Object def, Object outPtr, - @Bind("this") Node inliningTarget, - @Cached PRaiseNode raiseNode, - @Cached(parameters = "hpyContext") GraalHPyCAccess.WriteHPyNode writeHPyNode) { - if (!(var instanceof PContextVar contextVar)) { - throw raiseNode.raise(TypeError, ErrorMessages.INSTANCE_OF_CONTEXTVAR_EXPECTED); - } - PythonContext context = hpyContext.getContext(); - PythonThreadState threadState = context.getThreadState(context.getLanguage(inliningTarget)); - Object result = getObject(threadState, contextVar, def); - writeHPyNode.write(hpyContext, outPtr, result); - return 0; - } - - public static Object getObject(PythonThreadState threadState, PContextVar var, Object def) { - Object result = var.getValue(threadState); - if (result == null) { - if (def == NULL_HANDLE_DELEGATE) { - def = var.getDefault(); - if (def == PContextVar.NO_DEFAULT) { - def = NULL_HANDLE_DELEGATE; - } - } - result = def; - } - return result; - } - } - - @HPyContextFunction("ctx_ContextVar_Set") - @GenerateUncached - public abstract static class GraalHPyContextVarSet extends HPyTernaryContextFunction { - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object var, Object val, - @Bind("this") Node inliningTarget, - @Cached PRaiseNode raiseNode, - @Cached PythonObjectFactory factory) { - if (!(var instanceof PContextVar contextVar)) { - throw raiseNode.raise(TypeError, ErrorMessages.INSTANCE_OF_CONTEXTVAR_EXPECTED); - } - PythonContext context = hpyContext.getContext(); - PythonThreadState threadState = context.getThreadState(context.getLanguage(inliningTarget)); - Object oldValue = contextVar.getValue(threadState); - contextVar.setValue(threadState, val); - return factory.createContextVarsToken(contextVar, oldValue); - } - } - - @HPyContextFunction("ctx_Unicode_FromEncodedObject") - @GenerateUncached - public abstract static class GraalHPyUnicodeFromEncodedObject extends HPyQuaternaryContextFunction { - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object obj, Object encodingPtr, Object errorsPtr, - @Bind("this") Node inliningTarget, - @Cached InlinedConditionProfile nullProfile, - @Cached(parameters = "hpyContext") GraalHPyCAccess.IsNullNode isNullNode, - @Cached(parameters = "hpyContext") HPyFromCharPointerNode fromNativeCharPointerNode, - @Cached PyUnicodeFromEncodedObject libNode) { - if (nullProfile.profile(inliningTarget, obj == PNone.NO_VALUE)) { - throw PRaiseNode.raiseUncached(inliningTarget, SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC); - } - TruffleString encoding; - if (!isNullNode.execute(hpyContext, encodingPtr)) { - encoding = fromNativeCharPointerNode.execute(hpyContext, encodingPtr, true); - } else { - encoding = T_UTF8; - } - - TruffleString errors; - if (!isNullNode.execute(hpyContext, errorsPtr)) { - errors = fromNativeCharPointerNode.execute(hpyContext, errorsPtr, true); - } else { - errors = T_STRICT; - } - return libNode.execute(null, inliningTarget, obj, encoding, errors); - } - } - - @HPyContextFunction("ctx_Unicode_Substring") - @GenerateUncached - public abstract static class GraalHPyUnicodeSubstring extends HPyQuaternaryContextFunction { - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, Object obj, long lstart, long lend, - @Bind("this") Node inliningTarget, - @Cached CastToTruffleStringNode castStr, - @Cached CastToJavaIntExactNode castStart, - @Cached CastToJavaIntExactNode castEnd, - @Cached InlinedConditionProfile profile, - @Cached TruffleString.CodePointLengthNode codePointLengthNode, - @Cached StrGetItemNodeWithSlice getSlice) { - TruffleString value = castStr.execute(inliningTarget, obj); - int start = castStart.execute(inliningTarget, lstart); - int end = castEnd.execute(inliningTarget, lend); - if (profile.profile(inliningTarget, start < 0 || end < 0)) { - throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.IndexError, ErrorMessages.STRING_INDEX_OUT_OF_RANGE); - } - SliceInfo sliceInfo = PSlice.computeIndices(start, end, 1, codePointLengthNode.execute(value, TS_ENCODING)); - return getSlice.execute(value, sliceInfo); - } - } - - @HPyContextFunction("ctx_Slice_Unpack") - @GenerateUncached - public abstract static class GraalHPySliceUnpack extends HPy5ContextFunction { - @Specialization - static int doGeneric(GraalHPyContext hpyContext, Object obj, Object startPtr, Object endPtr, Object stepPtr, - @Bind("this") Node inliningTarget, - @Cached(parameters = "hpyContext") GraalHPyCAccess.WriteI64Node writeHPyNode, - @Cached SliceNodes.SliceUnpackLong sliceUnpack) { - if (obj instanceof PSlice slice) { - SliceInfoLong info = sliceUnpack.execute(inliningTarget, slice); - writeHPyNode.write(hpyContext, startPtr, info.start()); - writeHPyNode.write(hpyContext, endPtr, info.stop()); - writeHPyNode.write(hpyContext, stepPtr, info.step()); - return 0; - } - return -1; - } - } - - @HPyContextFunction("ctx_Type_GetBuiltinShape") - @GenerateUncached - public abstract static class GraalHPyTypeGetBuiltinShape extends HPyBinaryContextFunction { - - @Specialization - static int doGeneric(@SuppressWarnings("unused") Object hpyContext, Object typeObject, - @Bind("this") Node inliningTarget, - @Cached InlinedExactClassProfile classProfile, - @Cached PRaiseNode raiseNode) { - Object profiledTypeObject = classProfile.profile(inliningTarget, typeObject); - int result = GraalHPyDef.getBuiltinShapeFromHiddenAttribute(profiledTypeObject); - if (result == -2) { - throw raiseNode.raise(TypeError, ErrorMessages.S_MUST_BE_S, "arg", "type"); - } - return result; - } - } - - @HPyContextFunction("ctx_Compile_s") - @GenerateUncached - public abstract static class GraalHPyCompile extends HPyQuaternaryContextFunction { - @Specialization - static Object doGeneric(GraalHPyContext hpyContext, Object srcPtr, Object filenamePtr, int kind, - @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached CallNode callNode, - @Cached PRaiseNode raiseNode) { - TruffleString src = fromCharPointerNode.execute(srcPtr); - TruffleString filename = fromCharPointerNode.execute(filenamePtr); - Object builtinFunction = readAttributeFromObjectNode.execute(hpyContext.getContext().getBuiltins(), BuiltinNames.T_COMPILE); - GraalHPySourceKind sourceKind = GraalHPySourceKind.fromValue(kind); - if (sourceKind == null) { - throw raiseNode.raise(SystemError, ErrorMessages.HPY_INVALID_SOURCE_KIND); - } - return callNode.executeWithoutFrame(builtinFunction, src, filename, sourceKind.getMode()); - } - } - - @HPyContextFunction("ctx_EvalCode") - @GenerateUncached - public abstract static class GraalHPyEvalCode extends HPyQuaternaryContextFunction { - @Specialization - static Object doGeneric(@SuppressWarnings("unused") Object hpyContext, PCode code, Object globals, Object locals, - @Bind("this") Node inliningTarget, - @Cached PRaiseNode raiseNode, - @Cached CodeNodes.GetCodeCallTargetNode getCallTargetNode, - @Cached GenericInvokeNode invokeNode) { - - // prepare Python frame arguments - Object[] pArguments = PArguments.create(); - - if (locals == PNone.NO_VALUE) { - locals = globals; - } - PArguments.setSpecialArgument(pArguments, locals); - // TODO(fa): set builtins in globals - // PythonModule builtins = getContext().getBuiltins(); - // setBuiltinsInGlobals(globals, setBuiltins, builtins, lib); - if (globals instanceof PythonObject) { - PArguments.setGlobals(pArguments, (PythonObject) globals); - } else { - throw raiseNode.raise(SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC); - } - - RootCallTarget rootCallTarget = getCallTargetNode.execute(inliningTarget, code); - return invokeNode.execute(rootCallTarget, pArguments); - } - } - - @HPyContextFunction("ctx_SetCallFunction") - @GenerateUncached - public abstract static class GraalHPySetCallFunction extends HPyTernaryContextFunction { - @Specialization - static int doGeneric(GraalHPyContext hpyContext, PythonObject object, Object callFunctionDefPtr, - @Bind("this") Node inliningTarget, - @Cached GetPythonObjectClassNode getClassNode, - @Cached InlinedBranchProfile errorProfile, - @Cached HPyReadCallFunctionNode readCallFunctionNode) { - - Object clazz = getClassNode.execute(inliningTarget, object); - if (!(clazz instanceof PythonClass pythonClass) || !pythonClass.isHPyType()) { - errorProfile.enter(inliningTarget); - throw PRaiseNode.raiseUncached(inliningTarget, TypeError, ErrorMessages.HPY_TYPE_DOES_NOT_IMPLEMENT_CALL_PROTOCOL, clazz); - } - Object callFunction = readCallFunctionNode.execute(inliningTarget, hpyContext, callFunctionDefPtr); - GraalHPyData.setHPyCallFunction(object, callFunction); - return 0; - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyData.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyData.java deleted file mode 100644 index 660ada5a2b..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyData.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.util.PythonUtils; - -public abstract class GraalHPyData { - private static final int INDEX_DATA_PTR = 0; - private static final int INDEX_CALL_FUN = 1; - private static final int HPY_FIELD_OFFSET = 1; - - private static final Long DEFAULT_DATA_PTR_VALUE = 0L; - private static final Object DEFAULT_CALL_FUNCTION_VALUE = null; - - public static void setHPyNativeSpace(PythonObject object, Object dataPtr) { - Object[] hpyData = object.getHPyData(); - if (hpyData == null) { - hpyData = new Object[]{dataPtr, DEFAULT_CALL_FUNCTION_VALUE}; - object.setHPyData(hpyData); - } else { - hpyData[INDEX_DATA_PTR] = dataPtr; - } - } - - public static Object getHPyNativeSpace(PythonObject object) { - Object[] hpyData = object.getHPyData(); - return hpyData != null ? hpyData[INDEX_DATA_PTR] : DEFAULT_DATA_PTR_VALUE; - } - - public static void setHPyCallFunction(PythonObject object, Object callFunctionPtr) { - Object[] hpyData = object.getHPyData(); - if (hpyData == null) { - hpyData = new Object[]{DEFAULT_DATA_PTR_VALUE, callFunctionPtr}; - object.setHPyData(hpyData); - } else { - hpyData[INDEX_CALL_FUN] = callFunctionPtr; - } - } - - public static Object getHPyCallFunction(PythonObject object) { - Object[] hpyData = object.getHPyData(); - return hpyData != null ? hpyData[INDEX_CALL_FUN] : null; - } - - public static Object getHPyField(PythonObject object, int location) { - assert location > 0; - Object[] hpyData = object.getHPyData(); - return hpyData != null ? hpyData[location + HPY_FIELD_OFFSET] : null; - } - - public static int setHPyField(PythonObject object, Object referent, int location) { - Object[] hpyFields = object.getHPyData(); - if (location != 0) { - assert hpyFields != null; - hpyFields[location + HPY_FIELD_OFFSET] = referent; - return location; - } else { - int newLocation; - if (hpyFields == null) { - newLocation = 1; - hpyFields = new Object[]{DEFAULT_DATA_PTR_VALUE, null, referent}; - } else { - int newFieldIdx = hpyFields.length; - hpyFields = PythonUtils.arrayCopyOf(hpyFields, newFieldIdx + 1); - hpyFields[newFieldIdx] = referent; - newLocation = newFieldIdx - HPY_FIELD_OFFSET; - } - object.setHPyData(hpyFields); - return newLocation; - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyDef.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyDef.java deleted file mode 100644 index 81803d6aff..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyDef.java +++ /dev/null @@ -1,546 +0,0 @@ -/* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlotWrapper.RICHCMP_EQ; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlotWrapper.RICHCMP_GE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlotWrapper.RICHCMP_GT; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlotWrapper.RICHCMP_LE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlotWrapper.RICHCMP_LT; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlotWrapper.RICHCMP_NE; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ABS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ADD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AND__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___BOOL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___CALL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___CONTAINS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___DELITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___DIVMOD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___EQ__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___FLOAT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___FLOORDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IADD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IAND__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IFLOORDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ILSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IMATMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IMOD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INDEX__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INVERT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IOR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IPOW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IRSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ISUB__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ITRUEDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IXOR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LEN__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MATMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MOD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEG__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___OR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___POS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___POW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RADD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RAND__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___REPR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RFLOORDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RLSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RMATMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RMOD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ROR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RRSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RSUB__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RTRUEDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RXOR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SETITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___STR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SUB__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___TRUEDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___XOR__; - -import java.util.Arrays; - -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; -import com.oracle.graal.python.builtins.objects.cext.common.CExtContext; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.LLVMType; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyNew; -import com.oracle.graal.python.builtins.objects.type.PythonClass; -import com.oracle.graal.python.builtins.objects.type.TpSlots.TpSlotMeta; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode; -import com.oracle.graal.python.nodes.HiddenAttr; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.strings.TruffleString; - -/** - * A container class for mirroring definitions of {@code hpydef.h} - */ -public abstract class GraalHPyDef { - - /* enum values of 'HPyDef_Kind' */ - public static final int HPY_DEF_KIND_SLOT = 1; - public static final int HPY_DEF_KIND_METH = 2; - public static final int HPY_DEF_KIND_MEMBER = 3; - public static final int HPY_DEF_KIND_GETSET = 4; - - /** - * Same as {@code HPyFunc_Signature}. - */ - enum HPyFuncSignature { - VARARGS(1, LLVMType.HPyFunc_varargs), // METH_VARARGS - KEYWORDS(2, LLVMType.HPyFunc_keywords), // METH_VARARGS | METH_KEYWORDS - NOARGS(3, LLVMType.HPyFunc_noargs), // METH_NOARGS - O(4, LLVMType.HPyFunc_o), // METH_O - DESTROYFUNC(5, LLVMType.HPyFunc_destroyfunc), - GETBUFFERPROC(6, LLVMType.HPyFunc_getbufferproc), - RELEASEBUFFERPROC(7, LLVMType.HPyFunc_releasebufferproc), - UNARYFUNC(8, LLVMType.HPyFunc_unaryfunc), - BINARYFUNC(9, LLVMType.HPyFunc_binaryfunc), - TERNARYFUNC(10, LLVMType.HPyFunc_ternaryfunc), - INQUIRY(11, LLVMType.HPyFunc_inquiry), - LENFUNC(12, LLVMType.HPyFunc_lenfunc), - SSIZEARGFUNC(13, LLVMType.HPyFunc_ssizeargfunc), - SSIZESSIZEARGFUNC(14, LLVMType.HPyFunc_ssizessizeargfunc), - SSIZEOBJARGPROC(15, LLVMType.HPyFunc_ssizeobjargproc), - SSIZESSIZEOBJARGPROC(16, LLVMType.HPyFunc_ssizessizeobjargproc), - OBJOBJARGPROC(17, LLVMType.HPyFunc_objobjargproc), - FREEFUNC(18, LLVMType.HPyFunc_freefunc), - GETATTRFUNC(19, LLVMType.HPyFunc_getattrfunc), - GETATTROFUNC(20, LLVMType.HPyFunc_getattrofunc), - SETATTRFUNC(21, LLVMType.HPyFunc_setattrfunc), - SETATTROFUNC(22, LLVMType.HPyFunc_setattrofunc), - REPRFUNC(23, LLVMType.HPyFunc_reprfunc), - HASHFUNC(24, LLVMType.HPyFunc_hashfunc), - RICHCMPFUNC(25, LLVMType.HPyFunc_richcmpfunc), - GETITERFUNC(26, LLVMType.HPyFunc_getiterfunc), - ITERNEXTFUNC(27, LLVMType.HPyFunc_iternextfunc), - DESCRGETFUNC(28, LLVMType.HPyFunc_descrgetfunc), - DESCRSETFUNC(29, LLVMType.HPyFunc_descrsetfunc), - INITPROC(30, LLVMType.HPyFunc_initproc), - GETTER(31, LLVMType.HPyFunc_getter), - SETTER(32, LLVMType.HPyFunc_setter), - OBJOBJPROC(33, LLVMType.HPyFunc_objobjproc); - - /** The corresponding C enum value. */ - private final int value; - - /** The C function's type (basically it's signature). */ - private final LLVMType llvmFunctionType; - - HPyFuncSignature(int value, LLVMType llvmFunctionType) { - this.value = value; - this.llvmFunctionType = llvmFunctionType; - } - - public int getValue() { - return value; - } - - public LLVMType getLLVMFunctionType() { - return llvmFunctionType; - } - - @CompilationFinal(dimensions = 1) private static final HPyFuncSignature[] VALUES = values(); - @CompilationFinal(dimensions = 1) private static final HPyFuncSignature[] BY_VALUE = new HPyFuncSignature[40]; - - static { - for (var entry : VALUES) { - assert BY_VALUE[entry.value] == null; - BY_VALUE[entry.value] = entry; - } - } - - static HPyFuncSignature fromValue(int value) { - return value >= 0 && value < BY_VALUE.length ? BY_VALUE[value] : null; - } - - public static int getFlags(HPyFuncSignature sig) { - switch (sig) { - case VARARGS: - return CExtContext.METH_VARARGS; - case KEYWORDS: - return CExtContext.METH_VARARGS | CExtContext.METH_KEYWORDS; - case NOARGS: - return CExtContext.METH_NOARGS; - case O: - return CExtContext.METH_O; - } - return 0; - } - - static boolean isValid(int value) { - return fromValue(value) != null; - } - } - - /** - * An enumeration of all available slot wrappers as used by CPython (see - * {@code typeobject.c: slotdefs}. Each enum value (except of {@link #NULL}, - * {@link #DESTROYFUNC}, {@link #GETBUFFER}, and {@link #RELEASEBUFFER}) corresponds to a - * wrapper function which name starts with {@code wrap_}. For example, value {@link #UNARYFUNC} - * corresponds to wrapper function {@code wrap_unaryfunc}. - */ - public enum HPySlotWrapper { - NULL(LLVMType.HPyFunc_keywords), - UNARYFUNC(LLVMType.HPyFunc_unaryfunc), - BINARYFUNC(LLVMType.HPyFunc_binaryfunc), - BINARYFUNC_L(LLVMType.HPyFunc_binaryfunc), - BINARYFUNC_R(LLVMType.HPyFunc_binaryfunc), - CALL(LLVMType.HPyFunc_keywords), - HASHFUNC(LLVMType.HPyFunc_hashfunc), - TERNARYFUNC(LLVMType.HPyFunc_ternaryfunc), - TERNARYFUNC_R(LLVMType.HPyFunc_ternaryfunc), - INQUIRYPRED(LLVMType.HPyFunc_inquiry), - DEL, - INIT(LLVMType.HPyFunc_initproc), - LENFUNC(LLVMType.HPyFunc_lenfunc), - DELITEM, - SQ_ITEM(LLVMType.HPyFunc_ssizeargfunc), - SQ_SETITEM(LLVMType.HPyFunc_ssizeobjargproc), - SQ_DELITEM(LLVMType.HPyFunc_ssizeobjargproc), - OBJOBJARGPROC(LLVMType.HPyFunc_objobjargproc), - OBJOBJPROC(LLVMType.HPyFunc_objobjproc), - INDEXARGFUNC(LLVMType.HPyFunc_ssizeargfunc), - SETATTR(LLVMType.HPyFunc_setattrfunc), - DELATTR(LLVMType.HPyFunc_setattrfunc), - RICHCMP_LT(LLVMType.HPyFunc_richcmpfunc), - RICHCMP_LE(LLVMType.HPyFunc_richcmpfunc), - RICHCMP_EQ(LLVMType.HPyFunc_richcmpfunc), - RICHCMP_NE(LLVMType.HPyFunc_richcmpfunc), - RICHCMP_GT(LLVMType.HPyFunc_richcmpfunc), - RICHCMP_GE(LLVMType.HPyFunc_richcmpfunc), - DESCR_GET(LLVMType.HPyFunc_descrgetfunc), - DESCR_SET(LLVMType.HPyFunc_descrsetfunc), - DESCR_DELETE(LLVMType.HPyFunc_descrsetfunc), - DESTROYFUNC(LLVMType.HPyFunc_destroyfunc), - TRAVERSE(LLVMType.HPyFunc_traverseproc), - DESTRUCTOR(LLVMType.HPyFunc_destructor), - GETBUFFER(LLVMType.HPyFunc_getbufferproc), - RELEASEBUFFER(LLVMType.HPyFunc_releasebufferproc), - MOD_CREATE(LLVMType.HPyModule_create); - - /** The C function's type (basically it's signature). */ - private final LLVMType llvmFunctionType; - - HPySlotWrapper() { - this.llvmFunctionType = null; - } - - HPySlotWrapper(LLVMType llvmFunctionType) { - this.llvmFunctionType = llvmFunctionType; - } - - public LLVMType getLLVMFunctionType() { - return llvmFunctionType; - } - } - - /* enum values of 'HPyMember_FieldType' */ - public static final int HPY_MEMBER_SHORT = 0; - public static final int HPY_MEMBER_INT = 1; - public static final int HPY_MEMBER_LONG = 2; - public static final int HPY_MEMBER_FLOAT = 3; - public static final int HPY_MEMBER_DOUBLE = 4; - public static final int HPY_MEMBER_STRING = 5; - public static final int HPY_MEMBER_OBJECT = 6; - public static final int HPY_MEMBER_CHAR = 7; - public static final int HPY_MEMBER_BYTE = 8; - public static final int HPY_MEMBER_UBYTE = 9; - public static final int HPY_MEMBER_USHORT = 10; - public static final int HPY_MEMBER_UINT = 11; - public static final int HPY_MEMBER_ULONG = 12; - public static final int HPY_MEMBER_STRING_INPLACE = 13; - public static final int HPY_MEMBER_BOOL = 14; - public static final int HPY_MEMBER_OBJECT_EX = 16; - public static final int HPY_MEMBER_LONGLONG = 17; - public static final int HPY_MEMBER_ULONGLONG = 18; - public static final int HPY_MEMBER_HPYSSIZET = 19; - public static final int HPY_MEMBER_NONE = 20; - - /* enum values of 'HPyType_SpecParam_Kind' */ - public static final int HPyType_SPEC_PARAM_BASE = 1; - public static final int HPyType_SPEC_PARAM_BASES_TUPLE = 2; - public static final int HPyType_SPEC_PARAM_METACLASS = 3; - - /* type flags according to 'hpytype.h' */ - public static final long _Py_TPFLAGS_HEAPTYPE = (1L << 9); - public static final long HPy_TPFLAGS_BASETYPE = (1L << 10); - public static final long HPy_TPFLAGS_HAVE_GC = (1L << 14); - public static final long HPy_TPFLAGS_DEFAULT = _Py_TPFLAGS_HEAPTYPE; - - /* enum values of 'HPyType_BuiltinShape' */ - public static final int HPyType_BUILTIN_SHAPE_LEGACY = -1; - public static final int HPyType_BUILTIN_SHAPE_OBJECT = 0; - public static final int HPyType_BUILTIN_SHAPE_TYPE = 1; - public static final int HPyType_BUILTIN_SHAPE_LONG = 2; - public static final int HPyType_BUILTIN_SHAPE_FLOAT = 3; - public static final int HPyType_BUILTIN_SHAPE_UNICODE = 4; - public static final int HPyType_BUILTIN_SHAPE_TUPLE = 5; - public static final int HPyType_BUILTIN_SHAPE_LIST = 6; - - /** - * Used when the corresponding slot has not been migrated to the CPython compatible TpSlot, or - * when the CPython compatible TpSlot does not have HPy support yet. - */ - public static final TpSlotMeta NO_TP_SLOT = null; - - /* enum values for 'HPySlot_Slot' */ - enum HPySlot { - HPY_BF_GETBUFFER(1, NO_TP_SLOT, HPySlotWrapper.GETBUFFER, HiddenAttr.GETBUFFER), - HPY_BF_RELEASEBUFFER(2, NO_TP_SLOT, HPySlotWrapper.RELEASEBUFFER, HiddenAttr.RELEASEBUFFER), - HPY_MP_ASS_SUBSCRRIPT(3, NO_TP_SLOT, HPySlotWrapper.OBJOBJARGPROC, T___SETITEM__, T___DELITEM__), - HPY_MP_LENGTH(4, TpSlotMeta.MP_LENGTH, HPySlotWrapper.LENFUNC, T___LEN__), - HPY_MP_SUBSCRIPT(5, TpSlotMeta.MP_SUBSCRIPT, HPySlotWrapper.BINARYFUNC, T___GETITEM__), - HPY_NB_ABSOLUTE(6, NO_TP_SLOT, HPySlotWrapper.UNARYFUNC, T___ABS__), - HPY_NB_ADD(7, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___ADD__, HPySlotWrapper.BINARYFUNC_R, T___RADD__), - HPY_NB_AND(8, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___AND__, HPySlotWrapper.BINARYFUNC_R, T___RAND__), - HPY_NB_BOOL(9, NO_TP_SLOT, HPySlotWrapper.INQUIRYPRED, T___BOOL__), - HPY_NB_DIVMOD(10, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___DIVMOD__), - HPY_NB_FLOAT(11, NO_TP_SLOT, HPySlotWrapper.UNARYFUNC, T___FLOAT__), - HPY_NB_FLOOR_DIVIDE(12, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___FLOORDIV__, HPySlotWrapper.BINARYFUNC_R, T___RFLOORDIV__), - HPY_NB_INDEX(13, NO_TP_SLOT, HPySlotWrapper.UNARYFUNC, T___INDEX__), - HPY_NB_INPLACE_ADD(14, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___IADD__), - HPY_NB_INPLACE_AND(15, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___IAND__), - HPY_NB_INPLACE_FLOOR_DIVIDE(16, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___IFLOORDIV__), - HPY_NB_INPLACE_LSHIFT(17, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___ILSHIFT__), - HPY_NB_INPLACE_MULTIPLY(18, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___IMUL__), - HPY_NB_INPLACE_OR(19, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___IOR__), - HPY_NB_INPLACE_POWER(20, NO_TP_SLOT, HPySlotWrapper.TERNARYFUNC, T___IPOW__), - HPY_NB_INPLACE_REMAINDER(21, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___IMOD__), - HPY_NB_INPLACE_RSHIFT(22, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___IRSHIFT__), - HPY_NB_INPLACE_SUBTRACT(23, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___ISUB__), - HPY_NB_INPLACE_TRUE_DIVIDE(24, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___ITRUEDIV__), - HPY_NB_INPLACE_XOR(25, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___IXOR__), - HPY_NB_INT(26, NO_TP_SLOT, HPySlotWrapper.UNARYFUNC, T___INT__), - HPY_NB_INVERT(27, NO_TP_SLOT, HPySlotWrapper.UNARYFUNC, T___INVERT__), - HPY_NB_LSHIFT(28, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___LSHIFT__, HPySlotWrapper.BINARYFUNC_R, T___RLSHIFT__), - HPY_NB_MULTIPLY(29, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___MUL__, HPySlotWrapper.BINARYFUNC_R, T___RMUL__), - HPY_NB_NEGATIVE(30, NO_TP_SLOT, HPySlotWrapper.UNARYFUNC, T___NEG__), - HPY_NB_OR(31, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___OR__, HPySlotWrapper.BINARYFUNC_R, T___ROR__), - HPY_NB_POSITIVE(32, NO_TP_SLOT, HPySlotWrapper.UNARYFUNC, T___POS__), - HPY_NB_POWER(33, NO_TP_SLOT, HPySlotWrapper.TERNARYFUNC, T___POW__), - HPY_NB_REMAINDER(34, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___MOD__, HPySlotWrapper.BINARYFUNC_R, T___RMOD__), - HPY_NB_RSHIFT(35, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___RSHIFT__, HPySlotWrapper.BINARYFUNC_R, T___RRSHIFT__), - HPY_NB_SUBTRACT(36, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___SUB__, HPySlotWrapper.BINARYFUNC_R, T___RSUB__), - HPY_NB_TRUE_DIVIDE(37, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___TRUEDIV__, HPySlotWrapper.BINARYFUNC_R, T___RTRUEDIV__), - HPY_NB_XOR(38, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___XOR__, HPySlotWrapper.BINARYFUNC_R, T___RXOR__), - HPY_SQ_ASS_ITEM(39, NO_TP_SLOT, HPySlotWrapper.SQ_SETITEM, T___SETITEM__, HPySlotWrapper.SQ_DELITEM, T___DELITEM__), - HPY_SQ_CONCAT(40, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___ADD__), - HPY_SQ_CONTAINS(41, NO_TP_SLOT, HPySlotWrapper.OBJOBJPROC, T___CONTAINS__), - HPY_SQ_INPLACE_CONCAT(42, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___IADD__), - HPY_SQ_INPLACE_REPEAT(43, NO_TP_SLOT, HPySlotWrapper.INDEXARGFUNC, T___IMUL__), - HPY_SQ_ITEM(44, TpSlotMeta.SQ_ITEM, HPySlotWrapper.SQ_ITEM, T___GETITEM__), - HPY_SQ_LENGTH(45, TpSlotMeta.SQ_LENGTH, HPySlotWrapper.LENFUNC, T___LEN__), - HPY_SQ_REPEAT(46, TpSlotMeta.SQ_REPEAT, HPySlotWrapper.INDEXARGFUNC, T___MUL__, T___RMUL__), - HPY_TP_CALL(50, NO_TP_SLOT, HPySlotWrapper.CALL, T___CALL__), - HPY_TP_HASH(59, NO_TP_SLOT, HPySlotWrapper.HASHFUNC, T___HASH__), - HPY_TP_INIT(60, NO_TP_SLOT, HPySlotWrapper.INIT, T___INIT__), - HPY_TP_ITER(62, NO_TP_SLOT, HPySlotWrapper.UNARYFUNC, T___ITER__), - HPY_TP_NEW(65, NO_TP_SLOT, HPySlotWrapper.NULL, T___NEW__), - HPY_TP_REPR(66, NO_TP_SLOT, HPySlotWrapper.UNARYFUNC, T___REPR__), - HPY_TP_RICHCOMPARE(67, NO_TP_SLOT, w(RICHCMP_LT, RICHCMP_LE, RICHCMP_EQ, RICHCMP_NE, RICHCMP_GT, RICHCMP_GE), k(T___LT__, T___LE__, T___EQ__, T___NE__, T___GT__, T___GE__)), - HPY_TP_STR(70, NO_TP_SLOT, HPySlotWrapper.UNARYFUNC, T___STR__), - HPY_TP_TRAVERSE(71, NO_TP_SLOT, HPySlotWrapper.TRAVERSE), - HPY_NB_MATRIX_MULTIPLY(75, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___MATMUL__, HPySlotWrapper.BINARYFUNC_R, T___RMATMUL__), - HPY_NB_INPLACE_MATRIX_MULTIPLY(76, NO_TP_SLOT, HPySlotWrapper.BINARYFUNC_L, T___IMATMUL__), - HPY_TP_FINALIZE(80, NO_TP_SLOT, HPySlotWrapper.DESTRUCTOR), - HPY_TP_DESTROY(1000, NO_TP_SLOT, HPySlotWrapper.DESTROYFUNC), - HPY_MOD_CREATE(2000, NO_TP_SLOT, HPySlotWrapper.MOD_CREATE), - HPY_MOD_EXEC(2001, NO_TP_SLOT, HPySlotWrapper.INQUIRYPRED); - - /** The corresponding C enum value. */ - private final int value; - - /** Corresponding CPython compatible slot */ - private final TpSlotMeta tpSlot; - - /** - * The corresponding attribute key (mostly a {@link TruffleString} which is the name of a - * magic method, or a {@link HiddenAttr} if it's not exposed to the user, or {@code null} if - * unsupported). - */ - @CompilationFinal(dimensions = 1) private final Object[] attributeKeys; - - /** The signatures of the slot functions. */ - @CompilationFinal(dimensions = 1) private final HPySlotWrapper[] signatures; - - /** - * Common case: one slot causes the creation of one attribute. - */ - HPySlot(int value, TpSlotMeta tpSlot, HPySlotWrapper signature, HiddenAttr attributeKey) { - this.value = value; - this.tpSlot = tpSlot; - this.attributeKeys = new Object[]{attributeKey}; - this.signatures = new HPySlotWrapper[]{signature}; - } - - /** - * Special case: one slot causes the creation of multiple attributes using the same slot - * wrapper. - */ - HPySlot(int value, TpSlotMeta tpSlot, HPySlotWrapper signature, TruffleString... attributeKeys) { - this.value = value; - this.tpSlot = tpSlot; - this.attributeKeys = attributeKeys; - if (attributeKeys.length > 0) { - this.signatures = new HPySlotWrapper[attributeKeys.length]; - Arrays.fill(this.signatures, signature); - } else { - this.signatures = new HPySlotWrapper[]{signature}; - } - } - - /** - * Special case: one slot causes the creation of two attributes using different slot - * wrappers. - */ - HPySlot(int value, TpSlotMeta tpSlot, HPySlotWrapper sig0, TruffleString key0, HPySlotWrapper sig1, TruffleString key1) { - this.value = value; - this.tpSlot = tpSlot; - this.attributeKeys = new Object[]{key0, key1}; - this.signatures = new HPySlotWrapper[]{sig0, sig1}; - } - - /** - * Generic case: one slot causes the creation of multiple attributes with each different - * slot wrappers. - */ - HPySlot(int value, TpSlotMeta tpSlot, HPySlotWrapper[] sigs, TruffleString... keys) { - this.value = value; - this.tpSlot = tpSlot; - this.attributeKeys = keys; - this.signatures = sigs; - } - - int getValue() { - return value; - } - - Object[] getAttributeKeys() { - return attributeKeys; - } - - HPySlotWrapper[] getSignatures() { - return signatures; - } - - @CompilationFinal(dimensions = 1) private static final HPySlot[] BY_VALUE = new HPySlot[100]; - - static { - for (var entry : values()) { - if (entry.value >= 0 && entry.value < BY_VALUE.length) { - assert BY_VALUE[entry.value] == null; - BY_VALUE[entry.value] = entry; - } - } - } - - static HPySlot fromValue(int value) { - if (value >= 0 && value < BY_VALUE.length) { - return BY_VALUE[value]; - } - if (HPY_TP_DESTROY.value == value) { - return HPY_TP_DESTROY; - } else if (HPY_MOD_CREATE.value == value) { - return HPY_MOD_CREATE; - } else if (HPY_MOD_EXEC.value == value) { - return HPY_MOD_EXEC; - } - return null; - } - - private static HPySlotWrapper[] w(HPySlotWrapper... wrappers) { - return wrappers; - } - - private static TruffleString[] k(TruffleString... keys) { - return keys; - } - - public TpSlotMeta getTpSlot() { - return tpSlot; - } - } - - public static boolean isValidBuiltinShape(int i) { - return HPyType_BUILTIN_SHAPE_LEGACY <= i && i <= HPyType_BUILTIN_SHAPE_LIST; - } - - public static int getBuiltinShapeFromHiddenAttribute(Object object) { - if (object instanceof PythonClass pythonClass) { - return pythonClass.getBuiltinShape(); - } else if (object instanceof PythonAbstractNativeObject) { - assert IsTypeNode.executeUncached(object); - return HPyType_BUILTIN_SHAPE_LEGACY; - } - return -2; // error - } - - static PythonBuiltinClassType getBuiltinClassType(int builtinShape) { - return switch (builtinShape) { - case HPyType_BUILTIN_SHAPE_LEGACY, HPyType_BUILTIN_SHAPE_OBJECT -> PythonBuiltinClassType.PythonObject; - case HPyType_BUILTIN_SHAPE_TYPE -> PythonBuiltinClassType.PythonClass; - case HPyType_BUILTIN_SHAPE_LONG -> PythonBuiltinClassType.PInt; - case HPyType_BUILTIN_SHAPE_FLOAT -> PythonBuiltinClassType.PFloat; - case HPyType_BUILTIN_SHAPE_UNICODE -> PythonBuiltinClassType.PString; - case HPyType_BUILTIN_SHAPE_TUPLE -> PythonBuiltinClassType.PTuple; - case HPyType_BUILTIN_SHAPE_LIST -> PythonBuiltinClassType.PList; - default -> throw CompilerDirectives.shouldNotReachHere(GraalHPyNew.INVALID_BUILT_IN_SHAPE); - }; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyHandle.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyHandle.java deleted file mode 100644 index 132e94c20a..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyHandle.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -// skip GIL -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import static com.oracle.graal.python.nodes.truffle.TruffleStringMigrationHelpers.assertNoJavaString; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; -import static com.oracle.graal.python.util.PythonUtils.tsLiteral; - -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.PythonAbstractObject; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.GetHPyHandleForSingleton; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFactory.GetHPyHandleForSingletonNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMContext; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.interop.UnknownIdentifierException; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.library.ExportLibrary; -import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.ConditionProfile; -import com.oracle.truffle.api.strings.TruffleString; -import com.oracle.truffle.llvm.spi.NativeTypeLibrary; - -@ExportLibrary(InteropLibrary.class) -@ExportLibrary(value = NativeTypeLibrary.class, useForAOT = false) -public final class GraalHPyHandle implements TruffleObject { - private static final int UNINITIALIZED = Integer.MIN_VALUE; - - public static final Object NULL_HANDLE_DELEGATE = PNone.NO_VALUE; - public static final GraalHPyHandle NULL_HANDLE = new GraalHPyHandle(); - public static final String J_I = "_i"; - public static final TruffleString T_I = tsLiteral(J_I); - - private final Object delegate; - /** - * The ID of the handle if it was allocated in the handle table. - *

    - * The value also encodes the state:
    - * (1) If the value is {@link #UNINITIALIZED}, then the handle was never allocated in the handle - * table.
    - * (2) If the value is zero or positive then this is the index for the handle table. If the
    - * (3) If the value is negative but not {@link #UNINITIALIZED} then the handle was already - * closed (only used in HPy debug mode)
    - *

    - */ - private int id; - - private GraalHPyHandle() { - this(NULL_HANDLE_DELEGATE, 0); - } - - private GraalHPyHandle(Object delegate) { - this(delegate, UNINITIALIZED); - } - - private GraalHPyHandle(Object delegate, int id) { - assert delegate != null : "HPy handles to Java null are not allowed"; - assert delegate != NULL_HANDLE_DELEGATE || id == 0 : "must not not create more than on HPy_NULL"; - this.delegate = assertNoJavaString(delegate); - this.id = id; - } - - public static GraalHPyHandle createSingleton(Object delegate, int handle) { - assert handle <= GraalHPyBoxing.SINGLETON_HANDLE_MAX; - return new GraalHPyHandle(delegate, handle); - } - - public static GraalHPyHandle create(Object delegate) { - return new GraalHPyHandle(delegate); - } - - public static GraalHPyHandle createField(Object delegate, int idx) { - return new GraalHPyHandle(delegate, idx); - } - - public static GraalHPyHandle createGlobal(Object delegate, int idx) { - return new GraalHPyHandle(delegate, idx); - } - - /** - * This is basically like {@code toNative} but also returns the ID. - */ - public int getIdUncached(GraalHPyContext context) { - return getId(context, ConditionProfile.getUncached(), GetHPyHandleForSingletonNodeGen.getUncached()); - } - - public int getId(GraalHPyContext context, ConditionProfile hasIdProfile, GetHPyHandleForSingleton getSingletonNode) { - int result = id; - if (!isPointer(hasIdProfile)) { - assert !GraalHPyBoxing.isBoxablePrimitive(delegate) : "allocating handle for value that could be boxed"; - result = getSingletonNode.execute(this.delegate); - if (result == -1) { - // profiled by the node - result = context.getHPyHandleForNonSingleton(this.delegate); - } - id = result; - } - assert isValidId(this.delegate, result); - return result; - } - - public boolean isValidId(Object obj, int newId) { - if (delegate == PNone.NO_VALUE) { - // special case of HPy_NULL internally represented as NO_VALUE - return newId == 0; - } - int singletonId = GraalHPyContext.getHPyHandleForSingleton(obj); - return singletonId == -1 || singletonId == newId; - } - - @ExportMessage - boolean isPointer( - @Exclusive @Cached(inline = false) ConditionProfile isNativeProfile) { - return isNativeProfile.profile(id >= 0 || delegate instanceof Integer || delegate instanceof Double); - } - - @ExportMessage - long asPointer() throws UnsupportedMessageException { - // note: we don't use a profile here since 'asPointer' is usually used right after - // 'isPointer' - if (!isPointer(ConditionProfile.getUncached())) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw UnsupportedMessageException.create(); - } - if (id != UNINITIALIZED) { - return GraalHPyBoxing.boxHandle(id); - } else if (delegate instanceof Integer) { - return GraalHPyBoxing.boxInt((Integer) delegate); - } else if (delegate instanceof Double) { - return GraalHPyBoxing.boxDouble((Double) delegate); - } - throw CompilerDirectives.shouldNotReachHere(); - } - - /** - * Allocates the handle in the global handle table of the provided HPy context. If this is used - * in compiled code, this {@code GraalHPyHandle} object will definitively be allocated. - */ - @ExportMessage - void toNative(@Exclusive @Cached(inline = false) ConditionProfile isNativeProfile, - @Cached GetHPyHandleForSingleton getSingletonNode, - @CachedLibrary("this") InteropLibrary lib) { - getId(PythonContext.get(lib).getHPyContext(), isNativeProfile, getSingletonNode); - } - - @ExportMessage - @SuppressWarnings("static-method") - boolean hasNativeType(@Bind("$node") Node node) { - return PythonContext.get(node).getHPyContext().getBackend() instanceof GraalHPyLLVMContext; - } - - @ExportMessage - Object getNativeType(@Bind("$node") Node node) { - if (PythonContext.get(node).getHPyContext().getBackend() instanceof GraalHPyLLVMContext backend) { - return backend.getHPyNativeType(); - } - throw CompilerDirectives.shouldNotReachHere(); - } - - public Object getDelegate() { - return delegate; - } - - @ExportMessage - @SuppressWarnings("static-method") - boolean hasMembers() { - return true; - } - - @ExportMessage - @SuppressWarnings("static-method") - Object getMembers(@SuppressWarnings("unused") boolean includeInternal) { - return new PythonAbstractObject.Keys(new TruffleString[]{T_I}); - } - - @ExportMessage - @SuppressWarnings("static-method") - boolean isMemberReadable(String key, - @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode, - @Shared("eq") @Cached TruffleString.EqualNode eqNode) { - TruffleString tmember = fromJavaStringNode.execute(key, TS_ENCODING); - return eqNode.execute(T_I, tmember, TS_ENCODING); - } - - @ExportMessage - Object readMember(String key, - @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode, - @Shared("eq") @Cached TruffleString.EqualNode eqNode) throws UnknownIdentifierException { - TruffleString tmember = fromJavaStringNode.execute(key, TS_ENCODING); - if (eqNode.execute(T_I, tmember, TS_ENCODING)) { - return this; - } - throw UnknownIdentifierException.create(key); - } - - @ExportMessage - boolean isNull() { - return id == 0; - } - - static boolean isAllocated(int id) { - return id != UNINITIALIZED && id != 0; - } - - boolean isAllocated() { - return GraalHPyHandle.isAllocated(id); - } - - boolean isValid() { - return id > 0; - } - - void closeAndInvalidate(GraalHPyContext hpyContext) { - assert id != UNINITIALIZED; - if (hpyContext.releaseHPyHandleForObject(id)) { - id = -id; - } - } - - int getGlobalId() { - assert id > 0 : "any HPyGlobal handle already has an id"; - return id; - } - - int getFieldId() { - assert id >= 0 : "any HPyField handle already has an id"; - return id; - } - - public GraalHPyHandle copy() { - return new GraalHPyHandle(delegate); - } - - static boolean wasAllocated(int id) { - return id != UNINITIALIZED; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyLegacyDef.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyLegacyDef.java deleted file mode 100644 index c491d7d2ff..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyLegacyDef.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ABS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ADD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ALLOC__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AND__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___BOOL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___CALL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___CLEAR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___CONTAINS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___DEALLOC__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___DEL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___DIVMOD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___FLOAT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___FLOORDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___FREE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETATTR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GET__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IADD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IAND__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IFLOORDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ILSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IMATMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IMOD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INDEX__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INVERT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IOR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IPOW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IRSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ISUB__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ITRUEDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IXOR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LEN__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MATMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MOD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEG__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEXT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___OR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___POS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___POW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___REPR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SETATTR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SETITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SET__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___STR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SUB__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___TRUEDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___TRUFFLE_RICHCOMPARE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___XOR__; - -import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper; -import com.oracle.graal.python.builtins.objects.type.TpSlots.TpSlotMeta; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.strings.TruffleString; - -/** - * Definitions for legacy slots. - */ -public abstract class GraalHPyLegacyDef { - public static final int MEMBER_FLAG_READONLY = 1; - - /** - * Used when the corresponding slot has not been migrated to the CPython compatible TpSlot, or - * there is no equivalent CPython slot (for those we may still reserve space in TpSlots in the - * future). - */ - public static final TpSlotMeta NO_TP_SLOT = null; - - /** - * Values for field {@code slot} of structure {@code PyType_Slot}. - */ - enum HPyLegacySlot { - // generic type slots - Py_tp_alloc(47, NO_TP_SLOT, T___ALLOC__, PExternalFunctionWrapper.ALLOC), - Py_tp_base(48, NO_TP_SLOT), - Py_tp_bases(49, NO_TP_SLOT), - Py_tp_call(50, NO_TP_SLOT, T___CALL__, PExternalFunctionWrapper.KEYWORDS), - Py_tp_clear(51, NO_TP_SLOT, T___CLEAR__, PExternalFunctionWrapper.INQUIRY), - Py_tp_dealloc(52, NO_TP_SLOT, T___DEALLOC__), - Py_tp_del(53, NO_TP_SLOT, T___DEL__), - Py_tp_descr_get(54, NO_TP_SLOT, T___GET__), - Py_tp_descr_set(55, NO_TP_SLOT, T___SET__), - Py_tp_doc(56, NO_TP_SLOT), - Py_tp_getattr(57, NO_TP_SLOT, T___GETATTR__, PExternalFunctionWrapper.GETATTR), - Py_tp_getattro(58, NO_TP_SLOT, T___GETATTR__), - Py_tp_hash(59, NO_TP_SLOT, T___HASH__, PExternalFunctionWrapper.HASHFUNC), - Py_tp_init(60, NO_TP_SLOT, T___INIT__, PExternalFunctionWrapper.INITPROC), - Py_tp_is_gc(61, NO_TP_SLOT), - Py_tp_iter(62, NO_TP_SLOT, T___ITER__), - Py_tp_iternext(63, NO_TP_SLOT, T___NEXT__, PExternalFunctionWrapper.ITERNEXT), - Py_tp_methods(64, NO_TP_SLOT), - Py_tp_new(65, NO_TP_SLOT, T___NEW__, PExternalFunctionWrapper.KEYWORDS), - Py_tp_repr(66, NO_TP_SLOT, T___REPR__, PExternalFunctionWrapper.TP_REPR), - Py_tp_richcompare(67, NO_TP_SLOT, T___TRUFFLE_RICHCOMPARE__, PExternalFunctionWrapper.RICHCMP), - Py_tp_setattr(68, NO_TP_SLOT, T___SETATTR__, PExternalFunctionWrapper.SETATTR), - Py_tp_setattro(69, NO_TP_SLOT, T___SETATTR__), - Py_tp_str(70, NO_TP_SLOT, T___STR__, PExternalFunctionWrapper.TP_STR), - Py_tp_traverse(71, NO_TP_SLOT), - Py_tp_members(72, NO_TP_SLOT), - Py_tp_getset(73, NO_TP_SLOT), - Py_tp_free(74, NO_TP_SLOT, T___FREE__), - - // PyMappingMethods, NO_TP_SLOT - Py_mp_ass_subscript(3, NO_TP_SLOT, T___SETITEM__, PExternalFunctionWrapper.OBJOBJARGPROC), - Py_mp_length(4, NO_TP_SLOT, T___LEN__, PExternalFunctionWrapper.LENFUNC), - Py_mp_subscript(5, NO_TP_SLOT, T___GETITEM__), - - // PyNumberMethods, NO_TP_SLOT - Py_nb_absolute(6, NO_TP_SLOT, T___ABS__), - Py_nb_add(7, NO_TP_SLOT, T___ADD__), - Py_nb_and(8, NO_TP_SLOT, T___AND__), - Py_nb_bool(9, NO_TP_SLOT, T___BOOL__, PExternalFunctionWrapper.INQUIRY), - Py_nb_divmod(10, NO_TP_SLOT, T___DIVMOD__), - Py_nb_float(11, NO_TP_SLOT, T___FLOAT__), - Py_nb_floor_divide(12, NO_TP_SLOT, T___FLOORDIV__), - Py_nb_index(13, NO_TP_SLOT, T___INDEX__), - Py_nb_inplace_add(14, NO_TP_SLOT, T___IADD__), - Py_nb_inplace_and(15, NO_TP_SLOT, T___IAND__), - Py_nb_inplace_floor_divide(16, NO_TP_SLOT, T___IFLOORDIV__), - Py_nb_inplace_lshift(17, NO_TP_SLOT, T___ILSHIFT__), - Py_nb_inplace_multiply(18, NO_TP_SLOT, T___IMUL__), - Py_nb_inplace_or(19, NO_TP_SLOT, T___IOR__), - Py_nb_inplace_power(20, NO_TP_SLOT, T___IPOW__), - Py_nb_inplace_remainder(21, NO_TP_SLOT, T___IMOD__), - Py_nb_inplace_rshift(22, NO_TP_SLOT, T___IRSHIFT__), - Py_nb_inplace_subtract(23, NO_TP_SLOT, T___ISUB__), - Py_nb_inplace_true_divide(24, NO_TP_SLOT, T___ITRUEDIV__), - Py_nb_inplace_xor(25, NO_TP_SLOT, T___IXOR__), - Py_nb_int(26, NO_TP_SLOT, T___INT__), - Py_nb_invert(27, NO_TP_SLOT, T___INVERT__), - Py_nb_lshift(28, NO_TP_SLOT, T___LSHIFT__), - Py_nb_multiply(29, NO_TP_SLOT, T___MUL__), - Py_nb_negative(30, NO_TP_SLOT, T___NEG__), - Py_nb_or(31, NO_TP_SLOT, T___OR__), - Py_nb_positive(32, NO_TP_SLOT, T___POS__), - Py_nb_power(33, NO_TP_SLOT, T___POW__, PExternalFunctionWrapper.TERNARYFUNC), - Py_nb_remainder(34, NO_TP_SLOT, T___MOD__), - Py_nb_rshift(35, NO_TP_SLOT, T___RSHIFT__), - Py_nb_subtract(36, NO_TP_SLOT, T___SUB__), - Py_nb_true_divide(37, NO_TP_SLOT, T___TRUEDIV__), - Py_nb_xor(38, NO_TP_SLOT, T___XOR__), - Py_nb_matrix_multiply(75, NO_TP_SLOT, T___MATMUL__), - Py_nb_inplace_matrix_multiply(76, NO_TP_SLOT, T___IMATMUL__), - - // PySequenceMethods, NO_TP_SLOT - Py_sq_ass_item(39, NO_TP_SLOT, T___SETITEM__, PExternalFunctionWrapper.SETITEM), - Py_sq_concat(40, NO_TP_SLOT, T___ADD__), - Py_sq_contains(41, NO_TP_SLOT, T___CONTAINS__, PExternalFunctionWrapper.OBJOBJPROC), - Py_sq_inplace_concat(42, NO_TP_SLOT, T___IADD__), - Py_sq_inplace_repeat(43, NO_TP_SLOT, T___IMUL__, PExternalFunctionWrapper.SSIZE_ARG), - Py_sq_item(44, TpSlotMeta.SQ_ITEM, T___GETITEM__, PExternalFunctionWrapper.GETITEM), - Py_sq_length(45, NO_TP_SLOT, T___LEN__, PExternalFunctionWrapper.LENFUNC), - Py_sq_repeat(46, NO_TP_SLOT, T___MUL__, PExternalFunctionWrapper.SSIZE_ARG), - - // PyAsyncMethods, NO_TP_SLOT - Py_am_await(77, NO_TP_SLOT), - Py_am_aiter(78, NO_TP_SLOT), - Py_am_anext(79, NO_TP_SLOT); - - /** The corresponding C enum value. */ - private final int value; - - /** Corresponding CPython compatible slot. */ - private final TpSlotMeta tpSlot; - - /** - * The corresponding attribute key (mostly a {@link String} which is the name of a magic - * method, or a {@link com.oracle.graal.python.nodes.HiddenAttr} if it's not exposed to the - * user, or {@code null} if unsupported). - */ - private final TruffleString attributeKey; - - /** The signature of the slot function. */ - private final PExternalFunctionWrapper signature; - - HPyLegacySlot(int value, TpSlotMeta tpSlot) { - this(value, tpSlot, null); - } - - HPyLegacySlot(int value, TpSlotMeta tpSlot, TruffleString attributeKey) { - this(value, tpSlot, attributeKey, PExternalFunctionWrapper.DIRECT); - } - - HPyLegacySlot(int value, TpSlotMeta tpSlot, TruffleString attributeKey, PExternalFunctionWrapper signature) { - this.value = value; - this.tpSlot = tpSlot; - this.attributeKey = attributeKey; - this.signature = signature; - } - - int getValue() { - return value; - } - - TruffleString getAttributeKey() { - return attributeKey; - } - - PExternalFunctionWrapper getSignature() { - return signature; - } - - @CompilationFinal(dimensions = 1) private static final HPyLegacySlot[] VALUES = values(); - @CompilationFinal(dimensions = 1) private static final HPyLegacySlot[] BY_VALUE = new HPyLegacySlot[100]; - - static { - for (var entry : VALUES) { - assert BY_VALUE[entry.value] == null; - BY_VALUE[entry.value] = entry; - } - } - - static HPyLegacySlot fromValue(int value) { - return value >= 0 && value < BY_VALUE.length ? BY_VALUE[value] : null; - } - - public TpSlotMeta getTpSlot() { - return tpSlot; - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyMemberAccessNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyMemberAccessNodes.java deleted file mode 100644 index c14fca967e..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyMemberAccessNodes.java +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_BOOL; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_BYTE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_CHAR; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_DOUBLE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_FLOAT; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_HPYSSIZET; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_INT; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_LONG; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_LONGLONG; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_NONE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_OBJECT; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_OBJECT_EX; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_SHORT; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_STRING; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_STRING_INPLACE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_UBYTE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_UINT; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_ULONG; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_ULONGLONG; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPY_MEMBER_USHORT; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Bool; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.CDouble; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.CFloat; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Int; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Int16_t; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Int64_t; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Int8_t; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Uint16_t; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Uint8_t; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.UnsignedInt; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.UnsignedLong; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.Builtin; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.cext.common.CExtAsPythonObjectNode; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.AsNativeCharNode; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.AsNativePrimitiveNode; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodesFactory.AsNativeCharNodeGen; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodesFactory.AsNativePrimitiveNodeGen; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodesFactory.NativePrimitiveAsPythonBooleanNodeGen; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodesFactory.NativePrimitiveAsPythonCharNodeGen; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodesFactory.NativeUnsignedPrimitiveAsPythonObjectNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyMemberAccessNodesFactory.HPyBadMemberDescrNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyMemberAccessNodesFactory.HPyReadMemberNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyMemberAccessNodesFactory.HPyReadOnlyMemberNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyMemberAccessNodesFactory.HPyWriteMemberNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyMemberAccessNodesFactory.PyFloatAsDoubleCachedNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyFromCharPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyGetNativeSpacePointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyGetNativeSpacePointerNodeGen; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.getsetdescriptor.DescriptorDeleteMarker; -import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.lib.PyFloatAsDoubleNode; -import com.oracle.graal.python.lib.PyLongAsLongNode; -import com.oracle.graal.python.lib.PyLongAsLongNodeGen; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectExactProfile; -import com.oracle.graal.python.nodes.object.IsNode; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.util.PythonUtils.PrototypeNodeFactory; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.strings.TruffleString; - -public class GraalHPyMemberAccessNodes { - - static HPyContextSignatureType getCType(int type) { - switch (type) { - case HPY_MEMBER_SHORT: - return HPyContextSignatureType.Int16_t; - case HPY_MEMBER_INT: - return HPyContextSignatureType.Int; - case HPY_MEMBER_LONG: - return HPyContextSignatureType.Long; - case HPY_MEMBER_FLOAT: - return HPyContextSignatureType.CFloat; - case HPY_MEMBER_DOUBLE: - return HPyContextSignatureType.CDouble; - case HPY_MEMBER_STRING: - return HPyContextSignatureType.CharPtr; - case HPY_MEMBER_OBJECT: - case HPY_MEMBER_OBJECT_EX: - return HPyContextSignatureType.HPyField; - case HPY_MEMBER_CHAR: - case HPY_MEMBER_BYTE: - return HPyContextSignatureType.Int8_t; - case HPY_MEMBER_BOOL: - return HPyContextSignatureType.Bool; - case HPY_MEMBER_UBYTE: - return HPyContextSignatureType.Uint8_t; - case HPY_MEMBER_USHORT: - return HPyContextSignatureType.Uint16_t; - case HPY_MEMBER_UINT: - return HPyContextSignatureType.UnsignedInt; - case HPY_MEMBER_ULONG: - return HPyContextSignatureType.UnsignedLong; - case HPY_MEMBER_STRING_INPLACE, HPY_MEMBER_NONE: - return null; - case HPY_MEMBER_LONGLONG: - return HPyContextSignatureType.Uint64_t; - case HPY_MEMBER_ULONGLONG: - return HPyContextSignatureType.Int64_t; - case HPY_MEMBER_HPYSSIZET: - return HPyContextSignatureType.HPy_ssize_t; - } - throw CompilerDirectives.shouldNotReachHere("invalid member type"); - } - - static CExtAsPythonObjectNode getReadConverterNode(int type) { - return switch (type) { - // no conversion needed - case HPY_MEMBER_SHORT, HPY_MEMBER_INT, HPY_MEMBER_LONG, HPY_MEMBER_FLOAT, HPY_MEMBER_DOUBLE, HPY_MEMBER_BYTE, HPY_MEMBER_UBYTE, HPY_MEMBER_USHORT, HPY_MEMBER_STRING, - HPY_MEMBER_STRING_INPLACE, HPY_MEMBER_HPYSSIZET, HPY_MEMBER_NONE, HPY_MEMBER_OBJECT, HPY_MEMBER_OBJECT_EX -> - null; - case HPY_MEMBER_BOOL -> NativePrimitiveAsPythonBooleanNodeGen.create(); - case HPY_MEMBER_CHAR -> NativePrimitiveAsPythonCharNodeGen.create(); - case HPY_MEMBER_UINT, HPY_MEMBER_ULONG, HPY_MEMBER_LONGLONG, HPY_MEMBER_ULONGLONG -> NativeUnsignedPrimitiveAsPythonObjectNodeGen.create(); - default -> throw CompilerDirectives.shouldNotReachHere("invalid member type"); - }; - } - - /** - * Special case: members with type {@code STRING} and {@code STRING_INPLACE} are always - * read-only. - */ - static boolean isReadOnlyType(int type) { - return type == HPY_MEMBER_STRING || type == HPY_MEMBER_STRING_INPLACE; - } - - @Builtin(name = "hpy_member_read", minNumOfPositionalArgs = 1, parameterNames = "$self") - protected abstract static class HPyReadMemberNode extends PythonUnaryBuiltinNode { - private static final Builtin builtin = HPyReadMemberNode.class.getAnnotation(Builtin.class); - - @Child private GraalHPyCAccess.ReadGenericNode readGenericNode; - @Child private GraalHPyCAccess.ReadHPyFieldNode readHPyFieldNode; - @Child private GraalHPyCAccess.GetElementPtrNode getElementPtrNode; - @Child private GraalHPyCAccess.IsNullNode isNullNode; - @Child private HPyFromCharPointerNode fromCharPointerNode; - @Child private CExtAsPythonObjectNode asPythonObjectNode; - @Child private PForeignToPTypeNode fromForeign; - @Child private HPyGetNativeSpacePointerNode readNativeSpaceNode; - - /** The specified member type. */ - private final int type; - - /** The name of the native getter function. */ - private final HPyContextSignatureType fieldType; - - /** The offset where to read from (will be passed to the native getter). */ - private final int offset; - - protected HPyReadMemberNode(int offset, int type, CExtAsPythonObjectNode asPythonObjectNode) { - this.fieldType = getCType(type); - this.offset = offset; - this.type = type; - this.asPythonObjectNode = asPythonObjectNode; - if (asPythonObjectNode == null) { - fromForeign = PForeignToPTypeNode.create(); - } - } - - @Specialization - Object doGeneric(@SuppressWarnings("unused") VirtualFrame frame, Object self, - @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { - GraalHPyContext hPyContext = getContext().getHPyContext(); - - Object nativeSpacePtr = ensureReadNativeSpaceNode().executeCached(self); - if (nativeSpacePtr == PNone.NO_VALUE) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.SystemError, ErrorMessages.ATTEMPTING_READ_FROM_OFFSET_D, offset, self); - } - Object nativeResult; - switch (type) { - case HPY_MEMBER_OBJECT, HPY_MEMBER_OBJECT_EX: { - if (self instanceof PythonObject pythonObject) { - Object fieldValue = ensureReadHPyFieldNode(hPyContext).read(hPyContext, pythonObject, nativeSpacePtr, offset); - if (fieldValue == GraalHPyHandle.NULL_HANDLE_DELEGATE) { - if (type == HPY_MEMBER_OBJECT) { - return PNone.NONE; - } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.AttributeError); - } - } - return fieldValue; - } else { - throw CompilerDirectives.shouldNotReachHere("Cannot have HPyField on non-Python object"); - } - } - case HPY_MEMBER_NONE: - return PNone.NONE; - case HPY_MEMBER_STRING: - nativeResult = ensureReadGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, fieldType); - if (ensureIsNullNode(hPyContext).execute(hPyContext, nativeResult)) { - return PNone.NONE; - } - return ensureFromCharPointerNode(hPyContext).execute(hPyContext, nativeResult, false); - case HPY_MEMBER_STRING_INPLACE: - Object elementPtr = ensureGetElementPtrNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset); - return ensureFromCharPointerNode(hPyContext).execute(hPyContext, elementPtr, false); - default: - // default case: reading a primitive or a pointer - assert fieldType != null; - nativeResult = ensureReadGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, fieldType); - if (asPythonObjectNode != null) { - return asPythonObjectNode.execute(nativeResult); - } - /* - * We still need to use 'PForeignToPTypeNode' to ensure that we do not introduce - * unknown values into our value space. - */ - return fromForeign.executeConvert(nativeResult); - } - } - - private GraalHPyCAccess.ReadGenericNode ensureReadGenericNode(GraalHPyContext ctx) { - if (readGenericNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readGenericNode = insert(GraalHPyCAccess.ReadGenericNode.create(ctx)); - } - return readGenericNode; - } - - private GraalHPyCAccess.IsNullNode ensureIsNullNode(GraalHPyContext ctx) { - if (isNullNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - isNullNode = insert(GraalHPyCAccess.IsNullNode.create(ctx)); - } - return isNullNode; - } - - private GraalHPyCAccess.ReadHPyFieldNode ensureReadHPyFieldNode(GraalHPyContext ctx) { - if (readHPyFieldNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readHPyFieldNode = insert(GraalHPyCAccess.ReadHPyFieldNode.create(ctx)); - } - return readHPyFieldNode; - } - - private GraalHPyCAccess.GetElementPtrNode ensureGetElementPtrNode(GraalHPyContext ctx) { - if (getElementPtrNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - getElementPtrNode = insert(GraalHPyCAccess.GetElementPtrNode.create(ctx)); - } - return getElementPtrNode; - } - - private HPyFromCharPointerNode ensureFromCharPointerNode(GraalHPyContext ctx) { - if (fromCharPointerNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - fromCharPointerNode = insert(HPyFromCharPointerNode.create(ctx)); - } - return fromCharPointerNode; - } - - private HPyGetNativeSpacePointerNode ensureReadNativeSpaceNode() { - if (readNativeSpaceNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readNativeSpaceNode = insert(HPyGetNativeSpacePointerNodeGen.create()); - } - return readNativeSpaceNode; - } - - @TruffleBoundary - public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, TruffleString propertyName, int type, int offset) { - CExtAsPythonObjectNode asPythonObjectNode = getReadConverterNode(type); - RootCallTarget callTarget = language.createCachedPropAccessCallTarget( - l -> new BuiltinFunctionRootNode(l, builtin, new PrototypeNodeFactory<>(HPyReadMemberNodeGen.create(offset, type, asPythonObjectNode)), true), - HPyReadMemberNode.class, builtin.name(), type, offset); - int flags = PBuiltinFunction.getFlags(builtin, callTarget); - return PythonObjectFactory.getUncached().createBuiltinFunction(propertyName, null, 0, flags, callTarget); - } - } - - @Builtin(name = "hpy_member_write_read_only", minNumOfPositionalArgs = 1, parameterNames = {"$self", "value"}) - protected abstract static class HPyReadOnlyMemberNode extends PythonBinaryBuiltinNode { - private static final Builtin builtin = HPyReadOnlyMemberNode.class.getAnnotation(Builtin.class); - private final TruffleString propertyName; - - protected HPyReadOnlyMemberNode(TruffleString propertyName) { - this.propertyName = propertyName; - } - - @Specialization - @SuppressWarnings("unused") - Object doGeneric(Object self, Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATTRIBUTE_S_OF_P_OBJECTS_IS_NOT_WRITABLE, propertyName, self); - } - - @TruffleBoundary - public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, TruffleString propertyName) { - RootCallTarget builtinCt = language.createCachedCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, new PrototypeNodeFactory<>(HPyReadOnlyMemberNodeGen.create(propertyName)), true), - HPyReadOnlyMemberNode.class, builtin.name()); - int flags = PBuiltinFunction.getFlags(builtin, builtinCt); - return PythonObjectFactory.getUncached().createBuiltinFunction(propertyName, null, 0, flags, builtinCt); - } - } - - @Builtin(name = "hpy_bad_member_descr", minNumOfPositionalArgs = 2, parameterNames = {"$self", "value"}) - protected abstract static class HPyBadMemberDescrNode extends PythonBinaryBuiltinNode { - private static final Builtin builtin = HPyBadMemberDescrNode.class.getAnnotation(Builtin.class); - - @Specialization - static Object doGeneric(Object self, @SuppressWarnings("unused") Object value, - @Cached PRaiseNode raiseNode) { - if (value == DescriptorDeleteMarker.INSTANCE) { - // This node is actually only used for T_NONE, so this error message is right. - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.CAN_T_DELETE_NUMERIC_CHAR_ATTRIBUTE); - } - throw raiseNode.raise(PythonBuiltinClassType.SystemError, ErrorMessages.BAD_MEMBER_DESCR_TYPE_FOR_P, self); - } - - @TruffleBoundary - public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, TruffleString propertyName) { - RootCallTarget builtinCt = language.createCachedCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, new PrototypeNodeFactory<>(HPyBadMemberDescrNodeGen.create()), true), - HPyBadMemberDescrNode.class, builtin.name()); - int flags = PBuiltinFunction.getFlags(builtin, builtinCt); - return PythonObjectFactory.getUncached().createBuiltinFunction(propertyName, null, 0, flags, builtinCt); - } - } - - @Builtin(name = "hpy_write_member", minNumOfPositionalArgs = 2, parameterNames = {"$self", "value"}) - protected abstract static class HPyWriteMemberNode extends PythonBinaryBuiltinNode { - private static final Builtin builtin = HPyWriteMemberNode.class.getAnnotation(Builtin.class); - - @Child private AsNativeCharNode asNativeCharNode; - @Child private PyLongAsLongNode pyLongAsLongNode; - @Child private PyFloatAsDoubleCachedNode pyFloatAsDoubleNode; - @Child private AsNativePrimitiveNode asNativePrimitiveNode; - @Child private IsBuiltinObjectExactProfile isBuiltinObjectProfile; - @Child private IsNode isNode; - @Child private GraalHPyCAccess.ReadHPyFieldNode readHPyFieldNode; - @Child private GraalHPyCAccess.WriteHPyFieldNode writeHPyFieldNode; - @Child private GraalHPyCAccess.WriteGenericNode writeGenericNode; - @Child private HPyGetNativeSpacePointerNode readNativeSpaceNode; - - /** The specified member type. */ - private final int type; - - /** The offset where to read from (will be passed to the native getter). */ - private final int offset; - - protected HPyWriteMemberNode(int type, int offset) { - this.type = type; - this.offset = offset; - } - - @Specialization - Object doGeneric(VirtualFrame frame, Object self, Object value, - @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { - PythonContext context = getContext(); - GraalHPyContext hPyContext = context.getHPyContext(); - - Object nativeSpacePtr = ensureReadNativeSpaceNode().executeCached(self); - if (nativeSpacePtr == PNone.NO_VALUE) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.SystemError, ErrorMessages.ATTEMPTING_WRITE_OFFSET_D, offset, self); - } - - /* - * Deleting values is only allowed for members with object type (see structmember.c: - * PyMember_SetOne). - */ - Object newValue; - if (value == DescriptorDeleteMarker.INSTANCE) { - if (type == HPY_MEMBER_OBJECT_EX) { - if (self instanceof PythonObject pythonObject) { - Object oldValue = ensureReadHPyFieldNode(hPyContext).read(hPyContext, pythonObject, nativeSpacePtr, offset); - if (oldValue == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.AttributeError); - } - } else { - throw CompilerDirectives.shouldNotReachHere("Cannot have HPyField on non-Python object"); - } - } else if (type != HPY_MEMBER_OBJECT) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.CAN_T_DELETE_NUMERIC_CHAR_ATTRIBUTE); - } - // NO_VALUE will be converted to the NULL handle - newValue = PNone.NO_VALUE; - } else { - newValue = value; - } - - long val; - switch (type) { - case HPY_MEMBER_SHORT: - val = ensurePyLongAsLongNode().executeCached(frame, newValue); - ensureWriteGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, Int16_t, val); - // TODO(fa): truncation warning - // if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN)) - // WARN("Truncation of value to short"); - break; - case HPY_MEMBER_INT: - val = ensurePyLongAsLongNode().executeCached(frame, newValue); - ensureWriteGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, Int, val); - // TODO(fa): truncation warning - // if ((long_val > INT_MAX) || (long_val < INT_MIN)) - // WARN("Truncation of value to int"); - break; - case HPY_MEMBER_LONG: - val = ensurePyLongAsLongNode().executeCached(frame, newValue); - ensureWriteGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, HPyContextSignatureType.Long, val); - break; - case HPY_MEMBER_FLOAT: { - float fvalue = (float) ensurePyFloatAsDoubleNode().execute(frame, newValue); - ensureWriteGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, CFloat, fvalue); - break; - } - case HPY_MEMBER_DOUBLE: { - double dvalue = ensurePyFloatAsDoubleNode().execute(frame, newValue); - ensureWriteGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, CDouble, dvalue); - break; - } - case HPY_MEMBER_STRING, HPY_MEMBER_STRING_INPLACE: - /* - * This node is never created for string members because they are not writeable - * and we create HPyReadOnlyMemberNode for those. - */ - throw CompilerDirectives.shouldNotReachHere(); - case HPY_MEMBER_OBJECT, HPY_MEMBER_OBJECT_EX: - if (self instanceof PythonObject pythonObject) { - ensureWriteHPyFieldNode(hPyContext).execute(hPyContext, pythonObject, nativeSpacePtr, offset, newValue); - } else { - throw CompilerDirectives.shouldNotReachHere("Cannot have HPyField on non-Python object"); - } - break; - case HPY_MEMBER_CHAR: - val = ensureAsNativeCharNode().executeByte(newValue); - ensureWriteGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, Int8_t, val); - break; - case HPY_MEMBER_BYTE: - val = ensurePyLongAsLongNode().executeCached(frame, newValue); - ensureWriteGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, Int8_t, val); - // TODO(fa): truncation warning - // if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN)) - // WARN("Truncation of value to char"); - break; - case HPY_MEMBER_UBYTE: - val = ensurePyLongAsLongNode().executeCached(frame, newValue); - ensureWriteGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, Uint8_t, val); - // TODO(fa): truncation warning - // if ((long_val > UCHAR_MAX) || (long_val < 0)) - // WARN("Truncation of value to unsigned char"); - break; - case HPY_MEMBER_USHORT: - val = ensurePyLongAsLongNode().executeCached(frame, newValue); - ensureWriteGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, Uint16_t, val); - // TODO(fa): truncation warning - // if ((long_val > USHRT_MAX) || (long_val < 0)) - // WARN("Truncation of value to unsigned short"); - break; - case HPY_MEMBER_UINT: { - val = ensurePyLongAsLongNode().executeCached(frame, newValue); - Object uint = ensureAsNativePrimitiveNode().execute(val, 0, hPyContext.getCTypeSize(UnsignedInt), true); - ensureWriteGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, UnsignedInt, uint); - break; - } - case HPY_MEMBER_ULONG: { - val = ensurePyLongAsLongNode().executeCached(frame, newValue); - Object ulong = ensureAsNativePrimitiveNode().execute(val, 0, hPyContext.getCTypeSize(UnsignedLong), true); - ensureWriteGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, UnsignedLong, ulong); - break; - } - case HPY_MEMBER_BOOL: - // note: exact type check is sufficient; bool cannot be subclassed - if (!ensureIsBuiltinObjectProfile().profileObject(this, newValue, PythonBuiltinClassType.Boolean)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_VALUE_MUST_BE_BOOL); - } - val = ensureIsNode().isTrue(newValue) ? 1 : 0; - ensureWriteGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, Bool, val); - break; - case HPY_MEMBER_LONGLONG: - val = ensurePyLongAsLongNode().executeCached(frame, newValue); - ensureWriteGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, Int64_t, val); - break; - case HPY_MEMBER_ULONGLONG: - val = ensurePyLongAsLongNode().executeCached(frame, newValue); - val = (long) ensureAsNativePrimitiveNode().execute(val, 0, 8, true); - ensureWriteGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, Int64_t, val); - break; - case HPY_MEMBER_HPYSSIZET: - // TODO(fa): PyLongAsLong is not correct - val = ensurePyLongAsLongNode().executeCached(frame, newValue); - ensureWriteGenericNode(hPyContext).execute(hPyContext, nativeSpacePtr, offset, HPyContextSignatureType.HPy_ssize_t, val); - break; - default: - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.SystemError, ErrorMessages.BAD_MEMBER_DESCR_TYPE_FOR_S, ""); - } - return PNone.NONE; - } - - private GraalHPyCAccess.ReadHPyFieldNode ensureReadHPyFieldNode(GraalHPyContext ctx) { - if (readHPyFieldNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readHPyFieldNode = insert(GraalHPyCAccess.ReadHPyFieldNode.create(ctx)); - } - return readHPyFieldNode; - } - - private GraalHPyCAccess.WriteHPyFieldNode ensureWriteHPyFieldNode(GraalHPyContext ctx) { - if (writeHPyFieldNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - writeHPyFieldNode = insert(GraalHPyCAccess.WriteHPyFieldNode.create(ctx)); - } - return writeHPyFieldNode; - } - - private GraalHPyCAccess.WriteGenericNode ensureWriteGenericNode(GraalHPyContext ctx) { - if (writeGenericNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - writeGenericNode = insert(GraalHPyCAccess.WriteGenericNode.create(ctx)); - } - return writeGenericNode; - } - - private HPyGetNativeSpacePointerNode ensureReadNativeSpaceNode() { - if (readNativeSpaceNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readNativeSpaceNode = insert(HPyGetNativeSpacePointerNodeGen.create()); - } - return readNativeSpaceNode; - } - - private PyLongAsLongNode ensurePyLongAsLongNode() { - if (pyLongAsLongNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - pyLongAsLongNode = insert(PyLongAsLongNodeGen.create()); - } - return pyLongAsLongNode; - } - - private PyFloatAsDoubleCachedNode ensurePyFloatAsDoubleNode() { - if (pyFloatAsDoubleNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - pyFloatAsDoubleNode = insert(PyFloatAsDoubleCachedNodeGen.create()); - } - return pyFloatAsDoubleNode; - } - - private AsNativePrimitiveNode ensureAsNativePrimitiveNode() { - if (asNativePrimitiveNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - asNativePrimitiveNode = insert(AsNativePrimitiveNodeGen.create()); - } - return asNativePrimitiveNode; - } - - private IsBuiltinObjectExactProfile ensureIsBuiltinObjectProfile() { - if (isBuiltinObjectProfile == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - isBuiltinObjectProfile = insert(IsBuiltinObjectExactProfile.create()); - } - return isBuiltinObjectProfile; - } - - private IsNode ensureIsNode() { - if (isNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - isNode = insert(IsNode.create()); - } - return isNode; - } - - private AsNativeCharNode ensureAsNativeCharNode() { - if (asNativeCharNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - asNativeCharNode = insert(AsNativeCharNodeGen.create()); - } - return asNativeCharNode; - } - - @TruffleBoundary - public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, TruffleString propertyName, int type, int offset) { - if (isReadOnlyType(type)) { - return HPyReadOnlyMemberNode.createBuiltinFunction(language, propertyName); - } - if (type == HPY_MEMBER_NONE) { - return HPyBadMemberDescrNode.createBuiltinFunction(language, propertyName); - } - RootCallTarget callTarget = language.createCachedPropAccessCallTarget( - l -> new BuiltinFunctionRootNode(l, builtin, new PrototypeNodeFactory<>(HPyWriteMemberNodeGen.create(type, offset)), true), - HPyWriteMemberNode.class, builtin.name(), type, offset); - int flags = PBuiltinFunction.getFlags(builtin, callTarget); - return PythonObjectFactory.getUncached().createBuiltinFunction(propertyName, null, 0, flags, callTarget); - } - } - - @GenerateInline(false) - abstract static class PyFloatAsDoubleCachedNode extends Node { - - public abstract double execute(VirtualFrame frame, Object object); - - @Specialization - static double doGeneric(VirtualFrame frame, Object object, - @Bind("this") Node inliningTarget, - @Cached PyFloatAsDoubleNode pyFloatAsDoubleNode) { - return pyFloatAsDoubleNode.execute(frame, inliningTarget, object); - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyNativeCache.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyNativeCache.java deleted file mode 100644 index 4b3cb6b7f7..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyNativeCache.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.SIZEOF_LONG; - -import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers; - -import sun.misc.Unsafe; - -/** - * HPy native cache implementation. For documentation of the layout, see {@code hpy_native_cache.h}. - */ -public abstract class GraalHPyNativeCache { - - private static final Unsafe UNSAFE = CArrayWrappers.UNSAFE; - - private static final long HANDLE_MIRROR_OFFSET = 1; - - static long toBytes(long idx) { - return (HANDLE_MIRROR_OFFSET + idx) * SIZEOF_LONG; - } - - static long allocateNativeCache(int nHandleTable, int nGlobalsTable) { - long arraySize = toBytes(nHandleTable + nGlobalsTable); - long arrayPtr = UNSAFE.allocateMemory(arraySize); - UNSAFE.setMemory(arrayPtr, arraySize, (byte) 0); - UNSAFE.putLong(arrayPtr, nHandleTable); - return arrayPtr; - } - - static long reallocateNativeCache(long cachePtr, int nHandleTableOld, int nHandleTable, int nGlobalsTableOld, int nGlobalsTable) { - if (nHandleTableOld > nHandleTable || nGlobalsTableOld > nGlobalsTable) { - throw new RuntimeException("shrinking HPy handle/globals table is not yet supported"); - } - long arraySize = toBytes(nHandleTable + nGlobalsTable); - long newCachePtr = UNSAFE.reallocateMemory(cachePtr, arraySize); - if (nHandleTableOld != nHandleTable) { - // update handle table size - UNSAFE.putLong(newCachePtr, nHandleTable); - // move globals table entries (only if the handle table size changed) - UNSAFE.copyMemory(newCachePtr + toBytes(nHandleTableOld), newCachePtr + toBytes(nHandleTable), nGlobalsTableOld * SIZEOF_LONG); - } - return newCachePtr; - } - - static void putHandleNativeSpacePointer(long cachePtr, int handleID, long value) { - UNSAFE.putLong(cachePtr + toBytes(handleID), value); - } - - static void putGlobalNativeSpacePointer(long cachePtr, long nHandleTable, int globalID, long value) { - UNSAFE.putLong(cachePtr + toBytes(nHandleTable + globalID), value); - } - - static void initGlobalsNativeSpacePointer(long cachePtr, long nHandleTable, int globalStartID, int numElem) { - UNSAFE.setMemory(cachePtr + toBytes(nHandleTable + globalStartID), numElem * SIZEOF_LONG, (byte) 0); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyNativeContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyNativeContext.java deleted file mode 100644 index 7575f0d193..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyNativeContext.java +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.MemoryError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.RecursionError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; -import static com.oracle.graal.python.util.PythonUtils.EMPTY_OBJECT_ARRAY; - -import java.io.IOException; -import java.io.PrintStream; - -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ApiInitException; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ImportException; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.AllocateNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.BulkFreeHandleReferencesNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.FreeNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.GetElementPtrNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.IsNullNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadDoubleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadFloatNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyArrayNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyFieldNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadI32Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadI64Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadI8ArrayNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteDoubleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteGenericNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteHPyFieldNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteHPyNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteI32Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteI64Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WritePointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteSizeTNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.HPyABIVersion; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.HPyUpcall; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsCharPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyCallHelperFunctionNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyFromCharPointerNode; -import com.oracle.graal.python.builtins.objects.exception.PBaseException; -import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.util.CannotCastException; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.exception.ExceptionUtils; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.interop.ArityException; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.interop.UnsupportedTypeException; -import com.oracle.truffle.api.library.ExportLibrary; -import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.strings.TruffleString; - -@ExportLibrary(InteropLibrary.class) -public abstract class GraalHPyNativeContext implements TruffleObject { - - protected final GraalHPyContext context; - - protected GraalHPyNativeContext(GraalHPyContext context, boolean traceUpcalls) { - this.context = context; - } - - protected abstract String getName(); - - protected final PythonContext getContext() { - return context.getContext(); - } - - protected abstract void initNativeContext() throws ApiInitException; - - protected abstract void finalizeNativeContext(); - - protected abstract Object loadExtensionLibrary(Node location, PythonContext context, TruffleString name, TruffleString path) throws ImportException, IOException; - - protected abstract HPyABIVersion getHPyABIVersion(Object extLib, String getMajorVersionFuncName, String getMinorVersionFuncName) throws Exception; - - /** - * Execute an HPy extension's init function and return the raw result value. - * - * @param extLib The HPy extension's shared library object (received from - * {@link #loadExtensionLibrary(Node, PythonContext, TruffleString, TruffleString)}). - * @param initFuncName The HPy extension's init function name (e.g. {@code HPyInit_poc}). - * @param name The HPy extension's name as requested by the user. - * @param path The HPy extension's shared library path. - * @param mode An enum indicating which mode should be used to initialize the HPy extension. - * @return The bare (unconverted) result of the HPy extension's init function. This will be a - * handle that was created with the given {@code hpyContext}. - */ - protected abstract Object initHPyModule(Object extLib, String initFuncName, TruffleString name, TruffleString path, HPyMode mode) - throws UnsupportedMessageException, ArityException, UnsupportedTypeException, ImportException, ApiInitException; - - protected abstract HPyUpcall[] getUpcalls(); - - protected abstract int[] getUpcallCounts(); - - public abstract void initHPyDebugContext() throws ApiInitException; - - public abstract void initHPyTraceContext() throws ApiInitException; - - public abstract PythonModule getHPyDebugModule() throws ImportException; - - public abstract PythonModule getHPyTraceModule() throws ImportException; - - protected abstract void setNativeCache(long cachePtr); - - protected abstract int getCTypeSize(HPyContextSignatureType ctype); - - protected abstract int getCFieldOffset(GraalHPyCField cfield); - - /** - * Converts a native pointer from the representation used by this native context (e.g. - * {@link Long}) to an interop pointer object that responds to interop messages - * {@link InteropLibrary#isPointer(Object)} and {@link InteropLibrary#asPointer(Object)}. - */ - protected abstract Object nativeToInteropPointer(Object object); - - protected abstract Object getNativeNull(); - - protected abstract Object createArgumentsArray(Object[] args); - - protected abstract void freeArgumentsArray(Object argsArray); - - public abstract HPyCallHelperFunctionNode createCallHelperFunctionNode(); - - public abstract HPyCallHelperFunctionNode getUncachedCallHelperFunctionNode(); - - public abstract HPyFromCharPointerNode createFromCharPointerNode(); - - public abstract HPyFromCharPointerNode getUncachedFromCharPointerNode(); - - protected final boolean useNativeFastPaths() { - return context.useNativeFastPaths; - } - - public final GraalHPyContext getHPyContext() { - return context; - } - - @ExportMessage - public void toNative() { - try { - toNativeInternal(); - if (useNativeFastPaths()) { - initNativeFastPaths(); - /* - * Allocate a native array for the native space pointers of HPy objects and - * initialize it. - */ - context.allocateNativeSpacePointersMirror(); - } - } catch (CannotCastException e) { - /* - * We should only receive 'toNative' if native access is allowed. Hence, the exception - * should never happen. - */ - throw CompilerDirectives.shouldNotReachHere(); - } - } - - protected abstract void toNativeInternal(); - - protected abstract void initNativeFastPaths(); - - @TruffleBoundary - public static PException checkThrowableBeforeNative(Throwable t, String where1, Object where2) { - if (t instanceof PException pe) { - // this is ok, and will be handled correctly - throw pe; - } - if (t instanceof ThreadDeath td) { - // ThreadDeath subclasses are used internally by Truffle - throw td; - } - if (t instanceof StackOverflowError soe) { - CompilerDirectives.transferToInterpreter(); - PythonContext context = PythonContext.get(null); - context.ensureGilAfterFailure(); - PBaseException newException = context.factory().createBaseException(RecursionError, ErrorMessages.MAXIMUM_RECURSION_DEPTH_EXCEEDED, EMPTY_OBJECT_ARRAY); - throw ExceptionUtils.wrapJavaException(soe, null, newException); - } - if (t instanceof OutOfMemoryError oome) { - PBaseException newException = PythonContext.get(null).factory().createBaseException(MemoryError); - throw ExceptionUtils.wrapJavaException(oome, null, newException); - } - // everything else: log and convert to PException (SystemError) - CompilerDirectives.transferToInterpreter(); - PNodeWithContext.printStack(); - PrintStream out = new PrintStream(PythonContext.get(null).getEnv().err()); - out.println("while executing " + where1 + " " + where2); - out.println("should not throw exceptions apart from PException"); - t.printStackTrace(out); - out.flush(); - throw PRaiseNode.raiseUncached(null, SystemError, ErrorMessages.INTERNAL_EXCEPTION_OCCURED); - } - - public abstract AllocateNode createAllocateNode(); - - public abstract AllocateNode getUncachedAllocateNode(); - - public abstract FreeNode createFreeNode(); - - public abstract FreeNode getUncachedFreeNode(); - - public abstract ReadI32Node createReadI32Node(); - - public abstract ReadI32Node getUncachedReadI32Node(); - - public abstract ReadI64Node createReadI64Node(); - - public abstract ReadI64Node getUncachedReadI64Node(); - - public abstract ReadFloatNode createReadFloatNode(); - - public abstract ReadFloatNode getUncachedReadFloatNode(); - - public abstract ReadDoubleNode createReadDoubleNode(); - - public abstract ReadDoubleNode getUncachedReadDoubleNode(); - - public abstract ReadPointerNode createReadPointerNode(); - - public abstract ReadPointerNode getUncachedReadPointerNode(); - - public abstract WriteDoubleNode createWriteDoubleNode(); - - public abstract WriteDoubleNode getUncachedWriteDoubleNode(); - - public abstract WriteI32Node createWriteI32Node(); - - public abstract WriteI32Node getUncachedWriteI32Node(); - - public abstract WriteI64Node createWriteI64Node(); - - public abstract WriteI64Node getUncachedWriteI64Node(); - - public abstract WriteHPyNode createWriteHPyNode(); - - public abstract WriteHPyNode getUncachedWriteHPyNode(); - - public abstract ReadI8ArrayNode createReadI8ArrayNode(); - - public abstract ReadI8ArrayNode getUncachedReadI8ArrayNode(); - - public abstract WritePointerNode createWritePointerNode(); - - public abstract WritePointerNode getUncachedWritePointerNode(); - - public abstract ReadHPyArrayNode createReadHPyArrayNode(); - - public abstract ReadHPyArrayNode getUncachedReadHPyArrayNode(); - - public abstract ReadHPyNode createReadHPyNode(); - - public abstract ReadHPyNode getUncachedReadHPyNode(); - - public abstract ReadHPyFieldNode createReadHPyFieldNode(); - - public abstract ReadHPyFieldNode getUncachedReadFieldHPyNode(); - - public abstract IsNullNode createIsNullNode(); - - public abstract IsNullNode getUncachedIsNullNode(); - - public abstract GraalHPyCAccess.ReadGenericNode createReadGenericNode(); - - public abstract GraalHPyCAccess.ReadGenericNode getUncachedReadGenericNode(); - - public abstract WriteSizeTNode createWriteSizeTNode(); - - public abstract WriteSizeTNode getUncachedWriteSizeTNode(); - - public abstract GetElementPtrNode createGetElementPtrNode(); - - public abstract GetElementPtrNode getUncachedGetElementPtrNode(); - - public abstract WriteHPyFieldNode createWriteHPyFieldNode(); - - public abstract WriteHPyFieldNode getUncachedWriteHPyFieldNode(); - - public abstract WriteGenericNode createWriteGenericNode(); - - public abstract WriteGenericNode getUncachedWriteGenericNode(); - - public abstract BulkFreeHandleReferencesNode createBulkFreeHandleReferencesNode(); - - public abstract HPyAsCharPointerNode createAsCharPointerNode(); - - public abstract HPyAsCharPointerNode getUncachedAsCharPointerNode(); -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyNativeSymbol.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyNativeSymbol.java deleted file mode 100644 index 9366d0a759..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyNativeSymbol.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -public enum GraalHPyNativeSymbol { - - GRAAL_HPY_BUFFER_TO_NATIVE("graal_hpy_buffer_to_native"), - GRAAL_HPY_FREE("graal_hpy_free"), - GRAAL_HPY_FROM_HPY_ARRAY("graal_hpy_from_HPy_array"), - GRAAL_HPY_GET_ERRNO("graal_hpy_get_errno"), - GRAAL_HPY_GET_STRERROR("graal_hpy_get_strerror"), - GRAAL_HPY_STRLEN("graal_hpy_strlen"), - GRAAL_HPY_ARRAY_TO_NATIVE("graal_hpy_array_to_native"), - GRAAL_HPY_FROM_I8_ARRAY("graal_hpy_from_i8_array"), - GRAAL_HPY_CONTEXT_TO_NATIVE("graal_hpy_context_to_native"), - GRAAL_HPY_CALLOC("graal_hpy_calloc"), - GRAAL_HPY_GET_FIELD_I("graal_hpy_get_field_i"), - GRAAL_HPY_SET_FIELD_I("graal_hpy_set_field_i"), - GRAAL_HPY_GET_GLOBAL_I("graal_hpy_get_global_i"), - GRAAL_HPY_SET_GLOBAL_I("graal_hpy_set_global_i"), - GRAAL_HPY_GET_ELEMENT_PTR("graal_hpy_get_element_ptr"), - - /* C functions for reading native members by offset */ - GRAAL_HPY_READ_BOOL("graal_hpy_read_bool"), - GRAAL_HPY_READ_I8("graal_hpy_read_i8"), - GRAAL_HPY_READ_UI8("graal_hpy_read_ui8"), - GRAAL_HPY_READ_I16("graal_hpy_read_i16"), - GRAAL_HPY_READ_UI16("graal_hpy_read_ui16"), - GRAAL_HPY_READ_I32("graal_hpy_read_i32"), - GRAAL_HPY_READ_UI32("graal_hpy_read_ui32"), - GRAAL_HPY_READ_I64("graal_hpy_read_i64"), - GRAAL_HPY_READ_UI64("graal_hpy_read_ui64"), - GRAAL_HPY_READ_I("graal_hpy_read_i"), - GRAAL_HPY_READ_L("graal_hpy_read_l"), - GRAAL_HPY_READ_F("graal_hpy_read_f"), - GRAAL_HPY_READ_D("graal_hpy_read_d"), - GRAAL_HPY_READ_PTR("graal_hpy_read_ptr"), - GRAAL_HPY_READ_HPY("graal_hpy_read_HPy"), - GRAAL_HPY_READ_HPYFIELD("graal_hpy_read_HPyField"), - GRAAL_HPY_READ_UI("graal_hpy_read_ui"), - GRAAL_HPY_READ_UL("graal_hpy_read_ul"), - GRAAL_HPY_READ_HPY_SSIZE_T("graal_hpy_read_HPy_ssize_t"), - - /* C functions for writing native members by offset */ - GRAAL_HPY_WRITE_BOOL("graal_hpy_write_bool"), - GRAAL_HPY_WRITE_I8("graal_hpy_write_i8"), - GRAAL_HPY_WRITE_UI8("graal_hpy_write_ui8"), - GRAAL_HPY_WRITE_I16("graal_hpy_write_i16"), - GRAAL_HPY_WRITE_UI16("graal_hpy_write_ui16"), - GRAAL_HPY_WRITE_I32("graal_hpy_write_i32"), - GRAAL_HPY_WRITE_UI32("graal_hpy_write_ui32"), - GRAAL_HPY_WRITE_I64("graal_hpy_write_i64"), - GRAAL_HPY_WRITE_UI64("graal_hpy_write_ui64"), - GRAAL_HPY_WRITE_I("graal_hpy_write_i"), - GRAAL_HPY_WRITE_L("graal_hpy_write_l"), - GRAAL_HPY_WRITE_F("graal_hpy_write_f"), - GRAAL_HPY_WRITE_D("graal_hpy_write_d"), - GRAAL_HPY_WRITE_HPY("graal_hpy_write_HPy"), - GRAAL_HPY_WRITE_HPYFIELD("graal_hpy_write_HPyField"), - GRAAL_HPY_WRITE_UI("graal_hpy_write_ui"), - GRAAL_HPY_WRITE_UL("graal_hpy_write_ul"), - GRAAL_HPY_WRITE_HPY_SSIZE_T("graal_hpy_write_HPy_ssize_t"), - GRAAL_HPY_WRITE_PTR("graal_hpy_write_ptr"), - - GRAAL_HPY_BULK_FREE("graal_hpy_bulk_free"); - - private final String name; - - GraalHPyNativeSymbol(String name) { - this.name = name; - } - - public String getName() { - return name; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyNodes.java deleted file mode 100644 index 30eb5a37ce..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyNodes.java +++ /dev/null @@ -1,3188 +0,0 @@ -/* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlot.HPY_TP_CALL; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlot.HPY_TP_DESTROY; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlot.HPY_TP_NEW; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlot.HPY_TP_TRAVERSE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyHandle.NULL_HANDLE_DELEGATE; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_basicsize; -import static com.oracle.graal.python.nodes.StringLiterals.T_EXEC; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; -import static com.oracle.graal.python.util.PythonUtils.tsLiteral; - -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.logging.Level; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.PythonAbstractObject; -import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; -import com.oracle.graal.python.builtins.objects.cext.PythonNativeObject; -import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.CreateFunctionNode; -import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.CreateMethodNode; -import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.FromCharPointerNode; -import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.AsNativePrimitiveNode; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.ConvertPIntToPrimitiveNode; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.EnsureExecutableNode; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.TransformExceptionToNativeNode; -import com.oracle.graal.python.builtins.objects.cext.common.CExtToJavaNode; -import com.oracle.graal.python.builtins.objects.cext.common.CExtToNativeNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadGenericNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.LLVMType; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPyFuncSignature; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlot; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlotWrapper; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyLegacyDef.HPyLegacySlot; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyMemberAccessNodes.HPyReadMemberNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyMemberAccessNodes.HPyWriteMemberNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyAllHandleCloseNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyAttachJNIFunctionTypeNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyAttachNFIFunctionTypeNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyCloseHandleNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyGetNativeSpacePointerNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyGetSetSetterHandleCloseNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyKeywordsHandleCloseNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyRaiseNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyRichcmptFuncArgsCloseNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPySSizeObjArgProcCloseNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPySelfHandleCloseNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyTransformExceptionToNativeNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyTypeGetNameNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyVarargsHandleCloseNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyObjectBuiltins.HPyObjectNewNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodes.HPyCheckFunctionResultNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodes.HPyCheckHandleResultNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodes.HPyCheckPrimitiveResultNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodes.HPyGetSetDescriptorGetterRootNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodes.HPyGetSetDescriptorSetterRootNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodes.HPyLegacyGetSetDescriptorGetterRoot; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodes.HPyLegacyGetSetDescriptorSetterRoot; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNIFunctionPointer; -import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; -import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.builtins.objects.getsetdescriptor.GetSetDescriptor; -import com.oracle.graal.python.builtins.objects.ints.PInt; -import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; -import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.type.PythonClass; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.builtins.objects.type.TpSlots; -import com.oracle.graal.python.builtins.objects.type.TpSlots.Builder; -import com.oracle.graal.python.builtins.objects.type.TpSlots.TpSlotMeta; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.HasSameConstructorNode; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotNative; -import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; -import com.oracle.graal.python.lib.PyObjectGetItem; -import com.oracle.graal.python.lib.PyObjectIsTrueNode; -import com.oracle.graal.python.nodes.BuiltinNames; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.HiddenAttr; -import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.SpecialAttributeNames; -import com.oracle.graal.python.nodes.SpecialMethodNames; -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; -import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; -import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode; -import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.classes.IsSubtypeNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.object.IsNode; -import com.oracle.graal.python.nodes.util.CannotCastException; -import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; -import com.oracle.graal.python.runtime.PythonImageBuildOptions; -import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; -import com.oracle.graal.python.util.OverflowException; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.CompilerDirectives.ValueType; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.TruffleLogger; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.Frame; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.ArityException; -import com.oracle.truffle.api.interop.InteropException; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.interop.UnsupportedTypeException; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.nodes.ExplodeLoop; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.object.DynamicObjectLibrary; -import com.oracle.truffle.api.profiles.InlinedBranchProfile; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; -import com.oracle.truffle.api.profiles.InlinedExactClassProfile; -import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.strings.TruffleString; -import com.oracle.truffle.api.strings.TruffleString.Encoding; -import com.oracle.truffle.nfi.api.SignatureLibrary; - -public abstract class GraalHPyNodes { - - /** - * A node interface for calling (native) helper functions. The implementation depends on the HPy - * backend. This is the reason why this node takes the HPy context as construction parameter. - * The recommended usage of this node is - * - *
    -     * @Specialization
    -     * Object doSomething(GraalHPyContext hpyContext,
    -     *                 @Cached(parameters = "hpyContext") HPyCallHelperFunctionNode callHelperNode) {
    -     *     // ...
    -     * }
    -     * 
    - */ - public abstract static class HPyCallHelperFunctionNode extends Node { - public final Object call(GraalHPyContext context, GraalHPyNativeSymbol name, Object... args) { - return execute(context, name, args); - } - - protected abstract Object execute(GraalHPyContext context, GraalHPyNativeSymbol name, Object[] args); - - @NeverDefault - public static HPyCallHelperFunctionNode create(GraalHPyContext context) { - return context.getBackend().createCallHelperFunctionNode(); - } - - public static HPyCallHelperFunctionNode getUncached(GraalHPyContext context) { - return context.getBackend().getUncachedCallHelperFunctionNode(); - } - } - - /** - * Use this node to transform an exception to native if a Python exception was thrown during an - * upcall and before returning to native code. This node will correctly link to the current - * frame using the frame reference and tries to avoid any materialization of the frame. The - * exception is then registered in the native context as the current exception. - */ - @GenerateInline - @GenerateCached(false) - @GenerateUncached - public abstract static class HPyTransformExceptionToNativeNode extends Node { - - public abstract void execute(Frame frame, Node inliningTarget, GraalHPyContext nativeContext, PException e); - - public final void execute(Node inliningTarget, GraalHPyContext nativeContext, PException e) { - execute(null, inliningTarget, nativeContext, e); - } - - public final void execute(Node inliningTarget, PException e) { - execute(null, inliningTarget, PythonContext.get(this).getHPyContext(), e); - } - - public static void executeUncached(GraalHPyContext nativeContext, PException e) { - HPyTransformExceptionToNativeNodeGen.getUncached().execute(null, nativeContext, e); - } - - public static void executeUncached(PException e) { - HPyTransformExceptionToNativeNodeGen.getUncached().execute(null, null, e); - } - - @Specialization - static void setCurrentException(Frame frame, Node inliningTarget, @SuppressWarnings("unused") GraalHPyContext nativeContext, PException e, - @Cached TransformExceptionToNativeNode transformExceptionToNativeNode) { - transformExceptionToNativeNode.execute(frame, inliningTarget, e); - } - } - - @GenerateUncached - @GenerateInline(false) - public abstract static class HPyRaiseNode extends Node { - - public final int raiseInt(Frame frame, GraalHPyContext nativeContext, int errorValue, PythonBuiltinClassType errType, TruffleString format, Object... arguments) { - return executeInt(frame, nativeContext, errorValue, errType, format, arguments); - } - - public final Object raise(Frame frame, GraalHPyContext nativeContext, Object errorValue, PythonBuiltinClassType errType, TruffleString format, Object... arguments) { - return execute(frame, nativeContext, errorValue, errType, format, arguments); - } - - public final int raiseIntWithoutFrame(GraalHPyContext nativeContext, int errorValue, PythonBuiltinClassType errType, TruffleString format, Object... arguments) { - return executeInt(null, nativeContext, errorValue, errType, format, arguments); - } - - public final Object raiseWithoutFrame(GraalHPyContext nativeContext, Object errorValue, PythonBuiltinClassType errType, TruffleString format, Object... arguments) { - return execute(null, nativeContext, errorValue, errType, format, arguments); - } - - public static int raiseIntUncached(GraalHPyContext nativeContext, int errorValue, PythonBuiltinClassType errType, TruffleString format, Object... arguments) { - return HPyRaiseNodeGen.getUncached().raiseIntWithoutFrame(nativeContext, errorValue, errType, format, arguments); - } - - public abstract Object execute(Frame frame, GraalHPyContext nativeContext, Object errorValue, PythonBuiltinClassType errType, TruffleString format, Object[] arguments); - - public abstract int executeInt(Frame frame, GraalHPyContext nativeContext, int errorValue, PythonBuiltinClassType errType, TruffleString format, Object[] arguments); - - @Specialization - static int doInt(Frame frame, GraalHPyContext nativeContext, int errorValue, PythonBuiltinClassType errType, TruffleString format, Object[] arguments, - @Bind("this") Node inliningTarget, - @Shared("raiseNode") @Cached PRaiseNode raiseNode, - @Shared("transformExceptionToNativeNode") @Cached HPyTransformExceptionToNativeNode transformExceptionToNativeNode) { - try { - throw raiseNode.execute(raiseNode, errType, PNone.NO_VALUE, format, arguments); - } catch (PException p) { - transformExceptionToNativeNode.execute(frame, inliningTarget, nativeContext, p); - } - return errorValue; - } - - @Specialization - static Object doObject(Frame frame, GraalHPyContext nativeContext, Object errorValue, PythonBuiltinClassType errType, TruffleString format, Object[] arguments, - @Bind("this") Node inliningTarget, - @Shared("raiseNode") @Cached PRaiseNode raiseNode, - @Shared("transformExceptionToNativeNode") @Cached HPyTransformExceptionToNativeNode transformExceptionToNativeNode) { - try { - throw raiseNode.execute(raiseNode, errType, PNone.NO_VALUE, format, arguments); - } catch (PException p) { - transformExceptionToNativeNode.execute(frame, inliningTarget, nativeContext, p); - } - return errorValue; - } - } - - /** - * A node interface for creating a TruffleString from a {@code char *}. The implementation - * depends on the HPy backend. This is the reason why this node takes the HPy context as - * construction parameter. The recommended usage of this node is - * - *
    -     * @Specialization
    -     * Object doSomething(GraalHPyContext hpyContext,
    -     *                 @Cached(parameters = "hpyContext") HPyFromCharPointerNode fromCharPointerNode) {
    -     *     // ...
    -     * }
    -     * 
    - */ - public abstract static class HPyFromCharPointerNode extends Node { - - public final TruffleString execute(GraalHPyContext hpyContext, Object charPtr, boolean copy) { - return execute(hpyContext, charPtr, -1, Encoding.UTF_8, copy); - } - - public final TruffleString execute(GraalHPyContext hpyContext, Object charPtr, Encoding encoding) { - return execute(hpyContext, charPtr, -1, encoding, true); - } - - public abstract TruffleString execute(GraalHPyContext hpyContext, Object charPtr, int n, Encoding encoding, boolean copy); - - public abstract TruffleString execute(GraalHPyContext hpyContext, long charPtr, int n, Encoding encoding, boolean copy); - - @NeverDefault - public static HPyFromCharPointerNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createFromCharPointerNode(); - } - - public static HPyFromCharPointerNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedFromCharPointerNode(); - } - } - - public abstract static class HPyAsCharPointerNode extends Node { - - public abstract Object execute(GraalHPyContext hpyContext, TruffleString string, Encoding encoding); - - @NeverDefault - public static HPyAsCharPointerNode create(GraalHPyContext hpyContext) { - return hpyContext.getBackend().createAsCharPointerNode(); - } - - public static HPyAsCharPointerNode getUncached(GraalHPyContext hpyContext) { - return hpyContext.getBackend().getUncachedAsCharPointerNode(); - } - } - - /** - * Creates an HPy module from a module definition structure: - * - *
    -     * typedef struct {
    -     *     const char* doc;
    -     *     HPy_ssize_t size;
    -     *     cpy_PyMethodDef *legacy_methods;
    -     *     HPyDef **defines;
    -     *     HPyGlobal **globals;
    -     * } HPyModuleDef;
    -     * 
    - */ - @GenerateUncached - @GenerateCached(false) - @GenerateInline(false) // footprint reduction 108 -> 89 - public abstract static class GraalHPyModuleCreate extends Node { - - private static final TruffleLogger LOGGER = GraalHPyContext.getLogger(GraalHPyModuleCreate.class); - - public abstract Object execute(GraalHPyContext hpyContext, TruffleString mName, Object spec, Object moduleDefPtr); - - @Specialization - static Object doGeneric(GraalHPyContext context, TruffleString mName, Object spec, Object moduleDefPtr, - @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, - @Cached(parameters = "context") GraalHPyCAccess.ReadPointerNode readPointerNode, - @Cached(parameters = "context") GraalHPyCAccess.IsNullNode isNullNode, - @Cached(parameters = "context") GraalHPyCAccess.ReadGenericNode readGenericNode, - @Cached(parameters = "context") GraalHPyCAccess.WriteSizeTNode writeSizeTNode, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached WriteAttributeToObjectNode writeAttrNode, - @Cached WriteAttributeToPythonObjectNode writeAttrToMethodNode, - @Cached HPyCreateFunctionNode addFunctionNode, - @Cached CreateMethodNode addLegacyMethodNode, - @Cached HPyReadSlotNode readSlotNode, - @Cached HPyCheckHandleResultNode checkFunctionResultNode, - @Cached HPyAsHandleNode asHandleNode, - @CachedLibrary(limit = "1") InteropLibrary createLib, - @Cached PRaiseNode raiseNode) { - - TruffleString mDoc; - long size; - Object docPtr = readPointerNode.read(context, moduleDefPtr, GraalHPyCField.HPyModuleDef__doc); - if (!isNullNode.execute(context, docPtr)) { - mDoc = fromCharPointerNode.execute(docPtr); - } else { - mDoc = null; - } - - size = readGenericNode.readLong(context, moduleDefPtr, GraalHPyCField.HPyModuleDef__size); - if (size < 0) { - throw raiseNode.raise(PythonBuiltinClassType.SystemError, tsLiteral("HPy does not permit HPyModuleDef.size < 0")); - } else if (size > 0) { - throw raiseNode.raise(PythonBuiltinClassType.SystemError, tsLiteral("Module state is not supported yet in HPy, set HPyModuleDef.size = 0 if module state is not needed")); - } - - // process HPy module slots - Object moduleDefinesPtr = readPointerNode.read(context, moduleDefPtr, GraalHPyCField.HPyModuleDef__defines); - - List executeSlots = new LinkedList<>(); - List methodDefs = new LinkedList<>(); - Object createFunction = null; - - if (!isNullNode.execute(context, moduleDefinesPtr)) { - for (int i = 0;; i++) { - Object def = readPointerNode.readArrayElement(context, moduleDefinesPtr, i); - if (isNullNode.execute(context, def)) { - break; - } - int kind = readGenericNode.readInt(context, def, GraalHPyCField.HPyDef__kind); - switch (kind) { - case GraalHPyDef.HPY_DEF_KIND_METH: - methodDefs.add(def); - break; - case GraalHPyDef.HPY_DEF_KIND_SLOT: - HPySlotData slotData = readSlotNode.execute(inliningTarget, context, def); - switch (slotData.slot) { - case HPY_MOD_CREATE -> { - if (createFunction != null) { - throw raiseNode.raise(PythonErrorType.SystemError, ErrorMessages.MODULE_HAS_MULTIPLE_CREATE_SLOTS, mName); - } - createFunction = slotData.impl; - } - case HPY_MOD_EXEC -> { - if (createFunction != null) { - throw raiseNode.raise(PythonErrorType.SystemError, ErrorMessages.HPY_DEFINES_CREATE_AND_OTHER_SLOTS, mName); - } - /* - * In contrast to CPython, we already parse and store the - * HPy_mod_exec slots here since parsing is a bit more expensive - * in our case. - */ - executeSlots.add(slotData.impl); - } - default -> throw raiseNode.raise(PythonErrorType.SystemError, ErrorMessages.MODULE_USES_UNKNOW_SLOT_ID, mName, slotData.slot); - } - break; - case GraalHPyDef.HPY_DEF_KIND_MEMBER: - case GraalHPyDef.HPY_DEF_KIND_GETSET: - // silently ignore - LOGGER.warning("get/set definitions are not supported for modules"); - break; - default: - if (LOGGER.isLoggable(Level.SEVERE)) { - LOGGER.severe(PythonUtils.formatJString("unknown definition kind: %d", kind)); - } - assert false; - } - } - } - - // determine of 'legacy_methods' is NULL upfront (required for a consistency check) - Object legacyMethods = readPointerNode.read(context, moduleDefPtr, GraalHPyCField.HPyModuleDef__legacy_methods); - // the field 'legacy_methods' may be 'NULL' - boolean hasLegacyMethods = !isNullNode.execute(context, legacyMethods); - - // allocate module's HPyGlobals - int globalStartIdx = context.getEndIndexOfGlobalTable(); - int nModuleGlobals = initModuleGlobals(context, moduleDefPtr, globalStartIdx, isNullNode, readPointerNode, writeSizeTNode); - context.initBatchGlobals(globalStartIdx, nModuleGlobals); - - // create the module object - Object module; - if (createFunction != null) { - /* - * TODO(fa): this check should be before any other check (and the also test for - * 'size > 0') - */ - if (hasLegacyMethods || mDoc != null || nModuleGlobals != 0) { - throw raiseNode.raise(SystemError, ErrorMessages.HPY_DEFINES_CREATE_AND_NON_DEFAULT); - } - module = callCreate(inliningTarget, createFunction, context, spec, checkFunctionResultNode, asHandleNode, createLib); - if (module instanceof PythonModule) { - throw raiseNode.raise(SystemError, ErrorMessages.HPY_MOD_CREATE_RETURNED_BUILTIN_MOD); - } - } else { - PythonModule pmodule = factory.createPythonModule(mName); - pmodule.setNativeModuleDef(executeSlots); - module = pmodule; - } - - // process HPy methods - for (Object methodDef : methodDefs) { - PBuiltinFunction fun = addFunctionNode.execute(context, null, methodDef); - PBuiltinMethod method = factory.createBuiltinMethod(module, fun); - writeAttrToMethodNode.execute(method, SpecialAttributeNames.T___MODULE__, mName); - writeAttrNode.execute(module, fun.getName(), method); - } - - // process legacy methods - if (hasLegacyMethods) { - for (int i = 0;; i++) { - PBuiltinFunction fun = addLegacyMethodNode.execute(inliningTarget, legacyMethods, i); - if (fun == null) { - break; - } - PBuiltinMethod method = factory.createBuiltinMethod(module, fun); - writeAttrToMethodNode.execute(method, SpecialAttributeNames.T___MODULE__, mName); - writeAttrNode.execute(module, fun.getName(), method); - } - } - - if (mDoc != null) { - writeAttrNode.execute(module, SpecialAttributeNames.T___DOC__, mDoc); - } - - return module; - } - - /** - * Initializes all HPy globals of the currently created module. - */ - private static int initModuleGlobals(GraalHPyContext hpyContext, Object moduleDefPtr, int startID, - GraalHPyCAccess.IsNullNode isNullNode, - GraalHPyCAccess.ReadPointerNode readPointerNode, - GraalHPyCAccess.WriteSizeTNode writeSizeTNode) { - Object globalsPtrArr = readPointerNode.read(hpyContext, moduleDefPtr, GraalHPyCField.HPyModuleDef__globals); - if (!isNullNode.execute(hpyContext, globalsPtrArr)) { - for (int i = 0;; i++) { - Object globalPtr = readPointerNode.readArrayElement(hpyContext, globalsPtrArr, i); - if (isNullNode.execute(hpyContext, globalPtr)) { - return i; - } - writeSizeTNode.execute(hpyContext, globalPtr, 0, startID + i); - } - } - return 0; - } - - private static final TruffleString CREATE = tsLiteral("create"); - - /** - * Call the create slot function. - * - * TODO(fa): This method shares some logic with - * {@link com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodes.HPyExternalFunctionInvokeNode}. - * We should refactor the node such that we can use it here. - */ - static Object callCreate(Node inliningTarget, Object callable, GraalHPyContext hPyContext, Object spec, - HPyCheckFunctionResultNode checkFunctionResultNode, HPyAsHandleNode asHandleNode, InteropLibrary lib) { - - PythonContext ctx = hPyContext.getContext(); - PythonLanguage language = ctx.getLanguage(inliningTarget); - PythonThreadState pythonThreadState = ctx.getThreadState(language); - - GraalHPyHandle hSpec = asHandleNode.execute(spec); - try { - return checkFunctionResultNode.execute(pythonThreadState, CREATE, lib.execute(callable, hPyContext.getBackend(), hSpec)); - } catch (UnsupportedTypeException | UnsupportedMessageException e) { - throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CALLING_NATIVE_FUNC_FAILED, CREATE, e); - } catch (ArityException e) { - throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CALLING_NATIVE_FUNC_EXPECTED_ARGS, CREATE, e.getExpectedMinArity(), e.getActualArity()); - } finally { - // close all handles (if necessary) - if (hSpec.isAllocated()) { - hSpec.closeAndInvalidate(hPyContext); - } - } - } - } - - @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class GraalHPyModuleExecNode extends Node { - - public abstract void execute(Node node, GraalHPyContext hpyContext, PythonModule module); - - @Specialization - static void doGeneric(Node node, GraalHPyContext hpyContext, PythonModule module, - @Cached(inline = false) HPyCheckPrimitiveResultNode checkFunctionResultNode, - @Cached(inline = false) HPyAsHandleNode asHandleNode, - @CachedLibrary(limit = "1") InteropLibrary lib) { - // TODO(fa): once we support HPy module state, we need to allocate it here - Object execSlotsObj = module.getNativeModuleDef(); - if (execSlotsObj instanceof LinkedList execSlots) { - for (Object execSlot : execSlots) { - callExec(node, hpyContext, execSlot, module, checkFunctionResultNode, asHandleNode, lib); - } - } - } - - /** - * Call the exec slot function. - *

    - * TODO(fa): This method shares some logic with - * {@link com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodes.HPyExternalFunctionInvokeNode}. - * We should refactor the node such that we can use it here. - *

    - */ - static void callExec(Node node, GraalHPyContext hPyContext, Object callable, PythonModule module, - HPyCheckPrimitiveResultNode checkFunctionResultNode, HPyAsHandleNode asHandleNode, InteropLibrary lib) { - - PythonContext ctx = hPyContext.getContext(); - PythonLanguage language = ctx.getLanguage(node); - PythonThreadState pythonThreadState = ctx.getThreadState(language); - - GraalHPyHandle hModule = asHandleNode.execute(module); - try { - checkFunctionResultNode.execute(pythonThreadState, T_EXEC, lib.execute(callable, hPyContext.getBackend(), hModule)); - } catch (UnsupportedTypeException | UnsupportedMessageException e) { - throw PRaiseNode.raiseUncached(node, PythonBuiltinClassType.TypeError, ErrorMessages.CALLING_NATIVE_FUNC_FAILED, T_EXEC, e); - } catch (ArityException e) { - throw PRaiseNode.raiseUncached(node, PythonBuiltinClassType.TypeError, ErrorMessages.CALLING_NATIVE_FUNC_EXPECTED_ARGS, T_EXEC, e.getExpectedMinArity(), e.getActualArity()); - } finally { - // close all handles (if necessary) - if (hModule.isAllocated()) { - hModule.closeAndInvalidate(hPyContext); - } - } - } - } - - /** - *
    -     *     typedef struct {
    -     *         const char *name;             // The name of the built-in function/method
    -     *         const char *doc;              // The __doc__ attribute, or NULL
    -     *         void *impl;                   // Function pointer to the implementation
    -     *         void *cpy_trampoline;         // Used by CPython to call impl
    -     *         HPyFunc_Signature signature;  // Indicates impl's expected the signature
    -     *     } HPyMeth;
    -     * 
    - */ - @GenerateUncached - @GenerateInline(false) // footprint reduction 52 -> 33 - public abstract static class HPyCreateFunctionNode extends PNodeWithContext { - - public abstract PBuiltinFunction execute(GraalHPyContext context, Object enclosingType, Object methodDef); - - @Specialization - static PBuiltinFunction doIt(GraalHPyContext context, Object enclosingType, Object methodDef, - @Bind("this") Node inliningTarget, - @Cached(parameters = "context") GraalHPyCAccess.ReadPointerNode readPointerNode, - @Cached(parameters = "context") GraalHPyCAccess.IsNullNode isNullNode, - @Cached(parameters = "context") GraalHPyCAccess.ReadGenericNode readGenericNode, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached HPyAttachFunctionTypeNode attachFunctionTypeNode, - @Cached PythonObjectFactory factory, - @Cached WriteAttributeToPythonObjectNode writeAttributeToPythonObjectNode, - @Cached PRaiseNode raiseNode) { - - TruffleString methodName = fromCharPointerNode.execute(readPointerNode.read(context, methodDef, GraalHPyCField.HPyDef__meth__name)); - - // note: 'ml_doc' may be NULL; in this case, we would store 'None' - Object methodDoc = PNone.NONE; - Object doc = readPointerNode.read(context, methodDef, GraalHPyCField.HPyDef__meth__doc); - if (!isNullNode.execute(context, doc)) { - methodDoc = fromCharPointerNode.execute(doc, false); - } - - HPyFuncSignature signature; - Object methodFunctionPointer; - signature = HPyFuncSignature.fromValue(readGenericNode.readInt(context, methodDef, GraalHPyCField.HPyDef__meth__signature)); - if (signature == null) { - throw raiseNode.raise(PythonBuiltinClassType.ValueError, ErrorMessages.UNSUPPORTED_HYPMETH_SIG); - } - - methodFunctionPointer = readPointerNode.read(context, methodDef, GraalHPyCField.HPyDef__meth__impl); - methodFunctionPointer = attachFunctionTypeNode.execute(context, methodFunctionPointer, signature.getLLVMFunctionType()); - - PythonLanguage language = context.getContext().getLanguage(inliningTarget); - PBuiltinFunction function = HPyExternalFunctionNodes.createWrapperFunction(language, context, signature, methodName, methodFunctionPointer, enclosingType, factory); - - // write doc string; we need to directly write to the storage otherwise it is - // disallowed writing to builtin types. - writeAttributeToPythonObjectNode.execute(function, SpecialAttributeNames.T___DOC__, methodDoc); - - return function; - } - } - - /** - * Parses a pointer to a {@code PyGetSetDef} struct and creates the corresponding property. - * - *
    -     *     typedef struct PyGetSetDef {
    -     *         const char *name;
    -     *         getter get;
    -     *         setter set;
    -     *         const char *doc;
    -     *         void *closure;
    -     * } PyGetSetDef;
    -     * 
    - */ - @GenerateUncached - @GenerateInline(false) // footprint reduction 44 -> 25 - public abstract static class HPyAddLegacyGetSetDefNode extends PNodeWithContext { - - public abstract GetSetDescriptor execute(GraalHPyContext context, Object owner, Object legacyGetSetDefArrPtr, int i); - - @Specialization - static GetSetDescriptor doGeneric(GraalHPyContext context, Object owner, Object legacyGetSetDef, int i, - @Bind("this") Node inliningTarget, - @Cached(parameters = "context") GraalHPyCAccess.ReadPointerNode readPointerNode, - @Cached(parameters = "context") GraalHPyCAccess.IsNullNode isNullNode, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached PythonObjectFactory factory, - @Cached EnsureExecutableNode ensureExecutableNode, - @Cached WriteAttributeToPythonObjectNode writeDocNode, - @Cached PRaiseNode raiseNode) { - - // compute offset of name and read name pointer - long nameOffset = GraalHPyCAccess.ReadPointerNode.getElementPtr(context, i, HPyContextSignatureType.PyGetSetDef, GraalHPyCField.PyGetSetDef__name); - Object namePtr = readPointerNode.execute(context, legacyGetSetDef, nameOffset); - - // if the name pointer is null, this is the sentinel - if (isNullNode.execute(context, namePtr)) { - return null; - } - TruffleString getSetDescrName = fromCharPointerNode.execute(namePtr); - - // compute remaining offsets - long docOffset = GraalHPyCAccess.ReadPointerNode.getElementPtr(context, i, HPyContextSignatureType.PyGetSetDef, GraalHPyCField.PyGetSetDef__doc); - long getOffset = GraalHPyCAccess.ReadPointerNode.getElementPtr(context, i, HPyContextSignatureType.PyGetSetDef, GraalHPyCField.PyGetSetDef__get); - long setOffset = GraalHPyCAccess.ReadPointerNode.getElementPtr(context, i, HPyContextSignatureType.PyGetSetDef, GraalHPyCField.PyGetSetDef__set); - long closureOffset = GraalHPyCAccess.ReadPointerNode.getElementPtr(context, i, HPyContextSignatureType.PyGetSetDef, GraalHPyCField.PyGetSetDef__closure); - - // note: 'doc' may be NULL; in this case, we would store 'None' - Object getSetDescrDoc = PNone.NONE; - Object docPtr = readPointerNode.execute(context, legacyGetSetDef, docOffset); - if (!isNullNode.execute(context, docPtr)) { - getSetDescrDoc = fromCharPointerNode.execute(docPtr); - } - - Object getterFunPtr = readPointerNode.execute(context, legacyGetSetDef, getOffset); - Object setterFunPtr = readPointerNode.execute(context, legacyGetSetDef, setOffset); - /* - * Note: we need to convert the native closure pointer to an interop pointer because it - * will be handed to a C API root which expects that. - */ - Object closurePtr = context.nativeToInteropPointer(readPointerNode.execute(context, legacyGetSetDef, closureOffset)); - - PythonLanguage lang = context.getContext().getLanguage(inliningTarget); - PBuiltinFunction getterObject = null; - if (!isNullNode.execute(context, getterFunPtr)) { - Object getterFunInteropPtr = ensureExecutableNode.execute(inliningTarget, context.nativeToInteropPointer(getterFunPtr), PExternalFunctionWrapper.GETTER); - getterObject = HPyLegacyGetSetDescriptorGetterRoot.createLegacyFunction(context, lang, owner, getSetDescrName, getterFunInteropPtr, closurePtr); - } - - PBuiltinFunction setterObject = null; - boolean hasSetter = !isNullNode.execute(context, setterFunPtr); - if (hasSetter) { - Object setterFunInteropPtr = ensureExecutableNode.execute(inliningTarget, context.nativeToInteropPointer(setterFunPtr), PExternalFunctionWrapper.SETTER); - setterObject = HPyLegacyGetSetDescriptorSetterRoot.createLegacyFunction(context, lang, owner, getSetDescrName, setterFunInteropPtr, closurePtr); - } - - GetSetDescriptor getSetDescriptor = factory.createGetSetDescriptor(getterObject, setterObject, getSetDescrName, owner, hasSetter); - writeDocNode.execute(getSetDescriptor, SpecialAttributeNames.T___DOC__, getSetDescrDoc); - return getSetDescriptor; - } - } - - /** - * A simple helper class to return the property and its name separately. - */ - @ValueType - static final class HPyProperty { - final Object key; - final Object value; - - /** - * In a very few cases, a single definition can define several properties. For example, slot - * {@link HPySlot#HPY_SQ_ASS_ITEM} defines properties - * {@link com.oracle.graal.python.nodes.SpecialMethodNames#T___SETITEM__} and - * {@link com.oracle.graal.python.nodes.SpecialMethodNames#T___DELITEM__}. Therefore, we use - * this field to create a linked list of such related properties. - */ - final HPyProperty next; - - HPyProperty(Object key, Object value, HPyProperty next) { - assert key instanceof TruffleString || key instanceof HiddenAttr; - this.key = key; - this.value = value; - this.next = next; - } - - HPyProperty(TruffleString key, Object value) { - this(key, value, null); - } - - void write(Node inliningTarget, WritePropertyNode writePropertyNode, ReadPropertyNode readPropertyNode, Object enclosingType) { - for (HPyProperty prop = this; prop != null; prop = prop.next) { - /* - * Do not overwrite existing attributes. Reason: Different slots may map to the same - * magic method. For example: 'nb_add' and 'sq_concat' are both mapped to '__add__'. - * For now, we will always use the first mapping. However, that is not fully - * correct. CPython has a fixed order for slots defined by array 'static slotdef - * slotdefs[]' in 'typeobject.c'. They iterate over this array and check if the new - * type provides the slot. The first mapping will then be install. The problem is - * that we cannot easily do the same since we have two separate sets of slots: HPy - * slots and legacy slots. Right now, the HPy slots have precedence. - */ - if (!keyExists(inliningTarget, readPropertyNode, enclosingType, prop.key)) { - writePropertyNode.execute(inliningTarget, enclosingType, prop.key, prop.value); - } - } - } - - static boolean keyExists(Node inliningTarget, ReadPropertyNode readPropertyNode, Object enclosingType, Object key) { - return readPropertyNode.execute(inliningTarget, enclosingType, key) != PNone.NO_VALUE; - } - - static boolean keyExists(ReadAttributeFromObjectNode readAttributeFromObjectNode, Object enclosingType, TruffleString key) { - return readAttributeFromObjectNode.execute(enclosingType, key) != PNone.NO_VALUE; - } - - } - - @GenerateInline - @GenerateCached(false) - @GenerateUncached - abstract static class ReadPropertyNode extends Node { - abstract Object execute(Node inliningTarget, Object receiver, Object key); - - @Specialization - static Object doHiddenAttr(Node inliningTarget, PythonAbstractObject receiver, HiddenAttr key, - @Cached HiddenAttr.ReadNode readNode) { - return readNode.execute(inliningTarget, receiver, key, PNone.NO_VALUE); - } - - @Specialization - static Object doOther(Object receiver, TruffleString key, - @Cached(inline = false) ReadAttributeFromObjectNode readAttributeFromObjectNode) { - return readAttributeFromObjectNode.execute(receiver, key); - } - } - - @GenerateInline - @GenerateCached(false) - @GenerateUncached - abstract static class WritePropertyNode extends Node { - // key comes from HPyProperty#key which is either TruffleString or HiddenAttr - abstract void execute(Node inliningTarget, Object receiver, Object key, Object value); - - @Specialization - static void doHiddenAttr(Node inliningTarget, PythonAbstractObject receiver, HiddenAttr key, Object value, - @Cached HiddenAttr.WriteNode writeNode) { - writeNode.execute(inliningTarget, receiver, key, value); - } - - @Specialization - static void doString(Object receiver, TruffleString key, Object value, - @Cached(inline = false) WriteAttributeToObjectNode writeAttributeToObjectNode) { - writeAttributeToObjectNode.execute(receiver, key, value); - } - } - - /** - * A simple helper class to return the parsed data of an {@code HPySlot} structure. - * - *
    -     * typedef struct {
    -     *     HPySlot_Slot slot;     // The slot to fill
    -     *     void *impl;            // Function pointer to the implementation
    -     *     void *cpy_trampoline;  // Used by CPython to call impl
    -     * } HPySlot;
    -     * 
    - */ - @ValueType - record HPySlotData(HPySlot slot, Object impl) { - } - - @GenerateUncached - @GenerateInline(false) // footprint reduction 48 -> 29 - public abstract static class HPyCreateLegacyMemberNode extends PNodeWithContext { - - public abstract HPyProperty execute(GraalHPyContext context, Object enclosingType, Object memberDefArrPtr, int i); - - /** - *
    -         * typedef struct PyMemberDef {
    -         *     const char *name;
    -         *     int type;
    -         *     Py_ssize_t offset;
    -         *     int flags;
    -         *     const char *doc;
    -         * } PyMemberDef;
    -         * 
    - */ - @Specialization - static HPyProperty doIt(GraalHPyContext context, Object enclosingType, Object memberDefArrPtr, int i, - @Bind("this") Node inliningTarget, - @Cached(parameters = "context") GraalHPyCAccess.ReadPointerNode readPointerNode, - @Cached(parameters = "context") GraalHPyCAccess.IsNullNode isNullNode, - @Cached(parameters = "context") GraalHPyCAccess.ReadGenericNode readGenericNode, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached PythonObjectFactory factory, - @Cached WriteAttributeToPythonObjectNode writeDocNode) { - - // computes offsets like '&(memberDefArrPtr[i].name)' - int pyMemberDefSize = context.getCTypeSize(HPyContextSignatureType.PyMemberDef); - long nameOffset = ReadGenericNode.getElementPtr(context, i, pyMemberDefSize, GraalHPyCField.PyMemberDef__name); - long typeOffset = ReadGenericNode.getElementPtr(context, i, pyMemberDefSize, GraalHPyCField.PyMemberDef__type); - long offsetOffset = ReadGenericNode.getElementPtr(context, i, pyMemberDefSize, GraalHPyCField.PyMemberDef__offset); - long flagsOffset = ReadGenericNode.getElementPtr(context, i, pyMemberDefSize, GraalHPyCField.PyMemberDef__flags); - long docOffset = ReadGenericNode.getElementPtr(context, i, pyMemberDefSize, GraalHPyCField.PyMemberDef__doc); - - Object namePtr = readPointerNode.execute(context, memberDefArrPtr, nameOffset); - if (isNullNode.execute(context, namePtr)) { - return null; - } - - TruffleString name = fromCharPointerNode.execute(namePtr); - - // note: 'doc' may be NULL; in this case, we would store 'None' - Object memberDoc = PNone.NONE; - Object doc = readPointerNode.execute(context, memberDefArrPtr, docOffset); - if (!isNullNode.execute(context, doc)) { - memberDoc = fromCharPointerNode.execute(doc, false); - } - - int flags = readGenericNode.executeInt(context, memberDefArrPtr, flagsOffset, HPyContextSignatureType.Int); - int type = readGenericNode.executeInt(context, memberDefArrPtr, typeOffset, HPyContextSignatureType.Int); - int offset = readGenericNode.executeInt(context, memberDefArrPtr, offsetOffset, HPyContextSignatureType.Int); - - PythonLanguage language = context.getContext().getLanguage(inliningTarget); - PBuiltinFunction getterObject = HPyReadMemberNode.createBuiltinFunction(language, name, type, offset); - - Object setterObject = null; - if ((flags & GraalHPyLegacyDef.MEMBER_FLAG_READONLY) == 0) { - setterObject = HPyWriteMemberNode.createBuiltinFunction(language, name, type, offset); - } - - // create a property - GetSetDescriptor memberDescriptor = factory.createMemberDescriptor(getterObject, setterObject, name, enclosingType); - writeDocNode.execute(memberDescriptor, SpecialAttributeNames.T___DOC__, memberDoc); - return new HPyProperty(name, memberDescriptor); - } - } - - @GenerateUncached - @GenerateInline(false) // footprint reduction 52 -> 33 - public abstract static class HPyAddMemberNode extends PNodeWithContext { - - public abstract HPyProperty execute(GraalHPyContext context, PythonClass enclosingType, Object memberDef); - - /** - *
    -         * typedef struct {
    -         *     const char *name;
    -         *     HPyMember_FieldType type;
    -         *     HPy_ssize_t offset;
    -         *     int readonly;
    -         *     const char *doc;
    -         * } HPyMember;
    -         * 
    - */ - @Specialization - static HPyProperty doIt(GraalHPyContext context, PythonClass enclosingType, Object memberDef, - @Bind("this") Node inliningTarget, - @Cached(parameters = "context") GraalHPyCAccess.ReadPointerNode readPointerNode, - @Cached(parameters = "context") GraalHPyCAccess.IsNullNode isNullNode, - @Cached(parameters = "context") GraalHPyCAccess.ReadGenericNode readGenericNode, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached TruffleString.EqualNode equalNode, - @Cached PythonObjectFactory factory, - @Cached WriteAttributeToPythonObjectNode writeDocNode) { - - TruffleString name = fromCharPointerNode.execute(readPointerNode.read(context, memberDef, GraalHPyCField.HPyDef__member__name)); - - // note: 'doc' may be NULL; in this case, we would store 'None' - Object memberDoc = PNone.NONE; - Object doc = readPointerNode.read(context, memberDef, GraalHPyCField.HPyDef__member__doc); - if (!isNullNode.execute(context, doc)) { - memberDoc = fromCharPointerNode.execute(doc, false); - } - - int type = readGenericNode.readInt(context, memberDef, GraalHPyCField.HPyDef__member__type); - boolean readOnly = readGenericNode.readInt(context, memberDef, GraalHPyCField.HPyDef__member__readonly) != 0; - int offset = readGenericNode.readInt(context, memberDef, GraalHPyCField.HPyDef__member__offset); - - if (equalNode.execute(SpecialAttributeNames.T___VECTORCALLOFFSET__, name, TS_ENCODING)) { - enclosingType.setHPyVectorcallOffset(offset); - } - - PythonLanguage language = context.getContext().getLanguage(inliningTarget); - PBuiltinFunction getterObject = HPyReadMemberNode.createBuiltinFunction(language, name, type, offset); - - Object setterObject = null; - if (!readOnly) { - setterObject = HPyWriteMemberNode.createBuiltinFunction(language, name, type, offset); - } - - // create member descriptor - GetSetDescriptor memberDescriptor = factory.createMemberDescriptor(getterObject, setterObject, name, enclosingType); - writeDocNode.execute(memberDescriptor, SpecialAttributeNames.T___DOC__, memberDoc); - return new HPyProperty(name, memberDescriptor); - } - } - - /** - * Creates a get/set descriptor from an HPy get/set descriptor specification. - * - *
    -     * typedef struct {
    -     *     const char *name;
    -     *     void *getter_impl;            // Function pointer to the implementation
    -     *     void *setter_impl;            // Same; this may be NULL
    -     *     void *getter_cpy_trampoline;  // Used by CPython to call getter_impl
    -     *     void *setter_cpy_trampoline;  // Same; this may be NULL
    -     *     const char *doc;
    -     *     void *closure;
    -     * } HPyGetSet;
    -     * 
    - */ - @GenerateUncached - @GenerateInline(false) // footprint reduction 44 -> 25 - public abstract static class HPyCreateGetSetDescriptorNode extends PNodeWithContext { - - public abstract GetSetDescriptor execute(GraalHPyContext context, Object type, Object memberDef); - - @Specialization - static GetSetDescriptor doIt(GraalHPyContext context, Object type, Object memberDef, - @Cached(parameters = "context") GraalHPyCAccess.ReadPointerNode readPointerNode, - @Cached(parameters = "context") GraalHPyCAccess.IsNullNode isNullNode, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached HPyAttachFunctionTypeNode attachFunctionTypeNode, - @Cached PythonObjectFactory factory, - @Cached WriteAttributeToPythonObjectNode writeDocNode) { - - TruffleString name = fromCharPointerNode.execute(readPointerNode.read(context, memberDef, GraalHPyCField.HPyDef__getset__name)); - - // note: 'doc' may be NULL; in this case, we would store 'None' - Object memberDoc = PNone.NONE; - Object docCharPtr = readPointerNode.read(context, memberDef, GraalHPyCField.HPyDef__getset__doc); - if (!isNullNode.execute(context, docCharPtr)) { - memberDoc = fromCharPointerNode.execute(docCharPtr, false); - } - - Object closurePtr = readPointerNode.read(context, memberDef, GraalHPyCField.HPyDef__getset__closure); - - // signature: self, closure - Object getterFunctionPtr = readPointerNode.read(context, memberDef, GraalHPyCField.HPyDef__getset__getter_impl); - boolean hasGetter = !isNullNode.execute(context, getterFunctionPtr); - if (hasGetter) { - getterFunctionPtr = attachFunctionTypeNode.execute(context, getterFunctionPtr, LLVMType.HPyFunc_getter); - } - - // signature: self, value, closure - Object setterFunctionPtr = readPointerNode.read(context, memberDef, GraalHPyCField.HPyDef__getset__setter_impl); - boolean hasSetter = !isNullNode.execute(context, setterFunctionPtr); - if (hasSetter) { - setterFunctionPtr = attachFunctionTypeNode.execute(context, setterFunctionPtr, LLVMType.HPyFunc_setter); - } - - PBuiltinFunction getterObject; - if (hasGetter) { - getterObject = HPyGetSetDescriptorGetterRootNode.createFunction(context, type, name, getterFunctionPtr, closurePtr); - } else { - getterObject = null; - } - - PBuiltinFunction setterObject; - if (hasSetter) { - setterObject = HPyGetSetDescriptorSetterRootNode.createFunction(context, type, name, setterFunctionPtr, closurePtr); - } else { - setterObject = null; - } - - GetSetDescriptor getSetDescriptor = factory.createGetSetDescriptor(getterObject, setterObject, name, type, !hasSetter); - writeDocNode.execute(getSetDescriptor, SpecialAttributeNames.T___DOC__, memberDoc); - return getSetDescriptor; - } - } - - /** - * Parser an {@code HPySlot} structure, creates and adds the appropriate function as magic - * method. Returns either an HPyProperty if created, or the HPySlot itself. - * - *
    -     * typedef struct {
    -     *     HPySlot_Slot slot;     // The slot to fill
    -     *     void *impl;            // Function pointer to the implementation
    -     *     void *cpy_trampoline;  // Used by CPython to call impl
    -     * } HPySlot;
    -     * 
    - */ - @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class HPyReadSlotNode extends PNodeWithContext { - - public abstract HPySlotData execute(Node inliningTarget, GraalHPyContext context, Object slotDef); - - @Specialization - static HPySlotData doIt(Node inliningTarget, GraalHPyContext context, Object slotDef, - @Cached(parameters = "context", inline = false) GraalHPyCAccess.ReadGenericNode readGenericNode, - @Cached(parameters = "context", inline = false) GraalHPyCAccess.ReadPointerNode readPointerNode, - @Cached(inline = false) HPyAttachFunctionTypeNode attachFunctionTypeNode) { - - int slotNr = readGenericNode.readInt(context, slotDef, GraalHPyCField.HPyDef__slot__slot); - HPySlot slot = HPySlot.fromValue(slotNr); - if (slot == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.SystemError, ErrorMessages.INVALID_SLOT_VALUE, slotNr); - } - - // read and check the function pointer - Object methodFunctionPointer = readPointerNode.read(context, slotDef, GraalHPyCField.HPyDef__slot__impl); - methodFunctionPointer = attachFunctionTypeNode.execute(context, methodFunctionPointer, slot.getSignatures()[0].getLLVMFunctionType()); - return new HPySlotData(slot, methodFunctionPointer); - } - } - - @GenerateUncached - @GenerateInline(false) // footprint reduction 44 -> 25 - public abstract static class HPyCreateSlotNode extends PNodeWithContext { - - public abstract Object execute(GraalHPyContext context, PythonClass enclosingType, TpSlots.Builder tpSlotsBuilder, Object slotDef); - - @Specialization - static Object doIt(GraalHPyContext context, PythonClass enclosingType, TpSlots.Builder tpSlotsBuilder, Object slotDef, - @Bind("this") Node inliningTarget, - @Cached HPyReadSlotNode readSlotNode, - @Cached PythonObjectFactory factory, - @Cached TruffleString.FromJavaStringNode fromJavaStringNode, - @Cached PRaiseNode raiseNode) { - - assert enclosingType.isHPyType(); - HPySlotData slotData = readSlotNode.execute(inliningTarget, context, slotDef); - HPySlot slot = slotData.slot; - - TpSlotMeta tpSlot = slot.getTpSlot(); - if (tpSlot != null) { - // Slot that directly maps to a CPython compatible slot - Object boundExecutable = EnsureExecutableNode.executeUncached(slotData.impl(), tpSlot.getNativeSignature()); - tpSlotsBuilder.set(tpSlot, TpSlotNative.createHPySlot(boundExecutable)); - return null; - } - - HPyProperty property = null; - Object[] methodNames = slot.getAttributeKeys(); - HPySlotWrapper[] slotWrappers = slot.getSignatures(); - - /* - * Special case: DESTROYFUNC. This won't be usable from Python, so we just store the - * bare pointer object into Java field. - */ - if (HPY_TP_DESTROY.equals(slot)) { - enclosingType.setHPyDestroyFunc(slotData.impl()); - } else if (HPY_TP_TRAVERSE.equals(slot)) { - assert methodNames.length == 0; - return HPY_TP_TRAVERSE; - } else { - // create properties - for (int i = 0; i < methodNames.length; i++) { - Object methodName; - TruffleString methodNameStr; - if (methodNames[i] instanceof HiddenAttr ha) { - methodNameStr = fromJavaStringNode.execute(ha.getName(), TS_ENCODING); - methodName = methodNames[i]; - } else { - methodNameStr = (TruffleString) methodNames[i]; - methodName = methodNameStr; - } - HPySlotWrapper slotWrapper = slotWrappers[i]; - - Object enclosingTypeForFun = HPY_TP_NEW.equals(slot) ? null : enclosingType; - PythonLanguage language = context.getContext().getLanguage(inliningTarget); - Object function = HPyExternalFunctionNodes.createWrapperFunction(language, context, slotWrapper, null, null, methodNameStr, slotData.impl(), enclosingTypeForFun, factory); - property = new HPyProperty(methodName, function, property); - } - } - - /* - * Special case: HPy_tp_call. The installed attributed __call__ will be just a - * dispatcher. The actual function pointer given by the HPy definition is just the - * default call function that we need to remember and set on every freshly created - * instance of this type. - */ - if (HPY_TP_CALL.equals(slot)) { - if (enclosingType.getItemSize() > 0) { - throw raiseNode.raise(TypeError, ErrorMessages.HPY_CANNOT_USE_CALL_WITH_VAR_OBJECTS); - } - if (enclosingType.getBuiltinShape() == GraalHPyDef.HPyType_BUILTIN_SHAPE_LEGACY && enclosingType.getBasicSize() == 0) { - throw raiseNode.raise(TypeError, ErrorMessages.HPY_CANNOT_USE_CALL_WITH_LEGACY); - } - enclosingType.setHPyDefaultCallFunc(slotData.impl()); - } - return property; - } - } - - /** - * Parses a {@code PyType_Slot} structure - * - *
    -     * typedef struct{
    -     *     int slot;
    -     *     void *pfunc;
    -     * } PyType_Slot;
    -     * 
    - */ - @GenerateUncached - @GenerateInline(false) // footprint reduction 80 -> 61 - public abstract static class HPyCreateLegacySlotNode extends PNodeWithContext { - - public abstract boolean execute(GraalHPyContext context, Object enclosingType, TpSlots.Builder tpSlotsBuilder, Object slotDefArrPtr, int i); - - @Specialization - static boolean doIt(GraalHPyContext context, Object enclosingType, TpSlots.Builder tpSlotsBuilder, Object slotDefArrPtr, int i, - @Bind("this") Node inliningTarget, - @Cached(parameters = "context") GraalHPyCAccess.ReadGenericNode readGenericNode, - @Cached(parameters = "context") GraalHPyCAccess.ReadPointerNode readPointerNode, - @Cached CreateMethodNode legacyMethodNode, - @Cached HPyCreateLegacyMemberNode createLegacyMemberNode, - @Cached HPyAddLegacyGetSetDefNode legacyGetSetNode, - @Cached WriteAttributeToObjectNode writeAttributeToObjectNode, - @Cached ReadAttributeFromObjectNode readAttributeToObjectNode, - @Cached ReadPropertyNode readPropertyNode, - @Cached WritePropertyNode writePropertyNode, - @CachedLibrary(limit = "1") InteropLibrary lib, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - - // computes '&(slotDefArrPtr[i].slot)' - long slotIdOffset = ReadGenericNode.getElementPtr(context, i, context.getCTypeSize(HPyContextSignatureType.PyType_Slot), GraalHPyCField.PyType_Slot__slot); - int slotId = readGenericNode.executeInt(context, slotDefArrPtr, slotIdOffset, HPyContextSignatureType.Int); - if (slotId == 0) { - return false; - } - - HPyLegacySlot slot = HPyLegacySlot.fromValue(slotId); - if (slot == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.SystemError, ErrorMessages.INVALID_SLOT_VALUE, slotId); - } - - // computes '&(slotDefArrPtr[i].pfunc)' - long pfuncOffset = ReadGenericNode.getElementPtr(context, i, context.getCTypeSize(HPyContextSignatureType.PyType_Slot), GraalHPyCField.PyType_Slot__pfunc); - Object pfuncPtr = readPointerNode.execute(context, slotDefArrPtr, pfuncOffset); - - TpSlotMeta tpSlot = slot.getTpSlot(); - if (tpSlot != null) { - // Note: not a HPy native slot, just plain native slot, because it is legacy and - // expects PyObject* arguments - Object boundExecutable = EnsureExecutableNode.executeUncached(pfuncPtr, tpSlot.getNativeSignature()); - tpSlotsBuilder.set(tpSlot, TpSlotNative.createCExtSlot(boundExecutable)); - return true; - } - - // treatment for special slots 'Py_tp_members', 'Py_tp_getset', 'Py_tp_methods' - switch (slot) { - case Py_tp_members: - for (int j = 0;; j++) { - HPyProperty property = createLegacyMemberNode.execute(context, enclosingType, pfuncPtr, j); - if (property == null) { - break; - } - property.write(inliningTarget, writePropertyNode, readPropertyNode, enclosingType); - } - break; - case Py_tp_methods: - for (int j = 0;; j++) { - PBuiltinFunction method = legacyMethodNode.execute(inliningTarget, pfuncPtr, j); - if (method == null) { - break; - } - writeAttributeToObjectNode.execute(enclosingType, method.getName(), method); - } - break; - case Py_tp_getset: - for (int j = 0;; j++) { - GetSetDescriptor getSetDescriptor = legacyGetSetNode.execute(context, enclosingType, pfuncPtr, j); - if (getSetDescriptor == null) { - break; - } - writeAttributeToObjectNode.execute(enclosingType, getSetDescriptor.getName(), getSetDescriptor); - } - break; - default: - // this is the generic slot case - // TODO: when all CPython compatible slots are implemented, this should go away - TruffleString attributeKey = slot.getAttributeKey(); - if (attributeKey != null) { - if (!HPyProperty.keyExists(readAttributeToObjectNode, enclosingType, attributeKey)) { - Object interopPFuncPtr = context.nativeToInteropPointer(pfuncPtr); - PBuiltinFunction method; - Object resolved = CreateFunctionNode.resolveClosurePointerToBuiltinFun(context.getContext(), interopPFuncPtr, lib, enclosingType, attributeKey, - slot.getSignature()); - if (resolved instanceof PBuiltinFunction builtinFunction) { - method = builtinFunction; - } else { - Object callable; - if (resolved instanceof RootCallTarget || resolved instanceof BuiltinMethodDescriptor) { - callable = resolved; - } else { - assert resolved == null; - // the pointer is not a closure pointer, so we assume it is a - // native function pointer - callable = interopPFuncPtr; - } - PythonLanguage lang = context.getContext().getLanguage(inliningTarget); - method = PExternalFunctionWrapper.createWrapperFunction(attributeKey, callable, enclosingType, 0, slot.getSignature(), lang, factory, true); - } - writeAttributeToObjectNode.execute(enclosingType, attributeKey, method); - } else { - // TODO(fa): implement support for remaining legacy slot kinds - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw CompilerDirectives.shouldNotReachHere(PythonUtils.formatJString("support for legacy slot %s not yet implemented", slot.name())); - } - } - break; - } - return true; - } - } - - @GenerateUncached - @GenerateInline(false) - public abstract static class HPyAsContextNode extends CExtToJavaNode { - - @Specialization - static GraalHPyContext doHandle(GraalHPyNativeContext hpyContext) { - return hpyContext.context; - } - - /* - * n.b. we could actually accept anything else, but we have specializations to be more * - * strict about what we expect - */ - - @Specialization - GraalHPyContext doInt(@SuppressWarnings("unused") int handle) { - return getContext().getHPyContext(); - } - - @Specialization - GraalHPyContext doLong(@SuppressWarnings("unused") long handle) { - return getContext().getHPyContext(); - } - - @Specialization(guards = "interopLibrary.isPointer(handle)", limit = "2") - static GraalHPyContext doPointer(@SuppressWarnings("unused") Object handle, - @CachedLibrary("handle") InteropLibrary interopLibrary) { - return PythonContext.get(interopLibrary).getHPyContext(); - } - } - - @ImportStatic(GraalHPyBoxing.class) - public abstract static class HPyWithContextNode extends PNodeWithContext { - - static long asPointer(Object handle, InteropLibrary lib) { - try { - return lib.asPointer(handle); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - } - - @GenerateInline - @GenerateCached(false) - @GenerateUncached - @ImportStatic(GraalHPyBoxing.class) - public abstract static class HPyEnsureHandleNode extends HPyWithContextNode { - - public abstract GraalHPyHandle execute(Node inliningTarget, Object object); - - @Specialization - static GraalHPyHandle doHandle(GraalHPyHandle handle) { - return handle; - } - - @Specialization(guards = {"!isLong(value)", "!isHPyHandle(value)", "!isBoxedNullHandle(bits)", "isBoxedHandle(bits)"}) - static GraalHPyHandle doOtherBoxedHandle(Node inliningTarget, @SuppressWarnings("unused") Object value, - @Shared("lib") @CachedLibrary(limit = "2") @SuppressWarnings("unused") InteropLibrary lib, - @Bind("asPointer(value, lib)") long bits) { - return doLong(inliningTarget, bits); - } - - @Specialization(guards = {"!isLong(value)", "!isHPyHandle(value)", "isBoxedNullHandle(bits)"}) - @SuppressWarnings("unused") - static GraalHPyHandle doOtherNull(Object value, - @Shared("lib") @CachedLibrary(limit = "2") InteropLibrary lib, - @Bind("asPointer(value, lib)") long bits) { - return GraalHPyHandle.NULL_HANDLE; - } - - @Specialization(guards = {"!isLong(value)", "!isHPyHandle(value)", "isBoxedInt(bits) || isBoxedDouble(bits)"}) - static GraalHPyHandle doOtherBoxedPrimitive(Node inliningTarget, @SuppressWarnings("unused") Object value, - @Shared("lib") @CachedLibrary(limit = "2") @SuppressWarnings("unused") InteropLibrary lib, - @Bind("asPointer(value, lib)") long bits) { - return doBoxedPrimitive(inliningTarget, bits); - } - - @Specialization(guards = "isBoxedNullHandle(bits)") - @SuppressWarnings("unused") - static GraalHPyHandle doLongNull(long bits) { - return GraalHPyHandle.NULL_HANDLE; - } - - @Specialization(guards = {"isBoxedHandle(bits)"}, replaces = "doLongNull") - static GraalHPyHandle doLong(Node inliningTarget, long bits) { - GraalHPyContext context = PythonContext.get(inliningTarget).getHPyContext(); - return context.createHandle(context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(bits))); - } - - @Specialization(guards = "isBoxedInt(bits) || isBoxedDouble(bits)") - @SuppressWarnings("unused") - static GraalHPyHandle doBoxedPrimitive(Node inliningTarget, long bits) { - /* - * In this case, the long value is a boxed primitive and we cannot resolve it to a - * GraalHPyHandle instance (because no instance has ever been created). We create a - * fresh GaalHPyHandle instance here. - */ - Object delegate; - if (GraalHPyBoxing.isBoxedInt(bits)) { - delegate = GraalHPyBoxing.unboxInt(bits); - } else if (GraalHPyBoxing.isBoxedDouble(bits)) { - delegate = GraalHPyBoxing.unboxDouble(bits); - } else { - throw CompilerDirectives.shouldNotReachHere(); - } - return PythonContext.get(inliningTarget).getHPyContext().createHandle(delegate); - } - } - - @GenerateInline - @GenerateCached(false) - @GenerateUncached - @ImportStatic(GraalHPyBoxing.class) - public abstract static class HPyCloseHandleNode extends HPyWithContextNode { - - public abstract void execute(Node inliningTarget, Object object); - - public static void executeUncached(Object object) { - HPyCloseHandleNodeGen.getUncached().execute(null, object); - } - - @Specialization(guards = "!handle.isAllocated()") - @SuppressWarnings("unused") - static void doHandle(GraalHPyHandle handle) { - // nothing to do - } - - @Specialization(guards = "handle.isAllocated()") - static void doHandleAllocated(Node inliningTarget, GraalHPyHandle handle) { - handle.closeAndInvalidate(PythonContext.get(inliningTarget).getHPyContext()); - } - - @Specialization(guards = "isBoxedNullHandle(bits)") - @SuppressWarnings("unused") - static void doNullLong(long bits) { - // nothing to do - } - - @Specialization(guards = {"!isBoxedNullHandle(bits)", "isBoxedHandle(bits)"}) - static void doLong(Node inliningTarget, long bits) { - /* - * Since we have a long and it is in the "boxed handle" range, we know that the handle - * *MUST* be allocated. - */ - int id = GraalHPyBoxing.unboxHandle(bits); - assert GraalHPyHandle.isAllocated(id); - PythonContext.get(inliningTarget).getHPyContext().releaseHPyHandleForObject(id); - } - - @Specialization(guards = "!isBoxedHandle(bits)") - @SuppressWarnings("unused") - static void doLongDouble(long bits) { - // nothing to do - } - - @Specialization(guards = {"!isLong(value)", "!isHPyHandle(value)", "isBoxedNullHandle(bits)"}) - @SuppressWarnings("unused") - static void doNullOther(Object value, - @Shared("lib") @CachedLibrary(limit = "2") InteropLibrary lib, - @Bind("asPointer(value, lib)") long bits) { - // nothing to do - } - - @Specialization(guards = {"!isLong(value)", "!isHPyHandle(value)", "!isBoxedNullHandle(bits)", "isBoxedHandle(bits)"}) - static void doOther(Node inliningTarget, @SuppressWarnings("unused") Object value, - @Shared("lib") @CachedLibrary(limit = "2") @SuppressWarnings("unused") InteropLibrary lib, - @Bind("asPointer(value, lib)") long bits) { - doLong(inliningTarget, bits); - } - - @Specialization(guards = {"!isLong(value)", "!isHPyHandle(value)", "!isBoxedHandle(bits)"}) - @SuppressWarnings("unused") - static void doOtherDouble(Object value, - @Shared("lib") @CachedLibrary(limit = "2") InteropLibrary lib, - @Bind("asPointer(value, lib)") long bits) { - // nothing to do - } - } - - @GenerateInline - @GenerateCached(false) - @GenerateUncached - public abstract static class HPyCloseAndGetHandleNode extends HPyWithContextNode { - - public abstract Object execute(Node inliningTarget, Object object); - - public abstract Object execute(Node inliningTarget, long object); - - @Specialization(guards = "!handle.isAllocated()") - static Object doHandle(GraalHPyHandle handle) { - return handle.getDelegate(); - } - - @Specialization(guards = "handle.isAllocated()") - static Object doHandleAllocated(Node inliningTarget, GraalHPyHandle handle) { - handle.closeAndInvalidate(PythonContext.get(inliningTarget).getHPyContext()); - return handle.getDelegate(); - } - - @Specialization(guards = "isBoxedNullHandle(bits)") - @SuppressWarnings("unused") - static Object doNullLong(long bits) { - return GraalHPyHandle.NULL_HANDLE_DELEGATE; - } - - @Specialization(guards = {"!isBoxedNullHandle(bits)", "isBoxedHandle(bits)"}) - static Object doLong(Node inliningTarget, long bits) { - /* - * Since we have a long and it is in the "boxed handle" range, we know that the handle - * *MUST* be allocated. - */ - int id = GraalHPyBoxing.unboxHandle(bits); - assert GraalHPyHandle.isAllocated(id); - GraalHPyContext context = PythonContext.get(inliningTarget).getHPyContext(); - Object delegate = context.getObjectForHPyHandle(id); - context.releaseHPyHandleForObject(id); - return delegate; - } - - @Specialization(guards = "isBoxedDouble(bits)") - static double doLongDouble(long bits) { - return GraalHPyBoxing.unboxDouble(bits); - } - - @Specialization(guards = "isBoxedInt(bits)") - static int doLongInt(long bits) { - return GraalHPyBoxing.unboxInt(bits); - } - - static long asPointer(Object handle, InteropLibrary lib) { - try { - return lib.asPointer(handle); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @Specialization(guards = {"!isLong(value)", "!isHPyHandle(value)", "isBoxedNullHandle(bits)"}) - @SuppressWarnings("unused") - static Object doNullOther(Object value, - @Shared("lib") @CachedLibrary(limit = "2") InteropLibrary lib, - @Bind("asPointer(value, lib)") long bits) { - return GraalHPyHandle.NULL_HANDLE_DELEGATE; - } - - @Specialization(guards = {"!isLong(value)", "!isHPyHandle(value)", "!isBoxedNullHandle(bits)", "isBoxedHandle(bits)"}) - static Object doOther(Node inliningTarget, @SuppressWarnings("unused") Object value, - @Shared("lib") @CachedLibrary(limit = "2") @SuppressWarnings("unused") InteropLibrary lib, - @Bind("asPointer(value, lib)") long bits) { - return doLong(inliningTarget, bits); - } - - @Specialization(guards = {"!isLong(value)", "!isHPyHandle(value)", "isBoxedDouble(bits)"}) - static double doOtherDouble(@SuppressWarnings("unused") Object value, - @Shared("lib") @CachedLibrary(limit = "2") @SuppressWarnings("unused") InteropLibrary lib, - @Bind("asPointer(value, lib)") long bits) { - return GraalHPyBoxing.unboxDouble(bits); - } - - @Specialization(guards = {"!isLong(value)", "!isHPyHandle(value)", "isBoxedInt(bits)"}) - static int doOtherInt(@SuppressWarnings("unused") Object value, - @Shared("lib") @CachedLibrary(limit = "2") @SuppressWarnings("unused") InteropLibrary lib, - @Bind("asPointer(value, lib)") long bits) { - return GraalHPyBoxing.unboxInt(bits); - } - } - - @GenerateUncached - @GenerateInline(false) - @ImportStatic(GraalHPyBoxing.class) - public abstract static class HPyAsPythonObjectNode extends CExtToJavaNode { - - public abstract Object execute(long bits); - - @Specialization - static Object doHandle(GraalHPyHandle handle) { - return handle.getDelegate(); - } - - @Specialization(guards = "isBoxedNullHandle(bits)") - @SuppressWarnings("unused") - static Object doNullLong(long bits) { - return GraalHPyHandle.NULL_HANDLE_DELEGATE; - } - - @Specialization(guards = {"!isBoxedNullHandle(bits)", "isBoxedHandle(bits)"}) - Object doLong(long bits) { - return getContext().getHPyContext().getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(bits)); - } - - @Specialization(guards = "isBoxedDouble(bits)") - static double doLongDouble(long bits) { - return GraalHPyBoxing.unboxDouble(bits); - } - - @Specialization(guards = "isBoxedInt(bits)") - static int doLongInt(long bits) { - return GraalHPyBoxing.unboxInt(bits); - } - - static long asPointer(Object handle, InteropLibrary lib) { - try { - return lib.asPointer(handle); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @Specialization(guards = {"!isLong(value)", "!isHPyHandle(value)", "isBoxedNullHandle(bits)"}) - static Object doNullOther(@SuppressWarnings("unused") Object value, - @Shared("lib") @CachedLibrary(limit = "2") @SuppressWarnings("unused") InteropLibrary lib, - @Bind("asPointer(value, lib)") @SuppressWarnings("unused") long bits) { - return GraalHPyHandle.NULL_HANDLE_DELEGATE; - } - - @Specialization(guards = {"!isLong(value)", "!isHPyHandle(value)", "!isBoxedNullHandle(bits)", "isBoxedHandle(bits)"}) - Object doOther(@SuppressWarnings("unused") Object value, - @Shared("lib") @CachedLibrary(limit = "2") @SuppressWarnings("unused") InteropLibrary lib, - @Bind("asPointer(value, lib)") long bits) { - return getContext().getHPyContext().getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(bits)); - } - - @Specialization(guards = {"!isLong(value)", "!isHPyHandle(value)", "isBoxedDouble(bits)"}) - static double doOtherDouble(@SuppressWarnings("unused") Object value, - @Shared("lib") @CachedLibrary(limit = "2") @SuppressWarnings("unused") InteropLibrary lib, - @Bind("asPointer(value, lib)") long bits) { - return GraalHPyBoxing.unboxDouble(bits); - } - - @Specialization(guards = {"!isLong(value)", "!isHPyHandle(value)", "isBoxedInt(bits)"}) - static int doOtherInt(@SuppressWarnings("unused") Object value, - @Shared("lib") @CachedLibrary(limit = "2") @SuppressWarnings("unused") InteropLibrary lib, - @Bind("asPointer(value, lib)") long bits) { - return GraalHPyBoxing.unboxInt(bits); - } - - @Specialization(replaces = {"doHandle", // - "doNullLong", "doLong", "doLongDouble", "doLongInt", // - "doNullOther", "doOther", "doOtherDouble", "doOtherInt" // - }) - Object doGeneric(Object value, - @Shared("lib") @CachedLibrary(limit = "2") InteropLibrary lib) { - if (value instanceof GraalHPyHandle) { - return ((GraalHPyHandle) value).getDelegate(); - } - long bits; - if (value instanceof Long) { - bits = (Long) value; - } else { - lib.toNative(value); - try { - bits = lib.asPointer(value); - } catch (UnsupportedMessageException ex) { - throw CompilerDirectives.shouldNotReachHere(ex); - } - } - if (GraalHPyBoxing.isBoxedNullHandle(bits)) { - return GraalHPyHandle.NULL_HANDLE_DELEGATE; - } else if (GraalHPyBoxing.isBoxedInt(bits)) { - return GraalHPyBoxing.unboxInt(bits); - } else if (GraalHPyBoxing.isBoxedDouble(bits)) { - return GraalHPyBoxing.unboxDouble(bits); - } else { - assert GraalHPyBoxing.isBoxedHandle(bits); - return getContext().getHPyContext().getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(bits)); - } - } - } - - public static final class HPyDummyToJavaNode extends CExtToJavaNode { - private static final HPyDummyToJavaNode UNCACHED = new HPyDummyToJavaNode(); - - public static HPyDummyToJavaNode create() { - return new HPyDummyToJavaNode(); - } - - public static HPyDummyToJavaNode getUncached() { - return UNCACHED; - } - - @Override - public Object execute(Object object) { - return object; - } - - @Override - public boolean isAdoptable() { - return this != UNCACHED; - } - } - - @GenerateUncached - @GenerateInline(false) - @ImportStatic(PGuards.class) - public abstract static class HPyAsHandleNode extends CExtToNativeNode { - protected static final byte HANDLE = 0; - protected static final byte GLOBAL = 1; - protected static final byte FIELD = 2; - - @Override - public final GraalHPyHandle execute(Object object) { - return execute(object, 0, HANDLE); - } - - public final GraalHPyHandle executeGlobal(Object object, int id) { - return execute(object, id, GLOBAL); - } - - public final GraalHPyHandle executeField(Object object, int id) { - return execute(object, id, FIELD); - } - - protected abstract GraalHPyHandle execute(Object object, int id, int type); - - /* - * NOTE: We *MUST NOT* box values here because we don't know where the handle will be given - * to. In case we give it to LLVM code, we must still have an object that emulates the HPy - * struct. - */ - - @Specialization(guards = "isNoValue(object)") - @SuppressWarnings("unused") - static GraalHPyHandle doNoValue(PNone object, int id, int type) { - return GraalHPyHandle.NULL_HANDLE; - } - - @Specialization(guards = {"!isNoValue(object)", "type == HANDLE"}) - GraalHPyHandle doObject(Object object, @SuppressWarnings("unused") int id, @SuppressWarnings("unused") int type) { - return getContext().getHPyContext().createHandle(object); - } - - @Specialization(guards = {"!isNoValue(object)", "type == GLOBAL"}) - static GraalHPyHandle doGlobal(Object object, int id, @SuppressWarnings("unused") int type) { - return GraalHPyHandle.createGlobal(object, id); - } - - @Specialization(guards = {"!isNoValue(object)", "type == FIELD"}) - GraalHPyHandle doField(Object object, int id, @SuppressWarnings("unused") int type) { - return getContext().getHPyContext().createField(object, id); - } - } - - /** - * Converts a Python object to a native {@code int64_t} compatible value. - */ - @GenerateUncached - @GenerateInline(false) - public abstract static class HPyAsNativeInt64Node extends CExtToNativeNode { - - // Adding specializations for primitives does not make a lot of sense just to avoid - // un-/boxing in the interpreter since interop will force un-/boxing anyway. - @Specialization - static Object doGeneric(Object value, - @Bind("this") Node inliningTarget, - @Cached ConvertPIntToPrimitiveNode asNativePrimitiveNode) { - return asNativePrimitiveNode.execute(inliningTarget, value, 1, Long.BYTES); - } - } - - public abstract static class HPyConvertArgsToSulongNode extends PNodeWithContext { - - public abstract void executeInto(VirtualFrame frame, Object[] args, int argsOffset, Object[] dest, int destOffset); - - abstract HPyCloseArgHandlesNode createCloseHandleNode(); - } - - public abstract static class HPyCloseArgHandlesNode extends PNodeWithContext { - - public abstract void executeInto(VirtualFrame frame, Object[] args, int argsOffset); - } - - @GenerateInline(false) - public abstract static class HPyVarargsToSulongNode extends HPyConvertArgsToSulongNode { - - @Specialization - static void doConvert(Object[] args, int argsOffset, Object[] dest, int destOffset, - @Cached HPyAsHandleNode selfAsHandleNode) { - dest[destOffset] = selfAsHandleNode.execute(args[argsOffset]); - dest[destOffset + 1] = args[argsOffset + 1]; - dest[destOffset + 2] = args[argsOffset + 2]; - } - - @Override - HPyCloseArgHandlesNode createCloseHandleNode() { - return HPyVarargsHandleCloseNodeGen.create(); - } - } - - /** - * The counter part of {@link HPyVarargsToSulongNode}. - */ - @GenerateInline(false) - public abstract static class HPyVarargsHandleCloseNode extends HPyCloseArgHandlesNode { - - @Specialization - static void doConvert(Object[] dest, int destOffset, - @Bind("this") Node inliningTarget, - @Cached HPyCloseHandleNode closeHandleNode) { - closeHandleNode.execute(inliningTarget, dest[destOffset]); - } - } - - /** - * Always closes parameter at position {@code destOffset} (assuming that it is a handle). - */ - @GenerateInline(false) - public abstract static class HPySelfHandleCloseNode extends HPyCloseArgHandlesNode { - - @Specialization - static void doConvert(Object[] dest, int destOffset, - @Bind("this") Node inliningTarget, - @Cached HPyCloseHandleNode closeHandleNode) { - closeHandleNode.execute(inliningTarget, dest[destOffset]); - } - } - - @GenerateInline(false) - public abstract static class HPyKeywordsToSulongNode extends HPyConvertArgsToSulongNode { - - @Specialization - static void doConvert(Object[] args, int argsOffset, Object[] dest, int destOffset, - @Cached HPyAsHandleNode selfAsHandleNode, - @Cached HPyAsHandleNode kwAsHandleNode) { - dest[destOffset] = selfAsHandleNode.execute(args[argsOffset]); - dest[destOffset + 1] = args[argsOffset + 1]; - dest[destOffset + 2] = args[argsOffset + 2]; - dest[destOffset + 3] = kwAsHandleNode.execute(args[argsOffset + 3]); - } - - @Override - HPyCloseArgHandlesNode createCloseHandleNode() { - return HPyKeywordsHandleCloseNodeGen.create(); - } - } - - /** - * The counter part of {@link HPyKeywordsToSulongNode}. - */ - @GenerateInline(false) - public abstract static class HPyKeywordsHandleCloseNode extends HPyCloseArgHandlesNode { - - @Specialization - static void doConvert(Object[] dest, int destOffset, - @Bind("this") Node inliningTarget, - @Cached HPyCloseHandleNode closeFirstHandleNode, - @Cached HPyCloseHandleNode closeSecondHandleNode) { - closeFirstHandleNode.execute(inliningTarget, dest[destOffset]); - closeSecondHandleNode.execute(inliningTarget, dest[destOffset + 3]); - } - } - - @GenerateInline(false) - public abstract static class HPyAllAsHandleNode extends HPyConvertArgsToSulongNode { - - static boolean isArgsOffsetPlus(int len, int off, int plus) { - return len == off + plus; - } - - static boolean isLeArgsOffsetPlus(int len, int off, int plus) { - return len < plus + off; - } - - @Specialization(guards = {"args.length == argsOffset"}) - @SuppressWarnings("unused") - static void cached0(Object[] args, int argsOffset, Object[] dest, int destOffset) { - } - - @Specialization(guards = {"args.length == cachedLength", "isLeArgsOffsetPlus(cachedLength, argsOffset, 8)"}, limit = "1", replaces = "cached0") - @ExplodeLoop - static void cachedLoop(Object[] args, int argsOffset, Object[] dest, int destOffset, - @Cached("args.length") int cachedLength, - @Shared @Cached HPyAsHandleNode toSulongNode) { - CompilerAsserts.partialEvaluationConstant(destOffset); - for (int i = 0; i < cachedLength - argsOffset; i++) { - dest[destOffset + i] = toSulongNode.execute(args[argsOffset + i]); - } - } - - @Specialization(replaces = {"cached0", "cachedLoop"}) - static void uncached(Object[] args, int argsOffset, Object[] dest, int destOffset, - @Shared @Cached HPyAsHandleNode toSulongNode) { - int len = args.length; - for (int i = 0; i < len - argsOffset; i++) { - dest[destOffset + i] = toSulongNode.execute(args[argsOffset + i]); - } - } - - @Override - HPyCloseArgHandlesNode createCloseHandleNode() { - return HPyAllHandleCloseNodeGen.create(); - } - } - - /** - * The counter part of {@link HPyAllAsHandleNode}. - */ - @GenerateInline(false) - public abstract static class HPyAllHandleCloseNode extends HPyCloseArgHandlesNode { - - @Specialization(guards = {"dest.length == destOffset"}) - @SuppressWarnings("unused") - static void cached0(Object[] dest, int destOffset) { - } - - @Specialization(guards = {"dest.length == cachedLength", "isLeArgsOffsetPlus(cachedLength, destOffset, 8)"}, limit = "1", replaces = "cached0") - @ExplodeLoop - static void cachedLoop(Object[] dest, int destOffset, - @Bind("this") Node inliningTarget, - @Cached("dest.length") int cachedLength, - @Shared @Cached HPyCloseHandleNode closeHandleNode) { - CompilerAsserts.partialEvaluationConstant(destOffset); - for (int i = 0; i < cachedLength - destOffset; i++) { - closeHandleNode.execute(inliningTarget, dest[destOffset + i]); - } - } - - @Specialization(replaces = {"cached0", "cachedLoop"}) - static void uncached(Object[] dest, int destOffset, - @Bind("this") Node inliningTarget, - @Shared @Cached HPyCloseHandleNode closeHandleNode) { - int len = dest.length; - for (int i = 0; i < len - destOffset; i++) { - closeHandleNode.execute(inliningTarget, dest[destOffset + i]); - } - } - - static boolean isLeArgsOffsetPlus(int len, int off, int plus) { - return len < plus + off; - } - } - - /** - * Argument converter for calling a native get/set descriptor getter function. The native - * signature is: {@code HPy getter(HPyContext ctx, HPy self, void* closure)}. - */ - @GenerateInline(false) - public abstract static class HPyGetSetGetterToSulongNode extends HPyConvertArgsToSulongNode { - - @Specialization - static void doConvert(Object[] args, int argsOffset, Object[] dest, int destOffset, - @Cached HPyAsHandleNode selfAsHandleNode) { - dest[destOffset] = selfAsHandleNode.execute(args[argsOffset]); - dest[destOffset + 1] = args[argsOffset + 1]; - } - - @Override - HPyCloseArgHandlesNode createCloseHandleNode() { - return HPySelfHandleCloseNodeGen.create(); - } - } - - /** - * Argument converter for calling a native get/set descriptor setter function. The native - * signature is: {@code HPy setter(HPyContext ctx, HPy self, HPy value, void* closure)}. - */ - @GenerateInline(false) - public abstract static class HPyGetSetSetterToSulongNode extends HPyConvertArgsToSulongNode { - - @Specialization - static void doConvert(Object[] args, int argsOffset, Object[] dest, int destOffset, - @Cached HPyAsHandleNode asHandleNode) { - dest[destOffset] = asHandleNode.execute(args[argsOffset]); - dest[destOffset + 1] = asHandleNode.execute(args[argsOffset + 1]); - dest[destOffset + 2] = args[argsOffset + 2]; - } - - @Override - HPyCloseArgHandlesNode createCloseHandleNode() { - return HPyGetSetSetterHandleCloseNodeGen.create(); - } - } - - /** - * The counter part of {@link HPyGetSetSetterToSulongNode}. - */ - @GenerateInline(false) - public abstract static class HPyGetSetSetterHandleCloseNode extends HPyCloseArgHandlesNode { - - @Specialization - static void doConvert(Object[] dest, int destOffset, - @Bind("this") Node inliningTarget, - @Cached HPyCloseHandleNode closeFirstHandleNode, - @Cached HPyCloseHandleNode closeSecondHandleNode) { - closeFirstHandleNode.execute(inliningTarget, dest[destOffset]); - closeSecondHandleNode.execute(inliningTarget, dest[destOffset + 1]); - } - } - - /** - * Converts {@code self} to an HPy handle and any other argument to {@code HPy_ssize_t}. - */ - @GenerateInline(false) - public abstract static class HPySSizeArgFuncToSulongNode extends HPyConvertArgsToSulongNode { - - @Specialization(guards = {"isArity(args.length, argsOffset, 2)"}) - static void doHandleSsizeT(Object[] args, int argsOffset, Object[] dest, int destOffset, - @Bind("this") Node inliningTarget, - @Shared @Cached HPyAsHandleNode asHandleNode, - @Shared @Cached ConvertPIntToPrimitiveNode asSsizeTNode) { - CompilerAsserts.partialEvaluationConstant(argsOffset); - dest[destOffset] = asHandleNode.execute(args[argsOffset]); - dest[destOffset + 1] = asSsizeTNode.execute(inliningTarget, args[argsOffset + 1], 1, Long.BYTES); - } - - @Specialization(guards = {"isArity(args.length, argsOffset, 3)"}) - static void doHandleSsizeTSsizeT(Object[] args, int argsOffset, Object[] dest, int destOffset, - @Bind("this") Node inliningTarget, - @Shared @Cached HPyAsHandleNode asHandleNode, - @Shared @Cached ConvertPIntToPrimitiveNode asSsizeTNode) { - CompilerAsserts.partialEvaluationConstant(argsOffset); - dest[destOffset] = asHandleNode.execute(args[argsOffset]); - dest[destOffset + 1] = asSsizeTNode.execute(inliningTarget, args[argsOffset + 1], 1, Long.BYTES); - dest[destOffset + 2] = asSsizeTNode.execute(inliningTarget, args[argsOffset + 2], 1, Long.BYTES); - } - - @Specialization(replaces = {"doHandleSsizeT", "doHandleSsizeTSsizeT"}) - static void doGeneric(Object[] args, int argsOffset, Object[] dest, int destOffset, - @Bind("this") Node inliningTarget, - @Shared @Cached HPyAsHandleNode asHandleNode, - @Shared @Cached ConvertPIntToPrimitiveNode asSsizeTNode) { - dest[destOffset] = asHandleNode.execute(args[argsOffset]); - for (int i = 1; i < args.length - argsOffset; i++) { - dest[destOffset + i] = asSsizeTNode.execute(inliningTarget, args[argsOffset + i], 1, Long.BYTES); - } - } - - @Override - HPyCloseArgHandlesNode createCloseHandleNode() { - return HPySelfHandleCloseNodeGen.create(); - } - - static boolean isArity(int len, int off, int expected) { - return len - off == expected; - } - } - - /** - * Converts arguments for C function signature - * {@code int (*HPyFunc_ssizeobjargproc)(HPyContext ctx, HPy, HPy_ssize_t, HPy)}. - */ - @GenerateInline(false) - public abstract static class HPySSizeObjArgProcToSulongNode extends HPyConvertArgsToSulongNode { - - @Specialization - static void doConvert(Object[] args, int argsOffset, Object[] dest, int destOffset, - @Bind("this") Node inliningTarget, - @Cached HPyAsHandleNode asHandleNode, - @Cached ConvertPIntToPrimitiveNode asSsizeTNode) { - CompilerAsserts.partialEvaluationConstant(argsOffset); - dest[destOffset] = asHandleNode.execute(args[argsOffset]); - dest[destOffset + 1] = asSsizeTNode.execute(inliningTarget, args[argsOffset + 1], 1, Long.BYTES); - dest[destOffset + 2] = asHandleNode.execute(args[argsOffset + 2]); - } - - @Override - HPyCloseArgHandlesNode createCloseHandleNode() { - return HPySSizeObjArgProcCloseNodeGen.create(); - } - } - - /** - * Always closes handle parameter at position {@code destOffset} and also closes parameter at - * position {@code destOffset + 2} if it is not a {@code NULL} handle. - */ - @GenerateInline(false) - public abstract static class HPySSizeObjArgProcCloseNode extends HPyCloseArgHandlesNode { - - @Specialization - static void doConvert(Object[] dest, int destOffset, - @Bind("this") Node inliningTarget, - @Cached HPyCloseHandleNode closeFirstHandleNode, - @Cached HPyCloseHandleNode closeSecondHandleNode) { - closeFirstHandleNode.execute(inliningTarget, dest[destOffset]); - closeSecondHandleNode.execute(inliningTarget, dest[destOffset + 2]); - } - } - - /** - * Converts arguments for C function signature - * {@code HPy (*HPyFunc_richcmpfunc)(HPyContext ctx, HPy, HPy, HPy_RichCmpOp);}. - */ - @GenerateInline(false) - public abstract static class HPyRichcmpFuncArgsToSulongNode extends HPyConvertArgsToSulongNode { - - @Specialization - static void doConvert(Object[] args, int argsOffset, Object[] dest, int destOffset, - @Cached HPyAsHandleNode asHandleNode) { - CompilerAsserts.partialEvaluationConstant(argsOffset); - dest[destOffset] = asHandleNode.execute(args[argsOffset]); - dest[destOffset + 1] = asHandleNode.execute(args[argsOffset + 1]); - dest[destOffset + 2] = args[argsOffset + 2]; - } - - @Override - HPyCloseArgHandlesNode createCloseHandleNode() { - return HPyRichcmptFuncArgsCloseNodeGen.create(); - } - } - - /** - * Always closes handle parameter at positions {@code destOffset} and {@code destOffset + 1}. - */ - @GenerateInline(false) - public abstract static class HPyRichcmptFuncArgsCloseNode extends HPyCloseArgHandlesNode { - - @Specialization - static void doConvert(Object[] dest, int destOffset, - @Bind("this") Node inliningTarget, - @Cached HPyCloseHandleNode closeFirstHandleNode, - @Cached HPyCloseHandleNode closeSecondHandleNode) { - closeFirstHandleNode.execute(inliningTarget, dest[destOffset]); - closeSecondHandleNode.execute(inliningTarget, dest[destOffset + 1]); - } - } - - /** - * Converts for C function signature - * {@code int (*HPyFunc_getbufferproc)(HPyContext ctx, HPy self, HPy_buffer *buffer, int flags)} - * . - */ - @GenerateInline(false) - public abstract static class HPyGetBufferProcToSulongNode extends HPyConvertArgsToSulongNode { - - @Specialization - static void doConversion(Object[] args, int argsOffset, Object[] dest, int destOffset, - @Cached HPyAsHandleNode asHandleNode, - @Cached AsNativePrimitiveNode asIntNode) { - CompilerAsserts.partialEvaluationConstant(argsOffset); - dest[destOffset] = asHandleNode.execute(args[argsOffset]); - dest[destOffset + 1] = args[argsOffset + 1]; - dest[destOffset + 2] = asIntNode.execute(args[argsOffset + 2], 1, Integer.BYTES, true); - } - - @Override - HPyCloseArgHandlesNode createCloseHandleNode() { - return HPySelfHandleCloseNodeGen.create(); - } - } - - /** - * Converts for C function signature - * {@code void (*HPyFunc_releasebufferproc)(HPyContext ctx, HPy self, HPy_buffer *buffer)}. - */ - @GenerateInline(false) - public abstract static class HPyReleaseBufferProcToSulongNode extends HPyConvertArgsToSulongNode { - - @Specialization - static void doConversion(Object[] args, int argsOffset, Object[] dest, int destOffset, - @Cached HPyAsHandleNode asHandleNode) { - CompilerAsserts.partialEvaluationConstant(argsOffset); - dest[destOffset] = asHandleNode.execute(args[argsOffset]); - dest[destOffset + 1] = args[argsOffset + 1]; - } - - @Override - HPyCloseArgHandlesNode createCloseHandleNode() { - return HPySelfHandleCloseNodeGen.create(); - } - } - - @GenerateUncached - @GenerateInline - @GenerateCached(false) - abstract static class HPyLongFromLong extends Node { - public abstract Object execute(Node inliningTarget, int value, boolean signed); - - public abstract Object execute(Node inliningTarget, long value, boolean signed); - - public abstract Object execute(Node inliningTarget, Object value, boolean signed); - - @Specialization(guards = "signed") - static int doSignedInt(int n, @SuppressWarnings("unused") boolean signed) { - return n; - } - - @Specialization(guards = "!signed") - static long doUnsignedInt(int n, @SuppressWarnings("unused") boolean signed) { - if (n < 0) { - return n & 0xFFFFFFFFL; - } - return n; - } - - @Specialization(guards = "signed") - static long doSignedLong(long n, @SuppressWarnings("unused") boolean signed) { - return n; - } - - @Specialization(guards = {"!signed", "n >= 0"}) - static long doUnsignedLongPositive(long n, @SuppressWarnings("unused") boolean signed) { - return n; - } - - @Specialization(guards = {"!signed", "n < 0"}) - static Object doUnsignedLongNegative(long n, @SuppressWarnings("unused") boolean signed, - @Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { - return factory.createInt(convertToBigInteger(n)); - } - - @TruffleBoundary - private static BigInteger convertToBigInteger(long n) { - return BigInteger.valueOf(n).add(BigInteger.ONE.shiftLeft(Long.SIZE)); - } - - @Specialization - static Object doPointer(PythonNativeObject n, @SuppressWarnings("unused") boolean signed, - @Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { - return factory.createNativeVoidPtr(n.getPtr()); - } - } - - /** - * Represents {@code HPyType_SpecParam}. - */ - @ValueType - record HPyTypeSpecParam(int kind, Object object) { - }; - - /** - *
    -     *     typedef struct {
    -     *         const char* name;
    -     *         int basicsize;
    -     *         int itemsize;
    -     *         unsigned int flags;
    -     *         int legacy;
    -     *         void *legacy_slots;
    -     *         HPyDef **defines;
    -     *         const char *doc;
    -     *     } HPyType_Spec;
    -     * 
    - */ - @ImportStatic(SpecialMethodSlot.class) - @GenerateUncached - @GenerateInline(false) // footprint reduction 196 -> 180 - abstract static class HPyCreateTypeFromSpecNode extends Node { - - private static final TruffleLogger LOGGER = GraalHPyContext.getLogger(HPyCreateTypeFromSpecNode.class); - static final TruffleString T_PYTRUFFLE_CREATETYPE = tsLiteral("PyTruffle_CreateType"); - - abstract Object execute(GraalHPyContext context, Object typeSpec, Object typeSpecParamArray); - - @Specialization - static Object doGeneric(GraalHPyContext context, Object typeSpec, Object typeSpecParamArray, - @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") DynamicObjectLibrary dylib, - @Cached(parameters = "context") GraalHPyCAccess.ReadPointerNode readPointerNode, - @Cached(parameters = "context") GraalHPyCAccess.AllocateNode allocateNode, - @Cached(parameters = "context") GraalHPyCAccess.ReadI32Node readI32Node, - @Cached(parameters = "context") GraalHPyCAccess.IsNullNode isNullNode, - @Cached(parameters = "context") HPyAsCharPointerNode asCharPointerNode, - @Cached HPyTypeSplitNameNode splitName, - @Cached FromCharPointerNode fromCharPointerNode, - @Cached PythonObjectFactory factory, - @Cached IsTypeNode isTypeNode, - @Cached HasSameConstructorNode hasSameConstructorNode, - @Cached CStructAccess.ReadI64Node getMetaSizeNode, - @Cached WriteAttributeToObjectNode writeAttributeToObjectNode, - @Cached ReadPropertyNode readPropertyNode, - @Cached WritePropertyNode writePropertyNode, - @Cached PyObjectCallMethodObjArgs callCreateTypeNode, - @Cached HPyCreateFunctionNode addFunctionNode, - @Cached HPyAddMemberNode addMemberNode, - @Cached HPyCreateSlotNode addSlotNode, - @Cached HPyCreateLegacySlotNode createLegacySlotNode, - @Cached HPyCreateGetSetDescriptorNode createGetSetDescriptorNode, - @Cached GetBaseClassNode getBaseClassNode, - @Cached(parameters = "New") LookupCallableSlotInMRONode lookupNewNode, - @Cached PRaiseNode raiseNode) { - - try { - // the name as given by the specification - TruffleString specName = fromCharPointerNode.execute(readPointerNode.read(context, typeSpec, GraalHPyCField.HPyType_Spec__name), false); - - // extract module and type name - TruffleString[] names = splitName.execute(inliningTarget, specName); - assert names.length == 2; - - Object tpName = asCharPointerNode.execute(context, names[1], Encoding.UTF_8); - - PDict namespace; - Object doc = readPointerNode.read(context, typeSpec, GraalHPyCField.HPyType_Spec__doc); - if (!isNullNode.execute(context, doc)) { - TruffleString docString = fromCharPointerNode.execute(doc); - namespace = factory.createDict(new PKeyword[]{new PKeyword(SpecialAttributeNames.T___DOC__, docString)}); - } else { - namespace = factory.createDict(); - } - - HPyTypeSpecParam[] typeSpecParams = extractTypeSpecParams(context, typeSpecParamArray); - - // extract bases from type spec params - PTuple bases = extractBases(typeSpecParams, factory); - // extract metaclass from type spec params - Object metatype = getMetatype(typeSpecParams, raiseNode); - - if (metatype != null) { - if (!isTypeNode.execute(inliningTarget, metatype)) { - throw raiseNode.raise(TypeError, ErrorMessages.HPY_METACLASS_IS_NOT_A_TYPE, metatype); - } - if (!hasSameConstructorNode.execute(inliningTarget, metatype, PythonBuiltinClassType.PythonClass)) { - throw raiseNode.raise(TypeError, ErrorMessages.HPY_METACLASS_WITH_CUSTOM_CONS_NOT_SUPPORTED); - } - } - - // create the type object - PythonModule pythonCextModule = PythonContext.get(inliningTarget).lookupBuiltinModule(BuiltinNames.T___GRAALPYTHON__); - PythonClass newType = (PythonClass) callCreateTypeNode.execute(null, inliningTarget, pythonCextModule, T_PYTRUFFLE_CREATETYPE, - names[1], bases, namespace, metatype != null ? metatype : PythonBuiltinClassType.PythonClass); - // allocate additional memory for the metatype and set it - long metaBasicSize = 0; - Object destroyFunc = null; - if (metatype instanceof PythonClass metaclass) { - // get basicsize of metatype and allocate it into - // GraalHPyDef.OBJECT_HPY_NATIVE_SPACE - metaBasicSize = metaclass.getBasicSize(); - destroyFunc = metaclass.getHPyDestroyFunc(); - } else if (metatype instanceof PythonAbstractNativeObject nativeObject) { - // This path is implemented only for completeness, - // but is not expected to happen often, hence the - // uncached nodes, no profiling and potential leak - metaBasicSize = getMetaSizeNode.readFromObj(nativeObject, PyTypeObject__tp_basicsize); - } - if (metaBasicSize > 0) { - Object dataPtr = allocateNode.calloc(context, 1, metaBasicSize); - GraalHPyData.setHPyNativeSpace(newType, dataPtr); - if (destroyFunc != null) { - context.createHandleReference(newType, dataPtr, destroyFunc != PNone.NO_VALUE ? destroyFunc : null); - } - } - - // determine and set the correct module attribute - TruffleString value = names[0]; - if (value != null) { - writeAttributeToObjectNode.execute(newType, SpecialAttributeNames.T___MODULE__, value); - } else { - // TODO(fa): issue deprecation warning with message "builtin type %.200s has no - // __module__ attribute" - } - - // store flags, basicsize, and itemsize to type - long flags = readI32Node.readUnsigned(context, typeSpec, GraalHPyCField.HPyType_Spec__flags); - int builtinShape = readI32Node.read(context, typeSpec, GraalHPyCField.HPyType_Spec__builtin_shape); - if (!GraalHPyDef.isValidBuiltinShape(builtinShape)) { - throw raiseNode.raise(ValueError, ErrorMessages.HPY_INVALID_BUILTIN_SHAPE, builtinShape); - } - - long basicSize = readI32Node.read(context, typeSpec, GraalHPyCField.HPyType_Spec__basicsize); - long itemSize = readI32Node.read(context, typeSpec, GraalHPyCField.HPyType_Spec__itemsize); - newType.setHPyTypeExtra(new HPyTypeExtra(flags, basicSize, itemSize, tpName, builtinShape)); - newType.makeStaticBase(dylib); - - boolean seenNew = false; - boolean needsTpTraverse = ((flags & GraalHPyDef.HPy_TPFLAGS_HAVE_GC) != 0); - // The builder will collect both the HPy and legacy slots - Builder tpSlotsBuilder = TpSlots.newBuilder(); - - // process defines - Object defines = readPointerNode.read(context, typeSpec, GraalHPyCField.HPyType_Spec__defines); - // field 'defines' may be 'NULL' - if (!isNullNode.execute(context, defines)) { - for (long i = 0;; i++) { - Object def = readPointerNode.readArrayElement(context, defines, i); - if (isNullNode.execute(context, def)) { - break; - } - HPyProperty property = null; - int kind = readI32Node.read(context, def, GraalHPyCField.HPyDef__kind); - switch (kind) { - case GraalHPyDef.HPY_DEF_KIND_METH: - PBuiltinFunction fun = addFunctionNode.execute(context, newType, def); - property = new HPyProperty(fun.getName(), fun); - break; - case GraalHPyDef.HPY_DEF_KIND_SLOT: - Object addSlotResult = addSlotNode.execute(context, newType, tpSlotsBuilder, def); - if (HPY_TP_TRAVERSE.equals(addSlotResult)) { - needsTpTraverse = false; - } else if (addSlotResult instanceof HPyProperty) { - property = (HPyProperty) addSlotResult; - } - if (property != null && SpecialMethodNames.T___NEW__.equals(property.key)) { - seenNew = true; - } - break; - case GraalHPyDef.HPY_DEF_KIND_MEMBER: - property = addMemberNode.execute(context, newType, def); - break; - case GraalHPyDef.HPY_DEF_KIND_GETSET: - GetSetDescriptor getSetDescriptor = createGetSetDescriptorNode.execute(context, newType, def); - property = new HPyProperty(getSetDescriptor.getName(), getSetDescriptor); - break; - default: - if (LOGGER.isLoggable(Level.SEVERE)) { - LOGGER.severe(PythonUtils.formatJString("unknown definition kind: %d", kind)); - } - assert false; - } - - if (property != null) { - property.write(inliningTarget, writePropertyNode, readPropertyNode, newType); - } - } - } - - /* - * Enforce constraint that we cannot have slot 'HPy_tp_call' and an explicit member - * '__vectorcalloffset__'. - */ - if (newType.getHPyVectorcallOffset() != Long.MIN_VALUE && newType.getHPyDefaultCallFunc() != null) { - throw raiseNode.raise(TypeError, ErrorMessages.HPY_CANNOT_HAVE_CALL_AND_VECTORCALLOFFSET); - } - - if (needsTpTraverse) { - throw raiseNode.raise(ValueError, ErrorMessages.TRAVERSE_FUNCTION_NEEDED); - } - - // process legacy slots; this is of type 'cpy_PyTypeSlot legacy_slots[]' - Object legacySlotsArrPtr = readPointerNode.read(context, typeSpec, GraalHPyCField.HPyType_Spec__legacy_slots); - if (!isNullNode.execute(context, legacySlotsArrPtr)) { - if (builtinShape != GraalHPyDef.HPyType_BUILTIN_SHAPE_LEGACY) { - throw raiseNode.raise(TypeError, ErrorMessages.HPY_CANNOT_SPECIFY_LEG_SLOTS_WO_SETTING_LEG); - } - for (int i = 0;; i++) { - if (!createLegacySlotNode.execute(context, newType, tpSlotsBuilder, legacySlotsArrPtr, i)) { - break; - } - } - } - - // These are the slots for the type we are creating as specified by the user: - TpSlots newSlots = tpSlotsBuilder.build(); - // Slots inheritance: - newType.setTpSlots(newType.getTpSlots().copy().overrideIgnoreGroups(newSlots).build()); - // Create descriptors wrapping the slots, but only the new slots: - newSlots.addOperators(newType); - TpSlots.fixupSlotDispatchers(newType); - - /* - * If 'basicsize > 0' and no explicit constructor is given, the constructor of the - * object needs to allocate the native space for the object. However, the inherited - * constructors won't do that. Also, if the default call function needs to be set - * (i.e. 'HPy_tp_call' was defined), an inherited constructor won't do it. - * - * The built-in shape determines the "native" shape of the object which means that - * it determines which Java object we need to allocate (e.g. PInt, PythonObject, - * PFloat, etc.). - */ - Object baseClass = getBaseClassNode.execute(inliningTarget, newType); - if (!seenNew && (basicSize > 0 || newType.getHPyDefaultCallFunc() != null)) { - - /* - * TODO(fa): we could do some shortcut if 'baseClass == PythonObject' and use - * 'inheritedConstruct = null' but that needs to be considered in the decorating - * new as well - */ - // Lookup the inherited constructor and pass it to the HPy decorator. - Object inheritedConstructor = lookupNewNode.execute(baseClass); - PythonLanguage language = context.getContext().getLanguage(inliningTarget); - PBuiltinFunction constructorDecorator = HPyObjectNewNode.createBuiltinFunction(language, inheritedConstructor, builtinShape); - writeAttributeToObjectNode.execute(newType, SpecialMethodNames.T___NEW__, constructorDecorator); - } - - long baseFlags; - if (baseClass instanceof PythonClass pythonBaseClass) { - baseFlags = pythonBaseClass.getFlags(); - } else { - baseFlags = 0; - } - int baseBuiltinShape = GraalHPyDef.getBuiltinShapeFromHiddenAttribute(baseClass); - checkInheritanceConstraints(flags, baseFlags, builtinShape, baseBuiltinShape > GraalHPyDef.HPyType_BUILTIN_SHAPE_LEGACY, raiseNode); - return newType; - } catch (CannotCastException e) { - throw raiseNode.raise(SystemError, ErrorMessages.COULD_NOT_CREATE_TYPE_FROM_SPEC_BECAUSE, e); - } - } - - /** - * Read the array of {@code HPyType_SpecParam} and convert to a Java array of - * {@link HPyTypeSpecParam}. - * - *
    -         *     typedef struct {
    -         *         HPyType_SpecParam_Kind kind;
    -         *         HPy object;
    -         *     } HPyType_SpecParam;
    -         * 
    - */ - @TruffleBoundary - private static HPyTypeSpecParam[] extractTypeSpecParams(GraalHPyContext context, Object typeSpecParamArray) { - - // if the pointer is NULL, no bases have been explicitly specified - if (GraalHPyCAccess.IsNullNode.executeUncached(context, typeSpecParamArray)) { - return null; - } - - GraalHPyCAccess.ReadI32Node readI32Node = GraalHPyCAccess.ReadI32Node.getUncached(context); - GraalHPyCAccess.ReadHPyNode readHPyNode = GraalHPyCAccess.ReadHPyNode.getUncached(context); - - long specParamSize = context.getCTypeSize(HPyContextSignatureType.HPyType_SpecParam); - - List specParams = new LinkedList<>(); - for (int i = 0;; i++) { - long specParamKindOffset = ReadHPyNode.getElementPtr(context, i, specParamSize, GraalHPyCField.HPyType_SpecParam__kind); - int specParamKind = readI32Node.readOffset(context, typeSpecParamArray, specParamKindOffset); - if (specParamKind == 0) { - break; - } - long specParamObjectOffset = ReadHPyNode.getElementPtr(context, i, specParamSize, GraalHPyCField.HPyType_SpecParam__object); - Object specParamObject = readHPyNode.read(context, typeSpecParamArray, specParamObjectOffset); - - specParams.add(new HPyTypeSpecParam(specParamKind, specParamObject)); - } - return specParams.toArray(new HPyTypeSpecParam[0]); - } - - /** - * Extract bases from the array of type spec params. Reference implementation can be found - * in {@code ctx_type.c:build_bases_from_params}. - * - * @return The bases tuple or {@code null} in case of an error. - */ - @TruffleBoundary - private static PTuple extractBases(HPyTypeSpecParam[] typeSpecParams, PythonObjectFactory factory) { - - // if there are no type spec params, no bases have been explicitly specified - if (typeSpecParams == null) { - return factory.createEmptyTuple(); - } - - ArrayList basesList = new ArrayList<>(); - for (HPyTypeSpecParam typeSpecParam : typeSpecParams) { - switch (typeSpecParam.kind()) { - case GraalHPyDef.HPyType_SPEC_PARAM_BASE: - // In this case, the 'specParamObject' is a single handle. We add it to - // the list of bases. - assert PGuards.isClassUncached(typeSpecParam.object()) : "base object is not a Python class"; - basesList.add(typeSpecParam.object()); - break; - case GraalHPyDef.HPyType_SPEC_PARAM_BASES_TUPLE: - // In this case, the 'specParamObject' is tuple. According to the - // reference implementation, we immediately use this tuple and throw - // away any other single base classes or subsequent params. - assert PGuards.isPTuple(typeSpecParam.object()) : "type spec param claims to be a tuple but isn't"; - return (PTuple) typeSpecParam.object(); - case GraalHPyDef.HPyType_SPEC_PARAM_METACLASS: - // intentionally ignored - break; - default: - assert false : "unknown type spec param kind"; - } - } - return factory.createTuple(basesList.toArray()); - } - - /** - * Reference implementation can be found in {@code ctx_type.c:get_metatype} - */ - @TruffleBoundary - private static Object getMetatype(HPyTypeSpecParam[] typeSpecParams, PRaiseNode raiseNode) { - Object result = null; - if (typeSpecParams != null) { - for (HPyTypeSpecParam typeSpecParam : typeSpecParams) { - if (typeSpecParam.kind() == GraalHPyDef.HPyType_SPEC_PARAM_METACLASS) { - if (result != null) { - throw raiseNode.raise(ValueError, ErrorMessages.HPY_METACLASS_SPECIFIED_MULTIPLE_TIMES); - } - result = typeSpecParam.object(); - if (!IsTypeNode.executeUncached(result)) { - throw raiseNode.raise(TypeError, ErrorMessages.HPY_METACLASS_IS_NOT_A_TYPE, result); - } - } - } - } - return result; - } - - private static void checkInheritanceConstraints(long flags, long baseFlags, int builtinShape, boolean baseIsPure, PRaiseNode raiseNode) { - // Pure types may inherit from: - // - // * pure types, or - // * PyBaseObject_Type, or - // * other builtin or legacy types as long as as they do not - // access the struct layout (e.g. by using HPy_AsStruct or defining - // a deallocator with HPy_tp_destroy). - // - // It would be nice to relax these restrictions or check them here. - // See https://github.com/hpyproject/hpy/issues/169 for details. - assert GraalHPyDef.isValidBuiltinShape(builtinShape); - if (builtinShape == GraalHPyDef.HPyType_BUILTIN_SHAPE_LEGACY && baseIsPure) { - throw raiseNode.raise(TypeError, ErrorMessages.LEG_TYPE_SHOULDNT_INHERIT_MEM_LAYOUT_FROM_PURE_TYPE); - } - } - } - - /** - * Extract the heap type's and the module's name from the name given by the type - * specification.
    - * According to CPython, we need to look for the last {@code '.'} and everything before it - * (which may also contain more dots) is the module name. Everything after it is the type name. - * See also: {@code typeobject.c: PyType_FromSpecWithBases} - */ - @GenerateUncached - @GenerateInline - @GenerateCached(false) - abstract static class HPyTypeSplitNameNode extends Node { - - public abstract TruffleString[] execute(Node inliningTarget, TruffleString tpName); - - @Specialization - static TruffleString[] doGeneric(TruffleString specNameUtf8, - @Cached(inline = false) TruffleString.SwitchEncodingNode switchEncodingNode, - @Cached(inline = false) TruffleString.LastIndexOfCodePointNode indexOfCodepointNode, - @Cached(inline = false) TruffleString.SubstringNode substringNode, - @Cached(inline = false) TruffleString.CodePointLengthNode lengthNode) { - TruffleString specName = switchEncodingNode.execute(specNameUtf8, TS_ENCODING); - int length = lengthNode.execute(specName, TS_ENCODING); - int firstDotIdx = indexOfCodepointNode.execute(specName, '.', length, 0, TS_ENCODING); - if (firstDotIdx > -1) { - TruffleString left = substringNode.execute(specName, 0, firstDotIdx, TS_ENCODING, false); - TruffleString right = substringNode.execute(specName, firstDotIdx + 1, length - firstDotIdx - 1, TS_ENCODING, false); - return new TruffleString[]{left, right}; - } - return new TruffleString[]{null, specName}; - } - } - - @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class HPyTypeGetNameNode extends Node { - - public static Object executeUncached(GraalHPyContext ctx, Object object) { - return HPyTypeGetNameNodeGen.getUncached().execute(null, ctx, object); - } - - public abstract Object execute(Node inliningTarget, GraalHPyContext ctx, Object object); - - @Specialization(guards = "tpName != null") - static Object doTpName(@SuppressWarnings("unused") GraalHPyContext ctx, @SuppressWarnings("unused") PythonClass clazz, - @Bind("clazz.getTpName()") Object tpName) { - return tpName; - } - - @Specialization(replaces = "doTpName") - static Object doGeneric(Node inliningTarget, GraalHPyContext ctx, Object type, - @Cached GetNameNode getName, - @Cached(parameters = "ctx", inline = false) HPyAsCharPointerNode asCharPointerNode) { - if (type instanceof PythonClass pythonClass && pythonClass.getTpName() != null) { - return pythonClass.getTpName(); - } - TruffleString baseName = getName.execute(inliningTarget, type); - return asCharPointerNode.execute(ctx, baseName, Encoding.UTF_8); - } - } - - @GenerateInline(inlineByDefault = true) - @GenerateCached - @GenerateUncached - @ImportStatic(PGuards.class) - public abstract static class HPyGetNativeSpacePointerNode extends Node { - - public abstract Object execute(Node inliningTarget, Object object); - - public final Object executeCached(Object object) { - return execute(this, object); - } - - public static Object executeUncached(Object object) { - return HPyGetNativeSpacePointerNodeGen.getUncached().execute(null, object); - } - - @Specialization - static Object doPythonObject(PythonObject object) { - return GraalHPyData.getHPyNativeSpace(object); - } - - @Fallback - static Object doOther(Node inliningTarget, @SuppressWarnings("unused") Object object) { - // TODO(fa): this should be a backend-specific value - return PythonContext.get(inliningTarget).getNativeNull(); - } - } - - public abstract static class HPyAttachFunctionTypeNode extends PNodeWithContext { - public abstract Object execute(GraalHPyContext hpyContext, Object pointerObject, LLVMType llvmFunctionType); - - @NeverDefault - public static HPyAttachFunctionTypeNode create() { - PythonLanguage language = PythonLanguage.get(null); - switch (language.getEngineOption(PythonOptions.HPyBackend)) { - case JNI: - if (!PythonImageBuildOptions.WITHOUT_JNI) { - return HPyAttachJNIFunctionTypeNodeGen.create(); - } - throw CompilerDirectives.shouldNotReachHere(); - case LLVM: - return HPyLLVMAttachFunctionTypeNode.UNCACHED; - case NFI: - return HPyAttachNFIFunctionTypeNodeGen.create(); - } - throw CompilerDirectives.shouldNotReachHere(); - } - - public static HPyAttachFunctionTypeNode getUncached() { - PythonLanguage language = PythonLanguage.get(null); - switch (language.getEngineOption(PythonOptions.HPyBackend)) { - case JNI: - if (!PythonImageBuildOptions.WITHOUT_JNI) { - return HPyAttachJNIFunctionTypeNodeGen.getUncached(); - } - throw CompilerDirectives.shouldNotReachHere(); - case LLVM: - return HPyLLVMAttachFunctionTypeNode.UNCACHED; - case NFI: - return HPyAttachNFIFunctionTypeNodeGen.getUncached(); - } - throw CompilerDirectives.shouldNotReachHere(); - } - } - - /** - * This node can be used to attach a function type to a function pointer if the function pointer - * is not executable, i.e., if - * {@code InteropLibrary.getUncached().isExecutable(functionPointer) == false}. This should not - * be necessary if running bitcode because Sulong should then know if a pointer is a function - * pointer but it might be necessary if a library was loaded with NFI since no bitcode is - * available. The node will return a typed function pointer that is then executable. - */ - @GenerateUncached - @GenerateInline(false) - public abstract static class HPyAttachNFIFunctionTypeNode extends HPyAttachFunctionTypeNode { - private static final String J_NFI_LANGUAGE = "nfi"; - - @Specialization(guards = {"isSingleContext()", "llvmFunctionType == cachedType"}, limit = "3") - static Object doCachedSingleContext(@SuppressWarnings("unused") GraalHPyContext hpyContext, Object pointerObject, @SuppressWarnings("unused") LLVMType llvmFunctionType, - @Cached("llvmFunctionType") @SuppressWarnings("unused") LLVMType cachedType, - @Cached("getNFISignature(hpyContext, llvmFunctionType)") Object nfiSignature, - @CachedLibrary("nfiSignature") SignatureLibrary signatureLibrary) { - return signatureLibrary.bind(nfiSignature, pointerObject); - } - - @Specialization(guards = "llvmFunctionType == cachedType", limit = "3", replaces = "doCachedSingleContext") - static Object doCached(@SuppressWarnings("unused") GraalHPyContext hpyContext, Object pointerObject, @SuppressWarnings("unused") LLVMType llvmFunctionType, - @Cached("llvmFunctionType") @SuppressWarnings("unused") LLVMType cachedType, - @Cached("getNFISignatureCallTarget(hpyContext, llvmFunctionType)") CallTarget nfiSignatureCt, - @Shared @CachedLibrary(limit = "1") SignatureLibrary signatureLibrary) { - return signatureLibrary.bind(nfiSignatureCt.call(), pointerObject); - } - - @Specialization(replaces = {"doCachedSingleContext", "doCached"}) - static Object doGeneric(GraalHPyContext hpyContext, Object pointerObject, LLVMType llvmFunctionType, - @Shared @CachedLibrary(limit = "1") SignatureLibrary signatureLibrary) { - return signatureLibrary.bind(getNFISignature(hpyContext, llvmFunctionType), pointerObject); - } - - @TruffleBoundary - static Object getNFISignature(GraalHPyContext hpyContext, LLVMType llvmFunctionType) { - return hpyContext.getContext().getEnv().parseInternal(getNFISignatureSource(llvmFunctionType)).call(); - } - - @TruffleBoundary - static CallTarget getNFISignatureCallTarget(GraalHPyContext hpyContext, LLVMType llvmFunctionType) { - return hpyContext.getContext().getEnv().parseInternal(getNFISignatureSource(llvmFunctionType)); - } - - @TruffleBoundary - static Source getNFISignatureSource(LLVMType llvmFunctionType) { - return Source.newBuilder(J_NFI_LANGUAGE, getNFISignatureSourceString(llvmFunctionType), llvmFunctionType.name()).build(); - } - - private static String getNFISignatureSourceString(LLVMType llvmFunctionType) { - switch (llvmFunctionType) { - case HPyModule_init: - return "(POINTER): POINTER"; - case HPyFunc_noargs: - case HPyFunc_unaryfunc: - case HPyFunc_getiterfunc: - case HPyFunc_iternextfunc: - case HPyFunc_reprfunc: - return "(POINTER, POINTER): POINTER"; - case HPyFunc_binaryfunc: - case HPyFunc_o: - case HPyFunc_getter: - case HPyFunc_getattrfunc: - case HPyFunc_getattrofunc: - return "(POINTER, POINTER, POINTER): POINTER"; - case HPyFunc_varargs: - return "(POINTER, POINTER, POINTER, SINT64): POINTER"; - case HPyFunc_keywords: - return "(POINTER, POINTER, POINTER, SINT64, POINTER): POINTER"; - case HPyFunc_ternaryfunc: - case HPyFunc_descrgetfunc: - return "(POINTER, POINTER, POINTER, POINTER): POINTER"; - case HPyFunc_inquiry: - return "(POINTER, POINTER): SINT32"; - case HPyFunc_lenfunc: - case HPyFunc_hashfunc: - return "(POINTER, POINTER): SINT64"; - case HPyFunc_ssizeargfunc: - return "(POINTER, POINTER, SINT64): POINTER"; - case HPyFunc_ssizessizeargfunc: - return "(POINTER, POINTER, SINT64, SINT64): POINTER"; - case HPyFunc_ssizeobjargproc: - return "(POINTER, POINTER, SINT64, POINTER): SINT32"; - case HPyFunc_initproc: - return "(POINTER, POINTER, POINTER, SINT64, POINTER): SINT32"; - case HPyFunc_ssizessizeobjargproc: - return "(POINTER, POINTER, SINT64, SINT64, POINTER): SINT32"; - case HPyFunc_objobjargproc: - case HPyFunc_setter: - case HPyFunc_descrsetfunc: - case HPyFunc_setattrfunc: - case HPyFunc_setattrofunc: - return "(POINTER, POINTER, POINTER, POINTER): SINT32"; - case HPyFunc_freefunc: - return "(POINTER, POINTER): VOID"; - case HPyFunc_richcmpfunc: - return "(POINTER, POINTER, POINTER, SINT32): POINTER"; - case HPyFunc_objobjproc: - return "(POINTER, POINTER, POINTER): SINT32"; - case HPyFunc_getbufferproc: - return "(POINTER, POINTER, POINTER, SINT32): SINT32"; - case HPyFunc_releasebufferproc: - return "(POINTER, POINTER, POINTER): VOID"; - case HPyFunc_traverseproc: - return "(POINTER, POINTER, POINTER): SINT32"; - case HPyFunc_destroyfunc: - return "(POINTER): VOID"; - } - throw CompilerDirectives.shouldNotReachHere(); - } - } - - /** - */ - @GenerateUncached - @GenerateInline(false) - public abstract static class HPyAttachJNIFunctionTypeNode extends HPyAttachFunctionTypeNode { - - @Specialization - static GraalHPyJNIFunctionPointer doLong(GraalHPyContext hpyContext, long pointer, LLVMType llvmFunctionType) { - return new GraalHPyJNIFunctionPointer(pointer, llvmFunctionType, hpyContext.getCurrentMode()); - } - - @Specialization - static GraalHPyJNIFunctionPointer doGeneric(GraalHPyContext hpyContext, Object pointerObject, LLVMType llvmFunctionType, - @CachedLibrary(limit = "1") InteropLibrary interopLibrary) { - long pointer; - if (pointerObject instanceof Long pointerLong) { - pointer = pointerLong; - } else { - if (!interopLibrary.isPointer(pointerObject)) { - interopLibrary.toNative(pointerObject); - } - try { - pointer = interopLibrary.asPointer(pointerObject); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } - return new GraalHPyJNIFunctionPointer(pointer, llvmFunctionType, hpyContext.getCurrentMode()); - } - } - - public static final class HPyLLVMAttachFunctionTypeNode extends HPyAttachFunctionTypeNode { - - private static final HPyLLVMAttachFunctionTypeNode UNCACHED = new HPyLLVMAttachFunctionTypeNode(); - - @Override - public Object execute(GraalHPyContext hpyContext, Object pointerObject, LLVMType llvmFunctionType) { - assert InteropLibrary.getUncached().isExecutable(pointerObject); - return pointerObject; - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - protected static Object callBuiltinFunction(GraalHPyContext graalHPyContext, TruffleString func, Object[] pythonArguments, - ReadAttributeFromObjectNode readAttr, - CallNode callNode) { - Object builtinFunction = readAttr.execute(graalHPyContext.getContext().getBuiltins(), func); - return callNode.executeWithoutFrame(builtinFunction, pythonArguments, PKeyword.EMPTY_KEYWORDS); - } - - @ImportStatic(PGuards.class) - @GenerateUncached - @GenerateInline(false) // footprint reduction 60 -> 41 - public abstract static class RecursiveExceptionMatches extends Node { - abstract int execute(GraalHPyContext context, Object err, Object exc); - - @Specialization - static int tuple(GraalHPyContext context, Object err, PTuple exc, - @Bind("this") Node inliningTarget, - @Shared @Cached RecursiveExceptionMatches recExcMatch, - @Exclusive @Cached PyObjectGetItem getItemNode, - @Exclusive @Cached InlinedLoopConditionProfile loopProfile) { - int len = exc.getSequenceStorage().length(); - for (int i = 0; loopProfile.profile(inliningTarget, i < len); i++) { - Object e = getItemNode.execute(null, inliningTarget, exc, i); - if (recExcMatch.execute(context, err, e) != 0) { - return 1; - } - } - return 0; - } - - @Specialization(guards = {"!isPTuple(exc)", "isTupleSubtype(inliningTarget, exc, getClassNode, isSubtypeNode)"}, limit = "1") - static int subtuple(GraalHPyContext context, Object err, Object exc, - @Bind("this") Node inliningTarget, - @Shared @Cached RecursiveExceptionMatches recExcMatch, - @SuppressWarnings("unused") @Exclusive @Cached GetClassNode getClassNode, - @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Shared @Cached ReadAttributeFromObjectNode readAttr, - @Shared @Cached CallNode callNode, - @Cached CastToJavaIntExactNode cast, - @Exclusive @Cached PyObjectGetItem getItemNode, - @Exclusive @Cached InlinedLoopConditionProfile loopProfile) { - int len = cast.execute(inliningTarget, callBuiltinFunction(context, BuiltinNames.T_LEN, new Object[]{exc}, readAttr, callNode)); - for (int i = 0; loopProfile.profile(inliningTarget, i < len); i++) { - Object e = getItemNode.execute(null, inliningTarget, exc, i); - if (recExcMatch.execute(context, err, e) != 0) { - return 1; - } - } - return 0; - } - - @Specialization(guards = {"!isPTuple(exc)", "!isTupleSubtype(inliningTarget, exc, getClassNode, isSubtypeNode)"}, limit = "1") - static int others(GraalHPyContext context, Object err, Object exc, - @Bind("this") Node inliningTarget, - @Exclusive @Cached GetClassNode getClassNode, - @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtypeNode, - @Shared @Cached ReadAttributeFromObjectNode readAttr, - @Shared @Cached CallNode callNode, - @Cached PyObjectIsTrueNode isTrueNode, - @Cached IsTypeNode isTypeNode, - @Cached IsNode isNode, - @Cached InlinedBranchProfile isBaseExceptionProfile, - @Cached InlinedConditionProfile isExceptionProfile) { - Object isInstance = callBuiltinFunction(context, - BuiltinNames.T_ISINSTANCE, - new Object[]{err, PythonBuiltinClassType.PBaseException}, - readAttr, callNode); - Object e = err; - if (isTrueNode.execute(null, isInstance)) { - isBaseExceptionProfile.enter(inliningTarget); - e = getClassNode.execute(inliningTarget, err); - } - if (isExceptionProfile.profile(inliningTarget, - isExceptionClass(context, inliningTarget, e, isTypeNode, readAttr, callNode, isTrueNode) && - isExceptionClass(context, inliningTarget, exc, isTypeNode, readAttr, callNode, isTrueNode))) { - return isSubClass(context, e, exc, readAttr, callNode, isTrueNode) ? 1 : 0; - } else { - return isNode.execute(exc, e) ? 1 : 0; - } - } - - protected boolean isTupleSubtype(Node inliningTarget, Object obj, GetClassNode getClassNode, IsSubtypeNode isSubtypeNode) { - return isSubtypeNode.execute(getClassNode.execute(inliningTarget, obj), PythonBuiltinClassType.PTuple); - } - - static boolean isSubClass(GraalHPyContext graalHPyContext, Object derived, Object cls, - ReadAttributeFromObjectNode readAttr, - CallNode callNode, - PyObjectIsTrueNode isTrueNode) { - return isTrueNode.execute(null, callBuiltinFunction(graalHPyContext, - BuiltinNames.T_ISSUBCLASS, - new Object[]{derived, cls}, readAttr, callNode)); - - } - - private static boolean isExceptionClass(GraalHPyContext nativeContext, Node inliningTarget, Object obj, - IsTypeNode isTypeNode, - ReadAttributeFromObjectNode readAttr, - CallNode callNode, - PyObjectIsTrueNode isTrueNode) { - return isTypeNode.execute(inliningTarget, obj) && isSubClass(nativeContext, obj, PythonBuiltinClassType.PBaseException, readAttr, callNode, isTrueNode); - } - } - - @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class HPyPackKeywordArgsNode extends Node { - - public abstract PKeyword[] execute(Node inliningTarget, Object[] kwvalues, PTuple kwnames, int nkw); - - @Specialization - static PKeyword[] doPTuple(Node inliningTarget, Object[] kwvalues, PTuple kwnames, int nkw, - @Cached SequenceStorageNodes.GetItemScalarNode getItemNode, - @Cached InlinedLoopConditionProfile loopProfile) { - loopProfile.profileCounted(inliningTarget, nkw); - if (nkw == 0) { - return PKeyword.EMPTY_KEYWORDS; - } - PKeyword[] result = new PKeyword[nkw]; - SequenceStorage storage = kwnames.getSequenceStorage(); - for (int i = 0; loopProfile.inject(inliningTarget, i < nkw); i++) { - TruffleString name = (TruffleString) getItemNode.execute(inliningTarget, storage, i); - result[i] = new PKeyword(name, kwvalues[i]); - } - return result; - } - } - - @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class HPyFieldLoadNode extends Node { - - public abstract Object execute(Node inliningTarget, PythonObject owner, Object hpyFieldPtr); - - @Specialization - static Object doHandle(@SuppressWarnings("unused") PythonObject owner, GraalHPyHandle handle) { - return handle.getDelegate(); - } - - @Specialization(replaces = "doHandle") - static Object doGeneric(Node inliningTarget, PythonObject owner, Object hpyFieldPtr, - @CachedLibrary(limit = "3") InteropLibrary lib, - @Cached InlinedExactClassProfile fieldTypeProfile) { - Object hpyFieldObject = fieldTypeProfile.profile(inliningTarget, hpyFieldPtr); - Object referent; - // avoid `asPointer` message dispatch - if (hpyFieldObject instanceof GraalHPyHandle) { - referent = ((GraalHPyHandle) hpyFieldObject).getDelegate(); - } else { - int idx; - if (hpyFieldObject instanceof Long) { - // branch profile in lib.asPointer - try { - idx = PInt.intValueExact((Long) hpyFieldObject); - } catch (OverflowException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } else { - try { - idx = PInt.intValueExact(lib.asPointer(hpyFieldObject)); - } catch (InteropException | OverflowException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - if (idx == 0) { - return NULL_HANDLE_DELEGATE; - } - referent = GraalHPyData.getHPyField(owner, idx); - } - return referent; - } - } - - @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class HPyFieldStoreNode extends Node { - - public abstract int execute(Node inliningTarget, PythonObject owner, Object hpyFieldObject, Object referent); - - @Specialization - static int doHandle(Node inliningTarget, @SuppressWarnings("unused") PythonObject owner, GraalHPyHandle hpyFieldObject, Object referent, - @Shared @Cached InlinedConditionProfile nullHandleProfile) { - int idx = hpyFieldObject.getFieldId(); - if (nullHandleProfile.profile(inliningTarget, referent == NULL_HANDLE_DELEGATE && idx == 0)) { - // assigning HPy_NULL to a field that already holds HPy_NULL, nothing to do - return 0; - } else { - return GraalHPyData.setHPyField(owner, referent, idx); - } - } - - @Specialization(replaces = "doHandle") - static int doGeneric(Node inliningTarget, PythonObject owner, Object hpyFieldObject, Object referent, - @CachedLibrary(limit = "3") InteropLibrary lib, - @Shared @Cached InlinedConditionProfile nullHandleProfile) { - int idx; - if (lib.isNull(hpyFieldObject)) { // uninitialized - idx = 0; - } else if (hpyFieldObject instanceof GraalHPyHandle) { - // avoid `asPointer` message dispatch - idx = ((GraalHPyHandle) hpyFieldObject).getFieldId(); - } else { - if (hpyFieldObject instanceof Long) { - // branch profile in lib.asPointer - try { - idx = PInt.intValueExact((Long) hpyFieldObject); - } catch (OverflowException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } else { - try { - idx = PInt.intValueExact(lib.asPointer(hpyFieldObject)); - } catch (InteropException | OverflowException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - } - // TODO: (tfel) do not actually allocate the index / free the existing one when - // value can be stored as tagged handle - if (nullHandleProfile.profile(inliningTarget, referent == NULL_HANDLE_DELEGATE && idx == 0)) { - // assigning HPy_NULL to a field that already holds HPy_NULL, nothing to do - } else { - idx = GraalHPyData.setHPyField(owner, referent, idx); - } - return idx; - } - } - - /** - * Parses an {@code HPyCallFunction} structure and returns the {@code impl} function pointer. A - * {@code NULL} pointer will be translated to Java {@code null}. - * - *
    -     * typedef struct {
    -     *     cpy_vectorcallfunc cpy_trampoline;
    -     *     HPyFunc_keywords impl;
    -     * } HPyCallFunction;
    -     * 
    - */ - @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class HPyReadCallFunctionNode extends PNodeWithContext { - - public abstract Object execute(Node inliningTarget, GraalHPyContext context, Object def); - - @Specialization - static Object doIt(GraalHPyContext context, Object def, - @Cached(parameters = "context", inline = false) GraalHPyCAccess.ReadPointerNode readPointerNode, - @Cached(parameters = "context", inline = false) GraalHPyCAccess.IsNullNode isNullNode, - @Cached(inline = false) HPyAttachFunctionTypeNode attachFunctionTypeNode) { - // read and check the function pointer - Object methodFunctionPointer = readPointerNode.read(context, def, GraalHPyCField.HPyCallFunction__impl); - if (isNullNode.execute(context, methodFunctionPointer)) { - return null; - } - HPySlotWrapper slotWrapper = HPY_TP_CALL.getSignatures()[0]; - return attachFunctionTypeNode.execute(context, methodFunctionPointer, slotWrapper.getLLVMFunctionType()); - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyObjectBuiltins.java deleted file mode 100644 index 574b5642a3..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyObjectBuiltins.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import static com.oracle.graal.python.util.PythonUtils.tsArray; -import static com.oracle.graal.python.util.PythonUtils.tsLiteral; - -import java.util.logging.Level; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.cext.common.CExtContext; -import com.oracle.graal.python.builtins.objects.floats.PFloat; -import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.builtins.objects.function.Signature; -import com.oracle.graal.python.builtins.objects.ints.PInt; -import com.oracle.graal.python.builtins.objects.list.PList; -import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.builtins.objects.str.PString; -import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.type.PythonClass; -import com.oracle.graal.python.nodes.PRootNode; -import com.oracle.graal.python.nodes.SpecialMethodNames; -import com.oracle.graal.python.nodes.argument.ReadIndexedArgumentNode; -import com.oracle.graal.python.nodes.argument.ReadVarArgsNode; -import com.oracle.graal.python.nodes.argument.ReadVarKeywordsNode; -import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode; -import com.oracle.graal.python.runtime.ExecutionContext.CalleeContext; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.TruffleLogger; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.strings.TruffleString; - -public abstract class GraalHPyObjectBuiltins { - - public static final class HPyObjectNewNode extends PRootNode { - private static final TruffleString KW_SUPERCONS = tsLiteral("$supercons"); - private static final TruffleString[] KEYWORDS_HIDDEN_SUPERCONS = {KW_SUPERCONS}; - - private static final Signature SIGNATURE = new Signature(-1, true, 1, false, tsArray("self"), KEYWORDS_HIDDEN_SUPERCONS, false); - - private static final TruffleLogger LOGGER = GraalHPyContext.getLogger(HPyObjectNewNode.class); - - private static PKeyword[] createKwDefaults(Object superConstructor) { - if (superConstructor != null) { - return new PKeyword[]{new PKeyword(KW_SUPERCONS, superConstructor)}; - } - return PKeyword.EMPTY_KEYWORDS; - } - - @Child private CalleeContext calleeContext; - @Child private ReadIndexedArgumentNode readSelfNode; - @Child private ReadVarArgsNode readVarargsNode; - @Child private ReadVarKeywordsNode readKwargsNode; - @Child private ReadIndexedArgumentNode readCallableNode; - @Child private GraalHPyCAccess.AllocateNode allocateNode; - @Child private CallVarargsMethodNode callNewNode; - - private final int builtinShape; - - private HPyObjectNewNode(PythonLanguage language, int builtinShape) { - super(language); - this.builtinShape = builtinShape; - } - - @Override - public Object execute(VirtualFrame frame) { - getCalleeContext().enter(frame); - try { - return doCall(frame, getSuperConstructor(frame), getSelf(frame), getVarargs(frame), getKwargs(frame)); - } finally { - getCalleeContext().exit(frame, this); - } - } - - private Object doCall(VirtualFrame frame, Object superConstructor, Object explicitSelf, Object[] arguments, PKeyword[] keywords) { - assert explicitSelf != null; - - // create the managed Python object - - // delegate to the best base's constructor - Object self; - Object[] argsWithSelf; - if (explicitSelf == PNone.NO_VALUE) { - argsWithSelf = arguments; - self = argsWithSelf[0]; - } else { - argsWithSelf = new Object[arguments.length + 1]; - argsWithSelf[0] = explicitSelf; - PythonUtils.arraycopy(arguments, 0, argsWithSelf, 1, arguments.length); - self = explicitSelf; - } - PythonContext context = PythonContext.get(this); - Object dataPtr = null; - Object defaultCallFunction = null; - if (self instanceof PythonClass pythonClass) { - // allocate native space - long basicSize = pythonClass.getBasicSize(); - if (basicSize > 0) { - /* - * This is just calling 'calloc' which is a pure helper function. Therefore, we - * can take any HPy context and don't need to attach a context to this __new__ - * function for that since the helper function won't deal with handles. - */ - GraalHPyContext hpyContext = context.getHPyContext(); - dataPtr = ensureAllocateNode(hpyContext).calloc(hpyContext, 1L, basicSize); - - if (LOGGER.isLoggable(Level.FINEST)) { - LOGGER.finest(PythonUtils.formatJString("Allocated HPy object with native space of size %d at %s", basicSize, dataPtr)); - } - } - - defaultCallFunction = pythonClass.getHPyDefaultCallFunc(); - } - - Object result = ensureCallNewNode().execute(frame, superConstructor, argsWithSelf, keywords); - assert validateSuperConstructorResult(result, builtinShape); - - /* - * Since we are creating an object with an unknown constructor, the Java type may be - * anything (e.g. PInt, etc). However, we require it to be a PythonObject otherwise we - * don't know where to store the native data pointer. - */ - if (result instanceof PythonObject pythonObject) { - if (dataPtr != null) { - GraalHPyData.setHPyNativeSpace(pythonObject, dataPtr); - } - if (defaultCallFunction != null) { - GraalHPyData.setHPyCallFunction(pythonObject, defaultCallFunction); - } - } else { - assert false : "inherited constructor of HPy type did not create a managed Python object"; - } - return result; - } - - private static boolean validateSuperConstructorResult(Object result, int builtinShape) { - return switch (builtinShape) { - case GraalHPyDef.HPyType_BUILTIN_SHAPE_LEGACY, GraalHPyDef.HPyType_BUILTIN_SHAPE_OBJECT -> result instanceof PythonObject; - case GraalHPyDef.HPyType_BUILTIN_SHAPE_TYPE -> result instanceof PythonClass; - case GraalHPyDef.HPyType_BUILTIN_SHAPE_LONG -> result instanceof PInt; - case GraalHPyDef.HPyType_BUILTIN_SHAPE_FLOAT -> result instanceof PFloat; - case GraalHPyDef.HPyType_BUILTIN_SHAPE_UNICODE -> result instanceof PString; - case GraalHPyDef.HPyType_BUILTIN_SHAPE_TUPLE -> result instanceof PTuple; - case GraalHPyDef.HPyType_BUILTIN_SHAPE_LIST -> result instanceof PList; - default -> false; - }; - } - - private Object getSelf(VirtualFrame frame) { - if (readSelfNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readSelfNode = insert(ReadIndexedArgumentNode.create(0)); - } - return readSelfNode.execute(frame); - } - - private Object[] getVarargs(VirtualFrame frame) { - if (readVarargsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readVarargsNode = insert(ReadVarArgsNode.create(true)); - } - return readVarargsNode.executeObjectArray(frame); - } - - private PKeyword[] getKwargs(VirtualFrame frame) { - if (PArguments.getKeywordArguments(frame).length == 0) { - return PKeyword.EMPTY_KEYWORDS; - } - if (readKwargsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readKwargsNode = insert(ReadVarKeywordsNode.create()); - } - return (PKeyword[]) readKwargsNode.execute(frame); - } - - private Object getSuperConstructor(VirtualFrame frame) { - if (readCallableNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - // we insert a hidden argument at the end of the positional arguments - int hiddenArg = getSignature().getParameterIds().length; - readCallableNode = insert(ReadIndexedArgumentNode.create(hiddenArg)); - } - return readCallableNode.execute(frame); - } - - private CalleeContext getCalleeContext() { - if (calleeContext == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - calleeContext = insert(CalleeContext.create()); - } - return calleeContext; - } - - private static Object extractInheritedConstructor(PythonContext context, PKeyword[] keywords) { - for (int i = 0; i < keywords.length; i++) { - if (keywords[i].getName() == KW_SUPERCONS) { - return keywords[i].getValue(); - } - } - return context.lookupType(PythonBuiltinClassType.PythonObject).getAttribute(SpecialMethodNames.T___NEW__); - } - - private GraalHPyCAccess.AllocateNode ensureAllocateNode(GraalHPyContext ctx) { - if (allocateNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - allocateNode = insert(GraalHPyCAccess.AllocateNode.create(ctx)); - } - return allocateNode; - } - - private CallVarargsMethodNode ensureCallNewNode() { - if (callNewNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - callNewNode = insert(CallVarargsMethodNode.create()); - } - return callNewNode; - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - - @Override - public boolean isPythonInternal() { - return true; - } - - @Override - public boolean setsUpCalleeContext() { - return true; - } - - @TruffleBoundary - public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, Object superConstructor, int builtinShape) { - // do not decorate the decorator - if (superConstructor instanceof PBuiltinFunction builtinFunction && isHPyObjectNewDecorator(builtinFunction)) { - return builtinFunction; - } - RootCallTarget callTarget = language.createCachedCallTarget(l -> new HPyObjectNewNode(language, builtinShape), HPyObjectNewNode.class, builtinShape); - int flags = CExtContext.METH_KEYWORDS | CExtContext.METH_VARARGS; - return PythonObjectFactory.getUncached().createBuiltinFunction(SpecialMethodNames.T___NEW__, null, PythonUtils.EMPTY_OBJECT_ARRAY, createKwDefaults(superConstructor), flags, callTarget); - } - - public static Object getDecoratedSuperConstructor(PBuiltinFunction builtinFunction) { - if (isHPyObjectNewDecorator(builtinFunction)) { - return extractInheritedConstructor(PythonContext.get(null), builtinFunction.getKwDefaults()); - } - return null; - } - - private static boolean isHPyObjectNewDecorator(PBuiltinFunction builtinFunction) { - return builtinFunction.getFunctionRootNode() instanceof HPyObjectNewNode; - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyContextMember.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyContextMember.java deleted file mode 100644 index 28dcf99fc7..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyContextMember.java +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Bool; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.CDouble; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.CVoid; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.ConstCharPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.ConstHPyPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.ConstWchar_tPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Cpy_PyObjectPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPy; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyCallFunctionPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyCapsule_DestructorPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyContextPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyField; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyFieldPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyGlobal; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyGlobalPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyListBuilder; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyThreadState; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyTracker; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyTupleBuilder; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyType_BuiltinShape; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyType_SpecParamPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPyType_SpecPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPy_SourceKind; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPy_UCS4; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPy_hash_t; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPy_ssize_t; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.HPy_ssize_tPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Int; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Int32_t; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Int64_t; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Size_t; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Uint32_t; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.Uint64_t; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.VoidPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType.VoidPtrPtr; -import static com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType._HPyCapsule_key; - -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.HPyUpcall; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; - -/** - * An enum of all fields currently available in the HPy context (see {@code public_api.h}). - */ -public enum HPyContextMember implements HPyUpcall { - NAME("name"), - PRIVATE("_private"), - ABI_VERSION("abi_version"), - - // {{start ctx members}} - // @formatter:off - // Checkstyle: stop - // DO NOT EDIT THIS PART! - // This part is automatically generated by hpy.tools.autogen.graalpy.autogen_ctx_member_enum - H_NONE("h_None"), - H_TRUE("h_True"), - H_FALSE("h_False"), - H_NOTIMPLEMENTED("h_NotImplemented"), - H_ELLIPSIS("h_Ellipsis"), - H_BASEEXCEPTION("h_BaseException"), - H_EXCEPTION("h_Exception"), - H_STOPASYNCITERATION("h_StopAsyncIteration"), - H_STOPITERATION("h_StopIteration"), - H_GENERATOREXIT("h_GeneratorExit"), - H_ARITHMETICERROR("h_ArithmeticError"), - H_LOOKUPERROR("h_LookupError"), - H_ASSERTIONERROR("h_AssertionError"), - H_ATTRIBUTEERROR("h_AttributeError"), - H_BUFFERERROR("h_BufferError"), - H_EOFERROR("h_EOFError"), - H_FLOATINGPOINTERROR("h_FloatingPointError"), - H_OSERROR("h_OSError"), - H_IMPORTERROR("h_ImportError"), - H_MODULENOTFOUNDERROR("h_ModuleNotFoundError"), - H_INDEXERROR("h_IndexError"), - H_KEYERROR("h_KeyError"), - H_KEYBOARDINTERRUPT("h_KeyboardInterrupt"), - H_MEMORYERROR("h_MemoryError"), - H_NAMEERROR("h_NameError"), - H_OVERFLOWERROR("h_OverflowError"), - H_RUNTIMEERROR("h_RuntimeError"), - H_RECURSIONERROR("h_RecursionError"), - H_NOTIMPLEMENTEDERROR("h_NotImplementedError"), - H_SYNTAXERROR("h_SyntaxError"), - H_INDENTATIONERROR("h_IndentationError"), - H_TABERROR("h_TabError"), - H_REFERENCEERROR("h_ReferenceError"), - H_SYSTEMERROR("h_SystemError"), - H_SYSTEMEXIT("h_SystemExit"), - H_TYPEERROR("h_TypeError"), - H_UNBOUNDLOCALERROR("h_UnboundLocalError"), - H_UNICODEERROR("h_UnicodeError"), - H_UNICODEENCODEERROR("h_UnicodeEncodeError"), - H_UNICODEDECODEERROR("h_UnicodeDecodeError"), - H_UNICODETRANSLATEERROR("h_UnicodeTranslateError"), - H_VALUEERROR("h_ValueError"), - H_ZERODIVISIONERROR("h_ZeroDivisionError"), - H_BLOCKINGIOERROR("h_BlockingIOError"), - H_BROKENPIPEERROR("h_BrokenPipeError"), - H_CHILDPROCESSERROR("h_ChildProcessError"), - H_CONNECTIONERROR("h_ConnectionError"), - H_CONNECTIONABORTEDERROR("h_ConnectionAbortedError"), - H_CONNECTIONREFUSEDERROR("h_ConnectionRefusedError"), - H_CONNECTIONRESETERROR("h_ConnectionResetError"), - H_FILEEXISTSERROR("h_FileExistsError"), - H_FILENOTFOUNDERROR("h_FileNotFoundError"), - H_INTERRUPTEDERROR("h_InterruptedError"), - H_ISADIRECTORYERROR("h_IsADirectoryError"), - H_NOTADIRECTORYERROR("h_NotADirectoryError"), - H_PERMISSIONERROR("h_PermissionError"), - H_PROCESSLOOKUPERROR("h_ProcessLookupError"), - H_TIMEOUTERROR("h_TimeoutError"), - H_WARNING("h_Warning"), - H_USERWARNING("h_UserWarning"), - H_DEPRECATIONWARNING("h_DeprecationWarning"), - H_PENDINGDEPRECATIONWARNING("h_PendingDeprecationWarning"), - H_SYNTAXWARNING("h_SyntaxWarning"), - H_RUNTIMEWARNING("h_RuntimeWarning"), - H_FUTUREWARNING("h_FutureWarning"), - H_IMPORTWARNING("h_ImportWarning"), - H_UNICODEWARNING("h_UnicodeWarning"), - H_BYTESWARNING("h_BytesWarning"), - H_RESOURCEWARNING("h_ResourceWarning"), - H_BASEOBJECTTYPE("h_BaseObjectType"), - H_TYPETYPE("h_TypeType"), - H_BOOLTYPE("h_BoolType"), - H_LONGTYPE("h_LongType"), - H_FLOATTYPE("h_FloatType"), - H_UNICODETYPE("h_UnicodeType"), - H_TUPLETYPE("h_TupleType"), - H_LISTTYPE("h_ListType"), - H_COMPLEXTYPE("h_ComplexType"), - H_BYTESTYPE("h_BytesType"), - H_MEMORYVIEWTYPE("h_MemoryViewType"), - H_CAPSULETYPE("h_CapsuleType"), - H_SLICETYPE("h_SliceType"), - H_BUILTINS("h_Builtins"), - CTX_DUP("ctx_Dup", HPy, HPyContextPtr, HPy), - CTX_CLOSE("ctx_Close", CVoid, HPyContextPtr, HPy), - CTX_LONG_FROMINT32_T("ctx_Long_FromInt32_t", HPy, HPyContextPtr, Int32_t), - CTX_LONG_FROMUINT32_T("ctx_Long_FromUInt32_t", HPy, HPyContextPtr, Uint32_t), - CTX_LONG_FROMINT64_T("ctx_Long_FromInt64_t", HPy, HPyContextPtr, Int64_t), - CTX_LONG_FROMUINT64_T("ctx_Long_FromUInt64_t", HPy, HPyContextPtr, Uint64_t), - CTX_LONG_FROMSIZE_T("ctx_Long_FromSize_t", HPy, HPyContextPtr, Size_t), - CTX_LONG_FROMSSIZE_T("ctx_Long_FromSsize_t", HPy, HPyContextPtr, HPy_ssize_t), - CTX_LONG_ASINT32_T("ctx_Long_AsInt32_t", Int32_t, HPyContextPtr, HPy), - CTX_LONG_ASUINT32_T("ctx_Long_AsUInt32_t", Uint32_t, HPyContextPtr, HPy), - CTX_LONG_ASUINT32_TMASK("ctx_Long_AsUInt32_tMask", Uint32_t, HPyContextPtr, HPy), - CTX_LONG_ASINT64_T("ctx_Long_AsInt64_t", Int64_t, HPyContextPtr, HPy), - CTX_LONG_ASUINT64_T("ctx_Long_AsUInt64_t", Uint64_t, HPyContextPtr, HPy), - CTX_LONG_ASUINT64_TMASK("ctx_Long_AsUInt64_tMask", Uint64_t, HPyContextPtr, HPy), - CTX_LONG_ASSIZE_T("ctx_Long_AsSize_t", Size_t, HPyContextPtr, HPy), - CTX_LONG_ASSSIZE_T("ctx_Long_AsSsize_t", HPy_ssize_t, HPyContextPtr, HPy), - CTX_LONG_ASVOIDPTR("ctx_Long_AsVoidPtr", VoidPtr, HPyContextPtr, HPy), - CTX_LONG_ASDOUBLE("ctx_Long_AsDouble", CDouble, HPyContextPtr, HPy), - CTX_FLOAT_FROMDOUBLE("ctx_Float_FromDouble", HPy, HPyContextPtr, CDouble), - CTX_FLOAT_ASDOUBLE("ctx_Float_AsDouble", CDouble, HPyContextPtr, HPy), - CTX_BOOL_FROMBOOL("ctx_Bool_FromBool", HPy, HPyContextPtr, Bool), - CTX_LENGTH("ctx_Length", HPy_ssize_t, HPyContextPtr, HPy), - CTX_NUMBER_CHECK("ctx_Number_Check", Int, HPyContextPtr, HPy), - CTX_ADD("ctx_Add", HPy, HPyContextPtr, HPy, HPy), - CTX_SUBTRACT("ctx_Subtract", HPy, HPyContextPtr, HPy, HPy), - CTX_MULTIPLY("ctx_Multiply", HPy, HPyContextPtr, HPy, HPy), - CTX_MATRIXMULTIPLY("ctx_MatrixMultiply", HPy, HPyContextPtr, HPy, HPy), - CTX_FLOORDIVIDE("ctx_FloorDivide", HPy, HPyContextPtr, HPy, HPy), - CTX_TRUEDIVIDE("ctx_TrueDivide", HPy, HPyContextPtr, HPy, HPy), - CTX_REMAINDER("ctx_Remainder", HPy, HPyContextPtr, HPy, HPy), - CTX_DIVMOD("ctx_Divmod", HPy, HPyContextPtr, HPy, HPy), - CTX_POWER("ctx_Power", HPy, HPyContextPtr, HPy, HPy, HPy), - CTX_NEGATIVE("ctx_Negative", HPy, HPyContextPtr, HPy), - CTX_POSITIVE("ctx_Positive", HPy, HPyContextPtr, HPy), - CTX_ABSOLUTE("ctx_Absolute", HPy, HPyContextPtr, HPy), - CTX_INVERT("ctx_Invert", HPy, HPyContextPtr, HPy), - CTX_LSHIFT("ctx_Lshift", HPy, HPyContextPtr, HPy, HPy), - CTX_RSHIFT("ctx_Rshift", HPy, HPyContextPtr, HPy, HPy), - CTX_AND("ctx_And", HPy, HPyContextPtr, HPy, HPy), - CTX_XOR("ctx_Xor", HPy, HPyContextPtr, HPy, HPy), - CTX_OR("ctx_Or", HPy, HPyContextPtr, HPy, HPy), - CTX_INDEX("ctx_Index", HPy, HPyContextPtr, HPy), - CTX_LONG("ctx_Long", HPy, HPyContextPtr, HPy), - CTX_FLOAT("ctx_Float", HPy, HPyContextPtr, HPy), - CTX_INPLACEADD("ctx_InPlaceAdd", HPy, HPyContextPtr, HPy, HPy), - CTX_INPLACESUBTRACT("ctx_InPlaceSubtract", HPy, HPyContextPtr, HPy, HPy), - CTX_INPLACEMULTIPLY("ctx_InPlaceMultiply", HPy, HPyContextPtr, HPy, HPy), - CTX_INPLACEMATRIXMULTIPLY("ctx_InPlaceMatrixMultiply", HPy, HPyContextPtr, HPy, HPy), - CTX_INPLACEFLOORDIVIDE("ctx_InPlaceFloorDivide", HPy, HPyContextPtr, HPy, HPy), - CTX_INPLACETRUEDIVIDE("ctx_InPlaceTrueDivide", HPy, HPyContextPtr, HPy, HPy), - CTX_INPLACEREMAINDER("ctx_InPlaceRemainder", HPy, HPyContextPtr, HPy, HPy), - CTX_INPLACEPOWER("ctx_InPlacePower", HPy, HPyContextPtr, HPy, HPy, HPy), - CTX_INPLACELSHIFT("ctx_InPlaceLshift", HPy, HPyContextPtr, HPy, HPy), - CTX_INPLACERSHIFT("ctx_InPlaceRshift", HPy, HPyContextPtr, HPy, HPy), - CTX_INPLACEAND("ctx_InPlaceAnd", HPy, HPyContextPtr, HPy, HPy), - CTX_INPLACEXOR("ctx_InPlaceXor", HPy, HPyContextPtr, HPy, HPy), - CTX_INPLACEOR("ctx_InPlaceOr", HPy, HPyContextPtr, HPy, HPy), - CTX_CALLABLE_CHECK("ctx_Callable_Check", Int, HPyContextPtr, HPy), - CTX_CALLTUPLEDICT("ctx_CallTupleDict", HPy, HPyContextPtr, HPy, HPy, HPy), - CTX_CALL("ctx_Call", HPy, HPyContextPtr, HPy, ConstHPyPtr, Size_t, HPy), - CTX_CALLMETHOD("ctx_CallMethod", HPy, HPyContextPtr, HPy, ConstHPyPtr, Size_t, HPy), - CTX_FATALERROR("ctx_FatalError", CVoid, HPyContextPtr, ConstCharPtr), - CTX_ERR_SETSTRING("ctx_Err_SetString", CVoid, HPyContextPtr, HPy, ConstCharPtr), - CTX_ERR_SETOBJECT("ctx_Err_SetObject", CVoid, HPyContextPtr, HPy, HPy), - CTX_ERR_SETFROMERRNOWITHFILENAME("ctx_Err_SetFromErrnoWithFilename", HPy, HPyContextPtr, HPy, ConstCharPtr), - CTX_ERR_SETFROMERRNOWITHFILENAMEOBJECTS("ctx_Err_SetFromErrnoWithFilenameObjects", CVoid, HPyContextPtr, HPy, HPy, HPy), - CTX_ERR_OCCURRED("ctx_Err_Occurred", Int, HPyContextPtr), - CTX_ERR_EXCEPTIONMATCHES("ctx_Err_ExceptionMatches", Int, HPyContextPtr, HPy), - CTX_ERR_NOMEMORY("ctx_Err_NoMemory", CVoid, HPyContextPtr), - CTX_ERR_CLEAR("ctx_Err_Clear", CVoid, HPyContextPtr), - CTX_ERR_NEWEXCEPTION("ctx_Err_NewException", HPy, HPyContextPtr, ConstCharPtr, HPy, HPy), - CTX_ERR_NEWEXCEPTIONWITHDOC("ctx_Err_NewExceptionWithDoc", HPy, HPyContextPtr, ConstCharPtr, ConstCharPtr, HPy, HPy), - CTX_ERR_WARNEX("ctx_Err_WarnEx", Int, HPyContextPtr, HPy, ConstCharPtr, HPy_ssize_t), - CTX_ERR_WRITEUNRAISABLE("ctx_Err_WriteUnraisable", CVoid, HPyContextPtr, HPy), - CTX_ISTRUE("ctx_IsTrue", Int, HPyContextPtr, HPy), - CTX_TYPE_FROMSPEC("ctx_Type_FromSpec", HPy, HPyContextPtr, HPyType_SpecPtr, HPyType_SpecParamPtr), - CTX_TYPE_GENERICNEW("ctx_Type_GenericNew", HPy, HPyContextPtr, HPy, ConstHPyPtr, HPy_ssize_t, HPy), - CTX_GETATTR("ctx_GetAttr", HPy, HPyContextPtr, HPy, HPy), - CTX_GETATTR_S("ctx_GetAttr_s", HPy, HPyContextPtr, HPy, ConstCharPtr), - CTX_HASATTR("ctx_HasAttr", Int, HPyContextPtr, HPy, HPy), - CTX_HASATTR_S("ctx_HasAttr_s", Int, HPyContextPtr, HPy, ConstCharPtr), - CTX_SETATTR("ctx_SetAttr", Int, HPyContextPtr, HPy, HPy, HPy), - CTX_SETATTR_S("ctx_SetAttr_s", Int, HPyContextPtr, HPy, ConstCharPtr, HPy), - CTX_GETITEM("ctx_GetItem", HPy, HPyContextPtr, HPy, HPy), - CTX_GETITEM_I("ctx_GetItem_i", HPy, HPyContextPtr, HPy, HPy_ssize_t), - CTX_GETITEM_S("ctx_GetItem_s", HPy, HPyContextPtr, HPy, ConstCharPtr), - CTX_CONTAINS("ctx_Contains", Int, HPyContextPtr, HPy, HPy), - CTX_SETITEM("ctx_SetItem", Int, HPyContextPtr, HPy, HPy, HPy), - CTX_SETITEM_I("ctx_SetItem_i", Int, HPyContextPtr, HPy, HPy_ssize_t, HPy), - CTX_SETITEM_S("ctx_SetItem_s", Int, HPyContextPtr, HPy, ConstCharPtr, HPy), - CTX_DELITEM("ctx_DelItem", Int, HPyContextPtr, HPy, HPy), - CTX_DELITEM_I("ctx_DelItem_i", Int, HPyContextPtr, HPy, HPy_ssize_t), - CTX_DELITEM_S("ctx_DelItem_s", Int, HPyContextPtr, HPy, ConstCharPtr), - CTX_TYPE("ctx_Type", HPy, HPyContextPtr, HPy), - CTX_TYPECHECK("ctx_TypeCheck", Int, HPyContextPtr, HPy, HPy), - CTX_TYPE_GETNAME("ctx_Type_GetName", ConstCharPtr, HPyContextPtr, HPy), - CTX_TYPE_ISSUBTYPE("ctx_Type_IsSubtype", Int, HPyContextPtr, HPy, HPy), - CTX_IS("ctx_Is", Int, HPyContextPtr, HPy, HPy), - CTX_ASSTRUCT_OBJECT("ctx_AsStruct_Object", VoidPtr, HPyContextPtr, HPy), - CTX_ASSTRUCT_LEGACY("ctx_AsStruct_Legacy", VoidPtr, HPyContextPtr, HPy), - CTX_ASSTRUCT_TYPE("ctx_AsStruct_Type", VoidPtr, HPyContextPtr, HPy), - CTX_ASSTRUCT_LONG("ctx_AsStruct_Long", VoidPtr, HPyContextPtr, HPy), - CTX_ASSTRUCT_FLOAT("ctx_AsStruct_Float", VoidPtr, HPyContextPtr, HPy), - CTX_ASSTRUCT_UNICODE("ctx_AsStruct_Unicode", VoidPtr, HPyContextPtr, HPy), - CTX_ASSTRUCT_TUPLE("ctx_AsStruct_Tuple", VoidPtr, HPyContextPtr, HPy), - CTX_ASSTRUCT_LIST("ctx_AsStruct_List", VoidPtr, HPyContextPtr, HPy), - CTX_TYPE_GETBUILTINSHAPE("ctx_Type_GetBuiltinShape", HPyType_BuiltinShape, HPyContextPtr, HPy), - CTX_NEW("ctx_New", HPy, HPyContextPtr, HPy, VoidPtrPtr), - CTX_REPR("ctx_Repr", HPy, HPyContextPtr, HPy), - CTX_STR("ctx_Str", HPy, HPyContextPtr, HPy), - CTX_ASCII("ctx_ASCII", HPy, HPyContextPtr, HPy), - CTX_BYTES("ctx_Bytes", HPy, HPyContextPtr, HPy), - CTX_RICHCOMPARE("ctx_RichCompare", HPy, HPyContextPtr, HPy, HPy, Int), - CTX_RICHCOMPAREBOOL("ctx_RichCompareBool", Int, HPyContextPtr, HPy, HPy, Int), - CTX_HASH("ctx_Hash", HPy_hash_t, HPyContextPtr, HPy), - CTX_BYTES_CHECK("ctx_Bytes_Check", Int, HPyContextPtr, HPy), - CTX_BYTES_SIZE("ctx_Bytes_Size", HPy_ssize_t, HPyContextPtr, HPy), - CTX_BYTES_GET_SIZE("ctx_Bytes_GET_SIZE", HPy_ssize_t, HPyContextPtr, HPy), - CTX_BYTES_ASSTRING("ctx_Bytes_AsString", ConstCharPtr, HPyContextPtr, HPy), - CTX_BYTES_AS_STRING("ctx_Bytes_AS_STRING", ConstCharPtr, HPyContextPtr, HPy), - CTX_BYTES_FROMSTRING("ctx_Bytes_FromString", HPy, HPyContextPtr, ConstCharPtr), - CTX_BYTES_FROMSTRINGANDSIZE("ctx_Bytes_FromStringAndSize", HPy, HPyContextPtr, ConstCharPtr, HPy_ssize_t), - CTX_UNICODE_FROMSTRING("ctx_Unicode_FromString", HPy, HPyContextPtr, ConstCharPtr), - CTX_UNICODE_CHECK("ctx_Unicode_Check", Int, HPyContextPtr, HPy), - CTX_UNICODE_ASASCIISTRING("ctx_Unicode_AsASCIIString", HPy, HPyContextPtr, HPy), - CTX_UNICODE_ASLATIN1STRING("ctx_Unicode_AsLatin1String", HPy, HPyContextPtr, HPy), - CTX_UNICODE_ASUTF8STRING("ctx_Unicode_AsUTF8String", HPy, HPyContextPtr, HPy), - CTX_UNICODE_ASUTF8ANDSIZE("ctx_Unicode_AsUTF8AndSize", ConstCharPtr, HPyContextPtr, HPy, HPy_ssize_tPtr), - CTX_UNICODE_FROMWIDECHAR("ctx_Unicode_FromWideChar", HPy, HPyContextPtr, ConstWchar_tPtr, HPy_ssize_t), - CTX_UNICODE_DECODEFSDEFAULT("ctx_Unicode_DecodeFSDefault", HPy, HPyContextPtr, ConstCharPtr), - CTX_UNICODE_DECODEFSDEFAULTANDSIZE("ctx_Unicode_DecodeFSDefaultAndSize", HPy, HPyContextPtr, ConstCharPtr, HPy_ssize_t), - CTX_UNICODE_ENCODEFSDEFAULT("ctx_Unicode_EncodeFSDefault", HPy, HPyContextPtr, HPy), - CTX_UNICODE_READCHAR("ctx_Unicode_ReadChar", HPy_UCS4, HPyContextPtr, HPy, HPy_ssize_t), - CTX_UNICODE_DECODEASCII("ctx_Unicode_DecodeASCII", HPy, HPyContextPtr, ConstCharPtr, HPy_ssize_t, ConstCharPtr), - CTX_UNICODE_DECODELATIN1("ctx_Unicode_DecodeLatin1", HPy, HPyContextPtr, ConstCharPtr, HPy_ssize_t, ConstCharPtr), - CTX_UNICODE_FROMENCODEDOBJECT("ctx_Unicode_FromEncodedObject", HPy, HPyContextPtr, HPy, ConstCharPtr, ConstCharPtr), - CTX_UNICODE_SUBSTRING("ctx_Unicode_Substring", HPy, HPyContextPtr, HPy, HPy_ssize_t, HPy_ssize_t), - CTX_LIST_CHECK("ctx_List_Check", Int, HPyContextPtr, HPy), - CTX_LIST_NEW("ctx_List_New", HPy, HPyContextPtr, HPy_ssize_t), - CTX_LIST_APPEND("ctx_List_Append", Int, HPyContextPtr, HPy, HPy), - CTX_DICT_CHECK("ctx_Dict_Check", Int, HPyContextPtr, HPy), - CTX_DICT_NEW("ctx_Dict_New", HPy, HPyContextPtr), - CTX_DICT_KEYS("ctx_Dict_Keys", HPy, HPyContextPtr, HPy), - CTX_DICT_COPY("ctx_Dict_Copy", HPy, HPyContextPtr, HPy), - CTX_TUPLE_CHECK("ctx_Tuple_Check", Int, HPyContextPtr, HPy), - CTX_TUPLE_FROMARRAY("ctx_Tuple_FromArray", HPy, HPyContextPtr, HPyPtr, HPy_ssize_t), - CTX_SLICE_UNPACK("ctx_Slice_Unpack", Int, HPyContextPtr, HPy, HPy_ssize_tPtr, HPy_ssize_tPtr, HPy_ssize_tPtr), - CTX_IMPORT_IMPORTMODULE("ctx_Import_ImportModule", HPy, HPyContextPtr, ConstCharPtr), - CTX_CAPSULE_NEW("ctx_Capsule_New", HPy, HPyContextPtr, VoidPtr, ConstCharPtr, HPyCapsule_DestructorPtr), - CTX_CAPSULE_GET("ctx_Capsule_Get", VoidPtr, HPyContextPtr, HPy, _HPyCapsule_key, ConstCharPtr), - CTX_CAPSULE_ISVALID("ctx_Capsule_IsValid", Int, HPyContextPtr, HPy, ConstCharPtr), - CTX_CAPSULE_SET("ctx_Capsule_Set", Int, HPyContextPtr, HPy, _HPyCapsule_key, VoidPtr), - CTX_FROMPYOBJECT("ctx_FromPyObject", HPy, HPyContextPtr, Cpy_PyObjectPtr), - CTX_ASPYOBJECT("ctx_AsPyObject", Cpy_PyObjectPtr, HPyContextPtr, HPy), - CTX_LISTBUILDER_NEW("ctx_ListBuilder_New", HPyListBuilder, HPyContextPtr, HPy_ssize_t), - CTX_LISTBUILDER_SET("ctx_ListBuilder_Set", CVoid, HPyContextPtr, HPyListBuilder, HPy_ssize_t, HPy), - CTX_LISTBUILDER_BUILD("ctx_ListBuilder_Build", HPy, HPyContextPtr, HPyListBuilder), - CTX_LISTBUILDER_CANCEL("ctx_ListBuilder_Cancel", CVoid, HPyContextPtr, HPyListBuilder), - CTX_TUPLEBUILDER_NEW("ctx_TupleBuilder_New", HPyTupleBuilder, HPyContextPtr, HPy_ssize_t), - CTX_TUPLEBUILDER_SET("ctx_TupleBuilder_Set", CVoid, HPyContextPtr, HPyTupleBuilder, HPy_ssize_t, HPy), - CTX_TUPLEBUILDER_BUILD("ctx_TupleBuilder_Build", HPy, HPyContextPtr, HPyTupleBuilder), - CTX_TUPLEBUILDER_CANCEL("ctx_TupleBuilder_Cancel", CVoid, HPyContextPtr, HPyTupleBuilder), - CTX_TRACKER_NEW("ctx_Tracker_New", HPyTracker, HPyContextPtr, HPy_ssize_t), - CTX_TRACKER_ADD("ctx_Tracker_Add", Int, HPyContextPtr, HPyTracker, HPy), - CTX_TRACKER_FORGETALL("ctx_Tracker_ForgetAll", CVoid, HPyContextPtr, HPyTracker), - CTX_TRACKER_CLOSE("ctx_Tracker_Close", CVoid, HPyContextPtr, HPyTracker), - CTX_FIELD_STORE("ctx_Field_Store", CVoid, HPyContextPtr, HPy, HPyFieldPtr, HPy), - CTX_FIELD_LOAD("ctx_Field_Load", HPy, HPyContextPtr, HPy, HPyField), - CTX_REENTERPYTHONEXECUTION("ctx_ReenterPythonExecution", CVoid, HPyContextPtr, HPyThreadState), - CTX_LEAVEPYTHONEXECUTION("ctx_LeavePythonExecution", HPyThreadState, HPyContextPtr), - CTX_GLOBAL_STORE("ctx_Global_Store", CVoid, HPyContextPtr, HPyGlobalPtr, HPy), - CTX_GLOBAL_LOAD("ctx_Global_Load", HPy, HPyContextPtr, HPyGlobal), - CTX_DUMP("ctx_Dump", CVoid, HPyContextPtr, HPy), - CTX_COMPILE_S("ctx_Compile_s", HPy, HPyContextPtr, ConstCharPtr, ConstCharPtr, HPy_SourceKind), - CTX_EVALCODE("ctx_EvalCode", HPy, HPyContextPtr, HPy, HPy, HPy), - CTX_CONTEXTVAR_NEW("ctx_ContextVar_New", HPy, HPyContextPtr, ConstCharPtr, HPy), - CTX_CONTEXTVAR_GET("ctx_ContextVar_Get", Int32_t, HPyContextPtr, HPy, HPy, HPyPtr), - CTX_CONTEXTVAR_SET("ctx_ContextVar_Set", HPy, HPyContextPtr, HPy, HPy), - CTX_SETCALLFUNCTION("ctx_SetCallFunction", Int, HPyContextPtr, HPy, HPyCallFunctionPtr); - - // @formatter:on - // Checkstyle: resume - // {{end ctx members}} - - private final String name; - private final HPyContextSignature signature; - - HPyContextMember(String name) { - this.name = name; - this.signature = null; - } - - HPyContextMember(String name, HPyContextSignatureType returnType, HPyContextSignatureType... paramTypes) { - this.name = name; - this.signature = new HPyContextSignature(returnType, paramTypes); - } - - @CompilationFinal(dimensions = 1) public static final HPyContextMember[] VALUES = values(); - - @Override - public String getName() { - return name; - } - - public HPyContextSignature getSignature() { - return signature; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyContextSignatureType.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyContextSignatureType.java deleted file mode 100644 index 1e4bed20c6..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyContextSignatureType.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -/** - * Describes the type of argument or return type in the HPyContext functions. - */ -public enum HPyContextSignatureType { - HPyContextPtr("HPyContext*", "POINTER", long.class), - CVoid("void", "VOID", void.class), - VoidPtr("void*", "POINTER", long.class), - VoidPtrPtr("void**", "POINTER", long.class), - Bool("bool", "UINT8", boolean.class), - Int("int", null, int.class), - UnsignedInt("unsigned int", null, int.class), - Long("long", null, int.class), - UnsignedLong("unsigned long", "SINT32", int.class), - Int8_t("int8_t", "SINT8", byte.class), - Uint8_t("uint8_t", "UINT8", byte.class), - Int16_t("int16_t", "SINT16", short.class), - Uint16_t("uint16_t", "UINT16", short.class), - Int32_t("int32_t", "SINT32", int.class), - Uint32_t("uint32_t", "UINT32", int.class), - CFloat("float", "FLOAT", float.class), - CDouble("double", "DOUBLE", double.class), - Int64_t("int64_t", "SINT64", int.class), - Uint64_t("uint64_t", "UINT64", int.class), - HPy("HPy", "POINTER", long.class), - HPyPtr("HPy*", "POINTER", long.class), - ConstHPyPtr("const HPy*", "POINTER", long.class), - Wchar_tPtr("wchar_t*", "POINTER", long.class), - ConstWchar_tPtr("const wchar_t*", "POINTER", long.class), - CharPtr("char*", "POINTER", long.class), - ConstCharPtr("const char*", "POINTER", long.class), - DataPtr("void*", "POINTER", long.class), - DataPtrPtr("void**", "POINTER", long.class), - HPyTracker("HPyTracker", "POINTER", long.class), - Size_t("size_t", "UINT64", long.class), - HPy_ssize_t("HPy_ssize_t", "UINT64", long.class), - HPy_ssize_tPtr("HPy_ssize_t*", "POINTER", long.class), - HPy_hash_t("HPy_hash_t", "UINT64", long.class), - HPy_UCS4("HPy_UCS4", "UINT32", int.class), - HPyTupleBuilder("HPyTupleBuilder", "POINTER", long.class), - HPyListBuilder("HPyListBuilder", "POINTER", long.class), - Cpy_PyObjectPtr("cpy_PyObject*", "POINTER", long.class), - Cpy_PyMethodDefPtr("cpy_PyMethodDef*", "POINTER", long.class), - HPyModuleDefPtr("HPyModuleDef*", "POINTER", long.class), - HPyType_SpecPtr("HPyType_Spec*", "POINTER", long.class), - HPyType_SpecParam("HPyType_SpecParam", null, null), - HPyType_SpecParamPtr("HPyType_SpecParam*", "POINTER", long.class), - HPyDefPtr("HPyDef*", "POINTER", long.class), - HPyThreadState("HPyThreadState", "POINTER", long.class), - HPyField("HPyField", "POINTER", long.class), - HPyFieldPtr("HPyField*", "POINTER", long.class), - HPyGlobal("HPyGlobal", "POINTER", long.class), - HPyGlobalPtr("HPyGlobal*", "POINTER", long.class), - HPyCapsule_DestructorPtr("HPyCapsule_Destructor*", "POINTER", long.class), - _HPyCapsule_key("_HPyCapsule_key", "SINT32", int.class), - HPyType_BuiltinShape("HPyType_BuiltinShape", "SINT32", int.class), - HPy_SourceKind("HPy_SourceKind", "SINT32", int.class), - HPyCallFunctionPtr("HPyCallFunction*", "POINTER", long.class), - PyType_Slot("PyType_Slot", null, null), - PyType_SlotPtr("PyType_Slot*", "POINTER", long.class), - HPyFunc_Signature("HPyFunc_Signature", null, null), - HPyMember_FieldType("HPyMember_FieldType", null, null), - HPySlot_Slot("HPySlot_Slot", null, null), - PyMemberDef("PyMemberDef", null, null), - HPy_buffer("HPy_buffer", null, null), - PyGetSetDef("PyGetSetDef", null, null); - - /** - * The type definition used in C source code. - */ - final String cType; - /** - * The type definition that is used in NFI signatures. - */ - final String nfiType; - /** - * The type used on the Java side in JNI/CLinker functions. - */ - final Class jniType; - - HPyContextSignatureType(String cType, String nfiType, Class jniType) { - this.cType = cType; - this.nfiType = nfiType; - this.jniType = jniType; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyExternalFunctionNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyExternalFunctionNodes.java deleted file mode 100644 index d61f11be8e..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyExternalFunctionNodes.java +++ /dev/null @@ -1,1875 +0,0 @@ -/* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy; - -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; -import static com.oracle.graal.python.util.PythonUtils.EMPTY_TRUFFLESTRING_ARRAY; -import static com.oracle.graal.python.util.PythonUtils.tsArray; -import static com.oracle.graal.python.util.PythonUtils.tsLiteral; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; -import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.FromCharPointerNode; -import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.FromCharPointerNodeGen; -import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes; -import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.GetterRoot; -import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper; -import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.SetterRoot; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.EnsureExecutableNode; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.GetIndexNode; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.TransformExceptionFromNativeNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPyFuncSignature; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlotWrapper; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyCloseAndGetHandleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyCloseArgHandlesNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyConvertArgsToSulongNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyGetNativeSpacePointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyAllAsHandleNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyGetBufferProcToSulongNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyGetNativeSpacePointerNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyGetSetGetterToSulongNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyGetSetSetterToSulongNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyKeywordsToSulongNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyReleaseBufferProcToSulongNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyRichcmpFuncArgsToSulongNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPySSizeArgFuncToSulongNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPySSizeObjArgProcToSulongNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyVarargsToSulongNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodesFactory.HPyCheckHandleResultNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodesFactory.HPyCheckPrimitiveResultNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodesFactory.HPyCheckVoidResultNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodesFactory.HPyExternalFunctionInvokeNodeGen; -import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.builtins.objects.function.Signature; -import com.oracle.graal.python.builtins.objects.memoryview.CExtPyBuffer; -import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotHPyNative; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRootNode; -import com.oracle.graal.python.nodes.argument.ReadIndexedArgumentNode; -import com.oracle.graal.python.nodes.argument.ReadVarArgsNode; -import com.oracle.graal.python.nodes.argument.ReadVarKeywordsNode; -import com.oracle.graal.python.runtime.ExecutionContext.CalleeContext; -import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext; -import com.oracle.graal.python.runtime.IndirectCallData; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.ArityException; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.interop.UnsupportedTypeException; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.strings.TruffleString; - -public abstract class HPyExternalFunctionNodes { - - public static final TruffleString KW_CALLABLE = tsLiteral("$callable"); - private static final TruffleString KW_CLOSURE = tsLiteral("$closure"); - private static final TruffleString KW_CONTEXT = tsLiteral("$context"); - private static final TruffleString[] KEYWORDS_HIDDEN_CONTEXT = {KW_CONTEXT}; - private static final TruffleString[] KEYWORDS_HIDDEN_CALLABLE = {KW_CONTEXT, KW_CALLABLE}; - private static final TruffleString[] KEYWORDS_HIDDEN_CALLABLE_AND_CLOSURE = {KW_CONTEXT, KW_CALLABLE, KW_CLOSURE}; - private static final Object[] KW_DEFAULTS = {PNone.NO_VALUE}; - - private static PKeyword[] createKwDefaults(GraalHPyContext context) { - return new PKeyword[]{new PKeyword(KW_CONTEXT, context)}; - } - - private static PKeyword[] createKwDefaults(Object callable, GraalHPyContext context) { - // return new PKeyword[]{new PKeyword(KW_CALLABLE, callable), new PKeyword(KW_CONTEXT, - // context)}; - return new PKeyword[]{new PKeyword(KW_CONTEXT, context), new PKeyword(KW_CALLABLE, callable)}; - } - - public static PKeyword[] createKwDefaults(Object callable, Object closure, GraalHPyContext context) { - // return new PKeyword[]{new PKeyword(KW_CALLABLE, callable), new PKeyword(KW_CONTEXT, - // context), new PKeyword(KW_CLOSURE, closure)}; - return new PKeyword[]{new PKeyword(KW_CONTEXT, context), new PKeyword(KW_CALLABLE, callable), new PKeyword(KW_CLOSURE, closure)}; - } - - /** - * Creates a built-in function that accepts the specified signatures, does appropriate argument - * and result conversion and calls the provided callable. - * - * @param language The Python language object. - * @param context The HPy context the new function object belongs to. This will also be the - * context that is passed to the native functions when they are called. - * @param signature The signature ID as defined in {@link GraalHPyDef}. - * @param name The name of the method. - * @param callable The native function pointer. - * @param enclosingType The type the function belongs to (needed for checking of {@code self}). - * @param factory Just an instance of {@link PythonObjectFactory} to create the function object. - * We could also use the uncached version but this way, the allocations are reported - * for the caller. - * @return A {@link PBuiltinFunction} that accepts the given signature. - */ - @TruffleBoundary - static PBuiltinFunction createWrapperFunction(PythonLanguage language, GraalHPyContext context, HPyFuncSignature signature, TruffleString name, Object callable, Object enclosingType, - PythonObjectFactory factory) { - assert InteropLibrary.getUncached(callable).isExecutable(callable) : "object is not callable"; - RootCallTarget callTarget = language.createCachedCallTarget(l -> createRootNode(l, signature, name), signature, name, true); - - Object[] defaults; - if (signature == HPyFuncSignature.TERNARYFUNC) { - // the third argument is optional - // so it has a default value (this implicitly is 'None') - defaults = KW_DEFAULTS; - } else { - defaults = PythonUtils.EMPTY_OBJECT_ARRAY; - } - int flags = HPyFuncSignature.getFlags(signature); - return factory.createBuiltinFunction(name, enclosingType, defaults, createKwDefaults(callable, context), flags, callTarget); - } - - private static PRootNode createRootNode(PythonLanguage language, HPyFuncSignature signature, TruffleString name) { - switch (signature) { - case NOARGS: - case UNARYFUNC: - case REPRFUNC: - case GETITERFUNC: - case ITERNEXTFUNC: - case DESTROYFUNC: - return new HPyMethNoargsRoot(language, name, false); - case O: - case BINARYFUNC: - return new HPyMethORoot(language, name, false); - case KEYWORDS: - return new HPyMethKeywordsRoot(language, name); - case INITPROC: - return new HPyMethInitProcRoot(language, name); - case VARARGS: - return new HPyMethVarargsRoot(language, name); - case TERNARYFUNC: - return new HPyMethTernaryRoot(language, name); - case LENFUNC: - return new HPyMethNoargsRoot(language, name, true); - case SSIZEOBJARGPROC: - return new HPyMethSSizeObjArgProcRoot(language, name); - case INQUIRY: - return new HPyMethInquiryRoot(language, name); - case SSIZEARGFUNC: - return new HPyMethSSizeArgFuncRoot(language, name); - case OBJOBJARGPROC: - return new HPyMethObjObjArgProcRoot(language, name); - case OBJOBJPROC: - return new HPyMethObjObjProcRoot(language, name); - default: - // TODO(fa): support remaining signatures - throw CompilerDirectives.shouldNotReachHere("unsupported HPy method signature: " + signature.name()); - } - } - - /** - * Creates a built-in function for a specific slot. This built-in function also does appropriate - * argument and result conversion and calls the provided callable. - * - * @param language The Python language object. - * @param wrapper The wrapper ID as defined in {@link HPySlotWrapper}. - * @param name The name of the method. - * @param callable The native function pointer. - * @param enclosingType The type the function belongs to (needed for checking of {@code self}). - * @param factory Just an instance of {@link PythonObjectFactory} to create the function object. - * @return A {@link PBuiltinFunction} implementing the semantics of the specified slot wrapper. - */ - @TruffleBoundary - public static PBuiltinFunction createWrapperFunction(PythonLanguage language, GraalHPyContext context, HPySlotWrapper wrapper, TpSlotHPyNative slot, PExternalFunctionWrapper legacySlotWrapper, - TruffleString name, Object callable, Object enclosingType, - PythonObjectFactory factory) { - assert InteropLibrary.getUncached(callable).isExecutable(callable) : "object is not callable"; - RootCallTarget callTarget = language.createCachedCallTarget(l -> createSlotRootNode(l, wrapper, name), wrapper, name); - Object[] defaults; - if (wrapper == HPySlotWrapper.TERNARYFUNC || wrapper == HPySlotWrapper.SQ_DELITEM) { - /* - * For TERNARYFUNC: The third argument is optional. So it has a default value (this - * implicitly is 'None'). For SQ_DELITEM: it's really the same as SQ_SETITEM but with a - * default. - */ - defaults = new Object[]{PNone.NO_VALUE}; - } else { - defaults = PythonUtils.EMPTY_OBJECT_ARRAY; - } - PKeyword[] kwDefaults; - if (wrapper == HPySlotWrapper.CALL) { - kwDefaults = createKwDefaults(context); - } else { - kwDefaults = createKwDefaults(callable, context); - - } - return factory.createWrapperDescriptor(name, enclosingType, defaults, kwDefaults, 0, callTarget, slot, legacySlotWrapper); - } - - private static PRootNode createSlotRootNode(PythonLanguage language, HPySlotWrapper wrapper, TruffleString name) { - switch (wrapper) { - case NULL: - return new HPyMethKeywordsRoot(language, name); - case UNARYFUNC: - return new HPyMethNoargsRoot(language, name, false); - case BINARYFUNC: - case BINARYFUNC_L: - return new HPyMethORoot(language, name, false); - case BINARYFUNC_R: - return new HPyMethReverseBinaryRoot(language, name, false); - case INIT: - return new HPyMethInitProcRoot(language, name); - case TERNARYFUNC: - return new HPyMethTernaryRoot(language, name); - case LENFUNC: - return new HPyMethNoargsRoot(language, name, true); - case INQUIRYPRED: - return new HPyMethInquiryRoot(language, name); - case INDEXARGFUNC: - return new HPyMethSSizeArgFuncRoot(language, name); - case OBJOBJARGPROC: - return new HPyMethObjObjArgProcRoot(language, name); - case OBJOBJPROC: - return new HPyMethObjObjProcRoot(language, name); - case SQ_ITEM: - return new HPyMethSqItemWrapperRoot(language, name); - case SQ_SETITEM: - case SQ_DELITEM: - // SQ_DELITEM is really the same as SQ_SETITEM but with a default - return new HPyMethSqSetitemWrapperRoot(language, name); - case RICHCMP_LT: - case RICHCMP_LE: - case RICHCMP_EQ: - case RICHCMP_NE: - case RICHCMP_GT: - case RICHCMP_GE: - return new HPyMethRichcmpOpRootNode(language, name, getCompareOpCode(wrapper)); - case GETBUFFER: - return new HPyGetBufferRootNode(language, name); - case RELEASEBUFFER: - return new HPyReleaseBufferRootNode(language, name); - case HASHFUNC: - return new HPyMethHashRoot(language, name); - case CALL: - return new HPyMethCallRoot(language, name); - default: - // TODO(fa): support remaining slot wrappers - throw CompilerDirectives.shouldNotReachHere("unsupported HPy slot wrapper: wrap_" + wrapper.name().toLowerCase()); - } - - } - - /** - * Resolve the requested slot wrapper to the numeric op code as defined by HPy's enum - * {@code HPy_RichCmpOp}. - */ - private static int getCompareOpCode(HPySlotWrapper sig) { - // op codes for binary comparisons (defined in 'object.h') - switch (sig) { - case RICHCMP_LT: - return 0; - case RICHCMP_LE: - return 1; - case RICHCMP_EQ: - return 2; - case RICHCMP_NE: - return 3; - case RICHCMP_GT: - return 4; - case RICHCMP_GE: - return 5; - } - throw CompilerDirectives.shouldNotReachHere(); - } - - /** - * Invokes an HPy C function. It takes care of argument and result conversion and always passes - * the HPy context as a first parameter. - */ - public abstract static class HPyExternalFunctionInvokeNode extends Node { - - @Child private HPyConvertArgsToSulongNode toSulongNode; - @Child private HPyCheckFunctionResultNode checkFunctionResultNode; - @Child private HPyCloseArgHandlesNode handleCloseNode; - - HPyExternalFunctionInvokeNode() { - CompilerAsserts.neverPartOfCompilation(); - this.toSulongNode = HPyAllAsHandleNodeGen.create(); - this.checkFunctionResultNode = HPyCheckHandleResultNodeGen.create(); - this.handleCloseNode = this.toSulongNode.createCloseHandleNode(); - } - - HPyExternalFunctionInvokeNode(HPyConvertArgsToSulongNode convertArgsNode) { - CompilerAsserts.neverPartOfCompilation(); - this.toSulongNode = convertArgsNode != null ? convertArgsNode : HPyAllAsHandleNodeGen.create(); - this.checkFunctionResultNode = HPyCheckHandleResultNodeGen.create(); - this.handleCloseNode = this.toSulongNode.createCloseHandleNode(); - } - - HPyExternalFunctionInvokeNode(HPyCheckFunctionResultNode checkFunctionResultNode, HPyConvertArgsToSulongNode convertArgsNode) { - CompilerAsserts.neverPartOfCompilation(); - this.toSulongNode = convertArgsNode != null ? convertArgsNode : HPyAllAsHandleNodeGen.create(); - this.checkFunctionResultNode = checkFunctionResultNode != null ? checkFunctionResultNode : HPyCheckHandleResultNodeGen.create(); - this.handleCloseNode = this.toSulongNode.createCloseHandleNode(); - } - - public abstract Object execute(VirtualFrame frame, TruffleString name, Object callable, GraalHPyContext hPyContext, Object[] frameArgs); - - @Specialization(limit = "1") - Object doIt(VirtualFrame frame, TruffleString name, Object callable, GraalHPyContext hPyContext, Object[] arguments, - @Cached("createFor(this)") IndirectCallData indirectCallData, - @CachedLibrary("callable") InteropLibrary lib, - @Cached PRaiseNode raiseNode) { - Object[] convertedArguments = new Object[arguments.length + 1]; - toSulongNode.executeInto(frame, arguments, 0, convertedArguments, 1); - - // first arg is always the HPyContext - convertedArguments[0] = hPyContext.getBackend(); - - PythonContext ctx = hPyContext.getContext(); - PythonLanguage language = ctx.getLanguage(this); - PythonThreadState pythonThreadState = ctx.getThreadState(language); - - // If any code requested the caught exception (i.e. used 'sys.exc_info()'), we store - // it to the context since we cannot propagate it through the native frames. - Object state = IndirectCallContext.enter(frame, pythonThreadState, indirectCallData); - - try { - return checkFunctionResultNode.execute(pythonThreadState, name, lib.execute(callable, convertedArguments)); - } catch (UnsupportedTypeException | UnsupportedMessageException e) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.CALLING_NATIVE_FUNC_FAILED, name, e); - } catch (ArityException e) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.CALLING_NATIVE_FUNC_EXPECTED_ARGS, name, e.getExpectedMinArity(), e.getActualArity()); - } finally { - // special case after calling a C function: transfer caught exception back to frame - // to simulate the global state semantics - PArguments.setException(frame, pythonThreadState.getCaughtException()); - IndirectCallContext.exit(frame, pythonThreadState, state); - - // close all handles (if necessary) - if (handleCloseNode != null) { - handleCloseNode.executeInto(frame, convertedArguments, 1); - } - } - } - } - - abstract static class HPyMethodDescriptorRootNode extends PRootNode { - @Child private CalleeContext calleeContext; - @Child private HPyExternalFunctionInvokeNode invokeNode; - @Child private ReadIndexedArgumentNode readSelfNode; - @Child private ReadIndexedArgumentNode readCallableNode; - @Child private ReadIndexedArgumentNode readContextNode; - - private final TruffleString name; - - @TruffleBoundary - public HPyMethodDescriptorRootNode(PythonLanguage language, TruffleString name, HPyConvertArgsToSulongNode convertArgsToSulongNode) { - super(language); - this.name = name; - this.invokeNode = HPyExternalFunctionInvokeNodeGen.create(convertArgsToSulongNode); - } - - @TruffleBoundary - public HPyMethodDescriptorRootNode(PythonLanguage language, TruffleString name, HPyCheckFunctionResultNode checkFunctionResultNode, HPyConvertArgsToSulongNode convertArgsToSulongNode) { - super(language); - this.name = name; - this.invokeNode = HPyExternalFunctionInvokeNodeGen.create(checkFunctionResultNode, convertArgsToSulongNode); - } - - protected static Object intToBoolean(Object result) { - if (result instanceof Integer) { - return ((Integer) result) != 0; - } else if (result instanceof Long) { - return ((Long) result) != 0; - } - throw CompilerDirectives.shouldNotReachHere(); - } - - @Override - public Object execute(VirtualFrame frame) { - Object callable = ensureReadCallableNode().execute(frame); - GraalHPyContext hpyContext = readContext(frame); - Object[] cArguments = prepareCArguments(frame, hpyContext); - getCalleeContext().enter(frame); - try { - return processResult(frame, invokeNode.execute(frame, name, callable, hpyContext, cArguments)); - } finally { - getCalleeContext().exit(frame, this); - closeCArguments(frame, hpyContext, cArguments); - } - } - - protected abstract Object[] prepareCArguments(VirtualFrame frame, GraalHPyContext hpyContext); - - protected Object processResult(@SuppressWarnings("unused") VirtualFrame frame, Object result) { - return result; - } - - @SuppressWarnings("unused") - protected void closeCArguments(VirtualFrame frame, GraalHPyContext hpyContext, Object[] cArguments) { - // nothing to do by default - } - - protected final HPyExternalFunctionInvokeNode getInvokeNode() { - return invokeNode; - } - - protected final Object getSelf(VirtualFrame frame) { - if (readSelfNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readSelfNode = insert(ReadIndexedArgumentNode.create(0)); - } - return readSelfNode.execute(frame); - } - - protected final CalleeContext getCalleeContext() { - if (calleeContext == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - calleeContext = insert(CalleeContext.create()); - } - return calleeContext; - } - - protected final ReadIndexedArgumentNode ensureReadCallableNode() { - if (readCallableNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - // we insert a hidden argument after the hidden context argument - int hiddenArg = getSignature().getParameterIds().length + 1; - readCallableNode = insert(ReadIndexedArgumentNode.create(hiddenArg)); - } - return readCallableNode; - } - - protected final GraalHPyContext readContext(VirtualFrame frame) { - if (readContextNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - // we insert a hidden argument at the end of the positional arguments - int hiddenArg = getSignature().getParameterIds().length; - readContextNode = insert(ReadIndexedArgumentNode.create(hiddenArg)); - } - Object hpyContext = readContextNode.execute(frame); - if (hpyContext instanceof GraalHPyContext) { - return (GraalHPyContext) hpyContext; - } - throw CompilerDirectives.shouldNotReachHere("invalid HPy context"); - } - - @Override - public String getName() { - return name.toJavaStringUncached(); - } - - public TruffleString getTSName() { - return name; - } - - @Override - public String toString() { - return ""; - } - - @Override - public boolean isInternal() { - return true; - } - - @Override - public boolean isPythonInternal() { - return true; - } - - @Override - public boolean setsUpCalleeContext() { - return true; - } - } - - static final class HPyMethNoargsRoot extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(1, false, -1, false, tsArray("self"), KEYWORDS_HIDDEN_CALLABLE, true); - - public HPyMethNoargsRoot(PythonLanguage language, TruffleString name, boolean nativePrimitiveResult) { - super(language, name, nativePrimitiveResult ? HPyCheckPrimitiveResultNodeGen.create() : HPyCheckHandleResultNodeGen.create(), HPyAllAsHandleNodeGen.create()); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, @SuppressWarnings("unused") GraalHPyContext hpyContext) { - return new Object[]{getSelf(frame)}; - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - static final class HPyMethORoot extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(-1, false, -1, false, tsArray("self", "arg"), KEYWORDS_HIDDEN_CALLABLE, true); - - @Child private ReadIndexedArgumentNode readArgNode; - - public HPyMethORoot(PythonLanguage language, TruffleString name, boolean nativePrimitiveResult) { - super(language, name, nativePrimitiveResult ? HPyCheckPrimitiveResultNodeGen.create() : HPyCheckHandleResultNodeGen.create(), HPyAllAsHandleNodeGen.create()); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, @SuppressWarnings("unused") GraalHPyContext hpyContext) { - return new Object[]{getSelf(frame), getArg(frame)}; - } - - private Object getArg(VirtualFrame frame) { - if (readArgNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readArgNode = insert(ReadIndexedArgumentNode.create(1)); - } - return readArgNode.execute(frame); - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - static final class HPyMethVarargsRoot extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(-1, false, 1, false, tsArray("self"), KEYWORDS_HIDDEN_CALLABLE, true); - - @Child private ReadVarArgsNode readVarargsNode; - - @TruffleBoundary - public HPyMethVarargsRoot(PythonLanguage language, TruffleString name) { - super(language, name, HPyVarargsToSulongNodeGen.create()); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, GraalHPyContext hpyContext) { - Object[] args = getVarargs(frame); - return new Object[]{getSelf(frame), hpyContext.createArgumentsArray(args), (long) args.length}; - } - - @Override - protected void closeCArguments(VirtualFrame frame, GraalHPyContext hpyContext, Object[] cArguments) { - hpyContext.freeArgumentsArray(cArguments[1]); - } - - private Object[] getVarargs(VirtualFrame frame) { - if (readVarargsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readVarargsNode = insert(ReadVarArgsNode.create(true)); - } - return readVarargsNode.executeObjectArray(frame); - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - static final class HPyMethKeywordsRoot extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(-1, true, 1, false, tsArray("self"), KEYWORDS_HIDDEN_CALLABLE, true); - - @Child private ReadVarArgsNode readVarargsNode; - @Child private ReadVarKeywordsNode readKwargsNode; - @Child private PythonObjectFactory factory; - - @TruffleBoundary - public HPyMethKeywordsRoot(PythonLanguage language, TruffleString name) { - super(language, name, HPyKeywordsToSulongNodeGen.create()); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, GraalHPyContext hpyContext) { - Object[] positionalArgs = getVarargs(frame); - PKeyword[] keywords = getKwargs(frame); - long nPositionalArgs = positionalArgs.length; - - Object[] args; - Object kwnamesTuple; - // this condition is implicitly profiled by 'getKwnamesTuple' - if (keywords.length > 0) { - args = PythonUtils.arrayCopyOf(positionalArgs, positionalArgs.length + keywords.length); - TruffleString[] kwnames = new TruffleString[keywords.length]; - for (int i = 0; i < keywords.length; i++) { - args[positionalArgs.length + i] = keywords[i].getValue(); - kwnames[i] = keywords[i].getName(); - } - kwnamesTuple = getKwnamesTuple(kwnames); - } else { - args = positionalArgs; - kwnamesTuple = GraalHPyHandle.NULL_HANDLE_DELEGATE; - } - return new Object[]{getSelf(frame), createArgumentsArray(hpyContext, args), nPositionalArgs, kwnamesTuple}; - } - - @Override - protected void closeCArguments(VirtualFrame frame, GraalHPyContext hpyContext, Object[] cArguments) { - hpyContext.freeArgumentsArray(cArguments[1]); - } - - private Object createArgumentsArray(GraalHPyContext hpyContext, Object[] args) { - return hpyContext.createArgumentsArray(args); - } - - private Object[] getVarargs(VirtualFrame frame) { - if (readVarargsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readVarargsNode = insert(ReadVarArgsNode.create(true)); - } - return readVarargsNode.executeObjectArray(frame); - } - - private PKeyword[] getKwargs(VirtualFrame frame) { - if (PArguments.getKeywordArguments(frame).length == 0) { - return PKeyword.EMPTY_KEYWORDS; - } - if (readKwargsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readKwargsNode = insert(ReadVarKeywordsNode.create()); - } - return (PKeyword[]) readKwargsNode.execute(frame); - } - - private PTuple getKwnamesTuple(TruffleString[] kwnames) { - if (factory == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - factory = insert(PythonObjectFactory.create()); - } - return factory.createTuple(kwnames); - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - static final class HPyMethInitProcRoot extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(-1, true, 1, false, tsArray("self"), KEYWORDS_HIDDEN_CALLABLE, true); - - @Child private ReadVarArgsNode readVarargsNode; - @Child private ReadVarKeywordsNode readKwargsNode; - - @TruffleBoundary - public HPyMethInitProcRoot(PythonLanguage language, TruffleString name) { - super(language, name, HPyCheckPrimitiveResultNodeGen.create(), HPyKeywordsToSulongNodeGen.create()); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, GraalHPyContext hpyContext) { - Object[] args = getVarargs(frame); - return new Object[]{getSelf(frame), hpyContext.createArgumentsArray(args), (long) args.length, getKwargs(frame)}; - } - - @Override - protected void closeCArguments(VirtualFrame frame, GraalHPyContext hpyContext, Object[] cArguments) { - hpyContext.freeArgumentsArray(cArguments[1]); - } - - @Override - @SuppressWarnings("unused") - protected Object processResult(VirtualFrame frame, Object result) { - // If no error occurred, the init function always returns None. - // Possible errors are already handled in the HPyExternalFunctionInvokeNode. - return PNone.NONE; - } - - private Object[] getVarargs(VirtualFrame frame) { - if (readVarargsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readVarargsNode = insert(ReadVarArgsNode.create(true)); - } - return readVarargsNode.executeObjectArray(frame); - } - - private Object getKwargs(VirtualFrame frame) { - if (readKwargsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readKwargsNode = insert(ReadVarKeywordsNode.createForUserFunction(EMPTY_TRUFFLESTRING_ARRAY)); - } - return readKwargsNode.execute(frame); - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - static final class HPyMethTernaryRoot extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(3, false, -1, false, tsArray("x", "y", "z"), KEYWORDS_HIDDEN_CALLABLE, true); - - @Child private ReadIndexedArgumentNode readArg1Node; - @Child private ReadIndexedArgumentNode readArg2Node; - - public HPyMethTernaryRoot(PythonLanguage language, TruffleString name) { - super(language, name, HPyAllAsHandleNodeGen.create()); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, @SuppressWarnings("unused") GraalHPyContext hpyContext) { - return new Object[]{getSelf(frame), getArg1(frame), getArg2(frame)}; - } - - private Object getArg1(VirtualFrame frame) { - if (readArg1Node == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readArg1Node = insert(ReadIndexedArgumentNode.create(1)); - } - return readArg1Node.execute(frame); - } - - private Object getArg2(VirtualFrame frame) { - if (readArg2Node == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readArg2Node = insert(ReadIndexedArgumentNode.create(2)); - } - Object arg2 = readArg2Node.execute(frame); - return arg2 != PNone.NO_VALUE ? arg2 : PNone.NONE; - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - static class HPyMethSSizeArgFuncRoot extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(2, false, -1, false, tsArray("$self", "n"), KEYWORDS_HIDDEN_CALLABLE, true); - - @Child private ReadIndexedArgumentNode readArg1Node; - - public HPyMethSSizeArgFuncRoot(PythonLanguage language, TruffleString name) { - super(language, name, HPySSizeArgFuncToSulongNodeGen.create()); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, @SuppressWarnings("unused") GraalHPyContext hpyContext) { - return new Object[]{getSelf(frame), getArg1(frame)}; - } - - protected Object getArg1(VirtualFrame frame) { - if (readArg1Node == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readArg1Node = insert(ReadIndexedArgumentNode.create(1)); - } - return readArg1Node.execute(frame); - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - /** - * Implements semantics of {@code typeobject.c: wrap_sq_item}. - */ - static final class HPyMethSqItemWrapperRoot extends HPyMethSSizeArgFuncRoot { - - @Child private GetIndexNode getIndexNode; - - public HPyMethSqItemWrapperRoot(PythonLanguage language, TruffleString name) { - super(language, name); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, @SuppressWarnings("unused") GraalHPyContext hpyContext) { - Object self = getSelf(frame); - return new Object[]{self, getIndex(self, getArg1(frame))}; - } - - private int getIndex(Object self, Object index) { - if (getIndexNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - getIndexNode = insert(CExtCommonNodes.GetIndexNode.create()); - } - return getIndexNode.execute(self, index); - } - } - - /** - * Implements semantics of {@code typeobject.c: wrap_sq_setitem}. - */ - static final class HPyMethSqSetitemWrapperRoot extends HPyMethSSizeObjArgProcRoot { - - @Child private GetIndexNode getIndexNode; - - public HPyMethSqSetitemWrapperRoot(PythonLanguage language, TruffleString name) { - super(language, name); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, @SuppressWarnings("unused") GraalHPyContext hpyContext) { - Object self = getSelf(frame); - return new Object[]{self, getIndex(self, getArg1(frame)), getArg2(frame)}; - } - - private int getIndex(Object self, Object index) { - if (getIndexNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - getIndexNode = insert(CExtCommonNodes.GetIndexNode.create()); - } - return getIndexNode.execute(self, index); - } - } - - static final class HPyMethSSizeSSizeArgFuncRoot extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(3, false, -1, false, tsArray("$self", "n", "m"), KEYWORDS_HIDDEN_CALLABLE, true); - - @Child private ReadIndexedArgumentNode readArg1Node; - @Child private ReadIndexedArgumentNode readArg2Node; - - public HPyMethSSizeSSizeArgFuncRoot(PythonLanguage language, TruffleString name) { - super(language, name, HPySSizeArgFuncToSulongNodeGen.create()); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, @SuppressWarnings("unused") GraalHPyContext hpyContext) { - return new Object[]{getSelf(frame), getArg1(frame), getArg2(frame)}; - } - - private Object getArg1(VirtualFrame frame) { - if (readArg1Node == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readArg1Node = insert(ReadIndexedArgumentNode.create(1)); - } - return readArg1Node.execute(frame); - } - - private Object getArg2(VirtualFrame frame) { - if (readArg2Node == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readArg2Node = insert(ReadIndexedArgumentNode.create(2)); - } - return readArg2Node.execute(frame); - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - /** - * Very similar to {@link HPyMethNoargsRoot} but converts the result to a boolean. - */ - static final class HPyMethInquiryRoot extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(-1, false, -1, false, tsArray("self"), KEYWORDS_HIDDEN_CALLABLE); - - public HPyMethInquiryRoot(PythonLanguage language, TruffleString name) { - super(language, name, HPyCheckPrimitiveResultNodeGen.create(), HPyAllAsHandleNodeGen.create()); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, @SuppressWarnings("unused") GraalHPyContext hpyContext) { - return new Object[]{getSelf(frame)}; - } - - @Override - protected Object processResult(VirtualFrame frame, Object result) { - // 'HPyCheckPrimitiveResultNode' already guarantees that the result is 'int' or 'long'. - return intToBoolean(result); - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - static final class HPyMethObjObjArgProcRoot extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(-1, false, 1, false, tsArray("$self", "x"), KEYWORDS_HIDDEN_CALLABLE, true); - - @Child private ReadIndexedArgumentNode readArg1Node; - @Child private ReadVarArgsNode readVarargsNode; - @Child private PRaiseNode raiseNode; - - public HPyMethObjObjArgProcRoot(PythonLanguage language, TruffleString name) { - super(language, name, HPyCheckPrimitiveResultNodeGen.create(), HPyAllAsHandleNodeGen.create()); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, @SuppressWarnings("unused") GraalHPyContext hpyContext) { - Object[] varargs = getVarargs(frame); - if (varargs.length == 0) { - return new Object[]{getSelf(frame), getArg1(frame), PNone.NO_VALUE}; - } else if (varargs.length == 1) { - return new Object[]{getSelf(frame), getArg1(frame), varargs[0]}; - } else { - throw getRaiseNode().raise(PythonBuiltinClassType.TypeError, - ErrorMessages.TAKES_FROM_D_TO_D_POS_ARG_S_BUT_D_S_GIVEN_S, - getName(), 2, 3, "s", 1 + varargs.length, "were", ""); - } - } - - private PRaiseNode getRaiseNode() { - if (raiseNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - raiseNode = insert(PRaiseNode.create()); - } - return raiseNode; - } - - private Object[] getVarargs(VirtualFrame frame) { - if (readVarargsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readVarargsNode = insert(ReadVarArgsNode.create(true)); - } - return readVarargsNode.executeObjectArray(frame); - } - - private Object getArg1(VirtualFrame frame) { - if (readArg1Node == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readArg1Node = insert(ReadIndexedArgumentNode.create(1)); - } - return readArg1Node.execute(frame); - } - - @Override - protected Object processResult(VirtualFrame frame, Object result) { - // 'HPyCheckPrimitiveResultNode' already guarantees that the result is 'int' or 'long'. - return intToBoolean(result); - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - static final class HPyMethObjObjProcRoot extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(2, false, -1, false, tsArray("$self", "other"), KEYWORDS_HIDDEN_CALLABLE, true); - - @Child private ReadIndexedArgumentNode readArg1Node; - - public HPyMethObjObjProcRoot(PythonLanguage language, TruffleString name) { - super(language, name, HPyCheckPrimitiveResultNodeGen.create(), HPyAllAsHandleNodeGen.create()); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, @SuppressWarnings("unused") GraalHPyContext hpyContext) { - return new Object[]{getSelf(frame), getArg1(frame)}; - } - - private Object getArg1(VirtualFrame frame) { - if (readArg1Node == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readArg1Node = insert(ReadIndexedArgumentNode.create(1)); - } - return readArg1Node.execute(frame); - } - - @Override - protected Object processResult(VirtualFrame frame, Object result) { - // 'HPyCheckPrimitiveResultNode' already guarantees that the result is 'int' or 'long'. - return intToBoolean(result); - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - static class HPyMethSSizeObjArgProcRoot extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(3, false, -1, false, tsArray("$self", "arg0", "arg1"), KEYWORDS_HIDDEN_CALLABLE, true); - - @Child private ReadIndexedArgumentNode readArg1Node; - @Child private ReadIndexedArgumentNode readArg2Node; - - public HPyMethSSizeObjArgProcRoot(PythonLanguage language, TruffleString name) { - super(language, name, HPyCheckPrimitiveResultNodeGen.create(), HPySSizeObjArgProcToSulongNodeGen.create()); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, @SuppressWarnings("unused") GraalHPyContext hpyContext) { - return new Object[]{getSelf(frame), getArg1(frame), getArg2(frame)}; - } - - protected Object getArg1(VirtualFrame frame) { - if (readArg1Node == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readArg1Node = insert(ReadIndexedArgumentNode.create(1)); - } - return readArg1Node.execute(frame); - } - - protected Object getArg2(VirtualFrame frame) { - if (readArg2Node == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readArg2Node = insert(ReadIndexedArgumentNode.create(2)); - } - return readArg2Node.execute(frame); - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - static final class HPyMethReverseBinaryRoot extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(-1, false, -1, false, tsArray("self", "other"), KEYWORDS_HIDDEN_CALLABLE, true); - - @Child private ReadIndexedArgumentNode readOtherNode; - - public HPyMethReverseBinaryRoot(PythonLanguage language, TruffleString name, boolean nativePrimitiveResult) { - super(language, name, nativePrimitiveResult ? HPyCheckPrimitiveResultNodeGen.create() : HPyCheckHandleResultNodeGen.create(), HPyAllAsHandleNodeGen.create()); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, @SuppressWarnings("unused") GraalHPyContext hpyContext) { - return new Object[]{getOther(frame), getSelf(frame)}; - } - - private Object getOther(VirtualFrame frame) { - if (readOtherNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readOtherNode = insert(ReadIndexedArgumentNode.create(1)); - } - return readOtherNode.execute(frame); - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - public abstract static class HPyCheckFunctionResultNode extends Node { - - public abstract Object execute(PythonThreadState pythonThreadState, TruffleString name, Object value); - } - - // roughly equivalent to _Py_CheckFunctionResult in Objects/call.c - @GenerateUncached - @GenerateInline(false) - @ImportStatic(PGuards.class) - public abstract static class HPyCheckHandleResultNode extends HPyCheckFunctionResultNode { - - @Specialization - static Object doLongNull(PythonThreadState pythonThreadState, TruffleString name, Object value, - @Bind("this") Node inliningTarget, - @Cached HPyCloseAndGetHandleNode closeAndGetHandleNode, - @Cached TransformExceptionFromNativeNode transformExceptionFromNativeNode) { - Object delegate = closeAndGetHandleNode.execute(inliningTarget, value); - transformExceptionFromNativeNode.execute(inliningTarget, pythonThreadState, name, delegate == GraalHPyHandle.NULL_HANDLE_DELEGATE, true); - return delegate; - } - } - - /** - * Similar to {@link HPyCheckFunctionResultNode}, this node checks a primitive result of a - * native function. This node guarantees that an {@code int} or {@code long} is returned. - */ - @GenerateUncached - @GenerateInline(false) - @ImportStatic(PGuards.class) - abstract static class HPyCheckPrimitiveResultNode extends HPyCheckFunctionResultNode { - public abstract int executeInt(PythonThreadState context, TruffleString name, int value); - - public abstract long executeLong(PythonThreadState context, TruffleString name, long value); - - @Specialization - static int doInteger(PythonThreadState pythonThreadState, TruffleString name, int value, - @Bind("this") Node inliningTarget, - @Shared @Cached TransformExceptionFromNativeNode transformExceptionFromNativeNode) { - transformExceptionFromNativeNode.execute(inliningTarget, pythonThreadState, name, value == -1, false); - return value; - } - - @Specialization(replaces = "doInteger") - static long doLong(PythonThreadState pythonThreadState, TruffleString name, long value, - @Bind("this") Node inliningTarget, - @Shared @Cached TransformExceptionFromNativeNode transformExceptionFromNativeNode) { - transformExceptionFromNativeNode.execute(inliningTarget, pythonThreadState, name, value == -1, false); - return value; - } - - @Specialization(limit = "1") - static Object doObject(PythonThreadState pythonThreadState, TruffleString name, Object value, - @Bind("this") Node inliningTarget, - @CachedLibrary("value") InteropLibrary lib, - @Shared @Cached PRaiseNode.Lazy raiseNode, - @Shared @Cached TransformExceptionFromNativeNode transformExceptionFromNativeNode) { - if (lib.fitsInLong(value)) { - try { - long lvalue = lib.asLong(value); - transformExceptionFromNativeNode.execute(inliningTarget, pythonThreadState, name, lvalue == -1, false); - return lvalue; - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } - throw raiseNode.get(inliningTarget).raise(SystemError, ErrorMessages.FUNC_S_DIDNT_RETURN_INT, name); - } - } - - /** - * Does not actually check the result of a function (since this is used when {@code void} - * functions are called) but checks if an error occurred during execution of the function. - */ - @GenerateUncached - @GenerateInline(false) - @ImportStatic(PGuards.class) - abstract static class HPyCheckVoidResultNode extends HPyCheckFunctionResultNode { - - @Specialization - static Object doGeneric(PythonThreadState threadState, TruffleString name, Object value, - @Bind("this") Node inliningTarget, - @Cached TransformExceptionFromNativeNode transformExceptionFromNativeNode) { - /* - * A 'void' function never indicates an error but an error could still happen. So this - * must also be checked. The actual result value (which will be something like NULL or - * 0) is not used. - */ - transformExceptionFromNativeNode.execute(inliningTarget, threadState, name, false, true); - return value; - } - } - - static final class HPyMethRichcmpOpRootNode extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(-1, false, -1, false, tsArray("self", "other"), KEYWORDS_HIDDEN_CALLABLE, true); - @Child private ReadIndexedArgumentNode readArgNode; - - private final int op; - - HPyMethRichcmpOpRootNode(PythonLanguage language, TruffleString name, int op) { - super(language, name, HPyRichcmpFuncArgsToSulongNodeGen.create()); - this.readArgNode = ReadIndexedArgumentNode.create(1); - this.op = op; - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, @SuppressWarnings("unused") GraalHPyContext hpyContext) { - return new Object[]{getSelf(frame), readArgNode.execute(frame), op}; - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - /** - * A simple and lightweight Python root node that invokes a native getter function. The native - * call target and the native closure pointer are passed as Python closure. - */ - abstract static class HPyGetSetDescriptorRootNode extends PRootNode { - - @Child private CalleeContext calleeContext; - @Child private HPyExternalFunctionInvokeNode invokeNode; - @Child private ReadIndexedArgumentNode readCallableNode; - @Child private ReadIndexedArgumentNode readContextNode; - @Child private ReadIndexedArgumentNode readClosureNode; - - private final TruffleString name; - - HPyGetSetDescriptorRootNode(PythonLanguage language, TruffleString name) { - super(language); - this.name = name; - } - - @Override - public Object execute(VirtualFrame frame) { - getCalleeContext().enter(frame); - try { - Object target = readCallable(frame); - GraalHPyContext hpyContext = readContext(frame); - Object closure = readClosure(frame); - return ensureInvokeNode().execute(frame, name, target, hpyContext, createArguments(frame, closure)); - } finally { - getCalleeContext().exit(frame, this); - } - } - - protected abstract HPyConvertArgsToSulongNode createArgumentConversionNode(); - - protected abstract HPyCheckFunctionResultNode createResultConversionNode(); - - protected abstract Object[] createArguments(VirtualFrame frame, Object closure); - - @Override - public String getName() { - return name.toJavaStringUncached(); - } - - private CalleeContext getCalleeContext() { - if (calleeContext == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - calleeContext = insert(CalleeContext.create()); - } - return calleeContext; - } - - private HPyExternalFunctionInvokeNode ensureInvokeNode() { - if (invokeNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - invokeNode = insert(HPyExternalFunctionInvokeNodeGen.create(createResultConversionNode(), createArgumentConversionNode())); - } - return invokeNode; - } - - protected final Object readCallable(VirtualFrame frame) { - if (readCallableNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - // we insert a hidden argument after the hidden context argument - int hiddenArg = getSignature().getParameterIds().length + 1; - readCallableNode = insert(ReadIndexedArgumentNode.create(hiddenArg)); - } - return readCallableNode.execute(frame); - } - - private GraalHPyContext readContext(VirtualFrame frame) { - if (readContextNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - // we insert a hidden argument at the end of the positional arguments - int hiddenArg = getSignature().getParameterIds().length; - readContextNode = insert(ReadIndexedArgumentNode.create(hiddenArg)); - } - Object hpyContext = readContextNode.execute(frame); - if (hpyContext instanceof GraalHPyContext) { - return (GraalHPyContext) hpyContext; - } - throw CompilerDirectives.shouldNotReachHere("invalid HPy context"); - } - - protected final Object readClosure(VirtualFrame frame) { - if (readClosureNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - // we insert a hidden closure argument after the hidden context arg - int hiddenArg = getSignature().getParameterIds().length + 2; - readClosureNode = insert(ReadIndexedArgumentNode.create(hiddenArg)); - } - return readClosureNode.execute(frame); - } - - @Override - public boolean isPythonInternal() { - return true; - } - - @Override - public boolean isInternal() { - return true; - } - - @Override - public boolean setsUpCalleeContext() { - return true; - } - } - - /** - * A simple and lightweight Python root node that invokes a native getter function. The native - * call target and the native closure pointer are passed as Python closure. - */ - static final class HPyGetSetDescriptorGetterRootNode extends HPyGetSetDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(-1, false, -1, false, tsArray("$self"), KEYWORDS_HIDDEN_CALLABLE_AND_CLOSURE, true); - - HPyGetSetDescriptorGetterRootNode(PythonLanguage language, TruffleString name) { - super(language, name); - } - - @Override - protected Object[] createArguments(VirtualFrame frame, Object closure) { - return new Object[]{PArguments.getArgument(frame, 0), closure}; - } - - @Override - protected HPyConvertArgsToSulongNode createArgumentConversionNode() { - return HPyGetSetGetterToSulongNodeGen.create(); - } - - @Override - protected HPyCheckFunctionResultNode createResultConversionNode() { - return HPyCheckHandleResultNodeGen.create(); - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - - @TruffleBoundary - public static PBuiltinFunction createFunction(GraalHPyContext hpyContext, Object enclosingType, TruffleString propertyName, Object target, Object closure) { - PythonContext pythonContext = hpyContext.getContext(); - PythonLanguage lang = pythonContext.getLanguage(); - RootCallTarget callTarget = lang.createCachedCallTarget(l -> new HPyGetSetDescriptorGetterRootNode(l, propertyName), HPyGetSetDescriptorGetterRootNode.class, propertyName); - PythonObjectFactory factory = pythonContext.getCore().factory(); - return factory.createBuiltinFunction(propertyName, enclosingType, PythonUtils.EMPTY_OBJECT_ARRAY, createKwDefaults(target, closure, hpyContext), 0, callTarget); - } - } - - static final class HPyLegacyGetSetDescriptorGetterRoot extends GetterRoot { - - @Child private HPyGetNativeSpacePointerNode getNativeSpacePointerNode; - - protected HPyLegacyGetSetDescriptorGetterRoot(PythonLanguage language, TruffleString name, PExternalFunctionWrapper provider) { - super(language, name, provider); - } - - /* - * TODO(fa): It's still unclear how to handle HPy native space pointers when passed to an - * 'AsPythonObjectNode'. This can happen when, e.g., the getter returns the 'self' pointer. - */ - @Override - protected Object[] prepareCArguments(VirtualFrame frame) { - Object[] objects = super.prepareCArguments(frame); - if (getNativeSpacePointerNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - getNativeSpacePointerNode = insert(HPyGetNativeSpacePointerNodeGen.create()); - } - /* - * We now need to pass the native space pointer in a way that the PythonToNativeNode - * correctly exposes the bare pointer object. For this, we pack the pointer into a - * PythonAbstractNativeObject which will just be unwrapped. - */ - Object nativeSpacePtr = getNativeSpacePointerNode.executeCached(objects[0]); - if (nativeSpacePtr == PNone.NO_VALUE) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(this, SystemError, ErrorMessages.ATTEMPTING_GETTER_NO_NATIVE_SPACE); - } - objects[0] = new PythonAbstractNativeObject(nativeSpacePtr); - return objects; - } - - @TruffleBoundary - public static PBuiltinFunction createLegacyFunction(GraalHPyContext context, PythonLanguage lang, Object owner, TruffleString propertyName, Object target, Object closure) { - PythonContext pythonContext = context.getContext(); - PythonObjectFactory factory = pythonContext.factory(); - RootCallTarget rootCallTarget = lang.createCachedCallTarget(l -> new HPyLegacyGetSetDescriptorGetterRoot(l, propertyName, PExternalFunctionWrapper.GETTER), - HPyLegacyGetSetDescriptorGetterRoot.class, propertyName); - if (rootCallTarget == null) { - throw CompilerDirectives.shouldNotReachHere("Calling non-native get descriptor functions is not support in HPy"); - } - target = EnsureExecutableNode.executeUncached(target, PExternalFunctionWrapper.GETTER); - return factory.createBuiltinFunction(propertyName, owner, PythonUtils.EMPTY_OBJECT_ARRAY, ExternalFunctionNodes.createKwDefaults(target, closure), 0, rootCallTarget); - } - } - - /** - * A simple and lightweight Python root node that invokes a native setter function. The native - * call target and the native closure pointer are passed as Python closure. - */ - static final class HPyGetSetDescriptorSetterRootNode extends HPyGetSetDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(-1, false, -1, false, tsArray("$self", "value"), KEYWORDS_HIDDEN_CALLABLE_AND_CLOSURE, true); - - private HPyGetSetDescriptorSetterRootNode(PythonLanguage language, TruffleString name) { - super(language, name); - } - - @Override - protected Object[] createArguments(VirtualFrame frame, Object closure) { - return new Object[]{PArguments.getArgument(frame, 0), PArguments.getArgument(frame, 1), closure}; - } - - @Override - protected HPyConvertArgsToSulongNode createArgumentConversionNode() { - return HPyGetSetSetterToSulongNodeGen.create(); - } - - @Override - protected HPyCheckFunctionResultNode createResultConversionNode() { - return HPyCheckPrimitiveResultNodeGen.create(); - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - - @TruffleBoundary - public static PBuiltinFunction createFunction(GraalHPyContext hpyContext, Object enclosingType, TruffleString propertyName, Object target, Object closure) { - PythonContext pythonContext = hpyContext.getContext(); - PythonLanguage lang = pythonContext.getLanguage(); - RootCallTarget callTarget = lang.createCachedCallTarget(l -> new HPyGetSetDescriptorSetterRootNode(l, propertyName), HPyGetSetDescriptorSetterRootNode.class, propertyName); - PythonObjectFactory factory = pythonContext.factory(); - return factory.createBuiltinFunction(propertyName, enclosingType, PythonUtils.EMPTY_OBJECT_ARRAY, createKwDefaults(target, closure, hpyContext), 0, callTarget); - } - - } - - static final class HPyLegacyGetSetDescriptorSetterRoot extends SetterRoot { - - @Child private HPyGetNativeSpacePointerNode getNativeSpacePointerNode; - - private HPyLegacyGetSetDescriptorSetterRoot(PythonLanguage language, TruffleString name, PExternalFunctionWrapper provider) { - super(language, name, provider); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame) { - Object[] objects = super.prepareCArguments(frame); - if (getNativeSpacePointerNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - getNativeSpacePointerNode = insert(HPyGetNativeSpacePointerNodeGen.create()); - } - /* - * We now need to pass the native space pointer in a way that the PythonToNativeNode - * correctly exposes the bare pointer object. For this, we pack the pointer into a - * PythonAbstractNativeObject which will just be unwrapped. - */ - Object nativeSpacePtr = getNativeSpacePointerNode.executeCached(objects[0]); - if (nativeSpacePtr == PNone.NO_VALUE) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(this, SystemError, ErrorMessages.ATTEMPTING_SETTER_NO_NATIVE_SPACE); - } - objects[0] = new PythonAbstractNativeObject(nativeSpacePtr); - return objects; - } - - @TruffleBoundary - public static PBuiltinFunction createLegacyFunction(GraalHPyContext context, PythonLanguage lang, Object owner, TruffleString propertyName, Object target, Object closure) { - PythonContext pythonContext = context.getContext(); - PythonObjectFactory factory = pythonContext.factory(); - RootCallTarget rootCallTarget = lang.createCachedCallTarget(l -> new HPyLegacyGetSetDescriptorSetterRoot(l, propertyName, PExternalFunctionWrapper.SETTER), - HPyLegacyGetSetDescriptorSetterRoot.class, propertyName); - if (rootCallTarget == null) { - throw CompilerDirectives.shouldNotReachHere("Calling non-native get descriptor functions is not support in HPy"); - } - target = EnsureExecutableNode.executeUncached(target, PExternalFunctionWrapper.SETTER); - return factory.createBuiltinFunction(propertyName, owner, PythonUtils.EMPTY_OBJECT_ARRAY, ExternalFunctionNodes.createKwDefaults(target, closure), 0, rootCallTarget); - } - } - - /** - * Root node to call a C functions with signature - * {@code int (*HPyFunc_getbufferproc)(HPyContext ctx, HPy self, HPy_buffer *buffer, int flags)} - * . The {@code buffer} arguments will be created by this root node since it needs the C - * extension context and the result of a call to this function is an instance of - * {@link CExtPyBuffer}. - */ - static final class HPyGetBufferRootNode extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(-1, false, 1, false, tsArray("self", "flags"), KEYWORDS_HIDDEN_CALLABLE); - - @Child private ReadIndexedArgumentNode readArg1Node; - @Child private FromCharPointerNode fromCharPointerNode; - @Child private GraalHPyCAccess.AllocateNode allocateNode; - @Child private GraalHPyCAccess.FreeNode freeNode; - @Child private GraalHPyCAccess.ReadPointerNode readPointerNode; - @Child private GraalHPyCAccess.ReadGenericNode readGenericNode; - @Child private GraalHPyCAccess.ReadHPyNode readHPyNode; - @Child private GraalHPyCAccess.IsNullNode isNullNode; - - @TruffleBoundary - public HPyGetBufferRootNode(PythonLanguage language, TruffleString name) { - super(language, name, HPyCheckPrimitiveResultNodeGen.create(), HPyGetBufferProcToSulongNodeGen.create()); - } - - @Override - public CExtPyBuffer execute(VirtualFrame frame) { - getCalleeContext().enter(frame); - Object bufferPtr = null; - GraalHPyContext hpyContext = null; - try { - Object callable = ensureReadCallableNode().execute(frame); - hpyContext = readContext(frame); - bufferPtr = ensureAllocateNode(hpyContext).malloc(hpyContext, HPyContextSignatureType.HPy_buffer); - Object[] cArguments = new Object[]{getSelf(frame), bufferPtr, getArg1(frame)}; - getInvokeNode().execute(frame, getTSName(), callable, hpyContext, cArguments); - return createPyBuffer(hpyContext, bufferPtr); - } finally { - if (hpyContext != null && bufferPtr != null) { - ensureFreeNode(hpyContext).free(hpyContext, bufferPtr); - } - getCalleeContext().exit(frame, this); - } - } - - /** - * Reads the values from C struct {@code HPy_buffer}, converts them appropriately and - * creates an instance of {@link CExtPyBuffer}. - * - *
    -         *     typedef struct {
    -         *         void *buf;
    -         *         HPy obj;
    -         *         Py_ssize_t len;
    -         *         Py_ssize_t itemsize;
    -         *         int readonly;
    -         *         int ndim;
    -         *         char *format;
    -         *         Py_ssize_t *shape;
    -         *         Py_ssize_t *strides;
    -         *         Py_ssize_t *suboffsets;
    -         *         void *internal;
    -         * } HPy_buffer;
    -         * 
    - * - */ - private CExtPyBuffer createPyBuffer(GraalHPyContext ctx, Object bufferPtr) { - if (readGenericNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readGenericNode = insert(GraalHPyCAccess.ReadGenericNode.create(ctx)); - } - if (readPointerNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readPointerNode = insert(GraalHPyCAccess.ReadPointerNode.create(ctx)); - } - if (readHPyNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readHPyNode = insert(GraalHPyCAccess.ReadHPyNode.create(ctx)); - } - if (isNullNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - isNullNode = insert(GraalHPyCAccess.IsNullNode.create(ctx)); - } - if (fromCharPointerNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - fromCharPointerNode = insert(FromCharPointerNodeGen.create()); - } - int len = readGenericNode.readInt(ctx, bufferPtr, GraalHPyCField.HPy_buffer__len); - Object buf = readPointerNode.read(ctx, bufferPtr, GraalHPyCField.HPy_buffer__buf); - /* - * Since we are now the owner of the handle and no one else will ever use it, we need to - * close it. - */ - Object owner = readHPyNode.readAndClose(ctx, bufferPtr, GraalHPyCField.HPy_buffer__obj); - - int ndim = readGenericNode.readInt(ctx, bufferPtr, GraalHPyCField.HPy_buffer__ndim); - int itemSize = readGenericNode.readInt(ctx, bufferPtr, GraalHPyCField.HPy_buffer__itemsize); - boolean readonly = readGenericNode.readInt(ctx, bufferPtr, GraalHPyCField.HPy_buffer__readonly) != 0; - TruffleString format = fromCharPointerNode.execute(readPointerNode.read(ctx, bufferPtr, GraalHPyCField.HPy_buffer__format)); - Object shapePtr = readPointerNode.read(ctx, bufferPtr, GraalHPyCField.HPy_buffer__shape); - Object stridesPtr = readPointerNode.read(ctx, bufferPtr, GraalHPyCField.HPy_buffer__strides); - Object suboffsetsPtr = readPointerNode.read(ctx, bufferPtr, GraalHPyCField.HPy_buffer__suboffsets); - Object internal = readPointerNode.read(ctx, bufferPtr, GraalHPyCField.HPy_buffer__internal); - int[] shape = null; - int[] strides = null; - int[] subOffsets = null; - if (ndim > 0) { - if (!isNullNode.execute(ctx, shapePtr)) { - shape = readLongAsIntArray(ctx, shapePtr, ndim); - } - if (!isNullNode.execute(ctx, stridesPtr)) { - strides = readLongAsIntArray(ctx, stridesPtr, ndim); - } - if (!isNullNode.execute(ctx, suboffsetsPtr)) { - subOffsets = readLongAsIntArray(ctx, suboffsetsPtr, ndim); - } - } - return new CExtPyBuffer(buf, owner, len, itemSize, readonly, ndim, format, shape, strides, subOffsets, internal); - } - - private int[] readLongAsIntArray(GraalHPyContext ctx, Object pointer, int elements) { - GraalHPyCAccess.ReadGenericNode readI64Node = ensureReadGenericNode(ctx); - int elemSize = ctx.getCTypeSize(HPyContextSignatureType.HPy_ssize_t); - int[] result = new int[elements]; - for (int i = 0; i < result.length; i++) { - result[i] = readI64Node.executeInt(ctx, pointer, (long) i * elemSize, HPyContextSignatureType.HPy_ssize_t); - } - return result; - } - - private GraalHPyCAccess.AllocateNode ensureAllocateNode(GraalHPyContext ctx) { - if (allocateNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - allocateNode = insert(GraalHPyCAccess.AllocateNode.create(ctx)); - } - return allocateNode; - } - - private GraalHPyCAccess.FreeNode ensureFreeNode(GraalHPyContext ctx) { - if (freeNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - freeNode = insert(GraalHPyCAccess.FreeNode.create(ctx)); - } - return freeNode; - } - - private GraalHPyCAccess.ReadGenericNode ensureReadGenericNode(GraalHPyContext ctx) { - if (readGenericNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readGenericNode = insert(GraalHPyCAccess.ReadGenericNode.create(ctx)); - } - return readGenericNode; - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, GraalHPyContext hpyContext) { - throw CompilerDirectives.shouldNotReachHere(); - } - - private Object getArg1(VirtualFrame frame) { - if (readArg1Node == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readArg1Node = insert(ReadIndexedArgumentNode.create(1)); - } - return readArg1Node.execute(frame); - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - /** - * Root node to call a C functions with signature - * {@code void (*HPyFunc_releasebufferproc)(HPyContext ctx, HPy self, HPy_buffer *buffer)} . - */ - static final class HPyReleaseBufferRootNode extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(-1, false, 1, false, tsArray("self", "buffer"), KEYWORDS_HIDDEN_CALLABLE); - - @Child private ReadIndexedArgumentNode readArg1Node; - @Child private GraalHPyCAccess.FreeNode freeNode; - @Child private GraalHPyCAccess.ReadPointerNode readPointerNode; - @Child private GraalHPyCAccess.ReadHPyNode readHPyNode; - - @TruffleBoundary - public HPyReleaseBufferRootNode(PythonLanguage language, TruffleString name) { - super(language, name, HPyCheckVoidResultNodeGen.create(), HPyReleaseBufferProcToSulongNodeGen.create()); - } - - @Override - public Object execute(VirtualFrame frame) { - getCalleeContext().enter(frame); - try { - Object callable = ensureReadCallableNode().execute(frame); - GraalHPyContext hpyContext = readContext(frame); - Object arg1 = getArg1(frame); - if (!(arg1 instanceof CExtPyBuffer buffer)) { - throw CompilerDirectives.shouldNotReachHere("invalid argument"); - } - GraalHPyBuffer hpyBuffer = new GraalHPyBuffer(hpyContext, buffer); - try { - getInvokeNode().execute(frame, getTSName(), callable, hpyContext, new Object[]{getSelf(frame), hpyBuffer}); - } finally { - if (hpyBuffer.isPointer()) { - hpyBuffer.free(hpyContext, ensureFreeNode(hpyContext), ensureReadPointerNode(hpyContext), ensureReadHPyNode(hpyContext)); - } - } - return PNone.NONE; - } finally { - getCalleeContext().exit(frame, this); - } - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, GraalHPyContext hpyContext) { - throw CompilerDirectives.shouldNotReachHere(); - } - - @Override - protected Object processResult(VirtualFrame frame, Object result) { - throw CompilerDirectives.shouldNotReachHere(); - } - - private Object getArg1(VirtualFrame frame) { - if (readArg1Node == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readArg1Node = insert(ReadIndexedArgumentNode.create(1)); - } - return readArg1Node.execute(frame); - } - - private GraalHPyCAccess.FreeNode ensureFreeNode(GraalHPyContext ctx) { - if (freeNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - freeNode = insert(GraalHPyCAccess.FreeNode.create(ctx)); - } - return freeNode; - } - - private GraalHPyCAccess.ReadPointerNode ensureReadPointerNode(GraalHPyContext ctx) { - if (readPointerNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readPointerNode = insert(GraalHPyCAccess.ReadPointerNode.create(ctx)); - } - return readPointerNode; - } - - private GraalHPyCAccess.ReadHPyNode ensureReadHPyNode(GraalHPyContext ctx) { - if (readHPyNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readHPyNode = insert(GraalHPyCAccess.ReadHPyNode.create(ctx)); - } - return readHPyNode; - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - /** - * Very similar to {@link HPyMethNoargsRoot} but converts the result to a boolean. - */ - static final class HPyMethHashRoot extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(-1, false, -1, false, tsArray("self"), KEYWORDS_HIDDEN_CALLABLE); - - public HPyMethHashRoot(PythonLanguage language, TruffleString name) { - super(language, name, HPyCheckPrimitiveResultNodeGen.create(), HPyAllAsHandleNodeGen.create()); - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, @SuppressWarnings("unused") GraalHPyContext hpyContext) { - return new Object[]{getSelf(frame)}; - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } - - static final class HPyMethCallRoot extends HPyMethodDescriptorRootNode { - private static final Signature SIGNATURE = new Signature(-1, true, 1, false, tsArray("self"), KEYWORDS_HIDDEN_CONTEXT, true); - - @Child private ReadVarArgsNode readVarargsNode; - @Child private ReadVarKeywordsNode readKwargsNode; - @Child private PythonObjectFactory factory; - - @TruffleBoundary - public HPyMethCallRoot(PythonLanguage language, TruffleString name) { - super(language, name, HPyKeywordsToSulongNodeGen.create()); - } - - @Override - public Object execute(VirtualFrame frame) { - GraalHPyContext hpyContext = readContext(frame); - Object[] cArguments = prepareCArguments(frame, hpyContext); - Object self = cArguments[0]; - Object callable; - if (self instanceof PythonObject pythonObject) { - callable = GraalHPyData.getHPyCallFunction(pythonObject); - } else { - callable = null; - } - if (callable == null) { - throw PRaiseNode.raiseUncached(this, TypeError, ErrorMessages.HPY_OBJECT_DOES_NOT_SUPPORT_CALL, self); - } - - getCalleeContext().enter(frame); - try { - return getInvokeNode().execute(frame, getTSName(), callable, hpyContext, cArguments); - } finally { - getCalleeContext().exit(frame, this); - closeCArguments(frame, hpyContext, cArguments); - } - } - - @Override - protected Object[] prepareCArguments(VirtualFrame frame, GraalHPyContext hpyContext) { - Object[] positionalArgs = getVarargs(frame); - PKeyword[] keywords = getKwargs(frame); - long nPositionalArgs = positionalArgs.length; - - Object[] args; - Object kwnamesTuple; - // this condition is implicitly profiled by 'getKwnamesTuple' - if (keywords.length > 0) { - args = PythonUtils.arrayCopyOf(positionalArgs, positionalArgs.length + keywords.length); - TruffleString[] kwnames = new TruffleString[keywords.length]; - for (int i = 0; i < keywords.length; i++) { - args[positionalArgs.length + i] = keywords[i].getValue(); - kwnames[i] = keywords[i].getName(); - } - kwnamesTuple = getKwnamesTuple(kwnames); - } else { - args = positionalArgs; - kwnamesTuple = GraalHPyHandle.NULL_HANDLE_DELEGATE; - } - return new Object[]{getSelf(frame), createArgumentsArray(hpyContext, args), nPositionalArgs, kwnamesTuple}; - } - - @Override - protected void closeCArguments(VirtualFrame frame, GraalHPyContext hpyContext, Object[] cArguments) { - hpyContext.freeArgumentsArray(cArguments[1]); - } - - private Object createArgumentsArray(GraalHPyContext hpyContext, Object[] args) { - return hpyContext.createArgumentsArray(args); - } - - private Object[] getVarargs(VirtualFrame frame) { - if (readVarargsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readVarargsNode = insert(ReadVarArgsNode.create(true)); - } - return readVarargsNode.executeObjectArray(frame); - } - - private PKeyword[] getKwargs(VirtualFrame frame) { - if (PArguments.getKeywordArguments(frame).length == 0) { - return PKeyword.EMPTY_KEYWORDS; - } - if (readKwargsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - readKwargsNode = insert(ReadVarKeywordsNode.create()); - } - return (PKeyword[]) readKwargsNode.execute(frame); - } - - private PTuple getKwnamesTuple(TruffleString[] kwnames) { - if (factory == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - factory = insert(PythonObjectFactory.create()); - } - return factory.createTuple(kwnames); - } - - @Override - public Signature getSignature() { - return SIGNATURE; - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNICallHelperFunctionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNICallHelperFunctionNode.java deleted file mode 100644 index 237f547787..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNICallHelperFunctionNode.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy.jni; - -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNativeSymbol; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyCallHelperFunctionNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.HPyJNIFromCharPointerNode; -import com.oracle.truffle.api.CompilerDirectives; - -/** - * This is the implementation of {@link HPyCallHelperFunctionNode} for the JNI backend. This node - * calls helper functions also via JNI. The goal of this node is minimal footprint and best - * uncached/interpreter performance. - */ -final class GraalHPyJNICallHelperFunctionNode extends HPyCallHelperFunctionNode { - - static final GraalHPyJNICallHelperFunctionNode UNCACHED = new GraalHPyJNICallHelperFunctionNode(); - - private GraalHPyJNICallHelperFunctionNode() { - } - - @Override - protected Object execute(GraalHPyContext context, GraalHPyNativeSymbol name, Object[] args) { - assert context.getBackend() instanceof GraalHPyJNIContext; - return switch (name) { - case GRAAL_HPY_GET_ERRNO -> GraalHPyJNIContext.getErrno(); - case GRAAL_HPY_GET_STRERROR -> GraalHPyJNIContext.getStrerror((int) args[0]); - case GRAAL_HPY_STRLEN -> HPyJNIFromCharPointerNode.strlen((long) args[0]); - default -> throw CompilerDirectives.shouldNotReachHere("not yet implemented"); - }; - } - - @Override - public boolean isAdoptable() { - return false; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNIContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNIContext.java deleted file mode 100644 index 26be2d9259..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNIContext.java +++ /dev/null @@ -1,3011 +0,0 @@ -/* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy.jni; - -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; -import static com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.UNSAFE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.IMMUTABLE_HANDLE_COUNT; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.SINGLETON_HANDLE_ELIPSIS; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.SINGLETON_HANDLE_NONE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.SINGLETON_HANDLE_NOT_IMPLEMENTED; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.SIZEOF_LONG; -import static com.oracle.graal.python.nodes.StringLiterals.J_DEBUG; -import static com.oracle.graal.python.nodes.StringLiterals.J_NFI_LANGUAGE; -import static com.oracle.graal.python.nodes.StringLiterals.J_TRACE; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; -import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; -import static com.oracle.graal.python.util.PythonUtils.tsLiteral; - -import java.io.IOException; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.Objects; - -import org.graalvm.nativeimage.ImageInfo; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.Python3Core; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.bytes.PBytes; -import com.oracle.graal.python.builtins.objects.capsule.PyCapsule; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodesFactory.AsNativePrimitiveNodeGen; -import com.oracle.graal.python.builtins.objects.cext.common.CExtContext; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ApiInitException; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ImportException; -import com.oracle.graal.python.builtins.objects.cext.common.NativePointer; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyBoxing; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.AllocateNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.BulkFreeHandleReferencesNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.FreeNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.GetElementPtrNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.IsNullNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadDoubleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadFloatNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadGenericNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyArrayNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyFieldNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadI32Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadI64Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadI8ArrayNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteDoubleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteGenericNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteHPyFieldNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteHPyNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteI32Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteI64Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WritePointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteSizeTNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCField; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.HPyABIVersion; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.HPyUpcall; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.CapsuleKey; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyCapsuleGet; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyContextFunction; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyContextVarGet; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.HPyBinaryContextFunction; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.HPyTernaryContextFunction; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyData; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyHandle; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNativeContext; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsCharPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyCallHelperFunctionNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyFromCharPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyGetNativeSpacePointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyRaiseNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyTransformExceptionToNativeNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyTypeGetNameNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.GraalHPyModuleCreateNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.GraalHPyModuleExecNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyAsNativeInt64NodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyAsPythonObjectNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyPackKeywordArgsNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyRaiseNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextMember; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignature; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyMode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeAllocateNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeBulkFreeHandleReferencesNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeFreeNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeGetElementPtrNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeIsNullNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeReadDoubleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeReadFloatNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeReadGenericNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeReadHPyArrayNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeReadHPyFieldNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeReadHPyNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeReadI32Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeReadI64Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeReadI8ArrayNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeReadPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeWriteDoubleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeWriteGenericNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeWriteHPyFieldNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeWriteHPyNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeWriteI32Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeWriteI64Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeWritePointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodes.UnsafeWriteSizeTNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodesFactory.HPyJNIAsCharPointerNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNINodesFactory.HPyJNIFromCharPointerNodeGen; -import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; -import com.oracle.graal.python.builtins.objects.common.EmptyStorage; -import com.oracle.graal.python.builtins.objects.common.HashingStorage; -import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem; -import com.oracle.graal.python.builtins.objects.contextvars.PContextVar; -import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis; -import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.builtins.objects.ints.PInt; -import com.oracle.graal.python.builtins.objects.list.PList; -import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; -import com.oracle.graal.python.builtins.objects.type.PythonClass; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode; -import com.oracle.graal.python.lib.PyFloatAsDoubleNode; -import com.oracle.graal.python.lib.PyLongAsDoubleNode; -import com.oracle.graal.python.lib.PyNumberCheckNode; -import com.oracle.graal.python.lib.PyObjectGetAttr; -import com.oracle.graal.python.lib.PyObjectGetItem; -import com.oracle.graal.python.lib.PyObjectSetItem; -import com.oracle.graal.python.lib.PyObjectSizeNodeGen; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.classes.IsSubtypeNode; -import com.oracle.graal.python.nodes.classes.IsSubtypeNodeGen; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; -import com.oracle.graal.python.nodes.object.IsNodeGen; -import com.oracle.graal.python.nodes.util.CannotCastException; -import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; -import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonImageBuildOptions; -import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.runtime.PythonOptions.HPyBackendMode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory; -import com.oracle.graal.python.runtime.sequence.PSequence; -import com.oracle.graal.python.runtime.sequence.storage.DoubleSequenceStorage; -import com.oracle.graal.python.runtime.sequence.storage.IntSequenceStorage; -import com.oracle.graal.python.runtime.sequence.storage.LongSequenceStorage; -import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; -import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; -import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.TruffleFile; -import com.oracle.truffle.api.TruffleLogger; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.UnknownIdentifierException; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.library.ExportLibrary; -import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.strings.InternalByteArray; -import com.oracle.truffle.api.strings.NativeAllocator; -import com.oracle.truffle.api.strings.TruffleString; -import com.oracle.truffle.api.strings.TruffleString.AsNativeNode; -import com.oracle.truffle.api.strings.TruffleString.Encoding; -import com.oracle.truffle.api.strings.TruffleString.GetInternalByteArrayNode; -import com.oracle.truffle.api.strings.TruffleString.GetInternalNativePointerNode; -import com.oracle.truffle.api.strings.TruffleString.SwitchEncodingNode; - -/** - * This object is used to override specific native upcall pointers in the HPyContext. This is - * queried for every member of HPyContext by {@code graal_hpy_context_to_native}, and overrides the - * original values (which are NFI closures for functions in {@code hpy.c}, subsequently calling into - * {@link GraalHPyContextFunctions}. - */ -@ExportLibrary(InteropLibrary.class) -public final class GraalHPyJNIContext extends GraalHPyNativeContext { - - private static final String J_NAME = "HPy Universal ABI (GraalVM JNI backend)"; - - private static final TruffleLogger LOGGER = GraalHPyContext.getLogger(GraalHPyJNIContext.class); - - static final NativeAllocator TS_NATIVE_ALLOCATOR = byteSize -> new NativePointer(UNSAFE.allocateMemory(byteSize)); - - private static boolean jniBackendLoaded = false; - - private final PythonObjectSlowPathFactory slowPathFactory; - private final int[] counts; - - private final int[] ctypeSizes; - private final int[] cfieldOffsets; - - private long hPyDebugContext; - private long hPyTraceContext; - private long nativePointer; - - /** - * This list holds a strong reference to all loaded extension libraries to keep the library - * objects alive. This is necessary because NFI will {@code dlclose} the library (and thus - * {@code munmap} all code) if the library object is no longer reachable. However, it can happen - * that we still store raw function pointers (as Java {@code long} values) in - * {@link GraalHPyJNIFunctionPointer} objects which are invoked asynchronously. For - * example, destroy functions will be executed on a different thread some time after the object - * died. Buffer release functions run on the main thread but like an async action at some - * unknown point in time after the buffer owner died. - * - * Since we have no control over the execution order of those cleaners, we need to ensure that - * the code is still mapped. - */ - private final List loadedExtensions = new LinkedList<>(); - - public GraalHPyJNIContext(GraalHPyContext context, boolean traceUpcalls) { - super(context, traceUpcalls); - assert !PythonImageBuildOptions.WITHOUT_JNI; - this.slowPathFactory = context.getContext().factory(); - this.counts = traceUpcalls ? new int[HPyJNIUpcall.VALUES.length] : null; - this.ctypeSizes = new int[HPyContextSignatureType.values().length]; - this.cfieldOffsets = new int[GraalHPyCField.values().length]; - } - - @Override - protected String getName() { - return J_NAME; - } - - @Override - protected Object loadExtensionLibrary(Node location, PythonContext context, TruffleString name, TruffleString path) throws ImportException { - CompilerAsserts.neverPartOfCompilation(); - TruffleFile extLibFile = context.getPublicTruffleFileRelaxed(path, context.getSoAbi()); - try { - /* - * Even in the JNI backend, we load the library with NFI (instead of using - * 'System.load') because NFI may take care of additional security checks. - */ - String src = "load \"" + extLibFile + '"'; - Source loadSrc = Source.newBuilder(J_NFI_LANGUAGE, src, "load:" + name).internal(true).build(); - Object extLib = context.getEnv().parseInternal(loadSrc).call(); - loadedExtensions.add(extLib); - return extLib; - } catch (SecurityException e) { - throw new ImportException(CExtContext.wrapJavaException(e, location), name, path, ErrorMessages.CANNOT_LOAD_M, path, e); - } - } - - @Override - protected HPyABIVersion getHPyABIVersion(Object extLib, String getMajorVersionFuncName, String getMinorVersionFuncName) throws UnknownIdentifierException { - CompilerAsserts.neverPartOfCompilation(); - try { - InteropLibrary lib = InteropLibrary.getUncached(extLib); - Object majorVersionFun = lib.readMember(extLib, getMajorVersionFuncName); - Object minorVersionFun = lib.readMember(extLib, getMinorVersionFuncName); - int requiredMajorVersion = (int) GraalHPyJNITrampolines.executeModuleInit(coerceToPointer(majorVersionFun)); - int requiredMinorVersion = (int) GraalHPyJNITrampolines.executeModuleInit(coerceToPointer(minorVersionFun)); - return new HPyABIVersion(requiredMajorVersion, requiredMinorVersion); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - @Override - protected Object initHPyModule(Object extLib, String initFuncName, TruffleString name, TruffleString path, HPyMode mode) - throws ImportException, ApiInitException { - CompilerAsserts.neverPartOfCompilation(); - /* - * We eagerly initialize the debug mode here to be able to produce an error message now if - * we cannot use it. - */ - if (Objects.requireNonNull(mode) == HPyMode.MODE_DEBUG) { - initHPyDebugContext(); - } else if (mode == HPyMode.MODE_TRACE) { - initHPyTraceContext(); - } - - Object initFunction; - try { - InteropLibrary lib = InteropLibrary.getUncached(extLib); - initFunction = lib.readMember(extLib, initFuncName); - } catch (UnknownIdentifierException | UnsupportedMessageException e1) { - throw new ImportException(null, name, path, ErrorMessages.CANNOT_INITIALIZE_EXT_NO_ENTRY, name, path, initFuncName); - } - // NFI doesn't know if a symbol is executable, so it always reports false - assert !InteropLibrary.getUncached().isExecutable(initFunction); - - // coerce 'initFunction' to a native pointer and invoke it via JNI trampoline - long moduleDefPtr; - moduleDefPtr = GraalHPyJNITrampolines.executeModuleInit(coerceToPointer(initFunction)); - return convertLongArg(HPyContextSignatureType.HPyModuleDefPtr, moduleDefPtr); - } - - @Override - protected HPyUpcall[] getUpcalls() { - return HPyJNIUpcall.VALUES; - } - - @Override - protected int[] getUpcallCounts() { - return counts; - } - - @Override - protected int getCTypeSize(HPyContextSignatureType ctype) { - return ctypeSizes[ctype.ordinal()]; - } - - @Override - protected int getCFieldOffset(GraalHPyCField cfield) { - return cfieldOffsets[cfield.ordinal()]; - } - - @Override - protected NativePointer nativeToInteropPointer(Object object) { - assert object instanceof Long; - return new NativePointer((Long) object); - } - - static long interopPointerToNative(Object object, InteropLibrary lib) { - if (!lib.isPointer(object)) { - lib.toNative(object); - } - try { - return lib.asPointer(object); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @Override - protected Object getNativeNull() { - return 0L; - } - - @ExportMessage - boolean isPointer() { - return nativePointer != 0; - } - - @ExportMessage - long asPointer() throws UnsupportedMessageException { - if (isPointer()) { - return nativePointer; - } - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw UnsupportedMessageException.create(); - } - - /** - * Internal method for transforming the HPy universal context to native. This is mostly like the - * interop message {@code toNative} but may of course fail if native access is not allowed. This - * method can be used to force the context to native if a native pointer is needed that will be - * handed to a native (e.g. JNI or NFI) function. - */ - @Override - protected void toNativeInternal() { - if (nativePointer == 0) { - CompilerDirectives.transferToInterpreter(); - assert PythonLanguage.get(null).getEngineOption(PythonOptions.HPyBackend) == HPyBackendMode.JNI; - if (!getContext().getEnv().isNativeAccessAllowed()) { - throw new RuntimeException(ErrorMessages.NATIVE_ACCESS_NOT_ALLOWED.toJavaStringUncached()); - } - loadJNIBackend(); - nativePointer = initJNI(this, context, createContextHandleArray(), ctypeSizes, cfieldOffsets); - if (nativePointer == 0) { - throw CompilerDirectives.shouldNotReachHere("Could not initialize HPy JNI backend."); - } - } - } - - @Override - protected void initNativeFastPaths() { - /* - * Currently, the native fast path functions are only available if the JNI backend is used - * because they rely on 'initJNI' being called. In the future, we might also want to use the - * native fast path functions for the NFI backend. - */ - assert useNativeFastPaths(); - initJNINativeFastPaths(nativePointer); - } - - @SuppressWarnings("restricted") - public static void loadJNIBackend() { - if (!(ImageInfo.inImageBuildtimeCode() || jniBackendLoaded)) { - String pythonJNIPath; - pythonJNIPath = getJNILibrary(); - try { - LOGGER.fine("Loading HPy JNI backend from " + pythonJNIPath); - System.load(pythonJNIPath); - jniBackendLoaded = true; - } catch (NullPointerException | UnsatisfiedLinkError e) { - LOGGER.severe("HPy JNI backend library could not be found: " + pythonJNIPath); - LOGGER.severe("Error was: " + e); - } - } - } - - public static String getJNILibrary() { - CompilerAsserts.neverPartOfCompilation(); - PythonContext context = PythonContext.get(null); - TruffleFile libPath = context.getPublicTruffleFileRelaxed(context.getJNIHome()).resolve(PythonContext.J_PYTHON_JNI_LIBRARY_NAME).getAbsoluteFile(); - try { - return libPath.getCanonicalFile().toString(); - } catch (IOException e) { - LOGGER.severe(String.format("Cannot determine canonical path for %s: %s", libPath, e)); - throw new IllegalStateException(e); - } - } - - @Override - protected void initNativeContext() { - /* - * We eagerly initialize any native resources (e.g. allocating off-heap memory for - * 'HPyContext') for the JNI backend because this method will be called if we are up to load - * an HPy extension module with the JNI backend and there is no way to run the JNI backend - * without native resources. - */ - toNative(); - } - - @Override - protected void finalizeNativeContext() { - finalizeJNIContext(nativePointer); - nativePointer = 0; - if (hPyDebugContext != 0) { - finalizeJNIDebugContext(hPyDebugContext); - hPyDebugContext = 0; - } - if (hPyTraceContext != 0) { - finalizeJNITraceContext(hPyTraceContext); - hPyTraceContext = 0; - } - loadedExtensions.clear(); - } - - @Override - public void initHPyDebugContext() throws ApiInitException { - if (hPyDebugContext == 0) { - CompilerDirectives.transferToInterpreter(); - if (!getContext().getEnv().isNativeAccessAllowed() || getContext().getLanguage().getEngineOption(PythonOptions.HPyBackend) != HPyBackendMode.JNI) { - throw new ApiInitException(ErrorMessages.HPY_S_MODE_NOT_AVAILABLE, J_DEBUG); - } - try { - toNativeInternal(); - long debugCtxPtr = initJNIDebugContext(nativePointer); - if (debugCtxPtr == 0) { - throw new RuntimeException("Could not initialize HPy debug context"); - } - hPyDebugContext = debugCtxPtr; - } catch (CannotCastException e) { - // TODO(fa): this can go away once 'isNativeAccessAllowed' is always correctly set - throw new ApiInitException(ErrorMessages.HPY_S_MODE_NOT_AVAILABLE, J_DEBUG); - } - } - } - - @Override - public void initHPyTraceContext() throws ApiInitException { - if (hPyTraceContext == 0) { - CompilerDirectives.transferToInterpreter(); - if (!getContext().getEnv().isNativeAccessAllowed() || getContext().getLanguage().getEngineOption(PythonOptions.HPyBackend) != HPyBackendMode.JNI) { - throw new ApiInitException(ErrorMessages.HPY_S_MODE_NOT_AVAILABLE, J_TRACE); - } - try { - toNativeInternal(); - long traceCtxPtr = initJNITraceContext(nativePointer); - if (traceCtxPtr == 0) { - throw new RuntimeException("Could not initialize HPy trace context"); - } - hPyTraceContext = traceCtxPtr; - } catch (CannotCastException e) { - // TODO(fa): this can go away once 'isNativeAccessAllowed' is always correctly set - throw new ApiInitException(ErrorMessages.HPY_S_MODE_NOT_AVAILABLE, "trace"); - } - } - } - - @Override - protected Object createArgumentsArray(Object[] args) { - return context.createNativeArguments(args); - } - - @Override - protected void freeArgumentsArray(Object argsArray) { - if (argsArray instanceof Long argsArrayPtr) { - context.freeNativeArgumentsUntil(argsArrayPtr); - } - } - - /** - * Equivalent of {@code hpy_debug_get_ctx}. In fact, this method is called from the native - * {@code hpy_jni.c: hpy_debug_get_ctx} function to get the debug context's pointer via JNI. So, - * if you change the name of this function, also modify {@code hpy_jni.c} appropriately. - */ - long getHPyDebugContext() { - /* - * It is a valid path that this method is called but the debug context has not yet been - * initialized. In particular, this can happen if the leak detector is used which calls - * methods of the native debug module. The native methods may call function - * 'hpy_debug_get_ctx' which upcalls to this method. All this may happen before any HPy - * extension was loaded with debug mode enabled. - */ - if (hPyDebugContext == 0) { - try { - initHPyDebugContext(); - } catch (ApiInitException e) { - throw CompilerDirectives.shouldNotReachHere(e.getMessage()); - } - } - return hPyDebugContext; - } - - @Override - @TruffleBoundary - public PythonModule getHPyDebugModule() throws ImportException { - // force the universal context to native; we need a real pointer for JNI - toNativeInternal(); - - // initialize the debug module via JNI - long debugModuleDef = initJNIDebugModule(nativePointer); - if (debugModuleDef == 0) { - throw new ImportException(null, null, null, ErrorMessages.HPY_S_MODE_NOT_AVAILABLE, "debug"); - } - return loadInternalModule(debugModuleDef, tsLiteral("_debug")); - } - - /** - * Equivalent of {@code hpy_trace_get_ctx}. In fact, this method is called from the native - * {@code hpy_jni.c: hpy_trace_get_ctx} function to get the debug context's pointer via JNI. So, - * if you change the name of this function, also modify {@code hpy_jni.c} appropriately. - */ - long getHPyTraceContext() { - /* - * It is a valid path that this method is called but the debug context has not yet been - * initialized. In particular, this can happen if the leak detector is used which calls - * methods of the native debug module. The native methods may call function - * 'hpy_debug_get_ctx' which upcalls to this method. All this may happen before any HPy - * extension was loaded with debug mode enabled. - */ - if (hPyTraceContext == 0) { - try { - initHPyTraceContext(); - } catch (ApiInitException e) { - throw CompilerDirectives.shouldNotReachHere(e.getMessage()); - } - } - return hPyTraceContext; - } - - @Override - @TruffleBoundary - public PythonModule getHPyTraceModule() throws ImportException { - // force the universal context to native; we need a real pointer for JNI - toNativeInternal(); - - // initialize the debug module via JNI - long debugModuleDef = initJNITraceModule(nativePointer); - if (debugModuleDef == 0) { - throw new ImportException(null, null, null, ErrorMessages.HPY_S_MODE_NOT_AVAILABLE, "trace"); - } - return loadInternalModule(debugModuleDef, tsLiteral("_trace")); - } - - private PythonModule loadInternalModule(long debugModuleDef, TruffleString name) { - CompilerAsserts.neverPartOfCompilation(); - assert getContext().getEnv().isNativeAccessAllowed(); - assert getContext().getLanguage().getEngineOption(PythonOptions.HPyBackend) == HPyBackendMode.JNI; - - /* - * Note: we don't need a 'spec' object since that's only required if the module has slot - * HPy_mod_create which is guaranteed to be missing in this case. - */ - Object moduleDefPtrObj = convertLongArg(HPyContextSignatureType.HPyModuleDefPtr, debugModuleDef); - Object nativeModule = GraalHPyModuleCreateNodeGen.getUncached().execute(context, name, null, moduleDefPtrObj); - if (nativeModule instanceof PythonModule pythonModule) { - GraalHPyModuleExecNodeGen.getUncached().execute(null, context, pythonModule); - return (PythonModule) nativeModule; - } - /* - * Since we have the internal modules fully under control, this is clearly an internal - * error. - */ - throw new RuntimeException(name.toJavaStringUncached() + " module is expected to be a Python module object"); - } - - @Override - protected void setNativeCache(long cachePtr) { - assert useNativeFastPaths(); - setNativeSpaceFunction(nativePointer, cachePtr); - } - - @Override - public HPyCallHelperFunctionNode createCallHelperFunctionNode() { - return GraalHPyJNICallHelperFunctionNode.UNCACHED; - } - - @Override - public HPyCallHelperFunctionNode getUncachedCallHelperFunctionNode() { - return GraalHPyJNICallHelperFunctionNode.UNCACHED; - } - - @Override - public HPyFromCharPointerNode createFromCharPointerNode() { - return HPyJNIFromCharPointerNodeGen.create(); - } - - @Override - public HPyFromCharPointerNode getUncachedFromCharPointerNode() { - return HPyJNIFromCharPointerNodeGen.getUncached(); - } - - @Override - public HPyAsCharPointerNode createAsCharPointerNode() { - return HPyJNIAsCharPointerNodeGen.create(); - } - - @Override - public HPyAsCharPointerNode getUncachedAsCharPointerNode() { - return HPyJNIAsCharPointerNodeGen.getUncached(); - } - - @Override - public AllocateNode createAllocateNode() { - return UnsafeAllocateNode.UNCACHED; - } - - @Override - public AllocateNode getUncachedAllocateNode() { - return UnsafeAllocateNode.UNCACHED; - } - - @Override - public FreeNode createFreeNode() { - return UnsafeFreeNode.UNCACHED; - } - - @Override - public FreeNode getUncachedFreeNode() { - return UnsafeFreeNode.UNCACHED; - } - - @Override - public BulkFreeHandleReferencesNode createBulkFreeHandleReferencesNode() { - return UnsafeBulkFreeHandleReferencesNode.UNCACHED; - } - - @Override - public GetElementPtrNode createGetElementPtrNode() { - return UnsafeGetElementPtrNode.UNCACHED; - } - - @Override - public GetElementPtrNode getUncachedGetElementPtrNode() { - return UnsafeGetElementPtrNode.UNCACHED; - } - - @Override - public ReadI32Node createReadI32Node() { - return UnsafeReadI32Node.UNCACHED; - } - - @Override - public ReadI32Node getUncachedReadI32Node() { - return UnsafeReadI32Node.UNCACHED; - } - - @Override - public ReadI64Node createReadI64Node() { - return UnsafeReadI64Node.UNCACHED; - } - - @Override - public ReadI64Node getUncachedReadI64Node() { - return UnsafeReadI64Node.UNCACHED; - } - - @Override - public ReadFloatNode createReadFloatNode() { - return UnsafeReadFloatNode.UNCACHED; - } - - @Override - public ReadFloatNode getUncachedReadFloatNode() { - return UnsafeReadFloatNode.UNCACHED; - } - - @Override - public ReadDoubleNode createReadDoubleNode() { - return UnsafeReadDoubleNode.UNCACHED; - } - - @Override - public ReadDoubleNode getUncachedReadDoubleNode() { - return UnsafeReadDoubleNode.UNCACHED; - } - - @Override - public ReadPointerNode createReadPointerNode() { - return UnsafeReadPointerNode.UNCACHED; - } - - @Override - public ReadPointerNode getUncachedReadPointerNode() { - return UnsafeReadPointerNode.UNCACHED; - } - - @Override - public IsNullNode createIsNullNode() { - return UnsafeIsNullNode.UNCACHED; - } - - @Override - public IsNullNode getUncachedIsNullNode() { - return UnsafeIsNullNode.UNCACHED; - } - - @Override - public ReadGenericNode createReadGenericNode() { - return UnsafeReadGenericNode.UNCACHED; - } - - @Override - public ReadGenericNode getUncachedReadGenericNode() { - return UnsafeReadGenericNode.UNCACHED; - } - - @Override - public ReadHPyNode createReadHPyNode() { - return UnsafeReadHPyNode.UNCACHED; - } - - @Override - public ReadHPyNode getUncachedReadHPyNode() { - return UnsafeReadHPyNode.UNCACHED; - } - - @Override - public ReadHPyFieldNode createReadHPyFieldNode() { - return UnsafeReadHPyFieldNode.UNCACHED; - } - - @Override - public ReadHPyFieldNode getUncachedReadFieldHPyNode() { - return UnsafeReadHPyFieldNode.UNCACHED; - } - - @Override - public WriteDoubleNode createWriteDoubleNode() { - return UnsafeWriteDoubleNode.UNCACHED; - } - - @Override - public WriteDoubleNode getUncachedWriteDoubleNode() { - return UnsafeWriteDoubleNode.UNCACHED; - } - - @Override - public WriteI32Node createWriteI32Node() { - return UnsafeWriteI32Node.UNCACHED; - } - - @Override - public WriteI32Node getUncachedWriteI32Node() { - return UnsafeWriteI32Node.UNCACHED; - } - - @Override - public WriteI64Node createWriteI64Node() { - return UnsafeWriteI64Node.UNCACHED; - } - - @Override - public WriteI64Node getUncachedWriteI64Node() { - return UnsafeWriteI64Node.UNCACHED; - } - - @Override - public WriteHPyNode createWriteHPyNode() { - return UnsafeWriteHPyNode.UNCACHED; - } - - @Override - public WriteHPyNode getUncachedWriteHPyNode() { - return UnsafeWriteHPyNode.UNCACHED; - } - - @Override - public WritePointerNode createWritePointerNode() { - return UnsafeWritePointerNode.UNCACHED; - } - - @Override - public WritePointerNode getUncachedWritePointerNode() { - return UnsafeWritePointerNode.UNCACHED; - } - - @Override - public ReadI8ArrayNode createReadI8ArrayNode() { - return UnsafeReadI8ArrayNode.UNCACHED; - } - - @Override - public ReadI8ArrayNode getUncachedReadI8ArrayNode() { - return UnsafeReadI8ArrayNode.UNCACHED; - } - - @Override - public ReadHPyArrayNode createReadHPyArrayNode() { - return UnsafeReadHPyArrayNode.UNCACHED; - } - - @Override - public ReadHPyArrayNode getUncachedReadHPyArrayNode() { - return UnsafeReadHPyArrayNode.UNCACHED; - } - - @Override - public WriteSizeTNode createWriteSizeTNode() { - return UnsafeWriteSizeTNode.UNCACHED; - } - - @Override - public WriteSizeTNode getUncachedWriteSizeTNode() { - return UnsafeWriteSizeTNode.UNCACHED; - } - - @Override - public WriteGenericNode createWriteGenericNode() { - return UnsafeWriteGenericNode.UNCACHED; - } - - @Override - public WriteGenericNode getUncachedWriteGenericNode() { - return UnsafeWriteGenericNode.UNCACHED; - } - - @Override - public WriteHPyFieldNode createWriteHPyFieldNode() { - return UnsafeWriteHPyFieldNode.UNCACHED; - } - - @Override - public WriteHPyFieldNode getUncachedWriteHPyFieldNode() { - return UnsafeWriteHPyFieldNode.UNCACHED; - } - - /* JNI helper functions */ - - @TruffleBoundary - public static native int strcmp(long s1, long s2); - - @TruffleBoundary - private static native int setNativeSpaceFunction(long uctxPointer, long cachePtr); - - @TruffleBoundary - private static native int initJNINativeFastPaths(long uctxPointer); - - @TruffleBoundary - public static native int getErrno(); - - @TruffleBoundary - public static native long getStrerror(int errno); - - /* HPY internal JNI trampoline declarations */ - - @TruffleBoundary - private static native long initJNI(GraalHPyJNIContext backend, GraalHPyContext hpyContext, long[] ctxHandles, int[] ctypeSizes, int[] cfieldOffsets); - - @TruffleBoundary - private static native int finalizeJNIContext(long uctxPointer); - - @TruffleBoundary - private static native long initJNIDebugContext(long uctxPointer); - - @TruffleBoundary - private static native int finalizeJNIDebugContext(long dctxPointer); - - @TruffleBoundary - private static native long initJNIDebugModule(long uctxPointer); - - @TruffleBoundary - private static native long initJNITraceContext(long uctxPointer); - - @TruffleBoundary - private static native int finalizeJNITraceContext(long dctxPointer); - - @TruffleBoundary - private static native long initJNITraceModule(long uctxPointer); - - @TruffleBoundary - static native void bulkFreeNativeSpace(long[] nativeSpacePtrs, long[] destroyFuncPtrs, int n); - - enum HPyJNIUpcall implements HPyUpcall { - HPyUnicodeFromJCharArray, - HPyBulkClose, - HPySequenceFromArray, - - // {{start jni upcalls}} - // @formatter:off - // Checkstyle: stop - // DO NOT EDIT THIS PART! - // This part is automatically generated by hpy.tools.autogen.graalpy.autogen_ctx_jni_upcall_enum - HPyDup, - HPyClose, - HPyLongFromInt32t, - HPyLongFromUInt32t, - HPyLongFromInt64t, - HPyLongFromUInt64t, - HPyLongFromSizet, - HPyLongFromSsizet, - HPyLongAsInt32t, - HPyLongAsUInt32t, - HPyLongAsUInt32tMask, - HPyLongAsInt64t, - HPyLongAsUInt64t, - HPyLongAsUInt64tMask, - HPyLongAsSizet, - HPyLongAsSsizet, - HPyLongAsVoidPtr, - HPyLongAsDouble, - HPyFloatFromDouble, - HPyFloatAsDouble, - HPyBoolFromBool, - HPyLength, - HPyNumberCheck, - HPyAdd, - HPySubtract, - HPyMultiply, - HPyMatrixMultiply, - HPyFloorDivide, - HPyTrueDivide, - HPyRemainder, - HPyDivmod, - HPyPower, - HPyNegative, - HPyPositive, - HPyAbsolute, - HPyInvert, - HPyLshift, - HPyRshift, - HPyAnd, - HPyXor, - HPyOr, - HPyIndex, - HPyLong, - HPyFloat, - HPyInPlaceAdd, - HPyInPlaceSubtract, - HPyInPlaceMultiply, - HPyInPlaceMatrixMultiply, - HPyInPlaceFloorDivide, - HPyInPlaceTrueDivide, - HPyInPlaceRemainder, - HPyInPlacePower, - HPyInPlaceLshift, - HPyInPlaceRshift, - HPyInPlaceAnd, - HPyInPlaceXor, - HPyInPlaceOr, - HPyCallableCheck, - HPyCallTupleDict, - HPyCall, - HPyCallMethod, - HPyFatalError, - HPyErrSetString, - HPyErrSetObject, - HPyErrSetFromErrnoWithFilename, - HPyErrSetFromErrnoWithFilenameObjects, - HPyErrOccurred, - HPyErrExceptionMatches, - HPyErrNoMemory, - HPyErrClear, - HPyErrNewException, - HPyErrNewExceptionWithDoc, - HPyErrWarnEx, - HPyErrWriteUnraisable, - HPyIsTrue, - HPyTypeFromSpec, - HPyTypeGenericNew, - HPyGetAttr, - HPyGetAttrs, - HPyHasAttr, - HPyHasAttrs, - HPySetAttr, - HPySetAttrs, - HPyGetItem, - HPyGetItemi, - HPyGetItems, - HPyContains, - HPySetItem, - HPySetItemi, - HPySetItems, - HPyDelItem, - HPyDelItemi, - HPyDelItems, - HPyType, - HPyTypeCheck, - HPyTypeGetName, - HPyTypeIsSubtype, - HPyIs, - HPyAsStructObject, - HPyAsStructLegacy, - HPyAsStructType, - HPyAsStructLong, - HPyAsStructFloat, - HPyAsStructUnicode, - HPyAsStructTuple, - HPyAsStructList, - HPyTypeGetBuiltinShape, - HPyNew, - HPyRepr, - HPyStr, - HPyASCII, - HPyBytes, - HPyRichCompare, - HPyRichCompareBool, - HPyHash, - HPyBytesCheck, - HPyBytesSize, - HPyBytesGETSIZE, - HPyBytesAsString, - HPyBytesASSTRING, - HPyBytesFromString, - HPyBytesFromStringAndSize, - HPyUnicodeFromString, - HPyUnicodeCheck, - HPyUnicodeAsASCIIString, - HPyUnicodeAsLatin1String, - HPyUnicodeAsUTF8String, - HPyUnicodeAsUTF8AndSize, - HPyUnicodeFromWideChar, - HPyUnicodeDecodeFSDefault, - HPyUnicodeDecodeFSDefaultAndSize, - HPyUnicodeEncodeFSDefault, - HPyUnicodeReadChar, - HPyUnicodeDecodeASCII, - HPyUnicodeDecodeLatin1, - HPyUnicodeFromEncodedObject, - HPyUnicodeSubstring, - HPyListCheck, - HPyListNew, - HPyListAppend, - HPyDictCheck, - HPyDictNew, - HPyDictKeys, - HPyDictCopy, - HPyTupleCheck, - HPyTupleFromArray, - HPySliceUnpack, - HPyImportImportModule, - HPyCapsuleNew, - HPyCapsuleGet, - HPyCapsuleIsValid, - HPyCapsuleSet, - HPyFromPyObject, - HPyAsPyObject, - HPyCallRealFunctionFromTrampoline, - HPyListBuilderNew, - HPyListBuilderSet, - HPyListBuilderBuild, - HPyListBuilderCancel, - HPyTupleBuilderNew, - HPyTupleBuilderSet, - HPyTupleBuilderBuild, - HPyTupleBuilderCancel, - HPyTrackerNew, - HPyTrackerAdd, - HPyTrackerForgetAll, - HPyTrackerClose, - HPyFieldStore, - HPyFieldLoad, - HPyReenterPythonExecution, - HPyLeavePythonExecution, - HPyGlobalStore, - HPyGlobalLoad, - HPyDump, - HPyCompiles, - HPyEvalCode, - HPyContextVarNew, - HPyContextVarGet, - HPyContextVarSet, - HPySetCallFunction; - - // @formatter:on - // Checkstyle: resume - // {{end jni upcalls}} - - @CompilationFinal(dimensions = 1) private static final HPyJNIUpcall[] VALUES = values(); - - @Override - public String getName() { - return name(); - } - } - - private void increment(HPyJNIUpcall upcall) { - if (counts != null) { - counts[upcall.ordinal()]++; - } - } - - private static PythonBuiltinClassType getBuiltinClass(Object cls) { - if (cls instanceof PythonBuiltinClassType) { - return (PythonBuiltinClassType) cls; - } else if (cls instanceof PythonBuiltinClass) { - return ((PythonBuiltinClass) cls).getType(); - } else { - return null; - } - } - - private int typeCheck(long handle, Object type) { - Object receiver; - if (GraalHPyBoxing.isBoxedDouble(handle)) { - receiver = PythonBuiltinClassType.PFloat; - } else if (GraalHPyBoxing.isBoxedInt(handle)) { - receiver = PythonBuiltinClassType.PInt; - } else { - receiver = GetClassNode.executeUncached(context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(handle))); - } - - if (receiver == type) { - return 1; - } - - PythonBuiltinClassType receiverBuiltin = getBuiltinClass(receiver); - if (receiverBuiltin != null) { - PythonBuiltinClassType typeBuiltin = getBuiltinClass(type); - if (typeBuiltin == null) { - // builtin type cannot be a subclass of a non-builtin type - return 0; - } - // fast path for builtin types: walk class hierarchy - while (true) { - if (receiverBuiltin == typeBuiltin) { - return 1; - } - if (receiverBuiltin == PythonBuiltinClassType.PythonObject) { - return 0; - } - receiverBuiltin = receiverBuiltin.getBase(); - } - } - - try { - return IsSubtypeNode.getUncached().execute(receiver, type) ? 1 : 0; - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - return 0; - } - } - - /** - * Coerces an object to a native pointer (i.e. a {@code void *}; represented as Java - * {@code long}). This is similar to {@link #expectPointer(Object)} but will send - * {@link InteropLibrary#toNative(Object)} if the object is not a pointer already. - */ - static long coerceToPointer(Object value) { - if (value == null) { - return 0; - } - if (value instanceof Long) { - return (long) value; - } - if (value instanceof NativePointer nativePointer) { - return nativePointer.asPointer(); - } - return interopPointerToNative(value, InteropLibrary.getUncached(value)); - } - - /** - * Expects an object that can be casted (without coercion) to a native pointer (i.e. a - * {@code void *}; represented as Java {@code long}). This method will return {@code 0} in case - * of errors. - */ - public static long expectPointer(Object value) { - if (value instanceof Long) { - return (long) value; - } - InteropLibrary interopLibrary = InteropLibrary.getUncached(value); - if (interopLibrary.isPointer(value)) { - try { - return interopLibrary.asPointer(value); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere("cannot cast " + value); - } - } - return 0; - } - - private long createHPyObject(long typeHandle, long dataOutVar) { - Object type = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(typeHandle)); - PythonObject pythonObject; - - /* - * Check if argument is actually a type. We will only accept PythonClass because that's the - * only one that makes sense here. - */ - if (type instanceof PythonClass clazz) { - // allocate native space - long basicSize = clazz.getBasicSize(); - if (basicSize == -1) { - // create the managed Python object - pythonObject = slowPathFactory.createPythonObject(clazz, clazz.getInstanceShape()); - } else { - /* - * Since this is a JNI upcall method, we know that (1) we are not running in some - * managed mode, and (2) the data will be used in real native code. Hence, we can - * immediately allocate native memory via Unsafe. - */ - long dataPtr = UNSAFE.allocateMemory(basicSize); - UNSAFE.setMemory(dataPtr, basicSize, (byte) 0); - if (dataOutVar != 0) { - UNSAFE.putAddress(dataOutVar, dataPtr); - } - pythonObject = slowPathFactory.createPythonHPyObject(clazz, dataPtr); - Object destroyFunc = clazz.getHPyDestroyFunc(); - context.createHandleReference(pythonObject, dataPtr, destroyFunc != PNone.NO_VALUE ? destroyFunc : null); - } - Object defaultCallFunc = clazz.getHPyDefaultCallFunc(); - if (defaultCallFunc != null) { - GraalHPyData.setHPyCallFunction(pythonObject, defaultCallFunc); - } - } else { - // check if argument is still a type (e.g. a built-in type, ...) - if (!IsTypeNode.executeUncached(type)) { - return HPyRaiseNodeGen.getUncached().raiseIntWithoutFrame(context, 0, PythonBuiltinClassType.TypeError, ErrorMessages.HPY_NEW_ARG_1_MUST_BE_A_TYPE); - } - // TODO(fa): this should actually call __new__ - pythonObject = slowPathFactory.createPythonObject(type); - } - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(pythonObject)); - } - - // {{start ctx funcs}} - public int ctxTypeCheck(long bits, long typeBits) { - increment(HPyJNIUpcall.HPyTypeCheck); - Object type = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(typeBits)); - return typeCheck(bits, type); - } - - public int ctxTypeCheckg(long bits, long typeGlobalBits) { - increment(HPyJNIUpcall.HPyTypeCheck); - Object type = context.getObjectForHPyGlobal(GraalHPyBoxing.unboxHandle(typeGlobalBits)); - return typeCheck(bits, type); - } - - public long ctxLength(long handle) { - increment(HPyJNIUpcall.HPyLength); - assert GraalHPyBoxing.isBoxedHandle(handle); - - Object receiver = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(handle)); - - Object clazz = GetClassNode.executeUncached(receiver); - if (clazz == PythonBuiltinClassType.PList || clazz == PythonBuiltinClassType.PTuple) { - PSequence sequence = (PSequence) receiver; - SequenceStorage storage = sequence.getSequenceStorage(); - return storage.length(); - } - try { - return PyObjectSizeNodeGen.executeUncached(receiver); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - return -1; - } - } - - public int ctxListCheck(long handle) { - increment(HPyJNIUpcall.HPyListCheck); - if (GraalHPyBoxing.isBoxedHandle(handle)) { - Object obj = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(handle)); - Object clazz = GetClassNode.executeUncached(obj); - return PInt.intValue(clazz == PythonBuiltinClassType.PList || IsSubtypeNodeGen.getUncached().execute(clazz, PythonBuiltinClassType.PList)); - } else { - return 0; - } - } - - public long ctxUnicodeFromWideChar(long wcharArrayPtr, long size) { - increment(HPyJNIUpcall.HPyUnicodeFromWideChar); - - if (!PInt.isIntRange(size)) { - // NULL handle - return 0; - } - int isize = (int) size; - // TODO GR-37216: use TruffleString.FromNativePointer? - char[] decoded = new char[isize]; - for (int i = 0; i < size; i++) { - int wchar = UNSAFE.getInt(wcharArrayPtr + (long) Integer.BYTES * i); - if (Character.isBmpCodePoint(wchar)) { - decoded[i] = (char) wchar; - } else { - // TODO(fa): handle this case - throw new RuntimeException(); - } - } - TruffleString result = toTruffleStringUncached(new String(decoded, 0, isize)); - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(result)); - } - - public long ctxUnicodeFromJCharArray(char[] arr) { - increment(HPyJNIUpcall.HPyUnicodeFromJCharArray); - TruffleString string = TruffleString.fromCharArrayUTF16Uncached(arr).switchEncodingUncached(TS_ENCODING); - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(string)); - } - - public long ctxDictNew() { - increment(HPyJNIUpcall.HPyDictNew); - PDict dict = slowPathFactory.createDict(); - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(dict)); - } - - public long ctxListNew(long llen) { - try { - increment(HPyJNIUpcall.HPyListNew); - int len = CastToJavaIntExactNode.executeUncached(llen); - Object[] data = new Object[len]; - Arrays.fill(data, PNone.NONE); - PList list = slowPathFactory.createList(data); - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(list)); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - // NULL handle - return 0; - } - } - - /** - * Implementation of context function {@code ctx_Tuple_FromArray} (JNI upcall). This method can - * optionally steal the item handles in order to avoid repeated upcalls just to close them. This - * is useful to implement, e.g., tuple builder. - */ - public long ctxSequenceFromArray(long[] hItems, boolean steal, boolean create_list) { - increment(HPyJNIUpcall.HPySequenceFromArray); - - Object[] objects = new Object[hItems.length]; - for (int i = 0; i < hItems.length; i++) { - long hBits = hItems[i]; - objects[i] = context.bitsAsPythonObject(hBits); - if (steal) { - closeNativeHandle(hBits); - } - } - Object result; - if (create_list) { - result = slowPathFactory.createList(objects); - } else { - result = slowPathFactory.createTuple(objects); - } - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(result)); - } - - public long ctxFieldLoad(long bits, long idx) { - increment(HPyJNIUpcall.HPyFieldLoad); - Object owner = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(bits)); - // HPyField index is always non-zero because zero means: uninitialized - assert idx > 0; - Object referent = GraalHPyData.getHPyField((PythonObject) owner, (int) idx); - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(referent)); - } - - public long ctxFieldStore(long bits, long idx, long value) { - increment(HPyJNIUpcall.HPyFieldStore); - PythonObject owner = (PythonObject) context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(bits)); - Object referent = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(value)); - return GraalHPyData.setHPyField(owner, referent, (int) idx); - } - - public long ctxGlobalLoad(long bits) { - increment(HPyJNIUpcall.HPyGlobalLoad); - assert GraalHPyBoxing.isBoxedHandle(bits); - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(context.getObjectForHPyGlobal(GraalHPyBoxing.unboxHandle(bits)))); - } - - public long ctxGlobalStore(long bits, long v) { - increment(HPyJNIUpcall.HPyGlobalStore); - assert GraalHPyBoxing.isBoxedHandle(bits); - return context.createGlobal(context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(v)), GraalHPyBoxing.unboxHandle(bits)); - } - - public long ctxType(long bits) { - increment(HPyJNIUpcall.HPyType); - Object clazz; - if (GraalHPyBoxing.isBoxedHandle(bits)) { - clazz = GetClassNode.executeUncached(context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(bits))); - } else if (GraalHPyBoxing.isBoxedInt(bits)) { - clazz = GetClassNode.executeUncached(GraalHPyBoxing.unboxInt(bits)); - } else if (GraalHPyBoxing.isBoxedDouble(bits)) { - clazz = GetClassNode.executeUncached(GraalHPyBoxing.unboxDouble(bits)); - } else { - assert false; - clazz = null; - } - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(clazz)); - } - - public long ctxTypeGetName(long bits) { - increment(HPyJNIUpcall.HPyTypeGetName); - assert GraalHPyBoxing.isBoxedHandle(bits); - Object clazz = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(bits)); - Object tpName = HPyTypeGetNameNode.executeUncached(context, clazz); - try { - return coerceToPointer(tpName); - } catch (CannotCastException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } - - public long ctxContextVarGet(long varBits, long defBits, long errBits) { - increment(HPyJNIUpcall.HPyContextVarGet); - assert GraalHPyBoxing.isBoxedHandle(varBits); - Object var = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(varBits)); - if (!(var instanceof PContextVar)) { - try { - throw PRaiseNode.raiseUncached(null, TypeError, ErrorMessages.INSTANCE_OF_CONTEXTVAR_EXPECTED); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - } - return errBits; - } - PythonContext ctx = getContext(); - PythonLanguage lang = ctx.getLanguage(); - Object def = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(defBits)); - Object res = GraalHPyContextVarGet.getObject(ctx.getThreadState(lang), (PContextVar) var, def); - if (res == GraalHPyHandle.NULL_HANDLE_DELEGATE) { - return 0; - } - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(res)); - } - - public int ctxIs(long aBits, long bBits) { - Object a = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(aBits)); - Object b = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(bBits)); - try { - return PInt.intValue(IsNodeGen.getUncached().execute(a, b)); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - return -1; - } - } - - public int ctxIsg(long aBits, long bBits) { - Object a = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(aBits)); - Object b = context.getObjectForHPyGlobal(GraalHPyBoxing.unboxHandle(bBits)); - try { - return PInt.intValue(IsNodeGen.getUncached().execute(a, b)); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - return -1; - } - } - - public long ctxCapsuleNew(long pointer, long name, long destructor) { - if (pointer == 0) { - return HPyRaiseNodeGen.getUncached().raiseIntWithoutFrame(context, 0, ValueError, ErrorMessages.HPYCAPSULE_NEW_NULL_PTR_ERROR); - } - long hpyDestructor; - if (destructor != 0) { - long cpyTrampoline = UNSAFE.getLong(destructor); // HPyCapsule_Destructor.cpy_trampoline - hpyDestructor = UNSAFE.getLong(destructor + SIZEOF_LONG); // HPyCapsule_Destructor.impl - if (cpyTrampoline == 0 || hpyDestructor == 0) { - return HPyRaiseNodeGen.getUncached().raiseIntWithoutFrame(context, 0, ValueError, ErrorMessages.INVALID_HPYCAPSULE_DESTRUCTOR); - } - } else { - hpyDestructor = 0; - } - PyCapsule result = slowPathFactory.createCapsuleNativeName(pointer, new NativePointer(name)); - if (hpyDestructor != 0) { - result.registerDestructor(hpyDestructor); - } - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(result)); - } - - static boolean capsuleNameMatches(long name1, long name2) { - // additional shortcut (compared to CPython) to avoid a unnecessary downcalls - if (name1 == name2) { - return true; - } - /* - * If one of them is NULL, then both need to be NULL. However, at this point we have - * invariant 'name1 != name2' because of the above shortcut. - */ - if (name1 == 0 || name2 == 0) { - return false; - } - return strcmp(name1, name2) == 0; - } - - public long ctxCapsuleGet(long capsuleBits, int key, long namePtr) { - Object capsule = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(capsuleBits)); - try { - if (!(capsule instanceof PyCapsule pyCapsule) || pyCapsule.getPointer() == null) { - return HPyRaiseNodeGen.getUncached().raiseIntWithoutFrame(context, 0, ValueError, GraalHPyCapsuleGet.getErrorMessage(key)); - } - GraalHPyCapsuleGet.isLegalCapsule(capsule, key, PRaiseNode.getUncached()); - Object result; - switch (key) { - case CapsuleKey.Pointer -> { - if (!capsuleNameMatches(namePtr, coerceToPointer(pyCapsule.getNamePtr()))) { - return HPyRaiseNodeGen.getUncached().raiseIntWithoutFrame(context, 0, ValueError, GraalHPyCapsuleGet.INCORRECT_NAME); - } - result = pyCapsule.getPointer(); - } - case CapsuleKey.Context -> result = pyCapsule.getContext(); - // The capsule's name may either be a native pointer or a TruffleString. - case CapsuleKey.Name -> result = pyCapsule.getNamePtr(); - case CapsuleKey.Destructor -> result = pyCapsule.getDestructor(); - default -> throw CompilerDirectives.shouldNotReachHere("invalid key"); - } - return coerceToPointer(result); - } catch (CannotCastException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } - - public long ctxGetAttrs(long receiverHandle, String name) { - increment(HPyJNIUpcall.HPyGetAttrs); - Object receiver = context.bitsAsPythonObject(receiverHandle); - TruffleString tsName = toTruffleStringUncached(name); - Object result; - try { - result = PyObjectGetAttr.executeUncached(receiver, tsName); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - return 0; - } - return context.pythonObjectAsBits(result); - } - - @SuppressWarnings("static-method") - public long ctxFloatFromDouble(double value) { - increment(HPyJNIUpcall.HPyFloatFromDouble); - return GraalHPyBoxing.boxDouble(value); - } - - public double ctxFloatAsDouble(long handle) { - increment(HPyJNIUpcall.HPyFloatAsDouble); - - if (GraalHPyBoxing.isBoxedDouble(handle)) { - return GraalHPyBoxing.unboxDouble(handle); - } else if (GraalHPyBoxing.isBoxedInt(handle)) { - return GraalHPyBoxing.unboxInt(handle); - } else { - Object object = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(handle)); - try { - return PyFloatAsDoubleNode.executeUncached(object); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - return -1.0; - } - } - } - - public int ctxLongAsInt32t(long h) { - increment(HPyJNIUpcall.HPyLongAsInt32t); - if (GraalHPyBoxing.isBoxedInt(h)) { - return GraalHPyBoxing.unboxInt(h); - } - return executeIntBinaryContextFunction(HPyContextMember.CTX_LONG_ASINT32_T, h); - } - - public int ctxLongAsUInt32t(long h) { - increment(HPyJNIUpcall.HPyLongAsUInt32t); - // we may only unbox positive values; negative values will raise an error - int unboxedVal; - if (GraalHPyBoxing.isBoxedInt(h) && (unboxedVal = GraalHPyBoxing.unboxInt(h)) >= 0) { - return unboxedVal; - } - return executeIntBinaryContextFunction(HPyContextMember.CTX_LONG_ASUINT32_T, h); - } - - public int ctxLongAsUInt32tMask(long h) { - increment(HPyJNIUpcall.HPyLongAsUInt32tMask); - if (GraalHPyBoxing.isBoxedInt(h)) { - return GraalHPyBoxing.unboxInt(h); - } - return executeIntBinaryContextFunction(HPyContextMember.CTX_LONG_ASUINT32_TMASK, h); - } - - public long ctxLongAsInt64t(long handle) { - increment(HPyJNIUpcall.HPyLongAsInt64t); - - if (GraalHPyBoxing.isBoxedInt(handle)) { - return GraalHPyBoxing.unboxInt(handle); - } else { - Object object = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(handle)); - try { - return (long) AsNativePrimitiveNodeGen.getUncached().execute(object, 1, java.lang.Long.BYTES, true); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - return -1L; - } - } - } - - public long ctxLongAsUInt64t(long h) { - increment(HPyJNIUpcall.HPyLongAsUInt64t); - return executeLongBinaryContextFunction(HPyContextMember.CTX_LONG_ASUINT64_T, h); - } - - public long ctxLongAsUInt64tMask(long h) { - increment(HPyJNIUpcall.HPyLongAsUInt64tMask); - return executeLongBinaryContextFunction(HPyContextMember.CTX_LONG_ASUINT64_TMASK, h); - } - - public double ctxLongAsDouble(long handle) { - increment(HPyJNIUpcall.HPyLongAsDouble); - - if (GraalHPyBoxing.isBoxedInt(handle)) { - return GraalHPyBoxing.unboxInt(handle); - } else { - Object object = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(handle)); - try { - return PyLongAsDoubleNode.executeUncached(object); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - return -1L; - } - } - } - - public long ctxLongFromInt32t(int v) { - increment(HPyJNIUpcall.HPyLongFromInt32t); - return GraalHPyBoxing.boxInt(v); - } - - public long ctxLongFromUInt32t(int value) { - increment(HPyJNIUpcall.HPyLongFromUInt32t); - return executeLongBinaryContextFunction(HPyContextMember.CTX_LONG_FROMUINT32_T, value); - } - - public long ctxLongFromInt64t(long v) { - increment(HPyJNIUpcall.HPyLongFromInt64t); - if (PInt.isIntRange(v)) { - return GraalHPyBoxing.boxInt((int) v); - } - return executeLongBinaryContextFunction(HPyContextMember.CTX_LONG_FROMINT64_T, v); - } - - public long ctxLongFromUInt64t(long v) { - increment(HPyJNIUpcall.HPyLongFromUInt64t); - return executeLongBinaryContextFunction(HPyContextMember.CTX_LONG_FROMUINT64_T, v); - } - - public long ctxBoolFromBool(boolean v) { - increment(HPyJNIUpcall.HPyBoolFromBool); - Python3Core core = context.getContext(); - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(v ? core.getTrue() : core.getFalse())); - } - - public long ctxAsStructObject(long h) { - increment(HPyJNIUpcall.HPyAsStructObject); - Object receiver = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(h)); - return expectPointer(HPyGetNativeSpacePointerNode.executeUncached(receiver)); - } - - public long ctxAsStructLegacy(long h) { - increment(HPyJNIUpcall.HPyAsStructLegacy); - Object receiver = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(h)); - return expectPointer(HPyGetNativeSpacePointerNode.executeUncached(receiver)); - } - - public long ctxAsStructType(long h) { - increment(HPyJNIUpcall.HPyAsStructType); - Object receiver = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(h)); - return expectPointer(HPyGetNativeSpacePointerNode.executeUncached(receiver)); - } - - public long ctxAsStructLong(long h) { - increment(HPyJNIUpcall.HPyAsStructLong); - Object receiver = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(h)); - return expectPointer(HPyGetNativeSpacePointerNode.executeUncached(receiver)); - } - - public long ctxAsStructFloat(long h) { - increment(HPyJNIUpcall.HPyAsStructFloat); - Object receiver = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(h)); - return expectPointer(HPyGetNativeSpacePointerNode.executeUncached(receiver)); - } - - public long ctxAsStructUnicode(long h) { - increment(HPyJNIUpcall.HPyAsStructUnicode); - Object receiver = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(h)); - return expectPointer(HPyGetNativeSpacePointerNode.executeUncached(receiver)); - } - - public long ctxAsStructTuple(long h) { - increment(HPyJNIUpcall.HPyAsStructTuple); - Object receiver = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(h)); - return expectPointer(HPyGetNativeSpacePointerNode.executeUncached(receiver)); - } - - public long ctxAsStructList(long h) { - increment(HPyJNIUpcall.HPyAsStructList); - Object receiver = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(h)); - return expectPointer(HPyGetNativeSpacePointerNode.executeUncached(receiver)); - } - - // Note: assumes that receiverHandle is not a boxed primitive value - public int ctxSetItems(long receiverHandle, String name, long valueHandle) { - increment(HPyJNIUpcall.HPySetItems); - Object receiver = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(receiverHandle)); - Object value = context.bitsAsPythonObject(valueHandle); - if (value == GraalHPyHandle.NULL_HANDLE_DELEGATE) { - HPyRaiseNode.raiseIntUncached(context, -1, SystemError, ErrorMessages.HPY_UNEXPECTED_HPY_NULL); - return -1; - } - TruffleString tsName = toTruffleStringUncached(name); - try { - PyObjectSetItem.executeUncached(receiver, tsName, value); - return 0; - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - return -1; - } - } - - // Note: assumes that receiverHandle is not a boxed primitive value - public long ctxGetItems(long receiverHandle, String name) { - increment(HPyJNIUpcall.HPyGetItems); - Object receiver = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(receiverHandle)); - TruffleString tsName = toTruffleStringUncached(name); - Object result; - try { - result = PyObjectGetItem.executeUncached(receiver, tsName); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - return 0; - } - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(result)); - } - - public long ctxNew(long typeHandle, long dataOutVar) { - increment(HPyJNIUpcall.HPyNew); - return createHPyObject(typeHandle, dataOutVar); - } - - @SuppressWarnings("unused") - public long ctxTypeGenericNew(long typeHandle, long args, long nargs, long kw) { - increment(HPyJNIUpcall.HPyTypeGenericNew); - return createHPyObject(typeHandle, 0); - } - - /** - * Close a native handle received from a JNI upcall (hence represented by a Java {code long}). - */ - private void closeNativeHandle(long handle) { - if (GraalHPyBoxing.isBoxedHandle(handle)) { - context.releaseHPyHandleForObject(GraalHPyBoxing.unboxHandle(handle)); - } - } - - public void ctxClose(long handle) { - increment(HPyJNIUpcall.HPyClose); - closeNativeHandle(handle); - } - - public void ctxBulkClose(long unclosedHandlePtr, int size) { - increment(HPyJNIUpcall.HPyBulkClose); - for (int i = 0; i < size; i++) { - long handle = UNSAFE.getLong(unclosedHandlePtr); - unclosedHandlePtr += 8; - assert GraalHPyBoxing.isBoxedHandle(handle); - assert handle >= IMMUTABLE_HANDLE_COUNT; - context.releaseHPyHandleForObject(GraalHPyBoxing.unboxHandle(handle)); - } - } - - public long ctxDup(long handle) { - increment(HPyJNIUpcall.HPyDup); - if (GraalHPyBoxing.isBoxedHandle(handle)) { - Object delegate = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(handle)); - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(delegate)); - } else { - return handle; - } - } - - public long ctxGetItemi(long hCollection, long lidx) { - increment(HPyJNIUpcall.HPyGetItemi); - try { - // If handle 'hCollection' is a boxed int or double, the object is not subscriptable. - if (!GraalHPyBoxing.isBoxedHandle(hCollection)) { - throw PRaiseNode.raiseUncached(null, PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_NOT_SUBSCRIPTABLE, 0); - } - Object receiver = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(hCollection)); - Object clazz = GetClassNode.executeUncached(receiver); - if (clazz == PythonBuiltinClassType.PList || clazz == PythonBuiltinClassType.PTuple) { - if (!PInt.isIntRange(lidx)) { - throw PRaiseNode.raiseUncached(null, PythonBuiltinClassType.IndexError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, lidx); - } - int idx = (int) lidx; - PSequence sequence = (PSequence) receiver; - SequenceStorage storage = sequence.getSequenceStorage(); - if (storage instanceof IntSequenceStorage) { - return GraalHPyBoxing.boxInt(((IntSequenceStorage) storage).getIntItemNormalized(idx)); - } else if (storage instanceof DoubleSequenceStorage) { - return GraalHPyBoxing.boxDouble(((DoubleSequenceStorage) storage).getDoubleItemNormalized(idx)); - } else if (storage instanceof LongSequenceStorage) { - long lresult = ((LongSequenceStorage) storage).getLongItemNormalized(idx); - if (com.oracle.graal.python.builtins.objects.ints.PInt.isIntRange(lresult)) { - return GraalHPyBoxing.boxInt((int) lresult); - } - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(lresult)); - } else if (storage instanceof ObjectSequenceStorage) { - Object result = ((ObjectSequenceStorage) storage).getObjectItemNormalized(idx); - if (result instanceof Integer) { - return GraalHPyBoxing.boxInt((int) result); - } else if (result instanceof Double) { - return GraalHPyBoxing.boxDouble((double) result); - } - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(result)); - } - // TODO: other storages... - } - Object result = PyObjectGetItem.executeUncached(receiver, lidx); - return GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(result)); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - // NULL handle - return 0; - } - } - - /** - * HPy signature: {@code HPy_SetItem(HPyContext ctx, HPy obj, HPy key, HPy value)} - * - * @param hSequence - * @param hKey - * @param hValue - * @return {@code 0} on success; {@code -1} on error - */ - public int ctxSetItem(long hSequence, long hKey, long hValue) { - increment(HPyJNIUpcall.HPySetItem); - try { - // If handle 'hSequence' is a boxed int or double, the object is not a sequence. - if (!GraalHPyBoxing.isBoxedHandle(hSequence)) { - throw PRaiseNode.raiseUncached(null, PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_DOES_NOT_SUPPORT_ITEM_ASSIGMENT, 0); - } - Object receiver = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(hSequence)); - Object clazz = GetClassNode.executeUncached(receiver); - Object key = HPyAsPythonObjectNodeGen.getUncached().execute(hKey); - Object value = HPyAsPythonObjectNodeGen.getUncached().execute(hValue); - - // fast path - if (clazz == PythonBuiltinClassType.PDict) { - PDict dict = (PDict) receiver; - HashingStorage dictStorage = dict.getDictStorage(); - - // super-fast path for string keys - if (key instanceof TruffleString) { - if (dictStorage instanceof EmptyStorage) { - dictStorage = PDict.createNewStorage(1); - dict.setDictStorage(dictStorage); - } - - if (dictStorage instanceof EconomicMapStorage) { - ((EconomicMapStorage) dictStorage).putUncached((TruffleString) key, value); - return 0; - } - // fall through to generic case - } - dict.setDictStorage(HashingStorageSetItem.executeUncached(dictStorage, key, value)); - return 0; - } else if (clazz == PythonBuiltinClassType.PList && PGuards.isInteger(key) && ctxListSetItem(receiver, ((Number) key).longValue(), hValue)) { - return 0; - } - PyObjectSetItem.executeUncached(receiver, key, value); - return 0; - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - // non-null value indicates an error - return -1; - } - } - - public int ctxSetItemi(long hSequence, long lidx, long hValue) { - increment(HPyJNIUpcall.HPySetItemi); - try { - // If handle 'hSequence' is a boxed int or double, the object is not a sequence. - if (!GraalHPyBoxing.isBoxedHandle(hSequence)) { - throw PRaiseNode.raiseUncached(null, PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_DOES_NOT_SUPPORT_ITEM_ASSIGMENT, 0); - } - Object receiver = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(hSequence)); - Object clazz = GetClassNode.executeUncached(receiver); - - if (clazz == PythonBuiltinClassType.PList && ctxListSetItem(receiver, lidx, hValue)) { - return 0; - } - Object value = HPyAsPythonObjectNodeGen.getUncached().execute(hValue); - PyObjectSetItem.executeUncached(receiver, lidx, value); - return 0; - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - // non-null value indicates an error - return -1; - } - } - - private boolean ctxListSetItem(Object receiver, long lidx, long hValue) { - // fast path for list - if (!PInt.isIntRange(lidx)) { - throw PRaiseNode.raiseUncached(null, PythonBuiltinClassType.IndexError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, lidx); - } - int idx = (int) lidx; - PList sequence = (PList) receiver; - SequenceStorage storage = sequence.getSequenceStorage(); - if (storage instanceof IntSequenceStorage && GraalHPyBoxing.isBoxedInt(hValue)) { - ((IntSequenceStorage) storage).setIntItemNormalized(idx, GraalHPyBoxing.unboxInt(hValue)); - return true; - } else if (storage instanceof DoubleSequenceStorage && GraalHPyBoxing.isBoxedDouble(hValue)) { - ((DoubleSequenceStorage) storage).setDoubleItemNormalized(idx, GraalHPyBoxing.unboxDouble(hValue)); - return true; - } else if (storage instanceof LongSequenceStorage && GraalHPyBoxing.isBoxedInt(hValue)) { - ((LongSequenceStorage) storage).setLongItemNormalized(idx, GraalHPyBoxing.unboxInt(hValue)); - return true; - } else if (storage instanceof ObjectSequenceStorage) { - Object value = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(hValue)); - ((ObjectSequenceStorage) storage).setObjectItemNormalized(idx, value); - return true; - } - // TODO: other storages... - return false; - } - - public int ctxNumberCheck(long handle) { - increment(HPyJNIUpcall.HPyNumberCheck); - if (GraalHPyBoxing.isBoxedDouble(handle) || GraalHPyBoxing.isBoxedInt(handle)) { - return 1; - } - Object receiver = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(handle)); - - try { - return PInt.intValue(PyNumberCheckNode.executeUncached(receiver)); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(context, e); - return 0; - } - } - - public long ctxLongFromSizet(long value) { - increment(HPyJNIUpcall.HPyLongFromSizet); - return executeLongBinaryContextFunction(HPyContextMember.CTX_LONG_FROMSIZE_T, value); - } - - public long ctxLongFromSsizet(long value) { - increment(HPyJNIUpcall.HPyLongFromSsizet); - return executeLongBinaryContextFunction(HPyContextMember.CTX_LONG_FROMSSIZE_T, value); - } - - public long ctxLongAsSizet(long h) { - increment(HPyJNIUpcall.HPyLongAsSizet); - return executeLongBinaryContextFunction(HPyContextMember.CTX_LONG_ASSIZE_T, h); - } - - public long ctxLongAsSsizet(long h) { - increment(HPyJNIUpcall.HPyLongAsSsizet); - return executeLongBinaryContextFunction(HPyContextMember.CTX_LONG_ASSSIZE_T, h); - } - - public long ctxLongAsVoidPtr(long h) { - increment(HPyJNIUpcall.HPyLongAsVoidPtr); - return executeLongBinaryContextFunction(HPyContextMember.CTX_LONG_ASVOIDPTR, h); - } - - public long ctxAdd(long h1, long h2) { - increment(HPyJNIUpcall.HPyAdd); - return executeLongTernaryContextFunction(HPyContextMember.CTX_ADD, h1, h2); - } - - public long ctxSubtract(long h1, long h2) { - increment(HPyJNIUpcall.HPySubtract); - return executeLongTernaryContextFunction(HPyContextMember.CTX_SUBTRACT, h1, h2); - } - - public long ctxMultiply(long h1, long h2) { - increment(HPyJNIUpcall.HPyMultiply); - return executeLongTernaryContextFunction(HPyContextMember.CTX_MULTIPLY, h1, h2); - } - - public long ctxMatrixMultiply(long h1, long h2) { - increment(HPyJNIUpcall.HPyMatrixMultiply); - return executeLongTernaryContextFunction(HPyContextMember.CTX_MATRIXMULTIPLY, h1, h2); - } - - public long ctxFloorDivide(long h1, long h2) { - increment(HPyJNIUpcall.HPyFloorDivide); - return executeLongTernaryContextFunction(HPyContextMember.CTX_FLOORDIVIDE, h1, h2); - } - - public long ctxTrueDivide(long h1, long h2) { - increment(HPyJNIUpcall.HPyTrueDivide); - return executeLongTernaryContextFunction(HPyContextMember.CTX_TRUEDIVIDE, h1, h2); - } - - public long ctxRemainder(long h1, long h2) { - increment(HPyJNIUpcall.HPyRemainder); - return executeLongTernaryContextFunction(HPyContextMember.CTX_REMAINDER, h1, h2); - } - - public long ctxDivmod(long h1, long h2) { - increment(HPyJNIUpcall.HPyDivmod); - return executeLongTernaryContextFunction(HPyContextMember.CTX_DIVMOD, h1, h2); - } - - public long ctxPower(long h1, long h2, long h3) { - increment(HPyJNIUpcall.HPyPower); - return executeLongContextFunction(HPyContextMember.CTX_POWER, new long[]{h1, h2, h3}); - } - - public long ctxNegative(long h1) { - increment(HPyJNIUpcall.HPyNegative); - return executeLongBinaryContextFunction(HPyContextMember.CTX_NEGATIVE, h1); - } - - public long ctxPositive(long h1) { - increment(HPyJNIUpcall.HPyPositive); - return executeLongBinaryContextFunction(HPyContextMember.CTX_POSITIVE, h1); - } - - public long ctxAbsolute(long h1) { - increment(HPyJNIUpcall.HPyAbsolute); - return executeLongBinaryContextFunction(HPyContextMember.CTX_ABSOLUTE, h1); - } - - public long ctxInvert(long h1) { - increment(HPyJNIUpcall.HPyInvert); - return executeLongBinaryContextFunction(HPyContextMember.CTX_INVERT, h1); - } - - public long ctxLshift(long h1, long h2) { - increment(HPyJNIUpcall.HPyLshift); - return executeLongTernaryContextFunction(HPyContextMember.CTX_LSHIFT, h1, h2); - } - - public long ctxRshift(long h1, long h2) { - increment(HPyJNIUpcall.HPyRshift); - return executeLongTernaryContextFunction(HPyContextMember.CTX_RSHIFT, h1, h2); - } - - public long ctxAnd(long h1, long h2) { - increment(HPyJNIUpcall.HPyAnd); - return executeLongTernaryContextFunction(HPyContextMember.CTX_AND, h1, h2); - } - - public long ctxXor(long h1, long h2) { - increment(HPyJNIUpcall.HPyXor); - return executeLongTernaryContextFunction(HPyContextMember.CTX_XOR, h1, h2); - } - - public long ctxOr(long h1, long h2) { - increment(HPyJNIUpcall.HPyOr); - return executeLongTernaryContextFunction(HPyContextMember.CTX_OR, h1, h2); - } - - public long ctxIndex(long h1) { - increment(HPyJNIUpcall.HPyIndex); - return executeLongBinaryContextFunction(HPyContextMember.CTX_INDEX, h1); - } - - public long ctxLong(long h1) { - increment(HPyJNIUpcall.HPyLong); - return executeLongBinaryContextFunction(HPyContextMember.CTX_LONG, h1); - } - - public long ctxFloat(long h1) { - increment(HPyJNIUpcall.HPyFloat); - return executeLongBinaryContextFunction(HPyContextMember.CTX_FLOAT, h1); - } - - public long ctxInPlaceAdd(long h1, long h2) { - increment(HPyJNIUpcall.HPyInPlaceAdd); - return executeLongTernaryContextFunction(HPyContextMember.CTX_INPLACEADD, h1, h2); - } - - public long ctxInPlaceSubtract(long h1, long h2) { - increment(HPyJNIUpcall.HPyInPlaceSubtract); - return executeLongTernaryContextFunction(HPyContextMember.CTX_INPLACESUBTRACT, h1, h2); - } - - public long ctxInPlaceMultiply(long h1, long h2) { - increment(HPyJNIUpcall.HPyInPlaceMultiply); - return executeLongTernaryContextFunction(HPyContextMember.CTX_INPLACEMULTIPLY, h1, h2); - } - - public long ctxInPlaceMatrixMultiply(long h1, long h2) { - increment(HPyJNIUpcall.HPyInPlaceMatrixMultiply); - return executeLongTernaryContextFunction(HPyContextMember.CTX_INPLACEMATRIXMULTIPLY, h1, h2); - } - - public long ctxInPlaceFloorDivide(long h1, long h2) { - increment(HPyJNIUpcall.HPyInPlaceFloorDivide); - return executeLongTernaryContextFunction(HPyContextMember.CTX_INPLACEFLOORDIVIDE, h1, h2); - } - - public long ctxInPlaceTrueDivide(long h1, long h2) { - increment(HPyJNIUpcall.HPyInPlaceTrueDivide); - return executeLongTernaryContextFunction(HPyContextMember.CTX_INPLACETRUEDIVIDE, h1, h2); - } - - public long ctxInPlaceRemainder(long h1, long h2) { - increment(HPyJNIUpcall.HPyInPlaceRemainder); - return executeLongTernaryContextFunction(HPyContextMember.CTX_INPLACEREMAINDER, h1, h2); - } - - public long ctxInPlacePower(long h1, long h2, long h3) { - increment(HPyJNIUpcall.HPyInPlacePower); - return executeLongContextFunction(HPyContextMember.CTX_INPLACEPOWER, new long[]{h1, h2, h3}); - } - - public long ctxInPlaceLshift(long h1, long h2) { - increment(HPyJNIUpcall.HPyInPlaceLshift); - return executeLongTernaryContextFunction(HPyContextMember.CTX_INPLACELSHIFT, h1, h2); - } - - public long ctxInPlaceRshift(long h1, long h2) { - increment(HPyJNIUpcall.HPyInPlaceRshift); - return executeLongTernaryContextFunction(HPyContextMember.CTX_INPLACERSHIFT, h1, h2); - } - - public long ctxInPlaceAnd(long h1, long h2) { - increment(HPyJNIUpcall.HPyInPlaceAnd); - return executeLongTernaryContextFunction(HPyContextMember.CTX_INPLACEAND, h1, h2); - } - - public long ctxInPlaceXor(long h1, long h2) { - increment(HPyJNIUpcall.HPyInPlaceXor); - return executeLongTernaryContextFunction(HPyContextMember.CTX_INPLACEXOR, h1, h2); - } - - public long ctxInPlaceOr(long h1, long h2) { - increment(HPyJNIUpcall.HPyInPlaceOr); - return executeLongTernaryContextFunction(HPyContextMember.CTX_INPLACEOR, h1, h2); - } - - public int ctxCallableCheck(long h) { - increment(HPyJNIUpcall.HPyCallableCheck); - return executeIntBinaryContextFunction(HPyContextMember.CTX_CALLABLE_CHECK, h); - } - - public long ctxCallTupleDict(long callable, long args, long kw) { - increment(HPyJNIUpcall.HPyCallTupleDict); - return executeLongContextFunction(HPyContextMember.CTX_CALLTUPLEDICT, new long[]{callable, args, kw}); - } - - public void ctxFatalError(long message) { - increment(HPyJNIUpcall.HPyFatalError); - executeIntBinaryContextFunction(HPyContextMember.CTX_FATALERROR, message); - } - - public void ctxErrSetString(long h_type, long message) { - increment(HPyJNIUpcall.HPyErrSetString); - executeIntTernaryContextFunction(HPyContextMember.CTX_ERR_SETSTRING, h_type, message); - } - - public void ctxErrSetObject(long h_type, long h_value) { - increment(HPyJNIUpcall.HPyErrSetObject); - executeIntTernaryContextFunction(HPyContextMember.CTX_ERR_SETOBJECT, h_type, h_value); - } - - public long ctxErrSetFromErrnoWithFilename(long h_type, long filename_fsencoded) { - increment(HPyJNIUpcall.HPyErrSetFromErrnoWithFilename); - return executeLongTernaryContextFunction(HPyContextMember.CTX_ERR_SETFROMERRNOWITHFILENAME, h_type, filename_fsencoded); - } - - public void ctxErrSetFromErrnoWithFilenameObjects(long h_type, long filename1, long filename2) { - increment(HPyJNIUpcall.HPyErrSetFromErrnoWithFilenameObjects); - executeIntContextFunction(HPyContextMember.CTX_ERR_SETFROMERRNOWITHFILENAMEOBJECTS, new long[]{h_type, filename1, filename2}); - } - - public int ctxErrOccurred() { - increment(HPyJNIUpcall.HPyErrOccurred); - return executeIntContextFunction(HPyContextMember.CTX_ERR_OCCURRED, new long[]{}); - } - - public int ctxErrExceptionMatches(long exc) { - increment(HPyJNIUpcall.HPyErrExceptionMatches); - return executeIntBinaryContextFunction(HPyContextMember.CTX_ERR_EXCEPTIONMATCHES, exc); - } - - public void ctxErrNoMemory() { - increment(HPyJNIUpcall.HPyErrNoMemory); - executeIntContextFunction(HPyContextMember.CTX_ERR_NOMEMORY, new long[]{}); - } - - public void ctxErrClear() { - increment(HPyJNIUpcall.HPyErrClear); - executeIntContextFunction(HPyContextMember.CTX_ERR_CLEAR, new long[]{}); - } - - public long ctxErrNewException(long name, long base, long dict) { - increment(HPyJNIUpcall.HPyErrNewException); - return executeLongContextFunction(HPyContextMember.CTX_ERR_NEWEXCEPTION, new long[]{name, base, dict}); - } - - public long ctxErrNewExceptionWithDoc(long name, long doc, long base, long dict) { - increment(HPyJNIUpcall.HPyErrNewExceptionWithDoc); - return executeLongContextFunction(HPyContextMember.CTX_ERR_NEWEXCEPTIONWITHDOC, new long[]{name, doc, base, dict}); - } - - public int ctxErrWarnEx(long category, long message, long stack_level) { - increment(HPyJNIUpcall.HPyErrWarnEx); - return executeIntContextFunction(HPyContextMember.CTX_ERR_WARNEX, new long[]{category, message, stack_level}); - } - - public void ctxErrWriteUnraisable(long obj) { - increment(HPyJNIUpcall.HPyErrWriteUnraisable); - executeIntBinaryContextFunction(HPyContextMember.CTX_ERR_WRITEUNRAISABLE, obj); - } - - public int ctxIsTrue(long h) { - increment(HPyJNIUpcall.HPyIsTrue); - return executeIntBinaryContextFunction(HPyContextMember.CTX_ISTRUE, h); - } - - public long ctxTypeFromSpec(long spec, long params) { - increment(HPyJNIUpcall.HPyTypeFromSpec); - return executeLongTernaryContextFunction(HPyContextMember.CTX_TYPE_FROMSPEC, spec, params); - } - - public long ctxGetAttr(long obj, long name) { - increment(HPyJNIUpcall.HPyGetAttr); - return executeLongTernaryContextFunction(HPyContextMember.CTX_GETATTR, obj, name); - } - - public int ctxHasAttr(long obj, long name) { - increment(HPyJNIUpcall.HPyHasAttr); - return executeIntTernaryContextFunction(HPyContextMember.CTX_HASATTR, obj, name); - } - - public int ctxHasAttrs(long obj, long name) { - increment(HPyJNIUpcall.HPyHasAttrs); - return executeIntTernaryContextFunction(HPyContextMember.CTX_HASATTR_S, obj, name); - } - - public int ctxSetAttr(long obj, long name, long value) { - increment(HPyJNIUpcall.HPySetAttr); - return executeIntContextFunction(HPyContextMember.CTX_SETATTR, new long[]{obj, name, value}); - } - - public int ctxSetAttrs(long obj, long name, long value) { - increment(HPyJNIUpcall.HPySetAttrs); - return executeIntContextFunction(HPyContextMember.CTX_SETATTR_S, new long[]{obj, name, value}); - } - - public long ctxGetItem(long obj, long key) { - increment(HPyJNIUpcall.HPyGetItem); - return executeLongTernaryContextFunction(HPyContextMember.CTX_GETITEM, obj, key); - } - - public int ctxContains(long container, long key) { - increment(HPyJNIUpcall.HPyContains); - return executeIntTernaryContextFunction(HPyContextMember.CTX_CONTAINS, container, key); - } - - public int ctxTypeIsSubtype(long sub, long type) { - increment(HPyJNIUpcall.HPyTypeIsSubtype); - return executeIntTernaryContextFunction(HPyContextMember.CTX_TYPE_ISSUBTYPE, sub, type); - } - - public long ctxRepr(long obj) { - increment(HPyJNIUpcall.HPyRepr); - return executeLongBinaryContextFunction(HPyContextMember.CTX_REPR, obj); - } - - public long ctxStr(long obj) { - increment(HPyJNIUpcall.HPyStr); - return executeLongBinaryContextFunction(HPyContextMember.CTX_STR, obj); - } - - public long ctxASCII(long obj) { - increment(HPyJNIUpcall.HPyASCII); - return executeLongBinaryContextFunction(HPyContextMember.CTX_ASCII, obj); - } - - public long ctxBytes(long obj) { - increment(HPyJNIUpcall.HPyBytes); - return executeLongBinaryContextFunction(HPyContextMember.CTX_BYTES, obj); - } - - public long ctxRichCompare(long v, long w, int op) { - increment(HPyJNIUpcall.HPyRichCompare); - return executeLongContextFunction(HPyContextMember.CTX_RICHCOMPARE, new Object[]{v, w, op}); - } - - public int ctxRichCompareBool(long v, long w, int op) { - increment(HPyJNIUpcall.HPyRichCompareBool); - return executeIntContextFunction(HPyContextMember.CTX_RICHCOMPAREBOOL, new Object[]{v, w, op}); - } - - public long ctxHash(long obj) { - increment(HPyJNIUpcall.HPyHash); - return executeLongBinaryContextFunction(HPyContextMember.CTX_HASH, obj); - } - - public int ctxBytesCheck(long h) { - increment(HPyJNIUpcall.HPyBytesCheck); - if (GraalHPyBoxing.isBoxedHandle(h)) { - Object object = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(h)); - if (object instanceof PBytes) { - return 1; - } - return executeIntBinaryContextFunction(HPyContextMember.CTX_BYTES_CHECK, h); - } - return 0; - } - - public long ctxBytesSize(long h) { - increment(HPyJNIUpcall.HPyBytesSize); - return executeLongBinaryContextFunction(HPyContextMember.CTX_BYTES_SIZE, h); - } - - public long ctxBytesGETSIZE(long h) { - increment(HPyJNIUpcall.HPyBytesGETSIZE); - return executeLongBinaryContextFunction(HPyContextMember.CTX_BYTES_GET_SIZE, h); - } - - public long ctxBytesAsString(long h) { - increment(HPyJNIUpcall.HPyBytesAsString); - return executeLongBinaryContextFunction(HPyContextMember.CTX_BYTES_ASSTRING, h); - } - - public long ctxBytesASSTRING(long h) { - increment(HPyJNIUpcall.HPyBytesASSTRING); - return executeLongBinaryContextFunction(HPyContextMember.CTX_BYTES_AS_STRING, h); - } - - public long ctxBytesFromString(long v) { - increment(HPyJNIUpcall.HPyBytesFromString); - return executeLongBinaryContextFunction(HPyContextMember.CTX_BYTES_FROMSTRING, v); - } - - public long ctxBytesFromStringAndSize(long v, long len) { - increment(HPyJNIUpcall.HPyBytesFromStringAndSize); - return executeLongTernaryContextFunction(HPyContextMember.CTX_BYTES_FROMSTRINGANDSIZE, v, len); - } - - public long ctxUnicodeFromString(long utf8) { - increment(HPyJNIUpcall.HPyUnicodeFromString); - return executeLongBinaryContextFunction(HPyContextMember.CTX_UNICODE_FROMSTRING, utf8); - } - - public int ctxUnicodeCheck(long h) { - increment(HPyJNIUpcall.HPyUnicodeCheck); - return executeIntBinaryContextFunction(HPyContextMember.CTX_UNICODE_CHECK, h); - } - - public long ctxUnicodeAsASCIIString(long h) { - increment(HPyJNIUpcall.HPyUnicodeAsASCIIString); - return executeLongBinaryContextFunction(HPyContextMember.CTX_UNICODE_ASASCIISTRING, h); - } - - public long ctxUnicodeAsLatin1String(long h) { - increment(HPyJNIUpcall.HPyUnicodeAsLatin1String); - return executeLongBinaryContextFunction(HPyContextMember.CTX_UNICODE_ASLATIN1STRING, h); - } - - public long ctxUnicodeAsUTF8String(long h) { - increment(HPyJNIUpcall.HPyUnicodeAsUTF8String); - return executeLongBinaryContextFunction(HPyContextMember.CTX_UNICODE_ASUTF8STRING, h); - } - - public long ctxUnicodeAsUTF8AndSize(long h, long size) { - increment(HPyJNIUpcall.HPyUnicodeAsUTF8AndSize); - Object string = context.bitsAsPythonObject(h); - TruffleString tsUtf8; - try { - tsUtf8 = SwitchEncodingNode.getUncached().execute(CastToTruffleStringNode.executeUncached(string), Encoding.UTF_8); - } catch (CannotCastException e) { - return HPyRaiseNode.raiseIntUncached(context, 0, TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); - } - TruffleString nativeTName = AsNativeNode.getUncached().execute(tsUtf8, TS_NATIVE_ALLOCATOR, Encoding.UTF_8, false, true); - Object result = GetInternalNativePointerNode.getUncached().execute(nativeTName, Encoding.UTF_8); - if (size != 0) { - InternalByteArray internalByteArray = GetInternalByteArrayNode.getUncached().execute(tsUtf8, Encoding.UTF_8); - UnsafeWriteSizeTNode.write(size, internalByteArray.getLength()); - } - - if (result instanceof NativePointer nativePointer) { - return nativePointer.asPointer(); - } - return interopPointerToNative(result, InteropLibrary.getUncached(result)); - } - - public long ctxUnicodeDecodeFSDefault(long v) { - increment(HPyJNIUpcall.HPyUnicodeDecodeFSDefault); - return executeLongBinaryContextFunction(HPyContextMember.CTX_UNICODE_DECODEFSDEFAULT, v); - } - - public long ctxUnicodeDecodeFSDefaultAndSize(long v, long size) { - increment(HPyJNIUpcall.HPyUnicodeDecodeFSDefaultAndSize); - return executeLongTernaryContextFunction(HPyContextMember.CTX_UNICODE_DECODEFSDEFAULTANDSIZE, v, size); - } - - public long ctxUnicodeEncodeFSDefault(long h) { - increment(HPyJNIUpcall.HPyUnicodeEncodeFSDefault); - return executeLongBinaryContextFunction(HPyContextMember.CTX_UNICODE_ENCODEFSDEFAULT, h); - } - - public int ctxUnicodeReadChar(long h, long index) { - increment(HPyJNIUpcall.HPyUnicodeReadChar); - return executeIntTernaryContextFunction(HPyContextMember.CTX_UNICODE_READCHAR, h, index); - } - - public long ctxUnicodeDecodeASCII(long s, long size, long errors) { - increment(HPyJNIUpcall.HPyUnicodeDecodeASCII); - return executeLongContextFunction(HPyContextMember.CTX_UNICODE_DECODEASCII, new long[]{s, size, errors}); - } - - public long ctxUnicodeDecodeLatin1(long s, long size, long errors) { - increment(HPyJNIUpcall.HPyUnicodeDecodeLatin1); - return executeLongContextFunction(HPyContextMember.CTX_UNICODE_DECODELATIN1, new long[]{s, size, errors}); - } - - public long ctxUnicodeFromEncodedObject(long obj, long encoding, long errors) { - increment(HPyJNIUpcall.HPyUnicodeFromEncodedObject); - return executeLongContextFunction(HPyContextMember.CTX_UNICODE_FROMENCODEDOBJECT, new long[]{obj, encoding, errors}); - } - - public long ctxUnicodeSubstring(long obj, long start, long end) { - increment(HPyJNIUpcall.HPyUnicodeSubstring); - return executeLongContextFunction(HPyContextMember.CTX_UNICODE_SUBSTRING, new long[]{obj, start, end}); - } - - public int ctxListAppend(long h_list, long h_item) { - increment(HPyJNIUpcall.HPyListAppend); - return executeIntTernaryContextFunction(HPyContextMember.CTX_LIST_APPEND, h_list, h_item); - } - - public int ctxDictCheck(long h) { - increment(HPyJNIUpcall.HPyDictCheck); - return executeIntBinaryContextFunction(HPyContextMember.CTX_DICT_CHECK, h); - } - - public long ctxDictKeys(long h) { - increment(HPyJNIUpcall.HPyDictKeys); - return executeLongBinaryContextFunction(HPyContextMember.CTX_DICT_KEYS, h); - } - - public int ctxTupleCheck(long h) { - increment(HPyJNIUpcall.HPyTupleCheck); - return executeIntBinaryContextFunction(HPyContextMember.CTX_TUPLE_CHECK, h); - } - - public int ctxSliceUnpack(long slice, long start, long stop, long step) { - increment(HPyJNIUpcall.HPySliceUnpack); - return executeIntContextFunction(HPyContextMember.CTX_SLICE_UNPACK, new long[]{slice, start, stop, step}); - } - - public long ctxContextVarNew(long name, long default_value) { - increment(HPyJNIUpcall.HPyContextVarNew); - return executeLongTernaryContextFunction(HPyContextMember.CTX_CONTEXTVAR_NEW, name, default_value); - } - - public long ctxContextVarSet(long context_var, long value) { - increment(HPyJNIUpcall.HPyContextVarSet); - return executeLongTernaryContextFunction(HPyContextMember.CTX_CONTEXTVAR_SET, context_var, value); - } - - public long ctxImportImportModule(long name) { - increment(HPyJNIUpcall.HPyImportImportModule); - return executeLongBinaryContextFunction(HPyContextMember.CTX_IMPORT_IMPORTMODULE, name); - } - - public int ctxCapsuleIsValid(long capsule, long name) { - increment(HPyJNIUpcall.HPyCapsuleIsValid); - return executeIntTernaryContextFunction(HPyContextMember.CTX_CAPSULE_ISVALID, capsule, name); - } - - public int ctxCapsuleSet(long capsule, int key, long value) { - increment(HPyJNIUpcall.HPyCapsuleSet); - return executeIntContextFunction(HPyContextMember.CTX_CAPSULE_SET, new Object[]{capsule, key, value}); - } - - public long ctxFromPyObject(long obj) { - increment(HPyJNIUpcall.HPyFromPyObject); - return executeLongBinaryContextFunction(HPyContextMember.CTX_FROMPYOBJECT, obj); - } - - public long ctxAsPyObject(long h) { - increment(HPyJNIUpcall.HPyAsPyObject); - return executeLongBinaryContextFunction(HPyContextMember.CTX_ASPYOBJECT, h); - } - - public long ctxListBuilderNew(long initial_size) { - increment(HPyJNIUpcall.HPyListBuilderNew); - return executeLongBinaryContextFunction(HPyContextMember.CTX_LISTBUILDER_NEW, initial_size); - } - - public void ctxListBuilderSet(long builder, long index, long h_item) { - increment(HPyJNIUpcall.HPyListBuilderSet); - executeIntContextFunction(HPyContextMember.CTX_LISTBUILDER_SET, new long[]{builder, index, h_item}); - } - - public long ctxListBuilderBuild(long builder) { - increment(HPyJNIUpcall.HPyListBuilderBuild); - return executeLongBinaryContextFunction(HPyContextMember.CTX_LISTBUILDER_BUILD, builder); - } - - public void ctxListBuilderCancel(long builder) { - increment(HPyJNIUpcall.HPyListBuilderCancel); - executeIntBinaryContextFunction(HPyContextMember.CTX_LISTBUILDER_CANCEL, builder); - } - - public long ctxTupleBuilderNew(long initial_size) { - increment(HPyJNIUpcall.HPyTupleBuilderNew); - return executeLongBinaryContextFunction(HPyContextMember.CTX_TUPLEBUILDER_NEW, initial_size); - } - - public void ctxTupleBuilderSet(long builder, long index, long h_item) { - increment(HPyJNIUpcall.HPyTupleBuilderSet); - executeIntContextFunction(HPyContextMember.CTX_TUPLEBUILDER_SET, new long[]{builder, index, h_item}); - } - - public long ctxTupleBuilderBuild(long builder) { - increment(HPyJNIUpcall.HPyTupleBuilderBuild); - return executeLongBinaryContextFunction(HPyContextMember.CTX_TUPLEBUILDER_BUILD, builder); - } - - public void ctxTupleBuilderCancel(long builder) { - increment(HPyJNIUpcall.HPyTupleBuilderCancel); - executeIntBinaryContextFunction(HPyContextMember.CTX_TUPLEBUILDER_CANCEL, builder); - } - - public void ctxReenterPythonExecution(long state) { - increment(HPyJNIUpcall.HPyReenterPythonExecution); - executeIntBinaryContextFunction(HPyContextMember.CTX_REENTERPYTHONEXECUTION, state); - } - - public long ctxLeavePythonExecution() { - increment(HPyJNIUpcall.HPyLeavePythonExecution); - return executeLongContextFunction(HPyContextMember.CTX_LEAVEPYTHONEXECUTION, new long[]{}); - } - - public void ctxDump(long h) { - increment(HPyJNIUpcall.HPyDump); - executeIntBinaryContextFunction(HPyContextMember.CTX_DUMP, h); - } - - public long ctxCall(long callable, long args, long lnargs, long kwnames) { - increment(HPyJNIUpcall.HPyCall); - // some assumptions that may be made - assert callable != 0 && GraalHPyBoxing.isBoxedHandle(callable); - assert kwnames == 0 || GraalHPyBoxing.isBoxedHandle(kwnames); - assert args != 0 || lnargs == 0; - try { - if (!PInt.isIntRange(lnargs)) { - throw PRaiseNode.raiseUncached(null, PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_DOES_NOT_SUPPORT_ITEM_ASSIGMENT, 0); - } - int nargs = (int) lnargs; - Object callableObj = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(callable)); - - PKeyword[] keywords; - Object[] argsArr = new Object[nargs]; - for (int i = 0; i < argsArr.length; i++) { - long argBits = UNSAFE.getLong(args + i * SIZEOF_LONG); - argsArr[i] = context.bitsAsPythonObject(argBits); - } - - if (kwnames != 0) { - Object kwnamesObj = context.getObjectForHPyHandle(GraalHPyBoxing.unboxHandle(kwnames)); - if (kwnamesObj instanceof PTuple kwnamesTuple) { - int nkw = kwnamesTuple.getSequenceStorage().length(); - Object[] kwvalues = new Object[nkw]; - long kwvaluesPtr = args + nargs * SIZEOF_LONG; - for (int i = 0; i < kwvalues.length; i++) { - long argBits = UNSAFE.getLong(kwvaluesPtr + i * SIZEOF_LONG); - kwvalues[i] = context.bitsAsPythonObject(argBits); - } - keywords = HPyPackKeywordArgsNodeGen.getUncached().execute(null, kwvalues, kwnamesTuple, nkw); - } else { - // fatal error (CPython would just cause a memory corruption) - throw CompilerDirectives.shouldNotReachHere(); - } - } else { - keywords = PKeyword.EMPTY_KEYWORDS; - } - - Object result = CallNode.executeUncached(callableObj, argsArr, keywords); - return context.pythonObjectAsBits(result); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(e); - return 0; - } catch (Throwable t) { - throw checkThrowableBeforeNative(t, "HPy context function", HPyJNIUpcall.HPyCall.getName()); - } - } - - public long ctxCallMethod(long name, long args, long nargs, long kwnames) { - increment(HPyJNIUpcall.HPyCallMethod); - return executeLongContextFunction(HPyContextMember.CTX_CALLMETHOD, new long[]{name, args, nargs, kwnames}); - } - - public int ctxDelItem(long obj, long key) { - increment(HPyJNIUpcall.HPyDelItem); - return executeIntTernaryContextFunction(HPyContextMember.CTX_DELITEM, obj, key); - } - - public int ctxDelItemi(long obj, long idx) { - increment(HPyJNIUpcall.HPyDelItemi); - return executeIntTernaryContextFunction(HPyContextMember.CTX_DELITEM_I, obj, idx); - } - - public int ctxDelItems(long obj, long utf8_key) { - increment(HPyJNIUpcall.HPyDelItems); - return executeIntTernaryContextFunction(HPyContextMember.CTX_DELITEM_S, obj, utf8_key); - } - - public int ctxTypeGetBuiltinShape(long h_type) { - increment(HPyJNIUpcall.HPyTypeGetBuiltinShape); - assert GraalHPyBoxing.isBoxedHandle(h_type); - Object typeObject = context.bitsAsPythonObject(h_type); - int result = GraalHPyDef.getBuiltinShapeFromHiddenAttribute(typeObject); - if (result == -2) { - return HPyRaiseNode.raiseIntUncached(context, -2, TypeError, ErrorMessages.S_MUST_BE_S, "arg", "type"); - } - assert GraalHPyDef.isValidBuiltinShape(result); - return result; - } - - public long ctxDictCopy(long h) { - increment(HPyJNIUpcall.HPyDictCopy); - return executeLongBinaryContextFunction(HPyContextMember.CTX_DICT_COPY, h); - } - - public long ctxCompiles(long utf8_source, long utf8_filename, int kind) { - increment(HPyJNIUpcall.HPyCompiles); - return executeLongContextFunction(HPyContextMember.CTX_COMPILE_S, new Object[]{utf8_source, utf8_filename, kind}); - } - - public long ctxEvalCode(long code, long globals, long locals) { - increment(HPyJNIUpcall.HPyEvalCode); - return executeLongContextFunction(HPyContextMember.CTX_EVALCODE, new long[]{code, globals, locals}); - } - - public int ctxSetCallFunction(long h, long func) { - increment(HPyJNIUpcall.HPySetCallFunction); - return executeIntTernaryContextFunction(HPyContextMember.CTX_SETCALLFUNCTION, h, func); - } - // {{end ctx funcs}} - - private long createConstant(Object value) { - return context.getHPyContextHandle(value); - } - - private long createBuiltinsConstant() { - return createConstant(GetOrCreateDictNode.executeUncached(context.getContext().getBuiltins())); - } - - private static long createSingletonConstant(Object value, int handle) { - assert GraalHPyContext.getHPyHandleForSingleton(value) == handle; - return handle; - } - - private long createTypeConstant(PythonBuiltinClassType value) { - return context.getHPyContextHandle(context.getContext().lookupType(value)); - } - - /** - * Creates the context handles, i.e., allocates a handle for each object that is available in - * {@code HPyContext} (e.g. {@code HPyContext.h_None}). This table is then intended to be used - * to initialize the native {@code HPyContext *}. The handles are stored in a {@code long} array - * and the index for each handle is the context index (i.e. the index as specified in - * HPy's {@code public_api.h}). - */ - private long[] createContextHandleArray() { - // {{start ctx handles array}} - // @formatter:off - // Checkstyle: stop - // DO NOT EDIT THIS PART! - // This part is automatically generated by hpy.tools.autogen.graalpy.autogen_ctx_handles_init - long[] ctxHandles = new long[244]; - ctxHandles[0] = createSingletonConstant(PNone.NONE, SINGLETON_HANDLE_NONE); - ctxHandles[1] = createConstant(context.getContext().getTrue()); - ctxHandles[2] = createConstant(context.getContext().getFalse()); - ctxHandles[3] = createSingletonConstant(PNotImplemented.NOT_IMPLEMENTED, SINGLETON_HANDLE_NOT_IMPLEMENTED); - ctxHandles[4] = createSingletonConstant(PEllipsis.INSTANCE, SINGLETON_HANDLE_ELIPSIS); - ctxHandles[5] = createTypeConstant(PythonBuiltinClassType.PBaseException); - ctxHandles[6] = createTypeConstant(PythonBuiltinClassType.Exception); - ctxHandles[7] = createTypeConstant(PythonBuiltinClassType.StopAsyncIteration); - ctxHandles[8] = createTypeConstant(PythonBuiltinClassType.StopIteration); - ctxHandles[9] = createTypeConstant(PythonBuiltinClassType.GeneratorExit); - ctxHandles[10] = createTypeConstant(PythonBuiltinClassType.ArithmeticError); - ctxHandles[11] = createTypeConstant(PythonBuiltinClassType.LookupError); - ctxHandles[12] = createTypeConstant(PythonBuiltinClassType.AssertionError); - ctxHandles[13] = createTypeConstant(PythonBuiltinClassType.AttributeError); - ctxHandles[14] = createTypeConstant(PythonBuiltinClassType.BufferError); - ctxHandles[15] = createTypeConstant(PythonBuiltinClassType.EOFError); - ctxHandles[16] = createTypeConstant(PythonBuiltinClassType.FloatingPointError); - ctxHandles[17] = createTypeConstant(PythonBuiltinClassType.OSError); - ctxHandles[18] = createTypeConstant(PythonBuiltinClassType.ImportError); - ctxHandles[19] = createTypeConstant(PythonBuiltinClassType.ModuleNotFoundError); - ctxHandles[20] = createTypeConstant(PythonBuiltinClassType.IndexError); - ctxHandles[21] = createTypeConstant(PythonBuiltinClassType.KeyError); - ctxHandles[22] = createTypeConstant(PythonBuiltinClassType.KeyboardInterrupt); - ctxHandles[23] = createTypeConstant(PythonBuiltinClassType.MemoryError); - ctxHandles[24] = createTypeConstant(PythonBuiltinClassType.NameError); - ctxHandles[25] = createTypeConstant(PythonBuiltinClassType.OverflowError); - ctxHandles[26] = createTypeConstant(PythonBuiltinClassType.RuntimeError); - ctxHandles[27] = createTypeConstant(PythonBuiltinClassType.RecursionError); - ctxHandles[28] = createTypeConstant(PythonBuiltinClassType.NotImplementedError); - ctxHandles[29] = createTypeConstant(PythonBuiltinClassType.SyntaxError); - ctxHandles[30] = createTypeConstant(PythonBuiltinClassType.IndentationError); - ctxHandles[31] = createTypeConstant(PythonBuiltinClassType.TabError); - ctxHandles[32] = createTypeConstant(PythonBuiltinClassType.ReferenceError); - ctxHandles[33] = createTypeConstant(SystemError); - ctxHandles[34] = createTypeConstant(PythonBuiltinClassType.SystemExit); - ctxHandles[35] = createTypeConstant(PythonBuiltinClassType.TypeError); - ctxHandles[36] = createTypeConstant(PythonBuiltinClassType.UnboundLocalError); - ctxHandles[37] = createTypeConstant(PythonBuiltinClassType.UnicodeError); - ctxHandles[38] = createTypeConstant(PythonBuiltinClassType.UnicodeEncodeError); - ctxHandles[39] = createTypeConstant(PythonBuiltinClassType.UnicodeDecodeError); - ctxHandles[40] = createTypeConstant(PythonBuiltinClassType.UnicodeTranslateError); - ctxHandles[41] = createTypeConstant(PythonBuiltinClassType.ValueError); - ctxHandles[42] = createTypeConstant(PythonBuiltinClassType.ZeroDivisionError); - ctxHandles[43] = createTypeConstant(PythonBuiltinClassType.BlockingIOError); - ctxHandles[44] = createTypeConstant(PythonBuiltinClassType.BrokenPipeError); - ctxHandles[45] = createTypeConstant(PythonBuiltinClassType.ChildProcessError); - ctxHandles[46] = createTypeConstant(PythonBuiltinClassType.ConnectionError); - ctxHandles[47] = createTypeConstant(PythonBuiltinClassType.ConnectionAbortedError); - ctxHandles[48] = createTypeConstant(PythonBuiltinClassType.ConnectionRefusedError); - ctxHandles[49] = createTypeConstant(PythonBuiltinClassType.ConnectionResetError); - ctxHandles[50] = createTypeConstant(PythonBuiltinClassType.FileExistsError); - ctxHandles[51] = createTypeConstant(PythonBuiltinClassType.FileNotFoundError); - ctxHandles[52] = createTypeConstant(PythonBuiltinClassType.InterruptedError); - ctxHandles[53] = createTypeConstant(PythonBuiltinClassType.IsADirectoryError); - ctxHandles[54] = createTypeConstant(PythonBuiltinClassType.NotADirectoryError); - ctxHandles[55] = createTypeConstant(PythonBuiltinClassType.PermissionError); - ctxHandles[56] = createTypeConstant(PythonBuiltinClassType.ProcessLookupError); - ctxHandles[57] = createTypeConstant(PythonBuiltinClassType.TimeoutError); - ctxHandles[58] = createTypeConstant(PythonBuiltinClassType.Warning); - ctxHandles[59] = createTypeConstant(PythonBuiltinClassType.UserWarning); - ctxHandles[60] = createTypeConstant(PythonBuiltinClassType.DeprecationWarning); - ctxHandles[61] = createTypeConstant(PythonBuiltinClassType.PendingDeprecationWarning); - ctxHandles[62] = createTypeConstant(PythonBuiltinClassType.SyntaxWarning); - ctxHandles[63] = createTypeConstant(PythonBuiltinClassType.RuntimeWarning); - ctxHandles[64] = createTypeConstant(PythonBuiltinClassType.FutureWarning); - ctxHandles[65] = createTypeConstant(PythonBuiltinClassType.ImportWarning); - ctxHandles[66] = createTypeConstant(PythonBuiltinClassType.UnicodeWarning); - ctxHandles[67] = createTypeConstant(PythonBuiltinClassType.BytesWarning); - ctxHandles[68] = createTypeConstant(PythonBuiltinClassType.ResourceWarning); - ctxHandles[69] = createTypeConstant(PythonBuiltinClassType.PythonObject); - ctxHandles[70] = createTypeConstant(PythonBuiltinClassType.PythonClass); - ctxHandles[71] = createTypeConstant(PythonBuiltinClassType.Boolean); - ctxHandles[72] = createTypeConstant(PythonBuiltinClassType.PInt); - ctxHandles[73] = createTypeConstant(PythonBuiltinClassType.PFloat); - ctxHandles[74] = createTypeConstant(PythonBuiltinClassType.PString); - ctxHandles[75] = createTypeConstant(PythonBuiltinClassType.PTuple); - ctxHandles[76] = createTypeConstant(PythonBuiltinClassType.PList); - ctxHandles[238] = createTypeConstant(PythonBuiltinClassType.PComplex); - ctxHandles[239] = createTypeConstant(PythonBuiltinClassType.PBytes); - ctxHandles[240] = createTypeConstant(PythonBuiltinClassType.PMemoryView); - ctxHandles[241] = createTypeConstant(PythonBuiltinClassType.Capsule); - ctxHandles[242] = createTypeConstant(PythonBuiltinClassType.PSlice); - ctxHandles[243] = createBuiltinsConstant(); - return ctxHandles; - - // @formatter:on - // Checkstyle: resume - // {{end ctx handles array}} - } - - private Object executeContextFunction(HPyContextMember member, long[] arguments) { - HPyContextSignature signature = member.getSignature(); - HPyContextSignatureType[] argTypes = signature.parameterTypes(); - assert arguments.length == argTypes.length - 1; - Object[] argCast = new Object[argTypes.length]; - argCast[0] = context; - for (int i = 1; i < argCast.length; i++) { - argCast[i] = convertLongArg(argTypes[i], arguments[i - 1]); - } - return GraalHPyContextFunction.getUncached(member).execute(argCast); - } - - private Object executeBinaryContextFunction(HPyContextMember member, long larg0) { - HPyContextSignature signature = member.getSignature(); - HPyContextSignatureType[] argTypes = signature.parameterTypes(); - assert argTypes.length - 1 == 1; - Object arg0 = convertLongArg(argTypes[1], larg0); - return ((HPyBinaryContextFunction) GraalHPyContextFunction.getUncached(member)).execute(context, arg0); - } - - private Object executeTernaryContextFunction(HPyContextMember member, long larg0, long larg1) { - HPyContextSignature signature = member.getSignature(); - HPyContextSignatureType[] argTypes = signature.parameterTypes(); - assert argTypes.length - 1 == 2; - Object arg0 = convertLongArg(argTypes[1], larg0); - Object arg1 = convertLongArg(argTypes[2], larg1); - return ((HPyTernaryContextFunction) GraalHPyContextFunction.getUncached(member)).execute(context, arg0, arg1); - } - - private Object executeContextFunction(HPyContextMember member, Object[] arguments) { - HPyContextSignature signature = member.getSignature(); - HPyContextSignatureType[] argTypes = signature.parameterTypes(); - assert arguments.length == argTypes.length - 1; - Object[] argCast = new Object[argTypes.length]; - argCast[0] = context; - for (int i = 1; i < argCast.length; i++) { - argCast[i] = convertArg(argTypes[i], arguments[i - 1]); - } - return GraalHPyContextFunction.getUncached(member).execute(argCast); - } - - private long executeLongContextFunction(HPyContextMember member, long[] arguments) { - try { - Object result = executeContextFunction(member, arguments); - return convertLongRet(member.getSignature().returnType(), result); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(e); - return getLongErrorValue(member.getSignature().returnType()); - } catch (Throwable t) { - throw checkThrowableBeforeNative(t, "HPy context function", member.getName()); - } - } - - private long executeLongBinaryContextFunction(HPyContextMember member, long arg0) { - try { - Object result = executeBinaryContextFunction(member, arg0); - return convertLongRet(member.getSignature().returnType(), result); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(e); - return getLongErrorValue(member.getSignature().returnType()); - } catch (Throwable t) { - throw checkThrowableBeforeNative(t, "HPy context function", member.getName()); - } - } - - private long executeLongTernaryContextFunction(HPyContextMember member, long arg0, long arg1) { - try { - Object result = executeTernaryContextFunction(member, arg0, arg1); - return convertLongRet(member.getSignature().returnType(), result); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(e); - return getLongErrorValue(member.getSignature().returnType()); - } catch (Throwable t) { - throw checkThrowableBeforeNative(t, "HPy context function", member.getName()); - } - } - - private int executeIntContextFunction(HPyContextMember member, long[] arguments) { - try { - Object result = executeContextFunction(member, arguments); - return convertIntRet(member.getSignature().returnType(), result); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(e); - return getIntErrorValue(member.getSignature().returnType()); - } catch (Throwable t) { - throw checkThrowableBeforeNative(t, "HPy context function", member.getName()); - } - } - - @TruffleBoundary - private int executeIntBinaryContextFunction(HPyContextMember member, long arg0) { - try { - Object result = executeBinaryContextFunction(member, arg0); - return convertIntRet(member.getSignature().returnType(), result); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(e); - return getIntErrorValue(member.getSignature().returnType()); - } catch (Throwable t) { - throw checkThrowableBeforeNative(t, "HPy context function", member.getName()); - } - } - - private int executeIntTernaryContextFunction(HPyContextMember member, long arg0, long arg1) { - try { - Object result = executeTernaryContextFunction(member, arg0, arg1); - return convertIntRet(member.getSignature().returnType(), result); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(e); - return getIntErrorValue(member.getSignature().returnType()); - } catch (Throwable t) { - throw checkThrowableBeforeNative(t, "HPy context function", member.getName()); - } - } - - private long executeLongContextFunction(HPyContextMember member, Object[] arguments) { - try { - Object result = executeContextFunction(member, arguments); - return convertLongRet(member.getSignature().returnType(), result); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(e); - return getLongErrorValue(member.getSignature().returnType()); - } catch (Throwable t) { - throw checkThrowableBeforeNative(t, "HPy context function", member.getName()); - } - } - - private int executeIntContextFunction(HPyContextMember member, Object[] arguments) { - try { - Object result = executeContextFunction(member, arguments); - return convertIntRet(member.getSignature().returnType(), result); - } catch (PException e) { - HPyTransformExceptionToNativeNode.executeUncached(e); - return getIntErrorValue(member.getSignature().returnType()); - } catch (Throwable t) { - throw checkThrowableBeforeNative(t, "HPy context function", member.getName()); - } - } - - private Object convertLongArg(HPyContextSignatureType type, long argBits) { - return switch (type) { - case HPy, HPyThreadState, HPyListBuilder, HPyTupleBuilder -> context.bitsAsPythonObject(argBits); - case Int, HPy_UCS4 -> -1; - case Int64_t, Uint64_t, Size_t, HPy_ssize_t, HPy_hash_t, VoidPtr, CVoid -> argBits; - case Int32_t, Uint32_t -> argBits & 0xFFFFFFFFL; - case CDouble -> throw CompilerDirectives.shouldNotReachHere("invalid argument handle"); - case HPyModuleDefPtr, HPyType_SpecPtr, HPyType_SpecParamPtr, HPy_ssize_tPtr, ConstHPyPtr, HPyPtr, HPyCallFunctionPtr, CharPtr, ConstCharPtr -> argBits; - case Cpy_PyObjectPtr -> nativeToInteropPointer(argBits); - default -> throw CompilerDirectives.shouldNotReachHere("unsupported arg type"); - }; - } - - private Object convertArg(HPyContextSignatureType type, Object arg) { - return switch (type) { - case Int, Int32_t, Uint32_t, HPy_UCS4, _HPyCapsule_key, HPy_SourceKind -> (Integer) arg; - default -> convertLongArg(type, (Long) arg); - }; - } - - private long convertLongRet(HPyContextSignatureType type, Object result) { - return switch (type) { - case HPy, HPyThreadState, HPyListBuilder, HPyTupleBuilder -> GraalHPyBoxing.boxHandle(context.getHPyHandleForObject(result)); - case VoidPtr, CharPtr, ConstCharPtr, Cpy_PyObjectPtr -> coerceToPointer(result); - case Int64_t, Uint64_t, Size_t, HPy_ssize_t, HPy_hash_t -> (Long) HPyAsNativeInt64NodeGen.getUncached().execute(result); - default -> throw CompilerDirectives.shouldNotReachHere(); - }; - } - - private int convertIntRet(HPyContextSignatureType type, Object result) { - return switch (type) { - case Int, Int32_t, Uint32_t, HPy_UCS4 -> (int) result; - case CVoid -> 0; - default -> throw CompilerDirectives.shouldNotReachHere(); - }; - } - - private long getLongErrorValue(HPyContextSignatureType type) { - return switch (type) { - case HPy, VoidPtr, CharPtr, ConstCharPtr, Cpy_PyObjectPtr, HPyListBuilder, HPyTupleBuilder, HPyThreadState -> 0; - case Int64_t, Uint64_t, Size_t, HPy_ssize_t, HPy_hash_t -> -1L; - default -> throw CompilerDirectives.shouldNotReachHere(); - }; - } - - private int getIntErrorValue(HPyContextSignatureType type) { - return switch (type) { - case Int, Int32_t, Uint32_t, HPy_UCS4 -> -1; - case CVoid -> 0; - case HPyType_BuiltinShape -> -2; - default -> throw CompilerDirectives.shouldNotReachHere(); - }; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNIConvertArgNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNIConvertArgNode.java deleted file mode 100644 index db63b1a2d1..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNIConvertArgNode.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy.jni; - -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyBoxing; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.GetHPyHandleForSingleton; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.LLVMType; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFactory.GetHPyHandleForSingletonNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyHandle; -import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.ConditionProfile; - -public abstract class GraalHPyJNIConvertArgNode extends Node { - - private static final GraalHPyJNIConvertArgUncachedNode UNCACHED = new GraalHPyJNIConvertArgUncachedNode(); - - @NeverDefault - public static GraalHPyJNIConvertArgNode create(@SuppressWarnings("unused") LLVMType signature) { - return new GraalHPyJNIConvertArgCachedNode(); - } - - public static GraalHPyJNIConvertArgNode getUncached(@SuppressWarnings("unused") LLVMType signature) { - return UNCACHED; - } - - public abstract long execute(Object[] arguments, int i); - - protected static GraalHPyJNIContext getHPyContext(Object[] arguments) { - Object backend = arguments[0]; - if (backend instanceof GraalHPyJNIContext jniBackend) { - return jniBackend; - } - /* - * That's clearly an internal error because we cannot have a GraalHPyJNIConvertArgNode - * instance if we are not using the JNI backend. - */ - throw CompilerDirectives.shouldNotReachHere("first argument is expected to the HPy context"); - } - - static final class GraalHPyJNIConvertArgCachedNode extends GraalHPyJNIConvertArgNode { - /** - * Carefully picked limit. Expected possible argument object types are: LLVM native pointer, - * LLVM managed pointer, {@link GraalHPyContext}, and {@link GraalHPyHandle}. - */ - private static final int CACHE_LIMIT = 4; - - @Child private InteropLibrary interopLibrary; - @CompilationFinal private ConditionProfile profile; - @Child GetHPyHandleForSingleton getHPyHandleForSingleton; - - @Override - public long execute(Object[] arguments, int i) { - CompilerAsserts.partialEvaluationConstant(i); - // TODO(fa): improved cached implementation; use state bits to remember types we've - // seen per argument - Object value = arguments[i]; - - if (value instanceof GraalHPyHandle handle) { - Object delegate = handle.getDelegate(); - if (GraalHPyBoxing.isBoxablePrimitive(delegate)) { - if (delegate instanceof Integer) { - return GraalHPyBoxing.boxInt((Integer) delegate); - } - assert delegate instanceof Double; - return GraalHPyBoxing.boxDouble((Double) delegate); - } else { - return handle.getId(getHPyContext(arguments).getHPyContext(), ensureProfile(), ensureHandleForSingletonNode()); - } - } else if (value instanceof Long) { - return (long) value; - } else { - if (interopLibrary == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - interopLibrary = insert(InteropLibrary.getFactory().createDispatched(CACHE_LIMIT)); - } - if (!interopLibrary.isPointer(value)) { - interopLibrary.toNative(value); - } - try { - return interopLibrary.asPointer(value); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } - } - - private ConditionProfile ensureProfile() { - if (profile == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - profile = ConditionProfile.create(); - } - return profile; - } - - private GetHPyHandleForSingleton ensureHandleForSingletonNode() { - if (getHPyHandleForSingleton == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - getHPyHandleForSingleton = insert(GetHPyHandleForSingletonNodeGen.create()); - } - return getHPyHandleForSingleton; - } - } - - static final class GraalHPyJNIConvertArgUncachedNode extends GraalHPyJNIConvertArgNode { - - @Override - public long execute(Object[] arguments, int i) { - Object value = arguments[i]; - if (value instanceof GraalHPyHandle handle) { - Object delegate = handle.getDelegate(); - if (GraalHPyBoxing.isBoxablePrimitive(delegate)) { - if (delegate instanceof Integer) { - return GraalHPyBoxing.boxInt((Integer) delegate); - } - assert delegate instanceof Double; - return GraalHPyBoxing.boxDouble((Double) delegate); - } else { - return handle.getIdUncached(getHPyContext(arguments).getHPyContext()); - } - } else if (value instanceof Long) { - return (long) value; - } else { - InteropLibrary interopLibrary = InteropLibrary.getUncached(value); - if (!interopLibrary.isPointer(value)) { - interopLibrary.toNative(value); - } - try { - return interopLibrary.asPointer(value); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNIFunctionPointer.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNIFunctionPointer.java deleted file mode 100644 index 670b66bb97..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNIFunctionPointer.java +++ /dev/null @@ -1,516 +0,0 @@ -/* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy.jni; - -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.LLVMType; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyMode; -import com.oracle.graal.python.runtime.PythonImageBuildOptions; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.library.ExportLibrary; -import com.oracle.truffle.api.library.ExportMessage; - -/** - * Represents a native function pointer that will be called using an appropriate JNI trampoline - * function depending on the {@link #signature} and the {@link #mode} enum. - */ -@ExportLibrary(InteropLibrary.class) -public final class GraalHPyJNIFunctionPointer implements TruffleObject { - final long pointer; - final LLVMType signature; - - /** - * Function pointers created through {@code HPyModule_Create} or {@code HPyType_FromSpec} - * remembers if the context that created it was in debug mode. Depending on this flag, we decide - * which trampolines (universal or debug) we need to use. For reference: In CPython this is - * implicitly given by the fact that the HPy context is stored in a C global variable - * {@code _ctx_for_trampolines}. - */ - final HPyMode mode; - - public GraalHPyJNIFunctionPointer(long pointer, LLVMType signature, HPyMode mode) { - assert !PythonImageBuildOptions.WITHOUT_JNI; - this.pointer = pointer; - this.signature = signature; - this.mode = mode; - } - - @ExportMessage - @SuppressWarnings("static-method") - boolean isExecutable() { - return true; - } - - @ExportMessage - static final class Execute { - - @Specialization(guards = "receiver.signature == cachedSignature", limit = "1") - static Object doCached(GraalHPyJNIFunctionPointer receiver, Object[] arguments, - @CachedLibrary(limit = "1") InteropLibrary interopLibrary, - @Cached("receiver.signature") LLVMType cachedSignature, - @Cached(parameters = "receiver.signature") GraalHPyJNIConvertArgNode convertArgNode) { - // Make it explicit, that we cannot to JNI calls if WITHOUT_JNI is true. - if (PythonImageBuildOptions.WITHOUT_JNI) { - throw CompilerDirectives.shouldNotReachHere(); - } - return switch (receiver.mode) { - case MODE_UNIVERSAL -> callUniversal(receiver, cachedSignature, convertHPyContext(arguments), arguments, interopLibrary, convertArgNode); - case MODE_DEBUG -> callDebug(receiver, cachedSignature, convertHPyDebugContext(arguments), arguments, interopLibrary, convertArgNode); - case MODE_TRACE -> callUniversal(receiver, cachedSignature, convertHPyTraceContext(arguments), arguments, interopLibrary, convertArgNode); - default -> throw CompilerDirectives.shouldNotReachHere("unsupported HPy mode"); - }; - } - - /** - * Uses the appropriate trampoline to call the native function pointer. - */ - private static long callUniversal(GraalHPyJNIFunctionPointer receiver, LLVMType signature, long ctx, Object[] arguments, - InteropLibrary interopLibrary, GraalHPyJNIConvertArgNode convertArgNode) { - switch (signature) { - case HPyModule_init: - return GraalHPyJNITrampolines.executeModuleInit(receiver.pointer); - case HPyModule_create: - return GraalHPyJNITrampolines.executeModcreate(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_noargs: - return GraalHPyJNITrampolines.executeNoargs(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_unaryfunc: - return GraalHPyJNITrampolines.executeUnaryfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_getiterfunc: - return GraalHPyJNITrampolines.executeGetiterfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_iternextfunc: - return GraalHPyJNITrampolines.executeIternextfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_reprfunc: - return GraalHPyJNITrampolines.executeReprfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_lenfunc: - return GraalHPyJNITrampolines.executeLenfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_hashfunc: - return GraalHPyJNITrampolines.executeHashfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_binaryfunc: - return GraalHPyJNITrampolines.executeBinaryfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2)); - case HPyFunc_o: - return GraalHPyJNITrampolines.executeO(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2)); - case HPyFunc_getter: - return GraalHPyJNITrampolines.executeGetter(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2)); - case HPyFunc_getattrfunc: - return GraalHPyJNITrampolines.executeGetattrfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2)); - case HPyFunc_getattrofunc: - return GraalHPyJNITrampolines.executeGetattrofunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2)); - case HPyFunc_ssizeargfunc: - return GraalHPyJNITrampolines.executeSsizeargfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2)); - case HPyFunc_traverseproc: - return GraalHPyJNITrampolines.executeTraverseproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2)); - case HPyFunc_varargs: - return GraalHPyJNITrampolines.executeVarargs(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2), - convertArgNode.execute(arguments, 3)); - case HPyFunc_ternaryfunc: - return GraalHPyJNITrampolines.executeTernaryfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2), - convertArgNode.execute(arguments, 3)); - case HPyFunc_descrgetfunc: - return GraalHPyJNITrampolines.executeDescrgetfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2), - convertArgNode.execute(arguments, 3)); - case HPyFunc_ssizessizeargfunc: - return GraalHPyJNITrampolines.executeSsizessizeargfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2), - convertArgNode.execute(arguments, 3)); - case HPyFunc_keywords: - return GraalHPyJNITrampolines.executeKeywords(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2), - convertArgNode.execute(arguments, 3), convertArgNode.execute(arguments, 4)); - case HPyFunc_inquiry: - return GraalHPyJNITrampolines.executeInquiry(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_ssizeobjargproc: - return GraalHPyJNITrampolines.executeSsizeobjargproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), (long) arguments[2], convertArgNode.execute(arguments, 3)); - case HPyFunc_initproc: - return GraalHPyJNITrampolines.executeInitproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2), (long) arguments[3], - convertArgNode.execute(arguments, 4)); - case HPyFunc_ssizessizeobjargproc: - return GraalHPyJNITrampolines.executeSsizessizeobjargproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), (long) arguments[2], (long) arguments[3], - convertArgNode.execute(arguments, 4)); - case HPyFunc_setter: - return GraalHPyJNITrampolines.executeSetter(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2), - convertArgNode.execute(arguments, 3)); - case HPyFunc_setattrfunc: - return GraalHPyJNITrampolines.executeSetattrfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2), - convertArgNode.execute(arguments, 3)); - case HPyFunc_objobjargproc: - return GraalHPyJNITrampolines.executeObjobjargproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2), - convertArgNode.execute(arguments, 3)); - case HPyFunc_descrsetfunc: - return GraalHPyJNITrampolines.executeDescrsetfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2), - convertArgNode.execute(arguments, 3)); - case HPyFunc_setattrofunc: - return GraalHPyJNITrampolines.executeSetattrofunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2), - convertArgNode.execute(arguments, 3)); - case HPyFunc_freefunc: - GraalHPyJNITrampolines.executeFreefunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - return 0; - case HPyFunc_richcmpfunc: - return GraalHPyJNITrampolines.executeRichcmpfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2), (int) arguments[3]); - case HPyFunc_objobjproc: - return GraalHPyJNITrampolines.executeObjobjproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2)); - case HPyFunc_getbufferproc: - return GraalHPyJNITrampolines.executeGetbufferproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2), (int) arguments[3]); - case HPyFunc_releasebufferproc: - GraalHPyJNITrampolines.executeReleasebufferproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), convertArgNode.execute(arguments, 2)); - return 0; - case HPyFunc_destroyfunc: - GraalHPyJNITrampolines.executeDestroyfunc(receiver.pointer, convertPointer(arguments[0], interopLibrary)); - return 0; - case HPyFunc_destructor: - GraalHPyJNITrampolines.executeDestructor(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - return 0; - } - throw CompilerDirectives.shouldNotReachHere(); - } - - /** - * When we are in debug mode, we need to use different trampolines for calling the HPy - * extension functions because object parameters (that will become handles) will be wrapped - * in debug handles ({@code DHPy}) and, vice versa, object return values need to be - * unwrapped. This un/-wrapping is done by the trampoline via calling {@code DHPy_open} and - * {@code DHPy_unwrap}. - */ - private static long callTrace(GraalHPyJNIFunctionPointer receiver, LLVMType signature, Object[] arguments, - InteropLibrary interopLibrary, GraalHPyJNIConvertArgNode convertArgNode) { - switch (signature) { - case HPyModule_init: - // there is no difference to the universal mode - return GraalHPyJNITrampolines.executeModuleInit(receiver.pointer); - case HPyModule_create: - return GraalHPyJNITrampolines.executeDebugModcreate(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1)); - case HPyFunc_noargs: - return GraalHPyJNITrampolines.executeDebugNoargs(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1)); - case HPyFunc_unaryfunc: - return GraalHPyJNITrampolines.executeDebugUnaryfunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1)); - case HPyFunc_getiterfunc: - return GraalHPyJNITrampolines.executeDebugGetiterfunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1)); - case HPyFunc_iternextfunc: - return GraalHPyJNITrampolines.executeDebugIternextfunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1)); - case HPyFunc_reprfunc: - return GraalHPyJNITrampolines.executeDebugReprfunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1)); - case HPyFunc_lenfunc: - return GraalHPyJNITrampolines.executeDebugLenfunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1)); - case HPyFunc_hashfunc: - // HPy_ssize_t (*HPyFunc_lenfunc)(HPyContext *ctx, HPy); - // HPy_hash_t (*HPyFunc_hashfunc)(HPyContext *ctx, HPy); - return GraalHPyJNITrampolines.executeDebugHashfunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1)); - case HPyFunc_binaryfunc: - return GraalHPyJNITrampolines.executeDebugBinaryfunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_o: - return GraalHPyJNITrampolines.executeDebugO(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_getattrofunc: - return GraalHPyJNITrampolines.executeDebugGetattrofunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_getattrfunc: - // HPy (*HPyFunc_getattrfunc) (HPyContext *ctx, HPy, char *); - return GraalHPyJNITrampolines.executeDebugGetattrfunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_ssizeargfunc: - // HPy (*HPyFunc_ssizeargfunc)(HPyContext *ctx, HPy, HPy_ssize_t); - return GraalHPyJNITrampolines.executeDebugSsizeargfunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_getter: - // HPy (*HPyFunc_getter) (HPyContext *ctx, HPy, void *); - return GraalHPyJNITrampolines.executeDebugGetter(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_traverseproc: - // int (*HPyFunc_traverseproc)(void *, HPyFunc_visitproc, void *); - return GraalHPyJNITrampolines.executeTraverseproc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_varargs: - // HPy (*HPyFunc_varargs)(HPyContext *, HPy, HPy *, HPy_ssize_t); - return GraalHPyJNITrampolines.executeDebugVarargs(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_ternaryfunc: - // HPy (*HPyFunc_ternaryfunc)(HPyContext *, HPy, HPy, HPy) - return GraalHPyJNITrampolines.executeDebugTernaryfunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_descrgetfunc: - return GraalHPyJNITrampolines.executeDebugDescrgetfunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - // HPy (*HPyFunc_descrgetfunc)(HPyContext *, HPy, HPy, HPy) - case HPyFunc_ssizessizeargfunc: - // HPy (*HPyFunc_ssizessizeargfunc)(HPyContext *, HPy, HPy_ssize_t, - // HPy_ssize_t); - return GraalHPyJNITrampolines.executeDebugSsizessizeargfunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_keywords: - // HPy (*HPyFunc_keywords)(HPyContext *, HPy, HPy *, HPy_ssize_t , HPy) - return GraalHPyJNITrampolines.executeDebugKeywords(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3), convertArgNode.execute(arguments, 4)); - case HPyFunc_inquiry: - return GraalHPyJNITrampolines.executeDebugInquiry(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1)); - case HPyFunc_ssizeobjargproc: - return GraalHPyJNITrampolines.executeDebugSsizeobjargproc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), (long) arguments[2], - convertArgNode.execute(arguments, 3)); - case HPyFunc_initproc: - return GraalHPyJNITrampolines.executeDebugInitproc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), (long) arguments[3], convertArgNode.execute(arguments, 4)); - case HPyFunc_ssizessizeobjargproc: - return GraalHPyJNITrampolines.executeDebugSsizessizeobjargproc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), (long) arguments[2], - (long) arguments[3], convertArgNode.execute(arguments, 4)); - case HPyFunc_setter: - // int (*HPyFunc_setter)(HPyContext *ctx, HPy, HPy, void *); - return GraalHPyJNITrampolines.executeDebugSetter(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_setattrfunc: - // int (*HPyFunc_setattrfunc)(HPyContext *ctx, HPy, char *, HPy); - return GraalHPyJNITrampolines.executeDebugSetattrfunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_objobjargproc: - return GraalHPyJNITrampolines.executeDebugObjobjargproc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_descrsetfunc: - return GraalHPyJNITrampolines.executeDebugDescrsetfunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_setattrofunc: - return GraalHPyJNITrampolines.executeDebugSetattrofunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_freefunc: - // no handles involved in freefunc; we can use the universal trampoline - GraalHPyJNITrampolines.executeDebugFreefunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1)); - return 0; - case HPyFunc_richcmpfunc: - // HPy (*HPyFunc_richcmpfunc)(HPyContext *ctx, HPy, HPy, HPy_RichCmpOp) - return GraalHPyJNITrampolines.executeDebugRichcmpfunc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), (int) arguments[3]); - case HPyFunc_objobjproc: - return GraalHPyJNITrampolines.executeDebugObjobjproc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_getbufferproc: - return GraalHPyJNITrampolines.executeDebugGetbufferproc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), (int) arguments[3]); - case HPyFunc_releasebufferproc: - GraalHPyJNITrampolines.executeDebugReleasebufferproc(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - return 0; - case HPyFunc_destroyfunc: - GraalHPyJNITrampolines.executeDestroyfunc(convertPointer(arguments[0], interopLibrary), receiver.pointer); - return 0; - case HPyFunc_destructor: - GraalHPyJNITrampolines.executeDebugDestructor(receiver.pointer, convertHPyTraceContext(arguments), convertArgNode.execute(arguments, 1)); - return 0; - } - throw CompilerDirectives.shouldNotReachHere(); - } - - /** - * When we are in debug mode, we need to use different trampolines for calling the HPy - * extension functions because object parameters (that will become handles) will be wrapped - * in debug handles ({@code DHPy}) and, vice versa, object return values need to be - * unwrapped. This un/-wrapping is done by the trampoline via calling {@code DHPy_open} and - * {@code DHPy_unwrap}. - */ - private static long callDebug(GraalHPyJNIFunctionPointer receiver, LLVMType signature, long ctx, Object[] arguments, - InteropLibrary interopLibrary, GraalHPyJNIConvertArgNode convertArgNode) { - switch (signature) { - case HPyModule_init: - // there is not difference to the universal mode - return GraalHPyJNITrampolines.executeModuleInit(receiver.pointer); - case HPyModule_create: - return GraalHPyJNITrampolines.executeDebugModcreate(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_noargs: - return GraalHPyJNITrampolines.executeDebugNoargs(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_unaryfunc: - return GraalHPyJNITrampolines.executeDebugUnaryfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_getiterfunc: - return GraalHPyJNITrampolines.executeDebugGetiterfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_iternextfunc: - return GraalHPyJNITrampolines.executeDebugIternextfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_reprfunc: - return GraalHPyJNITrampolines.executeDebugReprfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_lenfunc: - return GraalHPyJNITrampolines.executeDebugLenfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_hashfunc: - // HPy_ssize_t (*HPyFunc_lenfunc)(HPyContext *ctx, HPy); - // HPy_hash_t (*HPyFunc_hashfunc)(HPyContext *ctx, HPy); - return GraalHPyJNITrampolines.executeDebugHashfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_binaryfunc: - return GraalHPyJNITrampolines.executeDebugBinaryfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_o: - return GraalHPyJNITrampolines.executeDebugO(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_getattrofunc: - return GraalHPyJNITrampolines.executeDebugGetattrofunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_getattrfunc: - // HPy (*HPyFunc_getattrfunc) (HPyContext *ctx, HPy, char *); - return GraalHPyJNITrampolines.executeDebugGetattrfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_ssizeargfunc: - // HPy (*HPyFunc_ssizeargfunc)(HPyContext *ctx, HPy, HPy_ssize_t); - return GraalHPyJNITrampolines.executeDebugSsizeargfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_getter: - // HPy (*HPyFunc_getter) (HPyContext *ctx, HPy, void *); - return GraalHPyJNITrampolines.executeDebugGetter(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_traverseproc: - // int (*HPyFunc_traverseproc)(void *, HPyFunc_visitproc, void *); - return GraalHPyJNITrampolines.executeTraverseproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_varargs: - // HPy (*HPyFunc_varargs)(HPyContext *, HPy, HPy *, HPy_ssize_t); - return GraalHPyJNITrampolines.executeDebugVarargs(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_ternaryfunc: - // HPy (*HPyFunc_ternaryfunc)(HPyContext *, HPy, HPy, HPy) - return GraalHPyJNITrampolines.executeDebugTernaryfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_descrgetfunc: - return GraalHPyJNITrampolines.executeDebugDescrgetfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - // HPy (*HPyFunc_descrgetfunc)(HPyContext *, HPy, HPy, HPy) - case HPyFunc_ssizessizeargfunc: - // HPy (*HPyFunc_ssizessizeargfunc)(HPyContext *, HPy, HPy_ssize_t, - // HPy_ssize_t); - return GraalHPyJNITrampolines.executeDebugSsizessizeargfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_keywords: - // HPy (*HPyFunc_keywords)(HPyContext *, HPy, HPy *, HPy_ssize_t , HPy) - return GraalHPyJNITrampolines.executeDebugKeywords(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3), convertArgNode.execute(arguments, 4)); - case HPyFunc_inquiry: - return GraalHPyJNITrampolines.executeDebugInquiry(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - case HPyFunc_ssizeobjargproc: - return GraalHPyJNITrampolines.executeDebugSsizeobjargproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), (long) arguments[2], - convertArgNode.execute(arguments, 3)); - case HPyFunc_initproc: - return GraalHPyJNITrampolines.executeDebugInitproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), (long) arguments[3], convertArgNode.execute(arguments, 4)); - case HPyFunc_ssizessizeobjargproc: - return GraalHPyJNITrampolines.executeDebugSsizessizeobjargproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), (long) arguments[2], - (long) arguments[3], convertArgNode.execute(arguments, 4)); - case HPyFunc_setter: - // int (*HPyFunc_setter)(HPyContext *ctx, HPy, HPy, void *); - return GraalHPyJNITrampolines.executeDebugSetter(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_setattrfunc: - // int (*HPyFunc_setattrfunc)(HPyContext *ctx, HPy, char *, HPy); - return GraalHPyJNITrampolines.executeDebugSetattrfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_objobjargproc: - return GraalHPyJNITrampolines.executeDebugObjobjargproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_descrsetfunc: - return GraalHPyJNITrampolines.executeDebugDescrsetfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_setattrofunc: - return GraalHPyJNITrampolines.executeDebugSetattrofunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), convertArgNode.execute(arguments, 3)); - case HPyFunc_freefunc: - // no handles involved in freefunc; we can use the universal trampoline - GraalHPyJNITrampolines.executeDebugFreefunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - return 0; - case HPyFunc_richcmpfunc: - // HPy (*HPyFunc_richcmpfunc)(HPyContext *ctx, HPy, HPy, HPy_RichCmpOp) - return GraalHPyJNITrampolines.executeDebugRichcmpfunc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), (int) arguments[3]); - case HPyFunc_objobjproc: - return GraalHPyJNITrampolines.executeDebugObjobjproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - case HPyFunc_getbufferproc: - return GraalHPyJNITrampolines.executeDebugGetbufferproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2), (int) arguments[3]); - case HPyFunc_releasebufferproc: - GraalHPyJNITrampolines.executeDebugReleasebufferproc(receiver.pointer, ctx, convertArgNode.execute(arguments, 1), - convertArgNode.execute(arguments, 2)); - return 0; - case HPyFunc_destroyfunc: - GraalHPyJNITrampolines.executeDestroyfunc(convertPointer(arguments[0], interopLibrary), receiver.pointer); - return 0; - case HPyFunc_destructor: - GraalHPyJNITrampolines.executeDebugDestructor(receiver.pointer, ctx, convertArgNode.execute(arguments, 1)); - return 0; - } - throw CompilerDirectives.shouldNotReachHere(); - } - - private static long convertHPyContext(Object[] arguments) { - GraalHPyJNIContext jniBackend = GraalHPyJNIConvertArgNode.getHPyContext(arguments); - try { - return jniBackend.asPointer(); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } - - private static long convertHPyDebugContext(Object[] arguments) { - GraalHPyJNIContext jniBackend = GraalHPyJNIConvertArgNode.getHPyContext(arguments); - assert jniBackend.getHPyDebugContext() != 0; - return jniBackend.getHPyDebugContext(); - } - - private static long convertHPyTraceContext(Object[] arguments) { - GraalHPyJNIContext jniBackend = GraalHPyJNIConvertArgNode.getHPyContext(arguments); - assert jniBackend.getHPyTraceContext() != 0; - return jniBackend.getHPyTraceContext(); - } - - private static long convertPointer(Object argument, InteropLibrary interopLibrary) { - if (!interopLibrary.isPointer(argument)) { - interopLibrary.toNative(argument); - } - try { - return interopLibrary.asPointer(argument); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } - } - - @ExportMessage - @SuppressWarnings("static-method") - boolean isPointer() { - return true; - } - - @ExportMessage - long asPointer() { - return pointer; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNINodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNINodes.java deleted file mode 100644 index bef2dab579..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNINodes.java +++ /dev/null @@ -1,848 +0,0 @@ -/* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy.jni; - -import static com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.UNSAFE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyHandle.NULL_HANDLE_DELEGATE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.jni.GraalHPyJNIContext.coerceToPointer; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; - -import com.oracle.graal.python.builtins.objects.cext.common.NativePointer; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyBoxing; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.AllocateNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.BulkFreeHandleReferencesNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.FreeNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.GetElementPtrNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.IsNullNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadDoubleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadFloatNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadGenericNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyArrayNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyFieldNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadI32Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadI64Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadI8ArrayNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteDoubleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteGenericNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteHPyFieldNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteHPyNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteI32Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteI64Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WritePointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteSizeTNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.GraalHPyHandleReference; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyData; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsCharPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyFromCharPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType; -import com.oracle.graal.python.builtins.objects.ints.PInt; -import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; -import com.oracle.truffle.api.profiles.InlinedExactClassProfile; -import com.oracle.truffle.api.strings.TruffleString; -import com.oracle.truffle.api.strings.TruffleString.Encoding; - -import sun.misc.Unsafe; - -abstract class GraalHPyJNINodes { - - private GraalHPyJNINodes() { - } - - static final class UnsafeIsNullNode extends IsNullNode { - - static final UnsafeIsNullNode UNCACHED = new UnsafeIsNullNode(); - - private UnsafeIsNullNode() { - } - - @Override - protected boolean execute(@SuppressWarnings("unused") GraalHPyContext ctx, Object pointer) { - return coerceToPointer(pointer) == 0; - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeAllocateNode extends AllocateNode { - - static final UnsafeAllocateNode UNCACHED = new UnsafeAllocateNode(); - - private UnsafeAllocateNode() { - } - - @Override - protected Object execute(@SuppressWarnings("unused") GraalHPyContext ctx, long size, boolean zero) { - long result = UNSAFE.allocateMemory(size); - if (zero) { - UNSAFE.setMemory(result, size, (byte) 0); - } - return result; - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeFreeNode extends FreeNode { - - static final UnsafeFreeNode UNCACHED = new UnsafeFreeNode(); - - private UnsafeFreeNode() { - } - - @Override - protected void execute(@SuppressWarnings("unused") GraalHPyContext ctx, Object pointer) { - UNSAFE.freeMemory(coerceToPointer(pointer)); - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeBulkFreeHandleReferencesNode extends BulkFreeHandleReferencesNode { - - private static final int BULK_CAPACITY = 1024; - - static final UnsafeBulkFreeHandleReferencesNode UNCACHED = new UnsafeBulkFreeHandleReferencesNode(); - - private UnsafeBulkFreeHandleReferencesNode() { - } - - @Override - @TruffleBoundary - protected void execute(@SuppressWarnings("unused") GraalHPyContext ctx, GraalHPyHandleReference[] references) { - long[] nativeSpacePtrs = new long[BULK_CAPACITY]; - long[] destroyFuncPtrs = new long[BULK_CAPACITY]; - int i = 0; - for (GraalHPyHandleReference ref : references) { - long destroyFunPtr = coerceToPointer(ref.getDestroyFunc()); - long nativeSpacePtr = coerceToPointer(ref.getNativeSpace()); - if (destroyFunPtr == 0) { - // in this case, we can just use 'free' - UNSAFE.freeMemory(nativeSpacePtr); - } else { - if (i >= BULK_CAPACITY) { - GraalHPyJNIContext.bulkFreeNativeSpace(nativeSpacePtrs, destroyFuncPtrs, BULK_CAPACITY); - i = 0; - } - destroyFuncPtrs[i] = destroyFunPtr; - nativeSpacePtrs[i] = nativeSpacePtr; - i++; - } - } - if (i > 0) { - GraalHPyJNIContext.bulkFreeNativeSpace(nativeSpacePtrs, destroyFuncPtrs, i); - } - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeGetElementPtrNode extends GetElementPtrNode { - static final UnsafeGetElementPtrNode UNCACHED = new UnsafeGetElementPtrNode(); - - private UnsafeGetElementPtrNode() { - } - - @Override - public Object execute(@SuppressWarnings("unused") GraalHPyContext ctx, Object pointer, long offset) { - return coerceToPointer(pointer) + offset; - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeReadI8ArrayNode extends ReadI8ArrayNode { - - static final UnsafeReadI8ArrayNode UNCACHED = new UnsafeReadI8ArrayNode(); - - private UnsafeReadI8ArrayNode() { - } - - @Override - protected byte[] execute(GraalHPyContext ctx, Object pointer, long offset, long n) { - if (!PInt.isIntRange(n)) { - throw CompilerDirectives.shouldNotReachHere("cannot fit long into int"); - } - byte[] result = new byte[(int) n]; - long ptr = coerceToPointer(pointer) + offset; - UNSAFE.copyMemory(null, ptr, result, Unsafe.ARRAY_BYTE_BASE_OFFSET, n); - return result; - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeReadHPyNode extends ReadHPyNode { - - static final UnsafeReadHPyNode UNCACHED = new UnsafeReadHPyNode(); - - private UnsafeReadHPyNode() { - } - - @Override - protected Object execute(GraalHPyContext ctx, Object pointer, long offset, boolean close) { - assert ctx.getCTypeSize(HPyContextSignatureType.HPy) == UNSAFE.addressSize(); - long bits = UNSAFE.getAddress(coerceToPointer(pointer) + offset); - Object result = ctx.bitsAsPythonObject(bits); - if (close && GraalHPyBoxing.isBoxedHandle(bits)) { - ctx.releaseHPyHandleForObject(GraalHPyBoxing.unboxHandle(bits)); - } - return result; - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeReadHPyFieldNode extends ReadHPyFieldNode { - - static final UnsafeReadHPyFieldNode UNCACHED = new UnsafeReadHPyFieldNode(); - - private UnsafeReadHPyFieldNode() { - } - - @Override - protected Object execute(GraalHPyContext ctx, PythonObject owner, Object pointer, long offset, boolean close) { - assert ctx.getCTypeSize(HPyContextSignatureType.HPy) == UNSAFE.addressSize(); - long bits = UNSAFE.getAddress(coerceToPointer(pointer) + offset); - if (!PInt.isIntRange(bits)) { - throw CompilerDirectives.shouldNotReachHere(); - } - int idx = (int) bits; - if (idx == 0) { - return NULL_HANDLE_DELEGATE; - } - return GraalHPyData.getHPyField(owner, idx); - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeReadHPyArrayNode extends ReadHPyArrayNode { - - static final UnsafeReadHPyArrayNode UNCACHED = new UnsafeReadHPyArrayNode(); - - private UnsafeReadHPyArrayNode() { - } - - @Override - protected Object[] execute(GraalHPyContext ctx, Object pointer, long offset, long n) { - if (!PInt.isIntRange(n)) { - throw CompilerDirectives.shouldNotReachHere("cannot fit long into int"); - } - long basePtr = coerceToPointer(pointer); - Object[] result = new Object[(int) n]; - for (int i = 0; i < result.length; i++) { - result[i] = ctx.bitsAsPythonObject(UNSAFE.getAddress(basePtr + (i + offset) * UNSAFE.addressSize())); - } - return result; - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeReadI32Node extends ReadI32Node { - - static final UnsafeReadI32Node UNCACHED = new UnsafeReadI32Node(); - - private UnsafeReadI32Node() { - } - - @Override - protected int execute(@SuppressWarnings("unused") GraalHPyContext ctx, Object pointer, long offset) { - return UNSAFE.getInt(coerceToPointer(pointer) + offset); - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeReadI64Node extends ReadI64Node { - - static final UnsafeReadI64Node UNCACHED = new UnsafeReadI64Node(); - - private UnsafeReadI64Node() { - } - - @Override - protected long execute(@SuppressWarnings("unused") GraalHPyContext ctx, Object pointer, long offset) { - return UNSAFE.getLong(coerceToPointer(pointer) + offset); - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeReadFloatNode extends ReadFloatNode { - - static final UnsafeReadFloatNode UNCACHED = new UnsafeReadFloatNode(); - - private UnsafeReadFloatNode() { - } - - @Override - protected double execute(@SuppressWarnings("unused") GraalHPyContext ctx, Object pointer, long offset) { - return UNSAFE.getFloat(coerceToPointer(pointer) + offset); - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeReadDoubleNode extends ReadDoubleNode { - - static final UnsafeReadDoubleNode UNCACHED = new UnsafeReadDoubleNode(); - - private UnsafeReadDoubleNode() { - } - - @Override - protected double execute(@SuppressWarnings("unused") GraalHPyContext ctx, Object pointer, long offset) { - return UNSAFE.getDouble(coerceToPointer(pointer) + offset); - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeReadPointerNode extends ReadPointerNode { - - static final UnsafeReadPointerNode UNCACHED = new UnsafeReadPointerNode(); - - private UnsafeReadPointerNode() { - } - - @Override - protected Object execute(@SuppressWarnings("unused") GraalHPyContext ctx, Object pointer, long offset) { - return UNSAFE.getAddress(coerceToPointer(pointer) + offset); - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeReadGenericNode extends ReadGenericNode { - - static final UnsafeReadGenericNode UNCACHED = new UnsafeReadGenericNode(); - - private UnsafeReadGenericNode() { - } - - @Override - protected Object execute(@SuppressWarnings("unused") GraalHPyContext ctx, Object pointer, long offset, HPyContextSignatureType type) { - long addr = coerceToPointer(pointer) + offset; - switch (type) { - case Int8_t, Uint8_t, Bool: - return UNSAFE.getByte(addr); - case Int16_t, Uint16_t: - return UNSAFE.getShort(addr); - case Int32_t, Uint32_t: - return UNSAFE.getInt(addr); - case Int64_t, Uint64_t: - return UNSAFE.getLong(addr); - case CFloat: - return UNSAFE.getFloat(addr); - case CDouble: - return UNSAFE.getDouble(addr); - case HPyContextPtr, VoidPtr, VoidPtrPtr, HPyPtr, ConstHPyPtr, Wchar_tPtr, ConstWchar_tPtr, CharPtr: - case ConstCharPtr, DataPtr, DataPtrPtr, Cpy_PyObjectPtr, HPyModuleDefPtr, HPyType_SpecPtr: - case HPyType_SpecParamPtr, HPyDefPtr, HPyFieldPtr, HPyGlobalPtr, HPyCapsule_DestructorPtr, PyType_SlotPtr: - return UNSAFE.getAddress(addr); - default: - int size = ctx.getCTypeSize(type); - switch (size) { - case 1: - return UNSAFE.getByte(addr); - case 2: - return UNSAFE.getShort(addr); - case 4: - return UNSAFE.getInt(addr); - case 8: - return UNSAFE.getLong(addr); - } - - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @Override - protected int executeInt(@SuppressWarnings("unused") GraalHPyContext ctx, Object pointer, long offset, HPyContextSignatureType type) { - return (int) executeLong(ctx, pointer, offset, type); - } - - @Override - protected long executeLong(@SuppressWarnings("unused") GraalHPyContext ctx, Object pointer, long offset, HPyContextSignatureType type) { - long addr = coerceToPointer(pointer) + offset; - int size; - switch (type) { - case Int8_t, Uint8_t, Bool: - size = 1; - break; - case Int16_t, Uint16_t: - size = 2; - break; - case Int32_t, Uint32_t: - size = 4; - break; - case Int64_t, Uint64_t: - size = 8; - break; - default: - size = ctx.getCTypeSize(type); - break; - } - switch (size) { - case 1: - return UNSAFE.getByte(addr); - case 2: - return UNSAFE.getShort(addr); - case 4: - return UNSAFE.getInt(addr); - case 8: - return UNSAFE.getLong(addr); - default: - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeWriteI32Node extends WriteI32Node { - - static final UnsafeWriteI32Node UNCACHED = new UnsafeWriteI32Node(); - - private UnsafeWriteI32Node() { - } - - @Override - protected void execute(@SuppressWarnings("unused") GraalHPyContext ctx, Object pointer, long offset, int value) { - UNSAFE.putInt(coerceToPointer(pointer) + offset, value); - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeWriteI64Node extends WriteI64Node { - - static final UnsafeWriteI64Node UNCACHED = new UnsafeWriteI64Node(); - - private UnsafeWriteI64Node() { - } - - @Override - protected void execute(@SuppressWarnings("unused") GraalHPyContext ctx, Object pointer, long offset, long value) { - UNSAFE.putLong(coerceToPointer(pointer) + offset, value); - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeWriteDoubleNode extends WriteDoubleNode { - - static final UnsafeWriteDoubleNode UNCACHED = new UnsafeWriteDoubleNode(); - - private UnsafeWriteDoubleNode() { - } - - @Override - protected void execute(@SuppressWarnings("unused") GraalHPyContext ctx, Object pointer, long offset, double value) { - UNSAFE.putDouble(coerceToPointer(pointer) + offset, value); - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeWriteGenericNode extends WriteGenericNode { - - static final UnsafeWriteGenericNode UNCACHED = new UnsafeWriteGenericNode(); - - private UnsafeWriteGenericNode() { - } - - @Override - protected void execute(GraalHPyContext ctx, Object pointer, long offset, HPyContextSignatureType type, long value) { - long addr = coerceToPointer(pointer) + offset; - int size; - switch (type) { - case Int8_t, Uint8_t, Bool: - size = 1; - break; - case Int16_t, Uint16_t: - size = 2; - break; - case Int32_t, Uint32_t: - size = 4; - break; - case Int64_t, Uint64_t: - size = 8; - break; - default: - size = ctx.getCTypeSize(type); - break; - } - switch (size) { - case 1: - UNSAFE.putByte(addr, (byte) value); - break; - case 2: - UNSAFE.putShort(addr, (short) value); - break; - case 4: - UNSAFE.putInt(addr, (int) value); - break; - case 8: - UNSAFE.putLong(addr, value); - break; - default: - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @Override - protected void execute(GraalHPyContext ctx, Object pointer, long offset, HPyContextSignatureType type, Object value) { - long addr = coerceToPointer(pointer) + offset; - switch (type) { - case Int8_t, Uint8_t, Bool: - UNSAFE.putByte(addr, (byte) value); - break; - case Int16_t, Uint16_t: - UNSAFE.putShort(addr, (short) value); - break; - case Int32_t, Uint32_t: - UNSAFE.putInt(addr, (int) value); - break; - case Int64_t, Uint64_t: - UNSAFE.putLong(addr, (long) value); - break; - case CFloat: - UNSAFE.putFloat(addr, (float) value); - break; - case CDouble: - UNSAFE.putDouble(addr, (double) value); - break; - case HPyContextPtr, VoidPtr, VoidPtrPtr, HPyPtr, ConstHPyPtr, Wchar_tPtr, ConstWchar_tPtr, CharPtr: - case ConstCharPtr, DataPtr, DataPtrPtr, Cpy_PyObjectPtr, HPyModuleDefPtr, HPyType_SpecPtr: - case HPyType_SpecParamPtr, HPyDefPtr, HPyFieldPtr, HPyGlobalPtr, HPyCapsule_DestructorPtr, PyType_SlotPtr: - UNSAFE.putAddress(addr, (long) value); - break; - default: - int size = ctx.getCTypeSize(type); - switch (size) { - case 1: - UNSAFE.putByte(addr, (byte) value); - break; - case 2: - UNSAFE.putShort(addr, (short) value); - break; - case 4: - UNSAFE.putInt(addr, (int) value); - break; - case 8: - UNSAFE.putLong(addr, (long) value); - break; - default: - throw CompilerDirectives.shouldNotReachHere(); - } - } - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeWriteHPyNode extends WriteHPyNode { - - static final UnsafeWriteHPyNode UNCACHED = new UnsafeWriteHPyNode(); - - private UnsafeWriteHPyNode() { - } - - @Override - protected void execute(GraalHPyContext ctx, Object pointer, long offset, Object value) { - long bits = ctx.pythonObjectAsBits(value); - UNSAFE.putAddress(coerceToPointer(pointer) + offset, bits); - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeWriteHPyFieldNode extends WriteHPyFieldNode { - - static final UnsafeWriteHPyFieldNode UNCACHED = new UnsafeWriteHPyFieldNode(); - - private UnsafeWriteHPyFieldNode() { - } - - @Override - protected void execute(GraalHPyContext ctx, PythonObject owner, Object pointer, long offset, Object value) { - long address = coerceToPointer(pointer) + offset; - long loldValue = UNSAFE.getAddress(address); - if (!PInt.isIntRange(loldValue)) { - throw CompilerDirectives.shouldNotReachHere(); - } - int oldValue = (int) loldValue; - // TODO: (tfel) do not actually allocate the index / free the existing one when - // value can be stored as tagged handle - if (value == NULL_HANDLE_DELEGATE && oldValue == 0) { - // assigning HPy_NULL to a field that already holds HPy_NULL, nothing to do - } else { - int newValue = GraalHPyData.setHPyField(owner, value, oldValue); - if (oldValue != newValue) { - UNSAFE.putAddress(address, newValue); - } - } - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeWritePointerNode extends WritePointerNode { - - static final UnsafeWritePointerNode UNCACHED = new UnsafeWritePointerNode(); - - private UnsafeWritePointerNode() { - } - - @Override - protected void execute(GraalHPyContext ctx, Object basePointer, long offset, Object valuePointer) { - UNSAFE.putAddress(coerceToPointer(basePointer) + offset, coerceToPointer(valuePointer)); - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - static final class UnsafeWriteSizeTNode extends WriteSizeTNode { - - static final UnsafeWriteSizeTNode UNCACHED = new UnsafeWriteSizeTNode(); - - private UnsafeWriteSizeTNode() { - } - - @Override - protected void execute(GraalHPyContext ctx, Object basePointer, long offset, long valuePointer) { - write(coerceToPointer(basePointer) + offset, valuePointer); - } - - static void write(long address, long value) { - UNSAFE.putAddress(address, value); - } - - @Override - public boolean isAdoptable() { - return false; - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyJNIFromCharPointerNode extends HPyFromCharPointerNode { - - @Specialization - static TruffleString doLong(@SuppressWarnings("unused") GraalHPyContext hpyContext, long charPtr, int n, Encoding encoding, boolean copy, - @Bind("this") Node inliningTarget, - @Exclusive @Cached InlinedConditionProfile lengthProfile, - @Exclusive @Cached TruffleString.FromNativePointerNode fromNativePointerNode, - @Exclusive @Cached TruffleString.SwitchEncodingNode switchEncodingNode) { - int length = lengthProfile.profile(inliningTarget, n < 0) ? strlen(charPtr) : n; - return read(new NativePointer(charPtr), length, encoding, copy, fromNativePointerNode, switchEncodingNode); - } - - @Specialization - static TruffleString doNativePointer(@SuppressWarnings("unused") GraalHPyContext hpyContext, NativePointer charPtr, int n, Encoding encoding, boolean copy, - @Bind("this") Node inliningTarget, - @Exclusive @Cached InlinedConditionProfile lengthProfile, - @Exclusive @Cached TruffleString.FromNativePointerNode fromNativePointerNode, - @Exclusive @Cached TruffleString.SwitchEncodingNode switchEncodingNode) { - int length = lengthProfile.profile(inliningTarget, n < 0) ? strlen(charPtr.asPointer()) : n; - return read(charPtr, length, encoding, copy, fromNativePointerNode, switchEncodingNode); - } - - @Specialization(replaces = {"doLong", "doNativePointer"}) - static TruffleString doGeneric(@SuppressWarnings("unused") GraalHPyContext hpyContext, Object charPtr, int n, Encoding encoding, boolean copy, - @Bind("this") Node inliningTarget, - @Exclusive @CachedLibrary(limit = "1") InteropLibrary lib, - @Exclusive @Cached InlinedConditionProfile lengthProfile, - @Exclusive @Cached TruffleString.FromNativePointerNode fromNativePointerNode, - @Exclusive @Cached TruffleString.SwitchEncodingNode switchEncodingNode) { - - long lcharPtr; - Object interopPtr; - if (charPtr instanceof Long ltmp) { - interopPtr = new NativePointer(ltmp); - lcharPtr = ltmp; - } else if (charPtr instanceof NativePointer nativeCharPtr) { - interopPtr = nativeCharPtr; - lcharPtr = nativeCharPtr.asPointer(); - } else { - try { - interopPtr = charPtr; - lcharPtr = lib.asPointer(charPtr); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - int length = lengthProfile.profile(inliningTarget, n < 0) ? strlen(lcharPtr) : n; - return read(interopPtr, length, encoding, copy, fromNativePointerNode, switchEncodingNode); - } - - private static TruffleString read(Object charPtr, int length, Encoding encoding, boolean copy, - TruffleString.FromNativePointerNode fromNativePointerNode, - TruffleString.SwitchEncodingNode switchEncodingNode) { - assert length >= 0; - TruffleString result = fromNativePointerNode.execute(charPtr, 0, length, encoding, copy); - if (TS_ENCODING != encoding) { - return switchEncodingNode.execute(result, TS_ENCODING); - } - return result; - } - - static int strlen(long charPtr) { - int length = 0; - while (UNSAFE.getByte(charPtr + length) != 0) { - length++; - } - return length; - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyJNIAsCharPointerNode extends HPyAsCharPointerNode { - - abstract long executeLong(GraalHPyContext hpyContext, TruffleString string, Encoding encoding); - - @Specialization - static long doGeneric(@SuppressWarnings("unused") GraalHPyContext hpyContext, TruffleString string, Encoding encoding, - @Bind("this") Node inliningTarget, - @Cached InlinedExactClassProfile classProfile, - @Cached TruffleString.SwitchEncodingNode switchEncodingNode, - @Cached TruffleString.AsNativeNode asNativeNode, - @Cached TruffleString.GetInternalNativePointerNode getInternalNativePointerNode) { - TruffleString tsEncoded = switchEncodingNode.execute(string, encoding); - TruffleString tsNative = asNativeNode.execute(tsEncoded, GraalHPyJNIContext.TS_NATIVE_ALLOCATOR, encoding, false, true); - Object profiledInteropPointer = classProfile.profile(inliningTarget, getInternalNativePointerNode.execute(tsNative, encoding)); - if (profiledInteropPointer instanceof NativePointer nativePointer) { - return nativePointer.asPointer(); - } - return interopPointerToNative(profiledInteropPointer); - } - - @TruffleBoundary - private static long interopPointerToNative(Object object) { - return GraalHPyJNIContext.interopPointerToNative(object, InteropLibrary.getUncached(object)); - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNITrampolines.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNITrampolines.java deleted file mode 100644 index a15956b467..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/jni/GraalHPyJNITrampolines.java +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy.jni; - -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; - -abstract class GraalHPyJNITrampolines { - - /* manual HPY JNI trampoline declarations */ - - @TruffleBoundary - public static native long executeModuleInit(long target); - - @TruffleBoundary - public static native void executeDestroyfunc(long target, long dataptr); - - // int (*HPyFunc_traverseproc)(void *, HPyFunc_visitproc, void *); - public static long executeTraverseproc(long target, long self, long visitproc, long field) { - throw CompilerDirectives.shouldNotReachHere("traverseproc should never be called"); - } - - /* generated HPY JNI trampoline declarations */ - - // {{start autogen}} - // @formatter:off - // Checkstyle: stop - // DO NOT EDIT THIS PART! - // This part is automatically generated by hpy.tools.autogen.graalpy.autogen_ctx_jni - // typedef HPy (*HPyFunc_noargs)(HPyContext *ctx, HPy self) - @TruffleBoundary - public static native long executeNoargs(long target, long ctx, long self); - - // typedef HPy (*HPyFunc_o)(HPyContext *ctx, HPy self, HPy arg) - @TruffleBoundary - public static native long executeO(long target, long ctx, long self, long arg); - - // typedef HPy (*HPyFunc_varargs)(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - @TruffleBoundary - public static native long executeVarargs(long target, long ctx, long self, long args, long nargs); - - // typedef HPy (*HPyFunc_keywords)(HPyContext *ctx, HPy self, const HPy *args, size_t nargs, HPy kwnames) - @TruffleBoundary - public static native long executeKeywords(long target, long ctx, long self, long args, long nargs, long kwnames); - - // typedef HPy (*HPyFunc_unaryfunc)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native long executeUnaryfunc(long target, long ctx, long arg0); - - // typedef HPy (*HPyFunc_binaryfunc)(HPyContext *ctx, HPy, HPy) - @TruffleBoundary - public static native long executeBinaryfunc(long target, long ctx, long arg0, long arg1); - - // typedef HPy (*HPyFunc_ternaryfunc)(HPyContext *ctx, HPy, HPy, HPy) - @TruffleBoundary - public static native long executeTernaryfunc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef int (*HPyFunc_inquiry)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native int executeInquiry(long target, long ctx, long arg0); - - // typedef HPy_ssize_t (*HPyFunc_lenfunc)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native long executeLenfunc(long target, long ctx, long arg0); - - // typedef HPy (*HPyFunc_ssizeargfunc)(HPyContext *ctx, HPy, HPy_ssize_t) - @TruffleBoundary - public static native long executeSsizeargfunc(long target, long ctx, long arg0, long arg1); - - // typedef HPy (*HPyFunc_ssizessizeargfunc)(HPyContext *ctx, HPy, HPy_ssize_t, HPy_ssize_t) - @TruffleBoundary - public static native long executeSsizessizeargfunc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef int (*HPyFunc_ssizeobjargproc)(HPyContext *ctx, HPy, HPy_ssize_t, HPy) - @TruffleBoundary - public static native int executeSsizeobjargproc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef int (*HPyFunc_ssizessizeobjargproc)(HPyContext *ctx, HPy, HPy_ssize_t, HPy_ssize_t, HPy) - @TruffleBoundary - public static native int executeSsizessizeobjargproc(long target, long ctx, long arg0, long arg1, long arg2, long arg3); - - // typedef int (*HPyFunc_objobjargproc)(HPyContext *ctx, HPy, HPy, HPy) - @TruffleBoundary - public static native int executeObjobjargproc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef void (*HPyFunc_freefunc)(HPyContext *ctx, void *) - @TruffleBoundary - public static native void executeFreefunc(long target, long ctx, long arg0); - - // typedef HPy (*HPyFunc_getattrfunc)(HPyContext *ctx, HPy, char *) - @TruffleBoundary - public static native long executeGetattrfunc(long target, long ctx, long arg0, long arg1); - - // typedef HPy (*HPyFunc_getattrofunc)(HPyContext *ctx, HPy, HPy) - @TruffleBoundary - public static native long executeGetattrofunc(long target, long ctx, long arg0, long arg1); - - // typedef int (*HPyFunc_setattrfunc)(HPyContext *ctx, HPy, char *, HPy) - @TruffleBoundary - public static native int executeSetattrfunc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef int (*HPyFunc_setattrofunc)(HPyContext *ctx, HPy, HPy, HPy) - @TruffleBoundary - public static native int executeSetattrofunc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef HPy (*HPyFunc_reprfunc)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native long executeReprfunc(long target, long ctx, long arg0); - - // typedef HPy_hash_t (*HPyFunc_hashfunc)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native long executeHashfunc(long target, long ctx, long arg0); - - // typedef HPy (*HPyFunc_richcmpfunc)(HPyContext *ctx, HPy, HPy, HPy_RichCmpOp) - @TruffleBoundary - public static native long executeRichcmpfunc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef HPy (*HPyFunc_getiterfunc)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native long executeGetiterfunc(long target, long ctx, long arg0); - - // typedef HPy (*HPyFunc_iternextfunc)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native long executeIternextfunc(long target, long ctx, long arg0); - - // typedef HPy (*HPyFunc_descrgetfunc)(HPyContext *ctx, HPy, HPy, HPy) - @TruffleBoundary - public static native long executeDescrgetfunc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef int (*HPyFunc_descrsetfunc)(HPyContext *ctx, HPy, HPy, HPy) - @TruffleBoundary - public static native int executeDescrsetfunc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef int (*HPyFunc_initproc)(HPyContext *ctx, HPy self, const HPy *args, HPy_ssize_t nargs, HPy kw) - @TruffleBoundary - public static native int executeInitproc(long target, long ctx, long self, long args, long nargs, long kw); - - // typedef HPy (*HPyFunc_newfunc)(HPyContext *ctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw) - @TruffleBoundary - public static native long executeNewfunc(long target, long ctx, long type, long args, long nargs, long kw); - - // typedef HPy (*HPyFunc_getter)(HPyContext *ctx, HPy, void *) - @TruffleBoundary - public static native long executeGetter(long target, long ctx, long arg0, long arg1); - - // typedef int (*HPyFunc_setter)(HPyContext *ctx, HPy, HPy, void *) - @TruffleBoundary - public static native int executeSetter(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef int (*HPyFunc_objobjproc)(HPyContext *ctx, HPy, HPy) - @TruffleBoundary - public static native int executeObjobjproc(long target, long ctx, long arg0, long arg1); - - // typedef int (*HPyFunc_getbufferproc)(HPyContext *ctx, HPy, HPy_buffer *, int) - @TruffleBoundary - public static native int executeGetbufferproc(long target, long ctx, long arg0, long arg1, int arg2); - - // typedef void (*HPyFunc_releasebufferproc)(HPyContext *ctx, HPy, HPy_buffer *) - @TruffleBoundary - public static native void executeReleasebufferproc(long target, long ctx, long arg0, long arg1); - - // typedef void (*HPyFunc_destructor)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native void executeDestructor(long target, long ctx, long arg0); - - // typedef HPy (*HPyFunc_mod_create)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native long executeModcreate(long target, long ctx, long arg0); - - // typedef HPy (*HPyFunc_noargs)(HPyContext *ctx, HPy self) - @TruffleBoundary - public static native long executeDebugNoargs(long target, long ctx, long self); - - // typedef HPy (*HPyFunc_o)(HPyContext *ctx, HPy self, HPy arg) - @TruffleBoundary - public static native long executeDebugO(long target, long ctx, long self, long arg); - - // typedef HPy (*HPyFunc_varargs)(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - @TruffleBoundary - public static native long executeDebugVarargs(long target, long ctx, long self, long args, long nargs); - - // typedef HPy (*HPyFunc_keywords)(HPyContext *ctx, HPy self, const HPy *args, size_t nargs, HPy kwnames) - @TruffleBoundary - public static native long executeDebugKeywords(long target, long ctx, long self, long args, long nargs, long kwnames); - - // typedef HPy (*HPyFunc_unaryfunc)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native long executeDebugUnaryfunc(long target, long ctx, long arg0); - - // typedef HPy (*HPyFunc_binaryfunc)(HPyContext *ctx, HPy, HPy) - @TruffleBoundary - public static native long executeDebugBinaryfunc(long target, long ctx, long arg0, long arg1); - - // typedef HPy (*HPyFunc_ternaryfunc)(HPyContext *ctx, HPy, HPy, HPy) - @TruffleBoundary - public static native long executeDebugTernaryfunc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef int (*HPyFunc_inquiry)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native int executeDebugInquiry(long target, long ctx, long arg0); - - // typedef HPy_ssize_t (*HPyFunc_lenfunc)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native long executeDebugLenfunc(long target, long ctx, long arg0); - - // typedef HPy (*HPyFunc_ssizeargfunc)(HPyContext *ctx, HPy, HPy_ssize_t) - @TruffleBoundary - public static native long executeDebugSsizeargfunc(long target, long ctx, long arg0, long arg1); - - // typedef HPy (*HPyFunc_ssizessizeargfunc)(HPyContext *ctx, HPy, HPy_ssize_t, HPy_ssize_t) - @TruffleBoundary - public static native long executeDebugSsizessizeargfunc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef int (*HPyFunc_ssizeobjargproc)(HPyContext *ctx, HPy, HPy_ssize_t, HPy) - @TruffleBoundary - public static native int executeDebugSsizeobjargproc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef int (*HPyFunc_ssizessizeobjargproc)(HPyContext *ctx, HPy, HPy_ssize_t, HPy_ssize_t, HPy) - @TruffleBoundary - public static native int executeDebugSsizessizeobjargproc(long target, long ctx, long arg0, long arg1, long arg2, long arg3); - - // typedef int (*HPyFunc_objobjargproc)(HPyContext *ctx, HPy, HPy, HPy) - @TruffleBoundary - public static native int executeDebugObjobjargproc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef void (*HPyFunc_freefunc)(HPyContext *ctx, void *) - @TruffleBoundary - public static native void executeDebugFreefunc(long target, long ctx, long arg0); - - // typedef HPy (*HPyFunc_getattrfunc)(HPyContext *ctx, HPy, char *) - @TruffleBoundary - public static native long executeDebugGetattrfunc(long target, long ctx, long arg0, long arg1); - - // typedef HPy (*HPyFunc_getattrofunc)(HPyContext *ctx, HPy, HPy) - @TruffleBoundary - public static native long executeDebugGetattrofunc(long target, long ctx, long arg0, long arg1); - - // typedef int (*HPyFunc_setattrfunc)(HPyContext *ctx, HPy, char *, HPy) - @TruffleBoundary - public static native int executeDebugSetattrfunc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef int (*HPyFunc_setattrofunc)(HPyContext *ctx, HPy, HPy, HPy) - @TruffleBoundary - public static native int executeDebugSetattrofunc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef HPy (*HPyFunc_reprfunc)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native long executeDebugReprfunc(long target, long ctx, long arg0); - - // typedef HPy_hash_t (*HPyFunc_hashfunc)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native long executeDebugHashfunc(long target, long ctx, long arg0); - - // typedef HPy (*HPyFunc_richcmpfunc)(HPyContext *ctx, HPy, HPy, HPy_RichCmpOp) - @TruffleBoundary - public static native long executeDebugRichcmpfunc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef HPy (*HPyFunc_getiterfunc)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native long executeDebugGetiterfunc(long target, long ctx, long arg0); - - // typedef HPy (*HPyFunc_iternextfunc)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native long executeDebugIternextfunc(long target, long ctx, long arg0); - - // typedef HPy (*HPyFunc_descrgetfunc)(HPyContext *ctx, HPy, HPy, HPy) - @TruffleBoundary - public static native long executeDebugDescrgetfunc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef int (*HPyFunc_descrsetfunc)(HPyContext *ctx, HPy, HPy, HPy) - @TruffleBoundary - public static native int executeDebugDescrsetfunc(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef int (*HPyFunc_initproc)(HPyContext *ctx, HPy self, const HPy *args, HPy_ssize_t nargs, HPy kw) - @TruffleBoundary - public static native int executeDebugInitproc(long target, long ctx, long self, long args, long nargs, long kw); - - // typedef HPy (*HPyFunc_newfunc)(HPyContext *ctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw) - @TruffleBoundary - public static native long executeDebugNewfunc(long target, long ctx, long type, long args, long nargs, long kw); - - // typedef HPy (*HPyFunc_getter)(HPyContext *ctx, HPy, void *) - @TruffleBoundary - public static native long executeDebugGetter(long target, long ctx, long arg0, long arg1); - - // typedef int (*HPyFunc_setter)(HPyContext *ctx, HPy, HPy, void *) - @TruffleBoundary - public static native int executeDebugSetter(long target, long ctx, long arg0, long arg1, long arg2); - - // typedef int (*HPyFunc_objobjproc)(HPyContext *ctx, HPy, HPy) - @TruffleBoundary - public static native int executeDebugObjobjproc(long target, long ctx, long arg0, long arg1); - - // typedef int (*HPyFunc_getbufferproc)(HPyContext *ctx, HPy, HPy_buffer *, int) - @TruffleBoundary - public static native int executeDebugGetbufferproc(long target, long ctx, long arg0, long arg1, int arg2); - - // typedef void (*HPyFunc_releasebufferproc)(HPyContext *ctx, HPy, HPy_buffer *) - @TruffleBoundary - public static native void executeDebugReleasebufferproc(long target, long ctx, long arg0, long arg1); - - // typedef void (*HPyFunc_destructor)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native void executeDebugDestructor(long target, long ctx, long arg0); - - // typedef HPy (*HPyFunc_mod_create)(HPyContext *ctx, HPy) - @TruffleBoundary - public static native long executeDebugModcreate(long target, long ctx, long arg0); - - // @formatter:on - // Checkstyle: resume - // {{end autogen}} -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/GraalHPyInitObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/GraalHPyInitObject.java deleted file mode 100644 index 2278ff6ce0..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/GraalHPyInitObject.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy.llvm; - -import com.oracle.graal.python.builtins.objects.PythonAbstractObject; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.interop.ArityException; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.library.ExportLibrary; -import com.oracle.truffle.api.library.ExportMessage; - -/** - * A simple interop-capable object that is used to initialize the HPy LLVM backend. - */ -@ExportLibrary(InteropLibrary.class) -public final class GraalHPyInitObject implements TruffleObject { - - private static final String J_SET_HPY_CONTEXT_NATIVE_TYPE = "setHPyContextNativeType"; - private static final String J_SET_HPY_NATIVE_TYPE = "setHPyNativeType"; - private static final String J_SET_HPY_ARRAY_NATIVE_TYPE = "setHPyArrayNativeType"; - private static final String J_SET_NATIVE_CACHE_FUNCTION_PTR = "setNativeCacheFunctionPtr"; - - private final GraalHPyLLVMContext backend; - - public GraalHPyInitObject(GraalHPyLLVMContext backend) { - this.backend = backend; - } - - @ExportMessage - @SuppressWarnings("static-method") - boolean hasMembers() { - return true; - } - - @ExportMessage - @TruffleBoundary - @SuppressWarnings("static-method") - Object getMembers(@SuppressWarnings("unused") boolean includeInternal) { - return new PythonAbstractObject.Keys( - new String[]{J_SET_HPY_CONTEXT_NATIVE_TYPE, J_SET_HPY_NATIVE_TYPE, J_SET_HPY_ARRAY_NATIVE_TYPE, J_SET_NATIVE_CACHE_FUNCTION_PTR}); - } - - @ExportMessage - @TruffleBoundary - @SuppressWarnings("static-method") - boolean isMemberInvocable(String key) { - return switch (key) { - case J_SET_HPY_CONTEXT_NATIVE_TYPE, J_SET_HPY_NATIVE_TYPE, J_SET_HPY_ARRAY_NATIVE_TYPE, J_SET_NATIVE_CACHE_FUNCTION_PTR -> true; - default -> false; - }; - } - - @ExportMessage - @TruffleBoundary - Object invokeMember(String key, Object[] arguments) throws UnsupportedMessageException, ArityException { - if (arguments.length != 1) { - throw ArityException.create(1, 1, arguments.length); - } - - switch (key) { - case J_SET_HPY_CONTEXT_NATIVE_TYPE -> backend.hpyContextNativeTypeID = arguments[0]; - case J_SET_HPY_NATIVE_TYPE -> backend.hpyNativeTypeID = arguments[0]; - case J_SET_HPY_ARRAY_NATIVE_TYPE -> backend.hpyArrayNativeTypeID = arguments[0]; - case J_SET_NATIVE_CACHE_FUNCTION_PTR -> backend.setNativeSpaceFunction = arguments[0]; - default -> throw UnsupportedMessageException.create(); - } - return 0; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/GraalHPyLLVMContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/GraalHPyLLVMContext.java deleted file mode 100644 index 616bfdb93c..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/GraalHPyLLVMContext.java +++ /dev/null @@ -1,1357 +0,0 @@ -/* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy.llvm; - -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.SINGLETON_HANDLE_ELIPSIS; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.SINGLETON_HANDLE_NONE; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.SINGLETON_HANDLE_NOT_IMPLEMENTED; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNativeSymbol.GRAAL_HPY_CONTEXT_TO_NATIVE; -import static com.oracle.graal.python.nodes.StringLiterals.J_LLVM_LANGUAGE; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; -import static com.oracle.graal.python.util.PythonUtils.tsLiteral; - -import java.io.IOException; -import java.util.HashMap; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.PythonAbstractObject; -import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CStringWrapper; -import com.oracle.graal.python.builtins.objects.cext.common.CExtAsPythonObjectNode; -import com.oracle.graal.python.builtins.objects.cext.common.CExtContext; -import com.oracle.graal.python.builtins.objects.cext.common.CExtToNativeNode; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ApiInitException; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ImportException; -import com.oracle.graal.python.builtins.objects.cext.common.NativePointer; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyBoxing; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.AllocateNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.BulkFreeHandleReferencesNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.FreeNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.GetElementPtrNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.IsNullNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadDoubleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadFloatNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadGenericNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyArrayNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyFieldNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadI32Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadI64Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadI8ArrayNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteDoubleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteGenericNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteHPyFieldNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteHPyNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteI32Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteI64Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WritePointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteSizeTNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCField; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.HPyABIVersion; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.HPyUpcall; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyContextFunction; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyHandle; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNativeContext; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNativeSymbol; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsCharPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyCallHelperFunctionNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyDummyToJavaNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyFromCharPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyTransformExceptionToNativeNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyAsContextNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyAsHandleNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyAsNativeInt64NodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyAsPythonObjectNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyTransformExceptionToNativeNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextMember; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyMode; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodes.HPyLLVMCallHelperFunctionNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMAsCharPointerNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMBulkFreeHandleReferencesNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMFreeNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMFromCharPointerNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMGetElementPtrNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMIsNullNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMReadDoubleNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMReadFloatNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMReadGenericNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMReadHPyArrayNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMReadHPyFieldNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMReadHPyNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMReadI32NodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMReadI64NodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMReadPointerNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMWriteDoubleNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMWriteGenericNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMWriteHPyFieldNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMWriteHPyNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMWriteI32NodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMWriteI64NodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMWritePointerNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMWriteSizeTNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.LLVMAllocateNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.LLVMReadI8ArrayNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.HPyArrayWrappers.HPyArrayWrapper; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.HPyArrayWrappers.IntArrayWrapper; -import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis; -import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.StringLiterals; -import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.runtime.PythonOptions.HPyBackendMode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.TruffleFile; -import com.oracle.truffle.api.TruffleLanguage.Env; -import com.oracle.truffle.api.TruffleLogger; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.ReportPolymorphism.Megamorphic; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.ArityException; -import com.oracle.truffle.api.interop.InteropException; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.interop.UnknownIdentifierException; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.interop.UnsupportedTypeException; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.library.ExportLibrary; -import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.api.nodes.ExplodeLoop; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.source.Source.SourceBuilder; -import com.oracle.truffle.api.strings.TruffleString; -import com.oracle.truffle.llvm.spi.NativeTypeLibrary; - -/** - * This object is used to override specific native upcall pointers in the HPyContext. This is - * queried for every member of HPyContext by {@code graal_hpy_context_to_native}, and overrides the - * original values (which are NFI closures for functions in {@code hpy.c}, subsequently calling into - * {@link GraalHPyContextFunctions}. - */ -@ExportLibrary(InteropLibrary.class) -@ExportLibrary(value = NativeTypeLibrary.class, useForAOT = false) -public final class GraalHPyLLVMContext extends GraalHPyNativeContext { - - private static final String J_NAME = "HPy Universal ABI (GraalVM LLVM backend)"; - private static final TruffleLogger LOGGER = GraalHPyContext.getLogger(GraalHPyLLVMContext.class); - - /** A resolving cache from Java string to HPyContextMember */ - public static HashMap contextMembersByName; - - private final int[] counts; - - /** the native type ID of C struct 'HPyContext' */ - @CompilationFinal Object hpyContextNativeTypeID; - - /** the native type ID of C struct 'HPy' */ - @CompilationFinal Object hpyNativeTypeID; - @CompilationFinal Object hpyArrayNativeTypeID; - @CompilationFinal Object setNativeSpaceFunction; - - @CompilationFinal(dimensions = 1) private final int[] ctypeSizes; - @CompilationFinal(dimensions = 1) private final int[] cfieldOffsets; - - @CompilationFinal(dimensions = 1) private final Object[] hpyContextMembers; - @CompilationFinal(dimensions = 1) private final Object[] nativeSymbolCache; - - Object nativePointer; - - public GraalHPyLLVMContext(GraalHPyContext context, boolean traceUpcalls) { - super(context, traceUpcalls); - Object[] ctxMembers = createMembers(tsLiteral(J_NAME)); - this.ctypeSizes = new int[HPyContextSignatureType.values().length]; - this.cfieldOffsets = new int[GraalHPyCField.values().length]; - if (traceUpcalls) { - this.counts = new int[HPyContextMember.VALUES.length]; - /* - * For upcall tracing, each executable member is wrapped into an HPyExecuteWrapper which - * does the tracing - */ - for (int i = 0; i < ctxMembers.length; i++) { - Object m = ctxMembers[i]; - if (m instanceof HPyExecuteWrapper executeWrapper) { - ctxMembers[i] = new HPyExecuteWrapperTraceUpcall(this.counts, i, executeWrapper); - } - } - } else { - this.counts = null; - } - // This will assign handles to the remaining context constants - for (Object member : ctxMembers) { - if (member instanceof GraalHPyHandle handle) { - int id = handle.getIdUncached(context); - assert id > 0 && id < GraalHPyContext.IMMUTABLE_HANDLE_COUNT; - assert id > GraalHPyBoxing.SINGLETON_HANDLE_MAX || - context.getHPyHandleForObject(handle.getDelegate()) == id; - } - } - this.hpyContextMembers = ctxMembers; - this.nativeSymbolCache = new Object[GraalHPyNativeSymbol.values().length]; - } - - void setHPyContextNativeType(Object nativeType) { - this.hpyContextNativeTypeID = nativeType; - } - - public Object getHPyNativeType() { - assert this.hpyNativeTypeID != null : "HPy native type ID not available"; - return hpyNativeTypeID; - } - - public Object getHPyArrayNativeType() { - assert this.hpyArrayNativeTypeID != null : "HPy* native type ID not available"; - return hpyArrayNativeTypeID; - } - - @Override - protected int getCTypeSize(HPyContextSignatureType ctype) { - assert ctypeSizes != null; - return ctypeSizes[ctype.ordinal()]; - } - - @Override - protected int getCFieldOffset(GraalHPyCField cfield) { - assert cfieldOffsets != null; - return cfieldOffsets[cfield.ordinal()]; - } - - @Override - protected Object nativeToInteropPointer(Object object) { - return object; - } - - Object[] getNativeSymbolCache() { - return nativeSymbolCache; - } - - @Override - protected Object getNativeNull() { - return NativePointer.createNull(); - } - - @Override - protected String getName() { - return J_NAME; - } - - /** - * Load {@code libhpy} with LLVM and return the library object. - */ - public static Object loadLLVMLibrary(PythonContext context) throws IOException { - CompilerAsserts.neverPartOfCompilation(); - Env env = context.getEnv(); - TruffleFile homePath = env.getInternalTruffleFile(context.getCAPIHome().toJavaStringUncached()); - // e.g. "libhpy-native.so" - TruffleFile capiFile = homePath.resolve(context.getLLVMSupportExt("hpy")); - try { - LOGGER.fine("Loading HPy LLVM backend from " + capiFile); - SourceBuilder capiSrcBuilder = Source.newBuilder(J_LLVM_LANGUAGE, capiFile); - if (!context.getLanguage().getEngineOption(PythonOptions.ExposeInternalSources)) { - capiSrcBuilder.internal(true); - } - return context.getEnv().parseInternal(capiSrcBuilder.build()).call(); - } catch (RuntimeException e) { - LOGGER.severe(String.format("Fatal error occurred when loading %s", capiFile)); - /* - * Just loading the library is not expected to throw any legitimate exceptions because - * it does not have any 'ctors' that could raise, e.g., a Python exception. So, any - * exception is considered to be fatal. - */ - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - @Override - protected Object loadExtensionLibrary(Node location, PythonContext context, TruffleString name, TruffleString path) throws ImportException, IOException { - CompilerAsserts.neverPartOfCompilation(); - return CExtContext.loadLLVMLibrary(location, context, name, path); - } - - @Override - protected HPyABIVersion getHPyABIVersion(Object extLib, String getMajorVersionFuncName, String getMinorVersionFuncName) throws InteropException { - CompilerAsserts.neverPartOfCompilation(); - InteropLibrary lib = InteropLibrary.getUncached(extLib); - Object majorVersionFun = lib.readMember(extLib, getMajorVersionFuncName); - Object minorVersionFun = lib.readMember(extLib, getMinorVersionFuncName); - InteropLibrary funLib = InteropLibrary.getUncached(majorVersionFun); - assert (funLib.accepts(minorVersionFun)); - int requiredMajorVersion = expectInt(funLib.execute(majorVersionFun)); - int requiredMinorVersion = expectInt(funLib.execute(minorVersionFun)); - return new HPyABIVersion(requiredMajorVersion, requiredMinorVersion); - } - - @Override - protected Object initHPyModule(Object llvmLibrary, String initFuncName, TruffleString name, TruffleString path, HPyMode mode) - throws UnsupportedMessageException, ArityException, UnsupportedTypeException, ImportException { - CompilerAsserts.neverPartOfCompilation(); - assert mode == HPyMode.MODE_UNIVERSAL; - Object initFunction; - InteropLibrary lib = InteropLibrary.getUncached(llvmLibrary); - if (lib.isMemberReadable(llvmLibrary, initFuncName)) { - try { - initFunction = lib.readMember(llvmLibrary, initFuncName); - } catch (UnknownIdentifierException | UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } else { - throw new ImportException(null, name, path, ErrorMessages.CANNOT_INITIALIZE_EXT_NO_ENTRY, name, path, initFuncName); - } - /* - * LLVM always answers message 'isExecutable' correctly. If the pointer object is not - * executable, this most certainly means that the loaded library does not contain bitcode, - * and so we fail. - */ - if (!InteropLibrary.getUncached().isExecutable(initFunction)) { - throw new ImportException(null, name, path, ErrorMessages.NO_FUNCTION_FOUND, "", initFuncName, path); - } - return InteropLibrary.getUncached().execute(initFunction, this); - } - - @Override - protected void initNativeContext() throws ApiInitException { - Object hpyLibrary = context.getLLVMLibrary(); - InteropLibrary interopLibrary = InteropLibrary.getFactory().getUncached(hpyLibrary); - try { - interopLibrary.invokeMember(hpyLibrary, "graal_hpy_init", context, new GraalHPyInitObject(this), new IntArrayWrapper(ctypeSizes), new IntArrayWrapper(cfieldOffsets)); - } catch (InteropException e) { - throw new ApiInitException(e); - } - assert nativeSymbolCache != null; - for (GraalHPyNativeSymbol symbol : GraalHPyNativeSymbol.values()) { - try { - String name = symbol.getName(); - Object nativeSymbol = interopLibrary.readMember(hpyLibrary, name); - assert nativeSymbolCache[symbol.ordinal()] == null; - nativeSymbolCache[symbol.ordinal()] = nativeSymbol; - } catch (UnknownIdentifierException e) { - throw new ApiInitException(ErrorMessages.INVALID_CAPI_FUNC, TruffleString.fromJavaStringUncached(symbol.getName(), TS_ENCODING)); - } catch (UnsupportedMessageException e) { - throw new ApiInitException(ErrorMessages.CORRUPTED_CAPI_LIB_OBJ, hpyLibrary); - } - } - } - - @Override - protected void initNativeFastPaths() { - throw CompilerDirectives.shouldNotReachHere(""); - } - - @Override - protected HPyUpcall[] getUpcalls() { - return HPyContextMember.VALUES; - } - - @Override - protected int[] getUpcallCounts() { - return counts; - } - - @Override - protected void finalizeNativeContext() { - - } - - @Override - public void initHPyDebugContext() throws ApiInitException { - // debug mode is currently not available with the LLVM backend - throw new ApiInitException(ErrorMessages.HPY_S_MODE_NOT_AVAILABLE, StringLiterals.J_DEBUG); - } - - @Override - public PythonModule getHPyDebugModule() throws ImportException { - // debug mode is currently not available with the LLVM backend - throw new ImportException(null, null, null, ErrorMessages.HPY_S_MODE_NOT_AVAILABLE, StringLiterals.J_DEBUG); - } - - @Override - public void initHPyTraceContext() throws ApiInitException { - // debug mode is currently not available with the LLVM backend - throw new ApiInitException(ErrorMessages.HPY_S_MODE_NOT_AVAILABLE, StringLiterals.J_TRACE); - } - - @Override - public PythonModule getHPyTraceModule() throws ImportException { - // trace mode is currently not available with the LLVM backend - throw new ImportException(null, null, null, ErrorMessages.HPY_S_MODE_NOT_AVAILABLE, StringLiterals.J_TRACE); - } - - @Override - protected void setNativeCache(long cachePtr) { - assert useNativeFastPaths(); - try { - InteropLibrary.getUncached().execute(setNativeSpaceFunction, nativePointer, cachePtr); - } catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @Override - public HPyCallHelperFunctionNode createCallHelperFunctionNode() { - return GraalHPyLLVMCallHelperFunctionNodeGen.create(); - } - - @Override - public HPyCallHelperFunctionNode getUncachedCallHelperFunctionNode() { - return GraalHPyLLVMCallHelperFunctionNodeGen.getUncached(); - } - - @Override - public HPyFromCharPointerNode createFromCharPointerNode() { - return HPyLLVMFromCharPointerNodeGen.create(); - } - - @Override - public HPyFromCharPointerNode getUncachedFromCharPointerNode() { - return HPyLLVMFromCharPointerNodeGen.getUncached(); - } - - @Override - public HPyAsCharPointerNode createAsCharPointerNode() { - return HPyLLVMAsCharPointerNodeGen.create(); - } - - @Override - public HPyAsCharPointerNode getUncachedAsCharPointerNode() { - return HPyLLVMAsCharPointerNodeGen.getUncached(); - } - - @Override - public AllocateNode createAllocateNode() { - return LLVMAllocateNodeGen.create(); - } - - @Override - public AllocateNode getUncachedAllocateNode() { - return LLVMAllocateNodeGen.getUncached(); - } - - @Override - public FreeNode createFreeNode() { - return HPyLLVMFreeNodeGen.create(); - } - - @Override - public FreeNode getUncachedFreeNode() { - return HPyLLVMFreeNodeGen.getUncached(); - } - - @Override - public BulkFreeHandleReferencesNode createBulkFreeHandleReferencesNode() { - return HPyLLVMBulkFreeHandleReferencesNodeGen.create(); - } - - @Override - public GetElementPtrNode createGetElementPtrNode() { - return HPyLLVMGetElementPtrNodeGen.create(); - } - - @Override - public GetElementPtrNode getUncachedGetElementPtrNode() { - return HPyLLVMGetElementPtrNodeGen.getUncached(); - } - - @Override - public IsNullNode createIsNullNode() { - return HPyLLVMIsNullNodeGen.create(); - } - - @Override - public IsNullNode getUncachedIsNullNode() { - return HPyLLVMIsNullNodeGen.getUncached(); - } - - @Override - public ReadI32Node createReadI32Node() { - return HPyLLVMReadI32NodeGen.create(); - } - - @Override - public ReadI32Node getUncachedReadI32Node() { - return HPyLLVMReadI32NodeGen.getUncached(); - } - - @Override - public ReadI64Node createReadI64Node() { - return HPyLLVMReadI64NodeGen.create(); - } - - @Override - public ReadI64Node getUncachedReadI64Node() { - return HPyLLVMReadI64NodeGen.getUncached(); - } - - @Override - public ReadFloatNode createReadFloatNode() { - return HPyLLVMReadFloatNodeGen.create(); - } - - @Override - public ReadFloatNode getUncachedReadFloatNode() { - return HPyLLVMReadFloatNodeGen.getUncached(); - } - - @Override - public ReadDoubleNode createReadDoubleNode() { - return HPyLLVMReadDoubleNodeGen.create(); - } - - @Override - public ReadDoubleNode getUncachedReadDoubleNode() { - return HPyLLVMReadDoubleNodeGen.getUncached(); - } - - @Override - public ReadPointerNode createReadPointerNode() { - return HPyLLVMReadPointerNodeGen.create(); - } - - @Override - public ReadPointerNode getUncachedReadPointerNode() { - return HPyLLVMReadPointerNodeGen.getUncached(); - } - - @Override - public WriteDoubleNode createWriteDoubleNode() { - return HPyLLVMWriteDoubleNodeGen.create(); - } - - @Override - public WriteDoubleNode getUncachedWriteDoubleNode() { - return HPyLLVMWriteDoubleNodeGen.getUncached(); - } - - @Override - public WriteI32Node createWriteI32Node() { - return HPyLLVMWriteI32NodeGen.create(); - } - - @Override - public WriteI32Node getUncachedWriteI32Node() { - return HPyLLVMWriteI32NodeGen.getUncached(); - } - - @Override - public WriteI64Node createWriteI64Node() { - return HPyLLVMWriteI64NodeGen.create(); - } - - @Override - public WriteI64Node getUncachedWriteI64Node() { - return HPyLLVMWriteI64NodeGen.getUncached(); - } - - @Override - public WriteHPyNode createWriteHPyNode() { - return HPyLLVMWriteHPyNodeGen.create(); - } - - @Override - public WriteHPyNode getUncachedWriteHPyNode() { - return HPyLLVMWriteHPyNodeGen.getUncached(); - } - - @Override - public ReadI8ArrayNode createReadI8ArrayNode() { - return LLVMReadI8ArrayNodeGen.create(); - } - - @Override - public ReadI8ArrayNode getUncachedReadI8ArrayNode() { - return LLVMReadI8ArrayNodeGen.getUncached(); - } - - @Override - public ReadHPyNode createReadHPyNode() { - return HPyLLVMReadHPyNodeGen.create(); - } - - @Override - public ReadHPyNode getUncachedReadHPyNode() { - return HPyLLVMReadHPyNodeGen.getUncached(); - } - - @Override - public ReadHPyFieldNode createReadHPyFieldNode() { - return HPyLLVMReadHPyFieldNodeGen.create(); - } - - @Override - public ReadHPyFieldNode getUncachedReadFieldHPyNode() { - return HPyLLVMReadHPyFieldNodeGen.getUncached(); - } - - @Override - public ReadGenericNode createReadGenericNode() { - return HPyLLVMReadGenericNodeGen.create(); - } - - @Override - public ReadGenericNode getUncachedReadGenericNode() { - return HPyLLVMReadGenericNodeGen.getUncached(); - } - - @Override - public ReadHPyArrayNode createReadHPyArrayNode() { - return HPyLLVMReadHPyArrayNodeGen.create(); - } - - @Override - public ReadHPyArrayNode getUncachedReadHPyArrayNode() { - return HPyLLVMReadHPyArrayNodeGen.getUncached(); - } - - @Override - public WritePointerNode createWritePointerNode() { - return HPyLLVMWritePointerNodeGen.create(); - } - - @Override - public WritePointerNode getUncachedWritePointerNode() { - return HPyLLVMWritePointerNodeGen.getUncached(); - } - - @Override - public WriteSizeTNode createWriteSizeTNode() { - return HPyLLVMWriteSizeTNodeGen.create(); - } - - @Override - public WriteSizeTNode getUncachedWriteSizeTNode() { - return HPyLLVMWriteSizeTNodeGen.getUncached(); - } - - @Override - public WriteGenericNode createWriteGenericNode() { - return HPyLLVMWriteGenericNodeGen.create(); - } - - @Override - public WriteGenericNode getUncachedWriteGenericNode() { - return HPyLLVMWriteGenericNodeGen.getUncached(); - } - - @Override - public WriteHPyFieldNode createWriteHPyFieldNode() { - return HPyLLVMWriteHPyFieldNodeGen.create(); - } - - @Override - public WriteHPyFieldNode getUncachedWriteHPyFieldNode() { - return HPyLLVMWriteHPyFieldNodeGen.getUncached(); - } - - @ExportMessage - boolean isPointer() { - return nativePointer != null; - } - - @ExportMessage(limit = "1") - long asPointer(@CachedLibrary("this.nativePointer") InteropLibrary lib) throws UnsupportedMessageException { - if (isPointer()) { - return lib.asPointer(nativePointer); - } - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw UnsupportedMessageException.create(); - } - - /** - * Internal method for transforming the HPy universal context to native. This is mostly like the - * interop message {@code toNative} but may of course fail if native access is not allowed. This - * method can be used to force the context to native if a native pointer is needed that will be - * handed to a native (e.g. JNI or NFI) function. - */ - @Override - protected void toNativeInternal() { - CompilerDirectives.transferToInterpreter(); - assert !isPointer(); - assert PythonLanguage.get(null).getEngineOption(PythonOptions.HPyBackend) == HPyBackendMode.LLVM; - nativePointer = HPyLLVMCallHelperFunctionNode.callUncached(context, GRAAL_HPY_CONTEXT_TO_NATIVE, this); - } - - @Override - protected Object createArgumentsArray(Object[] args) { - return new HPyArrayWrapper(context, args); - } - - @Override - protected void freeArgumentsArray(Object argsArray) { - if (argsArray instanceof HPyArrayWrapper hpyArrayWrapper) { - hpyArrayWrapper.close(); - } - } - - private static int expectInt(Object value) { - if (value instanceof Integer i) { - return i; - } - InteropLibrary lib = InteropLibrary.getUncached(value); - if (lib.fitsInInt(value)) { - try { - return lib.asInt(value); - } catch (UnsupportedMessageException e) { - // fall through - } - } - throw CompilerDirectives.shouldNotReachHere(); - } - - private static Object createConstant(Object value) { - return GraalHPyHandle.create(value); - } - - private Object createBuiltinsConstant() { - return createConstant(GetOrCreateDictNode.executeUncached(context.getContext().getBuiltins())); - } - - private static Object createSingletonConstant(Object value, int handle) { - return GraalHPyHandle.createSingleton(value, handle); - } - - private Object createTypeConstant(PythonBuiltinClassType value) { - return GraalHPyHandle.create(context.getContext().lookupType(value)); - } - - private static HPyExecuteWrapper createContextFunction(HPyContextMember member) { - return new HPyExecuteWrapper(member); - } - - private Object[] createMembers(TruffleString name) { - Object[] members = new Object[HPyContextMember.VALUES.length]; - - members[HPyContextMember.NAME.ordinal()] = new CStringWrapper(name.switchEncodingUncached(TruffleString.Encoding.UTF_8), TruffleString.Encoding.UTF_8); - // TODO(fa): we should use the value of macro HPY_ABI_VERSION here - members[HPyContextMember.ABI_VERSION.ordinal()] = 0; - - // {{start llvm ctx init}} - // @formatter:off - // Checkstyle: stop - // DO NOT EDIT THIS PART! - // This part is automatically generated by hpy.tools.autogen.graalpy.autogen_ctx_llvm_init - members[HPyContextMember.H_NONE.ordinal()] = createSingletonConstant(PNone.NONE, SINGLETON_HANDLE_NONE); - members[HPyContextMember.H_TRUE.ordinal()] = createConstant(context.getContext().getTrue()); - members[HPyContextMember.H_FALSE.ordinal()] = createConstant(context.getContext().getFalse()); - members[HPyContextMember.H_NOTIMPLEMENTED.ordinal()] = createSingletonConstant(PNotImplemented.NOT_IMPLEMENTED, SINGLETON_HANDLE_NOT_IMPLEMENTED); - members[HPyContextMember.H_ELLIPSIS.ordinal()] = createSingletonConstant(PEllipsis.INSTANCE, SINGLETON_HANDLE_ELIPSIS); - members[HPyContextMember.H_BASEEXCEPTION.ordinal()] = createTypeConstant(PythonBuiltinClassType.PBaseException); - members[HPyContextMember.H_EXCEPTION.ordinal()] = createTypeConstant(PythonBuiltinClassType.Exception); - members[HPyContextMember.H_STOPASYNCITERATION.ordinal()] = createTypeConstant(PythonBuiltinClassType.StopAsyncIteration); - members[HPyContextMember.H_STOPITERATION.ordinal()] = createTypeConstant(PythonBuiltinClassType.StopIteration); - members[HPyContextMember.H_GENERATOREXIT.ordinal()] = createTypeConstant(PythonBuiltinClassType.GeneratorExit); - members[HPyContextMember.H_ARITHMETICERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.ArithmeticError); - members[HPyContextMember.H_LOOKUPERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.LookupError); - members[HPyContextMember.H_ASSERTIONERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.AssertionError); - members[HPyContextMember.H_ATTRIBUTEERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.AttributeError); - members[HPyContextMember.H_BUFFERERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.BufferError); - members[HPyContextMember.H_EOFERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.EOFError); - members[HPyContextMember.H_FLOATINGPOINTERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.FloatingPointError); - members[HPyContextMember.H_OSERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.OSError); - members[HPyContextMember.H_IMPORTERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.ImportError); - members[HPyContextMember.H_MODULENOTFOUNDERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.ModuleNotFoundError); - members[HPyContextMember.H_INDEXERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.IndexError); - members[HPyContextMember.H_KEYERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.KeyError); - members[HPyContextMember.H_KEYBOARDINTERRUPT.ordinal()] = createTypeConstant(PythonBuiltinClassType.KeyboardInterrupt); - members[HPyContextMember.H_MEMORYERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.MemoryError); - members[HPyContextMember.H_NAMEERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.NameError); - members[HPyContextMember.H_OVERFLOWERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.OverflowError); - members[HPyContextMember.H_RUNTIMEERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.RuntimeError); - members[HPyContextMember.H_RECURSIONERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.RecursionError); - members[HPyContextMember.H_NOTIMPLEMENTEDERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.NotImplementedError); - members[HPyContextMember.H_SYNTAXERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.SyntaxError); - members[HPyContextMember.H_INDENTATIONERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.IndentationError); - members[HPyContextMember.H_TABERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.TabError); - members[HPyContextMember.H_REFERENCEERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.ReferenceError); - members[HPyContextMember.H_SYSTEMERROR.ordinal()] = createTypeConstant(SystemError); - members[HPyContextMember.H_SYSTEMEXIT.ordinal()] = createTypeConstant(PythonBuiltinClassType.SystemExit); - members[HPyContextMember.H_TYPEERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.TypeError); - members[HPyContextMember.H_UNBOUNDLOCALERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.UnboundLocalError); - members[HPyContextMember.H_UNICODEERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.UnicodeError); - members[HPyContextMember.H_UNICODEENCODEERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.UnicodeEncodeError); - members[HPyContextMember.H_UNICODEDECODEERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.UnicodeDecodeError); - members[HPyContextMember.H_UNICODETRANSLATEERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.UnicodeTranslateError); - members[HPyContextMember.H_VALUEERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.ValueError); - members[HPyContextMember.H_ZERODIVISIONERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.ZeroDivisionError); - members[HPyContextMember.H_BLOCKINGIOERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.BlockingIOError); - members[HPyContextMember.H_BROKENPIPEERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.BrokenPipeError); - members[HPyContextMember.H_CHILDPROCESSERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.ChildProcessError); - members[HPyContextMember.H_CONNECTIONERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.ConnectionError); - members[HPyContextMember.H_CONNECTIONABORTEDERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.ConnectionAbortedError); - members[HPyContextMember.H_CONNECTIONREFUSEDERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.ConnectionRefusedError); - members[HPyContextMember.H_CONNECTIONRESETERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.ConnectionResetError); - members[HPyContextMember.H_FILEEXISTSERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.FileExistsError); - members[HPyContextMember.H_FILENOTFOUNDERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.FileNotFoundError); - members[HPyContextMember.H_INTERRUPTEDERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.InterruptedError); - members[HPyContextMember.H_ISADIRECTORYERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.IsADirectoryError); - members[HPyContextMember.H_NOTADIRECTORYERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.NotADirectoryError); - members[HPyContextMember.H_PERMISSIONERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.PermissionError); - members[HPyContextMember.H_PROCESSLOOKUPERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.ProcessLookupError); - members[HPyContextMember.H_TIMEOUTERROR.ordinal()] = createTypeConstant(PythonBuiltinClassType.TimeoutError); - members[HPyContextMember.H_WARNING.ordinal()] = createTypeConstant(PythonBuiltinClassType.Warning); - members[HPyContextMember.H_USERWARNING.ordinal()] = createTypeConstant(PythonBuiltinClassType.UserWarning); - members[HPyContextMember.H_DEPRECATIONWARNING.ordinal()] = createTypeConstant(PythonBuiltinClassType.DeprecationWarning); - members[HPyContextMember.H_PENDINGDEPRECATIONWARNING.ordinal()] = createTypeConstant(PythonBuiltinClassType.PendingDeprecationWarning); - members[HPyContextMember.H_SYNTAXWARNING.ordinal()] = createTypeConstant(PythonBuiltinClassType.SyntaxWarning); - members[HPyContextMember.H_RUNTIMEWARNING.ordinal()] = createTypeConstant(PythonBuiltinClassType.RuntimeWarning); - members[HPyContextMember.H_FUTUREWARNING.ordinal()] = createTypeConstant(PythonBuiltinClassType.FutureWarning); - members[HPyContextMember.H_IMPORTWARNING.ordinal()] = createTypeConstant(PythonBuiltinClassType.ImportWarning); - members[HPyContextMember.H_UNICODEWARNING.ordinal()] = createTypeConstant(PythonBuiltinClassType.UnicodeWarning); - members[HPyContextMember.H_BYTESWARNING.ordinal()] = createTypeConstant(PythonBuiltinClassType.BytesWarning); - members[HPyContextMember.H_RESOURCEWARNING.ordinal()] = createTypeConstant(PythonBuiltinClassType.ResourceWarning); - members[HPyContextMember.H_BASEOBJECTTYPE.ordinal()] = createTypeConstant(PythonBuiltinClassType.PythonObject); - members[HPyContextMember.H_TYPETYPE.ordinal()] = createTypeConstant(PythonBuiltinClassType.PythonClass); - members[HPyContextMember.H_BOOLTYPE.ordinal()] = createTypeConstant(PythonBuiltinClassType.Boolean); - members[HPyContextMember.H_LONGTYPE.ordinal()] = createTypeConstant(PythonBuiltinClassType.PInt); - members[HPyContextMember.H_FLOATTYPE.ordinal()] = createTypeConstant(PythonBuiltinClassType.PFloat); - members[HPyContextMember.H_UNICODETYPE.ordinal()] = createTypeConstant(PythonBuiltinClassType.PString); - members[HPyContextMember.H_TUPLETYPE.ordinal()] = createTypeConstant(PythonBuiltinClassType.PTuple); - members[HPyContextMember.H_LISTTYPE.ordinal()] = createTypeConstant(PythonBuiltinClassType.PList); - members[HPyContextMember.H_COMPLEXTYPE.ordinal()] = createTypeConstant(PythonBuiltinClassType.PComplex); - members[HPyContextMember.H_BYTESTYPE.ordinal()] = createTypeConstant(PythonBuiltinClassType.PBytes); - members[HPyContextMember.H_MEMORYVIEWTYPE.ordinal()] = createTypeConstant(PythonBuiltinClassType.PMemoryView); - members[HPyContextMember.H_CAPSULETYPE.ordinal()] = createTypeConstant(PythonBuiltinClassType.Capsule); - members[HPyContextMember.H_SLICETYPE.ordinal()] = createTypeConstant(PythonBuiltinClassType.PSlice); - members[HPyContextMember.H_BUILTINS.ordinal()] = createBuiltinsConstant(); - - members[HPyContextMember.CTX_DUP.ordinal()] = createContextFunction(HPyContextMember.CTX_DUP); - members[HPyContextMember.CTX_CLOSE.ordinal()] = createContextFunction(HPyContextMember.CTX_CLOSE); - members[HPyContextMember.CTX_LONG_FROMINT32_T.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_FROMINT32_T); - members[HPyContextMember.CTX_LONG_FROMUINT32_T.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_FROMUINT32_T); - members[HPyContextMember.CTX_LONG_FROMINT64_T.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_FROMINT64_T); - members[HPyContextMember.CTX_LONG_FROMUINT64_T.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_FROMUINT64_T); - members[HPyContextMember.CTX_LONG_FROMSIZE_T.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_FROMSIZE_T); - members[HPyContextMember.CTX_LONG_FROMSSIZE_T.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_FROMSSIZE_T); - members[HPyContextMember.CTX_LONG_ASINT32_T.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_ASINT32_T); - members[HPyContextMember.CTX_LONG_ASUINT32_T.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_ASUINT32_T); - members[HPyContextMember.CTX_LONG_ASUINT32_TMASK.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_ASUINT32_TMASK); - members[HPyContextMember.CTX_LONG_ASINT64_T.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_ASINT64_T); - members[HPyContextMember.CTX_LONG_ASUINT64_T.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_ASUINT64_T); - members[HPyContextMember.CTX_LONG_ASUINT64_TMASK.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_ASUINT64_TMASK); - members[HPyContextMember.CTX_LONG_ASSIZE_T.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_ASSIZE_T); - members[HPyContextMember.CTX_LONG_ASSSIZE_T.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_ASSSIZE_T); - members[HPyContextMember.CTX_LONG_ASVOIDPTR.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_ASVOIDPTR); - members[HPyContextMember.CTX_LONG_ASDOUBLE.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG_ASDOUBLE); - members[HPyContextMember.CTX_FLOAT_FROMDOUBLE.ordinal()] = createContextFunction(HPyContextMember.CTX_FLOAT_FROMDOUBLE); - members[HPyContextMember.CTX_FLOAT_ASDOUBLE.ordinal()] = createContextFunction(HPyContextMember.CTX_FLOAT_ASDOUBLE); - members[HPyContextMember.CTX_BOOL_FROMBOOL.ordinal()] = createContextFunction(HPyContextMember.CTX_BOOL_FROMBOOL); - members[HPyContextMember.CTX_LENGTH.ordinal()] = createContextFunction(HPyContextMember.CTX_LENGTH); - members[HPyContextMember.CTX_NUMBER_CHECK.ordinal()] = createContextFunction(HPyContextMember.CTX_NUMBER_CHECK); - members[HPyContextMember.CTX_ADD.ordinal()] = createContextFunction(HPyContextMember.CTX_ADD); - members[HPyContextMember.CTX_SUBTRACT.ordinal()] = createContextFunction(HPyContextMember.CTX_SUBTRACT); - members[HPyContextMember.CTX_MULTIPLY.ordinal()] = createContextFunction(HPyContextMember.CTX_MULTIPLY); - members[HPyContextMember.CTX_MATRIXMULTIPLY.ordinal()] = createContextFunction(HPyContextMember.CTX_MATRIXMULTIPLY); - members[HPyContextMember.CTX_FLOORDIVIDE.ordinal()] = createContextFunction(HPyContextMember.CTX_FLOORDIVIDE); - members[HPyContextMember.CTX_TRUEDIVIDE.ordinal()] = createContextFunction(HPyContextMember.CTX_TRUEDIVIDE); - members[HPyContextMember.CTX_REMAINDER.ordinal()] = createContextFunction(HPyContextMember.CTX_REMAINDER); - members[HPyContextMember.CTX_DIVMOD.ordinal()] = createContextFunction(HPyContextMember.CTX_DIVMOD); - members[HPyContextMember.CTX_POWER.ordinal()] = createContextFunction(HPyContextMember.CTX_POWER); - members[HPyContextMember.CTX_NEGATIVE.ordinal()] = createContextFunction(HPyContextMember.CTX_NEGATIVE); - members[HPyContextMember.CTX_POSITIVE.ordinal()] = createContextFunction(HPyContextMember.CTX_POSITIVE); - members[HPyContextMember.CTX_ABSOLUTE.ordinal()] = createContextFunction(HPyContextMember.CTX_ABSOLUTE); - members[HPyContextMember.CTX_INVERT.ordinal()] = createContextFunction(HPyContextMember.CTX_INVERT); - members[HPyContextMember.CTX_LSHIFT.ordinal()] = createContextFunction(HPyContextMember.CTX_LSHIFT); - members[HPyContextMember.CTX_RSHIFT.ordinal()] = createContextFunction(HPyContextMember.CTX_RSHIFT); - members[HPyContextMember.CTX_AND.ordinal()] = createContextFunction(HPyContextMember.CTX_AND); - members[HPyContextMember.CTX_XOR.ordinal()] = createContextFunction(HPyContextMember.CTX_XOR); - members[HPyContextMember.CTX_OR.ordinal()] = createContextFunction(HPyContextMember.CTX_OR); - members[HPyContextMember.CTX_INDEX.ordinal()] = createContextFunction(HPyContextMember.CTX_INDEX); - members[HPyContextMember.CTX_LONG.ordinal()] = createContextFunction(HPyContextMember.CTX_LONG); - members[HPyContextMember.CTX_FLOAT.ordinal()] = createContextFunction(HPyContextMember.CTX_FLOAT); - members[HPyContextMember.CTX_INPLACEADD.ordinal()] = createContextFunction(HPyContextMember.CTX_INPLACEADD); - members[HPyContextMember.CTX_INPLACESUBTRACT.ordinal()] = createContextFunction(HPyContextMember.CTX_INPLACESUBTRACT); - members[HPyContextMember.CTX_INPLACEMULTIPLY.ordinal()] = createContextFunction(HPyContextMember.CTX_INPLACEMULTIPLY); - members[HPyContextMember.CTX_INPLACEMATRIXMULTIPLY.ordinal()] = createContextFunction(HPyContextMember.CTX_INPLACEMATRIXMULTIPLY); - members[HPyContextMember.CTX_INPLACEFLOORDIVIDE.ordinal()] = createContextFunction(HPyContextMember.CTX_INPLACEFLOORDIVIDE); - members[HPyContextMember.CTX_INPLACETRUEDIVIDE.ordinal()] = createContextFunction(HPyContextMember.CTX_INPLACETRUEDIVIDE); - members[HPyContextMember.CTX_INPLACEREMAINDER.ordinal()] = createContextFunction(HPyContextMember.CTX_INPLACEREMAINDER); - members[HPyContextMember.CTX_INPLACEPOWER.ordinal()] = createContextFunction(HPyContextMember.CTX_INPLACEPOWER); - members[HPyContextMember.CTX_INPLACELSHIFT.ordinal()] = createContextFunction(HPyContextMember.CTX_INPLACELSHIFT); - members[HPyContextMember.CTX_INPLACERSHIFT.ordinal()] = createContextFunction(HPyContextMember.CTX_INPLACERSHIFT); - members[HPyContextMember.CTX_INPLACEAND.ordinal()] = createContextFunction(HPyContextMember.CTX_INPLACEAND); - members[HPyContextMember.CTX_INPLACEXOR.ordinal()] = createContextFunction(HPyContextMember.CTX_INPLACEXOR); - members[HPyContextMember.CTX_INPLACEOR.ordinal()] = createContextFunction(HPyContextMember.CTX_INPLACEOR); - members[HPyContextMember.CTX_CALLABLE_CHECK.ordinal()] = createContextFunction(HPyContextMember.CTX_CALLABLE_CHECK); - members[HPyContextMember.CTX_CALLTUPLEDICT.ordinal()] = createContextFunction(HPyContextMember.CTX_CALLTUPLEDICT); - members[HPyContextMember.CTX_CALL.ordinal()] = createContextFunction(HPyContextMember.CTX_CALL); - members[HPyContextMember.CTX_CALLMETHOD.ordinal()] = createContextFunction(HPyContextMember.CTX_CALLMETHOD); - members[HPyContextMember.CTX_FATALERROR.ordinal()] = createContextFunction(HPyContextMember.CTX_FATALERROR); - members[HPyContextMember.CTX_ERR_SETSTRING.ordinal()] = createContextFunction(HPyContextMember.CTX_ERR_SETSTRING); - members[HPyContextMember.CTX_ERR_SETOBJECT.ordinal()] = createContextFunction(HPyContextMember.CTX_ERR_SETOBJECT); - members[HPyContextMember.CTX_ERR_SETFROMERRNOWITHFILENAME.ordinal()] = createContextFunction(HPyContextMember.CTX_ERR_SETFROMERRNOWITHFILENAME); - members[HPyContextMember.CTX_ERR_SETFROMERRNOWITHFILENAMEOBJECTS.ordinal()] = createContextFunction(HPyContextMember.CTX_ERR_SETFROMERRNOWITHFILENAMEOBJECTS); - members[HPyContextMember.CTX_ERR_OCCURRED.ordinal()] = createContextFunction(HPyContextMember.CTX_ERR_OCCURRED); - members[HPyContextMember.CTX_ERR_EXCEPTIONMATCHES.ordinal()] = createContextFunction(HPyContextMember.CTX_ERR_EXCEPTIONMATCHES); - members[HPyContextMember.CTX_ERR_NOMEMORY.ordinal()] = createContextFunction(HPyContextMember.CTX_ERR_NOMEMORY); - members[HPyContextMember.CTX_ERR_CLEAR.ordinal()] = createContextFunction(HPyContextMember.CTX_ERR_CLEAR); - members[HPyContextMember.CTX_ERR_NEWEXCEPTION.ordinal()] = createContextFunction(HPyContextMember.CTX_ERR_NEWEXCEPTION); - members[HPyContextMember.CTX_ERR_NEWEXCEPTIONWITHDOC.ordinal()] = createContextFunction(HPyContextMember.CTX_ERR_NEWEXCEPTIONWITHDOC); - members[HPyContextMember.CTX_ERR_WARNEX.ordinal()] = createContextFunction(HPyContextMember.CTX_ERR_WARNEX); - members[HPyContextMember.CTX_ERR_WRITEUNRAISABLE.ordinal()] = createContextFunction(HPyContextMember.CTX_ERR_WRITEUNRAISABLE); - members[HPyContextMember.CTX_ISTRUE.ordinal()] = createContextFunction(HPyContextMember.CTX_ISTRUE); - members[HPyContextMember.CTX_TYPE_FROMSPEC.ordinal()] = createContextFunction(HPyContextMember.CTX_TYPE_FROMSPEC); - members[HPyContextMember.CTX_TYPE_GENERICNEW.ordinal()] = createContextFunction(HPyContextMember.CTX_TYPE_GENERICNEW); - members[HPyContextMember.CTX_GETATTR.ordinal()] = createContextFunction(HPyContextMember.CTX_GETATTR); - members[HPyContextMember.CTX_GETATTR_S.ordinal()] = createContextFunction(HPyContextMember.CTX_GETATTR_S); - members[HPyContextMember.CTX_HASATTR.ordinal()] = createContextFunction(HPyContextMember.CTX_HASATTR); - members[HPyContextMember.CTX_HASATTR_S.ordinal()] = createContextFunction(HPyContextMember.CTX_HASATTR_S); - members[HPyContextMember.CTX_SETATTR.ordinal()] = createContextFunction(HPyContextMember.CTX_SETATTR); - members[HPyContextMember.CTX_SETATTR_S.ordinal()] = createContextFunction(HPyContextMember.CTX_SETATTR_S); - members[HPyContextMember.CTX_GETITEM.ordinal()] = createContextFunction(HPyContextMember.CTX_GETITEM); - members[HPyContextMember.CTX_GETITEM_I.ordinal()] = createContextFunction(HPyContextMember.CTX_GETITEM_I); - members[HPyContextMember.CTX_GETITEM_S.ordinal()] = createContextFunction(HPyContextMember.CTX_GETITEM_S); - members[HPyContextMember.CTX_CONTAINS.ordinal()] = createContextFunction(HPyContextMember.CTX_CONTAINS); - members[HPyContextMember.CTX_SETITEM.ordinal()] = createContextFunction(HPyContextMember.CTX_SETITEM); - members[HPyContextMember.CTX_SETITEM_I.ordinal()] = createContextFunction(HPyContextMember.CTX_SETITEM_I); - members[HPyContextMember.CTX_SETITEM_S.ordinal()] = createContextFunction(HPyContextMember.CTX_SETITEM_S); - members[HPyContextMember.CTX_DELITEM.ordinal()] = createContextFunction(HPyContextMember.CTX_DELITEM); - members[HPyContextMember.CTX_DELITEM_I.ordinal()] = createContextFunction(HPyContextMember.CTX_DELITEM_I); - members[HPyContextMember.CTX_DELITEM_S.ordinal()] = createContextFunction(HPyContextMember.CTX_DELITEM_S); - members[HPyContextMember.CTX_TYPE.ordinal()] = createContextFunction(HPyContextMember.CTX_TYPE); - members[HPyContextMember.CTX_TYPECHECK.ordinal()] = createContextFunction(HPyContextMember.CTX_TYPECHECK); - members[HPyContextMember.CTX_TYPE_GETNAME.ordinal()] = createContextFunction(HPyContextMember.CTX_TYPE_GETNAME); - members[HPyContextMember.CTX_TYPE_ISSUBTYPE.ordinal()] = createContextFunction(HPyContextMember.CTX_TYPE_ISSUBTYPE); - members[HPyContextMember.CTX_IS.ordinal()] = createContextFunction(HPyContextMember.CTX_IS); - members[HPyContextMember.CTX_ASSTRUCT_OBJECT.ordinal()] = createContextFunction(HPyContextMember.CTX_ASSTRUCT_OBJECT); - members[HPyContextMember.CTX_ASSTRUCT_LEGACY.ordinal()] = createContextFunction(HPyContextMember.CTX_ASSTRUCT_LEGACY); - members[HPyContextMember.CTX_ASSTRUCT_TYPE.ordinal()] = createContextFunction(HPyContextMember.CTX_ASSTRUCT_TYPE); - members[HPyContextMember.CTX_ASSTRUCT_LONG.ordinal()] = createContextFunction(HPyContextMember.CTX_ASSTRUCT_LONG); - members[HPyContextMember.CTX_ASSTRUCT_FLOAT.ordinal()] = createContextFunction(HPyContextMember.CTX_ASSTRUCT_FLOAT); - members[HPyContextMember.CTX_ASSTRUCT_UNICODE.ordinal()] = createContextFunction(HPyContextMember.CTX_ASSTRUCT_UNICODE); - members[HPyContextMember.CTX_ASSTRUCT_TUPLE.ordinal()] = createContextFunction(HPyContextMember.CTX_ASSTRUCT_TUPLE); - members[HPyContextMember.CTX_ASSTRUCT_LIST.ordinal()] = createContextFunction(HPyContextMember.CTX_ASSTRUCT_LIST); - members[HPyContextMember.CTX_TYPE_GETBUILTINSHAPE.ordinal()] = createContextFunction(HPyContextMember.CTX_TYPE_GETBUILTINSHAPE); - members[HPyContextMember.CTX_NEW.ordinal()] = createContextFunction(HPyContextMember.CTX_NEW); - members[HPyContextMember.CTX_REPR.ordinal()] = createContextFunction(HPyContextMember.CTX_REPR); - members[HPyContextMember.CTX_STR.ordinal()] = createContextFunction(HPyContextMember.CTX_STR); - members[HPyContextMember.CTX_ASCII.ordinal()] = createContextFunction(HPyContextMember.CTX_ASCII); - members[HPyContextMember.CTX_BYTES.ordinal()] = createContextFunction(HPyContextMember.CTX_BYTES); - members[HPyContextMember.CTX_RICHCOMPARE.ordinal()] = createContextFunction(HPyContextMember.CTX_RICHCOMPARE); - members[HPyContextMember.CTX_RICHCOMPAREBOOL.ordinal()] = createContextFunction(HPyContextMember.CTX_RICHCOMPAREBOOL); - members[HPyContextMember.CTX_HASH.ordinal()] = createContextFunction(HPyContextMember.CTX_HASH); - members[HPyContextMember.CTX_BYTES_CHECK.ordinal()] = createContextFunction(HPyContextMember.CTX_BYTES_CHECK); - members[HPyContextMember.CTX_BYTES_SIZE.ordinal()] = createContextFunction(HPyContextMember.CTX_BYTES_SIZE); - members[HPyContextMember.CTX_BYTES_GET_SIZE.ordinal()] = createContextFunction(HPyContextMember.CTX_BYTES_GET_SIZE); - members[HPyContextMember.CTX_BYTES_ASSTRING.ordinal()] = createContextFunction(HPyContextMember.CTX_BYTES_ASSTRING); - members[HPyContextMember.CTX_BYTES_AS_STRING.ordinal()] = createContextFunction(HPyContextMember.CTX_BYTES_AS_STRING); - members[HPyContextMember.CTX_BYTES_FROMSTRING.ordinal()] = createContextFunction(HPyContextMember.CTX_BYTES_FROMSTRING); - members[HPyContextMember.CTX_BYTES_FROMSTRINGANDSIZE.ordinal()] = createContextFunction(HPyContextMember.CTX_BYTES_FROMSTRINGANDSIZE); - members[HPyContextMember.CTX_UNICODE_FROMSTRING.ordinal()] = createContextFunction(HPyContextMember.CTX_UNICODE_FROMSTRING); - members[HPyContextMember.CTX_UNICODE_CHECK.ordinal()] = createContextFunction(HPyContextMember.CTX_UNICODE_CHECK); - members[HPyContextMember.CTX_UNICODE_ASASCIISTRING.ordinal()] = createContextFunction(HPyContextMember.CTX_UNICODE_ASASCIISTRING); - members[HPyContextMember.CTX_UNICODE_ASLATIN1STRING.ordinal()] = createContextFunction(HPyContextMember.CTX_UNICODE_ASLATIN1STRING); - members[HPyContextMember.CTX_UNICODE_ASUTF8STRING.ordinal()] = createContextFunction(HPyContextMember.CTX_UNICODE_ASUTF8STRING); - members[HPyContextMember.CTX_UNICODE_ASUTF8ANDSIZE.ordinal()] = createContextFunction(HPyContextMember.CTX_UNICODE_ASUTF8ANDSIZE); - members[HPyContextMember.CTX_UNICODE_FROMWIDECHAR.ordinal()] = createContextFunction(HPyContextMember.CTX_UNICODE_FROMWIDECHAR); - members[HPyContextMember.CTX_UNICODE_DECODEFSDEFAULT.ordinal()] = createContextFunction(HPyContextMember.CTX_UNICODE_DECODEFSDEFAULT); - members[HPyContextMember.CTX_UNICODE_DECODEFSDEFAULTANDSIZE.ordinal()] = createContextFunction(HPyContextMember.CTX_UNICODE_DECODEFSDEFAULTANDSIZE); - members[HPyContextMember.CTX_UNICODE_ENCODEFSDEFAULT.ordinal()] = createContextFunction(HPyContextMember.CTX_UNICODE_ENCODEFSDEFAULT); - members[HPyContextMember.CTX_UNICODE_READCHAR.ordinal()] = createContextFunction(HPyContextMember.CTX_UNICODE_READCHAR); - members[HPyContextMember.CTX_UNICODE_DECODEASCII.ordinal()] = createContextFunction(HPyContextMember.CTX_UNICODE_DECODEASCII); - members[HPyContextMember.CTX_UNICODE_DECODELATIN1.ordinal()] = createContextFunction(HPyContextMember.CTX_UNICODE_DECODELATIN1); - members[HPyContextMember.CTX_UNICODE_FROMENCODEDOBJECT.ordinal()] = createContextFunction(HPyContextMember.CTX_UNICODE_FROMENCODEDOBJECT); - members[HPyContextMember.CTX_UNICODE_SUBSTRING.ordinal()] = createContextFunction(HPyContextMember.CTX_UNICODE_SUBSTRING); - members[HPyContextMember.CTX_LIST_CHECK.ordinal()] = createContextFunction(HPyContextMember.CTX_LIST_CHECK); - members[HPyContextMember.CTX_LIST_NEW.ordinal()] = createContextFunction(HPyContextMember.CTX_LIST_NEW); - members[HPyContextMember.CTX_LIST_APPEND.ordinal()] = createContextFunction(HPyContextMember.CTX_LIST_APPEND); - members[HPyContextMember.CTX_DICT_CHECK.ordinal()] = createContextFunction(HPyContextMember.CTX_DICT_CHECK); - members[HPyContextMember.CTX_DICT_NEW.ordinal()] = createContextFunction(HPyContextMember.CTX_DICT_NEW); - members[HPyContextMember.CTX_DICT_KEYS.ordinal()] = createContextFunction(HPyContextMember.CTX_DICT_KEYS); - members[HPyContextMember.CTX_DICT_COPY.ordinal()] = createContextFunction(HPyContextMember.CTX_DICT_COPY); - members[HPyContextMember.CTX_TUPLE_CHECK.ordinal()] = createContextFunction(HPyContextMember.CTX_TUPLE_CHECK); - members[HPyContextMember.CTX_TUPLE_FROMARRAY.ordinal()] = createContextFunction(HPyContextMember.CTX_TUPLE_FROMARRAY); - members[HPyContextMember.CTX_SLICE_UNPACK.ordinal()] = createContextFunction(HPyContextMember.CTX_SLICE_UNPACK); - members[HPyContextMember.CTX_IMPORT_IMPORTMODULE.ordinal()] = createContextFunction(HPyContextMember.CTX_IMPORT_IMPORTMODULE); - members[HPyContextMember.CTX_CAPSULE_NEW.ordinal()] = createContextFunction(HPyContextMember.CTX_CAPSULE_NEW); - members[HPyContextMember.CTX_CAPSULE_GET.ordinal()] = createContextFunction(HPyContextMember.CTX_CAPSULE_GET); - members[HPyContextMember.CTX_CAPSULE_ISVALID.ordinal()] = createContextFunction(HPyContextMember.CTX_CAPSULE_ISVALID); - members[HPyContextMember.CTX_CAPSULE_SET.ordinal()] = createContextFunction(HPyContextMember.CTX_CAPSULE_SET); - members[HPyContextMember.CTX_FROMPYOBJECT.ordinal()] = createContextFunction(HPyContextMember.CTX_FROMPYOBJECT); - members[HPyContextMember.CTX_ASPYOBJECT.ordinal()] = createContextFunction(HPyContextMember.CTX_ASPYOBJECT); - members[HPyContextMember.CTX_LISTBUILDER_NEW.ordinal()] = createContextFunction(HPyContextMember.CTX_LISTBUILDER_NEW); - members[HPyContextMember.CTX_LISTBUILDER_SET.ordinal()] = createContextFunction(HPyContextMember.CTX_LISTBUILDER_SET); - members[HPyContextMember.CTX_LISTBUILDER_BUILD.ordinal()] = createContextFunction(HPyContextMember.CTX_LISTBUILDER_BUILD); - members[HPyContextMember.CTX_LISTBUILDER_CANCEL.ordinal()] = createContextFunction(HPyContextMember.CTX_LISTBUILDER_CANCEL); - members[HPyContextMember.CTX_TUPLEBUILDER_NEW.ordinal()] = createContextFunction(HPyContextMember.CTX_TUPLEBUILDER_NEW); - members[HPyContextMember.CTX_TUPLEBUILDER_SET.ordinal()] = createContextFunction(HPyContextMember.CTX_TUPLEBUILDER_SET); - members[HPyContextMember.CTX_TUPLEBUILDER_BUILD.ordinal()] = createContextFunction(HPyContextMember.CTX_TUPLEBUILDER_BUILD); - members[HPyContextMember.CTX_TUPLEBUILDER_CANCEL.ordinal()] = createContextFunction(HPyContextMember.CTX_TUPLEBUILDER_CANCEL); - members[HPyContextMember.CTX_TRACKER_NEW.ordinal()] = createContextFunction(HPyContextMember.CTX_TRACKER_NEW); - members[HPyContextMember.CTX_TRACKER_ADD.ordinal()] = createContextFunction(HPyContextMember.CTX_TRACKER_ADD); - members[HPyContextMember.CTX_TRACKER_FORGETALL.ordinal()] = createContextFunction(HPyContextMember.CTX_TRACKER_FORGETALL); - members[HPyContextMember.CTX_TRACKER_CLOSE.ordinal()] = createContextFunction(HPyContextMember.CTX_TRACKER_CLOSE); - members[HPyContextMember.CTX_FIELD_STORE.ordinal()] = createContextFunction(HPyContextMember.CTX_FIELD_STORE); - members[HPyContextMember.CTX_FIELD_LOAD.ordinal()] = createContextFunction(HPyContextMember.CTX_FIELD_LOAD); - members[HPyContextMember.CTX_REENTERPYTHONEXECUTION.ordinal()] = createContextFunction(HPyContextMember.CTX_REENTERPYTHONEXECUTION); - members[HPyContextMember.CTX_LEAVEPYTHONEXECUTION.ordinal()] = createContextFunction(HPyContextMember.CTX_LEAVEPYTHONEXECUTION); - members[HPyContextMember.CTX_GLOBAL_STORE.ordinal()] = createContextFunction(HPyContextMember.CTX_GLOBAL_STORE); - members[HPyContextMember.CTX_GLOBAL_LOAD.ordinal()] = createContextFunction(HPyContextMember.CTX_GLOBAL_LOAD); - members[HPyContextMember.CTX_DUMP.ordinal()] = createContextFunction(HPyContextMember.CTX_DUMP); - members[HPyContextMember.CTX_COMPILE_S.ordinal()] = createContextFunction(HPyContextMember.CTX_COMPILE_S); - members[HPyContextMember.CTX_EVALCODE.ordinal()] = createContextFunction(HPyContextMember.CTX_EVALCODE); - members[HPyContextMember.CTX_CONTEXTVAR_NEW.ordinal()] = createContextFunction(HPyContextMember.CTX_CONTEXTVAR_NEW); - members[HPyContextMember.CTX_CONTEXTVAR_GET.ordinal()] = createContextFunction(HPyContextMember.CTX_CONTEXTVAR_GET); - members[HPyContextMember.CTX_CONTEXTVAR_SET.ordinal()] = createContextFunction(HPyContextMember.CTX_CONTEXTVAR_SET); - members[HPyContextMember.CTX_SETCALLFUNCTION.ordinal()] = createContextFunction(HPyContextMember.CTX_SETCALLFUNCTION); - - // @formatter:on - // Checkstyle: resume - // {{end llvm ctx init}} - - return members; - } - - @TruffleBoundary - public static int getIndex(String key) { - if (contextMembersByName == null) { - HashMap contextMemberHashMap = new HashMap<>(); - for (HPyContextMember member : HPyContextMember.VALUES) { - contextMemberHashMap.put(member.getName(), member); - } - // allow races; it doesn't matter since contents will always be the same - contextMembersByName = contextMemberHashMap; - } - HPyContextMember member = contextMembersByName.get(key); - return member == null ? -1 : member.ordinal(); - } - - @ExportMessage - @SuppressWarnings("static-method") - boolean hasMembers() { - return true; - } - - @ExportMessage - @SuppressWarnings("static-method") - Object getMembers(@SuppressWarnings("unused") boolean includeInternal) { - String[] names = new String[HPyContextMember.VALUES.length]; - for (int i = 0; i < names.length; i++) { - names[i] = HPyContextMember.VALUES[i].getName(); - } - return new PythonAbstractObject.Keys(names); - } - - @ExportMessage - @ImportStatic(GraalHPyLLVMContext.class) - static class IsMemberReadable { - @Specialization(guards = "cachedKey.equals(key)", limit = "1") - static boolean isMemberReadableCached(@SuppressWarnings("unused") GraalHPyLLVMContext context, @SuppressWarnings("unused") String key, - @Cached(value = "key") @SuppressWarnings("unused") String cachedKey, - @Cached(value = "getIndex(key)") int cachedIdx) { - return cachedIdx != -1; - } - - @Specialization(replaces = "isMemberReadableCached") - static boolean isMemberReadable(@SuppressWarnings("unused") GraalHPyLLVMContext context, String key) { - return getIndex(key) != -1; - } - } - - @ExportMessage - Object readMember(String key, - @Bind("$node") Node inliningTarget, - @Shared("readMemberNode") @Cached GraalHPyReadMemberNode readMemberNode) { - return readMemberNode.execute(inliningTarget, this, key); - } - - @ExportMessage - @SuppressWarnings("static-method") - boolean hasNativeType() { - return true; - } - - @ExportMessage - Object getNativeType() { - return hpyContextNativeTypeID; - } - - @GenerateUncached - @GenerateInline - @GenerateCached(false) - @ImportStatic(GraalHPyLLVMContext.class) - abstract static class GraalHPyReadMemberNode extends Node { - - public abstract Object execute(Node node, GraalHPyLLVMContext backend, String key); - - @Specialization(guards = "cachedKey == key", limit = "1") - static Object doMemberCached(GraalHPyLLVMContext backend, String key, - @Cached("key") @SuppressWarnings("unused") String cachedKey, - @Cached("getIndex(key)") int cachedIdx) { - // TODO(fa) once everything is implemented, remove this check - if (cachedIdx != -1) { - Object value = backend.hpyContextMembers[cachedIdx]; - if (value != null) { - return value; - } - } - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw CompilerDirectives.shouldNotReachHere(PythonUtils.formatJString("context function %s not yet implemented: ", key)); - } - - @Specialization(replaces = "doMemberCached") - static Object doMember(GraalHPyLLVMContext backend, String key) { - return doMemberCached(backend, key, key, getIndex(key)); - } - } - - @ExportMessage - boolean isMemberInvocable(String key, - @Bind("$node") Node inliningTarget, - @Shared("readMemberNode") @Cached GraalHPyReadMemberNode readMemberNode, - @Shared("memberInvokeLib") @CachedLibrary(limit = "1") InteropLibrary memberInvokeLib) { - Object member = readMemberNode.execute(inliningTarget, this, key); - return member != null && memberInvokeLib.isExecutable(member); - } - - @ExportMessage - Object invokeMember(String key, Object[] args, - @Bind("$node") Node inliningTarget, - @Shared("readMemberNode") @Cached GraalHPyReadMemberNode readMemberNode, - @Shared("memberInvokeLib") @CachedLibrary(limit = "1") InteropLibrary memberInvokeLib) - throws UnsupportedMessageException, UnsupportedTypeException, ArityException { - Object member = readMemberNode.execute(inliningTarget, this, key); - assert member != null; - /* - * Optimization: the first argument *MUST* always be the context. If not, we can just set - * 'this'. - */ - args[0] = context; - return memberInvokeLib.execute(member, args); - } - - @GenerateUncached - @GenerateInline - @GenerateCached(false) - @SuppressWarnings("truffle-inlining") - abstract static class HPyExecuteContextFunction extends Node { - public abstract Object execute(Node inliningTarget, HPyContextMember member, Object[] arguments) throws ArityException; - - @Specialization(guards = "member == cachedMember", limit = "1") - static Object doCached(Node inliningTarget, @SuppressWarnings("unused") HPyContextMember member, Object[] arguments, - @Cached("member") HPyContextMember cachedMember, - @Cached(parameters = "member") GraalHPyContextFunction contextFunctionNode, - @Cached("createRetNode(member)") CExtToNativeNode retNode, - @Cached("createArgNodes(member)") CExtAsPythonObjectNode[] argNodes, - @Cached HPyTransformExceptionToNativeNode transformExceptionToNativeNode) throws ArityException { - checkArity(arguments, cachedMember.getSignature().parameterTypes().length); - try { - try { - Object[] argCast; - if (argNodes != null) { - argCast = new Object[argNodes.length]; - castArguments(arguments, argCast, argNodes); - } else { - argCast = arguments; - } - Object result = contextFunctionNode.execute(argCast); - if (retNode != null) { - result = retNode.execute(result); - } - return result; - } catch (Throwable t) { - throw checkThrowableBeforeNative(t, "HPy context function", cachedMember.getName()); - } - } catch (PException e) { - transformExceptionToNativeNode.execute(inliningTarget, e); - return getErrorValue(inliningTarget, cachedMember.getSignature().returnType()); - } - } - - @Specialization(replaces = "doCached") - @Megamorphic - @TruffleBoundary - static Object doUncached(Node inliningTarget, HPyContextMember member, Object[] arguments) throws ArityException { - return doCached(inliningTarget, member, arguments, member, GraalHPyContextFunction.getUncached(member), getUncachedRetNode(member), getUncachedArgNodes(member), - HPyTransformExceptionToNativeNodeGen.getUncached()); - } - - private static void checkArity(Object[] arguments, int expectedArity) throws ArityException { - if (arguments.length != expectedArity) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw ArityException.create(expectedArity, expectedArity, arguments.length); - } - } - - @ExplodeLoop - private static void castArguments(Object[] arguments, Object[] argCast, CExtAsPythonObjectNode[] argNodes) { - for (int i = 0; i < argNodes.length; i++) { - argCast[i] = argNodes[i] == null ? arguments[i] : argNodes[i].execute(arguments[i]); - } - } - - private static Object getErrorValue(Node inliningTarget, HPyContextSignatureType type) { - return switch (type) { - case Int, Int32_t, Uint32_t, HPy_UCS4 -> -1; - case Int64_t, Uint64_t, Size_t, HPy_ssize_t, HPy_hash_t -> -1L; - case CDouble -> -1.0; - case HPy -> GraalHPyHandle.NULL_HANDLE; - case VoidPtr, CharPtr, ConstCharPtr, Cpy_PyObjectPtr -> PythonContext.get(inliningTarget).getNativeNull(); - case CVoid -> PNone.NO_VALUE; - default -> throw CompilerDirectives.shouldNotReachHere("unsupported return type"); - }; - } - - static CExtToNativeNode createRetNode(HPyContextMember member) { - return switch (member.getSignature().returnType()) { - case HPy, HPyThreadState -> HPyAsHandleNodeGen.create(); - case HPy_ssize_t, HPy_hash_t -> HPyAsNativeInt64NodeGen.create(); - default -> null; - }; - } - - static CExtToNativeNode getUncachedRetNode(HPyContextMember member) { - return switch (member.getSignature().returnType()) { - case HPy, HPyThreadState -> HPyAsHandleNodeGen.getUncached(); - case HPy_ssize_t, HPy_hash_t -> HPyAsNativeInt64NodeGen.getUncached(); - default -> null; - }; - } - - /* - * Special cases: the following context functions need the bare handles. Hence, we leave the - * conversion up to the context function impl. - */ - private static boolean noArgumentConversion(HPyContextMember member) { - return switch (member) { - case CTX_CLOSE, CTX_TRACKER_ADD -> true; - default -> false; - }; - } - - static CExtAsPythonObjectNode[] createArgNodes(HPyContextMember member) { - if (noArgumentConversion(member)) { - return null; - } - HPyContextSignatureType[] argTypes = member.getSignature().parameterTypes(); - CExtAsPythonObjectNode[] argNodes = new CExtAsPythonObjectNode[argTypes.length]; - for (int i = 0; i < argNodes.length; i++) { - argNodes[i] = switch (argTypes[i]) { - case HPyContextPtr -> HPyAsContextNodeGen.create(); - case HPy, HPyThreadState -> HPyAsPythonObjectNodeGen.create(); - default -> HPyDummyToJavaNode.getUncached(); - }; - } - return argNodes; - } - - static CExtAsPythonObjectNode[] getUncachedArgNodes(HPyContextMember member) { - if (noArgumentConversion(member)) { - return null; - } - HPyContextSignatureType[] argTypes = member.getSignature().parameterTypes(); - CExtAsPythonObjectNode[] argNodes = new CExtAsPythonObjectNode[argTypes.length]; - for (int i = 0; i < argNodes.length; i++) { - argNodes[i] = switch (argTypes[i]) { - case HPyContextPtr -> HPyAsContextNodeGen.getUncached(); - case HPy, HPyThreadState -> HPyAsPythonObjectNodeGen.getUncached(); - default -> HPyDummyToJavaNode.getUncached(); - }; - } - return argNodes; - } - } - - @ExportLibrary(InteropLibrary.class) - static final class HPyExecuteWrapper implements TruffleObject { - final HPyContextMember member; - - HPyExecuteWrapper(HPyContextMember member) { - this.member = member; - } - - @ExportMessage - boolean isExecutable() { - return true; - } - - @ExportMessage - Object execute(Object[] arguments, - @Bind("$node") Node inliningTarget, - @Cached HPyExecuteContextFunction call) throws ArityException { - return call.execute(inliningTarget, member, arguments); - } - } - - @ExportLibrary(InteropLibrary.class) - static final class HPyExecuteWrapperTraceUpcall implements TruffleObject { - - private final int[] counts; - private final int index; - - final HPyExecuteWrapper delegate; - - public HPyExecuteWrapperTraceUpcall(int[] counts, int index, HPyExecuteWrapper delegate) { - this.counts = counts; - this.index = index; - this.delegate = delegate; - } - - @ExportMessage - boolean isExecutable() { - return true; - } - - @ExportMessage - Object execute(Object[] arguments, - @CachedLibrary("this.delegate") InteropLibrary lib) throws UnsupportedMessageException, UnsupportedTypeException, ArityException { - counts[index]++; - return lib.execute(delegate, arguments); - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/GraalHPyLLVMNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/GraalHPyLLVMNodes.java deleted file mode 100644 index f48b29dcc6..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/GraalHPyLLVMNodes.java +++ /dev/null @@ -1,914 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy.llvm; - -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNativeSymbol.GRAAL_HPY_WRITE_D; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNativeSymbol.GRAAL_HPY_WRITE_HPY; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNativeSymbol.GRAAL_HPY_WRITE_HPY_SSIZE_T; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNativeSymbol.GRAAL_HPY_WRITE_I32; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNativeSymbol.GRAAL_HPY_WRITE_I64; -import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNativeSymbol.GRAAL_HPY_WRITE_PTR; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; - -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.cext.capi.PySequenceArrayWrapper; -import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CArrayWrapper; -import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CByteArrayWrapper; -import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CStringWrapper; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.EnsureTruffleStringNode; -import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.GetByteArrayNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.AllocateNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.BulkFreeHandleReferencesNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.FreeNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.GetElementPtrNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.IsNullNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadDoubleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadFloatNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadGenericNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyArrayNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyFieldNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadHPyNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadI32Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadI64Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadI8ArrayNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.ReadPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteDoubleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteGenericNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteHPyFieldNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteHPyNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteI32Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteI64Node; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WritePointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyCAccess.WriteSizeTNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.GraalHPyHandleReference; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyHandle; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNativeSymbol; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsCharPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsHandleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsPythonObjectNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyCloseAndGetHandleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyFieldLoadNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyFieldStoreNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyFromCharPointerNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyContextSignatureType; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.HPyLLVMCallHelperFunctionNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodesFactory.LLVMAllocateNodeGen; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.HPyArrayWrappers.HPyArrayWrapper; -import com.oracle.graal.python.builtins.objects.ints.PInt; -import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.util.OverflowException; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.ArityException; -import com.oracle.truffle.api.interop.InteropException; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.InvalidArrayIndexException; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.interop.UnsupportedTypeException; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; -import com.oracle.truffle.api.profiles.InlinedExactClassProfile; -import com.oracle.truffle.api.strings.InternalByteArray; -import com.oracle.truffle.api.strings.TruffleString; -import com.oracle.truffle.api.strings.TruffleString.Encoding; - -import sun.misc.Unsafe; - -abstract class GraalHPyLLVMNodes { - - private GraalHPyLLVMNodes() { - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMIsNullNode extends IsNullNode { - @Specialization(limit = "2") - static boolean doGeneric(@SuppressWarnings("unused") GraalHPyContext hpyContext, Object pointer, - @CachedLibrary("pointer") InteropLibrary lib) { - return lib.isNull(pointer); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class LLVMAllocateNode extends AllocateNode { - - @Specialization - static Object doGeneric(GraalHPyContext ctx, long size, @SuppressWarnings("unused") boolean zero, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHelperNode) { - return callHelperNode.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_CALLOC, size, 1L); - } - - static LLVMAllocateNode create() { - return LLVMAllocateNodeGen.create(); - } - - static LLVMAllocateNode getUncached() { - return LLVMAllocateNodeGen.getUncached(); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMFreeNode extends FreeNode { - - @Specialization - static void doGeneric(GraalHPyContext ctx, Object pointer, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHelperNode) { - callHelperNode.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_FREE, pointer); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMBulkFreeHandleReferencesNode extends BulkFreeHandleReferencesNode { - - @Specialization - static void doGeneric(GraalHPyContext ctx, GraalHPyHandleReference[] references, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHelperNode) { - NativeSpaceArrayWrapper nativeSpaceArrayWrapper = new NativeSpaceArrayWrapper(references); - callHelperNode.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_BULK_FREE, nativeSpaceArrayWrapper); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMGetElementPtrNode extends GetElementPtrNode { - - @Specialization - static Object doGeneric(GraalHPyContext ctx, Object pointer, long offset, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHelperNode) { - return callHelperNode.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_GET_ELEMENT_PTR, pointer, offset); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class LLVMReadI8ArrayNode extends ReadI8ArrayNode { - - @Specialization(limit = "1") - static byte[] doGeneric(GraalHPyContext ctx, Object pointer, long offset, long n, - @Bind("this") Node inliningTarget, - @CachedLibrary("pointer") InteropLibrary interopLib, - @Cached GetByteArrayNode getByteArrayNode, - @Cached HPyLLVMCallHelperFunctionNode callHPyFunction) { - if (!PInt.isIntRange(n)) { - throw CompilerDirectives.shouldNotReachHere("cannot fit long into int"); - } - Object typedPointer; - if (!interopLib.hasArrayElements(pointer)) { - typedPointer = callHPyFunction.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_FROM_I8_ARRAY, pointer, n); - } else { - typedPointer = pointer; - } - try { - return getByteArrayNode.execute(inliningTarget, typedPointer, n); - } catch (OverflowException | InteropException ex) { - throw CompilerDirectives.shouldNotReachHere(ex); - } - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMReadHPyNode extends ReadHPyNode { - - @Specialization(guards = "!close") - static Object doGet(GraalHPyContext ctx, Object pointer, long offset, @SuppressWarnings("unused") boolean close, - @Bind("this") Node inliningTarget, - @Exclusive @Cached HPyLLVMCallHelperFunctionNode callHelperNode, - @Exclusive @Cached HPyAsPythonObjectNode asPythonObjectNode) { - Object nativeValue = callHelperNode.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_READ_HPY, pointer, offset); - return asPythonObjectNode.execute(nativeValue); - } - - @Specialization(guards = "close") - static Object doClose(GraalHPyContext ctx, Object pointer, long offset, @SuppressWarnings("unused") boolean close, - @Bind("this") Node inliningTarget, - @Exclusive @Cached HPyLLVMCallHelperFunctionNode callHelperNode, - @Exclusive @Cached HPyCloseAndGetHandleNode closeAndGetHandleNode) { - Object nativeValue = callHelperNode.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_READ_HPY, pointer, offset); - return closeAndGetHandleNode.execute(inliningTarget, nativeValue); - } - - @Specialization(replaces = {"doGet", "doClose"}) - static Object doGeneric(GraalHPyContext ctx, Object pointer, long offset, @SuppressWarnings("unused") boolean close, - @Bind("this") Node inliningTarget, - @Exclusive @Cached HPyLLVMCallHelperFunctionNode callHelperNode, - @Exclusive @Cached HPyAsPythonObjectNode asPythonObjectNode, - @Exclusive @Cached HPyCloseAndGetHandleNode closeAndGetHandleNode) { - Object nativeValue = callHelperNode.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_READ_HPY, pointer, offset); - if (close) { - return closeAndGetHandleNode.execute(inliningTarget, nativeValue); - } - return asPythonObjectNode.execute(nativeValue); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMReadHPyFieldNode extends ReadHPyFieldNode { - - @Specialization - static Object doGeneric(GraalHPyContext ctx, PythonObject owner, Object pointer, long offset, @SuppressWarnings("unused") boolean close, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHelperNode, - @Cached HPyFieldLoadNode hpyFieldLoadNode) { - Object nativeValue = callHelperNode.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_READ_HPYFIELD, pointer, offset); - return hpyFieldLoadNode.execute(inliningTarget, owner, nativeValue); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMReadHPyArrayNode extends ReadHPyArrayNode { - - @Specialization - static Object[] doHPyArrayWrapper(@SuppressWarnings("unused") GraalHPyContext ctx, HPyArrayWrapper pointer, long loffset, long ln, - @Bind("this") Node inliningTarget, - @Cached InlinedConditionProfile profile) { - int n = ensureIntRange(ln); - int offset = ensureIntRange(loffset); - Object[] delegate = pointer.getDelegate(); - if (profile.profile(inliningTarget, offset == 0 && delegate.length == n)) { - return delegate; - } - return PythonUtils.arrayCopyOfRange(delegate, offset, offset + n); - } - - @Specialization - static Object[] doPointer(GraalHPyContext ctx, Object pointer, long offset, long ln, - @Bind("this") Node inliningTarget, - @CachedLibrary(limit = "1") InteropLibrary arrayLib, - @Cached HPyLLVMCallHelperFunctionNode callHelperNode, - @Cached HPyAsPythonObjectNode asPythonObjectNode) { - int n = ensureIntRange(ln); - Object typedArrayPtr = callHelperNode.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_FROM_HPY_ARRAY, pointer, offset + ln); - if (!arrayLib.hasArrayElements(typedArrayPtr)) { - throw CompilerDirectives.shouldNotReachHere("returned pointer object must have array type"); - } - - Object[] elements = new Object[n]; - try { - for (int i = 0; i < elements.length; i++) { - /* - * This will read an element of a 'VoidPtr arr[]' and the returned value will be - * 'void *'. So, there is no need to read any further element (in particular - * "_i") to get the internal handle value. - */ - Object element = arrayLib.readArrayElement(typedArrayPtr, offset + i); - elements[i] = asPythonObjectNode.execute(element); - } - return elements; - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } catch (InvalidArrayIndexException e) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(arrayLib, SystemError, ErrorMessages.CANNOT_ACCESS_IDX, e.getInvalidIndex(), n); - } - } - - private static int ensureIntRange(long n) { - if (PInt.isIntRange(n)) { - return (int) n; - } - throw CompilerDirectives.shouldNotReachHere("cannot fit long into int"); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMReadI32Node extends ReadI32Node { - - @Specialization - static int doGeneric(GraalHPyContext ctx, Object pointer, long offset, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHelperFunction, - @CachedLibrary(limit = "1") InteropLibrary lib) { - - Object nativeValue = callHelperFunction.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_READ_I32, pointer, offset); - if (nativeValue instanceof Integer) { - return (int) nativeValue; - } - if (lib.fitsInInt(nativeValue)) { - try { - return lib.asInt(nativeValue); - } catch (UnsupportedMessageException e) { - // fall through - } - } - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMReadI64Node extends ReadI64Node { - - @Specialization - static long doGeneric(GraalHPyContext ctx, Object pointer, long offset, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHelperFunction, - @CachedLibrary(limit = "1") InteropLibrary lib) { - - Object nativeValue = callHelperFunction.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_READ_I64, pointer, offset); - if (nativeValue instanceof Long) { - return (long) nativeValue; - } - if (lib.fitsInLong(nativeValue)) { - try { - return lib.asLong(nativeValue); - } catch (UnsupportedMessageException e) { - // fall through - } - } - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMReadFloatNode extends ReadFloatNode { - - @Specialization - static double doGeneric(GraalHPyContext ctx, Object pointer, long offset, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHelperFunction, - @CachedLibrary(limit = "1") InteropLibrary lib) { - - // note: C function 'graal_hpy_read_f' already returns a C double - Object nativeValue = callHelperFunction.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_READ_F, pointer, offset); - if (nativeValue instanceof Double d) { - return d; - } - if (lib.fitsInDouble(nativeValue)) { - try { - return lib.asDouble(nativeValue); - } catch (UnsupportedMessageException e) { - // fall through - } - } - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMReadDoubleNode extends ReadDoubleNode { - - @Specialization - static double doGeneric(GraalHPyContext ctx, Object pointer, long offset, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHelperFunction, - @CachedLibrary(limit = "1") InteropLibrary lib) { - - Object nativeValue = callHelperFunction.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_READ_D, pointer, offset); - if (nativeValue instanceof Double d) { - return d; - } - if (lib.fitsInDouble(nativeValue)) { - try { - return lib.asDouble(nativeValue); - } catch (UnsupportedMessageException e) { - // fall through - } - } - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMReadPointerNode extends ReadPointerNode { - - @Specialization - static Object doGeneric(GraalHPyContext ctx, Object pointer, long offset, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHelperFunction) { - return callHelperFunction.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_READ_PTR, pointer, offset); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMReadGenericNode extends ReadGenericNode { - - @Override - protected final int executeInt(GraalHPyContext ctx, Object pointer, long offset, HPyContextSignatureType size) { - Object object = execute(ctx, pointer, offset, size); - if (object instanceof Integer i) { - return i; - } else if (object instanceof Long l) { - return (int) (long) l; - } - return numberAsInt((Number) object); - } - - @Override - protected final long executeLong(GraalHPyContext ctx, Object pointer, long offset, HPyContextSignatureType size) { - Object object = execute(ctx, pointer, offset, size); - if (object instanceof Integer i) { - return (int) i; - } else if (object instanceof Long l) { - return l; - } - return numberAsLong((Number) object); - } - - @Specialization - static Object doGeneric(GraalHPyContext ctx, Object pointer, long offset, HPyContextSignatureType ctype, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHelperFunction) { - return callHelperFunction.call(inliningTarget, ctx, getReadAccessorName(ctx, ctype), pointer, offset); - } - - static GraalHPyNativeSymbol getReadAccessorName(GraalHPyContext ctx, HPyContextSignatureType type) { - switch (type) { - case Int8_t: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_I8; - case Uint8_t: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_UI8; - case Int16_t: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_I16; - case Uint16_t: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_UI16; - case Int32_t: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_I32; - case Uint32_t: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_UI32; - case Int64_t: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_I64; - case Uint64_t: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_UI64; - case Int: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_I; - case Long: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_L; - case CFloat: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_F; - case CDouble: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_D; - case HPyContextPtr, VoidPtr, VoidPtrPtr, HPyPtr, ConstHPyPtr, Wchar_tPtr, ConstWchar_tPtr, CharPtr: - case ConstCharPtr, DataPtr, DataPtrPtr, Cpy_PyObjectPtr, HPyModuleDefPtr, HPyType_SpecPtr: - case HPyType_SpecParamPtr, HPyDefPtr, HPyFieldPtr, HPyGlobalPtr, HPyCapsule_DestructorPtr, PyType_SlotPtr: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_PTR; - case Bool: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_BOOL; - case UnsignedInt: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_UI; - case UnsignedLong: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_UL; - case HPy_ssize_t: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_HPY_SSIZE_T; - } - int size = ctx.getCTypeSize(type); - switch (size) { - case 1: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_I8; - case 2: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_I16; - case 4: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_I32; - case 8: - return GraalHPyNativeSymbol.GRAAL_HPY_READ_I64; - } - throw CompilerDirectives.shouldNotReachHere("invalid member type"); - } - - @TruffleBoundary - private int numberAsInt(Number number) { - return number.intValue(); - } - - @TruffleBoundary - private long numberAsLong(Number number) { - return number.longValue(); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMWriteI32Node extends WriteI32Node { - - @Specialization - static void doGeneric(GraalHPyContext ctx, Object basePointer, long offset, int value, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHelperFunction) { - callHelperFunction.call(inliningTarget, ctx, GRAAL_HPY_WRITE_I32, basePointer, offset, value); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMWriteI64Node extends WriteI64Node { - - @Specialization - static void doGeneric(GraalHPyContext ctx, Object basePointer, long offset, long value, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHelperFunction) { - callHelperFunction.call(inliningTarget, ctx, GRAAL_HPY_WRITE_I64, basePointer, offset, value); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMWriteSizeTNode extends WriteSizeTNode { - - @Specialization - static void doGeneric(GraalHPyContext ctx, Object basePointer, long offset, long value, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHelperFunction) { - callHelperFunction.call(inliningTarget, ctx, GRAAL_HPY_WRITE_HPY_SSIZE_T, basePointer, offset, value); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMWriteDoubleNode extends WriteDoubleNode { - - @Specialization - static void doGeneric(GraalHPyContext ctx, Object basePointer, long offset, double value, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHelperFunction) { - callHelperFunction.call(inliningTarget, ctx, GRAAL_HPY_WRITE_D, basePointer, offset, value); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMWriteGenericNode extends WriteGenericNode { - - @Specialization(guards = {"type == cachedType"}, limit = "1") - static void doCached(GraalHPyContext ctx, Object pointer, long offset, @SuppressWarnings("unused") HPyContextSignatureType type, Object value, - @Bind("this") Node inliningTarget, - @Cached("type") HPyContextSignatureType cachedType, - @Exclusive @Cached HPyLLVMCallHelperFunctionNode callHelperFunction) { - callHelperFunction.call(inliningTarget, ctx, getWriteAccessor(ctx, cachedType), pointer, offset, value); - } - - @Specialization(replaces = "doCached") - static void doGeneric(GraalHPyContext ctx, Object pointer, long offset, HPyContextSignatureType type, Object value, - @Bind("this") Node inliningTarget, - @Exclusive @Cached HPyLLVMCallHelperFunctionNode callHelperFunction) { - callHelperFunction.call(inliningTarget, ctx, getWriteAccessor(ctx, type), pointer, offset, value); - } - - static GraalHPyNativeSymbol getWriteAccessor(GraalHPyContext ctx, HPyContextSignatureType type) { - switch (type) { - case Int8_t: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_I8; - case Uint8_t: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_UI8; - case Int16_t: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_I16; - case Uint16_t: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_UI16; - case Int32_t: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_I32; - case Uint32_t: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_UI32; - case Int64_t: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_I64; - case Uint64_t: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_UI64; - case Int: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_I; - case Long: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_L; - case CFloat: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_F; - case CDouble: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_D; - case HPyContextPtr, VoidPtr, VoidPtrPtr, HPyPtr, ConstHPyPtr, Wchar_tPtr, ConstWchar_tPtr, CharPtr: - case ConstCharPtr, DataPtr, DataPtrPtr, Cpy_PyObjectPtr, HPyModuleDefPtr, HPyType_SpecPtr: - case HPyType_SpecParamPtr, HPyDefPtr, HPyFieldPtr, HPyGlobalPtr, HPyCapsule_DestructorPtr, PyType_SlotPtr: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_PTR; - case Bool: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_BOOL; - case UnsignedInt: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_UI; - case UnsignedLong: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_UL; - case HPy_ssize_t: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_HPY_SSIZE_T; - } - int size = ctx.getCTypeSize(type); - switch (size) { - case 1: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_I8; - case 2: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_I16; - case 4: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_I32; - case 8: - return GraalHPyNativeSymbol.GRAAL_HPY_WRITE_I64; - } - throw CompilerDirectives.shouldNotReachHere("invalid member type"); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMWriteHPyNode extends WriteHPyNode { - - @Specialization - static void doGeneric(GraalHPyContext ctx, Object basePointer, long offset, Object object, - @Bind("this") Node inliningTarget, - @Cached HPyAsHandleNode asHandleNode, - @Cached HPyLLVMCallHelperFunctionNode callWriteDataNode) { - callWriteDataNode.call(inliningTarget, ctx, GRAAL_HPY_WRITE_HPY, basePointer, offset, asHandleNode.execute(object)); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMWriteHPyFieldNode extends WriteHPyFieldNode { - - @Specialization - static void doGeneric(GraalHPyContext ctx, PythonObject owner, Object pointer, long offset, Object referent, - @Bind("this") Node inliningTarget, - @Cached HPyFieldStoreNode fieldStoreNode, - @Cached HPyAsHandleNode asHandleNode, - @Cached HPyLLVMCallHelperFunctionNode callGetElementPtr, - @Cached HPyLLVMCallHelperFunctionNode callHelperFunctionNode) { - Object hpyFieldPtr = HPyLLVMGetElementPtrNode.doGeneric(ctx, pointer, offset, inliningTarget, callGetElementPtr); - Object hpyFieldObject = callHelperFunctionNode.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_GET_FIELD_I, hpyFieldPtr); - int idx = fieldStoreNode.execute(inliningTarget, owner, hpyFieldObject, referent); - GraalHPyHandle newHandle = asHandleNode.executeField(referent, idx); - callHelperFunctionNode.call(inliningTarget, ctx, GraalHPyNativeSymbol.GRAAL_HPY_SET_FIELD_I, hpyFieldPtr, newHandle); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMWritePointerNode extends WritePointerNode { - - @Specialization - static void doGeneric(GraalHPyContext ctx, Object basePointer, long offset, Object valuePointer, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callWriteDataNode) { - callWriteDataNode.call(inliningTarget, ctx, GRAAL_HPY_WRITE_PTR, basePointer, offset, valuePointer); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMFromCharPointerNode extends HPyFromCharPointerNode { - - @Specialization - @SuppressWarnings("unused") - static TruffleString doCStringWrapper(GraalHPyContext hpyContext, CStringWrapper cStringWrapper, int n, Encoding encoding, boolean copy) { - return cStringWrapper.getString(); - } - - @Specialization - static TruffleString doCByteArrayWrapper(@SuppressWarnings("unused") GraalHPyContext hpyContext, CByteArrayWrapper cByteArrayWrapper, int n, Encoding encoding, boolean copy, - @Shared @Cached TruffleString.FromByteArrayNode fromByteArrayNode, - @Shared @Cached TruffleString.SwitchEncodingNode switchEncodingNode) { - CompilerAsserts.partialEvaluationConstant(encoding); - CompilerAsserts.partialEvaluationConstant(copy); - byte[] byteArray = cByteArrayWrapper.getByteArray(); - int length = n < 0 ? byteArray.length : n; - return switchEncodingNode.execute(fromByteArrayNode.execute(byteArray, 0, length, encoding, copy), TS_ENCODING); - } - - @Specialization(guards = {"!isCArrayWrapper(charPtr)", "isPointer(lib, charPtr)"}) - static TruffleString doPointer(GraalHPyContext hpyContext, Object charPtr, int n, Encoding encoding, boolean copy, - @Shared @CachedLibrary(limit = "2") InteropLibrary lib, - @Cached TruffleString.FromNativePointerNode fromNative, - @Shared @Cached TruffleString.SwitchEncodingNode switchEncodingNode) { - CompilerAsserts.partialEvaluationConstant(encoding); - CompilerAsserts.partialEvaluationConstant(copy); - long pointer; - try { - pointer = lib.asPointer(charPtr); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - int length; - if (n < 0) { - length = 0; - /* - * We use 'PythonContext.getUnsafe()' here to ensure that native access is allowed - * because this specialization can be reached if 'charPtr' is not a CArrayWrapper - * but a pointer. An attacker could create a TruffleObject that answers - * 'isPointer()' with 'true' (but isn't really a native pointer). - */ - Unsafe unsafe = hpyContext.getContext().getUnsafe(); - while (unsafe.getByte(pointer + length) != 0) { - length++; - } - } else { - length = n; - } - return switchEncodingNode.execute(fromNative.execute(charPtr, 0, length, encoding, copy), TS_ENCODING); - } - - @Specialization(guards = {"!isCArrayWrapper(charPtr)", "!isPointer(lib, charPtr)"}) - static TruffleString doForeignArray(@SuppressWarnings("unused") GraalHPyContext hpyContext, Object charPtr, int n, Encoding encoding, @SuppressWarnings("unused") boolean copy, - @Shared @CachedLibrary(limit = "2") InteropLibrary lib, - @CachedLibrary(limit = "1") InteropLibrary elementLib, - @Bind("this") Node inliningTarget, - @Cached GraalHPyLLVMCallHelperFunctionNode callHelperFunctionNode, - @Cached GetByteArrayNode getByteArrayNode, - @Shared @Cached TruffleString.FromByteArrayNode fromByteArrayNode, - @Shared @Cached TruffleString.SwitchEncodingNode switchEncodingNode) { - CompilerAsserts.partialEvaluationConstant(encoding); - CompilerAsserts.partialEvaluationConstant(copy); - - Object typedCharPtr; - int length; - try { - if (!lib.hasArrayElements(charPtr)) { - /* - * If the foreign object does not have array elements, we assume it is an LLVM - * pointer where we can attach a type. We use size 'n' if available, otherwise - * we determine the size by looking for the zero-byte. - */ - int size = n < 0 ? Integer.MAX_VALUE : n; - typedCharPtr = callHelperFunctionNode.call(hpyContext, GraalHPyNativeSymbol.GRAAL_HPY_FROM_I8_ARRAY, charPtr, size); - if (n < 0) { - length = 0; - while (elementLib.asByte(lib.readArrayElement(typedCharPtr, length)) != 0) { - length++; - } - } else { - length = n; - } - } else { - /* - * Simple case: the foreign object has array elements, so just use the array - * size and read the elements. - */ - typedCharPtr = charPtr; - length = n < 0 ? PInt.intValueExact(lib.getArraySize(charPtr)) : n; - } - assert lib.hasArrayElements(typedCharPtr); - assert length >= 0; - byte[] bytes = getByteArrayNode.execute(inliningTarget, typedCharPtr, length); - // since we created a fresh byte array, we don't need to copy it - return switchEncodingNode.execute(fromByteArrayNode.execute(bytes, 0, bytes.length, encoding, false), TS_ENCODING); - } catch (InteropException | OverflowException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - static boolean isCArrayWrapper(Object object) { - return object instanceof CArrayWrapper || object instanceof PySequenceArrayWrapper; - } - - static boolean isPointer(InteropLibrary lib, Object object) { - return lib.isPointer(object); - } - } - - @GenerateUncached - @GenerateInline(false) - abstract static class HPyLLVMAsCharPointerNode extends HPyAsCharPointerNode { - - @Specialization(guards = "isNativeAccessAllowed(hpyContext)") - static Object doNative(GraalHPyContext hpyContext, TruffleString string, Encoding encoding, - @Bind("this") Node inliningTarget, - @Exclusive @Cached HPyLLVMCallHelperFunctionNode callHelperNode, - @Exclusive @Cached TruffleString.SwitchEncodingNode switchEncodingNode, - @Exclusive @Cached TruffleString.AsNativeNode asNativeNode, - @Exclusive @Cached TruffleString.GetInternalNativePointerNode getInternalNativePointerNode) { - TruffleString tsEncoded = switchEncodingNode.execute(string, encoding); - TruffleString tsNative = asNativeNode.execute(tsEncoded, byteSize -> callHelperNode.call(inliningTarget, hpyContext, GraalHPyNativeSymbol.GRAAL_HPY_CALLOC, byteSize, 1L), encoding, - false, true); - return getInternalNativePointerNode.execute(tsNative, encoding); - } - - @Specialization(replaces = "doNative") - static Object doGeneric(@SuppressWarnings("unused") GraalHPyContext hpyContext, TruffleString string, Encoding encoding, - @Exclusive @Cached TruffleString.SwitchEncodingNode switchEncodingNode, - @Exclusive @Cached TruffleString.GetInternalByteArrayNode getInternalByteArrayNode) { - TruffleString tsEncoded = switchEncodingNode.execute(string, encoding); - InternalByteArray internalByteArray = getInternalByteArrayNode.execute(tsEncoded, encoding); - return new CByteArrayWrapper(internalByteArray.getArray()); - - } - - static boolean isNativeAccessAllowed(GraalHPyContext hpyContext) { - return hpyContext.getContext().isNativeAccessAllowed(); - } - } - - @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class HPyLLVMImportSymbolNode extends PNodeWithContext { - - public abstract Object execute(Node inliningTarget, GraalHPyContext hpyContext, GraalHPyNativeSymbol symbol); - - @Specialization(guards = {"isSingleContext()", "cachedSymbol == symbol"}, limit = "1") - static Object doSymbolCached(@SuppressWarnings("unused") GraalHPyContext nativeContext, @SuppressWarnings("unused") GraalHPyNativeSymbol symbol, - @SuppressWarnings("unused") @Cached("symbol") GraalHPyNativeSymbol cachedSymbol, - @Cached("getLLVMSymbol(nativeContext, symbol)") Object llvmSymbol) { - return llvmSymbol; - } - - @Specialization(replaces = "doSymbolCached") - static Object doGeneric(Node inliningTarget, GraalHPyContext hpyContext, GraalHPyNativeSymbol symbol, - @Cached InlinedExactClassProfile exactClassProfile) { - return getLLVMSymbol(exactClassProfile.profile(inliningTarget, hpyContext), symbol); - } - - static Object getLLVMSymbol(GraalHPyContext hpyContext, GraalHPyNativeSymbol symbol) { - if (hpyContext.getBackend() instanceof GraalHPyLLVMContext hpyLLVMContext) { - return hpyLLVMContext.getNativeSymbolCache()[symbol.ordinal()]; - } - throw CompilerDirectives.shouldNotReachHere(); - } - } - - @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class HPyLLVMCallHelperFunctionNode extends PNodeWithContext { - - public static Object callUncached(GraalHPyContext context, GraalHPyNativeSymbol name, Object... args) { - return HPyLLVMCallHelperFunctionNodeGen.getUncached().execute(null, context, name, args); - } - - public final Object call(Node inliningTarget, GraalHPyContext context, GraalHPyNativeSymbol name, Object... args) { - return execute(inliningTarget, context, name, args); - } - - public abstract Object execute(Node inliningTarget, GraalHPyContext context, GraalHPyNativeSymbol name, Object[] args); - - @Specialization - static Object doIt(Node inliningTarget, GraalHPyContext context, GraalHPyNativeSymbol name, Object[] args, - @CachedLibrary(limit = "1") InteropLibrary interopLibrary, - @Cached HPyLLVMImportSymbolNode importCExtSymbolNode, - @Cached EnsureTruffleStringNode ensureTruffleStringNode, - @Cached PRaiseNode.Lazy raiseNode) { - try { - Object llvmFunction = importCExtSymbolNode.execute(inliningTarget, context, name); - return ensureTruffleStringNode.execute(inliningTarget, interopLibrary.execute(llvmFunction, args)); - } catch (UnsupportedTypeException | ArityException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, e); - } catch (UnsupportedMessageException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.HPY_CAPI_SYM_NOT_CALLABLE, name); - } - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/HPyArrayWrappers.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/HPyArrayWrappers.java deleted file mode 100644 index 6fb73174d7..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/HPyArrayWrappers.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy.llvm; - -import java.util.Arrays; - -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyHandle; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsHandleNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyCloseHandleNode; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.InvalidArrayIndexException; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.interop.UnsupportedTypeException; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.library.ExportLibrary; -import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.api.nodes.ExplodeLoop; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.ConditionProfile; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; -import com.oracle.truffle.llvm.spi.NativeTypeLibrary; - -abstract class HPyArrayWrappers { - - /** - * Wraps a sequence object (like a list) such that it behaves like a {@code HPy} array (C type - * {@code HPy *}). - */ - @ExportLibrary(InteropLibrary.class) - @ExportLibrary(value = NativeTypeLibrary.class, useForAOT = false) - static final class HPyArrayWrapper implements TruffleObject { - - private static final int UNINITIALIZED = 0; - private static final int INVALIDATED = -1; - - final GraalHPyContext hpyContext; - - final Object[] delegate; - - private final GraalHPyHandle[] wrappers; - private long nativePointer = UNINITIALIZED; - - public HPyArrayWrapper(GraalHPyContext hpyContext, Object[] delegate) { - this.hpyContext = hpyContext; - this.delegate = delegate; - this.wrappers = new GraalHPyHandle[delegate.length]; - } - - public Object[] getDelegate() { - return delegate; - } - - void setNativePointer(long nativePointer) { - assert nativePointer != UNINITIALIZED; - this.nativePointer = nativePointer; - } - - long getNativePointer() { - return this.nativePointer; - } - - @Override - public int hashCode() { - CompilerAsserts.neverPartOfCompilation(); - final int prime = 31; - int result = 1; - result = prime * result + Arrays.hashCode(delegate); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - // n.b.: (tfel) This is hopefully fine here, since if we get to this - // code path, we don't speculate that either of those objects is - // constant anymore, so any caching on them won't happen anyway - return delegate == ((HPyArrayWrapper) obj).delegate; - } - - @SuppressWarnings("static-method") - @ExportMessage - boolean hasArrayElements() { - return true; - } - - @ExportMessage - long getArraySize() { - return delegate.length; - } - - @ExportMessage - boolean isArrayElementReadable(long index) { - return 0 <= index && index < delegate.length; - } - - @ExportMessage - Object readArrayElement(long index, - @Cached HPyAsHandleNode asHandleNode) throws InvalidArrayIndexException { - if (index < 0 || index > delegate.length) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw InvalidArrayIndexException.create(index); - } - int i = (int) index; - GraalHPyHandle wrapper = wrappers[i]; - if (wrapper == null) { - wrapper = asHandleNode.execute(delegate[i]); - wrappers[i] = wrapper; - } - return wrapper; - } - - @ExportMessage - boolean isPointer() { - return nativePointer != UNINITIALIZED; - } - - @ExportMessage - long asPointer() throws UnsupportedMessageException { - if (!isPointer()) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw UnsupportedMessageException.create(); - } - return nativePointer; - } - - @ExportMessage - void toNative() { - if (!isPointer()) { - setNativePointer(hpyContext.createNativeArguments(delegate)); - } - } - - @ExportMessage - @SuppressWarnings("static-method") - boolean hasNativeType() { - return hpyContext.getBackend() instanceof GraalHPyLLVMContext; - } - - @ExportMessage - Object getNativeType() { - if (hpyContext.getBackend() instanceof GraalHPyLLVMContext llvmContext) { - return llvmContext.getHPyArrayNativeType(); - } - throw CompilerDirectives.shouldNotReachHere(); - } - - void close() { - for (int i = 0; i < wrappers.length; i++) { - if (wrappers[i] != null) { - HPyCloseHandleNode.executeUncached(wrappers[i]); - wrappers[i] = null; - } - } - if (isPointer()) { - hpyContext.freeNativeArgumentsArray(delegate.length); - } - } - } - - @GenerateInline - @GenerateCached(false) - @ImportStatic(PythonUtils.class) - abstract static class HPyCloseArrayWrapperNode extends Node { - - public abstract void execute(Node inliningTarget, HPyArrayWrapper wrapper); - - @Specialization(guards = {"cachedLen == wrapper.delegate.length", "cachedLen <= 8"}, limit = "1") - @ExplodeLoop - static void doCachedLen(Node inliningTarget, HPyArrayWrapper wrapper, - @Cached("wrapper.delegate.length") int cachedLen, - @Exclusive @Cached HPyCloseHandleNode closeHandleNode, - @Cached(value = "createConditionProfiles(cachedLen)", dimensions = 1) ConditionProfile[] profiles, - @Exclusive @Cached InlinedConditionProfile isPointerProfile) { - for (int i = 0; i < cachedLen; i++) { - Object element = wrapper.delegate[i]; - if (profiles[i].profile(element instanceof GraalHPyHandle)) { - closeHandleNode.execute(inliningTarget, element); - } - } - if (isPointerProfile.profile(inliningTarget, wrapper.isPointer())) { - wrapper.hpyContext.freeNativeArgumentsArray(wrapper.delegate.length); - wrapper.setNativePointer(HPyArrayWrapper.INVALIDATED); - } - } - - @Specialization(replaces = "doCachedLen") - static void doLoop(Node inliningTarget, HPyArrayWrapper wrapper, - @Exclusive @Cached HPyCloseHandleNode closeHandleNode, - @Exclusive @Cached InlinedConditionProfile profile, - @Exclusive @Cached InlinedConditionProfile isPointerProfile) { - int n = wrapper.delegate.length; - for (int i = 0; i < n; i++) { - Object element = wrapper.delegate[i]; - if (profile.profile(inliningTarget, element instanceof GraalHPyHandle)) { - closeHandleNode.execute(inliningTarget, element); - } - } - if (isPointerProfile.profile(inliningTarget, wrapper.isPointer())) { - wrapper.hpyContext.freeNativeArgumentsArray(wrapper.delegate.length); - wrapper.setNativePointer(HPyArrayWrapper.INVALIDATED); - } - } - - } - - /** - * Wraps a sequence object (like a list) such that it behaves like a {@code HPy} array (C type - * {@code HPy *}). - */ - @ExportLibrary(InteropLibrary.class) - static final class IntArrayWrapper implements TruffleObject { - - final int[] delegate; - - public IntArrayWrapper(int[] delegate) { - this.delegate = delegate; - } - - public int[] getDelegate() { - return delegate; - } - - @SuppressWarnings("static-method") - @ExportMessage - boolean hasArrayElements() { - return true; - } - - @ExportMessage - long getArraySize() { - return delegate.length; - } - - @ExportMessage(name = "isArrayElementReadable") - @ExportMessage(name = "isArrayElementModifiable") - boolean isValidIndex(long index) { - return 0 <= index && index < delegate.length; - } - - @ExportMessage - boolean isArrayElementInsertable(@SuppressWarnings("unused") long index) { - return false; - } - - @ExportMessage - @TruffleBoundary - Object readArrayElement(long index) throws InvalidArrayIndexException { - return delegate[checkIndex(index)]; - } - - @ExportMessage - @TruffleBoundary - void writeArrayElement(long index, Object value, - @CachedLibrary(limit = "1") InteropLibrary lib) throws UnsupportedTypeException, InvalidArrayIndexException { - delegate[checkIndex(index)] = coerceToInt(value, lib); - } - - private int coerceToInt(Object value, InteropLibrary lib) throws UnsupportedTypeException { - if (value instanceof Integer i) { - return i; - } - if (lib.fitsInInt(value)) { - try { - return lib.asInt(value); - } catch (UnsupportedMessageException e) { - // fall through - } - } - throw UnsupportedTypeException.create(new Object[]{value}); - } - - private int checkIndex(long index) throws InvalidArrayIndexException { - if (index < 0 || index > delegate.length) { - throw InvalidArrayIndexException.create(index); - } - return (int) index; - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/NativeSpaceArrayWrapper.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/NativeSpaceArrayWrapper.java deleted file mode 100644 index ce9f1732f0..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/NativeSpaceArrayWrapper.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.cext.hpy.llvm; - -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext.GraalHPyHandleReference; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyHandle; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.library.ExportLibrary; -import com.oracle.truffle.api.library.ExportMessage; - -/** - * This class implements a simple interop array that has elements with following layout: - * - *
    - *     [nativeSpacePtr0, destroyFun0, nativeSpacePtr1, destroyFun1, ...]
    - * 
    - * - * So, each element at indices {@code i % 2 == 0} is a native space pointer and each element at - * indices {@code i % 2 == 1} is the corresponding pointer to a destroy function. On the C side, - * this should be use like this: - * - *
    - *     typedef void (*destroyfunc_t)(void *);
    - *     void bulk_cleanup(void *nativeSpaceArrayWrapper) {
    - *         int64_t n = polyglot_get_array_size(nativeSpaceArrayWrapper);
    - *         void *nativeSpacePtr;
    - *         destroyfunc_t destroyfunc;
    - *         for (int64_t i = 0; i < n; i += 2) {
    - *             nativeSpacePtr = nativeSpaceArrayWrapper[i];
    - *             destroyfunc = nativeSpaceArrayWrapper[i+1];
    - *             ... 
    - *         }
    - *     }
    - * 
    - */ -@ExportLibrary(InteropLibrary.class) -final class NativeSpaceArrayWrapper implements TruffleObject { - - final GraalHPyHandleReference[] data; - - public NativeSpaceArrayWrapper(GraalHPyHandleReference[] data) { - this.data = data; - } - - @ExportMessage - @SuppressWarnings("static-method") - boolean hasArrayElements() { - return true; - } - - @ExportMessage - long getArraySize() { - return data.length * 2L; - } - - @ExportMessage - boolean isArrayElementReadable(long i) { - return i < data.length * 2L; - } - - @ExportMessage - Object readArrayElement(long i) { - GraalHPyHandleReference ref = data[(int) i / 2]; - if (ref != null) { - if (i % 2 == 0) { - return ref.getNativeSpace(); - } else { - Object destroyFunc = ref.getDestroyFunc(); - return destroyFunc != null ? destroyFunc : GraalHPyHandle.NULL_HANDLE; - } - } - /* - * At this point, we need to return something that fulfills 'interopLib.isNull(obj)'. - * However, it MUST NOT be any 'PythonAbstractObject' because the interop messages could try - * to acquire the GIL. - */ - return GraalHPyHandle.NULL_HANDLE; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/structs/CConstants.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/structs/CConstants.java index 47f21f9fb1..f4ee44d620 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/structs/CConstants.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/structs/CConstants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -90,7 +90,7 @@ public int intValue() { CompilerDirectives.transferToInterpreterAndInvalidate(); resolve(); if (intValue == -1) { - throw PRaiseNode.raiseUncached(null, SystemError, INTERNAL_INT_OVERFLOW); + throw PRaiseNode.raiseStatic(null, SystemError, INTERNAL_INT_OVERFLOW); } return intValue; } @@ -104,10 +104,10 @@ private static void resolve() { for (CConstants constant : VALUES) { constant.longValue = constants[constant.ordinal()]; if (constant.longValue == -1) { - throw PRaiseNode.raiseUncached(null, SystemError, toTruffleStringUncached("internal limitation - cannot extract constants with value '-1'")); + throw PRaiseNode.raiseStatic(null, SystemError, toTruffleStringUncached("internal limitation - cannot extract constants with value '-1'")); } if ((constant.longValue & 0xFFFF0000L) == 0xDEAD0000L) { - throw PRaiseNode.raiseUncached(null, SystemError, toTruffleStringUncached("marker value reached, regenerate C code (mx python-capi)")); + throw PRaiseNode.raiseStatic(null, SystemError, toTruffleStringUncached("marker value reached, regenerate C code (mx python-capi)")); } if (constant.longValue == (int) constant.longValue) { constant.intValue = (int) constant.longValue; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java index 013bdc4b46..b426a403b3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2014, Regents of the University of California * * All rights reserved. @@ -28,10 +28,8 @@ import static com.oracle.graal.python.annotations.ArgumentClinic.VALUE_EMPTY_TSTRING; import static com.oracle.graal.python.annotations.ArgumentClinic.VALUE_NONE; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.nodes.StringLiterals.T_NONE; +import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.objectArrayToTruffleStringArray; @@ -39,7 +37,11 @@ import java.util.Arrays; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -47,26 +49,39 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; +import com.oracle.graal.python.builtins.objects.bytes.PBytes; +import com.oracle.graal.python.builtins.objects.code.CodeBuiltinsClinicProviders.CodeConstructorNodeClinicProviderGen; +import com.oracle.graal.python.builtins.objects.common.SequenceNodes; import com.oracle.graal.python.builtins.objects.str.StringNodes.InternStringNode; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.RichCmpBuiltinNode; +import com.oracle.graal.python.compiler.BytecodeCodeUnit; import com.oracle.graal.python.compiler.CodeUnit; import com.oracle.graal.python.compiler.OpCodes; import com.oracle.graal.python.compiler.SourceMap; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyObjectHashNode; +import com.oracle.graal.python.lib.RichCmpOp; +import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.IndirectCallData; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.PythonOptions; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.bytecode.BytecodeNode; +import com.oracle.truffle.api.bytecode.Instruction; +import com.oracle.truffle.api.bytecode.SourceInformationTree; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; @@ -76,25 +91,92 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.api.strings.TruffleString; @CoreFunctions(extendClasses = PythonBuiltinClassType.PCode) public final class CodeBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = CodeBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return CodeBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "code", minNumOfPositionalArgs = 16, numOfPositionalOnlyArgs = 18, parameterNames = { + "$cls", "argcount", "posonlyargcount", "kwonlyargcount", "nlocals", "stacksize", "flags", "codestring", + "constants", "names", "varnames", "filename", "name", "qualname", "firstlineno", + "linetable", "exceptiontable", "freevars", "cellvars"}) + @ArgumentClinic(name = "argcount", conversion = ArgumentClinic.ClinicConversion.Int) + @ArgumentClinic(name = "posonlyargcount", conversion = ArgumentClinic.ClinicConversion.Int) + @ArgumentClinic(name = "kwonlyargcount", conversion = ArgumentClinic.ClinicConversion.Int) + @ArgumentClinic(name = "nlocals", conversion = ArgumentClinic.ClinicConversion.Int) + @ArgumentClinic(name = "stacksize", conversion = ArgumentClinic.ClinicConversion.Int) + @ArgumentClinic(name = "flags", conversion = ArgumentClinic.ClinicConversion.Int) + @ArgumentClinic(name = "filename", conversion = ArgumentClinic.ClinicConversion.TString) + @ArgumentClinic(name = "name", conversion = ArgumentClinic.ClinicConversion.TString) + @ArgumentClinic(name = "qualname", conversion = ArgumentClinic.ClinicConversion.TString) + @ArgumentClinic(name = "firstlineno", conversion = ArgumentClinic.ClinicConversion.Int) + @GenerateNodeFactory + public abstract static class CodeConstructorNode extends PythonClinicBuiltinNode { + @Specialization + static PCode call(VirtualFrame frame, @SuppressWarnings("unused") Object cls, int argcount, + int posonlyargcount, int kwonlyargcount, + int nlocals, int stacksize, int flags, + PBytes codestring, PTuple constants, PTuple names, PTuple varnames, + TruffleString filename, TruffleString name, TruffleString qualname, + int firstlineno, PBytes linetable, @SuppressWarnings("unused") PBytes exceptiontable, + PTuple freevars, PTuple cellvars, + @Bind("this") Node inliningTarget, + @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, + @Cached CodeNodes.CreateCodeNode createCodeNode, + @Cached SequenceNodes.GetObjectArrayNode getObjectArrayNode, + @Cached CastToTruffleStringNode castToTruffleStringNode) { + byte[] codeBytes = bufferLib.getCopiedByteArray(codestring); + byte[] linetableBytes = bufferLib.getCopiedByteArray(linetable); + + Object[] constantsArr = getObjectArrayNode.execute(inliningTarget, constants); + TruffleString[] namesArr = objectArrayToTruffleStringArray(inliningTarget, getObjectArrayNode.execute(inliningTarget, names), castToTruffleStringNode); + TruffleString[] varnamesArr = objectArrayToTruffleStringArray(inliningTarget, getObjectArrayNode.execute(inliningTarget, varnames), castToTruffleStringNode); + TruffleString[] freevarsArr = objectArrayToTruffleStringArray(inliningTarget, getObjectArrayNode.execute(inliningTarget, freevars), castToTruffleStringNode); + TruffleString[] cellcarsArr = objectArrayToTruffleStringArray(inliningTarget, getObjectArrayNode.execute(inliningTarget, cellvars), castToTruffleStringNode); + + return createCodeNode.execute(frame, argcount, posonlyargcount, kwonlyargcount, + nlocals, stacksize, flags, + codeBytes, constantsArr, namesArr, + varnamesArr, freevarsArr, cellcarsArr, + filename, name, qualname, + firstlineno, linetableBytes); + } + + @Fallback + @SuppressWarnings("unused") + static PCode call(Object cls, Object argcount, Object kwonlyargcount, Object posonlyargcount, + Object nlocals, Object stacksize, Object flags, + Object codestring, Object constants, Object names, Object varnames, + Object filename, Object name, Object qualname, + Object firstlineno, Object linetable, Object exceptiontable, + Object freevars, Object cellvars, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.INVALID_ARGS, "code"); + } + + @Override + protected ArgumentClinicProvider getArgumentClinic() { + return CodeConstructorNodeClinicProviderGen.INSTANCE; + } + } + @Builtin(name = "co_freevars", minNumOfPositionalArgs = 1, isGetter = true) @GenerateNodeFactory public abstract static class GetFreeVarsNode extends PythonUnaryBuiltinNode { @Specialization static Object get(PCode self, @Bind("this") Node inliningTarget, - @Cached InternStringNode internStringNode, - @Cached PythonObjectFactory factory) { - return internStrings(inliningTarget, self.getFreeVars(), internStringNode, factory); + @Cached InternStringNode internStringNode) { + return internStrings(inliningTarget, self.getFreeVars(), internStringNode); } } @@ -104,9 +186,8 @@ public abstract static class GetCellVarsNode extends PythonUnaryBuiltinNode { @Specialization static Object get(PCode self, @Bind("this") Node inliningTarget, - @Cached InternStringNode internStringNode, - @Cached PythonObjectFactory factory) { - return internStrings(inliningTarget, self.getCellVars(), internStringNode, factory); + @Cached InternStringNode internStringNode) { + return internStrings(inliningTarget, self.getCellVars(), internStringNode); } } @@ -215,8 +296,8 @@ static Object get(PCode self) { public abstract static class GetCodeNode extends PythonUnaryBuiltinNode { @Specialization static Object get(PCode self, - @Cached PythonObjectFactory factory) { - return self.co_code(factory); + @Bind PythonLanguage language) { + return self.co_code(language); } } @@ -226,9 +307,8 @@ public abstract static class GetConstsNode extends PythonUnaryBuiltinNode { @Specialization static Object get(PCode self, @Bind("this") Node inliningTarget, - @Cached InternStringNode internStringNode, - @Cached PythonObjectFactory factory) { - return internStrings(inliningTarget, self.getConstants(), internStringNode, factory); + @Cached InternStringNode internStringNode) { + return internStrings(inliningTarget, self.getConstants(), internStringNode); } } @@ -238,9 +318,8 @@ public abstract static class GetNamesNode extends PythonUnaryBuiltinNode { @Specialization static Object get(PCode self, @Bind("this") Node inliningTarget, - @Cached InternStringNode internStringNode, - @Cached PythonObjectFactory factory) { - return internStrings(inliningTarget, self.getNames(), internStringNode, factory); + @Cached InternStringNode internStringNode) { + return internStrings(inliningTarget, self.getNames(), internStringNode); } } @@ -250,9 +329,8 @@ public abstract static class GetVarNamesNode extends PythonUnaryBuiltinNode { @Specialization static Object get(PCode self, @Bind("this") Node inliningTarget, - @Cached InternStringNode internStringNode, - @Cached PythonObjectFactory factory) { - return internStrings(inliningTarget, self.getVarnames(), internStringNode, factory); + @Cached InternStringNode internStringNode) { + return internStrings(inliningTarget, self.getVarnames(), internStringNode); } } @@ -263,13 +341,13 @@ static Object get(PCode self, public abstract static class GetLineTableNode extends PythonUnaryBuiltinNode { @Specialization static Object get(PCode self, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { byte[] linetable = self.getLinetable(); if (linetable == null) { // TODO: this is for the moment undefined (see co_code) linetable = PythonUtils.EMPTY_BYTE_ARRAY; } - return factory.createBytes(linetable); + return PFactory.createBytes(language, linetable); } } @@ -279,9 +357,9 @@ abstract static class GetExceptionTableNode extends PythonUnaryBuiltinNode { @Specialization @SuppressWarnings("unused") static Object get(PCode self, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { // We store our exception table together with the bytecode, not in this field - return factory.createEmptyBytes(); + return PFactory.createEmptyBytes(language); } } @@ -296,30 +374,111 @@ private static final class IteratorData { @Specialization @TruffleBoundary static Object lines(PCode self) { - PythonObjectFactory factory = PythonContext.get(null).factory(); + PythonLanguage language = PythonLanguage.get(null); PTuple tuple; CodeUnit co = self.getCodeUnit(); if (co != null) { - SourceMap map = co.getSourceMap(); - List lines = new ArrayList<>(); - if (map != null && map.startLineMap.length > 0) { - IteratorData data = new IteratorData(); - data.line = map.startLineMap[0]; - co.iterateBytecode((int bci, OpCodes op, int oparg, byte[] followingArgs) -> { - int nextStart = bci + op.length(); - if (map.startLineMap[bci] != data.line || nextStart == co.code.length) { - lines.add(factory.createTuple(new int[]{data.start, nextStart, data.line})); - data.line = map.startLineMap[bci]; - data.start = nextStart; - } - }); + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + PBytecodeDSLRootNode rootNode = (PBytecodeDSLRootNode) self.getRootNodeForExtraction(); + List lines = computeLinesForBytecodeDSLInterpreter(rootNode); + tuple = PFactory.createTuple(language, lines.toArray()); + } else { + BytecodeCodeUnit bytecodeCo = (BytecodeCodeUnit) co; + SourceMap map = bytecodeCo.getSourceMap(); + List lines = new ArrayList<>(); + if (map != null && map.startLineMap.length > 0) { + IteratorData data = new IteratorData(); + data.line = map.startLineMap[0]; + bytecodeCo.iterateBytecode((int bci, OpCodes op, int oparg, byte[] followingArgs) -> { + int nextStart = bci + op.length(); + if (map.startLineMap[bci] != data.line || nextStart == bytecodeCo.code.length) { + lines.add(PFactory.createTuple(language, new int[]{data.start, nextStart, data.line})); + data.line = map.startLineMap[bci]; + data.start = nextStart; + } + }); + } + tuple = PFactory.createTuple(language, lines.toArray()); } - tuple = factory.createTuple(lines.toArray()); } else { - tuple = factory.createEmptyTuple(); + tuple = PFactory.createEmptyTuple(language); } return PyObjectGetIter.executeUncached(tuple); } + + private static List computeLinesForBytecodeDSLInterpreter(PBytecodeDSLRootNode root) { + BytecodeNode bytecodeNode = root.getBytecodeNode(); + List triples = new ArrayList<>(); + SourceInformationTree sourceInformationTree = bytecodeNode.getSourceInformationTree(); + assert sourceInformationTree.getSourceSection() != null; + traverseSourceInformationTree(sourceInformationTree, triples); + return convertTripleBcisToInstructionIndices(bytecodeNode, root.getLanguage(), triples); + } + + /** + * This function traverses the source information tree recursively to compute a list of + * consecutive bytecode ranges with their corresponding line numbers. + *

    + * Each node in the tree covers a bytecode range. Each child covers some sub-range. The + * bytecodes covered by a particular node are the bytecodes within its range that are *not* + * covered by the node's children. + *

    + * For example, consider a node covering [0, 20] with children covering [4, 9] and [15, 18]. + * The node itself covers the ranges [0, 4], [9, 15], and [18, 20]. These ranges are + * assigned the line number of the node. + */ + private static void traverseSourceInformationTree(SourceInformationTree tree, List triples) { + int startIndex = tree.getStartBytecodeIndex(); + int startLine = tree.getSourceSection().getStartLine(); + for (SourceInformationTree child : tree.getChildren()) { + if (startIndex < child.getStartBytecodeIndex()) { + // range before child.start is uncovered + triples.add(new int[]{startIndex, child.getStartBytecodeIndex(), startLine}); + } + // recursively handle [child.start, child.end] + traverseSourceInformationTree(child, triples); + startIndex = child.getEndBytecodeIndex(); + } + + if (startIndex < tree.getEndBytecodeIndex()) { + // range after last_child.end is uncovered + triples.add(new int[]{startIndex, tree.getEndBytecodeIndex(), startLine}); + } + } + + /** + * The bci ranges in the triples are not stable and can change when the bytecode is + * instrumented. We create new triples with stable instruction indices by walking the + * instructions. + */ + private static List convertTripleBcisToInstructionIndices(BytecodeNode bytecodeNode, PythonLanguage language, List triples) { + List result = new ArrayList<>(triples.size()); + int tripleIndex = 0; + int[] triple = triples.get(0); + assert triple[0] == 0 : "the first bytecode range should start from 0"; + + int startInstructionIndex = 0; + int instructionIndex = 0; + for (Instruction instruction : bytecodeNode.getInstructions()) { + if (instruction.getBytecodeIndex() == triple[1] /* end bci */) { + result.add(PFactory.createTuple(language, new int[]{startInstructionIndex, instructionIndex, triple[2]})); + startInstructionIndex = instructionIndex; + triple = triples.get(++tripleIndex); + assert triple[0] == instruction.getBytecodeIndex() : "bytecode ranges should be consecutive"; + } + + if (!instruction.isInstrumentation()) { + // Emulate CPython's fixed 2-word instructions. + instructionIndex += 2; + } + } + + result.add(PFactory.createTuple(language, new int[]{startInstructionIndex, instructionIndex, triple[2]})); + assert tripleIndex == triples.size() : "every bytecode range should have been converted to an instruction range"; + + return result; + } + } @Builtin(name = "co_positions", minNumOfPositionalArgs = 1) @@ -329,28 +488,49 @@ abstract static class CoPositionsNode extends PythonUnaryBuiltinNode { @Specialization @TruffleBoundary Object positions(PCode self) { - PythonObjectFactory factory = PythonContext.get(null).factory(); + PythonLanguage language = PythonLanguage.get(null); PTuple tuple; CodeUnit co = self.getCodeUnit(); if (co != null) { - SourceMap map = co.getSourceMap(); List lines = new ArrayList<>(); - if (map != null && map.startLineMap.length > 0) { - byte[] bytecode = co.code; - for (int i = 0; i < bytecode.length;) { - lines.add(factory.createTuple(new int[]{map.startLineMap[i], map.endLineMap[i], map.startColumnMap[i], map.endColumnMap[i]})); - i += OpCodes.fromOpCode(bytecode[i]).length(); + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + PBytecodeDSLRootNode rootNode = (PBytecodeDSLRootNode) self.getRootNodeForExtraction(); + for (Instruction instruction : rootNode.getBytecodeNode().getInstructions()) { + if (instruction.isInstrumentation()) { + // Skip instrumented instructions. The co_positions array should agree + // with the logical instruction index. + continue; + } + SourceSection section = rootNode.getSourceSectionForLocation(instruction.getLocation()); + lines.add(PFactory.createTuple(language, new int[]{ + section.getStartLine(), + section.getEndLine(), + // 1-based inclusive to 0-based inclusive + section.getStartColumn() - 1, + // 1-based inclusive to 0-based exclusive (-1 + 1 = 0) + section.getEndColumn() + })); + } + } else { + BytecodeCodeUnit bytecodeCo = (BytecodeCodeUnit) co; + SourceMap map = bytecodeCo.getSourceMap(); + if (map != null && map.startLineMap.length > 0) { + byte[] bytecode = bytecodeCo.code; + for (int i = 0; i < bytecode.length;) { + lines.add(PFactory.createTuple(language, new int[]{map.startLineMap[i], map.endLineMap[i], map.startColumnMap[i], map.endColumnMap[i]})); + i += OpCodes.fromOpCode(bytecode[i]).length(); + } } } - tuple = factory.createTuple(lines.toArray()); + tuple = PFactory.createTuple(language, lines.toArray()); } else { - tuple = factory.createEmptyTuple(); + tuple = PFactory.createEmptyTuple(language); } return PyObjectGetIter.executeUncached(tuple); } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class CodeReprNode extends PythonUnaryBuiltinNode { @Specialization @@ -363,59 +543,60 @@ static TruffleString repr(PCode self, } } - @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.tp_richcompare, isComplex = true) @GenerateNodeFactory - public abstract static class CodeEqNode extends PythonBinaryBuiltinNode { + public abstract static class CodeEqNode extends RichCmpBuiltinNode { - @Specialization + @Specialization(guards = "op.isEqOrNe()") @TruffleBoundary - boolean eq(PCode self, PCode other) { + boolean eq(PCode self, PCode other, RichCmpOp op) { if (self == other) { - return true; + return op.isEq(); } // it's quite difficult for our deserialized code objects to tell if they are the same if (self.getRootNode() != null && other.getRootNode() != null) { if (!self.getName().equalsUncached(other.getName(), TS_ENCODING)) { - return false; + return op.isNe(); } if (self.co_argcount() != other.co_argcount() || self.co_posonlyargcount() != other.co_posonlyargcount() || self.co_kwonlyargcount() != other.co_kwonlyargcount() || self.co_nlocals() != other.co_nlocals() || self.co_flags() != other.co_flags() || self.co_firstlineno() != other.co_firstlineno()) { - return false; + return op.isNe(); } if (!Arrays.equals(self.getCodestring(), other.getCodestring())) { - return false; + return op.isNe(); } // TODO compare co_const - return Arrays.equals(self.getNames(), other.getNames()) && Arrays.equals(self.getVarnames(), other.getVarnames()) && Arrays.equals(self.getFreeVars(), other.getFreeVars()) && + boolean eq = Arrays.equals(self.getNames(), other.getNames()) && Arrays.equals(self.getVarnames(), other.getVarnames()) && Arrays.equals(self.getFreeVars(), other.getFreeVars()) && Arrays.equals(self.getCellVars(), other.getCellVars()); + return eq == op.isEq(); } - return false; + return op.isNe(); } @SuppressWarnings("unused") @Fallback - Object fail(Object self, Object other) { + Object fail(Object self, Object other, RichCmpOp op) { return PNotImplemented.NOT_IMPLEMENTED; } } - @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_hash, isComplex = true) @GenerateNodeFactory - public abstract static class CodeHashNode extends PythonUnaryBuiltinNode { + public abstract static class CodeHashNode extends HashBuiltinNode { @Specialization static long hash(VirtualFrame frame, PCode self, @Bind("this") Node inliningTarget, - @Cached PyObjectHashNode hashNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language, + @Cached PyObjectHashNode hashNode) { long h, h0, h1, h2, h3, h4, h5, h6; h0 = hashNode.execute(frame, inliningTarget, self.co_name()); - h1 = hashNode.execute(frame, inliningTarget, self.co_code(factory)); - h2 = hashNode.execute(frame, inliningTarget, self.co_consts(factory)); - h3 = hashNode.execute(frame, inliningTarget, self.co_names(factory)); - h4 = hashNode.execute(frame, inliningTarget, self.co_varnames(factory)); - h5 = hashNode.execute(frame, inliningTarget, self.co_freevars(factory)); - h6 = hashNode.execute(frame, inliningTarget, self.co_cellvars(factory)); + h1 = hashNode.execute(frame, inliningTarget, self.co_code(language)); + h2 = hashNode.execute(frame, inliningTarget, self.co_consts(language)); + h3 = hashNode.execute(frame, inliningTarget, self.co_names(language)); + h4 = hashNode.execute(frame, inliningTarget, self.co_varnames(language)); + h5 = hashNode.execute(frame, inliningTarget, self.co_freevars(language)); + h6 = hashNode.execute(frame, inliningTarget, self.co_cellvars(language)); h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^ self.co_argcount() ^ self.co_posonlyargcount() ^ self.co_kwonlyargcount() ^ @@ -509,9 +690,10 @@ private static boolean hasStrings(Object[] values) { return false; } - private static PTuple internStrings(Node inliningTarget, Object[] values, InternStringNode internStringNode, PythonObjectFactory factory) { + private static PTuple internStrings(Node inliningTarget, Object[] values, InternStringNode internStringNode) { + PythonLanguage language = PythonLanguage.get(inliningTarget); if (values == null) { - return factory.createEmptyTuple(); + return PFactory.createEmptyTuple(language); } Object[] result; if (!hasStrings(values)) { @@ -526,6 +708,6 @@ private static PTuple internStrings(Node inliningTarget, Object[] values, Intern } } } - return factory.createTuple(result); + return PFactory.createTuple(language, result); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeNodes.java index 5b0bf0374b..45e204f3b0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeNodes.java @@ -46,20 +46,24 @@ import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.MarshalModuleBuiltins; -import com.oracle.graal.python.builtins.objects.code.CodeNodesFactory.GetCodeCallTargetNodeGen; import com.oracle.graal.python.builtins.objects.code.CodeNodesFactory.GetCodeRootNodeGen; import com.oracle.graal.python.builtins.objects.function.PFunction; import com.oracle.graal.python.builtins.objects.function.Signature; +import com.oracle.graal.python.compiler.BytecodeCodeUnit; import com.oracle.graal.python.compiler.CodeUnit; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRootNode; import com.oracle.graal.python.nodes.bytecode.PBytecodeGeneratorFunctionRootNode; import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode; +import com.oracle.graal.python.nodes.bytecode_dsl.BytecodeDSLCodeUnit; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLGeneratorFunctionRootNode; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode; import com.oracle.graal.python.nodes.util.BadOPCodeNode; import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.PythonOptions; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.graal.python.util.Supplier; import com.oracle.truffle.api.CallTarget; @@ -76,7 +80,6 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.strings.TruffleString; @@ -139,35 +142,44 @@ private static PCode createCode(PythonLanguage language, PythonContext context, signature = new Signature(positionalOnlyArgCount, (flags & PCode.CO_VARKEYWORDS) != 0, varArgsIndex, - positionalOnlyArgCount > 0, parameterNames, kwOnlyNames); } else { - ct = create().deserializeForBytecodeInterpreter(language, codedata, cellvars, freevars); + ct = create().deserializeForBytecodeInterpreter(language, context, codedata, cellvars, freevars); signature = ((PRootNode) ct.getRootNode()).getSignature(); } if (filename != null) { context.setCodeFilename(ct, filename); } - PythonObjectFactory factory = context.factory(); - return factory.createCode(ct, signature, nlocals, stacksize, flags, constants, names, varnames, freevars, cellvars, filename, name, qualname, firstlineno, linetable); + return PFactory.createCode(language, ct, signature, nlocals, stacksize, flags, constants, names, varnames, freevars, cellvars, filename, name, qualname, firstlineno, linetable); } @SuppressWarnings("static-method") - private RootCallTarget deserializeForBytecodeInterpreter(PythonLanguage language, byte[] data, TruffleString[] cellvars, TruffleString[] freevars) { - CodeUnit code = MarshalModuleBuiltins.deserializeCodeUnit(data); - if (cellvars != null && !Arrays.equals(code.cellvars, cellvars) || freevars != null && !Arrays.equals(code.freevars, freevars)) { - code = new CodeUnit(code.name, code.qualname, code.argCount, code.kwOnlyArgCount, code.positionalOnlyArgCount, code.stacksize, code.code, - code.srcOffsetTable, code.flags, code.names, code.varnames, - cellvars != null ? cellvars : code.cellvars, freevars != null ? freevars : code.freevars, - code.cell2arg, code.constants, code.primitiveConstants, code.exceptionHandlerRanges, code.conditionProfileCount, - code.startLine, code.startColumn, code.endLine, code.endColumn, - code.outputCanQuicken, code.variableShouldUnbox, - code.generalizeInputsMap, code.generalizeVarsMap); - } - RootNode rootNode = PBytecodeRootNode.create(language, code, PythonUtils.createFakeSource()); - if (code.isGeneratorOrCoroutine()) { - rootNode = new PBytecodeGeneratorFunctionRootNode(language, rootNode.getFrameDescriptor(), (PBytecodeRootNode) rootNode, code.name); + private RootCallTarget deserializeForBytecodeInterpreter(PythonLanguage language, PythonContext context, byte[] data, TruffleString[] cellvars, TruffleString[] freevars) { + CodeUnit codeUnit = MarshalModuleBuiltins.deserializeCodeUnit(null, context, data); + RootNode rootNode = null; + + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + BytecodeDSLCodeUnit code = (BytecodeDSLCodeUnit) codeUnit; + rootNode = code.createRootNode(context, PythonUtils.createFakeSource()); + if (code.isGeneratorOrCoroutine()) { + rootNode = new PBytecodeDSLGeneratorFunctionRootNode(language, rootNode.getFrameDescriptor(), (PBytecodeDSLRootNode) rootNode, code.name); + } + } else { + BytecodeCodeUnit code = (BytecodeCodeUnit) codeUnit; + if (cellvars != null && !Arrays.equals(code.cellvars, cellvars) || freevars != null && !Arrays.equals(code.freevars, freevars)) { + code = new BytecodeCodeUnit(code.name, code.qualname, code.argCount, code.kwOnlyArgCount, code.positionalOnlyArgCount, code.flags, code.names, + code.varnames, cellvars != null ? cellvars : code.cellvars, freevars != null ? freevars : code.freevars, code.cell2arg, + code.constants, code.startLine, + code.startColumn, code.endLine, code.endColumn, code.code, code.srcOffsetTable, + code.primitiveConstants, code.exceptionHandlerRanges, code.stacksize, code.conditionProfileCount, + code.outputCanQuicken, code.variableShouldUnbox, + code.generalizeInputsMap, code.generalizeVarsMap); + } + rootNode = PBytecodeRootNode.create(context.getLanguage(), code, PythonUtils.createFakeSource()); + if (code.isGeneratorOrCoroutine()) { + rootNode = new PBytecodeGeneratorFunctionRootNode(context.getLanguage(), rootNode.getFrameDescriptor(), (PBytecodeRootNode) rootNode, code.name); + } } return PythonUtils.getOrCreateCallTarget(rootNode); } @@ -183,12 +195,11 @@ public static PCode createCode(PythonContext context, int flags, byte[] codedata return context.getEnv().parsePublic(source); }; - PythonObjectFactory factory = context.factory(); if (context.isCoreInitialized() || isNotAModule) { - return factory.createCode(createCode, flags, firstlineno, lnotab, filename); + return PFactory.createCode(language, (RootCallTarget) createCode.get(), flags, firstlineno, lnotab, filename); } else { RootCallTarget ct = (RootCallTarget) language.cacheCode(filename, createCode); - return factory.createCode(ct, flags, firstlineno, lnotab, filename); + return PFactory.createCode(language, ct, flags, firstlineno, lnotab, filename); } } @@ -203,34 +214,17 @@ public static CreateCodeNode create() { @GenerateCached(false) public abstract static class GetCodeCallTargetNode extends PNodeWithContext { - GetCodeCallTargetNode() { - } - public abstract RootCallTarget execute(Node inliningTarget, PCode code); - public static RootCallTarget executeUncached(PCode code) { - return GetCodeCallTargetNodeGen.getUncached().execute(null, code); - } - @Specialization(guards = {"cachedCode == code", "isSingleContext()"}, limit = "2") static RootCallTarget doCachedCode(@SuppressWarnings("unused") PCode code, - @SuppressWarnings("unused") @Cached(value = "code", weak = true) PCode cachedCode, - @Cached(value = "code.initializeCallTarget()", weak = true) RootCallTarget cachedRootCallTarget) { - return cachedRootCallTarget; + @Cached(value = "code", weak = true) PCode cachedCode) { + return cachedCode.getRootCallTarget(); } @Specialization(replaces = "doCachedCode") - static RootCallTarget doGeneric(Node inliningTarget, PCode code, - @Cached InlinedConditionProfile hasCtProfile) { - return getInMultiContext(inliningTarget, code, hasCtProfile); - } - - public static RootCallTarget getInMultiContext(Node inliningTarget, PCode code, InlinedConditionProfile hasCtProfile) { - RootCallTarget ct = code.callTarget; - if (hasCtProfile.profile(inliningTarget, ct == null)) { - ct = code.initializeCallTarget(); - } - return ct; + static RootCallTarget doGeneric(PCode code) { + return code.getRootCallTarget(); } } @@ -264,10 +258,8 @@ public static Signature getInSingleContextMode(Node inliningTarget, PCode code) } @Specialization(replaces = "doCached") - static Signature doCode(Node inliningTarget, PCode code, - @Cached InlinedConditionProfile signatureProfile, - @Cached InlinedConditionProfile ctProfile) { - return code.getSignature(inliningTarget, signatureProfile); + static Signature doCode(PCode code) { + return code.getSignature(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/PCode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/PCode.java index 90dfe41bac..ab6f6bc32d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/PCode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/PCode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -59,37 +59,38 @@ import com.oracle.graal.python.builtins.objects.function.Signature; import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.compiler.BytecodeCodeUnit; import com.oracle.graal.python.compiler.CodeUnit; import com.oracle.graal.python.compiler.OpCodes; import com.oracle.graal.python.nodes.PRootNode; import com.oracle.graal.python.nodes.bytecode.PBytecodeGeneratorFunctionRootNode; import com.oracle.graal.python.nodes.bytecode.PBytecodeGeneratorRootNode; import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode; +import com.oracle.graal.python.nodes.bytecode_dsl.BytecodeDSLCodeUnit; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLGeneratorFunctionRootNode; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode; import com.oracle.graal.python.nodes.object.IsForeignObjectNode; import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.PythonOptions; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.BoolSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.DoubleSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.LongSequenceStorage; import com.oracle.graal.python.util.PythonUtils; -import com.oracle.graal.python.util.Supplier; -import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.bytecode.BytecodeNode; +import com.oracle.truffle.api.bytecode.ContinuationRootNode; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.object.Shape; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.api.strings.TruffleString; @@ -108,11 +109,8 @@ public final class PCode extends PythonBuiltinObject { /* GraalPy-specific */ public static final int CO_GRAALPYHON_MODULE = 0x1000; - // callTargetSupplier may be null, in which case callTarget and signature will be - // set. Otherwise, these are lazily created from the supplier. - private Supplier callTargetSupplier; - RootCallTarget callTarget; - @CompilationFinal private Signature signature; + private final RootCallTarget callTarget; + private final Signature signature; // number of local variables private int nlocals = -1; @@ -149,7 +147,7 @@ public final class PCode extends PythonBuiltinObject { public PCode(Object cls, Shape instanceShape, RootCallTarget callTarget) { super(cls, instanceShape); this.callTarget = callTarget; - initializeSignature(callTarget); + this.signature = Signature.fromCallTarget(callTarget); } public PCode(Object cls, Shape instanceShape, RootCallTarget callTarget, int flags, int firstlineno, byte[] linetable, TruffleString filename) { @@ -160,19 +158,16 @@ public PCode(Object cls, Shape instanceShape, RootCallTarget callTarget, int fla this.filename = filename; } - public PCode(Object cls, Shape instanceShape, Supplier callTargetSupplier, int flags, int firstlineno, byte[] linetable, TruffleString filename) { - super(cls, instanceShape); - this.callTargetSupplier = callTargetSupplier; - this.flags = flags; - this.firstlineno = firstlineno; - this.linetable = linetable; - this.filename = filename; + public PCode(Object cls, Shape instanceShape, RootCallTarget callTarget, Signature signature, BytecodeCodeUnit codeUnit) { + this(cls, instanceShape, callTarget, signature, codeUnit.varnames.length, -1, -1, null, null, + null, null, null, null, + codeUnit.name, codeUnit.qualname, -1, codeUnit.srcOffsetTable); } - public PCode(Object cls, Shape instanceShape, RootCallTarget callTarget, Signature signature, CodeUnit codeUnit) { + public PCode(Object cls, Shape instanceShape, RootCallTarget callTarget, Signature signature, BytecodeDSLCodeUnit codeUnit) { this(cls, instanceShape, callTarget, signature, codeUnit.varnames.length, -1, -1, null, null, null, null, null, null, - codeUnit.name, codeUnit.qualname, -1, codeUnit.srcOffsetTable); + codeUnit.name, codeUnit.qualname, -1, null); } public PCode(Object cls, Shape instanceShape, RootCallTarget callTarget, Signature signature, int nlocals, @@ -196,6 +191,7 @@ public PCode(Object cls, Shape instanceShape, RootCallTarget callTarget, Signatu this.cellvars = cellvars; this.callTarget = callTarget; this.signature = signature; + assert signature != null; } private static TruffleString[] extractFreeVars(RootNode rootNode) { @@ -266,13 +262,14 @@ private static String getSourceSectionFileName(SourceSection src) { @TruffleBoundary private static int extractFirstLineno(RootNode rootNode) { RootNode funcRootNode = rootNodeForExtraction(rootNode); - if (funcRootNode instanceof PBytecodeRootNode) { - CodeUnit co = ((PBytecodeRootNode) funcRootNode).getCodeUnit(); + CodeUnit co = getCodeUnit(funcRootNode); + if (co != null) { if ((co.flags & CO_GRAALPYHON_MODULE) != 0) { return 1; } return co.startLine; } + SourceSection sourceSection = funcRootNode.getSourceSection(); if (sourceSection != null) { return sourceSection.getStartLine(); @@ -288,10 +285,15 @@ private static TruffleString extractName(RootNode rootNode) { @TruffleBoundary private static int extractStackSize(RootNode rootNode) { RootNode funcRootNode = rootNodeForExtraction(rootNode); - if (funcRootNode instanceof PBytecodeRootNode) { - CodeUnit code = ((PBytecodeRootNode) funcRootNode).getCodeUnit(); + if (funcRootNode instanceof PBytecodeRootNode bytecodeRootNode) { + BytecodeCodeUnit code = bytecodeRootNode.getCodeUnit(); return code.stacksize + code.varnames.length + code.cellvars.length + code.freevars.length; } + /** + * NB: This fallback case includes PBytecodeDSLRootNode. The Bytecode DSL stack does not + * mirror a CPython stack (it's an operand stack for its own instruction set), so the frame + * size is our best estimate. + */ return funcRootNode.getFrameDescriptor().getNumberOfSlots(); } @@ -307,8 +309,18 @@ private static TruffleString[] extractVarnames(RootNode node) { @TruffleBoundary private static Object[] extractConstants(RootNode node) { RootNode rootNode = rootNodeForExtraction(node); - if (rootNode instanceof PBytecodeRootNode) { - CodeUnit co = ((PBytecodeRootNode) rootNode).getCodeUnit(); + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + if (rootNode instanceof PBytecodeDSLRootNode bytecodeDSLRootNode) { + BytecodeDSLCodeUnit co = bytecodeDSLRootNode.getCodeUnit(); + List constants = new ArrayList<>(); + for (int i = 0; i < co.constants.length; i++) { + Object constant = convertConstantToPythonSpace(rootNode, co.constants[i]); + constants.add(constant); + } + return constants.toArray(new Object[0]); + } + } else if (rootNode instanceof PBytecodeRootNode bytecodeRootNode) { + BytecodeCodeUnit co = bytecodeRootNode.getCodeUnit(); Set bytecodeConstants = new HashSet<>(); for (int bci = 0; bci < co.code.length;) { OpCodes op = OpCodes.fromOpCode(co.code[bci]); @@ -355,11 +367,20 @@ private static TruffleString[] extractNames(RootNode node) { } private static RootNode rootNodeForExtraction(RootNode rootNode) { - if (rootNode instanceof PBytecodeGeneratorFunctionRootNode) { - return ((PBytecodeGeneratorFunctionRootNode) rootNode).getBytecodeRootNode(); - } - if (rootNode instanceof PBytecodeGeneratorRootNode) { - return ((PBytecodeGeneratorRootNode) rootNode).getBytecodeRootNode(); + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + if (rootNode instanceof PBytecodeDSLGeneratorFunctionRootNode generatorFunctionRootNode) { + return generatorFunctionRootNode.getBytecodeRootNode(); + } + if (rootNode instanceof ContinuationRootNode generatorRootNode) { + return (RootNode) generatorRootNode.getSourceRootNode(); + } + } else { + if (rootNode instanceof PBytecodeGeneratorFunctionRootNode generatorFunctionRootNode) { + return generatorFunctionRootNode.getBytecodeRootNode(); + } + if (rootNode instanceof PBytecodeGeneratorRootNode generatorRootNode) { + return generatorRootNode.getBytecodeRootNode(); + } } return rootNode; } @@ -376,8 +397,12 @@ private static int extractFlags(RootNode node) { private static CodeUnit getCodeUnit(RootNode node) { RootNode rootNode = rootNodeForExtraction(node); - if (rootNode instanceof PBytecodeRootNode) { - return ((PBytecodeRootNode) rootNode).getCodeUnit(); + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + if (rootNode instanceof PBytecodeDSLRootNode bytecodeDSLRootNode) { + return bytecodeDSLRootNode.getCodeUnit(); + } + } else if (rootNode instanceof PBytecodeRootNode bytecodeRootNode) { + return bytecodeRootNode.getCodeUnit(); } return null; } @@ -386,6 +411,10 @@ RootNode getRootNode() { return getRootCallTarget().getRootNode(); } + RootNode getRootNodeForExtraction() { + return rootNodeForExtraction(getRootNode()); + } + public TruffleString[] getFreeVars() { if (freevars == null) { freevars = extractFreeVars(getRootNode()); @@ -433,23 +462,19 @@ public int getFirstLineNo() { } @TruffleBoundary - public int bciToLine(int bci) { + public int lastiToLine(int lasti) { RootNode funcRootNode = rootNodeForExtraction(getRootNode()); - if (funcRootNode instanceof PBytecodeRootNode bytecodeRootNode) { - return bytecodeRootNode.bciToLine(bci); + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + if (funcRootNode instanceof PBytecodeDSLRootNode bytecodeDSLRootNode) { + BytecodeNode bytecodeNode = bytecodeDSLRootNode.getBytecodeNode(); + return bytecodeDSLRootNode.bciToLine(PBytecodeDSLRootNode.lastiToBci(lasti, bytecodeNode), bytecodeNode); + } + } else if (funcRootNode instanceof PBytecodeRootNode bytecodeRootNode) { + return bytecodeRootNode.bciToLine(bytecodeRootNode.lastiToBci(lasti)); } return -1; } - @TruffleBoundary - public int lastiToBci(int lasti) { - RootNode funcRootNode = rootNodeForExtraction(getRootNode()); - if (funcRootNode instanceof PBytecodeRootNode bytecodeRootNode) { - return bytecodeRootNode.lastiToBci(lasti); - } - return lasti; - } - public TruffleString getName() { if (name == null) { name = extractName(getRootNode()); @@ -527,31 +552,35 @@ public Object[] getConstants() { @TruffleBoundary private static Object convertConstantToPythonSpace(RootNode rootNode, Object o) { - PythonObjectFactory factory = PythonObjectFactory.getUncached(); + PythonLanguage language = PythonLanguage.get(null); if (o instanceof CodeUnit) { - CodeUnit code = ((CodeUnit) o); - PBytecodeRootNode bytecodeRootNode = PBytecodeRootNode.create(PythonLanguage.get(rootNode), code, getSourceSection(rootNode).getSource()); - return factory.createCode(bytecodeRootNode.getCallTarget(), bytecodeRootNode.getSignature(), code); + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + BytecodeDSLCodeUnit code = (BytecodeDSLCodeUnit) o; + PBytecodeDSLRootNode root = code.createRootNode(PythonContext.get(rootNode), getSourceSection(rootNode).getSource()); + return PFactory.createCode(language, root.getCallTarget(), root.getSignature(), code); + } else { + BytecodeCodeUnit code = (BytecodeCodeUnit) o; + PBytecodeRootNode bytecodeRootNode = PBytecodeRootNode.create(language, code, getSourceSection(rootNode).getSource()); + return PFactory.createCode(language, bytecodeRootNode.getCallTarget(), bytecodeRootNode.getSignature(), code); + } } else if (o instanceof BigInteger) { - return factory.createInt((BigInteger) o); + return PFactory.createInt(language, (BigInteger) o); } else if (o instanceof int[]) { - return factory.createTuple((int[]) o); + return PFactory.createTuple(language, (int[]) o); } else if (o instanceof long[]) { - return factory.createTuple(new LongSequenceStorage((long[]) o)); + return PFactory.createTuple(language, new LongSequenceStorage((long[]) o)); } else if (o instanceof double[]) { - return factory.createTuple(new DoubleSequenceStorage((double[]) o)); + return PFactory.createTuple(language, new DoubleSequenceStorage((double[]) o)); } else if (o instanceof boolean[]) { - return factory.createTuple(new BoolSequenceStorage((boolean[]) o)); + return PFactory.createTuple(language, new BoolSequenceStorage((boolean[]) o)); } else if (o instanceof byte[]) { - return factory.createBytes((byte[]) o); - } else if (o instanceof TruffleString[]) { - TruffleString[] strings = (TruffleString[]) o; + return PFactory.createBytes(language, (byte[]) o); + } else if (o instanceof TruffleString[] strings) { Object[] array = new Object[strings.length]; System.arraycopy(strings, 0, array, 0, strings.length); - return factory.createTuple(array); - } else if (o instanceof Object[]) { - Object[] objects = (Object[]) o; - return factory.createTuple(objects.clone()); + return PFactory.createTuple(language, array); + } else if (o instanceof Object[] objects) { + return PFactory.createTuple(language, objects.clone()); } // Ensure no conversion is missing assert !IsForeignObjectNode.executeUncached(o) : o; @@ -599,49 +628,10 @@ public boolean takesVarKeywordArgs() { } public Signature getSignature() { - return getSignature(null, InlinedConditionProfile.getUncached()); - } - - public Signature getSignature(Node inliningTarget, InlinedConditionProfile signatureProfile) { - if (signatureProfile.profile(inliningTarget, signature == null)) { - if (CompilerDirectives.isPartialEvaluationConstant(this)) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - } - if (callTarget == null) { - callTarget = initializeCallTarget(); - } - signature = initializeSignature(callTarget); - } - return signature; - } - - @TruffleBoundary - synchronized Signature initializeSignature(RootCallTarget rootCallTarget) { - assert PythonContext.get(null).ownsGil(); // otherwise this is racy - if (signature == null) { - if (rootCallTarget.getRootNode() instanceof PRootNode) { - signature = ((PRootNode) rootCallTarget.getRootNode()).getSignature(); - } else { - signature = Signature.createVarArgsAndKwArgsOnly(); - } - } return signature; } public RootCallTarget getRootCallTarget() { - if (callTarget == null) { - initializeCallTarget(); - } - return callTarget; - } - - @TruffleBoundary - synchronized RootCallTarget initializeCallTarget() { - assert PythonContext.get(null).ownsGil(); // otherwise this is racy - if (callTarget == null) { - callTarget = (RootCallTarget) callTargetSupplier.get(); - callTargetSupplier = null; - } return callTarget; } @@ -694,35 +684,33 @@ public String toString() { @TruffleBoundary public String toDisassembledString(boolean quickened) { RootNode rootNode = getRootCallTarget().getRootNode(); - if (rootNode instanceof PBytecodeGeneratorRootNode r) { + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER && rootNode instanceof PBytecodeDSLRootNode dslRoot) { + return dslRoot.getCodeUnit().toString(quickened); + } else if (rootNode instanceof PBytecodeGeneratorRootNode r) { rootNode = r.getBytecodeRootNode(); } else if (rootNode instanceof PBytecodeGeneratorFunctionRootNode r) { rootNode = r.getBytecodeRootNode(); } - if (rootNode instanceof PBytecodeRootNode) { - CodeUnit code = ((PBytecodeRootNode) rootNode).getCodeUnit(); - if (quickened) { - return code.toString(((PBytecodeRootNode) rootNode).getBytecode()); - } - return code.toString(); + if (rootNode instanceof PBytecodeRootNode bytecodeRootNode) { + return bytecodeRootNode.getCodeUnit().toString(quickened); } return J_EMPTY_STRING; } - private static PTuple createTuple(Object[] array, PythonObjectFactory factory) { + private static PTuple createTuple(PythonLanguage language, Object[] array) { Object[] data = array; if (data == null) { data = PythonUtils.EMPTY_OBJECT_ARRAY; } - return factory.createTuple(data); + return PFactory.createTuple(language, data); } - private static PBytes createBytes(byte[] array, PythonObjectFactory factory) { + private static PBytes createBytes(byte[] array, PythonLanguage language) { byte[] bytes = array; if (bytes == null) { bytes = PythonUtils.EMPTY_BYTE_ARRAY; } - return factory.createBytes(bytes); + return PFactory.createBytes(language, bytes); } public TruffleString co_name() { @@ -743,32 +731,32 @@ public TruffleString co_filename() { return fName; } - public PBytes co_code(PythonObjectFactory factory) { - return createBytes(this.getCodestring(), factory); + public PBytes co_code(PythonLanguage language) { + return createBytes(this.getCodestring(), language); } - public PBytes co_lnotab(PythonObjectFactory factory) { - return createBytes(this.getLinetable(), factory); + public PBytes co_lnotab(PythonLanguage language) { + return createBytes(this.getLinetable(), language); } - public PTuple co_consts(PythonObjectFactory factory) { - return createTuple(this.getConstants(), factory); + public PTuple co_consts(PythonLanguage language) { + return createTuple(language, this.getConstants()); } - public PTuple co_names(PythonObjectFactory factory) { - return createTuple(this.getNames(), factory); + public PTuple co_names(PythonLanguage language) { + return createTuple(language, this.getNames()); } - public PTuple co_varnames(PythonObjectFactory factory) { - return createTuple(this.getVarnames(), factory); + public PTuple co_varnames(PythonLanguage language) { + return createTuple(language, this.getVarnames()); } - public PTuple co_freevars(PythonObjectFactory factory) { - return createTuple(this.getFreeVars(), factory); + public PTuple co_freevars(PythonLanguage language) { + return createTuple(language, this.getFreeVars()); } - public PTuple co_cellvars(PythonObjectFactory factory) { - return createTuple(this.getCellVars(), factory); + public PTuple co_cellvars(PythonLanguage language) { + return createTuple(language, this.getCellVars()); } public int co_argcount() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/BufferStorageNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/BufferStorageNodes.java index 70c5e1110e..4c5652bd89 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/BufferStorageNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/BufferStorageNodes.java @@ -45,6 +45,7 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.ints.PInt; @@ -58,8 +59,9 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.util.CastToJavaLongExactNode; import com.oracle.graal.python.nodes.util.CastToJavaUnsignedLongNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.BufferFormat; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -125,12 +127,12 @@ static long unpackSignedLong(@SuppressWarnings("unused") BufferFormat format, Ob @Specialization(guards = "format == UINT_64") static Object unpackUnsignedLong(Node inliningTarget, @SuppressWarnings("unused") BufferFormat format, Object buffer, int offset, + @Bind PythonLanguage language, @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached InlinedConditionProfile needsPIntProfile, - @Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { + @Cached InlinedConditionProfile needsPIntProfile) { long signedLong = bufferLib.readLong(buffer, offset); if (needsPIntProfile.profile(inliningTarget, signedLong < 0)) { - return factory.createInt(PInt.longToUnsignedBigInteger(signedLong)); + return PFactory.createInt(language, PInt.longToUnsignedBigInteger(signedLong)); } else { return signedLong; } @@ -156,19 +158,19 @@ static boolean unpackBoolean(@SuppressWarnings("unused") BufferFormat format, Ob @Specialization(guards = "format == CHAR") static PBytes unpackChar(@SuppressWarnings("unused") BufferFormat format, Object buffer, int offset, - @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { - return factory.createBytes(new byte[]{bufferLib.readByte(buffer, offset)}); + @Bind PythonLanguage language, + @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib) { + return PFactory.createBytes(language, new byte[]{bufferLib.readByte(buffer, offset)}); } @Specialization(guards = "format == UNICODE") static TruffleString unpackUnicode(Node inliningTarget, @SuppressWarnings("unused") BufferFormat format, Object buffer, int offset, @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached(inline = false) TruffleString.FromCodePointNode fromCodePointNode) { int codePoint = bufferLib.readInt(buffer, offset); if (!Character.isValidCodePoint(codePoint)) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.UNMAPPABLE_CHARACTER); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.UNMAPPABLE_CHARACTER); } return fromCodePointNode.execute(codePoint, TS_ENCODING, true); } @@ -184,9 +186,9 @@ public abstract static class PackValueNode extends Node { @Specialization(guards = "format == UINT_8") static void packUnsignedByteInt(Node inliningTarget, @SuppressWarnings("unused") BufferFormat format, int value, Object buffer, int offset, @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { if (value < 0 || value > 0xFF) { - throw raiseNode.get(inliningTarget).raise(OverflowError); + throw raiseNode.raise(inliningTarget, OverflowError); } bufferLib.writeByte(buffer, offset, (byte) value); } @@ -195,10 +197,10 @@ static void packUnsignedByteInt(Node inliningTarget, @SuppressWarnings("unused") static void packUnsignedByteGeneric(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") BufferFormat format, Object object, Object buffer, int offset, @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Shared @Cached PyNumberAsSizeNode asSizeNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { int value = asSizeNode.executeExact(frame, inliningTarget, object); if (value < 0 || value > 0xFF) { - throw raiseNode.get(inliningTarget).raise(OverflowError); + throw raiseNode.raise(inliningTarget, OverflowError); } bufferLib.writeByte(buffer, offset, (byte) value); } @@ -207,10 +209,10 @@ static void packUnsignedByteGeneric(VirtualFrame frame, Node inliningTarget, @Su static void packSignedByteGeneric(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") BufferFormat format, Object object, Object buffer, int offset, @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Shared @Cached PyNumberAsSizeNode asSizeNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { int value = asSizeNode.executeExact(frame, inliningTarget, object); if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) { - throw raiseNode.get(inliningTarget).raise(OverflowError); + throw raiseNode.raise(inliningTarget, OverflowError); } bufferLib.writeByte(buffer, offset, (byte) value); } @@ -219,10 +221,10 @@ static void packSignedByteGeneric(VirtualFrame frame, Node inliningTarget, @Supp static void packSignedShortGeneric(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") BufferFormat format, Object object, Object buffer, int offset, @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Shared @Cached PyNumberAsSizeNode asSizeNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { int value = asSizeNode.executeExact(frame, inliningTarget, object); if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) { - throw raiseNode.get(inliningTarget).raise(OverflowError); + throw raiseNode.raise(inliningTarget, OverflowError); } bufferLib.writeShort(buffer, offset, (short) value); } @@ -231,10 +233,10 @@ static void packSignedShortGeneric(VirtualFrame frame, Node inliningTarget, @Sup static void packUnsignedShortGeneric(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") BufferFormat format, Object object, Object buffer, int offset, @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Shared @Cached PyNumberAsSizeNode asSizeNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { int value = asSizeNode.executeExact(frame, inliningTarget, object); if (value < 0 || value > (Short.MAX_VALUE << 1) + 1) { - throw raiseNode.get(inliningTarget).raise(OverflowError); + throw raiseNode.raise(inliningTarget, OverflowError); } bufferLib.writeShort(buffer, offset, (short) value); } @@ -258,10 +260,10 @@ static void packUnsignedIntGeneric(VirtualFrame frame, Node inliningTarget, @Sup @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Shared @Cached PyNumberIndexNode indexNode, @Shared @Cached CastToJavaLongExactNode castToLong, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { long value = castToLong.execute(inliningTarget, indexNode.execute(frame, inliningTarget, object)); if (value < 0 || value > ((long) (Integer.MAX_VALUE) << 1L) + 1L) { - throw raiseNode.get(inliningTarget).raise(OverflowError); + throw raiseNode.raise(inliningTarget, OverflowError); } bufferLib.writeInt(buffer, offset, (int) value); } @@ -311,9 +313,9 @@ static void packBoolean(VirtualFrame frame, @SuppressWarnings("unused") BufferFo @Specialization(guards = "format == CHAR") static void packChar(Node inliningTarget, @SuppressWarnings("unused") BufferFormat format, PBytes object, Object buffer, int offset, @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { if (bufferLib.getBufferLength(object) != 1) { - throw raiseNode.get(inliningTarget).raise(OverflowError); + throw raiseNode.raise(inliningTarget, OverflowError); } byte value = bufferLib.readByte(object, 0); bufferLib.writeByte(buffer, offset, value); @@ -321,9 +323,8 @@ static void packChar(Node inliningTarget, @SuppressWarnings("unused") BufferForm @Specialization(guards = {"format == CHAR", "!isPBytes(object)"}) @SuppressWarnings("unused") - static void packChar(Node inliningTarget, BufferFormat format, Object object, Object buffer, int offset, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(TypeError); + static void packChar(Node inliningTarget, BufferFormat format, Object object, Object buffer, int offset) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError); } @Specialization(guards = "format == UNICODE") @@ -332,13 +333,13 @@ static void packDouble(Node inliningTarget, @SuppressWarnings("unused") BufferFo @Cached StringNodes.CastToTruffleStringCheckedNode cast, @Cached(inline = false) TruffleString.CodePointLengthNode codePointLengthNode, @Cached(inline = false) TruffleString.CodePointAtIndexNode codePointAtIndexNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { TruffleString str = cast.cast(inliningTarget, object, ErrorMessages.ARRAY_ITEM_MUST_BE_UNICODE); if (codePointLengthNode.execute(str, TS_ENCODING) == 1) { int codePoint = codePointAtIndexNode.execute(str, 0, TS_ENCODING); bufferLib.writeInt(buffer, offset, codePoint); } else { - throw raiseNode.get(inliningTarget).raise(TypeError); + throw raiseNode.raise(inliningTarget, TypeError); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/DynamicObjectStorage.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/DynamicObjectStorage.java index 3f6ecee108..808297aad0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/DynamicObjectStorage.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/DynamicObjectStorage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -236,14 +236,14 @@ static Object notString(Frame frame, DynamicObjectStorage self, Object key, long @Shared("readKey") @Cached ReadAttributeFromPythonObjectNode readKey, @Exclusive @Cached("self.store.getShape()") Shape cachedShape, @Exclusive @Cached(value = "keyArray(cachedShape)", dimensions = 1) Object[] keyList, - @Shared("eqNode") @Cached PyObjectRichCompareBool.EqNode eqNode, + @Shared("eqNode") @Cached PyObjectRichCompareBool eqNode, @Shared("hashNode") @Cached PyObjectHashNode hashNode, @Shared("noValueProfile") @Cached InlinedConditionProfile noValueProfile) { long hash = hashIn == -1 ? hashNode.execute(frame, inliningTarget, key) : hashIn; for (Object currentKey : keyList) { if (currentKey instanceof TruffleString) { long keyHash = hashNode.execute(frame, inliningTarget, currentKey); - if (keyHash == hash && eqNode.compare(frame, inliningTarget, key, currentKey)) { + if (keyHash == hash && eqNode.executeEq(frame, inliningTarget, key, currentKey)) { return string(inliningTarget, self, (TruffleString) currentKey, -1, readKey, noValueProfile); } } @@ -255,7 +255,7 @@ static Object notString(Frame frame, DynamicObjectStorage self, Object key, long static Object notStringLoop(Frame frame, DynamicObjectStorage self, Object key, long hashIn, @Bind("this") Node inliningTarget, @Shared("readKey") @Cached ReadAttributeFromPythonObjectNode readKey, - @Shared("eqNode") @Cached PyObjectRichCompareBool.EqNode eqNode, + @Shared("eqNode") @Cached PyObjectRichCompareBool eqNode, @Shared("hashNode") @Cached PyObjectHashNode hashNode, @Shared("noValueProfile") @Cached InlinedConditionProfile noValueProfile) { long hash = hashIn == -1 ? hashNode.execute(frame, inliningTarget, key) : hashIn; @@ -264,7 +264,7 @@ static Object notStringLoop(Frame frame, DynamicObjectStorage self, Object key, Object currentKey = getNext(keys); if (currentKey instanceof TruffleString) { long keyHash = hashNode.execute(frame, inliningTarget, currentKey); - if (keyHash == hash && eqNode.compare(frame, inliningTarget, key, currentKey)) { + if (keyHash == hash && eqNode.executeEq(frame, inliningTarget, key, currentKey)) { return string(inliningTarget, self, (TruffleString) currentKey, -1, readKey, noValueProfile); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/EconomicMapStorage.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/EconomicMapStorage.java index d6943f1508..0fce48416a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/EconomicMapStorage.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/EconomicMapStorage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -50,6 +50,7 @@ import com.oracle.graal.python.builtins.objects.common.ObjectHashMap.DictKey; import com.oracle.graal.python.builtins.objects.common.ObjectHashMap.MapCursor; import com.oracle.graal.python.builtins.objects.common.ObjectHashMap.PutNode; +import com.oracle.graal.python.builtins.objects.common.ObjectHashMap.PutUnsafeNode; import com.oracle.graal.python.lib.PyObjectHashNode; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -131,11 +132,15 @@ void clear() { map.clear(); } + public boolean mapIsEqualTo(ObjectHashMap other) { + return other == this.map; + } + public HashingStorage copy() { return new EconomicMapStorage(this.map, true); } - protected void setValueForAllKeys(VirtualFrame frame, Node inliningTarget, Object value, PutNode putNode, InlinedLoopConditionProfile loopProfile) { + protected void setValueForAllKeys(VirtualFrame frame, Node inliningTarget, Object value, PutUnsafeNode putNode, InlinedLoopConditionProfile loopProfile) { MapCursor cursor = map.getEntries(); final int size = map.size(); loopProfile.profileCounted(inliningTarget, size); @@ -147,26 +152,23 @@ protected void setValueForAllKeys(VirtualFrame frame, Node inliningTarget, Objec @TruffleBoundary public void putUncached(TruffleString key, Object value) { - ObjectHashMap.PutNode.putUncached(this.map, key, PyObjectHashNode.hash(key, HashCodeNode.getUncached()), value); - } - - private void putUncached(Object key, Object value) { - ObjectHashMap.PutNode.putUncached(this.map, key, PyObjectHashNode.executeUncached(key), value); + PutUnsafeNode.putUncached(this.map, key, PyObjectHashNode.hash(key, HashCodeNode.getUncached()), value); } - // Solves boot-order problem, do not use in normal code or during startup when __eq__ of - // builtins may not be properly set-up - public void putUncachedWithJavaEq(Object key, long keyHash, Object value) { - ObjectHashMap.PutNode.putUncachedWithJavaEq(this.map, key, keyHash, value); + @TruffleBoundary + public void putUncached(Object key, Object value) { + PutNode.getUncached().execute(null, null, this.map, key, PyObjectHashNode.executeUncached(key), value); } - public void putUncachedWithJavaEq(TruffleString key, Object value) { - putUncachedWithJavaEq(key, PyObjectHashNode.hash(key, HashCodeNode.getUncached()), value); + @TruffleBoundary + public void putUncached(int key, Object value) { + PutUnsafeNode.putUncached(this.map, key, PyObjectHashNode.hash(key), value); } - public void putUncachedWithJavaEq(String key, Object value) { + @TruffleBoundary + public void putUncached(String key, Object value) { TruffleString ts = toTruffleStringUncached(key); - putUncachedWithJavaEq(ts, value); + putUncached(ts, value); } private static void putAllUncached(LinkedHashMap map, EconomicMapStorage result) { @@ -212,7 +214,7 @@ public abstract static class EconomicMapSetStringKey extends SpecializedSetStrin @Specialization static void doIt(Node inliningTarget, HashingStorage self, TruffleString key, Object value, @Cached PyObjectHashNode hashNode, - @Cached PutNode putNode) { + @Cached PutUnsafeNode putNode) { putNode.put(null, inliningTarget, ((EconomicMapStorage) self).map, key, hashNode.execute(null, inliningTarget, key), value); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/ForeignHashingStorage.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/ForeignHashingStorage.java index 721a463be6..9aee630703 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/ForeignHashingStorage.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/ForeignHashingStorage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -48,7 +48,6 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode; import com.oracle.graal.python.nodes.object.IsForeignObjectNode; import com.oracle.graal.python.runtime.GilNode; @@ -121,7 +120,7 @@ static Object get(Node inliningTarget, ForeignHashingStorage storage, Object key @CachedLibrary(limit = "getCallSiteInlineCacheMaxDepth()") InteropLibrary interop, @Cached(inline = false) GilNode gil, @Cached(inline = false) PForeignToPTypeNode toPythonNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { var dict = storage.foreignDict; Object value; gil.release(true); @@ -130,7 +129,7 @@ static Object get(Node inliningTarget, ForeignHashingStorage storage, Object key } catch (UnknownKeyException e) { return null; } catch (UnsupportedMessageException e) { - throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.ATTR_S_OF_S_OBJ_IS_NOT_READABLE, key, dict); + throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.ATTR_S_OF_S_OBJ_IS_NOT_READABLE, key, dict); } finally { gil.acquire(); } @@ -150,21 +149,21 @@ public abstract static class PutNode extends PNodeWithContext { static void put(Node inliningTarget, ForeignHashingStorage storage, Object key, Object value, @CachedLibrary(limit = "getCallSiteInlineCacheMaxDepth()") InteropLibrary interop, @Cached(inline = false) GilNode gil, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { var dict = storage.foreignDict; gil.release(true); try { interop.writeHashEntry(dict, key, value); } catch (UnknownKeyException e) { - throw raiseNode.get(inliningTarget).raise(KeyError, new Object[]{key}); + throw raiseNode.raise(inliningTarget, KeyError, new Object[]{key}); } catch (UnsupportedMessageException e) { if (interop.isHashEntryExisting(dict, key)) { - throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.ATTR_S_OF_S_OBJ_IS_NOT_WRITABLE, key, dict); + throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.ATTR_S_OF_S_OBJ_IS_NOT_WRITABLE, key, dict); } else { - throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.ATTR_S_OF_S_OBJ_IS_NOT_INSERTABLE, key, dict); + throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.ATTR_S_OF_S_OBJ_IS_NOT_INSERTABLE, key, dict); } } catch (UnsupportedTypeException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.TYPE_P_NOT_SUPPORTED_BY_FOREIGN_OBJ, value); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TYPE_P_NOT_SUPPORTED_BY_FOREIGN_OBJ, value); } finally { gil.acquire(); } @@ -182,7 +181,7 @@ public abstract static class RemoveNode extends PNodeWithContext { static boolean remove(Node inliningTarget, ForeignHashingStorage storage, Object key, @CachedLibrary(limit = "getCallSiteInlineCacheMaxDepth()") InteropLibrary interop, @Cached(inline = false) GilNode gil, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { var dict = storage.foreignDict; gil.release(true); @@ -191,7 +190,7 @@ static boolean remove(Node inliningTarget, ForeignHashingStorage storage, Object } catch (UnknownKeyException e) { return false; } catch (UnsupportedMessageException e) { - throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.ATTR_S_OF_S_OBJ_IS_NOT_REMOVABLE, key, dict); + throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.ATTR_S_OF_S_OBJ_IS_NOT_REMOVABLE, key, dict); } finally { gil.acquire(); } @@ -233,7 +232,7 @@ static void clear(Node inliningTarget, ForeignHashingStorage storage, @CachedLibrary(limit = "getCallSiteInlineCacheMaxDepth()") InteropLibrary interop, @Cached(inline = false) GilNode gil, @CachedLibrary(limit = "getCallSiteInlineCacheMaxDepth()") InteropLibrary iteratorInterop, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { // We cannot just remove while iterating otherwise we get e.g. // ConcurrentModificationException with java.util.HashMap // So we remove keys by batch of 32 keys. @@ -262,13 +261,13 @@ static void clear(Node inliningTarget, ForeignHashingStorage storage, } } - private static void remove(Node inliningTarget, Object dict, Object key, InteropLibrary interop, Lazy raiseNode) { + private static void remove(Node inliningTarget, Object dict, Object key, InteropLibrary interop, PRaiseNode raiseNode) { try { interop.removeHashEntry(dict, key); } catch (UnknownKeyException e) { // already removed concurrently } catch (UnsupportedMessageException e) { - throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.ATTR_S_OF_S_OBJ_IS_NOT_REMOVABLE, key, dict); + throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.ATTR_S_OF_S_OBJ_IS_NOT_REMOVABLE, key, dict); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/FormatNodeBase.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/FormatNodeBase.java index c29dde81fc..23a122ad6d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/FormatNodeBase.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/FormatNodeBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,27 +40,23 @@ */ package com.oracle.graal.python.builtins.objects.common; -import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; +import com.oracle.graal.python.lib.PyObjectStrAsObjectNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; +@GenerateCached(false) public abstract class FormatNodeBase extends PythonBinaryClinicBuiltinNode { - @Override - protected ArgumentClinicProvider getArgumentClinic() { - // must be implemented here, because DSL creates a generated node for this class - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw new AbstractMethodError(); - } - // applies to all types: empty format string => use __str__ @Specialization(guards = "formatString.isEmpty()") public static Object formatEmptyString(VirtualFrame frame, Object self, @SuppressWarnings("unused") TruffleString formatString, - @Cached("create(Str)") LookupAndCallUnaryNode lookupAndCallNode) { - return lookupAndCallNode.executeObject(frame, self); + @Bind Node inliningTarget, + @Cached PyObjectStrAsObjectNode str) { + return str.execute(frame, inliningTarget, self); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingCollectionNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingCollectionNodes.java index 55c4644dbe..edd88d1e13 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingCollectionNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingCollectionNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -51,16 +51,18 @@ import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageIteratorKey; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageIteratorNext; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem; +import com.oracle.graal.python.builtins.objects.common.ObjectHashMap.PutUnsafeNode; import com.oracle.graal.python.builtins.objects.dict.DictNodes; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.dict.PDictView; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.builtins.objects.set.PBaseSet; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -121,8 +123,8 @@ abstract static class SetValueHashingStorageNode extends PNodeWithContext { @Specialization static HashingStorage doEconomicStorage(VirtualFrame frame, Node inliningTarget, EconomicMapStorage map, Object value, - @Cached ObjectHashMap.PutNode putNode, - @Cached InlinedLoopConditionProfile loopProfile) { + @Shared("putNode") @Cached PutUnsafeNode putNode, + @Shared("loopProfile") @Cached InlinedLoopConditionProfile loopProfile) { // We want to avoid calling __hash__() during map.put map.setValueForAllKeys(frame, inliningTarget, value, putNode, loopProfile); return map; @@ -134,14 +136,25 @@ static HashingStorage doGeneric(VirtualFrame frame, Node inliningTarget, Hashing @Cached HashingStorageSetItem setItem, @Cached HashingStorageGetIterator getIterator, @Cached HashingStorageIteratorNext itNext, - @Cached HashingStorageIteratorKey itKey) { + @Cached HashingStorageIteratorKey itKey, + @Shared("putNode") @Cached PutUnsafeNode putNode, + @Shared("loopProfile") @Cached InlinedLoopConditionProfile loopProfile) { HashingStorageIterator it = getIterator.execute(inliningTarget, map); - HashingStorage storage = map; while (itNext.execute(inliningTarget, map, it)) { - Object key = itKey.execute(inliningTarget, storage, it); - storage = setItem.execute(frame, inliningTarget, storage, key, value); + Object key = itKey.execute(inliningTarget, map, it); + HashingStorage newStorage = setItem.execute(frame, inliningTarget, map, key, value); + if (newStorage != map) { + // when the storage changes, the iterator state is not a reliable cursor + // anymore and we need to restart. + if (newStorage instanceof EconomicMapStorage mapStorage) { + mapStorage.setValueForAllKeys(frame, inliningTarget, value, putNode, loopProfile); + return mapStorage; + } else { + throw CompilerDirectives.shouldNotReachHere("We only generalize to EconomicMapStorage"); + } + } } - return storage; + return map; } protected static boolean isEconomicMapStorage(Object o) { @@ -150,42 +163,62 @@ protected static boolean isEconomicMapStorage(Object o) { } /** - * Gets clone of the keys of the storage with all values either set to given value or with no - * guarantees about the values if {@link PNone#NO_VALUE} is passed as {@code value}. + * Gets clone of the keys of the storage with all values set to given value or (when used to + * create a set or frozenset) to NO_VALUE. */ @GenerateInline(inlineByDefault = true) public abstract static class GetClonedHashingStorageNode extends PNodeWithContext { - public abstract HashingStorage execute(VirtualFrame frame, Node inliningTarget, Object iterator, Object value); + protected abstract HashingStorage execute(VirtualFrame frame, Node inliningTarget, Object iterator, Object value); + + /** + * Gets clone of the keys of the storage with all values either set to given value or, if + * that is PNone.NO_VALUE, all values set to PNone.NONE. Use this method to clone into a + * dict or other object where the values may be accessible from Python to avoid a) + * PNone.NO_VALUE leaking to Python. + */ + public final HashingStorage getForDictionaries(VirtualFrame frame, Node inliningTarget, Object iterator, Object value) { + return execute(frame, inliningTarget, iterator, value == PNone.NO_VALUE ? PNone.NONE : value); + } - public final HashingStorage doNoValue(VirtualFrame frame, Node inliningTarget, Object iterator) { + /** + * Gets a clone of the keys of the storage with all values set to NO_VALUE. This must be + * used *only* to create new storages for use in sets and frozensets where the values cannot + * be accessed from user code. + */ + public final HashingStorage getForSets(VirtualFrame frame, Node inliningTarget, Object iterator) { return execute(frame, inliningTarget, iterator, PNone.NO_VALUE); } - public final HashingStorage doNoValueCached(VirtualFrame frame, Object iterator) { + /** + * IMPORTANT: Only for sets and frozensets. + * + * @see #getForSets(VirtualFrame, Node, Object) + */ + public final HashingStorage getForSetsCached(VirtualFrame frame, Object iterator) { return execute(frame, null, iterator, PNone.NO_VALUE); } - @Specialization(guards = "isNoValue(value)") - static HashingStorage doHashingCollectionNoValue(Node inliningTarget, PHashingCollection other, @SuppressWarnings("unused") Object value, - @Shared("copyNode") @Cached HashingStorageCopy copyNode) { + // This for cloning sets (we come here from doNoValue or doNoValueCached). If we clone from + // some other PHashingCollection, we would hold on to keys in the sets, and if we were to + // clone for some other PHashingCollection (not PBaseSet), we might leak NO_VALUE into user + // code. + @Specialization(guards = "isNoValue(givenValue)") + static HashingStorage doSet(Node inliningTarget, PBaseSet other, @SuppressWarnings("unused") Object givenValue, + @Cached HashingStorageCopy copyNode) { return copyNode.execute(inliningTarget, other.getDictStorage()); } - @Specialization(guards = "isNoValue(value)") - static HashingStorage doPDictKeyViewNoValue(Node inliningTarget, PDictView.PDictKeysView other, Object value, - @Shared("copyNode") @Cached HashingStorageCopy copyNode) { - return copyNode.execute(inliningTarget, other.getWrappedStorage()); - } - - @Specialization(guards = "!isNoValue(value)") - static HashingStorage doHashingCollection(VirtualFrame frame, PHashingCollection other, Object value, + @Specialization(replaces = "doSet") + static HashingStorage doHashingCollection(VirtualFrame frame, PHashingCollection other, Object givenValue, @Shared @Cached(inline = false) GetClonedHashingCollectionNode hashingCollectionNode) { + Object value = givenValue == PNone.NO_VALUE ? PNone.NONE : givenValue; return hashingCollectionNode.execute(frame, other.getDictStorage(), value); } - @Specialization(guards = "!isNoValue(value)") - static HashingStorage doPDictView(VirtualFrame frame, PDictView.PDictKeysView other, Object value, + @Specialization + static HashingStorage doPDictView(VirtualFrame frame, PDictView.PDictKeysView other, Object givenValue, @Shared @Cached(inline = false) GetClonedHashingCollectionNode hashingCollectionNode) { + Object value = givenValue == PNone.NO_VALUE ? PNone.NONE : givenValue; return hashingCollectionNode.execute(frame, other.getWrappedStorage(), value); } @@ -215,8 +248,7 @@ static HashingStorage doString(Node inliningTarget, Object strObj, Object value, @InliningCutoff static HashingStorage doIterable(VirtualFrame frame, Node inliningTarget, Object other, Object value, @Cached PyObjectGetIter getIter, - @Cached(inline = false) GetNextNode nextNode, - @Cached IsBuiltinObjectProfile errorProfile, + @Cached PyIterNextNode nextNode, @Exclusive @Cached HashingStorageSetItem setStorageItem) { HashingStorage curStorage = EmptyStorage.INSTANCE; Object iterator = getIter.execute(frame, inliningTarget, other); @@ -224,9 +256,8 @@ static HashingStorage doIterable(VirtualFrame frame, Node inliningTarget, Object while (true) { Object key; try { - key = nextNode.execute(frame, iterator); - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); + key = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { return curStorage; } curStorage = setStorageItem.execute(frame, inliningTarget, curStorage, key, val); @@ -259,7 +290,7 @@ static HashingStorage doHashingCollection(VirtualFrame frame, HashingStorage oth * Returns {@link HashingStorage} with the same keys as the given iterator. There is no * guarantee about the values! * - * @see DictNodes.GetDictStorageNode + * @see com.oracle.graal.python.builtins.objects.dict.DictNodes.GetDictStorageNode */ @GenerateInline(inlineByDefault = true) public abstract static class GetSetStorageNode extends PNodeWithContext { @@ -284,7 +315,7 @@ static HashingStorage doPDictView(PDictView.PDictKeysView other) { @InliningCutoff static HashingStorage doGeneric(VirtualFrame frame, Node inliningTarget, Object other, @Cached GetClonedHashingStorageNode getHashingStorageNode) { - return getHashingStorageNode.doNoValue(frame, inliningTarget, other); + return getHashingStorageNode.getForSets(frame, inliningTarget, other); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingStorage.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingStorage.java index 0da6b4a46f..9f5ab122b3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingStorage.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingStorage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,11 +40,9 @@ */ package com.oracle.graal.python.builtins.objects.common; -import static com.oracle.graal.python.builtins.objects.function.PKeyword.EMPTY_KEYWORDS; import static com.oracle.graal.python.nodes.SpecialMethodNames.T_KEYS; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; -import static com.oracle.graal.python.util.PythonUtils.EMPTY_OBJECT_ARRAY; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.common.HashingStorageFactory.InitNodeGen; @@ -54,6 +52,8 @@ import com.oracle.graal.python.builtins.objects.common.SequenceNodes.LenNode; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.function.PKeyword; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyObjectGetIter; @@ -61,9 +61,8 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; import com.oracle.graal.python.nodes.builtins.ListNodes.FastConstructListNode; -import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode; +import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.exception.PException; @@ -102,20 +101,20 @@ static HashingStorage doKeywords(@SuppressWarnings("unused") PNone iterable, PKe return new KeywordsStorage(kwargs); } - @Specialization(guards = {"isEmpty(kwargs)", "hasBuiltinDictIter(inliningTarget, dict, getClassNode, lookupIter)"}) + @Specialization(guards = {"isEmpty(kwargs)", "hasBuiltinDictIter(inliningTarget, dict, getClassNode, getSlots)"}) static HashingStorage doPDict(PDict dict, @SuppressWarnings("unused") PKeyword[] kwargs, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode.GetPythonObjectClassNode getClassNode, - @SuppressWarnings("unused") @Shared @Cached(parameters = "Iter") LookupCallableSlotInMRONode lookupIter, + @SuppressWarnings("unused") @Shared @Cached GetCachedTpSlotsNode getSlots, @Shared @Cached HashingStorageCopy copyNode) { return copyNode.execute(inliningTarget, dict.getDictStorage()); } - @Specialization(guards = {"!isEmpty(kwargs)", "hasBuiltinDictIter(inliningTarget, dict, getClassNode, lookupIter)"}) + @Specialization(guards = {"!isEmpty(kwargs)", "hasBuiltinDictIter(inliningTarget, dict, getClassNode, getSlots)"}) static HashingStorage doPDictKwargs(VirtualFrame frame, PDict dict, PKeyword[] kwargs, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode.GetPythonObjectClassNode getClassNode, - @SuppressWarnings("unused") @Shared @Cached(parameters = "Iter") LookupCallableSlotInMRONode lookupIter, + @SuppressWarnings("unused") @Shared @Cached GetCachedTpSlotsNode getSlots, @Shared @Cached HashingStorageCopy copyNode, @Exclusive @Cached HashingStorageAddAllToOther addAllToOther) { HashingStorage iterableDictStorage = dict.getDictStorage(); @@ -208,15 +207,20 @@ public abstract static class ObjectToArrayPairNode extends PNodeWithContext { static ArrayBuilder partialMerge(VirtualFrame frame, Object mapping, Object keyAttr, @Bind("this") Node inliningTarget, @Shared @Cached PyObjectGetIter getIter, - @Shared @Cached(neverDefault = false) PyIterNextNode nextNode, + @Shared @Cached PyIterNextNode nextNode, @Shared @Cached PyObjectGetItem getItemNode, - @Cached CallVarargsMethodNode callKeysMethod) { + @Cached CallNode callKeysMethod) { // We don't need to pass self as the attribute object has it already. - Object keysIterable = callKeysMethod.execute(frame, keyAttr, EMPTY_OBJECT_ARRAY, EMPTY_KEYWORDS); + Object keysIterable = callKeysMethod.execute(frame, keyAttr); Object keysIt = getIter.execute(frame, inliningTarget, keysIterable); ArrayBuilder elements = new ArrayBuilder<>(); - Object keyObj; - while ((keyObj = nextNode.execute(frame, keysIt)) != null) { + while (true) { + Object keyObj; + try { + keyObj = nextNode.execute(frame, inliningTarget, keysIt); + } catch (IteratorExhausted e) { + break; + } Object valueObj = getItemNode.execute(frame, inliningTarget, mapping, keyObj); elements.add(new KeyValue(keyObj, valueObj)); } @@ -228,19 +232,24 @@ static ArrayBuilder partialMerge(VirtualFrame frame, Object mapping, O static ArrayBuilder partialMergeFromSeq2(VirtualFrame frame, Object iterable, @SuppressWarnings("unused") PNone keyAttr, @Bind("this") Node inliningTarget, @Shared @Cached PyObjectGetIter getIter, - @Shared @Cached(neverDefault = false) PyIterNextNode nextNode, + @Shared @Cached PyIterNextNode nextNode, @Shared @Cached PyObjectGetItem getItemNode, @Cached FastConstructListNode createListNode, @Cached LenNode seqLenNode, - @Cached PRaiseNode.Lazy raise, + @Cached PRaiseNode raise, @Cached InlinedConditionProfile lengthTwoProfile, @Cached IsBuiltinObjectProfile isTypeErrorProfile) throws PException { Object it = getIter.execute(frame, inliningTarget, iterable); ArrayBuilder elements = new ArrayBuilder<>(); - Object next; int len = 2; try { - while ((next = nextNode.execute(frame, it)) != null) { + while (true) { + Object next; + try { + next = nextNode.execute(frame, inliningTarget, it); + } catch (IteratorExhausted e) { + break; + } PSequence element = createListNode.execute(frame, inliningTarget, next); assert element != null; // This constructs a new list using the builtin type. So, the object cannot @@ -248,7 +257,7 @@ static ArrayBuilder partialMergeFromSeq2(VirtualFrame frame, Object it len = seqLenNode.execute(inliningTarget, element); if (lengthTwoProfile.profile(inliningTarget, len != 2)) { - throw raise.get(inliningTarget).raise(ValueError, ErrorMessages.DICT_UPDATE_SEQ_ELEM_HAS_LENGTH_2_REQUIRED, elements.size(), len); + throw raise.raise(inliningTarget, ValueError, ErrorMessages.DICT_UPDATE_SEQ_ELEM_HAS_LENGTH_2_REQUIRED, elements.size(), len); } Object key = getItemNode.execute(frame, inliningTarget, element, 0); Object value = getItemNode.execute(frame, inliningTarget, element, 1); @@ -257,7 +266,7 @@ static ArrayBuilder partialMergeFromSeq2(VirtualFrame frame, Object it } catch (PException e) { if (!lengthTwoProfile.profile(inliningTarget, len != 2) && isTypeErrorProfile.profileException(inliningTarget, e, TypeError)) { - throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.CANNOT_CONVERT_DICT_UPDATE_SEQ, elements.size()); + throw raise.raise(inliningTarget, TypeError, ErrorMessages.CANNOT_CONVERT_DICT_UPDATE_SEQ, elements.size()); } throw e; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingStorageNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingStorageNodes.java index 06a19bd600..18034362c9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingStorageNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingStorageNodes.java @@ -40,6 +40,9 @@ */ package com.oracle.graal.python.builtins.objects.common; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; +import static com.oracle.graal.python.nodes.ErrorMessages.FOREIGN_OBJ_ISNT_REVERSE_ITERABLE; + import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage.EconomicMapSetStringKey; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodesFactory.CachedHashingStorageGetItemNodeGen; @@ -59,6 +62,7 @@ import com.oracle.graal.python.builtins.objects.common.HashingStorageNodesFactory.HashingStorageSetItemWithHashNodeGen; import com.oracle.graal.python.builtins.objects.common.KeywordsStorage.GetKeywordsStorageItemNode; import com.oracle.graal.python.builtins.objects.common.ObjectHashMap.PutNode; +import com.oracle.graal.python.builtins.objects.common.ObjectHashMap.PutUnsafeNode; import com.oracle.graal.python.lib.PyObjectHashNode; import com.oracle.graal.python.lib.PyObjectRichCompareBool; import com.oracle.graal.python.lib.PyUnicodeCheckExactNode; @@ -98,9 +102,6 @@ import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile; import com.oracle.truffle.api.strings.TruffleString; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; -import static com.oracle.graal.python.nodes.ErrorMessages.FOREIGN_OBJ_ISNT_REVERSE_ITERABLE; - public class HashingStorageNodes { public abstract static class HashingStorageGuards { @@ -121,7 +122,7 @@ public static boolean mayHaveSideEffectingEq(HashingStorage storage) { public static boolean mayHaveSideEffects(PHashingCollection wrapper) { HashingStorage s = wrapper.getDictStorage(); - return !(s instanceof EconomicMapStorage && ((EconomicMapStorage) s).map.hasSideEffect()); + return s instanceof EconomicMapStorage && ((EconomicMapStorage) s).map.hasSideEffectingKeys(); } } @@ -252,7 +253,7 @@ abstract static class SpecializedSetStringKey extends Node { public abstract void execute(Node inliningTarget, HashingStorage self, TruffleString key, Object value); } - static EconomicMapStorage dynamicObjectStorageToEconomicMap(Node inliningTarget, DynamicObjectStorage s, DynamicObjectLibrary dylib, PyObjectHashNode hashNode, PutNode putNode) { + static EconomicMapStorage dynamicObjectStorageToEconomicMap(Node inliningTarget, DynamicObjectStorage s, DynamicObjectLibrary dylib, PyObjectHashNode hashNode, PutUnsafeNode putNode) { // TODO: shouldn't we invalidate all MRO assumptions in this case? DynamicObject store = s.store; EconomicMapStorage result = EconomicMapStorage.create(dylib.getShape(store).getPropertyCount()); @@ -287,24 +288,16 @@ public final HashingStorage executeCached(Frame frame, HashingStorage self, Obje @Specialization static HashingStorage economicMap(Frame frame, Node inliningTarget, EconomicMapStorage self, Object key, long keyHash, Object value, - @Exclusive @Cached PyUnicodeCheckExactNode isBuiltinString, - @Exclusive @Cached ObjectHashMap.PutNode putNode) { + @Exclusive @Cached PutNode putNode) { putNode.execute(frame, inliningTarget, self.map, key, keyHash, value); - if (!self.map.hasSideEffect() && !isBuiltinString.execute(inliningTarget, key)) { - self.map.setSideEffectingKeysFlag(); - } return self; } @Specialization static HashingStorage empty(Frame frame, Node inliningTarget, @SuppressWarnings("unused") EmptyStorage self, Object key, long keyHash, Object value, - @Exclusive @Cached PyUnicodeCheckExactNode isBuiltinString, - @Exclusive @Cached ObjectHashMap.PutNode putNode) { + @Exclusive @Cached PutNode putNode) { EconomicMapStorage storage = EconomicMapStorage.create(1); putNode.execute(frame, inliningTarget, storage.map, key, keyHash, value); - if (!isBuiltinString.execute(inliningTarget, key)) { - storage.map.setSideEffectingKeysFlag(); - } return storage; } @@ -335,17 +328,16 @@ static HashingStorage dom(Frame frame, Node inliningTarget, DynamicObjectStorage @Specialization @InliningCutoff static HashingStorage keywords(Frame frame, Node inliningTarget, KeywordsStorage self, Object key, long keyHash, Object value, - @Exclusive @Cached PyUnicodeCheckExactNode isBuiltinString, - @Exclusive @Cached ObjectHashMap.PutNode putNode, + @Exclusive @Cached PutNode putNode, @Cached EconomicMapSetStringKey specializedPutNode) { // TODO: do we want to try DynamicObjectStorage if the key is a string? EconomicMapStorage result = EconomicMapStorage.create(self.length()); self.addAllTo(inliningTarget, result, specializedPutNode); - return economicMap(frame, inliningTarget, result, key, keyHash, value, isBuiltinString, putNode); + return economicMap(frame, inliningTarget, result, key, keyHash, value, putNode); } @Specialization - static HashingStorage foreign(Frame frame, Node inliningTarget, ForeignHashingStorage self, Object key, long keyHash, Object value, + static HashingStorage foreign(Node inliningTarget, ForeignHashingStorage self, Object key, long keyHash, Object value, @Cached ForeignHashingStorage.PutNode putNode) { putNode.execute(inliningTarget, self, key, value); return self; @@ -373,8 +365,9 @@ static HashingStorage domStringKey(Node inliningTarget, DynamicObjectStorage sel static HashingStorage domTransition(Frame frame, Node inliningTarget, DynamicObjectStorage self, Object key, @SuppressWarnings("unused") long keyHash, Object value, @SuppressWarnings("unused") boolean transition, DynamicObjectLibrary dylib, @Cached PyObjectHashNode hashNode, - @Cached ObjectHashMap.PutNode putNode) { - EconomicMapStorage result = dynamicObjectStorageToEconomicMap(inliningTarget, self, dylib, hashNode, putNode); + @Cached PutUnsafeNode putUnsafeNode, + @Cached PutNode putNode) { + EconomicMapStorage result = dynamicObjectStorageToEconomicMap(inliningTarget, self, dylib, hashNode, putUnsafeNode); putNode.execute(frame, inliningTarget, result.map, key, keyHash, value); return result; } @@ -415,27 +408,22 @@ public final HashingStorage execute(Node inliningTarget, HashingStorage self, Tr @Specialization static HashingStorage economicMap(Frame frame, Node inliningTarget, EconomicMapStorage self, Object key, Object value, - @Exclusive @Cached PyUnicodeCheckExactNode isBuiltinString, @Exclusive @Cached PyObjectHashNode hashNode, - @Exclusive @Cached ObjectHashMap.PutNode putNode) { + @Exclusive @Cached PutNode putNode) { putNode.execute(frame, inliningTarget, self.map, key, hashNode.execute(frame, inliningTarget, key), value); - if (!self.map.hasSideEffect() && !isBuiltinString.execute(inliningTarget, key)) { - self.map.setSideEffectingKeysFlag(); - } return self; } @Specialization static HashingStorage empty(Frame frame, Node inliningTarget, @SuppressWarnings("unused") EmptyStorage self, Object key, Object value, - @Exclusive @Cached PyUnicodeCheckExactNode isBuiltinString, @Exclusive @Cached PyObjectHashNode hashNode, - @Exclusive @Cached ObjectHashMap.PutNode putNode) { + @Exclusive @Cached PutNode putNode) { // The ObjectHashMap.PutNode is @Exclusive because profiles for a put into a freshly new // allocated map can be quite different to profiles in the other situations when we are // putting into a map that already has or will have some more items in it // It is also @Cached(inline = false) because inlining it triggers GR-44836 // TODO: do we want to try DynamicObjectStorage if the key is a string? - return economicMap(frame, inliningTarget, EconomicMapStorage.create(1), key, value, isBuiltinString, hashNode, putNode); + return economicMap(frame, inliningTarget, EconomicMapStorage.create(1), key, value, hashNode, putNode); } @Specialization(guards = "!self.shouldTransitionOnPut()") @@ -466,13 +454,12 @@ static HashingStorage dom(Frame frame, Node inliningTarget, DynamicObjectStorage @InliningCutoff static HashingStorage keywords(Frame frame, Node inliningTarget, KeywordsStorage self, Object key, Object value, @Exclusive @Cached PyObjectHashNode hashNode, - @Exclusive @Cached PyUnicodeCheckExactNode isBuiltinString, - @Exclusive @Cached ObjectHashMap.PutNode putNode, + @Exclusive @Cached PutNode putNode, @Cached EconomicMapSetStringKey specializedPutNode) { // TODO: do we want to try DynamicObjectStorage if the key is a string? EconomicMapStorage result = EconomicMapStorage.create(self.length()); self.addAllTo(inliningTarget, result, specializedPutNode); - return economicMap(frame, inliningTarget, result, key, value, isBuiltinString, hashNode, putNode); + return economicMap(frame, inliningTarget, result, key, value, hashNode, putNode); } @Specialization @@ -504,8 +491,9 @@ static HashingStorage domStringKey(Node inliningTarget, DynamicObjectStorage sel static HashingStorage domTransition(Frame frame, Node inliningTarget, DynamicObjectStorage self, Object key, Object value, @SuppressWarnings("unused") boolean transition, DynamicObjectLibrary dylib, @Cached PyObjectHashNode hashNode, - @Cached ObjectHashMap.PutNode putNode) { - EconomicMapStorage result = dynamicObjectStorageToEconomicMap(inliningTarget, self, dylib, hashNode, putNode); + @Cached PutUnsafeNode putUnsafeNode, + @Cached PutNode putNode) { + EconomicMapStorage result = dynamicObjectStorageToEconomicMap(inliningTarget, self, dylib, hashNode, putUnsafeNode); putNode.execute(frame, inliningTarget, result.map, key, hashNode.execute(frame, inliningTarget, key), value); return result; } @@ -908,9 +896,9 @@ static HashingStorageIterator keywords(@SuppressWarnings("unused") KeywordsStora @Specialization static HashingStorageIterator foreign(@SuppressWarnings("unused") ForeignHashingStorage self, - @Cached(inline = false) PRaiseNode raiseNode) { + @Bind("this") Node inliningTarget) { // InteropLibrary does not provide a reverse HashEntriesIterator - throw raiseNode.raise(TypeError, FOREIGN_OBJ_ISNT_REVERSE_ITERABLE); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, FOREIGN_OBJ_ISNT_REVERSE_ITERABLE); } } @@ -1039,9 +1027,9 @@ static boolean foreign(ForeignHashingStorage self, HashingStorageIterator it, @Specialization(guards = "it.isReverse") static boolean foreignReverse(@SuppressWarnings("unused") ForeignHashingStorage self, HashingStorageIterator it, - @Cached(inline = false) PRaiseNode raiseNode) { + @Bind("this") Node inliningTarget) { // InteropLibrary does not provide a reverse HashEntriesIterator - throw raiseNode.raise(TypeError, FOREIGN_OBJ_ISNT_REVERSE_ITERABLE); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, FOREIGN_OBJ_ISNT_REVERSE_ITERABLE); } } @@ -1247,7 +1235,7 @@ static boolean doIt(Frame frame, Node inliningTarget, HashingStorage aStorage, H @Cached HashingStorageIteratorKey aIterKey, @Cached HashingStorageIteratorValue aIterValue, @Cached HashingStorageIteratorKeyHash aIterHash, - @Cached PyObjectRichCompareBool.EqNode eqNode, + @Cached PyObjectRichCompareBool eqNode, @Cached InlinedLoopConditionProfile loopProfile, @Cached InlinedLoopConditionProfile earlyExitProfile) { if (lenANode.execute(inliningTarget, aStorage) != lenBNode.execute(inliningTarget, bStorage)) { @@ -1265,7 +1253,7 @@ static boolean doIt(Frame frame, Node inliningTarget, HashingStorage aStorage, H long aHash = aIterHash.execute(frame, inliningTarget, aStorage, aIter); Object bValue = getBNode.execute(frame, inliningTarget, bStorage, aKey, aHash); Object aValue = aIterValue.execute(inliningTarget, aStorage, aIter); - if (earlyExitProfile.profile(inliningTarget, !(bValue == null || !eqNode.compare(frame, inliningTarget, bValue, aValue)))) { + if (earlyExitProfile.profile(inliningTarget, !(bValue == null || !eqNode.executeEq(frame, inliningTarget, bValue, aValue)))) { // if->continue such that the "true" count of the profile represents the // loop iterations and the "false" count the early exit continue; @@ -1365,7 +1353,7 @@ public abstract static class HashingStorageXorCallback extends HashingStorageFor @Specialization static ResultAndOther doGeneric(Frame frame, Node inliningTarget, HashingStorage storage, HashingStorageIterator it, ResultAndOther acc, - @Cached ObjectHashMap.PutNode putResultNode, + @Cached PutNode putResultNode, @Cached HashingStorageGetItemWithHash getFromOther, @Cached HashingStorageIteratorKey iterKey, @Cached HashingStorageIteratorValue iterValue, @@ -1417,7 +1405,7 @@ public abstract static class HashingStorageIntersectCallback extends HashingStor @Specialization static ResultAndOther doGeneric(Frame frame, Node inliningTarget, HashingStorage storage, HashingStorageIterator it, ResultAndOther acc, - @Cached ObjectHashMap.PutNode putResultNode, + @Cached PutNode putResultNode, @Cached HashingStorageGetItemWithHash getFromOther, @Cached HashingStorageIteratorKey iterKey, @Cached HashingStorageIteratorKeyHash iterHash) { @@ -1463,7 +1451,7 @@ public abstract static class HashingStorageDiffCallback extends HashingStorageFo @Specialization static ResultAndOther doGeneric(Frame frame, Node inliningTarget, HashingStorage storage, HashingStorageIterator it, ResultAndOther acc, - @Cached ObjectHashMap.PutNode putResultNode, + @Cached PutNode putResultNode, @Cached HashingStorageGetItemWithHash getFromOther, @Cached HashingStorageIteratorKey iterKey, @Cached HashingStorageIteratorKeyHash iterHash, @@ -1530,17 +1518,17 @@ static HashingStorage doGeneric(Frame frame, Node inliningTarget, HashingStorage @GenerateInline @GenerateCached(false) @ImportStatic({PGuards.class}) - public abstract static class HashingStorageCompareKeys extends Node { - public abstract int execute(Frame frame, Node inliningTarget, HashingStorage a, HashingStorage b); + public abstract static class IsKeysSubset extends Node { + public abstract boolean execute(Frame frame, Node inliningTarget, HashingStorage a, HashingStorage b); @Specialization(guards = "aStorage == bStorage") @SuppressWarnings("unused") - static int doSame(HashingStorage aStorage, HashingStorage bStorage) { - return 0; + static boolean doSame(HashingStorage aStorage, HashingStorage bStorage) { + return true; } @Specialization(guards = "aStorage != bStorage") - static int doGeneric(Frame frame, Node inliningTarget, HashingStorage aStorage, HashingStorage bStorage, + static boolean doGeneric(Frame frame, Node inliningTarget, HashingStorage aStorage, HashingStorage bStorage, @Cached HashingStorageLen aLenNode, @Cached HashingStorageLen bLenNode, @Cached HashingStorageForEach forEachA, @@ -1548,18 +1536,14 @@ static int doGeneric(Frame frame, Node inliningTarget, HashingStorage aStorage, int aLen = aLenNode.execute(inliningTarget, aStorage); int bLen = bLenNode.execute(inliningTarget, bStorage); if (aLen > bLen) { - return 1; + return false; } try { forEachA.execute(frame, inliningTarget, aStorage, callback, bStorage); } catch (AbortIteration ignored) { - return 1; - } - if (aLen == bLen) { - return 0; - } else { - return -1; + return false; } + return true; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/IndexNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/IndexNodes.java index a651a07fa3..88544ace1f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/IndexNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/IndexNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,7 +46,6 @@ import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; import com.oracle.graal.python.util.OverflowException; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; @@ -193,7 +192,7 @@ abstract static class NormalizeIndexWithBoundsCheckNode extends NormalizeIndexCu static int doInt(int index, int length, TruffleString errorMessage, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile negativeIndexProfile, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { int normalizedIndex = index; if (negativeIndexProfile.profile(inliningTarget, normalizedIndex < 0)) { normalizedIndex += length; @@ -205,7 +204,7 @@ static int doInt(int index, int length, TruffleString errorMessage, @Specialization static int doBool(boolean bIndex, int length, TruffleString errorMessage, @Bind("this") Node inliningTarget, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { int index = PInt.intValue(bIndex); checkBounds(inliningTarget, raiseNode, errorMessage, index, length); return index; @@ -215,7 +214,7 @@ static int doBool(boolean bIndex, int length, TruffleString errorMessage, static int doLong(long lIndex, int length, TruffleString errorMessage, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile negativeIndexProfile, - @Shared @Cached PRaiseNode.Lazy raiseNode) throws OverflowException { + @Shared @Cached PRaiseNode raiseNode) throws OverflowException { int index = PInt.intValueExact(lIndex); return doInt(index, length, errorMessage, inliningTarget, negativeIndexProfile, raiseNode); } @@ -224,11 +223,11 @@ static int doLong(long lIndex, int length, TruffleString errorMessage, int doLongOvf(long index, int length, TruffleString errorMessage, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile negativeIndexProfile, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { try { return doLong(index, length, errorMessage, inliningTarget, negativeIndexProfile, raiseNode); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raiseNumberTooLarge(PythonBuiltinClassType.IndexError, index); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.IndexError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, index); } } @@ -236,7 +235,7 @@ int doLongOvf(long index, int length, TruffleString errorMessage, static int doPInt(PInt index, int length, TruffleString errorMessage, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile negativeIndexProfile, - @Shared @Cached PRaiseNode.Lazy raiseNode) throws OverflowException { + @Shared @Cached PRaiseNode raiseNode) throws OverflowException { int idx = index.intValueExact(); return doInt(idx, length, errorMessage, inliningTarget, negativeIndexProfile, raiseNode); } @@ -245,11 +244,11 @@ static int doPInt(PInt index, int length, TruffleString errorMessage, int doPIntOvf(PInt index, int length, TruffleString errorMessage, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile negativeIndexProfile, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { try { return doPInt(index, length, errorMessage, inliningTarget, negativeIndexProfile, raiseNode); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raiseNumberTooLarge(PythonBuiltinClassType.IndexError, index); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.IndexError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, index); } } @@ -257,7 +256,7 @@ int doPIntOvf(PInt index, int length, TruffleString errorMessage, static long doLongLong(long lIndex, long length, TruffleString errorMessage, @Bind("this") Node inliningTarget, @Shared @Cached InlinedConditionProfile negativeIndexProfile, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { long normalizedIndex = lIndex; if (negativeIndexProfile.profile(inliningTarget, normalizedIndex < 0)) { normalizedIndex += length; @@ -306,7 +305,7 @@ static int doLongOvf(long index, int length, TruffleString errorMessage, try { return doLong(index, length, errorMessage, inliningTarget, negativeIndexProfile); } catch (OverflowException e) { - throw raiseNode.raiseNumberTooLarge(PythonBuiltinClassType.IndexError, index); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.IndexError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, index); } } @@ -326,7 +325,7 @@ static int doPIntOvf(PInt index, int length, TruffleString errorMessage, try { return doPInt(index, length, errorMessage, inliningTarget, negativeIndexProfile); } catch (OverflowException e) { - throw raiseNode.raiseNumberTooLarge(PythonBuiltinClassType.IndexError, index); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.IndexError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, index); } } @@ -342,26 +341,26 @@ static long doLongLong(long index, long length, @SuppressWarnings("unused") Truf } } - public static void checkBounds(Node inliningTarget, PRaiseNode.Lazy raiseNode, TruffleString errorMessage, int idx, int length) { + public static void checkBounds(Node inliningTarget, PRaiseNode raiseNode, TruffleString errorMessage, int idx, int length) { if (idx < 0 || idx >= length) { raiseIndexError(inliningTarget, errorMessage, raiseNode); } } - public static void checkBounds(Node inliningTarget, PRaiseNode.Lazy raiseNode, TruffleString errorMessage, long idx, long length) { + public static void checkBounds(Node inliningTarget, PRaiseNode raiseNode, TruffleString errorMessage, long idx, long length) { if (idx < 0 || idx >= length) { raiseIndexError(inliningTarget, errorMessage, raiseNode); } } - public static void checkBounds(Node inliningTarget, PRaiseNode.Lazy raiseNode, TruffleString errorMessage, int idx, long length) { + public static void checkBounds(Node inliningTarget, PRaiseNode raiseNode, TruffleString errorMessage, int idx, long length) { if (idx < 0 || idx >= length) { raiseIndexError(inliningTarget, errorMessage, raiseNode); } } @InliningCutoff - private static void raiseIndexError(Node inliningTarget, TruffleString errorMessage, Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.IndexError, errorMessage); + private static void raiseIndexError(Node inliningTarget, TruffleString errorMessage, PRaiseNode raiseNode) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.IndexError, errorMessage); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/KeywordsStorage.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/KeywordsStorage.java index 39f4671f52..cdee12929c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/KeywordsStorage.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/KeywordsStorage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -68,7 +68,7 @@ public class KeywordsStorage extends HashingStorage { final PKeyword[] keywords; - protected KeywordsStorage(PKeyword[] keywords) { + public KeywordsStorage(PKeyword[] keywords) { this.keywords = keywords; } @@ -141,12 +141,12 @@ static Object pstring(Node inliningTarget, KeywordsStorage self, PString key, @S static Object notString(Frame frame, Node inliningTarget, KeywordsStorage self, Object key, long hashIn, @SuppressWarnings("unused") @Exclusive @Cached PyUnicodeCheckExactNode isBuiltinString, @Cached PyObjectHashNode hashNode, - @Cached PyObjectRichCompareBool.EqNode eqNode) { + @Cached PyObjectRichCompareBool eqNode) { long hash = hashIn == -1 ? hashNode.execute(frame, inliningTarget, key) : hashIn; for (int i = 0; i < self.keywords.length; i++) { TruffleString currentKey = self.keywords[i].getName(); long keyHash = hashNode.execute(frame, inliningTarget, currentKey); - if (keyHash == hash && eqNode.compare(frame, inliningTarget, key, currentKey)) { + if (keyHash == hash && eqNode.executeEq(frame, inliningTarget, key, currentKey)) { return self.keywords[i].getValue(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/ObjectHashMap.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/ObjectHashMap.java index 3bff0b7c7e..5ec9b1c41f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/ObjectHashMap.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/ObjectHashMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,21 +44,21 @@ import java.util.Arrays; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass; -import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; +import com.oracle.graal.python.builtins.objects.common.ObjectHashMapFactory.IsSideEffectingKeyNodeGen; +import com.oracle.graal.python.builtins.objects.common.ObjectHashMapFactory.PutNodeGen; +import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.lib.PyObjectRichCompareBool; -import com.oracle.graal.python.lib.PyObjectRichCompareBool.EqNode; +import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.nodes.LoopNode; @@ -70,7 +70,7 @@ /** * Generic dictionary/set backing storage implementation. - * + *

    * The basic algorithm is hash table with open addressing for collision resolution. For that we need * to have a fixed order of indexes to probe if collision happens. Simple implementations use linear * search (+/-1) from the bucket where the collision happened. We use the same more advanced scheme @@ -79,7 +79,7 @@ * * j = ((5*j) + 1) mod N^2 * - * + *

    * generates all numbers from 0 to (N^2)-1, but not in linear order, i.e., for j=1, N=3, we get: 1 6 * 7 4 5 2 3 0. In our case we set j to the index of the bucket that has the collision. To make this * scheme also dependent on the higher bits of the hash, we use this formula (also like CPython): @@ -88,29 +88,29 @@ * perturb >>= PERTURB_SHIFT * j = ((5*j) + perturb + 1) mod N^2 * - * + *

    * Which is not guaranteed to generate numbers from 0 to (N^2)-1 in general, but when the perturb * value is shifted often enough, it becomes 0, and then we're effectively using the original * version of the recurrence that does guarantee that. - * + *

    * Additionally, we use the same trick as PyPy/CPython: there is one sparse array, which is the * actual hash table, but it does not contain the entries, it contains indices into compact arrays * with hashes and keys and values. This not only should be memory efficient and cache friendly, but * it preserves the insertion order, which is a requirement. - * + *

    * On top of the PyPy/CPython design: we use the highest bit in the indices stored in the sparse * array to indicate whether given bucket participates in some collisions chain. When searching * through a collision chain, we can stop at items that do not have this bit set. The practical * implications of this is that for close to full maps, lookups of items that are not present in the * map are faster, because we can terminate the collisions chain chasing earlier. - * + *

    * Notable use case that does not (yet) work well with this approach: repeated insertion and removal * of the same key. This keeps on adding dummy entries when removing the entry and creating long * collisions chains that the insertion needs to follow to find a free slot. This all repeats until * the insertion concludes that the map is too full and rehashes it, in this case actually not * growing it, but just removing the dummy entries. The same seems to happen on CPython also, but * can be improved. - * + *

    * Areas for future improvements: *

      *
    • Use byte[] array for the sparse indices array and determine the size of an index according to @@ -204,8 +204,9 @@ private static int unwrapIndex(int value) { boolean hasSideEffectingKeys; public ObjectHashMap(int capacity, boolean hasSideEffects) { + int allocateSize; if (capacity <= INITIAL_INDICES_SIZE) { - allocateData(INITIAL_INDICES_SIZE); + allocateSize = INITIAL_INDICES_SIZE; } else { // We need the hash table of this size, in order to accommodate "capacity" many entries int indicesCapacity = capacity + (capacity / 3); @@ -216,13 +217,14 @@ public ObjectHashMap(int capacity, boolean hasSideEffects) { // reach the memory limit. We'd fail on the memory limit earlier -> difference in // behavior, so we take it easy if the requested size is too large. Maybe we should // rather revisit all such callsites instead of fixing this here... - allocateData(MAX_PREALLOCATED_INDICES_SIZE); + allocateSize = MAX_PREALLOCATED_INDICES_SIZE; } else { int pow2 = getNextPow2(indicesCapacity); assert pow2 > INITIAL_INDICES_SIZE; - allocateData(pow2); + allocateSize = pow2; } } + allocateData(allocateSize); hasSideEffectingKeys = hasSideEffects; } @@ -249,10 +251,6 @@ private void allocateData(int newSize) { keysAndValues = new Object[usableSize * 2]; } - public void setSideEffectingKeysFlag() { - hasSideEffectingKeys = true; - } - public void clear() { size = 0; usedHashes = 0; @@ -276,7 +274,7 @@ public MapCursor getEntries() { return new MapCursor(); } - public boolean hasSideEffect() { + public boolean hasSideEffectingKeys() { return hasSideEffectingKeys; } @@ -436,10 +434,7 @@ public static Object doGetWithRestart(Frame frame, Node inliningTarget, ObjectHa @Cached InlinedCountingConditionProfile foundEqKey, @Cached InlinedCountingConditionProfile collisionFoundNoValue, @Cached InlinedCountingConditionProfile collisionFoundEqKey, - @Cached PyObjectRichCompareBool.EqNode eqNode) { - // Must not call generic __eq__ before builtins are initialized - // If this assert fires: we'll need something like putUncachedWithJavaEq also for get - assert map.size == 0 || SpecialMethodSlot.areBuiltinSlotsInitialized(); + @Cached PyObjectRichCompareBool eqNode) { while (true) { try { return doGet(frame, map, key, keyHash, inliningTarget, foundNullKey, foundSameHashKey, @@ -457,7 +452,7 @@ static Object doGet(Frame frame, ObjectHashMap map, Object key, long keyHash, InlinedCountingConditionProfile foundEqKey, InlinedCountingConditionProfile collisionFoundNoValue, InlinedCountingConditionProfile collisionFoundEqKey, - PyObjectRichCompareBool.EqNode eqNode) throws RestartLookupException { + PyObjectRichCompareBool eqNode) throws RestartLookupException { assert map.checkInternalState(); int[] indices = map.indices; int indicesLen = indices.length; @@ -485,7 +480,7 @@ static Object doGet(Frame frame, ObjectHashMap map, Object key, long keyHash, private static Object getCollision(Frame frame, ObjectHashMap map, Object key, long keyHash, Node inliningTarget, InlinedCountingConditionProfile collisionFoundNoValue, InlinedCountingConditionProfile collisionFoundEqKey, - EqNode eqNode, int[] indices, int indicesLen, int compactIndex) throws RestartLookupException { + PyObjectRichCompareBool eqNode, int[] indices, int indicesLen, int compactIndex) throws RestartLookupException { int index; // collision: intentionally counted loop long perturb = keyHash; @@ -524,10 +519,90 @@ private static Object getCollision(Frame frame, ObjectHashMap map, Object key, l } } + @GenerateUncached + @GenerateInline + @GenerateCached(false) + abstract static class UpdateSideEffectingFlag extends Node { + public abstract void execute(Node inliningTarget, ObjectHashMap self, Object key); + + @Specialization(guards = "self.hasSideEffectingKeys()") + static void flagAlreadySet(@SuppressWarnings("unused") ObjectHashMap self, @SuppressWarnings("unused") Object key) { + // nop + } + + @Specialization(guards = "!self.hasSideEffectingKeys()") + static void flagNotSet(Node inliningTarget, ObjectHashMap self, Object key, + @Cached IsSideEffectingKey isSideEffectingKey) { + if (isSideEffectingKey.execute(inliningTarget, key)) { + self.hasSideEffectingKeys = true; + } + } + } + + @GenerateUncached + @GenerateInline + @GenerateCached(false) + @ImportStatic(PGuards.class) + abstract static class IsSideEffectingKey extends Node { + public abstract boolean execute(Node inliningTarget, Object key); + + @Specialization + static boolean doBuiltinString(@SuppressWarnings("unused") int key) { + return false; + } + + @Specialization + static boolean doString(@SuppressWarnings("unused") long key) { + return false; + } + + @Specialization + static boolean doString(@SuppressWarnings("unused") TruffleString object) { + return false; + } + + @Specialization(guards = "isBuiltinPString(string)") + static boolean doBuiltinString(@SuppressWarnings("unused") PString string) { + return false; + } + + @Fallback + static boolean doOthers(@SuppressWarnings("unused") Object key) { + return true; + } + } + @GenerateUncached @GenerateInline @GenerateCached(false) public abstract static class PutNode extends Node { + public static PutNode getUncached() { + return PutNodeGen.getUncached(); + } + + public final void put(Frame frame, Node inliningTarget, ObjectHashMap map, DictKey key, Object value) { + execute(frame, inliningTarget, map, key.getValue(), key.getPythonHash(), value); + } + + public final void put(Frame frame, Node inliningTarget, ObjectHashMap map, Object key, long keyHash, Object value) { + execute(frame, inliningTarget, map, key, keyHash, value); + } + + abstract void execute(Frame frame, Node inliningTarget, ObjectHashMap map, Object key, long keyHash, Object value); + + @Specialization + static void doIt(Frame frame, Node inliningTarget, ObjectHashMap map, Object key, long keyHash, Object value, + @Cached UpdateSideEffectingFlag updateSideEffectingFlag, + @Cached PutUnsafeNode putUnsafeNode) { + updateSideEffectingFlag.execute(inliningTarget, map, key); + putUnsafeNode.execute(frame, inliningTarget, map, key, keyHash, value); + } + } + + @GenerateUncached + @GenerateInline + @GenerateCached(false) + public abstract static class PutUnsafeNode extends Node { public final void put(Frame frame, Node inliningTarget, ObjectHashMap map, DictKey key, Object value) { execute(frame, inliningTarget, map, key.getValue(), key.getPythonHash(), value); } @@ -542,14 +617,6 @@ public static void putUncached(ObjectHashMap map, Object key, long keyHash, Obje abstract void execute(Frame frame, Node inliningTarget, ObjectHashMap map, Object key, long keyHash, Object value); - static void putUncachedWithJavaEq(ObjectHashMap map, Object key, long keyHash, Object value) { - assert isJavaEqualsAllowed(key) : key; - doPutWithRestart(null, null, map, key, keyHash, value, - InlinedBranchProfile.getUncached(), InlinedCountingConditionProfile.getUncached(), InlinedCountingConditionProfile.getUncached(), - InlinedCountingConditionProfile.getUncached(), InlinedCountingConditionProfile.getUncached(), InlinedBranchProfile.getUncached(), InlinedBranchProfile.getUncached(), - null); - } - // "public" for testing... @Specialization public static void doPutWithRestart(Frame frame, Node inliningTarget, ObjectHashMap map, Object key, long keyHash, Object value, @@ -560,10 +627,9 @@ public static void doPutWithRestart(Frame frame, Node inliningTarget, ObjectHash @Cached InlinedCountingConditionProfile collisionFoundEqKey, @Cached InlinedBranchProfile rehash1Profile, @Cached InlinedBranchProfile rehash2Profile, - @Cached PyObjectRichCompareBool.EqNode eqNode) { - // Must not call generic __eq__ before builtins are initialized - // If this assert fires: make sure to use putUncachedWithJavaEq during initialization - assert map.size == 0 || (SpecialMethodSlot.areBuiltinSlotsInitialized() || eqNode == null); + @Cached PyObjectRichCompareBool eqNode) { + // If this assert fires: you're probably using PutUnsafeNode, but should use PutNode + assert map.hasSideEffectingKeys || (!IsSideEffectingKeyNodeGen.getUncached().execute(null, key)); while (true) { try { doPut(frame, map, key, keyHash, value, inliningTarget, foundNullKey, foundEqKey, @@ -584,7 +650,7 @@ static void doPut(Frame frame, ObjectHashMap map, Object key, long keyHash, Obje InlinedCountingConditionProfile collisionFoundEqKey, InlinedBranchProfile rehash1Profile, InlinedBranchProfile rehash2Profile, - PyObjectRichCompareBool.EqNode eqNode) throws RestartLookupException { + PyObjectRichCompareBool eqNode) throws RestartLookupException { assert map.checkInternalState(); int[] indices = map.indices; int indicesLen = indices.length; @@ -608,7 +674,7 @@ static void doPut(Frame frame, ObjectHashMap map, Object key, long keyHash, Obje @InliningCutoff private static void putCollision(Frame frame, ObjectHashMap map, Object key, long keyHash, Object value, Node inliningTarget, InlinedCountingConditionProfile collisionFoundNoValue, InlinedCountingConditionProfile collisionFoundEqKey, - InlinedBranchProfile rehash2Profile, EqNode eqNode, + InlinedBranchProfile rehash2Profile, PyObjectRichCompareBool eqNode, int[] indices, int indicesLen, int compactIndex) throws RestartLookupException { markCollision(indices, compactIndex); long perturb = keyHash; @@ -719,7 +785,7 @@ public static Object doRemoveWithRestart(Frame frame, Node inliningTarget, Objec @Cached InlinedCountingConditionProfile collisionFoundNoValue, @Cached InlinedCountingConditionProfile collisionFoundEqKey, @Cached InlinedBranchProfile compactProfile, - @Cached PyObjectRichCompareBool.EqNode eqNode) { + @Cached PyObjectRichCompareBool eqNode) { while (true) { try { return doRemove(frame, inliningTarget, map, key, keyHash, foundNullKey, foundEqKey, @@ -737,7 +803,7 @@ static Object doRemove(Frame frame, Node inliningTarget, ObjectHashMap map, Obje InlinedCountingConditionProfile collisionFoundNoValue, InlinedCountingConditionProfile collisionFoundEqKey, InlinedBranchProfile compactProfile, - PyObjectRichCompareBool.EqNode eqNode) throws RestartLookupException { + PyObjectRichCompareBool eqNode) throws RestartLookupException { assert map.checkInternalState(); // TODO: move this to the point after we find the value to remove? if (CompilerDirectives.injectBranchProbability(SLOWPATH_PROBABILITY, map.needsCompaction())) { @@ -772,7 +838,7 @@ static Object doRemove(Frame frame, Node inliningTarget, ObjectHashMap map, Obje @InliningCutoff private static Object removeCollision(Frame frame, Node inliningTarget, ObjectHashMap map, Object key, long keyHash, InlinedCountingConditionProfile collisionFoundNoValue, InlinedCountingConditionProfile collisionFoundEqKey, - EqNode eqNode, int[] indices, int indicesLen, int compactIndex) throws RestartLookupException { + PyObjectRichCompareBool eqNode, int[] indices, int indicesLen, int compactIndex) throws RestartLookupException { int unwrappedIndex; long perturb = keyHash; int searchLimit = getBucketsCount(indices) + PERTURB_SHIFTS_COUT; @@ -824,7 +890,7 @@ public Throwable fillInStackTrace() { } private boolean keysEqual(int[] originalIndices, Frame frame, Node inliningTarget, int index, Object key, long keyHash, - PyObjectRichCompareBool.EqNode eqNode) throws RestartLookupException { + PyObjectRichCompareBool eqNode) throws RestartLookupException { if (hashes[index] != keyHash) { return false; } @@ -832,11 +898,7 @@ private boolean keysEqual(int[] originalIndices, Frame frame, Node inliningTarge if (originalKey == key) { return true; } - if (CompilerDirectives.inInterpreter() && eqNode == null) { - // this is hack, see putUncachedWithJavaEq - return javaEquals(originalKey, key); - } - boolean result = eqNode.compare(frame, inliningTarget, originalKey, key); + boolean result = eqNode.executeEq(frame, inliningTarget, originalKey, key); if (getKey(index) != originalKey || indices != originalIndices) { // Either someone overridden the slot we are just examining, or rehasing reallocated the // indices array. We need to restart the lookup. Other situations are OK: @@ -854,18 +916,6 @@ private boolean keysEqual(int[] originalIndices, Frame frame, Node inliningTarge return result; } - private static boolean javaEquals(Object a, Object b) { - CompilerAsserts.neverPartOfCompilation(); - assert isJavaEqualsAllowed(a) : a; - assert isJavaEqualsAllowed(b) : b; - return a.equals(b); - } - - private static boolean isJavaEqualsAllowed(Object o) { - return o instanceof PythonManagedClass || o instanceof PythonBuiltinClassType || // - o instanceof PythonNativeClass || o instanceof Number || o instanceof TruffleString; - } - /** * Called when we need space for new entry. It determines the new size from the number of slots * occupied by real values (i.e., does not count dummy entries), so the new size may be actually diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java index 7e2783727f..d2637b0baf 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,12 +43,15 @@ import static com.oracle.graal.python.nodes.ErrorMessages.IS_NOT_A_SEQUENCE; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; +import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; import com.oracle.graal.python.builtins.objects.common.SequenceNodesFactory.CachedGetObjectArrayNodeGen; import com.oracle.graal.python.builtins.objects.common.SequenceNodesFactory.GetObjectArrayNodeGen; import com.oracle.graal.python.builtins.objects.common.SequenceNodesFactory.SetSequenceStorageNodeGen; import com.oracle.graal.python.builtins.objects.ints.PInt; +import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.builtins.objects.str.StringNodes; +import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.lib.PySequenceCheckNode; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; @@ -122,6 +125,32 @@ static boolean doWithStorage(Node inliningTarget, PSequence seq, long idx, } } + @GenerateUncached + @GenerateInline(inlineByDefault = true) + public abstract static class GetPSequenceStorageNode extends PNodeWithContext { + public abstract SequenceStorage execute(Node inliningTarget, PSequence seq); + + @Specialization + static SequenceStorage doTuple(PTuple seq) { + return seq.getSequenceStorage(); + } + + @Specialization + static SequenceStorage doBytesLike(PBytesLike seq) { + return seq.getSequenceStorage(); + } + + @Specialization + static SequenceStorage doList(PList seq) { + return seq.getSequenceStorage(); + } + + @Specialization + static SequenceStorage doSequence(@SuppressWarnings("unused") PSequence seq) { + throw CompilerDirectives.shouldNotReachHere(); + } + } + @GenerateUncached @GenerateInline(inlineByDefault = true) public abstract static class GetSequenceStorageNode extends PNodeWithContext { @@ -136,15 +165,10 @@ public final SequenceStorage executeCached(Object seq) { return execute(this, seq); } - @Specialization(guards = {"seq.getClass() == cachedClass"}, limit = "2") - static SequenceStorage doSequenceCached(PSequence seq, - @Cached("seq.getClass()") Class cachedClass) { - return CompilerDirectives.castExact(seq, cachedClass).getSequenceStorage(); - } - - @Specialization(replaces = "doSequenceCached") - static SequenceStorage doSequence(PSequence seq) { - return seq.getSequenceStorage(); + @Specialization + static SequenceStorage doSequence(Node inliningTarget, PSequence seq, + @Cached GetPSequenceStorageNode getPSequenceStorageNode) { + return getPSequenceStorageNode.execute(inliningTarget, seq); } // Note: this does not seem currently used but is good to accept foreign lists in more @@ -163,9 +187,8 @@ static SequenceStorage doForeign(Node inliningTarget, Object seq, } @Fallback - static SequenceStorage doFallback(Node inliningTarget, Object seq, - @Cached PRaiseNode.Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(TypeError, IS_NOT_A_SEQUENCE, seq); + static SequenceStorage doFallback(Node inliningTarget, Object seq) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, IS_NOT_A_SEQUENCE, seq); } @NeverDefault @@ -247,9 +270,9 @@ public abstract static class CheckIsSequenceNode extends Node { @Specialization static void check(Node inliningTarget, Object obj, @Cached PySequenceCheckNode sequenceCheckNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (!sequenceCheckNode.execute(inliningTarget, obj)) { - throw raiseNode.get(inliningTarget).raise(TypeError, IS_NOT_A_SEQUENCE, obj); + throw raiseNode.raise(inliningTarget, TypeError, IS_NOT_A_SEQUENCE, obj); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceStorageNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceStorageNodes.java index deadffaff8..f01905d609 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceStorageNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceStorageNodes.java @@ -26,7 +26,6 @@ package com.oracle.graal.python.builtins.objects.common; import static com.oracle.graal.python.builtins.objects.common.IndexNodes.checkBounds; -import static com.oracle.graal.python.builtins.objects.iterator.IteratorBuiltins.NextHelperNode.STOP_MARKER; import static com.oracle.graal.python.runtime.exception.PythonErrorType.IndexError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.MemoryError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.OverflowError; @@ -43,8 +42,8 @@ import java.lang.reflect.Array; import java.util.Arrays; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.modules.SysModuleBuiltins; import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; @@ -55,9 +54,6 @@ import com.oracle.graal.python.builtins.objects.common.IndexNodes.NormalizeIndexNode; import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetSequenceStorageNode; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodesFactory.AppendNodeGen; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodesFactory.CmpNodeGen; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodesFactory.ConcatBaseNodeGen; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodesFactory.ConcatNodeGen; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodesFactory.CreateStorageFromIteratorNodeFactory.CreateStorageFromIteratorNodeCachedNodeGen; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodesFactory.DeleteNodeGen; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodesFactory.ExtendNodeGen; @@ -75,6 +71,7 @@ import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodesFactory.SetItemNodeGen; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodesFactory.StorageToNativeNodeGen; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodesFactory.ToByteArrayNodeGen; +import com.oracle.graal.python.builtins.objects.floats.PFloat; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.iterator.IteratorBuiltins.NextHelperNode; import com.oracle.graal.python.builtins.objects.iterator.IteratorNodes.BuiltinIteratorLengthHint; @@ -89,12 +86,16 @@ import com.oracle.graal.python.builtins.objects.slice.SliceNodes.ComputeIndices; import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyIndexCheckNode; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectGetIter; -import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.lib.PyObjectRichCompareBool; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; @@ -102,7 +103,6 @@ import com.oracle.graal.python.nodes.SpecialMethodNames; import com.oracle.graal.python.nodes.StringLiterals; import com.oracle.graal.python.nodes.builtins.ListNodes; -import com.oracle.graal.python.nodes.expression.BinaryComparisonNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; @@ -112,7 +112,7 @@ import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.native_memory.NativeBuffer; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.graal.python.runtime.sequence.storage.ArrayBasedSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.BoolSequenceStorage; @@ -180,12 +180,12 @@ public abstract static class SequenceStorageSqItemNode extends Node { @Specialization static Object doIt(Node inliningTarget, SequenceStorage self, int index, TruffleString errorMessage, - @Cached PRaiseNode.Lazy raiseNode, - @Cached SequenceStorageNodes.GetItemScalarNode getItemNode) { + @Cached PRaiseNode raiseNode, + @Cached GetItemScalarNode getItemNode) { return getItem(inliningTarget, self, index, errorMessage, raiseNode, getItemNode); } - private static Object getItem(Node inliningTarget, SequenceStorage storage, int index, TruffleString errorMessage, PRaiseNode.Lazy raiseNode, GetItemScalarNode getItemNode) { + private static Object getItem(Node inliningTarget, SequenceStorage storage, int index, TruffleString errorMessage, PRaiseNode raiseNode, GetItemScalarNode getItemNode) { checkBounds(inliningTarget, raiseNode, errorMessage, index, storage.length()); return getItemNode.execute(inliningTarget, storage, index); } @@ -193,7 +193,7 @@ private static Object getItem(Node inliningTarget, SequenceStorage storage, int @FunctionalInterface public interface StorageWrapperFactory { - Object create(PythonObjectFactory factory, SequenceStorage newStorage); + Object create(PythonLanguage language, SequenceStorage newStorage); } @GenerateInline @@ -215,11 +215,11 @@ abstract Object executeImpl(VirtualFrame frame, Node inliningTarget, SequenceSto @Specialization(guards = "!isPSlice(idx)") static Object doNonSlice(VirtualFrame frame, Node inliningTarget, SequenceStorage storage, Object idx, - TruffleString indexBoundsErrorMessage, StorageWrapperFactory wrapperFactory, + TruffleString indexBoundsErrorMessage, @SuppressWarnings("unused") StorageWrapperFactory wrapperFactory, @Cached PyNumberAsSizeNode numberAsSizeNode, @Cached InlinedConditionProfile negativeIndexProfile, - @Cached PRaiseNode.Lazy raiseNode, - @Cached SequenceStorageNodes.GetItemScalarNode getItemNode) { + @Cached PRaiseNode raiseNode, + @Cached GetItemScalarNode getItemNode) { int index = numberAsSizeNode.executeExact(frame, inliningTarget, idx, PythonBuiltinClassType.IndexError); if (negativeIndexProfile.profile(inliningTarget, index < 0)) { index += storage.length(); @@ -229,15 +229,15 @@ static Object doNonSlice(VirtualFrame frame, Node inliningTarget, SequenceStorag @Specialization static Object doSlice(VirtualFrame frame, Node inliningTarget, SequenceStorage storage, PSlice slice, - @SuppressWarnings("unused") TruffleString indexBoundsErrorMessage, StorageWrapperFactory wrapperFactory, - @Cached(inline = false) PythonObjectFactory factory, + TruffleString indexBoundsErrorMessage, StorageWrapperFactory wrapperFactory, + @Bind PythonLanguage language, @Cached CoerceToIntSlice sliceCast, @Cached(inline = false) ComputeIndices compute, @Cached(inline = false) GetItemSliceNode getItemSliceNode, @Cached LenOfRangeNode sliceLen) { SliceInfo info = compute.execute(frame, sliceCast.execute(inliningTarget, slice), storage.length()); SequenceStorage newStorage = getItemSliceNode.execute(storage, info.start, info.stop, info.step, sliceLen.len(inliningTarget, info)); - return wrapperFactory.create(factory, newStorage); + return wrapperFactory.create(language, newStorage); } } @@ -267,7 +267,7 @@ static boolean compatibleAssign(Node inliningTarget, SequenceStorage lhs, Sequen case Byte: return rhsType == Byte || rhsType == Uninitialized || rhsType == Empty; case Int: - return rhsType == StorageType.Byte || rhsType == StorageType.Int || rhsType == Uninitialized || rhsType == Empty; + return rhsType == Byte || rhsType == Int || rhsType == Uninitialized || rhsType == Empty; case Long: return rhsType == Byte || rhsType == Int || rhsType == Long || rhsType == Uninitialized || rhsType == Empty; case Double: @@ -331,11 +331,11 @@ protected static boolean isEmpty(SequenceStorage left) { } protected static boolean isBoolean(StorageType et) { - return et == StorageType.Boolean; + return et == Boolean; } protected static boolean isByte(StorageType et) { - return et == StorageType.Byte; + return et == Byte; } protected static boolean isByteLike(StorageType et) { @@ -343,15 +343,15 @@ protected static boolean isByteLike(StorageType et) { } protected static boolean isInt(StorageType et) { - return et == StorageType.Int; + return et == Int; } protected static boolean isLong(StorageType et) { - return et == StorageType.Long; + return et == Long; } protected static boolean isDouble(StorageType et) { - return et == StorageType.Double; + return et == Double; } protected static boolean isObject(StorageType et) { @@ -404,9 +404,9 @@ public abstract static class GetItemNode extends NormalizingNode { @Child private GetItemScalarNode getItemScalarNode; @Child private GetItemSliceNode getItemSliceNode; - private final BiFunction factoryMethod; + private final BiFunction factoryMethod; - public GetItemNode(NormalizeIndexNode normalizeIndexNode, BiFunction factoryMethod) { + public GetItemNode(NormalizeIndexNode normalizeIndexNode, BiFunction factoryMethod) { super(normalizeIndexNode); this.factoryMethod = factoryMethod; } @@ -462,13 +462,12 @@ protected Object doScalarGeneric(VirtualFrame frame, SequenceStorage storage, Ob @SuppressWarnings("truffle-static-method") protected Object doSlice(VirtualFrame frame, SequenceStorage storage, PSlice slice, @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, @Cached CoerceToIntSlice sliceCast, @Cached ComputeIndices compute, @Cached LenOfRangeNode sliceLen) { SliceInfo info = compute.execute(frame, sliceCast.execute(inliningTarget, slice), storage.length()); if (factoryMethod != null) { - return factoryMethod.apply(getGetItemSliceNode().execute(storage, info.start, info.stop, info.step, sliceLen.len(inliningTarget, info)), factory); + return factoryMethod.apply(getGetItemSliceNode().execute(storage, info.start, info.stop, info.step, sliceLen.len(inliningTarget, info)), PythonLanguage.get(inliningTarget)); } CompilerDirectives.transferToInterpreterAndInvalidate(); throw new IllegalStateException(); @@ -506,18 +505,18 @@ public static GetItemNode create() { } @NeverDefault - public static GetItemNode create(NormalizeIndexNode normalizeIndexNode, BiFunction factoryMethod) { + public static GetItemNode create(NormalizeIndexNode normalizeIndexNode, BiFunction factoryMethod) { return GetItemNodeGen.create(normalizeIndexNode, factoryMethod); } @NeverDefault - public static SequenceStorageNodes.GetItemNode createForList() { - return SequenceStorageNodes.GetItemNode.create(NormalizeIndexNode.forList(), (s, f) -> f.createList(s)); + public static GetItemNode createForList() { + return GetItemNode.create(NormalizeIndexNode.forList(), (s, l) -> PFactory.createList(l, s)); } @NeverDefault - public static SequenceStorageNodes.GetItemNode createForTuple() { - return SequenceStorageNodes.GetItemNode.create(NormalizeIndexNode.forTuple(), (s, f) -> f.createTuple(s)); + public static GetItemNode createForTuple() { + return GetItemNode.create(NormalizeIndexNode.forTuple(), (s, l) -> PFactory.createTuple(l, s)); } } @@ -1203,8 +1202,8 @@ public static SetItemNode create(TruffleString invalidItemErrorMessage) { } @NeverDefault - public static SequenceStorageNodes.SetItemNode createForList() { - return SequenceStorageNodes.SetItemNode.create(NormalizeIndexNode.forListAssign(), ListGeneralizationNode::create); + public static SetItemNode createForList() { + return SetItemNode.create(NormalizeIndexNode.forListAssign(), ListGeneralizationNode::create); } } @@ -1749,7 +1748,7 @@ static void multiStep(SequenceStorage self, SliceInfo sinfo, SequenceStorage val } else { /*- Assign slice */ if (wrongLength.profile(inliningTarget, needed != slicelen)) { - raiseNode.raise(ValueError, ErrorMessages.ATTEMPT_TO_ASSIGN_SEQ_OF_SIZE_TO_SLICE_OF_SIZE, needed, slicelen); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.ATTEMPT_TO_ASSIGN_SEQ_OF_SIZE_TO_SLICE_OF_SIZE, needed, slicelen); } for (int cur = start, i = 0; i < slicelen; cur += step, i++) { setLeftItemNode.execute(inliningTarget, self, cur, getRightItemNode.execute(inliningTarget, data, i)); @@ -1814,7 +1813,7 @@ static void singleStep(SequenceStorage self, int lo, int hi, SequenceStorage dat ensureCapacityNode.execute(inliningTarget, self, len + growth); if (memoryError.profile(inliningTarget, len > Integer.MAX_VALUE - growth)) { - throw raiseNode.raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } len += growth; @@ -1880,180 +1879,199 @@ static NativeSequenceStorage doObject(Object[] arr, int length, boolean createRe } } + @GenerateInline + @GenerateCached(false) public abstract static class CmpNode extends SequenceStorageBaseNode { - @Child private BinaryComparisonNode cmpOp; - @Child private PyObjectIsTrueNode castToBooleanNode; - - protected CmpNode(BinaryComparisonNode cmpOp) { - this.cmpOp = cmpOp; - } - - public abstract boolean execute(VirtualFrame frame, SequenceStorage left, SequenceStorage right); - - private boolean testingEqualsWithDifferingLengths(int llen, int rlen) { - // shortcut: if the lengths differ, the lists differ. - CompilerAsserts.compilationConstant(cmpOp.getClass()); - if (cmpOp instanceof BinaryComparisonNode.EqNode) { - if (llen != rlen) { - return true; - } - } - return false; - } + public abstract boolean execute(VirtualFrame frame, Node inliningTarget, SequenceStorage left, SequenceStorage right, + boolean isListComparison, Object leftSeq, Object rightSeq, RichCmpOp op); @SuppressWarnings("unused") @Specialization(guards = {"isEmpty(left)", "isEmpty(right)"}) - boolean doEmpty(SequenceStorage left, SequenceStorage right) { - return cmpOp.cmp(0, 0); + static boolean doEmpty(SequenceStorage left, SequenceStorage right, boolean isListComparison, Object leftSeq, Object rightSeq, RichCmpOp op) { + return op.compare(0, 0); } @Specialization - boolean doBoolStorage(BoolSequenceStorage left, BoolSequenceStorage right) { + static boolean doBoolStorage(Node inliningTarget, BoolSequenceStorage left, BoolSequenceStorage right, boolean isListComparison, Object leftSeq, Object rightSeq, + RichCmpOp op, + @Shared @Cached InlinedLoopConditionProfile loopProfile) { int llen = left.length(); int rlen = right.length(); - if (testingEqualsWithDifferingLengths(llen, rlen)) { - return false; + if (op.isEqOrNe() && llen != rlen) { + return op == RichCmpOp.Py_NE; } - for (int i = 0; i < Math.min(llen, rlen); i++) { + // intentionally imprecise loop profile to avoid its overhead... + loopProfile.profileCounted(inliningTarget, Math.min(llen, rlen)); + for (int i = 0; loopProfile.inject(inliningTarget, i < Math.min(llen, rlen)); i++) { int litem = PInt.intValue(left.getBoolItemNormalized(i)); int ritem = PInt.intValue(right.getBoolItemNormalized(i)); if (litem != ritem) { - return cmpOp.cmp(litem, ritem); + LoopNode.reportLoopCount(inliningTarget, i); + return op.compare(litem, ritem); } } - return cmpOp.cmp(llen, rlen); + LoopNode.reportLoopCount(inliningTarget, Math.min(llen, rlen)); + return op.compare(llen, rlen); } @Specialization - boolean doByteStorage(ByteSequenceStorage left, ByteSequenceStorage right) { + static boolean doByteStorage(Node inliningTarget, ByteSequenceStorage left, ByteSequenceStorage right, boolean isListComparison, Object leftSeq, Object rightSeq, + RichCmpOp op, + @Shared @Cached InlinedLoopConditionProfile loopProfile) { int llen = left.length(); int rlen = right.length(); - if (testingEqualsWithDifferingLengths(llen, rlen)) { - return false; + if (op.isEqOrNe() && llen != rlen) { + return op == RichCmpOp.Py_NE; } - for (int i = 0; i < Math.min(llen, rlen); i++) { + // intentionally imprecise loop profile to avoid its overhead... + loopProfile.profileCounted(inliningTarget, Math.min(llen, rlen)); + for (int i = 0; loopProfile.inject(inliningTarget, i < Math.min(llen, rlen)); i++) { byte litem = left.getByteItemNormalized(i); byte ritem = right.getByteItemNormalized(i); if (litem != ritem) { - return cmpOp.cmp(litem, ritem); + LoopNode.reportLoopCount(inliningTarget, i); + return op.compare(litem, ritem); } } - return cmpOp.cmp(llen, rlen); + LoopNode.reportLoopCount(inliningTarget, Math.min(llen, rlen)); + return op.compare(llen, rlen); } @Specialization - boolean doIntStorage(IntSequenceStorage left, IntSequenceStorage right) { + static boolean doIntStorage(Node inliningTarget, IntSequenceStorage left, IntSequenceStorage right, boolean isListComparison, Object leftSeq, Object rightSeq, RichCmpOp op, + @Shared @Cached InlinedLoopConditionProfile loopProfile) { int llen = left.length(); int rlen = right.length(); - if (testingEqualsWithDifferingLengths(llen, rlen)) { - return false; + if (op.isEqOrNe() && llen != rlen) { + return op == RichCmpOp.Py_NE; } - for (int i = 0; i < Math.min(llen, rlen); i++) { + // intentionally imprecise loop profile to avoid its overhead... + loopProfile.profileCounted(inliningTarget, Math.min(llen, rlen)); + for (int i = 0; loopProfile.inject(inliningTarget, i < Math.min(llen, rlen)); i++) { int litem = left.getIntItemNormalized(i); int ritem = right.getIntItemNormalized(i); if (litem != ritem) { - return cmpOp.cmp(litem, ritem); + LoopNode.reportLoopCount(inliningTarget, i); + return op.compare(litem, ritem); } } - return cmpOp.cmp(llen, rlen); + LoopNode.reportLoopCount(inliningTarget, Math.min(llen, rlen)); + return op.compare(llen, rlen); } @Specialization - boolean doLongStorage(LongSequenceStorage left, LongSequenceStorage right) { + static boolean doLongStorage(Node inliningTarget, LongSequenceStorage left, LongSequenceStorage right, boolean isListComparison, Object leftSeq, Object rightSeq, + RichCmpOp op, + @Shared @Cached InlinedLoopConditionProfile loopProfile) { int llen = left.length(); int rlen = right.length(); - if (testingEqualsWithDifferingLengths(llen, rlen)) { - return false; + if (op.isEqOrNe() && llen != rlen) { + return op == RichCmpOp.Py_NE; } - for (int i = 0; i < Math.min(llen, rlen); i++) { + // intentionally imprecise loop profile to avoid its overhead... + loopProfile.profileCounted(inliningTarget, Math.min(llen, rlen)); + for (int i = 0; loopProfile.inject(inliningTarget, i < Math.min(llen, rlen)); i++) { long litem = left.getLongItemNormalized(i); long ritem = right.getLongItemNormalized(i); if (litem != ritem) { - return cmpOp.cmp(litem, ritem); + LoopNode.reportLoopCount(inliningTarget, i); + return op.compare(litem, ritem); } } - return cmpOp.cmp(llen, rlen); + LoopNode.reportLoopCount(inliningTarget, Math.min(llen, rlen)); + return op.compare(llen, rlen); } @Specialization - boolean doDoubleStorage(DoubleSequenceStorage left, DoubleSequenceStorage right) { + static boolean doDoubleStorage(Node inliningTarget, DoubleSequenceStorage left, DoubleSequenceStorage right, boolean isListComparison, Object leftSeq, Object rightSeq, + RichCmpOp op, + @Shared @Cached InlinedLoopConditionProfile loopProfile) { int llen = left.length(); int rlen = right.length(); - if (testingEqualsWithDifferingLengths(llen, rlen)) { - return false; + if (op.isEqOrNe() && llen != rlen) { + return op == RichCmpOp.Py_NE; } - for (int i = 0; i < Math.min(llen, rlen); i++) { + // intentionally imprecise loop profile to avoid its overhead... + loopProfile.profileCounted(inliningTarget, Math.min(llen, rlen)); + for (int i = 0; loopProfile.inject(inliningTarget, i < Math.min(llen, rlen)); i++) { double litem = left.getDoubleItemNormalized(i); double ritem = right.getDoubleItemNormalized(i); - if (java.lang.Double.compare(litem, ritem) != 0) { - return cmpOp.cmp(litem, ritem); + if (!PFloat.areIdentical(litem, ritem)) { + LoopNode.reportLoopCount(inliningTarget, i); + return op.compare(litem, ritem); } } - return cmpOp.cmp(llen, rlen); + LoopNode.reportLoopCount(inliningTarget, Math.min(llen, rlen)); + return op.compare(llen, rlen); } @Specialization @SuppressWarnings("truffle-static-method") - boolean doGeneric(VirtualFrame frame, SequenceStorage left, SequenceStorage right, - @Bind("this") Node inliningTarget, - @Cached PyObjectRichCompareBool.EqNode eqNode, + static boolean doGeneric(VirtualFrame frame, Node inliningTarget, SequenceStorage left, SequenceStorage right, boolean isListComparison, Object leftSeq, Object rightSeq, + RichCmpOp op, + @Cached PyObjectRichCompareBool eqNode, + @Cached PyObjectRichCompareBool cmpNode, + @Exclusive @Cached InlinedLoopConditionProfile loopProfile, + @Cached InlinedBranchProfile storageHasChanged, @Cached GetItemScalarNode getLeftItemNode, - @Cached GetItemScalarNode getRightItemNode) { + @Cached GetItemScalarNode getRightItemNode, + @Cached ListNodes.GetListStorageNode getListStorageNode) { int llen = left.length(); int rlen = right.length(); - if (testingEqualsWithDifferingLengths(llen, rlen)) { - return false; + if (op.isEqOrNe() && llen != rlen) { + return op == RichCmpOp.Py_NE; } - for (int i = 0; i < Math.min(llen, rlen); i++) { + // intentionally imprecise loop profile to avoid its overhead... + loopProfile.profileCounted(inliningTarget, Math.min(left.length(), right.length())); + for (int i = 0; loopProfile.inject(inliningTarget, i < Math.min(left.length(), right.length())); i++) { Object leftItem = getLeftItemNode.execute(inliningTarget, left, i); Object rightItem = getRightItemNode.execute(inliningTarget, right, i); - if (!eqNode.compare(frame, inliningTarget, leftItem, rightItem)) { - return cmpGeneric(frame, leftItem, rightItem); + if (!eqNode.execute(frame, inliningTarget, leftItem, rightItem, RichCmpOp.Py_EQ)) { + LoopNode.reportLoopCount(inliningTarget, i); + // Following CPython semantics: we must compare the length again... + SequenceStorage newLeft = null, newRight = null; + if (isListComparison) { + newLeft = getListStorageNode.execute(inliningTarget, leftSeq); + newRight = getListStorageNode.execute(inliningTarget, rightSeq); + if (i >= newLeft.length() || i >= newRight.length()) { + storageHasChanged.enter(inliningTarget); + return op.compare(newLeft.length(), newRight.length()); + } + } + // Then apply shortcut for eq/ne... + if (op.isEqOrNe()) { + return op.isNe(); + } + // Then re-read the items, because the __eq__ call could have changed them + if (isListComparison) { + leftItem = getLeftItemNode.execute(inliningTarget, newLeft, i); + rightItem = getRightItemNode.execute(inliningTarget, newRight, i); + } + // Then do the final comparison of now possibly different items + return cmpNode.execute(frame, inliningTarget, leftItem, rightItem, op); + } + // Note: the semantics of CPython (which is tested in its unit tests) is that the + // loop should re-read the list size in every iteration. For us this means also + // re-reading the storage. See {@code test_list.py: + // ListTest.test_equal_operator_modifying_operand}. + // + // This node is either used to compare two tuples or to compare two lists, which can + // be either PList or a foreign list. We assume that tuples are immutable, which is + // not entirely correct (C API), but taking care of that eventuality is stretching + // this too far. + CompilerAsserts.partialEvaluationConstant(isListComparison); + if (isListComparison) { + SequenceStorage newLeft = getListStorageNode.execute(inliningTarget, leftSeq); + SequenceStorage newRight = getListStorageNode.execute(inliningTarget, rightSeq); + if (left != newLeft || right != newRight) { + storageHasChanged.enter(inliningTarget); + left = newLeft; + right = newRight; + } } } - return cmpOp.cmp(llen, rlen); - } - - private boolean cmpGeneric(VirtualFrame frame, Object left, Object right) { - return castToBoolean(frame, cmpOp.executeObject(frame, left, right)); - } - - private boolean castToBoolean(VirtualFrame frame, Object value) { - if (castToBooleanNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castToBooleanNode = insert(PyObjectIsTrueNode.create()); - } - return castToBooleanNode.execute(frame, value); - } - - @NeverDefault - public static CmpNode createLe() { - return CmpNodeGen.create(BinaryComparisonNode.LeNode.create()); - } - - @NeverDefault - public static CmpNode createLt() { - return CmpNodeGen.create(BinaryComparisonNode.LtNode.create()); - } - - @NeverDefault - public static CmpNode createGe() { - return CmpNodeGen.create(BinaryComparisonNode.GeNode.create()); - } - - @NeverDefault - public static CmpNode createGt() { - return CmpNodeGen.create(BinaryComparisonNode.GtNode.create()); - } - - @NeverDefault - public static CmpNode createEq() { - return CmpNodeGen.create(BinaryComparisonNode.EqNode.create()); - } - - @NeverDefault - public static CmpNode createNe() { - return CmpNodeGen.create(BinaryComparisonNode.NeNode.create()); + LoopNode.reportLoopCount(inliningTarget, Math.min(left.length(), right.length())); + return op.compare(left.length(), right.length()); } } @@ -2185,6 +2203,7 @@ static boolean isByteSequenceStorage(SequenceStorage s) { } @SuppressWarnings("truffle-inlining") // footprint reduction 68 -> 49 + @GenerateUncached public abstract static class ConcatBaseNode extends SequenceStorageBaseNode { public abstract SequenceStorage execute(SequenceStorage dest, SequenceStorage left, SequenceStorage right); @@ -2197,7 +2216,7 @@ static SequenceStorage doLeftEmpty(@SuppressWarnings("unused") EmptySequenceStor try { return copyNode.execute(inliningTarget, right); } catch (OutOfMemoryError e) { - throw raiseNode.raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } } @@ -2209,7 +2228,7 @@ static SequenceStorage doRightEmpty(@SuppressWarnings("unused") EmptySequenceSto try { return copyNode.execute(inliningTarget, left); } catch (OutOfMemoryError e) { - throw raiseNode.raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } } @@ -2314,104 +2333,32 @@ private static void concat(Object dest, Object arr1, int len1, Object arr2, int } } - /** - * Concatenates two sequence storages; creates a storage of a suitable type and writes the - * result to the new storage. - */ - public abstract static class ConcatNode extends SequenceStorageBaseNode { - private static final TruffleString DEFAULT_ERROR_MSG = ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP; - - @Child private ConcatBaseNode concatBaseNode = ConcatBaseNodeGen.create(); - @Child private GeneralizationNode genNode; - - private final Supplier genNodeProvider; - - /* - * CPython is inconsistent when too repeats are done. Most types raise MemoryError, but e.g. - * bytes raises OverflowError when the memory might be available but the size overflows - * sys.maxint - */ - private final PythonBuiltinClassType errorForOverflow; - - ConcatNode(Supplier genNodeProvider, PythonBuiltinClassType errorForOverflow) { - this.genNodeProvider = genNodeProvider; - this.errorForOverflow = errorForOverflow; - } + @GenerateInline + @GenerateCached(false) + @GenerateUncached + public abstract static class ConcatListOrTupleNode extends Node { - public abstract SequenceStorage execute(SequenceStorage left, SequenceStorage right); + public abstract SequenceStorage execute(Node inliningTarget, SequenceStorage left, SequenceStorage right); @Specialization - SequenceStorage doRight(SequenceStorage left, SequenceStorage right, - @Bind("this") Node inliningTarget, - @Cached CreateEmptyNode createEmptyNode, - @Cached InlinedConditionProfile shouldOverflow, + static SequenceStorage concat(Node inliningTarget, SequenceStorage left, SequenceStorage right, + @Cached CreateEmpty2Node create, + @Cached(inline = false) ConcatBaseNode concat, @Cached PRaiseNode raiseNode) { - int destlen = 0; try { int len1 = left.length(); int len2 = right.length(); - // we eagerly generalize the store to avoid possible cascading generalizations - destlen = PythonUtils.addExact(len1, len2); - if (errorForOverflow == OverflowError && shouldOverflow.profile(inliningTarget, destlen >= SysModuleBuiltins.MAXSIZE)) { - // cpython raises an overflow error when this happens - throw raiseNode.raise(OverflowError); + int destlen = PythonUtils.addExact(len1, len2); + SequenceStorage empty = create.execute(inliningTarget, left, right, destlen); + empty.setNewLength(destlen); + try { + return concat.execute(empty, left, right); + } catch (SequenceStoreException e) { + throw CompilerDirectives.shouldNotReachHere(); } - SequenceStorage generalized = generalizeStore(createEmpty(createEmptyNode, inliningTarget, left, right, destlen), right); - return doConcat(generalized, left, right); - } catch (OutOfMemoryError e) { - throw raiseNode.raise(MemoryError); - } catch (OverflowException e) { - throw raiseNode.raise(errorForOverflow); - } - } - - private SequenceStorage createEmpty(CreateEmptyNode createEmptyNode, Node inliningTarget, SequenceStorage l, SequenceStorage r, int len) { - if (l instanceof EmptySequenceStorage) { - return createEmptyNode.execute(inliningTarget, r, len, -1); - } - return createEmptyNode.execute(inliningTarget, l, len, len); - } - - private SequenceStorage doConcat(SequenceStorage dest, SequenceStorage leftProfiled, SequenceStorage rightProfiled) { - try { - return concatBaseNode.execute(dest, leftProfiled, rightProfiled); - } catch (SequenceStoreException e) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw new IllegalStateException("generalized sequence storage cannot take value: " + e.getIndicationValue()); - } - } - - private SequenceStorage generalizeStore(SequenceStorage storage, Object value) { - if (genNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - genNode = insert(genNodeProvider.get()); + } catch (OutOfMemoryError | OverflowException e) { + throw raiseNode.raise(inliningTarget, MemoryError); } - return genNode.executeCached(storage, value); - } - - @NeverDefault - public static ConcatNode create() { - return create(() -> NoGeneralizationCustomMessageNode.create(DEFAULT_ERROR_MSG), MemoryError); - } - - @NeverDefault - public static ConcatNode createWithOverflowError() { - return create(() -> NoGeneralizationCustomMessageNode.create(DEFAULT_ERROR_MSG), OverflowError); - } - - @NeverDefault - public static ConcatNode create(TruffleString msg) { - return create(() -> NoGeneralizationCustomMessageNode.create(msg), MemoryError); - } - - @NeverDefault - public static ConcatNode create(Supplier genNodeProvider) { - return create(genNodeProvider, MemoryError); - } - - @NeverDefault - private static ConcatNode create(Supplier genNodeProvider, PythonBuiltinClassType errorForOverflow) { - return ConcatNodeGen.create(genNodeProvider, errorForOverflow); } } @@ -2474,25 +2421,31 @@ SequenceStorage doWithoutStorage(VirtualFrame frame, SequenceStorage left, Objec @Bind("this") Node inliningTarget, @Cached PyObjectGetIter getIter, @Exclusive @Cached EnsureCapacityNode ensureCapacityNode, - @Cached GetNextNode getNextNode, - @Cached IsBuiltinObjectProfile errorProfile, + @Cached GetObjectSlotsNode getSlots, + @Cached CallSlotTpIterNextNode callIterNext, + @Cached IsBuiltinObjectProfile stopIterationProfile, + @Cached InlinedLoopConditionProfile loopProfile, @Cached AppendNode appendNode) { SequenceStorage currentStore = left; int lenLeft = currentStore.length(); Object it = getIter.execute(frame, inliningTarget, iterable); + TpSlot iterNext = getSlots.execute(inliningTarget, it).tp_iternext(); if (len > 0) { ensureCapacityNode.execute(inliningTarget, left, lengthResult(lenLeft, len)); } - while (true) { - Object value; + boolean exhausted = false; + while (loopProfile.profile(inliningTarget, !exhausted)) { try { - value = getNextNode.execute(frame, it); + Object value = callIterNext.execute(frame, inliningTarget, iterNext, it); currentStore = appendNode.execute(inliningTarget, currentStore, value, genNodeProvider); + } catch (IteratorExhausted e) { + exhausted = true; } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); - return currentStore; + e.expectStopIteration(inliningTarget, stopIterationProfile); + exhausted = true; } } + return currentStore; } private SequenceStorage generalizeStore(SequenceStorage storage, Object value) { @@ -2515,8 +2468,6 @@ public static ExtendNode create(GenNodeSupplier genNodeProvider) { } public abstract static class RepeatNode extends SequenceStorageBaseNode { - @Child private RepeatNode recursive; - /* * CPython is inconsistent when too repeats are done. Most types raise MemoryError, but e.g. * bytes raises OverflowError when the memory might be available but the size overflows @@ -2528,8 +2479,6 @@ protected RepeatNode(PythonBuiltinClassType errorForOverflow) { this.errorForOverflow = errorForOverflow; } - public abstract SequenceStorage execute(VirtualFrame frame, SequenceStorage left, Object times); - public abstract SequenceStorage execute(VirtualFrame frame, SequenceStorage left, int times); @Specialization @@ -2547,95 +2496,102 @@ static SequenceStorage doZeroRepeat(SequenceStorage s, @SuppressWarnings("unused /* special but common case: something like '[False] * n' */ @Specialization(guards = {"s.length() == 1", "times > 0"}) BoolSequenceStorage doBoolSingleElement(BoolSequenceStorage s, int times, + @Bind("this") Node inliningTarget, @Shared @Cached PRaiseNode raiseNode) { try { boolean[] repeated = new boolean[PythonUtils.multiplyExact(s.length(), times)]; Arrays.fill(repeated, s.getBoolItemNormalized(0)); return new BoolSequenceStorage(repeated); } catch (OutOfMemoryError e) { - throw raiseNode.raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } catch (OverflowException e) { - throw raiseNode.raise(errorForOverflow); + throw raiseNode.raise(inliningTarget, errorForOverflow); } } /* special but common case: something like '["\x00"] * n' */ @Specialization(guards = {"s.length() == 1", "times > 0"}) ByteSequenceStorage doByteSingleElement(ByteSequenceStorage s, int times, + @Bind("this") Node inliningTarget, @Shared @Cached PRaiseNode raiseNode) { try { byte[] repeated = new byte[PythonUtils.multiplyExact(s.length(), times)]; Arrays.fill(repeated, s.getByteItemNormalized(0)); return new ByteSequenceStorage(repeated); } catch (OutOfMemoryError e) { - throw raiseNode.raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } catch (OverflowException e) { - throw raiseNode.raise(errorForOverflow); + throw raiseNode.raise(inliningTarget, errorForOverflow); } } /* special but common case: something like '[0] * n' */ @Specialization(guards = {"s.length() == 1", "times > 0"}) IntSequenceStorage doIntSingleElement(IntSequenceStorage s, int times, + @Bind("this") Node inliningTarget, @Shared @Cached PRaiseNode raiseNode) { try { int[] repeated = new int[PythonUtils.multiplyExact(s.length(), times)]; Arrays.fill(repeated, s.getIntItemNormalized(0)); return new IntSequenceStorage(repeated); } catch (OutOfMemoryError e) { - throw raiseNode.raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } catch (OverflowException e) { - throw raiseNode.raise(errorForOverflow); + throw raiseNode.raise(inliningTarget, errorForOverflow); } } /* special but common case: something like '[0L] * n' */ @Specialization(guards = {"s.length() == 1", "times > 0"}) LongSequenceStorage doLongSingleElement(LongSequenceStorage s, int times, + @Bind("this") Node inliningTarget, @Shared @Cached PRaiseNode raiseNode) { try { long[] repeated = new long[PythonUtils.multiplyExact(s.length(), times)]; Arrays.fill(repeated, s.getLongItemNormalized(0)); return new LongSequenceStorage(repeated); } catch (OutOfMemoryError e) { - throw raiseNode.raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } catch (OverflowException e) { - throw raiseNode.raise(errorForOverflow); + throw raiseNode.raise(inliningTarget, errorForOverflow); } } /* special but common case: something like '[0.0] * n' */ @Specialization(guards = {"s.length() == 1", "times > 0"}) DoubleSequenceStorage doDoubleSingleElement(DoubleSequenceStorage s, int times, + @Bind("this") Node inliningTarget, @Shared @Cached PRaiseNode raiseNode) { try { double[] repeated = new double[PythonUtils.multiplyExact(s.length(), times)]; Arrays.fill(repeated, s.getDoubleItemNormalized(0)); return new DoubleSequenceStorage(repeated); } catch (OutOfMemoryError e) { - throw raiseNode.raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } catch (OverflowException e) { - throw raiseNode.raise(errorForOverflow); + throw raiseNode.raise(inliningTarget, errorForOverflow); } } /* special but common case: something like '[None] * n' */ @Specialization(guards = {"s.length() == 1", "times > 0"}) ObjectSequenceStorage doObjectSingleElement(ObjectSequenceStorage s, int times, + @Bind("this") Node inliningTarget, @Shared @Cached PRaiseNode raiseNode) { try { Object[] repeated = new Object[PythonUtils.multiplyExact(s.length(), times)]; Arrays.fill(repeated, s.getObjectItemNormalized(0)); return new ObjectSequenceStorage(repeated); } catch (OutOfMemoryError e) { - throw raiseNode.raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } catch (OverflowException e) { - throw raiseNode.raise(errorForOverflow); + throw raiseNode.raise(inliningTarget, errorForOverflow); } } @Specialization(limit = "MAX_BASIC_STORAGES", guards = {"times > 0", "!isNative(s)", "s.getClass() == cachedClass"}) SequenceStorage doArrayBasedManaged(ArrayBasedSequenceStorage s, int times, + @Bind("this") Node inliningTarget, @Shared @Cached PRaiseNode raiseNode, @Cached("s.getClass()") Class cachedClass) { try { @@ -2649,9 +2605,9 @@ SequenceStorage doArrayBasedManaged(ArrayBasedSequenceStorage s, int times, repeated.setNewLength(newLength); return repeated; } catch (OutOfMemoryError e) { - throw raiseNode.raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } catch (OverflowException e) { - throw raiseNode.raise(errorForOverflow); + throw raiseNode.raise(inliningTarget, errorForOverflow); } } @@ -2683,28 +2639,10 @@ SequenceStorage doGeneric(SequenceStorage s, int times, repeated.setNewLength(newLen); return repeated; } catch (OutOfMemoryError e) { - throw raiseNode.raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } catch (OverflowException e) { - throw raiseNode.raise(errorForOverflow); - } - } - - @Specialization(guards = "!isInt(times)") - @SuppressWarnings("truffle-static-method") - SequenceStorage doNonInt(VirtualFrame frame, SequenceStorage s, Object times, - @Bind("this") Node inliningTarget, - @Cached PyIndexCheckNode indexCheckNode, - @Cached PyNumberAsSizeNode asSizeNode, - @Shared @Cached PRaiseNode raiseNode) { - if (!indexCheckNode.execute(inliningTarget, times)) { - throw raiseNode.raise(TypeError, ErrorMessages.CANT_MULTIPLY_SEQ_BY_NON_INT, times); - } - int i = asSizeNode.executeExact(frame, inliningTarget, times); - if (recursive == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - recursive = insert(RepeatNodeGen.create(errorForOverflow)); + throw raiseNode.raise(inliningTarget, errorForOverflow); } - return recursive.execute(frame, s, i); } private static void repeat(Object dest, Object src, int len, int times) { @@ -2780,10 +2718,10 @@ public static int doDoubleStorage(DoubleSequenceStorage s, double item) { @Specialization static int doGeneric(VirtualFrame frame, Node inliningTarget, SequenceStorage self, Object item, @Cached(inline = false) GetItemScalarNode getItemNode, - @Cached PyObjectRichCompareBool.EqNode eqNode) { + @Cached PyObjectRichCompareBool eqNode) { for (int i = 0; i < self.length(); i++) { Object seqItem = getItemNode.execute(inliningTarget, self, i); - if (eqNode.compare(frame, inliningTarget, seqItem, item)) { + if (eqNode.execute(frame, inliningTarget, seqItem, item, RichCmpOp.Py_EQ)) { return i; } } @@ -2843,7 +2781,7 @@ protected SequenceStorage doGeneric(SequenceStorage s, Object indicationVal, return s; } - throw raiseNode.raise(TypeError, getErrorMessage()); + throw raiseNode.raise(inliningTarget, TypeError, getErrorMessage()); } protected TruffleString getErrorMessage() { @@ -3114,6 +3052,23 @@ static ArrayBasedSequenceStorage doIt(Node inliningTarget, SequenceStorage s, in @GenerateInline @GenerateCached(false) + @GenerateUncached + public abstract static class CreateEmpty2Node extends SequenceStorageBaseNode { + + public abstract SequenceStorage execute(Node inliningTarget, SequenceStorage s1, SequenceStorage s2, int cap); + + @Specialization + static SequenceStorage doIt(Node inliningTarget, SequenceStorage s1, SequenceStorage s2, int cap, + @Cached GetElementType getElementType1, + @Cached GetElementType getElementType2, + @Cached CreateEmptyForTypesNode create) { + return create.execute(inliningTarget, getElementType1.execute(inliningTarget, s1), getElementType2.execute(inliningTarget, s2), cap); + } + } + + @GenerateInline + @GenerateCached(false) + @GenerateUncached abstract static class CreateEmptyForTypeNode extends SequenceStorageBaseNode { public abstract ArrayBasedSequenceStorage execute(Node inliningTarget, StorageType type, int cap); @@ -3149,6 +3104,46 @@ static ObjectSequenceStorage doObject(@SuppressWarnings("unused") StorageType ty } } + @GenerateInline + @GenerateCached(false) + @GenerateUncached + @ImportStatic(StorageType.class) + abstract static class CreateEmptyForTypesNode extends SequenceStorageBaseNode { + + public abstract SequenceStorage execute(Node inliningTarget, StorageType type1, StorageType type2, int cap); + + @Specialization(guards = {"type1 == type2 || type2 == Empty", "type1 != Empty"}) + static SequenceStorage doSameOr1Empty(Node inliningTarget, StorageType type1, @SuppressWarnings("unused") StorageType type2, int cap, + @Shared @Cached CreateEmptyForTypeNode create) { + return create.execute(inliningTarget, type1, cap); + } + + @Specialization(guards = {"type1 == Empty", "type2 != Empty"}) + static SequenceStorage do2Empty(Node inliningTarget, @SuppressWarnings("unused") StorageType type1, StorageType type2, int cap, + @Shared @Cached CreateEmptyForTypeNode create) { + return create.execute(inliningTarget, type2, cap); + } + + @Specialization(guards = {"type1 == Empty", "type2 == Empty", "cap == 0"}) + static SequenceStorage doBothEmpty(@SuppressWarnings("unused") StorageType type1, @SuppressWarnings("unused") StorageType type2, @SuppressWarnings("unused") int cap) { + return EmptySequenceStorage.INSTANCE; + } + + @Specialization(guards = "generalizeToLong(type1, type2)") + static SequenceStorage doLong(@SuppressWarnings("unused") StorageType type1, @SuppressWarnings("unused") StorageType type2, int cap) { + return new LongSequenceStorage(cap); + } + + @Fallback + static SequenceStorage doObject(@SuppressWarnings("unused") StorageType type1, @SuppressWarnings("unused") StorageType type2, int cap) { + return new ObjectSequenceStorage(cap); + } + + protected static boolean generalizeToLong(StorageType type1, StorageType type2) { + return isInt(type1) && isLong(type2) || isLong(type1) && isInt(type2); + } + } + @GenerateUncached @GenerateInline @GenerateCached(false) @@ -3226,7 +3221,7 @@ static void doNativeByte(NativeByteSequenceStorage s, int cap, @Shared @CachedLibrary(limit = "2") InteropLibrary lib, @Shared @Cached CStructAccess.AllocateNode alloc, @Shared @Cached CStructAccess.FreeNode free, - @Shared @Cached PRaiseNode.Lazy raiseNode, + @Shared @Cached PRaiseNode raiseNode, @Cached CStructAccess.ReadByteNode read, @Cached CStructAccess.WriteByteNode write) { int oldCapacity = s.getCapacity(); @@ -3235,7 +3230,7 @@ static void doNativeByte(NativeByteSequenceStorage s, int cap, Object oldMem = s.getPtr(); Object newMem = alloc.alloc(newCapacity); if (lib.isNull(newMem)) { - throw raiseNode.get(inliningTarget).raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } // TODO: turn this into a memcpy for (long i = 0; i < oldCapacity; i++) { @@ -3253,7 +3248,7 @@ static void doNativeObject(NativeObjectSequenceStorage s, int cap, @Shared @CachedLibrary(limit = "2") InteropLibrary lib, @Shared @Cached CStructAccess.AllocateNode alloc, @Shared @Cached CStructAccess.FreeNode free, - @Shared @Cached PRaiseNode.Lazy raiseNode, + @Shared @Cached PRaiseNode raiseNode, @Cached CStructAccess.ReadPointerNode read, @Cached CStructAccess.WritePointerNode write) { int oldCapacity = s.getCapacity(); @@ -3263,7 +3258,7 @@ static void doNativeObject(NativeObjectSequenceStorage s, int cap, long bytes = newCapacity * 8; Object newMem = alloc.alloc(bytes); if (lib.isNull(newMem)) { - throw raiseNode.get(inliningTarget).raise(MemoryError); + throw raiseNode.raise(inliningTarget, MemoryError); } // TODO: turn this into a memcpy for (long i = 0; i < oldCapacity; i++) { @@ -3689,7 +3684,7 @@ static void multipleSteps(Node inliningTarget, SequenceStorage store, SliceInfo multipleSteps(store, sinfo, inliningTarget, setLenNode, ensureCapacityNode, memove); } - static void multipleSteps(SequenceStorage self, PSlice.SliceInfo sinfo, + static void multipleSteps(SequenceStorage self, SliceInfo sinfo, Node inliningTarget, SetLenNode setLenNode, EnsureCapacityNode ensureCapacityNode, @@ -3749,42 +3744,42 @@ public abstract static class GetElementType extends Node { @Specialization static StorageType type(EmptySequenceStorage s) { - return StorageType.Empty; + return Empty; } @Specialization static StorageType type(BoolSequenceStorage s) { - return StorageType.Boolean; + return Boolean; } @Specialization static StorageType type(ByteSequenceStorage s) { - return StorageType.Byte; + return Byte; } @Specialization static StorageType type(NativeByteSequenceStorage s) { - return StorageType.Byte; + return Byte; } @Specialization static StorageType type(IntSequenceStorage s) { - return StorageType.Int; + return Int; } @Specialization static StorageType type(NativeIntSequenceStorage s) { - return StorageType.Int; + return Int; } @Specialization static StorageType type(LongSequenceStorage s) { - return StorageType.Long; + return Long; } @Specialization static StorageType type(DoubleSequenceStorage s) { - return StorageType.Double; + return Double; } @Fallback @@ -3854,10 +3849,10 @@ int doDouble(DoubleSequenceStorage s, double item, int start, int end) { @Specialization static int doGeneric(VirtualFrame frame, Node inliningTarget, SequenceStorage s, Object item, int start, int end, @Cached GetItemScalarNode getItemNode, - @Cached PyObjectRichCompareBool.EqNode eqNode) { + @Cached PyObjectRichCompareBool eqNode) { for (int i = start; i < getLength(s, end); i++) { Object seqItem = getItemNode.execute(inliningTarget, s, i); - if (eqNode.compare(frame, inliningTarget, seqItem, item)) { + if (eqNode.execute(frame, inliningTarget, seqItem, item, RichCmpOp.Py_EQ)) { return i; } } @@ -4141,11 +4136,11 @@ public final SequenceStorage execute(VirtualFrame frame, Object iterator) { private static final int START_SIZE = 4; - protected SequenceStorage createStorage(VirtualFrame frame, Object iterator, int len, StorageType type, GetNextNode nextNode, IsBuiltinObjectProfile errorProfile, + protected SequenceStorage createStorage(VirtualFrame frame, Object iterator, int len, StorageType type, PyIterNextNode nextNode, Node inliningTarget, InlinedCountingConditionProfile growArrayProfile) { final int size = len > 0 ? len : START_SIZE; if (type == Uninitialized || type == Empty) { - return createStorageUninitialized(frame, inliningTarget, iterator, nextNode, errorProfile, size); + return createStorageUninitialized(frame, inliningTarget, iterator, nextNode, size); } else { int i = 0; Object array = null; @@ -4154,107 +4149,118 @@ protected SequenceStorage createStorage(VirtualFrame frame, Object iterator, int case Boolean: { boolean[] elements = new boolean[size]; array = elements; - try { - while (true) { - boolean value = nextNode.executeBoolean(frame, iterator); - if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { - array = elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); - } - elements[i++] = value; + while (true) { + Object next; + try { + next = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { + LoopNode.reportLoopCount(this, i); + break; + } + boolean value = PGuards.expectBoolean(next); + if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { + array = elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); } - } catch (PException e) { - LoopNode.reportLoopCount(this, i); - e.expectStopIteration(inliningTarget, errorProfile); + elements[i++] = value; } return new BoolSequenceStorage(elements, i); } case Byte: { byte[] elements = new byte[size]; array = elements; - try { - while (true) { - int value = nextNode.executeInt(frame, iterator); - byte bvalue; - try { - bvalue = PInt.byteValueExact(value); - if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { - array = elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); - } - elements[i++] = bvalue; - } catch (OverflowException e) { - throw new UnexpectedResultException(value); + while (true) { + Object next; + try { + next = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { + LoopNode.reportLoopCount(this, i); + break; + } + int value = PGuards.expectInteger(next); + byte bvalue; + try { + bvalue = PInt.byteValueExact(value); + if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { + array = elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); } + elements[i++] = bvalue; + } catch (OverflowException e) { + throw new UnexpectedResultException(value); } - } catch (PException e) { - LoopNode.reportLoopCount(this, i); - e.expectStopIteration(inliningTarget, errorProfile); } return new ByteSequenceStorage(elements, i); } case Int: { int[] elements = new int[size]; array = elements; - try { - while (true) { - int value = nextNode.executeInt(frame, iterator); - if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { - array = elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); - } - elements[i++] = value; + while (true) { + Object next; + try { + next = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { + LoopNode.reportLoopCount(this, i); + break; + } + int value = PGuards.expectInteger(next); + if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { + array = elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); } - } catch (PException e) { - LoopNode.reportLoopCount(this, i); - e.expectStopIteration(inliningTarget, errorProfile); + elements[i++] = value; } return new IntSequenceStorage(elements, i); } case Long: { long[] elements = new long[size]; array = elements; - try { - while (true) { - long value = nextNode.executeLong(frame, iterator); - if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { - array = elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); - } - elements[i++] = value; + while (true) { + Object next; + try { + next = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { + LoopNode.reportLoopCount(this, i); + break; } - } catch (PException e) { - LoopNode.reportLoopCount(this, i); - e.expectStopIteration(inliningTarget, errorProfile); + long value = PGuards.expectLong(next); + if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { + array = elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); + } + elements[i++] = value; } return new LongSequenceStorage(elements, i); } case Double: { double[] elements = new double[size]; array = elements; - try { - while (true) { - double value = nextNode.executeDouble(frame, iterator); - if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { - array = elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); - } - elements[i++] = value; + while (true) { + Object next; + try { + next = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { + LoopNode.reportLoopCount(this, i); + break; } - } catch (PException e) { - LoopNode.reportLoopCount(this, i); - e.expectStopIteration(inliningTarget, errorProfile); + double value = PGuards.expectDouble(next); + if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { + array = elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); + } + elements[i++] = value; } return new DoubleSequenceStorage(elements, i); } case Generic: { Object[] elements = new Object[size]; - try { - while (true) { - Object value = nextNode.execute(frame, iterator); - if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { - elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); - } - elements[i++] = value; + while (true) { + Object value; + try { + value = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { + LoopNode.reportLoopCount(this, i); + break; } - } catch (PException e) { - LoopNode.reportLoopCount(this, i); - e.expectStopIteration(inliningTarget, errorProfile); + if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { + elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); + } + elements[i++] = value; } return new ObjectSequenceStorage(elements, i); } @@ -4263,33 +4269,32 @@ protected SequenceStorage createStorage(VirtualFrame frame, Object iterator, int throw new RuntimeException("unexpected state"); } } catch (UnexpectedResultException e) { - return genericFallback(frame, iterator, array, i, e.getResult(), nextNode, errorProfile, inliningTarget, growArrayProfile); + return genericFallback(frame, iterator, array, i, e.getResult(), nextNode, inliningTarget, growArrayProfile); } } } - private SequenceStorage createStorageUninitialized(VirtualFrame frame, Node inliningTarget, Object iterator, GetNextNode nextNode, IsBuiltinObjectProfile errorProfile, int size) { + private SequenceStorage createStorageUninitialized(VirtualFrame frame, Node inliningTarget, Object iterator, PyIterNextNode nextNode, int size) { Object[] elements = new Object[size]; int i = 0; while (true) { + Object value; try { - Object value = nextNode.execute(frame, iterator); - if (i >= elements.length) { - // Intentionally not profiled, because "size" can be reprofiled after this - // first initialization run - elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); - } - elements[i++] = value; - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); + value = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { LoopNode.reportLoopCount(this, i); - break; + return SequenceStorageFactory.createStorage(PythonUtils.arrayCopyOf(elements, i)); } + if (i >= elements.length) { + // Intentionally not profiled, because "size" can be reprofiled after this + // first initialization run + elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); + } + elements[i++] = value; } - return SequenceStorageFactory.createStorage(PythonUtils.arrayCopyOf(elements, i)); } - private SequenceStorage genericFallback(VirtualFrame frame, Object iterator, Object array, int count, Object result, GetNextNode nextNode, IsBuiltinObjectProfile errorProfile, + private SequenceStorage genericFallback(VirtualFrame frame, Object iterator, Object array, int count, Object result, PyIterNextNode nextNode, Node inliningTarget, InlinedCountingConditionProfile growArrayProfile) { Object[] elements = new Object[Array.getLength(array) * 2]; int i = 0; @@ -4298,19 +4303,18 @@ private SequenceStorage genericFallback(VirtualFrame frame, Object iterator, Obj } elements[i++] = result; while (true) { + Object value; try { - Object value = nextNode.execute(frame, iterator); - if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { - elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); - } - elements[i++] = value; - } catch (PException e) { + value = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { LoopNode.reportLoopCount(this, i); - e.expectStopIteration(inliningTarget, errorProfile); - break; + return new ObjectSequenceStorage(elements, i); + } + if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { + elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); } + elements[i++] = value; } - return new ObjectSequenceStorage(elements, i); } /** @@ -4320,120 +4324,146 @@ private SequenceStorage genericFallback(VirtualFrame frame, Object iterator, Obj protected static SequenceStorage createStorageFromBuiltin(VirtualFrame frame, PBuiltinIterator iterator, int len, StorageType type, NextHelperNode nextNode, IsBuiltinObjectProfile errorProfile, Node inliningTarget, InlinedCountingConditionProfile growArrayProfile, InlinedLoopConditionProfile loopProfile) { final int size = len > 0 ? len : START_SIZE; + int i = 0; + boolean exhausted = false; if (type == Uninitialized || type == Empty) { Object[] elements = new Object[size]; - int i = 0; - try { - Object value; - for (; loopProfile.profile(inliningTarget, (value = nextNode.execute(frame, inliningTarget, iterator, false)) != STOP_MARKER); i++) { + while (loopProfile.profile(inliningTarget, !exhausted)) { + try { + Object value = nextNode.execute(frame, inliningTarget, iterator); if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); } - elements[i] = value; + elements[i++] = value; + } catch (IteratorExhausted e) { + exhausted = true; + } catch (PException e) { + e.expectStopIteration(inliningTarget, errorProfile); + exhausted = true; } - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); } return SequenceStorageFactory.createStorage(PythonUtils.arrayCopyOf(elements, i)); } else { - int i = 0; Object array = null; try { - Object value; switch (type) { case Boolean: { boolean[] elements = new boolean[size]; array = elements; - try { - for (; loopProfile.profile(inliningTarget, (value = nextNode.execute(frame, inliningTarget, iterator, false)) != STOP_MARKER); i++) { + while (loopProfile.profile(inliningTarget, !exhausted)) { + try { + Object value = nextNode.execute(frame, inliningTarget, iterator); if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); array = elements; } elements[i] = PGuards.expectBoolean(value); + } catch (IteratorExhausted e) { + exhausted = true; + } catch (PException e) { + e.expectStopIteration(inliningTarget, errorProfile); + exhausted = true; } - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); } return new BoolSequenceStorage(elements, i); } case Byte: { byte[] elements = new byte[size]; array = elements; - try { - for (; loopProfile.profile(inliningTarget, (value = nextNode.execute(frame, inliningTarget, iterator, false)) != STOP_MARKER); i++) { + while (loopProfile.profile(inliningTarget, !exhausted)) { + try { + Object value = nextNode.execute(frame, inliningTarget, iterator); byte bvalue; try { bvalue = PInt.byteValueExact(PGuards.expectInteger(value)); - if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { - array = elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); - } - elements[i] = bvalue; } catch (OverflowException e) { throw new UnexpectedResultException(value); } + if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { + array = elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); + } + elements[i++] = bvalue; + } catch (IteratorExhausted e) { + exhausted = true; + } catch (PException e) { + e.expectStopIteration(inliningTarget, errorProfile); + exhausted = true; } - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); } return new ByteSequenceStorage(elements, i); } case Int: { int[] elements = new int[size]; array = elements; - try { - for (; loopProfile.profile(inliningTarget, (value = nextNode.execute(frame, inliningTarget, iterator, false)) != STOP_MARKER); i++) { + while (loopProfile.profile(inliningTarget, !exhausted)) { + try { + Object value = nextNode.execute(frame, inliningTarget, iterator); if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { array = elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); } - elements[i] = PGuards.expectInteger(value); + elements[i++] = PGuards.expectInteger(value); + } catch (IteratorExhausted e) { + exhausted = true; + } catch (PException e) { + e.expectStopIteration(inliningTarget, errorProfile); + exhausted = true; } - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); } return new IntSequenceStorage(elements, i); } case Long: { long[] elements = new long[size]; array = elements; - try { - for (; loopProfile.profile(inliningTarget, (value = nextNode.execute(frame, inliningTarget, iterator, false)) != STOP_MARKER); i++) { + while (loopProfile.profile(inliningTarget, !exhausted)) { + try { + Object value = nextNode.execute(frame, inliningTarget, iterator); if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { array = elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); } - elements[i] = PGuards.expectLong(value); + elements[i++] = PGuards.expectLong(value); + } catch (IteratorExhausted e) { + exhausted = true; + } catch (PException e) { + e.expectStopIteration(inliningTarget, errorProfile); + exhausted = true; } - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); } return new LongSequenceStorage(elements, i); } case Double: { double[] elements = new double[size]; array = elements; - try { - for (; loopProfile.profile(inliningTarget, (value = nextNode.execute(frame, inliningTarget, iterator, false)) != STOP_MARKER); i++) { + while (loopProfile.profile(inliningTarget, !exhausted)) { + try { + Object value = nextNode.execute(frame, inliningTarget, iterator); if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { array = elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); } - elements[i] = PGuards.expectDouble(value); + elements[i++] = PGuards.expectDouble(value); + } catch (IteratorExhausted e) { + exhausted = true; + } catch (PException e) { + e.expectStopIteration(inliningTarget, errorProfile); + exhausted = true; } - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); } return new DoubleSequenceStorage(elements, i); } case Generic: { Object[] elements = new Object[size]; - try { - for (; loopProfile.profile(inliningTarget, (value = nextNode.execute(frame, inliningTarget, iterator, false)) != STOP_MARKER); i++) { + while (loopProfile.profile(inliningTarget, !exhausted)) { + try { + Object value = nextNode.execute(frame, inliningTarget, iterator); if (growArrayProfile.profile(inliningTarget, i >= elements.length)) { elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); } - elements[i] = value; + elements[i++] = value; + } catch (IteratorExhausted e) { + exhausted = true; + } catch (PException e) { + e.expectStopIteration(inliningTarget, errorProfile); + exhausted = true; } - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); } return new ObjectSequenceStorage(elements, i); } @@ -4442,7 +4472,7 @@ protected static SequenceStorage createStorageFromBuiltin(VirtualFrame frame, PB throw new RuntimeException("unexpected state"); } } catch (UnexpectedResultException e) { - return genericFallback(frame, iterator, array, i, e.getResult(), nextNode, inliningTarget, errorProfile); + return genericFallback(frame, iterator, array, i - 1, e.getResult(), nextNode, inliningTarget, errorProfile); } } } @@ -4455,16 +4485,18 @@ private static SequenceStorage genericFallback(VirtualFrame frame, PBuiltinItera elements[i] = Array.get(array, i); } elements[i++] = result; - Object value; - try { - while ((value = nextNode.execute(frame, inliningTarget, iterator, false)) != STOP_MARKER) { + while (true) { + try { + Object value = nextNode.execute(frame, inliningTarget, iterator); if (i >= elements.length) { elements = PythonUtils.arrayCopyOf(elements, elements.length * 2); } elements[i++] = value; + } catch (IteratorExhausted e) { + break; + } catch (PException e) { + e.expectStopIteration(inliningTarget, errorProfile); } - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); } return new ObjectSequenceStorage(elements, i); } @@ -4478,7 +4510,7 @@ public abstract static class CreateStorageFromIteratorNodeCached extends CreateS @CompilationFinal int startSizeProfiled = START_SIZE; public boolean isBuiltinIterator(GetClassNode getClass, Node inliningTarget, Object iterator) { - return iterator instanceof PBuiltinIterator && getClass.execute(inliningTarget, (PBuiltinIterator) iterator) == PythonBuiltinClassType.PIterator; + return iterator instanceof PBuiltinIterator && getClass.execute(inliningTarget, iterator) == PythonBuiltinClassType.PIterator; } public static SequenceStorage getSequenceStorage(Node inliningTarget, GetInternalIteratorSequenceStorage node, PBuiltinIterator iterator) { @@ -4531,11 +4563,10 @@ public SequenceStorage createBuiltinKnownLen(VirtualFrame frame, PBuiltinIterato public SequenceStorage createGenericUnknownLen(VirtualFrame frame, Object iterator, @SuppressWarnings("unused") int len, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, - @Shared("errProfile") @Cached IsBuiltinObjectProfile errorProfile, @Shared("arrayGrowProfile") @Cached InlinedCountingConditionProfile arrayGrowProfile, @Shared @Cached GetElementType getElementType, - @Shared @Cached GetNextNode getNextNode) { - SequenceStorage s = createStorage(frame, iterator, startSizeProfiled, expectedElementType, getNextNode, errorProfile, inliningTarget, arrayGrowProfile); + @Shared @Cached PyIterNextNode nextNode) { + SequenceStorage s = createStorage(frame, iterator, startSizeProfiled, expectedElementType, nextNode, inliningTarget, arrayGrowProfile); return profileResult(getElementType, inliningTarget, s, true); } @@ -4543,11 +4574,10 @@ public SequenceStorage createGenericUnknownLen(VirtualFrame frame, Object iterat public SequenceStorage createGenericKnownLen(VirtualFrame frame, Object iterator, int len, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached GetClassNode getClassNode, - @Shared("errProfile") @Cached IsBuiltinObjectProfile errorProfile, @Shared("arrayGrowProfile") @Cached InlinedCountingConditionProfile arrayGrowProfile, @Shared @Cached GetElementType getElementType, - @Shared @Cached GetNextNode getNextNode) { - SequenceStorage s = createStorage(frame, iterator, len, expectedElementType, getNextNode, errorProfile, inliningTarget, arrayGrowProfile); + @Shared @Cached PyIterNextNode nextNode) { + SequenceStorage s = createStorage(frame, iterator, len, expectedElementType, nextNode, inliningTarget, arrayGrowProfile); return profileResult(getElementType, inliningTarget, s, false); } @@ -4581,11 +4611,11 @@ private static SequenceStorage executeImpl(Object iterator, int len) { if (GetPythonObjectClassNode.executeUncached(pbi) == PythonBuiltinClassType.PIterator && pbi.index == 0 && !pbi.isExhausted()) { SequenceStorage s = GetInternalIteratorSequenceStorage.executeUncached(pbi); if (s != null) { - return SequenceStorageNodes.CopyNode.executeUncached(s); + return CopyNode.executeUncached(s); } } } - return create().createStorageUninitialized(null, null, iterator, GetNextNode.getUncached(), IsBuiltinObjectProfile.getUncached(), len >= 0 ? len : START_SIZE); + return create().createStorageUninitialized(null, null, iterator, PyIterNextNode.getUncached(), len >= 0 ? len : START_SIZE); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SortNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SortNodes.java index 241d0d724b..bd6c7bd2b2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SortNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SortNodes.java @@ -50,11 +50,11 @@ import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.function.Signature; import com.oracle.graal.python.builtins.objects.str.StringUtils; -import com.oracle.graal.python.lib.PyObjectIsTrueNode; +import com.oracle.graal.python.lib.RichCmpOp; +import com.oracle.graal.python.lib.PyObjectRichCompareBool.CachedPyObjectRichCompareBool; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRootNode; import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.expression.BinaryComparisonNode; import com.oracle.graal.python.runtime.ExecutionContext; import com.oracle.graal.python.runtime.ExecutionContext.CallContext; import com.oracle.graal.python.runtime.ExecutionContext.IndirectCalleeContext; @@ -100,12 +100,11 @@ public SortingPair(Object key, Object value) { } private static class ObjectComparatorRootNode extends PRootNode { - private static final Signature SIGNATURE = new Signature(-1, false, -1, false, tsArray("a", "b"), PythonUtils.EMPTY_TRUFFLESTRING_ARRAY); + private static final Signature SIGNATURE = new Signature(-1, false, -1, tsArray("a", "b"), PythonUtils.EMPTY_TRUFFLESTRING_ARRAY); @Child private ExecutionContext.CalleeContext calleeContext = ExecutionContext.CalleeContext.create(); - @Child private PyObjectIsTrueNode isTrueNode = PyObjectIsTrueNode.create(); - @Child private BinaryComparisonNode.LtNode ltNodeA = BinaryComparisonNode.LtNode.create(); - @Child private BinaryComparisonNode.LtNode ltNodeB = BinaryComparisonNode.LtNode.create(); + @Child private CachedPyObjectRichCompareBool ltNodeA = CachedPyObjectRichCompareBool.create(); + @Child private CachedPyObjectRichCompareBool ltNodeB = CachedPyObjectRichCompareBool.create(); enum Result { LT(-1), @@ -131,9 +130,9 @@ public Object execute(VirtualFrame frame) { Object[] arguments = frame.getArguments(); Object a = arguments[PArguments.USER_ARGUMENTS_OFFSET]; Object b = arguments[PArguments.USER_ARGUMENTS_OFFSET + 1]; - if (isTrueNode.execute(frame, ltNodeA.executeObject(frame, a, b))) { + if (ltNodeA.execute(frame, a, b, RichCmpOp.Py_LT)) { return Result.LT; - } else if (isTrueNode.execute(frame, ltNodeB.executeObject(frame, b, a))) { + } else if (ltNodeB.execute(frame, b, a, RichCmpOp.Py_LT)) { return Result.GT; } else { return Result.EQ; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/complex/ComplexBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/complex/ComplexBuiltins.java index 1a2d47ab09..e985ae9016 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/complex/ComplexBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/complex/ComplexBuiltins.java @@ -42,47 +42,54 @@ import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyComplexObject__cval__imag; import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyComplexObject__cval__real; +import static com.oracle.graal.python.nodes.BuiltinNames.J_COMPLEX; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___COMPLEX__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___FORMAT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETNEWARGS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___POW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RPOW__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___COMPLEX__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.OverflowError; +import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ZeroDivisionError; import static com.oracle.graal.python.runtime.formatting.FormattingUtils.validateForFloat; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.modules.SysModuleBuiltins; +import com.oracle.graal.python.builtins.modules.WarningsModuleBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; +import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes; +import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol; +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions; import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; import com.oracle.graal.python.builtins.objects.common.FormatNodeBase; import com.oracle.graal.python.builtins.objects.complex.ComplexBuiltinsClinicProviders.FormatNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.floats.FloatBuiltins; +import com.oracle.graal.python.builtins.objects.floats.FloatUtils; +import com.oracle.graal.python.builtins.objects.floats.PFloat; import com.oracle.graal.python.builtins.objects.ints.PInt; +import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotInquiry.NbBoolBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare; +import com.oracle.graal.python.lib.CanBeDoubleNode; import com.oracle.graal.python.lib.PyComplexCheckExactNode; import com.oracle.graal.python.lib.PyComplexCheckNode; import com.oracle.graal.python.lib.PyFloatAsDoubleNode; @@ -90,27 +97,34 @@ import com.oracle.graal.python.lib.PyLongAsDoubleNode; import com.oracle.graal.python.lib.PyLongCheckNode; import com.oracle.graal.python.lib.PyObjectHashNode; +import com.oracle.graal.python.lib.PyObjectReprAsObjectNode; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; +import com.oracle.graal.python.nodes.object.BuiltinClassProfiles; +import com.oracle.graal.python.nodes.truffle.PythonIntegerAndFloatTypes; +import com.oracle.graal.python.nodes.util.CastToJavaStringNode; +import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; import com.oracle.graal.python.runtime.formatting.ComplexFormatter; import com.oracle.graal.python.runtime.formatting.InternalFormat; import com.oracle.graal.python.runtime.formatting.InternalFormat.Spec; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.CompilerDirectives.ValueType; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -208,6 +222,486 @@ static ComplexValue doOther(Node inliningTarget, Object v) { } } + // complex([real[, imag]]) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = J_COMPLEX, minNumOfPositionalArgs = 1, parameterNames = {"$cls", "real", "imag"}) + @GenerateNodeFactory + public abstract static class ComplexNewNode extends PythonTernaryBuiltinNode { + @Child private PyObjectReprAsObjectNode reprNode; + @Child private LookupAndCallUnaryNode callComplexNode; + @Child private WarningsModuleBuiltins.WarnNode warnNode; + + @GenerateInline + @GenerateCached(false) + @GenerateUncached + abstract static class CreateComplexNode extends Node { + public abstract Object execute(Node inliningTarget, Object cls, double real, double imaginary); + + public static Object executeUncached(Object cls, double real, double imaginary) { + return ComplexBuiltinsFactory.ComplexNewNodeFactory.CreateComplexNodeGen.getUncached().execute(null, cls, real, imaginary); + } + + @Specialization(guards = "!needsNativeAllocationNode.execute(inliningTarget, cls)", limit = "1") + static PComplex doManaged(@SuppressWarnings("unused") Node inliningTarget, Object cls, double real, double imaginary, + @SuppressWarnings("unused") @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + return PFactory.createComplex(language, cls, getInstanceShape.execute(cls), real, imaginary); + } + + @Fallback + static Object doNative(Node inliningTarget, Object cls, double real, double imaginary, + @Cached(inline = false) CExtNodes.PCallCapiFunction callCapiFunction, + @Cached(inline = false) CApiTransitions.PythonToNativeNode toNativeNode, + @Cached(inline = false) CApiTransitions.NativeToPythonTransferNode toPythonNode, + @Cached(inline = false) ExternalFunctionNodes.DefaultCheckFunctionResultNode checkFunctionResultNode) { + NativeCAPISymbol symbol = NativeCAPISymbol.FUN_COMPLEX_SUBTYPE_FROM_DOUBLES; + Object nativeResult = callCapiFunction.call(symbol, toNativeNode.execute(cls), real, imaginary); + return toPythonNode.execute(checkFunctionResultNode.execute(PythonContext.get(inliningTarget), symbol.getTsName(), nativeResult)); + } + } + + @Specialization(guards = {"isNoValue(real)", "isNoValue(imag)"}) + @SuppressWarnings("unused") + static Object complexFromNone(Object cls, PNone real, PNone imag, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode) { + return createComplexNode.execute(inliningTarget, cls, 0, 0); + } + + @Specialization + static Object complexFromIntInt(Object cls, int real, int imaginary, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode) { + return createComplexNode.execute(inliningTarget, cls, real, imaginary); + } + + @Specialization + static Object complexFromLongLong(Object cls, long real, long imaginary, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode) { + return createComplexNode.execute(inliningTarget, cls, real, imaginary); + } + + @Specialization + static Object complexFromLongLong(Object cls, PInt real, PInt imaginary, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode) { + return createComplexNode.execute(inliningTarget, cls, real.doubleValueWithOverflow(inliningTarget), + imaginary.doubleValueWithOverflow(inliningTarget)); + } + + @Specialization + static Object complexFromDoubleDouble(Object cls, double real, double imaginary, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode) { + return createComplexNode.execute(inliningTarget, cls, real, imaginary); + } + + @Specialization(guards = "isNoValue(imag)") + static Object complexFromDouble(Object cls, double real, @SuppressWarnings("unused") PNone imag, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode) { + return createComplexNode.execute(inliningTarget, cls, real, 0); + } + + @Specialization(guards = "isNoValue(imag)") + Object complexFromDouble(VirtualFrame frame, Object cls, PFloat real, @SuppressWarnings("unused") PNone imag, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode, + @Cached.Shared @Cached CanBeDoubleNode canBeDoubleNode, + @Cached.Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, + @Cached.Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, + @Cached.Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, + @Cached.Shared("isPrimitive") @Cached BuiltinClassProfiles.IsBuiltinClassExactProfile isPrimitiveProfile, + @Cached.Shared("isBuiltinObj") @Cached PyComplexCheckExactNode isBuiltinObjectProfile, + @Cached.Shared @Cached PRaiseNode raiseNode) { + return complexFromObject(frame, cls, real, imag, inliningTarget, createComplexNode, canBeDoubleNode, asDoubleNode, isComplexType, isResultComplexType, isPrimitiveProfile, + isBuiltinObjectProfile, + raiseNode); + } + + @Specialization(guards = "isNoValue(imag)") + static Object complexFromInt(Object cls, int real, @SuppressWarnings("unused") PNone imag, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode) { + return createComplexNode.execute(inliningTarget, cls, real, 0); + } + + @Specialization(guards = "isNoValue(imag)") + static Object complexFromLong(Object cls, long real, @SuppressWarnings("unused") PNone imag, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode) { + return createComplexNode.execute(inliningTarget, cls, real, 0); + } + + @Specialization(guards = "isNoValue(imag)") + Object complexFromLong(VirtualFrame frame, Object cls, PInt real, @SuppressWarnings("unused") PNone imag, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode, + @Cached.Shared @Cached CanBeDoubleNode canBeDoubleNode, + @Cached.Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, + @Cached.Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, + @Cached.Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, + @Cached.Shared("isPrimitive") @Cached BuiltinClassProfiles.IsBuiltinClassExactProfile isPrimitiveProfile, + @Cached.Shared("isBuiltinObj") @Cached PyComplexCheckExactNode complexCheck, + @Cached.Shared @Cached PRaiseNode raiseNode) { + return complexFromObject(frame, cls, real, imag, inliningTarget, createComplexNode, canBeDoubleNode, asDoubleNode, isComplexType, isResultComplexType, isPrimitiveProfile, complexCheck, + raiseNode); + } + + @Specialization(guards = {"isNoValue(imag)", "!isNoValue(number)", "!isString(number)"}) + Object complexFromObject(VirtualFrame frame, Object cls, Object number, @SuppressWarnings("unused") PNone imag, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode, + @Cached.Shared @Cached CanBeDoubleNode canBeDoubleNode, + @Cached.Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, + @Cached.Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, + @Cached.Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, + @Cached.Shared("isPrimitive") @Cached BuiltinClassProfiles.IsBuiltinClassExactProfile isPrimitiveProfile, + @Cached.Shared("isBuiltinObj") @Cached PyComplexCheckExactNode complexCheck, + @Cached.Shared @Cached PRaiseNode raiseNode) { + PComplex value = getComplexNumberFromObject(frame, number, inliningTarget, isComplexType, isResultComplexType, raiseNode); + if (value == null) { + if (canBeDoubleNode.execute(inliningTarget, number)) { + return createComplexNode.execute(inliningTarget, cls, asDoubleNode.execute(frame, inliningTarget, number), 0.0); + } else { + throw raiseFirstArgError(number, inliningTarget, raiseNode); + } + } + if (isPrimitiveProfile.profileClass(inliningTarget, cls, PythonBuiltinClassType.PComplex)) { + if (complexCheck.execute(inliningTarget, value)) { + return value; + } + return PFactory.createComplex(PythonLanguage.get(inliningTarget), value.getReal(), value.getImag()); + } + return createComplexNode.execute(inliningTarget, cls, value.getReal(), value.getImag()); + } + + @Specialization + static Object complexFromLongComplex(Object cls, long one, PComplex two, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode) { + return createComplexNode.execute(inliningTarget, cls, one - two.getImag(), two.getReal()); + } + + @Specialization + static Object complexFromPIntComplex(Object cls, PInt one, PComplex two, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode) { + return createComplexNode.execute(inliningTarget, cls, one.doubleValueWithOverflow(inliningTarget) - two.getImag(), two.getReal()); + } + + @Specialization + static Object complexFromDoubleComplex(Object cls, double one, PComplex two, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode) { + return createComplexNode.execute(inliningTarget, cls, one - two.getImag(), two.getReal()); + } + + @Specialization(guards = "!isString(one)") + Object complexFromComplexLong(VirtualFrame frame, Object cls, Object one, long two, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode, + @Cached.Shared @Cached CanBeDoubleNode canBeDoubleNode, + @Cached.Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, + @Cached.Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, + @Cached.Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, + @Cached.Shared @Cached PRaiseNode raiseNode) { + PComplex value = getComplexNumberFromObject(frame, one, inliningTarget, isComplexType, isResultComplexType, raiseNode); + if (value == null) { + if (canBeDoubleNode.execute(inliningTarget, one)) { + return createComplexNode.execute(inliningTarget, cls, asDoubleNode.execute(frame, inliningTarget, one), two); + } else { + throw raiseFirstArgError(one, inliningTarget, raiseNode); + } + } + return createComplexNode.execute(inliningTarget, cls, value.getReal(), value.getImag() + two); + } + + @Specialization(guards = "!isString(one)") + Object complexFromComplexDouble(VirtualFrame frame, Object cls, Object one, double two, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode, + @Cached.Shared @Cached CanBeDoubleNode canBeDoubleNode, + @Cached.Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, + @Cached.Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, + @Cached.Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, + @Cached.Shared @Cached PRaiseNode raiseNode) { + PComplex value = getComplexNumberFromObject(frame, one, inliningTarget, isComplexType, isResultComplexType, raiseNode); + if (value == null) { + if (canBeDoubleNode.execute(inliningTarget, one)) { + return createComplexNode.execute(inliningTarget, cls, asDoubleNode.execute(frame, inliningTarget, one), two); + } else { + throw raiseFirstArgError(one, inliningTarget, raiseNode); + } + } + return createComplexNode.execute(inliningTarget, cls, value.getReal(), value.getImag() + two); + } + + @Specialization(guards = "!isString(one)") + Object complexFromComplexPInt(VirtualFrame frame, Object cls, Object one, PInt two, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode, + @Cached.Shared @Cached CanBeDoubleNode canBeDoubleNode, + @Cached.Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, + @Cached.Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, + @Cached.Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, + @Cached.Shared @Cached PRaiseNode raiseNode) { + PComplex value = getComplexNumberFromObject(frame, one, inliningTarget, isComplexType, isResultComplexType, raiseNode); + if (value == null) { + if (canBeDoubleNode.execute(inliningTarget, one)) { + return createComplexNode.execute(inliningTarget, cls, asDoubleNode.execute(frame, inliningTarget, one), two.doubleValueWithOverflow(this)); + } else { + throw raiseFirstArgError(one, inliningTarget, raiseNode); + } + } + return createComplexNode.execute(inliningTarget, cls, value.getReal(), value.getImag() + two.doubleValueWithOverflow(this)); + } + + @Specialization(guards = "!isString(one)") + Object complexFromComplexComplex(VirtualFrame frame, Object cls, Object one, PComplex two, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode, + @Cached.Shared @Cached CanBeDoubleNode canBeDoubleNode, + @Cached.Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, + @Cached.Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, + @Cached.Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, + @Cached.Shared @Cached PRaiseNode raiseNode) { + PComplex value = getComplexNumberFromObject(frame, one, inliningTarget, isComplexType, isResultComplexType, raiseNode); + if (value == null) { + if (canBeDoubleNode.execute(inliningTarget, one)) { + return createComplexNode.execute(inliningTarget, cls, asDoubleNode.execute(frame, inliningTarget, one) - two.getImag(), two.getReal()); + } else { + throw raiseFirstArgError(one, inliningTarget, raiseNode); + } + } + return createComplexNode.execute(inliningTarget, cls, value.getReal() - two.getImag(), value.getImag() + two.getReal()); + } + + @Specialization(guards = {"!isString(one)", "!isNoValue(two)", "!isPComplex(two)"}) + @SuppressWarnings("truffle-static-method") + Object complexFromComplexObject(VirtualFrame frame, Object cls, Object one, Object two, + @Bind("this") Node inliningTarget, + @Cached.Shared @Cached CreateComplexNode createComplexNode, + @Cached.Shared @Cached CanBeDoubleNode canBeDoubleNode, + @Cached.Shared("floatAsDouble") @Cached PyFloatAsDoubleNode asDoubleNode, + @Cached.Shared("isComplex") @Cached PyComplexCheckExactNode isComplexType, + @Cached.Shared("isComplexResult") @Cached PyComplexCheckExactNode isResultComplexType, + @Cached.Shared @Cached PRaiseNode raiseNode) { + PComplex oneValue = getComplexNumberFromObject(frame, one, inliningTarget, isComplexType, isResultComplexType, raiseNode); + if (canBeDoubleNode.execute(inliningTarget, two)) { + double twoValue = asDoubleNode.execute(frame, inliningTarget, two); + if (oneValue == null) { + if (canBeDoubleNode.execute(inliningTarget, one)) { + return createComplexNode.execute(inliningTarget, cls, asDoubleNode.execute(frame, inliningTarget, one), twoValue); + } else { + throw raiseFirstArgError(one, inliningTarget, raiseNode); + } + } + return createComplexNode.execute(inliningTarget, cls, oneValue.getReal(), oneValue.getImag() + twoValue); + } else { + throw raiseSecondArgError(two, inliningTarget, raiseNode); + } + } + + @Specialization + Object complexFromString(VirtualFrame frame, Object cls, TruffleString real, Object imaginary, + @Bind("this") Node inliningTarget, + @Cached TruffleString.ToJavaStringNode toJavaStringNode, + @Cached.Shared @Cached PRaiseNode raiseNode) { + if (imaginary != PNone.NO_VALUE) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.COMPLEX_CANT_TAKE_ARG); + } + return convertStringToComplex(frame, inliningTarget, toJavaStringNode.execute(real), cls, real, raiseNode); + } + + @Specialization + Object complexFromString(VirtualFrame frame, Object cls, PString real, Object imaginary, + @Bind("this") Node inliningTarget, + @Cached CastToJavaStringNode castToStringNode, + @Cached.Shared @Cached PRaiseNode raiseNode) { + if (imaginary != PNone.NO_VALUE) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.COMPLEX_CANT_TAKE_ARG); + } + return convertStringToComplex(frame, inliningTarget, castToStringNode.execute(real), cls, real, raiseNode); + } + + private Object callComplex(VirtualFrame frame, Object object) { + if (callComplexNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + callComplexNode = insert(LookupAndCallUnaryNode.create(T___COMPLEX__)); + } + return callComplexNode.executeObject(frame, object); + } + + private WarningsModuleBuiltins.WarnNode getWarnNode() { + if (warnNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + warnNode = insert(WarningsModuleBuiltins.WarnNode.create()); + } + return warnNode; + } + + private static PException raiseFirstArgError(Object x, Node inliningTarget, PRaiseNode raiseNode) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ARG_MUST_BE_STRING_OR_NUMBER, "complex() first", x); + } + + private static PException raiseSecondArgError(Object x, Node inliningTarget, PRaiseNode raiseNode) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ARG_MUST_BE_NUMBER, "complex() second", x); + } + + private PComplex getComplexNumberFromObject(VirtualFrame frame, Object object, Node inliningTarget, + PyComplexCheckExactNode isComplexType, PyComplexCheckExactNode isResultComplexType, PRaiseNode raiseNode) { + if (isComplexType.execute(inliningTarget, object)) { + return (PComplex) object; + } else { + Object result = callComplex(frame, object); + if (result instanceof PComplex) { + if (!isResultComplexType.execute(inliningTarget, result)) { + getWarnNode().warnFormat(frame, null, PythonBuiltinClassType.DeprecationWarning, 1, + ErrorMessages.WARN_P_RETURNED_NON_P, + object, "__complex__", "complex", result, "complex"); + } + return (PComplex) result; + } else if (result != PNone.NO_VALUE) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.COMPLEX_RETURNED_NON_COMPLEX, result); + } + if (object instanceof PComplex) { + // the class extending PComplex but doesn't have __complex__ method + return (PComplex) object; + } + return null; + } + } + + @Fallback + @SuppressWarnings("unused") + static Object complexGeneric(Object cls, Object realObj, Object imaginaryObj, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "complex.__new__(X): X", cls); + } + + // Adapted from CPython's complex_subtype_from_string + private Object convertStringToComplex(VirtualFrame frame, Node inliningTarget, String src, Object cls, Object origObj, PRaiseNode raiseNode) { + String str = FloatUtils.removeUnicodeAndUnderscores(src); + if (str == null) { + if (reprNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + reprNode = insert(PyObjectReprAsObjectNode.create()); + } + Object strStr = reprNode.executeCached(frame, origObj); + if (PGuards.isString(strStr)) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.COULD_NOT_CONVERT_STRING_TO_COMPLEX, strStr); + } else { + // During the formatting of "ValueError: invalid literal ..." exception, + // CPython attempts to raise "TypeError: __repr__ returned non-string", + // which gets later overwitten with the original "ValueError", + // but without any message (since the message formatting failed) + throw raiseNode.raise(inliningTarget, ValueError); + } + } + Object c = convertStringToComplexOrNull(str, cls); + if (c == null) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.COMPLEX_ARG_IS_MALFORMED_STR); + } + return c; + } + + // Adapted from CPython's complex_from_string_inner + @TruffleBoundary + private Object convertStringToComplexOrNull(String str, Object cls) { + int len = str.length(); + + // position on first nonblank + int i = FloatUtils.skipAsciiWhitespace(str, 0, len); + + boolean gotBracket; + if (i < len && str.charAt(i) == '(') { + // Skip over possible bracket from repr(). + gotBracket = true; + i = FloatUtils.skipAsciiWhitespace(str, i + 1, len); + } else { + gotBracket = false; + } + + double x, y; + boolean expectJ; + + // first look for forms starting with + FloatUtils.StringToDoubleResult res1 = FloatUtils.stringToDouble(str, i, len); + if (res1 != null) { + // all 4 forms starting with land here + i = res1.position; + char ch = i < len ? str.charAt(i) : '\0'; + if (ch == '+' || ch == '-') { + // j | j + x = res1.value; + FloatUtils.StringToDoubleResult res2 = FloatUtils.stringToDouble(str, i, len); + if (res2 != null) { + // j + y = res2.value; + i = res2.position; + } else { + // j + y = ch == '+' ? 1.0 : -1.0; + i++; + } + expectJ = true; + } else if (ch == 'j' || ch == 'J') { + // j + i++; + y = res1.value; + x = 0; + expectJ = false; + } else { + // + x = res1.value; + y = 0; + expectJ = false; + } + } else { + // not starting with ; must be j or j + char ch = i < len ? str.charAt(i) : '\0'; + if (ch == '+' || ch == '-') { + // j + y = ch == '+' ? 1.0 : -1.0; + i++; + } else { + // j + y = 1.0; + } + x = 0; + expectJ = true; + } + + if (expectJ) { + char ch = i < len ? str.charAt(i) : '\0'; + if (!(ch == 'j' || ch == 'J')) { + return null; + } + i++; + } + + // trailing whitespace and closing bracket + i = FloatUtils.skipAsciiWhitespace(str, i, len); + if (gotBracket) { + // if there was an opening parenthesis, then the corresponding + // closing parenthesis should be right here + if (i >= len || str.charAt(i) != ')') { + return null; + } + i = FloatUtils.skipAsciiWhitespace(str, i + 1, len); + } + + // we should now be at the end of the string + if (i != len) { + return null; + } + return CreateComplexNode.executeUncached(cls, x, y); + } + } + @Builtin(name = J___COMPLEX__, minNumOfPositionalArgs = 1) @GenerateNodeFactory abstract static class ComplexNode extends PythonUnaryBuiltinNode { @@ -215,13 +709,12 @@ abstract static class ComplexNode extends PythonUnaryBuiltinNode { static Object complex(Object self, @Bind("this") Node inliningTarget, @Cached PyComplexCheckExactNode check, - @Cached ToComplexValueNode toComplexValueNode, - @Cached PythonObjectFactory.Lazy factory) { + @Cached ToComplexValueNode toComplexValueNode) { if (check.execute(inliningTarget, self)) { return self; } else { ComplexValue c = toComplexValueNode.execute(inliningTarget, self); - return factory.get(inliningTarget).createComplex(c.real, c.imag); + return PFactory.createComplex(PythonLanguage.get(inliningTarget), c.real, c.imag); } } } @@ -237,7 +730,7 @@ public abstract static class AbsNode extends PythonUnaryBuiltinNode { static double abs(Object self, @Bind("this") Node inliningTarget, @Cached ToComplexValueNode toComplexValueNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { ComplexValue c = toComplexValueNode.execute(inliningTarget, self); double x = c.getReal(); double y = c.getImag(); @@ -271,7 +764,7 @@ static double abs(Object self, // remove scaling double r = scalb(scaledH, middleExp); if (Double.isInfinite(r)) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.OverflowError, ErrorMessages.ABSOLUTE_VALUE_TOO_LARGE); + throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.ABSOLUTE_VALUE_TOO_LARGE); } return r; } @@ -382,14 +875,14 @@ public static AbsNode create() { abstract static class AddNode extends BinaryOpBuiltinNode { @Specialization static PComplex doInt(PComplex left, int right, - @Shared @Cached PythonObjectFactory factory) { - return factory.createComplex(left.getReal() + right, left.getImag()); + @Bind PythonLanguage language) { + return PFactory.createComplex(language, left.getReal() + right, left.getImag()); } @Specialization static PComplex doDouble(PComplex left, double right, - @Shared @Cached PythonObjectFactory factory) { - return factory.createComplex(left.getReal() + right, left.getImag()); + @Bind PythonLanguage language) { + return PFactory.createComplex(language, left.getReal() + right, left.getImag()); } @Specialization @@ -398,13 +891,13 @@ static Object doGeneric(Object leftObj, Object rightObj, @Cached ToComplexValueNode toComplexLeft, @Cached ToComplexValueNode toComplexRight, @Cached InlinedConditionProfile notImplementedProfile, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { ComplexValue left = toComplexLeft.execute(inliningTarget, leftObj); ComplexValue right = toComplexRight.execute(inliningTarget, rightObj); if (notImplementedProfile.profile(inliningTarget, left == null || right == null)) { return PNotImplemented.NOT_IMPLEMENTED; } - return factory.createComplex(left.getReal() + right.getReal(), left.getImag() + right.getImag()); + return PFactory.createComplex(language, left.getReal() + right.getReal(), left.getImag() + right.getImag()); } } @@ -427,8 +920,8 @@ static Object doComplex(Object leftObj, Object rightObj, @Cached InlinedConditionProfile notImplementedProfile, @Cached InlinedConditionProfile topConditionProfile, @Cached InlinedConditionProfile zeroDivisionProfile, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { ComplexValue left = toComplexLeft.execute(inliningTarget, leftObj); ComplexValue right = toComplexRight.execute(inliningTarget, rightObj); if (notImplementedProfile.profile(inliningTarget, left == null || right == null)) { @@ -441,7 +934,7 @@ static Object doComplex(Object leftObj, Object rightObj, if (topConditionProfile.profile(inliningTarget, absRightReal >= absRightImag)) { /* divide tops and bottom by right.real */ if (zeroDivisionProfile.profile(inliningTarget, absRightReal == 0.0)) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.ZeroDivisionError, ErrorMessages.S_DIVISION_BY_ZERO, "complex"); + throw raiseNode.raise(inliningTarget, PythonErrorType.ZeroDivisionError, ErrorMessages.S_DIVISION_BY_ZERO, "complex"); } else { double ratio = right.getImag() / right.getReal(); double denom = right.getReal() + right.getImag() * ratio; @@ -455,16 +948,16 @@ static Object doComplex(Object leftObj, Object rightObj, real = (left.getReal() * ratio + left.getImag()) / denom; imag = (left.getImag() * ratio - left.getReal()) / denom; } - return factory.createComplex(real, imag); + return PFactory.createComplex(language, real, imag); } - static PComplex doubleDivComplex(double left, PComplex right, PythonObjectFactory factory) { + static PComplex doubleDivComplex(double left, PComplex right, PythonLanguage language) { double oprealSq = right.getReal() * right.getReal(); double opimagSq = right.getImag() * right.getImag(); double realPart = right.getReal() * left; double imagPart = right.getImag() * left; double denom = oprealSq + opimagSq; - return factory.createComplex(realPart / denom, -imagPart / denom); + return PFactory.createComplex(language, realPart / denom, -imagPart / denom); } } @@ -477,14 +970,14 @@ static Object doComplex(Object leftObj, Object rightObj, @Cached ToComplexValueNode toComplexLeft, @Cached ToComplexValueNode toComplexRight, @Cached InlinedConditionProfile notImplementedProfile, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { ComplexValue left = toComplexLeft.execute(inliningTarget, leftObj); ComplexValue right = toComplexRight.execute(inliningTarget, rightObj); if (notImplementedProfile.profile(inliningTarget, left == null || right == null)) { return PNotImplemented.NOT_IMPLEMENTED; } ComplexValue res = multiply(left, right); - return factory.createComplex(res.getReal(), res.getImag()); + return PFactory.createComplex(language, res.getReal(), res.getImag()); } static ComplexValue multiply(ComplexValue left, ComplexValue right) { @@ -498,14 +991,14 @@ static ComplexValue multiply(ComplexValue left, ComplexValue right) { @Slot(value = SlotKind.nb_subtract, isComplex = true) abstract static class SubNode extends BinaryOpBuiltinNode { static PComplex doComplex(PComplex left, double right, - @Shared @Cached PythonObjectFactory factory) { - return factory.createComplex(left.getReal() - right, left.getImag()); + @Bind PythonLanguage language) { + return PFactory.createComplex(language, left.getReal() - right, left.getImag()); } @Specialization static PComplex doComplex(PComplex left, int right, - @Shared @Cached PythonObjectFactory factory) { - return factory.createComplex(left.getReal() - right, left.getImag()); + @Bind PythonLanguage language) { + return PFactory.createComplex(language, left.getReal() - right, left.getImag()); } @Specialization @@ -514,24 +1007,21 @@ static Object doComplex(Object leftObj, Object rightObj, @Cached ToComplexValueNode toComplexLeft, @Cached ToComplexValueNode toComplexRight, @Cached InlinedConditionProfile notImplementedProfile, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { ComplexValue left = toComplexLeft.execute(inliningTarget, leftObj); ComplexValue right = toComplexRight.execute(inliningTarget, rightObj); if (notImplementedProfile.profile(inliningTarget, left == null || right == null)) { return PNotImplemented.NOT_IMPLEMENTED; } - return factory.createComplex(left.getReal() - right.getReal(), left.getImag() - right.getImag()); + return PFactory.createComplex(language, left.getReal() - right.getReal(), left.getImag() - right.getImag()); } } - @Builtin(name = J___RPOW__, minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3, reverseOperation = true) - @Builtin(name = J___POW__, minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3) - @TypeSystemReference(PythonArithmeticTypes.class) + @Slot(value = SlotKind.nb_power, isComplex = true) @GenerateNodeFactory abstract static class PowerNode extends PythonTernaryBuiltinNode { @Specialization - @InliningCutoff static Object doGeneric(Object leftObj, Object rightObj, @SuppressWarnings("unused") PNone mod, @Bind("this") Node inliningTarget, @Cached ToComplexValueNode toComplexLeft, @@ -542,8 +1032,8 @@ static Object doGeneric(Object leftObj, Object rightObj, @SuppressWarnings("unus @Cached InlinedBranchProfile smallPositiveProfile, @Cached InlinedBranchProfile smallNegativeProfile, @Cached InlinedBranchProfile complexProfile, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { ComplexValue left = toComplexLeft.execute(inliningTarget, leftObj); ComplexValue right = toComplexRight.execute(inliningTarget, rightObj); if (notImplementedProfile.profile(inliningTarget, left == null || right == null)) { @@ -552,27 +1042,27 @@ static Object doGeneric(Object leftObj, Object rightObj, @SuppressWarnings("unus PComplex result; if (right.getReal() == 0.0 && right.getImag() == 0.0) { rightZeroProfile.enter(inliningTarget); - result = factory.createComplex(1.0, 0.0); + result = PFactory.createComplex(language, 1.0, 0.0); } else if (left.getReal() == 0.0 && left.getImag() == 0.0) { leftZeroProfile.enter(inliningTarget); if (right.getImag() != 0.0 || right.getReal() < 0.0) { - throw PRaiseNode.raiseUncached(inliningTarget, ZeroDivisionError, ErrorMessages.COMPLEX_ZERO_TO_NEGATIVE_POWER); + throw PRaiseNode.raiseStatic(inliningTarget, ZeroDivisionError, ErrorMessages.COMPLEX_ZERO_TO_NEGATIVE_POWER); } - result = factory.createComplex(0.0, 0.0); + result = PFactory.createComplex(language, 0.0, 0.0); } else if (right.getImag() == 0.0 && right.getReal() == (int) right.getReal() && right.getReal() < 100 && right.getReal() > -100) { if (right.getReal() >= 0) { smallPositiveProfile.enter(inliningTarget); - result = complexToSmallPositiveIntPower(left, (int) right.getReal(), factory); + result = complexToSmallPositiveIntPower(left, (int) right.getReal(), language); } else { smallNegativeProfile.enter(inliningTarget); - result = DivNode.doubleDivComplex(1.0, complexToSmallPositiveIntPower(left, -(int) right.getReal(), factory), factory); + result = DivNode.doubleDivComplex(1.0, complexToSmallPositiveIntPower(left, -(int) right.getReal(), language), language); } } else { complexProfile.enter(inliningTarget); - result = complexToComplexBoundary(left.getReal(), left.getImag(), right.getReal(), right.getImag(), factory); + result = complexToComplexBoundary(left.getReal(), left.getImag(), right.getReal(), right.getImag(), language); } if (Double.isInfinite(result.getReal()) || Double.isInfinite(result.getImag())) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.COMPLEX_EXPONENTIATION); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.COMPLEX_EXPONENTIATION); } return result; } @@ -581,11 +1071,11 @@ static Object doGeneric(Object leftObj, Object rightObj, @SuppressWarnings("unus @InliningCutoff @SuppressWarnings("unused") static Object error(Object left, Object right, Object mod, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(ValueError, ErrorMessages.COMPLEX_MODULO); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.COMPLEX_MODULO); } - private static PComplex complexToSmallPositiveIntPower(ComplexValue x, long n, PythonObjectFactory factory) { + private static PComplex complexToSmallPositiveIntPower(ComplexValue x, long n, PythonLanguage language) { long mask = 1; ComplexValue r = new ComplexValue(1.0, 0.0); ComplexValue p = x; @@ -596,11 +1086,11 @@ private static PComplex complexToSmallPositiveIntPower(ComplexValue x, long n, P mask <<= 1; p = MulNode.multiply(p, p); } - return factory.createComplex(r.getReal(), r.getImag()); + return PFactory.createComplex(language, r.getReal(), r.getImag()); } @TruffleBoundary - private static PComplex complexToComplexBoundary(double leftRead, double leftImag, double rightReal, double rightImag, PythonObjectFactory factory) { + private static PComplex complexToComplexBoundary(double leftRead, double leftImag, double rightReal, double rightImag, PythonLanguage language) { PComplex result; double vabs = Math.hypot(leftRead, leftImag); double len = Math.pow(vabs, rightReal); @@ -610,14 +1100,15 @@ private static PComplex complexToComplexBoundary(double leftRead, double leftIma len /= Math.exp(at * rightImag); phase += rightImag * Math.log(vabs); } - result = factory.createComplex(len * Math.cos(phase), len * Math.sin(phase)); + result = PFactory.createComplex(language, len * Math.cos(phase), len * Math.sin(phase)); return result; } } @GenerateInline @GenerateCached(false) - @TypeSystemReference(PythonArithmeticTypes.class) + @GenerateUncached + @TypeSystemReference(PythonIntegerAndFloatTypes.class) abstract static class ComplexEqNode extends Node { public abstract Object execute(Node inliningTarget, Object left, Object right); @@ -665,74 +1156,28 @@ static PNotImplemented doNotImplemented(Object left, Object right) { } } + @Slot(SlotKind.tp_richcompare) @GenerateNodeFactory - @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2) - abstract static class EqNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doComplex(Object left, Object right, - @Bind("this") Node inliningTarget, - @Cached ComplexEqNode complexEqNode) { - return complexEqNode.execute(inliningTarget, left, right); - } - } - - @GenerateNodeFactory - @Builtin(name = J___NE__, minNumOfPositionalArgs = 2) - abstract static class NeNode extends PythonBinaryBuiltinNode { + @GenerateUncached + abstract static class ComplexRichCmpNode extends TpSlotRichCompare.RichCmpBuiltinNode { @Specialization - static Object doComplex(Object left, Object right, + static Object doComplex(Object left, Object right, RichCmpOp op, @Bind("this") Node inliningTarget, - @Cached ComplexEqNode complexEqNode) { - Object res = complexEqNode.execute(inliningTarget, left, right); - if (res == PNotImplemented.NOT_IMPLEMENTED) { + @Cached ComplexEqNode complexEqNode, + @Cached InlinedConditionProfile isNotImplementedProfile) { + if (!op.isEqOrNe()) { return PNotImplemented.NOT_IMPLEMENTED; } - return !(boolean) res; - } - } - - @GenerateNodeFactory - @Builtin(name = J___GE__, minNumOfPositionalArgs = 2) - abstract static class GeNode extends PythonBinaryBuiltinNode { - @SuppressWarnings("unused") - @Specialization - static PNotImplemented doGeneric(Object left, Object right) { - return PNotImplemented.NOT_IMPLEMENTED; - } - } - - @GenerateNodeFactory - @Builtin(name = J___GT__, minNumOfPositionalArgs = 2) - abstract static class GtNode extends PythonBinaryBuiltinNode { - @SuppressWarnings("unused") - @Specialization - static PNotImplemented doGeneric(Object left, Object right) { - return PNotImplemented.NOT_IMPLEMENTED; - } - } - - @GenerateNodeFactory - @Builtin(name = J___LT__, minNumOfPositionalArgs = 2) - abstract static class LtNode extends PythonBinaryBuiltinNode { - @SuppressWarnings("unused") - @Specialization - static PNotImplemented doGeneric(Object left, Object right) { - return PNotImplemented.NOT_IMPLEMENTED; - } - } - - @GenerateNodeFactory - @Builtin(name = J___LE__, minNumOfPositionalArgs = 2) - abstract static class LeNode extends PythonBinaryBuiltinNode { - @SuppressWarnings("unused") - @Specialization - static PNotImplemented doGeneric(Object left, Object right) { - return PNotImplemented.NOT_IMPLEMENTED; + Object result = complexEqNode.execute(inliningTarget, left, right); + if (isNotImplementedProfile.profile(inliningTarget, result == PNotImplemented.NOT_IMPLEMENTED)) { + return PNotImplemented.NOT_IMPLEMENTED; + } + return (boolean) result == (op == RichCmpOp.Py_EQ); } } @GenerateNodeFactory - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization @InliningCutoff @@ -765,7 +1210,7 @@ protected ArgumentClinicProvider getArgumentClinic() { static TruffleString format(Object self, TruffleString formatString, @Bind("this") Node inliningTarget, @Cached ToComplexValueNode toComplexValueNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { ComplexValue c = toComplexValueNode.execute(inliningTarget, self); InternalFormat.Spec spec = InternalFormat.fromText(formatString, Spec.NONE, '>', inliningTarget); validateSpec(inliningTarget, spec, raiseNode); @@ -779,14 +1224,14 @@ private static TruffleString doFormat(Node raisingNode, double real, double imag return formatter.pad().getResult(); } - private static void validateSpec(Node inliningTarget, Spec spec, PRaiseNode.Lazy raiseNode) { + private static void validateSpec(Node inliningTarget, Spec spec, PRaiseNode raiseNode) { if (spec.getFill(' ') == '0') { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.ZERO_PADDING_NOT_ALLOWED_FOR_COMPLEX_FMT); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.ZERO_PADDING_NOT_ALLOWED_FOR_COMPLEX_FMT); } char align = spec.getAlign('>'); if (align == '=') { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.S_ALIGNMENT_FLAG_NOT_ALLOWED_FOR_COMPLEX_FMT, align); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.S_ALIGNMENT_FLAG_NOT_ALLOWED_FOR_COMPLEX_FMT, align); } } } @@ -811,9 +1256,9 @@ abstract static class NegNode extends PythonUnaryBuiltinNode { static PComplex neg(Object self, @Bind("this") Node inliningTarget, @Cached ToComplexValueNode toComplexValueNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { ComplexValue c = toComplexValueNode.execute(inliningTarget, self); - return factory.createComplex(-c.getReal(), -c.getImag()); + return PFactory.createComplex(language, -c.getReal(), -c.getImag()); } } @@ -824,9 +1269,9 @@ abstract static class PosNode extends PythonUnaryBuiltinNode { static PComplex pos(Object self, @Bind("this") Node inliningTarget, @Cached ToComplexValueNode toComplexValueNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { ComplexValue c = toComplexValueNode.execute(inliningTarget, self); - return factory.createComplex(c.getReal(), c.getImag()); + return PFactory.createComplex(language, c.getReal(), c.getImag()); } } @@ -837,9 +1282,9 @@ abstract static class GetNewArgsNode extends PythonUnaryBuiltinNode { static PTuple get(Object self, @Bind("this") Node inliningTarget, @Cached ToComplexValueNode toComplexValueNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { ComplexValue c = toComplexValueNode.execute(inliningTarget, self); - return factory.createTuple(new Object[]{c.getReal(), c.getImag()}); + return PFactory.createTuple(language, new Object[]{c.getReal(), c.getImag()}); } } @@ -875,9 +1320,9 @@ static double getNative(PythonAbstractNativeObject self, } } + @Slot(value = SlotKind.tp_hash, isComplex = true) @GenerateNodeFactory - @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1) - abstract static class HashNode extends PythonUnaryBuiltinNode { + abstract static class HashNode extends HashBuiltinNode { @Specialization static long doPComplex(Object self, @Bind("this") Node inliningTarget, @@ -898,9 +1343,9 @@ abstract static class ConjugateNode extends PythonUnaryBuiltinNode { static PComplex hash(Object self, @Bind("this") Node inliningTarget, @Cached ToComplexValueNode toComplexValueNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { ComplexValue c = toComplexValueNode.execute(inliningTarget, self); - return factory.createComplex(c.getReal(), -c.getImag()); + return PFactory.createComplex(language, c.getReal(), -c.getImag()); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/ContextBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/ContextBuiltins.java index 9e10d1ea1d..6327e7da89 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/ContextBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/ContextBuiltins.java @@ -41,13 +41,14 @@ package com.oracle.graal.python.builtins.objects.contextvars; import static com.oracle.graal.python.nodes.PGuards.isNoValue; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CONTAINS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.HashNotImplemented; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -57,6 +58,7 @@ import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.CallNode; @@ -64,7 +66,7 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -76,6 +78,7 @@ import com.oracle.truffle.api.profiles.InlinedConditionProfile; @CoreFunctions(extendClasses = PythonBuiltinClassType.ContextVarsContext) +@HashNotImplemented public final class ContextBuiltins extends PythonBuiltins { public static final TpSlots SLOTS = ContextBuiltinsSlotsGen.SLOTS; @@ -84,6 +87,17 @@ protected List> getNodeFa return ContextBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "Context", minNumOfPositionalArgs = 1) + @GenerateNodeFactory + public abstract static class ContextNode extends PythonUnaryBuiltinNode { + @Specialization + static Object construct(@SuppressWarnings("unused") Object cls, + @Bind PythonLanguage language) { + return PFactory.createContextVarsContext(language); + } + } + @Slot(SlotKind.mp_length) @GenerateUncached @GenerateNodeFactory @@ -100,18 +114,18 @@ public abstract static class GetContextVar extends MpSubscriptBuiltinNode { @Specialization Object get(PContextVarsContext self, Object key, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raise) { + @Cached PRaiseNode raise) { return getContextVar(inliningTarget, self, key, null, raise); } } - @Builtin(name = J___ITER__, declaresExplicitSelf = true, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iter, isComplex = true) @GenerateNodeFactory public abstract static class Iter extends PythonUnaryBuiltinNode { @Specialization static Object iter(PContextVarsContext self, - @Cached PythonObjectFactory factory) { - return factory.createContextIterator(self, PContextIterator.ItemKind.KEYS); + @Bind PythonLanguage language) { + return PFactory.createContextIterator(language, self, PContextIterator.ItemKind.KEYS); } } @@ -120,8 +134,8 @@ static Object iter(PContextVarsContext self, public abstract static class Keys extends PythonUnaryBuiltinNode { @Specialization static Object keys(PContextVarsContext self, - @Cached PythonObjectFactory factory) { - return factory.createContextIterator(self, PContextIterator.ItemKind.KEYS); + @Bind PythonLanguage language) { + return PFactory.createContextIterator(language, self, PContextIterator.ItemKind.KEYS); } } @@ -130,8 +144,8 @@ static Object keys(PContextVarsContext self, public abstract static class Values extends PythonUnaryBuiltinNode { @Specialization static Object values(PContextVarsContext self, - @Cached PythonObjectFactory factory) { - return factory.createContextIterator(self, PContextIterator.ItemKind.VALUES); + @Bind PythonLanguage language) { + return PFactory.createContextIterator(language, self, PContextIterator.ItemKind.VALUES); } } @@ -140,8 +154,8 @@ static Object values(PContextVarsContext self, public abstract static class Items extends PythonUnaryBuiltinNode { @Specialization static Object items(PContextVarsContext self, - @Cached PythonObjectFactory factory) { - return factory.createContextIterator(self, PContextIterator.ItemKind.ITEMS); + @Bind PythonLanguage language) { + return PFactory.createContextIterator(language, self, PContextIterator.ItemKind.ITEMS); } } @@ -153,7 +167,7 @@ static Object get(VirtualFrame frame, PContextVarsContext self, Object fun, Obje @Bind("this") Node inliningTarget, @Bind PythonContext context, @Cached CallNode call, - @Cached PRaiseNode.Lazy raise) { + @Cached PRaiseNode raise) { PythonContext.PythonThreadState threadState = context.getThreadState(context.getLanguage(inliningTarget)); self.enter(inliningTarget, threadState, raise); try { @@ -169,8 +183,8 @@ static Object get(VirtualFrame frame, PContextVarsContext self, Object fun, Obje public abstract static class Copy extends PythonUnaryBuiltinNode { @Specialization static Object doCopy(PContextVarsContext self, - @Cached PythonObjectFactory factory) { - PContextVarsContext ret = factory.createContextVarsContext(); + @Bind PythonLanguage language) { + PContextVarsContext ret = PFactory.createContextVarsContext(language); ret.contextVarValues = self.contextVarValues; return ret; } @@ -184,32 +198,33 @@ public abstract static class GetMethod extends PythonBuiltinNode { Object doGetDefault(PContextVarsContext self, Object key, Object def, @Bind("this") Node inliningTarget, @Cached InlinedConditionProfile noValueProfile, - @Cached PRaiseNode.Lazy raise) { + @Cached PRaiseNode raise) { Object defVal = noValueProfile.profile(inliningTarget, isNoValue(def)) ? PNone.NONE : def; return getContextVar(inliningTarget, self, key, defVal, raise); } } - @Builtin(name = J___CONTAINS__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.sq_contains, isComplex = true) @GenerateNodeFactory - public abstract static class Contains extends PythonBuiltinNode { + public abstract static class Contains extends SqContainsBuiltinNode { @Specialization boolean doIn(PContextVarsContext self, Object key, + @Bind("this") Node inliningTarget, @Cached PRaiseNode raise) { if (key instanceof PContextVar var) { return self.contextVarValues.lookup(var, var.getHash()) != null; } - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.CONTEXTVAR_KEY_EXPECTED, key); + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CONTEXTVAR_KEY_EXPECTED, key); } } - private static Object getContextVar(Node inliningTarget, PContextVarsContext self, Object key, Object def, PRaiseNode.Lazy raise) { + private static Object getContextVar(Node inliningTarget, PContextVarsContext self, Object key, Object def, PRaiseNode raise) { if (key instanceof PContextVar ctxVar) { Object value = self.contextVarValues.lookup(key, ctxVar.getHash()); if (value == null) { if (def == null) { - throw raise.get(inliningTarget).raise(PythonBuiltinClassType.KeyError, new Object[]{key}); + throw raise.raise(inliningTarget, PythonBuiltinClassType.KeyError, new Object[]{key}); } else { return def; } @@ -217,7 +232,7 @@ private static Object getContextVar(Node inliningTarget, PContextVarsContext sel return value; } } else { - throw raise.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.CONTEXTVAR_KEY_EXPECTED, key); + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CONTEXTVAR_KEY_EXPECTED, key); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/ContextIteratorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/ContextIteratorBuiltins.java index fa79001cd4..7e77838bb5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/ContextIteratorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/ContextIteratorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,34 +40,33 @@ */ package com.oracle.graal.python.builtins.objects.contextvars; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__; - import java.util.List; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node; @CoreFunctions(extendClasses = PythonBuiltinClassType.ContextIterator) public final class ContextIteratorBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = ContextIteratorBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return ContextIteratorBuiltinsFactory.getFactories(); } - @Builtin(name = J___ITER__, declaresExplicitSelf = true, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iter, isComplex = true) @GenerateNodeFactory public abstract static class Iter extends PythonUnaryBuiltinNode { @Specialization @@ -76,17 +75,15 @@ static Object iter(PContextIterator self) { } } - @Builtin(name = J___NEXT__, declaresExplicitSelf = true, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iternext, isComplex = true) @GenerateNodeFactory - public abstract static class Next extends PythonUnaryBuiltinNode { + public abstract static class Next extends TpIterNextBuiltin { @Specialization static Object next(PContextIterator self, - @Bind("this") Node inliningTarget, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { - Object next = self.next(factory); + @Bind PythonLanguage language) { + Object next = self.next(language); if (next == null) { - throw raiseNode.get(inliningTarget).raiseStopIteration(); + throw iteratorExhausted(); } else { return next; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/ContextVarBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/ContextVarBuiltins.java index 8afad6b55f..6786558dbf 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/ContextVarBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/ContextVarBuiltins.java @@ -48,17 +48,26 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.contextvars.ContextVarBuiltinsClinicProviders.ContextVarNodeClinicProviderGen; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -67,15 +76,41 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedConditionProfile; +import com.oracle.truffle.api.strings.TruffleString; @CoreFunctions(extendClasses = PythonBuiltinClassType.ContextVar) public final class ContextVarBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = ContextVarBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return ContextVarBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "ContextVar", minNumOfPositionalArgs = 2, parameterNames = {"cls", "name", "default"}) + @ArgumentClinic(name = "name", conversion = ArgumentClinic.ClinicConversion.TString) + @GenerateNodeFactory + public abstract static class ContextVarNode extends PythonTernaryClinicBuiltinNode { + + @Override + protected ArgumentClinicProvider getArgumentClinic() { + return ContextVarNodeClinicProviderGen.INSTANCE; + } + + @Specialization + protected static Object constructDef(@SuppressWarnings("unused") Object cls, TruffleString name, Object def, + @Bind("this") Node inliningTarget, + @Cached InlinedConditionProfile noValueProfile, + @Bind PythonLanguage language) { + if (noValueProfile.profile(inliningTarget, isNoValue(def))) { + def = PContextVar.NO_DEFAULT; + } + return PFactory.createContextVar(language, name, def); + } + } + @Builtin(name = "get", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2) @GenerateNodeFactory public abstract static class GetNode extends PythonBinaryBuiltinNode { @@ -83,7 +118,7 @@ public abstract static class GetNode extends PythonBinaryBuiltinNode { static Object get(PContextVar self, Object def, @Bind("this") Node inliningTarget, @Cached InlinedConditionProfile defIsNoValueProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object defValue = defIsNoValueProfile.profile(inliningTarget, isNoValue(def)) ? PContextVar.NO_DEFAULT : def; PythonContext context = PythonContext.get(inliningTarget); PythonContext.PythonThreadState threadState = context.getThreadState(context.getLanguage(inliningTarget)); @@ -91,7 +126,7 @@ static Object get(PContextVar self, Object def, if (value != null) { return value; } - throw raiseNode.get(inliningTarget).raise(LookupError); + throw raiseNode.raise(inliningTarget, LookupError); } } @@ -101,12 +136,12 @@ public abstract static class SetNode extends PythonBinaryBuiltinNode { @Specialization static Object set(PContextVar self, Object value, @Bind("this") Node inliningTarget, - @Bind PythonContext context, - @Cached PythonObjectFactory factory) { - PythonContext.PythonThreadState threadState = context.getThreadState(context.getLanguage(inliningTarget)); + @Bind PythonContext context) { + PythonLanguage language = context.getLanguage(inliningTarget); + PythonContext.PythonThreadState threadState = context.getThreadState(language); Object oldValue = self.getValue(threadState); self.setValue(threadState, value); - return factory.createContextVarsToken(self, oldValue); + return PFactory.createContextVarsToken(language, self, oldValue); } } @@ -117,7 +152,7 @@ public abstract static class ResetNode extends PythonBinaryBuiltinNode { static Object reset(PContextVar self, PContextVarsToken token, @Bind("this") Node inliningTarget, @Bind PythonContext pythonContext, - @Shared @Cached PRaiseNode.Lazy raise) { + @Shared @Cached PRaiseNode raise) { if (self == token.getVar()) { token.use(inliningTarget, raise); PythonContext.PythonThreadState threadState = pythonContext.getThreadState(pythonContext.getLanguage(inliningTarget)); @@ -128,7 +163,7 @@ static Object reset(PContextVar self, PContextVarsToken token, self.setValue(threadState, token.getOldValue()); } } else { - throw raise.get(inliningTarget).raise(ValueError, ErrorMessages.TOKEN_FOR_DIFFERENT_CONTEXTVAR, token); + throw raise.raise(inliningTarget, ValueError, ErrorMessages.TOKEN_FOR_DIFFERENT_CONTEXTVAR, token); } return PNone.NONE; } @@ -136,8 +171,8 @@ static Object reset(PContextVar self, PContextVarsToken token, @Specialization(guards = "!isToken(token)") Object doError(@SuppressWarnings("unused") PContextVar self, Object token, @Bind("this") Node inliningTarget, - @Shared @Cached PRaiseNode.Lazy raise) { - throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.INSTANCE_OF_TOKEN_EXPECTED, token); + @Shared @Cached PRaiseNode raise) { + throw raise.raise(inliningTarget, TypeError, ErrorMessages.INSTANCE_OF_TOKEN_EXPECTED, token); } static boolean isToken(Object obj) { @@ -150,8 +185,8 @@ static boolean isToken(Object obj) { public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode { @Specialization static Object classGetItem(Object cls, Object key, - @Cached PythonObjectFactory factory) { - return factory.createGenericAlias(cls, key); + @Bind PythonLanguage language) { + return PFactory.createGenericAlias(language, cls, key); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/Hamt.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/Hamt.java index 6f1aaf07b2..34d24f1e50 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/Hamt.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/Hamt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -147,7 +147,7 @@ private static TreePart partWithEntry(TreePart original, Entry newEntry, int has if (original instanceof Entry) { Entry existing = (Entry) original; if (newEntry.hash == existing.hash) { - if (PyObjectRichCompareBool.EqNode.compareUncached(newEntry.key, existing.key)) { + if (PyObjectRichCompareBool.executeEqUncached(newEntry.key, existing.key)) { return newEntry; } else { return new CollisionPart(existing.hash, existing, newEntry); @@ -230,7 +230,7 @@ private static Object lookupKeyInPart(TreePart part, Object key, int hash, int h } if (part instanceof Entry) { Entry existing = (Entry) part; - if (existing.hash == hash && PyObjectRichCompareBool.EqNode.compareUncached(existing.key, key)) { + if (existing.hash == hash && PyObjectRichCompareBool.executeEqUncached(existing.key, key)) { return existing.value; } return null; @@ -256,7 +256,7 @@ private static Object lookupKeyInPart(TreePart part, Object key, int hash, int h return null; } for (Entry entry : existing.elems) { - if (PyObjectRichCompareBool.EqNode.compareUncached(entry.key, key)) { + if (PyObjectRichCompareBool.executeEqUncached(entry.key, key)) { return entry.value; } } @@ -325,7 +325,7 @@ private static TreePart partWithoutKey(TreePart root, Object key, int hash, int } if (root instanceof Entry) { Entry existing = (Entry) root; - if (existing.hash == hash && PyObjectRichCompareBool.EqNode.compareUncached(existing.key, key)) { + if (existing.hash == hash && PyObjectRichCompareBool.executeEqUncached(existing.key, key)) { return null; } return root; @@ -369,7 +369,7 @@ private static TreePart partWithoutKey(TreePart root, Object key, int hash, int CollisionPart existing = (CollisionPart) root; if (existing.hash == hash) { for (int i = 0; i < existing.elems.length; ++i) { - if (PyObjectRichCompareBool.EqNode.compareUncached(existing.elems[i].key, key)) { + if (PyObjectRichCompareBool.executeEqUncached(existing.elems[i].key, key)) { if (existing.elems.length == 1) { return null; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/PContextIterator.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/PContextIterator.java index 17ab98a5e3..401b98a7f3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/PContextIterator.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/PContextIterator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,8 +40,9 @@ */ package com.oracle.graal.python.builtins.objects.contextvars; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.object.Shape; @@ -51,14 +52,14 @@ public enum ItemKind { VALUES, ITEMS; - public Object apply(Hamt.Entry item, PythonObjectFactory factory) { + public Object apply(Hamt.Entry item, PythonLanguage language) { switch (this) { case KEYS: return item.key; case VALUES: return item.value; case ITEMS: - return factory.createTuple(new Object[]{item.key, item.value}); + return PFactory.createTuple(language, new Object[]{item.key, item.value}); default: throw CompilerDirectives.shouldNotReachHere("null ItemKind in PHamtIterator"); } @@ -76,8 +77,8 @@ public PContextIterator(Object cls, Shape instanceShape, PContextVarsContext ctx } // can return null - public Object next(PythonObjectFactory factory) { + public Object next(PythonLanguage language) { Hamt.Entry item = it.next(); - return item == null ? null : kind.apply(item, factory); + return item == null ? null : kind.apply(item, language); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/PContextVarsContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/PContextVarsContext.java index d26463bb45..9896cf8266 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/PContextVarsContext.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/PContextVarsContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -52,9 +52,9 @@ public class PContextVarsContext extends PythonBuiltinObject { Hamt contextVarValues; private PContextVarsContext previousContext = null; - public void enter(Node inliningTarget, PythonContext.PythonThreadState threadState, PRaiseNode.Lazy raise) { + public void enter(Node inliningTarget, PythonContext.PythonThreadState threadState, PRaiseNode raise) { if (previousContext != null) { - throw raise.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.CANNOT_ENTER_CONTEXT_ALREADY_ENTERED, this); + throw raise.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.CANNOT_ENTER_CONTEXT_ALREADY_ENTERED, this); } previousContext = threadState.getContextVarsContext(); assert previousContext != null : "ThreadState had null Context. This should not happen"; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/PContextVarsToken.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/PContextVarsToken.java index 1c0e80d1a8..ea4b0c6c90 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/PContextVarsToken.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/PContextVarsToken.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -60,9 +60,9 @@ public PContextVarsToken(PContextVar var, Object oldValue, Object cls, Shape ins this.oldValue = oldValue; } - public void use(Node inliningTarget, PRaiseNode.Lazy raise) { + public void use(Node inliningTarget, PRaiseNode raise) { if (used) { - throw raise.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.TOKEN_ALREADY_USED, this); + throw raise.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.TOKEN_ALREADY_USED, this); } used = true; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/TokenBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/TokenBuiltins.java index 231f12ad28..b67f235d64 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/TokenBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/contextvars/TokenBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,30 +45,53 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.HashNotImplemented; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.dsl.Cached; +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @CoreFunctions(extendClasses = PythonBuiltinClassType.ContextVarsToken) +@HashNotImplemented public final class TokenBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = TokenBuiltinsSlotsGen.SLOTS; @Override protected List> getNodeFactories() { return TokenBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "Token", minNumOfPositionalArgs = 1) + @GenerateNodeFactory + public abstract static class TokenNode extends PythonUnaryBuiltinNode { + @Specialization + Object construct(@SuppressWarnings("unused") Object cls, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.TOKEN_ONLY_BY_CONTEXTVAR); + } + } + @Builtin(name = "var", isGetter = true, minNumOfPositionalArgs = 1) @GenerateNodeFactory public abstract static class VarAttr extends PythonBuiltinNode { @@ -101,8 +124,8 @@ public void postInitialize(Python3Core core) { public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode { @Specialization static Object classGetItem(Object cls, Object key, - @Cached PythonObjectFactory factory) { - return factory.createGenericAlias(cls, key); + @Bind PythonLanguage language) { + return PFactory.createGenericAlias(language, cls, key); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeBuiltins.java index afaec0767f..d712b3d5dc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeBuiltins.java @@ -44,30 +44,17 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.MemoryError; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.OverflowError; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.RuntimeError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.StopIteration; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; import static com.oracle.graal.python.nodes.BuiltinNames.J_APPEND; +import static com.oracle.graal.python.nodes.BuiltinNames.J_DEQUE; import static com.oracle.graal.python.nodes.BuiltinNames.J_EXTEND; import static com.oracle.graal.python.nodes.ErrorMessages.DEQUE_MUTATED_DURING_REMOVE; import static com.oracle.graal.python.nodes.ErrorMessages.DEQUE_REMOVE_X_NOT_IN_DEQUE; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CONTAINS__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___COPY__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IADD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REVERSED__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__; import static com.oracle.graal.python.nodes.StringLiterals.T_ELLIPSIS_IN_BRACKETS; import static com.oracle.graal.python.nodes.StringLiterals.T_LPAREN; import static com.oracle.graal.python.nodes.StringLiterals.T_RPAREN; @@ -77,36 +64,43 @@ import java.util.Iterator; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; +import com.oracle.graal.python.annotations.HashNotImplemented; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.common.IndexNodes.NormalizeIndexCustomMessageNode; -import com.oracle.graal.python.builtins.objects.deque.DequeBuiltinsClinicProviders.DequeInplaceMulNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.deque.DequeBuiltinsClinicProviders.DequeInsertNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.deque.DequeBuiltinsClinicProviders.DequeRotateNodeClinicProviderGen; +import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.SqConcatBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqItemBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqRepeatBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqAssItem.SqAssItemBuiltinNode; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyObjectGetStateNode; import com.oracle.graal.python.lib.PyObjectRichCompareBool; import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; @@ -117,6 +111,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; @@ -124,15 +119,12 @@ import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.util.ComparisonOp; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NodeFactory; @@ -145,6 +137,7 @@ import com.oracle.truffle.api.strings.TruffleStringBuilder; @CoreFunctions(extendClasses = PythonBuiltinClassType.PDeque) +@HashNotImplemented public final class DequeBuiltins extends PythonBuiltins { public static final TpSlots SLOTS = DequeBuiltinsSlotsGen.SLOTS; @@ -153,15 +146,23 @@ protected List> getNodeFa return DequeBuiltinsFactory.getFactories(); } - @Override - public void initialize(Python3Core core) { - super.initialize(core); - // setting None means that this type is unhashable - addBuiltinConstant(T___HASH__, PNone.NONE); + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = J_DEQUE, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class DequeNode extends PythonVarargsBuiltinNode { + + @Specialization + @SuppressWarnings("unused") + PDeque doGeneric(Object cls, Object[] args, PKeyword[] kwargs, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + return PFactory.createDeque(language, cls, getInstanceShape.execute(cls)); + } } // deque.__init__(self, [iterable, [maxlen]]) - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self", "iterable", "maxlen"}) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "deque", minNumOfPositionalArgs = 1, parameterNames = {"$self", "iterable", "maxlen"}) @GenerateNodeFactory public abstract static class DequeInitNode extends PythonTernaryBuiltinNode { @@ -176,17 +177,16 @@ static PNone doIterable(VirtualFrame frame, PDeque self, Object iterable, @Suppr @Bind("this") Node inliningTarget, @Exclusive @Cached InlinedConditionProfile sizeZeroProfile, @Exclusive @Cached PyObjectGetIter getIter, - @Exclusive @Cached GetNextNode getNextNode, - @Exclusive @Cached IsBuiltinObjectProfile isStopIterationProfile) { + @Exclusive @Cached PyIterNextNode nextNode) { if (sizeZeroProfile.profile(inliningTarget, self.getSize() != 0)) { self.clear(); } Object iterator = getIter.execute(frame, inliningTarget, iterable); while (true) { try { - self.append(getNextNode.execute(frame, iterator)); - } catch (PException e) { - e.expect(inliningTarget, PythonBuiltinClassType.StopIteration, isStopIterationProfile); + Object next = nextNode.execute(frame, inliningTarget, iterator); + self.append(next); + } catch (IteratorExhausted e) { break; } } @@ -199,15 +199,14 @@ static PNone doGeneric(VirtualFrame frame, PDeque self, Object iterable, Object @Exclusive @Cached InlinedConditionProfile sizeZeroProfile, @Cached CastToJavaIntExactNode castToIntNode, @Exclusive @Cached PyObjectGetIter getIter, - @Exclusive @Cached GetNextNode getNextNode, + @Exclusive @Cached PyIterNextNode nextNode, @Exclusive @Cached IsBuiltinObjectProfile isTypeErrorProfile, - @Exclusive @Cached IsBuiltinObjectProfile isStopIterationProfile, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (!PGuards.isPNone(maxlenObj)) { try { int maxlen = castToIntNode.execute(inliningTarget, maxlenObj); if (maxlen < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MAXLEN_MUST_BE_NONNEG); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MAXLEN_MUST_BE_NONNEG); } self.setMaxLength(maxlen); } catch (PException e) { @@ -216,14 +215,14 @@ static PNone doGeneric(VirtualFrame frame, PDeque self, Object iterable, Object * OverflowError */ e.expect(inliningTarget, TypeError, isTypeErrorProfile); - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "int"); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "int"); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.INTEGER_REQUIRED); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.INTEGER_REQUIRED); } } if (iterable != PNone.NO_VALUE) { - doIterable(frame, self, iterable, PNone.NO_VALUE, inliningTarget, sizeZeroProfile, getIter, getNextNode, isStopIterationProfile); + doIterable(frame, self, iterable, PNone.NO_VALUE, inliningTarget, sizeZeroProfile, getIter, nextNode); } return PNone.NONE; } @@ -290,9 +289,11 @@ public abstract static class DequeCopyNode extends PythonUnaryBuiltinNode { @Specialization static PDeque doGeneric(PDeque self, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached GetClassNode getClassNode, - @Cached PythonObjectFactory factory) { - PDeque copy = factory.createDeque(getClassNode.execute(inliningTarget, self)); + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + Object cls = getClassNode.execute(inliningTarget, self); + PDeque copy = PFactory.createDeque(language, cls, getInstanceShape.execute(cls)); copy.setMaxLength(self.getMaxLength()); copy.addAll(self); return copy; @@ -310,11 +311,11 @@ int doGeneric(PDeque self, Object value) { int n = 0; int startState = self.getState(); for (Object item : self.data) { - if (PyObjectRichCompareBool.EqNode.compareUncached(item, value)) { + if (PyObjectRichCompareBool.executeUncached(item, value, RichCmpOp.Py_EQ)) { n++; } if (startState != self.getState()) { - throw PRaiseNode.raiseUncached(this, RuntimeError, ErrorMessages.DEQUE_MUTATED_DURING_ITERATION); + throw PRaiseNode.raiseStatic(this, RuntimeError, ErrorMessages.DEQUE_MUTATED_DURING_ITERATION); } } return n; @@ -347,36 +348,34 @@ PNone doGeneric(VirtualFrame frame, PDeque self, Object other, @Cached InlinedConditionProfile selfIsOtherProfile, @Cached InlinedConditionProfile maxLenZeroProfile, @Cached PyObjectGetIter getIter, - @Cached GetNextNode getNextNode, - @Cached IsBuiltinObjectProfile isStopIterationProfile) { + @Cached PyIterNextNode nextNode) { if (selfIsOtherProfile.profile(inliningTarget, self == other)) { return doSelf(self, self); } Object it = getIter.execute(frame, inliningTarget, other); if (maxLenZeroProfile.profile(inliningTarget, self.getMaxLength() == 0)) { - consumeIterator(frame, it, getNextNode, inliningTarget, isStopIterationProfile); + consumeIterator(frame, it, nextNode, inliningTarget); return PNone.NONE; } while (true) { try { - appendOperation(self, getNextNode.execute(frame, it)); - } catch (PException e) { - e.expect(inliningTarget, StopIteration, isStopIterationProfile); + Object next = nextNode.execute(frame, inliningTarget, it); + appendOperation(self, next); + } catch (IteratorExhausted e) { break; } } - consumeIterator(frame, it, getNextNode, inliningTarget, isStopIterationProfile); + consumeIterator(frame, it, nextNode, inliningTarget); return PNone.NONE; } - private static void consumeIterator(VirtualFrame frame, Object it, GetNextNode getNextNode, Node inliningTarget, IsBuiltinObjectProfile isStopIterationProfile) { + private static void consumeIterator(VirtualFrame frame, Object it, PyIterNextNode getNextNode, Node inliningTarget) { while (true) { try { - getNextNode.execute(frame, it); - } catch (PException e) { - e.expect(inliningTarget, StopIteration, isStopIterationProfile); + getNextNode.execute(frame, inliningTarget, it); + } catch (IteratorExhausted e) { break; } } @@ -400,16 +399,16 @@ public abstract static class DequeIndexNode extends PythonQuaternaryBuiltinNode @Specialization(guards = {"isNoValue(start)", "isNoValue(stop)"}) static int doWithoutSlice(VirtualFrame frame, PDeque self, Object value, @SuppressWarnings("unused") PNone start, @SuppressWarnings("unused") PNone stop, @Bind("this") Node inliningTarget, - @Shared("eqNode") @Cached PyObjectRichCompareBool.EqNode eqNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared("eqNode") @Cached PyObjectRichCompareBool eqNode, + @Shared @Cached PRaiseNode raiseNode) { return doWithIntSlice(frame, self, value, 0, self.getSize(), inliningTarget, eqNode, raiseNode); } @Specialization static int doWithIntSlice(VirtualFrame frame, PDeque self, Object value, int start, int stop, @Bind("this") Node inliningTarget, - @Shared("eqNode") @Cached PyObjectRichCompareBool.EqNode eqNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared("eqNode") @Cached PyObjectRichCompareBool eqNode, + @Shared @Cached PRaiseNode raiseNode) { int size = self.getSize(); int normStart = normalize(start, size); int normStop = normalize(stop, size); @@ -428,25 +427,25 @@ static int doWithIntSlice(VirtualFrame frame, PDeque self, Object value, int sta */ Object item = next(iterator); if (normStart <= idx) { - if (eqNode.compare(frame, inliningTarget, item, value)) { + if (eqNode.execute(frame, inliningTarget, item, value, RichCmpOp.Py_EQ)) { return idx; } if (startState != self.getState()) { - throw raiseNode.get(inliningTarget).raise(RuntimeError, ErrorMessages.DEQUE_MUTATED_DURING_ITERATION); + throw raiseNode.raise(inliningTarget, RuntimeError, ErrorMessages.DEQUE_MUTATED_DURING_ITERATION); } } } - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.S_IS_NOT_DEQUE, value); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.S_IS_NOT_DEQUE, value); } @Specialization static int doGeneric(VirtualFrame frame, PDeque self, Object value, Object start, Object stop, @Bind("this") Node inliningTarget, - @Exclusive @Cached PyObjectRichCompareBool.EqNode eqNode, + @Exclusive @Cached PyObjectRichCompareBool eqNode, @Cached CastToJavaIntExactNode castToIntNode, @Cached PyNumberAsSizeNode startIndexNode, @Cached PyNumberAsSizeNode stopIndexNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { int istart; int istop; if (start != PNone.NO_VALUE) { @@ -492,7 +491,7 @@ protected ArgumentClinicProvider getArgumentClinic() { PNone doGeneric(PDeque self, int index, Object value) { int n = self.getSize(); if (self.getMaxLength() == n) { - throw PRaiseNode.raiseUncached(this, IndexError, ErrorMessages.DEQUE_AT_MAX_SIZE); + throw PRaiseNode.raiseStatic(this, IndexError, ErrorMessages.DEQUE_AT_MAX_SIZE); } // shortcuts for simple cases @@ -522,10 +521,10 @@ public abstract static class DequePopNode extends PythonUnaryBuiltinNode { @Specialization static Object doGeneric(PDeque self, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object value = self.pop(); if (value == null) { - throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.POP_FROM_EMPTY_DEQUE); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.POP_FROM_EMPTY_DEQUE); } return value; } @@ -539,10 +538,10 @@ public abstract static class DequePopLeftNode extends PythonUnaryBuiltinNode { @Specialization static Object doGeneric(PDeque self, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object value = self.popLeft(); if (value == null) { - throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.POP_FROM_EMPTY_DEQUE); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.POP_FROM_EMPTY_DEQUE); } return value; } @@ -560,9 +559,9 @@ Object doGeneric(PDeque self, Object value) { int n = self.getSize(); for (int i = 0; i < n; i++) { try { - boolean result = PyObjectRichCompareBool.EqNode.compareUncached(self.peekLeft(), value); + boolean result = PyObjectRichCompareBool.executeUncached(self.peekLeft(), value, RichCmpOp.Py_EQ); if (n != self.getSize()) { - throw PRaiseNode.raiseUncached(this, IndexError, DEQUE_MUTATED_DURING_REMOVE); + throw PRaiseNode.raiseStatic(this, IndexError, DEQUE_MUTATED_DURING_REMOVE); } if (result) { Object removed = self.popLeft(); @@ -582,7 +581,7 @@ Object doGeneric(PDeque self, Object value) { throw e; } } - throw PRaiseNode.raiseUncached(this, ValueError, DEQUE_REMOVE_X_NOT_IN_DEQUE); + throw PRaiseNode.raiseStatic(this, ValueError, DEQUE_REMOVE_X_NOT_IN_DEQUE); } } @@ -670,7 +669,7 @@ static int doGeneric(PDeque self) { } // deque.__iadd__(v) - @Builtin(name = J___IADD__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.sq_inplace_concat, isComplex = true) @GenerateNodeFactory public abstract static class DequeInplaceAddNode extends PythonBinaryBuiltinNode { @@ -690,8 +689,7 @@ static PDeque doDeque(PDeque self, PDeque other) { static PDeque doOther(VirtualFrame frame, PDeque self, Object other, @Bind("this") Node inliningTarget, @Cached PyObjectGetIter getIter, - @Cached GetNextNode getNextNode, - @Cached IsBuiltinObjectProfile isStopIterationProfile) { + @Cached PyIterNextNode nextNode) { if (other instanceof PDeque) { return doDeque(self, (PDeque) other); } @@ -703,9 +701,9 @@ static PDeque doOther(VirtualFrame frame, PDeque self, Object other, Object iterator = getIter.execute(frame, inliningTarget, other); while (true) { try { - self.append(getNextNode.execute(frame, iterator)); - } catch (PException e) { - e.expect(inliningTarget, PythonBuiltinClassType.StopIteration, isStopIterationProfile); + Object next = nextNode.execute(frame, inliningTarget, iterator); + self.append(next); + } catch (IteratorExhausted e) { break; } } @@ -720,7 +718,7 @@ public abstract static class DequeAddNode extends SqConcatBuiltinNode { @Specialization @TruffleBoundary static PDeque doDeque(PDeque self, PDeque other) { - PDeque newDeque = PythonObjectFactory.getUncached().createDeque(); + PDeque newDeque = PFactory.createDeque(PythonLanguage.get(null)); newDeque.setMaxLength(self.getMaxLength()); newDeque.addAll(self); newDeque.addAll(other); @@ -730,24 +728,18 @@ static PDeque doDeque(PDeque self, PDeque other) { @Specialization(replaces = "doDeque") static PDeque doGeneric(PDeque self, Object other, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (!(other instanceof PDeque)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CAN_ONLY_CONCATENATE_DEQUE_NOT_P_TO_DEQUE, other); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CAN_ONLY_CONCATENATE_DEQUE_NOT_P_TO_DEQUE, other); } return doDeque(self, (PDeque) other); } } - // deque.__mul__(v) - @Builtin(name = J___IMUL__, minNumOfPositionalArgs = 2, parameterNames = {"$self", "n"}) + // deque.__imul__(v) + @Slot(value = SlotKind.sq_inplace_repeat, isComplex = true) @GenerateNodeFactory - @ArgumentClinic(name = "n", conversion = ClinicConversion.Index) - public abstract static class DequeInplaceMulNode extends PythonBinaryClinicBuiltinNode { - - @Override - protected ArgumentClinicProvider getArgumentClinic() { - return DequeInplaceMulNodeClinicProviderGen.INSTANCE; - } + public abstract static class DequeInplaceMulNode extends SqRepeatBuiltinNode { @Specialization PDeque doGeneric(PDeque self, int n) { @@ -766,7 +758,7 @@ static PDeque doGeneric(Node node, PDeque self, int n) { } if (size > Integer.MAX_VALUE / n) { - throw PRaiseNode.raiseUncached(node, MemoryError); + throw PRaiseNode.raiseStatic(node, MemoryError); } // Reduce the number of repetitions when maxlen would be exceeded @@ -790,27 +782,27 @@ public abstract static class DequeMulNode extends SqRepeatBuiltinNode { @Specialization @TruffleBoundary PDeque doGeneric(PDeque self, int n) { - PDeque newDeque = PythonObjectFactory.getUncached().createDeque(); + PDeque newDeque = PFactory.createDeque(PythonLanguage.get(null)); newDeque.setMaxLength(self.getMaxLength()); newDeque.addAll(self); return DequeInplaceMulNode.doGeneric(this, newDeque, n); } } - @Builtin(name = J___CONTAINS__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.sq_contains, isComplex = true) @GenerateNodeFactory - public abstract static class DequeContainsNode extends PythonBinaryBuiltinNode { + public abstract static class DequeContainsNode extends SqContainsBuiltinNode { @Specialization @TruffleBoundary boolean doGeneric(PDeque self, Object value) { int startState = self.getState(); for (Object item : self.data) { - if (PyObjectRichCompareBool.EqNode.compareUncached(item, value)) { + if (PyObjectRichCompareBool.executeUncached(item, value, RichCmpOp.Py_EQ)) { return true; } if (startState != self.getState()) { - throw PRaiseNode.raiseUncached(this, RuntimeError, ErrorMessages.DEQUE_MUTATED_DURING_ITERATION); + throw PRaiseNode.raiseStatic(this, RuntimeError, ErrorMessages.DEQUE_MUTATED_DURING_ITERATION); } } return false; @@ -852,14 +844,14 @@ static void setOrDel(PDeque self, int idx, Object value, } // deque.__iter__() - @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iter, isComplex = true) @GenerateNodeFactory public abstract static class DequeIterNode extends PythonUnaryBuiltinNode { @Specialization static PDequeIter doGeneric(PDeque self, - @Cached PythonObjectFactory factory) { - return factory.createDequeIter(self); + @Bind PythonLanguage language) { + return PFactory.createDequeIter(language, self); } } @@ -870,13 +862,13 @@ public abstract static class DequeReversedNode extends PythonUnaryBuiltinNode { @Specialization static PDequeIter doGeneric(PDeque self, - @Cached PythonObjectFactory factory) { - return factory.createDequeRevIter(self); + @Bind PythonLanguage language) { + return PFactory.createDequeRevIter(language, self); } } // deque.__repr__() - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class DequeReprNode extends PythonUnaryBuiltinNode { @@ -890,7 +882,7 @@ TruffleString repr(PDeque self) { Node outerNode = ref.set(this); try { Object[] items = self.data.toArray(); - PList asList = PythonObjectFactory.getUncached().createList(items); + PList asList = PFactory.createList(PythonLanguage.get(null), items); int maxLength = self.getMaxLength(); TruffleStringBuilder sb = TruffleStringBuilder.create(TS_ENCODING); sb.appendStringUncached(GetNameNode.executeUncached(GetPythonObjectClassNode.executeUncached(self))); @@ -919,149 +911,74 @@ Object doGeneric(VirtualFrame frame, PDeque self, @Cached PyObjectGetIter getIter, @Cached PyObjectGetStateNode getStateNode, @Cached GetClassNode getClassNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { Object clazz = getClassNode.execute(inliningTarget, self); Object state = getStateNode.execute(frame, inliningTarget, self); Object it = getIter.execute(frame, inliningTarget, self); - PTuple emptyTuple = factory.createEmptyTuple(); + PTuple emptyTuple = PFactory.createEmptyTuple(language); int maxLength = self.getMaxLength(); if (maxLength != -1) { - return factory.createTuple(new Object[]{clazz, factory.createTuple(new Object[]{emptyTuple, maxLength}), state, it}); + return PFactory.createTuple(language, new Object[]{clazz, PFactory.createTuple(language, new Object[]{emptyTuple, maxLength}), state, it}); } - return factory.createTuple(new Object[]{clazz, emptyTuple, state, it}); + return PFactory.createTuple(language, new Object[]{clazz, emptyTuple, state, it}); } } - @GenerateInline - @GenerateCached(false) - public abstract static class DequeCompareHelperNode extends Node { - - abstract Object execute(VirtualFrame frame, Node inliningTarget, Object self, Object other, ComparisonOp op, PyObjectRichCompareBool.ComparisonBaseNode cmpNode); - - @Specialization(guards = {"self == other", "op.isEqualityOp()"}) + @Slot(value = SlotKind.tp_richcompare, isComplex = true) + @GenerateNodeFactory + public abstract static class DequeRichCmpNode extends TpSlotRichCompare.RichCmpBuiltinNode { + @Specialization(guards = {"self == other", "op.isEqOrNe()"}) @SuppressWarnings("unused") - static boolean doSame(PDeque self, PDeque other, ComparisonOp op, PyObjectRichCompareBool.ComparisonBaseNode cmpNode) { - return op == ComparisonOp.EQ; + static boolean doSame(PDeque self, PDeque other, RichCmpOp op) { + return op == RichCmpOp.Py_EQ; } - @Specialization(guards = {"self.getSize() != other.getSize()", "op.isEqualityOp()"}) + @Specialization(guards = {"self.getSize() != other.getSize()", "op.isEqOrNe()"}) @SuppressWarnings("unused") - static boolean doDifferentLengths(PDeque self, PDeque other, ComparisonOp op, PyObjectRichCompareBool.ComparisonBaseNode cmpNode) { - return op == ComparisonOp.NE; + static boolean doDifferentLengths(PDeque self, PDeque other, RichCmpOp op) { + return op == RichCmpOp.Py_NE; } @Specialization(guards = "!isPDeque(self) || !isPDeque(other)") @SuppressWarnings("unused") - static Object doOther(Object self, Object other, ComparisonOp op, PyObjectRichCompareBool.ComparisonBaseNode cmpNode) { + static Object doOther(Object self, Object other, RichCmpOp op) { return PNotImplemented.NOT_IMPLEMENTED; } @Specialization(guards = "isGenericCase(self, other, op)") - static Object doGeneric(VirtualFrame frame, Node inliningTarget, PDeque self, PDeque other, @SuppressWarnings("unused") ComparisonOp op, PyObjectRichCompareBool.ComparisonBaseNode cmpNode, + static Object doGeneric(VirtualFrame frame, PDeque self, PDeque other, RichCmpOp op, + @Bind("$node") Node inliningTarget, @Cached PyObjectGetIter getIterSelf, @Cached PyObjectGetIter getIterOther, - @Cached(inline = false) GetNextNode selfItNextNode, - @Cached(inline = false) GetNextNode otherItNextNode, - @Cached PyObjectRichCompareBool.EqNode eqNode, - @Cached IsBuiltinObjectProfile profile) { + @Cached PyIterNextNode selfItNextNode, + @Cached PyIterNextNode otherItNextNode, + @Cached PyObjectRichCompareBool eqNode, + @Cached PyObjectRichCompareBool cmpNode) { Object ait = getIterSelf.execute(frame, inliningTarget, self); Object bit = getIterOther.execute(frame, inliningTarget, other); while (true) { + Object selfItem, otherItem; try { - Object selfItem = selfItNextNode.execute(frame, ait); - Object otherItem = otherItNextNode.execute(frame, bit); - if (!eqNode.compare(frame, inliningTarget, selfItem, otherItem)) { - return cmpNode.compare(frame, inliningTarget, selfItem, otherItem); - } - } catch (PException e) { - e.expect(inliningTarget, StopIteration, profile); - return cmpNode.compare(frame, inliningTarget, self.getSize(), other.getSize()); + selfItem = selfItNextNode.execute(frame, inliningTarget, ait); + otherItem = otherItNextNode.execute(frame, inliningTarget, bit); + } catch (IteratorExhausted e) { + break; + } + if (!eqNode.execute(frame, inliningTarget, selfItem, otherItem, RichCmpOp.Py_EQ)) { + return cmpNode.execute(frame, inliningTarget, selfItem, otherItem, op); } } + return cmpNode.execute(frame, inliningTarget, self.getSize(), other.getSize(), op); } static boolean isPDeque(Object object) { return object instanceof PDeque; } - static boolean isGenericCase(PDeque self, PDeque other, ComparisonOp op) { - return !op.isEqualityOp() || (self != other && self.getSize() == other.getSize()); - } - } - - @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class DequeEqNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doCmp(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached DequeCompareHelperNode helperNode, - @Cached PyObjectRichCompareBool.EqNode cmpNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.EQ, cmpNode); - } - } - - @Builtin(name = J___NE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class DequeNeNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doCmp(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached DequeCompareHelperNode helperNode, - @Cached PyObjectRichCompareBool.NeNode cmpNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.NE, cmpNode); - } - } - - @Builtin(name = J___LE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class DequeLeNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doCmp(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached DequeCompareHelperNode helperNode, - @Cached PyObjectRichCompareBool.LeNode cmpNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.LE, cmpNode); - } - } - - @Builtin(name = J___LT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class DequeLtNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doCmp(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached DequeCompareHelperNode helperNode, - @Cached PyObjectRichCompareBool.LtNode cmpNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.LT, cmpNode); - } - } - - @Builtin(name = J___GE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class DequeGeNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doCmp(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached DequeCompareHelperNode helperNode, - @Cached PyObjectRichCompareBool.GeNode cmpNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.GE, cmpNode); + static boolean isGenericCase(PDeque self, PDeque other, RichCmpOp op) { + return !op.isEqOrNe() || (self != other && self.getSize() == other.getSize()); } - - } - - @Builtin(name = J___GT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class DequeGtNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doCmp(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached DequeCompareHelperNode helperNode, - @Cached PyObjectRichCompareBool.GtNode cmpNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.GT, cmpNode); - } - } @Builtin(name = J___CLASS_GETITEM__, minNumOfPositionalArgs = 2, isClassmethod = true) @@ -1069,8 +986,8 @@ static Object doCmp(VirtualFrame frame, Object self, Object other, public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode { @Specialization static Object classGetItem(Object cls, Object key, - @Cached PythonObjectFactory factory) { - return factory.createGenericAlias(cls, key); + @Bind PythonLanguage language) { + return PFactory.createGenericAlias(language, cls, key); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeIterBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeIterBuiltins.java index 66e8f2e586..fbe1d7ac6a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeIterBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeIterBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,106 +40,71 @@ */ package com.oracle.graal.python.builtins.objects.deque; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.RuntimeError; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LENGTH_HINT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; +import static com.oracle.graal.python.nodes.BuiltinNames.J_DEQUE_ITER; -import java.util.ConcurrentModificationException; import java.util.List; -import java.util.NoSuchElementException; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.lib.PyNumberIndexNode; +import com.oracle.graal.python.nodes.BuiltinNames; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; +import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; -@CoreFunctions(extendClasses = {PythonBuiltinClassType.PDequeIter, PythonBuiltinClassType.PDequeRevIter}) +@CoreFunctions(extendClasses = PythonBuiltinClassType.PDequeIter) public final class DequeIterBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = DequeIterBuiltinsSlotsGen.SLOTS; @Override protected List> getNodeFactories() { return DequeIterBuiltinsFactory.getFactories(); } - // _deque_iterator.__iter__() - @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = J_DEQUE_ITER, minNumOfPositionalArgs = 2, parameterNames = {"$self", "iterable", "index"}) @GenerateNodeFactory - public abstract static class DequeIterIterNode extends PythonUnaryBuiltinNode { + public abstract static class DequeIterNode extends PythonTernaryBuiltinNode { @Specialization - static PDequeIter doGeneric(PDequeIter self) { - return self; - } - } - - // _deque_iterator.__next__() - @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1) - @GenerateNodeFactory - public abstract static class DequeIterNextNode extends PythonUnaryBuiltinNode { - - public abstract Object execute(PDequeIter self); - - @Specialization - @TruffleBoundary - Object doGeneric(PDequeIter self) { - try { - if (self.startState == self.deque.getState()) { - if (!self.hasNext()) { - assert self.lengthHint() == 0; - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.StopIteration); - } - return self.next(); + static PDequeIter doGeneric(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object deque, Object indexObj, + @Bind("this") Node inliningTarget, + @Cached InlinedConditionProfile dequeProfile, + @Cached InlinedConditionProfile indexNoneProfile, + @Cached PyNumberIndexNode toIndexNode, + @Cached CastToJavaIntExactNode castToJavaIntExactNode, + @Cached DequeIterCommonBuiltins.DequeIterNextNode getNextNode, + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { + if (!dequeProfile.profile(inliningTarget, deque instanceof PDeque)) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.EXPECTED_OBJ_TYPE_S_GOT_P, BuiltinNames.T_DEQUE, deque); + } + PDequeIter dequeIter = PFactory.createDequeIter(language, (PDeque) deque); + if (indexNoneProfile.profile(inliningTarget, indexObj != PNone.NO_VALUE)) { + int index = castToJavaIntExactNode.execute(inliningTarget, toIndexNode.execute(frame, inliningTarget, indexObj)); + for (int i = 0; i < index; i++) { + getNextNode.execute(dequeIter); } - } catch (NoSuchElementException e) { - throw CompilerDirectives.shouldNotReachHere(); - } catch (ConcurrentModificationException e) { - // fall through } - self.reset(); - throw PRaiseNode.raiseUncached(this, RuntimeError, ErrorMessages.DEQUE_MUTATED_DURING_ITERATION); - } - } - - // _deque_iterator.__length_hint__() - @Builtin(name = J___LENGTH_HINT__, minNumOfPositionalArgs = 1) - @GenerateNodeFactory - public abstract static class DequeIterLengthHintNode extends PythonUnaryBuiltinNode { - - @Specialization - static int doGeneric(PDequeIter self) { - return self.lengthHint(); - } - } - - // _deque_iterator.__reduce__() - @Builtin(name = J___REDUCE__, minNumOfPositionalArgs = 1) - @GenerateNodeFactory - public abstract static class DequeIterReduceNode extends PythonUnaryBuiltinNode { - - @Specialization - static PTuple doGeneric(PDequeIter self, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached PythonObjectFactory factory) { - Object clazz = getClassNode.execute(inliningTarget, self); - return factory.createTuple(new Object[]{clazz, factory.createTuple(new Object[]{self.deque, self.deque.getSize() - self.lengthHint()})}); + return dequeIter; } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeIterCommonBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeIterCommonBuiltins.java new file mode 100644 index 0000000000..32012e8ab8 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeIterCommonBuiltins.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.builtins.objects.deque; + +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.RuntimeError; +import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LENGTH_HINT__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; + +import java.util.ConcurrentModificationException; +import java.util.List; +import java.util.NoSuchElementException; + +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.builtins.CoreFunctions; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateNodeFactory; +import com.oracle.truffle.api.dsl.NodeFactory; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; + +@CoreFunctions(extendClasses = {PythonBuiltinClassType.PDequeIter, PythonBuiltinClassType.PDequeRevIter}) +public final class DequeIterCommonBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = DequeIterCommonBuiltinsSlotsGen.SLOTS; + + @Override + protected List> getNodeFactories() { + return DequeIterCommonBuiltinsFactory.getFactories(); + } + + // _deque_iterator.__iter__() + @Slot(value = SlotKind.tp_iter, isComplex = true) + @GenerateNodeFactory + public abstract static class DequeIterIterNode extends PythonUnaryBuiltinNode { + + @Specialization + static PDequeIter doGeneric(PDequeIter self) { + return self; + } + } + + // _deque_iterator.__next__() + @Slot(value = SlotKind.tp_iternext, isComplex = true) + @GenerateNodeFactory + public abstract static class DequeIterNextNode extends TpIterNextBuiltin { + + public abstract Object execute(PDequeIter self); + + @Specialization + @TruffleBoundary + Object doGeneric(PDequeIter self) { + try { + if (self.startState == self.deque.getState()) { + if (!self.hasNext()) { + assert self.lengthHint() == 0; + throw iteratorExhausted(); + } + return self.next(); + } + } catch (NoSuchElementException e) { + throw CompilerDirectives.shouldNotReachHere(); + } catch (ConcurrentModificationException e) { + // fall through + } + self.reset(); + throw PRaiseNode.raiseStatic(this, RuntimeError, ErrorMessages.DEQUE_MUTATED_DURING_ITERATION); + } + } + + // _deque_iterator.__length_hint__() + @Builtin(name = J___LENGTH_HINT__, minNumOfPositionalArgs = 1) + @GenerateNodeFactory + public abstract static class DequeIterLengthHintNode extends PythonUnaryBuiltinNode { + + @Specialization + static int doGeneric(PDequeIter self) { + return self.lengthHint(); + } + } + + // _deque_iterator.__reduce__() + @Builtin(name = J___REDUCE__, minNumOfPositionalArgs = 1) + @GenerateNodeFactory + public abstract static class DequeIterReduceNode extends PythonUnaryBuiltinNode { + + @Specialization + static PTuple doGeneric(PDequeIter self, + @Bind("this") Node inliningTarget, + @Cached GetClassNode getClassNode, + @Bind PythonLanguage language) { + Object clazz = getClassNode.execute(inliningTarget, self); + return PFactory.createTuple(language, new Object[]{clazz, PFactory.createTuple(language, new Object[]{self.deque, self.deque.getSize() - self.lengthHint()})}); + } + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeRevIterBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeRevIterBuiltins.java new file mode 100644 index 0000000000..bd9261862e --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeRevIterBuiltins.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.builtins.objects.deque; + +import static com.oracle.graal.python.nodes.BuiltinNames.J_DEQUE_REV_ITER; + +import java.util.List; + +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; +import com.oracle.graal.python.builtins.CoreFunctions; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.lib.PyNumberIndexNode; +import com.oracle.graal.python.nodes.BuiltinNames; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; +import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateNodeFactory; +import com.oracle.truffle.api.dsl.NodeFactory; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; + +@CoreFunctions(extendClasses = PythonBuiltinClassType.PDequeRevIter) +public class DequeRevIterBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = DequeRevIterBuiltinsSlotsGen.SLOTS; + + @Override + protected List> getNodeFactories() { + return DequeRevIterBuiltinsFactory.getFactories(); + } + + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = J_DEQUE_REV_ITER, minNumOfPositionalArgs = 2, parameterNames = {"$self", "iterable", "index"}) + @GenerateNodeFactory + public abstract static class DequeRevIterNode extends PythonTernaryBuiltinNode { + @Specialization + static PDequeIter doGeneric(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object deque, Object indexObj, + @Bind("this") Node inliningTarget, + @Cached InlinedConditionProfile dequeProfile, + @Cached InlinedConditionProfile indexNoneProfile, + @Cached PyNumberIndexNode toIndexNode, + @Cached CastToJavaIntExactNode castToJavaIntExactNode, + @Cached DequeIterCommonBuiltins.DequeIterNextNode getNextNode, + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { + if (!dequeProfile.profile(inliningTarget, deque instanceof PDeque)) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.EXPECTED_OBJ_TYPE_S_GOT_P, BuiltinNames.T_DEQUE, deque); + } + PDequeIter dequeIter = PFactory.createDequeRevIter(language, (PDeque) deque); + if (indexNoneProfile.profile(inliningTarget, indexObj != PNone.NO_VALUE)) { + int index = castToJavaIntExactNode.execute(inliningTarget, toIndexNode.execute(frame, inliningTarget, indexObj)); + for (int i = 0; i < index; i++) { + getNextNode.execute(dequeIter); + } + } + return dequeIter; + } + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DefaultDictBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DefaultDictBuiltins.java index eefa3beb93..1c0de526dd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DefaultDictBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DefaultDictBuiltins.java @@ -41,16 +41,17 @@ package com.oracle.graal.python.builtins.objects.dict; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; +import static com.oracle.graal.python.nodes.BuiltinNames.J_DEFAULTDICT; import static com.oracle.graal.python.nodes.ErrorMessages.FIRST_ARG_MUST_BE_CALLABLE_S; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___MISSING__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -71,11 +72,11 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -97,7 +98,20 @@ protected List> getNodeFa return DefaultDictBuiltinsFactory.getFactories(); } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = J_DEFAULTDICT, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class DefaultDictNode extends PythonVarargsBuiltinNode { + @Specialization + @SuppressWarnings("unused") + PDefaultDict doGeneric(Object cls, Object[] args, PKeyword[] kwargs, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + return PFactory.createDefaultDict(language, cls, getInstanceShape.execute(cls)); + } + } + + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization @@ -124,11 +138,11 @@ static Object reduce(VirtualFrame frame, PDefaultDict self, @Bind("this") Node inliningTarget, @Cached GetClassNode getClassNode, @Cached PyObjectGetIter getIter, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { final Object defaultFactory = self.getDefaultFactory(); - PTuple args = (defaultFactory == PNone.NONE) ? factory.createEmptyTuple() : factory.createTuple(new Object[]{defaultFactory}); - Object iter = getIter.execute(frame, inliningTarget, factory.createDictItemsView(self)); - return factory.createTuple(new Object[]{getClassNode.execute(inliningTarget, self), args, PNone.NONE, PNone.NONE, iter}); + PTuple args = (defaultFactory == PNone.NONE) ? PFactory.createEmptyTuple(language) : PFactory.createTuple(language, new Object[]{defaultFactory}); + Object iter = getIter.execute(frame, inliningTarget, PFactory.createDictItemsView(language, self)); + return PFactory.createTuple(language, new Object[]{getClassNode.execute(inliningTarget, self), args, PNone.NONE, PNone.NONE, iter}); } } @@ -140,8 +154,8 @@ public abstract static class CopyNode extends PythonUnaryBuiltinNode { static PDefaultDict copy(@SuppressWarnings("unused") VirtualFrame frame, PDefaultDict self, @Bind("this") Node inliningTarget, @Cached HashingStorageCopy copyNode, - @Cached PythonObjectFactory factory) { - return factory.createDefaultDict(self.getDefaultFactory(), copyNode.execute(inliningTarget, self.getDictStorage())); + @Bind PythonLanguage language) { + return PFactory.createDefaultDict(language, self.getDefaultFactory(), copyNode.execute(inliningTarget, self.getDictStorage())); } } @@ -150,9 +164,8 @@ static PDefaultDict copy(@SuppressWarnings("unused") VirtualFrame frame, PDefaul public abstract static class MissingNode extends PythonBinaryBuiltinNode { @Specialization(guards = "isNone(self.getDefaultFactory())") static Object doNoFactory(@SuppressWarnings("unused") PDefaultDict self, Object key, - @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.KeyError, new Object[]{key}); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.KeyError, new Object[]{key}); } @Specialization(guards = "!isNone(self.getDefaultFactory())") @@ -166,21 +179,22 @@ static Object doMissing(VirtualFrame frame, PDefaultDict self, Object key, } } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(name = "defaultdict", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory - public abstract static class InitNode extends PythonBuiltinNode { + public abstract static class InitNode extends PythonVarargsBuiltinNode { @Specialization static Object doInit(VirtualFrame frame, PDefaultDict self, Object[] args, PKeyword[] kwargs, @Bind("this") Node inliningTarget, @Cached DictBuiltins.InitNode dictInitNode, @Cached PyCallableCheckNode callableCheckNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object[] newArgs = args; Object newDefault = PNone.NONE; if (newArgs.length > 0) { newDefault = newArgs[0]; if (newDefault != PNone.NONE && !callableCheckNode.execute(inliningTarget, newDefault)) { - throw raiseNode.get(inliningTarget).raise(TypeError, FIRST_ARG_MUST_BE_CALLABLE_S, " or None"); + throw raiseNode.raise(inliningTarget, TypeError, FIRST_ARG_MUST_BE_CALLABLE_S, " or None"); } newArgs = PythonUtils.arrayCopyOfRange(args, 1, args.length); } @@ -215,7 +229,7 @@ static Object or(VirtualFrame frame, PDict self, PDict other, @Cached GetClassNode getClassNode, @Cached CallNode callNode, @Cached DictNodes.UpdateNode updateNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { PDefaultDict dd = (PDefaultDict) (self instanceof PDefaultDict ? self : other); Object type = getClassNode.execute(inliningTarget, dd); Object result = callNode.execute(frame, type, dd.getDefaultFactory(), self); @@ -224,7 +238,7 @@ static Object or(VirtualFrame frame, PDict self, PDict other, return result; } else { /* Cpython doesn't check for this and ends up with SystemError */ - throw raiseNode.get(inliningTarget).raise(TypeError); + throw raiseNode.raise(inliningTarget, TypeError); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictBuiltins.java index 3a23d26d0b..3343033f36 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictBuiltins.java @@ -26,25 +26,23 @@ package com.oracle.graal.python.builtins.objects.dict; import static com.oracle.graal.python.builtins.objects.PNone.NO_VALUE; +import static com.oracle.graal.python.nodes.BuiltinNames.J_DICT; import static com.oracle.graal.python.nodes.SpecialMethodNames.J_ITEMS; import static com.oracle.graal.python.nodes.SpecialMethodNames.J_KEYS; import static com.oracle.graal.python.nodes.SpecialMethodNames.J_VALUES; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CONTAINS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IOR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REVERSED__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.KeyError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.HashNotImplemented; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -52,6 +50,7 @@ import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.common.EmptyStorage; import com.oracle.graal.python.builtins.objects.common.ForeignHashingStorage; import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes; import com.oracle.graal.python.builtins.objects.common.HashingStorage; @@ -67,23 +66,30 @@ import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStoragePop; import com.oracle.graal.python.builtins.objects.dict.DictBuiltinsFactory.DispatchMissingNodeGen; import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotMpAssSubscript.MpAssSubscriptBuiltinNode; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.RichCmpBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyDictCheckNode; import com.oracle.graal.python.lib.PyDictSetDefault; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyObjectSetItem; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.SpecialMethodNames; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode; +import com.oracle.graal.python.nodes.call.special.SpecialMethodNotFound; +import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; @@ -92,9 +98,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; @@ -109,6 +113,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.profiles.InlinedConditionProfile; /** @@ -117,13 +122,13 @@ * a proper error and not allow other objects as arguments. */ @CoreFunctions(extendClasses = PythonBuiltinClassType.PDict) +@HashNotImplemented public final class DictBuiltins extends PythonBuiltins { public static final TpSlots SLOTS = DictBuiltinsSlotsGen.SLOTS; @Override public void initialize(Python3Core core) { super.initialize(core); - addBuiltinConstant(T___HASH__, PNone.NONE); } @Override @@ -131,7 +136,42 @@ protected List> getNodeFactories() { return DictReprBuiltinFactory.getFactories(); } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { private static final TruffleString T_LPAREN_BRACKET = tsLiteral("(["); @@ -139,12 +142,12 @@ protected final int getLimit() { protected static TruffleString getReprString(Node inliningTarget, Object obj, ReprState s, LookupAndCallUnaryDynamicNode reprNode, CastToTruffleStringNode castStr, - PRaiseNode.Lazy raiseNode) { + PRaiseNode raiseNode) { Object reprObj = s == null || obj != s.self ? reprNode.executeObject(obj, T___REPR__) : T_ELLIPSIS_IN_BRACES; try { return castStr.execute(inliningTarget, reprObj); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.RETURNED_NON_STRING, "__repr__", reprObj); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.RETURNED_NON_STRING, "__repr__", reprObj); } } @@ -165,7 +168,7 @@ public static ReprState append(@SuppressWarnings("unused") Node node, HashingSto @Bind("this") Node inliningTarget, @Cached LookupAndCallUnaryDynamicNode reprNode, @Cached CastToTruffleStringNode castStr, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached InlinedConditionProfile lengthCheck, @Cached HashingStorageIteratorKey itKey, @Cached TruffleStringBuilder.AppendStringNode appendStringNode) { @@ -186,7 +189,7 @@ public static ReprState dict(Frame frame, @SuppressWarnings("unused") Node node, @Bind("this") Node inliningTarget, @Cached LookupAndCallUnaryDynamicNode reprNode, @Cached CastToTruffleStringNode castStr, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached InlinedConditionProfile lengthCheck, @Cached HashingStorageIteratorValue itValue, @Cached TruffleStringBuilder.AppendStringNode appendStringNode) { @@ -208,7 +211,7 @@ public static ReprState dict(Frame frame, @SuppressWarnings("unused") Node node, @Cached LookupAndCallUnaryDynamicNode keyReprNode, @Cached LookupAndCallUnaryDynamicNode valueReprNode, @Cached CastToTruffleStringNode castStr, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached InlinedConditionProfile lengthCheck, @Cached HashingStorageIteratorKey itKey, @Cached HashingStorageIteratorValue itValue, @@ -236,7 +239,7 @@ public static ReprState dict(Frame frame, @SuppressWarnings("unused") Node node, @Cached LookupAndCallUnaryDynamicNode keyReprNode, @Cached LookupAndCallUnaryDynamicNode valueReprNode, @Cached CastToTruffleStringNode castStr, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached InlinedConditionProfile lengthCheck, @Cached HashingStorageIteratorKey itKey, @Cached HashingStorageIteratorValue itValue, diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictValuesBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictValuesBuiltins.java index e442eb1674..ad2262067f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictValuesBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictValuesBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -25,11 +25,11 @@ */ package com.oracle.graal.python.builtins.objects.dict; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REVERSED__; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.Builtin; @@ -45,7 +45,7 @@ import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -68,8 +68,8 @@ protected List> getNodeFa abstract static class MappingNode extends PythonUnaryBuiltinNode { @Specialization static Object mapping(PDictView self, - @Cached PythonObjectFactory factory) { - return factory.createMappingproxy(self.getWrappedDict()); + @Bind PythonLanguage language) { + return PFactory.createMappingproxy(language, self.getWrappedDict()); } } @@ -85,7 +85,7 @@ static int run(PDictView self, } } - @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iter, isComplex = true) @GenerateNodeFactory public abstract static class IterNode extends PythonUnaryBuiltinNode { @Specialization @@ -93,9 +93,9 @@ static Object doPDictValuesView(PDictValuesView self, @Bind("this") Node inliningTarget, @Cached HashingStorageLen lenNode, @Cached HashingStorageGetIterator getIterator, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { HashingStorage storage = self.getWrappedStorage(); - return factory.createDictValueIterator(getIterator.execute(inliningTarget, storage), storage, lenNode.execute(inliningTarget, storage)); + return PFactory.createDictValueIterator(language, getIterator.execute(inliningTarget, storage), storage, lenNode.execute(inliningTarget, storage)); } } @@ -107,9 +107,9 @@ static Object doPDictValuesView(PDictValuesView self, @Bind("this") Node inliningTarget, @Cached HashingStorageLen lenNode, @Cached HashingStorageGetReverseIterator getReverseIter, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { HashingStorage storage = self.getWrappedStorage(); - return factory.createDictValueIterator(getReverseIter.execute(inliningTarget, storage), storage, lenNode.execute(inliningTarget, storage)); + return PFactory.createDictValueIterator(language, getReverseIter.execute(inliningTarget, storage), storage, lenNode.execute(inliningTarget, storage)); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictViewBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictViewBuiltins.java index e93012e83c..05a917e4d8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictViewBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictViewBuiltins.java @@ -41,18 +41,11 @@ package com.oracle.graal.python.builtins.objects.dict; import static com.oracle.graal.python.nodes.SpecialMethodNames.J_ISDISJOINT; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CONTAINS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REVERSED__; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.Builtin; @@ -78,26 +71,25 @@ import com.oracle.graal.python.builtins.objects.set.PSet; import com.oracle.graal.python.builtins.objects.set.SetNodes; import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare; +import com.oracle.graal.python.lib.RichCmpOp; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.lib.PyObjectRichCompareBool; import com.oracle.graal.python.lib.PyObjectSizeNode; +import com.oracle.graal.python.lib.PySequenceContainsNode; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; -import com.oracle.graal.python.util.ComparisonOp; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -131,8 +123,8 @@ protected List> getNodeFa abstract static class MappingNode extends PythonUnaryBuiltinNode { @Specialization static Object mapping(PDictView self, - @Cached PythonObjectFactory factory) { - return factory.createMappingproxy(self.getWrappedDict()); + @Bind PythonLanguage language) { + return PFactory.createMappingproxy(language, self.getWrappedDict()); } } @@ -148,7 +140,7 @@ static int len(PDictView self, } } - @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iter, isComplex = true) @GenerateNodeFactory public abstract static class IterNode extends PythonUnaryBuiltinNode { @Specialization @@ -156,9 +148,9 @@ static Object getKeysViewIter(@SuppressWarnings("unused") PDictKeysView self, @Bind("this") Node inliningTarget, @Shared("len") @Cached HashingStorageLen lenNode, @Shared("getit") @Cached HashingStorageGetIterator getIterator, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { HashingStorage storage = self.getWrappedStorage(); - return factory.createDictKeyIterator(getIterator.execute(inliningTarget, storage), storage, lenNode.execute(inliningTarget, storage)); + return PFactory.createDictKeyIterator(language, getIterator.execute(inliningTarget, storage), storage, lenNode.execute(inliningTarget, storage)); } @Specialization @@ -166,9 +158,9 @@ static Object getItemsViewIter(PDictItemsView self, @Bind("this") Node inliningTarget, @Shared("len") @Cached HashingStorageLen lenNode, @Shared("getit") @Cached HashingStorageGetIterator getIterator, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { HashingStorage storage = self.getWrappedStorage(); - return factory.createDictItemIterator(getIterator.execute(inliningTarget, storage), storage, lenNode.execute(inliningTarget, storage)); + return PFactory.createDictItemIterator(language, getIterator.execute(inliningTarget, storage), storage, lenNode.execute(inliningTarget, storage)); } } @@ -180,9 +172,9 @@ static Object getReversedKeysViewIter(PDictKeysView self, @Bind("this") Node inliningTarget, @Shared @Cached HashingStorageLen lenNode, @Shared @Cached HashingStorageGetReverseIterator getReverseIterator, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { HashingStorage storage = self.getWrappedStorage(); - return factory.createDictKeyIterator(getReverseIterator.execute(inliningTarget, storage), storage, lenNode.execute(inliningTarget, storage)); + return PFactory.createDictKeyIterator(language, getReverseIterator.execute(inliningTarget, storage), storage, lenNode.execute(inliningTarget, storage)); } @Specialization @@ -190,15 +182,15 @@ static Object getReversedItemsViewIter(PDictItemsView self, @Bind("this") Node inliningTarget, @Shared @Cached HashingStorageLen lenNode, @Shared @Cached HashingStorageGetReverseIterator getReverseIterator, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { HashingStorage storage = self.getWrappedStorage(); - return factory.createDictItemIterator(getReverseIterator.execute(inliningTarget, storage), storage, lenNode.execute(inliningTarget, storage)); + return PFactory.createDictItemIterator(language, getReverseIterator.execute(inliningTarget, storage), storage, lenNode.execute(inliningTarget, storage)); } } - @Builtin(name = J___CONTAINS__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.sq_contains, isComplex = true) @GenerateNodeFactory - public abstract static class ContainsNode extends PythonBinaryBuiltinNode { + public abstract static class ContainsNode extends SqContainsBuiltinNode { @SuppressWarnings("unused") @Specialization(guards = "len.execute(inliningTarget, self.getWrappedStorage()) == 0", limit = "1") static boolean containsEmpty(PDictView self, Object key, @@ -218,7 +210,7 @@ static boolean contains(VirtualFrame frame, PDictKeysView self, Object key, static boolean contains(VirtualFrame frame, PDictItemsView self, PTuple key, @Bind("this") Node inliningTarget, @Exclusive @Cached HashingStorageGetItem getItem, - @Cached PyObjectRichCompareBool.EqNode eqNode, + @Cached PyObjectRichCompareBool eqNode, @Cached InlinedConditionProfile tupleLenProfile, @Cached("createNotNormalized()") SequenceStorageNodes.GetItemNode getTupleItemNode) { SequenceStorage tupleStorage = key.getSequenceStorage(); @@ -228,7 +220,7 @@ static boolean contains(VirtualFrame frame, PDictItemsView self, PTuple key, HashingStorage dictStorage = self.getWrappedStorage(); Object value = getItem.execute(frame, inliningTarget, dictStorage, getTupleItemNode.execute(tupleStorage, 0)); if (value != null) { - return eqNode.compare(frame, inliningTarget, value, getTupleItemNode.execute(tupleStorage, 1)); + return eqNode.execute(frame, inliningTarget, value, getTupleItemNode.execute(tupleStorage, 1), RichCmpOp.Py_EQ); } else { return false; } @@ -298,39 +290,12 @@ static boolean disjoint(VirtualFrame frame, PDictView self, Object other, * view comparisons dictates that we need to use iteration to compare them in the general case. */ protected abstract static class ContainedInNode extends PNodeWithContext { - @Child private GetNextNode next; - @Child private LookupAndCallBinaryNode contains; - @Child private PyObjectIsTrueNode cast; private final boolean checkAll; public ContainedInNode(boolean checkAll) { this.checkAll = checkAll; } - private GetNextNode getNext() { - if (next == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - next = insert(GetNextNode.create()); - } - return next; - } - - private LookupAndCallBinaryNode getContains() { - if (contains == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - contains = insert(LookupAndCallBinaryNode.create(SpecialMethodSlot.Contains)); - } - return contains; - } - - private PyObjectIsTrueNode getCast() { - if (cast == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - cast = insert(PyObjectIsTrueNode.create()); - } - return cast; - } - public abstract boolean execute(VirtualFrame frame, Object self, Object other); @Specialization @@ -338,18 +303,23 @@ public boolean doIt(VirtualFrame frame, Object self, Object other, @Bind("this") Node inliningTarget, @Cached InlinedLoopConditionProfile loopConditionProfile, @Cached PyObjectGetIter getIterNode, - @Cached IsBuiltinObjectProfile stopProfile) { + @Cached PyIterNextNode nextNode, + @Cached PySequenceContainsNode containsNode, + @Cached PyObjectIsTrueNode isTrueNode) { Object iterator = getIterNode.execute(frame, inliningTarget, self); boolean ok = checkAll; int i = 0; try { while (loopConditionProfile.profile(inliningTarget, checkAll && ok || !checkAll && !ok)) { - Object item = getNext().execute(frame, iterator); - ok = getCast().execute(frame, getContains().executeObject(frame, other, item)); + Object item; + try { + item = nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { + break; + } + ok = isTrueNode.execute(frame, containsNode.execute(frame, inliningTarget, other, item)); i++; } - } catch (PException e) { - e.expectStopIteration(inliningTarget, stopProfile); } finally { LoopNode.reportLoopCount(this, i < 0 ? Integer.MAX_VALUE : i); } @@ -367,72 +337,63 @@ static ContainedInNode create(boolean all) { } } - @GenerateInline - @GenerateCached(false) - abstract static class DictViewRichcompareHelperNode extends Node { - - abstract Object execute(VirtualFrame frame, Node inliningTarget, Object self, Object other, ComparisonOp op); + @Slot(value = SlotKind.tp_richcompare, isComplex = true) + @GenerateNodeFactory + abstract static class DictViewRichcompareHelperNode extends TpSlotRichCompare.RichCmpBuiltinNode { - protected static boolean reverse(ComparisonOp op) { - return op == ComparisonOp.GE || op == ComparisonOp.GT; + protected static boolean reverse(RichCmpOp op) { + return op == RichCmpOp.Py_GE || op == RichCmpOp.Py_GT; } - @Specialization - static boolean doView(VirtualFrame frame, Node inliningTarget, PDictView self, PBaseSet other, ComparisonOp op, - @Shared @Cached HashingStorageLen selfLenNode, - @Shared @Cached HashingStorageLen otherLenNode, - @Shared @Cached(inline = false) ContainedInNode allContained) { - int lenSelf = selfLenNode.execute(inliningTarget, self.getWrappedStorage()); - int lenOther = otherLenNode.execute(inliningTarget, other.getDictStorage()); - return op.cmpResultToBool(lenSelf - lenOther) && (reverse(op) ? allContained.execute(frame, other, self) : allContained.execute(frame, self, other)); + static boolean isDictViewOrSet(Object o) { + return o instanceof PDictView || o instanceof PBaseSet; } - @Specialization - static boolean doView(VirtualFrame frame, Node inliningTarget, PDictView self, PDictView other, ComparisonOp op, - @Shared @Cached HashingStorageLen selfLenNode, - @Shared @Cached HashingStorageLen otherLenNode, - @Shared @Cached(inline = false) ContainedInNode allContained) { + @Specialization(guards = "isDictViewOrSet(other)") + static boolean doIt(VirtualFrame frame, PDictView self, Object other, RichCmpOp originalOp, + @Bind("$node") Node inliningTarget, + @Cached InlinedConditionProfile isSetProfile, + @Cached InlinedConditionProfile lenCheckProfile, + @Cached InlinedConditionProfile reverseProfile, + @Cached HashingStorageLen selfLenNode, + @Cached HashingStorageLen otherLenNode, + @Cached(inline = false) ContainedInNode allContained) { + // Note: more compact (to help hosted inlining) implementation, but should be in the end + // the same as CPython dictview_richcompare + RichCmpOp op = originalOp != RichCmpOp.Py_NE ? originalOp : RichCmpOp.Py_EQ; + int lenSelf = selfLenNode.execute(inliningTarget, self.getWrappedStorage()); - int lenOther = otherLenNode.execute(inliningTarget, other.getWrappedStorage()); - return op.cmpResultToBool(lenSelf - lenOther) && (reverse(op) ? allContained.execute(frame, other, self) : allContained.execute(frame, self, other)); + HashingStorage otherStorage; + if (isSetProfile.profile(inliningTarget, other instanceof PBaseSet)) { + otherStorage = ((PBaseSet) other).getDictStorage(); + } else { + otherStorage = ((PDictView) other).getWrappedStorage(); + } + + int lenOther = otherLenNode.execute(inliningTarget, otherStorage); + if (lenCheckProfile.profile(inliningTarget, !op.compareResultToBool(lenSelf - lenOther))) { + return originalOp == RichCmpOp.Py_NE; + } + Object left = self; + Object right = other; + if (reverseProfile.profile(inliningTarget, reverse(op))) { + left = other; + right = self; + } + boolean result = allContained.execute(frame, left, right); + if (originalOp == RichCmpOp.Py_NE) { + result = !result; + } + return result; } @Fallback @SuppressWarnings("unused") - static PNotImplemented wrongTypes(Object self, Object other, ComparisonOp op) { + static PNotImplemented wrongTypes(Object self, Object other, RichCmpOp op) { return PNotImplemented.NOT_IMPLEMENTED; } } - @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class EqNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object doIt(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached DictViewRichcompareHelperNode helperNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.EQ); - } - } - - @Builtin(name = J___NE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class NeNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object notEqual(VirtualFrame frame, Object self, Object other, - @Cached EqNode eqNode) { - Object result = eqNode.execute(frame, self, other); - if (result == PNotImplemented.NOT_IMPLEMENTED) { - return result; - } else { - assert result instanceof Boolean; - return !((Boolean) result); - } - } - } - @Slot(value = SlotKind.nb_subtract, isComplex = true) @GenerateNodeFactory abstract static class SubNode extends BinaryOpBuiltinNode { @@ -441,18 +402,18 @@ abstract static class SubNode extends BinaryOpBuiltinNode { static PBaseSet doKeysView(VirtualFrame frame, PDictKeysView self, PBaseSet other, @Bind("this") Node inliningTarget, @Shared("diff") @Cached HashingStorageDiff diffNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { HashingStorage storage = diffNode.execute(frame, inliningTarget, self.getWrappedStorage(), other.getDictStorage()); - return factory.createSet(storage); + return PFactory.createSet(language, storage); } @Specialization static PBaseSet doKeysView(VirtualFrame frame, PDictKeysView self, PDictKeysView other, @Bind("this") Node inliningTarget, @Shared("diff") @Cached HashingStorageDiff diffNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { HashingStorage storage = diffNode.execute(frame, inliningTarget, self.getWrappedStorage(), other.getWrappedStorage()); - return factory.createSet(storage); + return PFactory.createSet(language, storage); } @Specialization @@ -460,11 +421,11 @@ static PBaseSet doKeysView(VirtualFrame frame, PDictKeysView self, Object other, @Bind("this") Node inliningTarget, @Shared("constrSet") @Cached SetNodes.ConstructSetNode constructSetNode, @Shared("diff") @Cached HashingStorageDiff diffNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { HashingStorage left = self.getWrappedStorage(); - HashingStorage right = constructSetNode.executeWith(frame, other).getDictStorage(); + HashingStorage right = constructSetNode.execute(frame, other).getDictStorage(); HashingStorage storage = diffNode.execute(frame, inliningTarget, left, right); - return factory.createSet(storage); + return PFactory.createSet(language, storage); } @Specialization @@ -472,10 +433,10 @@ static PBaseSet doItemsView(VirtualFrame frame, PDictItemsView self, PBaseSet ot @Bind("this") Node inliningTarget, @Shared("constrSet") @Cached SetNodes.ConstructSetNode constructSetNode, @Shared("diff") @Cached HashingStorageDiff diffNode, - @Shared @Cached PythonObjectFactory factory) { - PSet selfSet = constructSetNode.executeWith(frame, self); + @Bind PythonLanguage language) { + PSet selfSet = constructSetNode.execute(frame, self); HashingStorage storage = diffNode.execute(frame, inliningTarget, selfSet.getDictStorage(), other.getDictStorage()); - return factory.createSet(storage); + return PFactory.createSet(language, storage); } @Specialization @@ -483,11 +444,11 @@ static PBaseSet doGeneric(VirtualFrame frame, Object self, Object other, @Bind("this") Node inliningTarget, @Shared("constrSet") @Cached SetNodes.ConstructSetNode constructSetNode, @Shared("diff") @Cached HashingStorageDiff diffNode, - @Shared @Cached PythonObjectFactory factory) { - HashingStorage left = constructSetNode.executeWith(frame, self).getDictStorage(); - HashingStorage right = constructSetNode.executeWith(frame, other).getDictStorage(); + @Bind PythonLanguage language) { + HashingStorage left = constructSetNode.execute(frame, self).getDictStorage(); + HashingStorage right = constructSetNode.execute(frame, other).getDictStorage(); HashingStorage storage = diffNode.execute(frame, inliningTarget, left, right); - return factory.createSet(storage); + return PFactory.createSet(language, storage); } } @@ -509,7 +470,7 @@ static HashingStorage doSet(PBaseSet obj) { @Fallback static HashingStorage doOther(VirtualFrame frame, Object obj, @Cached SetNodes.ConstructSetNode constructSetNode) { - return constructSetNode.executeWith(frame, obj).getDictStorage(); + return constructSetNode.execute(frame, obj).getDictStorage(); } } @@ -533,7 +494,7 @@ static HashingStorage doSet(Node inliningTarget, PBaseSet obj, @Fallback static HashingStorage doOther(VirtualFrame frame, Object obj, @Cached SetNodes.ConstructSetNode constructSetNode) { - return constructSetNode.executeWith(frame, obj).getDictStorage(); + return constructSetNode.execute(frame, obj).getDictStorage(); } } @@ -546,10 +507,10 @@ static PBaseSet doGeneric(VirtualFrame frame, Object self, Object other, @Bind("this") Node inliningTarget, @Cached GetStorageForBinopNode getStorage, @Cached HashingStorageIntersect intersectNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { HashingStorage left = getStorage.execute(frame, inliningTarget, self); HashingStorage right = getStorage.execute(frame, inliningTarget, other); - return factory.createSet(intersectNode.execute(frame, inliningTarget, left, right)); + return PFactory.createSet(language, intersectNode.execute(frame, inliningTarget, left, right)); } } @@ -562,10 +523,10 @@ static PBaseSet doGeneric(VirtualFrame frame, Object self, Object other, @Bind("this") Node inliningTarget, @Cached GetCopiedStorageForBinopNode getStorage, @Cached HashingStorageAddAllToOther addAllToOther, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { HashingStorage left = getStorage.execute(frame, inliningTarget, self); HashingStorage right = getStorage.execute(frame, inliningTarget, other); - return factory.createSet(addAllToOther.execute(frame, inliningTarget, left, right)); + return PFactory.createSet(language, addAllToOther.execute(frame, inliningTarget, left, right)); } } @@ -578,58 +539,10 @@ static PBaseSet doGeneric(VirtualFrame frame, Object self, Object other, @Bind("this") Node inliningTarget, @Cached GetStorageForBinopNode getStorage, @Cached HashingStorageXor xor, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { HashingStorage left = getStorage.execute(frame, inliningTarget, self); HashingStorage right = getStorage.execute(frame, inliningTarget, other); - return factory.createSet(xor.execute(frame, inliningTarget, left, right)); - } - } - - @Builtin(name = J___LE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class LessEqualNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object doIt(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached DictViewRichcompareHelperNode helperNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.LE); - } - } - - @Builtin(name = J___GE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class GreaterEqualNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object doIt(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached DictViewRichcompareHelperNode helperNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.GE); - } - } - - @Builtin(name = J___LT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class LessThanNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object doIt(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached DictViewRichcompareHelperNode helperNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.LT); - } - } - - @Builtin(name = J___GT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class GreaterThanNode extends PythonBinaryBuiltinNode { - - @Specialization - static Object doIt(VirtualFrame frame, Object self, Object other, - @Bind("this") Node inliningTarget, - @Cached DictViewRichcompareHelperNode helperNode) { - return helperNode.execute(frame, inliningTarget, self, other, ComparisonOp.GT); + return PFactory.createSet(language, xor.execute(frame, inliningTarget, left, right)); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/PDict.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/PDict.java index bc23b74f72..b184f8ad4e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/PDict.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/PDict.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -117,7 +117,7 @@ static boolean hasHashEntries(@SuppressWarnings("unused") PDict self) { @ExportMessage static long getHashSize(PDict self, - @Bind("$node") Node inliningTarget, + @Bind Node inliningTarget, @Exclusive @Cached GilNode gil, @Cached HashingStorageLen lenNode) { boolean mustRelease = gil.acquire(); @@ -132,7 +132,7 @@ static long getHashSize(PDict self, @ExportMessage(name = "isHashEntryModifiable") @ExportMessage(name = "isHashEntryRemovable") static boolean isHashEntryReadable(PDict self, Object key, - @Bind("$node") Node inliningTarget, + @Bind Node inliningTarget, @Exclusive @Cached GilNode gil, @Shared("getItem") @Cached HashingStorageGetItem getItem, @Exclusive @Cached PForeignToPTypeNode convertNode) { @@ -146,7 +146,7 @@ static boolean isHashEntryReadable(PDict self, Object key, @ExportMessage static Object readHashValue(PDict self, Object key, - @Bind("$node") Node inliningTarget, + @Bind Node inliningTarget, @Exclusive @Cached GilNode gil, @Exclusive @Cached HashingStorageGetItem getItem, @Exclusive @Cached PForeignToPTypeNode convertNode) throws UnknownKeyException { @@ -166,7 +166,7 @@ static Object readHashValue(PDict self, Object key, @ExportMessage static boolean isHashEntryInsertable(PDict self, Object key, - @Bind("$node") Node inliningTarget, + @Bind Node inliningTarget, @Exclusive @Cached GilNode gil, @Cached PyObjectHashNode hashNode, @Exclusive @Cached HashingStorageGetItem getItem, @@ -213,7 +213,7 @@ static void writeHashEntry(PDict self, Object key, Object value, @ExportMessage static void removeHashEntry(PDict self, Object key, - @Bind("$node") Node inliningTarget, + @Bind Node inliningTarget, @Exclusive @Cached GilNode gil, @Cached HashingStorageDelItem delItem, @Exclusive @Cached PForeignToPTypeNode convertNode) throws UnknownKeyException { @@ -231,7 +231,7 @@ static void removeHashEntry(PDict self, Object key, @ExportMessage static Object getHashEntriesIterator(PDict self, - @Bind("$node") Node inliningTarget, + @Bind Node inliningTarget, @Exclusive @Cached GilNode gil, @Shared("getIter") @Cached PyObjectGetIter getIter, @Shared("callMethod") @Cached PyObjectCallMethodObjArgs callMethod) { @@ -246,7 +246,7 @@ static Object getHashEntriesIterator(PDict self, @ExportMessage static Object getHashKeysIterator(PDict self, - @Bind("$node") Node inliningTarget, + @Bind Node inliningTarget, @Exclusive @Cached GilNode gil, @Shared("getIter") @Cached PyObjectGetIter getIter, @Shared("callMethod") @Cached PyObjectCallMethodObjArgs callMethod) { @@ -261,7 +261,7 @@ static Object getHashKeysIterator(PDict self, @ExportMessage static Object getHashValuesIterator(PDict self, - @Bind("$node") Node inliningTarget, + @Bind Node inliningTarget, @Exclusive @Cached GilNode gil, @Shared("getIter") @Cached PyObjectGetIter getIter, @Shared("callMethod") @Cached PyObjectCallMethodObjArgs callMethod) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ellipsis/EllipsisBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ellipsis/EllipsisBuiltins.java index 334b32744c..0ebc937019 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ellipsis/EllipsisBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ellipsis/EllipsisBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,43 +41,53 @@ package com.oracle.graal.python.builtins.objects.ellipsis; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import java.util.List; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.strings.TruffleString; @CoreFunctions(extendClasses = PythonBuiltinClassType.PEllipsis) -@SuppressWarnings("unused") public final class EllipsisBuiltins extends PythonBuiltins { - private static final TruffleString T_ELLIPSIS = tsLiteral("Ellipsis"); + public static final TruffleString T_ELLIPSIS = tsLiteral("Ellipsis"); + + public static final TpSlots SLOTS = EllipsisBuiltinsSlotsGen.SLOTS; @Override protected List> getNodeFactories() { return EllipsisBuiltinsFactory.getFactories(); } - @Override - public void postInitialize(Python3Core core) { - super.postInitialize(core); - core.getBuiltins().setAttribute(T_ELLIPSIS, PEllipsis.INSTANCE); + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "ellipsis", minNumOfPositionalArgs = 1) + @GenerateNodeFactory + public abstract static class EllipsisTypeNode extends PythonBuiltinNode { + @SuppressWarnings("unused") + @Specialization + public static PEllipsis call(Object cls) { + return PEllipsis.INSTANCE; + } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory - abstract static class ReprNode extends PythonBuiltinNode { + abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization @SuppressWarnings("unused") static Object doit(PEllipsis self) { @@ -87,7 +97,7 @@ static Object doit(PEllipsis self) { @Builtin(name = J___REDUCE__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2) @GenerateNodeFactory - public abstract static class ReduceNode extends PythonBuiltinNode { + public abstract static class ReduceNode extends PythonBinaryBuiltinNode { @Specialization @SuppressWarnings("unused") Object doit(PEllipsis self, Object ignored) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/enumerate/EnumerateBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/enumerate/EnumerateBuiltins.java index 57f9e9dd34..0494dbb965 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/enumerate/EnumerateBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/enumerate/EnumerateBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2014, Regents of the University of California * * All rights reserved. @@ -25,26 +25,42 @@ */ package com.oracle.graal.python.builtins.objects.enumerate; +import static com.oracle.graal.python.nodes.BuiltinNames.J_ENUMERATE; +import static com.oracle.graal.python.nodes.PGuards.isInteger; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; +import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; +import com.oracle.graal.python.lib.PyObjectGetIter; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; @@ -54,29 +70,85 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PEnumerate) public final class EnumerateBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = EnumerateBuiltinsSlotsGen.SLOTS; @Override protected List> getNodeFactories() { return EnumerateBuiltinsFactory.getFactories(); } - @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1) + // enumerate(iterable, start=0) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = J_ENUMERATE, minNumOfPositionalArgs = 2, parameterNames = {"cls", "iterable", "start"}) @GenerateNodeFactory - public abstract static class NextNode extends PythonUnaryBuiltinNode { + public abstract static class EnumerateNode extends PythonBuiltinNode { + + @Specialization + static PEnumerate doNone(VirtualFrame frame, Object cls, Object iterable, @SuppressWarnings("unused") PNone keywordArg, + @Bind("this") Node inliningTarget, + @Shared("getIter") @Cached PyObjectGetIter getIter, + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) { + return PFactory.createEnumerate(language, cls, getInstanceShape.execute(cls), getIter.execute(frame, inliningTarget, iterable), 0); + } + + @Specialization + static PEnumerate doInt(VirtualFrame frame, Object cls, Object iterable, int start, + @Bind("this") Node inliningTarget, + @Shared("getIter") @Cached PyObjectGetIter getIter, + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) { + return PFactory.createEnumerate(language, cls, getInstanceShape.execute(cls), getIter.execute(frame, inliningTarget, iterable), start); + } + + @Specialization + static PEnumerate doLong(VirtualFrame frame, Object cls, Object iterable, long start, + @Bind("this") Node inliningTarget, + @Shared("getIter") @Cached PyObjectGetIter getIter, + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) { + return PFactory.createEnumerate(language, cls, getInstanceShape.execute(cls), getIter.execute(frame, inliningTarget, iterable), start); + } + + @Specialization + static PEnumerate doPInt(VirtualFrame frame, Object cls, Object iterable, PInt start, + @Bind("this") Node inliningTarget, + @Shared("getIter") @Cached PyObjectGetIter getIter, + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) { + return PFactory.createEnumerate(language, cls, getInstanceShape.execute(cls), getIter.execute(frame, inliningTarget, iterable), start); + } + + static boolean isIntegerIndex(Object idx) { + return isInteger(idx) || idx instanceof PInt; + } + + @Specialization(guards = "!isIntegerIndex(start)") + static void enumerate(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") Object iterable, Object start, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, start); + } + } + + @Slot(value = SlotKind.tp_iternext, isComplex = true) + @GenerateNodeFactory + public abstract static class NextNode extends TpIterNextBuiltin { @Specialization static Object doNext(VirtualFrame frame, PEnumerate self, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached InlinedConditionProfile bigIntIndexProfile, - @Cached GetNextNode next, - @Cached PythonObjectFactory factory) { - Object index = self.getAndIncrementIndex(inliningTarget, factory, bigIntIndexProfile); - Object nextValue = next.execute(frame, self.getDecoratedIterator()); - return factory.createTuple((new Object[]{index, nextValue})); + @Cached GetObjectSlotsNode getSlots, + @Cached CallSlotTpIterNextNode callIterNext) { + Object index = self.getAndIncrementIndex(inliningTarget, language, bigIntIndexProfile); + Object it = self.getDecoratedIterator(); + Object nextValue = callIterNext.execute(frame, inliningTarget, getSlots.execute(inliningTarget, it).tp_iternext(), it); + return PFactory.createTuple(language, (new Object[]{index, nextValue})); } } - @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iter, isComplex = true) @GenerateNodeFactory public abstract static class IterNode extends PythonUnaryBuiltinNode { @@ -92,13 +164,13 @@ public abstract static class ReduceNode extends PythonUnaryBuiltinNode { @Specialization static Object reduce(PEnumerate self, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached InlinedConditionProfile bigIntIndexProfile, - @Cached GetClassNode getClassNode, - @Cached PythonObjectFactory factory) { + @Cached GetClassNode getClassNode) { Object iterator = self.getDecoratedIterator(); Object index = self.getIndex(inliningTarget, bigIntIndexProfile); - PTuple contents = factory.createTuple(new Object[]{iterator, index}); - return factory.createTuple(new Object[]{getClassNode.execute(inliningTarget, self), contents}); + PTuple contents = PFactory.createTuple(language, new Object[]{iterator, index}); + return PFactory.createTuple(language, new Object[]{getClassNode.execute(inliningTarget, self), contents}); } } @@ -107,8 +179,8 @@ static Object reduce(PEnumerate self, public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode { @Specialization static Object classGetItem(Object cls, Object key, - @Cached PythonObjectFactory factory) { - return factory.createGenericAlias(cls, key); + @Bind PythonLanguage language) { + return PFactory.createGenericAlias(language, cls, key); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/enumerate/PEnumerate.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/enumerate/PEnumerate.java index 88d62ba68c..4cc18fb6e4 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/enumerate/PEnumerate.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/enumerate/PEnumerate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -25,9 +25,10 @@ */ package com.oracle.graal.python.builtins.objects.enumerate; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.profiles.InlinedConditionProfile; @@ -53,10 +54,10 @@ public Object getDecoratedIterator() { return iterator; } - public Object getAndIncrementIndex(Node inliningTarget, PythonObjectFactory factory, InlinedConditionProfile bigIntIndexProfile) { + public Object getAndIncrementIndex(Node inliningTarget, PythonLanguage language, InlinedConditionProfile bigIntIndexProfile) { if (bigIntIndexProfile.profile(inliningTarget, bigIndex != null)) { PInt idx = bigIndex; - bigIndex = factory.createInt(bigIndex.inc()); + bigIndex = PFactory.createInt(language, bigIndex.inc()); return idx; } return index++; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/AttributeErrorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/AttributeErrorBuiltins.java new file mode 100644 index 0000000000..bc25caa14e --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/AttributeErrorBuiltins.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.builtins.objects.exception; + +import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETSTATE__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; +import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; +import static com.oracle.graal.python.util.PythonUtils.tsLiteral; + +import java.util.List; + +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; +import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.builtins.CoreFunctions; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.common.EmptyStorage; +import com.oracle.graal.python.builtins.objects.common.HashingStorage; +import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes; +import com.oracle.graal.python.builtins.objects.dict.PDict; +import com.oracle.graal.python.builtins.objects.function.PKeyword; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; +import com.oracle.graal.python.nodes.object.BuiltinClassProfiles; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; +import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateNodeFactory; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NodeFactory; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; +import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile; +import com.oracle.truffle.api.strings.TruffleString; + +@CoreFunctions(extendClasses = PythonBuiltinClassType.AttributeError) +public final class AttributeErrorBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = AttributeErrorBuiltinsSlotsGen.SLOTS; + + @Override + protected List> getNodeFactories() { + return AttributeErrorBuiltinsFactory.getFactories(); + } + + private static final int IDX_NAME = 0; + private static final int IDX_OBJ = 1; + private static final int NUM_ATTRS = IDX_OBJ + 1; + + private static final TruffleString T_NAME = tsLiteral("name"); + private static final TruffleString T_OBJ = tsLiteral("obj"); + + private static final BaseExceptionAttrNode.StorageFactory ATTR_FACTORY = (args) -> new Object[NUM_ATTRS]; + + public static Object[] dataForObjKey(Object obj, Object key) { + return new Object[]{key, obj}; + } + + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + abstract static class InitNode extends PythonVarargsBuiltinNode { + + @Specialization + static Object init(PBaseException self, Object[] args, PKeyword[] kwargs, + @Bind Node inliningTarget, + @Cached BaseExceptionBuiltins.BaseExceptionInitNode baseExceptionInitNode, + @Cached TruffleString.EqualNode equalNameNode, + @Cached TruffleString.EqualNode equalObjNode, + @Cached InlinedLoopConditionProfile loopProfile, + @Cached PRaiseNode raiseNode) { + baseExceptionInitNode.execute(self, args); + Object[] attrs = new Object[NUM_ATTRS]; + loopProfile.profileCounted(inliningTarget, kwargs.length); + for (int i = 0; loopProfile.inject(inliningTarget, i < kwargs.length); i++) { + PKeyword kw = kwargs[i]; + TruffleString kwName = kw.getName(); + if (equalNameNode.execute(kwName, T_NAME, TS_ENCODING)) { + attrs[IDX_NAME] = kw.getValue(); + } else if (equalObjNode.execute(kwName, T_OBJ, TS_ENCODING)) { + attrs[IDX_OBJ] = kw.getValue(); + } else { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.S_IS_AN_INVALID_ARG_FOR_S, kw.getName(), "AttributeError"); + } + } + self.setExceptionAttributes(attrs); + return PNone.NONE; + } + } + + @Builtin(name = "name", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true, allowsDelete = true, doc = "attribute name") + @GenerateNodeFactory + public abstract static class NameNode extends PythonBinaryBuiltinNode { + @Specialization + static Object generic(PBaseException self, Object value, + @Cached BaseExceptionAttrNode attrNode) { + return attrNode.execute(self, value, IDX_NAME, ATTR_FACTORY); + } + } + + @Builtin(name = "obj", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true, allowsDelete = true, doc = "object") + @GenerateNodeFactory + public abstract static class ObjNode extends PythonBinaryBuiltinNode { + @Specialization + static Object generic(PBaseException self, Object value, + @Cached BaseExceptionAttrNode attrNode) { + return attrNode.execute(self, value, IDX_OBJ, ATTR_FACTORY); + } + } + + @Builtin(name = J___GETSTATE__, minNumOfPositionalArgs = 1) + @GenerateNodeFactory + public abstract static class GetStateNode extends PythonUnaryBuiltinNode { + + @Specialization + static Object get(PBaseException self, + @Bind("this") Node inliningTarget, + @Cached BaseExceptionAttrNode attrNode, + @Cached GetDictIfExistsNode getDictIfExistsNode, + @Cached HashingStorageNodes.HashingStorageSetItem setHashingStorageItem, + @Cached HashingStorageNodes.HashingStorageCopy copyStorageNode, + @Bind PythonLanguage language) { + PDict dict = getDictIfExistsNode.execute(self); + /* + * Note from CPython: We specifically are not pickling the obj attribute since there are + * many cases where it is unlikely to be picklable. + */ + Object name = attrNode.get(self, IDX_NAME, ATTR_FACTORY); + if (name != null) { + HashingStorage storage = (dict != null) ? copyStorageNode.execute(inliningTarget, dict.getDictStorage()) : EmptyStorage.INSTANCE; + storage = setHashingStorageItem.execute(inliningTarget, storage, T_NAME, name); + return PFactory.createDict(language, storage); + } else if (dict != null) { + return dict; + } else { + return PNone.NONE; + } + } + } + + @Builtin(name = J___REDUCE__, minNumOfPositionalArgs = 1) + @GenerateNodeFactory + public abstract static class ReduceNode extends PythonUnaryBuiltinNode { + + @Specialization + static Object reduce(VirtualFrame frame, PBaseException self, + @Bind("this") Node inliningTarget, + @Cached GetClassNode getClassNode, + @Cached ExceptionNodes.GetArgsNode getArgsNode, + @Cached GetStateNode getStateNode, + @Bind PythonLanguage language) { + Object clazz = getClassNode.execute(inliningTarget, self); + Object args = getArgsNode.execute(inliningTarget, self); + Object state = getStateNode.execute(frame, self); + return PFactory.createTuple(language, new Object[]{clazz, args, state}); + } + } + + @GenerateInline + @GenerateCached(false) + @GenerateUncached + public abstract static class SetAttributeErrorContext extends Node { + public abstract PException execute(Node inliningTarget, PException e, Object obj, Object name); + + @Specialization + static PException set(Node inliningTarget, PException e, Object obj, Object name, + @Cached BuiltinClassProfiles.IsBuiltinObjectProfile errorProfile, + @Cached BaseExceptionAttrNode attrNode, + @Cached InlinedConditionProfile writeAttrsProfile) { + e.expectAttributeError(inliningTarget, errorProfile); + if (writeAttrsProfile.profile(inliningTarget, e.getUnreifiedException() instanceof PBaseException exception && + exception.getExceptionAttributes() != null && + exception.getExceptionAttributes()[IDX_NAME] == null && exception.getExceptionAttributes()[IDX_OBJ] == null)) { + PBaseException exception = (PBaseException) e.getUnreifiedException(); + attrNode.set(exception, name, IDX_NAME, ATTR_FACTORY); + attrNode.set(exception, obj, IDX_OBJ, ATTR_FACTORY); + } + throw e; + } + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionAttrNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionAttrNode.java index 727aa9aa65..15bd3afcaa 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionAttrNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionAttrNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,7 +44,6 @@ import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -59,11 +58,7 @@ @SuppressWarnings("truffle-inlining") // footprint reduction 36 -> 20 public abstract class BaseExceptionAttrNode extends Node { public interface StorageFactory { - Object[] create(Object[] args, PythonObjectFactory factory); - - default Object[] create(Object[] args) { - return create(args, null); - } + Object[] create(Object[] args); default Object[] create() { return create(null); @@ -99,13 +94,12 @@ abstract static class EnsureAttrStorageNode extends Node { static Object[] ensure(PBaseException self, StorageFactory storageFactory, @Bind("this") Node inliningTarget, @Cached ExceptionNodes.GetArgsNode getArgsNode, - @Cached SequenceStorageNodes.GetInternalObjectArrayNode getInternalObjectArrayNode, - @Cached PythonObjectFactory factory) { + @Cached SequenceStorageNodes.GetInternalObjectArrayNode getInternalObjectArrayNode) { Object[] attributes = self.getExceptionAttributes(); if (attributes == null) { PTuple argsTuple = getArgsNode.execute(inliningTarget, self); Object[] args = getInternalObjectArrayNode.execute(inliningTarget, argsTuple.getSequenceStorage()); - attributes = storageFactory.create(args, factory); + attributes = storageFactory.create(args); self.setExceptionAttributes(attributes); } return attributes; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionBuiltins.java index aa6f045310..9171f0dd0d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2014, Regents of the University of California * * All rights reserved. @@ -35,11 +35,8 @@ import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___SUPPRESS_CONTEXT__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___TRACEBACK__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_PARENS; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; import static com.oracle.graal.python.nodes.StringLiterals.T_LPAREN; @@ -48,12 +45,20 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; +import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes; +import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol; +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions; import com.oracle.graal.python.builtins.objects.common.HashingStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageForEach; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageForEachCallback; @@ -67,6 +72,8 @@ import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.traceback.PTraceback; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyExceptionInstanceCheckNode; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.lib.PyObjectLookupAttr; @@ -91,11 +98,10 @@ import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaBooleanNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.nodes.util.SplitArgsNode; +import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.ValueType; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -111,39 +117,64 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleStringBuilder; @CoreFunctions(extendClasses = PythonBuiltinClassType.PBaseException) public final class BaseExceptionBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = BaseExceptionBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return BaseExceptionBuiltinsFactory.getFactories(); } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "BaseException", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @GenerateNodeFactory + public abstract static class BaseExceptionNode extends PythonVarargsBuiltinNode { + + @Specialization(guards = "!needsNativeAllocationNode.execute(inliningTarget, cls)", limit = "1") + static Object doManaged(Object cls, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") PKeyword[] kwargs, + @Bind("this") Node inliningTarget, + @SuppressWarnings("unused") @Cached.Exclusive @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached InlinedConditionProfile argsProfile) { + PTuple argsTuple; + if (argsProfile.profile(inliningTarget, args.length == 0)) { + argsTuple = null; + } else { + argsTuple = PFactory.createTuple(language, args); + } + return PFactory.createBaseException(language, cls, getInstanceShape.execute(cls), null, argsTuple); + } + + @Specialization(guards = "needsNativeAllocationNode.execute(inliningTarget, cls)", limit = "1") + static Object doNativeSubtype(Object cls, Object[] args, @SuppressWarnings("unused") PKeyword[] kwargs, + @SuppressWarnings("unused") @Bind("this") Node inliningTarget, + @SuppressWarnings("unused") @Cached.Exclusive @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, + @Bind PythonLanguage language, + @Cached CExtNodes.PCallCapiFunction callCapiFunction, + @Cached CApiTransitions.PythonToNativeNode toNativeNode, + @Cached CApiTransitions.NativeToPythonTransferNode toPythonNode, + @Cached ExternalFunctionNodes.DefaultCheckFunctionResultNode checkFunctionResultNode) { + Object argsTuple = args.length > 0 ? PFactory.createTuple(language, args) : PFactory.createEmptyTuple(language); + Object nativeResult = callCapiFunction.call(NativeCAPISymbol.FUN_EXCEPTION_SUBTYPE_NEW, toNativeNode.execute(cls), toNativeNode.execute(argsTuple)); + return toPythonNode.execute(checkFunctionResultNode.execute(PythonContext.get(inliningTarget), NativeCAPISymbol.FUN_EXCEPTION_SUBTYPE_NEW.getTsName(), nativeResult)); + } + } + + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory public abstract static class BaseExceptionInitNode extends PythonVarargsBuiltinNode { - @Child private SplitArgsNode splitArgsNode; public final Object execute(Object self, Object[] args) { return execute(null, self, args, PKeyword.EMPTY_KEYWORDS); } - @Override - public Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported { - if (arguments.length == 0) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw VarargsBuiltinDirectInvocationNotSupported.INSTANCE; - } - if (splitArgsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - splitArgsNode = insert(SplitArgsNode.create()); - } - Object[] argsWithoutSelf = splitArgsNode.executeCached(arguments); - return execute(frame, arguments[0], argsWithoutSelf, keywords); - } - @Specialization(guards = {"args.length == 0", "keywords.length == 0"}) static Object doNoArguments(PBaseException self, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") PKeyword[] keywords) { self.setArgs(null); @@ -151,35 +182,41 @@ static Object doNoArguments(PBaseException self, @SuppressWarnings("unused") Obj } @Specialization(guards = {"args.length != 0", "keywords.length == 0"}) - Object doWithArguments(PBaseException self, Object[] args, @SuppressWarnings("unused") PKeyword[] keywords) { - self.setArgs(factory().createTuple(args)); + Object doWithArguments(PBaseException self, Object[] args, @SuppressWarnings("unused") PKeyword[] keywords, + @Bind PythonLanguage language) { + self.setArgs(PFactory.createTuple(language, args)); return PNone.NONE; } @Specialization(replaces = {"doNoArguments", "doWithArguments"}) - Object doGeneric(PBaseException self, Object[] args, PKeyword[] keywords) { + static Object doGeneric(PBaseException self, Object[] args, PKeyword[] keywords, + @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { if (keywords.length != 0) { - throw raise(TypeError, P_TAKES_NO_KEYWORD_ARGS, self); + throw raiseNode.raise(inliningTarget, TypeError, P_TAKES_NO_KEYWORD_ARGS, self); } if (args.length == 0) { self.setArgs(null); } else { - self.setArgs(factory().createTuple(args)); + self.setArgs(PFactory.createTuple(language, args)); } return PNone.NONE; } @Specialization - Object doNative(PythonAbstractNativeObject self, Object[] args, PKeyword[] keywords, + static Object doNative(PythonAbstractNativeObject self, Object[] args, PKeyword[] keywords, @Bind("this") Node inliningTarget, - @Cached ExceptionNodes.SetArgsNode setArgsNode) { + @Cached ExceptionNodes.SetArgsNode setArgsNode, + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { if (keywords.length != 0) { - throw raise(TypeError, P_TAKES_NO_KEYWORD_ARGS, self); + throw raiseNode.raise(inliningTarget, TypeError, P_TAKES_NO_KEYWORD_ARGS, self); } if (args.length == 0) { - setArgsNode.execute(inliningTarget, self, factory().createEmptyTuple()); + setArgsNode.execute(inliningTarget, self, PFactory.createEmptyTuple(language)); } else { - setArgsNode.execute(inliningTarget, self, factory().createTuple(args)); + setArgsNode.execute(inliningTarget, self, PFactory.createTuple(language, args)); } return PNone.NONE; } @@ -202,9 +239,9 @@ static Object args(VirtualFrame frame, Object self, Object value, @Cached CastToListNode castToList, @Cached SequenceStorageNodes.CopyInternalArrayNode copy, @Cached ExceptionNodes.SetArgsNode setArgsNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { PList list = castToList.execute(frame, value); - setArgsNode.execute(inliningTarget, self, factory.createTuple(copy.execute(inliningTarget, list.getSequenceStorage()))); + setArgsNode.execute(inliningTarget, self, PFactory.createTuple(language, copy.execute(inliningTarget, list.getSequenceStorage()))); return PNone.NONE; } } @@ -238,10 +275,9 @@ public static Object setCause(Object self, @SuppressWarnings("unused") PNone val @Specialization(guards = {"!isNoValue(value)", "!check.execute(inliningTarget, value)"}) public static Object cause(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object value, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached PyExceptionInstanceCheckNode check, - @Cached PRaiseNode raise) { - throw raise.raise(TypeError, ErrorMessages.EXCEPTION_CAUSE_MUST_BE_NONE_OR_DERIVE_FROM_BASE_EX); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.EXCEPTION_CAUSE_MUST_BE_NONE_OR_DERIVE_FROM_BASE_EX); } } @@ -274,10 +310,9 @@ public static Object setContext(Object self, @SuppressWarnings("unused") PNone v @Specialization(guards = {"!isNoValue(value)", "!check.execute(inliningTarget, value)"}) public static Object context(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object value, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached PyExceptionInstanceCheckNode check, - @Cached PRaiseNode raise) { - throw raise.raise(TypeError, ErrorMessages.EXCEPTION_CONTEXT_MUST_BE_NONE_OR_DERIVE_FROM_BASE_EX); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.EXCEPTION_CONTEXT_MUST_BE_NONE_OR_DERIVE_FROM_BASE_EX); } } @@ -296,12 +331,12 @@ static Object setSuppressContext(Object self, Object valueObj, @Bind("this") Node inliningTarget, @Cached ExceptionNodes.SetSuppressContextNode setSuppressContextNode, @Cached CastToJavaBooleanNode castToJavaBooleanNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { boolean value; try { value = castToJavaBooleanNode.execute(inliningTarget, valueObj); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ATTR_VALUE_MUST_BE_BOOL); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ATTR_VALUE_MUST_BE_BOOL); } setSuppressContextNode.execute(inliningTarget, self, value); return PNone.NONE; @@ -337,8 +372,8 @@ static Object setTraceback(Object self, PTraceback tb, @Fallback static Object setTraceback(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object tb, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.MUST_BE_S_OR_S, "__traceback__", "a traceback", "None"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.MUST_BE_S_OR_S, "__traceback__", "a traceback", "None"); } } @@ -383,8 +418,8 @@ static Object dict(Object self, @SuppressWarnings("unused") PNone mapping, @Specialization(guards = {"!isNoValue(mapping)", "!isDict(mapping)"}) static PNone dict(@SuppressWarnings("unused") Object self, Object mapping, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, mapping); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, mapping); } } @@ -397,15 +432,15 @@ static Object reduce(VirtualFrame frame, Object self, @Cached GetClassNode getClassNode, @Cached ExceptionNodes.GetArgsNode argsNode, @Cached DictNode dictNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { Object clazz = getClassNode.execute(inliningTarget, self); PTuple args = argsNode.execute(inliningTarget, self); Object dict = dictNode.execute(frame, self, PNone.NO_VALUE); - return factory.createTuple(new Object[]{clazz, args, dict}); + return PFactory.createTuple(language, new Object[]{clazz, args, dict}); } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory public abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization @@ -443,7 +478,7 @@ Object repr(VirtualFrame frame, Object self, } } - @Builtin(name = J___STR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_str, isComplex = true) @GenerateNodeFactory public abstract static class StrNode extends PythonUnaryBuiltinNode { @Specialization @@ -518,9 +553,9 @@ static Object setDict(VirtualFrame frame, Object self, PDict state, @Specialization(guards = "!isDict(state)") static Object generic(@SuppressWarnings("unused") Object self, Object state, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (state != PNone.NONE) { - throw raiseNode.get(inliningTarget).raise(TypeError, STATE_IS_NOT_A_DICT); + throw raiseNode.raise(inliningTarget, TypeError, STATE_IS_NOT_A_DICT); } return PNone.NONE; } @@ -536,20 +571,20 @@ Object addNote(VirtualFrame frame, Object self, Object note, @Cached PyObjectLookupAttr lookupAttr, @Cached PyObjectSetAttr setAttr, @Cached ListNodes.AppendNode appendNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { if (!unicodeCheckNode.execute(inliningTarget, note)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.NOTE_MUST_BE_A_STR_NOT_P, note); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.NOTE_MUST_BE_A_STR_NOT_P, note); } Object notes = lookupAttr.execute(frame, inliningTarget, self, T___NOTES__); if (notes == PNone.NO_VALUE) { - notes = factory.createList(); + notes = PFactory.createList(language); setAttr.execute(frame, inliningTarget, self, T___NOTES__, notes); } if (notes instanceof PList notesList) { appendNode.execute(notesList, note); } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANNOT_ADD_NOTE_NOTES_IS_NOT_A_LIST); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANNOT_ADD_NOTE_NOTES_IS_NOT_A_LIST); } return PNone.NONE; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionGroupBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionGroupBuiltins.java index 6f59828fca..900f56d397 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionGroupBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionGroupBuiltins.java @@ -46,8 +46,8 @@ import static com.oracle.graal.python.nodes.BuiltinNames.T___NOTES__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___MODULE__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; +import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; @@ -55,6 +55,9 @@ import java.util.List; import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -69,9 +72,11 @@ import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.traceback.PTraceback; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyErrExceptionMatchesNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; +import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectSetAttr; @@ -80,16 +85,20 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.builtins.ListNodes; +import com.oracle.graal.python.nodes.builtins.TupleNodes; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.nodes.util.CannotCastException; +import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -99,11 +108,15 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile; import com.oracle.truffle.api.strings.TruffleString; import com.oracle.truffle.api.strings.TruffleStringBuilder; @CoreFunctions(extendClasses = PythonBuiltinClassType.PBaseExceptionGroup) public class BaseExceptionGroupBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = BaseExceptionGroupBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return BaseExceptionGroupBuiltinsFactory.getFactories(); @@ -116,17 +129,89 @@ public void postInitialize(Python3Core core) { private static void createExceptionGroupType(Python3Core core) { PythonModule builtins = core.getBuiltins(); + PythonLanguage language = core.getLanguage(); Object typeBuiltin = builtins.getAttribute(T_TYPE); - PythonObjectSlowPathFactory factory = core.factory(); - PTuple bases = factory.createTuple(new Object[]{PythonBuiltinClassType.PBaseExceptionGroup, PythonBuiltinClassType.Exception}); + PTuple bases = PFactory.createTuple(language, new Object[]{PythonBuiltinClassType.PBaseExceptionGroup, PythonBuiltinClassType.Exception}); EconomicMapStorage dictStorage = EconomicMapStorage.create(1); - dictStorage.putUncachedWithJavaEq(T___MODULE__, T_BUILTINS); - PDict dict = factory.createDict(dictStorage); + dictStorage.putUncached(T___MODULE__, T_BUILTINS); + PDict dict = PFactory.createDict(language, dictStorage); Object exceptionGroupType = CallNode.executeUncached(typeBuiltin, T_EXCEPTION_GROUP, bases, dict); builtins.setAttribute(T_EXCEPTION_GROUP, exceptionGroupType); } - @Builtin(name = J___STR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "BaseExceptionGroup.__new__", minNumOfPositionalArgs = 3) + @GenerateNodeFactory + public abstract static class BaseExceptionGroupNode extends PythonTernaryBuiltinNode { + + @Specialization + static Object doManaged(VirtualFrame frame, Object cls, Object messageObj, Object exceptionsObj, + @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached CastToTruffleStringNode castToStringNode, + @Cached PySequenceCheckNode sequenceCheckNode, + @Cached TupleNodes.ConstructTupleNode toTupleNode, + @Cached SequenceStorageNodes.ToArrayNode toArrayNode, + @Cached PyObjectGetAttr getAttr, + @Cached InlinedLoopConditionProfile loopConditionProfile, + @Cached GetClassNode getClassNode, + @Cached BuiltinClassProfiles.IsBuiltinClassProfile exceptionProfile, + @Cached BuiltinClassProfiles.IsBuiltinClassProfile baseExceptionProfile, + @Cached TypeNodes.IsSameTypeNode isSameTypeNode, + @Cached PRaiseNode raiseNode) { + TruffleString message; + try { + message = castToStringNode.execute(inliningTarget, messageObj); + } catch (CannotCastException ex) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "BaseExceptionGroup", 1, "str", messageObj); + } + if (!sequenceCheckNode.execute(inliningTarget, exceptionsObj)) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.SECOND_ARGUMENT_EXCEPTIONS_MUST_BE_A_SEQUENCE); + } + PTuple exceptionsTuple = toTupleNode.execute(frame, exceptionsObj); + Object[] exceptions = toArrayNode.execute(inliningTarget, exceptionsTuple.getSequenceStorage()); + if (exceptions.length == 0) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.SECOND_ARGUMENT_EXCEPTIONS_MUST_BE_A_NON_EMPTY_SEQUENCE); + } + PythonContext context = PythonContext.get(inliningTarget); + Object exceptionGroupType = getAttr.execute(inliningTarget, context.getBuiltins(), T_EXCEPTION_GROUP); + boolean nestedBaseExceptions = false; + loopConditionProfile.profileCounted(inliningTarget, exceptions.length); + for (int i = 0; loopConditionProfile.inject(inliningTarget, i < exceptions.length); i++) { + Object exceptionType = getClassNode.execute(inliningTarget, exceptions[i]); + if (exceptionProfile.profileClass(inliningTarget, exceptionType, PythonBuiltinClassType.Exception)) { + continue; + } + if (baseExceptionProfile.profileClass(inliningTarget, exceptionType, PythonBuiltinClassType.PBaseException)) { + nestedBaseExceptions = true; + } else { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.ITEM_D_OF_SECOND_ARGUMENT_EXCEPTIONS_IS_NOT_AN_EXCEPTION, i); + } + } + if (isSameTypeNode.execute(inliningTarget, cls, PythonBuiltinClassType.PBaseExceptionGroup)) { + if (!nestedBaseExceptions) { + /* + * All nested exceptions are Exception subclasses, wrap them in an + * ExceptionGroup + */ + cls = exceptionGroupType; + } + } else if (isSameTypeNode.execute(inliningTarget, cls, exceptionGroupType)) { + if (nestedBaseExceptions) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANNOT_NEST_BASE_EXCEPTIONS_IN_AN_EXCEPTION_GROUP); + } + } else { + /* user-defined subclass */ + if (nestedBaseExceptions && exceptionProfile.profileClass(inliningTarget, cls, PythonBuiltinClassType.Exception)) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANNOT_NEST_BASE_EXCEPTIONS_IN_N, cls); + } + } + return PFactory.createBaseExceptionGroup(language, cls, getInstanceShape.execute(cls), message, exceptions, new Object[]{messageObj, exceptionsObj}); + } + } + + @Slot(value = SlotKind.tp_str, isComplex = true) @GenerateNodeFactory abstract static class StrNode extends PythonUnaryBuiltinNode { @@ -166,8 +251,8 @@ static TruffleString message(PBaseExceptionGroup self) { abstract static class ExceptionsNode extends PythonUnaryBuiltinNode { @Specialization static Object exceptions(PBaseExceptionGroup self, - @Cached PythonObjectFactory factory) { - return factory.createTuple(self.getExceptions()); + @Bind PythonLanguage language) { + return PFactory.createTuple(language, self.getExceptions()); } } @@ -188,10 +273,9 @@ private static PBaseExceptionGroup subset(Node inliningTarget, PBaseExceptionGro if (exceptions.length == 0) { return null; } - PythonObjectSlowPathFactory factory = PythonContext.get(inliningTarget).factory(); - Object egObj = PyObjectCallMethodObjArgs.executeUncached(orig, T_DERIVE, factory.createTuple(exceptions)); + Object egObj = PyObjectCallMethodObjArgs.executeUncached(orig, T_DERIVE, PFactory.createTuple(PythonLanguage.get(null), exceptions)); if (!(egObj instanceof PBaseExceptionGroup eg)) { - throw PRaiseNode.raiseUncached(inliningTarget, TypeError, ErrorMessages.DERIVE_MUST_RETURN_AN_INSTANCE_OF_BASE_EXCEPTION_GROUP); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DERIVE_MUST_RETURN_AN_INSTANCE_OF_BASE_EXCEPTION_GROUP); } Object tb = ExceptionNodes.GetTracebackNode.executeUncached(orig); if (tb instanceof PTraceback) { @@ -232,12 +316,12 @@ private static MatcherType getMatcherType(Node inliningTarget, Object value) { for (int i = 0; i < storage.length(); i++) { Object elem = SequenceStorageNodes.GetItemScalarNode.executeUncached(storage, i); if (!isExceptionTypeUncached(elem)) { - throw PRaiseNode.raiseUncached(inliningTarget, TypeError, ErrorMessages.EXPECTED_A_FUNCTION_EXCEPTION_TYPE_OR_TUPLE_OF_EXCEPTION_TYPES); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.EXPECTED_A_FUNCTION_EXCEPTION_TYPE_OR_TUPLE_OF_EXCEPTION_TYPES); } } return MatcherType.BY_TYPE; } - throw PRaiseNode.raiseUncached(inliningTarget, TypeError, ErrorMessages.EXPECTED_A_FUNCTION_EXCEPTION_TYPE_OR_TUPLE_OF_EXCEPTION_TYPES); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.EXPECTED_A_FUNCTION_EXCEPTION_TYPE_OR_TUPLE_OF_EXCEPTION_TYPES); } private static boolean isExceptionTypeUncached(Object value) { @@ -257,7 +341,7 @@ private static boolean splitCheckMatch(Object exception, MatcherType matcherType private record SplitResult(Object match, Object rest) { static final SplitResult EMPTY = new SplitResult(null, null); - }; + } @TruffleBoundary private static SplitResult splitRecursive(Node inliningTarget, Object exception, MatcherType matcherType, Object matcherValue, boolean constructRest) { @@ -310,8 +394,7 @@ abstract static class SplitNode extends PythonBinaryBuiltinNode { @Specialization static Object split(VirtualFrame frame, PBaseExceptionGroup self, Object matcherValue, @Bind("this") Node inliningTarget, - @Cached("createFor(this)") IndirectCallData indirectCallData, - @Cached PythonObjectFactory factory) { + @Cached("createFor(this)") IndirectCallData indirectCallData) { PythonContext context = PythonContext.get(inliningTarget); PythonLanguage language = context.getLanguage(inliningTarget); Object state = IndirectCallContext.enter(frame, language, context, indirectCallData); @@ -327,7 +410,7 @@ static Object split(VirtualFrame frame, PBaseExceptionGroup self, Object matcher } Object match = result.match != null ? result.match : PNone.NONE; Object rest = result.rest != null ? result.rest : PNone.NONE; - return factory.createTuple(new Object[]{match, rest}); + return PFactory.createTuple(language, new Object[]{match, rest}); } } @@ -360,8 +443,8 @@ static Object subgroup(VirtualFrame frame, PBaseExceptionGroup self, Object matc abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode { @Specialization static Object classGetItem(Object cls, Object key, - @Cached PythonObjectFactory factory) { - return factory.createGenericAlias(cls, key); + @Bind PythonLanguage language) { + return PFactory.createGenericAlias(language, cls, key); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/ExceptionNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/ExceptionNodes.java index 263294cf73..7765db96c0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/ExceptionNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/ExceptionNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,6 +47,7 @@ import java.util.IllegalFormatException; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; import com.oracle.graal.python.builtins.objects.cext.structs.CFields; @@ -62,11 +63,11 @@ import com.oracle.graal.python.nodes.object.IsForeignObjectNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.formatting.ErrorMessageFormatter; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; @@ -156,7 +157,7 @@ static void doNative(Node inliningTarget, PythonAbstractNativeObject exception, @Specialization @SuppressWarnings("unused") static void doInterop(Node inliningTarget, AbstractTruffleException exception, Object value) { - throw PRaiseNode.raiseUncached(inliningTarget, TypeError, ErrorMessages.CANNOT_SET_PROPERTY_ON_INTEROP_EXCEPTION); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CANNOT_SET_PROPERTY_ON_INTEROP_EXCEPTION); } } @@ -220,7 +221,7 @@ static void doNative(Node inliningTarget, PythonAbstractNativeObject exception, @Specialization @SuppressWarnings("unused") static void doInterop(Node inliningTarget, AbstractTruffleException exception, Object value) { - throw PRaiseNode.raiseUncached(inliningTarget, TypeError, ErrorMessages.CANNOT_SET_PROPERTY_ON_INTEROP_EXCEPTION); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CANNOT_SET_PROPERTY_ON_INTEROP_EXCEPTION); } } @@ -279,7 +280,7 @@ static void doNative(@SuppressWarnings("unused") Node inliningTarget, PythonAbst @Specialization @SuppressWarnings("unused") static void doInterop(Node inliningTarget, AbstractTruffleException exception, boolean value) { - throw PRaiseNode.raiseUncached(inliningTarget, TypeError, ErrorMessages.CANNOT_SET_PROPERTY_ON_INTEROP_EXCEPTION); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CANNOT_SET_PROPERTY_ON_INTEROP_EXCEPTION); } } @@ -351,7 +352,7 @@ static void doNative(Node inliningTarget, PythonAbstractNativeObject exception, @Specialization @SuppressWarnings("unused") static void doInterop(Node inliningTarget, AbstractTruffleException exception, Object value) { - throw PRaiseNode.raiseUncached(inliningTarget, TypeError, ErrorMessages.CANNOT_SET_PROPERTY_ON_INTEROP_EXCEPTION); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CANNOT_SET_PROPERTY_ON_INTEROP_EXCEPTION); } } @@ -382,17 +383,17 @@ private static String getFormattedMessage(TruffleString format, Object... args) @Specialization static PTuple doManaged(Node inliningTarget, PBaseException self, - @Shared @Cached(inline = false) PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached InlinedConditionProfile nullArgsProfile, @Cached InlinedConditionProfile hasMessageFormat, @Cached(inline = false) TruffleString.FromJavaStringNode fromJavaStringNode) { PTuple args = self.getArgs(); if (nullArgsProfile.profile(inliningTarget, args == null)) { if (hasMessageFormat.profile(inliningTarget, !self.hasMessageFormat())) { - args = factory.createEmptyTuple(); + args = PFactory.createEmptyTuple(language); } else { // lazily format the exception message: - args = factory.createTuple(new Object[]{fromJavaStringNode.execute(getFormattedMessage(self.getMessageFormat(), self.getMessageArgs()), TS_ENCODING)}); + args = PFactory.createTuple(language, new Object[]{fromJavaStringNode.execute(getFormattedMessage(self.getMessageFormat(), self.getMessageArgs()), TS_ENCODING)}); } self.setArgs(args); } @@ -408,7 +409,7 @@ static PTuple doNative(@SuppressWarnings("unused") Node inliningTarget, PythonAb @Specialization static PTuple doInterop(AbstractTruffleException exception, - @Shared @Cached(inline = false) PythonObjectFactory factory, + @Bind PythonLanguage language, @CachedLibrary(limit = "getCallSiteInlineCacheMaxDepth()") InteropLibrary interop, @Cached(inline = false) TruffleString.SwitchEncodingNode switchEncodingNode) { assert IsForeignObjectNode.executeUncached(exception); @@ -422,9 +423,9 @@ static PTuple doInterop(AbstractTruffleException exception, } if (interop.hasMetaObject(exception)) { - return factory.createTuple(new Object[]{concat(getMetaObjectName(exception), message)}); + return PFactory.createTuple(language, new Object[]{concat(getMetaObjectName(exception), message)}); } else { - return factory.createTuple(new Object[]{message}); + return PFactory.createTuple(language, new Object[]{message}); } } catch (UnsupportedMessageException e) { throw CompilerDirectives.shouldNotReachHere(e); @@ -478,7 +479,7 @@ static void doNative(@SuppressWarnings("unused") Node inliningTarget, PythonAbst @Specialization @SuppressWarnings("unused") static void doInterop(Node inliningTarget, AbstractTruffleException exception, PTuple argsTuple) { - throw PRaiseNode.raiseUncached(inliningTarget, TypeError, ErrorMessages.CANNOT_SET_PROPERTY_ON_INTEROP_EXCEPTION); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CANNOT_SET_PROPERTY_ON_INTEROP_EXCEPTION); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/ImportErrorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/ImportErrorBuiltins.java index f3a69f4d82..03b25d2da6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/ImportErrorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/ImportErrorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,9 +41,7 @@ package com.oracle.graal.python.builtins.objects.exception; import static com.oracle.graal.python.nodes.ErrorMessages.S_IS_AN_INVALID_ARG_FOR_S; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__; import static com.oracle.graal.python.nodes.StringLiterals.T_NAME; import static com.oracle.graal.python.nodes.StringLiterals.T_PATH; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; @@ -51,6 +49,10 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -62,16 +64,16 @@ import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.function.PKeyword; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.lib.PyUnicodeCheckExactNode; +import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; -import com.oracle.graal.python.nodes.util.SplitArgsNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -84,6 +86,8 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.ImportError) public final class ImportErrorBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = ImportErrorBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return ImportErrorBuiltinsFactory.getFactories(); @@ -94,7 +98,7 @@ protected List> getNodeFa protected static final int IDX_PATH = 2; public static final int IMPORT_ERR_NUM_ATTRS = IDX_PATH + 1; - public static final BaseExceptionAttrNode.StorageFactory IMPORT_ERROR_ATTR_FACTORY = (args, factory) -> { + public static final BaseExceptionAttrNode.StorageFactory IMPORT_ERROR_ATTR_FACTORY = (args) -> { Object[] attrs = new Object[IMPORT_ERR_NUM_ATTRS]; if (args.length == 1) { attrs[IDX_MSG] = args[0]; @@ -108,35 +112,21 @@ protected List> getNodeFa * 'takesVarArgs = true' and ' takesVarKeywordArgs = true' because otherwise the created root * node would fail. */ - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, // - takesVarArgs = true, varArgsMarker = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory public abstract static class ImportErrorInitNode extends PythonVarargsBuiltinNode { private static final TruffleString NAME = tsLiteral("name"); private static final TruffleString PATH = tsLiteral("path"); - @Child private SplitArgsNode splitArgsNode; - - @Override - public Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported { - if (arguments.length == 0) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw VarargsBuiltinDirectInvocationNotSupported.INSTANCE; - } - if (splitArgsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - splitArgsNode = insert(SplitArgsNode.create()); - } - Object[] argsWithoutSelf = splitArgsNode.executeCached(arguments); - return execute(frame, arguments[0], argsWithoutSelf, keywords); - } - @Specialization - Object init(PBaseException self, Object[] args, PKeyword[] kwargs, + static Object init(PBaseException self, Object[] args, PKeyword[] kwargs, + @Bind("this") Node inliningTarget, @Cached BaseExceptionBuiltins.BaseExceptionInitNode baseExceptionInitNode, - @Cached TruffleString.EqualNode equalNode) { + @Cached TruffleString.EqualNode equalNode, + @Cached PRaiseNode raiseNode) { baseExceptionInitNode.execute(self, args); - Object[] attrs = IMPORT_ERROR_ATTR_FACTORY.create(args, null); + Object[] attrs = IMPORT_ERROR_ATTR_FACTORY.create(args); for (PKeyword kw : kwargs) { TruffleString kwName = kw.getName(); if (equalNode.execute(kwName, NAME, TS_ENCODING)) { @@ -144,7 +134,7 @@ Object init(PBaseException self, Object[] args, PKeyword[] kwargs, } else if (equalNode.execute(kwName, PATH, TS_ENCODING)) { attrs[IDX_PATH] = kw.getValue(); } else { - throw raise(PythonBuiltinClassType.TypeError, S_IS_AN_INVALID_ARG_FOR_S, kw.getName(), "ImportError"); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, S_IS_AN_INVALID_ARG_FOR_S, kw.getName(), "ImportError"); } } self.setExceptionAttributes(attrs); @@ -186,7 +176,7 @@ Object generic(PBaseException self, Object value, @GenerateNodeFactory public abstract static class ImportErrorReduceNode extends PythonUnaryBuiltinNode { private static Object getState(Node inliningTarget, PBaseException self, GetDictIfExistsNode getDictIfExistsNode, HashingStorageSetItem setHashingStorageItem, - HashingStorageCopy copyStorageNode, BaseExceptionAttrNode attrNode, PythonObjectFactory factory) { + HashingStorageCopy copyStorageNode, BaseExceptionAttrNode attrNode, PythonLanguage language) { PDict dict = getDictIfExistsNode.execute(self); final Object name = attrNode.get(self, IDX_NAME, IMPORT_ERROR_ATTR_FACTORY); final Object path = attrNode.get(self, IDX_PATH, IMPORT_ERROR_ATTR_FACTORY); @@ -198,7 +188,7 @@ private static Object getState(Node inliningTarget, PBaseException self, GetDict if (path != null) { storage = setHashingStorageItem.execute(inliningTarget, storage, T_PATH, path); } - return factory.createDict(storage); + return PFactory.createDict(language, storage); } else if (dict != null) { return dict; } else { @@ -215,18 +205,18 @@ static Object reduce(PBaseException self, @Cached ExceptionNodes.GetArgsNode getArgsNode, @Cached HashingStorageSetItem setHashingStorageItem, @Cached HashingStorageCopy copyStorageNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { Object clazz = getClassNode.execute(inliningTarget, self); Object args = getArgsNode.execute(inliningTarget, self); - Object state = getState(inliningTarget, self, getDictIfExistsNode, setHashingStorageItem, copyStorageNode, attrNode, factory); + Object state = getState(inliningTarget, self, getDictIfExistsNode, setHashingStorageItem, copyStorageNode, attrNode, language); if (state == PNone.NONE) { - return factory.createTuple(new Object[]{clazz, args}); + return PFactory.createTuple(language, new Object[]{clazz, args}); } - return factory.createTuple(new Object[]{clazz, args, state}); + return PFactory.createTuple(language, new Object[]{clazz, args, state}); } } - @Builtin(name = J___STR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_str, isComplex = true) @GenerateNodeFactory public abstract static class ImportErrorStrNode extends PythonUnaryBuiltinNode { @Specialization diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/KeyErrorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/KeyErrorBuiltins.java index 7ac6e20448..0075902b70 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/KeyErrorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/KeyErrorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,16 +40,16 @@ */ package com.oracle.graal.python.builtins.objects.exception; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__; - import java.util.List; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; @@ -65,12 +65,14 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.KeyError) public final class KeyErrorBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = KeyErrorBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return KeyErrorBuiltinsFactory.getFactories(); } - @Builtin(name = J___STR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_str, isComplex = true) @GenerateNodeFactory abstract static class KeyErrorStrNode extends PythonUnaryBuiltinNode { @Specialization diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/OsErrorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/OsErrorBuiltins.java index ba106fac08..57a3b285d3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/OsErrorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/OsErrorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -52,16 +52,15 @@ import static com.oracle.graal.python.builtins.objects.exception.OSErrorEnum.ESRCH; import static com.oracle.graal.python.builtins.objects.exception.OSErrorEnum.ETIMEDOUT; import static com.oracle.graal.python.nodes.ErrorMessages.P_TAKES_NO_KEYWORD_ARGS; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEW__; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.Python3Core; @@ -75,11 +74,12 @@ import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyArgCheckPositionalNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyNumberCheckNode; -import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode; import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode; import com.oracle.graal.python.nodes.ErrorMessages; @@ -88,10 +88,10 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.nodes.object.BuiltinClassProfiles; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.dsl.Bind; @@ -117,12 +117,14 @@ public final class OsErrorBuiltins extends PythonBuiltins { public static final int IDX_WRITTEN = 5; public static final int OS_ERR_NUM_ATTRS = IDX_WRITTEN + 1; - public static final BaseExceptionAttrNode.StorageFactory OS_ERROR_ATTR_FACTORY = (args, factory) -> { + public static final BaseExceptionAttrNode.StorageFactory OS_ERROR_ATTR_FACTORY = (args) -> { final Object[] attrs = new Object[OS_ERR_NUM_ATTRS]; attrs[IDX_WRITTEN] = -1; return attrs; }; + public static final TpSlots SLOTS = OsErrorBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return OsErrorBuiltinsFactory.getFactories(); @@ -135,7 +137,7 @@ public void postInitialize(Python3Core core) { core.registerTypeInBuiltins(tsLiteral("IOError"), PythonBuiltinClassType.OSError); } - static boolean osErrorUseInit(VirtualFrame frame, Node inliningTarget, Python3Core core, Object type, PyObjectGetAttr getAttr) { + static boolean osErrorUseInit(Node inliningTarget, Object type, GetCachedTpSlotsNode getSlots) { // When __init__ is defined in an OSError subclass, we want any extraneous argument // to __new__ to be ignored. The only reasonable solution, given __new__ takes a // variable number of arguments, is to defer arg parsing and initialization to __init__. @@ -143,12 +145,8 @@ static boolean osErrorUseInit(VirtualFrame frame, Node inliningTarget, Python3Co // arguments. // // (see http://bugs.python.org/issue12555#msg148829 ) - final PythonBuiltinClass osErrorType = core.lookupType(PythonBuiltinClassType.OSError); - final Object tpInit = getAttr.execute(frame, inliningTarget, type, T___INIT__); - final Object tpNew = getAttr.execute(frame, inliningTarget, type, T___NEW__); - final Object osErrInit = getAttr.execute(frame, inliningTarget, osErrorType, T___INIT__); - final Object osErrNew = getAttr.execute(frame, inliningTarget, osErrorType, T___NEW__); - return tpInit != osErrInit && tpNew == osErrNew; + TpSlots slots = getSlots.execute(inliningTarget, type); + return slots.tp_init() != SLOTS.tp_init() && slots.tp_new() == SLOTS.tp_new(); } static PythonBuiltinClassType errno2errorType(int errno) { @@ -262,31 +260,33 @@ static Object[] osErrorParseArgs(Object[] args, Node inliningTarget, PyArgCheckP return parsed; } - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory protected abstract static class OSErrorNewNode extends PythonBuiltinNode { @Specialization static Object newCData(VirtualFrame frame, Object subType, Object[] args, PKeyword[] kwds, @Bind("this") Node inliningTarget, - @Cached PyObjectGetAttr getAttr, + @Cached GetCachedTpSlotsNode getSlots, @Cached PyNumberCheckNode pyNumberCheckNode, @Cached PyNumberAsSizeNode pyNumberAsSizeNode, + @Cached BuiltinClassProfiles.IsBuiltinClassExactProfile isOSErrorExact, @Cached PyArgCheckPositionalNode checkPositionalNode, @Cached BaseExceptionBuiltins.BaseExceptionInitNode baseInitNode, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached PRaiseNode raiseNode) { Object type = subType; Object[] parsedArgs = new Object[IDX_WRITTEN + 1]; - final Python3Core core = PythonContext.get(inliningTarget); - if (!osErrorUseInit(frame, inliningTarget, core, type, getAttr)) { + if (!osErrorUseInit(inliningTarget, type, getSlots)) { if (kwds.length != 0) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, P_TAKES_NO_KEYWORD_ARGS, type); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, P_TAKES_NO_KEYWORD_ARGS, type); } parsedArgs = osErrorParseArgs(args, inliningTarget, checkPositionalNode); final Object errnoVal = parsedArgs[IDX_ERRNO]; if (errnoVal != null && PGuards.canBeInteger(errnoVal) && - subType == PythonBuiltinClassType.OSError) { + isOSErrorExact.profileClass(inliningTarget, subType, PythonBuiltinClassType.OSError)) { final int errno = pyNumberAsSizeNode.executeExact(frame, inliningTarget, errnoVal); Object newType = errno2errorType(errno); if (newType != null) { @@ -295,17 +295,18 @@ static Object newCData(VirtualFrame frame, Object subType, Object[] args, PKeywo } } - PBaseException self = factory.createBaseException(type); - if (!osErrorUseInit(frame, inliningTarget, core, type, getAttr)) { + PBaseException self = PFactory.createBaseException(language, type, getInstanceShape.execute(type)); + if (!osErrorUseInit(inliningTarget, type, getSlots)) { osErrorInit(frame, inliningTarget, self, type, args, parsedArgs, pyNumberCheckNode, pyNumberAsSizeNode, baseInitNode); } else { - self.setArgs(factory.createEmptyTuple()); + self.setArgs(PFactory.createEmptyTuple(language)); } return self; } } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory public abstract static class OSErrorInitNode extends PythonBuiltinNode { public abstract Object execute(VirtualFrame frame, PBaseException self, Object[] args, PKeyword[] kwds); @@ -314,20 +315,20 @@ public abstract static class OSErrorInitNode extends PythonBuiltinNode { static Object initNoArgs(VirtualFrame frame, PBaseException self, Object[] args, PKeyword[] kwds, @Bind("this") Node inliningTarget, @Cached GetClassNode getClassNode, - @Cached PyObjectGetAttr getAttr, + @Cached GetCachedTpSlotsNode getSlots, @Cached PyNumberCheckNode pyNumberCheckNode, @Cached PyNumberAsSizeNode pyNumberAsSizeNode, @Cached PyArgCheckPositionalNode checkPositionalNode, @Cached BaseExceptionBuiltins.BaseExceptionInitNode baseInitNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { final Object type = getClassNode.execute(inliningTarget, self); - if (!osErrorUseInit(frame, inliningTarget, PythonContext.get(inliningTarget), type, getAttr)) { + if (!osErrorUseInit(inliningTarget, type, getSlots)) { // Everything already done in OSError_new return PNone.NONE; } if (kwds.length != 0) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, P_TAKES_NO_KEYWORD_ARGS, type); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, P_TAKES_NO_KEYWORD_ARGS, type); } Object[] parsedArgs = osErrorParseArgs(args, inliningTarget, checkPositionalNode); @@ -408,8 +409,8 @@ boolean isInvalid(PBaseException self) { @Specialization(guards = "isInvalid(self)") @SuppressWarnings("unused") static Object generic(PBaseException self, Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.AttributeError, ErrorMessages.CHARACTERS_WRITTEN); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.CHARACTERS_WRITTEN); } @Specialization(guards = "!isInvalid(self)") @@ -424,7 +425,7 @@ static Object generic(PBaseException self, Object value, } } - @Builtin(name = J___STR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_str, isComplex = true) @GenerateNodeFactory public abstract static class OSErrorStrNode extends PythonUnaryBuiltinNode { @Specialization @@ -472,7 +473,7 @@ static Object reduce(PBaseException self, @Cached GetClassNode getClassNode, @Cached GetDictIfExistsNode getDictNode, @Cached SequenceStorageNodes.GetItemScalarNode getItemNode, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { PTuple args = getArgsNode.execute(inliningTarget, self); final Object filename = attrNode.get(self, IDX_FILENAME, OS_ERROR_ATTR_FACTORY); final Object filename2 = attrNode.get(self, IDX_FILENAME2, OS_ERROR_ATTR_FACTORY); @@ -488,15 +489,15 @@ static Object reduce(PBaseException self, argData[3] = PNone.NONE; argData[4] = filename2; } - args = factory.createTuple(argData); + args = PFactory.createTuple(language, argData); } final Object type = getClassNode.execute(inliningTarget, self); final PDict dict = getDictNode.execute(self); if (dict != null) { - return factory.createTuple(new Object[]{type, args, dict}); + return PFactory.createTuple(language, new Object[]{type, args, dict}); } else { - return factory.createTuple(new Object[]{type, args}); + return PFactory.createTuple(language, new Object[]{type, args}); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PrepareExceptionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PrepareExceptionNode.java index 68ea9891c9..bc6cf47604 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PrepareExceptionNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PrepareExceptionNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,6 +42,7 @@ import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.modules.BuiltinFunctions; import com.oracle.graal.python.builtins.objects.PNone; @@ -55,7 +56,7 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -90,10 +91,9 @@ static Object doException(PythonAbstractNativeObject exc, @SuppressWarnings("unu @Specialization(guards = {"check.execute(inliningTarget, exc)", "!isPNone(value)"}) static Object doException(@SuppressWarnings("unused") PBaseException exc, @SuppressWarnings("unused") Object value, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared @Cached PyExceptionInstanceCheckNode check, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.INSTANCE_EX_MAY_NOT_HAVE_SEP_VALUE); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.INSTANCE_EX_MAY_NOT_HAVE_SEP_VALUE); } @Specialization(guards = {"isTypeNode.execute(inliningTarget, type)", "!isPNone(value)", "!isPTuple(value)"}, limit = "1") @@ -106,7 +106,7 @@ static Object doExceptionOrCreate(VirtualFrame frame, Object type, Object value, @Shared @Cached IsSubtypeNode isSubtypeNode, @Shared @Cached PRaiseNode raiseNode, @Shared("callCtor") @Cached CallNode callConstructor) { - checkExceptionClass(type, isSubtypeNode, raiseNode); + checkExceptionClass(inliningTarget, type, isSubtypeNode, raiseNode); if (isInstanceProfile.profile(inliningTarget, isInstanceNode.executeWith(frame, value, type))) { return value; } else { @@ -127,7 +127,7 @@ static Object doCreate(VirtualFrame frame, Object type, @SuppressWarnings("unuse @Shared @Cached IsSubtypeNode isSubtypeNode, @Shared @Cached PRaiseNode raiseNode, @Shared("callCtor") @Cached CallNode callConstructor) { - checkExceptionClass(type, isSubtypeNode, raiseNode); + checkExceptionClass(inliningTarget, type, isSubtypeNode, raiseNode); Object instance = callConstructor.execute(frame, type); if (check.execute(inliningTarget, instance)) { return instance; @@ -145,7 +145,7 @@ static Object doCreateTuple(VirtualFrame frame, Object type, PTuple value, @Shared @Cached IsSubtypeNode isSubtypeNode, @Shared @Cached PRaiseNode raiseNode, @Shared("callCtor") @Cached CallNode callConstructor) { - checkExceptionClass(type, isSubtypeNode, raiseNode); + checkExceptionClass(inliningTarget, type, isSubtypeNode, raiseNode); Object[] args = getObjectArrayNode.execute(inliningTarget, value); Object instance = callConstructor.execute(frame, type, args); if (check.execute(inliningTarget, instance)) { @@ -158,9 +158,8 @@ static Object doCreateTuple(VirtualFrame frame, Object type, PTuple value, @Specialization(guards = "fallbackGuard(type, inliningTarget, isTypeNode)", limit = "1") static Object doError(Object type, @SuppressWarnings("unused") Object value, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached IsTypeNode isTypeNode, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.EXCEPTIONS_MUST_BE_CLASSES_OR_INSTANCES_DERIVING_FROM_BASE_EX, type); + @SuppressWarnings("unused") @Exclusive @Cached IsTypeNode isTypeNode) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.EXCEPTIONS_MUST_BE_CLASSES_OR_INSTANCES_DERIVING_FROM_BASE_EX, type); } static boolean fallbackGuard(Object type, Node inliningTarget, IsTypeNode isTypeNode) { @@ -172,12 +171,12 @@ private static PBaseException handleInstanceNotAnException(Object type, Object i * Instead of throwing the exception here, we replace the created exception with it. This is * done to match CPython's behavior of `generator.throw` */ - return PythonObjectFactory.getUncached().createBaseException(TypeError, ErrorMessages.CALLING_N_SHOULD_HAVE_RETURNED_AN_INSTANCE_OF_BASE_EXCEPTION_NOT_P, new Object[]{type, instance}); + return PFactory.createBaseException(PythonLanguage.get(null), TypeError, ErrorMessages.CALLING_N_SHOULD_HAVE_RETURNED_AN_INSTANCE_OF_BASE_EXCEPTION_NOT_P, new Object[]{type, instance}); } - private static void checkExceptionClass(Object type, IsSubtypeNode isSubtypeNode, PRaiseNode raiseNode) { + private static void checkExceptionClass(Node inliningTarget, Object type, IsSubtypeNode isSubtypeNode, PRaiseNode raiseNode) { if (!isSubtypeNode.execute(type, PythonBuiltinClassType.PBaseException)) { - throw raiseNode.raise(TypeError, ErrorMessages.EXCEPTIONS_MUST_BE_CLASSES_OR_INSTANCES_DERIVING_FROM_BASE_EX, type); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.EXCEPTIONS_MUST_BE_CLASSES_OR_INSTANCES_DERIVING_FROM_BASE_EX, type); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/StopIterationBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/StopIterationBuiltins.java index 2a4b436cbf..57a8042c24 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/StopIterationBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/StopIterationBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,21 +40,21 @@ */ package com.oracle.graal.python.builtins.objects.exception; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; - import java.util.List; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.function.PKeyword; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; -import com.oracle.graal.python.nodes.util.SplitArgsNode; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; @@ -64,37 +64,25 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.StopIteration) public final class StopIterationBuiltins extends PythonBuiltins { - public static final BaseExceptionAttrNode.StorageFactory STOP_ITERATION_ATTR_FACTORY = (args, factory) -> new Object[]{(args != null && args.length > 0) ? args[0] : PNone.NONE}; + public static final BaseExceptionAttrNode.StorageFactory STOP_ITERATION_ATTR_FACTORY = (args) -> new Object[]{(args != null && args.length > 0) ? args[0] : PNone.NONE}; + + public static final TpSlots SLOTS = StopIterationBuiltinsSlotsGen.SLOTS; @Override protected List> getNodeFactories() { return StopIterationBuiltinsFactory.getFactories(); } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory public abstract static class StopIterationInitNode extends PythonVarargsBuiltinNode { - @Child private SplitArgsNode splitArgsNode; - - @Override - public final Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) { - if (arguments.length == 0 || keywords.length != 0) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw VarargsBuiltinDirectInvocationNotSupported.INSTANCE; - } - if (splitArgsNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - splitArgsNode = insert(SplitArgsNode.create()); - } - Object[] argsWithoutSelf = splitArgsNode.executeCached(arguments); - return execute(frame, arguments[0], argsWithoutSelf, keywords); - } @Specialization - static Object init(PBaseException self, Object[] args, + static Object init(VirtualFrame frame, PBaseException self, Object[] args, PKeyword[] keywords, @Cached BaseExceptionBuiltins.BaseExceptionInitNode baseExceptionInitNode) { - baseExceptionInitNode.execute(self, args); - self.setExceptionAttributes(STOP_ITERATION_ATTR_FACTORY.create(args, null)); + baseExceptionInitNode.execute(frame, self, args, keywords); + self.setExceptionAttributes(STOP_ITERATION_ATTR_FACTORY.create(args)); return PNone.NONE; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/SyntaxErrorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/SyntaxErrorBuiltins.java index e929e4184f..84dcfc8428 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/SyntaxErrorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/SyntaxErrorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,20 +43,23 @@ import static com.oracle.graal.python.nodes.ErrorMessages.MISSING_PARENTHESES_IN_CALL_TO_EXEC; import static com.oracle.graal.python.nodes.ErrorMessages.MISSING_PARENTHESES_IN_CALL_TO_PRINT; import static com.oracle.graal.python.nodes.ErrorMessages.TUPLE_OUT_OF_BOUNDS; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import java.util.List; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; +import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.lib.PyLongAsLongAndOverflowNode; import com.oracle.graal.python.lib.PyLongCheckExactNode; import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode; @@ -70,7 +73,6 @@ import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.OverflowException; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -94,14 +96,17 @@ public final class SyntaxErrorBuiltins extends PythonBuiltins { public static final int IDX_PRINT_FILE_AND_LINE = 7; public static final int SYNTAX_ERR_NUM_ATTRS = IDX_PRINT_FILE_AND_LINE + 1; - public static final BaseExceptionAttrNode.StorageFactory SYNTAX_ERROR_ATTR_FACTORY = (args, factory) -> new Object[SYNTAX_ERR_NUM_ATTRS]; + public static final BaseExceptionAttrNode.StorageFactory SYNTAX_ERROR_ATTR_FACTORY = (args) -> new Object[SYNTAX_ERR_NUM_ATTRS]; + + public static final TpSlots SLOTS = SyntaxErrorBuiltinsSlotsGen.SLOTS; @Override protected List> getNodeFactories() { return SyntaxErrorBuiltinsFactory.getFactories(); } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory public abstract static class SyntaxErrorInitNode extends PythonBuiltinNode { private static final String PREFIX_PRINT = "print "; @@ -111,7 +116,7 @@ public abstract static class SyntaxErrorInitNode extends PythonBuiltinNode { private static final char CHR_COMMA = ','; private static final char CHR_SEMICOLON = ';'; - @CompilerDirectives.TruffleBoundary + @TruffleBoundary private static String getLegacyPrintStatementMsg(String text) { int endPos = text.indexOf(CHR_SEMICOLON); if (endPos == -1) { @@ -128,7 +133,7 @@ private static String getLegacyPrintStatementMsg(String text) { return String.format(MISSING_PARENTHESES_IN_CALL_TO_PRINT.toJavaStringUncached(), data, maybeEndArg); } - @CompilerDirectives.TruffleBoundary + @TruffleBoundary private static Object checkForLegacyStatements(String text, int start) { // Ignore leading whitespace final String trimmedText = trimLeft(text, start); @@ -149,7 +154,7 @@ private static Object checkForLegacyStatements(String text, int start) { return null; } - @CompilerDirectives.TruffleBoundary + @TruffleBoundary private static Object reportMissingParentheses(Object msg, String text) { // Skip entirely if there is an opening parenthesis final int leftParenIndex = text.indexOf(CHR_LEFTPAREN); @@ -183,14 +188,14 @@ private static String trimLeft(String str, int start) { } @Specialization - static Object init(VirtualFrame frame, PBaseException self, Object[] args, + static Object init(VirtualFrame frame, PBaseException self, Object[] args, PKeyword[] keywords, @Bind("this") Node inliningTarget, @Cached CastToJavaStringNode castToJavaStringNode, @Cached TupleNodes.ConstructTupleNode constructTupleNode, @Cached SequenceStorageNodes.GetItemNode getItemNode, @Cached BaseExceptionBuiltins.BaseExceptionInitNode baseExceptionInitNode, - @Cached PRaiseNode.Lazy raiseNode) { - baseExceptionInitNode.execute(self, args); + @Cached PRaiseNode raiseNode) { + baseExceptionInitNode.execute(frame, self, args, keywords); Object[] attrs = SYNTAX_ERROR_ATTR_FACTORY.create(); if (args.length >= 1) { attrs[IDX_MSG] = args[0]; @@ -200,7 +205,7 @@ static Object init(VirtualFrame frame, PBaseException self, Object[] args, final SequenceStorage storage = info.getSequenceStorage(); if (storage.length() != 4) { // not a very good error message, but it's what Python 2.4 gives - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.IndexError, TUPLE_OUT_OF_BOUNDS); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.IndexError, TUPLE_OUT_OF_BOUNDS); } attrs[IDX_FILENAME] = getItemNode.execute(storage, 0); @@ -300,7 +305,7 @@ Object generic(PBaseException self, Object value, } } - @Builtin(name = J___STR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_str, isComplex = true) @GenerateNodeFactory public abstract static class SyntaxErrorStrNode extends PythonUnaryBuiltinNode { @Specialization diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/SystemExitBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/SystemExitBuiltins.java index 79b59ad75d..dce5260aa3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/SystemExitBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/SystemExitBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,18 +40,22 @@ */ package com.oracle.graal.python.builtins.objects.exception; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; - import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.function.PKeyword; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; @@ -60,12 +64,14 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.SystemExit) public final class SystemExitBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = SystemExitBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return SystemExitBuiltinsFactory.getFactories(); } - public static final BaseExceptionAttrNode.StorageFactory SYSTEM_EXIT_ATTR_FACTORY = (args, factory) -> { + public static final BaseExceptionAttrNode.StorageFactory SYSTEM_EXIT_ATTR_FACTORY = (args) -> { Object code; switch (args.length) { case 0: @@ -75,20 +81,20 @@ protected List> getNodeFa code = args[0]; break; default: - code = factory.createTuple(args); + code = PFactory.createTuple(PythonLanguage.get(null), args); } return new Object[]{code}; }; - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory public abstract static class InitNode extends PythonBuiltinNode { @Specialization - static Object initNoArgs(PBaseException self, Object[] args, - @Cached BaseExceptionBuiltins.BaseExceptionInitNode baseExceptionInitNode, - @Cached PythonObjectFactory factory) { - baseExceptionInitNode.execute(self, args); - self.setExceptionAttributes(SYSTEM_EXIT_ATTR_FACTORY.create(args, factory)); + static Object initNoArgs(PBaseException self, Object[] args, PKeyword[] keywords, + @Cached BaseExceptionBuiltins.BaseExceptionInitNode baseExceptionInitNode) { + baseExceptionInitNode.execute(null, self, args, keywords); + self.setExceptionAttributes(SYSTEM_EXIT_ATTR_FACTORY.create(args)); return PNone.NONE; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeDecodeErrorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeDecodeErrorBuiltins.java index a3d7b4c833..8ed216902a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeDecodeErrorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeDecodeErrorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -49,23 +49,25 @@ import static com.oracle.graal.python.builtins.objects.exception.UnicodeErrorBuiltins.getArgAsBytes; import static com.oracle.graal.python.builtins.objects.exception.UnicodeErrorBuiltins.getArgAsInt; import static com.oracle.graal.python.builtins.objects.exception.UnicodeErrorBuiltins.getArgAsString; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.runtime.exception.PythonErrorType.UnicodeDecodeError; import java.util.List; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; +import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringCheckedNode; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.lib.PyObjectSizeNode; import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode; import com.oracle.graal.python.nodes.ErrorMessages; @@ -93,25 +95,28 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.UnicodeDecodeError) public final class UnicodeDecodeErrorBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = UnicodeDecodeErrorBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return UnicodeDecodeErrorBuiltinsFactory.getFactories(); } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory public abstract static class UnicodeDecodeErrorInitNode extends PythonBuiltinNode { public abstract Object execute(VirtualFrame frame, PBaseException self, Object[] args); @Specialization - static Object initNoArgs(VirtualFrame frame, PBaseException self, Object[] args, + static Object initNoArgs(VirtualFrame frame, PBaseException self, Object[] args, PKeyword[] keywords, @Bind("this") Node inliningTarget, @Cached UnicodeErrorBuiltins.GetArgAsBytesNode getArgAsBytesNode, @Cached CastToTruffleStringNode toStringNode, @Cached CastToJavaIntExactNode toJavaIntExactNode, @Cached BaseExceptionBuiltins.BaseExceptionInitNode baseInitNode, - @Cached PRaiseNode.Lazy raiseNode) { - baseInitNode.execute(self, args); + @Cached PRaiseNode raiseNode) { + baseInitNode.execute(frame, self, args, keywords); // PyArg_ParseTuple(args, "UOnnU"), TODO: add proper error messages self.setExceptionAttributes(new Object[]{ getArgAsString(inliningTarget, args, 0, raiseNode, toStringNode), @@ -124,7 +129,7 @@ static Object initNoArgs(VirtualFrame frame, PBaseException self, Object[] args, } } - @Builtin(name = J___STR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_str, isComplex = true) @GenerateNodeFactory public abstract static class UnicodeEncodeErrorStrNode extends PythonUnaryBuiltinNode { @Specialization @@ -177,14 +182,14 @@ static PBaseException createNew(VirtualFrame frame, Node inliningTarget, @Suppre int endPos, TruffleString reason, @Cached(inline = false) CallNode callNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object obj = callNode.execute(frame, UnicodeDecodeError, encoding, inputObject, startPos, endPos, reason); if (obj instanceof PBaseException exception) { return exception; } // Shouldn't happen unless the user manually replaces the method, which is really // unexpected and shouldn't be permitted at all, but currently it is - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.SHOULD_HAVE_RETURNED_EXCEPTION, UnicodeDecodeError, obj); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.SHOULD_HAVE_RETURNED_EXCEPTION, UnicodeDecodeError, obj); } @Specialization(guards = "exceptionObject != null") @@ -210,17 +215,17 @@ public abstract static class PyUnicodeDecodeErrorGetObjectNode extends Node { public abstract Object execute(Node inliningTarget, PBaseException exceptionObject); @Specialization - static Object doIt(VirtualFrame frame, Node inliningTarget, PBaseException exceptionObject, + static Object doIt(Node inliningTarget, PBaseException exceptionObject, @Cached(inline = false) BaseExceptionAttrNode attrNode, @Cached GetClassNode getClassNode, @Cached(inline = false) IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object obj = attrNode.get(exceptionObject, IDX_OBJECT, UNICODE_ERROR_ATTR_FACTORY); if (obj == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_ATTRIBUTE_NOT_SET, "object"); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_ATTRIBUTE_NOT_SET, "object"); } - if (!isSubtypeNode.execute(frame, getClassNode.execute(inliningTarget, obj), PythonBuiltinClassType.PBytes)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_ATTRIBUTE_MUST_BE_BYTES, "object"); + if (!isSubtypeNode.execute(getClassNode.execute(inliningTarget, obj), PythonBuiltinClassType.PBytes)) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_ATTRIBUTE_MUST_BE_BYTES, "object"); } return obj; } @@ -297,10 +302,10 @@ public abstract static class PyUnicodeDecodeErrorGetEncodingNode extends Node { static TruffleString doIt(Node inliningTarget, PBaseException exceptionObject, @Cached(inline = false) BaseExceptionAttrNode attrNode, @Cached CastToTruffleStringCheckedNode castToStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object obj = attrNode.get(exceptionObject, IDX_ENCODING, UNICODE_ERROR_ATTR_FACTORY); if (obj == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_ATTRIBUTE_NOT_SET, "encoding"); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_ATTRIBUTE_NOT_SET, "encoding"); } return castToStringNode.cast(inliningTarget, obj, ErrorMessages.S_ATTRIBUTE_MUST_BE_UNICODE, "encoding"); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeEncodeErrorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeEncodeErrorBuiltins.java index 36f7588105..ecb356adee 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeEncodeErrorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeEncodeErrorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -49,20 +49,22 @@ import static com.oracle.graal.python.builtins.objects.exception.UnicodeErrorBuiltins.UNICODE_ERROR_ATTR_FACTORY; import static com.oracle.graal.python.builtins.objects.exception.UnicodeErrorBuiltins.getArgAsInt; import static com.oracle.graal.python.builtins.objects.exception.UnicodeErrorBuiltins.getArgAsString; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import java.util.List; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringCheckedNode; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; @@ -86,24 +88,27 @@ @CoreFunctions(extendClasses = UnicodeEncodeError) public final class UnicodeEncodeErrorBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = UnicodeEncodeErrorBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return UnicodeEncodeErrorBuiltinsFactory.getFactories(); } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory public abstract static class UnicodeEncodeErrorInitNode extends PythonBuiltinNode { - public abstract Object execute(PBaseException self, Object[] args); @Specialization - static Object initNoArgs(PBaseException self, Object[] args, + static Object initNoArgs(VirtualFrame frame, PBaseException self, Object[] args, PKeyword[] keywords, @Bind("this") Node inliningTarget, @Cached CastToTruffleStringNode toStringNode, @Cached CastToJavaIntExactNode toJavaIntExactNode, @Cached BaseExceptionBuiltins.BaseExceptionInitNode baseInitNode, - @Cached PRaiseNode.Lazy raiseNode) { - baseInitNode.execute(self, args); + @Cached PRaiseNode raiseNode) { + baseInitNode.execute(frame, self, args, keywords); // PyArg_ParseTuple(args, "UUnnU"), TODO: add proper error messages self.setExceptionAttributes(new Object[]{ getArgAsString(inliningTarget, args, 0, raiseNode, toStringNode), @@ -116,7 +121,7 @@ static Object initNoArgs(PBaseException self, Object[] args, } } - @Builtin(name = J___STR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_str, isComplex = true) @GenerateNodeFactory public abstract static class UnicodeEncodeErrorStrNode extends PythonUnaryBuiltinNode { @Specialization @@ -178,14 +183,14 @@ static PBaseException createNew(VirtualFrame frame, Node inliningTarget, @Suppre int startPos, int endPos, TruffleString reason, @Cached(inline = false) CallNode callNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object obj = callNode.execute(frame, UnicodeEncodeError, encoding, inputObject, startPos, endPos, reason); if (obj instanceof PBaseException exception) { return exception; } // Shouldn't happen unless the user manually replaces the method, which is really // unexpected and shouldn't be permitted at all, but currently it is - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.SHOULD_HAVE_RETURNED_EXCEPTION, UnicodeEncodeError, obj); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.SHOULD_HAVE_RETURNED_EXCEPTION, UnicodeEncodeError, obj); } @Specialization(guards = "exceptionObject != null") @@ -214,10 +219,10 @@ public abstract static class PyUnicodeEncodeOrTranslateErrorGetObjectNode extend static TruffleString doIt(Node inliningTarget, PBaseException exceptionObject, @Cached(inline = false) BaseExceptionAttrNode attrNode, @Cached CastToTruffleStringCheckedNode castToStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object obj = attrNode.get(exceptionObject, IDX_OBJECT, UNICODE_ERROR_ATTR_FACTORY); if (obj == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_ATTRIBUTE_NOT_SET, "object"); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_ATTRIBUTE_NOT_SET, "object"); } return castToStringNode.cast(inliningTarget, obj, ErrorMessages.S_ATTRIBUTE_MUST_BE_UNICODE, "object"); } @@ -294,10 +299,10 @@ public abstract static class PyUnicodeEncodeErrorGetEncodingNode extends Node { static TruffleString doIt(Node inliningTarget, PBaseException exceptionObject, @Cached(inline = false) BaseExceptionAttrNode attrNode, @Cached CastToTruffleStringCheckedNode castToStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object obj = attrNode.get(exceptionObject, IDX_ENCODING, UNICODE_ERROR_ATTR_FACTORY); if (obj == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_ATTRIBUTE_NOT_SET, "encoding"); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_ATTRIBUTE_NOT_SET, "encoding"); } return castToStringNode.cast(inliningTarget, obj, ErrorMessages.S_ATTRIBUTE_MUST_BE_UNICODE, "encoding"); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeErrorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeErrorBuiltins.java index ed6fa8973d..38d08d7198 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeErrorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeErrorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,6 +44,7 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -60,7 +61,7 @@ import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.IndirectCallData; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -84,24 +85,24 @@ public final class UnicodeErrorBuiltins extends PythonBuiltins { public static final int IDX_REASON = 4; public static final int UNICODE_ERR_NUM_ATTRS = IDX_REASON + 1; - public static final BaseExceptionAttrNode.StorageFactory UNICODE_ERROR_ATTR_FACTORY = (args, factory) -> new Object[UNICODE_ERR_NUM_ATTRS]; + public static final BaseExceptionAttrNode.StorageFactory UNICODE_ERROR_ATTR_FACTORY = (args) -> new Object[UNICODE_ERR_NUM_ATTRS]; @Override protected List> getNodeFactories() { return UnicodeErrorBuiltinsFactory.getFactories(); } - public static TruffleString getArgAsString(Node inliningTarget, Object[] args, int index, PRaiseNode.Lazy raiseNode, CastToTruffleStringNode castNode) { + public static TruffleString getArgAsString(Node inliningTarget, Object[] args, int index, PRaiseNode raiseNode, CastToTruffleStringNode castNode) { if (args.length < index + 1 || !PGuards.isString(args[index])) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError); } else { return castNode.execute(inliningTarget, args[index]); } } - public static int getArgAsInt(Node inliningTarget, Object[] args, int index, PRaiseNode.Lazy raiseNode, CastToJavaIntExactNode castNode) { + public static int getArgAsInt(Node inliningTarget, Object[] args, int index, PRaiseNode raiseNode, CastToJavaIntExactNode castNode) { if (args.length < index + 1 || !(PGuards.isInteger(args[index]) || PGuards.isPInt(args[index]))) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError); } else { return castNode.execute(inliningTarget, args[index]); } @@ -115,11 +116,11 @@ public abstract static class GetArgAsBytesNode extends PNodeWithContext { @Specialization @TruffleBoundary static PBytes doString(TruffleString value, - @Shared @Cached(inline = false) PythonObjectFactory factory) { + @Bind PythonLanguage language) { // TODO GR-37601: cbasca cPython works directly with bytes while we have Java strings // which are encoded, here we decode using the system encoding but this might not be the // correct / ideal case - return factory.createBytes(value.toJavaStringUncached().getBytes()); + return PFactory.createBytes(language, value.toJavaStringUncached().getBytes()); } @Specialization @@ -131,20 +132,20 @@ static PBytes doBytes(PBytes value) { static PBytes doOther(VirtualFrame frame, Object value, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary(limit = "getCallSiteInlineCacheMaxDepth()") PythonBufferAccessLibrary bufferLib, - @Shared @Cached(inline = false) PythonObjectFactory factory) { + @Bind PythonLanguage language) { try { final byte[] buffer = bufferLib.getInternalOrCopiedByteArray(value); final int bufferLength = bufferLib.getBufferLength(value); - return factory.createBytes(buffer, 0, bufferLength); + return PFactory.createBytes(language, buffer, bufferLength); } finally { bufferLib.release(value, frame, indirectCallData); } } } - public static Object getArgAsBytes(VirtualFrame frame, Node inliningTarget, Object[] args, int index, PRaiseNode.Lazy raiseNode, GetArgAsBytesNode getArgAsBytesNode) { + public static Object getArgAsBytes(VirtualFrame frame, Node inliningTarget, Object[] args, int index, PRaiseNode raiseNode, GetArgAsBytesNode getArgAsBytesNode) { if (args.length < index + 1) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError); } else { return getArgAsBytesNode.execute(frame, inliningTarget, args[index]); } @@ -208,8 +209,8 @@ static Object setPInt(PBaseException self, PInt value, @Specialization(guards = {"!isNoValue(value)", "!canBeInteger(value)"}) @SuppressWarnings("unused") static Object generic(PBaseException self, Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, INTEGER_REQUIRED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, INTEGER_REQUIRED); } } @@ -245,8 +246,8 @@ static Object setPInt(PBaseException self, PInt value, @Specialization(guards = {"!isNoValue(value)", "!canBeInteger(value)"}) @SuppressWarnings("unused") static Object generic(PBaseException self, Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, INTEGER_REQUIRED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, INTEGER_REQUIRED); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeTranslateErrorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeTranslateErrorBuiltins.java index 3ffffd7c75..de7cabf855 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeTranslateErrorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeTranslateErrorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,19 +47,21 @@ import static com.oracle.graal.python.builtins.objects.exception.UnicodeErrorBuiltins.UNICODE_ERROR_ATTR_FACTORY; import static com.oracle.graal.python.builtins.objects.exception.UnicodeErrorBuiltins.getArgAsInt; import static com.oracle.graal.python.builtins.objects.exception.UnicodeErrorBuiltins.getArgAsString; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import java.util.List; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; @@ -80,24 +82,26 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.UnicodeTranslateError) public final class UnicodeTranslateErrorBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = UnicodeTranslateErrorBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return UnicodeTranslateErrorBuiltinsFactory.getFactories(); } - @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true) + @Slot(value = SlotKind.tp_init, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory public abstract static class UnicodeTranslateErrorInitNode extends PythonBuiltinNode { - public abstract Object execute(PBaseException self, Object[] args); @Specialization - static Object initNoArgs(PBaseException self, Object[] args, + static Object initNoArgs(VirtualFrame frame, PBaseException self, Object[] args, PKeyword[] keywords, @Bind("this") Node inliningTarget, @Cached CastToTruffleStringNode toStringNode, @Cached CastToJavaIntExactNode toJavaIntExactNode, @Cached BaseExceptionBuiltins.BaseExceptionInitNode baseInitNode, - @Cached PRaiseNode.Lazy raiseNode) { - baseInitNode.execute(self, args); + @Cached PRaiseNode raiseNode) { + baseInitNode.execute(frame, self, args, keywords); // PyArg_ParseTuple(args, "UnnU"), TODO: add proper error messages self.setExceptionAttributes(new Object[]{ null, // placeholder for object so we do not redefine the access indexes @@ -112,7 +116,7 @@ static Object initNoArgs(PBaseException self, Object[] args, } } - @Builtin(name = J___STR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_str, isComplex = true) @GenerateNodeFactory public abstract static class UnicodeTranslateErrorStrNode extends PythonUnaryBuiltinNode { @Specialization diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/FloatBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/FloatBuiltins.java index eadc01ee34..2ec6609e3d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/FloatBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/FloatBuiltins.java @@ -29,22 +29,11 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; import static com.oracle.graal.python.nodes.BuiltinNames.J_FLOAT; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CEIL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___FLOOR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___FORMAT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETFORMAT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETNEWARGS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___POW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ROUND__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RPOW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___TRUNC__; import static com.oracle.graal.python.runtime.formatting.FormattingUtils.validateForFloat; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; @@ -56,32 +45,44 @@ import java.nio.ByteOrder; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; import com.oracle.graal.python.builtins.objects.common.FormatNodeBase; import com.oracle.graal.python.builtins.objects.floats.FloatBuiltinsClinicProviders.FormatNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.floats.FloatUtils.PFloatUnboxing; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotInquiry.NbBoolBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare; import com.oracle.graal.python.lib.PyFloatCheckNode; +import com.oracle.graal.python.lib.PyFloatFromString; import com.oracle.graal.python.lib.PyLongFromDoubleNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; +import com.oracle.graal.python.lib.PyNumberFloatNode; +import com.oracle.graal.python.lib.PyNumberPowerNode; import com.oracle.graal.python.lib.PyObjectHashNode; +import com.oracle.graal.python.lib.PyUnicodeCheckExactNode; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallTernaryNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallVarargsNode; +import com.oracle.graal.python.nodes.call.CallNode; +import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; @@ -89,7 +90,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; +import com.oracle.graal.python.nodes.object.BuiltinClassProfiles; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaDoubleNode; import com.oracle.graal.python.runtime.exception.PException; @@ -97,7 +98,7 @@ import com.oracle.graal.python.runtime.formatting.FloatFormatter; import com.oracle.graal.python.runtime.formatting.InternalFormat; import com.oracle.graal.python.runtime.formatting.InternalFormat.Spec; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; @@ -110,12 +111,15 @@ import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.UnexpectedResultException; +import com.oracle.truffle.api.object.Shape; +import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleString; import com.oracle.truffle.api.strings.TruffleString.FromJavaStringNode; @@ -137,13 +141,13 @@ private static double castToDoubleChecked(Node inliningTarget, Object obj, CastT try { return cast.execute(inliningTarget, obj); } catch (CannotCastException e) { - throw raiseWrongSelf(obj); + throw raiseWrongSelf(inliningTarget, obj); } } @InliningCutoff - private static PException raiseWrongSelf(Object obj) { - throw PRaiseNode.getUncached().raise(TypeError, ErrorMessages.DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P, "float", obj); + private static PException raiseWrongSelf(Node inliningTarget, Object obj) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P, "float", obj); } @GenerateCached(false) @@ -166,7 +170,7 @@ Object doOther(Object object, @GenerateCached(false) abstract static class AbstractNumericBinaryBuiltin extends BinaryOpBuiltinNode { - @Child private PRaiseNode raiseNode; + private final BranchProfile errorProfile = BranchProfile.create(); protected abstract Object op(double a, double b); @@ -198,20 +202,132 @@ Object doOther(Object a, Object b, void raiseDivisionByZero(boolean cond) { if (cond) { - if (raiseNode == null) { + errorProfile.enter(); + throw PRaiseNode.raiseStatic(this, PythonErrorType.ZeroDivisionError, ErrorMessages.DIVISION_BY_ZERO); + } + } + } + + // float([x]) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = J_FLOAT, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2) + @GenerateNodeFactory + public abstract static class FloatNewNode extends PythonBinaryBuiltinNode { + + @Child NonPrimitiveFloatNode nonPrimitiveFloatNode; + + @Specialization + Object doIt(VirtualFrame frame, Object cls, Object arg, + @Bind("this") Node inliningTarget, + @Cached BuiltinClassProfiles.IsBuiltinClassExactProfile isPrimitiveFloatProfile, + @Cached PrimitiveFloatNode primitiveFloatNode, + @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode) { + if (isPrimitiveFloat(inliningTarget, cls, isPrimitiveFloatProfile)) { + return primitiveFloatNode.execute(frame, inliningTarget, arg); + } else { + boolean needsNativeAllocation = needsNativeAllocationNode.execute(inliningTarget, cls); + if (nonPrimitiveFloatNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - if (isAdoptable()) { - raiseNode = insert(PRaiseNode.create()); - } else { - raiseNode = PRaiseNode.getUncached(); - } + nonPrimitiveFloatNode = insert(FloatBuiltinsFactory.FloatNewNodeFactory.NonPrimitiveFloatNodeGen.create()); } - throw raiseNode.raise(PythonErrorType.ZeroDivisionError, ErrorMessages.DIVISION_BY_ZERO); + return nonPrimitiveFloatNode.execute(frame, cls, arg, needsNativeAllocation); } } + + @GenerateCached(false) + @GenerateInline + @ImportStatic(PGuards.class) + abstract static class PrimitiveFloatNode extends Node { + abstract double execute(VirtualFrame frame, Node inliningTarget, Object arg); + + @Specialization + static double floatFromDouble(double arg) { + return arg; + } + + @Specialization + static double floatFromInt(int arg) { + return arg; + } + + @Specialization + static double floatFromLong(long arg) { + return arg; + } + + @Specialization + static double floatFromBoolean(boolean arg) { + return arg ? 1d : 0d; + } + + @Specialization(guards = "isNoValue(obj)") + static double floatFromNoValue(@SuppressWarnings("unused") PNone obj) { + return 0.0; + } + + @Fallback + @InliningCutoff + static double floatFromObject(VirtualFrame frame, Node inliningTarget, Object obj, + @Cached PyUnicodeCheckExactNode stringCheck, + @Cached PyFloatFromString fromString, + @Cached PyNumberFloatNode pyNumberFloat) { + if (stringCheck.execute(inliningTarget, obj)) { + return fromString.execute(frame, inliningTarget, obj); + } + return pyNumberFloat.execute(frame, inliningTarget, obj); + } + } + + @ImportStatic(PGuards.class) + @GenerateInline(false) // intentionally lazy + abstract static class NonPrimitiveFloatNode extends Node { + abstract Object execute(VirtualFrame frame, Object cls, Object arg, boolean needsNativeAllocation); + + @Specialization(guards = {"!needsNativeAllocation", "isNoValue(obj)"}) + @InliningCutoff + static Object floatFromNoneManagedSubclass(Object cls, PNone obj, @SuppressWarnings("unused") boolean needsNativeAllocation, + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) { + Shape shape = getInstanceShape.execute(cls); + return PFactory.createFloat(language, cls, shape, PrimitiveFloatNode.floatFromNoValue(obj)); + } + + @Specialization(guards = "!needsNativeAllocation") + @InliningCutoff + static Object floatFromObjectManagedSubclass(VirtualFrame frame, Object cls, Object obj, @SuppressWarnings("unused") boolean needsNativeAllocation, + @Bind("this") @SuppressWarnings("unused") Node inliningTarget, + @Bind PythonLanguage language, + @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Shared @Cached PrimitiveFloatNode recursiveCallNode) { + Shape shape = getInstanceShape.execute(cls); + return PFactory.createFloat(language, cls, shape, recursiveCallNode.execute(frame, inliningTarget, obj)); + } + + // logic similar to float_subtype_new(PyTypeObject *type, PyObject *x) from CPython + // floatobject.c we have to first create a temporary float, then fill it into + // a natively allocated subtype structure + @Specialization(guards = {"needsNativeAllocation", // + "isSubtypeOfFloat( isSubtype, cls)"}, limit = "1") + @InliningCutoff + static Object floatFromObjectNativeSubclass(VirtualFrame frame, Object cls, Object obj, @SuppressWarnings("unused") boolean needsNativeAllocation, + @Bind("this") @SuppressWarnings("unused") Node inliningTarget, + @Cached @SuppressWarnings("unused") IsSubtypeNode isSubtype, + @Cached CExtNodes.FloatSubtypeNew subtypeNew, + @Shared @Cached PrimitiveFloatNode recursiveCallNode) { + return subtypeNew.call(cls, recursiveCallNode.execute(frame, inliningTarget, obj)); + } + + protected static boolean isSubtypeOfFloat(IsSubtypeNode isSubtypeNode, Object cls) { + return isSubtypeNode.execute(cls, PythonBuiltinClassType.PFloat); + } + } + + protected static boolean isPrimitiveFloat(Node inliningTarget, Object cls, BuiltinClassProfiles.IsBuiltinClassExactProfile isPrimitiveProfile) { + return isPrimitiveProfile.profileClass(inliningTarget, cls, PythonBuiltinClassType.PFloat); + } } - @Builtin(name = J___STR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_str, isComplex = true) @GenerateNodeFactory public abstract static class StrNode extends AbstractNumericUnaryBuiltin { public static final Spec spec = new Spec(' ', '>', Spec.NONE, false, Spec.UNSPECIFIED, Spec.NONE, 0, 'r'); @@ -229,7 +345,7 @@ public static TruffleString doFormat(double d, FloatFormatter f) { } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends StrNode { } @@ -343,8 +459,7 @@ protected Object op(double a, double b) { } } - @Builtin(name = J___RPOW__, minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3, reverseOperation = true) - @Builtin(name = J___POW__, minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3) + @Slot(value = SlotKind.nb_power, isComplex = true) @GenerateNodeFactory public abstract static class PowNode extends PythonTernaryBuiltinNode { protected abstract double executeDouble(VirtualFrame frame, double left, double right, PNone none) throws UnexpectedResultException; @@ -362,7 +477,7 @@ public final Object execute(double left, double right) { @Specialization static double doDI(double left, int right, @SuppressWarnings("unused") PNone none, @Bind("this") Node inliningTarget, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { return doOperation(inliningTarget, left, right, raiseNode); } @@ -370,7 +485,7 @@ static double doDI(double left, int right, @SuppressWarnings("unused") PNone non * The special cases we need to deal with always return 1, so 0 means no special case, not a * result. */ - private static double doSpecialCases(Node inliningTarget, double left, double right, PRaiseNode.Lazy raiseNode) { + private static double doSpecialCases(Node inliningTarget, double left, double right, PRaiseNode raiseNode) { // see cpython://Objects/floatobject.c#float_pow for special cases if (Double.isNaN(right) && left == 1) { // 1**nan = 1, unlike on Java @@ -382,12 +497,12 @@ private static double doSpecialCases(Node inliningTarget, double left, double ri } if (left == 0 && right < 0 && Double.isFinite(right)) { // 0**w is an error if w is finite and negative, unlike Java - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ZeroDivisionError, ErrorMessages.POW_ZERO_CANNOT_RAISE_TO_NEGATIVE_POWER); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ZeroDivisionError, ErrorMessages.POW_ZERO_CANNOT_RAISE_TO_NEGATIVE_POWER); } return 0; } - private static double doOperation(Node inliningTarget, double left, double right, PRaiseNode.Lazy raiseNode) { + private static double doOperation(Node inliningTarget, double left, double right, PRaiseNode raiseNode) { if (doSpecialCases(inliningTarget, left, right, raiseNode) == 1) { return 1.0; } @@ -398,16 +513,16 @@ private static double doOperation(Node inliningTarget, double left, double right @InliningCutoff static double doDD(VirtualFrame frame, double left, double right, @SuppressWarnings("unused") PNone none, @Bind("this") Node inliningTarget, - @Shared("powCall") @Cached("create(Pow)") LookupAndCallTernaryNode callPow, - @Shared @Cached PRaiseNode.Lazy raiseNode) throws UnexpectedResultException { + @Shared @Cached PyNumberPowerNode powerNode, + @Shared @Cached PRaiseNode raiseNode) throws UnexpectedResultException { if (doSpecialCases(inliningTarget, left, right, raiseNode) == 1) { return 1.0; } if (left < 0 && Double.isFinite(left) && Double.isFinite(right) && (right % 1 != 0)) { CompilerDirectives.transferToInterpreterAndInvalidate(); // Negative numbers raised to fractional powers become complex. - PythonObjectFactory factory = PythonObjectFactory.getUncached(); - throw new UnexpectedResultException(callPow.execute(frame, factory.createComplex(left, 0), factory.createComplex(right, 0), none)); + PythonLanguage language = PythonLanguage.get(inliningTarget); + throw new UnexpectedResultException(powerNode.execute(frame, PFactory.createComplex(language, left, 0), PFactory.createComplex(language, right, 0), none)); } return Math.pow(left, right); } @@ -416,16 +531,15 @@ static double doDD(VirtualFrame frame, double left, double right, @SuppressWarni @InliningCutoff static Object doDDToComplex(VirtualFrame frame, double left, double right, PNone none, @Bind("this") Node inliningTarget, - @Shared("powCall") @Cached("create(Pow)") LookupAndCallTernaryNode callPow, - @Exclusive @Cached PythonObjectFactory.Lazy factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PyNumberPowerNode powerNode, + @Exclusive @Cached PRaiseNode raiseNode) { if (doSpecialCases(inliningTarget, left, right, raiseNode) == 1) { return 1.0; } if (left < 0 && Double.isFinite(left) && Double.isFinite(right) && (right % 1 != 0)) { // Negative numbers raised to fractional powers become complex. - PythonObjectFactory pof = factory.get(inliningTarget); - return callPow.execute(frame, pof.createComplex(left, 0), pof.createComplex(right, 0), none); + PythonLanguage language = PythonLanguage.get(inliningTarget); + return powerNode.execute(frame, PFactory.createComplex(language, left, 0), PFactory.createComplex(language, right, 0), none); } return Math.pow(left, right); } @@ -435,11 +549,10 @@ static Object doDDToComplex(VirtualFrame frame, double left, double right, PNone static Object doGeneric(VirtualFrame frame, Object left, Object right, Object mod, @Bind("this") Node inliningTarget, @Cached CastToJavaDoubleNode castToJavaDoubleNode, - @Shared("powCall") @Cached("create(Pow)") LookupAndCallTernaryNode callPow, - @Exclusive @Cached PythonObjectFactory.Lazy factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PyNumberPowerNode powerNode, + @Exclusive @Cached PRaiseNode raiseNode) { if (!(mod instanceof PNone)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.POW_3RD_ARG_NOT_ALLOWED_UNLESS_INTEGERS); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.POW_3RD_ARG_NOT_ALLOWED_UNLESS_INTEGERS); } double leftDouble, rightDouble; @@ -449,7 +562,7 @@ static Object doGeneric(VirtualFrame frame, Object left, Object right, Object mo } catch (CannotCastException e) { return PNotImplemented.NOT_IMPLEMENTED; } - return doDDToComplex(frame, leftDouble, rightDouble, PNone.NONE, inliningTarget, callPow, factory, raiseNode); + return doDDToComplex(frame, leftDouble, rightDouble, PNone.NONE, inliningTarget, powerNode, raiseNode); } public static PowNode create() { @@ -470,27 +583,33 @@ protected Object op(double left, double right) { @Slot(value = SlotKind.nb_divmod, isComplex = true) @GenerateNodeFactory abstract static class DivModNode extends AbstractNumericBinaryBuiltin { - @Child private PythonObjectFactory factory = PythonObjectFactory.create(); @Override protected PTuple op(double left, double right) { raiseDivisionByZero(right == 0); - return factory.createTuple(new Object[]{Math.floor(left / right), ModNode.mod(left, right)}); + PythonLanguage language = PythonLanguage.get(this); + return PFactory.createTuple(language, new Object[]{Math.floor(left / right), ModNode.mod(left, right)}); } } - @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_hash, isComplex = true) @GenerateNodeFactory - abstract static class HashNode extends AbstractNumericUnaryBuiltin { - @Override - protected Object op(double self) { - return PyObjectHashNode.hash(self); + abstract static class HashNode extends HashBuiltinNode { + @Specialization + static long doDouble(double num) { + return PyObjectHashNode.hash(num); + } + + @Specialization(replaces = "doDouble") + static long doOther(Object object, + @Bind("this") Node inliningTarget, + @Cached CastToJavaDoubleNode cast) { + return doDouble(castToDoubleChecked(inliningTarget, object, cast)); } } @Builtin(name = "fromhex", minNumOfPositionalArgs = 2, isClassmethod = true) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) public abstract static class FromHexNode extends PythonBuiltinNode { @TruffleBoundary @@ -499,7 +618,7 @@ private double fromHex(String arg) { String str = arg.trim().toLowerCase(); if (str.isEmpty()) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.ValueError, ErrorMessages.INVALID_STRING); + throw PRaiseNode.raiseStatic(this, PythonErrorType.ValueError, ErrorMessages.INVALID_STRING); } else if (str.equals("inf") || str.equals("infinity") || str.equals("+inf") || str.equals("+infinity")) { return Double.POSITIVE_INFINITY; } else if (str.equals("-inf") || str.equals("-infinity")) { @@ -516,7 +635,7 @@ private double fromHex(String arg) { } if (str.isEmpty()) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.ValueError, ErrorMessages.INVALID_STRING); + throw PRaiseNode.raiseStatic(this, PythonErrorType.ValueError, ErrorMessages.INVALID_STRING); } if (!str.startsWith("0x")) { @@ -534,12 +653,12 @@ private double fromHex(String arg) { try { double result = Double.parseDouble(str); if (Double.isInfinite(result)) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.OverflowError, ErrorMessages.HEX_VALUE_TOO_LARGE_AS_FLOAT); + throw PRaiseNode.raiseStatic(this, PythonErrorType.OverflowError, ErrorMessages.HEX_VALUE_TOO_LARGE_AS_FLOAT); } return result; } catch (NumberFormatException ex) { - throw PRaiseNode.raiseUncached(this, PythonErrorType.ValueError, ErrorMessages.INVALID_STRING); + throw PRaiseNode.raiseStatic(this, PythonErrorType.ValueError, ErrorMessages.INVALID_STRING); } } @@ -550,18 +669,18 @@ private double fromHex(String arg) { } @Specialization(guards = "!isPythonBuiltinClass(cl)") - Object fromhexO(Object cl, TruffleString arg, - @Cached("create(T___CALL__)") LookupAndCallVarargsNode constr, + Object fromhexO(VirtualFrame frame, Object cl, TruffleString arg, + @Cached CallNode callNode, @Shared("ts2js") @Cached TruffleString.ToJavaStringNode toJavaStringNode) { double value = fromHex(toJavaStringNode.execute(arg)); - return constr.execute(null, cl, new Object[]{cl, value}); + return callNode.execute(frame, cl, value); } @Fallback @SuppressWarnings("unused") static double fromhex(Object object, Object arg, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); } } @@ -679,14 +798,14 @@ private static double op(double x, int n) { @Specialization static double round(double x, int n, @Bind("this") Node inliningTarget, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { if (Double.isNaN(x) || Double.isInfinite(x) || x == 0.0) { // nans, infinities and zeros round to themselves return x; } double d = op(x, n); if (Double.isInfinite(d)) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.ROUNDED_VALUE_TOO_LARGE); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.ROUNDED_VALUE_TOO_LARGE); } return d; } @@ -696,29 +815,29 @@ static Object round(VirtualFrame frame, Object x, Object n, @Bind("this") Node inliningTarget, @Exclusive @Cached CastToJavaDoubleNode cast, @Cached PyNumberAsSizeNode asSizeNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { return round(castToDoubleChecked(inliningTarget, x, cast), asSizeNode.executeLossy(frame, inliningTarget, n), inliningTarget, raiseNode); } @Specialization static Object round(Object xObj, @SuppressWarnings("unused") PNone none, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Exclusive @Cached CastToJavaDoubleNode cast, @Cached InlinedConditionProfile nanProfile, @Cached InlinedConditionProfile infProfile, @Cached InlinedConditionProfile isLongProfile, - @Cached PythonObjectFactory.Lazy factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { double x = castToDoubleChecked(inliningTarget, xObj, cast); if (nanProfile.profile(inliningTarget, Double.isNaN(x))) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.CANNOT_CONVERT_S_TO_INT, "float NaN"); + throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.CANNOT_CONVERT_S_TO_INT, "float NaN"); } if (infProfile.profile(inliningTarget, Double.isInfinite(x))) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.OverflowError, ErrorMessages.CANNOT_CONVERT_S_TO_INT, "float infinity"); + throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.CANNOT_CONVERT_S_TO_INT, "float infinity"); } double result = round(x, 0, inliningTarget, raiseNode); if (isLongProfile.profile(inliningTarget, result > Long.MAX_VALUE || result < Long.MIN_VALUE)) { - return factory.get(inliningTarget).createInt(toBigInteger(result)); + return PFactory.createInt(language, toBigInteger(result)); } else { return (long) result; } @@ -732,72 +851,70 @@ private static BigInteger toBigInteger(double d) { @GenerateInline @GenerateCached(false) + @GenerateUncached @TypeSystemReference(PFloatUnboxing.class) public abstract static class ComparisonHelperNode extends Node { - @FunctionalInterface - interface Op { - boolean compute(double a, double b); - } - - abstract Object execute(Node inliningTarget, Object left, Object right, Op op); + abstract Object execute(Node inliningTarget, Object left, Object right, RichCmpOp op); @Specialization - static boolean doDD(double a, double b, Op op) { - return op.compute(a, b); + static boolean doDD(double a, double b, RichCmpOp op) { + return op.compare(a, b); } @Specialization - static boolean doDI(double a, int b, Op op) { - return op.compute(a, b); + static boolean doDI(double a, int b, RichCmpOp op) { + return op.compare(a, b); } @Specialization(guards = "check.execute(inliningTarget, bObj)", replaces = "doDD", limit = "1") @InliningCutoff - static boolean doOO(Node inliningTarget, Object aObj, Object bObj, Op op, + static boolean doOO(Node inliningTarget, Object aObj, Object bObj, RichCmpOp op, @SuppressWarnings("unused") @Cached PyFloatCheckNode check, @Exclusive @Cached CastToJavaDoubleNode cast) { double a = castToDoubleChecked(inliningTarget, aObj, cast); double b = castToDoubleChecked(inliningTarget, bObj, cast); - return op.compute(a, b); + return op.compare(a, b); } @Specialization(replaces = "doDI") @InliningCutoff - static boolean doOI(Node inliningTarget, Object aObj, int b, Op op, + static boolean doOI(Node inliningTarget, Object aObj, int b, RichCmpOp op, @Shared @Cached CastToJavaDoubleNode cast) { double a = castToDoubleChecked(inliningTarget, aObj, cast); - return op.compute(a, b); + return op.compare(a, b); } @Specialization @InliningCutoff - static boolean doOL(Node inliningTarget, Object aObj, long b, Op op, + static boolean doOL(Node inliningTarget, Object aObj, long b, RichCmpOp op, @Exclusive @Cached CastToJavaDoubleNode cast, @Cached InlinedConditionProfile longFitsToDoubleProfile) { double a = castToDoubleChecked(inliningTarget, aObj, cast); - return op.compute(compareDoubleToLong(inliningTarget, a, b, longFitsToDoubleProfile), 0.0); + double a1 = compareDoubleToLong(inliningTarget, a, b, longFitsToDoubleProfile); + return op.compare(a1, 0.0); } @Specialization @InliningCutoff - static boolean doOPInt(Node inliningTarget, Object aObj, PInt b, Op op, + static boolean doOPInt(Node inliningTarget, Object aObj, PInt b, RichCmpOp op, @Shared @Cached CastToJavaDoubleNode cast) { double a = castToDoubleChecked(inliningTarget, aObj, cast); - return op.compute(compareDoubleToLargeInt(a, b), 0.0); + double a1 = compareDoubleToLargeInt(a, b); + return op.compare(a1, 0.0); } @Specialization @InliningCutoff - static boolean doOB(Node inliningTarget, Object aObj, boolean b, Op op, + static boolean doOB(Node inliningTarget, Object aObj, boolean b, RichCmpOp op, @Shared @Cached CastToJavaDoubleNode cast) { double a = castToDoubleChecked(inliningTarget, aObj, cast); - return op.compute(a, b ? 1 : 0); + return op.compare(a, b ? 1 : 0); } @Fallback @SuppressWarnings("unused") - static PNotImplemented fallback(Object a, Object b, Op op) { + static PNotImplemented fallback(Object a, Object b, RichCmpOp op) { return PNotImplemented.NOT_IMPLEMENTED; } @@ -837,69 +954,15 @@ private static double compareUsingBigDecimal(double v, BigInteger w) { } } - @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class EqNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doIt(Object left, Object right, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode comparisonHelperNode) { - return comparisonHelperNode.execute(inliningTarget, left, right, (a, b) -> a == b); - } - } - - @Builtin(name = J___NE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class NeNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doIt(Object left, Object right, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode comparisonHelperNode) { - return comparisonHelperNode.execute(inliningTarget, left, right, (a, b) -> a != b); - } - } - - @Builtin(name = J___LT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class LtNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doIt(Object left, Object right, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode comparisonHelperNode) { - return comparisonHelperNode.execute(inliningTarget, left, right, (a, b) -> a < b); - } - } - - @Builtin(name = J___LE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class LeNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doIt(Object left, Object right, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode comparisonHelperNode) { - return comparisonHelperNode.execute(inliningTarget, left, right, (a, b) -> a <= b); - } - } - - @Builtin(name = J___GT__, minNumOfPositionalArgs = 2) + @Slot(SlotKind.tp_richcompare) @GenerateNodeFactory - public abstract static class GtNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doIt(Object left, Object right, - @Bind("this") Node inliningTarget, - @Cached ComparisonHelperNode comparisonHelperNode) { - return comparisonHelperNode.execute(inliningTarget, left, right, (a, b) -> a > b); - } - } - - @Builtin(name = J___GE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class GeNode extends PythonBinaryBuiltinNode { + @GenerateUncached + public abstract static class EqNode extends TpSlotRichCompare.RichCmpBuiltinNode { @Specialization - static Object doIt(Object left, Object right, + static Object doIt(Object left, Object right, RichCmpOp op, @Bind("this") Node inliningTarget, @Cached ComparisonHelperNode comparisonHelperNode) { - return comparisonHelperNode.execute(inliningTarget, left, right, (a, b) -> a >= b); + return comparisonHelperNode.execute(inliningTarget, left, right, op); } } @@ -919,7 +982,6 @@ protected Object op(double arg) { @Builtin(name = J___FLOOR__, minNumOfPositionalArgs = 1) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class FloorNode extends PythonUnaryBuiltinNode { @Specialization static Object floor(Object self, @@ -932,7 +994,6 @@ static Object floor(Object self, @Builtin(name = J___CEIL__, minNumOfPositionalArgs = 1) @GenerateNodeFactory - @TypeSystemReference(PythonArithmeticTypes.class) abstract static class CeilNode extends PythonUnaryBuiltinNode { @Specialization static Object ceil(Object self, @@ -966,17 +1027,17 @@ abstract static class AsIntegerRatio extends PythonUnaryBuiltinNode { @Specialization static PTuple get(Object selfObj, @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, @Cached CastToJavaDoubleNode cast, @Cached InlinedConditionProfile nanProfile, @Cached InlinedConditionProfile infProfile, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { double self = castToDoubleChecked(inliningTarget, selfObj, cast); if (nanProfile.profile(inliningTarget, Double.isNaN(self))) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.CANNOT_CONVERT_S_TO_INT_RATIO, "NaN"); + throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.CANNOT_CONVERT_S_TO_INT_RATIO, "NaN"); } if (infProfile.profile(inliningTarget, Double.isInfinite(self))) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.OverflowError, ErrorMessages.CANNOT_CONVERT_S_TO_INT_RATIO, "Infinity"); + throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.CANNOT_CONVERT_S_TO_INT_RATIO, "Infinity"); } // At the first time find mantissa and exponent. This is functionality of @@ -1010,11 +1071,11 @@ static PTuple get(Object selfObj, } // count the ratio - return factory.createTuple(countIt(mantissa, exponent)); + return PFactory.createTuple(language, countIt(language, mantissa, exponent)); } @TruffleBoundary - private static Object[] countIt(double mantissa, int exponent) { + private static Object[] countIt(PythonLanguage language, double mantissa, int exponent) { double m = mantissa; int e = exponent; for (int i = 0; i < 300 && Double.compare(m, Math.floor(m)) != 0; i++) { @@ -1033,8 +1094,7 @@ private static Object[] countIt(double mantissa, int exponent) { if (numerator.bitLength() < Long.SIZE && denominator.bitLength() < Long.SIZE) { return new Object[]{numerator.longValue(), denominator.longValue()}; } - PythonObjectFactory factory = PythonObjectFactory.getUncached(); - return new Object[]{factory.createInt(numerator), factory.createInt(denominator)}; + return new Object[]{PFactory.createInt(language, numerator), PFactory.createInt(language, denominator)}; } } @@ -1078,8 +1138,8 @@ static TruffleString getFormat(@SuppressWarnings("unused") Object cls, @Suppress @Fallback static TruffleString getFormat(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") Object typeStr, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonErrorType.ValueError, ErrorMessages.ARG_D_MUST_BE_S_OR_S, "__getformat__()", 1, "double", "float"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.ValueError, ErrorMessages.ARG_D_MUST_BE_S_OR_S, "__getformat__()", 1, "double", "float"); } @Override @@ -1100,11 +1160,10 @@ protected Object op(double value) { @Builtin(name = J___GETNEWARGS__, minNumOfPositionalArgs = 1) @GenerateNodeFactory abstract static class GetNewArgsNode extends AbstractNumericUnaryBuiltin { - @Child private PythonObjectFactory factory = PythonObjectFactory.create(); - @Override protected Object op(double self) { - return factory.createTuple(new Object[]{factory.createFloat(self)}); + PythonLanguage language = PythonLanguage.get(this); + return PFactory.createTuple(language, new Object[]{PFactory.createFloat(language, self)}); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/PFloat.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/PFloat.java index 4c66a4af24..6205c8c21b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/PFloat.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/PFloat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2014, Regents of the University of California * * All rights reserved. @@ -26,13 +26,10 @@ // skip GIL package com.oracle.graal.python.builtins.objects.floats; -import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; - import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.library.CachedLibrary; @@ -40,7 +37,6 @@ import com.oracle.truffle.api.library.ExportMessage; import com.oracle.truffle.api.library.ExportMessage.Ignore; import com.oracle.truffle.api.object.Shape; -import com.oracle.truffle.api.strings.TruffleString; @SuppressWarnings("truffle-abstract-export") @ExportLibrary(InteropLibrary.class) @@ -86,30 +82,19 @@ public static PFloat create(Object cls, Shape instanceShape, double value) { return new PFloat(cls, instanceShape, value); } - @TruffleBoundary - public static TruffleString doubleToString(double item) { - String d = Double.toString(item); - int exp = d.indexOf("E"); - if (exp != -1) { - int l = d.length() - 1; - if (exp == (l - 2)) { - if (d.charAt(exp + 1) == '-') { - if (Integer.valueOf(d.charAt(l) + "") == 4) { - /*- Java convert double when 0.000###... while Python does it when 0.0000####... */ - d = Double.toString((item * 10)).replace(".", ".0"); - } else { - d = d.substring(0, l) + "0" + d.substring(l); - } - - exp = d.indexOf("E"); - } - } - if (exp != -1 && d.charAt(exp + 1) != '-') { - d = d.substring(0, exp + 1) + "+" + d.substring(exp + 1, l + 1); - } - d = d.toLowerCase(); - } - return toTruffleStringUncached(d); + public static int compare(double x, double y) { + return (x < y) ? -1 : ((x == y) ? 0 : 1); + } + + /** + * CPython does identity check in {@code PyObject_RichCompareBool}. We do not really have + * identity for doubles, so we cannot say if NaNs, which are by definition not equal + * (PyObjectRichCompare always returns false for NaN and NaN), are identical or not. So we + * choose that all NaNs with equal bit patterns are identical. This method should be used in + * places which use {@code PyObject_RichCompareBool} in CPython. + */ + public static boolean areIdentical(double x, double y) { + return x == y || Double.doubleToRawLongBits(x) == Double.doubleToRawLongBits(y); } @ExportMessage diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignAbstractClassBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignAbstractClassBuiltins.java index 48cfd68373..cbc0b82c5f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignAbstractClassBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignAbstractClassBuiltins.java @@ -26,6 +26,12 @@ package com.oracle.graal.python.builtins.objects.foreign; +import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___BASES__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INSTANCECHECK__; + +import java.util.List; + +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -34,9 +40,9 @@ import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.runtime.GilNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.util.PythonUtils; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; @@ -45,11 +51,6 @@ import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.library.CachedLibrary; -import java.util.List; - -import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___BASES__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INSTANCECHECK__; - /* * NOTE: We are not using IndirectCallContext here in this file * because it seems unlikely that these interop messages would call back to Python @@ -68,8 +69,8 @@ protected List> getNodeFa abstract static class BasesNode extends PythonUnaryBuiltinNode { @Specialization static Object getBases(Object self, - @Cached PythonObjectFactory factory) { - return factory.createTuple(PythonUtils.EMPTY_OBJECT_ARRAY); + @Bind PythonLanguage language) { + return PFactory.createEmptyTuple(language); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignBooleanBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignBooleanBuiltins.java index dd2ec3943d..a3f22962e9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignBooleanBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignBooleanBuiltins.java @@ -26,14 +26,10 @@ package com.oracle.graal.python.builtins.objects.foreign; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__; - import java.util.List; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; -import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; @@ -114,8 +110,8 @@ protected static int doIt(Object object, } } - @Builtin(name = J___STR__, minNumOfPositionalArgs = 1) - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_str, isComplex = true) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class StrNode extends PythonUnaryBuiltinNode { @Specialization diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignExecutableBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignExecutableBuiltins.java index b9c054c701..2f7c3644de 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignExecutableBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignExecutableBuiltins.java @@ -26,25 +26,32 @@ package com.oracle.graal.python.builtins.objects.foreign; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__; +import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___DOC__; +import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___NAME__; +import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__; import java.util.List; import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode; import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext; import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.exception.PythonErrorType; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -54,6 +61,7 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ArityException; import com.oracle.truffle.api.interop.InteropLibrary; +import com.oracle.truffle.api.interop.UnknownIdentifierException; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.interop.UnsupportedTypeException; import com.oracle.truffle.api.library.CachedLibrary; @@ -61,22 +69,70 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.ForeignExecutable) public final class ForeignExecutableBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = ForeignExecutableBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return ForeignExecutableBuiltinsFactory.getFactories(); } - @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true) + @Builtin(name = J___NAME__, minNumOfPositionalArgs = 1, isGetter = true) + @GenerateNodeFactory + public abstract static class NameNode extends PythonUnaryBuiltinNode { + @Specialization + static Object getName(Object self, + @Bind("this") Node inliningTarget, + @Cached PRaiseNode raiseNode, + @Cached PForeignToPTypeNode toPythonNode, + @CachedLibrary(limit = "2") InteropLibrary lib) { + try { + if (lib.isMemberReadable(self, J___NAME__)) { + return toPythonNode.executeConvert(lib.readMember(self, J___NAME__)); + } else if (lib.hasExecutableName(self)) { + return toPythonNode.executeConvert(lib.getExecutableName(self)); + } else { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, self, T___NAME__); + } + } catch (UnsupportedMessageException | UnknownIdentifierException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + } + + @Builtin(name = J___DOC__, minNumOfPositionalArgs = 1, isGetter = true) + @GenerateNodeFactory + public abstract static class DocNode extends PythonUnaryBuiltinNode { + @Specialization + static Object getName(Object self, + @Bind("this") Node inliningTarget, + @Cached PRaiseNode raiseNode, + @Cached PForeignToPTypeNode toPythonNode, + @CachedLibrary(limit = "2") InteropLibrary lib) { + if (lib.isMemberReadable(self, J___DOC__)) { + try { + return toPythonNode.executeConvert(lib.readMember(self, J___DOC__)); + } catch (UnsupportedMessageException | UnknownIdentifierException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } else { + return PNone.NONE; + } + } + } + + @Slot(value = SlotKind.tp_call, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true) @GenerateNodeFactory public abstract static class CallNode extends PythonBuiltinNode { @Specialization static Object doInteropCall(VirtualFrame frame, Object callee, Object[] arguments, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, + @Bind("this") Node inliningTarget, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary(limit = "4") InteropLibrary lib, @Cached PForeignToPTypeNode toPTypeNode, @Cached GilNode gil, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { PythonContext context = PythonContext.get(inliningTarget); PythonLanguage language = context.getLanguage(inliningTarget); try { @@ -89,7 +145,7 @@ static Object doInteropCall(VirtualFrame frame, Object callee, Object[] argument IndirectCallContext.exit(frame, language, context, state); } } catch (ArityException | UnsupportedTypeException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ); } catch (UnsupportedMessageException e) { throw CompilerDirectives.shouldNotReachHere(e); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignInstantiableBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignInstantiableBuiltins.java index 2e259e80ca..d6fead055e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignInstantiableBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignInstantiableBuiltins.java @@ -26,16 +26,16 @@ package com.oracle.graal.python.builtins.objects.foreign; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; - import java.util.List; import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; @@ -62,13 +62,17 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.ForeignInstantiable) public final class ForeignInstantiableBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = ForeignInstantiableBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return ForeignInstantiableBuiltinsFactory.getFactories(); } - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true) - @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true) + @Slot(value = SlotKind.tp_call, isComplex = true) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true) @GenerateNodeFactory public abstract static class CallNode extends PythonBuiltinNode { @Specialization @@ -78,7 +82,7 @@ static Object doInteropCall(VirtualFrame frame, Object callee, Object[] argument @CachedLibrary(limit = "4") InteropLibrary lib, @Cached PForeignToPTypeNode toPTypeNode, @Cached GilNode gil, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { PythonContext context = PythonContext.get(inliningTarget); PythonLanguage language = context.getLanguage(inliningTarget); try { @@ -91,7 +95,7 @@ static Object doInteropCall(VirtualFrame frame, Object callee, Object[] argument IndirectCallContext.exit(frame, language, context, state); } } catch (ArityException | UnsupportedTypeException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ); } catch (UnsupportedMessageException e) { throw CompilerDirectives.shouldNotReachHere(e); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignIterableBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignIterableBuiltins.java index 647eee6b2f..f7e2711f0e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignIterableBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignIterableBuiltins.java @@ -26,14 +26,14 @@ package com.oracle.graal.python.builtins.objects.foreign; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; - import java.util.List; -import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode; @@ -55,12 +55,14 @@ */ @CoreFunctions(extendClasses = PythonBuiltinClassType.ForeignIterable) public final class ForeignIterableBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = ForeignIterableBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return ForeignIterableBuiltinsFactory.getFactories(); } - @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iter, isComplex = true) @GenerateNodeFactory public abstract static class IterNode extends PythonUnaryBuiltinNode { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignNumberBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignNumberBuiltins.java index fdc2923be2..ae0430d70a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignNumberBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignNumberBuiltins.java @@ -28,71 +28,71 @@ import static com.oracle.graal.python.builtins.objects.str.StringUtils.simpleTruffleStringFormatUncached; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CEIL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___FLOOR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___POW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ROUND__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RPOW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___TRUNC__; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.PythonAbstractObject; import com.oracle.graal.python.builtins.objects.foreign.ForeignObjectBuiltins.ForeignGetattrNode; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins; import com.oracle.graal.python.builtins.objects.object.ObjectNodes; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.GetAttrBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotInquiry.NbBoolBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare; import com.oracle.graal.python.lib.PyNumberAbsoluteNode; import com.oracle.graal.python.lib.PyNumberAddNode; import com.oracle.graal.python.lib.PyNumberAndNode; import com.oracle.graal.python.lib.PyNumberDivmodNode; +import com.oracle.graal.python.lib.PyNumberFloatNode; import com.oracle.graal.python.lib.PyNumberFloorDivideNode; import com.oracle.graal.python.lib.PyNumberInvertNode; +import com.oracle.graal.python.lib.PyNumberLongNode; import com.oracle.graal.python.lib.PyNumberLshiftNode; import com.oracle.graal.python.lib.PyNumberMultiplyNode; import com.oracle.graal.python.lib.PyNumberNegativeNode; import com.oracle.graal.python.lib.PyNumberOrNode; import com.oracle.graal.python.lib.PyNumberPositiveNode; +import com.oracle.graal.python.lib.PyNumberPowerNode; import com.oracle.graal.python.lib.PyNumberRemainderNode; import com.oracle.graal.python.lib.PyNumberRshiftNode; import com.oracle.graal.python.lib.PyNumberSubtractNode; import com.oracle.graal.python.lib.PyNumberTrueDivideNode; import com.oracle.graal.python.lib.PyNumberXorNode; +import com.oracle.graal.python.lib.PyObjectRichCompare; import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode; +import com.oracle.graal.python.lib.RichCmpOp; +import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.SpecialMethodNames; import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode; -import com.oracle.graal.python.nodes.expression.BinaryArithmetic; +import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; +import com.oracle.graal.python.nodes.call.special.SpecialMethodNotFound; import com.oracle.graal.python.nodes.expression.BinaryOpNode; -import com.oracle.graal.python.nodes.expression.UnaryArithmetic; import com.oracle.graal.python.nodes.expression.UnaryOpNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.IsForeignObjectNode; import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -169,13 +169,13 @@ long doLong(Object obj, @Specialization(guards = {"!lib.fitsInLong(obj)", "lib.fitsInBigInteger(obj)"}) PInt doBigInt(Object obj, + @Bind PythonLanguage language, @Shared @CachedLibrary(limit = "3") InteropLibrary lib, - @Shared @Cached(inline = false) GilNode gil, - @Cached(inline = false) PythonObjectFactory factory) { + @Shared @Cached(inline = false) GilNode gil) { assert !lib.isBoolean(obj); gil.release(true); try { - return factory.createInt(lib.asBigInteger(obj)); + return PFactory.createInt(language, lib.asBigInteger(obj)); } catch (UnsupportedMessageException e) { throw CompilerDirectives.shouldNotReachHere(e); } finally { @@ -265,11 +265,8 @@ Object doGeneric(VirtualFrame frame, Object value, @Bind("this") Node inliningTarget, @Cached UnboxNode unboxNode) { Object unboxed = unboxNode.execute(inliningTarget, value); - if (unboxed != null) { - return op.executeCached(frame, unboxed); - } else { - return PNotImplemented.NOT_IMPLEMENTED; - } + assert unboxed != null; + return op.execute(frame, unboxed); } } @@ -289,9 +286,9 @@ Object doGeneric(VirtualFrame frame, Object left, Object right, Object unboxed = unboxNode.execute(inliningTarget, left); if (unboxed != null) { if (!reverse) { - return op.executeObject(frame, unboxed, right); + return op.execute(frame, unboxed, right); } else { - return op.executeObject(frame, right, unboxed); + return op.execute(frame, right, unboxed); } } else { return PNotImplemented.NOT_IMPLEMENTED; @@ -321,7 +318,7 @@ static Object doIt(VirtualFrame frame, Node inliningTarget, Object left, Object if (newLeft == null || newRight == null) { return PNotImplemented.NOT_IMPLEMENTED; } - return op.executeObject(frame, newLeft, newRight); + return op.execute(frame, newLeft, newRight); } } @@ -390,7 +387,7 @@ abstract static class AbsNode extends ForeignUnaryNode { @GenerateNodeFactory abstract static class CeilNode extends ForeignUnaryNode { CeilNode() { - super(UnaryArithmetic.GenericUnaryArithmeticNode.create(SpecialMethodNames.T___CEIL__)); + super(LookupAndCallUnaryNode.create(SpecialMethodNames.T___CEIL__)); } } @@ -398,7 +395,7 @@ abstract static class CeilNode extends ForeignUnaryNode { @GenerateNodeFactory abstract static class FloorNode extends ForeignUnaryNode { FloorNode() { - super(UnaryArithmetic.GenericUnaryArithmeticNode.create(SpecialMethodNames.T___FLOOR__)); + super(LookupAndCallUnaryNode.create(SpecialMethodNames.T___FLOOR__)); } } @@ -406,23 +403,33 @@ abstract static class FloorNode extends ForeignUnaryNode { @GenerateNodeFactory abstract static class TruncNode extends ForeignUnaryNode { TruncNode() { - super(UnaryArithmetic.GenericUnaryArithmeticNode.create(SpecialMethodNames.T___TRUNC__)); + super(LookupAndCallUnaryNode.create(SpecialMethodNames.T___TRUNC__)); } } @Slot(value = SlotKind.nb_int, isComplex = true) @GenerateNodeFactory - abstract static class IntNode extends ForeignUnaryNode { - IntNode() { - super(UnaryArithmetic.GenericUnaryArithmeticNode.create(SpecialMethodNames.T___INT__)); + abstract static class IntNode extends PythonUnaryBuiltinNode { + @Specialization + Object doGeneric(VirtualFrame frame, Object self, + @Bind("this") Node inliningTarget, + @Cached UnboxNode unboxNode, + @Cached PyNumberLongNode longNode) { + Object unboxed = unboxNode.execute(inliningTarget, self); + return longNode.execute(frame, inliningTarget, unboxed); } } @Slot(value = SlotKind.nb_float, isComplex = true) @GenerateNodeFactory - abstract static class FloatNode extends ForeignUnaryNode { - FloatNode() { - super(UnaryArithmetic.GenericUnaryArithmeticNode.create(SpecialMethodNames.T___FLOAT__)); + abstract static class FloatNode extends PythonUnaryBuiltinNode { + @Specialization + Object doGeneric(VirtualFrame frame, Object self, + @Bind("this") Node inliningTarget, + @Cached UnboxNode unboxNode, + @Cached PyNumberFloatNode floatNode) { + Object unboxed = unboxNode.execute(inliningTarget, self); + return floatNode.execute(frame, inliningTarget, unboxed); } } @@ -570,87 +577,65 @@ static Object doIt(VirtualFrame frame, Object left, Object right, } } - @Builtin(name = J___POW__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class PowNode extends ForeignBinaryNode { - PowNode() { - super(BinaryArithmetic.Pow.create(), false); - } - } - - @Builtin(name = J___RPOW__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.nb_power, isComplex = true) @GenerateNodeFactory - abstract static class RPowNode extends ForeignBinaryNode { - RPowNode() { - super(BinaryArithmetic.Pow.create(), true); - } - } - - @Builtin(name = J___ROUND__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class RoundNode extends ForeignBinaryNode { - RoundNode() { - super(BinaryArithmetic.GenericBinaryArithmeticNode.create(SpecialMethodSlot.Round), false); - } - } - - public abstract static class ForeignBinaryComparisonNode extends PythonBinaryBuiltinNode { - @Child private LookupAndCallBinaryNode comparisonNode; - - protected ForeignBinaryComparisonNode(SpecialMethodSlot slot, SpecialMethodSlot rslot) { - this.comparisonNode = LookupAndCallBinaryNode.create(slot, rslot, true, true); - } + abstract static class PowNode extends PythonTernaryBuiltinNode { @Specialization - Object doComparison(VirtualFrame frame, Object left, Object right, + static Object doIt(VirtualFrame frame, Object v, Object w, Object z, @Bind("this") Node inliningTarget, - @Cached UnboxNode unboxNode) { - Object unboxed = unboxNode.execute(inliningTarget, left); - if (unboxed != null) { - return comparisonNode.executeObject(frame, unboxed, right); - } else { + @Cached UnboxNode unboxV, + @Cached UnboxNode unboxW, + @Cached UnboxNode unboxZ, + @Cached PyNumberPowerNode power) { + v = unboxV.execute(inliningTarget, v); + w = unboxW.execute(inliningTarget, w); + if (!(z instanceof PNone)) { + z = unboxZ.execute(inliningTarget, z); + } + if (v == null || w == null || z == null) { return PNotImplemented.NOT_IMPLEMENTED; } + return power.execute(frame, v, w, z); } } - @Builtin(name = J___LT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class LtNode extends ForeignBinaryComparisonNode { - protected LtNode() { - super(SpecialMethodSlot.Lt, SpecialMethodSlot.Gt); - } - } - - @Builtin(name = J___LE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class LeNode extends ForeignBinaryComparisonNode { - protected LeNode() { - super(SpecialMethodSlot.Le, SpecialMethodSlot.Ge); - } - } - - @Builtin(name = J___GT__, minNumOfPositionalArgs = 2) + @Builtin(name = J___ROUND__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2) @GenerateNodeFactory - public abstract static class GtNode extends ForeignBinaryComparisonNode { - protected GtNode() { - super(SpecialMethodSlot.Gt, SpecialMethodSlot.Lt); - } - } + abstract static class RoundNode extends PythonBinaryBuiltinNode { - @Builtin(name = J___GE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class GeNode extends ForeignBinaryComparisonNode { - protected GeNode() { - super(SpecialMethodSlot.Ge, SpecialMethodSlot.Le); + @Specialization + Object doGeneric(VirtualFrame frame, Object self, Object n, + @Bind("this") Node inliningTarget, + @Cached UnboxNode unboxNode, + @Cached("create(T___ROUND__)") LookupAndCallBinaryNode callRound) { + Object unboxed = unboxNode.execute(inliningTarget, self); + try { + return callRound.executeObject(frame, unboxed, n); + } catch (SpecialMethodNotFound ignore) { + throw CompilerDirectives.shouldNotReachHere(); + } } } - @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.tp_richcompare, isComplex = true) @GenerateNodeFactory - public abstract static class EqNode extends ForeignBinaryComparisonNode { - protected EqNode() { - super(SpecialMethodSlot.Eq, SpecialMethodSlot.Eq); + public abstract static class ForeignBinaryComparisonNode extends TpSlotRichCompare.RichCmpBuiltinNode { + @Specialization + Object doComparison(VirtualFrame frame, Object left, Object right, RichCmpOp op, + @Bind("this") Node inliningTarget, + @Cached UnboxNode unboxNode, + @Cached IsBuiltinObjectProfile exProfile, + @Cached PyObjectRichCompare richCompareNode) { + Object unboxed = unboxNode.execute(inliningTarget, left); + if (unboxed != null) { + try { + return richCompareNode.execute(frame, inliningTarget, unboxed, right, op); + } catch (PException ex) { + ex.expect(inliningTarget, PythonBuiltinClassType.TypeError, exProfile); + } + } + return PNotImplemented.NOT_IMPLEMENTED; } } @@ -659,10 +644,10 @@ protected EqNode() { abstract static class IndexNode extends PythonUnaryBuiltinNode { @Specialization(limit = "3") protected static Object doIt(Object object, + @Bind("this") Node inliningTarget, @Cached PRaiseNode raiseNode, @CachedLibrary("object") InteropLibrary lib, - @Cached GilNode gil, - @Cached PythonObjectFactory factory) { + @Cached GilNode gil) { assert !lib.isBoolean(object); gil.release(true); try { @@ -685,20 +670,20 @@ protected static Object doIt(Object object, if (lib.fitsInBigInteger(object)) { try { var big = lib.asBigInteger(object); - return factory.createInt(big); + return PFactory.createInt(PythonLanguage.get(inliningTarget), big); } catch (UnsupportedMessageException e) { CompilerDirectives.transferToInterpreterAndInvalidate(); throw new IllegalStateException("foreign value claims to be a big integer but isn't"); } } - throw raiseNode.raiseIntegerInterpretationError(object); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, object); } finally { gil.acquire(); } } } - @Builtin(name = J___STR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_str, isComplex = true) @GenerateNodeFactory abstract static class StrNode extends PythonUnaryBuiltinNode { @Child private TruffleString.SwitchEncodingNode switchEncodingNode; @@ -735,7 +720,7 @@ protected TruffleString defaultConversion(VirtualFrame frame, InteropLibrary lib } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends StrNode { @Child private ObjectNodes.DefaultObjectReprNode defaultReprNode; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignObjectBuiltins.java index ea386f7fed..ec35c37e72 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignObjectBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignObjectBuiltins.java @@ -30,9 +30,6 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; import static com.oracle.graal.python.builtins.objects.str.StringUtils.simpleTruffleStringFormatUncached; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___DIR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import java.util.List; @@ -46,16 +43,24 @@ import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PythonAbstractObject; +import com.oracle.graal.python.builtins.objects.list.ListBuiltins; +import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins; import com.oracle.graal.python.builtins.objects.object.ObjectNodes; +import com.oracle.graal.python.builtins.objects.set.PSet; +import com.oracle.graal.python.builtins.objects.set.SetNodes; import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; +import com.oracle.graal.python.builtins.objects.type.TypeBuiltins; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.GetAttrBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSetAttr.SetAttrBuiltinNode; +import com.oracle.graal.python.lib.PyObjectReprAsObjectNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; +import com.oracle.graal.python.nodes.builtins.ListNodes; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode; @@ -68,7 +73,6 @@ import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -83,12 +87,14 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ArityException; import com.oracle.truffle.api.interop.InteropLibrary; +import com.oracle.truffle.api.interop.InvalidArrayIndexException; import com.oracle.truffle.api.interop.UnknownIdentifierException; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.interop.UnsupportedTypeException; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleString; /* @@ -106,11 +112,11 @@ protected List> getNodeFa return ForeignObjectBuiltinsFactory.getFactories(); } - @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_hash, isComplex = true) @GenerateNodeFactory - abstract static class HashNode extends PythonUnaryBuiltinNode { + abstract static class HashNode extends HashBuiltinNode { @Specialization(limit = "getCallSiteInlineCacheMaxDepth()") - static int hash(Object self, + static long hash(Object self, @CachedLibrary("self") InteropLibrary library) { if (library.hasIdentity(self)) { try { @@ -168,14 +174,14 @@ static Object doIt(Node inliningTarget, Object object, Object memberObj, @Cached(inline = false) CastToJavaStringNode castToString, @Cached(inline = false) GilNode gil, @Cached(inline = false) PForeignToPTypeNode toPythonNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { gil.release(true); try { String member; try { member = castToString.execute(memberObj); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, memberObj); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, memberObj); } if (read.isMemberReadable(object, member)) { @@ -197,7 +203,7 @@ static Object doIt(Node inliningTarget, Object object, Object memberObj, } finally { gil.acquire(); } - throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.FOREIGN_OBJ_HAS_NO_ATTR_S, memberObj); + throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.FOREIGN_OBJ_HAS_NO_ATTR_S, memberObj); } } @@ -211,13 +217,13 @@ static void doSet(Object object, Object key, Object value, @Shared @CachedLibrary(limit = "3") InteropLibrary lib, @Shared @Cached CastToJavaStringNode castToString, @Shared @Cached GilNode gil, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { gil.release(true); String member; try { member = castToString.execute(key); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, key); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, key); } try { try { @@ -240,11 +246,11 @@ static void doSet(Object object, Object key, Object value, } } } catch (UnsupportedTypeException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.INVALID_TYPE_FOR_S, key); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.INVALID_TYPE_FOR_S, key); } finally { gil.acquire(); } - throw raiseNode.get(inliningTarget).raise(PythonErrorType.AttributeError, ErrorMessages.FOREIGN_OBJ_HAS_NO_ATTR_S, key); + throw raiseNode.raise(inliningTarget, PythonErrorType.AttributeError, ErrorMessages.FOREIGN_OBJ_HAS_NO_ATTR_S, key); } @Specialization(guards = "isNoValue(value)") @@ -253,68 +259,92 @@ static void doDelete(Object object, Object key, @SuppressWarnings("unused") PNon @Shared @CachedLibrary(limit = "3") InteropLibrary lib, @Shared @Cached CastToJavaStringNode castToString, @Shared @Cached GilNode gil, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { gil.release(true); try { lib.removeMember(object, castToString.execute(key)); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, key); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, key); } catch (UnknownIdentifierException | UnsupportedMessageException e) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.AttributeError, ErrorMessages.FOREIGN_OBJ_HAS_NO_ATTR_S, key); + throw raiseNode.raise(inliningTarget, PythonErrorType.AttributeError, ErrorMessages.FOREIGN_OBJ_HAS_NO_ATTR_S, key); } finally { gil.acquire(); } } } - // TODO dir(foreign) should list both foreign object members and attributes from class @Builtin(name = J___DIR__, minNumOfPositionalArgs = 1) @GenerateNodeFactory abstract static class DirNode extends PythonUnaryBuiltinNode { @Specialization - protected Object doIt(Object object, + protected Object doIt(VirtualFrame frame, Object object, @Bind("this") Node inliningTarget, @CachedLibrary(limit = "3") InteropLibrary lib, + @CachedLibrary(limit = "3") InteropLibrary arrayInterop, + @CachedLibrary(limit = "3") InteropLibrary stringInterop, + @Cached TruffleString.SwitchEncodingNode switchEncodingNode, @Cached GilNode gil, - @Cached PythonObjectFactory.Lazy factory) { - if (lib.hasMembers(object)) { + @Cached InlinedConditionProfile profile, + @Cached GetClassNode getClassNode, + @Cached TypeBuiltins.DirNode typeDirNode, + @Cached SetNodes.AddNode addNode, + @Cached(inline = false) ListBuiltins.ListSortNode sortNode, + @Cached(inline = false) ListNodes.ConstructListNode constructListNode) { + // Inspired by ObjectBuiltins.DirNode + var pythonClass = getClassNode.execute(inliningTarget, object); + PSet attributes = typeDirNode.execute(frame, pythonClass); + + if (profile.profile(inliningTarget, lib.hasMembers(object))) { + final Object members; gil.release(true); try { - return lib.getMembers(object); + members = lib.getMembers(object); } catch (UnsupportedMessageException e) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw new IllegalStateException("foreign object claims to have members, but does not return them"); + throw CompilerDirectives.shouldNotReachHere("foreign object claims to have members, but does not return them"); } finally { gil.acquire(); } - } else { - return factory.get(inliningTarget).createList(); + + try { + long size = arrayInterop.getArraySize(members); + for (int i = 0; i < size; i++) { + TruffleString memberString = stringInterop.asTruffleString(arrayInterop.readArrayElement(members, i)); + memberString = switchEncodingNode.execute(memberString, TS_ENCODING); + addNode.execute(frame, attributes, memberString); + } + } catch (UnsupportedMessageException | InvalidArrayIndexException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } } + + // set to sorted list, like in PyObjectDir + PList list = constructListNode.execute(frame, attributes); + sortNode.execute(frame, list); + return list; } } - @Builtin(name = J___STR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_str, isComplex = true) @GenerateNodeFactory abstract static class StrNode extends PythonUnaryBuiltinNode { @Child private TruffleString.SwitchEncodingNode switchEncodingNode; + private static final TpSlot FOREIGN_REPR = SLOTS.tp_repr(); + @Specialization Object str(VirtualFrame frame, Object object, @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached(parameters = "T___REPR__") LookupAttributeInMRONode lookupAttributeInMRONode, - @Cached(parameters = "Repr") LookupAndCallUnaryNode reprNode, + @Cached GetObjectSlotsNode getSlots, + @Cached PyObjectReprAsObjectNode reprNode, @CachedLibrary(limit = "3") InteropLibrary lib, @Cached ObjectNodes.DefaultObjectReprNode defaultReprNode, @Cached InlinedBranchProfile isIterator, @Cached InlinedBranchProfile defaultCase) { // Check if __repr__ is defined before foreign, if so call that, like object.__str__ // would do - var klass = getClassNode.execute(inliningTarget, object); - var repr = lookupAttributeInMRONode.execute(klass); - var foreignObjectBuiltinsRepr = lookupAttributeInMRONode.execute(PythonBuiltinClassType.ForeignObject); - if (repr != foreignObjectBuiltinsRepr) { - return reprNode.executeObject(frame, object); + TpSlots slots = getSlots.execute(inliningTarget, object); + if (slots.tp_repr() != FOREIGN_REPR) { + return reprNode.execute(frame, inliningTarget, object); } if (lib.isIterator(object)) { @@ -343,7 +373,7 @@ protected TruffleString defaultConversion(VirtualFrame frame, InteropLibrary lib } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends StrNode { @Child private ObjectNodes.DefaultObjectReprNode defaultReprNode; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/FrameBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/FrameBuiltins.java index e2e34ad12c..e91e50c63c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/FrameBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/FrameBuiltins.java @@ -26,10 +26,12 @@ package com.oracle.graal.python.builtins.objects.frame; import static com.oracle.graal.python.builtins.objects.PythonAbstractObject.objectHashCodeAsHexString; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -44,6 +46,7 @@ import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins.DictNode; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.lib.PyLongAsLongAndOverflowNode; import com.oracle.graal.python.lib.PyLongCheckExactNode; import com.oracle.graal.python.nodes.ErrorMessages; @@ -59,7 +62,7 @@ import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaBooleanNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.OverflowException; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.RootCallTarget; @@ -79,12 +82,14 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PFrame) public final class FrameBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = FrameBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return FrameBuiltinsFactory.getFactories(); } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization @@ -110,8 +115,7 @@ public abstract static class GetGlobalsNode extends PythonBuiltinNode { public abstract Object execute(VirtualFrame frame, PFrame self); @Specialization - Object get(VirtualFrame curFrame, PFrame self, - @Cached PythonObjectFactory factory) { + Object get(VirtualFrame curFrame, PFrame self) { PythonObject globals = self.getGlobals(); if (globals instanceof PythonModule) { if (getDictNode == null) { @@ -120,7 +124,7 @@ Object get(VirtualFrame curFrame, PFrame self, } return getDictNode.execute(curFrame, globals, PNone.NO_VALUE); } else { - return globals != null ? globals : factory.createDict(); + return globals != null ? globals : PFactory.createDict(PythonLanguage.get(this)); } } @@ -156,8 +160,8 @@ public abstract static class LinenoNode extends PythonBinaryBuiltinNode { @Specialization Object delete(VirtualFrame frame, PFrame self, DescriptorDeleteMarker ignored, @Bind("this") Node inliningTarget, - @Cached @Cached.Exclusive PRaiseNode.Lazy raise) { - raise.get(inliningTarget).raise(PythonBuiltinClassType.AttributeError, ErrorMessages.CANNOT_DELETE); + @Cached @Cached.Exclusive PRaiseNode raise) { + raise.raise(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.CANNOT_DELETE); return PNone.NONE; } @@ -187,7 +191,7 @@ PNone set(VirtualFrame frame, PFrame self, Object newLineno, @Bind("this") Node inliningTarget, @Cached @Cached.Exclusive InlinedConditionProfile isCurrentFrameProfile, @Cached @Cached.Exclusive MaterializeFrameNode materializeNode, - @Cached @Cached.Exclusive PRaiseNode.Lazy raise, + @Cached @Cached.Exclusive PRaiseNode raise, @Cached PyLongCheckExactNode isLong, @Cached PyLongAsLongAndOverflowNode toLong) { syncLocationIfNeeded(frame, self, this, inliningTarget, isCurrentFrameProfile, materializeNode); @@ -198,17 +202,17 @@ PNone set(VirtualFrame frame, PFrame self, Object newLineno, if (lineno <= Integer.MAX_VALUE && lineno >= Integer.MIN_VALUE) { self.setJumpDestLine((int) lineno); } else { - throw raise.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.LINENO_OUT_OF_RANGE); + throw raise.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.LINENO_OUT_OF_RANGE); } } catch (OverflowException e) { - throw raise.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.LINENO_OUT_OF_RANGE); + throw raise.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.LINENO_OUT_OF_RANGE); } } else { - throw raise.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.LINENO_MUST_BE_AN_INTEGER); + throw raise.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.LINENO_MUST_BE_AN_INTEGER); } } else { PythonContext context = getContext(); - throw raise.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.CANT_JUMP_FROM_S_EVENT, + throw raise.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.CANT_JUMP_FROM_S_EVENT, context.getThreadState(context.getLanguage(inliningTarget)).getTracingWhat().pythonName); } return PNone.NONE; @@ -261,7 +265,7 @@ static Object doSet(PFrame self, Object v, @Bind("this") Node inliningTarget, try { self.setTraceLine(cast.execute(inliningTarget, v)); } catch (CannotCastException e) { - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATTRIBUTE_VALUE_MUST_BE_BOOL); + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATTRIBUTE_VALUE_MUST_BE_BOOL); } return PNone.NONE; } @@ -274,10 +278,10 @@ public abstract static class GetCodeNode extends PythonBuiltinNode { @Specialization static PCode get(PFrame self, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { RootCallTarget ct = self.getTarget(); assert ct != null; - return factory.createCode(ct); + return PFactory.createCode(language, ct); } @NeverDefault diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/PFrame.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/PFrame.java index cc236bb633..a98bea7397 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/PFrame.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/PFrame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -50,22 +50,27 @@ import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.nodes.bytecode.PBytecodeGeneratorRootNode; import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode; import com.oracle.graal.python.nodes.frame.GetFrameLocalsNode; import com.oracle.graal.python.nodes.frame.MaterializeFrameNode; +import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.bytecode.BytecodeNode; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.nodes.Node; public final class PFrame extends PythonBuiltinObject { + private static final int UNINITIALIZED_LINE = -2; + private Object[] arguments; private final MaterializedFrame locals; private Object localsDict; private final Reference virtualFrameInfo; private Node location; private RootCallTarget callTarget; - private int line = -2; + private int line = UNINITIALIZED_LINE; private int bci = -1; /* @@ -187,7 +192,7 @@ public PFrame(PythonLanguage lang, @SuppressWarnings("unused") Object threadStat this.virtualFrameInfo = curFrameInfo; curFrameInfo.setPyFrame(this); this.location = GetCodeRootNode.executeUncached(code); - this.line = this.location == null ? code.getFirstLineNo() : -2; + this.line = this.location == null ? code.getFirstLineNo() : UNINITIALIZED_LINE; this.arguments = frameArgs; this.locals = null; this.localsDict = localsDict; @@ -254,11 +259,16 @@ public boolean didJump() { @TruffleBoundary public int getLine() { - if (line == -2) { + if (line == UNINITIALIZED_LINE) { if (location == null) { line = -1; - } else if (location instanceof PBytecodeRootNode) { - return ((PBytecodeRootNode) location).bciToLine(bci); + } else if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + if (location instanceof BytecodeNode bytecodeNode) { + PBytecodeDSLRootNode rootNode = (PBytecodeDSLRootNode) bytecodeNode.getRootNode(); + return rootNode.bciToLine(bci, bytecodeNode); + } + } else if (location instanceof PBytecodeRootNode bytecodeRootNode) { + return bytecodeRootNode.bciToLine(bci); } } return line; @@ -304,6 +314,10 @@ public Node getLocation() { return location; } + public BytecodeNode getBytecodeNode() { + return (location instanceof BytecodeNode bytecodeNode) ? bytecodeNode : null; + } + public int getBci() { return bci; } @@ -313,15 +327,21 @@ public void setBci(int bci) { } public int getLasti() { - return bciToLasti(bci); + return bciToLasti(bci, location); } @TruffleBoundary - public int bciToLasti(int bci) { - if (location instanceof PBytecodeRootNode bytecodeRootNode) { - return bytecodeRootNode.bciToLasti(bci); - } else if (location instanceof PBytecodeGeneratorRootNode generatorRootNode) { - return generatorRootNode.getBytecodeRootNode().bciToLasti(bci); + public static int bciToLasti(int bci, Node location) { + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + if (bci >= 0 && location instanceof BytecodeNode bytecodeNode) { + return PBytecodeDSLRootNode.bciToLasti(bci, bytecodeNode); + } + } else { + if (location instanceof PBytecodeRootNode bytecodeRootNode) { + return bytecodeRootNode.bciToLasti(bci); + } else if (location instanceof PBytecodeGeneratorRootNode generatorRootNode) { + return generatorRootNode.getBytecodeRootNode().bciToLasti(bci); + } } return -1; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java index 0582591478..4e9cf01f09 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2014, Regents of the University of California * * All rights reserved. @@ -36,7 +36,6 @@ import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___MODULE__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___TEXT_SIGNATURE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__; import static com.oracle.graal.python.nodes.StringLiterals.T_COMMA_SPACE; import static com.oracle.graal.python.nodes.StringLiterals.T_EQ; import static com.oracle.graal.python.nodes.StringLiterals.T_LPAREN; @@ -48,6 +47,10 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -57,21 +60,21 @@ import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.object.PythonObject; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.StringLiterals; -import com.oracle.graal.python.nodes.argument.CreateArgumentsNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; -import com.oracle.graal.python.nodes.call.CallDispatchNode; +import com.oracle.graal.python.nodes.call.CallDispatchers; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; import com.oracle.graal.python.nodes.object.SetDictNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -83,6 +86,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleString; import com.oracle.truffle.api.strings.TruffleStringBuilder; @@ -91,26 +95,29 @@ @CoreFunctions(extendClasses = {PythonBuiltinClassType.PFunction, PythonBuiltinClassType.PBuiltinFunction, PythonBuiltinClassType.WrapperDescriptor}) public final class AbstractFunctionBuiltins extends PythonBuiltins { + public static final TpSlots SLOTS = AbstractFunctionBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return AbstractFunctionBuiltinsFactory.getFactories(); } - @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) + @Slot(value = SlotKind.tp_call, isComplex = true) + @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) @GenerateNodeFactory public abstract static class CallNode extends PythonBuiltinNode { @Specialization - protected Object doIt(VirtualFrame frame, PFunction self, Object[] arguments, PKeyword[] keywords, - @Shared @Cached CreateArgumentsNode createArgs, - @Shared @Cached CallDispatchNode dispatch) { - return dispatch.executeCall(frame, self, createArgs.execute(self, arguments, keywords)); + Object doIt(VirtualFrame frame, PFunction self, Object[] arguments, PKeyword[] keywords, + @Bind Node inliningTarget, + @Cached CallDispatchers.FunctionCachedCallNode callNode) { + return callNode.execute(frame, inliningTarget, self, arguments, keywords); } @Specialization - protected Object doIt(VirtualFrame frame, PBuiltinFunction self, Object[] arguments, PKeyword[] keywords, - @Shared @Cached CreateArgumentsNode createArgs, - @Shared @Cached CallDispatchNode dispatch) { - return dispatch.executeCall(frame, self, createArgs.execute(self, arguments, keywords)); + Object doIt(VirtualFrame frame, PBuiltinFunction self, Object[] arguments, PKeyword[] keywords, + @Bind Node inliningTarget, + @Cached CallDispatchers.BuiltinFunctionCachedCallNode callNode) { + return callNode.execute(frame, inliningTarget, self, arguments, keywords); } } @@ -119,19 +126,19 @@ protected Object doIt(VirtualFrame frame, PBuiltinFunction self, Object[] argume public abstract static class GetClosureNode extends PythonBuiltinNode { @Specialization(guards = "!isBuiltinFunction(self)") Object getClosure(PFunction self, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { PCell[] closure = self.getClosure(); if (closure == null) { return PNone.NONE; } - return factory.createTuple(closure); + return PFactory.createTuple(language, closure); } @SuppressWarnings("unused") @Fallback static Object getClosure(Object self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "builtin_function_or_method", "__closure__"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "builtin_function_or_method", "__closure__"); } } @@ -155,8 +162,8 @@ Object getGlobals(PFunction self, @SuppressWarnings("unused") @Fallback static Object getGlobals(Object self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "builtin_function_or_method", "__globals__"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "builtin_function_or_method", "__globals__"); } } @@ -208,8 +215,8 @@ static Object setModule(PFunction self, Object value, @SuppressWarnings("unused") @Specialization static Object getModule(PBuiltinFunction self, Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "builtin_function_or_method", "__module__"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "builtin_function_or_method", "__module__"); } } @@ -221,10 +228,11 @@ static Object getModule(PFunction self, @SuppressWarnings("unused") PNone none, @Bind("this") Node inliningTarget, @Cached ReadAttributeFromObjectNode readObject, @Shared @Cached WriteAttributeToObjectNode writeObject, - @Cached PythonObjectFactory.Lazy factory) { + @Cached InlinedBranchProfile createAnnotations) { Object annotations = readObject.execute(self, T___ANNOTATIONS__); if (annotations == PNone.NO_VALUE) { - annotations = factory.get(inliningTarget).createDict(); + createAnnotations.enter(inliningTarget); + annotations = PFactory.createDict(PythonLanguage.get(inliningTarget)); writeObject.execute(self, T___ANNOTATIONS__, annotations); } return annotations; @@ -240,8 +248,8 @@ static Object getModule(PFunction self, Object value, @SuppressWarnings("unused") @Specialization static Object getModule(PBuiltinFunction self, Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "builtin_function_or_method", "__annotations__"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "builtin_function_or_method", "__annotations__"); } } @@ -265,15 +273,15 @@ static Object dict(PFunction self, @SuppressWarnings("unused") PNone mapping, @Specialization(guards = {"!isNoValue(mapping)", "!isDict(mapping)"}) static PNone dict(@SuppressWarnings("unused") PFunction self, Object mapping, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, mapping); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, mapping); } @Specialization @SuppressWarnings("unused") static Object builtinCode(PBuiltinFunction self, Object mapping, - @Shared @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "builtin_function_or_method", "__dict__"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "builtin_function_or_method", "__dict__"); } } @@ -285,10 +293,10 @@ public abstract static class TextSignatureNode extends PythonBinaryBuiltinNode { static Object getFunction(PFunction self, @SuppressWarnings("unused") PNone none, @Bind("this") Node inliningTarget, @Cached ReadAttributeFromObjectNode readNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object signature = readNode.execute(self, T___TEXT_SIGNATURE__); if (signature == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "function", "__text_signature__"); + throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "function", "__text_signature__"); } return signature; } @@ -306,7 +314,7 @@ static TruffleString getBuiltin(PBuiltinFunction self, @SuppressWarnings("unused @Bind("this") Node inliningTarget) { Signature signature = self.getSignature(); if (signature.isHidden()) { - throw PRaiseNode.raiseUncached(inliningTarget, AttributeError, ErrorMessages.HAS_NO_ATTR, self, T___TEXT_SIGNATURE__); + throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, ErrorMessages.HAS_NO_ATTR, self, T___TEXT_SIGNATURE__); } return signatureToText(signature, false); } @@ -375,8 +383,8 @@ private static boolean appendCommaIfNeeded(TruffleStringBuilder sb, boolean firs @Specialization(guards = "!isNoValue(value)") static Object setBuiltin(@SuppressWarnings("unused") PBuiltinFunction self, @SuppressWarnings("unused") Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(AttributeError, ErrorMessages.ATTR_S_OF_S_IS_NOT_WRITABLE, "__text_signature__", "builtin_function_or_method"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, ErrorMessages.ATTR_S_OF_S_IS_NOT_WRITABLE, "__text_signature__", "builtin_function_or_method"); } public static TextSignatureNode create() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/BuiltinFunctionBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/BuiltinFunctionBuiltins.java index 2a98c32ba2..8aa39bc6d5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/BuiltinFunctionBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/BuiltinFunctionBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2014, Regents of the University of California * * All rights reserved. @@ -31,7 +31,7 @@ import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___NAME__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___QUALNAME__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___SIGNATURE__; -import static com.oracle.graal.python.nodes.SpecialAttributeNames.T__SIGNATURE__; +import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___SIGNATURE__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___OBJCLASS__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; import static com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode.T_DOLLAR_DECL_TYPE; @@ -41,6 +41,7 @@ import java.util.ArrayList; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -57,9 +58,8 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -67,7 +67,6 @@ import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -90,8 +89,8 @@ static TruffleString getName(PBuiltinFunction self, @SuppressWarnings("unused") @Specialization(guards = "!isNoValue(value)") static TruffleString setName(@SuppressWarnings("unused") PBuiltinFunction self, @SuppressWarnings("unused") Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonErrorType.AttributeError, ErrorMessages.ATTR_S_OF_S_IS_NOT_WRITABLE, "__name__", "builtin function"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.AttributeError, ErrorMessages.ATTR_S_OF_S_IS_NOT_WRITABLE, "__name__", "builtin function"); } } @@ -105,19 +104,18 @@ static TruffleString getQualname(PBuiltinFunction self, @SuppressWarnings("unuse @Specialization(guards = "!isNoValue(value)") static TruffleString setQualname(@SuppressWarnings("unused") PBuiltinFunction self, @SuppressWarnings("unused") Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonErrorType.AttributeError, ErrorMessages.ATTR_S_OF_S_IS_NOT_WRITABLE, "__qualname__", "builtin function"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.AttributeError, ErrorMessages.ATTR_S_OF_S_IS_NOT_WRITABLE, "__qualname__", "builtin function"); } } @Builtin(name = J___OBJCLASS__, minNumOfPositionalArgs = 1, isGetter = true) - @TypeSystemReference(PythonArithmeticTypes.class) @GenerateNodeFactory public abstract static class ObjclassNode extends PythonUnaryBuiltinNode { @Specialization(guards = "self.getEnclosingType() == null") static Object objclassMissing(@SuppressWarnings("unused") PBuiltinFunction self, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonErrorType.AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "builtin_function_or_method", "__objclass__"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "builtin_function_or_method", "__objclass__"); } @Specialization(guards = "self.getEnclosingType() != null") @@ -133,11 +131,11 @@ public abstract static class ReduceNode extends PythonUnaryBuiltinNode { Object doBuiltinFunc(VirtualFrame frame, PBuiltinFunction func, @Bind("this") Node inliningTarget, @Cached PyObjectGetAttr getAttr, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { PythonModule builtins = getContext().getBuiltins(); Object getattr = getAttr.execute(frame, inliningTarget, builtins, T_GETATTR); - PTuple args = factory.createTuple(new Object[]{func.getEnclosingType(), func.getName()}); - return factory.createTuple(new Object[]{getattr, args}); + PTuple args = PFactory.createTuple(language, new Object[]{func.getEnclosingType(), func.getName()}); + return PFactory.createTuple(language, new Object[]{getattr, args}); } } @@ -150,7 +148,7 @@ public abstract static class SignatureNode extends PythonUnaryBuiltinNode { static Object doIt(PBuiltinFunction fun, @Bind("this") Node inliningTarget) { if (fun.getSignature().isHidden()) { - throw PRaiseNode.raiseUncached(inliningTarget, AttributeError, ErrorMessages.HAS_NO_ATTR, fun, T__SIGNATURE__); + throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, ErrorMessages.HAS_NO_ATTR, fun, T___SIGNATURE__); } return createInspectSignature(fun.getSignature(), false); } @@ -214,7 +212,7 @@ public static Object createInspectSignature(Signature signature, boolean skipSel parameters.add(callNode.executeWithoutFrame(inspectParameter, StringLiterals.T_KWARGS, ParameterKinds.VAR_KEYWORD.get(parameterKinds, inspectParameter))); } - return callNode.executeWithoutFrame(inspectSignature, PythonObjectFactory.getUncached().createTuple(parameters.toArray())); + return callNode.executeWithoutFrame(inspectSignature, PFactory.createTuple(PythonLanguage.get(null), parameters.toArray())); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/BuiltinMethodDescriptor.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/BuiltinMethodDescriptor.java deleted file mode 100644 index 9191c44680..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/BuiltinMethodDescriptor.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.function; - -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; - -import java.lang.annotation.Annotation; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; - -import com.oracle.graal.python.builtins.Builtin; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.PythonOS; -import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotBuiltin; -import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.dsl.GeneratedBy; -import com.oracle.truffle.api.dsl.NodeFactory; - -/** - * Context independent wrapper of a method that can be stored in special method slots. These - * wrappers are context and also language instance independent. - * - * @see com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot - */ -public abstract class BuiltinMethodDescriptor { - - /** - * Size of this cache is limited by the number of builtins in GraalPython. First few contexts - * may, in theory, experience lock contention while this cache is being filled up, but after - * that there should be no cache misses and no locking to update the cache. - * - * Another way to look at this is that it is a map of all builtins, like - * {@link PythonBuiltinClassType} is list of all builtin types, but initialized at runtime. - * - * Not having this cache per {@link com.oracle.graal.python.PythonLanguage} allows to save the - * indirection when comparing to some well known {@link BuiltinMethodDescriptor} in guards. - */ - private static final ConcurrentHashMap CACHE = new ConcurrentHashMap<>(); - - /** - * First caller of this method within given {@code PythonLanguage} instance should add a cache - * entry for this builtin's call target. - */ - public static BuiltinMethodDescriptor get(PBuiltinFunction function) { - CompilerAsserts.neverPartOfCompilation(); - NodeFactory factory = function.getBuiltinNodeFactory(); - if (factory == null) { - return null; - } - Builtin builtinAnnotation = findBuiltinAnnotation(function.getName().toJavaStringUncached(), factory); - if (builtinAnnotation == null || builtinAnnotation.needsFrame()) { - return null; - } - - PythonBuiltinClassType type = null; - Object enclosing = function.getEnclosingType(); - if (enclosing instanceof PythonBuiltinClassType) { - type = (PythonBuiltinClassType) enclosing; - } else if (enclosing instanceof PythonBuiltinClass) { - type = ((PythonBuiltinClass) enclosing).getType(); - } else { - assert enclosing == null; - } - - return get(function.getName().toJavaStringUncached(), factory, type); - } - - static BuiltinMethodDescriptor get(String name, NodeFactory factory, PythonBuiltinClassType type) { - Builtin builtinAnnotation = findBuiltinAnnotation(name, factory); - if (builtinAnnotation == null) { - // New slots HACK: to be removed. This is only used for comparing with existing slot - // found at runtime, the dummy value will not match anything - return new UnaryBuiltinDescriptor(name, null, PythonBuiltinClassType.PythonObject, new Builtin() { - - @Override - public Class annotationType() { - return Builtin.class; - } - - @Override - public String name() { - return name; - } - - @Override - public String doc() { - return null; - } - - @Override - public PythonOS os() { - return null; - } - - @Override - public PythonBuiltinClassType constructsClass() { - return null; - } - - @Override - public PythonBuiltinClassType[] base() { - return new PythonBuiltinClassType[0]; - } - - @Override - public int minNumOfPositionalArgs() { - return 0; - } - - @Override - public int maxNumOfPositionalArgs() { - return 0; - } - - @Override - public int numOfPositionalOnlyArgs() { - return 0; - } - - @Override - public boolean isGetter() { - return false; - } - - @Override - public boolean isSetter() { - return false; - } - - @Override - public boolean allowsDelete() { - return false; - } - - @Override - public boolean takesVarArgs() { - return false; - } - - @Override - public boolean varArgsMarker() { - return false; - } - - @Override - public boolean takesVarKeywordArgs() { - return false; - } - - @Override - public String[] parameterNames() { - return new String[0]; - } - - @Override - public String[] keywordOnlyNames() { - return new String[0]; - } - - @Override - public boolean isPublic() { - return false; - } - - @Override - public boolean isClassmethod() { - return false; - } - - @Override - public boolean isStaticmethod() { - return false; - } - - @Override - public boolean needsFrame() { - return false; - } - - @Override - public boolean alwaysNeedsCallerFrame() { - return false; - } - - @Override - public boolean declaresExplicitSelf() { - return false; - } - - @Override - public boolean reverseOperation() { - return false; - } - - @Override - public String raiseErrorName() { - return null; - } - - @Override - public boolean forceSplitDirectCalls() { - return false; - } - - @Override - public boolean autoRegister() { - return false; - } - }); - } - assert builtinAnnotation != null && !builtinAnnotation.needsFrame(); - return get(name, factory, type, builtinAnnotation); - } - - private static BuiltinMethodDescriptor get(String name, NodeFactory factory, PythonBuiltinClassType type, Builtin builtinAnnotation) { - CompilerAsserts.neverPartOfCompilation(); - if (factory.getClass().getAnnotation(GeneratedBy.class) == null) { - // For non-generated factories, we do not assume that they are singletons, so we cannot - // use them for our cache that must be bounded in size - return null; - } - Class nodeClass = factory.getNodeClass(); - BuiltinMethodDescriptor result = null; - if (PythonUnaryBuiltinNode.class.isAssignableFrom(nodeClass)) { - result = new UnaryBuiltinDescriptor(name, factory, type, builtinAnnotation); - assert result.getBuiltinAnnotation().minNumOfPositionalArgs() <= 1 : name; - } else if (PythonBinaryBuiltinNode.class.isAssignableFrom(nodeClass)) { - result = new BinaryBuiltinDescriptor(name, factory, type, builtinAnnotation); - assert result.getBuiltinAnnotation().minNumOfPositionalArgs() <= 2 : name; - } else if (PythonTernaryBuiltinNode.class.isAssignableFrom(nodeClass)) { - result = new TernaryBuiltinDescriptor(name, factory, type, builtinAnnotation); - assert result.getBuiltinAnnotation().minNumOfPositionalArgs() <= 3 : name; - } - if (result != null) { - return CACHE.computeIfAbsent(result, x -> x); - } - return null; - } - - public static boolean isInstance(Object obj) { - return obj instanceof BuiltinMethodDescriptor; - } - - private static Builtin findBuiltinAnnotation(String name, NodeFactory factory) { - // Temporary hack until new slots fully replace "special method slots" and these descriptors - if (TpSlotBuiltin.isSlotFactory(factory)) { - return null; - } - for (Builtin builtin : factory.getNodeClass().getAnnotationsByType(Builtin.class)) { - if (builtin.name().equals(name)) { - return builtin; - } - if (builtin.constructsClass() != PythonBuiltinClassType.nil && J___NEW__.equals(name)) { - return builtin; - } - } - throw new IllegalStateException(String.format( - "Cannot find corresponding builtin annotation on class %s for builtin '%s'", - factory.getNodeClass().getSimpleName(), name)); - } - - private final NodeFactory factory; - private final PythonBuiltinClassType type; - // The builtin annotation allows us to differentiate between builtins shared for reversible - // operations, such as int.__mul__ and int.__rmul__, which have the same node factory - private final Builtin builtinAnnotation; - // Shortcuts for fields of builtinAnnotation that are accessed on a fast-path - private final String name; - private final boolean isReverseOperation; - private final int minNumOfPositionalArgs; - - private BuiltinMethodDescriptor(String name, NodeFactory factory, PythonBuiltinClassType type, Builtin builtinAnnotation) { - assert name.equals(builtinAnnotation.name()); - this.name = name; - this.factory = factory; - this.type = type; - this.builtinAnnotation = builtinAnnotation; - this.isReverseOperation = builtinAnnotation.reverseOperation(); - this.minNumOfPositionalArgs = builtinAnnotation.minNumOfPositionalArgs(); - } - - public final NodeFactory getFactory() { - return factory; - } - - public final boolean isDescriptorOf(PBuiltinFunction fun) { - return fun.getDescriptor() == this; - } - - public final PythonBuiltinClassType getEnclosingType() { - return type; - } - - public final String getName() { - return name; - } - - public final boolean isReverseOperation() { - return isReverseOperation; - } - - public final int minNumOfPositionalArgs() { - return minNumOfPositionalArgs; - } - - public final Builtin getBuiltinAnnotation() { - return builtinAnnotation; - } - - @Override - public final boolean equals(Object o) { - CompilerAsserts.neverPartOfCompilation(); - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - BuiltinMethodDescriptor that = (BuiltinMethodDescriptor) o; - // Rudimentary check of the assumption that builtin node factories are singletons, if we - // create&cache BuiltinMethodDescriptors with non-singleton factories, we do not have the - // guarantee that the cache size is bounded - assert (factory.getNodeClass() == that.factory.getNodeClass()) == (factory == that.factory) : name; - return factory == that.factory && type == that.type && name.equals(that.name); - } - - @Override - public final int hashCode() { - CompilerAsserts.neverPartOfCompilation(); - return Objects.hash(factory, type, name); - } - - @Override - public String toString() { - CompilerAsserts.neverPartOfCompilation(); - return getClass().getSimpleName() + "{" + type + "." + name + '}'; - } - - // Note: manually written subclass for each builtin works better with Truffle DSL than one - // generic class that would parametrize the 'factory' field - - public static final class UnaryBuiltinDescriptor extends BuiltinMethodDescriptor { - public UnaryBuiltinDescriptor(String name, NodeFactory factory, PythonBuiltinClassType type, Builtin builtinAnnotation) { - super(name, factory, type, builtinAnnotation); - } - - public PythonUnaryBuiltinNode createNode() { - return (PythonUnaryBuiltinNode) getFactory().createNode(); - } - } - - public static final class BinaryBuiltinDescriptor extends BuiltinMethodDescriptor { - public BinaryBuiltinDescriptor(String name, NodeFactory factory, PythonBuiltinClassType type, Builtin builtinAnnotation) { - super(name, factory, type, builtinAnnotation); - } - - public PythonBinaryBuiltinNode createNode() { - return (PythonBinaryBuiltinNode) getFactory().createNode(); - } - } - - public static final class TernaryBuiltinDescriptor extends BuiltinMethodDescriptor { - public TernaryBuiltinDescriptor(String name, NodeFactory factory, PythonBuiltinClassType type, Builtin builtinAnnotation) { - super(name, factory, type, builtinAnnotation); - } - - public PythonTernaryBuiltinNode createNode() { - return (PythonTernaryBuiltinNode) getFactory().createNode(); - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/BuiltinMethodDescriptors.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/BuiltinMethodDescriptors.java deleted file mode 100644 index 7a4aafab1c..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/BuiltinMethodDescriptors.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.function; - -import static com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.get; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; - -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.dict.DictBuiltinsFactory; - -/** - * Enum-like class with some useful well known descriptors. Because of initialization order issues, - * these constants cannot be places in {@link BuiltinMethodDescriptor} class. - */ -public abstract class BuiltinMethodDescriptors { - public static final BuiltinMethodDescriptor DICT_ITER = get(J___ITER__, DictBuiltinsFactory.IterNodeFactory.getInstance(), PythonBuiltinClassType.PDict); - - private BuiltinMethodDescriptors() { - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java index 95372770ba..bd2b4581a4 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2014, Regents of the University of California * * All rights reserved. @@ -26,6 +26,7 @@ package com.oracle.graal.python.builtins.objects.function; +import static com.oracle.graal.python.nodes.BuiltinNames.T_LAMBDA_NAME; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___CODE__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___DEFAULTS__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___DOC__; @@ -36,7 +37,6 @@ import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___QUALNAME__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J_TRUFFLE_SOURCE; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.nodes.truffle.TruffleStringMigrationHelpers.assertNoJavaString; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; @@ -44,14 +44,17 @@ import java.util.ArrayList; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PythonAbstractObject; +import com.oracle.graal.python.builtins.objects.cell.PCell; import com.oracle.graal.python.builtins.objects.code.PCode; import com.oracle.graal.python.builtins.objects.common.HashingStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetIterator; @@ -73,10 +76,10 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetFunctionCodeNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -87,7 +90,6 @@ import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -100,14 +102,88 @@ protected List> getNodeFa return FunctionBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "function", minNumOfPositionalArgs = 3, parameterNames = {"$cls", "code", "globals", "name", "argdefs", "closure"}) + @GenerateNodeFactory + public abstract static class FunctionNode extends PythonBuiltinNode { + + @Specialization + static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, @SuppressWarnings("unused") PNone defaultArgs, + @SuppressWarnings("unused") PNone closure, + @Bind PythonLanguage language) { + return PFactory.createFunction(language, name, code, globals, null); + } + + @Specialization + static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, @SuppressWarnings("unused") PNone name, @SuppressWarnings("unused") PNone defaultArgs, + PTuple closure, + @Bind("this") Node inliningTarget, + @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode, + @Bind PythonLanguage language) { + return PFactory.createFunction(language, T_LAMBDA_NAME, code, globals, PCell.toCellArray(getObjectArrayNode.execute(inliningTarget, closure))); + } + + @Specialization + static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, @SuppressWarnings("unused") PNone name, @SuppressWarnings("unused") PNone defaultArgs, + @SuppressWarnings("unused") PNone closure, + @SuppressWarnings("unused") @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode, + @Bind PythonLanguage language) { + return PFactory.createFunction(language, T_LAMBDA_NAME, code, globals, null); + } + + @Specialization + static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, @SuppressWarnings("unused") PNone defaultArgs, PTuple closure, + @Bind("this") Node inliningTarget, + @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode, + @Bind PythonLanguage language) { + return PFactory.createFunction(language, name, code, globals, PCell.toCellArray(getObjectArrayNode.execute(inliningTarget, closure))); + } + + @Specialization + static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, @SuppressWarnings("unused") PNone name, PTuple defaultArgs, + @SuppressWarnings("unused") PNone closure, + @Bind("this") Node inliningTarget, + @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode, + @Bind PythonLanguage language) { + // TODO split defaults of positional args from kwDefaults + return PFactory.createFunction(language, code.getName(), code, globals, getObjectArrayNode.execute(inliningTarget, defaultArgs), null, null); + } + + @Specialization + static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, PTuple defaultArgs, @SuppressWarnings("unused") PNone closure, + @Bind("this") Node inliningTarget, + @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode, + @Bind PythonLanguage language) { + // TODO split defaults of positional args from kwDefaults + return PFactory.createFunction(language, name, code, globals, getObjectArrayNode.execute(inliningTarget, defaultArgs), null, null); + } + + @Specialization + static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, PTuple defaultArgs, PTuple closure, + @Bind("this") Node inliningTarget, + @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode, + @Bind PythonLanguage language) { + // TODO split defaults of positional args from kwDefaults + return PFactory.createFunction(language, name, code, globals, getObjectArrayNode.execute(inliningTarget, defaultArgs), null, + PCell.toCellArray(getObjectArrayNode.execute(inliningTarget, closure))); + } + + @Fallback + @SuppressWarnings("unused") + static PFunction function(@SuppressWarnings("unused") Object cls, Object code, Object globals, Object name, Object defaultArgs, Object closure, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.FUNC_CONSTRUCTION_NOT_SUPPORTED, cls, code, globals, name, defaultArgs, closure); + } + } + @Slot(SlotKind.tp_descr_get) @GenerateUncached @GenerateNodeFactory public abstract static class GetNode extends DescrGetBuiltinNode { @Specialization(guards = {"!isPNone(instance)"}) static PMethod doMethod(PFunction self, Object instance, @SuppressWarnings("unused") Object klass, - @Cached PythonObjectFactory factory) { - return factory.createMethod(instance, self); + @Bind PythonLanguage language) { + return PFactory.createMethod(language, instance, self); } @Specialization @@ -116,8 +192,7 @@ static Object doFunction(PFunction self, @SuppressWarnings("unused") PNone insta } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization @@ -176,10 +251,10 @@ static Object setQualname(PFunction self, Object value, public abstract static class GetDefaultsNode extends PythonBinaryBuiltinNode { @Specialization(guards = "isNoValue(defaults)") static Object defaults(PFunction self, @SuppressWarnings("unused") PNone defaults, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { Object[] argDefaults = self.getDefaults(); assert argDefaults != null; - return (argDefaults.length == 0) ? PNone.NONE : factory.createTuple(argDefaults); + return (argDefaults.length == 0) ? PNone.NONE : PFactory.createTuple(language, argDefaults); } @Specialization @@ -205,8 +280,8 @@ static Object setDefaults(PFunction self, @SuppressWarnings("unused") PNone defa @Fallback @SuppressWarnings("unused") static Object setDefaults(Object self, Object defaults, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.MUST_BE_SET_TO_S_NOT_P, T___DEFAULTS__, "tuple"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.MUST_BE_SET_TO_S_NOT_P, T___DEFAULTS__, "tuple"); } } @@ -215,9 +290,9 @@ static Object setDefaults(Object self, Object defaults, public abstract static class GetKeywordDefaultsNode extends PythonBinaryBuiltinNode { @Specialization(guards = "isNoValue(arg)") static Object get(PFunction self, @SuppressWarnings("unused") PNone arg, - @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { PKeyword[] kwdefaults = self.getKwDefaults(); - return (kwdefaults.length > 0) ? factory.createDict(kwdefaults) : PNone.NONE; + return (kwdefaults.length > 0) ? PFactory.createDict(language, kwdefaults) : PNone.NONE; } @Specialization(guards = "!isNoValue(arg)") @@ -237,7 +312,7 @@ Object set(PFunction self, PDict arg) { if (key instanceof PString) { key = ((PString) key).getValueUncached(); } else if (!(key instanceof TruffleString)) { - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.TypeError, ErrorMessages.KEYWORD_NAMES_MUST_BE_STR_GOT_P, key); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.KEYWORD_NAMES_MUST_BE_STR_GOT_P, key); } keywords.add(new PKeyword((TruffleString) key, HashingStorageIteratorValue.executeUncached(storage, it))); } @@ -274,8 +349,8 @@ static Object doMethod(PMethod method, @Fallback static Object doGeneric(Object object, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.GETTING_THER_SOURCE_NOT_SUPPORTED_FOR_P, object); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.GETTING_THER_SOURCE_NOT_SUPPORTED_FOR_P, object); } } @@ -293,11 +368,11 @@ static Object getCodeU(PFunction self, @SuppressWarnings("unused") PNone none, @Specialization static Object setCode(PFunction self, PCode code, @Bind("this") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int closureLength = self.getClosure() == null ? 0 : self.getClosure().length; int freeVarsLength = code.getFreeVars().length; if (closureLength != freeVarsLength) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.REQUIRES_CODE_OBJ, self.getName(), closureLength, freeVarsLength); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.REQUIRES_CODE_OBJ, self.getName(), closureLength, freeVarsLength); } self.setCode(code); return PNone.NONE; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/MethodDescriptorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/MethodDescriptorBuiltins.java index 7aa0278c7f..106f225cbb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/MethodDescriptorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/MethodDescriptorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,13 +40,11 @@ */ package com.oracle.graal.python.builtins.objects.function; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; - import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; -import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; @@ -58,15 +56,13 @@ import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.DescrGetBuiltinNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.strings.TruffleString; @CoreFunctions(extendClasses = PythonBuiltinClassType.PBuiltinFunction) @@ -85,8 +81,8 @@ protected List> getNodeFa public abstract static class GetNode extends DescrGetBuiltinNode { @Specialization(guards = "!isNoValue(instance)") static PMethod doMethod(PFunction self, Object instance, Object klass, - @Shared @Cached PythonObjectFactory factory) { - return factory.createMethod(instance, self); + @Bind PythonLanguage language) { + return PFactory.createMethod(language, instance, self); } @Specialization(guards = "isNoValue(instance)") @@ -96,14 +92,14 @@ static Object doFunction(PFunction self, Object instance, Object klass) { @Specialization(guards = {"!isNoValue(instance)", "!self.needsDeclaringType()"}) static PBuiltinMethod doBuiltinMethod(PBuiltinFunction self, Object instance, Object klass, - @Shared @Cached PythonObjectFactory factory) { - return factory.createBuiltinMethod(instance, self); + @Bind PythonLanguage language) { + return PFactory.createBuiltinMethod(language, instance, self); } @Specialization(guards = {"!isNoValue(instance)", "self.needsDeclaringType()"}) static PBuiltinMethod doBuiltinMethodWithDeclaringClass(PBuiltinFunction self, Object instance, Object klass, - @Shared @Cached PythonObjectFactory factory) { - return factory.createBuiltinMethod(instance, self, self.getEnclosingType()); + @Bind PythonLanguage language) { + return PFactory.createBuiltinMethod(language, instance, self, self.getEnclosingType()); } @Specialization(guards = "isNoValue(instance)") @@ -112,8 +108,7 @@ static Object doBuiltinFunction(PBuiltinFunction self, Object instance, Object k } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization(guards = "self.getEnclosingType() == null") @@ -126,7 +121,7 @@ static TruffleString reprModuleFunction(PBuiltinFunction self, @Specialization(guards = "self.getEnclosingType() != null") static TruffleString reprClassFunction(PBuiltinFunction self, @Cached.Shared("formatter") @Cached StringUtils.SimpleTruffleStringFormatNode simpleTruffleStringFormatNode) { - return simpleTruffleStringFormatNode.format("", self.getName(), TypeNodes.GetNameNode.doSlowPath(self.getEnclosingType())); + return simpleTruffleStringFormatNode.format("", self.getName(), TypeNodes.GetNameNode.executeUncached(self.getEnclosingType())); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PArguments.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PArguments.java index 25baa2d572..febb49e675 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PArguments.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PArguments.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -28,6 +28,8 @@ import com.oracle.graal.python.builtins.objects.cell.PCell; import com.oracle.graal.python.builtins.objects.frame.PFrame; import com.oracle.graal.python.builtins.objects.object.PythonObject; +import com.oracle.graal.python.runtime.PythonOptions; +import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.exception.AbstractTruffleException; @@ -217,6 +219,11 @@ public static Object getExceptionUnchecked(Object[] arguments) { return arguments[INDEX_CURRENT_EXCEPTION]; } + public static boolean hasException(Object[] arguments) { + Object exception = getExceptionUnchecked(arguments); + return exception != null && exception != PException.NO_EXCEPTION; + } + public static void setException(Frame frame, AbstractTruffleException exc) { setException(frame.getArguments(), exc); } @@ -280,6 +287,7 @@ public static int getUserArgumentLength(Object[] arguments) { } public static MaterializedFrame getGeneratorFrame(Object[] arguments) { + assert !PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER; return (MaterializedFrame) arguments[INDEX_GENERATOR_FRAME]; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PBuiltinFunction.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PBuiltinFunction.java index 9d452b879a..e82e1c3677 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PBuiltinFunction.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PBuiltinFunction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -28,9 +28,9 @@ import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__; import static com.oracle.graal.python.nodes.StringLiterals.T_DOT; -import java.lang.invoke.VarHandle; import java.util.Arrays; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.BoundBuiltinCallable; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -45,7 +45,7 @@ import com.oracle.graal.python.nodes.PRootNode; import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; @@ -79,7 +79,6 @@ public final class PBuiltinFunction extends PythonBuiltinObject implements Bound private final int flags; private final TpSlot slot; private final PExternalFunctionWrapper slotWrapper; - private BuiltinMethodDescriptor descriptor; @CompilationFinal(dimensions = 1) private final Object[] defaults; @CompilationFinal(dimensions = 1) private final PKeyword[] kwDefaults; @@ -88,7 +87,7 @@ public PBuiltinFunction(PythonBuiltinClassType cls, Shape shape, TruffleString n super(cls, shape); this.name = PythonUtils.toPString(name); if (enclosingType != null) { - this.qualname = StringUtils.cat(GetNameNode.doSlowPath(enclosingType), T_DOT, name); + this.qualname = StringUtils.cat(GetNameNode.executeUncached(enclosingType), T_DOT, name); } else { this.qualname = name; } @@ -106,7 +105,7 @@ public PBuiltinFunction(PythonBuiltinClassType cls, Shape shape, TruffleString n this(cls, shape, name, enclosingType, defaults, kwDefaults, flags, callTarget, null, null); } - private static PKeyword[] generateKwDefaults(Signature signature) { + public static PKeyword[] generateKwDefaults(Signature signature) { TruffleString[] keywordNames = signature.getKeywordNames(); PKeyword[] kwDefaults = PKeyword.create(keywordNames.length); for (int i = 0; i < keywordNames.length; i++) { @@ -157,19 +156,6 @@ public NodeFactory getBuiltinNodeFactory() { } } - public boolean isReverseOperationSlot() { - return isReverseOperationSlot(callTarget); - } - - public static boolean isReverseOperationSlot(RootCallTarget ct) { - RootNode functionRootNode = ct.getRootNode(); - if (functionRootNode instanceof BuiltinFunctionRootNode) { - return ((BuiltinFunctionRootNode) functionRootNode).getBuiltin().reverseOperation(); - } else { - return false; - } - } - public int getFlags() { return flags; } @@ -250,11 +236,11 @@ public String toString() { } @Override - public PBuiltinFunction boundToObject(PythonBuiltinClassType klass, PythonObjectFactory factory) { + public PBuiltinFunction boundToObject(PythonBuiltinClassType klass, PythonLanguage language) { if (klass == enclosingType) { return this; } else { - PBuiltinFunction func = factory.createBuiltinFunction(this, klass); + PBuiltinFunction func = PFactory.createBuiltinFunction(language, this, klass); func.setAttribute(T___DOC__, getAttribute(T___DOC__)); return func; } @@ -278,23 +264,4 @@ boolean hasExecutableName() { TruffleString getExecutableName() { return getName(); } - - public void setDescriptor(BuiltinMethodDescriptor value) { - assert value.getName().equals(getName().toJavaStringUncached()) && getBuiltinNodeFactory() == value.getFactory() : getName() + " vs " + value; - // Only make sure that info is fully initialized, otherwise it is fine if it is set multiple - // times from different threads, all of them should set the same value - VarHandle.storeStoreFence(); - BuiltinMethodDescriptor local = descriptor; - assert local == null || local == value : value; - this.descriptor = value; - } - - /** - * The descriptor is set lazily once this builtin function is stored in any special method slot. - * I.e., one can assume that any builtin function looked up via special method slots has its - * descriptor set. - */ - public BuiltinMethodDescriptor getDescriptor() { - return descriptor; - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PFunction.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PFunction.java index fb32adb968..f527d415b3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PFunction.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PFunction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -43,6 +43,7 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -62,12 +63,12 @@ public final class PFunction extends PythonObject { private TruffleString qualname; private boolean forceSplitDirectCalls; private final Assumption codeStableAssumption; - private final Assumption defaultsStableAssumption; private final PythonObject globals; @CompilationFinal private boolean isBuiltin; @CompilationFinal(dimensions = 1) private final PCell[] closure; @CompilationFinal private PCode finalCode; private PCode code; + private RootCallTarget callTarget; @CompilationFinal(dimensions = 1) private Object[] finalDefaultValues; private Object[] defaultValues; @CompilationFinal(dimensions = 1) private PKeyword[] finalKwDefaultValues; @@ -79,25 +80,23 @@ public PFunction(PythonLanguage lang, TruffleString name, TruffleString qualname } public PFunction(PythonLanguage lang, TruffleString name, TruffleString qualname, PCode code, PythonObject globals, Object[] defaultValues, - PKeyword[] kwDefaultValues, - PCell[] closure) { - this(lang, name, qualname, code, globals, defaultValues, kwDefaultValues, closure, Truffle.getRuntime().createAssumption(), Truffle.getRuntime().createAssumption()); + PKeyword[] kwDefaultValues, PCell[] closure) { + this(lang, name, qualname, code, globals, defaultValues, kwDefaultValues, closure, Truffle.getRuntime().createAssumption()); } public PFunction(PythonLanguage lang, TruffleString name, TruffleString qualname, PCode code, PythonObject globals, Object[] defaultValues, - PKeyword[] kwDefaultValues, - PCell[] closure, Assumption codeStableAssumption, Assumption defaultsStableAssumption) { + PKeyword[] kwDefaultValues, PCell[] closure, Assumption codeStableAssumption) { super(PythonBuiltinClassType.PFunction, PythonBuiltinClassType.PFunction.getInstanceShape(lang)); this.name = name; this.qualname = qualname; assert code != null; this.code = this.finalCode = code; + this.callTarget = code.getRootCallTarget(); this.globals = globals; this.defaultValues = this.finalDefaultValues = defaultValues == null ? PythonUtils.EMPTY_OBJECT_ARRAY : defaultValues; this.kwDefaultValues = this.finalKwDefaultValues = kwDefaultValues == null ? PKeyword.EMPTY_KEYWORDS : kwDefaultValues; this.closure = closure; this.codeStableAssumption = codeStableAssumption; - this.defaultsStableAssumption = defaultsStableAssumption; this.forceSplitDirectCalls = false; } @@ -105,10 +104,6 @@ public Assumption getCodeStableAssumption() { return codeStableAssumption; } - public Assumption getDefaultsStableAssumption() { - return defaultsStableAssumption; - } - public PythonObject getGlobals() { return globals; } @@ -185,17 +180,22 @@ public PCode getCode() { return code; } + public RootCallTarget getCallTarget() { + return callTarget; + } + @TruffleBoundary public void setCode(PCode code) { codeStableAssumption.invalidate("code changed for function " + getName()); assert code != null : "code cannot be null"; this.finalCode = null; this.code = code; + this.callTarget = code.getRootCallTarget(); } public Object[] getDefaults() { if (CompilerDirectives.inCompiledCode() && CompilerDirectives.isPartialEvaluationConstant(this)) { - if (defaultsStableAssumption.isValid()) { + if (codeStableAssumption.isValid()) { return finalDefaultValues; } } @@ -204,14 +204,14 @@ public Object[] getDefaults() { @TruffleBoundary public void setDefaults(Object[] defaults) { - this.defaultsStableAssumption.invalidate("defaults changed for function " + getName()); + this.codeStableAssumption.invalidate("defaults changed for function " + getName()); this.finalDefaultValues = null; // avoid leak, and make code that wrongly uses it crash this.defaultValues = defaults; } public PKeyword[] getKwDefaults() { if (CompilerDirectives.inCompiledCode() && CompilerDirectives.isPartialEvaluationConstant(this)) { - if (defaultsStableAssumption.isValid()) { + if (codeStableAssumption.isValid()) { return finalKwDefaultValues; } } @@ -220,7 +220,7 @@ public PKeyword[] getKwDefaults() { @TruffleBoundary public void setKwDefaults(PKeyword[] defaults) { - this.defaultsStableAssumption.invalidate("kw defaults changed for function " + getName()); + this.codeStableAssumption.invalidate("kw defaults changed for function " + getName()); this.finalDefaultValues = null; // avoid leak, and make code that wrongly uses it crash this.kwDefaultValues = defaults; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/Signature.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/Signature.java index cfa9c1edca..4c5cd9fa77 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/Signature.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/Signature.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -31,17 +31,19 @@ import java.util.ArrayList; import java.util.List; +import com.oracle.graal.python.nodes.PRootNode; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.strings.TruffleString; public final class Signature { - public static final Signature EMPTY = new Signature(-1, false, -1, false, PythonUtils.EMPTY_TRUFFLESTRING_ARRAY, PythonUtils.EMPTY_TRUFFLESTRING_ARRAY); + public static final Signature EMPTY = new Signature(-1, false, -1, PythonUtils.EMPTY_TRUFFLESTRING_ARRAY, PythonUtils.EMPTY_TRUFFLESTRING_ARRAY); + public static final Signature GENERIC_VARARGS = new Signature(-1, true, 0, null, null); private final int varArgIndex; private final int positionalOnlyArgIndex; - private final boolean isVarArgsMarker; private final boolean takesVarKeywordArgs; private final boolean checkEnclosingType; // See javadoc for isHidden @@ -52,32 +54,31 @@ public final class Signature { private final TruffleString raiseErrorName; - public Signature(boolean takesVarKeywordArgs, int takesVarArgs, boolean varArgsMarker, + public Signature(boolean takesVarKeywordArgs, int takesVarArgs, TruffleString[] parameterIds, TruffleString[] keywordNames) { - this(-1, takesVarKeywordArgs, takesVarArgs, varArgsMarker, parameterIds, keywordNames); + this(-1, takesVarKeywordArgs, takesVarArgs, parameterIds, keywordNames); } - public Signature(int positionOnlyArgIndex, boolean takesVarKeywordArgs, int takesVarArgs, boolean varArgsMarker, + public Signature(int positionOnlyArgIndex, boolean takesVarKeywordArgs, int takesVarArgs, TruffleString[] parameterIds, TruffleString[] keywordNames) { - this(positionOnlyArgIndex, takesVarKeywordArgs, takesVarArgs, varArgsMarker, parameterIds, keywordNames, false); + this(positionOnlyArgIndex, takesVarKeywordArgs, takesVarArgs, parameterIds, keywordNames, false); } - public Signature(int positionOnlyArgIndex, boolean takesVarKeywordArgs, int takesVarArgs, boolean varArgsMarker, + public Signature(int positionOnlyArgIndex, boolean takesVarKeywordArgs, int takesVarArgs, TruffleString[] parameterIds, TruffleString[] keywordNames, boolean checkEnclosingType) { - this(positionOnlyArgIndex, takesVarKeywordArgs, takesVarArgs, varArgsMarker, parameterIds, keywordNames, checkEnclosingType, T_EMPTY_STRING); + this(positionOnlyArgIndex, takesVarKeywordArgs, takesVarArgs, parameterIds, keywordNames, checkEnclosingType, T_EMPTY_STRING); } - public Signature(int positionOnlyArgIndex, boolean takesVarKeywordArgs, int takesVarArgs, boolean varArgsMarker, + public Signature(int positionOnlyArgIndex, boolean takesVarKeywordArgs, int takesVarArgs, TruffleString[] parameterIds, TruffleString[] keywordNames, boolean checkEnclosingType, TruffleString raiseErrorName) { - this(positionOnlyArgIndex, takesVarKeywordArgs, takesVarArgs, varArgsMarker, parameterIds, keywordNames, checkEnclosingType, raiseErrorName, false); + this(positionOnlyArgIndex, takesVarKeywordArgs, takesVarArgs, parameterIds, keywordNames, checkEnclosingType, raiseErrorName, false); } - public Signature(int positionOnlyArgIndex, boolean takesVarKeywordArgs, int takesVarArgs, boolean varArgsMarker, + public Signature(int positionOnlyArgIndex, boolean takesVarKeywordArgs, int takesVarArgs, TruffleString[] parameterIds, TruffleString[] keywordNames, boolean checkEnclosingType, TruffleString raiseErrorName, boolean hidden) { this.positionalOnlyArgIndex = positionOnlyArgIndex; this.takesVarKeywordArgs = takesVarKeywordArgs; this.varArgIndex = takesVarArgs; - this.isVarArgsMarker = varArgsMarker; this.positionalParameterNames = (parameterIds != null) ? parameterIds : PythonUtils.EMPTY_TRUFFLESTRING_ARRAY; this.keywordOnlyNames = (keywordNames != null) ? keywordNames : PythonUtils.EMPTY_TRUFFLESTRING_ARRAY; this.checkEnclosingType = checkEnclosingType; @@ -85,10 +86,6 @@ public Signature(int positionOnlyArgIndex, boolean takesVarKeywordArgs, int take this.hidden = hidden; } - public static Signature createVarArgsAndKwArgsOnly() { - return new Signature(-1, true, 0, false, null, null); - } - public int getNumOfRequiredKeywords() { return keywordOnlyNames.length; } @@ -106,18 +103,10 @@ public int getPositionalOnlyArgIndex() { return positionalOnlyArgIndex; } - public int getVarargsIdx() { - return varArgIndex; - } - public boolean takesVarArgs() { return varArgIndex != -1; } - public boolean isVarArgsMarker() { - return isVarArgsMarker; - } - public boolean takesVarKeywordArgs() { return takesVarKeywordArgs; } @@ -150,7 +139,7 @@ public boolean takesKeywordArgs() { } public boolean takesPositionalOnly() { - return !takesVarArgs() && !takesVarKeywordArgs && !isVarArgsMarker && keywordOnlyNames.length == 0; + return !takesVarArgs() && !takesVarKeywordArgs && keywordOnlyNames.length == 0; } public boolean takesNoArguments() { @@ -173,4 +162,8 @@ public TruffleString getRaiseErrorName() { public boolean isHidden() { return hidden; } + + public static Signature fromCallTarget(RootCallTarget callTarget) { + return callTarget.getRootNode() instanceof PRootNode rootNode ? rootNode.getSignature() : Signature.GENERIC_VARARGS; + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/WrapperDescriptorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/WrapperDescriptorBuiltins.java index 64ebc9484e..8cddaa5ee1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/WrapperDescriptorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/WrapperDescriptorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,13 +40,11 @@ */ package com.oracle.graal.python.builtins.objects.function; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; - import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; -import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; @@ -58,15 +56,13 @@ import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.DescrGetBuiltinNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.strings.TruffleString; @CoreFunctions(extendClasses = PythonBuiltinClassType.WrapperDescriptor) @@ -85,8 +81,8 @@ protected List> getNodeFa public abstract static class GetNode extends DescrGetBuiltinNode { @Specialization(guards = {"!isNoValue(instance)"}) static PMethod doMethod(PFunction self, Object instance, Object klass, - @Shared @Cached PythonObjectFactory factory) { - return factory.createMethod(PythonBuiltinClassType.MethodWrapper, instance, self); + @Bind PythonLanguage language) { + return PFactory.createMethod(language, PythonBuiltinClassType.MethodWrapper, PythonBuiltinClassType.MethodWrapper.getInstanceShape(language), instance, self); } @Specialization(guards = "isNoValue(instance)") @@ -96,8 +92,8 @@ static Object doFunction(PFunction self, Object instance, Object klass) { @Specialization(guards = {"!isNoValue(instance)"}) static PBuiltinMethod doBuiltinMethod(PBuiltinFunction self, Object instance, Object klass, - @Shared @Cached PythonObjectFactory factory) { - return factory.createBuiltinMethod(PythonBuiltinClassType.MethodWrapper, instance, self); + @Bind PythonLanguage language) { + return PFactory.createBuiltinMethod(language, PythonBuiltinClassType.MethodWrapper, PythonBuiltinClassType.MethodWrapper.getInstanceShape(language), instance, self); } @Specialization(guards = "isNoValue(instance)") @@ -106,8 +102,7 @@ static Object doBuiltinFunction(PBuiltinFunction self, Object instance, Object k } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) - @TypeSystemReference(PythonArithmeticTypes.class) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization @@ -117,7 +112,7 @@ static TruffleString reprClassFunction(PBuiltinFunction self, // XXX: this is wrong return simpleTruffleStringFormatNode.format("", self.getName()); } else { - return simpleTruffleStringFormatNode.format("", self.getName(), TypeNodes.GetNameNode.doSlowPath(self.getEnclosingType())); + return simpleTruffleStringFormatNode.format("", self.getName(), TypeNodes.GetNameNode.executeUncached(self.getEnclosingType())); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/CommonGeneratorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/CommonGeneratorBuiltins.java index 0a204506da..f115918692 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/CommonGeneratorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/CommonGeneratorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -61,14 +61,15 @@ import com.oracle.graal.python.builtins.objects.frame.PFrame; import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.traceback.PTraceback; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.bytecode.FrameInfo; import com.oracle.graal.python.nodes.bytecode.GeneratorReturnException; import com.oracle.graal.python.nodes.bytecode.GeneratorYieldResult; -import com.oracle.graal.python.nodes.call.CallTargetInvokeNode; -import com.oracle.graal.python.nodes.call.GenericInvokeNode; +import com.oracle.graal.python.nodes.call.CallDispatchers; import com.oracle.graal.python.nodes.frame.MaterializeFrameNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; @@ -77,10 +78,10 @@ import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.bytecode.ContinuationResult; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -93,6 +94,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.DirectCallNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.profiles.InlinedConditionProfile; @@ -105,7 +107,7 @@ public final class CommonGeneratorBuiltins extends PythonBuiltins { * is invoked using {@code next(g)} outside of any {@code except} handler but the generator * requests the exception state, then the exception state will be written into the arguments. If * we now use the same arguments array every time, the next invocation would think that there is - * not excepion but in fact, the a subsequent call ot {@code next} may have a different + * not an exception but in fact, a subsequent call to {@code next} may have a different * exception state. * *
      @@ -135,33 +137,34 @@ protected List> getNodeFa
               return CommonGeneratorBuiltinsFactory.getFactories();
           }
       
      -    private static void checkResumable(Node inliningTarget, PGenerator self, PRaiseNode.Lazy raiseNode) {
      +    private static void checkResumable(Node inliningTarget, PGenerator self, PRaiseNode raiseNode) {
               if (self.isFinished()) {
                   if (self.isAsyncGen()) {
      -                throw raiseNode.get(inliningTarget).raise(StopAsyncIteration);
      +                throw raiseNode.raise(inliningTarget, StopAsyncIteration);
                   }
                   if (self.isCoroutine()) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.CANNOT_REUSE_CORO);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.CANNOT_REUSE_CORO);
                   }
      -            throw raiseNode.get(inliningTarget).raiseStopIteration();
      +            throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.StopIteration);
               }
               if (self.isRunning()) {
      -            throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.GENERATOR_ALREADY_EXECUTING);
      +            throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.GENERATOR_ALREADY_EXECUTING);
               }
           }
       
           @GenerateInline
           @GenerateCached(false)
      -    @ImportStatic({PGuards.class, PythonOptions.class})
      +    @ImportStatic({PGuards.class, PythonOptions.class, CallDispatchers.class})
           abstract static class ResumeGeneratorNode extends Node {
               public abstract Object execute(VirtualFrame frame, Node inliningTarget, PGenerator self, Object sendValue);
       
      -        @Specialization(guards = "sameCallTarget(self.getCurrentCallTarget(), call.getCallTarget())", limit = "getCallSiteInlineCacheMaxDepth()")
      +        @Specialization(guards = {"!isBytecodeDSLInterpreter()", "sameCallTarget(self.getCurrentCallTarget(), callNode)"}, limit = "getCallSiteInlineCacheMaxDepth()")
               static Object cached(VirtualFrame frame, Node inliningTarget, PGenerator self, Object sendValue,
      -                        @Cached(value = "createDirectCall(self.getCurrentCallTarget())", inline = false) CallTargetInvokeNode call,
      +                        @Cached(parameters = "self.getCurrentCallTarget()") DirectCallNode callNode,
      +                        @Cached CallDispatchers.SimpleDirectInvokeNode invoke,
                               @Exclusive @Cached InlinedBranchProfile returnProfile,
                               @Exclusive @Cached IsBuiltinObjectProfile errorProfile,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   self.setRunning(true);
                   Object[] arguments = prepareArguments(self);
                   if (sendValue != null) {
      @@ -169,26 +172,80 @@ static Object cached(VirtualFrame frame, Node inliningTarget, PGenerator self, O
                   }
                   GeneratorYieldResult result;
                   try {
      -                result = (GeneratorYieldResult) call.execute(frame, null, null, null, arguments);
      +                result = (GeneratorYieldResult) invoke.execute(frame, inliningTarget, callNode, arguments);
                   } catch (PException e) {
                       throw handleException(self, inliningTarget, errorProfile, raiseNode, e);
                   } catch (GeneratorReturnException e) {
                       returnProfile.enter(inliningTarget);
      -                throw handleReturn(self, e, raiseNode.get(inliningTarget));
      +                throw handleReturn(inliningTarget, self, e.value);
                   } finally {
                       self.setRunning(false);
                   }
                   return handleResult(inliningTarget, self, result);
               }
       
      -        @Specialization(replaces = "cached")
      +        @Specialization(guards = {"isBytecodeDSLInterpreter()", "sameCallTarget(self.getCurrentCallTarget(), callNode)"}, limit = "getCallSiteInlineCacheMaxDepth()")
      +        static Object cachedBytecodeDSL(VirtualFrame frame, Node inliningTarget, PGenerator self, Object sendValue,
      +                        @Cached(parameters = "self.getCurrentCallTarget()") DirectCallNode callNode,
      +                        @Cached CallDispatchers.SimpleDirectInvokeNode invoke,
      +                        @Cached("self.getContinuation() == null") boolean firstCall,
      +                        @Exclusive @Cached InlinedBranchProfile returnProfile,
      +                        @Exclusive @Cached IsBuiltinObjectProfile errorProfile,
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
      +            self.setRunning(true);
      +            Object generatorResult;
      +            try {
      +                ContinuationResult continuation = self.getContinuation();
      +                Object[] arguments;
      +                // TODO: GR-62196, Bytecode DSL does not have the same shape of arguments array for
      +                // continuation calls:
      +
      +                // 1) in the manual interpreter, we always pass an array of the same length (with
      +                // slots defined in PArguments), this argument array is used for callee context
      +                // enter/exit in PBytecodeGeneratorRootNode as opposed to the original arguments
      +                // array taken from the PGenerator object. Moreover, this array is a copy of
      +                // PGenerator arguments, and the comment above prepareArguments seems to indicate
      +                // that we indeed need a fresh copy, because we do not want to share the state
      +                // stored in the arguments between invocations
      +
      +                // 2) Bytecode DSL doesn't do callee context enter/exit for individual calls,
      +                // but for the whole coroutine
      +
      +                // 3) when walking the stack, e.g., in MaterializeFrameNode, we must take care of
      +                // this additional arguments shape and unwrap the materialized frame from the
      +                // continuation frame to access its arguments array that will have the desired
      +                // "PArguments shape", however this will be a shared arguments array, so it is a
      +                // question if this unwrapping would be correct, see 1).
      +
      +                if (firstCall) {
      +                    // First invocation: call the regular root node.
      +                    arguments = prepareArguments(self);
      +                } else {
      +                    // Subsequent invocations: call a continuation root node.
      +                    arguments = new Object[]{continuation.getFrame(), sendValue};
      +                }
      +                generatorResult = invoke.execute(frame, inliningTarget, callNode, arguments);
      +            } catch (PException e) {
      +                throw handleException(self, inliningTarget, errorProfile, raiseNode, e);
      +            } finally {
      +                self.setRunning(false);
      +            }
      +            if (generatorResult instanceof ContinuationResult continuation) {
      +                return handleResult(inliningTarget, self, continuation);
      +            } else {
      +                returnProfile.enter(inliningTarget);
      +                throw handleReturn(inliningTarget, self, generatorResult);
      +            }
      +
      +        }
      +
      +        @Specialization(replaces = "cached", guards = "!isBytecodeDSLInterpreter()")
               @Megamorphic
               static Object generic(VirtualFrame frame, Node inliningTarget, PGenerator self, Object sendValue,
      -                        @Cached InlinedConditionProfile hasFrameProfile,
      -                        @Cached(inline = false) GenericInvokeNode call,
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke,
                               @Exclusive @Cached InlinedBranchProfile returnProfile,
                               @Exclusive @Cached IsBuiltinObjectProfile errorProfile,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   self.setRunning(true);
                   Object[] arguments = prepareArguments(self);
                   if (sendValue != null) {
      @@ -196,60 +253,82 @@ static Object generic(VirtualFrame frame, Node inliningTarget, PGenerator self,
                   }
                   GeneratorYieldResult result;
                   try {
      -                if (hasFrameProfile.profile(inliningTarget, frame != null)) {
      -                    result = (GeneratorYieldResult) call.execute(frame, self.getCurrentCallTarget(), arguments);
      -                } else {
      -                    result = (GeneratorYieldResult) call.execute(self.getCurrentCallTarget(), arguments);
      -                }
      +                result = (GeneratorYieldResult) invoke.execute(frame, inliningTarget, self.getCurrentCallTarget(), arguments);
                   } catch (PException e) {
                       throw handleException(self, inliningTarget, errorProfile, raiseNode, e);
                   } catch (GeneratorReturnException e) {
                       returnProfile.enter(inliningTarget);
      -                throw handleReturn(self, e, raiseNode.get(inliningTarget));
      +                throw handleReturn(inliningTarget, self, e.value);
                   } finally {
                       self.setRunning(false);
                   }
                   return handleResult(inliningTarget, self, result);
               }
       
      -        private static PException handleException(PGenerator self, Node inliningTarget, IsBuiltinObjectProfile profile, PRaiseNode.Lazy raiseNode, PException e) {
      +        @Specialization(replaces = "cachedBytecodeDSL", guards = "isBytecodeDSLInterpreter()")
      +        @Megamorphic
      +        static Object genericBytecodeDSL(VirtualFrame frame, Node inliningTarget, PGenerator self, Object sendValue,
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke,
      +                        @Cached InlinedConditionProfile firstInvocationProfile,
      +                        @Cached InlinedBranchProfile returnProfile,
      +                        @Cached IsBuiltinObjectProfile errorProfile,
      +                        @Cached PRaiseNode raiseNode) {
      +            self.setRunning(true);
      +            Object generatorResult;
      +            try {
      +                ContinuationResult continuation = self.getContinuation();
      +                Object[] arguments;
      +                if (firstInvocationProfile.profile(inliningTarget, continuation == null)) {
      +                    // First invocation: call the regular root node.
      +                    arguments = prepareArguments(self);
      +                } else {
      +                    // Subsequent invocations: call a continuation root node.
      +                    arguments = new Object[]{continuation.getFrame(), sendValue};
      +                }
      +
      +                generatorResult = invoke.execute(frame, inliningTarget, self.getCurrentCallTarget(), arguments);
      +            } catch (PException e) {
      +                throw handleException(self, inliningTarget, errorProfile, raiseNode, e);
      +            } finally {
      +                self.setRunning(false);
      +            }
      +            if (generatorResult instanceof ContinuationResult continuation) {
      +                return handleResult(inliningTarget, self, continuation);
      +            } else {
      +                returnProfile.enter(inliningTarget);
      +                throw handleReturn(inliningTarget, self, generatorResult);
      +            }
      +        }
      +
      +        private static PException handleException(PGenerator self, Node inliningTarget, IsBuiltinObjectProfile profile, PRaiseNode raiseNode, PException e) {
                   self.markAsFinished();
                   if (self.isAsyncGen()) {
                       // Async generators need to wrap StopAsyncIteration in a runtime error
                       if (profile.profileException(inliningTarget, e, StopAsyncIteration)) {
      -                    throw raiseNode.get(inliningTarget).raiseWithCause(RuntimeError, e.getEscapedException(), ErrorMessages.ASYNCGEN_RAISED_ASYNCSTOPITER);
      +                    throw raiseNode.raiseWithCause(inliningTarget, RuntimeError, e, ErrorMessages.ASYNCGEN_RAISED_ASYNCSTOPITER);
                       }
                   }
                   // PEP 479 - StopIteration raised from generator body needs to be wrapped in
                   // RuntimeError
                   e.expectStopIteration(inliningTarget, profile);
      -            throw raiseNode.get(inliningTarget).raiseWithCause(RuntimeError, e.getEscapedException(), ErrorMessages.GENERATOR_RAISED_STOPITER);
      +            throw raiseNode.raiseWithCause(inliningTarget, RuntimeError, e, ErrorMessages.GENERATOR_RAISED_STOPITER);
               }
       
      -        private static Object handleResult(Node node, PGenerator self, GeneratorYieldResult result) {
      -            self.handleResult(PythonLanguage.get(node), result);
      -            return result.yieldValue;
      +        private static Object handleResult(Node node, PGenerator self, Object result) {
      +            return self.handleResult(PythonLanguage.get(node), result);
               }
       
      -        private static PException handleReturn(PGenerator self, GeneratorReturnException e, PRaiseNode raiseNode) {
      +        private static PException handleReturn(Node inliningTarget, PGenerator self, Object returnValue) {
                   self.markAsFinished();
                   if (self.isAsyncGen()) {
      -                throw raiseNode.raise(StopAsyncIteration);
      +                throw PRaiseNode.raiseStatic(inliningTarget, StopAsyncIteration);
                   }
      -            if (e.value != PNone.NONE) {
      -                throw raiseNode.raise(StopIteration, new Object[]{e.value});
      +            if (returnValue != PNone.NONE) {
      +                throw PRaiseNode.raiseStatic(inliningTarget, StopIteration, new Object[]{returnValue});
                   } else {
      -                throw raiseNode.raise(StopIteration);
      +                throw TpIterNextBuiltin.iteratorExhausted();
                   }
               }
      -
      -        protected static CallTargetInvokeNode createDirectCall(CallTarget target) {
      -            return CallTargetInvokeNode.create(target, false, true);
      -        }
      -
      -        protected static boolean sameCallTarget(RootCallTarget target1, CallTarget target2) {
      -            return target1 == target2;
      -        }
           }
       
           @Builtin(name = "send", minNumOfPositionalArgs = 2)
      @@ -260,14 +339,18 @@ public abstract static class SendNode extends PythonBinaryBuiltinNode {
               static Object send(VirtualFrame frame, PGenerator self, Object value,
                               @Bind("this") Node inliningTarget,
                               @Cached ResumeGeneratorNode resumeGeneratorNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   // even though this isn't a builtin for async generators, SendNode is used on async
                   // generators by PAsyncGenSend
                   checkResumable(inliningTarget, self, raiseNode);
                   if (!self.isStarted() && value != PNone.NONE) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.SEND_NON_NONE_TO_UNSTARTED_GENERATOR);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.SEND_NON_NONE_TO_UNSTARTED_GENERATOR);
      +            }
      +            try {
      +                return resumeGeneratorNode.execute(frame, inliningTarget, self, value);
      +            } catch (IteratorExhausted e) {
      +                throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.StopIteration);
                   }
      -            return resumeGeneratorNode.execute(frame, inliningTarget, self, value);
               }
           }
       
      @@ -288,16 +371,15 @@ static Object sendThrow(VirtualFrame frame, PGenerator self, Object typ, Object
                               @Cached ExceptionNodes.GetTracebackNode getTracebackNode,
                               @Cached ExceptionNodes.SetTracebackNode setTracebackNode,
                               @Cached ExceptionNodes.SetContextNode setContextNode,
      -                        @Cached PythonObjectFactory.Lazy factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   boolean hasTb = hasTbProfile.profile(inliningTarget, !(tb instanceof PNone));
                   if (hasTb && !(tb instanceof PTraceback)) {
                       invalidTbProfile.enter(inliningTarget);
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.THROW_THIRD_ARG_MUST_BE_TRACEBACK);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.THROW_THIRD_ARG_MUST_BE_TRACEBACK);
                   }
                   if (self.isRunning()) {
                       runningProfile.enter(inliningTarget);
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.GENERATOR_ALREADY_EXECUTING);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.GENERATOR_ALREADY_EXECUTING);
                   }
                   Object instance = prepareExceptionNode.execute(frame, typ, val);
                   if (hasTb) {
      @@ -307,12 +389,16 @@ static Object sendThrow(VirtualFrame frame, PGenerator self, Object typ, Object
                   setContextNode.execute(inliningTarget, instance, PNone.NONE); // Will be filled when
                                                                                 // caught
                   if (self.isCoroutine() && self.isFinished()) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.CANNOT_REUSE_CORO);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.CANNOT_REUSE_CORO);
                   }
                   if (startedProfile.profile(inliningTarget, self.isStarted() && !self.isFinished())) {
                       // Pass it to the generator where it will be thrown by the last yield, the location
                       // will be filled there
      -                return resumeGeneratorNode.execute(frame, inliningTarget, self, new ThrowData(instance, PythonOptions.isPExceptionWithJavaStacktrace(language)));
      +                try {
      +                    return resumeGeneratorNode.execute(frame, inliningTarget, self, new ThrowData(instance, PythonOptions.isPExceptionWithJavaStacktrace(language)));
      +                } catch (IteratorExhausted e) {
      +                    throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.StopIteration);
      +                }
                   } else {
                       // Unstarted generator, we cannot pass the exception into the generator as there is
                       // nothing that would handle it.
      @@ -320,15 +406,20 @@ static Object sendThrow(VirtualFrame frame, PGenerator self, Object typ, Object
                       // its frame to the traceback manually.
                       self.markAsFinished();
                       Node location = self.getCurrentCallTarget().getRootNode();
      -                MaterializedFrame generatorFrame = PArguments.getGeneratorFrame(self.getArguments());
      -                PFrame pFrame = MaterializeFrameNode.materializeGeneratorFrame(location, generatorFrame, PFrame.Reference.EMPTY, factory.get(inliningTarget));
      +                MaterializedFrame generatorFrame;
      +                if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
      +                    generatorFrame = Truffle.getRuntime().createMaterializedFrame(PArguments.create(), self.getRootNode().getFrameDescriptor());
      +                } else {
      +                    generatorFrame = PArguments.getGeneratorFrame(self.getArguments());
      +                }
      +                PFrame pFrame = MaterializeFrameNode.materializeGeneratorFrame(location, generatorFrame, PFrame.Reference.EMPTY);
                       FrameInfo info = (FrameInfo) generatorFrame.getFrameDescriptor().getInfo();
      -                pFrame.setLine(info.getRootNode().getFirstLineno());
      +                pFrame.setLine(info.getFirstLineNumber());
                       Object existingTracebackObj = getTracebackNode.execute(inliningTarget, instance);
      -                PTraceback newTraceback = factory.get(inliningTarget).createTraceback(pFrame, pFrame.getLine(),
      +                PTraceback newTraceback = PFactory.createTraceback(language, pFrame, pFrame.getLine(),
                                       (existingTracebackObj instanceof PTraceback existingTraceback) ? existingTraceback : null);
                       setTracebackNode.execute(inliningTarget, instance, newTraceback);
      -                throw PException.fromObject(instance, location, PythonOptions.isPExceptionWithJavaStacktrace(language));
      +                throw PException.fromObject(instance, inliningTarget, PythonOptions.isPExceptionWithJavaStacktrace(language));
                   }
               }
           }
      @@ -343,18 +434,20 @@ static Object close(VirtualFrame frame, PGenerator self,
                               @Cached IsBuiltinObjectProfile isStopIteration,
                               @Cached ResumeGeneratorNode resumeGeneratorNode,
                               @Cached InlinedConditionProfile isStartedPorfile,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (self.isRunning()) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.GENERATOR_ALREADY_EXECUTING);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.GENERATOR_ALREADY_EXECUTING);
                   }
                   if (isStartedPorfile.profile(inliningTarget, self.isStarted() && !self.isFinished())) {
      -                PBaseException pythonException = factory.createBaseException(GeneratorExit);
      +                PBaseException pythonException = PFactory.createBaseException(PythonLanguage.get(inliningTarget), GeneratorExit);
                       // Pass it to the generator where it will be thrown by the last yield, the location
                       // will be filled there
                       boolean withJavaStacktrace = PythonOptions.isPExceptionWithJavaStacktrace(PythonLanguage.get(inliningTarget));
                       try {
                           resumeGeneratorNode.execute(frame, inliningTarget, self, new ThrowData(pythonException, withJavaStacktrace));
      +                } catch (IteratorExhausted e) {
      +                    // This is the "success" path
      +                    return PNone.NONE;
                       } catch (PException pe) {
                           if (isGeneratorExit.profileException(inliningTarget, pe, GeneratorExit) || isStopIteration.profileException(inliningTarget, pe, StopIteration)) {
                               // This is the "success" path
      @@ -364,7 +457,7 @@ static Object close(VirtualFrame frame, PGenerator self,
                       } finally {
                           self.markAsFinished();
                       }
      -                throw raiseNode.get(inliningTarget).raise(RuntimeError, ErrorMessages.GENERATOR_IGNORED_EXIT);
      +                throw raiseNode.raise(inliningTarget, RuntimeError, ErrorMessages.GENERATOR_IGNORED_EXIT);
                   } else {
                       self.markAsFinished();
                       return PNone.NONE;
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/CoroutineBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/CoroutineBuiltins.java
      index 3ffbaacefe..85a25d7d98 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/CoroutineBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/CoroutineBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,11 +40,11 @@
        */
       package com.oracle.graal.python.builtins.objects.generator;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___AWAIT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
      -
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -52,9 +52,10 @@
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -67,6 +68,9 @@
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PCoroutine)
       public final class CoroutineBuiltins extends PythonBuiltins {
      +
      +    public static final TpSlots SLOTS = CoroutineBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return CoroutineBuiltinsFactory.getFactories();
      @@ -78,9 +82,8 @@ public abstract static class GetCode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object getCode(PGenerator self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached InlinedConditionProfile hasCodeProfile,
      -                        @Cached PythonObjectFactory.Lazy factory) {
      -            return self.getOrCreateCode(inliningTarget, hasCodeProfile, factory);
      +                        @Cached InlinedConditionProfile hasCodeProfile) {
      +            return self.getOrCreateCode(inliningTarget, hasCodeProfile);
               }
           }
       
      @@ -122,17 +125,17 @@ static boolean suspended(PGenerator self) {
               }
           }
       
      -    @Builtin(name = J___AWAIT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.am_await, isComplex = true)
           @GenerateNodeFactory
           abstract static class AwaitNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object await(PGenerator self,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createCoroutineWrapper(self);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createCoroutineWrapper(language, self);
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
               @Specialization
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/GeneratorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/GeneratorBuiltins.java
      index f4dd2ac5af..01342aa0c9 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/GeneratorBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/GeneratorBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2017, 2024, Oracle and/or its affiliates.
      + * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
        * Copyright (c) 2014, Regents of the University of California
        *
        * All rights reserved.
      @@ -31,13 +31,13 @@
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___QUALNAME__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -48,14 +48,20 @@
       import com.oracle.graal.python.builtins.objects.function.PArguments;
       import com.oracle.graal.python.builtins.objects.str.StringNodes;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
      -import com.oracle.graal.python.nodes.bytecode.FrameInfo;
      +import com.oracle.graal.python.nodes.bytecode.BytecodeFrameInfo;
      +import com.oracle.graal.python.nodes.bytecode_dsl.BytecodeDSLFrameInfo;
       import com.oracle.graal.python.nodes.frame.MaterializeFrameNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.PythonOptions;
      +import com.oracle.graal.python.runtime.object.PFactory;
      +import com.oracle.truffle.api.bytecode.BytecodeLocation;
      +import com.oracle.truffle.api.bytecode.ContinuationResult;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -70,15 +76,17 @@
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PGenerator)
       public final class GeneratorBuiltins extends PythonBuiltins {
       
      -    private static void checkResumable(Node inliningTarget, PGenerator self, PRaiseNode.Lazy raiseNode) {
      +    private static void checkResumable(Node inliningTarget, PGenerator self, PRaiseNode raiseNode) {
               if (self.isFinished()) {
      -            throw raiseNode.get(inliningTarget).raiseStopIteration();
      +            throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.StopIteration);
               }
               if (self.isRunning()) {
      -            throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.GENERATOR_ALREADY_EXECUTING);
      +            throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.GENERATOR_ALREADY_EXECUTING);
               }
           }
       
      +    public static final TpSlots SLOTS = GeneratorBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return GeneratorBuiltinsFactory.getFactories();
      @@ -128,7 +136,7 @@ static Object setQualname(PGenerator self, Object value,
               }
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
       
      @@ -138,15 +146,20 @@ static Object iter(PGenerator self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1, doc = "Implement next(self).")
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization
               static Object next(VirtualFrame frame, PGenerator self,
                               @Bind("this") Node inliningTarget,
                               @Cached CommonGeneratorBuiltins.ResumeGeneratorNode resumeGeneratorNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      -            checkResumable(inliningTarget, self, raiseNode);
      +                        @Cached PRaiseNode raiseNode) {
      +            if (self.isFinished()) {
      +                throw iteratorExhausted();
      +            }
      +            if (self.isRunning()) {
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.GENERATOR_ALREADY_EXECUTING);
      +            }
                   return resumeGeneratorNode.execute(frame, inliningTarget, self, null);
               }
           }
      @@ -157,9 +170,8 @@ public abstract static class GetCodeNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object getCode(PGenerator self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached InlinedConditionProfile hasCodeProfile,
      -                        @Cached PythonObjectFactory.Lazy factory) {
      -            return self.getOrCreateCode(inliningTarget, hasCodeProfile, factory);
      +                        @Cached InlinedConditionProfile hasCodeProfile) {
      +            return self.getOrCreateCode(inliningTarget, hasCodeProfile);
               }
           }
       
      @@ -173,8 +185,8 @@ static Object getRunning(PGenerator self, @SuppressWarnings("unused") PNone none
       
               @Specialization(guards = "!isNoValue(obj)")
               static Object setRunning(@SuppressWarnings("unused") PGenerator self, @SuppressWarnings("unused") Object obj,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(AttributeError, ErrorMessages.ATTRIBUTE_S_OF_P_OBJECTS_IS_NOT_WRITABLE, "gi_running", self);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, ErrorMessages.ATTRIBUTE_S_OF_P_OBJECTS_IS_NOT_WRITABLE, "gi_running", self);
               }
           }
       
      @@ -182,19 +194,29 @@ static Object setRunning(@SuppressWarnings("unused") PGenerator self, @SuppressW
           @GenerateNodeFactory
           public abstract static class GetFrameNode extends PythonUnaryBuiltinNode {
               @Specialization
      -        static Object getFrame(PGenerator self,
      -                        @Cached PythonObjectFactory factory) {
      +        static Object getFrame(PGenerator self) {
                   if (self.isFinished()) {
                       return PNone.NONE;
                   } else {
      -                MaterializedFrame generatorFrame = PArguments.getGeneratorFrame(self.getArguments());
      -                Node location = ((FrameInfo) generatorFrame.getFrameDescriptor().getInfo()).getRootNode();
      -                PFrame frame = MaterializeFrameNode.materializeGeneratorFrame(location, generatorFrame, PFrame.Reference.EMPTY, factory);
      -                FrameInfo info = (FrameInfo) generatorFrame.getFrameDescriptor().getInfo();
      -                int bci = self.getBci();
      -                frame.setBci(bci);
      -                frame.setLine(info.getRootNode().bciToLine(bci));
      -                return frame;
      +                if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
      +                    ContinuationResult continuation = self.getContinuation();
      +                    BytecodeLocation location = continuation.getBytecodeLocation();
      +                    MaterializedFrame generatorFrame = continuation.getFrame();
      +                    BytecodeDSLFrameInfo info = (BytecodeDSLFrameInfo) generatorFrame.getFrameDescriptor().getInfo();
      +                    PFrame frame = MaterializeFrameNode.materializeGeneratorFrame(location.getBytecodeNode(), generatorFrame, PFrame.Reference.EMPTY);
      +                    int bci = location.getBytecodeIndex();
      +                    frame.setBci(bci);
      +                    frame.setLine(info.getRootNode().bciToLine(bci, location.getBytecodeNode()));
      +                    return frame;
      +                } else {
      +                    MaterializedFrame generatorFrame = PArguments.getGeneratorFrame(self.getArguments());
      +                    BytecodeFrameInfo info = (BytecodeFrameInfo) generatorFrame.getFrameDescriptor().getInfo();
      +                    PFrame frame = MaterializeFrameNode.materializeGeneratorFrame(info.getRootNode(), generatorFrame, PFrame.Reference.EMPTY);
      +                    int bci = self.getBci();
      +                    frame.setBci(bci);
      +                    frame.setLine(info.getRootNode().bciToLine(bci));
      +                    return frame;
      +                }
                   }
               }
           }
      @@ -218,7 +240,7 @@ static boolean suspended(PGenerator self) {
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -233,8 +255,8 @@ static TruffleString repr(PGenerator self,
           public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode {
               @Specialization
               static Object classGetItem(Object cls, Object key,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createGenericAlias(cls, key);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createGenericAlias(language, cls, key);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/PGenerator.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/PGenerator.java
      index 2325e7cfc9..7f7888b099 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/PGenerator.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/PGenerator.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2017, 2023, Oracle and/or its affiliates.
      + * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
        * Copyright (c) 2013, Regents of the University of California
        *
        * All rights reserved.
      @@ -31,15 +31,21 @@
       import com.oracle.graal.python.builtins.objects.code.PCode;
       import com.oracle.graal.python.builtins.objects.function.PArguments;
       import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
      +import com.oracle.graal.python.nodes.bytecode.BytecodeFrameInfo;
       import com.oracle.graal.python.nodes.bytecode.FrameInfo;
       import com.oracle.graal.python.nodes.bytecode.GeneratorYieldResult;
       import com.oracle.graal.python.nodes.bytecode.PBytecodeGeneratorRootNode;
       import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.nodes.bytecode_dsl.BytecodeDSLFrameInfo;
      +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode;
      +import com.oracle.graal.python.runtime.PythonOptions;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
      +import com.oracle.truffle.api.bytecode.ContinuationResult;
       import com.oracle.truffle.api.RootCallTarget;
       import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.nodes.RootNode;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       
      @@ -47,32 +53,94 @@ public class PGenerator extends PythonBuiltinObject {
       
           private TruffleString name;
           private TruffleString qualname;
      -    /**
      -     * Call targets with copies of the generator's AST. Each call target corresponds to one possible
      -     * entry point into the generator: the first call, and continuation for each yield. Each AST can
      -     * then specialize towards which nodes are executed when starting from that particular entry
      -     * point. When yielding, the next index to the next call target to continue from is updated via
      -     * {@link #handleResult}.
      -     */
      -    @CompilationFinal(dimensions = 1) protected final RootCallTarget[] callTargets;
      -    protected final Object[] arguments;
      -    private boolean finished;
      -    private PCode code;
      -    private int currentCallTarget;
      -    private final PBytecodeRootNode bytecodeRootNode;
           private final FrameInfo frameInfo;
      +
      +    private boolean finished;
           // running means it is currently on the stack, not just started
           private boolean running;
           private final boolean isCoroutine;
           private final boolean isAsyncGen;
       
      +    private PCode code;
      +    protected final Object[] arguments;
      +
      +    // TODO (GR-38700): remove BytecodeState after migrated to the Bytecode DSL interpreter.
      +    protected static class BytecodeState {
      +        private final PBytecodeRootNode rootNode;
      +
      +        /**
      +         * Call targets with copies of the generator's AST. Each call target corresponds to one
      +         * possible entry point into the generator: the first call, and continuation for each yield.
      +         * Each AST can then specialize towards which nodes are executed when starting from that
      +         * particular entry point. When yielding, the next index to the next call target to continue
      +         * from is updated via {@link #handleResult}.
      +         */
      +        @CompilationFinal(dimensions = 1) private final RootCallTarget[] callTargets;
      +        private int currentCallTarget;
      +
      +        public BytecodeState(PBytecodeRootNode rootNode, RootCallTarget[] callTargets) {
      +            this.rootNode = rootNode;
      +            this.callTargets = callTargets;
      +            this.currentCallTarget = 0;
      +        }
      +
      +        public RootCallTarget getCurrentCallTarget() {
      +            return callTargets[currentCallTarget];
      +        }
      +
      +        public PBytecodeGeneratorRootNode getCurrentRootNode() {
      +            return (PBytecodeGeneratorRootNode) getCurrentCallTarget().getRootNode();
      +        }
      +
      +        public Object handleResult(PythonLanguage language, GeneratorYieldResult result) {
      +            currentCallTarget = result.resumeBci;
      +            if (callTargets[currentCallTarget] == null) {
      +                CompilerDirectives.transferToInterpreterAndInvalidate();
      +                PBytecodeGeneratorRootNode generatorRootNode = new PBytecodeGeneratorRootNode(language, rootNode, result.resumeBci, result.resumeStackTop);
      +                callTargets[currentCallTarget] = generatorRootNode.getCallTarget();
      +            }
      +            return result.yieldValue;
      +        }
      +    }
      +
      +    private static class BytecodeDSLState {
      +        private final PBytecodeDSLRootNode rootNode;
      +        private ContinuationResult yieldResult;
      +
      +        public BytecodeDSLState(PBytecodeDSLRootNode rootNode) {
      +            this.rootNode = rootNode;
      +            this.yieldResult = null;
      +        }
      +
      +        public Object handleResult(ContinuationResult result) {
      +            yieldResult = result;
      +            return result.getResult();
      +        }
      +    }
      +
      +    // This is either BytecodeState or BytecodeDSLState.
      +    private final Object state;
      +
      +    private BytecodeState getBytecodeState() {
      +        return (BytecodeState) state;
      +    }
      +
      +    private BytecodeDSLState getBytecodeDSLState() {
      +        return (BytecodeDSLState) state;
      +    }
      +
           // An explicit isIterableCoroutine argument is needed for iterable coroutines (generally created
           // via types.coroutine)
           public static PGenerator create(PythonLanguage lang, TruffleString name, TruffleString qualname, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, Object[] arguments,
                           PythonBuiltinClassType cls, boolean isIterableCoroutine) {
               // note: also done in PAsyncGen.create
               rootNode.createGeneratorFrame(arguments);
      -        return new PGenerator(lang, name, qualname, rootNode, callTargets, arguments, cls, isIterableCoroutine);
      +        return new PGenerator(lang, name, qualname, arguments, cls, isIterableCoroutine, new BytecodeState(rootNode, callTargets));
      +    }
      +
      +    public static PGenerator create(PythonLanguage lang, TruffleString name, TruffleString qualname, PBytecodeDSLRootNode rootNode, Object[] arguments,
      +                    PythonBuiltinClassType cls, boolean isIterableCoroutine) {
      +        return new PGenerator(lang, name, qualname, arguments, cls, isIterableCoroutine, new BytecodeDSLState(rootNode));
           }
       
           public static PGenerator create(PythonLanguage lang, TruffleString name, TruffleString qualname, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, Object[] arguments,
      @@ -80,61 +148,79 @@ public static PGenerator create(PythonLanguage lang, TruffleString name, Truffle
               return create(lang, name, qualname, rootNode, callTargets, arguments, cls, false);
           }
       
      -    protected PGenerator(PythonLanguage lang, TruffleString name, TruffleString qualname, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, Object[] arguments, PythonBuiltinClassType cls,
      -                    boolean isIterableCoroutine) {
      +    public static PGenerator create(PythonLanguage lang, TruffleString name, TruffleString qualname, PBytecodeDSLRootNode rootNode, Object[] arguments,
      +                    PythonBuiltinClassType cls) {
      +        return create(lang, name, qualname, rootNode, arguments, cls, false);
      +    }
      +
      +    protected PGenerator(PythonLanguage lang, TruffleString name, TruffleString qualname, Object[] arguments, PythonBuiltinClassType cls, boolean isIterableCoroutine, Object state) {
               super(cls, cls.getInstanceShape(lang));
               this.name = name;
               this.qualname = qualname;
      -        this.callTargets = callTargets;
      -        this.currentCallTarget = 0;
               this.arguments = arguments;
               this.finished = false;
      -        this.bytecodeRootNode = rootNode;
      -        this.frameInfo = (FrameInfo) rootNode.getFrameDescriptor().getInfo();
               this.isCoroutine = isIterableCoroutine || cls == PythonBuiltinClassType.PCoroutine;
               this.isAsyncGen = cls == PythonBuiltinClassType.PAsyncGenerator;
      +        if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
      +            BytecodeDSLState bytecodeDSLState = (BytecodeDSLState) state;
      +            this.state = state;
      +            this.frameInfo = (BytecodeDSLFrameInfo) bytecodeDSLState.rootNode.getFrameDescriptor().getInfo();
      +        } else {
      +            BytecodeState bytecodeState = (BytecodeState) state;
      +            this.state = state;
      +            this.frameInfo = (BytecodeFrameInfo) bytecodeState.rootNode.getFrameDescriptor().getInfo();
      +        }
           }
       
      -    public final void handleResult(PythonLanguage language, GeneratorYieldResult result) {
      -        currentCallTarget = result.resumeBci;
      -        if (callTargets[currentCallTarget] == null) {
      -            CompilerDirectives.transferToInterpreterAndInvalidate();
      -            PBytecodeGeneratorRootNode rootNode = new PBytecodeGeneratorRootNode(language, bytecodeRootNode, result.resumeBci, result.resumeStackTop);
      -            callTargets[currentCallTarget] = rootNode.getCallTarget();
      +    public RootNode getRootNode() {
      +        if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
      +            return getBytecodeDSLState().rootNode;
      +        } else {
      +            return getBytecodeState().rootNode;
               }
           }
       
           /**
      -     * Returns the call target that should be used the next time the generator is called. Each time
      -     * a generator call target returns through a yield, the generator should be updated with the
      -     * next yield index to use via {@link #handleResult}
      +     * Returns the call target that should be used the next time the generator is called.
            */
      -    public final RootCallTarget getCurrentCallTarget() {
      -        return callTargets[currentCallTarget];
      +    public RootCallTarget getCurrentCallTarget() {
      +        if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
      +            BytecodeDSLState bytecodeDSLState = getBytecodeDSLState();
      +            if (bytecodeDSLState.yieldResult == null) {
      +                return bytecodeDSLState.rootNode.getCallTarget();
      +            }
      +            return bytecodeDSLState.yieldResult.getContinuationCallTarget();
      +        } else {
      +            return getBytecodeState().getCurrentCallTarget();
      +        }
           }
       
      -    public final Object getYieldFrom() {
      -        if (running || finished) {
      +    public Object getYieldFrom() {
      +        if (isRunning() || isFinished()) {
                   return null;
               }
      -        return frameInfo.getYieldFrom(PArguments.getGeneratorFrame(arguments), getBci(), getCurrentRootNode().getResumeStackTop());
      -    }
       
      -    private PBytecodeGeneratorRootNode getCurrentRootNode() {
      -        return (PBytecodeGeneratorRootNode) getCurrentCallTarget().getRootNode();
      +        if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
      +            throw new UnsupportedOperationException("not implemented"); // TODO: GR-64250
      +        } else {
      +            return frameInfo.getYieldFrom(PArguments.getGeneratorFrame(arguments), getBci(), getBytecodeState().getCurrentRootNode().getResumeStackTop());
      +        }
      +
           }
       
      -    public final boolean isStarted() {
      -        return currentCallTarget != 0 && !running;
      +    public boolean isStarted() {
      +        if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
      +            return getBytecodeDSLState().yieldResult != null && !isRunning();
      +        } else {
      +            return getBytecodeState().currentCallTarget != 0 && !isRunning();
      +        }
           }
       
      -    public final int getBci() {
      -        if (!isStarted()) {
      -            return -1;
      -        } else if (finished) {
      -            return bytecodeRootNode.getCodeUnit().code.length;
      +    public Object handleResult(PythonLanguage language, Object result) {
      +        if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
      +            return getBytecodeDSLState().handleResult((ContinuationResult) result);
               } else {
      -            return getCurrentRootNode().getResumeBci();
      +            return getBytecodeState().handleResult(language, (GeneratorYieldResult) result);
               }
           }
       
      @@ -155,11 +241,10 @@ public final String toString() {
               return "";
           }
       
      -    public final PCode getOrCreateCode(Node inliningTarget, InlinedConditionProfile hasCodeProfile, PythonObjectFactory.Lazy factory) {
      +    public final PCode getOrCreateCode(Node inliningTarget, InlinedConditionProfile hasCodeProfile) {
               if (hasCodeProfile.profile(inliningTarget, code == null)) {
      -            RootCallTarget callTarget;
      -            callTarget = bytecodeRootNode.getCallTarget();
      -            code = factory.get(inliningTarget).createCode(callTarget);
      +            RootCallTarget callTarget = getRootNode().getCallTarget();
      +            code = PFactory.createCode(PythonLanguage.get(inliningTarget), callTarget);
               }
               return code;
           }
      @@ -196,4 +281,20 @@ public final boolean isCoroutine() {
           public final boolean isAsyncGen() {
               return isAsyncGen;
           }
      +
      +    public int getBci() {
      +        assert !PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER;
      +        if (!isStarted()) {
      +            return -1;
      +        } else if (isFinished()) {
      +            return getBytecodeState().rootNode.getCodeUnit().code.length;
      +        } else {
      +            return getBytecodeState().getCurrentRootNode().getResumeBci();
      +        }
      +    }
      +
      +    public ContinuationResult getContinuation() {
      +        assert PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER;
      +        return getBytecodeDSLState().yieldResult;
      +    }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/DescriptorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/DescriptorBuiltins.java
      index 09f580f2da..0d569b0e38 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/DescriptorBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/DescriptorBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -55,7 +55,6 @@
       import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetIndexedSlotsCountNode;
      -import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetFixedAttributeNode;
      @@ -142,10 +141,10 @@ abstract static class DescriptorCheckNode extends Node {
               static void check(Node inliningTarget, Object descrType, Object name, Object obj,
                               @Cached GetClassNode getClassNode,
                               @Cached(inline = false) IsSubtypeNode isSubtypeNode,
      -                        @Cached(inline = false) PRaiseNode raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object type = getClassNode.execute(inliningTarget, obj);
                   if (!isSubtypeNode.execute(type, descrType)) {
      -                throw raiseNode.raise(TypeError, ErrorMessages.DESC_S_FOR_N_DOESNT_APPLY_TO_N, name, descrType, type);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.DESC_S_FOR_N_DOESNT_APPLY_TO_N, name, descrType, type);
                   }
               }
           }
      @@ -158,27 +157,26 @@ public abstract static class DescrGetNode extends Node {
               @Specialization
               Object doGetSetDescriptor(VirtualFrame frame, GetSetDescriptor descr, Object obj,
                               @Bind("this") Node inliningTarget,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode,
      -                        @Cached GetNameNode getNameNode,
      +                        @Exclusive @Cached PRaiseNode raiseNode,
                               @Cached CallUnaryMethodNode callNode) {
                   if (descr.getGet() != null) {
                       return callNode.executeObject(frame, descr.getGet(), obj);
                   } else {
      -                throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.ATTR_S_OF_S_IS_NOT_READABLE, descr.getName(), getNameNode.execute(inliningTarget, descr.getType()));
      +                throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.ATTR_S_OF_N_IS_NOT_READABLE, descr.getName(), descr.getType());
                   }
               }
       
               @Specialization
               Object doIndexedSlotDescriptor(IndexedSlotDescriptor descr, PythonAbstractObject obj,
                               @Bind("this") Node inliningTarget,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode,
      +                        @Exclusive @Cached PRaiseNode raiseNode,
                               @Cached GetOrCreateIndexedSlots getSlotsNode) {
                   Object[] slots = getSlotsNode.execute(inliningTarget, obj);
                   Object val = slots[descr.getIndex()];
                   if (val != null) {
                       return val;
                   }
      -            throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.OBJ_N_HAS_NO_ATTR_S, descr.getType(), descr.getName());
      +            throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.OBJ_N_HAS_NO_ATTR_S, descr.getType(), descr.getName());
               }
           }
       
      @@ -189,13 +187,12 @@ public abstract static class DescrSetNode extends Node {
               @Specialization
               Object doGetSetDescriptor(VirtualFrame frame, GetSetDescriptor descr, Object obj, Object value,
                               @Bind("this") Node inliningTarget,
      -                        @Cached GetNameNode getNameNode,
      -                        @Cached PRaiseNode.Lazy raiseNode,
      +                        @Cached PRaiseNode raiseNode,
                               @Cached CallBinaryMethodNode callNode) {
                   if (descr.getSet() != null) {
                       return callNode.executeObject(frame, descr.getSet(), obj, value);
                   } else {
      -                throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.ATTR_S_OF_S_OBJ_IS_NOT_WRITABLE, descr.getName(), getNameNode.execute(inliningTarget, descr.getType()));
      +                throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.ATTR_S_OF_N_OBJ_IS_NOT_WRITABLE, descr.getName(), descr.getType());
                   }
               }
       
      @@ -215,8 +212,7 @@ public abstract static class DescrDeleteNode extends Node {
               @Specialization
               Object doGetSetDescriptor(VirtualFrame frame, GetSetDescriptor descr, Object obj,
                               @Bind("this") Node inliningTarget,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode,
      -                        @Cached GetNameNode getNameNode,
      +                        @Exclusive @Cached PRaiseNode raiseNode,
                               @Cached CallBinaryMethodNode callNode,
                               @Cached InlinedBranchProfile branchProfile) {
                   if (descr.allowsDelete()) {
      @@ -224,9 +220,9 @@ Object doGetSetDescriptor(VirtualFrame frame, GetSetDescriptor descr, Object obj
                   } else {
                       branchProfile.enter(inliningTarget);
                       if (descr.getSet() != null) {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANNOT_DELETE_ATTRIBUTE, getNameNode.execute(inliningTarget, descr.getType()), descr.getName());
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANNOT_DELETE_ATTRIBUTE, descr.getType(), descr.getName());
                       } else {
      -                    throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.ATTRIBUTE_S_OF_P_OBJECTS_IS_NOT_WRITABLE, descr.getName(), obj);
      +                    throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.ATTRIBUTE_S_OF_P_OBJECTS_IS_NOT_WRITABLE, descr.getName(), obj);
                       }
                   }
               }
      @@ -234,7 +230,7 @@ Object doGetSetDescriptor(VirtualFrame frame, GetSetDescriptor descr, Object obj
               @Specialization
               Object doIndexedSlotDescriptor(IndexedSlotDescriptor descr, PythonAbstractObject obj,
                               @Bind("this") Node inliningTarget,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode,
      +                        @Exclusive @Cached PRaiseNode raiseNode,
                               @Cached GetOrCreateIndexedSlots getSlotsNode,
                               @Cached InlinedConditionProfile profile) {
                   // PyMember_SetOne - Check if the attribute is set.
      @@ -243,7 +239,7 @@ Object doIndexedSlotDescriptor(IndexedSlotDescriptor descr, PythonAbstractObject
                       slots[descr.getIndex()] = null;
                       return PNone.NONE;
                   }
      -            throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.AttributeError, ErrorMessages.S, descr.getName());
      +            throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.S, descr.getName());
               }
           }
       
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/GetSetDescriptor.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/GetSetDescriptor.java
      index e148bf4e8c..c928893384 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/GetSetDescriptor.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/GetSetDescriptor.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -47,7 +47,7 @@
       import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
       import com.oracle.graal.python.builtins.objects.str.PString;
       import com.oracle.graal.python.nodes.SpecialAttributeNames;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.truffle.api.object.Shape;
       import com.oracle.truffle.api.strings.TruffleString;
      @@ -102,11 +102,11 @@ public boolean allowsDelete() {
               return allowsDelete;
           }
       
      -    public GetSetDescriptor boundToObject(PythonBuiltinClassType klass, PythonObjectFactory factory) {
      +    public GetSetDescriptor boundToObject(PythonBuiltinClassType klass, PythonLanguage language) {
               if (klass == type) {
                   return this;
               } else {
      -            return factory.createGetSetDescriptor(get, set, getName(), klass, allowsDelete);
      +            return PFactory.createGetSetDescriptor(language, get, set, getName(), klass, allowsDelete);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/GetSetDescriptorTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/GetSetDescriptorTypeBuiltins.java
      index 0b693af60b..6b7afbcc72 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/GetSetDescriptorTypeBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/GetSetDescriptorTypeBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -41,7 +41,6 @@
       package com.oracle.graal.python.builtins.objects.getsetdescriptor;
       
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___OBJCLASS__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       
       import java.util.List;
       
      @@ -101,7 +100,7 @@ static Object doIndexedSlotDescriptor(IndexedSlotDescriptor self) {
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class GetSetReprNode extends PythonUnaryBuiltinNode {
               @Specialization
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/MemberDescriptorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/MemberDescriptorBuiltins.java
      index 880a385966..204e64277c 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/MemberDescriptorBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/MemberDescriptorBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -41,10 +41,10 @@
       package com.oracle.graal.python.builtins.objects.getsetdescriptor;
       
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
      @@ -66,7 +66,7 @@
       import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Cached.Shared;
      @@ -90,7 +90,7 @@ protected List> getNodeFa
               return MemberDescriptorBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class MemberDescriptorReprNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -109,10 +109,10 @@ abstract static class MemberDescriptorReduceNode extends PythonUnaryBuiltinNode
               Object doGeneric(GetSetDescriptor descr,
                               @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode,
                               @Cached GetIdNode getIdNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object getattr = readAttributeFromObjectNode.execute(getContext().getBuiltins(), BuiltinNames.T_GETATTR);
                   Object id = getIdNode.execute(getattr);
      -            return factory.createTuple(new Object[]{id, factory.createTuple(new Object[]{descr.getType(), descr.getName()})});
      +            return PFactory.createTuple(language, new Object[]{id, PFactory.createTuple(language, new Object[]{descr.getType(), descr.getName()})});
               }
           }
       
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/IntBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/IntBuiltins.java
      index e2a653ee65..e1fa889ae0 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/IntBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/IntBuiltins.java
      @@ -40,23 +40,12 @@
        */
       package com.oracle.graal.python.builtins.objects.ints;
       
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_INT;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CEIL__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___FLOOR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___FORMAT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETNEWARGS__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___POW__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ROUND__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___RPOW__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___TRUFFLE_RICHCOMPARE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___TRUNC__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___BYTES__;
       import static com.oracle.graal.python.nodes.StringLiterals.T_BIG;
      @@ -71,10 +60,12 @@
       import java.math.RoundingMode;
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.ArgumentClinic;
       import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -84,21 +75,49 @@
       import com.oracle.graal.python.builtins.objects.PNotImplemented;
       import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary;
       import com.oracle.graal.python.builtins.objects.bytes.BytesNodes;
      +import com.oracle.graal.python.builtins.objects.bytes.BytesNodes.BytesFromObject;
       import com.oracle.graal.python.builtins.objects.bytes.PBytes;
       import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
       import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr;
      -import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes;
       import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.FromNativeSubclassNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PointerCompareNode;
       import com.oracle.graal.python.builtins.objects.common.FormatNodeBase;
      +import com.oracle.graal.python.builtins.objects.floats.PFloat;
       import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsClinicProviders.FormatNodeClinicProviderGen;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsClinicProviders.FromBytesNodeClinicProviderGen;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsClinicProviders.ToBytesNodeClinicProviderGen;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsFactory.AddNodeFactory;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsFactory.AndNodeFactory;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsFactory.FloorDivNodeFactory;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsFactory.LShiftNodeFactory;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsFactory.ModNodeFactory;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsFactory.MulNodeFactory;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsFactory.NegNodeFactory;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsFactory.OrNodeFactory;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsFactory.PowNodeFactory;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsFactory.RShiftNodeFactory;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsFactory.SubNodeFactory;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsFactory.TrueDivNodeFactory;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsFactory.XorNodeFactory;
      +import com.oracle.graal.python.builtins.objects.ints.IntNodes.PyLongFromByteArray;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotInquiry.NbBoolBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.RichCmpBuiltinNode;
       import com.oracle.graal.python.lib.PyLongCheckNode;
       import com.oracle.graal.python.lib.PyLongCopy;
      +import com.oracle.graal.python.lib.PyLongFromUnicodeObject;
      +import com.oracle.graal.python.lib.PyNumberAsSizeNode;
       import com.oracle.graal.python.lib.PyNumberFloatNode;
      +import com.oracle.graal.python.lib.PyNumberLongNode;
       import com.oracle.graal.python.lib.PyObjectHashNode;
      +import com.oracle.graal.python.lib.PyUnicodeCheckNode;
      +import com.oracle.graal.python.lib.RichCmpOp;
       import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.PGuards;
      +import com.oracle.graal.python.nodes.PNodeWithContext;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.SpecialMethodNames;
       import com.oracle.graal.python.nodes.call.CallNode;
      @@ -111,17 +130,16 @@
       import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
      -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles;
      +import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassExactProfile;
       import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode;
      -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
      +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.exception.PythonErrorType;
       import com.oracle.graal.python.runtime.formatting.FloatFormatter;
       import com.oracle.graal.python.runtime.formatting.IntegerFormatter;
       import com.oracle.graal.python.runtime.formatting.InternalFormat;
       import com.oracle.graal.python.runtime.formatting.InternalFormat.Spec;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      -import com.oracle.graal.python.util.ComparisonOp;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.OverflowException;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.truffle.api.CompilerDirectives;
      @@ -153,21 +171,23 @@
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.profiles.InlinedIntValueProfile;
       import com.oracle.truffle.api.strings.TruffleString;
      +import com.oracle.truffle.api.strings.TruffleString.EqualNode;
      +import com.oracle.truffle.api.strings.TruffleString.FromJavaStringNode;
      +import com.oracle.truffle.api.strings.TruffleString.FromLongNode;
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PInt)
       public final class IntBuiltins extends PythonBuiltins {
           public static final TpSlots SLOTS = IntBuiltinsSlotsGen.SLOTS;
       
      -    private static void raiseDivisionByZero(Node inliningTarget, boolean cond, InlinedBranchProfile divisionByZeroProfile, PRaiseNode.Lazy raiseNode) {
      +    private static void raiseDivisionByZero(Node inliningTarget, boolean cond, PRaiseNode raiseNode) {
               if (cond) {
      -            raiseDivisionByZero(inliningTarget, divisionByZeroProfile, raiseNode.get(inliningTarget));
      +            raiseDivisionByZero(inliningTarget, raiseNode);
               }
           }
       
           @InliningCutoff
      -    private static void raiseDivisionByZero(Node inliningTarget, InlinedBranchProfile divisionByZeroProfile, PRaiseNode raiseNode) {
      -        divisionByZeroProfile.enter(inliningTarget);
      -        throw raiseNode.raise(PythonErrorType.ZeroDivisionError, ErrorMessages.S_DIVISION_OR_MODULO_BY_ZERO, "integer");
      +    private static void raiseDivisionByZero(Node inliningTarget, PRaiseNode raiseNode) {
      +        throw raiseNode.raise(inliningTarget, PythonErrorType.ZeroDivisionError, ErrorMessages.S_DIVISION_OR_MODULO_BY_ZERO, "integer");
           }
       
           @Override
      @@ -175,10 +195,115 @@ protected List> getNodeFa
               return IntBuiltinsFactory.getFactories();
           }
       
      +    // int(x=0)
      +    // int(x, base=10)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = J_INT, minNumOfPositionalArgs = 1, parameterNames = {"cls", "x", "base"}, numOfPositionalOnlyArgs = 2)
      +    @GenerateNodeFactory
      +    public abstract static class IntNewNode extends PythonTernaryBuiltinNode {
      +
      +        @Specialization
      +        static Object doGeneric(VirtualFrame frame, Object cls, Object x, Object baseObj,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached IntNodeInnerNode innerNode,
      +                        @Cached IsBuiltinClassExactProfile isPrimitiveIntProfile,
      +                        @Cached CreateIntSubclassNode createIntSubclassNode) {
      +            Object result = innerNode.execute(frame, inliningTarget, x, baseObj);
      +            if (isPrimitiveIntProfile.profileClass(inliningTarget, cls, PythonBuiltinClassType.PInt)) {
      +                return result;
      +            } else {
      +                return createIntSubclassNode.execute(inliningTarget, cls, result);
      +            }
      +        }
      +
      +        @GenerateInline
      +        @GenerateCached(false)
      +        abstract static class CreateIntSubclassNode extends Node {
      +            public abstract Object execute(Node inliningTarget, Object cls, Object intObj);
      +
      +            @Specialization
      +            static Object doSubclass(Object cls, int value,
      +                            @Bind PythonLanguage language,
      +                            @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +                return PFactory.createInt(language, cls, getInstanceShape.execute(cls), value);
      +            }
      +
      +            @Specialization
      +            static Object doSubclass(Object cls, long value,
      +                            @Bind PythonLanguage language,
      +                            @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +                return PFactory.createInt(language, cls, getInstanceShape.execute(cls), value);
      +            }
      +
      +            @Specialization
      +            static Object doSubclass(Object cls, boolean value,
      +                            @Bind PythonLanguage language,
      +                            @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +                return PFactory.createInt(language, cls, getInstanceShape.execute(cls), PInt.intValue(value));
      +            }
      +
      +            @Specialization
      +            static Object doSubclass(Object cls, PInt value,
      +                            @Bind PythonLanguage language,
      +                            @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +                return PFactory.createInt(language, cls, getInstanceShape.execute(cls), value.getValue());
      +            }
      +        }
      +
      +        @GenerateInline
      +        @GenerateCached(false)
      +        @ImportStatic(PGuards.class)
      +        abstract static class IntNodeInnerNode extends Node {
      +            public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object x, Object base);
      +
      +            @Specialization(guards = "isNoValue(baseObj)")
      +            static Object doNoBase(VirtualFrame frame, Node inliningTarget, Object x, @SuppressWarnings("unused") Object baseObj,
      +                            @Cached InlinedBranchProfile noX,
      +                            @Cached PyNumberLongNode pyNumberLongNode) {
      +                if (x == PNone.NO_VALUE) {
      +                    noX.enter(inliningTarget);
      +                    return 0;
      +                } else {
      +                    return pyNumberLongNode.execute(frame, inliningTarget, x);
      +                }
      +            }
      +
      +            @Fallback
      +            @InliningCutoff
      +            static Object doWithBase(VirtualFrame frame, Node inliningTarget, Object x, Object baseObj,
      +                            @Cached InlinedBranchProfile missingArgument,
      +                            @Cached InlinedBranchProfile wrongBase,
      +                            @Cached InlinedBranchProfile cannotConvert,
      +                            @Cached PyNumberAsSizeNode asSizeNode,
      +                            @Cached PyUnicodeCheckNode unicodeCheckNode,
      +                            @Cached PyLongFromUnicodeObject longFromUnicode,
      +                            @Cached BytesNodes.BytesLikeCheck bytesLikeCheck,
      +                            @Cached PyNumberLongNode.LongFromBufferNode fromBufferNode,
      +                            @Cached PRaiseNode raiseNode) {
      +                if (x == PNone.NO_VALUE) {
      +                    missingArgument.enter(inliningTarget);
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.INT_MISSING_STRING_ARGUMENT);
      +                }
      +                int base = asSizeNode.executeLossy(frame, inliningTarget, baseObj);
      +                if ((base != 0 && base < 2) || base > 36) {
      +                    wrongBase.enter(inliningTarget);
      +                    throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.INT_BASE_MUST_BE_2_AND_36_OR_0);
      +                }
      +                if (unicodeCheckNode.execute(inliningTarget, x)) {
      +                    return longFromUnicode.execute(inliningTarget, x, base);
      +                } else if (bytesLikeCheck.execute(inliningTarget, x)) {
      +                    return fromBufferNode.execute(frame, x, base);
      +                }
      +                cannotConvert.enter(inliningTarget);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.INT_CANT_CONVERT_STRING_WITH_EXPL_BASE);
      +            }
      +        }
      +    }
      +
           @Builtin(name = J___ROUND__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2)
           @GenerateNodeFactory
           @ImportStatic(MathGuards.class)
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           abstract static class RoundNode extends PythonBinaryBuiltinNode {
               @SuppressWarnings("unused")
               @Specialization
      @@ -196,70 +321,70 @@ static long roundLongNone(long arg, PNone n) {
               @Specialization
               static PInt roundPIntNone(PInt arg, PNone n,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory.Lazy factory) {
      -            return factory.get(inliningTarget).createInt(arg.getValue());
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, arg.getValue());
               }
       
               @Specialization
               static Object roundLongInt(long arg, int n,
                               @Bind("this") Node inliningTarget,
                               @Shared("intOvf") @Cached InlinedBranchProfile intOverflow,
      -                        @Shared @Cached PythonObjectFactory.Lazy factory) {
      +                        @Shared("longOvf") @Cached InlinedBranchProfile longOverflow) {
                   if (n >= 0) {
                       return arg;
                   }
      -            return makeInt(inliningTarget, op(arg, n), intOverflow, factory);
      +            return makeInt(inliningTarget, op(arg, n), intOverflow, longOverflow);
               }
       
               @Specialization
               static Object roundPIntInt(PInt arg, int n,
                               @Bind("this") Node inliningTarget,
                               @Shared("intOvf") @Cached InlinedBranchProfile intOverflow,
      -                        @Shared @Cached PythonObjectFactory.Lazy factory) {
      +                        @Shared("longOvf") @Cached InlinedBranchProfile longOverflow) {
                   if (n >= 0) {
                       return arg;
                   }
      -            return makeInt(inliningTarget, op(arg.getValue(), n), intOverflow, factory);
      +            return makeInt(inliningTarget, op(arg.getValue(), n), intOverflow, longOverflow);
               }
       
               @Specialization
               static Object roundLongLong(long arg, long n,
                               @Bind("this") Node inliningTarget,
                               @Shared("intOvf") @Cached InlinedBranchProfile intOverflow,
      -                        @Shared @Cached PythonObjectFactory.Lazy factory) {
      +                        @Shared("longOvf") @Cached InlinedBranchProfile longOverflow) {
                   if (n >= 0) {
                       return arg;
                   }
                   if (n < Integer.MIN_VALUE) {
                       return 0;
                   }
      -            return makeInt(inliningTarget, op(arg, (int) n), intOverflow, factory);
      +            return makeInt(inliningTarget, op(arg, (int) n), intOverflow, longOverflow);
               }
       
               @Specialization
               static Object roundPIntLong(PInt arg, long n,
                               @Bind("this") Node inliningTarget,
                               @Shared("intOvf") @Cached InlinedBranchProfile intOverflow,
      -                        @Shared @Cached PythonObjectFactory.Lazy factory) {
      +                        @Shared("longOvf") @Cached InlinedBranchProfile longOverflow) {
                   if (n >= 0) {
                       return arg;
                   }
                   if (n < Integer.MIN_VALUE) {
                       return 0;
                   }
      -            return makeInt(inliningTarget, op(arg.getValue(), (int) n), intOverflow, factory);
      +            return makeInt(inliningTarget, op(arg.getValue(), (int) n), intOverflow, longOverflow);
               }
       
               @Specialization
               static Object roundPIntLong(long arg, PInt n,
                               @Bind("this") Node inliningTarget,
                               @Shared("intOvf") @Cached InlinedBranchProfile intOverflow,
      -                        @Shared @Cached PythonObjectFactory.Lazy factory) {
      +                        @Shared("longOvf") @Cached InlinedBranchProfile longOverflow) {
                   if (n.isZeroOrPositive()) {
                       return arg;
                   }
                   try {
      -                return makeInt(inliningTarget, op(arg, n.intValueExact()), intOverflow, factory);
      +                return makeInt(inliningTarget, op(arg, n.intValueExact()), intOverflow, longOverflow);
                   } catch (OverflowException e) {
                       // n is < -2^31, max. number of base-10 digits in BigInteger is 2^31 * log10(2)
                       return 0;
      @@ -270,12 +395,12 @@ static Object roundPIntLong(long arg, PInt n,
               static Object roundPIntPInt(PInt arg, PInt n,
                               @Bind("this") Node inliningTarget,
                               @Shared("intOvf") @Cached InlinedBranchProfile intOverflow,
      -                        @Shared @Cached PythonObjectFactory.Lazy factory) {
      +                        @Shared("longOvf") @Cached InlinedBranchProfile longOverflow) {
                   if (n.isZeroOrPositive()) {
                       return arg;
                   }
                   try {
      -                return makeInt(inliningTarget, op(arg.getValue(), n.intValueExact()), intOverflow, factory);
      +                return makeInt(inliningTarget, op(arg.getValue(), n.intValueExact()), intOverflow, longOverflow);
                   } catch (OverflowException e) {
                       // n is < -2^31, max. number of base-10 digits in BigInteger is 2^31 * log10(2)
                       return 0;
      @@ -285,11 +410,11 @@ static Object roundPIntPInt(PInt arg, PInt n,
               @Specialization(guards = {"!isInteger(n)"})
               @SuppressWarnings("unused")
               static Object roundPIntPInt(Object arg, Object n,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, n);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, n);
               }
       
      -        private static Object makeInt(Node inliningTarget, BigDecimal d, InlinedBranchProfile intOverflow, PythonObjectFactory.Lazy factory) {
      +        private static Object makeInt(Node inliningTarget, BigDecimal d, InlinedBranchProfile intOverflow, InlinedBranchProfile longOverflow) {
                   try {
                       return intValueExact(d);
                   } catch (OverflowException e) {
      @@ -300,10 +425,10 @@ private static Object makeInt(Node inliningTarget, BigDecimal d, InlinedBranchPr
                       return longValueExact(d);
                   } catch (OverflowException e) {
                       // does not fit long, try BigInteger
      +                longOverflow.enter(inliningTarget);
                   }
                   try {
      -                // lazy factory initialization should serve as branch profile
      -                return factory.get(inliningTarget).createInt(toBigIntegerExact(d));
      +                return PFactory.createInt(PythonLanguage.get(inliningTarget), toBigIntegerExact(d));
                   } catch (OverflowException e) {
                       // has non-zero fractional part, which should not happen
                       throw CompilerDirectives.shouldNotReachHere("non-integer produced after rounding an integer", e);
      @@ -360,67 +485,67 @@ private static BigDecimal op(BigInteger arg, int n) {
       
           @Slot(value = SlotKind.nb_add, isComplex = true)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           public abstract static class AddNode extends BinaryOpBuiltinNode {
               public abstract Object execute(int left, int right);
       
               @Specialization(rewriteOn = ArithmeticException.class)
      -        static int add(int left, int right) {
      +        static int doII(int left, int right) {
                   return Math.addExact(left, right);
               }
       
      -        @Specialization(rewriteOn = ArithmeticException.class)
      -        static long addLong(long left, long right) {
      +        @Specialization(replaces = "doII", rewriteOn = ArithmeticException.class)
      +        static long doLL(long left, long right) {
                   return Math.addExact(left, right);
               }
       
      -        @Specialization
      -        static Object addLongWithOverflow(long x, long y,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +        @Specialization(replaces = "doLL")
      +        static Object doLLOvf(long x, long y,
      +                        @Bind PythonLanguage language) {
                   /* Inlined version of Math.addExact(x, y) with BigInteger fallback. */
                   long r = x + y;
                   // HD 2-12 Overflow iff both arguments have the opposite sign of the result
                   if (((x ^ r) & (y ^ r)) < 0) {
      -                return factory.createInt(op(PInt.longToBigInteger(x), PInt.longToBigInteger(y)));
      +                return PFactory.createInt(language, add(PInt.longToBigInteger(x), PInt.longToBigInteger(y)));
                   }
                   return r;
               }
       
               @Specialization(rewriteOn = OverflowException.class)
      -        static Object addPIntLongAndNarrow(PInt left, long right) throws OverflowException {
      -            return PInt.longValueExact(op(left.getValue(), PInt.longToBigInteger(right)));
      +        static Object doPLNarrow(PInt left, long right) throws OverflowException {
      +            return PInt.longValueExact(add(left.getValue(), PInt.longToBigInteger(right)));
               }
       
      -        @Specialization(replaces = "addPIntLongAndNarrow")
      -        static Object addPIntLong(PInt left, long right,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(op(left.getValue(), PInt.longToBigInteger(right)));
      +        @Specialization(replaces = "doPLNarrow")
      +        static Object doPL(PInt left, long right,
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, add(left.getValue(), PInt.longToBigInteger(right)));
               }
       
               @Specialization(rewriteOn = OverflowException.class)
      -        static Object addLongPIntAndNarrow(long left, PInt right) throws OverflowException {
      -            return PInt.longValueExact(op(PInt.longToBigInteger(left), right.getValue()));
      +        static Object doLPNarrow(long left, PInt right) throws OverflowException {
      +            return PInt.longValueExact(add(PInt.longToBigInteger(left), right.getValue()));
               }
       
      -        @Specialization(replaces = "addLongPIntAndNarrow")
      -        static Object addLongPInt(long left, PInt right,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(op(PInt.longToBigInteger(left), right.getValue()));
      +        @Specialization(replaces = "doLPNarrow")
      +        static Object doLP(long left, PInt right,
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, add(PInt.longToBigInteger(left), right.getValue()));
               }
       
               @Specialization(rewriteOn = OverflowException.class)
      -        static Object addPIntPIntAndNarrow(PInt left, PInt right) throws OverflowException {
      -            return PInt.longValueExact(op(left.getValue(), right.getValue()));
      +        static Object doPPNarrow(PInt left, PInt right) throws OverflowException {
      +            return PInt.longValueExact(add(left.getValue(), right.getValue()));
               }
       
      -        @Specialization(replaces = "addPIntPIntAndNarrow")
      -        static Object addPIntPInt(PInt left, PInt right,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(op(left.getValue(), right.getValue()));
      +        @Specialization(replaces = "doPPNarrow")
      +        static Object doPP(PInt left, PInt right,
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, add(left.getValue(), right.getValue()));
               }
       
               @TruffleBoundary
      -        static BigInteger op(BigInteger left, BigInteger right) {
      +        public static BigInteger add(BigInteger left, BigInteger right) {
                   return left.add(right);
               }
       
      @@ -438,13 +563,13 @@ static PNotImplemented doGeneric(Object left, Object right) {
       
               @NeverDefault
               public static AddNode create() {
      -            return IntBuiltinsFactory.AddNodeFactory.create();
      +            return AddNodeFactory.create();
               }
           }
       
           @Slot(value = SlotKind.nb_subtract, isComplex = true)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           public abstract static class SubNode extends BinaryOpBuiltinNode {
               public abstract Object execute(int left, int right);
       
      @@ -453,7 +578,7 @@ static int doII(int x, int y) throws ArithmeticException {
                   return Math.subtractExact(x, y);
               }
       
      -        @Specialization
      +        @Specialization(replaces = "doII")
               static long doIIOvf(int x, int y) {
                   return (long) x - (long) y;
               }
      @@ -463,54 +588,54 @@ static long doLL(long x, long y) throws ArithmeticException {
                   return Math.subtractExact(x, y);
               }
       
      -        @Specialization
      +        @Specialization(replaces = "doLL")
               static Object doLongWithOverflow(long x, long y,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind("this") Node inliningTarget) {
                   /* Inlined version of Math.subtractExact(x, y) with BigInteger fallback. */
                   long r = x - y;
                   // HD 2-12 Overflow iff the arguments have different signs and
                   // the sign of the result is different than the sign of x
                   if (((x ^ y) & (x ^ r)) < 0) {
      -                return factory.createInt(op(PInt.longToBigInteger(x), PInt.longToBigInteger(y)));
      +                return PFactory.createInt(PythonLanguage.get(inliningTarget), sub(PInt.longToBigInteger(x), PInt.longToBigInteger(y)));
                   }
                   return r;
               }
       
               @Specialization(rewriteOn = OverflowException.class)
               static long doPIntLongAndNarrow(PInt left, long right) throws OverflowException {
      -            return PInt.longValueExact(op(left.getValue(), PInt.longToBigInteger(right)));
      +            return PInt.longValueExact(sub(left.getValue(), PInt.longToBigInteger(right)));
               }
       
               @Specialization(replaces = "doPIntLongAndNarrow")
               static PInt doPIntLong(PInt left, long right,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(op(left.getValue(), PInt.longToBigInteger(right)));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, sub(left.getValue(), PInt.longToBigInteger(right)));
               }
       
               @Specialization(rewriteOn = OverflowException.class)
               static long doLongPIntAndNarrow(long left, PInt right) throws OverflowException {
      -            return PInt.longValueExact(op(PInt.longToBigInteger(left), right.getValue()));
      +            return PInt.longValueExact(sub(PInt.longToBigInteger(left), right.getValue()));
               }
       
               @Specialization(replaces = "doLongPIntAndNarrow")
               static PInt doLongPInt(long left, PInt right,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(op(PInt.longToBigInteger(left), right.getValue()));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, sub(PInt.longToBigInteger(left), right.getValue()));
               }
       
               @Specialization(rewriteOn = OverflowException.class)
               static long doPIntPIntAndNarrow(PInt left, PInt right) throws OverflowException {
      -            return PInt.longValueExact(op(left.getValue(), right.getValue()));
      +            return PInt.longValueExact(sub(left.getValue(), right.getValue()));
               }
       
               @Specialization(replaces = "doPIntPIntAndNarrow")
               static PInt doPIntPInt(PInt left, PInt right,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(op(left.getValue(), right.getValue()));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, sub(left.getValue(), right.getValue()));
               }
       
               @TruffleBoundary
      -        private static BigInteger op(BigInteger left, BigInteger right) {
      +        public static BigInteger sub(BigInteger left, BigInteger right) {
                   return left.subtract(right);
               }
       
      @@ -522,45 +647,45 @@ static PNotImplemented doGeneric(Object left, Object right) {
       
               @NeverDefault
               public static SubNode create() {
      -            return IntBuiltinsFactory.SubNodeFactory.create();
      +            return SubNodeFactory.create();
               }
           }
       
           @Slot(value = SlotKind.nb_true_divide, isComplex = true)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           public abstract static class TrueDivNode extends BinaryOpBuiltinNode {
               public abstract Object execute(int left, int right);
       
               @Specialization
               static double divII(int x, int y,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   return divDD(x, y, inliningTarget, raiseNode);
               }
       
               @Specialization(guards = {"fitsIntoDouble(x)", "fitsIntoDouble(y)"})
               static double divLL(long x, long y,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   return divDD(x, y, inliningTarget, raiseNode);
               }
       
               @Specialization(guards = {"!fitsIntoDouble(x) || !fitsIntoDouble(y)"})
               static double divLLLarge(long x, long y,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   if (y == 0) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.ZeroDivisionError, ErrorMessages.DIVISION_BY_ZERO);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.ZeroDivisionError, ErrorMessages.DIVISION_BY_ZERO);
                   }
                   return op(inliningTarget, PInt.longToBigInteger(x), PInt.longToBigInteger(y));
               }
       
               static double divDD(double x, double y,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   if (y == 0) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.ZeroDivisionError, ErrorMessages.DIVISION_BY_ZERO);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.ZeroDivisionError, ErrorMessages.DIVISION_BY_ZERO);
                   }
                   return x / y;
               }
      @@ -568,9 +693,9 @@ static double divDD(double x, double y,
               @Specialization
               static double doPI(long left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   if (right.isZero()) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.ZeroDivisionError, ErrorMessages.DIVISION_BY_ZERO);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.ZeroDivisionError, ErrorMessages.DIVISION_BY_ZERO);
                   }
                   return op(inliningTarget, PInt.longToBigInteger(left), right.getValue());
               }
      @@ -578,9 +703,9 @@ static double doPI(long left, PInt right,
               @Specialization
               static double doPL(PInt left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   if (right == 0) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.ZeroDivisionError, ErrorMessages.DIVISION_BY_ZERO);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.ZeroDivisionError, ErrorMessages.DIVISION_BY_ZERO);
                   }
                   return op(inliningTarget, left.getValue(), PInt.longToBigInteger(right));
               }
      @@ -588,9 +713,9 @@ static double doPL(PInt left, long right,
               @Specialization
               static double doPP(PInt left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   if (right.isZero()) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.ZeroDivisionError, ErrorMessages.DIVISION_BY_ZERO);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.ZeroDivisionError, ErrorMessages.DIVISION_BY_ZERO);
                   }
                   return op(inliningTarget, left.getValue(), right.getValue());
               }
      @@ -601,7 +726,7 @@ static double doPP(PInt left, PInt right,
                */
               @TruffleBoundary
               private static double op(Node raisingNode, BigInteger a, BigInteger b) {
      -            final int precisionOfDouble = 17;
      +            final int precisionOfDouble = 18;
                   if (fitsIntoDouble(a) && fitsIntoDouble(b)) {
                       return a.doubleValue() / b.doubleValue();
                   }
      @@ -612,12 +737,12 @@ private static double op(Node raisingNode, BigInteger a, BigInteger b) {
                   BigDecimal result = aDecimal.divide(bDecimal, bPrec - aPrec + precisionOfDouble, RoundingMode.HALF_EVEN);
                   double d = result.doubleValue();
                   if (Double.isInfinite(d)) {
      -                throw PRaiseNode.raiseUncached(raisingNode, OverflowError, ErrorMessages.INTEGER_DIVISION_RESULT_TOO_LARGE);
      +                throw PRaiseNode.raiseStatic(raisingNode, OverflowError, ErrorMessages.INTEGER_DIVISION_RESULT_TOO_LARGE);
                   }
                   return d;
               }
       
      -        protected static boolean fitsIntoDouble(long x) {
      +        public static boolean fitsIntoDouble(long x) {
                   return x < (1L << 52) && x > -(1L << 52);
               }
       
      @@ -633,12 +758,12 @@ static PNotImplemented doGeneric(Object left, Object right) {
       
               @NeverDefault
               public static TrueDivNode create() {
      -            return IntBuiltinsFactory.TrueDivNodeFactory.create();
      +            return TrueDivNodeFactory.create();
               }
           }
       
           @Slot(value = SlotKind.nb_floor_divide, isComplex = true)
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           @GenerateNodeFactory
           public abstract static class FloorDivNode extends BinaryOpBuiltinNode {
               public abstract Object execute(int left, int right);
      @@ -649,10 +774,9 @@ public abstract static class FloorDivNode extends BinaryOpBuiltinNode {
               @Specialization
               static Object doII(int left, int right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
                               @Shared @Cached BranchProfile overflowValueProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            raiseDivisionByZero(inliningTarget, right == 0, divisionByZeroProfile, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            raiseDivisionByZero(inliningTarget, right == 0, raiseNode);
                   if (left == Integer.MIN_VALUE && right == -1) {
                       overflowValueProfile.enter();
                       return INT_OVERFLOW_VALUE;
      @@ -663,14 +787,12 @@ static Object doII(int left, int right,
               @Specialization
               static Object doLL(long left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
                               @Shared @Cached BranchProfile overflowValueProfile,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            raiseDivisionByZero(inliningTarget, right == 0, divisionByZeroProfile, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            raiseDivisionByZero(inliningTarget, right == 0, raiseNode);
                   if (left == Long.MIN_VALUE && right == -1) {
                       overflowValueProfile.enter();
      -                return factory.createInt(LONG_OVERFLOW_VALUE);
      +                return PFactory.createInt(PythonLanguage.get(inliningTarget), LONG_OVERFLOW_VALUE);
                   }
                   return Math.floorDiv(left, right);
               }
      @@ -678,12 +800,11 @@ static Object doLL(long left, long right,
               @Specialization
               static Object doIPi(int left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
                               @Shared @Cached BranchProfile overflowValueProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   try {
                       int rightValue = right.intValueExact();
      -                raiseDivisionByZero(inliningTarget, rightValue == 0, divisionByZeroProfile, raiseNode);
      +                raiseDivisionByZero(inliningTarget, rightValue == 0, raiseNode);
                       if (left == Integer.MIN_VALUE && rightValue == -1) {
                           overflowValueProfile.enter();
                           return INT_OVERFLOW_VALUE;
      @@ -697,16 +818,14 @@ static Object doIPi(int left, PInt right,
               @Specialization
               static Object doLPi(long left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
                               @Shared @Cached BranchProfile overflowValueProfile,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   try {
                       long rightValue = right.longValueExact();
      -                raiseDivisionByZero(inliningTarget, rightValue == 0, divisionByZeroProfile, raiseNode);
      +                raiseDivisionByZero(inliningTarget, rightValue == 0, raiseNode);
                       if (left == Long.MIN_VALUE && rightValue == -1) {
                           overflowValueProfile.enter();
      -                    return factory.createInt(LONG_OVERFLOW_VALUE);
      +                    return PFactory.createInt(PythonLanguage.get(inliningTarget), LONG_OVERFLOW_VALUE);
                       }
                       return Math.floorDiv(left, rightValue);
                   } catch (OverflowException e) {
      @@ -717,58 +836,52 @@ static Object doLPi(long left, PInt right,
               @Specialization(rewriteOn = OverflowException.class)
               static long doPiIAndNarrow(PInt left, int right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) throws OverflowException {
      -            raiseDivisionByZero(inliningTarget, right == 0, divisionByZeroProfile, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) throws OverflowException {
      +            raiseDivisionByZero(inliningTarget, right == 0, raiseNode);
                   return PInt.longValueExact(op(left.getValue(), PInt.longToBigInteger(right)));
               }
       
               @Specialization(replaces = "doPiIAndNarrow")
               static PInt doPiI(PInt left, int right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            raiseDivisionByZero(inliningTarget, right == 0, divisionByZeroProfile, raiseNode);
      -            return factory.createInt(op(left.getValue(), PInt.longToBigInteger(right)));
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            raiseDivisionByZero(inliningTarget, right == 0, raiseNode);
      +            return PFactory.createInt(language, op(left.getValue(), PInt.longToBigInteger(right)));
               }
       
               @Specialization(rewriteOn = OverflowException.class)
               static long doPiLAndNarrow(PInt left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) throws OverflowException {
      -            raiseDivisionByZero(inliningTarget, right == 0, divisionByZeroProfile, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) throws OverflowException {
      +            raiseDivisionByZero(inliningTarget, right == 0, raiseNode);
                   return PInt.longValueExact(op(left.getValue(), PInt.longToBigInteger(right)));
               }
       
               @Specialization(replaces = "doPiLAndNarrow")
               static PInt doPiL(PInt left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            raiseDivisionByZero(inliningTarget, right == 0, divisionByZeroProfile, raiseNode);
      -            return factory.createInt(op(left.getValue(), PInt.longToBigInteger(right)));
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            raiseDivisionByZero(inliningTarget, right == 0, raiseNode);
      +            return PFactory.createInt(language, op(left.getValue(), PInt.longToBigInteger(right)));
               }
       
               @Specialization(rewriteOn = OverflowException.class)
               static long doPiPiAndNarrow(PInt left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) throws OverflowException {
      -            raiseDivisionByZero(inliningTarget, right.isZero(), divisionByZeroProfile, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) throws OverflowException {
      +            raiseDivisionByZero(inliningTarget, right.isZero(), raiseNode);
                   return PInt.longValueExact(op(left.getValue(), right.getValue()));
               }
       
               @Specialization(replaces = "doPiPiAndNarrow")
               static PInt doPiPi(PInt left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            raiseDivisionByZero(inliningTarget, right.isZero(), divisionByZeroProfile, raiseNode);
      -            return factory.createInt(op(left.getValue(), right.getValue()));
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            raiseDivisionByZero(inliningTarget, right.isZero(), raiseNode);
      +            return PFactory.createInt(language, op(left.getValue(), right.getValue()));
               }
       
               @TruffleBoundary
      @@ -790,7 +903,7 @@ static PNotImplemented doGeneric(Object right, Object left) {
       
               @NeverDefault
               public static FloorDivNode create() {
      -            return IntBuiltinsFactory.FloorDivNodeFactory.create();
      +            return FloorDivNodeFactory.create();
               }
           }
       
      @@ -800,20 +913,20 @@ abstract static class DivModNode extends BinaryOpBuiltinNode {
       
               @Specialization
               static Object doGeneric(VirtualFrame frame, Object left, Object right,
      +                        @Bind("this") Node inliningTarget,
                               @Cached FloorDivNode floorDivNode,
      -                        @Cached ModNode modNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Cached ModNode modNode) {
                   Object div = floorDivNode.execute(frame, left, right);
                   if (div == PNotImplemented.NOT_IMPLEMENTED) {
                       return PNotImplemented.NOT_IMPLEMENTED;
                   }
                   Object mod = modNode.execute(frame, left, right);
      -            return factory.createTuple(new Object[]{div, mod});
      +            return PFactory.createTuple(PythonLanguage.get(inliningTarget), new Object[]{div, mod});
               }
           }
       
           @Slot(value = SlotKind.nb_remainder, isComplex = true)
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           @GenerateNodeFactory
           public abstract static class ModNode extends BinaryOpBuiltinNode {
               public abstract int executeInt(int left, int right) throws UnexpectedResultException;
      @@ -823,114 +936,102 @@ public abstract static class ModNode extends BinaryOpBuiltinNode {
               @Specialization
               static int doII(int left, int right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            raiseDivisionByZero(inliningTarget, right == 0, divisionByZeroProfile, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            raiseDivisionByZero(inliningTarget, right == 0, raiseNode);
                   return Math.floorMod(left, right);
               }
       
               @Specialization
               static long doLL(long left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            raiseDivisionByZero(inliningTarget, right == 0, divisionByZeroProfile, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            raiseDivisionByZero(inliningTarget, right == 0, raiseNode);
                   return Math.floorMod(left, right);
               }
       
               @Specialization(guards = "right.isZeroOrPositive()", rewriteOn = OverflowException.class)
               static long doLPiAndNarrow(long left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) throws OverflowException {
      -            raiseDivisionByZero(inliningTarget, right.isZero(), divisionByZeroProfile, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) throws OverflowException {
      +            raiseDivisionByZero(inliningTarget, right.isZero(), raiseNode);
                   return PInt.longValueExact(op(PInt.longToBigInteger(left), right.getValue()));
               }
       
               @Specialization(guards = "right.isZeroOrPositive()", replaces = "doLPiAndNarrow")
               static PInt doLPi(long left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            raiseDivisionByZero(inliningTarget, right.isZero(), divisionByZeroProfile, raiseNode);
      -            return factory.createInt(op(PInt.longToBigInteger(left), right.getValue()));
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            raiseDivisionByZero(inliningTarget, right.isZero(), raiseNode);
      +            return PFactory.createInt(language, op(PInt.longToBigInteger(left), right.getValue()));
               }
       
               @Specialization(guards = "!right.isZeroOrPositive()", rewriteOn = OverflowException.class)
               static long doLPiNegativeAndNarrow(long left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) throws OverflowException {
      -            raiseDivisionByZero(inliningTarget, right.isZero(), divisionByZeroProfile, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) throws OverflowException {
      +            raiseDivisionByZero(inliningTarget, right.isZero(), raiseNode);
                   return PInt.longValueExact(opNeg(PInt.longToBigInteger(left), right.getValue()));
               }
       
               @Specialization(guards = "!right.isZeroOrPositive()", replaces = "doLPiNegativeAndNarrow")
               static PInt doLPiNegative(long left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            raiseDivisionByZero(inliningTarget, right.isZero(), divisionByZeroProfile, raiseNode);
      -            return factory.createInt(opNeg(PInt.longToBigInteger(left), right.getValue()));
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            raiseDivisionByZero(inliningTarget, right.isZero(), raiseNode);
      +            return PFactory.createInt(language, opNeg(PInt.longToBigInteger(left), right.getValue()));
               }
       
               @Specialization(guards = "right >= 0", rewriteOn = OverflowException.class)
               static long doPiLAndNarrow(PInt left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) throws OverflowException {
      -            raiseDivisionByZero(inliningTarget, right == 0, divisionByZeroProfile, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) throws OverflowException {
      +            raiseDivisionByZero(inliningTarget, right == 0, raiseNode);
                   return PInt.longValueExact(op(left.getValue(), PInt.longToBigInteger(right)));
               }
       
               @Specialization(guards = "right >= 0", replaces = "doPiLAndNarrow")
               static PInt doPiL(PInt left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            raiseDivisionByZero(inliningTarget, right == 0, divisionByZeroProfile, raiseNode);
      -            return factory.createInt(op(left.getValue(), PInt.longToBigInteger(right)));
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            raiseDivisionByZero(inliningTarget, right == 0, raiseNode);
      +            return PFactory.createInt(language, op(left.getValue(), PInt.longToBigInteger(right)));
               }
       
               @Specialization(guards = "right < 0", rewriteOn = OverflowException.class)
               static long doPiLNegAndNarrow(PInt left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) throws OverflowException {
      -            raiseDivisionByZero(inliningTarget, right == 0, divisionByZeroProfile, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) throws OverflowException {
      +            raiseDivisionByZero(inliningTarget, right == 0, raiseNode);
                   return PInt.longValueExact(opNeg(left.getValue(), PInt.longToBigInteger(right)));
               }
       
               @Specialization(guards = "right < 0", replaces = "doPiLNegAndNarrow")
               static PInt doPiLNeg(PInt left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            raiseDivisionByZero(inliningTarget, right == 0, divisionByZeroProfile, raiseNode);
      -            return factory.createInt(opNeg(left.getValue(), PInt.longToBigInteger(right)));
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            raiseDivisionByZero(inliningTarget, right == 0, raiseNode);
      +            return PFactory.createInt(language, opNeg(left.getValue(), PInt.longToBigInteger(right)));
               }
       
               @Specialization(guards = "right.isZeroOrPositive()", rewriteOn = OverflowException.class)
               static long doPiPiAndNarrow(PInt left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) throws OverflowException {
      -            raiseDivisionByZero(inliningTarget, right.isZero(), divisionByZeroProfile, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) throws OverflowException {
      +            raiseDivisionByZero(inliningTarget, right.isZero(), raiseNode);
                   return PInt.longValueExact(op(left.getValue(), right.getValue()));
               }
       
               @Specialization(guards = "right.isZeroOrPositive()", replaces = "doPiPiAndNarrow")
               static PInt doPiPi(PInt left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedBranchProfile divisionByZeroProfile,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            raiseDivisionByZero(inliningTarget, right.isZero(), divisionByZeroProfile, raiseNode);
      -            return factory.createInt(op(left.getValue(), right.getValue()));
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            raiseDivisionByZero(inliningTarget, right.isZero(), raiseNode);
      +            return PFactory.createInt(language, op(left.getValue(), right.getValue()));
               }
       
               @Specialization(guards = "!right.isZeroOrPositive()", rewriteOn = OverflowException.class)
      @@ -940,8 +1041,8 @@ static long doPiPiNegAndNarrow(PInt left, PInt right) throws OverflowException {
       
               @Specialization(guards = "!right.isZeroOrPositive()", replaces = "doPiPiNegAndNarrow")
               static PInt doPiPiNeg(PInt left, PInt right,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(opNeg(left.getValue(), right.getValue()));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, opNeg(left.getValue(), right.getValue()));
               }
       
               @TruffleBoundary
      @@ -969,13 +1070,13 @@ static PNotImplemented doGeneric(Object left, Object right) {
       
               @NeverDefault
               public static ModNode create() {
      -            return IntBuiltinsFactory.ModNodeFactory.create();
      +            return ModNodeFactory.create();
               }
           }
       
           @Slot(value = SlotKind.nb_multiply, isComplex = true)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           public abstract static class MulNode extends BinaryOpBuiltinNode {
               public abstract Object execute(int left, int right);
       
      @@ -994,9 +1095,9 @@ static long doLL(long x, long y) {
                   return Math.multiplyExact(x, y);
               }
       
      -        @Specialization
      +        @Specialization(replaces = "doLL")
               static Object doLongWithOverflow(long x, long y,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind("this") Node inliningTarget) {
                   /* Inlined version of Math.multiplyExact(x, y) with BigInteger fallback. */
                   long r = x * y;
                   long ax = Math.abs(x);
      @@ -1007,7 +1108,7 @@ static Object doLongWithOverflow(long x, long y,
                       // and check for the special case of Long.MIN_VALUE * -1
                       if (((y != 0) && (r / y != x)) ||
                                       (x == Long.MIN_VALUE && y == -1)) {
      -                    return factory.createInt(mul(PInt.longToBigInteger(x), PInt.longToBigInteger(y)));
      +                    return PFactory.createInt(PythonLanguage.get(inliningTarget), mul(PInt.longToBigInteger(x), PInt.longToBigInteger(y)));
                       }
                   }
                   return r;
      @@ -1025,37 +1126,37 @@ static int doPIntLongZero(@SuppressWarnings("unused") long left, @SuppressWarnin
       
               @Specialization(guards = "right == 1")
               static PInt doPIntLongOne(PInt left, @SuppressWarnings("unused") long right,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   // we must return a new object with the same value
      -            return factory.createInt(left.getValue());
      +            return PFactory.createInt(language, left.getValue());
               }
       
               @Specialization(guards = "left == 1")
               PInt doPIntLongOne(@SuppressWarnings("unused") long left, PInt right,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(right.getValue());
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, right.getValue());
               }
       
               @Specialization(guards = {"right != 0", "right != 1"})
               static PInt doPIntLong(PInt left, long right,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(mul(left.getValue(), PInt.longToBigInteger(right)));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, mul(left.getValue(), PInt.longToBigInteger(right)));
               }
       
               @Specialization(guards = {"left != 0", "left != 1"})
               PInt doPIntLong(long left, PInt right,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(mul(PInt.longToBigInteger(left), right.getValue()));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, mul(PInt.longToBigInteger(left), right.getValue()));
               }
       
               @Specialization
               static PInt doPIntPInt(PInt left, PInt right,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(mul(left.getValue(), right.getValue()));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, mul(left.getValue(), right.getValue()));
               }
       
               @TruffleBoundary
      -        static BigInteger mul(BigInteger a, BigInteger b) {
      +        public static BigInteger mul(BigInteger a, BigInteger b) {
                   if (!BigInteger.ZERO.equals(b) && b.and(b.subtract(BigInteger.ONE)).equals(BigInteger.ZERO)) {
                       return bigIntegerShift(a, b.getLowestSetBit());
                   } else {
      @@ -1081,14 +1182,13 @@ static PNotImplemented doGeneric(Object left, Object right) {
       
               @NeverDefault
               public static MulNode create() {
      -            return IntBuiltinsFactory.MulNodeFactory.create();
      +            return MulNodeFactory.create();
               }
           }
       
      -    @Builtin(name = J___RPOW__, minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3, reverseOperation = true)
      -    @Builtin(name = J___POW__, minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3)
      +    @Slot(value = SlotKind.nb_power, isComplex = true)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           @ImportStatic(MathGuards.class)
           @ReportPolymorphism
           public abstract static class PowNode extends PythonTernaryBuiltinNode {
      @@ -1142,8 +1242,8 @@ static long doLLFast(long left, long right, @SuppressWarnings("unused") PNone no
               @Specialization(guards = "right >= 0", replaces = "doLLFast")
               @InliningCutoff
               PInt doLLPos(long left, long right, @SuppressWarnings("unused") PNone none,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(op(PInt.longToBigInteger(left), right));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, op(PInt.longToBigInteger(left), right));
               }
       
               @Specialization(guards = "right < 0")
      @@ -1151,9 +1251,9 @@ PInt doLLPos(long left, long right, @SuppressWarnings("unused") PNone none,
               double doLLNeg(long left, long right, @SuppressWarnings("unused") PNone none,
                               @Bind("this") Node inliningTarget,
                               @Shared("leftIsZero") @Cached InlinedConditionProfile leftIsZero,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   if (leftIsZero.profile(inliningTarget, left == 0)) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ZeroDivisionError, ErrorMessages.POW_ZERO_CANNOT_RAISE_TO_NEGATIVE_POWER);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ZeroDivisionError, ErrorMessages.POW_ZERO_CANNOT_RAISE_TO_NEGATIVE_POWER);
                   }
                   return Math.pow(left, right);
               }
      @@ -1163,7 +1263,7 @@ PInt doLLPos(long left, long right, @SuppressWarnings("unused") PNone none,
               Object doLPNarrow(long left, PInt right, @SuppressWarnings("unused") PNone none,
                               @Bind("this") Node inliningTarget,
                               @Shared("leftIsZero") @Cached InlinedConditionProfile leftIsZero,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) throws OverflowException {
      +                        @Shared @Cached PRaiseNode raiseNode) throws OverflowException {
                   long lright = right.longValueExact();
                   if (lright >= 0) {
                       return doLLFast(left, lright, none);
      @@ -1173,11 +1273,10 @@ Object doLPNarrow(long left, PInt right, @SuppressWarnings("unused") PNone none,
       
               @Specialization(replaces = "doLPNarrow")
               @InliningCutoff
      -        Object doLP(long left, PInt right, @SuppressWarnings("unused") PNone none,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +        Object doLP(long left, PInt right, @SuppressWarnings("unused") PNone none) {
                   Object result = op(PInt.longToBigInteger(left), right.getValue());
                   if (result instanceof BigInteger) {
      -                return factory.createInt((BigInteger) result);
      +                return PFactory.createInt(PythonLanguage.get(this), (BigInteger) result);
                   } else {
                       return result;
                   }
      @@ -1192,8 +1291,8 @@ long doPLNarrow(PInt left, long right, @SuppressWarnings("unused") PNone none) t
               @Specialization(guards = "right >= 0", replaces = "doPLNarrow")
               @InliningCutoff
               PInt doPLPos(PInt left, long right, @SuppressWarnings("unused") PNone none,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(op(left.getValue(), right));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, op(left.getValue(), right));
               }
       
               @Specialization(guards = "right < 0")
      @@ -1201,20 +1300,20 @@ PInt doPLPos(PInt left, long right, @SuppressWarnings("unused") PNone none,
               double doPLNeg(PInt left, long right, @SuppressWarnings("unused") PNone none,
                               @Bind("this") Node inliningTarget,
                               @Shared("leftIsZero") @Cached InlinedConditionProfile leftIsZero,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            if (leftIsZero.profile(inliningTarget, left.isZero())) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ZeroDivisionError, ErrorMessages.POW_ZERO_CANNOT_RAISE_TO_NEGATIVE_POWER);
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            double leftDouble = PInt.doubleValueWithOverflow(this, left.getValue());
      +            if (leftIsZero.profile(inliningTarget, leftDouble == 0.0)) {
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ZeroDivisionError, ErrorMessages.POW_ZERO_CANNOT_RAISE_TO_NEGATIVE_POWER);
                   }
      -            return TrueDivNode.op(this, BigInteger.ONE, op(left.getValue(), -right));
      +            return Math.pow(leftDouble, right);
               }
       
               @Specialization
               @InliningCutoff
      -        Object doPP(PInt left, PInt right, @SuppressWarnings("unused") PNone none,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +        Object doPP(PInt left, PInt right, @SuppressWarnings("unused") PNone none) {
                   Object result = op(left.getValue(), right.getValue());
                   if (result instanceof BigInteger) {
      -                return factory.createInt((BigInteger) result);
      +                return PFactory.createInt(PythonLanguage.get(this), (BigInteger) result);
                   } else {
                       return result;
                   }
      @@ -1237,9 +1336,9 @@ static long doLLPosLPos(long left, long right, long mod) {
               static long doLLPosLGeneric(long left, long right, long mod,
                               @Bind("this") Node inliningTarget,
                               @Exclusive @Cached InlinedConditionProfile modNegativeProfile,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   if (mod == 0) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.POW_THIRD_ARG_CANNOT_BE_ZERO);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.POW_THIRD_ARG_CANNOT_BE_ZERO);
                   }
                   try {
                       if (modNegativeProfile.profile(inliningTarget, mod < 0)) {
      @@ -1256,8 +1355,7 @@ static long doLLPosLGeneric(long left, long right, long mod,
               // see cpython://Objects/longobject.c#long_pow
               @Specialization(replaces = "doPP")
               @InliningCutoff
      -        Object powModulo(Object x, Object y, Object z,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +        Object powModulo(Object x, Object y, Object z) {
                   if (!(MathGuards.isInteger(x) && MathGuards.isInteger(y))) {
                       return PNotImplemented.NOT_IMPLEMENTED;
                   }
      @@ -1270,7 +1368,7 @@ Object powModulo(Object x, Object y, Object z,
                       return PNotImplemented.NOT_IMPLEMENTED;
                   }
                   if (result instanceof BigInteger) {
      -                return factory.createInt((BigInteger) result);
      +                return PFactory.createInt(PythonLanguage.get(this), (BigInteger) result);
                   } else {
                       return result;
                   }
      @@ -1289,7 +1387,7 @@ private Object objectOp(Object left, Object right, Object mod) {
                   BigInteger bigRight = integerToBigInteger(right);
                   BigInteger bigMod = integerToBigInteger(mod);
                   if (bigMod.signum() == 0) {
      -                throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.POW_THIRD_ARG_CANNOT_BE_ZERO);
      +                throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.POW_THIRD_ARG_CANNOT_BE_ZERO);
                   } else {
                       BigInteger bigModPos;
                       if (bigMod.signum() < 0) {
      @@ -1307,7 +1405,7 @@ private Object objectOp(Object left, Object right, Object mod) {
                       } catch (ArithmeticException e) {
                           // a positive mod was used, so this exception must mean the exponent was
                           // negative and the base is not relatively prime to the exponent
      -                    throw PRaiseNode.raiseUncached(this, ValueError, ErrorMessages.POW_BASE_NOT_INVERTIBLE);
      +                    throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.POW_BASE_NOT_INVERTIBLE);
                       }
                   }
               }
      @@ -1358,14 +1456,13 @@ private Object op(BigInteger left, BigInteger right) {
                           // we'll raise unless left is one of the shortcut values
                           return op(left, Long.MAX_VALUE);
                       }
      -            } else if (left.signum() == 0) {
      -                throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.ZeroDivisionError, ErrorMessages.POW_ZERO_CANNOT_RAISE_TO_NEGATIVE_POWER);
                   } else {
      -                try {
      -                    return Math.pow(left.longValueExact(), right.longValueExact());
      -                } catch (ArithmeticException e) {
      -                    return Math.pow(left.doubleValue(), right.doubleValue());
      +                double leftDouble = PInt.doubleValueWithOverflow(this, left);
      +                double rightDouble = PInt.doubleValueWithOverflow(this, right);
      +                if (leftDouble == 0.0) {
      +                    throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.ZeroDivisionError, ErrorMessages.POW_ZERO_CANNOT_RAISE_TO_NEGATIVE_POWER);
                       }
      +                return Math.pow(leftDouble, rightDouble);
                   }
               }
       
      @@ -1391,14 +1488,14 @@ private BigInteger op(BigInteger a, long b) {
                   }
                   if (b != (int) b) {
                       // exponent does not fit in an int, this is likely going to cause out-of-memory
      -                throw PRaiseNode.raiseUncached(this, PythonErrorType.ArithmeticError, ErrorMessages.EXPONENT_TOO_LARGE);
      +                throw PRaiseNode.raiseStatic(this, PythonErrorType.ArithmeticError, ErrorMessages.EXPONENT_TOO_LARGE);
                   }
                   return a.pow((int) b);
               }
       
               @NeverDefault
               public static PowNode create() {
      -            return IntBuiltinsFactory.PowNodeFactory.create();
      +            return PowNodeFactory.create();
               }
           }
       
      @@ -1412,16 +1509,14 @@ static Object absInt(int arg) {
       
               @Specialization
               static Object absLong(long arg,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory.Lazy factory) {
      -            return PInt.abs(inliningTarget, arg, factory);
      +                        @Bind("this") Node inliningTarget) {
      +            return PInt.abs(inliningTarget, arg);
               }
       
               @Specialization
               static PInt absPInt(PInt arg,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory.Lazy factory) {
      -            return factory.get(inliningTarget).createInt(arg.abs());
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, arg.abs());
               }
       
               @Specialization
      @@ -1432,7 +1527,7 @@ static int absBoolean(boolean arg) {
       
           @Builtin(name = J___CEIL__, minNumOfPositionalArgs = 1)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           abstract static class CeilNode extends PythonUnaryBuiltinNode {
               @Specialization
               static int ceil(int arg) {
      @@ -1452,7 +1547,7 @@ static PInt ceil(PInt arg) {
       
           @Builtin(name = J___FLOOR__, minNumOfPositionalArgs = 1)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           abstract static class FloorNode extends PythonUnaryBuiltinNode {
               @Specialization
               static int floor(int arg) {
      @@ -1466,8 +1561,8 @@ static long floor(long arg) {
       
               @Specialization
               static PInt floor(PInt arg,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createInt(arg.getValue());
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, arg.getValue());
               }
           }
       
      @@ -1486,8 +1581,8 @@ static Long pos(Long arg) {
       
               @Specialization
               static PInt pos(PInt arg,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createInt(arg.getValue());
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, arg.getValue());
               }
       
               @Specialization
      @@ -1518,15 +1613,15 @@ static long neg(long arg) {
       
               @Specialization
               static PInt negOvf(long arg,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   BigInteger value = arg == Long.MIN_VALUE ? negate(PInt.longToBigInteger(arg)) : PInt.longToBigInteger(-arg);
      -            return factory.createInt(value);
      +            return PFactory.createInt(language, value);
               }
       
               @Specialization
               static PInt doPInt(PInt operand,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(negate(operand.getValue()));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, negate(operand.getValue()));
               }
       
               @Specialization
      @@ -1541,7 +1636,7 @@ static BigInteger negate(BigInteger value) {
       
               @NeverDefault
               public static NegNode create() {
      -            return IntBuiltinsFactory.NegNodeFactory.create();
      +            return NegNodeFactory.create();
               }
           }
       
      @@ -1565,8 +1660,8 @@ static long neg(long arg) {
       
               @Specialization
               static PInt doPInt(PInt operand,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createInt(not(operand.getValue()));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, not(operand.getValue()));
               }
       
               @TruffleBoundary
      @@ -1577,13 +1672,13 @@ static BigInteger not(BigInteger value) {
       
           @Slot(value = SlotKind.nb_lshift, isComplex = true)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           public abstract static class LShiftNode extends BinaryOpBuiltinNode {
               public abstract int executeInt(int left, int right) throws UnexpectedResultException;
       
               public abstract Object execute(int left, int right);
       
      -        private static long leftShiftExact(Node inliningTarget, long left, long right, PRaiseNode.Lazy raiseNode) throws OverflowException {
      +        private static long leftShiftExact(Node inliningTarget, long left, long right, PRaiseNode raiseNode) throws OverflowException {
                   if (right >= Long.SIZE || right < 0) {
                       shiftError(inliningTarget, right, raiseNode);
                   }
      @@ -1597,7 +1692,7 @@ private static long leftShiftExact(Node inliningTarget, long left, long right, P
                   return result;
               }
       
      -        private static int leftShiftExact(Node inliningTarget, int left, int right, PRaiseNode.Lazy raiseNode) throws OverflowException {
      +        private static int leftShiftExact(Node inliningTarget, int left, int right, PRaiseNode raiseNode) throws OverflowException {
                   if (right >= Integer.SIZE || right < 0) {
                       shiftError(inliningTarget, right, raiseNode);
                   }
      @@ -1611,18 +1706,18 @@ private static int leftShiftExact(Node inliningTarget, int left, int right, PRai
                   return result;
               }
       
      -        private static void shiftError(Node inliningTarget, long shiftCount, PRaiseNode.Lazy raiseNode) throws OverflowException {
      +        private static void shiftError(Node inliningTarget, long shiftCount, PRaiseNode raiseNode) throws OverflowException {
                   if (shiftCount >= Integer.SIZE) {
                       throw OverflowException.INSTANCE;
                   } else if (shiftCount < 0) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.NEGATIVE_SHIFT_COUNT);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NEGATIVE_SHIFT_COUNT);
                   }
               }
       
               @Specialization(rewriteOn = OverflowException.class)
               static int doII(int left, int right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) throws OverflowException {
      +                        @Shared @Cached PRaiseNode raiseNode) throws OverflowException {
                   raiseNegativeShiftCount(inliningTarget, right < 0, raiseNode);
                   return leftShiftExact(inliningTarget, left, right, raiseNode);
               }
      @@ -1630,20 +1725,19 @@ static int doII(int left, int right,
               @Specialization
               static Object doIIOvf(int left, int right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   raiseNegativeShiftCount(inliningTarget, right < 0, raiseNode);
                   try {
                       return leftShiftExact(inliningTarget, left, right, raiseNode);
                   } catch (OverflowException e) {
      -                return doGuardedBiI(inliningTarget, PInt.longToBigInteger(left), right, factory, raiseNode);
      +                return doGuardedBiI(inliningTarget, PInt.longToBigInteger(left), right, raiseNode);
                   }
               }
       
               @Specialization(rewriteOn = OverflowException.class)
               static long doLL(long left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) throws OverflowException {
      +                        @Shared @Cached PRaiseNode raiseNode) throws OverflowException {
                   raiseNegativeShiftCount(inliningTarget, right < 0, raiseNode);
                   return leftShiftExact(inliningTarget, left, right, raiseNode);
               }
      @@ -1651,24 +1745,21 @@ static long doLL(long left, long right,
               @Specialization
               static Object doILOvf(int left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            return doLLOvf(left, right, inliningTarget, factory, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            return doLLOvf(left, right, inliningTarget, raiseNode);
               }
       
               @Specialization
               static Object doLIOvf(long left, int right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            return doLLOvf(left, right, inliningTarget, factory, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            return doLLOvf(left, right, inliningTarget, raiseNode);
               }
       
               @Specialization
               static Object doLLOvf(long left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   raiseNegativeShiftCount(inliningTarget, right < 0, raiseNode);
                   try {
                       return leftShiftExact(inliningTarget, left, right, raiseNode);
      @@ -1676,12 +1767,12 @@ static Object doLLOvf(long left, long right,
                       int rightI = (int) right;
                       if (rightI == right) {
                           try {
      -                        return factory.createInt(op(PInt.longToBigInteger(left), rightI));
      +                        return PFactory.createInt(PythonLanguage.get(inliningTarget), op(PInt.longToBigInteger(left), rightI));
                           } catch (OverflowException ex) {
                               // fallback to the raise of overflow error
                           }
                       }
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.OverflowError);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError);
                   }
               }
       
      @@ -1693,17 +1784,17 @@ static int doIPiZero(@SuppressWarnings("unused") int left, @SuppressWarnings("un
               @Specialization(replaces = "doIPiZero")
               static PInt doIPi(int left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   raiseNegativeShiftCount(inliningTarget, !right.isZeroOrPositive(), raiseNode);
                   if (left == 0) {
      -                return factory.createInt(BigInteger.ZERO);
      +                return PFactory.createInt(language, BigInteger.ZERO);
                   }
                   try {
                       int iright = right.intValueExact();
      -                return factory.createInt(op(PInt.longToBigInteger(left), iright));
      +                return PFactory.createInt(language, op(PInt.longToBigInteger(left), iright));
                   } catch (OverflowException e) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.OverflowError);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError);
                   }
               }
       
      @@ -1717,47 +1808,45 @@ static int doLPiZero(@SuppressWarnings("unused") long left, @SuppressWarnings("u
               @Specialization(replaces = "doLPiZero")
               static PInt doLPi(long left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   raiseNegativeShiftCount(inliningTarget, !right.isZeroOrPositive(), raiseNode);
      +            PythonLanguage language = PythonLanguage.get(inliningTarget);
                   if (left == 0) {
      -                return factory.createInt(BigInteger.ZERO);
      +                return PFactory.createInt(language, BigInteger.ZERO);
                   }
                   try {
                       int iright = right.intValueExact();
      -                return factory.createInt(op(PInt.longToBigInteger(left), iright));
      +                return PFactory.createInt(language, op(PInt.longToBigInteger(left), iright));
                   } catch (OverflowException e) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.OverflowError);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError);
                   }
               }
       
               @Specialization
               static PInt doPiI(PInt left, int right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   raiseNegativeShiftCount(inliningTarget, right < 0, raiseNode);
      -            return doGuardedBiI(inliningTarget, left.getValue(), right, factory, raiseNode);
      +            return doGuardedBiI(inliningTarget, left.getValue(), right, raiseNode);
               }
       
      -        static PInt doGuardedBiI(Node inliningTarget, BigInteger left, int right, PythonObjectFactory factory, PRaiseNode.Lazy raiseNode) {
      +        static PInt doGuardedBiI(Node inliningTarget, BigInteger left, int right, PRaiseNode raiseNode) {
                   try {
      -                return factory.createInt(op(left, right));
      +                return PFactory.createInt(PythonLanguage.get(inliningTarget), op(left, right));
                   } catch (OverflowException e) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.OverflowError);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError);
                   }
               }
       
               @Specialization
               static PInt doPiL(PInt left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   int rightI = (int) right;
                   if (rightI == right) {
      -                return doPiI(left, rightI, inliningTarget, factory, raiseNode);
      +                return doPiI(left, rightI, inliningTarget, raiseNode);
                   } else {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.OverflowError);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError);
                   }
               }
       
      @@ -1769,16 +1858,16 @@ static int doPiPiZero(@SuppressWarnings("unused") PInt left, @SuppressWarnings("
               @Specialization(replaces = "doPiPiZero")
               static PInt doPiPi(PInt left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   raiseNegativeShiftCount(inliningTarget, !right.isZeroOrPositive(), raiseNode);
      +            PythonLanguage language = PythonLanguage.get(inliningTarget);
                   if (left.isZero()) {
      -                return factory.createInt(BigInteger.ZERO);
      +                return PFactory.createInt(language, BigInteger.ZERO);
                   }
                   try {
      -                return factory.createInt(op(left.getValue(), right.intValueExact()));
      +                return PFactory.createInt(language, op(left.getValue(), right.intValueExact()));
                   } catch (OverflowException e) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.OverflowError);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError);
                   }
               }
       
      @@ -1797,20 +1886,20 @@ static BigInteger op(BigInteger left, int right) throws OverflowException {
                   }
               }
       
      -        private static void raiseNegativeShiftCount(Node inliningTarget, boolean cond, PRaiseNode.Lazy raiseNode) {
      +        private static void raiseNegativeShiftCount(Node inliningTarget, boolean cond, PRaiseNode raiseNode) {
                   if (cond) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.NEGATIVE_SHIFT_COUNT);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.NEGATIVE_SHIFT_COUNT);
                   }
               }
       
               @NeverDefault
               public static LShiftNode create() {
      -            return IntBuiltinsFactory.LShiftNodeFactory.create();
      +            return LShiftNodeFactory.create();
               }
           }
       
           @Slot(value = SlotKind.nb_rshift, isComplex = true)
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           @GenerateNodeFactory
           public abstract static class RShiftNode extends BinaryOpBuiltinNode {
               public abstract int executeInt(int left, int right) throws UnexpectedResultException;
      @@ -1820,7 +1909,7 @@ public abstract static class RShiftNode extends BinaryOpBuiltinNode {
               @Specialization(guards = "right < 32")
               static int doIISmall(int left, int right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   raiseNegativeShiftCount(inliningTarget, right < 0, raiseNode);
                   return left >> right;
               }
      @@ -1828,7 +1917,7 @@ static int doIISmall(int left, int right,
               @Specialization(replaces = "doIISmall")
               static int doII(int left, int right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   raiseNegativeShiftCount(inliningTarget, right < 0, raiseNode);
                   // Note: according to JLS, if 'left' is an int, then only the 5 LSBs of 'right' are
                   // considered. However, Python would consider more bits, so do the max possible shift.
      @@ -1838,7 +1927,7 @@ static int doII(int left, int right,
               @Specialization(guards = "right < 64")
               static long doLLSmall(long left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   raiseNegativeShiftCount(inliningTarget, right < 0, raiseNode);
                   return left >> right;
               }
      @@ -1846,7 +1935,7 @@ static long doLLSmall(long left, long right,
               @Specialization(replaces = "doLLSmall")
               static long doLL(long left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   raiseNegativeShiftCount(inliningTarget, right < 0, raiseNode);
                   // for explanation, see 'doII'
                   return left >> (right >= 64 ? 63 : right);
      @@ -1855,37 +1944,35 @@ static long doLL(long left, long right,
               @Specialization
               static Object doIPi(int left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            return doHugeShift(inliningTarget, PInt.longToBigInteger(left), right, factory, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            return doHugeShift(inliningTarget, PInt.longToBigInteger(left), right, raiseNode);
               }
       
               @Specialization
               static Object doLPi(long left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            return doHugeShift(inliningTarget, PInt.longToBigInteger(left), right, factory, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            return doHugeShift(inliningTarget, PInt.longToBigInteger(left), right, raiseNode);
               }
       
               @Specialization
               static PInt doPiI(PInt left, int right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   raiseNegativeShiftCount(inliningTarget, right < 0, raiseNode);
      -            return factory.createInt(op(left.getValue(), right));
      +            return PFactory.createInt(language, op(left.getValue(), right));
               }
       
               @Specialization
               static Object doPiL(PInt left, long right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   raiseNegativeShiftCount(inliningTarget, right < 0, raiseNode);
                   int rightI = (int) right;
                   if (rightI == right) {
      -                return factory.createInt(op(left.getValue(), rightI));
      +                return PFactory.createInt(language, op(left.getValue(), rightI));
                   }
                   // right is >= 2**31, BigInteger's bitLength is at most 2**31-1
                   // therefore the result of shifting right is just the sign bit
      @@ -1895,14 +1982,13 @@ static Object doPiL(PInt left, long right,
               @Specialization
               static Object doPInt(PInt left, PInt right,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            return doHugeShift(inliningTarget, left.getValue(), right, factory, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            return doHugeShift(inliningTarget, left.getValue(), right, raiseNode);
               }
       
      -        private static void raiseNegativeShiftCount(Node inliningTarget, boolean cond, PRaiseNode.Lazy raiseNode) {
      +        private static void raiseNegativeShiftCount(Node inliningTarget, boolean cond, PRaiseNode raiseNode) {
                   if (cond) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.NEGATIVE_SHIFT_COUNT);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.NEGATIVE_SHIFT_COUNT);
                   }
               }
       
      @@ -1912,10 +1998,10 @@ static PNotImplemented doGeneric(Object a, Object b) {
                   return PNotImplemented.NOT_IMPLEMENTED;
               }
       
      -        private static Object doHugeShift(Node inliningTarget, BigInteger left, PInt right, PythonObjectFactory factory, PRaiseNode.Lazy raiseNode) {
      +        private static Object doHugeShift(Node inliningTarget, BigInteger left, PInt right, PRaiseNode raiseNode) {
                   raiseNegativeShiftCount(inliningTarget, !right.isZeroOrPositive(), raiseNode);
                   try {
      -                return factory.createInt(op(left, right.intValueExact()));
      +                return PFactory.createInt(PythonLanguage.get(inliningTarget), op(left, right.intValueExact()));
                   } catch (OverflowException e) {
                       // right is >= 2**31, BigInteger's bitLength is at most 2**31-1
                       // therefore the result of shifting right is just the sign bit
      @@ -1930,7 +2016,7 @@ private static BigInteger op(BigInteger left, int right) {
       
               @NeverDefault
               public static RShiftNode create() {
      -            return IntBuiltinsFactory.RShiftNodeFactory.create();
      +            return RShiftNodeFactory.create();
               }
           }
       
      @@ -2011,20 +2097,20 @@ long voidPtrsManaged(VirtualFrame frame, PythonNativeVoidPtr a, PythonNativeVoid
       
               @Specialization
               PInt doPInt(long left, PInt right,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(op(PInt.longToBigInteger(left), right.getValue()));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, op(PInt.longToBigInteger(left), right.getValue()));
               }
       
               @Specialization
               PInt doPInt(PInt left, long right,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(op(left.getValue(), PInt.longToBigInteger(right)));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, op(left.getValue(), PInt.longToBigInteger(right)));
               }
       
               @Specialization
               PInt doPInt(PInt left, PInt right,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(op(left.getValue(), right.getValue()));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, op(left.getValue(), right.getValue()));
               }
       
               @SuppressWarnings("unused")
      @@ -2035,7 +2121,7 @@ static PNotImplemented doGeneric(Object a, Object b) {
           }
       
           @Slot(value = SlotKind.nb_and, isComplex = true)
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           @GenerateNodeFactory
           public abstract static class AndNode extends BinaryBitwiseNode {
       
      @@ -2057,12 +2143,12 @@ protected final BigInteger op(BigInteger left, BigInteger right) {
       
               @NeverDefault
               public static AndNode create() {
      -            return IntBuiltinsFactory.AndNodeFactory.create();
      +            return AndNodeFactory.create();
               }
           }
       
           @Slot(value = SlotKind.nb_or, isComplex = true)
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           @GenerateNodeFactory
           public abstract static class OrNode extends BinaryBitwiseNode {
       
      @@ -2084,12 +2170,12 @@ public final BigInteger op(BigInteger left, BigInteger right) {
       
               @NeverDefault
               public static OrNode create() {
      -            return IntBuiltinsFactory.OrNodeFactory.create();
      +            return OrNodeFactory.create();
               }
           }
       
           @Slot(value = SlotKind.nb_xor, isComplex = true)
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           @GenerateNodeFactory
           public abstract static class XorNode extends BinaryBitwiseNode {
               @Override
      @@ -2110,472 +2196,213 @@ public BigInteger op(BigInteger left, BigInteger right) {
       
               @NeverDefault
               public static XorNode create() {
      -            return IntBuiltinsFactory.XorNodeFactory.create();
      +            return XorNodeFactory.create();
               }
           }
       
      -    @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      -    public abstract static class EqNode extends PythonBinaryBuiltinNode {
      -        @Specialization
      -        static boolean eqLL(long a, long b) {
      -            return a == b;
      -        }
      -
      -        @Specialization
      -        static boolean eqPIntBoolean(PInt a, boolean b) {
      -            return b ? a.isOne() : a.isZero();
      -        }
      -
      -        @Specialization
      -        static boolean eqBooleanPInt(boolean a, PInt b) {
      -            return a ? b.isOne() : b.isZero();
      -        }
      -
      -        @Specialization(rewriteOn = OverflowException.class)
      -        static boolean eqPiL(PInt a, long b) throws OverflowException {
      -            return a.longValueExact() == b;
      -        }
      -
      -        @Specialization
      -        static boolean eqPiLOvf(PInt a, long b) {
      -            try {
      -                return a.longValueExact() == b;
      -            } catch (OverflowException e) {
      -                return false;
      -            }
      -        }
      -
      -        @Specialization(rewriteOn = OverflowException.class)
      -        static boolean eqLPi(long b, PInt a) throws OverflowException {
      -            return a.longValueExact() == b;
      -        }
      -
      -        @Specialization
      -        static boolean eqPiLOvf(long b, PInt a) {
      -            try {
      -                return a.longValueExact() == b;
      -            } catch (OverflowException e) {
      -                return false;
      -            }
      -        }
      -
      -        @Specialization
      -        static boolean eqPiPi(PInt a, PInt b) {
      -            return a.compareTo(b) == 0;
      -        }
      -
      -        // left: PythonNativeVoidPtr
      -
      -        @Specialization
      -        static boolean eqLongVoidPtr(VirtualFrame frame, long a, PythonNativeVoidPtr b,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared("h") @Cached PyObjectHashNode hashNode) {
      -            return eqVoidPtrLong(frame, b, a, inliningTarget, hashNode);
      -        }
      -
      -        @Specialization
      -        static boolean eqPIntVoidPtr(PInt a, PythonNativeVoidPtr b) {
      -            return eqVoidPtrPInt(b, a);
      -        }
      -
      -        @Specialization
      -        static boolean eqVoidPtrLong(VirtualFrame frame, PythonNativeVoidPtr a, long b,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared("h") @Cached PyObjectHashNode hashNode) {
      -            if (a.isNativePointer()) {
      -                long ptrVal = a.getNativePointer();
      -                // pointers are considered unsigned
      -                return ptrVal == b;
      -            }
      -            return hashNode.execute(frame, inliningTarget, a) == b;
      -        }
      -
      -        @Specialization(guards = {"a.isNativePointer()", "b.isNativePointer()"})
      -        static boolean voidPtrsNative(PythonNativeVoidPtr a, PythonNativeVoidPtr b) {
      -            long ptrVal = a.getNativePointer();
      -            // pointers are considered unsigned
      -            return ptrVal == b.getNativePointer();
      -        }
      -
      -        @Specialization(guards = {"a.isNativePointer()", "!b.isNativePointer()"})
      -        static boolean voidPtrsANative(VirtualFrame frame, PythonNativeVoidPtr a, PythonNativeVoidPtr b,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared("h") @Cached PyObjectHashNode hashNode) {
      -            long ptrVal = a.getNativePointer();
      -            // pointers are considered unsigned
      -            return ptrVal == hashNode.execute(frame, inliningTarget, b);
      -        }
      -
      -        @Specialization(guards = {"!a.isNativePointer()", "b.isNativePointer()"})
      -        static boolean voidPtrsBNative(VirtualFrame frame, PythonNativeVoidPtr a, PythonNativeVoidPtr b,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared("h") @Cached PyObjectHashNode hashNode) {
      -            long ptrVal = b.getNativePointer();
      -            // pointers are considered unsigned
      -            return ptrVal == hashNode.execute(frame, inliningTarget, a);
      -        }
      +    @GenerateInline
      +    @GenerateCached(false)
      +    @TypeSystemReference(PythonIntegerTypes.class)
      +    @ImportStatic(FromNativeSubclassNode.class)
      +    abstract static class RichCompareHelperNode extends Node {
       
      -        @Specialization(guards = {"!a.isNativePointer()", "!b.isNativePointer()"})
      -        static boolean voidPtrsManaged(VirtualFrame frame, PythonNativeVoidPtr a, PythonNativeVoidPtr b,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared("h") @Cached PyObjectHashNode hashNode) {
      -            return hashNode.execute(frame, inliningTarget, a) == hashNode.execute(frame, inliningTarget, b);
      -        }
      +        abstract Object execute(VirtualFrame frame, Node inliningTarget, Object left, Object right, RichCmpOp op);
       
               @Specialization
      -        @TruffleBoundary
      -        static boolean eqVoidPtrPInt(PythonNativeVoidPtr a, PInt b) {
      -            if (a.isNativePointer()) {
      -                long ptrVal = a.getNativePointer();
      -                if (ptrVal < 0) {
      -                    // pointers are considered unsigned
      -                    BigInteger bi = PInt.longToBigInteger(ptrVal).add(BigInteger.ONE.shiftLeft(64));
      -                    return bi.equals(b.getValue());
      -                }
      -                return PInt.longToBigInteger(ptrVal).equals(b.getValue());
      -            }
      -            try {
      -                return PyObjectHashNode.executeUncached(a) == b.longValueExact();
      -            } catch (OverflowException e) {
      -                return false;
      -            }
      +        static boolean doII(int left, int right, RichCmpOp op) {
      +            return op.compareResultToBool(Integer.compare(left, right));
               }
       
      -        @Fallback
      -        @SuppressWarnings("unused")
      -        static PNotImplemented eq(Object a, Object b) {
      -            return PNotImplemented.NOT_IMPLEMENTED;
      -        }
      -    }
      -
      -    @Builtin(name = J___NE__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      -    abstract static class NeNode extends PythonBinaryBuiltinNode {
               @Specialization
      -        static boolean eqLL(long a, long b) {
      -            return a != b;
      +        static boolean doLL(long left, long right, RichCmpOp op) {
      +            return op.compareResultToBool(Long.compare(left, right));
               }
       
               @Specialization(rewriteOn = OverflowException.class)
      -        static boolean eqPiL(PInt a, long b) throws OverflowException {
      -            return a.longValueExact() != b;
      -        }
      -
      -        @Specialization(replaces = "eqPiL")
      -        static boolean eqPiLOvf(PInt a, long b) {
      -            try {
      -                return a.longValueExact() != b;
      -            } catch (OverflowException e) {
      -                return true;
      -            }
      +        static boolean doLPExact(long left, PInt right, RichCmpOp op) throws OverflowException {
      +            return op.compareResultToBool(Long.compare(left, right.longValueExact()));
               }
       
               @Specialization(rewriteOn = OverflowException.class)
      -        static boolean eqLPi(long b, PInt a) throws OverflowException {
      -            return a.longValueExact() != b;
      -        }
      -
      -        @Specialization(replaces = "eqLPi")
      -        static boolean eqLPiOvf(long b, PInt a) {
      -            try {
      -                return a.longValueExact() != b;
      -            } catch (OverflowException e) {
      -                return true;
      -            }
      -        }
      -
      -        @Specialization
      -        static boolean eqPiPi(PInt a, PInt b) {
      -            return a.compareTo(b) != 0;
      -        }
      -
      -        @SuppressWarnings("unused")
      -        @Fallback
      -        static PNotImplemented eq(Object a, Object b) {
      -            return PNotImplemented.NOT_IMPLEMENTED;
      -        }
      -    }
      -
      -    @Builtin(name = J___LT__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      -    @ImportStatic(FromNativeSubclassNode.class)
      -    public abstract static class LtNode extends PythonBinaryBuiltinNode {
      -        @Specialization
      -        static boolean doII(int left, int right) {
      -            return left < right;
      -        }
      -
      -        @Specialization
      -        static boolean doLL(long left, long right) {
      -            return left < right;
      +        static boolean doPLExact(PInt left, long right, RichCmpOp op) throws OverflowException {
      +            return op.compareResultToBool(Long.compare(left.longValueExact(), right));
               }
       
      -        @Specialization
      -        static boolean doLP(long left, PInt right) {
      -            try {
      -                return left < right.longValueExact();
      -            } catch (OverflowException e) {
      -                return right.doubleValue() > 0;
      -            }
      +        @Specialization(replaces = "doLPExact")
      +        static boolean doLP(long left, PInt right, RichCmpOp op) {
      +            return op.compareResultToBool(PInt.compareTo(left, right));
               }
       
      -        @Specialization
      -        static boolean doPL(PInt left, long right) {
      -            try {
      -                return left.longValueExact() < right;
      -            } catch (OverflowException e) {
      -                return left.doubleValue() < 0;
      -            }
      +        @Specialization(replaces = "doPLExact")
      +        static boolean doPL(PInt left, long right, RichCmpOp op) {
      +            return op.compareResultToBool(left.compareTo(right));
               }
       
               @Specialization
      -        static boolean doPP(PInt left, PInt right) {
      -            return left.compareTo(right) < 0;
      +        static boolean doPP(PInt left, PInt right, RichCmpOp op) {
      +            return op.compareResultToBool(left.compareTo(right));
               }
       
      -        @Specialization(guards = "isFloatSubtype(frame, inliningTarget, y, getClass, isSubtype)")
      -        static boolean doDN(VirtualFrame frame, long x, PythonAbstractNativeObject y,
      -                        @SuppressWarnings("unused") @Bind("this") Node inliningTarget,
      +        @Specialization(guards = "isFloatSubtype(inliningTarget, y, getClass, isSubtype)")
      +        @InliningCutoff
      +        static boolean doDN(VirtualFrame frame, Node inliningTarget, long x, PythonAbstractNativeObject y, RichCmpOp op,
                               @SuppressWarnings("unused") @Shared @Cached GetPythonObjectClassNode getClass,
                               @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtype,
                               @Shared @Cached FromNativeSubclassNode nativeRight) {
      -            return x < nativeRight.execute(frame, y);
      +            return op.compareResultToBool(PFloat.compare(x, nativeRight.execute(frame, y)));
               }
       
               @Specialization(guards = {
      -                        "isFloatSubtype(frame, inliningTarget, x, getClass, isSubtype)",
      -                        "isFloatSubtype(frame, inliningTarget, y, getClass, isSubtype)"})
      -        static boolean doDN(VirtualFrame frame, PythonAbstractNativeObject x, PythonAbstractNativeObject y,
      -                        @SuppressWarnings("unused") @Bind("this") Node inliningTarget,
      +                        "isFloatSubtype(inliningTarget, x, getClass, isSubtype)",
      +                        "isFloatSubtype(inliningTarget, y, getClass, isSubtype)"})
      +        @InliningCutoff
      +        static boolean doDN(VirtualFrame frame, Node inliningTarget, PythonAbstractNativeObject x, PythonAbstractNativeObject y, RichCmpOp op,
                               @SuppressWarnings("unused") @Shared @Cached GetPythonObjectClassNode getClass,
                               @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtype,
                               @Shared @Cached FromNativeSubclassNode nativeLeft,
                               @Shared @Cached FromNativeSubclassNode nativeRight) {
      -            return nativeLeft.execute(frame, x) < nativeRight.execute(frame, y);
      +            return op.compareResultToBool(PFloat.compare(nativeLeft.execute(frame, x), nativeRight.execute(frame, y)));
               }
       
      -        @Specialization(guards = "isFloatSubtype(frame, inliningTarget, x, getClass, isSubtype)")
      -        static boolean doDN(VirtualFrame frame, PythonAbstractNativeObject x, double y,
      -                        @SuppressWarnings("unused") @Bind("this") Node inliningTarget,
      +        @Specialization(guards = "isFloatSubtype(inliningTarget, x, getClass, isSubtype)")
      +        @InliningCutoff
      +        static boolean doDN(VirtualFrame frame, Node inliningTarget, PythonAbstractNativeObject x, double y, RichCmpOp op,
                               @SuppressWarnings("unused") @Shared @Cached GetPythonObjectClassNode getClass,
                               @SuppressWarnings("unused") @Shared @Cached IsSubtypeNode isSubtype,
                               @Shared @Cached FromNativeSubclassNode nativeLeft) {
      -            return nativeLeft.execute(frame, x) < y;
      -        }
      -
      -        @Specialization
      -        static boolean doVoidPtr(PythonNativeVoidPtr x, long y,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached CExtNodes.PointerCompareNode ltNode) {
      -            return ltNode.execute(inliningTarget, ComparisonOp.LT, x, y);
      -        }
      -
      -        @SuppressWarnings("unused")
      -        @Fallback
      -        static PNotImplemented doGeneric(Object a, Object b) {
      -            return PNotImplemented.NOT_IMPLEMENTED;
      -        }
      -    }
      -
      -    @Builtin(name = J___LE__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      -    abstract static class LeNode extends PythonBinaryBuiltinNode {
      -        @Specialization
      -        static boolean doII(int left, int right) {
      -            return left <= right;
      +            return op.compareResultToBool(PFloat.compare(nativeLeft.execute(frame, x), y));
               }
       
      -        @Specialization
      -        static boolean doLL(long left, long right) {
      -            return left <= right;
      -        }
      +        // Note: native int subclasses are still represented as Java PInt, just with a different
      +        // Python level class
       
      -        @Specialization
      -        static boolean doLP(long left, PInt right) {
      -            try {
      -                return left <= right.longValueExact();
      -            } catch (OverflowException e) {
      -                return right.doubleValue() > 0;
      -            }
      +        static boolean someIsNativePtr(Object a, Object b) {
      +            return a instanceof PythonNativeVoidPtr || b instanceof PythonNativeVoidPtr;
               }
       
      -        @Specialization
      -        static boolean doPL(PInt left, long right) {
      -            try {
      -                return left.longValueExact() <= right;
      -            } catch (OverflowException e) {
      -                return left.doubleValue() < 0;
      +        @Specialization(guards = "someIsNativePtr(x, y)")
      +        @InliningCutoff
      +        static Object doVoidPtr(VirtualFrame frame, Node inliningTarget, Object x, Object y, RichCmpOp op,
      +                        @Cached PointerCompareNode pointerCompareNode,
      +                        @Cached EqNodeNativePtr pointerEqNode) {
      +            if (op.isEqOrNe()) {
      +                Object result = pointerEqNode.execute(frame, x, y);
      +                if (result == PNotImplemented.NOT_IMPLEMENTED) {
      +                    return result;
      +                }
      +                return ((boolean) result) == op.isEq();
                   }
      +            return pointerCompareNode.execute(inliningTarget, op, x, y);
               }
       
      -        @Specialization
      -        static boolean doPP(PInt left, PInt right) {
      -            return left.compareTo(right) <= 0;
      -        }
      -
      -        @SuppressWarnings("unused")
      -        @Fallback
      -        static PNotImplemented doGeneric(Object a, Object b) {
      -            return PNotImplemented.NOT_IMPLEMENTED;
      -        }
      -    }
      -
      -    @Builtin(name = J___GT__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      -    public abstract static class GtNode extends PythonBinaryBuiltinNode {
      -
      -        @Specialization
      -        static boolean doII(int left, int right) {
      -            return left > right;
      -        }
      +        @TypeSystemReference(PythonIntegerTypes.class)
      +        abstract static class EqNodeNativePtr extends PNodeWithContext {
       
      -        @Specialization
      -        static boolean doLL(long left, long right) {
      -            return left > right;
      -        }
      +            abstract Object execute(VirtualFrame frame, Object a, Object b);
       
      -        @Specialization
      -        static boolean doLP(long left, PInt right) {
      -            try {
      -                return left > right.longValueExact();
      -            } catch (OverflowException e) {
      -                return right.doubleValue() < 0;
      +            @Specialization
      +            static boolean eqLongVoidPtr(VirtualFrame frame, long a, PythonNativeVoidPtr b,
      +                            @Bind("this") Node inliningTarget,
      +                            @Shared("h") @Cached PyObjectHashNode hashNode) {
      +                return eqVoidPtrLong(frame, b, a, inliningTarget, hashNode);
                   }
      -        }
       
      -        @Specialization
      -        static boolean doPL(PInt left, long right) {
      -            try {
      -                return left.longValueExact() > right;
      -            } catch (OverflowException e) {
      -                return left.doubleValue() > 0;
      +            @Specialization
      +            static boolean eqPIntVoidPtr(PInt a, PythonNativeVoidPtr b) {
      +                return eqVoidPtrPInt(b, a);
                   }
      -        }
       
      -        @Specialization
      -        static boolean doPP(PInt left, PInt right) {
      -            return left.compareTo(right) > 0;
      -        }
      -
      -        @SuppressWarnings("unused")
      -        @Fallback
      -        static PNotImplemented doGeneric(Object a, Object b) {
      -            return PNotImplemented.NOT_IMPLEMENTED;
      -        }
      -    }
      -
      -    @Builtin(name = J___GE__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      -    abstract static class GeNode extends PythonBinaryBuiltinNode {
      -
      -        @Specialization
      -        static boolean doII(int left, int right) {
      -            return left >= right;
      -        }
      -
      -        @Specialization
      -        static boolean doLL(long left, long right) {
      -            return left >= right;
      -        }
      -
      -        @Specialization
      -        static boolean doLP(long left, PInt right) {
      -            try {
      -                return left >= right.longValueExact();
      -            } catch (OverflowException e) {
      -                return right.doubleValue() < 0;
      +            @Specialization
      +            static boolean eqVoidPtrLong(VirtualFrame frame, PythonNativeVoidPtr a, long b,
      +                            @Bind("this") Node inliningTarget,
      +                            @Shared("h") @Cached PyObjectHashNode hashNode) {
      +                if (a.isNativePointer()) {
      +                    long ptrVal = a.getNativePointer();
      +                    // pointers are considered unsigned
      +                    return ptrVal == b;
      +                }
      +                return hashNode.execute(frame, inliningTarget, a) == b;
                   }
      -        }
       
      -        @Specialization
      -        static boolean doPL(PInt left, long right) {
      -            try {
      -                return left.longValueExact() >= right;
      -            } catch (OverflowException e) {
      -                return left.doubleValue() > 0;
      +            @Specialization(guards = {"a.isNativePointer()", "b.isNativePointer()"})
      +            static boolean voidPtrsNative(PythonNativeVoidPtr a, PythonNativeVoidPtr b) {
      +                long ptrVal = a.getNativePointer();
      +                // pointers are considered unsigned
      +                return ptrVal == b.getNativePointer();
                   }
      -        }
      -
      -        @Specialization
      -        static boolean doPP(PInt left, PInt right) {
      -            return left.compareTo(right) >= 0;
      -        }
      -
      -        @SuppressWarnings("unused")
      -        @Fallback
      -        static PNotImplemented doGeneric(Object a, Object b) {
      -            return PNotImplemented.NOT_IMPLEMENTED;
      -        }
      -    }
      -
      -    @GenerateInline
      -    @GenerateCached(false)
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      -    abstract static class RichCompareHelperNode extends Node {
       
      -        abstract Object execute(Node inliningTarget, Object left, Object right, ComparisonOp op);
      -
      -        @Specialization
      -        static boolean doII(int left, int right, ComparisonOp op) {
      -            return op.cmpResultToBool(Integer.compare(left, right));
      -        }
      -
      -        @Specialization
      -        static boolean doLL(long left, long right, ComparisonOp op) {
      -            return op.cmpResultToBool(Long.compare(left, right));
      -        }
      +            @Specialization(guards = {"a.isNativePointer()", "!b.isNativePointer()"})
      +            static boolean voidPtrsANative(VirtualFrame frame, PythonNativeVoidPtr a, PythonNativeVoidPtr b,
      +                            @Bind("this") Node inliningTarget,
      +                            @Shared("h") @Cached PyObjectHashNode hashNode) {
      +                long ptrVal = a.getNativePointer();
      +                // pointers are considered unsigned
      +                return ptrVal == hashNode.execute(frame, inliningTarget, b);
      +            }
       
      -        @Specialization
      -        static boolean doLP(long left, PInt right, ComparisonOp op) {
      -            return op.cmpResultToBool(PInt.compareTo(left, right));
      -        }
      +            @Specialization(guards = {"!a.isNativePointer()", "b.isNativePointer()"})
      +            static boolean voidPtrsBNative(VirtualFrame frame, PythonNativeVoidPtr a, PythonNativeVoidPtr b,
      +                            @Bind("this") Node inliningTarget,
      +                            @Shared("h") @Cached PyObjectHashNode hashNode) {
      +                long ptrVal = b.getNativePointer();
      +                // pointers are considered unsigned
      +                return ptrVal == hashNode.execute(frame, inliningTarget, a);
      +            }
       
      -        @Specialization
      -        static boolean doPL(PInt left, long right, ComparisonOp op) {
      -            return op.cmpResultToBool(left.compareTo(right));
      -        }
      +            @Specialization(guards = {"!a.isNativePointer()", "!b.isNativePointer()"})
      +            static boolean voidPtrsManaged(VirtualFrame frame, PythonNativeVoidPtr a, PythonNativeVoidPtr b,
      +                            @Bind("this") Node inliningTarget,
      +                            @Shared("h") @Cached PyObjectHashNode hashNode) {
      +                return hashNode.execute(frame, inliningTarget, a) == hashNode.execute(frame, inliningTarget, b);
      +            }
       
      -        @Specialization
      -        static boolean doPP(PInt left, PInt right, ComparisonOp op) {
      -            return op.cmpResultToBool(left.compareTo(right));
      -        }
      +            @Specialization
      +            @TruffleBoundary
      +            static boolean eqVoidPtrPInt(PythonNativeVoidPtr a, PInt b) {
      +                if (a.isNativePointer()) {
      +                    long ptrVal = a.getNativePointer();
      +                    if (ptrVal < 0) {
      +                        // pointers are considered unsigned
      +                        BigInteger bi = PInt.longToBigInteger(ptrVal).add(BigInteger.ONE.shiftLeft(64));
      +                        return bi.equals(b.getValue());
      +                    }
      +                    return PInt.longToBigInteger(ptrVal).equals(b.getValue());
      +                }
      +                try {
      +                    return PyObjectHashNode.executeUncached(a) == b.longValueExact();
      +                } catch (OverflowException e) {
      +                    return false;
      +                }
      +            }
       
      -        @Specialization
      -        static boolean doVoidPtr(Node inliningTarget, PythonNativeVoidPtr x, long y, ComparisonOp op,
      -                        @Cached CExtNodes.PointerCompareNode ltNode) {
      -            return ltNode.execute(inliningTarget, op, x, y);
      +            @SuppressWarnings("unused")
      +            @Fallback
      +            static PNotImplemented doGeneric(Object a, Object b) {
      +                return PNotImplemented.NOT_IMPLEMENTED;
      +            }
               }
       
               @SuppressWarnings("unused")
               @Fallback
      -        static PNotImplemented doGeneric(Object a, Object b, ComparisonOp op) {
      +        static PNotImplemented doGeneric(Object a, Object b, RichCmpOp op) {
                   return PNotImplemented.NOT_IMPLEMENTED;
               }
           }
       
      -    @Builtin(name = J___TRUFFLE_RICHCOMPARE__, minNumOfPositionalArgs = 3)
      +    @Slot(value = SlotKind.tp_richcompare, isComplex = true)
           @GenerateNodeFactory
      -    @ImportStatic(ComparisonOp.class)
      -    abstract static class RichCompareNode extends PythonTernaryBuiltinNode {
      -
      -        @Specialization(guards = {"opCode == cachedOp.opCode"}, limit = "6")
      -        static Object doCached(Object left, Object right, @SuppressWarnings("unused") int opCode,
      +    abstract static class RichCompareNode extends RichCmpBuiltinNode {
      +        @Specialization(guards = {"opCode == cachedOp"}, limit = "6")
      +        static Object doCached(VirtualFrame frame, Object left, Object right, @SuppressWarnings("unused") RichCmpOp opCode,
                               @Bind("this") Node inliningTarget,
                               @Cached PyLongCheckNode checkLeft,
                               @Cached PyLongCheckNode checkRight,
      -                        @SuppressWarnings("unused") @Cached("fromOpCode(opCode)") ComparisonOp cachedOp,
      +                        @SuppressWarnings("unused") @Cached("opCode") RichCmpOp cachedOp,
                               @Cached RichCompareHelperNode cmpNode) {
                   if (!checkLeft.execute(inliningTarget, left) || !checkRight.execute(inliningTarget, right)) {
                       return PNotImplemented.NOT_IMPLEMENTED;
                   }
      -            return cmpNode.execute(inliningTarget, left, right, cachedOp);
      +            return cmpNode.execute(frame, inliningTarget, left, right, cachedOp);
               }
           }
       
      @@ -2586,7 +2413,7 @@ static Object doCached(Object left, Object right, @SuppressWarnings("unused") in
           @ArgumentClinic(name = "signed", conversion = ClinicConversion.Boolean, defaultValue = "false")
           @GenerateNodeFactory
           @SuppressWarnings("unused")
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           public abstract static class ToBytesNode extends PythonClinicBuiltinNode {
       
               @TruffleBoundary
      @@ -2597,33 +2424,33 @@ private static boolean isBigEndian(Node raisingNode, TruffleString order) {
                   if (order.equalsUncached(T_LITTLE, TS_ENCODING)) {
                       return false;
                   }
      -            throw PRaiseNode.raiseUncached(raisingNode, PythonErrorType.ValueError, ErrorMessages.BYTEORDER_MUST_BE_LITTLE_OR_BIG);
      +            throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.BYTEORDER_MUST_BE_LITTLE_OR_BIG);
               }
       
               @Specialization
               static PBytes fromLong(long self, int byteCount, TruffleString byteorder, boolean signed,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Exclusive @Cached InlinedConditionProfile negativeByteCountProfile,
                               @Exclusive @Cached InlinedConditionProfile negativeNumberProfile,
                               @Exclusive @Cached InlinedConditionProfile overflowProfile,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   if (negativeByteCountProfile.profile(inliningTarget, byteCount < 0)) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.MESSAGE_LENGTH_ARGUMENT);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.MESSAGE_LENGTH_ARGUMENT);
                   }
                   if (self < 0) {
                       if (negativeNumberProfile.profile(inliningTarget, !signed)) {
      -                    throw raiseNode.get(inliningTarget).raise(PythonErrorType.OverflowError, ErrorMessages.MESSAGE_CONVERT_NEGATIVE);
      +                    throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.MESSAGE_CONVERT_NEGATIVE);
                       }
                   }
      -            return factory.createBytes(fromLong(self, byteCount, isBigEndian(inliningTarget, byteorder), signed,
      +            return PFactory.createBytes(language, fromLong(self, byteCount, isBigEndian(inliningTarget, byteorder), signed,
                                   inliningTarget, overflowProfile, raiseNode));
               }
       
               public static byte[] fromLong(long self, int byteCount, boolean isBigEndian, boolean signed,
                               Node inliningTarget,
                               InlinedConditionProfile overflowProfile,
      -                        PRaiseNode.Lazy raiseNode) {
      +                        PRaiseNode raiseNode) {
                   byte signByte = 0;
                   if (self < 0) {
                       assert signed : ErrorMessages.MESSAGE_CONVERT_NEGATIVE;
      @@ -2651,8 +2478,8 @@ public static byte[] fromLong(long self, int byteCount, boolean isBigEndian, boo
                       index += delta;
                   }
       
      -            if (overflowProfile.profile(inliningTarget, !signed && number != 0 || (signed && bytes.length == 1 && bytes[0] != self) || (byteCount == 0 && self != 0))) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.OverflowError, ErrorMessages.MESSAGE_INT_TO_BIG);
      +            if (overflowProfile.profile(inliningTarget, !signed && number != 0 || (signed && bytes.length == 1 && bytes[0] != self) || (byteCount == 0 && self != 0 && self != -1))) {
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.MESSAGE_INT_TO_BIG);
                   }
       
                   if (signed) {
      @@ -2668,7 +2495,7 @@ public static byte[] fromLong(long self, int byteCount, boolean isBigEndian, boo
               private static byte getSignByte(BigInteger value, boolean signed, Node raisingNode) {
                   if (value.compareTo(BigInteger.ZERO) < 0) {
                       if (!signed) {
      -                    throw PRaiseNode.raiseUncached(raisingNode, PythonErrorType.OverflowError, ErrorMessages.MESSAGE_CONVERT_NEGATIVE);
      +                    throw PRaiseNode.raiseStatic(raisingNode, OverflowError, ErrorMessages.MESSAGE_CONVERT_NEGATIVE);
                       }
                       return -1;
                   }
      @@ -2683,21 +2510,21 @@ private static byte[] getBytes(BigInteger value) {
               @Specialization
               static PBytes fromPIntInt(PInt self, int byteCount, TruffleString byteorder, boolean signed,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Exclusive @Cached InlinedConditionProfile negativeByteCountProfile,
                               @Exclusive @Cached InlinedConditionProfile overflowProfile,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   if (negativeByteCountProfile.profile(inliningTarget, byteCount < 0)) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.MESSAGE_LENGTH_ARGUMENT);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.MESSAGE_LENGTH_ARGUMENT);
                   }
      -            return factory.createBytes(fromBigInteger(self, byteCount, isBigEndian(inliningTarget, byteorder), signed,
      +            return PFactory.createBytes(language, fromBigInteger(self, byteCount, isBigEndian(inliningTarget, byteorder), signed,
                                   inliningTarget, overflowProfile, raiseNode));
               }
       
               public static byte[] fromBigInteger(PInt self, int byteCount, boolean isBigEndian, boolean signed,
                               Node inliningTarget,
                               InlinedConditionProfile overflowProfile,
      -                        PRaiseNode.Lazy raiseNode) {
      +                        PRaiseNode raiseNode) {
                   BigInteger value = self.getValue();
                   byte signByte = getSignByte(value, signed, inliningTarget);
                   byte[] bytes = getBytes(value);
      @@ -2715,7 +2542,7 @@ public static byte[] fromBigInteger(PInt self, int byteCount, boolean isBigEndia
                       }
                       if (overflowProfile.profile(inliningTarget, len > byteCount)) {
                           // the corrected len is still bigger then we need.
      -                    throw raiseNode.get(inliningTarget).raise(PythonErrorType.OverflowError, ErrorMessages.MESSAGE_INT_TO_BIG);
      +                    throw raiseNode.raise(inliningTarget, PythonErrorType.OverflowError, ErrorMessages.MESSAGE_INT_TO_BIG);
                       }
                       // the array starts with sign bytes and has to be truncated to the requested
                       // size
      @@ -2757,11 +2584,11 @@ public static byte[] fromBigInteger(PInt self, int byteCount, boolean isBigEndia
       
               @Override
               protected ArgumentClinicProvider getArgumentClinic() {
      -            return IntBuiltinsClinicProviders.ToBytesNodeClinicProviderGen.INSTANCE;
      +            return ToBytesNodeClinicProviderGen.INSTANCE;
               }
           }
       
      -    @Builtin(name = "from_bytes", minNumOfPositionalArgs = 2, parameterNames = {"cls", "bytes", "byteorder"}, varArgsMarker = true, keywordOnlyNames = {"signed"}, isClassmethod = true)
      +    @Builtin(name = "from_bytes", minNumOfPositionalArgs = 2, parameterNames = {"cls", "bytes", "byteorder"}, keywordOnlyNames = {"signed"}, isClassmethod = true)
           @ArgumentClinic(name = "byteorder", conversion = ClinicConversion.TString, defaultValue = "T_BIG")
           @ArgumentClinic(name = "signed", conversion = ClinicConversion.Boolean, defaultValue = "false")
           @ImportStatic(SpecialMethodNames.class)
      @@ -2771,29 +2598,29 @@ public abstract static class FromBytesNode extends PythonClinicBuiltinNode {
               @Specialization
               static Object fromObject(VirtualFrame frame, Object cl, Object object, TruffleString byteorder, boolean signed,
                               @Bind("this") Node inliningTarget,
      -                        @Cached("create(Bytes)") LookupAndCallUnaryNode callBytes,
      +                        @Cached("create(T___BYTES__)") LookupAndCallUnaryNode callBytes,
                               @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib,
      -                        @Cached BuiltinClassProfiles.IsBuiltinClassExactProfile isBuiltinIntProfile,
      +                        @Cached IsBuiltinClassExactProfile isBuiltinIntProfile,
                               @Cached InlinedBranchProfile hasBytesProfile,
      -                        @Cached TruffleString.EqualNode equalNode,
      -                        @Cached BytesNodes.BytesFromObject bytesFromObject,
      -                        @Cached IntNodes.PyLongFromByteArray fromByteArray,
      +                        @Cached EqualNode equalNode,
      +                        @Cached BytesFromObject bytesFromObject,
      +                        @Cached PyLongFromByteArray fromByteArray,
                               @Cached CallNode callCtor,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   boolean littleEndian;
                   if (equalNode.execute(byteorder, T_BIG, TS_ENCODING)) {
                       littleEndian = false;
                   } else if (equalNode.execute(byteorder, T_LITTLE, TS_ENCODING)) {
                       littleEndian = true;
                   } else {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.BYTEORDER_MUST_BE_LITTLE_OR_BIG);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.BYTEORDER_MUST_BE_LITTLE_OR_BIG);
                   }
                   byte[] bytes;
                   Object bytesObj = callBytes.executeObject(frame, object);
                   if (bytesObj != PNone.NO_VALUE) {
                       hasBytesProfile.enter(inliningTarget);
                       if (!(bytesObj instanceof PBytes)) {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.RETURNED_NONBYTES, T___BYTES__);
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.RETURNED_NONBYTES, T___BYTES__);
                       }
                       bytes = bufferLib.getCopiedByteArray(bytesObj);
                   } else {
      @@ -2809,7 +2636,7 @@ static Object fromObject(VirtualFrame frame, Object cl, Object object, TruffleSt
       
               @Override
               protected ArgumentClinicProvider getArgumentClinic() {
      -            return IntBuiltinsClinicProviders.FromBytesNodeClinicProviderGen.INSTANCE;
      +            return FromBytesNodeClinicProviderGen.INSTANCE;
               }
           }
       
      @@ -2844,24 +2671,24 @@ static boolean toBoolean(PythonNativeVoidPtr self,
               }
           }
       
      -    @Builtin(name = J___STR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_str, isComplex = true)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      -    abstract static class StrNode extends PythonBuiltinNode {
      +    @TypeSystemReference(PythonIntegerTypes.class)
      +    abstract static class StrNode extends PythonUnaryBuiltinNode {
       
               @Specialization
               static TruffleString doL(long self,
      -                        @Shared("fromLong") @Cached TruffleString.FromLongNode fromLongNode) {
      +                        @Shared("fromLong") @Cached FromLongNode fromLongNode) {
                   return fromLongNode.execute(self, TS_ENCODING, false);
               }
       
               @Specialization
               static TruffleString doPInt(PInt self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached TruffleString.FromJavaStringNode fromJavaStringNode,
      +                        @Cached FromJavaStringNode fromJavaStringNode,
                               @Cached InlinedIntValueProfile maxDigitsProfile,
                               @Cached InlinedIntValueProfile maxDigitsBitLengthProfile,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   PythonContext context = PythonContext.get(inliningTarget);
                   int intMaxStrDigits = maxDigitsProfile.profile(inliningTarget, context.getIntMaxStrDigits());
                   /*
      @@ -2879,7 +2706,7 @@ static TruffleString doPInt(PInt self,
                   if (intMaxStrDigits > 0) {
                       int bitLength = positiveBitLength(self);
                       if (bitLength >= maxDigitsBitLengthProfile.profile(inliningTarget, context.getMinIntBitLengthOverLimit())) {
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.EXCEEDS_THE_LIMIT_FOR_INTEGER_STRING_CONVERSION, intMaxStrDigits);
      +                    throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.EXCEEDS_THE_LIMIT_FOR_INTEGER_STRING_CONVERSION, intMaxStrDigits);
                       }
                   }
                   String value = self.toString();
      @@ -2890,7 +2717,7 @@ static TruffleString doPInt(PInt self,
                   if (intMaxStrDigits > 0) {
                       int digits = self.isNegative() ? value.length() - 1 : value.length();
                       if (digits > intMaxStrDigits) {
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.EXCEEDS_THE_LIMIT_FOR_INTEGER_STRING_CONVERSION);
      +                    throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.EXCEEDS_THE_LIMIT_FOR_INTEGER_STRING_CONVERSION);
                       }
                   }
                   return fromJavaStringNode.execute(value, TS_ENCODING);
      @@ -2905,12 +2732,12 @@ private static int positiveBitLength(PInt self) {
               static TruffleString doNativeVoidPtr(VirtualFrame frame, PythonNativeVoidPtr self,
                               @Bind("this") Node inliningTarget,
                               @Cached PyObjectHashNode hashNode,
      -                        @Shared("fromLong") @Cached TruffleString.FromLongNode fromLongNode) {
      +                        @Shared("fromLong") @Cached FromLongNode fromLongNode) {
                   return doL(hashNode.execute(frame, inliningTarget, self), fromLongNode);
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends StrNode {
           }
      @@ -2924,19 +2751,19 @@ protected ArgumentClinicProvider getArgumentClinic() {
                   return FormatNodeClinicProviderGen.INSTANCE;
               }
       
      -        // We cannot use PythonArithmeticTypes, because for empty format string we need to call the
      +        // We cannot use PythonIntegerTypes, because for empty format string we need to call the
               // boolean's __str__ and not int's __str__ (that specialization is inherited)
               @Specialization(guards = "!formatString.isEmpty()")
               static TruffleString formatB(boolean self, TruffleString formatString,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   return formatI(self ? 1 : 0, formatString, inliningTarget, raiseNode);
               }
       
               @Specialization(guards = "!formatString.isEmpty()")
               static TruffleString formatI(int self, TruffleString formatString,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   Spec spec = getSpec(formatString, inliningTarget);
                   if (isDoubleSpec(spec)) {
                       return formatDouble(spec, self, inliningTarget);
      @@ -2948,17 +2775,17 @@ static TruffleString formatI(int self, TruffleString formatString,
               @Specialization(guards = "!formatString.isEmpty()")
               static TruffleString formatL(VirtualFrame frame, long self, TruffleString formatString,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Shared @Cached PyNumberFloatNode floatNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            return formatPI(frame, factory.createInt(self), formatString, inliningTarget, floatNode, raiseNode);
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            return formatPI(frame, PFactory.createInt(language, self), formatString, inliningTarget, floatNode, raiseNode);
               }
       
               @Specialization(guards = "!formatString.isEmpty()")
               static TruffleString formatPI(VirtualFrame frame, PInt self, TruffleString formatString,
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached PyNumberFloatNode floatNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   Spec spec = getSpec(formatString, inliningTarget);
                   if (isDoubleSpec(spec)) {
                       // lazy init of floatNode serves as branch profile
      @@ -3005,25 +2832,25 @@ private static TruffleString formatPInt(PInt self, Spec spec, Node raisingNode)
                   return formatter.pad().getResult();
               }
       
      -        private static void validateIntegerSpec(Node inliningTarget, PRaiseNode.Lazy raiseNode, Spec spec) {
      +        private static void validateIntegerSpec(Node inliningTarget, PRaiseNode raiseNode, Spec spec) {
                   if (Spec.specified(spec.precision)) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.PRECISION_NOT_ALLOWED_FOR_INT);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.PRECISION_NOT_ALLOWED_FOR_INT);
                   }
                   if (spec.type == 'c') {
                       if (Spec.specified(spec.sign)) {
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.SIGN_NOT_ALLOWED_WITH_C_FOR_INT);
      +                    throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.SIGN_NOT_ALLOWED_WITH_C_FOR_INT);
                       } else if (spec.alternate) {
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.ALTERNATE_NOT_ALLOWED_WITH_C_FOR_INT);
      +                    throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.ALTERNATE_NOT_ALLOWED_WITH_C_FOR_INT);
                       }
                   }
               }
           }
       
      -    @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_hash, isComplex = true)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      -    abstract static class HashNode extends PythonUnaryBuiltinNode {
      -
      +    @TypeSystemReference(PythonIntegerTypes.class)
      +    @GenerateUncached
      +    public abstract static class HashNode extends HashBuiltinNode {
               @Specialization
               static long hash(int self) {
                   return PyObjectHashNode.hash(self);
      @@ -3061,7 +2888,7 @@ private static long hashCodeBoundary(Object object) {
       
           @Builtin(name = "bit_count", minNumOfPositionalArgs = 1)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           abstract static class BitCountNode extends PythonBuiltinNode {
               @Specialization
               static int bitCount(int i) {
      @@ -3082,7 +2909,7 @@ static int bitCount(PInt i) {
       
           @Builtin(name = "bit_length", minNumOfPositionalArgs = 1)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           public abstract static class BitLengthNode extends PythonUnaryBuiltinNode {
               public abstract int execute(Object argument);
       
      @@ -3105,7 +2932,7 @@ static int bitLength(PInt argument) {
       
           @Builtin(name = "is_integer", minNumOfPositionalArgs = 1)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           abstract static class IsIntegerNode extends PythonUnaryBuiltinNode {
               @Specialization
               static boolean doLong(long argument) {
      @@ -3160,8 +2987,8 @@ static int get(@SuppressWarnings("unused") Object self) {
           abstract static class AsIntegerRatioNode extends PythonBuiltinNode {
               @Specialization
               static Object get(VirtualFrame frame, Object self, @Cached IntNode intNode,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createTuple(new Object[]{intNode.execute(frame, self), 1});
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createTuple(language, new Object[]{intNode.execute(frame, self), 1});
               }
           }
       
      @@ -3188,27 +3015,17 @@ static Object doCopy(Object self,
           @GenerateNodeFactory
           abstract static class GetNewArgsNode extends PythonUnaryBuiltinNode {
               @Specialization
      -        static Object doI(int self,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createTuple(new Object[]{factory.createInt(self)});
      -        }
      -
      -        @Specialization
      -        static Object doL(long self,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createTuple(new Object[]{factory.createInt(self)});
      -        }
      -
      -        @Specialization
      -        static Object getPI(PInt self,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createTuple(new Object[]{factory.createInt(self.getValue())});
      +        static Object doI(Object self,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Cached PyLongCopy copy) {
      +            return PFactory.createTuple(language, new Object[]{copy.execute(inliningTarget, self)});
               }
           }
       
           @Slot(value = SlotKind.nb_float, isComplex = true)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           public abstract static class FloatNode extends PythonUnaryBuiltinNode {
               @Specialization
               static double doBoolean(boolean self) {
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/IntNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/IntNodes.java
      index 8f2ce4b2fb..4cd53ffff2 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/IntNodes.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/IntNodes.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -45,9 +45,10 @@
       
       import java.math.BigInteger;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.NumericSupport;
       import com.oracle.graal.python.util.OverflowException;
       import com.oracle.truffle.api.dsl.Cached;
      @@ -149,26 +150,26 @@ static byte[] doPrimitive(long value, int size, boolean bigEndian,
       
               @Specialization
               static byte[] doArbitraryBytesLong(Node inliningTarget, long value, int size, boolean bigEndian,
      -                        @Shared("raiseNode") @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared("raiseNode") @Cached PRaiseNode raiseNode) {
                   final byte[] bytes = new byte[size];
                   NumericSupport support = bigEndian ? NumericSupport.bigEndian() : NumericSupport.littleEndian();
                   try {
                       support.putBigInteger(bytes, 0, PInt.longToBigInteger(value), size);
                   } catch (OverflowException oe) {
      -                throw raiseNode.get(inliningTarget).raise(OverflowError, TOO_LARGE_TO_CONVERT, "int");
      +                throw raiseNode.raise(inliningTarget, OverflowError, TOO_LARGE_TO_CONVERT, "int");
                   }
                   return bytes;
               }
       
               @Specialization
               static byte[] doPInt(Node inliningTarget, PInt value, int size, boolean bigEndian,
      -                        @Shared("raiseNode") @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared("raiseNode") @Cached PRaiseNode raiseNode) {
                   final byte[] bytes = new byte[size];
                   NumericSupport support = bigEndian ? NumericSupport.bigEndian() : NumericSupport.littleEndian();
                   try {
                       support.putBigInteger(bytes, 0, value.getValue(), size);
                   } catch (OverflowException oe) {
      -                throw raiseNode.get(inliningTarget).raise(OverflowError, TOO_LARGE_TO_CONVERT, "int");
      +                throw raiseNode.raise(inliningTarget, OverflowError, TOO_LARGE_TO_CONVERT, "int");
                   }
                   return bytes;
               }
      @@ -197,8 +198,7 @@ static Object doOther(Node inliningTarget, byte[] data, boolean littleEndian, bo
                               @Cached InlinedBranchProfile fastPath4,
                               @Cached InlinedBranchProfile fastPath8,
                               @Cached InlinedBranchProfile generic,
      -                        @Cached(inline = false) PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   NumericSupport support = littleEndian ? NumericSupport.littleEndian() : NumericSupport.bigEndian();
                   if (signed) {
                       switch (data.length) {
      @@ -227,10 +227,10 @@ static Object doOther(Node inliningTarget, byte[] data, boolean littleEndian, bo
                           long longValue = PInt.longValue(integer);
                           return PInt.isIntRange(longValue) ? (int) longValue : longValue;
                       } else {
      -                    return factory.createInt(integer);
      +                    return PFactory.createInt(PythonLanguage.get(inliningTarget), integer);
                       }
                   } catch (OverflowException e) {
      -                throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.BYTE_ARRAY_TOO_LONG_TO_CONVERT_TO_INT);
      +                throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.BYTE_ARRAY_TOO_LONG_TO_CONVERT_TO_INT);
                   }
               }
           }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/PInt.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/PInt.java
      index 6bf68bcc18..1b8e62a498 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/PInt.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/PInt.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2017, 2024, Oracle and/or its affiliates.
      + * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
        * Copyright (c) 2013, Regents of the University of California
        *
        * All rights reserved.
      @@ -30,6 +30,7 @@
       import java.math.BigInteger;
       import java.util.Objects;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.modules.SysModuleBuiltins;
       import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
      @@ -37,7 +38,7 @@
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.runtime.PythonContext;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.OverflowException;
       import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
      @@ -402,7 +403,7 @@ public double doubleValueWithOverflow(Node raisingNode) {
           public static double doubleValueWithOverflow(Node raisingNode, BigInteger value) {
               double d = value.doubleValue();
               if (Double.isInfinite(d)) {
      -            throw PRaiseNode.raiseUncached(raisingNode, OverflowError, ErrorMessages.INT_TOO_LARGE_TO_CONVERT_TO_FLOAT);
      +            throw PRaiseNode.raiseStatic(raisingNode, OverflowError, ErrorMessages.INT_TOO_LARGE_TO_CONVERT_TO_FLOAT);
               }
               return d;
           }
      @@ -604,7 +605,7 @@ public static int long2int(Node inliningTarget, long size, InlinedBranchProfile
               int intSize = (int) size;
               if (intSize != size) {
                   errorProfile.enter(inliningTarget);
      -            throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.OverflowError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, size);
      +            throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.OverflowError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, size);
               }
               return intSize;
           }
      @@ -616,9 +617,9 @@ public static Object abs(int v) {
               return Math.abs(v);
           }
       
      -    public static Object abs(Node inliningTarget, long v, PythonObjectFactory.Lazy factory) {
      +    public static Object abs(Node inliningTarget, long v) {
               if (v == Long.MIN_VALUE) {
      -            return factory.get(inliningTarget).createInt(abs(PInt.longToBigInteger(v)));
      +            return PFactory.createInt(PythonLanguage.get(inliningTarget), abs(PInt.longToBigInteger(v)));
               }
               return Math.abs(v);
           }
      @@ -688,15 +689,14 @@ private boolean fitsIn(BigInteger left, BigInteger right) {
            * Creates a Python {@code int} object from a Java {@code long} value by interpreting it as an
            * unsigned number.
            *
      -     * @param factory Python object factory
            * @param profile condition profile for the case when the unsigned value fits into Java
            *            {@code long}
            * @param value the value
            * @return either {@code Long} or {@code PInt} containing an unsigned value with bit pattern
            *         matching that of {@code value}
            */
      -    public static Object createPythonIntFromUnsignedLong(Node inliningTarget, PythonObjectFactory factory, InlinedConditionProfile profile, long value) {
      -        return profile.profile(inliningTarget, value >= 0) ? value : factory.createInt(longToUnsignedBigInt(value));
      +    public static Object createPythonIntFromUnsignedLong(Node inliningTarget, PythonLanguage language, InlinedConditionProfile profile, long value) {
      +        return profile.profile(inliningTarget, value >= 0) ? value : PFactory.createInt(language, longToUnsignedBigInt(value));
           }
       
           @TruffleBoundary
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorBuiltins.java
      index d8cc41b9e0..39619733d0 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, Oracle and/or its affiliates.
      + * Copyright (c) 2024, 2025, Oracle and/or its affiliates.
        * Copyright (c) 2014, Regents of the University of California
        *
        * All rights reserved.
      @@ -29,9 +29,7 @@
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
       import static com.oracle.graal.python.nodes.BuiltinNames.T_ITER;
       import static com.oracle.graal.python.nodes.ErrorMessages.DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LENGTH_HINT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__;
       import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING;
      @@ -40,6 +38,9 @@
       import java.math.BigInteger;
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -61,6 +62,8 @@
       import com.oracle.graal.python.builtins.objects.list.PList;
       import com.oracle.graal.python.builtins.objects.module.PythonModule;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
       import com.oracle.graal.python.lib.PyNumberAsSizeNode;
       import com.oracle.graal.python.lib.PyObjectGetAttr;
       import com.oracle.graal.python.lib.PyObjectSizeNode;
      @@ -78,7 +81,7 @@
       import com.oracle.graal.python.runtime.GilNode;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
       import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
      @@ -114,20 +117,22 @@ public final class IteratorBuiltins extends PythonBuiltins {
            * class.
            */
       
      +    public static final TpSlots SLOTS = IteratorBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return IteratorBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
       
               @Specialization
               static Object exhausted(VirtualFrame frame, Object self,
                               @Bind("this") Node inliningTarget,
                               @Cached NextHelperNode nextHelperNode) {
      -            return nextHelperNode.execute(frame, inliningTarget, self, true);
      +            return nextHelperNode.execute(frame, inliningTarget, self);
               }
           }
       
      @@ -135,154 +140,125 @@ static Object exhausted(VirtualFrame frame, Object self,
           @GenerateCached(false)
           public abstract static class NextHelperNode extends PNodeWithContext {
       
      -        public static final Object STOP_MARKER = new Object();
      -
      -        public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object iterator, boolean throwStopIteration);
      +        public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object iterator);
       
      -        private static Object stopIteration(Node inliningTarget, PBuiltinIterator self, boolean throwStopIteration, PRaiseNode.Lazy raiseNode) {
      +        private static Object stopIteration(PBuiltinIterator self) {
                   self.setExhausted();
      -            if (throwStopIteration) {
      -                throw raiseNode.get(inliningTarget).raiseStopIteration();
      -            } else {
      -                return STOP_MARKER;
      -            }
      -        }
      -
      -        private static Object stopIterationForeign(Node inliningTarget, boolean throwStopIteration, PRaiseNode.Lazy raiseNode) {
      -            if (throwStopIteration) {
      -                throw raiseNode.get(inliningTarget).raiseStopIteration();
      -            } else {
      -                return STOP_MARKER;
      -            }
      +            throw TpIterNextBuiltin.iteratorExhausted();
               }
       
               @Specialization(guards = "self.isExhausted()")
      -        static Object exhausted(Node inliningTarget, @SuppressWarnings("unused") PBuiltinIterator self, boolean throwStopIteration,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      -            if (throwStopIteration) {
      -                throw raiseNode.get(inliningTarget).raiseStopIteration();
      -            } else {
      -                return STOP_MARKER;
      -            }
      +        static Object exhausted(@SuppressWarnings("unused") PBuiltinIterator self) {
      +            throw TpIterNextBuiltin.iteratorExhausted();
               }
       
               @Specialization(guards = "!self.isExhausted()")
      -        static Object next(Node inliningTarget, PArrayIterator self, boolean throwStopIteration,
      +        static Object next(Node inliningTarget, PArrayIterator self,
                               @Cached InlinedExactClassProfile itemTypeProfile,
      -                        @Cached ArrayNodes.GetValueNode getValueNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached ArrayNodes.GetValueNode getValueNode) {
                   PArray array = self.array;
                   if (self.getIndex() < array.getLength()) {
                       return itemTypeProfile.profile(inliningTarget, getValueNode.execute(inliningTarget, array, self.index++));
                   }
      -            return stopIteration(inliningTarget, self, throwStopIteration, raiseNode);
      +            return stopIteration(self);
               }
       
               @Specialization(guards = "!self.isExhausted()")
      -        static Object next(Node inliningTarget, PIntegerSequenceIterator self, boolean throwStopIteration,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +        static Object next(PIntegerSequenceIterator self) {
                   if (self.getIndex() < self.sequence.length()) {
                       return self.sequence.getIntItemNormalized(self.index++);
                   }
      -            return stopIteration(inliningTarget, self, throwStopIteration, raiseNode);
      +            return stopIteration(self);
               }
       
               @Specialization(guards = "!self.isExhausted()")
      -        static Object next(Node inliningTarget, PObjectSequenceIterator self, boolean throwStopIteration,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +        static Object next(PObjectSequenceIterator self) {
                   if (self.getIndex() < self.sequence.length()) {
                       return self.sequence.getObjectItemNormalized(self.index++);
                   }
      -            return stopIteration(inliningTarget, self, throwStopIteration, raiseNode);
      +            return stopIteration(self);
               }
       
               @Specialization(guards = "!self.isExhausted()")
      -        static Object next(Node inliningTarget, PIntRangeIterator self, boolean throwStopIteration,
      -                        @Exclusive @Cached InlinedConditionProfile profile,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +        static Object next(Node inliningTarget, PIntRangeIterator self,
      +                        @Exclusive @Cached InlinedConditionProfile profile) {
                   if (profile.profile(inliningTarget, self.hasNextInt())) {
                       return self.nextInt();
                   }
      -            return stopIteration(inliningTarget, self, throwStopIteration, raiseNode);
      +            return stopIteration(self);
               }
       
               @Specialization(guards = "!self.isExhausted()")
      -        static Object next(Node inliningTarget, PBigRangeIterator self, boolean throwStopIteration,
      -                        @Cached PythonObjectFactory.Lazy factory,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +        static Object next(PBigRangeIterator self,
      +                        @Bind PythonLanguage language) {
                   if (self.hasNextBigInt()) {
      -                return factory.get(inliningTarget).createInt(self.nextBigInt());
      +                return PFactory.createInt(language, self.nextBigInt());
                   }
      -            return stopIteration(inliningTarget, self, throwStopIteration, raiseNode);
      +            return stopIteration(self);
               }
       
               @Specialization(guards = "!self.isExhausted()")
      -        static Object next(Node inliningTarget, PDoubleSequenceIterator self, boolean throwStopIteration,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +        static Object next(PDoubleSequenceIterator self) {
                   if (self.getIndex() < self.sequence.length()) {
                       return self.sequence.getDoubleItemNormalized(self.index++);
                   }
      -            return stopIteration(inliningTarget, self, throwStopIteration, raiseNode);
      +            return stopIteration(self);
               }
       
               @Specialization(guards = "!self.isExhausted()")
      -        static Object next(Node inliningTarget, PLongSequenceIterator self, boolean throwStopIteration,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +        static Object next(PLongSequenceIterator self) {
                   if (self.getIndex() < self.sequence.length()) {
                       return self.sequence.getLongItemNormalized(self.index++);
                   }
      -            return stopIteration(inliningTarget, self, throwStopIteration, raiseNode);
      +            return stopIteration(self);
               }
       
               @Specialization(guards = "!self.isExhausted()")
      -        static Object next(Node inliningTarget, PStringIterator self, boolean throwStopIteration,
      +        static Object next(PStringIterator self,
                               @Cached(inline = false) TruffleString.CodePointLengthNode codePointLengthNode,
      -                        @Cached(inline = false) TruffleString.SubstringNode substringNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached(inline = false) TruffleString.SubstringNode substringNode) {
                   if (self.getIndex() < codePointLengthNode.execute(self.value, TS_ENCODING)) {
                       return substringNode.execute(self.value, self.index++, 1, TS_ENCODING, false);
                   }
      -            return stopIteration(inliningTarget, self, throwStopIteration, raiseNode);
      +            return stopIteration(self);
               }
       
               @Specialization(guards = "!self.isExhausted()")
      -        static Object nextHashingStorageIter(Node inliningTarget, PHashingStorageIterator self, boolean throwStopIteration,
      +        static Object nextHashingStorageIter(Node inliningTarget, PHashingStorageIterator self,
                               @Exclusive @Cached InlinedConditionProfile sizeChanged,
                               @Cached HashingStorageLen lenNode,
                               @Cached HashingStorageIteratorNext nextNode,
                               @Cached PHashingStorageIteratorNextValue itValueNode,
                               @Exclusive @Cached InlinedConditionProfile profile,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   HashingStorage storage = self.getHashingStorage();
                   final HashingStorageIterator it = self.getIterator();
                   if (profile.profile(inliningTarget, nextNode.execute(inliningTarget, storage, it))) {
                       if (sizeChanged.profile(inliningTarget, self.checkSizeChanged(inliningTarget, lenNode))) {
                           String name = PBaseSetIterator.isInstance(self) ? "Set" : "dictionary";
      -                    throw raiseNode.get(inliningTarget).raise(RuntimeError, ErrorMessages.CHANGED_SIZE_DURING_ITERATION, name);
      +                    throw raiseNode.raise(inliningTarget, RuntimeError, ErrorMessages.CHANGED_SIZE_DURING_ITERATION, name);
                       }
                       self.index++;
                       return itValueNode.execute(inliningTarget, self, storage, it);
                   }
      -            return stopIteration(inliningTarget, self, throwStopIteration, raiseNode);
      +            return stopIteration(self);
               }
       
               @Specialization(guards = {"!self.isExhausted()", "self.isPSequence()"})
      -        static Object next(Node inliningTarget, PSequenceIterator self, boolean throwStopIteration,
      +        static Object next(Node inliningTarget, PSequenceIterator self,
                               @Cached SequenceNodes.GetSequenceStorageNode getStorage,
      -                        @Cached(value = "createNotNormalized()", inline = false) SequenceStorageNodes.GetItemNode getItemNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached(value = "createNotNormalized()", inline = false) SequenceStorageNodes.GetItemNode getItemNode) {
                   SequenceStorage s = getStorage.execute(inliningTarget, self.getPSequence());
                   if (self.getIndex() < s.length()) {
                       return getItemNode.execute(s, self.index++);
                   }
      -            return stopIteration(inliningTarget, self, throwStopIteration, raiseNode);
      +            return stopIteration(self);
               }
       
               @Specialization(guards = {"!self.isExhausted()", "!self.isPSequence()"})
      -        static Object next(VirtualFrame frame, Node inliningTarget, PSequenceIterator self, boolean throwStopIteration,
      +        static Object next(VirtualFrame frame, Node inliningTarget, PSequenceIterator self,
                               @Cached(inline = false) PySequenceGetItemNode getItem,
      -                        @Cached IsBuiltinObjectProfile profile,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached IsBuiltinObjectProfile profile) {
                   try {
                       /*
                        * This must use PySequence_GetItem and not any other get item nodes. The reason is
      @@ -294,24 +270,23 @@ static Object next(VirtualFrame frame, Node inliningTarget, PSequenceIterator se
                       return getItem.execute(frame, self.getObject(), self.index++);
                   } catch (PException e) {
                       e.expectIndexError(inliningTarget, profile);
      -                return stopIteration(inliningTarget, self, throwStopIteration, raiseNode);
      +                return stopIteration(self);
                   }
               }
       
               @Specialization(guards = {"isForeignObjectNode.execute(inliningTarget, self)", "interop.isIterator(self)"}, limit = "1")
      -        static Object foreign(Node inliningTarget, Object self, boolean throwStopIteration,
      -                        @Cached IsForeignObjectNode isForeignObjectNode,
      +        static Object foreign(@SuppressWarnings("unused") Node inliningTarget, Object self,
      +                        @SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode,
                               @CachedLibrary(limit = "getCallSiteInlineCacheMaxDepth()") InteropLibrary interop,
                               @Cached(inline = false) GilNode gil,
      -                        @Cached(inline = false) PForeignToPTypeNode toPythonNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached(inline = false) PForeignToPTypeNode toPythonNode) {
                   final Object element;
       
                   gil.release(true);
                   try {
                       element = interop.getIteratorNextElement(self);
                   } catch (StopIterationException e) {
      -                return stopIterationForeign(inliningTarget, throwStopIteration, raiseNode);
      +                throw TpIterNextBuiltin.iteratorExhausted();
                   } catch (UnsupportedMessageException e) {
                       throw CompilerDirectives.shouldNotReachHere("iterator claimed to be iterator but wasn't");
                   } finally {
      @@ -340,10 +315,10 @@ static Object doDictKey(Node inliningTarget, @SuppressWarnings("unused") PDictVi
       
                   @Specialization
                   static PTuple doDictItem(Node inliningTarget, @SuppressWarnings("unused") PDictView.PDictItemIterator self, HashingStorage storage, HashingStorageIterator it,
      +                            @Bind PythonLanguage language,
                                   @Shared("val") @Cached HashingStorageIteratorValue itValueNode,
      -                            @Shared("key") @Cached HashingStorageIteratorKey itKeyNode,
      -                            @Cached(inline = false) PythonObjectFactory factory) {
      -                return factory.createTuple(new Object[]{itKeyNode.execute(inliningTarget, storage, it), itValueNode.execute(inliningTarget, storage, it)});
      +                            @Shared("key") @Cached HashingStorageIteratorKey itKeyNode) {
      +                return PFactory.createTuple(language, new Object[]{itKeyNode.execute(inliningTarget, storage, it), itValueNode.execute(inliningTarget, storage, it)});
                   }
       
                   @Specialization
      @@ -354,7 +329,7 @@ static Object doSetKey(Node inliningTarget, @SuppressWarnings("unused") PBaseSet
               }
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -407,8 +382,8 @@ static int lengthHint(PIntRangeIterator self) {
       
               @Specialization(guards = "!self.isExhausted()")
               static Object lengthHint(PBigRangeIterator self,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createInt(self.getRemainingLength());
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, self.getRemainingLength());
               }
       
               @Specialization(guards = "!self.isExhausted()")
      @@ -482,142 +457,138 @@ static int foreign(Object self,
           public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
       
               @Specialization
      -        Object reduce(VirtualFrame frame, PArrayIterator self,
      +        static Object reduce(VirtualFrame frame, PArrayIterator self,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonContext context,
                               @Shared @Cached InlinedConditionProfile exhaustedProfile,
      -                        @Shared @Cached PyObjectGetAttr getAttrNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            PythonContext context = PythonContext.get(this);
      +                        @Shared @Cached PyObjectGetAttr getAttrNode) {
                   if (!exhaustedProfile.profile(inliningTarget, self.isExhausted())) {
      -                return reduceInternal(frame, inliningTarget, self.array, self.getIndex(), context, getAttrNode, factory);
      +                return reduceInternal(frame, inliningTarget, self.array, self.getIndex(), context, getAttrNode);
                   } else {
      -                return reduceInternal(frame, inliningTarget, factory.createEmptyTuple(), context, getAttrNode, factory);
      +                return reduceInternal(frame, inliningTarget, PFactory.createEmptyTuple(context.getLanguage(inliningTarget)), context, getAttrNode);
                   }
               }
       
               @Specialization
      -        Object reduce(VirtualFrame frame, PHashingStorageIterator self,
      +        static Object reduce(VirtualFrame frame, PHashingStorageIterator self,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonContext context,
                               @Cached SequenceStorageNodes.CreateStorageFromIteratorNode storageNode,
                               // unused profile to avoid mixing shared and non-shared inlined nodes
                               @SuppressWarnings("unused") @Shared @Cached InlinedConditionProfile exhaustedProfile,
      -                        @Shared @Cached PyObjectGetAttr getAttrNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Shared @Cached PyObjectGetAttr getAttrNode) {
                   int index = self.index;
                   boolean isExhausted = self.isExhausted();
                   int state = self.getIterator().getState();
      -            PList list = factory.createList(storageNode.execute(frame, self));
      +            PList list = PFactory.createList(context.getLanguage(inliningTarget), storageNode.execute(frame, self));
                   self.getIterator().setState(state);
                   self.setExhausted(isExhausted);
                   self.index = index;
      -            return reduceInternal(frame, inliningTarget, list, PythonContext.get(this), getAttrNode, factory);
      +            return reduceInternal(frame, inliningTarget, list, context, getAttrNode);
               }
       
               @Specialization
      -        Object reduce(VirtualFrame frame, PIntegerSequenceIterator self,
      +        static Object reduce(VirtualFrame frame, PIntegerSequenceIterator self,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PyObjectGetAttr getAttrNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            PythonContext context = PythonContext.get(this);
      +                        @Bind PythonContext context,
      +                        @Shared @Cached PyObjectGetAttr getAttrNode) {
                   if (self.isExhausted()) {
      -                return reduceInternal(frame, inliningTarget, factory.createList(), null, context, getAttrNode, factory);
      +                return reduceInternal(frame, inliningTarget, PFactory.createList(context.getLanguage(inliningTarget)), null, context, getAttrNode);
                   }
      -            return reduceInternal(frame, inliningTarget, self.getObject(), self.getIndex(), context, getAttrNode, factory);
      +            return reduceInternal(frame, inliningTarget, self.getObject(), self.getIndex(), context, getAttrNode);
               }
       
               @Specialization
      -        Object reduce(VirtualFrame frame, PPrimitiveIterator self,
      +        static Object reduce(VirtualFrame frame, PPrimitiveIterator self,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PyObjectGetAttr getAttrNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            PythonContext context = PythonContext.get(this);
      +                        @Bind PythonContext context,
      +                        @Shared @Cached PyObjectGetAttr getAttrNode) {
                   if (self.isExhausted()) {
      -                return reduceInternal(frame, inliningTarget, factory.createList(), null, context, getAttrNode, factory);
      +                return reduceInternal(frame, inliningTarget, PFactory.createList(context.getLanguage(inliningTarget)), null, context, getAttrNode);
                   }
      -            return reduceInternal(frame, inliningTarget, self.getObject(), self.getIndex(), context, getAttrNode, factory);
      +            return reduceInternal(frame, inliningTarget, self.getObject(), self.getIndex(), context, getAttrNode);
               }
       
               @Specialization
      -        Object reduce(VirtualFrame frame, PStringIterator self,
      +        static Object reduce(VirtualFrame frame, PStringIterator self,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PyObjectGetAttr getAttrNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            PythonContext context = PythonContext.get(this);
      +                        @Bind PythonContext context,
      +                        @Shared @Cached PyObjectGetAttr getAttrNode) {
                   if (self.isExhausted()) {
      -                return reduceInternal(frame, inliningTarget, T_EMPTY_STRING, null, context, getAttrNode, factory);
      +                return reduceInternal(frame, inliningTarget, T_EMPTY_STRING, null, context, getAttrNode);
                   }
      -            return reduceInternal(frame, inliningTarget, self.value, self.getIndex(), context, getAttrNode, factory);
      +            return reduceInternal(frame, inliningTarget, self.value, self.getIndex(), context, getAttrNode);
               }
       
               @Specialization
      -        Object reduce(VirtualFrame frame, PIntRangeIterator self,
      +        static Object reduce(VirtualFrame frame, PIntRangeIterator self,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PyObjectGetAttr getAttrNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonContext context,
      +                        @Shared @Cached PyObjectGetAttr getAttrNode) {
                   int start = self.getStart();
                   int stop = self.getStop();
                   int step = self.getStep();
                   int len = self.getLen();
      -            return reduceInternal(frame, inliningTarget, factory.createIntRange(start, stop, step, len), self.getIndex(), PythonContext.get(this), getAttrNode, factory);
      +            PythonLanguage language = context.getLanguage(inliningTarget);
      +            return reduceInternal(frame, inliningTarget, PFactory.createIntRange(language, start, stop, step, len), self.getIndex(), context, getAttrNode);
               }
       
               @Specialization
      -        Object reduce(VirtualFrame frame, PBigRangeIterator self,
      +        static Object reduce(VirtualFrame frame, PBigRangeIterator self,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PyObjectGetAttr getAttrNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonContext context,
      +                        @Shared @Cached PyObjectGetAttr getAttrNode) {
                   PInt start = self.getStart();
                   PInt stop = self.getStop();
                   PInt step = self.getStep();
                   PInt len = self.getLen();
      -            return reduceInternal(frame, inliningTarget, factory.createBigRange(start, stop, step, len), self.getLongIndex(factory), PythonContext.get(this), getAttrNode, factory);
      +            PythonLanguage language = context.getLanguage(inliningTarget);
      +            return reduceInternal(frame, inliningTarget, PFactory.createBigRange(language, start, stop, step, len), self.getLongIndex(language), context, getAttrNode);
               }
       
               @Specialization(guards = "self.isPSequence()")
      -        Object reduce(VirtualFrame frame, PSequenceIterator self,
      +        static Object reduce(VirtualFrame frame, PSequenceIterator self,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PyObjectGetAttr getAttrNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            PythonContext context = PythonContext.get(this);
      +                        @Bind PythonContext context,
      +                        @Shared @Cached PyObjectGetAttr getAttrNode) {
                   if (self.isExhausted()) {
      -                return reduceInternal(frame, inliningTarget, factory.createTuple(new Object[0]), null, context, getAttrNode, factory);
      +                return reduceInternal(frame, inliningTarget, PFactory.createTuple(context.getLanguage(inliningTarget), new Object[0]), null, context, getAttrNode);
                   }
      -            return reduceInternal(frame, inliningTarget, self.getPSequence(), self.getIndex(), context, getAttrNode, factory);
      +            return reduceInternal(frame, inliningTarget, self.getPSequence(), self.getIndex(), context, getAttrNode);
               }
       
               @Specialization(guards = "!self.isPSequence()")
      -        Object reduceNonSeq(@SuppressWarnings({"unused"}) VirtualFrame frame, PSequenceIterator self,
      +        static Object reduceNonSeq(@SuppressWarnings({"unused"}) VirtualFrame frame, PSequenceIterator self,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PyObjectGetAttr getAttrNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            PythonContext context = PythonContext.get(this);
      +                        @Bind PythonContext context,
      +                        @Shared @Cached PyObjectGetAttr getAttrNode) {
                   if (!self.isExhausted()) {
      -                return reduceInternal(frame, inliningTarget, self.getObject(), self.getIndex(), context, getAttrNode, factory);
      +                return reduceInternal(frame, inliningTarget, self.getObject(), self.getIndex(), context, getAttrNode);
                   } else {
      -                return reduceInternal(frame, inliningTarget, factory.createTuple(new Object[0]), null, context, getAttrNode, factory);
      +                return reduceInternal(frame, inliningTarget, PFactory.createTuple(context.getLanguage(inliningTarget), new Object[0]), null, context, getAttrNode);
                   }
               }
       
               @Fallback
               static int other(Object self,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      -            throw raiseNode.get(inliningTarget).raise(TypeError, DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P, "iterator", self);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P, "iterator", self);
               }
       
      -        private static PTuple reduceInternal(VirtualFrame frame, Node inliningTarget, Object arg, PythonContext context, PyObjectGetAttr getAttrNode, PythonObjectFactory factory) {
      -            return reduceInternal(frame, inliningTarget, arg, null, context, getAttrNode, factory);
      +        private static PTuple reduceInternal(VirtualFrame frame, Node inliningTarget, Object arg, PythonContext context, PyObjectGetAttr getAttrNode) {
      +            return reduceInternal(frame, inliningTarget, arg, null, context, getAttrNode);
               }
       
      -        private static PTuple reduceInternal(VirtualFrame frame, Node inliningTarget, Object arg, Object state, PythonContext context, PyObjectGetAttr getAttrNode, PythonObjectFactory factory) {
      +        private static PTuple reduceInternal(VirtualFrame frame, Node inliningTarget, Object arg, Object state, PythonContext context, PyObjectGetAttr getAttrNode) {
                   PythonModule builtins = context.getBuiltins();
      +            PythonLanguage language = context.getLanguage(inliningTarget);
                   Object iter = getAttrNode.execute(frame, inliningTarget, builtins, T_ITER);
      -            PTuple args = factory.createTuple(new Object[]{arg});
      +            PTuple args = PFactory.createTuple(language, new Object[]{arg});
                   // callable, args, state (optional)
                   if (state != null) {
      -                return factory.createTuple(new Object[]{iter, args, state});
      +                return PFactory.createTuple(language, new Object[]{iter, args, state});
                   } else {
      -                return factory.createTuple(new Object[]{iter, args});
      +                return PFactory.createTuple(language, new Object[]{iter, args});
                   }
               }
           }
      @@ -652,9 +623,8 @@ static Object setstate(VirtualFrame frame, PBuiltinIterator self, Object index,
       
               @Fallback
               static Object other(Object self, Object index,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      -            throw raiseNode.get(inliningTarget).raise(TypeError, DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P, "iterator", self);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P, "iterator", self);
               }
       
               protected static boolean isPBigRangeIterator(Object obj) {
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorNodes.java
      index 00f0bb40e7..d7563f4347 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorNodes.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorNodes.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -61,12 +61,12 @@
       import com.oracle.graal.python.builtins.objects.str.PString;
       import com.oracle.graal.python.builtins.objects.str.StringNodes;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.CallSlotLenNode;
      -import com.oracle.graal.python.lib.GetNextNode;
      +import com.oracle.graal.python.lib.IteratorExhausted;
       import com.oracle.graal.python.lib.PyIndexCheckNode;
      +import com.oracle.graal.python.lib.PyIterNextNode;
       import com.oracle.graal.python.lib.PyNumberAsSizeNode;
       import com.oracle.graal.python.lib.PyObjectGetIter;
       import com.oracle.graal.python.nodes.ErrorMessages;
      @@ -75,7 +75,7 @@
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.SpecialMethodNames;
       import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode;
      -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode;
      +import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodNode;
       import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode;
      @@ -111,7 +111,7 @@ public abstract class IteratorNodes {
            */
           @GenerateInline
           @GenerateCached(false)
      -    @ImportStatic({PGuards.class, SpecialMethodNames.class, SpecialMethodSlot.class})
      +    @ImportStatic({PGuards.class, SpecialMethodNames.class})
           public abstract static class GetLength extends PNodeWithContext {
       
               public abstract int execute(VirtualFrame frame, Node inliningTarget, Object iterable);
      @@ -171,13 +171,13 @@ static int length(VirtualFrame frame, Node inliningTarget, Object iterable,
                               @Cached GetCachedTpSlotsNode getSlotsNode,
                               @Cached PyIndexCheckNode indexCheckNode,
                               @Cached PyNumberAsSizeNode asSizeNode,
      -                        @Cached(value = "create(LengthHint)", inline = false) LookupSpecialMethodSlotNode lenHintNode,
      +                        @Cached LookupSpecialMethodNode.Dynamic lenHintNode,
                               @Cached CallSlotLenNode callSlotLenNode,
                               @Cached(inline = false) CallUnaryMethodNode dispatchLenOrLenHint,
                               @Cached IsBuiltinObjectProfile errorProfile,
                               @Cached InlinedConditionProfile hasLenProfile,
                               @Cached InlinedConditionProfile hasLengthHintProfile,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object clazz = getClassNode.execute(inliningTarget, iterable);
                   TpSlots slots = getSlotsNode.execute(inliningTarget, clazz);
                   if (hasLenProfile.profile(inliningTarget, slots.combined_sq_mp_length() != null)) {
      @@ -190,9 +190,7 @@ static int length(VirtualFrame frame, Node inliningTarget, Object iterable,
                           e.expect(inliningTarget, TypeError, errorProfile);
                       }
                   }
      -            // TODO: __len_hint__ is not a slot, but it is resolved using _PyObject_LookupSpecial,
      -            // so looked up only on type, so we can cache it in slots
      -            Object attrLenHintObj = lenHintNode.execute(frame, clazz, iterable);
      +            Object attrLenHintObj = lenHintNode.execute(frame, inliningTarget, clazz, T___LENGTH_HINT__, iterable);
                   if (hasLengthHintProfile.profile(inliningTarget, attrLenHintObj != PNone.NO_VALUE)) {
                       Object len = null;
                       try {
      @@ -204,11 +202,11 @@ static int length(VirtualFrame frame, Node inliningTarget, Object iterable,
                           if (indexCheckNode.execute(inliningTarget, len)) {
                               int intLen = asSizeNode.executeExact(frame, inliningTarget, len);
                               if (intLen < 0) {
      -                            throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.LENGTH_HINT_SHOULD_RETURN_MT_ZERO);
      +                            throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.LENGTH_HINT_SHOULD_RETURN_MT_ZERO);
                               }
                               return intLen;
                           } else {
      -                        throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MUST_BE_INTEGER_NOT_P, T___LENGTH_HINT__, len);
      +                        throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_INTEGER_NOT_P, T___LENGTH_HINT__, len);
                           }
                       }
                   }
      @@ -367,19 +365,19 @@ public static Object[] doIt(PSequence iterable,
               @Fallback
               public static Object[] doIt(VirtualFrame frame, Object iterable,
                               @Bind("this") Node inliningTarget,
      -                        @Cached GetNextNode getNextNode,
      -                        @Cached IsBuiltinObjectProfile stopIterationProfile,
      -                        @Cached PyObjectGetIter getIter) {
      +                        @Cached PyObjectGetIter getIter,
      +                        @Cached PyIterNextNode nextNode) {
                   Object it = getIter.execute(frame, inliningTarget, iterable);
                   List result = createlist();
                   while (true) {
                       try {
      -                    result.add(getNextNode.execute(frame, it));
      -                } catch (PException e) {
      -                    e.expectStopIteration(inliningTarget, stopIterationProfile);
      -                    return result.toArray(new Object[result.size()]);
      +                    Object next = nextNode.execute(frame, inliningTarget, it);
      +                    result.add(next);
      +                } catch (IteratorExhausted e) {
      +                    break;
                       }
                   }
      +            return result.toArray(new Object[result.size()]);
               }
       
               @TruffleBoundary
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/PBigRangeIterator.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/PBigRangeIterator.java
      index b5272521dc..21a3cff0ba 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/PBigRangeIterator.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/PBigRangeIterator.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -42,8 +42,9 @@
       
       import java.math.BigInteger;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.builtins.objects.ints.PInt;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.object.Shape;
       
      @@ -98,8 +99,8 @@ public PInt getLen() {
               return len;
           }
       
      -    public PInt getLongIndex(PythonObjectFactory factory) {
      -        return factory.createInt(longIndex);
      +    public PInt getLongIndex(PythonLanguage language) {
      +        return PFactory.createInt(language, longIndex);
           }
       
           public void setLongIndex(BigInteger idx) {
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/PZipBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/PZipBuiltins.java
      deleted file mode 100644
      index 8c2edd1b59..0000000000
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/PZipBuiltins.java
      +++ /dev/null
      @@ -1,162 +0,0 @@
      -/*
      - * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
      - * Copyright (c) 2014, Regents of the University of California
      - *
      - * All rights reserved.
      - *
      - * Redistribution and use in source and binary forms, with or without modification, are
      - * permitted provided that the following conditions are met:
      - *
      - * 1. Redistributions of source code must retain the above copyright notice, this list of
      - * conditions and the following disclaimer.
      - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
      - * conditions and the following disclaimer in the documentation and/or other materials provided
      - * with the distribution.
      - *
      - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
      - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
      - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
      - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
      - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
      - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
      - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
      - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      - * OF THE POSSIBILITY OF SUCH DAMAGE.
      - */
      -package com.oracle.graal.python.builtins.objects.iterator;
      -
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__;
      -
      -import java.util.List;
      -
      -import com.oracle.graal.python.builtins.Builtin;
      -import com.oracle.graal.python.builtins.CoreFunctions;
      -import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      -import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.objects.PNone;
      -import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      -import com.oracle.graal.python.lib.GetNextNode;
      -import com.oracle.graal.python.lib.PyObjectIsTrueNode;
      -import com.oracle.graal.python.nodes.ErrorMessages;
      -import com.oracle.graal.python.nodes.PRaiseNode;
      -import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      -import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
      -import com.oracle.graal.python.nodes.object.GetClassNode;
      -import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      -import com.oracle.truffle.api.dsl.Bind;
      -import com.oracle.truffle.api.dsl.Cached;
      -import com.oracle.truffle.api.dsl.Cached.Shared;
      -import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      -import com.oracle.truffle.api.dsl.NodeFactory;
      -import com.oracle.truffle.api.dsl.Specialization;
      -import com.oracle.truffle.api.frame.VirtualFrame;
      -import com.oracle.truffle.api.nodes.Node;
      -import com.oracle.truffle.api.profiles.InlinedConditionProfile;
      -
      -@CoreFunctions(extendClasses = PythonBuiltinClassType.PZip)
      -public final class PZipBuiltins extends PythonBuiltins {
      -
      -    @Override
      -    protected List> getNodeFactories() {
      -        return PZipBuiltinsFactory.getFactories();
      -    }
      -
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      -    @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      -
      -        @Specialization(guards = "isEmpty(self.getIterators())")
      -        static Object doEmpty(@SuppressWarnings("unused") PZip self,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raiseStopIteration();
      -        }
      -
      -        @Specialization(guards = {"!isEmpty(self.getIterators())", "!self.isStrict()"})
      -        static Object doNext(VirtualFrame frame, PZip self,
      -                        @Shared @Cached GetNextNode next,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            Object[] iterators = self.getIterators();
      -            Object[] tupleElements = new Object[iterators.length];
      -            for (int i = 0; i < iterators.length; i++) {
      -                tupleElements[i] = next.execute(frame, iterators[i]);
      -            }
      -            return factory.createTuple(tupleElements);
      -        }
      -
      -        @Specialization(guards = {"!isEmpty(self.getIterators())", "self.isStrict()"})
      -        static Object doNext(VirtualFrame frame, PZip self,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared @Cached GetNextNode next,
      -                        @Cached IsBuiltinObjectProfile classProfile,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      -            Object[] iterators = self.getIterators();
      -            Object[] tupleElements = new Object[iterators.length];
      -            int i = 0;
      -            try {
      -                for (; i < iterators.length; i++) {
      -                    tupleElements[i] = next.execute(frame, iterators[i]);
      -                }
      -                return factory.createTuple(tupleElements);
      -            } catch (PException e) {
      -                e.expectStopIteration(inliningTarget, classProfile);
      -                if (i > 0) {
      -                    throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.ZIP_ARG_D_IS_SHORTER_THEN_ARG_SD, i + 1, i == 1 ? " " : "s 1-", i);
      -                }
      -                for (i = 1; i < iterators.length; i++) {
      -                    try {
      -                        next.execute(frame, iterators[i]);
      -                        throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.ZIP_ARG_D_IS_LONGER_THEN_ARG_SD, i + 1, i == 1 ? " " : "s 1-", i);
      -                    } catch (PException e2) {
      -                        e2.expectStopIteration(inliningTarget, classProfile);
      -                    }
      -                }
      -                throw e;
      -            }
      -        }
      -    }
      -
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      -    @GenerateNodeFactory
      -    public abstract static class IterNode extends PythonUnaryBuiltinNode {
      -
      -        @Specialization
      -        static Object doPZip(PZip self) {
      -            return self;
      -        }
      -    }
      -
      -    @Builtin(name = J___REDUCE__, minNumOfPositionalArgs = 1)
      -    @GenerateNodeFactory
      -    public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
      -
      -        @Specialization
      -        static Object reduce(PZip self,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached InlinedConditionProfile strictProfile,
      -                        @Cached GetClassNode getClass,
      -                        @Cached PythonObjectFactory factory) {
      -            Object type = getClass.execute(inliningTarget, self);
      -            PTuple tuple = factory.createTuple(self.getIterators());
      -            Object[] elements = strictProfile.profile(inliningTarget, self.isStrict()) ? new Object[]{type, tuple, true} : new Object[]{type, tuple};
      -            return factory.createTuple(elements);
      -        }
      -    }
      -
      -    @Builtin(name = J___SETSTATE__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    abstract static class SetStateNode extends PythonBinaryBuiltinNode {
      -        @Specialization
      -        Object doit(VirtualFrame frame, PZip self, Object state,
      -                        @Cached PyObjectIsTrueNode isTrueNode) {
      -            self.setStrict(isTrueNode.execute(frame, state));
      -            return PNone.NONE;
      -        }
      -    }
      -}
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/SentinelIteratorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/SentinelIteratorBuiltins.java
      index 96d3fbb4a8..8f67a0fe2e 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/SentinelIteratorBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/SentinelIteratorBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2017, 2024, Oracle and/or its affiliates.
      + * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
        * Copyright (c) 2013, Regents of the University of California
        *
        * All rights reserved.
      @@ -26,27 +26,29 @@
       package com.oracle.graal.python.builtins.objects.iterator;
       
       import static com.oracle.graal.python.nodes.BuiltinNames.T_ITER;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.module.PythonModule;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
       import com.oracle.graal.python.lib.PyObjectGetAttr;
       import com.oracle.graal.python.lib.PyObjectRichCompareBool;
      -import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.call.CallNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -58,23 +60,24 @@
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PSentinelIterator)
       public final class SentinelIteratorBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = SentinelIteratorBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return SentinelIteratorBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization
               static Object doIterator(VirtualFrame frame, PSentinelIterator iterator,
                               @Bind("this") Node inliningTarget,
                               @Cached CallNode callNode,
                               @Cached IsBuiltinObjectProfile errorProfile,
      -                        @Cached PyObjectRichCompareBool.EqNode eqNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PyObjectRichCompareBool eqNode) {
                   if (iterator.sentinelReached()) {
      -                throw raiseNode.get(inliningTarget).raiseStopIteration();
      +                throw iteratorExhausted();
                   }
                   Object nextValue;
                   try {
      @@ -82,18 +85,18 @@ static Object doIterator(VirtualFrame frame, PSentinelIterator iterator,
                   } catch (PException e) {
                       e.expectStopIteration(inliningTarget, errorProfile);
                       iterator.markSentinelReached();
      -                throw e;
      +                throw iteratorExhausted();
                   }
      -            boolean iteratorDone = eqNode.compare(frame, inliningTarget, nextValue, iterator.getSentinel());
      +            boolean iteratorDone = eqNode.executeEq(frame, inliningTarget, nextValue, iterator.getSentinel());
                   if (iteratorDone) {
                       iterator.markSentinelReached();
      -                throw raiseNode.get(inliningTarget).raiseStopIteration();
      +                throw iteratorExhausted();
                   }
                   return nextValue;
               }
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
       
      @@ -110,16 +113,16 @@ abstract static class ReduceNode extends PythonUnaryBuiltinNode {
               static Object reduce(VirtualFrame frame, PSentinelIterator self,
                               @Bind("this") Node inliningTarget,
                               @Cached PyObjectGetAttr getAttr,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   PythonModule builtins = PythonContext.get(inliningTarget).getBuiltins();
                   Object iter = getAttr.execute(frame, inliningTarget, builtins, T_ITER);
                   Object[] args;
                   if (self.sentinelReached()) {
      -                args = new Object[]{factory.createEmptyTuple()};
      +                args = new Object[]{PFactory.createEmptyTuple(language)};
                   } else {
                       args = new Object[]{self.getCallable(), self.getSentinel()};
                   }
      -            return factory.createTuple(new Object[]{iter, factory.createTuple(args)});
      +            return PFactory.createTuple(language, new Object[]{iter, PFactory.createTuple(language, args)});
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/ZipBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/ZipBuiltins.java
      new file mode 100644
      index 0000000000..b312d55883
      --- /dev/null
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/ZipBuiltins.java
      @@ -0,0 +1,233 @@
      +/*
      + * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
      + * Copyright (c) 2014, Regents of the University of California
      + *
      + * All rights reserved.
      + *
      + * Redistribution and use in source and binary forms, with or without modification, are
      + * permitted provided that the following conditions are met:
      + *
      + * 1. Redistributions of source code must retain the above copyright notice, this list of
      + * conditions and the following disclaimer.
      + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
      + * conditions and the following disclaimer in the documentation and/or other materials provided
      + * with the distribution.
      + *
      + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
      + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
      + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
      + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
      + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
      + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
      + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
      + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      + * OF THE POSSIBILITY OF SUCH DAMAGE.
      + */
      +package com.oracle.graal.python.builtins.objects.iterator;
      +
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_ZIP;
      +import static com.oracle.graal.python.nodes.BuiltinNames.T_ZIP;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__;
      +import static com.oracle.graal.python.nodes.StringLiterals.T_STRICT;
      +import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
      +import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
      +
      +import java.util.List;
      +
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
      +import com.oracle.graal.python.builtins.Builtin;
      +import com.oracle.graal.python.builtins.CoreFunctions;
      +import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      +import com.oracle.graal.python.builtins.PythonBuiltins;
      +import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.function.PKeyword;
      +import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
      +import com.oracle.graal.python.lib.IteratorExhausted;
      +import com.oracle.graal.python.lib.PyIterNextNode;
      +import com.oracle.graal.python.lib.PyObjectGetIter;
      +import com.oracle.graal.python.lib.PyObjectIsTrueNode;
      +import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.PGuards;
      +import com.oracle.graal.python.nodes.PRaiseNode;
      +import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.object.GetClassNode;
      +import com.oracle.graal.python.runtime.object.PFactory;
      +import com.oracle.truffle.api.dsl.Bind;
      +import com.oracle.truffle.api.dsl.Cached;
      +import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      +import com.oracle.truffle.api.dsl.NodeFactory;
      +import com.oracle.truffle.api.dsl.Specialization;
      +import com.oracle.truffle.api.frame.VirtualFrame;
      +import com.oracle.truffle.api.nodes.LoopNode;
      +import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.InlinedConditionProfile;
      +import com.oracle.truffle.api.strings.TruffleString;
      +
      +@CoreFunctions(extendClasses = PythonBuiltinClassType.PZip)
      +public final class ZipBuiltins extends PythonBuiltins {
      +
      +    public static final TpSlots SLOTS = ZipBuiltinsSlotsGen.SLOTS;
      +
      +    @Override
      +    protected List> getNodeFactories() {
      +        return ZipBuiltinsFactory.getFactories();
      +    }
      +
      +    // zip(*iterables)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = J_ZIP, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class ZipNode extends PythonBuiltinNode {
      +        static boolean isNoneOrEmptyPKeyword(Object value) {
      +            return PGuards.isPNone(value) || (value instanceof PKeyword[] kw && kw.length == 0);
      +        }
      +
      +        @Specialization(guards = "isNoneOrEmptyPKeyword(kw)")
      +        static PZip zip(VirtualFrame frame, Object cls, Object[] args, @SuppressWarnings("unused") Object kw,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached.Exclusive @Cached PyObjectGetIter getIter,
      +                        @Cached.Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return zip(frame, inliningTarget, cls, args, false, getIter, getInstanceShape);
      +        }
      +
      +        @Specialization(guards = "kw.length == 1")
      +        static PZip zip(VirtualFrame frame, Object cls, Object[] args, PKeyword[] kw,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached TruffleString.EqualNode eqNode,
      +                        @Cached.Exclusive @Cached PyObjectGetIter getIter,
      +                        @Cached PyObjectIsTrueNode isTrueNode,
      +                        @Cached InlinedConditionProfile profile,
      +                        @Cached.Shared @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached.Exclusive @Cached PRaiseNode raiseNode) {
      +            if (profile.profile(inliningTarget, eqNode.execute(kw[0].getName(), T_STRICT, TS_ENCODING))) {
      +                return zip(frame, inliningTarget, cls, args, isTrueNode.execute(frame, kw[0].getValue()), getIter, getInstanceShape);
      +            }
      +            throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_IS_AN_INVALID_ARG_FOR_S, kw[0].getName(), T_ZIP);
      +        }
      +
      +        @Specialization(guards = "kw.length != 1")
      +        static Object zip(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") Object[] args, PKeyword[] kw,
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.S_TAKES_AT_MOST_ONE_KEYWORD_ARGUMENT_D_GIVEN, T_ZIP, kw.length);
      +        }
      +
      +        private static PZip zip(VirtualFrame frame, Node inliningTarget, Object cls, Object[] args, boolean strict, PyObjectGetIter getIter, TypeNodes.GetInstanceShape getInstanceShape) {
      +            Object[] iterables = new Object[args.length];
      +            LoopNode.reportLoopCount(inliningTarget, args.length);
      +            for (int i = 0; i < args.length; i++) {
      +                Object item = args[i];
      +                iterables[i] = getIter.execute(frame, inliningTarget, item);
      +            }
      +            return PFactory.createZip(PythonLanguage.get(inliningTarget), cls, getInstanceShape.execute(cls), iterables, strict);
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
      +    @GenerateNodeFactory
      +    public abstract static class NextNode extends TpIterNextBuiltin {
      +
      +        @Specialization(guards = "isEmpty(self.getIterators())")
      +        static Object doEmpty(@SuppressWarnings("unused") PZip self) {
      +            throw iteratorExhausted();
      +        }
      +
      +        @Specialization(guards = {"!isEmpty(self.getIterators())", "!self.isStrict()"})
      +        static Object doNext(VirtualFrame frame, PZip self,
      +                        @Bind Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Cached GetObjectSlotsNode getSlots,
      +                        @Cached CallSlotTpIterNextNode callIterNext) {
      +            Object[] iterators = self.getIterators();
      +            Object[] tupleElements = new Object[iterators.length];
      +            for (int i = 0; i < iterators.length; i++) {
      +                Object it = iterators[i];
      +                /*
      +                 * Not using PyIterNext because the non-strict version should pass through existing
      +                 * StopIteration
      +                 */
      +                tupleElements[i] = callIterNext.execute(frame, inliningTarget, getSlots.execute(inliningTarget, it).tp_iternext(), it);
      +            }
      +            return PFactory.createTuple(language, tupleElements);
      +        }
      +
      +        @Specialization(guards = {"!isEmpty(self.getIterators())", "self.isStrict()"})
      +        static Object doNext(VirtualFrame frame, PZip self,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Cached PyIterNextNode nextNode,
      +                        @Cached PRaiseNode raiseNode) {
      +            Object[] iterators = self.getIterators();
      +            Object[] tupleElements = new Object[iterators.length];
      +            int i = 0;
      +            for (; i < iterators.length; i++) {
      +                try {
      +                    tupleElements[i] = nextNode.execute(frame, inliningTarget, iterators[i]);
      +                } catch (IteratorExhausted e) {
      +                    if (i > 0) {
      +                        throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.ZIP_ARG_D_IS_SHORTER_THEN_ARG_SD, i + 1, i == 1 ? " " : "s 1-", i);
      +                    }
      +                    for (i = 1; i < iterators.length; i++) {
      +                        try {
      +                            nextNode.execute(frame, inliningTarget, iterators[i]);
      +                        } catch (IteratorExhausted e1) {
      +                            continue;
      +                        }
      +                        throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.ZIP_ARG_D_IS_LONGER_THEN_ARG_SD, i + 1, i == 1 ? " " : "s 1-", i);
      +                    }
      +                    throw e;
      +                }
      +            }
      +            return PFactory.createTuple(language, tupleElements);
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
      +    @GenerateNodeFactory
      +    public abstract static class IterNode extends PythonUnaryBuiltinNode {
      +
      +        @Specialization
      +        static Object doPZip(PZip self) {
      +            return self;
      +        }
      +    }
      +
      +    @Builtin(name = J___REDUCE__, minNumOfPositionalArgs = 1)
      +    @GenerateNodeFactory
      +    public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
      +
      +        @Specialization
      +        static Object reduce(PZip self,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached InlinedConditionProfile strictProfile,
      +                        @Cached GetClassNode getClass,
      +                        @Bind PythonLanguage language) {
      +            Object type = getClass.execute(inliningTarget, self);
      +            PTuple tuple = PFactory.createTuple(language, self.getIterators());
      +            Object[] elements = strictProfile.profile(inliningTarget, self.isStrict()) ? new Object[]{type, tuple, true} : new Object[]{type, tuple};
      +            return PFactory.createTuple(language, elements);
      +        }
      +    }
      +
      +    @Builtin(name = J___SETSTATE__, minNumOfPositionalArgs = 2)
      +    @GenerateNodeFactory
      +    abstract static class SetStateNode extends PythonBinaryBuiltinNode {
      +        @Specialization
      +        Object doit(VirtualFrame frame, PZip self, Object state,
      +                        @Cached PyObjectIsTrueNode isTrueNode) {
      +            self.setStrict(isTrueNode.execute(frame, state));
      +            return PNone.NONE;
      +        }
      +    }
      +}
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/AccumulateBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/AccumulateBuiltins.java
      index ecd5340a1f..34341e93e0 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/AccumulateBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/AccumulateBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,29 +40,36 @@
        */
       package com.oracle.graal.python.builtins.objects.itertools;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.list.PList;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
       import com.oracle.graal.python.lib.PyNumberAddNode;
       import com.oracle.graal.python.lib.PyObjectGetIter;
       import com.oracle.graal.python.nodes.call.CallNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.object.GetClassNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -76,12 +83,34 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PAccumulate})
       public final class AccumulateBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = AccumulateBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return AccumulateBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "accumulate", minNumOfPositionalArgs = 2, parameterNames = {"cls", "iterable", "func"}, keywordOnlyNames = {"initial"})
      +    @GenerateNodeFactory
      +    public abstract static class AccumulateNode extends PythonBuiltinNode {
      +
      +        @Specialization
      +        protected static PAccumulate construct(VirtualFrame frame, Object cls, Object iterable, Object func, Object initial,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PyObjectGetIter getIter) {
      +            PAccumulate self = PFactory.createAccumulate(language, cls, getInstanceShape.execute(cls));
      +            self.setIterable(getIter.execute(frame, inliningTarget, iterable));
      +            self.setFunc(func instanceof PNone ? null : func);
      +            self.setTotal(null);
      +            self.setInitial(initial instanceof PNone ? null : initial);
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -90,13 +119,14 @@ static Object iter(PAccumulate self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization
               static Object next(VirtualFrame frame, PAccumulate self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached BuiltinFunctions.NextNode nextNode,
      +                        @Cached GetObjectSlotsNode getSlots,
      +                        @Cached CallSlotTpIterNextNode callIterNext,
                               @Cached PyNumberAddNode addNode,
                               @Cached CallNode callNode,
                               @Cached InlinedBranchProfile hasInitialProfile,
      @@ -108,14 +138,15 @@ static Object next(VirtualFrame frame, PAccumulate self,
                       self.setInitial(null);
                       return self.getTotal();
                   }
      -            Object value = nextNode.execute(frame, self.getIterable(), PNone.NO_VALUE);
      +            Object it = self.getIterable();
      +            Object value = callIterNext.execute(frame, inliningTarget, getSlots.execute(inliningTarget, it).tp_iternext(), it);
                   if (self.getTotal() == null) {
                       markerProfile.enter(inliningTarget);
                       self.setTotal(value);
                       return value;
                   }
                   if (hasFuncProfile.profile(inliningTarget, self.getFunc() == null)) {
      -                self.setTotal(addNode.execute(frame, inliningTarget, self.getTotal(), value));
      +                self.setTotal(addNode.execute(frame, self.getTotal(), value));
                   } else {
                       self.setTotal(callNode.execute(frame, self.getFunc(), self.getTotal(), value));
                   }
      @@ -136,7 +167,7 @@ static Object reduceNoFunc(VirtualFrame frame, PAccumulate self,
                               @Cached InlinedBranchProfile totalMarkerProfile,
                               @Cached InlinedBranchProfile elseProfile,
                               @Cached PyObjectGetIter getIter,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object func = self.getFunc();
                   if (func == null) {
                       func = PNone.NONE;
      @@ -145,39 +176,39 @@ static Object reduceNoFunc(VirtualFrame frame, PAccumulate self,
                       hasInitialProfile.enter(inliningTarget);
       
                       Object type = getClassNode.execute(inliningTarget, self);
      -                PChain chain = factory.createChain(PythonBuiltinClassType.PChain);
      -                chain.setSource(getIter.execute(frame, inliningTarget, factory.createList(new Object[]{self.getIterable()})));
      -                PTuple initialTuple = factory.createTuple(new Object[]{self.getInitial()});
      +                PChain chain = PFactory.createChain(language);
      +                chain.setSource(getIter.execute(frame, inliningTarget, PFactory.createList(language, new Object[]{self.getIterable()})));
      +                PTuple initialTuple = PFactory.createTuple(language, new Object[]{self.getInitial()});
                       chain.setActive(getIter.execute(frame, inliningTarget, initialTuple));
       
      -                PTuple tuple = factory.createTuple(new Object[]{chain, func});
      -                return factory.createTuple(new Object[]{type, tuple, PNone.NONE});
      +                PTuple tuple = PFactory.createTuple(language, new Object[]{chain, func});
      +                return PFactory.createTuple(language, new Object[]{type, tuple, PNone.NONE});
                   } else if (self.getTotal() == PNone.NONE) {
                       totalNoneProfile.enter(inliningTarget);
       
      -                PChain chain = factory.createChain(PythonBuiltinClassType.PChain);
      -                PList noneList = factory.createList(new Object[]{PNone.NONE});
      +                PChain chain = PFactory.createChain(language);
      +                PList noneList = PFactory.createList(language, new Object[]{PNone.NONE});
                       Object noneIter = getIter.execute(frame, inliningTarget, noneList);
      -                chain.setSource(getIter.execute(frame, inliningTarget, factory.createList(new Object[]{noneIter, self.getIterable()})));
      +                chain.setSource(getIter.execute(frame, inliningTarget, PFactory.createList(language, new Object[]{noneIter, self.getIterable()})));
                       chain.setActive(PNone.NONE);
      -                PAccumulate accumulate = factory.createAccumulate(PythonBuiltinClassType.PAccumulate);
      +                PAccumulate accumulate = PFactory.createAccumulate(language);
                       accumulate.setIterable(chain);
                       accumulate.setFunc(func);
       
      -                PTuple tuple = factory.createTuple(new Object[]{accumulate, 1, PNone.NONE});
      -                return factory.createTuple(new Object[]{PythonBuiltinClassType.PIslice, tuple});
      +                PTuple tuple = PFactory.createTuple(language, new Object[]{accumulate, 1, PNone.NONE});
      +                return PFactory.createTuple(language, new Object[]{PythonBuiltinClassType.PIslice, tuple});
                   } else if (self.getTotal() != null) {
                       totalMarkerProfile.enter(inliningTarget);
       
                       Object type = getClassNode.execute(inliningTarget, self);
      -                PTuple tuple = factory.createTuple(new Object[]{self.getIterable(), func});
      -                return factory.createTuple(new Object[]{type, tuple, self.getTotal()});
      +                PTuple tuple = PFactory.createTuple(language, new Object[]{self.getIterable(), func});
      +                return PFactory.createTuple(language, new Object[]{type, tuple, self.getTotal()});
                   } else {
                       elseProfile.enter(inliningTarget);
       
                       Object type = getClassNode.execute(inliningTarget, self);
      -                PTuple tuple = factory.createTuple(new Object[]{self.getIterable(), func});
      -                return factory.createTuple(new Object[]{type, tuple});
      +                PTuple tuple = PFactory.createTuple(language, new Object[]{self.getIterable(), func});
      +                return PFactory.createTuple(language, new Object[]{type, tuple});
                   }
               }
       
      @@ -192,5 +223,4 @@ static Object setState(PAccumulate self, Object state) {
                   return PNone.NONE;
               }
           }
      -
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ChainBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ChainBuiltins.java
      index 32e0311ef5..e2e2ac2525 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ChainBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ChainBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -44,33 +44,40 @@
       import static com.oracle.graal.python.nodes.ErrorMessages.ARGUMENTS_MUST_BE_ITERATORS;
       import static com.oracle.graal.python.nodes.ErrorMessages.IS_NOT_A;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
       import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
       import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins.GetItemNode;
       import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins.LenNode;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
      +import com.oracle.graal.python.lib.IteratorExhausted;
       import com.oracle.graal.python.lib.PyIterCheckNode;
      +import com.oracle.graal.python.lib.PyIterNextNode;
       import com.oracle.graal.python.lib.PyObjectGetIter;
      +import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
      +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      -import com.oracle.graal.python.util.PythonUtils;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -85,12 +92,41 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PChain})
       public final class ChainBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = ChainBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return ChainBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "chain", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class ChainNode extends PythonVarargsBuiltinNode {
      +
      +        @Specialization
      +        static PChain construct(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode,
      +                        @Cached PyObjectGetIter getIter,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!isTypeNode.execute(inliningTarget, cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +            if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "chain()");
      +            }
      +            PChain self = PFactory.createChain(language, cls, getInstanceShape.execute(cls));
      +            self.setSource(getIter.execute(frame, inliningTarget, PFactory.createList(language, args)));
      +            self.setActive(PNone.NONE);
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -99,38 +135,45 @@ static Object iter(PChain self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization
               static Object next(VirtualFrame frame, PChain self,
                               @Bind("this") Node inliningTarget,
                               @Cached PyObjectGetIter getIter,
      -                        @Cached BuiltinFunctions.NextNode nextNode,
      -                        @Cached IsBuiltinObjectProfile isStopIterationProfile,
      -                        @Cached InlinedBranchProfile nextExceptioProfile,
      -                        @Cached InlinedLoopConditionProfile loopProfile,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PyIterNextNode nextNode,
      +                        @Cached InlinedBranchProfile nextExceptionProfile,
      +                        @Cached InlinedLoopConditionProfile loopProfile) {
                   while (loopProfile.profile(inliningTarget, self.getSource() != PNone.NONE)) {
                       if (self.getActive() == PNone.NONE) {
                           try {
      -                        Object next = nextNode.execute(frame, self.getSource(), PNone.NO_VALUE);
      +                        Object next;
      +                        try {
      +                            next = nextNode.execute(frame, inliningTarget, self.getSource());
      +                        } catch (IteratorExhausted e) {
      +                            self.setSource(PNone.NONE);
      +                            throw e;
      +                        } catch (PException e) {
      +                            nextExceptionProfile.enter(inliningTarget);
      +                            self.setSource(PNone.NONE);
      +                            throw e;
      +                        }
                               Object iter = getIter.execute(frame, inliningTarget, next);
                               self.setActive(iter);
                           } catch (PException e) {
      -                        nextExceptioProfile.enter(inliningTarget);
      +                        nextExceptionProfile.enter(inliningTarget);
                               self.setSource(PNone.NONE);
                               throw e;
                           }
                       }
                       try {
      -                    return nextNode.execute(frame, self.getActive(), PNone.NO_VALUE);
      -                } catch (PException e) {
      -                    e.expectStopIteration(inliningTarget, isStopIterationProfile);
      +                    return nextNode.execute(frame, inliningTarget, self.getActive());
      +                } catch (IteratorExhausted e) {
                           self.setActive(PNone.NONE);
                       }
                   }
      -            throw raiseNode.get(inliningTarget).raiseStopIteration();
      +            throw iteratorExhausted();
               }
           }
       
      @@ -141,8 +184,8 @@ public abstract static class FromIterNode extends PythonBinaryBuiltinNode {
               static Object fromIter(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object arg,
                               @Bind("this") Node inliningTarget,
                               @Cached PyObjectGetIter getIter,
      -                        @Cached PythonObjectFactory factory) {
      -            PChain instance = factory.createChain(PythonBuiltinClassType.PChain);
      +                        @Bind PythonLanguage language) {
      +            PChain instance = PFactory.createChain(language);
                   instance.setSource(getIter.execute(frame, inliningTarget, arg));
                   instance.setActive(PNone.NONE);
                   return instance;
      @@ -158,19 +201,19 @@ static Object reducePos(PChain self,
                               @Cached GetClassNode getClass,
                               @Cached InlinedConditionProfile hasSourceProfile,
                               @Cached InlinedConditionProfile hasActiveProfile,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClass.execute(inliningTarget, self);
      -            PTuple empty = factory.createTuple(PythonUtils.EMPTY_OBJECT_ARRAY);
      +            PTuple empty = PFactory.createEmptyTuple(language);
                   if (hasSourceProfile.profile(inliningTarget, self.getSource() != PNone.NONE)) {
                       if (hasActiveProfile.profile(inliningTarget, self.getActive() != PNone.NONE)) {
      -                    PTuple tuple = factory.createTuple(new Object[]{self.getSource(), self.getActive()});
      -                    return factory.createTuple(new Object[]{type, empty, tuple});
      +                    PTuple tuple = PFactory.createTuple(language, new Object[]{self.getSource(), self.getActive()});
      +                    return PFactory.createTuple(language, new Object[]{type, empty, tuple});
                       } else {
      -                    PTuple tuple = factory.createTuple(new Object[]{self.getSource()});
      -                    return factory.createTuple(new Object[]{type, empty, tuple});
      +                    PTuple tuple = PFactory.createTuple(language, new Object[]{self.getSource()});
      +                    return PFactory.createTuple(language, new Object[]{type, empty, tuple});
                       }
                   } else {
      -                return factory.createTuple(new Object[]{type, empty});
      +                return PFactory.createTuple(language, new Object[]{type, empty});
                   }
               }
           }
      @@ -185,13 +228,13 @@ static Object setState(VirtualFrame frame, PChain self, Object state,
                               @Cached GetItemNode getItemNode,
                               @Cached InlinedBranchProfile len2Profile,
                               @Cached PyIterCheckNode iterCheckNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (!(state instanceof PTuple)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, IS_NOT_A, "state", "a length 1 or 2 tuple");
      +                throw raiseNode.raise(inliningTarget, TypeError, IS_NOT_A, "state", "a length 1 or 2 tuple");
                   }
                   int len = (int) lenNode.execute(frame, state);
                   if (len < 1 || len > 2) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, IS_NOT_A, "state", "a length 1 or 2 tuple");
      +                throw raiseNode.raise(inliningTarget, TypeError, IS_NOT_A, "state", "a length 1 or 2 tuple");
                   }
                   Object source = getItemNode.execute(frame, state, 0);
                   checkIterator(inliningTarget, iterCheckNode, source, raiseNode);
      @@ -205,9 +248,9 @@ static Object setState(VirtualFrame frame, PChain self, Object state,
                   return PNone.NONE;
               }
       
      -        private static void checkIterator(Node inliningTarget, PyIterCheckNode iterCheckNode, Object obj, PRaiseNode.Lazy raiseNode) throws PException {
      +        private static void checkIterator(Node inliningTarget, PyIterCheckNode iterCheckNode, Object obj, PRaiseNode raiseNode) throws PException {
                   if (!iterCheckNode.execute(inliningTarget, obj)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ARGUMENTS_MUST_BE_ITERATORS);
      +                throw raiseNode.raise(inliningTarget, TypeError, ARGUMENTS_MUST_BE_ITERATORS);
                   }
               }
           }
      @@ -217,8 +260,8 @@ private static void checkIterator(Node inliningTarget, PyIterCheckNode iterCheck
           public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode {
               @Specialization
               static Object classGetItem(Object cls, Object key,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createGenericAlias(cls, key);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createGenericAlias(language, cls, key);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CombinationsBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CombinationsBuiltins.java
      index 7380de3ab0..cc64734b7c 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CombinationsBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CombinationsBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -42,31 +42,41 @@
       
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
      +import static com.oracle.graal.python.nodes.ErrorMessages.MUST_BE_NON_NEGATIVE;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SETSTATE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.ArgumentClinic;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
      +import com.oracle.graal.python.builtins.objects.iterator.IteratorNodes;
      +import com.oracle.graal.python.builtins.objects.itertools.CombinationsBuiltinsClinicProviders.CombinationsNodeClinicProviderGen;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode;
      -import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.truffle.api.CompilerAsserts;
      @@ -77,19 +87,69 @@
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
      +import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile;
      +import com.oracle.truffle.api.profiles.LoopConditionProfile;
       
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PCombinations, PythonBuiltinClassType.PCombinationsWithReplacement})
       public final class CombinationsBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = CombinationsBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return CombinationsBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "combinations", minNumOfPositionalArgs = 3, parameterNames = {"cls", "iterable", "r"})
      +    @ArgumentClinic(name = "r", conversion = ArgumentClinic.ClinicConversion.Int)
      +    @GenerateNodeFactory
      +    public abstract static class CombinationsNode extends PythonTernaryClinicBuiltinNode {
      +
      +        @Override
      +        protected ArgumentClinicProvider getArgumentClinic() {
      +            return CombinationsNodeClinicProviderGen.INSTANCE;
      +        }
      +
      +        @Specialization
      +        static Object construct(VirtualFrame frame, Object cls, Object iterable, int r,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Cached IteratorNodes.ToArrayNode toArrayNode,
      +                        @Cached LoopConditionProfile indicesLoopProfile,
      +                        @Cached InlinedConditionProfile wrongTypeProfile,
      +                        @Cached InlinedConditionProfile negativeProfile,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!wrongTypeProfile.profile(inliningTarget, isTypeNode.execute(inliningTarget, cls))) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +            if (negativeProfile.profile(inliningTarget, r < 0)) {
      +                throw raiseNode.raise(inliningTarget, ValueError, MUST_BE_NON_NEGATIVE, "r");
      +            }
      +
      +            PCombinations self = PFactory.createCombinations(language, cls, getInstanceShape.execute(cls));
      +            self.setPool(toArrayNode.execute(frame, iterable));
      +
      +            int[] indices = new int[r];
      +            indicesLoopProfile.profileCounted(r);
      +            for (int i = 0; indicesLoopProfile.inject(i < r); i++) {
      +                indices[i] = i;
      +            }
      +            self.setIndices(indices);
      +            self.setR(r);
      +            self.setLastResult(null);
      +            self.setStopped(r > self.getPool().length);
      +
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -98,20 +158,20 @@ static Object iter(PAbstractCombinations self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @SuppressWarnings("unused")
               @Specialization(guards = "self.isStopped()")
               static Object nextStopped(PAbstractCombinations self,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raiseStopIteration();
      +                        @Bind("this") Node inliningTarget) {
      +            throw iteratorExhausted();
               }
       
               @Specialization(guards = {"!self.isStopped()", "isLastResultNull(self)"})
               static Object nextNoResult(PAbstractCombinations self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached @Shared PythonObjectFactory factory,
      +                        @Bind PythonLanguage language,
                               @Cached @Exclusive InlinedLoopConditionProfile loopConditionProfile) {
                   // On the first pass, initialize result tuple using the indices
                   Object[] result = new Object[self.getR()];
      @@ -121,31 +181,27 @@ static Object nextNoResult(PAbstractCombinations self,
                       result[i] = self.getPool()[idx];
                   }
                   self.setLastResult(result);
      -            return factory.createTuple(result);
      +            return PFactory.createTuple(language, result);
               }
       
               @Specialization(guards = {"!self.isStopped()", "!isLastResultNull(self)"})
               static Object next(PCombinations self,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
                               @Shared @Cached InlinedLoopConditionProfile indexLoopProfile,
      -                        @Shared @Cached InlinedLoopConditionProfile resultLoopProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            return nextInternal(inliningTarget, self, factory, indexLoopProfile, resultLoopProfile, raiseNode);
      +                        @Shared @Cached InlinedLoopConditionProfile resultLoopProfile) {
      +            return nextInternal(inliningTarget, self, indexLoopProfile, resultLoopProfile);
               }
       
               @Specialization(guards = {"!self.isStopped()", "!isLastResultNull(self)"})
               static Object next(PCombinationsWithReplacement self,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory factory,
                               @Shared @Cached InlinedLoopConditionProfile indexLoopProfile,
      -                        @Shared @Cached InlinedLoopConditionProfile resultLoopProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            return nextInternal(inliningTarget, self, factory, indexLoopProfile, resultLoopProfile, raiseNode);
      +                        @Shared @Cached InlinedLoopConditionProfile resultLoopProfile) {
      +            return nextInternal(inliningTarget, self, indexLoopProfile, resultLoopProfile);
               }
       
      -        private static Object nextInternal(Node inliningTarget, PAbstractCombinations self, PythonObjectFactory factory, InlinedLoopConditionProfile indexLoopProfile,
      -                        InlinedLoopConditionProfile resultLoopProfile, PRaiseNode.Lazy raiseNode) throws PException {
      +        private static Object nextInternal(Node inliningTarget, PAbstractCombinations self, InlinedLoopConditionProfile indexLoopProfile,
      +                        InlinedLoopConditionProfile resultLoopProfile) {
       
                   CompilerAsserts.partialEvaluationConstant(self.getClass());
       
      @@ -162,7 +218,7 @@ private static Object nextInternal(Node inliningTarget, PAbstractCombinations se
                   // If i is negative, then the indices are all at their maximum value and we're done
                   if (i < 0) {
                       self.setStopped(true);
      -                throw raiseNode.get(inliningTarget).raiseStopIteration();
      +                throw iteratorExhausted();
                   }
       
                   // Increment the current index which we know is not at its maximum.
      @@ -182,7 +238,7 @@ private static Object nextInternal(Node inliningTarget, PAbstractCombinations se
                       result[j] = elem;
                   }
                   self.setLastResult(result);
      -            return factory.createTuple(result);
      +            return PFactory.createTuple(PythonLanguage.get(inliningTarget), result);
               }
       
               protected boolean isLastResultNull(PAbstractCombinations self) {
      @@ -200,18 +256,18 @@ static Object reduce(PAbstractCombinations self,
                               @Cached InlinedConditionProfile hasNoLastResultProfile,
                               @Cached InlinedConditionProfile stoppedProfile,
                               @Cached GetClassNode getClassNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClassNode.execute(inliningTarget, self);
                   if (hasNoLastResultProfile.profile(inliningTarget, self.getLastResult() == null)) {
      -                PTuple args = factory.createTuple(new Object[]{factory.createTuple(self.getPool()), self.getR()});
      -                return factory.createTuple(new Object[]{type, args});
      +                PTuple args = PFactory.createTuple(language, new Object[]{PFactory.createTuple(language, self.getPool()), self.getR()});
      +                return PFactory.createTuple(language, new Object[]{type, args});
                   } else if (stoppedProfile.profile(inliningTarget, self.isStopped())) {
      -                PTuple args = factory.createTuple(new Object[]{factory.createEmptyTuple(), self.getR()});
      -                return factory.createTuple(new Object[]{type, args});
      +                PTuple args = PFactory.createTuple(language, new Object[]{PFactory.createEmptyTuple(language), self.getR()});
      +                return PFactory.createTuple(language, new Object[]{type, args});
                   }
      -            PTuple indices = factory.createTuple(PythonUtils.arrayCopyOf(self.getIndices(), self.getR()));
      -            PTuple args = factory.createTuple(new Object[]{factory.createTuple(self.getPool()), self.getR()});
      -            return factory.createTuple(new Object[]{type, args, indices});
      +            PTuple indices = PFactory.createTuple(language, PythonUtils.arrayCopyOf(self.getIndices(), self.getR()));
      +            PTuple args = PFactory.createTuple(language, new Object[]{PFactory.createTuple(language, self.getPool()), self.getR()});
      +            return PFactory.createTuple(language, new Object[]{type, args, indices});
               }
           }
       
      @@ -224,7 +280,7 @@ static Object setState(PAbstractCombinations self, Object stateObj,
                               @Bind("this") Node inliningTarget,
                               @Cached CastToJavaIntExactNode cast,
                               @Cached SequenceStorageNodes.GetItemScalarNode getItemNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   int n = self.getPool().length;
                   if (stateObj instanceof PTuple state && state.getSequenceStorage().length() == self.getR()) {
                       SequenceStorage storage = state.getSequenceStorage();
      @@ -241,7 +297,7 @@ static Object setState(PAbstractCombinations self, Object stateObj,
                               self.getIndices()[i] = index;
                           }
                       } catch (CannotCastException e) {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.INTEGER_REQUIRED);
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.INTEGER_REQUIRED);
                       }
                       Object[] result = new Object[self.getR()];
                       for (int i = 0; i < self.getR(); i++) {
      @@ -250,9 +306,8 @@ static Object setState(PAbstractCombinations self, Object stateObj,
                       self.setLastResult(result);
                       return PNone.NONE;
                   } else {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.INVALID_ARGS, T___SETSTATE__);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.INVALID_ARGS, T___SETSTATE__);
                   }
               }
           }
      -
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CombinationsWithReplacementBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CombinationsWithReplacementBuiltins.java
      new file mode 100644
      index 0000000000..86d85322d3
      --- /dev/null
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CombinationsWithReplacementBuiltins.java
      @@ -0,0 +1,125 @@
      +/*
      + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
      + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      + *
      + * The Universal Permissive License (UPL), Version 1.0
      + *
      + * Subject to the condition set forth below, permission is hereby granted to any
      + * person obtaining a copy of this software, associated documentation and/or
      + * data (collectively the "Software"), free of charge and under any and all
      + * copyright rights in the Software, and any and all patent rights owned or
      + * freely licensable by each licensor hereunder covering either (i) the
      + * unmodified Software as contributed to or provided by such licensor, or (ii)
      + * the Larger Works (as defined below), to deal in both
      + *
      + * (a) the Software, and
      + *
      + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
      + * one is included with the Software each a "Larger Work" to which the Software
      + * is contributed by such licensors),
      + *
      + * without restriction, including without limitation the rights to copy, create
      + * derivative works of, display, perform, and distribute the Software and make,
      + * use, sell, offer for sale, import, export, have made, and have sold the
      + * Software and the Larger Work(s), and to sublicense the foregoing rights on
      + * either these or other terms.
      + *
      + * This license is subject to the following condition:
      + *
      + * The above copyright notice and either this complete permission notice or at a
      + * minimum a reference to the UPL must be included in all copies or substantial
      + * portions of the Software.
      + *
      + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      + * SOFTWARE.
      + */
      +package com.oracle.graal.python.builtins.objects.itertools;
      +
      +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
      +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError;
      +import static com.oracle.graal.python.nodes.ErrorMessages.MUST_BE_NON_NEGATIVE;
      +
      +import java.util.List;
      +
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.ArgumentClinic;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
      +import com.oracle.graal.python.builtins.CoreFunctions;
      +import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      +import com.oracle.graal.python.builtins.PythonBuiltins;
      +import com.oracle.graal.python.builtins.objects.iterator.IteratorNodes;
      +import com.oracle.graal.python.builtins.objects.itertools.CombinationsWithReplacementBuiltinsClinicProviders.CombinationsWithReplacementNodeClinicProviderGen;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.PRaiseNode;
      +import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
      +import com.oracle.graal.python.runtime.object.PFactory;
      +import com.oracle.truffle.api.dsl.Bind;
      +import com.oracle.truffle.api.dsl.Cached;
      +import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      +import com.oracle.truffle.api.dsl.NodeFactory;
      +import com.oracle.truffle.api.dsl.Specialization;
      +import com.oracle.truffle.api.frame.VirtualFrame;
      +import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.InlinedConditionProfile;
      +
      +@CoreFunctions(extendClasses = PythonBuiltinClassType.PCombinationsWithReplacement)
      +public class CombinationsWithReplacementBuiltins extends PythonBuiltins {
      +
      +    public static final TpSlots SLOTS = CombinationsWithReplacementBuiltinsSlotsGen.SLOTS;
      +
      +    @Override
      +    protected List> getNodeFactories() {
      +        return CombinationsWithReplacementBuiltinsFactory.getFactories();
      +    }
      +
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "combinations_with_replacement", minNumOfPositionalArgs = 3, parameterNames = {
      +                    "cls", "iterable", "r"})
      +    @ArgumentClinic(name = "r", conversion = ArgumentClinic.ClinicConversion.Int)
      +    @GenerateNodeFactory
      +    public abstract static class CombinationsWithReplacementNode extends PythonTernaryClinicBuiltinNode {
      +
      +        @Override
      +        protected ArgumentClinicProvider getArgumentClinic() {
      +            return CombinationsWithReplacementNodeClinicProviderGen.INSTANCE;
      +        }
      +
      +        @Specialization
      +        static Object construct(VirtualFrame frame, Object cls, Object iterable, int r,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Cached IteratorNodes.ToArrayNode toArrayNode,
      +                        @Cached InlinedConditionProfile wrongTypeProfile,
      +                        @Cached InlinedConditionProfile negativeProfile,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!wrongTypeProfile.profile(inliningTarget, isTypeNode.execute(inliningTarget, cls))) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +            if (negativeProfile.profile(inliningTarget, r < 0)) {
      +                throw raiseNode.raise(inliningTarget, ValueError, MUST_BE_NON_NEGATIVE, "r");
      +            }
      +            PCombinationsWithReplacement self = PFactory.createCombinationsWithReplacement(language, cls, getInstanceShape.execute(cls));
      +            self.setPool(toArrayNode.execute(frame, iterable));
      +            self.setR(r);
      +
      +            self.setIndices(new int[r]);
      +            self.setLastResult(null);
      +            self.setStopped(self.getPool().length == 0 && r > 0);
      +
      +            return self;
      +        }
      +    }
      +}
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CompressBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CompressBuiltins.java
      index 67996302fd..5713ec178f 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CompressBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CompressBuiltins.java
      @@ -40,24 +40,35 @@
        */
       package com.oracle.graal.python.builtins.objects.itertools;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
      +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
      -import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
      +import com.oracle.graal.python.lib.PyObjectGetIter;
       import com.oracle.graal.python.lib.PyObjectIsTrueNode;
      +import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.object.GetClassNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -70,12 +81,36 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PCompress})
       public final class CompressBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = CompressBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return CompressBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "compress", minNumOfPositionalArgs = 3, parameterNames = {"cls", "data", "selectors"})
      +    @GenerateNodeFactory
      +    public abstract static class CompressNode extends PythonTernaryBuiltinNode {
      +        @Specialization
      +        static PCompress construct(VirtualFrame frame, Object cls, Object data, Object selectors,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached PyObjectGetIter getIter,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!isTypeNode.execute(inliningTarget, cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +            PCompress self = PFactory.createCompress(language, cls, getInstanceShape.execute(cls));
      +            self.setData(getIter.execute(frame, inliningTarget, data));
      +            self.setSelectors(getIter.execute(frame, inliningTarget, selectors));
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -84,22 +119,31 @@ static Object iter(PCompress self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization
               static Object next(VirtualFrame frame, PCompress self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached BuiltinFunctions.NextNode nextNode,
      +                        @Cached GetObjectSlotsNode getDataSlots,
      +                        @Cached GetObjectSlotsNode getSelectorsSlots,
      +                        @Cached CallSlotTpIterNextNode callIterNextData,
      +                        @Cached CallSlotTpIterNextNode callIterNextSelectors,
                               @Cached PyObjectIsTrueNode isTrue,
                               @Cached InlinedLoopConditionProfile loopConditionProfile) {
      -            Object nextSelector;
      -            Object nextItem;
      +            Object data = self.getData();
      +            Object selectors = self.getSelectors();
      +            TpSlot dataIterNext = getDataSlots.execute(inliningTarget, data).tp_iternext();
      +            TpSlot selectorsIterNext = getSelectorsSlots.execute(inliningTarget, selectors).tp_iternext();
      +            Object result = null;
                   do {
      -                nextItem = nextNode.execute(frame, self.getData(), PNone.NO_VALUE);
      -                nextSelector = nextNode.execute(frame, self.getSelectors(), PNone.NO_VALUE);
      -            } while (loopConditionProfile.profile(inliningTarget, !isTrue.execute(frame, nextSelector)));
      -            return nextItem;
      +                Object datum = callIterNextData.execute(frame, inliningTarget, dataIterNext, data);
      +                Object selector = callIterNextSelectors.execute(frame, inliningTarget, selectorsIterNext, selectors);
      +                if (isTrue.execute(frame, selector)) {
      +                    result = datum;
      +                }
      +            } while (loopConditionProfile.profile(inliningTarget, result == null));
      +            return result;
               }
           }
       
      @@ -110,11 +154,10 @@ public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
               static Object reduce(PCompress self,
                               @Bind("this") Node inliningTarget,
                               @Cached GetClassNode getClassNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClassNode.execute(inliningTarget, self);
      -            PTuple tuple = factory.createTuple(new Object[]{self.getData(), self.getSelectors()});
      -            return factory.createTuple(new Object[]{type, tuple});
      +            PTuple tuple = PFactory.createTuple(language, new Object[]{self.getData(), self.getSelectors()});
      +            return PFactory.createTuple(language, new Object[]{type, tuple});
               }
           }
      -
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CountBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CountBuiltins.java
      index 9999eca821..642df410dd 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CountBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CountBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,30 +40,43 @@
        */
       package com.oracle.graal.python.builtins.objects.itertools;
       
      +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
      +import static com.oracle.graal.python.nodes.ErrorMessages.NUMBER_IS_REQUIRED;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.ArgumentClinic;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      +import com.oracle.graal.python.builtins.objects.itertools.CountBuiltinsClinicProviders.CountNodeClinicProviderGen;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
       import com.oracle.graal.python.lib.PyNumberAddNode;
      +import com.oracle.graal.python.lib.PyNumberCheckNode;
       import com.oracle.graal.python.lib.PyObjectGetAttr;
       import com.oracle.graal.python.lib.PyObjectReprAsObjectNode;
       import com.oracle.graal.python.lib.PyObjectTypeCheck;
      +import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.nodes.util.CastToJavaLongExactNode;
       import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -78,12 +91,50 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PCount})
       public final class CountBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = CountBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return CountBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "count", minNumOfPositionalArgs = 1, parameterNames = {"cls", "start", "step"})
      +    @ArgumentClinic(name = "start", defaultValue = "0", useDefaultForNone = true)
      +    @ArgumentClinic(name = "step", defaultValue = "1", useDefaultForNone = true)
      +    @GenerateNodeFactory
      +    public abstract static class CountNode extends PythonTernaryClinicBuiltinNode {
      +
      +        @Override
      +        protected ArgumentClinicProvider getArgumentClinic() {
      +            return CountNodeClinicProviderGen.INSTANCE;
      +        }
      +
      +        @Specialization
      +        static Object construct(Object cls, Object start, Object step,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached PyNumberCheckNode checkNode,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!isTypeNode.execute(inliningTarget, cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +            if (!checkNode.execute(inliningTarget, start)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, NUMBER_IS_REQUIRED);
      +            }
      +            if (!checkNode.execute(inliningTarget, step)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, NUMBER_IS_REQUIRED);
      +            }
      +            PCount self = PFactory.createCount(language, cls, getInstanceShape.execute(cls));
      +            self.setCnt(start);
      +            self.setStep(step);
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -92,20 +143,19 @@ static Object iter(PCount self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization
               static Object next(VirtualFrame frame, PCount self,
      -                        @Bind("this") Node inliningTarget,
                               @Cached PyNumberAddNode addNode) {
                   Object cnt = self.getCnt();
      -            self.setCnt(addNode.execute(frame, inliningTarget, self.getCnt(), self.getStep()));
      +            self.setCnt(addNode.execute(frame, self.getCnt(), self.getStep()));
                   return cnt;
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           public abstract static class ReprNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -140,16 +190,16 @@ static Object reducePos(PCount self,
                               @Cached CastToJavaLongExactNode castLongNode,
                               @Cached PyObjectTypeCheck typeCheckNode,
                               @Cached InlinedConditionProfile hasDefaultStep,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClassNode.execute(inliningTarget, self);
                   PTuple tuple;
                   if (hasDefaultStep.profile(inliningTarget,
                                   !typeCheckNode.execute(inliningTarget, self.getStep(), PythonBuiltinClassType.PInt) || castLongNode.execute(inliningTarget, self.getStep()) != 1)) {
      -                tuple = factory.createTuple(new Object[]{self.getCnt(), self.getStep()});
      +                tuple = PFactory.createTuple(language, new Object[]{self.getCnt(), self.getStep()});
                   } else {
      -                tuple = factory.createTuple(new Object[]{self.getCnt()});
      +                tuple = PFactory.createTuple(language, new Object[]{self.getCnt()});
                   }
      -            return factory.createTuple(new Object[]{type, tuple});
      +            return PFactory.createTuple(language, new Object[]{type, tuple});
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CycleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CycleBuiltins.java
      index 5a4955219f..7c87288434 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CycleBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CycleBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -43,8 +43,6 @@
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
       import static com.oracle.graal.python.nodes.ErrorMessages.IS_NOT_A;
       import static com.oracle.graal.python.nodes.ErrorMessages.STATE_ARGUMENT_D_MUST_BE_A_S;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SETSTATE__;
      @@ -53,35 +51,44 @@
       import java.util.Arrays;
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ToArrayNode;
      +import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.list.PList;
      -import com.oracle.graal.python.builtins.objects.object.PythonObject;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
       import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins.GetItemNode;
       import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins.LenNode;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
      +import com.oracle.graal.python.lib.IteratorExhausted;
      +import com.oracle.graal.python.lib.PyIterNextNode;
       import com.oracle.graal.python.lib.PyNumberAsSizeNode;
       import com.oracle.graal.python.lib.PyObjectGetIter;
       import com.oracle.graal.python.lib.PyObjectLookupAttr;
      +import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Cached.Exclusive;
      -import com.oracle.truffle.api.dsl.Cached.Shared;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
      @@ -92,12 +99,47 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PCycle})
       public final class CycleBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = CycleBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return CycleBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "cycle", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class CycleNode extends PythonVarargsBuiltinNode {
      +
      +        @Specialization
      +        static PCycle construct(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode,
      +                        @Cached PyObjectGetIter getIter,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!isTypeNode.execute(inliningTarget, cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +            if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "cycle()");
      +            }
      +            if (args.length != 1) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_EXPECTED_D_ARGS, "cycle", 1);
      +            }
      +            Object iterable = args[0];
      +            PCycle self = PFactory.createCycle(language, cls, getInstanceShape.execute(cls));
      +            self.setSaved(new ArrayList<>());
      +            self.setIterable(getIter.execute(frame, inliningTarget, iterable));
      +            self.setIndex(0);
      +            self.setFirstpass(false);
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -106,33 +148,30 @@ static Object iter(PCycle self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization
               static Object next(VirtualFrame frame, PCycle self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached BuiltinFunctions.NextNode nextNode,
      -                        @Cached IsBuiltinObjectProfile isStopIterationProfile,
      +                        @Cached PyIterNextNode nextNode,
                               @Cached InlinedBranchProfile iterableProfile,
      -                        @Cached InlinedBranchProfile firstPassProfile,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached InlinedBranchProfile firstPassProfile) {
                   if (self.getIterable() != null) {
                       iterableProfile.enter(inliningTarget);
                       try {
      -                    Object item = nextNode.execute(frame, self.getIterable(), PNone.NO_VALUE);
      +                    Object item = nextNode.execute(frame, inliningTarget, self.getIterable());
                           if (!self.isFirstpass()) {
                               firstPassProfile.enter(inliningTarget);
                               add(self.getSaved(), item);
                           }
                           return item;
      -                } catch (PException e) {
      -                    e.expectStopIteration(inliningTarget, isStopIterationProfile);
      +                } catch (IteratorExhausted e) {
                           self.setIterable(null);
                       }
                   }
                   if (isEmpty(self.getSaved())) {
      -                throw raiseNode.get(inliningTarget).raiseStopIteration();
      +                throw iteratorExhausted();
                   }
                   Object item = get(self.getSaved(), self.getIndex());
                   self.setIndex(self.getIndex() + 1);
      @@ -170,11 +209,11 @@ public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
               static Object reduce(PCycle self,
                               @Bind("this") Node inliningTarget,
                               @Exclusive @Cached GetClassNode getClass,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClass.execute(inliningTarget, self);
      -            PTuple iterableTuple = factory.createTuple(new Object[]{self.getIterable()});
      -            PTuple tuple = factory.createTuple(new Object[]{getSavedList(self, factory), self.isFirstpass()});
      -            return factory.createTuple(new Object[]{type, iterableTuple, tuple});
      +            PTuple iterableTuple = PFactory.createTuple(language, new Object[]{self.getIterable()});
      +            PTuple tuple = PFactory.createTuple(language, new Object[]{getSavedList(self, language), self.isFirstpass()});
      +            return PFactory.createTuple(language, new Object[]{type, iterableTuple, tuple});
               }
       
               @Specialization(guards = "!hasIterable(self)")
      @@ -185,22 +224,22 @@ static Object reduceNoIterable(VirtualFrame frame, PCycle self,
                               @Cached CallUnaryMethodNode callNode,
                               @Cached PyObjectGetIter getIterNode,
                               @Cached InlinedBranchProfile indexProfile,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClass.execute(inliningTarget, self);
      -            PList savedList = getSavedList(self, factory);
      +            PList savedList = getSavedList(self, language);
                   Object it = getIterNode.execute(frame, inliningTarget, savedList);
                   if (self.getIndex() > 0) {
                       indexProfile.enter(inliningTarget);
                       Object setStateCallable = lookupAttrNode.execute(frame, inliningTarget, it, T___SETSTATE__);
                       callNode.executeObject(frame, setStateCallable, self.getIndex());
                   }
      -            PTuple iteratorTuple = factory.createTuple(new Object[]{it});
      -            PTuple tuple = factory.createTuple(new Object[]{savedList, true});
      -            return factory.createTuple(new Object[]{type, iteratorTuple, tuple});
      +            PTuple iteratorTuple = PFactory.createTuple(language, new Object[]{it});
      +            PTuple tuple = PFactory.createTuple(language, new Object[]{savedList, true});
      +            return PFactory.createTuple(language, new Object[]{type, iteratorTuple, tuple});
               }
       
      -        static PList getSavedList(PCycle self, PythonObjectFactory factory) {
      -            return factory.createList(toArray(self.getSaved()));
      +        static PList getSavedList(PCycle self, PythonLanguage language) {
      +            return PFactory.createList(language, toArray(self.getSaved()));
               }
       
               @TruffleBoundary
      @@ -216,8 +255,6 @@ protected boolean hasIterable(PCycle self) {
           @Builtin(name = J___SETSTATE__, minNumOfPositionalArgs = 2)
           @GenerateNodeFactory
           public abstract static class SetStateNode extends PythonBinaryBuiltinNode {
      -        abstract Object execute(VirtualFrame frame, PythonObject self, Object state);
      -
               @Specialization
               static Object setState(VirtualFrame frame, PCycle self, Object state,
                               @Bind("this") Node inliningTarget,
      @@ -226,13 +263,13 @@ static Object setState(VirtualFrame frame, PCycle self, Object state,
                               @Cached IsBuiltinObjectProfile isTypeErrorProfile,
                               @Cached ToArrayNode toArrayNode,
                               @Cached PyNumberAsSizeNode asSizeNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (!((state instanceof PTuple) && ((int) lenNode.execute(frame, state) == 2))) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, IS_NOT_A, "state", "2-tuple");
      +                throw raiseNode.raise(inliningTarget, TypeError, IS_NOT_A, "state", "2-tuple");
                   }
                   Object obj = getItemNode.execute(frame, state, 0);
                   if (!(obj instanceof PList)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, STATE_ARGUMENT_D_MUST_BE_A_S, 1, "Plist");
      +                throw raiseNode.raise(inliningTarget, TypeError, STATE_ARGUMENT_D_MUST_BE_A_S, 1, "Plist");
                   }
                   PList saved = (PList) obj;
       
      @@ -241,7 +278,7 @@ static Object setState(VirtualFrame frame, PCycle self, Object state,
                       firstPass = asSizeNode.executeLossy(frame, inliningTarget, getItemNode.execute(frame, state, 1)) != 0;
                   } catch (PException e) {
                       e.expectTypeError(inliningTarget, isTypeErrorProfile);
      -                throw raiseNode.get(inliningTarget).raise(TypeError, STATE_ARGUMENT_D_MUST_BE_A_S, 2, "int");
      +                throw raiseNode.raise(inliningTarget, TypeError, STATE_ARGUMENT_D_MUST_BE_A_S, 2, "int");
                   }
       
                   Object[] savedArray = toArrayNode.execute(inliningTarget, saved.getSequenceStorage());
      @@ -256,5 +293,4 @@ private static ArrayList toList(Object[] savedArray) {
                   return new ArrayList<>(Arrays.asList(savedArray));
               }
           }
      -
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/DropwhileBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/DropwhileBuiltins.java
      index f25a0b534a..273a8b3db5 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/DropwhileBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/DropwhileBuiltins.java
      @@ -40,33 +40,45 @@
        */
       package com.oracle.graal.python.builtins.objects.itertools;
       
      +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError;
       import static com.oracle.graal.python.nodes.ErrorMessages.INVALID_ARGS;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SETSTATE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
       import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
      +import com.oracle.graal.python.lib.PyObjectGetIter;
       import com.oracle.graal.python.lib.PyObjectIsTrueNode;
      +import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.call.CallNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToJavaBooleanNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -80,12 +92,46 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PDropwhile})
       public final class DropwhileBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = DropwhileBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return DropwhileBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "dropwhile", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class DropwhileNode extends PythonVarargsBuiltinNode {
      +        @Specialization
      +        static PDropwhile construct(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode,
      +                        @Cached PyObjectGetIter getIter,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!isTypeNode.execute(inliningTarget, cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +            if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "dropwhile()");
      +            }
      +            if (args.length != 2) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_EXPECTED_D_ARGS, "dropwhile", 2);
      +            }
      +            Object predicate = args[0];
      +            Object iterable = args[1];
      +            PDropwhile self = PFactory.createDropwhile(language, cls, getInstanceShape.execute(cls));
      +            self.setPredicate(predicate);
      +            self.setIterable(getIter.execute(frame, inliningTarget, iterable));
      +            self.setDoneDropping(false);
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -94,27 +140,32 @@ static Object iter(PDropwhile self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization
               static Object next(VirtualFrame frame, PDropwhile self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached BuiltinFunctions.NextNode nextNode,
      +                        @Cached GetObjectSlotsNode getSlots,
      +                        @Cached CallSlotTpIterNextNode callIterNext,
                               @Cached CallNode callNode,
                               @Cached PyObjectIsTrueNode isTrue,
                               @Cached InlinedBranchProfile doneDroppingProfile,
                               @Cached InlinedLoopConditionProfile loopProfile) {
      -
      -            while (loopProfile.profile(inliningTarget, !self.isDoneDropping())) {
      -                Object n = nextNode.execute(frame, self.getIterable(), PNone.NO_VALUE);
      -                if (!isTrue.execute(frame, callNode.execute(frame, self.getPredicate(), n))) {
      +            Object iterable = self.getIterable();
      +            TpSlot iterNext = getSlots.execute(inliningTarget, iterable).tp_iternext();
      +            Object result = null;
      +            do {
      +                Object item = callIterNext.execute(frame, inliningTarget, iterNext, iterable);
      +                if (self.isDoneDropping()) {
      +                    result = item;
      +                } else if (!isTrue.execute(frame, callNode.execute(frame, self.getPredicate(), item))) {
                           doneDroppingProfile.enter(inliningTarget);
                           self.setDoneDropping(true);
      -                    return n;
      +                    result = item;
                       }
      -            }
      -            return nextNode.execute(frame, self.getIterable(), PNone.NO_VALUE);
      +            } while (loopProfile.profile(inliningTarget, result == null));
      +            return result;
               }
           }
       
      @@ -125,10 +176,10 @@ public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
               static Object reduce(PDropwhile self,
                               @Bind("this") Node inliningTarget,
                               @Cached GetClassNode getClassNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClassNode.execute(inliningTarget, self);
      -            PTuple tuple = factory.createTuple(new Object[]{self.getPredicate(), self.getIterable()});
      -            return factory.createTuple(new Object[]{type, tuple, self.isDoneDropping()});
      +            PTuple tuple = PFactory.createTuple(language, new Object[]{self.getPredicate(), self.getIterable()});
      +            return PFactory.createTuple(language, new Object[]{type, tuple, self.isDoneDropping()});
               }
           }
       
      @@ -139,14 +190,13 @@ public abstract static class SetStateNode extends PythonBinaryBuiltinNode {
               static Object setState(PDropwhile self, Object state,
                               @Bind("this") Node inliningTarget,
                               @Cached CastToJavaBooleanNode castToBoolean,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   try {
                       self.setDoneDropping(castToBoolean.execute(inliningTarget, state));
                   } catch (CannotCastException e) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, INVALID_ARGS, T___SETSTATE__);
      +                throw raiseNode.raise(inliningTarget, ValueError, INVALID_ARGS, T___SETSTATE__);
                   }
                   return PNone.NONE;
               }
           }
      -
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/FilterfalseBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/FilterfalseBuiltins.java
      index f38bbacfcf..250c674075 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/FilterfalseBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/FilterfalseBuiltins.java
      @@ -40,28 +40,41 @@
        */
       package com.oracle.graal.python.builtins.objects.itertools;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
      +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
       import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
      +import com.oracle.graal.python.lib.PyObjectGetIter;
       import com.oracle.graal.python.lib.PyObjectIsTrueNode;
      +import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.PGuards;
      +import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.call.CallNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.object.GetClassNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      -import com.oracle.truffle.api.dsl.Cached.Shared;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
      @@ -73,12 +86,46 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PFilterfalse})
       public final class FilterfalseBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = FilterfalseBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return FilterfalseBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "filterfalse", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class FilterFalseNode extends PythonVarargsBuiltinNode {
      +
      +        @Specialization
      +        static PFilterfalse construct(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode,
      +                        @Cached PyObjectGetIter getIter,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!isTypeNode.execute(inliningTarget, cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +            if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "filterfalse()");
      +            }
      +            if (args.length != 2) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_EXPECTED_D_ARGS, "filterfalse", 2);
      +            }
      +            Object func = args[0];
      +            Object sequence = args[1];
      +            PFilterfalse self = PFactory.createFilterfalse(language, cls, getInstanceShape.execute(cls));
      +            self.setFunc(PGuards.isPNone(func) ? null : func);
      +            self.setSequence(getIter.execute(frame, inliningTarget, sequence));
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -87,38 +134,33 @@ static Object iter(PFilterfalse self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      -        @Specialization(guards = "hasFunc(self)")
      +    public abstract static class NextNode extends TpIterNextBuiltin {
      +        @Specialization
               static Object next(VirtualFrame frame, PFilterfalse self,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached BuiltinFunctions.NextNode nextNode,
      +                        @Cached GetObjectSlotsNode getSlots,
      +                        @Cached CallSlotTpIterNextNode callIterNext,
                               @Cached CallNode callNode,
      -                        @Shared @Cached PyObjectIsTrueNode isTrue,
      -                        @Shared @Cached InlinedLoopConditionProfile loopConditionProfile) {
      -            Object n;
      -            do {
      -                n = nextNode.execute(frame, self.getSequence(), PNone.NO_VALUE);
      -            } while (loopConditionProfile.profile(inliningTarget, isTrue.execute(frame, callNode.execute(frame, self.getFunc(), n))));
      -            return n;
      -        }
      -
      -        @Specialization(guards = "!hasFunc(self)")
      -        static Object nextNoFunc(VirtualFrame frame, PFilterfalse self,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared @Cached BuiltinFunctions.NextNode nextNode,
      -                        @Shared @Cached PyObjectIsTrueNode isTrue,
      -                        @Shared @Cached InlinedLoopConditionProfile loopConditionProfile) {
      -            Object n;
      +                        @Cached PyObjectIsTrueNode isTrue,
      +                        @Cached InlinedConditionProfile hasFuncProfile,
      +                        @Cached InlinedLoopConditionProfile loopConditionProfile) {
      +            Object sequence = self.getSequence();
      +            TpSlot iterNext = getSlots.execute(inliningTarget, sequence).tp_iternext();
      +            Object func = self.getFunc();
      +            boolean hasFunc = hasFuncProfile.profile(inliningTarget, func != null);
      +            Object result;
      +            boolean cont;
                   do {
      -                n = nextNode.execute(frame, self.getSequence(), PNone.NO_VALUE);
      -            } while (loopConditionProfile.profile(inliningTarget, isTrue.execute(frame, n)));
      -            return n;
      -        }
      -
      -        protected boolean hasFunc(PFilterfalse self) {
      -            return self.getFunc() != null;
      +                result = callIterNext.execute(frame, inliningTarget, iterNext, sequence);
      +                Object good = result;
      +                if (hasFunc) {
      +                    good = callNode.execute(frame, func, result);
      +                }
      +                cont = isTrue.execute(frame, good);
      +            } while (loopConditionProfile.profile(inliningTarget, cont));
      +            return result;
               }
           }
       
      @@ -130,15 +172,14 @@ Object reduce(PFilterfalse self,
                               @Bind("this") Node inliningTarget,
                               @Cached InlinedConditionProfile hasNoFuncProfile,
                               @Cached GetClassNode getClassNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object func = self.getFunc();
                   if (hasNoFuncProfile.profile(inliningTarget, func == null)) {
                       func = PNone.NONE;
                   }
                   Object type = getClassNode.execute(inliningTarget, self);
      -            PTuple tuple = factory.createTuple(new Object[]{func, self.getSequence()});
      -            return factory.createTuple(new Object[]{type, tuple});
      +            PTuple tuple = PFactory.createTuple(language, new Object[]{func, self.getSequence()});
      +            return PFactory.createTuple(language, new Object[]{type, tuple});
               }
           }
      -
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GroupByBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GroupByBuiltins.java
      index a00f7d7545..530655ee00 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GroupByBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GroupByBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -42,29 +42,41 @@
       
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
       import static com.oracle.graal.python.nodes.ErrorMessages.IS_NOT_A;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.ArgumentClinic;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
       import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.itertools.GroupByBuiltinsClinicProviders.GroupByNodeClinicProviderGen;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
       import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
      +import com.oracle.graal.python.lib.PyIterNextNode;
      +import com.oracle.graal.python.lib.PyObjectGetIter;
       import com.oracle.graal.python.lib.PyObjectRichCompareBool;
      +import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.call.CallNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
       import com.oracle.graal.python.nodes.object.GetClassNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -79,12 +91,43 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PGroupBy})
       public final class GroupByBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = GroupByBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return GroupByBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "groupby", minNumOfPositionalArgs = 2, parameterNames = {"cls", "iterable", "key"})
      +    @ArgumentClinic(name = "key", defaultValue = "PNone.NONE")
      +    @GenerateNodeFactory
      +    public abstract static class GroupByNode extends PythonTernaryClinicBuiltinNode {
      +
      +        @Override
      +        protected ArgumentClinicProvider getArgumentClinic() {
      +            return GroupByNodeClinicProviderGen.INSTANCE;
      +        }
      +
      +        @Specialization
      +        static PGroupBy construct(VirtualFrame frame, Object cls, Object iterable, Object key,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached PyObjectGetIter getIter,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!isTypeNode.execute(inliningTarget, cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +            PGroupBy self = PFactory.createGroupBy(language, cls, getInstanceShape.execute(cls));
      +            self.setKeyFunc(PGuards.isNone(key) ? null : key);
      +            self.setIt(getIter.execute(frame, inliningTarget, iterable));
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -93,36 +136,36 @@ static Object iter(PGroupBy self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization
               static Object next(VirtualFrame frame, PGroupBy self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached BuiltinFunctions.NextNode nextNode,
      +                        @Cached PyIterNextNode nextNode,
                               @Cached CallNode callNode,
      -                        @Cached PyObjectRichCompareBool.EqNode eqNode,
      +                        @Cached PyObjectRichCompareBool eqNode,
                               @Cached InlinedBranchProfile eqProfile,
                               @Cached InlinedConditionProfile hasFuncProfile,
                               @Cached InlinedLoopConditionProfile loopConditionProfile,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   self.setCurrGrouper(null);
                   while (loopConditionProfile.profile(inliningTarget, doGroupByStep(frame, inliningTarget, self, eqProfile, eqNode))) {
                       self.groupByStep(frame, inliningTarget, nextNode, callNode, hasFuncProfile);
                   }
                   self.setTgtKey(self.getCurrKey());
      -            PGrouper grouper = factory.createGrouper(self, self.getTgtKey());
      -            return factory.createTuple(new Object[]{self.getCurrKey(), grouper});
      +            PGrouper grouper = PFactory.createGrouper(language, self, self.getTgtKey());
      +            return PFactory.createTuple(language, new Object[]{self.getCurrKey(), grouper});
               }
       
      -        private static boolean doGroupByStep(VirtualFrame frame, Node inliningTarget, PGroupBy self, InlinedBranchProfile eqProfile, PyObjectRichCompareBool.EqNode eqNode) {
      +        private static boolean doGroupByStep(VirtualFrame frame, Node inliningTarget, PGroupBy self, InlinedBranchProfile eqProfile, PyObjectRichCompareBool eqNode) {
                   if (self.getCurrKey() == null) {
                       return true;
                   } else if (self.getTgtKey() == null) {
                       return false;
                   } else {
                       eqProfile.enter(inliningTarget);
      -                if (!eqNode.compare(frame, inliningTarget, self.getTgtKey(), self.getCurrKey())) {
      +                if (!eqNode.executeEq(frame, inliningTarget, self.getTgtKey(), self.getCurrKey())) {
                           return false;
                       }
                   }
      @@ -139,18 +182,18 @@ static Object reduceMarkerNotSet(PGroupBy self,
                               @Cached InlinedConditionProfile noKeyFuncProfile,
                               @Cached InlinedConditionProfile noValuesProfile,
                               @Cached GetClassNode getClassNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object keyFunc = self.getKeyFunc();
                   if (noKeyFuncProfile.profile(inliningTarget, keyFunc == null)) {
                       keyFunc = PNone.NONE;
                   }
                   Object type = getClassNode.execute(inliningTarget, self);
      -            PTuple tuple1 = factory.createTuple(new Object[]{self.getIt(), keyFunc});
      +            PTuple tuple1 = PFactory.createTuple(language, new Object[]{self.getIt(), keyFunc});
                   if (noValuesProfile.profile(inliningTarget, !valuesSet(self))) {
      -                return factory.createTuple(new Object[]{type, tuple1});
      +                return PFactory.createTuple(language, new Object[]{type, tuple1});
                   }
      -            PTuple tuple2 = factory.createTuple(new Object[]{self.getCurrValue(), self.getTgtKey(), self.getCurrKey()});
      -            return factory.createTuple(new Object[]{type, tuple1, tuple2});
      +            PTuple tuple2 = PFactory.createTuple(language, new Object[]{self.getCurrValue(), self.getTgtKey(), self.getCurrKey()});
      +            return PFactory.createTuple(language, new Object[]{type, tuple1, tuple2});
               }
       
               private static boolean valuesSet(PGroupBy self) {
      @@ -167,9 +210,9 @@ static Object setState(VirtualFrame frame, PGroupBy self, Object state,
                               @Bind("this") Node inliningTarget,
                               @Cached TupleBuiltins.LenNode lenNode,
                               @Cached TupleBuiltins.GetItemNode getItemNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (!(state instanceof PTuple) || (int) lenNode.execute(frame, state) != 3) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, IS_NOT_A, "state", "3-tuple");
      +                throw raiseNode.raise(inliningTarget, TypeError, IS_NOT_A, "state", "3-tuple");
                   }
       
                   Object currValue = getItemNode.execute(frame, state, 0);
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GrouperBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GrouperBuiltins.java
      index 527efebabd..d50c11d35e 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GrouperBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GrouperBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,32 +40,39 @@
        */
       package com.oracle.graal.python.builtins.objects.itertools;
       
      +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
       import static com.oracle.graal.python.nodes.BuiltinNames.T_ITER;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
       import com.oracle.graal.python.builtins.objects.module.PythonModule;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
      +import com.oracle.graal.python.lib.PyIterNextNode;
       import com.oracle.graal.python.lib.PyObjectGetAttr;
       import com.oracle.graal.python.lib.PyObjectRichCompareBool;
       import com.oracle.graal.python.nodes.BuiltinNames;
      +import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.call.CallNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.object.GetClassNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      -import com.oracle.truffle.api.dsl.Cached.Shared;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
      @@ -77,12 +84,36 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PGrouper})
       public final class GrouperBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = GrouperBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return GrouperBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "_grouper", minNumOfPositionalArgs = 2, parameterNames = {"$self", "parent", "tgtkey"})
      +    @GenerateNodeFactory
      +    public abstract static class GrouperNode extends PythonTernaryBuiltinNode {
      +        @Specialization
      +        static PGrouper construct(Object cls, Object parent, Object tgtKey,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached InlinedConditionProfile wrongTypeProfile,
      +                        @Cached InlinedConditionProfile isPGroupByProfile,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!wrongTypeProfile.profile(inliningTarget, isTypeNode.execute(inliningTarget, cls))) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +            if (!isPGroupByProfile.profile(inliningTarget, parent instanceof PGroupBy)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.INCORRECT_USAGE_OF_INTERNAL_GROUPER);
      +            }
      +            return PFactory.createGrouper(language, (PGroupBy) parent, tgtKey);
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -91,32 +122,31 @@ static Object iter(PGrouper self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization
               static Object next(VirtualFrame frame, PGrouper self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached BuiltinFunctions.NextNode nextNode,
      +                        @Cached PyIterNextNode nextNode,
                               @Cached CallNode callNode,
      -                        @Cached PyObjectRichCompareBool.EqNode eqNode,
      +                        @Cached PyObjectRichCompareBool eqNode,
                               @Cached InlinedBranchProfile currGrouperProfile,
                               @Cached InlinedBranchProfile currValueMarkerProfile,
                               @Cached InlinedBranchProfile currValueTgtProfile,
      -                        @Cached InlinedConditionProfile hasFuncProfile,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached InlinedConditionProfile hasFuncProfile) {
                   PGroupBy gbo = self.getParent();
                   if (gbo.getCurrGrouper() != self) {
                       currGrouperProfile.enter(inliningTarget);
      -                throw raiseNode.get(inliningTarget).raiseStopIteration();
      +                throw iteratorExhausted();
                   }
                   if (gbo.getCurrValue() == null) {
                       currValueMarkerProfile.enter(inliningTarget);
                       gbo.groupByStep(frame, inliningTarget, nextNode, callNode, hasFuncProfile);
                   }
      -            if (!eqNode.compare(frame, inliningTarget, self.getTgtKey(), gbo.getCurrKey())) {
      +            if (!eqNode.executeEq(frame, inliningTarget, self.getTgtKey(), gbo.getCurrKey())) {
                       currValueTgtProfile.enter(inliningTarget);
      -                throw raiseNode.get(inliningTarget).raiseStopIteration();
      +                throw iteratorExhausted();
                   }
                   Object r = gbo.getCurrValue();
                   gbo.setCurrValue(null);
      @@ -131,21 +161,21 @@ public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
               static Object reduce(PGrouper self,
                               @Bind("this") Node inliningTarget,
                               @Cached GetClassNode getClassNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClassNode.execute(inliningTarget, self);
      -            PTuple tuple = factory.createTuple(new Object[]{self.getParent(), self.getTgtKey()});
      -            return factory.createTuple(new Object[]{type, tuple});
      +            PTuple tuple = PFactory.createTuple(language, new Object[]{self.getParent(), self.getTgtKey()});
      +            return PFactory.createTuple(language, new Object[]{type, tuple});
               }
       
               @Specialization(guards = "!currValueIsSelf(self)")
               Object reduceCurrNotSelf(VirtualFrame frame, @SuppressWarnings("unused") PGrouper self,
                               @Bind("this") Node inliningTarget,
                               @Cached PyObjectGetAttr getAttrNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   PythonModule builtins = getContext().getCore().lookupBuiltinModule(BuiltinNames.T_BUILTINS);
                   Object iterCallable = getAttrNode.execute(frame, inliningTarget, builtins, T_ITER);
                   // return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter));
      -            return factory.createTuple(new Object[]{iterCallable, factory.createTuple(new Object[]{factory.createEmptyTuple()})});
      +            return PFactory.createTuple(language, new Object[]{iterCallable, PFactory.createTuple(language, new Object[]{PFactory.createEmptyTuple(language)})});
               }
       
               protected boolean currValueIsSelf(PGrouper self) {
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/IsliceBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/IsliceBuiltins.java
      index bcc61d9783..68aa0c3b81 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/IsliceBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/IsliceBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,54 +40,180 @@
        */
       package com.oracle.graal.python.builtins.objects.itertools;
       
      +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.OverflowError;
      +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError;
       import static com.oracle.graal.python.nodes.ErrorMessages.INVALID_ARGS;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
      +import static com.oracle.graal.python.nodes.ErrorMessages.ISLICE_WRONG_ARGS;
      +import static com.oracle.graal.python.nodes.ErrorMessages.STEP_FOR_ISLICE_MUST_BE;
      +import static com.oracle.graal.python.nodes.ErrorMessages.S_FOR_ISLICE_MUST_BE;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SETSTATE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
      +import com.oracle.graal.python.builtins.modules.SysModuleBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
      +import com.oracle.graal.python.lib.IteratorExhausted;
      +import com.oracle.graal.python.lib.PyNumberAsSizeNode;
       import com.oracle.graal.python.lib.PyObjectGetIter;
      +import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToJavaIntLossyNode;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Cached.Exclusive;
      -import com.oracle.truffle.api.dsl.Cached.Shared;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
       import com.oracle.truffle.api.profiles.InlinedBranchProfile;
      +import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile;
       
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PIslice})
       public final class IsliceBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = IsliceBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return IsliceBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "islice", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class IsliceNode extends PythonVarargsBuiltinNode {
      +        @Specialization
      +        static Object constructOne(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode,
      +                        @Cached PyObjectGetIter getIter,
      +                        @Cached PyNumberAsSizeNode asIntNode,
      +                        @Cached InlinedBranchProfile hasStart,
      +                        @Cached InlinedBranchProfile hasStop,
      +                        @Cached InlinedBranchProfile hasStep,
      +                        @Cached InlinedBranchProfile stopNotInt,
      +                        @Cached InlinedBranchProfile startNotInt,
      +                        @Cached InlinedBranchProfile stopWrongValue,
      +                        @Cached InlinedBranchProfile stepWrongValue,
      +                        @Cached InlinedBranchProfile wrongValue,
      +                        @Cached InlinedBranchProfile overflowBranch,
      +                        @Cached InlinedConditionProfile argsLen1,
      +                        @Cached InlinedConditionProfile argsLen2,
      +                        @Cached InlinedConditionProfile argsLen3,
      +                        @Cached InlinedBranchProfile wrongTypeBranch,
      +                        @Cached InlinedBranchProfile wrongArgsBranch,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!isTypeNode.execute(inliningTarget, cls)) {
      +                wrongTypeBranch.enter(inliningTarget);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +            if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "islice()");
      +            }
      +            if (args.length < 2 || args.length > 4) {
      +                wrongArgsBranch.enter(inliningTarget);
      +                throw raiseNode.raise(inliningTarget, TypeError, ISLICE_WRONG_ARGS);
      +            }
      +            int start = 0;
      +            int step = 1;
      +            int stop = -1;
      +            if (argsLen1.profile(inliningTarget, args.length == 2)) {
      +                if (args[1] != PNone.NONE) {
      +                    hasStop.enter(inliningTarget);
      +                    try {
      +                        stop = asIntNode.executeExact(frame, inliningTarget, args[1], OverflowError);
      +                    } catch (PException e) {
      +                        stopNotInt.enter(inliningTarget);
      +                        throw raiseNode.raise(inliningTarget, ValueError, S_FOR_ISLICE_MUST_BE, "Indices");
      +                    }
      +                }
      +                if (stop < -1 || stop > SysModuleBuiltins.MAXSIZE) {
      +                    stopWrongValue.enter(inliningTarget);
      +                    throw raiseNode.raise(inliningTarget, ValueError, S_FOR_ISLICE_MUST_BE, "Indices");
      +                }
      +            } else if (argsLen2.profile(inliningTarget, args.length == 3) || argsLen3.profile(inliningTarget, args.length == 4)) {
      +                if (args[1] != PNone.NONE) {
      +                    hasStart.enter(inliningTarget);
      +                    try {
      +                        start = asIntNode.executeExact(frame, inliningTarget, args[1], OverflowError);
      +                    } catch (PException e) {
      +                        startNotInt.enter(inliningTarget);
      +                        throw raiseNode.raise(inliningTarget, ValueError, S_FOR_ISLICE_MUST_BE, "Indices");
      +                    }
      +                }
      +                if (args[2] != PNone.NONE) {
      +                    hasStop.enter(inliningTarget);
      +                    try {
      +                        stop = asIntNode.executeExact(frame, inliningTarget, args[2], OverflowError);
      +                    } catch (PException e) {
      +                        stopNotInt.enter(inliningTarget);
      +                        throw raiseNode.raise(inliningTarget, ValueError, S_FOR_ISLICE_MUST_BE, "Stop argument");
      +                    }
      +                }
      +                if (start < 0 || stop < -1 || start > SysModuleBuiltins.MAXSIZE || stop > SysModuleBuiltins.MAXSIZE) {
      +                    wrongValue.enter(inliningTarget);
      +                    throw raiseNode.raise(inliningTarget, ValueError, S_FOR_ISLICE_MUST_BE, "Indices");
      +                }
      +            }
      +            if (argsLen3.profile(inliningTarget, args.length == 4)) {
      +                if (args[3] != PNone.NONE) {
      +                    hasStep.enter(inliningTarget);
      +                    try {
      +                        step = asIntNode.executeExact(frame, inliningTarget, args[3], OverflowError);
      +                    } catch (PException e) {
      +                        overflowBranch.enter(inliningTarget);
      +                        step = -1;
      +                    }
      +                }
      +                if (step < 1) {
      +                    stepWrongValue.enter(inliningTarget);
      +                    throw raiseNode.raise(inliningTarget, ValueError, STEP_FOR_ISLICE_MUST_BE);
      +                }
      +            }
      +            Object iterable = args[0];
      +            PIslice self = PFactory.createIslice(language, cls, getInstanceShape.execute(cls));
      +            self.setIterable(getIter.execute(frame, inliningTarget, iterable));
      +            self.setNext(start);
      +            self.setStop(stop);
      +            self.setStep(step);
      +            self.setCnt(0);
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -96,57 +222,47 @@ static Object iter(PIslice self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization(guards = "isNone(self.getIterable())")
      -        static Object next(@SuppressWarnings("unused") PIslice self,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raiseStopIteration();
      +        static Object next(@SuppressWarnings("unused") PIslice self) {
      +            throw iteratorExhausted();
               }
       
               @Specialization(guards = "!isNone(self.getIterable())")
               static Object next(VirtualFrame frame, PIslice self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached BuiltinFunctions.NextNode nextNode,
      +                        @Cached GetObjectSlotsNode getSlots,
      +                        @Cached CallSlotTpIterNextNode callIterNext,
                               @Cached InlinedLoopConditionProfile loopProfile,
      -                        @Cached InlinedBranchProfile nextExceptionProfile,
      -                        @Cached InlinedBranchProfile nextExceptionProfile2,
      -                        @Cached InlinedBranchProfile setNextProfile,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached InlinedBranchProfile setNextProfile) {
                   Object it = self.getIterable();
      +            TpSlot iterNext = getSlots.execute(inliningTarget, it).tp_iternext();
                   int stop = self.getStop();
                   Object item;
      -            while (loopProfile.profile(inliningTarget, self.getCnt() < self.getNext())) {
      -                try {
      -                    item = nextNode.execute(frame, it, PNone.NO_VALUE);
      -                } catch (PException e) {
      -                    nextExceptionProfile.enter(inliningTarget);
      -                    // C code uses any exception to clear the iterator
      +            try {
      +                while (loopProfile.profile(inliningTarget, self.getCnt() < self.getNext())) {
      +                    callIterNext.execute(frame, inliningTarget, iterNext, it);
      +                    self.setCnt(self.getCnt() + 1);
      +                }
      +                if (stop != -1 && self.getCnt() >= stop) {
                           self.setIterable(PNone.NONE);
      -                    throw e;
      +                    throw iteratorExhausted();
                       }
      +                item = callIterNext.execute(frame, inliningTarget, iterNext, it);
                       self.setCnt(self.getCnt() + 1);
      -            }
      -            if (stop != -1 && self.getCnt() >= stop) {
      -                self.setIterable(PNone.NONE);
      -                throw raiseNode.get(inliningTarget).raiseStopIteration();
      -            }
      -            try {
      -                item = nextNode.execute(frame, it, PNone.NO_VALUE);
      -            } catch (PException e) {
      -                nextExceptionProfile2.enter(inliningTarget);
      +                int oldNext = self.getNext();
      +                self.setNext(self.getNext() + self.getStep());
      +                if (self.getNext() < oldNext || (stop != -1 && self.getNext() > stop)) {
      +                    setNextProfile.enter(inliningTarget);
      +                    self.setNext(stop);
      +                }
      +                return item;
      +            } catch (IteratorExhausted | PException e) {
                       self.setIterable(PNone.NONE);
                       throw e;
                   }
      -            self.setCnt(self.getCnt() + 1);
      -            int oldNext = self.getNext();
      -            self.setNext(self.getNext() + self.getStep());
      -            if (self.getNext() < oldNext || (stop != -1 && self.getNext() > stop)) {
      -                setNextProfile.enter(inliningTarget);
      -                self.setNext(stop);
      -            }
      -            return item;
               }
           }
       
      @@ -158,22 +274,22 @@ static Object reduceNoIterable(VirtualFrame frame, PIslice self,
                               @Bind("this") Node inliningTarget,
                               @Exclusive @Cached GetClassNode getClassNode,
                               @Cached PyObjectGetIter getIter,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   // return type(self), (iter([]), 0), 0
                   Object type = getClassNode.execute(inliningTarget, self);
      -            PTuple tuple = factory.createTuple(new Object[]{getIter.execute(frame, inliningTarget, factory.createList()), 0});
      -            return factory.createTuple(new Object[]{type, tuple, 0});
      +            PTuple tuple = PFactory.createTuple(language, new Object[]{getIter.execute(frame, inliningTarget, PFactory.createList(language)), 0});
      +            return PFactory.createTuple(language, new Object[]{type, tuple, 0});
               }
       
               @Specialization(guards = "!isNone(self.getIterable())")
               static Object reduce(PIslice self,
                               @Bind("this") Node inliningTarget,
                               @Exclusive @Cached GetClassNode getClassNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClassNode.execute(inliningTarget, self);
                   Object stop = (self.getStop() == -1) ? PNone.NONE : self.getStop();
      -            PTuple tuple = factory.createTuple(new Object[]{self.getIterable(), self.getNext(), stop, self.getStep()});
      -            return factory.createTuple(new Object[]{type, tuple, self.getCnt()});
      +            PTuple tuple = PFactory.createTuple(language, new Object[]{self.getIterable(), self.getNext(), stop, self.getStep()});
      +            return PFactory.createTuple(language, new Object[]{type, tuple, self.getCnt()});
               }
           }
       
      @@ -184,14 +300,13 @@ public abstract static class SetStateNode extends PythonBinaryBuiltinNode {
               static Object setState(PIslice self, Object state,
                               @Bind("this") Node inliningTarget,
                               @Cached CastToJavaIntLossyNode castInt,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   try {
                       self.setCnt(castInt.execute(inliningTarget, state));
                   } catch (CannotCastException e) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, INVALID_ARGS, T___SETSTATE__);
      +                throw raiseNode.raise(inliningTarget, ValueError, INVALID_ARGS, T___SETSTATE__);
                   }
                   return PNone.NONE;
               }
           }
      -
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PGroupBy.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PGroupBy.java
      index 9ab040d504..1d7b90b5f5 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PGroupBy.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PGroupBy.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,9 +40,8 @@
        */
       package com.oracle.graal.python.builtins.objects.itertools;
       
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
      -import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
      +import com.oracle.graal.python.lib.PyIterNextNode;
       import com.oracle.graal.python.nodes.call.CallNode;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
      @@ -110,8 +109,8 @@ public void setCurrKey(Object currKey) {
               this.currKey = currKey;
           }
       
      -    void groupByStep(VirtualFrame frame, Node inliningTarget, BuiltinFunctions.NextNode nextNode, CallNode callNode, InlinedConditionProfile hasFuncProfile) {
      -        Object newValue = nextNode.execute(frame, it, PNone.NO_VALUE);
      +    void groupByStep(VirtualFrame frame, Node inliningTarget, PyIterNextNode nextNode, CallNode callNode, InlinedConditionProfile hasFuncProfile) {
      +        Object newValue = nextNode.execute(frame, inliningTarget, it);
               Object newKey;
               if (hasFuncProfile.profile(inliningTarget, keyFunc == null)) {
                   newKey = newValue;
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PTeeDataObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PTeeDataObject.java
      index 2fabb2896f..ddc0353cd9 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PTeeDataObject.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PTeeDataObject.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -43,12 +43,12 @@
       import static com.oracle.graal.python.builtins.objects.itertools.TeeDataObjectBuiltins.LINKCELLS;
       import static com.oracle.graal.python.nodes.ErrorMessages.CANNOT_REENTER_TEE_ITERATOR;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
      -import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
      +import com.oracle.graal.python.lib.PyIterNextNode;
       import com.oracle.graal.python.nodes.PRaiseNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
       import com.oracle.truffle.api.object.Shape;
      @@ -113,33 +113,32 @@ public void setNextlink(PTeeDataObject nextlink) {
               this.nextlink = nextlink;
           }
       
      -    PTeeDataObject jumplink(PythonObjectFactory factory) {
      +    PTeeDataObject jumplink(PythonLanguage language) {
               if (getNextlink() == null) {
      -            PTeeDataObject dataObj = factory.createTeeDataObject(getIt());
      +            PTeeDataObject dataObj = PFactory.createTeeDataObject(language, getIt());
                   nextlink = dataObj;
               }
               return nextlink;
           }
       
      -    Object getItem(VirtualFrame frame, Node inliningTarget, int i, BuiltinFunctions.NextNode nextNode, PRaiseNode.Lazy raiseNode) {
      +    Object getItem(VirtualFrame frame, Node inliningTarget, int i, PyIterNextNode nextNode, PRaiseNode raiseNode) {
               assert i < TeeDataObjectBuiltins.LINKCELLS;
               if (i < numread) {
                   return values[i];
               } else {
                   assert i == numread;
                   if (running) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, CANNOT_REENTER_TEE_ITERATOR);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, CANNOT_REENTER_TEE_ITERATOR);
                   }
       
                   running = true;
      -            Object value;
                   try {
      -                value = nextNode.execute(frame, it, PNone.NO_VALUE);
      +                Object value = nextNode.execute(frame, inliningTarget, it);
      +                values[numread++] = value;
      +                return value;
                   } finally {
                       running = false;
                   }
      -            values[numread++] = value;
      -            return value;
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PairwiseBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PairwiseBuiltins.java
      index 775ebb45f6..6a3b2829ea 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PairwiseBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PairwiseBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,23 +40,31 @@
        */
       package com.oracle.graal.python.builtins.objects.itertools;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
      +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
       
       import java.util.List;
       
      -import com.oracle.graal.python.builtins.Builtin;
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
      -import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
      +import com.oracle.graal.python.lib.IteratorExhausted;
      +import com.oracle.graal.python.lib.PyObjectGetIter;
      +import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -68,12 +76,37 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PPairwise})
       public final class PairwiseBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = PairwiseBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return PairwiseBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "pairwise", minNumOfPositionalArgs = 2)
      +    @GenerateNodeFactory
      +    public abstract static class PairwaiseNode extends PythonBinaryBuiltinNode {
      +        @Specialization
      +        static PPairwise construct(VirtualFrame frame, Object cls, Object iterable,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached PyObjectGetIter getIter,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!isTypeNode.execute(inliningTarget, cls)) {
      +                // Note: @Fallback or other @Specialization generate data-class
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +
      +            PPairwise self = PFactory.createPairwise(language, cls, getInstanceShape.execute(cls));
      +            self.setIterable(getIter.execute(frame, inliningTarget, iterable));
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -82,37 +115,40 @@ static Object iter(PPairwise self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization(guards = "self.getIterable() != null")
               static Object next(VirtualFrame frame, PPairwise self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached BuiltinFunctions.NextNode nextNode,
      -                        @Cached IsBuiltinObjectProfile isStopIterationProfile,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Cached GetObjectSlotsNode getSlots,
      +                        @Cached CallSlotTpIterNextNode callIterNext,
      +                        @Bind PythonLanguage language) {
                   Object item;
                   Object old = self.getOld();
      -            if (self.getOld() == null) {
      -                old = nextNode.execute(frame, self.getIterable(), PNone.NO_VALUE);
      -                self.setOld(old);
      -            }
      +            Object iterable = self.getIterable();
                   try {
      -                item = nextNode.execute(frame, self.getIterable(), PNone.NO_VALUE);
      +                if (self.getOld() == null) {
      +                    old = callIterNext.execute(frame, inliningTarget, getSlots.execute(inliningTarget, iterable).tp_iternext(), iterable);
      +                    self.setOld(old);
      +                    iterable = self.getIterable();
      +                    if (iterable == null) {
      +                        throw iteratorExhausted();
      +                    }
      +                }
      +                item = callIterNext.execute(frame, inliningTarget, getSlots.execute(inliningTarget, iterable).tp_iternext(), iterable);
                       self.setOld(item);
      -            } catch (PException e) {
      -                e.expectStopIteration(inliningTarget, isStopIterationProfile);
      -                self.setIterable(null);
      +                return PFactory.createTuple(language, new Object[]{old, item});
      +            } catch (IteratorExhausted | PException e) {
                       self.setOld(null);
      +                self.setIterable(null);
                       throw e;
                   }
      -            return factory.createTuple(new Object[]{old, item});
               }
       
               @Specialization(guards = "self.getIterable() == null")
      -        static Object next(@SuppressWarnings("unused") PPairwise self,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raiseStopIteration();
      +        static Object next(@SuppressWarnings("unused") PPairwise self) {
      +            throw iteratorExhausted();
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PermutationsBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PermutationsBuiltins.java
      index 3d3851bfb2..44cda304dd 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PermutationsBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/PermutationsBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -42,34 +42,47 @@
       
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError;
      +import static com.oracle.graal.python.nodes.ErrorMessages.EXPECTED_INT_AS_R;
       import static com.oracle.graal.python.nodes.ErrorMessages.INVALID_ARGS;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
      +import static com.oracle.graal.python.nodes.ErrorMessages.MUST_BE_NON_NEGATIVE;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SETSTATE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.ArgumentClinic;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.iterator.IteratorNodes;
      +import com.oracle.graal.python.builtins.objects.itertools.PermutationsBuiltinsClinicProviders.PermutationsNodeClinicProviderGen;
       import com.oracle.graal.python.builtins.objects.list.PList;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
       import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins.GetItemNode;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
       import com.oracle.graal.python.lib.PyObjectSizeNode;
       import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToJavaBooleanNode;
       import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Cached.Shared;
      @@ -77,6 +90,7 @@
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      +import com.oracle.truffle.api.nodes.LoopNode;
       import com.oracle.truffle.api.nodes.Node;
       import com.oracle.truffle.api.profiles.InlinedBranchProfile;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
      @@ -85,12 +99,93 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PPermutations})
       public final class PermutationsBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = PermutationsBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return PermutationsBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "permutations", minNumOfPositionalArgs = 2, parameterNames = {"cls", "iterable", "r"})
      +    @ArgumentClinic(name = "r", defaultValue = "PNone.NONE")
      +    @GenerateNodeFactory
      +    public abstract static class PermutationsNode extends PythonTernaryClinicBuiltinNode {
      +        @Override
      +        protected ArgumentClinicProvider getArgumentClinic() {
      +            return PermutationsNodeClinicProviderGen.INSTANCE;
      +        }
      +
      +        @Specialization
      +        static Object construct(VirtualFrame frame, Object cls, Object iterable, Object rArg,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached InlinedConditionProfile rIsNoneProfile,
      +                        @Cached IteratorNodes.ToArrayNode toArrayNode,
      +                        @Cached CastToJavaIntExactNode castToInt,
      +                        @Cached InlinedConditionProfile wrongTypeProfile,
      +                        @Cached InlinedBranchProfile wrongRprofile,
      +                        @Cached InlinedBranchProfile negRprofile,
      +                        @Cached InlinedConditionProfile nrProfile,
      +                        @Cached InlinedLoopConditionProfile indicesLoopProfile,
      +                        @Cached InlinedLoopConditionProfile cyclesLoopProfile,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!wrongTypeProfile.profile(inliningTarget, isTypeNode.execute(inliningTarget, cls))) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +            int r;
      +            Object[] pool = toArrayNode.execute(frame, iterable);
      +            if (rIsNoneProfile.profile(inliningTarget, PGuards.isNone(rArg))) {
      +                r = pool.length;
      +            } else {
      +                try {
      +                    r = castToInt.execute(inliningTarget, rArg);
      +                } catch (CannotCastException e) {
      +                    wrongRprofile.enter(inliningTarget);
      +                    throw raiseNode.raise(inliningTarget, TypeError, EXPECTED_INT_AS_R);
      +                }
      +                if (r < 0) {
      +                    negRprofile.enter(inliningTarget);
      +                    throw raiseNode.raise(inliningTarget, ValueError, MUST_BE_NON_NEGATIVE, "r");
      +                }
      +            }
      +            PPermutations self = PFactory.createPermutations(language, cls, getInstanceShape.execute(cls));
      +            self.setPool(pool);
      +            self.setR(r);
      +            int n = pool.length;
      +            self.setN(n);
      +            int nMinusR = n - r;
      +            if (nrProfile.profile(inliningTarget, nMinusR < 0)) {
      +                self.setStopped(true);
      +                self.setRaisedStopIteration(true);
      +            } else {
      +                self.setStopped(false);
      +                int[] indices = new int[n];
      +                indicesLoopProfile.profileCounted(inliningTarget, indices.length);
      +                LoopNode.reportLoopCount(inliningTarget, indices.length);
      +                for (int i = 0; indicesLoopProfile.inject(inliningTarget, i < indices.length); i++) {
      +                    indices[i] = i;
      +                }
      +                self.setIndices(indices);
      +                int[] cycles = new int[r];
      +                int idx = 0;
      +                cyclesLoopProfile.profileCounted(inliningTarget, r);
      +                LoopNode.reportLoopCount(inliningTarget, r);
      +                for (int i = n; cyclesLoopProfile.inject(inliningTarget, i > nMinusR); i--) {
      +                    cycles[idx++] = i;
      +                }
      +                self.setCycles(cycles);
      +                self.setRaisedStopIteration(false);
      +                self.setStarted(false);
      +                return self;
      +            }
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -99,14 +194,13 @@ static Object iter(PPermutations self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization(guards = "self.isStopped()")
      -        static Object next(PPermutations self,
      -                        @Cached PRaiseNode raiseNode) {
      +        static Object next(PPermutations self) {
                   self.setRaisedStopIteration(true);
      -            throw raiseNode.raiseStopIteration();
      +            throw iteratorExhausted();
               }
       
               @Specialization(guards = "!self.isStopped()")
      @@ -117,8 +211,7 @@ static Object next(PPermutations self,
                               @Cached InlinedLoopConditionProfile resultLoopProfile,
                               @Cached InlinedLoopConditionProfile mainLoopProfile,
                               @Cached InlinedLoopConditionProfile shiftIndicesProfile,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Bind PythonLanguage language) {
                   int r = self.getR();
       
                   int[] indices = self.getIndices();
      @@ -139,7 +232,7 @@ static Object next(PPermutations self,
                           int tmp = indices[i];
                           indices[i] = indices[indices.length - j];
                           indices[indices.length - j] = tmp;
      -                    return factory.createTuple(result);
      +                    return PFactory.createTuple(language, result);
                       }
                       cycles[i] = indices.length - i;
                       int n1 = indices.length - 1;
      @@ -155,11 +248,11 @@ static Object next(PPermutations self,
       
                   self.setStopped(true);
                   if (isStartedProfile.profile(inliningTarget, self.isStarted())) {
      -                throw raiseNode.get(inliningTarget).raiseStopIteration();
      +                throw iteratorExhausted();
                   } else {
                       self.setStarted(true);
                   }
      -            return factory.createTuple(result);
      +            return PFactory.createTuple(language, result);
               }
           }
       
      @@ -170,29 +263,29 @@ public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
               static Object reduce(PPermutations self,
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached GetClassNode getClassNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClassNode.execute(inliningTarget, self);
      -            PList poolList = factory.createList(self.getPool());
      -            PTuple tuple = factory.createTuple(new Object[]{poolList, self.getR()});
      +            PList poolList = PFactory.createList(language, self.getPool());
      +            PTuple tuple = PFactory.createTuple(language, new Object[]{poolList, self.getR()});
       
                   // we must pickle the indices and use them for setstate
      -            PTuple indicesTuple = factory.createTuple(self.getIndices());
      -            PTuple cyclesTuple = factory.createTuple(self.getCycles());
      -            PTuple tuple2 = factory.createTuple(new Object[]{indicesTuple, cyclesTuple, self.isStarted()});
      +            PTuple indicesTuple = PFactory.createTuple(language, self.getIndices());
      +            PTuple cyclesTuple = PFactory.createTuple(language, self.getCycles());
      +            PTuple tuple2 = PFactory.createTuple(language, new Object[]{indicesTuple, cyclesTuple, self.isStarted()});
       
                   Object[] result = new Object[]{type, tuple, tuple2};
      -            return factory.createTuple(result);
      +            return PFactory.createTuple(language, result);
               }
       
               @Specialization(guards = "self.isRaisedStopIteration()")
               static Object reduceStopped(PPermutations self,
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached GetClassNode getClassNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClassNode.execute(inliningTarget, self);
      -            PTuple tuple = factory.createTuple(new Object[]{factory.createEmptyTuple(), self.getR()});
      +            PTuple tuple = PFactory.createTuple(language, new Object[]{PFactory.createEmptyTuple(language), self.getR()});
                   Object[] result = new Object[]{type, tuple};
      -            return factory.createTuple(result);
      +            return PFactory.createTuple(language, result);
               }
           }
       
      @@ -209,16 +302,16 @@ static Object setState(VirtualFrame frame, PPermutations self, Object state,
                               @Cached InlinedLoopConditionProfile cyclesProfile,
                               @Cached CastToJavaBooleanNode castBoolean,
                               @Cached CastToJavaIntExactNode castInt,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   try {
                       if (sizeNode.execute(frame, inliningTarget, state) != 3) {
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, INVALID_ARGS, T___SETSTATE__);
      +                    throw raiseNode.raise(inliningTarget, ValueError, INVALID_ARGS, T___SETSTATE__);
                       }
                       Object indices = getItemNode.execute(frame, state, 0);
                       Object cycles = getItemNode.execute(frame, state, 1);
                       int poolLen = self.getPool().length;
                       if (sizeNode.execute(frame, inliningTarget, indices) != poolLen || sizeNode.execute(frame, inliningTarget, cycles) != self.getR()) {
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, INVALID_ARGS, T___SETSTATE__);
      +                    throw raiseNode.raise(inliningTarget, ValueError, INVALID_ARGS, T___SETSTATE__);
                       }
       
                       self.setStarted(castBoolean.execute(inliningTarget, getItemNode.execute(frame, state, 2)));
      @@ -246,9 +339,8 @@ static Object setState(VirtualFrame frame, PPermutations self, Object state,
       
                       return PNone.NONE;
                   } catch (CannotCastException e) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.INTEGER_REQUIRED);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.INTEGER_REQUIRED);
                   }
               }
           }
      -
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ProductBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ProductBuiltins.java
      index 0496482d7a..d3a4d6d591 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ProductBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ProductBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,37 +40,47 @@
        */
       package com.oracle.graal.python.builtins.objects.itertools;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
      +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
      +import static com.oracle.graal.python.nodes.ErrorMessages.ARG_CANNOT_BE_NEGATIVE;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.iterator.IteratorNodes;
       import com.oracle.graal.python.builtins.objects.list.PList;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
       import com.oracle.graal.python.lib.PyLongAsIntNode;
       import com.oracle.graal.python.lib.PyObjectGetItem;
      +import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.object.GetClassNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Cached.Exclusive;
      -import com.oracle.truffle.api.dsl.Cached.Shared;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      +import com.oracle.truffle.api.nodes.LoopNode;
       import com.oracle.truffle.api.nodes.Node;
       import com.oracle.truffle.api.profiles.InlinedBranchProfile;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
      @@ -79,12 +89,122 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PProduct})
       public final class ProductBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = ProductBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return ProductBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "product", minNumOfPositionalArgs = 1, takesVarArgs = true, keywordOnlyNames = {"repeat"})
      +    @GenerateNodeFactory
      +    public abstract static class ProductNode extends PythonBuiltinNode {
      +
      +        @Specialization(guards = "isTypeNode.execute(inliningTarget, cls)")
      +        static Object constructNoneRepeat(VirtualFrame frame, Object cls, Object[] iterables, @SuppressWarnings("unused") PNone repeat,
      +                        @SuppressWarnings("unused") @Bind("this") Node inliningTarget,
      +                        @Cached.Shared @Cached IteratorNodes.ToArrayNode toArrayNode,
      +                        @SuppressWarnings("unused") @Cached.Shared("typeNode") @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached.Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            PProduct self = PFactory.createProduct(language, cls, getInstanceShape.execute(cls));
      +            constructOneRepeat(frame, self, iterables, toArrayNode);
      +            return self;
      +        }
      +
      +        @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "repeat == 1"}, limit = "1")
      +        static Object constructOneRepeat(VirtualFrame frame, Object cls, Object[] iterables, @SuppressWarnings("unused") int repeat,
      +                        @SuppressWarnings("unused") @Bind("this") Node inliningTarget,
      +                        @Cached.Shared @Cached IteratorNodes.ToArrayNode toArrayNode,
      +                        @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached.Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            PProduct self = PFactory.createProduct(language, cls, getInstanceShape.execute(cls));
      +            constructOneRepeat(frame, self, iterables, toArrayNode);
      +            return self;
      +        }
      +
      +        @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "repeat > 1"}, limit = "1")
      +        static Object construct(VirtualFrame frame, Object cls, Object[] iterables, int repeat,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached.Shared @Cached IteratorNodes.ToArrayNode toArrayNode,
      +                        @Cached InlinedLoopConditionProfile loopProfile,
      +                        @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached.Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            Object[][] lists = unpackIterables(frame, iterables, toArrayNode);
      +            Object[][] gears = new Object[lists.length * repeat][];
      +            loopProfile.profileCounted(inliningTarget, repeat);
      +            LoopNode.reportLoopCount(inliningTarget, repeat);
      +            for (int i = 0; loopProfile.inject(inliningTarget, i < repeat); i++) {
      +                PythonUtils.arraycopy(lists, 0, gears, i * lists.length, lists.length);
      +            }
      +            PProduct self = PFactory.createProduct(language, cls, getInstanceShape.execute(cls));
      +            construct(self, gears);
      +            return self;
      +        }
      +
      +        @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "repeat == 0"}, limit = "1")
      +        static Object constructNoRepeat(Object cls, @SuppressWarnings("unused") Object[] iterables, @SuppressWarnings("unused") int repeat,
      +                        @SuppressWarnings("unused") @Bind("this") Node inliningTarget,
      +                        @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached.Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            PProduct self = PFactory.createProduct(language, cls, getInstanceShape.execute(cls));
      +            self.setGears(new Object[0][]);
      +            self.setIndices(new int[0]);
      +            self.setLst(null);
      +            self.setStopped(false);
      +            return self;
      +        }
      +
      +        @SuppressWarnings("unused")
      +        @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "repeat < 0"}, limit = "1")
      +        static Object constructNeg(Object cls, Object[] iterables, int repeat,
      +                        @Bind("this") Node inliningTarget,
      +                        @Exclusive @Cached TypeNodes.IsTypeNode isTypeNode) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ARG_CANNOT_BE_NEGATIVE, "repeat");
      +        }
      +
      +        private static void constructOneRepeat(VirtualFrame frame, PProduct self, Object[] iterables, IteratorNodes.ToArrayNode toArrayNode) {
      +            Object[][] gears = unpackIterables(frame, iterables, toArrayNode);
      +            construct(self, gears);
      +        }
      +
      +        private static void construct(PProduct self, Object[][] gears) {
      +            self.setGears(gears);
      +            for (int i = 0; i < gears.length; i++) {
      +                if (gears[i].length == 0) {
      +                    self.setIndices(null);
      +                    self.setLst(null);
      +                    self.setStopped(true);
      +                    return;
      +                }
      +            }
      +            self.setIndices(new int[gears.length]);
      +            self.setLst(null);
      +            self.setStopped(false);
      +        }
      +
      +        private static Object[][] unpackIterables(VirtualFrame frame, Object[] iterables, IteratorNodes.ToArrayNode toArrayNode) {
      +            Object[][] lists = new Object[iterables.length][];
      +            for (int i = 0; i < lists.length; i++) {
      +                lists[i] = toArrayNode.execute(frame, iterables[i]);
      +            }
      +            return lists;
      +        }
      +
      +        @Specialization(guards = "!isTypeNode.execute(inliningTarget, cls)")
      +        @SuppressWarnings("unused")
      +        static Object construct(Object cls, Object iterables, Object repeat,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached.Shared("typeNode") @Cached TypeNodes.IsTypeNode isTypeNode) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -93,22 +213,22 @@ static Object iter(PProduct self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
       
               @Specialization(guards = {"!self.isStopped()", "!hasLst(self)"})
               static Object next(PProduct self,
                               @Bind("this") Node inliningTarget,
                               @Exclusive @Cached InlinedLoopConditionProfile loopProfile,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object[] lst = new Object[self.getGears().length];
                   loopProfile.profileCounted(inliningTarget, lst.length);
                   for (int i = 0; loopProfile.inject(inliningTarget, i < lst.length); i++) {
                       lst[i] = self.getGears()[i][0];
                   }
                   self.setLst(lst);
      -            return factory.createTuple(lst);
      +            return PFactory.createTuple(language, lst);
               }
       
               @Specialization(guards = {"!self.isStopped()", "hasLst(self)"})
      @@ -119,8 +239,7 @@ static Object next(PProduct self,
                               @Cached InlinedBranchProfile wasStoppedProfile,
                               @Exclusive @Cached InlinedLoopConditionProfile loopProfile,
                               @Cached InlinedBranchProfile doneProfile,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Bind PythonLanguage language) {
                   Object[][] gears = self.getGears();
                   int x = gears.length - 1;
                   if (gearsProfile.profile(inliningTarget, x >= 0)) {
      @@ -140,20 +259,18 @@ static Object next(PProduct self,
       
                   if (self.isStopped()) {
                       wasStoppedProfile.enter(inliningTarget);
      -                throw raiseNode.get(inliningTarget).raiseStopIteration();
      +                throw iteratorExhausted();
                   }
       
                   // the existing lst array can be changed in a following next call
                   Object[] ret = new Object[self.getLst().length];
                   PythonUtils.arraycopy(self.getLst(), 0, ret, 0, ret.length);
      -            return factory.createTuple(ret);
      +            return PFactory.createTuple(language, ret);
               }
       
      -        @SuppressWarnings("unused")
               @Specialization(guards = "self.isStopped()")
      -        static Object nextStopped(PProduct self,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raiseStopIteration();
      +        static Object nextStopped(@SuppressWarnings("unused") PProduct self) {
      +            throw iteratorExhausted();
               }
       
               private static void rotatePreviousGear(Node inliningTarget, PProduct self, InlinedLoopConditionProfile loopProfile, InlinedBranchProfile doneProfile) {
      @@ -198,26 +315,26 @@ static Object reduce(PProduct self,
                               @Cached InlinedConditionProfile stoppedProfile,
                               @Cached InlinedConditionProfile noLstProfile,
                               @Cached GetClassNode getClassNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClassNode.execute(inliningTarget, self);
                   if (stoppedProfile.profile(inliningTarget, self.isStopped())) {
      -                PTuple empty = factory.createEmptyTuple();
      -                return factory.createTuple(new Object[]{type, factory.createTuple(new Object[]{empty})});
      +                PTuple empty = PFactory.createEmptyTuple(language);
      +                return PFactory.createTuple(language, new Object[]{type, PFactory.createTuple(language, new Object[]{empty})});
                   }
      -            PTuple gearTuples = createGearTuple(self, factory);
      +            PTuple gearTuples = createGearTuple(self, language);
                   if (noLstProfile.profile(inliningTarget, self.getLst() == null)) {
      -                return factory.createTuple(new Object[]{type, gearTuples});
      +                return PFactory.createTuple(language, new Object[]{type, gearTuples});
                   }
      -            PTuple indicesTuple = factory.createTuple(PythonUtils.arrayCopyOf(self.getIndices(), self.getIndices().length));
      -            return factory.createTuple(new Object[]{type, gearTuples, indicesTuple});
      +            PTuple indicesTuple = PFactory.createTuple(language, PythonUtils.arrayCopyOf(self.getIndices(), self.getIndices().length));
      +            return PFactory.createTuple(language, new Object[]{type, gearTuples, indicesTuple});
               }
       
      -        private static PTuple createGearTuple(PProduct self, PythonObjectFactory factory) {
      +        private static PTuple createGearTuple(PProduct self, PythonLanguage language) {
                   PList[] lists = new PList[self.getGears().length];
                   for (int i = 0; i < lists.length; i++) {
      -                lists[i] = factory.createList(self.getGears()[i]);
      +                lists[i] = PFactory.createList(language, self.getGears()[i]);
                   }
      -            return factory.createTuple(lists);
      +            return PFactory.createTuple(language, lists);
               }
           }
       
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/RepeatBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/RepeatBuiltins.java
      index 58f51d17dd..4b7df9414d 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/RepeatBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/RepeatBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -43,28 +43,35 @@
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
       import static com.oracle.graal.python.nodes.ErrorMessages.LEN_OF_UNSIZED_OBJECT;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LENGTH_HINT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      +import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
      +import com.oracle.graal.python.lib.PyNumberAsSizeNode;
       import com.oracle.graal.python.lib.PyObjectGetAttr;
       import com.oracle.graal.python.lib.PyObjectReprAsObjectNode;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Cached.Shared;
      @@ -79,12 +86,37 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PRepeat})
       public final class RepeatBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = RepeatBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return RepeatBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "repeat", minNumOfPositionalArgs = 2, parameterNames = {"$self", "object", "times"})
      +    @GenerateNodeFactory
      +    public abstract static class RepeatNode extends PythonTernaryBuiltinNode {
      +
      +        @Specialization
      +        static Object construct(VirtualFrame frame, Object cls, Object object, Object timesObj,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Cached PyNumberAsSizeNode asSizeNode,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            PRepeat self = PFactory.createRepeat(language, cls, getInstanceShape.execute(cls));
      +            self.setElement(object);
      +            if (timesObj != PNone.NO_VALUE) {
      +                int times = asSizeNode.executeExact(frame, inliningTarget, timesObj);
      +                self.setCnt(times > 0 ? times : 0);
      +            } else {
      +                self.setCnt(-1);
      +            }
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -93,20 +125,18 @@ static Object iter(PRepeat self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization(guards = "self.getCnt() > 0")
               static Object nextPos(PRepeat self) {
                   self.setCnt(self.getCnt() - 1);
                   return self.getElement();
               }
       
      -        @SuppressWarnings("unused")
               @Specialization(guards = "self.getCnt() == 0")
      -        static Object nextZero(PRepeat self,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raiseStopIteration();
      +        static Object nextZero(@SuppressWarnings("unused") PRepeat self) {
      +            throw iteratorExhausted();
               }
       
               @Specialization(guards = "self.getCnt() < 0")
      @@ -126,8 +156,8 @@ static Object hintPos(PRepeat self) {
               @SuppressWarnings("unused")
               @Specialization(guards = "self.getCnt() < 0")
               static Object hintNeg(PRepeat self,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, LEN_OF_UNSIZED_OBJECT);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, LEN_OF_UNSIZED_OBJECT);
               }
           }
       
      @@ -139,7 +169,7 @@ static Object reduce(PRepeat self,
                               @Bind("this") Node inliningTarget,
                               @Cached InlinedConditionProfile negativeCountProfile,
                               @Cached GetClassNode getClass,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClass.execute(inliningTarget, self);
                   Object[] tupleElements;
                   if (negativeCountProfile.profile(inliningTarget, self.getCnt() < 0)) {
      @@ -147,12 +177,12 @@ static Object reduce(PRepeat self,
                   } else {
                       tupleElements = new Object[]{self.getElement(), self.getCnt()};
                   }
      -            PTuple tuple = factory.createTuple(tupleElements);
      -            return factory.createTuple(new Object[]{type, tuple});
      +            PTuple tuple = PFactory.createTuple(language, tupleElements);
      +            return PFactory.createTuple(language, new Object[]{type, tuple});
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           public abstract static class ReprNode extends PythonUnaryBuiltinNode {
               @Specialization(guards = "self.getCnt() >= 0")
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/StarmapBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/StarmapBuiltins.java
      index 96bbb96001..fd242fa0c5 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/StarmapBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/StarmapBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,26 +40,36 @@
        */
       package com.oracle.graal.python.builtins.objects.itertools;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
      +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
      -import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
      +import com.oracle.graal.python.lib.PyObjectGetIter;
      +import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode;
       import com.oracle.graal.python.nodes.call.CallNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.object.GetClassNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -71,12 +81,45 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PStarmap})
       public final class StarmapBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = StarmapBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return StarmapBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "starmap", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class StarmapNode extends PythonVarargsBuiltinNode {
      +        @Specialization
      +        static PStarmap construct(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode,
      +                        @Cached PyObjectGetIter getIter,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!isTypeNode.execute(inliningTarget, cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +            if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "starmap()");
      +            }
      +            if (args.length != 2) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_EXPECTED_D_ARGS, "starmap", 2);
      +            }
      +            Object fun = args[0];
      +            Object iterable = args[1];
      +            PStarmap self = PFactory.createStarmap(language, cls, getInstanceShape.execute(cls));
      +            self.setFun(fun);
      +            self.setIterable(getIter.execute(frame, inliningTarget, iterable));
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -85,15 +128,18 @@ static Object iter(PStarmap self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization
               static Object nextPos(VirtualFrame frame, PStarmap self,
      -                        @Cached BuiltinFunctions.NextNode nextNode,
      +                        @Bind Node inliningTarget,
      +                        @Cached GetObjectSlotsNode getSlots,
      +                        @Cached CallSlotTpIterNextNode callIterNext,
                               @Cached CallNode callNode,
                               @Cached ExecutePositionalStarargsNode getArgsNode) {
      -            Object obj = nextNode.execute(frame, self.getIterable(), PNone.NO_VALUE);
      +            Object it = self.getIterable();
      +            Object obj = callIterNext.execute(frame, inliningTarget, getSlots.execute(inliningTarget, it).tp_iternext(), it);
                   Object[] args = getArgsNode.executeWith(frame, obj);
                   return callNode.execute(frame, self.getFun(), args, PKeyword.EMPTY_KEYWORDS);
               }
      @@ -106,12 +152,11 @@ public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
               static Object reducePos(PStarmap self,
                               @Bind("this") Node inliningTarget,
                               @Cached GetClassNode getClassNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClassNode.execute(inliningTarget, self);
                   // return type(self), (self.fun, self.iterable)
      -            PTuple tuple = factory.createTuple(new Object[]{self.getFun(), self.getIterable()});
      -            return factory.createTuple(new Object[]{type, tuple});
      +            PTuple tuple = PFactory.createTuple(language, new Object[]{self.getFun(), self.getIterable()});
      +            return PFactory.createTuple(language, new Object[]{type, tuple});
               }
           }
      -
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TakewhileBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TakewhileBuiltins.java
      index cbaa174253..b1544ba1b2 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TakewhileBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TakewhileBuiltins.java
      @@ -40,26 +40,36 @@
        */
       package com.oracle.graal.python.builtins.objects.itertools;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
      +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
      -import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
      +import com.oracle.graal.python.lib.PyObjectGetIter;
       import com.oracle.graal.python.lib.PyObjectIsTrueNode;
      +import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.call.CallNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.object.GetClassNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      @@ -72,12 +82,45 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PTakewhile})
       public final class TakewhileBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = TakewhileBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return TakewhileBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "takewhile", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class TakewhileNode extends PythonVarargsBuiltinNode {
      +        @Specialization
      +        static PTakewhile construct(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode,
      +                        @Cached PyObjectGetIter getIter,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!isTypeNode.execute(inliningTarget, cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +            if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "takewhile()");
      +            }
      +            if (args.length != 2) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_EXPECTED_D_ARGS, "takewhile", 2);
      +            }
      +            Object predicate = args[0];
      +            Object iterable = args[1];
      +            PTakewhile self = PFactory.createTakewhile(language, cls, getInstanceShape.execute(cls));
      +            self.setPredicate(predicate);
      +            self.setIterable(getIter.execute(frame, inliningTarget, iterable));
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -86,21 +129,22 @@ static Object iter(PTakewhile self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization
               static Object next(VirtualFrame frame, PTakewhile self,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached BuiltinFunctions.NextNode nextNode,
      +                        @Bind Node inliningTarget,
      +                        @Cached GetObjectSlotsNode getSlots,
      +                        @Cached CallSlotTpIterNextNode callIterNext,
                               @Cached CallNode callNode,
                               @Cached PyObjectIsTrueNode isTrue,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      -            Object value = nextNode.execute(frame, self.getIterable(), PNone.NO_VALUE);
      +                        @Bind PythonLanguage language) {
      +            Object it = self.getIterable();
      +            Object value = callIterNext.execute(frame, inliningTarget, getSlots.execute(inliningTarget, it).tp_iternext(), it);
                   if (!isTrue.execute(frame, callNode.execute(frame, self.getPredicate(), value))) {
      -                self.setIterable(factory.createSequenceIterator(factory.createList(PythonUtils.EMPTY_OBJECT_ARRAY)));
      -                throw raiseNode.get(inliningTarget).raiseStopIteration();
      +                self.setIterable(PFactory.createSequenceIterator(language, PFactory.createList(language, PythonUtils.EMPTY_OBJECT_ARRAY)));
      +                throw iteratorExhausted();
                   }
                   return value;
               }
      @@ -113,10 +157,10 @@ public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
               static Object reduce(PTakewhile self,
                               @Bind("this") Node inliningTarget,
                               @Cached GetClassNode getClassNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClassNode.execute(inliningTarget, self);
      -            PTuple tuple = factory.createTuple(new Object[]{self.getPredicate(), self.getIterable()});
      -            return factory.createTuple(new Object[]{type, tuple});
      +            PTuple tuple = PFactory.createTuple(language, new Object[]{self.getPredicate(), self.getIterable()});
      +            return PFactory.createTuple(language, new Object[]{type, tuple});
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeBuiltins.java
      index 29fad45e82..a9733a1d57 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -47,25 +47,27 @@
       import static com.oracle.graal.python.nodes.ErrorMessages.INTEGER_REQUIRED_GOT;
       import static com.oracle.graal.python.nodes.ErrorMessages.IS_NOT_A;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___COPY__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___COPY__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
       import com.oracle.graal.python.builtins.objects.PNone;
      -import com.oracle.graal.python.builtins.objects.object.PythonObject;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
       import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins;
       import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins.LenNode;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
      +import com.oracle.graal.python.lib.PyIterNextNode;
       import com.oracle.graal.python.lib.PyObjectGetIter;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
      @@ -75,10 +77,9 @@
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToJavaIntLossyNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      -import com.oracle.truffle.api.dsl.Cached.Shared;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.ImportStatic;
       import com.oracle.truffle.api.dsl.NeverDefault;
      @@ -91,12 +92,15 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PTee})
       public final class TeeBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = TeeBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return TeeBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___NEW__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(minNumOfPositionalArgs = 2)
           @GenerateNodeFactory
           public abstract static class NewNode extends PythonBinaryBuiltinNode {
               @Specialization
      @@ -105,13 +109,13 @@ static Object newTee(VirtualFrame frame, @SuppressWarnings("unused") Object cls,
                               @Cached PyObjectGetIter getIter,
                               @Cached("createCopyNode()") LookupAndCallUnaryNode copyNode,
                               @Cached InlinedConditionProfile isTeeInstanceProfile,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object it = getIter.execute(frame, inliningTarget, iterable);
                   if (isTeeInstanceProfile.profile(inliningTarget, it instanceof PTee)) {
                       return copyNode.executeObject(frame, it);
                   } else {
      -                PTeeDataObject dataObj = factory.createTeeDataObject(it);
      -                return factory.createTee(dataObj, 0);
      +                PTeeDataObject dataObj = PFactory.createTeeDataObject(language, it);
      +                return PFactory.createTee(language, dataObj, 0);
                   }
               }
       
      @@ -126,12 +130,12 @@ protected LookupAndCallUnaryNode createCopyNode() {
           public abstract static class CopyNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object copy(PTee self,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createTee(self.getDataobj(), self.getIndex());
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createTee(language, self.getDataobj(), self.getIndex());
               }
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -140,55 +144,47 @@ static Object iter(PTee self) {
               }
           }
       
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @ImportStatic(TeeDataObjectBuiltins.class)
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      -        @Specialization(guards = "self.getIndex() < LINKCELLS")
      -        static Object next(VirtualFrame frame, PTee self,
      +    public abstract static class NextNode extends TpIterNextBuiltin {
      +        @Specialization
      +        static Object doIt(VirtualFrame frame, PTee self,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached BuiltinFunctions.NextNode nextNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Bind PythonLanguage language,
      +                        @Cached InlinedConditionProfile indexConditionProfile,
      +                        @Cached PyIterNextNode nextNode,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (indexConditionProfile.profile(inliningTarget, self.getIndex() >= LINKCELLS)) {
      +                self.setDataObj(self.getDataobj().jumplink(language));
      +                self.setIndex(0);
      +            }
                   Object value = self.getDataobj().getItem(frame, inliningTarget, self.getIndex(), nextNode, raiseNode);
                   self.setIndex(self.getIndex() + 1);
                   return value;
               }
      -
      -        @Specialization(guards = "self.getIndex() >= LINKCELLS")
      -        static Object nextNext(VirtualFrame frame, PTee self,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared @Cached BuiltinFunctions.NextNode nextNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            self.setDataObj(self.getDataobj().jumplink(factory));
      -            Object value = self.getDataobj().getItem(frame, inliningTarget, 0, nextNode, raiseNode);
      -            self.setIndex(1);
      -            return value;
      -        }
           }
       
           @Builtin(name = J___REDUCE__, minNumOfPositionalArgs = 1)
           @GenerateNodeFactory
           public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
      -        abstract Object execute(VirtualFrame frame, PythonObject self);
       
               @Specialization
               static Object reduce(PTee self,
                               @Bind("this") Node inliningTarget,
                               @Cached GetClassNode getClass,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   // return type(self), ((),), (self.dataobj, self.index)
                   Object type = getClass.execute(inliningTarget, self);
      -            PTuple tuple1 = factory.createTuple(new Object[]{factory.createEmptyTuple()});
      -            PTuple tuple2 = factory.createTuple(new Object[]{self.getDataobj(), self.getIndex()});
      -            return factory.createTuple(new Object[]{type, tuple1, tuple2});
      +            PTuple tuple1 = PFactory.createTuple(language, new Object[]{PFactory.createEmptyTuple(language)});
      +            PTuple tuple2 = PFactory.createTuple(language, new Object[]{self.getDataobj(), self.getIndex()});
      +            return PFactory.createTuple(language, new Object[]{type, tuple1, tuple2});
               }
           }
       
           @Builtin(name = J___SETSTATE__, minNumOfPositionalArgs = 2)
           @GenerateNodeFactory
           public abstract static class SetStateNode extends PythonBinaryBuiltinNode {
      -        abstract Object execute(VirtualFrame frame, PythonObject self, Object state);
       
               @Specialization
               static Object setState(VirtualFrame frame, PTee self, Object state,
      @@ -196,14 +192,14 @@ static Object setState(VirtualFrame frame, PTee self, Object state,
                               @Cached LenNode lenNode,
                               @Cached TupleBuiltins.GetItemNode getItemNode,
                               @Cached CastToJavaIntLossyNode castToIntNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
       
                   if (!(state instanceof PTuple) || (int) lenNode.execute(frame, state) != 2) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, IS_NOT_A, "state", "2-tuple");
      +                throw raiseNode.raise(inliningTarget, TypeError, IS_NOT_A, "state", "2-tuple");
                   }
                   Object dataObject = getItemNode.execute(frame, state, 0);
                   if (!(dataObject instanceof PTeeDataObject)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, IS_NOT_A, "state", "_tee_dataobject");
      +                throw raiseNode.raise(inliningTarget, TypeError, IS_NOT_A, "state", "_tee_dataobject");
                   }
                   self.setDataObj((PTeeDataObject) dataObject);
                   Object secondElement = getItemNode.execute(frame, state, 1);
      @@ -211,10 +207,10 @@ static Object setState(VirtualFrame frame, PTee self, Object state,
                   try {
                       index = castToIntNode.execute(inliningTarget, secondElement);
                   } catch (CannotCastException e) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, INTEGER_REQUIRED_GOT, secondElement);
      +                throw raiseNode.raise(inliningTarget, TypeError, INTEGER_REQUIRED_GOT, secondElement);
                   }
                   if (index < 0 || index > LINKCELLS) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, INDEX_OUT_OF_RANGE);
      +                throw raiseNode.raise(inliningTarget, ValueError, INDEX_OUT_OF_RANGE);
                   }
                   self.setIndex(index);
                   return PNone.NONE;
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeDataObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeDataObjectBuiltins.java
      index 0ee4d51cdf..fef12b270a 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeDataObjectBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeDataObjectBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -46,13 +46,15 @@
       import static com.oracle.graal.python.nodes.ErrorMessages.S_MUST_BE_S;
       import static com.oracle.graal.python.nodes.ErrorMessages.TDATAOBJECT_SHOULDNT_HAVE_NEXT;
       import static com.oracle.graal.python.nodes.ErrorMessages.TDATAOBJECT_SHOULD_NOT_HAVE_MORE_LINKS;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___COPY__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.ArgumentClinic;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -60,17 +62,21 @@
       import com.oracle.graal.python.builtins.modules.BuiltinFunctions.LenNode;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
      +import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.list.PList;
       import com.oracle.graal.python.builtins.objects.object.PythonObject;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
      -import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
       import com.oracle.graal.python.nodes.object.GetClassNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      @@ -86,12 +92,34 @@ public final class TeeDataObjectBuiltins extends PythonBuiltins {
       
           static final int LINKCELLS = 128;
       
      +    public static final TpSlots SLOTS = TeeDataObjectBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return TeeDataObjectBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self", "it", "values", "nxt"})
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "_tee_dataobject", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class TeeDataObjectNode extends PythonVarargsBuiltinNode {
      +        @SuppressWarnings("unused")
      +        @Specialization
      +        PTeeDataObject construct(Object cls, Object[] arguments, PKeyword[] keywords,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Cached InlinedBranchProfile errorProfile,
      +                        @Bind PythonLanguage language) {
      +            if (!isTypeNode.execute(inliningTarget, cls)) {
      +                errorProfile.enter(inliningTarget);
      +                throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +            return PFactory.createTeeDataObject(language);
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_init, isComplex = true)
      +    @SlotSignature(name = "TeeDataObject", minNumOfPositionalArgs = 1, parameterNames = {"$self", "it", "values", "nxt"})
           @ArgumentClinic(name = "values", defaultValue = "PNone.NONE", useDefaultForNone = true)
           @ArgumentClinic(name = "nxt", defaultValue = "PNone.NONE", useDefaultForNone = true)
           @GenerateNodeFactory
      @@ -130,17 +158,17 @@ static Object init(VirtualFrame frame, PTeeDataObject self, Object it, PList val
                               @Cached LenNode lenNode,
                               @Cached SequenceStorageNodes.GetInternalObjectArrayNode getInternalObjectArrayNode,
                               @Cached InlinedBranchProfile numreadLCProfile,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   int numread = (int) lenNode.execute(frame, values);
                   if (numread == LINKCELLS) {
                       numreadLCProfile.enter(inliningTarget);
                       if (!(nxt instanceof PTeeDataObject)) {
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, S_MUST_BE_S, "_tee_dataobject next link", "_tee_dataobject");
      +                    throw raiseNode.raise(inliningTarget, ValueError, S_MUST_BE_S, "_tee_dataobject next link", "_tee_dataobject");
                       }
                   } else if (numread > LINKCELLS) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, TDATAOBJECT_SHOULD_NOT_HAVE_MORE_LINKS, LINKCELLS);
      +                throw raiseNode.raise(inliningTarget, ValueError, TDATAOBJECT_SHOULD_NOT_HAVE_MORE_LINKS, LINKCELLS);
                   } else if (!(nxt instanceof PNone)) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, TDATAOBJECT_SHOULDNT_HAVE_NEXT);
      +                throw raiseNode.raise(inliningTarget, ValueError, TDATAOBJECT_SHOULDNT_HAVE_NEXT);
                   }
                   self.setIt(it);
                   Object[] valuesArray = getInternalObjectArrayNode.execute(inliningTarget, values.getSequenceStorage());
      @@ -156,12 +184,8 @@ static Object init(VirtualFrame frame, PTeeDataObject self, Object it, PList val
               @SuppressWarnings("unused")
               @Specialization(guards = {"!isList(values)", "!isNone(values)"})
               static Object init(VirtualFrame frame, PTeeDataObject self, Object it, Object values, Object nxt,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ARG_D_MUST_BE_S_NOT_P, "teedataobject()", 2, "list", values);
      -        }
      -
      -        protected LookupAndCallUnaryNode createCopyNode() {
      -            return LookupAndCallUnaryNode.create(T___COPY__);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ARG_D_MUST_BE_S_NOT_P, "teedataobject()", 2, "list", values);
               }
           }
       
      @@ -174,14 +198,14 @@ public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
               static Object reduce(PTeeDataObject self,
                               @Bind("this") Node inliningTarget,
                               @Cached GetClassNode getClass,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   int numread = self.getNumread();
                   Object[] values = new Object[numread];
                   PythonUtils.arraycopy(self.getValues(), 0, values, 0, numread);
                   Object type = getClass.execute(inliningTarget, self);
                   Object nextlink = self.getNextlink();
      -            PTuple tuple = factory.createTuple(new Object[]{self.getIt(), factory.createList(values), nextlink == null ? PNone.NONE : nextlink});
      -            return factory.createTuple(new Object[]{type, tuple});
      +            PTuple tuple = PFactory.createTuple(language, new Object[]{self.getIt(), PFactory.createList(language, values), nextlink == null ? PNone.NONE : nextlink});
      +            return PFactory.createTuple(language, new Object[]{type, tuple});
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ZipLongestBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ZipLongestBuiltins.java
      index 0384b449f1..144fb87465 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ZipLongestBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ZipLongestBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,48 +40,102 @@
        */
       package com.oracle.graal.python.builtins.objects.itertools;
       
      -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.StopIteration;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
      +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
      +import com.oracle.graal.python.lib.IteratorExhausted;
      +import com.oracle.graal.python.lib.PyIterNextNode;
      +import com.oracle.graal.python.lib.PyObjectGetIter;
      +import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      +import com.oracle.truffle.api.nodes.LoopNode;
       import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.InlinedBranchProfile;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile;
       
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PZipLongest})
       public final class ZipLongestBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = ZipLongestBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return ZipLongestBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "zip_longest", minNumOfPositionalArgs = 1, takesVarArgs = true, keywordOnlyNames = {"fillvalue"})
      +    @GenerateNodeFactory
      +    public abstract static class ZipLongestNode extends PythonBuiltinNode {
      +        @Specialization
      +        static Object construct(VirtualFrame frame, Object cls, Object[] args, Object fillValueIn,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached PyObjectGetIter getIterNode,
      +                        @Cached InlinedConditionProfile fillIsNone,
      +                        @Cached InlinedLoopConditionProfile loopProfile,
      +                        @Cached TypeNodes.IsTypeNode isTypeNode,
      +                        @Cached InlinedBranchProfile errorProfile,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (!isTypeNode.execute(inliningTarget, cls)) {
      +                // Note: @Fallback or other @Specialization generate data-class
      +                errorProfile.enter(inliningTarget);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls);
      +            }
      +
      +            Object fillValue = fillValueIn;
      +            if (fillIsNone.profile(inliningTarget, PGuards.isPNone(fillValue))) {
      +                fillValue = null;
      +            }
      +
      +            PZipLongest self = PFactory.createZipLongest(language, cls, getInstanceShape.execute(cls));
      +            self.setFillValue(fillValue);
      +            self.setNumActive(args.length);
      +
      +            Object[] itTuple = new Object[args.length];
      +            loopProfile.profileCounted(inliningTarget, itTuple.length);
      +            LoopNode.reportLoopCount(inliningTarget, itTuple.length);
      +            for (int i = 0; loopProfile.inject(inliningTarget, i < itTuple.length); i++) {
      +                itTuple[i] = getIterNode.execute(frame, inliningTarget, args[i]);
      +            }
      +            self.setItTuple(itTuple);
      +            return self;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -90,33 +144,23 @@ static Object iter(PZipLongest self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      -        @SuppressWarnings("unused")
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization(guards = "zeroSize(self)")
      -        static Object nextNoFillValue(VirtualFrame frame, PZipLongest self,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raiseStopIteration();
      +        static Object nextNoFillValue(@SuppressWarnings("unused") PZipLongest self) {
      +            throw iteratorExhausted();
               }
       
               @Specialization(guards = "!zeroSize(self)")
               static Object next(VirtualFrame frame, PZipLongest self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached BuiltinFunctions.NextNode nextNode,
      -                        @Cached IsBuiltinObjectProfile isStopIterationProfile,
      +                        @Cached PyIterNextNode nextNode,
                               @Cached InlinedConditionProfile noItProfile,
                               @Cached InlinedConditionProfile noActiveProfile,
                               @Cached InlinedLoopConditionProfile loopProfile,
      -                        @Cached InlinedConditionProfile isNullFillProfile,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached InlinedConditionProfile isNullFillProfile) {
                   Object fillValue = isNullFillProfile.profile(inliningTarget, isNullFillValue(self)) ? PNone.NONE : self.getFillValue();
      -            return next(frame, inliningTarget, self, fillValue, nextNode, isStopIterationProfile, loopProfile, noItProfile, noActiveProfile, factory, raiseNode);
      -        }
      -
      -        private static Object next(VirtualFrame frame, Node inliningTarget, PZipLongest self, Object fillValue, BuiltinFunctions.NextNode nextNode, IsBuiltinObjectProfile isStopIterationProfile,
      -                        InlinedLoopConditionProfile loopProfile, InlinedConditionProfile noItProfile, InlinedConditionProfile noActiveProfile, PythonObjectFactory factory, PRaiseNode.Lazy raiseNode) {
                   Object[] result = new Object[self.getItTuple().length];
                   loopProfile.profileCounted(inliningTarget, result.length);
                   for (int i = 0; loopProfile.inject(inliningTarget, i < result.length); i++) {
      @@ -126,25 +170,23 @@ private static Object next(VirtualFrame frame, Node inliningTarget, PZipLongest
                           item = fillValue;
                       } else {
                           try {
      -                        item = nextNode.execute(frame, it, PNone.NO_VALUE);
      -                    } catch (PException e) {
      -                        if (isStopIterationProfile.profileException(inliningTarget, e, StopIteration)) {
      -                            self.setNumActive(self.getNumActive() - 1);
      -                            if (noActiveProfile.profile(inliningTarget, self.getNumActive() == 0)) {
      -                                throw raiseNode.get(inliningTarget).raiseStopIteration();
      -                            } else {
      -                                item = fillValue;
      -                                self.getItTuple()[i] = PNone.NONE;
      -                            }
      +                        item = nextNode.execute(frame, inliningTarget, it);
      +                    } catch (IteratorExhausted e) {
      +                        self.setNumActive(self.getNumActive() - 1);
      +                        if (noActiveProfile.profile(inliningTarget, self.getNumActive() == 0)) {
      +                            throw iteratorExhausted();
                               } else {
      -                            self.setNumActive(0);
      -                            throw e;
      +                            item = fillValue;
      +                            self.getItTuple()[i] = PNone.NONE;
                               }
      +                    } catch (PException e) {
      +                        self.setNumActive(0);
      +                        throw e;
                           }
                       }
                       result[i] = item;
                   }
      -            return factory.createTuple(result);
      +            return PFactory.createTuple(PythonLanguage.get(inliningTarget), result);
               }
       
               protected static boolean isNullFillValue(PZipLongest self) {
      @@ -166,7 +208,7 @@ static Object reduce(PZipLongest self,
                               @Cached InlinedConditionProfile noFillValueProfile,
                               @Cached InlinedLoopConditionProfile loopProfile,
                               @Cached InlinedConditionProfile noItProfile,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object fillValue = self.getFillValue();
                   if (noFillValueProfile.profile(inliningTarget, fillValue == null)) {
                       fillValue = PNone.NONE;
      @@ -177,13 +219,13 @@ static Object reduce(PZipLongest self,
                   for (int i = 0; loopProfile.profile(inliningTarget, i < its.length); i++) {
                       Object it = self.getItTuple()[i];
                       if (noItProfile.profile(inliningTarget, it == PNone.NONE)) {
      -                    its[i] = factory.createEmptyTuple();
      +                    its[i] = PFactory.createEmptyTuple(language);
                       } else {
                           its[i] = it;
                       }
                   }
      -            PTuple tuple = factory.createTuple(its);
      -            return factory.createTuple(new Object[]{type, tuple, fillValue});
      +            PTuple tuple = PFactory.createTuple(language, its);
      +            return PFactory.createTuple(language, new Object[]{type, tuple, fillValue});
               }
           }
       
      @@ -196,5 +238,4 @@ static Object setState(PZipLongest self, Object state) {
                   return PNone.NONE;
               }
           }
      -
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/list/ListBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/list/ListBuiltins.java
      index 4abd0e414c..68abe0c743 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/list/ListBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/list/ListBuiltins.java
      @@ -27,22 +27,10 @@
       
       import static com.oracle.graal.python.nodes.BuiltinNames.J_APPEND;
       import static com.oracle.graal.python.nodes.BuiltinNames.J_EXTEND;
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_LIST;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J_SORT;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CONTAINS__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IADD__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IMUL__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REVERSED__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__;
       import static com.oracle.graal.python.nodes.StringLiterals.T_COMMA_SPACE;
       import static com.oracle.graal.python.nodes.StringLiterals.T_ELLIPSIS_IN_BRACKETS;
       import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_BRACKETS;
      @@ -55,9 +43,12 @@
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.ArgumentClinic;
      +import com.oracle.graal.python.annotations.HashNotImplemented;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.Python3Core;
      @@ -72,6 +63,7 @@
       import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.SequenceStorageMpSubscriptNode;
       import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.SequenceStorageSqItemNode;
       import com.oracle.graal.python.builtins.objects.common.SortNodes.SortSequenceStorageNode;
      +import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.iterator.IteratorNodes;
       import com.oracle.graal.python.builtins.objects.iterator.PDoubleSequenceIterator;
       import com.oracle.graal.python.builtins.objects.iterator.PIntegerSequenceIterator;
      @@ -80,20 +72,23 @@
       import com.oracle.graal.python.builtins.objects.range.PIntRange;
       import com.oracle.graal.python.builtins.objects.str.PString;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.SqConcatBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotMpAssSubscript.MpAssSubscriptBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqItemBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqRepeatBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqAssItem.SqAssItemBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode;
       import com.oracle.graal.python.lib.PyIndexCheckNode;
       import com.oracle.graal.python.lib.PyListCheckNode;
       import com.oracle.graal.python.lib.PyObjectGetIter;
       import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
       import com.oracle.graal.python.lib.PyObjectRichCompareBool;
      +import com.oracle.graal.python.lib.RichCmpOp;
       import com.oracle.graal.python.nodes.ErrorMessages;
      -import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.builtins.ListNodes;
       import com.oracle.graal.python.nodes.builtins.ListNodes.AppendNode;
      @@ -107,11 +102,12 @@
       import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
       import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.exception.PythonErrorType;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.runtime.sequence.storage.DoubleSequenceStorage;
       import com.oracle.graal.python.runtime.sequence.storage.EmptySequenceStorage;
       import com.oracle.graal.python.runtime.sequence.storage.IntSequenceStorage;
      @@ -128,9 +124,11 @@
       import com.oracle.truffle.api.dsl.NeverDefault;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      +import com.oracle.truffle.api.nodes.LoopNode;
       import com.oracle.truffle.api.nodes.Node;
       import com.oracle.truffle.api.profiles.InlinedBranchProfile;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
      +import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       import com.oracle.truffle.api.strings.TruffleStringBuilder;
       import com.oracle.truffle.api.strings.TruffleStringIterator;
      @@ -142,13 +140,13 @@
        * get a proper error and not allow other sequences, just PList or foreign list.
        */
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PList)
      +@HashNotImplemented
       public final class ListBuiltins extends PythonBuiltins {
           public static final TpSlots SLOTS = ListBuiltinsSlotsGen.SLOTS;
       
           @Override
           public void initialize(Python3Core core) {
               super.initialize(core);
      -        this.addBuiltinConstant(T___HASH__, PNone.NONE);
           }
       
           @Override
      @@ -156,7 +154,29 @@ protected List> getNodeFactories() {
               return MapBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = J_MAP, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class MapNode extends PythonVarargsBuiltinNode {
      +        @Specialization
      +        static PMap doit(VirtualFrame frame, Object cls, Object[] args, PKeyword[] keywords,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached(inline = false /* uncommon path */) TypeNodes.HasObjectInitNode hasObjectInitNode,
      +                        @Cached InlinedLoopConditionProfile loopProfile,
      +                        @Cached PyObjectGetIter getIter,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (keywords.length > 0 && hasObjectInitNode.executeCached(cls)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "map()");
      +            }
      +            if (args.length < 2) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MAP_MUST_HAVE_AT_LEAST_TWO_ARGUMENTS);
      +            }
      +            PMap map = PFactory.createMap(language, cls, getInstanceShape.execute(cls));
      +            map.setFunction(args[0]);
      +            Object[] iterators = new Object[args.length - 1];
      +            loopProfile.profileCounted(inliningTarget, iterators.length);
      +            for (int i = 0; loopProfile.inject(inliningTarget, i < iterators.length); i++) {
      +                iterators[i] = getIter.execute(frame, inliningTarget, args[i + 1]);
      +            }
      +            map.setIterators(iterators);
      +            return map;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization(guards = "self.getIterators().length == 1")
               Object doOne(VirtualFrame frame, PMap self,
      -                        @Shared @Cached CallVarargsMethodNode callNode,
      -                        @Shared @Cached GetNextNode next) {
      -            return callNode.execute(frame, self.getFunction(), new Object[]{next.execute(frame, self.getIterators()[0])}, PKeyword.EMPTY_KEYWORDS);
      +                        @Bind Node inliningTarget,
      +                        @Shared @Cached CallNode callNode,
      +                        @Shared @Cached PyIterNextNode nextNode) {
      +            Object item = nextNode.execute(frame, inliningTarget, self.getIterators()[0]);
      +            return callNode.execute(frame, self.getFunction(), item);
               }
       
               @Specialization(replaces = "doOne")
               Object doNext(VirtualFrame frame, PMap self,
      -                        @Shared @Cached CallVarargsMethodNode callNode,
      -                        @Shared @Cached GetNextNode next) {
      +                        @Bind Node inliningTarget,
      +                        @Shared @Cached CallNode callNode,
      +                        @Shared @Cached PyIterNextNode nextNode) {
                   Object[] iterators = self.getIterators();
                   Object[] arguments = new Object[iterators.length];
                   for (int i = 0; i < iterators.length; i++) {
      -                arguments[i] = next.execute(frame, iterators[i]);
      +                arguments[i] = nextNode.execute(frame, inliningTarget, iterators[i]);
                   }
      -            return callNode.execute(frame, self.getFunction(), arguments, PKeyword.EMPTY_KEYWORDS);
      +            return callNode.execute(frame, self.getFunction(), arguments);
               }
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
       
      @@ -111,12 +161,12 @@ static PMap iter(PMap self) {
           public abstract static class ReduceNode extends PythonBuiltinNode {
               @Specialization
               static PTuple doit(PMap self, @SuppressWarnings("unused") Object ignored,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object[] iterators = self.getIterators();
                   Object[] args = new Object[iterators.length + 1];
                   args[0] = self.getFunction();
                   System.arraycopy(iterators, 0, args, 1, iterators.length);
      -            return factory.createTuple(new Object[]{PythonBuiltinClassType.PMap, factory.createTuple(args)});
      +            return PFactory.createTuple(language, new Object[]{PythonBuiltinClassType.PMap, PFactory.createTuple(language, args)});
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java
      index 1800a7ca6c..a8e6ba7b6e 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java
      @@ -32,14 +32,7 @@
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J_KEYS;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J_VALUES;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CONTAINS__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IOR__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REVERSED__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T_COPY;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T_GET;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T_ITEMS;
      @@ -49,34 +42,43 @@
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.list.PList;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
      +import com.oracle.graal.python.builtins.objects.tuple.PTuple;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode;
      +import com.oracle.graal.python.lib.PyMappingCheckNode;
      +import com.oracle.graal.python.lib.PyNumberOrNode;
       import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
       import com.oracle.graal.python.lib.PyObjectGetItem;
       import com.oracle.graal.python.lib.PyObjectGetIter;
       import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
      -import com.oracle.graal.python.lib.PyObjectRichCompareBool;
      +import com.oracle.graal.python.lib.PyObjectRichCompare;
       import com.oracle.graal.python.lib.PyObjectSizeNode;
       import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
      +import com.oracle.graal.python.lib.PySequenceContainsNode;
      +import com.oracle.graal.python.lib.RichCmpOp;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
      -import com.oracle.graal.python.nodes.expression.BinaryArithmetic;
      -import com.oracle.graal.python.nodes.expression.BinaryOpNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.exception.PythonErrorType;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Cached.Shared;
      @@ -96,7 +98,33 @@ protected List= 0) {
      -                    selfXPtr = getCallCapiFunction().call(NativeCAPISymbol.FUN_TRUFFLE_ADD_SUBOFFSET, selfPtr, selfOffset, self.getBufferSuboffsets()[dim]);
      +                    selfXPtr = callCapiFunction.call(NativeCAPISymbol.FUN_TRUFFLE_ADD_SUBOFFSET, selfPtr, selfOffset, self.getBufferSuboffsets()[dim]);
                           selfXOffset = 0;
                       }
                       if (other.getBufferSuboffsets() != null && other.getBufferSuboffsets()[dim] >= 0) {
      -                    otherXPtr = getCallCapiFunction().call(NativeCAPISymbol.FUN_TRUFFLE_ADD_SUBOFFSET, otherPtr, otherOffset, other.getBufferSuboffsets()[dim]);
      +                    otherXPtr = callCapiFunction.call(NativeCAPISymbol.FUN_TRUFFLE_ADD_SUBOFFSET, otherPtr, otherOffset, other.getBufferSuboffsets()[dim]);
                           otherXOffset = 0;
                       }
                       if (dim == ndim - 1) {
                           Object selfItem = readSelf.execute(frame, self, selfXPtr, selfXOffset);
                           Object otherItem = readOther.execute(frame, other, otherXPtr, otherXOffset);
      -                    if (!eqNode.compare(frame, inliningTarget, selfItem, otherItem)) {
      +                    if (!eqNode.executeEq(frame, inliningTarget, selfItem, otherItem)) {
                               return false;
                           }
                       } else {
      -                    if (!recursive(frame, inliningTarget, eqNode, self, other, readSelf, readOther, dim + 1, ndim, selfXPtr, selfXOffset, otherXPtr, otherXOffset)) {
      +                    if (!recursive(frame, inliningTarget, eqNode, callCapiFunction, self, other, readSelf, readOther, dim + 1, ndim, selfXPtr, selfXOffset, otherXPtr, otherXOffset)) {
                               return false;
                           }
                       }
      @@ -406,14 +469,6 @@ private boolean recursive(VirtualFrame frame, Node inliningTarget, PyObjectRichC
                   }
                   return true;
               }
      -
      -        private CExtNodes.PCallCapiFunction getCallCapiFunction() {
      -            if (callCapiFunction == null) {
      -                CompilerDirectives.transferToInterpreterAndInvalidate();
      -                callCapiFunction = insert(CExtNodes.PCallCapiFunction.create());
      -            }
      -            return callCapiFunction;
      -        }
           }
       
           @Builtin(name = "tolist", minNumOfPositionalArgs = 1)
      @@ -424,38 +479,38 @@ public abstract static class ToListNode extends PythonUnaryBuiltinNode {
               @Specialization(guards = {"self.getDimensions() == cachedDimensions", "cachedDimensions < 8"}, limit = "3")
               Object tolistCached(VirtualFrame frame, PMemoryView self,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Cached("self.getDimensions()") int cachedDimensions,
                               @Shared @Cached MemoryViewNodes.ReadItemAtNode readItemAtNode,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   if (cachedDimensions == 0) {
                       // That's not a list but CPython does it this way
                       return readItemAtNode.execute(frame, self, self.getBufferPointer(), self.getOffset());
                   } else {
      -                return recursive(frame, self, readItemAtNode, 0, cachedDimensions, self.getBufferPointer(), self.getOffset(), factory);
      +                return recursive(frame, self, readItemAtNode, 0, cachedDimensions, self.getBufferPointer(), self.getOffset(), language);
                   }
               }
       
               @Specialization(replaces = "tolistCached")
               Object tolist(VirtualFrame frame, PMemoryView self,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Shared @Cached MemoryViewNodes.ReadItemAtNode readItemAtNode,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   if (self.getDimensions() == 0) {
                       return readItemAtNode.execute(frame, self, self.getBufferPointer(), self.getOffset());
                   } else {
      -                return recursiveBoundary(frame, self, readItemAtNode, 0, self.getDimensions(), self.getBufferPointer(), self.getOffset(), factory);
      +                return recursiveBoundary(frame, self, readItemAtNode, 0, self.getDimensions(), self.getBufferPointer(), self.getOffset(), language);
                   }
               }
       
      -        private PList recursiveBoundary(VirtualFrame frame, PMemoryView self, MemoryViewNodes.ReadItemAtNode readItemAtNode, int dim, int ndim, Object ptr, int offset, PythonObjectFactory factory) {
      -            return recursive(frame, self, readItemAtNode, dim, ndim, ptr, offset, factory);
      +        private PList recursiveBoundary(VirtualFrame frame, PMemoryView self, MemoryViewNodes.ReadItemAtNode readItemAtNode, int dim, int ndim, Object ptr, int offset, PythonLanguage language) {
      +            return recursive(frame, self, readItemAtNode, dim, ndim, ptr, offset, language);
               }
       
      -        private PList recursive(VirtualFrame frame, PMemoryView self, MemoryViewNodes.ReadItemAtNode readItemAtNode, int dim, int ndim, Object ptr, int initialOffset, PythonObjectFactory factory) {
      +        private PList recursive(VirtualFrame frame, PMemoryView self, MemoryViewNodes.ReadItemAtNode readItemAtNode, int dim, int ndim, Object ptr, int initialOffset, PythonLanguage language) {
                   int offset = initialOffset;
                   Object[] objects = new Object[self.getBufferShape()[dim]];
                   for (int i = 0; i < self.getBufferShape()[dim]; i++) {
      @@ -468,11 +523,11 @@ private PList recursive(VirtualFrame frame, PMemoryView self, MemoryViewNodes.Re
                       if (dim == ndim - 1) {
                           objects[i] = readItemAtNode.execute(frame, self, xptr, xoffset);
                       } else {
      -                    objects[i] = recursive(frame, self, readItemAtNode, dim + 1, ndim, xptr, xoffset, factory);
      +                    objects[i] = recursive(frame, self, readItemAtNode, dim + 1, ndim, xptr, xoffset, language);
                       }
                       offset += self.getBufferStrides()[dim];
                   }
      -            return factory.createList(objects);
      +            return PFactory.createList(language, objects);
               }
       
               private CExtNodes.PCallCapiFunction getCallCapiFunction() {
      @@ -499,9 +554,9 @@ public abstract static class ToBytesNode extends PythonBinaryClinicBuiltinNode {
               @Specialization
               PBytes tobytes(PMemoryView self, TruffleString order,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Cached TruffleString.EqualNode equalNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   byte[] bytes;
                   // The nodes act as branch profiles
      @@ -510,9 +565,9 @@ PBytes tobytes(PMemoryView self, TruffleString order,
                   } else if (equalNode.execute(order, T_F, TS_ENCODING)) {
                       bytes = getToJavaBytesFortranOrderNode().execute(self);
                   } else {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.ORDER_MUST_BE_C_F_OR_A);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.ORDER_MUST_BE_C_F_OR_A);
                   }
      -            return factory.createBytes(bytes);
      +            return PFactory.createBytes(language, bytes);
               }
       
               @Override
      @@ -549,7 +604,7 @@ TruffleString none(PMemoryView self, @SuppressWarnings("unused") PNone sep, @Sup
                               @Shared("p") @Cached InlinedConditionProfile earlyExit,
                               @Shared("b") @Cached MemoryViewNodes.ToJavaBytesNode toJavaBytesNode,
                               @Shared("h") @Cached BytesNodes.ByteToHexNode toHexNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   return hex(self, (byte) 0, 0, inliningTarget, earlyExit, toJavaBytesNode, toHexNode, raiseNode);
               }
       
      @@ -559,7 +614,7 @@ TruffleString hex(PMemoryView self, byte sep, int bytesPerSepGroup,
                               @Shared("p") @Cached InlinedConditionProfile earlyExit,
                               @Shared("b") @Cached MemoryViewNodes.ToJavaBytesNode toJavaBytesNode,
                               @Shared("h") @Cached BytesNodes.ByteToHexNode toHexNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   if (earlyExit.profile(inliningTarget, self.getLength() == 0)) {
                       return T_EMPTY_STRING;
      @@ -584,11 +639,11 @@ public final Object call(VirtualFrame frame, Object arg) {
       
               @Specialization
               static PMemoryView toreadonly(PMemoryView self,
      +                        @Bind PythonLanguage language,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
      -            return factory.createMemoryView(PythonContext.get(inliningTarget), self.getLifecycleManager(), self.getBuffer(), self.getOwner(), self.getLength(), true,
      +            return PFactory.createMemoryView(language, PythonContext.get(inliningTarget), self.getLifecycleManager(), self.getBuffer(), self.getOwner(), self.getLength(), true,
                                   self.getItemSize(), self.getFormat(), self.getFormatString(), self.getDimensions(), self.getBufferPointer(),
                                   self.getOffset(), self.getBufferShape(), self.getBufferStrides(), self.getBufferSuboffsets(), self.getFlags());
               }
      @@ -604,10 +659,9 @@ static PMemoryView cast(PMemoryView self, TruffleString formatString, @SuppressW
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached TruffleString.CodePointLengthNode lengthNode,
                               @Shared @Cached TruffleString.CodePointAtIndexNode atIndexNode,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
      -            return doCast(inliningTarget, self, formatString, 1, null, PythonContext.get(inliningTarget), lengthNode, atIndexNode, factory, raiseNode);
      +            return doCast(inliningTarget, self, formatString, 1, null, PythonContext.get(inliningTarget), lengthNode, atIndexNode, raiseNode);
               }
       
               @Specialization(guards = "isPTuple(shapeObj) || isList(shapeObj)")
      @@ -618,8 +672,7 @@ static PMemoryView cast(VirtualFrame frame, PMemoryView self, TruffleString form
                               @Cached PyNumberAsSizeNode asSizeNode,
                               @Shared @Cached TruffleString.CodePointLengthNode lengthNode,
                               @Shared @Cached TruffleString.CodePointAtIndexNode atIndexNode,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   SequenceStorage storage = getSequenceStorageNode.execute(inliningTarget, shapeObj);
                   int ndim = storage.length();
      @@ -627,39 +680,39 @@ static PMemoryView cast(VirtualFrame frame, PMemoryView self, TruffleString form
                   for (int i = 0; i < ndim; i++) {
                       shape[i] = asSizeNode.executeExact(frame, inliningTarget, getItemScalarNode.execute(inliningTarget, storage, i));
                       if (shape[i] <= 0) {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MEMORYVIEW_CAST_ELEMENTS_MUST_BE_POSITIVE_INTEGERS);
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MEMORYVIEW_CAST_ELEMENTS_MUST_BE_POSITIVE_INTEGERS);
                       }
                   }
      -            return doCast(inliningTarget, self, formatString, ndim, shape, PythonContext.get(inliningTarget), lengthNode, atIndexNode, factory, raiseNode);
      +            return doCast(inliningTarget, self, formatString, ndim, shape, PythonContext.get(inliningTarget), lengthNode, atIndexNode, raiseNode);
               }
       
               @Specialization(guards = {"!isPTuple(shape)", "!isList(shape)", "!isPNone(shape)"})
               @SuppressWarnings("unused")
               static PMemoryView error(PMemoryView self, TruffleString format, Object shape,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.ARG_S_MUST_BE_A_LIST_OR_TUPLE, "shape");
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.ARG_S_MUST_BE_A_LIST_OR_TUPLE, "shape");
               }
       
               private static PMemoryView doCast(Node inliningTarget, PMemoryView self, TruffleString formatString, int ndim, int[] shape, PythonContext context, TruffleString.CodePointLengthNode lengthNode,
      -                        TruffleString.CodePointAtIndexNode atIndexNode, PythonObjectFactory factory, PRaiseNode.Lazy raiseNode) {
      +                        TruffleString.CodePointAtIndexNode atIndexNode, PRaiseNode raiseNode) {
                   if (!self.isCContiguous()) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MEMORYVIEW_CASTS_RESTRICTED_TO_C_CONTIGUOUS);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MEMORYVIEW_CASTS_RESTRICTED_TO_C_CONTIGUOUS);
                   }
                   BufferFormat format = BufferFormat.forMemoryView(formatString, lengthNode, atIndexNode);
                   int itemsize = format.bytesize;
                   if (itemsize < 0) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MEMORYVIEW_DESTINATION_FORMAT_ERROR);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MEMORYVIEW_DESTINATION_FORMAT_ERROR);
                   }
                   if (!MemoryViewNodes.isByteFormat(format) && !MemoryViewNodes.isByteFormat(self.getFormat())) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MEMORYVIEW_CANNOT_CAST_NON_BYTE);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MEMORYVIEW_CANNOT_CAST_NON_BYTE);
                   }
                   if (self.getLength() % itemsize != 0) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MEMORYVIEW_LENGTH_NOT_MULTIPLE_OF_ITEMSIZE);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MEMORYVIEW_LENGTH_NOT_MULTIPLE_OF_ITEMSIZE);
                   }
                   if (shape != null || self.getDimensions() != 1) {
                       for (int i = 0; i < self.getDimensions(); i++) {
                           if (self.getBufferShape()[i] == 0) {
      -                        throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MEMORYVIEW_CANNOT_CAST_VIEW_WITH_ZEROS_IN_SHAPE_OR_STRIDES);
      +                        throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MEMORYVIEW_CANNOT_CAST_VIEW_WITH_ZEROS_IN_SHAPE_OR_STRIDES);
                           }
                       }
                   }
      @@ -671,30 +724,30 @@ private static PMemoryView doCast(Node inliningTarget, PMemoryView self, Truffle
                       newStrides = null;
                       flags |= PMemoryView.FLAG_SCALAR;
                       if (self.getLength() != itemsize) {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MEMORYVIEW_CAST_WRONG_LENGTH);
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MEMORYVIEW_CAST_WRONG_LENGTH);
                       }
                   } else {
                       if (shape == null) {
                           newShape = new int[]{self.getLength() / itemsize};
                       } else {
                           if (ndim != 1 && self.getDimensions() != 1) {
      -                        throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MEMORYVIEW_CAST_MUST_BE_1D_TO_ND_OR_ND_TO_1D);
      +                        throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MEMORYVIEW_CAST_MUST_BE_1D_TO_ND_OR_ND_TO_1D);
                           }
                           if (ndim > PMemoryView.MAX_DIM) {
      -                        throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MEMORYVIEW_NUMBER_OF_DIMENSIONS_MUST_NOT_EXCEED_D, ndim);
      +                        throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MEMORYVIEW_NUMBER_OF_DIMENSIONS_MUST_NOT_EXCEED_D, ndim);
                           }
                           int newLength = itemsize;
                           for (int i = 0; i < ndim; i++) {
                               newLength *= shape[i];
                           }
                           if (newLength != self.getLength()) {
      -                        throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MEMORYVIEW_CAST_WRONG_LENGTH);
      +                        throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MEMORYVIEW_CAST_WRONG_LENGTH);
                           }
                           newShape = shape;
                       }
                       newStrides = PMemoryView.initStridesFromShape(ndim, itemsize, shape);
                   }
      -            return factory.createMemoryView(context, self.getLifecycleManager(), self.getBuffer(), self.getOwner(), self.getLength(), self.isReadOnly(),
      +            return PFactory.createMemoryView(PythonLanguage.get(inliningTarget), context, self.getLifecycleManager(), self.getBuffer(), self.getOwner(), self.getLength(), self.isReadOnly(),
                                   itemsize, format, formatString, ndim, self.getBufferPointer(),
                                   self.getOffset(), newShape, newStrides, null, flags);
               }
      @@ -714,13 +767,13 @@ public abstract static class LenNode extends LenBuiltinNode {
               static int len(PMemoryView self,
                               @Bind("this") Node inliningTarget,
                               @Cached InlinedConditionProfile zeroDimProfile,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   return zeroDimProfile.profile(inliningTarget, self.getDimensions() == 0) ? 1 : self.getBufferShape()[0];
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -734,22 +787,22 @@ static TruffleString repr(PMemoryView self,
               }
           }
       
      -    @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_hash, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class HashNode extends PythonUnaryBuiltinNode {
      +    public abstract static class HashNode extends HashBuiltinNode {
               @Specialization
      -        static int hash(PMemoryView self,
      +        static long hash(PMemoryView self,
                               @Bind("this") Node inliningTarget,
                               @Cached InlinedConditionProfile cachedProfile,
                               @Cached InlinedConditionProfile writableProfile,
                               @Cached MemoryViewNodes.ToJavaBytesNode toJavaBytesNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (cachedProfile.profile(inliningTarget, self.getCachedHash() != -1)) {
                       return self.getCachedHash();
                   }
                   self.checkReleased(inliningTarget, raiseNode);
                   if (writableProfile.profile(inliningTarget, !self.isReadOnly())) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.CANNOT_HASH_WRITEABLE_MEMORYVIEW);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.CANNOT_HASH_WRITEABLE_MEMORYVIEW);
                   } else {
                       // TODO avoid copying
                       int hash = hashArray(toJavaBytesNode.execute(self));
      @@ -770,7 +823,7 @@ public abstract static class EnterNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object enter(PMemoryView self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   return self;
               }
      @@ -806,7 +859,7 @@ public abstract static class ItemSizeNode extends PythonUnaryBuiltinNode {
               @Specialization
               static int get(PMemoryView self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   return self.getItemSize();
               }
      @@ -819,7 +872,7 @@ public abstract static class NBytesNode extends PythonUnaryBuiltinNode {
               @Specialization
               static int get(PMemoryView self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   return self.getLength();
               }
      @@ -832,7 +885,7 @@ public abstract static class ObjNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object get(PMemoryView self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   return self.getOwner() != null ? self.getOwner() : PNone.NONE;
               }
      @@ -845,7 +898,7 @@ public abstract static class FormatNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object get(PMemoryView self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   return self.getFormatString() != null ? self.getFormatString() : T_UINT_8_TYPE_CODE;
               }
      @@ -858,14 +911,14 @@ public abstract static class ShapeNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object get(PMemoryView self,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Cached InlinedConditionProfile nullProfile,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   if (nullProfile.profile(inliningTarget, self.getBufferShape() == null)) {
      -                return factory.createEmptyTuple();
      +                return PFactory.createEmptyTuple(language);
                   }
      -            return factory.createTuple(new IntSequenceStorage(self.getBufferShape()));
      +            return PFactory.createTuple(language, new IntSequenceStorage(self.getBufferShape()));
               }
           }
       
      @@ -876,14 +929,14 @@ public abstract static class StridesNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object get(PMemoryView self,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Cached InlinedConditionProfile nullProfile,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   if (nullProfile.profile(inliningTarget, self.getBufferStrides() == null)) {
      -                return factory.createEmptyTuple();
      +                return PFactory.createEmptyTuple(language);
                   }
      -            return factory.createTuple(new IntSequenceStorage(self.getBufferStrides()));
      +            return PFactory.createTuple(language, new IntSequenceStorage(self.getBufferStrides()));
               }
           }
       
      @@ -894,14 +947,14 @@ public abstract static class SuboffsetsNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object get(PMemoryView self,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Cached InlinedConditionProfile nullProfile,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   if (nullProfile.profile(inliningTarget, self.getBufferSuboffsets() == null)) {
      -                return factory.createEmptyTuple();
      +                return PFactory.createEmptyTuple(language);
                   }
      -            return factory.createTuple(new IntSequenceStorage(self.getBufferSuboffsets()));
      +            return PFactory.createTuple(language, new IntSequenceStorage(self.getBufferSuboffsets()));
               }
           }
       
      @@ -912,7 +965,7 @@ public abstract static class ReadonlyNode extends PythonUnaryBuiltinNode {
               @Specialization
               static boolean get(PMemoryView self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   return self.isReadOnly();
               }
      @@ -925,7 +978,7 @@ public abstract static class NDimNode extends PythonUnaryBuiltinNode {
               @Specialization
               static int get(PMemoryView self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   return self.getDimensions();
               }
      @@ -938,7 +991,7 @@ public abstract static class CContiguousNode extends PythonUnaryBuiltinNode {
               @Specialization
               static boolean get(PMemoryView self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   return self.isCContiguous();
               }
      @@ -951,7 +1004,7 @@ public abstract static class FContiguousNode extends PythonUnaryBuiltinNode {
               @Specialization
               static boolean get(PMemoryView self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   return self.isFortranContiguous();
               }
      @@ -964,7 +1017,7 @@ public abstract static class ContiguousNode extends PythonUnaryBuiltinNode {
               @Specialization
               static boolean get(PMemoryView self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   return self.isAnyContiguous();
               }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java
      index 227216af94..00d5a649ba 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -103,7 +103,7 @@ static void checkBufferBounds(Node node, PMemoryView self, PythonBufferAccessLib
                    * reference counting.
                    */
                   CompilerDirectives.transferToInterpreterAndInvalidate();
      -            throw PRaiseNode.raiseUncached(node, IndexError, ErrorMessages.INVALID_BUFFER_ACCESS);
      +            throw PRaiseNode.raiseStatic(node, IndexError, ErrorMessages.INVALID_BUFFER_ACCESS);
               }
           }
       
      @@ -158,7 +158,7 @@ static Object unpack(Node inliningTarget, BufferFormat format, @SuppressWarnings
               @Fallback
               @SuppressWarnings("unused")
               static Object notImplemented(Node inliningTarget, BufferFormat format, TruffleString formatStr, Object buffer, int offset) {
      -            throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, ErrorMessages.MEMORYVIEW_FORMAT_S_NOT_SUPPORTED, formatStr);
      +            throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, ErrorMessages.MEMORYVIEW_FORMAT_S_NOT_SUPPORTED, formatStr);
               }
           }
       
      @@ -172,19 +172,19 @@ public abstract static class PackValueNode extends Node {
               static void pack(VirtualFrame frame, Node inliningTarget, BufferFormat format, TruffleString formatStr, Object value, Object buffer, int offset,
                               @Cached IsBuiltinObjectProfile errorProfile,
                               @Cached BufferStorageNodes.PackValueNode packValueNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   try {
                       packValueNode.execute(frame, inliningTarget, format, value, buffer, offset);
                   } catch (PException e) {
                       e.expect(inliningTarget, OverflowError, errorProfile);
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MEMORYVIEW_INVALID_VALUE_FOR_FORMAT_S, formatStr);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MEMORYVIEW_INVALID_VALUE_FOR_FORMAT_S, formatStr);
                   }
               }
       
               @Fallback
               @SuppressWarnings("unused")
               static void notImplemented(Node inliningTarget, BufferFormat format, TruffleString formatStr, Object object, Object buffer, int offset) {
      -            throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, ErrorMessages.MEMORYVIEW_FORMAT_S_NOT_SUPPORTED, formatStr);
      +            throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, ErrorMessages.MEMORYVIEW_FORMAT_S_NOT_SUPPORTED, formatStr);
               }
           }
       
      @@ -340,7 +340,7 @@ abstract static class PointerLookupNode extends Node {
       
               public abstract MemoryPointer execute(VirtualFrame frame, PMemoryView self, int index);
       
      -        private void lookupDimension(Node inliningTarget, PMemoryView self, MemoryPointer ptr, int dim, int initialIndex, InlinedConditionProfile hasSuboffsetsProfile, PRaiseNode.Lazy raiseNode) {
      +        private void lookupDimension(Node inliningTarget, PMemoryView self, MemoryPointer ptr, int dim, int initialIndex, InlinedConditionProfile hasSuboffsetsProfile, PRaiseNode raiseNode) {
                   int index = initialIndex;
                   int[] shape = self.getBufferShape();
                   int nitems = shape[dim];
      @@ -348,7 +348,7 @@ private void lookupDimension(Node inliningTarget, PMemoryView self, MemoryPointe
                       index += nitems;
                   }
                   if (index < 0 || index >= nitems) {
      -                throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.INDEX_OUT_OF_BOUNDS_ON_DIMENSION_D, dim + 1);
      +                throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.INDEX_OUT_OF_BOUNDS_ON_DIMENSION_D, dim + 1);
                   }
       
                   ptr.offset += self.getBufferStrides()[dim] * index;
      @@ -367,17 +367,17 @@ MemoryPointer resolveInt(PMemoryView self, int index,
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached InlinedConditionProfile hasOneDimensionProfile,
                               @Shared @Cached InlinedConditionProfile hasSuboffsetsProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   if (hasOneDimensionProfile.profile(inliningTarget, self.getDimensions() == 1)) {
                       MemoryPointer ptr = new MemoryPointer(self.getBufferPointer(), self.getOffset());
                       lookupDimension(inliningTarget, self, ptr, 0, index, hasSuboffsetsProfile, raiseNode);
                       return ptr;
                   }
                   if (self.getDimensions() == 0) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.INVALID_INDEXING_OF_0_DIM_MEMORY);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.INVALID_INDEXING_OF_0_DIM_MEMORY);
                   } else {
                       // CPython doesn't implement this either, as of 3.8
      -                throw raiseNode.get(inliningTarget).raise(NotImplementedError, ErrorMessages.MULTI_DIMENSIONAL_SUB_VIEWS_NOT_IMPLEMENTED);
      +                throw raiseNode.raise(inliningTarget, NotImplementedError, ErrorMessages.MULTI_DIMENSIONAL_SUB_VIEWS_NOT_IMPLEMENTED);
                   }
               }
       
      @@ -391,7 +391,7 @@ MemoryPointer resolveTupleCached(VirtualFrame frame, PMemoryView self, PTuple in
                               @Cached("self.getDimensions()") int cachedDimensions,
                               @Shared @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode,
                               @Shared @Cached SequenceStorageNodes.GetItemScalarNode getItemNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   SequenceStorage indicesStorage = getSequenceStorageNode.execute(inliningTarget, indices);
                   checkTupleLength(inliningTarget, indicesStorage, cachedDimensions, raiseNode);
                   MemoryPointer ptr = new MemoryPointer(self.getBufferPointer(), self.getOffset());
      @@ -410,7 +410,7 @@ MemoryPointer resolveTupleGeneric(VirtualFrame frame, PMemoryView self, PTuple i
                               @Shared @Cached PyIndexCheckNode indexCheckNode,
                               @Shared @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode,
                               @Shared @Cached SequenceStorageNodes.GetItemScalarNode getItemNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   SequenceStorage indicesStorage = getSequenceStorageNode.execute(inliningTarget, indices);
                   int ndim = self.getDimensions();
                   checkTupleLength(inliningTarget, indicesStorage, ndim, raiseNode);
      @@ -429,30 +429,30 @@ MemoryPointer resolveIntObj(VirtualFrame frame, PMemoryView self, Object indexOb
                               @Shared @Cached InlinedConditionProfile hasOneDimensionProfile,
                               @Shared @Cached InlinedConditionProfile hasSuboffsetsProfile,
                               @Shared @Cached PyIndexCheckNode indexCheckNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   final int index = convertIndex(frame, inliningTarget, indexCheckNode, indexObj, raiseNode);
                   return resolveInt(self, index, inliningTarget, hasOneDimensionProfile, hasSuboffsetsProfile, raiseNode);
               }
       
      -        private static void checkTupleLength(Node inliningTarget, SequenceStorage indicesStorage, int ndim, PRaiseNode.Lazy raiseNode) {
      +        private static void checkTupleLength(Node inliningTarget, SequenceStorage indicesStorage, int ndim, PRaiseNode raiseNode) {
                   int length = indicesStorage.length();
                   if (length == ndim) {
                       return;
                   }
                   // Error cases
                   if (ndim == 0) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.INVALID_INDEXING_OF_0_DIM_MEMORY);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.INVALID_INDEXING_OF_0_DIM_MEMORY);
                   } else if (length > ndim) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANNOT_INDEX_D_DIMENSION_VIEW_WITH_D, ndim, length);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANNOT_INDEX_D_DIMENSION_VIEW_WITH_D, ndim, length);
                   } else {
                       // CPython doesn't implement this either, as of 3.8
      -                throw raiseNode.get(inliningTarget).raise(NotImplementedError, ErrorMessages.SUB_VIEWS_NOT_IMPLEMENTED);
      +                throw raiseNode.raise(inliningTarget, NotImplementedError, ErrorMessages.SUB_VIEWS_NOT_IMPLEMENTED);
                   }
               }
       
      -        private int convertIndex(VirtualFrame frame, Node inliningTarget, PyIndexCheckNode indexCheckNode, Object indexObj, PRaiseNode.Lazy raiseNode) {
      +        private int convertIndex(VirtualFrame frame, Node inliningTarget, PyIndexCheckNode indexCheckNode, Object indexObj, PRaiseNode raiseNode) {
                   if (!indexCheckNode.execute(inliningTarget, indexObj)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MEMORYVIEW_INVALID_SLICE_KEY);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MEMORYVIEW_INVALID_SLICE_KEY);
                   }
                   return getAsSizeNode().executeExact(frame, inliningTarget, indexObj, IndexError);
               }
      @@ -486,7 +486,7 @@ byte[] tobytesCached(PMemoryView self,
                               @Cached("self.getDimensions()") int cachedDimensions,
                               @Shared @Cached ReadBytesAtNode readBytesAtNode,
                               @Shared @Cached CExtNodes.PCallCapiFunction callCapiFunction,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   byte[] bytes = new byte[self.getLength()];
                   if (cachedDimensions == 0) {
      @@ -502,7 +502,7 @@ byte[] tobytesGeneric(PMemoryView self,
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached ReadBytesAtNode readBytesAtNode,
                               @Shared @Cached CExtNodes.PCallCapiFunction callCapiFunction,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   self.checkReleased(inliningTarget, raiseNode);
                   byte[] bytes = new byte[self.getLength()];
                   if (self.getDimensions() == 0) {
      @@ -596,8 +596,9 @@ public final void execute(PMemoryView self) {
       
               @Specialization(guards = "self.getReference() == null")
               static void releaseSimple(PMemoryView self,
      +                        @Bind("this") Node inliningTarget,
                               @Shared("raise") @Cached PRaiseNode raiseNode) {
      -            self.checkExports(raiseNode);
      +            self.checkExports(inliningTarget, raiseNode);
                   self.setReleased();
               }
       
      @@ -607,7 +608,7 @@ static void releaseNative(VirtualFrame frame, PMemoryView self,
                               @Cached("createFor(this)") IndirectCallData indirectCallData,
                               @Cached ReleaseBufferNode releaseNode,
                               @Shared("raise") @Cached PRaiseNode raiseNode) {
      -            self.checkExports(raiseNode);
      +            self.checkExports(inliningTarget, raiseNode);
                   if (self.checkShouldReleaseBuffer()) {
                       releaseNode.execute(frame, inliningTarget, indirectCallData, self.getLifecycleManager());
                   }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/PMemoryView.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/PMemoryView.java
      index fb958911da..f0eed188e5 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/PMemoryView.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/PMemoryView.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -250,9 +250,9 @@ public void setShouldReleaseImmediately(boolean shouldReleaseImmediately) {
               this.shouldReleaseImmediately = shouldReleaseImmediately;
           }
       
      -    public void checkReleased(Node inliningTarget, PRaiseNode.Lazy raiseNode) {
      +    public void checkReleased(Node inliningTarget, PRaiseNode raiseNode) {
               if (isReleased()) {
      -            throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.MEMORYVIEW_FORBIDDEN_RELEASED);
      +            throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.MEMORYVIEW_FORBIDDEN_RELEASED);
               }
           }
       
      @@ -263,10 +263,10 @@ boolean checkShouldReleaseBuffer() {
               return false;
           }
       
      -    void checkExports(PRaiseNode node) {
      +    void checkExports(Node inliningTarget, PRaiseNode node) {
               long exportsValue = getExports().get();
               if (exportsValue > 0) {
      -            throw node.raise(BufferError, ErrorMessages.MEMORYVIEW_HAS_D_EXPORTED_BUFFERS, exportsValue);
      +            throw node.raise(inliningTarget, BufferError, ErrorMessages.MEMORYVIEW_HAS_D_EXPORTED_BUFFERS, exportsValue);
               }
           }
       
      @@ -290,29 +290,29 @@ int getBufferLength() {
           @ExportMessage
           Object acquire(int requestedFlags,
                           @Bind("$node") Node inliningTarget,
      -                    @Cached PRaiseNode.Lazy raiseNode) {
      +                    @Cached PRaiseNode raiseNode) {
               checkReleased(inliningTarget, raiseNode);
               if (BufferFlags.requestsWritable(requestedFlags) && readonly) {
      -            throw raiseNode.get(inliningTarget).raise(BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_WRITABLE);
      +            throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_WRITABLE);
               }
               if (BufferFlags.requestsCContiguous(requestedFlags) && !isCContiguous()) {
      -            throw raiseNode.get(inliningTarget).raise(BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_C_CONTIGUOUS);
      +            throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_C_CONTIGUOUS);
               }
               if (BufferFlags.requestsFContiguous(requestedFlags) && !isFortranContiguous()) {
      -            throw raiseNode.get(inliningTarget).raise(BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_FORTRAN_CONTIGUOUS);
      +            throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_FORTRAN_CONTIGUOUS);
               }
               if (BufferFlags.requestsAnyContiguous(requestedFlags) && !isAnyContiguous()) {
      -            throw raiseNode.get(inliningTarget).raise(BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_CONTIGUOUS);
      +            throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_CONTIGUOUS);
               }
               if (!BufferFlags.requestsIndirect(requestedFlags) && (flags & FLAG_PIL) != 0) {
      -            throw raiseNode.get(inliningTarget).raise(BufferError, ErrorMessages.MV_UNDERLYING_BUF_REQUIRES_SUBOFFSETS);
      +            throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_REQUIRES_SUBOFFSETS);
               }
               if (!BufferFlags.requestsStrides(requestedFlags) && !isCContiguous()) {
      -            throw raiseNode.get(inliningTarget).raise(BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_C_CONTIGUOUS);
      +            throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_C_CONTIGUOUS);
               }
               // TODO should reflect the cast to unsigned bytes if necessary
               if (!BufferFlags.requestsShape(requestedFlags) && BufferFlags.requestsFormat(requestedFlags)) {
      -            throw raiseNode.get(inliningTarget).raise(BufferError, ErrorMessages.MV_CANNOT_CAST_UNSIGNED_BYTES_IF_FMT_FLAG);
      +            throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_CANNOT_CAST_UNSIGNED_BYTES_IF_FMT_FLAG);
               }
               exports.incrementAndGet();
               return this;
      @@ -329,7 +329,7 @@ void release(
                * should be no such helper memoryviews, the C buffer should have a separate implementation.
                */
               if (shouldReleaseImmediately) {
      -            checkExports(raiseNode);
      +            checkExports(inliningTarget, raiseNode);
                   if (checkShouldReleaseBuffer()) {
                       releaseNode.execute(inliningTarget, getLifecycleManager());
                   }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractBuiltinMethodBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractBuiltinMethodBuiltins.java
      index 19861c30e8..815e3ca134 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractBuiltinMethodBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractBuiltinMethodBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2017, 2023, Oracle and/or its affiliates.
      + * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
        * Copyright (c) 2014, Regents of the University of California
        *
        * All rights reserved.
      @@ -116,7 +116,7 @@ static TruffleString getQualName(VirtualFrame frame, PMethod method,
                               @Shared @Cached InlinedConditionProfile isGlobalProfile,
                               @Shared @Cached GetClassNode getClassNode,
                               @Shared @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   return makeQualname(frame, inliningTarget, method, method.getSelf(), getQualNameAttrNode, getNameAttrNode, castToStringNode, getClassNode, isTypeNode, isGlobalProfile,
                                   simpleTruffleStringFormatNode, raiseNode);
               }
      @@ -131,19 +131,19 @@ static TruffleString getQualName(VirtualFrame frame, PBuiltinMethod method,
                               @Shared @Cached InlinedConditionProfile isGlobalProfile,
                               @Shared @Cached GetClassNode getClassNode,
                               @Shared @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   return makeQualname(frame, inliningTarget, method, method.getSelf(), getQualNameAttrNode, getNameAttrNode, castToStringNode, getClassNode, isTypeNode, isGlobalProfile,
                                   simpleTruffleStringFormatNode, raiseNode);
               }
       
               private static TruffleString makeQualname(VirtualFrame frame, Node inliningTarget, Object method, Object self, GetAttributeNode getQualNameAttrNode, GetAttributeNode getNameAttrNode,
                               CastToTruffleStringNode castToStringNode, GetClassNode getClassNode, TypeNodes.IsTypeNode isTypeNode, InlinedConditionProfile isGlobalProfile,
      -                        SimpleTruffleStringFormatNode simpleTruffleStringFormatNode, PRaiseNode.Lazy raiseNode) {
      +                        SimpleTruffleStringFormatNode simpleTruffleStringFormatNode, PRaiseNode raiseNode) {
                   TruffleString methodName;
                   try {
                       methodName = castToStringNode.execute(inliningTarget, getNameAttrNode.executeObject(frame, method));
                   } catch (CannotCastException e) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.IS_NOT_A_UNICODE_OBJECT, T___NAME__);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.IS_NOT_A_UNICODE_OBJECT, T___NAME__);
                   }
                   if (isGlobalProfile.profile(inliningTarget, self == PNone.NO_VALUE || self instanceof PythonModule)) {
                       return methodName;
      @@ -154,7 +154,7 @@ private static TruffleString makeQualname(VirtualFrame frame, Node inliningTarge
                   try {
                       typeQualName = castToStringNode.execute(inliningTarget, getQualNameAttrNode.executeObject(frame, type));
                   } catch (CannotCastException e) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.IS_NOT_A_UNICODE_OBJECT, T___QUALNAME__);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.IS_NOT_A_UNICODE_OBJECT, T___QUALNAME__);
                   }
       
                   return simpleTruffleStringFormatNode.format("%s.%s", typeQualName, methodName);
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractMethodBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractMethodBuiltins.java
      index ab1ae548c8..7207cf976f 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractMethodBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractMethodBuiltins.java
      @@ -37,34 +37,40 @@
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___MODULE__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___QUALNAME__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       
       import java.util.List;
       
       import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.PNotImplemented;
       import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
       import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
       import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.module.PythonModule;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.RichCmpBuiltinNode;
       import com.oracle.graal.python.lib.PyObjectGetAttr;
       import com.oracle.graal.python.lib.PyObjectLookupAttr;
      +import com.oracle.graal.python.lib.RichCmpOp;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
       import com.oracle.graal.python.nodes.attributes.ReadAttributeFromPythonObjectNode;
       import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      @@ -76,7 +82,7 @@
       import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
       import com.oracle.graal.python.runtime.IndirectCallData;
       import com.oracle.graal.python.runtime.PythonContext;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.dsl.Bind;
      @@ -89,47 +95,37 @@
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.interop.InteropLibrary;
       import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PMethod, PythonBuiltinClassType.PBuiltinFunctionOrMethod, PythonBuiltinClassType.MethodWrapper})
       public final class AbstractMethodBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = AbstractMethodBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return AbstractMethodBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @Slot(value = SlotKind.tp_call, isComplex = true)
      +    @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
           @GenerateNodeFactory
      -    public abstract static class CallNode extends PythonVarargsBuiltinNode {
      -        @Child private com.oracle.graal.python.nodes.call.CallNode callNode = com.oracle.graal.python.nodes.call.CallNode.create();
      -
      -        @Specialization(guards = "isFunction(self.getFunction())")
      -        protected Object doIt(VirtualFrame frame, PMethod self, Object[] arguments, PKeyword[] keywords) {
      -            return callNode.execute(frame, self, arguments, keywords);
      -        }
      -
      -        @Specialization(guards = "isFunction(self.getFunction())")
      -        protected Object doIt(VirtualFrame frame, PBuiltinMethod self, Object[] arguments, PKeyword[] keywords) {
      -            return callNode.execute(frame, self, arguments, keywords);
      -        }
      +    abstract static class CallNode extends PythonVarargsBuiltinNode {
       
      -        @Specialization(guards = "!isFunction(self.getFunction())")
      -        protected Object doItNonFunction(VirtualFrame frame, PMethod self, Object[] arguments, PKeyword[] keywords) {
      +        @Specialization
      +        static Object doItNonFunction(VirtualFrame frame, PMethod self, Object[] arguments, PKeyword[] keywords,
      +                        @Cached com.oracle.graal.python.nodes.call.CallNode callNode) {
                   return callNode.execute(frame, self.getFunction(), PythonUtils.prependArgument(self.getSelf(), arguments), keywords);
               }
       
      -        @Specialization(guards = "!isFunction(self.getFunction())")
      -        protected Object doItNonFunction(VirtualFrame frame, PBuiltinMethod self, Object[] arguments, PKeyword[] keywords) {
      -            return callNode.execute(frame, self.getFunction(), PythonUtils.prependArgument(self.getSelf(), arguments), keywords);
      +        @Specialization
      +        static Object doItNonFunction(VirtualFrame frame, PBuiltinMethod self, Object[] arguments, PKeyword[] keywords,
      +                        @Bind Node inliningTarget,
      +                        @Cached CallDispatchers.BuiltinMethodCachedCallNode callNode) {
      +            return callNode.execute(frame, inliningTarget, self, arguments, keywords);
               }
       
      -        @Override
      -        public Object varArgExecute(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported {
      -            Object[] argsWithoutSelf = new Object[arguments.length - 1];
      -            PythonUtils.arraycopy(arguments, 1, argsWithoutSelf, 0, argsWithoutSelf.length);
      -            return execute(frame, arguments[0], argsWithoutSelf, keywords);
      -        }
           }
       
           @Builtin(name = J___SELF__, minNumOfPositionalArgs = 1, isGetter = true)
      @@ -149,9 +145,9 @@ protected static Object doIt(PBuiltinMethod self) {
               }
           }
       
      -    @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.tp_richcompare, isComplex = true)
           @GenerateNodeFactory
      -    abstract static class EqNode extends PythonBinaryBuiltinNode {
      +    abstract static class EqNode extends RichCmpBuiltinNode {
       
               @Child private InteropLibrary identicalLib = InteropLibrary.getFactory().createDispatched(3);
               @Child private InteropLibrary identicalLib2 = InteropLibrary.getFactory().createDispatched(3);
      @@ -172,25 +168,46 @@ private boolean eq(Object function1, Object function2, Object self1, Object self
                   return true;
               }
       
      -        @Specialization
      -        boolean eq(PMethod self, PMethod other) {
      -            return eq(self.getFunction(), other.getFunction(), self.getSelf(), other.getSelf());
      -        }
      +        @Specialization(guards = "op.isEqOrNe()")
      +        boolean eqOrNe(Object self, Object other, RichCmpOp op,
      +                        @Bind("$node") Node inliningTarget,
      +                        @Cached InlinedConditionProfile isBuiltinProfile,
      +                        @Cached InlinedConditionProfile isMethodProfile) {
      +            Object selfFunction, otherFunction;
      +            Object selfSelf, otherSelf;
      +
      +            if (isBuiltinProfile.profile(inliningTarget, self instanceof PBuiltinMethod)) {
      +                selfFunction = ((PBuiltinMethod) self).getBuiltinFunction();
      +                selfSelf = ((PBuiltinMethod) self).getSelf();
      +            } else if (isMethodProfile.profile(inliningTarget, self instanceof PMethod)) {
      +                selfFunction = ((PMethod) self).getFunction();
      +                selfSelf = ((PMethod) self).getSelf();
      +            } else {
      +                return op.isNe();
      +            }
       
      -        @Specialization
      -        boolean eq(PBuiltinMethod self, PBuiltinMethod other) {
      -            return eq(self.getFunction(), other.getFunction(), self.getSelf(), other.getSelf());
      +            if (isBuiltinProfile.profile(inliningTarget, other instanceof PBuiltinMethod)) {
      +                otherFunction = ((PBuiltinMethod) other).getBuiltinFunction();
      +                otherSelf = ((PBuiltinMethod) other).getSelf();
      +            } else if (isMethodProfile.profile(inliningTarget, other instanceof PMethod)) {
      +                otherFunction = ((PMethod) other).getFunction();
      +                otherSelf = ((PMethod) other).getSelf();
      +            } else {
      +                return op.isNe();
      +            }
      +
      +            return eq(selfFunction, otherFunction, selfSelf, otherSelf) == op.isEq();
               }
       
               @Fallback
      -        static boolean eq(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object other) {
      -            return false;
      +        static Object others(Object self, Object other, RichCmpOp op) {
      +            return PNotImplemented.NOT_IMPLEMENTED;
               }
           }
       
      -    @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_hash, isComplex = true)
           @GenerateNodeFactory
      -    abstract static class HashNode extends PythonUnaryBuiltinNode {
      +    abstract static class HashNode extends HashBuiltinNode {
               @Specialization
               static long hash(PMethod self) {
                   return PythonAbstractObject.systemHashCode(self.getSelf()) ^ PythonAbstractObject.systemHashCode(self.getFunction());
      @@ -245,8 +262,8 @@ static Object getModule(VirtualFrame frame, PMethod self, @SuppressWarnings("unu
       
               @Specialization(guards = "!isNoValue(value)")
               static Object getModule(@SuppressWarnings("unused") PMethod self, @SuppressWarnings("unused") Object value,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "method", T___MODULE__);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, "method", T___MODULE__);
               }
           }
       
      @@ -333,7 +350,7 @@ static TruffleString doSelfIsObject(VirtualFrame frame, PMethod method,
                               @Shared("getQualname") @Cached PyObjectGetAttr getQualname,
                               @Shared("lookupName") @Cached PyObjectLookupAttr lookupName,
                               @Shared("formatter") @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   return getQualName(frame, inliningTarget, method.getSelf(), method.getFunction(), getClassNode, isTypeNode, toStringNode, getQualname, lookupName, simpleTruffleStringFormatNode,
                                   raiseNode);
               }
      @@ -347,21 +364,21 @@ static TruffleString doSelfIsObject(VirtualFrame frame, PBuiltinMethod method,
                               @Shared("getQualname") @Cached PyObjectGetAttr getQualname,
                               @Shared("lookupName") @Cached PyObjectLookupAttr lookupName,
                               @Shared("formatter") @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   return getQualName(frame, inliningTarget, method.getSelf(), method.getFunction(), getClassNode, isTypeNode, toStringNode, getQualname, lookupName, simpleTruffleStringFormatNode,
                                   raiseNode);
               }
       
               private static TruffleString getQualName(VirtualFrame frame, Node inliningTarget, Object self, Object func, GetClassNode getClassNode, TypeNodes.IsTypeNode isTypeNode,
                               CastToTruffleStringNode toStringNode, PyObjectGetAttr getQualname, PyObjectLookupAttr lookupName, SimpleTruffleStringFormatNode simpleTruffleStringFormatNode,
      -                        PRaiseNode.Lazy raiseNode) {
      +                        PRaiseNode raiseNode) {
                   Object type = isTypeNode.execute(inliningTarget, self) ? self : getClassNode.execute(inliningTarget, self);
       
                   try {
                       TruffleString typeQualName = toStringNode.execute(inliningTarget, getQualname.execute(frame, inliningTarget, type, T___QUALNAME__));
                       return simpleTruffleStringFormatNode.format("%s.%s", typeQualName, getName(frame, inliningTarget, func, toStringNode, lookupName));
                   } catch (CannotCastException cce) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.IS_NOT_A_UNICODE_OBJECT, T___QUALNAME__);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.IS_NOT_A_UNICODE_OBJECT, T___QUALNAME__);
                   }
               }
       
      @@ -403,11 +420,11 @@ PTuple doSelfIsObject(VirtualFrame frame, PMethod method, @SuppressWarnings("unu
                               @Shared("toStringNode") @Cached CastToTruffleStringNode toStringNode,
                               @Shared("getGetAttr") @Cached PyObjectGetAttr getGetAttr,
                               @Shared("getName") @Cached PyObjectGetAttr getName,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   PythonModule builtins = getContext().getBuiltins();
                   Object getattr = getGetAttr.execute(frame, inliningTarget, builtins, T_GETATTR);
      -            PTuple args = factory.createTuple(new Object[]{method.getSelf(), getName(frame, inliningTarget, method.getFunction(), toStringNode, getName)});
      -            return factory.createTuple(new Object[]{getattr, args});
      +            PTuple args = PFactory.createTuple(language, new Object[]{method.getSelf(), getName(frame, inliningTarget, method.getFunction(), toStringNode, getName)});
      +            return PFactory.createTuple(language, new Object[]{getattr, args});
               }
       
               @Specialization(guards = "!isSelfModuleOrNull(method)")
      @@ -416,11 +433,11 @@ PTuple doSelfIsObject(VirtualFrame frame, PBuiltinMethod method, @SuppressWarnin
                               @Shared("toStringNode") @Cached CastToTruffleStringNode toStringNode,
                               @Shared("getGetAttr") @Cached PyObjectGetAttr getGetAttr,
                               @Shared("getName") @Cached PyObjectGetAttr getName,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   PythonModule builtins = getContext().getBuiltins();
                   Object getattr = getGetAttr.execute(frame, inliningTarget, builtins, T_GETATTR);
      -            PTuple args = factory.createTuple(new Object[]{method.getSelf(), getName(frame, inliningTarget, method.getFunction(), toStringNode, getName)});
      -            return factory.createTuple(new Object[]{getattr, args});
      +            PTuple args = PFactory.createTuple(language, new Object[]{method.getSelf(), getName(frame, inliningTarget, method.getFunction(), toStringNode, getName)});
      +            return PFactory.createTuple(language, new Object[]{getattr, args});
               }
       
               private static TruffleString getName(VirtualFrame frame, Node inliningTarget, Object func, CastToTruffleStringNode toStringNode, PyObjectGetAttr getName) {
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/BuiltinClassmethodBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/BuiltinClassmethodBuiltins.java
      index 3cb22be5d9..6bfe4c858a 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/BuiltinClassmethodBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/BuiltinClassmethodBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -49,18 +49,20 @@
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___QUALNAME__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___TEXT_SIGNATURE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___OBJCLASS__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___OBJCLASS__;
       import static com.oracle.graal.python.nodes.StringLiterals.T_QUESTIONMARK;
       
       import java.util.List;
       
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.lib.PyObjectGetAttr;
       import com.oracle.graal.python.lib.PyObjectLookupAttr;
      @@ -79,6 +81,8 @@
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PBuiltinClassMethod)
       public final class BuiltinClassmethodBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = BuiltinClassmethodBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return BuiltinClassmethodBuiltinsFactory.getFactories();
      @@ -139,7 +143,7 @@ static Object textSignature(VirtualFrame frame, PDecoratedMethod self,
               }
           }
       
      -    @Builtin(name = J___REPR__, maxNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
               @Specialization
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/BuiltinFunctionOrMethodBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/BuiltinFunctionOrMethodBuiltins.java
      index b0c80b9bc1..c24bbecd7e 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/BuiltinFunctionOrMethodBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/BuiltinFunctionOrMethodBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -42,12 +42,13 @@
       
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.AttributeError;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___SIGNATURE__;
      -import static com.oracle.graal.python.nodes.SpecialAttributeNames.T__SIGNATURE__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
      +import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___SIGNATURE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -59,6 +60,7 @@
       import com.oracle.graal.python.builtins.objects.function.Signature;
       import com.oracle.graal.python.builtins.objects.module.PythonModule;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
      @@ -82,12 +84,14 @@
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PBuiltinFunctionOrMethod)
       public final class BuiltinFunctionOrMethodBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = BuiltinFunctionOrMethodBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return BuiltinFunctionOrMethodBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
               static boolean isBuiltinFunction(PBuiltinMethod self) {
      @@ -152,7 +156,7 @@ public Object doIt(Object fun,
                               @Bind("this") Node inliningTarget) {
                   Signature signature = GetSignatureNode.executeUncached(fun);
                   if (signature.isHidden()) {
      -                throw PRaiseNode.raiseUncached(inliningTarget, AttributeError, ErrorMessages.HAS_NO_ATTR, fun, T__SIGNATURE__);
      +                throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, ErrorMessages.HAS_NO_ATTR, fun, T___SIGNATURE__);
                   }
                   return BuiltinFunctionBuiltins.SignatureNode.createInspectSignature(signature, true);
               }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/ClassmethodBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/ClassmethodBuiltins.java
      index 9534170b94..2462d80a52 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/ClassmethodBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/ClassmethodBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,52 +40,40 @@
        */
       package com.oracle.graal.python.builtins.objects.method;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_CLASSMETHOD;
       import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
       import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      -import com.oracle.graal.python.builtins.Builtin;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
      -import com.oracle.graal.python.builtins.objects.function.PFunction;
      -import com.oracle.graal.python.builtins.objects.function.PKeyword;
      +import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
      -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.DescrGetBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.lib.PyObjectLookupAttr;
       import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
      -import com.oracle.graal.python.nodes.ErrorMessages;
      -import com.oracle.graal.python.nodes.PGuards;
      -import com.oracle.graal.python.nodes.PNodeWithContext;
      -import com.oracle.graal.python.nodes.PRaiseNode;
      +import com.oracle.graal.python.lib.PyObjectSetAttr;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
      -import com.oracle.graal.python.nodes.object.GetClassNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      -import com.oracle.graal.python.util.PythonUtils;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      -import com.oracle.truffle.api.dsl.Cached.Shared;
      -import com.oracle.truffle.api.dsl.GenerateCached;
      -import com.oracle.truffle.api.dsl.GenerateInline;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      -import com.oracle.truffle.api.dsl.GenerateUncached;
      -import com.oracle.truffle.api.dsl.ImportStatic;
       import com.oracle.truffle.api.dsl.NodeFactory;
      -import com.oracle.truffle.api.dsl.ReportPolymorphism;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
       import com.oracle.truffle.api.strings.TruffleString;
       import com.oracle.truffle.api.strings.TruffleStringBuilder;
       
      -@CoreFunctions(extendClasses = {PythonBuiltinClassType.PClassmethod, PythonBuiltinClassType.PBuiltinClassMethod})
      +@CoreFunctions(extendClasses = PythonBuiltinClassType.PClassmethod)
       public final class ClassmethodBuiltins extends PythonBuiltins {
       
           public static final TpSlots SLOTS = ClassmethodBuiltinsSlotsGen.SLOTS;
      @@ -95,120 +83,34 @@ protected List> getNodeFa
               return ClassmethodBuiltinsFactory.getFactories();
           }
       
      -    @Slot(SlotKind.tp_descr_get)
      -    @ReportPolymorphism
      -    @GenerateUncached
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = J_CLASSMETHOD, minNumOfPositionalArgs = 2)
           @GenerateNodeFactory
      -    abstract static class GetNode extends DescrGetBuiltinNode {
      -        /*-
      -        TODO: (GR-53082) this is not handling following code-path added to CPython at some later point:
      -        if (Py_TYPE(cm->cm_callable)->tp_descr_get != NULL) {
      -            return Py_TYPE(cm->cm_callable)->tp_descr_get(cm->cm_callable, type, type);
      -        }
      -        
      -        Additionally, in CPython tp_descrget is not shared between classmethod_descriptor and classmethod,
      -        we should investigate if we can really share the implementation
      -        */
      -
      -        // If self.getCallable() is null, let the next @Specialization handle that
      -        @Specialization(guards = {"isSingleContext()", "isNoValue(type)", "cachedSelf == self", "cachedCallable != null"}, limit = "3")
      -        static Object getCached(@SuppressWarnings("unused") PDecoratedMethod self, Object obj, @SuppressWarnings("unused") Object type,
      -                        @Bind("this") Node inliningTarget,
      -                        @SuppressWarnings("unused") @Cached(value = "self", weak = true) PDecoratedMethod cachedSelf,
      -                        @SuppressWarnings("unused") @Cached(value = "self.getCallable()", weak = true) Object cachedCallable,
      -                        @Shared @Cached GetClassNode getClass,
      -                        @Shared @Cached MakeMethodNode makeMethod) {
      -            return makeMethod.execute(inliningTarget, getClass.execute(inliningTarget, obj), cachedCallable);
      -        }
      -
      -        @Specialization(guards = "isNoValue(type)", replaces = "getCached")
      -        static Object get(PDecoratedMethod self, Object obj, @SuppressWarnings("unused") Object type,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared @Cached GetClassNode getClass,
      -                        @Shared @Cached MakeMethodNode makeMethod,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            return doGet(inliningTarget, self, getClass.execute(inliningTarget, obj), makeMethod, raiseNode);
      -        }
      -
      -        // If self.getCallable() is null, let the next @Specialization handle that
      -        @Specialization(guards = {"isSingleContext()", "!isNoValue(type)", "cachedSelf == self", "cachedCallable != null"}, limit = "3")
      -        static Object getTypeCached(@SuppressWarnings("unused") PDecoratedMethod self, @SuppressWarnings("unused") Object obj, Object type,
      -                        @Bind("this") Node inliningTarget,
      -                        @SuppressWarnings("unused") @Cached(value = "self", weak = true) PDecoratedMethod cachedSelf,
      -                        @SuppressWarnings("unused") @Cached(value = "self.getCallable()", weak = true) Object cachedCallable,
      -                        @Shared @Cached MakeMethodNode makeMethod) {
      -            return makeMethod.execute(inliningTarget, type, cachedCallable);
      -        }
      -
      -        @Specialization(guards = "!isNoValue(type)", replaces = "getTypeCached")
      -        static Object getType(PDecoratedMethod self, @SuppressWarnings("unused") Object obj, Object type,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared @Cached MakeMethodNode makeMethod,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            return doGet(inliningTarget, self, type, makeMethod, raiseNode);
      -        }
      -
      -        private static Object doGet(Node inliningTarget, PDecoratedMethod self, Object type, MakeMethodNode makeMethod, PRaiseNode.Lazy raiseNode) {
      -            Object callable = self.getCallable();
      -            if (callable == null) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.UNINITIALIZED_S_OBJECT);
      -            }
      -            return makeMethod.execute(inliningTarget, type, callable);
      -        }
      -    }
      -
      -    @GenerateInline
      -    @GenerateCached(false)
      -    @GenerateUncached
      -    @ImportStatic(PGuards.class)
      -    @ReportPolymorphism
      -    abstract static class MakeMethodNode extends PNodeWithContext {
      -        abstract Object execute(Node inliningTarget, Object self, Object func);
      -
      +    public abstract static class ClassmethodNode extends PythonBinaryBuiltinNode {
               @Specialization
      -        Object method(Object self, PFunction func,
      -                        @Shared("factory") @Cached(inline = false) PythonObjectFactory factory) {
      -            return factory.createMethod(self, func);
      -        }
      -
      -        @Specialization(guards = "!func.needsDeclaringType()")
      -        Object methodBuiltin(Object self, PBuiltinFunction func,
      -                        @Shared("factory") @Cached(inline = false) PythonObjectFactory factory) {
      -            return factory.createBuiltinMethod(self, func);
      -        }
      -
      -        @Specialization(guards = "func.needsDeclaringType()")
      -        Object methodBuiltinWithDeclaringType(Object self, PBuiltinFunction func,
      -                        @Shared("factory") @Cached(inline = false) PythonObjectFactory factory) {
      -            return factory.createBuiltinMethod(self, func, func.getEnclosingType());
      -        }
      -
      -        @Specialization(guards = "!isFunction(func)")
      -        Object generic(Object self, Object func,
      -                        @Shared("factory") @Cached(inline = false) PythonObjectFactory factory) {
      -            return factory.createMethod(self, func);
      +        static Object doObjectIndirect(Object cls, @SuppressWarnings("unused") Object callable,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createClassmethod(language, cls, getInstanceShape.execute(cls));
               }
           }
       
      -    @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @Slot(value = SlotKind.tp_init, isComplex = true)
      +    @Slot.SlotSignature(name = "classmethod", minNumOfPositionalArgs = 2)
           @GenerateNodeFactory
      -    abstract static class CallNode extends PythonVarargsBuiltinNode {
      -        @Child private com.oracle.graal.python.nodes.call.CallNode callNode = com.oracle.graal.python.nodes.call.CallNode.create();
      -
      +    abstract static class InitNode extends PythonBinaryBuiltinNode {
               @Specialization
      -        protected Object doIt(VirtualFrame frame, PDecoratedMethod self, Object[] arguments, PKeyword[] keywords) {
      -            return callNode.execute(frame, self.getCallable(), arguments, keywords);
      -        }
      -
      -        @Override
      -        public Object varArgExecute(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported {
      -            Object[] argsWithoutSelf = new Object[arguments.length - 1];
      -            PythonUtils.arraycopy(arguments, 1, argsWithoutSelf, 0, argsWithoutSelf.length);
      -            return execute(frame, arguments[0], argsWithoutSelf, keywords);
      +        protected PNone init(VirtualFrame frame, PDecoratedMethod self, Object callable,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached PyObjectLookupAttr lookup,
      +                        @Cached PyObjectSetAttr setAttr) {
      +            self.setCallable(callable);
      +            DecoratedMethodBuiltins.wraps(frame, self, callable, inliningTarget, lookup, setAttr);
      +            return PNone.NONE;
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
               private static final TruffleString PREFIX = tsLiteral("> getNodeFactories() {
      +        return ClassmethodCommonBuiltinsFactory.getFactories();
      +    }
      +
      +    @Slot(SlotKind.tp_descr_get)
      +    @ReportPolymorphism
      +    @GenerateUncached
      +    @GenerateNodeFactory
      +    abstract static class GetNode extends DescrGetBuiltinNode {
      +        /*-
      +        TODO: (GR-53082) this is not handling following code-path added to CPython at some later point:
      +        if (Py_TYPE(cm->cm_callable)->tp_descr_get != NULL) {
      +            return Py_TYPE(cm->cm_callable)->tp_descr_get(cm->cm_callable, type, type);
      +        }
      +        
      +        Additionally, in CPython tp_descrget is not shared between classmethod_descriptor and classmethod,
      +        we should investigate if we can really share the implementation
      +        */
      +
      +        // If self.getCallable() is null, let the next @Specialization handle that
      +        @Specialization(guards = {"isSingleContext()", "isNoValue(type)", "cachedSelf == self", "cachedCallable != null"}, limit = "3")
      +        static Object getCached(@SuppressWarnings("unused") PDecoratedMethod self, Object obj, @SuppressWarnings("unused") Object type,
      +                        @Bind("this") Node inliningTarget,
      +                        @SuppressWarnings("unused") @Cached(value = "self", weak = true) PDecoratedMethod cachedSelf,
      +                        @SuppressWarnings("unused") @Cached(value = "self.getCallable()", weak = true) Object cachedCallable,
      +                        @Shared @Cached GetClassNode getClass,
      +                        @Shared @Cached MakeMethodNode makeMethod) {
      +            return makeMethod.execute(inliningTarget, getClass.execute(inliningTarget, obj), cachedCallable);
      +        }
      +
      +        @Specialization(guards = "isNoValue(type)", replaces = "getCached")
      +        static Object get(PDecoratedMethod self, Object obj, @SuppressWarnings("unused") Object type,
      +                        @Bind("this") Node inliningTarget,
      +                        @Shared @Cached GetClassNode getClass,
      +                        @Shared @Cached MakeMethodNode makeMethod,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            return doGet(inliningTarget, self, getClass.execute(inliningTarget, obj), makeMethod, raiseNode);
      +        }
      +
      +        // If self.getCallable() is null, let the next @Specialization handle that
      +        @Specialization(guards = {"isSingleContext()", "!isNoValue(type)", "cachedSelf == self", "cachedCallable != null"}, limit = "3")
      +        static Object getTypeCached(@SuppressWarnings("unused") PDecoratedMethod self, @SuppressWarnings("unused") Object obj, Object type,
      +                        @Bind("this") Node inliningTarget,
      +                        @SuppressWarnings("unused") @Cached(value = "self", weak = true) PDecoratedMethod cachedSelf,
      +                        @SuppressWarnings("unused") @Cached(value = "self.getCallable()", weak = true) Object cachedCallable,
      +                        @Shared @Cached MakeMethodNode makeMethod) {
      +            return makeMethod.execute(inliningTarget, type, cachedCallable);
      +        }
      +
      +        @Specialization(guards = "!isNoValue(type)", replaces = "getTypeCached")
      +        static Object getType(PDecoratedMethod self, @SuppressWarnings("unused") Object obj, Object type,
      +                        @Bind("this") Node inliningTarget,
      +                        @Shared @Cached MakeMethodNode makeMethod,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            return doGet(inliningTarget, self, type, makeMethod, raiseNode);
      +        }
      +
      +        private static Object doGet(Node inliningTarget, PDecoratedMethod self, Object type, MakeMethodNode makeMethod, PRaiseNode raiseNode) {
      +            Object callable = self.getCallable();
      +            if (callable == null) {
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.UNINITIALIZED_S_OBJECT);
      +            }
      +            return makeMethod.execute(inliningTarget, type, callable);
      +        }
      +    }
      +
      +    @GenerateInline
      +    @GenerateCached(false)
      +    @GenerateUncached
      +    @ImportStatic(PGuards.class)
      +    @ReportPolymorphism
      +    abstract static class MakeMethodNode extends PNodeWithContext {
      +        abstract Object execute(Node inliningTarget, Object self, Object func);
      +
      +        @Specialization
      +        Object method(Object self, PFunction func,
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createMethod(language, self, func);
      +        }
      +
      +        @Specialization(guards = "!func.needsDeclaringType()")
      +        Object methodBuiltin(Object self, PBuiltinFunction func,
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createBuiltinMethod(language, self, func);
      +        }
      +
      +        @Specialization(guards = "func.needsDeclaringType()")
      +        Object methodBuiltinWithDeclaringType(Object self, PBuiltinFunction func,
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createBuiltinMethod(language, self, func, func.getEnclosingType());
      +        }
      +
      +        @Specialization(guards = "!isFunction(func)")
      +        Object generic(Object self, Object func,
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createMethod(language, self, func);
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_call, isComplex = true)
      +    @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    abstract static class CallNode extends PythonVarargsBuiltinNode {
      +        @Child private com.oracle.graal.python.nodes.call.CallNode callNode = com.oracle.graal.python.nodes.call.CallNode.create();
      +
      +        @Specialization
      +        protected Object doIt(VirtualFrame frame, PDecoratedMethod self, Object[] arguments, PKeyword[] keywords) {
      +            return callNode.execute(frame, self.getCallable(), arguments, keywords);
      +        }
      +
      +    }
      +}
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/DecoratedMethodBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/DecoratedMethodBuiltins.java
      index b45360f89f..76e01baa7d 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/DecoratedMethodBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/DecoratedMethodBuiltins.java
      @@ -49,7 +49,6 @@
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___MODULE__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___QUALNAME__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ISABSTRACTMETHOD__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ISABSTRACTMETHOD__;
       
      @@ -86,42 +85,24 @@
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PStaticmethod, PythonBuiltinClassType.PClassmethod})
       public final class DecoratedMethodBuiltins extends PythonBuiltins {
       
      -    @Override
      -    protected List> getNodeFactories() {
      -        return DecoratedMethodBuiltinsFactory.getFactories();
      +    static void wraps(VirtualFrame frame, PDecoratedMethod self, Object callable, Node inliningTarget, PyObjectLookupAttr lookup, PyObjectSetAttr setAttr) {
      +        copyAttr(frame, inliningTarget, callable, self, T___MODULE__, lookup, setAttr);
      +        copyAttr(frame, inliningTarget, callable, self, T___NAME__, lookup, setAttr);
      +        copyAttr(frame, inliningTarget, callable, self, T___QUALNAME__, lookup, setAttr);
      +        copyAttr(frame, inliningTarget, callable, self, T___DOC__, lookup, setAttr);
      +        copyAttr(frame, inliningTarget, callable, self, T___ANNOTATIONS__, lookup, setAttr);
           }
       
      -    @Builtin(name = J___INIT__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    abstract static class InitNode extends PythonBinaryBuiltinNode {
      -        @Specialization
      -        protected PNone init(VirtualFrame frame, PDecoratedMethod self, Object callable,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached PyObjectLookupAttr lookupModule,
      -                        @Cached PyObjectSetAttr setModule,
      -                        @Cached PyObjectLookupAttr lookupName,
      -                        @Cached PyObjectSetAttr setName,
      -                        @Cached PyObjectLookupAttr lookupQualname,
      -                        @Cached PyObjectSetAttr setQualname,
      -                        @Cached PyObjectLookupAttr lookupDoc,
      -                        @Cached PyObjectSetAttr setDoc,
      -                        @Cached PyObjectLookupAttr lookupAnnotations,
      -                        @Cached PyObjectSetAttr setAnnotations) {
      -            self.setCallable(callable);
      -            copyAttr(frame, inliningTarget, callable, self, T___MODULE__, lookupModule, setModule);
      -            copyAttr(frame, inliningTarget, callable, self, T___NAME__, lookupName, setName);
      -            copyAttr(frame, inliningTarget, callable, self, T___QUALNAME__, lookupQualname, setQualname);
      -            copyAttr(frame, inliningTarget, callable, self, T___DOC__, lookupDoc, setDoc);
      -            copyAttr(frame, inliningTarget, callable, self, T___ANNOTATIONS__, lookupAnnotations, setAnnotations);
      -            return PNone.NONE;
      +    private static void copyAttr(VirtualFrame frame, Node inliningTarget, Object wrapped, Object wrapper, TruffleString name, PyObjectLookupAttr lookup, PyObjectSetAttr set) {
      +        Object attr = lookup.execute(frame, inliningTarget, wrapped, name);
      +        if (attr != PNone.NO_VALUE) {
      +            set.execute(frame, inliningTarget, wrapper, name, attr);
               }
      +    }
       
      -        private static void copyAttr(VirtualFrame frame, Node inliningTarget, Object wrapped, Object wrapper, TruffleString name, PyObjectLookupAttr lookup, PyObjectSetAttr set) {
      -            Object attr = lookup.execute(frame, inliningTarget, wrapped, name);
      -            if (attr != PNone.NO_VALUE) {
      -                set.execute(frame, inliningTarget, wrapper, name, attr);
      -            }
      -        }
      +    @Override
      +    protected List> getNodeFactories() {
      +        return DecoratedMethodBuiltinsFactory.getFactories();
           }
       
           @Builtin(name = J___FUNC__, minNumOfPositionalArgs = 1, isGetter = true)
      @@ -155,8 +136,8 @@ static Object setDict(PDecoratedMethod self, PDict mapping,
       
               @Specialization(guards = {"!isNoValue(mapping)", "!isDict(mapping)"})
               static Object setDict(@SuppressWarnings("unused") PDecoratedMethod self, Object mapping,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, mapping);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, mapping);
               }
           }
       
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/InstancemethodBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/InstancemethodBuiltins.java
      index 77e7d15380..19304a7d04 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/InstancemethodBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/InstancemethodBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -41,19 +41,19 @@
       package com.oracle.graal.python.builtins.objects.method;
       
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_INSTANCEMETHOD;
       import static com.oracle.graal.python.nodes.ErrorMessages.FIRST_ARG_MUST_BE_CALLABLE_S;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___DOC__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___FUNC__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -64,6 +64,7 @@
       import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.DescrGetBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.GetAttrBuiltinNode;
       import com.oracle.graal.python.lib.PyCallableCheckNode;
      @@ -77,8 +78,7 @@
       import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      -import com.oracle.graal.python.util.PythonUtils;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      @@ -102,7 +102,20 @@ protected List> getNodeFa
               return InstancemethodBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___INIT__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = J_INSTANCEMETHOD, minNumOfPositionalArgs = 2)
      +    @GenerateNodeFactory
      +    public abstract static class InstancemethodNode extends PythonBinaryBuiltinNode {
      +        @Specialization
      +        static Object doObjectIndirect(Object cls, @SuppressWarnings("unused") Object callable,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createInstancemethod(language, cls, getInstanceShape.execute(cls));
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_init, isComplex = true)
      +    @SlotSignature(name = "instancemethod", minNumOfPositionalArgs = 2)
           @GenerateNodeFactory
           abstract static class InitNode extends PythonBinaryBuiltinNode {
               @Specialization(guards = "checkCallableNode.execute(this, callable)")
      @@ -115,8 +128,8 @@ static PNone init(PDecoratedMethod self, Object callable,
               @Specialization(guards = "!checkCallableNode.execute(this, callable)")
               static PNone noCallble(@SuppressWarnings("unused") PDecoratedMethod self, Object callable,
                               @Shared("checkCallable") @SuppressWarnings("unused") @Cached PyCallableCheckNode checkCallableNode,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, FIRST_ARG_MUST_BE_CALLABLE_S, callable);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, FIRST_ARG_MUST_BE_CALLABLE_S, callable);
               }
           }
       
      @@ -159,7 +172,8 @@ static Object doc(VirtualFrame frame, PDecoratedMethod self,
               }
           }
       
      -    @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @Slot(value = SlotKind.tp_call, isComplex = true)
      +    @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
           @GenerateNodeFactory
           public abstract static class CallNode extends PythonVarargsBuiltinNode {
               @Specialization
      @@ -168,12 +182,6 @@ protected static Object doIt(VirtualFrame frame, PDecoratedMethod self, Object[]
                   return callNode.execute(frame, self.getCallable(), arguments, keywords);
               }
       
      -        @Override
      -        public Object varArgExecute(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported {
      -            Object[] argsWithoutSelf = new Object[arguments.length - 1];
      -            PythonUtils.arraycopy(arguments, 1, argsWithoutSelf, 0, argsWithoutSelf.length);
      -            return execute(frame, arguments[0], argsWithoutSelf, keywords);
      -        }
           }
       
           @Slot(SlotKind.tp_descr_get)
      @@ -183,16 +191,15 @@ public abstract static class GetNode extends DescrGetBuiltinNode {
               @Specialization
               static Object doGeneric(PDecoratedMethod self, Object obj, @SuppressWarnings("unused") Object cls,
                               @Bind("this") Node inliningTarget,
      -                        @Cached InlinedConditionProfile objIsNoneProfile,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Cached InlinedConditionProfile objIsNoneProfile) {
                   if (objIsNoneProfile.profile(inliningTarget, obj == PNone.NO_VALUE)) {
                       return self.getCallable();
                   }
      -            return factory.createMethod(obj, self.getCallable());
      +            return PFactory.createMethod(PythonLanguage.get(inliningTarget), obj, self.getCallable());
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
               @Specialization
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/MethodBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/MethodBuiltins.java
      index 23b8f10f15..3d666dec18 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/MethodBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/MethodBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2017, 2024, Oracle and/or its affiliates.
      + * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
        * Copyright (c) 2014, Regents of the University of California
        *
        * All rights reserved.
      @@ -34,25 +34,29 @@
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___CODE__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___QUALNAME__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETATTRIBUTE__;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
      +import com.oracle.graal.python.builtins.objects.function.PFunction;
       import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.DescrGetBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.GetAttrBuiltinNode;
      +import com.oracle.graal.python.lib.PyCallableCheckNode;
       import com.oracle.graal.python.lib.PyObjectGetAttr;
       import com.oracle.graal.python.lib.PyObjectLookupAttr;
       import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
      @@ -63,13 +67,14 @@
       import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetKeywordDefaultsNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
       import com.oracle.graal.python.nodes.object.GetOrCreateDictNode;
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      @@ -91,6 +96,36 @@ protected List> getNodeFa
               return MethodBuiltinsFactory.getFactories();
           }
       
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "method", minNumOfPositionalArgs = 3)
      +    @GenerateNodeFactory
      +    public abstract static class MethodTypeNode extends PythonTernaryBuiltinNode {
      +        @Specialization
      +        static Object method(@SuppressWarnings("unused") Object cls, PFunction func, Object self,
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createMethod(language, self, func);
      +        }
      +
      +        @Specialization
      +        static Object methodBuiltin(@SuppressWarnings("unused") Object cls, PBuiltinFunction func, Object self,
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createMethod(language, self, func);
      +        }
      +
      +        @Specialization
      +        static Object methodGeneric(@SuppressWarnings("unused") Object cls, Object func, Object self,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Cached PyCallableCheckNode callableCheck,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (callableCheck.execute(inliningTarget, func)) {
      +                return PFactory.createMethod(language, self, func);
      +            } else {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.FIRST_ARG_MUST_BE_CALLABLE_S, "");
      +            }
      +        }
      +    }
      +
           @Builtin(name = J___FUNC__, minNumOfPositionalArgs = 1, isGetter = true)
           @GenerateNodeFactory
           public abstract static class FuncNode extends PythonBuiltinNode {
      @@ -132,14 +167,14 @@ static Object doIt(VirtualFrame frame, PMethod self, Object keyObj,
                               @Cached ObjectBuiltins.GetAttributeNode objectGetattrNode,
                               @Cached IsBuiltinObjectProfile errorProfile,
                               @Cached CastToTruffleStringNode castKeyToStringNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   // TODO: (GR-53090) this is different to what CPython does and CPython also does not
                   // define tp_descrget for method
                   TruffleString key;
                   try {
                       key = castKeyToStringNode.execute(inliningTarget, keyObj);
                   } catch (CannotCastException e) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj);
                   }
       
                   try {
      @@ -153,12 +188,12 @@ static Object doIt(VirtualFrame frame, PMethod self, Object keyObj,
               @Specialization(guards = "!isPMethod(self)")
               @InliningCutoff
               static Object getattribute(Object self, @SuppressWarnings("unused") Object key,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___GETATTRIBUTE__, "method", self);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___GETATTRIBUTE__, "method", self);
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -190,11 +225,10 @@ public abstract static class GetMethodDefaultsNode extends PythonUnaryBuiltinNod
               @Specialization
               static Object defaults(PMethod self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached GetDefaultsNode getDefaultsNode,
      -                        @Cached PythonObjectFactory.Lazy factory) {
      +                        @Cached GetDefaultsNode getDefaultsNode) {
                   Object[] argDefaults = getDefaultsNode.execute(inliningTarget, self);
                   assert argDefaults != null;
      -            return (argDefaults.length == 0) ? PNone.NONE : factory.get(inliningTarget).createTuple(argDefaults);
      +            return (argDefaults.length == 0) ? PNone.NONE : PFactory.createTuple(PythonLanguage.get(inliningTarget), argDefaults);
               }
           }
       
      @@ -204,10 +238,9 @@ public abstract static class GetMethodKwdefaultsNode extends PythonUnaryBuiltinN
               @Specialization
               static Object kwDefaults(PMethod self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached GetKeywordDefaultsNode getKeywordDefaultsNode,
      -                        @Cached PythonObjectFactory.Lazy factory) {
      +                        @Cached GetKeywordDefaultsNode getKeywordDefaultsNode) {
                   PKeyword[] kwdefaults = getKeywordDefaultsNode.execute(inliningTarget, self);
      -            return (kwdefaults.length > 0) ? factory.get(inliningTarget).createDict(kwdefaults) : PNone.NONE;
      +            return (kwdefaults.length > 0) ? PFactory.createDict(PythonLanguage.get(inliningTarget), kwdefaults) : PNone.NONE;
               }
           }
       
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/MethodWrapperBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/MethodWrapperBuiltins.java
      index 6150da3a0c..166463c045 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/MethodWrapperBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/MethodWrapperBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -42,16 +42,18 @@
       
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___OBJCLASS__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode;
       import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      @@ -71,6 +73,8 @@
       @CoreFunctions(extendClasses = PythonBuiltinClassType.MethodWrapper)
       public final class MethodWrapperBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = MethodWrapperBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return MethodWrapperBuiltinsFactory.getFactories();
      @@ -85,7 +89,7 @@ Object objclass(PBuiltinMethod self) {
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
               @Specialization
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/PDecoratedMethod.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/PDecoratedMethod.java
      index e4462ae95b..c132d51694 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/PDecoratedMethod.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/PDecoratedMethod.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,12 +40,13 @@
        */
       package com.oracle.graal.python.builtins.objects.method;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.builtins.BoundBuiltinCallable;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.objects.function.Signature;
       import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
       import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.object.Shape;
       
      @@ -74,14 +75,14 @@ public void setCallable(Object callable) {
           }
       
           @SuppressWarnings("unchecked")
      -    public Object boundToObject(PythonBuiltinClassType binding, PythonObjectFactory factory) {
      +    public Object boundToObject(PythonBuiltinClassType binding, PythonLanguage language) {
               if (GetPythonObjectClassNode.executeUncached(this) != PythonBuiltinClassType.PStaticmethod) {
                   if (callable instanceof BoundBuiltinCallable) {
      -                return factory.createBuiltinClassmethodFromCallableObj(((BoundBuiltinCallable) callable).boundToObject(binding, factory));
      +                return PFactory.createBuiltinClassmethodFromCallableObj(language, ((BoundBuiltinCallable) callable).boundToObject(binding, language));
                   }
               } else {
                   if (callable instanceof PBuiltinMethod) {
      -                return factory.createStaticmethodFromCallableObj(((PBuiltinMethod) callable).getBuiltinFunction().boundToObject(binding, factory));
      +                return PFactory.createStaticmethodFromCallableObj(language, ((PBuiltinMethod) callable).getBuiltinFunction().boundToObject(binding, language));
                   }
               }
               return this;
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/StaticmethodBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/StaticmethodBuiltins.java
      index 5ef47ed787..0c9c0fb70a 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/StaticmethodBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/StaticmethodBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,29 +40,35 @@
        */
       package com.oracle.graal.python.builtins.objects.method;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_STATICMETHOD;
       import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
       import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      -import com.oracle.graal.python.builtins.Builtin;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      +import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.DescrGetBuiltinNode;
      +import com.oracle.graal.python.lib.PyObjectLookupAttr;
       import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
      +import com.oracle.graal.python.lib.PyObjectSetAttr;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.call.CallNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -85,6 +91,33 @@ protected List> getNodeFa
               return StaticmethodBuiltinsFactory.getFactories();
           }
       
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = J_STATICMETHOD, minNumOfPositionalArgs = 2)
      +    @GenerateNodeFactory
      +    public abstract static class StaticmethodNode extends PythonBinaryBuiltinNode {
      +        @Specialization
      +        static Object doObjectIndirect(Object cls, @SuppressWarnings("unused") Object callable,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createStaticmethod(language, cls, getInstanceShape.execute(cls));
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_init, isComplex = true)
      +    @SlotSignature(name = "staticmethod", minNumOfPositionalArgs = 2)
      +    @GenerateNodeFactory
      +    abstract static class InitNode extends PythonBinaryBuiltinNode {
      +        @Specialization
      +        protected PNone init(VirtualFrame frame, PDecoratedMethod self, Object callable,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached PyObjectLookupAttr lookup,
      +                        @Cached PyObjectSetAttr setAttr) {
      +            self.setCallable(callable);
      +            DecoratedMethodBuiltins.wraps(frame, self, callable, inliningTarget, lookup, setAttr);
      +            return PNone.NONE;
      +        }
      +    }
      +
           @Slot(SlotKind.tp_descr_get)
           @ReportPolymorphism
           @GenerateUncached
      @@ -103,16 +136,17 @@ static Object getCached(@SuppressWarnings("unused") PDecoratedMethod self, @Supp
               @Specialization(replaces = "getCached")
               static Object get(PDecoratedMethod self, @SuppressWarnings("unused") Object obj, @SuppressWarnings("unused") Object type,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object callable = self.getCallable();
                   if (callable == null) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.UNINITIALIZED_S_OBJECT);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.UNINITIALIZED_S_OBJECT);
                   }
                   return callable;
               }
           }
       
      -    @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @Slot(value = SlotKind.tp_call, isComplex = true)
      +    @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
           @GenerateNodeFactory
           abstract static class CallMethodNode extends PythonVarargsBuiltinNode {
               @Specialization
      @@ -122,7 +156,7 @@ static Object call(VirtualFrame frame, PDecoratedMethod self, Object[] args, PKe
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
               private static final TruffleString PREFIX = tsLiteral("= fstatResult[ST_SIZE]) {
      +                        throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.MMAP_S_IS_GREATER_THAN_FILE_SIZE, "offset");
      +                    }
      +                    // Unlike in CPython, this always fits in the long range
      +                    length = fstatResult[ST_SIZE] - offset;
      +                } else if (fstatResult != null && (offset > fstatResult[ST_SIZE] || fstatResult[ST_SIZE] - offset < length)) {
      +                    throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.MMAP_S_IS_GREATER_THAN_FILE_SIZE, "length");
      +                }
      +            }
      +
      +            // Fixup the flags if we want to use anonymous map
      +            int dupFd;
      +            if (fd == ANONYMOUS_FD) {
      +                dupFd = ANONYMOUS_FD;
      +                flags |= MAP_ANONYMOUS.value;
      +                // TODO: CPython uses mapping to "/dev/zero" on systems that do not support
      +                // MAP_ANONYMOUS, maybe this can be detected and handled by the POSIX layer
      +            } else {
      +                try {
      +                    dupFd = posixSupport.dup(posixSupport1, fd);
      +                } catch (PosixException e) {
      +                    throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
      +                }
      +            }
      +
      +            Object mmapHandle;
      +            try {
      +                mmapHandle = posixSupport.mmap(posixSupport1, length, prot, flags, dupFd, offset);
      +            } catch (PosixException e) {
      +                throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
      +            }
      +            PythonContext context = PythonContext.get(inliningTarget);
      +            return PFactory.createMMap(context.getLanguage(inliningTarget), context, clazz, getInstanceShape.execute(clazz), mmapHandle, dupFd, length, access);
      +        }
      +
      +        @Specialization(guards = "isIllegal(fd)")
      +        @SuppressWarnings("unused")
      +        static PMMap doIllegal(Object clazz, int fd, long lengthIn, int flagsIn, int protIn, int accessIn, long offset,
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.OSError);
      +        }
      +
      +        protected static boolean isIllegal(int fd) {
      +            return fd < -1;
      +        }
      +    }
      +
           @Slot(value = SlotKind.sq_item, isComplex = true)
           @GenerateNodeFactory
           public abstract static class MMapSqItemNode extends SqItemBuiltinNode {
               @Specialization
               static PBytes doInt(VirtualFrame frame, PMMap self, int index,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode,
      +                        @Bind PythonContext context,
      +                        @Cached PRaiseNode raiseNode,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixSupportLib,
      -                        @Cached PythonObjectFactory factory) {
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixSupportLib) {
                   long len = self.getLength();
                   checkBounds(inliningTarget, raiseNode, MMAP_INDEX_OUT_OF_RANGE, index, len);
                   try {
      -                byte b = posixSupportLib.mmapReadByte(PosixSupport.get(inliningTarget), self.getPosixSupportHandle(), index);
      +                byte b = posixSupportLib.mmapReadByte(context.getPosixSupport(), self.getPosixSupportHandle(), index);
                       // CPython indeed returns bytes object from sq_item, although it returns single byte
                       // value as integer from mp_subscript, see, e.g.: `for i in mmap_object: print(i)`
      -                return factory.createBytes(new byte[]{b});
      +                return PFactory.createBytes(context.getLanguage(inliningTarget), new byte[]{b});
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
                   }
      @@ -196,17 +337,18 @@ public abstract static class GetItemNode extends MpSubscriptBuiltinNode {
               @Specialization(guards = "!isPSlice(idxObj)")
               static int doSingle(VirtualFrame frame, PMMap self, Object idxObj,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonContext context,
                               @Exclusive @Cached InlinedConditionProfile negativeIndexProfile,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixSupportLib,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixSupportLib,
                               @Cached PyLongAsLongNode asLongNode,
                               @Exclusive @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   long i = asLongNode.execute(frame, inliningTarget, idxObj);
                   long len = self.getLength();
                   long idx = negativeIndexProfile.profile(inliningTarget, i < 0) ? i + len : i;
                   checkBounds(inliningTarget, raiseNode, MMAP_INDEX_OUT_OF_RANGE, idx, len);
                   try {
      -                return posixSupportLib.mmapReadByte(PosixSupport.get(inliningTarget), self.getPosixSupportHandle(), idx) & 0xFF;
      +                return posixSupportLib.mmapReadByte(context.getPosixSupport(), self.getPosixSupportHandle(), idx) & 0xFF;
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
                   }
      @@ -215,24 +357,24 @@ static int doSingle(VirtualFrame frame, PMMap self, Object idxObj,
               @Specialization
               static Object doSlice(VirtualFrame frame, PMMap self, PSlice idx,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixSupportLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixSupportLib,
                               @Exclusive @Cached InlinedConditionProfile emptyProfile,
                               @Cached CoerceToIntSlice sliceCast,
                               @Cached ComputeIndices compute,
                               @Cached LenOfRangeNode sliceLenNode,
                               @Exclusive @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   try {
                       SliceInfo info = compute.execute(frame, sliceCast.execute(inliningTarget, idx), PInt.intValueExact(self.getLength()));
                       int len = sliceLenNode.len(inliningTarget, info);
                       if (emptyProfile.profile(inliningTarget, len == 0)) {
      -                    return factory.createEmptyBytes();
      +                    return PFactory.createEmptyBytes(context.getLanguage(inliningTarget));
                       }
      -                byte[] result = readBytes(frame, inliningTarget, self, posixSupportLib, PosixSupport.get(inliningTarget), info.start, len, constructAndRaiseNode);
      -                return factory.createBytes(result);
      +                byte[] result = readBytes(frame, inliningTarget, self, posixSupportLib, context.getPosixSupport(), info.start, len, constructAndRaiseNode);
      +                return PFactory.createBytes(context.getLanguage(inliningTarget), result);
                   } catch (OverflowException e) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.OverflowError, e);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.OverflowError, e);
                   }
               }
           }
      @@ -244,33 +386,34 @@ public abstract static class SetItemNode extends SqAssItemBuiltinNode {
               @Specialization
               static void doSingle(VirtualFrame frame, PMMap self, int index, Object val,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixSupportLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixSupportLib,
                               @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib,
                               @Cached PyBytesCheckNode checkNode,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   // NB: sq_ass_item and mp_ass_subscript implementations behave differently even with
                   // integer indices
                   if (self.isClosed()) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, MMAP_CLOSED_OR_INVALID);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, MMAP_CLOSED_OR_INVALID);
                   }
                   long len = self.getLength();
                   long idx = index < 0 ? index + len : index;
                   if (idx < 0 || idx >= len) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.IndexError, MMAP_INDEX_OUT_OF_RANGE);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.IndexError, MMAP_INDEX_OUT_OF_RANGE);
                   }
                   if (val == PNone.NO_VALUE) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, MMAP_OBJECT_DOESNT_SUPPORT_ITEM_DELETION);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, MMAP_OBJECT_DOESNT_SUPPORT_ITEM_DELETION);
                   }
                   if (!(checkNode.execute(inliningTarget, val) && bufferLib.getBufferLength(val) == 1)) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.IndexError, MMAP_ASSIGNMENT_MUST_BE_LENGTH_1_BYTES);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.IndexError, MMAP_ASSIGNMENT_MUST_BE_LENGTH_1_BYTES);
                   }
                   if (self.isReadonly()) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, MMAP_CANNOT_MODIFY_READONLY_MEMORY);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, MMAP_CANNOT_MODIFY_READONLY_MEMORY);
                   }
                   byte b = bufferLib.readByte(val, 0);
                   try {
      -                posixSupportLib.mmapWriteByte(PosixSupport.get(inliningTarget), self.getPosixSupportHandle(), idx, b);
      +                posixSupportLib.mmapWriteByte(context.getPosixSupport(), self.getPosixSupportHandle(), idx, b);
                   } catch (PosixException ex) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, ex);
                   }
      @@ -284,40 +427,41 @@ public abstract static class SetSubscriptNode extends MpAssSubscriptBuiltinNode
               @Specialization(guards = "!isPSlice(idxObj)")
               static void doSingle(VirtualFrame frame, PMMap self, Object idxObj, Object valueObj,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixSupportLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixSupportLib,
                               @Cached PyIndexCheckNode checkNode,
                               @Cached PyNumberAsSizeNode asSizeNode,
                               @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   // NB: sq_ass_item and mp_ass_subscript implementations behave differently even with
                   // integer indices
                   if (self.isClosed()) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, MMAP_CLOSED_OR_INVALID);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, MMAP_CLOSED_OR_INVALID);
                   }
                   if (self.isReadonly()) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, MMAP_CANNOT_MODIFY_READONLY_MEMORY);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, MMAP_CANNOT_MODIFY_READONLY_MEMORY);
                   }
                   if (!checkNode.execute(inliningTarget, idxObj)) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, MMAP_INDICES_MUST_BE_INTEGER);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, MMAP_INDICES_MUST_BE_INTEGER);
                   }
                   long idx = asSizeNode.executeExact(frame, inliningTarget, idxObj, PythonBuiltinClassType.IndexError);
                   long len = self.getLength();
                   idx = idx < 0 ? idx + len : idx;
                   if (idx < 0 || idx >= len) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.IndexError, MMAP_INDEX_OUT_OF_RANGE);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.IndexError, MMAP_INDEX_OUT_OF_RANGE);
                   }
                   if (valueObj == PNone.NO_VALUE) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, MMAP_OBJECT_DOESNT_SUPPORT_ITEM_DELETION);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, MMAP_OBJECT_DOESNT_SUPPORT_ITEM_DELETION);
                   }
                   if (!checkNode.execute(inliningTarget, valueObj)) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, MMAP_ITEM_VALUE_MUST_BE_AN_INT);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, MMAP_ITEM_VALUE_MUST_BE_AN_INT);
                   }
                   int value = asSizeNode.executeExact(frame, inliningTarget, valueObj, PythonBuiltinClassType.TypeError);
                   if (value < 0 || value > 255) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, MMAP_ITEM_VALUE_MUST_BE_IN_RANGE);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, MMAP_ITEM_VALUE_MUST_BE_IN_RANGE);
                   }
                   try {
      -                posixSupportLib.mmapWriteByte(PosixSupport.get(inliningTarget), self.getPosixSupportHandle(), idx, (byte) value);
      +                posixSupportLib.mmapWriteByte(context.getPosixSupport(), self.getPosixSupportHandle(), idx, (byte) value);
                   } catch (PosixException ex) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, ex);
                   }
      @@ -326,44 +470,45 @@ static void doSingle(VirtualFrame frame, PMMap self, Object idxObj, Object value
               @Specialization
               static void doSlice(VirtualFrame frame, PMMap self, PSlice slice, Object valueObj,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixSupportLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixSupportLib,
                               @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib,
                               @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib,
                               @Cached SliceNodes.SliceUnpack sliceUnpack,
                               @Cached SliceNodes.AdjustIndices adjustIndices,
                               @Cached InlinedConditionProfile step1Profile,
                               @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   if (self.isClosed()) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, MMAP_CLOSED_OR_INVALID);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, MMAP_CLOSED_OR_INVALID);
                   }
                   if (self.isReadonly()) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, MMAP_CANNOT_MODIFY_READONLY_MEMORY);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, MMAP_CANNOT_MODIFY_READONLY_MEMORY);
                   }
                   int len;
                   try {
                       len = PInt.intValueExact(self.getLength());
                   } catch (OverflowException e) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.OverflowError);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.OverflowError);
                   }
                   SliceInfo info = adjustIndices.execute(inliningTarget, len, sliceUnpack.execute(inliningTarget, slice));
                   if (valueObj == PNone.NO_VALUE) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, MMAP_OBJECT_DOESNT_SUPPORT_SLICE_DELETION);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, MMAP_OBJECT_DOESNT_SUPPORT_SLICE_DELETION);
                   }
                   Object buffer = acquireLib.acquireReadonly(valueObj);
                   try {
                       int bufferLen = bufferLib.getBufferLength(buffer);
                       if (info.sliceLength != bufferLen) {
      -                    throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.IndexError, MMAP_SLICE_ASSIGNMENT_IS_WRONG_SIZE);
      +                    throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.IndexError, MMAP_SLICE_ASSIGNMENT_IS_WRONG_SIZE);
                       }
                       if (info.sliceLength > 0) {
                           try {
                               if (step1Profile.profile(inliningTarget, info.step == 1)) {
      -                            posixSupportLib.mmapWriteBytes(PosixSupport.get(inliningTarget), self.getPosixSupportHandle(),
      +                            posixSupportLib.mmapWriteBytes(context.getPosixSupport(), self.getPosixSupportHandle(),
                                                   info.start, bufferLib.getInternalOrCopiedByteArray(buffer), bufferLen);
                               } else {
                                   for (int cur = info.start, i = 0; i < info.sliceLength; cur += info.step, i++) {
      -                                posixSupportLib.mmapWriteByte(PosixSupport.get(inliningTarget), self.getPosixSupportHandle(), cur, bufferLib.readByte(buffer, i));
      +                                posixSupportLib.mmapWriteByte(context.getPosixSupport(), self.getPosixSupportHandle(), cur, bufferLib.readByte(buffer, i));
                                   }
                               }
                           } catch (PosixException ex) {
      @@ -384,7 +529,7 @@ public abstract static class LenNode extends LenBuiltinNode {
               @Specialization
               static int len(PMMap self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   return PyNumberAsSizeNode.doLongExact(inliningTarget, self.getLength(), PythonBuiltinClassType.OverflowError, raiseNode);
               }
           }
      @@ -415,9 +560,10 @@ static Object size(VirtualFrame frame, PMMap self, @SuppressWarnings("unused") O
           abstract static class CloseNode extends PythonUnaryBuiltinNode {
       
               @Specialization
      -        PNone close(PMMap self,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixSupportLib) {
      -            self.close(posixSupportLib, getPosixSupport());
      +        static PNone close(PMMap self,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixSupportLib) {
      +            self.close(posixSupportLib, context.getPosixSupport());
                   return PNone.NONE;
               }
           }
      @@ -449,9 +595,9 @@ abstract static class ResizeNode extends PythonBuiltinNode {
               @Specialization
               @SuppressWarnings("unused")
               static long resize(PMMap self, Object n,
      -                        @Cached PRaiseNode raiseNode) {
      +                        @Bind("this") Node inliningTarget) {
                   // TODO: implement resize in NFI
      -            throw raiseNode.raise(PythonBuiltinClassType.SystemError, ErrorMessages.RESIZING_NOT_AVAILABLE);
      +            throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.SystemError, ErrorMessages.RESIZING_NOT_AVAILABLE);
               }
           }
       
      @@ -466,20 +612,20 @@ static long readline(PMMap self) {
       
           @Builtin(name = "read_byte", minNumOfPositionalArgs = 1)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
           abstract static class ReadByteNode extends PythonUnaryBuiltinNode {
       
               @Specialization
               static int readByte(VirtualFrame frame, PMMap self,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixSupportLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixSupportLib,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (self.getPos() >= self.getLength()) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, READ_BYTE_OUT_OF_RANGE);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, READ_BYTE_OUT_OF_RANGE);
                   }
                   try {
      -                byte res = posixSupportLib.mmapReadByte(PosixSupport.get(inliningTarget), self.getPosixSupportHandle(), self.getPos());
      +                byte res = posixSupportLib.mmapReadByte(context.getPosixSupport(), self.getPosixSupportHandle(), self.getPos());
                       self.setPos(self.getPos() + 1);
                       return res & 0xFF;
                   } catch (PosixException e) {
      @@ -490,21 +636,20 @@ static int readByte(VirtualFrame frame, PMMap self,
       
           @Builtin(name = "read", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
           abstract static class ReadNode extends PythonBuiltinNode {
       
               @Specialization
               static PBytes read(VirtualFrame frame, PMMap self, Object n,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonContext context,
                               @Cached InlinedConditionProfile noneProfile,
                               @Cached InlinedConditionProfile emptyProfile,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached PyIndexCheckNode indexCheckNode,
                               @Cached PyNumberAsSizeNode asSizeNode,
                               @Cached InlinedConditionProfile negativeProfile,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   long nread;
                   // intentionally accept NO_VALUE and NONE; both mean that we read unlimited # of bytes
                   if (noneProfile.profile(inliningTarget, isPNone(n))) {
      @@ -512,7 +657,7 @@ static PBytes read(VirtualFrame frame, PMMap self, Object n,
                   } else {
                       // _Py_convert_optional_to_ssize_t:
                       if (!indexCheckNode.execute(inliningTarget, n)) {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ARG_SHOULD_BE_INT_OR_NONE, n);
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ARG_SHOULD_BE_INT_OR_NONE, n);
                       }
                       nread = asSizeNode.executeExact(frame, inliningTarget, n);
       
      @@ -523,14 +668,14 @@ static PBytes read(VirtualFrame frame, PMMap self, Object n,
                       }
                   }
                   if (emptyProfile.profile(inliningTarget, nread == 0)) {
      -                return factory.createEmptyBytes();
      +                return PFactory.createEmptyBytes(context.getLanguage(inliningTarget));
                   }
                   try {
      -                byte[] buffer = MMapBuiltins.readBytes(frame, inliningTarget, self, posixLib, PosixSupport.get(inliningTarget), self.getPos(), PythonUtils.toIntExact(nread), constructAndRaiseNode);
      +                byte[] buffer = MMapBuiltins.readBytes(frame, inliningTarget, self, posixLib, context.getPosixSupport(), self.getPos(), PythonUtils.toIntExact(nread), constructAndRaiseNode);
                       self.setPos(self.getPos() + buffer.length);
      -                return factory.createBytes(buffer);
      +                return PFactory.createBytes(context.getLanguage(inliningTarget), buffer);
                   } catch (OverflowException e) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.OverflowError, ErrorMessages.TOO_MANY_REMAINING_BYTES_TO_BE_STORED);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.OverflowError, ErrorMessages.TOO_MANY_REMAINING_BYTES_TO_BE_STORED);
                   }
               }
           }
      @@ -541,12 +686,12 @@ abstract static class ReadlineNode extends PythonUnaryBuiltinNode {
               private static final int BUFFER_SIZE = 1024;
       
               @Specialization
      -        Object readline(VirtualFrame frame, PMMap self,
      +        static Object readline(VirtualFrame frame, PMMap self,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached SequenceStorageNodes.AppendNode appendNode,
      -                        @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
                   // Posix abstraction is leaking here a bit: with read mmapped memory, we'd just read
                   // byte by byte, but that would be very inefficient with emulated mmap, so we use a
                   // small buffer
      @@ -555,7 +700,7 @@ Object readline(VirtualFrame frame, PMMap self,
                   int nread;
                   outer: while (self.getPos() < self.getLength()) {
                       try {
      -                    nread = posixLib.mmapReadBytes(getPosixSupport(), self.getPosixSupportHandle(), self.getPos(), buffer, (int) Math.min(self.getRemaining(), buffer.length));
      +                    nread = posixLib.mmapReadBytes(context.getPosixSupport(), self.getPosixSupportHandle(), self.getPos(), buffer, (int) Math.min(self.getRemaining(), buffer.length));
                       } catch (PosixException e) {
                           throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
                       }
      @@ -569,7 +714,7 @@ Object readline(VirtualFrame frame, PMMap self,
                       }
                       self.setPos(self.getPos() + nread);
                   }
      -            return factory.createBytes(res);
      +            return PFactory.createBytes(context.getLanguage(inliningTarget), res);
               }
           }
       
      @@ -586,21 +731,22 @@ protected ArgumentClinicProvider getArgumentClinic() {
               @Specialization(limit = "3")
               static int doIt(VirtualFrame frame, PMMap self, Object dataBuffer,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonContext context,
                               @Cached("createFor(this)") IndirectCallData indirectCallData,
                               @CachedLibrary("dataBuffer") PythonBufferAccessLibrary bufferLib,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   try {
                       if (!self.isWriteable()) {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MMAP_CANNOT_MODIFY_READONLY_MEMORY);
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MMAP_CANNOT_MODIFY_READONLY_MEMORY);
                       }
                       byte[] dataBytes = bufferLib.getInternalOrCopiedByteArray(dataBuffer);
                       int dataLen = bufferLib.getBufferLength(dataBuffer);
                       if (self.getPos() > self.getLength() || self.getLength() - self.getPos() < dataLen) {
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.DATA_OUT_OF_RANGE);
      +                    throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.DATA_OUT_OF_RANGE);
                       }
      -                posixLib.mmapWriteBytes(PosixSupport.get(inliningTarget), self.getPosixSupportHandle(), self.getPos(), dataBytes, dataLen);
      +                posixLib.mmapWriteBytes(context.getPosixSupport(), self.getPosixSupportHandle(), self.getPos(), dataBytes, dataLen);
                       self.setPos(self.getPos() + dataLen);
                       return dataLen;
                   } catch (PosixException e) {
      @@ -615,7 +761,6 @@ static int doIt(VirtualFrame frame, PMMap self, Object dataBuffer,
           @ArgumentClinic(name = "dist", conversion = ClinicConversion.LongIndex)
           @ArgumentClinic(name = "how", conversion = ClinicConversion.Int)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
           abstract static class SeekNode extends PythonTernaryClinicBuiltinNode {
               @Override
               protected ArgumentClinicProvider getArgumentClinic() {
      @@ -626,7 +771,7 @@ protected ArgumentClinicProvider getArgumentClinic() {
               static Object seek(PMMap self, long dist, int how,
                               @Bind("this") Node inliningTarget,
                               @Cached InlinedBranchProfile errorProfile,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   long where;
                   switch (how) {
                       case 0: // relative to start
      @@ -640,10 +785,10 @@ static Object seek(PMMap self, long dist, int how,
                           break;
                       default:
                           errorProfile.enter(inliningTarget);
      -                    throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.UNKNOWN_S_TYPE, "seek");
      +                    throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.UNKNOWN_S_TYPE, "seek");
                   }
                   if (where > self.getLength() || where < 0) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.SEEK_OUT_OF_RANGE);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.SEEK_OUT_OF_RANGE);
                   }
                   self.setPos(where);
                   return PNone.NONE;
      @@ -653,7 +798,6 @@ static Object seek(PMMap self, long dist, int how,
           @Builtin(name = "find", minNumOfPositionalArgs = 2, parameterNames = {"$self", "sub", "start", "end"})
           @ArgumentClinic(name = "sub", conversion = ClinicConversion.ReadableBuffer)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
           public abstract static class FindNode extends PythonQuaternaryClinicBuiltinNode {
               private static final int BUFFER_SIZE = 1024; // keep in sync with test_mmap.py
       
      @@ -665,13 +809,14 @@ protected ArgumentClinicProvider getArgumentClinic() {
               @Specialization(limit = "3")
               static long find(VirtualFrame frame, PMMap self, Object subBuffer, Object startIn, Object endIn,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonContext context,
                               @Cached("createFor(this)") IndirectCallData indirectCallData,
                               @CachedLibrary("subBuffer") PythonBufferAccessLibrary bufferLib,
                               @Cached LongIndexConverterNode startConverter,
                               @Cached LongIndexConverterNode endConverter,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   try {
                       long start = normalizeIndex(frame, startConverter, startIn, self.getLength(), self.getPos());
                       long end = normalizeIndex(frame, endConverter, endIn, self.getLength(), self.getLength());
      @@ -690,7 +835,7 @@ static long find(VirtualFrame frame, PMMap self, Object subBuffer, Object startI
                       byte[] firstBuffer = new byte[bufferSize];
                       byte[] secondBuffer = new byte[bufferSize];
       
      -                readBytes(frame, inliningTarget, self, posixLib, start, secondBuffer, constructAndRaiseNode, raiseNode);
      +                readBytes(frame, inliningTarget, self, posixLib, context.getPosixSupport(), start, secondBuffer, constructAndRaiseNode, raiseNode);
                       for (long selfIdx = start; selfIdx <= end - subLen; selfIdx++, buffersIndex++) {
                           // Make sure that the buffers have enough room for the search
                           if (buffersIndex + subLen > bufferSize * 2) {
      @@ -699,7 +844,7 @@ static long find(VirtualFrame frame, PMMap self, Object subBuffer, Object startI
                               secondBuffer = tmp;
                               buffersIndex -= bufferSize; // move to the tail of the first buffer now
                               long readIndex = selfIdx + subLen - 1;
      -                        readBytes(frame, inliningTarget, self, posixLib, readIndex, secondBuffer, constructAndRaiseNode, raiseNode);
      +                        readBytes(frame, inliningTarget, self, posixLib, context.getPosixSupport(), readIndex, secondBuffer, constructAndRaiseNode, raiseNode);
                               // It's OK if we read less than buffer size, the outer loop condition
                               // 'selfIdx <= end' and the check in readBytes should cover that we don't
                               // read
      @@ -729,14 +874,14 @@ static long find(VirtualFrame frame, PMMap self, Object subBuffer, Object startI
                   }
               }
       
      -        private static void readBytes(VirtualFrame frame, Node inliningTarget, PMMap self, PosixSupportLibrary posixLib, long index, byte[] buffer, PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        PRaiseNode.Lazy raiseNode) {
      +        private static void readBytes(VirtualFrame frame, Node inliningTarget, PMMap self, PosixSupportLibrary posixLib, PosixSupport posixSupport, long index, byte[] buffer,
      +                        PConstructAndRaiseNode.Lazy constructAndRaiseNode, PRaiseNode raiseNode) {
                   try {
                       long remaining = self.getLength() - index;
                       int toReadLen = remaining > buffer.length ? buffer.length : (int) remaining;
      -                int nread = posixLib.mmapReadBytes(PosixSupport.get(inliningTarget), self.getPosixSupportHandle(), index, buffer, toReadLen);
      +                int nread = posixLib.mmapReadBytes(posixSupport, self.getPosixSupportHandle(), index, buffer, toReadLen);
                       if (toReadLen != nread) {
      -                    throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.SystemError, MMAP_CHANGED_LENGTH);
      +                    throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.SystemError, MMAP_CHANGED_LENGTH);
                       }
                   } catch (PosixException ex) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, ex);
      @@ -771,12 +916,13 @@ protected ArgumentClinicProvider getArgumentClinic() {
               }
       
               @Specialization
      -        Object flush(VirtualFrame frame, PMMap self, long offset, Object sizeObj,
      +        static Object flush(VirtualFrame frame, PMMap self, long offset, Object sizeObj,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonContext context,
                               @Cached LongIndexConverterNode sizeConversion,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   long size;
                   if (sizeObj == PNone.NO_VALUE) {
                       size = self.getLength();
      @@ -785,14 +931,14 @@ Object flush(VirtualFrame frame, PMMap self, long offset, Object sizeObj,
                   }
       
                   if (size < 0 || offset < 0 || self.getLength() - offset < size) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.FLUSH_VALUES_OUT_OF_RANGE);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.FLUSH_VALUES_OUT_OF_RANGE);
                   }
                   if (self.getAccess() == ACCESS_READ || self.getAccess() == ACCESS_COPY) {
                       return PNone.NONE;
                   }
       
                   try {
      -                posixLib.mmapFlush(getPosixSupport(), self.getPosixSupportHandle(), offset, self.getLength());
      +                posixLib.mmapFlush(context.getPosixSupport(), self.getPosixSupportHandle(), offset, self.getLength());
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
                   }
      @@ -833,5 +979,4 @@ public Object execute(VirtualFrame frame) {
                   }
               }
           }
      -
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/FrozenModules.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/FrozenModules.java
      index ad7000fa5e..bef91e264c 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/FrozenModules.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/FrozenModules.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -218,8 +218,10 @@ private static final class Map {
               private static final PythonFrozenModule FROZEN_ONLY = new PythonFrozenModule("FROZEN_ONLY", null, false);
               private static final PythonFrozenModule POLYGLOT_ARROW = new PythonFrozenModule("POLYGLOT_ARROW", null, false);
               private static final PythonFrozenModule _SYSCONFIGDATA = new PythonFrozenModule("_SYSCONFIGDATA", null, false);
      +        private static final PythonFrozenModule _POLYGLOT = new PythonFrozenModule("_POLYGLOT", null, false);
      +        private static final PythonFrozenModule _POLYGLOT_DATETIME = new PythonFrozenModule("_POLYGLOT_DATETIME", null, false);
      +        private static final PythonFrozenModule _POLYGLOT_TIME = new PythonFrozenModule("_POLYGLOT_TIME", null, false);
               private static final PythonFrozenModule GRAALPY___GRAALPYTHON__ = new PythonFrozenModule("GRAALPY___GRAALPYTHON__", null, false);
      -        private static final PythonFrozenModule GRAALPY__POLYGLOT = new PythonFrozenModule("GRAALPY__POLYGLOT", null, false);
               private static final PythonFrozenModule GRAALPY__SRE = new PythonFrozenModule("GRAALPY__SRE", null, false);
               private static final PythonFrozenModule GRAALPY__SYSCONFIG = new PythonFrozenModule("GRAALPY__SYSCONFIG", null, false);
               private static final PythonFrozenModule GRAALPY__WEAKREF = new PythonFrozenModule("GRAALPY__WEAKREF", null, false);
      @@ -227,6 +229,7 @@ private static final class Map {
               private static final PythonFrozenModule GRAALPY_JAVA = new PythonFrozenModule("GRAALPY_JAVA", null, false);
               private static final PythonFrozenModule GRAALPY_PIP_HOOK = new PythonFrozenModule("GRAALPY_PIP_HOOK", null, false);
               private static final PythonFrozenModule GRAALPY_UNICODEDATA = new PythonFrozenModule("GRAALPY_UNICODEDATA", null, false);
      +        private static final PythonFrozenModule GRAALPY__NT = new PythonFrozenModule("GRAALPY__NT", null, false);
           }
       
           public static final PythonFrozenModule lookup(String name) {
      @@ -595,10 +598,14 @@ public static final PythonFrozenModule lookup(String name) {
                       return Map.POLYGLOT_ARROW;
                   case "_sysconfigdata":
                       return Map._SYSCONFIGDATA;
      +            case "_polyglot":
      +                return Map._POLYGLOT;
      +            case "_polyglot_datetime":
      +                return Map._POLYGLOT_DATETIME;
      +            case "_polyglot_time":
      +                return Map._POLYGLOT_TIME;
                   case "graalpy.__graalpython__":
                       return Map.GRAALPY___GRAALPYTHON__;
      -            case "graalpy._polyglot":
      -                return Map.GRAALPY__POLYGLOT;
                   case "graalpy._sre":
                       return Map.GRAALPY__SRE;
                   case "graalpy._sysconfig":
      @@ -613,6 +620,8 @@ public static final PythonFrozenModule lookup(String name) {
                       return Map.GRAALPY_PIP_HOOK;
                   case "graalpy.unicodedata":
                       return Map.GRAALPY_UNICODEDATA;
      +            case "graalpy._nt":
      +                return Map.GRAALPY__NT;
                   default:
                       return null;
               }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleBuiltins.java
      index afd41e31b0..d4cdb74bf8 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleBuiltins.java
      @@ -41,6 +41,7 @@
       package com.oracle.graal.python.builtins.objects.module;
       
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_MODULE;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___ANNOTATIONS__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___DICT__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___ANNOTATIONS__;
      @@ -51,7 +52,6 @@
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___PACKAGE__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___SPEC__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___DIR__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___DIR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETATTRIBUTE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETATTR__;
      @@ -60,9 +60,11 @@
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.ArgumentClinic;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -70,12 +72,15 @@
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
       import com.oracle.graal.python.builtins.objects.dict.PDict;
      +import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.module.ModuleBuiltinsClinicProviders.ModuleNodeClinicProviderGen;
       import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins;
       import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringCheckedNode;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.GetAttrBuiltinNode;
       import com.oracle.graal.python.lib.PyDictGetItem;
      +import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
       import com.oracle.graal.python.lib.PyObjectIsTrueNode;
       import com.oracle.graal.python.lib.PyObjectLookupAttr;
       import com.oracle.graal.python.nodes.ErrorMessages;
      @@ -86,6 +91,7 @@
       import com.oracle.graal.python.nodes.builtins.ListNodes;
       import com.oracle.graal.python.nodes.call.CallNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      @@ -96,8 +102,9 @@
       import com.oracle.graal.python.nodes.object.SetDictNode;
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
      +import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      @@ -110,6 +117,7 @@
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.InlinedBranchProfile;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       
      @@ -124,9 +132,25 @@ protected List> getNodeFa
               return ModuleBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___INIT__, minNumOfPositionalArgs = 2, declaresExplicitSelf = true, parameterNames = {"self", "name", "doc"})
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = J_MODULE, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
           @GenerateNodeFactory
      +    public abstract static class ModuleNewNode extends PythonBuiltinNode {
      +
      +        @Specialization
      +        @SuppressWarnings("unused")
      +        static Object doGeneric(Object cls, Object[] varargs, PKeyword[] kwargs,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createPythonModule(language, cls, getInstanceShape.execute(cls));
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_init, isComplex = true)
      +    @SlotSignature(name = "module", minNumOfPositionalArgs = 2, parameterNames = {"self", "name", "doc"})
           @ArgumentClinic(name = "name", conversion = ArgumentClinic.ClinicConversion.TString)
      +    @GenerateNodeFactory
           public abstract static class ModuleNode extends PythonClinicBuiltinNode {
               @Override
               protected ArgumentClinicProvider getArgumentClinic() {
      @@ -169,7 +193,7 @@ static Object dir(VirtualFrame frame, PythonModule self,
                               @Cached ListNodes.ConstructListNode constructListNode,
                               @Cached CallNode callNode,
                               @Cached PyObjectLookupAttr lookup,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object dictObj = lookup.execute(frame, inliningTarget, self, T___DICT__);
                   if (dictObj instanceof PDict dict) {
                       Object dirFunc = pyDictGetItem.execute(frame, inliningTarget, dict, T___DIR__);
      @@ -179,7 +203,7 @@ static Object dir(VirtualFrame frame, PythonModule self,
                           return constructListNode.execute(frame, dict);
                       }
                   } else {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.IS_NOT_A_DICTIONARY, ".__dict__");
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.IS_NOT_A_DICTIONARY, ".__dict__");
                   }
               }
           }
      @@ -192,11 +216,10 @@ public abstract static class ModuleDictNode extends PythonBinaryBuiltinNode {
               static Object doManaged(PythonModule self, @SuppressWarnings("unused") PNone none,
                               @Bind("this") Node inliningTarget,
                               @Exclusive @Cached GetDictIfExistsNode getDict,
      -                        @Cached SetDictNode setDict,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Cached SetDictNode setDict) {
                   PDict dict = getDict.execute(self);
                   if (dict == null) {
      -                dict = createDict(inliningTarget, self, setDict, factory);
      +                dict = createDict(inliningTarget, self, setDict);
                   }
                   return dict;
               }
      @@ -205,22 +228,22 @@ static Object doManaged(PythonModule self, @SuppressWarnings("unused") PNone non
               static Object doNativeObject(PythonAbstractNativeObject self, @SuppressWarnings("unused") PNone none,
                               @Bind("this") Node inliningTarget,
                               @Exclusive @Cached GetDictIfExistsNode getDict,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   PDict dict = getDict.execute(self);
                   if (dict == null) {
      -                doError(self, none, raiseNode.get(inliningTarget));
      +                doError(self, none, raiseNode);
                   }
                   return dict;
               }
       
               @Fallback
               static Object doError(Object self, @SuppressWarnings("unused") Object dict,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.DESCRIPTOR_DICT_FOR_MOD_OBJ_DOES_NOT_APPLY_FOR_P, self);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.DESCRIPTOR_DICT_FOR_MOD_OBJ_DOES_NOT_APPLY_FOR_P, self);
               }
       
      -        private static PDict createDict(Node inliningTarget, PythonModule self, SetDictNode setDict, PythonObjectFactory factory) {
      -            PDict dict = factory.createDictFixedStorage(self);
      +        private static PDict createDict(Node inliningTarget, PythonModule self, SetDictNode setDict) {
      +            PDict dict = PFactory.createDictFixedStorage(PythonLanguage.get(inliningTarget), self);
                   setDict.execute(inliningTarget, self, dict);
                   return dict;
               }
      @@ -228,7 +251,7 @@ private static PDict createDict(Node inliningTarget, PythonModule self, SetDictN
       
           @Slot(value = SlotKind.tp_getattro, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class ModuleGetattritbuteNode extends GetAttrBuiltinNode {
      +    public abstract static class ModuleGetattributeNode extends GetAttrBuiltinNode {
               @Specialization
               static Object getattributeStr(VirtualFrame frame, PythonModule self, TruffleString key,
                               @Shared @Cached ObjectBuiltins.GetAttributeNode objectGetattrNode,
      @@ -271,7 +294,7 @@ static Object getattribute(VirtualFrame frame, PythonModule self, TruffleString
                                   @Cached CallNode callNode,
                                   @Cached PyObjectIsTrueNode castToBooleanNode,
                                   @Cached CastToTruffleStringNode castNameToStringNode,
      -                            @Cached PRaiseNode.Lazy raiseNode) {
      +                            @Cached PRaiseNode raiseNode) {
                       e.expect(inliningTarget, PythonBuiltinClassType.AttributeError, isAttrError);
                       Object getAttr = readGetattr.execute(self, T___GETATTR__);
                       if (customGetAttr.profile(inliningTarget, getAttr != PNone.NO_VALUE)) {
      @@ -289,20 +312,20 @@ static Object getattribute(VirtualFrame frame, PythonModule self, TruffleString
                               if (moduleSpec != PNone.NO_VALUE) {
                                   Object isInitializing = readGetattr.execute(moduleSpec, T__INITIALIZING);
                                   if (isInitializing != PNone.NO_VALUE && castToBooleanNode.execute(frame, isInitializing)) {
      -                                throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.MODULE_PARTIALLY_INITIALIZED_S_HAS_NO_ATTR_S, moduleName, key);
      +                                throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.MODULE_PARTIALLY_INITIALIZED_S_HAS_NO_ATTR_S, moduleName, key);
                                   }
                               }
      -                        throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.MODULE_S_HAS_NO_ATTR_S, moduleName, key);
      +                        throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.MODULE_S_HAS_NO_ATTR_S, moduleName, key);
                           }
      -                    throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.MODULE_HAS_NO_ATTR_S, key);
      +                    throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.MODULE_HAS_NO_ATTR_S, key);
                       }
                   }
               }
       
               @Specialization(guards = "!isPythonModule(self)")
               static Object getattribute(Object self, @SuppressWarnings("unused") Object key,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___GETATTRIBUTE__, "module", self);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___GETATTRIBUTE__, "module", self);
               }
           }
       
      @@ -314,10 +337,11 @@ static Object get(Object self, @SuppressWarnings("unused") Object value,
                               @Bind("this") Node inliningTarget,
                               @Shared("read") @Cached ReadAttributeFromObjectNode read,
                               @Shared("write") @Cached WriteAttributeToObjectNode write,
      -                        @Cached PythonObjectFactory.Lazy factory) {
      +                        @Cached InlinedBranchProfile createAnnotations) {
                   Object annotations = read.execute(self, T___ANNOTATIONS__);
                   if (annotations == PNone.NO_VALUE) {
      -                annotations = factory.get(inliningTarget).createDict();
      +                createAnnotations.enter(inliningTarget);
      +                annotations = PFactory.createDict(PythonLanguage.get(inliningTarget));
                       write.execute(self, T___ANNOTATIONS__, annotations);
                   }
                   return annotations;
      @@ -328,10 +352,10 @@ static Object delete(Object self, @SuppressWarnings("unused") Object value,
                               @Bind("this") Node inliningTarget,
                               @Shared("read") @Cached ReadAttributeFromObjectNode read,
                               @Shared("write") @Cached WriteAttributeToObjectNode write,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object annotations = read.execute(self, T___ANNOTATIONS__);
                   if (annotations == PNone.NO_VALUE) {
      -                throw raiseNode.get(inliningTarget).raise(AttributeError, new Object[]{T___ANNOTATIONS__});
      +                throw raiseNode.raise(inliningTarget, AttributeError, new Object[]{T___ANNOTATIONS__});
                   }
                   write.execute(self, T___ANNOTATIONS__, PNone.NO_VALUE);
                   return PNone.NONE;
      @@ -344,4 +368,19 @@ static Object set(Object self, Object value,
                   return PNone.NONE;
               }
           }
      +
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
      +    @GenerateNodeFactory
      +    abstract static class ReprNode extends PythonUnaryBuiltinNode {
      +
      +        public static final TruffleString T__MODULE_REPR = tsLiteral("_module_repr");
      +
      +        @Specialization
      +        Object repr(VirtualFrame frame, Object self,
      +                        @Bind Node inliningTarget,
      +                        @Bind PythonContext context,
      +                        @Cached PyObjectCallMethodObjArgs callMethod) {
      +            return callMethod.execute(frame, inliningTarget, context.getImportlib(), T__MODULE_REPR, self);
      +        }
      +    }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleGetNameNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleGetNameNode.java
      index 547ad995af..88118ab53b 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleGetNameNode.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleGetNameNode.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -69,13 +69,13 @@ public abstract class ModuleGetNameNode extends Node {
           static TruffleString doPythonModule(Node inliningTarget, PythonModule module,
                           @Cached(inline = false) ReadAttributeFromObjectNode readNameNode,
                           @Cached CastToTruffleStringNode castToTruffleStringNode,
      -                    @Cached PRaiseNode.Lazy raiseNode) {
      +                    @Cached PRaiseNode raiseNode) {
       
               try {
                   Object name = readNameNode.execute(module, SpecialAttributeNames.T___NAME__);
                   return castToTruffleStringNode.execute(inliningTarget, name);
               } catch (CannotCastException e) {
      -            throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.SystemError, ErrorMessages.NAMELESS_MODULE);
      +            throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.SystemError, ErrorMessages.NAMELESS_MODULE);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/PythonFrozenModule.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/PythonFrozenModule.java
      index fe76a33414..b20fc5df77 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/PythonFrozenModule.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/PythonFrozenModule.java
      @@ -47,6 +47,7 @@
       import java.io.IOException;
       import java.io.InputStream;
       
      +import com.oracle.graal.python.runtime.PythonOptions;
       import com.oracle.truffle.api.strings.TruffleString;
       
       public final class PythonFrozenModule {
      @@ -56,7 +57,7 @@ public final class PythonFrozenModule {
       
           private static byte[] getByteCode(String symbol) {
               try {
      -            InputStream resourceAsStream = PythonFrozenModule.class.getResourceAsStream("Frozen" + symbol + ".bin");
      +            InputStream resourceAsStream = PythonFrozenModule.class.getResourceAsStream("Frozen" + symbol + "." + getSuffix());
                   if (resourceAsStream != null) {
                       return resourceAsStream.readAllBytes();
                   }
      @@ -66,6 +67,14 @@ private static byte[] getByteCode(String symbol) {
               return null;
           }
       
      +    private static String getSuffix() {
      +        if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
      +            return "bin_dsl";
      +        } else {
      +            return "bin";
      +        }
      +    }
      +
           public PythonFrozenModule(String symbol, String originalName, boolean isPackage) {
               this(toTruffleStringUncached(originalName), getByteCode(symbol), isPackage);
           }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/PythonModule.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/PythonModule.java
      index e080f455ea..ba26300675 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/PythonModule.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/PythonModule.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2017, 2024, Oracle and/or its affiliates.
      + * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
        * Copyright (c) 2013, Regents of the University of California
        *
        * All rights reserved.
      @@ -41,7 +41,7 @@
       import com.oracle.graal.python.builtins.objects.object.PythonObject;
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.object.SetDictNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.object.Shape;
       import com.oracle.truffle.api.strings.TruffleString;
      @@ -109,9 +109,9 @@ private PythonModule(PythonLanguage lang, TruffleString moduleName) {
            */
           @TruffleBoundary
           public static PythonModule createInternal(TruffleString moduleName) {
      -        PythonObjectFactory factory = PythonObjectFactory.getUncached();
      -        PythonModule pythonModule = new PythonModule(PythonLanguage.get(null), moduleName);
      -        PDict dict = factory.createDictFixedStorage(pythonModule);
      +        PythonLanguage language = PythonLanguage.get(null);
      +        PythonModule pythonModule = new PythonModule(language, moduleName);
      +        PDict dict = PFactory.createDictFixedStorage(language, pythonModule);
               SetDictNode.executeUncached(pythonModule, dict);
               return pythonModule;
           }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/namespace/SimpleNamespaceBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/namespace/SimpleNamespaceBuiltins.java
      index 8a2222ac7c..025c028c77 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/namespace/SimpleNamespaceBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/namespace/SimpleNamespaceBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -42,10 +42,7 @@
       
       import static com.oracle.graal.python.nodes.ErrorMessages.NO_POSITIONAL_ARGUMENTS_EXPECTED;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___DICT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___REPR__;
       import static com.oracle.graal.python.nodes.StringLiterals.T_COMMA_SPACE;
       import static com.oracle.graal.python.nodes.StringLiterals.T_EQ;
      @@ -58,9 +55,12 @@
       import java.util.Comparator;
       import java.util.List;
       
      -import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode;
       import org.graalvm.collections.Pair;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -78,13 +78,16 @@
       import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.str.StringUtils;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.RichCmpBuiltinNode;
      +import com.oracle.graal.python.lib.RichCmpOp;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PRaiseNode;
      +import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode;
       import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassExactProfile;
      @@ -94,7 +97,7 @@
       import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.exception.PythonErrorType;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      @@ -111,19 +114,36 @@
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PSimpleNamespace)
       public final class SimpleNamespaceBuiltins extends PythonBuiltins {
      +    public static final TpSlots SLOTS = SimpleNamespaceBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return SimpleNamespaceBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "SimpleNamespace", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class SimpleNamespaceNode extends PythonVarargsBuiltinNode {
      +        @Specialization
      +        static PSimpleNamespace doit(Object cls, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") PKeyword[] keywords,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createSimpleNamespace(language, cls, getInstanceShape.execute(cls));
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_init, isComplex = true)
      +    @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
           @GenerateNodeFactory
           protected abstract static class SimpleNamespaceInitNode extends PythonVarargsBuiltinNode {
               @Specialization
      -        Object init(PSimpleNamespace self, Object[] args, PKeyword[] kwargs,
      -                        @Cached WriteAttributeToPythonObjectNode writeAttrNode) {
      +        static Object init(PSimpleNamespace self, Object[] args, PKeyword[] kwargs,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached WriteAttributeToPythonObjectNode writeAttrNode,
      +                        @Cached PRaiseNode raiseNode) {
                   if (args.length > 0) {
      -                throw raise(PythonBuiltinClassType.TypeError, NO_POSITIONAL_ARGUMENTS_EXPECTED);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, NO_POSITIONAL_ARGUMENTS_EXPECTED);
                   }
                   for (PKeyword keyword : kwargs) {
                       writeAttrNode.execute(self, keyword.getName(), keyword.getValue());
      @@ -143,20 +163,20 @@ Object getDict(PSimpleNamespace self,
               }
           }
       
      -    @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.tp_richcompare, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class SimpleNamespaceEqNode extends PythonBinaryBuiltinNode {
      +    public abstract static class SimpleNamespaceEqNode extends RichCmpBuiltinNode {
               @Specialization
      -        static Object eq(VirtualFrame frame, PSimpleNamespace self, PSimpleNamespace other,
      +        static Object eq(VirtualFrame frame, PSimpleNamespace self, PSimpleNamespace other, RichCmpOp op,
                               @Bind("this") Node inliningTarget,
                               @Cached GetOrCreateDictNode getDict,
                               @Cached DictBuiltins.EqNode eqNode) {
      -            return eqNode.execute(frame, getDict.execute(inliningTarget, self), getDict.execute(inliningTarget, other));
      +            return eqNode.execute(frame, getDict.execute(inliningTarget, self), getDict.execute(inliningTarget, other), op);
               }
       
               @Fallback
               @SuppressWarnings("unused")
      -        static PNotImplemented doGeneric(Object self, Object other) {
      +        static PNotImplemented doGeneric(Object self, Object other, RichCmpOp op) {
                   return PNotImplemented.NOT_IMPLEMENTED;
               }
           }
      @@ -169,14 +189,14 @@ static Object reduce(PSimpleNamespace self,
                               @Bind("this") Node inliningTarget,
                               @Cached GetClassNode getClassNode,
                               @Cached GetOrCreateDictNode getDict,
      -                        @Cached PythonObjectFactory factory) {
      -            PTuple args = factory.createEmptyTuple();
      +                        @Bind PythonLanguage language) {
      +            PTuple args = PFactory.createEmptyTuple(language);
                   final PDict dict = getDict.execute(inliningTarget, self);
      -            return factory.createTuple(new Object[]{getClassNode.execute(inliningTarget, self), args, dict});
      +            return PFactory.createTuple(language, new Object[]{getClassNode.execute(inliningTarget, self), args, dict});
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class SimpleNamespaceReprNode extends PythonUnaryBuiltinNode {
               private static final TruffleString T_RECURSE = tsLiteral("...)");
      @@ -232,7 +252,7 @@ protected static TruffleString getReprString(Node inliningTarget, Object obj,
                       try {
                           return castStr.execute(inliningTarget, reprObj);
                       } catch (CannotCastException e) {
      -                    throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.RETURNED_NON_STRING, "__repr__", reprObj);
      +                    throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.RETURNED_NON_STRING, "__repr__", reprObj);
                       }
                   }
       
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectBuiltins.java
      index 373ce219f3..b8e6894e9a 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectBuiltins.java
      @@ -26,6 +26,8 @@
       
       package com.oracle.graal.python.builtins.objects.object;
       
      +import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_OBJECT_NEW;
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_OBJECT;
       import static com.oracle.graal.python.nodes.PGuards.isDeleteMarker;
       import static com.oracle.graal.python.nodes.PGuards.isDict;
       import static com.oracle.graal.python.nodes.PGuards.isNoValue;
      @@ -33,30 +35,23 @@
       import static com.oracle.graal.python.nodes.PGuards.isPythonObject;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___CLASS__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___DICT__;
      +import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___ABSTRACTMETHODS__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___CLASS__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DICT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___DIR__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___FORMAT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETSTATE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT_SUBCLASS__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE_EX__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SIZEOF__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SUBCLASSHOOK__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___TRUFFLE_RICHCOMPARE__;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T_JOIN;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T_SORT;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T_UPDATE;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LEN__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___REDUCE__;
      +import static com.oracle.graal.python.nodes.StringLiterals.T_COMMA_SPACE;
       import static com.oracle.graal.python.nodes.StringLiterals.T_NONE;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.AttributeError;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
      @@ -64,18 +59,21 @@
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.ArgumentClinic;
       import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinConstructorsFactory;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.PNotImplemented;
       import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
      +import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions;
       import com.oracle.graal.python.builtins.objects.cext.structs.CFields;
       import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess;
       import com.oracle.graal.python.builtins.objects.dict.PDict;
      @@ -84,6 +82,7 @@
       import com.oracle.graal.python.builtins.objects.getsetdescriptor.DescriptorBuiltins.DescrGetNode;
       import com.oracle.graal.python.builtins.objects.getsetdescriptor.DescriptorBuiltins.DescrSetNode;
       import com.oracle.graal.python.builtins.objects.getsetdescriptor.DescriptorDeleteMarker;
      +import com.oracle.graal.python.builtins.objects.list.PList;
       import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
       import com.oracle.graal.python.builtins.objects.object.ObjectBuiltinsClinicProviders.FormatNodeClinicProviderGen;
       import com.oracle.graal.python.builtins.objects.object.ObjectBuiltinsClinicProviders.ReduceExNodeClinicProviderGen;
      @@ -91,8 +90,9 @@
       import com.oracle.graal.python.builtins.objects.object.ObjectBuiltinsFactory.GetAttributeNodeFactory;
       import com.oracle.graal.python.builtins.objects.set.PSet;
       import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
      -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
      +import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode;
       import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
       import com.oracle.graal.python.builtins.objects.type.TypeFlags;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      @@ -102,32 +102,32 @@
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.CallSlotDescrGet;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrSet;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.GetAttrBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRepr.CallSlotReprNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSetAttr.SetAttrBuiltinNode;
      -import com.oracle.graal.python.lib.PyObjectIsNotTrueNode;
      +import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
       import com.oracle.graal.python.lib.PyObjectIsTrueNode;
       import com.oracle.graal.python.lib.PyObjectLookupAttr;
       import com.oracle.graal.python.lib.PyObjectSizeNode;
      +import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
      +import com.oracle.graal.python.lib.RichCmpOp;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.HiddenAttr;
       import com.oracle.graal.python.nodes.PGuards;
      +import com.oracle.graal.python.nodes.PNodeWithContext;
       import com.oracle.graal.python.nodes.PRaiseNode;
      -import com.oracle.graal.python.nodes.PRaiseNode.Lazy;
       import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
      -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode;
       import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
       import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
      +import com.oracle.graal.python.nodes.builtins.ListNodes;
       import com.oracle.graal.python.nodes.call.CallNode;
      -import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
      -import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
       import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
      -import com.oracle.graal.python.nodes.expression.BinaryComparisonNode;
      -import com.oracle.graal.python.nodes.expression.BinaryComparisonNodeFactory;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode;
      -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
      @@ -141,8 +141,8 @@
       import com.oracle.graal.python.nodes.object.SetDictNode;
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
      -import com.oracle.graal.python.nodes.util.SplitArgsNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.exception.PException;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerAsserts;
       import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
      @@ -152,6 +152,7 @@
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Cached.Exclusive;
       import com.oracle.truffle.api.dsl.Cached.Shared;
      +import com.oracle.truffle.api.dsl.Fallback;
       import com.oracle.truffle.api.dsl.GenerateCached;
       import com.oracle.truffle.api.dsl.GenerateInline;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -162,7 +163,6 @@
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
      -import com.oracle.truffle.api.nodes.UnexpectedResultException;
       import com.oracle.truffle.api.profiles.InlinedBranchProfile;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
      @@ -196,16 +196,16 @@ static PNone setClass(VirtualFrame frame, Object self, Object value,
                               @Cached CheckCompatibleForAssigmentNode checkCompatibleForAssigmentNode,
                               @Exclusive @Cached GetClassNode getClassNode,
                               @Cached SetClassNode setClassNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (!isTypeNode.execute(inliningTarget, value)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CLASS_MUST_BE_SET_TO_CLASS, value);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CLASS_MUST_BE_SET_TO_CLASS, value);
                   }
                   Object type = getClassNode.execute(inliningTarget, self);
                   boolean bothModuleSubtypes = isModuleProfile.profileClass(inliningTarget, type, PythonBuiltinClassType.PythonModule) &&
                                   isModuleProfile.profileClass(inliningTarget, value, PythonBuiltinClassType.PythonModule);
                   boolean bothMutable = (getTypeFlagsNode.execute(type) & TypeFlags.IMMUTABLETYPE) == 0 && (getTypeFlagsNode.execute(value) & TypeFlags.IMMUTABLETYPE) == 0;
                   if (!bothModuleSubtypes && !bothMutable) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CLASS_ASSIGNMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CLASS_ASSIGNMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES);
                   }
       
                   checkCompatibleForAssigmentNode.execute(frame, type, value);
      @@ -233,20 +233,147 @@ static void doNative(PythonAbstractNativeObject self, Object newClass,
               }
           }
       
      -    @Builtin(name = J___INIT__, takesVarArgs = true, minNumOfPositionalArgs = 1, takesVarKeywordArgs = true)
      +    // object()
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = J_OBJECT, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
           @GenerateNodeFactory
      -    @ImportStatic(SpecialMethodSlot.class)
      -    public abstract static class InitNode extends PythonVarargsBuiltinNode {
      -        @Child private SplitArgsNode splitArgsNode;
      +    public abstract static class ObjectNode extends PythonVarargsBuiltinNode {
       
      -        @Override
      -        public final Object varArgExecute(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported {
      -            if (splitArgsNode == null) {
      +        @Child private ReportAbstractClassNode reportAbstractClassNode;
      +
      +        @GenerateInline(false) // Used lazily
      +        abstract static class ReportAbstractClassNode extends PNodeWithContext {
      +            public abstract PException execute(VirtualFrame frame, Object type);
      +
      +            @Specialization
      +            static PException report(VirtualFrame frame, Object type,
      +                            @Bind("this") Node inliningTarget,
      +                            @Cached PyObjectCallMethodObjArgs callSort,
      +                            @Cached PyObjectCallMethodObjArgs callJoin,
      +                            @Cached PyObjectSizeNode sizeNode,
      +                            @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode,
      +                            @Cached CastToTruffleStringNode cast,
      +                            @Cached ListNodes.ConstructListNode constructListNode,
      +                            @Cached PRaiseNode raiseNode) {
      +                PList list = constructListNode.execute(frame, readAttributeFromObjectNode.execute(type, T___ABSTRACTMETHODS__));
      +                int methodCount = sizeNode.execute(frame, inliningTarget, list);
      +                callSort.execute(frame, inliningTarget, list, T_SORT);
      +                TruffleString joined = cast.execute(inliningTarget, callJoin.execute(frame, inliningTarget, T_COMMA_SPACE, T_JOIN, list));
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_INSTANTIATE_ABSTRACT_CLASS_WITH_ABSTRACT_METHODS, type, methodCount > 1 ? "s" : "", joined);
      +            }
      +        }
      +
      +        @GenerateInline
      +        @GenerateCached(false)
      +        abstract static class CheckExcessArgsNode extends Node {
      +            abstract void execute(Node inliningTarget, Object type, Object[] args, PKeyword[] kwargs);
      +
      +            @Specialization(guards = {"args.length == 0", "kwargs.length == 0"})
      +            @SuppressWarnings("unused")
      +            static void doNothing(Object type, Object[] args, PKeyword[] kwargs) {
      +            }
      +
      +            @Fallback
      +            @SuppressWarnings("unused")
      +            static void check(Node inliningTarget, Object type, Object[] args, PKeyword[] kwargs,
      +                            @Cached GetCachedTpSlotsNode getSlots,
      +                            @Cached PRaiseNode raiseNode) {
      +                TpSlots slots = getSlots.execute(inliningTarget, type);
      +                if (slots.tp_new() != SLOTS.tp_new()) {
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.NEW_TAKES_ONE_ARG);
      +                }
      +                if (slots.tp_init() == SLOTS.tp_init()) {
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.NEW_TAKES_NO_ARGS, type);
      +                }
      +            }
      +        }
      +
      +        @Specialization(guards = {"!self.needsNativeAllocation()"})
      +        Object doManagedObject(VirtualFrame frame, PythonManagedClass self, Object[] varargs, PKeyword[] kwargs,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached CheckExcessArgsNode checkExcessArgsNode,
      +                        @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            checkExcessArgsNode.execute(inliningTarget, self, varargs, kwargs);
      +            if (self.isAbstractClass()) {
      +                throw reportAbstractClass(frame, self);
      +            }
      +            return PFactory.createPythonObject(language, self, getInstanceShape.execute(self));
      +        }
      +
      +        @Specialization
      +        static Object doBuiltinTypeType(PythonBuiltinClassType self, Object[] varargs, PKeyword[] kwargs,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached CheckExcessArgsNode checkExcessArgsNode,
      +                        @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            checkExcessArgsNode.execute(inliningTarget, self, varargs, kwargs);
      +            return PFactory.createPythonObject(language, self, getInstanceShape.execute(self));
      +        }
      +
      +        @Specialization(guards = "self.needsNativeAllocation()")
      +        @SuppressWarnings("truffle-static-method")
      +        @InliningCutoff
      +        Object doNativeObjectIndirect(VirtualFrame frame, PythonManagedClass self, Object[] varargs, PKeyword[] kwargs,
      +                        @Bind("this") Node inliningTarget,
      +                        @Shared @Cached CheckExcessArgsNode checkExcessArgsNode,
      +                        @Shared @Cached CallNativeGenericNewNode callNativeGenericNewNode) {
      +            checkExcessArgsNode.execute(inliningTarget, self, varargs, kwargs);
      +            if (self.isAbstractClass()) {
      +                throw reportAbstractClass(frame, self);
      +            }
      +            return callNativeGenericNewNode.execute(inliningTarget, self);
      +        }
      +
      +        @Specialization(guards = "isNativeClass(self)")
      +        @SuppressWarnings("truffle-static-method")
      +        @InliningCutoff
      +        Object doNativeObjectDirect(VirtualFrame frame, Object self, Object[] varargs, PKeyword[] kwargs,
      +                        @Bind("this") Node inliningTarget,
      +                        @Shared @Cached CheckExcessArgsNode checkExcessArgsNode,
      +                        @Exclusive @Cached TypeNodes.GetTypeFlagsNode getTypeFlagsNode,
      +                        @Shared @Cached CallNativeGenericNewNode callNativeGenericNewNode) {
      +            checkExcessArgsNode.execute(inliningTarget, self, varargs, kwargs);
      +            if ((getTypeFlagsNode.execute(self) & TypeFlags.IS_ABSTRACT) != 0) {
      +                throw reportAbstractClass(frame, self);
      +            }
      +            return callNativeGenericNewNode.execute(inliningTarget, self);
      +        }
      +
      +        @GenerateInline
      +        @GenerateCached(false)
      +        protected abstract static class CallNativeGenericNewNode extends Node {
      +            abstract Object execute(Node inliningTarget, Object cls);
      +
      +            @Specialization
      +            static Object call(Object cls,
      +                            @Cached(inline = false) CApiTransitions.PythonToNativeNode toNativeNode,
      +                            @Cached(inline = false) CApiTransitions.NativeToPythonTransferNode toPythonNode,
      +                            @Cached(inline = false) CExtNodes.PCallCapiFunction callCapiFunction) {
      +                return toPythonNode.execute(callCapiFunction.call(FUN_PY_OBJECT_NEW, toNativeNode.execute(cls)));
      +            }
      +        }
      +
      +        @SuppressWarnings("unused")
      +        @Fallback
      +        Object fallback(Object o, Object[] varargs, PKeyword[] kwargs) {
      +            throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "object.__new__(X): X", o);
      +        }
      +
      +        @InliningCutoff
      +        private PException reportAbstractClass(VirtualFrame frame, Object type) {
      +            if (reportAbstractClassNode == null) {
                       CompilerDirectives.transferToInterpreterAndInvalidate();
      -                splitArgsNode = insert(SplitArgsNode.create());
      +                reportAbstractClassNode = insert(ObjectBuiltinsFactory.ObjectNodeFactory.ReportAbstractClassNodeGen.create());
                   }
      -            return execute(frame, arguments[0], splitArgsNode.executeCached(arguments), keywords);
      +            return reportAbstractClassNode.execute(frame, type);
               }
      +    }
      +
      +    @Slot(value = SlotKind.tp_init, isComplex = true)
      +    @SlotSignature(takesVarArgs = true, minNumOfPositionalArgs = 1, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class InitNode extends PythonVarargsBuiltinNode {
       
               @Specialization(guards = {"arguments.length == 0", "keywords.length == 0"})
               @SuppressWarnings("unused")
      @@ -259,46 +386,45 @@ static PNone initNoArgs(Object self, Object[] arguments, PKeyword[] keywords) {
               static PNone init(Object self, Object[] arguments, PKeyword[] keywords,
                               @Bind("this") Node inliningTarget,
                               @Cached GetClassNode getClassNode,
      -                        @Cached(parameters = "Init") LookupCallableSlotInMRONode lookupInit,
      -                        @Cached(parameters = "New") LookupCallableSlotInMRONode lookupNew,
      -                        @Cached TypeNodes.CheckCallableIsSpecificBuiltinNode checkSlotIs,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached GetCachedTpSlotsNode getSlots,
      +                        @Cached PRaiseNode raiseNode) {
                   if (arguments.length != 0 || keywords.length != 0) {
                       Object type = getClassNode.execute(inliningTarget, self);
      -                if (!checkSlotIs.execute(inliningTarget, lookupInit.execute(type), ObjectBuiltinsFactory.InitNodeFactory.getInstance())) {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.INIT_TAKES_ONE_ARG_OBJECT);
      +                TpSlots slots = getSlots.execute(inliningTarget, type);
      +                if (slots.tp_init() != SLOTS.tp_init()) {
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.INIT_TAKES_ONE_ARG_OBJECT);
                       }
       
      -                if (checkSlotIs.execute(inliningTarget, lookupNew.execute(type), BuiltinConstructorsFactory.ObjectNodeFactory.getInstance())) {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.INIT_TAKES_ONE_ARG, type);
      +                if (slots.tp_new() == SLOTS.tp_new()) {
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.INIT_TAKES_ONE_ARG, type);
                       }
                   }
                   return PNone.NONE;
               }
           }
       
      -    @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_hash, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class HashNode extends PythonUnaryBuiltinNode {
      +    public abstract static class HashNode extends HashBuiltinNode {
               @Specialization
      -        public int hash(PythonBuiltinClassType self) {
      +        public long hash(PythonBuiltinClassType self) {
                   return hash(getContext().lookupType(self));
               }
       
               @TruffleBoundary
               @Specialization(guards = "!isPythonBuiltinClassType(self)")
      -        public static int hash(Object self) {
      +        public static long hash(Object self) {
                   return self.hashCode();
               }
           }
       
      -    @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.tp_richcompare, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class EqNode extends PythonBinaryBuiltinNode {
      -        @Specialization
      -        static Object eq(Object self, Object other,
      +    public abstract static class EqNode extends TpSlotRichCompare.RichCmpBuiltinNode {
      +        @Specialization(guards = "op.isEq()")
      +        static Object eq(Object self, Object other, RichCmpOp op,
                               @Bind("this") Node inliningTarget,
      -                        @Cached InlinedConditionProfile isEq,
      +                        @Exclusive @Cached InlinedConditionProfile isEq,
                               @Cached IsNode isNode) {
                   if (isEq.profile(inliningTarget, isNode.execute(self, other))) {
                       return true;
      @@ -308,49 +434,51 @@ static Object eq(Object self, Object other,
                       return PNotImplemented.NOT_IMPLEMENTED;
                   }
               }
      -    }
      -
      -    @Builtin(name = J___NE__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    @ImportStatic(SpecialMethodSlot.class)
      -    public abstract static class NeNode extends PythonBinaryBuiltinNode {
       
      -        @Specialization
      -        static Object doGeneric(VirtualFrame frame, Object self, Object other,
      -                        @Cached(parameters = "Eq") LookupAndCallBinaryNode eqNode,
      -                        @Cached PyObjectIsNotTrueNode ifFalseNode) {
      -            Object result = eqNode.executeObject(frame, self, other);
      -            if (result == PNotImplemented.NOT_IMPLEMENTED) {
      -                return result;
      +        @Specialization(guards = "op.isNe()")
      +        static Object ne(VirtualFrame frame, Object self, Object other, RichCmpOp op,
      +                        @Bind("this") Node inliningTarget,
      +                        @Exclusive @Cached InlinedConditionProfile isEq,
      +                        @Cached GetObjectSlotsNode getSlotsNode,
      +                        @Cached TpSlotRichCompare.CallSlotRichCmpNode callSlotRichCmp,
      +                        @Cached PyObjectIsTrueNode isTrueNode) {
      +            // By default, __ne__() delegates to __eq__() and inverts the result, unless the latter
      +            // returns NotImplemented
      +            TpSlot selfRichCmp = getSlotsNode.execute(inliningTarget, self).tp_richcmp();
      +            if (selfRichCmp == null) {
      +                return PNotImplemented.NOT_IMPLEMENTED;
      +            }
      +            Object result = callSlotRichCmp.execute(frame, inliningTarget, selfRichCmp, self, other, RichCmpOp.Py_EQ);
      +            if (result != PNotImplemented.NOT_IMPLEMENTED) {
      +                return !isTrueNode.execute(frame, result);
                   }
      -            return ifFalseNode.execute(frame, result);
      +            return PNotImplemented.NOT_IMPLEMENTED;
               }
      -    }
       
      -    @Builtin(name = J___LT__, minNumOfPositionalArgs = 2)
      -    @Builtin(name = J___LE__, minNumOfPositionalArgs = 2)
      -    @Builtin(name = J___GT__, minNumOfPositionalArgs = 2)
      -    @Builtin(name = J___GE__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    public abstract static class LtLeGtGeNode extends PythonBinaryBuiltinNode {
      -        @Specialization
      -        @SuppressWarnings("unused")
      -        static Object notImplemented(Object self, Object other) {
      +        @Fallback
      +        static Object doOthers(Object self, Object other, RichCmpOp op) {
                   return PNotImplemented.NOT_IMPLEMENTED;
               }
           }
       
      -    @Builtin(name = J___STR__, minNumOfPositionalArgs = 1, doc = "Return str(self).")
      +    @Slot(value = SlotKind.tp_str, isComplex = true)
           @GenerateNodeFactory
           abstract static class StrNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object str(VirtualFrame frame, Object self,
      -                        @Cached("create(Repr)") LookupAndCallUnaryNode reprNode) {
      -            return reprNode.executeObject(frame, self);
      +                        @Bind Node inliningTarget,
      +                        @Cached GetObjectSlotsNode getSlots,
      +                        @Cached CallSlotReprNode callSlot,
      +                        @Cached ObjectNodes.DefaultObjectReprNode defaultRepr) {
      +            TpSlots slots = getSlots.execute(inliningTarget, self);
      +            if (slots.tp_repr() != null) {
      +                return callSlot.execute(frame, inliningTarget, slots.tp_repr(), self);
      +            }
      +            return defaultRepr.execute(frame, inliningTarget, self);
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
       
      @@ -394,7 +522,7 @@ Object doItTruffleString(VirtualFrame frame, Object object, @SuppressWarnings("u
                               @Exclusive @Cached GetClassNode getClassNode,
                               @Exclusive @Cached GetObjectSlotsNode getSlotsNode,
                               @Cached("create(cachedKey)") LookupAttributeInMRONode lookup,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   Object type = getClassNode.execute(inliningTarget, object);
                   Object descr = lookup.execute(type);
                   return fullLookup(frame, inliningTarget, object, cachedKey, type, descr, getSlotsNode, raiseNode);
      @@ -408,12 +536,12 @@ Object doIt(VirtualFrame frame, Object object, Object keyObj,
                               @Exclusive @Cached GetClassNode getClassNode,
                               @Exclusive @Cached GetObjectSlotsNode getSlotsNode,
                               @Cached CastToTruffleStringNode castKeyToStringNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   TruffleString key;
                   try {
                       key = castKeyToStringNode.execute(inliningTarget, keyObj);
                   } catch (CannotCastException e) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj);
                   }
       
                   Object type = getClassNode.execute(inliningTarget, object);
      @@ -421,7 +549,7 @@ Object doIt(VirtualFrame frame, Object object, Object keyObj,
                   return fullLookup(frame, inliningTarget, object, key, type, descr, getSlotsNode, raiseNode);
               }
       
      -        private Object fullLookup(VirtualFrame frame, Node inliningTarget, Object object, TruffleString key, Object type, Object descr, GetObjectSlotsNode getSlotsNode, Lazy raiseNode) {
      +        private Object fullLookup(VirtualFrame frame, Node inliningTarget, Object object, TruffleString key, Object type, Object descr, GetObjectSlotsNode getSlotsNode, PRaiseNode raiseNode) {
                   boolean hasDescr = descr != PNone.NO_VALUE;
                   if (hasDescr && (profileFlags & HAS_DESCR) == 0) {
                       CompilerDirectives.transferToInterpreterAndInvalidate();
      @@ -455,7 +583,7 @@ private Object fullLookup(VirtualFrame frame, Node inliningTarget, Object object
                           return dispatch(frame, object, type, descr, descrGetSlot);
                       }
                   }
      -            throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key);
      +            throw raiseNode.raiseAttributeError(inliningTarget, object, key);
               }
       
               private Object readAttribute(Object object, TruffleString key) {
      @@ -607,8 +735,8 @@ private static Object getDescrFromBuiltinBase(Node inliningTarget, Object type,
       
               @Specialization(guards = {"!isNoValue(mapping)", "!isDict(mapping)", "!isDeleteMarker(mapping)"})
               static Object dict(@SuppressWarnings("unused") Object self, Object mapping,
      -                        @Shared @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, mapping);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, mapping);
               }
       
               @Specialization(guards = "isFallback(self, mapping, inliningTarget, getClassNode, otherBuiltinClassProfile, isBuiltinClassProfile)", limit = "1")
      @@ -617,9 +745,8 @@ static Object raise(Object self, Object mapping,
                               @Bind("this") Node inliningTarget,
                               @Exclusive @Cached IsOtherBuiltinClassProfile otherBuiltinClassProfile,
                               @Exclusive @Cached IsBuiltinClassExactProfile isBuiltinClassProfile,
      -                        @Exclusive @Cached GetClassNode getClassNode,
      -                        @Shared @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, self, "__dict__");
      +                        @Exclusive @Cached GetClassNode getClassNode) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, self, "__dict__");
               }
       
               static boolean isFallback(Object self, Object mapping, Node inliningTarget,
      @@ -651,60 +778,15 @@ protected ArgumentClinicProvider getArgumentClinic() {
       
               @Specialization(guards = "!formatString.isEmpty()")
               static Object format(Object self, @SuppressWarnings("unused") TruffleString formatString,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_FORMAT_STRING_PASSED_TO_P_FORMAT, self);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_FORMAT_STRING_PASSED_TO_P_FORMAT, self);
               }
       
               @Specialization(guards = "formatString.isEmpty()")
               static Object format(VirtualFrame frame, Object self, @SuppressWarnings("unused") TruffleString formatString,
      -                        @Cached("create(Str)") LookupAndCallUnaryNode strCall) {
      -            return strCall.executeObject(frame, self);
      -        }
      -    }
      -
      -    @Builtin(name = J___TRUFFLE_RICHCOMPARE__, minNumOfPositionalArgs = 3)
      -    @GenerateNodeFactory
      -    abstract static class RichCompareNode extends PythonTernaryBuiltinNode {
      -        protected static final int NO_SLOW_PATH = Integer.MAX_VALUE;
      -        @CompilationFinal private boolean seenNonBoolean = false;
      -
      -        static BinaryComparisonNode createOp(int op) {
      -            switch (op) {
      -                case 0:
      -                    return BinaryComparisonNodeFactory.LtNodeGen.create();
      -                case 4:
      -                    return BinaryComparisonNodeFactory.GtNodeGen.create();
      -                case 2:
      -                    return BinaryComparisonNodeFactory.EqNodeGen.create();
      -                case 5:
      -                    return BinaryComparisonNodeFactory.GeNodeGen.create();
      -                case 1:
      -                    return BinaryComparisonNodeFactory.LeNodeGen.create();
      -                case 3:
      -                    return BinaryComparisonNodeFactory.NeNodeGen.create();
      -                default:
      -                    throw new RuntimeException("unexpected operation: " + op);
      -            }
      -        }
      -
      -        @Specialization(guards = "op == cachedOp", limit = "NO_SLOW_PATH")
      -        @SuppressWarnings("truffle-static-method")
      -        boolean richcmp(VirtualFrame frame, Object left, Object right, @SuppressWarnings("unused") int op,
      -                        @Bind("this") Node inliningTarget,
      -                        @SuppressWarnings("unused") @Cached("op") int cachedOp,
      -                        @Cached("createOp(op)") BinaryComparisonNode node,
      -                        @Cached PyObjectIsTrueNode castToBooleanNode) {
      -            if (!seenNonBoolean) {
      -                try {
      -                    return node.executeBool(frame, left, right);
      -                } catch (UnexpectedResultException e) {
      -                    CompilerDirectives.transferToInterpreterAndInvalidate();
      -                    seenNonBoolean = true;
      -                    return castToBooleanNode.execute(frame, e.getResult());
      -                }
      -            } else {
      -                return castToBooleanNode.execute(frame, node.executeObject(frame, left, right));
      -            }
      +                        @Bind Node inliningTarget,
      +                        @Cached PyObjectStrAsObjectNode str) {
      +            return str.execute(frame, inliningTarget, self);
               }
           }
       
      @@ -726,10 +808,6 @@ static Object notImplemented(Object self, Object[] arguments, PKeyword[] keyword
                   return PNotImplemented.NOT_IMPLEMENTED;
               }
       
      -        @Override
      -        public Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported {
      -            return PNotImplemented.NOT_IMPLEMENTED;
      -        }
           }
       
           @Builtin(name = J___SIZEOF__, minNumOfPositionalArgs = 1)
      @@ -815,11 +893,11 @@ static Object dir(VirtualFrame frame, Object obj,
                               @Cached GetClassNode getClassNode,
                               @Cached IsSubtypeNode isSubtypeNode,
                               @Cached com.oracle.graal.python.builtins.objects.type.TypeBuiltins.DirNode dirNode,
      -                        @Cached PythonObjectFactory factory) {
      -            PSet names = factory.createSet();
      +                        @Bind PythonLanguage language) {
      +            PSet names = PFactory.createSet(language);
                   Object updateCallable = lookupAttrNode.execute(frame, inliningTarget, names, T_UPDATE);
                   Object ns = lookupAttrNode.execute(frame, inliningTarget, obj, T___DICT__);
      -            if (isSubtypeNode.execute(frame, getClassNode.execute(inliningTarget, ns), PythonBuiltinClassType.PDict)) {
      +            if (isSubtypeNode.execute(getClassNode.execute(inliningTarget, ns), PythonBuiltinClassType.PDict)) {
                       callNode.execute(frame, updateCallable, ns);
                   }
                   Object klass = lookupAttrNode.execute(frame, inliningTarget, obj, T___CLASS__);
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java
      index 8d29113d7c..983c513996 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -107,6 +107,8 @@
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
       import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode;
       import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrSet.CallSlotDescrSet;
      @@ -140,7 +142,7 @@
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.PythonOptions;
       import com.oracle.graal.python.runtime.object.IDUtils;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
       import com.oracle.truffle.api.Assumption;
       import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
      @@ -329,8 +331,8 @@ static Object id(boolean self,
       
               @Specialization
               static Object id(double self,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return IDUtils.getId(self, factory);
      +                        @Bind PythonLanguage language) {
      +            return IDUtils.getId(language, self);
               }
       
               @Specialization
      @@ -342,8 +344,8 @@ static Object id(PFloat self,
       
               @Specialization
               static Object id(long self,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return IDUtils.getId(self, factory);
      +                        @Bind PythonLanguage language) {
      +            return IDUtils.getId(language, self);
               }
       
               @Specialization
      @@ -461,14 +463,14 @@ static Pair doNewArgsEx(VirtualFrame frame, Object getNewArgsExA
                                   @Cached SequenceStorageNodes.GetItemNode getItemNode,
                                   @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode,
                                   @Cached PyObjectSizeNode sizeNode,
      -                            @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                            @Exclusive @Cached PRaiseNode raiseNode) {
                       Object newargs = callNode.execute(frame, getNewArgsExAttr);
                       if (!tupleCheckNode.execute(inliningTarget, newargs)) {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, SHOULD_RETURN_TYPE_A_NOT_TYPE_B, T___GETNEWARGS_EX__, "tuple", newargs);
      +                    throw raiseNode.raise(inliningTarget, TypeError, SHOULD_RETURN_TYPE_A_NOT_TYPE_B, T___GETNEWARGS_EX__, "tuple", newargs);
                       }
                       int length = sizeNode.execute(frame, inliningTarget, newargs);
                       if (length != 2) {
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, SHOULD_RETURN_A_NOT_B, T___GETNEWARGS_EX__, "tuple of length 2", length);
      +                    throw raiseNode.raise(inliningTarget, ValueError, SHOULD_RETURN_A_NOT_B, T___GETNEWARGS_EX__, "tuple of length 2", length);
                       }
       
                       SequenceStorage sequenceStorage = getSequenceStorageNode.execute(inliningTarget, newargs);
      @@ -476,10 +478,10 @@ static Pair doNewArgsEx(VirtualFrame frame, Object getNewArgsExA
                       Object kwargs = getItemNode.execute(sequenceStorage, 1);
       
                       if (!tupleCheckNode.execute(inliningTarget, args)) {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, MUST_BE_TYPE_A_NOT_TYPE_B, "first item of the tuple returned by __getnewargs_ex__", "tuple", args);
      +                    throw raiseNode.raise(inliningTarget, TypeError, MUST_BE_TYPE_A_NOT_TYPE_B, "first item of the tuple returned by __getnewargs_ex__", "tuple", args);
                       }
                       if (!isDictSubClassNode.execute(inliningTarget, kwargs)) {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, MUST_BE_TYPE_A_NOT_TYPE_B, "second item of the tuple returned by __getnewargs_ex__", "dict", kwargs);
      +                    throw raiseNode.raise(inliningTarget, TypeError, MUST_BE_TYPE_A_NOT_TYPE_B, "second item of the tuple returned by __getnewargs_ex__", "dict", kwargs);
                       }
       
                       return Pair.create(args, kwargs);
      @@ -490,10 +492,10 @@ static Pair doNewArgs(VirtualFrame frame, @SuppressWarnings("unu
                                   @Bind("this") Node inliningTarget,
                                   @Exclusive @Cached CallNode callNode,
                                   @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
      -                            @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                            @Exclusive @Cached PRaiseNode raiseNode) {
                       Object args = callNode.execute(frame, getNewArgsAttr);
                       if (!tupleCheckNode.execute(inliningTarget, args)) {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, SHOULD_RETURN_TYPE_A_NOT_TYPE_B, T___GETNEWARGS__, "tuple", args);
      +                    throw raiseNode.raise(inliningTarget, TypeError, SHOULD_RETURN_TYPE_A_NOT_TYPE_B, T___GETNEWARGS__, "tuple", args);
                       }
                       return Pair.create(args, PNone.NONE);
                   }
      @@ -519,7 +521,7 @@ static Object[] getstate(VirtualFrame frame, Node inliningTarget, Object type,
                               @Cached SequenceStorageNodes.ToArrayNode toArrayNode,
                               @Cached PyImportImport importNode,
                               @Cached PyObjectCallMethodObjArgs callMethod,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object slotnames = read.execute(type, T___SLOTNAMES__);
                   boolean hadCachedSlotnames = false;
                   if (slotnames != PNone.NO_VALUE) {
      @@ -533,9 +535,9 @@ static Object[] getstate(VirtualFrame frame, Node inliningTarget, Object type,
                   } else if (slotnames == PNone.NONE) {
                       return EMPTY_OBJECT_ARRAY;
                   } else if (hadCachedSlotnames) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.COPYREG_SLOTNAMES_DIDN_T_RETURN_A_LIST_OR_NONE);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.COPYREG_SLOTNAMES_DIDN_T_RETURN_A_LIST_OR_NONE);
                   } else {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.N_SLOTNAMES_SHOULD_BE_A_LIST_OR_NONE_NOT_P, type, slotnames);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.N_SLOTNAMES_SHOULD_BE_A_LIST_OR_NONE_NOT_P, type, slotnames);
                   }
               }
           }
      @@ -556,12 +558,11 @@ static Object getstate(VirtualFrame frame, Node inliningTarget, Object obj, bool
                               @Cached PyObjectLookupAttrO lookupAttr,
                               @Cached HashingStorageSetItem setHashingStorageItem,
                               @Cached CheckBasesizeForGetState checkBasesize,
      -                        @Cached PythonObjectFactory.Lazy factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object state;
                   Object type = getClassNode.execute(inliningTarget, obj);
                   if (required && getItemsizeNode.execute(inliningTarget, type) != 0) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, CANNOT_PICKLE_OBJECT_TYPE, obj);
      +                throw raiseNode.raise(inliningTarget, TypeError, CANNOT_PICKLE_OBJECT_TYPE, obj);
                   }
       
                   Object dict = lookupAttr.execute(frame, inliningTarget, obj, T___DICT__);
      @@ -574,7 +575,7 @@ static Object getstate(VirtualFrame frame, Node inliningTarget, Object obj, bool
                   Object[] slotnames = getSlotNamesNode.execute(frame, inliningTarget, type);
       
                   if (required && !checkBasesize.execute(inliningTarget, obj, type, slotnames.length)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, CANNOT_PICKLE_OBJECT_TYPE, obj);
      +                throw raiseNode.raise(inliningTarget, TypeError, CANNOT_PICKLE_OBJECT_TYPE, obj);
                   }
       
                   if (slotnames.length > 0) {
      @@ -592,8 +593,9 @@ static Object getstate(VirtualFrame frame, Node inliningTarget, Object obj, bool
                            * If we found some slot attributes, pack them in a tuple along the original
                            * attribute dictionary.
                            */
      -                    PDict slotsState = factory.get(inliningTarget).createDict(slotsStorage);
      -                    state = factory.get(inliningTarget).createTuple(new Object[]{state, slotsState});
      +                    PythonLanguage language = PythonLanguage.get(inliningTarget);
      +                    PDict slotsState = PFactory.createDict(language, slotsStorage);
      +                    state = PFactory.createTuple(language, new Object[]{state, slotsState});
                       }
                   }
       
      @@ -662,7 +664,7 @@ abstract static class CommonReduceNode extends PNodeWithContext {
               @Specialization(guards = "proto >= 2")
               static Object reduceNewObj(VirtualFrame frame, Node inliningTarget, Object obj, @SuppressWarnings("unused") int proto,
                               @Cached GetClassNode getClassNode,
      -                        @Cached(value = "create(T___NEW__)", inline = false) LookupAttributeInMRONode lookupNew,
      +                        @Cached GetCachedTpSlotsNode getSlots,
                               @Cached PyObjectLookupAttr lookupAttr,
                               @Exclusive @Cached PyImportImport importNode,
                               @Cached InlinedConditionProfile newObjProfile,
      @@ -675,11 +677,12 @@ static Object reduceNewObj(VirtualFrame frame, Node inliningTarget, Object obj,
                               @Cached PyObjectSizeNode sizeNode,
                               @Exclusive @Cached PyObjectCallMethodObjArgs callMethod,
                               @Cached PyObjectGetIter getIter,
      -                        @Cached(inline = false) PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Bind PythonLanguage language,
      +                        @Cached PRaiseNode raiseNode) {
                   Object cls = getClassNode.execute(inliningTarget, obj);
      -            if (lookupNew.execute(cls) == PNone.NO_VALUE) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, CANNOT_PICKLE_OBJECT_TYPE, obj);
      +            TpSlots slots = getSlots.execute(inliningTarget, cls);
      +            if (slots.tp_new() == null) {
      +                throw raiseNode.raise(inliningTarget, TypeError, CANNOT_PICKLE_OBJECT_TYPE, obj);
                   }
       
                   Pair rv = getNewArgsNode.execute(frame, obj);
      @@ -703,12 +706,12 @@ static Object reduceNewObj(VirtualFrame frame, Node inliningTarget, Object obj,
                       } else {
                           newargsVals = new Object[]{cls};
                       }
      -                newargs = factory.createTuple(newargsVals);
      +                newargs = PFactory.createTuple(language, newargsVals);
                   } else if (hasArgsProfile.profile(inliningTarget, hasargs)) {
                       newobj = lookupAttr.execute(frame, inliningTarget, copyReg, T___NEWOBJ_EX__);
      -                newargs = factory.createTuple(new Object[]{cls, args, kwargs});
      +                newargs = PFactory.createTuple(language, new Object[]{cls, args, kwargs});
                   } else {
      -                throw raiseNode.get(inliningTarget).raiseBadInternalCall();
      +                throw raiseNode.raiseBadInternalCall(inliningTarget);
                   }
       
                   boolean objIsList = isSubClassNode.executeWith(frame, cls, PythonBuiltinClassType.PList);
      @@ -719,7 +722,7 @@ static Object reduceNewObj(VirtualFrame frame, Node inliningTarget, Object obj,
                   Object listitems = objIsList ? getIter.execute(frame, inliningTarget, obj) : PNone.NONE;
                   Object dictitems = objIsDict ? getIter.execute(frame, inliningTarget, callMethod.execute(frame, inliningTarget, obj, T_ITEMS)) : PNone.NONE;
       
      -            return factory.createTuple(new Object[]{newobj, newargs, state, listitems, dictitems});
      +            return PFactory.createTuple(language, new Object[]{newobj, newargs, state, listitems, dictitems});
               }
       
               @Specialization(guards = "proto < 2")
      @@ -847,7 +850,7 @@ static void doStringKey(Node inliningTarget, VirtualFrame frame, Object object,
                               @Shared @Cached(inline = false) LookupAttributeInMRONode.Dynamic getExisting,
                               @Shared @Cached(inline = false) ReadAttributeFromObjectNode attrRead,
                               @Shared @Cached InlinedBranchProfile deleteNonExistingBranchProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   setAttr(inliningTarget, frame, object, key, value, writeNode, getClassNode, hasDescriptor,
                                   getDescrSlotsNode, callSetNode, getExisting, attrRead, deleteNonExistingBranchProfile,
                                   raiseNode);
      @@ -864,18 +867,18 @@ static void doGeneric(Node inliningTarget, VirtualFrame frame, Object object, Ob
                               @Shared @Cached(inline = false) LookupAttributeInMRONode.Dynamic getExisting,
                               @Shared @Cached(inline = false) ReadAttributeFromObjectNode attrRead,
                               @Shared @Cached InlinedBranchProfile deleteNonExistingBranchProfile,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   TruffleString key = castAttributeKey(inliningTarget, keyObject, castKeyToStringNode, raiseNode);
                   setAttr(inliningTarget, frame, object, key, value, writeNode, getClassNode, hasDescriptor,
                                   getDescrSlotsNode, callSetNode, getExisting, attrRead, deleteNonExistingBranchProfile,
                                   raiseNode);
               }
       
      -        public static TruffleString castAttributeKey(Node inliningTarget, Object keyObject, CastToTruffleStringNode castKeyToStringNode, PRaiseNode.Lazy raiseNode) {
      +        public static TruffleString castAttributeKey(Node inliningTarget, Object keyObject, CastToTruffleStringNode castKeyToStringNode, PRaiseNode raiseNode) {
                   try {
                       return castKeyToStringNode.execute(inliningTarget, keyObject);
                   } catch (CannotCastException e) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ATTR_NAME_MUST_BE_STRING, keyObject);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ATTR_NAME_MUST_BE_STRING, keyObject);
                   }
               }
       
      @@ -884,7 +887,7 @@ private static void setAttr(Node inliningTarget, VirtualFrame frame, Object obje
                               InlinedConditionProfile hasDescriptor, GetObjectSlotsNode getDescrSlotsNode,
                               CallSlotDescrSet callSetNode, LookupAttributeInMRONode.Dynamic getExisting,
                               ReadAttributeFromObjectNode attrRead, InlinedBranchProfile deleteNonExistingBranchProfile,
      -                        PRaiseNode.Lazy raiseNode) {
      +                        PRaiseNode raiseNode) {
                   Object type = getClassNode.execute(inliningTarget, object);
                   Object descr = getExisting.execute(type, key);
                   if (hasDescriptor.profile(inliningTarget, !PGuards.isNoValue(descr))) {
      @@ -912,9 +915,9 @@ private static void setAttr(Node inliningTarget, VirtualFrame frame, Object obje
                   }
       
                   if (descr != PNone.NO_VALUE) {
      -                throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.ATTR_S_READONLY, key);
      +                throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.ATTR_S_READONLY, key);
                   } else {
      -                throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.HAS_NO_ATTR, object, key);
      +                throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.HAS_NO_ATTR, object, key);
                   }
               }
       
      @@ -987,18 +990,14 @@ public abstract static class RaiseAttributeErrorNode extends Node {
                   static void doIt(Object object, Object key, Object type,
                                   @Bind("this") Node inliningTarget,
                                   @Cached PRaiseNode raiseNode,
      -                            @Cached IsSubtypeNode isSubtypeNode,
      -                            @Cached TypeNodes.GetNameNode getTypeName) {
      +                            @Cached IsSubtypeNode isSubtypeNode) {
                       TruffleString message;
      -                Object firstArg;
                       if (isSubtypeNode.execute(type, PythonBuiltinClassType.PythonClass)) {
      -                    message = ErrorMessages.TYPE_S_HAS_NO_ATTR;
      -                    firstArg = getTypeName.execute(inliningTarget, object);
      +                    message = ErrorMessages.TYPE_N_HAS_NO_ATTR;
                       } else {
                           message = ErrorMessages.HAS_NO_ATTR;
      -                    firstArg = object;
                       }
      -                raiseNode.raise(PythonBuiltinClassType.AttributeError, message, firstArg, key);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, message, object, key);
                   }
               }
       
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/PythonObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/PythonObject.java
      index a0383d1ea6..b2366ab49d 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/PythonObject.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/PythonObject.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2017, 2024, Oracle and/or its affiliates.
      + * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
        * Copyright (c) 2013, Regents of the University of California
        *
        * All rights reserved.
      @@ -72,8 +72,6 @@ public class PythonObject extends PythonAbstractObject {
       
           private final Object initialPythonClass;
       
      -    private Object[] hpyData;
      -
           @SuppressWarnings("this-escape") // escapes in the assertion
           public PythonObject(Object pythonClass, Shape instanceShape) {
               super(instanceShape);
      @@ -158,12 +156,4 @@ public String toString() {
           public static int getCallSiteInlineCacheMaxDepth() {
               return PythonOptions.getCallSiteInlineCacheMaxDepth();
           }
      -
      -    public final Object[] getHPyData() {
      -        return hpyData;
      -    }
      -
      -    public final void setHPyData(Object[] hpyFields) {
      -        this.hpyData = hpyFields;
      -    }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictBuiltins.java
      index 3e04f31442..a129279d04 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictBuiltins.java
      @@ -46,13 +46,7 @@
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J_ITEMS;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J_KEYS;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J_VALUES;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IOR__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REVERSED__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SIZEOF__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T_ITEMS;
      @@ -64,9 +58,11 @@
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.ArgumentClinic;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -83,6 +79,7 @@
       import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotMpAssSubscript.MpAssSubscriptBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.RichCmpBuiltinNode;
       import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
       import com.oracle.graal.python.lib.PyObjectDelItem;
       import com.oracle.graal.python.lib.PyObjectGetItem;
      @@ -93,6 +90,7 @@
       import com.oracle.graal.python.lib.PyObjectRichCompareBool;
       import com.oracle.graal.python.lib.PyObjectSetItem;
       import com.oracle.graal.python.lib.PySequenceContainsNode;
      +import com.oracle.graal.python.lib.RichCmpOp;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.builtins.ListNodes;
      @@ -109,7 +107,7 @@
       import com.oracle.graal.python.nodes.object.GetOrCreateDictNode;
       import com.oracle.graal.python.nodes.object.SetDictNode;
       import com.oracle.graal.python.runtime.PythonContext;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      @@ -129,7 +127,6 @@
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.POrderedDict)
       public class OrderedDictBuiltins extends PythonBuiltins {
      -
           public static final TpSlots SLOTS = OrderedDictBuiltinsSlotsGen.SLOTS;
       
           @Override
      @@ -137,7 +134,8 @@ protected List> getNodeFa
               return OrderedDictBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @Slot(value = SlotKind.tp_init, isComplex = true)
      +    @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
           @Builtin(name = "update", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
           @GenerateNodeFactory
           abstract static class InitNode extends PythonBuiltinNode {
      @@ -145,12 +143,12 @@ abstract static class InitNode extends PythonBuiltinNode {
               static PNone update(VirtualFrame frame, PDict self, Object[] args, PKeyword[] kwargs,
                               @Bind("this") Node inliningTarget,
                               @Cached UpdateFromArgsNode update,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object mapping = PNone.NO_VALUE;
                   if (args.length == 1) {
                       mapping = args[0];
                   } else if (args.length > 1) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.EXPECTED_AT_MOST_D_ARGS_GOT_D, 1, args.length);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.EXPECTED_AT_MOST_D_ARGS_GOT_D, 1, args.length);
                   }
                   update.execute(frame, inliningTarget, self, mapping, kwargs);
                   return PNone.NONE;
      @@ -191,7 +189,7 @@ static void delitem(VirtualFrame frame, POrderedDict self, Object key, @Suppress
                   long hash = hashNode.execute(frame, inliningTarget, key);
                   ODictNode node = (ODictNode) removeNode.execute(frame, inliningTarget, self.nodes, key, hash);
                   if (node == null) {
      -                throw raiseNode.raise(KeyError, new Object[]{key});
      +                throw raiseNode.raise(inliningTarget, KeyError, new Object[]{key});
                   }
                   self.remove(node);
                   // TODO with hash
      @@ -270,7 +268,7 @@ static Object or(Object self, Object other) {
               }
           }
       
      -    @Builtin(name = J___IOR__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.nb_inplace_or, isComplex = true)
           @GenerateNodeFactory
           abstract static class IOrNode extends PythonBinaryBuiltinNode {
               @Specialization
      @@ -292,14 +290,14 @@ static Object reduce(VirtualFrame frame, POrderedDict self,
                               @Cached PyObjectGetStateNode getStateNode,
                               @Cached PyObjectCallMethodObjArgs callMethod,
                               @Cached PyObjectGetIter getIter,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object type = getClassNode.execute(inliningTarget, self);
                   Object state = getStateNode.execute(frame, inliningTarget, self);
      -            Object args = factory.createEmptyTuple();
      +            Object args = PFactory.createEmptyTuple(language);
                   // Might be overridden
                   Object items = callMethod.execute(frame, inliningTarget, self, T_ITEMS);
                   Object itemsIter = getIter.execute(frame, inliningTarget, items);
      -            return factory.createTuple(new Object[]{type, args, state, PNone.NONE, itemsIter});
      +            return PFactory.createTuple(language, new Object[]{type, args, state, PNone.NONE, itemsIter});
               }
           }
       
      @@ -337,7 +335,7 @@ static Object pop(VirtualFrame frame, POrderedDict self, Object key, Object defa
                               @Cached PySequenceContainsNode containsNode,
                               @Cached PyObjectGetItem getItem,
                               @Cached PyObjectDelItem delItem,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   // XXX the CPython implementation is weird when self is a subclass
                   if (containsNode.execute(frame, inliningTarget, self, key)) {
                       Object value = getItem.execute(frame, inliningTarget, self, key);
      @@ -346,7 +344,7 @@ static Object pop(VirtualFrame frame, POrderedDict self, Object key, Object defa
                   } else if (defaultValue != PNone.NO_VALUE) {
                       return defaultValue;
                   } else {
      -                throw raiseNode.get(inliningTarget).raise(KeyError, new Object[]{key});
      +                throw raiseNode.raise(inliningTarget, KeyError, new Object[]{key});
                   }
               }
           }
      @@ -360,17 +358,17 @@ static Object popitem(VirtualFrame frame, POrderedDict self, boolean last,
                               @Bind("this") Node inliningTarget,
                               @Cached HashingStorageNodes.HashingStorageDelItem delItem,
                               @Cached ObjectHashMap.RemoveNode removeNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raise) {
      +                        @Bind PythonLanguage language,
      +                        @Cached PRaiseNode raise) {
                   ODictNode node = last ? self.last : self.first;
                   if (node == null) {
      -                throw raise.get(inliningTarget).raise(KeyError, ErrorMessages.IS_EMPTY, "dictionary");
      +                throw raise.raise(inliningTarget, KeyError, ErrorMessages.IS_EMPTY, "dictionary");
                   }
                   self.remove(node);
                   removeNode.execute(frame, inliningTarget, self.nodes, node.key, node.hash);
                   // TODO with hash
                   Object value = delItem.executePop(frame, inliningTarget, self.getDictStorage(), node.key, self);
      -            return factory.createTuple(new Object[]{node.key, value});
      +            return PFactory.createTuple(language, new Object[]{node.key, value});
               }
       
               @Override
      @@ -419,13 +417,13 @@ static PNone move(VirtualFrame frame, POrderedDict self, Object key, boolean las
                               @Cached PRaiseNode raiseNode) {
                   if (self.first == null) {
                       // Empty
      -                throw raiseNode.raise(KeyError, new Object[]{key});
      +                throw raiseNode.raise(inliningTarget, KeyError, new Object[]{key});
                   }
                   if ((last ? self.last : self.first).key != key) {
                       long hash = hashNode.execute(frame, inliningTarget, key);
                       ODictNode node = (ODictNode) getNode.execute(frame, inliningTarget, self.nodes, key, hash);
                       if (node == null) {
      -                    throw raiseNode.raise(KeyError, new Object[]{key});
      +                    throw raiseNode.raise(inliningTarget, KeyError, new Object[]{key});
                       }
                       if (last) {
                           if (self.last != node) {
      @@ -453,8 +451,8 @@ protected ArgumentClinicProvider getArgumentClinic() {
           abstract static class KeysNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object keys(POrderedDict self,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createOrderedDictKeys(self);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createOrderedDictKeys(language, self);
               }
           }
       
      @@ -463,8 +461,8 @@ static Object keys(POrderedDict self,
           abstract static class ValuesNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object values(POrderedDict self,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createOrderedDictValues(self);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createOrderedDictValues(language, self);
               }
           }
       
      @@ -473,18 +471,18 @@ static Object values(POrderedDict self,
           abstract static class ItemsNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object items(POrderedDict self,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createOrderedDictItems(self);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createOrderedDictItems(language, self);
               }
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object iter(POrderedDict self,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createOrderedDictIterator(self, POrderedDictIterator.IteratorType.KEYS, false);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createOrderedDictIterator(language, self, POrderedDictIterator.IteratorType.KEYS, false);
               }
           }
       
      @@ -493,12 +491,12 @@ static Object iter(POrderedDict self,
           abstract static class ReversedNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object iter(POrderedDict self,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createOrderedDictIterator(self, POrderedDictIterator.IteratorType.KEYS, true);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createOrderedDictIterator(language, self, POrderedDictIterator.IteratorType.KEYS, true);
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -545,7 +543,7 @@ abstract static class EqHelperNode extends Node {
               @Specialization
               static boolean cmp(VirtualFrame frame, Node inliningTarget, POrderedDict self, POrderedDict other,
                               @Cached HashingStorageNodes.HashingStorageGetItemWithHash getItem,
      -                        @Cached PyObjectRichCompareBool.EqNode eqNode) {
      +                        @Cached PyObjectRichCompareBool eqNode) {
                   ODictNode lnode = self.first;
                   ODictNode rnode = other.first;
                   do {
      @@ -555,12 +553,12 @@ static boolean cmp(VirtualFrame frame, Node inliningTarget, POrderedDict self, P
                       if (lnode == null || rnode == null) {
                           return false;
                       }
      -                if (!eqNode.compare(frame, inliningTarget, lnode.key, rnode.key)) {
      +                if (!eqNode.executeEq(frame, inliningTarget, lnode.key, rnode.key)) {
                           return false;
                       }
                       Object lvalue = getItem.execute(frame, inliningTarget, self.getDictStorage(), lnode.key, lnode.hash);
                       Object rvalue = getItem.execute(frame, inliningTarget, other.getDictStorage(), rnode.key, rnode.hash);
      -                if (!eqNode.compare(frame, inliningTarget, lvalue, rvalue)) {
      +                if (!eqNode.executeEq(frame, inliningTarget, lvalue, rvalue)) {
                           return false;
                       }
                       lnode = lnode.next;
      @@ -575,36 +573,19 @@ static boolean cmp(VirtualFrame frame, Node inliningTarget, POrderedDict self, P
               }
           }
       
      -    @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.tp_richcompare, isComplex = true)
           @GenerateNodeFactory
      -    abstract static class EqNode extends PythonBinaryBuiltinNode {
      -        @Specialization
      -        static boolean cmp(VirtualFrame frame, POrderedDict self, PDict other,
      +    abstract static class EqNode extends RichCmpBuiltinNode {
      +        @Specialization(guards = "op.isEqOrNe()")
      +        static boolean cmp(VirtualFrame frame, POrderedDict self, PDict other, RichCmpOp op,
                               @Bind("this") Node inliningTarget,
                               @Cached EqHelperNode eqHelperNode) {
      -            return eqHelperNode.execute(frame, inliningTarget, self, other);
      +            return eqHelperNode.execute(frame, inliningTarget, self, other) == op.isEq();
               }
       
               @Fallback
               @SuppressWarnings("unused")
      -        static Object cmp(Object self, Object other) {
      -            return PNotImplemented.NOT_IMPLEMENTED;
      -        }
      -    }
      -
      -    @Builtin(name = J___NE__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    abstract static class NeNode extends PythonBinaryBuiltinNode {
      -        @Specialization
      -        static boolean cmp(VirtualFrame frame, POrderedDict self, PDict other,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached EqHelperNode eqHelperNode) {
      -            return !eqHelperNode.execute(frame, inliningTarget, self, other);
      -        }
      -
      -        @Fallback
      -        @SuppressWarnings("unused")
      -        static Object cmp(Object self, Object other) {
      +        static Object cmp(Object self, Object other, RichCmpOp op) {
                   return PNotImplemented.NOT_IMPLEMENTED;
               }
           }
      @@ -629,8 +610,8 @@ static Object dict(Object self, @SuppressWarnings("unused") PNone mapping,
       
               @Specialization(guards = {"!isNoValue(mapping)", "!isDict(mapping)"})
               static PNone dict(@SuppressWarnings("unused") Object self, Object mapping,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, mapping);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, mapping);
               }
           }
       
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictItemsBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictItemsBuiltins.java
      index e789b2024d..51eb883711 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictItemsBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictItemsBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,38 +40,44 @@
        */
       package com.oracle.graal.python.builtins.objects.ordereddict;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REVERSED__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictItemsView;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      -import com.oracle.truffle.api.dsl.Cached;
      +import com.oracle.graal.python.runtime.object.PFactory;
      +import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.POrderedDictItems)
       public class OrderedDictItemsBuiltins extends PythonBuiltins {
      +
      +    public static final TpSlots SLOTS = OrderedDictItemsBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return OrderedDictItemsBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object iter(PDictItemsView self,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createOrderedDictIterator((POrderedDict) self.getWrappedDict(), POrderedDictIterator.IteratorType.ITEMS, false);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createOrderedDictIterator(language, (POrderedDict) self.getWrappedDict(), POrderedDictIterator.IteratorType.ITEMS, false);
               }
           }
       
      @@ -80,8 +86,8 @@ static Object iter(PDictItemsView self,
           abstract static class ReversedNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object iter(PDictItemsView self,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createOrderedDictIterator((POrderedDict) self.getWrappedDict(), POrderedDictIterator.IteratorType.ITEMS, true);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createOrderedDictIterator(language, (POrderedDict) self.getWrappedDict(), POrderedDictIterator.IteratorType.ITEMS, true);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictIteratorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictIteratorBuiltins.java
      index 0ea2b63941..6cabab4c6f 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictIteratorBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictIteratorBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -42,14 +42,14 @@
       
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.KeyError;
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.RuntimeError;
      -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.StopIteration;
       import static com.oracle.graal.python.nodes.BuiltinNames.T_ITER;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -57,6 +57,8 @@
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes;
       import com.oracle.graal.python.builtins.objects.list.PList;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
       import com.oracle.graal.python.lib.PyObjectGetAttr;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
      @@ -64,7 +66,7 @@
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.runtime.PythonContext;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -75,12 +77,15 @@
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.POrderedDictIterator)
       public class OrderedDictIteratorBuiltins extends PythonBuiltins {
      +
      +    public static final TpSlots SLOTS = OrderedDictIteratorBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return OrderedDictIteratorBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -89,20 +94,19 @@ static Object iter(POrderedDictIterator self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization
               static Object next(VirtualFrame frame, POrderedDictIterator self,
                               @Bind("this") Node inliningTarget,
                               @Cached PRaiseNode raiseNode,
      -                        @Cached HashingStorageNodes.HashingStorageGetItemWithHash getItem,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Cached HashingStorageNodes.HashingStorageGetItemWithHash getItem) {
                   if (self.current == null) {
      -                throw raiseNode.raise(StopIteration);
      +                throw iteratorExhausted();
                   }
                   if (self.size != self.dict.nodes.size()) {
      -                throw raiseNode.raise(RuntimeError, ErrorMessages.CHANGED_SIZE_DURING_ITERATION, "OrderedDict");
      +                throw raiseNode.raise(inliningTarget, RuntimeError, ErrorMessages.CHANGED_SIZE_DURING_ITERATION, "OrderedDict");
                   }
                   Object result;
                   Object key = self.current.key;
      @@ -111,12 +115,12 @@ static Object next(VirtualFrame frame, POrderedDictIterator self,
                   } else {
                       Object value = getItem.execute(frame, inliningTarget, self.dict.getDictStorage(), key, self.current.hash);
                       if (value == null) {
      -                    throw raiseNode.raise(KeyError, new Object[]{key});
      +                    throw raiseNode.raise(inliningTarget, KeyError, new Object[]{key});
                       }
                       if (self.type == POrderedDictIterator.IteratorType.VALUES) {
                           result = value;
                       } else {
      -                    result = factory.createTuple(new Object[]{key, value});
      +                    result = PFactory.createTuple(PythonLanguage.get(inliningTarget), new Object[]{key, value});
                       }
                   }
                   if (!self.reversed) {
      @@ -135,16 +139,16 @@ abstract static class ReduceNode extends PythonUnaryBuiltinNode {
               static Object reduce(VirtualFrame frame, POrderedDictIterator self,
                               @Bind("this") Node inliningTarget,
                               @Cached PyObjectGetAttr getAttr,
      -                        @Cached PythonObjectFactory factory,
      +                        @Bind PythonLanguage language,
                               @Cached ListNodes.ConstructListNode constructListNode) {
                   PythonContext context = PythonContext.get(inliningTarget);
                   Object iterBuiltin = getAttr.execute(frame, inliningTarget, context.getBuiltins(), T_ITER);
      -            POrderedDictIterator copy = factory.createOrderedDictIterator(self.dict, self.type, self.reversed);
      +            POrderedDictIterator copy = PFactory.createOrderedDictIterator(language, self.dict, self.type, self.reversed);
                   copy.current = self.current;
                   /* iterate the temporary into a list */
                   PList list = constructListNode.execute(frame, copy);
      -            PTuple args = factory.createTuple(new Object[]{list});
      -            return factory.createTuple(new Object[]{iterBuiltin, args});
      +            PTuple args = PFactory.createTuple(language, new Object[]{list});
      +            return PFactory.createTuple(language, new Object[]{iterBuiltin, args});
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictKeysBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictKeysBuiltins.java
      index b394891511..be0eb506e2 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictKeysBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictKeysBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,38 +40,44 @@
        */
       package com.oracle.graal.python.builtins.objects.ordereddict;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REVERSED__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictKeysView;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      -import com.oracle.truffle.api.dsl.Cached;
      +import com.oracle.graal.python.runtime.object.PFactory;
      +import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.POrderedDictKeys)
       public class OrderedDictKeysBuiltins extends PythonBuiltins {
      +
      +    public static final TpSlots SLOTS = OrderedDictKeysBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return OrderedDictKeysBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object iter(PDictKeysView self,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createOrderedDictIterator((POrderedDict) self.getWrappedDict(), POrderedDictIterator.IteratorType.KEYS, false);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createOrderedDictIterator(language, (POrderedDict) self.getWrappedDict(), POrderedDictIterator.IteratorType.KEYS, false);
               }
           }
       
      @@ -80,8 +86,8 @@ static Object iter(PDictKeysView self,
           abstract static class ReversedNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object iter(PDictKeysView self,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createOrderedDictIterator((POrderedDict) self.getWrappedDict(), POrderedDictIterator.IteratorType.KEYS, true);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createOrderedDictIterator(language, (POrderedDict) self.getWrappedDict(), POrderedDictIterator.IteratorType.KEYS, true);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictValuesBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictValuesBuiltins.java
      index 66b74ea5b8..8c5699fa6e 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictValuesBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ordereddict/OrderedDictValuesBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,38 +40,44 @@
        */
       package com.oracle.graal.python.builtins.objects.ordereddict;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REVERSED__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictValuesView;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      -import com.oracle.truffle.api.dsl.Cached;
      +import com.oracle.graal.python.runtime.object.PFactory;
      +import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.POrderedDictValues)
       public class OrderedDictValuesBuiltins extends PythonBuiltins {
      +
      +    public static final TpSlots SLOTS = OrderedDictValuesBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return OrderedDictValuesBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object iter(PDictValuesView self,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createOrderedDictIterator((POrderedDict) self.getWrappedDict(), POrderedDictIterator.IteratorType.VALUES, false);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createOrderedDictIterator(language, (POrderedDict) self.getWrappedDict(), POrderedDictIterator.IteratorType.VALUES, false);
               }
           }
       
      @@ -80,8 +86,8 @@ static Object iter(PDictValuesView self,
           abstract static class ReversedNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object iter(PDictValuesView self,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createOrderedDictIterator((POrderedDict) self.getWrappedDict(), POrderedDictIterator.IteratorType.VALUES, true);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createOrderedDictIterator(language, (POrderedDict) self.getWrappedDict(), POrderedDictIterator.IteratorType.VALUES, true);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/DirEntryBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/DirEntryBuiltins.java
      index a82890023e..ab0bc89d7c 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/DirEntryBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/DirEntryBuiltins.java
      @@ -43,7 +43,6 @@
       import static com.oracle.graal.python.builtins.modules.PosixModuleBuiltins.opaquePathToBytes;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___FSPATH__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.runtime.PosixConstants.AT_FDCWD;
       import static com.oracle.graal.python.runtime.PosixConstants.DT_DIR;
       import static com.oracle.graal.python.runtime.PosixConstants.DT_LNK;
      @@ -56,8 +55,11 @@
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.ArgumentClinic;
       import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -69,18 +71,19 @@
       import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
       import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
      -import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
      -import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
       import com.oracle.graal.python.runtime.PosixSupport;
       import com.oracle.graal.python.runtime.PosixSupportLibrary;
       import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.PythonContext;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Cached.Shared;
      @@ -99,6 +102,8 @@
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PDirEntry)
       public final class DirEntryBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = DirEntryBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return DirEntryBuiltinsFactory.getFactories();
      @@ -108,17 +113,17 @@ protected List> getNodeFa
           @GenerateNodeFactory
           abstract static class NameNode extends PythonUnaryBuiltinNode {
               @Specialization
      -        Object nameAsBytes(VirtualFrame frame, PDirEntry self,
      +        static Object nameAsBytes(VirtualFrame frame, PDirEntry self,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached InlinedConditionProfile produceBytesProfile,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      -                        @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
                   try {
                       if (produceBytesProfile.profile(inliningTarget, self.produceBytes())) {
      -                    return opaquePathToBytes(posixLib.dirEntryGetName(getPosixSupport(), self.dirEntryData), posixLib, getPosixSupport(), factory);
      +                    return opaquePathToBytes(posixLib.dirEntryGetName(context.getPosixSupport(), self.dirEntryData), posixLib, context.getPosixSupport(), context.getLanguage(inliningTarget));
                       } else {
      -                    return posixLib.getPathAsString(getPosixSupport(), posixLib.dirEntryGetName(getPosixSupport(), self.dirEntryData));
      +                    return posixLib.getPathAsString(context.getPosixSupport(), posixLib.dirEntryGetName(context.getPosixSupport(), self.dirEntryData));
                       }
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
      @@ -126,17 +131,16 @@ Object nameAsBytes(VirtualFrame frame, PDirEntry self,
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
               @Specialization
               static TruffleString repr(VirtualFrame frame, PDirEntry self,
                               @Bind("this") Node inliningTarget,
                               @Cached NameNode nameNode,
      -                        @Cached("create(Repr)") LookupAndCallUnaryNode reprNode,
      -                        @Cached CastToTruffleStringNode castToStringNode,
      +                        @Cached PyObjectReprAsTruffleStringNode repr,
                               @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode) {
      -            return simpleTruffleStringFormatNode.format("", castToStringNode.execute(inliningTarget, reprNode.executeObject(frame, nameNode.execute(frame, self))));
      +            return simpleTruffleStringFormatNode.format("", repr.execute(frame, inliningTarget, nameNode.execute(frame, self)));
               }
           }
       
      @@ -153,25 +157,25 @@ static PosixPath cached(PDirEntry self) {
       
               @Specialization(guards = "self.pathCache == null")
               static PosixPath createBytes(VirtualFrame frame, Node inliningTarget, PDirEntry self,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached InlinedConditionProfile produceBytesProfile,
                               @Cached InlinedConditionProfile posixPathProfile,
      -                        @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
      -                        @Cached PythonObjectFactory.Lazy factory,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
                   Object opaquePath;
                   try {
                       if (posixPathProfile.profile(inliningTarget, self.scandirPath instanceof PosixPath)) {
      -                    opaquePath = posixLib.dirEntryGetPath(PosixSupport.get(inliningTarget), self.dirEntryData, ((PosixPath) self.scandirPath).value);
      +                    opaquePath = posixLib.dirEntryGetPath(context.getPosixSupport(), self.dirEntryData, ((PosixPath) self.scandirPath).value);
                       } else {
      -                    opaquePath = posixLib.dirEntryGetName(PosixSupport.get(inliningTarget), self.dirEntryData);
      +                    opaquePath = posixLib.dirEntryGetName(context.getPosixSupport(), self.dirEntryData);
                       }
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
                   }
                   if (produceBytesProfile.profile(inliningTarget, self.produceBytes())) {
      -                self.pathCache = new PosixPath(opaquePathToBytes(opaquePath, posixLib, PosixSupport.get(inliningTarget), factory.get(inliningTarget)), opaquePath, true);
      +                self.pathCache = new PosixPath(opaquePathToBytes(opaquePath, posixLib, context.getPosixSupport(), context.getLanguage(inliningTarget)), opaquePath, true);
                   } else {
      -                self.pathCache = new PosixPath(posixLib.getPathAsString(PosixSupport.get(inliningTarget), opaquePath), opaquePath, false);
      +                self.pathCache = new PosixPath(posixLib.getPathAsString(context.getPosixSupport(), opaquePath), opaquePath, false);
                   }
                   return self.pathCache;
               }
      @@ -214,7 +218,7 @@ long inode(VirtualFrame frame, PDirEntry self,
               }
           }
       
      -    @Builtin(name = "stat", minNumOfPositionalArgs = 1, parameterNames = {"$self"}, varArgsMarker = true, keywordOnlyNames = {
      +    @Builtin(name = "stat", minNumOfPositionalArgs = 1, parameterNames = {"$self"}, keywordOnlyNames = {
                           "follow_symlinks"}, doc = "return stat_result object for the entry; cached per entry")
           @ArgumentClinic(name = "follow_symlinks", conversion = ClinicConversion.Boolean, defaultValue = "true")
           @GenerateNodeFactory
      @@ -252,32 +256,32 @@ static PTuple cachedLStat(PDirEntry self, boolean followSymlinks, boolean catchN
               @Specialization(guards = {"followSymlinks", "self.statCache == null", "isSymlink"}, limit = "1")
               static PTuple uncachedStatWithSymlink(VirtualFrame frame, PDirEntry self, boolean followSymlinks, boolean catchNoent,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @SuppressWarnings("unused") @Cached IsSymlinkNode isSymlinkNode,
                               @SuppressWarnings("unused") @Bind("isSymlinkNode.executeBoolean(frame, self)") boolean isSymlink,
      -                        @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
                               @Shared("cachedPosixPathNode") @Cached CachedPosixPathNode cachedPosixPathNode,
                               @Shared("positiveLongProfile") @Cached InlinedConditionProfile positiveLongProfile,
      -                        @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
                   // There are two caches - one for `follow_symlinks=True` and the other for
                   // 'follow_symlinks=False`. They are different only when the dir entry is a symlink.
      -            return uncachedLStatWithSymlink(frame, self, followSymlinks, catchNoent, inliningTarget, posixLib, cachedPosixPathNode, positiveLongProfile, constructAndRaiseNode, factory);
      +            return uncachedLStatWithSymlink(frame, self, followSymlinks, catchNoent, inliningTarget, context, posixLib, cachedPosixPathNode, positiveLongProfile, constructAndRaiseNode);
               }
       
               @Specialization(guards = {"!followSymlinks", "self.lstatCache == null"})
               static PTuple uncachedLStatWithSymlink(VirtualFrame frame, PDirEntry self, boolean followSymlinks, boolean catchNoent,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Shared("cachedPosixPathNode") @Cached CachedPosixPathNode cachedPosixPathNode,
                               @Shared("positiveLongProfile") @Cached InlinedConditionProfile positiveLongProfile,
      -                        @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
                   PTuple res;
                   int dirFd = self.scandirPath instanceof PosixFd ? ((PosixFd) self.scandirPath).fd : AT_FDCWD.value;
                   PosixPath posixPath = cachedPosixPathNode.execute(frame, inliningTarget, self);
                   try {
      -                long[] rawStat = posixLib.fstatat(PosixSupport.get(inliningTarget), dirFd, posixPath.value, followSymlinks);
      -                res = PosixModuleBuiltins.createStatResult(inliningTarget, factory, positiveLongProfile, rawStat);
      +                long[] rawStat = posixLib.fstatat(context.getPosixSupport(), dirFd, posixPath.value, followSymlinks);
      +                res = PosixModuleBuiltins.createStatResult(inliningTarget, context.getLanguage(inliningTarget), positiveLongProfile, rawStat);
                   } catch (PosixException e) {
                       if (catchNoent && e.getErrorCode() == OSErrorEnum.ENOENT.getNumber()) {
                           return null;
      @@ -384,7 +388,7 @@ static boolean isSymlink(VirtualFrame frame, PDirEntry self,
               }
           }
       
      -    @Builtin(name = "is_file", minNumOfPositionalArgs = 1, parameterNames = {"$self"}, varArgsMarker = true, keywordOnlyNames = {"follow_symlinks"})
      +    @Builtin(name = "is_file", minNumOfPositionalArgs = 1, parameterNames = {"$self"}, keywordOnlyNames = {"follow_symlinks"})
           @ArgumentClinic(name = "follow_symlinks", conversion = ClinicConversion.Boolean, defaultValue = "true")
           @GenerateNodeFactory
           abstract static class IsFileNode extends PythonClinicBuiltinNode {
      @@ -401,7 +405,7 @@ static boolean isFile(VirtualFrame frame, PDirEntry self, boolean followSymlinks
               }
           }
       
      -    @Builtin(name = "is_dir", minNumOfPositionalArgs = 1, parameterNames = {"$self"}, varArgsMarker = true, keywordOnlyNames = {"follow_symlinks"})
      +    @Builtin(name = "is_dir", minNumOfPositionalArgs = 1, parameterNames = {"$self"}, keywordOnlyNames = {"follow_symlinks"})
           @ArgumentClinic(name = "follow_symlinks", conversion = ClinicConversion.Boolean, defaultValue = "true")
           @GenerateNodeFactory
           abstract static class IsDirNode extends PythonClinicBuiltinNode {
      @@ -423,8 +427,8 @@ static boolean isDir(VirtualFrame frame, PDirEntry self, boolean followSymlinks,
           public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode {
               @Specialization
               static Object classGetItem(Object cls, Object key,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createGenericAlias(cls, key);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createGenericAlias(language, cls, key);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/ScandirIteratorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/ScandirIteratorBuiltins.java
      index 89ba012a09..2cc289f1ed 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/ScandirIteratorBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/ScandirIteratorBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -42,19 +42,20 @@
       
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ENTER__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EXIT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       
       import java.util.List;
       
       import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
       import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
      -import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      @@ -63,7 +64,7 @@
       import com.oracle.graal.python.runtime.PosixSupportLibrary;
       import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException;
       import com.oracle.graal.python.runtime.PythonContext;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CallTarget;
       import com.oracle.truffle.api.TruffleLanguage;
       import com.oracle.truffle.api.dsl.Bind;
      @@ -79,6 +80,8 @@
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PScandirIterator)
       public final class ScandirIteratorBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = ScandirIteratorBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return ScandirIteratorBuiltinsFactory.getFactories();
      @@ -95,7 +98,7 @@ PNone close(PScandirIterator self,
               }
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -104,27 +107,26 @@ PScandirIterator iter(PScandirIterator self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization
      -        static PDirEntry next(VirtualFrame frame, PScandirIterator self,
      +        static Object next(VirtualFrame frame, PScandirIterator self,
                               @Bind("this") Node inliningTarget,
                               @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Bind PythonLanguage language) {
                   if (self.ref.isReleased()) {
      -                throw raiseNode.get(inliningTarget).raiseStopIteration();
      +                throw iteratorExhausted();
                   }
                   PosixSupport posixSupport = PosixSupport.get(inliningTarget);
                   try {
                       Object dirEntryData = posixLib.readdir(posixSupport, self.ref.getReference());
                       if (dirEntryData == null) {
                           self.ref.rewindAndClose(posixLib, posixSupport);
      -                    throw raiseNode.get(inliningTarget).raiseStopIteration();
      +                    throw iteratorExhausted();
                       }
      -                return factory.createDirEntry(dirEntryData, self.path);
      +                return PFactory.createDirEntry(language, dirEntryData, self.path);
                   } catch (PosixException e) {
                       self.ref.rewindAndClose(posixLib, posixSupport);
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/property/PropertyBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/property/PropertyBuiltins.java
      index 488d1eef29..cfb7c5d4e6 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/property/PropertyBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/property/PropertyBuiltins.java
      @@ -41,22 +41,25 @@
       package com.oracle.graal.python.builtins.objects.property;
       
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.AttributeError;
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_PROPERTY;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___DOC__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ISABSTRACTMETHOD__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SET_NAME__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ISABSTRACTMETHOD__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.DescrGetBuiltinNode;
      @@ -76,12 +79,13 @@
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassExactProfile;
       import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassProfile;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
       import com.oracle.truffle.api.dsl.Bind;
      @@ -106,7 +110,20 @@ protected List> getNodeFa
               return PropertyBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___INIT__, parameterNames = {"$self", "fget", "fset", "fdel", "doc"})
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = J_PROPERTY, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class PropertyNode extends PythonVarargsBuiltinNode {
      +        @Specialization
      +        static PProperty doit(Object cls, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") PKeyword[] keywords,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createProperty(language, cls, getInstanceShape.execute(cls));
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_init, isComplex = true)
      +    @SlotSignature(name = "property", parameterNames = {"$self", "fget", "fset", "fdel", "doc"})
           @GenerateNodeFactory
           abstract static class PropertyInitNode extends PythonBuiltinNode {
       
      @@ -156,7 +173,7 @@ abstract static class PropertyFuncNode extends PythonBinaryBuiltinNode {
               @Specialization(guards = "!isNoValue(value)")
               @SuppressWarnings("unused")
               static Object doSet(PProperty self, Object value,
      -                        @Cached PRaiseNode raiseNode) {
      +                        @Bind("this") Node inliningTarget) {
                   /*
                    * That's a bit unfortunate: if we define 'isGetter = true' and 'isSetter = false' then
                    * this will use a GetSetDescriptor which has a slightly different error message for
      @@ -164,7 +181,7 @@ static Object doSet(PProperty self, Object value,
                    * with expected message. This should be fixed by distinguishing between getset and
                    * member descriptors.
                    */
      -            throw raiseNode.raise(PythonBuiltinClassType.AttributeError, ErrorMessages.READONLY_ATTRIBUTE);
      +            throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.READONLY_ATTRIBUTE);
               }
           }
       
      @@ -256,7 +273,7 @@ static Object copy(PProperty pold, Object getArg, Object setArg, Object delArg)
       
                   // shortcut: create new property object directly
                   if (IsBuiltinClassProfile.profileClassSlowPath(type, PythonBuiltinClassType.PProperty)) {
      -                PProperty copy = PythonObjectFactory.getUncached().createProperty();
      +                PProperty copy = PFactory.createProperty(PythonLanguage.get(null));
                       PropertyInitNode.doGeneric(copy, get, set, del, doc);
                       return copy;
                   }
      @@ -313,9 +330,9 @@ PException error(VirtualFrame frame, PProperty self, Object obj, String what,
                   TruffleString qualName = getQualNameNode.execute(inliningTarget, getClassNode.execute(inliningTarget, obj));
                   if (self.getPropertyName() != null) {
                       TruffleString propertyName = reprNode.execute(frame, inliningTarget, self.getPropertyName());
      -                throw raiseNode.raise(AttributeError, ErrorMessages.PROPERTY_S_OF_S_OBJECT_HAS_NO_S, propertyName, qualName, what);
      +                throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.PROPERTY_S_OF_S_OBJECT_HAS_NO_S, propertyName, qualName, what);
                   } else {
      -                throw raiseNode.raise(AttributeError, ErrorMessages.PROPERTY_OF_S_OBJECT_HAS_NO_S, qualName, what);
      +                throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.PROPERTY_OF_S_OBJECT_HAS_NO_S, qualName, what);
                   }
               }
           }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/queue/SimpleQueueBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/queue/SimpleQueueBuiltins.java
      index a149c1b169..9ab1d24d08 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/queue/SimpleQueueBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/queue/SimpleQueueBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -43,18 +43,25 @@
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.Empty;
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.OverflowError;
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError;
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_SIMPLE_QUEUE;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.ArgumentClinic;
       import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.queue.SimpleQueueBuiltinsClinicProviders.SimpleQueueGetNodeClinicProviderGen;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.lib.PyLongAsLongAndOverflowNode;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
      @@ -67,7 +74,7 @@
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToJavaDoubleNode;
       import com.oracle.graal.python.runtime.GilNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.OverflowException;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.truffle.api.CompilerDirectives;
      @@ -84,11 +91,26 @@
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PSimpleQueue)
       public final class SimpleQueueBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = SimpleQueueBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return SimpleQueueBuiltinsFactory.getFactories();
           }
       
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = J_SIMPLE_QUEUE, minNumOfPositionalArgs = 1)
      +    @GenerateNodeFactory
      +    public abstract static class SimpleQueueNode extends PythonUnaryBuiltinNode {
      +
      +        @Specialization
      +        static PSimpleQueue doGeneric(Object cls,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createSimpleQueue(language, cls, getInstanceShape.execute(cls));
      +        }
      +    }
      +
           @Builtin(name = "empty", minNumOfPositionalArgs = 1, //
                           doc = "empty($self, /)\n--\n\nReturn True if the queue is empty, False otherwise (not reliable!).")
           @GenerateNodeFactory
      @@ -127,12 +149,12 @@ public abstract static class SimpleQueueGetNoWaitNode extends PythonUnaryBuiltin
               @Specialization
               static Object doNoTimeout(PSimpleQueue self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object result = self.poll();
                   if (result != null) {
                       return result;
                   }
      -            throw raiseNode.get(inliningTarget).raise(Empty);
      +            throw raiseNode.raise(inliningTarget, Empty);
               }
           }
       
      @@ -164,7 +186,7 @@ protected ArgumentClinicProvider getArgumentClinic() {
               static Object doNoTimeout(PSimpleQueue self, boolean block, @SuppressWarnings("unused") Object timeout,
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached GilNode gil,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   // CPython first tries a non-blocking get without releasing the GIL
                   Object result = self.poll();
                   if (result != null) {
      @@ -182,7 +204,7 @@ static Object doNoTimeout(PSimpleQueue self, boolean block, @SuppressWarnings("u
                           gil.acquire();
                       }
                   }
      -            throw raiseNode.get(inliningTarget).raise(Empty);
      +            throw raiseNode.raise(inliningTarget, Empty);
               }
       
               @Specialization(guards = "withTimeout(block, timeout)")
      @@ -191,7 +213,7 @@ static Object doTimeout(VirtualFrame frame, PSimpleQueue self, boolean block, Ob
                               @Cached PyLongAsLongAndOverflowNode asLongNode,
                               @Cached CastToJavaDoubleNode castToDouble,
                               @Shared @Cached GilNode gil,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   assert block;
       
                   // convert timeout object (given in seconds) to a Java long in microseconds
      @@ -202,12 +224,12 @@ static Object doTimeout(VirtualFrame frame, PSimpleQueue self, boolean block, Ob
                       try {
                           ltimeout = PythonUtils.multiplyExact(asLongNode.execute(frame, inliningTarget, timeout), 1000000);
                       } catch (OverflowException oe) {
      -                    throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.TIMEOUT_VALUE_TOO_LARGE);
      +                    throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.TIMEOUT_VALUE_TOO_LARGE);
                       }
                   }
       
                   if (ltimeout < 0) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.TIMEOUT_MUST_BE_NON_NEG_NUM);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.TIMEOUT_MUST_BE_NON_NEG_NUM);
                   }
       
                   // CPython first tries a non-blocking get without releasing the GIL
      @@ -228,7 +250,7 @@ static Object doTimeout(VirtualFrame frame, PSimpleQueue self, boolean block, Ob
                   } finally {
                       gil.acquire();
                   }
      -            throw raiseNode.get(inliningTarget).raise(Empty);
      +            throw raiseNode.raise(inliningTarget, Empty);
               }
       
               static boolean withTimeout(boolean block, Object timeout) {
      @@ -252,13 +274,13 @@ public abstract static class SimpleQueuePutNode extends PythonQuaternaryBuiltinN
               @Specialization
               static PNone doGeneric(PSimpleQueue self, Object item, @SuppressWarnings("unused") Object block, @SuppressWarnings("unused") Object timeout,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (!self.put(item)) {
                       /*
                        * CPython uses a Python list as backing storage. This will throw an OverflowError
                        * if no more elements can be added to the list.
                        */
      -                throw raiseNode.get(inliningTarget).raise(OverflowError);
      +                throw raiseNode.raise(inliningTarget, OverflowError);
                   }
                   return PNone.NONE;
               }
      @@ -277,13 +299,13 @@ public abstract static class SimpleQueuePutNoWaitNode extends PythonBinaryBuilti
               @Specialization
               static PNone doGeneric(PSimpleQueue self, Object item,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (!self.put(item)) {
                       /*
                        * CPython uses a Python list as backing storage. This will throw an OverflowError
                        * if no more elements can be added to the list.
                        */
      -                throw raiseNode.get(inliningTarget).raise(OverflowError);
      +                throw raiseNode.raise(inliningTarget, OverflowError);
                   }
                   return PNone.NONE;
               }
      @@ -294,8 +316,8 @@ static PNone doGeneric(PSimpleQueue self, Object item,
           public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode {
               @Specialization
               static Object classGetItem(Object cls, Object key,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createGenericAlias(cls, key);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createGenericAlias(language, cls, key);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java
      index f17d91e9e0..173bfee093 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -42,6 +42,7 @@
       
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
      +import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
       
       import java.math.BigInteger;
       import java.nio.ByteBuffer;
      @@ -49,8 +50,12 @@
       import java.security.SecureRandom;
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.ArgumentClinic;
       import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -59,17 +64,22 @@
       import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetObjectArrayNode;
       import com.oracle.graal.python.builtins.objects.ints.PInt;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.lib.PyObjectHashNode;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
      +import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
      +import com.oracle.graal.python.nodes.call.special.SpecialMethodNotFound;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
      -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
      +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes;
       import com.oracle.graal.python.nodes.util.CastToJavaUnsignedLongNode;
       import com.oracle.graal.python.runtime.exception.PythonErrorType;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
      +import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      @@ -80,17 +90,45 @@
       import com.oracle.truffle.api.dsl.TypeSystemReference;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.strings.TruffleString;
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PRandom)
       public final class RandomBuiltins extends PythonBuiltins {
      +
      +    public static final TpSlots SLOTS = RandomBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return RandomBuiltinsFactory.getFactories();
           }
       
      +    // _random.Random([seed])
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "Random", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    abstract static class PRandomNode extends PythonBuiltinNode {
      +        private static final TruffleString T_SEED = tsLiteral("seed");
      +
      +        @Child LookupAndCallBinaryNode setSeed = LookupAndCallBinaryNode.create(T_SEED);
      +
      +        @Specialization
      +        PRandom random(VirtualFrame frame, Object cls, Object seed,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            PRandom random = PFactory.createRandom(language, cls, getInstanceShape.execute(cls));
      +            try {
      +                setSeed.executeObject(frame, random, seed != PNone.NO_VALUE ? seed : PNone.NONE);
      +            } catch (SpecialMethodNotFound ignore) {
      +                CompilerDirectives.transferToInterpreterAndInvalidate();
      +                throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.SystemError);
      +            }
      +            return random;
      +        }
      +    }
      +
           @Builtin(name = "seed", minNumOfPositionalArgs = 1, parameterNames = {"$self", "seed"})
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      +    @TypeSystemReference(PythonIntegerTypes.class)
           public abstract static class SeedNode extends PythonBuiltinNode {
               @Specialization
               @TruffleBoundary
      @@ -159,10 +197,10 @@ static PNone setstate(PRandom random, PTuple tuple,
                               @Bind("this") Node inliningTarget,
                               @Cached GetObjectArrayNode getObjectArrayNode,
                               @Cached CastToJavaUnsignedLongNode castNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object[] arr = getObjectArrayNode.execute(inliningTarget, tuple);
                   if (arr.length != PRandom.N + 1) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.STATE_VECTOR_INVALID);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.STATE_VECTOR_INVALID);
                   }
                   int[] state = new int[PRandom.N];
                   for (int i = 0; i < PRandom.N; ++i) {
      @@ -171,7 +209,7 @@ static PNone setstate(PRandom random, PTuple tuple,
                   }
                   long index = castNode.execute(inliningTarget, arr[PRandom.N]);
                   if (index < 0 || index > PRandom.N) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.STATE_VECTOR_INVALID);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.STATE_VECTOR_INVALID);
                   }
                   random.restore(state, (int) index);
                   return PNone.NONE;
      @@ -180,8 +218,8 @@ static PNone setstate(PRandom random, PTuple tuple,
               @Fallback
               @SuppressWarnings("unused")
               static Object setstate(Object random, Object state,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.STATE_VECTOR_MUST_BE_A_TUPLE);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.STATE_VECTOR_MUST_BE_A_TUPLE);
               }
           }
       
      @@ -191,8 +229,8 @@ public abstract static class GetStateNode extends PythonBuiltinNode {
       
               @Specialization
               static PTuple getstate(PRandom random,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createTuple(encodeState(random));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createTuple(language, encodeState(random));
               }
       
               @TruffleBoundary
      @@ -235,8 +273,8 @@ protected ArgumentClinicProvider getArgumentClinic() {
               @Specialization(guards = "k < 0")
               @SuppressWarnings("unused")
               static int negative(PRandom random, int k,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(ValueError, ErrorMessages.NUMBER_OF_BITS_MUST_BE_NON_NEGATIVE);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.NUMBER_OF_BITS_MUST_BE_NON_NEGATIVE);
               }
       
               @Specialization(guards = "k == 0")
      @@ -275,7 +313,7 @@ static PInt genBigInteger(PRandom random, int k) {
                       bb.putInt(4 * i, x);
                   }
                   bb.putInt(0, random.nextInt() >>> (32 - (k % 32)));
      -            return PythonObjectFactory.getUncached().createInt(new BigInteger(1, bb.array()));
      +            return PFactory.createInt(PythonLanguage.get(null), new BigInteger(1, bb.array()));
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/range/RangeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/range/RangeBuiltins.java
      index 2fa9c621ed..0d6b756f32 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/range/RangeBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/range/RangeBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2017, 2024, Oracle and/or its affiliates.
      + * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
        * Copyright (c) 2014, Regents of the University of California
        *
        * All rights reserved.
      @@ -29,20 +29,20 @@
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.OverflowError;
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError;
       import static com.oracle.graal.python.builtins.objects.common.IndexNodes.checkBounds;
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_RANGE;
      +import static com.oracle.graal.python.nodes.ErrorMessages.ARG_MUST_NOT_BE_ZERO;
       import static com.oracle.graal.python.nodes.ErrorMessages.RANGE_OUT_OF_BOUNDS;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CONTAINS__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      +import static com.oracle.graal.python.nodes.PGuards.isNoValue;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
       
       import java.math.BigInteger;
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -67,31 +67,39 @@
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotInquiry.NbBoolBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.RichCmpBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqItemBuiltinNode;
      -import com.oracle.graal.python.lib.GetNextNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode;
      +import com.oracle.graal.python.lib.IteratorExhausted;
       import com.oracle.graal.python.lib.PyIndexCheckNode;
      +import com.oracle.graal.python.lib.PyIterNextNode;
       import com.oracle.graal.python.lib.PyLongCheckExactNode;
       import com.oracle.graal.python.lib.PyNumberAsSizeNode;
      +import com.oracle.graal.python.lib.PyNumberIndexNode;
       import com.oracle.graal.python.lib.PyObjectGetIter;
       import com.oracle.graal.python.lib.PyObjectHashNode;
       import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
       import com.oracle.graal.python.lib.PyObjectRichCompareBool;
      +import com.oracle.graal.python.lib.RichCmpOp;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      -import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
       import com.oracle.graal.python.nodes.object.GetClassNode;
      -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
      +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes;
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToJavaBigIntegerNode;
      +import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.exception.PythonErrorType;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.OverflowException;
       import com.oracle.truffle.api.CompilerAsserts;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
      @@ -106,10 +114,12 @@
       import com.oracle.truffle.api.dsl.ImportStatic;
       import com.oracle.truffle.api.dsl.NeverDefault;
       import com.oracle.truffle.api.dsl.NodeFactory;
      +import com.oracle.truffle.api.dsl.ReportPolymorphism;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.dsl.TypeSystemReference;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.InlinedBranchProfile;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       
      @@ -122,14 +132,164 @@ protected List> getNodeFa
               return RangeBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1)
      +    // range(stop)
      +    // range(start, stop[, step])
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = J_RANGE, minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 4)
           @GenerateNodeFactory
      -    public abstract static class HashNode extends PythonBuiltinNode {
      +    @ReportPolymorphism
      +    public abstract static class RangeNode extends PythonQuaternaryBuiltinNode {
      +        // stop
      +        @Specialization(guards = "isStop(start, stop, step)")
      +        static Object doIntStop(Object cls, int stop, @SuppressWarnings("unused") PNone start, @SuppressWarnings("unused") PNone step,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Shared("exceptionProfile") @Cached InlinedBranchProfile exceptionProfile,
      +                        @Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact,
      +                        @Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            return doInt(cls, 0, stop, 1, inliningTarget, language, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode, raiseNode);
      +        }
      +
      +        @Specialization(guards = "isStop(start, stop, step)")
      +        static Object doPintStop(Object cls, PInt stop, @SuppressWarnings("unused") PNone start, @SuppressWarnings("unused") PNone step,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Shared("lenOfRangeNode") @Cached RangeNodes.LenOfRangeNode lenOfRangeNode,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            return doPint(cls, PFactory.createInt(language, BigInteger.ZERO), stop, PFactory.createInt(language, BigInteger.ONE), inliningTarget, language, lenOfRangeNode, raiseNode);
      +        }
      +
      +        @Specialization(guards = "isStop(start, stop, step)")
      +        static Object doGenericStop(VirtualFrame frame, Object cls, Object stop, @SuppressWarnings("unused") PNone start, @SuppressWarnings("unused") PNone step,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Shared("exceptionProfile") @Cached InlinedBranchProfile exceptionProfile,
      +                        @Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact,
      +                        @Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode,
      +                        @Shared("cast") @Cached CastToJavaIntExactNode cast,
      +                        @Shared("overflowProfile") @Cached IsBuiltinObjectProfile overflowProfile,
      +                        @Shared("indexNode") @Cached PyNumberIndexNode indexNode,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            return doGeneric(frame, cls, 0, stop, 1, inliningTarget, language, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode, cast, overflowProfile, indexNode, raiseNode);
      +        }
      +
      +        // start stop
      +        @Specialization(guards = "isStartStop(start, stop, step)")
      +        static Object doIntStartStop(Object cls, int start, int stop, @SuppressWarnings("unused") PNone step,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Shared("exceptionProfile") @Cached InlinedBranchProfile exceptionProfile,
      +                        @Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact,
      +                        @Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            return doInt(cls, start, stop, 1, inliningTarget, language, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode, raiseNode);
      +        }
      +
      +        @Specialization(guards = "isStartStop(start, stop, step)")
      +        static Object doPintStartStop(Object cls, PInt start, PInt stop, @SuppressWarnings("unused") PNone step,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Shared("lenOfRangeNode") @Cached RangeNodes.LenOfRangeNode lenOfRangeNode,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            return doPint(cls, start, stop, PFactory.createInt(language, BigInteger.ONE), inliningTarget, language, lenOfRangeNode, raiseNode);
      +        }
      +
      +        @Specialization(guards = "isStartStop(start, stop, step)")
      +        static Object doGenericStartStop(VirtualFrame frame, Object cls, Object start, Object stop, @SuppressWarnings("unused") PNone step,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Shared("exceptionProfile") @Cached InlinedBranchProfile exceptionProfile,
      +                        @Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact,
      +                        @Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode,
      +                        @Shared("cast") @Cached CastToJavaIntExactNode cast,
      +                        @Shared("overflowProfile") @Cached IsBuiltinObjectProfile overflowProfile,
      +                        @Shared("indexNode") @Cached PyNumberIndexNode indexNode,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            return doGeneric(frame, cls, start, stop, 1, inliningTarget, language, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode, cast, overflowProfile, indexNode, raiseNode);
      +        }
      +
      +        // start stop step
      +        @Specialization
      +        static Object doInt(@SuppressWarnings("unused") Object cls, int start, int stop, int step,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Shared("exceptionProfile") @Cached InlinedBranchProfile exceptionProfile,
      +                        @Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNode,
      +                        @Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            if (step == 0) {
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ARG_MUST_NOT_BE_ZERO, "range()", 3);
      +            }
      +            try {
      +                int len = lenOfRangeNode.executeInt(inliningTarget, start, stop, step);
      +                return PFactory.createIntRange(language, start, stop, step, len);
      +            } catch (OverflowException e) {
      +                exceptionProfile.enter(inliningTarget);
      +                return createBigRangeNode.execute(inliningTarget, start, stop, step);
      +            }
      +        }
      +
      +        @Specialization
      +        static Object doPint(@SuppressWarnings("unused") Object cls, PInt start, PInt stop, PInt step,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Shared("lenOfRangeNode") @Cached RangeNodes.LenOfRangeNode lenOfRangeNode,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            if (step.isZero()) {
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ARG_MUST_NOT_BE_ZERO, "range()", 3);
      +            }
      +            BigInteger len = lenOfRangeNode.execute(inliningTarget, start.getValue(), stop.getValue(), step.getValue());
      +            return PFactory.createBigRange(language, start, stop, step, PFactory.createInt(language, len));
      +        }
      +
      +        @Specialization(guards = "isStartStopStep(start, stop, step)")
      +        static Object doGeneric(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object start, Object stop, Object step,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Shared("exceptionProfile") @Cached InlinedBranchProfile exceptionProfile,
      +                        @Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact,
      +                        @Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode,
      +                        @Shared("cast") @Cached CastToJavaIntExactNode cast,
      +                        @Shared("overflowProfile") @Cached IsBuiltinObjectProfile overflowProfile,
      +                        @Shared("indexNode") @Cached PyNumberIndexNode indexNode,
      +                        @Shared @Cached PRaiseNode raiseNode) {
      +            Object lstart = indexNode.execute(frame, inliningTarget, start);
      +            Object lstop = indexNode.execute(frame, inliningTarget, stop);
      +            Object lstep = indexNode.execute(frame, inliningTarget, step);
      +
      +            try {
      +                int istart = cast.execute(inliningTarget, lstart);
      +                int istop = cast.execute(inliningTarget, lstop);
      +                int istep = cast.execute(inliningTarget, lstep);
      +                return doInt(cls, istart, istop, istep, inliningTarget, language, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode, raiseNode);
      +            } catch (PException e) {
      +                e.expect(inliningTarget, PythonErrorType.OverflowError, overflowProfile);
      +                return createBigRangeNode.execute(inliningTarget, lstart, lstop, lstep);
      +            }
      +        }
      +
      +        protected static boolean isStop(Object start, Object stop, Object step) {
      +            return isNoValue(start) && !isNoValue(stop) && isNoValue(step);
      +        }
      +
      +        protected static boolean isStartStop(Object start, Object stop, Object step) {
      +            return !isNoValue(start) && !isNoValue(stop) && isNoValue(step);
      +        }
      +
      +        protected static boolean isStartStopStep(Object start, Object stop, Object step) {
      +            return !isNoValue(start) && !isNoValue(stop) && !isNoValue(step);
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_hash, isComplex = true)
      +    @GenerateNodeFactory
      +    public abstract static class HashNode extends HashBuiltinNode {
               @Specialization
               static long hash(VirtualFrame frame, PIntRange self,
                               @Bind("this") Node inliningTarget,
      -                        @Shared("hashNode") @Cached PyObjectHashNode hashNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language,
      +                        @Shared("hashNode") @Cached PyObjectHashNode hashNode) {
                   Object[] content = new Object[3];
                   int intLength = self.getIntLength();
                   content[0] = intLength;
      @@ -143,14 +303,14 @@ static long hash(VirtualFrame frame, PIntRange self,
                       content[1] = self.getIntStart();
                       content[2] = self.getIntStep();
                   }
      -            return hashNode.execute(frame, inliningTarget, factory.createTuple(content));
      +            return hashNode.execute(frame, inliningTarget, PFactory.createTuple(language, content));
               }
       
               @Specialization
               static long hash(VirtualFrame frame, PBigRange self,
                               @Bind("this") Node inliningTarget,
      -                        @Shared("hashNode") @Cached PyObjectHashNode hashNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language,
      +                        @Shared("hashNode") @Cached PyObjectHashNode hashNode) {
                   Object[] content = new Object[3];
                   PInt length = self.getPIntLength();
                   content[0] = length;
      @@ -164,13 +324,13 @@ static long hash(VirtualFrame frame, PBigRange self,
                       content[1] = self.getStart();
                       content[2] = self.getStep();
                   }
      -            return hashNode.execute(frame, inliningTarget, factory.createTuple(content));
      +            return hashNode.execute(frame, inliningTarget, PFactory.createTuple(language, content));
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
      -    abstract static class ReprNode extends PythonBuiltinNode {
      +    abstract static class ReprNode extends PythonUnaryBuiltinNode {
               @Specialization
               public static TruffleString repr(PRange self,
                               @Bind("this") Node inliningTarget,
      @@ -207,12 +367,12 @@ static int doPBigRange(VirtualFrame frame, PBigRange self,
                               @Bind("this") Node inliningTarget,
                               @Cached PyIndexCheckNode indexCheckNode,
                               @Cached PyNumberAsSizeNode asSizeNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object length = self.getLength();
                   if (indexCheckNode.execute(inliningTarget, length)) {
                       return asSizeNode.executeExact(frame, inliningTarget, length);
                   }
      -            throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, length);
      +            throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, length);
               }
       
               @NeverDefault
      @@ -241,19 +401,19 @@ boolean doPBigRange(PBigRange self) {
               }
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object doPIntRange(PIntRange self,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createIntRangeIterator(self);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createIntRangeIterator(language, self);
               }
       
               @Specialization
               static Object doPIntRange(PBigRange self,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createBigRangeIterator(self);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createBigRangeIterator(language, self);
               }
           }
       
      @@ -296,17 +456,16 @@ public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object reduce(PRange self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached GetClassNode getClassNode,
      -                        @Cached PythonObjectFactory factory) {
      -            PTuple args = factory.createTuple(new Object[]{self.getStart(), self.getStop(), self.getStep()});
      -            return factory.createTuple(new Object[]{getClassNode.execute(inliningTarget, self), args});
      +                        @Bind PythonLanguage language,
      +                        @Cached GetClassNode getClassNode) {
      +            PTuple args = PFactory.createTuple(language, new Object[]{self.getStart(), self.getStop(), self.getStep()});
      +            return PFactory.createTuple(language, new Object[]{getClassNode.execute(inliningTarget, self), args});
               }
           }
       
      -    @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.tp_richcompare, isComplex = true)
           @GenerateNodeFactory
      -    abstract static class EqNode extends PythonBinaryBuiltinNode {
      -
      +    abstract static class EqNode extends RichCmpBuiltinNode {
               private static boolean eqInt(PIntRange range, int len, int start, int step) {
                   return eqInt(range.getIntLength(), range.getIntStart(), range.getIntStep(),
                                   len, start, step);
      @@ -347,17 +506,17 @@ private static boolean eqBigInt(BigInteger llen, BigInteger lstart, BigInteger l
                   return lstep.compareTo(rstep) == 0;
               }
       
      -        @Specialization
      -        static boolean eqIntInt(PIntRange left, PIntRange right) {
      +        @Specialization(guards = "op.isEqOrNe()")
      +        static boolean eqIntInt(PIntRange left, PIntRange right, RichCmpOp op) {
                   if (left == right) {
      -                return true;
      +                return op.isEq();
                   }
                   return eqInt(left.getIntLength(), left.getIntStart(), left.getIntStep(),
      -                            right.getIntLength(), right.getIntStart(), right.getIntStep());
      +                            right.getIntLength(), right.getIntStart(), right.getIntStep()) == op.isEq();
               }
       
      -        @Specialization
      -        static boolean eqIntBig(VirtualFrame frame, PIntRange left, PBigRange right,
      +        @Specialization(guards = "op.isEqOrNe()")
      +        static boolean eqIntBig(VirtualFrame frame, PIntRange left, PBigRange right, RichCmpOp op,
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached RangeNodes.CoerceToBigRange intToBigRange,
                               @Shared @Cached PyNumberAsSizeNode asSizeNode) {
      @@ -365,14 +524,14 @@ static boolean eqIntBig(VirtualFrame frame, PIntRange left, PBigRange right,
                       int rlen = asSizeNode.executeExact(frame, inliningTarget, right.getPIntLength());
                       int rstart = asSizeNode.executeExact(frame, inliningTarget, right.getPIntStart());
                       int rstep = asSizeNode.executeExact(frame, inliningTarget, right.getPIntStep());
      -                return eqInt(left, rlen, rstart, rstep);
      +                return eqInt(left, rlen, rstart, rstep) == op.isEq();
                   } catch (PException e) {
      -                return eqBigInt(intToBigRange.execute(inliningTarget, left), right);
      +                return eqBigInt(intToBigRange.execute(inliningTarget, left), right, op);
                   }
               }
       
      -        @Specialization
      -        static boolean eqIntBig(VirtualFrame frame, PBigRange left, PIntRange right,
      +        @Specialization(guards = "op.isEqOrNe()")
      +        static boolean eqIntBig(VirtualFrame frame, PBigRange left, PIntRange right, RichCmpOp op,
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached RangeNodes.CoerceToBigRange intToBigRange,
                               @Shared @Cached PyNumberAsSizeNode asSizeNode) {
      @@ -380,24 +539,24 @@ static boolean eqIntBig(VirtualFrame frame, PBigRange left, PIntRange right,
                       int llen = asSizeNode.executeExact(frame, inliningTarget, left.getPIntLength());
                       int lstart = asSizeNode.executeExact(frame, inliningTarget, left.getPIntStart());
                       int lstep = asSizeNode.executeExact(frame, inliningTarget, left.getPIntStep());
      -                return eqInt(right, llen, lstart, lstep);
      +                return eqInt(right, llen, lstart, lstep) == op.isEq();
                   } catch (PException e) {
      -                return eqBigInt(left, intToBigRange.execute(inliningTarget, right));
      +                return eqBigInt(left, intToBigRange.execute(inliningTarget, right), op);
                   }
               }
       
      -        @Specialization
      -        static boolean eqBigInt(PBigRange left, PBigRange right) {
      +        @Specialization(guards = "op.isEqOrNe()")
      +        static boolean eqBigInt(PBigRange left, PBigRange right, RichCmpOp op) {
                   if (left == right) {
      -                return true;
      +                return op.isEq();
                   }
                   return eqBigInt(left.getBigIntegerLength(), left.getBigIntegerStart(), left.getBigIntegerStep(),
      -                            right.getBigIntegerLength(), right.getBigIntegerStart(), right.getBigIntegerStep());
      +                            right.getBigIntegerLength(), right.getBigIntegerStart(), right.getBigIntegerStep()) == op.isEq();
               }
       
               @Fallback
               @SuppressWarnings("unused")
      -        static Object doOther(Object left, Object right) {
      +        static Object doOther(Object left, Object right, RichCmpOp op) {
                   return PNotImplemented.NOT_IMPLEMENTED;
               }
           }
      @@ -409,7 +568,7 @@ public abstract static class RangeSqItemNode extends SqItemBuiltinNode {
               static int doInt(PIntRange self, int index,
                               @Bind("this") Node inliningTarget,
                               @Cached InlinedConditionProfile negativeIndexProfile,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (negativeIndexProfile.profile(inliningTarget, index < 0)) {
                       index += self.getIntLength();
                   }
      @@ -421,8 +580,8 @@ static int doInt(PIntRange self, int index,
               @InliningCutoff
               static Object doBigInt(PBigRange self, int index,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createInt(self.getBigIntItemNormalized(GetItemNode.computeBigRangeItem(inliningTarget, self, index)));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createInt(language, self.getBigIntItemNormalized(GetItemNode.computeBigRangeItem(inliningTarget, self, index)));
               }
           }
       
      @@ -464,9 +623,8 @@ static Object doPRange(VirtualFrame frame, PIntRange self, Object idx,
               static Object doPRange(PBigRange self, Object idx,
                               @SuppressWarnings("unused") @Bind("this") Node inliningTarget,
                               @Shared @Cached CastToJavaBigIntegerNode toBigInt,
      -                        @SuppressWarnings("unused") @Shared @Cached PyIndexCheckNode indexCheckNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createInt(self.getBigIntItemNormalized(computeBigRangeItem(inliningTarget, self, idx, toBigInt)));
      +                        @SuppressWarnings("unused") @Shared @Cached PyIndexCheckNode indexCheckNode) {
      +            return PFactory.createInt(PythonLanguage.get(inliningTarget), self.getBigIntItemNormalized(computeBigRangeItem(inliningTarget, self, idx, toBigInt)));
               }
       
               @Specialization(guards = "!canBeIndex(this, slice, indexCheckNode)")
      @@ -479,13 +637,12 @@ static Object doPRangeSliceSlowPath(VirtualFrame frame, PIntRange self, PSlice s
                               @Shared @Cached CoerceToObjectSlice toBigIntSlice,
                               @Shared @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact,
                               @Shared @Cached RangeNodes.LenOfRangeNode lenOfRangeNode,
      -                        @SuppressWarnings("unused") @Shared @Cached PyIndexCheckNode indexCheckNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @SuppressWarnings("unused") @Shared @Cached PyIndexCheckNode indexCheckNode) {
                   try {
                       final int rStart = self.getIntStart();
                       final int rStep = self.getIntStep();
                       SliceInfo info = compute.execute(frame, slice, self.getIntLength());
      -                return createRange(inliningTarget, info, rStart, rStep, lenOfRangeNodeExact, factory);
      +                return createRange(inliningTarget, info, rStart, rStep, lenOfRangeNodeExact);
                   } catch (PException pe) {
                       pe.expect(inliningTarget, PythonBuiltinClassType.OverflowError, profileError);
                       // pass
      @@ -496,7 +653,7 @@ static Object doPRangeSliceSlowPath(VirtualFrame frame, PIntRange self, PSlice s
                   BigInteger rangeStart = rangeBI.getBigIntegerStart();
                   BigInteger rangeStep = rangeBI.getBigIntegerStep();
       
      -            SliceObjectInfo info = PObjectSlice.computeIndicesSlowPath(toBigIntSlice.execute(slice), rangeBI.getBigIntegerLength(), null);
      +            SliceObjectInfo info = PObjectSlice.computeIndicesSlowPath(toBigIntSlice.execute(slice), rangeBI.getBigIntegerLength(), false);
                   return createRange(inliningTarget, info, rangeStart, rangeStep, lenOfRangeNode);
               }
       
      @@ -514,14 +671,13 @@ static Object doPRangeSliceSlowPath(VirtualFrame frame, PBigRange self, PSlice s
                               @Shared @Cached RangeNodes.LenOfRangeNode lenOfRangeNode,
                               @SuppressWarnings("unused") @Shared @Cached PyIndexCheckNode indexCheckNode,
                               @Shared @Cached PyNumberAsSizeNode asSizeNode,
      -                        @Shared @Cached PythonObjectFactory factory,
                               // unused node to avoid mixing shared and non-shared inlined nodes
      -                        @SuppressWarnings("unused") @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @SuppressWarnings("unused") @Shared @Cached PRaiseNode raiseNode) {
                   try {
                       int rStart = asSizeNode.executeExact(frame, inliningTarget, self.getStart());
                       int rStep = asSizeNode.executeExact(frame, inliningTarget, self.getStep());
                       SliceInfo info = compute.execute(frame, slice, asSizeNode.executeExact(frame, inliningTarget, self.getLength()));
      -                return createRange(inliningTarget, info, rStart, rStep, lenOfRangeNodeExact, factory);
      +                return createRange(inliningTarget, info, rStart, rStep, lenOfRangeNodeExact);
                   } catch (PException pe) {
                       pe.expect(inliningTarget, PythonBuiltinClassType.OverflowError, profileError);
                       // pass
      @@ -532,7 +688,7 @@ static Object doPRangeSliceSlowPath(VirtualFrame frame, PBigRange self, PSlice s
                   BigInteger rangeStart = rangeBI.getBigIntegerStart();
                   BigInteger rangeStep = rangeBI.getBigIntegerStep();
       
      -            SliceObjectInfo info = PObjectSlice.computeIndicesSlowPath(toBigIntSlice.execute(slice), rangeBI.getBigIntegerLength(), null);
      +            SliceObjectInfo info = PObjectSlice.computeIndicesSlowPath(toBigIntSlice.execute(slice), rangeBI.getBigIntegerLength(), false);
                   return createRange(inliningTarget, info, rangeStart, rangeStep, lenOfRangeNode);
               }
       
      @@ -552,24 +708,23 @@ static Object doGeneric(VirtualFrame frame, PRange self, Object idx,
                               @Shared @Cached PyIndexCheckNode indexCheckNode,
                               @Shared @Cached PyNumberAsSizeNode asSizeNode,
                               @Shared @Cached IndexNodes.NormalizeIndexCustomMessageNode normalize,
      -                        @Shared @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   if (isNumIndexProfile.profile(inliningTarget, canBeIndex(inliningTarget, idx, indexCheckNode))) {
                       if (self instanceof PIntRange) {
                           return doPRange(frame, (PIntRange) self, idx, inliningTarget, indexCheckNode, asSizeNode, normalize);
                       }
      -                return doPRange((PBigRange) self, idx, inliningTarget, toBigInt, indexCheckNode, factory);
      +                return doPRange((PBigRange) self, idx, inliningTarget, toBigInt, indexCheckNode);
                   }
                   if (isSliceIndexProfile.profile(inliningTarget, idx instanceof PSlice)) {
                       PSlice slice = (PSlice) idx;
                       if (self instanceof PIntRange) {
                           return doPRangeSliceSlowPath(frame, (PIntRange) self, slice, inliningTarget, compute, profileError, toBigIntRange, toBigIntSlice, lenOfRangeNodeExact, lenOfRangeNode,
      -                                    indexCheckNode, factory);
      +                                    indexCheckNode);
                       }
                       return doPRangeSliceSlowPath(frame, (PBigRange) self, slice, inliningTarget, isNumIndexProfile, isSliceIndexProfile, compute, profileError, toBigIntRange, toBigIntSlice,
      -                                lenOfRangeNodeExact, lenOfRangeNode, indexCheckNode, asSizeNode, factory, raiseNode);
      +                                lenOfRangeNodeExact, lenOfRangeNode, indexCheckNode, asSizeNode, raiseNode);
                   }
      -            throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.OBJ_INDEX_MUST_BE_INT_OR_SLICES, "range", idx);
      +            throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.OBJ_INDEX_MUST_BE_INT_OR_SLICES, "range", idx);
               }
       
               @TruffleBoundary
      @@ -594,17 +749,17 @@ private static BigInteger computeBigRangeItem(Node inliningTarget, PBigRange ran
                   }
       
                   if (i.compareTo(BigInteger.ZERO) < 0 || i.compareTo(length) >= 0) {
      -                throw PRaiseNode.raiseUncached(inliningTarget, IndexError, ErrorMessages.RANGE_OBJ_IDX_OUT_OF_RANGE);
      +                throw PRaiseNode.raiseStatic(inliningTarget, IndexError, ErrorMessages.RANGE_OBJ_IDX_OUT_OF_RANGE);
                   }
                   return i;
               }
       
      -        private static PIntRange createRange(Node inliningTarget, SliceInfo info, int rStart, int rStep, LenOfIntRangeNodeExact lenOfRangeNode, PythonObjectFactory factory) throws OverflowException {
      +        private static PIntRange createRange(Node inliningTarget, SliceInfo info, int rStart, int rStep, LenOfIntRangeNodeExact lenOfRangeNode) throws OverflowException {
                   int newStep = rStep * info.step;
                   int newStart = rStart + info.start * rStep;
                   int newStop = rStart + info.stop * rStep;
                   int len = lenOfRangeNode.executeInt(inliningTarget, newStart, newStop, newStep);
      -            return factory.createIntRange(newStart, newStop, newStep, len);
      +            return PFactory.createIntRange(PythonLanguage.get(inliningTarget), newStart, newStop, newStep, len);
               }
       
               @TruffleBoundary
      @@ -617,8 +772,8 @@ private static PBigRange createRange(Node inliningTarget, SliceObjectInfo info,
                   BigInteger start = rStart.add(sliceStart.multiply(rStep));
                   BigInteger stop = rStart.add(sliceStop.multiply(rStep));
                   BigInteger len = lenOfRangeNode.execute(inliningTarget, start, stop, step);
      -            PythonObjectFactory factory = PythonObjectFactory.getUncached();
      -            return factory.createBigRange(factory.createInt(start), factory.createInt(stop), factory.createInt(step), factory.createInt(len));
      +            PythonLanguage language = PythonLanguage.get(null);
      +            return PFactory.createBigRange(language, PFactory.createInt(language, start), PFactory.createInt(language, stop), PFactory.createInt(language, step), PFactory.createInt(language, len));
               }
       
               @NeverDefault
      @@ -631,11 +786,11 @@ public static GetItemNode getUncached() {
               }
           }
       
      -    @Builtin(name = J___CONTAINS__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.sq_contains, isComplex = true)
           @GenerateNodeFactory
           @ImportStatic(PGuards.class)
      -    @TypeSystemReference(PythonArithmeticTypes.class)
      -    abstract static class ContainsNode extends PythonBinaryBuiltinNode {
      +    @TypeSystemReference(PythonIntegerTypes.class)
      +    abstract static class ContainsNode extends SqContainsBuiltinNode {
               private static final BigInteger MINUS_ONE = BigInteger.ONE.negate();
       
               public abstract boolean execute(VirtualFrame frame, PRange self, Object value);
      @@ -789,23 +944,21 @@ static boolean containsSlowNum(PBigRange self, PInt other,
               static boolean containsIterator(VirtualFrame frame, PRange self, Object elem,
                               @Bind("this") Node inliningTarget,
                               @Cached PyObjectGetIter getIter,
      -                        @Cached GetNextNode nextNode,
      -                        @Cached PyObjectRichCompareBool.EqNode eqNode,
      -                        @Cached IsBuiltinObjectProfile errorProfile,
      +                        @Cached PyIterNextNode nextNode,
      +                        @Cached PyObjectRichCompareBool eqNode,
                               @SuppressWarnings("unused") @Exclusive @Cached PyLongCheckExactNode isBuiltin) {
                   Object iter = getIter.execute(frame, inliningTarget, self);
                   while (true) {
      +                Object item;
                       try {
      -                    Object item = nextNode.execute(frame, iter);
      -                    if (eqNode.compare(frame, inliningTarget, elem, item)) {
      -                        return true;
      -                    }
      -                } catch (PException e) {
      -                    e.expectStopIteration(inliningTarget, errorProfile);
      -                    break;
      +                    item = nextNode.execute(frame, inliningTarget, iter);
      +                } catch (IteratorExhausted e) {
      +                    return false;
      +                }
      +                if (eqNode.executeEq(frame, inliningTarget, elem, item)) {
      +                    return true;
                       }
                   }
      -            return false;
               }
       
               @NeverDefault
      @@ -843,14 +996,14 @@ private static BigInteger slowIntIndex(Node inliningTarget, PBigRange self, Obje
               static int doFastRange(VirtualFrame frame, PIntRange self, int elem,
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached ContainsNode containsNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   if (containsNode.execute(frame, self, elem)) {
                       int index = fastIntIndex(self, elem);
                       if (index != -1) {
                           return index;
                       }
                   }
      -            throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.D_IS_NOT_IN_RANGE, elem);
      +            throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.D_IS_NOT_IN_RANGE, elem);
               }
       
               @Specialization(guards = "canBeInteger(elem)")
      @@ -858,7 +1011,7 @@ static Object doFastRangeGeneric(VirtualFrame frame, PIntRange self, Object elem
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached ContainsNode containsNode,
                               @Cached PyNumberAsSizeNode asSizeNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   if (containsNode.execute(frame, self, elem)) {
                       int value = asSizeNode.executeExact(frame, inliningTarget, elem);
                       int index = fastIntIndex(self, value);
      @@ -866,7 +1019,7 @@ static Object doFastRangeGeneric(VirtualFrame frame, PIntRange self, Object elem
                           return index;
                       }
                   }
      -            throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.IS_NOT_IN_RANGE, elem);
      +            throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.IS_NOT_IN_RANGE, elem);
               }
       
               @Specialization(guards = "canBeInteger(elem)")
      @@ -874,15 +1027,14 @@ static Object doLongRange(VirtualFrame frame, PBigRange self, Object elem,
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached ContainsNode containsNode,
                               @Cached CastToJavaBigIntegerNode castToBigInt,
      -                        @Cached PythonObjectFactory factory,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   if (containsNode.execute(frame, self, elem)) {
                       BigInteger index = slowIntIndex(inliningTarget, self, elem, castToBigInt);
                       if (index != null) {
      -                    return factory.createInt(index);
      +                    return PFactory.createInt(PythonLanguage.get(inliningTarget), index);
                       }
                   }
      -            throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.D_IS_NOT_IN_RANGE, elem);
      +            throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.D_IS_NOT_IN_RANGE, elem);
               }
       
               /**
      @@ -892,29 +1044,28 @@ static Object doLongRange(VirtualFrame frame, PBigRange self, Object elem,
               @Specialization(guards = "!canBeInteger(elem)")
               static Object containsIterator(VirtualFrame frame, PIntRange self, Object elem,
                               @Bind("this") Node inliningTarget,
      -                        @Cached GetNextNode nextNode,
                               @Cached PyObjectGetIter getIter,
      -                        @Cached PyObjectRichCompareBool.EqNode eqNode,
      -                        @Cached IsBuiltinObjectProfile errorProfile,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PyIterNextNode nextNode,
      +                        @Cached PyObjectRichCompareBool eqNode,
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   int idx = 0;
                   Object iter = getIter.execute(frame, inliningTarget, self);
                   while (true) {
      +                Object item;
                       try {
      -                    Object item = nextNode.execute(frame, iter);
      -                    if (eqNode.compare(frame, inliningTarget, elem, item)) {
      -                        return idx;
      -                    }
      -                } catch (PException e) {
      -                    e.expectStopIteration(inliningTarget, errorProfile);
      +                    item = nextNode.execute(frame, inliningTarget, iter);
      +                } catch (IteratorExhausted e) {
                           break;
                       }
      +                if (eqNode.executeEq(frame, inliningTarget, elem, item)) {
      +                    return idx;
      +                }
                       if (idx == SysModuleBuiltins.MAXSIZE) {
      -                    throw raiseNode.get(inliningTarget).raiseOverflow();
      +                    throw raiseNode.raiseOverflow(inliningTarget);
                       }
                       idx++;
                   }
      -            throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.D_IS_NOT_IN_RANGE, elem);
      +            throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.D_IS_NOT_IN_RANGE, elem);
               }
           }
       
      @@ -992,27 +1143,25 @@ static boolean isFallback(Object value) {
               static int doGeneric(VirtualFrame frame, PRange self, Object elem,
                               @Bind("this") Node inliningTarget,
                               @Cached PyObjectGetIter getIter,
      -                        @Cached GetNextNode nextNode,
      -                        @Cached PyObjectRichCompareBool.EqNode eqNode,
      -                        @Cached IsBuiltinObjectProfile errorProfile,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PyIterNextNode nextNode,
      +                        @Cached PyObjectRichCompareBool eqNode,
      +                        @Cached PRaiseNode raiseNode) {
                   int count = 0;
                   Object iter = getIter.execute(frame, inliningTarget, self);
                   while (true) {
      +                Object item;
                       try {
      -                    Object item = nextNode.execute(frame, iter);
      -                    if (eqNode.compare(frame, inliningTarget, elem, item)) {
      -                        if (count == SysModuleBuiltins.MAXSIZE) {
      -                            throw raiseNode.get(inliningTarget).raiseOverflow();
      -                        }
      -                        count = count + 1;
      +                    item = nextNode.execute(frame, inliningTarget, iter);
      +                } catch (IteratorExhausted e) {
      +                    return count;
      +                }
      +                if (eqNode.executeEq(frame, inliningTarget, elem, item)) {
      +                    if (count == SysModuleBuiltins.MAXSIZE) {
      +                        throw raiseNode.raiseOverflow(inliningTarget);
                           }
      -                } catch (PException e) {
      -                    e.expectStopIteration(inliningTarget, errorProfile);
      -                    break;
      +                    count = count + 1;
                       }
                   }
      -            return count;
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/range/RangeNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/range/RangeNodes.java
      index 057719c193..ef29cc7899 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/range/RangeNodes.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/range/RangeNodes.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -45,12 +45,13 @@
       
       import java.math.BigInteger;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.builtins.objects.slice.PSlice.SliceInfo;
       import com.oracle.graal.python.nodes.PNodeWithContext;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.SpecialMethodNames;
       import com.oracle.graal.python.nodes.util.CastToJavaBigIntegerNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.OverflowException;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
      @@ -72,9 +73,9 @@ public abstract static class CreateBigRangeNode extends Node {
               public abstract PBigRange execute(Node inliningTarget, Object start, Object stop, Object step);
       
               @TruffleBoundary
      -        private static void checkStepZero(Node inliningTarget, BigInteger stepBI, PRaiseNode.Lazy raise) {
      +        private static void checkStepZero(Node inliningTarget, BigInteger stepBI, PRaiseNode raise) {
                   if (stepBI.compareTo(BigInteger.ZERO) == 0) {
      -                throw raise.get(inliningTarget).raise(ValueError, ARG_MUST_NOT_BE_ZERO, "range()", 3);
      +                throw raise.raise(inliningTarget, ValueError, ARG_MUST_NOT_BE_ZERO, "range()", 3);
                   }
               }
       
      @@ -84,14 +85,15 @@ static PBigRange createBigRange(Node inliningTarget, Object start, Object stop,
                               @Cached CastToJavaBigIntegerNode startToBI,
                               @Cached CastToJavaBigIntegerNode stopToBI,
                               @Cached CastToJavaBigIntegerNode stepToBI,
      -                        @Cached PRaiseNode.Lazy raise,
      -                        @Cached(inline = false) PythonObjectFactory factory) {
      +                        @Cached PRaiseNode raise) {
                   BigInteger stepBI = stepToBI.execute(inliningTarget, step);
                   checkStepZero(inliningTarget, stepBI, raise);
                   BigInteger startBI = startToBI.execute(inliningTarget, start);
                   BigInteger stopBI = stopToBI.execute(inliningTarget, stop);
                   BigInteger len = lenOfRangeNode.execute(inliningTarget, startBI, stopBI, stepBI);
      -            return factory.createBigRange(factory.createInt(startBI), factory.createInt(stopBI), factory.createInt(stepBI), factory.createInt(len));
      +            PythonLanguage language = PythonLanguage.get(inliningTarget);
      +            return PFactory.createBigRange(language, PFactory.createInt(language, startBI), PFactory.createInt(language, stopBI), PFactory.createInt(language, stepBI),
      +                            PFactory.createInt(language, len));
               }
       
           }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/referencetype/PReferenceType.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/referencetype/PReferenceType.java
      index 204448a4ec..b528f8efdc 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/referencetype/PReferenceType.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/referencetype/PReferenceType.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -51,7 +51,7 @@
       
       public class PReferenceType extends PythonBuiltinObject {
           public static class WeakRefStorage extends WeakReference {
      -        private final Object callback;
      +        private Object callback;
               private final PReferenceType ref;
               private final long pointer;
       
      @@ -72,7 +72,7 @@ public PReferenceType getRef() {
       
               /**
                * get the native pointer of the referent.
      -         * 
      +         *
                * @return the native pointer if referent is a native reference, otherwise, 0.
                */
               public long getPointer() {
      @@ -80,7 +80,7 @@ public long getPointer() {
               }
           }
       
      -    private final WeakRefStorage store;
      +    private WeakRefStorage store;
           private long hash = -1;
       
           @TruffleBoundary
      @@ -89,16 +89,40 @@ public PReferenceType(Object cls, Shape instanceShape, Object pythonObject, Obje
               this.store = new WeakRefStorage(this, pythonObject, callback, queue);
           }
       
      +    /**
      +     * In CPython, this functions clears the reference without calling the callback. This is not
      +     * exactly what we can do here since the WeakRefStorage is already enqueued. We clear the
      +     * callback so that when the Java WeakReference is enqueued because the Object was collected,
      +     * there is no callback to run anymore, and we also drop the store reference here entirely so
      +     * that the object is not longer reachable through this weakref.
      +     */
      +    public void clearRef() {
      +        WeakRefStorage s = this.store;
      +        if (s != null) {
      +            s.callback = null;
      +            this.store = null;
      +        }
      +    }
      +
           public Object getCallback() {
      -        if (this.store.callback == null) {
      +        Object callback = null;
      +        WeakRefStorage s = this.store;
      +        if (s != null) {
      +            callback = s.callback;
      +        }
      +        if (callback == null) {
                   return PNone.NONE;
               }
      -        return this.store.callback;
      +        return callback;
           }
       
           @TruffleBoundary
           public Object getObject() {
      -        return this.store.get();
      +        WeakRefStorage s = this.store;
      +        if (s != null) {
      +            return s.get();
      +        }
      +        return null;
           }
       
           public Object getPyObject() {
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/referencetype/ReferenceTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/referencetype/ReferenceTypeBuiltins.java
      index 0cc8893301..db79c0854a 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/referencetype/ReferenceTypeBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/referencetype/ReferenceTypeBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -41,45 +41,65 @@
       package com.oracle.graal.python.builtins.objects.referencetype;
       
       import static com.oracle.graal.python.builtins.objects.PythonAbstractObject.objectHashCode;
      +import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_weaklistoffset;
      +import static com.oracle.graal.python.nodes.HiddenAttr.WEAKLIST;
      +import static com.oracle.graal.python.nodes.HiddenAttr.WEAK_REF_QUEUE;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALLBACK__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
      +import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
       
      +import java.lang.ref.ReferenceQueue;
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.PNotImplemented;
      +import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
      +import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
      +import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions;
      +import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess;
      +import com.oracle.graal.python.builtins.objects.referencetype.ReferenceTypeBuiltinsFactory.ReferenceTypeNodeFactory;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
      +import com.oracle.graal.python.builtins.objects.type.PythonClass;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.RichCmpBuiltinNode;
       import com.oracle.graal.python.lib.PyObjectHashNode;
       import com.oracle.graal.python.lib.PyObjectLookupAttr;
      +import com.oracle.graal.python.lib.PyObjectRichCompare;
      +import com.oracle.graal.python.lib.RichCmpOp;
       import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.HiddenAttr;
      +import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PRaiseNode;
      -import com.oracle.graal.python.nodes.expression.BinaryComparisonNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.object.BuiltinClassProfiles;
       import com.oracle.graal.python.nodes.object.GetClassNode;
      +import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.exception.PythonErrorType;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
      +import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Cached.Shared;
       import com.oracle.truffle.api.dsl.Fallback;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      +import com.oracle.truffle.api.dsl.NeverDefault;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      @@ -89,12 +109,144 @@
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PReferenceType)
       public final class ReferenceTypeBuiltins extends PythonBuiltins {
      +    public static final TpSlots SLOTS = ReferenceTypeBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return ReferenceTypeBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___INIT__, minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "ReferenceType", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class ReferenceTypeNode extends PythonBuiltinNode {
      +        @Child private CStructAccess.ReadI64Node getTpWeaklistoffsetNode;
      +
      +        public abstract PReferenceType execute(Object cls, Object object, Object callback);
      +
      +        @Specialization(guards = "!isNativeObject(object)")
      +        static PReferenceType refType(Object cls, Object object, @SuppressWarnings("unused") PNone none,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached.Exclusive @Cached GetClassNode getClassNode,
      +                        @Cached HiddenAttr.ReadNode readWeaklistNode,
      +                        @Cached HiddenAttr.WriteNode writeWeakListNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached.Exclusive @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached.Exclusive @Cached HiddenAttr.ReadNode readQueueNode,
      +                        @Cached.Exclusive @Cached PRaiseNode raiseNode) {
      +            Object obj = object;
      +            if (object instanceof PythonBuiltinClassType tobj) {
      +                obj = PythonContext.get(inliningTarget).getCore().lookupType(tobj);
      +            }
      +
      +            Object clazz = getClassNode.execute(inliningTarget, obj);
      +            boolean allowed = true;
      +            if (clazz instanceof PythonBuiltinClassType type) {
      +                allowed = type.getWeaklistoffset() != 0;
      +            }
      +            if (!allowed) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANNOT_CREATE_WEAK_REFERENCE_TO, obj);
      +            }
      +            assert obj instanceof PythonAbstractObject;
      +            Object wr = readWeaklistNode.execute(inliningTarget, (PythonAbstractObject) obj, WEAKLIST, null);
      +            if (wr != null) {
      +                return (PReferenceType) wr; // is must be a PReferenceType instance.
      +            }
      +
      +            PReferenceType ref = PFactory.createReferenceType(language, cls, getInstanceShape.execute(cls), obj, null, getWeakReferenceQueue(inliningTarget, readQueueNode));
      +            writeWeakListNode.execute(inliningTarget, (PythonAbstractObject) obj, WEAKLIST, ref);
      +            return ref;
      +        }
      +
      +        @Specialization(guards = {"!isNativeObject(object)", "!isPNone(callback)"})
      +        static PReferenceType refTypeWithCallback(Object cls, Object object, Object callback,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached.Exclusive @Cached HiddenAttr.ReadNode readQueueNode,
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createReferenceType(language, cls, getInstanceShape.execute(cls), object, callback, getWeakReferenceQueue(inliningTarget, readQueueNode));
      +        }
      +
      +        @Specialization
      +        @SuppressWarnings("truffle-static-method")
      +        PReferenceType refType(Object cls, PythonAbstractNativeObject pythonObject, Object callback,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached.Exclusive @Cached GetClassNode getClassNode,
      +                        @Cached BuiltinClassProfiles.IsBuiltinClassExactProfile profile,
      +                        @Cached TypeNodes.GetMroNode getMroNode,
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape,
      +                        @Cached.Exclusive @Cached HiddenAttr.ReadNode readQueueNode,
      +                        @Cached.Exclusive @Cached PRaiseNode raiseNode) {
      +            Object actualCallback = callback instanceof PNone ? null : callback;
      +            Object clazz = getClassNode.execute(inliningTarget, pythonObject);
      +
      +            // if the object is a type, a weak ref is allowed
      +            boolean allowed = false;
      +            if (profile.profileClass(inliningTarget, clazz, PythonBuiltinClassType.PythonClass)) {
      +                allowed = true;
      +            } else {
      +                // if the object's type is a native type, we need to consider 'tp_weaklistoffset'
      +                if (PGuards.isNativeClass(clazz) || clazz instanceof PythonClass && ((PythonClass) clazz).needsNativeAllocation()) {
      +                    for (Object base : getMroNode.execute(inliningTarget, clazz)) {
      +                        if (PGuards.isNativeClass(base)) {
      +                            if (getTpWeaklistoffsetNode == null) {
      +                                CompilerDirectives.transferToInterpreterAndInvalidate();
      +                                getTpWeaklistoffsetNode = insert(CStructAccess.ReadI64Node.create());
      +                            }
      +                            long tpWeaklistoffset = getTpWeaklistoffsetNode.readFromObj((PythonNativeClass) base, PyTypeObject__tp_weaklistoffset);
      +                            if (tpWeaklistoffset != 0) {
      +                                allowed = true;
      +                                break;
      +                            }
      +                        } else if (base instanceof PythonClass /* not PythonBuiltinClass */) {
      +                            // any subclass of a normal (non-builtin) class supports weakrefs
      +                            allowed = true;
      +                            break;
      +                        }
      +                    }
      +                }
      +            }
      +            if (allowed) {
      +                CApiTransitions.addNativeWeakRef(getContext(), pythonObject);
      +                return PFactory.createReferenceType(language, cls, getInstanceShape.execute(cls), pythonObject, actualCallback, getWeakReferenceQueue(inliningTarget, readQueueNode));
      +            } else {
      +                return refType(cls, pythonObject, actualCallback, raiseNode);
      +            }
      +        }
      +
      +        @Fallback
      +        static PReferenceType refType(@SuppressWarnings("unused") Object cls, Object object, @SuppressWarnings("unused") Object callback,
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CANNOT_CREATE_WEAK_REFERENCE_TO, object);
      +        }
      +
      +        @SuppressWarnings("unchecked")
      +        private static ReferenceQueue getWeakReferenceQueue(Node inliningTarget, HiddenAttr.ReadNode readNode) {
      +            PythonContext context = PythonContext.get(inliningTarget);
      +            Object queueObject = readNode.execute(inliningTarget, context.lookupType(PythonBuiltinClassType.PReferenceType), WEAK_REF_QUEUE, null);
      +            if (queueObject != null) {
      +                return (ReferenceQueue) queueObject;
      +            } else {
      +                if (context.isCoreInitialized()) {
      +                    CompilerDirectives.transferToInterpreterAndInvalidate();
      +                    throw new IllegalStateException("the weak reference queue was modified!");
      +                } else {
      +                    // returning a null reference queue is fine, it just means
      +                    // that the finalizer won't run
      +                    return null;
      +                }
      +            }
      +        }
      +
      +        @NeverDefault
      +        public static ReferenceTypeNode create() {
      +            return ReferenceTypeNodeFactory.create(null);
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_init, isComplex = true)
      +    @SlotSignature(name = "ref", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3)
           @GenerateNodeFactory
           public abstract static class InitNode extends PythonTernaryBuiltinNode {
               @Specialization
      @@ -115,7 +267,8 @@ public Object getCallback(PReferenceType self) {
           }
       
           // ref.__call__()
      -    @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_call, isComplex = true)
      +    @SlotSignature(minNumOfPositionalArgs = 1)
           @GenerateNodeFactory
           public abstract static class RefTypeCallNode extends PythonBuiltinNode {
               @Specialization
      @@ -125,9 +278,9 @@ public Object call(PReferenceType self) {
           }
       
           // ref.__hash__
      -    @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_hash, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class RefTypeHashNode extends PythonUnaryBuiltinNode {
      +    public abstract static class RefTypeHashNode extends HashBuiltinNode {
               static long HASH_UNSET = -1;
       
               @Specialization(guards = "self.getHash() != HASH_UNSET")
      @@ -140,28 +293,28 @@ static long computeHash(VirtualFrame frame, PReferenceType self,
                               @Bind("this") Node inliningTarget,
                               @Cached InlinedConditionProfile referentProfile,
                               @Cached PyObjectHashNode hashNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object referent = self.getObject();
                   if (referentProfile.profile(inliningTarget, referent != null)) {
                       long hash = hashNode.execute(frame, inliningTarget, referent);
                       self.setHash(hash);
                       return hash;
                   } else {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.WEAK_OBJ_GONE_AWAY);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.WEAK_OBJ_GONE_AWAY);
                   }
               }
       
               @Fallback
      -        static int hashWrong(@SuppressWarnings("unused") Object self,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, "__hash__", "weakref", self);
      +        static long hashWrong(@SuppressWarnings("unused") Object self,
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, "__hash__", "weakref", self);
               }
           }
       
           // ref.__repr__
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
      -    abstract static class RefTypeReprNode extends PythonBuiltinNode {
      +    abstract static class RefTypeReprNode extends PythonUnaryBuiltinNode {
               @Specialization(guards = "self.getObject() == null")
               static TruffleString repr(PReferenceType self,
                               @Shared("formatter") @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode) {
      @@ -193,46 +346,25 @@ private static String toStr(Object o) {
               }
           }
       
      -    // ref.__eq__
      -    @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    public abstract static class RefTypeEqNode extends PythonBuiltinNode {
      -        @Specialization(guards = {"self.getObject() != null", "other.getObject() != null"})
      -        Object eq(VirtualFrame frame, PReferenceType self, PReferenceType other,
      -                        @Cached BinaryComparisonNode.EqNode eqNode) {
      -            return eqNode.executeObject(frame, self.getObject(), other.getObject());
      -        }
      -
      -        @Specialization(guards = "self.getObject() == null || other.getObject() == null")
      -        boolean eq(PReferenceType self, PReferenceType other) {
      -            return self == other;
      -        }
      -
      -        @Fallback
      -        @SuppressWarnings("unused")
      -        Object eq(Object self, Object other) {
      -            return PNotImplemented.NOT_IMPLEMENTED;
      -        }
      -    }
      -
      -    // ref.__ne__
      -    @Builtin(name = J___NE__, minNumOfPositionalArgs = 2)
      +    // ref.__eq__ and __ne__
      +    @Slot(value = SlotKind.tp_richcompare, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class RefTypeNeNode extends PythonBuiltinNode {
      -        @Specialization(guards = {"self.getObject() != null", "other.getObject() != null"})
      -        Object ne(VirtualFrame frame, PReferenceType self, PReferenceType other,
      -                        @Cached BinaryComparisonNode.NeNode neNode) {
      -            return neNode.executeObject(frame, self.getObject(), other.getObject());
      +    public abstract static class RefTypeEqNode extends RichCmpBuiltinNode {
      +        @Specialization(guards = {"self.getObject() != null", "other.getObject() != null", "op.isEqOrNe()"})
      +        static Object withObjs(VirtualFrame frame, PReferenceType self, PReferenceType other, RichCmpOp op,
      +                        @Bind("$node") Node inliningTarget,
      +                        @Cached PyObjectRichCompare richCompareNode) {
      +            return richCompareNode.execute(frame, inliningTarget, self.getObject(), other.getObject(), op);
               }
       
      -        @Specialization(guards = "self.getObject() == null || other.getObject() == null")
      -        boolean ne(PReferenceType self, PReferenceType other) {
      -            return self != other;
      +        @Specialization(guards = {"self.getObject() == null || other.getObject() == null", "op.isEqOrNe()"})
      +        static boolean withoutObjs(PReferenceType self, PReferenceType other, RichCmpOp op) {
      +            return (self == other) == op.isEq();
               }
       
               @Fallback
               @SuppressWarnings("unused")
      -        Object eq(Object self, Object other) {
      +        static Object others(Object self, Object other, RichCmpOp op) {
                   return PNotImplemented.NOT_IMPLEMENTED;
               }
           }
      @@ -242,8 +374,8 @@ Object eq(Object self, Object other) {
           public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode {
               @Specialization
               static Object classGetItem(Object cls, Object key,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createGenericAlias(cls, key);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createGenericAlias(language, cls, key);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/reversed/ReversedBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/reversed/ReversedBuiltins.java
      index 801dfb46d2..cc94bad098 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/reversed/ReversedBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/reversed/ReversedBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2017, 2024, Oracle and/or its affiliates.
      + * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
        * Copyright (c) 2014, Regents of the University of California
        *
        * All rights reserved.
      @@ -25,46 +25,72 @@
        */
       package com.oracle.graal.python.builtins.objects.reversed;
       
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_REVERSED;
       import static com.oracle.graal.python.nodes.ErrorMessages.OBJ_HAS_NO_LEN;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LENGTH_HINT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETSTATE__;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
       import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
      +import static com.oracle.graal.python.util.PythonUtils.addExact;
      +import static com.oracle.graal.python.util.PythonUtils.multiplyExact;
      +import static com.oracle.graal.python.util.PythonUtils.negateExact;
      +import static com.oracle.graal.python.util.PythonUtils.subtractExact;
       
      +import java.math.BigInteger;
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.common.SequenceNodes;
      +import com.oracle.graal.python.builtins.objects.iterator.PBigRangeIterator;
       import com.oracle.graal.python.builtins.objects.iterator.PBuiltinIterator;
      +import com.oracle.graal.python.builtins.objects.object.PythonObject;
      +import com.oracle.graal.python.builtins.objects.range.PBigRange;
      +import com.oracle.graal.python.builtins.objects.range.PIntRange;
      +import com.oracle.graal.python.builtins.objects.str.PString;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
       import com.oracle.graal.python.lib.PyNumberAsSizeNode;
       import com.oracle.graal.python.lib.PyObjectSizeNode;
      +import com.oracle.graal.python.lib.PySequenceCheckNode;
       import com.oracle.graal.python.lib.PySequenceGetItemNode;
      +import com.oracle.graal.python.lib.PySequenceSizeNode;
      +import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
      +import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode;
       import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
      +import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
       import com.oracle.graal.python.nodes.object.GetClassNode;
      +import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
      +import com.oracle.graal.python.util.OverflowException;
      +import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      -import com.oracle.truffle.api.dsl.Cached.Exclusive;
       import com.oracle.truffle.api.dsl.Cached.Shared;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.InlinedBranchProfile;
      +import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PReverseIterator)
      @@ -75,27 +101,118 @@ public final class ReversedBuiltins extends PythonBuiltins {
            * class.
            */
       
      +    public static final TpSlots SLOTS = ReversedBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return ReversedBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    // reversed(seq)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = J_REVERSED, minNumOfPositionalArgs = 2)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class ReversedNode extends PythonBuiltinNode {
       
      -        @Specialization(guards = "self.isExhausted()")
      -        static Object exhausted(@SuppressWarnings("unused") PBuiltinIterator self,
      +        @Specialization
      +        static PythonObject reversed(@SuppressWarnings("unused") Object cls, PIntRange range,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Cached InlinedBranchProfile overflowProfile) {
      +            int lstart = range.getIntStart();
      +            int lstep = range.getIntStep();
      +            int ulen = range.getIntLength();
      +            try {
      +                int new_stop = subtractExact(lstart, lstep);
      +                int new_start = addExact(new_stop, multiplyExact(ulen, lstep));
      +                return PFactory.createIntRangeIterator(language, new_start, new_stop, negateExact(lstep), ulen);
      +            } catch (OverflowException e) {
      +                overflowProfile.enter(inliningTarget);
      +                return handleOverflow(language, lstart, lstep, ulen);
      +            }
      +        }
      +
      +        @CompilerDirectives.TruffleBoundary
      +        private static PBigRangeIterator handleOverflow(PythonLanguage language, int lstart, int lstep, int ulen) {
      +            BigInteger bstart = BigInteger.valueOf(lstart);
      +            BigInteger bstep = BigInteger.valueOf(lstep);
      +            BigInteger blen = BigInteger.valueOf(ulen);
      +            BigInteger new_stop = bstart.subtract(bstep);
      +            BigInteger new_start = new_stop.add(blen.multiply(bstep));
      +
      +            return PFactory.createBigRangeIterator(language, new_start, new_stop, bstep.negate(), blen);
      +        }
      +
      +        @Specialization
      +        @CompilerDirectives.TruffleBoundary
      +        static PythonObject reversed(@SuppressWarnings("unused") Object cls, PBigRange range) {
      +            BigInteger lstart = range.getBigIntegerStart();
      +            BigInteger lstep = range.getBigIntegerStep();
      +            BigInteger ulen = range.getBigIntegerLength();
      +
      +            BigInteger new_stop = lstart.subtract(lstep);
      +            BigInteger new_start = new_stop.add(ulen.multiply(lstep));
      +
      +            return PFactory.createBigRangeIterator(PythonLanguage.get(null), new_start, new_stop, lstep.negate(), ulen);
      +        }
      +
      +        @Specialization
      +        static PythonObject reversed(Object cls, PString value,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached CastToTruffleStringNode castToStringNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createStringReverseIterator(language, cls, getInstanceShape.execute(cls), castToStringNode.execute(inliningTarget, value));
      +        }
      +
      +        @Specialization
      +        static PythonObject reversed(Object cls, TruffleString value,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createStringReverseIterator(language, cls, getInstanceShape.execute(cls), value);
      +        }
      +
      +        @Specialization(guards = {"!isString(sequence)", "!isPRange(sequence)"})
      +        static Object reversed(VirtualFrame frame, Object cls, Object sequence,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached GetClassNode getClassNode,
      +                        @Cached("create(T___REVERSED__)") LookupSpecialMethodNode lookupReversed,
      +                        @Cached CallUnaryMethodNode callReversed,
      +                        @Cached PySequenceSizeNode pySequenceSizeNode,
      +                        @Cached InlinedConditionProfile noReversedProfile,
      +                        @Cached PySequenceCheckNode pySequenceCheck,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
                               @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raiseStopIteration();
      +            Object sequenceKlass = getClassNode.execute(inliningTarget, sequence);
      +            Object reversed = lookupReversed.execute(frame, sequenceKlass, sequence);
      +            if (noReversedProfile.profile(inliningTarget, reversed == PNone.NO_VALUE)) {
      +                if (!pySequenceCheck.execute(inliningTarget, sequence)) {
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.OBJ_ISNT_REVERSIBLE, sequence);
      +                } else {
      +                    int lengthHint = pySequenceSizeNode.execute(frame, inliningTarget, sequence);
      +                    return PFactory.createSequenceReverseIterator(language, cls, getInstanceShape.execute(cls), sequence, lengthHint);
      +                }
      +            } else {
      +                return callReversed.executeObject(frame, reversed, sequence);
      +            }
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
      +    @GenerateNodeFactory
      +    public abstract static class NextNode extends TpIterNextBuiltin {
      +
      +        @Specialization(guards = "self.isExhausted()")
      +        static Object exhausted(@SuppressWarnings("unused") PBuiltinIterator self) {
      +            throw iteratorExhausted();
               }
       
               @Specialization(guards = "!self.isExhausted()")
               static Object next(VirtualFrame frame, PSequenceReverseIterator self,
                               @Bind("this") Node inliningTarget,
                               @Cached PySequenceGetItemNode getItemNode,
      -                        @Cached IsBuiltinObjectProfile profile,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached IsBuiltinObjectProfile profile) {
                   if (self.index >= 0) {
                       try {
                           return getItemNode.execute(frame, self.getObject(), self.index--);
      @@ -104,23 +221,21 @@ static Object next(VirtualFrame frame, PSequenceReverseIterator self,
                       }
                   }
                   self.setExhausted();
      -            throw raiseNode.get(inliningTarget).raiseStopIteration();
      +            throw iteratorExhausted();
               }
       
               @Specialization(guards = "!self.isExhausted()")
               static Object next(PStringReverseIterator self,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached TruffleString.SubstringNode substringNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached TruffleString.SubstringNode substringNode) {
                   if (self.index >= 0) {
                       return substringNode.execute(self.value, self.index--, 1, TS_ENCODING, false);
                   }
                   self.setExhausted();
      -            throw raiseNode.get(inliningTarget).raiseStopIteration();
      +            throw iteratorExhausted();
               }
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
       
      @@ -148,10 +263,10 @@ static int lengthHint(PStringReverseIterator self) {
               static int lengthHint(PSequenceReverseIterator self,
                               @Bind("this") Node inliningTarget,
                               @Cached SequenceNodes.LenNode lenNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   int len = lenNode.execute(inliningTarget, self.getPSequence());
                   if (len == -1) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, OBJ_HAS_NO_LEN, self);
      +                throw raiseNode.raise(inliningTarget, TypeError, OBJ_HAS_NO_LEN, self);
                   }
                   if (len < self.index) {
                       return 0;
      @@ -179,22 +294,22 @@ public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
               static Object reduce(PStringReverseIterator self,
                               @Bind("this") Node inliningTarget,
                               @Shared("getClassNode") @Cached GetClassNode getClassNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   if (self.isExhausted()) {
      -                return reduceInternal(inliningTarget, self, "", null, getClassNode, factory);
      +                return reduceInternal(inliningTarget, self, "", null, getClassNode, language);
                   }
      -            return reduceInternal(inliningTarget, self, self.value, self.index, getClassNode, factory);
      +            return reduceInternal(inliningTarget, self, self.value, self.index, getClassNode, language);
               }
       
               @Specialization(guards = "self.isPSequence()")
               static Object reduce(PSequenceReverseIterator self,
                               @Bind("this") Node inliningTarget,
                               @Shared("getClassNode") @Cached GetClassNode getClassNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   if (self.isExhausted()) {
      -                return reduceInternal(inliningTarget, self, factory.createList(), null, getClassNode, factory);
      +                return reduceInternal(inliningTarget, self, PFactory.createList(language), null, getClassNode, language);
                   }
      -            return reduceInternal(inliningTarget, self, self.getPSequence(), self.index, getClassNode, factory);
      +            return reduceInternal(inliningTarget, self, self.getPSequence(), self.index, getClassNode, language);
               }
       
               @Specialization(guards = "!self.isPSequence()")
      @@ -202,19 +317,19 @@ static Object reduce(VirtualFrame frame, PSequenceReverseIterator self,
                               @Bind("this") Node inliningTarget,
                               @Cached("create(T___REDUCE__)") LookupAndCallUnaryNode callReduce,
                               @Shared("getClassNode") @Cached GetClassNode getClassNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object content = callReduce.executeObject(frame, self.getObject());
      -            return reduceInternal(inliningTarget, self, content, self.index, getClassNode, factory);
      +            return reduceInternal(inliningTarget, self, content, self.index, getClassNode, language);
               }
       
      -        private static PTuple reduceInternal(Node inliningTarget, Object self, Object arg, Object state, GetClassNode getClassNode, PythonObjectFactory factory) {
      +        private static PTuple reduceInternal(Node inliningTarget, Object self, Object arg, Object state, GetClassNode getClassNode, PythonLanguage language) {
                   Object revIter = getClassNode.execute(inliningTarget, self);
      -            PTuple args = factory.createTuple(new Object[]{arg});
      +            PTuple args = PFactory.createTuple(language, new Object[]{arg});
                   // callable, args, state (optional)
                   if (state != null) {
      -                return factory.createTuple(new Object[]{revIter, args, state});
      +                return PFactory.createTuple(language, new Object[]{revIter, args, state});
                   } else {
      -                return factory.createTuple(new Object[]{revIter, args});
      +                return PFactory.createTuple(language, new Object[]{revIter, args});
                   }
               }
           }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/BaseSetBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/BaseSetBuiltins.java
      index 43408ee3bb..918371c29e 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/BaseSetBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/BaseSetBuiltins.java
      @@ -41,15 +41,7 @@
       package com.oracle.graal.python.builtins.objects.set;
       
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CONTAINS__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.nodes.StringLiterals.T_COMMA_SPACE;
       import static com.oracle.graal.python.nodes.StringLiterals.T_ELLIPSIS_IN_PARENS;
       import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_PARENS;
      @@ -61,19 +53,18 @@
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.PNotImplemented;
       import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes;
       import com.oracle.graal.python.builtins.objects.common.HashingStorage;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageAreDisjoint;
      -import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageCompareKeys;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageCopy;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetIterator;
      @@ -81,30 +72,33 @@
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageIteratorKey;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageIteratorNext;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageLen;
      +import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.IsKeysSubset;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode;
      -import com.oracle.graal.python.lib.GetNextNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode;
      +import com.oracle.graal.python.lib.IteratorExhausted;
      +import com.oracle.graal.python.lib.PyIterNextNode;
       import com.oracle.graal.python.lib.PyObjectGetIter;
       import com.oracle.graal.python.lib.PyObjectGetStateNode;
       import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
      +import com.oracle.graal.python.lib.RichCmpOp;
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PNodeWithContext;
      -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.runtime.PythonContext;
      -import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
      +import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      -import com.oracle.truffle.api.dsl.Cached.Shared;
       import com.oracle.truffle.api.dsl.Fallback;
       import com.oracle.truffle.api.dsl.GenerateCached;
       import com.oracle.truffle.api.dsl.GenerateInline;
      @@ -127,7 +121,7 @@ protected List> getNodeFa
               return BaseSetBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class BaseReprNode extends PythonUnaryBuiltinNode {
               private static void fillItems(VirtualFrame frame, Node inliningTarget, HashingStorage storage, TruffleStringBuilder sb, PyObjectReprAsTruffleStringNode repr,
      @@ -190,7 +184,7 @@ public static Object repr(VirtualFrame frame, PBaseSet self,
               }
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           protected abstract static class BaseIterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -198,9 +192,9 @@ static Object doBaseSet(PBaseSet self,
                               @Bind("this") Node inliningTarget,
                               @Cached HashingStorageLen lenNode,
                               @Cached HashingStorageGetIterator getIterator,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage storage = self.getDictStorage();
      -            return factory.createBaseSetIterator(self, getIterator.execute(inliningTarget, storage), lenNode.execute(inliningTarget, storage));
      +            return PFactory.createBaseSetIterator(language, self, getIterator.execute(inliningTarget, storage), lenNode.execute(inliningTarget, storage));
               }
           }
       
      @@ -229,7 +223,7 @@ static Object reduce(VirtualFrame frame, PBaseSet self,
                               @Cached HashingStorageIteratorKey getIterKey,
                               @Cached GetClassNode getClassNode,
                               @Cached PyObjectGetStateNode getStateNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage storage = self.getDictStorage();
                   int len = lenNode.execute(inliningTarget, storage);
                   Object[] keysArray = new Object[len];
      @@ -239,32 +233,70 @@ static Object reduce(VirtualFrame frame, PBaseSet self,
                       assert hasNext;
                       keysArray[i] = getIterKey.execute(inliningTarget, storage, it);
                   }
      -            PTuple contents = factory.createTuple(new Object[]{factory.createList(keysArray)});
      +            PTuple contents = PFactory.createTuple(language, new Object[]{PFactory.createList(language, keysArray)});
                   Object state = getStateNode.execute(frame, inliningTarget, self);
      -            return factory.createTuple(new Object[]{getClassNode.execute(inliningTarget, self), contents, state});
      +            return PFactory.createTuple(language, new Object[]{getClassNode.execute(inliningTarget, self), contents, state});
               }
           }
       
      -    @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.tp_richcompare, isComplex = true)
           @GenerateNodeFactory
      -    protected abstract static class BaseEqNode extends PythonBinaryBuiltinNode {
      +    protected abstract static class BaseSetRichCmpNode extends TpSlotRichCompare.RichCmpBuiltinNode {
      +        static boolean lengthsMismatch(int len1, int len2, RichCmpOp op) {
      +            return switch (op) {
      +                case Py_EQ -> len1 != len2;
      +                case Py_LT -> len1 >= len2;
      +                case Py_GT -> len1 <= len2;
      +                case Py_LE -> len1 > len2;
      +                case Py_GE -> len1 < len2;
      +                case Py_NE -> throw CompilerDirectives.shouldNotReachHere();
      +            };
      +        }
      +
               @Specialization
      -        static boolean doSetSameType(VirtualFrame frame, PBaseSet self, PBaseSet other,
      +        static Object doIt(VirtualFrame frame, PBaseSet self, PBaseSet other, RichCmpOp opIn,
                               @Bind("this") Node inliningTarget,
      -                        @Cached HashingStorageCompareKeys compareKeys) {
      -            return compareKeys.execute(frame, inliningTarget, self.getDictStorage(), other.getDictStorage()) == 0;
      +                        @Cached HashingStorageLen lenSelfNode,
      +                        @Cached HashingStorageLen lenOtherNode,
      +                        @Cached InlinedConditionProfile sizeProfile,
      +                        @Cached IsKeysSubset issubsetNode) {
      +            boolean wasNe = opIn.isNe();
      +            RichCmpOp op = opIn;
      +            if (wasNe) {
      +                op = RichCmpOp.Py_EQ;
      +            }
      +
      +            final int len1 = lenSelfNode.execute(inliningTarget, self.getDictStorage());
      +            final int len2 = lenOtherNode.execute(inliningTarget, other.getDictStorage());
      +            if (sizeProfile.profile(inliningTarget, lengthsMismatch(len1, len2, op))) {
      +                return wasNe;
      +            }
      +
      +            PBaseSet left, right;
      +            if (op.isEq() || op.isLe() || op.isLt()) {
      +                left = self;
      +                right = other;
      +            } else {
      +                left = other;
      +                right = self;
      +            }
      +            boolean result = issubsetNode.execute(frame, inliningTarget, left.getDictStorage(), right.getDictStorage());
      +            if (wasNe) {
      +                return !result;
      +            }
      +            return result;
               }
       
               @Fallback
               @SuppressWarnings("unused")
      -        static PNotImplemented doGeneric(Object self, Object other) {
      +        static PNotImplemented doGeneric(Object self, Object other, RichCmpOp op) {
                   return PNotImplemented.NOT_IMPLEMENTED;
               }
           }
       
      -    @Builtin(name = J___CONTAINS__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.sq_contains, isComplex = true)
           @GenerateNodeFactory
      -    protected abstract static class BaseContainsNode extends PythonBinaryBuiltinNode {
      +    protected abstract static class BaseContainsNode extends SqContainsBuiltinNode {
       
               @Specialization
               static boolean contains(VirtualFrame frame, PBaseSet self, Object key,
      @@ -282,14 +314,14 @@ abstract static class CreateSetNode extends Node {
       
               @Specialization
               static PBaseSet doSet(HashingStorage storage, @SuppressWarnings("unused") PSet template,
      -                        @Shared @Cached(inline = false) PythonObjectFactory factory) {
      -            return factory.createSet(storage);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createSet(language, storage);
               }
       
               @Specialization
               static PBaseSet doFrozenSet(HashingStorage storage, @SuppressWarnings("unused") PFrozenSet template,
      -                        @Shared @Cached(inline = false) PythonObjectFactory factory) {
      -            return factory.createFrozenSet(storage);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createFrozenSet(language, storage);
               }
           }
       
      @@ -392,9 +424,9 @@ protected abstract static class BaseIsSubsetNode extends PythonBinaryBuiltinNode
               static boolean isSubSetGeneric(VirtualFrame frame, PBaseSet self, Object other,
                               @Bind("this") Node inliningTarget,
                               @Cached HashingCollectionNodes.GetSetStorageNode getSetStorageNode,
      -                        @Cached HashingStorageCompareKeys compareKeys) {
      +                        @Cached IsKeysSubset compareKeys) {
                   HashingStorage otherStorage = getSetStorageNode.execute(frame, inliningTarget, other);
      -            return compareKeys.execute(frame, inliningTarget, self.getDictStorage(), otherStorage) <= 0;
      +            return compareKeys.execute(frame, inliningTarget, self.getDictStorage(), otherStorage);
               }
           }
       
      @@ -405,9 +437,9 @@ protected abstract static class BaseIsSupersetNode extends PythonBinaryBuiltinNo
               static boolean isSuperSetGeneric(VirtualFrame frame, PBaseSet self, Object other,
                               @Bind("this") Node inliningTarget,
                               @Cached HashingCollectionNodes.GetSetStorageNode getSetStorageNode,
      -                        @Cached HashingStorageCompareKeys compareKeys) {
      +                        @Cached HashingStorageNodes.IsKeysSubset compareKeys) {
                   HashingStorage otherStorage = getSetStorageNode.execute(frame, inliningTarget, other);
      -            return compareKeys.execute(frame, inliningTarget, otherStorage, self.getDictStorage()) <= 0;
      +            return compareKeys.execute(frame, inliningTarget, otherStorage, self.getDictStorage());
               }
       
           }
      @@ -435,114 +467,27 @@ static boolean isDisjointGeneric(VirtualFrame frame, Object self, Object other,
                               @Bind("this") Node inliningTarget,
                               @Cached HashingStorageGetItem getHashingStorageItem,
                               @Cached PyObjectGetIter getIter,
      -                        @Cached GetNextNode getNextNode,
      -                        @Cached IsBuiltinObjectProfile errorProfile) {
      +                        @Cached PyIterNextNode nextNode) {
                   HashingStorage selfStorage = ((PBaseSet) self).getDictStorage();
                   Object iterator = getIter.execute(frame, inliningTarget, other);
                   while (true) {
      +                Object nextValue;
                       try {
      -                    Object nextValue = getNextNode.execute(frame, iterator);
      -                    if (getHashingStorageItem.hasKey(frame, inliningTarget, selfStorage, nextValue)) {
      -                        return false;
      -                    }
      -                } catch (PException e) {
      -                    e.expectStopIteration(inliningTarget, errorProfile);
      +                    nextValue = nextNode.execute(frame, inliningTarget, iterator);
      +                } catch (IteratorExhausted e) {
                           return true;
                       }
      +                if (getHashingStorageItem.hasKey(frame, inliningTarget, selfStorage, nextValue)) {
      +                    return false;
      +                }
                   }
               }
       
           }
       
      -    @Builtin(name = J___LE__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    protected abstract static class BaseLessEqualNode extends PythonBinaryBuiltinNode {
      -        @Specialization
      -        static boolean doLE(VirtualFrame frame, PBaseSet self, PBaseSet other,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached HashingStorageCompareKeys compareKeys) {
      -            return compareKeys.execute(frame, inliningTarget, self.getDictStorage(), other.getDictStorage()) <= 0;
      -        }
      -
      -        @Fallback
      -        @SuppressWarnings("unused")
      -        static PNotImplemented doNotImplemented(Object self, Object other) {
      -            return PNotImplemented.NOT_IMPLEMENTED;
      -        }
      -    }
      -
      -    @Builtin(name = J___GE__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    protected abstract static class BaseGreaterEqualNode extends PythonBinaryBuiltinNode {
      -        @Specialization
      -        static boolean doGE(VirtualFrame frame, PBaseSet self, PBaseSet other,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached HashingStorageCompareKeys compareKeys) {
      -            return compareKeys.execute(frame, inliningTarget, other.getDictStorage(), self.getDictStorage()) <= 0;
      -        }
      -
      -        @Fallback
      -        @SuppressWarnings("unused")
      -        static PNotImplemented doNotImplemented(Object self, Object other) {
      -            return PNotImplemented.NOT_IMPLEMENTED;
      -        }
      -    }
      -
      -    @Builtin(name = J___LT__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    protected abstract static class BaseLessThanNode extends PythonBinaryBuiltinNode {
      -
      -        @Specialization
      -        static boolean isLessThan(VirtualFrame frame, PBaseSet self, PBaseSet other,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached HashingStorageLen lenSelfNode,
      -                        @Cached HashingStorageLen lenOtherNode,
      -                        @Cached HashingStorageCompareKeys compareKeys,
      -                        @Cached InlinedConditionProfile sizeProfile) {
      -            final int len1 = lenSelfNode.execute(inliningTarget, self.getDictStorage());
      -            final int len2 = lenOtherNode.execute(inliningTarget, other.getDictStorage());
      -            if (sizeProfile.profile(inliningTarget, len1 >= len2)) {
      -                return false;
      -            }
      -            return BaseLessEqualNode.doLE(frame, self, other, inliningTarget, compareKeys);
      -        }
      -
      -        @Fallback
      -        @SuppressWarnings("unused")
      -        static PNotImplemented doNotImplemented(Object self, Object other) {
      -            return PNotImplemented.NOT_IMPLEMENTED;
      -        }
      -    }
      -
      -    @Builtin(name = J___GT__, minNumOfPositionalArgs = 2)
      -    @GenerateNodeFactory
      -    protected abstract static class BaseGreaterThanNode extends PythonBinaryBuiltinNode {
      -
      -        @Specialization
      -        static boolean isGreaterThan(VirtualFrame frame, PBaseSet self, PBaseSet other,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached HashingStorageLen aLenNode,
      -                        @Cached HashingStorageLen bLenNode,
      -                        @Cached HashingStorageCompareKeys compareKeys,
      -                        @Cached InlinedConditionProfile sizeProfile) {
      -            final int len1 = aLenNode.execute(inliningTarget, self.getDictStorage());
      -            final int len2 = bLenNode.execute(inliningTarget, other.getDictStorage());
      -            if (sizeProfile.profile(inliningTarget, len1 <= len2)) {
      -                return false;
      -            }
      -            return BaseGreaterEqualNode.doGE(frame, self, other, inliningTarget, compareKeys);
      -        }
      -
      -        @Fallback
      -        @SuppressWarnings("unused")
      -        static PNotImplemented doNotImplemented(Object self, Object other) {
      -            return PNotImplemented.NOT_IMPLEMENTED;
      -        }
      -    }
      -
           @GenerateInline
           @GenerateCached(false)
      -    @ImportStatic({PGuards.class, SpecialMethodSlot.class})
      +    @ImportStatic(PGuards.class)
           protected abstract static class ConvertKeyNode extends PNodeWithContext {
               public abstract Object execute(Node inliningTarget, Object key);
       
      @@ -554,12 +499,15 @@ static Object doNotPSet(Object key) {
               @Specialization
               static Object doPSet(Node inliningTarget, PSet key,
                               @Cached HashingStorageCopy copyNode,
      -                        @Cached GetClassNode getClassNode,
      -                        @Cached(parameters = "Hash", inline = false) LookupCallableSlotInMRONode lookupHash,
      -                        @Cached PythonObjectFactory.Lazy factory) {
      -            Object hashDescr = lookupHash.execute(getClassNode.execute(inliningTarget, key));
      -            if (hashDescr instanceof PNone) {
      -                return factory.get(inliningTarget).createFrozenSet(copyNode.execute(inliningTarget, key.getDictStorage()));
      +                        @Cached GetObjectSlotsNode getSlotsNode) {
      +            // This follows the logic in CPython's setobject.c:set_contains
      +            // TODO: CPython first tries the search and only if it gets back TypeError and the key
      +            // type is set, then it transforms it to frozenset. The issue is that the TypeError can
      +            // come from the tp_hash implementation or from the tp_richcompare also called during
      +            // the search
      +            TpSlots slots = getSlotsNode.execute(inliningTarget, key);
      +            if (slots.tp_hash() == null || slots.tp_hash() == TpSlotHashFun.HASH_NOT_IMPLEMENTED) {
      +                return PFactory.createFrozenSet(PythonLanguage.get(inliningTarget), copyNode.execute(inliningTarget, key.getDictStorage()));
                   } else {
                       return key;
                   }
      @@ -571,8 +519,8 @@ static Object doPSet(Node inliningTarget, PSet key,
           public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode {
               @Specialization
               static Object classGetItem(Object cls, Object key,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createGenericAlias(cls, key);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createGenericAlias(language, cls, key);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/FrozenSetBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/FrozenSetBuiltins.java
      index ecee481ff7..f4beb6e2c3 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/FrozenSetBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/FrozenSetBuiltins.java
      @@ -25,19 +25,24 @@
        */
       package com.oracle.graal.python.builtins.objects.set;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__;
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_FROZENSET;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
      -import com.oracle.graal.python.builtins.objects.PNotImplemented;
      +import com.oracle.graal.python.builtins.objects.common.EmptyStorage;
       import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes;
       import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes.GetSetStorageNode;
       import com.oracle.graal.python.builtins.objects.common.HashingStorage;
      +import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageAddAllToOther;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageCopy;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageDiff;
      @@ -47,17 +52,20 @@
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageIteratorKey;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageIteratorNext;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageXor;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode;
       import com.oracle.graal.python.lib.PyObjectHashNode;
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsAnyBuiltinObjectProfile;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.nodes.object.BuiltinClassProfiles;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Cached.Shared;
      -import com.oracle.truffle.api.dsl.Fallback;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
      @@ -69,26 +77,68 @@
        */
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PFrozenSet})
       public final class FrozenSetBuiltins extends PythonBuiltins {
      +    public static final TpSlots SLOTS = FrozenSetBuiltinsSlotsGen.SLOTS;
       
           @Override
           protected List> getNodeFactories() {
               return FrozenSetBuiltinsFactory.getFactories();
           }
       
      +    // frozenset([iterable])
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = J_FROZENSET, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2)
      +    @GenerateNodeFactory
      +    public abstract static class FrozenSetNode extends PythonBinaryBuiltinNode {
      +
      +        @Specialization(guards = "isNoValue(arg)")
      +        static PFrozenSet frozensetEmpty(Object cls, @SuppressWarnings("unused") PNone arg,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createFrozenSet(language, cls, getInstanceShape.execute(cls), EmptyStorage.INSTANCE);
      +        }
      +
      +        @Specialization(guards = "isBuiltinClass.profileIsAnyBuiltinClass(inliningTarget, cls)")
      +        static PFrozenSet frozensetIdentity(@SuppressWarnings("unused") Object cls, PFrozenSet arg,
      +                        @SuppressWarnings("unused") @Bind("this") Node inliningTarget,
      +                        @Shared("isBuiltinProfile") @SuppressWarnings("unused") @Cached BuiltinClassProfiles.IsAnyBuiltinClassProfile isBuiltinClass) {
      +            return arg;
      +        }
      +
      +        @Specialization(guards = "!isBuiltinClass.profileIsAnyBuiltinClass(inliningTarget, cls)")
      +        static PFrozenSet subFrozensetIdentity(Object cls, PFrozenSet arg,
      +                        @SuppressWarnings("unused") @Bind("this") Node inliningTarget,
      +                        @Shared("isBuiltinProfile") @SuppressWarnings("unused") @Cached BuiltinClassProfiles.IsAnyBuiltinClassProfile isBuiltinClass,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createFrozenSet(language, cls, getInstanceShape.execute(cls), arg.getDictStorage());
      +        }
      +
      +        @Specialization(guards = {"!isNoValue(iterable)", "!isPFrozenSet(iterable)"})
      +        static PFrozenSet frozensetIterable(VirtualFrame frame, Object cls, Object iterable,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached HashingCollectionNodes.GetClonedHashingStorageNode getHashingStorageNode,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            HashingStorage storage = getHashingStorageNode.getForSets(frame, inliningTarget, iterable);
      +            return PFactory.createFrozenSet(language, cls, getInstanceShape.execute(cls), storage);
      +        }
      +    }
      +
           @Builtin(name = "copy", minNumOfPositionalArgs = 1)
           @GenerateNodeFactory
           public abstract static class CopyNode extends PythonUnaryBuiltinNode {
       
      -        @Specialization
      -        static PFrozenSet subFrozensetIdentity(PFrozenSet arg,
      +        @Specialization(guards = "isBuiltinFrozenSet(self)")
      +        static PFrozenSet frozenSetIdentity(PFrozenSet self) {
      +            return self;
      +        }
      +
      +        @Specialization(guards = "!isBuiltinFrozenSet(self)")
      +        static PFrozenSet doGeneric(PFrozenSet self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached IsAnyBuiltinObjectProfile isBuiltinClass,
      -                        @Cached PythonObjectFactory.Lazy factory) {
      -            if (isBuiltinClass.profileIsAnyBuiltinObject(inliningTarget, arg)) {
      -                return arg;
      -            } else {
      -                return factory.get(inliningTarget).createFrozenSet(arg.getDictStorage());
      -            }
      +                        @Bind PythonLanguage language,
      +                        @Cached HashingStorageNodes.HashingStorageCopy copy) {
      +            return PFactory.createFrozenSet(language, copy.execute(inliningTarget, self.getDictStorage()));
               }
           }
       
      @@ -98,8 +148,8 @@ public abstract static class IntersectNode extends PythonBuiltinNode {
       
               @Specialization(guards = "isNoValue(other)")
               static PFrozenSet doSet(@SuppressWarnings("unused") VirtualFrame frame, PFrozenSet self, @SuppressWarnings("unused") PNone other,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createFrozenSet(self.getDictStorage());
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createFrozenSet(language, self.getDictStorage());
               }
       
               @Specialization(guards = {"args.length == len", "args.length < 32"}, limit = "3")
      @@ -109,12 +159,12 @@ static PBaseSet doCached(VirtualFrame frame, PFrozenSet self, Object[] args,
                               @Shared @Cached HashingCollectionNodes.GetSetStorageNode getSetStorageNode,
                               @Shared @Cached HashingStorageCopy copyNode,
                               @Shared @Cached HashingStorageIntersect intersectNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = copyNode.execute(inliningTarget, self.getDictStorage());
                   for (int i = 0; i < len; i++) {
                       result = intersectNode.execute(frame, inliningTarget, result, getSetStorageNode.execute(frame, inliningTarget, args[i]));
                   }
      -            return factory.createFrozenSet(result);
      +            return PFactory.createFrozenSet(language, result);
               }
       
               @Specialization(replaces = "doCached")
      @@ -123,12 +173,12 @@ static PBaseSet doGeneric(VirtualFrame frame, PFrozenSet self, Object[] args,
                               @Shared @Cached GetSetStorageNode getSetStorageNode,
                               @Shared @Cached HashingStorageCopy copyNode,
                               @Shared @Cached HashingStorageIntersect intersectNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = copyNode.execute(inliningTarget, self.getDictStorage());
                   for (int i = 0; i < args.length; i++) {
                       result = intersectNode.execute(frame, inliningTarget, result, getSetStorageNode.execute(frame, inliningTarget, args[i]));
                   }
      -            return factory.createFrozenSet(result);
      +            return PFactory.createFrozenSet(language, result);
               }
       
               static boolean isOther(Object arg) {
      @@ -140,9 +190,9 @@ static PFrozenSet doSet(@SuppressWarnings("unused") VirtualFrame frame, PFrozenS
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached HashingCollectionNodes.GetSetStorageNode getSetStorageNode,
                               @Shared @Cached HashingStorageIntersect intersectNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = intersectNode.execute(frame, inliningTarget, self.getDictStorage(), getSetStorageNode.execute(frame, inliningTarget, other));
      -            return factory.createFrozenSet(result);
      +            return PFactory.createFrozenSet(language, result);
               }
           }
       
      @@ -155,9 +205,9 @@ static PFrozenSet doSet(@SuppressWarnings("unused") VirtualFrame frame, PFrozenS
                               @Bind("this") Node inliningTarget,
                               @Cached HashingCollectionNodes.GetSetStorageNode getHashingStorage,
                               @Cached HashingStorageXor xorNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = xorNode.execute(frame, inliningTarget, self.getDictStorage(), getHashingStorage.execute(frame, inliningTarget, other));
      -            return factory.createFrozenSet(result);
      +            return PFactory.createFrozenSet(language, result);
               }
           }
       
      @@ -167,8 +217,8 @@ public abstract static class DifferenceNode extends PythonBuiltinNode {
       
               @Specialization(guards = "isNoValue(other)")
               static PFrozenSet doSet(@SuppressWarnings("unused") VirtualFrame frame, PFrozenSet self, @SuppressWarnings("unused") PNone other,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createFrozenSet(self.getDictStorage());
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createFrozenSet(language, self.getDictStorage());
               }
       
               @Specialization(guards = {"args.length == len", "args.length < 32"}, limit = "3")
      @@ -178,12 +228,12 @@ static PBaseSet doCached(VirtualFrame frame, PFrozenSet self, Object[] args,
                               @Shared @Cached HashingCollectionNodes.GetSetStorageNode getSetStorageNode,
                               @Shared @Cached HashingStorageCopy copyNode,
                               @Shared @Cached HashingStorageDiff diffNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = copyNode.execute(inliningTarget, self.getDictStorage());
                   for (int i = 0; i < len; i++) {
                       result = diffNode.execute(frame, inliningTarget, result, getSetStorageNode.execute(frame, inliningTarget, args[i]));
                   }
      -            return factory.createFrozenSet(result);
      +            return PFactory.createFrozenSet(language, result);
               }
       
               @Specialization(replaces = "doCached")
      @@ -192,12 +242,12 @@ static PBaseSet doGeneric(VirtualFrame frame, PFrozenSet self, Object[] args,
                               @Shared @Cached HashingCollectionNodes.GetSetStorageNode getSetStorageNode,
                               @Shared @Cached HashingStorageCopy copyNode,
                               @Shared @Cached HashingStorageDiff diffNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = copyNode.execute(inliningTarget, self.getDictStorage());
                   for (int i = 0; i < args.length; i++) {
                       result = diffNode.execute(frame, inliningTarget, result, getSetStorageNode.execute(frame, inliningTarget, args[i]));
                   }
      -            return factory.createFrozenSet(result);
      +            return PFactory.createFrozenSet(language, result);
               }
       
               static boolean isOther(Object arg) {
      @@ -209,9 +259,9 @@ static PFrozenSet doSet(@SuppressWarnings("unused") VirtualFrame frame, PFrozenS
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached GetSetStorageNode getSetStorageNode,
                               @Shared @Cached HashingStorageDiff diffNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = diffNode.execute(frame, inliningTarget, self.getDictStorage(), getSetStorageNode.execute(frame, inliningTarget, other));
      -            return factory.createFrozenSet(result);
      +            return PFactory.createFrozenSet(language, result);
               }
           }
       
      @@ -226,12 +276,12 @@ static PBaseSet doCached(VirtualFrame frame, PBaseSet self, Object[] args,
                               @Shared @Cached GetSetStorageNode getHashingStorage,
                               @Shared @Cached HashingStorageCopy copyNode,
                               @Shared @Cached HashingStorageAddAllToOther addAllToOther,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = copyNode.execute(inliningTarget, self.getDictStorage());
                   for (int i = 0; i < len; i++) {
                       result = addAllToOther.execute(frame, inliningTarget, getHashingStorage.execute(frame, inliningTarget, args[i]), result);
                   }
      -            return factory.createFrozenSet(result);
      +            return PFactory.createFrozenSet(language, result);
               }
       
               @Specialization(replaces = "doCached")
      @@ -240,18 +290,18 @@ static PBaseSet doGeneric(VirtualFrame frame, PBaseSet self, Object[] args,
                               @Shared @Cached GetSetStorageNode getHashingStorage,
                               @Shared @Cached HashingStorageCopy copyNode,
                               @Shared @Cached HashingStorageAddAllToOther addAllToOther,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = copyNode.execute(inliningTarget, self.getDictStorage());
                   for (int i = 0; i < args.length; i++) {
                       result = addAllToOther.execute(frame, inliningTarget, getHashingStorage.execute(frame, inliningTarget, args[i]), result);
                   }
      -            return factory.createFrozenSet(result);
      +            return PFactory.createFrozenSet(language, result);
               }
           }
       
      -    @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_hash, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class HashNode extends PythonUnaryBuiltinNode {
      +    public abstract static class HashNode extends HashBuiltinNode {
               protected static long HASH_UNSET = -1;
       
               @Specialization(guards = {"self.getHash() != HASH_UNSET"})
      @@ -308,10 +358,5 @@ public static long computeHash(VirtualFrame frame, PFrozenSet self,
               private static long shuffleBits(long value) {
                   return ((value ^ 0x55b4db3) ^ (value << 16)) * 0xd93f34d7;
               }
      -
      -        @Fallback
      -        static Object genericHash(@SuppressWarnings("unused") Object self) {
      -            return PNotImplemented.NOT_IMPLEMENTED;
      -        }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/SetBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/SetBuiltins.java
      index a789168129..baf225ebf0 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/SetBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/SetBuiltins.java
      @@ -26,16 +26,16 @@
       package com.oracle.graal.python.builtins.objects.set;
       
       import static com.oracle.graal.python.nodes.BuiltinNames.J_ADD;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IAND__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IOR__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ISUB__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___IXOR__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__;
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_SET;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.HashNotImplemented;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.Python3Core;
      @@ -60,7 +60,10 @@
       import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
       import com.oracle.graal.python.builtins.objects.dict.PDictView;
       import com.oracle.graal.python.builtins.objects.str.PString;
      -import com.oracle.graal.python.lib.GetNextNode;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
      +import com.oracle.graal.python.lib.IteratorExhausted;
      +import com.oracle.graal.python.lib.PyIterNextNode;
       import com.oracle.graal.python.lib.PyObjectGetIter;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PGuards;
      @@ -70,12 +73,10 @@
       import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
       import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode;
       import com.oracle.graal.python.runtime.PythonOptions;
      -import com.oracle.graal.python.runtime.exception.PException;
       import com.oracle.graal.python.runtime.exception.PythonErrorType;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.runtime.sequence.PSequence;
       import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
       import com.oracle.truffle.api.dsl.Bind;
      @@ -98,12 +99,13 @@
        * binary operations are implemented in {@link BaseSetBuiltins}
        */
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PSet)
      +@HashNotImplemented
       public final class SetBuiltins extends PythonBuiltins {
      +    public static final TpSlots SLOTS = SetBuiltinsSlotsGen.SLOTS;
       
           @Override
           public void initialize(Python3Core core) {
               super.initialize(core);
      -        addBuiltinConstant(T___HASH__, PNone.NONE);
           }
       
           @Override
      @@ -111,7 +113,31 @@ protected List> getNodeFa
               return SetBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2)
      +    // set([iterable])
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = J_SET, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class SetNode extends PythonBuiltinNode {
      +        @Specialization(guards = "isBuiltinSet(cls)")
      +        public PSet setEmpty(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") Object arg,
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createSet(language);
      +        }
      +
      +        @Fallback
      +        public PSet setEmpty(Object cls, @SuppressWarnings("unused") Object arg,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createSet(language, cls, getInstanceShape.execute(cls));
      +        }
      +
      +        protected static boolean isBuiltinSet(Object cls) {
      +            return cls == PythonBuiltinClassType.PSet;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_init, isComplex = true)
      +    @SlotSignature(name = "set", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2)
           @GenerateNodeFactory
           @ImportStatic(PGuards.class)
           public abstract static class InitNode extends PythonBuiltinNode {
      @@ -129,15 +155,15 @@ static PNone doNoValue(PSet self, @SuppressWarnings("unused") PNone iterable,
               static PNone doGeneric(VirtualFrame frame, PSet self, Object iterable,
                               @Bind("this") Node inliningTarget,
                               @Cached HashingCollectionNodes.GetClonedHashingStorageNode getHashingStorageNode) {
      -            HashingStorage storage = getHashingStorageNode.doNoValue(frame, inliningTarget, iterable);
      +            HashingStorage storage = getHashingStorageNode.getForSets(frame, inliningTarget, iterable);
                   self.setDictStorage(storage);
                   return PNone.NONE;
               }
       
               @Fallback
               static PNone fail(@SuppressWarnings("unused") VirtualFrame frame, @SuppressWarnings("unused") Object self, Object iterable,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.SET_DOES_NOT_SUPPORT_ITERABLE_OBJ, iterable);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.SET_DOES_NOT_SUPPORT_ITERABLE_OBJ, iterable);
               }
           }
       
      @@ -149,8 +175,8 @@ public abstract static class CopyNode extends PythonBuiltinNode {
               static PSet doSet(PSet self,
                               @Bind("this") Node inliningTarget,
                               @Cached HashingStorageCopy copyNode,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createSet(copyNode.execute(inliningTarget, self.getDictStorage()));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createSet(language, copyNode.execute(inliningTarget, self.getDictStorage()));
               }
           }
       
      @@ -180,7 +206,7 @@ public static Object add(VirtualFrame frame, PSet self, Object o,
               }
           }
       
      -    @Builtin(name = J___IOR__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.nb_inplace_or, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IOrNode extends PythonBinaryBuiltinNode {
               @Specialization
      @@ -209,12 +235,12 @@ static PBaseSet doCached(VirtualFrame frame, PSet self, Object[] args,
                               @Shared @Cached HashingCollectionNodes.GetSetStorageNode getSetStorageNode,
                               @Shared @Cached HashingStorageCopy copyNode,
                               @Shared @Cached HashingStorageAddAllToOther addAllToOther,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = copyNode.execute(inliningTarget, self.getDictStorage());
                   for (int i = 0; i < len; i++) {
                       result = addAllToOther.execute(frame, inliningTarget, getSetStorageNode.execute(frame, inliningTarget, args[i]), result);
                   }
      -            return factory.createSet(result);
      +            return PFactory.createSet(language, result);
               }
       
               @Specialization(replaces = "doCached")
      @@ -223,12 +249,12 @@ static PBaseSet doGeneric(VirtualFrame frame, PSet self, Object[] args,
                               @Shared @Cached HashingCollectionNodes.GetSetStorageNode getSetStorageNode,
                               @Shared @Cached HashingStorageCopy copyNode,
                               @Shared @Cached HashingStorageAddAllToOther addAllToOther,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = copyNode.execute(inliningTarget, self.getDictStorage());
                   for (int i = 0; i < args.length; i++) {
                       result = addAllToOther.execute(frame, inliningTarget, getSetStorageNode.execute(frame, inliningTarget, args[i]), result);
                   }
      -            return factory.createSet(result);
      +            return PFactory.createSet(language, result);
               }
           }
       
      @@ -282,17 +308,15 @@ static void doIterable(VirtualFrame frame, PHashingCollection collection, Object
                               @Bind("this") Node inliningTarget,
                               @SuppressWarnings("unused") @Exclusive @Cached GetPythonObjectClassNode getClassNode,
                               @Cached PyObjectGetIter getIter,
      -                        @Cached GetNextNode nextNode,
      -                        @Cached IsBuiltinObjectProfile errorProfile,
      +                        @Cached PyIterNextNode nextNode,
                               @Exclusive @Cached HashingStorageSetItem setStorageItem) {
                   HashingStorage curStorage = collection.getDictStorage();
                   Object iterator = getIter.execute(frame, inliningTarget, other);
                   while (true) {
                       Object key;
                       try {
      -                    key = nextNode.execute(frame, iterator);
      -                } catch (PException e) {
      -                    e.expectStopIteration(inliningTarget, errorProfile);
      +                    key = nextNode.execute(frame, inliningTarget, iterator);
      +                } catch (IteratorExhausted e) {
                           collection.setDictStorage(curStorage);
                           return;
                       }
      @@ -368,7 +392,7 @@ static PNone doSet(VirtualFrame frame, PSet self, Object other,
               }
           }
       
      -    @Builtin(name = J___IAND__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.nb_inplace_and, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IAndNode extends PythonBinaryBuiltinNode {
       
      @@ -405,10 +429,9 @@ public abstract static class IntersectNode extends PythonBuiltinNode {
               @Specialization(guards = "isNoValue(other)")
               Object doSet(@SuppressWarnings("unused") VirtualFrame frame, PSet self, @SuppressWarnings("unused") PNone other,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached HashingStorageCopy copyNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Shared @Cached HashingStorageCopy copyNode) {
                   HashingStorage result = copyNode.execute(inliningTarget, self.getDictStorage());
      -            return createResult(self, result, factory);
      +            return createResult(self, result);
               }
       
               @Specialization(guards = {"args.length == len", "args.length < 32"}, limit = "3")
      @@ -417,13 +440,12 @@ Object doCached(VirtualFrame frame, PSet self, Object[] args,
                               @Cached("args.length") int len,
                               @Shared @Cached HashingCollectionNodes.GetSetStorageNode getSetStorageNode,
                               @Shared @Cached HashingStorageCopy copyNode,
      -                        @Shared @Cached HashingStorageIntersect intersectNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Shared @Cached HashingStorageIntersect intersectNode) {
                   HashingStorage result = copyNode.execute(inliningTarget, self.getDictStorage());
                   for (int i = 0; i < len; i++) {
                       result = intersectNode.execute(frame, inliningTarget, result, getSetStorageNode.execute(frame, inliningTarget, args[i]));
                   }
      -            return createResult(self, result, factory);
      +            return createResult(self, result);
               }
       
               @Specialization(replaces = "doCached")
      @@ -431,13 +453,12 @@ Object doGeneric(VirtualFrame frame, PSet self, Object[] args,
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached HashingCollectionNodes.GetSetStorageNode getSetStorageNode,
                               @Shared @Cached HashingStorageCopy copyNode,
      -                        @Shared @Cached HashingStorageIntersect intersectNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Shared @Cached HashingStorageIntersect intersectNode) {
                   HashingStorage result = copyNode.execute(inliningTarget, self.getDictStorage());
                   for (int i = 0; i < args.length; i++) {
                       result = intersectNode.execute(frame, inliningTarget, result, getSetStorageNode.execute(frame, inliningTarget, args[i]));
                   }
      -            return createResult(self, result, factory);
      +            return createResult(self, result);
               }
       
               static boolean isOther(Object arg) {
      @@ -450,14 +471,14 @@ Object doSet(VirtualFrame frame, PSet self, Object other,
                               @Shared @Cached GetSetStorageNode getSetStorageNode,
                               @Shared @Cached HashingStorageCopy copyNode,
                               @Shared @Cached HashingStorageIntersect intersectNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = copyNode.execute(inliningTarget, self.getDictStorage());
                   result = intersectNode.execute(frame, inliningTarget, result, getSetStorageNode.execute(frame, inliningTarget, other));
      -            return createResult(self, result, factory);
      +            return PFactory.createSet(language, result);
               }
       
      -        protected Object createResult(PSet self, HashingStorage result, PythonObjectFactory factory) {
      -            return factory.createSet(result);
      +        protected Object createResult(PSet self, HashingStorage result) {
      +            return PFactory.createSet(PythonLanguage.get(this), result);
               }
           }
       
      @@ -465,15 +486,14 @@ protected Object createResult(PSet self, HashingStorage result, PythonObjectFact
           @GenerateNodeFactory
           @ImportStatic({SpecialMethodNames.class})
           public abstract static class IntersectUpdateNode extends IntersectNode {
      -        @Override
      -        protected Object createResult(PSet self, HashingStorage result, PythonObjectFactory factory) {
      +        protected Object createResult(PSet self, HashingStorage result) {
                   // In order to be compatible w.r.t. __eq__ calls we cannot reuse self storage
                   self.setDictStorage(result);
                   return PNone.NONE;
               }
           }
       
      -    @Builtin(name = J___IXOR__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.nb_inplace_xor, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IXorNode extends PythonBinaryBuiltinNode {
       
      @@ -501,9 +521,9 @@ static PSet doSet(VirtualFrame frame, PSet self, Object other,
                               @Bind("this") Node inliningTarget,
                               @Cached GetSetStorageNode getHashingStorage,
                               @Cached HashingStorageXor xorNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = xorNode.execute(frame, inliningTarget, self.getDictStorage(), getHashingStorage.execute(frame, inliningTarget, other));
      -            return factory.createSet(result);
      +            return PFactory.createSet(language, result);
               }
           }
       
      @@ -559,7 +579,7 @@ static PNone doSetOther(VirtualFrame frame, PSet self, Object other,
               }
           }
       
      -    @Builtin(name = J___ISUB__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.nb_inplace_subtract, isComplex = true)
           @GenerateNodeFactory
           abstract static class ISubNode extends PythonBinaryBuiltinNode {
               @Specialization
      @@ -584,8 +604,8 @@ public abstract static class DifferenceNode extends PythonBuiltinNode {
       
               @Specialization(guards = "isNoValue(other)")
               static PSet doSet(@SuppressWarnings("unused") VirtualFrame frame, PSet self, @SuppressWarnings("unused") PNone other,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createSet(self.getDictStorage());
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createSet(language, self.getDictStorage());
               }
       
               @Specialization(guards = {"args.length == len", "args.length < 32"}, limit = "3")
      @@ -595,12 +615,12 @@ static PBaseSet doCached(VirtualFrame frame, PSet self, Object[] args,
                               @Shared @Cached HashingCollectionNodes.GetSetStorageNode getSetStorageNode,
                               @Shared @Cached HashingStorageCopy copyNode,
                               @Shared @Cached HashingStorageDiff diffNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = copyNode.execute(inliningTarget, self.getDictStorage());
                   for (int i = 0; i < len; i++) {
                       result = diffNode.execute(frame, inliningTarget, result, getSetStorageNode.execute(frame, inliningTarget, args[i]));
                   }
      -            return factory.createSet(result);
      +            return PFactory.createSet(language, result);
               }
       
               @Specialization(replaces = "doCached")
      @@ -609,12 +629,12 @@ static PBaseSet doGeneric(VirtualFrame frame, PSet self, Object[] args,
                               @Shared @Cached GetSetStorageNode getSetStorageNode,
                               @Shared @Cached HashingStorageCopy copyNode,
                               @Shared @Cached HashingStorageDiff diffNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = copyNode.execute(inliningTarget, self.getDictStorage());
                   for (int i = 0; i < args.length; i++) {
                       result = diffNode.execute(frame, inliningTarget, result, getSetStorageNode.execute(frame, inliningTarget, args[i]));
                   }
      -            return factory.createSet(result);
      +            return PFactory.createSet(language, result);
               }
       
               static boolean isOther(Object arg) {
      @@ -626,9 +646,9 @@ static PSet doSet(VirtualFrame frame, PSet self, Object other,
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached GetSetStorageNode getSetStorageNode,
                               @Shared @Cached HashingStorageDiff diffNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   HashingStorage result = diffNode.execute(frame, inliningTarget, self.getDictStorage(), getSetStorageNode.execute(frame, inliningTarget, other));
      -            return factory.createSet(result);
      +            return PFactory.createSet(language, result);
               }
           }
       
      @@ -687,9 +707,9 @@ abstract static class RemoveNode extends PythonBinaryBuiltinNode {
               static Object remove(VirtualFrame frame, PSet self, Object key,
                               @Bind("this") Node inliningTarget,
                               @Cached com.oracle.graal.python.builtins.objects.set.SetNodes.DiscardNode discardNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (!discardNode.execute(frame, self, key)) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.KeyError, new Object[]{key});
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.KeyError, new Object[]{key});
                   }
                   return PNone.NONE;
               }
      @@ -713,13 +733,12 @@ public abstract static class PopNode extends PythonUnaryBuiltinNode {
               static Object remove(PSet self,
                               @Bind("this") Node inliningTarget,
                               @Cached HashingStoragePop popNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object[] result = popNode.execute(inliningTarget, self.getDictStorage(), self);
                   if (result != null) {
                       return result[0];
                   }
      -            throw raiseNode.get(inliningTarget).raise(PythonErrorType.KeyError, ErrorMessages.POP_FROM_EMPTY_SET);
      +            throw raiseNode.raise(inliningTarget, PythonErrorType.KeyError, ErrorMessages.POP_FROM_EMPTY_SET);
               }
           }
      -
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/SetNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/SetNodes.java
      index aa6dbc34b0..137c1d2b66 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/SetNodes.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/SetNodes.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -41,21 +41,20 @@
       package com.oracle.graal.python.builtins.objects.set;
       
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
      -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
       
      -import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageDelItem;
      -import com.oracle.graal.python.lib.GetNextNode;
      +import com.oracle.graal.python.lib.IteratorExhausted;
      +import com.oracle.graal.python.lib.PyIterNextNode;
       import com.oracle.graal.python.lib.PyObjectGetIter;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PNodeWithContext;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
      -import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
      +import com.oracle.truffle.api.bytecode.OperationProxy;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Cached.Exclusive;
      @@ -66,68 +65,44 @@
       import com.oracle.truffle.api.frame.Frame;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
      -import com.oracle.truffle.api.strings.TruffleString;
      -import com.oracle.truffle.api.strings.TruffleStringIterator;
       
       public abstract class SetNodes {
       
           @GenerateUncached
           @SuppressWarnings("truffle-inlining")       // footprint reduction 116 -> 98
           public abstract static class ConstructSetNode extends PNodeWithContext {
      -        public abstract PSet execute(Frame frame, Object cls, Object value);
      +        public abstract PSet execute(Frame frame, Object value);
       
      -        public final PSet executeWith(Frame frame, Object value) {
      -            return this.execute(frame, PythonBuiltinClassType.PSet, value);
      -        }
      -
      -        @Specialization
      -        static PSet setString(VirtualFrame frame, Object cls, TruffleString arg,
      -                        @Bind("this") Node inliningTarget,
      -                        @Exclusive @Cached PythonObjectFactory factory,
      -                        @Exclusive @Cached HashingCollectionNodes.SetItemNode setItemNode,
      -                        @Cached TruffleString.CreateCodePointIteratorNode createCodePointIteratorNode,
      -                        @Cached TruffleStringIterator.NextNode nextNode,
      -                        @Cached TruffleString.FromCodePointNode fromCodePointNode) {
      -            PSet set = factory.createSet(cls);
      -            TruffleStringIterator it = createCodePointIteratorNode.execute(arg, TS_ENCODING);
      -            while (it.hasNext()) {
      -                int cp = nextNode.execute(it);
      -                TruffleString s = fromCodePointNode.execute(cp, TS_ENCODING, true);
      -                setItemNode.execute(frame, inliningTarget, set, s, PNone.NONE);
      -            }
      -            return set;
      -        }
      -
      -        @Specialization(guards = "emptyArguments(none)")
      -        static PSet set(Object cls, @SuppressWarnings("unused") PNone none,
      -                        @Exclusive @Cached PythonObjectFactory factory) {
      -            return factory.createSet(cls);
      +        @Specialization(guards = "isNoValue(none)")
      +        static PSet set(@SuppressWarnings("unused") PNone none,
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createSet(language);
               }
       
               @Specialization(guards = "!isNoValue(iterable)")
      -        static PSet setIterable(VirtualFrame frame, Object cls, Object iterable,
      +        static PSet setIterable(VirtualFrame frame, Object iterable,
                               @Bind("this") Node inliningTarget,
      -                        @Exclusive @Cached PythonObjectFactory factory,
      +                        @Bind PythonLanguage language,
                               @Exclusive @Cached HashingCollectionNodes.SetItemNode setItemNode,
                               @Cached PyObjectGetIter getIter,
      -                        @Cached GetNextNode nextNode,
      -                        @Cached IsBuiltinObjectProfile errorProfile) {
      -            PSet set = factory.createSet(cls);
      +                        @Cached PyIterNextNode nextNode) {
      +            PSet set = PFactory.createSet(language);
                   Object iterator = getIter.execute(frame, inliningTarget, iterable);
                   while (true) {
      +                Object next;
                       try {
      -                    setItemNode.execute(frame, inliningTarget, set, nextNode.execute(frame, iterator), PNone.NONE);
      -                } catch (PException e) {
      -                    e.expectStopIteration(inliningTarget, errorProfile);
      +                    next = nextNode.execute(frame, inliningTarget, iterator);
      +                } catch (IteratorExhausted e) {
                           return set;
                       }
      +                setItemNode.execute(frame, inliningTarget, set, next, PNone.NONE);
                   }
               }
       
               @Fallback
      -        static PSet setObject(@SuppressWarnings("unused") Object cls, Object value,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.OBJ_NOT_ITERABLE, value);
      +        static PSet setObject(Object value,
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.OBJ_NOT_ITERABLE, value);
               }
       
               @NeverDefault
      @@ -141,6 +116,7 @@ public static ConstructSetNode getUncached() {
           }
       
           @GenerateUncached
      +    @OperationProxy.Proxyable
           @SuppressWarnings("truffle-inlining")       // footprint reduction 92 -> 73
           public abstract static class AddNode extends PNodeWithContext {
               public abstract void execute(Frame frame, PSet self, Object o);
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/PObjectSlice.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/PObjectSlice.java
      index 5379a81015..c66da77e16 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/PObjectSlice.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/PObjectSlice.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -48,7 +48,7 @@
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerAsserts;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.CompilerDirectives.ValueType;
      @@ -128,13 +128,13 @@ private static int pySign(BigInteger n) {
            * _PySlice_GetLongIndices
            */
           @TruffleBoundary
      -    public static SliceObjectInfo computeIndicesSlowPath(PObjectSlice slice, Object lengthIn, PythonObjectFactory factory) {
      +    public static SliceObjectInfo computeIndicesSlowPath(PObjectSlice slice, Object lengthIn, boolean usePInt) {
               boolean stepIsNegative;
               BigInteger lower, upper;
               BigInteger start, stop, step, length;
               length = (BigInteger) lengthIn;
               if (pySign(length) < 0) {
      -            throw PRaiseNode.raiseUncached(null, ValueError, ErrorMessages.LENGTH_SHOULD_NOT_BE_NEG);
      +            throw PRaiseNode.raiseStatic(null, ValueError, ErrorMessages.LENGTH_SHOULD_NOT_BE_NEG);
               }
               if (slice.getStep() == PNone.NONE) {
                   step = ONE;
      @@ -143,7 +143,7 @@ public static SliceObjectInfo computeIndicesSlowPath(PObjectSlice slice, Object
                   step = (BigInteger) slice.getStep();
                   stepIsNegative = pySign(step) < 0;
                   if (pySign(step) == 0) {
      -                throw PRaiseNode.raiseUncached(null, ValueError, ErrorMessages.SLICE_STEP_CANNOT_BE_ZERO);
      +                throw PRaiseNode.raiseStatic(null, ValueError, ErrorMessages.SLICE_STEP_CANNOT_BE_ZERO);
                   }
               }
       
      @@ -194,8 +194,9 @@ public static SliceObjectInfo computeIndicesSlowPath(PObjectSlice slice, Object
                   }
               }
       
      -        if (factory != null) {
      -            return new SliceObjectInfo(factory.createInt(start), factory.createInt(stop), factory.createInt(step));
      +        if (usePInt) {
      +            PythonLanguage language = PythonLanguage.get(null);
      +            return new SliceObjectInfo(PFactory.createInt(language, start), PFactory.createInt(language, stop), PFactory.createInt(language, step));
               } else {
                   return new SliceObjectInfo(start, stop, step);
               }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/PSlice.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/PSlice.java
      index 2989727c5e..d49fed28e8 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/PSlice.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/PSlice.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2017, 2024, Oracle and/or its affiliates.
      + * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
        * Copyright (c) 2013, Regents of the University of California
        *
        * All rights reserved.
      @@ -110,7 +110,7 @@ public record SliceInfoLong(long start, long stop, long step) {
           protected static void checkNegative(int length) {
               if (length < 0) {
                   CompilerDirectives.transferToInterpreterAndInvalidate();
      -            throw PRaiseNode.raiseUncached(null, ValueError, ErrorMessages.LENGTH_SHOULD_NOT_BE_NEG);
      +            throw PRaiseNode.raiseStatic(null, ValueError, ErrorMessages.LENGTH_SHOULD_NOT_BE_NEG);
               }
           }
       
      @@ -142,7 +142,7 @@ public static SliceInfo computeIndices(Object startIn, Object stopIn, Object ste
                   stepIsNegative = pySign(step) < 0;
                   if (pySign(step) == 0) {
                       CompilerDirectives.transferToInterpreterAndInvalidate();
      -                throw PRaiseNode.raiseUncached(null, ValueError, ErrorMessages.SLICE_STEP_CANNOT_BE_ZERO);
      +                throw PRaiseNode.raiseStatic(null, ValueError, ErrorMessages.SLICE_STEP_CANNOT_BE_ZERO);
                   }
               }
       
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/SliceBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/SliceBuiltins.java
      index 59bdeab756..df3df4f9d3 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/SliceBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/SliceBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2017, 2024, Oracle and/or its affiliates.
      + * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
        * Copyright (c) 2014, Regents of the University of California
        *
        * All rights reserved.
      @@ -25,59 +25,102 @@
        */
       package com.oracle.graal.python.builtins.objects.slice;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
       import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.HashNotImplemented;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      +import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.PNotImplemented;
       import com.oracle.graal.python.builtins.objects.slice.PSlice.SliceInfo;
       import com.oracle.graal.python.builtins.objects.slice.SliceNodes.CoerceToObjectSlice;
       import com.oracle.graal.python.builtins.objects.slice.SliceNodes.ComputeIndices;
       import com.oracle.graal.python.builtins.objects.slice.SliceNodes.SliceCastToToBigInt;
       import com.oracle.graal.python.builtins.objects.slice.SliceNodes.SliceExactCastToInt;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.RichCmpBuiltinNode;
      +import com.oracle.graal.python.lib.PyObjectRichCompare;
       import com.oracle.graal.python.lib.PyObjectRichCompareBool;
      +import com.oracle.graal.python.lib.PySliceNew;
      +import com.oracle.graal.python.lib.RichCmpOp;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      -import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Cached.Exclusive;
       import com.oracle.truffle.api.dsl.Cached.Shared;
      +import com.oracle.truffle.api.dsl.Fallback;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PSlice)
      +@HashNotImplemented
       public final class SliceBuiltins extends PythonBuiltins {
      +    public static final TpSlots SLOTS = SliceBuiltinsSlotsGen.SLOTS;
       
           @Override
           protected List> getNodeFactories() {
               return SliceBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    // slice(stop)
      +    // slice(start, stop[, step])
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "slice", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 4)
           @GenerateNodeFactory
      -    abstract static class ReprNode extends PythonBuiltinNode {
      +    public abstract static class SliceNode extends PythonQuaternaryBuiltinNode {
      +        @Specialization(guards = {"isNoValue(second)"})
      +        @SuppressWarnings("unused")
      +        static Object singleArg(Object cls, Object first, Object second, Object third,
      +                        @Bind("this") Node inliningTarget,
      +                        @Shared @Cached PySliceNew sliceNode) {
      +            return sliceNode.execute(inliningTarget, PNone.NONE, first, PNone.NONE);
      +        }
      +
      +        @Specialization(guards = {"!isNoValue(stop)", "isNoValue(step)"})
      +        @SuppressWarnings("unused")
      +        static Object twoArgs(Object cls, Object start, Object stop, Object step,
      +                        @Bind("this") Node inliningTarget,
      +                        @Shared @Cached PySliceNew sliceNode) {
      +            return sliceNode.execute(inliningTarget, start, stop, PNone.NONE);
      +        }
      +
      +        @Fallback
      +        static Object threeArgs(@SuppressWarnings("unused") Object cls, Object start, Object stop, Object step,
      +                        @Bind("this") Node inliningTarget,
      +                        @Shared @Cached PySliceNew sliceNode) {
      +            return sliceNode.execute(inliningTarget, start, stop, step);
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
      +    @GenerateNodeFactory
      +    abstract static class ReprNode extends PythonUnaryBuiltinNode {
               @Specialization
               @TruffleBoundary
               public static TruffleString repr(PSlice self) {
      @@ -85,38 +128,78 @@ public static TruffleString repr(PSlice self) {
               }
           }
       
      -    @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.tp_richcompare, isComplex = true)
           @GenerateNodeFactory
      -    abstract static class EqNode extends PythonBuiltinNode {
      +    abstract static class EqNode extends RichCmpBuiltinNode {
               @Specialization
      -        static boolean sliceCmp(PIntSlice left, PIntSlice right) {
      -            return left.equals(right);
      -        }
      -
      -        /**
      -         * As per {@link "https://github.com/python/cpython/blob/master/Objects/sliceobject.c#L569"}
      -         *
      -         *
      -         * both {@code left} and {@code right} must be a slice.
      -         *
      -         * @return CPython returns {@code NOTIMPLEMENTED} which will eventually yield {@value false}
      -         *         , so we shortcut and return {@value false}.
      -         */
      -        @SuppressWarnings("unused")
      -        @Specialization(guards = "!isPSlice(right)")
      -        static boolean notEqual(PSlice left, Object right) {
      -            return false;
      +        static boolean doIntSliceEq(PIntSlice left, PIntSlice right, RichCmpOp op,
      +                        @Bind("$node") Node inliningTarget,
      +                        @Cached InlinedConditionProfile startCmpProfile,
      +                        @Cached InlinedConditionProfile stopCmpProfile,
      +                        @Cached InlinedConditionProfile stepCmpProfile,
      +                        @Cached PRaiseNode raiseNode) {
      +            // Inlined tuple comparison specialized for ints
      +            if (startCmpProfile.profile(inliningTarget, left.start != right.start)) {
      +                return cmpVal(inliningTarget, left.start, right.start, left.startIsNone, right.startIsNone, op, raiseNode);
      +            }
      +            if (stopCmpProfile.profile(inliningTarget, left.stop != right.stop)) {
      +                return cmpVal(inliningTarget, left.stop, right.stop, false, false, op, raiseNode);
      +            }
      +            if (stepCmpProfile.profile(inliningTarget, left.step != right.step)) {
      +                return cmpVal(inliningTarget, left.step, right.step, left.stepIsNone, right.stepIsNone, op, raiseNode);
      +            }
      +            return op.isEq() || op.isLe() || op.isGe();
               }
       
      -        @Specialization
      -        static boolean sliceCmpWithLib(VirtualFrame frame, PSlice left, PSlice right,
      +        private static boolean cmpVal(Node inliningTarget, int leftVal, int rightVal, boolean leftValIsNone, boolean rightValIsNone, RichCmpOp op, PRaiseNode raiseNode) {
      +            if (op.isEqOrNe()) {
      +                return op.isNe();
      +            }
      +            if (leftValIsNone || rightValIsNone) {
      +                Object leftObj = leftValIsNone ? PNone.NONE : leftVal;
      +                Object rightObj = rightValIsNone ? PNone.NONE : rightVal;
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.NOT_SUPPORTED_BETWEEN_INSTANCES, op.getOpName(), leftObj, rightObj);
      +            }
      +            return op.compare(leftVal, rightVal);
      +        }
      +
      +        static boolean noIntSlices(PSlice a, PSlice b) {
      +            return !(a instanceof PIntSlice && b instanceof PIntSlice);
      +        }
      +
      +        @Specialization(guards = {"noIntSlices(left, right)", "left == right"})
      +        static boolean sliceCmpIdentical(VirtualFrame frame, PSlice left, PSlice right, RichCmpOp op) {
      +            // CPython fast-path, can have visible behavior, because we skip richcmp
      +            return op.isEq() || op.isLe() || op.isGe();
      +        }
      +
      +        @Specialization(guards = {"noIntSlices(left, right)", "left != right"})
      +        static Object sliceCmpWithLib(VirtualFrame frame, PSlice left, PSlice right, RichCmpOp op,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PyObjectRichCompareBool.EqNode eqNode) {
      -            return eqNode.compare(frame, inliningTarget, left.getStart(), right.getStart()) &&
      -                            eqNode.compare(frame, inliningTarget, left.getStop(), right.getStop()) &&
      -                            eqNode.compare(frame, inliningTarget, left.getStep(), right.getStep());
      +                        @Cached InlinedConditionProfile startCmpProfile,
      +                        @Cached InlinedConditionProfile stopCmpProfile,
      +                        @Cached InlinedConditionProfile stepCmpProfile,
      +                        @Cached PyObjectRichCompareBool eqNode,
      +                        @Cached PyObjectRichCompare cmpNode) {
      +            // Inlined tuple comparison specialized for tuples of 3 items to avoid the tuples
      +            // allocation
      +            if (startCmpProfile.profile(inliningTarget, !eqNode.executeEq(frame, inliningTarget, left.getStart(), right.getStart()))) {
      +                return cmpNode.execute(frame, inliningTarget, left.getStart(), right.getStart(), op);
      +            }
      +            if (stopCmpProfile.profile(inliningTarget, !eqNode.executeEq(frame, inliningTarget, left.getStop(), right.getStop()))) {
      +                return cmpNode.execute(frame, inliningTarget, left.getStop(), right.getStop(), op);
      +            }
      +            if (stepCmpProfile.profile(inliningTarget, !eqNode.executeEq(frame, inliningTarget, left.getStep(), right.getStep()))) {
      +                return cmpNode.execute(frame, inliningTarget, left.getStep(), right.getStep(), op);
      +            }
      +            return op.isEq() || op.isLe() || op.isGe();
               }
       
      +        @Fallback
      +        @SuppressWarnings("unused")
      +        static Object doOthers(VirtualFrame frame, Object left, Object right, RichCmpOp op) {
      +            return PNotImplemented.NOT_IMPLEMENTED;
      +        }
           }
       
           @Builtin(name = "start", minNumOfPositionalArgs = 1, isGetter = true)
      @@ -168,9 +251,9 @@ protected static Object get(PObjectSlice self) {
           @GenerateNodeFactory
           abstract static class IndicesNode extends PythonBinaryBuiltinNode {
       
      -        private static PTuple doPSlice(VirtualFrame frame, PSlice self, int length, ComputeIndices compute, PythonObjectFactory factory) {
      +        private static PTuple doPSlice(VirtualFrame frame, PSlice self, int length, ComputeIndices compute, PythonLanguage language) {
                   SliceInfo sliceInfo = compute.execute(frame, self, length);
      -            return factory.createTuple(new Object[]{sliceInfo.start, sliceInfo.stop, sliceInfo.step});
      +            return PFactory.createTuple(language, new Object[]{sliceInfo.start, sliceInfo.stop, sliceInfo.step});
               }
       
               protected static boolean isSafeIntSlice(PSlice self, Object length) {
      @@ -179,31 +262,31 @@ protected static boolean isSafeIntSlice(PSlice self, Object length) {
       
               @Specialization
               static PTuple safeInt(VirtualFrame frame, PIntSlice self, int length,
      -                        @Shared @Cached ComputeIndices compute,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return doPSlice(frame, self, length, compute, factory);
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached ComputeIndices compute) {
      +            return doPSlice(frame, self, length, compute, language);
               }
       
               @Specialization(guards = "!isPNone(length)", rewriteOn = PException.class)
               static PTuple doSliceObject(VirtualFrame frame, PSlice self, Object length,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Exclusive @Cached SliceExactCastToInt toInt,
      -                        @Shared @Cached ComputeIndices compute,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return doPSlice(frame, self, (int) toInt.execute(frame, inliningTarget, length), compute, factory);
      +                        @Shared @Cached ComputeIndices compute) {
      +            return doPSlice(frame, self, (int) toInt.execute(frame, inliningTarget, length), compute, language);
               }
       
               @Specialization(guards = "!isPNone(length)", replaces = {"doSliceObject"})
               static PTuple doSliceObjectWithSlowPath(VirtualFrame frame, PSlice self, Object length,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Exclusive @Cached SliceExactCastToInt toInt,
                               @Shared @Cached ComputeIndices compute,
                               @Cached IsBuiltinObjectProfile profileError,
                               @Cached SliceCastToToBigInt castLengthNode,
      -                        @Cached CoerceToObjectSlice castNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Cached CoerceToObjectSlice castNode) {
                   try {
      -                return doPSlice(frame, self, (int) toInt.execute(frame, inliningTarget, length), compute, factory);
      +                return doPSlice(frame, self, (int) toInt.execute(frame, inliningTarget, length), compute, language);
                   } catch (PException pe) {
                       if (!profileError.profileException(inliningTarget, pe, PythonBuiltinClassType.OverflowError)) {
                           throw pe;
      @@ -212,25 +295,14 @@ static PTuple doSliceObjectWithSlowPath(VirtualFrame frame, PSlice self, Object
                   }
       
                   Object lengthIn = castLengthNode.execute(inliningTarget, length);
      -            PObjectSlice.SliceObjectInfo sliceInfo = PObjectSlice.computeIndicesSlowPath(castNode.execute(self), lengthIn, factory);
      -            return factory.createTuple(new Object[]{sliceInfo.start, sliceInfo.stop, sliceInfo.step});
      +            PObjectSlice.SliceObjectInfo sliceInfo = PObjectSlice.computeIndicesSlowPath(castNode.execute(self), lengthIn, true);
      +            return PFactory.createTuple(language, new Object[]{sliceInfo.start, sliceInfo.stop, sliceInfo.step});
               }
       
               @Specialization(guards = {"isPNone(length)"})
               static PTuple lengthNone(@SuppressWarnings("unused") PSlice self, @SuppressWarnings("unused") Object length,
      -                        @Cached PRaiseNode raise) {
      -            throw raise.raise(ValueError);
      -        }
      -    }
      -
      -    @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1)
      -    @GenerateNodeFactory
      -    public abstract static class HashNode extends PythonBuiltinNode {
      -        @SuppressWarnings("unused")
      -        @Specialization
      -        public static long hash(PSlice self,
      -                        @Cached PRaiseNode raise) {
      -            throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNHASHABLE_TYPE_P, PythonBuiltinClassType.PSlice);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, ValueError);
               }
           }
       
      @@ -240,10 +312,10 @@ public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object reduce(PSlice self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached GetClassNode getClassNode,
      -                        @Cached PythonObjectFactory factory) {
      -            PTuple args = factory.createTuple(new Object[]{self.getStart(), self.getStop(), self.getStep()});
      -            return factory.createTuple(new Object[]{getClassNode.execute(inliningTarget, self), args});
      +                        @Bind PythonLanguage language,
      +                        @Cached GetClassNode getClassNode) {
      +            PTuple args = PFactory.createTuple(language, new Object[]{self.getStart(), self.getStop(), self.getStep()});
      +            return PFactory.createTuple(language, new Object[]{getClassNode.execute(inliningTarget, self), args});
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/SliceNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/SliceNodes.java
      index 7432624a01..e867c633bd 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/SliceNodes.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/SliceNodes.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -45,6 +45,7 @@
       
       import java.math.BigInteger;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.ints.IntNodes.PyLongSign;
       import com.oracle.graal.python.lib.PyIndexCheckNode;
      @@ -57,7 +58,7 @@
       import com.oracle.graal.python.nodes.util.CastToJavaBigIntegerNode;
       import com.oracle.graal.python.runtime.PythonOptions;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.OverflowException;
       import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
       import com.oracle.truffle.api.dsl.Bind;
      @@ -84,34 +85,34 @@ public abstract static class CreateSliceNode extends PNodeWithContext {
       
               @SuppressWarnings("unused")
               static PSlice doInt(int start, int stop, PNone step,
      -                        @Shared("factory") @Cached PythonObjectFactory factory) {
      -            return factory.createIntSlice(start, stop, 1, false, true);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createIntSlice(language, start, stop, 1, false, true);
               }
       
               @Specialization
               static PSlice doInt(int start, int stop, int step,
      -                        @Shared("factory") @Cached PythonObjectFactory factory) {
      -            return factory.createIntSlice(start, stop, step);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createIntSlice(language, start, stop, step);
               }
       
               @Specialization
               @SuppressWarnings("unused")
               static PSlice doInt(PNone start, int stop, PNone step,
      -                        @Shared("factory") @Cached PythonObjectFactory factory) {
      -            return factory.createIntSlice(0, stop, 1, true, true);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createIntSlice(language, 0, stop, 1, true, true);
               }
       
               @Specialization
               @SuppressWarnings("unused")
               static PSlice doInt(PNone start, int stop, int step,
      -                        @Shared("factory") @Cached PythonObjectFactory factory) {
      -            return factory.createIntSlice(0, stop, step, true, false);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createIntSlice(language, 0, stop, step, true, false);
               }
       
               @Fallback
               static PSlice doGeneric(Object start, Object stop, Object step,
      -                        @Shared("factory") @Cached PythonObjectFactory factory) {
      -            return factory.createObjectSlice(start, stop, step);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createObjectSlice(language, start, stop, step);
               }
       
               @NeverDefault
      @@ -136,13 +137,13 @@ public abstract static class AdjustIndices extends PNodeWithContext {
       
               @Specialization
               static PSlice.SliceInfo calc(Node inliningTarget, int length, PSlice.SliceInfo slice,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   int start = slice.start;
                   int stop = slice.stop;
                   int step = slice.step;
       
                   if (step == 0) {
      -                raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.SLICE_STEP_CANNOT_BE_ZERO);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.SLICE_STEP_CANNOT_BE_ZERO);
                   }
                   assert step > Integer.MIN_VALUE : "step must not be minimum integer value";
       
      @@ -206,8 +207,8 @@ PSlice.SliceInfo doSliceObject(VirtualFrame frame, PObjectSlice slice, int lengt
       
               @Specialization(guards = "length < 0")
               PSlice.SliceInfo doSliceInt(@SuppressWarnings("unused") PSlice slice, @SuppressWarnings("unused") int length,
      -                        @Cached PRaiseNode raise) {
      -            throw raise.raise(ValueError, ErrorMessages.LENGTH_SHOULD_NOT_BE_NEG);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.LENGTH_SHOULD_NOT_BE_NEG);
               }
           }
       
      @@ -226,8 +227,8 @@ PObjectSlice doSliceInt(PIntSlice slice,
                               @Shared @Cached SliceCastToToBigInt start,
                               @Shared @Cached SliceCastToToBigInt stop,
                               @Shared @Cached SliceCastToToBigInt step,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createObjectSlice(start.execute(inliningTarget, slice.getStart()), stop.execute(inliningTarget, slice.getStop()), step.execute(inliningTarget, slice.getStep()));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createObjectSlice(language, start.execute(inliningTarget, slice.getStart()), stop.execute(inliningTarget, slice.getStop()), step.execute(inliningTarget, slice.getStep()));
               }
       
               protected static boolean isBigInt(PObjectSlice slice) {
      @@ -245,8 +246,8 @@ PObjectSlice doSliceObject(PObjectSlice slice,
                               @Shared @Cached SliceCastToToBigInt start,
                               @Shared @Cached SliceCastToToBigInt stop,
                               @Shared @Cached SliceCastToToBigInt step,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return factory.createObjectSlice(start.execute(inliningTarget, slice.getStart()), stop.execute(inliningTarget, slice.getStop()), step.execute(inliningTarget, slice.getStep()));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createObjectSlice(language, start.execute(inliningTarget, slice.getStart()), stop.execute(inliningTarget, slice.getStop()), step.execute(inliningTarget, slice.getStep()));
               }
       
           }
      @@ -271,8 +272,8 @@ static PSlice doSliceObject(Node inliningTarget, PObjectSlice slice,
                               @Cached SliceLossyCastToInt start,
                               @Cached SliceLossyCastToInt stop,
                               @Cached SliceLossyCastToInt step,
      -                        @Cached(inline = false) PythonObjectFactory factory) {
      -            return factory.createObjectSlice(start.execute(inliningTarget, slice.getStart()), stop.execute(inliningTarget, slice.getStop()), step.execute(inliningTarget, slice.getStep()));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createObjectSlice(language, start.execute(inliningTarget, slice.getStart()), stop.execute(inliningTarget, slice.getStop()), step.execute(inliningTarget, slice.getStep()));
               }
           }
       
      @@ -296,7 +297,7 @@ static PSlice.SliceInfo doSliceInt(PIntSlice slice) {
               @InliningCutoff
               static PSlice.SliceInfo doSliceObject(Node inliningTarget, PObjectSlice slice,
                               @Cached SliceLossyCastToInt toInt,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   /* this is harder to get right than you might think */
                   int start, stop, step;
                   if (slice.getStep() == PNone.NONE) {
      @@ -304,7 +305,7 @@ static PSlice.SliceInfo doSliceObject(Node inliningTarget, PObjectSlice slice,
                   } else {
                       step = (int) toInt.execute(inliningTarget, slice.getStep());
                       if (step == 0) {
      -                    raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.SLICE_STEP_CANNOT_BE_ZERO);
      +                    throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.SLICE_STEP_CANNOT_BE_ZERO);
                       }
                   }
       
      @@ -338,10 +339,10 @@ public abstract static class SliceUnpackLong extends PNodeWithContext {
       
               @Specialization
               static PSlice.SliceInfoLong doSliceInt(Node inliningTarget, PIntSlice slice,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   long step = slice.getIntStep();
                   if (step == 0) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.SLICE_STEP_CANNOT_BE_ZERO);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.SLICE_STEP_CANNOT_BE_ZERO);
                   }
       
                   long start;
      @@ -356,7 +357,7 @@ static PSlice.SliceInfoLong doSliceInt(Node inliningTarget, PIntSlice slice,
               @Specialization
               static PSlice.SliceInfoLong doSliceObject(Node inliningTarget, PObjectSlice slice,
                               @Cached SliceLossyCastToLong toInt,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   /* this is harder to get right than you might think */
                   long start, stop, step;
                   if (slice.getStep() == PNone.NONE) {
      @@ -364,7 +365,7 @@ static PSlice.SliceInfoLong doSliceObject(Node inliningTarget, PObjectSlice slic
                   } else {
                       step = toInt.execute(inliningTarget, slice.getStep());
                       if (step == 0) {
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.SLICE_STEP_CANNOT_BE_ZERO);
      +                    throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.SLICE_STEP_CANNOT_BE_ZERO);
                       }
                       /*
                        * Same as in CPython 'PySlice_Unpack': Here step might be -Long.MAX_VALUE-1; in
      @@ -409,13 +410,13 @@ protected static Object doNone(@SuppressWarnings("unused") PNone i) {
               @Specialization(guards = "!isPNone(i)")
               protected static Object doGeneric(Node inliningTarget, Object i,
                               @Cached InlinedBranchProfile exceptionProfile,
      -                        @Cached PRaiseNode.Lazy raise,
      +                        @Cached PRaiseNode raise,
                               @Cached CastToJavaBigIntegerNode cast) {
                   try {
                       return cast.execute(inliningTarget, i);
                   } catch (PException e) {
                       exceptionProfile.enter(inliningTarget);
      -                throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.SLICE_INDICES_MUST_BE_INT_NONE_HAVE_INDEX);
      +                throw raise.raise(inliningTarget, TypeError, ErrorMessages.SLICE_INDICES_MUST_BE_INT_NONE_HAVE_INDEX);
                   }
               }
           }
      @@ -435,13 +436,13 @@ protected static Object doNone(@SuppressWarnings("unused") PNone i) {
       
               @Specialization(guards = "!isPNone(i)")
               protected static Object doGeneric(Node inliningTarget, Object i,
      -                        @Cached PRaiseNode.Lazy raise,
      +                        @Cached PRaiseNode raise,
                               @Cached PyIndexCheckNode indexCheckNode,
                               @Cached PyNumberAsSizeNode asSizeNode) {
                   if (indexCheckNode.execute(inliningTarget, i)) {
                       return asSizeNode.executeExact(null, inliningTarget, i);
                   }
      -            throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.SLICE_INDICES_MUST_BE_INT_NONE_HAVE_INDEX);
      +            throw raise.raise(inliningTarget, TypeError, ErrorMessages.SLICE_INDICES_MUST_BE_INT_NONE_HAVE_INDEX);
               }
           }
       
      @@ -461,14 +462,14 @@ protected static Object doNone(@SuppressWarnings("unused") PNone i) {
               @Specialization(guards = "!isPNone(i)")
               protected static Object doGeneric(Node inliningTarget, Object i,
                               @Cached InlinedBranchProfile exceptionProfile,
      -                        @Cached PRaiseNode.Lazy raise,
      +                        @Cached PRaiseNode raise,
                               @Cached PyIndexCheckNode indexCheckNode,
                               @Cached PyNumberAsSizeNode asSizeNode) {
                   if (indexCheckNode.execute(inliningTarget, i)) {
                       return asSizeNode.executeLossy(null, inliningTarget, i);
                   }
                   exceptionProfile.enter(inliningTarget);
      -            throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.SLICE_INDICES_MUST_BE_INT_NONE_HAVE_INDEX);
      +            throw raise.raise(inliningTarget, TypeError, ErrorMessages.SLICE_INDICES_MUST_BE_INT_NONE_HAVE_INDEX);
               }
           }
       
      @@ -482,7 +483,7 @@ public abstract static class SliceLossyCastToLong extends Node {
       
               @Specialization(guards = "!isPNone(i)")
               static long doGeneric(Node inliningTarget, Object i,
      -                        @Cached PRaiseNode.Lazy raise,
      +                        @Cached PRaiseNode raise,
                               @Cached PyIndexCheckNode indexCheckNode,
                               @Cached(inline = false) PyLongSign signNode,
                               @Cached PyLongAsLongAndOverflowNode asSizeNode) {
      @@ -496,7 +497,7 @@ static long doGeneric(Node inliningTarget, Object i,
                           return Long.MAX_VALUE;
                       }
                   }
      -            throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.SLICE_INDICES_MUST_BE_INT_NONE_HAVE_INDEX);
      +            throw raise.raise(inliningTarget, TypeError, ErrorMessages.SLICE_INDICES_MUST_BE_INT_NONE_HAVE_INDEX);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketBuiltins.java
      index 9e114866d9..c58aa3ab58 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketBuiltins.java
      @@ -51,8 +51,6 @@
       import static com.oracle.graal.python.builtins.objects.exception.OSErrorEnum.ENOTSOCK;
       import static com.oracle.graal.python.builtins.objects.socket.PSocket.INVALID_FD;
       import static com.oracle.graal.python.nodes.BuiltinNames.T__SOCKET;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.runtime.PosixConstants.SOL_SOCKET;
       import static com.oracle.graal.python.runtime.PosixConstants.SO_ERROR;
       import static com.oracle.graal.python.runtime.PosixConstants.SO_PROTOCOL;
      @@ -60,7 +58,11 @@
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.ArgumentClinic;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -73,6 +75,8 @@
       import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
       import com.oracle.graal.python.builtins.objects.socket.SocketUtils.TimeoutHelper;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.lib.PyLongAsIntNode;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
      @@ -85,6 +89,7 @@
       import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
       import com.oracle.graal.python.runtime.GilNode;
       import com.oracle.graal.python.runtime.IndirectCallData;
      @@ -97,7 +102,7 @@
       import com.oracle.graal.python.runtime.PosixSupportLibrary.UniversalSockAddrLibrary;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.graal.python.util.TimeUtils;
       import com.oracle.truffle.api.CompilerDirectives;
      @@ -118,14 +123,16 @@
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PSocket)
       public final class SocketBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = SocketBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return SocketBuiltinsFactory.getFactories();
           }
       
      -    private static void checkSelectable(Node inliningTarget, PRaiseNode.Lazy raiseNode, PSocket socket) {
      +    private static void checkSelectable(Node inliningTarget, PRaiseNode raiseNode, PSocket socket) {
               if (!isSelectable(socket)) {
      -            throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.UNABLE_TO_SELECT_ON_SOCKET);
      +            throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.UNABLE_TO_SELECT_ON_SOCKET);
               }
           }
       
      @@ -133,7 +140,22 @@ private static boolean isSelectable(PSocket socket) {
               return socket.getTimeoutNs() <= 0 || socket.getFd() < PosixConstants.FD_SETSIZE.value;
           }
       
      -    @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self", "family", "type", "proto", "fileno"})
      +    // socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "socket", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class SocketNode extends PythonVarargsBuiltinNode {
      +        // All the "real" work is done by __init__
      +        @Specialization
      +        Object socket(Object cls,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createSocket(language, cls, getInstanceShape.execute(cls));
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_init, isComplex = true)
      +    @SlotSignature(name = "socket", minNumOfPositionalArgs = 1, parameterNames = {"$self", "family", "type", "proto", "fileno"})
           @ArgumentClinic(name = "family", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "-1")
           @ArgumentClinic(name = "type", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "-1")
           @ArgumentClinic(name = "proto", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "-1")
      @@ -141,7 +163,8 @@ private static boolean isSelectable(PSocket socket) {
           public abstract static class InitNode extends PythonClinicBuiltinNode {
               @Specialization
               static Object init(VirtualFrame frame, PSocket self, int familyIn, int typeIn, int protoIn, @SuppressWarnings("unused") PNone fileno,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Bind("this") Node inliningTarget,
                               @Exclusive @Cached SysModuleBuiltins.AuditNode auditNode,
                               @Cached GilNode gil,
      @@ -160,7 +183,6 @@ static Object init(VirtualFrame frame, PSocket self, int familyIn, int typeIn, i
                   if (proto == -1) {
                       proto = 0;
                   }
      -            PythonContext context = PythonContext.get(inliningTarget);
                   try {
                       // TODO SOCK_CLOEXEC?
                       int fd;
      @@ -191,20 +213,20 @@ static Object init(VirtualFrame frame, PSocket self, int familyIn, int typeIn, i
       
               @Specialization(guards = "!isPNone(fileno)")
               static Object init(VirtualFrame frame, PSocket self, int familyIn, int typeIn, int protoIn, Object fileno,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @CachedLibrary(limit = "1") UniversalSockAddrLibrary addrLib,
                               @Bind("this") Node inliningTarget,
                               @Exclusive @Cached SysModuleBuiltins.AuditNode auditNode,
                               @Cached PyLongAsIntNode asIntNode,
                               @Exclusive @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   // sic! CPython really has __new__ there, even though it's in __init__
                   auditNode.audit(inliningTarget, "socket.__new__", self, familyIn, typeIn, protoIn);
      -            PythonContext context = PythonContext.get(inliningTarget);
       
                   int fd = asIntNode.execute(frame, inliningTarget, fileno);
                   if (fd < 0) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.NEG_FILE_DESC);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NEG_FILE_DESC);
                   }
                   int family = familyIn;
                   try {
      @@ -264,7 +286,7 @@ protected ArgumentClinicProvider getArgumentClinic() {
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -281,23 +303,23 @@ abstract static class AcceptNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object accept(VirtualFrame frame, PSocket self,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached SocketNodes.MakeSockAddrNode makeSockAddrNode,
                               @Cached GilNode gil,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   checkSelectable(inliningTarget, raiseNode, self);
       
                   try {
      -                PosixSupport posixSupport = PosixSupport.get(inliningTarget);
      +                PosixSupport posixSupport = context.getPosixSupport();
                       PosixSupportLibrary.AcceptResult acceptResult = SocketUtils.callSocketFunctionWithRetry(frame, inliningTarget, constructAndRaiseNode, posixLib, posixSupport, gil, self,
                                       (p, s) -> p.accept(s, self.getFd()),
                                       false, false);
                       try {
                           Object pythonAddr = makeSockAddrNode.execute(frame, inliningTarget, acceptResult.sockAddr);
                           posixLib.setInheritable(posixSupport, acceptResult.socketFd, false);
      -                    return factory.createTuple(new Object[]{acceptResult.socketFd, pythonAddr});
      +                    return PFactory.createTuple(context.getLanguage(inliningTarget), new Object[]{acceptResult.socketFd, pythonAddr});
                       } catch (Exception e) {
                           // If we failed before giving the fd to python-land, close it
                           CompilerDirectives.transferToInterpreterAndInvalidate();
      @@ -319,9 +341,10 @@ static Object accept(VirtualFrame frame, PSocket self,
           @GenerateNodeFactory
           abstract static class BindNode extends PythonBinaryBuiltinNode {
               @Specialization
      -        Object bind(VirtualFrame frame, PSocket self, Object address,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLibrary,
      +        static Object bind(VirtualFrame frame, PSocket self, Object address,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLibrary,
                               @Cached SocketNodes.GetSockAddrArgNode getSockAddrArgNode,
                               @Cached SysModuleBuiltins.AuditNode auditNode,
                               @Cached GilNode gil,
      @@ -332,7 +355,7 @@ Object bind(VirtualFrame frame, PSocket self, Object address,
                   try {
                       gil.release(true);
                       try {
      -                    posixLibrary.bind(getPosixSupport(), self.getFd(), addr);
      +                    posixLibrary.bind(context.getPosixSupport(), self.getFd(), addr);
                       } finally {
                           gil.acquire();
                       }
      @@ -348,9 +371,10 @@ Object bind(VirtualFrame frame, PSocket self, Object address,
           @GenerateNodeFactory
           abstract static class CloseNode extends PythonUnaryBuiltinNode {
               @Specialization
      -        Object close(VirtualFrame frame, PSocket socket,
      +        static Object close(VirtualFrame frame, PSocket socket,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached GilNode gil,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
                   int fd = socket.getFd();
      @@ -359,7 +383,7 @@ Object close(VirtualFrame frame, PSocket socket,
                           socket.setFd(INVALID_FD);
                           gil.release(true);
                           try {
      -                        posixLib.close(getPosixSupport(), fd);
      +                        posixLib.close(context.getPosixSupport(), fd);
                           } finally {
                               gil.acquire();
                           }
      @@ -379,8 +403,9 @@ Object close(VirtualFrame frame, PSocket socket,
           @GenerateNodeFactory
           abstract static class ConnectNode extends PythonBinaryBuiltinNode {
               @Specialization
      -        Object connect(VirtualFrame frame, PSocket self, Object address,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +        static Object connect(VirtualFrame frame, PSocket self, Object address,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Bind("this") Node inliningTarget,
                               @Cached SocketNodes.GetSockAddrArgNode getSockAddrArgNode,
                               @Cached GilNode gil,
      @@ -391,7 +416,7 @@ Object connect(VirtualFrame frame, PSocket self, Object address,
                   auditNode.audit(inliningTarget, "socket.connect", self, address);
       
                   try {
      -                doConnect(frame, inliningTarget, constructAndRaiseNode, posixLib, getPosixSupport(), gil, self, connectAddr);
      +                doConnect(frame, inliningTarget, constructAndRaiseNode, posixLib, context.getPosixSupport(), gil, self, connectAddr);
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
                   }
      @@ -439,8 +464,9 @@ static void doConnect(Frame frame, Node inliningTarget, PConstructAndRaiseNode.L
           @GenerateNodeFactory
           abstract static class ConnectExNode extends PythonBinaryBuiltinNode {
               @Specialization
      -        Object connectEx(VirtualFrame frame, PSocket self, Object address,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +        static Object connectEx(VirtualFrame frame, PSocket self, Object address,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Bind("this") Node inliningTarget,
                               @Cached SocketNodes.GetSockAddrArgNode getSockAddrArgNode,
                               @Cached GilNode gil,
      @@ -451,7 +477,7 @@ Object connectEx(VirtualFrame frame, PSocket self, Object address,
                   auditNode.audit(inliningTarget, "socket.connect", self, address); // sic! connect
       
                   try {
      -                ConnectNode.doConnect(frame, inliningTarget, constructAndRaiseNode, posixLib, getPosixSupport(), gil, self, connectAddr);
      +                ConnectNode.doConnect(frame, inliningTarget, constructAndRaiseNode, posixLib, context.getPosixSupport(), gil, self, connectAddr);
                   } catch (PosixException e) {
                       return e.getErrorCode();
                   }
      @@ -464,9 +490,10 @@ Object connectEx(VirtualFrame frame, PSocket self, Object address,
           @GenerateNodeFactory
           abstract static class GetPeerNameNode extends PythonUnaryBuiltinNode {
               @Specialization
      -        Object get(VirtualFrame frame, PSocket socket,
      +        static Object get(VirtualFrame frame, PSocket socket,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached SocketNodes.MakeSockAddrNode makeSockAddrNode,
                               @Cached GilNode gil,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
      @@ -474,7 +501,7 @@ Object get(VirtualFrame frame, PSocket socket,
                       UniversalSockAddr addr;
                       gil.release(true);
                       try {
      -                    addr = posixLib.getpeername(getPosixSupport(), socket.getFd());
      +                    addr = posixLib.getpeername(context.getPosixSupport(), socket.getFd());
                       } finally {
                           gil.acquire();
                       }
      @@ -490,9 +517,10 @@ Object get(VirtualFrame frame, PSocket socket,
           @GenerateNodeFactory
           abstract static class GetSockNameNode extends PythonUnaryBuiltinNode {
               @Specialization
      -        Object get(VirtualFrame frame, PSocket socket,
      +        static Object get(VirtualFrame frame, PSocket socket,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached SocketNodes.MakeSockAddrNode makeSockAddrNode,
                               @Cached GilNode gil,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
      @@ -500,7 +528,7 @@ Object get(VirtualFrame frame, PSocket socket,
                       UniversalSockAddr addr;
                       gil.release(true);
                       try {
      -                    addr = posixLib.getsockname(getPosixSupport(), socket.getFd());
      +                    addr = posixLib.getsockname(context.getPosixSupport(), socket.getFd());
                       } finally {
                           gil.acquire();
                       }
      @@ -516,7 +544,7 @@ Object get(VirtualFrame frame, PSocket socket,
           @GenerateNodeFactory
           public abstract static class GetBlockingNode extends PythonUnaryBuiltinNode {
               @Specialization
      -        public static boolean get(PSocket socket) {
      +        static boolean get(PSocket socket) {
                   return socket.getTimeoutNs() != 0;
               }
           }
      @@ -541,9 +569,10 @@ static Object get(PSocket socket) {
           @GenerateNodeFactory
           abstract static class ListenNode extends PythonBinaryClinicBuiltinNode {
               @Specialization
      -        Object listen(VirtualFrame frame, PSocket self, int backlogIn,
      +        static Object listen(VirtualFrame frame, PSocket self, int backlogIn,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached GilNode gil,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
                   int backlog = backlogIn;
      @@ -553,7 +582,7 @@ Object listen(VirtualFrame frame, PSocket self, int backlogIn,
                   try {
                       gil.release(true);
                       try {
      -                    posixLib.listen(getPosixSupport(), self.getFd(), backlog);
      +                    posixLib.listen(context.getPosixSupport(), self.getFd(), backlog);
                       } finally {
                           gil.acquire();
                       }
      @@ -576,37 +605,38 @@ protected ArgumentClinicProvider getArgumentClinic() {
           @GenerateNodeFactory
           abstract static class RecvNode extends PythonTernaryClinicBuiltinNode {
               @Specialization
      -        Object recv(VirtualFrame frame, PSocket socket, int recvlen, int flags,
      +        static Object recv(VirtualFrame frame, PSocket socket, int recvlen, int flags,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached GilNode gil,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (recvlen < 0) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.NEG_BUFF_SIZE_IN_RECV);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NEG_BUFF_SIZE_IN_RECV);
                   }
                   checkSelectable(inliningTarget, raiseNode, socket);
      +            PythonLanguage language = context.getLanguage(inliningTarget);
                   if (recvlen == 0) {
      -                return factory.createEmptyBytes();
      +                return PFactory.createEmptyBytes(language);
                   }
       
                   byte[] bytes;
                   try {
                       bytes = new byte[recvlen];
                   } catch (OutOfMemoryError error) {
      -                throw raiseNode.get(inliningTarget).raise(MemoryError);
      +                throw raiseNode.raise(inliningTarget, MemoryError);
                   }
       
                   try {
      -                int outlen = SocketUtils.callSocketFunctionWithRetry(frame, inliningTarget, constructAndRaiseNode, posixLib, getPosixSupport(), gil, socket,
      +                int outlen = SocketUtils.callSocketFunctionWithRetry(frame, inliningTarget, constructAndRaiseNode, posixLib, context.getPosixSupport(), gil, socket,
                                       (p, s) -> p.recv(s, socket.getFd(), bytes, 0, bytes.length, flags),
                                       false, false);
                       if (outlen == 0) {
      -                    return factory.createEmptyBytes();
      +                    return PFactory.createEmptyBytes(language);
                       }
                       // TODO maybe resize if much smaller?
      -                return factory.createBytes(bytes, outlen);
      +                return PFactory.createBytes(language, bytes, outlen);
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
                   }
      @@ -625,16 +655,16 @@ protected ArgumentClinicProvider getArgumentClinic() {
           @GenerateNodeFactory
           abstract static class RecvFromNode extends PythonTernaryClinicBuiltinNode {
               @Specialization
      -        Object recvFrom(VirtualFrame frame, PSocket socket, int recvlen, int flags,
      +        static Object recvFrom(VirtualFrame frame, PSocket socket, int recvlen, int flags,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached GilNode gil,
                               @Cached SocketNodes.MakeSockAddrNode makeSockAddrNode,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (recvlen < 0) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.NEG_BUFF_SIZE_IN_RECVFROM);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NEG_BUFF_SIZE_IN_RECVFROM);
                   }
                   checkSelectable(inliningTarget, raiseNode, socket);
       
      @@ -642,21 +672,22 @@ Object recvFrom(VirtualFrame frame, PSocket socket, int recvlen, int flags,
                   try {
                       bytes = new byte[recvlen];
                   } catch (OutOfMemoryError error) {
      -                throw raiseNode.get(inliningTarget).raise(MemoryError);
      +                throw raiseNode.raise(inliningTarget, MemoryError);
                   }
       
                   try {
      -                RecvfromResult result = SocketUtils.callSocketFunctionWithRetry(frame, inliningTarget, constructAndRaiseNode, posixLib, getPosixSupport(), gil, socket,
      +                RecvfromResult result = SocketUtils.callSocketFunctionWithRetry(frame, inliningTarget, constructAndRaiseNode, posixLib, context.getPosixSupport(), gil, socket,
                                       (p, s) -> p.recvfrom(s, socket.getFd(), bytes, 0, bytes.length, flags),
                                       false, false);
                       PBytes resultBytes;
      +                PythonLanguage language = context.getLanguage(inliningTarget);
                       if (result.readBytes == 0) {
      -                    resultBytes = factory.createEmptyBytes();
      +                    resultBytes = PFactory.createEmptyBytes(language);
                       } else {
                           // TODO maybe resize if much smaller?
      -                    resultBytes = factory.createBytes(bytes, result.readBytes);
      +                    resultBytes = PFactory.createBytes(language, bytes, result.readBytes);
                       }
      -                return factory.createTuple(new Object[]{resultBytes, makeSockAddrNode.execute(frame, inliningTarget, result.sockAddr)});
      +                return PFactory.createTuple(language, new Object[]{resultBytes, makeSockAddrNode.execute(frame, inliningTarget, result.sockAddr)});
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
                   }
      @@ -677,17 +708,18 @@ abstract static class RecvIntoNode extends PythonQuaternaryClinicBuiltinNode {
               @Specialization(limit = "3")
               static Object recvInto(VirtualFrame frame, PSocket socket, Object bufferObj, int recvlenIn, int flags,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonContext context,
                               @Cached("createFor(this)") IndirectCallData indirectCallData,
                               @CachedLibrary("bufferObj") PythonBufferAcquireLibrary bufferAcquireLib,
                               @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached GilNode gil,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object buffer = bufferAcquireLib.acquireWritable(bufferObj, frame, indirectCallData);
                   try {
                       if (recvlenIn < 0) {
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.NEG_BUFF_SIZE_IN_RECV_INTO);
      +                    throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NEG_BUFF_SIZE_IN_RECV_INTO);
                       }
                       int buflen = bufferLib.getBufferLength(buffer);
                       int recvlen = recvlenIn;
      @@ -695,7 +727,7 @@ static Object recvInto(VirtualFrame frame, PSocket socket, Object bufferObj, int
                           recvlen = buflen;
                       }
                       if (buflen < recvlen) {
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.BUFF_TOO_SMALL);
      +                    throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.BUFF_TOO_SMALL);
                       }
       
                       checkSelectable(inliningTarget, raiseNode, socket);
      @@ -708,13 +740,13 @@ static Object recvInto(VirtualFrame frame, PSocket socket, Object bufferObj, int
                           try {
                               bytes = new byte[recvlen];
                           } catch (OutOfMemoryError error) {
      -                        throw raiseNode.get(inliningTarget).raise(MemoryError);
      +                        throw raiseNode.raise(inliningTarget, MemoryError);
                           }
                       }
       
                       final int len = recvlen;
                       try {
      -                    int outlen = SocketUtils.callSocketFunctionWithRetry(frame, inliningTarget, constructAndRaiseNode, posixLib, PosixSupport.get(inliningTarget), gil, socket,
      +                    int outlen = SocketUtils.callSocketFunctionWithRetry(frame, inliningTarget, constructAndRaiseNode, posixLib, context.getPosixSupport(), gil, socket,
                                           (p, s) -> p.recv(s, socket.getFd(), bytes, 0, len, flags),
                                           false, false);
                           if (!directWrite) {
      @@ -744,19 +776,19 @@ abstract static class RecvFromIntoNode extends PythonQuaternaryClinicBuiltinNode
               @Specialization(limit = "3")
               static Object recvFromInto(VirtualFrame frame, PSocket socket, Object bufferObj, int recvlenIn, int flags,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonContext context,
                               @Cached("createFor(this)") IndirectCallData indirectCallData,
                               @CachedLibrary("bufferObj") PythonBufferAcquireLibrary bufferAcquireLib,
                               @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached GilNode gil,
                               @Cached SocketNodes.MakeSockAddrNode makeSockAddrNode,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object buffer = bufferAcquireLib.acquireWritable(bufferObj, frame, indirectCallData);
                   try {
                       if (recvlenIn < 0) {
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.NEG_BUFF_SIZE_IN_RECVFROM_INTO);
      +                    throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NEG_BUFF_SIZE_IN_RECVFROM_INTO);
                       }
                       int buflen = bufferLib.getBufferLength(buffer);
                       int recvlen = recvlenIn;
      @@ -764,7 +796,7 @@ static Object recvFromInto(VirtualFrame frame, PSocket socket, Object bufferObj,
                           recvlen = buflen;
                       }
                       if (buflen < recvlen) {
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.NBYTES_GREATER_THAT_BUFF);
      +                    throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NBYTES_GREATER_THAT_BUFF);
                       }
       
                       checkSelectable(inliningTarget, raiseNode, socket);
      @@ -777,18 +809,18 @@ static Object recvFromInto(VirtualFrame frame, PSocket socket, Object bufferObj,
                           try {
                               bytes = new byte[recvlen];
                           } catch (OutOfMemoryError error) {
      -                        throw raiseNode.get(inliningTarget).raise(MemoryError);
      +                        throw raiseNode.raise(inliningTarget, MemoryError);
                           }
                       }
       
                       try {
      -                    RecvfromResult result = SocketUtils.callSocketFunctionWithRetry(frame, inliningTarget, constructAndRaiseNode, posixLib, PosixSupport.get(inliningTarget), gil, socket,
      +                    RecvfromResult result = SocketUtils.callSocketFunctionWithRetry(frame, inliningTarget, constructAndRaiseNode, posixLib, context.getPosixSupport(), gil, socket,
                                           (p, s) -> p.recvfrom(s, socket.getFd(), bytes, 0, bytes.length, flags),
                                           false, false);
                           if (!directWrite) {
                               bufferLib.writeFromByteArray(buffer, 0, bytes, 0, result.readBytes);
                           }
      -                    return factory.createTuple(new Object[]{result.readBytes, makeSockAddrNode.execute(frame, inliningTarget, result.sockAddr)});
      +                    return PFactory.createTuple(context.getLanguage(inliningTarget), new Object[]{result.readBytes, makeSockAddrNode.execute(frame, inliningTarget, result.sockAddr)});
                       } catch (PosixException e) {
                           throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
                       }
      @@ -811,13 +843,14 @@ abstract static class SendNode extends PythonTernaryClinicBuiltinNode {
               @Specialization(limit = "3")
               static int send(VirtualFrame frame, PSocket socket, Object bufferObj, int flags,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonContext context,
                               @Cached("createFor(this)") IndirectCallData indirectCallData,
                               @CachedLibrary("bufferObj") PythonBufferAcquireLibrary bufferAcquireLib,
                               @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached GilNode gil,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object buffer = bufferAcquireLib.acquireReadonly(bufferObj, frame, indirectCallData);
                   try {
                       checkSelectable(inliningTarget, raiseNode, socket);
      @@ -826,7 +859,7 @@ static int send(VirtualFrame frame, PSocket socket, Object bufferObj, int flags,
                       byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer);
       
                       try {
      -                    return SocketUtils.callSocketFunctionWithRetry(frame, inliningTarget, constructAndRaiseNode, posixLib, PosixSupport.get(inliningTarget), gil, socket,
      +                    return SocketUtils.callSocketFunctionWithRetry(frame, inliningTarget, constructAndRaiseNode, posixLib, context.getPosixSupport(), gil, socket,
                                           (p, s) -> p.send(s, socket.getFd(), bytes, 0, len, flags),
                                           true, false);
                       } catch (PosixException e) {
      @@ -851,13 +884,14 @@ abstract static class SendAllNode extends PythonTernaryClinicBuiltinNode {
               @Specialization(limit = "3")
               static Object sendAll(VirtualFrame frame, PSocket socket, Object bufferObj, int flags,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonContext context,
                               @Cached("createFor(this)") IndirectCallData indirectCallData,
                               @CachedLibrary("bufferObj") PythonBufferAcquireLibrary bufferAcquireLib,
                               @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached GilNode gil,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object buffer = bufferAcquireLib.acquireReadonly(bufferObj, frame, indirectCallData);
                   try {
                       checkSelectable(inliningTarget, raiseNode, socket);
      @@ -876,7 +910,7 @@ static Object sendAll(VirtualFrame frame, PSocket socket, Object bufferObj, int
                           try {
                               final int offset1 = offset;
                               final int len1 = len;
      -                        int outlen = SocketUtils.callSocketFunctionWithRetry(frame, inliningTarget, constructAndRaiseNode, posixLib, PosixSupport.get(inliningTarget), gil, socket,
      +                        int outlen = SocketUtils.callSocketFunctionWithRetry(frame, inliningTarget, constructAndRaiseNode, posixLib, context.getPosixSupport(), gil, socket,
                                               (p, s) -> p.send(s, socket.getFd(), bytes, offset1, len1, flags),
                                               true, false, timeoutHelper);
                               offset += outlen;
      @@ -909,17 +943,18 @@ abstract static class SendToNode extends PythonBuiltinNode {
               @Specialization(limit = "3")
               static Object sendTo(VirtualFrame frame, PSocket socket, Object bufferObj, Object flagsOrAddress, Object maybeAddress,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonContext context,
                               @Cached("createFor(this)") IndirectCallData indirectCallData,
                               @CachedLibrary("bufferObj") PythonBufferAcquireLibrary bufferAcquireLib,
                               @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached InlinedConditionProfile hasFlagsProfile,
                               @Cached PyLongAsIntNode asIntNode,
                               @Cached SocketNodes.GetSockAddrArgNode getSockAddrArgNode,
                               @Cached SysModuleBuiltins.AuditNode auditNode,
                               @Cached GilNode gil,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   int flags;
                   Object address;
                   if (hasFlagsProfile.profile(inliningTarget, maybeAddress == PNone.NO_VALUE)) {
      @@ -941,7 +976,7 @@ static Object sendTo(VirtualFrame frame, PSocket socket, Object bufferObj, Objec
                       byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer);
       
                       try {
      -                    return SocketUtils.callSocketFunctionWithRetry(frame, inliningTarget, constructAndRaiseNode, posixLib, PosixSupport.get(inliningTarget), gil, socket,
      +                    return SocketUtils.callSocketFunctionWithRetry(frame, inliningTarget, constructAndRaiseNode, posixLib, context.getPosixSupport(), gil, socket,
                                           (p, s) -> p.sendto(s, socket.getFd(), bytes, 0, len, flags, addr),
                                           true, false);
                       } catch (PosixException e) {
      @@ -958,12 +993,13 @@ static Object sendTo(VirtualFrame frame, PSocket socket, Object bufferObj, Objec
           @GenerateNodeFactory
           public abstract static class SetBlockingNode extends PythonBinaryClinicBuiltinNode {
               @Specialization
      -        PNone doBoolean(VirtualFrame frame, PSocket socket, boolean blocking,
      +        static PNone doBoolean(VirtualFrame frame, PSocket socket, boolean blocking,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
                   try {
      -                posixLib.setBlocking(getPosixSupport(), socket.getFd(), blocking);
      +                posixLib.setBlocking(context.getPosixSupport(), socket.getFd(), blocking);
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
                   }
      @@ -982,15 +1018,16 @@ protected ArgumentClinicProvider getArgumentClinic() {
           @GenerateNodeFactory
           abstract static class SetTimeoutNode extends PythonBinaryBuiltinNode {
               @Specialization
      -        Object setTimeout(VirtualFrame frame, PSocket socket, Object seconds,
      +        static Object setTimeout(VirtualFrame frame, PSocket socket, Object seconds,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached SocketNodes.ParseTimeoutNode parseTimeoutNode,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
                   long timeout = parseTimeoutNode.execute(frame, inliningTarget, seconds);
                   socket.setTimeoutNs(timeout);
                   try {
      -                posixLib.setBlocking(getPosixSupport(), socket.getFd(), timeout < 0);
      +                posixLib.setBlocking(context.getPosixSupport(), socket.getFd(), timeout < 0);
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
                   }
      @@ -1004,12 +1041,13 @@ Object setTimeout(VirtualFrame frame, PSocket socket, Object seconds,
           @GenerateNodeFactory
           abstract static class ShutdownNode extends PythonBinaryClinicBuiltinNode {
               @Specialization
      -        Object shutdown(VirtualFrame frame, PSocket socket, int how,
      +        static Object shutdown(VirtualFrame frame, PSocket socket, int how,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
                   try {
      -                posixLib.shutdown(getPosixSupport(), socket.getFd(), how);
      +                posixLib.shutdown(context.getPosixSupport(), socket.getFd(), how);
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
                   }
      @@ -1081,8 +1119,9 @@ int detach(PSocket socket) {
           abstract static class SetSockOptNode extends PythonClinicBuiltinNode {
               @Specialization(guards = "isNoValue(none)")
               static Object setInt(VirtualFrame frame, PSocket socket, int level, int option, Object value, @SuppressWarnings("unused") PNone none,
      +                        @Bind PythonContext context,
                               @Cached("createFor(this)") IndirectCallData indirectCallData,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib,
                               @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib,
                               @Bind("this") Node inliningTarget,
      @@ -1106,7 +1145,7 @@ static Object setInt(VirtualFrame frame, PSocket socket, int level, int option,
       
                   }
                   try {
      -                posixLib.setsockopt(PosixSupport.get(inliningTarget), socket.getFd(), level, option, bytes, len);
      +                posixLib.setsockopt(context.getPosixSupport(), socket.getFd(), level, option, bytes, len);
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
                   }
      @@ -1115,18 +1154,19 @@ static Object setInt(VirtualFrame frame, PSocket socket, int level, int option,
       
               @Specialization(guards = "isNone(none)")
               static Object setNull(VirtualFrame frame, PSocket socket, int level, int option, @SuppressWarnings("unused") PNone none, Object buflenObj,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Bind("this") Node inliningTarget,
                               @Exclusive @Cached PyLongAsIntNode asIntNode,
                               @Exclusive @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   int buflen = asIntNode.execute(frame, inliningTarget, buflenObj);
                   if (buflen < 0) {
                       // GraalPython-specific because we don't have unsigned integers
      -                throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.SETSECKOPT_BUFF_OUT_OFRANGE);
      +                throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.SETSECKOPT_BUFF_OUT_OFRANGE);
                   }
                   try {
      -                posixLib.setsockopt(PosixSupport.get(inliningTarget), socket.getFd(), level, option, null, buflen);
      +                posixLib.setsockopt(context.getPosixSupport(), socket.getFd(), level, option, null, buflen);
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
                   }
      @@ -1136,8 +1176,8 @@ static Object setNull(VirtualFrame frame, PSocket socket, int level, int option,
               @Fallback
               @SuppressWarnings("unused")
               static Object error(Object self, Object level, Object option, Object flag1, Object flag2,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.SETSECKOPT_REQUIRERS_3RD_ARG_NULL);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.SETSECKOPT_REQUIRERS_3RD_ARG_NULL);
               }
       
               @Override
      @@ -1153,23 +1193,23 @@ protected ArgumentClinicProvider getArgumentClinic() {
           @GenerateNodeFactory
           abstract static class GetSockOptNode extends PythonQuaternaryClinicBuiltinNode {
               @Specialization
      -        Object getSockOpt(VirtualFrame frame, PSocket socket, int level, int option, int buflen,
      +        static Object getSockOpt(VirtualFrame frame, PSocket socket, int level, int option, int buflen,
                               @Bind("this") Node inliningTarget,
      -                        @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
      +                        @Bind PythonContext context,
      +                        @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   try {
                       if (buflen == 0) {
                           byte[] result = new byte[4];
      -                    posixLib.getsockopt(getPosixSupport(), socket.getFd(), level, option, result, result.length);
      +                    posixLib.getsockopt(context.getPosixSupport(), socket.getFd(), level, option, result, result.length);
                           return PythonUtils.ARRAY_ACCESSOR.getInt(result, 0);
                       } else if (buflen > 0 && buflen < 1024) {
                           byte[] result = new byte[buflen];
      -                    int len = posixLib.getsockopt(getPosixSupport(), socket.getFd(), level, option, result, result.length);
      -                    return factory.createBytes(result, len);
      +                    int len = posixLib.getsockopt(context.getPosixSupport(), socket.getFd(), level, option, result, result.length);
      +                    return PFactory.createBytes(context.getLanguage(inliningTarget), result, len);
                       } else {
      -                    throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.GETSECKOPT_BUFF_OUT_OFRANGE);
      +                    throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.GETSECKOPT_BUFF_OUT_OFRANGE);
                       }
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java
      index db3af25fef..3bd1e0eac4 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -62,6 +62,7 @@
       
       import java.util.Arrays;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.builtins.modules.CodecsModuleBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary;
      @@ -97,7 +98,7 @@
       import com.oracle.graal.python.runtime.PosixSupportLibrary.UnsupportedPosixFeatureException;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.TimeUtils;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      @@ -132,14 +133,14 @@ static UniversalSockAddr doInet(VirtualFrame frame, @SuppressWarnings("unused")
                               @Cached @Shared("idnaConverter") IdnaFromStringOrBytesConverterNode idnaConverter,
                               @Cached @Shared("errorProfile") IsBuiltinObjectProfile errorProfile,
                               @Cached @Shared("setIpAddr") SetIpAddrNode setIpAddrNode,
      -                        @Cached @Shared PRaiseNode.Lazy raiseNode) {
      +                        @Cached @Shared PRaiseNode raiseNode) {
                   PythonContext context = PythonContext.get(inliningTarget);
                   if (!(address instanceof PTuple)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_AF_INET_VALUES_MUST_BE_TUPLE_NOT_P, caller, address);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_AF_INET_VALUES_MUST_BE_TUPLE_NOT_P, caller, address);
                   }
                   Object[] hostAndPort = getObjectArrayNode.execute(inliningTarget, address);
                   if (hostAndPort.length != 2) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.AF_INET_VALUES_MUST_BE_PAIR);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.AF_INET_VALUES_MUST_BE_PAIR);
                   }
                   byte[] host = idnaConverter.execute(frame, hostAndPort[0]);
                   int port = parsePort(frame, caller, asIntNode, inliningTarget, errorProfile, hostAndPort[1], raiseNode);
      @@ -158,14 +159,14 @@ static UniversalSockAddr doInet6(VirtualFrame frame, @SuppressWarnings("unused")
                               @Cached @Shared("idnaConverter") IdnaFromStringOrBytesConverterNode idnaConverter,
                               @Cached @Shared("errorProfile") IsBuiltinObjectProfile errorProfile,
                               @Cached @Shared("setIpAddr") SetIpAddrNode setIpAddrNode,
      -                        @Cached @Shared PRaiseNode.Lazy raiseNode) {
      +                        @Cached @Shared PRaiseNode raiseNode) {
                   PythonContext context = PythonContext.get(inliningTarget);
                   if (!(address instanceof PTuple)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_AF_INET_VALUES_MUST_BE_TUPLE_NOT_S, caller, address);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_AF_INET_VALUES_MUST_BE_TUPLE_NOT_S, caller, address);
                   }
                   Object[] hostAndPort = getObjectArrayNode.execute(inliningTarget, address);
                   if (hostAndPort.length < 2 || hostAndPort.length > 4) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.AF_INET6_ADDR_MUST_BE_TUPLE);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.AF_INET6_ADDR_MUST_BE_TUPLE);
                   }
                   byte[] host = idnaConverter.execute(frame, hostAndPort[0]);
                   int port = parsePort(frame, caller, asIntNode, inliningTarget, errorProfile, hostAndPort[1], raiseNode);
      @@ -173,7 +174,7 @@ static UniversalSockAddr doInet6(VirtualFrame frame, @SuppressWarnings("unused")
                   if (hostAndPort.length > 2) {
                       flowinfo = asIntNode.execute(frame, inliningTarget, hostAndPort[2]);
                       if (flowinfo < 0 || flowinfo > 0xfffff) {
      -                    throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.S_FLOWINFO_RANGE, caller);
      +                    throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.S_FLOWINFO_RANGE, caller);
                       }
                   }
                   int scopeid = 0;
      @@ -196,7 +197,7 @@ static UniversalSockAddr doUnix(VirtualFrame frame, @SuppressWarnings("unused")
                               @CachedLibrary(limit = "1") PythonBufferAcquireLibrary bufferAcquireLib,
                               @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib,
                               @CachedLibrary(limit = "1") @Shared("posixLib") PosixSupportLibrary posixLib,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   byte[] path;
                   if (unicodeCheckNode.execute(inliningTarget, address)) {
                       // PyUnicode_EncodeFSDefault
      @@ -219,17 +220,17 @@ static UniversalSockAddr doUnix(VirtualFrame frame, @SuppressWarnings("unused")
                   try {
                       return posixLib.createUniversalSockAddrUnix(posixSupport, new UnixSockAddr(path));
                   } catch (UnsupportedPosixFeatureException e) {
      -                throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.AF_UNIX_NOT_SUPPORTED, caller);
      +                throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.AF_UNIX_NOT_SUPPORTED, caller);
                   } catch (InvalidUnixSocketPathException e) {
      -                throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.AF_UNIX_PATH_TOO_LONG, caller);
      +                throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.AF_UNIX_PATH_TOO_LONG, caller);
                   }
               }
       
               @Specialization(guards = {"!isInet(socket)", "!isInet6(socket)", "!isUnix(socket)"})
               @SuppressWarnings("unused")
               static UniversalSockAddr getSockAddr(VirtualFrame frame, PSocket socket, Object address, String caller,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(OSError, ErrorMessages.BAD_FAMILY, caller);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, OSError, ErrorMessages.BAD_FAMILY, caller);
               }
       
               static boolean isInet(PSocket socket) {
      @@ -245,7 +246,7 @@ static boolean isUnix(PSocket socket) {
               }
       
               private static int parsePort(VirtualFrame frame, String caller, PyLongAsIntNode asIntNode, Node inliningTarget, IsBuiltinObjectProfile errorProfile, Object portObj,
      -                        PRaiseNode.Lazy raiseNode) {
      +                        PRaiseNode raiseNode) {
                   int port;
                   try {
                       port = asIntNode.execute(frame, inliningTarget, portObj);
      @@ -254,7 +255,7 @@ private static int parsePort(VirtualFrame frame, String caller, PyLongAsIntNode
                       port = -1;
                   }
                   if (port < 0 || port > 0xffff) {
      -                throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.S_PORT_RANGE, caller);
      +                throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.S_PORT_RANGE, caller);
                   }
                   return port;
               }
      @@ -279,7 +280,7 @@ static UniversalSockAddr setipaddr(VirtualFrame frame, byte[] name, int family,
                               @Cached InetPtoNCachedPNode inetPtoNCachedPNode,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
                               @Cached GilNode gil,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   PythonContext context = PythonContext.get(inliningTarget);
                   Object posixSupport = context.getPosixSupport();
                   try {
      @@ -291,7 +292,7 @@ static UniversalSockAddr setipaddr(VirtualFrame frame, byte[] name, int family,
                                               family, SOCK_DGRAM.value, 0, AI_PASSIVE.value);
                               try {
                                   if (addrInfoLib.next(cursor)) {
      -                                throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.WILD_CARD_RESOLVED_TO_MULTIPLE_ADDRESS);
      +                                throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.WILD_CARD_RESOLVED_TO_MULTIPLE_ADDRESS);
                                   }
                                   return addrInfoLib.getSockAddr(cursor);
                               } finally {
      @@ -304,7 +305,7 @@ static UniversalSockAddr setipaddr(VirtualFrame frame, byte[] name, int family,
                       /* special-case broadcast - inet_addr() below can return INADDR_NONE for this */
                       if (Arrays.equals(name, BROADCAST_IP) || Arrays.equals(name, BROADCAST)) {
                           if (family != AF_INET.value && family != AF_UNSPEC.value) {
      -                        throw raiseNode.get(inliningTarget).raise(OSError, ErrorMessages.ADDRESS_FAMILY_MISMATCHED);
      +                        throw raiseNode.raise(inliningTarget, OSError, ErrorMessages.ADDRESS_FAMILY_MISMATCHED);
                           }
                           return posixLib.createUniversalSockAddrInet4(posixSupport, new Inet4SockAddr(0, INADDR_BROADCAST.value));
                       }
      @@ -394,38 +395,38 @@ public abstract static class MakeSockAddrNode extends Node {
               static Object makeSockAddr(VirtualFrame frame, Node inliningTarget, UniversalSockAddr addr,
                               @CachedLibrary(limit = "1") PosixSupportLibrary posixLib,
                               @CachedLibrary("addr") UniversalSockAddrLibrary addrLib,
      -                        @Cached(inline = false) PythonObjectFactory factory,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
                               @Cached(inline = false) TruffleString.FromJavaStringNode fromJavaStringNode,
                               @Cached(inline = false) TruffleString.FromByteArrayNode fromByteArrayNode,
                               @Cached(inline = false) TruffleString.SwitchEncodingNode switchEncodingNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   try {
                       PythonContext context = PythonContext.get(inliningTarget);
      +                PythonLanguage language = context.getLanguage(inliningTarget);
                       int family = addrLib.getFamily(addr);
                       if (family == AF_INET.value) {
                           Inet4SockAddr inet4SockAddr = addrLib.asInet4SockAddr(addr);
                           Object posixSupport = context.getPosixSupport();
                           TruffleString addressString = posixLib.getPathAsString(posixSupport, posixLib.inet_ntop(posixSupport, family, inet4SockAddr.getAddressAsBytes()));
      -                    return factory.createTuple(new Object[]{addressString, inet4SockAddr.getPort()});
      +                    return PFactory.createTuple(language, new Object[]{addressString, inet4SockAddr.getPort()});
                       } else if (family == AF_INET6.value) {
                           Inet6SockAddr inet6SockAddr = addrLib.asInet6SockAddr(addr);
                           Object posixSupport = context.getPosixSupport();
                           TruffleString addressString = posixLib.getPathAsString(posixSupport, posixLib.inet_ntop(posixSupport, family, inet6SockAddr.getAddress()));
      -                    return factory.createTuple(new Object[]{addressString, inet6SockAddr.getPort(), inet6SockAddr.getFlowInfo(), inet6SockAddr.getScopeId()});
      +                    return PFactory.createTuple(language, new Object[]{addressString, inet6SockAddr.getPort(), inet6SockAddr.getFlowInfo(), inet6SockAddr.getScopeId()});
                       } else if (family == AF_UNIX.value) {
                           UnixSockAddr unixSockAddr = addrLib.asUnixSockAddr(addr);
                           byte[] path = unixSockAddr.getPath();
                           if (PosixConstants.IS_LINUX && path.length > 0 && path[0] == 0) {
                               // linux-specific "abstract" address
      -                        return factory.createBytes(arrayCopyOf(path, path.length));
      +                        return PFactory.createBytes(language, arrayCopyOf(path, path.length));
                           }
                           return bytesToString(path, fromByteArrayNode, switchEncodingNode);
                       } else if (family == AF_UNSPEC.value) {
                           // Can be returned from recvfrom when used on a connected socket
                           return PNone.NONE;
                       } else {
      -                    throw raiseNode.get(inliningTarget).raise(NotImplementedError, toTruffleStringUncached("makesockaddr: unknown address family"));
      +                    throw raiseNode.raise(inliningTarget, NotImplementedError, toTruffleStringUncached("makesockaddr: unknown address family"));
                       }
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, e.getErrorCode(), fromJavaStringNode.execute(e.getMessage(), TS_ENCODING));
      @@ -457,7 +458,7 @@ static Object makeAddr(VirtualFrame frame, Node inliningTarget, UniversalSockAdd
                               @CachedLibrary("addr") UniversalSockAddrLibrary addrLib,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
                               @Cached(inline = false) TruffleString.FromJavaStringNode fromJavaStringNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   try {
                       PythonContext context = PythonContext.get(inliningTarget);
                       int family = addrLib.getFamily(addr);
      @@ -470,7 +471,7 @@ static Object makeAddr(VirtualFrame frame, Node inliningTarget, UniversalSockAdd
                           Object posixSupport = context.getPosixSupport();
                           return posixLib.getPathAsString(posixSupport, posixLib.inet_ntop(posixSupport, family, inet6SockAddr.getAddress()));
                       } else {
      -                    throw raiseNode.get(inliningTarget).raise(NotImplementedError, toTruffleStringUncached("makesockaddr: unknown address family"));
      +                    throw raiseNode.raise(inliningTarget, NotImplementedError, toTruffleStringUncached("makesockaddr: unknown address family"));
                       }
                   } catch (PosixException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, e.getErrorCode(), fromJavaStringNode.execute(e.getMessage(), TS_ENCODING));
      @@ -500,7 +501,7 @@ byte[] convert(VirtualFrame frame, Object value,
                               @Cached TruffleString.SwitchEncodingNode switchEncodingNode,
                               @Cached TruffleString.CopyToByteArrayNode copyToByteArrayNode,
                               @Cached CodecsModuleBuiltins.EncodeNode encodeNode,
      -                        @Cached PRaiseNode.Lazy raise) {
      +                        @Cached PRaiseNode raise) {
                   Object bytes;
                   if (unicodeCheckNode.execute(inliningTarget, value)) {
                       TruffleString string = castToString.execute(inliningTarget, value);
      @@ -517,9 +518,9 @@ byte[] convert(VirtualFrame frame, Object value,
                       bytes = value;
                   } else {
                       if (builtinName != null) {
      -                    throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.ARG_MUST_BE_STRING_OR_BYTELIKE_OR_BYTEARRAY, builtinName, argumentIndex, value);
      +                    throw raise.raise(inliningTarget, TypeError, ErrorMessages.ARG_MUST_BE_STRING_OR_BYTELIKE_OR_BYTEARRAY, builtinName, argumentIndex, value);
                       } else {
      -                    throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.STR_BYTES_OR_BYTEARRAY_EXPECTED, value);
      +                    throw raise.raise(inliningTarget, TypeError, ErrorMessages.STR_BYTES_OR_BYTEARRAY_EXPECTED, value);
                       }
                   }
                   return bufferLib.getCopiedByteArray(bytes);
      @@ -553,10 +554,10 @@ static long parse(@SuppressWarnings("unused") PNone none) {
               @Specialization(guards = "!isNone(seconds)")
               static long parse(VirtualFrame frame, Node inliningTarget, Object seconds,
                               @Cached PyTimeFromObjectNode timeFromObjectNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   long timeout = timeFromObjectNode.execute(frame, inliningTarget, seconds, RoundType.TIMEOUT, TimeUtils.SEC_TO_NS);
                   if (timeout < 0) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.TIMEOUT_VALUE_OUT_OF_RANGE);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.TIMEOUT_VALUE_OUT_OF_RANGE);
                   }
                   return timeout;
               }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java
      index 76902ffaf2..f0a7459c18 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/CertUtils.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -101,6 +101,7 @@
       import org.bouncycastle.pkcs.PKCSException;
       import org.bouncycastle.util.encoders.DecoderException;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.builtins.objects.common.HashingStorage;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem;
       import com.oracle.graal.python.builtins.objects.dict.PDict;
      @@ -108,8 +109,7 @@
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
       import com.oracle.graal.python.runtime.PythonContext;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      -import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.TruffleFile;
       import com.oracle.truffle.api.strings.TruffleString;
      @@ -186,19 +186,19 @@ static boolean isCrl(boolean[] keyUsage) {
            * _ssl.c#_decode_certificate
            */
           @TruffleBoundary
      -    public static PDict decodeCertificate(PythonObjectSlowPathFactory factory, X509Certificate cert) throws CertificateParsingException {
      -        PDict dict = factory.createDict();
      +    public static PDict decodeCertificate(X509Certificate cert, PythonLanguage language) throws CertificateParsingException {
      +        PDict dict = PFactory.createDict(language);
               HashingStorage storage = dict.getDictStorage();
               try {
      -            storage = setItem(storage, T_JAVA_X509_OCSP, parseOCSP(cert, factory));
      -            storage = setItem(storage, T_JAVA_X509_CA_ISSUERS, parseCAIssuers(cert, factory));
      -            storage = setItem(storage, T_JAVA_X509_ISSUER, createTupleForX509Name(cert.getIssuerX500Principal().getName("RFC1779"), factory));
      +            storage = setItem(storage, T_JAVA_X509_OCSP, parseOCSP(cert, language));
      +            storage = setItem(storage, T_JAVA_X509_CA_ISSUERS, parseCAIssuers(cert, language));
      +            storage = setItem(storage, T_JAVA_X509_ISSUER, createTupleForX509Name(cert.getIssuerX500Principal().getName("RFC1779"), language));
                   storage = setItem(storage, T_JAVA_X509_NOT_AFTER, getNotAfter(cert));
                   storage = setItem(storage, T_JAVA_X509_NOT_BEFORE, getNotBefore(cert));
                   storage = setItem(storage, T_JAVA_X509_SERIAL_NUMBER, getSerialNumber(cert));
      -            storage = setItem(storage, T_JAVA_X509_CRL_DISTRIBUTION_POINTS, parseCRLPoints(cert, factory));
      -            storage = setItem(storage, T_JAVA_X509_SUBJECT, createTupleForX509Name(cert.getSubjectX500Principal().getName("RFC1779"), factory));
      -            storage = setItem(storage, T_JAVA_X509_SUBJECT_ALT_NAME, parseSubjectAltName(cert, factory));
      +            storage = setItem(storage, T_JAVA_X509_CRL_DISTRIBUTION_POINTS, parseCRLPoints(cert, language));
      +            storage = setItem(storage, T_JAVA_X509_SUBJECT, createTupleForX509Name(cert.getSubjectX500Principal().getName("RFC1779"), language));
      +            storage = setItem(storage, T_JAVA_X509_SUBJECT_ALT_NAME, parseSubjectAltName(cert, language));
                   storage = setItem(storage, T_JAVA_X509_VERSION, getVersion(cert));
               } catch (RuntimeException re) {
                   throw PConstructAndRaiseNode.raiseUncachedSSLError(SSLErrorCode.ERROR_SSL, re);
      @@ -246,23 +246,23 @@ private static TruffleString formatDate(Date d) {
           }
       
           @TruffleBoundary
      -    private static PTuple createTupleForX509Name(String name, PythonObjectFactory factory) {
      +    private static PTuple createTupleForX509Name(String name, PythonLanguage language) {
               List result = new ArrayList<>();
               for (String component : name.split(",")) {
                   String[] kv = component.split("=");
                   if (kv.length == 2) {
      -                PTuple innerTuple = factory.createTuple(new Object[]{ASN1Helper.translateKeyToPython(kv[0].trim()), toTruffleStringUncached(kv[1].trim())});
      -                result.add(factory.createTuple(new Object[]{innerTuple}));
      +                PTuple innerTuple = PFactory.createTuple(language, new Object[]{ASN1Helper.translateKeyToPython(kv[0].trim()), toTruffleStringUncached(kv[1].trim())});
      +                result.add(PFactory.createTuple(language, new Object[]{innerTuple}));
                   }
               }
               // The String form is in the LDAP format, where the elements are in reverse order from what
               // was in the certificate
               Collections.reverse(result);
      -        return factory.createTuple(result.toArray(new Object[0]));
      +        return PFactory.createTuple(language, result.toArray(new Object[0]));
           }
       
           @TruffleBoundary
      -    private static PTuple parseSubjectAltName(X509Certificate certificate, PythonObjectFactory factory) throws CertificateParsingException {
      +    private static PTuple parseSubjectAltName(X509Certificate certificate, PythonLanguage language) throws CertificateParsingException {
               List tuples = new ArrayList<>(16);
               Collection> altNames = certificate.getSubjectAlternativeNames();
               if (altNames != null) {
      @@ -279,38 +279,39 @@ private static PTuple parseSubjectAltName(X509Certificate certificate, PythonObj
                           switch (type) {
                               // see openssl v3_alt.c#i2v_GENERAL_NAME()
                               case 0:
      -                            tuples.add(factory.createTuple(new Object[]{T_OTHERNAME, stringValue}));
      +                            tuples.add(PFactory.createTuple(language, new Object[]{T_OTHERNAME, stringValue}));
                                   break;
                               case 1:
      -                            tuples.add(factory.createTuple(new Object[]{T_EMAIL, stringValue}));
      +                            tuples.add(PFactory.createTuple(language, new Object[]{T_EMAIL, stringValue}));
                                   break;
                               case 2:
      -                            tuples.add(factory.createTuple(new Object[]{T_DNS, stringValue}));
      +                            tuples.add(PFactory.createTuple(language, new Object[]{T_DNS, stringValue}));
                                   break;
                               case 3:
      -                            tuples.add(factory.createTuple(new Object[]{T_X_400_NAME, stringValue}));
      +                            tuples.add(PFactory.createTuple(language, new Object[]{T_X_400_NAME, stringValue}));
                                   break;
                               case 4:
      -                            tuples.add(factory.createTuple(new Object[]{T_DIR_NAME, value instanceof String ? createTupleForX509Name((String) value, factory) : factory.createEmptyTuple()}));
      +                            tuples.add(PFactory.createTuple(language,
      +                                            new Object[]{T_DIR_NAME, value instanceof String ? createTupleForX509Name((String) value, language) : PFactory.createEmptyTuple(language)}));
                                   break;
                               case 5:
      -                            tuples.add(factory.createTuple(new Object[]{T_EDI_PARTY_NAME, stringValue}));
      +                            tuples.add(PFactory.createTuple(language, new Object[]{T_EDI_PARTY_NAME, stringValue}));
                                   break;
                               case 6:
      -                            tuples.add(factory.createTuple(new Object[]{T_URI, stringValue}));
      +                            tuples.add(PFactory.createTuple(language, new Object[]{T_URI, stringValue}));
                                   break;
                               case 7:
      -                            tuples.add(factory.createTuple(new Object[]{T_IP_ADDRESS, stringValue}));
      +                            tuples.add(PFactory.createTuple(language, new Object[]{T_IP_ADDRESS, stringValue}));
                                   break;
                               case 8:
      -                            tuples.add(factory.createTuple(new Object[]{T_REGISTERED_ID, stringValue}));
      +                            tuples.add(PFactory.createTuple(language, new Object[]{T_REGISTERED_ID, stringValue}));
                                   break;
                               default:
                                   continue;
                           }
                       }
                   }
      -            return factory.createTuple(tuples.toArray(new Object[tuples.size()]));
      +            return PFactory.createTuple(language, tuples.toArray(new Object[tuples.size()]));
               }
               return null;
           }
      @@ -464,7 +465,7 @@  void iterateSequence(DerSequenceConsumer consumer, T value) thr
           }
       
           @TruffleBoundary
      -    private static PTuple parseCRLPoints(X509Certificate cert, PythonObjectFactory factory) throws CertificateParsingException {
      +    private static PTuple parseCRLPoints(X509Certificate cert, PythonLanguage language) throws CertificateParsingException {
               List result = new ArrayList<>();
               byte[] bytes = cert.getExtensionValue(OID_CRL_DISTRIBUTION_POINTS);
               if (bytes == null) {
      @@ -502,14 +503,14 @@ private static PTuple parseCRLPoints(X509Certificate cert, PythonObjectFactory f
                   }
               }, result);
               if (result.size() > 0) {
      -            return factory.createTuple(result.toArray(new Object[result.size()]));
      +            return PFactory.createTuple(language, result.toArray(new Object[result.size()]));
               } else {
                   return null;
               }
           }
       
           @TruffleBoundary
      -    private static PTuple parseCAIssuers(X509Certificate cert, PythonObjectFactory factory) throws CertificateParsingException {
      +    private static PTuple parseCAIssuers(X509Certificate cert, PythonLanguage language) throws CertificateParsingException {
               List result = new ArrayList<>();
               byte[] bytes = cert.getExtensionValue(OID_AUTHORITY_INFO_ACCESS);
               if (bytes == null) {
      @@ -538,14 +539,14 @@ private static PTuple parseCAIssuers(X509Certificate cert, PythonObjectFactory f
                   }
               }, result);
               if (result.size() > 0) {
      -            return factory.createTuple(result.toArray(new Object[result.size()]));
      +            return PFactory.createTuple(language, result.toArray(new Object[result.size()]));
               } else {
                   return null;
               }
           }
       
           @TruffleBoundary
      -    private static PTuple parseOCSP(X509Certificate cert, PythonObjectFactory factory) throws CertificateParsingException {
      +    private static PTuple parseOCSP(X509Certificate cert, PythonLanguage language) throws CertificateParsingException {
               List result = new ArrayList<>();
               byte[] bytes = cert.getExtensionValue(OID_AUTHORITY_INFO_ACCESS);
               if (bytes == null) {
      @@ -574,7 +575,7 @@ private static PTuple parseOCSP(X509Certificate cert, PythonObjectFactory factor
                   }
               }, result);
               if (result.size() > 0) {
      -            return factory.createTuple(result.toArray(new Object[result.size()]));
      +            return PFactory.createTuple(language, result.toArray(new Object[result.size()]));
               } else {
                   return null;
               }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/MemoryBIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/MemoryBIOBuiltins.java
      index b4c0a6403a..51428ff7b8 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/MemoryBIOBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/MemoryBIOBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -45,7 +45,11 @@
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.ArgumentClinic;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -53,6 +57,8 @@
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary;
       import com.oracle.graal.python.builtins.objects.bytes.PBytes;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      @@ -60,7 +66,7 @@
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
       import com.oracle.graal.python.runtime.IndirectCallData;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.OverflowException;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      @@ -73,18 +79,23 @@
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PMemoryBIO)
       public final class MemoryBIOBuiltins extends PythonBuiltins {
      +
      +    public static final TpSlots SLOTS = MemoryBIOBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return MemoryBIOBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = "MemoryBIO", constructsClass = PythonBuiltinClassType.PMemoryBIO, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "MemoryBIO", minNumOfPositionalArgs = 1)
           @GenerateNodeFactory
           abstract static class MemoryBIONode extends PythonUnaryBuiltinNode {
               @Specialization
               static PMemoryBIO create(Object type,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createMemoryBIO(type);
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createMemoryBIO(language, type, getInstanceShape.execute(type));
               }
           }
       
      @@ -112,9 +123,9 @@ static boolean eof(PMemoryBIO self) {
           abstract static class ReadNode extends PythonBinaryClinicBuiltinNode {
               @Specialization
               static PBytes read(PMemoryBIO self, int size,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   int len = size >= 0 ? size : Integer.MAX_VALUE;
      -            return factory.createBytes(self.read(len));
      +            return PFactory.createBytes(language, self.read(len));
               }
       
               @Override
      @@ -133,7 +144,7 @@ static int write(VirtualFrame frame, PMemoryBIO self, Object buffer,
                               @Cached("createFor(this)") IndirectCallData indirectCallData,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
                               @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   try {
                       if (self.didWriteEOF()) {
                           throw constructAndRaiseNode.get(inliningTarget).raiseSSLError(frame, SSL_CANNOT_WRITE_AFTER_EOF);
      @@ -144,7 +155,7 @@ static int write(VirtualFrame frame, PMemoryBIO self, Object buffer,
                           self.write(bytes, len);
                           return len;
                       } catch (OverflowException | OutOfMemoryError e) {
      -                    throw raiseNode.get(inliningTarget).raise(MemoryError);
      +                    throw raiseNode.raise(inliningTarget, MemoryError);
                       }
                   } finally {
                       bufferLib.release(buffer, frame, indirectCallData);
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java
      index b69faff792..7ef0a4df79 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLCipherSelector.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -111,7 +111,7 @@ private static void selectSingle(Node node, String cipherString, List
                   if (cipherString.startsWith("@STRENGTH")) {
                       selected.sort(Comparator.comparingInt(SSLCipher::getStrengthBits).reversed());
                   } else if (cipherString.startsWith("@SECLEVEL=")) {
      -                throw PRaiseNode.raiseUncached(node, NotImplementedError, toTruffleStringUncached("@SECLEVEL not implemented"));
      +                throw PRaiseNode.raiseStatic(node, NotImplementedError, toTruffleStringUncached("@SECLEVEL not implemented"));
                   } else {
                       throw PConstructAndRaiseNode.raiseUncachedSSLError(ErrorMessages.NO_CIPHER_CAN_BE_SELECTED);
                   }
      @@ -133,7 +133,7 @@ private static List getCiphersForCipherString(Node node, String ciphe
                   List ciphers = SSLCipherStringMapping.get(component);
                   if (ciphers == null) {
                       if (component.equals("PROFILE=SYSTEM")) {
      -                    throw PRaiseNode.raiseUncached(node, NotImplementedError, toTruffleStringUncached("PROFILE=SYSTEM not implemented"));
      +                    throw PRaiseNode.raiseStatic(node, NotImplementedError, toTruffleStringUncached("PROFILE=SYSTEM not implemented"));
                       }
                       return Collections.emptyList();
                   }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java
      index 7902bad812..2011290203 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java
      @@ -78,7 +78,11 @@
       
       import org.bouncycastle.util.encoders.DecoderException;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.ArgumentClinic;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -101,6 +105,8 @@
       import com.oracle.graal.python.builtins.objects.ssl.CertUtils.NeedsPasswordException;
       import com.oracle.graal.python.builtins.objects.ssl.CertUtils.NoCertificateFoundException;
       import com.oracle.graal.python.builtins.objects.str.StringNodes;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.lib.PyCallableCheckNode;
       import com.oracle.graal.python.lib.PyNumberAsSizeNode;
       import com.oracle.graal.python.lib.PyNumberIndexNode;
      @@ -120,14 +126,13 @@
       import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
      -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToJavaLongExactNode;
       import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
       import com.oracle.graal.python.runtime.IndirectCallData;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.IPAddressUtil;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.truffle.api.CompilerDirectives;
      @@ -141,7 +146,6 @@
       import com.oracle.truffle.api.dsl.NeverDefault;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
      -import com.oracle.truffle.api.dsl.TypeSystemReference;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.library.CachedLibrary;
       import com.oracle.truffle.api.nodes.Node;
      @@ -152,12 +156,15 @@ public final class SSLContextBuiltins extends PythonBuiltins {
       
           private static final TruffleString T_ENVIRON = tsLiteral("environ");
       
      +    public static final TpSlots SLOTS = SSLContextBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return SSLContextBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = "_SSLContext", constructsClass = PythonBuiltinClassType.PSSLContext, minNumOfPositionalArgs = 2, parameterNames = {"type", "protocol"})
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "_SSLContext", minNumOfPositionalArgs = 2, parameterNames = {"type", "protocol"})
           @ArgumentClinic(name = "protocol", conversion = ArgumentClinic.ClinicConversion.Int)
           @GenerateNodeFactory
           abstract static class SSLContextNode extends PythonBinaryClinicBuiltinNode {
      @@ -165,12 +172,13 @@ abstract static class SSLContextNode extends PythonBinaryClinicBuiltinNode {
               @Specialization
               static PSSLContext createContext(VirtualFrame frame, Object type, int protocol,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   SSLMethod method = SSLMethod.fromPythonId(protocol);
                   if (method == null) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.INVALID_OR_UNSUPPORTED_PROTOCOL_VERSION, "NULL");
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.INVALID_OR_UNSUPPORTED_PROTOCOL_VERSION, "NULL");
                   }
                   try {
                       boolean checkHostname;
      @@ -182,7 +190,8 @@ static PSSLContext createContext(VirtualFrame frame, Object type, int protocol,
                           checkHostname = false;
                           verifyMode = SSLModuleBuiltins.SSL_CERT_NONE;
                       }
      -                PSSLContext context = factory.createSSLContext(type, method, SSLModuleBuiltins.X509_V_FLAG_TRUSTED_FIRST, checkHostname, verifyMode, createSSLContext());
      +                PSSLContext context = PFactory.createSSLContext(language, type, getInstanceShape.execute(type), method, SSLModuleBuiltins.X509_V_FLAG_TRUSTED_FIRST, checkHostname, verifyMode,
      +                                createSSLContext());
                       long options = SSLOptions.SSL_OP_ALL;
                       if (method != SSLMethod.SSL3) {
                           options |= SSLOptions.SSL_OP_NO_SSLv3;
      @@ -190,7 +199,7 @@ static PSSLContext createContext(VirtualFrame frame, Object type, int protocol,
                       context.setOptions(options);
                       return context;
                   } catch (NoSuchAlgorithmException e) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.INVALID_OR_UNSUPPORTED_PROTOCOL_VERSION, e);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.INVALID_OR_UNSUPPORTED_PROTOCOL_VERSION, e);
                   } catch (KeyManagementException e) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseSSLError(frame, SSLErrorCode.ERROR_SSL, e);
                   }
      @@ -227,9 +236,9 @@ static SSLEngine createSSLEngine(Node raisingNode, PSSLContext context, boolean
                       parameters.setServerNames(Collections.singletonList(new SNIHostName(serverHostname)));
                   } catch (IllegalArgumentException e) {
                       if (serverHostname.contains("\0")) {
      -                    throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.ARG_MUST_BE_ENCODED_NON_NULL);
      +                    throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.ARG_MUST_BE_ENCODED_NON_NULL);
                       }
      -                throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.INVALID_HOSTNAME);
      +                throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.INVALID_HOSTNAME);
                   }
                   if (context.getCheckHostname()) {
                       parameters.setEndpointIdentificationAlgorithm("HTTPS");
      @@ -284,15 +293,15 @@ abstract static class WrapSocketNode extends PythonClinicBuiltinNode {
               @Specialization
               static Object wrap(PSSLContext context, PSocket sock, boolean serverSide, Object serverHostnameObj, Object owner, @SuppressWarnings("unused") PNone session,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Cached StringNodes.CastToTruffleStringCheckedNode cast,
      -                        @Cached TruffleString.ToJavaStringNode toJavaStringNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Cached TruffleString.ToJavaStringNode toJavaStringNode) {
                   TruffleString serverHostname = null;
                   if (!(serverHostnameObj instanceof PNone)) {
                       serverHostname = cast.cast(inliningTarget, serverHostnameObj, ErrorMessages.S_MUST_BE_NONE_OR_STRING, "serverHostname", serverHostnameObj);
                   }
                   SSLEngine engine = createSSLEngine(inliningTarget, context, serverSide, serverHostname == null ? null : toJavaStringNode.execute(serverHostname));
      -            PSSLSocket sslSocket = factory.createSSLSocket(PythonBuiltinClassType.PSSLSocket, context, engine, sock);
      +            PSSLSocket sslSocket = PFactory.createSSLSocket(language, context, engine, sock);
                   if (!(owner instanceof PNone)) {
                       sslSocket.setOwner(owner);
                   }
      @@ -303,8 +312,8 @@ static Object wrap(PSSLContext context, PSocket sock, boolean serverSide, Object
               @Fallback
               @SuppressWarnings("unused")
               static Object wrap(Object context, Object sock, Object serverSide, Object serverHostname, Object owner, Object session,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.INVALID_WRAP_SOCKET_CALL);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.INVALID_WRAP_SOCKET_CALL);
               }
       
               @Override
      @@ -321,15 +330,15 @@ abstract static class WrapBIONode extends PythonClinicBuiltinNode {
               static Object wrap(PSSLContext context, PMemoryBIO incoming, PMemoryBIO outgoing, boolean serverSide, Object serverHostnameObj, Object owner,
                               @SuppressWarnings("unused") PNone session,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Cached StringNodes.CastToTruffleStringCheckedNode cast,
      -                        @Cached TruffleString.ToJavaStringNode toJavaStringNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Cached TruffleString.ToJavaStringNode toJavaStringNode) {
                   TruffleString serverHostname = null;
                   if (!(serverHostnameObj instanceof PNone)) {
                       serverHostname = cast.cast(inliningTarget, serverHostnameObj, ErrorMessages.S_MUST_BE_NONE_OR_STRING, "serverHostname", serverHostnameObj);
                   }
                   SSLEngine engine = createSSLEngine(inliningTarget, context, serverSide, serverHostname == null ? null : toJavaStringNode.execute(serverHostname));
      -            PSSLSocket sslSocket = factory.createSSLSocket(PythonBuiltinClassType.PSSLSocket, context, engine, incoming, outgoing);
      +            PSSLSocket sslSocket = PFactory.createSSLSocket(language, context, engine, incoming, outgoing);
                   if (!(owner instanceof PNone)) {
                       sslSocket.setOwner(owner);
                   }
      @@ -340,8 +349,8 @@ static Object wrap(PSSLContext context, PMemoryBIO incoming, PMemoryBIO outgoing
               @Fallback
               @SuppressWarnings("unused")
               static Object wrap(Object context, Object incoming, Object outgoing, Object serverSide, Object serverHostname, Object owner, Object session,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.INVALID_WRAP_BIO_CALL);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.INVALID_WRAP_BIO_CALL);
               }
       
               @Override
      @@ -429,10 +438,10 @@ static int get(PSSLContext self, @SuppressWarnings("unused") PNone value) {
               static Object set(VirtualFrame frame, PSSLContext self, Object value,
                               @Bind("this") Node inliningTarget,
                               @Cached PyNumberAsSizeNode asSizeNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   int mode = asSizeNode.executeLossy(frame, inliningTarget, value);
                   if (mode == SSLModuleBuiltins.SSL_CERT_NONE && self.getCheckHostname()) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.CANNOT_SET_VERIFY_MODE_TO_CERT_NONE);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.CANNOT_SET_VERIFY_MODE_TO_CERT_NONE);
                   }
                   switch (mode) {
                       case SSLModuleBuiltins.SSL_CERT_NONE:
      @@ -441,14 +450,14 @@ static Object set(VirtualFrame frame, PSSLContext self, Object value,
                           self.setVerifyMode(mode);
                           return PNone.NONE;
                       default:
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.INVALID_VALUE_FOR_VERIFY_MODE);
      +                    throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.INVALID_VALUE_FOR_VERIFY_MODE);
                   }
               }
           }
       
      -    private static void setMinMaxVersion(Node inliningTarget, PRaiseNode.Lazy raiseNode, PSSLContext context, boolean maximum, int value) {
      +    private static void setMinMaxVersion(Node inliningTarget, PRaiseNode raiseNode, PSSLContext context, boolean maximum, int value) {
               if (context.getMethod().isSingleVersion()) {
      -            throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.CONTEXT_DOESNT_SUPPORT_MIN_MAX);
      +            throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.CONTEXT_DOESNT_SUPPORT_MIN_MAX);
               }
               SSLProtocol selected = null;
               switch (value) {
      @@ -466,7 +475,7 @@ private static void setMinMaxVersion(Node inliningTarget, PRaiseNode.Lazy raiseN
                           }
                       }
                       if (selected == null) {
      -                    throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.UNSUPPORTED_PROTOCOL_VERSION, value);
      +                    throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.UNSUPPORTED_PROTOCOL_VERSION, value);
                       }
               }
               if (maximum) {
      @@ -488,7 +497,7 @@ static int get(PSSLContext self, @SuppressWarnings("unused") Object none) {
               static Object set(VirtualFrame frame, PSSLContext self, Object obj,
                               @Bind("this") Node inliningTarget,
                               @Cached PyNumberAsSizeNode asSizeNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   setMinMaxVersion(inliningTarget, raiseNode, self, false, asSizeNode.executeExact(frame, inliningTarget, obj));
                   return PNone.NONE;
               }
      @@ -506,7 +515,7 @@ static int get(PSSLContext self, @SuppressWarnings("unused") Object none) {
               static Object set(VirtualFrame frame, PSSLContext self, Object obj,
                               @Bind("this") Node inliningTarget,
                               @Cached PyNumberAsSizeNode asSizeNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   setMinMaxVersion(inliningTarget, raiseNode, self, true, asSizeNode.executeExact(frame, inliningTarget, obj));
                   return PNone.NONE;
               }
      @@ -517,13 +526,14 @@ static Object set(VirtualFrame frame, PSSLContext self, Object obj,
           abstract static class GetCiphersNode extends PythonUnaryBuiltinNode {
               @Specialization
               @TruffleBoundary
      -        static PList getCiphers(PSSLContext self) {
      +        static PList getCiphers(PSSLContext self,
      +                        @Bind PythonLanguage language) {
                   List ciphers = self.computeEnabledCiphers(self.getContext().createSSLEngine());
                   Object[] dicts = new Object[ciphers.size()];
                   for (int i = 0; i < dicts.length; i++) {
      -                dicts[i] = PythonObjectFactory.getUncached().createDict(ciphers.get(i).asKeywords());
      +                dicts[i] = PFactory.createDict(language, ciphers.get(i).asKeywords());
                   }
      -            return PythonObjectFactory.getUncached().createList(dicts);
      +            return PFactory.createList(language, dicts);
               }
           }
       
      @@ -546,22 +556,21 @@ protected ArgumentClinicProvider getArgumentClinic() {
       
           @Builtin(name = "num_tickets", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
           abstract static class NumTicketsNode extends PythonBinaryBuiltinNode {
               @SuppressWarnings("unused")
               @Specialization(guards = "isNoValue(value)")
               static int get(PSSLContext self, PNone value,
      -                        @Shared @Cached PRaiseNode raiseNode) {
      +                        @Bind("this") Node inliningTarget) {
                   // not used yet so rather raise error
      -            throw raiseNode.raise(NotImplementedError);
      +            throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError);
               }
       
               @SuppressWarnings("unused")
               @Specialization(guards = "!isNoValue(value)")
               static Object set(VirtualFrame frame, PSSLContext self, Object value,
      -                        @Shared @Cached PRaiseNode raiseNode) {
      +                        @Bind("this") Node inliningTarget) {
                   // not used yet so rather raise error
      -            throw raiseNode.raise(NotImplementedError);
      +            throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError);
                   // int num;
                   // try {
                   // num = (int) castToLong.execute(lib.asIndexWithFrame(value, frame));
      @@ -584,8 +593,8 @@ static Object set(VirtualFrame frame, PSSLContext self, Object value,
           abstract static class SNICallbackNode extends PythonBinaryBuiltinNode {
               @Specialization
               static Object notImplemented(@SuppressWarnings("unused") PSSLContext self, @SuppressWarnings("unused") Object value,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(NotImplementedError);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError);
               }
           }
       
      @@ -641,13 +650,13 @@ Object set(VirtualFrame frame, PSSLContext self,
               @NeverDefault
               @TruffleBoundary
               protected PBytes createCertFileKey() {
      -            return PythonObjectFactory.getUncached().createBytes("SSL_CERT_FILE".getBytes());
      +            return PFactory.createBytes(PythonLanguage.get(null), "SSL_CERT_FILE".getBytes());
               }
       
               @NeverDefault
               @TruffleBoundary
               protected PBytes createCertDirKey() {
      -            return PythonObjectFactory.getUncached().createBytes("SSL_CERT_DIR".getBytes());
      +            return PFactory.createBytes(PythonLanguage.get(null), "SSL_CERT_DIR".getBytes());
               }
       
               @NeverDefault
      @@ -683,8 +692,8 @@ abstract static class CertStoreStatsNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object storeStats(VirtualFrame frame, PSSLContext self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language,
      +                        @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
                   try {
                       int x509 = 0, crl = 0, ca = 0;
                       for (X509Certificate cert : self.getCACerts()) {
      @@ -698,7 +707,7 @@ static Object storeStats(VirtualFrame frame, PSSLContext self,
                               }
                           }
                       }
      -                return factory.createDict(new PKeyword[]{new PKeyword(T_X509, x509), new PKeyword(T_CRL, crl), new PKeyword(T_X509_CA, ca)});
      +                return PFactory.createDict(language, new PKeyword[]{new PKeyword(T_X509, x509), new PKeyword(T_CRL, crl), new PKeyword(T_X509_CA, ca)});
                   } catch (Exception ex) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseSSLError(frame, SSLErrorCode.ERROR_SSL, ex);
                   }
      @@ -707,7 +716,6 @@ static Object storeStats(VirtualFrame frame, PSSLContext self,
       
           @Builtin(name = "load_verify_locations", minNumOfPositionalArgs = 1, parameterNames = {"$self", "cafile", "capath", "cadata"})
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
           abstract static class LoadVerifyLocationsNode extends PythonQuaternaryBuiltinNode {
               @Specialization
               Object load(VirtualFrame frame, PSSLContext self, Object cafile, Object capath, Object cadata,
      @@ -718,15 +726,15 @@ Object load(VirtualFrame frame, PSSLContext self, Object cafile, Object capath,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
                               @Cached TruffleString.ToJavaStringNode toJavaStringNode,
                               @Cached TruffleString.EqualNode eqNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (cafile instanceof PNone && capath instanceof PNone && cadata instanceof PNone) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CA_FILE_PATH_DATA_CANNOT_BE_ALL_OMMITED);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CA_FILE_PATH_DATA_CANNOT_BE_ALL_OMMITED);
                   }
                   if (!(cafile instanceof PNone) && !PGuards.isString(cafile) && !PGuards.isBytes(cafile)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_SHOULD_BE_A_VALID_FILESYSTEMPATH, "cafile");
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_SHOULD_BE_A_VALID_FILESYSTEMPATH, "cafile");
                   }
                   if (!(capath instanceof PNone) && !PGuards.isString(capath) && !PGuards.isBytes(capath)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_SHOULD_BE_A_VALID_FILESYSTEMPATH, "capath");
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_SHOULD_BE_A_VALID_FILESYSTEMPATH, "capath");
                   }
                   final TruffleFile file;
                   if (!(cafile instanceof PNone)) {
      @@ -753,7 +761,7 @@ Object load(VirtualFrame frame, PSSLContext self, Object cafile, Object capath,
                               if (cadata instanceof PBytesLike) {
                                   certificates = fromBytesLike(toBytes.execute(inliningTarget, ((PBytesLike) cadata).getSequenceStorage()));
                               } else {
      -                            throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_SHOULD_BE_ASCII_OR_BYTELIKE, "cadata");
      +                            throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_SHOULD_BE_ASCII_OR_BYTELIKE, "cadata");
                               }
                           }
                           self.setCAEntries(certificates);
      @@ -785,10 +793,10 @@ private TruffleFile toTruffleFile(VirtualFrame frame, Node inliningTarget, PyUni
                   }
               }
       
      -        private static List fromString(Node inliningTarget, String dataString, PRaiseNode.Lazy raiseNode)
      +        private static List fromString(Node inliningTarget, String dataString, PRaiseNode raiseNode)
                               throws IOException, CertificateException, CRLException {
                   if (dataString.isEmpty()) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.EMPTY_CERTIFICATE_DATA);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.EMPTY_CERTIFICATE_DATA);
                   }
                   return getCertificates(dataString);
               }
      @@ -830,7 +838,6 @@ private static Collection fromBytesLike(byte[] bytes) {
       
           @Builtin(name = "load_cert_chain", minNumOfPositionalArgs = 2, parameterNames = {"$self", "certfile", "keyfile", "password"})
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonArithmeticTypes.class)
           abstract static class LoadCertChainNode extends PythonQuaternaryBuiltinNode {
               @Specialization
               Object load(VirtualFrame frame, PSSLContext self, Object certfile, Object keyfile, Object passwordObj,
      @@ -840,12 +847,12 @@ Object load(VirtualFrame frame, PSSLContext self, Object certfile, Object keyfil
                               @Cached GetPasswordNode getPasswordNode,
                               @Cached TruffleString.ToJavaStringNode toJavaStringNode,
                               @Cached TruffleString.EqualNode eqNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (!PGuards.isString(certfile) && !PGuards.isBytes(certfile)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_SHOULD_BE_A_VALID_FILESYSTEMPATH, "certfile");
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_SHOULD_BE_A_VALID_FILESYSTEMPATH, "certfile");
                   }
                   if (!(keyfile instanceof PNone) && !PGuards.isString(keyfile) && !PGuards.isBytes(keyfile)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_SHOULD_BE_A_VALID_FILESYSTEMPATH, "keyfile");
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_SHOULD_BE_A_VALID_FILESYSTEMPATH, "keyfile");
                   }
                   Object kf = keyfile instanceof PNone ? certfile : keyfile;
                   TruffleFile certTruffleFile = toTruffleFile(frame, inliningTarget, asPath.execute(frame, certfile), toJavaStringNode, eqNode, constructAndRaiseNode);
      @@ -862,7 +869,7 @@ Object load(VirtualFrame frame, PSSLContext self, Object certfile, Object keyfil
                                   throw CompilerDirectives.shouldNotReachHere();
                               }
                           }
      -                    throw raiseNode.get(inliningTarget).raise(NotImplementedError, ErrorMessages.PASSWORD_NOT_IMPLEMENTED);
      +                    throw raiseNode.raise(inliningTarget, NotImplementedError, ErrorMessages.PASSWORD_NOT_IMPLEMENTED);
                       }
                   } catch (IOException ex) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseSSLError(frame, SSLErrorCode.ERROR_SSL, ex);
      @@ -883,7 +890,7 @@ private BufferedReader getReader(TruffleFile file, String arg) throws IOExceptio
                       LOGGER.fine(() -> String.format("load_cert_chain %s:%s", arg, file.getPath()));
                       return file.newBufferedReader();
                   } catch (CannotCastException e) {
      -                throw PRaiseNode.raiseUncached(this, TypeError, ErrorMessages.S_SHOULD_BE_A_VALID_FILESYSTEMPATH, arg);
      +                throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.S_SHOULD_BE_A_VALID_FILESYSTEMPATH, arg);
                   }
               }
       
      @@ -932,20 +939,22 @@ abstract static class GetPasswordNode extends PNodeWithContext {
       
               @Specialization(guards = "isString(password)")
               static char[] doString(Object password,
      +                        @Bind("this") Node inliningTarget,
                               @Cached CastToJavaStringNode cast,
                               @Shared @Cached PRaiseNode raiseNode) {
                   String str = cast.execute(password);
      -            checkPasswordLength(raiseNode, str.length());
      +            checkPasswordLength(raiseNode, str.length(), inliningTarget);
                   return stringToChars(str);
               }
       
               @Specialization(limit = "2")
               static char[] doBytes(PBytesLike bytes,
      +                        @Bind("this") Node inliningTarget,
                               @CachedLibrary("bytes") PythonBufferAccessLibrary bufferLib,
                               @Shared @Cached PRaiseNode raiseNode) {
                   byte[] data = bufferLib.getInternalOrCopiedByteArray(bytes);
                   int length = bufferLib.getBufferLength(bytes);
      -            checkPasswordLength(raiseNode, length);
      +            checkPasswordLength(raiseNode, length, inliningTarget);
                   char[] res = new char[length];
                   for (int i = 0; i < res.length; i++) {
                       res[i] = (char) data[i];
      @@ -965,9 +974,9 @@ static char[] doCallable(VirtualFrame frame, Object callable,
                       if (PGuards.isString(result) || result instanceof PBytesLike) {
                           return recursive.execute(frame, result);
                       }
      -                throw raiseNode.raise(TypeError, ErrorMessages.PSSWD_CALLBACK_MUST_RETURN_STR);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.PSSWD_CALLBACK_MUST_RETURN_STR);
                   }
      -            throw raiseNode.raise(TypeError, ErrorMessages.PSSWD_SHOULD_BE_STR_OR_CALLABLE);
      +            throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.PSSWD_SHOULD_BE_STR_OR_CALLABLE);
               }
       
               @TruffleBoundary
      @@ -975,9 +984,9 @@ private static char[] stringToChars(String str) {
                   return str.toCharArray();
               }
       
      -        private static void checkPasswordLength(PRaiseNode raiseNode, int length) {
      +        private static void checkPasswordLength(PRaiseNode raiseNode, int length, Node inliningTarget) {
                   if (length > MAX_LEN) {
      -                throw raiseNode.raise(ValueError, ErrorMessages.PSSWD_CANNOT_BE_LONGER_THAN_D_BYTES, MAX_LEN);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.PSSWD_CANNOT_BE_LONGER_THAN_D_BYTES, MAX_LEN);
                   }
               }
           }
      @@ -988,11 +997,11 @@ abstract static class LoadDhParamsNode extends PythonBinaryBuiltinNode {
               @SuppressWarnings("unused")
               @Specialization
               static PNone load(VirtualFrame frame, PSSLContext self, Object pathObject,
      -                        @Cached PyUnicodeFSDecoderNode asPath,
      -                        @Cached PRaiseNode raiseNode) {
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached PyUnicodeFSDecoderNode asPath) {
                   TruffleString path = asPath.execute(frame, pathObject);
                   // not used yet so rather raise error
      -            throw raiseNode.raise(NotImplementedError);
      +            throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError);
                   // File file = new File(path);
                   // if (!file.exists()) {
                   // throw raiseOSError(frame, OSErrorEnum.ENOENT);
      @@ -1056,16 +1065,16 @@ abstract static class GetCACerts extends PythonBinaryClinicBuiltinNode {
               @Specialization(guards = "!binary_form")
               Object getCerts(VirtualFrame frame, PSSLContext self, @SuppressWarnings("unused") boolean binary_form,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language,
      +                        @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
                   try {
                       List result = PythonUtils.newList();
                       for (X509Certificate cert : self.getCACerts()) {
                           if (CertUtils.isCA(cert, CertUtils.getKeyUsage(cert))) {
      -                        PythonUtils.add(result, CertUtils.decodeCertificate(getContext().factory(), cert));
      +                        PythonUtils.add(result, CertUtils.decodeCertificate(cert, language));
                           }
                       }
      -                return factory.createList(PythonUtils.toArray(result));
      +                return PFactory.createList(language, PythonUtils.toArray(result));
                   } catch (KeyStoreException | NoSuchAlgorithmException | CertificateParsingException ex) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseSSLError(frame, SSLErrorCode.ERROR_SSL, ex);
                   }
      @@ -1073,15 +1082,15 @@ Object getCerts(VirtualFrame frame, PSSLContext self, @SuppressWarnings("unused"
       
               @Specialization(guards = "binary_form")
               static Object getCertsBinary(PSSLContext self, @SuppressWarnings("unused") boolean binary_form,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   try {
                       List result = PythonUtils.newList();
                       for (X509Certificate cert : self.getCACerts()) {
                           if (CertUtils.isCA(cert, CertUtils.getKeyUsage(cert))) {
      -                        PythonUtils.add(result, factory.createBytes(CertUtils.getEncoded(cert)));
      +                        PythonUtils.add(result, PFactory.createBytes(language, CertUtils.getEncoded(cert)));
                           }
                       }
      -                return factory.createList(PythonUtils.toArray(result));
      +                return PFactory.createList(language, PythonUtils.toArray(result));
                   } catch (KeyStoreException | NoSuchAlgorithmException | CertificateEncodingException ex) {
                       throw PConstructAndRaiseNode.raiseUncachedSSLError(SSLErrorCode.ERROR_SSL, ex);
                   }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLErrorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLErrorBuiltins.java
      index 4347b6ea97..bcd86d8391 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLErrorBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLErrorBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -43,12 +43,13 @@
       import static com.oracle.graal.python.builtins.objects.exception.OsErrorBuiltins.IDX_STRERROR;
       import static com.oracle.graal.python.builtins.objects.exception.OsErrorBuiltins.IDX_WRITTEN;
       import static com.oracle.graal.python.builtins.objects.ssl.SSLErrorCode.ERROR_CERT_VERIFICATION;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__;
       import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
       
       import java.util.List;
       
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -59,13 +60,13 @@
       import com.oracle.graal.python.builtins.objects.exception.OsErrorBuiltins;
       import com.oracle.graal.python.builtins.objects.exception.PBaseException;
       import com.oracle.graal.python.builtins.objects.function.PKeyword;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      @@ -85,9 +86,11 @@ public final class SSLErrorBuiltins extends PythonBuiltins {
           static final int IDX_VERIFY_MESSAGE = IDX_WRITTEN + 4;
           static final int SSL_ERR_NUM_ATTRS = IDX_VERIFY_MESSAGE + 1;
       
      -    public static final BaseExceptionAttrNode.StorageFactory SSL_ERROR_ATTR_FACTORY = (args, factory) -> new Object[SSL_ERR_NUM_ATTRS];
      +    public static final BaseExceptionAttrNode.StorageFactory SSL_ERROR_ATTR_FACTORY = (args) -> new Object[SSL_ERR_NUM_ATTRS];
           public static final TruffleString T_SSL_IN_BRACKETS = tsLiteral("[SSL]");
       
      +    public static final TpSlots SLOTS = SSLErrorBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return SSLErrorBuiltinsFactory.getFactories();
      @@ -116,17 +119,17 @@ public static void setSSLErrorAttributes(PBaseException self, SSLErrorCode error
               self.setExceptionAttributes(data);
           }
       
      -    @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @Slot(value = SlotKind.tp_init, isComplex = true)
      +    @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
           @GenerateNodeFactory
           public abstract static class SSLErrorInitNode extends PythonBuiltinNode {
               public abstract Object execute(VirtualFrame frame, PBaseException self, Object[] args, PKeyword[] kwds);
       
               @Specialization
               static Object init(VirtualFrame frame, PBaseException self, Object[] args, PKeyword[] kwds,
      -                        @Cached OsErrorBuiltins.OSErrorInitNode initNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Cached OsErrorBuiltins.OSErrorInitNode initNode) {
                   initNode.execute(frame, self, args, kwds);
      -            Object[] sslAttrs = SSL_ERROR_ATTR_FACTORY.create(args, factory);
      +            Object[] sslAttrs = SSL_ERROR_ATTR_FACTORY.create(args);
                   PythonUtils.arraycopy(self.getExceptionAttributes(), 0, sslAttrs, 0, self.getExceptionAttributes().length);
                   self.setExceptionAttributes(sslAttrs);
                   return PNone.NONE;
      @@ -173,7 +176,7 @@ Object generic(PBaseException self, Object value,
               }
           }
       
      -    @Builtin(name = J___STR__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_str, isComplex = true)
           @GenerateNodeFactory
           abstract static class StrNode extends PythonUnaryBuiltinNode {
               @Specialization
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLOperationNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLOperationNode.java
      index fc04f6d46f..8dc68a63fb 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLOperationNode.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLOperationNode.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -177,7 +177,7 @@ static void doSocket(VirtualFrame frame, Node inliningTarget, PSSLSocket socket,
                           @Cached(inline = false) GilNode gil,
                           @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
                           @Cached(inline = false) TruffleString.FromJavaStringNode fromJavaStringNode,
      -                    @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                    @Shared @Cached PRaiseNode raiseNode) {
               assert socket.getSocket() != null;
               prepare(socket);
               TimeoutHelper timeoutHelper = null;
      @@ -270,7 +270,7 @@ static void doSocket(VirtualFrame frame, Node inliningTarget, PSSLSocket socket,
                   } catch (SSLException e) {
                       throw handleSSLException(e);
                   } catch (OverflowException | OutOfMemoryError node) {
      -                throw raiseNode.get(inliningTarget).raise(MemoryError);
      +                throw raiseNode.raise(inliningTarget, MemoryError);
                   }
                   PythonContext.triggerAsyncActions(inliningTarget);
               }
      @@ -279,7 +279,7 @@ static void doSocket(VirtualFrame frame, Node inliningTarget, PSSLSocket socket,
           @Specialization(guards = "socket.getSocket() == null")
           static void doMemory(VirtualFrame frame, Node inliningTarget, PSSLSocket socket, ByteBuffer appInput, ByteBuffer targetBuffer, SSLOperation operation,
                           @Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
      -                    @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                    @Shared @Cached PRaiseNode raiseNode) {
               prepare(socket);
               SSLOperationStatus status;
               try {
      @@ -312,7 +312,7 @@ static void doMemory(VirtualFrame frame, Node inliningTarget, PSSLSocket socket,
               } catch (SSLException e) {
                   throw handleSSLException(e);
               } catch (OverflowException | OutOfMemoryError node) {
      -            throw raiseNode.get(inliningTarget).raise(MemoryError);
      +            throw raiseNode.raise(inliningTarget, MemoryError);
               }
           }
       
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLSocketBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLSocketBuiltins.java
      index 1acb11c3bf..1e25fb80b3 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLSocketBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLSocketBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -57,6 +57,7 @@
       import javax.net.ssl.SSLPeerUnverifiedException;
       import javax.net.ssl.SSLSession;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.ArgumentClinic;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
      @@ -75,8 +76,7 @@
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
       import com.oracle.graal.python.runtime.IndirectCallData;
      -import com.oracle.graal.python.runtime.PythonContext;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.dsl.Bind;
      @@ -104,18 +104,18 @@ abstract static class ReadNode extends PythonTernaryClinicBuiltinNode {
               @Specialization(guards = "isNoValue(buffer)")
               static Object read(VirtualFrame frame, PSSLSocket self, int len, @SuppressWarnings("unused") PNone buffer,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Shared @Cached SSLOperationNode sslOperationNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   if (len == 0) {
      -                return factory.createBytes(new byte[0]);
      +                return PFactory.createBytes(language, new byte[0]);
                   } else if (len < 0) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.SIZE_SHOULD_NOT_BE_NEGATIVE);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.SIZE_SHOULD_NOT_BE_NEGATIVE);
                   }
                   ByteBuffer output = PythonUtils.allocateByteBuffer(len);
                   sslOperationNode.read(frame, inliningTarget, self, output);
                   PythonUtils.flipBuffer(output);
      -            return factory.createBytes(PythonUtils.getBufferArray(output), PythonUtils.getBufferLimit(output));
      +            return PFactory.createBytes(language, PythonUtils.getBufferArray(output), PythonUtils.getBufferLimit(output));
               }
       
               @Specialization(guards = "!isNoValue(bufferObj)", limit = "3")
      @@ -126,7 +126,7 @@ static Object readInto(VirtualFrame frame, PSSLSocket self, int len, Object buff
                               @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib,
                               @Shared @Cached SSLOperationNode sslOperationNode,
                               // unused node to avoid mixing shared and non-shared inlined nodes
      -                        @SuppressWarnings("unused") @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @SuppressWarnings("unused") @Shared @Cached PRaiseNode raiseNode) {
                   Object buffer = bufferAcquireLib.acquireWritableWithTypeError(bufferObj, "read", frame, indirectCallData);
                   try {
                       int bufferLen = bufferLib.getBufferLength(buffer);
      @@ -294,9 +294,9 @@ static Object get(@SuppressWarnings("unused") PSSLSocket self, @SuppressWarnings
       
               @Specialization(guards = "!isNoValue(obj)")
               static Object set(@SuppressWarnings("unused") PSSLSocket self, @SuppressWarnings("unused") Object obj,
      -                        @Cached PRaiseNode raiseNode) {
      +                        @Bind("this") Node inliningTarget) {
                   // JDK API doesn't support setting session ID
      -            throw raiseNode.raise(NotImplementedError);
      +            throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError);
               }
           }
       
      @@ -316,15 +316,15 @@ abstract static class GetPeerCertNode extends PythonBinaryClinicBuiltinNode {
               @Specialization(guards = "der")
               static Object getPeerCertDER(PSSLSocket self, @SuppressWarnings("unused") boolean der,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory.Lazy factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   if (!self.isHandshakeComplete()) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.HANDSHAKE_NOT_DONE_YET);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.HANDSHAKE_NOT_DONE_YET);
                   }
                   Certificate certificate = getCertificate(self.getEngine());
                   if (certificate != null) {
                       try {
      -                    return factory.get(inliningTarget).createBytes(getEncoded(certificate));
      +                    return PFactory.createBytes(language, getEncoded(certificate));
                       } catch (CertificateEncodingException e) {
                           // Fallthrough
                       }
      @@ -337,20 +337,20 @@ static Object getPeerCertDER(PSSLSocket self, @SuppressWarnings("unused") boolea
               @Specialization(guards = "!der")
               static PDict getPeerCertDict(PSSLSocket self, @SuppressWarnings("unused") boolean der,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached PythonObjectFactory.Lazy factory,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   if (!self.isHandshakeComplete()) {
      -                throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.HANDSHAKE_NOT_DONE_YET);
      +                throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.HANDSHAKE_NOT_DONE_YET);
                   }
                   Certificate certificate = getCertificate(self.getEngine());
                   if (certificate instanceof X509Certificate) {
                       try {
      -                    return CertUtils.decodeCertificate(PythonContext.get(inliningTarget).factory(), (X509Certificate) certificate);
      +                    return CertUtils.decodeCertificate((X509Certificate) certificate, language);
                       } catch (CertificateParsingException e) {
      -                    return factory.get(inliningTarget).createDict();
      +                    return PFactory.createDict(language);
                       }
                   }
      -            return factory.get(inliningTarget).createDict();
      +            return PFactory.createDict(language);
               }
       
               @TruffleBoundary
      @@ -387,9 +387,9 @@ abstract static class GetChannelBinding extends PythonBinaryClinicBuiltinNode {
               @Specialization
               @SuppressWarnings("unused")
               static Object getChannelBinding(PSSLSocket self, TruffleString sbType,
      -                        @Cached PRaiseNode raiseNode) {
      +                        @Bind("this") Node inliningTarget) {
                   // JDK doesn't have an API to access what we need. BouncyCastle could provide this
      -            throw raiseNode.raise(ValueError, ErrorMessages.S_CHANNEL_BINDING_NOT_IMPLEMENTED, sbType);
      +            throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.S_CHANNEL_BINDING_NOT_IMPLEMENTED, sbType);
               }
       
               @Override
      @@ -403,7 +403,7 @@ protected ArgumentClinicProvider getArgumentClinic() {
           abstract static class CipherNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object getCipher(PSSLSocket self,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   if (!self.isHandshakeComplete()) {
                       return PNone.NONE;
                   }
      @@ -411,7 +411,7 @@ static Object getCipher(PSSLSocket self,
                   if (cipher == null) {
                       return PNone.NONE;
                   }
      -            return factory.createTuple(new Object[]{cipher.getOpensslName(), cipher.getProtocol(), cipher.getStrengthBits()});
      +            return PFactory.createTuple(language, new Object[]{cipher.getOpensslName(), cipher.getProtocol(), cipher.getStrengthBits()});
               }
       
               @TruffleBoundary
      @@ -434,13 +434,14 @@ Object get(PSSLSocket socket) {
                   if (!socket.isHandshakeComplete()) {
                       return PNone.NONE;
                   }
      +            PythonLanguage language = PythonLanguage.get(null);
                   List ciphers = socket.getContext().computeEnabledCiphers(socket.getEngine());
                   Object[] result = new Object[ciphers.size()];
                   for (int i = 0; i < ciphers.size(); i++) {
                       SSLCipher cipher = ciphers.get(i);
      -                result[i] = PythonObjectFactory.getUncached().createTuple(new Object[]{cipher.getOpensslName(), cipher.getProtocol(), cipher.getStrengthBits()});
      +                result[i] = PFactory.createTuple(language, new Object[]{cipher.getOpensslName(), cipher.getProtocol(), cipher.getStrengthBits()});
                   }
      -            return PythonObjectFactory.getUncached().createList(result);
      +            return PFactory.createList(language, result);
               }
           }
       
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java
      index a94ccb4f20..ca4dec0357 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java
      @@ -32,27 +32,15 @@
       import static com.oracle.graal.python.nodes.BuiltinNames.J_REMOVEPREFIX;
       import static com.oracle.graal.python.nodes.BuiltinNames.J_REMOVESUFFIX;
       import static com.oracle.graal.python.nodes.BuiltinNames.J_STARTSWITH;
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_STR;
       import static com.oracle.graal.python.nodes.BuiltinNames.T_ENDSWITH;
       import static com.oracle.graal.python.nodes.BuiltinNames.T_FORMAT;
       import static com.oracle.graal.python.nodes.BuiltinNames.T_STARTSWITH;
       import static com.oracle.graal.python.nodes.ErrorMessages.FILL_CHAR_MUST_BE_UNICODE_CHAR_NOT_P;
       import static com.oracle.graal.python.nodes.ErrorMessages.S_ENCODER_RETURNED_P_INSTEAD_OF_BYTES;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CONTAINS__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___FORMAT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETNEWARGS__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___TRUFFLE_RICHCOMPARE__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ADD__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___EQ__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETITEM__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETNEWARGS__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__;
      @@ -61,6 +49,7 @@
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___REPR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___STR__;
       import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING;
      +import static com.oracle.graal.python.nodes.StringLiterals.T_UTF8;
       import static com.oracle.graal.python.nodes.truffle.TruffleStringMigrationHelpers.assertNoJavaString;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.IndexError;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
      @@ -82,6 +71,7 @@
       import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -90,8 +80,12 @@
       import com.oracle.graal.python.builtins.modules.CodecsModuleBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.PNotImplemented;
      +import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary;
      +import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary;
      +import com.oracle.graal.python.builtins.objects.bytes.BytesCommonBuiltins;
       import com.oracle.graal.python.builtins.objects.bytes.PByteArray;
       import com.oracle.graal.python.builtins.objects.bytes.PBytes;
      +import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes;
       import com.oracle.graal.python.builtins.objects.common.FormatNodeBase;
       import com.oracle.graal.python.builtins.objects.common.HashingStorage;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetIterator;
      @@ -125,17 +119,23 @@
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
       import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.SqConcatBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqItemBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqRepeatBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode;
       import com.oracle.graal.python.lib.PyIndexCheckNode;
       import com.oracle.graal.python.lib.PyNumberAsSizeNode;
       import com.oracle.graal.python.lib.PyObjectGetItem;
       import com.oracle.graal.python.lib.PyObjectHashNode;
      +import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
       import com.oracle.graal.python.lib.PyUnicodeCheckNode;
      +import com.oracle.graal.python.lib.RichCmpOp;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PRaiseNode;
      @@ -148,13 +148,12 @@
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryClinicBuiltinNode;
      -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
      +import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassExactProfile;
       import com.oracle.graal.python.nodes.object.GetClassNode;
      -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode;
       import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
      @@ -166,9 +165,7 @@
       import com.oracle.graal.python.runtime.formatting.InternalFormat.Spec;
       import com.oracle.graal.python.runtime.formatting.StringFormatProcessor;
       import com.oracle.graal.python.runtime.formatting.TextFormatter;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      -import com.oracle.graal.python.util.ComparisonOp;
      -import com.oracle.graal.python.util.IntPredicate;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerAsserts;
       import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
      @@ -178,14 +175,14 @@
       import com.oracle.truffle.api.dsl.Cached.Exclusive;
       import com.oracle.truffle.api.dsl.Cached.Shared;
       import com.oracle.truffle.api.dsl.Fallback;
      -import com.oracle.truffle.api.dsl.GenerateCached;
       import com.oracle.truffle.api.dsl.GenerateInline;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.GenerateUncached;
       import com.oracle.truffle.api.dsl.ImportStatic;
      +import com.oracle.truffle.api.dsl.NeverDefault;
       import com.oracle.truffle.api.dsl.Specialization;
      -import com.oracle.truffle.api.dsl.TypeSystemReference;
       import com.oracle.truffle.api.frame.VirtualFrame;
      +import com.oracle.truffle.api.library.CachedLibrary;
       import com.oracle.truffle.api.nodes.Node;
       import com.oracle.truffle.api.profiles.InlinedBranchProfile;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
      @@ -214,7 +211,178 @@ protected List 0) {
      -                    throw PRaiseNode.raiseUncached(node, ValueError, EXPECTED_RBRACE_BEFORE_END_OF_STRING);
      +                    throw PRaiseNode.raiseStatic(node, ValueError, EXPECTED_RBRACE_BEFORE_END_OF_STRING);
                       }
                       Object rendered = renderField(node, fieldStart, i, recursive, level, formatNode);
                       out.append(rendered);
      @@ -217,13 +217,13 @@ private Field parseField(Node node, int start, int end) {
                       if (c == '!') {
                           i += 1;
                           if (i == end) {
      -                        throw PRaiseNode.raiseUncached(node, ValueError, EXPECTED_CONVERSION);
      +                        throw PRaiseNode.raiseStatic(node, ValueError, EXPECTED_CONVERSION);
                           }
                           conversion = s.charAt(i);
                           i += 1;
                           if (i < end) {
                               if (s.charAt(i) != ':') {
      -                            throw PRaiseNode.raiseUncached(node, ValueError, EXPECTED_S_AFTER_FORMAT_CONVERSION, ':');
      +                            throw PRaiseNode.raiseStatic(node, ValueError, EXPECTED_S_AFTER_FORMAT_CONVERSION, ':');
                               }
                               i += 1;
                           }
      @@ -237,7 +237,7 @@ private Field parseField(Node node, int start, int end) {
                           i += 1;
                       }
                   } else if (c == '{') {
      -                throw PRaiseNode.raiseUncached(node, ValueError, UNEXPECTED_S_IN_FIELD_NAME, "'{'");
      +                throw PRaiseNode.raiseStatic(node, ValueError, UNEXPECTED_S_IN_FIELD_NAME, "'{'");
                   }
                   i += 1;
               }
      @@ -274,10 +274,10 @@ private Object getArgument(Node node, String name) {
               if (useNumeric) {
                   if (this.autoNumberingState == ANS_MANUAL) {
                       if (isEmpty) {
      -                    throw PRaiseNode.raiseUncached(node, ValueError, SWITCHING_FROM_MANUAL_TO_AUTOMATIC_NUMBERING);
      +                    throw PRaiseNode.raiseStatic(node, ValueError, SWITCHING_FROM_MANUAL_TO_AUTOMATIC_NUMBERING);
                       }
                   } else if (!isEmpty) {
      -                throw PRaiseNode.raiseUncached(node, ValueError, SWITCHING_FROM_AUTOMATIC_TO_MANUAL_NUMBERING);
      +                throw PRaiseNode.raiseStatic(node, ValueError, SWITCHING_FROM_AUTOMATIC_TO_MANUAL_NUMBERING);
                   }
               }
               if (isEmpty) {
      @@ -289,13 +289,13 @@ private Object getArgument(Node node, String name) {
                   String kwarg = intString;
                   arg = getKeyword(node, kwarg);
               } else if (index > SysModuleBuiltins.MAXSIZE) {
      -            throw PRaiseNode.raiseUncached(node, ValueError, TOO_MANY_DECIMAL_DIGITS_IN_FORMAT_STRING);
      +            throw PRaiseNode.raiseStatic(node, ValueError, TOO_MANY_DECIMAL_DIGITS_IN_FORMAT_STRING);
               } else {
                   if (this.args == null) {
      -                throw PRaiseNode.raiseUncached(node, ValueError, FORMAT_STR_CONTAINS_POS_FIELDS);
      +                throw PRaiseNode.raiseStatic(node, ValueError, FORMAT_STR_CONTAINS_POS_FIELDS);
                   }
                   if (index >= this.args.length) {
      -                throw PRaiseNode.raiseUncached(node, IndexError, REPLACEMENT_INDEX_S_OUT_OF_RANGE, index);
      +                throw PRaiseNode.raiseStatic(node, IndexError, REPLACEMENT_INDEX_S_OUT_OF_RANGE, index);
                   }
                   arg = this.args[index];
               }
      @@ -320,7 +320,7 @@ private Object resolveLookups(Node node, Object obj, String name, int startArg,
                           i += 1;
                       }
                       if (start == i) {
      -                    throw PRaiseNode.raiseUncached(node, ValueError, EMPTY_ATTR_IN_FORMAT_STR);
      +                    throw PRaiseNode.raiseStatic(node, ValueError, EMPTY_ATTR_IN_FORMAT_STR);
                       }
                       TruffleString attr = toTruffleStringUncached(name.substring(start, i));
                       if (result != null) {
      @@ -341,11 +341,11 @@ private Object resolveLookups(Node node, Object obj, String name, int startArg,
                           i += 1;
                       }
                       if (!gotBracket) {
      -                    throw PRaiseNode.raiseUncached(node, ValueError, MISSING_S, "']'");
      +                    throw PRaiseNode.raiseStatic(node, ValueError, MISSING_S, "']'");
                       }
                       String s = name.substring(start, i);
                       if (s.isEmpty()) {
      -                    throw PRaiseNode.raiseUncached(node, ValueError, EMPTY_ATTR_IN_FORMAT_STR);
      +                    throw PRaiseNode.raiseStatic(node, ValueError, EMPTY_ATTR_IN_FORMAT_STR);
                       }
                       int index = toInt(node, s);
                       Object item = index != -1 ? index : toTruffleStringUncached(s);
      @@ -356,7 +356,7 @@ private Object resolveLookups(Node node, Object obj, String name, int startArg,
                           this.parserList.add(new Object[]{false, item});
                       }
                   } else {
      -                throw PRaiseNode.raiseUncached(node, ValueError, ONLY_S_AND_S_AMY_FOLLOW_S, "'['", "'.'", "']'");
      +                throw PRaiseNode.raiseStatic(node, ValueError, ONLY_S_AND_S_AMY_FOLLOW_S, "'['", "'.'", "']'");
                   }
               }
               return result;
      @@ -372,7 +372,7 @@ private static int toInt(Node node, String s) {
               } catch (NumberFormatException e) {
                   return -1;
               } catch (ArithmeticException e) {
      -            throw PRaiseNode.raiseUncached(node, ValueError, TOO_MANY_DECIMAL_DIGITS_IN_FORMAT_STRING);
      +            throw PRaiseNode.raiseStatic(node, ValueError, TOO_MANY_DECIMAL_DIGITS_IN_FORMAT_STRING);
               }
           }
       
      @@ -462,7 +462,7 @@ private static Object convert(Node node, Object obj, char conversion) {
                   case 'a':
                       return PyObjectAsciiNode.executeUncached(obj);
                   default:
      -                throw PRaiseNode.raiseUncached(node, ValueError, INVALID_CONVERSION);
      +                throw PRaiseNode.raiseStatic(node, ValueError, INVALID_CONVERSION);
               }
           }
       
      @@ -491,7 +491,7 @@ private Object getKeyword(Node node, String key) {
                       return result;
                   }
               }
      -        throw PRaiseNode.raiseUncached(node, KeyError, tKey);
      +        throw PRaiseNode.raiseStatic(node, KeyError, tKey);
           }
       
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructBuiltins.java
      index ef7ef6c4c9..f35aefce49 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructBuiltins.java
      @@ -1,10 +1,56 @@
      -/* Copyright (c) 2020, 2024, Oracle and/or its affiliates.
      +/* Copyright (c) 2020, 2025, Oracle and/or its affiliates.
        * Copyright (C) 1996-2020 Python Software Foundation
        *
        * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
        */
       package com.oracle.graal.python.builtins.objects.struct;
       
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_BOOL;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_CHAR;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_DOUBLE;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_FLOAT;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_HALF_FLOAT;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_INT;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_LONG;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_LONG_LONG;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_PAD_BYTE;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_PASCAL_STRING;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_SHORT;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_SIGNED_CHAR;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_SIZE_T;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_STRING;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_UNSIGNED_CHAR;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_UNSIGNED_INT;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_UNSIGNED_LONG;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_UNSIGNED_LONG_LONG;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_UNSIGNED_SHORT;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_UNSIGNED_SIZE_T;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_VOID_PTR;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_BOOL;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_CHAR;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_DOUBLE;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_FLOAT;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_HALF_FLOAT;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_INT;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_LONG;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_LONG_LONG;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_PAD_BYTE;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_PASCAL_STRING;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_SHORT;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_SIGNED_CHAR;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_SIZE_T;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_STRING;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_UNSIGNED_CHAR;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_UNSIGNED_INT;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_UNSIGNED_LONG;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_UNSIGNED_LONG_LONG;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_UNSIGNED_SHORT;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_UNSIGNED_SIZE_T;
      +import static com.oracle.graal.python.builtins.objects.struct.FormatCode.T_LBL_VOID_PTR;
      +import static com.oracle.graal.python.nodes.ErrorMessages.ARG_MUST_BE_STR_OR_BYTES;
      +import static com.oracle.graal.python.nodes.ErrorMessages.BAD_CHR_IN_STRUCT_FMT;
      +import static com.oracle.graal.python.nodes.ErrorMessages.EMBEDDED_NULL_CHARACTER;
      +import static com.oracle.graal.python.nodes.ErrorMessages.REPEAT_COUNT_WITHOUT_FMT;
       import static com.oracle.graal.python.nodes.ErrorMessages.STRUCT_ITER_CANNOT_UNPACK_FROM_STRUCT_OF_SIZE_0;
       import static com.oracle.graal.python.nodes.ErrorMessages.STRUCT_ITER_UNPACK_REQ_A_BUFFER_OF_A_MUL_OF_BYTES;
       import static com.oracle.graal.python.nodes.ErrorMessages.STRUCT_NOT_ENOUGH_DATA_TO_UNPACK_N_BYTES;
      @@ -13,37 +59,55 @@
       import static com.oracle.graal.python.nodes.ErrorMessages.STRUCT_PACK_EXPECTED_N_ITEMS_GOT_K;
       import static com.oracle.graal.python.nodes.ErrorMessages.STRUCT_PACK_INTO_REQ_BUFFER_TO_PACK;
       import static com.oracle.graal.python.nodes.ErrorMessages.STRUCT_UNPACK_FROM_REQ_AT_LEAST_N_BYTES;
      -import static com.oracle.graal.python.nodes.ErrorMessages.UNPACK_REQ_A_BUFFER_OF_N_BYTES;
       import static com.oracle.graal.python.nodes.ErrorMessages.S_TAKES_NO_KEYWORD_ARGS;
      +import static com.oracle.graal.python.nodes.ErrorMessages.UNPACK_REQ_A_BUFFER_OF_N_BYTES;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.StructError;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
       import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
       
      +import java.nio.ByteOrder;
      +import java.util.HashSet;
       import java.util.List;
      +import java.util.Set;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.ArgumentClinic;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      +import com.oracle.graal.python.builtins.PythonOS;
      +import com.oracle.graal.python.builtins.modules.StructModuleBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary;
      +import com.oracle.graal.python.builtins.objects.bytes.PBytes;
       import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.iterator.PStructUnpackIterator;
      +import com.oracle.graal.python.builtins.objects.str.PString;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
      +import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
       import com.oracle.graal.python.runtime.IndirectCallData;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
      +import com.oracle.graal.python.util.PythonUtils;
      +import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      +import com.oracle.truffle.api.dsl.ImportStatic;
       import com.oracle.truffle.api.dsl.NeverDefault;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
      @@ -82,11 +146,298 @@ public static Object[] unpackInternal(PStruct self, StructNodes.UnpackValueNode
               return values;
           }
       
      +    public static final TpSlots SLOTS = StructBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return StructBuiltinsFactory.getFactories();
           }
       
      +    @ImportStatic(PythonUtils.class)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "Struct", minNumOfPositionalArgs = 2)
      +    @GenerateNodeFactory
      +    public abstract static class ConstructStructNode extends PythonBinaryBuiltinNode {
      +        public static final int NUM_BYTES_LIMIT;
      +
      +        private static final int SHORT_ALIGN = Short.BYTES;
      +        private static final int INT_ALIGN = Integer.BYTES;
      +        private static final int LONG_ALIGN = Long.BYTES;
      +        private static final int FLOAT_ALIGN = Float.BYTES;
      +        private static final int DOUBLE_ALIGN = Double.BYTES;
      +
      +        private static final char ALIGNMENT_NATIVE_NATIVE = '@';
      +        private static final char ALIGNMENT_NATIVE_STD = '=';
      +        private static final char ALIGNMENT_LE_STD = '<';
      +        private static final char ALIGNMENT_BE_STD = '>';
      +        private static final char ALIGNMENT_NET_BE_STD = '!';
      +        private static final char DEFAULT_ALIGNMENT = ALIGNMENT_NATIVE_NATIVE;
      +        // format def tables
      +        private static final FormatDef[] FMT_TABLE = new FormatDef[128];
      +        private static final FormatDef[] FMT_TABLE_NATIVE = new FormatDef[128];
      +        static {
      +            Set numBytes = new HashSet<>();
      +
      +            setFormatDefEntry(FMT_TABLE, FMT_PAD_BYTE, T_LBL_PAD_BYTE, 1, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_SIGNED_CHAR, T_LBL_SIGNED_CHAR, 1, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_UNSIGNED_CHAR, T_LBL_UNSIGNED_CHAR, 1, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_CHAR, T_LBL_CHAR, 1, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_STRING, T_LBL_STRING, 1, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_PASCAL_STRING, T_LBL_PASCAL_STRING, 1, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_SHORT, T_LBL_SHORT, 2, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_UNSIGNED_SHORT, T_LBL_UNSIGNED_SHORT, 2, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_INT, T_LBL_INT, 4, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_UNSIGNED_INT, T_LBL_UNSIGNED_INT, 4, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_LONG, T_LBL_LONG, 4, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_UNSIGNED_LONG, T_LBL_UNSIGNED_LONG, 4, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_LONG_LONG, T_LBL_LONG_LONG, 8, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_UNSIGNED_LONG_LONG, T_LBL_UNSIGNED_LONG_LONG, 8, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_BOOL, T_LBL_BOOL, 1, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_HALF_FLOAT, T_LBL_HALF_FLOAT, 2, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_FLOAT, T_LBL_FLOAT, 4, numBytes);
      +            setFormatDefEntry(FMT_TABLE, FMT_DOUBLE, T_LBL_DOUBLE, 8, numBytes);
      +
      +            // native format table
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_PAD_BYTE, T_LBL_PAD_BYTE, Byte.BYTES, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_SIGNED_CHAR, T_LBL_SIGNED_CHAR, Byte.BYTES, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_UNSIGNED_CHAR, T_LBL_UNSIGNED_CHAR, Byte.BYTES, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_CHAR, T_LBL_CHAR, Byte.BYTES, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_STRING, T_LBL_STRING, Byte.BYTES, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_PASCAL_STRING, T_LBL_PASCAL_STRING, Byte.BYTES, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_SHORT, T_LBL_SHORT, Short.BYTES, SHORT_ALIGN, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_UNSIGNED_SHORT, T_LBL_UNSIGNED_SHORT, Short.BYTES, SHORT_ALIGN, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_INT, T_LBL_INT, Integer.BYTES, INT_ALIGN, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_UNSIGNED_INT, T_LBL_UNSIGNED_INT, Integer.BYTES, INT_ALIGN, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_LONG, T_LBL_LONG,
      +                            PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32 ? Integer.BYTES : Long.BYTES,
      +                            PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32 ? INT_ALIGN : LONG_ALIGN,
      +                            numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_UNSIGNED_LONG, T_LBL_UNSIGNED_LONG,
      +                            PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32 ? Integer.BYTES : Long.BYTES,
      +                            PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32 ? INT_ALIGN : LONG_ALIGN,
      +                            numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_SIZE_T, T_LBL_SIZE_T, Long.BYTES, LONG_ALIGN, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_UNSIGNED_SIZE_T, T_LBL_UNSIGNED_SIZE_T, Long.BYTES, LONG_ALIGN, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_LONG_LONG, T_LBL_LONG_LONG, Long.BYTES, LONG_ALIGN, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_UNSIGNED_LONG_LONG, T_LBL_UNSIGNED_LONG_LONG, Long.BYTES, LONG_ALIGN, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_BOOL, T_LBL_BOOL, Byte.BYTES, 0, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_HALF_FLOAT, T_LBL_HALF_FLOAT, Float.BYTES / 2, SHORT_ALIGN, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_FLOAT, T_LBL_FLOAT, Float.BYTES, FLOAT_ALIGN, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_DOUBLE, T_LBL_DOUBLE, Double.BYTES, DOUBLE_ALIGN, numBytes);
      +            setFormatDefEntry(FMT_TABLE_NATIVE, FMT_VOID_PTR, T_LBL_VOID_PTR, Long.BYTES, LONG_ALIGN, numBytes);
      +
      +            NUM_BYTES_LIMIT = numBytes.size();
      +        }
      +
      +        static void setFormatDefEntry(FormatDef[] table, char format, TruffleString label, int size, Set numBytes) {
      +            setFormatDefEntry(table, format, label, size, 0, numBytes);
      +        }
      +
      +        static void setFormatDefEntry(FormatDef[] table, char format, TruffleString label, int size, int alignment, Set numBytes) {
      +            table[format] = new FormatDef(format, label, size, alignment);
      +            numBytes.add(size);
      +        }
      +
      +        public final PStruct execute(Object format) {
      +            return execute(PythonBuiltinClassType.PStruct, format);
      +        }
      +
      +        public abstract PStruct execute(Object cls, Object format);
      +
      +        @Specialization(guards = "isAscii(format, getCodeRangeNode)")
      +        static PStruct struct(@SuppressWarnings("unused") Object cls, TruffleString format,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached.Shared @Cached TruffleString.CopyToByteArrayNode copyToByteArrayNode,
      +                        @Cached.Shared @Cached TruffleString.SwitchEncodingNode switchEncodingNode,
      +                        @SuppressWarnings("unused") @Cached.Shared @Cached TruffleString.GetCodeRangeNode getCodeRangeNode) {
      +            byte[] fmt = PythonUtils.getAsciiBytes(format, copyToByteArrayNode, switchEncodingNode);
      +            return PFactory.createStruct(PythonLanguage.get(inliningTarget), createStructInternal(inliningTarget, fmt));
      +        }
      +
      +        @Specialization
      +        static PStruct struct(Object cls, PString format,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached CastToTruffleStringNode castToTruffleStringNode,
      +                        @Cached.Shared @Cached TruffleString.CopyToByteArrayNode copyToByteArrayNode,
      +                        @Cached.Shared @Cached TruffleString.SwitchEncodingNode switchEncodingNode,
      +                        @SuppressWarnings("unused") @Cached.Shared @Cached TruffleString.GetCodeRangeNode getCodeRangeNode) {
      +            return struct(cls, castToTruffleStringNode.execute(inliningTarget, format), inliningTarget, copyToByteArrayNode, switchEncodingNode, getCodeRangeNode);
      +        }
      +
      +        @Specialization(limit = "1")
      +        static PStruct struct(@SuppressWarnings("unused") Object cls, PBytes format,
      +                        @Bind("this") Node inliningTarget,
      +                        @CachedLibrary("format") PythonBufferAccessLibrary bufferLib) {
      +            byte[] fmt = bufferLib.getCopiedByteArray(format);
      +            return PFactory.createStruct(PythonLanguage.get(inliningTarget), createStructInternal(inliningTarget, fmt));
      +        }
      +
      +        @Specialization(guards = {"!isPBytes(format)", "!isPString(format)", "!isAsciiTruffleString(format, getCodeRangeNode)"})
      +        static PStruct fallback(@SuppressWarnings("unused") Object cls, Object format,
      +                        @SuppressWarnings("unused") @Cached.Shared @Cached TruffleString.GetCodeRangeNode getCodeRangeNode,
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, StructError, ARG_MUST_BE_STR_OR_BYTES, "Struct()", format);
      +        }
      +
      +        protected static boolean isAsciiTruffleString(Object o, TruffleString.GetCodeRangeNode getCodeRangeNode) {
      +            return o instanceof TruffleString && PythonUtils.isAscii((TruffleString) o, getCodeRangeNode);
      +        }
      +
      +        @CompilerDirectives.TruffleBoundary
      +        private static PStruct.StructInfo createStructInternal(Node raisingNode, byte[] format) {
      +            int size = 0;
      +            int len = 0;
      +            int nCodes = 0;
      +            int num;
      +
      +            if (StructModuleBuiltins.containsNullCharacter(format)) {
      +                throw PRaiseNode.raiseStatic(raisingNode, PythonBuiltinClassType.StructError, EMBEDDED_NULL_CHARACTER);
      +            }
      +
      +            char alignment = DEFAULT_ALIGNMENT;
      +            int start = 0;
      +
      +            if (format.length > 0 && isAlignment((char) format[0])) {
      +                alignment = (char) format[0];
      +                start = 1;
      +            }
      +
      +            final FormatAlignment formatAlignment = whichAlignment(alignment);
      +            FormatDef[] formatTable = (formatAlignment.nativeSizing) ? FMT_TABLE_NATIVE : FMT_TABLE;
      +
      +            // first pass: validation
      +            for (int i = start; i < format.length; i++) {
      +                char c = (char) format[i];
      +                if (c == ' ') {
      +                    continue;
      +                } else if ('0' <= c && c <= '9') {
      +                    num = c - '0';
      +                    while (++i < format.length && '0' <= (c = (char) format[i]) && c <= '9') {
      +                        if (num >= Integer.MAX_VALUE / 10 && (num > Integer.MAX_VALUE / 10 || (c - '0') > Integer.MAX_VALUE % 10)) {
      +                            throw PRaiseNode.raiseStatic(raisingNode, StructError, ErrorMessages.STRUCT_SIZE_TOO_LONG);
      +                        }
      +                        num = num * 10 + (c - '0');
      +                    }
      +                    if (i == format.length) {
      +                        throw PRaiseNode.raiseStatic(raisingNode, StructError, REPEAT_COUNT_WITHOUT_FMT);
      +                    }
      +                } else {
      +                    num = 1;
      +                }
      +
      +                FormatDef formatDef = getEntry(raisingNode, c, formatTable);
      +
      +                switch (c) {
      +                    case 's': // fall through
      +                    case 'p':
      +                        len++;
      +                        nCodes++;
      +                        break;
      +                    case 'x':
      +                        break;
      +                    default:
      +                        len += num;
      +                        if (num != 0) {
      +                            nCodes++;
      +                        }
      +                        break;
      +                }
      +
      +                int itemSize = formatDef.size;
      +                size = align(size, c, formatDef);
      +                if (size == -1) {
      +                    throw PRaiseNode.raiseStatic(raisingNode, StructError, ErrorMessages.STRUCT_SIZE_TOO_LONG);
      +                }
      +
      +                if (num > (Integer.MAX_VALUE - size) / itemSize) {
      +                    throw PRaiseNode.raiseStatic(raisingNode, StructError, ErrorMessages.STRUCT_SIZE_TOO_LONG);
      +                }
      +                size += num * itemSize;
      +            }
      +
      +            // second pass - fill in the codes (no validation needed)
      +            FormatCode[] codes = new FormatCode[nCodes];
      +            int structSize = size;
      +            int structLen = len;
      +
      +            int j = 0;
      +            size = 0;
      +            for (int i = start; i < format.length; i++) {
      +                char c = (char) format[i];
      +                if (c == ' ') {
      +                    continue;
      +                } else if ('0' <= c && c <= '9') {
      +                    num = c - '0';
      +                    while (++i < format.length && '0' <= (c = (char) format[i]) && c <= '9') {
      +                        num = num * 10 + (c - '0');
      +                    }
      +                } else {
      +                    num = 1;
      +                }
      +
      +                FormatDef formatDef = getEntry(raisingNode, c, formatTable);
      +                size = align(size, c, formatDef);
      +                if (c == 's' || c == 'p') {
      +                    codes[j++] = new FormatCode(formatDef, size, num, 1);
      +                    size += num;
      +                } else if (c == 'x') {
      +                    size += num;
      +                } else if (num != 0) {
      +                    codes[j++] = new FormatCode(formatDef, size, formatDef.size, num);
      +                    size += formatDef.size * num;
      +                }
      +            }
      +
      +            return new PStruct.StructInfo(format, structSize, structLen, formatAlignment, codes);
      +        }
      +
      +        private static FormatDef getEntry(Node raisingNode, char format, FormatDef[] table) {
      +            FormatDef formatDef = table[format];
      +            if (formatDef != null) {
      +                return formatDef;
      +            }
      +            throw PRaiseNode.raiseStatic(raisingNode, StructError, BAD_CHR_IN_STRUCT_FMT, format);
      +        }
      +
      +        private static boolean isAlignment(char alignment) {
      +            return alignment == ALIGNMENT_LE_STD ||
      +                            alignment == ALIGNMENT_BE_STD ||
      +                            alignment == ALIGNMENT_NET_BE_STD ||
      +                            alignment == ALIGNMENT_NATIVE_STD ||
      +                            alignment == ALIGNMENT_NATIVE_NATIVE;
      +        }
      +
      +        private static FormatAlignment whichAlignment(char alignment) {
      +            switch (alignment) {
      +                case ALIGNMENT_LE_STD:
      +                    return new FormatAlignment(false, false);
      +                case ALIGNMENT_BE_STD:
      +                case ALIGNMENT_NET_BE_STD:
      +                    return new FormatAlignment(true, false);
      +                case ALIGNMENT_NATIVE_STD:
      +                    return new FormatAlignment(ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN, false);
      +                case ALIGNMENT_NATIVE_NATIVE:
      +                default:
      +                    return new FormatAlignment(ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN, true);
      +            }
      +        }
      +
      +        private static int align(int size, char c, FormatDef formatDef) {
      +            int extra;
      +            int alignedSize = size;
      +            if (formatDef.format == c) {
      +                if (formatDef.alignment > 0 && alignedSize > 0) {
      +                    extra = (formatDef.alignment - 1) - (alignedSize - 1) % (formatDef.alignment);
      +                    if (extra > Integer.MAX_VALUE - alignedSize) {
      +                        return -1;
      +                    }
      +                    alignedSize += extra;
      +                }
      +            }
      +            return alignedSize;
      +        }
      +    }
      +
           @Builtin(name = "pack", minNumOfPositionalArgs = 1, parameterNames = {"$self"}, takesVarArgs = true, takesVarKeywordArgs = true, forceSplitDirectCalls = true)
           @GenerateNodeFactory
           public abstract static class StructPackNode extends PythonVarargsBuiltinNode {
      @@ -94,24 +445,21 @@ public final Object execute(VirtualFrame frame, PStruct self, Object[] args) {
                   return execute(frame, self, args, PKeyword.EMPTY_KEYWORDS);
               }
       
      -        @Override
      -        public Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported {
      -            return this.execute(frame, self, arguments, PKeyword.EMPTY_KEYWORDS);
      -        }
      -
               @Specialization
      -        Object pack(VirtualFrame frame, PStruct self, Object[] args, PKeyword[] keywords,
      +        static Object pack(VirtualFrame frame, PStruct self, Object[] args, PKeyword[] keywords,
      +                        @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Cached StructNodes.PackValueNode packValueNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (keywords.length != 0) {
      -                throw raise(TypeError, S_TAKES_NO_KEYWORD_ARGS, "pack()");
      +                throw raiseNode.raise(inliningTarget, TypeError, S_TAKES_NO_KEYWORD_ARGS, "pack()");
                   }
                   if (args.length != self.getLen()) {
      -                throw raise(StructError, STRUCT_PACK_EXPECTED_N_ITEMS_GOT_K, self.getLen(), args.length);
      +                throw raiseNode.raise(inliningTarget, StructError, STRUCT_PACK_EXPECTED_N_ITEMS_GOT_K, self.getLen(), args.length);
                   }
                   byte[] bytes = new byte[self.getSize()];
                   packInternal(frame, self, packValueNode, args, bytes, 0);
      -            return factory.createBytes(bytes);
      +            return PFactory.createBytes(language, bytes);
               }
           }
       
      @@ -133,11 +481,11 @@ static Object packInto(VirtualFrame frame, PStruct self, Object buffer, int offs
                               @Cached("createFor(this)") IndirectCallData indirectCallData,
                               @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib,
                               @Cached StructNodes.PackValueNode packValueNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   try {
                       final long size = self.getUnsignedSize();
                       if (args.length != self.getLen()) {
      -                    throw raiseNode.get(inliningTarget).raise(StructError, STRUCT_PACK_EXPECTED_N_ITEMS_GOT_K, size, args.length);
      +                    throw raiseNode.raise(inliningTarget, StructError, STRUCT_PACK_EXPECTED_N_ITEMS_GOT_K, size, args.length);
                       }
                       int bufferOffset = offset;
                       int bufferLen = bufferLib.getBufferLength(buffer);
      @@ -153,12 +501,12 @@ static Object packInto(VirtualFrame frame, PStruct self, Object buffer, int offs
                       if (bufferOffset < 0) {
                           // Check that negative offset is low enough to fit data
                           if (bufferOffset + size > 0) {
      -                        throw raiseNode.get(inliningTarget).raise(StructError, STRUCT_NO_SPACE_TO_PACK_N_BYTES, size, bufferOffset);
      +                        throw raiseNode.raise(inliningTarget, StructError, STRUCT_NO_SPACE_TO_PACK_N_BYTES, size, bufferOffset);
                           }
       
                           // Check that negative offset is not crossing buffer boundary
                           if (bufferOffset + bufferLen < 0) {
      -                        throw raiseNode.get(inliningTarget).raise(StructError, STRUCT_OFFSET_OUT_OF_RANGE, bufferOffset, bufferLen);
      +                        throw raiseNode.raise(inliningTarget, StructError, STRUCT_OFFSET_OUT_OF_RANGE, bufferOffset, bufferLen);
                           }
       
                           bufferOffset += bufferLen;
      @@ -169,7 +517,7 @@ static Object packInto(VirtualFrame frame, PStruct self, Object buffer, int offs
                           assert bufferOffset >= 0;
                           assert size >= 0;
       
      -                    throw raiseNode.get(inliningTarget).raise(StructError, STRUCT_PACK_INTO_REQ_BUFFER_TO_PACK, size + bufferOffset, size, bufferOffset, bufferLen);
      +                    throw raiseNode.raise(inliningTarget, StructError, STRUCT_PACK_INTO_REQ_BUFFER_TO_PACK, size + bufferOffset, size, bufferOffset, bufferLen);
                       }
       
                       // TODO: GR-54860 use buffer API in the packing process
      @@ -203,18 +551,18 @@ protected ArgumentClinicProvider getArgumentClinic() {
               @Specialization(limit = "3")
               static Object unpack(VirtualFrame frame, PStruct self, Object buffer,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Cached("createFor(this)") IndirectCallData indirectCallData,
                               @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib,
                               @Cached StructNodes.UnpackValueNode unpackValueNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   try {
                       int bytesLen = bufferLib.getBufferLength(buffer);
                       byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer);
                       if (bytesLen != self.getSize()) {
      -                    throw raiseNode.get(inliningTarget).raise(StructError, UNPACK_REQ_A_BUFFER_OF_N_BYTES, self.getSize());
      +                    throw raiseNode.raise(inliningTarget, StructError, UNPACK_REQ_A_BUFFER_OF_N_BYTES, self.getSize());
                       }
      -                return factory.createTuple(unpackInternal(self, unpackValueNode, bytes, 0));
      +                return PFactory.createTuple(language, unpackInternal(self, unpackValueNode, bytes, 0));
                   } finally {
                       bufferLib.release(buffer, frame, indirectCallData);
                   }
      @@ -235,17 +583,17 @@ protected ArgumentClinicProvider getArgumentClinic() {
               @Specialization(limit = "3")
               static Object iterUnpack(VirtualFrame frame, PStruct self, Object buffer,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Cached("createFor(this)") IndirectCallData indirectCallData,
                               @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   try {
                       if (self.getSize() == 0) {
      -                    throw raiseNode.get(inliningTarget).raise(StructError, STRUCT_ITER_CANNOT_UNPACK_FROM_STRUCT_OF_SIZE_0);
      +                    throw raiseNode.raise(inliningTarget, StructError, STRUCT_ITER_CANNOT_UNPACK_FROM_STRUCT_OF_SIZE_0);
                       }
                       int bufferLen = bufferLib.getBufferLength(buffer);
                       if (bufferLen % self.getSize() != 0) {
      -                    throw raiseNode.get(inliningTarget).raise(StructError, STRUCT_ITER_UNPACK_REQ_A_BUFFER_OF_A_MUL_OF_BYTES, self.getSize());
      +                    throw raiseNode.raise(inliningTarget, StructError, STRUCT_ITER_UNPACK_REQ_A_BUFFER_OF_A_MUL_OF_BYTES, self.getSize());
                       }
                   } catch (Exception e) {
                       bufferLib.release(buffer, frame, indirectCallData);
      @@ -253,7 +601,7 @@ static Object iterUnpack(VirtualFrame frame, PStruct self, Object buffer,
                   }
                   // The buffer ownership is transferred to the iterator
                   // TODO: GR-54860 release it when iterator is collected
      -            final PStructUnpackIterator structUnpackIterator = factory.createStructUnpackIterator(self, buffer);
      +            final PStructUnpackIterator structUnpackIterator = PFactory.createStructUnpackIterator(language, self, buffer);
                   structUnpackIterator.index = 0;
                   return structUnpackIterator;
               }
      @@ -274,11 +622,11 @@ protected ArgumentClinicProvider getArgumentClinic() {
               @Specialization(limit = "3")
               static Object unpackFrom(VirtualFrame frame, PStruct self, Object buffer, int offset,
                               @Bind("this") Node inliningTarget,
      +                        @Bind PythonLanguage language,
                               @Cached("createFor(this)") IndirectCallData indirectCallData,
                               @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib,
                               @Cached StructNodes.UnpackValueNode unpackValueNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   try {
                       int bufferOffset = offset;
                       int bytesLen = bufferLib.getBufferLength(buffer);
      @@ -287,20 +635,20 @@ static Object unpackFrom(VirtualFrame frame, PStruct self, Object buffer, int of
                       final long size = self.getUnsignedSize();
                       if (bufferOffset < 0) {
                           if (bufferOffset + size > 0) {
      -                        throw raiseNode.get(inliningTarget).raise(StructError, STRUCT_NOT_ENOUGH_DATA_TO_UNPACK_N_BYTES, size, bufferOffset);
      +                        throw raiseNode.raise(inliningTarget, StructError, STRUCT_NOT_ENOUGH_DATA_TO_UNPACK_N_BYTES, size, bufferOffset);
                           }
       
                           if (bufferOffset + bytesLen < 0) {
      -                        throw raiseNode.get(inliningTarget).raise(StructError, STRUCT_OFFSET_OUT_OF_RANGE, bufferOffset, bytesLen);
      +                        throw raiseNode.raise(inliningTarget, StructError, STRUCT_OFFSET_OUT_OF_RANGE, bufferOffset, bytesLen);
                           }
                           bufferOffset += bytesLen;
                       }
       
                       if ((bytesLen - bufferOffset) < size) {
      -                    throw raiseNode.get(inliningTarget).raise(StructError, STRUCT_UNPACK_FROM_REQ_AT_LEAST_N_BYTES, size + bufferOffset, size, bufferOffset, bytesLen);
      +                    throw raiseNode.raise(inliningTarget, StructError, STRUCT_UNPACK_FROM_REQ_AT_LEAST_N_BYTES, size + bufferOffset, size, bufferOffset, bytesLen);
                       }
       
      -                return factory.createTuple(unpackInternal(self, unpackValueNode, bytes, bufferOffset));
      +                return PFactory.createTuple(language, unpackInternal(self, unpackValueNode, bytes, bufferOffset));
                   } finally {
                       bufferLib.release(buffer, frame, indirectCallData);
                   }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructNodes.java
      index 2c68a5d753..a3067ac10d 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructNodes.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructNodes.java
      @@ -5,13 +5,6 @@
        */
       package com.oracle.graal.python.builtins.objects.struct;
       
      -import static com.oracle.graal.python.builtins.modules.StructModuleBuiltins.ConstructStructNode.NUM_BYTES_LIMIT;
      -import static com.oracle.graal.python.nodes.ErrorMessages.ARG_FOR_N_MUST_BE;
      -import static com.oracle.graal.python.nodes.ErrorMessages.ARG_NOT_T;
      -import static com.oracle.graal.python.nodes.ErrorMessages.ARG_O_O_RANGE;
      -import static com.oracle.graal.python.nodes.ErrorMessages.FMT_REQ_RANGE;
      -import static com.oracle.graal.python.nodes.ErrorMessages.STRUCT_CHR_FMT_BYTES_1;
      -import static com.oracle.graal.python.nodes.ErrorMessages.STRUCT_FMT_NOT_YET_SUPPORTED;
       import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_BOOL;
       import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_CHAR;
       import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_DOUBLE;
      @@ -20,12 +13,20 @@
       import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_PASCAL_STRING;
       import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_STRING;
       import static com.oracle.graal.python.builtins.objects.struct.FormatCode.FMT_VOID_PTR;
      +import static com.oracle.graal.python.builtins.objects.struct.StructBuiltins.ConstructStructNode.NUM_BYTES_LIMIT;
      +import static com.oracle.graal.python.nodes.ErrorMessages.ARG_FOR_N_MUST_BE;
      +import static com.oracle.graal.python.nodes.ErrorMessages.ARG_NOT_T;
      +import static com.oracle.graal.python.nodes.ErrorMessages.ARG_O_O_RANGE;
      +import static com.oracle.graal.python.nodes.ErrorMessages.FMT_REQ_RANGE;
      +import static com.oracle.graal.python.nodes.ErrorMessages.STRUCT_CHR_FMT_BYTES_1;
      +import static com.oracle.graal.python.nodes.ErrorMessages.STRUCT_FMT_NOT_YET_SUPPORTED;
       import static com.oracle.graal.python.nodes.PGuards.isBytes;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.NotImplementedError;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.StructError;
       
       import java.math.BigInteger;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary;
       import com.oracle.graal.python.builtins.objects.bytes.PBytesLike;
      @@ -44,7 +45,7 @@
       import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
       import com.oracle.graal.python.nodes.util.CastToJavaBigIntegerNode;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.NumericSupport;
       import com.oracle.graal.python.util.OverflowException;
       import com.oracle.graal.python.util.PythonUtils;
      @@ -81,13 +82,13 @@ static long get(VirtualFrame frame, Object value, boolean unsigned,
                               @Cached PyLongCheckNode pyLongCheckNode,
                               @Cached PyNumberIndexNode indexNode,
                               @Cached PyLongAsLongNode pyLongAsLongNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   Object longValue;
                   if (!pyLongCheckNode.execute(inliningTarget, value)) {
                       if (indexCheckNode.execute(inliningTarget, value)) {
                           longValue = indexNode.execute(frame, inliningTarget, value);
                       } else {
      -                    throw raiseNode.get(inliningTarget).raise(StructError, ARG_NOT_T, "an integer");
      +                    throw raiseNode.raise(inliningTarget, StructError, ARG_NOT_T, "an integer");
                       }
                   } else {
                       longValue = value;
      @@ -98,10 +99,10 @@ static long get(VirtualFrame frame, Object value, boolean unsigned,
                       x = pyLongAsLongNode.execute(frame, inliningTarget, longValue);
                   } catch (PException pe) {
                       pe.expect(inliningTarget, PythonBuiltinClassType.OverflowError, errorProfile);
      -                throw raiseNode.get(inliningTarget).raise(StructError, ARG_O_O_RANGE);
      +                throw raiseNode.raise(inliningTarget, StructError, ARG_O_O_RANGE);
                   }
                   if (unsigned && x < 0) {
      -                throw raiseNode.get(inliningTarget).raise(StructError, ARG_O_O_RANGE);
      +                throw raiseNode.raise(inliningTarget, StructError, ARG_O_O_RANGE);
                   }
                   return x;
               }
      @@ -158,30 +159,30 @@ public static boolean isSupportedFormat(FormatCode formatCode) {
               }
       
               // checks
      -        private static PException raiseNumberError(FormatCode formatCode, PRaiseNode raiseNode) {
      +        private static PException raiseNumberError(Node inliningTarget, FormatCode formatCode, PRaiseNode raiseNode) {
                   if (formatCode.formatDef.name == null) {
      -                return raiseNode.raise(StructError, ARG_O_O_RANGE);
      +                return raiseNode.raise(inliningTarget, StructError, ARG_O_O_RANGE);
                   }
      -            return raiseNode.raise(StructError, FMT_REQ_RANGE, formatCode.formatDef.name, formatCode.formatDef.min, formatCode.formatDef.max);
      +            return raiseNode.raise(inliningTarget, StructError, FMT_REQ_RANGE, formatCode.formatDef.name, formatCode.formatDef.min, formatCode.formatDef.max);
               }
       
               private static PException raiseNumberErrorUncached(Node raisingNode, FormatCode formatCode) {
                   if (formatCode.formatDef.name == null) {
      -                return PRaiseNode.raiseUncached(raisingNode, StructError, ARG_O_O_RANGE);
      +                return PRaiseNode.raiseStatic(raisingNode, StructError, ARG_O_O_RANGE);
                   }
      -            return PRaiseNode.raiseUncached(raisingNode, StructError, FMT_REQ_RANGE, formatCode.formatDef.name, formatCode.formatDef.min, formatCode.formatDef.max);
      +            return PRaiseNode.raiseStatic(raisingNode, StructError, FMT_REQ_RANGE, formatCode.formatDef.name, formatCode.formatDef.min, formatCode.formatDef.max);
               }
       
      -        public static long checkLong(Node inliningTarget, FormatCode formatCode, long value, PRaiseNode.Lazy raiseNode) {
      +        public static long checkLong(Node inliningTarget, FormatCode formatCode, long value, PRaiseNode raiseNode) {
                   if (value < formatCode.formatDef.min || value > formatCode.formatDef.max) {
      -                throw raiseNumberError(formatCode, raiseNode.get(inliningTarget));
      +                throw raiseNumberError(inliningTarget, formatCode, raiseNode);
                   }
                   return value;
               }
       
      -        public static long checkLongUnsigned(Node inliningTarget, FormatCode formatCode, long value, PRaiseNode.Lazy raiseNode) {
      +        public static long checkLongUnsigned(Node inliningTarget, FormatCode formatCode, long value, PRaiseNode raiseNode) {
                   if (value < formatCode.formatDef.min || Long.compareUnsigned(value, formatCode.formatDef.max) > 0) {
      -                throw raiseNumberError(formatCode, raiseNode.get(inliningTarget));
      +                throw raiseNumberError(inliningTarget, formatCode, raiseNode);
                   }
                   return value;
               }
      @@ -221,7 +222,7 @@ public abstract static class PackValueNode extends StructBaseNode {
               public abstract void execute(VirtualFrame frame, FormatCode formatCode, FormatAlignment formatAlignment, Object value, byte[] buffer, int offset);
       
               private static void packLongInternal(Node inliningTarget, FormatCode formatCode, long value, byte[] buffer, int offset, NumericSupport numericSupport, int numBytes,
      -                        InlinedConditionProfile profileSigned, PRaiseNode.Lazy raiseNode) {
      +                        InlinedConditionProfile profileSigned, PRaiseNode raiseNode) {
                   final long num;
                   if (profileSigned.profile(inliningTarget, formatCode.isUnsigned())) {
                       num = checkLongUnsigned(inliningTarget, formatCode, value, raiseNode);
      @@ -236,7 +237,7 @@ static void packLong(FormatCode formatCode, @SuppressWarnings("unused") FormatAl
                               @Bind("this") Node inliningTarget,
                               @Cached("getNumericSupport(formatAlignment)") NumericSupport numericSupport,
                               @Shared @Cached InlinedConditionProfile profileSigned,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   packLongInternal(inliningTarget, formatCode, value, buffer, offset, numericSupport, formatCode.numBytes(), profileSigned, raiseNode);
               }
       
      @@ -245,7 +246,7 @@ static void packInt(FormatCode formatCode, @SuppressWarnings("unused") FormatAli
                               @Bind("this") Node inliningTarget,
                               @Cached("getNumericSupport(formatAlignment)") NumericSupport numericSupport,
                               @Shared @Cached InlinedConditionProfile profileSigned,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   packLongInternal(inliningTarget, formatCode, value, buffer, offset, numericSupport, formatCode.numBytes(), profileSigned, raiseNode);
               }
       
      @@ -254,12 +255,12 @@ static void packPInt(FormatCode formatCode, @SuppressWarnings("unused") FormatAl
                               @Bind("this") Node inliningTarget,
                               @Cached("getNumericSupport(formatAlignment)") NumericSupport numericSupport,
                               @Shared @Cached CastToJavaBigIntegerNode toJavaBigIntegerNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   try {
                       BigInteger num = checkBigInt(inliningTarget, formatCode, toJavaBigIntegerNode.execute(inliningTarget, value));
                       numericSupport.putBigInteger(buffer, offset, num, formatCode.numBytes());
                   } catch (OverflowException oe) {
      -                throw raiseNode.get(inliningTarget).raise(StructError, ARG_O_O_RANGE);
      +                throw raiseNode.raise(inliningTarget, StructError, ARG_O_O_RANGE);
                   }
               }
       
      @@ -267,7 +268,7 @@ static void packPInt(FormatCode formatCode, @SuppressWarnings("unused") FormatAl
               static void packFloat(FormatCode formatCode, @SuppressWarnings("unused") FormatAlignment formatAlignment, double value, byte[] buffer, int offset,
                               @Bind("this") Node inliningTarget,
                               @Cached("getNumericSupport(formatAlignment)") NumericSupport numericSupport,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   numericSupport.putDouble(inliningTarget, buffer, offset, value, formatCode.numBytes(), raiseNode);
               }
       
      @@ -275,7 +276,7 @@ static void packFloat(FormatCode formatCode, @SuppressWarnings("unused") FormatA
               static void packPFloat(FormatCode formatCode, FormatAlignment formatAlignment, PFloat value, byte[] buffer, int offset,
                               @Bind("this") Node inliningTarget,
                               @Cached("getNumericSupport(formatAlignment)") NumericSupport numericSupport,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   packFloat(formatCode, formatAlignment, value.getValue(), buffer, offset, inliningTarget, numericSupport, raiseNode);
               }
       
      @@ -290,13 +291,13 @@ static void packBytes(FormatCode formatCode, @SuppressWarnings("unused") FormatA
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached("createEqualityProfile()") PrimitiveValueProfile formatProfile,
                               @CachedLibrary("value") PythonBufferAccessLibrary bufferLib,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   int n = bufferLib.getBufferLength(value);
       
                   switch (formatProfile.profile(formatCode.formatDef.format)) {
                       case FMT_CHAR:
                           if (n != 1) {
      -                        throw raiseNode.get(inliningTarget).raise(StructError, STRUCT_CHR_FMT_BYTES_1);
      +                        throw raiseNode.raise(inliningTarget, StructError, STRUCT_CHR_FMT_BYTES_1);
                           }
                           assert n <= buffer.length - offset;
                           bufferLib.readIntoByteArray(value, 0, buffer, offset, n);
      @@ -339,7 +340,7 @@ static void packObjectCached(VirtualFrame frame, FormatCode formatCode, FormatAl
                               @Shared @Cached InlinedConditionProfile profileSigned,
                               @Shared @Cached IsBuiltinObjectProfile errorProfile,
                               @Shared @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   if (isNumberUpToSize8Unsigned(formatCode)) {
                       packLong(formatCode, formatAlignment, getLongNode.execute(frame, value, formatCode.isUnsigned()), buffer, offset, inliningTarget, numericSupport, profileSigned, raiseNode);
                   } else if (isNumberSize8Unsigned(formatCode)) {
      @@ -350,15 +351,15 @@ static void packObjectCached(VirtualFrame frame, FormatCode formatCode, FormatAl
                               BigInteger num = checkBigInt(inliningTarget, formatCode, toJavaBigIntegerNode.execute(inliningTarget, value));
                               getNumericSupport(formatAlignment).putBigInteger(buffer, offset, num, formatCode.numBytes());
                           } catch (OverflowException oe) {
      -                        throw raiseNode.get(inliningTarget).raise(StructError, ARG_O_O_RANGE);
      +                        throw raiseNode.raise(inliningTarget, StructError, ARG_O_O_RANGE);
                           } catch (PException pe) {
                               pe.expect(inliningTarget, PythonBuiltinClassType.TypeError, errorProfile);
      -                        throw raiseNode.get(inliningTarget).raise(StructError, ARG_NOT_T, "an integer");
      +                        throw raiseNode.raise(inliningTarget, StructError, ARG_NOT_T, "an integer");
                           }
                       }
                   } else if (isFmtFloat(formatCode)) {
                       if (!canBeDoubleNode.execute(inliningTarget, value)) {
      -                    throw raiseNode.get(inliningTarget).raise(StructError, ARG_NOT_T, "a float");
      +                    throw raiseNode.raise(inliningTarget, StructError, ARG_NOT_T, "a float");
                       }
                       packFloat(formatCode, formatAlignment, asDoubleNode.execute(frame, inliningTarget, value), buffer, offset, inliningTarget, numericSupport, raiseNode);
                   } else if (isFmtVoidPtr(formatCode)) {
      @@ -368,11 +369,11 @@ static void packObjectCached(VirtualFrame frame, FormatCode formatCode, FormatAl
                       packBoolean(formatCode, formatAlignment, isTrueNode.execute(frame, value), buffer, offset);
                   } else if (isFmtBytes(formatCode)) {
                       if (!isBytes(value)) {
      -                    throw raiseNode.get(inliningTarget).raise(StructError, ARG_FOR_N_MUST_BE, formatCode.formatDef.format, "bytes");
      +                    throw raiseNode.raise(inliningTarget, StructError, ARG_FOR_N_MUST_BE, formatCode.formatDef.format, "bytes");
                       }
                       packBytes(formatCode, formatAlignment, (PBytesLike) value, buffer, offset, inliningTarget, formatProfile, bufferLib, raiseNode);
                   } else {
      -                throw raiseNode.get(inliningTarget).raise(NotImplementedError, STRUCT_FMT_NOT_YET_SUPPORTED, formatCode);
      +                throw raiseNode.raise(inliningTarget, NotImplementedError, STRUCT_FMT_NOT_YET_SUPPORTED, formatCode);
                   }
               }
       
      @@ -388,7 +389,7 @@ static void packObject(VirtualFrame frame, FormatCode formatCode, FormatAlignmen
                               @Shared @Cached InlinedConditionProfile profileSigned,
                               @Shared @Cached IsBuiltinObjectProfile errorProfile,
                               @Shared @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   packObjectCached(frame, formatCode, formatAlignment, value, buffer, offset, inliningTarget, getLongNode, toJavaBigIntegerNode,
                                   canBeDoubleNode, asDoubleNode, isTrueNode,
                                   getNumericSupport(formatAlignment), formatProfile, profileSigned, errorProfile, bufferLib, raiseNode);
      @@ -406,8 +407,7 @@ static Object unpack8Cached(FormatCode formatCode, @SuppressWarnings("unused") F
                               @Cached("formatCode.numBytes()") int numBytes,
                               @Cached("getNumericSupport(formatAlignment)") NumericSupport numericSupport,
                               @Shared @Cached InlinedConditionProfile profilePIntResult,
      -                        @Shared @Cached InlinedConditionProfile profileSigned,
      -                        @Shared @Cached PythonObjectFactory.Lazy factory) {
      +                        @Shared @Cached InlinedConditionProfile profileSigned) {
                   long num;
                   if (profileSigned.profile(inliningTarget, formatCode.isUnsigned())) {
                       num = numericSupport.getLongUnsigned(buffer, offset, numBytes);
      @@ -416,7 +416,7 @@ static Object unpack8Cached(FormatCode formatCode, @SuppressWarnings("unused") F
                       num = handleSign(formatCode, num);
                   }
                   if (profilePIntResult.profile(inliningTarget, formatCode.isUnsigned() && num < 0)) {
      -                return factory.get(inliningTarget).createInt(getAsUnsignedBigInt(num));
      +                return PFactory.createInt(PythonLanguage.get(inliningTarget), getAsUnsignedBigInt(num));
                   }
                   return num;
               }
      @@ -425,10 +425,9 @@ static Object unpack8Cached(FormatCode formatCode, @SuppressWarnings("unused") F
               static Object unpack8(FormatCode formatCode, @SuppressWarnings("unused") FormatAlignment formatAlignment, byte[] buffer, int offset,
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached InlinedConditionProfile profilePIntResult,
      -                        @Shared @Cached InlinedConditionProfile profileSigned,
      -                        @Shared @Cached PythonObjectFactory.Lazy factory) {
      +                        @Shared @Cached InlinedConditionProfile profileSigned) {
                   return unpack8Cached(formatCode, formatAlignment, buffer, offset, inliningTarget, formatCode.numBytes(),
      -                            getNumericSupport(formatAlignment), profilePIntResult, profileSigned, factory);
      +                            getNumericSupport(formatAlignment), profilePIntResult, profileSigned);
               }
       
               @Specialization(guards = {"isFmtFloat(formatCode)", "numericSupport == getNumericSupport(formatAlignment)"}, limit = "3")
      @@ -441,12 +440,10 @@ static Object unpackFloat8(FormatCode formatCode, @SuppressWarnings("unused") Fo
               @SuppressWarnings("unused")
               static Object unpackVoidPtr(FormatCode formatCode, FormatAlignment formatAlignment, byte[] buffer, int offset,
                               @Bind("this") Node inliningTarget,
      -                        @Shared @Cached InlinedConditionProfile profilePIntResult,
      -                        @Shared @Cached PythonObjectFactory.Lazy factory,
      -                        @Shared @Cached PRaiseNode raiseNode) {
      +                        @Shared @Cached InlinedConditionProfile profilePIntResult) {
                   long num = getNumericSupport(formatAlignment).getLongUnsigned(buffer, offset, formatCode.numBytes());
                   if (profilePIntResult.profile(inliningTarget, num < 0)) {
      -                return factory.get(inliningTarget).createInt(getAsUnsignedBigInt(num));
      +                return PFactory.createInt(PythonLanguage.get(inliningTarget), getAsUnsignedBigInt(num));
                   }
                   return num;
               }
      @@ -459,8 +456,7 @@ static Object unpackBool(@SuppressWarnings("unused") FormatCode formatCode, @Sup
               @Specialization(guards = "isFmtBytes(formatCode)")
               static Object unpackBytes(@SuppressWarnings("unused") FormatCode formatCode, @SuppressWarnings("unused") FormatAlignment formatAlignment, byte[] buffer, int offset,
                               @Bind("this") Node inliningTarget,
      -                        @Cached(value = "createIdentityProfile()", inline = false) ValueProfile formatProfile,
      -                        @Shared @Cached PythonObjectFactory.Lazy factory) {
      +                        @Cached(value = "createIdentityProfile()", inline = false) ValueProfile formatProfile) {
                   byte[] bytes;
                   switch (formatProfile.profile(formatCode.formatDef.format)) {
                       case FMT_CHAR:
      @@ -479,14 +475,14 @@ static Object unpackBytes(@SuppressWarnings("unused") FormatCode formatCode, @Su
                           bytes = new byte[n];
                           PythonUtils.arraycopy(buffer, offset + 1, bytes, 0, n);
                   }
      -            return factory.get(inliningTarget).createBytes(bytes);
      +            return PFactory.createBytes(PythonLanguage.get(inliningTarget), bytes);
               }
       
               @Specialization(guards = "!isSupportedFormat(formatCode)")
               @SuppressWarnings("unused")
               static byte[] unpackUnsupported(FormatCode formatCode, FormatAlignment formatAlignment, byte[] buffer, int offset,
      -                        @Shared @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(NotImplementedError, STRUCT_FMT_NOT_YET_SUPPORTED, formatCode);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, STRUCT_FMT_NOT_YET_SUPPORTED, formatCode);
               }
           }
       
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructUnpackIteratorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructUnpackIteratorBuiltins.java
      index 706ba0f621..b3bb9309cc 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructUnpackIteratorBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructUnpackIteratorBuiltins.java
      @@ -1,19 +1,20 @@
      -/* Copyright (c) 2020, 2024, Oracle and/or its affiliates.
      +/* Copyright (c) 2020, 2025, Oracle and/or its affiliates.
        * Copyright (C) 1996-2020 Python Software Foundation
        *
        * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
        */
       package com.oracle.graal.python.builtins.objects.struct;
       
      -import static com.oracle.graal.python.nodes.ErrorMessages.CANNOT_CREATE_P_OBJECTS;
       import static com.oracle.graal.python.builtins.objects.struct.StructBuiltins.unpackInternal;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      +import static com.oracle.graal.python.nodes.ErrorMessages.CANNOT_CREATE_P_OBJECTS;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LENGTH_HINT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -21,12 +22,14 @@
       import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary;
       import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.iterator.PStructUnpackIterator;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.runtime.IndirectCallData;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -38,22 +41,26 @@
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PStructUnpackIterator)
       public class StructUnpackIteratorBuiltins extends PythonBuiltins {
      +
      +    public static final TpSlots SLOTS = StructUnpackIteratorBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return StructUnpackIteratorBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
           @GenerateNodeFactory
           protected abstract static class NewNode extends PythonBuiltinNode {
               @Specialization
               static Object createNew(Object type, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") PKeyword[] kwds,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(PythonBuiltinClassType.TypeError, CANNOT_CREATE_P_OBJECTS, type);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, CANNOT_CREATE_P_OBJECTS, type);
               }
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           public abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -76,23 +83,20 @@ static int lenHint(PStructUnpackIterator self,
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    public abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    public abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization(guards = "self.isExhausted()")
      -        static Object nextExhausted(@SuppressWarnings("unused") PStructUnpackIterator self,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(PythonBuiltinClassType.StopIteration);
      +        static Object nextExhausted(@SuppressWarnings("unused") PStructUnpackIterator self) {
      +            throw iteratorExhausted();
               }
       
               @Specialization(guards = "!self.isExhausted()", limit = "3")
               static Object next(VirtualFrame frame, PStructUnpackIterator self,
      -                        @Bind("this") Node inliningTarget,
                               @Cached("createFor(this)") IndirectCallData indirectCallData,
                               @Cached StructNodes.UnpackValueNode unpackValueNode,
                               @CachedLibrary("self.getBuffer()") PythonBufferAccessLibrary bufferLib,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Bind PythonLanguage language) {
                   final PStruct struct = self.getStruct();
                   final Object buffer = self.getBuffer();
                   final int bufferLen = bufferLib.getBufferLength(buffer);
      @@ -100,7 +104,7 @@ static Object next(VirtualFrame frame, PStructUnpackIterator self,
                   if (struct == null || self.index >= bufferLen) {
                       self.setExhausted();
                       bufferLib.release(buffer, frame, indirectCallData);
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.StopIteration);
      +                throw iteratorExhausted();
                   }
       
                   assert self.index + struct.getSize() <= bufferLen;
      @@ -117,7 +121,7 @@ static Object next(VirtualFrame frame, PStructUnpackIterator self,
                   }
       
                   // TODO: GR-54860 handle buffers directly in unpack
      -            Object result = factory.createTuple(unpackInternal(struct, unpackValueNode, bytes, offset));
      +            Object result = PFactory.createTuple(language, unpackInternal(struct, unpackValueNode, bytes, offset));
                   self.index += struct.getSize();
                   return result;
               }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/superobject/SuperBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/superobject/SuperBuiltins.java
      index f35dac0ca0..5c44fb206c 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/superobject/SuperBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/superobject/SuperBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -41,18 +41,19 @@
       package com.oracle.graal.python.builtins.objects.superobject;
       
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.RuntimeError;
      +import static com.oracle.graal.python.nodes.BuiltinNames.J_SUPER;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___SELF_CLASS__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___SELF__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___THISCLASS__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___CLASS__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -84,22 +85,26 @@
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PNodeWithContext;
      +import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.SpecialAttributeNames;
       import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
       import com.oracle.graal.python.nodes.bytecode.FrameInfo;
       import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode;
      +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode;
       import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
       import com.oracle.graal.python.nodes.frame.ReadCallerFrameNode;
       import com.oracle.graal.python.nodes.frame.ReadCallerFrameNode.FrameSelector;
       import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.nodes.object.IsForeignObjectNode;
      +import com.oracle.graal.python.runtime.PythonOptions;
       import com.oracle.graal.python.runtime.exception.PException;
       import com.oracle.graal.python.runtime.exception.PythonErrorType;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
      @@ -116,6 +121,7 @@
       import com.oracle.truffle.api.frame.MaterializedFrame;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.BranchProfile;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       
      @@ -193,34 +199,43 @@ static Object uncached(SuperObject self) {
               }
           }
       
      -    @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, alwaysNeedsCallerFrame = true)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = J_SUPER, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 3)
      +    @GenerateNodeFactory
      +    public abstract static class SuperNode extends PythonTernaryBuiltinNode {
      +        @Specialization(guards = "isBuiltinSuper(cls)")
      +        static Object doBuiltin(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") Object type, @SuppressWarnings("unused") Object object,
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createSuperObject(language);
      +        }
      +
      +        @Fallback
      +        static Object doOther(Object cls, @SuppressWarnings("unused") Object type, @SuppressWarnings("unused") Object object,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createSuperObject(language, cls, getInstanceShape.execute(cls));
      +        }
      +
      +        protected static boolean isBuiltinSuper(Object cls) {
      +            return cls == PythonBuiltinClassType.Super;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_init, isComplex = true)
      +    @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, alwaysNeedsCallerFrame = true)
           @GenerateNodeFactory
           public abstract static class SuperInitNode extends PythonVarargsBuiltinNode {
               @Child private IsSubtypeNode isSubtypeNode;
               @Child private GetClassNode getClassNode;
               @Child private PyObjectLookupAttr getAttrNode;
               @Child private TypeNodes.IsTypeNode isTypeNode;
      -
      -        @Override
      -        public Object varArgExecute(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported {
      -            if (keywords.length != 0) {
      -                throw raise(RuntimeError, ErrorMessages.UNEXPECTED_KEYWORD_ARGS, "super()");
      -            }
      -            if (arguments.length == 1) {
      -                return execute(frame, arguments[0], PNone.NO_VALUE, PNone.NO_VALUE);
      -            } else if (arguments.length == 2) {
      -                return execute(frame, arguments[0], arguments[1], PNone.NO_VALUE);
      -            } else if (arguments.length == 3) {
      -                return execute(frame, arguments[0], arguments[1], arguments[2]);
      -            } else {
      -                throw raise(RuntimeError, ErrorMessages.INVALID_NUMBER_OF_ARGUMENTS, "super()");
      -            }
      -        }
      +        private final BranchProfile errorProfile = BranchProfile.create();
       
               @Override
               public final Object execute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) {
                   if (keywords.length != 0) {
      -                throw raise(RuntimeError, ErrorMessages.UNEXPECTED_KEYWORD_ARGS, "super()");
      +                errorProfile.enter();
      +                throw PRaiseNode.raiseStatic(this, RuntimeError, ErrorMessages.UNEXPECTED_KEYWORD_ARGS, "super()");
                   }
                   if (arguments.length == 0) {
                       return execute(frame, self, PNone.NO_VALUE, PNone.NO_VALUE);
      @@ -229,16 +244,19 @@ public final Object execute(VirtualFrame frame, Object self, Object[] arguments,
                   } else if (arguments.length == 2) {
                       return execute(frame, self, arguments[0], arguments[1]);
                   } else {
      -                throw raise(RuntimeError, ErrorMessages.TOO_MANY_ARG, "super()");
      +                errorProfile.enter();
      +                throw PRaiseNode.raiseStatic(this, RuntimeError, ErrorMessages.TOO_MANY_ARG, "super()");
                   }
               }
       
               protected abstract Object execute(VirtualFrame frame, Object self, Object cls, Object obj);
       
               @Specialization(guards = "!isNoValue(cls)")
      -        PNone init(VirtualFrame frame, SuperObject self, Object cls, Object obj) {
      +        PNone init(VirtualFrame frame, SuperObject self, Object cls, Object obj,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached PRaiseNode raiseNode) {
                   if (!(obj instanceof PNone)) {
      -                Object type = supercheck(frame, cls, obj);
      +                Object type = supercheck(frame, inliningTarget, cls, obj, raiseNode);
                       self.init(cls, type, obj);
                   } else {
                       self.init(cls, null, null);
      @@ -257,13 +275,19 @@ protected boolean isInBuiltinFunctionRoot() {
               @Specialization(guards = {"!isInBuiltinFunctionRoot()", "isNoValue(clsArg)", "isNoValue(objArg)"})
               PNone initInPlace(VirtualFrame frame, SuperObject self, @SuppressWarnings("unused") PNone clsArg, @SuppressWarnings("unused") PNone objArg,
                               @Bind("this") Node inliningTarget,
      +                        @Shared @Cached PRaiseNode raiseNode,
                               @Shared @Cached CellBuiltins.GetRefNode getRefNode) {
      -            PBytecodeRootNode rootNode = (PBytecodeRootNode) getRootNode();
      -            Frame localFrame = frame;
      -            if (rootNode.getCodeUnit().isGeneratorOrCoroutine()) {
      -                localFrame = PArguments.getGeneratorFrame(frame);
      +            if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
      +                PBytecodeDSLRootNode rootNode = (PBytecodeDSLRootNode) getRootNode();
      +                return initFromLocalFrame(frame, inliningTarget, self, rootNode, frame, getRefNode, raiseNode);
      +            } else {
      +                PBytecodeRootNode rootNode = (PBytecodeRootNode) getRootNode();
      +                Frame localFrame = frame;
      +                if (rootNode.getCodeUnit().isGeneratorOrCoroutine()) {
      +                    localFrame = PArguments.getGeneratorFrame(frame);
      +                }
      +                return initFromLocalFrame(frame, inliningTarget, self, rootNode, localFrame, getRefNode, raiseNode);
                   }
      -            return initFromLocalFrame(frame, inliningTarget, self, rootNode, localFrame, getRefNode);
               }
       
               /**
      @@ -272,41 +296,65 @@ PNone initInPlace(VirtualFrame frame, SuperObject self, @SuppressWarnings("unuse
               @Specialization(guards = {"isInBuiltinFunctionRoot()", "isNoValue(clsArg)", "isNoValue(objArg)"})
               PNone init(VirtualFrame frame, SuperObject self, @SuppressWarnings("unused") PNone clsArg, @SuppressWarnings("unused") PNone objArg,
                               @Bind("this") Node inliningTarget,
      +                        @Shared @Cached PRaiseNode raiseNode,
                               @Cached ReadCallerFrameNode readCaller,
                               @Shared @Cached CellBuiltins.GetRefNode getRefNode) {
                   PFrame target = readCaller.executeWith(frame, FrameSelector.SKIP_PYTHON_BUILTIN, 0);
                   if (target == null) {
      -                throw raise(RuntimeError, ErrorMessages.NO_CURRENT_FRAME, "super()");
      +                throw raiseNode.raise(inliningTarget, RuntimeError, ErrorMessages.NO_CURRENT_FRAME, "super()");
                   }
                   MaterializedFrame locals = target.getLocals();
                   if (locals == null) {
      -                throw raise(RuntimeError, ErrorMessages.SUPER_NO_CLASS);
      +                throw raiseNode.raise(inliningTarget, RuntimeError, ErrorMessages.SUPER_NO_CLASS);
                   }
                   FrameInfo frameInfo = (FrameInfo) locals.getFrameDescriptor().getInfo();
      -            return initFromLocalFrame(frame, inliningTarget, self, frameInfo.getRootNode(), locals, getRefNode);
      +            if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
      +                return initFromLocalFrame(frame, inliningTarget, self, (PBytecodeDSLRootNode) frameInfo.getRootNode(), locals, getRefNode, raiseNode);
      +            } else {
      +                return initFromLocalFrame(frame, inliningTarget, self, (PBytecodeRootNode) frameInfo.getRootNode(), locals, getRefNode, raiseNode);
      +            }
      +        }
      +
      +        private PNone initFromLocalFrame(VirtualFrame frame, Node inliningTarget, SuperObject self, PBytecodeRootNode rootNode, Frame localFrame, CellBuiltins.GetRefNode getRefNode,
      +                        PRaiseNode raiseNode) {
      +            PCell classCell = rootNode.readClassCell(localFrame);
      +            if (classCell == null) {
      +                throw raiseNode.raise(inliningTarget, RuntimeError, ErrorMessages.SUPER_NO_CLASS);
      +            }
      +            Object cls = getRefNode.execute(inliningTarget, classCell);
      +            if (cls == null) {
      +                // the cell is empty
      +                throw raiseNode.raise(inliningTarget, RuntimeError, ErrorMessages.SUPER_EMPTY_CLASS);
      +            }
      +            Object obj = rootNode.readSelf(localFrame);
      +            if (obj == null) {
      +                throw raiseNode.raise(inliningTarget, RuntimeError, ErrorMessages.NO_ARGS, "super()");
      +            }
      +            return init(frame, self, cls, obj, inliningTarget, raiseNode);
               }
       
      -        private PNone initFromLocalFrame(VirtualFrame frame, Node inliningTarget, SuperObject self, PBytecodeRootNode rootNode, Frame localFrame, CellBuiltins.GetRefNode getRefNode) {
      +        private PNone initFromLocalFrame(VirtualFrame frame, Node inliningTarget, SuperObject self, PBytecodeDSLRootNode rootNode, Frame localFrame, CellBuiltins.GetRefNode getRefNode,
      +                        PRaiseNode raiseNode) {
                   PCell classCell = rootNode.readClassCell(localFrame);
                   if (classCell == null) {
      -                throw raise(RuntimeError, ErrorMessages.SUPER_NO_CLASS);
      +                throw raiseNode.raise(inliningTarget, RuntimeError, ErrorMessages.SUPER_NO_CLASS);
                   }
                   Object cls = getRefNode.execute(inliningTarget, classCell);
                   if (cls == null) {
                       // the cell is empty
      -                throw raise(RuntimeError, ErrorMessages.SUPER_EMPTY_CLASS);
      +                throw raiseNode.raise(inliningTarget, RuntimeError, ErrorMessages.SUPER_EMPTY_CLASS);
                   }
                   Object obj = rootNode.readSelf(localFrame);
                   if (obj == null) {
      -                throw raise(RuntimeError, ErrorMessages.NO_ARGS, "super()");
      +                throw raiseNode.raise(inliningTarget, RuntimeError, ErrorMessages.NO_ARGS, "super()");
                   }
      -            return init(frame, self, cls, obj);
      +            return init(frame, self, cls, obj, inliningTarget, raiseNode);
               }
       
               @SuppressWarnings("unused")
               @Fallback
               PNone initFallback(Object self, Object cls, Object obj) {
      -            throw raise(RuntimeError, ErrorMessages.INVALID_ARGS, "super()");
      +            throw PRaiseNode.raiseStatic(this, RuntimeError, ErrorMessages.INVALID_ARGS, "super()");
               }
       
               private IsSubtypeNode getIsSubtype() {
      @@ -341,7 +389,7 @@ private PyObjectLookupAttr getGetAttr() {
                   return getAttrNode;
               }
       
      -        private Object supercheck(VirtualFrame frame, Object cls, Object object) {
      +        private Object supercheck(VirtualFrame frame, Node inliningTarget, Object cls, Object object, PRaiseNode raiseNode) {
                   /*
                    * Check that a super() call makes sense. Return a type object.
                    *
      @@ -358,19 +406,19 @@ private Object supercheck(VirtualFrame frame, Object cls, Object object) {
                    * proxy for obj.
                    */
                   if (ensureIsTypeNode().executeCached(object)) {
      -                if (getIsSubtype().execute(frame, object, cls)) {
      +                if (getIsSubtype().execute(object, cls)) {
                           return object;
                       }
                   }
       
                   Object objectType = getGetClass().executeCached(object);
      -            if (getIsSubtype().execute(frame, objectType, cls)) {
      +            if (getIsSubtype().execute(objectType, cls)) {
                       return objectType;
                   } else {
                       try {
                           Object classObject = getGetAttr().executeCached(frame, object, SpecialAttributeNames.T___CLASS__);
                           if (ensureIsTypeNode().executeCached(classObject)) {
      -                        if (getIsSubtype().execute(frame, classObject, cls)) {
      +                        if (getIsSubtype().execute(classObject, cls)) {
                                   return classObject;
                               }
                           }
      @@ -378,7 +426,7 @@ private Object supercheck(VirtualFrame frame, Object cls, Object object) {
                           // error is ignored
                       }
       
      -                throw raise(PythonErrorType.TypeError, ErrorMessages.SUPER_OBJ_MUST_BE_INST_SUB_OR_TYPE);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.SUPER_OBJ_MUST_BE_INST_SUB_OR_TYPE);
                   }
               }
           }
      @@ -412,8 +460,10 @@ static Object doIt(Node inliningTarget, SuperObject self, Object obj,
                               @Cached GetTypeNode getType,
                               @Cached(inline = false) SuperInitNode superInit,
                               @Cached GetClassNode getClass,
      -                        @Cached(inline = false) PythonObjectFactory factory) {
      -            SuperObject newSuper = factory.createSuperObject(getClass.execute(inliningTarget, self));
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            Object cls = getClass.execute(inliningTarget, self);
      +            SuperObject newSuper = PFactory.createSuperObject(language, cls, getInstanceShape.execute(cls));
                   superInit.execute(null, newSuper, getType.execute(inliningTarget, self), obj);
                   return newSuper;
               }
      @@ -587,7 +637,7 @@ Object getClass(SuperObject self,
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           public abstract static class SuperReprNode extends PythonUnaryBuiltinNode {
               @Specialization
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/LockBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/CommonLockBuiltins.java
      similarity index 87%
      rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/LockBuiltins.java
      rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/CommonLockBuiltins.java
      index 41c435b6b4..ab0b6244ba 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/LockBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/CommonLockBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -43,19 +43,22 @@
       import static com.oracle.graal.python.builtins.objects.thread.AbstractPythonLock.TIMEOUT_MAX;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ENTER__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EXIT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.OverflowError;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
       
       import java.util.List;
       
       import com.oracle.graal.python.annotations.ArgumentClinic;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
      +import com.oracle.graal.python.builtins.objects.thread.CommonLockBuiltinsClinicProviders.AcquireLockNodeClinicProviderGen;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
      @@ -80,25 +83,28 @@
       import com.oracle.truffle.api.strings.TruffleString;
       
       @CoreFunctions(extendClasses = {PythonBuiltinClassType.PLock, PythonBuiltinClassType.PRLock})
      -public final class LockBuiltins extends PythonBuiltins {
      +public final class CommonLockBuiltins extends PythonBuiltins {
      +
      +    public static final TpSlots SLOTS = CommonLockBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
      -        return LockBuiltinsFactory.getFactories();
      +        return CommonLockBuiltinsFactory.getFactories();
           }
       
           public static final boolean DEFAULT_BLOCKING = AbstractPythonLock.DEFAULT_BLOCKING;
           public static final double UNSET_TIMEOUT = AbstractPythonLock.UNSET_TIMEOUT;
       
           @Builtin(name = "acquire", minNumOfPositionalArgs = 1, parameterNames = {"self", "blocking", "timeout"})
      -    @ArgumentClinic(name = "blocking", conversion = ArgumentClinic.ClinicConversion.Boolean, defaultValue = "LockBuiltins.DEFAULT_BLOCKING", useDefaultForNone = true)
      -    @ArgumentClinic(name = "timeout", conversion = ArgumentClinic.ClinicConversion.Double, defaultValue = "LockBuiltins.UNSET_TIMEOUT", useDefaultForNone = true)
      -    @ImportStatic({LockBuiltins.class, AbstractPythonLock.class})
      +    @ArgumentClinic(name = "blocking", conversion = ArgumentClinic.ClinicConversion.Boolean, defaultValue = "CommonLockBuiltins.DEFAULT_BLOCKING", useDefaultForNone = true)
      +    @ArgumentClinic(name = "timeout", conversion = ArgumentClinic.ClinicConversion.Double, defaultValue = "CommonLockBuiltins.UNSET_TIMEOUT", useDefaultForNone = true)
      +    @ImportStatic({CommonLockBuiltins.class, AbstractPythonLock.class})
           @GenerateNodeFactory
           public abstract static class AcquireLockNode extends PythonTernaryClinicBuiltinNode {
       
               @Override
               protected ArgumentClinicProvider getArgumentClinic() {
      -            return LockBuiltinsClinicProviders.AcquireLockNodeClinicProviderGen.INSTANCE;
      +            return AcquireLockNodeClinicProviderGen.INSTANCE;
               }
       
               @Specialization(guards = {"!invalidArgs(blocking, timeout)", "!blocking"})
      @@ -152,22 +158,22 @@ boolean acTimeOut(AbstractPythonLock self, @SuppressWarnings("unused") boolean b
               @SuppressWarnings("unused")
               @Specialization(guards = {"invalidArgs(blocking, timeout)", "timeout != UNSET_TIMEOUT", "!blocking"})
               static boolean err1(AbstractPythonLock self, boolean blocking, double timeout,
      -                        @Shared @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(ValueError, ErrorMessages.CANT_SPECIFY_TIMEOUT_FOR_NONBLOCKING);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.CANT_SPECIFY_TIMEOUT_FOR_NONBLOCKING);
               }
       
               @SuppressWarnings("unused")
               @Specialization(guards = {"invalidArgs(blocking, timeout)", "timeout != UNSET_TIMEOUT", "isNeg(timeout)"})
               static boolean err2(AbstractPythonLock self, boolean blocking, double timeout,
      -                        @Shared @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(ValueError, ErrorMessages.TIMEOUT_VALUE_MUST_BE_POSITIVE);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.TIMEOUT_VALUE_MUST_BE_POSITIVE);
               }
       
               @SuppressWarnings("unused")
               @Specialization(guards = {"invalidArgs(blocking, timeout)", "timeout != UNSET_TIMEOUT", "timeout > TIMEOUT_MAX"})
               static boolean err3(AbstractPythonLock self, boolean blocking, double timeout,
      -                        @Shared @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(OverflowError, ErrorMessages.TIMEOUT_VALUE_TOO_LARGE);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, OverflowError, ErrorMessages.TIMEOUT_VALUE_TOO_LARGE);
               }
       
               protected static boolean invalidArgs(boolean blocking, double timeout) {
      @@ -211,9 +217,9 @@ static Object doRelease(PLock self) {
               @Specialization
               static Object doRelease(PRLock self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (!self.isOwned()) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.LOCK_NOT_HELD);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, ErrorMessages.LOCK_NOT_HELD);
                   }
                   self.release();
                   return PNone.NONE;
      @@ -240,7 +246,7 @@ static boolean isLocked(PLock self) {
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprLockNode extends PythonUnaryBuiltinNode {
               @Specialization
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/LockTypeBuiltins.java
      similarity index 68%
      rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadBuiltins.java
      rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/LockTypeBuiltins.java
      index d932d54da1..d4c334dde2 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/LockTypeBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -42,31 +42,43 @@
       
       import java.util.List;
       
      -import com.oracle.graal.python.builtins.Builtin;
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
      +import com.oracle.graal.python.runtime.object.PFactory;
      +import com.oracle.truffle.api.dsl.Bind;
      +import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       
      -@CoreFunctions(extendClasses = PythonBuiltinClassType.PThread)
      -public final class ThreadBuiltins extends PythonBuiltins {
      +@CoreFunctions(extendClasses = PythonBuiltinClassType.PLock)
      +public class LockTypeBuiltins extends PythonBuiltins {
      +
      +    public static final TpSlots SLOTS = LockTypeBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
      -        return ThreadBuiltinsFactory.getFactories();
      +        return LockTypeBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = "native_id", minNumOfPositionalArgs = 1, isGetter = true)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "LockType", minNumOfPositionalArgs = 1)
           @GenerateNodeFactory
      -    public abstract static class GetNativeIdNode extends PythonUnaryBuiltinNode {
      +    public abstract static class ConstructLockNode extends PythonUnaryBuiltinNode {
               @Specialization
      -        @TruffleBoundary
      -        protected static long get(PThread self) {
      -            return self.getId();
      +        PLock construct(Object cls,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createLock(language, cls, getInstanceShape.execute(cls));
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PThreadLocal.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PThreadLocal.java
      index 4b3f583d5f..5c46139e74 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PThreadLocal.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PThreadLocal.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -55,7 +55,6 @@
       import com.oracle.graal.python.builtins.objects.dict.PDict;
       import com.oracle.graal.python.builtins.objects.function.PKeyword;
       import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
      -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
       import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.util.PythonUtils;
      @@ -63,7 +62,6 @@
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Cached.Shared;
      -import com.oracle.truffle.api.dsl.ImportStatic;
       import com.oracle.truffle.api.interop.InteropLibrary;
       import com.oracle.truffle.api.library.ExportLibrary;
       import com.oracle.truffle.api.library.ExportMessage;
      @@ -73,7 +71,6 @@
       import com.oracle.truffle.api.strings.TruffleString;
       
       @ExportLibrary(InteropLibrary.class)
      -@ImportStatic(SpecialMethodSlot.class)
       public final class PThreadLocal extends PythonBuiltinObject {
           private final ThreadLocal threadLocalDict;
           private final Object[] args;
      @@ -136,7 +133,7 @@ private Object readMember(Node inliningTarget, String member, HashingStorageGetI
       
           @ExportMessage
           public boolean isMemberReadable(String member,
      -                    @Bind("$node") Node inliningTarget,
      +                    @Bind Node inliningTarget,
                           @Shared("getItem") @Cached HashingStorageGetItem getItem,
                           @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode) {
               return readMember(inliningTarget, member, getItem, fromJavaStringNode) != null;
      @@ -144,7 +141,7 @@ public boolean isMemberReadable(String member,
       
           @ExportMessage
           public boolean isMemberModifiable(String member,
      -                    @Bind("$node") Node inliningTarget,
      +                    @Bind Node inliningTarget,
                           @Shared("getItem") @Cached HashingStorageGetItem getItem,
                           @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode) {
               return readMember(inliningTarget, member, getItem, fromJavaStringNode) != null;
      @@ -152,7 +149,7 @@ public boolean isMemberModifiable(String member,
       
           @ExportMessage
           public boolean isMemberInsertable(String member,
      -                    @Bind("$node") Node inliningTarget,
      +                    @Bind Node inliningTarget,
                           @Shared("getItem") @Cached HashingStorageGetItem getItem,
                           @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode) {
               return !isMemberReadable(member, inliningTarget, getItem, fromJavaStringNode);
      @@ -160,7 +157,7 @@ public boolean isMemberInsertable(String member,
       
           @ExportMessage
           public boolean isMemberInvocable(String member,
      -                    @Bind("$node") Node inliningTarget,
      +                    @Bind Node inliningTarget,
                           @Shared("getItem") @Cached HashingStorageGetItem getItem,
                           @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode) {
               PDict localDict = getThreadLocalDict();
      @@ -169,7 +166,7 @@ public boolean isMemberInvocable(String member,
       
           @ExportMessage
           public boolean isMemberRemovable(String member,
      -                    @Bind("$node") Node inliningTarget,
      +                    @Bind Node inliningTarget,
                           @Shared("getItem") @Cached HashingStorageGetItem getItem,
                           @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode) {
               return isMemberReadable(member, inliningTarget, getItem, fromJavaStringNode);
      @@ -177,7 +174,7 @@ public boolean isMemberRemovable(String member,
       
           @ExportMessage
           public boolean hasMemberReadSideEffects(String member,
      -                    @Bind("$node") Node inliningTarget,
      +                    @Bind Node inliningTarget,
                           @Shared("getItem") @Cached HashingStorageGetItem getItem,
                           @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode,
                           @Shared @Cached GetObjectSlotsNode getSlotsNode) {
      @@ -187,7 +184,7 @@ public boolean hasMemberReadSideEffects(String member,
       
           @ExportMessage
           public boolean hasMemberWriteSideEffects(String member,
      -                    @Bind("$node") Node inliningTarget,
      +                    @Bind Node inliningTarget,
                           @Shared("getItem") @Cached HashingStorageGetItem getItem,
                           @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode,
                           @Shared @Cached GetObjectSlotsNode getSlotsNode) {
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java
      index 845bf35846..ca89c93435 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -42,6 +42,10 @@
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -49,6 +53,8 @@
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      @@ -57,7 +63,7 @@
       import com.oracle.graal.python.nodes.util.CastToJavaUnsignedLongNode;
       import com.oracle.graal.python.runtime.GilNode;
       import com.oracle.graal.python.runtime.exception.PythonErrorType;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -68,11 +74,26 @@
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PRLock)
       public final class RLockBuiltins extends PythonBuiltins {
      +
      +    public static final TpSlots SLOTS = RLockBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return RLockBuiltinsFactory.getFactories();
           }
       
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "RLock", minNumOfPositionalArgs = 1)
      +    @GenerateNodeFactory
      +    public abstract static class ConstructRLockNode extends PythonUnaryBuiltinNode {
      +        @Specialization
      +        PRLock construct(Object cls,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createRLock(language, cls, getInstanceShape.execute(cls));
      +        }
      +    }
      +
           @Builtin(name = "_is_owned", minNumOfPositionalArgs = 1)
           @GenerateNodeFactory
           abstract static class IsOwnedRLockNode extends PythonUnaryBuiltinNode {
      @@ -121,13 +142,13 @@ abstract static class ReleaseSaveRLockNode extends PythonUnaryBuiltinNode {
               static Object releaseSave(PRLock self,
                               @Bind("this") Node inliningTarget,
                               @Cached InlinedConditionProfile countProfile,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Bind PythonLanguage language,
      +                        @Cached PRaiseNode raiseNode) {
                   int count = self.getCount();
                   if (countProfile.profile(inliningTarget, count == 0)) {
      -                throw raiseNode.get(inliningTarget).raise(PythonErrorType.RuntimeError, ErrorMessages.CANNOT_RELEASE_UNAQUIRED_LOCK);
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.RuntimeError, ErrorMessages.CANNOT_RELEASE_UNAQUIRED_LOCK);
                   }
      -            PTuple retVal = factory.createTuple(new Object[]{count, self.getOwnerId()});
      +            PTuple retVal = PFactory.createTuple(language, new Object[]{count, self.getOwnerId()});
                   self.releaseAll();
                   return retVal;
               }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadLocalBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadLocalBuiltins.java
      index 947e2607c1..57e98241a2 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadLocalBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadLocalBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -41,13 +41,13 @@
       package com.oracle.graal.python.builtins.objects.thread;
       
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___DICT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
      -import static com.oracle.graal.python.runtime.exception.PythonErrorType.AttributeError;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -55,10 +55,13 @@
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem;
       import com.oracle.graal.python.builtins.objects.dict.PDict;
      +import com.oracle.graal.python.builtins.objects.function.PKeyword;
      +import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins;
       import com.oracle.graal.python.builtins.objects.object.ObjectNodes;
       import com.oracle.graal.python.builtins.objects.object.ObjectNodes.GenericSetAttrWithDictNode;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
       import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.CallSlotDescrGet;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrSet;
      @@ -69,10 +72,12 @@
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
       import com.oracle.truffle.api.dsl.Bind;
      @@ -96,12 +101,24 @@ protected List> getNodeFa
               return ThreadLocalBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___INIT__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "_local", minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
           @GenerateNodeFactory
      -    abstract static class InitNode extends PythonUnaryBuiltinNode {
      +    public abstract static class ThreadLocalNode extends PythonBuiltinNode {
               @Specialization
      -        PNone repr(@SuppressWarnings("unused") PThreadLocal self) {
      -            return PNone.NONE;
      +        static PThreadLocal construct(Object cls, Object[] args, PKeyword[] keywordArgs,
      +                        @Bind Node inliningTarget,
      +                        @Bind PythonLanguage language,
      +                        @Cached TpSlots.GetCachedTpSlotsNode getSlots,
      +                        @Cached PRaiseNode raiseNode,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            if (args.length != 0 || keywordArgs.length != 0) {
      +                TpSlots slots = getSlots.execute(inliningTarget, cls);
      +                if (slots.tp_init() == ObjectBuiltins.SLOTS.tp_init()) {
      +                    throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.INITIALIZATION_ARGUMENTS_ARE_NOT_SUPPORTED);
      +                }
      +            }
      +            return PFactory.createThreadLocal(language, cls, getInstanceShape.execute(cls), args, keywordArgs);
               }
           }
       
      @@ -133,14 +150,14 @@ Object doIt(VirtualFrame frame, PThreadLocal object, Object keyObj,
                               @Cached InlinedConditionProfile hasDescrProfile,
                               @Cached InlinedConditionProfile hasDescrGetProfile,
                               @Cached InlinedConditionProfile hasValueProfile,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   // Note: getting thread local dict has potential side-effects, don't move
                   PDict localDict = getThreadLocalDict.execute(frame, object);
                   TruffleString key;
                   try {
                       key = castKeyToStringNode.execute(inliningTarget, keyObj);
                   } catch (CannotCastException e) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj);
                   }
       
                   Object type = getClassNode.execute(inliningTarget, object);
      @@ -167,7 +184,7 @@ Object doIt(VirtualFrame frame, PThreadLocal object, Object keyObj,
                           return dispatch(frame, object, type, descr, descrGetSlot);
                       }
                   }
      -            throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key);
      +            throw raiseNode.raiseAttributeError(inliningTarget, object, key);
               }
       
               private Object dispatch(VirtualFrame frame, Object object, Object type, Object descr, TpSlot get) {
      @@ -199,7 +216,7 @@ static void doGeneric(VirtualFrame frame, PThreadLocal object, Object keyObject,
                               @Bind("this") Node inliningTarget,
                               @Exclusive @Cached ThreadLocalNodes.GetThreadLocalDict getThreadLocalDict,
                               @Cached CastToTruffleStringNode castKeyToStringNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode,
      +                        @Exclusive @Cached PRaiseNode raiseNode,
                               @Exclusive @Cached GenericSetAttrWithDictNode setAttrWithDictNode) {
                   // Note: getting thread local dict has potential side-effects, don't move
                   PDict localDict = getThreadLocalDict.execute(frame, object);
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadLocalNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadLocalNodes.java
      index b42bebeab3..b1dcea9c3d 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadLocalNodes.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadLocalNodes.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,17 +40,20 @@
        */
       package com.oracle.graal.python.builtins.objects.thread;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.builtins.objects.dict.PDict;
      -import com.oracle.graal.python.lib.PyObjectLookupAttr;
      +import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotVarargs.CallSlotTpInitNode;
       import com.oracle.graal.python.nodes.PNodeWithContext;
      -import com.oracle.graal.python.nodes.SpecialMethodNames;
      -import com.oracle.graal.python.nodes.call.CallNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.InlinedBranchProfile;
       
       public abstract class ThreadLocalNodes {
       
      @@ -59,17 +62,20 @@ public abstract static class GetThreadLocalDict extends PNodeWithContext {
               public abstract PDict execute(VirtualFrame frame, PThreadLocal self);
       
               @Specialization
      -        PDict get(VirtualFrame frame, PThreadLocal self,
      +        static PDict get(VirtualFrame frame, PThreadLocal self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PyObjectLookupAttr lookup,
      -                        @Cached CallNode callNode) {
      +                        @Cached InlinedBranchProfile create,
      +                        @Cached GetObjectSlotsNode getSlots,
      +                        @Cached CallSlotTpInitNode callInit) {
                   PDict dict = self.getThreadLocalDict();
                   if (dict == null) {
      -                dict = factory.createDict();
      +                create.enter(inliningTarget);
      +                dict = PFactory.createDict(PythonLanguage.get(inliningTarget));
                       self.setThreadLocalDict(dict);
      -                Object initMethod = lookup.execute(frame, inliningTarget, self, SpecialMethodNames.T___INIT__);
      -                callNode.execute(frame, initMethod, self.getArgs(), self.getKeywords());
      +                TpSlots slots = getSlots.execute(inliningTarget, self);
      +                if (slots.tp_init() != ObjectBuiltins.SLOTS.tp_init()) {
      +                    callInit.execute(frame, inliningTarget, slots.tp_init(), self, self.getArgs(), self.getKeywords());
      +                }
                   }
                   return dict;
               }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tokenize/TokenizerIterBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tokenize/TokenizerIterBuiltins.java
      index f7a393dcbb..d44f366398 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tokenize/TokenizerIterBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tokenize/TokenizerIterBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,24 +40,31 @@
        */
       package com.oracle.graal.python.builtins.objects.tokenize;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
       import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
       
       import java.util.List;
       
      -import com.oracle.graal.python.builtins.Builtin;
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.ArgumentClinic;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      +import com.oracle.graal.python.builtins.objects.tokenize.TokenizerIterBuiltinsClinicProviders.TokenizerIterNodeClinicProviderGen;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
       import com.oracle.graal.python.pegparser.tokenizer.Token;
       import com.oracle.graal.python.pegparser.tokenizer.Token.Kind;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -69,12 +76,33 @@
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PTokenizerIter)
       public final class TokenizerIterBuiltins extends PythonBuiltins {
       
      +    public static final TpSlots SLOTS = TokenizerIterBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return TokenizerIterBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "TokenizerIter", minNumOfPositionalArgs = 2, parameterNames = {"$cls", "source"})
      +    @ArgumentClinic(name = "source", conversion = ArgumentClinic.ClinicConversion.TString)
      +    @GenerateNodeFactory
      +    public abstract static class TokenizerIterNode extends PythonBinaryClinicBuiltinNode {
      +
      +        @Override
      +        protected ArgumentClinicProvider getArgumentClinic() {
      +            return TokenizerIterNodeClinicProviderGen.INSTANCE;
      +        }
      +
      +        @Specialization
      +        static PTokenizerIter tokenizerIter(@SuppressWarnings("unused") Object cls, TruffleString source,
      +                        @Bind PythonLanguage language,
      +                        @Cached TruffleString.ToJavaStringNode toJavaStringNode) {
      +            return PFactory.createTokenizerIter(language, toJavaStringNode.execute(source));
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
      @@ -83,20 +111,20 @@ static PTokenizerIter iter(PTokenizerIter self) {
               }
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    abstract static class NextNode extends TpIterNextBuiltin {
               private static final TruffleString T_EOF = tsLiteral("EOF");
       
               @Specialization
               static PTuple next(PTokenizerIter self,
                               @Bind("this") Node inliningTarget,
                               @Cached TruffleString.FromJavaStringNode fromJavaStringNode,
      -                        @Cached PythonObjectFactory factory,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Bind PythonLanguage language,
      +                        @Cached PRaiseNode raiseNode) {
                   Token token = self.getNextToken();
                   if (token.type == Kind.ERRORTOKEN || token.type == Kind.ENDMARKER) {
      -                throw raiseNode.get(inliningTarget).raiseStopIteration(T_EOF);
      +                throw raiseNode.raiseStopIteration(inliningTarget, T_EOF);
                   }
                   int startColumn;
                   int endColumn;
      @@ -110,7 +138,7 @@ static PTuple next(PTokenizerIter self,
                   if (token.type == Kind.NEWLINE) {
                       endColumn--;
                   }
      -            return factory.createTuple(new Object[]{
      +            return PFactory.createTuple(language, new Object[]{
                                   fromJavaStringNode.execute(self.getTokenString(token), TS_ENCODING),
                                   token.type,
                                   token.sourceRange.startLine,
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/LazyTraceback.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/LazyTraceback.java
      index a63b7d14b6..8de472f4bb 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/LazyTraceback.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/LazyTraceback.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -154,8 +154,8 @@ public static boolean elementWantedForTraceback(TruffleStackTraceElement element
               if (frame != null) {
                   // only include frames of non-builtin python functions
                   Object info = frame.getFrameDescriptor().getInfo();
      -            if (info instanceof FrameInfo) {
      -                return ((FrameInfo) info).getRootNode().frameIsVisibleToPython();
      +            if (info instanceof FrameInfo frameInfo) {
      +                return frameInfo.includeInTraceback();
                   }
               }
               return false;
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/MaterializeLazyTracebackNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/MaterializeLazyTracebackNode.java
      index 0f90e1a881..a08af605d8 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/MaterializeLazyTracebackNode.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/MaterializeLazyTracebackNode.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,8 +40,9 @@
        */
       package com.oracle.graal.python.builtins.objects.traceback;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.Fallback;
       import com.oracle.truffle.api.dsl.GenerateCached;
      @@ -71,7 +72,7 @@
        * frames that the exception has passed through during the unwinding plus the frame where it was
        * caught. It doesn't include the frames above it (to the top). Secondly, the traceback is never
        * frozen. The traceback accumulates more frames when the exception gets reraised. To correct the
      - * mismatch between Truffle and Python eception handling, we need to wrap {@link PException}s in
      + * mismatch between Truffle and Python exception handling, we need to wrap {@link PException}s in
        * {@link LazyTraceback} objects when caught and adhere to particular rules of exception handling
        * mentioned below.
        * 

      @@ -134,7 +135,6 @@ static PTraceback getMaterialized(LazyTraceback tb) { @Fallback static PTraceback getTraceback(Node inliningTarget, LazyTraceback tb, - @Cached(inline = false) PythonObjectFactory factory, @Cached InlinedLoopConditionProfile loopConditionProfile) { PTraceback newTraceback = null; LazyTraceback current = tb; @@ -143,7 +143,7 @@ static PTraceback getTraceback(Node inliningTarget, LazyTraceback tb, if (current.isMaterialized()) { newTraceback = current.getTraceback(); } else { - newTraceback = factory.createTraceback(current); + newTraceback = PFactory.createTraceback(PythonLanguage.get(inliningTarget), current); } break; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/PTraceback.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/PTraceback.java index 3d04a261ab..21011830be 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/PTraceback.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/PTraceback.java @@ -46,7 +46,10 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.frame.PFrame; import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; +import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.bytecode.BytecodeNode; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; public final class PTraceback extends PythonBuiltinObject { @@ -56,6 +59,7 @@ public final class PTraceback extends PythonBuiltinObject { private PFrame.Reference frameInfo; private int lineno = UNKNOWN_LINE_NUMBER; private int bci = -1; + private BytecodeNode bytecodeNode = null; private int lasti = -1; private PTraceback next; private LazyTraceback lazyTraceback; @@ -107,13 +111,20 @@ public int getLineno() { public int getLasti(PFrame pFrame) { if (lasti == -1 && bci >= 0) { - lasti = pFrame.bciToLasti(bci); + Node location; + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + location = bytecodeNode; + } else { + location = pFrame.getLocation(); + } + lasti = PFrame.bciToLasti(bci, location); } return lasti; } - public void setBci(int bci) { + public void setLocation(int bci, BytecodeNode bytecodeNode) { this.bci = bci; + this.bytecodeNode = bytecodeNode; // nullable this.lasti = -1; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/TracebackBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/TracebackBuiltins.java index 228a0a26ed..6d1275e6e4 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/TracebackBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/TracebackBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2014, Regents of the University of California * * All rights reserved. @@ -35,6 +35,11 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; @@ -43,6 +48,8 @@ import com.oracle.graal.python.builtins.objects.frame.PFrame; import com.oracle.graal.python.builtins.objects.frame.PFrame.Reference; import com.oracle.graal.python.builtins.objects.function.PArguments; +import com.oracle.graal.python.builtins.objects.traceback.TracebackBuiltinsClinicProviders.TracebackTypeNodeClinicProviderGen; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.bytecode.PBytecodeGeneratorRootNode; @@ -52,8 +59,11 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.exception.PythonErrorType; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.TruffleStackTrace; import com.oracle.truffle.api.TruffleStackTraceElement; @@ -75,18 +85,65 @@ @CoreFunctions(extendClasses = PythonBuiltinClassType.PTraceback) public final class TracebackBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = TracebackBuiltinsSlotsGen.SLOTS; + @Override protected List> getNodeFactories() { return TracebackBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = "TracebackType", minNumOfPositionalArgs = 5, parameterNames = {"$cls", "tb_next", "tb_frame", + "tb_lasti", + "tb_lineno"}) + @ArgumentClinic(name = "tb_lasti", conversion = ArgumentClinic.ClinicConversion.Index) + @ArgumentClinic(name = "tb_lineno", conversion = ArgumentClinic.ClinicConversion.Index) + @GenerateNodeFactory + public abstract static class TracebackTypeNode extends PythonClinicBuiltinNode { + @Specialization + static Object createTraceback(@SuppressWarnings("unused") Object cls, PTraceback next, PFrame pframe, int lasti, int lineno, + @Bind PythonLanguage language) { + return PFactory.createTracebackWithLasti(language, pframe, lineno, lasti, next); + } + + @Specialization + static Object createTraceback(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") PNone next, PFrame pframe, int lasti, int lineno, + @Bind PythonLanguage language) { + return PFactory.createTracebackWithLasti(language, pframe, lineno, lasti, null); + } + + @Specialization(guards = {"!isPTraceback(next)", "!isNone(next)"}) + @SuppressWarnings("unused") + static Object errorNext(Object cls, Object next, Object frame, Object lasti, Object lineno, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.EXPECTED_TRACEBACK_OBJ_OR_NONE, next); + } + + @Specialization(guards = "!isPFrame(frame)") + @SuppressWarnings("unused") + static Object errorFrame(Object cls, Object next, Object frame, Object lasti, Object lineno, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.TRACEBACK_TYPE_ARG_MUST_BE_FRAME, frame); + } + + protected static boolean isPFrame(Object obj) { + return obj instanceof PFrame; + } + + @Override + protected ArgumentClinicProvider getArgumentClinic() { + return TracebackTypeNodeClinicProviderGen.INSTANCE; + } + } + @Builtin(name = J___DIR__, minNumOfPositionalArgs = 1) @GenerateNodeFactory public abstract static class DirNode extends PythonBuiltinNode { @Specialization static Object dir(@SuppressWarnings("unused") PTraceback self, - @Cached PythonObjectFactory factory) { - return factory.createList(PTraceback.getTbFieldNames()); + @Bind PythonLanguage language) { + return PFactory.createList(language, PTraceback.getTbFieldNames()); } } @@ -109,8 +166,7 @@ static void doExisting(@SuppressWarnings("unused") PTraceback tb) { @Specialization(guards = "!tb.isMaterialized()") static void doMaterialize(Node inliningTarget, PTraceback tb, @Cached(inline = false) MaterializeFrameNode materializeFrameNode, - @Cached MaterializeLazyTracebackNode materializeLazyTracebackNode, - @Cached(inline = false) PythonObjectFactory factory) { + @Cached MaterializeLazyTracebackNode materializeLazyTracebackNode) { /* * Truffle stacktrace consists of the frames captured during the unwinding and the * frames that are now on the Java stack. We don't want the frames from the stack to @@ -136,15 +192,15 @@ static void doMaterialize(Node inliningTarget, PTraceback tb, TruffleStackTraceElement element = stackTrace.get(truffleIndex); if (LazyTraceback.elementWantedForTraceback(element)) { PFrame pFrame = materializeFrame(element, materializeFrameNode); - next = factory.createTraceback(pFrame, pFrame.getLine(), next); - next.setBci(pFrame.getBci()); + next = PFactory.createTraceback(PythonLanguage.get(null), pFrame, pFrame.getLine(), next); + next.setLocation(pFrame.getBci(), pFrame.getBytecodeNode()); pyIndex++; } } } if (lazyTraceback.catchingFrameWantedForTraceback()) { - tb.setBci(pException.getCatchBci()); - tb.setLineno(pException.getCatchRootNode().bciToLine(pException.getCatchBci())); + tb.setLocation(pException.getCatchBci(), pException.getBytecodeNode()); + tb.setLineno(pException.getCatchLine()); tb.setNext(next); } else { assert next != null; @@ -272,12 +328,12 @@ static Object set(PTraceback self, PTraceback next, @Bind("this") Node inliningTarget, @Cached InlinedLoopConditionProfile loopProfile, @Exclusive @Cached MaterializeTruffleStacktraceNode materializeTruffleStacktraceNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { // Check for loops PTraceback tb = next; while (loopProfile.profile(inliningTarget, tb != null)) { if (tb == self) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.TRACEBACK_LOOP_DETECTED); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.TRACEBACK_LOOP_DETECTED); } tb = tb.getNext(); } @@ -301,8 +357,8 @@ static Object clear(PTraceback self, @SuppressWarnings("unused") PNone next, @Specialization(guards = {"!isPNone(next)", "!isPTraceback(next)"}) static Object setError(@SuppressWarnings("unused") PTraceback self, Object next, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.EXPECTED_TRACEBACK_OBJ, next); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.EXPECTED_TRACEBACK_OBJ, next); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/InstantiableStructSequenceBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/InstantiableStructSequenceBuiltins.java new file mode 100644 index 0000000000..215ab8bbd1 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/InstantiableStructSequenceBuiltins.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.builtins.objects.tuple; + +import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; + +import java.util.Collections; +import java.util.List; + +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.builtins.CoreFunctions; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; +import com.oracle.graal.python.builtins.objects.dict.PDict; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.lib.PyDictGetItem; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.builtins.ListNodes; +import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; +import com.oracle.graal.python.nodes.object.BuiltinClassProfiles; +import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; +import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateNodeFactory; +import com.oracle.truffle.api.dsl.NodeFactory; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; +import com.oracle.truffle.api.strings.TruffleString; + +@CoreFunctions(extendClasses = { + PythonBuiltinClassType.PStatResult, + PythonBuiltinClassType.PStatvfsResult, + PythonBuiltinClassType.PTerminalSize, + PythonBuiltinClassType.PUnameResult, + PythonBuiltinClassType.PStructTime, + PythonBuiltinClassType.PProfilerEntry, + PythonBuiltinClassType.PProfilerSubentry, + PythonBuiltinClassType.PStructPasswd, + PythonBuiltinClassType.PStructRusage, + PythonBuiltinClassType.PFloatInfo, + PythonBuiltinClassType.PIntInfo, + PythonBuiltinClassType.PHashInfo, + PythonBuiltinClassType.PThreadInfo, + PythonBuiltinClassType.PUnraisableHookArgs}) +public class InstantiableStructSequenceBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = InstantiableStructSequenceBuiltinsSlotsGen.SLOTS; + + @Override + protected List> getNodeFactories() { + return Collections.emptyList(); + } + + @Slot(value = Slot.SlotKind.tp_new, isComplex = true) + @Slot.SlotSignature(minNumOfPositionalArgs = 2, parameterNames = {"$cls", "sequence", "dict"}) + @GenerateNodeFactory + public abstract static class NewNode extends PythonTernaryBuiltinNode { + + @Specialization + static PTuple withDict(VirtualFrame frame, Object cls, Object sequence, Object dict, + @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, + @Cached StructSequenceBuiltins.GetSizeNode getSizeNode, + @Cached StructSequenceBuiltins.GetFieldNamesNode getFieldNamesNode, + @Cached ListNodes.FastConstructListNode fastConstructListNode, + @Cached SequenceStorageNodes.GetItemScalarNode getItem, + @Cached BuiltinClassProfiles.IsBuiltinObjectProfile notASequenceProfile, + @Cached InlinedBranchProfile wrongLenProfile, + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached PyDictGetItem dictGetItem, + @Cached InlinedConditionProfile hasDictProfile, + @Cached PRaiseNode raiseNode) { + SequenceStorage seq; + try { + seq = fastConstructListNode.execute(frame, inliningTarget, sequence).getSequenceStorage(); + } catch (PException e) { + e.expect(inliningTarget, TypeError, notASequenceProfile); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CONSTRUCTOR_REQUIRES_A_SEQUENCE); + } + + boolean hasDict = hasDictProfile.profile(inliningTarget, dict instanceof PDict); + if (!hasDict && dict != PNone.NO_VALUE) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TAKES_A_DICT_AS_SECOND_ARG_IF_ANY, StructSequence.getTpName(cls)); + } + + int len = seq.length(); + int minLen = getSizeNode.execute(frame, inliningTarget, cls, StructSequence.T_N_SEQUENCE_FIELDS); + int maxLen = getSizeNode.execute(frame, inliningTarget, cls, StructSequence.T_N_FIELDS); + int unnamedFields = getSizeNode.execute(frame, inliningTarget, cls, StructSequence.T_N_UNNAMED_FIELDS); + + if (len < minLen || len > maxLen) { + wrongLenProfile.enter(inliningTarget); + if (minLen == maxLen) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TAKES_A_D_SEQUENCE, StructSequence.getTpName(cls), minLen, len); + } + if (len < minLen) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TAKES_AN_AT_LEAST_D_SEQUENCE, StructSequence.getTpName(cls), minLen, len); + } else { // len > maxLen + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TAKES_AN_AT_MOST_D_SEQUENCE, StructSequence.getTpName(cls), maxLen, len); + } + } + + Object[] dst = new Object[maxLen]; + for (int i = 0; i < seq.length(); i++) { + dst[i] = getItem.execute(inliningTarget, seq, i); + } + TruffleString[] fieldNames = hasDict ? getFieldNamesNode.execute(inliningTarget, cls) : null; + for (int i = seq.length(); i < dst.length; ++i) { + if (hasDict) { + Object o = dictGetItem.execute(frame, inliningTarget, (PDict) dict, fieldNames[i - unnamedFields]); + dst[i] = o == null ? PNone.NONE : o; + } else { + dst[i] = PNone.NONE; + } + } + return PFactory.createTuple(language, cls, getInstanceShape.execute(cls), new ObjectSequenceStorage(dst, minLen)); + } + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/PTuple.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/PTuple.java index d91d651368..b80c95a225 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/PTuple.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/PTuple.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequence.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequence.java index 45fd01e7a8..71ae4abd50 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequence.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequence.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,95 +40,50 @@ */ package com.oracle.graal.python.builtins.objects.tuple; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.NotImplementedError; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEW__; -import static com.oracle.graal.python.nodes.StringLiterals.T_COMMA_SPACE; -import static com.oracle.graal.python.nodes.StringLiterals.T_EQ; -import static com.oracle.graal.python.nodes.StringLiterals.T_LPAREN; -import static com.oracle.graal.python.nodes.StringLiterals.T_RPAREN; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___REDUCE__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___REPR__; import static com.oracle.graal.python.util.PythonUtils.EMPTY_TRUFFLESTRING_ARRAY; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.toTruffleStringArrayUncached; -import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; import static com.oracle.graal.python.util.PythonUtils.tsArray; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; -import org.graalvm.nativeimage.ImageInfo; - import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; -import com.oracle.graal.python.builtins.objects.common.HashingStorage; -import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem; -import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem; +import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemNode; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ToArrayNode; -import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.function.Signature; import com.oracle.graal.python.builtins.objects.getsetdescriptor.GetSetDescriptor; -import com.oracle.graal.python.builtins.objects.object.ObjectNodes.GetFullyQualifiedClassNameNode; -import com.oracle.graal.python.builtins.objects.tuple.StructSequenceFactory.DisabledNewNodeGen; -import com.oracle.graal.python.builtins.objects.tuple.StructSequenceFactory.NewNodeGen; -import com.oracle.graal.python.builtins.objects.tuple.StructSequenceFactory.ReduceNodeGen; -import com.oracle.graal.python.builtins.objects.tuple.StructSequenceFactory.ReprNodeGen; +import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; +import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeFlags; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode; -import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotBuiltin; import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.PRootNode; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; -import com.oracle.graal.python.nodes.builtins.ListNodes.FastConstructListNode; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; -import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; -import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory; -import com.oracle.graal.python.runtime.sequence.PSequence; -import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; -import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; -import com.oracle.graal.python.util.Function; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.graal.python.util.PythonUtils.PrototypeNodeFactory; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.strings.TruffleString; -import com.oracle.truffle.api.strings.TruffleStringBuilder; /** * Allows definitions of tuple-like structs with named fields (like structseq.c in CPython). @@ -151,88 +106,33 @@ public class StructSequence { * type's name in the descriptor and this will improve code sharing. */ public static sealed class Descriptor permits BuiltinTypeDescriptor { - public final TruffleString docString; public final int inSequence; public final TruffleString[] fieldNames; public final TruffleString[] fieldDocStrings; - public final boolean allowInstances; - public Descriptor(TruffleString docString, int inSequence, TruffleString[] fieldNames, TruffleString[] fieldDocStrings, boolean allowInstances) { + public Descriptor(int inSequence, TruffleString[] fieldNames, TruffleString[] fieldDocStrings) { assert fieldDocStrings == null || fieldNames.length == fieldDocStrings.length; - this.docString = docString; this.inSequence = inSequence; this.fieldNames = fieldNames; this.fieldDocStrings = fieldDocStrings; - this.allowInstances = allowInstances; - } - - public Descriptor(TruffleString docString, int inSequence, TruffleString[] fieldNames, TruffleString[] fieldDocStrings) { - this(docString, inSequence, fieldNames, fieldDocStrings, true); - } - - // This shifts the names in a confusing way, but that is what CPython does: - // >>> s = os.stat('.') - // >>> s.st_atime - // 1607033732.3041613 - // >>> s - // os.stat_result(..., st_atime=1607033732, ...) - // - // note that st_atime accessed by name returns float (index 10), but in repr the same label - // is assigned to the int value at index 7 - TruffleString[] getFieldsForRepr() { - TruffleString[] fieldNamesForRepr = new TruffleString[inSequence]; - int k = 0; - for (int idx = 0; idx < fieldNames.length && k < inSequence; ++idx) { - if (fieldNames[idx] != null) { - fieldNamesForRepr[k++] = fieldNames[idx]; - } - } - // each field < inSequence must have a name - assert k == inSequence; - return fieldNamesForRepr; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof Descriptor)) { - return false; - } - Descriptor that = (Descriptor) o; - return inSequence == that.inSequence && allowInstances == that.allowInstances && Objects.equals(docString, that.docString) && Arrays.equals(fieldNames, that.fieldNames) && - Arrays.equals(fieldDocStrings, that.fieldDocStrings); - } - - @Override - public int hashCode() { - int result = Objects.hash(docString, inSequence, allowInstances); - result = 31 * result + Arrays.hashCode(fieldNames); - result = 31 * result + Arrays.hashCode(fieldDocStrings); - return result; } } /** * Very similar to {@code PyStructSequence_Desc} but already specific to a built-in type. Used - * for built-in structseq objects. + * for built-in structseq objects. All BuiltinTypeDescriptor instances should be kept in + * {@code static final} fields to ensure there is a finite number of them. */ public static final class BuiltinTypeDescriptor extends Descriptor { public final PythonBuiltinClassType type; - private final boolean initializedInBuildTime = ImageInfo.inImageBuildtimeCode(); - public BuiltinTypeDescriptor(PythonBuiltinClassType type, String docString, int inSequence, String[] fieldNames, String[] fieldDocStrings, boolean allowInstances) { - super(docString == null ? null : toTruffleStringUncached(docString), inSequence, toTruffleStringArrayUncached(fieldNames), toTruffleStringArrayUncached(fieldDocStrings), allowInstances); + public BuiltinTypeDescriptor(PythonBuiltinClassType type, int inSequence, String[] fieldNames, String[] fieldDocStrings) { + super(inSequence, toTruffleStringArrayUncached(fieldNames), toTruffleStringArrayUncached(fieldDocStrings)); assert type.getBase() == PythonBuiltinClassType.PTuple; assert !type.isAcceptableBase(); this.type = type; } - public BuiltinTypeDescriptor(PythonBuiltinClassType type, String docString, int inSequence, String[] fieldNames, String[] fieldDocStrings) { - this(type, docString, inSequence, fieldNames, fieldDocStrings, true); - } - @Override public boolean equals(Object o) { if (this == o) { @@ -251,28 +151,17 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(super.hashCode(), type); } - - public boolean wasInitializedAtBuildTime() { - return initializedInBuildTime; - } - } - - public record DescriptorCallTargets(RootCallTarget reprBuiltin, RootCallTarget reduceBuiltin, RootCallTarget newBuiltin) { } @TruffleBoundary public static void initType(Python3Core core, BuiltinTypeDescriptor desc) { - initType(core.factory(), core.getLanguage(), core.lookupType(desc.type), desc); - } - - @TruffleBoundary - public static void initType(PythonLanguage language, Object klass, Descriptor desc) { - initType(PythonContext.get(null).factory(), language, klass, desc); + initType(core.getContext(), core.lookupType(desc.type), desc); } @TruffleBoundary - public static void initType(PythonObjectSlowPathFactory factory, PythonLanguage language, Object klass, Descriptor desc) { + public static void initType(PythonContext context, PythonAbstractClass klass, Descriptor desc) { assert IsSubtypeNode.getUncached().execute(klass, PythonBuiltinClassType.PTuple); + PythonLanguage language = context.getLanguage(); long flags = TypeNodes.GetTypeFlagsNode.executeUncached(klass); if ((flags & TypeFlags.IMMUTABLETYPE) != 0) { @@ -282,268 +171,70 @@ public static void initType(PythonObjectSlowPathFactory factory, PythonLanguage // create descriptors for accessing named fields by their names int unnamedFields = 0; + List namedFields = new ArrayList<>(desc.fieldNames.length); for (int idx = 0; idx < desc.fieldNames.length; ++idx) { - if (desc.fieldNames[idx] != null) { + TruffleString fieldName = desc.fieldNames[idx]; + if (fieldName != null) { TruffleString doc = desc.fieldDocStrings == null ? null : desc.fieldDocStrings[idx]; - createMember(factory, language, klass, desc.fieldNames[idx], doc, idx); + createMember(language, klass, fieldName, doc, idx); + namedFields.add(fieldName); } else { unnamedFields++; } } - - DescriptorCallTargets callTargets = language.getOrCreateStructSequenceCallTargets(desc, d -> new DescriptorCallTargets( - createBuiltinCallTarget(language, desc, ReprNode.class, ReprNodeGen::create, true), - createBuiltinCallTarget(language, desc, ReduceNode.class, ReduceNodeGen::create, true), - desc.allowInstances ? // - createBuiltinCallTarget(language, desc, NewNode.class, NewNodeGen::create, false) : // - createBuiltinCallTarget(language, desc, DisabledNewNode.class, ignore -> DisabledNewNodeGen.create(), false))); - - createMethod(factory, klass, ReprNode.class, callTargets.reprBuiltin); - createMethod(factory, klass, ReduceNode.class, callTargets.reduceBuiltin); - WriteAttributeToObjectNode writeAttrNode = WriteAttributeToObjectNode.getUncached(true); - /* - * Only set __doc__ if given. It may be 'null' e.g. in case of initializing a native class - * where 'tp_doc' is set in native code already. - */ - if (desc.docString != null) { - writeAttrNode.execute(klass, T___DOC__, desc.docString); + if (klass instanceof PythonManagedClass managedClass) { + /* + * The methods and slots are already set for each PBCT, but we need to store the field + * names. + */ + HiddenAttr.WriteNode.executeUncached(managedClass, HiddenAttr.STRUCTSEQ_FIELD_NAMES, namedFields.toArray(new TruffleString[0])); + } else if (klass instanceof PythonAbstractNativeObject nativeClass) { + /* + * We need to add the methods. Note that PyType_Ready already ran, so we just write the + * method wrappers. Field names are already populated in tp_members on the native side. + */ + TpSlotBuiltin newSlot = null; + if ((flags & TypeFlags.DISALLOW_INSTANTIATION) == 0) { + newSlot = (TpSlotBuiltin) InstantiableStructSequenceBuiltins.SLOTS.tp_new(); + writeAttrNode.execute(klass, T___NEW__, newSlot.createBuiltin(context, klass, T___NEW__, TpSlots.TpSlotMeta.TP_NEW.getNativeSignature())); + } + /* + * The tp_new slot doesn't get updated by writing the python wrapper. See the comments + * about tp_new in TpSlots.updateSlots. We have to write it manually + */ + nativeClass.setTpSlots(nativeClass.getTpSlots().copy().set(TpSlots.TpSlotMeta.TP_NEW, newSlot).build()); + TpSlots.toNative(nativeClass.getPtr(), TpSlots.TpSlotMeta.TP_NEW, newSlot, context.getNativeNull()); + TpSlotBuiltin reprSlot = (TpSlotBuiltin) StructSequenceBuiltins.SLOTS.tp_repr(); + writeAttrNode.execute(klass, T___REPR__, reprSlot.createBuiltin(context, klass, T___REPR__, TpSlots.TpSlotMeta.TP_REPR.getNativeSignature())); + PythonBuiltinClass template = context.lookupType(PythonBuiltinClassType.PFloatInfo); + copyMethod(language, klass, T___REDUCE__, template); } writeAttrNode.execute(klass, T_N_SEQUENCE_FIELDS, desc.inSequence); writeAttrNode.execute(klass, T_N_FIELDS, desc.fieldNames.length); writeAttrNode.execute(klass, T_N_UNNAMED_FIELDS, unnamedFields); - if (ReadAttributeFromObjectNode.getUncachedForceType().execute(klass, T___NEW__) == PNone.NO_VALUE) { - Builtin builtin = NewNode.class.getAnnotation(Builtin.class); - PythonUtils.createConstructor(factory, klass, builtin, callTargets.newBuiltin); - } - if ((flags & TypeFlags.IMMUTABLETYPE) != 0) { - // Restore flags - TypeNodes.SetTypeFlagsNode.executeUncached(klass, flags); - } + TypeNodes.SetTypeFlagsNode.executeUncached(klass, flags); } - private static RootCallTarget createBuiltinCallTarget(PythonLanguage l, Descriptor descriptor, Class nodeClass, Function nodeFactory, - boolean declaresExplicitSelf) { - Builtin builtin = nodeClass.getAnnotation(Builtin.class); - return new BuiltinFunctionRootNode(l, builtin, new PrototypeNodeFactory(nodeFactory.apply(descriptor)), declaresExplicitSelf).getCallTarget(); + private static void copyMethod(PythonLanguage language, PythonAbstractClass klass, TruffleString name, PythonBuiltinClass template) { + PBuiltinFunction templateMethod = (PBuiltinFunction) template.getAttribute(name); + PBuiltinFunction method = PFactory.createBuiltinFunction(language, templateMethod, klass); + WriteAttributeToObjectNode.getUncached(true).execute(klass, name, method); } - private static void createMember(PythonObjectSlowPathFactory factory, PythonLanguage language, Object klass, TruffleString name, TruffleString doc, int idx) { + private static void createMember(PythonLanguage language, Object klass, TruffleString name, TruffleString doc, int idx) { RootCallTarget callTarget = language.createStructSeqIndexedMemberAccessCachedCallTarget((l) -> new GetStructMemberNode(l, idx), idx); - PBuiltinFunction getter = factory.createBuiltinFunction(name, klass, 0, 0, callTarget); - GetSetDescriptor callable = factory.createGetSetDescriptor(getter, null, name, klass, false); + PBuiltinFunction getter = PFactory.createBuiltinFunction(language, name, klass, 0, 0, callTarget); + GetSetDescriptor callable = PFactory.createGetSetDescriptor(language, getter, null, name, klass, false); if (doc != null) { callable.setAttribute(T___DOC__, doc); } WriteAttributeToObjectNode.getUncached(true).execute(klass, name, callable); } - private static void createMethod(PythonObjectSlowPathFactory factory, Object klass, Class nodeClass, RootCallTarget callTarget) { - Builtin builtin = nodeClass.getAnnotation(Builtin.class); - PythonUtils.createMethod(factory, klass, builtin, callTarget, PythonBuiltinClassType.PTuple, 0); - } - - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true) - public abstract static class DisabledNewNode extends PythonVarargsBuiltinNode { - - @Override - @SuppressWarnings("unused") - public final Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported { - if (arguments.length > 0) { - return error(arguments[0], PythonUtils.EMPTY_OBJECT_ARRAY, PKeyword.EMPTY_KEYWORDS); - } - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw VarargsBuiltinDirectInvocationNotSupported.INSTANCE; - } - - @Specialization - @SuppressWarnings("unused") - Object error(Object cls, Object[] arguments, PKeyword[] keywords) { - throw raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, StructSequence.getTpName(cls)); - } - } - - @Builtin(name = J___NEW__, minNumOfPositionalArgs = 2, parameterNames = {"$cls", "sequence", "dict"}) - public abstract static class NewNode extends PythonTernaryBuiltinNode { - - @CompilationFinal(dimensions = 1) private final TruffleString[] fieldNames; - private final int inSequence; - - NewNode(Descriptor desc) { - this.fieldNames = desc.fieldNames; - this.inSequence = desc.inSequence; - } - - @NeverDefault - public static NewNode create(Descriptor desc) { - return NewNodeGen.create(desc); - } - - @Specialization(guards = "isNoValue(dict)") - @SuppressWarnings("truffle-static-method") - PTuple withoutDict(VirtualFrame frame, Object cls, Object sequence, @SuppressWarnings("unused") PNone dict, - @Bind("this") Node inliningTarget, - @Exclusive @Cached FastConstructListNode fastConstructListNode, - @Exclusive @Cached ToArrayNode toArrayNode, - @Exclusive @Cached IsBuiltinObjectProfile notASequenceProfile, - @Exclusive @Cached InlinedBranchProfile wrongLenProfile, - @Exclusive @Cached InlinedBranchProfile needsReallocProfile, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - Object[] src = sequenceToArray(frame, inliningTarget, sequence, fastConstructListNode, toArrayNode, notASequenceProfile, raiseNode); - Object[] dst = processSequence(inliningTarget, cls, src, wrongLenProfile, needsReallocProfile, raiseNode); - for (int i = src.length; i < dst.length; ++i) { - dst[i] = PNone.NONE; - } - return factory.createTuple(cls, new ObjectSequenceStorage(dst, inSequence)); - } - - @Specialization - @SuppressWarnings("truffle-static-method") - PTuple withDict(VirtualFrame frame, Object cls, Object sequence, PDict dict, - @Bind("this") Node inliningTarget, - @Exclusive @Cached FastConstructListNode fastConstructListNode, - @Exclusive @Cached ToArrayNode toArrayNode, - @Exclusive @Cached IsBuiltinObjectProfile notASequenceProfile, - @Exclusive @Cached InlinedBranchProfile wrongLenProfile, - @Exclusive @Cached InlinedBranchProfile needsReallocProfile, - @Cached HashingStorageGetItem getItem, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - Object[] src = sequenceToArray(frame, inliningTarget, sequence, fastConstructListNode, toArrayNode, notASequenceProfile, raiseNode); - Object[] dst = processSequence(inliningTarget, cls, src, wrongLenProfile, needsReallocProfile, raiseNode); - HashingStorage hs = dict.getDictStorage(); - for (int i = src.length; i < dst.length; ++i) { - Object o = getItem.execute(inliningTarget, hs, fieldNames[i]); - dst[i] = o == null ? PNone.NONE : o; - } - return factory.createTuple(cls, new ObjectSequenceStorage(dst, inSequence)); - } - - @Specialization(guards = {"!isNoValue(dict)", "!isDict(dict)"}) - @SuppressWarnings("unused") - static PTuple doDictError(VirtualFrame frame, Object cls, Object sequence, Object dict, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.TAKES_A_DICT_AS_SECOND_ARG_IF_ANY, StructSequence.getTpName(cls)); - } - - private static Object[] sequenceToArray(VirtualFrame frame, Node inliningTarget, Object sequence, FastConstructListNode fastConstructListNode, - ToArrayNode toArrayNode, IsBuiltinObjectProfile notASequenceProfile, PRaiseNode.Lazy raiseNode) { - PSequence seq; - try { - seq = fastConstructListNode.execute(frame, inliningTarget, sequence); - } catch (PException e) { - e.expect(inliningTarget, TypeError, notASequenceProfile); - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CONSTRUCTOR_REQUIRES_A_SEQUENCE); - } - return toArrayNode.execute(inliningTarget, seq.getSequenceStorage()); - } - - private Object[] processSequence(Node inliningTarget, Object cls, Object[] src, InlinedBranchProfile wrongLenProfile, InlinedBranchProfile needsReallocProfile, PRaiseNode.Lazy raiseNode) { - int len = src.length; - int minLen = inSequence; - int maxLen = fieldNames.length; - - if (len < minLen || len > maxLen) { - wrongLenProfile.enter(inliningTarget); - if (minLen == maxLen) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.TAKES_A_D_SEQUENCE, StructSequence.getTpName(cls), minLen, len); - } - if (len < minLen) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.TAKES_AN_AT_LEAST_D_SEQUENCE, StructSequence.getTpName(cls), minLen, len); - } else { // len > maxLen - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.TAKES_AN_AT_MOST_D_SEQUENCE, StructSequence.getTpName(cls), maxLen, len); - } - } - - if (len != maxLen) { - needsReallocProfile.enter(inliningTarget); - Object[] dst = new Object[maxLen]; - PythonUtils.arraycopy(src, 0, dst, 0, len); - return dst; - } - return src; - } - } - - @Builtin(name = J___REDUCE__, minNumOfPositionalArgs = 1) - abstract static class ReduceNode extends PythonUnaryBuiltinNode { - - @CompilationFinal(dimensions = 1) private final TruffleString[] fieldNames; - private final int inSequence; - - ReduceNode(Descriptor desc) { - this.fieldNames = desc.fieldNames; - this.inSequence = desc.inSequence; - } - - @Specialization - PTuple reduce(PTuple self, - @Bind("this") Node inliningTarget, - @Cached HashingStorageSetItem setHashingStorageItem, - @Cached GetClassNode getClass, - @Cached PythonObjectFactory factory) { - assert self.getSequenceStorage() instanceof ObjectSequenceStorage; - Object[] data = CompilerDirectives.castExact(self.getSequenceStorage(), ObjectSequenceStorage.class).getInternalObjectArray(); - assert data.length == fieldNames.length; - PTuple seq; - PDict dict; - if (fieldNames.length == inSequence) { - seq = factory.createTuple(data); - dict = factory.createDict(); - } else { - HashingStorage storage = EconomicMapStorage.create(fieldNames.length - inSequence); - for (int i = inSequence; i < fieldNames.length; ++i) { - storage = setHashingStorageItem.execute(inliningTarget, storage, fieldNames[i], data[i]); - } - seq = factory.createTuple(Arrays.copyOf(data, inSequence)); - dict = factory.createDict(storage); - } - PTuple seqDictPair = factory.createTuple(new Object[]{seq, dict}); - return factory.createTuple(new Object[]{getClass.execute(inliningTarget, self), seqDictPair}); - } - } - - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) - abstract static class ReprNode extends PythonUnaryBuiltinNode { - - @CompilationFinal(dimensions = 1) private final TruffleString[] fieldNames; - - ReprNode(Descriptor desc) { - this.fieldNames = desc.getFieldsForRepr(); - } - - @Specialization - public TruffleString repr(VirtualFrame frame, PTuple self, - @Bind("this") Node inliningTarget, - @Cached GetFullyQualifiedClassNameNode getFullyQualifiedClassNameNode, - @Cached("createNotNormalized()") GetItemNode getItemNode, - @Cached PyObjectReprAsTruffleStringNode reprNode, - @Cached TruffleStringBuilder.AppendStringNode appendStringNode, - @Cached TruffleStringBuilder.ToStringNode toStringNode) { - TruffleStringBuilder sb = TruffleStringBuilder.create(TS_ENCODING); - appendStringNode.execute(sb, getFullyQualifiedClassNameNode.execute(frame, inliningTarget, self)); - appendStringNode.execute(sb, T_LPAREN); - SequenceStorage tupleStore = self.getSequenceStorage(); - if (fieldNames.length > 0) { - appendStringNode.execute(sb, fieldNames[0]); - appendStringNode.execute(sb, T_EQ); - appendStringNode.execute(sb, reprNode.execute(frame, inliningTarget, getItemNode.execute(tupleStore, 0))); - for (int i = 1; i < fieldNames.length; i++) { - appendStringNode.execute(sb, T_COMMA_SPACE); - appendStringNode.execute(sb, fieldNames[i]); - appendStringNode.execute(sb, T_EQ); - appendStringNode.execute(sb, reprNode.execute(frame, inliningTarget, getItemNode.execute(tupleStore, i))); - } - } - appendStringNode.execute(sb, T_RPAREN); - return toStringNode.execute(sb); - } - } - private static class GetStructMemberNode extends PRootNode { - public static final Signature SIGNATURE = new Signature(-1, false, -1, false, tsArray("$self"), EMPTY_TRUFFLESTRING_ARRAY); + public static final Signature SIGNATURE = new Signature(-1, false, -1, tsArray("$self"), EMPTY_TRUFFLESTRING_ARRAY); private final int fieldIdx; GetStructMemberNode(PythonLanguage language, int fieldIdx) { @@ -554,6 +245,9 @@ private static class GetStructMemberNode extends PRootNode { @Override public Object execute(VirtualFrame frame) { PTuple self = (PTuple) PArguments.getArgument(frame, 0); + if (self.getSequenceStorage() instanceof NativeSequenceStorage && fieldIdx >= self.getSequenceStorage().length()) { + throw PRaiseNode.raiseStatic(this, NotImplementedError, ErrorMessages.UNSUPPORTED_ACCESS_OF_STRUCT_SEQUENCE_NATIVE_STORAGE); + } return SequenceStorageNodes.GetItemScalarNode.executeUncached(self.getSequenceStorage(), fieldIdx); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequenceBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequenceBuiltins.java new file mode 100644 index 0000000000..7786b2fe94 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequenceBuiltins.java @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.builtins.objects.tuple; + +import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__; +import static com.oracle.graal.python.nodes.StringLiterals.T_COMMA_SPACE; +import static com.oracle.graal.python.nodes.StringLiterals.T_EQ; +import static com.oracle.graal.python.nodes.StringLiterals.T_LPAREN; +import static com.oracle.graal.python.nodes.StringLiterals.T_RPAREN; +import static com.oracle.graal.python.runtime.exception.PythonErrorType.NotImplementedError; +import static com.oracle.graal.python.util.PythonUtils.EMPTY_TRUFFLESTRING_ARRAY; +import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; + +import java.util.ArrayList; +import java.util.List; + +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.builtins.Builtin; +import com.oracle.graal.python.builtins.CoreFunctions; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; +import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; +import com.oracle.graal.python.builtins.objects.cext.structs.CFields; +import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; +import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; +import com.oracle.graal.python.builtins.objects.dict.PDict; +import com.oracle.graal.python.builtins.objects.object.ObjectNodes; +import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.lib.PyDictSetItem; +import com.oracle.graal.python.lib.PyNumberAsSizeNode; +import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.HiddenAttr; +import com.oracle.graal.python.nodes.PGuards; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage; +import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Cached.Shared; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateNodeFactory; +import com.oracle.truffle.api.dsl.NodeFactory; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.InteropLibrary; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.strings.TruffleString; +import com.oracle.truffle.api.strings.TruffleStringBuilder; + +@CoreFunctions(extendClasses = { + PythonBuiltinClassType.PStatResult, + PythonBuiltinClassType.PStatvfsResult, + PythonBuiltinClassType.PTerminalSize, + PythonBuiltinClassType.PUnameResult, + PythonBuiltinClassType.PStructTime, + PythonBuiltinClassType.PProfilerEntry, + PythonBuiltinClassType.PProfilerSubentry, + PythonBuiltinClassType.PStructPasswd, + PythonBuiltinClassType.PStructRusage, + PythonBuiltinClassType.PVersionInfo, + PythonBuiltinClassType.PWindowsVersion, + PythonBuiltinClassType.PFlags, + PythonBuiltinClassType.PFloatInfo, + PythonBuiltinClassType.PIntInfo, + PythonBuiltinClassType.PHashInfo, + PythonBuiltinClassType.PThreadInfo, + PythonBuiltinClassType.PUnraisableHookArgs}) +public final class StructSequenceBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = StructSequenceBuiltinsSlotsGen.SLOTS; + + @Override + protected List> getNodeFactories() { + return StructSequenceBuiltinsFactory.getFactories(); + } + + @GenerateInline + @GenerateCached(false) + abstract static class GetSizeNode extends Node { + public abstract int execute(VirtualFrame frame, Node inliningTarget, Object type, TruffleString key); + + @Specialization + static int doPBCT(VirtualFrame frame, Node inliningTarget, PythonBuiltinClassType type, TruffleString key, + @Shared @Cached("createForceType()") ReadAttributeFromObjectNode read, + @Shared @Cached PyNumberAsSizeNode asSizeNode) { + return doGeneric(frame, inliningTarget, PythonContext.get(inliningTarget).lookupType(type), key, read, asSizeNode); + } + + @Fallback + static int doGeneric(VirtualFrame frame, Node inliningTarget, Object type, TruffleString key, + @Shared @Cached("createForceType()") ReadAttributeFromObjectNode read, + @Shared @Cached PyNumberAsSizeNode asSizeNode) { + return asSizeNode.executeExact(frame, inliningTarget, read.execute(type, key)); + } + } + + @GenerateInline + @GenerateCached(false) + abstract static class GetFieldNamesNode extends Node { + public abstract TruffleString[] execute(Node inliningTarget, Object type); + + @Specialization + static TruffleString[] doPBCT(Node inliningTarget, PythonBuiltinClassType type, + @Shared @Cached HiddenAttr.ReadNode readNode) { + return doManaged(inliningTarget, PythonContext.get(inliningTarget).lookupType(type), readNode); + } + + @Specialization + static TruffleString[] doManaged(Node inliningTarget, PythonManagedClass type, + @Shared @Cached HiddenAttr.ReadNode readNode) { + return (TruffleString[]) readNode.execute(inliningTarget, type, HiddenAttr.STRUCTSEQ_FIELD_NAMES, EMPTY_TRUFFLESTRING_ARRAY); + } + + @Specialization + @TruffleBoundary + static TruffleString[] doNative(PythonAbstractNativeObject type) { + CStructAccess.ReadPointerNode read = CStructAccess.ReadPointerNode.getUncached(); + Object membersPtr = read.readFromObj(type, CFields.PyTypeObject__tp_members); + List members = new ArrayList<>(); + InteropLibrary lib = InteropLibrary.getUncached(); + if (!PGuards.isNullOrZero(membersPtr, lib)) { + for (int i = 0;; i++) { + Object memberNamePtr = read.readStructArrayElement(membersPtr, i, CFields.PyMemberDef__name); + if (PGuards.isNullOrZero(memberNamePtr, lib)) { + break; + } + TruffleString name = CExtNodes.FromCharPointerNode.executeUncached(memberNamePtr); + members.add(name); + } + } + return members.toArray(new TruffleString[0]); + } + } + + @Slot(value = SlotKind.tp_repr, isComplex = true) + @GenerateNodeFactory + abstract static class ReprNode extends PythonUnaryBuiltinNode { + + @Specialization + static TruffleString repr(VirtualFrame frame, PTuple self, + @Bind("this") Node inliningTarget, + @Cached GetClassNode getClassNode, + @Cached GetFieldNamesNode getFieldNamesNode, + @Cached ObjectNodes.GetFullyQualifiedNameNode getQName, + @Cached SequenceStorageNodes.GetItemScalarNode getItemNode, + @Cached PyObjectReprAsTruffleStringNode reprNode, + @Cached TruffleStringBuilder.AppendStringNode appendStringNode, + @Cached TruffleStringBuilder.ToStringNode toStringNode) { + Object type = getClassNode.execute(inliningTarget, self); + TruffleStringBuilder sb = TruffleStringBuilder.create(TS_ENCODING); + appendStringNode.execute(sb, getQName.execute(frame, type)); + appendStringNode.execute(sb, T_LPAREN); + SequenceStorage tupleStore = self.getSequenceStorage(); + int visibleSize = tupleStore.length(); + TruffleString[] fieldNames = getFieldNamesNode.execute(inliningTarget, type); + if (visibleSize > 0) { + appendStringNode.execute(sb, fieldNames[0]); + appendStringNode.execute(sb, T_EQ); + appendStringNode.execute(sb, reprNode.execute(frame, inliningTarget, getItemNode.execute(inliningTarget, tupleStore, 0))); + for (int i = 1; i < visibleSize; i++) { + appendStringNode.execute(sb, T_COMMA_SPACE); + appendStringNode.execute(sb, fieldNames[i]); + appendStringNode.execute(sb, T_EQ); + appendStringNode.execute(sb, reprNode.execute(frame, inliningTarget, getItemNode.execute(inliningTarget, tupleStore, i))); + } + } + appendStringNode.execute(sb, T_RPAREN); + return toStringNode.execute(sb); + } + } + + @Builtin(name = J___REDUCE__, minNumOfPositionalArgs = 1) + @GenerateNodeFactory + abstract static class ReduceNode extends PythonUnaryBuiltinNode { + + @Specialization + static PTuple reduce(VirtualFrame frame, PTuple self, + @Bind("this") Node inliningTarget, + @Cached GetClassNode getClass, + @Cached GetSizeNode getSizeNode, + @Cached GetFieldNamesNode getFieldNamesNode, + @Cached SequenceStorageNodes.GetItemScalarNode getSeqItem, + @Cached SequenceStorageNodes.GetItemSliceNode getSeqSlice, + @Cached PyDictSetItem dictSetItem, + @Cached PRaiseNode raiseNode, + @Bind PythonLanguage language) { + SequenceStorage storage = self.getSequenceStorage(); + Object type = getClass.execute(inliningTarget, self); + int nFields = getSizeNode.execute(frame, inliningTarget, type, StructSequence.T_N_FIELDS); + int nVisibleFields = storage.length(); + int nUnnamedFields = getSizeNode.execute(frame, inliningTarget, type, StructSequence.T_N_UNNAMED_FIELDS); + PTuple tuple = PFactory.createTuple(language, getSeqSlice.execute(storage, 0, nVisibleFields, 1, nVisibleFields)); + PDict dict = PFactory.createDict(language); + if (nFields > nVisibleFields) { + if (storage instanceof NativeSequenceStorage) { + // TODO Native storage conversion wouldn't preserve the items past length + throw raiseNode.raise(inliningTarget, NotImplementedError, ErrorMessages.UNSUPPORTED_ACCESS_OF_STRUCT_SEQUENCE_NATIVE_STORAGE); + } + assert storage.getCapacity() >= nFields; + TruffleString[] fieldNames = getFieldNamesNode.execute(inliningTarget, type); + for (int i = nVisibleFields; i < nFields; i++) { + TruffleString n = fieldNames[i - nUnnamedFields]; + // We're reading past length, GetItemScalarNode doesn't do a bounds check + dictSetItem.execute(inliningTarget, dict, n, getSeqItem.execute(inliningTarget, storage, i)); + } + } + return PFactory.createTuple(language, new Object[]{type, PFactory.createTuple(language, new Object[]{tuple, dict})}); + } + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/TupleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/TupleBuiltins.java index 4c696b9e18..633dcc0b72 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/TupleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/TupleBuiltins.java @@ -25,19 +25,9 @@ */ package com.oracle.graal.python.builtins.objects.tuple; +import static com.oracle.graal.python.nodes.BuiltinNames.J_TUPLE; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CONTAINS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__; import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETNEWARGS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___TRUFFLE_RICHCOMPARE__; import static com.oracle.graal.python.nodes.StringLiterals.T_COMMA; import static com.oracle.graal.python.nodes.StringLiterals.T_COMMA_SPACE; import static com.oracle.graal.python.nodes.StringLiterals.T_ELLIPSIS_IN_PARENS; @@ -50,19 +40,19 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; +import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.CmpNode; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ConcatNode; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ListGeneralizationNode; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.SequenceStorageMpSubscriptNode; import com.oracle.graal.python.builtins.objects.iterator.PDoubleSequenceIterator; import com.oracle.graal.python.builtins.objects.iterator.PIntegerSequenceIterator; @@ -71,13 +61,16 @@ import com.oracle.graal.python.builtins.objects.iterator.PSequenceIterator; import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltinsClinicProviders.IndexNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.SqConcatBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqItemBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqRepeatBuiltinNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode; import com.oracle.graal.python.lib.PyIndexCheckNode; -import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectHashNode; import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode; import com.oracle.graal.python.lib.PyObjectRichCompareBool; @@ -85,37 +78,33 @@ import com.oracle.graal.python.lib.PyTupleCheckNode; import com.oracle.graal.python.lib.PyTupleGetItem; import com.oracle.graal.python.lib.PyTupleSizeNode; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.builtins.TupleNodes; import com.oracle.graal.python.nodes.builtins.TupleNodes.GetNativeTupleStorage; import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage; +import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryClinicBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.DoubleSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.IntSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.LongSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; -import com.oracle.graal.python.util.ComparisonOp; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; @@ -134,6 +123,60 @@ protected List> getNodeFa return TupleBuiltinsFactory.getFactories(); } + // tuple([iterable]) + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = J_TUPLE, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2) + @GenerateNodeFactory + public abstract static class TupleNode extends PythonBinaryBuiltinNode { + + @Specialization(guards = "isBuiltinTupleType(cls)") + static Object doBuiltin(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object iterable, + @Shared @Cached TupleNodes.ConstructTupleNode constructTupleNode) { + return constructTupleNode.execute(frame, iterable); + } + + @Specialization(guards = "!needsNativeAllocationNode.execute(inliningTarget, cls)", replaces = "doBuiltin") + static PTuple constructTuple(VirtualFrame frame, Object cls, Object iterable, + @SuppressWarnings("unused") @Bind("this") Node inliningTarget, + @SuppressWarnings("unused") @Shared @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, + @Shared @Cached TupleNodes.ConstructTupleNode constructTupleNode, + @Cached TypeNodes.IsSameTypeNode isSameTypeNode, + @Bind PythonLanguage language, + @Cached TypeNodes.GetInstanceShape getInstanceShape) { + PTuple tuple = constructTupleNode.execute(frame, iterable); + if (isSameTypeNode.execute(inliningTarget, cls, PythonBuiltinClassType.PTuple)) { + return tuple; + } else { + return PFactory.createTuple(language, cls, getInstanceShape.execute(cls), tuple.getSequenceStorage()); + } + } + + // delegate to tuple_subtype_new(PyTypeObject *type, PyObject *x) + @Specialization(guards = {"needsNativeAllocationNode.execute(inliningTarget, cls)", "isSubtypeOfTuple( isSubtype, cls)"}, limit = "1") + @InliningCutoff + static Object doNative(@SuppressWarnings("unused") VirtualFrame frame, Object cls, Object iterable, + @SuppressWarnings("unused") @Bind("this") Node inliningTarget, + @SuppressWarnings("unused") @Shared @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, + @Cached @SuppressWarnings("unused") IsSubtypeNode isSubtype, + @Cached CExtNodes.TupleSubtypeNew subtypeNew) { + return subtypeNew.call(cls, iterable); + } + + protected static boolean isBuiltinTupleType(Object cls) { + return cls == PythonBuiltinClassType.PTuple; + } + + protected static boolean isSubtypeOfTuple(IsSubtypeNode isSubtypeNode, Object cls) { + return isSubtypeNode.execute(cls, PythonBuiltinClassType.PTuple); + } + + @Fallback + static PTuple tupleObject(Object cls, @SuppressWarnings("unused") Object arg, + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.IS_NOT_TYPE_OBJ, "'cls'", cls); + } + } + // index(element) @Builtin(name = "index", minNumOfPositionalArgs = 2, parameterNames = {"$self", "value", "start", "stop"}) @ArgumentClinic(name = "start", conversion = ArgumentClinic.ClinicConversion.SliceIndex, defaultValue = "0") @@ -153,7 +196,7 @@ int index(VirtualFrame frame, Object self, Object value, int startIn, int endIn, @Cached InlinedBranchProfile startLe0Profile, @Cached InlinedBranchProfile endLe0Profile, @Cached SequenceStorageNodes.ItemIndexNode itemIndexNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { SequenceStorage storage = getTupleStorage.execute(inliningTarget, self); int start = startIn; if (start < 0) { @@ -175,7 +218,7 @@ int index(VirtualFrame frame, Object self, Object value, int startIn, int endIn, if (idx != -1) { return idx; } - throw raiseNode.get(inliningTarget).raise(PythonErrorType.ValueError, ErrorMessages.X_NOT_IN_TUPLE); + throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.X_NOT_IN_TUPLE); } } @@ -184,16 +227,16 @@ int index(VirtualFrame frame, Object self, Object value, int startIn, int endIn, public abstract static class CountNode extends PythonBinaryBuiltinNode { @Specialization - long count(VirtualFrame frame, Object self, Object value, + static long count(VirtualFrame frame, Object self, Object value, @Bind("this") Node inliningTarget, @Cached GetTupleStorage getTupleStorage, @Cached("createNotNormalized()") SequenceStorageNodes.GetItemNode getItemNode, - @Cached PyObjectRichCompareBool.EqNode eqNode) { + @Cached PyObjectRichCompareBool eqNode) { long count = 0; SequenceStorage tupleStore = getTupleStorage.execute(inliningTarget, self); for (int i = 0; i < tupleStore.length(); i++) { Object seqItem = getItemNode.execute(tupleStore, i); - if (eqNode.compare(frame, inliningTarget, seqItem, value)) { + if (eqNode.execute(frame, inliningTarget, seqItem, value, RichCmpOp.Py_EQ)) { count++; } } @@ -214,7 +257,7 @@ public int len(Object self, } } - @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_repr, isComplex = true) @GenerateNodeFactory public abstract static class ReprNode extends PythonUnaryBuiltinNode { @Override @@ -289,160 +332,38 @@ static Object doIt(VirtualFrame frame, Object self, Object idx, @Bind("this") Node inliningTarget, @Cached InlinedConditionProfile validProfile, @Cached PyIndexCheckNode indexCheckNode, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached GetTupleStorage getTupleStorage, @Cached SequenceStorageMpSubscriptNode subscriptNode) { if (!validProfile.profile(inliningTarget, SequenceStorageMpSubscriptNode.isValidIndex(inliningTarget, idx, indexCheckNode))) { raiseNonIntIndex(inliningTarget, raiseNode, idx); } return subscriptNode.execute(frame, inliningTarget, getTupleStorage.execute(inliningTarget, self), idx, - ErrorMessages.TUPLE_OUT_OF_BOUNDS, PythonObjectFactory::createTuple); + ErrorMessages.TUPLE_OUT_OF_BOUNDS, PFactory::createTuple); } @InliningCutoff - private static void raiseNonIntIndex(Node inliningTarget, PRaiseNode.Lazy raiseNode, Object index) { - raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_INDEX_MUST_BE_INT_OR_SLICES, "tuple", index); - } - } - - @GenerateCached(false) - abstract static class AbstractCmpNode extends PythonBinaryBuiltinNode { - @Specialization - static boolean doPTuple(VirtualFrame frame, PTuple left, PTuple right, - @Shared("cmp") @Cached("createCmp()") SequenceStorageNodes.CmpNode cmp) { - return cmp.execute(frame, left.getSequenceStorage(), right.getSequenceStorage()); - } - - @Specialization(guards = {"checkRight.execute(inliningTarget, right)"}, limit = "1", replaces = "doPTuple") - static boolean doTuple(VirtualFrame frame, Object left, Object right, - @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached PyTupleCheckNode checkRight, - @Cached GetTupleStorage getLeft, - @Cached GetTupleStorage getRight, - @Shared("cmp") @Cached("createCmp()") SequenceStorageNodes.CmpNode cmp) { - return cmp.execute(frame, getLeft.execute(inliningTarget, left), getRight.execute(inliningTarget, right)); - } - - @Fallback - @SuppressWarnings("unused") - static Object doOther(Object left, Object right) { - return PNotImplemented.NOT_IMPLEMENTED; - } - - @NeverDefault - protected abstract SequenceStorageNodes.CmpNode createCmp(); - } - - @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class EqNode extends AbstractCmpNode { - - @NeverDefault - @Override - protected CmpNode createCmp() { - return SequenceStorageNodes.CmpNode.createEq(); - } - } - - @Builtin(name = J___NE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class NeNode extends AbstractCmpNode { - - @NeverDefault - @Override - protected CmpNode createCmp() { - return SequenceStorageNodes.CmpNode.createNe(); - } - } - - @Builtin(name = J___GE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class GeNode extends AbstractCmpNode { - - @NeverDefault - @Override - protected CmpNode createCmp() { - return SequenceStorageNodes.CmpNode.createGe(); - } - } - - @Builtin(name = J___LE__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class LeNode extends AbstractCmpNode { - - @NeverDefault - @Override - protected CmpNode createCmp() { - return SequenceStorageNodes.CmpNode.createLe(); - } - } - - @Builtin(name = J___GT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class GtNode extends AbstractCmpNode { - - @NeverDefault - @Override - protected CmpNode createCmp() { - return SequenceStorageNodes.CmpNode.createGt(); - } - } - - @Builtin(name = J___LT__, minNumOfPositionalArgs = 2) - @GenerateNodeFactory - abstract static class LtNode extends AbstractCmpNode { - - @NeverDefault - @Override - protected CmpNode createCmp() { - return SequenceStorageNodes.CmpNode.createLt(); + private static void raiseNonIntIndex(Node inliningTarget, PRaiseNode raiseNode, Object index) { + raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_INDEX_MUST_BE_INT_OR_SLICES, "tuple", index); } } - @Builtin(name = J___TRUFFLE_RICHCOMPARE__, minNumOfPositionalArgs = 3) + @Slot(value = SlotKind.tp_richcompare, isComplex = true) @GenerateNodeFactory - @ImportStatic(ComparisonOp.class) - abstract static class RichCompareNode extends PythonTernaryBuiltinNode { - - @Specialization(guards = {"opCode == cachedOp.opCode"}, limit = "6") - static Object doPTuple(VirtualFrame frame, PTuple left, PTuple right, @SuppressWarnings("unused") int opCode, - @SuppressWarnings("unused") @Cached("fromOpCode(opCode)") ComparisonOp cachedOp, - @Exclusive @Cached("createCmpNode(cachedOp)") SequenceStorageNodes.CmpNode cmpNode) { - return cmpNode.execute(frame, left.getSequenceStorage(), right.getSequenceStorage()); - } - - @Specialization(guards = {"opCode == cachedOp.opCode"}, limit = "6", replaces = "doPTuple") - static Object doGeneric(VirtualFrame frame, Object left, Object right, @SuppressWarnings("unused") int opCode, + abstract static class TupleRichCmpNode extends TpSlotRichCompare.RichCmpBuiltinNode { + @Specialization + static Object doTuple(VirtualFrame frame, Object left, Object right, RichCmpOp op, @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached("fromOpCode(opCode)") ComparisonOp cachedOp, @Cached PyTupleCheckNode checkLeft, @Cached PyTupleCheckNode checkRight, + @Cached InlinedConditionProfile tupleCheckProfile, @Cached GetTupleStorage getLeft, @Cached GetTupleStorage getRight, - @Exclusive @Cached("createCmpNode(cachedOp)") SequenceStorageNodes.CmpNode cmpNode) { - if (!checkLeft.execute(inliningTarget, left) || !checkRight.execute(inliningTarget, right)) { + @Cached SequenceStorageNodes.CmpNode cmp) { + if (tupleCheckProfile.profile(inliningTarget, !checkLeft.execute(inliningTarget, left) || !checkRight.execute(inliningTarget, right))) { return PNotImplemented.NOT_IMPLEMENTED; } - return cmpNode.execute(frame, getLeft.execute(inliningTarget, left), getRight.execute(inliningTarget, right)); - } - - @NeverDefault - static SequenceStorageNodes.CmpNode createCmpNode(ComparisonOp op) { - switch (op) { - case LE: - return SequenceStorageNodes.CmpNode.createLe(); - case LT: - return SequenceStorageNodes.CmpNode.createLt(); - case EQ: - return SequenceStorageNodes.CmpNode.createEq(); - case NE: - return SequenceStorageNodes.CmpNode.createNe(); - case GT: - return SequenceStorageNodes.CmpNode.createGt(); - case GE: - return SequenceStorageNodes.CmpNode.createGe(); - } - throw CompilerDirectives.shouldNotReachHere(); + return cmp.execute(frame, inliningTarget, getLeft.execute(inliningTarget, left), getRight.execute(inliningTarget, right), false, null, null, op); } } @@ -456,21 +377,18 @@ static PTuple doTuple(Object left, Object right, @SuppressWarnings("unused") @Cached PyTupleCheckNode checkRight, @Cached GetTupleStorage getLeft, @Cached GetTupleStorage getRight, - @Cached("createConcat()") ConcatNode concatNode, - @Cached PythonObjectFactory factory) { - SequenceStorage concatenated = concatNode.execute(getLeft.execute(inliningTarget, left), getRight.execute(inliningTarget, right)); - return factory.createTuple(concatenated); - } - - @NeverDefault - protected static SequenceStorageNodes.ConcatNode createConcat() { - return SequenceStorageNodes.ConcatNode.create(ListGeneralizationNode::create); + @Cached SequenceStorageNodes.ConcatListOrTupleNode concatNode, + @Bind PythonLanguage language) { + SequenceStorage leftStorage = getLeft.execute(inliningTarget, left); + SequenceStorage rightStorage = getRight.execute(inliningTarget, right); + SequenceStorage concatenated = concatNode.execute(inliningTarget, leftStorage, rightStorage); + return PFactory.createTuple(language, concatenated); } @Fallback static Object doGeneric(@SuppressWarnings("unused") Object left, Object right, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.CAN_ONLY_CONCAT_S_NOT_P_TO_S, "tuple", right, "tuple"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CAN_ONLY_CONCAT_S_NOT_P_TO_S, "tuple", right, "tuple"); } } @@ -484,20 +402,18 @@ static Object doTuple(VirtualFrame frame, Object left, int repeats, @Cached PyTupleCheckExactNode checkTuple, @Cached GetTupleStorage getLeft, @Cached InlinedConditionProfile isSingleRepeat, - @Cached PyNumberAsSizeNode asSizeNode, - @Cached SequenceStorageNodes.RepeatNode repeatNode, - @Cached PythonObjectFactory.Lazy factory) { + @Cached SequenceStorageNodes.RepeatNode repeatNode) { if (isSingleRepeat.profile(inliningTarget, repeats == 1 && checkTuple.execute(inliningTarget, left))) { return left; } else { - return factory.get(inliningTarget).createTuple(repeatNode.execute(frame, getLeft.execute(inliningTarget, left), repeats)); + return PFactory.createTuple(PythonLanguage.get(inliningTarget), repeatNode.execute(frame, getLeft.execute(inliningTarget, left), repeats)); } } } - @Builtin(name = J___CONTAINS__, minNumOfPositionalArgs = 2) + @Slot(value = SlotKind.sq_contains, isComplex = true) @GenerateNodeFactory - abstract static class ContainsNode extends PythonBinaryBuiltinNode { + abstract static class ContainsNode extends SqContainsBuiltinNode { @Specialization boolean contains(VirtualFrame frame, Object self, Object other, @Bind("this") Node inliningTarget, @@ -505,52 +421,51 @@ boolean contains(VirtualFrame frame, Object self, Object other, @Cached SequenceStorageNodes.ContainsNode containsNode) { return containsNode.execute(frame, inliningTarget, getTupleStorage.execute(inliningTarget, self), other); } - } - @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_iter, isComplex = true) @GenerateNodeFactory public abstract static class IterNode extends PythonUnaryBuiltinNode { @Specialization(guards = {"isIntStorage(primary)"}) static PIntegerSequenceIterator doPTupleInt(PTuple primary, - @Shared @Cached PythonObjectFactory factory) { - return factory.createIntegerSequenceIterator((IntSequenceStorage) primary.getSequenceStorage(), primary); + @Bind PythonLanguage language) { + return PFactory.createIntegerSequenceIterator(language, (IntSequenceStorage) primary.getSequenceStorage(), primary); } @Specialization(guards = {"isObjectStorage(primary)"}) static PObjectSequenceIterator doPTupleObject(PTuple primary, - @Shared @Cached PythonObjectFactory factory) { - return factory.createObjectSequenceIterator((ObjectSequenceStorage) primary.getSequenceStorage(), primary); + @Bind PythonLanguage language) { + return PFactory.createObjectSequenceIterator(language, (ObjectSequenceStorage) primary.getSequenceStorage(), primary); } @Specialization(guards = {"isLongStorage(primary)"}) static PLongSequenceIterator doPTupleLong(PTuple primary, - @Shared @Cached PythonObjectFactory factory) { - return factory.createLongSequenceIterator((LongSequenceStorage) primary.getSequenceStorage(), primary); + @Bind PythonLanguage language) { + return PFactory.createLongSequenceIterator(language, (LongSequenceStorage) primary.getSequenceStorage(), primary); } @Specialization(guards = {"isDoubleStorage(primary)"}) static PDoubleSequenceIterator doPTupleDouble(PTuple primary, - @Shared @Cached PythonObjectFactory factory) { - return factory.createDoubleSequenceIterator((DoubleSequenceStorage) primary.getSequenceStorage(), primary); + @Bind PythonLanguage language) { + return PFactory.createDoubleSequenceIterator(language, (DoubleSequenceStorage) primary.getSequenceStorage(), primary); } @Specialization(guards = {"!isIntStorage(primary)", "!isLongStorage(primary)", "!isDoubleStorage(primary)"}) static PSequenceIterator doPTuple(PTuple primary, - @Shared @Cached PythonObjectFactory factory) { - return factory.createSequenceIterator(primary); + @Bind PythonLanguage language) { + return PFactory.createSequenceIterator(language, primary); } @Specialization static PSequenceIterator doNativeTuple(PythonAbstractNativeObject primary, - @Shared @Cached PythonObjectFactory factory) { - return factory.createSequenceIterator(primary); + @Bind PythonLanguage language) { + return PFactory.createSequenceIterator(language, primary); } } - @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1) + @Slot(value = SlotKind.tp_hash, isComplex = true) @GenerateNodeFactory - public abstract static class HashNode extends PythonUnaryBuiltinNode { + public abstract static class HashNode extends HashBuiltinNode { protected static long HASH_UNSET = -1; @Specialization(guards = {"self.getHash() != HASH_UNSET"}) @@ -607,8 +522,8 @@ public abstract static class GetNewargsNode extends PythonUnaryBuiltinNode { static PTuple doIt(Object self, @Bind("this") Node inliningTarget, @Cached GetTupleStorage getTupleStorage, - @Cached PythonObjectFactory factory) { - return factory.createTuple(new Object[]{factory.createTuple(getTupleStorage.execute(inliningTarget, self))}); + @Bind PythonLanguage language) { + return PFactory.createTuple(language, new Object[]{PFactory.createTuple(language, getTupleStorage.execute(inliningTarget, self))}); } } @@ -617,8 +532,8 @@ static PTuple doIt(Object self, public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode { @Specialization static Object classGetItem(Object cls, Object key, - @Cached PythonObjectFactory factory) { - return factory.createGenericAlias(cls, key); + @Bind PythonLanguage language) { + return PFactory.createGenericAlias(language, cls, key); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/TupleGetterBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/TupleGetterBuiltins.java index 33d8405fc1..6a57486201 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/TupleGetterBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/TupleGetterBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,6 +40,7 @@ */ package com.oracle.graal.python.builtins.objects.tuple; +import static com.oracle.graal.python.nodes.BuiltinNames.J_TUPLE_GETTER; import static com.oracle.graal.python.nodes.ErrorMessages.CANT_DELETE_ATTRIBUTE; import static com.oracle.graal.python.nodes.ErrorMessages.CANT_SET_ATTRIBUTE; import static com.oracle.graal.python.nodes.ErrorMessages.DESC_FOR_INDEX_S_FOR_S_DOESNT_APPLY_TO_P; @@ -49,13 +50,17 @@ import java.util.List; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.ArgumentClinic; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; +import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.tuple.TupleGetterBuiltinsClinicProviders.TupleGetterNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.DescrGetBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrSet.DescrSetBuiltinNode; @@ -64,9 +69,11 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; @@ -87,6 +94,23 @@ protected List> getNodeFa return TupleGetterBuiltinsFactory.getFactories(); } + @Slot(value = SlotKind.tp_new, isComplex = true) + @SlotSignature(name = J_TUPLE_GETTER, parameterNames = {"cls", "index", "doc"}) + @ArgumentClinic(name = "index", conversion = ArgumentClinic.ClinicConversion.Index) + @GenerateNodeFactory + public abstract static class TupleGetterNode extends PythonTernaryClinicBuiltinNode { + @Override + protected ArgumentClinicProvider getArgumentClinic() { + return TupleGetterNodeClinicProviderGen.INSTANCE; + } + + @Specialization + Object construct(@SuppressWarnings("unused") Object cls, int index, Object doc, + @Bind PythonLanguage language) { + return PFactory.createTupleGetter(language, index, doc); + } + } + @Builtin(name = J___REDUCE__, minNumOfPositionalArgs = 1) @GenerateNodeFactory public abstract static class ReduceNode extends PythonUnaryBuiltinNode { @@ -94,9 +118,9 @@ public abstract static class ReduceNode extends PythonUnaryBuiltinNode { static Object reduce(PTupleGetter self, @Bind("this") Node inliningTarget, @Cached GetClassNode getClassNode, - @Cached PythonObjectFactory factory) { - PTuple args = factory.createTuple(new Object[]{self.getIndex(), self.getDoc()}); - return factory.createTuple(new Object[]{getClassNode.execute(inliningTarget, self), args}); + @Bind PythonLanguage language) { + PTuple args = PFactory.createTuple(language, new Object[]{self.getIndex(), self.getDoc()}); + return PFactory.createTuple(language, new Object[]{getClassNode.execute(inliningTarget, self), args}); } } @@ -108,10 +132,10 @@ static Object getTuple(VirtualFrame frame, PTupleGetter self, PTuple instance, @ @Bind("this") Node inliningTarget, @Cached PyObjectSizeNode sizeNode, @Cached TupleBuiltins.GetItemNode getItemNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { final int index = self.getIndex(); if (index >= sizeNode.execute(frame, inliningTarget, instance)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.IndexError, TUPLE_OUT_OF_BOUNDS); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.IndexError, TUPLE_OUT_OF_BOUNDS); } return getItemNode.execute(frame, instance, index); } @@ -124,9 +148,9 @@ static Object getNone(@SuppressWarnings("unused") VirtualFrame frame, PTupleGett @Fallback @InliningCutoff static Object getOthers(@SuppressWarnings("unused") VirtualFrame frame, Object self, Object instance, @SuppressWarnings("unused") Object owner, - @Cached PRaiseNode raiseNode) { + @Bind("this") Node inliningTarget) { final int index = ((PTupleGetter) self).getIndex(); - throw raiseNode.raise(PythonBuiltinClassType.TypeError, DESC_FOR_INDEX_S_FOR_S_DOESNT_APPLY_TO_P, + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, DESC_FOR_INDEX_S_FOR_S_DOESNT_APPLY_TO_P, index, "tuple subclasses", instance); } } @@ -139,9 +163,9 @@ abstract static class DescrSet extends DescrSetBuiltinNode { @SuppressWarnings("unused") void set(PTupleGetter self, Object instance, Object value) { if (PGuards.isNoValue(value)) { - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.AttributeError, CANT_DELETE_ATTRIBUTE); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.AttributeError, CANT_DELETE_ATTRIBUTE); } else { - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.AttributeError, CANT_SET_ATTRIBUTE); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.AttributeError, CANT_SET_ATTRIBUTE); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/MethodsFlags.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/MethodsFlags.java deleted file mode 100644 index 2abeca2116..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/MethodsFlags.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.type; - -import com.oracle.graal.python.annotations.CApiConstants; - -/** - * This class is a simple representation of methods slots occupation of `cls->tp_as_number`, - * `cls->tp_as_sequence` and `cls->tp_as_mapping`. Builtins types are populated manually and then - * assigned in {@link com.oracle.graal.python.builtins.PythonBuiltinClassType}. While other heap - * types are set during type initalization in {@link SpecialMethodSlot}. - * - * Use {@link com.oracle.graal.python.lib.GetMethodsFlagsNode} to retrieve slots occupation of a - * given class. - */ -@CApiConstants -public abstract class MethodsFlags { - - // PyNumberMethods - - /* - * Number implementations must check *both* arguments for proper type and implement the - * necessary conversions in the slot functions themselves. - */ - - public static final long NB_SUBTRACT = 1L << 1; - public static final long NB_MULTIPLY = 1L << 2; - public static final long NB_REMAINDER = 1L << 3; - public static final long NB_DIVMOD = 1L << 4; - public static final long NB_POWER = 1L << 5; - public static final long NB_NEGATIVE = 1L << 6; - public static final long NB_POSITIVE = 1L << 7; - public static final long NB_ABSOLUTE = 1L << 8; - public static final long NB_BOOL = 1L << 9; - public static final long NB_INVERT = 1L << 10; - public static final long NB_LSHIFT = 1L << 11; - public static final long NB_RSHIFT = 1L << 12; - public static final long NB_AND = 1L << 13; - public static final long NB_XOR = 1L << 14; - public static final long NB_OR = 1L << 15; - public static final long NB_INT = 1L << 16; - public static final long NB_FLOAT = 1L << 18; - public static final long NB_INPLACE_ADD = 1L << 19; - public static final long NB_INPLACE_SUBTRACT = 1L << 20; - public static final long NB_INPLACE_MULTIPLY = 1L << 21; - public static final long NB_INPLACE_REMAINDER = 1L << 22; - public static final long NB_INPLACE_POWER = 1L << 23; - public static final long NB_INPLACE_LSHIFT = 1L << 24; - public static final long NB_INPLACE_RSHIFT = 1L << 25; - public static final long NB_INPLACE_AND = 1L << 26; - public static final long NB_INPLACE_XOR = 1L << 27; - public static final long NB_INPLACE_OR = 1L << 28; - public static final long NB_FLOOR_DIVIDE = 1L << 29; - public static final long NB_TRUE_DIVIDE = 1L << 30; - public static final long NB_INPLACE_FLOOR_DIVIDE = 1L << 31; - public static final long NB_INPLACE_TRUE_DIVIDE = 1L << 32; - public static final long NB_INDEX = 1L << 33; - public static final long NB_MATRIX_MULTIPLY = 1L << 34; - public static final long NB_INPLACE_MATRIX_MULTIPLY = 1L << 35; - - // this is helpful to determine if the binop slot is of a heaptype. - public static final long SLOT1BINFULL = 1L << 39; - - // PySequenceMethods - - public static final long SQ_LENGTH = 1L << 40; - public static final long SQ_REPEAT = 1L << 42; - public static final long SQ_ITEM = 1L << 43; - public static final long SQ_ASS_ITEM = 1L << 45; - public static final long SQ_CONTAINS = 1L << 47; - public static final long SQ_INPLACE_CONCAT = 1L << 48; - public static final long SQ_INPLACE_REPEAT = 1L << 49; - - // PyMappingMethods - - public static final long MP_LENGTH = 1L << 50; - public static final long MP_SUBSCRIPT = 1L << 51; - public static final long MP_ASS_SUBSCRIPT = 1L << 52; - - public static final long AM_AWAIT = 1L << 54; - public static final long AM_AITER = 1L << 55; - public static final long AM_ANEXT = 1L << 56; - public static final long AM_SEND = 1L << 57; - - public static final long ASYNC_METHODS = AM_AWAIT | AM_AITER | AM_ANEXT | AM_SEND; - public static final long SEQUENCE_METHODS = SQ_LENGTH | SQ_ITEM | SQ_ASS_ITEM | SQ_INPLACE_CONCAT | SQ_INPLACE_REPEAT | SQ_REPEAT | SQ_CONTAINS; - public static final long MAPPING_METHODS = MP_LENGTH | MP_SUBSCRIPT | MP_ASS_SUBSCRIPT; - - // builtins methods flags - - public static final long DEFAULT_M_FLAGS = 0; - - public static final long TYPE_M_FLAGS = NB_OR; - - public static final long NONE_M_FLAGS = NB_BOOL; - public static final long INT_M_FLAGS = NB_SUBTRACT | NB_MULTIPLY | NB_REMAINDER | NB_DIVMOD | - NB_POWER | NB_NEGATIVE | NB_POSITIVE | NB_ABSOLUTE | NB_BOOL | NB_INVERT | NB_LSHIFT | - NB_RSHIFT | NB_AND | NB_XOR | NB_OR | NB_INT | NB_FLOAT | - NB_FLOOR_DIVIDE | NB_TRUE_DIVIDE | NB_INDEX; - public static final long BOOLEAN_M_FLAGS = INT_M_FLAGS /* base */ | NB_AND | NB_XOR | NB_OR; - public static final long FLOAT_M_FLAGS = NB_SUBTRACT | NB_MULTIPLY | NB_REMAINDER | NB_DIVMOD | - NB_POWER | NB_NEGATIVE | NB_POSITIVE | NB_ABSOLUTE | NB_BOOL | NB_INT | NB_FLOAT | - NB_FLOOR_DIVIDE | NB_TRUE_DIVIDE; - public static final long BYTE_ARRAY_M_FLAGS = NB_REMAINDER | SQ_LENGTH | SQ_REPEAT | - SQ_ITEM | SQ_ASS_ITEM | SQ_CONTAINS | SQ_INPLACE_CONCAT | SQ_INPLACE_REPEAT | MP_LENGTH | - MP_SUBSCRIPT | MP_ASS_SUBSCRIPT; - public static final long BYTES_M_FLAGS = NB_REMAINDER | SQ_LENGTH | SQ_REPEAT | SQ_ITEM | - SQ_CONTAINS | MP_LENGTH | MP_SUBSCRIPT; - public static final long COMPLEX_M_FLAGS = NB_SUBTRACT | NB_MULTIPLY | NB_POWER | NB_NEGATIVE | - NB_POSITIVE | NB_ABSOLUTE | NB_BOOL | NB_TRUE_DIVIDE; - public static final long DICT_M_FLAGS = NB_OR | NB_INPLACE_OR | SQ_CONTAINS | MP_LENGTH | MP_SUBSCRIPT | - MP_ASS_SUBSCRIPT; - public static final long DICTVALUESVIEW_M_FLAGS = SQ_LENGTH; - public static final long DICTKEYSVIEW_M_FLAGS = NB_SUBTRACT | NB_AND | NB_XOR | NB_OR | SQ_LENGTH | - SQ_CONTAINS; - - public static final long DICTITEMSVIEW_M_FLAGS = NB_SUBTRACT | NB_AND | NB_XOR | NB_OR | SQ_LENGTH | - SQ_CONTAINS; - public static final long LIST_M_FLAGS = SQ_LENGTH | SQ_REPEAT | SQ_ITEM | SQ_ASS_ITEM | SQ_CONTAINS | - SQ_INPLACE_CONCAT | SQ_INPLACE_REPEAT | MP_LENGTH | MP_SUBSCRIPT | MP_ASS_SUBSCRIPT; - public static final long TUPLE_M_FLAGS = SQ_LENGTH | SQ_REPEAT | SQ_ITEM | SQ_CONTAINS | - MP_LENGTH | MP_SUBSCRIPT; - public static final long MEMORYVIEW_M_FLAGS = SQ_LENGTH | SQ_ITEM | MP_LENGTH | MP_SUBSCRIPT | - MP_ASS_SUBSCRIPT; - public static final long RANGE_M_FLAGS = NB_BOOL | SQ_LENGTH | SQ_ITEM | SQ_CONTAINS | MP_LENGTH | - MP_SUBSCRIPT; - public static final long FROZENSET_M_FLAGS = NB_SUBTRACT | NB_AND | NB_XOR | NB_OR | SQ_LENGTH | - SQ_CONTAINS; - public static final long SET_M_FLAGS = NB_SUBTRACT | NB_AND | NB_XOR | NB_OR | - NB_INPLACE_SUBTRACT | NB_INPLACE_AND | NB_INPLACE_XOR | NB_INPLACE_OR | SQ_LENGTH | SQ_CONTAINS; - public static final long STRING_M_FLAGS = NB_REMAINDER | SQ_LENGTH | SQ_REPEAT | SQ_ITEM | - SQ_CONTAINS | MP_LENGTH | MP_SUBSCRIPT; - - public static final long DEFAULTDICT_M_FLAGS = NB_OR | DICT_M_FLAGS; - public static final long DEQUE_M_FLAGS = SQ_LENGTH | SQ_REPEAT | - SQ_ITEM | SQ_ASS_ITEM | SQ_CONTAINS | SQ_INPLACE_CONCAT | SQ_INPLACE_REPEAT; - - public static final long MAPPINGPROXY_M_FLAGS = NB_OR | NB_INPLACE_OR | SQ_CONTAINS | MP_LENGTH | MP_SUBSCRIPT; - public static final long ARRAY_M_FLAGS = SQ_LENGTH | SQ_REPEAT | SQ_ITEM | SQ_ASS_ITEM | - SQ_CONTAINS | SQ_INPLACE_CONCAT | SQ_INPLACE_REPEAT | MP_LENGTH | MP_SUBSCRIPT | MP_ASS_SUBSCRIPT; - public static final long MMAP_M_FLAGS = SQ_LENGTH | SQ_ITEM | SQ_ASS_ITEM | - MP_LENGTH | MP_SUBSCRIPT | MP_ASS_SUBSCRIPT; - - public static final long GENERIC_ALIAS_M_FLAGS = NB_OR | MP_SUBSCRIPT; - public static final long UNION_TYPE_M_FLAGS = NB_OR | MP_SUBSCRIPT; - - public static final long CONTEXT_M_FLAGS = SQ_CONTAINS | MP_LENGTH | MP_SUBSCRIPT; - - public static final long GENERATOR_M_FLAGS = AM_SEND; - public static final long COROUTINE_M_FLAGS = AM_AWAIT | AM_SEND; - public static final long ASYNC_GENERATOR_M_FLAGS = AM_AITER | AM_ANEXT | AM_SEND; - public static final long ASYNC_GENERATOR_ASEND_M_FLAGS = AM_AWAIT; - public static final long ASYNC_GENERATOR_ATHROW_M_FLAGS = AM_AWAIT; - - // _ctypes - public static final long PYCFUNCPTRTYPE_M_FLAGS = SQ_REPEAT | TYPE_M_FLAGS; - public static final long PYCARRAY_M_FLAGS = SQ_LENGTH | SQ_ITEM | SQ_ASS_ITEM | MP_LENGTH | MP_SUBSCRIPT | - MP_ASS_SUBSCRIPT; - public static final long PYCARRAYTYPE_M_FLAGS = SQ_REPEAT | TYPE_M_FLAGS; - public static final long PYCFUNCPTR_M_FLAGS = NB_BOOL; - public static final long PYCPOINTER_M_FLAGS = NB_BOOL | SQ_ITEM | SQ_ASS_ITEM | MP_SUBSCRIPT; - public static final long PYCPOINTERTYPE_M_FLAGS = SQ_REPEAT | TYPE_M_FLAGS; - public static final long PYCSIMPLETYPE_M_FLAGS = SQ_REPEAT | TYPE_M_FLAGS; - public static final long PYCSTRUCTTYPE_M_FLAGS = SQ_REPEAT | TYPE_M_FLAGS; - public static final long SIMPLECDATA_M_FLAGS = NB_BOOL; - public static final long UNIONTYPE_M_FLAGS = SQ_REPEAT | TYPE_M_FLAGS; - - public static final long FOREIGNNUMBER_M_FLAGS = INT_M_FLAGS | FLOAT_M_FLAGS; - -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonBuiltinClass.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonBuiltinClass.java index 259834f2be..7e8ba5d0e3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonBuiltinClass.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonBuiltinClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -31,6 +31,7 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; +import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; @@ -69,7 +70,6 @@ public PythonBuiltinClass(PythonLanguage lang, PythonBuiltinClassType builtinCla super(lang, builtinClass.getType(), builtinClass.getType().getInstanceShape(lang), builtinClass.getInstanceShape(lang), builtinClass.getName(), base, new PythonAbstractClass[]{base}, builtinClass.getSlots()); this.type = builtinClass; - this.methodsFlags = type.getMethodsFlags(); } @Override @@ -78,7 +78,7 @@ public void setAttribute(TruffleString name, Object value) { if (!PythonContext.get(null).isCoreInitialized()) { setAttributeUnsafe(name, value); } else { - throw PRaiseNode.raiseUncached(null, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, PyObjectReprAsTruffleStringNode.executeUncached(name), this); + throw PRaiseNode.raiseStatic(null, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, PyObjectReprAsTruffleStringNode.executeUncached(name), this); } } @@ -101,10 +101,6 @@ public void onAttributeUpdate(TruffleString key, Object newValue) { // builtins. So there should be no assumptions to invalidate yet assert !getMethodResolutionOrder().invalidateAttributeInMROFinalAssumptions(key); assert checkSpecialMethodUpdate(key, newValue); - SpecialMethodSlot slot = SpecialMethodSlot.findSpecialSlotUncached(key); - if (slot != null) { - SpecialMethodSlot.fixupSpecialMethodSlot(this, slot, newValue); - } // NO_VALUE changes MRO lookup results without actually changing any Shapes in the MRO, this // can prevent some optimizations, so it is best to avoid any code that triggers such code // paths during initialization @@ -117,7 +113,7 @@ private static boolean checkSpecialMethodUpdate(TruffleString key, Object newVal // only with PythonBuiltinClassType#slots // TODO: change to the commented out line below once all @Builtin are converted to @Slot // assert ... || (newValue instanceof PBuiltinFunction pbf && pbf.getSlot() != null); - assert !TpSlots.isSpecialMethod(key) || (newValue instanceof PBuiltinFunction pbf); + assert !TpSlots.isSpecialMethod(key) || newValue instanceof PBuiltinFunction || newValue instanceof PBuiltinMethod; return true; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonClass.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonClass.java index b8db247479..12e0b93c84 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonClass.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -32,8 +32,6 @@ import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyTypeExtra; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetSubclassesAsArrayNode; import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromPythonObjectNode; @@ -71,8 +69,6 @@ public final class PythonClass extends PythonManagedClass { private static final int MRO_SUBTYPES_MAX = 64; private static final int MRO_SHAPE_INVALIDATIONS_MAX = 5; - public HPyTypeExtra hPyTypeExtra; - private final AtomicReference slotsFinalAssumption = new AtomicReference<>(); private MroShape mroShape; // only set if there's no inheritance from native types /** @@ -382,59 +378,4 @@ static void updateMroShapeSubTypes(PythonBuiltinClass klass) { } } } - - public long getBasicSize() { - return hPyTypeExtra != null ? hPyTypeExtra.basicSize : -1; - } - - public long getItemSize() { - return hPyTypeExtra != null ? hPyTypeExtra.itemSize : -1; - } - - public Object getHPyDestroyFunc() { - if (hPyTypeExtra != null) { - return hPyTypeExtra.hpyDestroyFunc; - } - return null; - } - - public Object getTpName() { - return hPyTypeExtra != null ? hPyTypeExtra.tpName : null; - } - - public long getFlags() { - return hPyTypeExtra != null ? hPyTypeExtra.flags : 0; - } - - public int getBuiltinShape() { - return hPyTypeExtra != null ? hPyTypeExtra.builtinShape : GraalHPyDef.HPyType_BUILTIN_SHAPE_LEGACY; - } - - public Object getHPyDefaultCallFunc() { - return hPyTypeExtra != null ? hPyTypeExtra.defaultCallFunc : null; - } - - public long getHPyVectorcallOffset() { - return hPyTypeExtra != null ? hPyTypeExtra.vectorcallOffset : Long.MIN_VALUE; - } - - public void setHPyDestroyFunc(Object destroyFunc) { - hPyTypeExtra.hpyDestroyFunc = destroyFunc; - } - - public void setHPyDefaultCallFunc(Object defaultCallFunc) { - hPyTypeExtra.defaultCallFunc = defaultCallFunc; - } - - public void setHPyVectorcallOffset(int vectorcallOffset) { - hPyTypeExtra.vectorcallOffset = vectorcallOffset; - } - - public void setHPyTypeExtra(HPyTypeExtra hpyTypeExtra) { - this.hPyTypeExtra = hpyTypeExtra; - } - - public boolean isHPyType() { - return hPyTypeExtra != null; - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonManagedClass.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonManagedClass.java index ddf02c227a..504dbe24ab 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonManagedClass.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonManagedClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -45,13 +45,12 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.MroSequenceStorage; -import com.oracle.truffle.api.Assumption; import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.strings.TruffleString; import com.oracle.truffle.api.strings.TruffleString.CodePointAtIndexNode; @@ -72,17 +71,8 @@ public abstract class PythonManagedClass extends PythonObject implements PythonA private TruffleString qualName; private int indexedSlotCount; - /** - * Access using methods in {@link SpecialMethodSlot}. - * - * @see SpecialMethodSlot - */ - Object[] specialMethodSlots; - protected TpSlots tpSlots; - @CompilationFinal protected long methodsFlags = 0L; - /** {@code true} if the MRO contains a native class. */ private final boolean needsNativeAllocation; @CompilationFinal private boolean mroInitialized = false; @@ -113,7 +103,8 @@ protected PythonManagedClass(PythonLanguage lang, Object typeClass, Shape classS unsafeSetSuperClass(baseClasses); } - this.setMRO(ComputeMroNode.doSlowPath(this, invokeMro)); + // TODO should pass node for exception location + this.setMRO(ComputeMroNode.doSlowPath(null, this, invokeMro)); if (invokeMro) { mroInitialized = true; } @@ -131,7 +122,7 @@ protected PythonManagedClass(PythonLanguage lang, Object typeClass, Shape classS this.instanceShape = lang.getShapeForClass(this); } - this.subClasses = PythonObjectFactory.getUncached().createDict(); + this.subClasses = PFactory.createDict(lang); } public boolean isMROInitialized() { @@ -142,18 +133,14 @@ public boolean isMROInitialized() { * Invoke metaclass mro() method and set the result as new method resolution order. */ @TruffleBoundary - public void invokeMro() { - PythonAbstractClass[] mro = ComputeMroNode.invokeMro(this); + public void invokeMro(Node node) { + PythonAbstractClass[] mro = ComputeMroNode.invokeMro(node, this); if (mro != null) { this.setMRO(mro); } mroInitialized = true; } - public Assumption getLookupStableAssumption() { - return methodResolutionOrder.getLookupStableAssumption(); - } - /** * This method needs to be called if the mro changes. (currently not used) */ @@ -242,15 +229,7 @@ public void setAttribute(TruffleString key, Object value) { public boolean canSkipOnAttributeUpdate(TruffleString key, @SuppressWarnings("unused") Object value, TruffleString.CodePointLengthNode codePointLengthNode, TruffleString.CodePointAtIndexNode codePointAtIndexNode) { return !methodResolutionOrder.hasAttributeInMROFinalAssumptions() && - !SpecialMethodSlot.canBeSpecial(key, codePointLengthNode, codePointAtIndexNode); - } - - public final void onAttributeUpdate(Object key, Object value) { - // In compilation: use a profile and call the String key overload - CompilerAsserts.neverPartOfCompilation(); - if (key instanceof TruffleString) { - onAttributeUpdate((TruffleString) key, value); - } + !TpSlots.canBeSpecialMethod(key, codePointLengthNode, codePointAtIndexNode); } @TruffleBoundary @@ -262,24 +241,9 @@ public void onAttributeUpdate(TruffleString key, Object value) { // not initialized yet TpSlots.updateSlot(this, key); } - // TODO: will be removed: - SpecialMethodSlot slot = SpecialMethodSlot.findSpecialSlotUncached(key); - if (slot != null) { - SpecialMethodSlot.fixupSpecialMethodSlot(this, slot, value); - } } } - @TruffleBoundary - public void setMethodsFlags(long flag) { - assert CompilerDirectives.inInterpreter(); - methodsFlags |= flag; - } - - public long getMethodsFlags() { - return methodsFlags; - } - /** * This method supports initialization and solves boot-order problems and should not normally be * used. @@ -294,7 +258,8 @@ private void unsafeSetSuperClass(PythonAbstractClass... newBaseClasses) { for (PythonAbstractClass base : getBaseClasses()) { if (base instanceof PythonManagedClass && !((PythonManagedClass) base).mroInitialized) { - throw PRaiseNode.getUncached().raise(TypeError, ErrorMessages.CANNOT_EXTEND_INCOMPLETE_P, base); + // TODO should pass node for exception location + throw PRaiseNode.raiseStatic(null, TypeError, ErrorMessages.CANNOT_EXTEND_INCOMPLETE_P, base); } } for (PythonAbstractClass base : getBaseClasses()) { @@ -309,7 +274,7 @@ private void unsafeSetSuperClass(PythonAbstractClass... newBaseClasses) { } @TruffleBoundary - public final void setBases(Object newBaseClass, PythonAbstractClass[] newBaseClasses) { + public final void setBases(Node node, Object newBaseClass, PythonAbstractClass[] newBaseClasses) { Object oldBase = getBase(); PythonAbstractClass[] oldBaseClasses = getBaseClasses(); PythonAbstractClass[] oldMRO = this.methodResolutionOrder.getInternalClassArray(); @@ -328,12 +293,12 @@ public final void setBases(Object newBaseClass, PythonAbstractClass[] newBaseCla this.base = newBaseClass; this.baseClasses = newBaseClasses; this.methodResolutionOrder.lookupChanged(); - this.setMRO(ComputeMroNode.doSlowPath(this)); + this.setMRO(ComputeMroNode.doSlowPath(node, this)); for (PythonAbstractClass scls : subclassesArray) { if (scls instanceof PythonManagedClass pmc) { pmc.methodResolutionOrder.lookupChanged(); - pmc.setMRO(ComputeMroNode.doSlowPath(scls)); + pmc.setMRO(ComputeMroNode.doSlowPath(node, scls)); } } } catch (PException pe) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/SpecialMethodSlot.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/SpecialMethodSlot.java deleted file mode 100644 index 127007bb91..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/SpecialMethodSlot.java +++ /dev/null @@ -1,1067 +0,0 @@ -/* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.type; - -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.AM_AITER; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.AM_ANEXT; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.AM_AWAIT; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.NB_INPLACE_ADD; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.NB_INPLACE_MULTIPLY; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.NB_POWER; -import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.SQ_CONTAINS; -import static com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot.Flags.NO_BUILTIN_DESCRIPTORS; -import static com.oracle.graal.python.nodes.HiddenAttr.METHODS_FLAGS; -import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DICT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AENTER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AEXIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ANEXT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AWAIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___BYTES__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___CALL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___CONTAINS__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___DELATTR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ENTER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___EQ__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___EXIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___FORMAT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IADD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INIT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INSTANCECHECK__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ITER__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LENGTH_HINT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MISSING__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEXT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___POW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___REPR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___REVERSED__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ROUND__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RPOW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SET_NAME__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___STR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SUBCLASSCHECK__; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; -import static com.oracle.graal.python.util.PythonUtils.tsLiteral; - -import java.util.ArrayDeque; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Objects; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.Python3Core; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; -import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass; -import com.oracle.graal.python.builtins.objects.common.HashingStorage; -import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem; -import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroStorageNode; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetSubclassesAsArrayNode; -import com.oracle.graal.python.lib.GetMethodsFlagsNodeGen; -import com.oracle.graal.python.nodes.HiddenAttr; -import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromPythonObjectNode; -import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.sequence.storage.MroSequenceStorage; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.Idempotent; -import com.oracle.truffle.api.dsl.NodeFactory; -import com.oracle.truffle.api.strings.TruffleString; -import com.oracle.truffle.api.utilities.CyclicAssumption; - -/** - * Subset of special methods that is cached in {@link PythonManagedClass} and - * {@link PythonBuiltinClassType}. - * - * For {@link PythonManagedClass}, we cache the result of special method lookup in a context - * specific form: exactly the context specific object that regular MRO lookup would give. For - * {@link PythonBuiltinClassType}, we cache only primitive and other context independent values and - * additionally instances of {@link BuiltinMethodDescriptor}, which wrap context independent - * information about the method that would be the result of the lookup. This information is further - * split to language independent (per VM) part, which is the node factory, and per language part, - * which is the call target. Call targets are cached in an array in the {@link PythonLanguage} - * instance, and {@link BuiltinMethodDescriptor} holds only index into that array. - * - * The state of the special methods cache in {@link PythonManagedClass} should mostly reflect what - * would be "cached" in the corresponding special slots in CPython. CPython updates the slots in - * {@code type.__setattr__}, we do the same and additionally also in - * {@link com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode}, which is used - * directly from some places bypassing {@code type.__setattr__}. - * - * The cache in {@link PythonBuiltinClassType} may contain {@code null} entries, which indicate that - * given slot cannot be cached in a context independent way. In such case, one needs to resolve to - * {@link PythonBuiltinClass} and lookup the slot there. - * - * The cache makes an assumption that builtin types do not change after GraalPython is fully - * initialized. - */ -public enum SpecialMethodSlot { - DelAttr(T___DELATTR__), - - Dict(T___DICT__), - - Iter(T___ITER__), - Next(T___NEXT__), - Await(T___AWAIT__, AM_AWAIT), - - AEnter(T___AENTER__), - AExit(T___AEXIT__), - - AIter(T___AITER__, AM_AITER), - ANext(T___ANEXT__, AM_ANEXT), - - New(T___NEW__, NO_BUILTIN_DESCRIPTORS), - Init(T___INIT__, NO_BUILTIN_DESCRIPTORS), - SetName(T___SET_NAME__, NO_BUILTIN_DESCRIPTORS), - InstanceCheck(T___INSTANCECHECK__), - Subclasscheck(T___SUBCLASSCHECK__), - Call(T___CALL__, NO_BUILTIN_DESCRIPTORS), - - Exit(T___EXIT__), - Enter(T___ENTER__), - - LengthHint(T___LENGTH_HINT__), - Contains(T___CONTAINS__, SQ_CONTAINS), - Hash(T___HASH__), - Str(T___STR__), - Repr(T___REPR__), - // Note: __format__ does not seem to be actual slot in CPython, but it is looked up frequently - Format(T___FORMAT__), - Missing(T___MISSING__), - - Eq(T___EQ__), - Ne(T___NE__), - Lt(T___LT__), - Le(T___LE__), - Gt(T___GT__), - Ge(T___GE__), - - Pow(T___POW__, NB_POWER), - RPow(T___RPOW__, NB_POWER), - Round(T___ROUND__), - - IAdd(T___IADD__, NB_INPLACE_ADD), - IMul(T___IMUL__, NB_INPLACE_MULTIPLY), - - Reversed(T___REVERSED__), - Bytes(T___BYTES__); - - static class Flags { - static final boolean NO_BUILTIN_DESCRIPTORS = false; - } - - public static final SpecialMethodSlot[] VALUES = values(); - - private final TruffleString name; - @CompilationFinal private SpecialMethodSlot reverse; - /** - * Indicates if given slot may or must not store context independent (AST cacheable) - * {@link BuiltinMethodDescriptor} objects. - * - * Values of some slots are always or mostly passed to call node variants that can handle - * {@link BuiltinMethodDescriptor}. This does not hold most notably for slots that are passed to - * {@link com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode}, like - * {@code __new__}. For those we do not allow storing the {@link BuiltinMethodDescriptor} in the - * slot, so that lookup using that slot always resolves to context dependent runtime object, - * such as {@link PBuiltinFunction}. - * - * An alternative would be to update the whole calling machinery ({@code InvokeNode}, - * {@code GetSignature}, ...) to handle {@link BuiltinMethodDescriptor} and extend - * {@link BuiltinMethodDescriptor} to contain all the information that is necessary for this - * (GR-32148). - */ - private final boolean allowsBuiltinDescriptors; - private final long methodsFlag; - - SpecialMethodSlot(TruffleString name, long methodsFlag, boolean allowsBuiltinDescriptors) { - this.name = name; - this.allowsBuiltinDescriptors = allowsBuiltinDescriptors; - this.methodsFlag = methodsFlag; - } - - SpecialMethodSlot(TruffleString name, boolean allowsBuiltinDescriptors) { - this(name, 0, allowsBuiltinDescriptors); - } - - SpecialMethodSlot(TruffleString name, long methodsFlag) { - this(name, methodsFlag, true); - } - - SpecialMethodSlot(TruffleString name) { - this(name, 0, true); - } - - static { - Pow.reverse = RPow; - assert checkFind(); - assert checkReverseSlots(); - } - - public TruffleString getName() { - return name; - } - - public SpecialMethodSlot getReverse() { - return reverse; - } - - public long getMethodsFlag() { - return methodsFlag; - } - - public Object getValue(PythonManagedClass klass) { - assert klass.specialMethodSlots != null; - return klass.specialMethodSlots[ordinal()]; - } - - @Idempotent - public Object getValue(PythonBuiltinClassType klassType) { - // should not be called during initialization - return klassType.getSpecialMethodSlots()[ordinal()]; - } - - private void setValue(PythonManagedClass klass, Object value, PythonContext context) { - // For builtin classes, we should see these updates only during initialization - assert !context.isInitialized() || !(klass instanceof PythonBuiltinClass) || - ((PythonBuiltinClass) klass).getType().getSpecialMethodSlots() == null : String.format("%s.%s = %s", klass, getName(), value); - klass.specialMethodSlots[ordinal()] = asSlotValue(this, value, context.getLanguage()); - if (klass instanceof PythonClass) { - ((PythonClass) klass).invalidateSlotsFinalAssumption(); - } - } - - // -------------------------------------------------- - // Initialization of the builtin types/classes: - - /** - * Initialized builtin classes and types right after they were initialized and populated with - * builtin methods, i.e., before calling the Python initialization part. - */ - public static void initializeBuiltinsSpecialMethodSlots(Python3Core core) { - // Initialize the builtin classes (once per context) - for (PythonBuiltinClassType type : PythonBuiltinClassType.VALUES) { - initializeBuiltinClassSpecialMethodSlots(core, core.lookupType(type)); - } - // Initialize the builtin types (once per VM) - initializeBuiltinTypeSlots(core); - } - - private static void initializeBuiltinClassSpecialMethodSlots(Python3Core core, PythonBuiltinClass klass) { - CompilerAsserts.neverPartOfCompilation(); - if (klass.specialMethodSlots != null) { - // Already initialized - return; - } - - // First initialize the base class' slots - PythonBuiltinClassType klassType = klass.getType(); - if (klassType.getBase() != null) { - PythonBuiltinClass base = core.lookupType(klassType.getBase()); - initializeBuiltinClassSpecialMethodSlots(core, base); - Object[] baseSlots = base.specialMethodSlots; - klass.specialMethodSlots = Arrays.copyOf(baseSlots, baseSlots.length); - } else { - Object[] slots = new Object[VALUES.length]; - Arrays.fill(slots, PNone.NO_VALUE); - klass.specialMethodSlots = slots; - } - - ReadAttributeFromObjectNode readNode = ReadAttributeFromObjectNode.getUncachedForceType(); - for (SpecialMethodSlot slot : VALUES) { - Object value = readNode.execute(klass, slot.getName()); - if (value != PNone.NO_VALUE) { - slot.setValue(klass, value, core.getContext()); - } - } - } - - private static final Object builtinSlotsInitializationLock = new Object(); - private static volatile boolean builtinSlotsInitialized; - - public static boolean areBuiltinSlotsInitialized() { - return builtinSlotsInitialized; - } - - /** - * Initialized builtin type according to its respective builtin class. Only context independent - * values are pushed from the class to the type, because types are shared across contexts. This - * initialization should run only once per VM and this method takes care of that. - */ - private static void initializeBuiltinTypeSlots(Python3Core core) { - synchronized (builtinSlotsInitializationLock) { - if (builtinSlotsInitialized) { - return; - } - initializeBuiltinTypeSlotsImpl(core); - builtinSlotsInitialized = true; - } - } - - private static void initializeBuiltinTypeSlotsImpl(Python3Core core) { - for (PythonBuiltinClassType type : PythonBuiltinClassType.VALUES) { - Object[] typeSlots = new Object[VALUES.length]; - PythonBuiltinClass klass = core.lookupType(type); - for (SpecialMethodSlot slot : VALUES) { - if (type.redefinesSlot(slot)) { - continue; - } - Object value = slot.getValue(klass); - if (value instanceof PBuiltinFunction && slot.allowsBuiltinDescriptors) { - BuiltinMethodDescriptor info = BuiltinMethodDescriptor.get((PBuiltinFunction) value); - if (info != null) { - typeSlots[slot.ordinal()] = info; - } - } else if ((value instanceof BuiltinMethodDescriptor && slot.allowsBuiltinDescriptors) || PythonLanguage.canCache(value)) { - typeSlots[slot.ordinal()] = value; - } - } - type.setSpecialMethodSlots(typeSlots); - } - } - - // -------------------------------------------------- - // Initialization and updates of the user classes: - - @TruffleBoundary - public static void reinitializeSpecialMethodSlots(PythonManagedClass klass, PythonLanguage language) { - reinitializeSpecialMethodSlots((Object) klass, language); - } - - @TruffleBoundary - public static void reinitializeSpecialMethodSlots(PythonNativeClass klass, PythonLanguage language) { - reinitializeSpecialMethodSlots((Object) klass, language); - } - - private static void reinitializeSpecialMethodSlots(Object klass, PythonLanguage language) { - PythonAbstractClass[] subClasses; - if (klass instanceof PythonManagedClass managedClass) { - // specialMethodSlots can be null if the type is just being initialized, for example, - // when the initialization calls the "mro" method, which may execute arbitrary code - // including setting its __bases__ to something. - // TODO: LookupAttributeInMRONode and other places rely on specialMethodSlots being - // always initialized, can it happen that some code invoked during type initialization - // is going to lookup something in that type's MRO? - if (managedClass.specialMethodSlots != null) { - managedClass.specialMethodSlots = null; - initializeSpecialMethodSlots(managedClass, GetMroStorageNode.executeUncached(managedClass), language); - } - subClasses = GetSubclassesAsArrayNode.executeUncached(managedClass); - } else if (klass instanceof PythonNativeClass clazz) { - subClasses = GetSubclassesAsArrayNode.executeUncached(clazz); - } else { - throw new AssertionError(Objects.toString(klass)); - } - for (PythonAbstractClass subClass : subClasses) { - reinitializeSpecialMethodSlots(subClass, language); - } - } - - public static void initializeSpecialMethodSlots(PythonManagedClass klass, MroSequenceStorage mro, PythonLanguage language) { - klass.specialMethodSlots = initializeSpecialMethodsSlots(klass, mro, language); - } - - @TruffleBoundary - private static Object[] initializeSpecialMethodsSlots(PythonManagedClass klass, MroSequenceStorage mro, PythonLanguage language) { - // Note: the classes in MRO may not have their special slots initialized, which is - // pathological case that can happen if MRO is fiddled with during MRO computation - - // Fast-path: If MRO(klass) == (A, B, C, ...) and A == klass and MRO(B) == (B, C, ...), then - // we can just "extend" the slots of B with the new overrides in A. This fast-path seem to - // handle large majority of the situations - if (mro.length() >= 2 && klass.getBaseClasses().length <= 1) { - PythonAbstractClass firstType = mro.getPythonClassItemNormalized(0); - PythonAbstractClass secondType = mro.getPythonClassItemNormalized(1); - if (firstType == klass && PythonManagedClass.isInstance(secondType)) { - PythonManagedClass managedBase = PythonManagedClass.cast(secondType); - if (managedBase.specialMethodSlots != null) { - if (isMroSubtype(mro, managedBase)) { - Object[] result = PythonUtils.arrayCopyOf(managedBase.specialMethodSlots, managedBase.specialMethodSlots.length); - setSlotsFromManaged(result, klass, language); - fixupNewSlot(result, klass); - setMethodsFlags(result, klass); - return result; - } - } - } - } - - // Deal with this pathological case - if (mro.length() == 0) { - Object[] slots = new Object[VALUES.length]; - Arrays.fill(slots, PNone.NO_VALUE); - return slots; - } - - // Check the last klass in MRO and use copy its slots for the beginning (if available) - // In most cases this will be `object`, which contains most of the slots - Object[] slots = null; - PythonAbstractClass lastType = mro.getPythonClassItemNormalized(mro.length() - 1); - boolean slotsInitializedFromLast = false; - if (PythonManagedClass.isInstance(lastType)) { - PythonManagedClass lastClass = PythonManagedClass.cast(lastType); - if (lastClass.specialMethodSlots != null) { - slots = PythonUtils.arrayCopyOf(lastClass.specialMethodSlots, lastClass.specialMethodSlots.length); - slotsInitializedFromLast = true; - } - } - if (!slotsInitializedFromLast) { - slots = new Object[VALUES.length]; - Arrays.fill(slots, PNone.NO_VALUE); - } - - // Traverse MRO in reverse order overriding the initial slots values if we find new override - int skip = slotsInitializedFromLast ? 1 : 0; - for (int i = mro.length() - skip - 1; i >= 0; i--) { - PythonAbstractClass base = mro.getPythonClassItemNormalized(i); - if (PythonManagedClass.isInstance(base)) { - setSlotsFromManaged(slots, PythonManagedClass.cast(base), language); - } else { - setSlotsFromGeneric(slots, base, language); - } - } - fixupNewSlot(slots, klass); - setMethodsFlags(slots, klass); - return slots; - } - - private static boolean isMroSubtype(MroSequenceStorage superTypeMro, PythonManagedClass subType) { - if (subType instanceof PythonBuiltinClass && ((PythonBuiltinClass) subType).getType() == PythonBuiltinClassType.PythonObject) { - // object is subclass of everything - return true; - } - MroSequenceStorage subTypeMro = GetMroStorageNode.executeUncached(subType); - boolean isMroSubtype = subTypeMro.length() == superTypeMro.length() - 1; - if (isMroSubtype) { - for (int i = 0; i < subTypeMro.length(); i++) { - if (superTypeMro.getPythonClassItemNormalized(i + 1) != subTypeMro.getPythonClassItemNormalized(i)) { - isMroSubtype = false; - break; - } - } - } - return isMroSubtype; - } - - private static void setMethodsFlag(PythonManagedClass klass, long flag, PythonContext context) { - if (flag == 0) { - return; - } - - long isHeaptype = context.isCoreInitialized() ? MethodsFlags.SLOT1BINFULL : 0L; - klass.setMethodsFlags(flag | isHeaptype); - } - - private static void setMethodsFlag(PythonNativeClass cls, long flag, PythonContext context) { - if (flag == 0) { - return; - } - - long flags = GetMethodsFlagsNodeGen.getUncached().execute(null, cls); - if ((flags & flag) == 0) { - // mq: We should put a wrapped function in the native slot. - CyclicAssumption assumption = context.getNativeClassStableAssumption(cls, false); - if (assumption != null && assumption.getAssumption().isValid()) { - assumption.invalidate("methods flags have changed after class creation"); - } - if (cls instanceof PythonAbstractNativeObject nclass) { - HiddenAttr.WriteNode.executeUncached(nclass, METHODS_FLAGS, flags | flag); - } - } - } - - private static void setMethodsFlags(Object[] slots, PythonManagedClass klass) { - long methodsFlags = 0; - for (SpecialMethodSlot slot : VALUES) { - if (slot.getMethodsFlag() > 0 && slots[slot.ordinal()] != PNone.NO_VALUE) { - methodsFlags |= slot.getMethodsFlag(); - } - } - - if (klass.getInitialPythonClass() instanceof PythonBuiltinClassType builtinClass) { - methodsFlags |= builtinClass.getMethodsFlags(); - } - - setMethodsFlag(klass, methodsFlags, PythonContext.get(null)); - } - - /** - * CPython has a bug in their {@code tp_new} slot inheritance. Packages, notably pandas, rely on - * the bug being present, so we have to try to replicate the same behavior. - *

      - * CPython first inherits {@code tp_new} from the dominant base ({@code tp_base}) and creates a - * {@code __new__} special method for it. Later, they update all slots to match what's in the - * object's special methods, which are looked up in MRO. In case of multiple inheritance, the - * MRO-inherited {@code __new__} may be different from the {@code tp_base}-inherited one. - * Normally, one would expect that the MRO-inherited one wins, as is the case for all other - * slots. See the code in {@code update_one_slot}, it does this: - * - *

      -        ...
      -        void **ptr = slotptr(type, offset);
      -        ...
      -        descr = find_name_in_mro(type, p->name_strobj, &error);
      -        ...
      -        else if (Py_IS_TYPE(descr, &PyCFunction_Type) &&
      -                 PyCFunction_GET_FUNCTION(descr) ==
      -                 (PyCFunction)(void(*)(void))tp_new_wrapper &&
      -                 ptr == (void**)&type->tp_new)
      -        {
      -            specific = (void *)type->tp_new;
      -        }
      -     * 
      - * - * Apparently, they wanted to make an optimization that avoids using the wrapper if the wrapper - * was for the same {@code tp_new} as was inherited from {@code tp_base}. But they only check - * that it's a wrapper, but they forgot to check that it's for the same type. The wrapper - * function carries the type in its self, so they should have also checked that - * {@code PyCFunction_GET_SELF(descr) == type}. So in summary, {@code tp_new} is inherited - * through {@code tp_base} when the one in MRO is builtin/native, and it's inherited through MRO - * otherwise. - *

      - * We approximate the check for the wrapper by checking that it's a builtin method, and it's - * named {@code __new__}. - */ - private static void fixupNewSlot(Object[] slots, Object type) { - Object mroInheritedNew = slots[New.ordinal()]; - if (mroInheritedNew instanceof PBuiltinMethod builtinMethod) { - mroInheritedNew = builtinMethod.getBuiltinFunction(); - } - if (mroInheritedNew instanceof PBuiltinFunction builtinFunction && builtinFunction.getName().equalsUncached(New.name, TS_ENCODING)) { - Object tpBaseInheritedNew = ReadAttributeFromObjectNode.getUncachedForceType().execute(type, New.name); - if (tpBaseInheritedNew == PNone.NO_VALUE) { - Object base = GetBaseClassNode.executeUncached(type); - tpBaseInheritedNew = LookupCallableSlotInMRONode.getUncached(New).execute(base); - } - slots[New.ordinal()] = tpBaseInheritedNew; - } - } - - private static void setSlotsFromManaged(Object[] slots, PythonManagedClass source, PythonLanguage language) { - PDict dict = GetDictIfExistsNode.getUncached().execute(source); - if (dict == null) { - for (SpecialMethodSlot slot : VALUES) { - final Object value = ReadAttributeFromPythonObjectNode.executeUncached(source, slot.getName(), PNone.NO_VALUE); - if (value != PNone.NO_VALUE) { - slots[slot.ordinal()] = asSlotValue(slot, value, language); - } - } - } else { - HashingStorage storage = dict.getDictStorage(); - for (SpecialMethodSlot slot : VALUES) { - final Object value = HashingStorageGetItem.executeUncached(storage, slot.getName()); - if (value != null) { - slots[slot.ordinal()] = asSlotValue(slot, value, language); - } - } - } - } - - private static void setSlotsFromGeneric(Object[] slots, PythonAbstractClass base, PythonLanguage language) { - ReadAttributeFromObjectNode readAttNode = ReadAttributeFromObjectNode.getUncachedForceType(); - for (SpecialMethodSlot slot : VALUES) { - Object value = readAttNode.execute(base, slot.getName()); - if (value != PNone.NO_VALUE) { - slots[slot.ordinal()] = asSlotValue(slot, value, language); - } - } - } - - @TruffleBoundary - public static void fixupSpecialMethodSlot(PythonNativeClass klass, SpecialMethodSlot slot, Object value) { - Object newValue = value; - if (value == PNone.NO_VALUE) { - // We are removing the value: find the new value for the class that is being updated and - // proceed with that - newValue = LookupAttributeInMRONode.lookupSlowPath(klass, slot.getName()); - } - fixupSpecialMethodInSubClasses(GetSubclassesAsArrayNode.executeUncached(klass), slot, newValue, PythonContext.get(null)); - } - - @TruffleBoundary - public static void fixupSpecialMethodSlot(PythonManagedClass klass, SpecialMethodSlot slot, Object value) { - if (klass.specialMethodSlots == null) { - // This can happen during type initialization, we'll initialize the slots when the - // whole initialization is done. We do the assert only if we maintain the stack of types - // currently being initialized - assert initializingTypes == null || initializingTypes.contains(klass); - return; - } - - Object oldValue = slot.getValue(klass); - if (value == oldValue) { - return; - } - - Object newValue = value; - if (value == PNone.NO_VALUE) { - // We are removing the value: find the new value for the class that is being updated and - // proceed with that - newValue = LookupAttributeInMRONode.lookupSlowPath(klass, slot.getName()); - } - - PythonContext context = PythonContext.get(null); - slot.setValue(klass, newValue, context); - if (oldValue == PNone.NO_VALUE) { - setMethodsFlag(klass, slot.getMethodsFlag(), context); - } - fixupSpecialMethodInSubClasses(GetSubclassesAsArrayNode.executeUncached(klass), slot, value, context); - } - - // Note: originalValue == null means originalValue is not available - private static void fixupSpecialMethodSlotInternal(PythonManagedClass klass, SpecialMethodSlot slot, Object newValue, PythonContext context) { - Object currentOldValue = slot.getValue(klass); - // Even if this slot was occupied by the same value as in the base, it does not mean that - // the value was here because it was inherited from the base class where we now overridden - // that slot. To stay on the safe side, we consult the MRO here. - Object currentNewValue = LookupAttributeInMRONode.lookupSlowPath(klass, slot.getName()); - if (newValue != PNone.NO_VALUE) { - // If the newly written value is not NO_VALUE, then should either override the slot with - // the new value or leave it unchanged if it inherited the value from some other class - assert currentNewValue != PNone.NO_VALUE; - assert asSlotValue(slot, currentNewValue, context.getLanguage()) == currentOldValue || currentNewValue == newValue; - } - // Else if the newly written value was NO_VALUE, then we either remove the slot or we pull - // its value from some other class in the MRO - if (currentOldValue != currentNewValue) { - // Something actually changed, fixup subclasses... - slot.setValue(klass, currentNewValue, context); - fixupSpecialMethodInSubClasses(GetSubclassesAsArrayNode.executeUncached(klass), slot, newValue, context); - } - } - - private static void fixupSpecialMethodSlot(Object klass, SpecialMethodSlot slot, Object newValue, PythonContext context) { - if (klass instanceof PythonManagedClass clazz) { - setMethodsFlag(clazz, slot.getMethodsFlag(), context); - fixupSpecialMethodSlotInternal((PythonManagedClass) klass, slot, newValue, context); - } else if (klass instanceof PythonNativeClass clazz) { - setMethodsFlag(clazz, slot.getMethodsFlag(), context); - fixupSpecialMethodInSubClasses(GetSubclassesAsArrayNode.executeUncached(clazz), slot, newValue, context); - } else { - throw new AssertionError(Objects.toString(klass)); - } - } - - private static void fixupSpecialMethodInSubClasses(PythonAbstractClass[] subClasses, SpecialMethodSlot slot, Object newValue, PythonContext context) { - for (PythonAbstractClass subClass : subClasses) { - fixupSpecialMethodSlot(subClass, slot, newValue, context); - } - } - - private static Object asSlotValue(SpecialMethodSlot slot, Object value, PythonLanguage language) { - if (value instanceof PBuiltinFunction && slot.allowsBuiltinDescriptors) { - PBuiltinFunction builtinFun = (PBuiltinFunction) value; - BuiltinMethodDescriptor info = BuiltinMethodDescriptor.get(builtinFun); - if (info != null) { - if (builtinFun.getDescriptor() == null) { - // Note: number of all builtins >> number of builtins used in slots, so it is - // better to do this lazily - language.registerBuiltinDescriptorCallTarget(info, builtinFun.getCallTarget()); - builtinFun.setDescriptor(info); - } - return info; - } - } - return value; - } - - // -------------------------------------------------- - // Lookup of the slots: - - /** - * Fast check that can rule out that given name is a special slot. - */ - public static boolean canBeSpecial(TruffleString name, TruffleString.CodePointLengthNode codePointLengthNode, TruffleString.CodePointAtIndexNode codePointAtIndexNode) { - int len = codePointLengthNode.execute(name, TS_ENCODING); - return len > 5 && codePointAtIndexNode.execute(name, len - 2, TS_ENCODING) == '_' && codePointAtIndexNode.execute(name, len - 1, TS_ENCODING) == '_' && - codePointAtIndexNode.execute(name, 1, TS_ENCODING) == '_' && codePointAtIndexNode.execute(name, 0, TS_ENCODING) == '_'; - } - - @TruffleBoundary - public static SpecialMethodSlot findSpecialSlotUncached(TruffleString name) { - return findSpecialSlot(name, TruffleString.CodePointLengthNode.getUncached(), TruffleString.CodePointAtIndexNode.getUncached(), TruffleString.EqualNode.getUncached()); - } - - public static SpecialMethodSlot findSpecialSlot(TruffleString name, TruffleString.CodePointLengthNode codePointLengthNode, TruffleString.CodePointAtIndexNode codePointAtIndexNode, - TruffleString.EqualNode eqNode) { - if (!canBeSpecial(name, codePointLengthNode, codePointAtIndexNode)) { - return null; - } - int x = codePointAtIndexNode.execute(name, 2, TS_ENCODING) * 26 + codePointAtIndexNode.execute(name, 3, TS_ENCODING); - switch (x) { - case 'g' * 26 + 'e': // ge - if (eqNode.execute(name, T___GE__, TS_ENCODING)) { - return Ge; - } - break; - case 's' * 26 + 'e': // se - if (eqNode.execute(name, T___SET_NAME__, TS_ENCODING)) { - return SetName; - } - break; - case 'd' * 26 + 'e': // de - if (eqNode.execute(name, T___DELATTR__, TS_ENCODING)) { - return DelAttr; - } - break; - case 'd' * 26 + 'i': // di - if (eqNode.execute(name, T___DICT__, TS_ENCODING)) { - return Dict; - } - break; - case 'i' * 26 + 't': // it - if (eqNode.execute(name, T___ITER__, TS_ENCODING)) { - return Iter; - } - break; - case 'n' * 26 + 'e': // ne - if (eqNode.execute(name, T___NEXT__, TS_ENCODING)) { - return Next; - } - if (eqNode.execute(name, T___NEW__, TS_ENCODING)) { - return New; - } - if (eqNode.execute(name, T___NE__, TS_ENCODING)) { - return Ne; - } - break; - case 'i' * 26 + 'n': // in - if (eqNode.execute(name, T___INIT__, TS_ENCODING)) { - return Init; - } - if (eqNode.execute(name, T___INSTANCECHECK__, TS_ENCODING)) { - return InstanceCheck; - } - break; - case 's' * 26 + 'u': // su - if (eqNode.execute(name, T___SUBCLASSCHECK__, TS_ENCODING)) { - return Subclasscheck; - } - break; - case 'c' * 26 + 'a': // ca - if (eqNode.execute(name, T___CALL__, TS_ENCODING)) { - return Call; - } - break; - case 'e' * 26 + 'x': // ex - if (eqNode.execute(name, T___EXIT__, TS_ENCODING)) { - return Exit; - } - break; - case 'e' * 26 + 'n': // en - if (eqNode.execute(name, T___ENTER__, TS_ENCODING)) { - return Enter; - } - break; - case 'l' * 26 + 'e': // le - if (eqNode.execute(name, T___LENGTH_HINT__, TS_ENCODING)) { - return LengthHint; - } - if (eqNode.execute(name, T___LE__, TS_ENCODING)) { - return Le; - } - break; - case 'c' * 26 + 'o': // co - if (eqNode.execute(name, T___CONTAINS__, TS_ENCODING)) { - return Contains; - } - break; - case 'h' * 26 + 'a': // ha - if (eqNode.execute(name, T___HASH__, TS_ENCODING)) { - return Hash; - } - break; - case 's' * 26 + 't': // st - if (eqNode.execute(name, T___STR__, TS_ENCODING)) { - return Str; - } - break; - case 'r' * 26 + 'e': // re - if (eqNode.execute(name, T___REPR__, TS_ENCODING)) { - return Repr; - } - if (eqNode.execute(name, T___REVERSED__, TS_ENCODING)) { - return Reversed; - } - break; - case 'f' * 26 + 'o': // fo - if (eqNode.execute(name, T___FORMAT__, TS_ENCODING)) { - return Format; - } - break; - case 'm' * 26 + 'i': // mi - if (eqNode.execute(name, T___MISSING__, TS_ENCODING)) { - return Missing; - } - break; - case 'e' * 26 + 'q': // eq - if (eqNode.execute(name, T___EQ__, TS_ENCODING)) { - return Eq; - } - break; - case 'l' * 26 + 't': // lt - if (eqNode.execute(name, T___LT__, TS_ENCODING)) { - return Lt; - } - break; - case 'g' * 26 + 't': // gt - if (eqNode.execute(name, T___GT__, TS_ENCODING)) { - return Gt; - } - break; - case 'a' * 26 + 'n': // an - if (eqNode.execute(name, T___ANEXT__, TS_ENCODING)) { - return ANext; - } - break; - case 'r' * 26 + 'o': // ro - if (eqNode.execute(name, T___ROUND__, TS_ENCODING)) { - return Round; - } - break; - case 'p' * 26 + 'o': // po - if (eqNode.execute(name, T___POW__, TS_ENCODING)) { - return Pow; - } - break; - case 'r' * 26 + 'p': // rp - if (eqNode.execute(name, T___RPOW__, TS_ENCODING)) { - return RPow; - } - break; - case 'i' * 26 + 'a': // ia - if (eqNode.execute(name, T___IADD__, TS_ENCODING)) { - return IAdd; - } - break; - case 'i' * 26 + 'm': // im - if (eqNode.execute(name, T___IMUL__, TS_ENCODING)) { - return IMul; - } - break; - case 'b' * 26 + 'y': // by - if (eqNode.execute(name, T___BYTES__, TS_ENCODING)) { - return Bytes; - } - break; - case 'a' * 26 + 'w': // aw - if (eqNode.execute(name, T___AWAIT__, TS_ENCODING)) { - return Await; - } - break; - case 'a' * 26 + 'e': // ae - if (eqNode.execute(name, T___AENTER__, TS_ENCODING)) { - return AEnter; - } - if (eqNode.execute(name, T___AEXIT__, TS_ENCODING)) { - return AExit; - } - break; - case 'a' * 26 + 'i': // ai - if (eqNode.execute(name, T___AITER__, TS_ENCODING)) { - return AIter; - } - break; - } - return null; - } - - private static boolean checkReverseSlots() { - TruffleString prefix = tsLiteral("__"); - TruffleString rPrefix = tsLiteral("__r"); - for (SpecialMethodSlot slot : VALUES) { - TruffleString slotName = slot.getName(); - if (rPrefix.regionEqualsUncached(0, slotName, 0, 3, TS_ENCODING)) { - int slotNameLen = slotName.codePointLengthUncached(TS_ENCODING); - TruffleString slotNamePart = slotName.substringUncached(3, slotNameLen - 3, TS_ENCODING, true); - SpecialMethodSlot rslot = findSpecialSlotUncached(prefix.concatUncached(slotNamePart, TS_ENCODING, false)); - if (rslot != null && rslot.reverse != slot) { - assert false : slotName; - return false; - } - } - } - return true; - } - - private static boolean checkFind() { - for (SpecialMethodSlot slot : VALUES) { - if (findSpecialSlotUncached(slot.getName()) != slot) { - assert false : slot; - return false; - } - } - return findSpecialSlotUncached(tsLiteral("__bogus__")) == null; - } - - // -------------------------------------------------- - // Methods for validation, some used in asserts, some unused but left here to aid local - // debugging - - /** - * Checks that there were no builtins' slots overridden except those explicitly marked so by - * {@link PythonBuiltinClassType#redefinesSlot}. - */ - public static boolean checkSlotOverrides(Python3Core core) { - assert builtinSlotsInitialized; - HashSet mismatches = new HashSet<>(); - for (PythonBuiltinClassType type : PythonBuiltinClassType.VALUES) { - PythonBuiltinClass klass = core.lookupType(type); - for (SpecialMethodSlot slot : VALUES) { - Object typeValue = slot.getValue(type); - if (typeValue != null) { - Object klassValue = slot.getValue(klass); - if (klassValue.equals(typeValue)) { - // values are same: OK - continue; - } - if (typeValue instanceof BuiltinMethodDescriptor && klassValue instanceof PBuiltinFunction && - ((BuiltinMethodDescriptor) typeValue).isDescriptorOf((PBuiltinFunction) klassValue)) { - // BuiltinMethodDescriptor and matching PBuiltinFunction: OK - continue; - } - mismatches.add(type.getName().toJavaStringUncached() + "." + slot.getName().toJavaStringUncached()); - } - } - } - // If this assertion fails, update the list of the redefinedSlots for the offending types - // See the static block in PythonBuiltinClassType - assert mismatches.size() == 0 : String.join(", ", mismatches); - return true; - } - - private static final ArrayDeque initializingTypes; // types that are being initialized - - static { - // Uncomment to start using validateSlots - // initializingTypes = new ArrayDeque<>(); - initializingTypes = null; - } - - public static boolean pushInitializedTypePlaceholder() { - if (initializingTypes != null) { - initializingTypes.push(42); - } - return true; - } - - public static boolean replaceInitializedTypeTop(Object type) { - if (initializingTypes != null) { - assert (Integer) initializingTypes.pop() == 42; - initializingTypes.push(type); - } - return true; - } - - public static boolean popInitializedType() { - if (initializingTypes != null) { - initializingTypes.pop(); - } - return true; - } - - // Note: this only works in single context, single threaded case! - // Uncomment the initialization of initializingTypes in the static block - @SuppressWarnings("unused") - public static boolean validateSlots(Object klassIn) { - if (initializingTypes.contains(klassIn)) { - return true; - } - ReadAttributeFromPythonObjectNode uncachedReadAttrNode = ReadAttributeFromPythonObjectNode.getUncached(); - final Python3Core core = PythonContext.get(uncachedReadAttrNode); - Object klass = klassIn; - if (klass instanceof PythonBuiltinClassType) { - PythonBuiltinClassType type = (PythonBuiltinClassType) klass; - klass = core.lookupType(type); - if (initializingTypes.contains(klass)) { - return true; - } - if (type.getSpecialMethodSlots() == null) { - return true; - } - for (SpecialMethodSlot slot : VALUES) { - Object actual = LookupAttributeInMRONode.findAttr(core, type, slot.getName(), uncachedReadAttrNode); - Object expected = slot.getValue(type); - if (expected instanceof BuiltinMethodDescriptor) { - assert actual instanceof PBuiltinFunction; - assert ((BuiltinMethodDescriptor) expected).isDescriptorOf((PBuiltinFunction) actual); - } else if (expected != null) { - assert PythonLanguage.canCache(expected); - assert actual == expected; - } - } - klass = core.lookupType(type); - } - if (klass instanceof PythonManagedClass) { - PythonManagedClass managed = (PythonManagedClass) klass; - for (SpecialMethodSlot slot : VALUES) { - Object actual = LookupAttributeInMRONode.lookupSlowPath(managed, slot.getName()); - Object expected = slot.getValue(managed); - if (expected instanceof NodeFactory) { - assert actual instanceof PBuiltinFunction; - assert ((PBuiltinFunction) actual).getBuiltinNodeFactory() == expected; - } else { - assert actual == expected; - } - } - } - return true; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TpSlots.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TpSlots.java index 914fbec3ce..2350b6a6dd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TpSlots.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TpSlots.java @@ -42,38 +42,70 @@ import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ABS__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ADD__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AITER__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AND__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ANEXT__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AWAIT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___BOOL__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___CALL__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___CONTAINS__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___DELATTR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___DELETE__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___DELITEM__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___DIVMOD__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___EQ__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___FLOAT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___FLOORDIV__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETATTRIBUTE__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETATTR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETITEM__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GET__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GE__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GT__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IADD__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IAND__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IFLOORDIV__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ILSHIFT__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IMATMUL__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IMOD__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IMUL__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INDEX__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INIT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INVERT__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IOR__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IPOW__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IRSHIFT__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ISUB__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ITER__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ITRUEDIV__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IXOR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LEN__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LE__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LSHIFT__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MATMUL__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MOD__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MUL__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEG__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEW__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEXT__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NE__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___OR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___POS__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___POW__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RADD__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RAND__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RDIVMOD__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___REPR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RFLOORDIV__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RLSHIFT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RMATMUL__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RMOD__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RMUL__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ROR__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RPOW__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RRSHIFT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RSHIFT__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RSUB__; @@ -82,6 +114,7 @@ import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SETATTR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SETITEM__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SET__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___STR__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SUB__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___TRUEDIV__; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___XOR__; @@ -99,71 +132,89 @@ import java.util.Set; import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.BoundBuiltinCallable; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; +import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext; import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper; +import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol; import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.BinaryOpSlotFuncWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.BinarySlotFuncWrapper; +import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.CallWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.DescrGetFunctionWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.DescrSetFunctionWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.GetAttrWrapper; +import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.HashfuncWrapper; +import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.InitWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.InquiryWrapper; +import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.IterNextWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.LenfuncWrapper; +import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.NbInPlacePowerWrapper; +import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.NbPowerWrapper; +import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.NewWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.ObjobjargWrapper; +import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.RichcmpFunctionWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.SetattrWrapper; +import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.SqContainsWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.SsizeargfuncSlotWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.SsizeobjargprocWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.TpSlotWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.UnaryFuncWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.PythonClassNativeWrapper; import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.EnsureExecutableNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlotWrapper; -import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodes; import com.oracle.graal.python.builtins.objects.cext.structs.CFields; import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess.ReadPointerNode; import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess.WritePointerNode; +import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem; +import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; +import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.builtins.objects.type.TpSlotsFactory.GetObjectSlotsNodeGen; import com.oracle.graal.python.builtins.objects.type.TpSlotsFactory.GetTpSlotsNodeGen; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetSubclassesAsArrayNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotBuiltin; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotCExtNative; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotHPyNative; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotManaged; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotNative; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPython; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPythonSingle; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.TpSlotBinaryFuncBuiltin; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.TpSlotSqConcat; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.TpSlotBinaryIOpBuiltin; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.TpSlotBinaryOpBuiltin; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.TpSlotBinaryOpPython; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.TpSlotReversiblePython; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.TpSlotDescrGetBuiltin; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrSet.TpSlotDescrSetBuiltin; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrSet.TpSlotDescrSetPython; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.TpSlotGetAttrBuiltin; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.TpSlotGetAttrPython; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.TpSlotHashBuiltin; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotInquiry.TpSlotInquiryBuiltin; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpSlotIterNextBuiltin; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.TpSlotLenBuiltin; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotMpAssSubscript.TpSlotMpAssSubscriptBuiltin; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotMpAssSubscript.TpSlotMpAssSubscriptPython; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotNbPower.TpSlotNbPowerBuiltin; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.TpSlotRichCmpBuiltin; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.TpSlotRichCmpPython; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSetAttr.TpSlotSetAttrBuiltin; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSetAttr.TpSlotSetAttrPython; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.TpSlotSizeArgFunBuiltin; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqAssItem.TpSlotSqAssItemBuiltin; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqAssItem.TpSlotSqAssItemPython; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.TpSlotSqContainsBuiltin; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotUnaryFunc.TpSlotUnaryFuncBuiltin; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotVarargs.TpSlotNewBuiltin; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotVarargs.TpSlotVarargsBuiltin; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; -import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.sequence.storage.MroSequenceStorage; import com.oracle.graal.python.util.InlineWeakValueProfile; @@ -181,6 +232,7 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.object.DynamicObjectLibrary; import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.strings.TruffleString; @@ -193,7 +245,7 @@ *
        *     Builtins:
        *      - initialization of the slots: static ctor of {@link PythonBuiltinClassType}
      - *      - initialization of the wrappers: context initialization calls {@link TpSlots#addOperatorsToBuiltin(Map, Python3Core, PythonBuiltinClassType)}
      + *      - initialization of the wrappers: context initialization calls {@link #addOperatorsToBuiltin(Python3Core, PythonBuiltinClassType, PythonBuiltinClass)}
        *      - all the slots are static and shared per JVM, builtins do not allow to update attributes after ctx initialization
        *
        *     Native classes:
      @@ -202,7 +254,7 @@
        *              - eventually will be replaced with one upcall to managed implementation of CPython's add_operators
        *                  that will use the {@link #SLOTDEFS} definitions and unsafe to read the slots
        *          - type_ready_inherit: does the slot inheritance in native
      - *          - type_ready_graalpy_process_inherited_slots: up-calls PyTruffle_AddInheritedSlots to:
      + *          - after type_ready_inherit: up-calls PyTruffle_AddInheritedSlots to:
        *              - transfer the native slots to their managed mirror {@link TpSlots}
        *              - re-validate cached lookups in TpSlotPython, see comment in {@link #fromNative(PythonAbstractNativeObject, PythonContext)}
        *              - fixup getsets and members
      @@ -258,30 +310,63 @@ public record TpSlots(TpSlot nb_bool, //
                       TpSlot nb_true_divide, //
                       TpSlot nb_divmod, //
                       TpSlot nb_matrix_multiply, //
      +                TpSlot nb_power, //
      +                TpSlot nb_inplace_add, //
      +                TpSlot nb_inplace_subtract, //
      +                TpSlot nb_inplace_multiply, //
      +                TpSlot nb_inplace_remainder, //
      +                TpSlot nb_inplace_lshift, //
      +                TpSlot nb_inplace_rshift, //
      +                TpSlot nb_inplace_and, //
      +                TpSlot nb_inplace_xor, //
      +                TpSlot nb_inplace_or, //
      +                TpSlot nb_inplace_floor_divide, //
      +                TpSlot nb_inplace_true_divide, //
      +                TpSlot nb_inplace_matrix_multiply, //
      +                TpSlot nb_inplace_power, //
                       TpSlot sq_length, //
                       TpSlot sq_item, //
                       TpSlot sq_ass_item, //
                       TpSlot sq_concat, //
                       TpSlot sq_repeat, //
      +                TpSlot sq_inplace_concat, //
      +                TpSlot sq_inplace_repeat, //
      +                TpSlot sq_contains, //
                       TpSlot mp_length, //
                       TpSlot mp_subscript, //
                       TpSlot mp_ass_subscript, //
                       TpSlot combined_sq_mp_length, //
                       TpSlot combined_mp_sq_length, //
      +                TpSlot tp_richcmp, //
                       TpSlot tp_descr_get, //
                       TpSlot tp_descr_set, //
      +                TpSlot tp_hash, //
                       TpSlot tp_getattro, //
                       TpSlot tp_getattr, //
                       TpSlot combined_tp_getattro_getattr, //
                       TpSlot tp_setattro, //
                       TpSlot tp_setattr,
                       TpSlot combined_tp_setattro_setattr,
      +                TpSlot tp_iter, //
      +                TpSlot tp_iternext, //
      +                TpSlot tp_repr, //
      +                TpSlot tp_str, //
      +                TpSlot tp_init, //
      +                TpSlot tp_new, //
      +                TpSlot tp_call, //
      +                TpSlot am_await, //
      +                TpSlot am_aiter, //
      +                TpSlot am_anext, //
                       boolean has_as_number,
                       boolean has_as_sequence,
      -                boolean has_as_mapping) {
      +                boolean has_as_mapping,
      +                boolean has_as_async) {
       
           private static final TruffleLogger LOGGER = PythonLanguage.getLogger(TpSlot.class);
       
      +    // Force class initialization earlier
      +    private static final TpSlot NEXT_NOT_IMPLEMENTED = TpSlotIterNext.NEXT_NOT_IMPLEMENTED;
      +
           @FunctionalInterface
           private interface TpSlotGetter {
               TpSlot get(TpSlots slots);
      @@ -338,18 +423,36 @@ public TpSlot create(Object[] callables, TruffleString[] names, Object klass) {
           }
       
           public enum TpSlotGroup {
      -        AS_NUMBER(CFields.PyTypeObject__tp_as_number),
      -        AS_SEQUENCE(CFields.PyTypeObject__tp_as_sequence),
      -        AS_MAPPING(CFields.PyTypeObject__tp_as_mapping),
      -        NO_GROUP(null); // Must be last
      +        AS_NUMBER(TpSlots::has_as_number, CFields.PyTypeObject__tp_as_number),
      +        AS_SEQUENCE(TpSlots::has_as_sequence, CFields.PyTypeObject__tp_as_sequence),
      +        AS_MAPPING(TpSlots::has_as_mapping, CFields.PyTypeObject__tp_as_mapping),
      +        AS_ASYNC(TpSlots::has_as_async, CFields.PyTypeObject__tp_as_async),
      +        NO_GROUP(null, null); // Must be last
       
               public static final TpSlotGroup[] VALID_VALUES = Arrays.copyOf(values(), values().length - 1);
       
      +        private final GroupGetter getter;
               private final CFields cField;
       
      -        TpSlotGroup(CFields cField) {
      +        TpSlotGroup(GroupGetter getter, CFields cField) {
      +            this.getter = getter;
                   this.cField = cField;
               }
      +
      +        public boolean getValue(TpSlots slots) {
      +            assert this != NO_GROUP;
      +            return getter.get(slots);
      +        }
      +
      +        public boolean readFromNative(PythonAbstractNativeObject pythonClass) {
      +            Object ptr = ReadPointerNode.getUncached().readFromObj(pythonClass, cField);
      +            return !InteropLibrary.getUncached().isNull(ptr);
      +        }
      +    }
      +
      +    @FunctionalInterface
      +    interface GroupGetter {
      +        boolean get(TpSlots slot);
           }
       
           /**
      @@ -422,7 +525,7 @@ public enum TpSlotMeta {
                               UnaryFuncWrapper::new),
               NB_ADD(
                               TpSlots::nb_add,
      -                        TpSlotBinaryOpPython.class,
      +                        TpSlotReversiblePython.class,
                               TpSlotBinaryOpBuiltin.class,
                               TpSlotGroup.AS_NUMBER,
                               CFields.PyNumberMethods__nb_add,
      @@ -430,7 +533,7 @@ public enum TpSlotMeta {
                               BinaryOpSlotFuncWrapper::createAdd),
               NB_SUBTRACT(
                               TpSlots::nb_subtract,
      -                        TpSlotBinaryOpPython.class,
      +                        TpSlotReversiblePython.class,
                               TpSlotBinaryOpBuiltin.class,
                               TpSlotGroup.AS_NUMBER,
                               CFields.PyNumberMethods__nb_subtract,
      @@ -438,7 +541,7 @@ public enum TpSlotMeta {
                               BinaryOpSlotFuncWrapper::createSubtract),
               NB_MULTIPLY(
                               TpSlots::nb_multiply,
      -                        TpSlotBinaryOpPython.class,
      +                        TpSlotReversiblePython.class,
                               TpSlotBinaryOpBuiltin.class,
                               TpSlotGroup.AS_NUMBER,
                               CFields.PyNumberMethods__nb_multiply,
      @@ -446,7 +549,7 @@ public enum TpSlotMeta {
                               BinaryOpSlotFuncWrapper::createMultiply),
               NB_REMAINDER(
                               TpSlots::nb_remainder,
      -                        TpSlotBinaryOpPython.class,
      +                        TpSlotReversiblePython.class,
                               TpSlotBinaryOpBuiltin.class,
                               TpSlotGroup.AS_NUMBER,
                               CFields.PyNumberMethods__nb_remainder,
      @@ -454,7 +557,7 @@ public enum TpSlotMeta {
                               BinaryOpSlotFuncWrapper::createRemainder),
               NB_LSHIFT(
                               TpSlots::nb_lshift,
      -                        TpSlotBinaryOpPython.class,
      +                        TpSlotReversiblePython.class,
                               TpSlotBinaryOpBuiltin.class,
                               TpSlotGroup.AS_NUMBER,
                               CFields.PyNumberMethods__nb_lshift,
      @@ -462,7 +565,7 @@ public enum TpSlotMeta {
                               BinaryOpSlotFuncWrapper::createLShift),
               NB_RSHIFT(
                               TpSlots::nb_rshift,
      -                        TpSlotBinaryOpPython.class,
      +                        TpSlotReversiblePython.class,
                               TpSlotBinaryOpBuiltin.class,
                               TpSlotGroup.AS_NUMBER,
                               CFields.PyNumberMethods__nb_rshift,
      @@ -470,7 +573,7 @@ public enum TpSlotMeta {
                               BinaryOpSlotFuncWrapper::createRShift),
               NB_AND(
                               TpSlots::nb_and,
      -                        TpSlotBinaryOpPython.class,
      +                        TpSlotReversiblePython.class,
                               TpSlotBinaryOpBuiltin.class,
                               TpSlotGroup.AS_NUMBER,
                               CFields.PyNumberMethods__nb_and,
      @@ -478,7 +581,7 @@ public enum TpSlotMeta {
                               BinaryOpSlotFuncWrapper::createAnd),
               NB_XOR(
                               TpSlots::nb_xor,
      -                        TpSlotBinaryOpPython.class,
      +                        TpSlotReversiblePython.class,
                               TpSlotBinaryOpBuiltin.class,
                               TpSlotGroup.AS_NUMBER,
                               CFields.PyNumberMethods__nb_xor,
      @@ -486,7 +589,7 @@ public enum TpSlotMeta {
                               BinaryOpSlotFuncWrapper::createXor),
               NB_OR(
                               TpSlots::nb_or,
      -                        TpSlotBinaryOpPython.class,
      +                        TpSlotReversiblePython.class,
                               TpSlotBinaryOpBuiltin.class,
                               TpSlotGroup.AS_NUMBER,
                               CFields.PyNumberMethods__nb_or,
      @@ -494,7 +597,7 @@ public enum TpSlotMeta {
                               BinaryOpSlotFuncWrapper::createOr),
               NB_FLOOR_DIVIDE(
                               TpSlots::nb_floor_divide,
      -                        TpSlotBinaryOpPython.class,
      +                        TpSlotReversiblePython.class,
                               TpSlotBinaryOpBuiltin.class,
                               TpSlotGroup.AS_NUMBER,
                               CFields.PyNumberMethods__nb_floor_divide,
      @@ -502,7 +605,7 @@ public enum TpSlotMeta {
                               BinaryOpSlotFuncWrapper::createFloorDivide),
               NB_TRUE_DIVIDE(
                               TpSlots::nb_true_divide,
      -                        TpSlotBinaryOpPython.class,
      +                        TpSlotReversiblePython.class,
                               TpSlotBinaryOpBuiltin.class,
                               TpSlotGroup.AS_NUMBER,
                               CFields.PyNumberMethods__nb_true_divide,
      @@ -510,7 +613,7 @@ public enum TpSlotMeta {
                               BinaryOpSlotFuncWrapper::createTrueDivide),
               NB_DIVMOD(
                               TpSlots::nb_divmod,
      -                        TpSlotBinaryOpPython.class,
      +                        TpSlotReversiblePython.class,
                               TpSlotBinaryOpBuiltin.class,
                               TpSlotGroup.AS_NUMBER,
                               CFields.PyNumberMethods__nb_divmod,
      @@ -518,12 +621,124 @@ public enum TpSlotMeta {
                               BinaryOpSlotFuncWrapper::createDivMod),
               NB_MATRIX_MULTIPLY(
                               TpSlots::nb_matrix_multiply,
      -                        TpSlotBinaryOpPython.class,
      +                        TpSlotReversiblePython.class,
                               TpSlotBinaryOpBuiltin.class,
                               TpSlotGroup.AS_NUMBER,
                               CFields.PyNumberMethods__nb_matrix_multiply,
                               PExternalFunctionWrapper.BINARYFUNC,
                               BinaryOpSlotFuncWrapper::createMatrixMultiply),
      +        NB_POWER(
      +                        TpSlots::nb_power,
      +                        TpSlotReversiblePython.class,
      +                        TpSlotNbPowerBuiltin.class,
      +                        TpSlotGroup.AS_NUMBER,
      +                        CFields.PyNumberMethods__nb_power,
      +                        PExternalFunctionWrapper.TERNARYFUNC,
      +                        NbPowerWrapper::new),
      +        NB_INPLACE_ADD(
      +                        TpSlots::nb_inplace_add,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotBinaryIOpBuiltin.class,
      +                        TpSlotGroup.AS_NUMBER,
      +                        CFields.PyNumberMethods__nb_inplace_add,
      +                        PExternalFunctionWrapper.BINARYFUNC,
      +                        BinarySlotFuncWrapper::new),
      +        NB_INPLACE_SUBTRACT(
      +                        TpSlots::nb_inplace_subtract,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotBinaryIOpBuiltin.class,
      +                        TpSlotGroup.AS_NUMBER,
      +                        CFields.PyNumberMethods__nb_inplace_subtract,
      +                        PExternalFunctionWrapper.BINARYFUNC,
      +                        BinarySlotFuncWrapper::new),
      +        NB_INPLACE_MULTIPLY(
      +                        TpSlots::nb_inplace_multiply,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotBinaryIOpBuiltin.class,
      +                        TpSlotGroup.AS_NUMBER,
      +                        CFields.PyNumberMethods__nb_inplace_multiply,
      +                        PExternalFunctionWrapper.BINARYFUNC,
      +                        BinarySlotFuncWrapper::new),
      +        NB_INPLACE_REMAINDER(
      +                        TpSlots::nb_inplace_remainder,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotBinaryIOpBuiltin.class,
      +                        TpSlotGroup.AS_NUMBER,
      +                        CFields.PyNumberMethods__nb_inplace_remainder,
      +                        PExternalFunctionWrapper.BINARYFUNC,
      +                        BinarySlotFuncWrapper::new),
      +        NB_INPLACE_LSHIFT(
      +                        TpSlots::nb_inplace_lshift,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotBinaryIOpBuiltin.class,
      +                        TpSlotGroup.AS_NUMBER,
      +                        CFields.PyNumberMethods__nb_inplace_lshift,
      +                        PExternalFunctionWrapper.BINARYFUNC,
      +                        BinarySlotFuncWrapper::new),
      +        NB_INPLACE_RSHIFT(
      +                        TpSlots::nb_inplace_rshift,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotBinaryIOpBuiltin.class,
      +                        TpSlotGroup.AS_NUMBER,
      +                        CFields.PyNumberMethods__nb_inplace_rshift,
      +                        PExternalFunctionWrapper.BINARYFUNC,
      +                        BinarySlotFuncWrapper::new),
      +        NB_INPLACE_AND(
      +                        TpSlots::nb_inplace_and,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotBinaryIOpBuiltin.class,
      +                        TpSlotGroup.AS_NUMBER,
      +                        CFields.PyNumberMethods__nb_inplace_and,
      +                        PExternalFunctionWrapper.BINARYFUNC,
      +                        BinarySlotFuncWrapper::new),
      +        NB_INPLACE_XOR(
      +                        TpSlots::nb_inplace_xor,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotBinaryIOpBuiltin.class,
      +                        TpSlotGroup.AS_NUMBER,
      +                        CFields.PyNumberMethods__nb_inplace_xor,
      +                        PExternalFunctionWrapper.BINARYFUNC,
      +                        BinarySlotFuncWrapper::new),
      +        NB_INPLACE_OR(
      +                        TpSlots::nb_inplace_or,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotBinaryIOpBuiltin.class,
      +                        TpSlotGroup.AS_NUMBER,
      +                        CFields.PyNumberMethods__nb_inplace_or,
      +                        PExternalFunctionWrapper.BINARYFUNC,
      +                        BinarySlotFuncWrapper::new),
      +        NB_INPLACE_FLOOR_DIVIDE(
      +                        TpSlots::nb_inplace_floor_divide,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotBinaryIOpBuiltin.class,
      +                        TpSlotGroup.AS_NUMBER,
      +                        CFields.PyNumberMethods__nb_inplace_floor_divide,
      +                        PExternalFunctionWrapper.BINARYFUNC,
      +                        BinarySlotFuncWrapper::new),
      +        NB_INPLACE_TRUE_DIVIDE(
      +                        TpSlots::nb_inplace_true_divide,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotBinaryIOpBuiltin.class,
      +                        TpSlotGroup.AS_NUMBER,
      +                        CFields.PyNumberMethods__nb_inplace_true_divide,
      +                        PExternalFunctionWrapper.BINARYFUNC,
      +                        BinarySlotFuncWrapper::new),
      +        NB_INPLACE_MATRIX_MULTIPLY(
      +                        TpSlots::nb_inplace_matrix_multiply,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotBinaryIOpBuiltin.class,
      +                        TpSlotGroup.AS_NUMBER,
      +                        CFields.PyNumberMethods__nb_inplace_matrix_multiply,
      +                        PExternalFunctionWrapper.BINARYFUNC,
      +                        BinarySlotFuncWrapper::new),
      +        NB_INPLACE_POWER(
      +                        TpSlots::nb_inplace_power,
      +                        TpSlotPythonSingle.class,
      +                        null, // No builtin implementations
      +                        TpSlotGroup.AS_NUMBER,
      +                        CFields.PyNumberMethods__nb_inplace_power,
      +                        PExternalFunctionWrapper.TERNARYFUNC,
      +                        NbInPlacePowerWrapper::new),
               SQ_LENGTH(
                               TpSlots::sq_length,
                               TpSlotPythonSingle.class,
      @@ -564,6 +779,30 @@ public enum TpSlotMeta {
                               CFields.PySequenceMethods__sq_repeat,
                               PExternalFunctionWrapper.SSIZE_ARG,
                               SsizeargfuncSlotWrapper::new),
      +        SQ_INPLACE_CONCAT(
      +                        TpSlots::sq_inplace_concat,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotBinaryIOpBuiltin.class,
      +                        TpSlotGroup.AS_SEQUENCE,
      +                        CFields.PySequenceMethods__sq_inplace_concat,
      +                        PExternalFunctionWrapper.BINARYFUNC,
      +                        BinarySlotFuncWrapper::new),
      +        SQ_INPLACE_REPEAT(
      +                        TpSlots::sq_inplace_repeat,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotSizeArgFunBuiltin.class,
      +                        TpSlotGroup.AS_SEQUENCE,
      +                        CFields.PySequenceMethods__sq_inplace_repeat,
      +                        PExternalFunctionWrapper.SSIZE_ARG,
      +                        SsizeargfuncSlotWrapper::new),
      +        SQ_CONTAINS(
      +                        TpSlots::sq_contains,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotSqContainsBuiltin.class,
      +                        TpSlotGroup.AS_SEQUENCE,
      +                        CFields.PySequenceMethods__sq_contains,
      +                        PExternalFunctionWrapper.OBJOBJPROC,
      +                        SqContainsWrapper::new),
               MP_LENGTH(
                               TpSlots::mp_length,
                               TpSlotPythonSingle.class,
      @@ -588,6 +827,14 @@ public enum TpSlotMeta {
                               CFields.PyMappingMethods__mp_ass_subscript,
                               PExternalFunctionWrapper.OBJOBJARGPROC,
                               ObjobjargWrapper::new),
      +        TP_RICHCOMPARE(
      +                        TpSlots::tp_richcmp,
      +                        TpSlotRichCmpPython.class,
      +                        TpSlotRichCmpBuiltin.class,
      +                        TpSlotGroup.NO_GROUP,
      +                        CFields.PyTypeObject__tp_richcompare,
      +                        PExternalFunctionWrapper.RICHCMP,
      +                        RichcmpFunctionWrapper::new),
               TP_DESCR_GET(
                               TpSlots::tp_descr_get,
                               TpSlotPythonSingle.class,
      @@ -604,6 +851,14 @@ public enum TpSlotMeta {
                               CFields.PyTypeObject__tp_descr_set,
                               PExternalFunctionWrapper.DESCR_SET,
                               DescrSetFunctionWrapper::new),
      +        TP_HASH(
      +                        TpSlots::tp_hash,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotHashBuiltin.class,
      +                        TpSlotGroup.NO_GROUP,
      +                        CFields.PyTypeObject__tp_hash,
      +                        PExternalFunctionWrapper.HASHFUNC,
      +                        HashfuncWrapper::new),
               TP_GETATTRO(
                               TpSlots::tp_getattro,
                               TpSlotGetAttrPython.class,
      @@ -635,7 +890,87 @@ public enum TpSlotMeta {
                               TpSlotGroup.NO_GROUP,
                               CFields.PyTypeObject__tp_setattr,
                               PExternalFunctionWrapper.SETATTR,
      -                        new NativeWrapperFactory.ShouldNotReach("tp_setattr"));
      +                        new NativeWrapperFactory.ShouldNotReach("tp_setattr")),
      +        TP_ITER(
      +                        TpSlots::tp_iter,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotUnaryFuncBuiltin.class,
      +                        TpSlotGroup.NO_GROUP,
      +                        CFields.PyTypeObject__tp_iter,
      +                        PExternalFunctionWrapper.UNARYFUNC,
      +                        UnaryFuncWrapper::new),
      +        TP_ITERNEXT(
      +                        TpSlots::tp_iternext,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotIterNextBuiltin.class,
      +                        TpSlotGroup.NO_GROUP,
      +                        CFields.PyTypeObject__tp_iternext,
      +                        PExternalFunctionWrapper.ITERNEXT,
      +                        IterNextWrapper::new),
      +        TP_REPR(
      +                        TpSlots::tp_repr,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotUnaryFuncBuiltin.class,
      +                        TpSlotGroup.NO_GROUP,
      +                        CFields.PyTypeObject__tp_repr,
      +                        PExternalFunctionWrapper.UNARYFUNC,
      +                        UnaryFuncWrapper::new),
      +        TP_STR(
      +                        TpSlots::tp_str,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotUnaryFuncBuiltin.class,
      +                        TpSlotGroup.NO_GROUP,
      +                        CFields.PyTypeObject__tp_str,
      +                        PExternalFunctionWrapper.UNARYFUNC,
      +                        UnaryFuncWrapper::new),
      +        TP_INIT(
      +                        TpSlots::tp_init,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotVarargsBuiltin.class,
      +                        TpSlotGroup.NO_GROUP,
      +                        CFields.PyTypeObject__tp_init,
      +                        PExternalFunctionWrapper.INITPROC,
      +                        InitWrapper::new),
      +        TP_NEW(
      +                        TpSlots::tp_new,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotNewBuiltin.class,
      +                        TpSlotGroup.NO_GROUP,
      +                        CFields.PyTypeObject__tp_new,
      +                        PExternalFunctionWrapper.NEW,
      +                        NewWrapper::new),
      +        TP_CALL(
      +                        TpSlots::tp_call,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotVarargsBuiltin.class,
      +                        TpSlotGroup.NO_GROUP,
      +                        CFields.PyTypeObject__tp_call,
      +                        PExternalFunctionWrapper.CALL,
      +                        CallWrapper::new),
      +        AM_AWAIT(
      +                        TpSlots::am_await,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotUnaryFuncBuiltin.class,
      +                        TpSlotGroup.AS_ASYNC,
      +                        CFields.PyAsyncMethods__am_await,
      +                        PExternalFunctionWrapper.UNARYFUNC,
      +                        UnaryFuncWrapper::new),
      +        AM_AITER(
      +                        TpSlots::am_aiter,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotUnaryFuncBuiltin.class,
      +                        TpSlotGroup.AS_ASYNC,
      +                        CFields.PyAsyncMethods__am_aiter,
      +                        PExternalFunctionWrapper.UNARYFUNC,
      +                        UnaryFuncWrapper::new),
      +        AM_ANEXT(
      +                        TpSlots::am_anext,
      +                        TpSlotPythonSingle.class,
      +                        TpSlotUnaryFuncBuiltin.class,
      +                        TpSlotGroup.AS_ASYNC,
      +                        CFields.PyAsyncMethods__am_anext,
      +                        PExternalFunctionWrapper.UNARYFUNC,
      +                        UnaryFuncWrapper::new);
       
               public static final TpSlotMeta[] VALUES = values();
       
      @@ -757,29 +1092,21 @@ public TpSlotGroup getGroup() {
            * @param wrapper {@code descrobject.h:wrapperbase#wrapper}
            */
           public record TpSlotDef(TruffleString name, PythonFunctionFactory functionFactory,
      -                    PExternalFunctionWrapper wrapper, HPySlotWrapper hpyWrapper) {
      -        public static TpSlotDef withoutHPy(TruffleString name, PythonFunctionFactory functionFactory, PExternalFunctionWrapper wrapper) {
      -            return new TpSlotDef(name, functionFactory, wrapper, null);
      +                    PExternalFunctionWrapper wrapper) {
      +        public static TpSlotDef create(TruffleString name, PythonFunctionFactory functionFactory, PExternalFunctionWrapper wrapper) {
      +            return new TpSlotDef(name, functionFactory, wrapper);
               }
       
               public static TpSlotDef withSimpleFunction(TruffleString name, PExternalFunctionWrapper wrapper) {
      -            return new TpSlotDef(name, SimplePythonWrapper.INSTANCE, wrapper, null);
      -        }
      -
      -        public static TpSlotDef withSimpleFunction(TruffleString name, PExternalFunctionWrapper wrapper, HPySlotWrapper hpyWrapper) {
      -            return new TpSlotDef(name, SimplePythonWrapper.INSTANCE, wrapper, hpyWrapper);
      +            return new TpSlotDef(name, SimplePythonWrapper.INSTANCE, wrapper);
               }
       
               public static TpSlotDef withNoFunctionNoWrapper(TruffleString name) {
      -            return new TpSlotDef(name, null, null, null);
      +            return new TpSlotDef(name, null, null);
               }
       
               public static TpSlotDef withNoFunction(TruffleString name, PExternalFunctionWrapper wrapper) {
      -            return new TpSlotDef(name, null, wrapper, null);
      -        }
      -
      -        public static TpSlotDef withNoFunction(TruffleString name, PExternalFunctionWrapper wrapper, HPySlotWrapper hpyWrapper) {
      -            return new TpSlotDef(name, null, wrapper, hpyWrapper);
      +            return new TpSlotDef(name, null, wrapper);
               }
           }
       
      @@ -805,55 +1132,86 @@ private static void addSlotDef(LinkedHashMap defs, TpSl
               addSlotDef(s, TpSlotMeta.TP_SETATTR,
                               TpSlotDef.withNoFunctionNoWrapper(T___SETATTR__),
                               TpSlotDef.withNoFunctionNoWrapper(T___DELATTR__));
      +        addSlotDef(s, TpSlotMeta.TP_HASH, TpSlotDef.withSimpleFunction(T___HASH__, PExternalFunctionWrapper.HASHFUNC));
               addSlotDef(s, TpSlotMeta.TP_GETATTRO,
      -                        TpSlotDef.withoutHPy(T___GETATTRIBUTE__, TpSlotGetAttrPython::create, PExternalFunctionWrapper.BINARYFUNC),
      -                        TpSlotDef.withoutHPy(T___GETATTR__, TpSlotGetAttrPython::create, null));
      +                        TpSlotDef.create(T___GETATTRIBUTE__, TpSlotGetAttrPython::create, PExternalFunctionWrapper.BINARYFUNC),
      +                        TpSlotDef.create(T___GETATTR__, TpSlotGetAttrPython::create, null));
               addSlotDef(s, TpSlotMeta.TP_SETATTRO,
      -                        TpSlotDef.withoutHPy(T___SETATTR__, TpSlotSetAttrPython::create, PExternalFunctionWrapper.SETATTRO),
      -                        TpSlotDef.withoutHPy(T___DELATTR__, TpSlotSetAttrPython::create, PExternalFunctionWrapper.DELATTRO));
      +                        TpSlotDef.create(T___SETATTR__, TpSlotSetAttrPython::create, PExternalFunctionWrapper.SETATTRO),
      +                        TpSlotDef.create(T___DELATTR__, TpSlotSetAttrPython::create, PExternalFunctionWrapper.DELATTRO));
      +        addSlotDef(s, TpSlotMeta.TP_RICHCOMPARE,
      +                        TpSlotDef.create(T___LT__, TpSlotRichCmpPython::create, PExternalFunctionWrapper.BINARYFUNC),
      +                        TpSlotDef.create(T___LE__, TpSlotRichCmpPython::create, PExternalFunctionWrapper.BINARYFUNC),
      +                        TpSlotDef.create(T___EQ__, TpSlotRichCmpPython::create, PExternalFunctionWrapper.BINARYFUNC),
      +                        TpSlotDef.create(T___NE__, TpSlotRichCmpPython::create, PExternalFunctionWrapper.BINARYFUNC),
      +                        TpSlotDef.create(T___GT__, TpSlotRichCmpPython::create, PExternalFunctionWrapper.BINARYFUNC),
      +                        TpSlotDef.create(T___GE__, TpSlotRichCmpPython::create, PExternalFunctionWrapper.BINARYFUNC));
               addSlotDef(s, TpSlotMeta.TP_DESCR_GET, TpSlotDef.withSimpleFunction(T___GET__, PExternalFunctionWrapper.DESCR_GET));
               addSlotDef(s, TpSlotMeta.TP_DESCR_SET, //
      -                        TpSlotDef.withoutHPy(T___SET__, TpSlotDescrSetPython::create, PExternalFunctionWrapper.DESCR_SET), //
      -                        TpSlotDef.withoutHPy(T___DELETE__, TpSlotDescrSetPython::create, PExternalFunctionWrapper.DESCR_DELETE));
      +                        TpSlotDef.create(T___SET__, TpSlotDescrSetPython::create, PExternalFunctionWrapper.DESCR_SET), //
      +                        TpSlotDef.create(T___DELETE__, TpSlotDescrSetPython::create, PExternalFunctionWrapper.DESCR_DELETE));
      +        addSlotDef(s, TpSlotMeta.TP_ITER, TpSlotDef.withSimpleFunction(T___ITER__, PExternalFunctionWrapper.UNARYFUNC));
      +        addSlotDef(s, TpSlotMeta.TP_ITERNEXT, TpSlotDef.withSimpleFunction(T___NEXT__, PExternalFunctionWrapper.ITERNEXT));
      +        addSlotDef(s, TpSlotMeta.TP_STR, TpSlotDef.withSimpleFunction(T___STR__, PExternalFunctionWrapper.UNARYFUNC));
      +        addSlotDef(s, TpSlotMeta.TP_REPR, TpSlotDef.withSimpleFunction(T___REPR__, PExternalFunctionWrapper.UNARYFUNC));
      +        addSlotDef(s, TpSlotMeta.TP_INIT, TpSlotDef.withSimpleFunction(T___INIT__, PExternalFunctionWrapper.INITPROC));
      +        addSlotDef(s, TpSlotMeta.TP_NEW, TpSlotDef.withSimpleFunction(T___NEW__, PExternalFunctionWrapper.NEW));
      +        addSlotDef(s, TpSlotMeta.TP_CALL, TpSlotDef.withSimpleFunction(T___CALL__, PExternalFunctionWrapper.CALL));
               addSlotDef(s, TpSlotMeta.NB_ADD,
      -                        TpSlotDef.withoutHPy(T___ADD__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      -                        TpSlotDef.withoutHPy(T___RADD__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_R));
      +                        TpSlotDef.create(T___ADD__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      +                        TpSlotDef.create(T___RADD__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_R));
               addSlotDef(s, TpSlotMeta.NB_SUBTRACT,
      -                        TpSlotDef.withoutHPy(T___SUB__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      -                        TpSlotDef.withoutHPy(T___RSUB__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_R));
      +                        TpSlotDef.create(T___SUB__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      +                        TpSlotDef.create(T___RSUB__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_R));
               addSlotDef(s, TpSlotMeta.NB_MULTIPLY,
      -                        TpSlotDef.withoutHPy(T___MUL__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      -                        TpSlotDef.withoutHPy(T___RMUL__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_R));
      +                        TpSlotDef.create(T___MUL__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      +                        TpSlotDef.create(T___RMUL__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_R));
               addSlotDef(s, TpSlotMeta.NB_REMAINDER,
      -                        TpSlotDef.withoutHPy(T___MOD__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      -                        TpSlotDef.withoutHPy(T___RMOD__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_R));
      +                        TpSlotDef.create(T___MOD__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      +                        TpSlotDef.create(T___RMOD__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_R));
               addSlotDef(s, TpSlotMeta.NB_LSHIFT,
      -                        TpSlotDef.withoutHPy(T___LSHIFT__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      -                        TpSlotDef.withoutHPy(T___RLSHIFT__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_R));
      +                        TpSlotDef.create(T___LSHIFT__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      +                        TpSlotDef.create(T___RLSHIFT__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_R));
               addSlotDef(s, TpSlotMeta.NB_RSHIFT,
      -                        TpSlotDef.withoutHPy(T___RSHIFT__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      -                        TpSlotDef.withoutHPy(T___RRSHIFT__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_R));
      +                        TpSlotDef.create(T___RSHIFT__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      +                        TpSlotDef.create(T___RRSHIFT__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_R));
               addSlotDef(s, TpSlotMeta.NB_AND,
      -                        TpSlotDef.withoutHPy(T___AND__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      -                        TpSlotDef.withoutHPy(T___RAND__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_R));
      +                        TpSlotDef.create(T___AND__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      +                        TpSlotDef.create(T___RAND__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_R));
               addSlotDef(s, TpSlotMeta.NB_XOR,
      -                        TpSlotDef.withoutHPy(T___XOR__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      -                        TpSlotDef.withoutHPy(T___RXOR__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_R));
      +                        TpSlotDef.create(T___XOR__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      +                        TpSlotDef.create(T___RXOR__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_R));
               addSlotDef(s, TpSlotMeta.NB_OR,
      -                        TpSlotDef.withoutHPy(T___OR__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      -                        TpSlotDef.withoutHPy(T___ROR__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_R));
      +                        TpSlotDef.create(T___OR__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      +                        TpSlotDef.create(T___ROR__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_R));
               addSlotDef(s, TpSlotMeta.NB_FLOOR_DIVIDE,
      -                        TpSlotDef.withoutHPy(T___FLOORDIV__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      -                        TpSlotDef.withoutHPy(T___RFLOORDIV__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_R));
      +                        TpSlotDef.create(T___FLOORDIV__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      +                        TpSlotDef.create(T___RFLOORDIV__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_R));
               addSlotDef(s, TpSlotMeta.NB_TRUE_DIVIDE,
      -                        TpSlotDef.withoutHPy(T___TRUEDIV__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      -                        TpSlotDef.withoutHPy(T___RTRUEDIV__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_R));
      +                        TpSlotDef.create(T___TRUEDIV__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      +                        TpSlotDef.create(T___RTRUEDIV__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_R));
               addSlotDef(s, TpSlotMeta.NB_DIVMOD,
      -                        TpSlotDef.withoutHPy(T___DIVMOD__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      -                        TpSlotDef.withoutHPy(T___RDIVMOD__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_R));
      +                        TpSlotDef.create(T___DIVMOD__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      +                        TpSlotDef.create(T___RDIVMOD__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_R));
               addSlotDef(s, TpSlotMeta.NB_MATRIX_MULTIPLY,
      -                        TpSlotDef.withoutHPy(T___MATMUL__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      -                        TpSlotDef.withoutHPy(T___RMATMUL__, TpSlotBinaryOpPython::create, PExternalFunctionWrapper.BINARYFUNC_R));
      +                        TpSlotDef.create(T___MATMUL__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_L),
      +                        TpSlotDef.create(T___RMATMUL__, TpSlotReversiblePython::create, PExternalFunctionWrapper.BINARYFUNC_R));
      +        addSlotDef(s, TpSlotMeta.NB_POWER,
      +                        TpSlotDef.create(T___POW__, TpSlotReversiblePython::create, PExternalFunctionWrapper.TERNARYFUNC),
      +                        TpSlotDef.create(T___RPOW__, TpSlotReversiblePython::create, PExternalFunctionWrapper.TERNARYFUNC_R));
      +        addSlotDef(s, TpSlotMeta.NB_INPLACE_ADD, TpSlotDef.withSimpleFunction(T___IADD__, PExternalFunctionWrapper.BINARYFUNC));
      +        addSlotDef(s, TpSlotMeta.NB_INPLACE_SUBTRACT, TpSlotDef.withSimpleFunction(T___ISUB__, PExternalFunctionWrapper.BINARYFUNC));
      +        addSlotDef(s, TpSlotMeta.NB_INPLACE_MULTIPLY, TpSlotDef.withSimpleFunction(T___IMUL__, PExternalFunctionWrapper.BINARYFUNC));
      +        addSlotDef(s, TpSlotMeta.NB_INPLACE_REMAINDER, TpSlotDef.withSimpleFunction(T___IMOD__, PExternalFunctionWrapper.BINARYFUNC));
      +        addSlotDef(s, TpSlotMeta.NB_INPLACE_LSHIFT, TpSlotDef.withSimpleFunction(T___ILSHIFT__, PExternalFunctionWrapper.BINARYFUNC));
      +        addSlotDef(s, TpSlotMeta.NB_INPLACE_RSHIFT, TpSlotDef.withSimpleFunction(T___IRSHIFT__, PExternalFunctionWrapper.BINARYFUNC));
      +        addSlotDef(s, TpSlotMeta.NB_INPLACE_AND, TpSlotDef.withSimpleFunction(T___IAND__, PExternalFunctionWrapper.BINARYFUNC));
      +        addSlotDef(s, TpSlotMeta.NB_INPLACE_XOR, TpSlotDef.withSimpleFunction(T___IXOR__, PExternalFunctionWrapper.BINARYFUNC));
      +        addSlotDef(s, TpSlotMeta.NB_INPLACE_OR, TpSlotDef.withSimpleFunction(T___IOR__, PExternalFunctionWrapper.BINARYFUNC));
      +        addSlotDef(s, TpSlotMeta.NB_INPLACE_FLOOR_DIVIDE, TpSlotDef.withSimpleFunction(T___IFLOORDIV__, PExternalFunctionWrapper.BINARYFUNC));
      +        addSlotDef(s, TpSlotMeta.NB_INPLACE_TRUE_DIVIDE, TpSlotDef.withSimpleFunction(T___ITRUEDIV__, PExternalFunctionWrapper.BINARYFUNC));
      +        addSlotDef(s, TpSlotMeta.NB_INPLACE_MATRIX_MULTIPLY, TpSlotDef.withSimpleFunction(T___IMATMUL__, PExternalFunctionWrapper.BINARYFUNC));
      +        addSlotDef(s, TpSlotMeta.NB_INPLACE_POWER, TpSlotDef.withSimpleFunction(T___IPOW__, PExternalFunctionWrapper.TERNARYFUNC));
               addSlotDef(s, TpSlotMeta.NB_BOOL, TpSlotDef.withSimpleFunction(T___BOOL__, PExternalFunctionWrapper.INQUIRY));
               addSlotDef(s, TpSlotMeta.NB_INDEX, TpSlotDef.withSimpleFunction(T___INDEX__, PExternalFunctionWrapper.UNARYFUNC));
               addSlotDef(s, TpSlotMeta.NB_INT, TpSlotDef.withSimpleFunction(T___INT__, PExternalFunctionWrapper.UNARYFUNC));
      @@ -862,24 +1220,30 @@ private static void addSlotDef(LinkedHashMap defs, TpSl
               addSlotDef(s, TpSlotMeta.NB_POSITIVE, TpSlotDef.withSimpleFunction(T___POS__, PExternalFunctionWrapper.UNARYFUNC));
               addSlotDef(s, TpSlotMeta.NB_NEGATIVE, TpSlotDef.withSimpleFunction(T___NEG__, PExternalFunctionWrapper.UNARYFUNC));
               addSlotDef(s, TpSlotMeta.NB_INVERT, TpSlotDef.withSimpleFunction(T___INVERT__, PExternalFunctionWrapper.UNARYFUNC));
      -        addSlotDef(s, TpSlotMeta.MP_LENGTH, TpSlotDef.withSimpleFunction(T___LEN__, PExternalFunctionWrapper.LENFUNC, HPySlotWrapper.LENFUNC));
      -        addSlotDef(s, TpSlotMeta.MP_SUBSCRIPT, TpSlotDef.withSimpleFunction(T___GETITEM__, PExternalFunctionWrapper.BINARYFUNC, HPySlotWrapper.BINARYFUNC));
      +        addSlotDef(s, TpSlotMeta.MP_LENGTH, TpSlotDef.withSimpleFunction(T___LEN__, PExternalFunctionWrapper.LENFUNC));
      +        addSlotDef(s, TpSlotMeta.MP_SUBSCRIPT, TpSlotDef.withSimpleFunction(T___GETITEM__, PExternalFunctionWrapper.BINARYFUNC));
               addSlotDef(s, TpSlotMeta.MP_ASS_SUBSCRIPT,
      -                        TpSlotDef.withoutHPy(T___SETITEM__, TpSlotMpAssSubscriptPython::create, PExternalFunctionWrapper.OBJOBJARGPROC),
      -                        TpSlotDef.withoutHPy(T___DELITEM__, TpSlotMpAssSubscriptPython::create, PExternalFunctionWrapper.MP_DELITEM));
      -        addSlotDef(s, TpSlotMeta.SQ_LENGTH, TpSlotDef.withSimpleFunction(T___LEN__, PExternalFunctionWrapper.LENFUNC, HPySlotWrapper.LENFUNC));
      +                        TpSlotDef.create(T___SETITEM__, TpSlotMpAssSubscriptPython::create, PExternalFunctionWrapper.OBJOBJARGPROC),
      +                        TpSlotDef.create(T___DELITEM__, TpSlotMpAssSubscriptPython::create, PExternalFunctionWrapper.MP_DELITEM));
      +        addSlotDef(s, TpSlotMeta.SQ_LENGTH, TpSlotDef.withSimpleFunction(T___LEN__, PExternalFunctionWrapper.LENFUNC));
               // sq_concat does not have a slotdef for __radd__ unlike sq_repeat. This have consequences
               // w.r.t. inheritance from native classes, where sq_repeat is not overridden by __mul__.
               // Makes one wonder whether this CPython behavior is intended.
               // see test_sq_repeat_mul_without_rmul_inheritance
               addSlotDef(s, TpSlotMeta.SQ_CONCAT, TpSlotDef.withNoFunction(T___ADD__, PExternalFunctionWrapper.BINARYFUNC));
               addSlotDef(s, TpSlotMeta.SQ_REPEAT,
      -                        TpSlotDef.withNoFunction(T___MUL__, PExternalFunctionWrapper.SSIZE_ARG, HPySlotWrapper.INDEXARGFUNC),
      -                        TpSlotDef.withNoFunction(T___RMUL__, PExternalFunctionWrapper.SSIZE_ARG, HPySlotWrapper.INDEXARGFUNC));
      -        addSlotDef(s, TpSlotMeta.SQ_ITEM, TpSlotDef.withSimpleFunction(T___GETITEM__, PExternalFunctionWrapper.GETITEM, HPySlotWrapper.SQ_ITEM));
      +                        TpSlotDef.withNoFunction(T___MUL__, PExternalFunctionWrapper.SSIZE_ARG),
      +                        TpSlotDef.withNoFunction(T___RMUL__, PExternalFunctionWrapper.SSIZE_ARG));
      +        addSlotDef(s, TpSlotMeta.SQ_ITEM, TpSlotDef.withSimpleFunction(T___GETITEM__, PExternalFunctionWrapper.GETITEM));
               addSlotDef(s, TpSlotMeta.SQ_ASS_ITEM,
      -                        TpSlotDef.withoutHPy(T___SETITEM__, TpSlotSqAssItemPython::create, PExternalFunctionWrapper.SETITEM),
      -                        TpSlotDef.withoutHPy(T___DELITEM__, TpSlotSqAssItemPython::create, PExternalFunctionWrapper.DELITEM));
      +                        TpSlotDef.create(T___SETITEM__, TpSlotSqAssItemPython::create, PExternalFunctionWrapper.SETITEM),
      +                        TpSlotDef.create(T___DELITEM__, TpSlotSqAssItemPython::create, PExternalFunctionWrapper.DELITEM));
      +        addSlotDef(s, TpSlotMeta.SQ_INPLACE_CONCAT, TpSlotDef.withNoFunction(T___IADD__, PExternalFunctionWrapper.BINARYFUNC));
      +        addSlotDef(s, TpSlotMeta.SQ_INPLACE_REPEAT, TpSlotDef.withNoFunction(T___IMUL__, PExternalFunctionWrapper.SSIZE_ARG));
      +        addSlotDef(s, TpSlotMeta.SQ_CONTAINS, TpSlotDef.withSimpleFunction(T___CONTAINS__, PExternalFunctionWrapper.OBJOBJPROC));
      +        addSlotDef(s, TpSlotMeta.AM_AWAIT, TpSlotDef.withSimpleFunction(T___AWAIT__, PExternalFunctionWrapper.UNARYFUNC));
      +        addSlotDef(s, TpSlotMeta.AM_ANEXT, TpSlotDef.withSimpleFunction(T___ANEXT__, PExternalFunctionWrapper.UNARYFUNC));
      +        addSlotDef(s, TpSlotMeta.AM_AITER, TpSlotDef.withSimpleFunction(T___AITER__, PExternalFunctionWrapper.UNARYFUNC));
       
               SLOTDEFS = s;
               SPECIAL2SLOT = new HashMap<>(SLOTDEFS.size() * 2);
      @@ -902,6 +1266,11 @@ public static TpSlots createEmpty() {
            */
           public static TpSlots fromNative(PythonAbstractNativeObject pythonClass, PythonContext ctx) {
               var builder = TpSlots.newBuilder();
      +        for (TpSlotGroup group : TpSlotGroup.VALID_VALUES) {
      +            if (group.readFromNative(pythonClass)) {
      +                builder.setExplicitGroup(group);
      +            }
      +        }
               for (TpSlotMeta def : TpSlotMeta.VALUES) {
                   if (!def.hasNativeWrapperFactory()) {
                       continue;
      @@ -916,12 +1285,26 @@ public static TpSlots fromNative(PythonAbstractNativeObject pythonClass, PythonC
                   TpSlotWrapper existingSlotWrapper = null;
                   if (interop.isPointer(field)) {
                       try {
      -                    Object executable = ctx.getCApiContext().getClosureExecutable(interop.asPointer(field));
      +                    long fieldPointer = interop.asPointer(field);
      +                    Object executable = ctx.getCApiContext().getClosureExecutable(fieldPointer);
                           if (executable instanceof TpSlotWrapper execWrapper) {
                               existingSlotWrapper = execWrapper;
                           } else if (executable != null) {
                               // This can happen for legacy slots where the delegate would be a PFunction
                               LOGGER.fine(() -> String.format("Unexpected executable for slot pointer: %s", executable));
      +                    } else if (def == TpSlotMeta.TP_HASH) {
      +                        // If the slot is not tp_iternext, but the value is
      +                        // PyObject_HashNotImplemented, we still assign it to the slot as wrapped
      +                        // native executable later on
      +                        if (CApiContext.isIdenticalToSymbol(fieldPointer, NativeCAPISymbol.FUN_PYOBJECT_HASH_NOT_IMPLEMENTED)) {
      +                            builder.set(def, TpSlotHashFun.HASH_NOT_IMPLEMENTED);
      +                            continue;
      +                        }
      +                    } else if (def == TpSlotMeta.TP_ITERNEXT) {
      +                        if (CApiContext.isIdenticalToSymbol(fieldPointer, NativeCAPISymbol.FUN_PY_OBJECT_NEXT_NOT_IMPLEMENTED)) {
      +                            builder.set(def, TpSlotIterNext.NEXT_NOT_IMPLEMENTED);
      +                            continue;
      +                        }
                           }
                       } catch (UnsupportedMessageException e) {
                           throw new IllegalStateException(e);
      @@ -971,7 +1354,7 @@ public static TpSlots fromNative(PythonAbstractNativeObject pythonClass, PythonC
               return builder.build();
           }
       
      -    private static void toNative(Object ptrToWrite, TpSlotMeta def, TpSlot value, Object nullValue) {
      +    public static void toNative(Object ptrToWrite, TpSlotMeta def, TpSlot value, Object nullValue) {
               assert !(ptrToWrite instanceof PythonAbstractNativeObject); // this should be the pointer
               Object slotNativeValue = def.getNativeValue(value, nullValue);
               toNative(ptrToWrite, def, slotNativeValue, nullValue);
      @@ -1002,7 +1385,13 @@ private static void toNative(Object prtToWrite, TpSlotMeta def, Object slotNativ
           }
       
           @TruffleBoundary
      -    public static void inherit(PythonClass klass, MroSequenceStorage mro, boolean allocateAllGroups) {
      +    public static void inherit(PythonClass klass, PDict namespace, MroSequenceStorage mro, boolean allocateAllGroups) {
      +        Builder klassSlots = buildInherited(klass, null, mro, allocateAllGroups);
      +        klass.setTpSlots(klassSlots.build());
      +    }
      +
      +    @TruffleBoundary
      +    public static TpSlots.Builder buildInherited(PythonClass klass, PDict namespace, MroSequenceStorage mro, boolean allocateAllGroups) {
               // partially implements CPython:type_ready_inherit
               // slots of native classes are initialized in PyTruffle_AddInheritedSlots, they are just a
               // mirror of the native slots initialized and inherited on the native side
      @@ -1011,15 +1400,19 @@ public static void inherit(PythonClass klass, MroSequenceStorage mro, boolean al
               if (allocateAllGroups) {
                   klassSlots.allocateAllGroups();
               }
      +        if (klass.getBase() != null) {
      +            // tp_new is first inherited from tp_base in type_ready_set_new
      +            klassSlots.set(TpSlotMeta.TP_NEW, GetTpSlotsNode.executeUncached(klass.getBase()).tp_new());
      +        }
               for (int i = 0; i < mro.length(); i++) {
                   PythonAbstractClass type = mro.getPythonClassItemNormalized(i);
                   TpSlots slots = GetTpSlotsNode.executeUncached(type);
                   assert slots != null || type == klass;
                   if (slots != null) {
      -                klassSlots.inherit(slots);
      +                klassSlots.inherit(klass, namespace, slots);
                   }
               }
      -        klass.setTpSlots(klassSlots.build());
      +        return klassSlots;
           }
       
           public static boolean canBeSpecialMethod(TruffleString name, TruffleString.CodePointLengthNode codePointLengthNode, TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
      @@ -1054,6 +1447,11 @@ private static TpSlotMeta resolveSlotdups(Builder slots, TruffleString name) {
           /**
            * Mirrors CPython's {@code typeobject.c:fixup_slot_dispatchers}.
            */
      +    @TruffleBoundary
      +    public static void fixupSlotDispatchers(PythonClass klass, TpSlots.Builder slots) {
      +        updateSlots(klass, slots, SLOTDEFS.entrySet());
      +    }
      +
           @TruffleBoundary
           public static void fixupSlotDispatchers(PythonClass klass) {
               updateSlots(klass, klass.getTpSlots(), SLOTDEFS.entrySet());
      @@ -1144,19 +1542,18 @@ private static Builder updateSlots(PythonAbstractClass klass, Builder slots, Set
                   // dynamic lookup.
                   for (int i = 0; i < defs.length; i++) {
                       TruffleString name = defs[i].name();
      -                Object decr = lookup.execute(klass, name);
      -                genericCallables[i] = decr;
      +                Object descr = lookup.execute(klass, name);
      +                genericCallables[i] = descr;
                       genericCallablesNames[i] = name;
      -                if (decr == PNone.NO_VALUE) {
      -                    /*- TODO:
      -                    if (ptr == (void**)&type->tp_iternext) {
      -                        specific = (void *)_PyObject_NextNotImplemented;
      -                    }*/
      +                if (descr == PNone.NO_VALUE) {
      +                    if (slot == TpSlotMeta.TP_ITERNEXT) {
      +                        specific = NEXT_NOT_IMPLEMENTED;
      +                    }
                           continue;
                       }
                       // Is the value a builtin function (in CPython PyWrapperDescr_Type) that wraps a
                       // builtin or native slot?
      -                if (decr instanceof PBuiltinFunction builtin && builtin.getSlot() != null) {
      +                if (descr instanceof PBuiltinFunction builtin && builtin.getSlot() != null) {
                           /*
                            * CPython source comment: if the special method is a wrapper_descriptor with
                            * the correct name but the type has precisely one slot set for that name and
      @@ -1195,38 +1592,61 @@ private static Builder updateSlots(PythonAbstractClass klass, Builder slots, Set
                                */
                               useGeneric = true;
                           }
      -
      -                    // TODO: special cases:
      -                    // PyCFunction_Type && tp_new (looks like just optimization)
      -                    // descr == Py_None && ptr == (void**)&type->tp_hash ->
      -                    // PyObject_HashNotImplemented
      +                } else if (slot == TpSlotMeta.TP_NEW && descr instanceof PBuiltinMethod method && method.getBuiltinFunction().getSlot() != null &&
      +                                !(slots.get(TpSlotMeta.TP_NEW) instanceof TpSlotPython)) {
      +                    /*
      +                     * From CPython: The __new__ wrapper is not a wrapper descriptor, so must be
      +                     * special-cased differently. If we don't do this, creating an instance will
      +                     * always use slot_tp_new which will look up __new__ in the MRO which will call
      +                     * tp_new_wrapper which will look through the base classes looking for a static
      +                     * base and call its tp_new (usually PyType_GenericNew), after performing
      +                     * various sanity checks and constructing a new argument list. Cut all that
      +                     * nonsense short -- this speeds up instance creation tremendously.
      +                     */
      +                    /*
      +                     * msimacek note: This optimization is not implemented correctly in CPython -
      +                     * it's missing a check that the method is for the same type. This can manifest
      +                     * with multiple-inheritance when the __new__ method inherited from the MRO is
      +                     * different from the current value in tp_new, which was populated from
      +                     * tp_base->tp_new earlier. If the one from tp_base is a wrapper, it will pass
      +                     * this check and stay in the slot, diverging from the __new__ wrapper inherited
      +                     * in MRO. This behavior is already relied upon in the wild (pandas) so we don't
      +                     * check the type either.
      +                     *
      +                     * The last part of the condition is GraalPy-specific because we cache the
      +                     * Python method in the slot. So we make it go to the generic path to make sure
      +                     * it creates a new wrapper for the right method.
      +                     *
      +                     * See test_tp_new_bug_to_bug_compatibility in cpyext/test_object.py
      +                     */
      +                    specific = slots.get(TpSlotMeta.TP_NEW);
      +                } else if (descr == PNone.NONE && slot == TpSlotMeta.TP_HASH) {
      +                    specific = TpSlotHashFun.HASH_NOT_IMPLEMENTED;
                       } else {
                           useGeneric = true;
                           generic = defs[i].functionFactory;
                       }
                   }
       
      +            TpSlot newValue = null;
                   if (specific != null && !useGeneric) {
      -                slots.set(slot, specific);
      -            } else {
      -                TpSlot newValue = null;
      -                if (generic != null) {
      -                    newValue = generic.create(genericCallables, genericCallablesNames, klass);
      -                }
      -                slots.set(slot, newValue);
      -                if (klass instanceof PythonAbstractNativeObject nativeClass) {
      -                    // Update the slots on the native side if this is a native class
      -                    toNative(nativeClass.getPtr(), slot, newValue, nativeNull);
      -                }
      -                if (klass instanceof PythonManagedClass managedClass) {
      -                    // Update the slots on the native side if this is a managed class that has a
      -                    // native mirror allocated already
      -                    PythonClassNativeWrapper classNativeWrapper = managedClass.getClassNativeWrapper();
      -                    if (classNativeWrapper != null) {
      -                        Object replacement = classNativeWrapper.getReplacementIfInitialized();
      -                        if (replacement != null) {
      -                            toNative(replacement, slot, newValue, nativeNull);
      -                        }
      +                newValue = specific;
      +            } else if (generic != null) {
      +                newValue = generic.create(genericCallables, genericCallablesNames, klass);
      +            }
      +            slots.set(slot, newValue);
      +            if (klass instanceof PythonAbstractNativeObject nativeClass) {
      +                // Update the slots on the native side if this is a native class
      +                toNative(nativeClass.getPtr(), slot, newValue, nativeNull);
      +            }
      +            if (klass instanceof PythonManagedClass managedClass) {
      +                // Update the slots on the native side if this is a managed class that has a
      +                // native mirror allocated already
      +                PythonClassNativeWrapper classNativeWrapper = managedClass.getClassNativeWrapper();
      +                if (classNativeWrapper != null) {
      +                    Object replacement = classNativeWrapper.getReplacementIfInitialized();
      +                    if (replacement != null) {
      +                        toNative(replacement, slot, newValue, nativeNull);
                           }
                       }
                   }
      @@ -1275,7 +1695,7 @@ private static boolean checkNoMagicOverrides(Python3Core core, PythonBuiltinClas
               return true;
           }
       
      -    public static void addOperatorsToBuiltin(Map> builtins, Python3Core core, PythonBuiltinClassType type) {
      +    public static void addOperatorsToBuiltin(Python3Core core, PythonBuiltinClassType type, PythonBuiltinClass pythonBuiltinClass) {
               TpSlots slots = type.getDeclaredSlots();
               assert checkNoMagicOverrides(core, type);
       
      @@ -1283,75 +1703,31 @@ public static void addOperatorsToBuiltin(Map builtinSlot)) {
                       continue;
                   }
                   for (TpSlotDef slotDef : slotDefGroup.getValue()) {
      -                if (slotDef.wrapper() != null && !builtins.containsKey(slotDef.name())) {
      +                if (slotDef.wrapper() != null && pythonBuiltinClass.getAttribute(slotDef.name()) == PNone.NO_VALUE) {
                           var value = builtinSlot.createBuiltin(core, type, slotDef.name(), slotDef.wrapper());
      -                    builtins.put(slotDef.name(), value);
      +                    pythonBuiltinClass.setAttribute(slotDef.name(), value);
                       }
                   }
               }
           }
       
      -    /**
      -     * Version of CPython's {@code add_operators} that assumes only native slots. This is useful for
      -     * the HPy case where users cannot "steal" other type's slots or builtin slots. TODO: (GR-53923)
      -     * extend this to support python/builtin slots, use it instead of PyTruffleType_AddSlot upcalls.
      -     */
      -    @TruffleBoundary
      -    public void addOperators(PythonClass type) {
      -        // Current version assumes no dict and writes to the object directly
      -        assert GetDictIfExistsNode.getUncached().execute(type) == null;
      -
      -        PythonContext context = PythonContext.get(null);
      -        var factory = context.factory();
      -        PythonLanguage language = context.getLanguage();
      -        for (Entry slotDefEntry : SLOTDEFS.entrySet()) {
      -            TpSlotMeta tpSlotMeta = slotDefEntry.getKey();
      -            for (TpSlotDef tpSlotDef : slotDefEntry.getValue()) {
      -                if (tpSlotDef.wrapper == null) {
      -                    continue;
      -                }
      -                TpSlot value = tpSlotMeta.getValue(this);
      -                if (value == null) {
      -                    continue;
      -                }
      -                Object existingValue = ReadAttributeFromObjectNode.getUncachedForceType().execute(type, tpSlotDef.name);
      -                if (!PGuards.isNoValue(existingValue)) {
      -                    continue;
      -                }
      -                // TODO: special case for PyObject_HashNotImplemented once we have tp_hash
      -                Object wrapperDescriptor = null;
      -                if (value instanceof TpSlotBuiltin builtinSlot) {
      -                    wrapperDescriptor = builtinSlot.createBuiltin(context, type, tpSlotDef.name, tpSlotDef.wrapper);
      -                } else if (value instanceof TpSlotPython) {
      -                    // TODO: see CExtNodes$CreateFunctionNode
      -                    throw new IllegalStateException("addOperators: TpSlotPython not implemented yet");
      -                } else if (value instanceof TpSlotNative nativeSlot) {
      -                    if (nativeSlot instanceof TpSlotHPyNative hpySlot) {
      -                        wrapperDescriptor = HPyExternalFunctionNodes.createWrapperFunction(language, context.getHPyContext(), tpSlotDef.hpyWrapper, hpySlot, tpSlotDef.wrapper, tpSlotDef.name,
      -                                        nativeSlot.getCallable(), type,
      -                                        factory);
      -                    } else {
      -                        wrapperDescriptor = PExternalFunctionWrapper.createWrapperFunction(tpSlotDef.name, (TpSlotCExtNative) nativeSlot, type, tpSlotDef.wrapper, language, factory);
      -                    }
      -                }
      -                assert wrapperDescriptor != null;
      -                // TODO: optionally take TpDict and write into it if provided
      -                WriteAttributeToPythonObjectNode.executeUncached(type, tpSlotDef.name, wrapperDescriptor);
      -            }
      -        }
      -    }
      -
           public Builder copy() {
               var result = new Builder();
               for (TpSlotMeta def : TpSlotMeta.VALUES) {
                   result.set(def, def.getValue(this));
               }
               for (TpSlotGroup group : TpSlotGroup.VALID_VALUES) {
      -            result.setExplicitGroup(group);
      +            if (group.getValue(this)) {
      +                result.setExplicitGroup(group);
      +            }
               }
               return result;
           }
      @@ -1360,10 +1736,6 @@ public static Builder newBuilder() {
               return new Builder();
           }
       
      -    public static TpSlots merge(TpSlots a, TpSlots b) {
      -        return a.copy().merge(b).build();
      -    }
      -
           public static final class Builder {
               private final TpSlot[] values = new TpSlot[TpSlotMeta.VALUES.length];
               private final boolean[] explicitGroups = new boolean[TpSlotGroup.VALID_VALUES.length];
      @@ -1393,45 +1765,60 @@ public Builder overrideIgnoreGroups(TpSlots other) {
                   return this;
               }
       
      -        private Builder inherit(TpSlots other) {
      +        private Builder inherit(PythonClass klass, PDict namespace, TpSlots base) {
                   // similar to CPython:inherit_slots
                   // indirect slots (from tp_as_number etc.) are not inherited if the group is not
                   // allocated explicitly. Note: native heap types and managed types have always all
                   // groups allocated.
                   for (TpSlotMeta def : TpSlotMeta.VALUES) {
      +                if (def == TpSlotMeta.TP_RICHCOMPARE || def == TpSlotMeta.TP_HASH ||
      +                                def == TpSlotMeta.TP_GETATTRO || def == TpSlotMeta.TP_GETATTR ||
      +                                def == TpSlotMeta.TP_SETATTRO || def == TpSlotMeta.TP_SETATTR) {
      +                    // handled manually below the loop
      +                    continue;
      +                }
                       if (def.group != TpSlotGroup.NO_GROUP && !explicitGroups[def.group.ordinal()]) {
                           continue;
                       }
                       TpSlot current = values[def.ordinal()];
      -                TpSlot otherValue = def.getter.get(other);
      +                TpSlot otherValue = def.getter.get(base);
                       TpSlot newValue = current != null ? current : otherValue;
                       set(def, newValue);
                   }
      +            if (get(TpSlotMeta.TP_GETATTR) == null && get(TpSlotMeta.TP_GETATTRO) == null) {
      +                set(TpSlotMeta.TP_GETATTR, base.tp_getattr());
      +                set(TpSlotMeta.TP_GETATTRO, base.tp_getattro());
      +            }
      +            if (get(TpSlotMeta.TP_SETATTR) == null && get(TpSlotMeta.TP_SETATTRO) == null) {
      +                set(TpSlotMeta.TP_SETATTR, base.tp_setattr());
      +                set(TpSlotMeta.TP_SETATTRO, base.tp_setattro());
      +            }
      +            if (get(TpSlotMeta.TP_RICHCOMPARE) == null && get(TpSlotMeta.TP_HASH) == null) {
      +                if (!overridesHash(namespace)) {
      +                    set(TpSlotMeta.TP_RICHCOMPARE, base.tp_richcmp());
      +                    set(TpSlotMeta.TP_HASH, base.tp_hash());
      +                }
      +            }
                   return this;
               }
       
      -        /**
      -         * Should be used when merging together generated slots from two or more
      -         * {@link com.oracle.graal.python.builtins.PythonBuiltins}. Checks that slots are not
      -         * overriding each other.
      -         */
      -        public Builder merge(TpSlots other) {
      -            for (TpSlotMeta def : TpSlotMeta.VALUES) {
      -                TpSlot current = values[def.ordinal()];
      -                TpSlot otherValue = def.getter.get(other);
      -                if (otherValue != null) {
      -                    assert current == null : def.name();
      -                    set(def, otherValue);
      -                }
      +        private static boolean overridesHash(PDict namespace) {
      +            if (namespace == null) {
      +                return false;
                   }
      -            return this;
      +            Object eq = HashingStorageGetItem.executeUncached(namespace.getDictStorage(), T___EQ__);
      +            if (eq == null) {
      +                Object hash = HashingStorageGetItem.executeUncached(namespace.getDictStorage(), T___HASH__);
      +                return hash != null;
      +            }
      +            return true;
               }
       
               private TpSlot fistNonNull(TpSlotMeta a, TpSlotMeta b) {
                   return values[a.ordinal()] != null ? values[a.ordinal()] : values[b.ordinal()];
               }
       
      -        private TpSlot get(TpSlotMeta s) {
      +        TpSlot get(TpSlotMeta s) {
                   return values[s.ordinal()];
               }
       
      @@ -1475,27 +1862,57 @@ public TpSlots build() {
                                   get(TpSlotMeta.NB_TRUE_DIVIDE), //
                                   get(TpSlotMeta.NB_DIVMOD), //
                                   get(TpSlotMeta.NB_MATRIX_MULTIPLY), //
      +                            get(TpSlotMeta.NB_POWER), //
      +                            get(TpSlotMeta.NB_INPLACE_ADD), //
      +                            get(TpSlotMeta.NB_INPLACE_SUBTRACT), //
      +                            get(TpSlotMeta.NB_INPLACE_MULTIPLY), //
      +                            get(TpSlotMeta.NB_INPLACE_REMAINDER), //
      +                            get(TpSlotMeta.NB_INPLACE_LSHIFT), //
      +                            get(TpSlotMeta.NB_INPLACE_RSHIFT), //
      +                            get(TpSlotMeta.NB_INPLACE_AND), //
      +                            get(TpSlotMeta.NB_INPLACE_XOR), //
      +                            get(TpSlotMeta.NB_INPLACE_OR), //
      +                            get(TpSlotMeta.NB_INPLACE_FLOOR_DIVIDE), //
      +                            get(TpSlotMeta.NB_INPLACE_TRUE_DIVIDE), //
      +                            get(TpSlotMeta.NB_INPLACE_MATRIX_MULTIPLY), //
      +                            get(TpSlotMeta.NB_INPLACE_POWER), //
                                   get(TpSlotMeta.SQ_LENGTH), //
                                   get(TpSlotMeta.SQ_ITEM), //
                                   get(TpSlotMeta.SQ_ASS_ITEM), //
                                   get(TpSlotMeta.SQ_CONCAT), //
                                   get(TpSlotMeta.SQ_REPEAT), //
      +                            get(TpSlotMeta.SQ_INPLACE_CONCAT), //
      +                            get(TpSlotMeta.SQ_INPLACE_REPEAT), //
      +                            get(TpSlotMeta.SQ_CONTAINS), //
                                   get(TpSlotMeta.MP_LENGTH), //
                                   get(TpSlotMeta.MP_SUBSCRIPT), //
                                   get(TpSlotMeta.MP_ASS_SUBSCRIPT), //
                                   sq_mp_length, //
                                   mp_sq_length, //
      +                            get(TpSlotMeta.TP_RICHCOMPARE), //
                                   get(TpSlotMeta.TP_DESCR_GET), //
                                   get(TpSlotMeta.TP_DESCR_SET), //
      +                            get(TpSlotMeta.TP_HASH), //
                                   get(TpSlotMeta.TP_GETATTRO), //
                                   get(TpSlotMeta.TP_GETATTR), //
                                   tp_get_attro_attr,
                                   get(TpSlotMeta.TP_SETATTRO),
                                   get(TpSlotMeta.TP_SETATTR),
                                   tp_set_attro_attr,
      +                            get(TpSlotMeta.TP_ITER), //
      +                            get(TpSlotMeta.TP_ITERNEXT), //
      +                            get(TpSlotMeta.TP_REPR), //
      +                            get(TpSlotMeta.TP_STR), //
      +                            get(TpSlotMeta.TP_INIT), //
      +                            get(TpSlotMeta.TP_NEW), //
      +                            get(TpSlotMeta.TP_CALL), //
      +                            get(TpSlotMeta.AM_AWAIT), //
      +                            get(TpSlotMeta.AM_AITER), //
      +                            get(TpSlotMeta.AM_ANEXT), //
                                   hasGroup(TpSlotGroup.AS_NUMBER),
                                   hasGroup(TpSlotGroup.AS_SEQUENCE),
      -                            hasGroup(TpSlotGroup.AS_MAPPING));
      +                            hasGroup(TpSlotGroup.AS_MAPPING),
      +                            hasGroup(TpSlotGroup.AS_ASYNC));
               }
           }
       
      @@ -1587,6 +2004,10 @@ public final TpSlots executeCached(Object pythonObject) {
                   return execute(this, pythonObject);
               }
       
      +        public static TpSlots executeUncached(Object pythonObject) {
      +            return GetObjectSlotsNodeGen.getUncached().execute(null, pythonObject);
      +        }
      +
               @NeverDefault
               public static GetObjectSlotsNode create() {
                   return GetObjectSlotsNodeGen.create();
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java
      index 2c3e4fa940..796dfbad88 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java
      @@ -50,31 +50,25 @@
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___ABSTRACTMETHODS__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___ANNOTATIONS__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___BASES__;
      -import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___CLASS__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DICT__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___MODULE__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___QUALNAME__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J_MRO;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___DIR__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INSTANCECHECK__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___PREPARE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SUBCLASSCHECK__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SUBCLASSES__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SUBCLASSHOOK__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T_MRO;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T_UPDATE;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GET__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INIT__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEW__;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MRO_ENTRIES__;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.AttributeError;
      +import static com.oracle.graal.python.runtime.exception.PythonErrorType.NotImplementedError;
       import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
       import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
      -import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
       
       import java.util.Arrays;
       import java.util.List;
      @@ -82,17 +76,16 @@
       import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
      -import com.oracle.graal.python.builtins.modules.BuiltinConstructorsFactory;
       import com.oracle.graal.python.builtins.modules.SysModuleBuiltins;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.PNotImplemented;
       import com.oracle.graal.python.builtins.objects.bytes.PBytes;
       import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
      -import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass;
       import com.oracle.graal.python.builtins.objects.cext.capi.PySequenceArrayWrapper;
       import com.oracle.graal.python.builtins.objects.cext.structs.CFields;
       import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess;
      @@ -100,26 +93,21 @@
       import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetObjectArrayNode;
       import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ToArrayNode;
       import com.oracle.graal.python.builtins.objects.dict.PDict;
      +import com.oracle.graal.python.builtins.objects.exception.AttributeErrorBuiltins;
       import com.oracle.graal.python.builtins.objects.function.AbstractFunctionBuiltins;
      -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor;
      -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
      -import com.oracle.graal.python.builtins.objects.function.PFunction;
       import com.oracle.graal.python.builtins.objects.function.PKeyword;
      -import com.oracle.graal.python.builtins.objects.function.Signature;
       import com.oracle.graal.python.builtins.objects.getsetdescriptor.DescriptorDeleteMarker;
       import com.oracle.graal.python.builtins.objects.list.PList;
      -import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
      -import com.oracle.graal.python.builtins.objects.method.PMethod;
      -import com.oracle.graal.python.builtins.objects.object.ObjectBuiltinsFactory;
      +import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins;
       import com.oracle.graal.python.builtins.objects.object.ObjectNodes;
      -import com.oracle.graal.python.builtins.objects.object.PythonObject;
       import com.oracle.graal.python.builtins.objects.set.PSet;
       import com.oracle.graal.python.builtins.objects.str.PString;
       import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode;
       import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
      -import com.oracle.graal.python.builtins.objects.type.TypeBuiltinsFactory.CallNodeFactory;
      -import com.oracle.graal.python.builtins.objects.type.TypeBuiltinsFactory.CallNodeHelperNodeGen;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetTpSlotsNode;
      +import com.oracle.graal.python.builtins.objects.type.TypeBuiltinsFactory.TypeNodeFactory;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes.CheckCompatibleForAssigmentNode;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBestBaseClassNode;
      @@ -135,11 +123,13 @@
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrSet;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.GetAttrBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSetAttr.SetAttrBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotVarargs;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotVarargs.CallSlotTpInitNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotVarargs.CallSlotTpNewNode;
       import com.oracle.graal.python.builtins.objects.types.GenericTypeNodes;
       import com.oracle.graal.python.lib.PyObjectIsTrueNode;
       import com.oracle.graal.python.lib.PyObjectLookupAttr;
       import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
      -import com.oracle.graal.python.lib.PyTupleCheckNode;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
       import com.oracle.graal.python.nodes.PGuards;
      @@ -149,33 +139,22 @@
       import com.oracle.graal.python.nodes.StringLiterals;
       import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetFixedAttributeNode;
       import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
      -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode;
       import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
       import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
      -import com.oracle.graal.python.nodes.builtins.FunctionNodes;
      -import com.oracle.graal.python.nodes.call.special.CallTernaryMethodNode;
      -import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode;
      -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode;
      -import com.oracle.graal.python.nodes.classes.AbstractObjectGetBasesNode;
      -import com.oracle.graal.python.nodes.classes.AbstractObjectIsSubclassNode;
       import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
      -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassExactProfile;
      -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.nodes.object.GetDictIfExistsNode;
      -import com.oracle.graal.python.nodes.truffle.PythonTypes;
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
      -import com.oracle.graal.python.nodes.util.SplitArgsNode;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.exception.PException;
       import com.oracle.graal.python.runtime.exception.PythonErrorType;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
      @@ -188,15 +167,13 @@
       import com.oracle.truffle.api.dsl.GenerateCached;
       import com.oracle.truffle.api.dsl.GenerateInline;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      -import com.oracle.truffle.api.dsl.GenerateUncached;
       import com.oracle.truffle.api.dsl.ImportStatic;
       import com.oracle.truffle.api.dsl.NeverDefault;
       import com.oracle.truffle.api.dsl.NodeFactory;
      -import com.oracle.truffle.api.dsl.ReportPolymorphism;
       import com.oracle.truffle.api.dsl.Specialization;
      -import com.oracle.truffle.api.dsl.TypeSystemReference;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.BranchProfile;
       import com.oracle.truffle.api.profiles.InlinedBranchProfile;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
      @@ -210,7 +187,7 @@ protected List> getNodeFa
               return TypeBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           @ImportStatic(SpecialAttributeNames.class)
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
      @@ -241,43 +218,41 @@ static TruffleString repr(VirtualFrame frame, Object self,
       
           @Builtin(name = J___DOC__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true, allowsDelete = true)
           @GenerateNodeFactory
      -    @ImportStatic(SpecialAttributeNames.class)
           public abstract static class DocNode extends PythonBinaryBuiltinNode {
       
      -        private static final TruffleString BUILTIN_DOC = tsLiteral("type(object_or_name, bases, dict)\n" + //
      -                        "type(object) -> the object's type\n" + //
      -                        "type(name, bases, dict) -> a new type");
      -
               @Specialization(guards = "isNoValue(value)")
      -        Object getDoc(PythonBuiltinClassType self, @SuppressWarnings("unused") PNone value) {
      -            return getDoc(getContext().lookupType(self), value);
      +        static Object getDoc(PythonBuiltinClassType self, @SuppressWarnings("unused") PNone value) {
      +            return self.getDoc() != null ? self.getDoc() : PNone.NONE;
               }
       
               @Specialization(guards = "isNoValue(value)")
               @TruffleBoundary
               static Object getDoc(PythonBuiltinClass self, @SuppressWarnings("unused") PNone value) {
      -            // see type.c#type_get_doc()
      -            if (IsBuiltinClassExactProfile.profileClassSlowPath(self, PythonBuiltinClassType.PythonClass)) {
      -                return BUILTIN_DOC;
      -            } else {
      -                return self.getAttribute(T___DOC__);
      -            }
      +            return getDoc(self.getType(), value);
               }
       
               @Specialization(guards = {"isNoValue(value)", "!isPythonBuiltinClass(self)"})
      -        static Object getDoc(VirtualFrame frame, PythonClass self, @SuppressWarnings("unused") PNone value) {
      +        static Object getDoc(VirtualFrame frame, PythonClass self, @SuppressWarnings("unused") PNone value,
      +                        @Bind Node inliningTarget,
      +                        @Cached ReadAttributeFromObjectNode read,
      +                        @Cached GetClassNode getClassNode,
      +                        @Cached GetCachedTpSlotsNode getSlots,
      +                        @Cached CallSlotDescrGet callGet) {
                   // see type.c#type_get_doc()
      -            Object res = self.getAttribute(T___DOC__);
      -            Object resClass = GetClassNode.executeUncached(res);
      -            Object get = LookupAttributeInMRONode.Dynamic.getUncached().execute(resClass, T___GET__);
      -            if (PGuards.isCallable(get)) {
      -                return CallTernaryMethodNode.getUncached().execute(frame, get, res, PNone.NONE, self);
      +            Object res = read.execute(self, T___DOC__);
      +            if (res == NO_VALUE) {
      +                return PNone.NONE;
      +            }
      +            Object resClass = getClassNode.execute(inliningTarget, res);
      +            TpSlots resSlots = getSlots.execute(inliningTarget, resClass);
      +            if (resSlots.tp_descr_get() != null) {
      +                return callGet.execute(frame, inliningTarget, resSlots.tp_descr_get(), res, NO_VALUE, self);
                   }
                   return res;
               }
       
               @Specialization
      -        static Object getDoc(PythonNativeClass self, @SuppressWarnings("unused") PNone value) {
      +        static Object getDoc(PythonAbstractNativeObject self, @SuppressWarnings("unused") PNone value) {
                   return ReadAttributeFromObjectNode.getUncachedForceType().execute(self, T___DOC__);
               }
       
      @@ -289,14 +264,14 @@ static Object setDoc(PythonClass self, Object value) {
       
               @Specialization(guards = {"!isNoValue(value)", "!isDeleteMarker(value)", "isKindOfBuiltinClass(self)"})
               static Object doc(Object self, @SuppressWarnings("unused") Object value,
      -                        @Shared @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, T___DOC__, self);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, T___DOC__, self);
               }
       
               @Specialization
               static Object doc(Object self, @SuppressWarnings("unused") DescriptorDeleteMarker marker,
      -                        @Shared @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.CANT_DELETE_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, T___DOC__, self);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.CANT_DELETE_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, T___DOC__, self);
               }
           }
       
      @@ -307,13 +282,12 @@ abstract static class MroAttrNode extends PythonUnaryBuiltinNode {
               static Object doit(Object klass,
                               @Bind("this") Node inliningTarget,
                               @Cached TypeNodes.GetMroNode getMroNode,
      -                        @Cached InlinedConditionProfile notInitialized,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Cached InlinedConditionProfile notInitialized) {
                   if (notInitialized.profile(inliningTarget, klass instanceof PythonManagedClass && !((PythonManagedClass) klass).isMROInitialized())) {
                       return PNone.NONE;
                   }
                   PythonAbstractClass[] mro = getMroNode.execute(inliningTarget, klass);
      -            return factory.createTuple(mro);
      +            return PFactory.createTuple(PythonLanguage.get(inliningTarget), mro);
               }
           }
       
      @@ -324,315 +298,217 @@ public abstract static class MroNode extends PythonUnaryBuiltinNode {
               static Object doit(Object klass,
                               @SuppressWarnings("unused") @Bind("this") Node inliningTarget,
                               @SuppressWarnings("unused") @Cached TypeNodes.IsTypeNode isTypeNode,
      -                        @Cached GetMroNode getMroNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Cached GetMroNode getMroNode) {
                   PythonAbstractClass[] mro = getMroNode.execute(inliningTarget, klass);
      -            return factory.createList(Arrays.copyOf(mro, mro.length, Object[].class));
      +            return PFactory.createList(PythonLanguage.get(inliningTarget), Arrays.copyOf(mro, mro.length, Object[].class));
               }
       
               @Fallback
               @SuppressWarnings("unused")
               static Object doit(Object object,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T_MRO, "type", object);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T_MRO, "type", object);
               }
           }
       
      -    @Builtin(name = J___INIT__, takesVarArgs = true, minNumOfPositionalArgs = 1, takesVarKeywordArgs = true)
      +    // type(object, bases, dict)
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true, needsFrame = true)
           @GenerateNodeFactory
      -    public abstract static class InitNode extends PythonVarargsBuiltinNode {
      -        @Child private SplitArgsNode splitArgsNode;
      +    public abstract static class TypeNode extends PythonVarargsBuiltinNode {
      +        @Child private IsSubtypeNode isSubtypeNode;
      +        @Child private TypeNodes.IsAcceptableBaseNode isAcceptableBaseNode;
      +        private final BranchProfile errorProfile = BranchProfile.create();
      +
      +        public abstract Object execute(VirtualFrame frame, Object cls, Object name, Object bases, Object dict, PKeyword[] kwds);
       
               @Override
      -        public final Object varArgExecute(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported {
      -            if (splitArgsNode == null) {
      -                CompilerDirectives.transferToInterpreterAndInvalidate();
      -                splitArgsNode = insert(SplitArgsNode.create());
      +        public final Object execute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) {
      +            if (arguments.length == 3) {
      +                return execute(frame, self, arguments[0], arguments[1], arguments[2], keywords);
      +            } else {
      +                errorProfile.enter();
      +                throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.TAKES_EXACTLY_D_ARGUMENTS_D_GIVEN, "type.__new__", 3, arguments.length);
                   }
      -            return execute(frame, arguments[0], splitArgsNode.executeCached(arguments), keywords);
               }
       
      -        @Specialization
      -        Object init(@SuppressWarnings("unused") Object self, Object[] arguments, @SuppressWarnings("unused") PKeyword[] kwds) {
      -            if (arguments.length != 1 && arguments.length != 3) {
      -                throw raise(TypeError, ErrorMessages.TAKES_D_OR_D_ARGS, "type.__init__()", 1, 3);
      +        @Specialization(guards = "isString(wName)")
      +        @SuppressWarnings("truffle-static-method")
      +        Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict namespaceOrig, PKeyword[] kwds,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached GetClassNode getClassNode,
      +                        @Cached GetCachedTpSlotsNode getSlots,
      +                        @Cached CallSlotTpNewNode callNew,
      +                        @Cached IsTypeNode isTypeNode,
      +                        @Cached PyObjectLookupAttr lookupMroEntriesNode,
      +                        @Cached CastToTruffleStringNode castStr,
      +                        @Cached TypeNodes.CreateTypeNode createType,
      +                        @Cached GetObjectArrayNode getObjectArrayNode) {
      +            // Determine the proper metatype to deal with this
      +            TruffleString name = castStr.execute(inliningTarget, wName);
      +            Object metaclass = cls;
      +            Object winner = calculateMetaclass(frame, inliningTarget, metaclass, bases, getClassNode, isTypeNode, lookupMroEntriesNode, getObjectArrayNode);
      +            if (winner != metaclass) {
      +                TpSlot winnerNew = getSlots.execute(inliningTarget, winner).tp_new();
      +                if (winnerNew != SLOTS.tp_new()) {
      +                    // Pass it to the winner
      +                    return callNew.execute(frame, inliningTarget, winnerNew, winner, new Object[]{name, bases, namespaceOrig}, kwds);
      +                }
      +                metaclass = winner;
                   }
      -            return PNone.NONE;
      -        }
      -    }
       
      -    @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      -    @GenerateNodeFactory
      -    public abstract static class CallNode extends PythonVarargsBuiltinNode {
      -        @Child CallNodeHelper callNodeHelper;
      +            return createType.execute(frame, namespaceOrig, name, bases, metaclass, kwds);
      +        }
       
      -        @NeverDefault
      -        public static CallNode create() {
      -            return CallNodeFactory.create();
      +        @Fallback
      +        Object generic(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") Object name, Object bases, Object namespace, @SuppressWarnings("unused") PKeyword[] kwds) {
      +            if (!(bases instanceof PTuple)) {
      +                throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "type.__new__()", 2, "tuple", bases);
      +            } else if (!(namespace instanceof PDict)) {
      +                throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "type.__new__()", 3, "dict", bases);
      +            } else {
      +                throw CompilerDirectives.shouldNotReachHere("type fallback reached incorrectly");
      +            }
               }
       
      -        @Override
      -        public final Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) {
      -            return execute(frame, self, arguments, keywords);
      +        private Object calculateMetaclass(VirtualFrame frame, Node inliningTarget, Object cls, PTuple bases, GetClassNode getClassNode, IsTypeNode isTypeNode,
      +                        PyObjectLookupAttr lookupMroEntries, GetObjectArrayNode getObjectArrayNode) {
      +            Object winner = cls;
      +            for (Object base : getObjectArrayNode.execute(inliningTarget, bases)) {
      +                if (!isTypeNode.execute(inliningTarget, base) && lookupMroEntries.execute(frame, inliningTarget, base, T___MRO_ENTRIES__) != NO_VALUE) {
      +                    throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.TYPE_DOESNT_SUPPORT_MRO_ENTRY_RESOLUTION);
      +                }
      +                if (!ensureIsAcceptableBaseNode().execute(base)) {
      +                    throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.TYPE_IS_NOT_ACCEPTABLE_BASE_TYPE, base);
      +                }
      +                Object typ = getClassNode.execute(inliningTarget, base);
      +                if (isSubType(winner, typ)) {
      +                    continue;
      +                } else if (isSubType(typ, winner)) {
      +                    winner = typ;
      +                    continue;
      +                }
      +                throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.METACLASS_CONFLICT);
      +            }
      +            return winner;
               }
       
      -        private CallNodeHelper getCallNodeHelper() {
      -            if (callNodeHelper == null) {
      +        protected boolean isSubType(Object subclass, Object superclass) {
      +            if (isSubtypeNode == null) {
                       CompilerDirectives.transferToInterpreterAndInvalidate();
      -                callNodeHelper = insert(CallNodeHelperNodeGen.create());
      +                isSubtypeNode = insert(IsSubtypeNode.create());
                   }
      -            return callNodeHelper;
      +            return isSubtypeNode.execute(subclass, superclass);
      +        }
      +
      +        @NeverDefault
      +        public static TypeNode create() {
      +            return TypeNodeFactory.create();
               }
       
      -        @Specialization(guards = "isNoValue(self)")
      -        Object selfInArgs(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] arguments, PKeyword[] keywords,
      +        @Specialization(guards = {"!isNoValue(bases)", "!isNoValue(dict)"})
      +        Object typeGeneric(VirtualFrame frame, Object cls, Object name, Object bases, Object dict, PKeyword[] kwds,
                               @Bind("this") Node inliningTarget,
      -                        @Cached CallNodeHelper callNodeHelper,
      -                        @Cached SplitArgsNode splitArgsNode,
      -                        @Exclusive @Cached IsSameTypeNode isSameTypeNode,
      -                        @Exclusive @Cached GetClassNode getClassNode) {
      -            if (isSameTypeNode.execute(inliningTarget, PythonBuiltinClassType.PythonClass, arguments[0])) {
      -                if (arguments.length == 2 && keywords.length == 0) {
      -                    return getClassNode.execute(inliningTarget, arguments[1]);
      -                } else if (arguments.length != 4) {
      -                    throw raise(TypeError, ErrorMessages.TAKES_D_OR_D_ARGS, "type()", 1, 3);
      -                }
      +                        @Cached TypeNode nextTypeNode,
      +                        @Cached PRaiseNode raiseNode,
      +                        @Exclusive @Cached IsTypeNode isTypeNode) {
      +            if (!(name instanceof TruffleString || name instanceof PString)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_STRINGS_NOT_P, "type() argument 1", name);
      +            } else if (!(bases instanceof PTuple)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_STRINGS_NOT_P, "type() argument 2", bases);
      +            } else if (!(dict instanceof PDict)) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_STRINGS_NOT_P, "type() argument 3", dict);
      +            } else if (!isTypeNode.execute(inliningTarget, cls)) {
      +                // TODO: this is actually allowed, deal with it
      +                throw raiseNode.raise(inliningTarget, NotImplementedError, ErrorMessages.CREATING_CLASS_NON_CLS_META_CLS);
      +            }
      +            return nextTypeNode.execute(frame, cls, name, bases, dict, kwds);
      +        }
      +
      +        private TypeNodes.IsAcceptableBaseNode ensureIsAcceptableBaseNode() {
      +            if (isAcceptableBaseNode == null) {
      +                CompilerDirectives.transferToInterpreterAndInvalidate();
      +                isAcceptableBaseNode = insert(TypeNodes.IsAcceptableBaseNode.create());
                   }
      -            return callNodeHelper.execute(frame, arguments[0], splitArgsNode.execute(inliningTarget, arguments), keywords);
      +            return isAcceptableBaseNode;
               }
      +    }
       
      -        @Fallback
      -        Object selfSeparate(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords,
      +    @Slot(value = SlotKind.tp_init, isComplex = true)
      +    @SlotSignature(takesVarArgs = true, minNumOfPositionalArgs = 1, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class InitNode extends PythonVarargsBuiltinNode {
      +
      +        @Specialization
      +        static Object init(@SuppressWarnings("unused") Object self, Object[] arguments, PKeyword[] kwds,
      +                        @Bind Node inliningTarget,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (arguments.length != 1 && arguments.length != 3) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TAKES_D_OR_D_ARGS, "type.__init__()", 1, 3);
      +            }
      +            if (arguments.length == 1 && kwds.length != 0) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_TAKES_NO_KEYWORD_ARGS, "type.__init__()");
      +            }
      +            return PNone.NONE;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_call, isComplex = true)
      +    @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @GenerateNodeFactory
      +    public abstract static class CallNode extends PythonVarargsBuiltinNode {
      +
      +        @Specialization
      +        Object call(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords,
                               @Bind("this") Node inliningTarget,
      -                        @Exclusive @Cached IsSameTypeNode isSameTypeNode,
      -                        @Exclusive @Cached GetClassNode getClassNode) {
      +                        @Cached IsSameTypeNode isSameTypeNode,
      +                        @Cached GetClassNode getClassNode,
      +                        @Cached PRaiseNode raiseNode,
      +                        @Cached CreateInstanceNode createInstanceNode) {
                   if (isSameTypeNode.execute(inliningTarget, PythonBuiltinClassType.PythonClass, self)) {
                       if (arguments.length == 1 && keywords.length == 0) {
                           return getClassNode.execute(inliningTarget, arguments[0]);
                       } else if (arguments.length != 3) {
      -                    throw raise(TypeError, ErrorMessages.TAKES_D_OR_D_ARGS, "type()", 1, 3);
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TAKES_D_OR_D_ARGS, "type()", 1, 3);
                       }
                   }
      -            return getCallNodeHelper().execute(frame, self, arguments, keywords);
      +            return createInstanceNode.execute(frame, inliningTarget, self, arguments, keywords);
               }
           }
       
           @GenerateInline
           @GenerateCached(false)
      -    @GenerateUncached
      -    public abstract static class BindNew extends PNodeWithContext {
      -        public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object descriptor, Object type);
      -
      -        @Specialization
      -        static Object doBuiltinMethod(PBuiltinMethod descriptor, @SuppressWarnings("unused") Object type) {
      -            return descriptor;
      -        }
      +    protected abstract static class CreateInstanceNode extends PNodeWithContext {
       
      -        @Specialization
      -        static Object doBuiltinDescriptor(BuiltinMethodDescriptor descriptor, @SuppressWarnings("unused") Object type) {
      -            return descriptor;
      -        }
      +        abstract Object execute(VirtualFrame frame, Node inliningTarget, Object self, Object[] args, PKeyword[] keywords);
       
               @Specialization
      -        static Object doFunction(PFunction descriptor, @SuppressWarnings("unused") Object type) {
      -            return descriptor;
      -        }
      -
      -        @Fallback
      -        static Object doBind(VirtualFrame frame, Node inliningTarget, Object descriptor, Object type,
      -                        @Cached GetObjectSlotsNode getSlotsNode,
      -                        @Cached CallSlotDescrGet callGetSlot) {
      -            var getMethod = getSlotsNode.execute(inliningTarget, descriptor).tp_descr_get();
      -            if (getMethod != null) {
      -                return callGetSlot.execute(frame, inliningTarget, getMethod, descriptor, NO_VALUE, type);
      +        static Object doGeneric(VirtualFrame frame, Node inliningTarget, Object type, Object[] arguments, PKeyword[] keywords,
      +                        @Cached InlinedConditionProfile builtinProfile,
      +                        @Cached GetCachedTpSlotsNode getTypeSlots,
      +                        @Cached GetCachedTpSlotsNode getInstanceSlots,
      +                        @Cached GetClassNode getInstanceClassNode,
      +                        @Cached IsSubtypeNode isSubtypeNode,
      +                        @Cached CallSlotTpNewNode callNew,
      +                        @Cached CallSlotTpInitNode callInit,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (builtinProfile.profile(inliningTarget, type instanceof PythonBuiltinClass)) {
      +                // PythonBuiltinClassType should help the code after this to optimize better
      +                type = ((PythonBuiltinClass) type).getType();
                   }
      -            return descriptor;
      -        }
      -    }
      -
      -    @ReportPolymorphism
      -    protected abstract static class CallNodeHelper extends PNodeWithContext {
      -        @Child private CallVarargsMethodNode dispatchNew = CallVarargsMethodNode.create();
      -        @Child private LookupCallableSlotInMRONode lookupNew = LookupCallableSlotInMRONode.create(SpecialMethodSlot.New);
      -        @Child private CallVarargsMethodNode dispatchInit;
      -        @Child private LookupSpecialMethodSlotNode lookupInit;
      -        @Child private IsSubtypeNode isSubTypeNode;
      -        @Child private TypeNodes.GetNameNode getNameNode;
      -
      -        abstract Object execute(VirtualFrame frame, Object self, Object[] args, PKeyword[] keywords);
      -
      -        @Specialization(limit = "getCallSiteInlineCacheMaxDepth()", guards = {"isSingleContext()", "self == cachedSelf"})
      -        protected Object doIt0BuiltinSingle(VirtualFrame frame, @SuppressWarnings("unused") PythonBuiltinClass self, Object[] arguments, PKeyword[] keywords,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached("self") PythonBuiltinClass cachedSelf,
      -                        @Shared @Cached GetClassNode getInstanceClassNode,
      -                        @Shared @Cached InlinedConditionProfile hasInit,
      -                        @Shared @Cached InlinedConditionProfile gotInitResult,
      -                        @Shared @Cached BindNew bindNew,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            PythonBuiltinClassType type = cachedSelf.getType();
      -            return op(frame, inliningTarget, type, arguments, keywords, getInstanceClassNode, hasInit, gotInitResult, bindNew, raiseNode);
      -        }
      -
      -        @Specialization(limit = "getCallSiteInlineCacheMaxDepth()", guards = {"isSingleContext()", "self == cachedSelf"})
      -        protected Object doIt0User(VirtualFrame frame, @SuppressWarnings("unused") PythonClass self, Object[] arguments, PKeyword[] keywords,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached(value = "self", weak = true) PythonClass cachedSelf,
      -                        @Shared @Cached GetClassNode getInstanceClassNode,
      -                        @Shared @Cached InlinedConditionProfile hasInit,
      -                        @Shared @Cached InlinedConditionProfile gotInitResult,
      -                        @Shared @Cached BindNew bindNew,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            return op(frame, inliningTarget, cachedSelf, arguments, keywords, getInstanceClassNode, hasInit, gotInitResult, bindNew, raiseNode);
      -        }
      -
      -        @Specialization(limit = "getCallSiteInlineCacheMaxDepth()", guards = {"self.getType() == cachedType"})
      -        protected Object doIt0BuiltinMulti(VirtualFrame frame, @SuppressWarnings("unused") PythonBuiltinClass self, Object[] arguments, PKeyword[] keywords,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached("self.getType()") PythonBuiltinClassType cachedType,
      -                        @Shared @Cached GetClassNode getInstanceClassNode,
      -                        @Shared @Cached InlinedConditionProfile hasInit,
      -                        @Shared @Cached InlinedConditionProfile gotInitResult,
      -                        @Shared @Cached BindNew bindNew,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            return op(frame, inliningTarget, cachedType, arguments, keywords, getInstanceClassNode, hasInit, gotInitResult, bindNew, raiseNode);
      -        }
      -
      -        @Specialization(limit = "getCallSiteInlineCacheMaxDepth()", guards = {"self == cachedType"})
      -        protected Object doIt0BuiltinType(VirtualFrame frame, @SuppressWarnings("unused") PythonBuiltinClassType self, Object[] arguments, PKeyword[] keywords,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached("self") PythonBuiltinClassType cachedType,
      -                        @Shared @Cached GetClassNode getInstanceClassNode,
      -                        @Shared @Cached InlinedConditionProfile hasInit,
      -                        @Shared @Cached InlinedConditionProfile gotInitResult,
      -                        @Shared @Cached BindNew bindNew,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            return op(frame, inliningTarget, cachedType, arguments, keywords, getInstanceClassNode, hasInit, gotInitResult, bindNew, raiseNode);
      -        }
      -
      -        @Specialization(replaces = {"doIt0BuiltinSingle", "doIt0BuiltinMulti"})
      -        protected Object doItIndirect0Builtin(VirtualFrame frame, PythonBuiltinClass self, Object[] arguments, PKeyword[] keywords,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared @Cached GetClassNode getInstanceClassNode,
      -                        @Shared @Cached InlinedConditionProfile hasInit,
      -                        @Shared @Cached InlinedConditionProfile gotInitResult,
      -                        @Shared @Cached BindNew bindNew,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            PythonBuiltinClassType type = self.getType();
      -            return op(frame, inliningTarget, type, arguments, keywords, getInstanceClassNode, hasInit, gotInitResult, bindNew, raiseNode);
      -        }
      -
      -        @Specialization(replaces = "doIt0BuiltinType")
      -        protected Object doItIndirect0BuiltinType(VirtualFrame frame, PythonBuiltinClassType self, Object[] arguments, PKeyword[] keywords,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared @Cached GetClassNode getInstanceClassNode,
      -                        @Shared @Cached InlinedConditionProfile hasInit,
      -                        @Shared @Cached InlinedConditionProfile gotInitResult,
      -                        @Shared @Cached BindNew bindNew,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            return op(frame, inliningTarget, self, arguments, keywords, getInstanceClassNode, hasInit, gotInitResult, bindNew, raiseNode);
      -        }
      -
      -        @Specialization(replaces = {"doIt0User"})
      -        protected Object doItIndirect0User(VirtualFrame frame, PythonClass self, Object[] arguments, PKeyword[] keywords,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared @Cached GetClassNode getInstanceClassNode,
      -                        @Shared @Cached InlinedConditionProfile hasInit,
      -                        @Shared @Cached InlinedConditionProfile gotInitResult,
      -                        @Shared @Cached BindNew bindNew,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            return op(frame, inliningTarget, self, arguments, keywords, getInstanceClassNode, hasInit, gotInitResult, bindNew, raiseNode);
      -        }
      -
      -        /* self is native */
      -        @Specialization(limit = "getCallSiteInlineCacheMaxDepth()", guards = {"isSingleContext()", "self == cachedSelf"})
      -        protected Object doIt1(VirtualFrame frame, @SuppressWarnings("unused") PythonAbstractNativeObject self, Object[] arguments, PKeyword[] keywords,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached("self") PythonAbstractNativeObject cachedSelf,
      -                        @Shared @Cached GetClassNode getInstanceClassNode,
      -                        @Shared @Cached GetTypeFlagsNode getTypeFlagsNode,
      -                        @Shared @Cached InlinedConditionProfile hasInit,
      -                        @Shared @Cached InlinedConditionProfile gotInitResult,
      -                        @Shared @Cached BindNew bindNew,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            checkFlags(self, inliningTarget, getTypeFlagsNode, raiseNode);
      -            return op(frame, inliningTarget, PythonNativeClass.cast(cachedSelf), arguments, keywords, getInstanceClassNode, hasInit, gotInitResult, bindNew, raiseNode);
      -        }
      -
      -        @Specialization(replaces = "doIt1")
      -        protected Object doItIndirect1(VirtualFrame frame, PythonAbstractNativeObject self, Object[] arguments, PKeyword[] keywords,
      -                        @Bind("this") Node inliningTarget,
      -                        @Shared @Cached GetClassNode getInstanceClassNode,
      -                        @Shared @Cached GetTypeFlagsNode getTypeFlagsNode,
      -                        @Shared @Cached InlinedConditionProfile hasInit,
      -                        @Shared @Cached InlinedConditionProfile gotInitResult,
      -                        @Shared @Cached BindNew bindNew,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      -            checkFlags(self, inliningTarget, getTypeFlagsNode, raiseNode);
      -            return op(frame, inliningTarget, PythonNativeClass.cast(self), arguments, keywords, getInstanceClassNode, hasInit, gotInitResult, bindNew, raiseNode);
      -        }
      -
      -        private void checkFlags(PythonAbstractNativeObject self, Node inliningTarget, GetTypeFlagsNode getTypeFlagsNode, PRaiseNode.Lazy raiseNode) {
      -            if ((getTypeFlagsNode.execute(self) & TypeFlags.DISALLOW_INSTANTIATION) != 0) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANNOT_CREATE_INSTANCES, getTypeName(self));
      +            TpSlots typeSlots = getTypeSlots.execute(inliningTarget, type);
      +            if (typeSlots.tp_new() == null) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANNOT_CREATE_N_INSTANCES, type);
                   }
      -        }
      -
      -        private Object op(VirtualFrame frame, Node inliningTarget, Object self, Object[] arguments, PKeyword[] keywords, GetClassNode getInstanceClassNode,
      -                        InlinedConditionProfile hasInit, InlinedConditionProfile gotInitResult, BindNew bindNew, PRaiseNode.Lazy raiseNode) {
      -            Object newMethod = lookupNew.execute(self);
      -            assert newMethod != NO_VALUE;
      -            Object[] newArgs = PythonUtils.prependArgument(self, arguments);
      -            Object newInstance = dispatchNew.execute(frame, bindNew.execute(frame, inliningTarget, newMethod, self), newArgs, keywords);
      -            callInit(inliningTarget, newInstance, self, frame, arguments, keywords, getInstanceClassNode, hasInit, gotInitResult, raiseNode);
      -            return newInstance;
      -        }
      -
      -        private void callInit(Node inliningTarget, Object newInstance, Object self, VirtualFrame frame, Object[] arguments, PKeyword[] keywords, GetClassNode getInstanceClassNode,
      -                        InlinedConditionProfile hasInit, InlinedConditionProfile gotInitResult, PRaiseNode.Lazy raiseNode) {
      +            Object newInstance = callNew.execute(frame, inliningTarget, typeSlots.tp_new(), type, arguments, keywords);
                   Object newInstanceKlass = getInstanceClassNode.execute(inliningTarget, newInstance);
      -            if (isSubType(newInstanceKlass, self)) {
      -                Object initMethod = getInitNode().execute(frame, newInstanceKlass, newInstance);
      -                if (hasInit.profile(inliningTarget, initMethod != NO_VALUE)) {
      -                    Object[] initArgs = PythonUtils.prependArgument(newInstance, arguments);
      -                    Object initResult = getDispatchNode().execute(frame, initMethod, initArgs, keywords);
      -                    if (gotInitResult.profile(inliningTarget, initResult != PNone.NONE && initResult != NO_VALUE)) {
      -                        throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.SHOULD_RETURN_NONE, "__init__()");
      -                    }
      +            if (isSubtypeNode.execute(newInstanceKlass, type)) {
      +                TpSlots instanceSlots = getInstanceSlots.execute(inliningTarget, newInstanceKlass);
      +                if (instanceSlots.tp_init() != null) {
      +                    callInit.execute(frame, inliningTarget, instanceSlots.tp_init(), newInstance, arguments, keywords);
                       }
                   }
      -        }
      -
      -        private LookupSpecialMethodSlotNode getInitNode() {
      -            if (lookupInit == null) {
      -                CompilerDirectives.transferToInterpreterAndInvalidate();
      -                lookupInit = insert(LookupSpecialMethodSlotNode.create(SpecialMethodSlot.Init));
      -            }
      -            return lookupInit;
      -        }
      -
      -        private CallVarargsMethodNode getDispatchNode() {
      -            if (dispatchInit == null) {
      -                CompilerDirectives.transferToInterpreterAndInvalidate();
      -                dispatchInit = insert(CallVarargsMethodNode.create());
      -            }
      -            return dispatchInit;
      -        }
      -
      -        private boolean isSubType(Object left, Object right) {
      -            if (isSubTypeNode == null) {
      -                CompilerDirectives.transferToInterpreterAndInvalidate();
      -                isSubTypeNode = insert(IsSubtypeNode.create());
      -            }
      -            return isSubTypeNode.execute(left, right);
      -        }
      -
      -        private TruffleString getTypeName(Object clazz) {
      -            if (getNameNode == null) {
      -                CompilerDirectives.transferToInterpreterAndInvalidate();
      -                getNameNode = insert(TypeNodes.GetNameNode.create());
      -            }
      -            return getNameNode.executeCached(clazz);
      +            return newInstance;
               }
           }
       
      @@ -657,12 +533,12 @@ protected Object doIt(VirtualFrame frame, Object object, Object keyObj,
                               @Cached InlinedBranchProfile hasValueProfile,
                               @Cached InlinedBranchProfile hasNonDescriptorValueProfile,
                               @Cached InlinedBranchProfile errorProfile,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   TruffleString key;
                   try {
                       key = castToString.execute(inliningTarget, keyObj);
                   } catch (CannotCastException e) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj);
                   }
       
                   Object metatype = getClassNode.execute(inliningTarget, object);
      @@ -699,7 +575,7 @@ protected Object doIt(VirtualFrame frame, Object object, Object keyObj,
                       }
                   }
                   errorProfile.enter(inliningTarget);
      -            throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.OBJ_N_HAS_NO_ATTR_S, object, key);
      +            throw raiseNode.raiseWithData(inliningTarget, AttributeError, AttributeErrorBuiltins.dataForObjKey(object, key), ErrorMessages.OBJ_N_HAS_NO_ATTR_S, object, key);
               }
       
               private Object readAttribute(Object object, TruffleString key) {
      @@ -753,7 +629,7 @@ static void set(VirtualFrame frame, Object object, Object key, Object value,
               @TruffleBoundary
               void setBuiltin(Object object, Object key, Object value) {
                   if (PythonContext.get(this).isInitialized()) {
      -                throw PRaiseNode.raiseUncached(this, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, PyObjectReprAsTruffleStringNode.executeUncached(key), object);
      +                throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, PyObjectReprAsTruffleStringNode.executeUncached(key), object);
                   } else {
                       set(null, object, key, value, null, ObjectNodes.GenericSetAttrNode.getUncached(), WriteAttributeToObjectNode.getUncached(true));
                   }
      @@ -771,8 +647,8 @@ public abstract static class PrepareNode extends PythonBuiltinNode {
               @SuppressWarnings("unused")
               @Specialization
               Object doIt(Object args, Object kwargs,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createDict(new DynamicObjectStorage(PythonLanguage.get(this)));
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createDict(language, new DynamicObjectStorage(language));
               }
           }
       
      @@ -784,15 +660,14 @@ abstract static class BasesNode extends PythonBinaryBuiltinNode {
               @Specialization
               static Object getBases(Object self, @SuppressWarnings("unused") PNone value,
                               @Bind("this") Node inliningTarget,
      -                        @Cached TypeNodes.GetBaseClassesNode getBaseClassesNode,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createTuple(getBaseClassesNode.execute(inliningTarget, self));
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetBaseClassesNode getBaseClassesNode) {
      +            return PFactory.createTuple(language, getBaseClassesNode.execute(inliningTarget, self));
               }
       
               @Specialization
               static Object setBases(VirtualFrame frame, PythonClass cls, PTuple value,
                               @Bind("this") Node inliningTarget,
      -                        @Cached GetNameNode getName,
                               @Cached GetObjectArrayNode getArray,
                               @Cached GetBaseClassNode getBase,
                               @Cached GetBestBaseClassNode getBestBase,
      @@ -800,18 +675,18 @@ static Object setBases(VirtualFrame frame, PythonClass cls, PTuple value,
                               @Cached IsSubtypeNode isSubtypeNode,
                               @Cached IsSameTypeNode isSameTypeNode,
                               @Cached GetMroNode getMroNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
       
                   Object[] a = getArray.execute(inliningTarget, value);
                   if (a.length == 0) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CAN_ONLY_ASSIGN_NON_EMPTY_TUPLE_TO_P, cls);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CAN_ONLY_ASSIGN_NON_EMPTY_TUPLE_TO_P, cls);
                   }
                   PythonAbstractClass[] baseClasses = new PythonAbstractClass[a.length];
                   for (int i = 0; i < a.length; i++) {
                       if (PGuards.isPythonClass(a[i])) {
      -                    if (isSubtypeNode.execute(frame, a[i], cls) ||
      +                    if (isSubtypeNode.execute(a[i], cls) ||
                                           hasMRO(inliningTarget, getMroNode, a[i]) && typeIsSubtypeBaseChain(inliningTarget, a[i], cls, getBase, isSameTypeNode)) {
      -                        throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.BASES_ITEM_CAUSES_INHERITANCE_CYCLE);
      +                        throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.BASES_ITEM_CAUSES_INHERITANCE_CYCLE);
                           }
                           if (a[i] instanceof PythonBuiltinClassType) {
                               baseClasses[i] = PythonContext.get(inliningTarget).lookupType((PythonBuiltinClassType) a[i]);
      @@ -819,7 +694,7 @@ static Object setBases(VirtualFrame frame, PythonClass cls, PTuple value,
                               baseClasses[i] = (PythonAbstractClass) a[i];
                           }
                       } else {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MUST_BE_TUPLE_OF_CLASSES_NOT_P, getName.execute(inliningTarget, cls), "__bases__", a[i]);
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_TUPLE_OF_CLASSES_NOT_P, cls, "__bases__", a[i]);
                       }
                   }
       
      @@ -831,8 +706,7 @@ static Object setBases(VirtualFrame frame, PythonClass cls, PTuple value,
                   Object oldBase = getBase.execute(inliningTarget, cls);
                   checkCompatibleForAssigment.execute(frame, oldBase, newBestBase);
       
      -            cls.setBases(newBestBase, baseClasses);
      -            SpecialMethodSlot.reinitializeSpecialMethodSlots(cls, PythonLanguage.get(inliningTarget));
      +            cls.setBases(inliningTarget, newBestBase, baseClasses);
                   TpSlots.updateAllSlots(cls);
       
                   return PNone.NONE;
      @@ -857,14 +731,14 @@ private static boolean typeIsSubtypeBaseChain(Node inliningTarget, Object a, Obj
       
               @Specialization(guards = "!isPTuple(value)")
               static Object setObject(@SuppressWarnings("unused") PythonClass cls, @SuppressWarnings("unused") Object value,
      -                        @Shared @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.CAN_ONLY_ASSIGN_S_TO_S_S_NOT_P, "tuple", GetNameNode.executeUncached(cls), "__bases__", value);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CAN_ONLY_ASSIGN_S_TO_S_S_NOT_P, "tuple", GetNameNode.executeUncached(cls), "__bases__", value);
               }
       
               @Specialization
               static Object setBuiltin(@SuppressWarnings("unused") PythonBuiltinClass cls, @SuppressWarnings("unused") Object value,
      -                        @Shared @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, J___BASES__, cls);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, J___BASES__, cls);
               }
       
           }
      @@ -886,25 +760,25 @@ static Object base(Object self,
           abstract static class DictNode extends PythonUnaryBuiltinNode {
               @Specialization
               Object doType(PythonBuiltinClassType self,
      -                        @Shared @Cached GetDictIfExistsNode getDict,
      -                        @Shared @Cached PythonObjectFactory factory) {
      -            return doManaged(getContext().lookupType(self), getDict, factory);
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached GetDictIfExistsNode getDict) {
      +            return doManaged(getContext().lookupType(self), language, getDict);
               }
       
               @Specialization
               static Object doManaged(PythonManagedClass self,
      -                        @Shared @Cached GetDictIfExistsNode getDict,
      -                        @Shared @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language,
      +                        @Shared @Cached GetDictIfExistsNode getDict) {
                   PDict dict = getDict.execute(self);
                   if (dict == null) {
      -                dict = factory.createDictFixedStorage(self, self.getMethodResolutionOrder());
      +                dict = PFactory.createDictFixedStorage(language, self, self.getMethodResolutionOrder());
                       // The mapping is unmodifiable, so we don't have to assign it back
                   }
      -            return factory.createMappingproxy(dict);
      +            return PFactory.createMappingproxy(language, dict);
               }
       
               @Specialization
      -        static Object doNative(PythonNativeClass self,
      +        static Object doNative(PythonAbstractNativeObject self,
                               @Cached CStructAccess.ReadObjectNode getTpDictNode) {
                   return getTpDictNode.readFromObj(self, CFields.PyTypeObject__tp_dict);
               }
      @@ -912,56 +786,13 @@ static Object doNative(PythonNativeClass self,
       
           @Builtin(name = J___INSTANCECHECK__, minNumOfPositionalArgs = 2)
           @GenerateNodeFactory
      -    public abstract static class InstanceCheckNode extends PythonBinaryBuiltinNode {
      -        @Child private PyObjectLookupAttr getAttributeNode;
      -
      -        public abstract boolean executeWith(VirtualFrame frame, Object cls, Object instance);
      -
      -        public PyObjectLookupAttr getGetAttributeNode() {
      -            if (getAttributeNode == null) {
      -                CompilerDirectives.transferToInterpreterAndInvalidate();
      -                getAttributeNode = insert(PyObjectLookupAttr.create());
      -            }
      -            return getAttributeNode;
      -        }
      -
      -        private PythonObject getInstanceClassAttr(VirtualFrame frame, Object instance) {
      -            Object classAttr = getGetAttributeNode().executeCached(frame, instance, T___CLASS__);
      -            if (classAttr instanceof PythonObject) {
      -                return (PythonObject) classAttr;
      -            }
      -            return null;
      -        }
      +    abstract static class InstanceCheckNode extends PythonBinaryBuiltinNode {
       
      -        @Specialization(guards = "isTypeNode.execute(inliningTarget, cls)", limit = "1")
      -        @SuppressWarnings("truffle-static-method")
      -        boolean isInstance(VirtualFrame frame, Object cls, Object instance,
      +        @Specialization
      +        static boolean isInstance(VirtualFrame frame, Object cls, Object instance,
                               @Bind("this") Node inliningTarget,
      -                        @SuppressWarnings("unused") @Cached TypeNodes.IsTypeNode isTypeNode,
      -                        @Cached GetClassNode getClassNode,
      -                        @Cached IsSubtypeNode isSubtypeNode) {
      -            if (instance instanceof PythonObject && isSubtypeNode.execute(frame, getClassNode.execute(inliningTarget, instance), cls)) {
      -                return true;
      -            }
      -
      -            Object instanceClass = getGetAttributeNode().executeCached(frame, instance, T___CLASS__);
      -            return PGuards.isManagedClass(instanceClass) && isSubtypeNode.execute(frame, instanceClass, cls);
      -        }
      -
      -        @Fallback
      -        @SuppressWarnings("truffle-static-method")
      -        boolean isInstance(VirtualFrame frame, Object cls, Object instance,
      -                        @Bind("this") Node inliningTarget,
      -                        @Cached InlinedConditionProfile typeErrorProfile,
      -                        @Cached AbstractObjectIsSubclassNode abstractIsSubclassNode,
      -                        @Cached AbstractObjectGetBasesNode getBasesNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      -            if (typeErrorProfile.profile(inliningTarget, getBasesNode.execute(frame, cls) == null)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ISINSTANCE_ARG_2_MUST_BE_TYPE_OR_TUPLE_OF_TYPE, instance);
      -            }
      -
      -            PythonObject instanceClass = getInstanceClassAttr(frame, instance);
      -            return instanceClass != null && abstractIsSubclassNode.execute(frame, instanceClass, cls);
      +                        @Cached TypeNodes.GenericInstanceCheckNode genericInstanceCheckNode) {
      +            return genericInstanceCheckNode.execute(frame, inliningTarget, instance, cls);
               }
           }
       
      @@ -969,54 +800,11 @@ boolean isInstance(VirtualFrame frame, Object cls, Object instance,
           @GenerateNodeFactory
           abstract static class SubclassCheckNode extends PythonBinaryBuiltinNode {
       
      -        @Specialization(guards = {"!isNativeClass(cls)", "!isNativeClass(derived)"})
      -        static boolean doManagedManaged(VirtualFrame frame, Object cls, Object derived,
      -                        @Bind("this") Node inliningTarget,
      -                        @Exclusive @Cached IsSameTypeNode isSameTypeNode,
      -                        @Exclusive @Cached IsSubtypeNode isSubtypeNode) {
      -            return isSameTypeNode.execute(inliningTarget, cls, derived) || isSubtypeNode.execute(frame, derived, cls);
      -        }
      -
               @Specialization
      -        static boolean doObjectObject(VirtualFrame frame, Object cls, Object derived,
      +        static boolean check(VirtualFrame frame, Object cls, Object derived,
                               @Bind("this") Node inliningTarget,
      -                        @Exclusive @Cached IsSameTypeNode isSameTypeNode,
      -                        @Exclusive @Cached IsSubtypeNode isSubtypeNode,
      -                        @Cached IsBuiltinObjectProfile isAttrErrorProfile,
      -                        @Cached("create(T___BASES__)") GetFixedAttributeNode getBasesAttrNode,
      -                        @Cached PyTupleCheckNode tupleCheck,
      -                        @Cached TypeNodes.IsTypeNode isClsTypeNode,
      -                        @Cached TypeNodes.IsTypeNode isDerivedTypeNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      -            if (isSameTypeNode.execute(inliningTarget, cls, derived)) {
      -                return true;
      -            }
      -
      -            // no profiles required because IsTypeNode profiles already
      -            if (isClsTypeNode.execute(inliningTarget, cls) && isDerivedTypeNode.execute(inliningTarget, derived)) {
      -                return isSubtypeNode.execute(frame, derived, cls);
      -            }
      -            if (!checkClass(frame, inliningTarget, derived, getBasesAttrNode, tupleCheck, isAttrErrorProfile)) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ARG_D_MUST_BE_S, "issubclass()", 1, "class");
      -            }
      -            if (!checkClass(frame, inliningTarget, cls, getBasesAttrNode, tupleCheck, isAttrErrorProfile)) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.ISSUBCLASS_MUST_BE_CLASS_OR_TUPLE);
      -            }
      -            return false;
      -        }
      -
      -        // checks if object has '__bases__' (see CPython 'abstract.c' function
      -        // 'recursive_issubclass')
      -        private static boolean checkClass(VirtualFrame frame, Node inliningTarget, Object obj, GetFixedAttributeNode getBasesAttrNode, PyTupleCheckNode tupleCheck,
      -                        IsBuiltinObjectProfile isAttrErrorProfile) {
      -            Object basesObj;
      -            try {
      -                basesObj = getBasesAttrNode.executeObject(frame, obj);
      -            } catch (PException e) {
      -                e.expectAttributeError(inliningTarget, isAttrErrorProfile);
      -                return false;
      -            }
      -            return tupleCheck.execute(inliningTarget, basesObj);
      +                        @Cached TypeNodes.GenericSubclassCheckNode genericSubclassCheckNode) {
      +            return genericSubclassCheckNode.execute(frame, inliningTarget, derived, cls);
               }
           }
       
      @@ -1037,18 +825,16 @@ abstract static class SubclassesNode extends PythonUnaryBuiltinNode {
               @Specialization
               static PList getSubclasses(Object cls,
                               @Bind("this") Node inliningTarget,
      -                        @Cached(inline = true) GetSubclassesAsArrayNode getSubclassesNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Cached(inline = true) GetSubclassesAsArrayNode getSubclassesNode) {
                   // TODO: missing: keep track of subclasses
                   PythonAbstractClass[] array = getSubclassesNode.execute(inliningTarget, cls);
                   Object[] classes = new Object[array.length];
                   PythonUtils.arraycopy(array, 0, classes, 0, array.length);
      -            return factory.createList(classes);
      +            return PFactory.createList(PythonLanguage.get(inliningTarget), classes);
               }
           }
       
           @GenerateNodeFactory
      -    @TypeSystemReference(PythonTypes.class)
           abstract static class AbstractSlotNode extends PythonBinaryBuiltinNode {
           }
       
      @@ -1059,15 +845,15 @@ abstract static class CheckSetSpecialTypeAttrNode extends Node {
       
               @Specialization
               static void check(Node inliningTarget, Object type, Object value, TruffleString name,
      -                        @Cached PRaiseNode.Lazy raiseNode,
      +                        @Cached PRaiseNode raiseNode,
                               @Cached(inline = false) GetTypeFlagsNode getTypeFlagsNode,
                               @Cached SysModuleBuiltins.AuditNode auditNode) {
                   if (PGuards.isKindOfBuiltinClass(type) || (getTypeFlagsNode.execute(type) & TypeFlags.IMMUTABLETYPE) != 0) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, name, type);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, name, type);
                   }
                   if (value == DescriptorDeleteMarker.INSTANCE) {
                       // Sic, it's not immutable, but CPython has this message
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANT_DELETE_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, name, type);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_DELETE_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, name, type);
                   }
                   auditNode.audit(inliningTarget, "object.__setattr__", type, name, value);
               }
      @@ -1077,29 +863,10 @@ static void check(Node inliningTarget, Object type, Object value, TruffleString
                           allowsDelete = true /* Delete handled by CheckSetSpecialTypeAttrNode */)
           abstract static class NameNode extends AbstractSlotNode {
               @Specialization(guards = "isNoValue(value)")
      -        static TruffleString getNameType(PythonBuiltinClassType cls, @SuppressWarnings("unused") PNone value) {
      -            return cls.getName();
      -        }
      -
      -        @Specialization(guards = "isNoValue(value)")
      -        static TruffleString getNameBuiltin(PythonManagedClass cls, @SuppressWarnings("unused") PNone value) {
      -            return cls.getName();
      -        }
      -
      -        @Specialization(guards = "isNoValue(value)")
      -        static Object getName(PythonAbstractNativeObject cls, @SuppressWarnings("unused") PNone value,
      -                        @Cached CStructAccess.ReadCharPtrNode getTpNameNode,
      -                        @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode,
      -                        @Cached TruffleString.LastIndexOfCodePointNode indexOfCodePointNode,
      -                        @Cached TruffleString.SubstringNode substringNode) {
      -            // 'tp_name' contains the fully-qualified name, i.e., 'module.A.B...'
      -            TruffleString tpName = getTpNameNode.readFromObj(cls, PyTypeObject__tp_name);
      -            int nameLen = codePointLengthNode.execute(tpName, TS_ENCODING);
      -            int lastDot = indexOfCodePointNode.execute(tpName, '.', nameLen, 0, TS_ENCODING);
      -            if (lastDot < 0) {
      -                return tpName;
      -            }
      -            return substringNode.execute(tpName, lastDot + 1, nameLen - lastDot - 1, TS_ENCODING, true);
      +        static TruffleString getNameType(Object cls, @SuppressWarnings("unused") PNone value,
      +                        @Bind Node inliningTarget,
      +                        @Cached GetNameNode getNameNode) {
      +            return getNameNode.execute(inliningTarget, cls);
               }
       
               @GenerateInline
      @@ -1114,16 +881,16 @@ static void set(PythonClass type, TruffleString value) {
       
                   @Specialization
                   static void set(PythonAbstractNativeObject type, TruffleString value,
      +                            @Bind PythonLanguage language,
                                   @Cached(inline = false) CStructAccess.WritePointerNode writePointerNode,
                                   @Cached(inline = false) CStructAccess.WriteObjectNewRefNode writeObject,
                                   @Cached(inline = false) TruffleString.SwitchEncodingNode switchEncodingNode,
      -                            @Cached(inline = false) TruffleString.CopyToByteArrayNode copyToByteArrayNode,
      -                            @Cached(inline = false) PythonObjectFactory factory) {
      +                            @Cached(inline = false) TruffleString.CopyToByteArrayNode copyToByteArrayNode) {
                       value = switchEncodingNode.execute(value, TruffleString.Encoding.UTF_8);
                       byte[] bytes = copyToByteArrayNode.execute(value, TruffleString.Encoding.UTF_8);
      -                PBytes bytesObject = factory.createBytes(bytes);
      +                PBytes bytesObject = PFactory.createBytes(language, bytes);
                       writePointerNode.writeToObj(type, PyTypeObject__tp_name, PySequenceArrayWrapper.ensureNativeSequence(bytesObject));
      -                PString pString = factory.createString(value);
      +                PString pString = PFactory.createString(language, value);
                       pString.setUtf8Bytes(bytesObject);
                       writeObject.writeToObject(type, PyHeapTypeObject__ht_name, pString);
                   }
      @@ -1133,22 +900,22 @@ static void set(PythonAbstractNativeObject type, TruffleString value,
               static Object setName(VirtualFrame frame, Object cls, Object value,
                               @Bind("this") Node inliningTarget,
                               @Cached CheckSetSpecialTypeAttrNode check,
      -                        @Exclusive @Cached CastToTruffleStringNode castToTruffleStringNode,
      +                        @Cached CastToTruffleStringNode castToTruffleStringNode,
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
                               @Cached TruffleString.IsValidNode isValidNode,
      -                        @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode,
      +                        @Cached TruffleString.CodePointLengthNode codePointLengthNode,
                               @Cached TruffleString.IndexOfCodePointNode indexOfCodePointNode,
                               @Cached SetNameInnerNode innerNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   check.execute(inliningTarget, cls, value, T___NAME__);
                   TruffleString string;
                   try {
                       string = castToTruffleStringNode.execute(inliningTarget, value);
                   } catch (CannotCastException e) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.CAN_ONLY_ASSIGN_S_TO_P_S_NOT_P, "string", cls, T___NAME__, value);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CAN_ONLY_ASSIGN_S_TO_P_S_NOT_P, "string", cls, T___NAME__, value);
                   }
                   if (indexOfCodePointNode.execute(string, 0, 0, codePointLengthNode.execute(string, TS_ENCODING), TS_ENCODING) >= 0) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.TYPE_NAME_NO_NULL_CHARS);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.TYPE_NAME_NO_NULL_CHARS);
                   }
                   if (!isValidNode.execute(string, TS_ENCODING)) {
                       throw constructAndRaiseNode.get(inliningTarget).raiseUnicodeEncodeError(frame, "utf-8", string, 0, string.codePointLengthUncached(TS_ENCODING), "can't encode classname");
      @@ -1176,10 +943,10 @@ static TruffleString getModuleBuiltin(PythonBuiltinClass cls, @SuppressWarnings(
               static Object getModule(PythonClass cls, @SuppressWarnings("unused") PNone value,
                               @Bind("this") Node inliningTarget,
                               @Cached ReadAttributeFromObjectNode readAttrNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   Object module = readAttrNode.execute(cls, T___MODULE__);
                   if (module == NO_VALUE) {
      -                throw raiseNode.get(inliningTarget).raise(AttributeError);
      +                throw raiseNode.raise(inliningTarget, AttributeError);
                   }
                   return module;
               }
      @@ -1192,7 +959,7 @@ static Object setModule(PythonClass cls, Object value,
               }
       
               @Specialization(guards = "isNoValue(value)")
      -        static Object getModule(PythonNativeClass cls, @SuppressWarnings("unused") PNone value,
      +        static Object getModule(PythonAbstractNativeObject cls, @SuppressWarnings("unused") PNone value,
                               @Bind("this") Node inliningTarget,
                               @Cached("createForceType()") ReadAttributeFromObjectNode readAttr,
                               @Shared @Cached GetTypeFlagsNode getFlags,
      @@ -1200,12 +967,12 @@ static Object getModule(PythonNativeClass cls, @SuppressWarnings("unused") PNone
                               @Cached TruffleString.CodePointLengthNode codePointLengthNode,
                               @Cached TruffleString.IndexOfCodePointNode indexOfCodePointNode,
                               @Cached TruffleString.SubstringNode substringNode,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   // see function 'typeobject.c: type_module'
                   if ((getFlags.execute(cls) & TypeFlags.HEAPTYPE) != 0) {
                       Object module = readAttr.execute(cls, T___MODULE__);
                       if (module == NO_VALUE) {
      -                    throw raiseNode.get(inliningTarget).raise(AttributeError);
      +                    throw raiseNode.raise(inliningTarget, AttributeError);
                       }
                       return module;
                   } else {
      @@ -1221,14 +988,14 @@ static Object getModule(PythonNativeClass cls, @SuppressWarnings("unused") PNone
               }
       
               @Specialization(guards = "!isNoValue(value)")
      -        static Object setNative(PythonNativeClass cls, Object value,
      +        static Object setNative(PythonAbstractNativeObject cls, Object value,
                               @Bind("this") Node inliningTarget,
                               @Shared @Cached GetTypeFlagsNode getFlags,
                               @Cached("createForceType()") WriteAttributeToObjectNode writeAttr,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   long flags = getFlags.execute(cls);
                   if ((flags & TypeFlags.HEAPTYPE) == 0) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANT_SET_N_S, cls, T___MODULE__);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_SET_N_S, cls, T___MODULE__);
                   }
                   writeAttr.execute(cls, T___MODULE__, value);
                   return PNone.NONE;
      @@ -1236,14 +1003,14 @@ static Object setNative(PythonNativeClass cls, Object value,
       
               @Specialization(guards = "!isNoValue(value)")
               static Object setModuleType(@SuppressWarnings("unused") PythonBuiltinClassType cls, @SuppressWarnings("unused") Object value,
      -                        @Shared("raise") @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.CANT_SET_ATTRIBUTES_OF_TYPE, "built-in/extension 'type'");
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.CANT_SET_ATTRIBUTES_OF_TYPE, "built-in/extension 'type'");
               }
       
               @Specialization(guards = "!isNoValue(value)")
               static Object setModuleBuiltin(@SuppressWarnings("unused") PythonBuiltinClass cls, @SuppressWarnings("unused") Object value,
      -                        @Shared("raise") @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.CANT_SET_ATTRIBUTES_OF_TYPE, "built-in/extension 'type'");
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.CANT_SET_ATTRIBUTES_OF_TYPE, "built-in/extension 'type'");
               }
           }
       
      @@ -1261,24 +1028,15 @@ static TruffleString getName(PythonManagedClass cls, @SuppressWarnings("unused")
               }
       
               @Specialization(guards = "isNoValue(value)")
      -        static Object getNative(PythonNativeClass cls, @SuppressWarnings("unused") PNone value,
      +        static Object getNative(PythonAbstractNativeObject cls, @SuppressWarnings("unused") PNone value,
      +                        @Bind Node inliningTarget,
                               @Cached GetTypeFlagsNode getTypeFlagsNode,
                               @Cached CStructAccess.ReadObjectNode getHtName,
      -                        @Cached CStructAccess.ReadCharPtrNode getTpNameNode,
      -                        @Cached TruffleString.CodePointLengthNode codePointLengthNode,
      -                        @Cached TruffleString.IndexOfCodePointNode indexOfCodePointNode,
      -                        @Cached TruffleString.SubstringNode substringNode) {
      +                        @Cached GetNameNode getNameNode) {
                   if ((getTypeFlagsNode.execute(cls) & TypeFlags.HEAPTYPE) != 0) {
                       return getHtName.readFromObj(cls, PyHeapTypeObject__ht_qualname);
                   } else {
      -                // 'tp_name' contains the fully-qualified name, i.e., 'module.A.B...'
      -                TruffleString tpName = getTpNameNode.readFromObj(cls, PyTypeObject__tp_name);
      -                int nameLen = codePointLengthNode.execute(tpName, TS_ENCODING);
      -                int firstDot = indexOfCodePointNode.execute(tpName, '.', 0, nameLen, TS_ENCODING);
      -                if (firstDot < 0) {
      -                    return tpName;
      -                }
      -                return substringNode.execute(tpName, firstDot + 1, nameLen - firstDot - 1, TS_ENCODING, true);
      +                return getNameNode.execute(inliningTarget, cls);
                   }
               }
       
      @@ -1305,13 +1063,13 @@ static Object setName(Object cls, Object value,
                               @Cached CheckSetSpecialTypeAttrNode check,
                               @Cached CastToTruffleStringNode castToStringNode,
                               @Cached SetQualNameInnerNode innerNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   check.execute(inliningTarget, cls, value, T___QUALNAME__);
                   TruffleString stringValue;
                   try {
                       stringValue = castToStringNode.execute(inliningTarget, value);
                   } catch (CannotCastException e) {
      -                throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.CAN_ONLY_ASSIGN_STR_TO_QUALNAME, cls, value);
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CAN_ONLY_ASSIGN_STR_TO_QUALNAME, cls, value);
                   }
                   innerNode.execute(inliningTarget, cls, stringValue);
                   return PNone.NONE;
      @@ -1371,11 +1129,11 @@ static Object doGeneric(Object self,
                               @Bind("this") Node inliningTarget,
                               @Cached IsTypeNode isTypeNode,
                               @Cached GetTypeFlagsNode getTypeFlagsNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (PGuards.isClass(inliningTarget, self, isTypeNode)) {
                       return getTypeFlagsNode.execute(self);
                   }
      -            throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.DESC_FLAG_FOR_TYPE_DOESNT_APPLY_TO_OBJ, self);
      +            throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.DESC_FLAG_FOR_TYPE_DOESNT_APPLY_TO_OBJ, self);
               }
           }
       
      @@ -1387,7 +1145,7 @@ static Object get(Object self, @SuppressWarnings("unused") PNone none,
                               @Bind("this") Node inliningTarget,
                               @Exclusive @Cached IsSameTypeNode isSameTypeNode,
                               @Exclusive @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   // Avoid returning this descriptor
                   if (!isSameTypeNode.execute(inliningTarget, self, PythonBuiltinClassType.PythonClass)) {
                       Object result = readAttributeFromObjectNode.execute(self, T___ABSTRACTMETHODS__);
      @@ -1395,7 +1153,7 @@ static Object get(Object self, @SuppressWarnings("unused") PNone none,
                           return result;
                       }
                   }
      -            throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.OBJ_N_HAS_NO_ATTR_S, self, T___ABSTRACTMETHODS__);
      +            throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.OBJ_N_HAS_NO_ATTR_S, self, T___ABSTRACTMETHODS__);
               }
       
               @Specialization(guards = {"!isNoValue(value)", "!isDeleteMarker(value)"})
      @@ -1404,13 +1162,13 @@ static Object set(VirtualFrame frame, PythonClass self, Object value,
                               @Cached PyObjectIsTrueNode isTrueNode,
                               @Exclusive @Cached IsSameTypeNode isSameTypeNode,
                               @Exclusive @Cached WriteAttributeToObjectNode writeAttributeToObjectNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   if (!isSameTypeNode.execute(inliningTarget, self, PythonBuiltinClassType.PythonClass)) {
                       writeAttributeToObjectNode.execute(self, T___ABSTRACTMETHODS__, value);
                       self.setAbstractClass(isTrueNode.execute(frame, value));
                       return PNone.NONE;
                   }
      -            throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, J___ABSTRACTMETHODS__, self);
      +            throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, J___ABSTRACTMETHODS__, self);
               }
       
               @Specialization(guards = "!isNoValue(value)")
      @@ -1419,7 +1177,7 @@ static Object delete(PythonClass self, @SuppressWarnings("unused") DescriptorDel
                               @Exclusive @Cached IsSameTypeNode isSameTypeNode,
                               @Exclusive @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode,
                               @Exclusive @Cached WriteAttributeToObjectNode writeAttributeToObjectNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   if (!isSameTypeNode.execute(inliningTarget, self, PythonBuiltinClassType.PythonClass)) {
                       if (readAttributeFromObjectNode.execute(self, T___ABSTRACTMETHODS__) != NO_VALUE) {
                           writeAttributeToObjectNode.execute(self, T___ABSTRACTMETHODS__, NO_VALUE);
      @@ -1427,14 +1185,14 @@ static Object delete(PythonClass self, @SuppressWarnings("unused") DescriptorDel
                           return PNone.NONE;
                       }
                   }
      -            throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, J___ABSTRACTMETHODS__, self);
      +            throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, J___ABSTRACTMETHODS__, self);
               }
       
               @Fallback
               @SuppressWarnings("unused")
               static Object set(Object self, Object value,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(AttributeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, J___ABSTRACTMETHODS__, self);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, J___ABSTRACTMETHODS__, self);
               }
           }
       
      @@ -1450,14 +1208,13 @@ static PSet dir(VirtualFrame frame, Object klass,
                               @Cached PyObjectLookupAttr lookupAttrNode,
                               @Cached com.oracle.graal.python.nodes.call.CallNode callNode,
                               @Cached ToArrayNode toArrayNode,
      -                        @Cached("createGetAttrNode()") GetFixedAttributeNode getBasesNode,
      -                        @Cached PythonObjectFactory factory) {
      -            return dir(frame, inliningTarget, klass, lookupAttrNode, callNode, getBasesNode, toArrayNode, factory);
      +                        @Cached("createGetAttrNode()") GetFixedAttributeNode getBasesNode) {
      +            return dir(frame, inliningTarget, klass, lookupAttrNode, callNode, getBasesNode, toArrayNode);
               }
       
               private static PSet dir(VirtualFrame frame, Node inliningTarget, Object klass, PyObjectLookupAttr lookupAttrNode, com.oracle.graal.python.nodes.call.CallNode callNode,
      -                        GetFixedAttributeNode getBasesNode, ToArrayNode toArrayNode, PythonObjectFactory factory) {
      -            PSet names = factory.createSet();
      +                        GetFixedAttributeNode getBasesNode, ToArrayNode toArrayNode) {
      +            PSet names = PFactory.createSet(PythonLanguage.get(inliningTarget));
                   Object updateCallable = lookupAttrNode.execute(frame, inliningTarget, names, T_UPDATE);
                   Object ns = lookupAttrNode.execute(frame, inliningTarget, klass, T___DICT__);
                   if (ns != NO_VALUE) {
      @@ -1469,7 +1226,7 @@ private static PSet dir(VirtualFrame frame, Node inliningTarget, Object klass, P
                       for (Object cls : bases) {
                           // Note that since we are only interested in the keys, the order
                           // we merge classes is unimportant
      -                    Object baseNames = dir(frame, inliningTarget, cls, lookupAttrNode, callNode, getBasesNode, toArrayNode, factory);
      +                    Object baseNames = dir(frame, inliningTarget, cls, lookupAttrNode, callNode, getBasesNode, toArrayNode);
                           callNode.execute(frame, updateCallable, baseNames);
                       }
                   }
      @@ -1503,17 +1260,18 @@ abstract static class AnnotationsNode extends PythonBinaryBuiltinNode {
               @Specialization(guards = "isNoValue(value)")
               static Object get(Object self, @SuppressWarnings("unused") Object value,
                               @Bind("this") Node inliningTarget,
      +                        @Cached InlinedBranchProfile createDict,
                               @Shared("read") @Cached ReadAttributeFromObjectNode read,
                               @Shared("write") @Cached WriteAttributeToObjectNode write,
      -                        @Cached PythonObjectFactory.Lazy factory,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   Object annotations = read.execute(self, T___ANNOTATIONS__);
                   if (annotations == NO_VALUE) {
      -                annotations = factory.get(inliningTarget).createDict();
      +                createDict.enter(inliningTarget);
      +                annotations = PFactory.createDict(PythonLanguage.get(inliningTarget));
                       try {
                           write.execute(self, T___ANNOTATIONS__, annotations);
                       } catch (PException e) {
      -                    throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, self, T___ANNOTATIONS__);
      +                    throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, self, T___ANNOTATIONS__);
                       }
                   }
                   return annotations;
      @@ -1524,15 +1282,15 @@ static Object delete(Object self, @SuppressWarnings("unused") Object value,
                               @Bind("this") Node inliningTarget,
                               @Shared("read") @Cached ReadAttributeFromObjectNode read,
                               @Shared("write") @Cached WriteAttributeToObjectNode write,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   Object annotations = read.execute(self, T___ANNOTATIONS__);
                   try {
                       write.execute(self, T___ANNOTATIONS__, NO_VALUE);
                   } catch (PException e) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, T___ANNOTATIONS__, self);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, T___ANNOTATIONS__, self);
                   }
                   if (annotations == NO_VALUE) {
      -                throw raiseNode.get(inliningTarget).raise(AttributeError, new Object[]{T___ANNOTATIONS__});
      +                throw raiseNode.raise(inliningTarget, AttributeError, new Object[]{T___ANNOTATIONS__});
                   }
                   return PNone.NONE;
               }
      @@ -1541,11 +1299,11 @@ static Object delete(Object self, @SuppressWarnings("unused") Object value,
               static Object set(Object self, Object value,
                               @Bind("this") Node inliningTarget,
                               @Shared("write") @Cached WriteAttributeToObjectNode write,
      -                        @Shared @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Shared @Cached PRaiseNode raiseNode) {
                   try {
                       write.execute(self, T___ANNOTATIONS__, value);
                   } catch (PException e) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, T___ANNOTATIONS__, self);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_S_OF_IMMUTABLE_TYPE_N, T___ANNOTATIONS__, self);
                   }
                   return PNone.NONE;
               }
      @@ -1560,25 +1318,16 @@ static Object signature(Object type) {
                   if (!(type instanceof PythonBuiltinClassType || type instanceof PythonBuiltinClass)) {
                       return PNone.NONE;
                   }
      +            TpSlots slots = GetTpSlotsNode.executeUncached(type);
                   /* Best effort at getting at least something */
      -            Object newSlot = LookupCallableSlotInMRONode.getUncached(SpecialMethodSlot.New).execute(type);
      -            if (!TypeNodes.CheckCallableIsSpecificBuiltinNode.executeUncached(newSlot, BuiltinConstructorsFactory.ObjectNodeFactory.getInstance())) {
      -                return fromMethod(LookupAttributeInMRONode.Dynamic.getUncached().execute(type, T___NEW__));
      +            if (slots.tp_new() instanceof TpSlotVarargs.TpSlotVarargsBuiltin builtin && builtin != ObjectBuiltins.SLOTS.tp_new()) {
      +                return AbstractFunctionBuiltins.TextSignatureNode.signatureToText(builtin.getSignature(), true);
                   }
      -            Object initSlot = LookupCallableSlotInMRONode.getUncached(SpecialMethodSlot.Init).execute(type);
      -            if (!TypeNodes.CheckCallableIsSpecificBuiltinNode.executeUncached(initSlot, ObjectBuiltinsFactory.InitNodeFactory.getInstance())) {
      -                return fromMethod(LookupAttributeInMRONode.Dynamic.getUncached().execute(type, T___INIT__));
      +            if (slots.tp_init() instanceof TpSlotVarargs.TpSlotVarargsBuiltin builtin && builtin != ObjectBuiltins.SLOTS.tp_init()) {
      +                return AbstractFunctionBuiltins.TextSignatureNode.signatureToText(builtin.getSignature(), true);
                   }
                   // object() signature
                   return StringLiterals.T_EMPTY_PARENS;
               }
      -
      -        private static Object fromMethod(Object method) {
      -            if (method instanceof PBuiltinFunction || method instanceof PBuiltinMethod || method instanceof PFunction || method instanceof PMethod) {
      -                Signature signature = FunctionNodes.GetSignatureNode.executeUncached(method);
      -                return AbstractFunctionBuiltins.TextSignatureNode.signatureToText(signature, true);
      -            }
      -            return PNone.NONE;
      -        }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java
      index db9cbda3a4..e492ce2c13 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java
      @@ -42,6 +42,7 @@
       
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError;
       import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
      +import static com.oracle.graal.python.builtins.objects.PNone.NO_VALUE;
       import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_SUBCLASS_CHECK;
       import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyHeapTypeObject__ht_qualname;
       import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_base;
      @@ -82,6 +83,7 @@
       import static com.oracle.graal.python.nodes.HiddenAttr.ITEMSIZE;
       import static com.oracle.graal.python.nodes.HiddenAttr.WEAKLISTOFFSET;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___CLASSCELL__;
      +import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___CLASS__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DICT__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___QUALNAME__;
      @@ -89,6 +91,7 @@
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___WEAKREF__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T_MRO;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___CLASS_GETITEM__;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INIT_SUBCLASS__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEW__;
       import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
      @@ -114,8 +117,6 @@
       import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PCallCapiFunction;
       import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol;
       import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitionsFactory.PythonToNativeNodeGen;
      -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef;
      -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyObjectBuiltins.HPyObjectNewNode;
       import com.oracle.graal.python.builtins.objects.cext.structs.CFields;
       import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess;
       import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage;
      @@ -140,7 +141,6 @@
       import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemScalarNode;
       import com.oracle.graal.python.builtins.objects.dict.PDict;
       import com.oracle.graal.python.builtins.objects.frame.PFrame;
      -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor;
       import com.oracle.graal.python.builtins.objects.function.PArguments;
       import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
       import com.oracle.graal.python.builtins.objects.function.PFunction;
      @@ -149,7 +149,6 @@
       import com.oracle.graal.python.builtins.objects.getsetdescriptor.IndexedSlotDescriptor;
       import com.oracle.graal.python.builtins.objects.ints.PInt;
       import com.oracle.graal.python.builtins.objects.list.PList;
      -import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
       import com.oracle.graal.python.builtins.objects.module.PythonModule;
       import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins;
       import com.oracle.graal.python.builtins.objects.object.ObjectBuiltinsFactory;
      @@ -158,6 +157,9 @@
       import com.oracle.graal.python.builtins.objects.str.StringUtils;
       import com.oracle.graal.python.builtins.objects.superobject.SuperObject;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.Builder;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.TpSlotMeta;
       import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.GetBaseClassNodeGen;
       import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.GetBaseClassesNodeGen;
       import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.GetBasicSizeNodeGen;
      @@ -167,6 +169,7 @@
       import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.GetSolidBaseNodeGen;
       import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.GetSubclassesAsArrayNodeGen;
       import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.GetSubclassesNodeGen;
      +import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.GetTpNameNodeGen;
       import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.GetTypeFlagsNodeGen;
       import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.InstancesOfTypeHaveDictNodeGen;
       import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.InstancesOfTypeHaveWeakrefsNodeGen;
      @@ -174,6 +177,8 @@
       import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.IsSameTypeNodeGen;
       import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.IsTypeNodeGen;
       import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.SetTypeFlagsNodeGen;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun;
      +import com.oracle.graal.python.lib.PyObjectLookupAttr;
       import com.oracle.graal.python.lib.PyObjectSizeNode;
       import com.oracle.graal.python.lib.PyUnicodeCheckNode;
       import com.oracle.graal.python.nodes.ErrorMessages;
      @@ -186,28 +191,28 @@
       import com.oracle.graal.python.nodes.SpecialMethodNames;
       import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
       import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
      -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode;
      -import com.oracle.graal.python.nodes.attributes.LookupInheritedSlotNode;
       import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
       import com.oracle.graal.python.nodes.call.CallNode;
       import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode;
      +import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodNode;
      +import com.oracle.graal.python.nodes.classes.AbstractObjectGetBasesNode;
      +import com.oracle.graal.python.nodes.classes.AbstractObjectIsSubclassNode;
       import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
       import com.oracle.graal.python.nodes.expression.CastToListExpressionNode.CastToListNode;
       import com.oracle.graal.python.nodes.frame.ReadCallerFrameNode;
       import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode;
      -import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassProfile;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode;
       import com.oracle.graal.python.nodes.object.GetOrCreateDictNode;
      -import com.oracle.graal.python.nodes.truffle.PythonTypes;
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
       import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
       import com.oracle.graal.python.runtime.IndirectCallData;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.exception.PythonErrorType;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.runtime.sequence.PSequence;
       import com.oracle.graal.python.runtime.sequence.storage.MroSequenceStorage;
       import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage;
      @@ -229,10 +234,8 @@
       import com.oracle.truffle.api.dsl.GenerateUncached;
       import com.oracle.truffle.api.dsl.ImportStatic;
       import com.oracle.truffle.api.dsl.NeverDefault;
      -import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.ReportPolymorphism;
       import com.oracle.truffle.api.dsl.Specialization;
      -import com.oracle.truffle.api.dsl.TypeSystemReference;
       import com.oracle.truffle.api.frame.Frame;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.interop.InteropLibrary;
      @@ -403,7 +406,7 @@ private static long defaultBuiltinFlags(PythonBuiltinClassType clazz) {
                           result = DEFAULT | HAVE_GC | METHOD_DESCRIPTOR;
                           break;
                       case PLruListElem:
      -                    result = DEFAULT | HAVE_GC | DISALLOW_INSTANTIATION;
      +                    result = DEFAULT | HAVE_GC;
                           break;
                       case PBytesIOBuf:
                       case PMethod:
      @@ -464,6 +467,7 @@ private static long defaultBuiltinFlags(PythonBuiltinClassType clazz) {
                           break;
                   }
                   result |= clazz.isAcceptableBase() ? BASETYPE : 0;
      +            result |= clazz.disallowInstantiation() ? DISALLOW_INSTANTIATION : 0;
                   PythonBuiltinClassType iter = clazz;
                   while (iter != null) {
                       if (iter == PythonBuiltinClassType.PBaseException) {
      @@ -590,7 +594,7 @@ private static MroSequenceStorage doPythonClass(PythonManagedClass obj, Node inl
       
               @InliningCutoff
               private static void initializeMRO(PythonManagedClass obj, Node inliningTarget, InlinedConditionProfile isPythonClass, PythonLanguage language) {
      -            PythonAbstractClass[] mro = ComputeMroNode.doSlowPath(obj, false);
      +            PythonAbstractClass[] mro = ComputeMroNode.doSlowPath(inliningTarget, obj, false);
                   if (isPythonClass.profile(inliningTarget, obj instanceof PythonClass)) {
                       ((PythonClass) obj).setMRO(mro, language);
                   } else {
      @@ -632,7 +636,7 @@ static MroSequenceStorage doNativeClass(Node inliningTarget, PythonNativeClass o
                       }
                   }
                   raiseSystemErrorBranch.enter(inliningTarget);
      -            throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.SystemError, ErrorMessages.INVALID_MRO_OBJ);
      +            throw PRaiseNode.raiseStatic(inliningTarget, SystemError, ErrorMessages.INVALID_MRO_OBJ);
               }
       
               private static Object initializeType(Node inliningTarget, PythonNativeClass obj, CStructAccess.ReadObjectNode getTpMroNode) {
      @@ -642,7 +646,7 @@ private static Object initializeType(Node inliningTarget, PythonNativeClass obj,
                   // call 'PyType_Ready' on the type
                   int res = (int) PCallCapiFunction.callUncached(NativeCAPISymbol.FUN_PY_TYPE_READY, PythonToNativeNodeGen.getUncached().execute(obj));
                   if (res < 0) {
      -                PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.SystemError, ErrorMessages.LAZY_INITIALIZATION_FAILED, GetNameNode.executeUncached(obj));
      +                throw PRaiseNode.raiseStatic(inliningTarget, SystemError, ErrorMessages.LAZY_INITIALIZATION_FAILED, obj);
                   }
       
                   Object tupleObj = getTpMroNode.readFromObj(obj, PyTypeObject__tp_mro);
      @@ -669,7 +673,7 @@ static MroSequenceStorage doSlowPath(Node inliningTarget, Object obj) {
                               return (MroSequenceStorage) sequenceStorage;
                           }
                       }
      -                throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.SystemError, ErrorMessages.INVALID_MRO_OBJ);
      +                throw PRaiseNode.raiseStatic(inliningTarget, SystemError, ErrorMessages.INVALID_MRO_OBJ);
                   }
                   throw new IllegalStateException("unknown type " + obj.getClass().getName());
               }
      @@ -684,17 +688,17 @@ public static GetMroStorageNode getUncached() {
               }
           }
       
      +    /**
      +     * Equivalent of {@code _PyType_Name}. Returns unqualified name. Different from
      +     * {@code GetTpNameNode}.
      +     */
           @GenerateUncached
      -    @GenerateInline(inlineByDefault = true)
      -    @GenerateCached
      +    @GenerateInline
      +    @GenerateCached(false)
           public abstract static class GetNameNode extends Node {
       
               public abstract TruffleString execute(Node inliningTarget, Object obj);
       
      -        public final TruffleString executeCached(Object obj) {
      -            return execute(this, obj);
      -        }
      -
               public static TruffleString executeUncached(Object obj) {
                   return GetNameNodeGen.getUncached().execute(null, obj);
               }
      @@ -711,26 +715,55 @@ static TruffleString doBuiltinClassType(PythonBuiltinClassType obj) {
       
               @Specialization
               TruffleString doNativeClass(PythonNativeClass obj,
      -                        @Cached(inline = false) CStructAccess.ReadCharPtrNode getTpNameNode) {
      -            return getTpNameNode.readFromObj(obj, PyTypeObject__tp_name);
      +                        @Cached CStructAccess.ReadCharPtrNode getTpNameNode,
      +                        @Cached TruffleString.CodePointLengthNode codePointLengthNode,
      +                        @Cached TruffleString.LastIndexOfCodePointNode indexOfCodePointNode,
      +                        @Cached TruffleString.SubstringNode substringNode) {
      +            // 'tp_name' contains the fully-qualified name, i.e., 'module.A.B...'
      +            TruffleString tpName = getTpNameNode.readFromObj(obj, PyTypeObject__tp_name);
      +            int nameLen = codePointLengthNode.execute(tpName, TS_ENCODING);
      +            int lastDot = indexOfCodePointNode.execute(tpName, '.', nameLen, 0, TS_ENCODING);
      +            if (lastDot < 0) {
      +                return tpName;
      +            }
      +            return substringNode.execute(tpName, lastDot + 1, nameLen - lastDot - 1, TS_ENCODING, true);
               }
      +    }
       
      -        @Specialization(replaces = {"doManagedClass", "doBuiltinClassType", "doNativeClass"})
      -        @TruffleBoundary
      -        public static TruffleString doSlowPath(Object obj) {
      -            if (obj instanceof PythonManagedClass) {
      -                return ((PythonManagedClass) obj).getName();
      -            } else if (obj instanceof PythonBuiltinClassType) {
      -                return ((PythonBuiltinClassType) obj).getName();
      -            } else if (PGuards.isNativeClass(obj)) {
      -                return CStructAccess.ReadCharPtrNode.getUncached().readFromObj((PythonNativeClass) obj, PyTypeObject__tp_name);
      -            }
      -            throw new IllegalStateException("unknown type " + obj.getClass().getName());
      +    /*
      +     * Equivalent of getting {@code tp_name} field. Returns unqualified name for heaptypes, but
      +     * qualified name for builtins. Typically used in exception messages.
      +     */
      +    @GenerateUncached
      +    @GenerateInline
      +    @GenerateCached(false)
      +    public abstract static class GetTpNameNode extends Node {
      +
      +        public abstract TruffleString execute(Node inliningTarget, Object obj);
      +
      +        public static TruffleString executeUncached(Object obj) {
      +            return GetTpNameNodeGen.getUncached().execute(null, obj);
               }
       
      -        @NeverDefault
      -        public static GetNameNode create() {
      -            return GetNameNodeGen.create();
      +        @Specialization
      +        static TruffleString doPythonClass(PythonClass obj) {
      +            return obj.getName();
      +        }
      +
      +        @Specialization
      +        static TruffleString doBuiltinClass(PythonBuiltinClass obj) {
      +            return doBuiltinClassType(obj.getType());
      +        }
      +
      +        @Specialization
      +        static TruffleString doBuiltinClassType(PythonBuiltinClassType obj) {
      +            return obj.getPrintName();
      +        }
      +
      +        @Specialization
      +        TruffleString doNativeClass(PythonNativeClass obj,
      +                        @Cached(inline = false) CStructAccess.ReadCharPtrNode getTpNameNode) {
      +            return getTpNameNode.readFromObj(obj, PyTypeObject__tp_name);
               }
           }
       
      @@ -767,7 +800,6 @@ static TruffleString getQualName(Node inliningTarget, PythonAbstractNativeObject
               }
           }
       
      -    @TypeSystemReference(PythonTypes.class)
           @GenerateUncached
           @GenerateInline
           @GenerateCached(false)
      @@ -783,19 +815,9 @@ protected static void unsafeAddSubclass(Object base, Object subclass) {
                   long hash = ObjectBuiltins.HashNode.hash(subclass);
                   PDict dict = executeUncached(base);
                   HashingStorage storage = dict.getDictStorage();
      -            // Booting order problem: special method slot for object.__eq__ is not initialized yet
      -            // In the unlikely event of hash collision __eq__ would fail
      -            if (HashingStorageLen.executeUncached(storage) == 0) {
      -                // This should not call __eq__
      -                HashingStorageSetItemWithHash setItem = HashingStorageSetItemWithHashNodeGen.getUncached();
      -                storage = setItem.execute(null, null, storage, subclass, hash, subclass);
      -                dict.setDictStorage(storage);
      -            } else {
      -                // the storage must be EconomicMap, because keys should not be Strings so there is
      -                // no other option left
      -                EconomicMapStorage mapStorage = (EconomicMapStorage) storage;
      -                mapStorage.putUncachedWithJavaEq(subclass, hash, subclass);
      -            }
      +            HashingStorageSetItemWithHash setItem = HashingStorageSetItemWithHashNodeGen.getUncached();
      +            storage = setItem.execute(null, null, storage, subclass, hash, subclass);
      +            dict.setDictStorage(storage);
               }
       
               protected static void unsafeRemoveSubclass(Object base, Object subclass) {
      @@ -820,7 +842,7 @@ static PDict doPythonClass(Node inliningTarget, PythonBuiltinClassType obj) {
               }
       
               @Specialization
      -        static PDict doNativeClass(Node inliningTarget, PythonNativeClass obj,
      +        static PDict doNativeClass(Node inliningTarget, PythonAbstractNativeObject obj,
                               @Cached(inline = false) CStructAccess.ReadObjectNode getTpSubclassesNode,
                               @Cached InlinedExactClassProfile profile) {
                   Object tpSubclasses = getTpSubclassesNode.readFromObj(obj, PyTypeObject__tp_subclasses);
      @@ -924,7 +946,7 @@ PythonAbstractClass[] doPythonClass(PythonBuiltinClassType obj) {
       
               @Specialization
               static PythonAbstractClass[] doNative(Node inliningTarget, PythonNativeClass obj,
      -                        @Cached PRaiseNode.Lazy raise,
      +                        @Cached PRaiseNode raise,
                               @Cached(inline = false) CStructAccess.ReadObjectNode getTpBasesNode,
                               @Cached InlinedExactClassProfile resultTypeProfile,
                               @Cached GetInternalObjectArrayNode toArrayNode) {
      @@ -935,10 +957,10 @@ static PythonAbstractClass[] doNative(Node inliningTarget, PythonNativeClass obj
                       try {
                           return cast(values, storage);
                       } catch (ClassCastException e) {
      -                    throw raise.get(inliningTarget).raise(PythonBuiltinClassType.SystemError, ErrorMessages.UNSUPPORTED_OBJ_IN, "tp_bases");
      +                    throw raise.raise(inliningTarget, PythonBuiltinClassType.SystemError, ErrorMessages.UNSUPPORTED_OBJ_IN, "tp_bases");
                       }
                   }
      -            throw raise.get(inliningTarget).raise(PythonBuiltinClassType.SystemError, ErrorMessages.TYPE_DOES_NOT_PROVIDE_BASES);
      +            throw raise.raise(inliningTarget, PythonBuiltinClassType.SystemError, ErrorMessages.TYPE_DOES_NOT_PROVIDE_BASES);
               }
       
               // TODO: get rid of this
      @@ -983,7 +1005,7 @@ static Object doNative(Node inliningTarget, PythonNativeClass obj,
                       return result;
                   }
                   CompilerDirectives.transferToInterpreterAndInvalidate();
      -            throw PRaiseNode.raiseUncached(inliningTarget, SystemError, ErrorMessages.INVALID_BASE_TYPE_OBJ_FOR_CLASS, GetNameNode.doSlowPath(obj), result);
      +            throw PRaiseNode.raiseStatic(inliningTarget, SystemError, ErrorMessages.INVALID_BASE_TYPE_OBJ_FOR_CLASS, obj, result);
               }
       
               public static GetBaseClassNode getUncached() {
      @@ -1013,7 +1035,7 @@ static PythonAbstractClass getOne(PythonAbstractClass[] bases) {
               static PythonAbstractClass getBestBase(Node inliningTarget, PythonAbstractClass[] bases,
                               @Cached(inline = false) IsSubtypeNode isSubTypeNode,
                               @Cached GetSolidBaseNode getSolidBaseNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   return bestBase(inliningTarget, bases, getSolidBaseNode, isSubTypeNode, raiseNode);
               }
       
      @@ -1028,7 +1050,7 @@ static PythonAbstractClass fallback(PythonAbstractClass[] bases) {
               /**
                * Aims to get as close as possible to typeobject.best_base().
                */
      -        private static PythonAbstractClass bestBase(Node inliningTarget, PythonAbstractClass[] bases, GetSolidBaseNode getSolidBaseNode, IsSubtypeNode isSubTypeNode, PRaiseNode.Lazy raiseNode)
      +        private static PythonAbstractClass bestBase(Node inliningTarget, PythonAbstractClass[] bases, GetSolidBaseNode getSolidBaseNode, IsSubtypeNode isSubTypeNode, PRaiseNode raiseNode)
                               throws PException {
                   PythonAbstractClass base = null;
                   Object winner = null;
      @@ -1044,7 +1066,7 @@ private static PythonAbstractClass bestBase(Node inliningTarget, PythonAbstractC
                           winner = candidate;
                           base = basei;
                       } else {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MULTIPLE_BASES_LAYOUT_CONFLICT);
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MULTIPLE_BASES_LAYOUT_CONFLICT);
                       }
                   }
                   return base;
      @@ -1084,8 +1106,6 @@ public abstract static class CheckCompatibleForAssigmentNode extends PNodeWithCo
               @Child private LookupAttributeInMRONode lookupSlotsNode;
               @Child private LookupAttributeInMRONode lookupNewNode;
               @Child private PyObjectSizeNode sizeNode;
      -        @Child private PRaiseNode raiseNode;
      -        @Child private GetNameNode getTypeNameNode;
               @Child private ReadAttributeFromObjectNode readAttr;
               @Child private InstancesOfTypeHaveDictNode instancesHaveDictNode;
       
      @@ -1099,7 +1119,7 @@ boolean isCompatible(VirtualFrame frame, Object oldBase, Object newBase,
                               @Cached GetBaseClassNode getBaseClassNode) {
                   if (!compatibleForAssignment(frame, inliningTarget, oldBase, newBase, isSameTypeNode, getBaseClassNode)) {
                       errorSlotsBranch.enter(inliningTarget);
      -                throw getRaiseNode().raise(TypeError, ErrorMessages.CLASS_ASSIGNMENT_S_LAYOUT_DIFFERS_FROM_S, getTypeName(newBase), getTypeName(oldBase));
      +                throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CLASS_ASSIGNMENT_N_LAYOUT_DIFFERS_FROM_N, newBase, oldBase);
                   }
                   return true;
               }
      @@ -1194,14 +1214,6 @@ private boolean compareSlots(VirtualFrame frame, Object aType, Object bType, Obj
                   return aSize == bSize;
               }
       
      -        private TruffleString getTypeName(Object clazz) {
      -            if (getTypeNameNode == null) {
      -                CompilerDirectives.transferToInterpreterAndInvalidate();
      -                getTypeNameNode = insert(TypeNodes.GetNameNode.create());
      -            }
      -            return getTypeNameNode.executeCached(clazz);
      -        }
      -
               private Object getSlotsFromType(Object type) {
                   Object slots = getReadAttr().execute(type, T___SLOTS__);
                   return slots != PNone.NO_VALUE ? slots : null;
      @@ -1246,14 +1258,6 @@ private LookupAttributeInMRONode getLookupNewNode() {
                   }
                   return lookupNewNode;
               }
      -
      -        private PRaiseNode getRaiseNode() {
      -            if (raiseNode == null) {
      -                CompilerDirectives.transferToInterpreterAndInvalidate();
      -                raiseNode = insert(PRaiseNode.create());
      -            }
      -            return raiseNode;
      -        }
           }
       
           /**
      @@ -1446,7 +1450,7 @@ private static boolean extraivars(Object type, Object base, Object typeSlots) {
                                   DynamicObjectLibrary.getUncached());
                   Object baseNewMethod = LookupAttributeInMRONode.lookup(T___NEW__, GetMroStorageNode.executeUncached(base), ReadAttributeFromObjectNode.getUncached(), true,
                                   DynamicObjectLibrary.getUncached());
      -            return !HasSameConstructorNode.isSameFunction(typeNewMethod, baseNewMethod);
      +            return typeNewMethod != baseNewMethod;
               }
       
               @TruffleBoundary
      @@ -1596,17 +1600,17 @@ static final class NotSameTypeException extends ControlFlowException {
           public abstract static class ComputeMroNode extends Node {
       
               @TruffleBoundary
      -        public static PythonAbstractClass[] doSlowPath(PythonAbstractClass cls) {
      -            return doSlowPath(cls, true);
      +        public static PythonAbstractClass[] doSlowPath(Node node, PythonAbstractClass cls) {
      +            return doSlowPath(node, cls, true);
               }
       
               @TruffleBoundary
      -        public static PythonAbstractClass[] doSlowPath(PythonAbstractClass cls, boolean invokeMro) {
      -            return computeMethodResolutionOrder(cls, invokeMro);
      +        public static PythonAbstractClass[] doSlowPath(Node node, PythonAbstractClass cls, boolean invokeMro) {
      +            return computeMethodResolutionOrder(node, cls, invokeMro);
               }
       
               @TruffleBoundary
      -        static PythonAbstractClass[] invokeMro(PythonAbstractClass cls) {
      +        static PythonAbstractClass[] invokeMro(Node node, PythonAbstractClass cls) {
                   Object type = GetClassNode.executeUncached(cls);
                   if (IsTypeNode.executeUncached(type) && type instanceof PythonClass) {
                       Object mroMeth = LookupAttributeInMRONode.Dynamic.getUncached().execute(type, T_MRO);
      @@ -1614,20 +1618,20 @@ static PythonAbstractClass[] invokeMro(PythonAbstractClass cls) {
                           Object mroObj = CallUnaryMethodNode.getUncached().executeObject(mroMeth, cls);
                           if (mroObj instanceof PSequence mroSequence) {
                               SequenceStorage mroStorage = mroSequence.getSequenceStorage();
      -                        return mroCheck(cls, GetInternalObjectArrayNode.executeUncached(mroStorage), mroStorage);
      +                        return mroCheck(node, cls, GetInternalObjectArrayNode.executeUncached(mroStorage), mroStorage);
                           }
      -                    throw PRaiseNode.getUncached().raise(TypeError, ErrorMessages.OBJ_NOT_ITERABLE, cls);
      +                    throw PRaiseNode.raiseStatic(node, TypeError, ErrorMessages.OBJ_NOT_ITERABLE, cls);
                       }
                   }
                   return null;
               }
       
      -        private static PythonAbstractClass[] computeMethodResolutionOrder(PythonAbstractClass cls, boolean invokeMro) {
      +        private static PythonAbstractClass[] computeMethodResolutionOrder(Node node, PythonAbstractClass cls, boolean invokeMro) {
                   CompilerAsserts.neverPartOfCompilation();
       
                   PythonAbstractClass[] currentMRO;
                   if (invokeMro) {
      -                PythonAbstractClass[] mro = invokeMro(cls);
      +                PythonAbstractClass[] mro = invokeMro(node, cls);
                       if (mro != null) {
                           return mro;
                       }
      @@ -1656,12 +1660,12 @@ private static PythonAbstractClass[] computeMethodResolutionOrder(PythonAbstract
                       toMerge[baseClasses.length] = new MROMergeState(baseClasses);
                       ArrayList mro = new ArrayList<>();
                       mro.add(cls);
      -                currentMRO = mergeMROs(toMerge, mro);
      +                currentMRO = mergeMROs(node, toMerge, mro);
                   }
                   return currentMRO;
               }
       
      -        private static PythonAbstractClass[] mroCheck(Object cls, Object[] mro, SequenceStorage storage) {
      +        private static PythonAbstractClass[] mroCheck(Node node, Object cls, Object[] mro, SequenceStorage storage) {
                   List resultMro = new ArrayList<>(storage.length());
                   Object solid = GetSolidBaseNode.executeUncached(cls);
                   for (int i = 0; i < storage.length(); i++) {
      @@ -1670,17 +1674,17 @@ private static PythonAbstractClass[] mroCheck(Object cls, Object[] mro, Sequence
                           continue;
                       }
                       if (!IsTypeNode.executeUncached(object)) {
      -                    throw PRaiseNode.getUncached().raise(TypeError, ErrorMessages.S_RETURNED_NON_CLASS, "mro()", object);
      +                    throw PRaiseNode.raiseStatic(node, TypeError, ErrorMessages.S_RETURNED_NON_CLASS, "mro()", object);
                       }
                       if (!IsSubtypeNode.getUncached().execute(solid, GetSolidBaseNode.executeUncached(object))) {
      -                    throw PRaiseNode.getUncached().raise(TypeError, ErrorMessages.S_RETURNED_BASE_WITH_UNSUITABLE_LAYOUT, "mro()", object);
      +                    throw PRaiseNode.raiseStatic(node, TypeError, ErrorMessages.S_RETURNED_BASE_WITH_UNSUITABLE_LAYOUT, "mro()", object);
                       }
                       resultMro.add((PythonAbstractClass) object);
                   }
                   return resultMro.toArray(new PythonAbstractClass[resultMro.size()]);
               }
       
      -        private static PythonAbstractClass[] mergeMROs(MROMergeState[] toMerge, List mro) {
      +        private static PythonAbstractClass[] mergeMROs(Node node, MROMergeState[] toMerge, List mro) {
                   int idx;
                   scan: for (idx = 0; idx < toMerge.length; idx++) {
                       if (toMerge[idx].isMerged()) {
      @@ -1715,11 +1719,11 @@ private static PythonAbstractClass[] mergeMROs(MROMergeState[] toMerge, List it = notMerged.iterator();
      -                StringBuilder bases = new StringBuilder(GetNameNode.doSlowPath(it.next()).toJavaStringUncached());
      +                StringBuilder bases = new StringBuilder(GetNameNode.executeUncached(it.next()).toJavaStringUncached());
                       while (it.hasNext()) {
      -                    bases.append(", ").append(GetNameNode.doSlowPath(it.next()));
      +                    bases.append(", ").append(GetNameNode.executeUncached(it.next()));
                       }
      -                throw PRaiseNode.getUncached().raise(TypeError, ErrorMessages.CANNOT_GET_CONSISTEMT_METHOD_RESOLUTION, bases.toString());
      +                throw PRaiseNode.raiseStatic(node, TypeError, ErrorMessages.CANNOT_GET_CONSISTEMT_METHOD_RESOLUTION, bases.toString());
                   }
       
                   return mro.toArray(new PythonAbstractClass[mro.size()]);
      @@ -1793,11 +1797,6 @@ public abstract static class IsAcceptableBaseNode extends Node {
       
               @Specialization
               static boolean doUserClass(PythonClass obj) {
      -            // Special case for custom classes created via HPy: They are managed classes but can
      -            // have custom flags. The flags may prohibit subtyping.
      -            if (obj.isHPyType()) {
      -                return (obj.getFlags() & GraalHPyDef.HPy_TPFLAGS_BASETYPE) != 0;
      -            }
                   return true;
               }
       
      @@ -1840,6 +1839,10 @@ public abstract static class GetInstanceShape extends PNodeWithContext {
       
               public abstract Shape execute(Object clazz);
       
      +        public static Shape executeUncached(Object clazz) {
      +            return TypeNodesFactory.GetInstanceShapeNodeGen.getUncached().execute(clazz);
      +        }
      +
               @Specialization(guards = "clazz == cachedClazz", limit = "1")
               @SuppressWarnings("unused")
               protected Shape doBuiltinClassTypeCached(PythonBuiltinClassType clazz,
      @@ -1895,13 +1898,16 @@ protected static Shape doNativeClass(PythonAbstractNativeObject clazz,
               @Specialization(guards = {"!isManagedClass(clazz)", "!isPythonBuiltinClassType(clazz)"})
               @InliningCutoff
               protected static Shape doError(@SuppressWarnings("unused") Object clazz,
      -                        @Cached PRaiseNode raise) {
      -            throw raise.raise(PythonBuiltinClassType.SystemError, ErrorMessages.CANNOT_GET_SHAPE_OF_NATIVE_CLS);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.SystemError, ErrorMessages.CANNOT_GET_SHAPE_OF_NATIVE_CLS);
               }
       
      +        public static GetInstanceShape getUncached() {
      +            return TypeNodesFactory.GetInstanceShapeNodeGen.getUncached();
      +        }
           }
       
      -    @ImportStatic({SpecialMethodNames.class, SpecialAttributeNames.class, SpecialMethodSlot.class})
      +    @ImportStatic({SpecialMethodNames.class, SpecialAttributeNames.class})
           public abstract static class CreateTypeNode extends Node {
               public abstract PythonClass execute(VirtualFrame frame, PDict namespaceOrig, TruffleString name, PTuple bases, Object metaclass, PKeyword[] kwds);
       
      @@ -1944,104 +1950,117 @@ protected PythonClass makeType(VirtualFrame frame, PDict namespaceOrig, TruffleS
                               @Cached HashingStorageIteratorKey itKey,
                               @Cached HashingStorageIteratorValue itValue,
                               @Cached HashingStorageDelItem delItemNamespace,
      -                        @Cached("create(SetName)") LookupInheritedSlotNode getSetNameNode,
      +                        @Cached GetClassNode getClassNode,
      +                        @Cached("create(T___SET_NAME__)") LookupSpecialMethodNode getSetNameNode,
                               @Cached CallNode callSetNameNode,
                               @Cached CallNode callInitSubclassNode,
                               @Cached("create(T___INIT_SUBCLASS__)") GetAttributeNode getInitSubclassNode,
                               @Cached GetMroStorageNode getMroStorageNode,
      -                        @Cached PythonObjectFactory factory,
      +                        @Bind PythonLanguage language,
                               @Cached PRaiseNode raise,
                               @Cached AllocateTypeWithMetaclassNode typeMetaclass) {
      -            try {
      -                assert SpecialMethodSlot.pushInitializedTypePlaceholder();
      -                PDict namespace = factory.createDict();
      -                PythonLanguage language = PythonLanguage.get(this);
      -                namespace.setDictStorage(initNode.execute(frame, namespaceOrig, PKeyword.EMPTY_KEYWORDS));
      -                PythonClass newType = typeMetaclass.execute(frame, name, bases, namespace, metaclass);
      -
      -                // set '__module__' attribute
      -                Object moduleAttr = ensureReadAttrNode().execute(newType, SpecialAttributeNames.T___MODULE__);
      -                if (moduleAttr == PNone.NO_VALUE) {
      -                    PythonObject globals;
      -                    if (getRootNode() instanceof BuiltinFunctionRootNode) {
      -                        PFrame callerFrame = getReadCallerFrameNode().executeWith(frame, 0);
      -                        globals = callerFrame != null ? callerFrame.getGlobals() : null;
      -                    } else {
      -                        globals = PArguments.getGlobals(frame);
      -                    }
      -                    if (globals != null) {
      -                        TruffleString moduleName = getModuleNameFromGlobals(inliningTarget, globals, getItemGlobals);
      -                        if (moduleName != null) {
      -                            newType.setAttribute(SpecialAttributeNames.T___MODULE__, moduleName);
      -                        }
      +            PDict namespace = PFactory.createDict(language);
      +            namespace.setDictStorage(initNode.execute(frame, namespaceOrig, PKeyword.EMPTY_KEYWORDS));
      +            PythonClass newType = typeMetaclass.execute(frame, name, bases, namespace, metaclass);
      +
      +            // set '__module__' attribute
      +            Object moduleAttr = ensureReadAttrNode().execute(newType, SpecialAttributeNames.T___MODULE__);
      +            if (moduleAttr == PNone.NO_VALUE) {
      +                PythonObject globals;
      +                if (getRootNode() instanceof BuiltinFunctionRootNode) {
      +                    PFrame callerFrame = getReadCallerFrameNode().executeWith(frame, 0);
      +                    globals = callerFrame != null ? callerFrame.getGlobals() : null;
      +                } else {
      +                    globals = PArguments.getGlobals(frame);
      +                }
      +                if (globals != null) {
      +                    TruffleString moduleName = getModuleNameFromGlobals(inliningTarget, globals, getItemGlobals);
      +                    if (moduleName != null) {
      +                        newType.setAttribute(SpecialAttributeNames.T___MODULE__, moduleName);
                           }
                       }
      +            }
       
      -                // delete __qualname__ from namespace
      -                delItemNamespace.execute(inliningTarget, namespace.getDictStorage(), T___QUALNAME__, namespace);
      +            // delete __qualname__ from namespace
      +            delItemNamespace.execute(inliningTarget, namespace.getDictStorage(), T___QUALNAME__, namespace);
       
      -                // initialize '__doc__' attribute
      -                if (newType.getAttribute(SpecialAttributeNames.T___DOC__) == PNone.NO_VALUE) {
      -                    newType.setAttribute(SpecialAttributeNames.T___DOC__, PNone.NONE);
      -                }
      +            // initialize '__doc__' attribute
      +            if (newType.getAttribute(SpecialAttributeNames.T___DOC__) == PNone.NO_VALUE) {
      +                newType.setAttribute(SpecialAttributeNames.T___DOC__, PNone.NONE);
      +            }
       
      -                // set __class__ cell contents
      -                Object classcell = getItemNamespace.execute(inliningTarget, namespace.getDictStorage(), SpecialAttributeNames.T___CLASSCELL__);
      -                if (classcell != null) {
      -                    if (classcell instanceof PCell) {
      -                        ((PCell) classcell).setRef(newType);
      -                    } else {
      -                        throw raise.raise(TypeError, ErrorMessages.MUST_BE_A_CELL, "__classcell__");
      -                    }
      -                    delItemNamespace.execute(inliningTarget, namespace.getDictStorage(), SpecialAttributeNames.T___CLASSCELL__, namespace);
      +            // set __class__ cell contents
      +            Object classcell = getItemNamespace.execute(inliningTarget, namespace.getDictStorage(), SpecialAttributeNames.T___CLASSCELL__);
      +            if (classcell != null) {
      +                if (classcell instanceof PCell) {
      +                    ((PCell) classcell).setRef(newType);
      +                } else {
      +                    throw raise.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_A_CELL, "__classcell__");
                       }
      +                delItemNamespace.execute(inliningTarget, namespace.getDictStorage(), SpecialAttributeNames.T___CLASSCELL__, namespace);
      +            }
      +
      +            // Initialization of the type slots:
      +            //
      +            // For now, we have the same helper functions as CPython and we execute them in the
      +            // same order even-though we could squash them and optimize the wrapping and
      +            // unwrapping of slots, but it would be more difficult to make sure that at the end
      +            // of the day we produce exactly the same results, especially if there are native
      +            // types in the MRO (we can, e.g., optimize this only for pure Python types to keep
      +            // it still simple).
      +            //
      +            // From CPython point of view: we are in "type_new_impl", we call PyType_Ready,
      +            // which calls:
      +            //
      +            // - type_ready_fill_dict, which calls add_operators, which fills the dunder methods
      +            // from the slots. Here we are creating a managed type, so there cannot be any
      +            // native slots, so this is a no-op for us.
      +            //
      +            // - type_ready_inherit to inherit the type slots. Here we may inherit slots from
      +            // native classes in the MRO and things would get complicated if we did not follow
      +            // CPython structure.
      +            //
      +            // - type_ready_set_hash: sets tp_hash=PyObject_HashNotImplemented and __hash__=None
      +            // if tp_hash is NULL (it must be, this is managed class) and there's no __hash__
      +            // magic method.
      +            //
      +            // - fixup_slot_dispatchers to set the slots according to magic methods.
      +
      +            Builder inheritedSlots = TpSlots.buildInherited(newType, namespace, getMroStorageNode.execute(inliningTarget, newType), true);
      +            // type_ready_set_hash
      +            if (inheritedSlots.get(TpSlotMeta.TP_HASH) == null) {
      +                Object dunderHash = getItemNamespace.execute(inliningTarget, namespace.getDictStorage(), T___HASH__);
      +                if (dunderHash == null) {
      +                    inheritedSlots.set(TpSlotMeta.TP_HASH, TpSlotHashFun.HASH_NOT_IMPLEMENTED);
      +                    newType.setAttribute(T___HASH__, PNone.NONE);
      +                }
      +            }
      +            TpSlots.fixupSlotDispatchers(newType, inheritedSlots);
      +            newType.setTpSlots(inheritedSlots.build());
       
      -                SpecialMethodSlot.initializeSpecialMethodSlots(newType, getMroStorageNode.execute(inliningTarget, newType), language);
      -
      -                // Initialization of the type slots:
      -                //
      -                // For now, we have the same helper functions as CPython and we execute them in the
      -                // same order even-though we could squash them and optimize the wrapping and
      -                // unwrapping of slots, but it would be more difficult to make sure that at the end
      -                // of the day we produce exactly the same results, especially if there are native
      -                // types in the MRO (we can, e.g., optimize this only for pure Python types to keep
      -                // it still simple).
      -                //
      -                // From CPython point of view: we are in "type_new_impl", we call PyType_Ready,
      -                // which calls type_ready_inherit to inherit the slots, and then
      -                // fixup_slot_dispatchers to set the slots according to magic methods.
      -                //
      -                // We do not need to map slots to magic methods (add_operators in CPython), because
      -                // this is a managed class and it cannot define its own slots.
      -                TpSlots.inherit(newType, getMroStorageNode.execute(inliningTarget, newType), true);
      -                TpSlots.fixupSlotDispatchers(newType);
      -
      -                HashingStorage storage = namespace.getDictStorage();
      -                HashingStorageIterator it = getIterator.execute(inliningTarget, storage);
      -                while (itNext.execute(inliningTarget, storage, it)) {
      -                    Object value = itValue.execute(inliningTarget, storage, it);
      -                    Object setName = getSetNameNode.execute(value);
      -                    if (setName != PNone.NO_VALUE) {
      -                        Object key = itKey.execute(inliningTarget, storage, it);
      -                        try {
      -                            callSetNameNode.execute(frame, setName, value, newType, key);
      -                        } catch (PException e) {
      -                            throw raise.raiseWithCause(PythonBuiltinClassType.RuntimeError, e.getEscapedException(), ErrorMessages.ERROR_CALLING_SET_NAME, value, key, newType);
      -                        }
      +            HashingStorage storage = namespace.getDictStorage();
      +            HashingStorageIterator it = getIterator.execute(inliningTarget, storage);
      +            while (itNext.execute(inliningTarget, storage, it)) {
      +                Object value = itValue.execute(inliningTarget, storage, it);
      +                Object setName = getSetNameNode.execute(frame, getClassNode.execute(inliningTarget, value), value);
      +                if (setName != PNone.NO_VALUE) {
      +                    Object key = itKey.execute(inliningTarget, storage, it);
      +                    try {
      +                        callSetNameNode.execute(frame, setName, value, newType, key);
      +                    } catch (PException e) {
      +                        throw raise.raiseWithCause(inliningTarget, PythonBuiltinClassType.RuntimeError, e, ErrorMessages.ERROR_CALLING_SET_NAME, value, key, newType);
                           }
                       }
      +            }
       
      -                // Call __init_subclass__ on the parent of a newly generated type
      -                SuperObject superObject = factory.createSuperObject(PythonBuiltinClassType.Super);
      -                superObject.init(newType, newType, newType);
      -                callInitSubclassNode.execute(frame, getInitSubclassNode.executeObject(frame, superObject), PythonUtils.EMPTY_OBJECT_ARRAY, kwds);
      +            // Call __init_subclass__ on the parent of a newly generated type
      +            SuperObject superObject = PFactory.createSuperObject(language);
      +            superObject.init(newType, newType, newType);
      +            callInitSubclassNode.execute(frame, getInitSubclassNode.executeObject(frame, superObject), PythonUtils.EMPTY_OBJECT_ARRAY, kwds);
       
      -                newType.initializeMroShape(language);
      +            newType.initializeMroShape(language);
       
      -                return newType;
      -            } finally {
      -                assert SpecialMethodSlot.popInitializedType();
      -            }
      +            return newType;
               }
       
               private TruffleString getModuleNameFromGlobals(Node inliningTarget, PythonObject globals, HashingStorageGetItem getItem) {
      @@ -2066,7 +2085,7 @@ private TruffleString getModuleNameFromGlobals(Node inliningTarget, PythonObject
               }
           }
       
      -    @ImportStatic({SpecialMethodNames.class, SpecialAttributeNames.class, SpecialMethodSlot.class})
      +    @ImportStatic({SpecialMethodNames.class, SpecialAttributeNames.class})
           @GenerateInline(false) // footprint reduction 208 -> 190
           protected abstract static class AllocateTypeWithMetaclassNode extends Node {
       
      @@ -2104,7 +2123,7 @@ static PythonClass typeMetaclass(VirtualFrame frame, TruffleString name, PTuple
                               @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
                               @Cached PRaiseNode raise,
                               @Cached GetObjectArrayNode getObjectArray,
      -                        @Cached PythonObjectFactory factory,
      +                        @Cached GetInstanceShape getInstanceShape,
                               @Cached CastToListNode castToListNode,
                               @Cached PyUnicodeCheckNode stringCheck,
                               @Cached TruffleString.IsValidNode isValidNode,
      @@ -2132,7 +2151,7 @@ static PythonClass typeMetaclass(VirtualFrame frame, TruffleString name, PTuple
                           } else if (array[i] instanceof PythonBuiltinClassType) {
                               basesArray[i] = core.lookupType((PythonBuiltinClassType) array[i]);
                           } else {
      -                        throw raise.raise(PythonBuiltinClassType.NotImplementedError, ErrorMessages.CREATING_CLASS_NON_CLS_BASES);
      +                        throw raise.raise(inliningTarget, PythonBuiltinClassType.NotImplementedError, ErrorMessages.CREATING_CLASS_NON_CLS_BASES);
                           }
                       }
                   }
      @@ -2145,35 +2164,23 @@ static PythonClass typeMetaclass(VirtualFrame frame, TruffleString name, PTuple
                       throw constructAndRaiseNode.get(inliningTarget).raiseUnicodeEncodeError(frame, "utf-8", name, 0, codePointLengthNode.execute(name, TS_ENCODING), "can't encode class name");
                   }
                   if (indexOfCodePointNode.execute(name, 0, 0, codePointLengthNode.execute(name, TS_ENCODING), TS_ENCODING) >= 0) {
      -                throw raise.raise(PythonBuiltinClassType.ValueError, ErrorMessages.TYPE_NAME_NO_NULL_CHARS);
      +                throw raise.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.TYPE_NAME_NO_NULL_CHARS);
                   }
       
                   // 1.) create class, but avoid calling mro method - it might try to access __dict__ so
                   // we have to copy dict slots first
      -            PythonClass pythonClass = factory.createPythonClass(metaclass, name, false, base, basesArray);
      -            assert SpecialMethodSlot.replaceInitializedTypeTop(pythonClass);
      +            PythonClass pythonClass = PFactory.createPythonClass(language, metaclass, getInstanceShape.execute(metaclass), name, false, base, basesArray);
       
                   // 2.) copy the dictionary slots
      -            copyDictSlots(frame, inliningTarget, ctx, pythonClass, namespace, setHashingStorageItem,
      +            copyDictSlots(frame, inliningTarget, language, ctx, pythonClass, namespace, setHashingStorageItem,
                                   getHashingStorageIterator, hashingStorageItNext, hashingStorageItKey, hashingStorageItKeyHash, hashingStorageItValue,
      -                            constructAndRaiseNode, factory, raise, isValidNode, equalNode, codePointLengthNode, getOrCreateDictNode, stringCheck, castToStringNode);
      +                            constructAndRaiseNode, raise, isValidNode, equalNode, codePointLengthNode, getOrCreateDictNode, stringCheck, castToStringNode);
                   if (!ctx.qualnameSet) {
                       pythonClass.setQualName(name);
                   }
       
                   // 3.) invoke metaclass mro() method
      -            pythonClass.invokeMro();
      -
      -            // CPython masks the __hash__ method with None when __eq__ is overriden, but __hash__ is
      -            // not
      -            HashingStorage namespaceStorage = namespace.getDictStorage();
      -            Object hashMethod = getHashingStorageItem.execute(frame, inliningTarget, namespaceStorage, SpecialMethodNames.T___HASH__);
      -            if (hashMethod == null) {
      -                Object eqMethod = getHashingStorageItem.execute(frame, inliningTarget, namespaceStorage, SpecialMethodNames.T___EQ__);
      -                if (eqMethod != null) {
      -                    pythonClass.setAttribute(SpecialMethodNames.T___HASH__, PNone.NONE);
      -                }
      -            }
      +            pythonClass.invokeMro(inliningTarget);
       
                   // may_add_dict = base->tp_dictoffset == 0
                   ctx.mayAddDict = !hasDictNode.execute(base);
      @@ -2207,7 +2214,7 @@ static PythonClass typeMetaclass(VirtualFrame frame, TruffleString name, PTuple
                       int slotlen = slotsStorage.length();
       
                       if (slotlen > 0 && hasItemSize) {
      -                    throw raise.raise(TypeError, ErrorMessages.NONEMPTY_SLOTS_NOT_ALLOWED_FOR_SUBTYPE_OF_S, base);
      +                    throw raise.raise(inliningTarget, TypeError, ErrorMessages.NONEMPTY_SLOTS_NOT_ALLOWED_FOR_SUBTYPE_OF_S, base);
                       }
       
                       for (int i = 0; i < slotlen; i++) {
      @@ -2217,20 +2224,20 @@ static PythonClass typeMetaclass(VirtualFrame frame, TruffleString name, PTuple
                           if (stringCheck.execute(inliningTarget, element)) {
                               slotName = castToStringNode.execute(inliningTarget, element);
                               if (!(boolean) isIdentifier.execute(frame, slotName)) {
      -                            throw raise.raise(TypeError, ErrorMessages.SLOTS_MUST_BE_IDENTIFIERS);
      +                            throw raise.raise(inliningTarget, TypeError, ErrorMessages.SLOTS_MUST_BE_IDENTIFIERS);
                               }
                           } else {
      -                        throw raise.raise(TypeError, ErrorMessages.MUST_BE_STRINGS_NOT_P, "__slots__ items", element);
      +                        throw raise.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_STRINGS_NOT_P, "__slots__ items", element);
                           }
                           if (equalNode.execute(slotName, T___DICT__, TS_ENCODING)) {
                               if (!ctx.mayAddDict || ctx.addDict) {
      -                            throw raise.raise(TypeError, ErrorMessages.DICT_SLOT_DISALLOWED_WE_GOT_ONE);
      +                            throw raise.raise(inliningTarget, TypeError, ErrorMessages.DICT_SLOT_DISALLOWED_WE_GOT_ONE);
                               }
                               ctx.addDict = true;
      -                        addDictDescrAttribute(basesArray, pythonClass, factory);
      +                        addDictDescrAttribute(basesArray, pythonClass, language);
                           } else if (equalNode.execute(slotName, T___WEAKREF__, TS_ENCODING)) {
                               if (!ctx.mayAddWeak || ctx.addWeak) {
      -                            throw raise.raise(TypeError, ErrorMessages.WEAKREF_SLOT_DISALLOWED_WE_GOT_ONE);
      +                            throw raise.raise(inliningTarget, TypeError, ErrorMessages.WEAKREF_SLOT_DISALLOWED_WE_GOT_ONE);
                               }
                               ctx.addWeak = true;
                           }
      @@ -2252,19 +2259,19 @@ static PythonClass typeMetaclass(VirtualFrame frame, TruffleString name, PTuple
                   int indexedSlotCount = getIndexedSlotsCountNode.execute(inliningTarget, base);
                   if (ctx.copiedSlots != null) {
                       for (TruffleString slotName : ctx.copiedSlots) {
      -                    IndexedSlotDescriptor slotDesc = factory.createIndexedSlotDescriptor(slotName, indexedSlotCount++, pythonClass);
      +                    IndexedSlotDescriptor slotDesc = PFactory.createIndexedSlotDescriptor(language, slotName, indexedSlotCount++, pythonClass);
                           pythonClass.setAttribute(slotName, slotDesc);
                       }
                   }
                   pythonClass.setIndexedSlotCount(indexedSlotCount);
       
                   if (ctx.addDict) {
      -                addDictDescrAttribute(basesArray, pythonClass, factory);
      +                addDictDescrAttribute(basesArray, pythonClass, language);
                   } else if (ctx.mayAddDict) {
                       pythonClass.setHasSlotsButNoDictFlag();
                   }
                   if (ctx.addWeak) {
      -                addWeakrefDescrAttribute(pythonClass, factory);
      +                addWeakrefDescrAttribute(pythonClass, language);
                   }
       
                   if (pythonClass.needsNativeAllocation()) {
      @@ -2296,31 +2303,31 @@ private static void typeNewSlotBases(TypeNewContext ctx, Object primaryBase, Pyt
               }
       
               @TruffleBoundary
      -        private static void addDictDescrAttribute(PythonAbstractClass[] basesArray, PythonClass pythonClass, PythonObjectFactory factory) {
      +        private static void addDictDescrAttribute(PythonAbstractClass[] basesArray, PythonClass pythonClass, PythonLanguage language) {
                   // Note: we need to avoid MRO lookup of __dict__ using slots because they are not
                   // initialized yet
                   if ((!hasPythonClassBases(basesArray) && LookupAttributeInMRONode.lookupSlowPath(pythonClass, T___DICT__) == PNone.NO_VALUE) || basesHaveSlots(basesArray)) {
                       Builtin dictBuiltin = ObjectBuiltins.DictNode.class.getAnnotation(Builtin.class);
                       RootCallTarget callTarget = PythonLanguage.get(null).createCachedCallTarget(
                                       l -> new BuiltinFunctionRootNode(l, dictBuiltin, ObjectBuiltinsFactory.DictNodeFactory.getInstance(), true), ObjectBuiltins.DictNode.class);
      -                setAttribute(T___DICT__, dictBuiltin, callTarget, pythonClass, factory);
      +                setAttribute(T___DICT__, dictBuiltin, callTarget, pythonClass, language);
                   }
               }
       
               @TruffleBoundary
      -        private static void addWeakrefDescrAttribute(PythonClass pythonClass, PythonObjectFactory factory) {
      +        private static void addWeakrefDescrAttribute(PythonClass pythonClass, PythonLanguage language) {
                   if (LookupAttributeInMRONode.lookupSlowPath(pythonClass, T___WEAKREF__) == PNone.NO_VALUE) {
                       Builtin builtin = GetWeakRefsNode.class.getAnnotation(Builtin.class);
                       RootCallTarget callTarget = PythonLanguage.get(null).createCachedCallTarget(
                                       l -> new BuiltinFunctionRootNode(l, builtin, WeakRefModuleBuiltinsFactory.GetWeakRefsNodeFactory.getInstance(), true), GetWeakRefsNode.class);
      -                setAttribute(T___WEAKREF__, builtin, callTarget, pythonClass, factory);
      +                setAttribute(T___WEAKREF__, builtin, callTarget, pythonClass, language);
                   }
               }
       
      -        private static void setAttribute(TruffleString name, Builtin builtin, RootCallTarget callTarget, PythonClass pythonClass, PythonObjectFactory factory) {
      +        private static void setAttribute(TruffleString name, Builtin builtin, RootCallTarget callTarget, PythonClass pythonClass, PythonLanguage language) {
                   int flags = PBuiltinFunction.getFlags(builtin, callTarget);
      -            PBuiltinFunction function = factory.createBuiltinFunction(name, pythonClass, 1, flags, callTarget);
      -            GetSetDescriptor desc = factory.createGetSetDescriptor(function, function, name, pythonClass, true);
      +            PBuiltinFunction function = PFactory.createBuiltinFunction(language, name, pythonClass, 1, flags, callTarget);
      +            GetSetDescriptor desc = PFactory.createGetSetDescriptor(language, function, function, name, pythonClass, true);
                   pythonClass.setAttribute(name, desc);
               }
       
      @@ -2410,10 +2417,11 @@ private static long installMemberDescriptors(PythonManagedClass pythonClass, Tru
                   return slotOffset;
               }
       
      -        private static void copyDictSlots(VirtualFrame frame, Node inliningTarget, TypeNewContext ctx, PythonClass pythonClass, PDict namespace, HashingStorageSetItemWithHash setHashingStorageItem,
      +        private static void copyDictSlots(VirtualFrame frame, Node inliningTarget, PythonLanguage language, TypeNewContext ctx, PythonClass pythonClass, PDict namespace,
      +                        HashingStorageSetItemWithHash setHashingStorageItem,
                               HashingStorageGetIterator getHashingStorageIterator, HashingStorageIteratorNext hashingStorageItNext, HashingStorageIteratorKey hashingStorageItKey,
                               HashingStorageIteratorKeyHash hashingStorageItKeyHash, HashingStorageIteratorValue hashingStorageItValue,
      -                        PConstructAndRaiseNode.Lazy constructAndRaiseNode, PythonObjectFactory factory, PRaiseNode raise, IsValidNode isValidNode,
      +                        PConstructAndRaiseNode.Lazy constructAndRaiseNode, PRaiseNode raise, IsValidNode isValidNode,
                               EqualNode equalNode, CodePointLengthNode codePointLengthNode, GetOrCreateDictNode getOrCreateDictNode, PyUnicodeCheckNode stringCheck,
                               CastToTruffleStringNode castToStringNode) {
                   // copy the dictionary slots over, as CPython does through PyDict_Copy
      @@ -2433,7 +2441,7 @@ private static void copyDictSlots(VirtualFrame frame, Node inliningTarget, TypeN
                           if (equalNode.execute(T___NEW__, key, TS_ENCODING)) {
                               // see CPython: if it's a plain function, make it a static function
                               if (value instanceof PFunction) {
      -                            pythonClass.setAttribute(key, factory.createStaticmethodFromCallableObj(value));
      +                            pythonClass.setAttribute(key, PFactory.createStaticmethodFromCallableObj(language, value));
                               } else {
                                   pythonClass.setAttribute(key, value);
                               }
      @@ -2444,7 +2452,7 @@ private static void copyDictSlots(VirtualFrame frame, Node inliningTarget, TypeN
                               // __class_getitem__: if they are plain functions, make them
                               // classmethods
                               if (value instanceof PFunction) {
      -                            pythonClass.setAttribute(key, factory.createClassmethodFromCallableObj(value));
      +                            pythonClass.setAttribute(key, PFactory.createClassmethodFromCallableObj(language, value));
                               } else {
                                   pythonClass.setAttribute(key, value);
                               }
      @@ -2471,7 +2479,7 @@ private static void copyDictSlots(VirtualFrame frame, Node inliningTarget, TypeN
                                   pythonClass.setQualName(castToStringNode.execute(inliningTarget, value));
                                   ctx.qualnameSet = true;
                               } catch (CannotCastException e) {
      -                            throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.MUST_BE_S_NOT_P, "type __qualname__", "str", value);
      +                            throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.MUST_BE_S_NOT_P, "type __qualname__", "str", value);
                               }
                               continue;
                           }
      @@ -2510,7 +2518,7 @@ private static TruffleString[] copySlots(Node inliningTarget, TypeNewContext ctx
                       try {
                           slotName = PythonUtils.mangleName(className, slotName);
                       } catch (OutOfMemoryError e) {
      -                    throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.OverflowError, ErrorMessages.PRIVATE_IDENTIFIER_TOO_LARGE_TO_BE_MANGLED);
      +                    throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.OverflowError, ErrorMessages.PRIVATE_IDENTIFIER_TOO_LARGE_TO_BE_MANGLED);
                       }
                       if (slotName == null) {
                           return null;
      @@ -2522,7 +2530,7 @@ private static TruffleString[] copySlots(Node inliningTarget, TypeNewContext ctx
                       if (!T___CLASSCELL__.equalsUncached(slotName, TS_ENCODING) && !T___QUALNAME__.equalsUncached(slotName, TS_ENCODING) &&
                                       HashingStorageGetItem.hasKeyUncached(namespace.getDictStorage(), slotName)) {
                           // __qualname__ and __classcell__ will be deleted later
      -                    throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.S_S_CONFLICTS_WITH_CLASS_VARIABLE, slotName, "__slots__");
      +                    throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.S_S_CONFLICTS_WITH_CLASS_VARIABLE, slotName, "__slots__");
                       }
                       j++;
                   }
      @@ -2753,101 +2761,122 @@ static boolean doOther(@SuppressWarnings("unused") Object cls) {
           @GenerateUncached
           @GenerateInline
           @GenerateCached(false)
      -    @ImportStatic(SpecialMethodSlot.class)
           public abstract static class HasSameConstructorNode extends Node {
       
               public abstract boolean execute(Node inliningTarget, Object leftClass, Object rightClass);
       
               @Specialization
               static boolean doGeneric(Node inliningTarget, Object left, Object right,
      -                        @Cached(parameters = "New", inline = false) LookupCallableSlotInMRONode lookupLeftNode,
      -                        @Cached(parameters = "New", inline = false) LookupCallableSlotInMRONode lookupRightNode,
      +                        @Cached(inline = false) LookupAttributeInMRONode.Dynamic lookupNew,
                               @Cached InlinedExactClassProfile leftNewProfile,
                               @Cached InlinedExactClassProfile rightNewProfile) {
                   assert IsTypeNode.executeUncached(left);
                   assert IsTypeNode.executeUncached(right);
       
      -            Object leftNew = leftNewProfile.profile(inliningTarget, lookupLeftNode.execute(left));
      -            Object rightNew = rightNewProfile.profile(inliningTarget, lookupRightNode.execute(right));
      -            return isSameFunction(leftNew, rightNew);
      -        }
      -
      -        static boolean isSameFunction(Object leftFunc, Object rightFunc) {
      -            Object leftResolved = leftFunc;
      -            if (leftFunc instanceof PBuiltinFunction builtinFunction) {
      -                Object typeDecorated = HPyObjectNewNode.getDecoratedSuperConstructor(builtinFunction);
      -                if (typeDecorated != null) {
      -                    leftResolved = typeDecorated;
      -                }
      -            }
      -            Object rightResolved = rightFunc;
      -            if (rightFunc instanceof PBuiltinFunction builtinFunction) {
      -                Object baseDecorated = HPyObjectNewNode.getDecoratedSuperConstructor(builtinFunction);
      -                if (baseDecorated != null) {
      -                    rightResolved = baseDecorated;
      -                }
      -            }
      -            return leftResolved == rightResolved;
      +            Object leftNew = leftNewProfile.profile(inliningTarget, lookupNew.execute(left, T___NEW__));
      +            Object rightNew = rightNewProfile.profile(inliningTarget, lookupNew.execute(right, T___NEW__));
      +            return leftNew == rightNew;
               }
           }
       
           /**
      -     * Check whether a given function, method or slot descriptor is a specific builtin function.
      -     * Used in cases where CPython compares slot for referential equality with a C function to check
      -     * for overriding, for example {@code type->tp_init == object_init}. For object {@code __init__}
      -     * in particular, there is a shortcut node {@link HasObjectInitNode}.
      +     * Check whether given type didn't override default object {@code __init__}. Equivalent of
      +     * CPython's {@code type->tp_init == object_init} check.
            */
      -    @GenerateInline
      -    @GenerateCached(false)
      -    @GenerateUncached
      -    public abstract static class CheckCallableIsSpecificBuiltinNode extends Node {
      -        public abstract boolean execute(Node inliningTarget, Object methodOrDescriptor, NodeFactory nodeFactory);
      +    @GenerateInline(inlineByDefault = true)
      +    public abstract static class HasObjectInitNode extends Node {
      +        public abstract boolean execute(Node inliningTarget, Object type);
       
      -        public static boolean executeUncached(Object methodOrDescriptor, NodeFactory nodeFactory) {
      -            return TypeNodesFactory.CheckCallableIsSpecificBuiltinNodeGen.getUncached().execute(null, methodOrDescriptor, nodeFactory);
      +        public final boolean executeCached(Object type) {
      +            return execute(this, type);
               }
       
               @Specialization
      -        static boolean check(PBuiltinFunction function, NodeFactory nodeFactory) {
      -            return function.getBuiltinNodeFactory() == nodeFactory;
      +        static boolean check(Node inliningTarget, Object type,
      +                        @Cached GetCachedTpSlotsNode getSlots) {
      +            TpSlots slots = getSlots.execute(inliningTarget, type);
      +            return slots.tp_init() == ObjectBuiltins.SLOTS.tp_init();
               }
      +    }
       
      -        @Specialization
      -        static boolean check(PBuiltinMethod method, NodeFactory nodeFactory) {
      -            return method.getBuiltinFunction().getBuiltinNodeFactory() == nodeFactory;
      -        }
      +    /** Equivalent of CPython's {@code recursive_isinstance} */
      +    @GenerateInline
      +    @GenerateCached(false)
      +    public abstract static class GenericInstanceCheckNode extends Node {
      +
      +        public abstract boolean execute(VirtualFrame frame, Node inliningTarget, Object instance, Object cls);
      +
      +        @Specialization(guards = "isTypeNode.execute(inliningTarget, cls)", limit = "1")
      +        static boolean isInstance(VirtualFrame frame, Node inliningTarget, Object instance, Object cls,
      +                        @Cached PyObjectLookupAttr lookupAttr,
      +                        @Cached IsTypeNode isTypeNode,
      +                        @Cached InlinedConditionProfile classSameResult,
      +                        @Cached GetClassNode getClassNode,
      +                        @Cached IsSubtypeNode isSubtypeNode) {
      +            Object type = getClassNode.execute(inliningTarget, instance);
      +            if (isSubtypeNode.execute(type, cls)) {
      +                return true;
      +            }
       
      -        @Specialization
      -        static boolean check(BuiltinMethodDescriptor descriptor, NodeFactory nodeFactory) {
      -            return descriptor.getFactory() == nodeFactory;
      +            Object instanceClass = lookupAttr.execute(frame, inliningTarget, instance, T___CLASS__);
      +            if (classSameResult.profile(inliningTarget, instanceClass == type)) {
      +                // We already did a check on this type
      +                return false;
      +            } else if (isTypeNode.execute(inliningTarget, instanceClass)) {
      +                return isSubtypeNode.execute(instanceClass, cls);
      +            } else {
      +                return false;
      +            }
               }
       
               @Fallback
      -        @SuppressWarnings("unused")
      -        static boolean check(Object descriptor, NodeFactory nodeFactory) {
      -            return false;
      +        static boolean isInstance(VirtualFrame frame, Node inliningTarget, Object instance, Object cls,
      +                        @Cached PyObjectLookupAttr lookupAttr,
      +                        @Cached AbstractObjectIsSubclassNode abstractIsSubclassNode,
      +                        @Cached AbstractObjectGetBasesNode getBasesNode,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (getBasesNode.execute(frame, inliningTarget, cls) == null) {
      +                throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.ISINSTANCE_ARG_2_MUST_BE_TYPE_OR_TUPLE_OF_TYPE, instance);
      +            }
      +
      +            Object instanceClass = lookupAttr.execute(frame, inliningTarget, instance, T___CLASS__);
      +            if (instanceClass != NO_VALUE) {
      +                return abstractIsSubclassNode.execute(frame, instanceClass, cls);
      +            } else {
      +                return false;
      +            }
               }
           }
       
      -    /**
      -     * Check whether given type didn't override default object {@code __init__}. Equivalent of
      -     * CPython's {@code type->tp_init == object_init} check.
      -     */
      -    @GenerateInline(inlineByDefault = true)
      -    @ImportStatic(SpecialMethodSlot.class)
      -    public abstract static class HasObjectInitNode extends Node {
      -        public abstract boolean execute(Node inliningTarget, Object type);
      +    /** Equivalent of CPython's {@code recursive_issubclass} */
      +    @GenerateInline
      +    @GenerateCached(false)
      +    public abstract static class GenericSubclassCheckNode extends Node {
       
      -        public final boolean executeCached(Object type) {
      -            return execute(this, type);
      +        public abstract boolean execute(VirtualFrame frame, Node inliningTarget, Object derived, Object cls);
      +
      +        @Specialization(guards = {"isTypeNode.execute(inliningTarget, cls)", "isTypeNode.execute(inliningTarget, derived)"}, limit = "1")
      +        static boolean doTypes(Node inliningTarget, Object derived, Object cls,
      +                        @SuppressWarnings("unused") @Cached IsTypeNode isTypeNode,
      +                        @Cached IsSameTypeNode isSameTypeNode,
      +                        @Cached IsSubtypeNode isSubtypeNode) {
      +            return isSameTypeNode.execute(inliningTarget, cls, derived) || isSubtypeNode.execute(derived, cls);
               }
       
      -        @Specialization
      -        static boolean check(Node inliningTarget, Object type,
      -                        @Cached(parameters = "Init", inline = false) LookupCallableSlotInMRONode lookup,
      -                        @Cached CheckCallableIsSpecificBuiltinNode check) {
      -            Object slot = lookup.execute(type);
      -            return check.execute(inliningTarget, slot, ObjectBuiltinsFactory.InitNodeFactory.getInstance());
      +        @Fallback
      +        @InliningCutoff
      +        static boolean doObjects(VirtualFrame frame, Node inliningTarget, Object derived, Object cls,
      +                        @Cached AbstractObjectGetBasesNode getBasesNode,
      +                        @Cached AbstractObjectIsSubclassNode abstractIsSubclassNode,
      +                        @Cached PRaiseNode raiseDerived,
      +                        @Cached PRaiseNode raiseCls) {
      +            if (getBasesNode.execute(frame, inliningTarget, derived) == null) {
      +                throw raiseDerived.raise(inliningTarget, TypeError, ErrorMessages.ARG_D_MUST_BE_S, "issubclass()", 1, "class");
      +            }
      +            if (getBasesNode.execute(frame, inliningTarget, cls) == null) {
      +                throw raiseCls.raise(inliningTarget, TypeError, ErrorMessages.ISSUBCLASS_MUST_BE_CLASS_OR_TUPLE);
      +            }
      +            return abstractIsSubclassNode.execute(frame, derived, cls);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/BuiltinDispatchers.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/BuiltinDispatchers.java
      deleted file mode 100644
      index 8a5079c5e0..0000000000
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/BuiltinDispatchers.java
      +++ /dev/null
      @@ -1,77 +0,0 @@
      -/*
      - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
      - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      - *
      - * The Universal Permissive License (UPL), Version 1.0
      - *
      - * Subject to the condition set forth below, permission is hereby granted to any
      - * person obtaining a copy of this software, associated documentation and/or
      - * data (collectively the "Software"), free of charge and under any and all
      - * copyright rights in the Software, and any and all patent rights owned or
      - * freely licensable by each licensor hereunder covering either (i) the
      - * unmodified Software as contributed to or provided by such licensor, or (ii)
      - * the Larger Works (as defined below), to deal in both
      - *
      - * (a) the Software, and
      - *
      - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
      - * one is included with the Software each a "Larger Work" to which the Software
      - * is contributed by such licensors),
      - *
      - * without restriction, including without limitation the rights to copy, create
      - * derivative works of, display, perform, and distribute the Software and make,
      - * use, sell, offer for sale, import, export, have made, and have sold the
      - * Software and the Larger Work(s), and to sublicense the foregoing rights on
      - * either these or other terms.
      - *
      - * This license is subject to the following condition:
      - *
      - * The above copyright notice and either this complete permission notice or at a
      - * minimum a reference to the UPL must be included in all copies or substantial
      - * portions of the Software.
      - *
      - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      - * SOFTWARE.
      - */
      -package com.oracle.graal.python.builtins.objects.type.slots;
      -
      -import com.oracle.graal.python.PythonLanguage;
      -import com.oracle.graal.python.runtime.ExecutionContext.CallContext;
      -import com.oracle.graal.python.runtime.ExecutionContext.IndirectCalleeContext;
      -import com.oracle.graal.python.runtime.PythonContext;
      -import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
      -import com.oracle.truffle.api.CallTarget;
      -import com.oracle.truffle.api.frame.VirtualFrame;
      -import com.oracle.truffle.api.nodes.IndirectCallNode;
      -import com.oracle.truffle.api.nodes.Node;
      -import com.oracle.truffle.api.profiles.InlinedConditionProfile;
      -
      -public class BuiltinDispatchers {
      -    static Object callGenericBuiltin(VirtualFrame frame, Node inliningTarget, int callTargetIndex, Object[] arguments,
      -                    CallContext callContext, InlinedConditionProfile isNullFrameProfile, IndirectCallNode indirectCallNode) {
      -        PythonLanguage language = PythonLanguage.get(inliningTarget);
      -        CallTarget callTarget = language.getBuiltinSlotCallTarget(callTargetIndex);
      -        if (isNullFrameProfile.profile(inliningTarget, frame != null)) {
      -            callContext.prepareIndirectCall(frame, arguments, inliningTarget);
      -            return indirectCallNode.call(callTarget, arguments);
      -        } else {
      -            return callWithNullFrame(inliningTarget, indirectCallNode, language, arguments, callTarget);
      -        }
      -    }
      -
      -    private static Object callWithNullFrame(Node inliningTarget, IndirectCallNode indirectCallNode, PythonLanguage language, Object[] arguments, CallTarget callTarget) {
      -        PythonContext context = PythonContext.get(inliningTarget);
      -        PythonThreadState threadState = context.getThreadState(language);
      -        Object state = IndirectCalleeContext.enterIndirect(threadState, arguments);
      -        try {
      -            return indirectCallNode.call(callTarget, arguments);
      -        } finally {
      -            IndirectCalleeContext.exit(threadState, state);
      -        }
      -    }
      -}
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/BuiltinSlotWrapperSignature.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/BuiltinSlotWrapperSignature.java
      index cafd60aae0..7821b0d686 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/BuiltinSlotWrapperSignature.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/BuiltinSlotWrapperSignature.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/PythonDispatchers.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/PythonDispatchers.java
      index 0f9085ce7d..361747db39 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/PythonDispatchers.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/PythonDispatchers.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,15 +40,16 @@
        */
       package com.oracle.graal.python.builtins.objects.type.slots;
       
      +import com.oracle.graal.python.builtins.objects.PNotImplemented;
       import com.oracle.graal.python.builtins.objects.function.PArguments;
       import com.oracle.graal.python.builtins.objects.function.PFunction;
       import com.oracle.graal.python.builtins.objects.function.Signature;
      -import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PNodeWithContext;
       import com.oracle.graal.python.nodes.call.BoundDescriptor;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
       import com.oracle.graal.python.nodes.call.CallNode;
      -import com.oracle.graal.python.nodes.call.FunctionInvokeNode;
       import com.oracle.graal.python.nodes.call.special.MaybeBindDescriptorNode;
      +import com.oracle.graal.python.runtime.exception.PException;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.truffle.api.CompilerAsserts;
       import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
      @@ -58,9 +59,9 @@
       import com.oracle.truffle.api.dsl.GenerateUncached;
       import com.oracle.truffle.api.dsl.Idempotent;
       import com.oracle.truffle.api.dsl.ImportStatic;
      -import com.oracle.truffle.api.dsl.NeverDefault;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      +import com.oracle.truffle.api.nodes.DirectCallNode;
       import com.oracle.truffle.api.nodes.Node;
       import com.oracle.truffle.api.utilities.TruffleWeakReference;
       
      @@ -78,17 +79,12 @@ static boolean isSimpleSignature(PFunction callable, int positionArgsCount) {
                   CompilerAsserts.partialEvaluationConstant(result); // should hold in single context
                   return result;
               }
      -
      -        @NeverDefault
      -        static FunctionInvokeNode createInvokeNode(PFunction callee) {
      -            return FunctionInvokeNode.create(callee);
      -        }
           }
       
           @GenerateUncached
           @GenerateInline
           @GenerateCached(false)
      -    @ImportStatic(PGuards.class)
      +    @ImportStatic(CallDispatchers.class)
           abstract static class UnaryPythonSlotDispatcherNode extends PythonSlotDispatcherNodeBase {
               final Object execute(VirtualFrame frame, Node inliningTarget, Object callable, Object type, Object self) {
                   assert !(callable instanceof TruffleWeakReference);
      @@ -100,12 +96,13 @@ final Object execute(VirtualFrame frame, Node inliningTarget, Object callable, O
       
               @Specialization(guards = {"isSingleContext()", "callee == cachedCallee", "isSimpleSignature(cachedCallee, 1)"}, //
                               limit = "getCallSiteInlineCacheMaxDepth()", assumptions = "cachedCallee.getCodeStableAssumption()")
      -        protected static Object doCachedPFunction(VirtualFrame frame, @SuppressWarnings("unused") PFunction callee, @SuppressWarnings("unused") Object type, Object self,
      +        protected static Object doCachedPFunction(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") PFunction callee, @SuppressWarnings("unused") Object type, Object self,
                               @SuppressWarnings("unused") @Cached("callee") PFunction cachedCallee,
      -                        @Cached("createInvokeNode(cachedCallee)") FunctionInvokeNode invoke) {
      +                        @Cached("createDirectCallNodeFor(callee)") DirectCallNode callNode,
      +                        @Cached CallDispatchers.FunctionDirectInvokeNode invoke) {
                   Object[] arguments = PArguments.create(1);
                   PArguments.setArgument(arguments, 0, self);
      -            return invoke.execute(frame, arguments);
      +            return invoke.execute(frame, inliningTarget, callNode, cachedCallee, arguments);
               }
       
               @Specialization(replaces = "doCachedPFunction")
      @@ -130,32 +127,51 @@ static Object doGeneric(VirtualFrame frame, Node inliningTarget, Object callable
           @GenerateUncached
           @GenerateInline
           @GenerateCached(false)
      +    @ImportStatic(CallDispatchers.class)
           abstract static class BinaryPythonSlotDispatcherNode extends PythonSlotDispatcherNodeBase {
               final Object execute(VirtualFrame frame, Node inliningTarget, Object callable, Object type, Object self, Object arg1) {
                   assert !(callable instanceof TruffleWeakReference);
                   assert !(type instanceof TruffleWeakReference);
      -            return executeImpl(frame, inliningTarget, callable, type, self, arg1);
      +            return executeImpl(frame, inliningTarget, callable, type, self, arg1, false);
      +        }
      +
      +        final Object executeIgnoreDescriptorBindErrors(VirtualFrame frame, Node inliningTarget, Object callable, Object type, Object self, Object arg1) {
      +            assert !(callable instanceof TruffleWeakReference);
      +            assert !(type instanceof TruffleWeakReference);
      +            return executeImpl(frame, inliningTarget, callable, type, self, arg1, true);
               }
       
      -        abstract Object executeImpl(VirtualFrame frame, Node inliningTarget, Object callable, Object type, Object self, Object arg1);
      +        abstract Object executeImpl(VirtualFrame frame, Node inliningTarget, Object callable, Object type, Object self, Object arg1, boolean ignoreDescBindErrors);
       
               @Specialization(guards = {"isSingleContext()", "callee == cachedCallee", "isSimpleSignature(cachedCallee, 2)"}, //
                               limit = "getCallSiteInlineCacheMaxDepth()", assumptions = "cachedCallee.getCodeStableAssumption()")
      -        protected static Object doCachedPFunction(VirtualFrame frame, @SuppressWarnings("unused") PFunction callee, @SuppressWarnings("unused") Object type, Object self, Object arg1,
      +        protected static Object doCachedPFunction(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") PFunction callee, @SuppressWarnings("unused") Object type, Object self,
      +                        Object arg1,
      +                        boolean ignoreDescBindErrors,
                               @SuppressWarnings("unused") @Cached("callee") PFunction cachedCallee,
      -                        @Cached("createInvokeNode(cachedCallee)") FunctionInvokeNode invoke) {
      +                        @Cached("createDirectCallNodeFor(callee)") DirectCallNode callNode,
      +                        @Cached CallDispatchers.FunctionDirectInvokeNode invoke) {
                   Object[] arguments = PArguments.create(2);
                   PArguments.setArgument(arguments, 0, self);
                   PArguments.setArgument(arguments, 1, arg1);
      -            return invoke.execute(frame, arguments);
      +            return invoke.execute(frame, inliningTarget, callNode, cachedCallee, arguments);
               }
       
               @Specialization(replaces = "doCachedPFunction")
               @InliningCutoff
      -        static Object doGeneric(VirtualFrame frame, Node inliningTarget, Object callableObj, Object type, Object self, Object arg1,
      +        static Object doGeneric(VirtualFrame frame, Node inliningTarget, Object callableObj, Object type, Object self, Object arg1, boolean ignoreDescBindErrors,
                               @Cached MaybeBindDescriptorNode bindDescriptorNode,
                               @Cached(inline = false) CallNode callNode) {
      -            Object bound = bindDescriptorNode.execute(frame, inliningTarget, callableObj, self, type);
      +            Object bound;
      +            try {
      +                bound = bindDescriptorNode.execute(frame, inliningTarget, callableObj, self, type);
      +            } catch (PException ex) {
      +                if (ignoreDescBindErrors) {
      +                    return PNotImplemented.NOT_IMPLEMENTED;
      +                } else {
      +                    throw ex;
      +                }
      +            }
                   Object[] arguments;
                   Object callable;
                   if (bound instanceof BoundDescriptor boundDescr) {
      @@ -172,6 +188,7 @@ static Object doGeneric(VirtualFrame frame, Node inliningTarget, Object callable
           @GenerateUncached
           @GenerateInline
           @GenerateCached(false)
      +    @ImportStatic(CallDispatchers.class)
           abstract static class TernaryPythonSlotDispatcherNode extends PythonSlotDispatcherNodeBase {
               final Object execute(VirtualFrame frame, Node inliningTarget, Object callable, Object type, Object self, Object arg1, Object arg2) {
                   assert !(callable instanceof TruffleWeakReference);
      @@ -183,15 +200,16 @@ final Object execute(VirtualFrame frame, Node inliningTarget, Object callable, O
       
               @Specialization(guards = {"isSingleContext()", "callee == cachedCallee", "isSimpleSignature(cachedCallee, 3)"}, //
                               limit = "getCallSiteInlineCacheMaxDepth()", assumptions = "cachedCallee.getCodeStableAssumption()")
      -        protected static Object doCachedPFunction(VirtualFrame frame, @SuppressWarnings("unused") PFunction callee, @SuppressWarnings("unused") Object type, Object self,
      +        protected static Object doCachedPFunction(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") PFunction callee, @SuppressWarnings("unused") Object type, Object self,
                               Object arg1, Object arg2,
                               @SuppressWarnings("unused") @Cached("callee") PFunction cachedCallee,
      -                        @Cached("createInvokeNode(cachedCallee)") FunctionInvokeNode invoke) {
      +                        @Cached("createDirectCallNodeFor(callee)") DirectCallNode callNode,
      +                        @Cached CallDispatchers.FunctionDirectInvokeNode invoke) {
                   Object[] arguments = PArguments.create(3);
                   PArguments.setArgument(arguments, 0, self);
                   PArguments.setArgument(arguments, 1, arg1);
                   PArguments.setArgument(arguments, 2, arg2);
      -            return invoke.execute(frame, arguments);
      +            return invoke.execute(frame, inliningTarget, callNode, cachedCallee, arguments);
               }
       
               @Specialization(replaces = "doCachedPFunction")
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/Slot2Builtin.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/Slot2Builtin.java
      index a866813b67..4acd65aa27 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/Slot2Builtin.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/Slot2Builtin.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -44,8 +44,8 @@
       
       import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
      -import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonOS;
      +import com.oracle.graal.python.util.PythonUtils;
       
       /**
        * Adopts the {@link SlotSignature} annotation to {@link Builtin} annotation, so that the builtin
      @@ -82,16 +82,6 @@ public PythonOS os() {
               return PythonOS.PLATFORM_ANY;
           }
       
      -    @Override
      -    public PythonBuiltinClassType constructsClass() {
      -        return PythonBuiltinClassType.nil;
      -    }
      -
      -    @Override
      -    public PythonBuiltinClassType[] base() {
      -        return new PythonBuiltinClassType[0];
      -    }
      -
           @Override
           public int minNumOfPositionalArgs() {
               return signature != null ? signature.minNumOfPositionalArgs() : annotation.minNumOfPositionalArgs();
      @@ -99,12 +89,12 @@ public int minNumOfPositionalArgs() {
       
           @Override
           public int maxNumOfPositionalArgs() {
      -        return -1;
      +        return annotation != null ? annotation.maxNumOfPositionalArgs() : -1;
           }
       
           @Override
           public int numOfPositionalOnlyArgs() {
      -        return -1;
      +        return annotation != null ? annotation.numOfPositionalOnlyArgs() : -1;
           }
       
           @Override
      @@ -127,14 +117,9 @@ public boolean takesVarArgs() {
               return annotation != null && annotation.takesVarArgs();
           }
       
      -    @Override
      -    public boolean varArgsMarker() {
      -        return false;
      -    }
      -
           @Override
           public boolean takesVarKeywordArgs() {
      -        return false;
      +        return annotation != null && annotation.takesVarKeywordArgs();
           }
       
           @Override
      @@ -144,12 +129,7 @@ public String[] parameterNames() {
       
           @Override
           public String[] keywordOnlyNames() {
      -        return new String[0];
      -    }
      -
      -    @Override
      -    public boolean isPublic() {
      -        return true;
      +        return annotation != null ? annotation.keywordOnlyNames() : PythonUtils.EMPTY_STRING_ARRAY;
           }
       
           @Override
      @@ -177,14 +157,9 @@ public boolean declaresExplicitSelf() {
               return false;
           }
       
      -    @Override
      -    public boolean reverseOperation() {
      -        return false;
      -    }
      -
           @Override
           public String raiseErrorName() {
      -        return annotation != null ? annotation.raiseErrorName() : "";
      +        return annotation != null ? annotation.name() : "";
           }
       
           @Override
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/SlotWrapperDocstrings.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/SlotWrapperDocstrings.java
      new file mode 100644
      index 0000000000..032f1dc8c4
      --- /dev/null
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/SlotWrapperDocstrings.java
      @@ -0,0 +1,135 @@
      +/*
      + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
      + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      + *
      + * The Universal Permissive License (UPL), Version 1.0
      + *
      + * Subject to the condition set forth below, permission is hereby granted to any
      + * person obtaining a copy of this software, associated documentation and/or
      + * data (collectively the "Software"), free of charge and under any and all
      + * copyright rights in the Software, and any and all patent rights owned or
      + * freely licensable by each licensor hereunder covering either (i) the
      + * unmodified Software as contributed to or provided by such licensor, or (ii)
      + * the Larger Works (as defined below), to deal in both
      + *
      + * (a) the Software, and
      + *
      + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
      + * one is included with the Software each a "Larger Work" to which the Software
      + * is contributed by such licensors),
      + *
      + * without restriction, including without limitation the rights to copy, create
      + * derivative works of, display, perform, and distribute the Software and make,
      + * use, sell, offer for sale, import, export, have made, and have sold the
      + * Software and the Larger Work(s), and to sublicense the foregoing rights on
      + * either these or other terms.
      + *
      + * This license is subject to the following condition:
      + *
      + * The above copyright notice and either this complete permission notice or at a
      + * minimum a reference to the UPL must be included in all copies or substantial
      + * portions of the Software.
      + *
      + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      + * SOFTWARE.
      + */
      +package com.oracle.graal.python.builtins.objects.type.slots;
      +
      +import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
      +
      +import com.oracle.truffle.api.strings.TruffleString;
      +
      +public enum SlotWrapperDocstrings {
      +    __repr__("Return repr(self)."),
      +    __hash__("Return hash(self)."),
      +    __call__("Call self as a function."),
      +    __str__("Return str(self)."),
      +    __getattribute__("Return getattr(self, name)."),
      +    __setattr__("Implement setattr(self, name, value)."),
      +    __delattr__("Implement delattr(self, name)."),
      +    __lt__("Return selfvalue."),
      +    __ge__("Return self>=value."),
      +    __iter__("Implement iter(self)."),
      +    __next__("Implement next(self)."),
      +    __get__("Return an attribute of instance, which is of type owner."),
      +    __set__("Set an attribute of instance to value."),
      +    __delete__("Delete an attribute of instance."),
      +    __init__("Initialize self.  See help(type(self)) for accurate signature."),
      +    __new__("Create and return new object.  See help(type) for accurate signature."),
      +    __await__("Return an iterator to be used in await expression."),
      +    __aiter__("Return an awaitable, that resolves in asynchronous iterator."),
      +    __anext__("Return a value or raise StopAsyncIteration."),
      +    __add__("Return self+value."),
      +    __radd__("Return value+self."),
      +    __sub__("Return self-value."),
      +    __rsub__("Return value-self."),
      +    __mul__("Return self*value."),
      +    __rmul__("Return value*self."),
      +    __mod__("Return self%value."),
      +    __rmod__("Return value%self."),
      +    __divmod__("Return divmod(self, value)."),
      +    __rdivmod__("Return divmod(value, self)."),
      +    __pow__("Return pow(self, value, mod)."),
      +    __rpow__("Return pow(value, self, mod)."),
      +    __neg__("-self"),
      +    __pos__("+self"),
      +    __abs__("abs(self)"),
      +    __bool__("True if self else False"),
      +    __invert__("~self"),
      +    __lshift__("Return self<>value."),
      +    __rrshift__("Return value>>self."),
      +    __and__("Return self&value."),
      +    __rand__("Return value&self."),
      +    __xor__("Return self^value."),
      +    __rxor__("Return value^self."),
      +    __or__("Return self|value."),
      +    __ror__("Return value|self."),
      +    __int__("int(self)"),
      +    __float__("float(self)"),
      +    __iadd__("Return self+=value."),
      +    __isub__("Return self-=value."),
      +    __imul__("Return self*=value."),
      +    __imod__("Return self%=value."),
      +    __ipow__("Return self**=value."),
      +    __ilshift__("Return self<<=value."),
      +    __irshift__("Return self>>=value."),
      +    __iand__("Return self&=value."),
      +    __ixor__("Return self^=value."),
      +    __ior__("Return self|=value."),
      +    __floordiv__("Return self//value."),
      +    __rfloordiv__("Return value//self."),
      +    __truediv__("Return self/value."),
      +    __rtruediv__("Return value/self."),
      +    __ifloordiv__("Return self//=value."),
      +    __itruediv__("Return self/=value."),
      +    __index__("Return self converted to an integer, if self is suitable for use as an index into a list."),
      +    __matmul__("Return self@value."),
      +    __rmatmul__("Return value@self."),
      +    __imatmul__("Return self@=value."),
      +    __len__("Return len(self)."),
      +    __getitem__("Return self[key]."),
      +    __setitem__("Set self[key] to value."),
      +    __delitem__("Delete self[key]."),
      +    __contains__("Return key in self.");
      +
      +    public final TruffleString docstring;
      +
      +    SlotWrapperDocstrings(String docstring) {
      +        this.docstring = tsLiteral(docstring);
      +    }
      +
      +    public static TruffleString getDocstring(String name) {
      +        return valueOf(name).docstring;
      +    }
      +}
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlot.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlot.java
      index d74d2513c6..69d19626d8 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlot.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlot.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -41,6 +41,7 @@
       package com.oracle.graal.python.builtins.objects.type.slots;
       
       import static com.oracle.graal.python.builtins.PythonBuiltins.numDefaults;
      +import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PYOBJECT_HASH_NOT_IMPLEMENTED;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__;
       
       import java.util.concurrent.atomic.AtomicInteger;
      @@ -50,19 +51,23 @@
       import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.Python3Core;
      +import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext;
       import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper;
      +import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol;
       import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.TpSlotWrapper;
       import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
      +import com.oracle.graal.python.builtins.objects.object.PythonObject;
       import com.oracle.graal.python.builtins.objects.type.TpSlots.TpSlotMeta;
       import com.oracle.graal.python.builtins.objects.type.slots.NodeFactoryUtils.NodeFactoryBase;
       import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode.Dynamic;
       import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.runtime.PythonContext;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.RootCallTarget;
      -import com.oracle.truffle.api.TruffleLogger;
       import com.oracle.truffle.api.dsl.Fallback;
       import com.oracle.truffle.api.dsl.GenerateCached;
       import com.oracle.truffle.api.dsl.GenerateInline;
      @@ -81,7 +86,6 @@
        * {@link com.oracle.graal.python.builtins.objects.type.TpSlots} object.
        */
       public abstract class TpSlot {
      -    private static final TruffleLogger LOGGER = PythonLanguage.getLogger(TpSlot.class);
       
           /**
            * Transforms the slot object to an interop object that can be sent to native.
      @@ -95,37 +99,27 @@ public static Object toNative(TpSlotMeta slotMeta, TpSlot slot, Object defaultVa
                   // This returns PyProcsWrapper, which will, in its toNative message, register the
                   // pointer in C API context, such that we can map back from a pointer that we get from C
                   // to the PyProcsWrapper and from that to the slot instance again in TpSlots#fromNative
      -            assert PythonContext.get(null).ownsGil(); // without GIL: use AtomicReference & CAS
      -            if (managedSlot.slotWrapper == null) {
      -                managedSlot.slotWrapper = slotMeta.createNativeWrapper(managedSlot);
      -            }
      -            return managedSlot.slotWrapper;
      +            return getNativeWrapper(slotMeta, managedSlot);
               } else {
                   throw CompilerDirectives.shouldNotReachHere("TpSlotWrapper should wrap only managed slots. Native slots should go directly to native unwrapped.");
               }
           }
       
      -    /**
      -     * If the interop object represents a pointer to existing {@link TpSlot}, then returns that
      -     * slot, otherwise {@code null}.
      -     */
      -    public static TpSlot fromNative(PythonContext ctx, Object ptr, InteropLibrary interop) {
      -        if (interop.isPointer(ptr)) {
      -            try {
      -                Object delegate = ctx.getCApiContext().getClosureDelegate(interop.asPointer(ptr));
      -                if (delegate instanceof TpSlot s) {
      -                    return s;
      -                } else if (delegate != null) {
      -                    // This can happen for legacy slots where the delegate would be a PFunction
      -                    LOGGER.warning(() -> String.format("Unexpected delegate for slot pointer: %s", delegate));
      -                }
      -            } catch (UnsupportedMessageException e) {
      -                throw new IllegalStateException(e);
      -            }
      -        } else if (ptr instanceof TpSlotWrapper slotWrapper) {
      -            return slotWrapper.getSlot();
      -        }
      -        return null;
      +    private static Object getNativeWrapper(TpSlotMeta slotMeta, TpSlotManaged slot) {
      +        if (slot == TpSlotHashFun.HASH_NOT_IMPLEMENTED) {
      +            // If there are more such cases, we should add generic mapping mechanism
      +            // This translation other way around is also done in TpSlots.fromNative
      +            // We must not cache this in the singleton slot object, it would hold onto and leak
      +            // Python objects
      +            return CApiContext.getNativeSymbol(null, FUN_PYOBJECT_HASH_NOT_IMPLEMENTED);
      +        } else if (slot == TpSlotIterNext.NEXT_NOT_IMPLEMENTED) {
      +            return CApiContext.getNativeSymbol(null, NativeCAPISymbol.FUN_PY_OBJECT_NEXT_NOT_IMPLEMENTED);
      +        }
      +        assert PythonContext.get(null).ownsGil(); // without GIL: use AtomicReference & CAS
      +        if (slot.slotWrapper == null) {
      +            slot.slotWrapper = slotMeta.createNativeWrapper(slot);
      +        }
      +        return slot.slotWrapper;
           }
       
           /**
      @@ -166,7 +160,11 @@ private static boolean hasExpectedType(TpSlot x) {
            * Marker base class for managed slots: either builtin slots or user defined Python slots.
            */
           public abstract static sealed class TpSlotManaged extends TpSlot permits TpSlotBuiltin, TpSlotPython {
      -        private TpSlotWrapper slotWrapper;
      +        /**
      +         * Represents native callable that delegates to this slot. Should be {@link TpSlotWrapper}
      +         * most of the time, but we allow overriding those wrappers with native implementation.
      +         */
      +        private Object slotWrapper;
           }
       
           /**
      @@ -207,7 +205,7 @@ static TruffleWeakReference asWeakRef(Object value) {
            * stored determines the signature. On Java level we have to do a call with boxed arguments
            * array and cannot optimize for specific signature.
            */
      -    public abstract static sealed class TpSlotNative extends TpSlot permits TpSlotCExtNative, TpSlotHPyNative {
      +    public abstract static sealed class TpSlotNative extends TpSlot permits TpSlotCExtNative {
               final Object callable;
       
               public TpSlotNative(Object callable) {
      @@ -218,10 +216,6 @@ public static TpSlotNative createCExtSlot(Object callable) {
                   return new TpSlotCExtNative(callable);
               }
       
      -        public static TpSlotNative createHPySlot(Object callable) {
      -            return new TpSlotHPyNative(callable);
      -        }
      -
               public final boolean isSameCallable(TpSlotNative other, InteropLibrary interop) {
                   if (this == other || this.callable == other.callable) {
                       return true;
      @@ -255,19 +249,6 @@ public TpSlotCExtNative(Object callable) {
               }
           }
       
      -    /**
      -     * HPy slots currently "pretend" to be Python magic methods. They are added to a newly
      -     * constructed type in HPyCreateTypeFromSpecNode, which triggers {@code TpSlots#updateSlot} for
      -     * every added slot. In the future HPy slots should be treated like native slots, except that
      -     * they will have another dispatch method in CallXYZSlot nodes, see {@link TpSlotLen} for an
      -     * example.
      -     */
      -    public static final class TpSlotHPyNative extends TpSlotNative {
      -        public TpSlotHPyNative(Object callable) {
      -            super(callable);
      -        }
      -    }
      -
           /**
            * Represents a slot that should delegate to a builtin node. Outside of this package, builtin
            * slots are opaque. The leaf subclasses of this class are specific to concrete signature of
      @@ -327,31 +308,46 @@ final SlotSignature getSlotSignatureAnnotation() {
                * return {@code null}. This can happen if user puts incompatible builtin slot value into a
                * slot, e.g., puts {@code descrsetfunc} builtin into {@code tp_getattro} slot.
                */
      -        public abstract PBuiltinFunction createBuiltin(Python3Core core, Object type, TruffleString tsName, PExternalFunctionWrapper wrapper);
      +        public abstract PythonObject createBuiltin(Python3Core core, Object type, TruffleString tsName, PExternalFunctionWrapper wrapper);
       
      -        // helper method
      +        /**
      +         * Helper method for creating a {@link PBuiltinFunction} as a wrapper for slots. Intended to
      +         * be used from implementation of
      +         * {@link #createBuiltin(Python3Core, Object, TruffleString, PExternalFunctionWrapper)}.
      +         */
               final PBuiltinFunction createBuiltin(Python3Core core, Object type, TruffleString tsName, BuiltinSlotWrapperSignature signature, PExternalFunctionWrapper wrapper,
                               NodeFactory factory) {
                   String name = tsName.toJavaStringUncached();
      -            RootCallTarget callTarget = createBuiltinCallTarget(core.getLanguage(), signature, factory, name);
      -            Builtin builtin = ((BuiltinFunctionRootNode) callTarget.getRootNode()).getBuiltin();
      -            PBuiltinFunction function = core.factory().createWrapperDescriptor(tsName, type, numDefaults(builtin), 0, callTarget, this, wrapper);
      -            function.setAttribute(T___DOC__, PNone.NONE);
      +
      +            SlotSignature slotSignature = factory.getNodeClass().getAnnotation(SlotSignature.class);
      +            Builtin builtin = new Slot2Builtin(slotSignature, name, signature);
      +            Class nodeClass = NodeFactoryBase.getWrappedNodeClass(factory);
      +            validateSlotNode(factory, nodeClass, slotSignature);
      +            PythonBuiltinClassType builtinType = type instanceof PythonBuiltinClassType bt ? bt : null;
      +            RootCallTarget callTarget = core.getLanguage().createCachedCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, factory, true, builtinType), factory.getNodeClass(), nodeClass,
      +                            builtinType, name);
      +
      +            PBuiltinFunction function = PFactory.createWrapperDescriptor(core.getLanguage(), tsName, type, numDefaults(builtin), 0, callTarget, this, wrapper);
      +            function.setAttribute(T___DOC__, SlotWrapperDocstrings.getDocstring(name));
                   return function;
               }
       
               /**
      -         * Helper method for creating a {@link RootCallTarget}, it may be used in
      +         * Helper method for creating a {@link RootCallTarget} for raw slots. Should be used in
                * {@link #initialize(PythonLanguage)} to create the slot call target if the slot node can
                * be wrapped by {@link BuiltinFunctionRootNode}.
                */
      -        static RootCallTarget createBuiltinCallTarget(PythonLanguage language, BuiltinSlotWrapperSignature signature, NodeFactory factory, String name) {
      +        static RootCallTarget createSlotCallTarget(PythonLanguage language, BuiltinSlotWrapperSignature signature, NodeFactory factory, String name) {
                   SlotSignature slotSignature = factory.getNodeClass().getAnnotation(SlotSignature.class);
                   Builtin builtin = new Slot2Builtin(slotSignature, name, signature);
                   Class nodeClass = NodeFactoryBase.getWrappedNodeClass(factory);
      +            validateSlotNode(factory, nodeClass, slotSignature);
      +            return language.createCachedCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, factory, true), factory.getNodeClass(), nodeClass, name);
      +        }
      +
      +        private static void validateSlotNode(NodeFactory factory, Class nodeClass, SlotSignature slotSignature) {
                   assert nodeClass == factory.getNodeClass() || slotSignature == null : //
                                   "@SlotSignature cannot be used for builtin slot nodes that are wrapped into multiple builtin magic methods";
      -            return language.createCachedCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, factory, true), factory.getNodeClass(), nodeClass, name);
               }
       
               public static boolean isSlotFactory(NodeFactory factory) {
      @@ -359,7 +355,6 @@ public static boolean isSlotFactory(NodeFactory factory) {
                                   NodeFactoryUtils.NodeFactoryBase.class.isAssignableFrom(factory.getClass());
               }
           }
      -
           // ------------------------------------------------------------------------
           // Convenience base classes for code sharing:
       
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryFunc.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryFunc.java
      index eeaee95aef..c6d9f28dc7 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryFunc.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryFunc.java
      @@ -40,8 +40,8 @@
        */
       package com.oracle.graal.python.builtins.objects.type.slots;
       
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ADD__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETITEM__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETITEM__;
       import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
       
       import com.oracle.graal.python.PythonLanguage;
      @@ -51,16 +51,13 @@
       import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming;
       import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonTransferNode;
       import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode;
      -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsHandleNode;
      -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsPythonObjectNode;
       import com.oracle.graal.python.builtins.objects.function.PArguments;
       import com.oracle.graal.python.builtins.objects.type.slots.PythonDispatchers.BinaryPythonSlotDispatcherNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotBuiltinBase;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotCExtNative;
      -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotHPyNative;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPythonSingle;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      -import com.oracle.graal.python.runtime.ExecutionContext.CallContext;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
       import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
      @@ -74,9 +71,7 @@
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      -import com.oracle.truffle.api.nodes.IndirectCallNode;
       import com.oracle.truffle.api.nodes.Node;
      -import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       
       public class TpSlotBinaryFunc {
      @@ -98,7 +93,7 @@ final PythonBinaryBuiltinNode createSlotNode() {
       
               @Override
               public void initialize(PythonLanguage language) {
      -            RootCallTarget target = createBuiltinCallTarget(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), builtinName);
      +            RootCallTarget target = createSlotCallTarget(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), builtinName);
                   language.setBuiltinSlotCallTarget(callTargetIndex, target);
               }
           }
      @@ -111,7 +106,7 @@ protected TpSlotMpSubscript(NodeFactory nodeFactory) {
       
           public abstract static class TpSlotSqConcat extends TpSlotBinaryFuncBuiltin {
               protected TpSlotSqConcat(NodeFactory nodeFactory) {
      -            super(nodeFactory, PExternalFunctionWrapper.BINARYFUNC, J___GETITEM__);
      +            super(nodeFactory, PExternalFunctionWrapper.BINARYFUNC, J___ADD__);
               }
           }
       
      @@ -160,32 +155,15 @@ static Object callNative(VirtualFrame frame, Node inliningTarget, TpSlotCExtNati
                   return checkResultNode.execute(state, T_BINARY_SLOT, toPythonNode.execute(result));
               }
       
      -        @Specialization
      -        @InliningCutoff
      -        static Object callHPy(VirtualFrame frame, Node inliningTarget, TpSlotHPyNative slot, Object self, Object index,
      -                        @Exclusive @Cached GetThreadStateNode getThreadStateNode,
      -                        @Cached(inline = false) HPyAsHandleNode selfToNativeNode,
      -                        @Cached(inline = false) HPyAsHandleNode indexToNativeNode,
      -                        @Exclusive @Cached ExternalFunctionInvokeNode externalInvokeNode,
      -                        @Cached(inline = false) HPyAsPythonObjectNode toPythonNode,
      -                        @Exclusive @Cached(inline = false) PyObjectCheckFunctionResultNode checkResultNode) {
      -            PythonContext ctx = PythonContext.get(inliningTarget);
      -            PythonThreadState threadState = getThreadStateNode.execute(inliningTarget, ctx);
      -            Object result = externalInvokeNode.call(frame, inliningTarget, threadState, C_API_TIMING, T___GETITEM__, slot.callable,
      -                            ctx.getHPyContext().getBackend(), selfToNativeNode.execute(self), indexToNativeNode.execute(index));
      -            return checkResultNode.execute(threadState, T___GETITEM__, toPythonNode.execute(result));
      -        }
      -
               @Specialization(replaces = "callCachedBuiltin")
               @InliningCutoff
               static Object callGenericComplexBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotBinaryFuncBuiltin slot, Object self, Object arg,
      -                        @Cached(inline = false) CallContext callContext,
      -                        @Cached InlinedConditionProfile isNullFrameProfile,
      -                        @Cached(inline = false) IndirectCallNode indirectCallNode) {
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
                   Object[] arguments = PArguments.create(2);
                   PArguments.setArgument(arguments, 0, self);
                   PArguments.setArgument(arguments, 1, arg);
      -            return BuiltinDispatchers.callGenericBuiltin(frame, inliningTarget, slot.callTargetIndex, arguments, callContext, isNullFrameProfile, indirectCallNode);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            return invoke.execute(frame, inliningTarget, callTarget, arguments);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryOp.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryOp.java
      index 3cc64a294f..d80f51a275 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryOp.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryOp.java
      @@ -49,6 +49,7 @@
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MOD__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MUL__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___OR__;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___POW__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RADD__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RAND__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RDIVMOD__;
      @@ -58,6 +59,7 @@
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RMOD__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RMUL__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ROR__;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RPOW__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RRSHIFT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RSHIFT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RSUB__;
      @@ -89,12 +91,14 @@
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotBuiltin;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotCExtNative;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPython;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.TpSlotBinaryFuncBuiltin;
       import com.oracle.graal.python.lib.PyObjectRichCompareBool;
      +import com.oracle.graal.python.lib.RichCmpOp;
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
       import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      -import com.oracle.graal.python.runtime.ExecutionContext.CallContext;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
       import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
      @@ -111,7 +115,6 @@
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      -import com.oracle.truffle.api.nodes.IndirectCallNode;
       import com.oracle.truffle.api.nodes.Node;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
      @@ -125,7 +128,7 @@ public class TpSlotBinaryOp {
           private TpSlotBinaryOp() {
           }
       
      -    public enum BinaryOpSlot {
      +    public enum ReversibleSlot {
               NB_ADD(T___ADD__, T___RADD__),
               NB_SUBTRACT(T___SUB__, T___RSUB__),
               NB_MULTIPLY(T___MUL__, T___RMUL__),
      @@ -138,13 +141,14 @@ public enum BinaryOpSlot {
               NB_FLOOR_DIVIDE(T___FLOORDIV__, T___RFLOORDIV__),
               NB_TRUE_DIVIDE(T___TRUEDIV__, T___RTRUEDIV__),
               NB_DIVMOD(T___DIVMOD__, T___RDIVMOD__),
      -        NB_MATRIX_MULTIPLY(T___MATMUL__, T___RMATMUL__);
      +        NB_MATRIX_MULTIPLY(T___MATMUL__, T___RMATMUL__),
      +        NB_POWER_BINARY(T___POW__, T___RPOW__);
       
      -        private static final BinaryOpSlot[] VALUES = values();
      +        private static final ReversibleSlot[] VALUES = values();
               private final TruffleString name;
               private final TruffleString rname;
       
      -        BinaryOpSlot(TruffleString name, TruffleString rname) {
      +        ReversibleSlot(TruffleString name, TruffleString rname) {
                   this.name = name;
                   this.rname = rname;
               }
      @@ -165,11 +169,12 @@ public TpSlot getSlotValue(TpSlots slots) {
                       case NB_TRUE_DIVIDE -> slots.nb_true_divide();
                       case NB_DIVMOD -> slots.nb_divmod();
                       case NB_MATRIX_MULTIPLY -> slots.nb_matrix_multiply();
      +                case NB_POWER_BINARY -> slots.nb_power();
                   };
               }
       
      -        public static BinaryOpSlot fromCallableNames(TruffleString[] names) {
      -            for (BinaryOpSlot op : VALUES) {
      +        public static ReversibleSlot fromCallableNames(TruffleString[] names) {
      +            for (ReversibleSlot op : VALUES) {
                       if (names[0].equals(op.name) && names[1].equals(op.rname)) {
                           return op;
                       }
      @@ -178,6 +183,49 @@ public static BinaryOpSlot fromCallableNames(TruffleString[] names) {
               }
           }
       
      +    public enum InplaceSlot {
      +        NB_INPLACE_ADD(ReversibleSlot.NB_ADD),
      +        NB_INPLACE_SUBTRACT(ReversibleSlot.NB_SUBTRACT),
      +        NB_INPLACE_MULTIPLY(ReversibleSlot.NB_MULTIPLY),
      +        NB_INPLACE_REMAINDER(ReversibleSlot.NB_REMAINDER),
      +        NB_INPLACE_LSHIFT(ReversibleSlot.NB_LSHIFT),
      +        NB_INPLACE_RSHIFT(ReversibleSlot.NB_RSHIFT),
      +        NB_INPLACE_AND(ReversibleSlot.NB_AND),
      +        NB_INPLACE_XOR(ReversibleSlot.NB_XOR),
      +        NB_INPLACE_OR(ReversibleSlot.NB_OR),
      +        NB_INPLACE_FLOOR_DIVIDE(ReversibleSlot.NB_FLOOR_DIVIDE),
      +        NB_INPLACE_TRUE_DIVIDE(ReversibleSlot.NB_TRUE_DIVIDE),
      +        NB_INPLACE_MATRIX_MULTIPLY(ReversibleSlot.NB_MATRIX_MULTIPLY);
      +
      +        private final ReversibleSlot reversibleSlot;
      +
      +        InplaceSlot(ReversibleSlot reversibleSlot) {
      +            this.reversibleSlot = reversibleSlot;
      +        }
      +
      +        public TpSlot getSlotValue(TpSlots slots) {
      +            // switch instead of using TpSlotMeta for better inlining on fast-path
      +            return switch (this) {
      +                case NB_INPLACE_ADD -> slots.nb_inplace_add();
      +                case NB_INPLACE_SUBTRACT -> slots.nb_inplace_subtract();
      +                case NB_INPLACE_MULTIPLY -> slots.nb_inplace_multiply();
      +                case NB_INPLACE_REMAINDER -> slots.nb_inplace_remainder();
      +                case NB_INPLACE_LSHIFT -> slots.nb_inplace_lshift();
      +                case NB_INPLACE_RSHIFT -> slots.nb_inplace_rshift();
      +                case NB_INPLACE_AND -> slots.nb_inplace_and();
      +                case NB_INPLACE_XOR -> slots.nb_inplace_xor();
      +                case NB_INPLACE_OR -> slots.nb_inplace_or();
      +                case NB_INPLACE_FLOOR_DIVIDE -> slots.nb_inplace_floor_divide();
      +                case NB_INPLACE_TRUE_DIVIDE -> slots.nb_inplace_true_divide();
      +                case NB_INPLACE_MATRIX_MULTIPLY -> slots.nb_inplace_matrix_multiply();
      +            };
      +        }
      +
      +        public ReversibleSlot getReversibleSlot() {
      +            return reversibleSlot;
      +        }
      +    }
      +
           public abstract static class TpSlotBinaryOpBuiltin extends TpSlotBuiltin {
               private final int callTargetIndex = TpSlotBuiltinCallTargetRegistry.getNextCallTargetIndex();
               private final String builtinName;
      @@ -193,7 +241,7 @@ final BinaryOpBuiltinNode createOpSlotNode() {
       
               @Override
               public void initialize(PythonLanguage language) {
      -            RootCallTarget callTarget = createBuiltinCallTarget(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), builtinName);
      +            RootCallTarget callTarget = createSlotCallTarget(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), builtinName);
                   language.setBuiltinSlotCallTarget(callTargetIndex, callTarget);
               }
       
      @@ -212,6 +260,13 @@ private PBuiltinFunction createRBuiltin(Python3Core core, Object type, TruffleSt
               }
           }
       
      +    public abstract static class TpSlotBinaryIOpBuiltin extends TpSlotBinaryFuncBuiltin {
      +
      +        protected TpSlotBinaryIOpBuiltin(NodeFactory nodeFactory, String builtinName) {
      +            super(nodeFactory, PExternalFunctionWrapper.BINARYFUNC, builtinName);
      +        }
      +    }
      +
           static final class SwapArgumentsNode extends PythonBinaryBuiltinNode {
               @Child private BinaryOpBuiltinNode wrapped;
       
      @@ -234,24 +289,24 @@ public Object execute(VirtualFrame frame, Object self, Object other) {
           public abstract static class BinaryOpBuiltinNode extends PythonBinaryBuiltinNode {
           }
       
      -    public static final class TpSlotBinaryOpPython extends TpSlotPython {
      -        private final BinaryOpSlot op;
      +    public static final class TpSlotReversiblePython extends TpSlotPython {
      +        private final ReversibleSlot op;
               private final TruffleWeakReference left;
               private final TruffleWeakReference right;
               private final TruffleWeakReference type;
       
      -        public TpSlotBinaryOpPython(BinaryOpSlot op, Object setattr, Object delattr, Object type) {
      +        public TpSlotReversiblePython(ReversibleSlot op, Object left, Object right, Object type) {
                   this.op = op;
      -            this.left = asWeakRef(setattr);
      -            this.right = asWeakRef(delattr);
      +            this.left = asWeakRef(left);
      +            this.right = asWeakRef(right);
                   this.type = new TruffleWeakReference<>(type);
               }
       
      -        public static TpSlotBinaryOpPython create(Object[] callables, TruffleString[] callableNames, Object type) {
      +        public static TpSlotReversiblePython create(Object[] callables, TruffleString[] callableNames, Object type) {
                   assert callables.length == 2;
      -            BinaryOpSlot op = BinaryOpSlot.fromCallableNames(callableNames);
      +            ReversibleSlot op = ReversibleSlot.fromCallableNames(callableNames);
                   assert op != null : "Unexpected callable names: " + Arrays.toString(callableNames);
      -            return new TpSlotBinaryOpPython(op, callables[0], callables[1], type);
      +            return new TpSlotReversiblePython(op, callables[0], callables[1], type);
               }
       
               @Override
      @@ -259,7 +314,7 @@ public TpSlotPython forNewType(Object klass) {
                   Object newLeft = LookupAttributeInMRONode.Dynamic.getUncached().execute(klass, op.name);
                   Object newRight = LookupAttributeInMRONode.Dynamic.getUncached().execute(klass, op.rname);
                   if (newLeft != getLeft() || newRight != getRight()) {
      -                return new TpSlotBinaryOpPython(op, newLeft, newRight, getType());
      +                return new TpSlotReversiblePython(op, newLeft, newRight, getType());
                   }
                   return this;
               }
      @@ -288,27 +343,27 @@ public abstract static class CallSlotBinaryOpNode extends Node {
               // This happens in CallBinaryOp1Node (cpython:binary_op1)
       
               public abstract Object execute(VirtualFrame frame, Node inliningTarget, TpSlot slot, Object self, Object selfType, Object other, TpSlot otherSlot, Object otherType, boolean sameTypes,
      -                        BinaryOpSlot op);
      +                        ReversibleSlot op);
       
               @SuppressWarnings("unused")
               @Specialization(guards = "cachedSlot == slot", limit = "3")
               static Object callCachedBuiltin(VirtualFrame frame, TpSlotBinaryOpBuiltin slot, Object self,
      -                        Object selfType, Object other, TpSlot otherSlot, Object otherType, boolean sameTypes, BinaryOpSlot op,
      +                        Object selfType, Object other, TpSlot otherSlot, Object otherType, boolean sameTypes, ReversibleSlot op,
                               @Cached("slot") TpSlotBinaryOpBuiltin cachedSlot,
                               @Cached("cachedSlot.createOpSlotNode()") BinaryOpBuiltinNode slotNode) {
                   return slotNode.execute(frame, self, other);
               }
       
               @Specialization
      -        static Object callPython(VirtualFrame frame, TpSlotBinaryOpPython slot, Object self, Object selfType, Object other, TpSlot otherSlot, Object otherType, boolean sameTypes, BinaryOpSlot op,
      -                        @Cached(inline = false) CallBinaryOpPythonSlotNode callPython) {
      +        static Object callPython(VirtualFrame frame, TpSlotReversiblePython slot, Object self, Object selfType, Object other, TpSlot otherSlot, Object otherType, boolean sameTypes, ReversibleSlot op,
      +                        @Cached(inline = false) CallReversiblePythonSlotNode callPython) {
                   return callPython.execute(frame, slot, self, selfType, other, otherSlot, otherType, sameTypes, op);
               }
       
               @SuppressWarnings("unused")
               @Specialization
               static Object callNative(VirtualFrame frame, Node inliningTarget, TpSlotCExtNative slot, Object self,
      -                        Object selfType, Object arg, TpSlot otherSlot, Object otherType, boolean sameTypes, BinaryOpSlot op,
      +                        Object selfType, Object arg, TpSlot otherSlot, Object otherType, boolean sameTypes, ReversibleSlot op,
                               @Exclusive @Cached GetThreadStateNode getThreadStateNode,
                               @Cached(inline = false) PythonToNativeNode selfToNativeNode,
                               @Cached(inline = false) PythonToNativeNode argToNativeNode,
      @@ -322,46 +377,28 @@ static Object callNative(VirtualFrame frame, Node inliningTarget, TpSlotCExtNati
                   return checkResultNode.execute(state, op.name, toPythonNode.execute(result));
               }
       
      -        /*- TODO
      -        @Specialization
      -        @InliningCutoff
      -        static Object callHPy(VirtualFrame frame, Node inliningTarget, TpSlotHPyNative slot, Object self, Object index,
      -                        @Exclusive @Cached GetThreadStateNode getThreadStateNode,
      -                        @Cached(inline = false) HPyAsHandleNode selfToNativeNode,
      -                        @Cached(inline = false) HPyAsHandleNode indexToNativeNode,
      -                        @Exclusive @Cached ExternalFunctionInvokeNode externalInvokeNode,
      -                        @Cached(inline = false) HPyAsPythonObjectNode toPythonNode,
      -                        @Exclusive @Cached(inline = false) PyObjectCheckFunctionResultNode checkResultNode) {
      -            PythonContext ctx = PythonContext.get(inliningTarget);
      -            PythonThreadState threadState = getThreadStateNode.execute(inliningTarget, ctx);
      -            Object result = externalInvokeNode.call(frame, inliningTarget, threadState, C_API_TIMING, T___GETITEM__, slot.callable,
      -                            ctx.getHPyContext().getBackend(), selfToNativeNode.execute(self), indexToNativeNode.execute(index));
      -            return checkResultNode.execute(threadState, T___GETITEM__, toPythonNode.execute(result));
      -        }
      -        */
      -
               @SuppressWarnings("unused")
               @Specialization(replaces = "callCachedBuiltin")
               @InliningCutoff
               static Object callGenericComplexBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotBinaryOpBuiltin slot,
      -                        Object self, Object selfType, Object other, TpSlot otherSlot, Object otherType, boolean sameTypes, BinaryOpSlot op,
      -                        @Cached(inline = false) CallContext callContext,
      -                        @Cached InlinedConditionProfile isNullFrameProfile,
      -                        @Cached(inline = false) IndirectCallNode indirectCallNode) {
      +                        Object self, Object selfType, Object other, TpSlot otherSlot, Object otherType, boolean sameTypes, ReversibleSlot op,
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
                   Object[] arguments = PArguments.create(2);
                   PArguments.setArgument(arguments, 0, self);
                   PArguments.setArgument(arguments, 1, other);
      -            return BuiltinDispatchers.callGenericBuiltin(frame, inliningTarget, slot.callTargetIndex, arguments, callContext, isNullFrameProfile, indirectCallNode);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            return invoke.execute(frame, inliningTarget, callTarget, arguments);
               }
           }
       
           @GenerateUncached
           @GenerateInline(false) // intentional explicit "data-class"
      -    abstract static class CallBinaryOpPythonSlotNode extends Node {
      -        public abstract Object execute(VirtualFrame frame, TpSlot slot, Object self, Object selfType, Object other, TpSlot otherSlot, Object otherType, boolean sameTypes, BinaryOpSlot op);
      +    abstract static class CallReversiblePythonSlotNode extends Node {
      +        public abstract Object execute(VirtualFrame frame, TpSlotReversiblePython slot, Object self, Object selfType, Object other, TpSlot otherSlot, Object otherType, boolean sameTypes,
      +                        ReversibleSlot op);
       
               @Specialization
      -        static Object callPython(VirtualFrame frame, TpSlotBinaryOpPython slot, Object self, Object selfType, Object other, TpSlot otherSlot, Object otherType, boolean sameTypes, BinaryOpSlot op,
      +        static Object callPython(VirtualFrame frame, TpSlotReversiblePython slot, Object self, Object selfType, Object other, TpSlot otherSlot, Object otherType, boolean sameTypes, ReversibleSlot op,
                               @Bind("this") Node inliningTarget,
                               @Cached IsSubtypeNode isSubtypeNode,
                               @Cached GetCachedTpSlotsNode getSelfSlotsNode,
      @@ -371,11 +408,11 @@ static Object callPython(VirtualFrame frame, TpSlotBinaryOpPython slot, Object s
                               @Cached InlinedConditionProfile dispatchR2Profile,
                               @Cached BinaryPythonSlotDispatcherNode dispatcherNode) {
                   // Implements the logic of SLOT1BINFULL macro from CPython
      -            TpSlotBinaryOpPython otherSlotValue = null;
      +            TpSlotReversiblePython otherSlotValue = null;
                   boolean doOther = false;
                   if (!sameTypes) {
      -                if (isBinOpWrapper(otherSlot, op)) {
      -                    otherSlotValue = (TpSlotBinaryOpPython) otherSlot;
      +                if (isSameReversibleWrapper(otherSlot, op)) {
      +                    otherSlotValue = (TpSlotReversiblePython) otherSlot;
                           doOther = true;
                       }
                   }
      @@ -383,8 +420,8 @@ static Object callPython(VirtualFrame frame, TpSlotBinaryOpPython slot, Object s
                   TpSlots selfSlots = getSelfSlotsNode.execute(inliningTarget, selfType);
                   TpSlot selfSlotValue = op.getSlotValue(selfSlots);
                   // Note: the slot may be other's slot, not self's slot, so this test may not pass
      -            if (isBinOpWrapper(selfSlotValue, op)) {
      -                if (doOther && isSubtypeNode.execute(frame, otherType, selfType)) {
      +            if (isSameReversibleWrapper(selfSlotValue, op)) {
      +                if (doOther && isSubtypeNode.execute(otherType, selfType)) {
                           if (methodIsOverloaded(frame, inliningTarget, slot, otherSlotValue, neNode)) {
                               Object result = dispatchIfAvailable(frame, inliningTarget, dispatchR1Profile, dispatcherNode, other, self, otherSlotValue.getRight(), otherSlotValue.getType());
                               if (result != PNotImplemented.NOT_IMPLEMENTED) {
      @@ -415,14 +452,14 @@ private static Object dispatchIfAvailable(VirtualFrame frame, Node inliningTarge
                   }
               }
       
      -        static boolean isBinOpWrapper(TpSlot s, BinaryOpSlot op) {
      +        static boolean isSameReversibleWrapper(TpSlot s, ReversibleSlot op) {
                   // Equivalent to CPython test: Py_TYPE(other)->tp_as_number->SLOTNAME == TESTFUNC
                   // We have multiple wrappers, because we cache state (MRO lookups) in the wrapper too
      -            return s instanceof TpSlotBinaryOpPython p && p.op == op;
      +            return s instanceof TpSlotReversiblePython p && p.op == op;
               }
       
               static boolean methodIsOverloaded(VirtualFrame frame, Node inliningTarget,
      -                        TpSlotBinaryOpPython leftSlot, TpSlotBinaryOpPython rightSlot, RichCompareCallablesNotEqual neNode) {
      +                        TpSlotReversiblePython leftSlot, TpSlotReversiblePython rightSlot, RichCompareCallablesNotEqual neNode) {
                   // CPython uses _PyObject_LookupAttr(Py_TYPE(x), name) as opposed to
                   // _PyType_Lookup(Py_TYPE(x), name). Moreover, we cache the MRO lookup results in the
                   // slot, CPython doesn't, presumably because the slot cannot (easily) hold the extra
      @@ -483,8 +520,8 @@ static boolean doMethods(PMethodBase a, PMethodBase b) {
       
               @Fallback
               static boolean doGenericRuntimeObjects(VirtualFrame frame, Node inliningTarget, Object a, Object b,
      -                        @Cached PyObjectRichCompareBool.NeNode neNode) {
      -            return neNode.compare(frame, inliningTarget, a, b);
      +                        @Cached PyObjectRichCompareBool neNode) {
      +            return neNode.execute(frame, inliningTarget, a, b, RichCmpOp.Py_NE);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrGet.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrGet.java
      index 52dc42ff18..c0e7923e55 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrGet.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrGet.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -66,14 +66,12 @@
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PRaiseNode;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
       import com.oracle.graal.python.nodes.call.CallNode;
      -import com.oracle.graal.python.nodes.call.FunctionInvokeNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
      -import com.oracle.graal.python.runtime.ExecutionContext.CallContext;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
       import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
      -import com.oracle.truffle.api.CompilerDirectives;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
       import com.oracle.truffle.api.RootCallTarget;
      @@ -82,11 +80,13 @@
       import com.oracle.truffle.api.dsl.GenerateCached;
       import com.oracle.truffle.api.dsl.GenerateInline;
       import com.oracle.truffle.api.dsl.GenerateUncached;
      +import com.oracle.truffle.api.dsl.ImportStatic;
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      -import com.oracle.truffle.api.nodes.IndirectCallNode;
      +import com.oracle.truffle.api.nodes.DirectCallNode;
       import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.BranchProfile;
       import com.oracle.truffle.api.profiles.ConditionProfile;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
      @@ -144,7 +144,7 @@ protected TpSlotDescrGetBuiltinComplex(NodeFactory nodeFactory) {
               public void initialize(PythonLanguage language) {
                   // We need a different call-target for the "raw" slot. It must not normalize None to
                   // NO_VALUE (NULL in CPython) like the __get__ wrapper.
      -            RootCallTarget callTarget = createBuiltinCallTarget(language, SIGNATURE, getNodeFactory(), J___GET__);
      +            RootCallTarget callTarget = createSlotCallTarget(language, SIGNATURE, getNodeFactory(), J___GET__);
                   language.setBuiltinSlotCallTarget(callTargetIndex, callTarget);
               }
           }
      @@ -152,7 +152,7 @@ public void initialize(PythonLanguage language) {
           static final class DescrGetWrapperNode extends PythonTernaryBuiltinNode {
               private final ConditionProfile objIsNoneProfile = ConditionProfile.create();
               private final ConditionProfile typeIsNoneProfile = ConditionProfile.create();
      -        @Child private PRaiseNode raiseNode;
      +        private final BranchProfile errorProfile = BranchProfile.create();
               @Child private DescrGetBuiltinNode wrapped;
       
               DescrGetWrapperNode(DescrGetBuiltinNode wrapped) {
      @@ -168,11 +168,8 @@ public Object execute(VirtualFrame frame, Object self, Object objIn, Object type
                   Object obj = normalizeNone(objIsNoneProfile, objIn);
                   Object type = normalizeNone(typeIsNoneProfile, typeIn);
                   if (obj == PNone.NO_VALUE && type == PNone.NO_VALUE) {
      -                if (raiseNode == null) {
      -                    CompilerDirectives.transferToInterpreterAndInvalidate();
      -                    raiseNode = insert(PRaiseNode.create());
      -                }
      -                raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.GET_NONE_NONE_IS_INVALID);
      +                errorProfile.enter();
      +                throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.GET_NONE_NONE_IS_INVALID);
                   }
                   return wrapped.execute(frame, self, obj, type);
               }
      @@ -244,14 +241,13 @@ static Object callGenericSimpleBuiltin(TpSlotDescrGetBuiltinSimple slot, Object
               @Specialization(replaces = "callCachedBuiltin")
               @InliningCutoff
               static Object callGenericBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotDescrGetBuiltinComplex slot, Object self, Object obj, Object type,
      -                        @Cached(inline = false) CallContext callContext,
      -                        @Cached InlinedConditionProfile isNullFrameProfile,
      -                        @Cached(inline = false) IndirectCallNode indirectCallNode) {
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
                   Object[] arguments = PArguments.create(3);
                   PArguments.setArgument(arguments, 0, self);
                   PArguments.setArgument(arguments, 1, obj);
                   PArguments.setArgument(arguments, 2, type);
      -            return BuiltinDispatchers.callGenericBuiltin(frame, inliningTarget, slot.callTargetIndex, arguments, callContext, isNullFrameProfile, indirectCallNode);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            return invoke.execute(frame, inliningTarget, callTarget, arguments);
               }
           }
       
      @@ -263,6 +259,7 @@ static Object callGenericBuiltin(VirtualFrame frame, Node inliningTarget, TpSlot
           @GenerateUncached
           @GenerateInline
           @GenerateCached(false)
      +    @ImportStatic(CallDispatchers.class)
           abstract static class DescrGetPythonSlotDispatcherNode extends PythonSlotDispatcherNodeBase {
               abstract Object execute(VirtualFrame frame, Node inliningTarget, Object callable, Object type, Object self, Object arg1, Object arg2);
       
      @@ -273,12 +270,13 @@ protected static Object doCachedPFunction(VirtualFrame frame, Node inliningTarge
                               @SuppressWarnings("unused") @Cached("callee") PFunction cachedCallee,
                               @Cached @Shared InlinedConditionProfile arg1Profile,
                               @Cached @Shared InlinedConditionProfile arg2Profile,
      -                        @Cached("createInvokeNode(cachedCallee)") FunctionInvokeNode invoke) {
      +                        @Cached("createDirectCallNodeFor(callee)") DirectCallNode callNode,
      +                        @Cached CallDispatchers.FunctionDirectInvokeNode invoke) {
                   Object[] arguments = PArguments.create(3);
                   PArguments.setArgument(arguments, 0, self);
                   PArguments.setArgument(arguments, 1, normalizeNoValue(arg1Profile, inliningTarget, arg1));
                   PArguments.setArgument(arguments, 2, normalizeNoValue(arg2Profile, inliningTarget, arg2));
      -            return invoke.execute(frame, arguments);
      +            return invoke.execute(frame, inliningTarget, callNode, cachedCallee, arguments);
               }
       
               private static Object normalizeNoValue(InlinedConditionProfile profile, Node inlinintTarget, Object o) {
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrSet.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrSet.java
      index b336adedd6..f2010e0ca9 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrSet.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrSet.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -68,8 +68,8 @@
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode.Dynamic;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
       import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
      -import com.oracle.graal.python.runtime.ExecutionContext.CallContext;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
       import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
      @@ -86,9 +86,7 @@
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      -import com.oracle.truffle.api.nodes.IndirectCallNode;
       import com.oracle.truffle.api.nodes.Node;
      -import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       import com.oracle.truffle.api.utilities.TruffleWeakReference;
       
      @@ -115,7 +113,7 @@ final DescrSetBuiltinNode createSlotNode() {
       
               @Override
               public void initialize(PythonLanguage language) {
      -            RootCallTarget target = createBuiltinCallTarget(language, SET_SIGNATURE, getNodeFactory(), J___SET__);
      +            RootCallTarget target = createSlotCallTarget(language, SET_SIGNATURE, getNodeFactory(), J___SET__);
                   language.setBuiltinSlotCallTarget(callTargetIndex, target);
               }
       
      @@ -210,8 +208,8 @@ static void callNative(VirtualFrame frame, Node inliningTarget, TpSlotNative slo
               }
           }
       
      -    private static PException raiseAttributeError(Node inliningTarget, PRaiseNode.Lazy raiseNode, TruffleString attrName) {
      -        return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.AttributeError, attrName);
      +    private static PException raiseAttributeError(Node inliningTarget, PRaiseNode raiseNode, TruffleString attrName) {
      +        return raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, attrName);
           }
       
           @GenerateInline(inlineByDefault = true)
      @@ -241,7 +239,7 @@ static void callCachedBuiltin(VirtualFrame frame, @SuppressWarnings("unused") Tp
               @Specialization(guards = "!isNoValue(value)")
               static void callPythonSet(VirtualFrame frame, Node inliningTarget, TpSlotDescrSetPython slot, Object self, Object obj, Object value,
                               @Cached TernaryPythonSlotDispatcherNode dispatcherNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   Object callable = slot.getSetCallable();
                   if (callable == null) {
                       throw raiseAttributeError(inliningTarget, raiseNode, T___SET__);
      @@ -253,7 +251,7 @@ static void callPythonSet(VirtualFrame frame, Node inliningTarget, TpSlotDescrSe
               @InliningCutoff
               static void callPythonDel(VirtualFrame frame, Node inliningTarget, TpSlotDescrSetPython slot, Object self, Object obj, @SuppressWarnings("unused") Object value,
                               @Cached BinaryPythonSlotDispatcherNode dispatcherNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Exclusive @Cached PRaiseNode raiseNode) {
                   Object callable = slot.getDelCallable();
                   if (callable == null) {
                       throw raiseAttributeError(inliningTarget, raiseNode, T___DEL__);
      @@ -271,14 +269,13 @@ static void callNative(VirtualFrame frame, Node inliningTarget, TpSlotNative slo
               @Specialization(replaces = "callCachedBuiltin")
               @InliningCutoff
               static void callGenericBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotDescrSetBuiltin slot, Object self, Object obj, Object value,
      -                        @Cached(inline = false) CallContext callContext,
      -                        @Cached InlinedConditionProfile isNullFrameProfile,
      -                        @Cached(inline = false) IndirectCallNode indirectCallNode) {
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
                   Object[] arguments = PArguments.create(3);
                   PArguments.setArgument(arguments, 0, self);
                   PArguments.setArgument(arguments, 1, obj);
                   PArguments.setArgument(arguments, 2, value);
      -            BuiltinDispatchers.callGenericBuiltin(frame, inliningTarget, slot.callTargetIndex, arguments, callContext, isNullFrameProfile, indirectCallNode);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            invoke.execute(frame, inliningTarget, callTarget, arguments);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotGetAttr.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotGetAttr.java
      index 890c8fca3c..369e4da197 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotGetAttr.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotGetAttr.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -63,11 +63,11 @@
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPython;
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode.Dynamic;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
       import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode;
       import com.oracle.graal.python.nodes.call.special.MaybeBindDescriptorNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
      -import com.oracle.graal.python.runtime.ExecutionContext.CallContext;
       import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
       import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
       import com.oracle.graal.python.runtime.exception.PException;
      @@ -83,7 +83,6 @@
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      -import com.oracle.truffle.api.nodes.IndirectCallNode;
       import com.oracle.truffle.api.nodes.Node;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
      @@ -110,7 +109,7 @@ final GetAttrBuiltinNode createSlotNode() {
       
               @Override
               public void initialize(PythonLanguage language) {
      -            RootCallTarget target = createBuiltinCallTarget(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), J___GETATTRIBUTE__);
      +            RootCallTarget target = createSlotCallTarget(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), J___GETATTRIBUTE__);
                   language.setBuiltinSlotCallTarget(callTargetIndex, target);
               }
           }
      @@ -333,13 +332,12 @@ static Object callPythonSimple(VirtualFrame frame, Node inliningTarget, TpSlotGe
               @Specialization(replaces = "callCachedBuiltin")
               @InliningCutoff
               static Object callGenericBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotGetAttrBuiltin slot, Object self, Object name,
      -                        @Cached(inline = false) CallContext callContext,
      -                        @Cached InlinedConditionProfile isNullFrameProfile,
      -                        @Cached(inline = false) IndirectCallNode indirectCallNode) {
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
                   Object[] arguments = PArguments.create(2);
                   PArguments.setArgument(arguments, 0, self);
                   PArguments.setArgument(arguments, 1, name);
      -            return BuiltinDispatchers.callGenericBuiltin(frame, inliningTarget, slot.callTargetIndex, arguments, callContext, isNullFrameProfile, indirectCallNode);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            return invoke.execute(frame, inliningTarget, callTarget, arguments);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotHashFun.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotHashFun.java
      new file mode 100644
      index 0000000000..0cb77594f1
      --- /dev/null
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotHashFun.java
      @@ -0,0 +1,241 @@
      +/*
      + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
      + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      + *
      + * The Universal Permissive License (UPL), Version 1.0
      + *
      + * Subject to the condition set forth below, permission is hereby granted to any
      + * person obtaining a copy of this software, associated documentation and/or
      + * data (collectively the "Software"), free of charge and under any and all
      + * copyright rights in the Software, and any and all patent rights owned or
      + * freely licensable by each licensor hereunder covering either (i) the
      + * unmodified Software as contributed to or provided by such licensor, or (ii)
      + * the Larger Works (as defined below), to deal in both
      + *
      + * (a) the Software, and
      + *
      + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
      + * one is included with the Software each a "Larger Work" to which the Software
      + * is contributed by such licensors),
      + *
      + * without restriction, including without limitation the rights to copy, create
      + * derivative works of, display, perform, and distribute the Software and make,
      + * use, sell, offer for sale, import, export, have made, and have sold the
      + * Software and the Larger Work(s), and to sublicense the foregoing rights on
      + * either these or other terms.
      + *
      + * This license is subject to the following condition:
      + *
      + * The above copyright notice and either this complete permission notice or at a
      + * minimum a reference to the UPL must be included in all copies or substantial
      + * portions of the Software.
      + *
      + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      + * SOFTWARE.
      + */
      +package com.oracle.graal.python.builtins.objects.type.slots;
      +
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__;
      +
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.CheckPrimitiveFunctionResultNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.ExternalFunctionInvokeNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode;
      +import com.oracle.graal.python.builtins.objects.function.PArguments;
      +import com.oracle.graal.python.builtins.objects.ints.IntBuiltins;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.TpSlotMeta;
      +import com.oracle.graal.python.builtins.objects.type.slots.PythonDispatchers.UnaryPythonSlotDispatcherNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotBuiltinBase;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotCExtNative;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotManaged;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPythonSingle;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.PyObjectHashNotImplemented.HashNotImplementedNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFunFactory.CallSlotHashFunNodeGen;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFunFactory.PyObjectHashNotImplementedFactory.HashNotImplementedNodeFactory;
      +import com.oracle.graal.python.lib.PyLongAsLongAndOverflowNode;
      +import com.oracle.graal.python.lib.PyLongCheckNode;
      +import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.PRaiseNode;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
      +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.runtime.PythonContext;
      +import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
      +import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
      +import com.oracle.graal.python.util.OverflowException;
      +import com.oracle.truffle.api.CompilerDirectives;
      +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
      +import com.oracle.truffle.api.RootCallTarget;
      +import com.oracle.truffle.api.dsl.Bind;
      +import com.oracle.truffle.api.dsl.Cached;
      +import com.oracle.truffle.api.dsl.Cached.Exclusive;
      +import com.oracle.truffle.api.dsl.GenerateCached;
      +import com.oracle.truffle.api.dsl.GenerateInline;
      +import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      +import com.oracle.truffle.api.dsl.GenerateUncached;
      +import com.oracle.truffle.api.dsl.NodeFactory;
      +import com.oracle.truffle.api.dsl.Specialization;
      +import com.oracle.truffle.api.frame.VirtualFrame;
      +import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.InlinedConditionProfile;
      +
      +public abstract class TpSlotHashFun {
      +    public static final TpSlotManaged HASH_NOT_IMPLEMENTED = new PyObjectHashNotImplemented();
      +
      +    private TpSlotHashFun() {
      +    }
      +
      +    /**
      +     * Mirror of the {@code PyObject_HashNotImplemented} slot on the managed side. We translate this
      +     * slot singleton instance to a pointer to the {@code PyObject_HashNotImplemented} C function in
      +     * {@link TpSlot#toNative(TpSlotMeta, TpSlot, Object)} and vice versa in
      +     * {@code TpSlot#fromNative(PythonContext, Object, InteropLibrary)}.
      +     */
      +    public static class PyObjectHashNotImplemented extends TpSlotHashBuiltin {
      +        private PyObjectHashNotImplemented() {
      +            super(HashNotImplementedNodeFactory.getInstance());
      +        }
      +
      +        @GenerateNodeFactory
      +        public abstract static class HashNotImplementedNode extends HashBuiltinNode {
      +            @Specialization
      +            static long doIt(@SuppressWarnings("unused") Object obj,
      +                            @Bind Node nodeForRaise) {
      +                throw PRaiseNode.raiseStatic(nodeForRaise, PythonBuiltinClassType.TypeError, ErrorMessages.UNHASHABLE_TYPE_P, obj);
      +            }
      +        }
      +    }
      +
      +    public abstract static class TpSlotHashBuiltin
      +                    extends TpSlotBuiltinBase {
      +        static final BuiltinSlotWrapperSignature SIGNATURE = BuiltinSlotWrapperSignature.UNARY;
      +        private final int callTargetIndex = TpSlotBuiltinCallTargetRegistry.getNextCallTargetIndex();
      +
      +        public TpSlotHashBuiltin(NodeFactory nodeFactory) {
      +            super(nodeFactory, SIGNATURE, PExternalFunctionWrapper.HASHFUNC);
      +        }
      +
      +        HashBuiltinNode createSlotNode() {
      +            return createNode();
      +        }
      +
      +        @Override
      +        public void initialize(PythonLanguage language) {
      +            RootCallTarget callTarget = createSlotCallTarget(language, SIGNATURE, getNodeFactory(), J___HASH__);
      +            language.setBuiltinSlotCallTarget(callTargetIndex, callTarget);
      +        }
      +    }
      +
      +    @GenerateInline(value = false, inherit = true)
      +    public abstract static class HashBuiltinNode extends PythonUnaryBuiltinNode {
      +        public abstract long executeLong(VirtualFrame frame, Object obj);
      +
      +        @Override
      +        public final Object execute(VirtualFrame frame, Object obj) {
      +            return executeLong(frame, obj);
      +        }
      +    }
      +
      +    @GenerateInline
      +    @GenerateCached(false)
      +    @GenerateUncached
      +    public abstract static class CallSlotHashFunNode extends Node {
      +        private static final CApiTiming C_API_TIMING = CApiTiming.create(true, "tp_hash");
      +
      +        public abstract long execute(VirtualFrame frame, Node inliningTarget, TpSlot slot, Object self);
      +
      +        @Specialization(guards = "cachedSlot == slot", limit = "3")
      +        static long callCachedBuiltin(VirtualFrame frame, @SuppressWarnings("unused") TpSlotHashBuiltin slot, Object self,
      +                        @SuppressWarnings("unused") @Cached("slot") TpSlotHashBuiltin cachedSlot,
      +                        @Cached("cachedSlot.createSlotNode()") HashBuiltinNode slotNode) {
      +            return slotNode.executeLong(frame, self);
      +        }
      +
      +        @Specialization
      +        static long callPython(VirtualFrame frame, TpSlotPythonSingle slot, Object self,
      +                        @Cached(inline = false) CallSlotHashFunPythonNode callSlotNode) {
      +            return callSlotNode.execute(frame, slot, self);
      +        }
      +
      +        @Specialization
      +        static long callNative(VirtualFrame frame, Node inliningTarget, TpSlotCExtNative slot, Object self,
      +                        @Exclusive @Cached GetThreadStateNode getThreadStateNode,
      +                        @Cached(inline = false) PythonToNativeNode toNativeNode,
      +                        @Exclusive @Cached ExternalFunctionInvokeNode externalInvokeNode,
      +                        @Exclusive @Cached(inline = false) CheckPrimitiveFunctionResultNode checkResultNode) {
      +            PythonContext ctx = PythonContext.get(inliningTarget);
      +            PythonThreadState state = getThreadStateNode.execute(inliningTarget, ctx);
      +            Object result = externalInvokeNode.call(frame, inliningTarget, state, C_API_TIMING, T___HASH__, slot.callable, toNativeNode.execute(self));
      +            return checkResultNode.executeLong(state, T___HASH__, result);
      +        }
      +
      +        @Specialization(replaces = "callCachedBuiltin")
      +        @InliningCutoff
      +        static long callGenericComplexBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotHashBuiltin slot, Object self,
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
      +            Object[] arguments = PArguments.create(1);
      +            PArguments.setArgument(arguments, 0, self);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            return (long) invoke.execute(frame, inliningTarget, callTarget, arguments);
      +        }
      +
      +        public static CallSlotHashFunNode getUncached() {
      +            return CallSlotHashFunNodeGen.getUncached();
      +        }
      +    }
      +
      +    @GenerateUncached
      +    @GenerateInline(false) // intentionally lazy
      +    abstract static class CallSlotHashFunPythonNode extends Node {
      +        abstract long execute(VirtualFrame frame, TpSlotPythonSingle slot, Object obj);
      +
      +        @Specialization
      +        static long doIt(VirtualFrame frame, TpSlotPythonSingle slot, Object self,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached UnaryPythonSlotDispatcherNode dispatcherNode,
      +                        @Cached PyLongCheckNode longCheckNode,
      +                        @Cached PyLongAsLongAndOverflowNode asLongNode,
      +                        @Cached IntBuiltins.HashNode intHashNode,
      +                        @Cached InlinedConditionProfile minusOneProfile,
      +                        @Cached PRaiseNode raiseNode) {
      +            // See CPython: slot_sq_length
      +            Object callable = slot.getCallable();
      +            if (callable == null) {
      +                CompilerDirectives.transferToInterpreterAndInvalidate();
      +                throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.UNHASHABLE_TYPE_P, self);
      +            }
      +            Object result = dispatcherNode.execute(frame, inliningTarget, callable, slot.getType(), self);
      +            if (!longCheckNode.execute(inliningTarget, result)) {
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.HASH_SHOULD_RETURN_INTEGER);
      +            }
      +            /*
      +             * CPython transforms to Py_hash_t using PyLong_AsSsize_t. For us the equivalent is Java
      +             * long. In any case: our transformation must preserve values that already lie within
      +             * this range, to ensure that if x.__hash__() returns hash(y) then hash(x) == hash(y)
      +             */
      +            long hash;
      +            try {
      +                hash = asLongNode.execute(frame, inliningTarget, result);
      +            } catch (OverflowException e) {
      +                /*
      +                 * CPython note: res was not within the range of a Py_hash_t, so we're free to use
      +                 * any sufficiently bit-mixing transformation; long.__hash__ will do nicely.
      +                 */
      +                return intHashNode.executeLong(frame, result);
      +            }
      +            /* -1 is reserved for errors. */
      +            if (minusOneProfile.profile(inliningTarget, hash == -1)) {
      +                return -2;
      +            }
      +            return hash;
      +        }
      +    }
      +}
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotInquiry.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotInquiry.java
      index 982f7127e7..9f0d8244b3 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotInquiry.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotInquiry.java
      @@ -152,7 +152,7 @@ static boolean doIt(VirtualFrame frame, TpSlotPythonSingle slot, Object self,
                               @Bind("this") Node inliningTarget,
                               @Cached UnaryPythonSlotDispatcherNode dispatcherNode,
                               @Cached PyBoolCheckNode pyBoolCheckNode,
      -                        @Cached PRaiseNode.Lazy raiseNode,
      +                        @Cached PRaiseNode raiseNode,
                               @Cached PyObjectIsTrueNode pyObjectIsTrueNode) {
                   // See CPython: slot_nb_bool
                   // TODO: it is not clear to me why CPython lookups __len__ in the slot wrapper although
      @@ -160,7 +160,7 @@ static boolean doIt(VirtualFrame frame, TpSlotPythonSingle slot, Object self,
                   // __len__. We ignore the __len__ lookup for now.
                   Object result = dispatcherNode.execute(frame, inliningTarget, slot.getCallable(), slot.getType(), self);
                   if (!pyBoolCheckNode.execute(inliningTarget, result)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.BOOL_SHOULD_RETURN_BOOL, result);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.BOOL_SHOULD_RETURN_BOOL, result);
                   }
                   return pyObjectIsTrueNode.execute(frame, result);
               }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotIterNext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotIterNext.java
      new file mode 100644
      index 0000000000..6c1684830d
      --- /dev/null
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotIterNext.java
      @@ -0,0 +1,213 @@
      +/*
      + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
      + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      + *
      + * The Universal Permissive License (UPL), Version 1.0
      + *
      + * Subject to the condition set forth below, permission is hereby granted to any
      + * person obtaining a copy of this software, associated documentation and/or
      + * data (collectively the "Software"), free of charge and under any and all
      + * copyright rights in the Software, and any and all patent rights owned or
      + * freely licensable by each licensor hereunder covering either (i) the
      + * unmodified Software as contributed to or provided by such licensor, or (ii)
      + * the Larger Works (as defined below), to deal in both
      + *
      + * (a) the Software, and
      + *
      + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
      + * one is included with the Software each a "Larger Work" to which the Software
      + * is contributed by such licensors),
      + *
      + * without restriction, including without limitation the rights to copy, create
      + * derivative works of, display, perform, and distribute the Software and make,
      + * use, sell, offer for sale, import, export, have made, and have sold the
      + * Software and the Larger Work(s), and to sublicense the foregoing rights on
      + * either these or other terms.
      + *
      + * This license is subject to the following condition:
      + *
      + * The above copyright notice and either this complete permission notice or at a
      + * minimum a reference to the UPL must be included in all copies or substantial
      + * portions of the Software.
      + *
      + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      + * SOFTWARE.
      + */
      +package com.oracle.graal.python.builtins.objects.type.slots;
      +
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEXT__;
      +
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.builtins.Python3Core;
      +import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      +import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.ExternalFunctionInvokeNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonTransferNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode;
      +import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.ClearCurrentExceptionNode;
      +import com.oracle.graal.python.builtins.objects.function.PArguments;
      +import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
      +import com.oracle.graal.python.builtins.objects.type.slots.NodeFactoryUtils.WrapperNodeFactory;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotBuiltin;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotCExtNative;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPythonSingle;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotUnaryFunc.CallSlotUnaryPythonNode;
      +import com.oracle.graal.python.lib.IteratorExhausted;
      +import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.PRaiseNode;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
      +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
      +import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
      +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
      +import com.oracle.truffle.api.RootCallTarget;
      +import com.oracle.truffle.api.dsl.Bind;
      +import com.oracle.truffle.api.dsl.Cached;
      +import com.oracle.truffle.api.dsl.GenerateCached;
      +import com.oracle.truffle.api.dsl.GenerateInline;
      +import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      +import com.oracle.truffle.api.dsl.GenerateUncached;
      +import com.oracle.truffle.api.dsl.NodeFactory;
      +import com.oracle.truffle.api.dsl.Specialization;
      +import com.oracle.truffle.api.frame.VirtualFrame;
      +import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.strings.TruffleString;
      +
      +public final class TpSlotIterNext {
      +    private TpSlotIterNext() {
      +    }
      +
      +    /** Equivalent of {@code _PyObject_NextNotImplemented} */
      +    public static final TpSlot NEXT_NOT_IMPLEMENTED = TpSlotIterNextSlotsGen.SLOTS.tp_iternext();
      +
      +    public abstract static class TpSlotIterNextBuiltin extends TpSlotBuiltin {
      +        final int callTargetIndex = TpSlotBuiltinCallTargetRegistry.getNextCallTargetIndex();
      +
      +        protected TpSlotIterNextBuiltin(NodeFactory nodeFactory) {
      +            super(nodeFactory);
      +        }
      +
      +        final PythonUnaryBuiltinNode createSlotNode() {
      +            return createNode();
      +        }
      +
      +        @Override
      +        public final void initialize(PythonLanguage language) {
      +            RootCallTarget callTarget = createSlotCallTarget(language, BuiltinSlotWrapperSignature.UNARY, getNodeFactory(), J___NEXT__);
      +            language.setBuiltinSlotCallTarget(callTargetIndex, callTarget);
      +        }
      +
      +        @Override
      +        public PBuiltinFunction createBuiltin(Python3Core core, Object type, TruffleString tsName, PExternalFunctionWrapper wrapper) {
      +            var factory = new WrapperNodeFactory<>(getNodeFactory(), TpIterNextBuiltinWrapperNode.class, TpIterNextBuiltinWrapperNode::new);
      +            return createBuiltin(core, type, tsName, BuiltinSlotWrapperSignature.UNARY, wrapper, factory);
      +        }
      +    }
      +
      +    public static final class TpIterNextBuiltinWrapperNode extends PythonUnaryBuiltinNode {
      +        @Child PythonUnaryBuiltinNode delegate;
      +
      +        public TpIterNextBuiltinWrapperNode(PythonUnaryBuiltinNode delegate) {
      +            this.delegate = delegate;
      +        }
      +
      +        @Override
      +        public Object execute(VirtualFrame frame, Object arg) {
      +            try {
      +                return delegate.execute(frame, arg);
      +            } catch (IteratorExhausted e) {
      +                throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.StopIteration);
      +            }
      +        }
      +    }
      +
      +    /**
      +     * Convenience base class for {@code tp_iternext} builtin implementations.
      +     * {@code PythonUnaryBuiltinNode} can be used instead if necessitated by existing inheritance
      +     * hierarchy.
      +     */
      +    @GenerateInline(value = false, inherit = true)
      +    public abstract static class TpIterNextBuiltin extends PythonUnaryBuiltinNode {
      +        /**
      +         * Raise a control flow exception that signals iterator exhaustion. A faster equivalent to
      +         * raising {@code StopIteration} python exception. Should not be used outside of
      +         * {@code tp_iternext} implementations.
      +         */
      +        public static IteratorExhausted iteratorExhausted() {
      +            throw IteratorExhausted.INSTANCE;
      +        }
      +    }
      +
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
      +    @GenerateNodeFactory
      +    abstract static class NextNotImplementedNode extends PythonUnaryBuiltinNode {
      +        @Specialization
      +        static Object error(Object iterable,
      +                        @Bind Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_NOT_ITERABLE, iterable);
      +        }
      +    }
      +
      +    @GenerateInline
      +    @GenerateCached(false)
      +    @GenerateUncached
      +    public abstract static class CallSlotTpIterNextNode extends Node {
      +        private static final CApiTiming C_API_TIMING = CApiTiming.create(true, "iternext");
      +
      +        public abstract Object execute(VirtualFrame frame, Node inliningTarget, TpSlot slot, Object self);
      +
      +        @Specialization(guards = "cachedSlot == slot", limit = "3")
      +        static Object callCachedBuiltin(VirtualFrame frame, @SuppressWarnings("unused") TpSlotIterNextBuiltin slot, Object self,
      +                        @SuppressWarnings("unused") @Cached("slot") TpSlotIterNextBuiltin cachedSlot,
      +                        @Cached("cachedSlot.createSlotNode()") PythonUnaryBuiltinNode slotNode) {
      +            return slotNode.execute(frame, self);
      +        }
      +
      +        @Specialization
      +        static Object callPython(VirtualFrame frame, TpSlotPythonSingle slot, Object self,
      +                        @Cached(inline = false) CallSlotUnaryPythonNode callSlotNode) {
      +            return callSlotNode.execute(frame, slot, self);
      +        }
      +
      +        @Specialization
      +        static Object callNative(VirtualFrame frame, Node inliningTarget, TpSlotCExtNative slot, Object self,
      +                        @Cached GetThreadStateNode getThreadStateNode,
      +                        @Cached(inline = false) PythonToNativeNode toNativeNode,
      +                        @Cached ExternalFunctionInvokeNode externalInvokeNode,
      +                        @Cached(inline = false) NativeToPythonTransferNode toPythonNode,
      +                        @Cached ClearCurrentExceptionNode clearCurrentExceptionNode) {
      +            PythonThreadState state = getThreadStateNode.execute(inliningTarget);
      +            Object nativeResult = externalInvokeNode.call(frame, inliningTarget, state, C_API_TIMING, T___NEXT__, slot.callable,
      +                            toNativeNode.execute(self));
      +            Object pythonResult = toPythonNode.execute(nativeResult);
      +            if (pythonResult == PNone.NO_VALUE) {
      +                if (state.getCurrentException() != null) {
      +                    throw clearCurrentExceptionNode.getCurrentExceptionForReraise(inliningTarget, state);
      +                } else {
      +                    throw TpIterNextBuiltin.iteratorExhausted();
      +                }
      +            }
      +            return pythonResult;
      +        }
      +
      +        @Specialization(replaces = "callCachedBuiltin")
      +        @InliningCutoff
      +        static Object callGenericBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotIterNextBuiltin slot, Object self,
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
      +            Object[] arguments = PArguments.create(1);
      +            PArguments.setArgument(arguments, 0, self);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            return invoke.execute(frame, inliningTarget, callTarget, arguments);
      +        }
      +    }
      +}
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotLen.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotLen.java
      index faca264b47..33630a7d05 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotLen.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotLen.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -51,25 +51,20 @@
       import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper;
       import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming;
       import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode;
      -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsHandleNode;
       import com.oracle.graal.python.builtins.objects.function.PArguments;
       import com.oracle.graal.python.builtins.objects.ints.PInt;
      -import com.oracle.graal.python.builtins.objects.type.slots.HPyDispatchers.UnaryHPySlotDispatcherNode;
       import com.oracle.graal.python.builtins.objects.type.slots.PythonDispatchers.UnaryPythonSlotDispatcherNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotBuiltinBase;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotCExtNative;
      -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotHPyNative;
      -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotNative;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPythonSingle;
       import com.oracle.graal.python.lib.PyNumberAsSizeNode;
       import com.oracle.graal.python.lib.PyNumberIndexNode;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PRaiseNode;
      -import com.oracle.graal.python.nodes.PRaiseNode.Lazy;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.util.CastToJavaIntLossyNode;
      -import com.oracle.graal.python.runtime.ExecutionContext.CallContext;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
       import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
      @@ -85,11 +80,9 @@
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      -import com.oracle.truffle.api.nodes.IndirectCallNode;
       import com.oracle.truffle.api.nodes.Node;
       import com.oracle.truffle.api.nodes.UnexpectedResultException;
       import com.oracle.truffle.api.profiles.InlinedBranchProfile;
      -import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       
       public abstract class TpSlotLen {
           private TpSlotLen() {
      @@ -134,7 +127,7 @@ protected TpSlotLenBuiltinComplex(NodeFactory nodeFactory) {
       
               @Override
               public final void initialize(PythonLanguage language) {
      -            RootCallTarget callTarget = createBuiltinCallTarget(language, SIGNATURE, getNodeFactory(), J___LEN__);
      +            RootCallTarget callTarget = createSlotCallTarget(language, SIGNATURE, getNodeFactory(), J___LEN__);
                   language.setBuiltinSlotCallTarget(callTargetIndex, callTarget);
               }
           }
      @@ -175,7 +168,7 @@ static int callNative(VirtualFrame frame, Node inliningTarget, TpSlotCExtNative
                               @Exclusive @Cached GetThreadStateNode getThreadStateNode,
                               @Cached(inline = false) PythonToNativeNode toNativeNode,
                               @Exclusive @Cached ExternalFunctionInvokeNode externalInvokeNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode,
      +                        @Exclusive @Cached PRaiseNode raiseNode,
                               @Exclusive @Cached(inline = false) CheckPrimitiveFunctionResultNode checkResultNode) {
                   PythonContext ctx = PythonContext.get(inliningTarget);
                   PythonThreadState state = getThreadStateNode.execute(inliningTarget, ctx);
      @@ -187,26 +180,9 @@ static int callNative(VirtualFrame frame, Node inliningTarget, TpSlotCExtNative
                   return (int) l;
               }
       
      -        @Specialization
      -        static int callNative(VirtualFrame frame, Node inliningTarget, TpSlotHPyNative slot, Object self,
      -                        @Exclusive @Cached GetThreadStateNode getThreadStateNode,
      -                        @Cached(inline = false) HPyAsHandleNode toNativeNode,
      -                        @Exclusive @Cached ExternalFunctionInvokeNode externalInvokeNode,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode,
      -                        @Exclusive @Cached(inline = false) CheckPrimitiveFunctionResultNode checkResultNode) {
      -            PythonContext ctx = PythonContext.get(inliningTarget);
      -            PythonThreadState state = getThreadStateNode.execute(inliningTarget, ctx);
      -            Object result = externalInvokeNode.call(frame, inliningTarget, state, C_API_TIMING, T___LEN__, slot.callable, ctx.getHPyContext().getBackend(), toNativeNode.execute(self));
      -            long l = checkResultNode.executeLong(state, T___LEN__, result);
      -            if (!PInt.isIntRange(l)) {
      -                raiseOverflow(inliningTarget, raiseNode, l);
      -            }
      -            return (int) l;
      -        }
      -
               @InliningCutoff
      -        private static void raiseOverflow(Node inliningTarget, Lazy raiseNode, long l) {
      -            throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, l);
      +        private static void raiseOverflow(Node inliningTarget, PRaiseNode raiseNode, long l) {
      +            throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, l);
               }
       
               @Specialization(replaces = "callCachedBuiltin")
      @@ -217,30 +193,11 @@ static int callGenericSimpleBuiltin(TpSlotLenBuiltinSimple slot, Object self)
               @Specialization(replaces = "callCachedBuiltin")
               @InliningCutoff
               static int callGenericComplexBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotLenBuiltinComplex slot, Object self,
      -                        @Cached(inline = false) CallContext callContext,
      -                        @Cached InlinedConditionProfile isNullFrameProfile,
      -                        @Cached(inline = false) IndirectCallNode indirectCallNode) {
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
                   Object[] arguments = PArguments.create(1);
                   PArguments.setArgument(arguments, 0, self);
      -            return (int) BuiltinDispatchers.callGenericBuiltin(frame, inliningTarget, slot.callTargetIndex, arguments, callContext, isNullFrameProfile, indirectCallNode);
      -        }
      -
      -        // @Specialization(guards = "slot.isHPySlot()")
      -        // @InliningCutoff
      -        @SuppressWarnings("unused")
      -        static int callHPy(VirtualFrame frame, Node inliningTarget, TpSlotNative slot, Object self,
      -                        @Cached GetThreadStateNode getThreadStateNode,
      -                        @Cached UnaryHPySlotDispatcherNode hpyDispatcher,
      -                        @Cached PRaiseNode.Lazy raiseNode,
      -                        @Cached(inline = false) CheckPrimitiveFunctionResultNode checkResultNode) {
      -            PythonContext ctx = PythonContext.get(inliningTarget);
      -            PythonThreadState state = getThreadStateNode.execute(inliningTarget, ctx);
      -            Object result = hpyDispatcher.execute(frame, inliningTarget, ctx, state, slot.callable, self);
      -            long l = checkResultNode.executeLong(state, T___LEN__, result);
      -            if (!PInt.isIntRange(l)) {
      -                raiseOverflow(inliningTarget, raiseNode, l);
      -            }
      -            return (int) l;
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            return (int) invoke.execute(frame, inliningTarget, callTarget, arguments);
               }
           }
       
      @@ -257,7 +214,7 @@ static int doIt(VirtualFrame frame, TpSlotPythonSingle slot, Object self,
                               @Bind("this") Node inliningTarget,
                               @Cached UnaryPythonSlotDispatcherNode dispatcherNode,
                               @Cached InlinedBranchProfile genericCheck,
      -                        @Cached PRaiseNode.Lazy raiseNode,
      +                        @Cached PRaiseNode raiseNode,
                               @Cached PyNumberIndexNode indexNode,
                               @Cached CastToJavaIntLossyNode castLossy,
                               @Cached PyNumberAsSizeNode asSizeNode) {
      @@ -274,7 +231,7 @@ static int doIt(VirtualFrame frame, TpSlotPythonSingle slot, Object self,
                   return convertAndCheckLen(frame, inliningTarget, result, indexNode, castLossy, asSizeNode, raiseNode);
               }
       
      -        static int checkLen(Node inliningTarget, PRaiseNode.Lazy raiseNode, int len) {
      +        static int checkLen(Node inliningTarget, PRaiseNode raiseNode, int len) {
                   if (len < 0) {
                       raiseLenGt0(inliningTarget, raiseNode);
                   }
      @@ -282,12 +239,12 @@ static int checkLen(Node inliningTarget, PRaiseNode.Lazy raiseNode, int len) {
               }
       
               @InliningCutoff
      -        private static void raiseLenGt0(Node inliningTarget, Lazy raiseNode) {
      -            throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.LEN_SHOULD_RETURN_GT_ZERO);
      +        private static void raiseLenGt0(Node inliningTarget, PRaiseNode raiseNode) {
      +            throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.LEN_SHOULD_RETURN_GT_ZERO);
               }
       
               public static int convertAndCheckLen(VirtualFrame frame, Node inliningTarget, Object result, PyNumberIndexNode indexNode,
      -                        CastToJavaIntLossyNode castLossy, PyNumberAsSizeNode asSizeNode, PRaiseNode.Lazy raiseNode) {
      +                        CastToJavaIntLossyNode castLossy, PyNumberAsSizeNode asSizeNode, PRaiseNode raiseNode) {
                   int len;
                   Object index = indexNode.execute(frame, inliningTarget, result);
                   try {
      @@ -305,7 +262,7 @@ public static int convertAndCheckLen(VirtualFrame frame, Node inliningTarget, Ob
               }
       
               @InliningCutoff
      -        private static PException checkNegative(Node inliningTarget, CastToJavaIntLossyNode castLossy, Lazy raiseNode, PException e, Object index) {
      +        private static PException checkNegative(Node inliningTarget, CastToJavaIntLossyNode castLossy, PRaiseNode raiseNode, PException e, Object index) {
                   int len;
                   len = castLossy.execute(inliningTarget, index);
                   checkLen(inliningTarget, raiseNode, len);
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotMpAssSubscript.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotMpAssSubscript.java
      index 5225165777..487d1264bb 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotMpAssSubscript.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotMpAssSubscript.java
      @@ -67,8 +67,8 @@
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
       import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
      -import com.oracle.graal.python.runtime.ExecutionContext.CallContext;
       import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
       import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
       import com.oracle.graal.python.runtime.exception.PException;
      @@ -84,9 +84,7 @@
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      -import com.oracle.truffle.api.nodes.IndirectCallNode;
       import com.oracle.truffle.api.nodes.Node;
      -import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       import com.oracle.truffle.api.utilities.TruffleWeakReference;
       
      @@ -108,7 +106,7 @@ final MpAssSubscriptBuiltinNode createSlotNode() {
       
               @Override
               public void initialize(PythonLanguage language) {
      -            RootCallTarget target = createBuiltinCallTarget(language, SET_SIGNATURE, getNodeFactory(), J___SETITEM__);
      +            RootCallTarget target = createSlotCallTarget(language, SET_SIGNATURE, getNodeFactory(), J___SETITEM__);
                   language.setBuiltinSlotCallTarget(callTargetIndex, target);
               }
       
      @@ -237,7 +235,7 @@ static void callCachedBuiltin(VirtualFrame frame, @SuppressWarnings("unused") Tp
       
               @Specialization(guards = "!isNoValue(value)")
               static void callPythonSimpleSet(VirtualFrame frame, Node inliningTarget, TpSlotMpAssSubscriptPython slot, Object self, Object key, Object value,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode,
      +                        @Exclusive @Cached PRaiseNode raiseNode,
                               @Cached TernaryPythonSlotDispatcherNode callPythonFun) {
                   Object callable = slot.getSetitem();
                   if (callable == null) {
      @@ -249,7 +247,7 @@ static void callPythonSimpleSet(VirtualFrame frame, Node inliningTarget, TpSlotM
               @Specialization(guards = "isNoValue(value)")
               @InliningCutoff
               static void callPythonSimpleDel(VirtualFrame frame, Node inliningTarget, TpSlotMpAssSubscriptPython slot, Object self, Object key, @SuppressWarnings("unused") Object value,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode,
      +                        @Exclusive @Cached PRaiseNode raiseNode,
                               @Cached BinaryPythonSlotDispatcherNode callPythonFun) {
                   Object callable = slot.getDelitem();
                   if (callable == null) {
      @@ -259,21 +257,20 @@ static void callPythonSimpleDel(VirtualFrame frame, Node inliningTarget, TpSlotM
               }
       
               @InliningCutoff
      -        private static PException raiseAttributeError(Node inliningTarget, PRaiseNode.Lazy raiseNode, TruffleString attrName) {
      -            return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.AttributeError, attrName);
      +        private static PException raiseAttributeError(Node inliningTarget, PRaiseNode raiseNode, TruffleString attrName) {
      +            return raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, attrName);
               }
       
               @Specialization(replaces = "callCachedBuiltin")
               @InliningCutoff
               static void callGenericBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotMpAssSubscriptBuiltin slot, Object self, Object key, Object value,
      -                        @Cached(inline = false) CallContext callContext,
      -                        @Cached InlinedConditionProfile isNullFrameProfile,
      -                        @Cached(inline = false) IndirectCallNode indirectCallNode) {
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
                   Object[] arguments = PArguments.create(3);
                   PArguments.setArgument(arguments, 0, self);
                   PArguments.setArgument(arguments, 1, key);
                   PArguments.setArgument(arguments, 2, value);
      -            BuiltinDispatchers.callGenericBuiltin(frame, inliningTarget, slot.callTargetIndex, arguments, callContext, isNullFrameProfile, indirectCallNode);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            invoke.execute(frame, inliningTarget, callTarget, arguments);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotNbPower.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotNbPower.java
      new file mode 100644
      index 0000000000..0abdde3f10
      --- /dev/null
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotNbPower.java
      @@ -0,0 +1,264 @@
      +/*
      + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
      + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      + *
      + * The Universal Permissive License (UPL), Version 1.0
      + *
      + * Subject to the condition set forth below, permission is hereby granted to any
      + * person obtaining a copy of this software, associated documentation and/or
      + * data (collectively the "Software"), free of charge and under any and all
      + * copyright rights in the Software, and any and all patent rights owned or
      + * freely licensable by each licensor hereunder covering either (i) the
      + * unmodified Software as contributed to or provided by such licensor, or (ii)
      + * the Larger Works (as defined below), to deal in both
      + *
      + * (a) the Software, and
      + *
      + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
      + * one is included with the Software each a "Larger Work" to which the Software
      + * is contributed by such licensors),
      + *
      + * without restriction, including without limitation the rights to copy, create
      + * derivative works of, display, perform, and distribute the Software and make,
      + * use, sell, offer for sale, import, export, have made, and have sold the
      + * Software and the Larger Work(s), and to sublicense the foregoing rights on
      + * either these or other terms.
      + *
      + * This license is subject to the following condition:
      + *
      + * The above copyright notice and either this complete permission notice or at a
      + * minimum a reference to the UPL must be included in all copies or substantial
      + * portions of the Software.
      + *
      + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      + * SOFTWARE.
      + */
      +package com.oracle.graal.python.builtins.objects.type.slots;
      +
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.J___POW__;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IPOW__;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___POW__;
      +
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.builtins.Python3Core;
      +import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.PNotImplemented;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.ExternalFunctionInvokeNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PyObjectCheckFunctionResultNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonTransferNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode;
      +import com.oracle.graal.python.builtins.objects.function.PArguments;
      +import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.NodeFactoryUtils.WrapperNodeFactory;
      +import com.oracle.graal.python.builtins.objects.type.slots.PythonDispatchers.BinaryPythonSlotDispatcherNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.PythonDispatchers.TernaryPythonSlotDispatcherNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotBuiltin;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotCExtNative;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPythonSingle;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.CallReversiblePythonSlotNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.TpSlotReversiblePython;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
      +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
      +import com.oracle.graal.python.runtime.PythonContext;
      +import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
      +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
      +import com.oracle.truffle.api.RootCallTarget;
      +import com.oracle.truffle.api.dsl.Bind;
      +import com.oracle.truffle.api.dsl.Cached;
      +import com.oracle.truffle.api.dsl.Fallback;
      +import com.oracle.truffle.api.dsl.GenerateCached;
      +import com.oracle.truffle.api.dsl.GenerateInline;
      +import com.oracle.truffle.api.dsl.GenerateUncached;
      +import com.oracle.truffle.api.dsl.NodeFactory;
      +import com.oracle.truffle.api.dsl.Specialization;
      +import com.oracle.truffle.api.frame.VirtualFrame;
      +import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.InlinedBranchProfile;
      +import com.oracle.truffle.api.strings.TruffleString;
      +
      +public final class TpSlotNbPower {
      +    private TpSlotNbPower() {
      +    }
      +
      +    public abstract static class TpSlotNbPowerBuiltin extends TpSlotBuiltin {
      +        private final int callTargetIndex = TpSlotBuiltinCallTargetRegistry.getNextCallTargetIndex();
      +
      +        private static final BuiltinSlotWrapperSignature SIGNATURE = BuiltinSlotWrapperSignature.of(2, "v", "w", "z");
      +
      +        protected TpSlotNbPowerBuiltin(NodeFactory nodeFactory) {
      +            super(nodeFactory);
      +        }
      +
      +        final PythonTernaryBuiltinNode createOpSlotNode() {
      +            return createNode();
      +        }
      +
      +        @Override
      +        public void initialize(PythonLanguage language) {
      +            RootCallTarget callTarget = createSlotCallTarget(language, SIGNATURE, getNodeFactory(), J___POW__);
      +            language.setBuiltinSlotCallTarget(callTargetIndex, callTarget);
      +        }
      +
      +        @Override
      +        public PBuiltinFunction createBuiltin(Python3Core core, Object type, TruffleString tsName, PExternalFunctionWrapper wrapper) {
      +            return switch (wrapper) {
      +                case TERNARYFUNC -> createBuiltin(core, type, tsName, SIGNATURE, wrapper, getNodeFactory());
      +                case TERNARYFUNC_R -> createRBuiltin(core, type, tsName);
      +                default -> null;
      +            };
      +        }
      +
      +        private PBuiltinFunction createRBuiltin(Python3Core core, Object type, TruffleString tsName) {
      +            var factory = WrapperNodeFactory.wrap(getNodeFactory(), SwapArgumentsNode.class, SwapArgumentsNode::new);
      +            return createBuiltin(core, type, tsName, SIGNATURE, PExternalFunctionWrapper.TERNARYFUNC_R, factory);
      +        }
      +    }
      +
      +    static final class SwapArgumentsNode extends PythonTernaryBuiltinNode {
      +        @Child private PythonTernaryBuiltinNode wrapped;
      +
      +        SwapArgumentsNode(PythonTernaryBuiltinNode wrapped) {
      +            this.wrapped = wrapped;
      +        }
      +
      +        @Override
      +        public Object execute(VirtualFrame frame, Object self, Object w, Object z) {
      +            return wrapped.execute(frame, w, self, z);
      +        }
      +    }
      +
      +    @GenerateInline
      +    @GenerateCached(false)
      +    @GenerateUncached
      +    public abstract static class CallSlotNbPowerNode extends Node {
      +        private static final CApiTiming C_API_TIMING = CApiTiming.create(true, "ternaryfunc");
      +
      +        public abstract Object execute(VirtualFrame frame, Node inliningTarget, TpSlot slot,
      +                        Object v, Object vType, Object w, TpSlot wSlot, Object wType, Object z, boolean sameTypes);
      +
      +        @SuppressWarnings("unused")
      +        @Specialization(guards = "cachedSlot == slot", limit = "3")
      +        static Object callCachedBuiltin(VirtualFrame frame, TpSlotNbPowerBuiltin slot,
      +                        Object v, Object vType, Object w, TpSlot wSlot, Object wType, Object z, boolean sameTypes,
      +                        @Cached("slot") TpSlotNbPowerBuiltin cachedSlot,
      +                        @Cached("cachedSlot.createOpSlotNode()") PythonTernaryBuiltinNode slotNode) {
      +            return slotNode.execute(frame, v, w, z);
      +        }
      +
      +        @Specialization
      +        static Object callPython(VirtualFrame frame, TpSlotReversiblePython slot,
      +                        Object v, Object vType, Object w, TpSlot wSlot, Object wType, Object z, boolean sameTypes,
      +                        @Cached(inline = false) CallNbPowerPythonNode callPython) {
      +            return callPython.execute(frame, slot, v, vType, w, wSlot, wType, z, sameTypes);
      +        }
      +
      +        @SuppressWarnings("unused")
      +        @Specialization
      +        static Object callNative(VirtualFrame frame, Node inliningTarget, TpSlotCExtNative slot,
      +                        Object v, Object vType, Object w, TpSlot wSlot, Object wType, Object z, boolean sameTypes,
      +                        @Cached GetThreadStateNode getThreadStateNode,
      +                        @Cached(inline = false) PythonToNativeNode vToNative,
      +                        @Cached(inline = false) PythonToNativeNode wToNative,
      +                        @Cached(inline = false) PythonToNativeNode zToNative,
      +                        @Cached ExternalFunctionInvokeNode externalInvokeNode,
      +                        @Cached(inline = false) NativeToPythonTransferNode toPythonNode,
      +                        @Cached(inline = false) PyObjectCheckFunctionResultNode checkResultNode) {
      +            PythonContext ctx = PythonContext.get(inliningTarget);
      +            PythonContext.PythonThreadState state = getThreadStateNode.execute(inliningTarget, ctx);
      +            Object result = externalInvokeNode.call(frame, inliningTarget, state, C_API_TIMING, T___POW__, slot.callable,
      +                            vToNative.execute(v), wToNative.execute(w), zToNative.execute(z));
      +            return checkResultNode.execute(state, T___POW__, toPythonNode.execute(result));
      +        }
      +
      +        @SuppressWarnings("unused")
      +        @Specialization(replaces = "callCachedBuiltin")
      +        @InliningCutoff
      +        static Object callGenericComplexBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotNbPowerBuiltin slot,
      +                        Object v, Object vType, Object w, TpSlot wSlot, Object wType, Object z, boolean sameTypes,
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
      +            Object[] arguments = PArguments.create(3);
      +            PArguments.setArgument(arguments, 0, v);
      +            PArguments.setArgument(arguments, 1, w);
      +            PArguments.setArgument(arguments, 2, z);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            return invoke.execute(frame, inliningTarget, callTarget, arguments);
      +        }
      +    }
      +
      +    @GenerateUncached
      +    @GenerateInline(false) // intentional explicit "data-class"
      +    abstract static class CallNbPowerPythonNode extends Node {
      +        public abstract Object execute(VirtualFrame frame, TpSlotReversiblePython slot, Object v, Object vType, Object w, TpSlot wSlot, Object wType, Object z, boolean sameTypes);
      +
      +        @Specialization
      +        static Object callPythonAsBinary(VirtualFrame frame, TpSlotReversiblePython slot,
      +                        Object v, Object vType, Object w, TpSlot wSlot, Object wType, @SuppressWarnings("unused") PNone z, boolean sameTypes,
      +                        @Cached CallReversiblePythonSlotNode callPython) {
      +            return callPython.execute(frame, slot, v, vType, w, wSlot, wType, sameTypes, ReversibleSlot.NB_POWER_BINARY);
      +        }
      +
      +        @Fallback
      +        @SuppressWarnings("unused")
      +        static Object callPythonAsTernary(VirtualFrame frame, TpSlotReversiblePython slot,
      +                        Object v, Object vType, Object w, TpSlot wSlot, Object wType, Object z, boolean sameTypes,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached GetCachedTpSlotsNode getSelfSlotsNode,
      +                        @Cached TernaryPythonSlotDispatcherNode dispatcherNode,
      +                        @Cached InlinedBranchProfile notImplementedProfile) {
      +            /*
      +             * Three-arg power doesn't use __rpow__. But ternary_op can call this when the second
      +             * argument's type uses slot_nb_power, so check before calling self.__pow__.
      +             */
      +            TpSlots selfSlots = getSelfSlotsNode.execute(inliningTarget, vType);
      +            if (CallReversiblePythonSlotNode.isSameReversibleWrapper(selfSlots.nb_power(), ReversibleSlot.NB_POWER_BINARY)) {
      +                return dispatcherNode.execute(frame, inliningTarget, slot.getLeft(), slot.getType(), v, w, z);
      +            }
      +            notImplementedProfile.enter(inliningTarget);
      +            return PNotImplemented.NOT_IMPLEMENTED;
      +        }
      +    }
      +
      +    @GenerateInline
      +    @GenerateCached(false)
      +    @GenerateUncached
      +    public abstract static class CallSlotNbInPlacePowerNode extends Node {
      +        private static final CApiTiming C_API_TIMING = CApiTiming.create(true, "ternaryfunc");
      +
      +        public abstract Object execute(VirtualFrame frame, Node inliningTarget, TpSlot slot, Object v, Object w, Object z);
      +
      +        // There are no builtin implementations
      +
      +        @Specialization
      +        static Object callPython(VirtualFrame frame, Node inliningTarget, TpSlotPythonSingle slot, Object v, Object w, @SuppressWarnings("unused") Object z,
      +                        @Cached BinaryPythonSlotDispatcherNode dispatcherNode) {
      +            // CPython doesn't pass the third argument to __ipow__
      +            return dispatcherNode.execute(frame, inliningTarget, slot.getCallable(), slot.getType(), v, w);
      +        }
      +
      +        @Specialization
      +        static Object callNative(VirtualFrame frame, Node inliningTarget, TpSlotCExtNative slot, Object v, Object w, Object z,
      +                        @Cached GetThreadStateNode getThreadStateNode,
      +                        @Cached(inline = false) PythonToNativeNode vToNative,
      +                        @Cached(inline = false) PythonToNativeNode wToNative,
      +                        @Cached(inline = false) PythonToNativeNode zToNative,
      +                        @Cached ExternalFunctionInvokeNode externalInvokeNode,
      +                        @Cached(inline = false) NativeToPythonTransferNode toPythonNode,
      +                        @Cached(inline = false) PyObjectCheckFunctionResultNode checkResultNode) {
      +            PythonContext ctx = PythonContext.get(inliningTarget);
      +            PythonContext.PythonThreadState state = getThreadStateNode.execute(inliningTarget, ctx);
      +            Object result = externalInvokeNode.call(frame, inliningTarget, state, C_API_TIMING, T___IPOW__, slot.callable,
      +                            vToNative.execute(v), wToNative.execute(w), zToNative.execute(z));
      +            return checkResultNode.execute(state, T___IPOW__, toPythonNode.execute(result));
      +        }
      +    }
      +}
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotRepr.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotRepr.java
      new file mode 100644
      index 0000000000..f4a87474a9
      --- /dev/null
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotRepr.java
      @@ -0,0 +1,191 @@
      +/*
      + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
      + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      + *
      + * The Universal Permissive License (UPL), Version 1.0
      + *
      + * Subject to the condition set forth below, permission is hereby granted to any
      + * person obtaining a copy of this software, associated documentation and/or
      + * data (collectively the "Software"), free of charge and under any and all
      + * copyright rights in the Software, and any and all patent rights owned or
      + * freely licensable by each licensor hereunder covering either (i) the
      + * unmodified Software as contributed to or provided by such licensor, or (ii)
      + * the Larger Works (as defined below), to deal in both
      + *
      + * (a) the Software, and
      + *
      + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
      + * one is included with the Software each a "Larger Work" to which the Software
      + * is contributed by such licensors),
      + *
      + * without restriction, including without limitation the rights to copy, create
      + * derivative works of, display, perform, and distribute the Software and make,
      + * use, sell, offer for sale, import, export, have made, and have sold the
      + * Software and the Larger Work(s), and to sublicense the foregoing rights on
      + * either these or other terms.
      + *
      + * This license is subject to the following condition:
      + *
      + * The above copyright notice and either this complete permission notice or at a
      + * minimum a reference to the UPL must be included in all copies or substantial
      + * portions of the Software.
      + *
      + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      + * SOFTWARE.
      + */
      +package com.oracle.graal.python.builtins.objects.type.slots;
      +
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___REPR__;
      +
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.ExternalFunctionInvokeNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PyObjectCheckFunctionResultNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonTransferNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode;
      +import com.oracle.graal.python.builtins.objects.function.PArguments;
      +import com.oracle.graal.python.builtins.objects.function.PFunction;
      +import com.oracle.graal.python.builtins.objects.object.ObjectNodes;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotCExtNative;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPythonSingle;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotUnaryFunc.TpSlotUnaryFuncBuiltin;
      +import com.oracle.graal.python.nodes.call.BoundDescriptor;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
      +import com.oracle.graal.python.nodes.call.CallNode;
      +import com.oracle.graal.python.nodes.call.special.MaybeBindDescriptorNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
      +import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
      +import com.oracle.graal.python.util.PythonUtils;
      +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
      +import com.oracle.truffle.api.RootCallTarget;
      +import com.oracle.truffle.api.dsl.Bind;
      +import com.oracle.truffle.api.dsl.Cached;
      +import com.oracle.truffle.api.dsl.GenerateCached;
      +import com.oracle.truffle.api.dsl.GenerateInline;
      +import com.oracle.truffle.api.dsl.GenerateUncached;
      +import com.oracle.truffle.api.dsl.ImportStatic;
      +import com.oracle.truffle.api.dsl.Specialization;
      +import com.oracle.truffle.api.exception.AbstractTruffleException;
      +import com.oracle.truffle.api.frame.VirtualFrame;
      +import com.oracle.truffle.api.nodes.DirectCallNode;
      +import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.utilities.TruffleWeakReference;
      +
      +public final class TpSlotRepr {
      +    private TpSlotRepr() {
      +    }
      +
      +    // The only difference from CallSlotUnaryNode is the fallback for failed descriptor bind
      +    @GenerateInline
      +    @GenerateCached(false)
      +    @GenerateUncached
      +    public abstract static class CallSlotReprNode extends Node {
      +        private static final CApiTiming C_API_TIMING = CApiTiming.create(true, "repr");
      +
      +        public abstract Object execute(VirtualFrame frame, Node inliningTarget, TpSlot slot, Object self);
      +
      +        @Specialization(guards = "cachedSlot == slot", limit = "3")
      +        static Object callCachedBuiltin(VirtualFrame frame, @SuppressWarnings("unused") TpSlotUnaryFuncBuiltin slot, Object self,
      +                        @SuppressWarnings("unused") @Cached("slot") TpSlotUnaryFuncBuiltin cachedSlot,
      +                        @Cached("cachedSlot.createSlotNode()") PythonUnaryBuiltinNode slotNode) {
      +            return slotNode.execute(frame, self);
      +        }
      +
      +        @Specialization
      +        static Object callPython(VirtualFrame frame, TpSlotPythonSingle slot, Object self,
      +                        @Cached(inline = false) CallSlotReprPythonNode callSlotNode) {
      +            return callSlotNode.execute(frame, slot, self);
      +        }
      +
      +        @Specialization
      +        static Object callNative(VirtualFrame frame, Node inliningTarget, TpSlotCExtNative slot, Object self,
      +                        @Cached GetThreadStateNode getThreadStateNode,
      +                        @Cached(inline = false) PythonToNativeNode toNativeNode,
      +                        @Cached ExternalFunctionInvokeNode externalInvokeNode,
      +                        @Cached(inline = false) NativeToPythonTransferNode toPythonNode,
      +                        @Cached(inline = false) PyObjectCheckFunctionResultNode checkResultNode) {
      +            PythonThreadState state = getThreadStateNode.execute(inliningTarget);
      +            Object result = externalInvokeNode.call(frame, inliningTarget, state, C_API_TIMING, T___REPR__, slot.callable,
      +                            toNativeNode.execute(self));
      +            return checkResultNode.execute(state, T___REPR__, toPythonNode.execute(result));
      +        }
      +
      +        @Specialization(replaces = "callCachedBuiltin")
      +        @InliningCutoff
      +        static Object callGenericBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotUnaryFuncBuiltin slot, Object self,
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
      +            Object[] arguments = PArguments.create(1);
      +            PArguments.setArgument(arguments, 0, self);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            return invoke.execute(frame, inliningTarget, callTarget, arguments);
      +        }
      +    }
      +
      +    @GenerateUncached
      +    @GenerateInline(false) // intentionally lazy
      +    abstract static class CallSlotReprPythonNode extends Node {
      +        abstract Object execute(VirtualFrame frame, TpSlotPythonSingle slot, Object obj);
      +
      +        @Specialization
      +        static Object doIt(VirtualFrame frame, TpSlotPythonSingle slot, Object self,
      +                        @Bind("this") Node inliningTarget,
      +                        @Cached ReprPythonSlotDispatcherNode dispatcherNode) {
      +            return dispatcherNode.execute(frame, inliningTarget, slot.getCallable(), slot.getType(), self);
      +        }
      +    }
      +
      +    @GenerateUncached
      +    @GenerateInline
      +    @GenerateCached(false)
      +    @ImportStatic(CallDispatchers.class)
      +    abstract static class ReprPythonSlotDispatcherNode extends PythonDispatchers.PythonSlotDispatcherNodeBase {
      +        final Object execute(VirtualFrame frame, Node inliningTarget, Object callable, Object type, Object self) {
      +            assert !(callable instanceof TruffleWeakReference);
      +            assert !(type instanceof TruffleWeakReference);
      +            return executeImpl(frame, inliningTarget, callable, type, self);
      +        }
      +
      +        abstract Object executeImpl(VirtualFrame frame, Node inliningTarget, Object callable, Object type, Object self);
      +
      +        @Specialization(guards = {"isSingleContext()", "callee == cachedCallee", "isSimpleSignature(cachedCallee, 1)"}, //
      +                        limit = "getCallSiteInlineCacheMaxDepth()", assumptions = "cachedCallee.getCodeStableAssumption()")
      +        protected static Object doCachedPFunction(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") PFunction callee, @SuppressWarnings("unused") Object type, Object self,
      +                        @SuppressWarnings("unused") @Cached("callee") PFunction cachedCallee,
      +                        @Cached("createDirectCallNodeFor(callee)") DirectCallNode callNode,
      +                        @Cached CallDispatchers.FunctionDirectInvokeNode invoke) {
      +            Object[] arguments = PArguments.create(1);
      +            PArguments.setArgument(arguments, 0, self);
      +            return invoke.execute(frame, inliningTarget, callNode, cachedCallee, arguments);
      +        }
      +
      +        @Specialization(replaces = "doCachedPFunction")
      +        @InliningCutoff
      +        static Object doGeneric(VirtualFrame frame, Node inliningTarget, Object callableObj, Object type, Object self,
      +                        @Cached MaybeBindDescriptorNode bindDescriptorNode,
      +                        @Cached(inline = false) CallNode callNode,
      +                        @Cached(inline = false) ObjectNodes.DefaultObjectReprNode defaultRepr) {
      +            Object bound;
      +            try {
      +                bound = bindDescriptorNode.execute(frame, inliningTarget, callableObj, self, type);
      +            } catch (AbstractTruffleException e) {
      +                return defaultRepr.executeCached(frame, self);
      +            }
      +            Object[] arguments;
      +            Object callable;
      +            if (bound instanceof BoundDescriptor boundDescr) {
      +                callable = boundDescr.descriptor;
      +                arguments = PythonUtils.EMPTY_OBJECT_ARRAY;
      +            } else {
      +                callable = bound;
      +                arguments = new Object[]{self};
      +            }
      +            return callNode.execute(frame, callable, arguments);
      +        }
      +    }
      +}
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotRichCompare.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotRichCompare.java
      new file mode 100644
      index 0000000000..6b05f997b9
      --- /dev/null
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotRichCompare.java
      @@ -0,0 +1,274 @@
      +/*
      + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
      + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      + *
      + * The Universal Permissive License (UPL), Version 1.0
      + *
      + * Subject to the condition set forth below, permission is hereby granted to any
      + * person obtaining a copy of this software, associated documentation and/or
      + * data (collectively the "Software"), free of charge and under any and all
      + * copyright rights in the Software, and any and all patent rights owned or
      + * freely licensable by each licensor hereunder covering either (i) the
      + * unmodified Software as contributed to or provided by such licensor, or (ii)
      + * the Larger Works (as defined below), to deal in both
      + *
      + * (a) the Software, and
      + *
      + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
      + * one is included with the Software each a "Larger Work" to which the Software
      + * is contributed by such licensors),
      + *
      + * without restriction, including without limitation the rights to copy, create
      + * derivative works of, display, perform, and distribute the Software and make,
      + * use, sell, offer for sale, import, export, have made, and have sold the
      + * Software and the Larger Work(s), and to sublicense the foregoing rights on
      + * either these or other terms.
      + *
      + * This license is subject to the following condition:
      + *
      + * The above copyright notice and either this complete permission notice or at a
      + * minimum a reference to the UPL must be included in all copies or substantial
      + * portions of the Software.
      + *
      + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      + * SOFTWARE.
      + */
      +package com.oracle.graal.python.builtins.objects.type.slots;
      +
      +import static com.oracle.graal.python.builtins.objects.type.slots.BuiltinSlotWrapperSignature.J_DOLLAR_SELF;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.J_TP_RICHCOMPARE;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T_TP_RICHCOMPARE;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___HASH__;
      +import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
      +
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.builtins.Python3Core;
      +import com.oracle.graal.python.builtins.objects.PNotImplemented;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.ExternalFunctionInvokeNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PyObjectCheckFunctionResultNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonTransferNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode;
      +import com.oracle.graal.python.builtins.objects.function.PArguments;
      +import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
      +import com.oracle.graal.python.builtins.objects.type.slots.NodeFactoryUtils.WrapperNodeFactory;
      +import com.oracle.graal.python.builtins.objects.type.slots.PythonDispatchers.BinaryPythonSlotDispatcherNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotBuiltinBase;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotCExtNative;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPython;
      +import com.oracle.graal.python.lib.RichCmpOp;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
      +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
      +import com.oracle.graal.python.runtime.PythonContext;
      +import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
      +import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
      +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
      +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
      +import com.oracle.truffle.api.RootCallTarget;
      +import com.oracle.truffle.api.dsl.Cached;
      +import com.oracle.truffle.api.dsl.Cached.Exclusive;
      +import com.oracle.truffle.api.dsl.GenerateCached;
      +import com.oracle.truffle.api.dsl.GenerateInline;
      +import com.oracle.truffle.api.dsl.GenerateUncached;
      +import com.oracle.truffle.api.dsl.NodeFactory;
      +import com.oracle.truffle.api.dsl.Specialization;
      +import com.oracle.truffle.api.frame.VirtualFrame;
      +import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.InlinedBranchProfile;
      +import com.oracle.truffle.api.strings.TruffleString;
      +import com.oracle.truffle.api.utilities.TruffleWeakReference;
      +
      +public abstract class TpSlotRichCompare {
      +
      +    private TpSlotRichCompare() {
      +    }
      +
      +    public abstract static sealed class TpSlotRichCmpBuiltin
      +                    extends TpSlotBuiltinBase permits TpSlotRichCmpBuiltinSimple, TpSlotRichCmpBuiltinComplex {
      +        static final BuiltinSlotWrapperSignature SIGNATURE = BuiltinSlotWrapperSignature.of(J_DOLLAR_SELF, "other", "op");
      +
      +        protected TpSlotRichCmpBuiltin(NodeFactory nodeFactory) {
      +            super(nodeFactory, SIGNATURE, PExternalFunctionWrapper.BINARYFUNC);
      +        }
      +
      +        final RichCmpBuiltinNode createSlotNode() {
      +            return createNode();
      +        }
      +
      +        @Override
      +        public PBuiltinFunction createBuiltin(Python3Core core, Object type, TruffleString tsName, PExternalFunctionWrapper wrapper) {
      +            RichCmpOp op = RichCmpOp.fromName(tsName);
      +            assert op != null : "Unexpected richcmp name: " + tsName.toJavaStringUncached();
      +            var factory = WrapperNodeFactory.wrap(getNodeFactory(), RichCmpWrapperNode.class, n -> new RichCmpWrapperNode(op, n));
      +            return createBuiltin(core, type, tsName, BuiltinSlotWrapperSignature.BINARY, wrapper, factory);
      +        }
      +    }
      +
      +    public abstract static non-sealed class TpSlotRichCmpBuiltinSimple extends TpSlotRichCmpBuiltin {
      +        protected TpSlotRichCmpBuiltinSimple(NodeFactory nodeFactory) {
      +            super(nodeFactory);
      +        }
      +
      +        protected abstract Object executeUncached(Object a, Object b, RichCmpOp op);
      +
      +        @Override
      +        public final void initialize(PythonLanguage language) {
      +            // nop: we do not need a call target
      +        }
      +    }
      +
      +    public abstract static non-sealed class TpSlotRichCmpBuiltinComplex extends TpSlotRichCmpBuiltin {
      +        private final int callTargetIndex = TpSlotBuiltinCallTargetRegistry.getNextCallTargetIndex();
      +
      +        protected TpSlotRichCmpBuiltinComplex(NodeFactory nodeFactory) {
      +            super(nodeFactory);
      +        }
      +
      +        @Override
      +        public final void initialize(PythonLanguage language) {
      +            RootCallTarget callTarget = createSlotCallTarget(language, SIGNATURE, getNodeFactory(), "tp_richcompare");
      +            language.setBuiltinSlotCallTarget(callTargetIndex, callTarget);
      +        }
      +    }
      +
      +    @GenerateInline(value = false, inherit = true)
      +    public abstract static class RichCmpBuiltinNode extends PythonTernaryBuiltinNode {
      +        @Override
      +        public final Object execute(VirtualFrame frame, Object arg, Object arg2, Object arg3) {
      +            return execute(frame, arg, arg2, (RichCmpOp) arg3);
      +        }
      +
      +        public abstract Object execute(VirtualFrame frame, Object a, Object b, RichCmpOp op);
      +    }
      +
      +    public static final class RichCmpWrapperNode extends PythonBinaryBuiltinNode {
      +        private final RichCmpOp op;
      +        @Child RichCmpBuiltinNode slotNode;
      +
      +        public RichCmpWrapperNode(RichCmpOp op, RichCmpBuiltinNode slotNode) {
      +            this.op = op;
      +            this.slotNode = slotNode;
      +        }
      +
      +        @Override
      +        public Object execute(VirtualFrame frame, Object arg, Object arg2) {
      +            return slotNode.execute(frame, arg, arg2, op);
      +        }
      +    }
      +
      +    public static final class TpSlotRichCmpPython extends TpSlotPython {
      +        private final TruffleWeakReference lt;
      +        private final TruffleWeakReference le;
      +        private final TruffleWeakReference eq;
      +        private final TruffleWeakReference ne;
      +        private final TruffleWeakReference gt;
      +        private final TruffleWeakReference ge;
      +        private final TruffleWeakReference type;
      +
      +        public TpSlotRichCmpPython(Object type, Object lt, Object le, Object eq, Object ne, Object gt, Object ge) {
      +            this.type = asWeakRef(type);
      +            this.lt = asWeakRef(lt);
      +            this.le = asWeakRef(le);
      +            this.eq = asWeakRef(eq);
      +            this.ne = asWeakRef(ne);
      +            this.gt = asWeakRef(gt);
      +            this.ge = asWeakRef(ge);
      +        }
      +
      +        public static TpSlotRichCmpPython create(Object[] callables, TruffleString[] callableNames, Object type) {
      +            assert callables.length == RichCmpOp.VALUES.length;
      +            assert callableNames == null || checkCallableNames(callableNames);
      +            return new TpSlotRichCmpPython(type, callables[0], callables[1], callables[2], callables[3], callables[4], callables[5]);
      +        }
      +
      +        private static boolean checkCallableNames(TruffleString[] callableNames) {
      +            for (int i = 0; i < RichCmpOp.VALUES.length; i++) {
      +                assert RichCmpOp.VALUES[i].getPythonName().equalsUncached(callableNames[i], TS_ENCODING);
      +            }
      +            return true;
      +        }
      +
      +        @Override
      +        public TpSlotPython forNewType(Object klass) {
      +            return new TpSlotRichCmpPython(type.get(), lt.get(), le.get(), eq.get(), ne.get(), gt.get(), ge.get());
      +        }
      +    }
      +
      +    @GenerateInline
      +    @GenerateCached(false)
      +    @GenerateUncached
      +    public abstract static class CallSlotRichCmpNode extends Node {
      +        private static final CApiTiming C_API_TIMING = CApiTiming.create(true, J_TP_RICHCOMPARE);
      +
      +        public abstract Object execute(VirtualFrame frame, Node inliningTarget, TpSlot slot, Object a, Object b, RichCmpOp op);
      +
      +        @Specialization(guards = "cachedSlot == slot", limit = "3")
      +        static Object callCachedBuiltin(VirtualFrame frame, @SuppressWarnings("unused") TpSlotRichCmpBuiltin slot, Object a, Object b, RichCmpOp op,
      +                        @SuppressWarnings("unused") @Cached("slot") TpSlotRichCmpBuiltin cachedSlot,
      +                        @Cached("cachedSlot.createSlotNode()") RichCmpBuiltinNode slotNode) {
      +            return slotNode.execute(frame, a, b, op);
      +        }
      +
      +        @Specialization
      +        static Object callPython(VirtualFrame frame, Node inliningTarget, TpSlotRichCmpPython slot, Object a, Object b, RichCmpOp op,
      +                        @Cached BinaryPythonSlotDispatcherNode dispatcher,
      +                        @Cached InlinedBranchProfile notImplementedProfile) {
      +            TruffleWeakReference callableRef = switch (op) {
      +                case Py_LT -> slot.lt;
      +                case Py_LE -> slot.le;
      +                case Py_EQ -> slot.eq;
      +                case Py_NE -> slot.ne;
      +                case Py_GT -> slot.gt;
      +                case Py_GE -> slot.ge;
      +            };
      +            Object callable = slot.safeGet(callableRef);
      +            Object type = slot.safeGet(slot.type);
      +            if (callable != null && type != null) {
      +                return dispatcher.executeIgnoreDescriptorBindErrors(frame, inliningTarget, callable, type, a, b);
      +            } else {
      +                notImplementedProfile.enter(inliningTarget);
      +                return PNotImplemented.NOT_IMPLEMENTED;
      +            }
      +        }
      +
      +        @Specialization
      +        static Object callNative(VirtualFrame frame, Node inliningTarget, TpSlotCExtNative slot, Object a, Object b, RichCmpOp op,
      +                        @Exclusive @Cached GetThreadStateNode getThreadStateNode,
      +                        @Cached(inline = false) PythonToNativeNode toNativeNodeA,
      +                        @Cached(inline = false) PythonToNativeNode toNativeNodeB,
      +                        @Exclusive @Cached ExternalFunctionInvokeNode externalInvokeNode,
      +                        @Exclusive @Cached(inline = false) NativeToPythonTransferNode toPythonNode,
      +                        @Exclusive @Cached(inline = false) PyObjectCheckFunctionResultNode checkResultNode) {
      +            PythonContext ctx = PythonContext.get(inliningTarget);
      +            PythonThreadState state = getThreadStateNode.execute(inliningTarget, ctx);
      +            Object result = externalInvokeNode.call(frame, inliningTarget, state, C_API_TIMING, T_TP_RICHCOMPARE, slot.callable, toNativeNodeA.execute(a), toNativeNodeB.execute(b),
      +                            op.asNative());
      +            return checkResultNode.execute(state, T___HASH__, toPythonNode.execute(result));
      +        }
      +
      +        @Specialization(replaces = "callCachedBuiltin")
      +        @TruffleBoundary
      +        static Object callGenericSimpleBuiltin(TpSlotRichCmpBuiltinSimple slot, Object a, Object b, RichCmpOp op) {
      +            return slot.executeUncached(a, b, op);
      +        }
      +
      +        @Specialization(replaces = "callCachedBuiltin")
      +        @InliningCutoff
      +        static Object callGenericComplexBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotRichCmpBuiltinComplex slot, Object a, Object b, RichCmpOp op,
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
      +            Object[] arguments = PArguments.create(3);
      +            PArguments.setArgument(arguments, 0, a);
      +            PArguments.setArgument(arguments, 1, b);
      +            PArguments.setArgument(arguments, 2, op);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            return invoke.execute(frame, inliningTarget, callTarget, arguments);
      +        }
      +    }
      +}
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSetAttr.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSetAttr.java
      index 910745cf17..6163b212d3 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSetAttr.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSetAttr.java
      @@ -70,8 +70,8 @@
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode.Dynamic;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
       import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
      -import com.oracle.graal.python.runtime.ExecutionContext.CallContext;
       import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
       import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
       import com.oracle.graal.python.runtime.exception.PException;
      @@ -87,7 +87,6 @@
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      -import com.oracle.truffle.api.nodes.IndirectCallNode;
       import com.oracle.truffle.api.nodes.Node;
       import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
      @@ -115,7 +114,7 @@ final SetAttrBuiltinNode createSlotNode() {
       
               @Override
               public void initialize(PythonLanguage language) {
      -            RootCallTarget target = createBuiltinCallTarget(language, SET_SIGNATURE, getNodeFactory(), J___SETATTR__);
      +            RootCallTarget target = createSlotCallTarget(language, SET_SIGNATURE, getNodeFactory(), J___SETATTR__);
                   language.setBuiltinSlotCallTarget(callTargetIndex, target);
               }
       
      @@ -318,7 +317,7 @@ static void callCachedBuiltin(VirtualFrame frame, @SuppressWarnings("unused") Tp
       
               @Specialization(guards = "!isNoValue(value)")
               static void callPythonSimpleSet(VirtualFrame frame, Node inliningTarget, TpSlotSetAttrPython slot, Object self, Object name, Object value,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode,
      +                        @Exclusive @Cached PRaiseNode raiseNode,
                               @Cached TernaryPythonSlotDispatcherNode callPythonFun) {
                   Object callable = slot.getSetattr();
                   if (callable == null) {
      @@ -330,7 +329,7 @@ static void callPythonSimpleSet(VirtualFrame frame, Node inliningTarget, TpSlotS
               @Specialization(guards = "isNoValue(value)")
               @InliningCutoff
               static void callPythonSimpleDel(VirtualFrame frame, Node inliningTarget, TpSlotSetAttrPython slot, Object self, Object name, @SuppressWarnings("unused") Object value,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode,
      +                        @Exclusive @Cached PRaiseNode raiseNode,
                               @Cached BinaryPythonSlotDispatcherNode callPythonFun) {
                   Object callable = slot.getDelattr();
                   if (callable == null) {
      @@ -340,21 +339,20 @@ static void callPythonSimpleDel(VirtualFrame frame, Node inliningTarget, TpSlotS
               }
       
               @InliningCutoff
      -        private static PException raiseAttributeError(Node inliningTarget, PRaiseNode.Lazy raiseNode, TruffleString attrName) {
      -            return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.AttributeError, attrName);
      +        private static PException raiseAttributeError(Node inliningTarget, PRaiseNode raiseNode, TruffleString attrName) {
      +            return raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, attrName);
               }
       
               @Specialization(replaces = "callCachedBuiltin")
               @InliningCutoff
               static void callGenericBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotSetAttrBuiltin slot, Object self, Object name, Object value,
      -                        @Cached(inline = false) CallContext callContext,
      -                        @Cached InlinedConditionProfile isNullFrameProfile,
      -                        @Cached(inline = false) IndirectCallNode indirectCallNode) {
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
                   Object[] arguments = PArguments.create(3);
                   PArguments.setArgument(arguments, 0, self);
                   PArguments.setArgument(arguments, 1, name);
                   PArguments.setArgument(arguments, 2, value);
      -            BuiltinDispatchers.callGenericBuiltin(frame, inliningTarget, slot.callTargetIndex, arguments, callContext, isNullFrameProfile, indirectCallNode);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            invoke.execute(frame, inliningTarget, callTarget, arguments);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSizeArgFun.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSizeArgFun.java
      index 59685c5755..cfd58eb67f 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSizeArgFun.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSizeArgFun.java
      @@ -40,7 +40,6 @@
        */
       package com.oracle.graal.python.builtins.objects.type.slots;
       
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GETITEM__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETITEM__;
       
       import java.util.Objects;
      @@ -54,8 +53,6 @@
       import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming;
       import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonTransferNode;
       import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode;
      -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsHandleNode;
      -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsPythonObjectNode;
       import com.oracle.graal.python.builtins.objects.function.PArguments;
       import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
       import com.oracle.graal.python.builtins.objects.type.TpSlots;
      @@ -64,15 +61,14 @@
       import com.oracle.graal.python.builtins.objects.type.slots.PythonDispatchers.BinaryPythonSlotDispatcherNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotBuiltin;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotCExtNative;
      -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotHPyNative;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPythonSingle;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.CallSlotLenNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFunFactory.FixNegativeIndexNodeGen;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFunFactory.WrapIndexArgFuncBuiltinNodeGen;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFunFactory.WrapSqItemBuiltinNodeGen;
       import com.oracle.graal.python.lib.PyNumberAsSizeNode;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      -import com.oracle.graal.python.runtime.ExecutionContext.CallContext;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
       import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
      @@ -89,9 +85,7 @@
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      -import com.oracle.truffle.api.nodes.IndirectCallNode;
       import com.oracle.truffle.api.nodes.Node;
      -import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       
       public class TpSlotSizeArgFun {
      @@ -100,9 +94,11 @@ private TpSlotSizeArgFun() {
       
           public abstract static class TpSlotSizeArgFunBuiltin extends TpSlotBuiltin {
               private final int callTargetIndex = TpSlotBuiltinCallTargetRegistry.getNextCallTargetIndex();
      +        private final String name;
       
      -        protected TpSlotSizeArgFunBuiltin(NodeFactory nodeFactory) {
      +        protected TpSlotSizeArgFunBuiltin(NodeFactory nodeFactory, String name) {
                   super(nodeFactory);
      +            this.name = name;
               }
       
               final SizeArgFunBuiltinNode createSlotNode() {
      @@ -111,7 +107,7 @@ final SizeArgFunBuiltinNode createSlotNode() {
       
               @Override
               public void initialize(PythonLanguage language) {
      -            RootCallTarget target = createBuiltinCallTarget(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), J___GETITEM__);
      +            RootCallTarget target = createSlotCallTarget(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), name);
                   language.setBuiltinSlotCallTarget(callTargetIndex, target);
               }
       
      @@ -266,31 +262,15 @@ static Object callNative(VirtualFrame frame, Node inliningTarget, TpSlotCExtNati
                   return checkResultNode.execute(threadState, T___GETITEM__, toPythonNode.execute(result));
               }
       
      -        @Specialization
      -        @InliningCutoff
      -        static Object callHPy(VirtualFrame frame, Node inliningTarget, TpSlotHPyNative slot, Object self, int index,
      -                        @Exclusive @Cached GetThreadStateNode getThreadStateNode,
      -                        @Cached(inline = false) HPyAsHandleNode toNativeNode,
      -                        @Exclusive @Cached ExternalFunctionInvokeNode externalInvokeNode,
      -                        @Cached(inline = false) HPyAsPythonObjectNode toPythonNode,
      -                        @Exclusive @Cached(inline = false) PyObjectCheckFunctionResultNode checkResultNode) {
      -            PythonContext ctx = PythonContext.get(inliningTarget);
      -            PythonThreadState threadState = getThreadStateNode.execute(inliningTarget, ctx);
      -            Object result = externalInvokeNode.call(frame, inliningTarget, threadState, C_API_TIMING, T___GETITEM__, slot.callable, ctx.getHPyContext().getBackend(), toNativeNode.execute(self),
      -                            (long) index);
      -            return checkResultNode.execute(threadState, T___GETITEM__, toPythonNode.execute(result));
      -        }
      -
               @Specialization(replaces = "callCachedBuiltin")
               @InliningCutoff
               static Object callGenericBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotSizeArgFunBuiltin slot, Object self, int index,
      -                        @Cached(inline = false) CallContext callContext,
      -                        @Cached InlinedConditionProfile isNullFrameProfile,
      -                        @Cached(inline = false) IndirectCallNode indirectCallNode) {
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
                   Object[] arguments = PArguments.create(2);
                   PArguments.setArgument(arguments, 0, self);
                   PArguments.setArgument(arguments, 1, index);
      -            return BuiltinDispatchers.callGenericBuiltin(frame, inliningTarget, slot.callTargetIndex, arguments, callContext, isNullFrameProfile, indirectCallNode);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            return invoke.execute(frame, inliningTarget, callTarget, arguments);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSqAssItem.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSqAssItem.java
      index 02e951b321..2da698a4a5 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSqAssItem.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSqAssItem.java
      @@ -72,9 +72,9 @@
       import com.oracle.graal.python.nodes.PGuards;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
      -import com.oracle.graal.python.runtime.ExecutionContext.CallContext;
       import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
       import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
       import com.oracle.graal.python.runtime.exception.PException;
      @@ -91,9 +91,7 @@
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      -import com.oracle.truffle.api.nodes.IndirectCallNode;
       import com.oracle.truffle.api.nodes.Node;
      -import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       import com.oracle.truffle.api.utilities.TruffleWeakReference;
       
      @@ -115,7 +113,7 @@ final SqAssItemBuiltinNode createSlotNode() {
       
               @Override
               public void initialize(PythonLanguage language) {
      -            RootCallTarget target = createBuiltinCallTarget(language, SET_SIGNATURE, getNodeFactory(), J___SETITEM__);
      +            RootCallTarget target = createSlotCallTarget(language, SET_SIGNATURE, getNodeFactory(), J___SETITEM__);
                   language.setBuiltinSlotCallTarget(callTargetIndex, target);
               }
       
      @@ -314,7 +312,7 @@ static void callCachedBuiltin(VirtualFrame frame, @SuppressWarnings("unused") Tp
       
               @Specialization(guards = "!isNoValue(value)")
               static void callPythonSimpleSet(VirtualFrame frame, Node inliningTarget, TpSlotSqAssItemPython slot, Object self, int key, Object value,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode,
      +                        @Exclusive @Cached PRaiseNode raiseNode,
                               @Cached TernaryPythonSlotDispatcherNode callPythonFun) {
                   Object callable = slot.getSetitem();
                   if (callable == null) {
      @@ -326,7 +324,7 @@ static void callPythonSimpleSet(VirtualFrame frame, Node inliningTarget, TpSlotS
               @Specialization(guards = "isNoValue(value)")
               @InliningCutoff
               static void callPythonSimpleDel(VirtualFrame frame, Node inliningTarget, TpSlotSqAssItemPython slot, Object self, int key, @SuppressWarnings("unused") Object value,
      -                        @Exclusive @Cached PRaiseNode.Lazy raiseNode,
      +                        @Exclusive @Cached PRaiseNode raiseNode,
                               @Cached BinaryPythonSlotDispatcherNode callPythonFun) {
                   Object callable = slot.getDelitem();
                   if (callable == null) {
      @@ -336,21 +334,20 @@ static void callPythonSimpleDel(VirtualFrame frame, Node inliningTarget, TpSlotS
               }
       
               @InliningCutoff
      -        private static PException raiseAttributeError(Node inliningTarget, PRaiseNode.Lazy raiseNode, TruffleString attrName) {
      -            return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.AttributeError, attrName);
      +        private static PException raiseAttributeError(Node inliningTarget, PRaiseNode raiseNode, TruffleString attrName) {
      +            return raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, attrName);
               }
       
               @Specialization(replaces = "callCachedBuiltin")
               @InliningCutoff
               static void callGenericBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotSqAssItemBuiltin slot, Object self, int key, Object value,
      -                        @Cached(inline = false) CallContext callContext,
      -                        @Cached InlinedConditionProfile isNullFrameProfile,
      -                        @Cached(inline = false) IndirectCallNode indirectCallNode) {
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
                   Object[] arguments = PArguments.create(3);
                   PArguments.setArgument(arguments, 0, self);
                   PArguments.setArgument(arguments, 1, key);
                   PArguments.setArgument(arguments, 2, value);
      -            BuiltinDispatchers.callGenericBuiltin(frame, inliningTarget, slot.callTargetIndex, arguments, callContext, isNullFrameProfile, indirectCallNode);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            invoke.execute(frame, inliningTarget, callTarget, arguments);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSqContains.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSqContains.java
      new file mode 100644
      index 0000000000..9a6fba5593
      --- /dev/null
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSqContains.java
      @@ -0,0 +1,155 @@
      +/*
      + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
      + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      + *
      + * The Universal Permissive License (UPL), Version 1.0
      + *
      + * Subject to the condition set forth below, permission is hereby granted to any
      + * person obtaining a copy of this software, associated documentation and/or
      + * data (collectively the "Software"), free of charge and under any and all
      + * copyright rights in the Software, and any and all patent rights owned or
      + * freely licensable by each licensor hereunder covering either (i) the
      + * unmodified Software as contributed to or provided by such licensor, or (ii)
      + * the Larger Works (as defined below), to deal in both
      + *
      + * (a) the Software, and
      + *
      + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
      + * one is included with the Software each a "Larger Work" to which the Software
      + * is contributed by such licensors),
      + *
      + * without restriction, including without limitation the rights to copy, create
      + * derivative works of, display, perform, and distribute the Software and make,
      + * use, sell, offer for sale, import, export, have made, and have sold the
      + * Software and the Larger Work(s), and to sublicense the foregoing rights on
      + * either these or other terms.
      + *
      + * This license is subject to the following condition:
      + *
      + * The above copyright notice and either this complete permission notice or at a
      + * minimum a reference to the UPL must be included in all copies or substantial
      + * portions of the Software.
      + *
      + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      + * SOFTWARE.
      + */
      +package com.oracle.graal.python.builtins.objects.type.slots;
      +
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CONTAINS__;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___CONTAINS__;
      +
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      +import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.CheckInquiryResultNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.ExternalFunctionInvokeNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode;
      +import com.oracle.graal.python.builtins.objects.function.PArguments;
      +import com.oracle.graal.python.builtins.objects.type.slots.PythonDispatchers.BinaryPythonSlotDispatcherNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotCExtNative;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPythonSingle;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.TpSlotBinaryFuncBuiltin;
      +import com.oracle.graal.python.lib.PyObjectIsTrueNode;
      +import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.PRaiseNode;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
      +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      +import com.oracle.graal.python.runtime.PythonContext;
      +import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
      +import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
      +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
      +import com.oracle.truffle.api.RootCallTarget;
      +import com.oracle.truffle.api.dsl.Cached;
      +import com.oracle.truffle.api.dsl.GenerateCached;
      +import com.oracle.truffle.api.dsl.GenerateInline;
      +import com.oracle.truffle.api.dsl.GenerateUncached;
      +import com.oracle.truffle.api.dsl.NodeFactory;
      +import com.oracle.truffle.api.dsl.Specialization;
      +import com.oracle.truffle.api.frame.VirtualFrame;
      +import com.oracle.truffle.api.nodes.Node;
      +
      +public final class TpSlotSqContains {
      +    private TpSlotSqContains() {
      +    }
      +
      +    public abstract static class TpSlotSqContainsBuiltin extends TpSlotBinaryFuncBuiltin {
      +
      +        protected TpSlotSqContainsBuiltin(NodeFactory nodeFactory) {
      +            super(nodeFactory, PExternalFunctionWrapper.OBJOBJPROC, J___CONTAINS__);
      +        }
      +
      +        final SqContainsBuiltinNode createOpSlotNode() {
      +            return createNode();
      +        }
      +    }
      +
      +    @GenerateInline(value = false, inherit = true)
      +    public abstract static class SqContainsBuiltinNode extends PythonBinaryBuiltinNode {
      +        public abstract boolean executeBoolean(VirtualFrame frame, Object obj, Object value);
      +
      +        @Override
      +        public final Object execute(VirtualFrame frame, Object obj, Object value) {
      +            return executeBoolean(frame, obj, value);
      +        }
      +    }
      +
      +    @GenerateInline
      +    @GenerateCached(false)
      +    @GenerateUncached
      +    public abstract static class CallSlotSqContainsNode extends Node {
      +        private static final CApiTiming C_API_TIMING = CApiTiming.create(true, "sq_contains");
      +
      +        public abstract boolean execute(VirtualFrame frame, Node inliningTarget, TpSlot slot, Object self, Object arg);
      +
      +        @Specialization(guards = "cachedSlot == slot", limit = "3")
      +        static boolean callCachedBuiltin(VirtualFrame frame, @SuppressWarnings("unused") TpSlotSqContainsBuiltin slot, Object self, Object arg,
      +                        @SuppressWarnings("unused") @Cached("slot") TpSlotSqContainsBuiltin cachedSlot,
      +                        @Cached("cachedSlot.createOpSlotNode()") SqContainsBuiltinNode slotNode) {
      +            return slotNode.executeBoolean(frame, self, arg);
      +        }
      +
      +        @Specialization
      +        static boolean callPython(VirtualFrame frame, Node inliningTarget, TpSlotPythonSingle slot, Object self, Object arg,
      +                        @Cached BinaryPythonSlotDispatcherNode dispatcherNode,
      +                        @Cached PyObjectIsTrueNode isTrueNode,
      +                        @Cached PRaiseNode raiseNode) {
      +            if (slot.getCallable() == PNone.NONE) {
      +                throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.IS_NOT_A_CONTAINER, self);
      +            }
      +            Object result = dispatcherNode.execute(frame, inliningTarget, slot.getCallable(), slot.getType(), self, arg);
      +            return isTrueNode.execute(frame, result);
      +        }
      +
      +        @Specialization
      +        static boolean callNative(VirtualFrame frame, Node inliningTarget, TpSlotCExtNative slot, Object self, Object arg,
      +                        @Cached GetThreadStateNode getThreadStateNode,
      +                        @Cached(inline = false) PythonToNativeNode selfToNativeNode,
      +                        @Cached(inline = false) PythonToNativeNode argToNativeNode,
      +                        @Cached ExternalFunctionInvokeNode externalInvokeNode,
      +                        @Cached(inline = false) CheckInquiryResultNode checkResultNode) {
      +            PythonContext ctx = PythonContext.get(inliningTarget);
      +            PythonThreadState state = getThreadStateNode.execute(inliningTarget, ctx);
      +            Object result = externalInvokeNode.call(frame, inliningTarget, state, C_API_TIMING, T___CONTAINS__, slot.callable,
      +                            selfToNativeNode.execute(self), argToNativeNode.execute(arg));
      +            return checkResultNode.executeBool(state, T___CONTAINS__, result);
      +        }
      +
      +        @Specialization(replaces = "callCachedBuiltin")
      +        @InliningCutoff
      +        static boolean callGenericComplexBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotBinaryFuncBuiltin slot, Object self, Object arg,
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
      +            Object[] arguments = PArguments.create(2);
      +            PArguments.setArgument(arguments, 0, self);
      +            PArguments.setArgument(arguments, 1, arg);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            return (boolean) invoke.execute(frame, inliningTarget, callTarget, arguments);
      +        }
      +    }
      +}
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotUnaryFunc.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotUnaryFunc.java
      index 53586fce99..046e1cf601 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotUnaryFunc.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotUnaryFunc.java
      @@ -54,8 +54,8 @@
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotBuiltinBase;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotCExtNative;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPythonSingle;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      -import com.oracle.graal.python.runtime.ExecutionContext.CallContext;
       import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
       import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
       import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
      @@ -68,9 +68,7 @@
       import com.oracle.truffle.api.dsl.NodeFactory;
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
      -import com.oracle.truffle.api.nodes.IndirectCallNode;
       import com.oracle.truffle.api.nodes.Node;
      -import com.oracle.truffle.api.profiles.InlinedConditionProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       
       public final class TpSlotUnaryFunc {
      @@ -92,7 +90,7 @@ final PythonUnaryBuiltinNode createSlotNode() {
       
               @Override
               public final void initialize(PythonLanguage language) {
      -            RootCallTarget callTarget = createBuiltinCallTarget(language, BuiltinSlotWrapperSignature.UNARY, getNodeFactory(), builtinName);
      +            RootCallTarget callTarget = createSlotCallTarget(language, BuiltinSlotWrapperSignature.UNARY, getNodeFactory(), builtinName);
                   language.setBuiltinSlotCallTarget(callTargetIndex, callTarget);
               }
           }
      @@ -135,12 +133,11 @@ static Object callNative(VirtualFrame frame, Node inliningTarget, TpSlotCExtNati
               @Specialization(replaces = "callCachedBuiltin")
               @InliningCutoff
               static Object callGenericBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotUnaryFuncBuiltin slot, Object self,
      -                        @Cached(inline = false) CallContext callContext,
      -                        @Cached InlinedConditionProfile isNullFrameProfile,
      -                        @Cached(inline = false) IndirectCallNode indirectCallNode) {
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
                   Object[] arguments = PArguments.create(1);
                   PArguments.setArgument(arguments, 0, self);
      -            return BuiltinDispatchers.callGenericBuiltin(frame, inliningTarget, slot.callTargetIndex, arguments, callContext, isNullFrameProfile, indirectCallNode);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            return invoke.execute(frame, inliningTarget, callTarget, arguments);
               }
           }
       
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotVarargs.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotVarargs.java
      new file mode 100644
      index 0000000000..f4fec1cf7f
      --- /dev/null
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotVarargs.java
      @@ -0,0 +1,445 @@
      +/*
      + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
      + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      + *
      + * The Universal Permissive License (UPL), Version 1.0
      + *
      + * Subject to the condition set forth below, permission is hereby granted to any
      + * person obtaining a copy of this software, associated documentation and/or
      + * data (collectively the "Software"), free of charge and under any and all
      + * copyright rights in the Software, and any and all patent rights owned or
      + * freely licensable by each licensor hereunder covering either (i) the
      + * unmodified Software as contributed to or provided by such licensor, or (ii)
      + * the Larger Works (as defined below), to deal in both
      + *
      + * (a) the Software, and
      + *
      + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
      + * one is included with the Software each a "Larger Work" to which the Software
      + * is contributed by such licensors),
      + *
      + * without restriction, including without limitation the rights to copy, create
      + * derivative works of, display, perform, and distribute the Software and make,
      + * use, sell, offer for sale, import, export, have made, and have sold the
      + * Software and the Larger Work(s), and to sublicense the foregoing rights on
      + * either these or other terms.
      + *
      + * This license is subject to the following condition:
      + *
      + * The above copyright notice and either this complete permission notice or at a
      + * minimum a reference to the UPL must be included in all copies or substantial
      + * portions of the Software.
      + *
      + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      + * SOFTWARE.
      + */
      +package com.oracle.graal.python.builtins.objects.type.slots;
      +
      +import static com.oracle.graal.python.builtins.objects.PNone.NO_VALUE;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___CALL__;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INIT__;
      +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEW__;
      +import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
      +
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
      +import com.oracle.graal.python.builtins.Python3Core;
      +import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      +import com.oracle.graal.python.builtins.PythonBuiltins;
      +import com.oracle.graal.python.builtins.objects.PNone;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.CreateArgsTupleNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.DefaultCheckFunctionResultNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.EagerTupleState;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.ExternalFunctionInvokeNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.InitCheckFunctionResultNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonTransferNode;
      +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode;
      +import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.CheckFunctionResultNode;
      +import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
      +import com.oracle.graal.python.builtins.objects.function.PFunction;
      +import com.oracle.graal.python.builtins.objects.function.PKeyword;
      +import com.oracle.graal.python.builtins.objects.function.Signature;
      +import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
      +import com.oracle.graal.python.builtins.objects.method.PDecoratedMethod;
      +import com.oracle.graal.python.builtins.objects.object.PythonObject;
      +import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotBuiltin;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotCExtNative;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPythonSingle;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.CallSlotDescrGet;
      +import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.PRaiseNode;
      +import com.oracle.graal.python.nodes.argument.CreateArgumentsNode;
      +import com.oracle.graal.python.nodes.call.BoundDescriptor;
      +import com.oracle.graal.python.nodes.call.CallDispatchers;
      +import com.oracle.graal.python.nodes.call.CallNode;
      +import com.oracle.graal.python.nodes.call.special.MaybeBindDescriptorNode;
      +import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode;
      +import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
      +import com.oracle.graal.python.runtime.PythonContext;
      +import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode;
      +import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
      +import com.oracle.graal.python.runtime.object.PFactory;
      +import com.oracle.graal.python.util.PythonUtils;
      +import com.oracle.truffle.api.CompilerAsserts;
      +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
      +import com.oracle.truffle.api.RootCallTarget;
      +import com.oracle.truffle.api.Truffle;
      +import com.oracle.truffle.api.dsl.Bind;
      +import com.oracle.truffle.api.dsl.Cached;
      +import com.oracle.truffle.api.dsl.Fallback;
      +import com.oracle.truffle.api.dsl.GenerateCached;
      +import com.oracle.truffle.api.dsl.GenerateInline;
      +import com.oracle.truffle.api.dsl.GenerateUncached;
      +import com.oracle.truffle.api.dsl.NodeFactory;
      +import com.oracle.truffle.api.dsl.ReportPolymorphism;
      +import com.oracle.truffle.api.dsl.Specialization;
      +import com.oracle.truffle.api.frame.VirtualFrame;
      +import com.oracle.truffle.api.nodes.DirectCallNode;
      +import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.strings.TruffleString;
      +
      +public final class TpSlotVarargs {
      +    private TpSlotVarargs() {
      +    }
      +
      +    public abstract static class TpSlotVarargsBuiltin extends TpSlotBuiltin {
      +        final int callTargetIndex = TpSlotBuiltinCallTargetRegistry.getNextCallTargetIndex();
      +        private final String name;
      +        private final TruffleString tsName;
      +        protected final boolean directInvocation;
      +        protected final Signature signature;
      +        protected final Object[] defaults;
      +        protected final PKeyword[] kwDefaults;
      +
      +        protected TpSlotVarargsBuiltin(NodeFactory nodeFactory, String name) {
      +            this(nodeFactory, name, false);
      +        }
      +
      +        protected TpSlotVarargsBuiltin(NodeFactory nodeFactory, String name, boolean takesClass) {
      +            super(nodeFactory);
      +            this.name = name;
      +            this.tsName = PythonUtils.tsLiteral(name);
      +            Class nodeClass = getNodeFactory().getNodeClass();
      +            SlotSignature slotSignature = nodeClass.getAnnotation(SlotSignature.class);
      +            Slot2Builtin builtin = new Slot2Builtin(slotSignature, name, null);
      +            signature = BuiltinFunctionRootNode.createSignature(getNodeFactory(), builtin, true, takesClass);
      +            defaults = PBuiltinFunction.generateDefaults(PythonBuiltins.numDefaults(builtin));
      +            kwDefaults = PBuiltinFunction.generateKwDefaults(signature);
      +            directInvocation = PythonUnaryBuiltinNode.class.isAssignableFrom(nodeClass) || PythonBinaryBuiltinNode.class.isAssignableFrom(nodeClass) || //
      +                            PythonTernaryBuiltinNode.class.isAssignableFrom(nodeClass) || PythonVarargsBuiltinNode.class.isAssignableFrom(nodeClass) || //
      +                            PythonQuaternaryBuiltinNode.class.isAssignableFrom(nodeClass);
      +        }
      +
      +        final PythonBuiltinBaseNode createSlotNodeIfDirect() {
      +            return directInvocation ? createNode() : null;
      +        }
      +
      +        public Signature getSignature() {
      +            return signature;
      +        }
      +
      +        public Object[] getDefaults() {
      +            return defaults;
      +        }
      +
      +        public PKeyword[] getKwDefaults() {
      +            return kwDefaults;
      +        }
      +
      +        public TruffleString getName() {
      +            return tsName;
      +        }
      +
      +        @Override
      +        public final void initialize(PythonLanguage language) {
      +            RootCallTarget callTarget = createSlotCallTarget(language, null, getNodeFactory(), name);
      +            language.setBuiltinSlotCallTarget(callTargetIndex, callTarget);
      +        }
      +
      +        @Override
      +        public PythonObject createBuiltin(Python3Core core, Object type, TruffleString tsName, PExternalFunctionWrapper wrapper) {
      +            return createBuiltin(core, type, tsName, null, wrapper, getNodeFactory());
      +        }
      +    }
      +
      +    public abstract static class TpSlotNewBuiltin extends TpSlotVarargsBuiltin {
      +
      +        protected TpSlotNewBuiltin(NodeFactory nodeFactory) {
      +            super(nodeFactory, J___NEW__, true);
      +        }
      +
      +        @Override
      +        public PBuiltinMethod createBuiltin(Python3Core core, Object type, TruffleString tsName, PExternalFunctionWrapper wrapper) {
      +            PythonLanguage language = core.getLanguage();
      +            NodeFactory factory = getNodeFactory();
      +            Class nodeClass = factory.getNodeClass();
      +            SlotSignature slotSignature = nodeClass.getAnnotation(SlotSignature.class);
      +            Slot2Builtin builtin = new Slot2Builtin(slotSignature, J___NEW__, null);
      +            PythonBuiltinClassType builtinType = type instanceof PythonBuiltinClassType bt ? bt : null;
      +            /*
      +             * Note: '__new__' is not a 'wrapper_descriptor', but a 'builtin_function_or_method'.
      +             * The method holds the declaring type as self and the actual 'cls' argument comes after
      +             * it. The underlying slot doesn't take the first self. In CPython 'tp_new_wrapper' uses
      +             * the self to check the call safety and then drops it for the slot call. Our
      +             * 'WrapTpNew' holds the type in a field and uses that to do the check. The dropping is
      +             * achieved by using `declaresExplicitSelf = false`.
      +             */
      +            RootCallTarget callTarget = language.createCachedCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, factory, false, builtinType),
      +                            nodeClass, nodeClass, builtinType, J___NEW__);
      +            return PFactory.createNewWrapper(language, type, defaults, kwDefaults, callTarget, this);
      +        }
      +    }
      +
      +    @GenerateCached(false)
      +    abstract static class CallVarargsTpSlotBaseNode extends Node {
      +        public abstract Object execute(VirtualFrame frame, Node inliningTarget, TpSlot slot, Object self, Object[] args, PKeyword[] keywords);
      +
      +        @Specialization(guards = {"frame != null", "cachedSlot == slot"}, limit = "3")
      +        static Object callCachedBuiltin(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") TpSlotVarargsBuiltin slot, Object self, Object[] args, PKeyword[] keywords,
      +                        @SuppressWarnings("unused") @Cached("slot") TpSlotVarargsBuiltin cachedSlot,
      +                        @Cached("cachedSlot.createSlotNodeIfDirect()") PythonBuiltinBaseNode slotNode,
      +                        @Cached DispatchVarargsBuiltinFullDirectNode dispatchFullNode) {
      +            if (slotNode != null) {
      +                if (slotNode instanceof PythonUnaryBuiltinNode unaryBuiltinNode) {
      +                    if (keywords.length == 0 && args.length == 0) {
      +                        return unaryBuiltinNode.execute(frame, self);
      +                    }
      +                } else if (slotNode instanceof PythonBinaryBuiltinNode binaryBuiltinNode) {
      +                    if (keywords.length == 0 && (args.length == 1 || args.length + cachedSlot.getDefaults().length >= 1 && args.length <= 1)) {
      +                        return binaryBuiltinNode.execute(frame, self, args.length == 1 ? args[0] : PNone.NO_VALUE);
      +                    }
      +                } else if (slotNode instanceof PythonTernaryBuiltinNode ternaryBuiltinNode) {
      +                    if (keywords.length == 0 && (args.length == 2 || args.length + cachedSlot.getDefaults().length >= 2 && args.length <= 2)) {
      +                        return ternaryBuiltinNode.execute(frame, self, args.length >= 1 ? args[0] : PNone.NO_VALUE, args.length == 2 ? args[1] : PNone.NO_VALUE);
      +                    }
      +                } else if (slotNode instanceof PythonQuaternaryBuiltinNode quaternaryBuiltinNode) {
      +                    if (keywords.length == 0 && (args.length == 3 || args.length + cachedSlot.getDefaults().length >= 3 && args.length <= 3)) {
      +                        return quaternaryBuiltinNode.execute(frame, self,
      +                                        args.length >= 1 ? args[0] : PNone.NO_VALUE,
      +                                        args.length >= 2 ? args[1] : PNone.NO_VALUE,
      +                                        args.length == 3 ? args[2] : PNone.NO_VALUE);
      +                    }
      +                } else if (slotNode instanceof PythonVarargsBuiltinNode varargsBuiltinNode) {
      +                    return varargsBuiltinNode.execute(frame, self, args, keywords);
      +                }
      +            }
      +            return dispatchFullNode.execute(frame, inliningTarget, cachedSlot, self, args, keywords);
      +        }
      +
      +        @Specialization(replaces = "callCachedBuiltin")
      +        @InliningCutoff
      +        static Object callGenericBuiltin(VirtualFrame frame, Node inliningTarget, TpSlotVarargsBuiltin slot, Object self, Object[] args, PKeyword[] keywords,
      +                        @Cached CreateArgumentsNode createArgumentsNode,
      +                        @Cached CallDispatchers.SimpleIndirectInvokeNode invoke) {
      +            Object[] arguments = createArgumentsNode.execute(inliningTarget, slot.getName(), args, keywords, slot.getSignature(), self, null, slot.getDefaults(), slot.getKwDefaults(),
      +                            false);
      +            RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex);
      +            return invoke.execute(frame, inliningTarget, callTarget, arguments);
      +        }
      +    }
      +
      +    @GenerateInline
      +    @GenerateCached(false)
      +    abstract static class DispatchVarargsBuiltinFullDirectNode extends Node {
      +
      +        public abstract Object execute(VirtualFrame frame, Node inliningTarget, TpSlotVarargsBuiltin slot, Object self, Object[] args, PKeyword[] keywords);
      +
      +        @Specialization
      +        static Object call(VirtualFrame frame, Node inliningTarget, TpSlotVarargsBuiltin slot, Object self, Object[] args, PKeyword[] keywords,
      +                        @Cached CreateArgumentsNode createArgumentsNode,
      +                        @Cached("createDirectCallNode(slot)") DirectCallNode callNode,
      +                        @Cached CallDispatchers.SimpleDirectInvokeNode invoke) {
      +            CompilerAsserts.partialEvaluationConstant(slot);
      +            Object[] arguments = createArgumentsNode.execute(inliningTarget, slot.getName(), args, keywords, slot.getSignature(), self, null, slot.getDefaults(), slot.getKwDefaults(), false);
      +            return invoke.execute(frame, inliningTarget, callNode, arguments);
      +        }
      +
      +        protected static DirectCallNode createDirectCallNode(TpSlotVarargsBuiltin slot) {
      +            return Truffle.getRuntime().createDirectCallNode(PythonLanguage.get(null).getBuiltinSlotCallTarget(slot.callTargetIndex));
      +        }
      +    }
      +
      +    @GenerateInline
      +    @GenerateCached(false)
      +    @GenerateUncached
      +    abstract static class CallSlotVarargsPythonNode extends Node {
      +        abstract Object execute(VirtualFrame frame, Node inliningTarget, TpSlotPythonSingle slot, Object self, Object[] args, PKeyword[] keywords);
      +
      +        @Specialization
      +        static Object callPython(VirtualFrame frame, Node inliningTarget, TpSlotPythonSingle slot, Object self, Object[] args, PKeyword[] keywords,
      +                        @Cached MaybeBindDescriptorNode bindDescriptorNode,
      +                        @Cached(inline = false) CallNode callNode) {
      +            Object bound = bindDescriptorNode.execute(frame, inliningTarget, slot.getCallable(), self, slot.getType());
      +            Object callable;
      +            Object[] callArgs;
      +            if (bound instanceof BoundDescriptor boundDescriptor) {
      +                callable = boundDescriptor.descriptor;
      +                callArgs = args;
      +            } else {
      +                callable = slot.getCallable();
      +                callArgs = new Object[args.length + 1];
      +                callArgs[0] = self;
      +                PythonUtils.arraycopy(args, 0, callArgs, 1, args.length);
      +            }
      +            return callNode.execute(frame, callable, callArgs, keywords);
      +        }
      +    }
      +
      +    private static final CApiTiming C_API_TIMING = CApiTiming.create(true, "");
      +
      +    @GenerateInline(false)
      +    @GenerateUncached
      +    abstract static class CallSlotVarargsNativeNode extends Node {
      +
      +        abstract Object execute(VirtualFrame frame, TpSlotCExtNative slot, Object self, Object[] args, PKeyword[] keywords, TruffleString name, CheckFunctionResultNode checkResultNode,
      +                        NativeToPythonTransferNode toPythonNode);
      +
      +        @Specialization
      +        static Object callNative(VirtualFrame frame, TpSlotCExtNative slot, Object self, Object[] args, PKeyword[] keywords, TruffleString name, CheckFunctionResultNode checkResultNode,
      +                        NativeToPythonTransferNode toPythonNode,
      +                        @Bind Node inliningTarget,
      +                        @Bind PythonContext context,
      +                        @Cached GetThreadStateNode getThreadStateNode,
      +                        @Cached(inline = false) PythonToNativeNode toNativeNode,
      +                        @Cached CreateArgsTupleNode createArgsTupleNode,
      +                        @Cached EagerTupleState eagerTupleState,
      +                        @Cached ExternalFunctionInvokeNode externalInvokeNode) {
      +            PythonLanguage language = context.getLanguage(inliningTarget);
      +            PythonThreadState state = getThreadStateNode.execute(inliningTarget, context);
      +            PTuple argsTuple = createArgsTupleNode.execute(inliningTarget, language, args, eagerTupleState);
      +            Object kwargsDict = PFactory.createDict(language, keywords);
      +            Object nativeResult = externalInvokeNode.call(frame, inliningTarget, state, C_API_TIMING, name, slot.callable,
      +                            toNativeNode.execute(self), toNativeNode.execute(argsTuple), toNativeNode.execute(kwargsDict));
      +            eagerTupleState.report(inliningTarget, argsTuple);
      +            checkResultNode.execute(state, name, nativeResult);
      +            if (toPythonNode != null) {
      +                return toPythonNode.execute(nativeResult);
      +            }
      +            return NO_VALUE;
      +        }
      +    }
      +
      +    @GenerateInline
      +    @GenerateCached(false)
      +    @GenerateUncached
      +    @ReportPolymorphism
      +    public abstract static class CallSlotTpInitNode extends CallVarargsTpSlotBaseNode {
      +
      +        @Specialization
      +        static Object callPython(VirtualFrame frame, Node inliningTarget, TpSlotPythonSingle slot, Object self, Object[] args, PKeyword[] keywords,
      +                        @Cached CallSlotVarargsPythonNode callNode,
      +                        @Cached PRaiseNode raiseNode) {
      +            Object result = callNode.execute(frame, inliningTarget, slot, self, args, keywords);
      +            if (result != PNone.NONE) {
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.SHOULD_RETURN_NONE, "__init__()");
      +            }
      +            return PNone.NO_VALUE;
      +        }
      +
      +        @Specialization
      +        @InliningCutoff
      +        static Object callNative(VirtualFrame frame, TpSlotCExtNative slot, Object self, Object[] args, PKeyword[] keywords,
      +                        @Cached InitCheckFunctionResultNode checkResult,
      +                        @Cached CallSlotVarargsNativeNode callNode) {
      +            return callNode.execute(frame, slot, self, args, keywords, T___INIT__, checkResult, null);
      +        }
      +    }
      +
      +    @GenerateInline
      +    @GenerateCached(false)
      +    @GenerateUncached
      +    public abstract static class BindNewMethodNode extends Node {
      +        public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object descriptor, Object type);
      +
      +        @Specialization(guards = "isStaticmethod(descriptor)")
      +        static Object doStaticmethod(PDecoratedMethod descriptor, @SuppressWarnings("unused") Object type) {
      +            return descriptor.getCallable();
      +        }
      +
      +        protected static boolean isStaticmethod(PDecoratedMethod descriptor) {
      +            return descriptor.getInitialPythonClass() == PythonBuiltinClassType.PStaticmethod;
      +        }
      +
      +        @Specialization
      +        static Object doBuiltinMethod(PBuiltinMethod descriptor, @SuppressWarnings("unused") Object type) {
      +            return descriptor;
      +        }
      +
      +        @Specialization
      +        static Object doFunction(PFunction descriptor, @SuppressWarnings("unused") Object type) {
      +            return descriptor;
      +        }
      +
      +        @Fallback
      +        static Object doBind(VirtualFrame frame, Node inliningTarget, Object descriptor, Object type,
      +                        @Cached GetObjectSlotsNode getSlotsNode,
      +                        @Cached CallSlotDescrGet callGetSlot) {
      +            var getMethod = getSlotsNode.execute(inliningTarget, descriptor).tp_descr_get();
      +            if (getMethod != null) {
      +                return callGetSlot.execute(frame, inliningTarget, getMethod, descriptor, NO_VALUE, type);
      +            }
      +            return descriptor;
      +        }
      +    }
      +
      +    @GenerateInline
      +    @GenerateCached(false)
      +    @GenerateUncached
      +    @ReportPolymorphism
      +    public abstract static class CallSlotTpNewNode extends CallVarargsTpSlotBaseNode {
      +
      +        @Specialization
      +        static Object callPython(VirtualFrame frame, Node inliningTarget, TpSlotPythonSingle slot, Object self, Object[] args, PKeyword[] keywords,
      +                        @Cached BindNewMethodNode bindNew,
      +                        @Cached(inline = false) CallNode callNode) {
      +            Object callable = bindNew.execute(frame, inliningTarget, slot.getCallable(), self);
      +            return callNode.execute(frame, callable, PythonUtils.prependArgument(self, args), keywords);
      +        }
      +
      +        @Specialization
      +        @InliningCutoff
      +        static Object callNative(VirtualFrame frame, TpSlotCExtNative slot, Object self, Object[] args, PKeyword[] keywords,
      +                        @Cached DefaultCheckFunctionResultNode checkResult,
      +                        @Cached NativeToPythonTransferNode toPythonNode,
      +                        @Cached CallSlotVarargsNativeNode callNode) {
      +            return callNode.execute(frame, slot, self, args, keywords, T___NEW__, checkResult, toPythonNode);
      +        }
      +    }
      +
      +    @GenerateInline
      +    @GenerateCached(false)
      +    @GenerateUncached
      +    @ReportPolymorphism
      +    public abstract static class CallSlotTpCallNode extends CallVarargsTpSlotBaseNode {
      +
      +        @Specialization
      +        static Object callPython(VirtualFrame frame, Node inliningTarget, TpSlotPythonSingle slot, Object self, Object[] args, PKeyword[] keywords,
      +                        @Cached CallSlotVarargsPythonNode callNode) {
      +            return callNode.execute(frame, inliningTarget, slot, self, args, keywords);
      +        }
      +
      +        @Specialization
      +        @InliningCutoff
      +        static Object callNative(VirtualFrame frame, TpSlotCExtNative slot, Object self, Object[] args, PKeyword[] keywords,
      +                        @Cached DefaultCheckFunctionResultNode checkResult,
      +                        @Cached NativeToPythonTransferNode toPythonNode,
      +                        @Cached CallSlotVarargsNativeNode callNode) {
      +            return callNode.execute(frame, slot, self, args, keywords, T___CALL__, checkResult, toPythonNode);
      +        }
      +    }
      +}
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasBuiltins.java
      index 3f651dc67a..35330b8ceb 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasBuiltins.java
      @@ -54,15 +54,10 @@
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___ORIG_CLASS__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___PARAMETERS__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___UNPACKED__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___DIR__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INSTANCECHECK__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___MRO_ENTRIES__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SUBCLASSCHECK__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___COPY__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.T___DEEPCOPY__;
      @@ -74,8 +69,10 @@
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
      +import com.oracle.graal.python.annotations.Slot.SlotSignature;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      @@ -94,6 +91,8 @@
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.GetAttrBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.RichCmpBuiltinNode;
       import com.oracle.graal.python.lib.PyObjectDir;
       import com.oracle.graal.python.lib.PyObjectGetAttr;
       import com.oracle.graal.python.lib.PyObjectGetIter;
      @@ -101,6 +100,7 @@
       import com.oracle.graal.python.lib.PyObjectRichCompareBool;
       import com.oracle.graal.python.lib.PyObjectSetAttr;
       import com.oracle.graal.python.lib.PySequenceContainsNode;
      +import com.oracle.graal.python.lib.RichCmpOp;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.StringLiterals;
      @@ -108,6 +108,7 @@
       import com.oracle.graal.python.nodes.call.CallNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
      +import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
       import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
      @@ -116,7 +117,7 @@
       import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
       import com.oracle.graal.python.runtime.PythonContext;
       import com.oracle.graal.python.runtime.exception.PException;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.dsl.Bind;
      @@ -128,6 +129,7 @@
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.ExplodeLoop;
       import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.InlinedBranchProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       import com.oracle.truffle.api.strings.TruffleStringBuilder;
       
      @@ -154,6 +156,18 @@ protected List> getNodeFa
               return GenericAliasBuiltinsFactory.getFactories();
           }
       
      +    @Slot(value = SlotKind.tp_new, isComplex = true)
      +    @SlotSignature(name = "GenericAlias", minNumOfPositionalArgs = 3)
      +    @GenerateNodeFactory
      +    public abstract static class GenericAliasNode extends PythonTernaryBuiltinNode {
      +        @Specialization
      +        static PGenericAlias doit(Object cls, Object origin, Object arguments,
      +                        @Bind PythonLanguage language,
      +                        @Cached TypeNodes.GetInstanceShape getInstanceShape) {
      +            return PFactory.createGenericAlias(language, cls, getInstanceShape.execute(cls), origin, arguments, false);
      +        }
      +    }
      +
           @Builtin(name = J___ORIGIN__, minNumOfPositionalArgs = 1, isGetter = true)
           @GenerateNodeFactory
           abstract static class OriginNode extends PythonUnaryBuiltinNode {
      @@ -178,9 +192,10 @@ abstract static class ParametersNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object parameters(PGenericAlias self,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PythonObjectFactory.Lazy factory) {
      +                        @Cached InlinedBranchProfile createProfile) {
                   if (self.getParameters() == null) {
      -                self.setParameters(factory.get(inliningTarget).createTuple(GenericTypeNodes.makeParameters(self.getArgs())));
      +                createProfile.enter(inliningTarget);
      +                self.setParameters(PFactory.createTuple(PythonLanguage.get(inliningTarget), GenericTypeNodes.makeParameters(self.getArgs())));
                   }
                   return self.getParameters();
               }
      @@ -205,7 +220,7 @@ static Object union(Object self, Object other,
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
               private static final TruffleString SEPARATOR = tsLiteral(", ");
      @@ -245,9 +260,9 @@ private static void reprItem(TruffleStringBuilder sb, Object obj) {
               }
           }
       
      -    @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_hash, isComplex = true)
           @GenerateNodeFactory
      -    abstract static class HashNode extends PythonUnaryBuiltinNode {
      +    abstract static class HashNode extends HashBuiltinNode {
               @Specialization
               static long hash(VirtualFrame frame, PGenericAlias self,
                               @Bind("this") Node inliningTarget,
      @@ -259,7 +274,8 @@ static long hash(VirtualFrame frame, PGenericAlias self,
               }
           }
       
      -    @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
      +    @Slot(value = SlotKind.tp_call, isComplex = true)
      +    @SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
           @GenerateNodeFactory
           abstract static class CallMethodNode extends PythonVarargsBuiltinNode {
               @Specialization
      @@ -308,23 +324,26 @@ static Object getattribute(VirtualFrame frame, PGenericAlias self, Object nameOb
               }
           }
       
      -    @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.tp_richcompare, isComplex = true)
           @GenerateNodeFactory
      -    abstract static class EqNode extends PythonBinaryBuiltinNode {
      -        @Specialization
      -        static boolean eq(VirtualFrame frame, PGenericAlias self, PGenericAlias other,
      +    abstract static class EqNode extends RichCmpBuiltinNode {
      +        @Specialization(guards = "op.isEqOrNe()")
      +        static boolean eq(VirtualFrame frame, PGenericAlias self, PGenericAlias other, RichCmpOp op,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PyObjectRichCompareBool.EqNode eqOrigin,
      -                        @Cached PyObjectRichCompareBool.EqNode eqArgs) {
      +                        @Cached PyObjectRichCompareBool eqOrigin,
      +                        @Cached PyObjectRichCompareBool eqArgs) {
                   if (self.isStarred() != other.isStarred()) {
      -                return false;
      +                return op.isNe();
      +            }
      +            if (!eqOrigin.executeEq(frame, inliningTarget, self.getOrigin(), other.getOrigin())) {
      +                return op.isNe();
                   }
      -            return eqOrigin.compare(frame, inliningTarget, self.getOrigin(), other.getOrigin()) && eqArgs.compare(frame, inliningTarget, self.getArgs(), other.getArgs());
      +            return eqArgs.executeEq(frame, inliningTarget, self.getArgs(), other.getArgs()) == op.isEq();
               }
       
               @Fallback
               @SuppressWarnings("unused")
      -        static Object eq(Object self, Object other) {
      +        static Object eq(Object self, Object other, RichCmpOp op) {
                   return PNotImplemented.NOT_IMPLEMENTED;
               }
           }
      @@ -334,8 +353,8 @@ static Object eq(Object self, Object other) {
           abstract static class MroEntriesNode extends PythonBinaryBuiltinNode {
               @Specialization
               static Object mro(PGenericAlias self, @SuppressWarnings("unused") Object bases,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createTuple(new Object[]{self.getOrigin()});
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createTuple(language, new Object[]{self.getOrigin()});
               }
           }
       
      @@ -345,8 +364,8 @@ abstract static class InstanceCheckNode extends PythonBinaryBuiltinNode {
               @Specialization
               @SuppressWarnings("unused")
               static Object check(PGenericAlias self, Object other,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.ISINSTANCE_ARG_2_CANNOT_BE_A_PARAMETERIZED_GENERIC);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.ISINSTANCE_ARG_2_CANNOT_BE_A_PARAMETERIZED_GENERIC);
               }
           }
       
      @@ -356,8 +375,8 @@ abstract static class SubclassCheckNode extends PythonBinaryBuiltinNode {
               @Specialization
               @SuppressWarnings("unused")
               static Object check(PGenericAlias self, Object other,
      -                        @Cached PRaiseNode raiseNode) {
      -            throw raiseNode.raise(TypeError, ErrorMessages.ISSUBCLASS_ARG_2_CANNOT_BE_A_PARAMETERIZED_GENERIC);
      +                        @Bind("this") Node inliningTarget) {
      +            throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.ISSUBCLASS_ARG_2_CANNOT_BE_A_PARAMETERIZED_GENERIC);
               }
           }
       
      @@ -370,16 +389,16 @@ static Object reduce(VirtualFrame frame, PGenericAlias self,
                               @Cached GetClassNode getClassNode,
                               @Cached PyObjectGetIter getIter,
                               @Cached PyObjectGetAttr getAttr,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   if (self.isStarred()) {
      -                PGenericAlias copy = factory.createGenericAlias(self.getOrigin(), self.getArgs());
      +                PGenericAlias copy = PFactory.createGenericAlias(language, self.getOrigin(), self.getArgs());
                       PythonModule builtins = PythonContext.get(inliningTarget).getBuiltins();
                       Object next = getAttr.execute(frame, inliningTarget, builtins, T_NEXT);
      -                Object args = factory.createTuple(new Object[]{getIter.execute(frame, inliningTarget, copy)});
      -                return factory.createTuple(new Object[]{next, args});
      +                Object args = PFactory.createTuple(language, new Object[]{getIter.execute(frame, inliningTarget, copy)});
      +                return PFactory.createTuple(language, new Object[]{next, args});
                   }
      -            Object args = factory.createTuple(new Object[]{self.getOrigin(), self.getArgs()});
      -            return factory.createTuple(new Object[]{getClassNode.execute(inliningTarget, self), args});
      +            Object args = PFactory.createTuple(language, new Object[]{self.getOrigin(), self.getArgs()});
      +            return PFactory.createTuple(language, new Object[]{getClassNode.execute(inliningTarget, self), args});
               }
           }
       
      @@ -409,13 +428,13 @@ abstract static class GetItemNode extends MpSubscriptBuiltinNode {
               @Specialization
               static Object getitem(PGenericAlias self, Object item,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   if (self.getParameters() == null) {
      -                self.setParameters(factory.createTuple(GenericTypeNodes.makeParameters(self.getArgs())));
      +                self.setParameters(PFactory.createTuple(language, GenericTypeNodes.makeParameters(self.getArgs())));
                   }
                   Object[] newargs = GenericTypeNodes.subsParameters(inliningTarget, self, self.getArgs(), self.getParameters(), item);
      -            PTuple newargsTuple = factory.createTuple(newargs);
      -            return factory.createGenericAlias(self.getOrigin(), newargsTuple, self.isStarred());
      +            PTuple newargsTuple = PFactory.createTuple(language, newargs);
      +            return PFactory.createGenericAlias(language, self.getOrigin(), newargsTuple, self.isStarred());
               }
           }
       
      @@ -433,13 +452,13 @@ static Object get(PGenericAlias self,
               }
           }
       
      -    @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iter, isComplex = true)
           @GenerateNodeFactory
           abstract static class IterNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object iter(PGenericAlias self,
      -                        @Cached PythonObjectFactory factory) {
      -            return factory.createGenericAliasIterator(self);
      +                        @Bind PythonLanguage language) {
      +            return PFactory.createGenericAliasIterator(language, self);
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasIteratorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasIteratorBuiltins.java
      index 9904ac8ec5..a1baec9e90 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasIteratorBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasIteratorBuiltins.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -41,22 +41,25 @@
       package com.oracle.graal.python.builtins.objects.types;
       
       import static com.oracle.graal.python.nodes.BuiltinNames.T_ITER;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEXT__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REDUCE__;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
      +import com.oracle.graal.python.annotations.Slot;
      +import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
       import com.oracle.graal.python.builtins.CoreFunctions;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.PythonBuiltins;
       import com.oracle.graal.python.builtins.objects.module.PythonModule;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
       import com.oracle.graal.python.lib.PyObjectGetAttr;
      -import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.runtime.PythonContext;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.truffle.api.dsl.Bind;
       import com.oracle.truffle.api.dsl.Cached;
       import com.oracle.truffle.api.dsl.GenerateNodeFactory;
      @@ -67,23 +70,25 @@
       
       @CoreFunctions(extendClasses = PythonBuiltinClassType.PGenericAliasIterator)
       public final class GenericAliasIteratorBuiltins extends PythonBuiltins {
      +
      +    public static final TpSlots SLOTS = GenericAliasIteratorBuiltinsSlotsGen.SLOTS;
      +
           @Override
           protected List> getNodeFactories() {
               return GenericAliasIteratorBuiltinsFactory.getFactories();
           }
       
      -    @Builtin(name = J___NEXT__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_iternext, isComplex = true)
           @GenerateNodeFactory
      -    abstract static class NextNode extends PythonUnaryBuiltinNode {
      +    abstract static class NextNode extends TpIterNextBuiltin {
               @Specialization
               static Object next(PGenericAliasIterator self,
      -                        @Cached PRaiseNode raiseNode,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   if (self.isExhausted()) {
      -                throw raiseNode.raise(PythonBuiltinClassType.StopIteration);
      +                throw iteratorExhausted();
                   }
                   PGenericAlias alias = self.getObj();
      -            PGenericAlias starredAlias = factory.createGenericAlias(alias.getOrigin(), alias.getArgs(), true);
      +            PGenericAlias starredAlias = PFactory.createGenericAlias(language, alias.getOrigin(), alias.getArgs(), true);
                   self.markExhausted();
                   return starredAlias;
               }
      @@ -96,16 +101,16 @@ abstract static class ReduceNode extends PythonUnaryBuiltinNode {
               static Object reduce(VirtualFrame frame, PGenericAliasIterator self,
                               @Bind("this") Node inliningTarget,
                               @Cached PyObjectGetAttr getAttr,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   PythonModule builtins = PythonContext.get(inliningTarget).getBuiltins();
                   Object iter = getAttr.execute(frame, inliningTarget, builtins, T_ITER);
                   Object[] args;
                   if (!self.isExhausted()) {
                       args = new Object[]{self.getObj()};
                   } else {
      -                args = new Object[]{factory.createEmptyTuple()};
      +                args = new Object[]{PFactory.createEmptyTuple(language)};
                   }
      -            return factory.createTuple(new Object[]{iter, factory.createTuple(args)});
      +            return PFactory.createTuple(language, new Object[]{iter, PFactory.createTuple(language, args)});
               }
           }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericTypeNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericTypeNodes.java
      index 844b9d7b1f..fcc9ea419d 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericTypeNodes.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericTypeNodes.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -52,13 +52,14 @@
       import java.util.Arrays;
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.builtins.PythonBuiltinClassType;
       import com.oracle.graal.python.builtins.objects.PNone;
       import com.oracle.graal.python.builtins.objects.PNotImplemented;
       import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
       import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis;
       import com.oracle.graal.python.builtins.objects.tuple.PTuple;
      -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
      +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
       import com.oracle.graal.python.builtins.objects.type.TypeNodes;
       import com.oracle.graal.python.lib.PyObjectGetItem;
       import com.oracle.graal.python.lib.PyObjectIsTrueNode;
      @@ -72,12 +73,10 @@
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PNodeWithContext;
       import com.oracle.graal.python.nodes.PRaiseNode;
      -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode;
       import com.oracle.graal.python.nodes.call.CallNode;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.nodes.object.IsNode;
      -import com.oracle.graal.python.runtime.PythonContext;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.dsl.Bind;
      @@ -124,7 +123,7 @@ static void reprItem(TruffleStringBuilder sb, Object obj) {
                   Object module = lookup.execute(null, null, obj, T___MODULE__);
                   if (!(module instanceof PNone)) {
                       // Looks like a class
      -                if (PyUnicodeCheckNode.executeUncached(module) && PyObjectRichCompareBool.EqNode.compareUncached(module, BuiltinNames.T_BUILTINS)) {
      +                if (PyUnicodeCheckNode.executeUncached(module) && PyObjectRichCompareBool.executeEqUncached(module, BuiltinNames.T_BUILTINS)) {
                           // builtins don't need a module name
                           sb.appendStringUncached(str.execute(null, null, qualname));
                           return;
      @@ -264,24 +263,24 @@ private static void unpackArgsInner(List newargs, Object item) {
           // Equivalent of _Py_subs_parameters
           @TruffleBoundary
           static Object[] subsParameters(Node node, Object self, PTuple args, PTuple parameters, Object item) {
      +        PythonLanguage language = PythonLanguage.get(null);
               SequenceStorage paramsStorage = parameters.getSequenceStorage();
               int nparams = paramsStorage.length();
               if (nparams == 0) {
      -            throw PRaiseNode.raiseUncached(node, TypeError, ErrorMessages.S_IS_NOT_A_GENERIC_CLASS, PyObjectReprAsTruffleStringNode.executeUncached(self));
      +            throw PRaiseNode.raiseStatic(node, TypeError, ErrorMessages.S_IS_NOT_A_GENERIC_CLASS, PyObjectReprAsTruffleStringNode.executeUncached(self));
               }
               Object[] argitems = unpackArgs(item);
               for (int i = 0; i < nparams; i++) {
                   Object param = getItemUncached(paramsStorage, i);
                   Object prepare = PyObjectLookupAttr.executeUncached(param, T___TYPING_PREPARE_SUBST__);
                   if (!(prepare instanceof PNone)) {
      -                Object itemarg = item instanceof PTuple ? item : PythonContext.get(node).factory().createTuple(new Object[]{item});
      +                Object itemarg = item instanceof PTuple ? item : PFactory.createTuple(language, new Object[]{item});
                       item = CallNode.executeUncached(prepare, self, itemarg);
                   }
               }
               if (argitems.length != nparams) {
      -            throw PRaiseNode.raiseUncached(node, TypeError, ErrorMessages.TOO_S_ARGUMENTS_FOR_S_ACTUAL_D_EXPECTED_D,
      -                            argitems.length > nparams ? "many" : "few", PyObjectReprAsTruffleStringNode.executeUncached(self),
      -                            argitems.length, nparams);
      +            throw PRaiseNode.raiseStatic(node, TypeError, ErrorMessages.TOO_S_ARGUMENTS_FOR_S_ACTUAL_D_EXPECTED_D, argitems.length > nparams ? "many" : "few",
      +                            PyObjectReprAsTruffleStringNode.executeUncached(self), argitems.length, nparams);
               }
               SequenceStorage argsStorage = args.getSequenceStorage();
               List newargs = new ArrayList<>(argsStorage.length());
      @@ -298,7 +297,7 @@ static Object[] subsParameters(Node node, Object self, PTuple args, PTuple param
                       assert iparam >= 0;
                       arg = CallNode.executeUncached(subst, argitems[iparam]);
                   } else {
      -                arg = subsTvars(node, arg, parameters, argitems);
      +                arg = subsTvars(arg, parameters, argitems);
                   }
                   if (unpack && arg instanceof PTuple tuple /* CPython doesn't check the cast?! */) {
                       listExtend(newargs, tuple);
      @@ -310,7 +309,7 @@ static Object[] subsParameters(Node node, Object self, PTuple args, PTuple param
           }
       
           @TruffleBoundary
      -    private static Object subsTvars(Node node, Object obj, PTuple parameters, Object[] argitems) {
      +    private static Object subsTvars(Object obj, PTuple parameters, Object[] argitems) {
               Object subparams = PyObjectLookupAttr.executeUncached(obj, T___PARAMETERS__);
               if (subparams instanceof PTuple tuple && tuple.getSequenceStorage().length() > 0) {
                   SequenceStorage subparamsStorage = tuple.getSequenceStorage();
      @@ -324,14 +323,14 @@ private static Object subsTvars(Node node, Object obj, PTuple parameters, Object
                           // TypeVarTuple
                           if (arg instanceof PTuple tuple1) {
                               Object paramType = GetClassNode.executeUncached(param);
      -                        if (LookupCallableSlotInMRONode.getUncached(SpecialMethodSlot.Iter).execute(paramType) != PNone.NO_VALUE) {
      +                        if (GetObjectSlotsNode.executeUncached(paramType).tp_iter() != null) {
                                   listExtend(subargs, tuple1);
                               }
                           }
                       }
                       subargs.add(arg);
                   }
      -            PTuple subargsTuple = PythonContext.get(node).factory().createTuple(subargs.toArray());
      +            PTuple subargsTuple = PFactory.createTuple(PythonLanguage.get(null), subargs.toArray());
                   obj = PyObjectGetItem.executeUncached(obj, subargsTuple);
               }
               return obj;
      @@ -345,13 +344,13 @@ public abstract static class UnionTypeOrNode extends PNodeWithContext {
               static Object union(Object self, Object other,
                               @SuppressWarnings("unused") @Bind("this") Node inliningTarget,
                               @SuppressWarnings("unused") @Cached PyObjectTypeCheck typeCheck,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   Object[] args = dedupAndFlattenArgs(new Object[]{self, other});
                   if (args.length == 1) {
                       return args[0];
                   }
                   assert args.length > 1;
      -            return factory.createUnionType(args);
      +            return PFactory.createUnionType(language, args);
               }
       
               @Fallback
      @@ -369,7 +368,7 @@ protected static boolean isUnionable(Node inliningTarget, PyObjectTypeCheck type
           @TruffleBoundary
           private static Object[] dedupAndFlattenArgs(Object[] args) {
               args = flattenArgs(args);
      -        PyObjectRichCompareBool.EqNode eq = PyObjectRichCompareBool.EqNode.getUncached();
      +        PyObjectRichCompareBool eq = PyObjectRichCompareBool.getUncached();
               Object[] newArgs = new Object[args.length];
               int addedItems = 0;
               for (int i = 0; i < args.length; i++) {
      @@ -379,7 +378,7 @@ private static Object[] dedupAndFlattenArgs(Object[] args) {
                       Object jElement = newArgs[j];
                       boolean isGA = iElement instanceof PGenericAlias && jElement instanceof PGenericAlias;
                       // RichCompare to also deduplicate GenericAlias types (slower)
      -                isDuplicate = isGA ? eq.compare(null, null, iElement, jElement) : IsNode.getUncached().execute(iElement, jElement);
      +                isDuplicate = isGA ? eq.executeEq(null, null, iElement, jElement) : IsNode.getUncached().execute(iElement, jElement);
                       if (isDuplicate) {
                           break;
                       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/UnionTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/UnionTypeBuiltins.java
      index 86174747fa..a39de9cde7 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/UnionTypeBuiltins.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/UnionTypeBuiltins.java
      @@ -44,16 +44,14 @@
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___ARGS__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___PARAMETERS__;
       import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___MODULE__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INSTANCECHECK__;
      -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
       import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SUBCLASSCHECK__;
       import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
       import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
       
       import java.util.List;
       
      +import com.oracle.graal.python.PythonLanguage;
       import com.oracle.graal.python.annotations.Slot;
       import com.oracle.graal.python.annotations.Slot.SlotKind;
       import com.oracle.graal.python.builtins.Builtin;
      @@ -72,21 +70,23 @@
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode;
       import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.GetAttrBuiltinNode;
      +import com.oracle.graal.python.lib.PyNumberOrNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode;
      +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.RichCmpBuiltinNode;
      +import com.oracle.graal.python.lib.RichCmpOp;
       import com.oracle.graal.python.lib.PyObjectGetAttr;
       import com.oracle.graal.python.lib.PyObjectHashNode;
       import com.oracle.graal.python.lib.PyObjectRichCompareBool;
       import com.oracle.graal.python.nodes.ErrorMessages;
       import com.oracle.graal.python.nodes.PRaiseNode;
       import com.oracle.graal.python.nodes.StringLiterals;
      -import com.oracle.graal.python.nodes.expression.BinaryArithmetic;
      -import com.oracle.graal.python.nodes.expression.BinaryOpNode;
       import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
       import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
       import com.oracle.graal.python.nodes.object.GetClassNode;
       import com.oracle.graal.python.nodes.util.CannotCastException;
       import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
      +import com.oracle.graal.python.runtime.object.PFactory;
       import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
       import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
       import com.oracle.truffle.api.dsl.Bind;
      @@ -97,6 +97,7 @@
       import com.oracle.truffle.api.dsl.Specialization;
       import com.oracle.truffle.api.frame.VirtualFrame;
       import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.profiles.InlinedBranchProfile;
       import com.oracle.truffle.api.strings.TruffleString;
       import com.oracle.truffle.api.strings.TruffleStringBuilder;
       
      @@ -123,9 +124,9 @@ Object args(PUnionType self) {
           abstract static class ParametersNode extends PythonUnaryBuiltinNode {
               @Specialization
               static Object parameters(PUnionType self,
      -                        @Cached PythonObjectFactory factory) {
      +                        @Bind PythonLanguage language) {
                   if (self.getParameters() == null) {
      -                self.setParameters(factory.createTuple(GenericTypeNodes.makeParameters(self.getArgs())));
      +                self.setParameters(PFactory.createTuple(language, GenericTypeNodes.makeParameters(self.getArgs())));
                   }
                   return self.getParameters();
               }
      @@ -141,7 +142,7 @@ Object union(Object self, Object other,
               }
           }
       
      -    @Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_repr, isComplex = true)
           @GenerateNodeFactory
           abstract static class ReprNode extends PythonUnaryBuiltinNode {
               private static final TruffleString SEPARATOR = tsLiteral(" | ");
      @@ -170,16 +171,16 @@ private static void reprItem(TruffleStringBuilder sb, Object obj) {
               }
           }
       
      -    @Builtin(name = J___HASH__, minNumOfPositionalArgs = 1)
      +    @Slot(value = SlotKind.tp_hash, isComplex = true)
           @GenerateNodeFactory
      -    abstract static class HashNode extends PythonUnaryBuiltinNode {
      +    abstract static class HashNode extends HashBuiltinNode {
               @Specialization
               static long hash(VirtualFrame frame, PUnionType self,
                               @Bind("this") Node inliningTarget,
                               @Cached PyObjectHashNode hashNode,
                               @Cached HashingCollectionNodes.GetClonedHashingStorageNode getHashingStorageNode,
      -                        @Cached PythonObjectFactory factory) {
      -            PFrozenSet argSet = factory.createFrozenSet(getHashingStorageNode.doNoValue(frame, inliningTarget, self.getArgs()));
      +                        @Bind PythonLanguage language) {
      +            PFrozenSet argSet = PFactory.createFrozenSet(language, getHashingStorageNode.getForSets(frame, inliningTarget, self.getArgs()));
                   return hashNode.execute(frame, inliningTarget, argSet);
               }
           }
      @@ -217,13 +218,13 @@ static boolean check(VirtualFrame frame, PUnionType self, Object other,
                               @Bind("this") Node inliningTarget,
                               @Cached SequenceStorageNodes.GetItemScalarNode getItem,
                               @Cached BuiltinFunctions.IsInstanceNode isInstanceNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   SequenceStorage argsStorage = self.getArgs().getSequenceStorage();
                   boolean result = false;
                   for (int i = 0; i < argsStorage.length(); i++) {
                       Object arg = getItem.execute(inliningTarget, argsStorage, i);
                       if (arg instanceof PGenericAlias) {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ISINSTANCE_ARG_2_CANNOT_CONTAIN_A_PARAMETERIZED_GENERIC);
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ISINSTANCE_ARG_2_CANNOT_CONTAIN_A_PARAMETERIZED_GENERIC);
                       }
                       if (!result) {
                           result = isInstanceNode.executeWith(frame, other, arg);
      @@ -243,16 +244,16 @@ static boolean check(VirtualFrame frame, PUnionType self, Object other,
                               @Cached TypeNodes.IsTypeNode isTypeNode,
                               @Cached SequenceStorageNodes.GetItemScalarNode getItem,
                               @Cached BuiltinFunctions.IsSubClassNode isSubClassNode,
      -                        @Cached PRaiseNode.Lazy raiseNode) {
      +                        @Cached PRaiseNode raiseNode) {
                   if (!isTypeNode.execute(inliningTarget, other)) {
      -                throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ISSUBCLASS_ARG_1_MUST_BE_A_CLASS);
      +                throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ISSUBCLASS_ARG_1_MUST_BE_A_CLASS);
                   }
                   SequenceStorage argsStorage = self.getArgs().getSequenceStorage();
                   boolean result = false;
                   for (int i = 0; i < argsStorage.length(); i++) {
                       Object arg = getItem.execute(inliningTarget, argsStorage, i);
                       if (arg instanceof PGenericAlias) {
      -                    throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ISSUBCLASS_ARG_2_CANNOT_CONTAIN_A_PARAMETERIZED_GENERIC);
      +                    throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ISSUBCLASS_ARG_2_CANNOT_CONTAIN_A_PARAMETERIZED_GENERIC);
                       }
                       if (!result) {
                           result = isSubClassNode.executeWith(frame, other, arg);
      @@ -263,23 +264,23 @@ static boolean check(VirtualFrame frame, PUnionType self, Object other,
               }
           }
       
      -    @Builtin(name = J___EQ__, minNumOfPositionalArgs = 2)
      +    @Slot(value = SlotKind.tp_richcompare, isComplex = true)
           @GenerateNodeFactory
      -    abstract static class EqNode extends PythonBinaryBuiltinNode {
      -        @Specialization
      -        static boolean eq(VirtualFrame frame, PUnionType self, PUnionType other,
      +    abstract static class EqNode extends RichCmpBuiltinNode {
      +        @Specialization(guards = "op.isEqOrNe()")
      +        static boolean eq(VirtualFrame frame, PUnionType self, PUnionType other, RichCmpOp op,
                               @Bind("this") Node inliningTarget,
                               @Cached HashingCollectionNodes.GetClonedHashingStorageNode getHashingStorageNode,
      -                        @Cached PyObjectRichCompareBool.EqNode eqNode,
      -                        @Cached PythonObjectFactory factory) {
      -            PFrozenSet argSet1 = factory.createFrozenSet(getHashingStorageNode.doNoValue(frame, inliningTarget, self.getArgs()));
      -            PFrozenSet argSet2 = factory.createFrozenSet(getHashingStorageNode.doNoValue(frame, inliningTarget, other.getArgs()));
      -            return eqNode.compare(frame, inliningTarget, argSet1, argSet2);
      +                        @Cached PyObjectRichCompareBool eqNode,
      +                        @Bind PythonLanguage language) {
      +            PFrozenSet argSet1 = PFactory.createFrozenSet(language, getHashingStorageNode.getForSets(frame, inliningTarget, self.getArgs()));
      +            PFrozenSet argSet2 = PFactory.createFrozenSet(language, getHashingStorageNode.getForSets(frame, inliningTarget, other.getArgs()));
      +            return eqNode.execute(frame, inliningTarget, argSet1, argSet2, op);
               }
       
               @Fallback
               @SuppressWarnings("unused")
      -        Object eq(Object self, Object other) {
      +        Object eq(Object self, Object other, RichCmpOp op) {
                   return PNotImplemented.NOT_IMPLEMENTED;
               }
           }
      @@ -287,19 +288,20 @@ Object eq(Object self, Object other) {
           @Slot(value = SlotKind.mp_subscript, isComplex = true)
           @GenerateNodeFactory
           abstract static class GetItemNode extends MpSubscriptBuiltinNode {
      -        @Child BinaryOpNode orNode = BinaryArithmetic.Or.create();
       
               @Specialization
               Object getitem(VirtualFrame frame, PUnionType self, Object item,
                               @Bind("this") Node inliningTarget,
      -                        @Cached PythonObjectFactory.Lazy factory) {
      +                        @Cached InlinedBranchProfile createProfile,
      +                        @Cached PyNumberOrNode orNode) {
                   if (self.getParameters() == null) {
      -                self.setParameters(factory.get(inliningTarget).createTuple(GenericTypeNodes.makeParameters(self.getArgs())));
      +                createProfile.enter(inliningTarget);
      +                self.setParameters(PFactory.createTuple(PythonLanguage.get(inliningTarget), GenericTypeNodes.makeParameters(self.getArgs())));
                   }
                   Object[] newargs = GenericTypeNodes.subsParameters(this, self, self.getArgs(), self.getParameters(), item);
                   Object result = newargs[0];
                   for (int i = 1; i < newargs.length; i++) {
      -                result = orNode.executeObject(frame, result, newargs[i]);
      +                result = orNode.execute(frame, result, newargs[i]);
                   }
                   return result;
               }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/BytecodeCodeUnit.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/BytecodeCodeUnit.java
      new file mode 100644
      index 0000000000..8e4c3acede
      --- /dev/null
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/BytecodeCodeUnit.java
      @@ -0,0 +1,685 @@
      +/*
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
      + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      + *
      + * The Universal Permissive License (UPL), Version 1.0
      + *
      + * Subject to the condition set forth below, permission is hereby granted to any
      + * person obtaining a copy of this software, associated documentation and/or
      + * data (collectively the "Software"), free of charge and under any and all
      + * copyright rights in the Software, and any and all patent rights owned or
      + * freely licensable by each licensor hereunder covering either (i) the
      + * unmodified Software as contributed to or provided by such licensor, or (ii)
      + * the Larger Works (as defined below), to deal in both
      + *
      + * (a) the Software, and
      + *
      + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
      + * one is included with the Software each a "Larger Work" to which the Software
      + * is contributed by such licensors),
      + *
      + * without restriction, including without limitation the rights to copy, create
      + * derivative works of, display, perform, and distribute the Software and make,
      + * use, sell, offer for sale, import, export, have made, and have sold the
      + * Software and the Larger Work(s), and to sublicense the foregoing rights on
      + * either these or other terms.
      + *
      + * This license is subject to the following condition:
      + *
      + * The above copyright notice and either this complete permission notice or at a
      + * minimum a reference to the UPL must be included in all copies or substantial
      + * portions of the Software.
      + *
      + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      + * SOFTWARE.
      + */
      +package com.oracle.graal.python.compiler;
      +
      +import java.util.ArrayDeque;
      +import java.util.ArrayList;
      +import java.util.Arrays;
      +import java.util.Collections;
      +import java.util.HashMap;
      +import java.util.List;
      +import java.util.Objects;
      +
      +import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      +import com.oracle.graal.python.builtins.objects.bytes.BytesUtils;
      +import com.oracle.graal.python.builtins.objects.code.PCode;
      +import com.oracle.graal.python.builtins.objects.str.StringNodes;
      +import com.oracle.graal.python.compiler.OpCodes.CollectionBits;
      +import com.oracle.graal.python.nodes.ErrorMessages;
      +import com.oracle.graal.python.nodes.PRaiseNode;
      +import com.oracle.graal.python.util.PythonUtils;
      +import com.oracle.truffle.api.CompilerDirectives;
      +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
      +import com.oracle.truffle.api.nodes.Node;
      +import com.oracle.truffle.api.strings.TruffleString;
      +
      +public final class BytecodeCodeUnit extends CodeUnit {
      +    private static final int DISASSEMBLY_NUM_COLUMNS = 8;
      +
      +    // Note this is being mutated when quickening
      +    @CompilationFinal(dimensions = 1) public final byte[] code;
      +    @CompilationFinal(dimensions = 1) public final byte[] srcOffsetTable;
      +    @CompilationFinal(dimensions = 1) public final long[] primitiveConstants;
      +    @CompilationFinal(dimensions = 1) public final int[] exceptionHandlerRanges;
      +    public final int stacksize;
      +    public final int conditionProfileCount;
      +
      +    /* Quickening data. See docs in PBytecodeRootNode */
      +    @CompilationFinal(dimensions = 1) public final byte[] outputCanQuicken;
      +    @CompilationFinal(dimensions = 1) public final byte[] variableShouldUnbox;
      +    @CompilationFinal(dimensions = 1) public final int[][] generalizeInputsMap;
      +    @CompilationFinal(dimensions = 1) public final int[][] generalizeVarsMap;
      +
      +    /* Lazily initialized source map */
      +    @CompilationFinal SourceMap sourceMap;
      +
      +    public BytecodeCodeUnit(TruffleString name, TruffleString qualname,
      +                    int argCount, int kwOnlyArgCount, int positionalOnlyArgCount, int flags,
      +                    TruffleString[] names, TruffleString[] varnames, TruffleString[] cellvars,
      +                    TruffleString[] freevars, int[] cell2arg, Object[] constants, int startLine, int startColumn,
      +                    int endLine, int endColumn,
      +                    byte[] code, byte[] linetable,
      +                    long[] primitiveConstants, int[] exceptionHandlerRanges, int stacksize, int conditionProfileCount,
      +                    byte[] outputCanQuicken, byte[] variableShouldUnbox, int[][] generalizeInputsMap, int[][] generalizeVarsMap) {
      +        super(name, qualname, argCount, kwOnlyArgCount, positionalOnlyArgCount, flags, names, varnames, cellvars, freevars, cell2arg, constants, startLine, startColumn, endLine, endColumn);
      +        this.code = code;
      +        this.srcOffsetTable = linetable;
      +        this.primitiveConstants = primitiveConstants;
      +        this.exceptionHandlerRanges = exceptionHandlerRanges;
      +        this.stacksize = stacksize;
      +        this.conditionProfileCount = conditionProfileCount;
      +        this.outputCanQuicken = outputCanQuicken;
      +        this.variableShouldUnbox = variableShouldUnbox;
      +        this.generalizeInputsMap = generalizeInputsMap;
      +        this.generalizeVarsMap = generalizeVarsMap;
      +    }
      +
      +    public SourceMap getSourceMap() {
      +        if (sourceMap == null) {
      +            CompilerDirectives.transferToInterpreterAndInvalidate();
      +            sourceMap = new SourceMap(code, srcOffsetTable, startLine, startColumn);
      +        }
      +        return sourceMap;
      +    }
      +
      +    public int bciToLine(int bci) {
      +        if (bci < 0 || bci >= code.length) {
      +            return -1;
      +        }
      +        return getSourceMap().startLineMap[bci];
      +    }
      +
      +    public int bciToColumn(int bci) {
      +        if (bci < 0 || bci >= code.length) {
      +            return -1;
      +        }
      +        return getSourceMap().startColumnMap[bci];
      +    }
      +
      +    @Override
      +    protected void dumpBytecode(StringBuilder sb, boolean quickened) {
      +        int bci = 0;
      +        int oparg = 0;
      +        SourceMap map = getSourceMap();
      +        HashMap lines = new HashMap<>();
      +        while (bci < code.length) {
      +            int bcBCI = bci;
      +            OpCodes opcode = OpCodes.fromOpCode(code[bci++]);
      +
      +            if (!quickened) {
      +                opcode = unquicken(opcode);
      +            }
      +
      +            String[] line = lines.computeIfAbsent(bcBCI, k -> new String[DISASSEMBLY_NUM_COLUMNS]);
      +            line[0] = String.format("%3d:%-3d - %3d:%-3d", map.startLineMap[bcBCI], map.startColumnMap[bcBCI], map.endLineMap[bcBCI], map.endColumnMap[bcBCI]);
      +            if (line[1] == null) {
      +                line[1] = "";
      +            }
      +            line[2] = String.valueOf(bcBCI);
      +            line[3] = opcode.toString();
      +            byte[] followingArgs = PythonUtils.EMPTY_BYTE_ARRAY;
      +            if (!opcode.hasArg()) {
      +                line[4] = "";
      +            } else {
      +                oparg |= Byte.toUnsignedInt(code[bci++]);
      +                if (opcode.argLength > 1) {
      +                    followingArgs = new byte[opcode.argLength - 1];
      +                    for (int i = 0; i < opcode.argLength - 1; i++) {
      +                        followingArgs[i] = code[bci++];
      +                    }
      +                }
      +                line[4] = String.format("% 2d", oparg);
      +            }
      +
      +            while (true) {
      +                switch (opcode) {
      +                    case EXTENDED_ARG:
      +                        line[4] = "";
      +                        break;
      +                    case LOAD_BYTE:
      +                        line[4] = String.format("% 2d", (byte) oparg);
      +                        break;
      +                    case LOAD_CONST:
      +                    case LOAD_BIGINT:
      +                    case LOAD_STRING:
      +                    case LOAD_BYTES:
      +                    case LOAD_CONST_COLLECTION:
      +                    case MAKE_KEYWORD: {
      +                        Object constant = constants[oparg];
      +                        if (constant instanceof CodeUnit) {
      +                            line[5] = ((CodeUnit) constant).qualname.toJavaStringUncached();
      +                        } else {
      +                            if (constant instanceof TruffleString) {
      +                                line[5] = StringNodes.StringReprNode.getUncached().execute((TruffleString) constant).toJavaStringUncached();
      +                            } else if (constant instanceof byte[]) {
      +                                byte[] bytes = (byte[]) constant;
      +                                line[5] = BytesUtils.bytesRepr(bytes, bytes.length);
      +                            } else if (constant instanceof int[]) {
      +                                line[5] = Arrays.toString((int[]) constant);
      +                            } else if (constant instanceof long[]) {
      +                                line[5] = Arrays.toString((long[]) constant);
      +                            } else if (constant instanceof boolean[]) {
      +                                line[5] = Arrays.toString((boolean[]) constant);
      +                            } else if (constant instanceof double[]) {
      +                                line[5] = Arrays.toString((double[]) constant);
      +                            } else if (constant instanceof Object[]) {
      +                                line[5] = Arrays.toString((Object[]) constant);
      +                            } else {
      +                                line[5] = Objects.toString(constant);
      +                            }
      +                        }
      +                        if (opcode == OpCodes.LOAD_CONST_COLLECTION) {
      +                            line[5] += " type " + collectionTypeToString(followingArgs[0]) + " into " + collectionKindToString(followingArgs[0]);
      +                        }
      +                        break;
      +                    }
      +                    case MAKE_FUNCTION: {
      +                        line[4] = String.format("% 2d", followingArgs[0]);
      +                        CodeUnit codeUnit = (CodeUnit) constants[oparg];
      +                        line[5] = line[5] = codeUnit.qualname.toJavaStringUncached();
      +                        break;
      +                    }
      +                    case LOAD_INT:
      +                    case LOAD_LONG:
      +                        line[5] = Objects.toString(primitiveConstants[oparg]);
      +                        break;
      +                    case LOAD_DOUBLE:
      +                        line[5] = Objects.toString(Double.longBitsToDouble(primitiveConstants[oparg]));
      +                        break;
      +                    case LOAD_COMPLEX: {
      +                        double[] num = (double[]) constants[oparg];
      +                        if (num[0] == 0.0) {
      +                            line[5] = String.format("%gj", num[1]);
      +                        } else {
      +                            line[5] = String.format("%g%+gj", num[0], num[1]);
      +                        }
      +                        break;
      +                    }
      +                    case LOAD_CLOSURE:
      +                    case LOAD_DEREF:
      +                    case STORE_DEREF:
      +                    case DELETE_DEREF:
      +                        if (oparg >= cellvars.length) {
      +                            line[5] = freevars[oparg - cellvars.length].toJavaStringUncached();
      +                        } else {
      +                            line[5] = cellvars[oparg].toJavaStringUncached();
      +                        }
      +                        break;
      +                    case LOAD_FAST:
      +                    case STORE_FAST:
      +                    case DELETE_FAST:
      +                        line[5] = varnames[oparg].toJavaStringUncached();
      +                        break;
      +                    case LOAD_NAME:
      +                    case LOAD_METHOD:
      +                    case STORE_NAME:
      +                    case DELETE_NAME:
      +                    case IMPORT_NAME:
      +                    case IMPORT_FROM:
      +                    case LOAD_GLOBAL:
      +                    case STORE_GLOBAL:
      +                    case DELETE_GLOBAL:
      +                    case LOAD_ATTR:
      +                    case STORE_ATTR:
      +                    case DELETE_ATTR:
      +                        line[5] = names[oparg].toJavaStringUncached();
      +                        break;
      +                    case FORMAT_VALUE: {
      +                        int type = oparg & FormatOptions.FVC_MASK;
      +                        switch (type) {
      +                            case FormatOptions.FVC_STR:
      +                                line[5] = "STR";
      +                                break;
      +                            case FormatOptions.FVC_REPR:
      +                                line[5] = "REPR";
      +                                break;
      +                            case FormatOptions.FVC_ASCII:
      +                                line[5] = "ASCII";
      +                                break;
      +                            case FormatOptions.FVC_NONE:
      +                                line[5] = "NONE";
      +                                break;
      +                        }
      +                        if ((oparg & FormatOptions.FVS_MASK) == FormatOptions.FVS_HAVE_SPEC) {
      +                            line[5] += " + SPEC";
      +                        }
      +                        break;
      +                    }
      +                    case CALL_METHOD: {
      +                        line[4] = String.format("% 2d", oparg);
      +                        break;
      +                    }
      +                    case UNARY_OP:
      +                        line[5] = UnaryOps.values()[oparg].toString();
      +                        break;
      +                    case BINARY_OP:
      +                        line[5] = BinaryOps.values()[oparg].toString();
      +                        break;
      +                    case COLLECTION_FROM_STACK:
      +                    case COLLECTION_ADD_STACK:
      +                    case COLLECTION_FROM_COLLECTION:
      +                    case COLLECTION_ADD_COLLECTION:
      +                    case ADD_TO_COLLECTION:
      +                        line[4] = String.format("% 2d", CollectionBits.elementCount(oparg));
      +                        line[5] = collectionKindToString(oparg);
      +                        break;
      +                    case UNPACK_EX:
      +                        line[5] = String.format("%d, %d", oparg, Byte.toUnsignedInt(followingArgs[0]));
      +                        break;
      +                    case JUMP_BACKWARD:
      +                        lines.computeIfAbsent(bcBCI - oparg, k -> new String[DISASSEMBLY_NUM_COLUMNS])[1] = ">>";
      +                        line[5] = String.format("to %d", bcBCI - oparg);
      +                        break;
      +                    case FOR_ITER:
      +                    case JUMP_FORWARD:
      +                    case POP_AND_JUMP_IF_FALSE:
      +                    case POP_AND_JUMP_IF_TRUE:
      +                    case JUMP_IF_FALSE_OR_POP:
      +                    case JUMP_IF_TRUE_OR_POP:
      +                    case MATCH_EXC_OR_JUMP:
      +                    case SEND:
      +                    case THROW:
      +                        lines.computeIfAbsent(bcBCI + oparg, k -> new String[DISASSEMBLY_NUM_COLUMNS])[1] = ">>";
      +                        line[5] = String.format("to %d", bcBCI + oparg);
      +                        break;
      +                    default:
      +                        if (opcode.quickens != null) {
      +                            opcode = opcode.quickens;
      +                            continue;
      +                        }
      +                }
      +                if (opcode == OpCodes.EXTENDED_ARG) {
      +                    oparg <<= 8;
      +                } else {
      +                    oparg = 0;
      +                }
      +                break;
      +            }
      +        }
      +
      +        for (int i = 0; i < exceptionHandlerRanges.length; i += 4) {
      +            int start = exceptionHandlerRanges[i];
      +            int stop = exceptionHandlerRanges[i + 1];
      +            int handler = exceptionHandlerRanges[i + 2];
      +            int stackAtHandler = exceptionHandlerRanges[i + 3];
      +            String[] line = lines.get(handler);
      +            assert line != null;
      +            String handlerStr = String.format("exc handler %d - %d; stack: %d", start, stop, stackAtHandler);
      +            if (line[6] == null) {
      +                line[6] = handlerStr;
      +            } else {
      +                line[6] += " | " + handlerStr;
      +            }
      +        }
      +
      +        for (bci = 0; bci < code.length; bci++) {
      +            String[] line = lines.get(bci);
      +            if (line != null) {
      +                line[5] = line[5] == null ? "" : String.format("(%s)", line[5]);
      +                line[6] = line[6] == null ? "" : String.format("(%s)", line[6]);
      +                line[7] = "";
      +                if (outputCanQuicken != null && (outputCanQuicken[bci] != 0 || generalizeInputsMap[bci] != null)) {
      +                    StringBuilder quickenSb = new StringBuilder();
      +                    if (outputCanQuicken[bci] != 0) {
      +                        quickenSb.append("can quicken");
      +                    }
      +                    if (generalizeInputsMap[bci] != null) {
      +                        if (quickenSb.length() > 0) {
      +                            quickenSb.append(", ");
      +                        }
      +                        quickenSb.append("generalizes: ");
      +                        for (int i = 0; i < generalizeInputsMap[bci].length; i++) {
      +                            if (i > 0) {
      +                                quickenSb.append(", ");
      +                            }
      +                            quickenSb.append(generalizeInputsMap[bci][i]);
      +                        }
      +                    }
      +                    line[7] = quickenSb.toString();
      +                }
      +                String formatted = String.format("%-8s %2s %4s %-32s %-3s   %-32s %s %s", (Object[]) line);
      +                sb.append(formatted.stripTrailing());
      +                sb.append('\n');
      +            }
      +        }
      +    }
      +
      +    private static String collectionKindToString(int oparg) {
      +        switch (CollectionBits.collectionKind(oparg)) {
      +            case CollectionBits.KIND_LIST:
      +                return "list";
      +            case CollectionBits.KIND_TUPLE:
      +                return "tuple";
      +            case CollectionBits.KIND_SET:
      +                return "set";
      +            case CollectionBits.KIND_DICT:
      +                return "dict";
      +            case CollectionBits.KIND_KWORDS:
      +                return "PKeyword[]";
      +            case CollectionBits.KIND_OBJECT:
      +                return "Object[]";
      +        }
      +        throw new IllegalStateException("Unknown kind");
      +    }
      +
      +    private static String collectionTypeToString(int oparg) {
      +        switch (CollectionBits.elementType(oparg)) {
      +            case CollectionBits.ELEMENT_BOOLEAN:
      +                return "boolean";
      +            case CollectionBits.ELEMENT_INT:
      +                return "int";
      +            case CollectionBits.ELEMENT_LONG:
      +                return "long";
      +            case CollectionBits.ELEMENT_DOUBLE:
      +                return "double";
      +            case CollectionBits.ELEMENT_OBJECT:
      +                return "Object";
      +        }
      +        throw new IllegalStateException("Unknown type");
      +    }
      +
      +    public static final int LINE_TO_BCI_LINE_AFTER_CODEBLOCK = -1;
      +    public static final int LINE_TO_BCI_LINE_BEFORE_CODEBLOCK = -2;
      +
      +    // -1 for line after the code block, -2 for line before the code block, line number otherwise
      +    public int lineToBci(int line) {
      +        if (startLine == line) {
      +            return 0;
      +        }
      +        if ((flags & PCode.CO_GRAALPYHON_MODULE) != 0 && line < startLine) {
      +            // allow jump to the first line of a file, even if it is a comment
      +            return 0;
      +        }
      +        int[] map = getSourceMap().startLineMap;
      +        int bestBci = LINE_TO_BCI_LINE_AFTER_CODEBLOCK;
      +        int lineDiff = Integer.MAX_VALUE;
      +        boolean afterFirst = false;
      +        for (int bci = 0; bci < map.length; ++bci) {
      +            if (map[bci] >= line) {
      +                int lineDiff2 = map[bci] - line;
      +                // the first bci found is the start of the line
      +                if (lineDiff2 < lineDiff) {
      +                    bestBci = bci;
      +                    lineDiff = lineDiff2;
      +                }
      +            }
      +            if (map[bci] > 0 && map[bci] <= line) {
      +                // the line is actually within the codeblock.
      +                afterFirst = true;
      +            }
      +        }
      +        // bestBci being -1 means the line is outside the code block
      +        return afterFirst ? bestBci : LINE_TO_BCI_LINE_BEFORE_CODEBLOCK;
      +    }
      +
      +    public enum StackItem {
      +        With("the body of a with statement"),
      +        Iterable("the body of a for loop"),
      +        Except("an 'except' block as there's no exception"),
      +        Object("Incompatible stack");
      +
      +        public final String error;
      +
      +        StackItem(String error) {
      +            this.error = error;
      +        }
      +
      +        ArrayList push(ArrayList v) {
      +            ArrayList ret = v == null ? new ArrayList<>() : new ArrayList<>(v);
      +            ret.add(this);
      +            return ret;
      +        }
      +    }
      +
      +    private void setNextStack(ArrayDeque todo, List> stacks, int target, ArrayList value) {
      +        ArrayList blocksAtTarget = stacks.get(target);
      +        if (blocksAtTarget == null) {
      +            stacks.set(target, value);
      +            todo.addLast(target);
      +        } else {
      +            assert value.equals(blocksAtTarget) : "found conflicting stacks depending on code path: " + this.name + "\t at " + target;
      +        }
      +    }
      +
      +    private static ArrayList popStack(ArrayList blocks) {
      +        assert blocks != null : "Pop from null stack";
      +        assert blocks.size() >= 1 : "Pop from empty stack";
      +        return new ArrayList<>(blocks.subList(0, blocks.size() - 1));
      +    }
      +
      +    // returns null if the jump is fine
      +    public String checkJump(Node node, List> stackElems, int from, int to) {
      +        ArrayList blkFrom = stackElems.get(from);
      +        if (blkFrom == null) {
      +            // this should not happen
      +            throw PRaiseNode.raiseStatic(node, PythonBuiltinClassType.ValueError, ErrorMessages.LINE_D_COMES_BEFORE_THE_CURRENT_CODE_BLOCK, bciToLine(from));
      +        }
      +        ArrayList blkTo = stackElems.get(to);
      +        if (blkTo == null) {
      +            throw PRaiseNode.raiseStatic(node, PythonBuiltinClassType.ValueError, ErrorMessages.LINE_D_COMES_AFTER_THE_CURRENT_CODE_BLOCK, bciToLine(from));
      +        }
      +        if (blkTo.size() > blkFrom.size()) {
      +            return blkTo.get(blkTo.size() - 1).error;
      +        }
      +        for (int i = blkTo.size() - 1; i >= 0; --i) {
      +            if (blkTo.get(i) != blkFrom.get(i)) {
      +                return blkTo.get(i).error;
      +            }
      +        }
      +        return null;
      +    }
      +
      +    public List> computeStackElems() {
      +        List> blocks = new ArrayList<>(Collections.nCopies(code.length + 1, null));
      +        blocks.set(0, new ArrayList<>());
      +        ArrayDeque todo = new ArrayDeque<>();
      +        todo.addFirst(0);
      +        while (!todo.isEmpty()) {
      +            int firstBci = todo.removeLast();
      +            assert blocks.get(firstBci) != null : "Reached block without determining its stack state";
      +            opCodeAt(code, firstBci, (bci, op, oparg, followingArgs) -> {
      +                // firstBci can be different from bci if EXTEND_ARG is used
      +                // the stack is kept both at firstBci and bci
      +                ArrayList next = blocks.get(firstBci);
      +                if (firstBci != bci) {
      +                    blocks.set(bci, next);
      +                }
      +                for (int j = 0; j < exceptionHandlerRanges.length; j += 4) {
      +                    int start = exceptionHandlerRanges[j];
      +                    int handler = exceptionHandlerRanges[j + 2];
      +                    int stack = exceptionHandlerRanges[j + 3];
      +                    if (start == bci) {
      +                        ArrayList handlerStack = StackItem.Except.push(new ArrayList<>(blocks.get(bci).subList(0, stack)));
      +                        // an exception handler is like a jump
      +                        // the except block is added in the lines below
      +                        setNextStack(todo, blocks, handler, handlerStack);
      +                    }
      +                }
      +                switch (op) {
      +                    case GET_ITER:
      +                    case GET_AITER:
      +                        next = StackItem.Iterable.push(popStack(blocks.get(bci)));
      +                        setNextStack(todo, blocks, bci + 1, next);
      +                        break;
      +                    case FOR_ITER:
      +                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), StackItem.Object.push(next));
      +                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, true), popStack(next));
      +                        break;
      +                    case PUSH_EXC_INFO:
      +                        next = StackItem.Except.push(StackItem.Object.push(popStack(blocks.get(bci))));
      +                        setNextStack(todo, blocks, bci + 1, next);
      +                        break;
      +                    case MATCH_EXC_OR_JUMP:
      +                        next = popStack(next);
      +                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), next);
      +                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, true), next);
      +                        break;
      +                    case SETUP_WITH:
      +                    case SETUP_AWITH:
      +                        next = StackItem.Object.push(StackItem.With.push(blocks.get(bci)));
      +                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), next);
      +                        break;
      +                    case GET_AEXIT_CORO:
      +                        next = StackItem.Object.push(StackItem.Except.push(popStack(popStack(popStack(blocks.get(bci))))));
      +                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), next);
      +                        break;
      +                    case DUP_TOP:
      +                        next = next.get(next.size() - 1).push(next);
      +                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), next);
      +                        break;
      +                    case ROT_TWO: {
      +                        StackItem top = next.get(next.size() - 1);
      +                        StackItem belowTop = next.get(next.size() - 2);
      +                        next = belowTop.push(top.push(popStack(popStack(next))));
      +                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), next);
      +                        break;
      +                    }
      +                    case ROT_THREE: {
      +                        StackItem top = next.get(next.size() - 1);
      +                        StackItem second = next.get(next.size() - 2);
      +                        StackItem third = next.get(next.size() - 3);
      +                        next = second.push(third.push(top.push(top.push(popStack(popStack(popStack(next)))))));
      +                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), next);
      +                        break;
      +                    }
      +                    case LOAD_NONE:
      +                        opCodeAt(code, op.getNextBci(bci, oparg, false), (ignored, nextOp, ignored2, ignored3) -> {
      +                            // Usually, when compiling bytecode around exception handlers, the code
      +                            // is generated twice, once for the path with no exception, and
      +                            // once for the path with the exception. However, when generating code
      +                            // for a with statement exit, the code is generated as follows (and in a
      +                            // similar manner for async with).
      +                            // ...
      +                            // LOAD_NONE
      +                            // EXIT_WITH (exception handler starts here)
      +                            // ...
      +                            // This means that setting the stack at EXIT_WITH to have Object on top,
      +                            // as LOAD_NONE usually would, would cause a conflict with the exception
      +                            // handler starting at that position, which has the stack top be an
      +                            // Exception.
      +                            if (nextOp != OpCodes.GET_AEXIT_CORO && nextOp != OpCodes.EXIT_WITH) {
      +                                setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), StackItem.Object.push(blocks.get(bci)));
      +                            }
      +                        });
      +                        break;
      +
      +                    default: {
      +                        int nextWJump = op.getNextBci(bci, oparg, true);
      +                        int nextWOJump = op.getNextBci(bci, oparg, false);
      +                        int stackLostWJump = op.getNumberOfConsumedStackItems(oparg, followingArgs, true);
      +                        int stackLostWOJump = op.getNumberOfConsumedStackItems(oparg, followingArgs, false);
      +                        int stackGainWJump = op.getNumberOfProducedStackItems(oparg, followingArgs, true);
      +                        int stackGainWOJump = op.getNumberOfProducedStackItems(oparg, followingArgs, false);
      +                        handleGeneralOp(blocks, todo, bci, nextWJump, stackLostWJump, stackGainWJump);
      +                        if (nextWJump != nextWOJump) {
      +                            handleGeneralOp(blocks, todo, bci, nextWOJump, stackLostWOJump, stackGainWOJump);
      +                        }
      +                        break;
      +                    }
      +                }
      +            });
      +        }
      +        return blocks;
      +    }
      +
      +    private void handleGeneralOp(List> blocks, ArrayDeque todo, int bci, int next, int stackLost, int stackGain) {
      +        if (next >= 0) {
      +            ArrayList blocksHere = new ArrayList<>(blocks.get(bci));
      +            for (int k = 0; k < stackLost; ++k) {
      +                blocksHere.remove(blocksHere.size() - 1);
      +            }
      +            for (int k = 0; k < stackGain; ++k) {
      +                blocksHere.add(StackItem.Object);
      +            }
      +            setNextStack(todo, blocks, next, blocksHere);
      +        }
      +    }
      +
      +    @FunctionalInterface
      +    public interface BytecodeAction {
      +        void run(int bci, OpCodes op, int oparg, byte[] followingArgs);
      +    }
      +
      +    // returns the following bci
      +    private static int opCodeAt(byte[] bytecode, int bci, BytecodeAction action) {
      +        int oparg = 0;
      +        OpCodes op = OpCodes.fromOpCode(bytecode[bci]);
      +        while (op == OpCodes.EXTENDED_ARG) {
      +            oparg |= Byte.toUnsignedInt(bytecode[bci + 1]);
      +            oparg <<= 8;
      +            bci += 2;
      +            op = OpCodes.fromOpCode(bytecode[bci]);
      +        }
      +        op = unquicken(op);
      +        byte[] followingArgs = null;
      +        if (op.argLength > 0) {
      +            oparg |= Byte.toUnsignedInt(bytecode[bci + 1]);
      +            if (op.argLength > 1) {
      +                followingArgs = new byte[op.argLength - 1];
      +                System.arraycopy(bytecode, bci + 2, followingArgs, 0, followingArgs.length);
      +            }
      +        }
      +        action.run(bci, op, oparg, followingArgs);
      +        return bci + op.length();
      +    }
      +
      +    public static void iterateBytecode(byte[] bytecode, BytecodeAction action) {
      +        for (int bci = 0; bci < bytecode.length;) {
      +            bci = opCodeAt(bytecode, bci, action);
      +        }
      +    }
      +
      +    public void iterateBytecode(BytecodeAction action) {
      +        iterateBytecode(code, action);
      +    }
      +
      +    public byte[] getBytecodeForSerialization() {
      +        byte[] bytecode = Arrays.copyOf(code, code.length);
      +        for (int bci = 0; bci < bytecode.length;) {
      +            OpCodes op = OpCodes.fromOpCode(bytecode[bci]);
      +            bytecode[bci] = (byte) unquicken(op).ordinal();
      +            bci += op.length();
      +        }
      +        return bytecode;
      +    }
      +
      +    private static OpCodes unquicken(OpCodes op) {
      +        if (op.quickens == null) {
      +            return op;
      +        }
      +        return switch (op.quickens) {
      +            // These are already quickened by the compiler, so keep them quickened
      +            // See CompilationUnit.emitBytecode
      +            case LOAD_BYTE, LOAD_INT, LOAD_LONG, LOAD_DOUBLE, LOAD_TRUE, LOAD_FALSE -> op;
      +            default -> op.quickens;
      +        };
      +    }
      +}
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/CodeUnit.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/CodeUnit.java
      index a9f29ef5fb..2f671177bd 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/CodeUnit.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/CodeUnit.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,23 +40,12 @@
        */
       package com.oracle.graal.python.compiler;
       
      -import java.util.ArrayDeque;
       import java.util.ArrayList;
       import java.util.Arrays;
      -import java.util.Collections;
      -import java.util.HashMap;
       import java.util.List;
      -import java.util.Objects;
       
      -import com.oracle.graal.python.builtins.PythonBuiltinClassType;
      -import com.oracle.graal.python.builtins.objects.bytes.BytesUtils;
       import com.oracle.graal.python.builtins.objects.code.PCode;
      -import com.oracle.graal.python.builtins.objects.str.StringNodes;
      -import com.oracle.graal.python.compiler.OpCodes.CollectionBits;
      -import com.oracle.graal.python.nodes.ErrorMessages;
      -import com.oracle.graal.python.nodes.PRaiseNode;
      -import com.oracle.graal.python.util.PythonUtils;
      -import com.oracle.truffle.api.CompilerDirectives;
      +import com.oracle.graal.python.builtins.objects.function.Signature;
       import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
       import com.oracle.truffle.api.source.Source;
       import com.oracle.truffle.api.source.SourceSection;
      @@ -67,9 +56,7 @@
        * bytecode and all the related data, like constants or exception handler ranges. It doesn't contain
        * the filename to make it easier to keep in native images.
        */
      -public final class CodeUnit {
      -    private static final int DISASSEMBLY_NUM_COLUMNS = 8;
      -
      +public abstract class CodeUnit {
           public final TruffleString name;
           public final TruffleString qualname;
       
      @@ -77,10 +64,6 @@ public final class CodeUnit {
           public final int kwOnlyArgCount;
           public final int positionalOnlyArgCount;
       
      -    public final int stacksize;
      -
      -    @CompilationFinal(dimensions = 1) public final byte[] code;
      -    @CompilationFinal(dimensions = 1) public final byte[] srcOffsetTable;
           public final int flags;
       
           @CompilationFinal(dimensions = 1) public final TruffleString[] names;
      @@ -91,42 +74,22 @@ public final class CodeUnit {
           @CompilationFinal(dimensions = 1) public final int[] arg2cell;
       
           @CompilationFinal(dimensions = 1) public final Object[] constants;
      -    @CompilationFinal(dimensions = 1) public final long[] primitiveConstants;
      -
      -    @CompilationFinal(dimensions = 1) public final int[] exceptionHandlerRanges;
      -
      -    public final int conditionProfileCount;
       
           public final int startLine;
           public final int startColumn;
           public final int endLine;
           public final int endColumn;
       
      -    /* Lazily initialized source map */
      -    @CompilationFinal SourceMap sourceMap;
      -
      -    /* Quickening data. See docs in PBytecodeRootNode */
      -    @CompilationFinal(dimensions = 1) public final byte[] outputCanQuicken;
      -    @CompilationFinal(dimensions = 1) public final byte[] variableShouldUnbox;
      -    @CompilationFinal(dimensions = 1) public final int[][] generalizeInputsMap;
      -    @CompilationFinal(dimensions = 1) public final int[][] generalizeVarsMap;
      -
           public CodeUnit(TruffleString name, TruffleString qualname,
      -                    int argCount, int kwOnlyArgCount, int positionalOnlyArgCount, int stacksize,
      -                    byte[] code, byte[] linetable, int flags,
      -                    TruffleString[] names, TruffleString[] varnames, TruffleString[] cellvars, TruffleString[] freevars, int[] cell2arg,
      -                    Object[] constants, long[] primitiveConstants,
      -                    int[] exceptionHandlerRanges, int conditionProfileCount,
      -                    int startLine, int startColumn, int endLine, int endColumn,
      -                    byte[] outputCanQuicken, byte[] variableShouldUnbox, int[][] generalizeInputsMap, int[][] generalizeVarsMap) {
      +                    int argCount, int kwOnlyArgCount, int positionalOnlyArgCount, int flags,
      +                    TruffleString[] names, TruffleString[] varnames, TruffleString[] cellvars,
      +                    TruffleString[] freevars, int[] cell2arg, Object[] constants, int startLine, int startColumn,
      +                    int endLine, int endColumn) {
               this.name = name;
               this.qualname = qualname != null ? qualname : name;
               this.argCount = argCount;
               this.kwOnlyArgCount = kwOnlyArgCount;
               this.positionalOnlyArgCount = positionalOnlyArgCount;
      -        this.stacksize = stacksize;
      -        this.code = code;
      -        this.srcOffsetTable = linetable;
               this.flags = flags;
               this.names = names;
               this.varnames = varnames;
      @@ -145,39 +108,11 @@ public CodeUnit(TruffleString name, TruffleString qualname,
               }
               this.arg2cell = arg2cellValue;
               this.constants = constants;
      -        this.primitiveConstants = primitiveConstants;
      -        this.exceptionHandlerRanges = exceptionHandlerRanges;
      -        this.conditionProfileCount = conditionProfileCount;
      +
               this.startLine = startLine;
               this.startColumn = startColumn;
               this.endLine = endLine;
               this.endColumn = endColumn;
      -        this.outputCanQuicken = outputCanQuicken;
      -        this.variableShouldUnbox = variableShouldUnbox;
      -        this.generalizeInputsMap = generalizeInputsMap;
      -        this.generalizeVarsMap = generalizeVarsMap;
      -    }
      -
      -    public SourceMap getSourceMap() {
      -        if (sourceMap == null) {
      -            CompilerDirectives.transferToInterpreterAndInvalidate();
      -            sourceMap = new SourceMap(code, srcOffsetTable, startLine, startColumn);
      -        }
      -        return sourceMap;
      -    }
      -
      -    public int bciToLine(int bci) {
      -        if (bci < 0 || bci >= code.length) {
      -            return -1;
      -        }
      -        return getSourceMap().startLineMap[bci];
      -    }
      -
      -    public int bciToColumn(int bci) {
      -        if (bci < 0 || bci >= code.length) {
      -            return -1;
      -        }
      -        return getSourceMap().startColumnMap[bci];
           }
       
           public SourceSection getSourceSection(Source source) {
      @@ -223,16 +158,31 @@ public int getTotalArgCount() {
               return count;
           }
       
      -    @SuppressWarnings("fallthrough")
      +    public final Signature computeSignature() {
      +        int posArgCount = argCount + positionalOnlyArgCount;
      +        TruffleString[] parameterNames = Arrays.copyOf(varnames, posArgCount);
      +        TruffleString[] kwOnlyNames = Arrays.copyOfRange(varnames, posArgCount, posArgCount + kwOnlyArgCount);
      +        int varArgsIndex = takesVarArgs() ? posArgCount : -1;
      +        return new Signature(positionalOnlyArgCount,
      +                        takesVarKeywordArgs(),
      +                        varArgsIndex,
      +                        parameterNames,
      +                        kwOnlyNames);
      +    }
      +
           @Override
           public String toString() {
      -        return toString(code);
      +        return toString(false);
           }
       
      -    public String toString(byte[] bytecode) {
      -        StringBuilder sb = new StringBuilder();
      +    protected abstract void dumpBytecode(StringBuilder sb, boolean optimized);
       
      -        HashMap lines = new HashMap<>();
      +    /**
      +     * @param optimized Whether to print the initial state of the bytecode or current state, if
      +     *            available, where some instructions may be transformed, e.g., quickened.
      +     */
      +    public String toString(boolean optimized) {
      +        StringBuilder sb = new StringBuilder();
       
               sb.append("Disassembly of ").append(qualname).append(":\n");
       
      @@ -250,541 +200,15 @@ public String toString(byte[] bytecode) {
                   sb.append("Flags: ").append(String.join(" | ", flagNames)).append("\n");
               }
       
      -        int bci = 0;
      -        int oparg = 0;
      -        SourceMap map = getSourceMap();
      -        while (bci < bytecode.length) {
      -            int bcBCI = bci;
      -            OpCodes opcode = OpCodes.fromOpCode(bytecode[bci++]);
      -
      -            String[] line = lines.computeIfAbsent(bcBCI, k -> new String[DISASSEMBLY_NUM_COLUMNS]);
      -            line[0] = String.format("%3d:%-3d - %3d:%-3d", map.startLineMap[bcBCI], map.startColumnMap[bcBCI], map.endLineMap[bcBCI], map.endColumnMap[bcBCI]);
      -            if (line[1] == null) {
      -                line[1] = "";
      -            }
      -            line[2] = String.valueOf(bcBCI);
      -            line[3] = opcode.toString();
      -            byte[] followingArgs = PythonUtils.EMPTY_BYTE_ARRAY;
      -            if (!opcode.hasArg()) {
      -                line[4] = "";
      -            } else {
      -                oparg |= Byte.toUnsignedInt(bytecode[bci++]);
      -                if (opcode.argLength > 1) {
      -                    followingArgs = new byte[opcode.argLength - 1];
      -                    for (int i = 0; i < opcode.argLength - 1; i++) {
      -                        followingArgs[i] = bytecode[bci++];
      -                    }
      -                }
      -                line[4] = String.format("% 2d", oparg);
      -            }
      -
      -            while (true) {
      -                switch (opcode) {
      -                    case EXTENDED_ARG:
      -                        line[4] = "";
      -                        break;
      -                    case LOAD_BYTE:
      -                        line[4] = String.format("% 2d", (byte) oparg);
      -                        break;
      -                    case LOAD_CONST:
      -                    case LOAD_BIGINT:
      -                    case LOAD_STRING:
      -                    case LOAD_BYTES:
      -                    case LOAD_CONST_COLLECTION:
      -                    case MAKE_KEYWORD: {
      -                        Object constant = constants[oparg];
      -                        if (constant instanceof CodeUnit) {
      -                            line[5] = ((CodeUnit) constant).qualname.toJavaStringUncached();
      -                        } else {
      -                            if (constant instanceof TruffleString) {
      -                                line[5] = StringNodes.StringReprNode.getUncached().execute((TruffleString) constant).toJavaStringUncached();
      -                            } else if (constant instanceof byte[]) {
      -                                byte[] bytes = (byte[]) constant;
      -                                line[5] = BytesUtils.bytesRepr(bytes, bytes.length);
      -                            } else if (constant instanceof int[]) {
      -                                line[5] = Arrays.toString((int[]) constant);
      -                            } else if (constant instanceof long[]) {
      -                                line[5] = Arrays.toString((long[]) constant);
      -                            } else if (constant instanceof boolean[]) {
      -                                line[5] = Arrays.toString((boolean[]) constant);
      -                            } else if (constant instanceof double[]) {
      -                                line[5] = Arrays.toString((double[]) constant);
      -                            } else if (constant instanceof Object[]) {
      -                                line[5] = Arrays.toString((Object[]) constant);
      -                            } else {
      -                                line[5] = Objects.toString(constant);
      -                            }
      -                        }
      -                        if (opcode == OpCodes.LOAD_CONST_COLLECTION) {
      -                            line[5] += " type " + collectionTypeToString(followingArgs[0]) + " into " + collectionKindToString(followingArgs[0]);
      -                        }
      -                        break;
      -                    }
      -                    case MAKE_FUNCTION: {
      -                        line[4] = String.format("% 2d", followingArgs[0]);
      -                        CodeUnit codeUnit = (CodeUnit) constants[oparg];
      -                        line[5] = line[5] = codeUnit.qualname.toJavaStringUncached();
      -                        break;
      -                    }
      -                    case LOAD_INT:
      -                    case LOAD_LONG:
      -                        line[5] = Objects.toString(primitiveConstants[oparg]);
      -                        break;
      -                    case LOAD_DOUBLE:
      -                        line[5] = Objects.toString(Double.longBitsToDouble(primitiveConstants[oparg]));
      -                        break;
      -                    case LOAD_COMPLEX: {
      -                        double[] num = (double[]) constants[oparg];
      -                        if (num[0] == 0.0) {
      -                            line[5] = String.format("%gj", num[1]);
      -                        } else {
      -                            line[5] = String.format("%g%+gj", num[0], num[1]);
      -                        }
      -                        break;
      -                    }
      -                    case LOAD_CLOSURE:
      -                    case LOAD_DEREF:
      -                    case STORE_DEREF:
      -                    case DELETE_DEREF:
      -                        if (oparg >= cellvars.length) {
      -                            line[5] = freevars[oparg - cellvars.length].toJavaStringUncached();
      -                        } else {
      -                            line[5] = cellvars[oparg].toJavaStringUncached();
      -                        }
      -                        break;
      -                    case LOAD_FAST:
      -                    case STORE_FAST:
      -                    case DELETE_FAST:
      -                        line[5] = varnames[oparg].toJavaStringUncached();
      -                        break;
      -                    case LOAD_NAME:
      -                    case LOAD_METHOD:
      -                    case STORE_NAME:
      -                    case DELETE_NAME:
      -                    case IMPORT_NAME:
      -                    case IMPORT_FROM:
      -                    case LOAD_GLOBAL:
      -                    case STORE_GLOBAL:
      -                    case DELETE_GLOBAL:
      -                    case LOAD_ATTR:
      -                    case STORE_ATTR:
      -                    case DELETE_ATTR:
      -                        line[5] = names[oparg].toJavaStringUncached();
      -                        break;
      -                    case FORMAT_VALUE: {
      -                        int type = oparg & FormatOptions.FVC_MASK;
      -                        switch (type) {
      -                            case FormatOptions.FVC_STR:
      -                                line[5] = "STR";
      -                                break;
      -                            case FormatOptions.FVC_REPR:
      -                                line[5] = "REPR";
      -                                break;
      -                            case FormatOptions.FVC_ASCII:
      -                                line[5] = "ASCII";
      -                                break;
      -                            case FormatOptions.FVC_NONE:
      -                                line[5] = "NONE";
      -                                break;
      -                        }
      -                        if ((oparg & FormatOptions.FVS_MASK) == FormatOptions.FVS_HAVE_SPEC) {
      -                            line[5] += " + SPEC";
      -                        }
      -                        break;
      -                    }
      -                    case CALL_METHOD: {
      -                        line[4] = String.format("% 2d", oparg);
      -                        break;
      -                    }
      -                    case UNARY_OP:
      -                        line[5] = UnaryOps.values()[oparg].toString();
      -                        break;
      -                    case BINARY_OP:
      -                        line[5] = BinaryOps.values()[oparg].toString();
      -                        break;
      -                    case COLLECTION_FROM_STACK:
      -                    case COLLECTION_ADD_STACK:
      -                    case COLLECTION_FROM_COLLECTION:
      -                    case COLLECTION_ADD_COLLECTION:
      -                    case ADD_TO_COLLECTION:
      -                        line[4] = String.format("% 2d", CollectionBits.elementCount(oparg));
      -                        line[5] = collectionKindToString(oparg);
      -                        break;
      -                    case UNPACK_EX:
      -                        line[5] = String.format("%d, %d", oparg, Byte.toUnsignedInt(followingArgs[0]));
      -                        break;
      -                    case JUMP_BACKWARD:
      -                        lines.computeIfAbsent(bcBCI - oparg, k -> new String[DISASSEMBLY_NUM_COLUMNS])[1] = ">>";
      -                        line[5] = String.format("to %d", bcBCI - oparg);
      -                        break;
      -                    case FOR_ITER:
      -                    case JUMP_FORWARD:
      -                    case POP_AND_JUMP_IF_FALSE:
      -                    case POP_AND_JUMP_IF_TRUE:
      -                    case JUMP_IF_FALSE_OR_POP:
      -                    case JUMP_IF_TRUE_OR_POP:
      -                    case MATCH_EXC_OR_JUMP:
      -                    case SEND:
      -                    case THROW:
      -                        lines.computeIfAbsent(bcBCI + oparg, k -> new String[DISASSEMBLY_NUM_COLUMNS])[1] = ">>";
      -                        line[5] = String.format("to %d", bcBCI + oparg);
      -                        break;
      -                    default:
      -                        if (opcode.quickens != null) {
      -                            opcode = opcode.quickens;
      -                            continue;
      -                        }
      -                }
      -                if (opcode == OpCodes.EXTENDED_ARG) {
      -                    oparg <<= 8;
      -                } else {
      -                    oparg = 0;
      -                }
      -                break;
      -            }
      -        }
      -
      -        for (int i = 0; i < exceptionHandlerRanges.length; i += 4) {
      -            int start = exceptionHandlerRanges[i];
      -            int stop = exceptionHandlerRanges[i + 1];
      -            int handler = exceptionHandlerRanges[i + 2];
      -            int stackAtHandler = exceptionHandlerRanges[i + 3];
      -            String[] line = lines.get(handler);
      -            assert line != null;
      -            String handlerStr = String.format("exc handler %d - %d; stack: %d", start, stop, stackAtHandler);
      -            if (line[6] == null) {
      -                line[6] = handlerStr;
      -            } else {
      -                line[6] += " | " + handlerStr;
      -            }
      -        }
      -
      -        for (bci = 0; bci < bytecode.length; bci++) {
      -            String[] line = lines.get(bci);
      -            if (line != null) {
      -                line[5] = line[5] == null ? "" : String.format("(%s)", line[5]);
      -                line[6] = line[6] == null ? "" : String.format("(%s)", line[6]);
      -                line[7] = "";
      -                if (outputCanQuicken != null && (outputCanQuicken[bci] != 0 || generalizeInputsMap[bci] != null)) {
      -                    StringBuilder quickenSb = new StringBuilder();
      -                    if (outputCanQuicken[bci] != 0) {
      -                        quickenSb.append("can quicken");
      -                    }
      -                    if (generalizeInputsMap[bci] != null) {
      -                        if (quickenSb.length() > 0) {
      -                            quickenSb.append(", ");
      -                        }
      -                        quickenSb.append("generalizes: ");
      -                        for (int i = 0; i < generalizeInputsMap[bci].length; i++) {
      -                            if (i > 0) {
      -                                quickenSb.append(", ");
      -                            }
      -                            quickenSb.append(generalizeInputsMap[bci][i]);
      -                        }
      -                    }
      -                    line[7] = quickenSb.toString();
      -                }
      -                String formatted = String.format("%-8s %2s %4s %-32s %-3s   %-32s %s %s", (Object[]) line);
      -                sb.append(formatted.stripTrailing());
      -                sb.append('\n');
      -            }
      -        }
      +        dumpBytecode(sb, optimized);
       
               for (Object c : constants) {
      -            if (c instanceof CodeUnit) {
      +            if (c instanceof CodeUnit cd) {
                       sb.append('\n');
      -                sb.append(c);
      +                sb.append(cd.toString(optimized));
                   }
               }
       
               return sb.toString();
           }
      -
      -    private static String collectionKindToString(int oparg) {
      -        switch (CollectionBits.collectionKind(oparg)) {
      -            case CollectionBits.KIND_LIST:
      -                return "list";
      -            case CollectionBits.KIND_TUPLE:
      -                return "tuple";
      -            case CollectionBits.KIND_SET:
      -                return "set";
      -            case CollectionBits.KIND_DICT:
      -                return "dict";
      -            case CollectionBits.KIND_KWORDS:
      -                return "PKeyword[]";
      -            case CollectionBits.KIND_OBJECT:
      -                return "Object[]";
      -        }
      -        throw new IllegalStateException("Unknown kind");
      -    }
      -
      -    private static String collectionTypeToString(int oparg) {
      -        switch (CollectionBits.elementType(oparg)) {
      -            case CollectionBits.ELEMENT_BOOLEAN:
      -                return "boolean";
      -            case CollectionBits.ELEMENT_INT:
      -                return "int";
      -            case CollectionBits.ELEMENT_LONG:
      -                return "long";
      -            case CollectionBits.ELEMENT_DOUBLE:
      -                return "double";
      -            case CollectionBits.ELEMENT_OBJECT:
      -                return "Object";
      -        }
      -        throw new IllegalStateException("Unknown type");
      -    }
      -
      -    public static final int LINE_TO_BCI_LINE_AFTER_CODEBLOCK = -1;
      -    public static final int LINE_TO_BCI_LINE_BEFORE_CODEBLOCK = -2;
      -
      -    // -1 for line after the code block, -2 for line before the code block, line number otherwise
      -    public int lineToBci(int line) {
      -        if (startLine == line) {
      -            return 0;
      -        }
      -        if ((flags & PCode.CO_GRAALPYHON_MODULE) != 0 && line < startLine) {
      -            // allow jump to the first line of a file, even if it is a comment
      -            return 0;
      -        }
      -        int[] map = getSourceMap().startLineMap;
      -        int bestBci = LINE_TO_BCI_LINE_AFTER_CODEBLOCK;
      -        int lineDiff = Integer.MAX_VALUE;
      -        boolean afterFirst = false;
      -        for (int bci = 0; bci < map.length; ++bci) {
      -            if (map[bci] >= line) {
      -                int lineDiff2 = map[bci] - line;
      -                // the first bci found is the start of the line
      -                if (lineDiff2 < lineDiff) {
      -                    bestBci = bci;
      -                    lineDiff = lineDiff2;
      -                }
      -            }
      -            if (map[bci] > 0 && map[bci] <= line) {
      -                // the line is actually within the codeblock.
      -                afterFirst = true;
      -            }
      -        }
      -        // bestBci being -1 means the line is outside the code block
      -        return afterFirst ? bestBci : LINE_TO_BCI_LINE_BEFORE_CODEBLOCK;
      -    }
      -
      -    public enum StackItem {
      -        With("the body of a with statement"),
      -        Iterable("the body of a for loop"),
      -        Except("an 'except' block as there's no exception"),
      -        Object("Incompatible stack");
      -
      -        public final String error;
      -
      -        StackItem(String error) {
      -            this.error = error;
      -        }
      -
      -        ArrayList push(ArrayList v) {
      -            ArrayList ret = v == null ? new ArrayList<>() : new ArrayList<>(v);
      -            ret.add(this);
      -            return ret;
      -        }
      -    }
      -
      -    private void setNextStack(ArrayDeque todo, List> stacks, int target, ArrayList value) {
      -        ArrayList blocksAtTarget = stacks.get(target);
      -        if (blocksAtTarget == null) {
      -            stacks.set(target, value);
      -            todo.addLast(target);
      -        } else {
      -            assert value.equals(blocksAtTarget) : "found conflicting stacks depending on code path: " + this.name + "\t at " + target;
      -        }
      -    }
      -
      -    private static ArrayList popStack(ArrayList blocks) {
      -        assert blocks != null : "Pop from null stack";
      -        assert blocks.size() >= 1 : "Pop from empty stack";
      -        return new ArrayList<>(blocks.subList(0, blocks.size() - 1));
      -    }
      -
      -    // returns null if the jump is fine
      -    public String checkJump(List> stackElems, int from, int to) {
      -        ArrayList blkFrom = stackElems.get(from);
      -        if (blkFrom == null) {
      -            // this should not happen
      -            PRaiseNode.getUncached().raise(PythonBuiltinClassType.ValueError, ErrorMessages.LINE_D_COMES_BEFORE_THE_CURRENT_CODE_BLOCK, bciToLine(from));
      -        }
      -        ArrayList blkTo = stackElems.get(to);
      -        if (blkTo == null) {
      -            PRaiseNode.getUncached().raise(PythonBuiltinClassType.ValueError, ErrorMessages.LINE_D_COMES_AFTER_THE_CURRENT_CODE_BLOCK, bciToLine(from));
      -        }
      -        if (blkTo.size() > blkFrom.size()) {
      -            return blkTo.get(blkTo.size() - 1).error;
      -        }
      -        for (int i = blkTo.size() - 1; i >= 0; --i) {
      -            if (blkTo.get(i) != blkFrom.get(i)) {
      -                return blkTo.get(i).error;
      -            }
      -        }
      -        return null;
      -    }
      -
      -    public List> computeStackElems() {
      -        List> blocks = new ArrayList<>(Collections.nCopies(code.length + 1, null));
      -        blocks.set(0, new ArrayList<>());
      -        ArrayDeque todo = new ArrayDeque<>();
      -        todo.addFirst(0);
      -        while (!todo.isEmpty()) {
      -            int firstBci = todo.removeLast();
      -            assert blocks.get(firstBci) != null : "Reached block without determining its stack state";
      -            opCodeAt(code, firstBci, (bci, op, oparg, followingArgs) -> {
      -                // firstBci can be different from bci if EXTEND_ARG is used
      -                // the stack is kept both at firstBci and bci
      -                ArrayList next = blocks.get(firstBci);
      -                if (firstBci != bci) {
      -                    blocks.set(bci, next);
      -                }
      -                for (int j = 0; j < exceptionHandlerRanges.length; j += 4) {
      -                    int start = exceptionHandlerRanges[j];
      -                    int handler = exceptionHandlerRanges[j + 2];
      -                    int stack = exceptionHandlerRanges[j + 3];
      -                    if (start == bci) {
      -                        ArrayList handlerStack = StackItem.Except.push(new ArrayList<>(blocks.get(bci).subList(0, stack)));
      -                        // an exception handler is like a jump
      -                        // the except block is added in the lines below
      -                        setNextStack(todo, blocks, handler, handlerStack);
      -                    }
      -                }
      -                switch (op) {
      -                    case GET_ITER:
      -                    case GET_AITER:
      -                        next = StackItem.Iterable.push(popStack(blocks.get(bci)));
      -                        setNextStack(todo, blocks, bci + 1, next);
      -                        break;
      -                    case FOR_ITER:
      -                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), StackItem.Object.push(next));
      -                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, true), popStack(next));
      -                        break;
      -                    case PUSH_EXC_INFO:
      -                        next = StackItem.Except.push(StackItem.Object.push(popStack(blocks.get(bci))));
      -                        setNextStack(todo, blocks, bci + 1, next);
      -                        break;
      -                    case MATCH_EXC_OR_JUMP:
      -                        next = popStack(next);
      -                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), next);
      -                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, true), next);
      -                        break;
      -                    case SETUP_WITH:
      -                    case SETUP_AWITH:
      -                        next = StackItem.Object.push(StackItem.With.push(blocks.get(bci)));
      -                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), next);
      -                        break;
      -                    case GET_AEXIT_CORO:
      -                        next = StackItem.Object.push(StackItem.Except.push(popStack(popStack(popStack(blocks.get(bci))))));
      -                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), next);
      -                        break;
      -                    case DUP_TOP:
      -                        next = next.get(next.size() - 1).push(next);
      -                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), next);
      -                        break;
      -                    case ROT_TWO: {
      -                        StackItem top = next.get(next.size() - 1);
      -                        StackItem belowTop = next.get(next.size() - 2);
      -                        next = belowTop.push(top.push(popStack(popStack(next))));
      -                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), next);
      -                        break;
      -                    }
      -                    case ROT_THREE: {
      -                        StackItem top = next.get(next.size() - 1);
      -                        StackItem second = next.get(next.size() - 2);
      -                        StackItem third = next.get(next.size() - 3);
      -                        next = second.push(third.push(top.push(top.push(popStack(popStack(popStack(next)))))));
      -                        setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), next);
      -                        break;
      -                    }
      -                    case LOAD_NONE:
      -                        opCodeAt(code, op.getNextBci(bci, oparg, false), (ignored, nextOp, ignored2, ignored3) -> {
      -                            // Usually, when compiling bytecode around exception handlers, the code
      -                            // is generated twice, once for the path with no exception, and
      -                            // once for the path with the exception. However, when generating code
      -                            // for a with statement exit, the code is generated as follows (and in a
      -                            // similar manner for async with).
      -                            // ...
      -                            // LOAD_NONE
      -                            // EXIT_WITH (exception handler starts here)
      -                            // ...
      -                            // This means that setting the stack at EXIT_WITH to have Object on top,
      -                            // as LOAD_NONE usually would, would cause a conflict with the exception
      -                            // handler starting at that position, which has the stack top be an
      -                            // Exception.
      -                            if (nextOp != OpCodes.GET_AEXIT_CORO && nextOp != OpCodes.EXIT_WITH) {
      -                                setNextStack(todo, blocks, op.getNextBci(bci, oparg, false), StackItem.Object.push(blocks.get(bci)));
      -                            }
      -                        });
      -                        break;
      -
      -                    default: {
      -                        int nextWJump = op.getNextBci(bci, oparg, true);
      -                        int nextWOJump = op.getNextBci(bci, oparg, false);
      -                        int stackLostWJump = op.getNumberOfConsumedStackItems(oparg, followingArgs, true);
      -                        int stackLostWOJump = op.getNumberOfConsumedStackItems(oparg, followingArgs, false);
      -                        int stackGainWJump = op.getNumberOfProducedStackItems(oparg, followingArgs, true);
      -                        int stackGainWOJump = op.getNumberOfProducedStackItems(oparg, followingArgs, false);
      -                        handleGeneralOp(blocks, todo, bci, nextWJump, stackLostWJump, stackGainWJump);
      -                        if (nextWJump != nextWOJump) {
      -                            handleGeneralOp(blocks, todo, bci, nextWOJump, stackLostWOJump, stackGainWOJump);
      -                        }
      -                        break;
      -                    }
      -                }
      -            });
      -        }
      -        return blocks;
      -    }
      -
      -    private void handleGeneralOp(List> blocks, ArrayDeque todo, int bci, int next, int stackLost, int stackGain) {
      -        if (next >= 0) {
      -            ArrayList blocksHere = new ArrayList<>(blocks.get(bci));
      -            for (int k = 0; k < stackLost; ++k) {
      -                blocksHere.remove(blocksHere.size() - 1);
      -            }
      -            for (int k = 0; k < stackGain; ++k) {
      -                blocksHere.add(StackItem.Object);
      -            }
      -            setNextStack(todo, blocks, next, blocksHere);
      -        }
      -    }
      -
      -    @FunctionalInterface
      -    public interface BytecodeAction {
      -        void run(int bci, OpCodes op, int oparg, byte[] followingArgs);
      -    }
      -
      -    // returns the following bci
      -    private static int opCodeAt(byte[] bytecode, int bci, BytecodeAction action) {
      -        int oparg = 0;
      -        OpCodes op = OpCodes.fromOpCode(bytecode[bci]);
      -        while (op == OpCodes.EXTENDED_ARG) {
      -            oparg |= Byte.toUnsignedInt(bytecode[bci + 1]);
      -            oparg <<= 8;
      -            bci += 2;
      -            op = OpCodes.fromOpCode(bytecode[bci]);
      -        }
      -        byte[] followingArgs = null;
      -        if (op.argLength > 0) {
      -            oparg |= Byte.toUnsignedInt(bytecode[bci + 1]);
      -            if (op.argLength > 1) {
      -                followingArgs = new byte[op.argLength - 1];
      -                System.arraycopy(bytecode, bci + 2, followingArgs, 0, followingArgs.length);
      -            }
      -        }
      -        action.run(bci, op, oparg, followingArgs);
      -        return bci + op.length();
      -    }
      -
      -    public static void iterateBytecode(byte[] bytecode, BytecodeAction action) {
      -        for (int bci = 0; bci < bytecode.length;) {
      -            bci = opCodeAt(bytecode, bci, action);
      -        }
      -    }
      -
      -    public void iterateBytecode(BytecodeAction action) {
      -        iterateBytecode(code, action);
      -    }
       }
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/CompilationScope.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/CompilationScope.java
      index dee34b0461..148cc15f37 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/CompilationScope.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/CompilationScope.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -40,7 +40,7 @@
        */
       package com.oracle.graal.python.compiler;
       
      -enum CompilationScope {
      +public enum CompilationScope {
           Module,
           Class,
           Function,
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/CompilationUnit.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/CompilationUnit.java
      index 1bb92cce55..6f4d2cc4cf 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/CompilationUnit.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/CompilationUnit.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -183,7 +183,7 @@ private void addImplicitReturn() {
               }
           }
       
      -    public CodeUnit assemble() {
      +    public BytecodeCodeUnit assemble() {
               addImplicitReturn();
               calculateJumpInstructionArguments();
       
      @@ -321,19 +321,20 @@ public CodeUnit assemble() {
                       }
                   }
               }
      -        return new CodeUnit(toTruffleStringUncached(name), toTruffleStringUncached(qualName),
      -                        argCount, kwOnlyArgCount, positionalOnlyArgCount, maxStackSize,
      -                        buf.toByteArray(), sourceMapBuilder.build(), flags,
      -                        orderedKeys(names, new TruffleString[0], PythonUtils::toTruffleStringUncached),
      -                        orderedKeys(varnames, new TruffleString[0], PythonUtils::toTruffleStringUncached),
      +        return new BytecodeCodeUnit(toTruffleStringUncached(name), toTruffleStringUncached(qualName),
      +                        argCount, kwOnlyArgCount, positionalOnlyArgCount, flags,
      +                        orderedKeys(names, new TruffleString[0], PythonUtils::toTruffleStringUncached), orderedKeys(varnames, new TruffleString[0], PythonUtils::toTruffleStringUncached),
                               orderedKeys(cellvars, new TruffleString[0], PythonUtils::toTruffleStringUncached),
                               orderedKeys(freevars, new TruffleString[0], cellvars.size(), PythonUtils::toTruffleStringUncached),
                               cell2arg,
                               orderedKeys(constants, new Object[0]),
      -                        orderedLong(primitiveConstants),
      -                        exceptionHandlerRanges,
      -                        conditionProfileCount,
      -                        startLocation.startLine, startLocation.startColumn, startLocation.endLine, startLocation.endColumn,
      +                        startLocation.startLine,
      +                        startLocation.startColumn,
      +                        startLocation.endLine,
      +                        startLocation.endColumn,
      +                        buf.toByteArray(),
      +                        sourceMapBuilder.build(),
      +                        orderedLong(primitiveConstants), exceptionHandlerRanges, maxStackSize, conditionProfileCount,
                               finishedCanQuickenOutput, shouldUnboxVariable, finishedGeneralizeInputsMap, finishedGeneralizeVarsMap);
           }
       
      diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/Compiler.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/Compiler.java
      index f8cfc842fd..f7aaaf07df 100644
      --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/Compiler.java
      +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/Compiler.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * The Universal Permissive License (UPL), Version 1.0
      @@ -196,7 +196,6 @@
       import com.oracle.graal.python.pegparser.sst.UnaryOpTy;
       import com.oracle.graal.python.pegparser.sst.WithItemTy;
       import com.oracle.graal.python.pegparser.tokenizer.SourceRange;
      -import com.oracle.graal.python.runtime.object.PythonObjectFactory;
       import com.oracle.graal.python.util.PythonUtils;
       import com.oracle.graal.python.util.SuppressFBWarnings;
       import com.oracle.truffle.api.memory.ByteArraySupport;
      @@ -238,9 +237,9 @@ public Compiler(ErrorCallback errorCallback) {
           public CompilationUnit compile(ModTy mod, EnumSet flags, int optimizationLevel, EnumSet futureFeatures) {
               this.flags = flags;
               if (mod instanceof ModTy.Module) {
      -            parseFuture(((ModTy.Module) mod).body);
      +            futureLineno = parseFuture(((ModTy.Module) mod).body, futureFeatures, errorCallback);
               } else if (mod instanceof ModTy.Interactive) {
      -            parseFuture(((ModTy.Interactive) mod).body);
      +            futureLineno = parseFuture(((ModTy.Interactive) mod).body, futureFeatures, errorCallback);
               }
               this.futureFeatures.addAll(futureFeatures);
               this.env = ScopeEnvironment.analyze(mod, errorCallback, this.futureFeatures);
      @@ -252,21 +251,23 @@ public CompilationUnit compile(ModTy mod, EnumSet flags, int optimization
               return topUnit;
           }
       
      -    private void parseFuture(StmtTy[] modBody) {
      +    public static int parseFuture(StmtTy[] modBody, EnumSet futureFeatures, ErrorCallback errorCallback) {
      +        int lastFutureLine = -1;
               if (modBody == null || modBody.length == 0) {
      -            return;
      +            return lastFutureLine;
               }
               boolean done = false;
               int prevLine = 0;
               int i = 0;
      -        if (getDocstring(modBody) != null) {
      +        if (findDocstring(modBody) != null) {
                   i++;
               }
      +
               for (; i < modBody.length; i++) {
                   StmtTy s = modBody[i];
                   int line = s.getSourceRange().startLine;
                   if (done && line > prevLine) {
      -                return;
      +                return lastFutureLine;
                   }
                   prevLine = line;
                   if (s instanceof StmtTy.ImportFrom) {
      @@ -275,8 +276,8 @@ private void parseFuture(StmtTy[] modBody) {
                           if (done) {
                               errorCallback.onError(ErrorType.Syntax, s.getSourceRange(), "from __future__ imports must occur at the beginning of the file");
                           }
      -                    parseFutureFeatures(importFrom, futureFeatures);
      -                    futureLineno = line;
      +                    parseFutureFeatures(importFrom, futureFeatures, errorCallback);
      +                    lastFutureLine = line;
                       } else {
                           done = true;
                       }
      @@ -284,9 +285,10 @@ private void parseFuture(StmtTy[] modBody) {
                       done = true;
                   }
               }
      +        return lastFutureLine;
           }
       
      -    private void parseFutureFeatures(StmtTy.ImportFrom node, EnumSet features) {
      +    private static void parseFutureFeatures(StmtTy.ImportFrom node, EnumSet features, ErrorCallback errorCallback) {
               for (AliasTy alias : node.names) {
                   if (alias.name != null) {
                       switch (alias.name) {
      @@ -446,7 +448,7 @@ private void exitScope() {
               }
           }
       
      -    private void checkForbiddenName(String id, ExprContextTy context) {
      +    protected final void checkForbiddenName(String id, ExprContextTy context) {
               if (context == ExprContextTy.Store) {
                   if (id.equals("__debug__")) {
                       errorCallback.onError(ErrorType.Syntax, unit.currentLocation, "cannot assign to __debug__");
      @@ -658,10 +660,7 @@ private static  int addObject(HashMap dict, T o) {
               return v;
           }
       
      -    private TruffleString getDocstring(StmtTy[] body) {
      -        if (optimizationLevel >= 2) {
      -            return null;
      -        }
      +    private static TruffleString findDocstring(StmtTy[] body) {
               if (body != null && body.length > 0) {
                   StmtTy stmt = body[0];
                   if (stmt instanceof StmtTy.Expr) {
      @@ -677,6 +676,13 @@ private TruffleString getDocstring(StmtTy[] body) {
               return null;
           }
       
      +    private TruffleString getDocstring(StmtTy[] body) {
      +        if (optimizationLevel >= 2) {
      +            return null;
      +        }
      +        return findDocstring(body);
      +    }
      +
           private SourceRange setLocation(SourceRange location) {
               SourceRange savedLocation = unit.currentLocation;
               unit.currentLocation = location;
      @@ -843,6 +849,19 @@ public boolean isEmpty() {
               }
           }
       
      +    /**
      +     * After these bytecodes are executed, there will a Python collection on the stack containing
      +     * all the arguments.
      +     * 

      + * We push individual arguments to the stack and when we reach certain size threshold, we emit + * instruction to collect N stack items (N is immediate operand) to the collection, which will + * now be on TOS. Next time this happens we emit instruction that adds the stack items to the + * collection. This way we accumulate the arguments into the collection and also never overflow + * certain stack size. + *

      + * When we encounter starred argument: we accumulate what we have on stack to the collection and + * then add the values in the starred arg to it. + */ private void collectIntoArray(ExprTy[] nodes, int bits, int alreadyOnStack) { Collector collector = new Collector(bits, alreadyOnStack); if (nodes != null) { @@ -887,7 +906,7 @@ private void collectIntoDict(ExprTy[] keys, ExprTy[] values) { collector.finishCollection(); } - private void validateKeywords(KeywordTy[] keywords) { + protected final void validateKeywords(KeywordTy[] keywords) { for (int i = 0; i < keywords.length; i++) { if (keywords[i].arg != null) { checkForbiddenName(keywords[i].arg, ExprContextTy.Store); @@ -1547,7 +1566,7 @@ public Void visit(ExprTy.List node) { case Store: return unpackInto(node.elements); case Load: - boolean emittedConstant = tryCollectConstantCollection(node.elements, CollectionBits.KIND_LIST); + boolean emittedConstant = tryLoadConstantCollection(node.elements, CollectionBits.KIND_LIST); if (emittedConstant) { return null; } @@ -1830,7 +1849,7 @@ public Void visit(ExprTy.Tuple node) { } } } - boolean emittedConstant = tryCollectConstantCollection(node.elements, CollectionBits.KIND_TUPLE); + boolean emittedConstant = tryLoadConstantCollection(node.elements, CollectionBits.KIND_TUPLE); if (emittedConstant) { return null; } @@ -1850,13 +1869,33 @@ public Void visit(ExprTy.Tuple node) { } } - private boolean tryCollectConstantCollection(ExprTy[] elements, int collectionKind) { + private boolean tryLoadConstantCollection(ExprTy[] elements, int collectionKind) { + ConstantCollection constantCollection = tryCollectConstantCollection(elements); + if (constantCollection == null) { + return false; + } + + addOp(LOAD_CONST_COLLECTION, addObject(unit.constants, constantCollection.collection), new byte[]{(byte) (constantCollection.elementType | collectionKind)}); + return true; + } + + public static final class ConstantCollection { + public final Object collection; + public final int elementType; + + ConstantCollection(Object collection, int elementType) { + this.collection = collection; + this.elementType = elementType; + } + } + + public static ConstantCollection tryCollectConstantCollection(ExprTy[] elements) { /* * We try to store the whole tuple as a Java array constant when all the elements are * constant and context-independent. */ if (elements == null || elements.length == 0) { - return false; + return null; } int constantType = -1; @@ -1886,10 +1925,10 @@ private boolean tryCollectConstantCollection(ExprTy[] elements, int collectionKi constantType = determineConstantType(constantType, CollectionBits.ELEMENT_OBJECT); constants.add(PNone.NONE); } else { - return false; + return null; } } else { - return false; + return null; } } Object newConstant = null; @@ -1930,11 +1969,10 @@ private boolean tryCollectConstantCollection(ExprTy[] elements, int collectionKi break; } } - addOp(LOAD_CONST_COLLECTION, addObject(unit.constants, newConstant), new byte[]{(byte) (constantType | collectionKind)}); - return true; + return new ConstantCollection(newConstant, constantType); } - int determineConstantType(int existing, int type) { + private static int determineConstantType(int existing, int type) { if (existing == -1 || existing == type) { return type; } @@ -3138,10 +3176,10 @@ public Void visit(PatternTy.MatchMapping node, PatternContext pc) { errorCallback.onError(ErrorType.Syntax, unit.currentLocation, "mapping pattern keys may only match literals and attribute lookups"); } assert constantValue != null; - Object pythonValue = PythonUtils.pythonObjectFromConstantValue(constantValue, PythonObjectFactory.getUncached()); + Object pythonValue = PythonUtils.pythonObjectFromConstantValue(constantValue); for (Object o : seen) { // need python like equal - e.g. 1 equals True - if (PyObjectRichCompareBool.EqNode.compareUncached(o, pythonValue)) { + if (PyObjectRichCompareBool.executeEqUncached(o, pythonValue)) { errorCallback.onError(ErrorType.Syntax, unit.currentLocation, "mapping pattern checks duplicate key (%s)", pythonValue); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/RaisePythonExceptionErrorCallback.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/RaisePythonExceptionErrorCallback.java index 1aef184604..f010568304 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/RaisePythonExceptionErrorCallback.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/RaisePythonExceptionErrorCallback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -48,6 +48,7 @@ import java.util.ArrayList; import java.util.List; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.modules.WarningsModuleBuiltins; import com.oracle.graal.python.builtins.objects.PNone; @@ -61,7 +62,7 @@ import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PIncompleteSourceException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.nodes.Node; @@ -163,7 +164,7 @@ public SourceSection getSourceSection() { cls = PythonBuiltinClassType.TabError; break; } - instance = PythonObjectFactory.getUncached().createBaseException(cls, message, PythonUtils.EMPTY_OBJECT_ARRAY); + instance = PFactory.createBaseException(PythonLanguage.get(null), cls, message, PythonUtils.EMPTY_OBJECT_ARRAY); final Object[] excAttrs = SyntaxErrorBuiltins.SYNTAX_ERROR_ATTR_FACTORY.create(); TruffleString filename = getFilename(source); excAttrs[SyntaxErrorBuiltins.IDX_FILENAME] = filename; @@ -174,7 +175,7 @@ public SourceSection getSourceSection() { // Not very nice. This counts on the implementation in traceback.py where if the value of // text attribute is NONE, then the line is not printed Object text = PNone.NONE; - if (sourceRange.startLine <= source.getLineCount()) { + if (source.hasCharacters() && sourceRange.startLine <= source.getLineCount()) { text = toTruffleStringUncached(source.getCharacters(sourceRange.startLine).toString()); } excAttrs[SyntaxErrorBuiltins.IDX_MSG] = message; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/Unparser.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/Unparser.java index 8f8502ff61..5bbd6d1753 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/Unparser.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/Unparser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -652,7 +652,7 @@ public Void visit(ExprTy.FormattedValue node) { conversion = "!s"; break; default: - throw PRaiseNode.getUncached().raise(PythonBuiltinClassType.SystemError, ErrorMessages.UNKNOWN_F_VALUE_CONVERSION_KIND); + throw PRaiseNode.raiseStatic(null, PythonBuiltinClassType.SystemError, ErrorMessages.UNKNOWN_F_VALUE_CONVERSION_KIND); } appendStr(conversion); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/BaseBytecodeDSLVisitor.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/BaseBytecodeDSLVisitor.java new file mode 100644 index 0000000000..d0910aee08 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/BaseBytecodeDSLVisitor.java @@ -0,0 +1,493 @@ +/* + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.compiler.bytecode_dsl; + +import com.oracle.graal.python.pegparser.sst.AliasTy; +import com.oracle.graal.python.pegparser.sst.ArgTy; +import com.oracle.graal.python.pegparser.sst.ArgumentsTy; +import com.oracle.graal.python.pegparser.sst.ComprehensionTy; +import com.oracle.graal.python.pegparser.sst.ExceptHandlerTy; +import com.oracle.graal.python.pegparser.sst.ExprTy; +import com.oracle.graal.python.pegparser.sst.KeywordTy; +import com.oracle.graal.python.pegparser.sst.MatchCaseTy; +import com.oracle.graal.python.pegparser.sst.ModTy; +import com.oracle.graal.python.pegparser.sst.PatternTy; +import com.oracle.graal.python.pegparser.sst.SSTNode; +import com.oracle.graal.python.pegparser.sst.SSTreeVisitor; +import com.oracle.graal.python.pegparser.sst.StmtTy; +import com.oracle.graal.python.pegparser.sst.TypeIgnoreTy.TypeIgnore; +import com.oracle.graal.python.pegparser.sst.WithItemTy; + +/** + * This interface provides default implementations of all {@code SSTreeVisitor} methods, which makes + * it easier to incrementally add support to the Bytecode DSL compiler. Once the compiler is stable, + * this interface should be removed. + */ +public interface BaseBytecodeDSLVisitor extends SSTreeVisitor { + + default T defaultValue(SSTNode node) { + throw new UnsupportedOperationException(getClass().getSimpleName() + ": " + node.getClass().getSimpleName()); + } + + default void visitNode(SSTNode node) { + if (node != null) { + node.accept(this); + } + } + + default T visit(AliasTy node) { + return defaultValue(node); + } + + default T visit(ArgTy node) { + return defaultValue(node); + } + + default T visit(ArgumentsTy node) { + visitSequence(node.defaults); + visitSequence(node.kwDefaults); + return defaultValue(node); + } + + default T visit(ComprehensionTy node) { + visitNode(node.iter); + visitSequence(node.ifs); + visitNode(node.target); + return defaultValue(node); + } + + default T visit(ExprTy.Attribute node) { + visitNode(node.value); + return defaultValue(node); + } + + default T visit(ExprTy.Await node) { + visitNode(node.value); + return defaultValue(node); + } + + default T visit(ExprTy.BinOp node) { + visitNode(node.left); + visitNode(node.right); + return defaultValue(node); + } + + default T visit(ExprTy.BoolOp node) { + visitSequence(node.values); + return defaultValue(node); + } + + default T visit(ExprTy.Call node) { + visitNode(node.func); + visitSequence(node.args); + visitSequence(node.keywords); + return defaultValue(node); + } + + default T visit(ExprTy.Compare node) { + visitNode(node.left); + visitSequence(node.comparators); + return defaultValue(node); + } + + default T visit(ExprTy.Constant node) { + return defaultValue(node); + } + + default T visit(ExprTy.Dict node) { + visitSequence(node.keys); + visitSequence(node.values); + return defaultValue(node); + } + + default T visit(ExprTy.DictComp node) { + visitSequence(node.generators); + visitNode(node.key); + visitNode(node.value); + return defaultValue(node); + } + + default T visit(ExprTy.FormattedValue node) { + visitNode(node.formatSpec); + visitNode(node.value); + return defaultValue(node); + } + + default T visit(ExprTy.GeneratorExp node) { + visitNode(node.element); + visitSequence(node.generators); + return defaultValue(node); + } + + default T visit(ExprTy.IfExp node) { + visitNode(node.test); + visitNode(node.body); + visitNode(node.orElse); + return defaultValue(node); + } + + default T visit(ExprTy.JoinedStr node) { + visitSequence(node.values); + return defaultValue(node); + } + + default T visit(ExprTy.Lambda node) { + visitNode(node.body); + return defaultValue(node); + } + + default T visit(ExprTy.List node) { + visitSequence(node.elements); + return defaultValue(node); + } + + default T visit(ExprTy.ListComp node) { + visitSequence(node.generators); + visitNode(node.element); + return defaultValue(node); + } + + default T visit(ExprTy.Name node) { + return defaultValue(node); + } + + default T visit(ExprTy.NamedExpr node) { + visitNode(node.target); + visitNode(node.value); + return defaultValue(node); + } + + default T visit(ExprTy.Set node) { + visitSequence(node.elements); + return defaultValue(node); + } + + default T visit(ExprTy.SetComp node) { + visitSequence(node.generators); + visitNode(node.element); + return defaultValue(node); + } + + default T visit(ExprTy.Slice node) { + visitNode(node.lower); + visitNode(node.upper); + visitNode(node.step); + return defaultValue(node); + } + + default T visit(ExprTy.Starred node) { + visitNode(node.value); + return defaultValue(node); + } + + default T visit(ExprTy.Subscript node) { + visitNode(node.value); + visitNode(node.slice); + return defaultValue(node); + } + + default T visit(ExprTy.Tuple node) { + visitSequence(node.elements); + return defaultValue(node); + } + + default T visit(ExprTy.UnaryOp node) { + visitNode(node.operand); + return defaultValue(node); + } + + default T visit(ExprTy.Yield node) { + visitNode(node.value); + return defaultValue(node); + } + + default T visit(ExprTy.YieldFrom node) { + visitNode(node.value); + return defaultValue(node); + } + + default T visit(KeywordTy node) { + visitNode(node.value); + return defaultValue(node); + } + + default T visit(ModTy.Expression node) { + visitNode(node.body); + return defaultValue(node); + } + + default T visit(ModTy.FunctionType node) { + visitNode(node.returns); + return defaultValue(node); + } + + default T visit(ModTy.Interactive node) { + visitSequence(node.body); + return defaultValue(node); + } + + default T visit(ModTy.Module node) { + visitSequence(node.body); + return defaultValue(node); + } + + default T visit(StmtTy.AnnAssign node) { + visitNode(node.target); + visitNode(node.annotation); + visitNode(node.value); + return defaultValue(node); + } + + default T visit(StmtTy.Assert node) { + visitNode(node.test); + visitNode(node.msg); + return defaultValue(node); + } + + default T visit(StmtTy.Assign node) { + visitNode(node.value); + visitSequence(node.targets); + return defaultValue(node); + } + + default T visit(StmtTy.AsyncFor node) { + visitNode(node.target); + visitNode(node.iter); + visitSequence(node.body); + visitSequence(node.orElse); + return defaultValue(node); + } + + default T visit(StmtTy.AsyncFunctionDef node) { + visitSequence(node.decoratorList); + visitNode(node.args); + visitNode(node.returns); + visitSequence(node.body); + return defaultValue(node); + } + + default T visit(StmtTy.AsyncWith node) { + visitSequence(node.items); + visitSequence(node.body); + return defaultValue(node); + } + + default T visit(StmtTy.AugAssign node) { + visitNode(node.target); + visitNode(node.value); + return defaultValue(node); + } + + default T visit(StmtTy.ClassDef node) { + visitSequence(node.decoratorList); + visitSequence(node.bases); + visitSequence(node.keywords); + visitSequence(node.body); + return defaultValue(node); + } + + default T visit(StmtTy.Delete node) { + visitSequence(node.targets); + return defaultValue(node); + } + + default T visit(StmtTy.Expr node) { + visitNode(node.value); + return defaultValue(node); + } + + default T visit(StmtTy.For node) { + visitNode(node.iter); + visitNode(node.target); + visitSequence(node.body); + visitSequence(node.orElse); + return defaultValue(node); + } + + default T visit(StmtTy.FunctionDef node) { + visitSequence(node.decoratorList); + visitNode(node.args); + visitNode(node.returns); + visitSequence(node.body); + return defaultValue(node); + } + + default T visit(StmtTy.Global node) { + return defaultValue(node); + } + + default T visit(StmtTy.If node) { + visitNode(node.test); + visitSequence(node.body); + visitSequence(node.orElse); + return defaultValue(node); + } + + default T visit(StmtTy.Import node) { + return defaultValue(node); + } + + default T visit(StmtTy.ImportFrom node) { + return defaultValue(node); + } + + default T visit(StmtTy.Match node) { + visitNode(node.subject); + visitSequence(node.cases); + return defaultValue(node); + } + + default T visit(MatchCaseTy node) { + visitNode(node.pattern); + visitNode(node.guard); + visitSequence(node.body); + return defaultValue(node); + } + + default T visit(PatternTy.MatchAs node) { + visitNode(node.pattern); + return defaultValue(node); + } + + default T visit(PatternTy.MatchClass node) { + visitSequence(node.patterns); + visitSequence(node.kwdPatterns); + visitNode(node.cls); + return defaultValue(node); + } + + default T visit(PatternTy.MatchMapping node) { + visitSequence(node.keys); + visitSequence(node.patterns); + return defaultValue(node); + } + + default T visit(PatternTy.MatchOr node) { + visitSequence(node.patterns); + return defaultValue(node); + } + + default T visit(PatternTy.MatchSequence node) { + visitSequence(node.patterns); + return defaultValue(node); + } + + default T visit(PatternTy.MatchSingleton node) { + return defaultValue(node); + } + + default T visit(PatternTy.MatchStar node) { + return defaultValue(node); + } + + default T visit(PatternTy.MatchValue node) { + visitNode(node.value); + return defaultValue(node); + } + + default T visit(StmtTy.Nonlocal node) { + return defaultValue(node); + } + + default T visit(StmtTy.Raise node) { + visitNode(node.exc); + visitNode(node.cause); + return defaultValue(node); + } + + default T visit(StmtTy.Return node) { + visitNode(node.value); + return defaultValue(node); + } + + default T visit(StmtTy.Try node) { + visitSequence(node.body); + visitSequence(node.orElse); + visitSequence(node.finalBody); + visitSequence(node.handlers); + return defaultValue(node); + } + + default T visit(StmtTy.TryStar node) { + return defaultValue(node); + } + + default T visit(ExceptHandlerTy.ExceptHandler node) { + visitNode(node.type); + visitSequence(node.body); + return defaultValue(node); + } + + default T visit(StmtTy.While node) { + visitNode(node.test); + visitSequence(node.body); + visitSequence(node.orElse); + return defaultValue(node); + } + + default T visit(StmtTy.With node) { + visitSequence(node.items); + visitSequence(node.body); + return defaultValue(node); + } + + default T visit(WithItemTy node) { + visitNode(node.contextExpr); + visitNode(node.optionalVars); + return defaultValue(node); + } + + default T visit(StmtTy.Break node) { + return defaultValue(node); + } + + default T visit(StmtTy.Continue node) { + return defaultValue(node); + } + + default T visit(StmtTy.Pass node) { + return defaultValue(node); + } + + default T visit(TypeIgnore node) { + return defaultValue(node); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/BytecodeDSLCompiler.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/BytecodeDSLCompiler.java new file mode 100644 index 0000000000..11e21db32b --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/BytecodeDSLCompiler.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.compiler.bytecode_dsl; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.compiler.Compiler; +import com.oracle.graal.python.compiler.RaisePythonExceptionErrorCallback; +import com.oracle.graal.python.nodes.bytecode_dsl.BytecodeDSLCodeUnit; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode; +import com.oracle.graal.python.pegparser.FutureFeature; +import com.oracle.graal.python.pegparser.scope.Scope; +import com.oracle.graal.python.pegparser.scope.ScopeEnvironment; +import com.oracle.graal.python.pegparser.sst.ModTy; +import com.oracle.graal.python.pegparser.sst.StmtTy; +import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.truffle.api.source.Source; + +public class BytecodeDSLCompiler { + + public static final record BytecodeDSLCompilerResult(PBytecodeDSLRootNode rootNode, BytecodeDSLCodeUnit codeUnit) { + } + + public static BytecodeDSLCompilerResult compile(PythonLanguage language, PythonContext context, ModTy mod, Source source, int optimize, RaisePythonExceptionErrorCallback errorCallback, + EnumSet futureFeatures) { + /** + * Parse __future__ annotations before the analysis step. The analysis does extra validation + * when __future__.annotations is imported. + */ + int futureLineNumber = parseFuture(mod, futureFeatures, errorCallback); + ScopeEnvironment scopeEnvironment = ScopeEnvironment.analyze(mod, errorCallback, futureFeatures); + BytecodeDSLCompilerContext ctx = new BytecodeDSLCompilerContext(language, context, mod, source, optimize, futureFeatures, futureLineNumber, errorCallback, scopeEnvironment); + RootNodeCompiler compiler = new RootNodeCompiler(ctx, mod, futureFeatures); + return compiler.compile(); + } + + private static int parseFuture(ModTy mod, EnumSet futureFeatures, RaisePythonExceptionErrorCallback errorCallback) { + StmtTy[] stmts = null; + if (mod instanceof ModTy.Module module) { + stmts = module.body; + } else if (mod instanceof ModTy.Interactive interactive) { + stmts = interactive.body; + } else { + return -1; + } + return Compiler.parseFuture(stmts, futureFeatures, errorCallback); + } + + public static class BytecodeDSLCompilerContext { + + public final PythonLanguage language; + public final PythonContext pythonContext; + public final ModTy mod; + public final Source source; + public final int optimizationLevel; + public final EnumSet futureFeatures; + public final int futureLineNumber; + public final RaisePythonExceptionErrorCallback errorCallback; + public final ScopeEnvironment scopeEnvironment; + public final Map qualifiedNames; + + public BytecodeDSLCompilerContext(PythonLanguage language, PythonContext context, ModTy mod, Source source, int optimizationLevel, + EnumSet futureFeatures, int futureLineNumber, RaisePythonExceptionErrorCallback errorCallback, ScopeEnvironment scopeEnvironment) { + this.language = language; + this.pythonContext = context; + this.mod = mod; + this.source = source; + this.optimizationLevel = optimizationLevel; + this.futureFeatures = futureFeatures; + this.futureLineNumber = futureLineNumber; + this.errorCallback = errorCallback; + this.scopeEnvironment = scopeEnvironment; + this.qualifiedNames = new HashMap<>(); + } + + String mangle(Scope scope, String name) { + return ScopeEnvironment.mangle(getClassName(scope), name); + } + + String getClassName(Scope s) { + Scope cur = s; + while (cur != null) { + if (cur.isClass()) { + return cur.getName(); + } + cur = scopeEnvironment.lookupParent(cur); + } + return null; + } + + String getQualifiedName(Scope scope) { + if (qualifiedNames.containsKey(scope)) { + return qualifiedNames.get(scope); + } else { + String qualifiedName = computeQualifiedName(scope); + qualifiedNames.put(scope, qualifiedName); + return qualifiedName; + } + } + + private String computeQualifiedName(Scope scope) { + String qualifiedName = scope.getName(); + Scope parentScope = scopeEnvironment.lookupParent(scope); + if (parentScope != null && parentScope != scopeEnvironment.getTopScope()) { + if (!((scope.isFunction() || scope.isClass()) && parentScope.getUseOfName(mangle(scope, scope.getName())).contains(Scope.DefUse.GlobalExplicit))) { + // Qualify the name, unless it's a function/class and the parent declared the + // name as a global (in which case the function/class doesn't belong to the + // parent). + if (parentScope.isFunction()) { + qualifiedName = getQualifiedName(parentScope) + ".." + scope.getName(); + } else { + qualifiedName = getQualifiedName(parentScope) + "." + scope.getName(); + } + } + } + + return qualifiedName; + } + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/RootNodeCompiler.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/RootNodeCompiler.java new file mode 100644 index 0000000000..3ebcfbb43d --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/RootNodeCompiler.java @@ -0,0 +1,5089 @@ +/* + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.compiler.bytecode_dsl; + +import static com.oracle.graal.python.compiler.CompilationScope.Class; +import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___CLASS__; +import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; + +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.code.PCode; +import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis; +import com.oracle.graal.python.builtins.objects.function.PArguments; +import com.oracle.graal.python.builtins.objects.function.PKeyword; +import com.oracle.graal.python.builtins.objects.type.TypeFlags; +import com.oracle.graal.python.compiler.CompilationScope; +import com.oracle.graal.python.compiler.Compiler; +import com.oracle.graal.python.compiler.Compiler.ConstantCollection; +import com.oracle.graal.python.compiler.OpCodes.CollectionBits; +import com.oracle.graal.python.compiler.Unparser; +import com.oracle.graal.python.compiler.bytecode_dsl.BytecodeDSLCompiler.BytecodeDSLCompilerContext; +import com.oracle.graal.python.compiler.bytecode_dsl.BytecodeDSLCompiler.BytecodeDSLCompilerResult; +import com.oracle.graal.python.lib.PyObjectRichCompareBool; +import com.oracle.graal.python.nodes.StringLiterals; +import com.oracle.graal.python.nodes.bytecode_dsl.BytecodeDSLCodeUnit; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNodeGen; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNodeGen.Builder; +import com.oracle.graal.python.pegparser.ErrorCallback.ErrorType; +import com.oracle.graal.python.pegparser.ErrorCallback.WarningType; +import com.oracle.graal.python.pegparser.FutureFeature; +import com.oracle.graal.python.pegparser.scope.Scope; +import com.oracle.graal.python.pegparser.scope.Scope.DefUse; +import com.oracle.graal.python.pegparser.sst.AliasTy; +import com.oracle.graal.python.pegparser.sst.ArgTy; +import com.oracle.graal.python.pegparser.sst.ArgumentsTy; +import com.oracle.graal.python.pegparser.sst.BoolOpTy; +import com.oracle.graal.python.pegparser.sst.CmpOpTy; +import com.oracle.graal.python.pegparser.sst.ComprehensionTy; +import com.oracle.graal.python.pegparser.sst.ConstantValue; +import com.oracle.graal.python.pegparser.sst.ConstantValue.Kind; +import com.oracle.graal.python.pegparser.sst.ExceptHandlerTy; +import com.oracle.graal.python.pegparser.sst.ExprContextTy; +import com.oracle.graal.python.pegparser.sst.ExprTy; +import com.oracle.graal.python.pegparser.sst.ExprTy.Constant; +import com.oracle.graal.python.pegparser.sst.ExprTy.DictComp; +import com.oracle.graal.python.pegparser.sst.ExprTy.GeneratorExp; +import com.oracle.graal.python.pegparser.sst.ExprTy.Lambda; +import com.oracle.graal.python.pegparser.sst.ExprTy.ListComp; +import com.oracle.graal.python.pegparser.sst.ExprTy.SetComp; +import com.oracle.graal.python.pegparser.sst.KeywordTy; +import com.oracle.graal.python.pegparser.sst.MatchCaseTy; +import com.oracle.graal.python.pegparser.sst.ModTy; +import com.oracle.graal.python.pegparser.sst.OperatorTy; +import com.oracle.graal.python.pegparser.sst.PatternTy; +import com.oracle.graal.python.pegparser.sst.SSTNode; +import com.oracle.graal.python.pegparser.sst.StmtTy; +import com.oracle.graal.python.pegparser.sst.StmtTy.AsyncFunctionDef; +import com.oracle.graal.python.pegparser.sst.UnaryOpTy; +import com.oracle.graal.python.pegparser.sst.WithItemTy; +import com.oracle.graal.python.pegparser.tokenizer.SourceRange; +import com.oracle.graal.python.util.PythonUtils; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.bytecode.BytecodeConfig; +import com.oracle.truffle.api.bytecode.BytecodeLabel; +import com.oracle.truffle.api.bytecode.BytecodeLocal; +import com.oracle.truffle.api.bytecode.BytecodeParser; +import com.oracle.truffle.api.bytecode.BytecodeRootNodes; +import com.oracle.truffle.api.instrumentation.StandardTags.StatementTag; +import com.oracle.truffle.api.strings.TruffleString; + +/** + * Compiles a top-level AST (modules, functions, classes, etc.) to a root node. Produces a + * {@link BytecodeDSLCompilerResult}. Every instance is associated with corresponding + * {@link SSTNode} that represents the compiled top level AST. + *

      + * The class implements SST visitor, so that it can have a separate handler for each top-level AST + * node type, the handler (one of the {@code visit} methods) then creates a lambda of type + * {@link BytecodeParser}, which captures the node being compiled and the instance of + * {@link RootNodeCompiler}, and it uses the {@link RootNodeCompiler} to do the parsing itself. The + * {@link BytecodeParser} instance is passed to Truffle API + * {@link PBytecodeDSLRootNodeGen#create(PythonLanguage, BytecodeConfig, BytecodeParser)} to trigger + * the parsing. Truffle keeps the lambda, and it may invoke it again when it needs to perform the + * parsing of the given node again. + *

      + * The parsing must happen within the {@link BytecodeParser} lambda invocation. + *

      + * This visitor also captures compilation unit state, such as the map of local variables, and serves + * the same purpose as the {@code compiler_unit} struct in the CPython compiler. Instead of explicit + * stack of compiler units, we use implicitly Java stack and new instances of + * {@link RootNodeCompiler}. + *

      + * For the parsing of the body of the top level AST element, this visitor delegates to the + * {@link StatementCompiler}, which does all the heavy lifting. + */ +public final class RootNodeCompiler implements BaseBytecodeDSLVisitor { + /** + * Because a {@link RootNodeCompiler} instance gets reused on reparse, it should be idempotent. + * Consequently, most of its fields are final and immutable/not mutated after construction. For + * some tables updated during parsing (e.g., the constants map), we ensure these updates are + * idempotent. Any remaining fields must be {@link #reset()} at the beginning of the parse. + */ + // Immutable + private final BytecodeDSLCompilerContext ctx; + private final SSTNode startNode; + private final Scope scope; + private final CompilationScope scopeType; + private final boolean isInteractive; + private final EnumSet futureFeatures; + + // Immutable after construction + private final HashMap varnames; + private final HashMap cellvars; + private final HashMap freevars; + private final int[] cell2arg; + private final String selfCellName; + + // Updated idempotently: the keys are filled during first parsing, on subsequent parsings the + // values will be just overridden, but no new keys should be added. + private final Map locals = new HashMap<>(); + private final Map cellLocals = new HashMap<>(); + private final Map freeLocals = new HashMap<>(); + private final HashMap constants = new HashMap<>(); + private final HashMap names = new HashMap<>(); + + // Mutable (must be reset) + private SourceRange currentLocation; + + public RootNodeCompiler(BytecodeDSLCompilerContext ctx, SSTNode rootNode, EnumSet futureFeatures) { + this.ctx = ctx; + this.startNode = rootNode; + this.scope = ctx.scopeEnvironment.lookupScope(rootNode); + this.scopeType = getScopeType(scope, rootNode); + this.isInteractive = rootNode instanceof ModTy.Interactive; + this.futureFeatures = futureFeatures; + + this.varnames = new HashMap<>(); + if (scope.isFunction()) { + /* + * scope.getVarnames only returns parameters. We use the scope to collect the rest of + * the regular variables. + */ + for (int i = 0; i < scope.getVarnames().size(); i++) { + varnames.put(scope.getVarnames().get(i), i); + } + varnames.putAll(scope.getSymbolsByType(EnumSet.of(DefUse.Local), EnumSet.of(DefUse.DefParam, DefUse.Cell, DefUse.Free), varnames.size())); + } + + this.cellvars = scope.getSymbolsByType(EnumSet.of(Scope.DefUse.Cell), 0); + if (scope.needsClassClosure()) { + assert scopeType == Class; + assert cellvars.isEmpty(); + cellvars.put("__class__", 0); + } + + this.freevars = scope.getSymbolsByType(EnumSet.of(Scope.DefUse.Free, Scope.DefUse.DefFreeClass), 0); + + int[] cell2argValue = new int[cellvars.size()]; + boolean hasArgCell = false; + Arrays.fill(cell2argValue, -1); + String selfCellNameValue = null; + for (String cellvar : cellvars.keySet()) { + if (varnames.containsKey(cellvar)) { + int argIndex = varnames.get(cellvar); + cell2argValue[cellvars.get(cellvar)] = argIndex; + hasArgCell = true; + if (argIndex == 0) { + assert selfCellNameValue == null; + selfCellNameValue = cellvar; + } + } + } + this.cell2arg = hasArgCell ? cell2argValue : null; + this.selfCellName = selfCellNameValue; + } + + private static CompilationScope getScopeType(Scope scope, SSTNode rootNode) { + if (scope.isModule()) { + return CompilationScope.Module; + } else if (scope.isClass()) { + return CompilationScope.Class; + } else if (scope.isFunction()) { + if (rootNode instanceof Lambda) { + return CompilationScope.Lambda; + } else if (rootNode instanceof AsyncFunctionDef) { + return CompilationScope.AsyncFunction; + } else if (rootNode instanceof DictComp || rootNode instanceof ListComp || rootNode instanceof SetComp || rootNode instanceof GeneratorExp) { + return CompilationScope.Comprehension; + } else { + return CompilationScope.Function; + } + } else { + throw new IllegalStateException("Unexpected scope: " + scope); + } + } + + private static U[] orderedKeys(HashMap map, U[] base, Function converter) { + U[] result = Arrays.copyOf(base, map.size()); + for (Map.Entry e : map.entrySet()) { + result[e.getValue()] = converter.apply(e.getKey()); + } + return result; + } + + private static T[] orderedKeys(HashMap map, T[] base) { + return orderedKeys(map, base, x -> x); + } + + private Object addConstant(Object c) { + Integer v = constants.get(c); + if (v == null) { + v = constants.size(); + constants.put(c, v); + } + return c; + } + + private static TruffleString[] orderedTruffleStringArray(HashMap map) { + return orderedKeys(map, new TruffleString[0], PythonUtils::toTruffleStringUncached); + } + + private BytecodeDSLCompilerResult compileRootNode(String name, ArgumentInfo argumentInfo, SourceRange sourceRange, BytecodeParser parser) { + BytecodeRootNodes nodes = PBytecodeDSLRootNodeGen.create(ctx.language, BytecodeConfig.WITH_SOURCE, parser); + List nodeList = nodes.getNodes(); + assert nodeList.size() == 1; + PBytecodeDSLRootNode rootNode = nodeList.get(0); + + int flags = PCode.CO_OPTIMIZED | PCode.CO_NEWLOCALS; + flags |= argumentInfo.takesVarArgs ? PCode.CO_VARARGS : 0; + flags |= argumentInfo.takesVarKeywordArgs ? PCode.CO_VARKEYWORDS : 0; + if (scope.isNested()) { + flags |= PCode.CO_NESTED; + } + if (scope.isModule()) { + flags |= PCode.CO_GRAALPYHON_MODULE; + } + if (scope.isGenerator() && scope.isCoroutine()) { + flags |= PCode.CO_ASYNC_GENERATOR; + } else if (scope.isGenerator()) { + flags |= PCode.CO_GENERATOR; + } else if (scope.isCoroutine()) { + flags |= PCode.CO_COROUTINE; + } + for (FutureFeature flag : futureFeatures) { + flags |= flag.flagValue; + } + + int classcellIndex = -1; + if (freeLocals.containsKey(J___CLASS__)) { + classcellIndex = freeLocals.get(J___CLASS__).getLocalOffset(); + } + + int selfIndex = -1; + if (argumentInfo.nonEmpty()) { + selfIndex = 0; + if (selfCellName != null) { + selfIndex = cellLocals.get(selfCellName).getLocalOffset(); + } + } + + BytecodeDSLCodeUnit codeUnit = new BytecodeDSLCodeUnit(toTruffleStringUncached(name), toTruffleStringUncached(ctx.getQualifiedName(scope)), + argumentInfo.argCount, argumentInfo.kwOnlyArgCount, argumentInfo.positionalOnlyArgCount, + flags, orderedTruffleStringArray(names), + orderedTruffleStringArray(varnames), + orderedTruffleStringArray(cellvars), + orderedTruffleStringArray(freevars), + cell2arg, + orderedKeys(constants, new Object[0]), + sourceRange.startLine, + sourceRange.startColumn, + sourceRange.endLine, + sourceRange.endColumn, + classcellIndex, + selfIndex, + null, + nodes); + rootNode.setMetadata(codeUnit, ctx.errorCallback); + return new BytecodeDSLCompilerResult(rootNode, codeUnit); + } + + private static class ArgumentInfo { + static final ArgumentInfo NO_ARGS = new ArgumentInfo(0, 0, 0, false, false); + + final int argCount; + final int positionalOnlyArgCount; + final int kwOnlyArgCount; + final boolean takesVarArgs; + final boolean takesVarKeywordArgs; + + ArgumentInfo(int argCount, int positionalOnlyArgCount, int kwOnlyArgCount, boolean takesVarArgs, boolean takesVarKeywordArgs) { + this.argCount = argCount; + this.positionalOnlyArgCount = positionalOnlyArgCount; + this.kwOnlyArgCount = kwOnlyArgCount; + this.takesVarArgs = takesVarArgs; + this.takesVarKeywordArgs = takesVarKeywordArgs; + } + + static ArgumentInfo fromArguments(ArgumentsTy args) { + int argc, pargc, kwargc; + boolean splat, kwSplat; + if (args == null) { + argc = pargc = kwargc = 0; + splat = kwSplat = false; + } else { + argc = args.args == null ? 0 : args.args.length; + pargc = args.posOnlyArgs == null ? 0 : args.posOnlyArgs.length; + kwargc = args.kwOnlyArgs == null ? 0 : args.kwOnlyArgs.length; + splat = args.varArg != null; + kwSplat = args.kwArg != null; + } + return new ArgumentInfo(argc, pargc, kwargc, splat, kwSplat); + } + + private boolean nonEmpty() { + return argCount + positionalOnlyArgCount + kwOnlyArgCount > 0 || takesVarArgs || takesVarKeywordArgs; + } + } + + private void checkForbiddenName(String id, NameOperation context) { + checkForbiddenName(id, context, currentLocation); + } + + private void checkForbiddenName(String id, NameOperation context, SourceRange location) { + if (context == NameOperation.BeginWrite) { + if (id.equals("__debug__")) { + ctx.errorCallback.onError(ErrorType.Syntax, location, "cannot assign to __debug__"); + } + } + if (context == NameOperation.Delete) { + if (id.equals("__debug__")) { + ctx.errorCallback.onError(ErrorType.Syntax, location, "cannot delete __debug__"); + } + } + } + + private void checkForbiddenArgs(ArgumentsTy args, SourceRange location) { + if (args != null) { + if (args.posOnlyArgs != null) { + for (ArgTy arg : args.posOnlyArgs) { + checkForbiddenName(arg.arg, NameOperation.BeginWrite, location); + } + } + if (args.args != null) { + for (ArgTy arg : args.args) { + checkForbiddenName(arg.arg, NameOperation.BeginWrite, location); + } + } + if (args.kwOnlyArgs != null) { + for (ArgTy arg : args.kwOnlyArgs) { + checkForbiddenName(arg.arg, NameOperation.BeginWrite, location); + } + } + if (args.varArg != null) { + checkForbiddenName(args.varArg.arg, NameOperation.BeginWrite, location); + } + if (args.kwArg != null) { + checkForbiddenName(args.kwArg.arg, NameOperation.BeginWrite, location); + } + } + } + + private boolean containsAnnotations(StmtTy[] stmts) { + if (stmts == null) { + return false; + } + for (StmtTy stmt : stmts) { + if (containsAnnotations(stmt)) { + return true; + } + } + return false; + } + + private boolean containsAnnotations(StmtTy stmt) { + if (stmt instanceof StmtTy.AnnAssign) { + return true; + } else if (stmt instanceof StmtTy.For) { + return containsAnnotations(((StmtTy.For) stmt).body) || containsAnnotations(((StmtTy.For) stmt).orElse); + } else if (stmt instanceof StmtTy.While) { + return containsAnnotations(((StmtTy.While) stmt).body) || containsAnnotations(((StmtTy.While) stmt).orElse); + } else if (stmt instanceof StmtTy.If) { + return containsAnnotations(((StmtTy.If) stmt).body) || containsAnnotations(((StmtTy.If) stmt).orElse); + } else if (stmt instanceof StmtTy.With) { + return containsAnnotations(((StmtTy.With) stmt).body); + } else if (stmt instanceof StmtTy.Try) { + StmtTy.Try tryStmt = (StmtTy.Try) stmt; + if (tryStmt.handlers != null) { + for (ExceptHandlerTy h : tryStmt.handlers) { + if (containsAnnotations(((ExceptHandlerTy.ExceptHandler) h).body)) { + return true; + } + } + } + return containsAnnotations(tryStmt.body) || containsAnnotations(tryStmt.finalBody) || containsAnnotations(tryStmt.orElse); + } + return false; + } + + private static final class ParamAnnotation { + final TruffleString name; + final ExprTy annotation; + + ParamAnnotation(TruffleString name, ExprTy annotation) { + this.name = name; + this.annotation = annotation; + } + } + + private List collectParamAnnotations(ArgumentsTy args, ExprTy returns) { + List result = new ArrayList<>(); + if (args != null) { + visitParamAnnotations(result, args.args); + visitParamAnnotations(result, args.posOnlyArgs); + if (args.varArg != null) { + visitParamAnnotation(result, args.varArg.arg, args.varArg.annotation); + } + visitParamAnnotations(result, args.kwOnlyArgs); + if (args.kwArg != null) { + visitParamAnnotation(result, args.kwArg.arg, args.kwArg.annotation); + } + } + visitParamAnnotation(result, "return", returns); + return result; + } + + private void visitParamAnnotations(List result, ArgTy[] args) { + for (int i = 0; i < args.length; i++) { + visitParamAnnotation(result, args[i].arg, args[i].annotation); + } + } + + private void visitParamAnnotation(List result, String name, ExprTy annotation) { + if (annotation != null) { + String mangled = mangle(name); + result.add(new ParamAnnotation(toTruffleStringUncached(mangled), annotation)); + } + } + + public BytecodeDSLCompilerResult compile() { + return startNode.accept(this); + } + + public void reset() { + this.currentLocation = null; + } + + // -------------- helpers -------------- + + void beginRootNode(SSTNode node, ArgumentsTy args, Builder b) { + reset(); + b.beginSource(ctx.source); + beginRootSourceSection(node, b); + + b.beginRoot(); + + checkForbiddenArgs(args, node.getSourceRange()); + setUpFrame(args, b); + + b.emitTraceOrProfileCall(); + } + + void endRootNode(Builder b) { + b.endRoot(); + endRootSourceSection(b); + b.endSource(); + } + + /** + * Opens a new SourceSection operation. Emits TraceLine and starts a new Tag(Statement) if this + * location has a different line from the previous location. + *

      + * Returns whether this call opened a new Tag(Statement). The result should be passed to the + * corresponding {@link #endSourceSection} call to ensure the Tag is closed. + */ + boolean beginSourceSection(SSTNode node, Builder b) { + SourceRange sourceRange = node.getSourceRange(); + SourceRange oldSourceRange = this.currentLocation; + this.currentLocation = sourceRange; + + if (ctx.source.hasCharacters()) { + int startOffset = getStartOffset(sourceRange); + int endOffset = getEndOffset(sourceRange); + int length = endOffset - startOffset; + if (length == 0) { + startOffset = 0; + } + b.beginSourceSection(startOffset, length); + + if (oldSourceRange == null || oldSourceRange.startLine != sourceRange.startLine) { + b.beginTag(StatementTag.class); + b.beginBlock(); + b.emitTraceLine(sourceRange.startLine); + return true; + } + } + return false; + } + + /** + * Same as {@link #beginSourceSection(SSTNode, Builder)}, but does not emit tags or trace events + * (since the root has not been started yet). Avoids setting {@link #currentLocation} so that + * {{@link #beginSourceSection(SSTNode, Builder)} will emit a TraceLine for a statement on the + * first line. + */ + void beginRootSourceSection(SSTNode node, Builder b) { + SourceRange sourceRange = node.getSourceRange(); + + if (ctx.source.hasCharacters()) { + int startOffset = getStartOffset(sourceRange); + int endOffset = getEndOffset(sourceRange); + int length = endOffset - startOffset; + if (length == 0) { + startOffset = 0; + } + b.beginSourceSection(startOffset, length); + } + } + + void endSourceSection(Builder b, boolean closeTag) { + if (ctx.source.hasCharacters()) { + if (closeTag) { + b.endBlock(); + b.endTag(StatementTag.class); + } + b.endSourceSection(); + } + } + + void endRootSourceSection(Builder b) { + if (ctx.source.hasCharacters()) { + b.endSourceSection(); + } + } + + int getStartOffset(SourceRange sourceRange) { + return ctx.source.getLineStartOffset(sourceRange.startLine) + sourceRange.startColumn; + } + + int getEndOffset(SourceRange sourceRange) { + return ctx.source.getLineStartOffset(sourceRange.endLine) + sourceRange.endColumn; + } + + void beginReturn(Builder b) { + b.beginReturn(); + b.beginTraceOrProfileReturn(); + } + + void endReturn(Builder b) { + b.endTraceOrProfileReturn(); + b.endReturn(); + } + + // --------------------- visitor --------------------------- + + @Override + public BytecodeDSLCompilerResult visit(ModTy.Module node) { + return compileRootNode("", ArgumentInfo.NO_ARGS, node.getSourceRange(), b -> { + beginRootNode(node, null, b); + visitModuleBody(node.body, b); + endRootNode(b); + }); + } + + @Override + public BytecodeDSLCompilerResult visit(ModTy.Expression node) { + return compileRootNode("", ArgumentInfo.NO_ARGS, node.getSourceRange(), b -> { + beginRootNode(node, null, b); + beginReturn(b); + new StatementCompiler(b).visitNode(node.body); + endReturn(b); + endRootNode(b); + }); + } + + @Override + public BytecodeDSLCompilerResult visit(ModTy.Interactive node) { + return compileRootNode("", ArgumentInfo.NO_ARGS, node.getSourceRange(), b -> { + beginRootNode(node, null, b); + visitModuleBody(node.body, b); + endRootNode(b); + }); + } + + private void visitModuleBody(StmtTy[] body, Builder b) { + if (body != null) { + if (containsAnnotations(body)) { + b.emitSetupAnnotations(); + } + + StatementCompiler statementCompiler = new StatementCompiler(b); + if (isInteractive) { + for (int i = 0; i < body.length; i++) { + StmtTy bodyNode = body[i]; + if (i == body.length - 1) { + bodyNode.accept(statementCompiler); + + // For interactive code, always return None. + beginReturn(b); + b.emitLoadConstant(PNone.NONE); + endReturn(b); + } else { + bodyNode.accept(statementCompiler); + } + } + } else { + int i = 0; + TruffleString docstring = getDocstring(body); + if (docstring != null) { + /* + * Skip over the docstring so it does not get evaluated (and registered as a + * constant) for higher optimization levels. We manually add it as a constant + * for lower levels. + */ + i++; + if (ctx.optimizationLevel < 2) { + beginStoreLocal("__doc__", b); + emitPythonConstant(docstring, b); + endStoreLocal("__doc__", b); + } + } + if (i == body.length) { + // Special case: module body just consists of a docstring. + beginReturn(b); + b.emitLoadConstant(PNone.NONE); + endReturn(b); + return; + } + + for (; i < body.length; i++) { + StmtTy bodyNode = body[i]; + if (i == body.length - 1) { + if (bodyNode instanceof StmtTy.Expr expr) { + // Return the value of the last statement for interop eval. + beginReturn(b); + expr.value.accept(statementCompiler); + endReturn(b); + } else { + bodyNode.accept(statementCompiler); + beginReturn(b); + b.emitLoadConstant(PNone.NONE); + endReturn(b); + } + } else { + bodyNode.accept(statementCompiler); + } + } + } + } else { + beginReturn(b); + b.emitLoadConstant(PNone.NONE); + endReturn(b); + } + } + + private static TruffleString getDocstring(StmtTy[] body) { + if (body != null && body.length > 0) { + StmtTy stmt = body[0]; + if (stmt instanceof StmtTy.Expr expr // + && expr.value instanceof ExprTy.Constant constant // + && constant.value.kind == ConstantValue.Kind.RAW) { + return constant.value.getRaw(TruffleString.class); + } + } + return null; + } + + @Override + public BytecodeDSLCompilerResult visit(StmtTy.FunctionDef node) { + return compileRootNode(node.name, ArgumentInfo.fromArguments(node.args), node.getSourceRange(), + b -> emitFunctionDef(node, node.args, node.body, b, getDocstring(node.body), false)); + } + + @Override + public BytecodeDSLCompilerResult visit(StmtTy.AsyncFunctionDef node) { + return compileRootNode(node.name, ArgumentInfo.fromArguments(node.args), node.getSourceRange(), + b -> emitFunctionDef(node, node.args, node.body, b, getDocstring(node.body), false)); + } + + @Override + public BytecodeDSLCompilerResult visit(ExprTy.Lambda node) { + return compileRootNode("", ArgumentInfo.fromArguments(node.args), node.getSourceRange(), + b -> emitFunctionDef(node, node.args, new SSTNode[]{node.body}, b, null, !scope.isGenerator())); + } + + private void emitFunctionDef(SSTNode node, ArgumentsTy args, SSTNode[] body, Builder b, Object docstring, boolean isRegularLambda) { + beginRootNode(node, args, b); + + int i = 0; + if (docstring != null) { + i++; + if (ctx.optimizationLevel < 2) { + addConstant(docstring); + } else { + addConstant(PNone.NONE); + } + } else { + addConstant(PNone.NONE); + } + + StatementCompiler statementCompiler = new StatementCompiler(b); + + if (isRegularLambda) { + assert i == 0; + assert body[0] instanceof ExprTy; + beginReturn(b); + body[0].accept(statementCompiler); + endReturn(b); + } else { + for (; i < body.length; i++) { + body[i].accept(statementCompiler); + } + beginReturn(b); + emitPythonConstant(PNone.NONE, b); + endReturn(b); + } + + endRootNode(b); + } + + @Override + public BytecodeDSLCompilerResult visit(StmtTy.ClassDef node) { + return compileRootNode(node.name, ArgumentInfo.NO_ARGS, node.getSourceRange(), b -> { + beginRootNode(node, null, b); + + beginStoreLocal("__module__", b); + emitReadLocal("__name__", b); + endStoreLocal("__module__", b); + + beginStoreLocal("__qualname__", b); + emitPythonConstant(toTruffleStringUncached(ctx.getQualifiedName(scope)), b); + endStoreLocal("__qualname__", b); + + if (containsAnnotations(node.body)) { + b.emitSetupAnnotations(); + } + + int i = 0; + TruffleString docstring = getDocstring(node.body); + if (docstring != null) { + i++; + if (ctx.optimizationLevel < 2) { + beginStoreLocal("__doc__", b); + emitPythonConstant(docstring, b); + endStoreLocal("__doc__", b); + } + } + + StatementCompiler statementCompiler = new StatementCompiler(b); + for (; i < node.body.length; i++) { + node.body[i].accept(statementCompiler); + } + + if (scope.needsClassClosure()) { + beginStoreLocal("__classcell__", b); + b.emitLoadLocal(cellLocals.get("__class__")); + endStoreLocal("__classcell__", b); + + beginReturn(b); + b.emitLoadLocal(cellLocals.get("__class__")); + endReturn(b); + } else { + beginReturn(b); + b.emitLoadConstant(PNone.NONE); + endReturn(b); + } + + endRootNode(b); + }); + } + + private boolean beginComprehension(ComprehensionTy comp, int index, Builder b) { + boolean newStatement = beginSourceSection(comp, b); + + BytecodeLocal localIter = b.createLocal(); + BytecodeLocal localValue = b.createLocal(); + StatementCompiler statementCompiler = new StatementCompiler(b); + + b.beginStoreLocal(localIter); + b.beginGetIter(); + if (index == 0) { + b.emitLoadArgument(PArguments.USER_ARGUMENTS_OFFSET); + } else { + comp.iter.accept(statementCompiler); + } + b.endGetIter(); + b.endStoreLocal(); + + b.beginWhile(); + + b.beginBlock(); + b.emitTraceLineAtLoopHeader(currentLocation.startLine); + b.beginForIterate(localValue); + b.emitLoadLocal(localIter); + b.endForIterate(); + b.endBlock(); + + b.beginBlock(); + + comp.target.accept(statementCompiler.new StoreVisitor(() -> b.emitLoadLocal(localValue))); + + if (comp.ifs != null) { + for (int i = 0; i < comp.ifs.length; i++) { + b.beginIfThen(); + statementCompiler.visitCondition(comp.ifs[i]); + b.beginBlock(); + } + } + + return newStatement; + } + + private void endComprehension(ComprehensionTy comp, Builder b, boolean newStatement) { + if (comp.ifs != null) { + for (int i = 0; i < len(comp.ifs); i++) { + b.endBlock(); + b.endIfThen(); + } + } + + b.endBlock(); + b.endWhile(); + + endSourceSection(b, newStatement); + } + + private BytecodeDSLCompilerResult buildComprehensionCodeUnit(SSTNode node, ComprehensionTy[] generators, String name, + Consumer emptyCollectionProducer, + BiConsumer accumulateProducer) { + return compileRootNode(name, new ArgumentInfo(1, 0, 0, false, false), node.getSourceRange(), b -> { + beginRootNode(node, null, b); + + StatementCompiler statementCompiler = new StatementCompiler(b); + boolean isGenerator = emptyCollectionProducer == null; + BytecodeLocal collectionLocal = null; + if (!isGenerator) { + collectionLocal = b.createLocal(); + b.beginStoreLocal(collectionLocal); + emptyCollectionProducer.accept(statementCompiler); + b.endStoreLocal(); + } + + boolean[] newStatement = new boolean[generators.length]; + for (int i = 0; i < generators.length; i++) { + newStatement[i] = beginComprehension(generators[i], i, b); + } + accumulateProducer.accept(statementCompiler, collectionLocal); + for (int i = generators.length - 1; i >= 0; i--) { + endComprehension(generators[i], b, newStatement[i]); + } + + beginReturn(b); + if (isGenerator) { + b.emitLoadConstant(PNone.NONE); + } else { + b.emitLoadLocal(collectionLocal); + } + endReturn(b); + + endRootNode(b); + }); + } + + @Override + public BytecodeDSLCompilerResult visit(ExprTy.ListComp node) { + return buildComprehensionCodeUnit(node, node.generators, "", + (statementCompiler) -> { + statementCompiler.b.beginMakeList(); + statementCompiler.b.emitLoadConstant(PythonUtils.EMPTY_OBJECT_ARRAY); + statementCompiler.b.endMakeList(); + }, + (statementCompiler, collection) -> { + statementCompiler.b.beginListAppend(); + statementCompiler.b.emitLoadLocal(collection); + node.element.accept(statementCompiler); + statementCompiler.b.endListAppend(); + }); + } + + @Override + public BytecodeDSLCompilerResult visit(ExprTy.DictComp node) { + return buildComprehensionCodeUnit(node, node.generators, "", + (statementCompiler) -> { + statementCompiler.b.beginMakeDict(0); + statementCompiler.b.endMakeDict(); + }, + (statementCompiler, collection) -> { + statementCompiler.b.beginSetDictItem(); + statementCompiler.b.emitLoadLocal(collection); + node.key.accept(statementCompiler); + node.value.accept(statementCompiler); + statementCompiler.b.endSetDictItem(); + }); + } + + @Override + public BytecodeDSLCompilerResult visit(ExprTy.SetComp node) { + return buildComprehensionCodeUnit(node, node.generators, "", + (statementCompiler) -> { + statementCompiler.b.beginMakeSet(); + statementCompiler.b.emitLoadConstant(PythonUtils.EMPTY_OBJECT_ARRAY); + statementCompiler.b.endMakeSet(); + }, + (statementCompiler, collection) -> { + statementCompiler.b.beginSetAdd(); + statementCompiler.b.emitLoadLocal(collection); + node.element.accept(statementCompiler); + statementCompiler.b.endSetAdd(); + }); + } + + @Override + public BytecodeDSLCompilerResult visit(ExprTy.GeneratorExp node) { + return buildComprehensionCodeUnit(node, node.generators, "", + null, + (statementCompiler, collection) -> emitYield((statementCompiler_) -> node.element.accept(statementCompiler_), statementCompiler)); + } + + enum NameOperation { + Read, + BeginWrite, + EndWrite, + Delete + } + + private String mangle(String name) { + return ctx.mangle(scope, name); + } + + private void emitNotImplemented(String what, Builder b) { + b.beginRaiseNotImplementedError(); + emitPythonConstant(toTruffleStringUncached(what), b); + b.endRaiseNotImplementedError(); + } + + /** + * Use this method for values that should show up in co_consts. + */ + private void emitPythonConstant(Object constant, Builder b) { + b.emitLoadConstant(addConstant(constant)); + } + + /** + * This helper encapsulates all of the logic needed to yield and resume. Yields should not be + * emitted directly. + */ + private static void emitYield(Consumer yieldValueProducer, StatementCompiler statementCompiler) { + statementCompiler.b.beginResumeYield(); + statementCompiler.b.beginYield(); + statementCompiler.b.beginPreYield(); + yieldValueProducer.accept(statementCompiler); + statementCompiler.b.endPreYield(); + statementCompiler.b.endYield(); + statementCompiler.b.endResumeYield(); + } + + private void emitNameCellOperation(String mangled, NameOperation op, Builder b) { + int index; + BytecodeLocal local; + if (freevars.containsKey(mangled)) { + index = freevars.get(mangled) + cellvars.size(); + local = freeLocals.get(mangled); + } else { + index = cellvars.get(mangled); + local = cellLocals.get(mangled); + } + + switch (op) { + case Read: + if (scope.isClass()) { + b.beginClassLoadCell(index); + b.emitLoadLocal(local); + b.endClassLoadCell(); + } else { + b.beginLoadCell(index); + b.emitLoadLocal(local); + b.endLoadCell(); + } + break; + case Delete: + b.beginClearCell(index); + b.emitLoadLocal(local); + b.endClearCell(); + break; + case BeginWrite: + b.beginStoreCell(); + b.emitLoadLocal(local); + break; + case EndWrite: + b.endStoreCell(); + break; + default: + throw new UnsupportedOperationException("unknown value: " + op); + } + } + + private void emitNameFastOperation(String mangled, NameOperation op, Builder b) { + BytecodeLocal local = locals.get(mangled); + switch (op) { + case Read: + b.emitCheckAndLoadLocal(local, varnames.get(mangled)); + break; + case Delete: + b.emitDeleteLocal(local, varnames.get(mangled)); + break; + case BeginWrite: + if (local == null) { + throw new NullPointerException("local " + mangled + " not defined"); + } + b.beginStoreLocal(local); + break; + case EndWrite: + b.endStoreLocal(); + break; + default: + throw new UnsupportedOperationException("unknown value: " + op); + } + } + + private void emitNameGlobalOperation(String name, NameOperation op, Builder b) { + assert locals.get(name) == null; + names.putIfAbsent(name, names.size()); + TruffleString tsName = toTruffleStringUncached(name); + switch (op) { + case Read: + b.emitReadGlobal(tsName); + break; + case Delete: + b.emitDeleteGlobal(tsName); + break; + case BeginWrite: + b.beginWriteGlobal(tsName); + break; + case EndWrite: + b.endWriteGlobal(); + break; + default: + throw new UnsupportedOperationException("unknown value: " + op); + } + } + + private void emitNameSlowOperation(String name, NameOperation op, Builder b) { + assert locals.get(name) == null; + names.putIfAbsent(name, names.size()); + TruffleString tsName = toTruffleStringUncached(name); + switch (op) { + case Read: + b.emitReadName(tsName); + break; + case Delete: + b.emitDeleteName(tsName); + break; + case BeginWrite: + b.beginWriteName(tsName); + break; + case EndWrite: + b.endWriteName(); + break; + default: + throw new UnsupportedOperationException("unknown value: " + op); + } + } + + private void emitNameOperation(String name, NameOperation op, Builder b) { + checkForbiddenName(name, op); + + String mangled = mangle(name); + EnumSet uses = scope.getUseOfName(mangled); + + if (uses != null) { + if (uses.contains(DefUse.Free)) { + assert freevars.containsKey(mangled) : String.format("scope analysis did not mark %s as a free variable", mangled); + emitNameCellOperation(mangled, op, b); + return; + } else if (uses.contains(DefUse.Cell)) { + assert cellvars.containsKey(mangled) : String.format("scope analysis did not mark %s as a cell variable", mangled); + emitNameCellOperation(mangled, op, b); + return; + } else if (uses.contains(DefUse.Local)) { + if (scope.isFunction()) { + assert varnames.containsKey(mangled) : String.format("scope analysis did not mark %s as a regular variable", mangled); + emitNameFastOperation(mangled, op, b); + return; + } + } else if (uses.contains(DefUse.GlobalImplicit)) { + if (scope.isFunction()) { + emitNameGlobalOperation(mangled, op, b); + return; + } + } else if (uses.contains(DefUse.GlobalExplicit)) { + emitNameGlobalOperation(mangled, op, b); + return; + } + } + emitNameSlowOperation(mangled, op, b); + } + + private void emitReadLocal(String name, Builder b) { + emitNameOperation(name, NameOperation.Read, b); + } + + private void emitDelLocal(String name, Builder b) { + emitNameOperation(name, NameOperation.Delete, b); + } + + private void beginStoreLocal(String name, Builder b) { + emitNameOperation(name, NameOperation.BeginWrite, b); + } + + private void endStoreLocal(String name, Builder b) { + emitNameOperation(name, NameOperation.EndWrite, b); + } + + private BytecodeLocal getLocal(String name) { + return locals.get(mangle(name)); + } + + public void setUpFrame(ArgumentsTy args, Builder b) { + /** + * This method does two things: + * + * 1. It allocates a contiguous region in the frame for Python variables. Some nodes in the + * GraalPy AST expect locals to be allocated contiguously starting at index 0. The resultant + * frame has the following layout: + * + * [var1, var2, ..., cell1, cell2, ..., free1, free2, ..., temp1, temp2, ..., stack] + * + * The temp variables are allocated elsewhere during compilation (e.g., to store an + * intermediate computation) and the stack space is automatically reserved by the DSL. + * + * 2. It emits code to copy arguments, initialize cells, and copy free variables. + */ + + // 1. Allocate space in the frame. + if (scope.isFunction()) { + String[] regularVariables = orderedKeys(varnames, new String[0]); + for (int i = 0; i < regularVariables.length; i++) { + locals.put(regularVariables[i], b.createLocal()); + } + } + + String[] cellVariables = orderedKeys(cellvars, new String[0]); + BytecodeLocal[] cellVariableLocals = new BytecodeLocal[cellVariables.length]; + for (int i = 0; i < cellVariables.length; i++) { + BytecodeLocal local = b.createLocal(); + cellLocals.put(cellVariables[i], local); + cellVariableLocals[i] = local; + } + + String[] freeVariables = orderedKeys(freevars, new String[0]); + BytecodeLocal[] freeVariableLocals = new BytecodeLocal[freeVariables.length]; + for (int i = 0; i < freeVariables.length; i++) { + BytecodeLocal local = b.createLocal(); + freeLocals.put(freeVariables[i], local); + freeVariableLocals[i] = local; + } + + // 2. Copy arguments, initialize cells, and copy free variables. + copyArguments(args, b); + + if (cellVariableLocals.length > 0) { + List toClear = new ArrayList<>(); + + b.beginStoreRange(cellVariableLocals); + b.beginCollectToObjectArray(); + for (int i = 0; i < cellVariableLocals.length; i++) { + b.beginCreateCell(); + if (scope.getUseOfName(cellVariables[i]).contains(DefUse.DefParam)) { + /* + * To simplify the argument copying performed above, we copy cell params into + * regular locals just like all other arguments. Then, here we move the value + * into a cell and clear the regular local. + */ + BytecodeLocal param = getLocal(cellVariables[i]); + b.emitLoadLocal(param); + toClear.add(param); + } else { + b.emitLoadNull(); + } + b.endCreateCell(); + } + b.endCollectToObjectArray(); + b.endStoreRange(); + + for (BytecodeLocal local : toClear) { + b.emitClearLocal(local); + } + } + + if (freeVariableLocals.length > 0) { + b.beginStoreRange(freeVariableLocals); + b.emitLoadClosure(); + b.endStoreRange(); + } + } + + private void copyArguments(ArgumentsTy args, Builder b) { + if (args == null) { + return; + } + + int argIdx = PArguments.USER_ARGUMENTS_OFFSET; + if (args.posOnlyArgs != null) { + for (int i = 0; i < args.posOnlyArgs.length; i++) { + BytecodeLocal local = getLocal(args.posOnlyArgs[i].arg); + assert local != null; + b.beginStoreLocal(local); + b.emitLoadArgument(argIdx++); + b.endStoreLocal(); + } + } + + if (args.args != null) { + for (int i = 0; i < args.args.length; i++) { + BytecodeLocal local = getLocal(args.args[i].arg); + assert local != null; + b.beginStoreLocal(local); + b.emitLoadArgument(argIdx++); + b.endStoreLocal(); + } + } + + if (args.kwOnlyArgs != null) { + for (int i = 0; i < args.kwOnlyArgs.length; i++) { + BytecodeLocal local = getLocal(args.kwOnlyArgs[i].arg); + assert local != null; + b.beginStoreLocal(local); + b.emitLoadArgument(argIdx++); + b.endStoreLocal(); + } + } + + if (args.varArg != null) { + BytecodeLocal local = getLocal(args.varArg.arg); + assert local != null; + b.beginStoreLocal(local); + b.emitLoadVariableArguments(); + b.endStoreLocal(); + } + + if (args.kwArg != null) { + BytecodeLocal local = getLocal(args.kwArg.arg); + assert local != null; + b.beginStoreLocal(local); + b.emitLoadKeywordArguments(); + b.endStoreLocal(); + } + } + + private static int len(T[] arr) { + return arr == null ? 0 : arr.length; + } + + /* ---------------- StatementCompiler -------------------- */ + + public class StatementCompiler implements BaseBytecodeDSLVisitor { + private final Builder b; + + private BytecodeLabel breakLabel; + private BytecodeLabel continueLabel; + + public StatementCompiler(Builder b) { + this.b = b; + } + + // --------------------- visitor --------------------------- + + @Override + public Void visit(AliasTy node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(ArgTy node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(ArgumentsTy node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(ComprehensionTy node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(ExprTy.Attribute node) { + boolean newStatement = beginSourceSection(node, b); + + b.beginGetAttribute(toTruffleStringUncached(mangle(node.attr))); + node.value.accept(this); + b.endGetAttribute(); + + endSourceSection(b, newStatement); + + return null; + } + + @Override + public Void visit(ExprTy.Await node) { + // TODO if !IS_TOP_LEVEL_AWAIT + // TODO handle await in comprehension correctly (currently, it is always allowed) + if (!scope.isFunction()) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "'await' outside function"); + } + if (scopeType != CompilationScope.AsyncFunction && scopeType != CompilationScope.Comprehension) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "'await' outside async function"); + } + boolean newStatement = beginSourceSection(node, b); + emitAwait(() -> node.value.accept(this)); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.BinOp node) { + boolean newStatement = beginSourceSection(node, b); + switch (node.op) { + case Add: + b.beginPyNumberAdd(); + node.left.accept(this); + node.right.accept(this); + b.endPyNumberAdd(); + break; + case BitAnd: + b.beginPyNumberAnd(); + node.left.accept(this); + node.right.accept(this); + b.endPyNumberAnd(); + break; + case BitOr: + b.beginPyNumberOr(); + node.left.accept(this); + node.right.accept(this); + b.endPyNumberOr(); + break; + case BitXor: + b.beginPyNumberXor(); + node.left.accept(this); + node.right.accept(this); + b.endPyNumberXor(); + break; + case Div: + b.beginPyNumberTrueDivide(); + node.left.accept(this); + node.right.accept(this); + b.endPyNumberTrueDivide(); + break; + case FloorDiv: + b.beginPyNumberFloorDivide(); + node.left.accept(this); + node.right.accept(this); + b.endPyNumberFloorDivide(); + break; + case LShift: + b.beginPyNumberLshift(); + node.left.accept(this); + node.right.accept(this); + b.endPyNumberLshift(); + break; + case MatMult: + b.beginPyNumberMatrixMultiply(); + node.left.accept(this); + node.right.accept(this); + b.endPyNumberMatrixMultiply(); + break; + case Mod: + b.beginPyNumberRemainder(); + node.left.accept(this); + node.right.accept(this); + b.endPyNumberRemainder(); + break; + case Mult: + b.beginPyNumberMultiply(); + node.left.accept(this); + node.right.accept(this); + b.endPyNumberMultiply(); + break; + case Pow: + b.beginPow(); + node.left.accept(this); + node.right.accept(this); + b.endPow(); + break; + case RShift: + b.beginPyNumberRshift(); + node.left.accept(this); + node.right.accept(this); + b.endPyNumberRshift(); + break; + case Sub: + b.beginPyNumberSubtract(); + node.left.accept(this); + node.right.accept(this); + b.endPyNumberSubtract(); + break; + default: + throw new UnsupportedOperationException("" + node.getClass()); + } + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.BoolOp node) { + boolean newStatement = beginSourceSection(node, b); + + if (node.op == BoolOpTy.And) { + b.beginBoolAnd(); + } else { + b.beginBoolOr(); + } + + visitSequence(node.values); + + if (node.op == BoolOpTy.And) { + b.endBoolAnd(); + } else { + b.endBoolOr(); + } + + endSourceSection(b, newStatement); + return null; + } + + private static boolean anyIsStarred(SSTNode[] nodes) { + for (int i = 0; i < nodes.length; i++) { + if (nodes[i] instanceof ExprTy.Starred) { + return true; + } + } + + return false; + } + + protected final void validateKeywords(KeywordTy[] keywords) { + for (int i = 0; i < keywords.length; i++) { + if (keywords[i].arg != null) { + checkForbiddenName(keywords[i].arg, NameOperation.BeginWrite); + for (int j = i + 1; j < keywords.length; j++) { + if (keywords[i].arg.equals(keywords[j].arg)) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "keyword argument repeated: " + keywords[i].arg); + } + } + } + } + } + + private static boolean isAttributeLoad(ExprTy node) { + return node instanceof ExprTy.Attribute && ((ExprTy.Attribute) node).context == ExprContextTy.Load; + } + + private static final int NUM_ARGS_MAX_FIXED = 4; + + private void emitCall(ExprTy func, ExprTy[] args, KeywordTy[] keywords) { + validateKeywords(keywords); + + boolean isMethodCall = isAttributeLoad(func) && keywords.length == 0; + int numArgs = len(args) + (isMethodCall ? 1 : 0); + boolean useVariadic = anyIsStarred(args) || len(keywords) > 0 || numArgs > NUM_ARGS_MAX_FIXED; + + // @formatter:off + if (useVariadic) { + b.beginCallVarargsMethod(); + } else { + switch (numArgs) { + case 0: b.beginCallNilaryMethod(); break; + case 1: b.beginCallUnaryMethod(); break; + case 2: b.beginCallBinaryMethod(); break; + case 3: b.beginCallTernaryMethod(); break; + case 4: b.beginCallQuaternaryMethod(); break; + } + } + + // @formatter:on + + if (isMethodCall) { + // The receiver is needed for method lookup and for the first argument. + BytecodeLocal receiver = b.createLocal(); + + if (useVariadic) { + BytecodeLocal function = b.createLocal(); + b.beginBlock(); + b.beginStoreLocal(function); + emitGetMethod(func, receiver); + b.endStoreLocal(); + b.emitLoadLocal(function); + b.endBlock(); + + emitUnstar(() -> b.emitLoadLocal(receiver), args); + emitKeywords(keywords, function); + } else { + assert len(keywords) == 0; + + emitGetMethod(func, receiver); + b.emitLoadLocal(receiver); + visitSequence(args); + } + + } else { + if (useVariadic) { + BytecodeLocal function = b.createLocal(); + + b.beginBlock(); + b.beginStoreLocal(function); + func.accept(this); + b.endStoreLocal(); + b.emitLoadLocal(function); + b.endBlock(); + + emitUnstar(args); + emitKeywords(keywords, function); + } else { + assert len(keywords) == 0; + + func.accept(this); + visitSequence(args); + } + } + + // @formatter:off + if (useVariadic) { + b.endCallVarargsMethod(); + } else { + switch (numArgs) { + case 0: b.endCallNilaryMethod(); break; + case 1: b.endCallUnaryMethod(); break; + case 2: b.endCallBinaryMethod(); break; + case 3: b.endCallTernaryMethod(); break; + case 4: b.endCallQuaternaryMethod(); break; + } + } + // @formatter:on + } + + private void emitGetMethod(ExprTy func, BytecodeLocal receiver) { + assert isAttributeLoad(func); + ExprTy.Attribute attrAccess = (ExprTy.Attribute) func; + b.beginBlock(); + b.beginStoreLocal(receiver); + attrAccess.value.accept(this); + b.endStoreLocal(); + + String mangled = mangle(attrAccess.attr); + b.beginGetMethod(toTruffleStringUncached(mangled)); + b.emitLoadLocal(receiver); + b.endGetMethod(); + b.endBlock(); + } + + @Override + public Void visit(ExprTy.Call node) { + boolean newStatement = beginSourceSection(node, b); + emitCall(node.func, node.args, node.keywords); + endSourceSection(b, newStatement); + return null; + } + + private void beginComparison(CmpOpTy op) { + switch (op) { + case Eq: + b.beginEq(); + break; + case NotEq: + b.beginNe(); + break; + case Lt: + b.beginLt(); + break; + case LtE: + b.beginLe(); + break; + case Gt: + b.beginGt(); + break; + case GtE: + b.beginGe(); + break; + case Is: + b.beginIs(); + break; + case IsNot: + b.beginNot(); + b.beginIs(); + break; + case In: + b.beginContains(); + break; + case NotIn: + b.beginNot(); + b.beginContains(); + break; + default: + throw new UnsupportedOperationException("" + op); + } + } + + private void endComparison(CmpOpTy op) { + switch (op) { + case Eq: + b.endEq(); + break; + case NotEq: + b.endNe(); + break; + case Lt: + b.endLt(); + break; + case LtE: + b.endLe(); + break; + case Gt: + b.endGt(); + break; + case GtE: + b.endGe(); + break; + case Is: + b.endIs(); + break; + case IsNot: + b.endIs(); + b.endNot(); + break; + case In: + b.endContains(); + break; + case NotIn: + b.endContains(); + b.endNot(); + break; + default: + throw new UnsupportedOperationException("" + op); + } + } + + @Override + public Void visit(ExprTy.Compare node) { + boolean newStatement = beginSourceSection(node, b); + checkCompare(node); + + boolean multipleComparisons = node.comparators.length > 1; + + if (multipleComparisons) { + b.beginBoolAnd(); + } + + BytecodeLocal tmp = b.createLocal(); + + for (int i = 0; i < node.comparators.length; i++) { + beginComparison(node.ops[i]); + + if (i == 0) { + node.left.accept(this); + } else { + b.emitLoadLocal(tmp); + } + + if (i != node.comparators.length - 1) { + b.beginTeeLocal(tmp); + } + node.comparators[i].accept(this); + if (i != node.comparators.length - 1) { + b.endTeeLocal(); + } + + endComparison(node.ops[i]); + } + + if (multipleComparisons) { + b.endBoolAnd(); + } + + endSourceSection(b, newStatement); + return null; + } + + private void warn(SSTNode node, String message, Object... arguments) { + ctx.errorCallback.onWarning(WarningType.Syntax, node.getSourceRange(), message, arguments); + } + + private void checkCompare(ExprTy node) { + if (!(node instanceof ExprTy.Compare compare)) { + return; + } + boolean left = checkIsArg(compare.left); + int n = compare.ops == null ? 0 : compare.ops.length; + for (int i = 0; i < n; ++i) { + CmpOpTy op = compare.ops[i]; + boolean right = checkIsArg(compare.comparators[i]); + if (op == CmpOpTy.Is || op == CmpOpTy.IsNot) { + if (!right || !left) { + warn(compare, op == CmpOpTy.Is ? "\"is\" with a literal. Did you mean \"==\"?" : "\"is not\" with a literal. Did you mean \"!=\"?"); + } + } + left = right; + } + } + + private static boolean checkIsArg(ExprTy e) { + if (e instanceof ExprTy.Constant) { + ConstantValue.Kind kind = ((Constant) e).value.kind; + return kind == Kind.NONE || kind == Kind.BOOLEAN || kind == Kind.ELLIPSIS; + } + return true; + } + + private void createConstant(ConstantValue value) { + switch (value.kind) { + case NONE: + b.emitLoadConstant(PNone.NONE); + break; + case ELLIPSIS: + b.emitLoadConstant(PEllipsis.INSTANCE); + break; + case BOOLEAN: + emitPythonConstant(value.getBoolean(), b); + break; + case LONG: + emitPythonConstant(getConstantNumber(value.getLong()), b); + break; + case DOUBLE: + emitPythonConstant(value.getDouble(), b); + break; + case COMPLEX: { + double[] complex = value.getComplex(); + addConstant(complex); + b.emitLoadComplex(complex[0], complex[1]); + break; + } + case BIGINTEGER: + addConstant(value.getBigInteger()); + b.emitLoadBigInt(value.getBigInteger()); + break; + case RAW: + emitPythonConstant(value.getRaw(TruffleString.class), b); + break; + case BYTES: + addConstant(value.getBytes()); + b.emitLoadBytes(value.getBytes()); + break; + case TUPLE: + b.beginMakeTuple(); + b.beginCollectToObjectArray(); + for (ConstantValue cv : value.getTupleElements()) { + createConstant(cv); + } + b.endCollectToObjectArray(); + b.endMakeTuple(); + break; + case FROZENSET: + b.beginMakeFrozenSet(); + for (ConstantValue cv : value.getFrozensetElements()) { + createConstant(cv); + } + b.endMakeFrozenSet(); + break; + + default: + throw new UnsupportedOperationException("not supported: " + value.kind); + } + } + + /** + * Some AST nodes have type guards expecting ints rather than long. When the actual constant + * fits into something smaller, convert it accordingly. + */ + private Object getConstantNumber(long value) { + if (value == (int) value) { + return (int) value; + } else { + return value; + } + } + + @Override + public Void visit(ExprTy.Constant node) { + boolean newStatement = beginSourceSection(node, b); + createConstant(node.value); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.Dict node) { + boolean newStatement = beginSourceSection(node, b); + + if (len(node.keys) == 0) { + b.beginMakeDict(0); + b.endMakeDict(); + } else { + b.beginMakeDict(node.keys.length); + for (int i = 0; i < node.keys.length; i++) { + if (node.keys[i] == null) { + b.emitLoadConstant(PNone.NO_VALUE); + } else { + node.keys[i].accept(this); + } + node.values[i].accept(this); + } + b.endMakeDict(); + } + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.DictComp node) { + boolean newStatement = beginSourceSection(node, b); + + b.beginCallUnaryMethod(); + emitMakeFunction(node, "", COMPREHENSION_ARGS, null); + node.generators[0].iter.accept(this); + b.endCallUnaryMethod(); + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.FormattedValue node) { + boolean newStatement = beginSourceSection(node, b); + b.beginFormat(); + + // @formatter:off + switch (node.conversion) { + case 's': b.beginFormatStr(); break; + case 'r': b.beginFormatRepr(); break; + case 'a': b.beginFormatAscii(); break; + case -1: break; + default: throw new UnsupportedOperationException("unknown conversion: " + node.conversion); + } + // @formatter:on + + node.value.accept(this); + + // @formatter:off + switch (node.conversion) { + case 's': b.endFormatStr(); break; + case 'r': b.endFormatRepr(); break; + case 'a': b.endFormatAscii(); break; + case -1: break; + default: throw new UnsupportedOperationException("unknown conversion: " + node.conversion); + } + // @formatter:on + + if (node.formatSpec != null) { + node.formatSpec.accept(this); + } else { + b.emitLoadConstant(StringLiterals.T_EMPTY_STRING); + } + + b.endFormat(); + endSourceSection(b, newStatement); + + return null; + } + + @Override + public Void visit(ExprTy.GeneratorExp node) { + boolean newStatement = beginSourceSection(node, b); + + b.beginCallUnaryMethod(); + emitMakeFunction(node, "", COMPREHENSION_ARGS, null); + node.generators[0].iter.accept(this); + b.endCallUnaryMethod(); + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.IfExp node) { + boolean newStatement = beginSourceSection(node, b); + + b.beginConditional(); + visitCondition(node.test); + node.body.accept(this); + node.orElse.accept(this); + b.endConditional(); + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.JoinedStr node) { + boolean newStatement = beginSourceSection(node, b); + + if (node.values.length == 1) { + node.values[0].accept(this); + } else { + b.beginBuildString(node.values.length); + visitSequence(node.values); + b.endBuildString(); + } + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.Lambda node) { + boolean newStatement = beginSourceSection(node, b); + emitMakeFunction(node, "", node.args, null); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.List node) { + boolean newStatement = beginSourceSection(node, b); + + ConstantCollection constantCollection = Compiler.tryCollectConstantCollection(node.elements); + if (constantCollection != null) { + emitConstantList(constantCollection); + } else { + b.beginMakeList(); + emitUnstar(node.elements); + b.endMakeList(); + } + + endSourceSection(b, newStatement); + return null; + } + + private static final String COMPREHENSION_ARGUMENT_NAME = ".0"; + private static final ArgumentsTy COMPREHENSION_ARGS = new ArgumentsTy(new ArgTy[]{new ArgTy(COMPREHENSION_ARGUMENT_NAME, null, null, null)}, null, null, null, null, null, null, null); + + @Override + public Void visit(ExprTy.ListComp node) { + boolean newStatement = beginSourceSection(node, b); + + b.beginCallUnaryMethod(); + emitMakeFunction(node, "", COMPREHENSION_ARGS, null); + node.generators[0].iter.accept(this); + b.endCallUnaryMethod(); + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.Name node) { + boolean newStatement = beginSourceSection(node, b); + emitReadLocal(node.id, b); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.NamedExpr node) { + boolean newStatement = beginSourceSection(node, b); + b.beginBlock(); + + // save expr result to "tmp" + BytecodeLocal tmp = b.createLocal(); + b.beginStoreLocal(tmp); + node.value.accept(this); + b.endStoreLocal(); + + node.target.accept(new StoreVisitor(() -> { + b.emitLoadLocal(tmp); + })); + + b.emitLoadLocal(tmp); + + b.endBlock(); + endSourceSection(b, newStatement); + return null; + } + + private void emitConstantList(ConstantCollection constantCollection) { + addConstant(constantCollection.collection); + switch (constantCollection.elementType) { + case CollectionBits.ELEMENT_INT: + b.emitMakeConstantIntList((int[]) constantCollection.collection); + break; + case CollectionBits.ELEMENT_LONG: + b.emitMakeConstantLongList((long[]) constantCollection.collection); + break; + case CollectionBits.ELEMENT_BOOLEAN: + b.emitMakeConstantBooleanList((boolean[]) constantCollection.collection); + break; + case CollectionBits.ELEMENT_DOUBLE: + b.emitMakeConstantDoubleList((double[]) constantCollection.collection); + break; + case CollectionBits.ELEMENT_OBJECT: + b.emitMakeConstantObjectList((Object[]) constantCollection.collection); + break; + default: + throw CompilerDirectives.shouldNotReachHere(); + } + } + + private void emitConstantTuple(ConstantCollection constantCollection) { + addConstant(constantCollection.collection); + switch (constantCollection.elementType) { + case CollectionBits.ELEMENT_INT: + b.emitMakeConstantIntTuple((int[]) constantCollection.collection); + break; + case CollectionBits.ELEMENT_LONG: + b.emitMakeConstantLongTuple((long[]) constantCollection.collection); + break; + case CollectionBits.ELEMENT_BOOLEAN: + b.emitMakeConstantBooleanTuple((boolean[]) constantCollection.collection); + break; + case CollectionBits.ELEMENT_DOUBLE: + b.emitMakeConstantDoubleTuple((double[]) constantCollection.collection); + break; + case CollectionBits.ELEMENT_OBJECT: + b.emitMakeConstantObjectTuple((Object[]) constantCollection.collection); + break; + default: + throw CompilerDirectives.shouldNotReachHere(); + } + } + + /** + * Converts a sequence of expressions of which some may be starred into just an Object[]. + * + * @param args the sequence of expressions + */ + private void emitUnstar(ExprTy[] args) { + emitUnstar(null, args); + } + + /** + * Same as above, but takes an optional Runnable to produce elements at the beginning of the + * sequence. + * + * @param initialElementsProducer a runnable to produce the first element(s) of the + * sequence. + * @param args the sequence of expressions to unstar + */ + private void emitUnstar(Runnable initialElementsProducer, ExprTy[] args) { + if (initialElementsProducer == null && len(args) == 0) { + b.emitLoadConstant(PythonUtils.EMPTY_OBJECT_ARRAY); + } else if (initialElementsProducer == null && len(args) == 1 && args[0] instanceof ExprTy.Starred) { + // Optimization for single starred argument: we can just upack it. For generic + // algorithm see the next branch + b.beginUnpackStarred(); + ((ExprTy.Starred) args[0]).value.accept(this); + b.endUnpackStarred(); + } else if (anyIsStarred(args)) { + /** + * We emit one or more arrays and concatenate them using Unstar. Each array + * corresponds to a contiguous sequence of arguments or the result of unpacking a + * single starred argument. + * + * For example, for the argument list a, b, *c, d, e, *f, g we would emit: + * + * @formatter:off + * Unstar( + * CollectToObjectArray(a, b), + * UnpackStarred(c), + * CollectToObjectArray(d, e), + * UnpackStarred(f), + * CollectToObjectArray(g) + * ) + * @formatter:on + */ + b.beginUnstar(); + boolean inVariadic = false; + int numOperands = 0; + + if (initialElementsProducer != null) { + b.beginCollectToObjectArray(); + initialElementsProducer.run(); + inVariadic = true; + } + + for (int i = 0; i < args.length; i++) { + if (args[i] instanceof ExprTy.Starred) { + if (inVariadic) { + b.endCollectToObjectArray(); + inVariadic = false; + numOperands++; + } + + b.beginUnpackStarred(); + ((ExprTy.Starred) args[i]).value.accept(this); + b.endUnpackStarred(); + numOperands++; + } else { + if (!inVariadic) { + b.beginCollectToObjectArray(); + inVariadic = true; + } + + args[i].accept(this); + } + } + + if (inVariadic) { + b.endCollectToObjectArray(); + numOperands++; + } + + b.endUnstar(numOperands); + } else { + b.beginCollectToObjectArray(); + if (initialElementsProducer != null) { + initialElementsProducer.run(); + } + visitSequence(args); + b.endCollectToObjectArray(); + } + } + + @Override + public Void visit(ExprTy.Set node) { + boolean newStatement = beginSourceSection(node, b); + b.beginMakeSet(); + if (len(node.elements) == 0) { + b.emitLoadConstant(PythonUtils.EMPTY_OBJECT_ARRAY); + } else { + emitUnstar(node.elements); + } + b.endMakeSet(); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.SetComp node) { + boolean newStatement = beginSourceSection(node, b); + + b.beginCallUnaryMethod(); + emitMakeFunction(node, "", COMPREHENSION_ARGS, null); + node.generators[0].iter.accept(this); + b.endCallUnaryMethod(); + + endSourceSection(b, newStatement); + return null; + } + + private void visitNoneable(ExprTy node) { + if (node == null) { + b.emitLoadConstant(PNone.NONE); + } else { + node.accept(this); + } + } + + @Override + public Void visit(ExprTy.Slice node) { + boolean newStatement = beginSourceSection(node, b); + + b.beginMakeSlice(); + + visitNoneable(node.lower); + visitNoneable(node.upper); + visitNoneable(node.step); + + b.endMakeSlice(); + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.Starred node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(ExprTy.Subscript node) { + boolean newStatement = beginSourceSection(node, b); + b.beginBinarySubscript(); + node.value.accept(this); + node.slice.accept(this); + b.endBinarySubscript(); + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.Tuple node) { + boolean newStatement = beginSourceSection(node, b); + + ConstantCollection constantCollection = Compiler.tryCollectConstantCollection(node.elements); + if (constantCollection != null) { + emitConstantTuple(constantCollection); + } else { + b.beginMakeTuple(); + emitUnstar(node.elements); + b.endMakeTuple(); + } + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.UnaryOp node) { + // Basic constant folding for unary negation + if (node.op == UnaryOpTy.USub && node.operand instanceof ExprTy.Constant c) { + if (c.value.kind == ConstantValue.Kind.BIGINTEGER || c.value.kind == ConstantValue.Kind.DOUBLE || c.value.kind == ConstantValue.Kind.LONG || + c.value.kind == ConstantValue.Kind.COMPLEX) { + ConstantValue cv = c.value.negate(); + boolean newStatement = beginSourceSection(node, b); + visit(new ExprTy.Constant(cv, null, c.getSourceRange())); + endSourceSection(b, newStatement); + return null; + } + } + boolean newStatement = beginSourceSection(node, b); + switch (node.op) { + case UAdd: + b.beginPyNumberPositive(); + node.operand.accept(this); + b.endPyNumberPositive(); + break; + case Invert: + b.beginPyNumberInvert(); + node.operand.accept(this); + b.endPyNumberInvert(); + break; + case USub: + b.beginPyNumberNegative(); + node.operand.accept(this); + b.endPyNumberNegative(); + break; + case Not: + b.beginNot(); + node.operand.accept(this); + b.endNot(); + break; + default: + throw new UnsupportedOperationException("" + node.getClass()); + } + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.Yield node) { + if (!scope.isFunction()) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "'yield' outside function"); + } + boolean newStatement = beginSourceSection(node, b); + emitYield((statementCompiler) -> { + if (node.value != null) { + node.value.accept(this); + } else { + statementCompiler.b.emitLoadConstant(PNone.NONE); + } + }, this); + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.YieldFrom node) { + if (!scope.isFunction()) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "'yield' outside function"); + } + if (scopeType == CompilationScope.AsyncFunction) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "'yield from' inside async function"); + } + boolean newStatement = beginSourceSection(node, b); + emitYieldFrom(() -> { + b.beginGetYieldFromIter(); + node.value.accept(this); + b.endGetYieldFromIter(); + }); + endSourceSection(b, newStatement); + return null; + } + + public void emitYieldFrom(Runnable generatorOrCoroutineProducer) { + /** + * @formatter:off + * generator = + * returnValue = None + * sentValue = None + * + * # Step 1: prime the generator + * try: + * yieldValue = generator.send(sentValue) + * except StopIteration as e: + * returnValue = e.value + * goto end + * + * while True: + * # Step 2: yield yieldValue to the caller + * try: + * sentValue = yield yieldValue + * except Exception as e: + * # throw/close generator + * if generator returned a value: + * goto end + * else: + * continue (generator yielded a value) + * + * # Step 3: send sentValue into the generator + * try: + * yieldValue = generator.send(sentValue) + * except StopIteration as e: + * returnValue = e.value + * goto end + * + * end: + * # Step 4: return returnValue + * returnValue (result) + * @formatter:on + */ + b.beginBlock(); + + BytecodeLocal generator = b.createLocal(); + BytecodeLocal returnValue = b.createLocal(); + BytecodeLocal sentValue = b.createLocal(); + BytecodeLocal yieldValue = b.createLocal(); + BytecodeLabel end = b.createLabel(); + + b.beginStoreLocal(generator); + generatorOrCoroutineProducer.run(); + b.endStoreLocal(); + + b.beginStoreLocal(returnValue); + b.emitLoadConstant(PNone.NONE); + b.endStoreLocal(); + + b.beginStoreLocal(sentValue); + b.emitLoadConstant(PNone.NONE); + b.endStoreLocal(); + + // Step 1: prime the generator + emitSend(generator, sentValue, yieldValue, returnValue, end); + + b.beginWhile(); + b.emitLoadConstant(true); + + b.beginBlock(); + BytecodeLabel loopEnd = b.createLabel(); + // Step 2: yield yieldValue to the caller + b.beginTryCatch(); + + // try clause: yield + b.beginStoreLocal(sentValue); + emitYield((statementCompiler) -> statementCompiler.b.emitLoadLocal(yieldValue), this); + b.endStoreLocal(); + + // catch clause: handle throw/close exceptions. + b.beginIfThenElse(); + b.beginYieldFromThrow(yieldValue, returnValue); + b.emitLoadLocal(generator); + b.emitLoadException(); + b.endYieldFromThrow(); + + // StopIteration was raised; go to the end. + b.emitBranch(end); + + // The generator yielded a value; go to top of the loop. + b.emitBranch(loopEnd); + + b.endIfThenElse(); + + b.endTryCatch(); + + // Step 3: send sentValue into the generator + emitSend(generator, sentValue, yieldValue, returnValue, end); + + b.emitLabel(loopEnd); + b.endBlock(); + b.endWhile(); + + // Step 4: return returnValue + b.emitLabel(end); + b.emitLoadLocal(returnValue); + + b.endBlock(); + } + + private void emitSend(BytecodeLocal generator, BytecodeLocal sentValue, BytecodeLocal yieldValue, BytecodeLocal returnValue, BytecodeLabel end) { + b.beginIfThen(); + // When the generator raises StopIteration, send evaluates to true; branch to the end. + b.beginYieldFromSend(yieldValue, returnValue); + b.emitLoadLocal(generator); + b.emitLoadLocal(sentValue); + b.endYieldFromSend(); + + b.emitBranch(end); + + b.endIfThen(); + } + + private void emitAwait(Runnable producer) { + emitYieldFrom(() -> { + b.beginGetAwaitable(); + producer.run(); + b.endGetAwaitable(); + }); + } + + @Override + public Void visit(KeywordTy node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(StmtTy.AnnAssign node) { + boolean newStatement = beginSourceSection(node, b); + b.beginBlock(); + if (node.value != null) { + // Emit the assignment if there's an RHS. + emitAssignment(new ExprTy[]{node.target}, node.value); + } + if (node.target instanceof ExprTy.Name) { + String name = ((ExprTy.Name) node.target).id; + checkForbiddenName(name, NameOperation.BeginWrite); + /* If we have a simple name in a module or class, store annotation. */ + if (node.isSimple && + (scopeType == CompilationScope.Module || scopeType == CompilationScope.Class)) { + b.beginSetDictItem(); + emitNameOperation("__annotations__", NameOperation.Read, b); + + String mangled = mangle(name); + emitPythonConstant(toTruffleStringUncached(mangled), b); + + if (futureFeatures.contains(FutureFeature.ANNOTATIONS)) { + emitPythonConstant(Unparser.unparse(node.annotation), b); + } else { + node.annotation.accept(this); + } + + b.endSetDictItem(); + } + } else if (node.target instanceof ExprTy.Attribute) { + if (node.value == null) { + ExprTy.Attribute attr = (ExprTy.Attribute) node.target; + checkForbiddenName(attr.attr, NameOperation.BeginWrite); + if (attr.value != null) { + checkAnnExpr(attr.value); + } + } + } else if (node.target instanceof ExprTy.Subscript) { + if (node.value == null) { + ExprTy.Subscript subscript = (ExprTy.Subscript) node.target; + if (subscript.value != null) { + checkAnnExpr(subscript.value); + } + checkAnnSubscr(subscript.slice); + } + } else { + ctx.errorCallback.onError(ErrorType.Syntax, node.getSourceRange(), "invalid node type for annotated assignment"); + } + if (!node.isSimple) { + /* + * Annotations of complex targets does not produce anything under annotations + * future. Annotations are only evaluated in a module or class. + */ + if (!futureFeatures.contains(FutureFeature.ANNOTATIONS) && (scopeType == CompilationScope.Module || scopeType == CompilationScope.Class)) { + checkAnnExpr(node.annotation); + } + } + b.endBlock(); + endSourceSection(b, newStatement); + return null; + } + + private void checkAnnExpr(ExprTy expr) { + expr.accept(this); + } + + private void checkAnnSubscr(ExprTy expr) { + if (expr instanceof ExprTy.Slice) { + ExprTy.Slice slice = (ExprTy.Slice) expr; + if (slice.lower != null) { + checkAnnExpr(slice.lower); + } + if (slice.upper != null) { + checkAnnExpr(slice.upper); + } + if (slice.step != null) { + checkAnnExpr(slice.step); + } + } else if (expr instanceof ExprTy.Tuple) { + ExprTy.Tuple tuple = (ExprTy.Tuple) expr; + for (int i = 0; i < tuple.elements.length; i++) { + checkAnnSubscr(tuple.elements[i]); + } + } else { + checkAnnExpr(expr); + } + } + + @Override + public Void visit(StmtTy.Assert node) { + if (ctx.optimizationLevel <= 0) { + boolean newStatement = beginSourceSection(node, b); + b.beginIfThen(); + + b.beginNot(); + node.test.accept(this); + b.endNot(); + + b.beginAssertFailed(); + if (node.msg == null) { + b.emitLoadConstant(PNone.NO_VALUE); + } else { + node.msg.accept(this); + } + b.endAssertFailed(); + + b.endIfThen(); + endSourceSection(b, newStatement); + } + return null; + } + + // --------------------- assign ------------------------ + + /** + * Generates code to store the value produced by {@link #generateValue} into the visited + * expression. + */ + public class StoreVisitor implements BaseBytecodeDSLVisitor { + private final Builder b = StatementCompiler.this.b; + private final Runnable generateValue; + + StoreVisitor(Runnable generateValue) { + this.generateValue = generateValue; + } + + @Override + public Void visit(ExprTy.Name node) { + boolean newStatement = beginSourceSection(node, b); + beginStoreLocal(node.id, b); + generateValue.run(); + endStoreLocal(node.id, b); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.Attribute node) { + boolean newStatement = beginSourceSection(node, b); + checkForbiddenName(node.attr, NameOperation.BeginWrite); + b.beginSetAttribute(toTruffleStringUncached(mangle(node.attr))); + generateValue.run(); + node.value.accept(StatementCompiler.this); + b.endSetAttribute(); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.Subscript node) { + boolean newStatement = beginSourceSection(node, b); + b.beginSetItem(); + generateValue.run(); + node.value.accept(StatementCompiler.this); + node.slice.accept(StatementCompiler.this); + b.endSetItem(); + endSourceSection(b, newStatement); + return null; + } + + /** + * This method unpacks the rhs (a sequence/iterable) to the elements on the lhs + * (specified by {@code nodes}. + */ + private void visitIterableAssign(ExprTy[] nodes) { + b.beginBlock(); + + /** + * The rhs should be fully evaluated and unpacked into the expected number of + * elements before storing values into the lhs (e.g., if an lhs element is f().attr, + * but computing or unpacking rhs throws, f() is not computed). Thus, the unpacking + * step stores the unpacked values into intermediate variables, and then those + * variables are copied into the lhs elements afterward. + */ + BytecodeLocal[] targets = new BytecodeLocal[nodes.length]; + for (int i = 0; i < targets.length; i++) { + targets[i] = b.createLocal(); + } + + int indexOfStarred = -1; + for (int i = 0; i < nodes.length; i++) { + if (nodes[i] instanceof ExprTy.Starred) { + indexOfStarred = i; + break; + } + } + + if (indexOfStarred == -1) { + b.beginUnpackToLocals(targets); + } else { + b.beginUnpackStarredToLocals(indexOfStarred, targets); + } + + generateValue.run(); + + if (indexOfStarred == -1) { + b.endUnpackToLocals(); + } else { + b.endUnpackStarredToLocals(); + } + + for (int i = 0; i < nodes.length; i++) { + final int index = i; + + ExprTy target = nodes[i]; + if (nodes[i] instanceof ExprTy.Starred) { + target = ((ExprTy.Starred) target).value; + } + + target.accept(new StoreVisitor(() -> { + b.emitLoadLocal(targets[index]); + })); + } + + b.endBlock(); + } + + @Override + public Void visit(ExprTy.Tuple node) { + boolean newStatement = beginSourceSection(node, b); + visitIterableAssign(node.elements); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.List node) { + boolean newStatement = beginSourceSection(node, b); + visitIterableAssign(node.elements); + endSourceSection(b, newStatement); + return null; + } + } + + private class AugStoreVisitor implements BaseBytecodeDSLVisitor { + private final Builder b = StatementCompiler.this.b; + private final ExprTy value; + private final OperatorTy op; + + AugStoreVisitor(OperatorTy op, ExprTy value) { + this.op = op; + this.value = value; + } + + private void beginAugAssign() { + switch (op) { + case Add -> b.beginPyNumberInPlaceAdd(); + case Sub -> b.beginPyNumberInPlaceSubtract(); + case Mult -> b.beginPyNumberInPlaceMultiply(); + case FloorDiv -> b.beginPyNumberInPlaceFloorDivide(); + case BitAnd -> b.beginPyNumberInPlaceAnd(); + case BitOr -> b.beginPyNumberInPlaceOr(); + case BitXor -> b.beginPyNumberInPlaceXor(); + case RShift -> b.beginPyNumberInPlaceRshift(); + case LShift -> b.beginPyNumberInPlaceLshift(); + case Div -> b.beginPyNumberInPlaceTrueDivide(); + case Mod -> b.beginPyNumberInPlaceRemainder(); + case MatMult -> b.beginPyNumberInPlaceMatrixMultiply(); + case Pow -> b.beginInPlacePow(); + default -> throw new UnsupportedOperationException("aug ass: " + op); + } + } + + private void endAugAssign() { + switch (op) { + case Add -> b.endPyNumberInPlaceAdd(); + case Sub -> b.endPyNumberInPlaceSubtract(); + case Mult -> b.endPyNumberInPlaceMultiply(); + case FloorDiv -> b.endPyNumberInPlaceFloorDivide(); + case BitAnd -> b.endPyNumberInPlaceAnd(); + case BitOr -> b.endPyNumberInPlaceOr(); + case BitXor -> b.endPyNumberInPlaceXor(); + case RShift -> b.endPyNumberInPlaceRshift(); + case LShift -> b.endPyNumberInPlaceLshift(); + case Div -> b.endPyNumberInPlaceTrueDivide(); + case Mod -> b.endPyNumberInPlaceRemainder(); + case MatMult -> b.endPyNumberInPlaceMatrixMultiply(); + case Pow -> b.endInPlacePow(); + default -> throw new UnsupportedOperationException("aug ass: " + op); + } + } + + @Override + public Void visit(ExprTy.Name node) { + boolean newStatement = beginSourceSection(node, b); + + beginStoreLocal(node.id, b); + beginAugAssign(); + emitReadLocal(node.id, b); + value.accept(StatementCompiler.this); + endAugAssign(); + endStoreLocal(node.id, b); + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.Attribute node) { + boolean newStatement = beginSourceSection(node, b); + checkForbiddenName(node.attr, NameOperation.BeginWrite); + b.beginBlock(); + // { + BytecodeLocal target = b.createLocal(); + + b.beginStoreLocal(target); + node.value.accept(StatementCompiler.this); + b.endStoreLocal(); + + TruffleString attrName = toTruffleStringUncached(mangle(node.attr)); + b.beginSetAttribute(attrName); + beginAugAssign(); + + b.beginGetAttribute(attrName); + b.emitLoadLocal(target); + b.endGetAttribute(); + + value.accept(StatementCompiler.this); + + endAugAssign(); + + b.emitLoadLocal(target); + b.endSetAttribute(); + // } + b.endBlock(); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.Subscript node) { + boolean newStatement = beginSourceSection(node, b); + b.beginBlock(); + // { + BytecodeLocal target = b.createLocal(); + BytecodeLocal slice = b.createLocal(); + + b.beginStoreLocal(target); + node.value.accept(StatementCompiler.this); + b.endStoreLocal(); + + b.beginStoreLocal(slice); + node.slice.accept(StatementCompiler.this); + b.endStoreLocal(); + + b.beginSetItem(); + beginAugAssign(); + + b.beginBinarySubscript(); + b.emitLoadLocal(target); + b.emitLoadLocal(slice); + b.endBinarySubscript(); + + value.accept(StatementCompiler.this); + + endAugAssign(); + + b.emitLoadLocal(target); + b.emitLoadLocal(slice); + b.endSetItem(); + // } + b.endBlock(); + endSourceSection(b, newStatement); + return null; + } + } + + @Override + public Void visit(StmtTy.Assign node) { + boolean newStatement = beginSourceSection(node, b); + b.beginBlock(); + emitAssignment(node.targets, node.value); + b.endBlock(); + endSourceSection(b, newStatement); + return null; + } + + private void emitAssignment(ExprTy[] targets, ExprTy value) { + if (targets.length == 1) { + targets[0].accept(new StoreVisitor(() -> { + value.accept(this); + })); + } else { + BytecodeLocal tmp = b.createLocal(); + b.beginStoreLocal(tmp); + value.accept(this); + b.endStoreLocal(); + + for (ExprTy target : targets) { + target.accept(new StoreVisitor(() -> { + b.emitLoadLocal(tmp); + })); + } + } + } + + @Override + public Void visit(StmtTy.AsyncFor node) { + emitNotImplemented("async for", b); + return null; + } + + @Override + public Void visit(StmtTy.AsyncWith node) { + if (!scope.isFunction()) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "'async with' outside function"); + } + if (scopeType != CompilationScope.AsyncFunction && scopeType != CompilationScope.Comprehension) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "'async with' outside async function"); + } + boolean newStatement = beginSourceSection(node, b); + visitWithRecurse(node.items, 0, node.body, true); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(StmtTy.AugAssign node) { + boolean newStatement = beginSourceSection(node, b); + node.target.accept(new AugStoreVisitor(node.op, node.value)); + endSourceSection(b, newStatement); + return null; + } + + private abstract static sealed class KeywordGroup permits NamedKeywords, SplatKeywords { + } + + private static final class NamedKeywords extends KeywordGroup { + final ArrayList names; + final ArrayList values; + + NamedKeywords(ArrayList names, ArrayList values) { + this.names = names; + this.values = values; + } + } + + private static final class SplatKeywords extends KeywordGroup { + final ExprTy expr; + + SplatKeywords(ExprTy expr) { + this.expr = expr; + } + } + + private void emitKeywords(KeywordTy[] kws, BytecodeLocal function) { + if (len(kws) == 0) { + b.emitLoadConstant(PKeyword.EMPTY_KEYWORDS); + } else { + KeywordGroup[] groups = partitionKeywords(kws); + // The nodes that validate keyword arguments operate on PDicts, so we convert into + // a list of PKeywords after validation. + b.beginMappingToKeywords(); + emitKeywordsRecursive(groups, groups.length - 1, function); + b.endMappingToKeywords(); + } + } + + private KeywordGroup[] partitionKeywords(KeywordTy[] kws) { + ArrayList groups = new ArrayList<>(); + + int i = 0; + while (i < kws.length) { + if (kws[i].arg == null) { + // splat + groups.add(new SplatKeywords(kws[i].value)); + i++; + } else { + // named keyword + ArrayList kwNames = new ArrayList<>(); + ArrayList kwValues = new ArrayList<>(); + while (i < kws.length && kws[i].arg != null) { + kwNames.add(toTruffleStringUncached(kws[i].arg)); + kwValues.add(kws[i].value); + i++; + } + groups.add(new NamedKeywords(kwNames, kwValues)); + } + } + + return groups.toArray(KeywordGroup[]::new); + } + + private void emitKeywordsRecursive(KeywordGroup[] groups, int i, BytecodeLocal function) { + /* + * Keyword groups should be merged left-to-right. For example, for groups [A, B, C] we + * should emit KwArgsMerge(KwArgsMerge(A, B), C). + */ + if (i == 0) { + emitKeywordGroup(groups[i], true, function); + } else { + b.beginKwargsMerge(function); + emitKeywordsRecursive(groups, i - 1, function); + emitKeywordGroup(groups[i], false, function); + b.endKwargsMerge(); + } + } + + private void emitKeywordGroup(KeywordGroup group, boolean copy, BytecodeLocal function) { + if (group instanceof NamedKeywords namedKeywords) { + b.beginMakeDict(namedKeywords.names.size()); + for (int i = 0; i < namedKeywords.names.size(); i++) { + emitPythonConstant(namedKeywords.names.get(i), b); + namedKeywords.values.get(i).accept(this); + } + b.endMakeDict(); + } else { + SplatKeywords splatKeywords = (SplatKeywords) group; + + if (copy) { + b.beginKwargsMerge(function); + b.beginMakeDict(0); + b.endMakeDict(); + splatKeywords.expr.accept(this); + b.endKwargsMerge(); + } else { + splatKeywords.expr.accept(this); + } + } + } + + @Override + public Void visit(StmtTy.ClassDef node) { + boolean newStatement = beginSourceSection(node, b); + b.beginBlock(); + BytecodeLocal buildClassFunction = b.createLocal(); + + // compute __build_class__ (we need it in multiple places, so store it) + b.beginStoreLocal(buildClassFunction); + b.emitBuildClass(); + b.endStoreLocal(); + + // ClassName = __build_class__(, "ClassName", bases, keywords) + beginStoreLocal(node.name, b); + + int numDeco = len(node.decoratorList); + for (int i = 0; i < numDeco; i++) { + b.beginCallUnaryMethod(); + node.decoratorList[i].accept(this); + } + + b.beginCallVarargsMethod(); + + b.emitLoadLocal(buildClassFunction); + + // positional args + emitUnstar(() -> { + emitMakeFunction(node, node.name, null, null); + emitPythonConstant(toTruffleStringUncached(node.name), b); + }, node.bases); + + // keyword args + validateKeywords(node.keywords); + emitKeywords(node.keywords, buildClassFunction); + + b.endCallVarargsMethod(); + + for (int i = 0; i < numDeco; i++) { + b.endCallUnaryMethod(); + } + + endStoreLocal(node.name, b); + + b.endBlock(); + endSourceSection(b, newStatement); + + return null; + } + + private class DeleteVisitor implements BaseBytecodeDSLVisitor { + + @Override + public Void visit(ExprTy.Subscript node) { + boolean newStatement = beginSourceSection(node, b); + + b.beginDeleteItem(); + node.value.accept(StatementCompiler.this); + node.slice.accept(StatementCompiler.this); + b.endDeleteItem(); + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.Attribute node) { + boolean newStatement = beginSourceSection(node, b); + checkForbiddenName(node.attr, NameOperation.BeginWrite); + b.beginDeleteAttribute(toTruffleStringUncached(node.attr)); + node.value.accept(StatementCompiler.this); + b.endDeleteAttribute(); + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.Name node) { + boolean newStatement = beginSourceSection(node, b); + emitNameOperation(node.id, NameOperation.Delete, b); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.Tuple node) { + boolean newStatement = beginSourceSection(node, b); + b.beginBlock(); + visitSequence(node.elements); + b.endBlock(); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(ExprTy.List node) { + boolean newStatement = beginSourceSection(node, b); + b.beginBlock(); + visitSequence(node.elements); + b.endBlock(); + endSourceSection(b, newStatement); + return null; + } + } + + @Override + public Void visit(StmtTy.Delete node) { + new DeleteVisitor().visitSequence(node.targets); + return null; + } + + @Override + public Void visit(StmtTy.Expr node) { + boolean newStatement = beginSourceSection(node, b); + if (isInteractive) { + b.beginPrintExpr(); + node.value.accept(this); + b.endPrintExpr(); + } else { + node.value.accept(this); + } + endSourceSection(b, newStatement); + + return null; + } + + @Override + public Void visit(StmtTy.For node) { + // @formatter:off + // iter = GetIter(<>); value; + // while (ForIterate(iter, &value)) { + // store value + // <> + // continueLabel: + // } + // < + // breakLabel: + // @formatter:on + boolean newStatement = beginSourceSection(node, b); + b.beginBlock(); + + BytecodeLocal iter = b.createLocal(); + + b.beginStoreLocal(iter); + b.beginGetIter(); + node.iter.accept(this); + b.endGetIter(); + b.endStoreLocal(); + + BytecodeLabel oldBreakLabel = breakLabel; + BytecodeLabel oldContinueLabel = continueLabel; + + BytecodeLabel currentBreakLabel = b.createLabel(); + breakLabel = currentBreakLabel; + + b.beginWhile(); + BytecodeLocal value = b.createLocal(); + + // condition + b.beginBlock(); + b.emitTraceLineAtLoopHeader(currentLocation.startLine); + b.beginForIterate(value); + b.emitLoadLocal(iter); + b.endForIterate(); + b.endBlock(); + + // body + b.beginBlock(); + continueLabel = b.createLabel(); + node.target.accept(new StoreVisitor(() -> { + b.emitLoadLocal(value); + })); + + visitSequence(node.body); + b.emitLabel(continueLabel); + b.endBlock(); + + b.endWhile(); + + breakLabel = oldBreakLabel; + continueLabel = oldContinueLabel; + visitSequence(node.orElse); + b.emitLabel(currentBreakLabel); + + b.endBlock(); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(StmtTy.FunctionDef node) { + boolean newStatement = beginSourceSection(node, b); + b.beginBlock(); + + beginStoreLocal(node.name, b); + + int numDeco = len(node.decoratorList); + for (int i = 0; i < numDeco; i++) { + b.beginCallUnaryMethod(); + node.decoratorList[i].accept(this); + } + + List annotations = collectParamAnnotations(node.args, node.returns); + emitMakeFunction(node, node.name, node.args, annotations); + + for (int i = 0; i < numDeco; i++) { + b.endCallUnaryMethod(); + } + + endStoreLocal(node.name, b); + + b.endBlock(); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(StmtTy.AsyncFunctionDef node) { + boolean newStatement = beginSourceSection(node, b); + beginStoreLocal(node.name, b); + + int numDeco = len(node.decoratorList); + for (int i = 0; i < numDeco; i++) { + b.beginCallUnaryMethod(); + node.decoratorList[i].accept(this); + } + + List annotations = collectParamAnnotations(node.args, node.returns); + emitMakeFunction(node, node.name, node.args, annotations); + + for (int i = 0; i < numDeco; i++) { + b.endCallUnaryMethod(); + } + + endStoreLocal(node.name, b); + endSourceSection(b, newStatement); + return null; + } + + private void emitParamAnnotation(ParamAnnotation paramAnnotation) { + emitPythonConstant(paramAnnotation.name, b); + + if (futureFeatures.contains(FutureFeature.ANNOTATIONS)) { + emitPythonConstant(Unparser.unparse(paramAnnotation.annotation), b); + } else { + if (paramAnnotation.annotation instanceof ExprTy.Starred starred) { + // *args: *Ts (where Ts is a TypeVarTuple). + // Do [annotation_value] = [*Ts]. + b.beginBlock(); + BytecodeLocal local = b.createLocal(); + b.beginUnpackToLocals(new BytecodeLocal[]{local}); + starred.value.accept(this); + b.endUnpackToLocals(); + b.emitLoadLocal(local); + b.endBlock(); + } else { + paramAnnotation.annotation.accept(this); + } + } + } + + private void emitMakeFunction(SSTNode node, String name, ArgumentsTy args, List annotations) { + BytecodeDSLCompilerResult compilerResult = compileNode(node); + BytecodeDSLCodeUnit codeUnit = compilerResult.codeUnit(); + + TruffleString functionName = toTruffleStringUncached(name); + Scope targetScope = ctx.scopeEnvironment.lookupScope(node); + TruffleString qualifiedName = toTruffleStringUncached(ctx.getQualifiedName(targetScope)); + + // Register these in the Python constants list. + addConstant(qualifiedName); + addConstant(codeUnit); + + b.beginMakeFunction(functionName, qualifiedName, codeUnit); + + if (args == null || len(args.defaults) == 0) { + b.emitLoadConstant(PythonUtils.EMPTY_OBJECT_ARRAY); + } else { + b.beginCollectToObjectArray(); + for (int i = 0; i < args.defaults.length; i++) { + args.defaults[i].accept(this); + } + b.endCollectToObjectArray(); + } + + boolean hasKeywords = false; + if (args != null && len(args.kwDefaults) != 0) { + // We only emit keywords with default values. Check if any exist. + for (int i = 0; i < args.kwDefaults.length; i++) { + if (args.kwDefaults[i] != null) { + hasKeywords = true; + break; + } + } + } + + if (!hasKeywords) { + b.emitLoadConstant(PKeyword.EMPTY_KEYWORDS); + } else { + ArgTy[] kwOnlyArgs = args.kwOnlyArgs; + + List keys = new ArrayList<>(); + b.beginMakeKeywords(); + for (int i = 0; i < args.kwDefaults.length; i++) { + // Only emit keywords with default values. + if (args.kwDefaults[i] != null) { + keys.add(toTruffleStringUncached(mangle(kwOnlyArgs[i].arg))); + args.kwDefaults[i].accept(this); + } + } + b.endMakeKeywords(keys.toArray(new TruffleString[0])); + } + + if (codeUnit.freevars.length == 0) { + b.emitLoadNull(); + } else { + b.beginMakeCellArray(); + for (int i = 0; i < codeUnit.freevars.length; i++) { + String fv = codeUnit.freevars[i].toJavaStringUncached(); + BytecodeLocal local; + if (scopeType == CompilationScope.Class && "__class__".equals(fv) || scope.getUseOfName(fv).contains(Scope.DefUse.Cell)) { + local = cellLocals.get(fv); + } else { + local = freeLocals.get(fv); + } + b.emitLoadLocal(local); + } + b.endMakeCellArray(); + } + + // __annotations__ + if (annotations != null && annotations.size() > 0) { + b.beginMakeDict(annotations.size()); + for (ParamAnnotation annotation : annotations) { + emitParamAnnotation(annotation); + } + b.endMakeDict(); + } else { + b.emitLoadNull(); + } + + b.endMakeFunction(); + } + + private BytecodeDSLCompilerResult compileNode(SSTNode node) { + return (new RootNodeCompiler(ctx, node, futureFeatures)).compile(); + } + + @Override + public Void visit(StmtTy.Global node) { + return null; + } + + private void visitStatements(StmtTy[] stmts) { + b.beginBlock(); + if (stmts != null) { + for (StmtTy stmt : stmts) { + stmt.accept(this); + } + } + b.endBlock(); + } + + @Override + public Void visit(StmtTy.If node) { + boolean newStatement = beginSourceSection(node, b); + if (node.orElse == null || node.orElse.length == 0) { + b.beginIfThen(); + visitCondition(node.test); + visitStatements(node.body); + b.endIfThen(); + } else { + b.beginIfThenElse(); + visitCondition(node.test); + visitStatements(node.body); + visitStatements(node.orElse); + b.endIfThenElse(); + } + + endSourceSection(b, newStatement); + return null; + } + + private boolean producesBoolean(ExprTy node) { + // NB: Binary and/or operations evaluate to their operands, which are not necessarily + // booleans. + return node instanceof ExprTy.UnaryOp unOp && unOp.op == UnaryOpTy.Not || + node instanceof ExprTy.Constant c && c.value.kind == Kind.BOOLEAN; + } + + private void visitCondition(ExprTy node) { + boolean mayNeedCoercion = !producesBoolean(node); + if (mayNeedCoercion) { + b.beginYes(); + } + + node.accept(this); + + if (mayNeedCoercion) { + b.endYes(); + } + } + + @Override + public Void visit(StmtTy.Import node) { + boolean newStatement = beginSourceSection(node, b); + b.beginBlock(); + + for (AliasTy name : node.names) { + addConstant(PythonUtils.EMPTY_TRUFFLESTRING_ARRAY); + if (name.asName == null) { + // import a.b.c + // --> a = (Import "a.b.c" [] 0) + // import a + // --> a = (Import "a" [] 0) + String resName = name.name.contains(".") + ? name.name.substring(0, name.name.indexOf('.')) + : name.name; + + beginStoreLocal(resName, b); + b.emitImport(toTruffleStringUncached(name.name), PythonUtils.EMPTY_TRUFFLESTRING_ARRAY, 0); + endStoreLocal(resName, b); + } else { + // import a.b.c as x + // --> x = (ImportFrom (ImportFrom (Import "a.b.c" [] 0) "b") "c") + // import a as x + // --> x = (Import "a" [] 0) + String[] parts = name.name.split("\\."); + + beginStoreLocal(name.asName, b); + + for (int i = parts.length - 1; i >= 0; i--) { + if (i != 0) { + b.beginImportFrom(toTruffleStringUncached(parts[i])); + } else { + b.emitImport(toTruffleStringUncached(name.name), PythonUtils.EMPTY_TRUFFLESTRING_ARRAY, 0); + } + } + + for (int i = 1; i < parts.length; i++) { + b.endImportFrom(); + } + + endStoreLocal(name.asName, b); + } + } + + b.endBlock(); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(StmtTy.ImportFrom node) { + boolean newStatement = beginSourceSection(node, b); + if (node.getSourceRange().startLine > ctx.futureLineNumber && "__future__".equals(node.module)) { + ctx.errorCallback.onError(ErrorType.Syntax, node.getSourceRange(), "from __future__ imports must occur at the beginning of the file"); + } + + TruffleString tsModuleName = toTruffleStringUncached(node.module == null ? "" : node.module); + + if (node.names[0].name.equals("*")) { + b.emitImportStar(tsModuleName, node.level); + } else { + b.beginBlock(); + + BytecodeLocal module = b.createLocal(); + + TruffleString[] fromList = new TruffleString[node.names.length]; + for (int i = 0; i < fromList.length; i++) { + fromList[i] = toTruffleStringUncached(node.names[i].name); + } + + b.beginStoreLocal(module); + b.emitImport(tsModuleName, fromList, node.level); + b.endStoreLocal(); + + TruffleString[] importedNames = new TruffleString[node.names.length]; + for (int i = 0; i < node.names.length; i++) { + AliasTy alias = node.names[i]; + String asName = alias.asName == null ? alias.name : alias.asName; + beginStoreLocal(asName, b); + + TruffleString name = toTruffleStringUncached(alias.name); + importedNames[i] = name; + b.beginImportFrom(name); + b.emitLoadLocal(module); + b.endImportFrom(); + + endStoreLocal(asName, b); + } + addConstant(importedNames); + + b.endBlock(); + } + + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(StmtTy.Match node) { + boolean newStatement = beginSourceSection(node, b); + b.beginBlock(); + // Compute and store the subject in a local. + BytecodeLocal subject = b.createLocal(); + b.beginStoreLocal(subject); + node.subject.accept(this); + b.endStoreLocal(); + + visitMatchCaseRecursively(node.cases, 0, new PatternContext(subject)); + + b.endBlock(); + endSourceSection(b, newStatement); + return null; + } + + private final class PatternContext { + private final Map bindVariables = new HashMap<>(); + private final BytecodeLocal subject; + private boolean allowIrrefutable = false; + + PatternContext(BytecodeLocal subject) { + this.subject = subject; + } + + public void copySubjectToTemporary(String name) { + BytecodeLocal temporary = allocateBindVariable(name); + b.beginStoreLocal(temporary); + b.emitLoadLocal(subject); + b.endStoreLocal(); + } + + private BytecodeLocal allocateBindVariable(String name) { + checkForbiddenName(name, NameOperation.BeginWrite); + if (bindVariables.containsKey(name)) { + duplicateStoreError(name); + } + BytecodeLocal result = b.createLocal(); + bindVariables.put(name, result); + return result; + } + + private void duplicateStoreError(String name) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "multiple assignments to name '%s' in pattern", name); + } + + } + + private void visitMatchCaseRecursively(MatchCaseTy[] cases, int index, PatternContext pc) { + /** + * Cases are chained as a sequence of if-then-else clauses, as in: + * + * @formatter:off + * IfThenElse( + * , + * , + * IfThenElse( + * , + * , + * ... + * ) + * ) + * @formatter:on + */ + MatchCaseTy c = cases[index]; + boolean newStatement = beginSourceSection(c, b); + + if (index != cases.length - 1) { + b.beginIfThenElse(); + + // A case that isn't last can be irrefutable only if it is guarded. + pc.allowIrrefutable = c.guard != null; + + emitPatternCondition(c, pc); + visitStatements(c.body); + pc.bindVariables.clear(); + visitMatchCaseRecursively(cases, index + 1, pc); + b.endIfThenElse(); + } else { + /** + * For the last pattern: if it's an unguarded wildcard _, just emit the body. + * Otherwise, emit an IfThen (no else). + */ + if (wildcardCheck(c.pattern) && c.guard == null) { + visitStatements(c.body); + } else { + b.beginIfThen(); + + // The last case can be irrefutable. + pc.allowIrrefutable = true; + + emitPatternCondition(c, pc); + visitStatements(c.body); + b.endIfThen(); + } + } + + endSourceSection(b, newStatement); + } + + private void emitPatternCondition(MatchCaseTy currentCase, PatternContext pc) { + PatternTy pattern = currentCase.pattern; + ExprTy guard = currentCase.guard; + + /** + * We evaluate conditions using a sequence of boolean computations chained with + * short-circuiting ANDs. If a condition fails at any point, we abort and continue with + * the next pattern. + * + * Patterns can bind variables, but a variable is only bound if the full pattern + * matches. We accumulate the bound values into temporary variables and copy them all + * over only if the pattern matches. For example: + * + * @formatter:off + * IfThenElse( + * And( + * , + * Block( + * + * ... + * , + * true // continue unconditionally + * ), + * + * ), + * , + * ... + * ) + * @formatter:on + */ + b.beginPrimitiveBoolAnd(); + + visitPattern(pattern, pc); + + if (!pc.bindVariables.isEmpty()) { + b.beginBlock(); + + for (Map.Entry entry : pc.bindVariables.entrySet()) { + beginStoreLocal(entry.getKey(), b); + b.emitLoadLocal(entry.getValue()); + endStoreLocal(entry.getKey(), b); + } + + b.emitLoadConstant(true); + b.endBlock(); + } + if (guard != null) { + visitCondition(guard); + } + b.endPrimitiveBoolAnd(); + } + + /** + * Generates code to test a {@code pattern} against the value stored in {@code subject}. + * + * Invariants: + *

        + *
      • The code for each pattern produces a boolean value. + *
      • When the pattern has a variable binding, the code will use the {@code pc} to allocate + * a new temporary variable to store the value of the binding. If the pattern match + * succeeds, only then will we copy the temporaries into Python-level variables. + *
      • The {@code pc.subject} variable always contains the value to match against a pattern. + * When performing structural recursion on a value, the original value will be overwritten + * unless saved in a new local. + *
      + */ + private void visitPattern(PatternTy pattern, PatternContext pc) { + boolean newStatement = beginSourceSection(pattern, b); + if (pattern instanceof PatternTy.MatchAs matchAs) { + doVisitPattern(matchAs, pc); + } else if (pattern instanceof PatternTy.MatchClass matchClass) { + doVisitPattern(matchClass, pc); + } else if (pattern instanceof PatternTy.MatchMapping matchMapping) { + doVisitPattern(matchMapping, pc); + } else if (pattern instanceof PatternTy.MatchOr matchOr) { + doVisitPattern(matchOr, pc); + } else if (pattern instanceof PatternTy.MatchSequence matchSequence) { + doVisitPattern(matchSequence, pc); + } else if (pattern instanceof PatternTy.MatchSingleton matchSingleton) { + doVisitPattern(matchSingleton, pc); + } else if (pattern instanceof PatternTy.MatchStar matchStar) { + doVisitPattern(matchStar, pc); + } else if (pattern instanceof PatternTy.MatchValue matchValue) { + doVisitPattern(matchValue, pc); + } else { + throw CompilerDirectives.shouldNotReachHere(); + } + endSourceSection(b, newStatement); + } + + // In a subpattern, irrefutable patterns are OK. + private void visitSubpattern(PatternTy pattern, PatternContext pc) { + boolean allowIrrefutable = pc.allowIrrefutable; + pc.allowIrrefutable = true; + visitPattern(pattern, pc); + pc.allowIrrefutable = allowIrrefutable; + } + + private void doVisitPattern(PatternTy.MatchAs node, PatternContext pc) { + b.beginBlock(); + if (node.name != null) { + pc.copySubjectToTemporary(node.name); + } + + if (node.pattern == null) { + // If there's no pattern (e.g., _), it trivially matches. Ensure this is permitted. + if (!pc.allowIrrefutable) { + if (node.name != null) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "name capture '%s' makes remaining patterns unreachable", node.name); + } + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "wildcard makes remaining patterns unreachable"); + } + b.emitLoadConstant(true); + } else { + assert node.name != null : "name should only be null for the empty wildcard pattern '_'"; + visitPattern(node.pattern, pc); + } + + b.endBlock(); + } + + private void emitPatternNotImplemented(String kind) { + b.beginBlock(); + emitNotImplemented(kind + " pattern matching", b); + // we need a value producing operation + b.emitLoadConstant(false); + b.endBlock(); + } + + /** + * Saves subject of the pattern context into BytecodeLocal variable, to be restored + * eventually. + * + * @param pc Pattern context, which subject needs to be saved. + * @return Subject saved in local variable. + */ + private BytecodeLocal patternContextSubjectSave(PatternContext pc) { + BytecodeLocal pcSave = b.createLocal(); + b.beginStoreLocal(pcSave); + b.emitLoadLocal(pc.subject); + b.endStoreLocal(); + return pcSave; + } + + /** + * Loads pattern context subject back into pattern context. + * + * @param pcSave Variable to restore pattern context subject from. + * @param pc Pattern context into which the subject should be restored. + */ + private void patternContextSubjectLoad(BytecodeLocal pcSave, PatternContext pc) { + b.beginStoreLocal(pc.subject); + b.emitLoadLocal(pcSave); + b.endStoreLocal(); + } + + /** + * Check if attribute and keyword attribute lengths match, or if there isn't too much + * patterns or attributes. Throws error on fail. + * + * @param patLen Patterns count + * @param attrsLen Attributes count + * @param kwdPatLen Keyword attributes count + * @param node MatchClass node for errors + */ + private void classMatchLengthChecks(int patLen, int attrsLen, int kwdPatLen, PatternTy.MatchClass node) { + if (attrsLen != kwdPatLen) { + ctx.errorCallback.onError(ErrorType.Syntax, node.getSourceRange(), "kwd_attrs (%d) / kwd_patterns (%d) length mismatch in class pattern", attrsLen, kwdPatLen); + } + if (Integer.MAX_VALUE < patLen + attrsLen - 1) { + String id = node.cls instanceof ExprTy.Name ? ((ExprTy.Name) node.cls).id : node.cls.toString(); + ctx.errorCallback.onError(ErrorType.Syntax, node.getSourceRange(), "too many sub-patterns in class pattern %s", id); + } + + } + + /** + * Visits sub-patterns for class pattern matching. Regular, positional patterns are handled + * first, then the keyword patterns (e.g. the "class.attribute = [keyword] pattern"). + * Generates boolean value based on results of the subpatterns; values are evaluated using + * the AND operator. + * + * @param patterns Patterns to check as subpatterns. + * @param kwdPatterns Keyword patterns to check as subpatterns. + * @param attrsValueUnpacked Values to use as `pc.subject` in sub-pattern check. + * @param pc Pattern context (subject is saved then restored). + * @param patLen Number of patterns. + * @param attrsLen Number of attributes (also keyword patterns). + */ + private void classMatchVisitSubpatterns(PatternTy[] patterns, PatternTy[] kwdPatterns, BytecodeLocal attrsValueUnpacked, PatternContext pc, int patLen, int attrsLen) { + BytecodeLocal pcSave = patternContextSubjectSave(pc); + + if (patLen + attrsLen == 0) { + b.emitLoadConstant(true); + } else { + BytecodeLocal temp = b.createLocal(); + b.beginStoreLocal(temp); + b.beginPrimitiveBoolAnd(); + for (int i = 0; i < patLen; i++) { + b.beginBlock(); + b.beginStoreLocal(pc.subject); + b.beginArrayIndex(i); + b.emitLoadLocal(attrsValueUnpacked); + b.endArrayIndex(); + b.endStoreLocal(); + + visitSubpattern(patterns[i], pc); + b.endBlock(); + } + + for (int i = 0, j = patLen; i < attrsLen; i++, j++) { + b.beginBlock(); + b.beginStoreLocal(pc.subject); + b.beginArrayIndex(j); + b.emitLoadLocal(attrsValueUnpacked); + b.endArrayIndex(); + b.endStoreLocal(); + + visitSubpattern(kwdPatterns[i], pc); + b.endBlock(); + } + b.endPrimitiveBoolAnd(); + b.endStoreLocal(); + + patternContextSubjectLoad(pcSave, pc); + + b.emitLoadLocal(temp); + } + } + + private void doVisitPattern(PatternTy.MatchClass node, PatternContext pc) { + /** + * Class pattern matching consists of subject and pattern. Pattern is split into: + *
        + *
      • patterns: These are positional and match the {@code __match_args__} arguments of the class, and are + * evaluated as sub-patterns with respective positional class attributes as subjects. + *
      • keyword attributes (kwdAttrs): These are non-positional, named class attributes that need to match + * the accompanying keyword patterns. + *
      • keyword patterns (kwdPatterns): Patterns that accompany keyword attributes, these are evaluated as + * sub-patterns with provided class attributes as subjects. Note that the number of keyword attributes + * and keyword patterns do need to match. + *
      + * + * Example: + * @formatter:off + * x = + * match x: + * case (x, 42 as y, a = ("test1" | "test2") as z): + * ... + * @formatter:on + * Here, {@code x} and {@code 42 as y} are "patterns" (positional), {@code a} is "keyword attribute" and + * {@code ... as z} is its accompanying "keyword pattern". + */ + + b.beginBlock(); + + PatternTy[] patterns = node.patterns; + String[] kwdAttrs = node.kwdAttrs; + PatternTy[] kwdPatterns = node.kwdPatterns; + int patLen = lengthOrZero(patterns); + int attrsLen = lengthOrZero(kwdAttrs); + int kwdPatLen = lengthOrZero(kwdPatterns); + + classMatchLengthChecks(patLen, attrsLen, kwdPatLen, node); + if (attrsLen > 0) { + validateKwdAttrs(kwdAttrs, kwdPatterns); + } + + //@formatter:off + // attributes needs to be converted into truffle strings + TruffleString[] tsAttrs = new TruffleString[attrsLen]; + for (int i = 0; i < attrsLen; i++) { + tsAttrs[i] = toTruffleStringUncached(kwdAttrs[i]); + } + + b.beginPrimitiveBoolAnd(); + BytecodeLocal attrsValue = b.createLocal(); + // match class that's in the subject + b.beginMatchClass(attrsValue); + b.emitLoadLocal(pc.subject); + node.cls.accept(this); // get class type + b.emitLoadConstant(patLen); + b.emitLoadConstant(tsAttrs); + b.endMatchClass(); + + b.beginBlock(); + // attributes from match class needs to be unpacked first + BytecodeLocal attrsValueUnpacked = b.createLocal(); + b.beginStoreLocal(attrsValueUnpacked); + b.beginUnpackSequence(patLen + attrsLen); + b.emitLoadLocal(attrsValue); + b.endUnpackSequence(); + b.endStoreLocal(); + + classMatchVisitSubpatterns(patterns, kwdPatterns, attrsValueUnpacked, pc, patLen, attrsLen); + b.endBlock(); + b.endPrimitiveBoolAnd(); + + b.endBlock(); + //@formatter:on + } + + /** + * Checks if keyword argument names aren't the same or if their name isn't forbidden. Raises + * error at fail. + * + * @param attrs Attributes to check. + * @param patterns Patterns for error source range. + */ + private void validateKwdAttrs(String[] attrs, PatternTy[] patterns) { + // Any errors will point to the pattern rather than the arg name as the + // parser is only supplying identifiers rather than Name or keyword nodes + int attrsLen = lengthOrZero(attrs); + for (int i = 0; i < attrsLen; i++) { + String attr = attrs[i]; + checkForbiddenName(attr, NameOperation.BeginWrite, patterns[i].getSourceRange()); + for (int j = i + 1; j < attrsLen; j++) { + String other = attrs[j]; + if (attr.equals(other)) { + ctx.errorCallback.onError(ErrorType.Syntax, patterns[j].getSourceRange(), "attribute name repeated in class pattern: `%s`", attr); + } + } + } + } + + private static int lengthOrZero(Object[] p) { + return p == null ? 0 : p.length; + } + + /** + * Checks if keys in pattern are, if present, longer than keys in subject. If yes, pattern + * should fail, otherwise, we should continue with evaluation. + * + * Generates result of the comparison (boolean). + * + * @param keyLen Number of keys in pattern. + * @param pc Pattern context. + */ + private void checkPatternKeysLength(int keyLen, PatternContext pc) { + b.beginGe(); + b.beginGetLen(); + b.emitLoadLocal(pc.subject); + b.endGetLen(); + b.emitLoadConstant(keyLen); + b.endGe(); + } + + /** + * Will process pattern keys: Attributes evaluation and constant folding. Checks for + * duplicate keys and that only literals and attributes lookups are being matched. + * + * Generates array. + * + * @param keys Pattern keys. + * @param keyLen Length of pattern keys. + * @param node Pattern matching node, for source range in errors. + */ + private void processPatternKeys(ExprTy[] keys, int keyLen, PatternTy.MatchMapping node) { + b.beginCollectToObjectArray(); // keys (from pattern) + List seen = new ArrayList<>(); + for (int i = 0; i < keyLen; i++) { + ExprTy key = keys[i]; + if (key instanceof ExprTy.Attribute) { + key.accept(this); + } else { + ConstantValue constantValue = null; + if (key instanceof ExprTy.UnaryOp || key instanceof ExprTy.BinOp) { + constantValue = foldConstantOp(key); + } else if (key instanceof ExprTy.Constant) { + constantValue = ((ExprTy.Constant) key).value; + } else { + ctx.errorCallback.onError(ErrorType.Syntax, node.getSourceRange(), "mapping pattern keys may only match literals and attribute lookups"); + } + assert constantValue != null; + Object pythonValue = PythonUtils.pythonObjectFromConstantValue(constantValue); + for (Object o : seen) { + // need python like equal - e.g. 1 equals True + if (PyObjectRichCompareBool.executeEqUncached(o, pythonValue)) { + ctx.errorCallback.onError(ErrorType.Syntax, node.getSourceRange(), "mapping pattern checks duplicate key (%s)", pythonValue); + } + } + seen.add(pythonValue); + createConstant(constantValue); + } + } + b.endCollectToObjectArray(); + } + + /** + * Visit all sub-patterns for mapping in pattern (not subject). + * + * Generates boolean value (AND of result of all sub-patterns). + * + * @param patterns Sub-patterns to iterate through. + * @param values Patterns from subject to set as subject for evaluated sub-patterns. + * @param pc Pattern context. + */ + private void mappingVisitSubpatterns(PatternTy[] patterns, BytecodeLocal values, PatternContext pc) { + int patLen = patterns.length; + + b.beginBlock(); + // unpack values from pc.subject + BytecodeLocal valuesUnpacked = b.createLocal(); + b.beginStoreLocal(valuesUnpacked); + b.beginUnpackSequence(patLen); + b.emitLoadLocal(values); + b.endUnpackSequence(); + b.endStoreLocal(); + + // backup pc.subject, it will get replaced for sub-patterns + BytecodeLocal pcSave = patternContextSubjectSave(pc); + + BytecodeLocal temp = b.createLocal(); + b.beginStoreLocal(temp); + b.beginPrimitiveBoolAnd(); + boolean hadNonWildcardPattern = false; + for (int i = 0; i < patLen; i++) { + if (wildcardCheck(patterns[i])) { + continue; + } + hadNonWildcardPattern = true; + b.beginBlock(); + b.beginStoreLocal(pc.subject); + b.beginArrayIndex(i); + b.emitLoadLocal(valuesUnpacked); + b.endArrayIndex(); + b.endStoreLocal(); + + visitSubpattern(patterns[i], pc); + b.endBlock(); + } + if (!hadNonWildcardPattern) { + b.emitLoadConstant(true); + } + b.endPrimitiveBoolAnd(); + b.endStoreLocal(); + + patternContextSubjectLoad(pcSave, pc); + + b.emitLoadLocal(temp); + b.endBlock(); + } + + private void doVisitPattern(PatternTy.MatchMapping node, PatternContext pc) { + /** + * Mapping pattern match will take the keys and check, whether the keys in the pattern + * are present in the subject. This is good enough, since the pattern needs only to be a + * subset of the subject. Keys aren't evaluated as subpatterns. + * + * After the key check, the values of the pattern are patterns as well and are evaluated + * as sub-patterns with values in the subject used as separate respective subjects. + */ + ExprTy[] keys = node.keys; + PatternTy[] patterns = node.patterns; + + int keyLen = lengthOrZero(keys); + int patLen = lengthOrZero(patterns); + + if (keyLen != patLen) { + ctx.errorCallback.onError(ErrorType.Syntax, node.getSourceRange(), "keys (%d) / patterns (%d) length mismatch in mapping pattern", keyLen, patLen); + } + // @formatter:off + + b.beginPrimitiveBoolAnd(); // AND for type, trivial and key length matching + // check that type matches + b.beginCheckTypeFlags(TypeFlags.MAPPING); + b.emitLoadLocal(pc.subject); + b.endCheckTypeFlags(); + + String starTarget = node.rest; + if (keyLen == 0 && starTarget == null) { + b.emitLoadConstant(true); + b.endPrimitiveBoolAnd(); + return; + } + if (Integer.MAX_VALUE < keyLen - 1) { + ctx.errorCallback.onError(ErrorType.Syntax, node.getSourceRange(), "too many sub-patterns in mapping pattern"); + } + + // If the pattern has any keys in it, perform a length check: + if (keyLen > 0) { + checkPatternKeysLength(keyLen, pc); + } + + b.beginBlock(); + BytecodeLocal subjectPatterns = b.createLocal(); + BytecodeLocal temp = b.createLocal(); + BytecodeLocal keysChecked = b.createLocal(); + + b.beginStoreLocal(temp); + b.beginPrimitiveBoolAnd(); // AND process keys and sub-patterns + b.beginBlock(); + b.beginStoreLocal(keysChecked); + processPatternKeys(keys, keyLen, node); + b.endStoreLocal(); + + // save match result together with values + b.beginMatchKeys(subjectPatterns); + b.emitLoadLocal(pc.subject); + b.emitLoadLocal(keysChecked); + b.endMatchKeys(); + b.endBlock(); + + if (patLen > 0) { + mappingVisitSubpatterns(patterns, subjectPatterns, pc); + } + b.endPrimitiveBoolAnd(); // AND process keys and sub-patterns + b.endStoreLocal(); // temp + + if (starTarget != null) { + BytecodeLocal starVariable = pc.allocateBindVariable(starTarget); + b.beginStoreLocal(starVariable); + b.beginCopyDictWithoutKeys(); + b.emitLoadLocal(pc.subject); + b.emitLoadLocal(keysChecked); + b.endCopyDictWithoutKeys(); + b.endStoreLocal(); + } + + b.emitLoadLocal(temp); + b.endBlock(); + b.endPrimitiveBoolAnd(); // AND for key length matching + + // @formatter:on + } + + private void checkAlternativePatternDifferentNames(Set control, Map bindVariables) { + if (!control.equals(bindVariables.keySet())) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "alternative patterns bind different names"); + } + } + + private void fromPatternContextToLocal(PatternContext pc, BytecodeLocal local_temp) { + b.beginIfThen(); + + // condition + b.emitLoadLocal(local_temp); + + // if-then + b.beginBlock(); + + if (!pc.bindVariables.isEmpty()) { + for (Map.Entry entry : pc.bindVariables.entrySet()) { + beginStoreLocal(entry.getKey(), b); + b.emitLoadLocal(entry.getValue()); + endStoreLocal(entry.getKey(), b); + } + } + + b.endBlock(); + b.endIfThen(); + } + + private void visitMatchOrRecursively(PatternTy[] patterns, int index, PatternContext pc, Set control, boolean allowIrrefutable) { + /** + * Case patterns joined by OR operator are chained as a sequence of binary OR operators, as in: + * + * @formatter:off + * case pattern1 | (pattern2 | (pattern3 | ... (patternN-1 | patternN))): + * ... + * @formatter:on + */ + b.beginBoolOr(); + b.beginBlock(); + + pc = new PatternContext(pc.subject); + + // store the (boolean) result of the sub-pattern + BytecodeLocal local_temp = b.createLocal(); + b.beginStoreLocal(local_temp); + visitPattern(patterns[index], pc); + b.endStoreLocal(); + + if (index == 0) { + control = new HashSet<>(pc.bindVariables.keySet()); + } + checkAlternativePatternDifferentNames(control, pc.bindVariables); + fromPatternContextToLocal(pc, local_temp); + + b.emitLoadLocal(local_temp); + b.endBlock(); + + if (index + 2 < patterns.length) { + visitMatchOrRecursively(patterns, index + 1, pc, control, allowIrrefutable); + b.endBoolOr(); + } else { + // Only last sub-pattern can be irrefutable -- if it was allowed in the first place + pc = new PatternContext(pc.subject); + pc.allowIrrefutable = allowIrrefutable; + + b.beginBlock(); + + // store the (boolean) result of the sub-pattern + local_temp = b.createLocal(); + b.beginStoreLocal(local_temp); + visitPattern(patterns[index + 1], pc); + b.endStoreLocal(); + + checkAlternativePatternDifferentNames(control, pc.bindVariables); + fromPatternContextToLocal(pc, local_temp); + + b.emitLoadLocal(local_temp); + b.endBlock(); + b.endBoolOr(); + } + } + + private void doVisitPattern(PatternTy.MatchOr node, PatternContext pc) { + boolean saveIrrefutable = pc.allowIrrefutable; + // sub-patterns are not irrefutable by default, only last one is + // this needs to be restored before last sub-pattern is visited + pc.allowIrrefutable = false; + visitMatchOrRecursively(node.patterns, 0, pc, null, saveIrrefutable); + } + + private void patternHelperSequenceUnpack(PatternTy[] patterns, PatternContext pc) { + int n = len(patterns); + + b.beginBlock(); + // We need to remember the unpacked array, since subject will be overwritten in + // recursive calls. + BytecodeLocal unpacked = b.createLocal(); + b.beginStoreLocal(unpacked); + patternUnpackHelper(patterns, pc); + b.endStoreLocal(); + + b.beginPrimitiveBoolAnd(); + for (int i = 0; i < n; i++) { + b.beginBlock(); + b.beginStoreLocal(pc.subject); + b.beginArrayIndex(i); + b.emitLoadLocal(unpacked); + b.endArrayIndex(); + b.endStoreLocal(); + + visitSubpattern(patterns[i], pc); + b.endBlock(); + } + + b.endPrimitiveBoolAnd(); + b.endBlock(); + } + + private void patternUnpackHelper(PatternTy[] patterns, PatternContext pc) { + int n = len(patterns); + + boolean seenStar = false; + for (int i = 0; i < n; i++) { + PatternTy pattern = patterns[i]; + if (pattern instanceof PatternTy.MatchStar) { + if (seenStar) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "multiple starred expressions in sequence pattern"); + } + seenStar = true; + int countAfter = n - i - 1; + if (countAfter != (byte) countAfter) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "too many expressions in star-unpacking sequence pattern"); + } + // If there's a star pattern, emit UnpackEx. + b.beginUnpackEx(i, countAfter); + b.emitLoadLocal(pc.subject); + b.endUnpackEx(); + // Continue in the loop to ensure there are no additional starred patterns. + } + } + // If there were no star patterns, emit UnpackSequence. + if (!seenStar) { + b.beginUnpackSequence(n); + b.emitLoadLocal(pc.subject); + b.endUnpackSequence(); + } + } + + /** + * Like patternHelperSequenceUnpack, but uses subscripting, which is (likely) more efficient + * for patterns with a starred wildcard like [first, *_], [first, *_, last], [*_, last], + * etc. + */ + private void patternHelperSequenceSubscr(PatternTy[] patterns, int star, PatternContext pc) { + int n = len(patterns); + + b.beginBlock(); + // We need to remember the sequence, since subject will be overwritten in recursive + // calls. + BytecodeLocal sequence = b.createLocal(); + b.beginStoreLocal(sequence); + b.emitLoadLocal(pc.subject); + b.endStoreLocal(); + + for (int i = 0; i < n; i++) { + PatternTy pattern = patterns[i]; + if (wildcardCheck(pattern)) { + // nothing to check + continue; + } else if (i == star) { + // nothing to check + assert wildcardStarCheck(pattern); + continue; + } + + b.beginStoreLocal(pc.subject); + b.beginBinarySubscript(); + b.emitLoadLocal(sequence); + if (i < star) { + b.emitLoadConstant(i); + } else { + // The subject may not support negative indexing! Compute a + // nonnegative index: + b.beginPyNumberSubtract(); + + b.beginGetLen(); + b.emitLoadLocal(sequence); + b.endGetLen(); + + b.emitLoadConstant(n - i); + + b.endPyNumberSubtract(); + } + b.endBinarySubscript(); + b.endStoreLocal(); + + visitSubpattern(pattern, pc); + } + b.endBlock(); + } + + private void doVisitPattern(PatternTy.MatchSequence node, PatternContext pc) { + int size = len(node.patterns); + int star = -1; + boolean onlyWildcard = true; + boolean starWildcard = false; + + // Find a starred name, if it exists. There may be at most one: + for (int i = 0; i < size; i++) { + PatternTy pattern = node.patterns[i]; + if (pattern instanceof PatternTy.MatchStar) { + if (star >= 0) { + ctx.errorCallback.onError(ErrorType.Syntax, node.getSourceRange(), "multiple starred names in sequence pattern"); + } + starWildcard = wildcardStarCheck(pattern); + onlyWildcard &= starWildcard; + star = i; + continue; + } + onlyWildcard &= wildcardCheck(pattern); + } + + b.beginBlock(); + BytecodeLocal resultOfAnd = b.createLocal(); + + // oldSubject <- pc.subject + // store pc.subject for eventual return from sub-pattern + BytecodeLocal oldSubject = b.createLocal(); + b.beginStoreLocal(oldSubject); + b.emitLoadLocal(pc.subject); + b.endStoreLocal(); + + b.beginStoreLocal(resultOfAnd); + b.beginPrimitiveBoolAnd(); + + b.beginCheckTypeFlags(TypeFlags.SEQUENCE); + b.emitLoadLocal(pc.subject); + b.endCheckTypeFlags(); + + if (star < 0) { + // No star: len(subject) == size + b.beginEq(); + b.beginGetLen(); + b.emitLoadLocal(pc.subject); + b.endGetLen(); + b.emitLoadConstant(size); + b.endEq(); + } else if (size > 1) { + // Star: len(subject) >= size - 1 + b.beginGe(); + b.beginGetLen(); + b.emitLoadLocal(pc.subject); + b.endGetLen(); + b.emitLoadConstant(size - 1); + b.endGe(); + } + + if (onlyWildcard) { + /** + * For patterns like: [] / [_] / [_, _] / [*_] / [_, *_] / [_, _, *_] / etc., there + * is nothing more to check. + */ + } else if (starWildcard) { + /** + * For sequences with a *_ pattern, it is (likely) more efficient to extract the + * bound elements with subscripting rather than iterating the entire collection. + */ + patternHelperSequenceSubscr(node.patterns, star, pc); + } else { + /** + * Otherwise, unpack the sequence element-by-element. If there's a named * pattern, + * collect the rest into it. + */ + patternHelperSequenceUnpack(node.patterns, pc); + } + + b.endPrimitiveBoolAnd(); + b.endStoreLocal(); + + // pc.subject <- oldSubject + // load old subject when returning from sub-pattern + b.beginStoreLocal(pc.subject); + b.emitLoadLocal(oldSubject); + b.endStoreLocal(); + + b.emitLoadLocal(resultOfAnd); + b.endBlock(); + + } + + private void doVisitPattern(PatternTy.MatchSingleton node, PatternContext pc) { + b.beginIs(); + b.emitLoadLocal(pc.subject); + + switch (node.value.kind) { + case BOOLEAN: + b.emitLoadConstant(node.value.getBoolean()); + break; + case NONE: + b.emitLoadConstant(PNone.NONE); + break; + default: + throw new IllegalStateException("wrong MatchSingleton value kind " + node.value.kind); + } + b.endIs(); + } + + private void doVisitPattern(PatternTy.MatchStar node, PatternContext pc) { + if (node.name != null) { + b.beginBlock(); + pc.copySubjectToTemporary(node.name); + b.emitLoadConstant(true); + b.endBlock(); + } + /** + * If there's no name, no need to emit anything. A MatchStar can only appear as a + * subpattern of a mapping/sequence pattern, at which point in code generation we will + * be in the middle of a short-circuiting AND (that already has at least one operand) + */ + } + + private void doVisitPattern(PatternTy.MatchValue node, PatternContext pc) { + b.beginEq(); + b.emitLoadLocal(pc.subject); + + if (node.value instanceof ExprTy.UnaryOp || node.value instanceof ExprTy.BinOp) { + createConstant(foldConstantOp(node.value)); + } else if (node.value instanceof ExprTy.Constant || node.value instanceof ExprTy.Attribute) { + node.value.accept(this); + } else { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "patterns may only match literals and attribute lookups"); + } + b.endEq(); + } + + private static boolean wildcardCheck(PatternTy pattern) { + return pattern instanceof PatternTy.MatchAs && ((PatternTy.MatchAs) pattern).name == null; + } + + private static boolean wildcardStarCheck(PatternTy pattern) { + return pattern instanceof PatternTy.MatchStar && ((PatternTy.MatchStar) pattern).name == null; + } + + /** + * handles only particular cases when a constant comes either as a unary or binary op + */ + private ConstantValue foldConstantOp(ExprTy value) { + if (value instanceof ExprTy.UnaryOp unaryOp) { + return foldUnaryOpConstant(unaryOp); + } else if (value instanceof ExprTy.BinOp binOp) { + return foldBinOpComplexConstant(binOp); + } + throw new IllegalStateException("should not reach here"); + } + + /** + * handles only unary sub and a numeric constant + */ + private ConstantValue foldUnaryOpConstant(ExprTy.UnaryOp unaryOp) { + assert unaryOp.op == UnaryOpTy.USub; + assert unaryOp.operand instanceof ExprTy.Constant : unaryOp.operand; + ExprTy.Constant c = (ExprTy.Constant) unaryOp.operand; + ConstantValue ret = c.value.negate(); + assert ret != null; + return ret; + } + + /** + * handles only complex which comes as a BinOp + */ + private ConstantValue foldBinOpComplexConstant(ExprTy.BinOp binOp) { + assert (binOp.left instanceof ExprTy.UnaryOp || binOp.left instanceof ExprTy.Constant) && binOp.right instanceof ExprTy.Constant : binOp.left + " " + binOp.right; + assert binOp.op == OperatorTy.Sub || binOp.op == OperatorTy.Add; + ConstantValue left; + if (binOp.left instanceof ExprTy.UnaryOp) { + left = foldUnaryOpConstant((ExprTy.UnaryOp) binOp.left); + } else { + left = ((ExprTy.Constant) binOp.left).value; + } + ExprTy.Constant right = (ExprTy.Constant) binOp.right; + switch (binOp.op) { + case Add: + return left.addComplex(right.value); + case Sub: + return left.subComplex(right.value); + default: + throw new IllegalStateException("wrong constant BinOp operator " + binOp.op); + } + } + + @Override + public Void visit(MatchCaseTy node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(PatternTy.MatchAs node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(PatternTy.MatchClass node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(PatternTy.MatchMapping node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(PatternTy.MatchOr node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(PatternTy.MatchSequence node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(PatternTy.MatchSingleton node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(PatternTy.MatchStar node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(PatternTy.MatchValue node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(StmtTy.Nonlocal node) { + return null; + } + + @Override + public Void visit(StmtTy.Raise node) { + boolean newStatement = beginSourceSection(node, b); + b.beginRaise(); + + if (node.exc != null) { + node.exc.accept(this); + } else { + b.emitLoadConstant(PNone.NO_VALUE); + } + + if (node.cause != null) { + node.cause.accept(this); + } else { + b.emitLoadConstant(PNone.NO_VALUE); + } + + b.endRaise(); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(StmtTy.Return node) { + boolean newStatement = beginSourceSection(node, b); + if (!scope.isFunction()) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "'return' outside function"); + } + beginReturn(b); + if (node.value != null) { + node.value.accept(this); + } else { + b.emitLoadConstant(PNone.NONE); + } + endReturn(b); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(StmtTy.Try node) { + boolean newStatement = beginSourceSection(node, b); + if (node.finalBody != null && node.finalBody.length != 0) { + /** + * In Python, an uncaught exception becomes the "current" exception inside a finally + * block. The finally body can itself throw, in which case it replaces the exception + * being thrown. For such a scenario, we have to be careful to restore the "current" + * exception using a try-finally. + * + * In pseudocode, the implementation looks like: + * @formatter:off + * try { + * try_catch_else + * } catch uncaught_ex { + * save current exception + * set the current exception to uncaught_ex + * markCaught(uncaught_ex) + * try { + * finally_body + * } catch handler_ex { + * restore current exception + * markCaught(handler_ex) + * reraise handler_ex + * } otherwise { + * restore current exception + * } + * reraise uncaught_ex + * } otherwise { + * finally_body + * } + */ + b.beginTryCatchOtherwise(() -> { + b.beginBlock(); // finally + visitSequence(node.finalBody); + b.endBlock(); + }); + + emitTryExceptElse(node); // try + + b.beginBlock(); // catch + BytecodeLocal savedException = b.createLocal(); + emitSaveCurrentException(savedException); + emitSetCurrentException(); + // Mark this location for the stack trace. + b.beginMarkExceptionAsCaught(); + b.emitLoadException(); + b.endMarkExceptionAsCaught(); + + b.beginTryCatchOtherwise(() -> emitRestoreCurrentException(savedException)); + b.beginBlock(); // try + visitSequence(node.finalBody); + b.endBlock(); // try + + b.beginBlock(); // catch + emitRestoreCurrentException(savedException); + + b.beginMarkExceptionAsCaught(); + b.emitLoadException(); + b.endMarkExceptionAsCaught(); + + b.beginReraise(); + b.emitLoadException(); + b.endReraise(); + b.endBlock(); // catch + b.endTryCatchOtherwise(); + + b.beginReraise(); + b.emitLoadException(); + b.endReraise(); + b.endBlock(); // catch + b.endTryCatchOtherwise(); + // @formatter:on + } else { + emitTryExceptElse(node); + } + + endSourceSection(b, newStatement); + return null; + } + + /** + * Emit the "try-except-else" part of a Try node. The "finally" part, if it exists, should + * be handled by the caller of this method. + */ + private void emitTryExceptElse(StmtTy.Try node) { + if (node.handlers != null && node.handlers.length != 0) { + /** + * There are two orthogonal issues that complicate Python try-except clauses. + * + * First, when in an exception handler, the "current" exception (accessible via, e.g., + * sys.exc_info) gets set to the caught exception. After leaving the handler, this + * "current" exception must be restored to the one previously stored. Since except + * clauses can themselves raise exceptions, the restoring process must happen inside + * a finally block. + * + * Second, when an exception is bound to an identifier (e.g., except BaseException as + * ex), the identifier must be deleted after leaving the except clause. Again, since + * the except clause may raise an exception, the deletion must happen inside a finally + * block. Since the bound name is different in each clause, this block is specific to + * each handler. + * + * @formatter:off + * try { + * try_body + * # fall through to else_body + * } catch ex { + * save current exception + * set current exception to ex + * markCaught(ex) + * try { + * if (handler_1_matches(ex)) { + * assign ex to handler_1_name + * try { + * handler_1_body + * } catch handler_1_ex { + * unbind handler_1_name + * // Freeze the bci before it gets rethrown. + * markCaught(handler_ex) + * throw handler_1_ex + * } otherwise { + * unbind handler_1_name + * } + * goto afterElse + * } + * ... // more handlers + * + * // case 1: bare except + * bare_except_body + * goto afterElse + * } catch handler_ex { + * // A handler raised or no handler was found. Restore exception state and reraise. + * restore current exception + * markCaught(handler_ex) // (no-op if handler_ex is the original exception) + * reraise handler_ex + * } otherwise { + * // Exception handled. Restore the exception state. + * restore current exception + * } + * // case 2: no bare except (we only reach this point if no handler matched/threw) + * reraise ex + * } + * else_body + * afterElse: + */ + b.beginBlock(); // outermost block + + BytecodeLocal savedException = b.createLocal(); + BytecodeLabel afterElse = b.createLabel(); + + b.beginTryCatch(); + + b.beginBlock(); // try + visitSequence(node.body); + b.endBlock(); // try + + b.beginBlock(); // catch + emitSaveCurrentException(savedException); + emitSetCurrentException(); + // Mark this location for the stack trace. + b.beginMarkExceptionAsCaught(); + b.emitLoadException(); // ex + b.endMarkExceptionAsCaught(); + + b.beginTryCatchOtherwise(() -> emitRestoreCurrentException(savedException)); + b.beginBlock(); // try + SourceRange bareExceptRange = null; + for (ExceptHandlerTy h : node.handlers) { + boolean newStatement = beginSourceSection(h, b); + if (bareExceptRange != null) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "default 'except:' must be last"); + } + + ExceptHandlerTy.ExceptHandler handler = (ExceptHandlerTy.ExceptHandler) h; + if (handler.type != null) { + b.beginIfThen(); + b.beginExceptMatch(); + b.emitLoadException(); // ex + handler.type.accept(this); + b.endExceptMatch(); + } else { + bareExceptRange = handler.getSourceRange(); + } + + b.beginBlock(); // handler body + + if (handler.name != null) { + // Assign exception to handler name. + beginStoreLocal(handler.name, b); + b.beginUnwrapException(); + b.emitLoadException(); // ex + b.endUnwrapException(); + endStoreLocal(handler.name, b); + + b.beginTryCatchOtherwise(() -> emitUnbindHandlerVariable(handler)); + b.beginBlock(); // try + visitSequence(handler.body); + b.endBlock(); // try + + b.beginBlock(); // catch + emitUnbindHandlerVariable(handler); + + b.beginMarkExceptionAsCaught(); + b.emitLoadException(); // handler_i_ex + b.endMarkExceptionAsCaught(); + + b.beginThrow(); + b.emitLoadException(); // handler_i_ex + b.endThrow(); + b.endBlock(); // catch + b.endTryCatchOtherwise(); + } else { // bare except + b.beginBlock(); + visitSequence(handler.body); + b.endBlock(); + } + + b.emitBranch(afterElse); + + b.endBlock(); // handler body + + if (handler.type != null) { + b.endIfThen(); + } + + endSourceSection(b, newStatement); + } + b.endBlock(); // try + + b.beginBlock(); // catch + emitRestoreCurrentException(savedException); + + b.beginMarkExceptionAsCaught(); + b.emitLoadException(); // handler_ex + b.endMarkExceptionAsCaught(); + + b.beginReraise(); + b.emitLoadException(); // handler_ex + b.endReraise(); + b.endBlock(); // catch + b.endTryCatchOtherwise(); + + /** + * Each handler branches to afterElse. If we reach this point and there was not a + * bare exception, none of the handlers matched, and we should reraise. + * Optimization: If there's a bare except clause, control will never fall through + * and we can omit the rethrow. + */ + if (bareExceptRange == null) { + b.beginReraise(); + b.emitLoadException(); // ex + b.endReraise(); + } + + b.endBlock(); // catch + + b.endTryCatch(); + + if (node.orElse != null) { + visitSequence(node.orElse); + } + b.emitLabel(afterElse); + + b.endBlock(); // outermost block + // @formatter:on + } else { + // Optimization: If there's no except clauses, there's no point in generating a + // TryCatch with a catch that just rethrows the caught exception. + b.beginBlock(); + visitSequence(node.body); + b.endBlock(); + } + } + + private void emitSaveCurrentException(BytecodeLocal savedException) { + b.beginStoreLocal(savedException); + b.emitGetCurrentException(); + b.endStoreLocal(); + } + + private void emitSetCurrentException() { + b.beginSetCurrentException(); + b.emitLoadException(); + b.endSetCurrentException(); + } + + private void emitRestoreCurrentException(BytecodeLocal savedException) { + b.beginSetCurrentException(); + b.emitLoadLocal(savedException); + b.endSetCurrentException(); + } + + private void emitUnbindHandlerVariable(ExceptHandlerTy.ExceptHandler handler) { + b.beginBlock(); + // Store None to the variable just in case the handler deleted it. + beginStoreLocal(handler.name, b); + b.emitLoadConstant(PNone.NONE); + endStoreLocal(handler.name, b); + emitDelLocal(handler.name, b); + b.endBlock(); + } + + @Override + public Void visit(StmtTy.TryStar node) { + emitNotImplemented("try star", b); + return null; + } + + @Override + public Void visit(ExceptHandlerTy.ExceptHandler node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(StmtTy.While node) { + boolean newStatement = beginSourceSection(node, b); + b.beginBlock(); + + BytecodeLabel oldBreakLabel = breakLabel; + BytecodeLabel oldContinueLabel = continueLabel; + + BytecodeLabel currentBreakLabel = b.createLabel(); + breakLabel = currentBreakLabel; + + b.beginWhile(); + + b.beginBlock(); + b.emitTraceLineAtLoopHeader(currentLocation.startLine); + visitCondition(node.test); + b.endBlock(); + + b.beginBlock(); + continueLabel = b.createLabel(); + visitStatements(node.body); + b.emitLabel(continueLabel); + b.endBlock(); + + b.endWhile(); + + breakLabel = oldBreakLabel; + continueLabel = oldContinueLabel; + visitStatements(node.orElse); + b.emitLabel(currentBreakLabel); + + b.endBlock(); + endSourceSection(b, newStatement); + return null; + } + + private void visitWithRecurse(WithItemTy[] items, int index, StmtTy[] body, boolean async) { + /** + * For a with-statement like + * + * with foo as x: + * bar + * + * we generate code that performs (roughly) + * + * @formatter:off + * contextManager = foo + * resolve __enter__ and __exit__ + * value = __enter__() + * try { + * x = value + * bar + * } catch ex { + * if not __exit__(...): + * raise + * } otherwise { + * call __exit__(None, None, None) + * } + * @formatter:on + * + * When there are multiple context managers, they are recursively generated (where "bar" + * is). Once we have entered all of the context managers, we emit the body. + */ + WithItemTy item = items[index]; + boolean newStatement = beginSourceSection(item, b); + b.beginBlock(); + + BytecodeLocal contextManager = b.createLocal(); + b.beginStoreLocal(contextManager); + item.contextExpr.accept(this); + b.endStoreLocal(); + + BytecodeLocal exit = b.createLocal(); + BytecodeLocal value = b.createLocal(); + if (async) { + // call __aenter__ + b.beginAsyncContextManagerEnter(exit, value); + b.emitLoadLocal(contextManager); + b.endAsyncContextManagerEnter(); + // await the result + emitAwait(() -> b.emitLoadLocal(value)); + } else { + // call __enter__ + b.beginContextManagerEnter(exit, value); + b.emitLoadLocal(contextManager); + b.endContextManagerEnter(); + } + + Runnable finallyHandler; + if (async) { + finallyHandler = () -> emitAwait(() -> { + b.beginAsyncContextManagerCallExit(); + b.emitLoadConstant(PNone.NONE); + b.emitLoadLocal(exit); + b.emitLoadLocal(contextManager); + b.endAsyncContextManagerCallExit(); + }); + } else { + finallyHandler = () -> { + // call __exit__ + b.beginContextManagerExit(); + b.emitLoadConstant(PNone.NONE); + b.emitLoadLocal(exit); + b.emitLoadLocal(contextManager); + b.endContextManagerExit(); + }; + } + b.beginTryCatchOtherwise(finallyHandler); + b.beginBlock(); // try + if (item.optionalVars != null) { + item.optionalVars.accept(new StoreVisitor(() -> b.emitLoadLocal(value))); + } + if (index < items.length - 1) { + visitWithRecurse(items, index + 1, body, async); + } else { + visitSequence(body); + } + b.endBlock(); // try + + b.beginBlock(); // catch + + // Mark this location for the stack trace. + b.beginMarkExceptionAsCaught(); + b.emitLoadException(); + b.endMarkExceptionAsCaught(); + + // exceptional exit + if (async) { + // call, await, and handle result of __aexit__ + b.beginAsyncContextManagerExit(); + b.emitLoadException(); + emitAwait(() -> { + b.beginAsyncContextManagerCallExit(); + b.emitLoadException(); + b.emitLoadLocal(exit); + b.emitLoadLocal(contextManager); + b.endAsyncContextManagerCallExit(); + }); + b.endAsyncContextManagerExit(); + } else { + // call __exit__ + b.beginContextManagerExit(); + b.emitLoadException(); + b.emitLoadLocal(exit); + b.emitLoadLocal(contextManager); + b.endContextManagerExit(); + } + b.endBlock(); // catch + + b.endTryCatchOtherwise(); + b.endBlock(); + endSourceSection(b, newStatement); + } + + @Override + public Void visit(StmtTy.With node) { + boolean newStatement = beginSourceSection(node, b); + visitWithRecurse(node.items, 0, node.body, false); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(WithItemTy node) { + throw new UnsupportedOperationException("" + node.getClass()); + } + + @Override + public Void visit(StmtTy.Break aThis) { + boolean newStatement = beginSourceSection(aThis, b); + if (breakLabel == null) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "'break' outside loop"); + } + b.emitBranch(breakLabel); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(StmtTy.Continue aThis) { + boolean newStatement = beginSourceSection(aThis, b); + if (continueLabel == null) { + ctx.errorCallback.onError(ErrorType.Syntax, currentLocation, "'continue' not properly in loop"); + } + b.emitBranch(continueLabel); + endSourceSection(b, newStatement); + return null; + } + + @Override + public Void visit(StmtTy.Pass aThis) { + return null; + } + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/capsule/CreateArrowPyCapsuleNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallBinaryIOp1Node.java similarity index 56% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/capsule/CreateArrowPyCapsuleNode.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallBinaryIOp1Node.java index 0efc521654..a873681881 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/capsule/CreateArrowPyCapsuleNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallBinaryIOp1Node.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,41 +38,46 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.nodes.arrow.capsule; +package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.modules.cext.PythonCextCapsuleBuiltins.PyCapsuleNewNode; -import com.oracle.graal.python.builtins.objects.capsule.PyCapsule; -import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers; -import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.CallSlotBinaryFuncNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.arrow.ArrowArray; -import com.oracle.graal.python.nodes.arrow.ArrowSchema; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; -@GenerateCached(false) +/** + * Equivalent of cpython://Objects/abstract.c#binary_iop1. + */ @GenerateInline -public abstract class CreateArrowPyCapsuleNode extends PNodeWithContext { - - public abstract PTuple execute(Node inliningTarget, ArrowArray arrowArray, ArrowSchema arrowSchema); +@GenerateCached(false) +@GenerateUncached +public abstract class CallBinaryIOp1Node extends PNodeWithContext { + public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object v, Object classV, TpSlots slotsV, + Object w, Object classW, TpSlots slotsW, InplaceSlot op); @Specialization - static PTuple doArrowCArray(Node inliningTarget, ArrowArray arrowArray, ArrowSchema arrowSchema, - @Cached PyCapsuleNewNode pyCapsuleNewNode, - @Cached(inline = false) PythonObjectFactory pythonObjectFactory) { - var ctx = getContext(inliningTarget); - long arrayDestructor = ctx.arrowSupport.getArrowArrayDestructor(); - var arrayCapsuleName = new CArrayWrappers.CByteArrayWrapper(ArrowArray.CAPSULE_NAME); - PyCapsule arrowArrayCapsule = pyCapsuleNewNode.execute(inliningTarget, arrowArray.memoryAddr, arrayCapsuleName, arrayDestructor); - - long schemaDestructor = ctx.arrowSupport.getArrowSchemaDestructor(); - var schemaCapsuleName = new CArrayWrappers.CByteArrayWrapper(ArrowSchema.CAPSULE_NAME); - PyCapsule arrowSchemaCapsule = pyCapsuleNewNode.execute(inliningTarget, arrowSchema.memoryAddr, schemaCapsuleName, schemaDestructor); - - return pythonObjectFactory.createTuple(new Object[]{arrowSchemaCapsule, arrowArrayCapsule}); + static Object doIt(VirtualFrame frame, Node inliningTarget, Object v, Object classV, TpSlots slotsV, Object w, Object classW, TpSlots slotsW, InplaceSlot iop, + @Cached CallSlotBinaryFuncNode callSlotNode, + @Cached InlinedBranchProfile resultProfile, + @Cached CallBinaryOp1Node callBinaryOp1Node) { + TpSlot slot = iop.getSlotValue(slotsV); + if (slot != null) { + Object result = callSlotNode.execute(frame, inliningTarget, slot, v, w); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + resultProfile.enter(inliningTarget); + return result; + } + } + return callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotsV, w, classW, slotsW, iop.getReversibleSlot()); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallBinaryIOpNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallBinaryIOpNode.java new file mode 100644 index 0000000000..b52455725d --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallBinaryIOpNode.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import static com.oracle.graal.python.lib.CallBinaryOpNode.raiseNotSupported; + +import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; + +/** + * Equivalent of cpython://Objects/abstract.c#binary_op. + */ +@GenerateInline +@GenerateCached(false) +@GenerateUncached +public abstract class CallBinaryIOpNode extends Node { + public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object v, Object w, InplaceSlot slot, String opName); + + @Specialization + static Object doIt(VirtualFrame frame, Node inliningTarget, Object v, Object w, InplaceSlot slot, String opName, + @Cached GetClassNode getVClass, + @Cached GetCachedTpSlotsNode getVSlots, + @Cached GetCachedTpSlotsNode getWSlots, + @Cached GetClassNode getWClass, + @Cached CallBinaryIOp1Node callBinaryIOp1Node, + @Cached PRaiseNode raiseNode) { + Object classV = getVClass.execute(inliningTarget, v); + Object classW = getWClass.execute(inliningTarget, w); + TpSlots slotsV = getVSlots.execute(inliningTarget, classV); + TpSlots slotsW = getWSlots.execute(inliningTarget, classW); + Object result = callBinaryIOp1Node.execute(frame, inliningTarget, v, classV, slotsV, w, classW, slotsW, slot); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + return result; + } + throw raiseNotSupported(inliningTarget, v, w, opName, raiseNode); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallBinaryOp1Node.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallBinaryOp1Node.java index 5da1edf36f..63e4204dab 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallBinaryOp1Node.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallBinaryOp1Node.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,16 +41,18 @@ package com.oracle.graal.python.lib; import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.IsSameSlotNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.CallSlotBinaryOpNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @@ -62,9 +64,10 @@ */ @GenerateInline @GenerateCached(false) +@GenerateUncached public abstract class CallBinaryOp1Node extends PNodeWithContext { - public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object v, Object classV, TpSlot slotV, - Object w, Object classW, TpSlot slotW, BinaryOpSlot op); + public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object v, Object classV, TpSlots slotsV, + Object w, Object classW, TpSlots slotsW, ReversibleSlot op); // CPython binary_op1 may end up calling SLOT1BINFULL - wrapper around the dunder methods, which // duplicates some of the logic checking the right operand, its slot, and whether it is subtype. @@ -86,47 +89,50 @@ public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object v // we just try __rxxx__, again, without any subclass check. @Specialization - static Object doIt(VirtualFrame frame, Node inliningTarget, Object v, Object classV, TpSlot slotV, Object w, Object classW, TpSlot slotWIn, BinaryOpSlot op, + static Object doIt(VirtualFrame frame, Node inliningTarget, Object v, Object classV, TpSlots slotsV, Object w, Object classW, TpSlots slotsW, ReversibleSlot op, @Cached IsSameTypeNode isSameTypeNode, @Cached IsSameSlotNode isSameSlotNode, @Cached InlinedConditionProfile isSameTypeProfile, @Cached InlinedConditionProfile isSameSlotProfile, @Cached(inline = false) IsSubtypeNode isSubtypeNode, - @Cached InlinedBranchProfile wResultBranch, - @Cached InlinedBranchProfile vResultBranch, + @Cached InlinedConditionProfile vResultProfile, + @Cached InlinedConditionProfile wResultProfile, @Cached InlinedBranchProfile notImplementedBranch, @Cached CallSlotBinaryOpNode callSlotWNode, @Cached CallSlotBinaryOpNode callSlotVNode) { - TpSlot slotW = null; - boolean sameTypes = isSameTypeProfile.profile(inliningTarget, isSameTypeNode.execute(inliningTarget, classW, classV)); - if (!sameTypes) { - slotW = slotWIn; - if (isSameSlotProfile.profile(inliningTarget, slotV != null && slotW != null && isSameSlotNode.execute(inliningTarget, slotW, slotV))) { - slotW = null; - } - } + final TpSlot slotV = op.getSlotValue(slotsV); + final TpSlot slotW = op.getSlotValue(slotsW); + boolean skipReverse = false; // Note: we call slotW with v as the receiver. This appears to be the semantics of // CPython reversible binop slots. This is supposed to allow the slot to handle // the reversible case, if the slot does not want to handle it, it should detect that // the first receiver argument is not of the right type and just return NotImplemented. if (slotV != null) { - if (slotW != null && isSubtypeNode.execute(frame, classW, classV)) { - assert !sameTypes; - Object result = callSlotWNode.execute(frame, inliningTarget, slotW, v, classV, w, slotW, classW, false, op); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - wResultBranch.enter(inliningTarget); - return result; + boolean sameTypes = false; + if (slotW != null) { + sameTypes = isSameTypeProfile.profile(inliningTarget, isSameTypeNode.execute(inliningTarget, classW, classV)); + if (!sameTypes) { + if (!isSameSlotProfile.profile(inliningTarget, isSameSlotNode.execute(inliningTarget, slotW, slotV))) { + if (isSubtypeNode.execute(classW, classV)) { + Object result = callSlotWNode.execute(frame, inliningTarget, slotW, v, classV, w, slotW, classW, false, op); + if (wResultProfile.profile(inliningTarget, result != PNotImplemented.NOT_IMPLEMENTED)) { + return result; + } + skipReverse = true; + } + } else { + skipReverse = true; + } + } else { + skipReverse = true; } - slotW = null; } - Object result = callSlotVNode.execute(frame, inliningTarget, slotV, v, classV, w, slotWIn, classW, sameTypes, op); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - vResultBranch.enter(inliningTarget); + Object result = callSlotVNode.execute(frame, inliningTarget, slotV, v, classV, w, slotW, classW, sameTypes, op); + if (vResultProfile.profile(inliningTarget, result != PNotImplemented.NOT_IMPLEMENTED)) { return result; } } - if (slotW != null) { - assert !sameTypes; + if (slotW != null && !skipReverse) { return callSlotWNode.execute(frame, inliningTarget, slotW, v, classV, w, slotW, classW, false, op); } notImplementedBranch.enter(inliningTarget); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallBinaryOpNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallBinaryOpNode.java new file mode 100644 index 0000000000..e09fb2c59d --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallBinaryOpNode.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; + +/** + * Equivalent of cpython://Objects/abstract.c#binary_op. + */ +@GenerateInline +@GenerateCached(false) +@GenerateUncached +public abstract class CallBinaryOpNode extends Node { + public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object v, Object w, ReversibleSlot slot, String opName); + + @Specialization + static Object doIt(VirtualFrame frame, Node inliningTarget, Object v, Object w, ReversibleSlot slot, String opName, + @Cached GetClassNode getVClass, + @Cached GetCachedTpSlotsNode getVSlots, + @Cached GetCachedTpSlotsNode getWSlots, + @Cached GetClassNode getWClass, + @Cached CallBinaryOp1Node callBinaryOp1Node, + @Cached PRaiseNode raiseNode) { + Object classV = getVClass.execute(inliningTarget, v); + Object classW = getWClass.execute(inliningTarget, w); + TpSlots slotsV = getVSlots.execute(inliningTarget, classV); + TpSlots slotsW = getWSlots.execute(inliningTarget, classW); + Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotsV, w, classW, slotsW, slot); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + return result; + } + throw raiseNotSupported(inliningTarget, v, w, opName, raiseNode); + } + + @InliningCutoff + static PException raiseNotSupported(Node inliningTarget, Object v, Object w, String opName, PRaiseNode raiseNode) { + return raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, opName, v, w); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallTernaryIOpNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallTernaryIOpNode.java new file mode 100644 index 0000000000..eda627ab2d --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallTernaryIOpNode.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotNbPower.CallSlotNbInPlacePowerNode; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; + +@GenerateInline +@GenerateCached(false) +@GenerateUncached +public abstract class CallTernaryIOpNode extends Node { + public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object v, Object w, Object z); + + @Specialization + static Object doGeneric(VirtualFrame frame, Node inliningTarget, Object v, Object w, Object z, + @Cached GetClassNode getVClass, + @Cached GetClassNode getWClass, + @Cached GetCachedTpSlotsNode getVSlots, + @Cached GetCachedTpSlotsNode getWSlots, + @Cached CallSlotNbInPlacePowerNode callInplacePower, + @Cached CallTernaryOpNode callTernaryOpNode) { + Object classV = getVClass.execute(inliningTarget, v); + TpSlots slotsV = getVSlots.execute(inliningTarget, classV); + TpSlot slotV = slotsV.nb_inplace_power(); + if (slotV != null) { + Object result = callInplacePower.execute(frame, inliningTarget, slotV, v, w, z); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + return result; + } + } + slotV = slotsV.nb_power(); + Object classW = getWClass.execute(inliningTarget, w); + TpSlot slotW = getWSlots.execute(inliningTarget, classW).nb_power(); + return callTernaryOpNode.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, z); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallTernaryOpNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallTernaryOpNode.java new file mode 100644 index 0000000000..b86d30c4d5 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/CallTernaryOpNode.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.IsSameSlotNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotNbPower.CallSlotNbPowerNode; +import com.oracle.graal.python.nodes.classes.IsSubtypeNode; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; + +@GenerateInline +@GenerateCached(value = false) +@GenerateUncached +public abstract class CallTernaryOpNode extends Node { + public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object v, Object classV, TpSlot slotV, Object w, Object classW, TpSlot slotW, Object z); + + @Specialization + static Object doGeneric(VirtualFrame frame, Node inliningTarget, Object v, Object classV, TpSlot slotV, Object w, Object classW, TpSlot slotWIn, Object z, + @Cached IsSameTypeNode isSameTypeNode, + @Cached IsSameSlotNode isSameSlotNode, + @Cached InlinedConditionProfile isSameTypeProfile, + @Cached InlinedConditionProfile isSameSlotProfile, + @Cached(inline = false) IsSubtypeNode isSubtypeNode, + @Cached InlinedBranchProfile wResultBranch, + @Cached InlinedBranchProfile vResultBranch, + @Cached InlinedBranchProfile wResult2Branch, + @Cached InlinedBranchProfile notImplementedBranch, + @Cached CallSlotNbPowerNode callSlotWNode, + @Cached CallSlotNbPowerNode callSlotVNode, + @Cached CallSlotNbPowerNode callSlotZNode, + @Cached GetClassNode getZClass, + @Cached GetCachedTpSlotsNode getZSlots) { + TpSlot slotW = null; + boolean sameTypes = isSameTypeProfile.profile(inliningTarget, isSameTypeNode.execute(inliningTarget, classW, classV)); + if (!sameTypes) { + slotW = slotWIn; + if (isSameSlotProfile.profile(inliningTarget, slotV != null && slotW != null && isSameSlotNode.execute(inliningTarget, slotW, slotV))) { + slotW = null; + } + } + + if (slotV != null) { + if (slotW != null && isSubtypeNode.execute(classW, classV)) { + assert !sameTypes; + Object result = callSlotWNode.execute(frame, inliningTarget, slotW, v, classV, w, slotW, classW, z, false); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + wResultBranch.enter(inliningTarget); + return result; + } + slotW = null; + } + Object result = callSlotVNode.execute(frame, inliningTarget, slotV, v, classV, w, slotWIn, classW, z, sameTypes); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + vResultBranch.enter(inliningTarget); + return result; + } + } + + if (slotW != null) { + assert !sameTypes; + Object result = callSlotWNode.execute(frame, inliningTarget, slotW, v, classV, w, slotW, classW, z, false); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + wResult2Branch.enter(inliningTarget); + return result; + } + } + + if (z != PNone.NONE) { + Object classZ = getZClass.execute(inliningTarget, z); + TpSlot slotZ = getZSlots.execute(inliningTarget, classZ).nb_power(); + if (slotZ != null) { + if ((slotV == null || !isSameSlotNode.execute(inliningTarget, slotZ, slotV)) && (slotW == null || !isSameSlotNode.execute(inliningTarget, slotZ, slotW))) { + return callSlotZNode.execute(frame, inliningTarget, slotZ, v, classV, w, slotWIn, classW, z, false); + } + } + } + + notImplementedBranch.enter(inliningTarget); + return PNotImplemented.NOT_IMPLEMENTED; + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/GetMethodsFlagsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/GetMethodsFlagsNode.java deleted file mode 100644 index 488fc884c9..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/GetMethodsFlagsNode.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.lib; - -import static com.oracle.graal.python.nodes.HiddenAttr.METHODS_FLAGS; - -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; -import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PCallCapiFunction; -import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol; -import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; -import com.oracle.graal.python.nodes.HiddenAttr; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.truffle.api.Assumption; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node; - -/** - * Retrieve slots occupation of `cls->tp_as_number`, `cls->tp_as_sequence` and `cls->tp_as_mapping` - * for a given class. - */ -@GenerateUncached -@GenerateInline(inlineByDefault = true) -public abstract class GetMethodsFlagsNode extends Node { - - public abstract long execute(Node inliningTarget, Object cls); - - @Specialization - protected static long pythonbuiltinclasstype(PythonManagedClass cls) { - return cls.getMethodsFlags(); - } - - @Specialization - protected static long pythonclasstype(PythonBuiltinClassType cls) { - return cls.getMethodsFlags(); - } - - @TruffleBoundary - private static long populateMethodsFlags(PythonAbstractNativeObject cls) { - Long flags = (Long) PCallCapiFunction.callUncached(NativeCAPISymbol.FUN_GET_METHODS_FLAGS, cls.getPtr()); - HiddenAttr.WriteNode.executeUncached(cls, METHODS_FLAGS, flags); - return flags; - } - - protected static long getMethodsFlags(PythonAbstractNativeObject cls) { - return doNative(null, cls, HiddenAttr.ReadNode.getUncached()); - } - - // The assumption should hold unless `PyType_Modified` is called. - protected static Assumption nativeAssumption(PythonAbstractNativeObject cls) { - return PythonContext.get(null).getNativeClassStableAssumption(cls, true).getAssumption(); - } - - @Specialization(guards = "cachedCls == cls", limit = "5", assumptions = "nativeAssumption(cachedCls)") - static long doNativeCached(@SuppressWarnings("unused") PythonAbstractNativeObject cls, - @SuppressWarnings("unused") @Cached("cls") PythonAbstractNativeObject cachedCls, - @Cached("getMethodsFlags(cls)") long flags) { - return flags; - } - - @Specialization(replaces = "doNativeCached") - static long doNative(Node inliningTarget, PythonAbstractNativeObject cls, - @Cached HiddenAttr.ReadNode readFlagsNode) { - // classes must have tp_dict since they are set during PyType_Ready - Long flags = (Long) readFlagsNode.execute(inliningTarget, cls, METHODS_FLAGS, null); - if (flags == null) { - return populateMethodsFlags(cls); - } - return flags; - } - - @Fallback - protected static long zero(@SuppressWarnings("unused") Object cls) { - return 0; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/GetNextNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/GetNextNode.java deleted file mode 100644 index e36648c901..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/GetNextNode.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.lib; - -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEXT__; - -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode.NoAttributeHandler; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.frame.Frame; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.UnexpectedResultException; - -public abstract class GetNextNode extends PNodeWithContext { - public abstract Object execute(Frame frame, Object iterator); - - public Object execute(Object iterator) { - return execute(null, iterator); - } - - public abstract boolean executeBoolean(VirtualFrame frame, Object iterator) throws UnexpectedResultException; - - public abstract int executeInt(VirtualFrame frame, Object iterator) throws UnexpectedResultException; - - public abstract long executeLong(VirtualFrame frame, Object iterator) throws UnexpectedResultException; - - public abstract double executeDouble(VirtualFrame frame, Object iterator) throws UnexpectedResultException; - - private static final class GetNextCached extends GetNextNode { - - @Child private LookupAndCallUnaryNode nextCall = LookupAndCallUnaryNode.create(SpecialMethodSlot.Next, () -> new NoAttributeHandler() { - @Child private PRaiseNode raiseNode = PRaiseNode.create(); - - @Override - public Object execute(Object receiver) { - throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.OBJ_NOT_ITERABLE, receiver); - } - }); - - @Override - public Object execute(Frame frame, Object iterator) { - return nextCall.executeObject((VirtualFrame) frame, iterator); - } - - @Override - public boolean executeBoolean(VirtualFrame frame, Object iterator) throws UnexpectedResultException { - return PGuards.expectBoolean(nextCall.executeObject(frame, iterator)); - } - - @Override - public int executeInt(VirtualFrame frame, Object iterator) throws UnexpectedResultException { - return PGuards.expectInteger(nextCall.executeObject(frame, iterator)); - } - - @Override - public long executeLong(VirtualFrame frame, Object iterator) throws UnexpectedResultException { - return PGuards.expectLong(nextCall.executeObject(frame, iterator)); - } - - @Override - public double executeDouble(VirtualFrame frame, Object iterator) throws UnexpectedResultException { - return PGuards.expectDouble(nextCall.executeObject(frame, iterator)); - } - } - - private static final class GetNextUncached extends GetNextNode { - static final GetNextUncached INSTANCE = new GetNextUncached(); - - @Override - public Object execute(Frame frame, Object iterator) { - return executeImpl(iterator); - } - - @SuppressWarnings("static-method") - @TruffleBoundary - private Object executeImpl(Object iterator) { - Object nextMethod = LookupSpecialMethodSlotNode.getUncached(SpecialMethodSlot.Next).execute(null, GetClassNode.executeUncached(iterator), iterator); - if (nextMethod == PNone.NO_VALUE) { - throw PRaiseNode.getUncached().raise(PythonErrorType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, iterator, T___NEXT__); - } - return CallUnaryMethodNode.getUncached().executeObject(nextMethod, iterator); - } - - @Override - public boolean executeBoolean(VirtualFrame frame, Object iterator) throws UnexpectedResultException { - Object value = execute(frame, iterator); - if (value instanceof Boolean) { - return (boolean) value; - } - throw new UnexpectedResultException(value); - } - - @Override - public int executeInt(VirtualFrame frame, Object iterator) throws UnexpectedResultException { - Object value = execute(frame, iterator); - if (value instanceof Integer) { - return (int) value; - } - throw new UnexpectedResultException(value); - } - - @Override - public long executeLong(VirtualFrame frame, Object iterator) throws UnexpectedResultException { - Object value = execute(frame, iterator); - if (value instanceof Long) { - return (long) value; - } - throw new UnexpectedResultException(value); - } - - @Override - public double executeDouble(VirtualFrame frame, Object iterator) throws UnexpectedResultException { - Object value = execute(frame, iterator); - if (value instanceof Double) { - return (double) value; - } - throw new UnexpectedResultException(value); - } - } - - @NeverDefault - public static GetNextNode create() { - return new GetNextCached(); - } - - public static GetNextNode getUncached() { - return GetNextUncached.INSTANCE; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyContextSignature.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/IteratorExhausted.java similarity index 84% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyContextSignature.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/IteratorExhausted.java index d3e9aa4ab9..a9b775d7d3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyContextSignature.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/IteratorExhausted.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,10 +38,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.builtins.objects.cext.hpy; +package com.oracle.graal.python.lib; -/** - * Describes the signature of an HPyContext function. - */ -public record HPyContextSignature(HPyContextSignatureType returnType, HPyContextSignatureType[] parameterTypes) { +import com.oracle.graal.python.runtime.exception.PythonControlFlowException; + +public class IteratorExhausted extends PythonControlFlowException { + public static final IteratorExhausted INSTANCE = new IteratorExhausted(); + + private IteratorExhausted() { + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/release_callback/ArrowArrayReleaseCallbackNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyAIterCheckNode.java similarity index 69% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/release_callback/ArrowArrayReleaseCallbackNode.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyAIterCheckNode.java index 44ee930a5f..ffbe391281 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/release_callback/ArrowArrayReleaseCallbackNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyAIterCheckNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,31 +38,39 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.nodes.arrow.release_callback; +package com.oracle.graal.python.lib; -import com.oracle.graal.python.nodes.arrow.ArrowArray; -import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.graal.python.builtins.objects.asyncio.PANextAwaitable; +import com.oracle.graal.python.builtins.objects.asyncio.PAsyncGen; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; -@GenerateCached(false) @GenerateInline @GenerateUncached -public abstract class ArrowArrayReleaseCallbackNode extends Node { +@GenerateCached(false) +public abstract class PyAIterCheckNode extends Node { + public abstract boolean execute(Node inliningTarget, Object object); - public abstract void execute(Node inliningTarget, ArrowArray arrowArray); + @Specialization + static boolean doIterator(@SuppressWarnings("unused") PAsyncGen object) { + return true; + } @Specialization - static void release(Node inliningTarget, ArrowArray arrowArray) { - /* - * This callback should be used for ArrowArray where we manage the memory. Since right now - * we are supporting only Apache Arrow Vectors the memory is managed on Java side. We use - * this callback in the capsule destructor which is only called when the consumer doesn't - * properly handle the take over the data from ArrowArray. - */ - throw CompilerDirectives.shouldNotReachHere(); + static boolean doAnextAwaitable(@SuppressWarnings("unused") PANextAwaitable object) { + return true; + } + + @Fallback + static boolean doGeneric(Node inliningTarget, Object object, + @Cached TpSlots.GetObjectSlotsNode getSlots) { + TpSlots slots = getSlots.execute(inliningTarget, object); + return slots.am_anext() != null; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyArgCheckPositionalNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyArgCheckPositionalNode.java index dbc3fec985..70fa3f5d5b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyArgCheckPositionalNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyArgCheckPositionalNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -66,16 +66,16 @@ public final boolean execute(Node inliningTarget, TruffleString name, Object[] a @Specialization static boolean doGeneric(Node inliningTarget, TruffleString name, int nargs, int min, int max, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { assert min >= 0; assert min <= max; if (nargs < min) { if (name != null) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, S_EXPECTED_SD_ARGS_GOT_D, + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, S_EXPECTED_SD_ARGS_GOT_D, name, (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs); } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, UNPACKED_TUPLE_SHOULD_HAVE_D_ELEMS, + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, UNPACKED_TUPLE_SHOULD_HAVE_D_ELEMS, (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs); } } @@ -86,10 +86,10 @@ static boolean doGeneric(Node inliningTarget, TruffleString name, int nargs, int if (nargs > max) { if (name != null) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, S_EXPECTED_SD_ARGS_GOT_D, + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, S_EXPECTED_SD_ARGS_GOT_D, name, (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs); } else { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, UNPACKED_TUPLE_SHOULD_HAVE_D_ELEMS, + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, UNPACKED_TUPLE_SHOULD_HAVE_D_ELEMS, (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyCallableCheckNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyCallableCheckNode.java index 74e27bfef4..0673c361f7 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyCallableCheckNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyCallableCheckNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,27 +41,20 @@ package com.oracle.graal.python.lib; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; import com.oracle.graal.python.builtins.objects.function.PFunction; import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.builtins.objects.method.PMethod; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; import com.oracle.graal.python.builtins.objects.type.PythonClass; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.object.IsForeignObjectNode; -import com.oracle.graal.python.nodes.util.LazyInteropLibrary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.nodes.Node; /** @@ -70,7 +63,6 @@ @GenerateUncached @GenerateInline(inlineByDefault = true) @GenerateCached -@ImportStatic(SpecialMethodSlot.class) public abstract class PyCallableCheckNode extends PNodeWithContext { public static boolean executeUncached(Object object) { return PyCallableCheckNodeGen.getUncached().execute(null, object); @@ -122,16 +114,8 @@ static boolean doType(@SuppressWarnings("unused") PythonBuiltinClassType o) { @Fallback static boolean doObject(Node inliningTarget, Object o, - @Cached GetClassNode getClassNode, - @Cached IsForeignObjectNode isForeignObjectNode, - @Cached LazyInteropLibrary lazyInteropLib, - @Cached(parameters = "Call", inline = false) LookupCallableSlotInMRONode lookupCall) { - Object type = getClassNode.execute(inliningTarget, o); - if (isForeignObjectNode.execute(inliningTarget, o)) { - InteropLibrary lib = lazyInteropLib.get(inliningTarget); - return lib.isExecutable(o) || lib.isInstantiable(o); - } - return lookupCall.execute(type) != PNone.NO_VALUE; + @Cached GetObjectSlotsNode getSlots) { + return getSlots.execute(inliningTarget, o).tp_call() != null; } public static PyCallableCheckNode create() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyContextCopyCurrent.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyContextCopyCurrent.java index cb3c4de41c..0159df5e47 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyContextCopyCurrent.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyContextCopyCurrent.java @@ -44,8 +44,7 @@ import com.oracle.graal.python.builtins.objects.contextvars.PContextVarsContext; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.dsl.Cached; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.Specialization; @@ -60,11 +59,10 @@ public abstract class PyContextCopyCurrent extends PNodeWithContext { public abstract PContextVarsContext execute(Node inliningTarget); @Specialization - static PContextVarsContext doIt(Node inliningTarget, - @Cached(inline = false) PythonObjectFactory factory) { + static PContextVarsContext doIt(Node inliningTarget) { PythonContext context = PythonContext.get(inliningTarget); PythonLanguage language = context.getLanguage(inliningTarget); PythonContext.PythonThreadState threadState = context.getThreadState(language); - return factory.copyContextVarsContext(threadState.getContextVarsContext()); + return PFactory.copyContextVarsContext(language, threadState.getContextVarsContext()); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyConvertOptionalToSizeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyConvertOptionalToSizeNode.java index 5fc303b88c..fab20906aa 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyConvertOptionalToSizeNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyConvertOptionalToSizeNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -69,14 +69,14 @@ int doOptional(@SuppressWarnings("unused") PNone value, int defaultValue) { @Specialization(guards = {"!isNone(value)", "!isNoValue(value)"}) static int doObject(VirtualFrame frame, Node inliningTarget, Object value, @SuppressWarnings("unused") int defaultValue, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached PyIndexCheckNode indexCheckNode, @Cached PyNumberAsSizeNode asSizeNode) { int limit; if (indexCheckNode.execute(inliningTarget, value)) { limit = asSizeNode.executeExact(frame, inliningTarget, value); } else { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.ARG_SHOULD_BE_INT_OR_NONE, value); + throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.ARG_SHOULD_BE_INT_OR_NONE, value); } return limit; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyDictDelItem.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyDictDelItem.java index 4e65a647d1..db133c06ef 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyDictDelItem.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyDictDelItem.java @@ -68,9 +68,9 @@ public abstract class PyDictDelItem extends Node { @Specialization static void delItem(VirtualFrame frame, Node inliningTarget, PDict dict, Object key, @Cached HashingStorageDelItem delItem, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (!delItem.execute(frame, inliningTarget, dict.getDictStorage(), key, dict)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.KeyError, new Object[]{key}); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.KeyError, new Object[]{key}); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyDictKeys.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyDictKeys.java index f928bdc036..ea0ede1ae7 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyDictKeys.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyDictKeys.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,6 +40,7 @@ */ package com.oracle.graal.python.lib; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.common.HashingStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetIterator; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageIterator; @@ -47,7 +48,8 @@ import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageIteratorNext; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageLen; import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -67,7 +69,7 @@ public abstract class PyDictKeys extends Node { @Specialization static Object getString(Node inliningTarget, PDict dict, - @Cached(inline = false) PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached HashingStorageLen lenNode, @Cached HashingStorageGetIterator getIter, @Cached HashingStorageIteratorNext iterNext, @@ -80,6 +82,6 @@ static Object getString(Node inliningTarget, PDict dict, while (iterNext.execute(inliningTarget, storage, it)) { keys[i++] = iterKey.execute(inliningTarget, storage, it); } - return factory.createList(keys); + return PFactory.createList(language, keys); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyFloatAsDoubleNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyFloatAsDoubleNode.java index 5f2d3f6a34..b39af80a79 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyFloatAsDoubleNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyFloatAsDoubleNode.java @@ -133,7 +133,7 @@ static double doObject(VirtualFrame frame, Node inliningTarget, Object object, @Cached PyNumberIndexNode indexNode, @Cached PyLongAsDoubleNode asDoubleNode, @Cached HandleFloatResultNode handleFloatResultNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object type = getClassNode.execute(inliningTarget, object); TpSlots slots = getSlots.execute(inliningTarget, type); if (slots.nb_float() != null) { @@ -147,7 +147,7 @@ static double doObject(VirtualFrame frame, Node inliningTarget, Object object, Object index = indexNode.execute(frame, inliningTarget, object); return asDoubleNode.execute(inliningTarget, index); } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MUST_BE_REAL_NUMBER, object); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_REAL_NUMBER, object); } @InliningCutoff @@ -156,7 +156,7 @@ static double handleFloatResult(VirtualFrame frame, Object result, Object object } static boolean isFloatSubtype(Node inliningTarget, Object object, GetClassNode getClass, IsSubtypeNode isSubtype) { - return FromNativeSubclassNode.isFloatSubtype(null, inliningTarget, object, getClass, isSubtype); + return FromNativeSubclassNode.isFloatSubtype(inliningTarget, object, getClass, isSubtype); } @GenerateInline(false) // Uncommon @@ -172,11 +172,11 @@ static double handle(VirtualFrame frame, Object result, Object original, @Cached IsSubtypeNode resultSubtypeNode, @Cached CastToJavaDoubleNode cast, @Cached WarningsModuleBuiltins.WarnNode warnNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object resultType = resultClassNode.execute(inliningTarget, result); if (!resultProfile.profileClass(inliningTarget, resultType, PythonBuiltinClassType.PFloat)) { if (!resultSubtypeNode.execute(resultType, PythonBuiltinClassType.PFloat)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.RETURNED_NON_FLOAT, original, result); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.RETURNED_NON_FLOAT, original, result); } else { warnNode.warnFormat(frame, null, DeprecationWarning, 1, ErrorMessages.WARN_P_RETURNED_NON_P, original, T___FLOAT__, "float", result, "float"); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyFloatFromString.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyFloatFromString.java index 87542d43eb..3d4c9b99ac 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyFloatFromString.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyFloatFromString.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -82,7 +82,7 @@ public abstract class PyFloatFromString extends PNodeWithContext { static double doString(VirtualFrame frame, Node inliningTarget, TruffleString object, @Cached(inline = false) TruffleString.ToJavaStringNode toJavaStringNode, @Shared @Cached PyObjectReprAsTruffleStringNode reprNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { return convertStringToDouble(frame, inliningTarget, toJavaStringNode.execute(object), object, reprNode, raiseNode); } @@ -93,7 +93,7 @@ static double doGeneric(VirtualFrame frame, Node inliningTarget, Object object, @CachedLibrary(limit = "3") PythonBufferAccessLibrary accessLib, @Cached(inline = false) CastToJavaStringNode cast, @Shared @Cached PyObjectReprAsTruffleStringNode reprNode, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { String string = null; try { string = cast.execute(object); @@ -117,7 +117,7 @@ static double doGeneric(VirtualFrame frame, Node inliningTarget, Object object, if (string != null) { return convertStringToDouble(frame, inliningTarget, string, object, reprNode, raiseNode); } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ARG_MUST_BE_STRING_OR_NUMBER, "float()", object); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ARG_MUST_BE_STRING_OR_NUMBER, "float()", object); } @TruffleBoundary(allowInlining = true) @@ -125,7 +125,7 @@ private static String newString(byte[] bytes, int offset, int length) { return new String(bytes, offset, length); } - private static double convertStringToDouble(VirtualFrame frame, Node inliningTarget, String src, Object origObj, PyObjectReprAsTruffleStringNode reprNode, PRaiseNode.Lazy raiseNode) { + private static double convertStringToDouble(VirtualFrame frame, Node inliningTarget, String src, Object origObj, PyObjectReprAsTruffleStringNode reprNode, PRaiseNode raiseNode) { String str = FloatUtils.removeUnicodeAndUnderscores(src); // Adapted from CPython's float_from_string_inner if (str != null) { @@ -144,9 +144,9 @@ private static double convertStringToDouble(VirtualFrame frame, Node inliningTar repr = reprNode.execute(frame, inliningTarget, origObj); } catch (PException e) { // Failed to format the message. Mirrors CPython behavior when the repr fails - throw raiseNode.get(inliningTarget).raise(ValueError); + throw raiseNode.raise(inliningTarget, ValueError); } - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.COULD_NOT_CONVERT_STRING_TO_FLOAT, repr); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.COULD_NOT_CONVERT_STRING_TO_FLOAT, repr); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyImportGetModule.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyImportGetModule.java index 309647e411..76e4cfc828 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyImportGetModule.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyImportGetModule.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -70,10 +70,10 @@ static Object doGeneric(VirtualFrame frame, Node node, Object name, @Bind("this") Node inliningTarget, @Cached InlinedConditionProfile noSysModulesProfile, @Cached(inline = false) DictBuiltins.GetItemNode getDictItemNode, - @Cached PRaiseNode.Lazy raise) { + @Cached PRaiseNode raise) { final PDict sysModules = PythonContext.get(node).getSysModules(); if (noSysModulesProfile.profile(inliningTarget, sysModules == null)) { - throw raise.get(inliningTarget).raise(PythonBuiltinClassType.RuntimeError, UNABLE_TO_GET_S, "sys.modules"); + throw raise.raise(inliningTarget, PythonBuiltinClassType.RuntimeError, UNABLE_TO_GET_S, "sys.modules"); } return getDictItemNode.execute(frame, sysModules, name); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyImportImport.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyImportImport.java index 3db032bdf8..7c056c7d2c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyImportImport.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyImportImport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,13 +47,15 @@ import static com.oracle.graal.python.nodes.BuiltinNames.T___IMPORT__; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.object.GetDictFromGlobalsNode; import com.oracle.graal.python.nodes.statement.AbstractImportNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -86,7 +88,7 @@ static Object doGeneric(VirtualFrame frame, Node inliningTarget, TruffleString m @Cached(inline = false) AbstractImportNode.PyImportImportModuleLevelObject importModuleLevelObject, @Cached PyEvalGetGlobals getGlobals, @Cached(inline = false) GetDictFromGlobalsNode getDictFromGlobals, - @Cached(inline = false) PythonObjectFactory factory) { + @Bind PythonLanguage language) { // Get the builtins from current globals Object globals = getGlobals.execute(frame, inliningTarget); Object builtins; @@ -95,7 +97,7 @@ static Object doGeneric(VirtualFrame frame, Node inliningTarget, TruffleString m } else { // No globals -- use standard builtins, and fake globals builtins = importModuleLevelObject.execute(frame, PythonContext.get(inliningTarget), T_BUILTINS, null, null, 0); - globals = factory.createDict(new PKeyword[]{new PKeyword(T___BUILTINS__, builtins)}); + globals = PFactory.createDict(language, new PKeyword[]{new PKeyword(T___BUILTINS__, builtins)}); } // Get the __import__ function from the builtins @@ -110,7 +112,7 @@ static Object doGeneric(VirtualFrame frame, Node inliningTarget, TruffleString m // here. Calling for side-effect of import. callNode.execute(frame, importFunc, new Object[]{moduleName}, new PKeyword[]{ new PKeyword(T_GLOBALS, globals), new PKeyword(T_LOCALS, globals), - new PKeyword(T_FROMLIST, factory.createList()), new PKeyword(T_LEVEL, 0) + new PKeyword(T_FROMLIST, PFactory.createList(language)), new PKeyword(T_LEVEL, 0) }); return importGetModule.execute(frame, inliningTarget, moduleName); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyIndexCheckNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyIndexCheckNode.java index ac53f18d4a..cf5ccb7dbf 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyIndexCheckNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyIndexCheckNode.java @@ -41,7 +41,6 @@ package com.oracle.graal.python.lib; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; @@ -50,7 +49,6 @@ import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -59,7 +57,6 @@ * Check if the object supports conversion to index (integer). Equivalent of CPython's * {@code PyIndex_Check}. The return value doesn't need to be profiled in most cases. */ -@ImportStatic(SpecialMethodSlot.class) @GenerateUncached @GenerateInline @GenerateCached(false) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyIterCheckNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyIterCheckNode.java index ddd93328cb..a985574977 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyIterCheckNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyIterCheckNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,18 +40,15 @@ */ package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.iterator.PBuiltinIterator; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; -import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; @@ -59,7 +56,6 @@ * Check if the object is iterable - has {@code __next__} method. Equivalent of CPython's * {@code PyIter_Check}. */ -@ImportStatic(SpecialMethodSlot.class) @GenerateInline(inlineByDefault = true) @GenerateUncached public abstract class PyIterCheckNode extends PNodeWithContext { @@ -81,9 +77,12 @@ static boolean doIterator(@SuppressWarnings("unused") PBuiltinIterator object) { @InliningCutoff @Fallback static boolean doGeneric(Node inliningTarget, Object object, - @Cached GetClassNode getClassNode, - @Cached(parameters = "Next", inline = false) LookupCallableSlotInMRONode lookupNext) { - Object type = getClassNode.execute(inliningTarget, object); - return !(lookupNext.execute(type) instanceof PNone); + @Cached TpSlots.GetObjectSlotsNode getSlots) { + TpSlots slots = getSlots.execute(inliningTarget, object); + return checkSlots(slots); + } + + public static boolean checkSlots(TpSlots slots) { + return slots.tp_iternext() != null && slots.tp_iternext() != TpSlotIterNext.NEXT_NOT_IMPLEMENTED; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyIterNextNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyIterNextNode.java index 5861c329e1..f311dab578 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyIterNextNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyIterNextNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,78 +40,57 @@ */ package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.iterator.PBigRangeIterator; -import com.oracle.graal.python.builtins.objects.iterator.PIntRangeIterator; -import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.exception.PythonErrorType; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; /** - * Obtains the next value of an iterator. When the iterator is exhausted it returns {@code null}. It - * never raises {@code StopIteration}. + * Obtains the next value of an iterator. It throws {@link IteratorExhausted} upon exhaustion. It + * never raises python {@code StopIteration}. */ @GenerateUncached -@GenerateInline(false) +@GenerateInline(inlineByDefault = true) public abstract class PyIterNextNode extends PNodeWithContext { - public abstract Object execute(Frame frame, Object iterator); + public abstract Object execute(Frame frame, Node inliningTarget, Object iterator); - @Specialization - Object doIntRange(PIntRangeIterator iterator) { - if (iterator.hasNextInt()) { - return iterator.nextInt(); - } - iterator.setExhausted(); - return null; + public final Object executeCached(VirtualFrame frame, Object iterator) { + return execute(frame, this, iterator); } - @Specialization - Object doBigIntRange(PBigRangeIterator iterator, - @Cached PythonObjectFactory factory) { - if (iterator.hasNextBigInt()) { - return factory.createInt(iterator.nextBigInt()); - } - iterator.setExhausted(); - return null; + public static Object executeUncached(Object iterator) { + return PyIterNextNodeGen.getUncached().execute(null, null, iterator); } - // TODO list, tuple, enumerate, dict keys, dict values, dict items, string, bytes - @Specialization - static Object doGeneric(VirtualFrame frame, Object iterator, - @Bind("this") Node inliningTarget, + static Object doGeneric(VirtualFrame frame, Node inliningTarget, Object iterator, @Cached GetClassNode getClassNode, - @Cached(parameters = "Next") LookupSpecialMethodSlotNode lookupNext, - @Cached CallUnaryMethodNode callNext, - @Cached IsBuiltinObjectProfile stopIterationProfile, - @Cached PRaiseNode.Lazy raiseNode) { - Object nextMethod = lookupNext.execute(frame, getClassNode.execute(inliningTarget, iterator), iterator); - if (nextMethod == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.OBJ_NOT_ITERABLE, iterator); - } + @Cached GetCachedTpSlotsNode getSlots, + @Cached CallSlotTpIterNextNode callNext, + @Cached IsBuiltinObjectProfile stopIterationProfile) { + TpSlots slots = getSlots.execute(inliningTarget, getClassNode.execute(inliningTarget, iterator)); + assert slots.tp_iternext() != null; try { - return callNext.executeObject(frame, nextMethod, iterator); + return callNext.execute(frame, inliningTarget, slots.tp_iternext(), iterator); } catch (PException e) { e.expectStopIteration(inliningTarget, stopIterationProfile); - return null; + throw TpIterNextBuiltin.iteratorExhausted(); } } + @NeverDefault public static PyIterNextNode create() { return PyIterNextNodeGen.create(); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsDoubleNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsDoubleNode.java index 4f4efd8c6b..464655747d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsDoubleNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsDoubleNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -97,14 +97,13 @@ static double doPInt(Node inliningTarget, PInt self) { static double doNative(Node inliningTarget, @SuppressWarnings("unused") PythonAbstractNativeObject self, @SuppressWarnings("unused") @Cached PyLongCheckNode check) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, ErrorMessages.CASTING_A_NATIVE_INT_OBJECT_IS_NOT_IMPLEMENTED_YET); + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, ErrorMessages.CASTING_A_NATIVE_INT_OBJECT_IS_NOT_IMPLEMENTED_YET); } @Fallback @InliningCutoff @SuppressWarnings("unused") - static double fallback(Node inliningTarget, Object object, - @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.INTEGER_REQUIRED); + static double fallback(Node inliningTarget, Object object) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.INTEGER_REQUIRED); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsIntNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsIntNode.java index c230fe81ab..f4134e8506 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsIntNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsIntNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,7 +45,6 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.util.OverflowException; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; @@ -81,7 +80,7 @@ static int doInt(int object) { @Specialization static int doObject(VirtualFrame frame, Node inliningTarget, Object object, @Cached PyLongAsLongAndOverflowNode pyLongAsLongAndOverflow, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { long result = pyLongAsLongAndOverflow.execute(frame, inliningTarget, object); int intResult = (int) result; @@ -95,7 +94,7 @@ static int doObject(VirtualFrame frame, Node inliningTarget, Object object, } @InliningCutoff - private static PException raiseOverflow(Node inliningTarget, Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "Java int"); + private static PException raiseOverflow(Node inliningTarget, PRaiseNode raiseNode) { + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "Java int"); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsLongAndOverflowNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsLongAndOverflowNode.java index 2d1e75fd10..679553a0f8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsLongAndOverflowNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsLongAndOverflowNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,7 +42,6 @@ import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr; import com.oracle.graal.python.builtins.objects.ints.PInt; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.util.OverflowException; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; @@ -51,7 +50,6 @@ import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; @@ -66,7 +64,6 @@ @GenerateUncached @GenerateInline(inlineByDefault = true) @GenerateCached(false) -@ImportStatic(SpecialMethodSlot.class) public abstract class PyLongAsLongAndOverflowNode extends PNodeWithContext { public abstract long execute(Frame frame, Node inliningTarget, Object object) throws OverflowException; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsLongNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsLongNode.java index 1656ee5464..0e08ac4a5f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsLongNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsLongNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -73,11 +73,11 @@ public final long executeCached(Frame frame, Object object) { @Specialization static long doObject(VirtualFrame frame, Node inliningTarget, Object object, @Cached PyLongAsLongAndOverflowNode pyLongAsLongAndOverflow, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { return pyLongAsLongAndOverflow.execute(frame, inliningTarget, object); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "Java long"); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "Java long"); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongCopy.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongCopy.java index 7c7698e273..b894177240 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongCopy.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongCopy.java @@ -40,12 +40,13 @@ */ package com.oracle.graal.python.lib; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.OverflowException; -import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; @@ -96,8 +97,8 @@ static long doPIntOverridenNarrowLong(PInt obj) throws OverflowException { @Specialization(guards = "!isBuiltinPInt(obj)", replaces = "doPIntOverridenNarrowLong") static PInt doPIntOverriden(PInt obj, - @Cached(inline = false) PythonObjectFactory factory) { - return factory.createInt(obj.getValue()); + @Bind PythonLanguage language) { + return PFactory.createInt(language, obj.getValue()); } @Specialization diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongFromDoubleNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongFromDoubleNode.java index f633950d5c..9ee63ec787 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongFromDoubleNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongFromDoubleNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,11 +47,13 @@ import java.math.BigInteger; import java.math.MathContext; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.MathGuards; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -83,18 +85,18 @@ static long doLong(double value) { @Specialization(guards = {"!fitLong(value)", "isFinite(value)"}) static Object doFinite(double value, - @Cached(inline = false) PythonObjectFactory factory) { - return factory.createInt(toBigInteger(value)); + @Bind PythonLanguage language) { + return PFactory.createInt(language, toBigInteger(value)); } @Specialization(guards = "!isFinite(value)") - static Object doInfinite(double value, - @Cached(inline = false) PRaiseNode raiseNode) { + static Object doInfinite(Node inliningTarget, double value, + @Cached PRaiseNode raiseNode) { if (Double.isNaN(value)) { - throw raiseNode.raise(ValueError, ErrorMessages.CANNOT_CONVERT_FLOAT_NAN_TO_INTEGER); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.CANNOT_CONVERT_FLOAT_NAN_TO_INTEGER); } assert Double.isInfinite(value); - throw raiseNode.raise(OverflowError, ErrorMessages.CANNOT_CONVERT_FLOAT_INFINITY_TO_INTEGER); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.CANNOT_CONVERT_FLOAT_INFINITY_TO_INTEGER); } @TruffleBoundary diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongFromUnicodeObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongFromUnicodeObject.java index c854537115..34f6d556eb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongFromUnicodeObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongFromUnicodeObject.java @@ -51,7 +51,7 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; @@ -127,40 +127,39 @@ static Object doGeneric(TruffleString numberTs, int base, byte[] originalBytes, @Cached InlinedBranchProfile invalidBase, @Cached InlinedBranchProfile notSimpleDecimalLiteralProfile, @Cached InlinedBranchProfile invalidValueProfile, - @Cached PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached StringNodes.StringReprNode stringReprNode, @Cached BytesNodes.BytesReprNode bytesReprNode) { String number = toJavaStringNode.execute(numberTs); if ((base != 0 && base < 2) || base > 36) { invalidBase.enter(inliningTarget); - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.INT_BASE_MUST_BE_2_AND_36_OR_0); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.INT_BASE_MUST_BE_2_AND_36_OR_0); } notSimpleDecimalLiteralProfile.enter(inliningTarget); PythonContext context = PythonContext.get(inliningTarget); - Object value = stringToIntInternal(number, base, context, factory); + Object value = stringToIntInternal(inliningTarget, number, base, context); if (value == null) { invalidValueProfile.enter(inliningTarget); Object repr; if (originalBytes == null) { repr = stringReprNode.execute(numberTs); } else { - repr = bytesReprNode.execute(inliningTarget, factory.createBytes(originalBytes, originalBytesLen)); + repr = bytesReprNode.execute(inliningTarget, PFactory.createBytes(context.getLanguage(inliningTarget), originalBytes, originalBytesLen)); } - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.INVALID_LITERAL_FOR_INT_WITH_BASE, base, repr); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.INVALID_LITERAL_FOR_INT_WITH_BASE, base, repr); } return value; } @TruffleBoundary - private static Object stringToIntInternal(String num, int base, PythonContext context, PythonObjectFactory factory) { + private static Object stringToIntInternal(Node inliningTarget, String num, int base, PythonContext context) { try { - BigInteger bi = asciiToBigInteger(num, base, context); + BigInteger bi = asciiToBigInteger(inliningTarget, num, base, context); if (bi == null) { return null; } if (bi.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0 || bi.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0) { - return factory.createInt(bi); + return PFactory.createInt(context.getLanguage(), bi); } else { return bi.intValue(); } @@ -170,7 +169,7 @@ private static Object stringToIntInternal(String num, int base, PythonContext co } @TruffleBoundary - private static BigInteger asciiToBigInteger(String str, int possibleBase, PythonContext context) throws NumberFormatException { + private static BigInteger asciiToBigInteger(Node inliningTarget, String str, int possibleBase, PythonContext context) throws NumberFormatException { int base = possibleBase; int b = 0; int e = str.length(); @@ -240,7 +239,7 @@ private static BigInteger asciiToBigInteger(String str, int possibleBase, Python } s = s.replace("_", ""); - checkMaxDigits(context, s.length(), base); + checkMaxDigits(inliningTarget, context, s.length(), base); BigInteger bi; if (sign == '-') { @@ -255,11 +254,12 @@ private static BigInteger asciiToBigInteger(String str, int possibleBase, Python return bi; } - private static void checkMaxDigits(PythonContext context, int digits, int base) { + private static void checkMaxDigits(Node inliningTarget, PythonContext context, int digits, int base) { if (digits > SysModuleBuiltins.INT_MAX_STR_DIGITS_THRESHOLD && Integer.bitCount(base) != 1) { int maxDigits = context.getIntMaxStrDigits(); if (maxDigits > 0 && digits > maxDigits) { - throw PRaiseNode.getUncached().raise(PythonBuiltinClassType.ValueError, ErrorMessages.EXCEEDS_THE_LIMIT_FOR_INTEGER_STRING_CONVERSION_D, maxDigits, digits); + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.EXCEEDS_THE_LIMIT_FOR_INTEGER_STRING_CONVERSION_D, maxDigits, + digits); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMemoryViewFromObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMemoryViewFromObject.java index 2d02aa4da8..d9a2ae7cfe 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMemoryViewFromObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMemoryViewFromObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -64,7 +64,7 @@ import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.NativeByteSequenceStorage; import com.oracle.graal.python.util.BufferFormat; import com.oracle.truffle.api.CompilerDirectives; @@ -89,10 +89,10 @@ public abstract class PyMemoryViewFromObject extends PNodeWithContext { @Specialization static PMemoryView fromMemoryView(PMemoryView object, @Bind("this") Node inliningTarget, - @Shared @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { object.checkReleased(inliningTarget, raiseNode); - return factory.createMemoryView(PythonContext.get(inliningTarget), object.getLifecycleManager(), object.getBuffer(), object.getOwner(), object.getLength(), + PythonContext context = PythonContext.get(inliningTarget); + return PFactory.createMemoryView(context.getLanguage(inliningTarget), context, object.getLifecycleManager(), object.getBuffer(), object.getOwner(), object.getLength(), object.isReadOnly(), object.getItemSize(), object.getFormat(), object.getFormatString(), object.getDimensions(), object.getBufferPointer(), object.getOffset(), object.getBufferShape(), object.getBufferStrides(), object.getBufferSuboffsets(), object.getFlags()); @@ -110,7 +110,7 @@ static PMemoryView fromPickleBuffer(VirtualFrame frame, PPickleBuffer object, @Bind("this") Node inliningTarget, @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached PyMemoryViewFromObject recursive, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { /* * PickleBuffer is just a buffer proxy for other objects, including native objects or other * memoryviews, we need to process the delegate recursively. @@ -120,7 +120,7 @@ static PMemoryView fromPickleBuffer(VirtualFrame frame, PPickleBuffer object, owner = bufferLib.getOwner(object.getView()); } if (owner == null) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.OP_FORBIDDEN_ON_OBJECT, "PickleBuffer"); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.OP_FORBIDDEN_ON_OBJECT, "PickleBuffer"); } return recursive.execute(frame, owner); } @@ -137,16 +137,16 @@ static PMemoryView fromManaged(VirtualFrame frame, Object object, @Cached HiddenAttr.ReadNode readGetBufferNode, @Cached HiddenAttr.ReadNode readReleaseBufferNode, @Cached CallNode callNode, - @Shared @Cached PythonObjectFactory factory, @Cached MemoryViewNodes.InitFlagsNode initFlagsNode, @Cached TruffleString.CodePointLengthNode lengthNode, @Cached TruffleString.CodePointAtIndexNode atIndexNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { Object typeObj = getClassNode.execute(inliningTarget, object); assert typeObj instanceof PythonBuiltinClassType || typeObj instanceof PythonAbstractObject; PythonAbstractObject type; + PythonContext context = PythonContext.get(inliningTarget); if (isBuiltinClassTypeProfile.profile(inliningTarget, typeObj instanceof PythonBuiltinClassType)) { - type = PythonContext.get(inliningTarget).lookupType((PythonBuiltinClassType) typeObj); + type = context.lookupType((PythonBuiltinClassType) typeObj); } else { type = (PythonAbstractObject) typeObj; } @@ -179,16 +179,18 @@ static PMemoryView fromManaged(VirtualFrame frame, Object object, // TODO when Sulong allows exposing pointers as interop buffer, we can get rid of this Object pythonBuffer = NativeByteSequenceStorage.create(cBuffer.getBuf(), cBuffer.getLen(), cBuffer.getLen(), false); TruffleString format = cBuffer.getFormat(); - return factory.createMemoryView(PythonContext.get(inliningTarget), bufferLifecycleManager, pythonBuffer, cBuffer.getObj(), cBuffer.getLen(), cBuffer.isReadOnly(), cBuffer.getItemSize(), + return PFactory.createMemoryView(context.getLanguage(inliningTarget), context, bufferLifecycleManager, pythonBuffer, cBuffer.getObj(), cBuffer.getLen(), cBuffer.isReadOnly(), + cBuffer.getItemSize(), BufferFormat.forMemoryView(format, lengthNode, atIndexNode), format, cBuffer.getDims(), cBuffer.getBuf(), 0, shape, strides, suboffsets, flags); } else if (bufferAcquireLib.hasBuffer(object)) { // Managed object that implements PythonBufferAcquireLibrary Object buffer = bufferAcquireLib.acquire(object, BufferFlags.PyBUF_FULL_RO, frame, indirectCallData); - return factory.createMemoryViewForManagedObject(buffer, bufferLib.getOwner(buffer), bufferLib.getItemSize(buffer), bufferLib.getBufferLength(buffer), bufferLib.isReadonly(buffer), + return PFactory.createMemoryViewForManagedObject(context.getLanguage(inliningTarget), buffer, bufferLib.getOwner(buffer), bufferLib.getItemSize(buffer), bufferLib.getBufferLength(buffer), + bufferLib.isReadonly(buffer), bufferLib.getFormatString(buffer), lengthNode, atIndexNode); } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.MEMORYVIEW_A_BYTES_LIKE_OBJECT_REQUIRED_NOT_P, object); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MEMORYVIEW_A_BYTES_LIKE_OBJECT_REQUIRED_NOT_P, object); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAbsoluteNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAbsoluteNode.java index 8d33936398..9c634f5901 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAbsoluteNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAbsoluteNode.java @@ -92,13 +92,13 @@ static Object doObject(VirtualFrame frame, Object object, @Cached GetClassNode getClassNode, @Cached GetCachedTpSlotsNode getSlots, @Cached CallSlotUnaryNode callSlot, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object type = getClassNode.execute(inliningTarget, object); TpSlots slots = getSlots.execute(inliningTarget, type); if (slots.nb_absolute() != null) { return callSlot.execute(frame, inliningTarget, slots.nb_absolute(), object); } - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.BAD_OPERAND_FOR, "abs()", "", object); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BAD_OPERAND_FOR, "abs()", "", object); } @NeverDefault diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAddNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAddNode.java index 483757851e..efeb878f58 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAddNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAddNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,133 +40,70 @@ */ package com.oracle.graal.python.lib; +import static com.oracle.graal.python.lib.CallBinaryOpNode.raiseNotSupported; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ListGeneralizationNode; import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.CallSlotBinaryFuncNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; -import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberAddFastPathsBase; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; -import com.oracle.graal.python.nodes.expression.BinaryOpNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; -import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.UnexpectedResultException; import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.strings.TruffleString; -@GenerateInline(inlineByDefault = true) -public abstract class PyNumberAddNode extends BinaryOpNode { - public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object v, Object w); +@GenerateInline(false) +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberAddNode extends PyNumberAddFastPathsBase { - @Override - public final Object executeObject(VirtualFrame frame, Object left, Object right) { - return executeCached(frame, left, right); - } - - public final Object executeCached(VirtualFrame frame, Object v, Object w) { - return execute(frame, this, v, w); - } - - public abstract int executeInt(VirtualFrame frame, Node inliningTarget, int left, int right) throws UnexpectedResultException; - - public abstract double executeDouble(VirtualFrame frame, Node inliningTarget, double left, double right) throws UnexpectedResultException; - - /* - * All the following fast paths need to be kept in sync with the corresponding builtin functions - * in IntBuiltins, FloatBuiltins, ListBuiltins, ... - */ - - @Specialization(rewriteOn = ArithmeticException.class) - public static int add(int left, int right) { - return Math.addExact(left, right); - } - - @Specialization - public static long doIIOvf(int x, int y) { - return x + (long) y; - } - - @Specialization(rewriteOn = ArithmeticException.class) - public static long addLong(long left, long right) { - return Math.addExact(left, right); - } - - @Specialization - public static double doDD(double left, double right) { - return left + right; - } - - @Specialization - public static double doDL(double left, long right) { - return left + right; - } - - @Specialization - public static double doLD(long left, double right) { - return left + right; - } - - @Specialization - public static double doDI(double left, int right) { - return left + right; - } - - @Specialization - public static double doID(int left, double right) { - return left + right; - } - - @NeverDefault - protected static SequenceStorageNodes.ConcatNode createConcat() { - return SequenceStorageNodes.ConcatNode.create(ListGeneralizationNode::create); - } - - @Specialization - static PList doPList(Node inliningTarget, PList left, PList right, - @Exclusive @Cached GetClassNode getClassNode, - @Shared @Cached(value = "createConcat()", inline = false) SequenceStorageNodes.ConcatNode concatNode, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - SequenceStorage newStore = concatNode.execute(left.getSequenceStorage(), right.getSequenceStorage()); - return factory.createList(getClassNode.execute(inliningTarget, left), newStore); + @Specialization(guards = {"isBuiltinList(left)", "isBuiltinList(right)"}) + public static PList doPList(PList left, PList right, + @Bind PythonLanguage language, + @Bind Node inliningTarget, + @Shared @Cached SequenceStorageNodes.ConcatListOrTupleNode concatNode) { + SequenceStorage newStore = concatNode.execute(inliningTarget, left.getSequenceStorage(), right.getSequenceStorage()); + return PFactory.createList(language, newStore); } @Specialization(guards = {"isBuiltinTuple(left)", "isBuiltinTuple(right)"}) - static PTuple doTuple(Node inliningTarget, PTuple left, PTuple right, - @Shared @Cached(value = "createConcat()", inline = false) SequenceStorageNodes.ConcatNode concatNode, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - SequenceStorage concatenated = concatNode.execute(left.getSequenceStorage(), right.getSequenceStorage()); - return factory.createTuple(concatenated); + public static PTuple doTuple(PTuple left, PTuple right, + @Bind PythonLanguage language, + @Bind Node inliningTarget, + @Shared @Cached SequenceStorageNodes.ConcatListOrTupleNode concatNode) { + SequenceStorage concatenated = concatNode.execute(inliningTarget, left.getSequenceStorage(), right.getSequenceStorage()); + return PFactory.createTuple(language, concatenated); } @Specialization - static TruffleString doIt(TruffleString left, TruffleString right, + public static TruffleString doIt(TruffleString left, TruffleString right, @Cached(inline = false) TruffleString.ConcatNode concatNode) { return concatNode.execute(left, right, TS_ENCODING, false); } @Fallback - static Object doIt(VirtualFrame frame, Node inliningTarget, Object v, Object w, + public static Object doIt(VirtualFrame frame, Object v, Object w, + @Bind Node inliningTarget, @Exclusive @Cached GetClassNode getVClass, @Cached GetCachedTpSlotsNode getVSlots, @Cached GetCachedTpSlotsNode getWSlots, @@ -174,33 +111,28 @@ static Object doIt(VirtualFrame frame, Node inliningTarget, Object v, Object w, @Cached CallBinaryOp1Node callBinaryOp1Node, @Cached InlinedBranchProfile hasNbAddResult, @Cached CallSlotBinaryFuncNode callBinarySlotNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object classV = getVClass.execute(inliningTarget, v); Object classW = getWClass.execute(inliningTarget, w); TpSlots slotsV = getVSlots.execute(inliningTarget, classV); TpSlots slotsW = getWSlots.execute(inliningTarget, classW); - TpSlot slotV = slotsV.nb_add(); - TpSlot slotW = slotsW.nb_add(); - if (slotV != null || slotW != null) { - Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, BinaryOpSlot.NB_ADD); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - hasNbAddResult.enter(inliningTarget); - return result; - } + Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotsV, w, classW, slotsW, ReversibleSlot.NB_ADD); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + hasNbAddResult.enter(inliningTarget); + return result; } if (slotsV.sq_concat() != null) { return callBinarySlotNode.execute(frame, inliningTarget, slotsV.sq_concat(), v, w); } - return raiseNotSupported(inliningTarget, v, w, raiseNode); - } - - @InliningCutoff - private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, Lazy raiseNode) { - return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, "+", v, w); + return raiseNotSupported(inliningTarget, v, w, "+", raiseNode); } @NeverDefault public static PyNumberAddNode create() { return PyNumberAddNodeGen.create(); } + + public static PyNumberAddNode getUncached() { + return PyNumberAddNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAndNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAndNode.java index dbaef51dc7..0ad79e2a87 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAndNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAndNode.java @@ -40,75 +40,38 @@ */ package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; -import com.oracle.graal.python.nodes.expression.BinaryOpNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberAndFastPathsBase; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @GenerateInline(false) -public abstract class PyNumberAndNode extends BinaryOpNode { - public abstract Object execute(VirtualFrame frame, Object v, Object w); - - @Override - public final Object executeObject(VirtualFrame frame, Object left, Object right) { - return execute(frame, left, right); - } - - @Specialization - public static int op(int left, int right) { - return left & right; - } - - @Specialization - public static long op(long left, long right) { - return left & right; - } +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberAndNode extends PyNumberAndFastPathsBase { @Fallback @InliningCutoff public static Object doIt(VirtualFrame frame, Object v, Object w, @Bind Node inliningTarget, - @Cached GetClassNode getVClass, - @Cached GetCachedTpSlotsNode getVSlots, - @Cached GetCachedTpSlotsNode getWSlots, - @Cached GetClassNode getWClass, - @Cached CallBinaryOp1Node callBinaryOp1Node, - @Cached Lazy raiseNode) { - Object classV = getVClass.execute(inliningTarget, v); - Object classW = getWClass.execute(inliningTarget, w); - TpSlot slotV = getVSlots.execute(inliningTarget, classV).nb_and(); - TpSlot slotW = getWSlots.execute(inliningTarget, classW).nb_and(); - if (slotV != null || slotW != null) { - Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, BinaryOpSlot.NB_AND); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - } - return raiseNotSupported(inliningTarget, v, w, raiseNode); - } - - @InliningCutoff - private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, Lazy raiseNode) { - return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, "&", v, w); + @Cached CallBinaryOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, ReversibleSlot.NB_AND, "&"); } @NeverDefault public static PyNumberAndNode create() { return PyNumberAndNodeGen.create(); } + + public static PyNumberAndNode getUncached() { + return PyNumberAndNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAsSizeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAsSizeNode.java index 4f311bd2dd..e25f5d02e5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAsSizeNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberAsSizeNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -115,7 +115,7 @@ public final int executeExact(Frame frame, Node inliningTarget, Object object, P return execute(frame, inliningTarget, object, errorClass); } - protected abstract int execute(Frame frame, Node inliningTarget, Object object, Object errorClass); + public abstract int execute(Frame frame, Node inliningTarget, Object object, Object errorClass); @Specialization static int doInt(int object, @SuppressWarnings("unused") Object errorClass) { @@ -124,12 +124,12 @@ static int doInt(int object, @SuppressWarnings("unused") Object errorClass) { @Specialization public static int doLongExact(Node inliningTarget, long object, PythonBuiltinClassType errorClass, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { int converted = (int) object; if (object == converted) { return converted; } - throw raiseNode.get(inliningTarget).raise(errorClass, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, object); + throw raiseNode.raise(inliningTarget, errorClass, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, object); } @Specialization @@ -157,13 +157,13 @@ abstract static class PyNumberAsSizeObjectNode extends Node { static int doObjectExact(VirtualFrame frame, Object object, PythonBuiltinClassType errorClass, @Bind("this") Node inliningTarget, @Exclusive @Cached PyNumberIndexNode indexNode, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached CastToJavaIntExactNode cast) { Object index = indexNode.execute(frame, inliningTarget, object); try { return cast.execute(inliningTarget, index); } catch (PException pe) { - throw raiseNode.get(inliningTarget).raise(errorClass, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, object); + throw raiseNode.raise(inliningTarget, errorClass, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, object); } catch (CannotCastException cannotCastException) { throw CompilerDirectives.shouldNotReachHere("PyNumberIndexNode didn't return a python integer"); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberCheckNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberCheckNode.java index ad46f1b0f3..ef416998a8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberCheckNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberCheckNode.java @@ -42,7 +42,6 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.complex.PComplex; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; import com.oracle.graal.python.nodes.PNodeWithContext; @@ -51,7 +50,6 @@ import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -63,7 +61,6 @@ @GenerateUncached @GenerateInline @GenerateCached(false) -@ImportStatic(SpecialMethodSlot.class) public abstract class PyNumberCheckNode extends PNodeWithContext { public abstract boolean execute(Node inliningTarget, Object object); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberDivmodNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberDivmodNode.java index cbb830c858..0cc37fd903 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberDivmodNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberDivmodNode.java @@ -40,30 +40,23 @@ */ package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; import com.oracle.graal.python.nodes.expression.BinaryOpNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @GenerateInline(inlineByDefault = true) +@GenerateUncached public abstract class PyNumberDivmodNode extends BinaryOpNode { public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object v, Object w); @Override - public final Object executeObject(VirtualFrame frame, Object left, Object right) { + public final Object execute(VirtualFrame frame, Object left, Object right) { return executeCached(frame, left, right); } @@ -72,33 +65,17 @@ public final Object executeCached(VirtualFrame frame, Object v, Object w) { } @Specialization - static Object doIt(VirtualFrame frame, Node inliningTarget, Object v, Object w, - @Cached GetClassNode getVClass, - @Cached GetCachedTpSlotsNode getVSlots, - @Cached GetCachedTpSlotsNode getWSlots, - @Cached GetClassNode getWClass, - @Cached CallBinaryOp1Node callBinaryOp1Node, - @Cached Lazy raiseNode) { - Object classV = getVClass.execute(inliningTarget, v); - Object classW = getWClass.execute(inliningTarget, w); - TpSlot slotV = getVSlots.execute(inliningTarget, classV).nb_divmod(); - TpSlot slotW = getWSlots.execute(inliningTarget, classW).nb_divmod(); - if (slotV != null || slotW != null) { - Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, BinaryOpSlot.NB_DIVMOD); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - } - return raiseNotSupported(inliningTarget, v, w, raiseNode); - } - - @InliningCutoff - private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, Lazy raiseNode) { - return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, "divmod()", v, w); + public static Object doIt(VirtualFrame frame, Node inliningTarget, Object v, Object w, + @Cached CallBinaryOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, ReversibleSlot.NB_DIVMOD, "divmod()"); } @NeverDefault public static PyNumberDivmodNode create() { return PyNumberDivmodNodeGen.create(); } + + public static PyNumberDivmodNode getUncached() { + return PyNumberDivmodNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberFloorDivideNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberFloorDivideNode.java index 29e1cda87a..710904e665 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberFloorDivideNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberFloorDivideNode.java @@ -40,103 +40,36 @@ */ package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; -import com.oracle.graal.python.nodes.expression.BinaryOpNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.util.OverflowException; -import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberFloorDivideFastPathsBase; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @GenerateInline(false) -public abstract class PyNumberFloorDivideNode extends BinaryOpNode { - public abstract Object execute(VirtualFrame frame, Object v, Object w); - - @Override - public final Object executeObject(VirtualFrame frame, Object left, Object right) { - return execute(frame, left, right); - } - - /* - * All the following fast paths need to be kept in sync with the corresponding builtin functions - * in IntBuiltins, FloatBuiltins, ... - */ - @Specialization(rewriteOn = OverflowException.class) - public static int doII(int left, int right) throws OverflowException { - if (right == 0 || (left == Integer.MIN_VALUE && right == -1)) { - throw OverflowException.INSTANCE; - } - return Math.floorDiv(left, right); - } - - @Specialization(rewriteOn = OverflowException.class) - public static long doLL(long left, long right) throws OverflowException { - if (right == 0 || (left == Long.MIN_VALUE && right == -1)) { - throw OverflowException.INSTANCE; - } - return Math.floorDiv(left, right); - } - - @Specialization(rewriteOn = OverflowException.class) - public static double doID(int left, double right) throws OverflowException { - return doDD(left, right); - } - - @Specialization(rewriteOn = OverflowException.class) - public static double doDI(double left, int right) throws OverflowException { - return doDD(left, right); - } - - @Specialization(rewriteOn = OverflowException.class) - public static double doDD(double left, double right) throws OverflowException { - if (right == 0.0) { - throw OverflowException.INSTANCE; - } - return Math.floor(left / right); - } +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberFloorDivideNode extends PyNumberFloorDivideFastPathsBase { @Fallback public static Object doIt(VirtualFrame frame, Object v, Object w, @Bind Node inliningTarget, - @Cached GetClassNode getVClass, - @Cached GetCachedTpSlotsNode getVSlots, - @Cached GetCachedTpSlotsNode getWSlots, - @Cached GetClassNode getWClass, - @Cached CallBinaryOp1Node callBinaryOp1Node, - @Cached Lazy raiseNode) { - Object classV = getVClass.execute(inliningTarget, v); - Object classW = getWClass.execute(inliningTarget, w); - TpSlot slotV = getVSlots.execute(inliningTarget, classV).nb_floor_divide(); - TpSlot slotW = getWSlots.execute(inliningTarget, classW).nb_floor_divide(); - if (slotV != null || slotW != null) { - Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, BinaryOpSlot.NB_FLOOR_DIVIDE); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - } - return raiseNotSupported(inliningTarget, v, w, raiseNode); - } - - @InliningCutoff - private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, Lazy raiseNode) { - return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, "//", v, w); + @Cached CallBinaryOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, ReversibleSlot.NB_FLOOR_DIVIDE, "//"); } @NeverDefault public static PyNumberFloorDivideNode create() { return PyNumberFloorDivideNodeGen.create(); } + + public static PyNumberFloorDivideNode getUncached() { + return PyNumberFloorDivideNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceAddNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceAddNode.java new file mode 100644 index 0000000000..c700c6ef4d --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceAddNode.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import static com.oracle.graal.python.lib.CallBinaryOpNode.raiseNotSupported; + +import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.CallSlotBinaryFuncNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberAddFastPathsBase; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Cached.Exclusive; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; + +@GenerateInline(false) +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberInPlaceAddNode extends PyNumberAddFastPathsBase { + + @Fallback + @InliningCutoff + public static Object doIt(VirtualFrame frame, Object v, Object w, + @Bind Node inliningTarget, + @Exclusive @Cached GetClassNode getVClass, + @Cached GetCachedTpSlotsNode getVSlots, + @Cached GetCachedTpSlotsNode getWSlots, + @Exclusive @Cached GetClassNode getWClass, + @Cached CallBinaryIOp1Node callBinaryIOp1Node, + @Cached InlinedBranchProfile hasNbAddResult, + @Cached InlinedBranchProfile hasInplaceConcat, + @Cached InlinedBranchProfile hasConcat, + @Cached CallSlotBinaryFuncNode callBinarySlotNode, + @Cached PRaiseNode raiseNode) { + Object classV = getVClass.execute(inliningTarget, v); + Object classW = getWClass.execute(inliningTarget, w); + TpSlots slotsV = getVSlots.execute(inliningTarget, classV); + TpSlots slotsW = getWSlots.execute(inliningTarget, classW); + Object result = callBinaryIOp1Node.execute(frame, inliningTarget, v, classV, slotsV, w, classW, slotsW, InplaceSlot.NB_INPLACE_ADD); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + hasNbAddResult.enter(inliningTarget); + return result; + } + TpSlot concatSlot; + if (slotsV.sq_inplace_concat() != null) { + hasInplaceConcat.enter(inliningTarget); + concatSlot = slotsV.sq_inplace_concat(); + } else if (slotsV.sq_concat() != null) { + hasConcat.enter(inliningTarget); + concatSlot = slotsV.sq_concat(); + } else { + return raiseNotSupported(inliningTarget, v, w, "+=", raiseNode); + } + return callBinarySlotNode.execute(frame, inliningTarget, concatSlot, v, w); + } + + @NeverDefault + public static PyNumberInPlaceAddNode create() { + return PyNumberInPlaceAddNodeGen.create(); + } + + public static PyNumberInPlaceAddNode getUncached() { + return PyNumberInPlaceAddNodeGen.getUncached(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceAndNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceAndNode.java new file mode 100644 index 0000000000..25f56faf46 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceAndNode.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberAndFastPathsBase; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; + +@GenerateInline(false) +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberInPlaceAndNode extends PyNumberAndFastPathsBase { + @Fallback + @InliningCutoff + public static Object doIt(VirtualFrame frame, Object v, Object w, + @Bind Node inliningTarget, + @Cached CallBinaryIOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, InplaceSlot.NB_INPLACE_AND, "&="); + } + + @NeverDefault + public static PyNumberInPlaceAndNode create() { + return PyNumberInPlaceAndNodeGen.create(); + } + + public static PyNumberInPlaceAndNode getUncached() { + return PyNumberInPlaceAndNodeGen.getUncached(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceFloorDivideNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceFloorDivideNode.java new file mode 100644 index 0000000000..b0eb213ec5 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceFloorDivideNode.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberFloorDivideFastPathsBase; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; + +@GenerateInline(false) +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberInPlaceFloorDivideNode extends PyNumberFloorDivideFastPathsBase { + @Fallback + @InliningCutoff + public static Object doIt(VirtualFrame frame, Object v, Object w, + @Bind Node inliningTarget, + @Cached CallBinaryIOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, InplaceSlot.NB_INPLACE_FLOOR_DIVIDE, "//="); + } + + @NeverDefault + public static PyNumberInPlaceFloorDivideNode create() { + return PyNumberInPlaceFloorDivideNodeGen.create(); + } + + public static PyNumberInPlaceFloorDivideNode getUncached() { + return PyNumberInPlaceFloorDivideNodeGen.getUncached(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/release_callback/ArrowSchemaReleaseCallbackNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceLshiftNode.java similarity index 62% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/release_callback/ArrowSchemaReleaseCallbackNode.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceLshiftNode.java index c7063bc21a..9ede290b1f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/release_callback/ArrowSchemaReleaseCallbackNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceLshiftNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,41 +38,38 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.nodes.arrow.release_callback; +package com.oracle.graal.python.lib; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.arrow.ArrowSchema; -import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; -import static com.oracle.graal.python.nodes.ErrorMessages.ARROW_SCHEMA_ALREADY_RELEASED; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; - -@GenerateCached(false) -@GenerateInline +// TODO: should inherit from PyNumberLshiftFastPathsBase, blocked by GR-64005 +@GenerateInline(false) @GenerateUncached -public abstract class ArrowSchemaReleaseCallbackNode extends Node { - - public abstract void execute(Node inliningTarget, ArrowSchema arrowSchema); +@OperationProxy.Proxyable +public abstract class PyNumberInPlaceLshiftNode extends BinaryOpNode { + @Specialization // (replaces = {"doII", "doLL"}) + public static Object doIt(VirtualFrame frame, Object v, Object w, + @Bind Node inliningTarget, + @Cached CallBinaryIOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, InplaceSlot.NB_INPLACE_LSHIFT, "<<="); + } - @Specialization - static void release(Node inliningTarget, ArrowSchema arrowSchema, - @Cached PRaiseNode.Lazy raiseNode) { - if (arrowSchema.isReleased()) { - throw raiseNode.get(inliningTarget).raise(ValueError, ARROW_SCHEMA_ALREADY_RELEASED); - } - var unsafe = PythonContext.get(inliningTarget).getUnsafe(); - /* - * Releasing only format since that's the only thing we create during the creation of - * ArrowSchema. See VectorToArrowSchemaNode - */ - unsafe.freeMemory(arrowSchema.getFormat()); - arrowSchema.markRelease(); + @NeverDefault + public static PyNumberInPlaceLshiftNode create() { + return PyNumberInPlaceLshiftNodeGen.create(); } + public static PyNumberInPlaceLshiftNode getUncached() { + return PyNumberInPlaceLshiftNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/GraalHPyLLVMCallHelperFunctionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceMatrixMultiplyNode.java similarity index 67% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/GraalHPyLLVMCallHelperFunctionNode.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceMatrixMultiplyNode.java index 0122356b89..76f26e8e4b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/llvm/GraalHPyLLVMCallHelperFunctionNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceMatrixMultiplyNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,32 +38,37 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.builtins.objects.cext.hpy.llvm; +package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNativeSymbol; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyCallHelperFunctionNode; -import com.oracle.graal.python.builtins.objects.cext.hpy.llvm.GraalHPyLLVMNodes.HPyLLVMCallHelperFunctionNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; -/** - * This is the implementation of {@link HPyCallHelperFunctionNode} for the LLVM backend. This node - * currently just delegates to {@link HPyLLVMCallHelperFunctionNode} but this may change in the - * future. - */ -@GenerateUncached @GenerateInline(false) -abstract class GraalHPyLLVMCallHelperFunctionNode extends HPyCallHelperFunctionNode { - +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberInPlaceMatrixMultiplyNode extends BinaryOpNode { @Specialization - static Object doGeneric(GraalHPyContext context, GraalHPyNativeSymbol name, Object[] args, - @Bind("this") Node inliningTarget, - @Cached HPyLLVMCallHelperFunctionNode callHPyFunction) { - return callHPyFunction.execute(inliningTarget, context, name, args); + public static Object doIt(VirtualFrame frame, Object v, Object w, + @Bind Node inliningTarget, + @Cached CallBinaryIOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, InplaceSlot.NB_INPLACE_MATRIX_MULTIPLY, "@="); + } + + @NeverDefault + public static PyNumberInPlaceMatrixMultiplyNode create() { + return PyNumberInPlaceMatrixMultiplyNodeGen.create(); + } + + public static PyNumberInPlaceMatrixMultiplyNode getUncached() { + return PyNumberInPlaceMatrixMultiplyNodeGen.getUncached(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceMultiplyNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceMultiplyNode.java new file mode 100644 index 0000000000..aa0b005f2c --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceMultiplyNode.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import static com.oracle.graal.python.lib.CallBinaryOpNode.raiseNotSupported; + +import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberMultiplyFastPathsBase; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Cached.Exclusive; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; + +@GenerateInline(false) +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberInPlaceMultiplyNode extends PyNumberMultiplyFastPathsBase { + + @Fallback + @InliningCutoff + public static Object doIt(VirtualFrame frame, Object v, Object w, + @Bind Node inliningTarget, + @Exclusive @Cached GetClassNode getVClass, + @Cached GetCachedTpSlotsNode getVSlots, + @Cached GetCachedTpSlotsNode getWSlots, + @Exclusive @Cached GetClassNode getWClass, + @Cached CallBinaryIOp1Node callBinaryIOp1Node, + @Cached InlinedBranchProfile hasNbMultiplyResult, + @Cached InlinedBranchProfile hasInplaceRepeat, + @Cached InlinedBranchProfile hasRepeat, + @Cached InlinedBranchProfile wHasRepeat, + @Cached SequenceRepeatHelperNode sequenceRepeatNode, + @Cached PRaiseNode raiseNode) { + Object classV = getVClass.execute(inliningTarget, v); + Object classW = getWClass.execute(inliningTarget, w); + TpSlots slotsV = getVSlots.execute(inliningTarget, classV); + TpSlots slotsW = getWSlots.execute(inliningTarget, classW); + Object result = callBinaryIOp1Node.execute(frame, inliningTarget, v, classV, slotsV, w, classW, slotsW, InplaceSlot.NB_INPLACE_MULTIPLY); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + hasNbMultiplyResult.enter(inliningTarget); + return result; + } + if (slotsV.has_as_sequence()) { + TpSlot repeatSlot = null; + if (slotsV.sq_inplace_repeat() != null) { + hasInplaceRepeat.enter(inliningTarget); + repeatSlot = slotsV.sq_inplace_repeat(); + } else if (slotsV.sq_repeat() != null) { + hasRepeat.enter(inliningTarget); + repeatSlot = slotsV.sq_repeat(); + } + if (repeatSlot != null) { + return sequenceRepeatNode.execute(frame, repeatSlot, v, w); + } + } else if (slotsW.has_as_sequence()) { + /* + * Note that the right hand operand should not be mutated in this case so + * sq_inplace_repeat is not used. + */ + if (slotsW.sq_repeat() != null) { + wHasRepeat.enter(inliningTarget); + return sequenceRepeatNode.execute(frame, slotsW.sq_repeat(), w, v); + } + } + return raiseNotSupported(inliningTarget, v, w, "*=", raiseNode); + } + + @NeverDefault + public static PyNumberInPlaceMultiplyNode create() { + return PyNumberInPlaceMultiplyNodeGen.create(); + } + + public static PyNumberInPlaceMultiplyNode getUncached() { + return PyNumberInPlaceMultiplyNodeGen.getUncached(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceOrNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceOrNode.java new file mode 100644 index 0000000000..28edd9a3d5 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceOrNode.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberOrFastPathsBase; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; + +@GenerateInline(false) +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberInPlaceOrNode extends PyNumberOrFastPathsBase { + @Fallback + @InliningCutoff + public static Object doIt(VirtualFrame frame, Object v, Object w, + @Bind Node inliningTarget, + @Cached CallBinaryIOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, InplaceSlot.NB_INPLACE_OR, "|="); + } + + @NeverDefault + public static PyNumberInPlaceOrNode create() { + return PyNumberInPlaceOrNodeGen.create(); + } + + public static PyNumberInPlaceOrNode getUncached() { + return PyNumberInPlaceOrNodeGen.getUncached(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallVarargsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlacePowerNode.java similarity index 50% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallVarargsNode.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlacePowerNode.java index 56bdeab352..def6460240 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallVarargsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlacePowerNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,53 +38,65 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.nodes.call.special; +package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.ReportPolymorphism.Megamorphic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.strings.TruffleString; -public abstract class LookupAndCallVarargsNode extends Node { - protected final TruffleString name; +@GenerateInline(false) +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberInPlacePowerNode extends BinaryOpNode { - public abstract Object execute(VirtualFrame frame, Object callable, Object[] arguments); + public abstract Object execute(VirtualFrame frame, Object v, Object w, Object z); - @NeverDefault - public static LookupAndCallVarargsNode create(TruffleString name) { - return LookupAndCallVarargsNodeGen.create(name); + @Override + public final Object execute(VirtualFrame frame, Object left, Object right) { + return execute(frame, left, right, PNone.NONE); } - LookupAndCallVarargsNode(TruffleString name) { - this.name = name; + @Specialization + public static Object doIt(VirtualFrame frame, Object v, Object w, Object z, + @Bind Node inliningTarget, + @Cached CallTernaryIOpNode callTernaryOpNode, + @Cached PRaiseNode raiseNode) { + Object result = callTernaryOpNode.execute(frame, inliningTarget, v, w, z); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + return result; + } + return raiseNotSupported(inliningTarget, v, w, z, raiseNode); } - @Specialization(guards = {"callable.getClass() == cachedClass"}, limit = "3") - static Object callObject(VirtualFrame frame, Object callable, Object[] arguments, - @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached("callable.getClass()") Class cachedClass, - @Shared @Cached GetClassNode getClassNode, - @Shared @Cached("create(name)") LookupSpecialMethodNode getattr, - @Shared @Cached CallVarargsMethodNode dispatchNode) { - return dispatchNode.execute(frame, getattr.execute(frame, getClassNode.execute(inliningTarget, callable), callable), arguments, PKeyword.EMPTY_KEYWORDS); + @InliningCutoff + private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, Object z, PRaiseNode raiseNode) { + if (z == PNone.NONE) { + return raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, "**=", v, w); + } else { + return raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_P_P, "**=", v, w, z); + } } - @Specialization(replaces = "callObject") - @InliningCutoff - @Megamorphic - static Object callObjectMegamorphic(VirtualFrame frame, Object callable, Object[] arguments, - @Bind("this") Node inliningTarget, - @Shared @Cached GetClassNode getClassNode, - @Shared @Cached("create(name)") LookupSpecialMethodNode getattr, - @Shared @Cached CallVarargsMethodNode dispatchNode) { - return dispatchNode.execute(frame, getattr.execute(frame, getClassNode.execute(inliningTarget, callable), callable), arguments, PKeyword.EMPTY_KEYWORDS); + @NeverDefault + public static PyNumberInPlacePowerNode create() { + return PyNumberInPlacePowerNodeGen.create(); + } + + public static PyNumberInPlacePowerNode getUncached() { + return PyNumberInPlacePowerNodeGen.getUncached(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceRemainderNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceRemainderNode.java new file mode 100644 index 0000000000..19c3df7d0e --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceRemainderNode.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberRemainderFastPathsBase; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; + +@GenerateInline(false) +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberInPlaceRemainderNode extends PyNumberRemainderFastPathsBase { + @Fallback + @InliningCutoff + public static Object doIt(VirtualFrame frame, Object v, Object w, + @Bind Node inliningTarget, + @Cached CallBinaryIOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, InplaceSlot.NB_INPLACE_REMAINDER, "%="); + } + + @NeverDefault + public static PyNumberInPlaceRemainderNode create() { + return PyNumberInPlaceRemainderNodeGen.create(); + } + + public static PyNumberInPlaceRemainderNode getUncached() { + return PyNumberInPlaceRemainderNodeGen.getUncached(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceRshiftNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceRshiftNode.java new file mode 100644 index 0000000000..3e961b7892 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceRshiftNode.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberRshiftFastPathsBase; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; + +@GenerateInline(false) +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberInPlaceRshiftNode extends PyNumberRshiftFastPathsBase { + @Fallback + @InliningCutoff + public static Object doIt(VirtualFrame frame, Object v, Object w, + @Bind Node inliningTarget, + @Cached CallBinaryIOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, InplaceSlot.NB_INPLACE_RSHIFT, ">>="); + } + + @NeverDefault + public static PyNumberInPlaceRshiftNode create() { + return PyNumberInPlaceRshiftNodeGen.create(); + } + + public static PyNumberInPlaceRshiftNode getUncached() { + return PyNumberInPlaceRshiftNodeGen.getUncached(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceSubtractNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceSubtractNode.java new file mode 100644 index 0000000000..c8e642dba0 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceSubtractNode.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberSubtractFastPathsBase; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; + +@GenerateInline(false) +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberInPlaceSubtractNode extends PyNumberSubtractFastPathsBase { + @Fallback + @InliningCutoff + public static Object doIt(VirtualFrame frame, Object v, Object w, + @Bind Node inliningTarget, + @Cached CallBinaryIOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, InplaceSlot.NB_INPLACE_SUBTRACT, "-="); + } + + @NeverDefault + public static PyNumberInPlaceSubtractNode create() { + return PyNumberInPlaceSubtractNodeGen.create(); + } + + public static PyNumberInPlaceSubtractNode getUncached() { + return PyNumberInPlaceSubtractNodeGen.getUncached(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceTrueDivideNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceTrueDivideNode.java new file mode 100644 index 0000000000..423ea1a51b --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceTrueDivideNode.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberTrueDivideFastPathsBase; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; + +@GenerateInline(false) +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberInPlaceTrueDivideNode extends PyNumberTrueDivideFastPathsBase { + @Fallback + @InliningCutoff + public static Object doIt(VirtualFrame frame, Object v, Object w, + @Bind Node inliningTarget, + @Cached CallBinaryIOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, InplaceSlot.NB_INPLACE_TRUE_DIVIDE, "/="); + } + + @NeverDefault + public static PyNumberInPlaceTrueDivideNode create() { + return PyNumberInPlaceTrueDivideNodeGen.create(); + } + + public static PyNumberInPlaceTrueDivideNode getUncached() { + return PyNumberInPlaceTrueDivideNodeGen.getUncached(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceXorNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceXorNode.java new file mode 100644 index 0000000000..c2665ccf1c --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInPlaceXorNode.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberXorFastPathsBase; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; + +@GenerateInline(false) +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberInPlaceXorNode extends PyNumberXorFastPathsBase { + @Fallback + @InliningCutoff + public static Object doIt(VirtualFrame frame, Object v, Object w, + @Bind Node inliningTarget, + @Cached CallBinaryIOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, InplaceSlot.NB_INPLACE_XOR, "^="); + } + + @NeverDefault + public static PyNumberInPlaceXorNode create() { + return PyNumberInPlaceXorNodeGen.create(); + } + + public static PyNumberInPlaceXorNode getUncached() { + return PyNumberInPlaceXorNodeGen.getUncached(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberIndexNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberIndexNode.java index 718c2a9d06..96b8dcd0f4 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberIndexNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberIndexNode.java @@ -104,7 +104,7 @@ static Object doCallIndex(VirtualFrame frame, Node inliningTarget, Object object @Cached TpSlots.GetCachedTpSlotsNode getSlots, @Cached CallSlotUnaryNode callIndex, @Cached(inline = false) IsSubtypeNode isSubtype, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached PyLongCheckExactNode checkNode, @Cached CheckIndexResultNotInt checkResult, @Cached PyLongCopy copy) { @@ -114,7 +114,7 @@ static Object doCallIndex(VirtualFrame frame, Node inliningTarget, Object object } TpSlots slots = getSlots.execute(inliningTarget, type); if (slots.nb_index() == null) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, object); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, object); } Object result = callIndex.execute(frame, inliningTarget, slots.nb_index(), object); if (checkNode.execute(inliningTarget, result)) { @@ -138,11 +138,11 @@ static Object doGeneric(VirtualFrame frame, Object original, Object result, @Bind("this") Node inliningTarget, @Cached GetClassNode getClassNode, @Cached IsSubtypeNode isSubtype, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached WarningsModuleBuiltins.WarnNode warnNode, @Cached PyLongCopy copy) { if (!isSubtype.execute(getClassNode.execute(inliningTarget, result), PythonBuiltinClassType.PInt)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.INDEX_RETURNED_NON_INT, result); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.INDEX_RETURNED_NON_INT, result); } warnNode.warnFormat(frame, null, DeprecationWarning, 1, ErrorMessages.WARN_P_RETURNED_NON_P, original, T___INDEX__, "int", result, "int"); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInvertNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInvertNode.java index e46d1003e8..fd35b6dddb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInvertNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberInvertNode.java @@ -49,6 +49,7 @@ import com.oracle.graal.python.nodes.expression.UnaryOpNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; @@ -61,6 +62,7 @@ @GenerateUncached @GenerateInline(false) +@OperationProxy.Proxyable public abstract class PyNumberInvertNode extends UnaryOpNode { @Specialization @@ -80,17 +82,21 @@ public static Object doObject(VirtualFrame frame, Object object, @Cached GetClassNode getClassNode, @Cached GetCachedTpSlotsNode getSlots, @Cached CallSlotUnaryNode callSlot, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object type = getClassNode.execute(inliningTarget, object); TpSlots slots = getSlots.execute(inliningTarget, type); if (slots.nb_invert() != null) { return callSlot.execute(frame, inliningTarget, slots.nb_invert(), object); } - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.BAD_OPERAND_FOR, "unary", "~", object); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BAD_OPERAND_FOR, "unary", "~", object); } @NeverDefault public static PyNumberInvertNode create() { return PyNumberInvertNodeGen.create(); } + + public static PyNumberInvertNode getUncached() { + return PyNumberInvertNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberLongNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberLongNode.java index 2b10b32afb..7023f671ae 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberLongNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberLongNode.java @@ -166,11 +166,11 @@ static Object doGeneric(VirtualFrame frame, Object original, Object result, @Bind("this") Node inliningTarget, @Cached GetClassNode getClassNode, @Cached IsSubtypeNode isSubtype, - @Cached PRaiseNode.Lazy raiseNode, + @Cached PRaiseNode raiseNode, @Cached WarningsModuleBuiltins.WarnNode warnNode, @Cached PyLongCopy copy) { if (!isSubtype.execute(getClassNode.execute(inliningTarget, result), PythonBuiltinClassType.PInt)) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.RETURNED_NON_INT, J___INT__, result); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.RETURNED_NON_INT, J___INT__, result); } warnNode.warnFormat(frame, null, PythonBuiltinClassType.DeprecationWarning, 1, ErrorMessages.WARN_P_RETURNED_NON_P, original, J___INT__, "int", result, "int"); @@ -199,7 +199,7 @@ static Object doGeneric(VirtualFrame frame, Object object, @Cached PyUnicodeCheckNode unicodeCheckNode, @Cached PyLongFromUnicodeObject fromUnicodeObject, @Cached LongFromBufferNode fromBufferNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object type = getClassNode.execute(inliningTarget, object); Object truncMethod = lookup.execute(type, T___TRUNC__); if (truncMethod != PNone.NO_VALUE) { @@ -214,7 +214,7 @@ static Object doGeneric(VirtualFrame frame, Object object, return longCopy.execute(inliningTarget, result); } if (!indexCheckNode.execute(inliningTarget, result)) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.RETURNED_NON_INTEGRAL, J___TRUNC__, result); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.RETURNED_NON_INTEGRAL, J___TRUNC__, result); } return indexNode.execute(frame, inliningTarget, result); } @@ -228,7 +228,7 @@ static Object doGeneric(VirtualFrame frame, Object object, return result; } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.ARG_MUST_BE_STRING_OR_BYTELIKE_OR_NUMBER, "int()", object); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ARG_MUST_BE_STRING_OR_BYTELIKE_OR_NUMBER, "int()", object); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberLshiftNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberLshiftNode.java index 82ce4248ae..df9e53e00f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberLshiftNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberLshiftNode.java @@ -40,83 +40,37 @@ */ package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; import com.oracle.graal.python.nodes.expression.BinaryOpNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.util.OverflowException; -import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +// TODO: should inherit from PyNumberLshiftFastPathsBase, blocked by GR-64005 @GenerateInline(false) +@GenerateUncached +@OperationProxy.Proxyable public abstract class PyNumberLshiftNode extends BinaryOpNode { - public abstract Object execute(VirtualFrame frame, Object v, Object w); - @Override - public final Object executeObject(VirtualFrame frame, Object left, Object right) { - return execute(frame, left, right); - } - - @Specialization(guards = {"right < 32", "right >= 0"}, rewriteOn = OverflowException.class) - public static int doII(int left, int right) throws OverflowException { - int result = left << right; - if (left != result >> right) { - throw OverflowException.INSTANCE; - } - return result; - } - - @Specialization(guards = {"right < 64", "right >= 0"}, rewriteOn = OverflowException.class) - public static long doLL(long left, long right) throws OverflowException { - long result = left << right; - if (left != result >> right) { - throw OverflowException.INSTANCE; - } - return result; - } - - @Fallback + @Specialization // (replaces = {"doII", "doLL"}) public static Object doIt(VirtualFrame frame, Object v, Object w, @Bind Node inliningTarget, - @Cached GetClassNode getVClass, - @Cached GetCachedTpSlotsNode getVSlots, - @Cached GetCachedTpSlotsNode getWSlots, - @Cached GetClassNode getWClass, - @Cached CallBinaryOp1Node callBinaryOp1Node, - @Cached Lazy raiseNode) { - Object classV = getVClass.execute(inliningTarget, v); - Object classW = getWClass.execute(inliningTarget, w); - TpSlot slotV = getVSlots.execute(inliningTarget, classV).nb_lshift(); - TpSlot slotW = getWSlots.execute(inliningTarget, classW).nb_lshift(); - if (slotV != null || slotW != null) { - Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, BinaryOpSlot.NB_LSHIFT); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - } - return raiseNotSupported(inliningTarget, v, w, raiseNode); - } - - @InliningCutoff - private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, Lazy raiseNode) { - return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, "<<", v, w); + @Cached CallBinaryOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, ReversibleSlot.NB_LSHIFT, "<<"); } @NeverDefault public static PyNumberLshiftNode create() { return PyNumberLshiftNodeGen.create(); } + + public static PyNumberLshiftNode getUncached() { + return PyNumberLshiftNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberMatrixMultiplyNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberMatrixMultiplyNode.java index fe1bcffd5e..bdc6dbfbe7 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberMatrixMultiplyNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberMatrixMultiplyNode.java @@ -40,63 +40,36 @@ */ package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; import com.oracle.graal.python.nodes.expression.BinaryOpNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @GenerateInline(false) +@OperationProxy.Proxyable +@GenerateUncached public abstract class PyNumberMatrixMultiplyNode extends BinaryOpNode { - public abstract Object execute(VirtualFrame frame, Object v, Object w); - - @Override - public final Object executeObject(VirtualFrame frame, Object left, Object right) { - return execute(frame, left, right); - } @Specialization public static Object doIt(VirtualFrame frame, Object v, Object w, @Bind Node inliningTarget, - @Cached GetClassNode getVClass, - @Cached GetCachedTpSlotsNode getVSlots, - @Cached GetCachedTpSlotsNode getWSlots, - @Cached GetClassNode getWClass, - @Cached CallBinaryOp1Node callBinaryOp1Node, - @Cached Lazy raiseNode) { - Object classV = getVClass.execute(inliningTarget, v); - Object classW = getWClass.execute(inliningTarget, w); - TpSlot slotV = getVSlots.execute(inliningTarget, classV).nb_matrix_multiply(); - TpSlot slotW = getWSlots.execute(inliningTarget, classW).nb_matrix_multiply(); - if (slotV != null || slotW != null) { - Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, BinaryOpSlot.NB_MATRIX_MULTIPLY); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - } - return raiseNotSupported(inliningTarget, v, w, raiseNode); - } - - @InliningCutoff - private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, Lazy raiseNode) { - return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, "@", v, w); + @Cached CallBinaryOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, ReversibleSlot.NB_MATRIX_MULTIPLY, "@"); } @NeverDefault public static PyNumberMatrixMultiplyNode create() { return PyNumberMatrixMultiplyNodeGen.create(); } + + public static PyNumberMatrixMultiplyNode getUncached() { + return PyNumberMatrixMultiplyNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberMultiplyNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberMultiplyNode.java index 2f58fa3bce..a7d60a4e5f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberMultiplyNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberMultiplyNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,85 +40,35 @@ */ package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import static com.oracle.graal.python.lib.CallBinaryOpNode.raiseNotSupported; + import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.CallSlotSizeArgFun; -import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberMultiplyFastPathsBase; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; -import com.oracle.graal.python.nodes.expression.BinaryOpNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.UnexpectedResultException; import com.oracle.truffle.api.profiles.InlinedBranchProfile; -@GenerateInline(inlineByDefault = true) -public abstract class PyNumberMultiplyNode extends BinaryOpNode { - public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object v, Object w); - - @Override - public final Object executeObject(VirtualFrame frame, Object left, Object right) { - return executeCached(frame, left, right); - } - - public final Object executeCached(VirtualFrame frame, Object v, Object w) { - return execute(frame, this, v, w); - } - - public abstract int executeInt(VirtualFrame frame, Node inliningTarget, int left, int right) throws UnexpectedResultException; - - public abstract double executeDouble(VirtualFrame frame, Node inliningTarget, double left, double right) throws UnexpectedResultException; - - /* - * All the following fast paths need to be kept in sync with the corresponding builtin functions - * in IntBuiltins, FloatBuiltins, ListBuiltins, ... - */ - - @Specialization(rewriteOn = ArithmeticException.class) - public static int doII(int x, int y) throws ArithmeticException { - return Math.multiplyExact(x, y); - } - - @Specialization(replaces = "doII") - public static long doIIL(int x, int y) { - return x * (long) y; - } - - @Specialization(rewriteOn = ArithmeticException.class) - public static long doLL(long x, long y) { - return Math.multiplyExact(x, y); - } - - @Specialization - public static double doDL(double left, long right) { - return left * right; - } - - @Specialization - public static double doLD(long left, double right) { - return left * right; - } - - @Specialization - public static double doDD(double left, double right) { - return left * right; - } +@GenerateInline(false) +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberMultiplyNode extends PyNumberMultiplyFastPathsBase { @Fallback - static Object doIt(VirtualFrame frame, Node inliningTarget, Object v, Object w, + public static Object doIt(VirtualFrame frame, Object v, Object w, + @Bind Node inliningTarget, @Exclusive @Cached GetClassNode getVClass, @Cached GetCachedTpSlotsNode getVSlots, @Cached GetCachedTpSlotsNode getWSlots, @@ -127,60 +77,33 @@ static Object doIt(VirtualFrame frame, Node inliningTarget, Object v, Object w, @Cached InlinedBranchProfile hasNbMulResult, @Cached InlinedBranchProfile vHasSqRepeat, @Cached InlinedBranchProfile wHasSqRepeat, - @Cached PyIndexCheckNode indexCheckNode, - @Cached PyNumberAsSizeNode asSizeNode, - @Cached CallSlotSizeArgFun callSlotNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached SequenceRepeatHelperNode sequenceRepeatNode, + @Cached PRaiseNode raiseNode) { Object classV = getVClass.execute(inliningTarget, v); Object classW = getWClass.execute(inliningTarget, w); TpSlots slotsV = getVSlots.execute(inliningTarget, classV); TpSlots slotsW = getWSlots.execute(inliningTarget, classW); - TpSlot slotV = slotsV.nb_multiply(); - TpSlot slotW = slotsW.nb_multiply(); - if (slotV != null || slotW != null) { - Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, BinaryOpSlot.NB_MULTIPLY); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - hasNbMulResult.enter(inliningTarget); - return result; - } + Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotsV, w, classW, slotsW, ReversibleSlot.NB_MULTIPLY); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + hasNbMulResult.enter(inliningTarget); + return result; } if (slotsV.sq_repeat() != null) { vHasSqRepeat.enter(inliningTarget); - return sequenceRepeat(frame, inliningTarget, slotsV.sq_repeat(), v, w, - indexCheckNode, asSizeNode, callSlotNode, raiseNode); + return sequenceRepeatNode.execute(frame, slotsV.sq_repeat(), v, w); } else if (slotsW.sq_repeat() != null) { wHasSqRepeat.enter(inliningTarget); - return sequenceRepeat(frame, inliningTarget, slotsW.sq_repeat(), w, v, - indexCheckNode, asSizeNode, callSlotNode, raiseNode); - } - return raiseNotSupported(inliningTarget, v, w, raiseNode); - } - - @InliningCutoff - private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, Lazy raiseNode) { - return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, "+", v, w); - } - - private static Object sequenceRepeat(VirtualFrame frame, Node inliningTarget, TpSlot slot, Object seq, Object n, - PyIndexCheckNode indexCheckNode, - PyNumberAsSizeNode asSizeNode, - CallSlotSizeArgFun callSlotNode, - PRaiseNode.Lazy raiseNode) { - if (indexCheckNode.execute(inliningTarget, n)) { - int count = asSizeNode.execute(frame, inliningTarget, n, PythonBuiltinClassType.OverflowError); - return callSlotNode.execute(frame, inliningTarget, slot, seq, count); - } else { - throw raiseNonIntSqMul(inliningTarget, n, raiseNode); + return sequenceRepeatNode.execute(frame, slotsW.sq_repeat(), w, v); } - } - - @InliningCutoff - private static PException raiseNonIntSqMul(Node inliningTarget, Object n, Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.CANT_MULTIPLY_SEQ_BY_NON_INT, n); + return raiseNotSupported(inliningTarget, v, w, "*", raiseNode); } @NeverDefault public static PyNumberMultiplyNode create() { return PyNumberMultiplyNodeGen.create(); } + + public static PyNumberMultiplyNode getUncached() { + return PyNumberMultiplyNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberNegativeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberNegativeNode.java index a11cae150f..399fe6c422 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberNegativeNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberNegativeNode.java @@ -49,6 +49,7 @@ import com.oracle.graal.python.nodes.expression.UnaryOpNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; @@ -61,6 +62,7 @@ @GenerateUncached @GenerateInline(false) +@OperationProxy.Proxyable public abstract class PyNumberNegativeNode extends UnaryOpNode { public static final int INT_MIN_VALUE = Integer.MIN_VALUE; @@ -93,17 +95,21 @@ public static Object doObject(VirtualFrame frame, Object object, @Cached GetClassNode getClassNode, @Cached GetCachedTpSlotsNode getSlots, @Cached CallSlotUnaryNode callSlot, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object type = getClassNode.execute(inliningTarget, object); TpSlots slots = getSlots.execute(inliningTarget, type); if (slots.nb_negative() != null) { return callSlot.execute(frame, inliningTarget, slots.nb_negative(), object); } - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.BAD_OPERAND_FOR, "unary", "-", object); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BAD_OPERAND_FOR, "unary", "-", object); } @NeverDefault public static PyNumberNegativeNode create() { return PyNumberNegativeNodeGen.create(); } + + public static PyNumberNegativeNode getUncached() { + return PyNumberNegativeNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberOrNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberOrNode.java index deba1bad16..a91292e253 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberOrNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberOrNode.java @@ -40,74 +40,38 @@ */ package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; -import com.oracle.graal.python.nodes.expression.BinaryOpNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberOrFastPathsBase; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @GenerateInline(false) -public abstract class PyNumberOrNode extends BinaryOpNode { - public abstract Object execute(VirtualFrame frame, Object v, Object w); - - @Override - public final Object executeObject(VirtualFrame frame, Object left, Object right) { - return execute(frame, left, right); - } - - @Specialization - public static int op(int left, int right) { - return left | right; - } - - @Specialization - public static long op(long left, long right) { - return left | right; - } +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberOrNode extends PyNumberOrFastPathsBase { @Fallback + @InliningCutoff public static Object doIt(VirtualFrame frame, Object v, Object w, @Bind Node inliningTarget, - @Cached GetClassNode getVClass, - @Cached GetCachedTpSlotsNode getVSlots, - @Cached GetCachedTpSlotsNode getWSlots, - @Cached GetClassNode getWClass, - @Cached CallBinaryOp1Node callBinaryOp1Node, - @Cached Lazy raiseNode) { - Object classV = getVClass.execute(inliningTarget, v); - Object classW = getWClass.execute(inliningTarget, w); - TpSlot slotV = getVSlots.execute(inliningTarget, classV).nb_or(); - TpSlot slotW = getWSlots.execute(inliningTarget, classW).nb_or(); - if (slotV != null || slotW != null) { - Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, BinaryOpSlot.NB_OR); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - } - return raiseNotSupported(inliningTarget, v, w, raiseNode); - } - - @InliningCutoff - private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, Lazy raiseNode) { - return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, "|", v, w); + @Cached CallBinaryOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, ReversibleSlot.NB_OR, "|"); } @NeverDefault public static PyNumberOrNode create() { return PyNumberOrNodeGen.create(); } + + public static PyNumberOrNode getUncached() { + return PyNumberOrNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberPositiveNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberPositiveNode.java index 9dee19a666..6689a5b541 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberPositiveNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberPositiveNode.java @@ -49,6 +49,7 @@ import com.oracle.graal.python.nodes.expression.UnaryOpNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; @@ -61,6 +62,7 @@ @GenerateUncached @GenerateInline(false) +@OperationProxy.Proxyable public abstract class PyNumberPositiveNode extends UnaryOpNode { @Specialization @@ -75,17 +77,21 @@ public static Object doObject(VirtualFrame frame, Object object, @Cached GetClassNode getClassNode, @Cached GetCachedTpSlotsNode getSlots, @Cached CallSlotUnaryNode callSlot, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object type = getClassNode.execute(inliningTarget, object); TpSlots slots = getSlots.execute(inliningTarget, type); if (slots.nb_positive() != null) { return callSlot.execute(frame, inliningTarget, slots.nb_positive(), object); } - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.BAD_OPERAND_FOR, "unary", "+", object); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BAD_OPERAND_FOR, "unary", "+", object); } @NeverDefault public static PyNumberPositiveNode create() { return PyNumberPositiveNodeGen.create(); } + + public static PyNumberPositiveNode getUncached() { + return PyNumberPositiveNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberPowerNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberPowerNode.java new file mode 100644 index 0000000000..2b7d4848b3 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberPowerNode.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; + +@GenerateInline(false) +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberPowerNode extends BinaryOpNode { + public abstract Object execute(VirtualFrame frame, Object v, Object w, Object z); + + @Override + public final Object execute(VirtualFrame frame, Object left, Object right) { + return execute(frame, left, right, PNone.NONE); + } + + @Specialization + public static Object doIt(VirtualFrame frame, Object v, Object w, Object z, + @Bind Node inliningTarget, + @Cached GetClassNode getVClass, + @Cached GetClassNode getWClass, + @Cached GetCachedTpSlotsNode getVSlots, + @Cached GetCachedTpSlotsNode getWSlots, + @Cached CallTernaryOpNode callTernaryOpNode, + @Cached PRaiseNode raiseNode) { + Object classV = getVClass.execute(inliningTarget, v); + Object classW = getWClass.execute(inliningTarget, w); + TpSlot slotV = getVSlots.execute(inliningTarget, classV).nb_power(); + TpSlot slotW = getWSlots.execute(inliningTarget, classW).nb_power(); + Object result = callTernaryOpNode.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, z); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + return result; + } + return raiseNotSupported(inliningTarget, v, w, z, raiseNode); + } + + @InliningCutoff + private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, Object z, PRaiseNode raiseNode) { + if (z == PNone.NONE) { + return raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, "** or pow()", v, w); + } else { + return raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_P_P, "** or pow()", v, w, z); + } + } + + @NeverDefault + public static PyNumberPowerNode create() { + return PyNumberPowerNodeGen.create(); + } + + public static PyNumberPowerNode getUncached() { + return PyNumberPowerNodeGen.getUncached(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberRemainderNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberRemainderNode.java index fdfb76ca64..88dee651ef 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberRemainderNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberRemainderNode.java @@ -40,80 +40,38 @@ */ package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.floats.FloatBuiltins; -import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; -import com.oracle.graal.python.nodes.expression.BinaryOpNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberRemainderFastPathsBase; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @GenerateInline(false) -public abstract class PyNumberRemainderNode extends BinaryOpNode { - public abstract Object execute(VirtualFrame frame, Object v, Object w); - - @Override - public final Object executeObject(VirtualFrame frame, Object left, Object right) { - return execute(frame, left, right); - } - - @Specialization(rewriteOn = ArithmeticException.class) - public static int doII(int left, int right) { - return Math.floorMod(left, right); - } - - @Specialization(rewriteOn = ArithmeticException.class) - public static long doLL(long left, long right) { - return Math.floorMod(left, right); - } - - @Specialization(guards = "right != 0") - public static double doDL(double left, long right) { - return FloatBuiltins.ModNode.mod(left, right); - } +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberRemainderNode extends PyNumberRemainderFastPathsBase { @Fallback + @InliningCutoff public static Object doIt(VirtualFrame frame, Object v, Object w, @Bind Node inliningTarget, - @Cached GetClassNode getVClass, - @Cached GetCachedTpSlotsNode getVSlots, - @Cached GetCachedTpSlotsNode getWSlots, - @Cached GetClassNode getWClass, - @Cached CallBinaryOp1Node callBinaryOp1Node, - @Cached Lazy raiseNode) { - Object classV = getVClass.execute(inliningTarget, v); - Object classW = getWClass.execute(inliningTarget, w); - TpSlot slotV = getVSlots.execute(inliningTarget, classV).nb_remainder(); - TpSlot slotW = getWSlots.execute(inliningTarget, classW).nb_remainder(); - if (slotV != null || slotW != null) { - Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, BinaryOpSlot.NB_REMAINDER); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - } - return raiseNotSupported(inliningTarget, v, w, raiseNode); - } - - @InliningCutoff - private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, Lazy raiseNode) { - return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, "%", v, w); + @Cached CallBinaryOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, ReversibleSlot.NB_REMAINDER, "%"); } @NeverDefault public static PyNumberRemainderNode create() { return PyNumberRemainderNodeGen.create(); } + + public static PyNumberRemainderNode getUncached() { + return PyNumberRemainderNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberRshiftNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberRshiftNode.java index 2bc00a6dff..9ede62d455 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberRshiftNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberRshiftNode.java @@ -46,44 +46,30 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; +import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberRshiftFastPathsBase; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; -import com.oracle.graal.python.nodes.expression.BinaryOpNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @GenerateInline(false) -public abstract class PyNumberRshiftNode extends BinaryOpNode { - public abstract Object execute(VirtualFrame frame, Object v, Object w); - - @Override - public final Object executeObject(VirtualFrame frame, Object left, Object right) { - return execute(frame, left, right); - } - - @Specialization(guards = {"right < 32", "right >= 0"}) - public static int doIISmall(int left, int right) { - return left >> right; - } - - @Specialization(guards = {"right < 64", "right >= 0"}) - public static long doIISmall(long left, long right) { - return left >> right; - } +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberRshiftNode extends PyNumberRshiftFastPathsBase { @Fallback public static Object doIt(VirtualFrame frame, Object v, Object w, @@ -93,32 +79,30 @@ public static Object doIt(VirtualFrame frame, Object v, Object w, @Cached GetCachedTpSlotsNode getWSlots, @Cached GetClassNode getWClass, @Cached CallBinaryOp1Node callBinaryOp1Node, - @Cached Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object classV = getVClass.execute(inliningTarget, v); Object classW = getWClass.execute(inliningTarget, w); - TpSlot slotV = getVSlots.execute(inliningTarget, classV).nb_rshift(); - TpSlot slotW = getWSlots.execute(inliningTarget, classW).nb_rshift(); - if (slotV != null || slotW != null) { - Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, BinaryOpSlot.NB_RSHIFT); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } + TpSlots slotsV = getVSlots.execute(inliningTarget, classV); + TpSlots slotsW = getWSlots.execute(inliningTarget, classW); + Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotsV, w, classW, slotsW, ReversibleSlot.NB_RSHIFT); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + return result; } - return raiseNotSupported(inliningTarget, v, w, raiseNode); + throw raiseNotSupported(inliningTarget, v, w, raiseNode); } @InliningCutoff - private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, Lazy raiseNode) { + private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, PRaiseNode raiseNode) { if (v instanceof PBuiltinMethod) { handlePossiblePrint(inliningTarget, v, w); } - return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, ">>", v, w); + return raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, ">>", v, w); } @TruffleBoundary private static void handlePossiblePrint(Node inliningTarget, Object v, Object w) { if (v instanceof PBuiltinMethod method && method.getBuiltinFunction().getName().equalsUncached(T_PRINT, TS_ENCODING)) { - throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P_PRINT, ">>", v, w); + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P_PRINT, ">>", v, w); } } @@ -126,4 +110,8 @@ private static void handlePossiblePrint(Node inliningTarget, Object v, Object w) public static PyNumberRshiftNode create() { return PyNumberRshiftNodeGen.create(); } + + public static PyNumberRshiftNode getUncached() { + return PyNumberRshiftNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberSubtractNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberSubtractNode.java index b9218bbf78..ee8db9dad3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberSubtractNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberSubtractNode.java @@ -40,109 +40,38 @@ */ package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; -import com.oracle.graal.python.nodes.expression.BinaryOpNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberSubtractFastPathsBase; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @GenerateInline(false) -public abstract class PyNumberSubtractNode extends BinaryOpNode { - @Override - public final Object executeObject(VirtualFrame frame, Object left, Object right) { - return execute(frame, left, right); - } - - public abstract Object execute(VirtualFrame frame, Object v, Object w); - - /* - * All the following fast paths need to be kept in sync with the corresponding builtin functions - * in IntBuiltins, FloatBuiltins, ListBuiltins, ... - */ - - @Specialization(rewriteOn = ArithmeticException.class) - public static int doII(int x, int y) throws ArithmeticException { - return Math.subtractExact(x, y); - } - - @Specialization - public static long doIIOvf(int x, int y) { - return (long) x - (long) y; - } - - @Specialization(rewriteOn = ArithmeticException.class) - public static long doLL(long x, long y) throws ArithmeticException { - return Math.subtractExact(x, y); - } - - @Specialization - public static double doDD(double left, double right) { - return left - right; - } - - @Specialization - public static double doDL(double left, long right) { - return left - right; - } - - @Specialization - public static double doLD(long left, double right) { - return left - right; - } - - @Specialization - public static double doDI(double left, int right) { - return left - right; - } - - @Specialization - public static double doID(int left, double right) { - return left - right; - } +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberSubtractNode extends PyNumberSubtractFastPathsBase { @Fallback + @InliningCutoff public static Object doIt(VirtualFrame frame, Object v, Object w, @Bind Node inliningTarget, - @Cached GetClassNode getVClass, - @Cached GetCachedTpSlotsNode getVSlots, - @Cached GetCachedTpSlotsNode getWSlots, - @Cached GetClassNode getWClass, - @Cached CallBinaryOp1Node callBinaryOp1Node, - @Cached Lazy raiseNode) { - Object classV = getVClass.execute(inliningTarget, v); - Object classW = getWClass.execute(inliningTarget, w); - TpSlot slotV = getVSlots.execute(inliningTarget, classV).nb_subtract(); - TpSlot slotW = getWSlots.execute(inliningTarget, classW).nb_subtract(); - if (slotV != null || slotW != null) { - Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, BinaryOpSlot.NB_SUBTRACT); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - } - return raiseNotSupported(inliningTarget, v, w, raiseNode); - } - - @InliningCutoff - private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, Lazy raiseNode) { - return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, "-", v, w); + @Cached CallBinaryOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, ReversibleSlot.NB_SUBTRACT, "-"); } @NeverDefault public static PyNumberSubtractNode create() { return PyNumberSubtractNodeGen.create(); } + + public static PyNumberSubtractNode getUncached() { + return PyNumberSubtractNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberTrueDivideNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberTrueDivideNode.java index 731a66d293..b63c97a07c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberTrueDivideNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberTrueDivideNode.java @@ -40,92 +40,38 @@ */ package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; -import com.oracle.graal.python.nodes.expression.BinaryOpNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.util.OverflowException; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberTrueDivideFastPathsBase; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @GenerateInline(false) -public abstract class PyNumberTrueDivideNode extends BinaryOpNode { - public abstract Object execute(VirtualFrame frame, Object v, Object w); - - @Override - public final Object executeObject(VirtualFrame frame, Object left, Object right) { - return execute(frame, left, right); - } - - /* - * All the following fast paths need to be kept in sync with the corresponding builtin functions - * in IntBuiltins, FloatBuiltins, ... - */ - @Specialization(rewriteOn = OverflowException.class) - public static double doII(int left, int right) throws OverflowException { - return doDD(left, right); - } - - @Specialization(rewriteOn = OverflowException.class) - public static double doDI(double left, int right) throws OverflowException { - return doDD(left, right); - } - - @Specialization(rewriteOn = OverflowException.class) - public static double doID(int left, double right) throws OverflowException { - return doDD(left, right); - } - - @Specialization(rewriteOn = OverflowException.class) - public static double doDD(double left, double right) throws OverflowException { - if (right == 0.0) { - throw OverflowException.INSTANCE; - } - return left / right; - } +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberTrueDivideNode extends PyNumberTrueDivideFastPathsBase { @Fallback + @InliningCutoff public static Object doIt(VirtualFrame frame, Object v, Object w, @Bind Node inliningTarget, - @Cached GetClassNode getVClass, - @Cached GetCachedTpSlotsNode getVSlots, - @Cached GetCachedTpSlotsNode getWSlots, - @Cached GetClassNode getWClass, - @Cached CallBinaryOp1Node callBinaryOp1Node, - @Cached Lazy raiseNode) { - Object classV = getVClass.execute(inliningTarget, v); - Object classW = getWClass.execute(inliningTarget, w); - TpSlot slotV = getVSlots.execute(inliningTarget, classV).nb_true_divide(); - TpSlot slotW = getWSlots.execute(inliningTarget, classW).nb_true_divide(); - if (slotV != null || slotW != null) { - Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, BinaryOpSlot.NB_TRUE_DIVIDE); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - } - return raiseNotSupported(inliningTarget, v, w, raiseNode); - } - - @InliningCutoff - private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, Lazy raiseNode) { - return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, "/", v, w); + @Cached CallBinaryOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, ReversibleSlot.NB_TRUE_DIVIDE, "/"); } @NeverDefault public static PyNumberTrueDivideNode create() { return PyNumberTrueDivideNodeGen.create(); } + + public static PyNumberTrueDivideNode getUncached() { + return PyNumberTrueDivideNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberXorNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberXorNode.java index 71a5de5032..e58dd7d03d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberXorNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberXorNode.java @@ -40,74 +40,38 @@ */ package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; -import com.oracle.graal.python.nodes.expression.BinaryOpNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; +import com.oracle.graal.python.lib.fastpath.PyNumberXorFastPathsBase; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @GenerateInline(false) -public abstract class PyNumberXorNode extends BinaryOpNode { - public abstract Object execute(VirtualFrame frame, Object v, Object w); - - @Override - public final Object executeObject(VirtualFrame frame, Object left, Object right) { - return execute(frame, left, right); - } - - @Specialization - public static int op(int left, int right) { - return left ^ right; - } - - @Specialization - public static long op(long left, long right) { - return left ^ right; - } +@GenerateUncached +@OperationProxy.Proxyable +public abstract class PyNumberXorNode extends PyNumberXorFastPathsBase { @Fallback + @InliningCutoff public static Object doIt(VirtualFrame frame, Object v, Object w, @Bind Node inliningTarget, - @Cached GetClassNode getVClass, - @Cached GetCachedTpSlotsNode getVSlots, - @Cached GetCachedTpSlotsNode getWSlots, - @Cached GetClassNode getWClass, - @Cached CallBinaryOp1Node callBinaryOp1Node, - @Cached Lazy raiseNode) { - Object classV = getVClass.execute(inliningTarget, v); - Object classW = getWClass.execute(inliningTarget, w); - TpSlot slotV = getVSlots.execute(inliningTarget, classV).nb_xor(); - TpSlot slotW = getWSlots.execute(inliningTarget, classW).nb_xor(); - if (slotV != null || slotW != null) { - Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, BinaryOpSlot.NB_XOR); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - } - return raiseNotSupported(inliningTarget, v, w, raiseNode); - } - - @InliningCutoff - private static PException raiseNotSupported(Node inliningTarget, Object v, Object w, Lazy raiseNode) { - return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, "^", v, w); + @Cached CallBinaryOpNode callBinaryOpNode) { + return callBinaryOpNode.execute(frame, inliningTarget, v, w, ReversibleSlot.NB_XOR, "^"); } @NeverDefault public static PyNumberXorNode create() { return PyNumberXorNodeGen.create(); } + + public static PyNumberXorNode getUncached() { + return PyNumberXorNodeGen.getUncached(); + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyOSFSPathNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyOSFSPathNode.java index 9e7c546a56..dd49945815 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyOSFSPathNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyOSFSPathNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -94,17 +94,17 @@ static Object callFspath(VirtualFrame frame, Node inliningTarget, Object object, @Cached GetClassNode getClassNode, @Cached LookupSpecialMethodNode.Dynamic lookupFSPath, @Cached(inline = false) CallUnaryMethodNode callFSPath, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object type = getClassNode.execute(inliningTarget, object); Object fspathMethod = lookupFSPath.execute(frame, inliningTarget, type, T___FSPATH__, object); if (fspathMethod == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.EXPECTED_STR_BYTE_OSPATHLIKE_OBJ, object); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.EXPECTED_STR_BYTE_OSPATHLIKE_OBJ, object); } Object result = callFSPath.executeObject(frame, fspathMethod, object); assert !isJavaString(result); if (result instanceof TruffleString || result instanceof PString || result instanceof PBytes) { return result; } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.EXPECTED_FSPATH_TO_RETURN_STR_OR_BYTES, object, result); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.EXPECTED_FSPATH_TO_RETURN_STR_OR_BYTES, object, result); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectAsFileDescriptor.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectAsFileDescriptor.java index c3c9d73083..3efcae5e8c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectAsFileDescriptor.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectAsFileDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -71,7 +71,7 @@ public abstract class PyObjectAsFileDescriptor extends PNodeWithContext { @Specialization static int doInt(Node inliningTarget, @SuppressWarnings("unused") int object, - @Exclusive @Cached PRaiseNode.Lazy raise) { + @Exclusive @Cached PRaiseNode raise) { return checkResult(object, inliningTarget, raise); } @@ -79,7 +79,7 @@ static int doInt(Node inliningTarget, @SuppressWarnings("unused") int object, static int doPyLong(VirtualFrame frame, @SuppressWarnings("unused") Node inliningTarget, Object object, @SuppressWarnings("unused") @Exclusive @Cached PyLongCheckNode longCheckNode, @Exclusive @Cached PyLongAsIntNode asIntNode, - @Exclusive @Cached PRaiseNode.Lazy raise) { + @Exclusive @Cached PRaiseNode raise) { return checkResult(asIntNode.execute(frame, inliningTarget, object), inliningTarget, raise); } @@ -89,21 +89,21 @@ static int doNotLong(VirtualFrame frame, Node inliningTarget, Object object, @Cached(inline = false) CallNode callFileno, @Exclusive @Cached PyLongCheckNode checkResultNode, @Exclusive @Cached PyLongAsIntNode asIntNode, - @Exclusive @Cached PRaiseNode.Lazy raise) { + @Exclusive @Cached PRaiseNode raise) { Object filenoMethod = lookupFileno.execute(frame, inliningTarget, object, T_FILENO); if (filenoMethod != PNone.NO_VALUE) { Object result = callFileno.execute(frame, filenoMethod); if (checkResultNode.execute(inliningTarget, result)) { return checkResult(asIntNode.execute(frame, inliningTarget, result), inliningTarget, raise); } - throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.RETURNED_NON_INTEGER, "fileno()"); + throw raise.raise(inliningTarget, TypeError, ErrorMessages.RETURNED_NON_INTEGER, "fileno()"); } - throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.ARG_MUST_BE_INT_OR_HAVE_FILENO_METHOD); + throw raise.raise(inliningTarget, TypeError, ErrorMessages.ARG_MUST_BE_INT_OR_HAVE_FILENO_METHOD); } - private static int checkResult(int result, Node inliningTarget, PRaiseNode.Lazy raiseNode) { + private static int checkResult(int result, Node inliningTarget, PRaiseNode raiseNode) { if (result < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.S_CANNOT_BE_NEGATIVE_INTEGER_D, "file descriptor", result); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.S_CANNOT_BE_NEGATIVE_INTEGER_D, "file descriptor", result); } return result; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectCallMethodObjArgs.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectCallMethodObjArgs.java index 7694f46cfe..b846cc4d38 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectCallMethodObjArgs.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectCallMethodObjArgs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,7 +41,6 @@ package com.oracle.graal.python.lib; import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.nodes.call.BoundDescriptor; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode; @@ -55,7 +54,6 @@ import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; @@ -69,7 +67,6 @@ @GenerateUncached @GenerateCached @GenerateInline(inlineByDefault = true) -@ImportStatic(SpecialMethodSlot.class) public abstract class PyObjectCallMethodObjArgs extends Node { public static Object executeUncached(Object receiver, TruffleString name, Object... arguments) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectDelItem.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectDelItem.java index 2f5bb76803..dc74ce0ebe 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectDelItem.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectDelItem.java @@ -54,6 +54,7 @@ import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Fallback; @@ -126,8 +127,8 @@ static void doSequence(VirtualFrame frame, Node inliningTarget, Object object, T @Fallback @InliningCutoff static void error(Object object, @SuppressWarnings("unused") TpSlots slots, @SuppressWarnings("unused") Object key, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_DOES_NOT_SUPPORT_ITEM_DELETION, object); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.OBJ_DOES_NOT_SUPPORT_ITEM_DELETION, object); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectDir.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectDir.java index 2184d0bb60..93f75625cd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectDir.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectDir.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -71,10 +71,10 @@ static PList dir(VirtualFrame frame, Node inliningTarget, Object object, @Cached(inline = false) ListBuiltins.ListSortNode sortNode, @Cached(inline = false) ListNodes.ConstructListNode constructListNode, @Cached(value = "create(T___DIR__)", inline = false) LookupAndCallUnaryNode callDir, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object result = callDir.executeObject(frame, object); if (result == PNone.NO_VALUE) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.OBJ_DOES_NOT_PROVIDE_DIR); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.OBJ_DOES_NOT_PROVIDE_DIR); } PList list = constructListNode.execute(frame, result); sortNode.execute(frame, list); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectFormat.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectFormat.java index c4c295dfea..c4c9f0c51b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectFormat.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,23 +40,20 @@ */ package com.oracle.graal.python.lib; -import static com.oracle.graal.python.builtins.objects.PNone.NO_VALUE; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___FORMAT__; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode; +import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.util.PythonUtils; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -120,32 +117,28 @@ static Object doLong(long obj, Object formatSpec) { // Note: PRaiseNode is @Exclusive to workaround a bug in DSL @Specialization(guards = "isString(formatSpec)") - static Object doGeneric(VirtualFrame frame, Object obj, Object formatSpec, - @Cached(parameters = "Format", inline = false) LookupAndCallBinaryNode callFormat, - @Exclusive @Cached(inline = false) PRaiseNode raiseNode) { - Object res = callFormat.executeObject(frame, obj, formatSpec); - if (res == NO_VALUE) { - throw raiseNode.raise(TypeError, ErrorMessages.TYPE_DOESNT_DEFINE_FORMAT, obj); + static Object doGeneric(VirtualFrame frame, Node inliningTarget, Object obj, Object formatSpec, + @Cached GetClassNode getClassNode, + @Cached LookupSpecialMethodNode.Dynamic lookupFormat, + @Cached CallBinaryMethodNode callFormat, + @Exclusive @Cached PRaiseNode raiseNode) { + Object formatMethod = lookupFormat.execute(frame, inliningTarget, getClassNode.execute(inliningTarget, obj), T___FORMAT__, obj); + if (formatMethod != PNone.NO_VALUE) { + Object res = callFormat.executeObject(frame, obj, formatSpec); + if (!PGuards.isString(res)) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_MUST_RETURN_S_NOT_P, T___FORMAT__, "str", res); + } + return res; + } else { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TYPE_DOESNT_DEFINE_FORMAT, obj); } - if (!PGuards.isString(res)) { - throw raiseNode.raise(TypeError, ErrorMessages.S_MUST_RETURN_S_NOT_P, T___FORMAT__, "str", res); - } - return res; - } - - @Specialization(guards = "isString(formatSpec)", replaces = "doGeneric") - static Object doGenericUncached(VirtualFrame frame, Object obj, Object formatSpec) { - PythonUtils.assertUncached(); - Object klass = GetClassNode.executeUncached(obj); - Object slot = LookupCallableSlotInMRONode.getUncached(SpecialMethodSlot.Format).execute(klass); - return CallBinaryMethodNode.getUncached().executeObject(frame, slot, obj, formatSpec); } // Note: PRaiseNode is @Exclusive to workaround a bug in DSL @Fallback static Object doNonStringFormat(Object obj, Object formatSpec, - @Exclusive @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.SystemError, ErrorMessages.S_MUST_BE_S_NOT_P, "Format specifier", "a string", formatSpec); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.SystemError, ErrorMessages.S_MUST_BE_S_NOT_P, "Format specifier", "a string", formatSpec); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetAttr.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetAttr.java index 1cbd75ed35..19944d57aa 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetAttr.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetAttr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,21 +40,19 @@ */ package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; +import com.oracle.graal.python.builtins.objects.exception.AttributeErrorBuiltins; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.CallSlotGetAttrNode; -import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetFixedAttributeNode; import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; @@ -70,7 +68,6 @@ @GenerateUncached @GenerateInline(inlineByDefault = true) @GenerateCached -@ImportStatic(SpecialMethodSlot.class) public abstract class PyObjectGetAttr extends Node { public static Object executeUncached(Object receiver, TruffleString name) { return PyObjectGetAttr.getUncached().execute(null, null, receiver, name); @@ -99,6 +96,7 @@ static Object getDynamicAttr(Frame frame, Node inliningTarget, Object receiver, @Cached GetClassNode getClass, @Cached GetObjectSlotsNode getSlotsNode, @Cached CallSlotGetAttrNode callGetAttrNode, + @Cached AttributeErrorBuiltins.SetAttributeErrorContext setContext, @Cached(inline = false) TruffleString.CodePointLengthNode codePointLengthNode, @Cached(inline = false) TruffleString.CodePointAtIndexNode codePointAtIndexNode) { Object type = getClass.execute(inliningTarget, receiver); @@ -108,12 +106,16 @@ static Object getDynamicAttr(Frame frame, Node inliningTarget, Object receiver, Object result = PyObjectLookupAttr.readAttributeQuickly(type, slots, receiver, name, codePointLengthNode, codePointAtIndexNode); if (result != null) { if (result == PNone.NO_VALUE) { - throw PRaiseNode.getUncached().raise(PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, receiver, name); + throw PRaiseNode.raiseAttributeErrorStatic(inliningTarget, receiver, name); } return result; } } - return callGetAttrNode.execute((VirtualFrame) frame, inliningTarget, slots, receiver, name); + try { + return callGetAttrNode.execute((VirtualFrame) frame, inliningTarget, slots, receiver, name); + } catch (PException e) { + throw setContext.execute(inliningTarget, e, receiver, name); + } } @NeverDefault diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetAttrO.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetAttrO.java index a2e0f0cd42..86d8f6da84 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetAttrO.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetAttrO.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -84,7 +84,7 @@ static Object getDynamicAttr(Frame frame, Node inliningTarget, Object receiver, Object result = PyObjectLookupAttr.readAttributeQuickly(type, slots, receiver, tsName, codePointLengthNode, codePointAtIndexNode); if (result != null) { if (result == PNone.NO_VALUE) { - throw PRaiseNode.getUncached().raise(PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, receiver, name); + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, receiver, name); } return result; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetItem.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetItem.java index b783cf527c..fcc826e684 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetItem.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetItem.java @@ -43,6 +43,7 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; import static com.oracle.graal.python.nodes.SpecialMethodNames.T___CLASS_GETITEM__; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.dict.DictBuiltins; @@ -62,7 +63,7 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassExactProfile; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -123,7 +124,7 @@ static Object doGeneric(VirtualFrame frame, Node inliningTarget, Object object, @GenerateUncached @GenerateInline @GenerateCached(false) - abstract static class PyObjectGetItemGeneric extends PNodeWithContext { + public abstract static class PyObjectGetItemGeneric extends PNodeWithContext { public abstract Object execute(Frame frame, Node inliningTarget, Object object, TpSlots objectKlassSlots, Object key); @Specialization(guards = "slots.mp_subscript() != null") @@ -155,9 +156,8 @@ static Object tryType(VirtualFrame frame, Node inliningTarget, Object maybeType, @Cached TypeNodes.IsTypeNode isTypeNode, @Cached PyObjectLookupAttr lookupClassGetItem, @Cached IsBuiltinClassExactProfile isBuiltinClassProfile, - @Cached(inline = false) PythonObjectFactory factory, @Cached(inline = false) CallNode callClassGetItem, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (isTypeNode.execute(inliningTarget, maybeType)) { Object classGetitem = lookupClassGetItem.execute(frame, inliningTarget, maybeType, T___CLASS_GETITEM__); if (!(classGetitem instanceof PNone)) { @@ -165,11 +165,11 @@ static Object tryType(VirtualFrame frame, Node inliningTarget, Object maybeType, } if (isBuiltinClassProfile.profileClass(inliningTarget, maybeType, PythonBuiltinClassType.PythonClass)) { // Special case type[int], but disallow other types so str[int] fails - return factory.createGenericAlias(maybeType, key); + return PFactory.createGenericAlias(PythonLanguage.get(inliningTarget), maybeType, key); } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.TYPE_NOT_SUBSCRIPTABLE, maybeType); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TYPE_NOT_SUBSCRIPTABLE, maybeType); } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.OBJ_NOT_SUBSCRIPTABLE, maybeType); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.OBJ_NOT_SUBSCRIPTABLE, maybeType); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetIter.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetIter.java index d6c04509b2..8f76c8c9cd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetIter.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetIter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,26 +42,25 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; -import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.range.PIntRange; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotUnaryFunc.CallSlotUnaryNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; /** @@ -70,7 +69,6 @@ @GenerateUncached @GenerateCached @GenerateInline(inlineByDefault = true) -@ImportStatic(SpecialMethodSlot.class) public abstract class PyObjectGetIter extends Node { public static Object executeUncached(Object obj) { return PyObjectGetIterNodeGen.getUncached().execute(null, null, obj); @@ -84,39 +82,33 @@ public final Object executeCached(Frame frame, Object receiver) { @Specialization static Object getIterRange(PIntRange object, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createIntRangeIterator(object); + @Bind PythonLanguage language) { + return PFactory.createIntRangeIterator(language, object); } @Specialization @InliningCutoff - static Object getIter(Frame frame, Node inliningTarget, Object receiver, + static Object getIter(VirtualFrame frame, Node inliningTarget, Object receiver, @Cached GetClassNode getReceiverClass, - @Cached(parameters = "Iter", inline = false) LookupSpecialMethodSlotNode lookupIter, + @Cached GetCachedTpSlotsNode getSlots, @Cached PySequenceCheckNode sequenceCheckNode, - @Shared @Cached(inline = false) PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raise, - @Cached(inline = false) CallUnaryMethodNode callIter, + @Cached PRaiseNode raise, + @Cached CallSlotUnaryNode callSlot, @Cached PyIterCheckNode checkNode) { Object type = getReceiverClass.execute(inliningTarget, receiver); - Object iterMethod = PNone.NO_VALUE; - try { - iterMethod = lookupIter.execute(frame, type, receiver); - } catch (PException e) { - // ignore - } - if (iterMethod instanceof PNone) { - if (sequenceCheckNode.execute(inliningTarget, receiver)) { - return factory.createSequenceIterator(receiver); - } - } else { - Object result = callIter.executeObject(frame, iterMethod, receiver); + TpSlots slots = getSlots.execute(inliningTarget, type); + if (slots.tp_iter() != null) { + Object result = callSlot.execute(frame, inliningTarget, slots.tp_iter(), receiver); if (!checkNode.execute(inliningTarget, result)) { - throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.RETURNED_NONITER, result); + throw raise.raise(inliningTarget, TypeError, ErrorMessages.RETURNED_NONITER, result); } return result; + } else { + if (sequenceCheckNode.execute(inliningTarget, receiver)) { + return PFactory.createSequenceIterator(PythonLanguage.get(inliningTarget), receiver); + } } - throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.OBJ_NOT_ITERABLE, receiver); + throw raise.raise(inliningTarget, TypeError, ErrorMessages.OBJ_NOT_ITERABLE, receiver); } @NeverDefault diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetMethod.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetMethod.java index 3940bb317b..5cc725f3a2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetMethod.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,20 +40,16 @@ */ package com.oracle.graal.python.lib; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.AttributeError; - import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PythonAbstractObject; import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.CallSlotDescrGet; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrSet; -import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; @@ -75,7 +71,6 @@ import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; @@ -96,7 +91,6 @@ @GenerateUncached @GenerateInline(inlineByDefault = true) @GenerateCached -@ImportStatic(SpecialMethodSlot.class) public abstract class PyObjectGetMethod extends Node { public final Object executeCached(Frame frame, Object receiver, TruffleString name) { return execute(frame, this, receiver, name); @@ -120,7 +114,7 @@ static Object getFixedAttr(VirtualFrame frame, Node inliningTarget, Object recei @Exclusive @Cached GetObjectSlotsNode getSlotsNode, @Exclusive @Cached CallSlotDescrGet callGetNode, @Shared("readAttr") @Cached(inline = false) ReadAttributeFromObjectNode readAttr, - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Cached InlinedBranchProfile hasDescr, @Cached InlinedBranchProfile returnDataDescr, @Cached InlinedBranchProfile returnAttr, @@ -163,7 +157,7 @@ static Object getFixedAttr(VirtualFrame frame, Node inliningTarget, Object recei if (descr != PNone.NO_VALUE) { return new BoundDescriptor(descr); } - throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, receiver, name); + throw raiseNode.raiseAttributeError(inliningTarget, receiver, name); } // No explicit branch profiling when we're looking up multiple things @@ -178,7 +172,7 @@ static Object getDynamicAttr(Frame frame, Node inliningTarget, Object receiver, @Exclusive @Cached GetObjectSlotsNode getSlotsNode, @Exclusive @Cached CallSlotDescrGet callGetNode, @Shared("readAttr") @Cached(inline = false) ReadAttributeFromObjectNode readAttr, - /* Truffle bug: @Shared("raiseNode") */ @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + /* Truffle bug: @Shared("raiseNode") */ @Exclusive @Cached PRaiseNode raiseNode) { boolean methodFound = false; Object descr = lookupNode.execute(lazyClass, name); TpSlot getMethod = null; @@ -208,7 +202,7 @@ static Object getDynamicAttr(Frame frame, Node inliningTarget, Object receiver, if (descr != PNone.NO_VALUE) { return new BoundDescriptor(descr); } - throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, receiver, name); + throw raiseNode.raiseAttributeError(inliningTarget, receiver, name); } @Specialization(guards = "isForeignObject(inliningTarget, isForeignObjectNode, receiver)", limit = "1") diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectHashNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectHashNode.java index 72334ce735..e0e087a41d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectHashNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectHashNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,25 +40,34 @@ */ package com.oracle.graal.python.lib; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import com.oracle.graal.python.builtins.modules.MathModuleBuiltins; import com.oracle.graal.python.builtins.modules.SysModuleBuiltins; -import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; +import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PCallCapiFunction; +import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol; +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode; +import com.oracle.graal.python.builtins.objects.cext.structs.CFields; +import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; +import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess.ReadI64Node; import com.oracle.graal.python.builtins.objects.str.PString; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.TypeFlags; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.CallSlotHashFunNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; -import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.MaybeBindDescriptorNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.nodes.util.CastUnsignedToJavaLongHashNode; +import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext; +import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -66,14 +75,13 @@ import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleString; -@ImportStatic(SpecialMethodSlot.class) @GenerateUncached @GenerateCached(false) @GenerateInline @@ -160,34 +168,71 @@ public static long hash(double object) { @Fallback @InliningCutoff - static long hash(VirtualFrame frame, Node inliningTarget, Object object, + static long genericHash(VirtualFrame frame, Node inliningTarget, Object object, @Cached GetClassNode getClassNode, - @Cached(parameters = "Hash", inline = false) LookupCallableSlotInMRONode lookupHash, - @Cached MaybeBindDescriptorNode bindDescriptorNode, - @Cached(inline = false) CallUnaryMethodNode callHash, - @Cached CastUnsignedToJavaLongHashNode cast, - @Cached PRaiseNode.Lazy raiseNode) { - /* This combines the logic from abstract.c:PyObject_Hash and typeobject.c:slot_tp_hash */ - Object type = getClassNode.execute(inliningTarget, object); - // We have to do the lookup and bind steps separately to avoid binding possible None - Object hashDescr = lookupHash.execute(type); - if (hashDescr != PNone.NO_VALUE && hashDescr != PNone.NONE) { - try { - hashDescr = bindDescriptorNode.execute(frame, inliningTarget, hashDescr, object, type); - } catch (PException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.UNHASHABLE_TYPE_P, object); - } - Object result = callHash.executeObject(frame, hashDescr, object); - try { - return avoidNegative1(cast.execute(inliningTarget, result)); - } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.HASH_SHOULD_RETURN_INTEGER); + @Cached GetCachedTpSlotsNode getSlotsNode, + @Cached CStructAccess.ReadI64Node readTypeObjectFieldNode, + @Cached InlinedConditionProfile typeIsNotReadyProfile, + @Cached("createFor(this)") IndirectCallData indirectCallData, + @Cached CallSlotHashFunNode callHashFun, + @Cached PRaiseNode raiseNode) { + Object klass = getClassNode.execute(inliningTarget, object); + TpSlots slots = getSlotsNode.execute(inliningTarget, klass); + if (slots.tp_hash() == null) { + slots = handleNoHash(frame, inliningTarget, object, readTypeObjectFieldNode, + typeIsNotReadyProfile, indirectCallData, raiseNode, klass, slots); + } + return callHashFun.execute(frame, inliningTarget, slots.tp_hash(), object); + } + + @InliningCutoff + private static TpSlots handleNoHash(VirtualFrame frame, Node inliningTarget, Object object, ReadI64Node readTypeObjectFieldNode, + InlinedConditionProfile typeIsNotReadyProfile, + IndirectCallData indirectCallData, PRaiseNode raiseNode, Object klass, TpSlots slots) { + boolean initialized = false; + if (klass instanceof PythonAbstractNativeObject nativeKlass) { + // Comment from CPython: + /* + * To keep to the general practice that inheriting solely from object in C code should + * work without an explicit call to PyType_Ready, we implicitly call PyType_Ready here + * and then check the tp_hash slot again + */ + long flags = readTypeObjectFieldNode.readFromObj(nativeKlass, CFields.PyTypeObject__tp_flags); + if (typeIsNotReadyProfile.profile(inliningTarget, (flags & TypeFlags.READY) == 0)) { + Object savedState = IndirectCallContext.enter(frame, indirectCallData); + try { + slots = callTypeReady(inliningTarget, object, nativeKlass); + initialized = true; + } finally { + IndirectCallContext.exit(frame, indirectCallData, savedState); + } } } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.UNHASHABLE_TYPE_P, object); + if (!initialized) { + throw raiseUnhashable(inliningTarget, object, raiseNode); + } + return slots; } - public static PyObjectHashNode getUncached() { - return PyObjectHashNodeGen.getUncached(); + @TruffleBoundary + private static TpSlots callTypeReady(Node inliningTarget, Object object, PythonAbstractNativeObject klass) { + int res = (int) PCallCapiFunction.getUncached().call(NativeCAPISymbol.FUN_PY_TYPE_READY, PythonToNativeNode.executeUncached(klass)); + if (res < 0) { + throw raiseSystemError(inliningTarget, klass); + } + TpSlots slots = GetTpSlotsNode.executeUncached(klass); + if (slots.tp_hash() == null) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.UNHASHABLE_TYPE_P, object); + } + return slots; + } + + private static PException raiseSystemError(Node inliningTarget, Object klass) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, ErrorMessages.LAZY_INITIALIZATION_FAILED, klass); + } + + @InliningCutoff + private static PException raiseUnhashable(Node inliningTarget, Object object, PRaiseNode raiseNode) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.UNHASHABLE_TYPE_P, object); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsNotTrueNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsNotTrueNode.java index 4784aa8526..27c7af8a60 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsNotTrueNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsNotTrueNode.java @@ -47,8 +47,9 @@ import com.oracle.graal.python.builtins.objects.set.PBaseSet; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.lib.PyObjectIsTrueNode.PyObjectIsTrueNodeGeneric; -import com.oracle.graal.python.nodes.expression.UnaryOpNode; +import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -66,14 +67,10 @@ * {@link PyObjectIsNotTrueNode}. */ @GenerateInline(false) -public abstract class PyObjectIsNotTrueNode extends UnaryOpNode { +@OperationProxy.Proxyable +public abstract class PyObjectIsNotTrueNode extends PNodeWithContext { public abstract boolean execute(Frame frame, Object object); - @Override - public final Object executeCached(VirtualFrame frame, Object value) { - return execute(frame, value); - } - @Specialization public static boolean doBoolean(boolean object) { return !object; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsTrueNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsTrueNode.java index 97e9460cdf..c4170433d0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsTrueNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsTrueNode.java @@ -52,8 +52,8 @@ import com.oracle.graal.python.builtins.objects.type.slots.TpSlotInquiry.CallSlotNbBoolNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.CallSlotLenNode; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.expression.UnaryOpNode; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -77,14 +77,10 @@ @GenerateUncached @GenerateInline(false) @GenerateCached -public abstract class PyObjectIsTrueNode extends UnaryOpNode { +@OperationProxy.Proxyable +public abstract class PyObjectIsTrueNode extends PNodeWithContext { public abstract boolean execute(Frame frame, Object object); - @Override - public final Object executeCached(VirtualFrame frame, Object value) { - return execute(frame, value); - } - public static boolean executeUncached(Object object) { return getUncached().execute(null, object); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectLookupAttr.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectLookupAttr.java index da0e9ffa2f..f537089835 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectLookupAttr.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectLookupAttr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -51,7 +51,6 @@ import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; @@ -94,7 +93,7 @@ @GenerateUncached @GenerateInline(inlineByDefault = true) @GenerateCached -@ImportStatic({SpecialMethodSlot.class, SpecialMethodNames.class, PGuards.class}) +@ImportStatic({SpecialMethodNames.class, PGuards.class}) public abstract class PyObjectLookupAttr extends Node { public static Object executeUncached(Object receiver, TruffleString name) { return PyObjectLookupAttrNodeGen.getUncached().execute(null, null, receiver, name); @@ -133,9 +132,7 @@ protected static boolean isBuiltinTypeType(Object type) { } protected static boolean isTypeSlot(TruffleString name, TruffleString.CodePointLengthNode codePointLengthNode, TruffleString.CodePointAtIndexNode codePointAtIndexNode) { - return SpecialMethodSlot.canBeSpecial(name, codePointLengthNode, codePointAtIndexNode) || // - TpSlots.canBeSpecialMethod(name, codePointLengthNode, codePointAtIndexNode) || // - name.equalsUncached(T_MRO, TS_ENCODING); + return TpSlots.canBeSpecialMethod(name, codePointLengthNode, codePointAtIndexNode) || name.equalsUncached(T_MRO, TS_ENCODING); } // simple version that needs no calls and only reads from the object directly @@ -341,7 +338,7 @@ static Object readAttributeQuickly(Object type, TpSlots slots, Object receiver, // this is slightly simpler than the previous case, since we don't need to check // the type. There may be a module-level __getattr__, however. Since that would be // a call anyway, we return to the generic code in that case - if (!SpecialMethodSlot.canBeSpecial(stringName, codePointLengthNode, codePointAtIndexNode)) { + if (!TpSlots.canBeSpecialMethod(stringName, codePointLengthNode, codePointAtIndexNode)) { // not a special name, so this attribute cannot be on the module class ReadAttributeFromObjectNode readUncached = ReadAttributeFromObjectNode.getUncached(); Object result = readUncached.execute(receiver, stringName); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectReprAsObjectNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectReprAsObjectNode.java index 8dd2e460cc..961e07ca9c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectReprAsObjectNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectReprAsObjectNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,29 +44,25 @@ import static com.oracle.graal.python.nodes.truffle.TruffleStringMigrationHelpers.assertNoJavaString; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; -import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.object.ObjectNodes; import com.oracle.graal.python.builtins.objects.str.PString; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRepr.CallSlotReprNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; -import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleString; /** @@ -80,7 +76,6 @@ @GenerateUncached @GenerateCached @GenerateInline(inlineByDefault = true) -@ImportStatic(SpecialMethodSlot.class) public abstract class PyObjectReprAsObjectNode extends PNodeWithContext { public static Object executeUncached(Object object) { @@ -99,37 +94,27 @@ public final Object executeCached(Frame frame, Object object) { @Specialization static Object repr(VirtualFrame frame, Node inliningTarget, Object obj, - @Cached GetClassNode getClassNode, - @Cached(parameters = "Repr", inline = false) LookupSpecialMethodSlotNode lookupRepr, - @Cached(inline = false) CallUnaryMethodNode callRepr, + @Cached GetObjectSlotsNode getSlots, + @Cached CallSlotReprNode callSlot, @Cached(inline = false) ObjectNodes.DefaultObjectReprNode defaultRepr, - @Cached InlinedConditionProfile isString, - @Cached InlinedConditionProfile isPString, - @Cached PRaiseNode.Lazy raiseNode) { - Object type = getClassNode.execute(inliningTarget, obj); - Object reprMethod; - try { - reprMethod = lookupRepr.execute(frame, type, obj); - } catch (PException e) { + @Cached PyUnicodeCheckNode checkNode, + @Cached PRaiseNode raiseNode) { + TpSlots slots = getSlots.execute(inliningTarget, obj); + if (slots.tp_repr() == null) { return defaultRepr.execute(frame, inliningTarget, obj); } - if (reprMethod != PNone.NO_VALUE) { - Object result = callRepr.executeObject(frame, reprMethod, obj); - result = assertNoJavaString(result); - if (isString.profile(inliningTarget, result instanceof TruffleString) || - isPString.profile(inliningTarget, result instanceof PString)) { - return result; - } - if (result != PNone.NO_VALUE) { - throw raiseTypeError(inliningTarget, obj, raiseNode); - } + Object result = callSlot.execute(frame, inliningTarget, slots.tp_repr(), obj); + assertNoJavaString(result); + if (checkNode.execute(inliningTarget, result)) { + return result; + } else { + throw raiseTypeError(inliningTarget, obj, raiseNode); } - return defaultRepr.execute(frame, inliningTarget, obj); } @InliningCutoff - private static PException raiseTypeError(Node inliningTarget, Object obj, PRaiseNode.Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.RETURNED_NON_STRING, T___REPR__, obj); + private static PException raiseTypeError(Node inliningTarget, Object obj, PRaiseNode raiseNode) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.RETURNED_NON_STRING, T___REPR__, obj); } @NeverDefault diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectRichCompare.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectRichCompare.java new file mode 100644 index 0000000000..08a6e4bd9c --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectRichCompare.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.CallSlotRichCmpNode; +import com.oracle.graal.python.lib.PyObjectRichCompareNodeGen.RichCompareBinaryOpNodeGen; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.classes.IsSubtypeNode; +import com.oracle.graal.python.nodes.expression.BinaryOp; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.nodes.object.IsNode; +import com.oracle.graal.python.nodes.truffle.PythonIntegerAndFloatTypes; +import com.oracle.graal.python.util.PythonUtils; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.dsl.TypeSystemReference; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; +import com.oracle.truffle.api.strings.TruffleString; +import com.oracle.truffle.api.strings.TruffleString.EqualNode; + +@GenerateInline +@GenerateUncached +@GenerateCached(false) +@TypeSystemReference(PythonIntegerAndFloatTypes.class) +public abstract class PyObjectRichCompare extends Node { + public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object a, Object b, RichCmpOp op); + + public static Object executeUncached(Object a, Object b, RichCmpOp op) { + return PyObjectRichCompareNodeGen.getUncached().execute(null, null, a, b, op); + } + + @Specialization + static boolean doInts(int a, int b, RichCmpOp op) { + return op.compare(a, b); + } + + @Specialization + static boolean doDoubles(double a, double b, RichCmpOp op) { + return op.compare(a, b); + } + + @Specialization + static boolean doLongs(long a, long b, RichCmpOp op) { + return op.compare(a, b); + } + + @Specialization(guards = "op.isEqOrNe()") + static boolean doStrings(TruffleString a, TruffleString b, RichCmpOp op, + @Cached EqualNode equalNode) { + return equalNode.execute(a, b, PythonUtils.TS_ENCODING) == op.isEq(); + } + + @Fallback + @InliningCutoff + static Object doIt(VirtualFrame frame, Object v, Object w, RichCmpOp op, + @Cached(inline = false) GenericRichCompare richCompare) { + return richCompare.execute(frame, v, w, op); + } + + @GenerateInline(false) + public abstract static class RichCompareBinaryOp extends Node implements BinaryOp { + private final RichCmpOp op; + + protected RichCompareBinaryOp(RichCmpOp op) { + this.op = op; + } + + public static RichCompareBinaryOp create(RichCmpOp op) { + return RichCompareBinaryOpNodeGen.create(op); + } + + @Specialization + final Object doIt(VirtualFrame frame, Object left, Object right, + @Cached PyObjectRichCompare richCmpNode) { + return richCmpNode.execute(frame, this, left, right, op); + } + } + + @GenerateInline(false) + @GenerateUncached + public abstract static class GenericRichCompare extends Node { + public abstract Object execute(VirtualFrame frame, Object a, Object b, RichCmpOp op); + + @Specialization + static Object doIt(VirtualFrame frame, Object v, Object w, RichCmpOp op, + @Bind Node inliningTarget, + @Cached GetClassNode getVClass, + @Cached GetClassNode getWClass, + @Cached GetCachedTpSlotsNode getVSlots, + @Cached GetCachedTpSlotsNode getWSlots, + @Cached InlinedConditionProfile checkRevOpProfile, + @Cached IsSameTypeNode isSameTypeNode, + @Cached IsSubtypeNode isSubtypeNode, + @Cached CallSlotRichCmpNode callRichCmpSwapped, + @Cached CallSlotRichCmpNode callRichCmp, + @Cached IsNode isNode, + @Cached InlinedConditionProfile notImplemented1Profile, + @Cached InlinedConditionProfile notImplemented2Profile, + @Cached InlinedConditionProfile notImplemented3Profile, + @Cached PRaiseNode raiseNode) { + Object vClass = getVClass.execute(inliningTarget, v); + Object wClass = getWClass.execute(inliningTarget, w); + TpSlots wSlots = getWSlots.execute(inliningTarget, wClass); + boolean checkedReverseOp = false; + if (checkRevOpProfile.profile(inliningTarget, wSlots.tp_richcmp() != null && + !isSameTypeNode.execute(inliningTarget, vClass, wClass) && isSubtypeNode.execute(wClass, vClass))) { + checkedReverseOp = true; + Object result = callRichCmpSwapped.execute(frame, inliningTarget, wSlots.tp_richcmp(), w, v, op.getSwapped()); + if (notImplemented1Profile.profile(inliningTarget, result != PNotImplemented.NOT_IMPLEMENTED)) { + return result; + } + } + TpSlots vSlots = getVSlots.execute(inliningTarget, vClass); + if (vSlots.tp_richcmp() != null) { + Object result = callRichCmp.execute(frame, inliningTarget, vSlots.tp_richcmp(), v, w, op); + if (notImplemented2Profile.profile(inliningTarget, result != PNotImplemented.NOT_IMPLEMENTED)) { + return result; + } + } + if (wSlots.tp_richcmp() != null && !checkedReverseOp) { + Object result = callRichCmpSwapped.execute(frame, inliningTarget, wSlots.tp_richcmp(), w, v, op.getSwapped()); + if (notImplemented3Profile.profile(inliningTarget, result != PNotImplemented.NOT_IMPLEMENTED)) { + return result; + } + } + // If neither object implements it, provide a sensible default for == and !=, but raise + // an exception for ordering. + return switch (op) { + case Py_EQ, Py_NE -> isNode.execute(v, w) == op.isEq(); + default -> + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.NOT_SUPPORTED_BETWEEN_INSTANCES, op.getOpName(), v, w); + }; + } + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectRichCompareBool.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectRichCompareBool.java index e2091decdc..f4449ef6dd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectRichCompareBool.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectRichCompareBool.java @@ -40,650 +40,134 @@ */ package com.oracle.graal.python.lib; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; -import static com.oracle.graal.python.builtins.objects.str.StringUtils.compareStrings; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; - -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.ints.PInt; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; -import com.oracle.graal.python.lib.PyObjectRichCompareBoolFactory.EqNodeGen; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; -import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; -import com.oracle.graal.python.nodes.classes.IsSubtypeNode; -import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.builtins.objects.floats.PFloat; +import com.oracle.graal.python.lib.PyObjectRichCompare.GenericRichCompare; +import com.oracle.graal.python.lib.PyObjectRichCompareBoolNodeGen.CachedPyObjectRichCompareBoolNodeGen; import com.oracle.graal.python.nodes.object.IsNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.util.OverflowException; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; +import com.oracle.graal.python.util.PythonUtils; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleString; +import com.oracle.truffle.api.strings.TruffleString.EqualNode; /** - * Performs one of comparison operations. The nodes for all operations are inner classes of this - * class - {@link EqNode}, {@link NeNode}, {@link LtNode}, {@link LeNode}, {@link GtNode} and - * {@link GeNode}. Equivalent of CPython's {@code PyObject_RichCompareBool} with the difference that - * the operation is selected by picking particular inner class. Note there is a small difference in - * behavior between {@code PyObject_RichCompareBool} and {@code PyObject_RichCompare} followed by - * {@code PyObject_IsTrue} - the objects are compared for referential equality first (when doing - * equality comparison) before calling the special method. This makes a difference for objects that - * report they are unequal to themselves (i.e. {@code NaN}). + * Performs one of comparison operations. Equivalent of CPython's {@code PyObject_RichCompareBool}. + * Note there is a small difference in behavior between {@code PyObject_RichCompareBool} and + * {@code PyObject_RichCompare} followed by {@code PyObject_IsTrue} (see + * bpo4296) - the objects are compared for + * referential equality first (when doing equality comparison) before calling the special method. + * This makes a difference for objects that report they are unequal to themselves (i.e. + * {@code NaN}). Since we do not maintain identity for unboxed float objects, we cannot fully match + * the CPython behavior - we treat all NaNs with exactly the same bits as equal. */ -public abstract class PyObjectRichCompareBool { - - public abstract static class Comparison { - protected boolean op(boolean a, boolean b) { - throw CompilerDirectives.shouldNotReachHere("abstract method"); - } - - protected boolean op(int a, int b) { - throw CompilerDirectives.shouldNotReachHere("abstract method"); - } - - protected boolean op(long a, long b) { - throw CompilerDirectives.shouldNotReachHere("abstract method"); - } - - protected boolean op(double a, double b) { - throw CompilerDirectives.shouldNotReachHere("abstract method"); - } - - protected SpecialMethodSlot getSlot() { - throw CompilerDirectives.shouldNotReachHere("abstract method"); - } - - protected SpecialMethodSlot getReverseSlot() { - throw CompilerDirectives.shouldNotReachHere("abstract method"); - } - - protected boolean needsIdentityComparison() { - return false; - } - - protected boolean identityComparisonResult() { - throw CompilerDirectives.shouldNotReachHere("abstract method"); - } - - protected boolean doDefault(Node inliningTarget, PRaiseNode.Lazy raiseNode, Object a, Object b) { - throw CompilerDirectives.shouldNotReachHere("abstract method"); - } +@GenerateInline +@GenerateCached(false) +@GenerateUncached +@TypeSystemReference(PythonIntegerTypes.class) +public abstract class PyObjectRichCompareBool extends Node { + public abstract boolean execute(Frame frame, Node inliningTarget, Object a, Object b, RichCmpOp op); + + public final boolean executeEq(Frame frame, Node inliningTarget, Object a, Object b) { + return execute(frame, inliningTarget, a, b, RichCmpOp.Py_EQ); } - @SuppressWarnings("unused") - @GenerateCached(false) - @GenerateInline(false) - @GenerateUncached(false) - public abstract static class ComparisonBaseNode extends PNodeWithContext { - // Overridden by the implementors to call execute with the right Comparison strategy - public boolean compare(Frame frame, Node inliningTarget, Object a, Object b) { - throw CompilerDirectives.shouldNotReachHere("abstract method"); - } - - protected abstract boolean execute(Frame frame, Node inliningTarget, Object a, Object b, Comparison cmp); - - @Specialization - static boolean doBB(boolean a, boolean b, Comparison cmp) { - return cmp.op(a, b); - } - - @Specialization - static boolean doII(int a, int b, Comparison cmp) { - return cmp.op(a, b); - } - - @Specialization - static boolean doIL(int a, long b, Comparison cmp) { - return cmp.op(a, b); - } - - @Specialization - static boolean doID(int a, double b, Comparison cmp) { - return cmp.op(a, b); - } - - @Specialization(guards = "isBuiltinPInt(b)", rewriteOn = OverflowException.class) - static boolean doIPNoOVerflow(int a, PInt b, Comparison cmp) throws OverflowException { - return cmp.op(a, b.intValueExact()); - } - - @Specialization(guards = "isBuiltinPInt(b)", replaces = "doIPNoOVerflow") - static boolean doIP(int a, PInt b, Comparison cmp) { - try { - return cmp.op(a, b.intValueExact()); - } catch (OverflowException e) { - return false; - } - } - - @Specialization - static boolean doLL(long a, long b, Comparison cmp) { - return cmp.op(a, b); - } - - @Specialization - static boolean doLI(long a, int b, Comparison cmp) { - return cmp.op(a, b); - } - - @Specialization - static boolean doLD(long a, double b, Comparison cmp) { - return cmp.op(a, b); - } - - @Specialization(guards = "isBuiltinPInt(b)", rewriteOn = OverflowException.class) - static boolean doLPNoOVerflow(long a, PInt b, Comparison cmp) throws OverflowException { - return cmp.op(a, b.longValueExact()); - } - - @Specialization(guards = "isBuiltinPInt(b)", replaces = "doLPNoOVerflow") - static boolean doLP(long a, PInt b, Comparison cmp) { - try { - return cmp.op(a, b.longValueExact()); - } catch (OverflowException e) { - return false; - } - } - - @Specialization(guards = "isBuiltinPInt(a)", rewriteOn = OverflowException.class) - static boolean doPINoOverflow(PInt a, int b, Comparison cmp) throws OverflowException { - return cmp.op(a.intValueExact(), b); - } - - @Specialization(guards = "isBuiltinPInt(a)", replaces = "doPINoOverflow") - static boolean doPI(PInt a, int b, Comparison cmp) { - try { - return cmp.op(a.intValueExact(), b); - } catch (OverflowException e) { - return false; - } - } - - @Specialization(guards = "isBuiltinPInt(a)", rewriteOn = OverflowException.class) - static boolean doPLNoOverflow(PInt a, long b, Comparison cmp) throws OverflowException { - return cmp.op(a.longValueExact(), b); - } - - @Specialization(guards = "isBuiltinPInt(a)", replaces = "doPLNoOverflow") - static boolean doPL(PInt a, long b, Comparison cmp) { - try { - return cmp.op(a.longValueExact(), b); - } catch (OverflowException e) { - return false; - } - } - - @Specialization(guards = {"isBuiltinPInt(a)", "isBuiltinPInt(b)"}) - @TruffleBoundary - static boolean doPP(PInt a, PInt b, Comparison cmp) { - return cmp.op(a.compareTo(b), 0); - } - - @Specialization - static boolean doDD(double a, double b, Comparison cmp) { - // nb: Eq subclass handles NaN identity - return cmp.op(a, b); - } - - @Specialization - static boolean doDI(double a, int b, Comparison cmp) { - return cmp.op(a, b); - } - - @Specialization - static boolean doDL(double a, long b, Comparison cmp) { - return cmp.op(a, b); - } - - @Specialization - @InliningCutoff - static boolean doGeneric(VirtualFrame frame, Node inliningTarget, Object a, Object b, Comparison cmp, - @Cached(inline = false) IsNode isNode, - @Cached GetClassNode getClassA, - @Cached GetClassNode getClassB, - @Cached InlinedConditionProfile reversedFirst, - @Cached IsSameTypeNode isSameTypeNode, - @Cached(inline = false) IsSubtypeNode isSubtypeNode, - @Cached(parameters = "cmp.getSlot()", inline = false) LookupSpecialMethodSlotNode lookupMethod, - @Cached(parameters = "cmp.getReverseSlot()", inline = false) LookupSpecialMethodSlotNode lookupReverseMethod, - @Cached(inline = false) CallBinaryMethodNode callMethod, - @Cached(inline = false) CallBinaryMethodNode callReverseMethod, - @Cached PyObjectIsTrueNode isTrueNode, - @Cached PRaiseNode.Lazy raiseNode) { - if (cmp.needsIdentityComparison()) { - if (isNode.execute(a, b)) { - return cmp.identityComparisonResult(); - } - } - boolean checkedReverseOp = false; - Object aType = getClassA.execute(inliningTarget, a); - Object bType = getClassB.execute(inliningTarget, b); - if (reversedFirst.profile(inliningTarget, !isSameTypeNode.execute(inliningTarget, aType, bType) && - isSubtypeNode.execute(bType, aType))) { - checkedReverseOp = true; - Object reverseMethod = lookupMethodIgnoreDescriptorError(frame, lookupReverseMethod, bType, b); - if (reverseMethod != PNone.NO_VALUE) { - Object result = callReverseMethod.executeObject(frame, reverseMethod, b, a); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return isTrueNode.execute(frame, result); - } - } - } - Object method = lookupMethodIgnoreDescriptorError(frame, lookupMethod, aType, a); - if (method != PNone.NO_VALUE) { - Object result = callMethod.executeObject(frame, method, a, b); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return isTrueNode.execute(frame, result); - } - } - if (!checkedReverseOp) { - Object reverseMethod = lookupMethodIgnoreDescriptorError(frame, lookupReverseMethod, bType, b); - if (reverseMethod != PNone.NO_VALUE) { - Object result = callReverseMethod.executeObject(frame, reverseMethod, b, a); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return isTrueNode.execute(frame, result); - } - } - } - return cmp.doDefault(inliningTarget, raiseNode, a, b); - } - - private static Object lookupMethodIgnoreDescriptorError(VirtualFrame frame, LookupSpecialMethodSlotNode lookupMethod, Object aType, Object a) { - try { - return lookupMethod.execute(frame, aType, a); - } catch (PException e) { - return PNone.NO_VALUE; - } - } + public final boolean executeCached(Frame frame, Object a, Object b, RichCmpOp op) { + return execute(frame, null, a, b, op); } - @GenerateUncached - @GenerateInline(inlineByDefault = true) - public abstract static class EqNode extends ComparisonBaseNode { - private static final class EqComparison extends Comparison { - @Override - protected boolean op(boolean a, boolean b) { - return a == b; - } - - @Override - protected boolean op(int a, int b) { - return a == b; - } - - @Override - protected boolean op(long a, long b) { - return a == b; - } - - @Override - protected boolean op(double a, double b) { - return a == b || (Double.isNaN(a) && Double.isNaN(b)); - } - - @Override - protected SpecialMethodSlot getSlot() { - return SpecialMethodSlot.Eq; - } - - @Override - protected SpecialMethodSlot getReverseSlot() { - return SpecialMethodSlot.Eq; - } - - @Override - protected boolean needsIdentityComparison() { - return true; - } - - @Override - protected boolean identityComparisonResult() { - return true; - } - - @Override - protected boolean doDefault(Node inliningTarget, PRaiseNode.Lazy raiseNode, Object a, Object b) { - // Already compared for identity - return false; - } - } - - private static final EqComparison CMP = new EqComparison(); - - public final boolean compareCached(Frame frame, Object a, Object b) { - return compare(frame, this, a, b); - } - - @Override - public final boolean compare(Frame frame, Node inliningTarget, Object a, Object b) { - return execute(frame, inliningTarget, a, b, CMP); - } - - public static boolean compareUncached(Object a, Object b) { - return EqNodeGen.getUncached().compare(null, null, a, b); - } - - @Specialization(insertBefore = "doGeneric") - @InliningCutoff - static boolean doSS(TruffleString a, TruffleString b, @SuppressWarnings("unused") Comparison cmp, - @Cached(inline = false) TruffleString.EqualNode equalNode) { - return equalNode.execute(a, b, TS_ENCODING); - } - - @NeverDefault - public static EqNode create() { - return PyObjectRichCompareBoolFactory.EqNodeGen.create(); - } - - public static EqNode getUncached() { - return PyObjectRichCompareBoolFactory.EqNodeGen.getUncached(); - } + public static boolean executeUncached(Object a, Object b, RichCmpOp op) { + return getUncached().execute(null, null, a, b, op); } - @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class NeNode extends ComparisonBaseNode { - private static final class NeComparison extends Comparison { - @Override - protected boolean op(boolean a, boolean b) { - return a != b; - } - - @Override - protected boolean op(int a, int b) { - return a != b; - } - - @Override - protected boolean op(long a, long b) { - return a != b; - } - - @Override - protected boolean op(double a, double b) { - return a != b; - } - - @Override - protected SpecialMethodSlot getSlot() { - return SpecialMethodSlot.Ne; - } - - @Override - protected SpecialMethodSlot getReverseSlot() { - return SpecialMethodSlot.Ne; - } - - @Override - protected boolean needsIdentityComparison() { - return true; - } - - @Override - protected boolean identityComparisonResult() { - return false; - } - - @Override - @SuppressWarnings("unused") - protected boolean doDefault(Node inliningTarget, PRaiseNode.Lazy raiseNode, Object a, Object b) { - // Already compared for identity - return true; - } - } - - private static final NeComparison CMP = new NeComparison(); - - @Override - public final boolean compare(Frame frame, Node inliningTarget, Object a, Object b) { - return execute(frame, inliningTarget, a, b, CMP); - } - - @Specialization(insertBefore = "doGeneric") - static boolean doSS(TruffleString a, TruffleString b, @SuppressWarnings("unused") Comparison cmp, - @Cached(inline = false) TruffleString.EqualNode equalNode) { - return !equalNode.execute(a, b, TS_ENCODING); - } + public static boolean executeEqUncached(Object a, Object b) { + return executeUncached(a, b, RichCmpOp.Py_EQ); } - @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class LtNode extends ComparisonBaseNode { - - private static final class LtComparison extends Comparison { - @Override - protected boolean op(boolean a, boolean b) { - return !a && b; - } - - @Override - protected boolean op(int a, int b) { - return a < b; - } - - @Override - protected boolean op(long a, long b) { - return a < b; - } - - @Override - protected boolean op(double a, double b) { - return a < b; - } - - @Override - protected SpecialMethodSlot getSlot() { - return SpecialMethodSlot.Lt; - } - - @Override - protected SpecialMethodSlot getReverseSlot() { - return SpecialMethodSlot.Gt; - } - - @Override - @SuppressWarnings("unused") - protected boolean doDefault(Node inliningTarget, PRaiseNode.Lazy raiseNode, Object a, Object b) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.NOT_SUPPORTED_BETWEEN_INSTANCES, "<", a, b); - } - } - - public static final LtComparison CMP = new LtComparison(); - - @Override - public boolean compare(Frame frame, Node inliningTarget, Object a, Object b) { - return execute(frame, inliningTarget, a, b, CMP); - } - - @Specialization(insertBefore = "doGeneric") - static boolean doSS(TruffleString a, TruffleString b, @SuppressWarnings("unused") Comparison cmp, - @Cached(inline = false) TruffleString.CompareIntsUTF32Node compareIntsUTF32Node) { - return compareStrings(a, b, compareIntsUTF32Node) < 0; - } + @Specialization + static boolean doInts(int a, int b, RichCmpOp op) { + return op.compare(a, b); } - @GenerateUncached - @GenerateInline(inlineByDefault = true) - public abstract static class LeNode extends ComparisonBaseNode { - - private static final class LeComparison extends Comparison { - @Override - protected boolean op(boolean a, boolean b) { - return b || !a; - } - - @Override - protected boolean op(int a, int b) { - return a <= b; - } - - @Override - protected boolean op(long a, long b) { - return a <= b; - } - - @Override - protected boolean op(double a, double b) { - return a <= b; - } - - @Override - protected SpecialMethodSlot getSlot() { - return SpecialMethodSlot.Le; - } - - @Override - protected SpecialMethodSlot getReverseSlot() { - return SpecialMethodSlot.Ge; - } - - @Override - protected boolean doDefault(Node inliningTarget, PRaiseNode.Lazy raiseNode, Object a, Object b) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.NOT_SUPPORTED_BETWEEN_INSTANCES, "<=", a, b); - } - } - - public static final LeComparison CMP = new LeComparison(); - - @Override - public final boolean compare(Frame frame, Node inliningTarget, Object a, Object b) { - return execute(frame, inliningTarget, a, b, CMP); - } - - @Specialization(insertBefore = "doGeneric") - static boolean doSS(TruffleString a, TruffleString b, @SuppressWarnings("unused") Comparison cmp, - @Cached(inline = false) TruffleString.CompareIntsUTF32Node compareIntsUTF32Node) { - return compareStrings(a, b, compareIntsUTF32Node) <= 0; - } + public static boolean compareWithFakeIdentity(RichCmpOp op, double a, double b) { + // CPython checks identity of the float objects first, we cannot do that so we chose to + // report the same NaN bit patterns as identical + return switch (op) { + case Py_LT -> a < b; + case Py_LE -> a <= b; + case Py_EQ, Py_NE -> PFloat.areIdentical(a, b) == op.isEq(); + case Py_GT -> a > b; + case Py_GE -> a >= b; + }; } - @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class GtNode extends ComparisonBaseNode { - - private static final class GtComparison extends Comparison { - @Override - protected boolean op(boolean a, boolean b) { - return a && !b; - } - - @Override - protected boolean op(int a, int b) { - return a > b; - } - - @Override - protected boolean op(long a, long b) { - return a > b; - } - - @Override - protected boolean op(double a, double b) { - return a > b; - } + @Specialization + static boolean doDoubles(double a, double b, RichCmpOp op) { + return compareWithFakeIdentity(op, a, b); + } - @Override - protected SpecialMethodSlot getSlot() { - return SpecialMethodSlot.Gt; - } + @Specialization + static boolean doLongs(long a, long b, RichCmpOp op) { + return op.compare(a, b); + } - @Override - protected SpecialMethodSlot getReverseSlot() { - return SpecialMethodSlot.Lt; - } + @Specialization(guards = "op.isEqOrNe()") + static boolean doStrings(TruffleString a, TruffleString b, RichCmpOp op, + @Cached EqualNode equalNode) { + return equalNode.execute(a, b, PythonUtils.TS_ENCODING) == op.isEq(); + } - @Override - protected boolean doDefault(Node inliningTarget, PRaiseNode.Lazy raiseNode, Object a, Object b) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.NOT_SUPPORTED_BETWEEN_INSTANCES, ">", a, b); + @Fallback + static boolean doIt(VirtualFrame frame, Object a, Object b, RichCmpOp op, + @Cached IsNode isNode, + @Cached(inline = false) GenericRichCompare richCompare, + @Cached PyObjectIsTrueNode isTrueNode) { + // CPython fast-path: Quick result when objects are the same. Guarantees that identity + // implies equality. + if (op.isEqOrNe()) { + if (isNode.execute(a, b)) { + return op.isEq(); } } + Object result = richCompare.execute(frame, a, b, op); + return isTrueNode.execute(frame, result); + } - public static final GtComparison CMP = new GtComparison(); - - @Override - public final boolean compare(Frame frame, Node inliningTarget, Object a, Object b) { - return execute(frame, inliningTarget, a, b, CMP); - } - - @Specialization(insertBefore = "doGeneric") - static boolean doSS(TruffleString a, TruffleString b, @SuppressWarnings("unused") Comparison cmp, - @Cached(inline = false) TruffleString.CompareIntsUTF32Node compareIntsUTF32Node) { - return compareStrings(a, b, compareIntsUTF32Node) > 0; - } + public static PyObjectRichCompareBool getUncached() { + return PyObjectRichCompareBoolNodeGen.getUncached(); } + @GenerateInline(false) @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class GeNode extends ComparisonBaseNode { - - private static final class GeComparison extends Comparison { - @Override - protected boolean op(boolean a, boolean b) { - return a || !b; - } + public abstract static class CachedPyObjectRichCompareBool extends Node { + public abstract boolean execute(Frame frame, Object a, Object b, RichCmpOp op); - @Override - protected boolean op(int a, int b) { - return a >= b; - } - - @Override - protected boolean op(long a, long b) { - return a >= b; - } - - @Override - protected boolean op(double a, double b) { - return a >= b; - } - - @Override - protected SpecialMethodSlot getSlot() { - return SpecialMethodSlot.Ge; - } - - @Override - protected SpecialMethodSlot getReverseSlot() { - return SpecialMethodSlot.Le; - } - - @Override - protected boolean doDefault(Node inliningTarget, Lazy raiseNode, Object a, Object b) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.NOT_SUPPORTED_BETWEEN_INSTANCES, ">=", a, b); - } + public final boolean executeEq(Frame frame, Object a, Object b) { + return execute(frame, a, b, RichCmpOp.Py_EQ); } - public static final GeComparison CMP = new GeComparison(); + @Specialization + static boolean doIt(Frame frame, Object a, Object b, RichCmpOp op, + @Bind Node inliningTarget, + @Cached PyObjectRichCompareBool delegate) { + return delegate.execute(frame, inliningTarget, a, b, op); + } - @Override - public final boolean compare(Frame frame, Node inliningTarget, Object a, Object b) { - return execute(frame, inliningTarget, a, b, CMP); + public static CachedPyObjectRichCompareBool create() { + return CachedPyObjectRichCompareBoolNodeGen.create(); } - @Specialization(insertBefore = "doGeneric") - static boolean doSS(TruffleString a, TruffleString b, @SuppressWarnings("unused") Comparison cmp, - @Cached(inline = false) TruffleString.CompareIntsUTF32Node compareIntsUTF32Node) { - return compareStrings(a, b, compareIntsUTF32Node) >= 0; + public static CachedPyObjectRichCompareBool getUncached() { + return CachedPyObjectRichCompareBoolNodeGen.getUncached(); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSetAttr.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSetAttr.java index f760e83822..a819ccc2ce 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSetAttr.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSetAttr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,20 +47,17 @@ import static com.oracle.graal.python.nodes.ErrorMessages.P_HAS_RO_ATTRS_S_TO_DELETE; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSetAttr.CallSlotSetAttrNode; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; @@ -76,7 +73,6 @@ @GenerateUncached @GenerateInline(inlineByDefault = true) @GenerateCached -@ImportStatic(SpecialMethodSlot.class) public abstract class PyObjectSetAttr extends PNodeWithContext { public static void executeUncached(Object receiver, TruffleString name, Object value) { PyObjectSetAttr.getUncached().execute(null, null, receiver, name, value); @@ -96,6 +92,10 @@ public final void deleteCached(Frame frame, Object receiver, TruffleString name) execute(frame, null, receiver, name, PNone.NO_VALUE); } + public static void deleteUncached(Object receiver, TruffleString name) { + executeUncached(receiver, name, PNone.NO_VALUE); + } + public final void delete(Frame frame, Node inliningTarget, Object receiver, TruffleString name) { execute(frame, inliningTarget, receiver, name, PNone.NO_VALUE); } @@ -104,7 +104,7 @@ public final void delete(Frame frame, Node inliningTarget, Object receiver, Truf static void setFixedAttr(Frame frame, Node inliningTarget, Object self, @SuppressWarnings("unused") TruffleString name, Object value, @SuppressWarnings("unused") @Cached("name") TruffleString cachedName, @Shared @Cached GetObjectSlotsNode getSlotsNode, - @Shared @Cached PRaiseNode.Lazy raise, + @Shared @Cached PRaiseNode raise, @Shared @Cached CallSlotSetAttrNode callSetAttr) { assert value != null; // should use PNone.NO_VALUE TpSlots slots = getSlotsNode.execute(inliningTarget, self); @@ -119,13 +119,13 @@ static void setFixedAttr(Frame frame, Node inliningTarget, Object self, @Suppres @InliningCutoff static void doDynamicAttr(Frame frame, Node inliningTarget, Object self, TruffleString name, Object value, @Shared @Cached GetObjectSlotsNode getSlotsNode, - @Shared @Cached PRaiseNode.Lazy raise, + @Shared @Cached PRaiseNode raise, @Shared @Cached CallSlotSetAttrNode callSetAttr) { setFixedAttr(frame, inliningTarget, self, name, value, name, getSlotsNode, raise, callSetAttr); } @InliningCutoff - static void raiseNoSlotError(Node inliningTarget, Object self, Object name, Object value, Lazy raise, TpSlots slots) { + static void raiseNoSlotError(Node inliningTarget, Object self, Object name, Object value, PRaiseNode raise, TpSlots slots) { TruffleString message; boolean isDelete = value == PNone.NO_VALUE; if (slots.combined_tp_getattro_getattr() == null) { @@ -133,7 +133,7 @@ static void raiseNoSlotError(Node inliningTarget, Object self, Object name, Obje } else { message = isDelete ? P_HAS_RO_ATTRS_S_TO_DELETE : P_HAS_RO_ATTRS_S_TO_ASSIGN; } - throw raise.get(inliningTarget).raise(TypeError, message, self, name); + throw raise.raise(inliningTarget, TypeError, message, self, name); } @NeverDefault diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSetAttrO.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSetAttrO.java index 11f29f6414..88c52f2a02 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSetAttrO.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSetAttrO.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,7 +44,6 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.str.PString; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSetAttr.CallSlotSetAttrONode; @@ -59,7 +58,6 @@ import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; @@ -72,7 +70,6 @@ @GenerateUncached @GenerateInline(inlineByDefault = true) @GenerateCached -@ImportStatic(SpecialMethodSlot.class) public abstract class PyObjectSetAttrO extends PNodeWithContext { public static void executeUncached(Object receiver, Object name, Object value) { PyObjectSetAttrONodeGen.getUncached().execute(null, null, receiver, name, value); @@ -117,11 +114,11 @@ public abstract static class PyObjectSetAttrOGeneric extends Node { static void doIt(Frame frame, Object self, Object nameObj, Object value, @Bind("this") Node inliningTarget, @Cached PyUnicodeCheckNode unicodeCheckNode, - @Cached PRaiseNode.Lazy raise, + @Cached PRaiseNode raise, @Cached GetObjectSlotsNode getSlotsNode, @Cached CallSlotSetAttrONode callSetAttr) { if (!unicodeCheckNode.execute(inliningTarget, nameObj)) { - throw raise.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ATTR_NAME_MUST_BE_STRING, nameObj); + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ATTR_NAME_MUST_BE_STRING, nameObj); } assert value != null; // should use PNone.NO_VALUE TpSlots slots = getSlotsNode.execute(inliningTarget, self); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSetItem.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSetItem.java index 1b5def6586..67e44e2ca2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSetItem.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSetItem.java @@ -53,6 +53,7 @@ import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Fallback; @@ -133,8 +134,8 @@ static void doSequence(VirtualFrame frame, Node inliningTarget, Object object, T @Fallback @InliningCutoff static void error(Object object, @SuppressWarnings("unused") TpSlots slots, @SuppressWarnings("unused") Object key, @SuppressWarnings("unused") Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(TypeError, ErrorMessages.OBJ_DOES_NOT_SUPPORT_ITEM_ASSIGMENT, object); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.OBJ_DOES_NOT_SUPPORT_ITEM_ASSIGMENT, object); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSizeGenericNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSizeGenericNode.java index c4fe6172d2..be578b19c1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSizeGenericNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSizeGenericNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,7 +42,6 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen; @@ -52,7 +51,6 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; @@ -60,7 +58,6 @@ // Note: this has to be a top-level class because of bug/restriction in Truffle DSL @GenerateUncached -@ImportStatic(SpecialMethodSlot.class) @GenerateInline(false) // intentionally lazy initialized... abstract class PyObjectSizeGenericNode extends Node { abstract int execute(Frame frame, Object object); @@ -70,11 +67,11 @@ static int doIt(VirtualFrame frame, Object object, @Bind("this") Node inliningTarget, @Cached GetObjectSlotsNode getTpSlotsNode, @Cached TpSlotLen.CallSlotLenNode callSlotLenNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TpSlots slots = getTpSlotsNode.execute(inliningTarget, object); if (slots.combined_sq_mp_length() != null) { return callSlotLenNode.execute(frame, inliningTarget, slots.combined_sq_mp_length(), object); } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.OBJ_HAS_NO_LEN, object); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.OBJ_HAS_NO_LEN, object); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSizeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSizeNode.java index c77ef6c297..aeee82ce9e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSizeNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectSizeNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -79,9 +79,6 @@ @GenerateInline(inlineByDefault = true) @GenerateCached() public abstract class PyObjectSizeNode extends PNodeWithContext { - public static int executeUncached(Frame frame, Object object) { - return PyObjectSizeNodeGen.getUncached().execute(frame, null, object); - } public static int executeUncached(Object object) { return PyObjectSizeNodeGen.getUncached().execute(null, null, object); @@ -146,9 +143,9 @@ static int doOthers(VirtualFrame frame, Object object, return genericNode.execute(frame, object); } - static int checkLen(PRaiseNode raiseNode, int len) { + static int checkLen(Node inliningTarget, PRaiseNode raiseNode, int len) { if (len < 0) { - throw raiseNode.raise(ValueError, ErrorMessages.LEN_SHOULD_RETURN_GT_ZERO); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.LEN_SHOULD_RETURN_GT_ZERO); } return len; } @@ -167,10 +164,10 @@ public static int convertAndCheckLen(VirtualFrame frame, Node inliningTarget, Ob * error. */ len = castLossy.execute(inliningTarget, index); - checkLen(raiseNode, len); + checkLen(inliningTarget, raiseNode, len); throw e; } - return checkLen(raiseNode, len); + return checkLen(inliningTarget, raiseNode, len); } @NeverDefault diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectStrAsObjectNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectStrAsObjectNode.java index dfb4dfb002..ddf29de641 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectStrAsObjectNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectStrAsObjectNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,22 +47,19 @@ import static com.oracle.graal.python.nodes.truffle.TruffleStringMigrationHelpers.assertNoJavaString; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.str.PString; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotUnaryFunc.CallSlotUnaryNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; -import com.oracle.graal.python.nodes.classes.IsSubtypeNode; -import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; @@ -81,7 +78,6 @@ @GenerateUncached @GenerateInline(inlineByDefault = true) @GenerateCached -@ImportStatic(SpecialMethodSlot.class) public abstract class PyObjectStrAsObjectNode extends PNodeWithContext { public final Object executeCached(Frame frame, Object object) { return execute(frame, this, object); @@ -111,25 +107,29 @@ TruffleString str(long object, @Specialization(guards = "!isTruffleString(obj)") static Object str(VirtualFrame frame, Node inliningTarget, Object obj, - @Cached GetClassNode getClassNode, - @Cached(parameters = "Str", inline = false) LookupSpecialMethodSlotNode lookupStr, - @Cached(inline = false) CallUnaryMethodNode callStr, - @Cached GetClassNode getResultClassNode, - @Cached(inline = false) IsSubtypeNode isSubtypeNode, - @Cached PRaiseNode.Lazy raiseNode) { - Object type = getClassNode.execute(inliningTarget, obj); - Object strDescr = lookupStr.execute(frame, type, obj); - // All our objects should have __str__ - assert strDescr != PNone.NO_VALUE; - Object result = callStr.executeObject(frame, strDescr, obj); - result = assertNoJavaString(result); - if (result instanceof TruffleString || isSubtypeNode.execute(getResultClassNode.execute(inliningTarget, result), PythonBuiltinClassType.PString)) { + @Cached GetObjectSlotsNode getSlots, + @Cached CallSlotUnaryNode callSlot, + @Cached PyObjectReprAsObjectNode repr, + @Cached PyUnicodeCheckNode checkNode, + @Cached PRaiseNode raiseNode) { + TpSlots slots = getSlots.execute(inliningTarget, obj); + if (slots.tp_str() == null) { + return repr.execute(frame, inliningTarget, obj); + } + Object result = callSlot.execute(frame, inliningTarget, slots.tp_str(), obj); + assertNoJavaString(result); + if (checkNode.execute(inliningTarget, result)) { return result; } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.RETURNED_NON_STRING, T___STR__, result); + throw raiseTypeError(inliningTarget, raiseNode, result); } } + @InliningCutoff + private static PException raiseTypeError(Node inliningTarget, PRaiseNode raiseNode, Object result) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.RETURNED_NON_STRING, T___STR__, result); + } + @NeverDefault public static PyObjectStrAsObjectNode create() { return PyObjectStrAsObjectNodeGen.create(); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceConcat.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceConcatNode.java similarity index 71% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceConcat.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceConcatNode.java index b428605f03..e7984682bb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceConcat.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceConcatNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,32 +42,31 @@ import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ListGeneralizationNode; import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.CallSlotBinaryFuncNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpSlot; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.ReversibleSlot; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @@ -76,29 +75,23 @@ @GenerateInline @GenerateCached(false) -public abstract class PySequenceConcat extends PNodeWithContext { +public abstract class PySequenceConcatNode extends PNodeWithContext { public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object v, Object w); - @NeverDefault - protected static SequenceStorageNodes.ConcatNode createConcat() { - return SequenceStorageNodes.ConcatNode.create(ListGeneralizationNode::create); - } - - @Specialization + @Specialization(guards = {"isBuiltinList(left)", "isBuiltinList(right)"}) static PList doPList(Node inliningTarget, PList left, PList right, - @Exclusive @Cached GetClassNode getClassNode, - @Shared @Cached(value = "createConcat()", inline = false) SequenceStorageNodes.ConcatNode concatNode, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - SequenceStorage newStore = concatNode.execute(left.getSequenceStorage(), right.getSequenceStorage()); - return factory.createList(getClassNode.execute(inliningTarget, left), newStore); + @Shared @Cached SequenceStorageNodes.ConcatListOrTupleNode concatNode, + @Bind PythonLanguage language) { + SequenceStorage newStore = concatNode.execute(inliningTarget, left.getSequenceStorage(), right.getSequenceStorage()); + return PFactory.createList(language, newStore); } @Specialization(guards = {"isBuiltinTuple(left)", "isBuiltinTuple(right)"}) - static PTuple doTuple(PTuple left, PTuple right, - @Shared @Cached(value = "createConcat()", inline = false) SequenceStorageNodes.ConcatNode concatNode, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - SequenceStorage concatenated = concatNode.execute(left.getSequenceStorage(), right.getSequenceStorage()); - return factory.createTuple(concatenated); + static PTuple doTuple(Node inliningTarget, PTuple left, PTuple right, + @Shared @Cached SequenceStorageNodes.ConcatListOrTupleNode concatNode, + @Bind PythonLanguage language) { + SequenceStorage concatenated = concatNode.execute(inliningTarget, left.getSequenceStorage(), right.getSequenceStorage()); + return PFactory.createTuple(language, concatenated); } @Specialization @@ -119,7 +112,7 @@ static Object doIt(VirtualFrame frame, Node inliningTarget, Object v, Object w, @Cached InlinedBranchProfile hasNbAddSlot, @Cached InlinedBranchProfile hasNbAddResult, @Cached CallSlotBinaryFuncNode callBinarySlotNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { Object classV = getVClass.execute(inliningTarget, v); TpSlots slotsV = getVSlots.execute(inliningTarget, classV); if (slotsV.sq_concat() != null) { @@ -128,22 +121,18 @@ static Object doIt(VirtualFrame frame, Node inliningTarget, Object v, Object w, if (pySeqCheckV.execute(inliningTarget, v) && pySeqCheckW.execute(inliningTarget, w)) { Object classW = getWClass.execute(inliningTarget, w); TpSlots slotsW = getWSlots.execute(inliningTarget, classW); - TpSlot slotV = slotsV.nb_add(); - TpSlot slotW = slotsW.nb_add(); - if (slotV != null || slotW != null) { - hasNbAddSlot.enter(inliningTarget); - Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotV, w, classW, slotW, BinaryOpSlot.NB_ADD); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - hasNbAddResult.enter(inliningTarget); - return result; - } + hasNbAddSlot.enter(inliningTarget); + Object result = callBinaryOp1Node.execute(frame, inliningTarget, v, classV, slotsV, w, classW, slotsW, ReversibleSlot.NB_ADD); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + hasNbAddResult.enter(inliningTarget); + return result; } } return raiseNotSupported(inliningTarget, v, raiseNode); } @InliningCutoff - private static PException raiseNotSupported(Node inliningTarget, Object v, PRaiseNode.Lazy raiseNode) { - return raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_CANT_BE_CONCATENATED, v); + private static PException raiseNotSupported(Node inliningTarget, Object v, PRaiseNode raiseNode) { + return raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_CANT_BE_CONCATENATED, v); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceContainsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceContainsNode.java index 0fa4539e05..7fd3e1120a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceContainsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceContainsNode.java @@ -40,24 +40,20 @@ */ package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.CallSlotSqContainsNode; import com.oracle.graal.python.lib.PySequenceIterSearchNode.LazyPySequenceIterSeachNode; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; /** * Equivalent of CPython's {@code PySequence_Contains}. @@ -65,33 +61,21 @@ @GenerateUncached @GenerateInline @GenerateCached(false) -@ImportStatic(SpecialMethodSlot.class) -public abstract class PySequenceContainsNode extends PNodeWithContext { - public abstract boolean execute(Frame frame, Node inlining, Object container, Object key); +public abstract class PySequenceContainsNode extends Node { + public abstract boolean execute(Frame frame, Node inliningTarget, Object container, Object key); @Specialization - static boolean contains(Frame frame, Node inliningTarget, Object container, Object key, - @Cached GetClassNode getReceiverClass, - @Cached(parameters = "Contains", inline = false) LookupSpecialMethodSlotNode lookupContains, - @Cached IsBuiltinObjectProfile noContainsProfile, - @Cached(inline = false) CallBinaryMethodNode callContains, - @Cached LazyPySequenceIterSeachNode iterSearch, - @Cached PyObjectIsTrueNode isTrue) { - Object type = getReceiverClass.execute(inliningTarget, container); - Object contains = PNone.NO_VALUE; - try { - contains = lookupContains.execute(frame, type, container); - } catch (PException e) { - e.expectAttributeError(inliningTarget, noContainsProfile); - } - Object result = PNotImplemented.NOT_IMPLEMENTED; - if (!(contains instanceof PNone)) { - result = callContains.executeObject(frame, contains, container, key); - } - if (result == PNotImplemented.NOT_IMPLEMENTED) { - return iterSearch.get(inliningTarget).executeCached(frame, container, key, PySequenceIterSearchNode.PY_ITERSEARCH_CONTAINS) == 1; + static boolean contains(VirtualFrame frame, Node inliningTarget, Object container, Object key, + @Cached GetClassNode getClassNode, + @Cached GetCachedTpSlotsNode getSlots, + @Cached InlinedConditionProfile hasContains, + @Cached CallSlotSqContainsNode callSlot, + @Cached LazyPySequenceIterSeachNode iterSearch) { + TpSlots slots = getSlots.execute(inliningTarget, getClassNode.execute(inliningTarget, container)); + if (hasContains.profile(inliningTarget, slots.sq_contains() != null)) { + return callSlot.execute(frame, inliningTarget, slots.sq_contains(), container, key); } else { - return isTrue.execute(frame, result); + return iterSearch.get(inliningTarget).executeCached(frame, container, key, PySequenceIterSearchNode.PY_ITERSEARCH_CONTAINS) == 1; } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceDelItemNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceDelItemNode.java index bb92067feb..582aa71259 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceDelItemNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceDelItemNode.java @@ -87,7 +87,7 @@ static void doGeneric(VirtualFrame frame, Node inliningTarget, Object object, in @Cached GetObjectSlotsNode getSlotsNode, @Cached IndexForSqSlotInt indexForSqSlot, @Cached CallSlotSqAssItemNode callSetItem, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TpSlots slots = getSlotsNode.execute(inliningTarget, object); index = indexForSqSlot.execute(frame, inliningTarget, object, slots, index); if (slots.sq_ass_item() != null) { @@ -98,11 +98,11 @@ static void doGeneric(VirtualFrame frame, Node inliningTarget, Object object, in } @InliningCutoff - static PException raiseNotSupported(Object object, Node inliningTarget, PRaiseNode.Lazy raiseNode, TpSlots slots) { + static PException raiseNotSupported(Object object, Node inliningTarget, PRaiseNode raiseNode, TpSlots slots) { TruffleString message = ErrorMessages.OBJ_DOES_NOT_SUPPORT_ITEM_DELETION; if (slots.mp_subscript() != null) { message = ErrorMessages.IS_NOT_A_SEQUENCE; } - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, message, object); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, message, object); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceGetItemNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceGetItemNode.java index 33462f56a3..e2c3e73f7f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceGetItemNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceGetItemNode.java @@ -44,7 +44,6 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.CallSlotLenNode; @@ -52,7 +51,6 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; @@ -74,7 +72,7 @@ * Equivalent of CPython's {@code PySequence_GetItem}. For native object it would only call * {@code sq_item} and never {@code mp_subscript}. */ -@ImportStatic({PGuards.class, SpecialMethodSlot.class, ExternalFunctionNodes.PExternalFunctionWrapper.class}) +@ImportStatic({PGuards.class, ExternalFunctionNodes.PExternalFunctionWrapper.class}) @GenerateInline(false) // One lazy usage, one eager usage => not worth it @GenerateUncached public abstract class PySequenceGetItemNode extends Node { @@ -90,7 +88,7 @@ static Object doGeneric(VirtualFrame frame, Object object, int index, @Cached GetObjectSlotsNode getSlotsNode, @Cached IndexForSqSlotInt indexForSqSlot, @Cached CallSlotSizeArgFun callSqItem, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TpSlots slots = getSlotsNode.execute(inliningTarget, object); index = indexForSqSlot.execute(frame, inliningTarget, object, slots, index); if (slots.sq_item() != null) { @@ -101,12 +99,12 @@ static Object doGeneric(VirtualFrame frame, Object object, int index, } @InliningCutoff - private static PException raiseNotSupported(Object object, Node inliningTarget, Lazy raiseNode, TpSlots slots) { + private static PException raiseNotSupported(Object object, Node inliningTarget, PRaiseNode raiseNode, TpSlots slots) { TruffleString message = ErrorMessages.OBJ_DOES_NOT_SUPPORT_INDEXING; if (slots.mp_subscript() != null) { message = ErrorMessages.IS_NOT_A_SEQUENCE; } - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, message, object); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, message, object); } @GenerateInline @@ -153,9 +151,9 @@ static int doGeneric(VirtualFrame frame, Node inliningTarget, Object object, TpS @Cached PyIndexCheckNode checkNode, @Cached PyNumberAsSizeNode asSizeNode, @Exclusive @Cached IndexForSqSlotInt indexForSqSlotInt, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (!checkNode.execute(inliningTarget, indexObj)) { - raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.SEQUENCE_INDEX_MUST_BE_INT_NOT_P, indexObj); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.SEQUENCE_INDEX_MUST_BE_INT_NOT_P, indexObj); } int index = asSizeNode.executeExact(frame, inliningTarget, indexObj, PythonBuiltinClassType.IndexError); return indexForSqSlotInt.execute(frame, inliningTarget, object, slots, index); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceInPlaceConcatNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceInPlaceConcatNode.java new file mode 100644 index 0000000000..e1b4970142 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceInPlaceConcatNode.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.CallSlotBinaryFuncNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PNodeWithContext; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; + +@GenerateInline +@GenerateCached(false) +public abstract class PySequenceInPlaceConcatNode extends PNodeWithContext { + public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object v, Object w); + + @Specialization + static Object doIt(VirtualFrame frame, Node inliningTarget, Object v, Object w, + @Cached GetClassNode getVClass, + @Cached GetCachedTpSlotsNode getVSlots, + @Cached GetCachedTpSlotsNode getWSlots, + @Cached GetClassNode getWClass, + @Cached PySequenceCheckNode pySeqCheckV, + @Cached PySequenceCheckNode pySeqCheckW, + @Cached CallBinaryIOp1Node callBinaryIOp1Node, + @Cached InlinedBranchProfile hasInplaceConcat, + @Cached InlinedBranchProfile hasConcat, + @Cached InlinedBranchProfile hasNbAddSlot, + @Cached InlinedBranchProfile hasNbAddResult, + @Cached CallSlotBinaryFuncNode callBinarySlotNode, + @Cached PRaiseNode raiseNode) { + Object classV = getVClass.execute(inliningTarget, v); + TpSlots slotsV = getVSlots.execute(inliningTarget, classV); + TpSlot concatSlot = null; + if (slotsV.sq_inplace_concat() != null) { + hasInplaceConcat.enter(inliningTarget); + concatSlot = slotsV.sq_inplace_concat(); + } else if (slotsV.sq_concat() != null) { + hasConcat.enter(inliningTarget); + concatSlot = slotsV.sq_concat(); + } + if (concatSlot != null) { + return callBinarySlotNode.execute(frame, inliningTarget, concatSlot, v, w); + } + if (pySeqCheckV.execute(inliningTarget, v) && pySeqCheckW.execute(inliningTarget, w)) { + Object classW = getWClass.execute(inliningTarget, w); + TpSlots slotsW = getWSlots.execute(inliningTarget, classW); + hasNbAddSlot.enter(inliningTarget); + Object result = callBinaryIOp1Node.execute(frame, inliningTarget, v, classV, slotsV, w, classW, slotsW, InplaceSlot.NB_INPLACE_ADD); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + hasNbAddResult.enter(inliningTarget); + return result; + } + } + return raiseNotSupported(inliningTarget, v, raiseNode); + } + + @InliningCutoff + private static PException raiseNotSupported(Node inliningTarget, Object v, PRaiseNode raiseNode) { + return raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_CANT_BE_CONCATENATED, v); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceInPlaceRepeatNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceInPlaceRepeatNode.java new file mode 100644 index 0000000000..e33fe8544a --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceInPlaceRepeatNode.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.objects.PNotImplemented; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.InplaceSlot; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.CallSlotSizeArgFun; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PNodeWithContext; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; + +@GenerateInline +@GenerateCached(false) +public abstract class PySequenceInPlaceRepeatNode extends PNodeWithContext { + public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object o, int count); + + @Specialization + static Object doIt(VirtualFrame frame, Node inliningTarget, Object o, int count, + @Cached GetClassNode getClassNode, + @Cached GetCachedTpSlotsNode slotsNode, + @Cached PySequenceCheckNode sequenceCheckNode, + @Cached CallBinaryIOp1Node callBinaryIOp1Node, + @Cached InlinedBranchProfile hasInplaceRepeat, + @Cached InlinedBranchProfile hasRepeat, + @Cached InlinedBranchProfile isSequence, + @Cached InlinedBranchProfile hasNbMultiplyResult, + @Cached CallSlotSizeArgFun callSlot, + @Cached PRaiseNode raiseNode) { + Object classV = getClassNode.execute(inliningTarget, o); + TpSlots slotsV = slotsNode.execute(inliningTarget, classV); + TpSlot repeatSlot = null; + if (slotsV.sq_inplace_repeat() != null) { + hasInplaceRepeat.enter(inliningTarget); + repeatSlot = slotsV.sq_inplace_repeat(); + } else if (slotsV.sq_repeat() != null) { + hasRepeat.enter(inliningTarget); + repeatSlot = slotsV.sq_repeat(); + } + if (repeatSlot != null) { + return callSlot.execute(frame, inliningTarget, repeatSlot, o, count); + } + if (sequenceCheckNode.execute(inliningTarget, o)) { + isSequence.enter(inliningTarget); + PythonBuiltinClassType countType = PythonBuiltinClassType.PInt; + Object result = callBinaryIOp1Node.execute(frame, inliningTarget, o, classV, slotsV, count, countType, countType.getSlots(), InplaceSlot.NB_INPLACE_MULTIPLY); + if (result != PNotImplemented.NOT_IMPLEMENTED) { + hasNbMultiplyResult.enter(inliningTarget); + return result; + } + } + return raiseNotSupported(inliningTarget, o, raiseNode); + } + + @InliningCutoff + private static PException raiseNotSupported(Node inliningTarget, Object v, PRaiseNode raiseNode) { + return raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_CANT_BE_REPEATED, v); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceIterSearchNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceIterSearchNode.java index 8d96d229df..a41b191157 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceIterSearchNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceIterSearchNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,33 +41,27 @@ package com.oracle.graal.python.lib; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; -import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedIntValueProfile; +import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile; /** * Equivalent of CPython's {@code _PySequence_IterSearch}. */ @GenerateUncached -@ImportStatic(SpecialMethodSlot.class) @GenerateInline(inlineByDefault = true) public abstract class PySequenceIterSearchNode extends PNodeWithContext { // return # of times obj appears in seq. @@ -91,37 +85,28 @@ public final int execute(Node inliningTarget, Object container, Object key, int static int search(Frame frame, Node inliningTarget, Object container, Object key, int operation, @Cached PyObjectGetIter getIter, @Cached IsBuiltinObjectProfile noIterProfile, - @Cached PRaiseNode.Lazy raiseNode, - @Cached GetClassNode getIterClass, - @Cached(parameters = "Next", inline = false) LookupSpecialMethodSlotNode lookupIternext, - @Cached IsBuiltinObjectProfile noNextProfile, - @Cached(inline = false) CallUnaryMethodNode callNext, - @Cached(inline = false) PyObjectRichCompareBool.EqNode eqNode, - @Cached IsBuiltinObjectProfile stopIterationProfile, + @Cached PRaiseNode raiseNode, + @Cached PyIterNextNode nextNode, + @Cached InlinedLoopConditionProfile loopProfile, + @Cached PyObjectRichCompareBool eqNode, @Cached InlinedIntValueProfile opProfile) { Object iterator; try { iterator = getIter.execute(frame, inliningTarget, container); } catch (PException e) { e.expectTypeError(inliningTarget, noIterProfile); - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.IS_NOT_A_CONTAINER, container); - } - Object next = PNone.NO_VALUE; - try { - next = lookupIternext.execute(frame, getIterClass.execute(inliningTarget, iterator), iterator); - } catch (PException e) { - e.expect(inliningTarget, PythonBuiltinClassType.AttributeError, noNextProfile); - } - if (next instanceof PNone) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_NOT_ITERABLE, iterator); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ARGUMENT_OF_TYPE_P_IS_NOT_ITERABLE, container); } + operation = opProfile.profile(inliningTarget, operation); int i = 0; int n = 0; boolean wrapped = false; - while (true) { + boolean exhausted = false; + do { try { - if (eqNode.compare(frame, inliningTarget, callNext.executeObject(frame, next, iterator), key)) { - switch (opProfile.profile(inliningTarget, operation)) { + Object next = nextNode.execute(frame, inliningTarget, iterator); + if (eqNode.executeEq(frame, inliningTarget, next, key)) { + switch (operation) { case PY_ITERSEARCH_COUNT: n++; break; @@ -130,7 +115,7 @@ static int search(Frame frame, Node inliningTarget, Object container, Object key LoopNode.reportLoopCount(inliningTarget, wrapped ? Integer.MAX_VALUE : i + 1); } if (wrapped) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.OverflowError, ErrorMessages.INDEX_EXCEEDS_INT); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.OverflowError, ErrorMessages.INDEX_EXCEEDS_INT); } else { return i; } @@ -141,21 +126,21 @@ static int search(Frame frame, Node inliningTarget, Object container, Object key return 1; } } - } catch (PException e) { - e.expectStopIteration(inliningTarget, stopIterationProfile); - if (CompilerDirectives.hasNextTier()) { - LoopNode.reportLoopCount(inliningTarget, wrapped ? Integer.MAX_VALUE : i + 1); + if (operation == PY_ITERSEARCH_INDEX && i == Integer.MAX_VALUE) { + wrapped = true; } - if (opProfile.profile(inliningTarget, operation) == PY_ITERSEARCH_INDEX) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.X_NOT_IN_SEQUENCE); - } - return n; - } - if (opProfile.profile(inliningTarget, operation) == PY_ITERSEARCH_INDEX && i == Integer.MAX_VALUE) { - wrapped = true; + i++; + } catch (IteratorExhausted e) { + exhausted = true; } - i++; + } while (loopProfile.profile(inliningTarget, !exhausted)); + if (CompilerDirectives.hasNextTier()) { + LoopNode.reportLoopCount(inliningTarget, wrapped ? Integer.MAX_VALUE : i + 1); + } + if (operation == PY_ITERSEARCH_INDEX) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.X_NOT_IN_SEQUENCE); } + return n; } @GenerateInline diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceSetItemNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceSetItemNode.java index ae6e2e7b1f..aa3ccaab98 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceSetItemNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceSetItemNode.java @@ -86,7 +86,7 @@ static void doGeneric(VirtualFrame frame, Node inliningTarget, Object object, in @Cached GetObjectSlotsNode getSlotsNode, @Cached IndexForSqSlotInt indexForSqSlot, @Cached CallSlotSqAssItemNode callSetItem, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { TpSlots slots = getSlotsNode.execute(inliningTarget, object); index = indexForSqSlot.execute(frame, inliningTarget, object, slots, index); if (slots.sq_ass_item() != null) { @@ -97,11 +97,11 @@ static void doGeneric(VirtualFrame frame, Node inliningTarget, Object object, in } @InliningCutoff - static PException raiseNotSupported(Object object, Node inliningTarget, PRaiseNode.Lazy raiseNode, TpSlots slots) { + static PException raiseNotSupported(Object object, Node inliningTarget, PRaiseNode raiseNode, TpSlots slots) { TruffleString message = ErrorMessages.OBJ_DOES_NOT_SUPPORT_ITEM_ASSIGMENT; if (slots.mp_subscript() != null) { message = ErrorMessages.IS_NOT_A_SEQUENCE; } - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, message, object); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, message, object); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceSizeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceSizeNode.java index 652ec34014..b48b8b0a62 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceSizeNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceSizeNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -56,7 +56,6 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNode.Lazy; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Cached; @@ -125,7 +124,7 @@ static int doPBytes(PBytesLike object) { static int doOthers(Frame frame, Node inliningTarget, Object object, @Cached GetObjectSlotsNode getTpSlotsNode, @Cached TpSlotLen.CallSlotLenNode callSlotLenNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode) { TpSlots slots = getTpSlotsNode.execute(inliningTarget, object); if (slots.sq_length() != null) { return callSlotLenNode.execute((VirtualFrame) frame, inliningTarget, slots.sq_length(), object); @@ -134,11 +133,11 @@ static int doOthers(Frame frame, Node inliningTarget, Object object, } @InliningCutoff - private static PException raiseError(Object object, Node inliningTarget, Lazy raiseNode, TpSlots slots) { + private static PException raiseError(Object object, Node inliningTarget, PRaiseNode raiseNode, TpSlots slots) { TruffleString error = ErrorMessages.OBJ_HAS_NO_LEN; if (slots.mp_length() == null) { error = ErrorMessages.IS_NOT_A_SEQUENCE; } - throw raiseNode.get(inliningTarget).raise(TypeError, error, object); + throw raiseNode.raise(inliningTarget, TypeError, error, object); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySliceNew.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySliceNew.java index e4380f48dd..516c0b2c29 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySliceNew.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySliceNew.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,12 +40,13 @@ */ package com.oracle.graal.python.lib; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.slice.PSlice; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.dsl.Cached; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -66,42 +67,42 @@ public abstract class PySliceNew extends PNodeWithContext { @SuppressWarnings("unused") static PSlice doInt(int start, int stop, PNone step, - @Cached.Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { - return factory.createIntSlice(start, stop, 1, false, true); + @Bind PythonLanguage language) { + return PFactory.createIntSlice(language, start, stop, 1, false, true); } @Specialization static PSlice doInt(int start, int stop, int step, - @Cached.Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { - return factory.createIntSlice(start, stop, step); + @Bind PythonLanguage language) { + return PFactory.createIntSlice(language, start, stop, step); } @Specialization @SuppressWarnings("unused") static PSlice doInt(PNone start, int stop, PNone step, - @Cached.Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { - return factory.createIntSlice(0, stop, 1, true, true); + @Bind PythonLanguage language) { + return PFactory.createIntSlice(language, 0, stop, 1, true, true); } @Specialization @SuppressWarnings("unused") static PSlice doInt(PNone start, int stop, int step, - @Cached.Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { - return factory.createIntSlice(0, stop, step, true, false); + @Bind PythonLanguage language) { + return PFactory.createIntSlice(language, 0, stop, step, true, false); } // This specialization is often used when called from C builtins @Specialization(guards = {"isIntRange(start)", "isIntRange(stop)"}) @SuppressWarnings("unused") static PSlice doLong(long start, long stop, PNone step, - @Cached.Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { - return factory.createIntSlice((int) start, (int) stop, 1, false, true); + @Bind PythonLanguage language) { + return PFactory.createIntSlice(language, (int) start, (int) stop, 1, false, true); } @Fallback static PSlice doGeneric(Object start, Object stop, Object step, - @Cached.Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { + @Bind PythonLanguage language) { assert start != PNone.NO_VALUE && stop != PNone.NO_VALUE && step != PNone.NO_VALUE; - return factory.createObjectSlice(start, stop, step); + return PFactory.createObjectSlice(language, start, stop, step); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTimeFromObjectNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTimeFromObjectNode.java index 629782b3bd..ebd030ea24 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTimeFromObjectNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTimeFromObjectNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,7 +47,7 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; +import com.oracle.graal.python.nodes.truffle.PythonIntegerAndFloatTypes; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaDoubleNode; import com.oracle.graal.python.runtime.exception.PException; @@ -66,7 +66,7 @@ /** * Equivalent of {@code _PyTime_FromObject} from CPython. */ -@TypeSystemReference(PythonArithmeticTypes.class) +@TypeSystemReference(PythonIntegerAndFloatTypes.class) @GenerateInline @GenerateCached(false) public abstract class PyTimeFromObjectNode extends PNodeWithContext { @@ -82,10 +82,10 @@ public enum RoundType { @Specialization static long doDouble(Node inliningTarget, double d, RoundType round, long unitToNs, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { // Implements _PyTime_FromDouble, rounding mode (HALF_UP) is hard-coded for now if (Double.isNaN(d)) { - throw raiseNode.get(inliningTarget).raise(ValueError, INVALID_VALUE_NAN); + throw raiseNode.raise(inliningTarget, ValueError, INVALID_VALUE_NAN); } double value = d * unitToNs; @@ -102,25 +102,25 @@ static long doDouble(Node inliningTarget, double d, RoundType round, long unitTo break; } if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) { - throw raiseTimeOverflow(raiseNode.get(inliningTarget)); + throw raiseTimeOverflow(inliningTarget, raiseNode); } return (long) value; } @Specialization static long doLong(Node inliningTarget, long l, @SuppressWarnings("unused") RoundType round, long unitToNs, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { try { return PythonUtils.multiplyExact(l, unitToNs); } catch (OverflowException e) { - throw raiseTimeOverflow(raiseNode.get(inliningTarget)); + throw raiseTimeOverflow(inliningTarget, raiseNode); } } @Specialization static long doOther(VirtualFrame frame, Node inliningTarget, Object value, RoundType round, long unitToNs, @Cached CastToJavaDoubleNode castToDouble, - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Cached PyLongAsLongAndOverflowNode asLongNode) { try { return doDouble(inliningTarget, castToDouble.execute(inliningTarget, value), round, unitToNs, raiseNode); @@ -128,12 +128,12 @@ static long doOther(VirtualFrame frame, Node inliningTarget, Object value, Round try { return doLong(inliningTarget, asLongNode.execute(frame, inliningTarget, value), round, unitToNs, raiseNode); } catch (OverflowException e1) { - throw raiseTimeOverflow(raiseNode.get(inliningTarget)); + throw raiseTimeOverflow(inliningTarget, raiseNode); } } } - private static PException raiseTimeOverflow(PRaiseNode raise) { - throw raise.raise(PythonBuiltinClassType.OverflowError, TOO_LARGE_TO_CONVERT_TO, "timestamp", "long"); + private static PException raiseTimeOverflow(Node inliningTarget, PRaiseNode raise) { + throw raise.raise(inliningTarget, PythonBuiltinClassType.OverflowError, TOO_LARGE_TO_CONVERT_TO, "timestamp", "long"); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTraceBackPrintNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTraceBackPrintNode.java index 292ed5e8d9..ae90fd3f61 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTraceBackPrintNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTraceBackPrintNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,6 +44,7 @@ import static com.oracle.graal.python.builtins.modules.io.IONodes.T_FLUSH; import static com.oracle.graal.python.builtins.modules.io.IONodes.T_WRITE; import static com.oracle.graal.python.nodes.BuiltinNames.T_TRACEBACKLIMIT; +import static com.oracle.graal.python.nodes.ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC; import static com.oracle.graal.python.nodes.StringLiterals.J_NEWLINE; import static com.oracle.graal.python.nodes.StringLiterals.T_SPACE; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; @@ -55,6 +56,8 @@ import java.nio.charset.StandardCharsets; import com.oracle.graal.python.PythonFileDetector; +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.code.PCode; import com.oracle.graal.python.builtins.objects.exception.ExceptionNodes; @@ -73,7 +76,7 @@ import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.OverflowException; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -185,7 +188,7 @@ public static boolean objectHasAttr(VirtualFrame frame, Object object, TruffleSt } public static TruffleString getTypeName(Object type) { - return TypeNodes.GetNameNode.executeUncached(type); + return TypeNodes.GetTpNameNode.executeUncached(type); } public static Object getObjectClass(Object object) { @@ -229,9 +232,9 @@ public static TruffleString classNameNoDot(TruffleString name) { return (i > 0) ? name.substringUncached(i + 1, len - i - 1, TS_ENCODING, true) : name; } - public PCode getCode(VirtualFrame frame, PythonObjectFactory factory, TracebackBuiltins.GetTracebackFrameNode getTbFrameNode, PTraceback tb) { + public PCode getCode(VirtualFrame frame, PythonLanguage language, TracebackBuiltins.GetTracebackFrameNode getTbFrameNode, PTraceback tb) { final PFrame pFrame = getTbFrameNode.execute(frame, tb); - return factory.createCode(pFrame.getTarget()); + return PFactory.createCode(language, pFrame.getTarget()); } protected PTraceback getNextTb(Node inliningTarget, TracebackBuiltins.MaterializeTruffleStacktraceNode materializeStNode, PTraceback traceback) { @@ -333,7 +336,7 @@ private static String trimLeft(CharSequence sequence) { return (st > 0 ? sequence.subSequence(st, len) : sequence).toString(); } - private void printInternal(VirtualFrame frame, Node inliningTarget, PythonObjectFactory factory, TracebackBuiltins.GetTracebackFrameNode getTbFrameNode, + private void printInternal(VirtualFrame frame, Node inliningTarget, TracebackBuiltins.GetTracebackFrameNode getTbFrameNode, TracebackBuiltins.MaterializeTruffleStacktraceNode materializeStNode, Object out, PTraceback traceback, long limit, TruffleString.EqualNode equalNode) { int depth = 0; @@ -351,8 +354,9 @@ private void printInternal(VirtualFrame frame, Node inliningTarget, PythonObject depth--; tb = getNextTb(inliningTarget, materializeStNode, tb); } + PythonLanguage language = PythonLanguage.get(inliningTarget); while (tb != null) { - final PCode code = getCode(frame, factory, getTbFrameNode, tb); + final PCode code = getCode(frame, language, getTbFrameNode, tb); if (lastFile == null || !equalNode.execute(code.getFilename(), lastFile, TS_ENCODING) || lastLine == -1 || tb.getLineno() != lastLine || @@ -383,7 +387,6 @@ public void printTraceBack(VirtualFrame frame, PythonModule sys, Object out, PTr @Bind("this") Node inliningTarget, @Cached TracebackBuiltins.GetTracebackFrameNode getTbFrameNode, @Cached TracebackBuiltins.MaterializeTruffleStacktraceNode materializeStNode, - @Cached PythonObjectFactory factory, @Cached TruffleString.EqualNode equalNode) { long limit = TRACEBACK_LIMIT; final Object limitv = objectReadAttr(sys, T_TRACEBACKLIMIT); @@ -394,14 +397,14 @@ public void printTraceBack(VirtualFrame frame, PythonModule sys, Object out, PTr } } fileWriteString(frame, out, "Traceback (most recent call last):\n"); - printInternal(frame, inliningTarget, factory, getTbFrameNode, materializeStNode, out, tb, limit, equalNode); + printInternal(frame, inliningTarget, getTbFrameNode, materializeStNode, out, tb, limit, equalNode); } @Specialization(guards = "!isPTraceback(tb)") @SuppressWarnings("unused") public void printTraceBack(VirtualFrame frame, PythonModule sys, Object out, Object tb, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raiseBadInternalCall(); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.SystemError, BAD_ARG_TO_INTERNAL_FUNC); } @NeverDefault diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTupleSizeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTupleSizeNode.java index b90c4c9b89..11dcd453dc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTupleSizeNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTupleSizeNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -54,6 +54,7 @@ import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; @@ -86,8 +87,8 @@ static int sizeNative(Node inliningTarget, PythonAbstractNativeObject tuple, @Fallback @InliningCutoff static int size(Object obj, - @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(SystemError, BAD_ARG_TO_INTERNAL_FUNC_S, "PyTuple_Size"); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, BAD_ARG_TO_INTERNAL_FUNC_S, "PyTuple_Size"); } protected boolean isTupleSubtype(Object obj, Node inliningTarget, GetClassNode getClassNode, IsSubtypeNode isSubtypeNode) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeAsEncodedString.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeAsEncodedString.java index 4ec03aba27..44e1c12f05 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeAsEncodedString.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeAsEncodedString.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,6 +45,7 @@ import static com.oracle.graal.python.runtime.exception.PythonErrorType.RuntimeWarning; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.CodecsModuleBuiltins; import com.oracle.graal.python.builtins.modules.WarningsModuleBuiltins; import com.oracle.graal.python.builtins.objects.PNone; @@ -53,7 +54,7 @@ import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -127,7 +128,7 @@ static Object doRegistry(VirtualFrame frame, Node inliningTarget, Object unicode @Cached InlinedConditionProfile isByteArrayProfile, @Cached SequenceStorageNodes.CopyNode copyNode, @Cached(inline = false) WarningsModuleBuiltins.WarnNode warnNode, - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @SuppressWarnings("unused") @Shared("ts2js") @Cached(inline = false) TruffleString.ToJavaStringNode toJavaStringNode) { final Object v = encodeNode.execute(frame, unicode, encoding, errors); // the normal path @@ -137,10 +138,10 @@ static Object doRegistry(VirtualFrame frame, Node inliningTarget, Object unicode // If the codec returns a buffer, raise a warning and convert to bytes if (isByteArrayProfile.profile(inliningTarget, v instanceof PByteArray)) { warnNode.warnFormat(frame, RuntimeWarning, ENCODER_S_RETURNED_S_INSTEAD_OF_BYTES, encoding, "bytearray"); - return PythonContext.get(inliningTarget).factory().createBytes(copyNode.execute(inliningTarget, ((PByteArray) v).getSequenceStorage())); + return PFactory.createBytes(PythonLanguage.get(inliningTarget), copyNode.execute(inliningTarget, ((PByteArray) v).getSequenceStorage())); } - throw raiseNode.get(inliningTarget).raise(TypeError, S_ENCODER_RETURNED_P_INSTEAD_OF_BYTES, encoding, v); + throw raiseNode.raise(inliningTarget, TypeError, S_ENCODER_RETURNED_P_INSTEAD_OF_BYTES, encoding, v); } @Specialization(guards = {"isString(unicode)", "isNoValue(encoding)"}) @@ -152,7 +153,7 @@ static Object doNoEncoding(VirtualFrame frame, Object unicode, @SuppressWarnings @Specialization(guards = "!isString(unicode)") @SuppressWarnings("unused") static Object doGeneric(VirtualFrame frame, Node inliningTarget, Object unicode, Object encoding, Object errors, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raiseBadInternalCall(); + @Exclusive @Cached PRaiseNode raiseNode) { + throw raiseNode.raiseBadInternalCall(inliningTarget); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeDecode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeDecode.java index 4dac6d3f1a..fc22e2ecae 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeDecode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeDecode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -73,10 +73,10 @@ public abstract class PyUnicodeDecode extends PNodeWithContext { @Specialization(guards = "frame != null") static Object doFast(VirtualFrame frame, Node inliningTarget, Object object, Object encoding, Object errors, @Cached(inline = false) CodecsModuleBuiltins.DecodeNode decodeNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { final Object unicode = decodeNode.execute(frame, object, encoding, errors); if (!PGuards.isString(unicode)) { - throw raiseNode.get(inliningTarget).raise(TypeError, DECODER_S_RETURNED_P_INSTEAD_OF_STR, encoding, unicode); + throw raiseNode.raise(inliningTarget, TypeError, DECODER_S_RETURNED_P_INSTEAD_OF_STR, encoding, unicode); } return unicode; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeFSDecoderNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeFSDecoderNode.java index 6f73e45799..e75124026e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeFSDecoderNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeFSDecoderNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -110,7 +110,7 @@ static TruffleString doPathLike(VirtualFrame frame, Object object, private static TruffleString checkString(Node raisingNode, TruffleString str, TruffleString.ByteIndexOfCodePointNode byteIndexOfCodePointNode) { if (byteIndexOfCodePointNode.execute(str, 0, 0, str.byteLength(TS_ENCODING), TS_ENCODING) >= 0) { - throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.EMBEDDED_NULL_BYTE); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.EMBEDDED_NULL_BYTE); } return str; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeFromEncodedObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeFromEncodedObject.java index fc25919b70..30858aa95d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeFromEncodedObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeFromEncodedObject.java @@ -43,6 +43,7 @@ import static com.oracle.graal.python.nodes.ErrorMessages.DECODING_STR_NOT_SUPPORTED; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; @@ -52,10 +53,10 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; @@ -90,25 +91,25 @@ static Object doBytes(VirtualFrame frame, Node inliningTarget, PBytes object, Ob @Specialization @SuppressWarnings("unused") static Object doString(VirtualFrame frame, TruffleString object, Object encoding, Object errors, - @Shared @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, DECODING_STR_NOT_SUPPORTED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, DECODING_STR_NOT_SUPPORTED); } @Specialization @SuppressWarnings("unused") static Object doPString(VirtualFrame frame, PString object, Object encoding, Object errors, - @Shared @Cached(inline = false) PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, DECODING_STR_NOT_SUPPORTED); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, DECODING_STR_NOT_SUPPORTED); } @Specialization(guards = {"!isPBytes(object)", "!isString(object)"}, limit = "3") static Object doBuffer(VirtualFrame frame, Node inliningTarget, Object object, Object encoding, Object errors, + @Bind PythonLanguage language, @Cached("createFor(this)") IndirectCallData indirectCallNode, @Exclusive @Cached InlinedConditionProfile emptyStringProfile, @CachedLibrary("object") PythonBufferAcquireLibrary bufferAcquireLib, @Exclusive @Cached PyUnicodeDecode decode, - @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached(inline = false) PythonObjectFactory factory) { + @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib) { PythonContext context = PythonContext.get(inliningTarget); Object buffer = bufferAcquireLib.acquireReadonly(object, frame, context, context.getLanguage(inliningTarget), indirectCallNode); try { @@ -116,7 +117,7 @@ static Object doBuffer(VirtualFrame frame, Node inliningTarget, Object object, O if (emptyStringProfile.profile(inliningTarget, len == 0)) { return T_EMPTY_STRING; } - PBytes bytes = factory.createBytes(bufferLib.getInternalOrCopiedByteArray(buffer), len); + PBytes bytes = PFactory.createBytes(language, bufferLib.getInternalOrCopiedByteArray(buffer), len); return decode.execute(frame, inliningTarget, bytes, encoding, errors); } finally { bufferLib.release(buffer, frame, indirectCallNode); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeReadCharNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeReadCharNode.java index c34ceb59ad..789eda9bee 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeReadCharNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeReadCharNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -74,19 +74,19 @@ static int doGeneric(Node inliningTarget, Object type, long lindex, @Cached CastToTruffleStringNode castToStringNode, @Cached(inline = false) TruffleString.CodePointLengthNode codePointLengthNode, @Cached(inline = false) TruffleString.CodePointAtIndexNode codePointAtIndexNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { TruffleString s = castToStringNode.execute(inliningTarget, type); int index = PInt.intValueExact(lindex); // avoid StringIndexOutOfBoundsException if (index < 0 || index >= codePointLengthNode.execute(s, TS_ENCODING)) { - throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.STRING_INDEX_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.STRING_INDEX_OUT_OF_RANGE); } return codePointAtIndexNode.execute(s, index, TS_ENCODING); } catch (CannotCastException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.BAD_ARG_TYPE_FOR_BUILTIN_OP); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.STRING_INDEX_OUT_OF_RANGE); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.STRING_INDEX_OUT_OF_RANGE); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/RichCmpOp.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/RichCmpOp.java new file mode 100644 index 0000000000..823421149e --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/RichCmpOp.java @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___EQ__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GE__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GT__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LE__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LT__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NE__; +import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; + +import com.oracle.graal.python.builtins.objects.ints.PInt; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.strings.TruffleString; + +/** + * Mirror of the CPython constants of the same name. The order is important: the ordinal should be + * the same as the constant value on the CPython side. + */ +public enum RichCmpOp { + Py_LT(T___LT__, "<"), + Py_LE(T___LE__, "<="), + Py_EQ(T___EQ__, "=="), + Py_NE(T___NE__, "!="), + Py_GT(T___GT__, ">"), + Py_GE(T___GE__, ">="); + + public static final RichCmpOp[] VALUES = values(); + private final TruffleString pythonName; + private final String opName; + + RichCmpOp(TruffleString pythonName, String opName) { + this.pythonName = pythonName; + this.opName = opName; + } + + public static RichCmpOp fromNative(int value) { + try { + return VALUES[value]; + } catch (IndexOutOfBoundsException ex) { + throw CompilerDirectives.shouldNotReachHere("Wrong 'op' argument to tp_richcompare"); + } + } + + public static RichCmpOp fromName(TruffleString name) { + for (RichCmpOp value : VALUES) { + if (value.pythonName.equalsUncached(name, TS_ENCODING)) { + return value; + } + } + return null; + } + + public final TruffleString getPythonName() { + return pythonName; + } + + public final String getOpName() { + return opName; + } + + /** + * Returns the numeric value that is used by CPython C API. + */ + public final int asNative() { + return ordinal(); + } + + // Convenience shortcuts: + public final boolean isEqOrNe() { + return this == Py_EQ || this == Py_NE; + } + + public final boolean isEq() { + return this == Py_EQ; + } + + public final boolean isNe() { + return this == Py_NE; + } + + public final boolean isLe() { + return this == Py_LE; + } + + public final boolean isLt() { + return this == Py_LT; + } + + public final boolean isGt() { + return this == Py_GT; + } + + public final boolean isGe() { + return this == Py_GE; + } + + /** + * Converts the result of Java's "compare" static method, such as + * {@link Integer#compare(int, int)} to a boolean value according to the given operation. If the + * result is computed, make sure that it can never overflow! + */ + public final boolean compareResultToBool(int result) { + return switch (this) { + case Py_LT -> result < 0; + case Py_LE -> result <= 0; + case Py_EQ -> result == 0; + case Py_NE -> result != 0; + case Py_GT -> result > 0; + case Py_GE -> result >= 0; + }; + } + + public final boolean compare(double a, double b) { + return switch (this) { + case Py_LT -> a < b; + case Py_LE -> a <= b; + case Py_EQ -> a == b; + case Py_NE -> a != b; + case Py_GT -> a > b; + case Py_GE -> a >= b; + }; + } + + public final boolean compare(long a, long b) { + return switch (this) { + case Py_LT -> a < b; + case Py_LE -> a <= b; + case Py_EQ -> a == b; + case Py_NE -> a != b; + case Py_GT -> a > b; + case Py_GE -> a >= b; + }; + } + + public final boolean compare(int a, int b) { + return switch (this) { + case Py_LT -> a < b; + case Py_LE -> a <= b; + case Py_EQ -> a == b; + case Py_NE -> a != b; + case Py_GT -> a > b; + case Py_GE -> a >= b; + }; + } + + public final boolean compare(byte a, byte b) { + return switch (this) { + case Py_LT -> a < b; + case Py_LE -> a <= b; + case Py_EQ -> a == b; + case Py_NE -> a != b; + case Py_GT -> a > b; + case Py_GE -> a >= b; + }; + } + + /** + * Equivalent of {@code Py_RETURN_RICHCOMPARE} macro from CPython. + */ + public final boolean compare(boolean a, boolean b) { + return compareResultToBool(PInt.intValue(a) - PInt.intValue(b)); + } + + public final RichCmpOp getSwapped() { + return switch (this) { + case Py_LT -> Py_GT; + case Py_LE -> Py_GE; + case Py_EQ -> Py_EQ; + case Py_NE -> Py_NE; + case Py_GT -> Py_LT; + case Py_GE -> Py_LE; + }; + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/vector/VectorArrowArrayReleaseCallback.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/SequenceRepeatHelperNode.java similarity index 55% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/vector/VectorArrowArrayReleaseCallback.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/SequenceRepeatHelperNode.java index 286334f1a5..07213af746 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/vector/VectorArrowArrayReleaseCallback.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/SequenceRepeatHelperNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,56 +38,45 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.nodes.arrow.vector; +package com.oracle.graal.python.lib; -import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun; +import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.arrow.ArrowArray; -import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.library.ExportLibrary; -import com.oracle.truffle.api.library.ExportMessage; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; -import static com.oracle.graal.python.nodes.ErrorMessages.ARROW_ARRAY_ALREADY_RELEASED; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; +@GenerateInline(false) +@GenerateUncached +public abstract class SequenceRepeatHelperNode extends Node { + abstract Object execute(VirtualFrame frame, TpSlot slot, Object seq, Object n); -@ExportLibrary(InteropLibrary.class) -public class VectorArrowArrayReleaseCallback implements TruffleObject { - - @ExportMessage - boolean isExecutable() { - return true; - } - - @ExportMessage - static class Execute { - - @Specialization(guards = "validateArgs(args)") - static Object doRelease(VectorArrowArrayReleaseCallback self, Object[] args, - @Bind("$node") Node inliningTarget, - @Cached PRaiseNode.Lazy raiseNode) { - ArrowArray arrowArray = ArrowArray.wrap((long) args[0]); - if (arrowArray.isReleased()) { - throw raiseNode.get(inliningTarget).raise(ValueError, ARROW_ARRAY_ALREADY_RELEASED); - } - - arrowArray.markReleased(); - return PNone.NO_VALUE; - } - - @Fallback - static Object doError(VectorArrowArrayReleaseCallback self, Object[] args) { - throw CompilerDirectives.shouldNotReachHere(); + @Specialization + static Object sequenceRepeat(VirtualFrame frame, TpSlot slot, Object seq, Object n, + @Bind Node inliningTarget, + @Cached PyIndexCheckNode indexCheckNode, + @Cached PyNumberAsSizeNode asSizeNode, + @Cached TpSlotSizeArgFun.CallSlotSizeArgFun callSlotNode, + @Cached PRaiseNode raiseNode) { + if (indexCheckNode.execute(inliningTarget, n)) { + int count = asSizeNode.execute(frame, inliningTarget, n, PythonBuiltinClassType.OverflowError); + return callSlotNode.execute(frame, inliningTarget, slot, seq, count); + } else { + throw raiseNonIntSqMul(inliningTarget, n, raiseNode); } + } - static boolean validateArgs(Object[] args) { - return args.length == 1 && args[0] instanceof Long; - } + @InliningCutoff + private static PException raiseNonIntSqMul(Node inliningTarget, Object n, PRaiseNode raiseNode) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CANT_MULTIPLY_SEQ_BY_NON_INT, n); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberAddFastPathsBase.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberAddFastPathsBase.java new file mode 100644 index 0000000000..a0aa6904be --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberAddFastPathsBase.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib.fastpath; + +import static com.oracle.graal.python.builtins.objects.ints.IntBuiltins.AddNode.add; + +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.builtins.objects.ints.PInt; +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.dsl.TypeSystemReference; + +/** + * Helper class with shared fast-paths. Must be public so that it is accessible by the Bytecode DSL + * generated code. + */ +@GenerateCached(false) +@TypeSystemReference(PythonIntegerTypes.class) +public abstract class PyNumberAddFastPathsBase extends BinaryOpNode { + + /* + * All the following fast paths need to be kept in sync with the corresponding builtin functions + * in IntBuiltins + */ + @Specialization(rewriteOn = ArithmeticException.class) + public static int doII(int left, int right) { + return Math.addExact(left, right); + } + + @Specialization(replaces = "doII", rewriteOn = ArithmeticException.class) + public static long doLL(long left, long right) { + return Math.addExact(left, right); + } + + @Specialization(replaces = "doLL") + public static Object doLLOvf(long x, long y, + @Bind PythonLanguage language) { + /* Inlined version of Math.addExact(x, y) with BigInteger fallback. */ + long r = x + y; + // HD 2-12 Overflow iff both arguments have the opposite sign of the result + if (((x ^ r) & (y ^ r)) < 0) { + return PFactory.createInt(language, add(PInt.longToBigInteger(x), PInt.longToBigInteger(y))); + } + return r; + } + + /* + * All the following fast paths need to be kept in sync with the corresponding builtin functions + * in FloatBuiltins + */ + @Specialization + public static double doDD(double left, double right) { + return left + right; + } + + @Specialization + public static double doDL(double left, long right) { + return left + right; + } + + @Specialization + public static double doLD(long left, double right) { + return left + right; + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberAndFastPathsBase.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberAndFastPathsBase.java new file mode 100644 index 0000000000..2aa536d5a1 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberAndFastPathsBase.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib.fastpath; + +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.dsl.TypeSystemReference; + +/** + * Helper class with shared fast-paths. Must be public so that it is accessible by the Bytecode DSL + * generated code. + */ +@GenerateCached(false) +@TypeSystemReference(PythonIntegerTypes.class) +public abstract class PyNumberAndFastPathsBase extends BinaryOpNode { + + @Specialization + public static boolean op(boolean left, boolean right) { + return left && right; + } + + @Specialization + public static int op(int left, int right) { + return left & right; + } + + @Specialization + public static long op(long left, long right) { + return left & right; + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/vector/VectorToArrowSchemaNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberFloorDivideFastPathsBase.java similarity index 52% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/vector/VectorToArrowSchemaNode.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberFloorDivideFastPathsBase.java index e5b022a427..451cdeeb44 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/vector/VectorToArrowSchemaNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberFloorDivideFastPathsBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,48 +38,60 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.nodes.arrow.vector; +package com.oracle.graal.python.lib.fastpath; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.arrow.ArrowSchema; -import com.oracle.graal.python.runtime.arrow.ArrowVectorSupport; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node; - -import static com.oracle.graal.python.nodes.arrow.ArrowArray.NULL; +import com.oracle.truffle.api.dsl.TypeSystemReference; +/** + * Helper class with shared fast-paths. Must be public so that it is accessible by the Bytecode DSL + * generated code. + */ @GenerateCached(false) -@GenerateInline -public abstract class VectorToArrowSchemaNode extends PNodeWithContext { +@TypeSystemReference(PythonIntegerTypes.class) +public abstract class PyNumberFloorDivideFastPathsBase extends BinaryOpNode { + + /* + * All the following fast paths need to be kept in sync with the corresponding builtin functions + * in IntBuiltins, FloatBuiltins, ... + */ + @Specialization(guards = "!specialCase(left, right)") + public static int doII(int left, int right) { + return Math.floorDiv(left, right); + } + + @Specialization(guards = "!specialCase(left, right)") + public static long doLL(long left, long right) { + return Math.floorDiv(left, right); + } - public abstract ArrowSchema execute(Node inliningTarget, Object vector); + @Specialization(guards = "!isZero(right)") + public static double doLD(long left, double right) { + return doDD(left, right); + } + + @Specialization(guards = "right != 0") + public static double doDL(double left, long right) { + return doDD(left, right); + } - @Specialization(guards = "arrowVectorSupport.isFixedWidthVector(vector)") - static ArrowSchema doIntVector(Node inliningTarget, Object vector, - @Bind("getContext(inliningTarget)") PythonContext ctx, - @Bind("ctx.arrowVectorSupport") ArrowVectorSupport arrowVectorSupport, - @Cached GetFormatFromVectorNode formatNode) { - Object hostVector = ctx.getEnv().asHostObject(vector); - var unsafe = ctx.getUnsafe(); - var snapshot = new ArrowSchema.Snapshot(); - // + 1 NULL terminator - snapshot.format = unsafe.allocateMemory(2); - unsafe.putByte(snapshot.format, formatNode.execute(inliningTarget, hostVector)); - unsafe.putByte(snapshot.format + 1, NULL); - snapshot.release = ctx.arrowSupport.getArrowSchemaReleaseCallback(); + @Specialization(guards = "!isZero(right)") + public static double doDD(double left, double right) { + return Math.floor(left / right); + } + + public static boolean specialCase(int left, int right) { + return right == 0 || left == Integer.MIN_VALUE && right == -1; + } - return ArrowSchema.allocateFromSnapshot(snapshot); + public static boolean specialCase(long left, long right) { + return right == 0 || left == Long.MIN_VALUE && right == -1; } - @Fallback - static ArrowSchema doError(Object object) { - throw CompilerDirectives.shouldNotReachHere(); + public static boolean isZero(double right) { + return right == 0.0; } } diff --git a/graalpython/org.graalvm.python.embedding.tools/src/org/graalvm/python/embedding/tools/exec/SubprocessLog.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberLshiftFastPathsBase.java similarity index 62% rename from graalpython/org.graalvm.python.embedding.tools/src/org/graalvm/python/embedding/tools/exec/SubprocessLog.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberLshiftFastPathsBase.java index 1bedf4d2a9..3662fe3a00 100644 --- a/graalpython/org.graalvm.python.embedding.tools/src/org/graalvm/python/embedding/tools/exec/SubprocessLog.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberLshiftFastPathsBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,50 +38,35 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.graalvm.python.embedding.tools.exec; +package com.oracle.graal.python.lib.fastpath; -import java.util.ArrayList; -import java.util.List; +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.graal.python.util.OverflowException; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.Specialization; -public interface SubprocessLog { - - default void subProcessOut(CharSequence out) { - System.out.println(out); - } - - default void subProcessErr(CharSequence err) { - System.err.println(err); - } - - default void log(CharSequence txt) { - System.out.println(txt); - } - - default void log(CharSequence txt, Throwable t) { - System.out.println(txt); - t.printStackTrace(); - } - - final class CollectOutputLog implements SubprocessLog { - private final List output = new ArrayList<>(); - - public List getOutput() { - return output; - } - - @Override - public void subProcessOut(CharSequence var1) { - output.add(var1.toString()); - } +/** + * Helper class with shared fast-paths. Must be public so that it is accessible by the Bytecode DSL + * generated code. TODO: unused due to GR-64005 + */ +@GenerateCached(false) +public abstract class PyNumberLshiftFastPathsBase extends BinaryOpNode { - @Override - public void subProcessErr(CharSequence var1) { - System.err.println(var1); + @Specialization(guards = {"right < 32", "right >= 0"}, rewriteOn = OverflowException.class) + public static int doII(int left, int right) throws OverflowException { + int result = left << right; + if (left != result >> right) { + throw OverflowException.INSTANCE; } + return result; + } - @Override - public void log(CharSequence var1) { + @Specialization(guards = {"right < 64", "right >= 0"}, rewriteOn = OverflowException.class) + public static long doLL(long left, long right) throws OverflowException { + long result = left << right; + if (left != result >> right) { + throw OverflowException.INSTANCE; } + return result; } - } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberMultiplyFastPathsBase.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberMultiplyFastPathsBase.java new file mode 100644 index 0000000000..e2975b0a4b --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberMultiplyFastPathsBase.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib.fastpath; + +import static com.oracle.graal.python.builtins.objects.ints.IntBuiltins.MulNode.mul; + +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.builtins.objects.ints.PInt; +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.dsl.TypeSystemReference; +import com.oracle.truffle.api.nodes.Node; + +/** + * Helper class with shared fast-paths. Must be public so that it is accessible by the Bytecode DSL + * generated code. + */ +@GenerateCached(false) +@TypeSystemReference(PythonIntegerTypes.class) +public abstract class PyNumberMultiplyFastPathsBase extends BinaryOpNode { + + /* + * All the following fast paths need to be kept in sync with the corresponding builtin functions + * in IntBuiltins + */ + @Specialization(rewriteOn = ArithmeticException.class) + public static int doII(int x, int y) throws ArithmeticException { + return Math.multiplyExact(x, y); + } + + @Specialization(replaces = "doII") + public static long doIIL(int x, int y) { + return x * (long) y; + } + + @Specialization(rewriteOn = ArithmeticException.class) + public static long doLL(long x, long y) { + return Math.multiplyExact(x, y); + } + + @Specialization(replaces = "doLL") + public static Object doLongWithOverflow(long x, long y, + @Bind("this") Node inliningTarget) { + /* Inlined version of Math.multiplyExact(x, y) with BigInteger fallback. */ + long r = x * y; + long ax = Math.abs(x); + long ay = Math.abs(y); + if (((ax | ay) >>> 31 != 0)) { + // Some bits greater than 2^31 that might cause overflow + // Check the result using the divide operator + // and check for the special case of Long.MIN_VALUE * -1 + if (((y != 0) && (r / y != x)) || + (x == Long.MIN_VALUE && y == -1)) { + return PFactory.createInt(PythonLanguage.get(inliningTarget), mul(PInt.longToBigInteger(x), PInt.longToBigInteger(y))); + } + } + return r; + } + + /* + * All the following fast paths need to be kept in sync with the corresponding builtin functions + * in FloatBuiltins + */ + @Specialization + public static double doDL(double left, long right) { + return left * right; + } + + @Specialization + public static double doLD(long left, double right) { + return left * right; + } + + @Specialization + public static double doDD(double left, double right) { + return left * right; + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberOrFastPathsBase.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberOrFastPathsBase.java new file mode 100644 index 0000000000..513f8f0224 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberOrFastPathsBase.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib.fastpath; + +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.dsl.TypeSystemReference; + +/** + * Helper class with shared fast-paths. Must be public so that it is accessible by the Bytecode DSL + * generated code. + */ +@GenerateCached(false) +@TypeSystemReference(PythonIntegerTypes.class) +public abstract class PyNumberOrFastPathsBase extends BinaryOpNode { + + @Specialization + public static boolean op(boolean left, boolean right) { + return left || right; + } + + @Specialization + public static int op(int left, int right) { + return left | right; + } + + @Specialization + public static long op(long left, long right) { + return left | right; + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPySourceKind.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberRemainderFastPathsBase.java similarity index 67% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPySourceKind.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberRemainderFastPathsBase.java index 15ea21df24..09b0c57412 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPySourceKind.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberRemainderFastPathsBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,38 +38,29 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.builtins.objects.cext.hpy; +package com.oracle.graal.python.lib.fastpath; -import com.oracle.graal.python.nodes.StringLiterals; -import com.oracle.truffle.api.strings.TruffleString; +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.dsl.TypeSystemReference; -public enum GraalHPySourceKind { - EXPR(0, StringLiterals.T_EVAL), - FILE(1, StringLiterals.T_EXEC), - SINGLE(2, StringLiterals.T_SINGLE); - - private final int value; - private final TruffleString mode; - - GraalHPySourceKind(int value, TruffleString mode) { - this.value = value; - this.mode = mode; - } - - public int getValue() { - return value; - } +/** + * Helper class with shared fast-paths. Must be public so that it is accessible by the Bytecode DSL + * generated code. + */ +@GenerateCached(false) +@TypeSystemReference(PythonIntegerTypes.class) +public abstract class PyNumberRemainderFastPathsBase extends BinaryOpNode { - public TruffleString getMode() { - return mode; + @Specialization(guards = "right != 0") + public static int doII(int left, int right) { + return Math.floorMod(left, right); } - public static GraalHPySourceKind fromValue(int value) { - return switch (value) { - case 0 -> EXPR; - case 1 -> FILE; - case 2 -> SINGLE; - default -> null; - }; + @Specialization(guards = "right != 0") + public static long doLL(long left, long right) { + return Math.floorMod(left, right); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyMode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberRshiftFastPathsBase.java similarity index 67% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyMode.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberRshiftFastPathsBase.java index 0191a7054a..d56ebea294 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyMode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberRshiftFastPathsBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,39 +38,29 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.builtins.objects.cext.hpy; +package com.oracle.graal.python.lib.fastpath; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.dsl.TypeSystemReference; -public enum HPyMode { - MODE_INVALID(-1), - MODE_UNIVERSAL(0), - MODE_DEBUG(1), - MODE_TRACE(2); - /* - * We do currently not test the combinations of debug and trace mode, so we do not offer them - * right now. This may change in future. - */ - // DEBUG_TRACE(3), - // TRACE_DEBUG(4) - - private final int value; - - HPyMode(int value) { - this.value = value; - } +/** + * Helper class with shared fast-paths. Must be public so that it is accessible by the Bytecode DSL + * generated code. + */ +@GenerateCached(false) +@TypeSystemReference(PythonIntegerTypes.class) +public abstract class PyNumberRshiftFastPathsBase extends BinaryOpNode { - public int getValue() { - return value; + @Specialization(guards = {"right < 32", "right >= 0"}) + public static int doIISmall(int left, int right) { + return left >> right; } - @TruffleBoundary - public static HPyMode fromValue(int i) { - for (HPyMode mode : values()) { - if (mode.value == i) { - return mode; - } - } - return MODE_INVALID; + @Specialization(guards = {"right < 64", "right >= 0"}) + public static long doIISmall(long left, long right) { + return left >> right; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberSubtractFastPathsBase.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberSubtractFastPathsBase.java new file mode 100644 index 0000000000..64fd91a4d2 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberSubtractFastPathsBase.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib.fastpath; + +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.builtins.objects.ints.IntBuiltins; +import com.oracle.graal.python.builtins.objects.ints.PInt; +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.dsl.TypeSystemReference; +import com.oracle.truffle.api.nodes.Node; + +@GenerateCached(false) +@TypeSystemReference(PythonIntegerTypes.class) +public abstract class PyNumberSubtractFastPathsBase extends BinaryOpNode { + + /* + * All the following fast paths need to be kept in sync with the corresponding builtin functions + * in IntBuiltins + */ + @Specialization(rewriteOn = ArithmeticException.class) + public static int doII(int x, int y) throws ArithmeticException { + return Math.subtractExact(x, y); + } + + @Specialization(replaces = "doII") + public static long doIIOvf(int x, int y) { + return (long) x - (long) y; + } + + @Specialization(rewriteOn = ArithmeticException.class) + public static long doLL(long x, long y) throws ArithmeticException { + return Math.subtractExact(x, y); + } + + @Specialization(replaces = "doLL") + public static Object doLongWithOverflow(long x, long y, + @Bind("this") Node inliningTarget) { + /* Inlined version of Math.subtractExact(x, y) with BigInteger fallback. */ + long r = x - y; + // HD 2-12 Overflow iff the arguments have different signs and + // the sign of the result is different than the sign of x + if (((x ^ y) & (x ^ r)) < 0) { + return PFactory.createInt(PythonLanguage.get(inliningTarget), IntBuiltins.SubNode.sub(PInt.longToBigInteger(x), PInt.longToBigInteger(y))); + } + return r; + } + + /* + * All the following fast paths need to be kept in sync with the corresponding builtin functions + * in FloatBuiltins + */ + @Specialization + public static double doDD(double left, double right) { + return left - right; + } + + @Specialization + public static double doDL(double left, long right) { + return left - right; + } + + @Specialization + public static double doLD(long left, double right) { + return left - right; + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberTrueDivideFastPathsBase.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberTrueDivideFastPathsBase.java new file mode 100644 index 0000000000..cdc180ab9b --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberTrueDivideFastPathsBase.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib.fastpath; + +import com.oracle.graal.python.builtins.objects.ints.IntBuiltins; +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.ImportStatic; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.dsl.TypeSystemReference; + +/** + * Helper class with shared fast-paths. Must be public so that it is accessible by the Bytecode DSL + * generated code. + */ +@GenerateCached(false) +@TypeSystemReference(PythonIntegerTypes.class) +@ImportStatic(IntBuiltins.TrueDivNode.class) +public abstract class PyNumberTrueDivideFastPathsBase extends BinaryOpNode { + + /* + * All the following fast paths need to be kept in sync with the corresponding builtin functions + * in IntBuiltins, FloatBuiltins, ... + */ + + @Specialization(guards = "!isZero(right)") + public static double doDD(double left, double right) { + return left / right; + } + + @Specialization(guards = "right != 0") + public static double doDL(double left, long right) { + return doDD(left, right); + } + + @Specialization(guards = "!isZero(right)") + public static double doLD(long left, double right) { + return doDD(left, right); + } + + @Specialization(guards = "right != 0") + public static double doII(int left, int right) { + return doDD(left, right); + } + + @Specialization(guards = {"right != 0", "fitsIntoDouble(left)", "fitsIntoDouble(right)"}) + public static double doLL(long left, long right) { + return doDD(left, right); + } + + public static boolean isZero(double right) { + return right == 0.0; + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberXorFastPathsBase.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberXorFastPathsBase.java new file mode 100644 index 0000000000..7aa8ec2e39 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/fastpath/PyNumberXorFastPathsBase.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib.fastpath; + +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.dsl.TypeSystemReference; + +/** + * Helper class with shared fast-paths. Must be public so that it is accessible by the Bytecode DSL + * generated code. + */ +@GenerateCached(false) +@TypeSystemReference(PythonIntegerTypes.class) +public abstract class PyNumberXorFastPathsBase extends BinaryOpNode { + + @Specialization + public static boolean op(boolean left, boolean right) { + return left != right; + } + + @Specialization + public static int op(int left, int right) { + return left ^ right; + } + + @Specialization + public static long op(long left, long right) { + return left ^ right; + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/BuiltinNames.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/BuiltinNames.java index 2f69d1e336..616387769c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/BuiltinNames.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/BuiltinNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -451,6 +451,8 @@ public abstract class BuiltinNames { public static final TruffleString T_SHA3 = tsLiteral(J_SHA3); public static final TruffleString T_SEND = tsLiteral("send"); + public static final TruffleString T_THROW = tsLiteral("throw"); + public static final TruffleString T_CLOSE = tsLiteral("close"); public static final String J__ASYNCIO = "_asyncio"; public static final TruffleString T__ASYNCIO = tsLiteral(J__ASYNCIO); @@ -478,4 +480,7 @@ public abstract class BuiltinNames { public static final String J_EXCEPTION_GROUP = "ExceptionGroup"; public static final TruffleString T_EXCEPTION_GROUP = tsLiteral(J_EXCEPTION_GROUP); + + public static final String J_UNICODEDATA = "unicodedata"; + public static final TruffleString T_UNICODEDATA = tsLiteral(J_UNICODEDATA); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java index 3f8cfe2700..42d0352eed 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java @@ -83,6 +83,7 @@ public abstract class ErrorMessages { public static final TruffleString ARG_MUST_NOT_BE_EMPTY = tsLiteral("%s arg %d must not be empty"); public static final TruffleString ARG_NOT_IN_RANGE = tsLiteral("%s arg not in range(%s)"); public static final TruffleString ARG_SHOULD_BE_INT_OR_NONE = tsLiteral("argument should be integer or None, not %p"); + public static final TruffleString ARG_SHOULD_BE_INT_OR_NONE_T = tsLiteral("argument should be integer or None, not %P"); public static final TruffleString ARGS_CHANGED_DURING_ITERATION = tsLiteral("args changed during iteration"); public static final TruffleString ARGS_MUST_HAVE_SAME_LENGTH = tsLiteral("%s arguments must have same length"); public static final TruffleString ARG_SHOULD_BE_BYTES_BUFFER_OR_ASCII_NOT_P = tsLiteral("argument should be bytes, buffer or ASCII string, not '%p'"); @@ -102,8 +103,9 @@ public abstract class ErrorMessages { public static final TruffleString ATTR_NAME_MUST_BE_STRING = tsLiteral("attribute name must be string, not '%p'"); public static final TruffleString S_MUST_BE_STRING_NOT_S = tsLiteral("\"%s\" must be string, not %.200s"); public static final TruffleString S_MUST_BE_STRING_OR_NONE_NOT_S = tsLiteral("\"%s\" must be string or None, not %.200s"); - public static final TruffleString ATTR_S_OF_S_IS_NOT_READABLE = tsLiteral("attribute %s of %s objects is not readable"); + public static final TruffleString ATTR_S_OF_N_IS_NOT_READABLE = tsLiteral("attribute %s of %N objects is not readable"); public static final TruffleString ATTR_S_OF_S_IS_NOT_WRITABLE = tsLiteral("attribute %s of %s is not writable"); + public static final TruffleString ATTR_S_OF_N_OBJ_IS_NOT_WRITABLE = tsLiteral("attribute %s of %N object is not writable"); public static final TruffleString ATTR_S_OF_S_OBJ_IS_NOT_WRITABLE = tsLiteral("attribute %s of %s object is not writable"); public static final TruffleString ATTR_S_OF_S_OBJ_IS_NOT_READABLE = tsLiteral("attribute %s of %s object is not readable"); public static final TruffleString ATTR_S_OF_S_OBJ_IS_NOT_INSERTABLE = tsLiteral("attribute %s of %s object is not insertable"); @@ -177,8 +179,9 @@ public abstract class ErrorMessages { public static final TruffleString CANNOT_CONVERT_S_TO_INT_RATIO = tsLiteral("cannot convert %s to integer ratio"); public static final TruffleString CANNOT_CREATE_CALL_TARGET = tsLiteral("cannot create a call target from the code object: %p"); public static final TruffleString CANNOT_CREATE_INSTANCES = tsLiteral("cannot create '%s' instances"); + public static final TruffleString CANNOT_CREATE_N_INSTANCES = tsLiteral("cannot create '%N' instances"); public static final TruffleString CANNOT_CREATE_WEAK_REFERENCE_TO = tsLiteral("cannot create weak reference to '%p' object"); - public static final TruffleString CANNOT_DELETE_ATTRIBUTE = tsLiteral("can't delete %s.%s"); + public static final TruffleString CANNOT_DELETE_ATTRIBUTE = tsLiteral("can't delete %N.%s"); public static final TruffleString CANNOT_DELETE_MEMORY = tsLiteral("cannot delete memory"); public static final TruffleString CANNOT_MODIFY_READONLY_MEMORY = tsLiteral("cannot modify read-only memory"); public static final TruffleString CANNOT_EXTEND_INCOMPLETE_P = tsLiteral("Cannot extend an incomplete type '%p'"); @@ -205,6 +208,7 @@ public abstract class ErrorMessages { public static final TruffleString CANNOT_CONVERT_FLOAT_NAN_TO_INTEGER = tsLiteral("cannot convert float NaN to integer"); public static final TruffleString CANT_CAPTURE_NAME_UNDERSCORE_IN_PATTERNS = tsLiteral("can't capture name '_' in patterns"); public static final TruffleString CANT_CONCAT_P_TO_S = tsLiteral("can't concat %p to %s"); + public static final TruffleString CANT_CONCAT_P_TO_P = tsLiteral("can't concat %p to %p"); public static final TruffleString CANT_CONVERT_TO_STR_IMPLICITLY = tsLiteral("Can't convert '%p' object to str implicitly"); public static final TruffleString CANT_COMPARE = tsLiteral("Can't compare %p and %p"); public static final TruffleString CAN_T_DELETE_NUMERIC_CHAR_ATTRIBUTE = tsLiteral("can't delete numeric/char attribute"); @@ -228,7 +232,7 @@ public abstract class ErrorMessages { public static final TruffleString CHARACTER_MAPPING_MUST_RETURN_INT_NONE_OR_STR = tsLiteral("character mapping must return integer, None or str"); public static final TruffleString CHARACTER_MAPPING_MUST_RETURN_INT_BYTES_OR_NONE_NOT_P = tsLiteral("character mapping must return integer, bytes or None, not %p"); public static final TruffleString CHARACTER_MAPS_TO_UNDEFINED = tsLiteral("character maps to "); - public static final TruffleString CLASS_ASSIGNMENT_S_LAYOUT_DIFFERS_FROM_S = tsLiteral("__class__ assignment: '%s' object layout differs from '%s'"); + public static final TruffleString CLASS_ASSIGNMENT_N_LAYOUT_DIFFERS_FROM_N = tsLiteral("__class__ assignment: '%N' object layout differs from '%N'"); public static final TruffleString CLASS_ASSIGNMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES = tsLiteral("__class__ assignment only supported for heap types or ModuleType subclasses"); public static final TruffleString CLASS_MUST_BE_SET_TO_CLASS = tsLiteral("__class__ must be set to a class, not '%p' object"); public static final TruffleString MUST_BE_SET_TO_S_NOT_P = tsLiteral("%s must be set to a %s, not a '%p'"); @@ -298,7 +302,7 @@ public abstract class ErrorMessages { public static final TruffleString EXPECTED_BYTES_P_FOUND = tsLiteral("expected bytes, %p found"); public static final TruffleString EXPECTED_CHARACTER_BUT_STRING_FOUND = tsLiteral("%s expected a character, but string of length %d found"); public static final TruffleString EXPECTED_CONVERSION = tsLiteral("expected conversion"); - public static final TruffleString EXPECTED_FSPATH_TO_RETURN_STR_OR_BYTES = tsLiteral("expected %p.__fspath__() to return str or bytes, not %p"); + public static final TruffleString EXPECTED_FSPATH_TO_RETURN_STR_OR_BYTES = tsLiteral("expected %p.__fspath__() to return str or bytes, not %P"); public static final TruffleString EXPECTED_OBJ_TYPE_S_GOT_P = tsLiteral("expected object of type %s, got %p"); public static final TruffleString EXPECTED_OBJ_TYPE_P_GOT_P = tsLiteral("expected object of type %p, got %p"); public static final TruffleString EXPECTED_S_GOT_P = tsLiteral("expected %s, got %p"); @@ -307,7 +311,7 @@ public abstract class ErrorMessages { public static final TruffleString EXPECTED_S_AFTER_FORMAT_CONVERSION = tsLiteral("expected '%s' after conversion specifier"); public static final TruffleString EXPECTED_S_NODE_GOT_P = tsLiteral("expected %s node, got %p"); public static final TruffleString EXPECTED_SOME_SORT_OF_S_BUT_GOT_S = tsLiteral("expected some sort of %s, but got %s"); - public static final TruffleString EXPECTED_STR_BYTE_OSPATHLIKE_OBJ = tsLiteral("expected str, bytes or os.PathLike object, not %p"); + public static final TruffleString EXPECTED_STR_BYTE_OSPATHLIKE_OBJ = tsLiteral("expected str, bytes or os.PathLike object, not %P"); public static final TruffleString EXPECTED_STR_OR_BYTESLIKE_OBJ = tsLiteral("expected string or bytes-like object"); public static final TruffleString S_EXPECTED_STRING_OF_LEN_BUT_P = tsLiteral("%s expected string of length %s, but %p found"); public static final TruffleString EXPECTED_UNICODE_CHAR_NOT_P = tsLiteral("expected a unicode character, not %p"); @@ -358,7 +362,7 @@ public abstract class ErrorMessages { public static final TruffleString GOT_UNEXPECTED_KEYWORD_ARG = tsLiteral("%s() got an unexpected keyword argument '%s'"); public static final TruffleString HANDLER_MUST_BE_CALLABLE = tsLiteral("handler must be callable"); public static final TruffleString HAS_NO_ATTR = tsLiteral("%p has no attribute '%s'"); - public static final TruffleString TYPE_S_HAS_NO_ATTR = tsLiteral("type object %s has no attribute '%s'"); + public static final TruffleString TYPE_N_HAS_NO_ATTR = tsLiteral("type object %s has no attribute '%s'"); public static final TruffleString P_HAS_NO_ATTRS_S_TO_ASSIGN = tsLiteral("'%p' object has no attributes (assign to .%s)"); public static final TruffleString P_HAS_NO_ATTRS_S_TO_DELETE = tsLiteral("'%p' object has no attributes (del .%s)"); public static final TruffleString P_HAS_RO_ATTRS_S_TO_ASSIGN = tsLiteral("'%p' object has only read-only attributes (assign to .%s)"); @@ -382,6 +386,7 @@ public abstract class ErrorMessages { public static final TruffleString INDEX_OUT_OF_BOUNDS_ON_DIMENSION_D = tsLiteral("index out of bounds on dimension %d"); public static final TruffleString INDEX_OUT_OF_RANGE = tsLiteral("index out of range"); public static final TruffleString INDEX_RETURNED_NON_INT = tsLiteral("__index__ returned non-int (type %p)"); + public static final TruffleString INITIALIZATION_ARGUMENTS_ARE_NOT_SUPPORTED = tsLiteral("Initialization arguments are not supported"); public static final TruffleString INPUT_TOO_LONG = tsLiteral("input too long"); public static final TruffleString INSTANCE_EX_MAY_NOT_HAVE_SEP_VALUE = tsLiteral("instance exception may not have a separate value"); public static final TruffleString INT_CANT_CONVERT_STRING_WITH_EXPL_BASE = tsLiteral("int() can't convert non-string with explicit base"); @@ -399,7 +404,7 @@ public abstract class ErrorMessages { public static final TruffleString INTEROP_CLASS_CREATION_NOT_POSSIBLE = tsLiteral("cannot create the python class for '%s' with collected classes: %s"); public static final TruffleString INVALD_OR_UNREADABLE_CLASSPATH = tsLiteral("invalid or unreadable classpath: '%s' - %m"); public static final TruffleString INVALID_ARGS = tsLiteral("%s: invalid arguments"); - public static final TruffleString INVALID_BASE_TYPE_OBJ_FOR_CLASS = tsLiteral("Invalid base type object for class %s (base type was '%p' object)."); + public static final TruffleString INVALID_BASE_TYPE_OBJ_FOR_CLASS = tsLiteral("Invalid base type object for class %N (base type was '%p' object)."); public static final TruffleString INVALID_CAPI_FUNC = tsLiteral("invalid C API function: %s"); public static final TruffleString INVALID_CONTAINER_FORMAT = tsLiteral("Invalid container format: %d"); public static final TruffleString INVALID_CONVERSION = tsLiteral("invalid conversion"); @@ -443,10 +448,14 @@ public abstract class ErrorMessages { public static final TruffleString ISINSTANCE_ARG_2_MUST_BE_TYPE_OR_TUPLE_OF_TYPE = tsLiteral("isinstance() arg 2 must be a type or tuple of types (was: %s)"); public static final TruffleString ISSUBCLASS_MUST_BE_CLASS_OR_TUPLE = tsLiteral("issubclass() arg 2 must be a class or tuple of classes"); public static final TruffleString ITER_V_MUST_BE_CALLABLE = tsLiteral("iter(v, w): v must be callable"); + public static final TruffleString ITERATION_VALUE_MUST_BE_GREATER_THAN_ZERO = tsLiteral("iteration value must be greater than 0."); + public static final TruffleString ITERATION_VALUE_IS_TOO_GREAT = tsLiteral("iteration value is too great."); + public static final TruffleString KEY_LENGTH_MUST_BE_GREATER_THAN_ZERO = tsLiteral("key length must be greater than 0."); + public static final TruffleString KEY_LENGTH_IS_TOO_GREAT = tsLiteral("key length is too great."); public static final TruffleString KEYWORD_NAMES_MUST_BE_STR_GOT_P = tsLiteral("keyword names must be str, get %p"); public static final TruffleString KEYWORDS_S_MUST_BE_STRINGS = tsLiteral("keywords must be strings"); public static final TruffleString KLASS_ARG_IS_NOT_HOST_OBJ = tsLiteral("klass argument '%p' is not a host object"); - public static final TruffleString LAZY_INITIALIZATION_FAILED = tsLiteral("lazy initialization of type %s failed"); + public static final TruffleString LAZY_INITIALIZATION_FAILED = tsLiteral("lazy initialization of type %N failed"); public static final TruffleString LEFT_BRACKET_WO_RIGHT_BRACKET_IN_ARG = tsLiteral("')' without '(' in argument parsing"); public static final TruffleString LEN_OF_UNSIZED_OBJECT = tsLiteral("len() of unsized object"); public static final TruffleString LEN_SHOULD_RETURN_GT_ZERO = tsLiteral("__len__() should return >= 0"); @@ -501,6 +510,7 @@ public abstract class ErrorMessages { public static final TruffleString MISSING_S = tsLiteral("Missing %s"); public static final TruffleString S_MISSING_REQUIRED_ARG_POS_D = tsLiteral("%s missing required argument (pos %d)"); public static final TruffleString MMAP_INDEX_OUT_OF_RANGE = tsLiteral("mmap index out of range"); + public static final TruffleString MODULE_FILENAME_MISSING = tsLiteral("module filename missing"); public static final TruffleString MODULE_HAS_NO_ATTR_S = tsLiteral("module has no attribute '%s'"); public static final TruffleString MODULE_PARTIALLY_INITIALIZED_S_HAS_NO_ATTR_S = tsLiteral("partially initialized module '%s' has no attribute '%s' (most likely due to a circular import)"); public static final TruffleString MODULE_S_HAS_NO_ATTR_S = tsLiteral("module '%s' has no attribute '%s'"); @@ -527,8 +537,8 @@ public abstract class ErrorMessages { public static final TruffleString MUST_BE_STRING = tsLiteral("%s must be a string"); public static final TruffleString MUST_BE_STRING_QUOTED = tsLiteral("\"%s\" must be a string"); public static final TruffleString MUST_BE_STRINGS_NOT_P = tsLiteral("%s must be strings, not %p"); - public static final TruffleString MUST_BE_TUPLE_OF_CLASSES_NOT_P = tsLiteral("%s.%s must be tuple of classes, not '%p'"); - public static final TruffleString MUST_RETURN_2TUPLE = tsLiteral("%p.__divmod__() must return a 2-tuple, not %p"); + public static final TruffleString MUST_BE_TUPLE_OF_CLASSES_NOT_P = tsLiteral("%N.%s must be tuple of classes, not '%p'"); + public static final TruffleString MUST_RETURN_2TUPLE = tsLiteral("%p.__divmod__() must return a 2-tuple, not %P"); public static final TruffleString S_MUST_RETURN_TUPLE = tsLiteral("%s must return a tuple (object, integer)"); public static final TruffleString MUST_S_ITER_RETURN_2TUPLE = tsLiteral("%s iterator must return 2-tuples"); public static final TruffleString S_MUST_RETURN_S_NOT_P = tsLiteral("%s must return a %s, not %p"); @@ -581,6 +591,7 @@ public abstract class ErrorMessages { public static final TruffleString OBJ_ISNT_MAPPING = tsLiteral("'%p' object is not a mapping"); public static final TruffleString OBJ_ISNT_REVERSIBLE = tsLiteral("'%p' object is not reversible"); public static final TruffleString OBJ_NOT_ITERABLE = tsLiteral("'%p' object is not iterable"); + public static final TruffleString ARGUMENT_OF_TYPE_P_IS_NOT_ITERABLE = tsLiteral("argument of type '%p' is not iterable"); public static final TruffleString OBJ_NOT_SUBSCRIPTABLE = tsLiteral("'%p' object is not subscriptable"); public static final TruffleString TYPE_NOT_SUBSCRIPTABLE = tsLiteral("type '%N' is not subscriptable"); public static final TruffleString OBJ_OR_KLASS_ARGS_IS_NOT_HOST_OBJ = tsLiteral("the object '%p' or klass '%p' arguments is not a host object"); @@ -626,7 +637,7 @@ public abstract class ErrorMessages { public static final TruffleString S_FORMAT_INTEGER_IS_REQUIRED_NOT_S = tsLiteral("%%%s format: an integer is required, not %p"); public static final TruffleString C_ARG_NOT_IN_RANGE256_DECIMAL = tsLiteral("%%c arg not in range(256)"); public static final TruffleString C_REQUIRES_INT_IN_BYTE_RANGE_OR_SINGLE_BYTE = tsLiteral("%%c requires an integer in range(256) or a single byte"); - public static final TruffleString REQUIRES_STRING_AS_LEFT_OPERAND = tsLiteral("'in ' requires string as left operand, not %P"); + public static final TruffleString REQUIRES_STRING_AS_LEFT_OPERAND = tsLiteral("'in ' requires string as left operand, not %p"); public static final TruffleString REQUIRES_STR_OBJECT_BUT_RECEIVED_P = tsLiteral("'%s' requires a 'str' object but received a '%p'"); public static final TruffleString REQUIRED_FIELD_S_MISSING_FROM_S = tsLiteral("required field \"%s\" missing from %s"); public static final TruffleString S_RETURNED_BASE_WITH_UNSUITABLE_LAYOUT = tsLiteral("%s returned base with unsuitable layout ('%p')"); @@ -654,7 +665,7 @@ public abstract class ErrorMessages { public static final TruffleString SHOULD_BE_USED_ONLY_NEW_SETS = tsLiteral("Should be used only on newly allocated empty sets"); public static final TruffleString S_MUST_BE_S = tsLiteral("%s must be %s"); public static final TruffleString S_NOT_SUPPORTED = tsLiteral("%s not supported"); - public static final TruffleString S_S_SHOULD_BE_S_NOT_P = tsLiteral("%s%s should be %s, not %p"); + public static final TruffleString S_S_SHOULD_BE_S_NOT_P = tsLiteral("%s%s should be %s, not %P"); public static final TruffleString S_S_CONFLICTS_WITH_CLASS_VARIABLE = tsLiteral("'%s' in %s conflicts with class variable"); public static final TruffleString S_SHOULD_BE_ASCII_OR_BYTELIKE = tsLiteral("%s should be an ASCII string or a bytes-like object"); public static final TruffleString S_FLOWINFO_RANGE = tsLiteral("%s(): flowinfo must be 0-1048575."); @@ -708,6 +719,7 @@ public abstract class ErrorMessages { public static final TruffleString TAKES_A_D_SEQUENCE = tsLiteral("%s() takes a %d-sequence (%d-sequence given)"); public static final TruffleString TAKES_AN_AT_LEAST_D_SEQUENCE = tsLiteral("%s() takes an at least %d-sequence (%d-sequence given)"); public static final TruffleString TAKES_AN_AT_MOST_D_SEQUENCE = tsLiteral("%s() takes an at most %d-sequence (%d-sequence given)"); + public static final TruffleString UNSUPPORTED_ACCESS_OF_STRUCT_SEQUENCE_NATIVE_STORAGE = tsLiteral("Unsupported access of struct sequence native storage"); public static final TruffleString TAKES_D_OR_D_ARGS = tsLiteral("%s takes %d or %d arguments"); public static final TruffleString TAKES_D_POS_ARG_S_BUT_D_POS_ARG_S = tsLiteral("%s() takes %d positional argument%s but %d positional argument%s (and %d keyword-only argument%s) were given%s"); public static final TruffleString TAKES_D_POS_ARG_S_BUT_GIVEN_S = tsLiteral("%s() takes %d positional argument%s but %d %s given%s"); @@ -769,6 +781,7 @@ public abstract class ErrorMessages { public static final TruffleString UNSIGNED_BYTE_INT_GREATER_THAN_MAX = tsLiteral("unsigned byte integer is greater than maximum"); public static final TruffleString UNSIGNED_BYTE_INT_LESS_THAN_MIN = tsLiteral("unsigned byte integer is less than minimum"); public static final TruffleString UNSUPPORTED_FORMAT_CHAR_AT_INDEX = tsLiteral("unsupported format character '%c' (0x%x) at index %d"); + public static final TruffleString UNSUPPORTED_HASH_TYPE = tsLiteral("unsupported hash type %s"); public static final TruffleString UNSUPPORTED_INSTANCEOF = tsLiteral("unsupported instanceof(%p, %p)"); public static final TruffleString UNSUPPORTED_LOCALE_SETTING = tsLiteral("unsupported locale setting"); public static final TruffleString UNSUPPORTED_OBJ_IN = tsLiteral("unsupported object in '%s'"); @@ -776,7 +789,7 @@ public abstract class ErrorMessages { public static final TruffleString UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P = tsLiteral("unsupported operand type(s) for %s: '%p' and '%p'"); public static final TruffleString UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P_PRINT = cat(UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, tsLiteral(". Did you mean \"print(, file=)\"?")); - public static final TruffleString UNSUPPORTED_OPERAND_TYPES_FOR_S_P_P_P = tsLiteral("unsupported operand type(s) for %s(): '%p', '%p', '%p'"); + public static final TruffleString UNSUPPORTED_OPERAND_TYPES_FOR_S_P_P_P = tsLiteral("unsupported operand type(s) for %s: '%p', '%p', '%p'"); public static final TruffleString UNSUPPORTED_OPERAND_TYPES_FOR_S_PR_S_P_AND_P = tsLiteral("unsupported operand type(s) for %s or %s(): '%p' and '%p'"); public static final TruffleString UNSUPPORTED_SIZE_WAS = tsLiteral("unsupported %s size; was: %d"); public static final TruffleString UNSUPPORTED_STR_TYPE = tsLiteral("unsupported string type: %s"); @@ -875,6 +888,7 @@ public abstract class ErrorMessages { public static final TruffleString BYTES_OR_INT_ADDR_EXPECTED_INSTEAD_OF_P = tsLiteral("bytes or integer address expected instead of %p instance"); public static final TruffleString UNICODE_STR_OR_INT_ADDR_EXPECTED_INSTEAD_OF_P = tsLiteral("unicode string or integer address expected instead of %p instance"); public static final TruffleString N_NOT_SUBTYPE_OF_ARRAY = tsLiteral("%n is not a subtype of array"); + public static final TruffleString FIRST_ARGUMENT_MUST_BE_A_TYPE_OBJECT_NOT_P = tsLiteral("first argument must be a type object, not %p"); public static final TruffleString CANNOT_BE_CONVERTED_TO_POINTER = tsLiteral("cannot be converted to pointer"); public static final TruffleString PY_OBJ_IS_NULL = tsLiteral("PyObject is NULL"); public static final TruffleString OUT_OF_RANGE_FLOAT_NOT_JSON_COMPLIANT = tsLiteral("Out of range float values are not JSON compliant"); @@ -953,7 +967,7 @@ public abstract class ErrorMessages { public static final TruffleString WARN_MUST_BE_SET_CALLABLE = tsLiteral("warnings._showwarnmsg() must be set to a callable"); public static final TruffleString UNABLE_GET_WARN_MSG = tsLiteral("unable to get warnings.WarningMessage"); public static final TruffleString REGISTRY_MUST_BE_DICT = tsLiteral("'registry' must be a dict or None"); - public static final TruffleString CATEGORY_MUST_BE_WARN_SUBCLS = tsLiteral("category must be a Warning subclass, not '%P'"); + public static final TruffleString CATEGORY_MUST_BE_WARN_SUBCLS = tsLiteral("category must be a Warning subclass, not '%p'"); public static final TruffleString INVALID_FILTER_SPECIFIED_FOR_FILTER = tsLiteral("Invalid filter specifier for %s filter"); public static final TruffleString UNSUPPORTED_INTEGRITY_CHECK = tsLiteral("Unsupported integrity check"); public static final TruffleString MEM_USAGE_LIMIT_EXCEEDED = tsLiteral("Memory usage limit exceeded"); @@ -1202,7 +1216,7 @@ public abstract class ErrorMessages { public static final TruffleString FIELDS_MUST_BE_A_SEQUENCE_OF_PAIRS = tsLiteral("'_fields_' must be a sequence of pairs"); public static final TruffleString FIELDS_IS_FINAL = tsLiteral("_fields_ is final"); public static final TruffleString SECOND_ITEM_IN_FIELDS_TUPLE_INDEX_D_MUST_BE_A_C_TYPE = tsLiteral("second item in _fields_ tuple (index %d) must be a C type"); - public static final TruffleString BIT_FIELDS_NOT_ALLOWED_FOR_TYPE_S = tsLiteral("bit fields not allowed for type %s"); + public static final TruffleString BIT_FIELDS_NOT_ALLOWED_FOR_TYPE_N = tsLiteral("bit fields not allowed for type %N"); public static final TruffleString NUMBER_OF_BITS_INVALID_FOR_BIT_FIELD = tsLiteral("number of bits invalid for bit field"); public static final TruffleString STRUCTURE_OR_UNION_CANNOT_CONTAIN_ITSELF = tsLiteral("Structure or union cannot contain itself"); public static final TruffleString FIELDS_MUST_BE_A_SEQUENCE_OF_NAME_C_TYPE_PAIRS = tsLiteral("'_fields_' must be a sequence of (name, C type) pairs"); @@ -1228,14 +1242,14 @@ public abstract class ErrorMessages { public static final TruffleString COULD_NOT_CONVERT_THE_HANDLE_ATTRIBUTE_TO_A_POINTER = tsLiteral("could not convert the _handle attribute to a pointer"); public static final TruffleString NO_ALIGNMENT_INFO = tsLiteral("no alignment info"); public static final TruffleString THIS_TYPE_HAS_NO_SIZE = tsLiteral("this type has no size"); - public static final TruffleString BYREF_ARGUMENT_MUST_BE_A_CTYPES_INSTANCE_NOT_S = tsLiteral("byref() argument must be a ctypes instance, not '%s'"); + public static final TruffleString BYREF_ARGUMENT_MUST_BE_A_CTYPES_INSTANCE_NOT_P = tsLiteral("byref() argument must be a ctypes instance, not '%p'"); public static final TruffleString INVALID_TYPE = tsLiteral("invalid type"); public static final TruffleString TOO_MANY_ARGUMENTS_D_MAXIMUM_IS_D = tsLiteral("too many arguments (%d), maximum is %d"); public static final TruffleString ARGUMENT_D = tsLiteral("argument %d: "); public static final TruffleString FFI_CALL_FAILED = tsLiteral("ffi_call failed"); public static final TruffleString FFI_PREP_CIF_FAILED = tsLiteral("ffi_prep_cif failed"); public static final TruffleString INT_TOO_LONG_TO_CONVERT = tsLiteral("int too long to convert"); - public static final TruffleString CAST_ARGUMENT_2_MUST_BE_A_POINTER_TYPE_NOT_S = tsLiteral("cast() argument 2 must be a pointer type, not %s"); + public static final TruffleString CAST_ARGUMENT_2_MUST_BE_A_POINTER_TYPE_NOT_N = tsLiteral("cast() argument 2 must be a pointer type, not %N"); public static final TruffleString WRONG_TYPE = tsLiteral("wrong type"); public static final TruffleString INVALID_RESULT_TYPE_FOR_CALLBACK_FUNCTION = tsLiteral("invalid result type for callback function"); public static final TruffleString INVALID_INDEX = tsLiteral("invalid index"); @@ -1250,7 +1264,7 @@ public abstract class ErrorMessages { public static final TruffleString CLASS_MUST_DEFINE_A_TYPE_ATTRIBUTE = tsLiteral("class must define a '_type_' attribute"); public static final TruffleString TYPE_MUST_HAVE_STORAGE_INFO = tsLiteral("_type_ must have storage info"); public static final TruffleString ARRAY_TOO_LARGE = tsLiteral("array too large"); - public static final TruffleString OUT_PARAMETER_D_MUST_BE_A_POINTER_TYPE_NOT_S = tsLiteral("'out' parameter %d must be a pointer type, not %s"); + public static final TruffleString OUT_PARAMETER_D_MUST_BE_A_POINTER_TYPE_NOT_N = tsLiteral("'out' parameter %d must be a pointer type, not %N"); public static final TruffleString ARGUMENT_MUST_BE_CALLABLE_OR_INTEGER_FUNCTION_ADDRESS = tsLiteral("argument must be callable or integer function address"); public static final TruffleString CANNOT_CONSTRUCT_INSTANCE_OF_THIS_CLASS_NO_ARGTYPES = tsLiteral("cannot construct instance of this class: no argtypes"); public static final TruffleString THE_ERRCHECK_ATTRIBUTE_MUST_BE_CALLABLE = tsLiteral("the errcheck attribute must be callable"); @@ -1261,7 +1275,7 @@ public abstract class ErrorMessages { public static final TruffleString NOT_ENOUGH_ARGUMENTS = tsLiteral("not enough arguments"); public static final TruffleString NO_POSITIONAL_ARGUMENTS_EXPECTED = tsLiteral("no positional arguments expected"); public static final TruffleString NULL_STGDICT_UNEXPECTED = tsLiteral("NULL stgdict unexpected"); - public static final TruffleString S_OUT_PARAMETER_MUST_BE_PASSED_AS_DEFAULT_VALUE = tsLiteral("%s 'out' parameter must be passed as default value"); + public static final TruffleString N_OUT_PARAMETER_MUST_BE_PASSED_AS_DEFAULT_VALUE = tsLiteral("%N 'out' parameter must be passed as default value"); public static final TruffleString PARAMFLAG_D_NOT_YET_IMPLEMENTED = tsLiteral("paramflag %d not yet implemented"); public static final TruffleString CALL_TAKES_EXACTLY_D_ARGUMENTS_D_GIVEN = tsLiteral("call takes exactly %d arguments (%d given)"); public static final TruffleString PARAMFLAGS_MUST_BE_A_TUPLE_OR_NONE = tsLiteral("paramflags must be a tuple or None"); @@ -1295,7 +1309,7 @@ public abstract class ErrorMessages { public static final TruffleString DUPLICATE_VALUES_FOR_FIELD_S = tsLiteral("duplicate values for field %s"); public static final TruffleString EXPECTED_P_INSTANCE_INSTEAD_OF_POINTER_TO_P = tsLiteral("expected %p instance instead of pointer to %p"); public static final TruffleString CTYPES_OBJECTS_CONTAINING_POINTERS_CANNOT_BE_PICKLED = tsLiteral("ctypes objects containing pointers cannot be pickled"); - public static final TruffleString S_DICT_MUST_BE_A_DICTIONARY_NOT_S = tsLiteral("%s.__dict__ must be a dictionary, not %s"); + public static final TruffleString P_DICT_MUST_BE_A_DICTIONARY_NOT_P = tsLiteral("%p.__dict__ must be a dictionary, not %p"); public static final TruffleString STRING_TOO_LONG = tsLiteral("string too long"); public static final TruffleString UNICODE_STRING_EXPECTED_INSTEAD_OF_P_INSTANCE = tsLiteral("unicode string expected instead of %p instance"); public static final TruffleString BYTES_EXPECTED_INSTEAD_OF_P_INSTANCE = tsLiteral("bytes expected instead of %p instance"); @@ -1427,64 +1441,10 @@ public abstract class ErrorMessages { public static final TruffleString NULL_ARG_INTERNAL = tsLiteral("null argument to internal routine"); - // HPy - - public static final TruffleString UNSUPPORTED_HYPMETH_SIG = tsLiteral("Unsupported HPyMeth signature"); - public static final TruffleString NULL_CHAR_PASSED = tsLiteral("NULL char * passed to HPyBytes_FromStringAndSize"); - public static final TruffleString CAPSULE_GETDESTRUCTOR_WITH_INVALID_CAPSULE = tsLiteral("HPyCapsule_GetDestructor called with invalid PyCapsule object"); - public static final TruffleString CAPSULE_GETPOINTER_WITH_INVALID_CAPSULE = tsLiteral("HPyCapsule_GetPointer called with invalid PyCapsule object"); - public static final TruffleString CAPSULE_GETCONTEXT_WITH_INVALID_CAPSULE = tsLiteral("HPyCapsule_GetContext called with invalid PyCapsule object"); - public static final TruffleString CAPSULE_GETNAME_WITH_INVALID_CAPSULE = tsLiteral("HPyCapsule_GetName called with invalid PyCapsule object"); - public static final TruffleString HPY_NEW_ARG_1_MUST_BE_A_TYPE = tsLiteral("HPy_New arg 1 must be a type"); - public static final TruffleString ERROR_LOADING_HPY_EXT_S_S = tsLiteral("Error during loading of the HPy extension module at path '%s'. Function HPyInit_'%s' returned NULL."); - public static final TruffleString HPY_CAPI_SYM_NOT_CALLABLE = tsLiteral("HPy C API symbol %s is not callable"); - public static final TruffleString HPY_CALLTUPLEDICT_REQUIRES_ARGS_TUPLE_OR_NULL = tsLiteral("HPy_CallTupleDict requires args to be a tuple or null handle"); - public static final TruffleString HPY_CALLTUPLEDICT_REQUIRES_KW_DICT_OR_NULL = tsLiteral("HPy_CallTupleDict requires kw to be a dict or null handle"); - public static final TruffleString CANNOT_INITIALIZE_EXT_NO_ENTRY = tsLiteral("cannot initialize extension '%s' at path '%s', entry point '%s' not found"); - public static final TruffleString HPY_S_MODE_NOT_AVAILABLE = tsLiteral("HPy %s mode is not available"); - public static final TruffleString HPY_UNEXPECTED_HPY_NULL = tsLiteral("unexpected HPy_NULL"); - public static final TruffleString HPY_MOD_CREATE_RETURNED_BUILTIN_MOD = tsLiteral("HPy_mod_create slot returned a builtin module object. This is currently not supported."); - public static final TruffleString HPYCAPSULE_NEW_NULL_PTR_ERROR = tsLiteral("HPyCapsule_New called with null pointer"); - public static final TruffleString INVALID_HPYCAPSULE_DESTRUCTOR = tsLiteral("Invalid HPyCapsule destructor"); - public static final TruffleString HPY_MODE_VALUE_MUST_BE_STRING = tsLiteral("Value of HPy mode environment variable must be a string"); - public static final TruffleString HPY_METACLASS_IS_NOT_A_TYPE = tsLiteral("Metaclass '%s' is not a subclass of 'type'."); - public static final TruffleString HPY_METACLASS_WITH_CUSTOM_CONS_NOT_SUPPORTED = tsLiteral("Metaclasses with custom constructor are not supported."); - public static final TruffleString HPY_ERROR_LOADING_EXT_MODULE = tsLiteral("Error during loading of the HPy extension module at path '%s'. " + - "Cannot locate the required minimal HPy versions as symbols '%s' and `%s`. Error message from dlopen/WinAPI: %s"); - public static final TruffleString HPY_ABI_VERSION_ERROR = tsLiteral("HPy extension module '%s' requires unsupported version of the HPy runtime. " + - "Requested version: %d.%d. Current HPy version: %d.%d."); - public static final TruffleString HPY_ABI_TAG_MISMATCH = tsLiteral("HPy extension module '%s' at path '%s': mismatch between the HPy ABI tag encoded in the filename " + - "and the major version requested by the HPy extension itself. Major version tag parsed from filename: %d. Requested version: %d.%d."); - public static final TruffleString HPY_NO_ABI_TAG = tsLiteral("HPy extension module '%s' at path '%s': could not find HPy ABI tag encoded in the filename. " + - "The extension claims to be compiled with HPy ABI version: %d.%d."); - public static final TruffleString HPY_INVALID_SOURCE_KIND = tsLiteral("invalid source kind"); - public static final TruffleString HPY_OBJECT_DOES_NOT_SUPPORT_CALL = tsLiteral("'%p' object does not support HPy call protocol"); - public static final TruffleString HPY_TYPE_DOES_NOT_IMPLEMENT_CALL_PROTOCOL = tsLiteral("type '%p' does not implement the HPy call protocol"); - public static final TruffleString HPY_METACLASS_SPECIFIED_MULTIPLE_TIMES = tsLiteral("metaclass was specified multiple times"); - public static final TruffleString HPY_INVALID_BUILTIN_SHAPE = tsLiteral("invalid shape: %d"); - public static final TruffleString HPY_CANNOT_USE_CALL_WITH_VAR_OBJECTS = tsLiteral("Cannot use HPy call protocol with var objects"); - public static final TruffleString HPY_CANNOT_HAVE_CALL_AND_VECTORCALLOFFSET = tsLiteral("Cannot have HPy_tp_call and explicit member '__vectorcalloffset__'. Specify just one of them."); - public static final TruffleString HPY_CANNOT_SPECIFY_LEG_SLOTS_WO_SETTING_LEG = tsLiteral("cannot specify .legacy_slots without setting .builtin_shape=HPyType_BuiltinShape_Legacy"); - public static final TruffleString HPY_CANNOT_USE_CALL_WITH_LEGACY = tsLiteral("Cannot use HPy call protocol with legacy types that inherit the struct. " + - "Either set the basicsize to a non-zero value or use legacy slot 'Py_tp_call'."); public static final TruffleString NFI_NOT_AVAILABLE = tsLiteral("GraalPy option '%s' is set to '%s, but the 'nfi' language, which is required for this feature, is not available. " + "If this is a GraalPy standalone distribution: this indicates internal error. If GraalPy was used as a Maven dependency: " + "are you missing a runtime dependency 'org.graalvm.truffle:truffle-nfi-libffi', which should be a dependency of 'org.graalvm.polyglot:python{-community}'?"); - public static final TruffleString LLVM_NOT_AVAILABLE = tsLiteral("GraalPy option 'NativeModules' is set to false, but the 'llvm' language, which is required for this feature, is not available. " + - "If this is a GraalPy standalone distribution: this indicates internal error. If GraalPy was used as a Maven dependency: are you missing a runtime dependency " + - "'org.graalvm.polyglot:llvm{-community}'?"); - public static final TruffleString HPY_CANNOT_USE_JNI_BACKEND = tsLiteral("Cannot use HPy JNI backend because JNI access is forbidden."); - public static final TruffleString HPY_NFI_NOT_YET_IMPLEMENTED = tsLiteral("HPy NFI backend is not yet implemented"); - public static final TruffleString HPY_UNKNOWN_BACKEND = tsLiteral("unknown HPy backend: "); - private static final String HPY_NON_DEFAULT_MESSAGE = "This is not allowed because custom HPy_mod_create slot cannot return a builtin module object and cannot make any use of any other " + - "data defined in the HPyModuleDef. Either do not define HPy_mod_create slot and let the runtime create a builtin module object from the provided HPyModuleDef, or do not " + - "define anything else but the HPy_mod_create slot."; - public static final TruffleString HPY_DEFINES_CREATE_AND_NON_DEFAULT = tsLiteral("HPyModuleDef defines a HPy_mod_create slot and some of the other fields are not set to their default value. " + - HPY_NON_DEFAULT_MESSAGE); - public static final TruffleString HPY_DEFINES_CREATE_AND_OTHER_SLOTS = tsLiteral("HPyModuleDef defines a HPy_mod_create slot and some other slots or methods. " + - HPY_NON_DEFAULT_MESSAGE); - // AST Validator public static final TruffleString ANN_ASSIGN_WITH_SIMPLE_NON_NAME_TARGET = tsLiteral("AnnAssign with simple non-Name target"); public static final TruffleString BOOL_OP_WITH_LESS_THAN_2_VALUES = tsLiteral("BoolOp with less than 2 values"); @@ -1518,9 +1478,9 @@ public abstract class ErrorMessages { public static final TruffleString PY_CAPSULE_IMPORT_S_IS_NOT_VALID = tsLiteral("PyCapsule_Import \"%s\" is not valid"); // asyncio - public static final TruffleString CANNOT_BE_USED_AWAIT = tsLiteral("object %s can't be used in 'await' expression"); + public static final TruffleString CANNOT_BE_USED_AWAIT = tsLiteral("object %N can't be used in 'await' expression"); public static final TruffleString AWAIT_RETURN_COROUTINE = tsLiteral("__await__() returned a coroutine"); - public static final TruffleString AWAIT_RETURN_NON_ITER = tsLiteral("__await__() returned non-iterator of type '%s'"); + public static final TruffleString AWAIT_RETURN_NON_ITER = tsLiteral("__await__() returned non-iterator of type '%N'"); public static final TruffleString NO_RUNNING_EVENT_LOOP = tsLiteral("no running event loop"); public static final TruffleString CANT_ENTER_TASK_ALREADY_RUNNING = tsLiteral("Cannot enter into task %s while another task %s is being executed."); public static final TruffleString TASK_NOT_ENTERED = tsLiteral("Leaving task %s does not match the current task %s."); @@ -1541,7 +1501,7 @@ public abstract class ErrorMessages { public static final TruffleString DECODING_ERROR_HANDLER_MUST_RETURN = tsLiteral("decoding error handler must return (str, int) tuple"); public static final TruffleString ARG_MUST_BE_A_SEQUENCE_OBJECT = tsLiteral("arg must be a sequence object"); - public static final TruffleString STREAM_FUNCTION_RETURNED_A_NON_BYTES_OBJECT_S = tsLiteral("stream function returned a non-bytes object (%s)"); + public static final TruffleString STREAM_FUNCTION_RETURNED_A_NON_BYTES_OBJECT_P = tsLiteral("stream function returned a non-bytes object (%p)"); public static final TruffleString CANNOT_BUILD_PARAMETER = tsLiteral("cannot build parameter"); public static final TruffleString ON_CALLING_CTYPES_CALLBACK_FUNCTION = tsLiteral("on calling ctypes callback function"); @@ -1550,12 +1510,12 @@ public abstract class ErrorMessages { public static final TruffleString INDEX_EXCEEDS_INT = tsLiteral("index exceeds integer size"); public static final TruffleString X_NOT_IN_SEQUENCE = tsLiteral("sequence.index(x): x not in sequence"); - public static final TruffleString ASYNC_FOR_NO_AITER = tsLiteral("'async for' requires object with __aiter__ method, got %s"); - public static final TruffleString ASYNC_FOR_NO_ANEXT_INITIAL = tsLiteral("'async for' received an object from __aiter__ that does not implement __anext__: %s"); + public static final TruffleString ASYNC_FOR_NO_AITER = tsLiteral("'async for' requires object with __aiter__ method, got %N"); + public static final TruffleString ASYNC_FOR_NO_ANEXT_INITIAL = tsLiteral("'async for' received an object from __aiter__ that does not implement __anext__: %p"); public static final TruffleString ASYNC_FOR_NO_ANEXT_ITERATION = tsLiteral("'async for' requires an iterator with __anext__ method, got %p"); public static final TruffleString CANNOT_REUSE_ASEND = tsLiteral("cannot reuse already awaited __anext__()/asend()"); - public static final TruffleString OBJECT_NOT_ASYNCGEN = tsLiteral("'%s' object is not an async generator"); + public static final TruffleString OBJECT_NOT_ASYNCGEN = tsLiteral("'%p' object is not an async generator"); public static final TruffleString CANNOT_REUSE_ATHROW = tsLiteral("cannot reuse already awaited aclose()/athrow()"); public static final TruffleString CANNOT_REUSE_CORO = tsLiteral("cannot reuse already awaited coroutine"); public static final TruffleString AGEN_ALREADY_RUNNING = tsLiteral("anext(): asynchronous generator is already running"); @@ -1685,6 +1645,6 @@ public abstract class ErrorMessages { "The sys.prefix must be a str, not '%p' when the `IsolateNativeModules' option is used, because it is the base path for searching the relocated C API. " + "Refer to https://www.graalvm.org/latest/reference-manual/python/Native-Extensions for details on native module isolation."); public static final TruffleString SYS_PREFIX_MUST_POINT_TO_A_VENV_FOR_CAPI_ISOLATION = tsLiteral( - "The sys.prefix must point to a venv, not be identical to sys.base_prefix when the `IsolateNativeModules' option is used, because it is the base path for searching and creating the relocated C API and extension modules. " + + "The sys.prefix must point to a writable venv folder or the system default temporary directory needs to be writable when the `IsolateNativeModules' option is used, because it is the base path for searching and creating the relocated C API and extension modules. " + "Refer to https://www.graalvm.org/latest/reference-manual/python/Native-Extensions for details on native module isolation."); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/HiddenAttr.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/HiddenAttr.java index 25e70a06da..ae1b21cf81 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/HiddenAttr.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/HiddenAttr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -101,10 +101,10 @@ public final class HiddenAttr { public static final HiddenAttr PROMOTED_START = new HiddenAttr("promoted_start"); // PythonCextSlotBuiltins public static final HiddenAttr PROMOTED_STEP = new HiddenAttr("promoted_step"); // PythonCextSlotBuiltins public static final HiddenAttr PROMOTED_STOP = new HiddenAttr("promoted_stop"); // PythonCextSlotBuiltins - public static final HiddenAttr METHODS_FLAGS = new HiddenAttr("__methods_flags__"); // GetMethodsFlagsNode public static final HiddenAttr NATIVE_STORAGE = new HiddenAttr("native_storage"); public static final HiddenAttr NATIVE_SLOTS = new HiddenAttr("__native_slots__"); public static final HiddenAttr INSTANCESHAPE = new HiddenAttr("instanceshape"); + public static final HiddenAttr STRUCTSEQ_FIELD_NAMES = new HiddenAttr("struct_seq_field_names"); private final HiddenKey key; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PConstructAndRaiseNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PConstructAndRaiseNode.java index 42e4771020..0011380ccc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PConstructAndRaiseNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PConstructAndRaiseNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -54,7 +54,7 @@ import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.ssl.SSLErrorCode; import com.oracle.graal.python.nodes.PConstructAndRaiseNodeGen.LazyNodeGen; -import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode; +import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException; import com.oracle.graal.python.runtime.PosixSupportLibrary.UnsupportedPosixFeatureException; import com.oracle.graal.python.runtime.PythonContext; @@ -95,7 +95,7 @@ private static TruffleString getFormattedMessage(TruffleString format, Object[] } private PException raiseInternal(VirtualFrame frame, PythonBuiltinClassType type, Object cause, Object[] arguments, PKeyword[] keywords, - CallVarargsMethodNode callNode, Python3Core core, TruffleString.FromJavaStringNode fromJavaStringNode) { + CallNode callNode, Python3Core core, TruffleString.FromJavaStringNode fromJavaStringNode) { if (arguments != null) { for (int i = 0; i < arguments.length; ++i) { if (arguments[i] instanceof String) { @@ -115,7 +115,7 @@ private PException raiseInternal(VirtualFrame frame, PythonBuiltinClassType type PException constructAndRaiseNoFormatString(VirtualFrame frame, PythonBuiltinClassType type, Object cause, @SuppressWarnings("unused") TruffleString format, @SuppressWarnings("unused") Object[] formatArgs, Object[] arguments, PKeyword[] keywords, - @Cached.Shared("callNode") @Cached CallVarargsMethodNode callNode, + @Cached.Shared("callNode") @Cached CallNode callNode, @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode) { Python3Core core = PythonContext.get(this); return raiseInternal(frame, type, cause, arguments, keywords, callNode, core, fromJavaStringNode); @@ -124,7 +124,7 @@ PException constructAndRaiseNoFormatString(VirtualFrame frame, PythonBuiltinClas @Specialization(guards = {"format != null", "arguments == null"}) PException constructAndRaiseNoArgs(VirtualFrame frame, PythonBuiltinClassType type, Object cause, TruffleString format, Object[] formatArgs, @SuppressWarnings("unused") Object[] arguments, PKeyword[] keywords, - @Cached.Shared("callNode") @Cached CallVarargsMethodNode callNode, + @Cached.Shared("callNode") @Cached CallNode callNode, @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode) { Python3Core core = PythonContext.get(this); Object[] args = new Object[]{formatArgs != null ? getFormattedMessage(format, formatArgs) : format}; @@ -134,7 +134,7 @@ PException constructAndRaiseNoArgs(VirtualFrame frame, PythonBuiltinClassType ty @Specialization(guards = {"format != null", "arguments != null"}) PException constructAndRaise(VirtualFrame frame, PythonBuiltinClassType type, Object cause, TruffleString format, Object[] formatArgs, Object[] arguments, PKeyword[] keywords, - @Cached.Shared("callNode") @Cached CallVarargsMethodNode callNode, + @Cached.Shared("callNode") @Cached CallNode callNode, @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode) { Python3Core core = PythonContext.get(this); Object[] args = new Object[arguments.length + 1]; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java index 77e3587a07..b25e29ddaf 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java @@ -57,30 +57,22 @@ import com.oracle.graal.python.builtins.objects.cext.PythonNativeObject; import com.oracle.graal.python.builtins.objects.cext.capi.PythonNativeWrapper; import com.oracle.graal.python.builtins.objects.cext.common.NativePointer; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyHandle; -import com.oracle.graal.python.builtins.objects.cext.hpy.PythonHPyObject; import com.oracle.graal.python.builtins.objects.code.PCode; import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; import com.oracle.graal.python.builtins.objects.common.EmptyStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorage; import com.oracle.graal.python.builtins.objects.common.PHashingCollection; import com.oracle.graal.python.builtins.objects.complex.PComplex; +import com.oracle.graal.python.builtins.objects.dict.DictBuiltins; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.dict.PDictView; import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis; import com.oracle.graal.python.builtins.objects.exception.PBaseException; import com.oracle.graal.python.builtins.objects.floats.PFloat; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.BinaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.TernaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.UnaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptors; -import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; import com.oracle.graal.python.builtins.objects.function.PFunction; import com.oracle.graal.python.builtins.objects.getsetdescriptor.DescriptorDeleteMarker; import com.oracle.graal.python.builtins.objects.ints.PInt; -import com.oracle.graal.python.builtins.objects.iterator.PSequenceIterator; import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; @@ -99,12 +91,12 @@ import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; -import com.oracle.graal.python.builtins.objects.type.PythonClass; import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyIndexCheckNode; -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; +import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage; @@ -116,60 +108,21 @@ import com.oracle.graal.python.runtime.sequence.storage.NativeObjectSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; -import com.oracle.graal.python.util.OverflowException; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Idempotent; import com.oracle.truffle.api.exception.AbstractTruffleException; -import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.UnexpectedResultException; -import com.oracle.truffle.api.profiles.ConditionProfile; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleString; import com.oracle.truffle.api.strings.TruffleString.CodeRange; public abstract class PGuards { - /** - * Specialization guards. - */ - - public static boolean stringEquals(String expected, String other, ConditionProfile profile) { - if (profile.profile(expected == other)) { - return true; - } - return expected.equals(other); - } - - public static boolean stringEquals(String expected, String other, Node inliningTarget, InlinedConditionProfile profile) { - if (profile.profile(inliningTarget, expected == other)) { - return true; - } - return expected.equals(other); - } - - public static boolean stringEquals(TruffleString expected, TruffleString other, TruffleString.EqualNode equalNode, ConditionProfile profile) { - if (profile.profile(expected == other)) { - return true; - } - return equalNode.execute(expected, other, TS_ENCODING); - } - - public static boolean stringEquals(TruffleString expected, TruffleString other, TruffleString.EqualNode equalNode, Node inliningTarget, InlinedConditionProfile profile) { - if (profile.profile(inliningTarget, expected == other)) { - return true; - } - return equalNode.execute(expected, other, TS_ENCODING); - } public static boolean stringEquals(TruffleString key, TruffleString cachedKey, TruffleString.EqualNode equalNode) { return equalNode.execute(cachedKey, key, TS_ENCODING); } - public static boolean isSameObject(Object left, Object right) { - return left == right; - } - public static boolean isEmpty(Object[] array) { return array.length == 0; } @@ -229,27 +182,10 @@ public static boolean isCallable(Object value) { return value instanceof PBuiltinFunction || value instanceof PFunction || value instanceof PBuiltinMethod || value instanceof PMethod; } - /** - * Use instead of {@link #isCallable(Object)} for objects coming from - * {@link com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode}. Note that such - * objects can be then forwarded only to call nodes that support them. - */ - public static boolean isCallableOrDescriptor(Object value) { - return isCallable(value) || BuiltinMethodDescriptor.isInstance(value); - } - - public static boolean isBuiltinDescriptor(Object value) { - return BuiltinMethodDescriptor.isInstance(value); - } - public static boolean isClass(Node inliningTarget, Object obj, TypeNodes.IsTypeNode isTypeNode) { return isTypeNode.execute(inliningTarget, obj); } - public static boolean isClassUncached(Object obj) { - return TypeNodes.IsTypeNode.executeUncached(obj); - } - public static boolean isEmptyStorage(PSequence sequence) { return sequence.getSequenceStorage() instanceof EmptySequenceStorage; } @@ -262,38 +198,18 @@ public static boolean isByteStorage(PSequence array) { return array.getSequenceStorage() instanceof ByteSequenceStorage; } - public static boolean areBothIntStorage(PSequence first, PSequence second) { - return first.getSequenceStorage() instanceof IntSequenceStorage && second.getSequenceStorage() instanceof IntSequenceStorage; - } - - public static boolean areBothByteStorage(PSequence first, PSequence second) { - return first.getSequenceStorage() instanceof ByteSequenceStorage && second.getSequenceStorage() instanceof ByteSequenceStorage; - } - public static boolean isLongStorage(PSequence sequence) { return sequence.getSequenceStorage() instanceof LongSequenceStorage; } - public static boolean areBothLongStorage(PList first, PList second) { - return first.getSequenceStorage() instanceof LongSequenceStorage && second.getSequenceStorage() instanceof LongSequenceStorage; - } - public static boolean isDoubleStorage(PSequence sequence) { return sequence.getSequenceStorage() instanceof DoubleSequenceStorage; } - public static boolean areBothDoubleStorage(PList first, PList second) { - return first.getSequenceStorage() instanceof DoubleSequenceStorage && second.getSequenceStorage() instanceof DoubleSequenceStorage; - } - public static boolean isObjectStorage(PSequence list) { return list.getSequenceStorage() instanceof ObjectSequenceStorage; } - public static boolean areBothObjectStorage(PList first, PList second) { - return first.getSequenceStorage() instanceof ObjectSequenceStorage && second.getSequenceStorage() instanceof ObjectSequenceStorage; - } - public static boolean isForeignSequenceStorage(SequenceStorage sequenceStorage) { return sequenceStorage instanceof ForeignSequenceStorage; } @@ -310,20 +226,6 @@ public static boolean isEconomicMapOrEmpty(HashingStorage self) { return self instanceof EconomicMapStorage || self instanceof EmptyStorage; } - public static boolean isObjectStorageIterator(PSequenceIterator iterator) { - if (!iterator.isPSequence()) { - return false; - } - - PSequence sequence = iterator.getPSequence(); - - if (sequence instanceof PList list) { - return list.getSequenceStorage() instanceof ObjectSequenceStorage; - } - - return false; - } - public static boolean isPythonObject(Object obj) { return obj instanceof PythonObject; } @@ -332,41 +234,6 @@ public static boolean isPythonModule(Object obj) { return obj instanceof PythonModule; } - /** - * Argument guards. - */ - public static boolean emptyArguments(VirtualFrame frame) { - return PArguments.getUserArgumentLength(frame) == 0; - } - - public static boolean argGiven(Object object) { - return object == PNone.NO_VALUE; - } - - public static boolean emptyArguments(PNone none) { - return none == PNone.NO_VALUE; - } - - public static boolean isIndexPositive(int idx) { - return idx >= 0; - } - - public static boolean isIndexNegative(int idx) { - return idx < 0; - } - - public static boolean isIndexPositive(long idx) { - return idx >= 0; - } - - public static boolean isIndexNegative(long idx) { - return idx < 0; - } - - public static boolean isPythonUserClass(Object klass) { - return klass instanceof PythonClass || PythonNativeClass.isInstance(klass); - } - public static boolean isPythonBuiltinClassType(Object klass) { return klass instanceof PythonBuiltinClassType; } @@ -564,14 +431,6 @@ public static boolean isCDataObject(Object obj) { return obj instanceof CDataObject; } - public static boolean isHPyHandle(Object obj) { - return obj instanceof GraalHPyHandle; - } - - public static boolean isHPyObject(Object obj) { - return obj instanceof PythonHPyObject; - } - public static boolean expectBoolean(Object result) throws UnexpectedResultException { if (result instanceof Boolean) { return (Boolean) result; @@ -586,16 +445,6 @@ public static int expectInteger(Object result) throws UnexpectedResultException throw new UnexpectedResultException(result); } - public static int expectInt(Object result) throws UnexpectedResultException, OverflowException { - if (result instanceof Integer) { - return (Integer) result; - } - if (result instanceof Long) { - return PInt.intValueExact((Long) result); - } - throw new UnexpectedResultException(result); - } - public static long expectLong(Object result) throws UnexpectedResultException { if (result instanceof Long) { return (Long) result; @@ -673,22 +522,6 @@ public static boolean isKindOfBuiltinClass(Object clazz) { return clazz instanceof PythonBuiltinClassType || clazz instanceof PythonBuiltinClass; } - public static boolean isUnaryBuiltinDescriptor(Object value) { - return value instanceof UnaryBuiltinDescriptor; - } - - public static boolean isBinaryBuiltinDescriptor(Object value) { - return value instanceof BinaryBuiltinDescriptor; - } - - public static boolean isTernaryBuiltinDescriptor(Object value) { - return value instanceof TernaryBuiltinDescriptor; - } - - public static boolean isMinusOne(long l) { - return l == -1; - } - public static boolean isAscii(TruffleString str, TruffleString.GetCodeRangeNode getCodeRangeNode) { return getCodeRangeNode.execute(str, TS_ENCODING) == CodeRange.ASCII; } @@ -715,7 +548,12 @@ public static boolean isNullOrZero(Object value, InteropLibrary lib) { } /* CPython tests that tp_iter is dict_iter */ - public static boolean hasBuiltinDictIter(Node inliningTarget, PDict dict, GetPythonObjectClassNode getClassNode, LookupCallableSlotInMRONode lookupIter) { - return isBuiltinDict(dict) || lookupIter.execute(getClassNode.execute(inliningTarget, dict)) == BuiltinMethodDescriptors.DICT_ITER; + public static boolean hasBuiltinDictIter(Node inliningTarget, PDict dict, GetPythonObjectClassNode getClassNode, GetCachedTpSlotsNode getSlots) { + return isBuiltinDict(dict) || getSlots.execute(inliningTarget, getClassNode.execute(inliningTarget, dict)).tp_iter() == DictBuiltins.SLOTS.tp_iter(); + } + + @Idempotent + public static boolean isBytecodeDSLInterpreter() { + return PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PNodeWithContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PNodeWithContext.java index f942d29e5d..03ebc57a10 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PNodeWithContext.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PNodeWithContext.java @@ -41,7 +41,6 @@ package com.oracle.graal.python.nodes; import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.runtime.PosixSupport; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonOptions; @@ -52,18 +51,9 @@ import com.oracle.truffle.api.dsl.NonIdempotent; import com.oracle.truffle.api.nodes.Node; -@ImportStatic({PGuards.class, PythonOptions.class, SpecialMethodNames.class, SpecialAttributeNames.class, SpecialMethodSlot.class, BuiltinNames.class}) +@ImportStatic({PGuards.class, PythonOptions.class, SpecialMethodNames.class, SpecialAttributeNames.class, BuiltinNames.class}) public abstract class PNodeWithContext extends Node { - /** - * @return {@code true} if this node can be shared statically. - */ - @Idempotent - // conflicting with Node.isUncached(). Should be migrated to Node.isUncached() in the future. - protected final boolean isUncachedNode() { - return !isAdoptable(); - } - @TruffleBoundary public static void printStack() { // a convenience methods for debugging diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRaiseNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRaiseNode.java index 4d0883a97f..64c1668d8f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRaiseNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRaiseNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,233 +41,215 @@ package com.oracle.graal.python.nodes; import static com.oracle.graal.python.nodes.ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC; -import static com.oracle.graal.python.nodes.truffle.TruffleStringMigrationHelpers.assertNoJavaString; import static com.oracle.graal.python.runtime.exception.PythonErrorType.OverflowError; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; -import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.exception.AttributeErrorBuiltins; import com.oracle.graal.python.builtins.objects.exception.PBaseException; -import com.oracle.graal.python.nodes.PRaiseNodeGen.LazyNodeGen; +import com.oracle.graal.python.lib.PyExceptionInstanceCheckNode; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.strings.TruffleString; -@ImportStatic(PGuards.class) +@GenerateInline +@GenerateCached(false) @GenerateUncached -@SuppressWarnings("truffle-inlining") // footprint reduction 32 -> 13 public abstract class PRaiseNode extends Node { - public final PException execute(Node raisingNode, PythonBuiltinClassType type, Object cause, Object format, Object[] arguments) { - return execute(raisingNode, type, null, cause, format, arguments); - } - - public abstract PException execute(Node raisingNode, PythonBuiltinClassType type, Object[] data, Object cause, Object format, Object[] arguments); + protected abstract void executeEnterProfile(Node inliningTarget); - public final PException raise(PythonBuiltinClassType type) { - throw execute(this, type, null, PNone.NO_VALUE, PNone.NO_VALUE, PythonUtils.EMPTY_OBJECT_ARRAY); + @Specialization + static void doProfile(Node inliningTarget, + @Cached InlinedBranchProfile profile) { + profile.enter(inliningTarget); } - public final PException raise(PythonBuiltinClassType type, TruffleString message) { - throw execute(this, type, null, PNone.NO_VALUE, message, PythonUtils.EMPTY_OBJECT_ARRAY); + public final PException raise(Node inliningTarget, PythonBuiltinClassType type) { + executeEnterProfile(inliningTarget); + throw raiseStatic(inliningTarget, type); } - public final PException raise(PythonBuiltinClassType type, TruffleString format, Object... arguments) { - throw execute(this, type, null, PNone.NO_VALUE, format, arguments); + public static PException raiseStatic(Node node, PythonBuiltinClassType type) { + PythonLanguage language = PythonLanguage.get(node); + PBaseException pythonException = PFactory.createBaseException(language, type); + throw raiseExceptionObject(node, pythonException, language); } - public final PException raise(PythonBuiltinClassType type, Object[] arguments) { - throw execute(this, type, null, PNone.NO_VALUE, PNone.NO_VALUE, arguments); + public final PException raise(Node inliningTarget, PythonBuiltinClassType type, TruffleString message) { + executeEnterProfile(inliningTarget); + throw raiseStatic(inliningTarget, type, message); } - public final PException raiseWithData(PythonBuiltinClassType type, Object[] data, Object... arguments) { - throw execute(this, type, data, PNone.NO_VALUE, PNone.NO_VALUE, arguments); + public static PException raiseStatic(Node node, PythonBuiltinClassType type, TruffleString message) { + PythonLanguage language = PythonLanguage.get(node); + PBaseException pythonException = PFactory.createBaseException(language, type, message); + throw raiseExceptionObject(node, pythonException, language); } - public final PException raise(PythonBuiltinClassType type, Exception e) { - throw execute(this, type, null, PNone.NO_VALUE, getMessage(e), PythonUtils.EMPTY_OBJECT_ARRAY); + public final PException raise(Node inliningTarget, PythonBuiltinClassType type, TruffleString format, Object... formatArgs) { + executeEnterProfile(inliningTarget); + throw raiseStatic(inliningTarget, type, format, formatArgs); } - public final PException raiseWithCause(PythonBuiltinClassType type, Object cause, TruffleString format, Object... arguments) { - throw execute(this, type, null, cause, format, arguments); + public static PException raiseStatic(Node node, PythonBuiltinClassType type, TruffleString message, Object... formatArgs) { + PythonLanguage language = PythonLanguage.get(node); + PBaseException pythonException = PFactory.createBaseException(language, type, message, formatArgs); + throw raiseExceptionObject(node, pythonException, language); } - public final PException raiseWithCause(PythonBuiltinClassType errorType, PException e, TruffleString message, Object... arguments) { - return raiseWithCause(errorType, e.getEscapedException(), message, arguments); + public final PException raise(Node inliningTarget, PythonBuiltinClassType type, Object[] arguments) { + executeEnterProfile(inliningTarget); + throw raiseStatic(inliningTarget, type, arguments); } - public static PException raiseUncached(Node raisingNode, PythonBuiltinClassType exceptionType) { - throw PRaiseNodeGen.getUncached().execute(raisingNode, exceptionType, null, PNone.NO_VALUE, PNone.NO_VALUE, PythonUtils.EMPTY_OBJECT_ARRAY); + public static PException raiseStatic(Node node, PythonBuiltinClassType type, Object[] arguments) { + PythonLanguage language = PythonLanguage.get(node); + PBaseException pythonException = PFactory.createBaseException(language, type, PFactory.createTuple(language, arguments)); + throw raiseExceptionObject(node, pythonException, language); } - public static PException raiseUncached(Node raisingNode, PythonBuiltinClassType exceptionType, TruffleString message) { - throw PRaiseNodeGen.getUncached().execute(raisingNode, exceptionType, null, PNone.NO_VALUE, assertNoJavaString(message), PythonUtils.EMPTY_OBJECT_ARRAY); + public final PException raiseWithData(Node inliningTarget, PythonBuiltinClassType type, Object[] data) { + executeEnterProfile(inliningTarget); + throw raiseWithDataStatic(inliningTarget, type, data); } - public static PException raiseUncached(Node raisingNode, PythonBuiltinClassType type, TruffleString format, Object... arguments) { - throw PRaiseNodeGen.getUncached().execute(raisingNode, type, null, PNone.NO_VALUE, format, arguments); + public static PException raiseWithDataStatic(Node node, PythonBuiltinClassType type, Object[] data) { + PythonLanguage language = PythonLanguage.get(node); + PBaseException pythonException = PFactory.createBaseException(language, type, data, null); + throw raiseExceptionObject(node, pythonException, language); } - public static PException raiseUncached(Node raisingNode, PythonBuiltinClassType type, Exception e) { - throw PRaiseNodeGen.getUncached().execute(raisingNode, type, null, PNone.NO_VALUE, getMessage(e), PythonUtils.EMPTY_OBJECT_ARRAY); + public final PException raiseAttributeError(Node inliningTarget, Object obj, Object key) { + executeEnterProfile(inliningTarget); + throw raiseAttributeErrorStatic(inliningTarget, obj, key); } - /** - * Raise an error saying that the {@code result} cannot fit into an index-sized integer. Use the - * specified {@code type} as exception class. - */ - public final PException raiseNumberTooLarge(PythonBuiltinClassType type, Object result) { - return execute(this, type, null, PNone.NO_VALUE, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, new Object[]{result}); + public static PException raiseAttributeErrorStatic(Node inliningTarget, Object obj, Object key) { + throw raiseWithDataStatic(inliningTarget, PythonBuiltinClassType.AttributeError, AttributeErrorBuiltins.dataForObjKey(obj, key), ErrorMessages.OBJ_P_HAS_NO_ATTR_S, obj, key); } - public final PException raiseOverflow() { - return raiseNumberTooLarge(OverflowError, 0); + public final PException raiseWithData(Node inliningTarget, PythonBuiltinClassType type, Object[] data, TruffleString format, Object... formatArgs) { + executeEnterProfile(inliningTarget); + throw raiseWithDataStatic(inliningTarget, type, data, format, formatArgs); } - public final PException raiseSystemExit(Object code) { - return raiseWithData(PythonBuiltinClassType.SystemExit, new Object[]{code}, code); + public static PException raiseWithDataStatic(Node node, PythonBuiltinClassType type, Object[] data, TruffleString format, Object... formatArgs) { + PythonLanguage language = PythonLanguage.get(node); + PBaseException pythonException = PFactory.createBaseException(language, type, data, format, formatArgs); + throw raiseExceptionObject(node, pythonException, language); } - public final PException raiseStopIteration() { - return raise(PythonBuiltinClassType.StopIteration); + public final PException raiseWithData(Node inliningTarget, PythonBuiltinClassType type, Object[] data, Object... arguments) { + executeEnterProfile(inliningTarget); + throw raiseWithDataStatic(inliningTarget, type, data, arguments); } - public final PException raiseStopIteration(Object value) { - final Object retVal = value != null ? value : PNone.NONE; - final Object[] args = {retVal}; - return raiseWithData(PythonBuiltinClassType.StopIteration, args, retVal); + public static PException raiseWithDataStatic(Node node, PythonBuiltinClassType type, Object[] data, Object[] arguments) { + PythonLanguage language = PythonLanguage.get(node); + PBaseException pythonException = PFactory.createBaseException(language, type, data, PFactory.createTuple(language, arguments)); + throw raiseExceptionObject(node, pythonException, language); } - public final PException raiseIntegerInterpretationError(Object result) { - return raise(PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, result); + public final PException raise(Node inliningTarget, PythonBuiltinClassType type, Exception e) { + executeEnterProfile(inliningTarget); + throw raiseStatic(inliningTarget, type, e); } - public final PException raiseBadInternalCall() { - return raise(PythonBuiltinClassType.SystemError, BAD_ARG_TO_INTERNAL_FUNC); + public static PException raiseStatic(Node node, PythonBuiltinClassType type, Exception e) { + PythonLanguage language = PythonLanguage.get(node); + PBaseException pythonException = PFactory.createBaseException(language, type, ErrorMessages.M, new Object[]{e}); + throw raiseExceptionObject(node, pythonException, language); } - public final PException raiseMemoryError() { - return raise(PythonBuiltinClassType.MemoryError); + private static void setCause(PBaseException pythonException, PException cause) { + // _PyErr_FormatFromCause sets both cause and context + Object causePythonException = cause.getEscapedException(); + pythonException.setCause(causePythonException); + pythonException.setContext(causePythonException); } - public final PException raiseExceptionObject(Object exc) { - throw raiseExceptionObject(this, exc, PythonOptions.isPExceptionWithJavaStacktrace(PythonLanguage.get(this))); + public final PException raiseWithCause(Node inliningTarget, PythonBuiltinClassType type, PException cause, TruffleString format) { + executeEnterProfile(inliningTarget); + throw raiseWithCauseStatic(inliningTarget, type, cause, format); } - public static PException raiseExceptionObject(Node raisingNode, Object exc) { - throw raiseExceptionObject(raisingNode, exc, PythonOptions.isPExceptionWithJavaStacktrace(PythonLanguage.get(raisingNode))); + public static PException raiseWithCauseStatic(Node node, PythonBuiltinClassType type, PException cause, TruffleString format) { + PythonLanguage language = PythonLanguage.get(node); + PBaseException pythonException = PFactory.createBaseException(language, type, format); + setCause(pythonException, cause); + throw raiseExceptionObject(node, pythonException, language); } - public static PException raiseExceptionObject(Node raisingNode, Object exc, boolean withJavaStacktrace) { - if (raisingNode != null && raisingNode.isAdoptable()) { - throw PException.fromObject(exc, raisingNode, withJavaStacktrace); - } else { - throw PException.fromObject(exc, EncapsulatingNodeReference.getCurrent().get(), withJavaStacktrace); - } + public final PException raiseWithCause(Node inliningTarget, PythonBuiltinClassType type, PException cause, TruffleString format, Object... arguments) { + assert PyExceptionInstanceCheckNode.executeUncached(cause); + executeEnterProfile(inliningTarget); + throw raiseWithCauseStatic(inliningTarget, type, cause, format, arguments); } - @Specialization(guards = {"isNoValue(cause)", "isNoValue(format)", "arguments.length == 0", "exceptionType == cachedType"}, limit = "8") - static PException doPythonBuiltinTypeCached(Node raisingNode, @SuppressWarnings("unused") PythonBuiltinClassType exceptionType, Object[] data, @SuppressWarnings("unused") PNone cause, - @SuppressWarnings("unused") PNone format, - @SuppressWarnings("unused") Object[] arguments, - @Cached("exceptionType") PythonBuiltinClassType cachedType, - @Shared("factory") @Cached PythonObjectFactory factory) { - throw raiseExceptionObject(raisingNode, factory.createBaseException(cachedType, data)); + public static PException raiseWithCauseStatic(Node node, PythonBuiltinClassType type, PException cause, TruffleString format, Object... formatArgs) { + assert PyExceptionInstanceCheckNode.executeUncached(cause); + PythonLanguage language = PythonLanguage.get(node); + PBaseException pythonException = PFactory.createBaseException(language, type, format, formatArgs); + setCause(pythonException, cause); + throw raiseExceptionObject(node, pythonException, language); } - @Specialization(guards = {"isNoValue(cause)", "isNoValue(format)", "arguments.length == 0"}, replaces = "doPythonBuiltinTypeCached") - static PException doPythonBuiltinType(Node raisingNode, PythonBuiltinClassType exceptionType, Object[] data, @SuppressWarnings("unused") PNone cause, - @SuppressWarnings("unused") PNone format, - @SuppressWarnings("unused") Object[] arguments, - @Shared("factory") @Cached PythonObjectFactory factory) { - throw raiseExceptionObject(raisingNode, factory.createBaseException(exceptionType, data)); + public final PException raiseOverflow(Node inliningTarget) { + throw raise(inliningTarget, OverflowError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, 0); } - @Specialization(guards = {"isNoValue(cause)", "isNoValue(format)", "arguments.length > 0"}) - static PException doBuiltinType(Node raisingNode, PythonBuiltinClassType type, Object[] data, @SuppressWarnings("unused") PNone cause, @SuppressWarnings("unused") PNone format, - Object[] arguments, - @Shared("factory") @Cached PythonObjectFactory factory, - @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode) { - ensureNoJavaStrings(arguments, fromJavaStringNode); - throw raiseExceptionObject(raisingNode, factory.createBaseException(type, data, factory.createTuple(arguments))); + public static PException raiseSystemExitStatic(Node inliningTarget, Object code) { + throw raiseWithDataStatic(inliningTarget, PythonBuiltinClassType.SystemExit, new Object[]{code}, new Object[]{code}); } - @Specialization(guards = {"isNoValue(cause)"}) - static PException doBuiltinType(Node raisingNode, PythonBuiltinClassType type, Object[] data, @SuppressWarnings("unused") PNone cause, TruffleString format, Object[] arguments, - @Shared("factory") @Cached PythonObjectFactory factory, - @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode) { - assert format != null; - ensureNoJavaStrings(arguments, fromJavaStringNode); - throw raiseExceptionObject(raisingNode, factory.createBaseException(type, data, format, arguments)); + public final PException raiseStopIteration(Node inliningTarget, Object value) { + final Object retVal = value != null ? value : PNone.NONE; + final Object[] args = {retVal}; + throw raiseWithData(inliningTarget, PythonBuiltinClassType.StopIteration, args, retVal); } - @Specialization(guards = {"!isNoValue(cause)"}) - static PException doBuiltinTypeWithCause(Node raisingNode, PythonBuiltinClassType type, Object[] data, PBaseException cause, TruffleString format, Object[] arguments, - @Shared("factory") @Cached PythonObjectFactory factory, - @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode) { - assert format != null; - ensureNoJavaStrings(arguments, fromJavaStringNode); - PBaseException baseException = factory.createBaseException(type, data, format, arguments); - baseException.setContext(cause); - baseException.setCause(cause); - throw raiseExceptionObject(raisingNode, baseException); + public final PException raiseStopAsyncIteration(Node inliningTarget, Object value) { + final Object retVal = value != null ? value : PNone.NONE; + final Object[] args = {retVal}; + throw raiseWithData(inliningTarget, PythonBuiltinClassType.StopAsyncIteration, args, retVal); } - @TruffleBoundary - private static TruffleString getMessage(Exception e) { - String msg = e.getMessage(); - return toTruffleStringUncached(msg != null ? msg : e.getClass().getSimpleName()); + public final PException raiseBadInternalCall(Node inliningTarget) { + throw raise(inliningTarget, PythonBuiltinClassType.SystemError, BAD_ARG_TO_INTERNAL_FUNC); } - @NeverDefault - public static PRaiseNode create() { - return PRaiseNodeGen.create(); + public final PException raiseExceptionObject(Object exc) { + throw raiseExceptionObject(this, exc, PythonOptions.isPExceptionWithJavaStacktrace(PythonLanguage.get(this))); } - public static PRaiseNode getUncached() { - return PRaiseNodeGen.getUncached(); + public static PException raiseExceptionObject(Node raisingNode, Object exc) { + throw raiseExceptionObject(raisingNode, exc, PythonOptions.isPExceptionWithJavaStacktrace(PythonLanguage.get(raisingNode))); } - private static void ensureNoJavaStrings(Object[] arguments, TruffleString.FromJavaStringNode fromJavaStringNode) { - for (int i = 0; i < arguments.length; i++) { - if (arguments[i] instanceof String) { - arguments[i] = fromJavaStringNode.execute((String) arguments[i], TS_ENCODING); - } - } + public static PException raiseExceptionObject(Node raisingNode, Object exc, PythonLanguage language) { + throw raiseExceptionObject(raisingNode, exc, PythonOptions.isPExceptionWithJavaStacktrace(language)); } - @GenerateInline - @GenerateUncached - @GenerateCached(false) - public abstract static class Lazy extends Node { - public static Lazy getUncached() { - return LazyNodeGen.getUncached(); - } - - public final PRaiseNode get(Node inliningTarget) { - return execute(inliningTarget); + public static PException raiseExceptionObject(Node raisingNode, Object exc, boolean withJavaStacktrace) { + if (raisingNode != null && raisingNode.isAdoptable()) { + throw PException.fromObject(exc, raisingNode, withJavaStacktrace); + } else { + throw PException.fromObject(exc, EncapsulatingNodeReference.getCurrent().get(), withJavaStacktrace); } + } - abstract PRaiseNode execute(Node inliningTarget); - - @Specialization - static PRaiseNode doIt(@Cached(inline = false) PRaiseNode node) { - return node; - } + public static PRaiseNode getUncached() { + return PRaiseNodeGen.getUncached(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRootNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRootNode.java index 1f56957fff..46b56a408e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRootNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRootNode.java @@ -61,19 +61,19 @@ public abstract class PRootNode extends RootNode { private final ConditionProfile frameEscaped = ConditionProfile.create(); - @CompilationFinal private Assumption dontNeedCallerFrame = createCallerFrameAssumption(); + @CompilationFinal private transient Assumption dontNeedCallerFrame = createCallerFrameAssumption(); /** * Flag indicating if some child node of this root node (or a callee) eventually needs the * exception state. Hence, the caller of this root node should provide the exception state in * the arguments. */ - @CompilationFinal private Assumption dontNeedExceptionState = createExceptionStateAssumption(); + @CompilationFinal private transient Assumption dontNeedExceptionState = createExceptionStateAssumption(); - private int nodeCount = -1; + private transient int nodeCount = -1; // contains the code of this root node in marshaled/serialized form - private byte[] code; + private transient byte[] code; protected PRootNode(TruffleLanguage language) { super(language); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/SpecialAttributeNames.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/SpecialAttributeNames.java index 9b53e57fc4..c3c378ce98 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/SpecialAttributeNames.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/SpecialAttributeNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -120,7 +120,7 @@ public abstract class SpecialAttributeNames { public static final TruffleString T___TEXT_SIGNATURE__ = tsLiteral(J___TEXT_SIGNATURE__); public static final String J___SIGNATURE__ = "__signature__"; - public static final TruffleString T__SIGNATURE__ = tsLiteral(J___SIGNATURE__); + public static final TruffleString T___SIGNATURE__ = tsLiteral(J___SIGNATURE__); public static final String J___TRACEBACK__ = "__traceback__"; public static final TruffleString T___TRACEBACK__ = tsLiteral(J___TRACEBACK__); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/SpecialMethodNames.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/SpecialMethodNames.java index 33a6a74639..d56e65a2d5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/SpecialMethodNames.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/SpecialMethodNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -462,8 +462,8 @@ public abstract class SpecialMethodNames { public static final TruffleString T_UPDATE = tsLiteral("update"); - public static final String J___TRUFFLE_RICHCOMPARE__ = "__truffle_richcompare__"; - public static final TruffleString T___TRUFFLE_RICHCOMPARE__ = tsLiteral(J___TRUFFLE_RICHCOMPARE__); + public static final String J_TP_RICHCOMPARE = "tp_richcompare"; + public static final TruffleString T_TP_RICHCOMPARE = tsLiteral(J_TP_RICHCOMPARE); public static final String J_TRUFFLE_SOURCE = "__truffle_source__"; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/StringLiterals.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/StringLiterals.java index 96dd482536..048b9a32ef 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/StringLiterals.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/StringLiterals.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -134,8 +134,6 @@ public abstract class StringLiterals { public static final TruffleString T_VERSION = tsLiteral("version"); public static final String J_DEFAULT = "default"; public static final TruffleString T_DEFAULT = tsLiteral(J_DEFAULT); - public static final String J_LLVM_LANGUAGE = "llvm"; - public static final TruffleString T_LLVM_LANGUAGE = tsLiteral(J_LLVM_LANGUAGE); public static final String J_NFI_LANGUAGE = "nfi"; public static final TruffleString T_ID = tsLiteral("id"); public static final TruffleString T_SITE = tsLiteral("site"); @@ -147,6 +145,7 @@ public abstract class StringLiterals { public static final TruffleString T_EXEC = tsLiteral("exec"); public static final TruffleString T_EVAL = tsLiteral("eval"); public static final TruffleString T_FUNC_TYPE = tsLiteral("func_type"); + public static final TruffleString T_SUPER = tsLiteral("super"); public static final String J_OB_REFCNT = "ob_refcnt"; public static final String J_DEBUG = "debug"; public static final String J_TRACE = "trace"; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/WriteUnraisableNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/WriteUnraisableNode.java index 3d87604cbc..e25713eb89 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/WriteUnraisableNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/WriteUnraisableNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,6 +46,7 @@ import java.io.IOException; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.SysModuleBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.exception.ExceptionNodes; @@ -55,7 +56,7 @@ import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -89,7 +90,7 @@ static void writeUnraisable(VirtualFrame frame, Object exception, TruffleString @Cached PyObjectLookupAttr lookup, @Cached CallNode callNode, @Cached GetClassNode getClassNode, - @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached ExceptionNodes.GetTracebackNode getTracebackNode, @Cached TruffleString.ConcatNode concatNode, @Cached TruffleString.CopyToByteArrayNode copyToByteArrayNode) { @@ -103,7 +104,8 @@ static void writeUnraisable(VirtualFrame frame, Object exception, TruffleString if (message != null) { messageObj = formatMessage(message, concatNode); } - Object hookArguments = factory.createStructSeq(SysModuleBuiltins.UNRAISABLEHOOK_ARGS_DESC, exceptionType, exception, traceback, messageObj, object != null ? object : PNone.NONE); + Object hookArguments = PFactory.createStructSeq(language, SysModuleBuiltins.UNRAISABLEHOOK_ARGS_DESC, exceptionType, exception, traceback, messageObj, + object != null ? object : PNone.NONE); callNode.execute(frame, unraisablehook, hookArguments); } catch (PException e) { ignoreException(context, message, concatNode, copyToByteArrayNode); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/CreateArgumentsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/CreateArgumentsNode.java index 162112edf4..f875c307d0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/CreateArgumentsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/CreateArgumentsNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -52,7 +52,6 @@ import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.code.CodeNodes; import com.oracle.graal.python.builtins.objects.code.PCode; import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; @@ -61,28 +60,19 @@ import com.oracle.graal.python.builtins.objects.function.Signature; import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.builtins.objects.method.PMethod; -import com.oracle.graal.python.builtins.objects.method.PMethodBase; import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.argument.CreateArgumentsNodeGen.ApplyPositionalArgumentsNodeGen; import com.oracle.graal.python.nodes.argument.CreateArgumentsNodeGen.HandleTooManyArgumentsNodeGen; -import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetCallTargetNode; -import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetDefaultsNode; -import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetKeywordDefaultsNode; -import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetSignatureNode; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -102,288 +92,132 @@ import com.oracle.truffle.api.strings.TruffleString; import com.oracle.truffle.api.strings.TruffleStringBuilder; -@ImportStatic({PythonOptions.class, PGuards.class}) @GenerateUncached -@GenerateInline(false) // footprint reduction 48 -> 29 +@GenerateInline +@GenerateCached(false) public abstract class CreateArgumentsNode extends PNodeWithContext { - public abstract Object[] execute(PMethodBase callable, Object[] userArguments, PKeyword[] keywords); - - public abstract Object[] execute(PFunction callable, Object[] userArguments, PKeyword[] keywords); - - public abstract Object[] execute(PBuiltinFunction callable, Object[] userArguments, PKeyword[] keywords); - - @Specialization(guards = {"isSingleContext()", "method == cachedMethod"}, limit = "getVariableArgumentInlineCacheLimit()") - static Object[] doMethodCached(@SuppressWarnings("unused") PMethodBase method, Object[] userArguments, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Exclusive @Cached CreateAndCheckArgumentsNode createAndCheckArgumentsNode, - @Cached(value = "method", weak = true) PMethodBase cachedMethod) { - - CompilerAsserts.partialEvaluationConstant(getFunction(cachedMethod)); - // Following getters should fold since getFunction(cachedMethod) is constant - Signature signature = GetSignatureNode.getMethodSignatureSingleContext(cachedMethod, inliningTarget); - Object[] defaults = GetDefaultsNode.getMethodDefaults(cachedMethod); - PKeyword[] kwdefaults = GetKeywordDefaultsNode.getMethodKeywords(cachedMethod); - Object self = cachedMethod.getSelf(); - CompilerAsserts.partialEvaluationConstant(self); - Object classObject = getClassObject(cachedMethod); - CompilerAsserts.partialEvaluationConstant(classObject); - return createAndCheckArgumentsNode.execute(inliningTarget, cachedMethod, userArguments, keywords, signature, self, classObject, defaults, kwdefaults, isMethodCall(self)); - } - - @Specialization(guards = {"isSingleContext()", "getFunction(method) == cachedFunction", - "getSelf(method) == cachedSelf"}, limit = "getVariableArgumentInlineCacheLimit()", replaces = "doMethodCached") - static Object[] doMethodFunctionAndSelfCached(PMethodBase method, Object[] userArguments, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Exclusive @Cached CreateAndCheckArgumentsNode createAndCheckArgumentsNode, - @Cached(value = "getFunction(method)", weak = true) @SuppressWarnings("unused") Object cachedFunction, - @Cached(value = "method.getSelf()", weak = true) Object cachedSelf, - @Cached(value = "getClassObject(method)", weak = true) Object cachedClassObject) { - // Following getters should fold since getFunction(cachedMethod) is constant - Signature signature = GetSignatureNode.getFunctionSignatureSingleContext(inliningTarget, cachedFunction); - Object[] defaults = GetDefaultsNode.getFunctionDefaults(cachedFunction); - PKeyword[] kwdefaults = GetKeywordDefaultsNode.getFunctionKeywords(cachedFunction); - return createAndCheckArgumentsNode.execute(inliningTarget, method, userArguments, keywords, signature, cachedSelf, cachedClassObject, defaults, kwdefaults, isMethodCall(cachedSelf)); - } - - @Specialization(guards = {"isSingleContext()", "getFunction(method) == cachedFunction"}, limit = "getVariableArgumentInlineCacheLimit()", replaces = "doMethodFunctionAndSelfCached") - static Object[] doMethodFunctionCached(PMethodBase method, Object[] userArguments, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Exclusive @Cached CreateAndCheckArgumentsNode createAndCheckArgumentsNode, - @Cached(value = "getFunction(method)", weak = true) @SuppressWarnings("unused") Object cachedFunction) { - // Following getters should fold since getFunction(cachedMethod) is constant - Signature signature = GetSignatureNode.getFunctionSignatureSingleContext(inliningTarget, cachedFunction); - Object[] defaults = GetDefaultsNode.getFunctionDefaults(cachedFunction); - PKeyword[] kwdefaults = GetKeywordDefaultsNode.getFunctionKeywords(cachedFunction); - Object self = method.getSelf(); - Object classObject = getClassObject(method); - return createAndCheckArgumentsNode.execute(inliningTarget, method, userArguments, keywords, signature, self, classObject, defaults, kwdefaults, isMethodCall(self)); - } - - @Specialization(guards = {"isSingleContext()", "callable == cachedCallable"}, limit = "getVariableArgumentInlineCacheLimit()") - static Object[] doFunctionCached(PFunction callable, Object[] userArguments, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Exclusive @Cached CreateAndCheckArgumentsNode createAndCheckArgumentsNode, - @Cached(value = "callable", weak = true) @SuppressWarnings("unused") PFunction cachedCallable) { - Signature signature = CodeNodes.GetCodeSignatureNode.getInSingleContextMode(inliningTarget, cachedCallable); - Object[] defaults = cachedCallable.getDefaults(); - PKeyword[] kwdefaults = cachedCallable.getKwDefaults(); - return createAndCheckArgumentsNode.execute(inliningTarget, callable, userArguments, keywords, signature, null, null, defaults, kwdefaults, false); - } - - @Specialization(guards = {"isSingleContext()", "callable == cachedCallable"}, limit = "getVariableArgumentInlineCacheLimit()") - static Object[] doBuiltinFunctionCached(PBuiltinFunction callable, Object[] userArguments, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Exclusive @Cached CreateAndCheckArgumentsNode createAndCheckArgumentsNode, - @Cached(value = "callable", weak = true) @SuppressWarnings("unused") PBuiltinFunction cachedCallable) { - - Signature signature = cachedCallable.getSignature(); - Object[] defaults = cachedCallable.getDefaults(); - PKeyword[] kwdefaults = cachedCallable.getKwDefaults(); - return createAndCheckArgumentsNode.execute(inliningTarget, callable, userArguments, keywords, signature, null, null, defaults, kwdefaults, false); - } - - @Specialization(guards = {"getCt.execute(callable) == cachedCallTarget", "cachedCallTarget != null"}, limit = "getVariableArgumentInlineCacheLimit()", replaces = {"doMethodFunctionCached", - "doFunctionCached"}) - static Object[] doCallTargetCached(PythonObject callable, Object[] userArguments, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached GetCallTargetNode getCt, - @Exclusive @Cached CreateAndCheckArgumentsNode createAndCheckArgumentsNode, - @Exclusive @SuppressWarnings("unused") @Cached GetSignatureNode getSignatureNode, - // signatures are attached to PRootNodes - @Cached("getSignatureNode.execute(inliningTarget, callable)") Signature signature, - @Cached InlinedConditionProfile gotMethod, - @Exclusive @Cached GetDefaultsNode getDefaultsNode, - @Exclusive @Cached GetKeywordDefaultsNode getKwDefaultsNode, - @Cached("getCt.execute(callable)") @SuppressWarnings("unused") RootCallTarget cachedCallTarget) { - Object[] defaults = getDefaultsNode.execute(inliningTarget, callable); - PKeyword[] kwdefaults = getKwDefaultsNode.execute(inliningTarget, callable); - Object self = null; - Object classObject = null; - if (gotMethod.profile(inliningTarget, PGuards.isMethod(callable))) { - self = getSelf(callable); - classObject = getClassObject(callable); - } - return createAndCheckArgumentsNode.execute(inliningTarget, callable, userArguments, keywords, signature, self, classObject, defaults, kwdefaults, isMethodCall(self)); - } - - @Specialization(replaces = {"doFunctionCached", "doMethodCached", "doMethodFunctionAndSelfCached", "doMethodFunctionCached", "doCallTargetCached"}) - static Object[] uncached(PythonObject callable, Object[] userArguments, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Exclusive @Cached CreateAndCheckArgumentsNode createAndCheckArgumentsNode, - @Exclusive @Cached GetSignatureNode getSignatureNode, - @Exclusive @Cached GetDefaultsNode getDefaultsNode, - @Exclusive @Cached GetKeywordDefaultsNode getKwDefaultsNode) { - - // mostly we will be calling proper functions directly here, - // but sometimes also methods that have functions directly. - // In all other cases, the arguments... TODO: unfinished comment? - Signature signature = getSignatureNode.execute(inliningTarget, callable); - Object[] defaults = getDefaultsNode.execute(inliningTarget, callable); - PKeyword[] kwdefaults = getKwDefaultsNode.execute(inliningTarget, callable); - Object self = getSelf(callable); - Object classObject = getClassObject(callable); - boolean methodcall = !(self instanceof PythonModule); - return createAndCheckArgumentsNode.execute(inliningTarget, callable, userArguments, keywords, signature, self, classObject, defaults, kwdefaults, methodcall); - } - - @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class CreateAndCheckArgumentsNode extends PNodeWithContext { - /** - * Creates a {@link PArguments} array from the provided arguments and metadata. - * - * @param inliningTarget The inlining target. - * @param callableOrName This object can either be the function/method object or just a name - * ({@link TruffleString}). It is primarily used to create error messages. It is - * also used to check if the function - * @param userArguments The positional arguments as provided by the caller (must not be - * {@code null} but may be empty). - * @param keywords The keyword arguments as provided by the caller (must not be {@code null} - * but may be empty). - * @param signature The callee's signature (i.e. specifies how the callee needs to be - * invoked). - * @param self The primary (aka. self) object. - * @param classObject The class object (if the invoked method is a class method). - * @param defaults Array of default values for positional arguments. - * @param kwdefaults Array of default values for keyword arguments. - * @param methodcall Indicates if this creates arguments for a method call. This is only - * used for creating better error messages. - * @return A {@link PArguments} array. - */ - public abstract Object[] execute(Node inliningTarget, Object callableOrName, Object[] userArguments, PKeyword[] keywords, Signature signature, Object self, Object classObject, - Object[] defaults, PKeyword[] kwdefaults, boolean methodcall); - - @Specialization - static Object[] doIt(Node inliningTarget, Object callableOrName, Object[] userArguments, PKeyword[] keywords, Signature signature, Object self, Object classObject, Object[] defaults, - PKeyword[] kwdefaults, boolean methodcall, - @Cached InlinedIntValueProfile lenProfile, - @Cached InlinedIntValueProfile maxPosProfile, - @Cached InlinedIntValueProfile numKwdsProfile, - @Cached LazyApplyKeywordsNode applyKeywords, - @Cached LazyHandleTooManyArgumentsNode handleTooManyArgumentsNode, - @Cached ApplyPositionalArguments applyPositional, - @Cached LazyFillDefaultsNode fillDefaultsNode, - @Cached LazyFillKwDefaultsNode fillKwDefaultsNode, - @Cached CheckEnclosingTypeNode checkEnclosingTypeNode) { - int cachedLen = lenProfile.profile(inliningTarget, userArguments.length); - int cachedMaxPos = maxPosProfile.profile(inliningTarget, signature.getMaxNumOfPositionalArgs()); - int cachedNumKwds = numKwdsProfile.profile(inliningTarget, signature.getNumOfRequiredKeywords()); - return createAndCheckArguments(inliningTarget, callableOrName, userArguments, cachedLen, keywords, signature, self, classObject, defaults, kwdefaults, methodcall, - cachedMaxPos, cachedNumKwds, applyPositional, applyKeywords, handleTooManyArgumentsNode, fillDefaultsNode, fillKwDefaultsNode, checkEnclosingTypeNode); - } - - private static Object[] createAndCheckArguments(Node inliningTarget, Object callableOrName, Object[] args_w, int num_args, PKeyword[] keywords, Signature signature, Object self, - Object classObject, - Object[] defaults, PKeyword[] kwdefaults, boolean methodcall, int co_argcount, int co_kwonlyargcount, - ApplyPositionalArguments applyPositional, - LazyApplyKeywordsNode applyKeywords, - LazyHandleTooManyArgumentsNode handleTooMany, - LazyFillDefaultsNode fillDefaults, - LazyFillKwDefaultsNode fillKwDefaults, - CheckEnclosingTypeNode checkEnclosingTypeNode) { - assert args_w.length == num_args; - - // see PyPy's Argument#_match_signature method - // expected formal arguments, without * and ** - boolean too_many_args = false; - - // positional args, kwd only args, varargs, var kwds - Object[] scope_w = PArguments.create(co_argcount + co_kwonlyargcount); - - int upfront = 0; - // put the special w_firstarg into the scope, if it exists - if (self != null) { - upfront++; - if (co_argcount > 0) { - PArguments.setArgument(scope_w, 0, self); - } - if (classObject != null) { - upfront++; - PArguments.setArgument(scope_w, 1, classObject); - } - } - - int avail = num_args + upfront; - - // put as many positional input arguments into place as available - int input_argcount = applyPositional.execute(inliningTarget, args_w, scope_w, upfront, co_argcount, num_args); - - // collect extra positional arguments into the *vararg - if (signature.takesVarArgs()) { - int args_left = co_argcount - upfront; - if (args_left < 0) { - // everything goes to starargs, including any magic self - assert upfront == 1; - Object[] varargs = new Object[num_args + 1]; - varargs[0] = self; - PythonUtils.arraycopy(args_w, 0, varargs, 1, num_args); - PArguments.setVariableArguments(scope_w, varargs); - } else if (num_args > args_left) { - PArguments.setVariableArguments(scope_w, Arrays.copyOfRange(args_w, args_left, args_w.length)); - } else { - // no varargs - } - } else if (avail > co_argcount) { - too_many_args = true; - } - - // handle keyword arguments - // match the keywords given at the call site to the argument names. - // the called node takes and collect the rest in the keywords. - if (keywords.length > 0) { - // the lazy node acts as a profile - applyKeywords(callableOrName, signature, scope_w, keywords, applyKeywords.get(inliningTarget)); + /** + * Creates a {@link PArguments} array from the provided arguments and metadata. + * + * @param inliningTarget The inlining target. + * @param callableOrName This object can either be the function/method object or just a name + * ({@link TruffleString}). It is primarily used to create error messages. It is also + * used to check if the function + * @param userArguments The positional arguments as provided by the caller (must not be + * {@code null} but may be empty). + * @param keywords The keyword arguments as provided by the caller (must not be {@code null} but + * may be empty). + * @param signature The callee's signature (i.e. specifies how the callee needs to be invoked). + * @param self The primary (aka. self) object. + * @param classObject The class object (if the invoked method is a class method). + * @param defaults Array of default values for positional arguments. + * @param kwdefaults Array of default values for keyword arguments. + * @param methodcall Indicates if this creates arguments for a method call. This is only used + * for creating better error messages. + * @return A {@link PArguments} array. + */ + public abstract Object[] execute(Node inliningTarget, Object callableOrName, Object[] userArguments, PKeyword[] keywords, Signature signature, Object self, Object classObject, + Object[] defaults, PKeyword[] kwdefaults, boolean methodcall); + + @Specialization + static Object[] doIt(Node inliningTarget, Object callableOrName, Object[] userArguments, PKeyword[] keywords, Signature signature, Object self, Object classObject, Object[] defaults, + PKeyword[] kwdefaults, boolean methodcall, + @Cached InlinedIntValueProfile lenProfile, + @Cached InlinedIntValueProfile maxPosProfile, + @Cached InlinedIntValueProfile numKwdsProfile, + @Cached LazyApplyKeywordsNode applyKeywords, + @Cached LazyHandleTooManyArgumentsNode handleTooManyArgumentsNode, + @Cached ApplyPositionalArguments applyPositional, + @Cached LazyFillDefaultsNode fillDefaultsNode, + @Cached LazyFillKwDefaultsNode fillKwDefaultsNode, + @Cached CheckEnclosingTypeNode checkEnclosingTypeNode) { + int cachedLen = lenProfile.profile(inliningTarget, userArguments.length); + int cachedMaxPos = maxPosProfile.profile(inliningTarget, signature.getMaxNumOfPositionalArgs()); + int cachedNumKwds = numKwdsProfile.profile(inliningTarget, signature.getNumOfRequiredKeywords()); + assert userArguments.length == cachedLen; + + // see PyPy's Argument#_match_signature method + + // expected formal arguments, without * and ** + boolean too_many_args = false; + + // positional args, kwd only args, varargs, var kwds + Object[] scope_w = PArguments.create(cachedMaxPos + cachedNumKwds); + + int upfront = 0; + // put the special w_firstarg into the scope, if it exists + if (self != null) { + upfront++; + if (cachedMaxPos > 0) { + PArguments.setArgument(scope_w, 0, self); } - - if (too_many_args) { - // the node acts as a profile - throw handleTooManyArguments(scope_w, callableOrName, signature, co_argcount, co_kwonlyargcount, defaults.length, avail, methodcall, handleTooMany.get(inliningTarget), - self instanceof PythonModule ? 1 : 0); + if (classObject != null) { + upfront++; + PArguments.setArgument(scope_w, 1, classObject); } + } - boolean more_filling = input_argcount < co_argcount + co_kwonlyargcount; - if (more_filling) { + int avail = cachedLen + upfront; - // then, fill the normal arguments with defaults_w (if needed) - fillDefaults(callableOrName, signature, scope_w, defaults, input_argcount, co_argcount, fillDefaults.get(inliningTarget)); + // put as many positional input arguments into place as available + int input_argcount = applyPositional.execute(inliningTarget, userArguments, scope_w, upfront, cachedMaxPos, cachedLen); - // finally, fill kwonly arguments with w_kw_defs (if needed) - fillKwDefaults(callableOrName, scope_w, signature, kwdefaults, co_argcount, co_kwonlyargcount, fillKwDefaults.get(inliningTarget)); + // collect extra positional arguments into the *vararg + if (signature.takesVarArgs()) { + int args_left = cachedMaxPos - upfront; + if (args_left < 0) { + // everything goes to starargs, including any magic self + assert upfront == 1; + Object[] varargs = new Object[cachedLen + 1]; + varargs[0] = self; + PythonUtils.arraycopy(userArguments, 0, varargs, 1, cachedLen); + PArguments.setVariableArguments(scope_w, varargs); + } else if (cachedLen > args_left) { + PArguments.setVariableArguments(scope_w, Arrays.copyOfRange(userArguments, args_left, userArguments.length)); + } else { + // no varargs } - - // Now we know that everything is fine, so check compatibility of the enclosing type. - // If we are calling a built-in method, and it's function has an enclosing type, we - // need to check if 'self' is a subtype of the function's enclosing type. - checkEnclosingTypeNode.execute(inliningTarget, signature, callableOrName, scope_w); - - return scope_w; + } else if (avail > cachedMaxPos) { + too_many_args = true; } - private static void applyKeywords(Object callable, Signature signature, Object[] scope_w, PKeyword[] keywords, ApplyKeywordsNode node) { - node.execute(callable, signature, scope_w, keywords); + // handle keyword arguments + // match the keywords given at the call site to the argument names. + // the called node takes and collect the rest in the keywords. + if (keywords.length > 0) { + // the lazy node acts as a profile + applyKeywords.get(inliningTarget).execute(callableOrName, signature, scope_w, keywords); } - private static PException handleTooManyArguments(Object[] scope_w, Object callable, Signature signature, int co_argcount, int co_kwonlyargcount, int ndefaults, int avail, boolean methodcall, - HandleTooManyArgumentsNode node, int adjustCount) { - return node.execute(scope_w, callable, signature, co_argcount, co_kwonlyargcount, ndefaults, avail, methodcall, adjustCount); + if (too_many_args) { + // the node acts as a profile + int adjustCount = self instanceof PythonModule ? 1 : 0; + throw handleTooManyArgumentsNode.get(inliningTarget).execute(scope_w, callableOrName, signature, cachedMaxPos, cachedNumKwds, defaults.length, avail, methodcall, adjustCount); } - private static void fillDefaults(Object callable, Signature signature, Object[] scope_w, Object[] defaults, int input_argcount, int co_argcount, FillDefaultsNode node) { - node.execute(callable, signature, scope_w, defaults, input_argcount, co_argcount); - } + boolean more_filling = input_argcount < cachedMaxPos + cachedNumKwds; + if (more_filling) { - private static void fillKwDefaults(Object callable, Object[] scope_w, Signature signature, PKeyword[] kwdefaults, int co_argcount, int co_kwonlyargcount, FillKwDefaultsNode node) { - node.execute(callable, scope_w, signature, kwdefaults, co_argcount, co_kwonlyargcount); + // then, fill the normal arguments with defaults_w (if needed) + fillDefaultsNode.get(inliningTarget).execute(callableOrName, signature, scope_w, defaults, input_argcount, cachedMaxPos); + + // finally, fill kwonly arguments with w_kw_defs (if needed) + fillKwDefaultsNode.get(inliningTarget).execute(callableOrName, scope_w, signature, kwdefaults, cachedMaxPos, cachedNumKwds); } + // Now we know that everything is fine, so check compatibility of the enclosing type. + // If we are calling a built-in method, and it's function has an enclosing type, we + // need to check if 'self' is a subtype of the function's enclosing type. + checkEnclosingTypeNode.execute(inliningTarget, signature, callableOrName, scope_w); + + return scope_w; } @GenerateInline @GenerateCached(false) @GenerateUncached - public abstract static class LazyHandleTooManyArgumentsNode extends Node { + abstract static class LazyHandleTooManyArgumentsNode extends Node { public final HandleTooManyArgumentsNode get(Node inliningTarget) { return execute(inliningTarget); } @@ -407,6 +241,7 @@ public abstract PException execute(Object[] scope_w, Object callable, Signature @ExplodeLoop static PException doCached(Object[] scope_w, Object callable, Signature signature, int co_argcount, @SuppressWarnings("unused") int co_kwonlyargcount, int ndefaults, int avail, boolean methodcall, int adjustCount, + @Bind("this") Node inliningTarget, @Shared @Cached PRaiseNode raise, @Shared @Cached TruffleString.EqualNode equalNode, @Cached("co_kwonlyargcount") int cachedKwOnlyArgCount) { @@ -417,12 +252,13 @@ static PException doCached(Object[] scope_w, Object callable, Signature signatur } } boolean forgotSelf = methodcall && avail + 1 == co_argcount && (signature.getParameterIds().length == 0 || !equalNode.execute(signature.getParameterIds()[0], T_SELF, TS_ENCODING)); - TruffleString name = signature.getRaiseErrorName().isEmpty() ? getName(callable) : signature.getRaiseErrorName(); - throw raiseTooManyArguments(name, co_argcount - adjustCount, ndefaults, avail - adjustCount, forgotSelf, kwonly_given, raise); + TruffleString name = getName(callable, signature); + throw raiseTooManyArguments(inliningTarget, name, co_argcount - adjustCount, ndefaults, avail - adjustCount, forgotSelf, kwonly_given, raise); } @Specialization(replaces = "doCached") static PException doUncached(Object[] scope_w, Object callable, Signature signature, int co_argcount, int co_kwonlyargcount, int ndefaults, int avail, boolean methodcall, int adjustCount, + @Bind("this") Node inliningTarget, @Shared @Cached PRaiseNode raise, @Shared @Cached TruffleString.EqualNode equalNode) { int kwonly_given = 0; @@ -432,15 +268,15 @@ static PException doUncached(Object[] scope_w, Object callable, Signature signat } } boolean forgotSelf = methodcall && avail + 1 == co_argcount && (signature.getParameterIds().length == 0 || !equalNode.execute(signature.getParameterIds()[0], T_SELF, TS_ENCODING)); - TruffleString name = signature.getRaiseErrorName().isEmpty() ? getName(callable) : signature.getRaiseErrorName(); - throw raiseTooManyArguments(name, co_argcount - adjustCount, ndefaults, avail - adjustCount, forgotSelf, kwonly_given, raise); + TruffleString name = getName(callable, signature); + throw raiseTooManyArguments(inliningTarget, name, co_argcount - adjustCount, ndefaults, avail - adjustCount, forgotSelf, kwonly_given, raise); } - private static PException raiseTooManyArguments(TruffleString name, int co_argcount, int ndefaults, int avail, boolean forgotSelf, int kwonly_given, PRaiseNode raise) { + private static PException raiseTooManyArguments(Node inliningTarget, TruffleString name, int co_argcount, int ndefaults, int avail, boolean forgotSelf, int kwonly_given, PRaiseNode raise) { String forgotSelfMsg = forgotSelf ? ". Did you forget 'self' in the function definition?" : ""; if (ndefaults > 0) { if (kwonly_given == 0) { - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.TAKES_FROM_D_TO_D_POS_ARG_S_BUT_D_S_GIVEN_S, + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.TAKES_FROM_D_TO_D_POS_ARG_S_BUT_D_S_GIVEN_S, name, co_argcount - ndefaults, co_argcount, @@ -449,7 +285,7 @@ private static PException raiseTooManyArguments(TruffleString name, int co_argco avail == 1 ? "was" : "were", forgotSelfMsg); } else { - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.TAKES_FROM_D_TO_D_POS_ARG_S_BUT_D_POS_ARG_S, + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.TAKES_FROM_D_TO_D_POS_ARG_S_BUT_D_POS_ARG_S, name, co_argcount - ndefaults, co_argcount, @@ -462,7 +298,7 @@ private static PException raiseTooManyArguments(TruffleString name, int co_argco } } else { if (kwonly_given == 0) { - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.TAKES_D_POS_ARG_S_BUT_GIVEN_S, + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.TAKES_D_POS_ARG_S_BUT_GIVEN_S, name, co_argcount - ndefaults, co_argcount == 1 ? "" : "s", @@ -470,7 +306,7 @@ private static PException raiseTooManyArguments(TruffleString name, int co_argco avail == 1 ? "was" : "were", forgotSelfMsg); } else { - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.TAKES_D_POS_ARG_S_BUT_D_POS_ARG_S, + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.TAKES_D_POS_ARG_S_BUT_D_POS_ARG_S, name, co_argcount, co_argcount == 1 ? "" : "s", @@ -501,10 +337,10 @@ static void doEnclosingTypeCheck(Node inliningTarget, @SuppressWarnings("unused" @Bind("getSelf(scope_w)") Object self, @Cached GetClassNode getClassNode, @Cached(inline = false) IsSubtypeNode isSubtypeMRONode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (!isSubtypeMRONode.execute(getClassNode.execute(inliningTarget, self), callable.getEnclosingType())) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.DESCR_S_FOR_P_OBJ_DOESNT_APPLY_TO_P, + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.DESCR_S_FOR_P_OBJ_DOESNT_APPLY_TO_P, callable.getName(), callable.getEnclosingType(), self); } } @@ -532,7 +368,7 @@ protected abstract static class ApplyPositionalArguments extends Node { public abstract int execute(Node inliningTarget, Object[] args_w, Object[] scope_w, int upfront, int co_argcount, int num_args); @Specialization(guards = "upfront < co_argcount") - int doIt(Object[] args_w, Object[] scope_w, int upfront, int co_argcount, int num_args) { + static int doIt(Object[] args_w, Object[] scope_w, int upfront, int co_argcount, int num_args) { int take = Math.min(num_args, co_argcount - upfront); PythonUtils.arraycopy(args_w, 0, scope_w, PArguments.USER_ARGUMENTS_OFFSET + upfront, take); return upfront + take; @@ -540,7 +376,7 @@ int doIt(Object[] args_w, Object[] scope_w, int upfront, int co_argcount, int nu @Specialization(guards = "upfront >= co_argcount") @SuppressWarnings("unused") - int doNothing(Object[] args_w, Object[] scope_w, int upfront, int co_argcount, int num_args) { + static int doNothing(Object[] args_w, Object[] scope_w, int upfront, int co_argcount, int num_args) { return 0; } @@ -552,7 +388,7 @@ protected static ApplyPositionalArguments getUncached() { @GenerateCached(false) @GenerateInline @GenerateUncached - public abstract static class LazyApplyKeywordsNode extends Node { + abstract static class LazyApplyKeywordsNode extends Node { public final ApplyKeywordsNode get(Node inliningTarget) { return execute(inliningTarget); } @@ -560,7 +396,7 @@ public final ApplyKeywordsNode get(Node inliningTarget) { public abstract ApplyKeywordsNode execute(Node inliningTarget); @Specialization - ApplyKeywordsNode doIt(@Cached(inline = false) ApplyKeywordsNode applyKeywordsNode) { + static ApplyKeywordsNode doIt(@Cached(inline = false) ApplyKeywordsNode applyKeywordsNode) { return applyKeywordsNode; } } @@ -623,7 +459,7 @@ static Object[] applyCached(Object callee, @SuppressWarnings("unused") Signature } } else { if (PArguments.getArgument(arguments, kwIdx) != null) { - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.S_PAREN_GOT_MULTIPLE_VALUES_FOR_ARG, CreateArgumentsNode.getName(callee), name); + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.S_PAREN_GOT_MULTIPLE_VALUES_FOR_ARG, getName(callee, cachedSignature), name); } PArguments.setArgument(arguments, kwIdx, kwArg.getValue()); } @@ -634,7 +470,8 @@ static Object[] applyCached(Object callee, @SuppressWarnings("unused") Signature lastWrongKeyword = name; } } - storeKeywordsOrRaise(callee, arguments, unusedKeywords, k, additionalKwds, lastWrongKeyword, posArgOnlyPassedAsKeywordNames, inliningTarget, posArgOnlyPassedAsKeywordProfile, raise); + storeKeywordsOrRaise(callee, arguments, unusedKeywords, k, additionalKwds, lastWrongKeyword, posArgOnlyPassedAsKeywordNames, inliningTarget, posArgOnlyPassedAsKeywordProfile, raise, + cachedSignature); return arguments; } @@ -679,7 +516,7 @@ static Object[] applyUncached(Object callee, Signature calleeSignature, Object[] } } else { if (PArguments.getArgument(arguments, kwIdx) != null) { - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.S_PAREN_GOT_MULTIPLE_VALUES_FOR_ARG, CreateArgumentsNode.getName(callee), name); + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.S_PAREN_GOT_MULTIPLE_VALUES_FOR_ARG, getName(callee, calleeSignature), name); } PArguments.setArgument(arguments, kwIdx, kwArg.getValue()); } @@ -691,7 +528,7 @@ static Object[] applyUncached(Object callee, Signature calleeSignature, Object[] } } storeKeywordsOrRaise(callee, arguments, unusedKeywords, k, additionalKwds, lastWrongKeyword, - posArgOnlyPassedAsKeywordNames, inliningTarget, posArgOnlyPassedAsKeywordProfile, raise); + posArgOnlyPassedAsKeywordNames, inliningTarget, posArgOnlyPassedAsKeywordProfile, raise, calleeSignature); return arguments; } @@ -707,15 +544,15 @@ private static List addPosArgOnlyPassedAsKeyword(List posArgOnlyPassedAsKeywordNames, Node inliningTarget, InlinedBranchProfile posArgOnlyPassedAsKeywordProfile, PRaiseNode raise) { + List posArgOnlyPassedAsKeywordNames, Node inliningTarget, InlinedBranchProfile posArgOnlyPassedAsKeywordProfile, PRaiseNode raise, Signature signature) { if (tooManyKeywords == 1) { - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.GOT_UNEXPECTED_KEYWORD_ARG, CreateArgumentsNode.getName(callee), lastWrongKeyword); + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.GOT_UNEXPECTED_KEYWORD_ARG, getName(callee, signature), lastWrongKeyword); } else if (tooManyKeywords > 1) { - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.GOT_UNEXPECTED_KEYWORD_ARG, CreateArgumentsNode.getName(callee), tooManyKeywords); + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.GOT_UNEXPECTED_KEYWORD_ARG, getName(callee, signature), tooManyKeywords); } else if (posArgOnlyPassedAsKeywordNames != null) { posArgOnlyPassedAsKeywordProfile.enter(inliningTarget); TruffleString names = joinUncached(T_COMMA_SPACE, posArgOnlyPassedAsKeywordNames); - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.GOT_SOME_POS_ONLY_ARGS_PASSED_AS_KEYWORD, CreateArgumentsNode.getName(callee), names); + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.GOT_SOME_POS_ONLY_ARGS_PASSED_AS_KEYWORD, getName(callee, signature), names); } else if (unusedKeywords != null) { PArguments.setKeywordArguments(arguments, Arrays.copyOf(unusedKeywords, unusedKeywordCount)); } @@ -771,9 +608,9 @@ static int uncached(TruffleString[] parameters, TruffleString name, protected abstract static class FillBaseNode extends PNodeWithContext { - protected static PException raiseMissing(Object callable, TruffleString[] missingNames, int missingCnt, TruffleString type, PRaiseNode raise) { - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.MISSING_D_REQUIRED_S_ARGUMENT_S_S, - getName(callable), + protected static PException raiseMissing(Node inliningTarget, Object callable, TruffleString[] missingNames, int missingCnt, TruffleString type, PRaiseNode raise, Signature signature) { + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.MISSING_D_REQUIRED_S_ARGUMENT_S_S, + getName(callable, signature), missingCnt, type, missingCnt == 1 ? "" : "s", @@ -849,7 +686,7 @@ static void doCached(Object callable, Signature signature, Object[] scope_w, Obj } } if (missingProfile.profile(inliningTarget, missingCnt > 0)) { - throw raiseMissing(callable, missingNames, missingCnt, toTruffleStringUncached("positional"), raise); + throw raiseMissing(inliningTarget, callable, missingNames, missingCnt, toTruffleStringUncached("positional"), raise, signature); } } @@ -873,7 +710,7 @@ static void doUncached(Object callable, Signature signature, Object[] scope_w, O } } if (missingProfile.profile(inliningTarget, missingCnt > 0)) { - throw raiseMissing(callable, missingNames, missingCnt, toTruffleStringUncached("positional"), raise); + throw raiseMissing(inliningTarget, callable, missingNames, missingCnt, toTruffleStringUncached("positional"), raise, signature); } } } @@ -904,7 +741,7 @@ protected abstract static class FillKwDefaultsNode extends FillBaseNode { static void doCached(Object callable, Object[] scope_w, Signature signature, PKeyword[] kwdefaults, @SuppressWarnings("unused") int co_argcount, @SuppressWarnings("unused") int co_kwonlyargcount, @Bind("this") Node inliningTarget, - @Exclusive @Cached PRaiseNode.Lazy raise, + @Exclusive @Cached PRaiseNode raise, @Exclusive @Cached FindKwDefaultNode findKwDefaultNode, @Cached("co_argcount") int cachedArgcount, @Cached("co_kwonlyargcount") int cachedKwOnlyArgcount, @@ -925,14 +762,14 @@ static void doCached(Object callable, Object[] scope_w, Signature signature, PKe } } if (missingProfile.profile(inliningTarget, missingCnt > 0)) { - throw raiseMissing(callable, missingNames, missingCnt, toTruffleStringUncached("keyword-only"), raise.get(inliningTarget)); + throw raiseMissing(inliningTarget, callable, missingNames, missingCnt, toTruffleStringUncached("keyword-only"), raise, signature); } } @Specialization(replaces = "doCached") static void doUncached(Object callable, Object[] scope_w, Signature signature, PKeyword[] kwdefaults, int co_argcount, int co_kwonlyargcount, @Bind("this") Node inliningTarget, - @Exclusive @Cached PRaiseNode.Lazy raise, + @Exclusive @Cached PRaiseNode raise, @Exclusive @Cached FindKwDefaultNode findKwDefaultNode, @Exclusive @Cached InlinedConditionProfile missingProfile) { TruffleString[] missingNames = new TruffleString[co_kwonlyargcount]; @@ -951,12 +788,14 @@ static void doUncached(Object callable, Object[] scope_w, Signature signature, P } } if (missingProfile.profile(inliningTarget, missingCnt > 0)) { - throw raiseMissing(callable, missingNames, missingCnt, toTruffleStringUncached("keyword-only"), raise.get(inliningTarget)); + throw raiseMissing(inliningTarget, callable, missingNames, missingCnt, toTruffleStringUncached("keyword-only"), raise, signature); } } } - /** finds a keyword-default value by a given name */ + /** + * finds a keyword-default value by a given name + */ @GenerateUncached @GenerateInline @GenerateCached(false) @@ -1012,19 +851,10 @@ static PKeyword doUncached(PKeyword[] kwdefaults, TruffleString kwname, } } - protected static Signature getSignatureUncached(Object callable) { - return getProperty(callable, UncachedSignatureGetter.INSTANCE); - } - - protected static Object[] getDefaultsUncached(Object callable) { - return getProperty(callable, UncachedDefaultsGetter.INSTANCE); - } - - protected static PKeyword[] getKwDefaultsUncached(Object callable) { - return getProperty(callable, UncachedKwDefaultsGetter.INSTANCE); - } - - protected static TruffleString getName(Object callable) { + protected static TruffleString getName(Object callable, Signature signature) { + if (!signature.getRaiseErrorName().isEmpty()) { + return signature.getRaiseErrorName(); + } if (callable instanceof TruffleString ts) { return ts; } @@ -1059,10 +889,6 @@ protected static Object getFunction(Object callable) { return null; } - protected static boolean isMethodCall(Object self) { - return !(self instanceof PythonModule); - } - private static T getProperty(Object callable, Getter getter) { if (callable instanceof PFunction) { return getter.fromPFunction((PFunction) callable); @@ -1089,48 +915,6 @@ private abstract static class Getter { public abstract T fromPBuiltinFunction(PBuiltinFunction fun); } - private static final class UncachedSignatureGetter extends Getter { - private static final UncachedSignatureGetter INSTANCE = new UncachedSignatureGetter(); - - @Override - public Signature fromPFunction(PFunction fun) { - return GetSignatureNode.executeUncached(fun); - } - - @Override - public Signature fromPBuiltinFunction(PBuiltinFunction fun) { - return fun.getSignature(); - } - } - - private static final class UncachedDefaultsGetter extends Getter { - private static final UncachedDefaultsGetter INSTANCE = new UncachedDefaultsGetter(); - - @Override - public Object[] fromPFunction(PFunction fun) { - return fun.getDefaults(); - } - - @Override - public Object[] fromPBuiltinFunction(PBuiltinFunction fun) { - return fun.getDefaults(); - } - } - - private static final class UncachedKwDefaultsGetter extends Getter { - private static final UncachedKwDefaultsGetter INSTANCE = new UncachedKwDefaultsGetter(); - - @Override - public PKeyword[] fromPFunction(PFunction fun) { - return fun.getKwDefaults(); - } - - @Override - public PKeyword[] fromPBuiltinFunction(PBuiltinFunction fun) { - return fun.getKwDefaults(); - } - } - private static final class QualnameGetter extends Getter { private static final QualnameGetter INSTANCE = new QualnameGetter(); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/ReadVarArgsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/ReadVarArgsNode.java index 716e488391..10f3ad8cc6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/ReadVarArgsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/ReadVarArgsNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -25,16 +25,17 @@ */ package com.oracle.graal.python.nodes.argument; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; public abstract class ReadVarArgsNode extends ReadArgumentNode { - @Child private PythonObjectFactory factory; + private final boolean isBuiltin; ReadVarArgsNode(boolean isBuiltin) { - factory = isBuiltin ? null : PythonObjectFactory.create(); + this.isBuiltin = isBuiltin; } public static ReadVarArgsNode create() { @@ -56,11 +57,11 @@ private Object output(Object[] varArgs) { if (isBuiltin()) { return varArgs; } else { - return factory.createTuple(varArgs); + return PFactory.createTuple(PythonLanguage.get(this), varArgs); } } public boolean isBuiltin() { - return factory == null; + return isBuiltin; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/ReadVarKeywordsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/ReadVarKeywordsNode.java index e09a866e44..8f6a0f059b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/ReadVarKeywordsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/ReadVarKeywordsNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -33,7 +33,7 @@ import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; @@ -47,7 +47,7 @@ public abstract class ReadVarKeywordsNode extends ReadArgumentNode { @CompilationFinal(dimensions = 1) private final TruffleString[] keywordNames; - @Child private PythonObjectFactory factory; + private final boolean doWrap; public abstract PKeyword[] executePKeyword(VirtualFrame frame); @@ -65,7 +65,7 @@ public static ReadVarKeywordsNode createForUserFunction(TruffleString[] names) { ReadVarKeywordsNode(TruffleString[] keywordNames, boolean doWrap) { this.keywordNames = keywordNames; - this.factory = doWrap ? PythonObjectFactory.create() : null; + this.doWrap = doWrap; } protected int getLimit() { @@ -86,8 +86,8 @@ protected static int getKwargLen(VirtualFrame frame) { } private Object returnValue(PKeyword[] keywords) { - if (factory != null) { - return factory.createDict(keywords); + if (doWrap) { + return PFactory.createDict(PythonLanguage.get(this), keywords); } else { return keywords; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/ConcatDictToStorageNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/ConcatDictToStorageNode.java index 6fa89a74ea..e51aa1bcef 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/ConcatDictToStorageNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/ConcatDictToStorageNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -49,12 +49,12 @@ import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.str.StringNodes; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; import com.oracle.graal.python.nodes.builtins.ListNodes; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; @@ -64,6 +64,7 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; +import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; @@ -78,20 +79,20 @@ public abstract class ConcatDictToStorageNode extends PNodeWithContext { public abstract HashingStorage execute(VirtualFrame frame, HashingStorage dest, Object other) throws SameDictKeyException, NonMappingException; - @Specialization(guards = "hasBuiltinDictIter(inliningTarget, other, getClassNode, lookupIter)", limit = "1") + @Specialization(guards = "hasBuiltinDictIter(inliningTarget, other, getClassNode, getSlots)", limit = "1") static HashingStorage doBuiltinDictEmptyDest(@SuppressWarnings("unused") EmptyStorage dest, PDict other, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Exclusive @Cached GetPythonObjectClassNode getClassNode, - @SuppressWarnings("unused") @Cached.Shared("lookupIter") @Cached(parameters = "Iter") LookupCallableSlotInMRONode lookupIter, + @SuppressWarnings("unused") @Shared @Cached GetCachedTpSlotsNode getSlots, @Cached HashingStorageNodes.HashingStorageCopy copyNode) { return copyNode.execute(inliningTarget, other.getDictStorage()); } - @Specialization(guards = "hasBuiltinDictIter(inliningTarget, other, getClassNode, lookupIter)", limit = "1") + @Specialization(guards = "hasBuiltinDictIter(inliningTarget, other, getClassNode, getSlots)", limit = "1") static HashingStorage doBuiltinDict(VirtualFrame frame, HashingStorage dest, PDict other, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Exclusive @Cached GetPythonObjectClassNode getClassNode, - @SuppressWarnings("unused") @Cached.Shared("lookupIter") @Cached(parameters = "Iter") LookupCallableSlotInMRONode lookupIter, + @SuppressWarnings("unused") @Shared @Cached GetCachedTpSlotsNode getSlots, @Exclusive @Cached HashingStorageNodes.HashingStorageGetItem resultGetItem, @Exclusive @Cached HashingStorageNodes.HashingStorageSetItem resultSetItem, @Cached HashingStorageNodes.HashingStorageGetIterator getIterator, @@ -118,15 +119,15 @@ static HashingStorage doBuiltinDict(VirtualFrame frame, HashingStorage dest, PDi } // Not using @Fallback because of GR-43912 - static boolean isFallback(Node inliningTarget, Object other, GetPythonObjectClassNode getClassNode, LookupCallableSlotInMRONode lookupIter) { - return !(other instanceof PDict otherDict && PGuards.hasBuiltinDictIter(inliningTarget, otherDict, getClassNode, lookupIter)); + static boolean isFallback(Node inliningTarget, Object other, GetPythonObjectClassNode getClassNode, GetCachedTpSlotsNode getSlots) { + return !(other instanceof PDict otherDict && PGuards.hasBuiltinDictIter(inliningTarget, otherDict, getClassNode, getSlots)); } - @Specialization(guards = "isFallback(inliningTarget, other, getClassNode, lookupIter)", limit = "1") + @Specialization(guards = "isFallback(inliningTarget, other, getClassNode, getSlots)", limit = "1") static HashingStorage doMapping(VirtualFrame frame, HashingStorage dest, Object other, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Exclusive @Cached GetPythonObjectClassNode getClassNode, - @SuppressWarnings("unused") @Cached.Shared("lookupIter") @Cached(parameters = "Iter") LookupCallableSlotInMRONode lookupIter, + @SuppressWarnings("unused") @Shared @Cached GetCachedTpSlotsNode getSlots, @Exclusive @Cached InlinedBranchProfile sameKeyProfile, @Exclusive @Cached StringNodes.CastToTruffleStringCheckedNode castToStringNode, @Cached PyObjectCallMethodObjArgs callKeys, diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/ExpandKeywordStarargsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/ExpandKeywordStarargsNode.java index 4e62c70612..76e6d8b836 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/ExpandKeywordStarargsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/ExpandKeywordStarargsNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -75,13 +75,13 @@ static PKeyword[] convert(@SuppressWarnings("unused") Object starargs) { @Specialization(guards = "!isNoValue(starargs)") static PKeyword[] convert(VirtualFrame frame, Node inliningTarget, Object starargs, @Cached MappingToKeywordsNode convertNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { return convertNode.execute(frame, inliningTarget, starargs); } catch (SameDictKeyException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.GOT_MULTIPLE_VALUES_FOR_KEYWORD_ARG, e.getKey()); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.GOT_MULTIPLE_VALUES_FOR_KEYWORD_ARG, e.getKey()); } catch (NonMappingException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.OBJ_ISNT_MAPPING, starargs); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.OBJ_ISNT_MAPPING, starargs); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/MappingToKeywordsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/MappingToKeywordsNode.java index 9f94f25a8c..8075f04481 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/MappingToKeywordsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/MappingToKeywordsNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -50,10 +50,10 @@ import com.oracle.graal.python.builtins.objects.common.KeywordsStorage; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.function.PKeyword; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; @@ -81,10 +81,10 @@ public abstract class MappingToKeywordsNode extends PNodeWithContext { public abstract PKeyword[] execute(VirtualFrame frame, Node inliningTarget, Object starargs) throws SameDictKeyException, NonMappingException; - @Specialization(guards = "hasBuiltinDictIter(inliningTarget, starargs, getClassNode, lookupIter)", limit = "1") + @Specialization(guards = "hasBuiltinDictIter(inliningTarget, starargs, getClassNode, getSlots)", limit = "1") public static PKeyword[] doDict(VirtualFrame frame, Node inliningTarget, PDict starargs, @SuppressWarnings("unused") @Cached GetPythonObjectClassNode getClassNode, - @SuppressWarnings("unused") @Cached(parameters = "Iter", inline = false) LookupCallableSlotInMRONode lookupIter, + @SuppressWarnings("unused") @Cached GetCachedTpSlotsNode getSlots, @Exclusive @Cached HashingStorageToKeywords convert) { return convert.execute(frame, inliningTarget, starargs.getDictStorage()); } @@ -118,7 +118,7 @@ public CopyKeywordsState add(Frame frame, @SuppressWarnings("unused") Node node, try { state.addKeyword(castToTruffleStringNode.execute(inliningTarget, key), value); } catch (CannotCastException e) { - throw raiseNode.raise(TypeError, ErrorMessages.KEYWORDS_S_MUST_BE_STRINGS); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.KEYWORDS_S_MUST_BE_STRINGS); } return state; } @@ -157,7 +157,6 @@ static PKeyword[] doEmptyStorage(@SuppressWarnings("unused") EmptyStorage storag @Specialization(guards = {"!isKeywordsStorage(storage)", "!isEmptyStorage(storage)"}) static PKeyword[] doCached(VirtualFrame frame, Node inliningTarget, HashingStorage storage, - @SuppressWarnings("unused") @Cached(parameters = "Iter", inline = false) LookupCallableSlotInMRONode lookupIter, @Cached(inline = false) AddKeywordNode addKeywordNode, @Cached HashingStorageNodes.HashingStorageForEach forEachNode, @SuppressWarnings("unused") @Cached HashingStorageLen lenNode, diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/positional/ExecutePositionalStarargsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/positional/ExecutePositionalStarargsNode.java index c9b2e9118e..3d7171a0e0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/positional/ExecutePositionalStarargsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/positional/ExecutePositionalStarargsNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -52,13 +52,12 @@ import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.set.PSet; import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; import com.oracle.graal.python.util.ArrayBuilder; import com.oracle.truffle.api.dsl.Bind; @@ -118,30 +117,29 @@ static Object[] doSet(PSet starargs, @Specialization static Object[] doNone(PNone none, - @Shared("raise") @Cached PRaiseNode raise) { - throw raise.raise(PythonErrorType.TypeError, ErrorMessages.ARG_AFTER_MUST_BE_ITERABLE, none); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.ARG_AFTER_MUST_BE_ITERABLE, none); } @Specialization static Object[] starargs(VirtualFrame frame, Object object, @Bind("this") Node inliningTarget, - @Shared("raise") @Cached PRaiseNode raise, + @Cached PRaiseNode raise, @Cached PyObjectGetIter getIter, - @Cached GetNextNode nextNode, - @Cached IsBuiltinObjectProfile errorProfile) { + @Cached PyIterNextNode nextNode) { Object iterator = getIter.execute(frame, inliningTarget, object); if (iterator != PNone.NO_VALUE && iterator != PNone.NONE) { ArrayBuilder internalStorage = new ArrayBuilder<>(); while (true) { try { - internalStorage.add(nextNode.execute(frame, iterator)); - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); + Object next = nextNode.execute(frame, inliningTarget, iterator); + internalStorage.add(next); + } catch (IteratorExhausted e) { return internalStorage.toArray(new Object[0]); } } } - throw raise.raise(PythonErrorType.TypeError, ErrorMessages.ARG_AFTER_MUST_BE_ITERABLE, object); + throw raise.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.ARG_AFTER_MUST_BE_ITERABLE, object); } @NeverDefault diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/ArrowArray.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/ArrowArray.java index 236927206b..5d2b56f03f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/ArrowArray.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/ArrowArray.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -89,67 +89,41 @@ public class ArrowArray { private static final long RELEASE_CALLBACK_INDEX = 8 * POINTER_SIZE; private static final long PRIVATE_DATA_INDEX = 9 * POINTER_SIZE; - public final long memoryAddr; + private final long memoryAddr; private ArrowArray(long memoryAddr) { this.memoryAddr = memoryAddr; } - public static ArrowArray allocate() { - var arrowArray = new ArrowArray(unsafe.allocateMemory(SIZE_OF)); - arrowArray.markReleased(); - return arrowArray; + public static ArrowArray allocate(long length, long nullCount, long offset, long nBuffers, long nChildren, long buffers, long children, long dictionary, long release, long privateData) { + var memoryAddr = unsafe.allocateMemory(SIZE_OF); + unsafe.putLong(memoryAddr + LENGTH_INDEX, length); + unsafe.putLong(memoryAddr + NULL_COUNT_INDEX, nullCount); + unsafe.putLong(memoryAddr + OFFSET_INDEX, offset); + unsafe.putLong(memoryAddr + N_BUFFERS_INDEX, nBuffers); + unsafe.putLong(memoryAddr + N_CHILDREN_INDEX, nChildren); + unsafe.putLong(memoryAddr + BUFFERS_INDEX, buffers); + unsafe.putLong(memoryAddr + CHILDREN_INDEX, children); + unsafe.putLong(memoryAddr + DICTIONARY_INDEX, dictionary); + unsafe.putLong(memoryAddr + RELEASE_CALLBACK_INDEX, release); + unsafe.putLong(memoryAddr + PRIVATE_DATA_INDEX, privateData); + + return new ArrowArray(memoryAddr); } - public static ArrowArray allocateFromSnapshot(Snapshot snapshot) { - var arrowArray = new ArrowArray(unsafe.allocateMemory(SIZE_OF)); - arrowArray.load(snapshot); - return arrowArray; + public long memoryAddress() { + return memoryAddr; } - public static ArrowArray wrap(long arrowArrayPointer) { - return new ArrowArray(arrowArrayPointer); + public long releaseCallback() { + return unsafe.getLong(memoryAddr + RELEASE_CALLBACK_INDEX); } - public void markReleased() { - unsafe.putLong(memoryAddr + RELEASE_CALLBACK_INDEX, NULL); + public static ArrowArray wrap(long arrowArrayPointer) { + return new ArrowArray(arrowArrayPointer); } public boolean isReleased() { - return unsafe.getLong(memoryAddr + RELEASE_CALLBACK_INDEX) == NULL; - } - - public long getBuffers() { - return unsafe.getLong(memoryAddr + BUFFERS_INDEX); - } - - public long getValueBuffer() { - return unsafe.getLong(getBuffers() + POINTER_SIZE); - } - - private void load(Snapshot snapshot) { - unsafe.putLong(memoryAddr + LENGTH_INDEX, snapshot.length); - unsafe.putLong(memoryAddr + NULL_COUNT_INDEX, snapshot.null_count); - unsafe.putLong(memoryAddr + OFFSET_INDEX, snapshot.offset); - unsafe.putLong(memoryAddr + N_BUFFERS_INDEX, snapshot.n_buffers); - unsafe.putLong(memoryAddr + N_CHILDREN_INDEX, snapshot.n_children); - unsafe.putLong(memoryAddr + BUFFERS_INDEX, snapshot.buffers); - unsafe.putLong(memoryAddr + CHILDREN_INDEX, snapshot.children); - unsafe.putLong(memoryAddr + DICTIONARY_INDEX, snapshot.dictionary); - unsafe.putLong(memoryAddr + RELEASE_CALLBACK_INDEX, snapshot.release); - unsafe.putLong(memoryAddr + PRIVATE_DATA_INDEX, snapshot.private_data); - } - - public static class Snapshot { - public long length = 0L; - public long null_count = 0L; - public long offset = 0L; - public long n_buffers = 0L; - public long n_children = 0L; - public long buffers = 0L; - public long children = 0L; - public long dictionary = 0L; - public long release = 0L; - public long private_data = 0L; + return releaseCallback() == NULL; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/ArrowSchema.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/ArrowSchema.java index e9f24171f5..0ac28db944 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/ArrowSchema.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/ArrowSchema.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -86,64 +86,39 @@ public class ArrowSchema { private static final long RELEASE_CALLBACK_INDEX = 7 * POINTER_SIZE; private static final long PRIVATE_DATA_INDEX = 8 * POINTER_SIZE; - public final long memoryAddr; + private final long memoryAddr; private ArrowSchema(long memoryAddr) { this.memoryAddr = memoryAddr; } - public static ArrowSchema allocate() { - var arrowSchema = new ArrowSchema(unsafe.allocateMemory(SIZE_OF)); - arrowSchema.markRelease(); - return arrowSchema; - } - - public static ArrowSchema allocateFromSnapshot(Snapshot snapshot) { - var arrowSchema = new ArrowSchema(unsafe.allocateMemory(SIZE_OF)); - arrowSchema.load(snapshot); - return arrowSchema; + public static ArrowSchema allocate(long format, long name, long metadata, long flags, long nChildren, long children, long dictionary, long release, long privateData) { + var memoryAddr = unsafe.allocateMemory(SIZE_OF); + unsafe.putLong(memoryAddr + FORMAT_INDEX, format); + unsafe.putLong(memoryAddr + NAME_INDEX, name); + unsafe.putLong(memoryAddr + METADATA_INDEX, metadata); + unsafe.putLong(memoryAddr + FLAGS_INDEX, flags); + unsafe.putLong(memoryAddr + N_CHILDREN_INDEX, nChildren); + unsafe.putLong(memoryAddr + CHILDREN_INDEX, children); + unsafe.putLong(memoryAddr + DICTIONARY_INDEX, dictionary); + unsafe.putLong(memoryAddr + RELEASE_CALLBACK_INDEX, release); + unsafe.putLong(memoryAddr + PRIVATE_DATA_INDEX, privateData); + return new ArrowSchema(memoryAddr); } public static ArrowSchema wrap(long arrowSchemaPointer) { return new ArrowSchema(arrowSchemaPointer); } - public long getFormat() { - return unsafe.getLong(memoryAddr); - } - - public boolean isReleased() { - return unsafe.getLong(memoryAddr + RELEASE_CALLBACK_INDEX) == NULL; + public long memoryAddress() { + return memoryAddr; } - public void markRelease() { - unsafe.putLong(memoryAddr + RELEASE_CALLBACK_INDEX, NULL); + public long releaseCallback() { + return unsafe.getLong(memoryAddr + RELEASE_CALLBACK_INDEX); } - public void load(Snapshot snapshot) { - unsafe.putLong(memoryAddr + FORMAT_INDEX, snapshot.format); - unsafe.putLong(memoryAddr + NAME_INDEX, snapshot.name); - unsafe.putLong(memoryAddr + METADATA_INDEX, snapshot.metadata); - unsafe.putLong(memoryAddr + FLAGS_INDEX, snapshot.flags); - unsafe.putLong(memoryAddr + N_CHILDREN_INDEX, snapshot.n_children); - unsafe.putLong(memoryAddr + CHILDREN_INDEX, snapshot.children); - unsafe.putLong(memoryAddr + DICTIONARY_INDEX, snapshot.dictionary); - unsafe.putLong(memoryAddr + RELEASE_CALLBACK_INDEX, snapshot.release); - unsafe.putLong(memoryAddr + PRIVATE_DATA_INDEX, snapshot.private_data); - } - - public static class Snapshot { - - public long format = 0L; - public long name = 0L; - public long metadata = 0L; - public long flags = 0L; - public long n_children = 0L; - public long children = 0L; - public long dictionary = 0L; - public long release = 0L; - public long private_data = 0L; - + public boolean isReleased() { + return releaseCallback() == NULL; } - } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/HPyDispatchers.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/InvokeArrowReleaseCallbackNode.java similarity index 56% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/HPyDispatchers.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/InvokeArrowReleaseCallbackNode.java index 96fe528b10..5a3da6a038 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/HPyDispatchers.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/InvokeArrowReleaseCallbackNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,53 +38,63 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.builtins.objects.type.slots; +package com.oracle.graal.python.nodes.arrow; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsHandleNode; -import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext; -import com.oracle.graal.python.runtime.IndirectCallData; +import com.oracle.graal.python.builtins.objects.cext.common.NativePointer; +import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; +import com.oracle.graal.python.runtime.arrow.ArrowUtil; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.InteropException; -import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.nfi.api.SignatureLibrary; -class HPyDispatchers { - private HPyDispatchers() { +@GenerateCached +@GenerateInline(inlineByDefault = true) +@GenerateUncached +public abstract class InvokeArrowReleaseCallbackNode extends PNodeWithContext { + + public abstract void execute(Node inliningTarget, long releaseCallback, long baseStructure); + + public final void executeCached(long releaseCallback, long baseStructure) { + execute(this, releaseCallback, baseStructure); + } + + @Specialization + static void doIt(Node inliningTarget, long releaseCallback, long baseStructure, + @Bind("getContext(inliningTarget)") PythonContext ctx, + @Cached(value = "createReleaseCallbackSignature(ctx)", allowUncached = true) Object callbackSignature, + @CachedLibrary(limit = "1") SignatureLibrary signatureLibrary) { + try { + signatureLibrary.call(callbackSignature, new NativePointer(releaseCallback), baseStructure); + } catch (Exception e) { + throw CompilerDirectives.shouldNotReachHere("Unable to call release callback. Error:", e); + } } + static Object createReleaseCallbackSignature(PythonContext context) { + return ArrowUtil.createNfiSignature("(UINT64):VOID", context); + } + + @GenerateCached(false) @GenerateInline @GenerateUncached - @GenerateCached(false) - public abstract static class UnaryHPySlotDispatcherNode extends Node { - public abstract Object execute(VirtualFrame frame, Node inliningTarget, PythonContext ctx, PythonThreadState threadState, Object nativeSlotCallable, Object self); + public abstract static class Lazy extends Node { + public final InvokeArrowReleaseCallbackNode get(Node inliningTarget) { + return execute(inliningTarget); + } + + abstract InvokeArrowReleaseCallbackNode execute(Node inliningTarget); @Specialization - static Object doIt(VirtualFrame frame, PythonContext ctx, PythonThreadState threadState, Object nativeSlotCallable, Object self, - @Cached("createFor(this)") IndirectCallData callData, - @Cached(inline = false) HPyAsHandleNode toHandleNode, - @CachedLibrary(limit = "3") InteropLibrary lib) { - Object hpyCtx = ctx.getHPyContext().getBackend(); - Object state = IndirectCallContext.enter(frame, threadState, callData); - try { - return lib.execute(nativeSlotCallable, hpyCtx, toHandleNode.execute(self)); - } catch (InteropException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } finally { - if (frame != null) { - PArguments.setException(frame, threadState.getCaughtException()); - } - IndirectCallContext.exit(frame, threadState, state); - } + static InvokeArrowReleaseCallbackNode doIt(@Cached(inline = false) InvokeArrowReleaseCallbackNode node) { + return node; } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/capsule/ArrowArrayCapsuleDestructor.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/capsule/ArrowArrayCapsuleDestructor.java index 983677ea99..1a84e3d306 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/capsule/ArrowArrayCapsuleDestructor.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/capsule/ArrowArrayCapsuleDestructor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,7 +45,7 @@ import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonNode; import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers; import com.oracle.graal.python.nodes.arrow.ArrowArray; -import com.oracle.graal.python.nodes.arrow.release_callback.ArrowArrayReleaseCallbackNode; +import com.oracle.graal.python.nodes.arrow.InvokeArrowReleaseCallbackNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Bind; @@ -72,15 +72,14 @@ static class Execute { @Specialization(guards = "isPointer(args, interopLib)") static Object doRelease(ArrowArrayCapsuleDestructor self, Object[] args, - @CachedLibrary(limit = "1") InteropLibrary interopLib, @Bind("$node") Node inliningTarget, + @CachedLibrary(limit = "1") InteropLibrary interopLib, @Cached NativeToPythonNode nativeToPythonNode, @Cached PyCapsuleGetPointerNode capsuleGetPointerNode, - @Cached ArrowArrayReleaseCallbackNode arrayReleaseNode) { + @Cached InvokeArrowReleaseCallbackNode.Lazy invokeReleaseCallbackNode) { Object capsule = nativeToPythonNode.execute(args[0]); var capsuleName = new CArrayWrappers.CByteArrayWrapper(ArrowArray.CAPSULE_NAME); - var arrowArrayPointer = (long) capsuleGetPointerNode.execute(inliningTarget, capsule, capsuleName); - var arrowArray = ArrowArray.wrap(arrowArrayPointer); + var arrowArray = ArrowArray.wrap((long) capsuleGetPointerNode.execute(inliningTarget, capsule, capsuleName)); /* * The exported PyCapsules should have a destructor that calls the release callback of * the Arrow struct, if it is not already null. This prevents a memory leak in case the @@ -91,9 +90,9 @@ static Object doRelease(ArrowArrayCapsuleDestructor self, Object[] args, * semantics */ if (!arrowArray.isReleased()) { - arrayReleaseNode.execute(inliningTarget, arrowArray); + invokeReleaseCallbackNode.get(inliningTarget).executeCached(arrowArray.releaseCallback(), arrowArray.memoryAddress()); } - PythonContext.get(inliningTarget).getUnsafe().freeMemory(arrowArrayPointer); + PythonContext.get(inliningTarget).getUnsafe().freeMemory(arrowArray.memoryAddress()); return PNone.NO_VALUE; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/capsule/ArrowSchemaCapsuleDestructor.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/capsule/ArrowSchemaCapsuleDestructor.java index 81e6344d49..020b871a8a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/capsule/ArrowSchemaCapsuleDestructor.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/capsule/ArrowSchemaCapsuleDestructor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,7 +45,7 @@ import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonNode; import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers; import com.oracle.graal.python.nodes.arrow.ArrowSchema; -import com.oracle.graal.python.nodes.arrow.release_callback.ArrowSchemaReleaseCallbackNode; +import com.oracle.graal.python.nodes.arrow.InvokeArrowReleaseCallbackNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Bind; @@ -74,19 +74,17 @@ static class Execute { static Object doRelease(ArrowSchemaCapsuleDestructor self, Object[] args, @Bind("$node") Node inliningTarget, @CachedLibrary(limit = "1") InteropLibrary interopLib, - @Cached ArrowSchemaReleaseCallbackNode releaseCallbackNode, @Cached NativeToPythonNode nativeToPythonNode, - @Cached PyCapsuleGetPointerNode pyCapsuleGetPointerNode) { + @Cached PyCapsuleGetPointerNode pyCapsuleGetPointerNode, @Cached InvokeArrowReleaseCallbackNode.Lazy invokeReleaseCallbackNode) { Object capsule = nativeToPythonNode.execute(args[0]); var capsuleName = new CArrayWrappers.CByteArrayWrapper(ArrowSchema.CAPSULE_NAME); - long arrowSchemaPointer = (long) pyCapsuleGetPointerNode.execute(inliningTarget, capsule, capsuleName); - ArrowSchema arrowSchema = ArrowSchema.wrap(arrowSchemaPointer); + var arrowSchema = ArrowSchema.wrap((long) pyCapsuleGetPointerNode.execute(inliningTarget, capsule, capsuleName)); if (!arrowSchema.isReleased()) { - releaseCallbackNode.execute(inliningTarget, arrowSchema); + invokeReleaseCallbackNode.get(inliningTarget).executeCached(arrowSchema.releaseCallback(), arrowSchema.memoryAddress()); } - PythonContext.get(inliningTarget).getUnsafe().freeMemory(arrowSchemaPointer); + PythonContext.get(inliningTarget).getUnsafe().freeMemory(arrowSchema.memoryAddress()); return PNone.NO_VALUE; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/release_callback/ArrowArrayReleaseCallback.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/release_callback/ArrowArrayReleaseCallback.java deleted file mode 100644 index 04699806e7..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/release_callback/ArrowArrayReleaseCallback.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.arrow.release_callback; - -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.nodes.arrow.ArrowArray; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.library.ExportLibrary; -import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.api.nodes.Node; - -@ExportLibrary(InteropLibrary.class) -public class ArrowArrayReleaseCallback implements TruffleObject { - - @ExportMessage - boolean isExecutable() { - return true; - } - - @ExportMessage - static class Execute { - - @Specialization(guards = "isPointer(args)") - static Object doRelease(ArrowArrayReleaseCallback self, Object[] args, - @Bind("$node") Node inliningTarget, - @Bind("wrapArrowArray(args)") ArrowArray arrowArray, - @Cached ArrowArrayReleaseCallbackNode releaseNode) { - releaseNode.execute(inliningTarget, arrowArray); - return PNone.NO_VALUE; - } - - @Fallback - static Object doError(ArrowArrayReleaseCallback self, Object[] args) { - throw CompilerDirectives.shouldNotReachHere(); - } - - static ArrowArray wrapArrowArray(Object[] args) { - long arrowArrayPointer = (long) args[0]; - return ArrowArray.wrap(arrowArrayPointer); - } - - static boolean isPointer(Object[] args) { - return args.length == 1 && args[0] instanceof Long; - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/vector/GetFormatFromVectorNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/vector/GetFormatFromVectorNode.java deleted file mode 100644 index 5c857c08be..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/vector/GetFormatFromVectorNode.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.arrow.vector; - -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node; - -@GenerateCached(false) -@GenerateInline -public abstract class GetFormatFromVectorNode extends PNodeWithContext { - - public abstract byte execute(Node inliningTarget, Object hostVector); - - static final String INT8_PACKAGE_PATH = "org.apache.arrow.vector.TinyIntVector"; - static final String INT16_PACKAGE_PATH = "org.apache.arrow.vector.SmallIntVector"; - static final String INT32_PACKAGE_PATH = "org.apache.arrow.vector.IntVector"; - static final String INT64_PACKAGE_PATH = "org.apache.arrow.vector.BigIntVector"; - static final String BOOLEAN_PACKAGE_PATH = "org.apache.arrow.vector.BitVector"; - static final String FLOAT2_PACKAGE_PATH = "org.apache.arrow.vector.Float2Vector"; - static final String FLOAT4_PACKAGE_PATH = "org.apache.arrow.vector.Float4Vector"; - static final String FLOAT8_PACKAGE_PATH = "org.apache.arrow.vector.Float8Vector"; - - @Specialization(guards = "int32VectorClass.isInstance(hostVector)", limit = "1") - static byte doInt32(Object hostVector, - @Cached(value = "getClass(INT32_PACKAGE_PATH)") Class int32VectorClass) { - // i = 105 - return 105; - } - - @Specialization(guards = "int64VectorClass.isInstance(hostVector)", limit = "1") - static byte doInt64(Object hostVector, - @Cached(value = "getClass(INT64_PACKAGE_PATH)") Class int64VectorClass) { - // l = 108 - return 108; - } - - @Specialization(guards = "float4VectorClass.isInstance(hostVector)", limit = "1") - static byte doFloat4(Object hostVector, - @Cached(value = "getClass(FLOAT4_PACKAGE_PATH)") Class float4VectorClass) { - // f = 102 - return 102; - } - - @Specialization(guards = "float8VectorClass.isInstance(hostVector)", limit = "1") - static byte doFloat8(Object hostVector, - @Cached(value = "getClass(FLOAT8_PACKAGE_PATH)") Class float8VectorClass) { - // g = 103 - return 103; - } - - @Specialization(guards = "int16VectorClass.isInstance(hostVector)", limit = "1") - static byte doInt16(Object hostVector, - @Cached(value = "getClass(INT16_PACKAGE_PATH)") Class int16VectorClass) { - // s = 115 - return 115; - } - - @Specialization(guards = "int8VectorClass.isInstance(hostVector)", limit = "1") - static byte doInt8(Object hostVector, - @Cached(value = "getClass(INT8_PACKAGE_PATH)") Class int8VectorClass) { - // c = 99 - return 99; - } - - @Specialization(guards = "boolVectorClass.isInstance(hostVector)", limit = "1") - static byte doBoolean(Object hostVector, - @Cached(value = "getClass(BOOLEAN_PACKAGE_PATH)") Class boolVectorClass) { - // b = 98 - return 98; - } - - @Specialization(guards = "float2VectorClass.isInstance(hostVector)", limit = "1") - static byte doFloat2(Object hostVector, - @Cached(value = "getClass(FLOAT2_PACKAGE_PATH)") Class float2VectorClass) { - // e = 101 - return 101; - } - - @Fallback - static byte doError(Object obj) { - throw CompilerDirectives.shouldNotReachHere(); - } - - static Class getClass(String path) { - try { - return Class.forName(path); - } catch (ClassNotFoundException e) { - throw CompilerDirectives.shouldNotReachHere(); - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/vector/VectorToArrowArrayNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/vector/VectorToArrowArrayNode.java deleted file mode 100644 index 96e3e4a462..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/vector/VectorToArrowArrayNode.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.arrow.vector; - -import static com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess.POINTER_SIZE; - -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.arrow.ArrowArray; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.nodes.Node; - -@GenerateCached(false) -@GenerateInline -public abstract class VectorToArrowArrayNode extends PNodeWithContext { - - public abstract ArrowArray execute(Node inliningTarget, Object vector); - - @Specialization(guards = "ctx.arrowVectorSupport.isFixedWidthVector(vector)") - static ArrowArray doIntVector(Node inliningTarget, Object vector, - @Bind("getContext(inliningTarget)") PythonContext ctx, - @CachedLibrary(limit = "3") InteropLibrary interopLib) { - var snapshot = new ArrowArray.Snapshot(); - var unsafe = ctx.getUnsafe(); - try { - snapshot.length = (Integer) interopLib.invokeMember(vector, "getValueCount"); - snapshot.null_count = (Integer) interopLib.invokeMember(vector, "getNullCount"); - snapshot.n_buffers = (Integer) interopLib.invokeMember(vector, "getExportedCDataBufferCount"); - if (snapshot.n_buffers != 2) { - throw CompilerDirectives.shouldNotReachHere( - "We expect that Vector implementation to has just 2 buffers, those are validity buffer and value buffer. This should never happen unless arrow changes internally"); - } - snapshot.buffers = unsafe.allocateMemory(2 * POINTER_SIZE); - long validityPointer = (long) interopLib.invokeMember(vector, "getValidityBufferAddress"); - unsafe.putLong(snapshot.buffers, validityPointer); - long dataPointer = (long) interopLib.invokeMember(vector, "getDataBufferAddress"); - unsafe.putLong(snapshot.buffers + POINTER_SIZE, dataPointer); - snapshot.release = ctx.arrowVectorSupport.getVectorArrowArrayReleaseCallback(); - - return ArrowArray.allocateFromSnapshot(snapshot); - } catch (Exception e) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw CompilerDirectives.shouldNotReachHere("Unable to convert vector to arrow array. Error: " + e.getMessage()); - } - } - - @Fallback - static ArrowArray doError(Object object) { - throw CompilerDirectives.shouldNotReachHere(); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/GetAttributeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/GetAttributeNode.java index c4e5a4f83c..889b74f54d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/GetAttributeNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/GetAttributeNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,6 +43,7 @@ import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETATTR__; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.exception.AttributeErrorBuiltins; import com.oracle.graal.python.builtins.objects.module.ModuleBuiltins; import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins; import com.oracle.graal.python.builtins.objects.type.TpSlots; @@ -52,6 +53,7 @@ import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.attributes.GetAttributeNodeFactory.GetFixedAttributeNodeGen; import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.NeverDefault; @@ -133,7 +135,7 @@ final Object doBuiltinType(VirtualFrame frame, Object object, @SuppressWarnings( @Specialization(guards = "isModuleGetAttribute(slots)") final Object doBuiltinModule(VirtualFrame frame, Object object, @SuppressWarnings("unused") TpSlots slots, - @Cached ModuleBuiltins.ModuleGetattritbuteNode getAttributeNode) { + @Cached ModuleBuiltins.ModuleGetattributeNode getAttributeNode) { assert hasNoGetAttr(object); return getAttributeNode.execute(frame, object, key); } @@ -141,8 +143,13 @@ final Object doBuiltinModule(VirtualFrame frame, Object object, @SuppressWarning @Specialization(replaces = {"doBuiltinObject", "doBuiltinType", "doBuiltinModule"}) final Object doGeneric(VirtualFrame frame, Object object, TpSlots slots, @Bind("this") Node inliningTarget, - @Cached CallSlotGetAttrNode callGetAttrNode) { - return callGetAttrNode.execute(frame, inliningTarget, slots, object, key); + @Cached CallSlotGetAttrNode callGetAttrNode, + @Cached AttributeErrorBuiltins.SetAttributeErrorContext setContext) { + try { + return callGetAttrNode.execute(frame, inliningTarget, slots, object, key); + } catch (PException e) { + throw setContext.execute(inliningTarget, e, object, key); + } } @NeverDefault diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupAttributeInMRONode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupAttributeInMRONode.java index a6d6af6b19..4cdb7b7215 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupAttributeInMRONode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupAttributeInMRONode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -84,7 +84,10 @@ import com.oracle.truffle.api.strings.TruffleString; @ImportStatic(PythonOptions.class) -public abstract class LookupAttributeInMRONode extends LookupInMROBaseNode { +public abstract class LookupAttributeInMRONode extends PNodeWithContext { + + public abstract Object execute(Object klass); + @GenerateUncached @GenerateInline(false) // footprint reduction 36 -> 17 public abstract static class Dynamic extends PNodeWithContext { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupCallableSlotInMRONode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupCallableSlotInMRONode.java deleted file mode 100644 index 9ef8490ac4..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupCallableSlotInMRONode.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.attributes; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.BinaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.TernaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.UnaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.function.PFunction; -import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; -import com.oracle.graal.python.builtins.objects.type.PythonClass; -import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.Idempotent; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node; - -/** - * The same as {@link LookupAttributeInMRONode}, but this may also return an instance of - * {@link BuiltinMethodDescriptor}. - * {@link com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode} and similar should accept - * such objects as a callable. - */ -@ImportStatic({PythonOptions.class, PythonLanguage.class}) -public abstract class LookupCallableSlotInMRONode extends LookupInMROBaseNode { - - protected abstract static class CachedLookup extends LookupCallableSlotInMRONode { - protected final SpecialMethodSlot slot; - - protected CachedLookup(SpecialMethodSlot slot) { - this.slot = slot; - } - - // Single and multi context: - // PythonBuiltinClassType: if there is a value for the slot in PythonBuiltinClassType, then - // we can just cache it even in multi-context case - @Specialization(guards = {"klass == cachedKlass", "result != null"}, limit = "getAttributeAccessInlineCacheMaxDepth()") - static Object doBuiltinTypeCached(@SuppressWarnings("unused") PythonBuiltinClassType klass, - @SuppressWarnings("unused") @Cached(value = "klass") PythonBuiltinClassType cachedKlass, - @Cached(value = "slot.getValue(klass)") Object result) { - assert isCacheable(result) : result; - return result; - } - - // Single-context - - @Specialization(guards = {"isSingleContext()", "klass == cachedKlass"}, // - assumptions = "cachedKlass.getSlotsFinalAssumption()", // - limit = "getAttributeAccessInlineCacheMaxDepth()") - static Object doSlotCachedSingleCtx(@SuppressWarnings("unused") PythonClass klass, - @SuppressWarnings("unused") @Cached(value = "klass", weak = true) PythonClass cachedKlass, - @Cached(value = "slot.getValue(klass)", weak = true) Object result) { - return result; - } - - @Specialization(guards = {"isSingleContext()", "klass == cachedKlass"}, limit = "getAttributeAccessInlineCacheMaxDepth()") - static Object doBuiltinCachedSingleCtx(@SuppressWarnings("unused") PythonBuiltinClass klass, - @SuppressWarnings("unused") @Cached("klass") PythonBuiltinClass cachedKlass, - @Cached("slot.getValue(klass)") Object result) { - return result; - } - - // PythonBuiltinClassType: if the value of the slot is not node factory or None, we must - // read - // the slot from the resolved builtin class - @Specialization(guards = {"isSingleContext()", "klassType == cachedKlassType", "slot.getValue(cachedKlassType) == null"}, // - limit = "getAttributeAccessInlineCacheMaxDepth()") - static Object doBuiltinTypeCachedSingleCtx(@SuppressWarnings("unused") PythonBuiltinClassType klassType, - @SuppressWarnings("unused") @Cached("klassType") PythonBuiltinClassType cachedKlassType, - @Cached("slot.getValue(getContext().lookupType(cachedKlassType))") Object value) { - return value; - } - - // Multi-context: - - @Specialization(replaces = "doSlotCachedSingleCtx", guards = {"slot.getValue(klass) == result", "isCacheable(result)"}, // - limit = "getAttributeAccessInlineCacheMaxDepth()") - static Object doSlotCachedMultiCtx(@SuppressWarnings("unused") PythonClass klass, - @Cached("slot.getValue(klass)") Object result) { - // in multi-context we can still cache primitives and BuiltinMethodDescriptor instances - return result; - } - - @Specialization(replaces = "doSlotCachedMultiCtx") - Object doSlotUncachedMultiCtx(PythonClass klass, - @Bind("this") Node inliningTarget, - @Shared("slotValueProfile") @Cached SlotValueProfile slotValueProfile) { - return slotValueProfile.profile(inliningTarget, slot.getValue(klass)); - } - - // For PythonBuiltinClass it depends on whether we can cache the result: - - @Idempotent - protected static boolean isCacheable(Object value) { - return PythonLanguage.canCache(value) || BuiltinMethodDescriptor.isInstance(value); - } - - @Specialization(guards = {"klass.getType() == cachedType", "isCacheable(result)"}, // - replaces = "doBuiltinCachedSingleCtx", limit = "getAttributeAccessInlineCacheMaxDepth()") - static Object doBuiltinCachedMultiCtx(@SuppressWarnings("unused") PythonBuiltinClass klass, - @SuppressWarnings("unused") @Cached("klass.getType()") PythonBuiltinClassType cachedType, - @Cached("slot.getValue(klass)") Object result) { - return result; - } - - @Specialization(replaces = {"doBuiltinCachedSingleCtx", "doBuiltinCachedMultiCtx"}) - Object doBuiltinUncachableMultiCtx(PythonBuiltinClass klass, - @Bind("this") Node inliningTarget, - @Shared("slotValueProfile") @Cached SlotValueProfile slotValueProfile) { - return slotValueProfile.profile(inliningTarget, slot.getValue(klass)); - } - - // PythonBuiltinClassType: if the value of the slot is null, we must read the slot from the - // resolved builtin class - @Specialization(guards = {"klassType == cachedKlassType", "slot.getValue(cachedKlassType) == null"}, limit = "1") - static Object doBuiltinTypeMultiContext(@SuppressWarnings("unused") PythonBuiltinClassType klassType, - @Bind("this") Node inliningTarget, - @Exclusive @Cached SlotValueProfile slotValueProfile, - @SuppressWarnings("unused") @Cached("klassType") PythonBuiltinClassType cachedKlassType, - @Bind("slot.getValue(getContext().lookupType(cachedKlassType))") Object value) { - return slotValueProfile.profile(inliningTarget, value); - } - - // Fallback when the cache with PythonBuiltinClassType overflows: - - @Specialization(replaces = {"doBuiltinTypeCached", "doBuiltinTypeCachedSingleCtx", "doBuiltinTypeMultiContext"}) - Object doBuiltinTypeGeneric(PythonBuiltinClassType klass, - @Bind("this") Node inliningTarget, - @Shared("slotValueProfile") @Cached SlotValueProfile slotValueProfile) { - Object result = slot.getValue(klass); - if (result == null) { - result = slot.getValue(PythonContext.get(this).lookupType(klass)); - } - return slotValueProfile.profile(inliningTarget, result); - } - - // Native classes: - - @Specialization - @InliningCutoff - static Object doNativeClass(PythonAbstractNativeObject klass, - @Bind("this") Node inliningTarget, - @Shared("slotValueProfile") @Cached SlotValueProfile slotValueProfile, - @Cached("create(slot.getName())") LookupAttributeInMRONode lookup) { - return slotValueProfile.profile(inliningTarget, lookup.execute(klass)); - } - } - - @NeverDefault - public static LookupCallableSlotInMRONode create(SpecialMethodSlot slot) { - return LookupCallableSlotInMRONodeFactory.CachedLookupNodeGen.create(slot); - } - - protected static final class UncachedLookup extends LookupCallableSlotInMRONode { - - private final SpecialMethodSlot slot; - - private UncachedLookup(SpecialMethodSlot slot) { - this.slot = slot; - } - - @Override - @TruffleBoundary - public final Object execute(Object klass) { - if (klass instanceof PythonBuiltinClassType) { - Object result = slot.getValue((PythonBuiltinClassType) klass); - if (result == null) { - result = slot.getValue(PythonContext.get(null).lookupType((PythonBuiltinClassType) klass)); - } - return result; - } else if (klass instanceof PythonManagedClass) { - return slot.getValue((PythonManagedClass) klass); - } else { - assert klass instanceof PythonAbstractNativeObject; - return LookupAttributeInMRONode.Dynamic.getUncached().execute(klass, slot.getName()); - } - } - - @Override - public boolean isAdoptable() { - return false; - } - - private static final UncachedLookup[] UNCACHEDS = new UncachedLookup[SpecialMethodSlot.values().length]; - static { - SpecialMethodSlot[] values = SpecialMethodSlot.values(); - for (int i = 0; i < values.length; i++) { - SpecialMethodSlot slot = values[i]; - UNCACHEDS[i] = new UncachedLookup(slot); - } - } - } - - public static LookupCallableSlotInMRONode getUncached(SpecialMethodSlot slot) { - return UncachedLookup.UNCACHEDS[slot.ordinal()]; - } - - @GenerateUncached - @GenerateInline - @GenerateCached(false) - @ImportStatic(PGuards.class) - protected abstract static class SlotValueProfile extends Node { - final Object profile(Node inliningTarget, Object value) { - return execute(inliningTarget, value); - } - - abstract Object execute(Node inliningTarget, Object value); - - @Specialization - static UnaryBuiltinDescriptor unaryDescr(UnaryBuiltinDescriptor value) { - return value; - } - - @Specialization - static BinaryBuiltinDescriptor binaryDescr(BinaryBuiltinDescriptor value) { - return value; - } - - @Specialization - static TernaryBuiltinDescriptor ternaryDescr(TernaryBuiltinDescriptor value) { - return value; - } - - @Specialization - static PBuiltinFunction builtin(PBuiltinFunction builtin) { - return builtin; - } - - @Specialization - static PFunction fun(PFunction fun) { - return fun; - } - - @Specialization(guards = "isNoValue(none)") - static PNone noValue(@SuppressWarnings("unused") PNone none) { - return PNone.NO_VALUE; - } - - @Specialization(guards = "isNone(none)") - static PNone none(@SuppressWarnings("unused") PNone none) { - return PNone.NONE; - } - - // Intentionally not guarded, if it is activated first, we want to just bail out from - // profiling - @Specialization(replaces = {"unaryDescr", "binaryDescr", "ternaryDescr", "builtin", "fun", "noValue", "none"}) - static Object other(Object value) { - return value; - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupInMROBaseNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupInMROBaseNode.java deleted file mode 100644 index 1b04c0d8ac..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupInMROBaseNode.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.attributes; - -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.truffle.api.dsl.ImportStatic; - -@ImportStatic(PythonOptions.class) -public abstract class LookupInMROBaseNode extends PNodeWithContext { - public abstract Object execute(Object klass); -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupNativeSlotNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupNativeSlotNode.java deleted file mode 100644 index aeb2714b01..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupNativeSlotNode.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.attributes; - -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; -import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext; -import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol; -import com.oracle.graal.python.builtins.objects.cext.capi.SlotMethodDef; -import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; -import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; -import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; -import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroStorageNode; -import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.interop.InteropLibrary; - -/** - * Lookup a suitable slot function. When the slot is found to be inherited from a native superclass, - * this returns the same function pointer, so behaves just like CPython would. For inheriting - * managed slots we differ, however. CPython installs some slot functions in PyHeapTypeObjects that - * do a lookup of the method in the type's dict and call it. We avoid this and instead return a - * function pointer that directly calls the correct method (see {@link #wrapManagedMethod}). - * However, there are two caveats: - * - * 1) In CPython, were a PyHeapTypeObject supertype to change a magic method in its dict after a - * subclass inherited from it, the slot lookup will (correctly) go to the new method. In our case it - * will not, since we have created a closure over the method at the time of inheritance. So far this - * has not been an issue, so we ignore it. - * - * 2) Some slots that map to the same Python method cannot be treated in this way. Consider what - * happens if we inherit from a managed type with a __len__ method and a native type with - * tp_as_mapping->mp_length. We would copy the mp_length slot from the native type, and create a - * closure to call the managed __len__ method for tp_as_sequence->sq_length. This is not what - * CPython does. In CPython, the sq_length slot would be set to a C function that does a dynamic - * lookup and call of __len__! So it depends on the MRO order if we end up in the managed __len__ or - * in fact bounce back into native to invoke the mp_length function when calling - * tp_as_sequence->sq_length on the subtype! As for 1), we ignore the potential of later __dict__ - * updates along the MRO chain and return the pointer to the native slot, if that should take - * precedence. - */ -public abstract class LookupNativeSlotNode extends PNodeWithContext { - private LookupNativeSlotNode() { - } - - @TruffleBoundary - public static Object executeUncached(PythonManagedClass klass, SlotMethodDef slot) { - var mro = GetMroStorageNode.getUncached().execute(null, klass); - var readAttrNode = ReadAttributeFromObjectNode.getUncachedForceType(); - var readPointerNode = CStructAccess.ReadPointerNode.getUncached(); - var interopLibrary = InteropLibrary.getUncached(); - var overlappingSlot = slot.overlappingSlot; - Object foundNativeSlotOverlap = null; - for (int i = 0; i < mro.length(); i++) { - PythonAbstractClass kls = mro.getPythonClassItemNormalized(i); - Object value = readSlot(slot, kls, readAttrNode, readPointerNode, interopLibrary); - if (value != null) { - if (foundNativeSlotOverlap != null && kls instanceof PythonManagedClass) { - // we found managed method with the same name as a previous slot. the slot - // should shadow the method - return foundNativeSlotOverlap; - } - return value; - } - if (overlappingSlot != null && foundNativeSlotOverlap == null && kls instanceof PythonAbstractNativeObject nativeObject) { - foundNativeSlotOverlap = readSlot(overlappingSlot, kls, readAttrNode, readPointerNode, interopLibrary); - } - } - if (foundNativeSlotOverlap != null) { - return foundNativeSlotOverlap; - } - return getNULL(); - } - - private static Object getNULL() { - return PythonContext.get(null).getNativeNull(); - } - - private static Object readSlot(SlotMethodDef slot, PythonAbstractClass currentType, ReadAttributeFromObjectNode readNode, CStructAccess.ReadPointerNode readPointerNode, - InteropLibrary interopLibrary) { - if (currentType instanceof PythonAbstractNativeObject nativeObject) { - Object value = readPointerNode.readFromObj(nativeObject, slot.typeField); - if (!PGuards.isNullOrZero(value, interopLibrary)) { - if (slot.methodsField == null) { - return value; - } else { - value = readPointerNode.read(value, slot.methodsField); - if (!PGuards.isNullOrZero(value, interopLibrary)) { - return value; - } - } - } - } else { - assert currentType instanceof PythonManagedClass; - if (slot.methodFlag != 0 && currentType instanceof PythonBuiltinClass builtinClass) { - if ((builtinClass.getType().getMethodsFlags() & slot.methodFlag) == 0) { - return null; - } - } - Object value = readNode.execute(currentType, slot.methodName); - if (value != PNone.NO_VALUE) { - if (slot == SlotMethodDef.TP_HASH && value == PNone.NONE) { - return CApiContext.getNativeSymbol(null, NativeCAPISymbol.FUN_PYOBJECT_HASH_NOT_IMPLEMENTED); - } - return wrapManagedMethod(slot, (PythonManagedClass) currentType, value); - } - } - return null; - } - - private static Object wrapManagedMethod(SlotMethodDef slot, PythonManagedClass owner, Object value) { - if (value instanceof PNone) { - return getNULL(); - } - return PythonContext.get(null).getCApiContext().getOrCreateProcWrapper(owner, slot, () -> slot.wrapperFactory.apply(value)); - } - - @Override - public boolean isAdoptable() { - return false; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/WriteAttributeToObjectNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/WriteAttributeToObjectNode.java index 012300b2b4..6dc8a40ddf 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/WriteAttributeToObjectNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/WriteAttributeToObjectNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -50,13 +50,13 @@ import com.oracle.graal.python.builtins.objects.cext.structs.CFields; import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; import com.oracle.graal.python.builtins.objects.common.HashingStorage; +import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; import com.oracle.graal.python.builtins.objects.type.PythonClass; import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeFlags; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode; @@ -151,7 +151,7 @@ boolean writeToDynamicStorageBuiltinType(PythonBuiltinClass klass, TruffleString @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) { if (PythonContext.get(this).isInitialized()) { - throw PRaiseNode.raiseUncached(this, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, key, klass); + throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, key, klass); } else { return writeToDynamicStorageManagedClass(klass, key, value, inliningTarget, callAttrUpdate, dylib, codePointLengthNode, codePointAtIndexNode); } @@ -188,7 +188,7 @@ private static boolean writeToDynamicStorageManagedClass(PythonManagedClass klas } // write to the dict: the basic specialization for non-classes - @Specialization(guards = {"dict != null", "!isManagedClass(object)"}) + @Specialization(guards = {"dict != null", "!isManagedClass(object)", "!isNoValue(value)"}) static boolean writeToDictNoType(@SuppressWarnings("unused") PythonObject object, TruffleString key, Object value, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared("getDict") @Cached GetDictIfExistsNode getDict, @@ -199,7 +199,7 @@ static boolean writeToDictNoType(@SuppressWarnings("unused") PythonObject object } // write to the dict & PythonManagedClass -> requires calling onAttributeUpdate - @Specialization(guards = {"dict != null"}) + @Specialization(guards = {"dict != null", "!isNoValue(value)"}) boolean writeToDictBuiltinType(PythonBuiltinClass klass, TruffleString key, Object value, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared("getDict") @Cached GetDictIfExistsNode getDict, @@ -210,13 +210,13 @@ boolean writeToDictBuiltinType(PythonBuiltinClass klass, TruffleString key, Obje @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) { if (PythonContext.get(this).isInitialized()) { - throw PRaiseNode.raiseUncached(this, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, PyObjectReprAsTruffleStringNode.executeUncached(key), klass); + throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, PyObjectReprAsTruffleStringNode.executeUncached(key), klass); } else { return writeToDictManagedClass(klass, dict, key, value, inliningTarget, callAttrUpdate, updateStorage, setHashingStorageItem, codePointLengthNode, codePointAtIndexNode); } } - @Specialization(guards = {"dict != null"}) + @Specialization(guards = {"dict != null", "!isNoValue(value)"}) static boolean writeToDictClass(PythonClass klass, TruffleString key, Object value, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Shared("getDict") @Cached GetDictIfExistsNode getDict, @@ -229,6 +229,36 @@ static boolean writeToDictClass(PythonClass klass, TruffleString key, Object val return writeToDictManagedClass(klass, dict, key, value, inliningTarget, callAttrUpdate, updateStorage, setHashingStorageItem, codePointLengthNode, codePointAtIndexNode); } + @Specialization(guards = {"dict != null", "isNoValue(value)", "!isPythonBuiltinClass(obj)"}) + static boolean deleteFromPythonObject(PythonObject obj, TruffleString key, Object value, + @Bind("this") Node inliningTarget, + @SuppressWarnings("unused") @Shared("getDict") @Cached GetDictIfExistsNode getDict, + @Bind("getDict.execute(obj)") PDict dict, + @Shared("callAttrUpdate") @Cached InlinedBranchProfile callAttrUpdate, + @Cached HashingStorageNodes.HashingStorageDelItem hashingStorageDelItem, + @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, + @Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) { + try { + HashingStorage dictStorage = dict.getDictStorage(); + return hashingStorageDelItem.execute(inliningTarget, dictStorage, key, dict); + } finally { + if (obj instanceof PythonManagedClass klass) { + if (!klass.canSkipOnAttributeUpdate(key, value, codePointLengthNode, codePointAtIndexNode)) { + callAttrUpdate.enter(inliningTarget); + klass.onAttributeUpdate(key, value); + } + } + } + } + + @Specialization(guards = {"dict != null", "isNoValue(value)"}) + static boolean deleteFromPythonBuiltinClass(PythonBuiltinClass klass, TruffleString key, Object value, + @Bind("this") Node inliningTarget, + @SuppressWarnings("unused") @Shared("getDict") @Cached GetDictIfExistsNode getDict, + @Bind("getDict.execute(klass)") PDict dict) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, key, klass); + } + private static boolean writeToDictManagedClass(PythonManagedClass klass, PDict dict, TruffleString key, Object value, Node inliningTarget, InlinedBranchProfile callAttrUpdate, InlinedBranchProfile updateStorage, HashingStorageSetItem setHashingStorageItem, TruffleString.CodePointLengthNode codePointLengthNode, TruffleString.CodePointAtIndexNode codePointAtIndexNode) { @@ -292,7 +322,7 @@ static boolean writeNativeObject(PythonAbstractNativeObject object, TruffleStrin @Shared("getDict") @Cached GetDictIfExistsNode getDict, @Shared("setHashingStorageItem") @Cached HashingStorageSetItem setHashingStorageItem, @Shared("updateStorage") @Cached InlinedBranchProfile updateStorage, - @Shared("raiseNode") @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode) { /* * The dict of native objects that stores the object attributes is located at 'objectPtr * + Py_TYPE(objectPtr)->tp_dictoffset'. 'PythonObjectLibrary.getDict' will exactly load @@ -302,28 +332,28 @@ static boolean writeNativeObject(PythonAbstractNativeObject object, TruffleStrin if (dict != null) { return writeToDict(dict, key, value, inliningTarget, updateStorage, setHashingStorageItem); } - throw raiseNode.raise(PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); } @Specialization(guards = "isErrorCase(getDict, object)") static boolean doError(Object object, TruffleString key, @SuppressWarnings("unused") Object value, @SuppressWarnings("unused") @Shared("getDict") @Cached GetDictIfExistsNode getDict, - @Shared("raiseNode") @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); } } @GenerateUncached - @ImportStatic(SpecialMethodSlot.class) @GenerateInline(false) // footprint reduction 132 -> 115 + @ImportStatic(TpSlots.class) protected abstract static class WriteAttributeToObjectTpDictNode extends WriteAttributeToObjectNode { - private static void checkNativeImmutable(PythonAbstractNativeObject object, TruffleString key, + private static void checkNativeImmutable(Node inliningTarget, PythonAbstractNativeObject object, TruffleString key, CStructAccess.ReadI64Node getNativeFlags, PRaiseNode raiseNode) { long flags = getNativeFlags.readFromObj(object, CFields.PyTypeObject__tp_flags); if ((flags & TypeFlags.IMMUTABLETYPE) != 0) { - throw raiseNode.raise(TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, key, object); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, key, object); } } @@ -331,7 +361,7 @@ private static void checkNativeImmutable(PythonAbstractNativeObject object, Truf * Simplest case: the key object is a String (so it cannot be a hidden key) and it's not a * special method slot. */ - @Specialization(guards = "!canBeSpecial(key, codePointLengthNode, codePointAtIndexNode)") + @Specialization(guards = "!canBeSpecialMethod(key, codePointLengthNode, codePointAtIndexNode)") static boolean writeNativeClassSimple(PythonAbstractNativeObject object, TruffleString key, Object value, @Bind("this") Node inliningTarget, @Shared @Cached CStructAccess.ReadI64Node getNativeFlags, @@ -341,7 +371,7 @@ static boolean writeNativeClassSimple(PythonAbstractNativeObject object, Truffle @Shared("raiseNode") @Cached PRaiseNode raiseNode, @SuppressWarnings("unused") @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, @SuppressWarnings("unused") @Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) { - checkNativeImmutable(object, key, getNativeFlags, raiseNode); + checkNativeImmutable(inliningTarget, object, key, getNativeFlags, raiseNode); /* * For native types, the type attributes are stored in a dict that is located in * 'typePtr->tp_dict'. So, this is different to a native object (that is not a type) and @@ -352,7 +382,7 @@ static boolean writeNativeClassSimple(PythonAbstractNativeObject object, Truffle if (dict instanceof PDict) { return writeToDict((PDict) dict, key, value, inliningTarget, updateStorage, setHashingStorageItem); } - throw raiseNode.raise(PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); } @Specialization(replaces = "writeNativeClassSimple") @@ -366,10 +396,9 @@ static boolean writeNativeClassGeneric(PythonAbstractNativeObject object, Truffl @Cached IsTypeNode isTypeNode, @Shared("raiseNode") @Cached PRaiseNode raiseNode, @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, - @Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, - @Cached TruffleString.EqualNode equalNode) { + @Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) { try { - checkNativeImmutable(object, key, getNativeFlags, raiseNode); + checkNativeImmutable(inliningTarget, object, key, getNativeFlags, raiseNode); /* * For native types, the type attributes are stored in a dict that is located in * 'typePtr->tp_dict'. So, this is different to a native object (that is not a type) @@ -380,7 +409,7 @@ static boolean writeNativeClassGeneric(PythonAbstractNativeObject object, Truffl if (dict instanceof PDict) { return writeToDict((PDict) dict, key, value, inliningTarget, updateStorage, setHashingStorageItem); } - throw raiseNode.raise(PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); } finally { if (TpSlots.canBeSpecialMethod(key, codePointLengthNode, codePointAtIndexNode)) { canBeSpecialSlot.enter(inliningTarget); @@ -391,11 +420,6 @@ static boolean writeNativeClassGeneric(PythonAbstractNativeObject object, Truffl if (isTypeNode.execute(inliningTarget, object)) { TpSlots.updateSlot(object, key); } - // TODO: will be removed: - SpecialMethodSlot slot = SpecialMethodSlot.findSpecialSlot(key, codePointLengthNode, codePointAtIndexNode, equalNode); - if (slot != null) { - SpecialMethodSlot.fixupSpecialMethodSlot(object, slot, value); - } } } } @@ -403,8 +427,8 @@ static boolean writeNativeClassGeneric(PythonAbstractNativeObject object, Truffl @Specialization(guards = "isErrorCase(getDict, object)") static boolean doError(Object object, TruffleString key, @SuppressWarnings("unused") Object value, @SuppressWarnings("unused") @Shared("getDict") @Cached GetDictIfExistsNode getDict, - @Shared("raiseNode") @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/ListNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/ListNodes.java index eee49e41de..9bdcccd688 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/ListNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/ListNodes.java @@ -46,6 +46,7 @@ import static com.oracle.graal.python.nodes.ErrorMessages.DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; @@ -54,10 +55,7 @@ import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ListGeneralizationNode; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.list.PList; -import com.oracle.graal.python.builtins.objects.str.PString; -import com.oracle.graal.python.builtins.objects.str.StringUtils; import com.oracle.graal.python.lib.PyObjectGetIter; -import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.builtins.ListNodesFactory.AppendNodeGen; @@ -65,10 +63,7 @@ import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.IsForeignObjectNode; -import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.runtime.sequence.PSequence; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.ArrayBasedSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.EmptySequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.ForeignSequenceStorage; @@ -76,15 +71,15 @@ import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; @@ -96,8 +91,6 @@ import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.profiles.InlinedConditionProfile; -import com.oracle.truffle.api.strings.TruffleString; -import com.oracle.truffle.api.strings.TruffleStringIterator; /** See the docs on {@link com.oracle.graal.python.builtins.objects.list.ListBuiltins}. */ public abstract class ListNodes { @@ -113,6 +106,7 @@ static SequenceStorage doPList(PList list) { return list.getSequenceStorage(); } + @InliningCutoff @Specialization(guards = {"isForeignObjectNode.execute(inliningTarget, seq)", "interop.hasArrayElements(seq)"}, limit = "1") static SequenceStorage doForeign(Node inliningTarget, Object seq, @Cached IsForeignObjectNode isForeignObjectNode, @@ -126,10 +120,10 @@ static SequenceStorage doForeign(Node inliningTarget, Object seq, } } + @InliningCutoff @Fallback - static SequenceStorage doFallback(Node inliningTarget, Object seq, - @Cached PRaiseNode.Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(TypeError, DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P, "list", seq); + static SequenceStorage doFallback(Node inliningTarget, Object seq) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P, "list", seq); } } @@ -203,68 +197,35 @@ static Object doForeign(Object list) { } @GenerateUncached - @ImportStatic({PGuards.class, PythonOptions.class}) @GenerateInline(false) // footprint reduction 40 -> 21 public abstract static class ConstructListNode extends PNodeWithContext { - public final PList execute(Frame frame, Object value) { - return execute(frame, PythonBuiltinClassType.PList, value); - } - - protected abstract PList execute(Frame frame, Object cls, Object value); - - @Specialization - static PList listString(Object cls, TruffleString arg, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached TruffleString.CodePointLengthNode codePointLengthNode, - @Shared @Cached TruffleString.CreateCodePointIteratorNode createCodePointIteratorNode, - @Shared @Cached TruffleStringIterator.NextNode nextNode, - @Shared @Cached TruffleString.FromCodePointNode fromCodePointNode) { - return factory.createList(cls, StringUtils.toCharacterArray(arg, codePointLengthNode, createCodePointIteratorNode, nextNode, fromCodePointNode)); - } - - @Specialization - static PList listString(Object cls, PString arg, - @Bind("this") Node inliningTarget, - @Shared @Cached PythonObjectFactory factory, - @Cached CastToTruffleStringNode castToStringNode, - @Shared @Cached TruffleString.CodePointLengthNode codePointLengthNode, - @Shared @Cached TruffleString.CreateCodePointIteratorNode createCodePointIteratorNode, - @Shared @Cached TruffleStringIterator.NextNode nextNode, - @Shared @Cached TruffleString.FromCodePointNode fromCodePointNode) { - return listString(cls, castToStringNode.execute(inliningTarget, arg), factory, codePointLengthNode, createCodePointIteratorNode, nextNode, fromCodePointNode); - } + public abstract PList execute(Frame frame, Object value); @Specialization(guards = "isNoValue(none)") - static PList none(Object cls, @SuppressWarnings("unused") PNone none, - @Shared @Cached PythonObjectFactory factory) { - return factory.createList(cls); + static PList none(@SuppressWarnings("unused") PNone none, + @Bind PythonLanguage language) { + return PFactory.createList(language); } @Specialization(guards = "isBuiltinList(list)") // Don't use PSequence, that might copy storages that we don't allow for lists - static PList fromList(Object cls, PList list, + static PList fromList(PList list, @Bind("this") Node inliningTarget, - @Shared @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached SequenceStorageNodes.CopyNode copyNode) { - return factory.createList(cls, copyNode.execute(inliningTarget, list.getSequenceStorage())); + return PFactory.createList(language, copyNode.execute(inliningTarget, list.getSequenceStorage())); } - @Specialization(guards = {"!isNoValue(iterable)", "!isString(iterable)"}) - static PList listIterable(VirtualFrame frame, Object cls, Object iterable, + @Specialization(guards = "!isNoValue(iterable)") + static PList listIterable(VirtualFrame frame, Object iterable, @Bind("this") Node inliningTarget, @Cached PyObjectGetIter getIter, @Cached SequenceStorageNodes.CreateStorageFromIteratorNode createStorageFromIteratorNode, - @Shared @Cached PythonObjectFactory factory) { + @Bind PythonLanguage language) { Object iterObj = getIter.execute(frame, inliningTarget, iterable); SequenceStorage storage = createStorageFromIteratorNode.execute(frame, iterObj); - return factory.createList(cls, storage); - } - - @Fallback - static PList listObject(@SuppressWarnings("unused") Object cls, Object value) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw CompilerDirectives.shouldNotReachHere("list does not support iterable object " + value); + return PFactory.createList(language, storage); } @NeverDefault @@ -282,17 +243,17 @@ public static ConstructListNode getUncached() { @GenerateCached(false) public abstract static class FastConstructListNode extends PNodeWithContext { - public abstract PSequence execute(Frame frame, Node inliningTarget, Object value); + public abstract PList execute(Frame frame, Node inliningTarget, Object value); @Specialization(guards = "isBuiltinList(value)") - protected static PSequence doPList(PSequence value) { + protected static PList doPList(PList value) { return value; } @Fallback - protected PSequence doGeneric(VirtualFrame frame, Object value, + protected PList doGeneric(VirtualFrame frame, Object value, @Cached(inline = false) ConstructListNode constructListNode) { - return constructListNode.execute(frame, PythonBuiltinClassType.PList, value); + return constructListNode.execute(frame, value); } } @@ -307,6 +268,7 @@ protected PSequence doGeneric(VirtualFrame frame, Object value, */ @GenerateUncached @GenerateInline(false) // footprint reduction 36 -> 17 + @OperationProxy.Proxyable public abstract static class AppendNode extends PNodeWithContext { private static final BranchProfile[] DISABLED = new BranchProfile[]{BranchProfile.getUncached()}; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java index 583ef42436..144d6c65bb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,23 +43,23 @@ import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTupleObject__ob_item; import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyVarObject__ob_size; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; +import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.CreateStorageFromIteratorNode; +import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyTupleCheckNode; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.NativeObjectSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -75,38 +75,36 @@ public abstract class TupleNodes { @GenerateUncached @GenerateInline(false) // footprint reduction 40 -> 21 public abstract static class ConstructTupleNode extends PNodeWithContext { - public final PTuple execute(VirtualFrame frame, Object value) { - return execute(frame, PythonBuiltinClassType.PTuple, value); - } - - public abstract PTuple execute(Frame frame, Object cls, Object value); + public abstract PTuple execute(Frame frame, Object value); @Specialization(guards = "isNoValue(none)") - static PTuple tuple(Object cls, @SuppressWarnings("unused") PNone none, - @Shared("factory") @Cached PythonObjectFactory factory) { - return factory.createEmptyTuple(cls); + static PTuple tuple(@SuppressWarnings("unused") PNone none, + @Bind PythonLanguage language) { + return PFactory.createEmptyTuple(language); } - @Specialization(guards = {"isBuiltinTupleType(inliningTarget, cls, isSameTypeNode)", "isBuiltinTuple(iterable)"}, limit = "1") - static PTuple tuple(@SuppressWarnings("unused") Object cls, PTuple iterable, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached TypeNodes.IsSameTypeNode isSameTypeNode) { + @Specialization(guards = "isBuiltinTuple(iterable)") + static PTuple tuple(PTuple iterable) { return iterable; } + @Specialization(guards = "isBuiltinList(iterable)") + static PTuple list(PList iterable, + @Bind("this") Node inliningTarget, + @Bind PythonLanguage language, + @Cached SequenceStorageNodes.CopyNode copyNode) { + return PFactory.createTuple(language, copyNode.execute(inliningTarget, iterable.getSequenceStorage())); + } + @Fallback @InliningCutoff - static PTuple tuple(VirtualFrame frame, Object cls, Object iterable, + static PTuple generic(VirtualFrame frame, Object iterable, @Bind("this") Node inliningTarget, - @Shared("factory") @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached CreateStorageFromIteratorNode storageNode, @Cached PyObjectGetIter getIter) { Object iterObj = getIter.execute(frame, inliningTarget, iterable); - return factory.createTuple(cls, storageNode.execute(frame, iterObj)); - } - - protected static boolean isBuiltinTupleType(Node inliningTarget, Object cls, TypeNodes.IsSameTypeNode isSameTypeNode) { - return isSameTypeNode.execute(inliningTarget, cls, PythonBuiltinClassType.PTuple); + return PFactory.createTuple(language, storageNode.execute(frame, iterObj)); } @NeverDefault diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/AbstractKwargsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/AbstractKwargsNode.java index 49408f54df..251ea87c36 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/AbstractKwargsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/AbstractKwargsNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -49,16 +49,17 @@ import com.oracle.graal.python.nodes.argument.keywords.SameDictKeyException; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; public class AbstractKwargsNode extends PNodeWithContext { - protected static PException handleNonMapping(VirtualFrame frame, PRaiseNode raise, int stackTop, NonMappingException e) { + protected static PException handleNonMapping(VirtualFrame frame, Node inliningTarget, PRaiseNode raise, int stackTop, NonMappingException e) { Object functionName = AbstractKwargsNode.getFunctionName(frame, stackTop); - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.ARG_AFTER_MUST_BE_MAPPING, functionName, e.getObject()); + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ARG_AFTER_MUST_BE_MAPPING, functionName, e.getObject()); } - protected static PException handleSameKey(VirtualFrame frame, PRaiseNode raise, int stackTop, SameDictKeyException e) { + protected static PException handleSameKey(VirtualFrame frame, Node inliningTarget, PRaiseNode raise, int stackTop, SameDictKeyException e) { Object functionName = AbstractKwargsNode.getFunctionName(frame, stackTop); - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.S_GOT_MULTIPLE_VALUES_FOR_KEYWORD_ARG, functionName, e.getKey()); + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.S_GOT_MULTIPLE_VALUES_FOR_KEYWORD_ARG, functionName, e.getKey()); } private static Object getFunctionName(VirtualFrame frame, int stackTop) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyTracker.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/BytecodeFrameInfo.java similarity index 53% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyTracker.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/BytecodeFrameInfo.java index 2f151bdeb5..5d0761210e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyTracker.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/BytecodeFrameInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,51 +38,63 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.builtins.objects.cext.hpy; +package com.oracle.graal.python.nodes.bytecode; -import java.util.Arrays; +import com.oracle.graal.python.compiler.CodeUnit; +import com.oracle.graal.python.compiler.OpCodesConstants; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.frame.Frame; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyCloseHandleNode; -import com.oracle.graal.python.util.OverflowException; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.nodes.Node; +public class BytecodeFrameInfo implements FrameInfo { + @CompilationFinal PBytecodeRootNode rootNode; -public final class GraalHPyTracker { - private static final int HPYTRACKER_INITIAL_SIZE = 5; - - private GraalHPyHandle[] handles; - private int cursor; + void setRootNode(PBytecodeRootNode rootNode) { + this.rootNode = rootNode; + } - public GraalHPyTracker(int capacity) { - int size = capacity == 0 ? HPYTRACKER_INITIAL_SIZE : capacity; - this.handles = new GraalHPyHandle[size]; + @Override + public PBytecodeRootNode getRootNode() { + return rootNode; } - public void add(GraalHPyHandle h) throws OverflowException { - handles[cursor++] = h; - if (handles.length <= cursor) { - resize(); + public int getBci(Frame frame) { + if (frame.isInt(rootNode.bcioffset)) { + return frame.getInt(rootNode.bcioffset); + } else { + return -1; } } - @TruffleBoundary - private void resize() throws OverflowException { - handles = Arrays.copyOf(handles, PythonUtils.multiplyExact(handles.length, 2) - 1); + public int getLineForBci(int bci) { + return rootNode.bciToLine(bci); } - public void free(Node inliningTarget, HPyCloseHandleNode closeHandleNode) { - assert cursor <= handles.length; - for (int i = 0; i < cursor; i++) { - closeHandleNode.execute(inliningTarget, handles[i]); - } - cursor = 0; + public int getLine(Frame frame) { + return getLineForBci(getBci(frame)); + } + + @Override + public int getFirstLineNumber() { + return rootNode.getFirstLineno(); } - public void removeAll() { - for (int i = 0; i < handles.length; i++) { - handles[i] = null; + @Override + public Object getYieldFrom(Frame generatorFrame, int bci, int stackTop) { + /* Match the `yield from` bytecode pattern and get the object from stack */ + if (bci > 3 && bci < rootNode.bytecode.length && rootNode.bytecode[bci - 3] == OpCodesConstants.SEND && rootNode.bytecode[bci - 1] == OpCodesConstants.YIELD_VALUE && + rootNode.bytecode[bci] == OpCodesConstants.RESUME_YIELD) { + return generatorFrame.getObject(stackTop); } - cursor = 0; + return null; + } + + @Override + public CodeUnit getCodeUnit() { + return rootNode.getCodeUnit(); + } + + @Override + public boolean includeInTraceback() { + return rootNode.frameIsVisibleToPython(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/release_callback/ArrowSchemaReleaseCallback.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/CallComprehensionNode.java similarity index 60% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/release_callback/ArrowSchemaReleaseCallback.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/CallComprehensionNode.java index af3979d0f6..f6d4a0087c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/arrow/release_callback/ArrowSchemaReleaseCallback.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/CallComprehensionNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,46 +38,36 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.nodes.arrow.release_callback; +package com.oracle.graal.python.nodes.bytecode; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.nodes.arrow.ArrowSchema; +import com.oracle.graal.python.builtins.objects.function.PFunction; +import com.oracle.graal.python.nodes.call.CallDispatchers; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.ImportStatic; +import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.library.ExportLibrary; -import com.oracle.truffle.api.library.ExportMessage; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.DirectCallNode; import com.oracle.truffle.api.nodes.Node; -@ExportLibrary(InteropLibrary.class) -public class ArrowSchemaReleaseCallback implements TruffleObject { +@GenerateInline(false) +@ImportStatic(CallDispatchers.class) +public abstract class CallComprehensionNode extends Node { + public abstract Object execute(VirtualFrame frame, PFunction callee, Object[] arguments); - @ExportMessage - boolean isExecutable() { - return true; + // No guard, comprehension functions don't change + @Specialization + static Object call(VirtualFrame frame, PFunction callee, Object[] arguments, + @Bind Node inliningTarget, + @Cached("createDirectCallNodeFor(callee)") DirectCallNode callNode, + @Cached CallDispatchers.FunctionDirectInvokeNode invoke) { + return invoke.execute(frame, inliningTarget, callNode, callee, arguments); } - @ExportMessage - static class Execute { - - @Specialization(guards = "isPointer(args)") - static Object doRelease(ArrowSchemaReleaseCallback self, Object[] args, - @Bind("$node") Node inliningTarget, - @Bind("wrapArrowSchema(args)") ArrowSchema arrowSchema, - @Cached ArrowSchemaReleaseCallbackNode releaseNode) { - releaseNode.execute(inliningTarget, arrowSchema); - return PNone.NO_VALUE; - } - - static boolean isPointer(Object[] args) { - return args.length == 1 && args[0] instanceof Long; - } - - static ArrowSchema wrapArrowSchema(Object[] args) { - long pointer = (long) args[0]; - return ArrowSchema.wrap(pointer); - } + @NeverDefault + public static CallComprehensionNode create() { + return CallComprehensionNodeGen.create(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/CopyDictWithoutKeysNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/CopyDictWithoutKeysNode.java index e6694902f8..11806cacb2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/CopyDictWithoutKeysNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/CopyDictWithoutKeysNode.java @@ -40,12 +40,14 @@ */ package com.oracle.graal.python.nodes.bytecode; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.dict.DictNodes; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.lib.PyDictDelItem; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -58,17 +60,18 @@ import com.oracle.truffle.api.nodes.Node; @GenerateInline(false) // used in BCI root node +@OperationProxy.Proxyable public abstract class CopyDictWithoutKeysNode extends PNodeWithContext { public abstract PDict execute(Frame frame, Object subject, Object[] keys); @Specialization(guards = {"keys.length == keysLength", "keysLength <= 32"}, limit = "1") - static PDict copy(VirtualFrame frame, Object subject, @NeverDefault @SuppressWarnings("unused") Object[] keys, + public static PDict copy(VirtualFrame frame, Object subject, @NeverDefault @SuppressWarnings("unused") Object[] keys, @Bind("this") Node inliningTarget, @Cached("keys.length") int keysLength, - @Shared @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Shared @Cached DictNodes.UpdateNode updateNode, @Shared @Cached PyDictDelItem delItem) { - PDict rest = factory.createDict(); + PDict rest = PFactory.createDict(language); updateNode.execute(frame, rest, subject); deleteKeys(frame, inliningTarget, keys, keysLength, delItem, rest); return rest; @@ -83,12 +86,12 @@ private static void deleteKeys(VirtualFrame frame, Node inliningTarget, Object[] } @Specialization(guards = "keys.length > 32") - static PDict copy(VirtualFrame frame, Object subject, Object[] keys, + public static PDict copy(VirtualFrame frame, Object subject, Object[] keys, @Bind("this") Node inliningTarget, - @Shared @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Shared @Cached DictNodes.UpdateNode updateNode, @Shared @Cached PyDictDelItem delItem) { - PDict rest = factory.createDict(); + PDict rest = PFactory.createDict(language); updateNode.execute(frame, rest, subject); for (int i = 0; i < keys.length; i++) { delItem.execute(frame, inliningTarget, rest, keys[i]); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ExitWithNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ExitWithNode.java index 22dd080662..ae7e59d39f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ExitWithNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ExitWithNode.java @@ -43,7 +43,6 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.exception.ExceptionNodes; import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.call.special.CallQuaternaryMethodNode; @@ -54,7 +53,6 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.exception.AbstractTruffleException; @@ -63,7 +61,6 @@ import com.oracle.truffle.api.nodes.Node; @GenerateUncached -@ImportStatic(SpecialMethodSlot.class) @GenerateInline(false) // Used in BCI public abstract class ExitWithNode extends PNodeWithContext { public abstract int execute(Frame frame, int stackTop, boolean rootNodeVisible); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ForIterINode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ForIterINode.java index 701a7839a8..c35c64eb89 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ForIterINode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ForIterINode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,18 +40,11 @@ */ package com.oracle.graal.python.nodes.bytecode; -import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.iterator.PIntRangeIterator; import com.oracle.graal.python.compiler.QuickeningTypes; -import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.exception.PythonErrorType; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; @@ -64,10 +57,6 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedCountingConditionProfile; -/** - * Obtains the next value of an iterator. When the iterator is exhausted it returns {@code null}. It - * never raises {@code StopIteration}. - */ @GenerateUncached @GenerateInline(false) // Used in BCI public abstract class ForIterINode extends PNodeWithContext { @@ -94,29 +83,19 @@ boolean doIntRange(VirtualFrame frame, PIntRangeIterator iterator, int stackTop, @Specialization @InliningCutoff static boolean doGeneric(VirtualFrame frame, Object iterator, int stackTop, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached(parameters = "Next") LookupSpecialMethodSlotNode lookupNext, - @Cached CallUnaryMethodNode callNext, - @Cached IsBuiltinObjectProfile stopIterationProfile, - @Cached PRaiseNode raiseNode) throws QuickeningGeneralizeException { - Object nextMethod = lookupNext.execute(frame, getClassNode.execute(inliningTarget, iterator), iterator); - if (nextMethod == PNone.NO_VALUE) { - throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.OBJ_NOT_ITERABLE, iterator); - } + @Bind Node inliningTarget, + @Cached PyIterNextNode nextNode) throws QuickeningGeneralizeException { try { - Object res = callNext.executeObject(frame, nextMethod, iterator); + Object res = nextNode.execute(frame, inliningTarget, iterator); if (res instanceof Integer) { frame.setInt(stackTop, (int) res); return true; } else { CompilerDirectives.transferToInterpreterAndInvalidate(); - // TODO other types frame.setObject(stackTop, res); throw new QuickeningGeneralizeException(QuickeningTypes.OBJECT); } - } catch (PException e) { - e.expectStopIteration(inliningTarget, stopIterationProfile); + } catch (IteratorExhausted e) { return false; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ForIterONode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ForIterONode.java index 06f8a9dabe..1e4084a8c7 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ForIterONode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ForIterONode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,17 +40,10 @@ */ package com.oracle.graal.python.nodes.bytecode; -import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.iterator.PIntRangeIterator; -import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.exception.PythonErrorType; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -62,10 +55,6 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedCountingConditionProfile; -/** - * Obtains the next value of an iterator. When the iterator is exhausted it returns {@code null}. It - * never raises {@code StopIteration}. - */ @GenerateUncached @GenerateInline(false) // Used in BCI public abstract class ForIterONode extends PNodeWithContext { @@ -92,22 +81,13 @@ boolean doIntRange(VirtualFrame frame, PIntRangeIterator iterator, int stackTop, @Specialization @InliningCutoff static boolean doGeneric(VirtualFrame frame, Object iterator, int stackTop, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached(parameters = "Next") LookupSpecialMethodSlotNode lookupNext, - @Cached CallUnaryMethodNode callNext, - @Cached IsBuiltinObjectProfile stopIterationProfile, - @Cached PRaiseNode raiseNode) { - assert iterator != null; - Object nextMethod = lookupNext.execute(frame, getClassNode.execute(inliningTarget, iterator), iterator); - if (nextMethod == PNone.NO_VALUE) { - throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.OBJ_NOT_ITERABLE, iterator); - } + @Bind Node inliningTarget, + @Cached PyIterNextNode nextNode) { try { - frame.setObject(stackTop, callNext.executeObject(frame, nextMethod, iterator)); + Object res = nextNode.execute(frame, inliningTarget, iterator); + frame.setObject(stackTop, res); return true; - } catch (PException e) { - e.expectStopIteration(inliningTarget, stopIterationProfile); + } catch (IteratorExhausted e) { return false; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/FrameInfo.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/FrameInfo.java index 97a4d69844..3fbc8a948f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/FrameInfo.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/FrameInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,8 +41,7 @@ package com.oracle.graal.python.nodes.bytecode; import com.oracle.graal.python.compiler.CodeUnit; -import com.oracle.graal.python.compiler.OpCodesConstants; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.graal.python.nodes.PRootNode; import com.oracle.truffle.api.dsl.Idempotent; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameDescriptor; @@ -53,38 +52,30 @@ * returned by {@link FrameDescriptor#getInfo()} if and only if the frame is coming from the * bytecode interpreter. */ -public final class FrameInfo { - @CompilationFinal PBytecodeRootNode rootNode; +public interface FrameInfo { - public PBytecodeRootNode getRootNode() { - return rootNode; - } + public PRootNode getRootNode(); - public int getBci(Frame frame) { - if (frame.isInt(rootNode.bcioffset)) { - return frame.getInt(rootNode.bcioffset); - } else { - return -1; - } - } + public int getFirstLineNumber(); - public Object getYieldFrom(Frame generatorFrame, int bci, int stackTop) { - /* Match the `yield from` bytecode pattern and get the object from stack */ - if (bci > 3 && bci < rootNode.bytecode.length && rootNode.bytecode[bci - 3] == OpCodesConstants.SEND && rootNode.bytecode[bci - 1] == OpCodesConstants.YIELD_VALUE && - rootNode.bytecode[bci] == OpCodesConstants.RESUME_YIELD) { - return generatorFrame.getObject(stackTop); - } - return null; - } + public Object getYieldFrom(Frame generatorFrame, int bci, int stackTop); + + public boolean includeInTraceback(); + + public CodeUnit getCodeUnit(); @Idempotent - public int getVariableCount() { - CodeUnit code = rootNode.getCodeUnit(); + public default int getVariableCount() { + CodeUnit code = getCodeUnit(); return code.varnames.length + code.cellvars.length + code.freevars.length; } - public TruffleString getVariableName(int slot) { - CodeUnit code = rootNode.getCodeUnit(); + public default int getRegularVariableCount() { + return getCodeUnit().varnames.length; + } + + public default TruffleString getVariableName(int slot) { + CodeUnit code = getCodeUnit(); if (slot < code.varnames.length) { return code.varnames[slot]; } else if (slot < code.varnames.length + code.cellvars.length) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetAExitCoroNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetAExitCoroNode.java index 214d78c0fb..6c264869f9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetAExitCoroNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetAExitCoroNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,7 +43,6 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.exception.ExceptionNodes; import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.call.special.CallQuaternaryMethodNode; import com.oracle.graal.python.nodes.object.GetClassNode; @@ -52,14 +51,12 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @GenerateUncached -@ImportStatic(SpecialMethodSlot.class) @GenerateInline(false) // used in BCI root node public abstract class GetAExitCoroNode extends PNodeWithContext { public abstract int execute(Frame frame, int stackTop); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetAIterNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetAIterNode.java index 2465b85a28..c6140ef39d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetAIterNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetAIterNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,30 +42,26 @@ import static com.oracle.graal.python.nodes.ErrorMessages.ASYNC_FOR_NO_AITER; import static com.oracle.graal.python.nodes.ErrorMessages.ASYNC_FOR_NO_ANEXT_INITIAL; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ANEXT__; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotUnaryFunc.CallSlotUnaryNode; +import com.oracle.graal.python.lib.PyAIterCheckNode; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode; -import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; +import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedBranchProfile; @GenerateUncached -@ImportStatic(SpecialMethodSlot.class) @GenerateInline(false) // used in bytecode root node public abstract class GetAIterNode extends PNodeWithContext { public abstract Object execute(Frame frame, Object receiver); @@ -74,32 +70,28 @@ public static GetAIterNode getUncached() { return GetAIterNodeGen.getUncached(); } + @NeverDefault public static GetAIterNode create() { return GetAIterNodeGen.create(); } @Specialization - Object doGeneric(Frame frame, Object receiver, + Object doGeneric(VirtualFrame frame, Object receiver, @Bind("this") Node inliningTarget, - @Cached(parameters = "AIter") LookupSpecialMethodSlotNode getAIter, @Cached GetClassNode getAsyncIterType, - @Cached PRaiseNode.Lazy raiseNoAIter, - @Cached TypeNodes.GetNameNode getName, - @Cached InlinedBranchProfile errorProfile, - @Cached CallUnaryMethodNode callAIter, - @Cached LookupInheritedAttributeNode.Dynamic lookupANext) { - + @Cached GetCachedTpSlotsNode getSlots, + @Cached CallSlotUnaryNode callSlot, + @Cached PRaiseNode raiseNoAIter, + @Cached PRaiseNode raiseNoANext, + @Cached PyAIterCheckNode checkNode) { Object type = getAsyncIterType.execute(inliningTarget, receiver); - Object getter = getAIter.execute(frame, type, receiver); - if (getter == PNone.NO_VALUE) { - errorProfile.enter(this); - throw raiseNoAIter.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ASYNC_FOR_NO_AITER, getName.execute(inliningTarget, type)); + TpSlots slots = getSlots.execute(inliningTarget, type); + if (slots.am_aiter() == null) { + throw raiseNoAIter.raise(inliningTarget, PythonBuiltinClassType.TypeError, ASYNC_FOR_NO_AITER, type); } - Object asyncIterator = callAIter.executeObject(frame, getter, receiver); - Object anext = lookupANext.execute(inliningTarget, asyncIterator, T___ANEXT__); - if (anext == PNone.NO_VALUE) { - errorProfile.enter(this); - throw raiseNoAIter.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ASYNC_FOR_NO_ANEXT_INITIAL, getName.execute(inliningTarget, type)); + Object asyncIterator = callSlot.execute(frame, inliningTarget, slots.am_aiter(), receiver); + if (!checkNode.execute(inliningTarget, asyncIterator)) { + throw raiseNoANext.raise(inliningTarget, PythonBuiltinClassType.TypeError, ASYNC_FOR_NO_ANEXT_INITIAL, asyncIterator); } return asyncIterator; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetANextNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetANextNode.java index deb1141529..98d34fb242 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetANextNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetANextNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,30 +44,26 @@ import static com.oracle.graal.python.nodes.ErrorMessages.ASYNC_FOR_NO_ANEXT_ITERATION; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.asyncio.GetAwaitableNode; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotUnaryFunc.CallSlotUnaryNode; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedBranchProfile; @GenerateUncached -@ImportStatic(SpecialMethodSlot.class) @GenerateInline(false) // used in bytecode root node public abstract class GetANextNode extends PNodeWithContext { - public abstract Object execute(Frame frame, Object receiver); + public abstract Object execute(VirtualFrame frame, Object receiver); public static GetANextNode getUncached() { return GetANextNodeGen.getUncached(); @@ -78,27 +74,24 @@ public static GetANextNode create() { } @Specialization - Object doGeneric(Frame frame, Object receiver, + Object doGeneric(VirtualFrame frame, Object receiver, @Bind("this") Node inliningTarget, - @Cached(parameters = "ANext") LookupSpecialMethodSlotNode getANext, @Cached GetClassNode getAsyncIterType, + @Cached GetCachedTpSlotsNode getSlots, + @Cached CallSlotUnaryNode callSlot, @Cached PRaiseNode raiseNoANext, - @Cached InlinedBranchProfile errorProfile, - @Cached CallUnaryMethodNode callANext, @Cached PRaiseNode raiseInvalidObject, - @Cached(neverDefault = true) GetAwaitableNode getAwaitable) { + @Cached GetAwaitableNode getAwaitable) { Object type = getAsyncIterType.execute(inliningTarget, receiver); - Object getter = getANext.execute(frame, type, receiver); - if (getter == PNone.NO_VALUE) { - errorProfile.enter(inliningTarget); - throw raiseNoANext.raise(PythonBuiltinClassType.TypeError, ASYNC_FOR_NO_ANEXT_ITERATION, receiver); + TpSlots slots = getSlots.execute(inliningTarget, type); + if (slots.am_anext() == null) { + throw raiseNoANext.raise(inliningTarget, PythonBuiltinClassType.TypeError, ASYNC_FOR_NO_ANEXT_ITERATION, receiver); } - Object anext = callANext.executeObject(frame, getter, receiver); + Object anext = callSlot.execute(frame, inliningTarget, slots.am_anext(), receiver); try { return getAwaitable.execute(frame, anext); } catch (PException e) { - errorProfile.enter(inliningTarget); - throw raiseInvalidObject.raiseWithCause(PythonBuiltinClassType.TypeError, e, ANEXT_INVALID_OBJECT, anext); + throw raiseInvalidObject.raiseWithCause(inliningTarget, PythonBuiltinClassType.TypeError, e, ANEXT_INVALID_OBJECT, anext); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetSendValueNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetSendValueNode.java index 45587123f8..a9149f87ef 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetSendValueNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetSendValueNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,6 +47,7 @@ import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; @GenerateUncached @@ -69,6 +70,7 @@ Object doSend(Object obj) { return obj; } + @NeverDefault public static GetSendValueNode create() { return GetSendValueNodeGen.create(); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetTPFlagsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetTPFlagsNode.java index 73f593079c..c958a54986 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetTPFlagsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetTPFlagsNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,6 +47,7 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; @@ -63,6 +64,7 @@ long get(Object object, return getTypeFlagsNode.execute(getClassNode.execute(inliningTarget, object)); } + @NeverDefault public static GetTPFlagsNode create() { return GetTPFlagsNodeGen.create(); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetYieldFromIterNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetYieldFromIterNode.java index 274e748b5a..c746d74f2e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetYieldFromIterNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/GetYieldFromIterNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,18 +44,20 @@ import com.oracle.graal.python.builtins.objects.generator.PGenerator; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectExactProfile; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @GenerateUncached @GenerateInline(false) // used in BCI root node +@OperationProxy.Proxyable public abstract class GetYieldFromIterNode extends Node { - public abstract Object execute(Frame frame, Object receiver); + public abstract Object execute(VirtualFrame frame, Object receiver); @Specialization public static Object getGeneratorOrCoroutine(PGenerator arg) { @@ -64,7 +66,7 @@ public static Object getGeneratorOrCoroutine(PGenerator arg) { } @Specialization - public static Object getGeneric(Frame frame, Object arg, + public static Object getGeneric(VirtualFrame frame, Object arg, @Bind("this") Node inliningTarget, @Cached PyObjectGetIter getIter, @Cached IsBuiltinObjectExactProfile isCoro) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportFromNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportFromNode.java index 98e70f902c..c064de5fbc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportFromNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportFromNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -62,6 +62,7 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; @@ -128,6 +129,7 @@ private Object tryResolveCircularImport(Object module, TruffleString name) { } } + @NeverDefault public static ImportFromNode create() { return ImportFromNodeGen.create(); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportNode.java index a55b537958..637f93662e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -63,6 +63,7 @@ Object doImport(VirtualFrame frame, TruffleString name, Object globals, @NeverDe return importModule(frame, name, globals, cachedFromList, level, importName); } + @NeverDefault public static ImportNode create() { return ImportNodeGen.create(); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportStarNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportStarNode.java index 5210ab2ea2..dc27691d43 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportStarNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportStarNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -35,7 +35,8 @@ import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.mappingproxy.PMappingproxy; import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyObjectGetIter; @@ -83,15 +84,14 @@ void doImport(VirtualFrame frame, TruffleString moduleName, int level, @Cached GetOrCreateDictNode getDictNode, @Cached PyObjectGetAttr getAttrNode, @Cached PyObjectGetIter getIterNode, - @Cached GetNextNode getNextNode, + @Cached PyIterNextNode nextNode, @Cached PyObjectSizeNode sizeNode, @Cached PyObjectGetItem getItemNode, @Cached InlinedConditionProfile javaImport, @Cached CastToTruffleStringNode castToTruffleStringNode, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, - @Cached IsBuiltinObjectProfile isAttributeErrorProfile, - @Cached IsBuiltinObjectProfile isStopIterationProfile) { + @Cached IsBuiltinObjectProfile isAttributeErrorProfile) { Object importedModule = importModule(frame, moduleName, PArguments.getGlobals(frame), T_IMPORT_ALL, level, importNameNode); Object locals = PArguments.getSpecialArgument(frame); if (locals == null) { @@ -128,14 +128,14 @@ void doImport(VirtualFrame frame, TruffleString moduleName, int level, assert importedModule instanceof PythonModule; Object keysIterator = getIterNode.execute(frame, inliningTarget, getDictNode.execute(inliningTarget, importedModule)); while (true) { + Object key; try { - Object key = getNextNode.execute(frame, keysIterator); - writeAttributeToLocals(frame, inliningTarget, moduleName, (PythonModule) importedModule, locals, key, false, castToTruffleStringNode, codePointLengthNode, - codePointAtIndexNode, getAttrNode, setItemNode, setAttrNode); - } catch (PException iterException) { - iterException.expectStopIteration(inliningTarget, isStopIterationProfile); + key = nextNode.execute(frame, inliningTarget, keysIterator); + } catch (IteratorExhausted e1) { break; } + writeAttributeToLocals(frame, inliningTarget, moduleName, (PythonModule) importedModule, locals, key, false, castToTruffleStringNode, codePointLengthNode, + codePointAtIndexNode, getAttrNode, setItemNode, setAttrNode); } } } @@ -164,8 +164,8 @@ private void writeAttributeToLocals(VirtualFrame frame, Node inliningTarget, Tru writeAttribute(frame, inliningTarget, locals, name, moduleAttr, dictWriteNode, setAttrNode); } } catch (CannotCastException cce) { - throw PRaiseNode.raiseUncached(this, TypeError, fromAll ? ErrorMessages.ITEM_IN_S_MUST_BE_STRING : ErrorMessages.KEY_IN_S_MUST_BE_STRING, - moduleName, fromAll ? T___ALL__ : T___DICT__, attrName); + TruffleString format = fromAll ? ErrorMessages.ITEM_IN_S_MUST_BE_STRING : ErrorMessages.KEY_IN_S_MUST_BE_STRING; + throw PRaiseNode.raiseStatic(this, TypeError, format, moduleName, fromAll ? T___ALL__ : T___DICT__, attrName); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/InNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/InNode.java new file mode 100644 index 0000000000..2d928803f2 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/InNode.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.nodes.bytecode; + +import com.oracle.graal.python.lib.PySequenceContainsNode; +import com.oracle.graal.python.nodes.expression.BinaryOpNode; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; + +@GenerateInline(false) +abstract class InNode extends BinaryOpNode { + + @Specialization + Object contains(VirtualFrame frame, Object item, Object container, + @Bind Node inliningTarget, + @Cached PySequenceContainsNode containsNode) { + return containsNode.execute(frame, inliningTarget, container, item); + } + + @NeverDefault + public static InNode create() { + return InNodeGen.create(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/KeywordsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/KeywordsNode.java index 5dd96fb4bf..480590e93a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/KeywordsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/KeywordsNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -66,15 +66,15 @@ static PKeyword[] kwords(VirtualFrame frame, Object sourceCollection, int stackT @Cached MappingToKeywordsNode expandKeywordStarargsNode, @Cached InlinedBranchProfile keywordsError1, @Cached InlinedBranchProfile keywordsError2, - @Cached PRaiseNode.Lazy raise) { + @Cached PRaiseNode raise) { try { return expandKeywordStarargsNode.execute(frame, inliningTarget, sourceCollection); } catch (SameDictKeyException e) { keywordsError1.enter(inliningTarget); - throw handleSameKey(frame, raise.get(inliningTarget), stackTop, e); + throw handleSameKey(frame, inliningTarget, raise, stackTop, e); } catch (NonMappingException e) { keywordsError2.enter(inliningTarget); - throw handleNonMapping(frame, raise.get(inliningTarget), stackTop, e); + throw handleNonMapping(frame, inliningTarget, raise, stackTop, e); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/KwargsMergeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/KwargsMergeNode.java index f0326ea589..b6165bc651 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/KwargsMergeNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/KwargsMergeNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -65,7 +65,7 @@ public abstract class KwargsMergeNode extends AbstractKwargsNode { static int merge(VirtualFrame frame, int initialStackTop, @Bind("this") Node inliningTarget, @Cached ConcatDictToStorageNode concatNode, - @Cached PRaiseNode.Lazy raise, + @Cached PRaiseNode raise, @Cached InlinedBranchProfile keywordsError1, @Cached InlinedBranchProfile keywordsError2) { int stackTop = initialStackTop; @@ -77,10 +77,10 @@ static int merge(VirtualFrame frame, int initialStackTop, dict.setDictStorage(resultStorage); } catch (SameDictKeyException e) { keywordsError1.enter(inliningTarget); - throw handleSameKey(frame, raise.get(inliningTarget), stackTop, e); + throw handleSameKey(frame, inliningTarget, raise, stackTop, e); } catch (NonMappingException e) { keywordsError2.enter(inliningTarget); - throw handleNonMapping(frame, raise.get(inliningTarget), stackTop, e); + throw handleNonMapping(frame, inliningTarget, raise, stackTop, e); } return stackTop; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MakeFunctionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MakeFunctionNode.java index b032f7da80..afa5ff1048 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MakeFunctionNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MakeFunctionNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -49,16 +49,17 @@ import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.function.Signature; import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.compiler.CodeUnit; +import com.oracle.graal.python.compiler.BytecodeCodeUnit; import com.oracle.graal.python.compiler.OpCodes; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.Assumption; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; @@ -66,16 +67,15 @@ public abstract class MakeFunctionNode extends PNodeWithContext { private final RootCallTarget callTarget; - private final CodeUnit code; + private final BytecodeCodeUnit code; private final Signature signature; @CompilationFinal private PCode cachedCode; - private final Assumption sharedCodeStableAssumption = Truffle.getRuntime().createAssumption("shared code stable assumption"); - private final Assumption sharedDefaultsStableAssumption = Truffle.getRuntime().createAssumption("shared defaults stable assumption"); + private final Assumption codeStableAssumption = Truffle.getRuntime().createAssumption("code stable assumption"); public abstract int execute(VirtualFrame frame, Object globals, int initialStackTop, int flags); - public MakeFunctionNode(RootCallTarget callTarget, CodeUnit code, Signature signature) { + public MakeFunctionNode(RootCallTarget callTarget, BytecodeCodeUnit code, Signature signature) { this.callTarget = callTarget; this.code = code; this.signature = signature; @@ -83,7 +83,7 @@ public MakeFunctionNode(RootCallTarget callTarget, CodeUnit code, Signature sign @Specialization int makeFunction(VirtualFrame frame, Object globals, int initialStackTop, int flags, - @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached WriteAttributeToPythonObjectNode writeAttrNode) { int stackTop = initialStackTop; @@ -95,10 +95,10 @@ int makeFunction(VirtualFrame frame, Object globals, int initialStackTop, int fl * We cannot initialize the cached code in create, because that may be called * without langauge context when materializing nodes for instrumentation */ - cachedCode = codeObj = factory.createCode(callTarget, signature, code); + cachedCode = codeObj = PFactory.createCode(language, callTarget, signature, code); } else { // In multi-context mode we have to create the code for every execution - codeObj = factory.createCode(callTarget, signature, code); + codeObj = PFactory.createCode(language, callTarget, signature, code); } } @@ -124,16 +124,7 @@ int makeFunction(VirtualFrame frame, Object globals, int initialStackTop, int fl frame.setObject(stackTop--, null); } - Assumption codeStableAssumption; - Assumption defaultsStableAssumption; - if (CompilerDirectives.inCompiledCode()) { - codeStableAssumption = sharedCodeStableAssumption; - defaultsStableAssumption = sharedDefaultsStableAssumption; - } else { - codeStableAssumption = Truffle.getRuntime().createAssumption(); - defaultsStableAssumption = Truffle.getRuntime().createAssumption(); - } - PFunction function = factory.createFunction(code.name, code.qualname, codeObj, (PythonObject) globals, defaults, kwdefaults, closure, codeStableAssumption, defaultsStableAssumption); + PFunction function = PFactory.createFunction(language, code.name, code.qualname, codeObj, (PythonObject) globals, defaults, kwdefaults, closure, codeStableAssumption); if (annotations != null) { writeAttrNode.execute(function, T___ANNOTATIONS__, annotations); @@ -143,7 +134,7 @@ int makeFunction(VirtualFrame frame, Object globals, int initialStackTop, int fl return stackTop; } - public static MakeFunctionNode create(PythonLanguage language, CodeUnit code, Source source) { + public static MakeFunctionNode create(PythonLanguage language, BytecodeCodeUnit code, Source source) { RootCallTarget callTarget; PBytecodeRootNode bytecodeRootNode = PBytecodeRootNode.create(language, code, source); if (code.isGeneratorOrCoroutine()) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MatchClassNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MatchClassNode.java index e943d7bf1e..bf3c37fd01 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MatchClassNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MatchClassNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,10 +44,12 @@ import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MATCH_ARGS; import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.modules.BuiltinFunctions; import com.oracle.graal.python.builtins.objects.str.StringBuiltins; import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins; import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.lib.PyObjectGetAttrO; import com.oracle.graal.python.lib.PyTupleCheckExactNode; import com.oracle.graal.python.lib.PyTupleSizeNode; @@ -57,7 +59,7 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -83,16 +85,16 @@ Object match(VirtualFrame frame, Object subject, Object type, int nargs, @NeverD @Cached PyObjectGetAttrO getAttr, @Cached TypeNodes.GetTypeFlagsNode getTypeFlagsNode, @Cached IsBuiltinObjectProfile isClassProfile, - @Cached StringBuiltins.EqNode eqStrNode, + @Cached StringBuiltins.StringRichCmpNode eqStrNode, @Cached PyTupleCheckExactNode tupleCheckExactNode, - @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached PyTupleSizeNode tupleSizeNode, @Cached TupleBuiltins.GetItemNode getItemNode, @Cached PyUnicodeCheckNode unicodeCheckNode, @Cached PRaiseNode raise) { if (!isTypeNode.execute(inliningTarget, type)) { - throw raise.raise(TypeError, ErrorMessages.CALLED_MATCH_PAT_MUST_BE_TYPE); + throw raise.raise(inliningTarget, TypeError, ErrorMessages.CALLED_MATCH_PAT_MUST_BE_TYPE); } if (!isInstanceNode.executeWith(frame, subject, type)) { @@ -110,7 +112,7 @@ Object match(VirtualFrame frame, Object subject, Object type, int nargs, @NeverD try { matchArgs = getAttr.execute(frame, inliningTarget, type, T___MATCH_ARGS); if (!tupleCheckExactNode.execute(inliningTarget, matchArgs)) { - throw raise.raise(TypeError, ErrorMessages.P_MATCH_ARGS_MUST_BE_A_TUPLE_GOT_P, type, matchArgs); + throw raise.raise(inliningTarget, TypeError, ErrorMessages.P_MATCH_ARGS_MUST_BE_A_TUPLE_GOT_P, type, matchArgs); } } catch (PException e) { // _Py_TPFLAGS_MATCH_SELF is only acknowledged if the type does not @@ -118,12 +120,12 @@ Object match(VirtualFrame frame, Object subject, Object type, int nargs, @NeverD // it's as if __match_args__ is some "magic" value that is lost as // soon as they redefine it. e.expectAttributeError(inliningTarget, isClassProfile); - matchArgs = factory.createEmptyTuple(); + matchArgs = PFactory.createEmptyTuple(language); matchSelf = (getTypeFlagsNode.execute(type) & MATCH_SELF) != 0; } int allowed = matchSelf ? 1 : tupleSizeNode.execute(inliningTarget, matchArgs); if (allowed < nargs) { - throw raise.raise(TypeError, ErrorMessages.P_ACCEPTS_D_POS_SUBARG_S_D_GIVEN, type, allowed, (allowed == 1) ? "" : "s", nargs); + throw raise.raise(inliningTarget, TypeError, ErrorMessages.P_ACCEPTS_D_POS_SUBARG_S_D_GIVEN, type, allowed, (allowed == 1) ? "" : "s", nargs); } if (matchSelf) { // Easy. Copy the subject itself, and move on to kwargs. @@ -138,20 +140,20 @@ Object match(VirtualFrame frame, Object subject, Object type, int nargs, @NeverD } // Finally, the keyword subpatterns: getKwArgs(frame, inliningTarget, subject, type, kwArgs, seen, seenLength, attrs, attrsLength, getAttr, eqStrNode, raise); - return factory.createList(attrs); + return PFactory.createList(language, attrs); } @ExplodeLoop private static void getArgs(VirtualFrame frame, Node inliningTarget, Object subject, Object type, int nargs, Object[] seen, int[] seenLength, Object[] attrs, int[] attrsLength, Object matchArgs, PyObjectGetAttrO getAttr, - StringBuiltins.EqNode eqStrNode, TupleBuiltins.GetItemNode getItemNode, PyUnicodeCheckNode unicodeCheckNode, PRaiseNode raise) { + StringBuiltins.StringRichCmpNode eqStrNode, TupleBuiltins.GetItemNode getItemNode, PyUnicodeCheckNode unicodeCheckNode, PRaiseNode raise) { CompilerAsserts.partialEvaluationConstant(nargs); for (int i = 0; i < nargs; i++) { Object name = getItemNode.execute(frame, matchArgs, i); if (!unicodeCheckNode.execute(inliningTarget, name)) { - throw raise.raise(TypeError, ErrorMessages.MATCH_ARGS_ELEMENTS_MUST_BE_STRINGS_GOT_P, name); + throw raise.raise(inliningTarget, TypeError, ErrorMessages.MATCH_ARGS_ELEMENTS_MUST_BE_STRINGS_GOT_P, name); } - setName(frame, type, name, seen, seenLength, eqStrNode, raise); + setName(frame, inliningTarget, type, name, seen, seenLength, eqStrNode, raise); attrs[attrsLength[0]++] = getAttr.execute(frame, inliningTarget, subject, name); } } @@ -159,27 +161,27 @@ private static void getArgs(VirtualFrame frame, Node inliningTarget, Object subj @ExplodeLoop private static void getKwArgs(VirtualFrame frame, Node inliningTarget, Object subject, Object type, TruffleString[] kwArgs, Object[] seen, int[] seenLength, Object[] attrs, int[] attrsLength, PyObjectGetAttrO getAttr, - StringBuiltins.EqNode eqStrNode, PRaiseNode raise) { + StringBuiltins.StringRichCmpNode eqStrNode, PRaiseNode raise) { CompilerAsserts.partialEvaluationConstant(kwArgs); for (int i = 0; i < kwArgs.length; i++) { TruffleString name = kwArgs[i]; CompilerAsserts.partialEvaluationConstant(name); - setName(frame, type, name, seen, seenLength, eqStrNode, raise); + setName(frame, inliningTarget, type, name, seen, seenLength, eqStrNode, raise); attrs[attrsLength[0]++] = getAttr.execute(frame, inliningTarget, subject, name); } } - private static void setName(VirtualFrame frame, Object type, Object name, Object[] seen, int[] seenLength, StringBuiltins.EqNode eqNode, PRaiseNode raise) { + private static void setName(VirtualFrame frame, Node inliningTarget, Object type, Object name, Object[] seen, int[] seenLength, StringBuiltins.StringRichCmpNode eqNode, PRaiseNode raise) { if (seenLength[0] > 0 && contains(frame, seen, name, eqNode)) { - throw raise.raise(TypeError, ErrorMessages.S_GOT_MULTIPLE_SUBPATTERNS_FOR_ATTR_S, type, name); + throw raise.raise(inliningTarget, TypeError, ErrorMessages.S_GOT_MULTIPLE_SUBPATTERNS_FOR_ATTR_S, type, name); } seen[seenLength[0]++] = name; } @ExplodeLoop - private static boolean contains(VirtualFrame frame, Object[] seen, Object name, StringBuiltins.EqNode eqNode) { + private static boolean contains(VirtualFrame frame, Object[] seen, Object name, StringBuiltins.StringRichCmpNode eqNode) { for (int i = 0; i < seen.length; i++) { - if (seen[i] != null && (boolean) eqNode.execute(frame, seen[i], name)) { + if (seen[i] != null && (boolean) eqNode.execute(frame, seen[i], name, RichCmpOp.Py_EQ)) { return true; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MatchKeysNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MatchKeysNode.java index 78329dbc91..a1119fee86 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MatchKeysNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/MatchKeysNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,13 +43,14 @@ import static com.oracle.graal.python.nodes.SpecialMethodNames.T_GET; import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.lib.PyObjectRichCompareBool; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.dsl.Bind; @@ -71,17 +72,16 @@ public abstract class MatchKeysNode extends PNodeWithContext { static Object matchCached(VirtualFrame frame, Object map, @NeverDefault Object[] keys, @Bind("this") Node inliningTarget, @Cached("keys.length") int keysLen, - @Shared @Cached PyObjectRichCompareBool.EqNode compareNode, + @Shared @Cached PyObjectRichCompareBool compareNode, @Shared @Cached PyObjectCallMethodObjArgs callMethod, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raise) { + @Shared @Cached PRaiseNode raise) { Object[] values = getValues(frame, inliningTarget, map, keys, keysLen, compareNode, callMethod, raise); - return values != null ? factory.createTuple(values) : PNone.NONE; + return values != null ? PFactory.createTuple(PythonLanguage.get(inliningTarget), values) : PNone.NONE; } @ExplodeLoop - private static Object[] getValues(VirtualFrame frame, Node inliningTarget, Object map, Object[] keys, int keysLen, PyObjectRichCompareBool.EqNode compareNode, PyObjectCallMethodObjArgs callMethod, - PRaiseNode.Lazy raise) { + private static Object[] getValues(VirtualFrame frame, Node inliningTarget, Object map, Object[] keys, int keysLen, PyObjectRichCompareBool compareNode, PyObjectCallMethodObjArgs callMethod, + PRaiseNode raise) { CompilerAsserts.partialEvaluationConstant(keysLen); Object[] values = new Object[keysLen]; Object dummy = new Object(); @@ -100,10 +100,10 @@ private static Object[] getValues(VirtualFrame frame, Node inliningTarget, Objec } @ExplodeLoop - private static void checkSeen(VirtualFrame frame, Node inliningTarget, PRaiseNode.Lazy raise, Object[] seen, Object key, PyObjectRichCompareBool.EqNode compareNode) { + private static void checkSeen(VirtualFrame frame, Node inliningTarget, PRaiseNode raise, Object[] seen, Object key, PyObjectRichCompareBool compareNode) { for (int i = 0; i < seen.length; i++) { - if (seen[i] != null && compareNode.compare(frame, inliningTarget, seen[i], key)) { - raise.get(inliningTarget).raise(ValueError, ErrorMessages.MAPPING_PATTERN_CHECKS_DUPE_KEY_S, key); + if (seen[i] != null && compareNode.executeEq(frame, inliningTarget, seen[i], key)) { + raise.raise(inliningTarget, ValueError, ErrorMessages.MAPPING_PATTERN_CHECKS_DUPE_KEY_S, key); } } } @@ -111,19 +111,18 @@ private static void checkSeen(VirtualFrame frame, Node inliningTarget, PRaiseNod @Specialization(guards = "keys.length > 0", replaces = "matchCached") static Object match(VirtualFrame frame, Object map, Object[] keys, @Bind("this") Node inliningTarget, - @Shared @Cached PyObjectRichCompareBool.EqNode compareNode, + @Shared @Cached PyObjectRichCompareBool compareNode, @Shared @Cached PyObjectCallMethodObjArgs callMethod, - @Shared @Cached PythonObjectFactory factory, - @Shared @Cached PRaiseNode.Lazy raise) { + @Shared @Cached PRaiseNode raise) { if (keys.length == 0) { - return factory.createTuple(PythonUtils.EMPTY_OBJECT_ARRAY); + return PFactory.createTuple(PythonLanguage.get(inliningTarget), PythonUtils.EMPTY_OBJECT_ARRAY); } Object[] values = getValuesLongArray(frame, inliningTarget, map, keys, compareNode, callMethod, raise); - return values != null ? factory.createTuple(values) : PNone.NONE; + return values != null ? PFactory.createTuple(PythonLanguage.get(inliningTarget), values) : PNone.NONE; } - private static Object[] getValuesLongArray(VirtualFrame frame, Node inliningTarget, Object map, Object[] keys, PyObjectRichCompareBool.EqNode compareNode, PyObjectCallMethodObjArgs callMethod, - PRaiseNode.Lazy raise) { + private static Object[] getValuesLongArray(VirtualFrame frame, Node inliningTarget, Object map, Object[] keys, PyObjectRichCompareBool compareNode, PyObjectCallMethodObjArgs callMethod, + PRaiseNode raise) { Object[] values = new Object[keys.length]; Object dummy = new Object(); Object[] seen = new Object[keys.length]; @@ -140,18 +139,18 @@ private static Object[] getValuesLongArray(VirtualFrame frame, Node inliningTarg return values; } - private static void checkSeenLongArray(VirtualFrame frame, Node inliningTarget, PRaiseNode.Lazy raise, Object[] seen, Object key, PyObjectRichCompareBool.EqNode compareNode) { + private static void checkSeenLongArray(VirtualFrame frame, Node inliningTarget, PRaiseNode raise, Object[] seen, Object key, PyObjectRichCompareBool compareNode) { for (int i = 0; i < seen.length; i++) { - if (seen[i] != null && compareNode.compare(frame, inliningTarget, seen[i], key)) { - raise.get(inliningTarget).raise(ValueError, ErrorMessages.MAPPING_PATTERN_CHECKS_DUPE_KEY_S, key); + if (seen[i] != null && compareNode.executeEq(frame, inliningTarget, seen[i], key)) { + raise.raise(inliningTarget, ValueError, ErrorMessages.MAPPING_PATTERN_CHECKS_DUPE_KEY_S, key); } } } @Specialization(guards = "keys.length == 0") static Object matchNoKeys(@SuppressWarnings("unused") Object map, @SuppressWarnings("unused") Object[] keys, - @Shared @Cached PythonObjectFactory factory) { - return factory.createTuple(PythonUtils.EMPTY_OBJECT_ARRAY); + @Bind PythonLanguage language) { + return PFactory.createTuple(language, PythonUtils.EMPTY_OBJECT_ARRAY); } public static MatchKeysNode create() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/NotNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/NotNode.java new file mode 100644 index 0000000000..83a68bac42 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/NotNode.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.nodes.bytecode; + +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageLen; +import com.oracle.graal.python.builtins.objects.dict.PDict; +import com.oracle.graal.python.builtins.objects.list.PList; +import com.oracle.graal.python.builtins.objects.set.PBaseSet; +import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.lib.PyObjectIsTrueNode; +import com.oracle.graal.python.lib.PyObjectIsTrueNode.PyObjectIsTrueNodeGeneric; +import com.oracle.graal.python.nodes.expression.UnaryOpNode; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Cached.Exclusive; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.strings.TruffleString; + +/** + * Equivalent of a negation of CPython's {@code PyObject_IsTrue}. This class exists only so that we + * can have quickening fast-paths for this operation. The fast-paths should be synchronized with + * {@link PyObjectIsTrueNode}. + */ +@GenerateInline(false) +@OperationProxy.Proxyable +public abstract class NotNode extends UnaryOpNode { + + @Specialization + public static boolean doBoolean(boolean object) { + return !object; + } + + @Specialization + public static boolean doNone(@SuppressWarnings("unused") PNone object) { + return true; + } + + @Specialization + public static boolean doInt(int object) { + return object == 0; + } + + @Specialization + public static boolean doLong(long object) { + return object == 0; + } + + @Specialization + public static boolean doDouble(double object) { + return object == 0.0; + } + + @Specialization + public static boolean doString(TruffleString object) { + return object.isEmpty(); + } + + @Specialization(guards = "isBuiltinList(object)") + public static boolean doList(PList object) { + return object.getSequenceStorage().length() == 0; + } + + @Specialization(guards = "isBuiltinTuple(object)") + public static boolean doTuple(PTuple object) { + return object.getSequenceStorage().length() == 0; + } + + @Specialization(guards = "isBuiltinDict(object)") + public static boolean doDict(PDict object, + @Bind Node inliningTarget, + @Exclusive @Cached HashingStorageLen lenNode) { + return lenNode.execute(inliningTarget, object.getDictStorage()) == 0; + } + + @Specialization(guards = "isBuiltinAnySet(object)") + @InliningCutoff + public static boolean doSet(PBaseSet object, + @Bind Node inliningTarget, + @Exclusive @Cached HashingStorageLen lenNode) { + return lenNode.execute(inliningTarget, object.getDictStorage()) == 0; + } + + @Specialization(guards = {"!isBoolean(object)", "!isPNone(object)", "!isInt(object)", "!isLong(object)", "!isDouble(object)", "!isTruffleString(object)"}, // + replaces = {"doList", "doTuple", "doDict", "doSet"}) + @InliningCutoff + public static boolean doOthers(VirtualFrame frame, Object object, + @Cached(inline = false) PyObjectIsTrueNodeGeneric internalNode) { + return !internalNode.execute(frame, object); + } + + @NeverDefault + public static NotNode create() { + return NotNodeGen.create(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeGeneratorFunctionRootNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeGeneratorFunctionRootNode.java index d3d8e9abe7..01dec11746 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeGeneratorFunctionRootNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeGeneratorFunctionRootNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,7 +45,7 @@ import com.oracle.graal.python.builtins.objects.function.PFunction; import com.oracle.graal.python.builtins.objects.function.Signature; import com.oracle.graal.python.nodes.PRootNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; @@ -63,7 +63,6 @@ public class PBytecodeGeneratorFunctionRootNode extends PRootNode { @CompilationFinal(dimensions = 1) private final RootCallTarget[] callTargets; - @Child private PythonObjectFactory factory = PythonObjectFactory.create(); private final ConditionProfile isIterableCoroutine = ConditionProfile.create(); @TruffleBoundary @@ -80,7 +79,8 @@ public PBytecodeGeneratorFunctionRootNode(PythonLanguage language, FrameDescript public Object execute(VirtualFrame frame) { Object[] arguments = frame.getArguments(); - // This is passed from InvokeNode node + PythonLanguage language = PythonLanguage.get(this); + // This is passed from the dispatch node PFunction generatorFunction = PArguments.getGeneratorFunction(arguments); assert generatorFunction != null; if (rootNode.getCodeUnit().isGenerator()) { @@ -88,14 +88,14 @@ public Object execute(VirtualFrame frame) { // pass the information to the generator // .gi_code.co_flags will still be wrong, but at least await will work correctly if (isIterableCoroutine.profile((generatorFunction.getCode().getFlags() & 0x100) != 0)) { - return factory.createIterableCoroutine(generatorFunction.getName(), generatorFunction.getQualname(), rootNode, callTargets, arguments); + return PFactory.createIterableCoroutine(language, generatorFunction.getName(), generatorFunction.getQualname(), rootNode, callTargets, arguments); } else { - return factory.createGenerator(generatorFunction.getName(), generatorFunction.getQualname(), rootNode, callTargets, arguments); + return PFactory.createGenerator(language, generatorFunction.getName(), generatorFunction.getQualname(), rootNode, callTargets, arguments); } } else if (rootNode.getCodeUnit().isCoroutine()) { - return factory.createCoroutine(generatorFunction.getName(), generatorFunction.getQualname(), rootNode, callTargets, arguments); + return PFactory.createCoroutine(language, generatorFunction.getName(), generatorFunction.getQualname(), rootNode, callTargets, arguments); } else if (rootNode.getCodeUnit().isAsyncGenerator()) { - return factory.createAsyncGenerator(generatorFunction.getName(), generatorFunction.getQualname(), rootNode, callTargets, arguments); + return PFactory.createAsyncGenerator(language, generatorFunction.getName(), generatorFunction.getQualname(), rootNode, callTargets, arguments); } throw CompilerDirectives.shouldNotReachHere("Unknown generator/coroutine type"); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java index ec48641f73..2ef13f97bc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java @@ -52,7 +52,6 @@ import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; import java.math.BigInteger; -import java.util.Arrays; import java.util.Collections; import java.util.Set; import java.util.concurrent.locks.Lock; @@ -66,11 +65,13 @@ import com.oracle.graal.python.builtins.objects.asyncio.GetAwaitableNode; import com.oracle.graal.python.builtins.objects.asyncio.GetAwaitableNodeGen; import com.oracle.graal.python.builtins.objects.cell.PCell; +import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes; import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes.SetItemNode; import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodesFactory; import com.oracle.graal.python.builtins.objects.common.HashingStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageFactory; +import com.oracle.graal.python.builtins.objects.common.ObjectHashMap; import com.oracle.graal.python.builtins.objects.dict.DictNodes; import com.oracle.graal.python.builtins.objects.dict.DictNodesFactory; import com.oracle.graal.python.builtins.objects.dict.PDict; @@ -101,7 +102,7 @@ import com.oracle.graal.python.builtins.objects.slice.SliceNodes.CreateSliceNode; import com.oracle.graal.python.builtins.objects.slice.SliceNodesFactory.CreateSliceNodeGen; import com.oracle.graal.python.compiler.BinaryOpsConstants; -import com.oracle.graal.python.compiler.CodeUnit; +import com.oracle.graal.python.compiler.BytecodeCodeUnit; import com.oracle.graal.python.compiler.FormatOptions; import com.oracle.graal.python.compiler.OpCodes; import com.oracle.graal.python.compiler.OpCodes.CollectionBits; @@ -109,9 +110,35 @@ import com.oracle.graal.python.compiler.QuickeningTypes; import com.oracle.graal.python.compiler.RaisePythonExceptionErrorCallback; import com.oracle.graal.python.compiler.UnaryOpsConstants; +import com.oracle.graal.python.lib.PyNumberAddNode; +import com.oracle.graal.python.lib.PyNumberAndNode; +import com.oracle.graal.python.lib.PyNumberFloorDivideNode; +import com.oracle.graal.python.lib.PyNumberInPlaceAddNode; +import com.oracle.graal.python.lib.PyNumberInPlaceAndNode; +import com.oracle.graal.python.lib.PyNumberInPlaceFloorDivideNode; +import com.oracle.graal.python.lib.PyNumberInPlaceLshiftNode; +import com.oracle.graal.python.lib.PyNumberInPlaceMatrixMultiplyNode; +import com.oracle.graal.python.lib.PyNumberInPlaceMultiplyNode; +import com.oracle.graal.python.lib.PyNumberInPlaceOrNode; +import com.oracle.graal.python.lib.PyNumberInPlacePowerNode; +import com.oracle.graal.python.lib.PyNumberInPlaceRemainderNode; +import com.oracle.graal.python.lib.PyNumberInPlaceRshiftNode; +import com.oracle.graal.python.lib.PyNumberInPlaceSubtractNode; +import com.oracle.graal.python.lib.PyNumberInPlaceTrueDivideNode; +import com.oracle.graal.python.lib.PyNumberInPlaceXorNode; import com.oracle.graal.python.lib.PyNumberInvertNode; +import com.oracle.graal.python.lib.PyNumberLshiftNode; +import com.oracle.graal.python.lib.PyNumberMatrixMultiplyNode; +import com.oracle.graal.python.lib.PyNumberMultiplyNode; import com.oracle.graal.python.lib.PyNumberNegativeNode; +import com.oracle.graal.python.lib.PyNumberOrNode; import com.oracle.graal.python.lib.PyNumberPositiveNode; +import com.oracle.graal.python.lib.PyNumberPowerNode; +import com.oracle.graal.python.lib.PyNumberRemainderNode; +import com.oracle.graal.python.lib.PyNumberRshiftNode; +import com.oracle.graal.python.lib.PyNumberSubtractNode; +import com.oracle.graal.python.lib.PyNumberTrueDivideNode; +import com.oracle.graal.python.lib.PyNumberXorNode; import com.oracle.graal.python.lib.PyObjectAsciiNode; import com.oracle.graal.python.lib.PyObjectAsciiNodeGen; import com.oracle.graal.python.lib.PyObjectDelItem; @@ -124,11 +151,12 @@ import com.oracle.graal.python.lib.PyObjectGetIterNodeGen; import com.oracle.graal.python.lib.PyObjectGetMethod; import com.oracle.graal.python.lib.PyObjectGetMethodNodeGen; -import com.oracle.graal.python.lib.PyObjectIsNotTrueNode; +import com.oracle.graal.python.lib.PyObjectHashNode; import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.lib.PyObjectIsTrueNodeGen; import com.oracle.graal.python.lib.PyObjectReprAsObjectNode; import com.oracle.graal.python.lib.PyObjectReprAsObjectNodeGen; +import com.oracle.graal.python.lib.PyObjectRichCompare.RichCompareBinaryOp; import com.oracle.graal.python.lib.PyObjectSetAttr; import com.oracle.graal.python.lib.PyObjectSetAttrNodeGen; import com.oracle.graal.python.lib.PyObjectSetItem; @@ -137,9 +165,9 @@ import com.oracle.graal.python.lib.PyObjectSizeNodeGen; import com.oracle.graal.python.lib.PyObjectStrAsObjectNode; import com.oracle.graal.python.lib.PyObjectStrAsObjectNodeGen; +import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.PRaiseNodeGen; import com.oracle.graal.python.nodes.PRootNode; import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode; import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNodeGen; @@ -147,6 +175,7 @@ import com.oracle.graal.python.nodes.builtins.ListNodesFactory; import com.oracle.graal.python.nodes.builtins.TupleNodes; import com.oracle.graal.python.nodes.builtins.TupleNodesFactory; +import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNodeFactory.ObjHashMapPutNodeGen; import com.oracle.graal.python.nodes.bytecode.SequenceFromStackNode.ListFromStackNode; import com.oracle.graal.python.nodes.bytecode.SequenceFromStackNode.TupleFromStackNode; import com.oracle.graal.python.nodes.bytecode.SequenceFromStackNodeFactory.ListFromStackNodeGen; @@ -156,8 +185,6 @@ import com.oracle.graal.python.nodes.call.BoundDescriptor; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.call.CallNodeGen; -import com.oracle.graal.python.nodes.call.CallTargetInvokeNode; -import com.oracle.graal.python.nodes.call.CallTargetInvokeNodeGen; import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode; import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNodeGen; import com.oracle.graal.python.nodes.call.special.CallQuaternaryMethodNode; @@ -168,11 +195,7 @@ import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNodeGen; import com.oracle.graal.python.nodes.exception.ExceptMatchNode; import com.oracle.graal.python.nodes.exception.ExceptMatchNodeGen; -import com.oracle.graal.python.nodes.expression.BinaryArithmetic; -import com.oracle.graal.python.nodes.expression.BinaryComparisonNode; import com.oracle.graal.python.nodes.expression.BinaryOp; -import com.oracle.graal.python.nodes.expression.ContainsNode; -import com.oracle.graal.python.nodes.expression.InplaceArithmetic; import com.oracle.graal.python.nodes.expression.UnaryOpNode; import com.oracle.graal.python.nodes.frame.DeleteGlobalNode; import com.oracle.graal.python.nodes.frame.DeleteGlobalNodeGen; @@ -200,7 +223,7 @@ import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonExitException; import com.oracle.graal.python.runtime.exception.PythonThreadKillException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.graal.python.runtime.sequence.storage.BoolSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.DoubleSequenceStorage; @@ -218,6 +241,11 @@ import com.oracle.truffle.api.HostCompilerDirectives.BytecodeInterpreterSwitch; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameDescriptor; @@ -252,6 +280,8 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod private static final NodeSupplier NODE_SET_ITEM = HashingCollectionNodes.SetItemNode::create; private static final SetItemNode UNCACHED_SET_ITEM = HashingCollectionNodes.SetItemNode.getUncached(); + private static final NodeSupplier NODE_OBJ_HASHMAP_PUT = ObjHashMapPutNodeGen::create; + private static final ObjHashMapPutNode UNCACHED_OBJ_HASHMAP_PUT = ObjHashMapPutNodeGen.getUncached(); private static final NodeSupplier NODE_CAST_TO_JAVA_INT_EXACT = CastToJavaIntExactNode::create; private static final CastToJavaIntExactNode UNCACHED_CAST_TO_JAVA_INT_EXACT = CastToJavaIntExactNode.getUncached(); private static final ImportNode UNCACHED_IMPORT = ImportNode.getUncached(); @@ -262,8 +292,8 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod private static final NodeSupplier NODE_IMPORT_STAR = ImportStarNode::create; private static final NodeSupplier NODE_OBJECT_GET_ATTR = PyObjectGetAttr::create; private static final PyObjectGetAttr UNCACHED_OBJECT_GET_ATTR = PyObjectGetAttr.getUncached(); - private static final NodeSupplier NODE_RAISE = PRaiseNode::create; - private static final PRaiseNode UNCACHED_RAISE = PRaiseNode.getUncached(); + private static final NodeSupplier NODE_RAISE = PRaiseCachedNode::create; + private static final PRaiseCachedNode UNCACHED_RAISE = PRaiseCachedNode.getUncached(); private static final NodeSupplier NODE_CALL = CallNode::create; private static final CallNode UNCACHED_CALL = CallNode.getUncached(); private static final NodeSupplier NODE_CALL_QUATERNARY_METHOD = CallQuaternaryMethodNode::create; @@ -379,6 +409,7 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod private static final NodeSupplier NODE_STORE_SUBSCR_SEQ_O = StoreSubscrSeq.ONode::create; private static final NodeSupplier NODE_STORE_SUBSCR_SEQ_I = StoreSubscrSeq.INode::create; private static final NodeSupplier NODE_STORE_SUBSCR_SEQ_D = StoreSubscrSeq.DNode::create; + private static final NodeSupplier NODE_CALL_COMPREHENSION = CallComprehensionNode::create; private static final NodeSupplier NODE_INT_ADD = IntBuiltins.AddNode::create; private static final NodeSupplier NODE_INT_SUB = IntBuiltins.SubNode::create; @@ -399,7 +430,7 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod private static final IntNodeFunction UNARY_OP_FACTORY = (int op) -> { switch (op) { case UnaryOpsConstants.NOT: - return PyObjectIsNotTrueNode.create(); + return NotNode.create(); case UnaryOpsConstants.POSITIVE: return PyNumberPositiveNode.create(); case UnaryOpsConstants.NEGATIVE: @@ -414,73 +445,73 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod private static final IntNodeFunction BINARY_OP_FACTORY = (int op) -> { switch (op) { case BinaryOpsConstants.ADD: - return BinaryArithmetic.Add.create(); + return PyNumberAddNode.create(); case BinaryOpsConstants.SUB: - return BinaryArithmetic.Sub.create(); + return PyNumberSubtractNode.create(); case BinaryOpsConstants.MUL: - return BinaryArithmetic.Mul.create(); + return PyNumberMultiplyNode.create(); case BinaryOpsConstants.TRUEDIV: - return BinaryArithmetic.TrueDiv.create(); + return PyNumberTrueDivideNode.create(); case BinaryOpsConstants.FLOORDIV: - return BinaryArithmetic.FloorDiv.create(); + return PyNumberFloorDivideNode.create(); case BinaryOpsConstants.MOD: - return BinaryArithmetic.Mod.create(); + return PyNumberRemainderNode.create(); case BinaryOpsConstants.LSHIFT: - return BinaryArithmetic.LShift.create(); + return PyNumberLshiftNode.create(); case BinaryOpsConstants.RSHIFT: - return BinaryArithmetic.RShift.create(); + return PyNumberRshiftNode.create(); case BinaryOpsConstants.AND: - return BinaryArithmetic.And.create(); + return PyNumberAndNode.create(); case BinaryOpsConstants.OR: - return BinaryArithmetic.Or.create(); + return PyNumberOrNode.create(); case BinaryOpsConstants.XOR: - return BinaryArithmetic.Xor.create(); + return PyNumberXorNode.create(); case BinaryOpsConstants.POW: - return BinaryArithmetic.Pow.create(); + return PyNumberPowerNode.create(); case BinaryOpsConstants.MATMUL: - return BinaryArithmetic.MatMul.create(); + return PyNumberMatrixMultiplyNode.create(); case BinaryOpsConstants.INPLACE_ADD: - return InplaceArithmetic.IAdd.create(); + return PyNumberInPlaceAddNode.create(); case BinaryOpsConstants.INPLACE_SUB: - return InplaceArithmetic.ISub.create(); + return PyNumberInPlaceSubtractNode.create(); case BinaryOpsConstants.INPLACE_MUL: - return InplaceArithmetic.IMul.create(); + return PyNumberInPlaceMultiplyNode.create(); case BinaryOpsConstants.INPLACE_TRUEDIV: - return InplaceArithmetic.ITrueDiv.create(); + return PyNumberInPlaceTrueDivideNode.create(); case BinaryOpsConstants.INPLACE_FLOORDIV: - return InplaceArithmetic.IFloorDiv.create(); + return PyNumberInPlaceFloorDivideNode.create(); case BinaryOpsConstants.INPLACE_MOD: - return InplaceArithmetic.IMod.create(); + return PyNumberInPlaceRemainderNode.create(); case BinaryOpsConstants.INPLACE_LSHIFT: - return InplaceArithmetic.ILShift.create(); + return PyNumberInPlaceLshiftNode.create(); case BinaryOpsConstants.INPLACE_RSHIFT: - return InplaceArithmetic.IRShift.create(); + return PyNumberInPlaceRshiftNode.create(); case BinaryOpsConstants.INPLACE_AND: - return InplaceArithmetic.IAnd.create(); + return PyNumberInPlaceAndNode.create(); case BinaryOpsConstants.INPLACE_OR: - return InplaceArithmetic.IOr.create(); + return PyNumberInPlaceOrNode.create(); case BinaryOpsConstants.INPLACE_XOR: - return InplaceArithmetic.IXor.create(); + return PyNumberInPlaceXorNode.create(); case BinaryOpsConstants.INPLACE_POW: - return InplaceArithmetic.IPow.create(); + return PyNumberInPlacePowerNode.create(); case BinaryOpsConstants.INPLACE_MATMUL: - return InplaceArithmetic.IMatMul.create(); + return PyNumberInPlaceMatrixMultiplyNode.create(); case BinaryOpsConstants.EQ: - return BinaryComparisonNode.EqNode.create(); + return RichCompareBinaryOp.create(RichCmpOp.Py_EQ); case BinaryOpsConstants.NE: - return BinaryComparisonNode.NeNode.create(); + return RichCompareBinaryOp.create(RichCmpOp.Py_NE); case BinaryOpsConstants.LT: - return BinaryComparisonNode.LtNode.create(); + return RichCompareBinaryOp.create(RichCmpOp.Py_LT); case BinaryOpsConstants.LE: - return BinaryComparisonNode.LeNode.create(); + return RichCompareBinaryOp.create(RichCmpOp.Py_LE); case BinaryOpsConstants.GT: - return BinaryComparisonNode.GtNode.create(); + return RichCompareBinaryOp.create(RichCmpOp.Py_GT); case BinaryOpsConstants.GE: - return BinaryComparisonNode.GeNode.create(); + return RichCompareBinaryOp.create(RichCmpOp.Py_GE); case BinaryOpsConstants.IS: return IsNode.create(); case BinaryOpsConstants.IN: - return ContainsNode.create(); + return InNode.create(); default: throw CompilerDirectives.shouldNotReachHere(); } @@ -502,7 +533,7 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod final int selfIndex; final int classcellIndex; - private final CodeUnit co; + private final BytecodeCodeUnit co; private final Source source; private SourceSection sourceSection; // For deferred deprecation warnings @@ -516,7 +547,7 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod @CompilationFinal(dimensions = 1) private final TruffleString[] freevars; @CompilationFinal(dimensions = 1) private final TruffleString[] cellvars; @CompilationFinal(dimensions = 1) private final int[] cell2arg; - @CompilationFinal(dimensions = 1) protected final Assumption[] cellEffectivelyFinalAssumptions; + @CompilationFinal(dimensions = 1) private final Assumption[] cellEffectivelyFinalAssumptions; @CompilationFinal(dimensions = 1) private final int[] exceptionHandlerRanges; @@ -559,10 +590,9 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod * When instrumentation is in use, InstrumentationSupport#bciToHelper node is used instead of * this array. Use getChildNodes() to get the right array. */ - @Children private final Node[] adoptedNodes; + @Children private Node[] adoptedNodes; @Child private CalleeContext calleeContext = CalleeContext.create(); // TODO: make some of those lazy? - @Child private PythonObjectFactory factory = PythonObjectFactory.create(); @Child private ExceptionStateNodes.GetCaughtExceptionNode getCaughtExceptionNode; @Child private MaterializeFrameNode traceMaterializeFrameNode = null; @Child private ChainExceptionsNode chainExceptionsNode; @@ -574,7 +604,7 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod @Child private InstrumentationRoot instrumentationRoot = InstrumentationRoot.create(); - private static FrameDescriptor makeFrameDescriptor(CodeUnit co, FrameInfo info) { + private static FrameDescriptor makeFrameDescriptor(BytecodeCodeUnit co, FrameInfo info) { int capacity = co.varnames.length + co.cellvars.length + co.freevars.length + co.stacksize + 1; FrameDescriptor.Builder newBuilder = FrameDescriptor.newBuilder(capacity); newBuilder.info(info); @@ -612,40 +642,27 @@ private static FrameDescriptor makeFrameDescriptor(CodeUnit co, FrameInfo info) return newBuilder.build(); } - private static Signature makeSignature(CodeUnit co) { - int posArgCount = co.argCount + co.positionalOnlyArgCount; - TruffleString[] parameterNames = Arrays.copyOf(co.varnames, posArgCount); - TruffleString[] kwOnlyNames = Arrays.copyOfRange(co.varnames, posArgCount, posArgCount + co.kwOnlyArgCount); - int varArgsIndex = co.takesVarArgs() ? posArgCount : -1; - return new Signature(co.positionalOnlyArgCount, - co.takesVarKeywordArgs(), - varArgsIndex, - co.positionalOnlyArgCount > 0, - parameterNames, - kwOnlyNames); - } - @TruffleBoundary - public static PBytecodeRootNode create(PythonLanguage language, CodeUnit co, Source source) { + public static PBytecodeRootNode create(PythonLanguage language, BytecodeCodeUnit co, Source source) { return create(language, co, source, null); } @TruffleBoundary - public static PBytecodeRootNode create(PythonLanguage language, CodeUnit co, Source source, RaisePythonExceptionErrorCallback parserErrorCallback) { - FrameInfo frameInfo = new FrameInfo(); + public static PBytecodeRootNode create(PythonLanguage language, BytecodeCodeUnit co, Source source, RaisePythonExceptionErrorCallback parserErrorCallback) { + BytecodeFrameInfo frameInfo = new BytecodeFrameInfo(); FrameDescriptor fd = makeFrameDescriptor(co, frameInfo); - PBytecodeRootNode rootNode = new PBytecodeRootNode(language, fd, makeSignature(co), co, source, parserErrorCallback); + PBytecodeRootNode rootNode = new PBytecodeRootNode(language, fd, co.computeSignature(), co, source, parserErrorCallback); PythonContext context = PythonContext.get(rootNode); if (context != null && context.getOption(PythonOptions.EagerlyMaterializeInstrumentationNodes)) { rootNode.adoptChildren(); rootNode.instrumentationRoot.materializeInstrumentableNodes(Collections.singleton(StandardTags.StatementTag.class)); } - frameInfo.rootNode = rootNode; + frameInfo.setRootNode(rootNode); return rootNode; } @TruffleBoundary - private PBytecodeRootNode(PythonLanguage language, FrameDescriptor fd, Signature sign, CodeUnit co, Source source, RaisePythonExceptionErrorCallback parserErrorCallback) { + private PBytecodeRootNode(PythonLanguage language, FrameDescriptor fd, Signature sign, BytecodeCodeUnit co, Source source, RaisePythonExceptionErrorCallback parserErrorCallback) { super(language, fd); assert source != null; this.celloffset = co.varnames.length; @@ -656,9 +673,7 @@ private PBytecodeRootNode(PythonLanguage language, FrameDescriptor fd, Signature this.internal = source.isInternal(); this.parserErrorCallback = parserErrorCallback; this.signature = sign; - this.bytecode = PythonUtils.arrayCopyOf(co.code, co.code.length); - this.adoptedNodes = new Node[co.code.length]; - this.conditionProfiles = new int[co.conditionProfileCount]; + this.bytecode = co.code; this.outputCanQuicken = co.outputCanQuicken; this.variableShouldUnbox = co.variableShouldUnbox; this.generalizeInputsMap = co.generalizeInputsMap; @@ -733,7 +748,7 @@ public void setPythonInternal(boolean pythonInternal) { this.pythonInternal = pythonInternal; } - public CodeUnit getCodeUnit() { + public BytecodeCodeUnit getCodeUnit() { return co; } @@ -747,7 +762,22 @@ public byte[] getBytecode() { private Node[] getChildNodes() { InstrumentationSupport instrumentation = instrumentationRoot.getInstrumentation(); - return instrumentation == null ? adoptedNodes : instrumentation.bciToHelperNode; + if (instrumentation != null) { + return instrumentation.bciToHelperNode; + } + if (adoptedNodes == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + Lock lock = getLock(); + lock.lock(); + try { + if (adoptedNodes == null) { + adoptedNodes = new Node[bytecode.length]; + } + } finally { + lock.unlock(); + } + } + return adoptedNodes; } @FunctionalInterface @@ -756,66 +786,30 @@ private interface NodeSupplier { T get(); } - @FunctionalInterface - private interface NodeFunction { - T apply(A argument); - } - @FunctionalInterface private interface IntNodeFunction { T apply(int argument); } - @SuppressWarnings("unchecked") - private T insertChildNode(Node[] nodes, int nodeIndex, Class cachedClass, NodeFunction nodeSupplier, A argument) { - Node node = nodes[nodeIndex]; - if (node != null && node.getClass() == cachedClass) { - return CompilerDirectives.castExact(node, cachedClass); - } - return CompilerDirectives.castExact(doInsertChildNode(nodes, nodeIndex, nodeSupplier, argument), cachedClass); - } - - @SuppressWarnings("unchecked") - private T doInsertChildNode(Node[] nodes, int nodeIndex, NodeFunction nodeSupplier, A argument) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - Lock lock = getLock(); - lock.lock(); - try { - T newNode = nodeSupplier.apply(argument); - doInsertChildNode(nodes, nodeIndex, newNode); - return newNode; - } finally { - lock.unlock(); - } - } - - @SuppressWarnings("unchecked") - private T insertChildNode(Node[] nodes, int nodeIndex, T uncached, Class cachedClass, NodeFunction nodeSupplier, A argument, boolean useCachedNodes) { - if (!useCachedNodes) { - return uncached; - } - Node node = nodes[nodeIndex]; - if (node != null && node.getClass() == cachedClass) { - return CompilerDirectives.castExact(node, cachedClass); - } - return CompilerDirectives.castExact(doInsertChildNode(nodes, nodeIndex, nodeSupplier, argument), cachedClass); - } - @SuppressWarnings("unchecked") private T insertChildNodeInt(Node[] nodes, int nodeIndex, Class expectedClass, IntNodeFunction nodeSupplier, int argument) { Node node = nodes[nodeIndex]; if (expectedClass.isInstance(node)) { return (T) node; } - return doInsertChildNodeInt(nodes, nodeIndex, nodeSupplier, argument); + return doInsertChildNodeInt(nodes, nodeIndex, expectedClass, nodeSupplier, argument); } @SuppressWarnings("unchecked") - private T doInsertChildNodeInt(Node[] nodes, int nodeIndex, IntNodeFunction nodeSupplier, int argument) { + private T doInsertChildNodeInt(Node[] nodes, int nodeIndex, Class expectedClass, IntNodeFunction nodeSupplier, int argument) { CompilerDirectives.transferToInterpreterAndInvalidate(); Lock lock = getLock(); lock.lock(); try { + Node node = nodes[nodeIndex]; + if (expectedClass.isInstance(node)) { + return (T) node; + } T newNode = nodeSupplier.apply(argument); doInsertChildNode(nodes, nodeIndex, newNode); return newNode; @@ -830,15 +824,19 @@ private U insertChildNode(Node[] nodes, int nodeIn if (node != null && node.getClass() == cachedClass) { return CompilerDirectives.castExact(node, cachedClass); } - return CompilerDirectives.castExact(doInsertChildNode(nodes, nodeIndex, nodeSupplier), cachedClass); + return CompilerDirectives.castExact(doInsertChildNode(nodes, nodeIndex, cachedClass, nodeSupplier), cachedClass); } @SuppressWarnings("unchecked") - private T doInsertChildNode(Node[] nodes, int nodeIndex, NodeSupplier nodeSupplier) { + private T doInsertChildNode(Node[] nodes, int nodeIndex, Class cachedClass, NodeSupplier nodeSupplier) { CompilerDirectives.transferToInterpreterAndInvalidate(); Lock lock = getLock(); lock.lock(); try { + Node node = nodes[nodeIndex]; + if (node != null && node.getClass() == cachedClass) { + return (T) node; + } T newNode = nodeSupplier.get(); doInsertChildNode(nodes, nodeIndex, newNode); return newNode; @@ -856,7 +854,7 @@ private T insertChildNode(Node[] nodes, int nodeIndex, T uncach if (node != null && node.getClass() == cachedClass) { return CompilerDirectives.castExact(node, cachedClass); } - return CompilerDirectives.castExact(doInsertChildNode(nodes, nodeIndex, nodeSupplier), cachedClass); + return CompilerDirectives.castExact(doInsertChildNode(nodes, nodeIndex, cachedClass, nodeSupplier), cachedClass); } private void doInsertChildNode(Node[] nodes, int nodeIndex, Node newNode) { @@ -868,6 +866,10 @@ private void doInsertChildNode(Node[] nodes, int nodeIndex, Node newNode) { } } + private PythonLanguage getLanguage() { + return getLanguage(PythonLanguage.class); + } + private static final int CONDITION_PROFILE_MAX_VALUE = 0x3fffffff; // Inlined from ConditionProfile.Counting#profile @@ -875,6 +877,10 @@ private boolean profileCondition(boolean value, byte[] localBC, int bci, boolean if (!useCachedNodes) { return value; } + if (conditionProfiles == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + conditionProfiles = new int[co.conditionProfileCount]; + } int index = Byte.toUnsignedInt(localBC[bci + 2]) | Byte.toUnsignedInt(localBC[bci + 3]) << 8; int t = conditionProfiles[index]; int f = conditionProfiles[index + 1]; @@ -1052,10 +1058,10 @@ private void copyArgsAndCells(Frame localFrame, Object[] arguments) { copyArgs(arguments, localFrame); int varIdx = co.getRegularArgCount(); if (co.takesVarArgs()) { - localFrame.setObject(varIdx++, factory.createTuple(PArguments.getVariableArguments(arguments))); + localFrame.setObject(varIdx++, PFactory.createTuple(getLanguage(), PArguments.getVariableArguments(arguments))); } if (co.takesVarKeywordArgs()) { - localFrame.setObject(varIdx, factory.createDict(PArguments.getKeywordArguments(arguments))); + localFrame.setObject(varIdx, PFactory.createDict(getLanguage(), PArguments.getKeywordArguments(arguments))); } initCellVars(localFrame); initFreeVars(localFrame, arguments); @@ -1072,7 +1078,6 @@ public Object execute(VirtualFrame virtualFrame) { if (!co.isGeneratorOrCoroutine()) { copyArgsAndCells(virtualFrame, virtualFrame.getArguments()); } - return executeFromBci(virtualFrame, virtualFrame, this, 0, getInitialStackTop()); } finally { calleeContext.exit(virtualFrame, this); @@ -1172,10 +1177,10 @@ private InstrumentationData getTraceData() { return instrumentationData; } - public PythonContext.PythonThreadState getThreadState(Node node) { + public PythonContext.PythonThreadState getThreadState(PBytecodeRootNode node) { if (this.getTraceData().threadState == null) { PythonContext context = PythonContext.get(node); - return this.getTraceData().threadState = context.getThreadState(context.getLanguage(node)); + return this.getTraceData().threadState = context.getThreadState(node.getLanguage()); } return this.getTraceData().threadState; } @@ -1381,7 +1386,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod } case OpCodesConstants.LOAD_BIGINT: { oparg |= Byte.toUnsignedInt(localBC[++bci]); - virtualFrame.setObject(++stackTop, factory.createInt((BigInteger) localConsts[oparg])); + virtualFrame.setObject(++stackTop, PFactory.createInt(language, (BigInteger) localConsts[oparg])); break; } case OpCodesConstants.LOAD_STRING: @@ -1392,7 +1397,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod } case OpCodesConstants.LOAD_BYTES: { oparg |= Byte.toUnsignedInt(localBC[++bci]); - virtualFrame.setObject(++stackTop, factory.createBytes((byte[]) localConsts[oparg])); + virtualFrame.setObject(++stackTop, PFactory.createBytes(language, (byte[]) localConsts[oparg])); break; } case OpCodesConstants.LOAD_CONST_COLLECTION: { @@ -1405,7 +1410,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod case OpCodesConstants.LOAD_COMPLEX: { oparg |= Byte.toUnsignedInt(localBC[++bci]); double[] num = (double[]) localConsts[oparg]; - virtualFrame.setObject(++stackTop, factory.createComplex(num[0], num[1])); + virtualFrame.setObject(++stackTop, PFactory.createComplex(language, num[0], num[1])); break; } case OpCodesConstants.MAKE_KEYWORD: { @@ -1652,7 +1657,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod break; } case OpCodesConstants.POP_TOP: - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); break; case OpCodesConstants.ROT_TWO: { Object top = virtualFrame.getObject(stackTop); @@ -1892,7 +1897,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod } case OpCodesConstants.DELETE_FAST: { oparg |= Byte.toUnsignedInt(localBC[++bci]); - bytecodeDeleteFast(localFrame, beginBci, localNodes, oparg, useCachedNodes); + bytecodeDeleteFast(localFrame, beginBci, localNodes, oparg); break; } case OpCodesConstants.LOAD_ATTR: { @@ -1964,7 +1969,9 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod generalizePopAndJumpIfFalseB(bci); continue; } - if (profileCondition(!virtualFrame.getBoolean(stackTop--), localBC, bci, useCachedNodes)) { + boolean cond = virtualFrame.getBoolean(stackTop); + clearInCompiledCode(virtualFrame, stackTop--); + if (profileCondition(!cond, localBC, bci, useCachedNodes)) { oparg |= Byte.toUnsignedInt(localBC[bci + 1]); bci += oparg; oparg = 0; @@ -1980,7 +1987,9 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod generalizePopAndJumpIfTrueB(bci); continue; } - if (profileCondition(virtualFrame.getBoolean(stackTop--), localBC, bci, useCachedNodes)) { + boolean cond = virtualFrame.getBoolean(stackTop); + clearInCompiledCode(virtualFrame, stackTop--); + if (profileCondition(cond, localBC, bci, useCachedNodes)) { oparg |= Byte.toUnsignedInt(localBC[bci + 1]); bci += oparg; oparg = 0; @@ -1995,7 +2004,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod setCurrentBci(virtualFrame, bciSlot, bci); boolean cond = evaluateObjectCondition(virtualFrame, useCachedNodes, stackTop, bci, localBC, localNodes, beginBci); if (cond) { - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); bci += 3; } else { oparg |= Byte.toUnsignedInt(localBC[bci + 1]); @@ -2016,7 +2025,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod notifyStatement(virtualFrame, instrumentation, mutableData, bci, beginBci); continue; } else { - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); bci += 3; } break; @@ -2089,7 +2098,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod stackTop++; bci++; } else { - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); oparg |= Byte.toUnsignedInt(localBC[bci + 1]); bci += oparg; oparg = 0; @@ -2105,7 +2114,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod stackTop++; bci++; } else { - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); oparg |= Byte.toUnsignedInt(localBC[bci + 1]); bci += oparg; oparg = 0; @@ -2222,7 +2231,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod break; } case OpCodesConstants.ASYNCGEN_WRAP: { - bytecodeAsyncGenWrap(virtualFrame, useCachedNodes, stackTop, localNodes, beginBci); + virtualFrame.setObject(stackTop, PFactory.createAsyncGeneratorWrappedValue(language, virtualFrame.getObject(stackTop))); break; } case OpCodesConstants.PUSH_EXC_INFO: { @@ -2231,7 +2240,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod } case OpCodesConstants.POP_EXCEPT: { mutableData.localException = popExceptionState(arguments, virtualFrame.getObject(stackTop), mutableData.outerException); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); break; } case OpCodesConstants.END_EXC_HANDLER: { @@ -2318,7 +2327,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod if (e instanceof AbstractTruffleException) { exception = (AbstractTruffleException) e; } else { - exception = wrapJavaExceptionIfApplicable(e); + exception = wrapJavaExceptionIfApplicable(language, e); if (exception == null) { throw e; } @@ -2382,11 +2391,6 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod } } - @BytecodeInterpreterSwitch - private void bytecodeAsyncGenWrap(VirtualFrame virtualFrame, boolean useCachedNodes, int stackTop, Node[] localNodes, int beginBci) { - virtualFrame.setObject(stackTop, factory.createAsyncGeneratorWrappedValue(virtualFrame.getObject(stackTop))); - } - @BytecodeInterpreterSwitch private int bytecodeGetAIter(VirtualFrame virtualFrame, boolean useCachedNodes, int stackTop, Node[] localNodes, int bci) { GetAIterNode node = insertChildNode(localNodes, bci, UNCACHED_GET_AITER, GetAIterNodeGen.class, NODE_GET_AITER, useCachedNodes); @@ -2405,9 +2409,9 @@ private int bytecodeGetANext(VirtualFrame virtualFrame, boolean useCachedNodes, private int bytecodeEndAsyncFor(VirtualFrame virtualFrame, boolean useCachedNodes, int stackTop, Node[] localNodes, int bci) { EndAsyncForNode node = insertChildNode(localNodes, bci, UNCACHED_END_ASYNC_FOR, EndAsyncForNodeGen.class, NODE_END_ASYNC_FOR, useCachedNodes); node.execute(virtualFrame.getObject(stackTop), frameIsVisibleToPython()); - virtualFrame.setObject(stackTop, null); // pop the exception - virtualFrame.setObject(stackTop - 1, null); // the coroutine that raised the exception - virtualFrame.setObject(stackTop - 2, null); // the async iterator + virtualFrame.clear(stackTop); // pop the exception + virtualFrame.clear(stackTop - 1); // the coroutine that raised the exception + virtualFrame.clear(stackTop - 2); // the async iterator return stackTop - 3; } @@ -2530,7 +2534,7 @@ private boolean bytecodeForIterI(VirtualFrame virtualFrame, boolean useCachedNod private boolean bytecodeMatchExc(VirtualFrame virtualFrame, boolean useCachedNodes, int stackTop, Node[] localNodes, int beginBci) { Object exception = virtualFrame.getObject(stackTop - 1); Object matchType = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop, null); + virtualFrame.clear(stackTop); ExceptMatchNode matchNode = insertChildNode(localNodes, beginBci, UNCACHED_EXCEPT_MATCH, ExceptMatchNodeGen.class, NODE_EXCEPT_MATCH, useCachedNodes); return matchNode.executeMatch(virtualFrame, exception, matchType); } @@ -2599,7 +2603,7 @@ private void bytecodeSetupAnnotations(VirtualFrame virtualFrame, boolean useCach @BytecodeInterpreterSwitch private int bytecodeMakeFunction(VirtualFrame virtualFrame, Object globals, int stackTop, Node[] localNodes, int beginBci, int flags, Object localConsts) { - CodeUnit codeUnit = (CodeUnit) localConsts; + BytecodeCodeUnit codeUnit = (BytecodeCodeUnit) localConsts; MakeFunctionNode makeFunctionNode = insertMakeFunctionNode(localNodes, beginBci, codeUnit); return makeFunctionNode.execute(virtualFrame, globals, stackTop, flags); } @@ -2634,7 +2638,7 @@ private GeneratorYieldResult bytecodeYieldValue(VirtualFrame virtualFrame, Frame LoopNode.reportLoopCount(this, mutableData.loopCount); } Object value = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); PArguments.setException(PArguments.getGeneratorFrame(arguments), mutableData.localException); if (mutableData.localException instanceof PException pe) { /* @@ -2772,15 +2776,15 @@ private Object notifyEnter(VirtualFrame virtualFrame, InstrumentationSupport ins return null; } - private MakeFunctionNode insertMakeFunctionNode(Node[] localNodes, int beginBci, CodeUnit codeUnit) { + private MakeFunctionNode insertMakeFunctionNode(Node[] localNodes, int beginBci, BytecodeCodeUnit codeUnit) { return insertChildNode(localNodes, beginBci, MakeFunctionNodeGen.class, () -> MakeFunctionNode.create(getLanguage(PythonLanguage.class), codeUnit, source)); } public void materializeContainedFunctionsForInstrumentation(Set> materializedTags) { usingCachedNodes = true; - CodeUnit.iterateBytecode(bytecode, (bci, op, oparg, followingArgs) -> { + BytecodeCodeUnit.iterateBytecode(bytecode, (bci, op, oparg, followingArgs) -> { if (op == OpCodes.MAKE_FUNCTION) { - CodeUnit codeUnit = (CodeUnit) consts[oparg]; + BytecodeCodeUnit codeUnit = (BytecodeCodeUnit) consts[oparg]; MakeFunctionNode makeFunctionNode = insertMakeFunctionNode(getChildNodes(), bci, codeUnit); RootNode rootNode = makeFunctionNode.getCallTarget().getRootNode(); if (rootNode instanceof PBytecodeGeneratorFunctionRootNode) { @@ -2800,7 +2804,7 @@ private int bytecodePrintExpr(VirtualFrame virtualFrame, boolean useCachedNodes, setCurrentBci(virtualFrame, bciSlot, bci); PrintExprNode printExprNode = insertChildNode(localNodes, beginBci, UNCACHED_PRINT_EXPR, PrintExprNodeGen.class, NODE_PRINT_EXPR, useCachedNodes); printExprNode.execute(virtualFrame, virtualFrame.getObject(stackTop)); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); return stackTop; } @@ -2877,7 +2881,7 @@ private void traceException(VirtualFrame virtualFrame, MutableLoopData mutableDa Object peType = GetClassNode.executeUncached(exceptionObject); Object traceback = ExceptionNodes.GetTracebackNode.executeUncached(exception); invokeTraceFunction(virtualFrame, - factory.createTuple(new Object[]{peType, exceptionObject, traceback}), mutableData.getThreadState(this), + PFactory.createTuple(getLanguage(), new Object[]{peType, exceptionObject, traceback}), mutableData.getThreadState(this), mutableData, PythonContext.TraceEvent.EXCEPTION, bciToLine(bci), true); } @@ -2948,12 +2952,12 @@ private int traceLine(VirtualFrame virtualFrame, MutableLoopData mutableData, by if (pyFrame.didJump()) { int newBci = lineToBci(pyFrame.getJumpDestLine()); mutableData.setPastBci(bci); - if (newBci == CodeUnit.LINE_TO_BCI_LINE_AFTER_CODEBLOCK) { + if (newBci == BytecodeCodeUnit.LINE_TO_BCI_LINE_AFTER_CODEBLOCK) { // line after the code block - throw PRaiseNode.getUncached().raise(ValueError, ErrorMessages.LINE_D_COMES_AFTER_THE_CURRENT_CODE_BLOCK, pyFrame.getLine()); - } else if (newBci == CodeUnit.LINE_TO_BCI_LINE_BEFORE_CODEBLOCK) { + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.LINE_D_COMES_AFTER_THE_CURRENT_CODE_BLOCK, pyFrame.getLine()); + } else if (newBci == BytecodeCodeUnit.LINE_TO_BCI_LINE_BEFORE_CODEBLOCK) { // line before the code block - throw PRaiseNode.getUncached().raise(ValueError, ErrorMessages.LINE_D_COMES_BEFORE_THE_CURRENT_CODE_BLOCK, pyFrame.getJumpDestLine()); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.LINE_D_COMES_BEFORE_THE_CURRENT_CODE_BLOCK, pyFrame.getJumpDestLine()); } else { ret = computeJumpStackDifference(bci, newBci); mutableData.setJumpBci(newBci); @@ -2970,9 +2974,9 @@ private int traceLine(VirtualFrame virtualFrame, MutableLoopData mutableData, by private int computeJumpStackDifference(int bci, int newBci) { int ret; var stacks = co.computeStackElems(); - String error = co.checkJump(stacks, bci, newBci); + String error = co.checkJump(this, stacks, bci, newBci); if (error != null) { - throw PRaiseNode.getUncached().raise(ValueError, ErrorMessages.CANT_JUMP_INTO_S, error); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.CANT_JUMP_INTO_S, error); } ret = stacks.get(newBci).size() - stacks.get(bci).size(); return ret; @@ -3016,7 +3020,7 @@ private int bytecodeBinarySubscrOO(VirtualFrame virtualFrame, int stackTop, int // Should only happen in multi-context mode return generalizeBinarySubscr(virtualFrame, stackTop, bci, localNodes); } - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); virtualFrame.setObject(stackTop, getItemNode.executeCached(virtualFrame, virtualFrame.getObject(stackTop), index)); return stackTop; } @@ -3035,7 +3039,7 @@ private int bytecodeBinarySubscrSeqIO(VirtualFrame virtualFrame, int stackTop, i } catch (QuickeningGeneralizeException e) { return generalizeBinarySubscrSeq(virtualFrame, stackTop, bci, localNodes, e); } - virtualFrame.setObject(stackTop--, null); + clearInCompiledCode(virtualFrame, stackTop--); virtualFrame.setObject(stackTop, value); return stackTop; } @@ -3054,7 +3058,7 @@ private int bytecodeBinarySubscrSeqII(VirtualFrame virtualFrame, int stackTop, i } catch (QuickeningGeneralizeException e) { return generalizeBinarySubscrSeq(virtualFrame, stackTop, bci, localNodes, e); } - virtualFrame.setObject(stackTop--, null); + clearInCompiledCode(virtualFrame, stackTop--); virtualFrame.setInt(stackTop, value); return stackTop; } @@ -3073,7 +3077,7 @@ private int bytecodeBinarySubscrSeqID(VirtualFrame virtualFrame, int stackTop, i } catch (QuickeningGeneralizeException e) { return generalizeBinarySubscrSeq(virtualFrame, stackTop, bci, localNodes, e); } - virtualFrame.setObject(stackTop--, null); + clearInCompiledCode(virtualFrame, stackTop--); virtualFrame.setDouble(stackTop, value); return stackTop; } @@ -3142,7 +3146,7 @@ private void invokeTraceFunction(VirtualFrame virtualFrame, Object arg, PythonCo pyFrame.setLocalTraceFun(null); } } catch (Throwable e) { - threadState.setTraceFun(null, PythonLanguage.get(this)); + threadState.setTraceFun(null, getLanguage()); throw e; } finally { if (line != -1) { @@ -3157,7 +3161,7 @@ private void syncLocalsBackToFrame(VirtualFrame virtualFrame, PFrame pyFrame) { if (co.isGeneratorOrCoroutine()) { localFrame = PArguments.getGeneratorFrame(virtualFrame); } - GetFrameLocalsNode.syncLocalsBackToFrame(co, pyFrame, localFrame); + GetFrameLocalsNode.syncLocalsBackToFrame(co, this, pyFrame, localFrame); } private void profileCEvent(VirtualFrame virtualFrame, Object callable, PythonContext.ProfileEvent event, MutableLoopData mutableData, byte tracingOrProfilingEnabled) { @@ -3203,7 +3207,7 @@ private void invokeProfileFunction(VirtualFrame virtualFrame, Object arg, Python Object realResult = result == PNone.NONE ? null : result; pyFrame.setLocalTraceFun(realResult); } catch (Throwable e) { - threadState.setProfileFun(null, PythonLanguage.get(this)); + threadState.setProfileFun(null, getLanguage()); throw e; } finally { threadState.profilingStop(); @@ -3276,7 +3280,14 @@ private void chainPythonExceptions(PException current, PException context) { private PException raiseUnknownBytecodeError(byte bc) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(this, SystemError, toTruffleStringUncached("not implemented bytecode %s"), OpCodes.fromOpCode(bc)); + TruffleString format = toTruffleStringUncached("not implemented bytecode %s"); + throw PRaiseNode.raiseStatic(this, SystemError, format, OpCodes.fromOpCode(bc)); + } + + private static void clearInCompiledCode(VirtualFrame virtualFrame, int stackTop) { + if (CompilerDirectives.inCompiledCode()) { + virtualFrame.clear(stackTop); + } } private void generalizeForIterI(int bci, QuickeningGeneralizeException e) { @@ -3323,7 +3334,7 @@ private boolean bytecodePopCondition(VirtualFrame virtualFrame, int stackTop, No // Can happen when multiple code paths produce different types cond = generalizePopCondition(virtualFrame, stackTop, bci); } - virtualFrame.setObject(stackTop, null); + virtualFrame.clear(stackTop); return isTrue.execute(virtualFrame, cond); } @@ -3471,6 +3482,7 @@ private void bytecodeBinaryOpIIB(VirtualFrame virtualFrame, int stackTop, int bc default: throw CompilerDirectives.shouldNotReachHere("Invalid operation for BINARY_OP_II_B"); } + clearInCompiledCode(virtualFrame, stackTop); virtualFrame.setBoolean(stackTop - 1, result); } @@ -3565,7 +3577,7 @@ private void bytecodeBinaryOpIIO(VirtualFrame virtualFrame, int stackTop, int bc default: throw CompilerDirectives.shouldNotReachHere("Invalid operation for BINARY_OP_II_O"); } - virtualFrame.setObject(stackTop, null); + clearInCompiledCode(virtualFrame, stackTop); virtualFrame.setObject(stackTop - 1, result); } @@ -3658,12 +3670,13 @@ private void bytecodeBinaryOpIII(VirtualFrame virtualFrame, int stackTop, int bc generalizeBinaryOpIIIOverflow(virtualFrame, stackTop, bci, localNodes, op); return; } + clearInCompiledCode(virtualFrame, stackTop); virtualFrame.setInt(stackTop - 1, result); } @InliningCutoff private void raiseDivOrModByZero(int bci, Node[] localNodes, boolean useCachedNodes) { - PRaiseNode raiseNode = insertChildNode(localNodes, bci, UNCACHED_RAISE, PRaiseNodeGen.class, NODE_RAISE, useCachedNodes); + PRaiseCachedNode raiseNode = insertChildNode(localNodes, bci, UNCACHED_RAISE, PRaiseCachedNodeGen.class, NODE_RAISE, useCachedNodes); throw raiseNode.raise(ZeroDivisionError, ErrorMessages.S_DIVISION_OR_MODULO_BY_ZERO, "integer"); } @@ -3710,6 +3723,7 @@ private void bytecodeBinaryOpDDD(VirtualFrame virtualFrame, int stackTop, int bc generalizeBinaryOpDDDOverflow(virtualFrame, stackTop, bci, localNodes, op, useCachedNodes); return; } + clearInCompiledCode(virtualFrame, stackTop); virtualFrame.setDouble(stackTop - 1, result); } @@ -3746,6 +3760,7 @@ private void bytecodeBinaryOpDDB(VirtualFrame virtualFrame, int stackTop, int bc default: throw CompilerDirectives.shouldNotReachHere("Invalid operation for BINARY_OP_DD_B"); } + clearInCompiledCode(virtualFrame, stackTop); virtualFrame.setBoolean(stackTop - 1, result); } @@ -3807,13 +3822,13 @@ private void bytecodeBinaryOpDDO(VirtualFrame virtualFrame, int stackTop, int bc default: throw CompilerDirectives.shouldNotReachHere("Invalid operation for BINARY_OP_DD_O"); } - virtualFrame.setObject(stackTop, null); + clearInCompiledCode(virtualFrame, stackTop); virtualFrame.setObject(stackTop - 1, result); } @InliningCutoff private void raiseDivByZero(int bci, Node[] localNodes, boolean useCachedNodes) { - PRaiseNode raiseNode = insertChildNode(localNodes, bci, UNCACHED_RAISE, PRaiseNodeGen.class, NODE_RAISE, useCachedNodes); + PRaiseCachedNode raiseNode = insertChildNode(localNodes, bci, UNCACHED_RAISE, PRaiseCachedNodeGen.class, NODE_RAISE, useCachedNodes); throw raiseNode.raise(ZeroDivisionError, ErrorMessages.DIVISION_BY_ZERO); } @@ -3850,8 +3865,8 @@ private void bytecodeBinaryOpOOO(VirtualFrame virtualFrame, int stackTop, int bc right = generalizePopCondition(virtualFrame, stackTop, bci); left = virtualFrame.getValue(stackTop - 1); } - virtualFrame.setObject(stackTop, null); - Object result = opNode.executeObject(virtualFrame, left, right); + virtualFrame.clear(stackTop); + Object result = opNode.execute(virtualFrame, left, right); virtualFrame.setObject(stackTop - 1, result); } @@ -4069,7 +4084,7 @@ private void bytecodeUnaryOpOO(VirtualFrame virtualFrame, int stackTop, int bci, generalizeInputs(bci); value = virtualFrame.getValue(stackTop); } - Object result = opNode.executeCached(virtualFrame, value); + Object result = opNode.execute(virtualFrame, value); virtualFrame.setObject(stackTop, result); } @@ -4194,6 +4209,7 @@ private void bytecodeStoreFastAdaptive(VirtualFrame virtualFrame, Frame localFra private void bytecodeStoreFastI(VirtualFrame virtualFrame, Frame localFrame, int stackTop, int bci, int index) { if (virtualFrame.isInt(stackTop)) { localFrame.setInt(index, virtualFrame.getInt(stackTop)); + clearInCompiledCode(virtualFrame, stackTop); } else { generalizeStoreFast(virtualFrame, localFrame, stackTop, bci, index); } @@ -4211,7 +4227,7 @@ private void bytecodeStoreFastUnboxI(VirtualFrame virtualFrame, Frame localFrame } if (object instanceof Integer) { localFrame.setInt(index, (int) object); - virtualFrame.setObject(stackTop, null); + virtualFrame.clear(stackTop); } else { generalizeStoreFast(virtualFrame, localFrame, stackTop, bci, index); } @@ -4236,13 +4252,14 @@ private void bytecodeStoreFastBoxedI(VirtualFrame virtualFrame, Frame localFrame } else { localFrame.setObject(index, object); } - virtualFrame.setObject(stackTop, null); + virtualFrame.clear(stackTop); } @BytecodeInterpreterSwitch private void bytecodeStoreFastL(VirtualFrame virtualFrame, Frame localFrame, int stackTop, int bci, int index) { if (virtualFrame.isLong(stackTop)) { localFrame.setLong(index, virtualFrame.getLong(stackTop)); + clearInCompiledCode(virtualFrame, stackTop); } else { generalizeStoreFast(virtualFrame, localFrame, stackTop, bci, index); } @@ -4260,7 +4277,7 @@ private void bytecodeStoreFastUnboxL(VirtualFrame virtualFrame, Frame localFrame } if (object instanceof Long) { localFrame.setLong(index, (long) object); - virtualFrame.setObject(stackTop, null); + virtualFrame.clear(stackTop); } else { generalizeStoreFast(virtualFrame, localFrame, stackTop, bci, index); } @@ -4285,13 +4302,14 @@ private void bytecodeStoreFastBoxedL(VirtualFrame virtualFrame, Frame localFrame } else { localFrame.setObject(index, object); } - virtualFrame.setObject(stackTop, null); + virtualFrame.clear(stackTop); } @BytecodeInterpreterSwitch private void bytecodeStoreFastD(VirtualFrame virtualFrame, Frame localFrame, int stackTop, int bci, int index) { if (virtualFrame.isDouble(stackTop)) { localFrame.setDouble(index, virtualFrame.getDouble(stackTop)); + clearInCompiledCode(virtualFrame, stackTop); } else { generalizeStoreFast(virtualFrame, localFrame, stackTop, bci, index); } @@ -4309,7 +4327,7 @@ private void bytecodeStoreFastUnboxD(VirtualFrame virtualFrame, Frame localFrame } if (object instanceof Double) { localFrame.setDouble(index, (double) object); - virtualFrame.setObject(stackTop, null); + virtualFrame.clear(stackTop); } else { generalizeStoreFast(virtualFrame, localFrame, stackTop, bci, index); } @@ -4334,13 +4352,14 @@ private void bytecodeStoreFastBoxedD(VirtualFrame virtualFrame, Frame localFrame } else { localFrame.setObject(index, object); } - virtualFrame.setObject(stackTop, null); + virtualFrame.clear(stackTop); } @BytecodeInterpreterSwitch private void bytecodeStoreFastB(VirtualFrame virtualFrame, Frame localFrame, int stackTop, int bci, int index) { if (virtualFrame.isBoolean(stackTop)) { localFrame.setBoolean(index, virtualFrame.getBoolean(stackTop)); + clearInCompiledCode(virtualFrame, stackTop); } else { generalizeStoreFast(virtualFrame, localFrame, stackTop, bci, index); } @@ -4358,7 +4377,7 @@ private void bytecodeStoreFastUnboxB(VirtualFrame virtualFrame, Frame localFrame } if (object instanceof Boolean) { localFrame.setBoolean(index, (boolean) object); - virtualFrame.setObject(stackTop, null); + virtualFrame.clear(stackTop); } else { generalizeStoreFast(virtualFrame, localFrame, stackTop, bci, index); } @@ -4383,7 +4402,7 @@ private void bytecodeStoreFastBoxedB(VirtualFrame virtualFrame, Frame localFrame } else { localFrame.setObject(index, object); } - virtualFrame.setObject(stackTop, null); + virtualFrame.clear(stackTop); } private void generalizeStoreFast(VirtualFrame virtualFrame, Frame localFrame, int stackTop, int bci, int index) { @@ -4406,7 +4425,7 @@ private void bytecodeStoreFastO(VirtualFrame virtualFrame, Frame localFrame, int object = virtualFrame.getValue(stackTop); } localFrame.setObject(index, object); - virtualFrame.setObject(stackTop, null); + virtualFrame.clear(stackTop); } @InliningCutoff @@ -4561,7 +4580,7 @@ private void bytecodeLoadFastO(VirtualFrame virtualFrame, Frame localFrame, int @InliningCutoff private PException raiseVarReferencedBeforeAssignment(Node[] localNodes, int bci, int index) { - PRaiseNode raiseNode = insertChildNode(localNodes, bci, PRaiseNodeGen.class, NODE_RAISE); + PRaiseCachedNode raiseNode = insertChildNode(localNodes, bci, PRaiseCachedNodeGen.class, NODE_RAISE); throw raiseNode.raise(PythonBuiltinClassType.UnboundLocalError, ErrorMessages.LOCAL_VAR_REFERENCED_BEFORE_ASSIGMENT, varnames[index]); } @@ -4630,17 +4649,17 @@ private void generalizeVariableStores(int index) { } @InliningCutoff - protected PException wrapJavaExceptionIfApplicable(Throwable e) { + private PException wrapJavaExceptionIfApplicable(PythonLanguage language, Throwable e) { if (e instanceof AbstractTruffleException) { return null; } if (e instanceof ControlFlowException) { return null; } - if (PythonLanguage.get(this).getEngineOption(PythonOptions.CatchAllExceptions) && (e instanceof Exception || e instanceof AssertionError)) { - return ExceptionUtils.wrapJavaException(e, this, factory.createBaseException(SystemError, ErrorMessages.M, new Object[]{e})); + if (language.getEngineOption(PythonOptions.CatchAllExceptions) && (e instanceof Exception || e instanceof AssertionError)) { + return ExceptionUtils.wrapJavaException(e, this, PFactory.createBaseException(language, SystemError, ErrorMessages.M, new Object[]{e})); } - return ExceptionUtils.wrapJavaExceptionIfApplicable(this, e, factory); + return ExceptionUtils.wrapJavaExceptionIfApplicable(this, e); } @ExplodeLoop @@ -4678,7 +4697,7 @@ private int bytecodeFormatValue(VirtualFrame virtualFrame, int initialStackTop, Object spec = PNone.NO_VALUE; if ((options & FormatOptions.FVS_MASK) == FormatOptions.FVS_HAVE_SPEC) { spec = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); } Object value = virtualFrame.getObject(stackTop); switch (type) { @@ -4713,7 +4732,7 @@ private void bytecodeDeleteDeref(Frame localFrame, int bci, Node[] localNodes, i private int bytecodeStoreDeref(VirtualFrame virtualFrame, Frame localFrame, int stackTop, int oparg, int cachedCelloffset) { PCell cell = (PCell) localFrame.getObject(cachedCelloffset + oparg); Object value = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); cell.setRef(value); return stackTop; } @@ -4784,11 +4803,11 @@ private void bytecodeLoadAttr(VirtualFrame virtualFrame, int stackTop, int bci, virtualFrame.setObject(stackTop, value); } - private void bytecodeDeleteFast(Frame localFrame, int bci, Node[] localNodes, int oparg, boolean useCachedNodes) { + private void bytecodeDeleteFast(Frame localFrame, int bci, Node[] localNodes, int oparg) { if (localFrame.isObject(oparg)) { Object value = localFrame.getObject(oparg); if (value == null) { - raiseVarReferencedBeforeAssignment(localNodes, bci, oparg); + throw raiseVarReferencedBeforeAssignment(localNodes, bci, oparg); } } else { generalizeVariableStores(oparg); @@ -4815,7 +4834,7 @@ private int bytecodeStoreGlobal(VirtualFrame virtualFrame, Object globals, int s TruffleString varname = localNames[oparg]; WriteGlobalNode writeGlobalNode = insertChildNode(localNodes, bci, UNCACHED_WRITE_GLOBAL, WriteGlobalNodeGen.class, NODE_WRITE_GLOBAL, useCachedNodes); writeGlobalNode.write(virtualFrame, globals, varname, virtualFrame.getObject(stackTop)); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); return stackTop; } @@ -4823,7 +4842,7 @@ private int bytecodeDeleteAttr(VirtualFrame virtualFrame, int stackTop, int bci, PyObjectSetAttr callNode = insertChildNode(localNodes, bci, UNCACHED_OBJECT_SET_ATTR, PyObjectSetAttrNodeGen.class, NODE_OBJECT_SET_ATTR, useCachedNodes); TruffleString varname = localNames[oparg]; Object owner = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); callNode.deleteCached(virtualFrame, owner, varname); return stackTop; } @@ -4833,9 +4852,9 @@ private int bytecodeStoreAttr(VirtualFrame virtualFrame, int stackTop, int bci, PyObjectSetAttr callNode = insertChildNode(localNodes, bci, UNCACHED_OBJECT_SET_ATTR, PyObjectSetAttrNodeGen.class, NODE_OBJECT_SET_ATTR, useCachedNodes); TruffleString varname = localNames[oparg]; Object owner = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); Object value = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); callNode.executeCached(virtualFrame, owner, varname, value); return stackTop; } @@ -4848,7 +4867,7 @@ private void bytecodeDeleteName(VirtualFrame virtualFrame, Object globals, Objec try { delItemNode.executeCached(virtualFrame, locals, varname); } catch (PException e) { - PRaiseNode raiseNode = insertChildNode(localNodes, bci, UNCACHED_RAISE, PRaiseNodeGen.class, NODE_RAISE, useCachedNodes); + PRaiseCachedNode raiseNode = insertChildNode(localNodes, bci, UNCACHED_RAISE, PRaiseCachedNodeGen.class, NODE_RAISE, useCachedNodes); throw raiseNode.raise(NameError, ErrorMessages.NAME_NOT_DEFINED, varname); } } else { @@ -4860,9 +4879,9 @@ private void bytecodeDeleteName(VirtualFrame virtualFrame, Object globals, Objec private int bytecodeDeleteSubscr(VirtualFrame virtualFrame, int stackTop, int bci, Node[] localNodes, boolean useCachedNodes) { PyObjectDelItem delItem = insertChildNode(localNodes, bci, UNCACHED_OBJECT_DEL_ITEM, PyObjectDelItemNodeGen.class, NODE_OBJECT_DEL_ITEM, useCachedNodes); Object slice = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); Object container = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); delItem.executeCached(virtualFrame, container, slice); return stackTop; } @@ -4904,9 +4923,9 @@ private int bytecodeStoreSubscrOOO(VirtualFrame virtualFrame, int stackTop, int // Should only happen in multi-context mode return generalizeStoreSubscr(virtualFrame, stackTop, bci, localNodes, useCachedNodes); } - virtualFrame.setObject(stackTop--, null); - virtualFrame.setObject(stackTop--, null); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); + virtualFrame.clear(stackTop--); + virtualFrame.clear(stackTop--); return stackTop; } @@ -4930,9 +4949,9 @@ private int bytecodeStoreSubscrSeqIOO(VirtualFrame virtualFrame, int stackTop, i } catch (QuickeningGeneralizeException e) { return generalizeStoreSubscr(virtualFrame, stackTop, bci, localNodes, useCachedNodes); } - virtualFrame.setObject(stackTop--, null); - virtualFrame.setObject(stackTop--, null); - virtualFrame.setObject(stackTop--, null); + clearInCompiledCode(virtualFrame, stackTop--); + virtualFrame.clear(stackTop--); + virtualFrame.clear(stackTop--); return stackTop; } @@ -4953,9 +4972,9 @@ private int bytecodeStoreSubscrSeqIIO(VirtualFrame virtualFrame, int stackTop, i } catch (QuickeningGeneralizeException e) { return generalizeStoreSubscr(virtualFrame, stackTop, bci, localNodes, useCachedNodes); } - virtualFrame.setObject(stackTop--, null); - virtualFrame.setObject(stackTop--, null); - virtualFrame.setObject(stackTop--, null); + clearInCompiledCode(virtualFrame, stackTop--); + virtualFrame.clear(stackTop--); + clearInCompiledCode(virtualFrame, stackTop--); return stackTop; } @@ -4976,9 +4995,9 @@ private int bytecodeStoreSubscrSeqIDO(VirtualFrame virtualFrame, int stackTop, i } catch (QuickeningGeneralizeException e) { return generalizeStoreSubscr(virtualFrame, stackTop, bci, localNodes, useCachedNodes); } - virtualFrame.setObject(stackTop--, null); - virtualFrame.setObject(stackTop--, null); - virtualFrame.setObject(stackTop--, null); + clearInCompiledCode(virtualFrame, stackTop--); + virtualFrame.clear(stackTop--); + clearInCompiledCode(virtualFrame, stackTop--); return stackTop; } @@ -5012,13 +5031,13 @@ private int bytecodeBuildSlice(VirtualFrame virtualFrame, int stackTop, int bci, Object step; if (count == 3) { step = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); } else { assert count == 2; step = PNone.NONE; } Object stop = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); Object start = virtualFrame.getObject(stackTop); CreateSliceNode sliceNode = insertChildNode(localNodes, bci, UNCACHED_CREATE_SLICE, CreateSliceNodeGen.class, NODE_CREATE_SLICE, useCachedNodes); PSlice slice = sliceNode.execute(start, stop, step); @@ -5033,10 +5052,11 @@ private void bytecodeLoadConstCollection(VirtualFrame virtualFrame, int stackTop int kind = CollectionBits.collectionKind(typeAndKind); assert kind == CollectionBits.KIND_LIST || kind == CollectionBits.KIND_TUPLE; boolean list = kind == CollectionBits.KIND_LIST; - var context = PythonContext.get(this); - boolean useNativePrimitiveStorage = context.getLanguage(this).getEngineOption(PythonOptions.UseNativePrimitiveStorageStrategy); + PythonLanguage language = getLanguage(); + boolean useNativePrimitiveStorage = language.getEngineOption(PythonOptions.UseNativePrimitiveStorageStrategy); switch (CollectionBits.elementType(typeAndKind)) { case CollectionBits.ELEMENT_INT: { + var context = PythonContext.get(this); int[] a = (int[]) array; if (useNativePrimitiveStorage) { storage = context.nativeBufferContext.toNativeIntStorage(a); @@ -5084,9 +5104,9 @@ private void bytecodeLoadConstCollection(VirtualFrame virtualFrame, int stackTop throw CompilerDirectives.shouldNotReachHere(); } if (list) { - result = factory.createList(storage); + result = PFactory.createList(language, storage); } else { - result = factory.createTuple(storage); + result = PFactory.createTuple(language, storage); } virtualFrame.setObject(stackTop, result); } @@ -5110,8 +5130,8 @@ private int bytecodeCallFunctionKw(VirtualFrame virtualFrame, int initialStackTo } virtualFrame.setObject(stackTop - 2, result); - virtualFrame.setObject(stackTop--, null); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); + virtualFrame.clear(stackTop--); return stackTop; } @@ -5134,7 +5154,7 @@ private int bytecodeCallFunctionVarargs(VirtualFrame virtualFrame, int initialSt } virtualFrame.setObject(stackTop - 1, result); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); return stackTop; } @@ -5157,7 +5177,7 @@ private int bytecodeCallMethodVarargs(VirtualFrame virtualFrame, int initialStac } virtualFrame.setObject(stackTop - 1, result); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); return stackTop; } @@ -5202,16 +5222,16 @@ private int bytecodeCallFunction(VirtualFrame virtualFrame, int stackTop, int bc throw e; } - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); virtualFrame.setObject(stackTop, result); break; } case 2: { CallBinaryMethodNode callNode = insertChildNode(localNodes, bci, UNCACHED_CALL_BINARY_METHOD, CallBinaryMethodNodeGen.class, NODE_CALL_BINARY_METHOD, useCachedNodes); Object arg1 = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); Object arg0 = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_CALL, mutableData, tracingOrProfilingEnabled); try { @@ -5228,11 +5248,11 @@ private int bytecodeCallFunction(VirtualFrame virtualFrame, int stackTop, int bc case 3: { CallTernaryMethodNode callNode = insertChildNode(localNodes, bci, UNCACHED_CALL_TERNARY_METHOD, CallTernaryMethodNodeGen.class, NODE_CALL_TERNARY_METHOD, useCachedNodes); Object arg2 = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); Object arg1 = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); Object arg0 = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_CALL, mutableData, tracingOrProfilingEnabled); try { @@ -5249,13 +5269,13 @@ private int bytecodeCallFunction(VirtualFrame virtualFrame, int stackTop, int bc case 4: { CallQuaternaryMethodNode callNode = insertChildNode(localNodes, bci, UNCACHED_CALL_QUATERNARY_METHOD, CallQuaternaryMethodNodeGen.class, NODE_CALL_QUATERNARY_METHOD, useCachedNodes); Object arg3 = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); Object arg2 = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); Object arg1 = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); Object arg0 = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_CALL, mutableData, tracingOrProfilingEnabled); try { @@ -5276,21 +5296,21 @@ private int bytecodeCallFunction(VirtualFrame virtualFrame, int stackTop, int bc @BytecodeInterpreterSwitch private int bytecodeCallComprehension(VirtualFrame virtualFrame, int stackTop, int bci, Node[] localNodes, MutableLoopData mutableData, byte tracingOrProfilingEnabled) { PFunction func = (PFunction) virtualFrame.getObject(stackTop - 1); - CallTargetInvokeNode callNode = insertChildNode(localNodes, bci, CallTargetInvokeNodeGen.class, () -> CallTargetInvokeNode.create(func)); + CallComprehensionNode callNode = insertChildNode(localNodes, bci, CallComprehensionNodeGen.class, NODE_CALL_COMPREHENSION); Object result; profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_CALL, mutableData, tracingOrProfilingEnabled); try { Object[] arguments = PArguments.create(1); PArguments.setArgument(arguments, 0, virtualFrame.getObject(stackTop)); - result = callNode.execute(virtualFrame, func, func.getGlobals(), func.getClosure(), arguments); + result = callNode.execute(virtualFrame, func, arguments); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_RETURN, mutableData, tracingOrProfilingEnabled); } catch (AbstractTruffleException e) { profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_EXCEPTION, mutableData, tracingOrProfilingEnabled); throw e; } - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); virtualFrame.setObject(stackTop, result); return stackTop; } @@ -5326,7 +5346,7 @@ private int bytecodeCallMethod(VirtualFrame virtualFrame, int stackTop, int bci, throw e; } - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); virtualFrame.setObject(stackTop, result); break; } @@ -5342,18 +5362,18 @@ private int bytecodeCallMethod(VirtualFrame virtualFrame, int stackTop, int bci, throw e; } - virtualFrame.setObject(stackTop--, null); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); + virtualFrame.clear(stackTop--); virtualFrame.setObject(stackTop, result); break; } case 2: { CallTernaryMethodNode callNode = insertChildNode(localNodes, bci + 1, UNCACHED_CALL_TERNARY_METHOD, CallTernaryMethodNodeGen.class, NODE_CALL_TERNARY_METHOD, useCachedNodes); Object arg1 = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); Object arg0 = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); + virtualFrame.clear(stackTop--); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_CALL, mutableData, tracingOrProfilingEnabled); try { @@ -5372,12 +5392,12 @@ private int bytecodeCallMethod(VirtualFrame virtualFrame, int stackTop, int bci, CallQuaternaryMethodNode callNode = insertChildNode(localNodes, bci + 1, UNCACHED_CALL_QUATERNARY_METHOD, CallQuaternaryMethodNodeGen.class, NODE_CALL_QUATERNARY_METHOD, useCachedNodes); Object arg2 = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); Object arg1 = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); Object arg0 = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); + virtualFrame.clear(stackTop--); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_CALL, mutableData, tracingOrProfilingEnabled); try { @@ -5398,7 +5418,7 @@ private int bytecodeCallMethod(VirtualFrame virtualFrame, int stackTop, int bci, private int bytecodeStoreName(VirtualFrame virtualFrame, int initialStackTop, int bci, int oparg, TruffleString[] localNames, Node[] localNodes, boolean useCachedNodes) { int stackTop = initialStackTop; Object value = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); WriteNameNode writeNameNode = insertChildNode(localNodes, bci, UNCACHED_WRITE_NAME, WriteNameNodeGen.class, NODE_WRITE_NAME, useCachedNodes); writeNameNode.execute(virtualFrame, localNames[oparg], value); return stackTop; @@ -5411,13 +5431,13 @@ private AbstractTruffleException bytecodeRaiseVarargs(VirtualFrame virtualFrame, Object exception; if (count > 1) { cause = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); } else { cause = PNone.NO_VALUE; } if (count > 0) { exception = virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); } else { exception = PNone.NO_VALUE; } @@ -5427,7 +5447,7 @@ private AbstractTruffleException bytecodeRaiseVarargs(VirtualFrame virtualFrame, @InliningCutoff private void raiseUnboundCell(Node[] localNodes, int bci, int oparg, boolean useCachedNodes) { - PRaiseNode raiseNode = insertChildNode(localNodes, bci, UNCACHED_RAISE, PRaiseNodeGen.class, NODE_RAISE, useCachedNodes); + PRaiseCachedNode raiseNode = insertChildNode(localNodes, bci, UNCACHED_RAISE, PRaiseCachedNodeGen.class, NODE_RAISE, useCachedNodes); if (oparg < cellvars.length) { throw raiseNode.raise(PythonBuiltinClassType.UnboundLocalError, ErrorMessages.LOCAL_VAR_REFERENCED_BEFORE_ASSIGMENT, cellvars[oparg]); } else { @@ -5442,7 +5462,7 @@ private int bytecodeImportName(VirtualFrame virtualFrame, Object globals, int in TruffleString modname = localNames[oparg]; int stackTop = initialStackTop; TruffleString[] fromlist = (TruffleString[]) virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); int level = castNode.executeCached(virtualFrame.getObject(stackTop)); ImportNode importNode = insertChildNode(localNodes, bci + 1, UNCACHED_IMPORT, ImportNodeGen.class, NODE_IMPORT, useCachedNodes); Object result = importNode.execute(virtualFrame, modname, globals, fromlist, level); @@ -5466,7 +5486,7 @@ private int bytecodeImportStar(VirtualFrame virtualFrame, int initialStackTop, i int stackTop = initialStackTop; TruffleString importName = localNames[oparg]; int level = (int) virtualFrame.getObject(stackTop); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); ImportStarNode importStarNode = insertChildNode(localNodes, bci, UNCACHED_IMPORT_STAR, ImportStarNodeGen.class, NODE_IMPORT_STAR, useCachedNodes); importStarNode.execute(virtualFrame, importName, level); return stackTop; @@ -5510,29 +5530,48 @@ private static void moveFromStack(VirtualFrame virtualFrame, int start, int CompilerAsserts.partialEvaluationConstant(stop); for (int j = 0, i = start; i < stop; i++, j++) { target[j] = (T) virtualFrame.getObject(i); - virtualFrame.setObject(i, null); + virtualFrame.clear(i); + } + } + + @GenerateInline(false) + @GenerateUncached + abstract static class ObjHashMapPutNode extends Node { + public abstract void execute(VirtualFrame frame, ObjectHashMap map, Object key, Object value); + + @Specialization + static void doIt(VirtualFrame frame, ObjectHashMap map, Object key, Object value, + @Bind Node inliningTarget, + @Cached PyObjectHashNode hashNode, + @Cached ObjectHashMap.PutNode putNode) { + long hash = hashNode.execute(frame, inliningTarget, key); + putNode.put(frame, inliningTarget, map, key, hash, value); } } @ExplodeLoop - private static void moveFromStack(VirtualFrame virtualFrame, int start, int stop, PSet target, HashingCollectionNodes.SetItemNode setItem) { + private static ObjectHashMap moveFromStackToSetHashMap(VirtualFrame virtualFrame, int start, int stop, ObjHashMapPutNode putNode) { CompilerAsserts.partialEvaluationConstant(start); CompilerAsserts.partialEvaluationConstant(stop); + var result = new ObjectHashMap(stop - start, false); for (int i = start; i < stop; i++) { - setItem.executeCached(virtualFrame, target, virtualFrame.getObject(i), PNone.NONE); - virtualFrame.setObject(i, null); + putNode.execute(virtualFrame, result, virtualFrame.getObject(i), PNone.NONE); + virtualFrame.clear(i); } + return result; } @ExplodeLoop - private static void moveFromStack(VirtualFrame virtualFrame, int start, int stop, PDict target, HashingCollectionNodes.SetItemNode setItem) { + private static ObjectHashMap moveFromStackToDictHashMap(VirtualFrame virtualFrame, int start, int stop, ObjHashMapPutNode putNode) { CompilerAsserts.partialEvaluationConstant(start); CompilerAsserts.partialEvaluationConstant(stop); + var result = new ObjectHashMap((stop - start) / 2, false); for (int i = start; i + 1 < stop; i += 2) { - setItem.executeCached(virtualFrame, target, virtualFrame.getObject(i), virtualFrame.getObject(i + 1)); - virtualFrame.setObject(i, null); - virtualFrame.setObject(i + 1, null); + putNode.execute(virtualFrame, result, virtualFrame.getObject(i), virtualFrame.getObject(i + 1)); + virtualFrame.clear(i); + virtualFrame.clear(i + 1); } + return result; } @BytecodeInterpreterSwitch @@ -5543,30 +5582,28 @@ private int bytecodeCollectionFromStack(VirtualFrame virtualFrame, int type, int case CollectionBits.KIND_LIST: { ListFromStackNode storageFromStackNode = insertChildNodeInt(localNodes, nodeIndex, ListFromStackNodeGen.class, LIST_FROM_STACK_NODE, count); SequenceStorage store = storageFromStackNode.execute(virtualFrame, stackTop - count + 1, stackTop + 1); - res = factory.createList(store, storageFromStackNode); + res = PFactory.createList(getLanguage(), store, storageFromStackNode); break; } case CollectionBits.KIND_TUPLE: { TupleFromStackNode storageFromStackNode = insertChildNodeInt(localNodes, nodeIndex, TupleFromStackNodeGen.class, TUPLE_FROM_STACK_NODE, count); SequenceStorage store = storageFromStackNode.execute(virtualFrame, stackTop - count + 1, stackTop + 1); - res = factory.createTuple(store); + res = PFactory.createTuple(getLanguage(), store); break; } case CollectionBits.KIND_SET: { - PSet set = factory.createSet(); - HashingCollectionNodes.SetItemNode newNode = insertChildNode(localNodes, nodeIndex, UNCACHED_SET_ITEM, HashingCollectionNodesFactory.SetItemNodeGen.class, NODE_SET_ITEM, + ObjHashMapPutNode putNode = insertChildNode(localNodes, nodeIndex, UNCACHED_OBJ_HASHMAP_PUT, ObjHashMapPutNodeGen.class, NODE_OBJ_HASHMAP_PUT, useCachedNodes); - moveFromStack(virtualFrame, stackTop - count + 1, stackTop + 1, set, newNode); - res = set; + ObjectHashMap storage = moveFromStackToSetHashMap(virtualFrame, stackTop - count + 1, stackTop + 1, putNode); + res = PFactory.createSet(getLanguage(), new EconomicMapStorage(storage, false)); break; } case CollectionBits.KIND_DICT: { - PDict dict = factory.createDict(); - HashingCollectionNodes.SetItemNode setItem = insertChildNode(localNodes, nodeIndex, UNCACHED_SET_ITEM, HashingCollectionNodesFactory.SetItemNodeGen.class, NODE_SET_ITEM, + ObjHashMapPutNode putNode = insertChildNode(localNodes, nodeIndex, UNCACHED_OBJ_HASHMAP_PUT, ObjHashMapPutNodeGen.class, NODE_OBJ_HASHMAP_PUT, useCachedNodes); assert count % 2 == 0; - moveFromStack(virtualFrame, stackTop - count + 1, stackTop + 1, dict, setItem); - res = dict; + ObjectHashMap storage = moveFromStackToDictHashMap(virtualFrame, stackTop - count + 1, stackTop + 1, putNode); + res = PFactory.createDict(getLanguage(), new EconomicMapStorage(storage, false)); break; } case CollectionBits.KIND_KWORDS: { @@ -5606,14 +5643,14 @@ private void bytecodeCollectionFromCollection(VirtualFrame virtualFrame, int typ } case CollectionBits.KIND_SET: { SetNodes.ConstructSetNode constructNode = insertChildNode(localNodes, nodeIndex, UNCACHED_CONSTRUCT_SET, SetNodesFactory.ConstructSetNodeGen.class, NODE_CONSTRUCT_SET, useCachedNodes); - result = constructNode.executeWith(virtualFrame, sourceCollection); + result = constructNode.execute(virtualFrame, sourceCollection); break; } case CollectionBits.KIND_DICT: { // TODO create uncached node HashingStorage.InitNode initNode = insertChildNode(localNodes, nodeIndex, HashingStorageFactory.InitNodeGen.class, NODE_HASHING_STORAGE_INIT); HashingStorage storage = initNode.execute(virtualFrame, sourceCollection, PKeyword.EMPTY_KEYWORDS); - result = factory.createDict(storage); + result = PFactory.createDict(getLanguage(), storage); break; } case CollectionBits.KIND_OBJECT: { @@ -5684,9 +5721,9 @@ private int bytecodeCollectionAddCollection(VirtualFrame virtualFrame, int type, } default: CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.getUncached().raise(SystemError, ErrorMessages.INVALID_TYPE_FOR_S, "COLLECTION_ADD_COLLECTION"); + throw PRaiseNode.raiseStatic(this, SystemError, ErrorMessages.INVALID_TYPE_FOR_S, "COLLECTION_ADD_COLLECTION"); } - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); virtualFrame.setObject(stackTop, result); return stackTop; } @@ -5712,21 +5749,21 @@ private int bytecodeAddToCollection(VirtualFrame virtualFrame, int initialStackT HashingCollectionNodes.SetItemNode setItem = insertChildNode(localNodes, nodeIndex, UNCACHED_SET_ITEM, HashingCollectionNodesFactory.SetItemNodeGen.class, NODE_SET_ITEM, useCachedNodes); setItem.executeCached(virtualFrame, (PDict) collection, key, item); - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); break; } default: CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.getUncached().raise(SystemError, ErrorMessages.INVALID_TYPE_FOR_S, "ADD_TO_COLLECTION"); + throw PRaiseNode.raiseStatic(this, SystemError, ErrorMessages.INVALID_TYPE_FOR_S, "ADD_TO_COLLECTION"); } - virtualFrame.setObject(stackTop--, null); + virtualFrame.clear(stackTop--); return stackTop; } @BytecodeInterpreterSwitch private void bytecodeTupleFromList(VirtualFrame virtualFrame, int stackTop) { PList list = (PList) virtualFrame.getObject(stackTop); - Object result = factory.createTuple(list.getSequenceStorage()); + Object result = PFactory.createTuple(getLanguage(), list.getSequenceStorage()); virtualFrame.setObject(stackTop, result); } @@ -5734,7 +5771,7 @@ private void bytecodeTupleFromList(VirtualFrame virtualFrame, int stackTop) { private void bytecodeFrozensetFromList(VirtualFrame virtualFrame, int stackTop, int nodeIndex, Node[] localNodes) { PList list = (PList) virtualFrame.getObject(stackTop); HashingStorageFromListSequenceStorageNode node = insertChildNode(localNodes, nodeIndex, HashingStorageFromListSequenceStorageNodeGen.class, NODE_HASHING_STORAGE_FROM_SEQUENCE); - Object result = factory.createFrozenSet(node.execute(virtualFrame, list.getSequenceStorage())); + Object result = PFactory.createFrozenSet(getLanguage(), node.execute(virtualFrame, list.getSequenceStorage())); virtualFrame.setObject(stackTop, result); } @@ -5775,7 +5812,7 @@ private static int unwindBlock(VirtualFrame virtualFrame, int stackTop, int stac CompilerAsserts.partialEvaluationConstant(stackTop); CompilerAsserts.partialEvaluationConstant(stackTopBeforeBlock); for (int i = stackTop; i > stackTopBeforeBlock; i--) { - virtualFrame.setObject(i, null); + virtualFrame.clear(i); } return stackTopBeforeBlock; } @@ -5890,7 +5927,7 @@ protected byte[] extractCode() { * * TODO We should revisit this when the AST interpreter is removed. */ - return MarshalModuleBuiltins.serializeCodeUnit(co); + return MarshalModuleBuiltins.serializeCodeUnit(this, PythonContext.get(this), co); } @Override @@ -5900,7 +5937,7 @@ protected boolean isCloneUninitializedSupported() { @Override protected RootNode cloneUninitialized() { - return new PBytecodeRootNode(PythonLanguage.get(this), getFrameDescriptor(), getSignature(), co, source, parserErrorCallback); + return new PBytecodeRootNode(getLanguage(), getFrameDescriptor(), getSignature(), co, source, parserErrorCallback); } public void triggerDeferredDeprecationWarnings() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupInheritedSlotNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PRaiseCachedNode.java similarity index 62% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupInheritedSlotNode.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PRaiseCachedNode.java index 9bf93bdaa3..965bae46d2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupInheritedSlotNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PRaiseCachedNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,35 +38,36 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.nodes.attributes; +package com.oracle.graal.python.nodes.bytecode; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.strings.TruffleString; -/** - * Variant of {@link LookupInheritedAttributeNode} for special attributes cached in internal slots. - * Unlike {@link LookupInheritedAttributeNode}, this node may return - * {@link com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor}. - * - * @see SpecialMethodSlot - */ -public final class LookupInheritedSlotNode extends PNodeWithContext { +@GenerateUncached +abstract class PRaiseCachedNode extends Node { + public final PException raise(PythonBuiltinClassType type, TruffleString format, Object... formatArgs) { + throw execute(type, format, formatArgs); + } - @Child private LookupCallableSlotInMRONode lookupInMRONode; - @Child private GetClassNode getClassNode = GetClassNode.create(); + protected abstract PException execute(PythonBuiltinClassType type, TruffleString format, Object[] formatArgs); - private LookupInheritedSlotNode(SpecialMethodSlot slot) { - lookupInMRONode = LookupCallableSlotInMRONode.create(slot); + @Specialization + PException doRaise(PythonBuiltinClassType type, TruffleString format, Object[] formatArgs) { + throw PRaiseNode.raiseStatic(this, type, format, formatArgs); } @NeverDefault - public static LookupInheritedSlotNode create(SpecialMethodSlot slot) { - return new LookupInheritedSlotNode(slot); + public static PRaiseCachedNode create() { + return PRaiseCachedNodeGen.create(); } - public Object execute(Object object) { - return lookupInMRONode.execute(getClassNode.executeCached(object)); + public static PRaiseCachedNode getUncached() { + return PRaiseCachedNodeGen.getUncached(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PrintExprNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PrintExprNode.java index c8e0576ba8..8e3044132c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PrintExprNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PrintExprNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -55,6 +55,7 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; @@ -74,11 +75,12 @@ void print(VirtualFrame frame, Object object, Object displayhook = lookupAttr.execute(frame, inliningTarget, sysModule, BuiltinNames.T_DISPLAYHOOK); if (displayhook == PNone.NO_VALUE) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(this, RuntimeError, ErrorMessages.LOST_SYSDISPLAYHOOK); + throw PRaiseNode.raiseStatic(this, RuntimeError, ErrorMessages.LOST_SYSDISPLAYHOOK); } callNode.execute(frame, displayhook, object); } + @NeverDefault public static PrintExprNode create() { return PrintExprNodeGen.create(); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/RaiseNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/RaiseNode.java index 4202c74e1e..14cd3802a9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/RaiseNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/RaiseNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -51,6 +51,7 @@ import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.ImportStatic; +import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.VirtualFrame; @@ -95,12 +96,11 @@ static void setCause(VirtualFrame frame, Object exception, Object causeClass, @Exclusive @Cached InlinedBranchProfile baseCheckFailedProfile, @Exclusive @Cached ValidExceptionNode validException, @Exclusive @Cached CallNode callConstructor, - @Exclusive @Cached PRaiseNode.Lazy raise, @Exclusive @Cached PyExceptionInstanceCheckNode check, @Exclusive @Cached ExceptionNodes.SetCauseNode setCauseNode) { if (!validException.execute(frame, causeClass)) { baseCheckFailedProfile.enter(inliningTarget); - throw raise.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.EXCEPTION_CAUSES_MUST_DERIVE_FROM_BASE_EX); + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.EXCEPTION_CAUSES_MUST_DERIVE_FROM_BASE_EX); } Object cause = callConstructor.execute(frame, causeClass); if (check.execute(inliningTarget, cause)) { @@ -118,11 +118,10 @@ static void setCause(VirtualFrame frame, Object exception, Object causeClass, // raise * from @Specialization(guards = {"!check.execute(inliningTarget, cause)", "!isTypeNode.execute(inliningTarget, cause)"}, limit = "1") static void setCause(@SuppressWarnings("unused") VirtualFrame frame, @SuppressWarnings("unused") Object exception, @SuppressWarnings("unused") Object cause, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @Exclusive @SuppressWarnings("unused") @Cached TypeNodes.IsTypeNode isTypeNode, @SuppressWarnings("unused") @Exclusive @Cached PyExceptionInstanceCheckNode check, - @Cached PRaiseNode raise) { - throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.EXCEPTION_CAUSES_MUST_DERIVE_FROM_BASE_EX); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.EXCEPTION_CAUSES_MUST_DERIVE_FROM_BASE_EX); } } @@ -139,7 +138,7 @@ static void reraise(VirtualFrame frame, @SuppressWarnings("unused") PNone type, } else if (caughtException != null) { throw caughtException; } else { - throw raise.raise(RuntimeError, ErrorMessages.NO_ACTIVE_EX_TO_RERAISE); + throw raise.raise(inliningTarget, RuntimeError, ErrorMessages.NO_ACTIVE_EX_TO_RERAISE); } } @@ -178,11 +177,11 @@ public static void doRaiseNative(@SuppressWarnings("unused") VirtualFrame frame, throw PRaiseNode.raiseExceptionObject(inliningTarget, exception); } - private static void checkBaseClass(VirtualFrame frame, Node inliningTarget, Object pythonClass, ValidExceptionNode validException, PRaiseNode.Lazy raise, + private static void checkBaseClass(VirtualFrame frame, Node inliningTarget, Object pythonClass, ValidExceptionNode validException, PRaiseNode raise, InlinedBranchProfile baseCheckFailedProfile) { if (!validException.execute(frame, pythonClass)) { baseCheckFailedProfile.enter(inliningTarget); - throw raiseNoException(raise.get(inliningTarget)); + throw raiseNoException(inliningTarget, raise); } } @@ -195,13 +194,13 @@ public static void doRaise(@SuppressWarnings("unused") VirtualFrame frame, Objec @Exclusive @Cached CallNode callConstructor, @Exclusive @Cached PyExceptionInstanceCheckNode check, @Exclusive @Cached InlinedBranchProfile baseCheckFailedProfile, - @Exclusive @Cached PRaiseNode.Lazy raise) { + @Exclusive @Cached PRaiseNode raise) { checkBaseClass(frame, inliningTarget, pythonClass, validException, raise, baseCheckFailedProfile); Object newException = callConstructor.execute(frame, pythonClass); if (check.execute(inliningTarget, newException)) { throw PRaiseNode.raiseExceptionObject(inliningTarget, newException); } else { - throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.SHOULD_HAVE_RETURNED_EXCEPTION, pythonClass, newException); + throw raise.raise(inliningTarget, TypeError, ErrorMessages.SHOULD_HAVE_RETURNED_EXCEPTION, pythonClass, newException); } } @@ -211,7 +210,7 @@ public static void doRaise(@SuppressWarnings("unused") VirtualFrame frame, Objec @Bind("this") Node inliningTarget, @Exclusive @SuppressWarnings("unused") @Cached TypeNodes.IsTypeNode isTypeNode, @Exclusive @Cached ValidExceptionNode validException, - @Exclusive @Cached PRaiseNode.Lazy raise, + @Exclusive @Cached PRaiseNode raise, @Exclusive @Cached CallNode callConstructor, @Exclusive @Cached PyExceptionInstanceCheckNode check, @Exclusive @Cached InlinedBranchProfile baseCheckFailedProfile, @@ -222,7 +221,7 @@ public static void doRaise(@SuppressWarnings("unused") VirtualFrame frame, Objec setExceptionCauseNode.execute(frame, newException, cause); throw PRaiseNode.raiseExceptionObject(inliningTarget, newException); } else { - throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.SHOULD_HAVE_RETURNED_EXCEPTION, pythonClass, newException); + throw raise.raise(inliningTarget, TypeError, ErrorMessages.SHOULD_HAVE_RETURNED_EXCEPTION, pythonClass, newException); } } @@ -232,7 +231,7 @@ public static void doRaise(@SuppressWarnings("unused") VirtualFrame frame, Objec public static void doRaise(VirtualFrame frame, Object exception, Object cause, @SuppressWarnings("unused") boolean rootNodeVisible, @Bind("this") Node inliningTarget, @CachedLibrary(limit = "1") InteropLibrary lib, - @Exclusive @Cached PRaiseNode.Lazy raise) { + @Exclusive @Cached PRaiseNode raise) { if (lib.isException(exception)) { try { throw lib.throwException(exception); @@ -240,13 +239,14 @@ public static void doRaise(VirtualFrame frame, Object exception, Object cause, @ throw CompilerDirectives.shouldNotReachHere(); } } - throw raiseNoException(raise.get(inliningTarget)); + throw raiseNoException(inliningTarget, raise); } - private static PException raiseNoException(PRaiseNode raise) { - throw raise.raise(TypeError, ErrorMessages.EXCEPTIONS_MUST_DERIVE_FROM_BASE_EX); + private static PException raiseNoException(Node inliningTarget, PRaiseNode raise) { + throw raise.raise(inliningTarget, TypeError, ErrorMessages.EXCEPTIONS_MUST_DERIVE_FROM_BASE_EX); } + @NeverDefault public static RaiseNode create() { return RaiseNodeGen.create(); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SendNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SendNode.java index 96fcfa8022..b1627795ec 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SendNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SendNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,7 +47,10 @@ import com.oracle.graal.python.builtins.objects.exception.StopIterationBuiltins; import com.oracle.graal.python.builtins.objects.generator.CommonGeneratorBuiltins; import com.oracle.graal.python.builtins.objects.generator.PGenerator; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode; +import com.oracle.graal.python.lib.IteratorExhausted; import com.oracle.graal.python.lib.PyIterCheckNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.nodes.PNodeWithContext; @@ -61,6 +64,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; @GenerateInline(false) // used in BCI root node public abstract class SendNode extends PNodeWithContext { @@ -84,23 +88,34 @@ static boolean doGenerator(VirtualFrame virtualFrame, int stackTop, PGenerator g } } - @Specialization(guards = "iterCheck.execute(inliningTarget, iter)", limit = "1") + @Specialization(guards = "hasIterSlot(slots)", limit = "1") static boolean doIterator(VirtualFrame virtualFrame, int stackTop, Object iter, @SuppressWarnings("unused") PNone arg, @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached PyIterCheckNode iterCheck, - @Cached GetNextNode getNextNode, + @SuppressWarnings("unused") @Cached GetObjectSlotsNode getSlots, + @Bind("getSlots.execute(inliningTarget, iter)") TpSlots slots, + @Cached CallSlotTpIterNextNode callIterNext, + @Exclusive @Cached InlinedBranchProfile exhaustedNoException, @Exclusive @Cached IsBuiltinObjectProfile stopIterationProfile, @Exclusive @Cached StopIterationBuiltins.StopIterationValueNode getValue) { try { - Object value = getNextNode.execute(virtualFrame, iter); + Object value = callIterNext.execute(virtualFrame, inliningTarget, slots.tp_iternext(), iter); virtualFrame.setObject(stackTop, value); return false; + } catch (IteratorExhausted e) { + exhaustedNoException.enter(inliningTarget); + virtualFrame.setObject(stackTop, null); + virtualFrame.setObject(stackTop - 1, PNone.NONE); + return true; } catch (PException e) { handleException(virtualFrame, e, inliningTarget, stopIterationProfile, getValue, stackTop); return true; } } + protected static boolean hasIterSlot(TpSlots slots) { + return PyIterCheckNode.checkSlots(slots); + } + @Fallback static boolean doOther(VirtualFrame virtualFrame, int stackTop, Object obj, Object arg, @Bind("this") Node inliningTarget, diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupAnnotationsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupAnnotationsNode.java index ab7481b702..af6bb2069b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupAnnotationsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupAnnotationsNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,6 +43,7 @@ import static com.oracle.graal.python.builtins.objects.function.PArguments.getSpecialArgument; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___ANNOTATIONS__; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.dict.PDict; @@ -57,10 +58,10 @@ import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -70,11 +71,13 @@ import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.profiles.InlinedConditionProfile; @GenerateUncached @ImportStatic(PArguments.class) @GenerateInline(false) // used in BCI root node +@OperationProxy.Proxyable public abstract class SetupAnnotationsNode extends PNodeWithContext { public abstract void execute(Frame frame); @@ -98,13 +101,14 @@ public abstract static class SetupAnnotationsFromDictOrModuleNode extends PNodeW public abstract void execute(Frame frame, Node inliningTarget, Object locals); @Specialization - static void doModule(PythonModule locals, + static void doModule(Node inliningTarget, PythonModule locals, @Cached(inline = false) ReadAttributeFromObjectNode read, @Cached(inline = false) WriteAttributeToObjectNode write, - @Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { + @Cached InlinedBranchProfile create) { Object annotations = read.execute(locals, T___ANNOTATIONS__); if (annotations == PNone.NO_VALUE) { - write.execute(locals, T___ANNOTATIONS__, factory.createDict()); + create.enter(inliningTarget); + write.execute(locals, T___ANNOTATIONS__, PFactory.createDict(PythonLanguage.get(inliningTarget))); } } @@ -112,10 +116,11 @@ static void doModule(PythonModule locals, static void doBuiltinDict(VirtualFrame frame, Node inliningTarget, PDict locals, @Cached PyDictGetItem getItem, @Cached PyDictSetItem setItem, - @Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { + @Cached InlinedBranchProfile create) { Object annotations = getItem.execute(frame, inliningTarget, locals, T___ANNOTATIONS__); if (annotations == null) { - setItem.execute(frame, inliningTarget, locals, T___ANNOTATIONS__, factory.createDict()); + create.enter(inliningTarget); + setItem.execute(frame, inliningTarget, locals, T___ANNOTATIONS__, PFactory.createDict(PythonLanguage.get(inliningTarget))); } } @@ -123,13 +128,12 @@ static void doBuiltinDict(VirtualFrame frame, Node inliningTarget, PDict locals, static void doOther(VirtualFrame frame, Node inliningTarget, Object locals, @Cached PyObjectGetItem getItem, @Cached PyObjectSetItem setItem, - @Cached IsBuiltinObjectProfile errorProfile, - @Shared("factory") @Cached(inline = false) PythonObjectFactory factory) { + @Cached IsBuiltinObjectProfile errorProfile) { try { getItem.execute(frame, inliningTarget, locals, T___ANNOTATIONS__); } catch (PException e) { e.expect(inliningTarget, PythonBuiltinClassType.KeyError, errorProfile); - setItem.execute(frame, inliningTarget, locals, T___ANNOTATIONS__, factory.createDict()); + setItem.execute(frame, inliningTarget, locals, T___ANNOTATIONS__, PFactory.createDict(PythonLanguage.get(inliningTarget))); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupAwithNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupAwithNode.java index b680d4ea7e..5c5bdfafd9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupAwithNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupAwithNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,27 +41,26 @@ package com.oracle.graal.python.nodes.bytecode; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AENTER__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AEXIT__; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; +import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @GenerateUncached -@ImportStatic(SpecialMethodSlot.class) @GenerateInline(false) // used in BCI root node public abstract class SetupAwithNode extends PNodeWithContext { public abstract int execute(Frame frame, int stackTop); @@ -70,20 +69,20 @@ public abstract class SetupAwithNode extends PNodeWithContext { static int setup(VirtualFrame frame, int stackTopIn, @Bind("this") Node inliningTarget, @Cached GetClassNode getClassNode, - @Cached(parameters = "AEnter") LookupSpecialMethodSlotNode lookupAEnter, - @Cached(parameters = "AExit") LookupSpecialMethodSlotNode lookupAExit, + @Cached LookupSpecialMethodNode.Dynamic lookupAEnter, + @Cached LookupSpecialMethodNode.Dynamic lookupAExit, @Cached CallUnaryMethodNode callEnter, @Cached PRaiseNode raiseNode) { int stackTop = stackTopIn; Object contextManager = frame.getObject(stackTop); Object type = getClassNode.execute(inliningTarget, contextManager); - Object enter = lookupAEnter.execute(frame, type, contextManager); + Object enter = lookupAEnter.execute(frame, inliningTarget, type, T___AENTER__, contextManager); if (enter == PNone.NO_VALUE) { - throw raiseNode.raise(TypeError, ErrorMessages.N_OBJECT_DOES_NOT_SUPPORT_THE_ASYNC_CONTEXT_MANAGER_PROTOCOL, type); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.N_OBJECT_DOES_NOT_SUPPORT_THE_ASYNC_CONTEXT_MANAGER_PROTOCOL, type); } - Object exit = lookupAExit.execute(frame, type, contextManager); + Object exit = lookupAExit.execute(frame, inliningTarget, type, T___AEXIT__, contextManager); if (exit == PNone.NO_VALUE) { - throw raiseNode.raise(TypeError, ErrorMessages.N_OBJECT_DOES_NOT_SUPPORT_THE_ASYNC_CONTEXT_MANAGER_PROTOCOL_AEXIT, type); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.N_OBJECT_DOES_NOT_SUPPORT_THE_ASYNC_CONTEXT_MANAGER_PROTOCOL_AEXIT, type); } Object res = callEnter.executeObject(frame, enter, contextManager); frame.setObject(++stackTop, exit); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupWithNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupWithNode.java index ab61c3e4f6..935368bd8d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupWithNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupWithNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,27 +41,26 @@ package com.oracle.graal.python.nodes.bytecode; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ENTER__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___EXIT__; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; +import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @GenerateUncached -@ImportStatic(SpecialMethodSlot.class) @GenerateInline(false) // used in BCI root node public abstract class SetupWithNode extends PNodeWithContext { public abstract int execute(Frame frame, int stackTop); @@ -70,20 +69,20 @@ public abstract class SetupWithNode extends PNodeWithContext { static int setup(VirtualFrame frame, int stackTopIn, @Bind("this") Node inliningTarget, @Cached GetClassNode getClassNode, - @Cached(parameters = "Enter") LookupSpecialMethodSlotNode lookupEnter, - @Cached(parameters = "Exit") LookupSpecialMethodSlotNode lookupExit, + @Cached LookupSpecialMethodNode.Dynamic lookupEnter, + @Cached LookupSpecialMethodNode.Dynamic lookupExit, @Cached CallUnaryMethodNode callEnter, @Cached PRaiseNode raiseNode) { int stackTop = stackTopIn; Object contextManager = frame.getObject(stackTop); Object type = getClassNode.execute(inliningTarget, contextManager); - Object enter = lookupEnter.execute(frame, type, contextManager); + Object enter = lookupEnter.execute(frame, inliningTarget, type, T___ENTER__, contextManager); if (enter == PNone.NO_VALUE) { - throw raiseNode.raise(TypeError, ErrorMessages.N_OBJECT_DOES_NOT_SUPPORT_CONTEXT_MANAGER_PROTOCOL, type); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.N_OBJECT_DOES_NOT_SUPPORT_CONTEXT_MANAGER_PROTOCOL, type); } - Object exit = lookupExit.execute(frame, type, contextManager); + Object exit = lookupExit.execute(frame, inliningTarget, type, T___EXIT__, contextManager); if (exit == PNone.NO_VALUE) { - throw raiseNode.raise(TypeError, ErrorMessages.N_OBJECT_DOES_NOT_SUPPORT_CONTEXT_MANAGER_PROTOCOL_EXIT, type); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.N_OBJECT_DOES_NOT_SUPPORT_CONTEXT_MANAGER_PROTOCOL_EXIT, type); } Object res = callEnter.executeObject(frame, enter, contextManager); frame.setObject(++stackTop, exit); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/UnpackExNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/UnpackExNode.java index 9813e6c1da..2d143f816d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/UnpackExNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/UnpackExNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,10 +43,12 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.common.SequenceNodes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.list.PList; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; @@ -54,14 +56,13 @@ import com.oracle.graal.python.nodes.builtins.ListNodes; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; @@ -82,8 +83,8 @@ static int doUnpackSequence(VirtualFrame frame, int initialStackTop, PSequence s @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode, @Exclusive @Cached SequenceStorageNodes.GetItemScalarNode getItemNode, @Exclusive @Cached SequenceStorageNodes.GetItemSliceNode getItemSliceNode, - @Shared("factory") @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Exclusive @Cached PRaiseNode raiseNode) { CompilerAsserts.partialEvaluationConstant(countBefore); CompilerAsserts.partialEvaluationConstant(countAfter); int resultStackTop = initialStackTop + countBefore + 1 + countAfter; @@ -92,10 +93,10 @@ static int doUnpackSequence(VirtualFrame frame, int initialStackTop, PSequence s int len = storage.length(); int starLen = len - countBefore - countAfter; if (starLen < 0) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK_EX, countBefore + countAfter, len); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK_EX, countBefore + countAfter, len); } stackTop = moveItemsToStack(frame, inliningTarget, storage, stackTop, 0, countBefore, getItemNode); - PList starList = factory.createList(getItemSliceNode.execute(storage, countBefore, countBefore + starLen, 1, starLen)); + PList starList = PFactory.createList(language, getItemSliceNode.execute(storage, countBefore, countBefore + starLen, 1, starLen)); frame.setObject(stackTop--, starList); moveItemsToStack(frame, inliningTarget, storage, stackTop, len - countAfter, countAfter, getItemNode); return resultStackTop; @@ -105,14 +106,13 @@ static int doUnpackSequence(VirtualFrame frame, int initialStackTop, PSequence s static int doUnpackIterable(VirtualFrame frame, int initialStackTop, Object collection, int countBefore, int countAfter, @Bind("this") Node inliningTarget, @Cached PyObjectGetIter getIter, - @Cached GetNextNode getNextNode, + @Cached PyIterNextNode nextNode, @Cached IsBuiltinObjectProfile notIterableProfile, - @Cached IsBuiltinObjectProfile stopIterationProfile, @Cached ListNodes.ConstructListNode constructListNode, @Exclusive @Cached SequenceStorageNodes.GetItemScalarNode getItemNode, @Exclusive @Cached SequenceStorageNodes.GetItemSliceNode getItemSliceNode, - @Shared("factory") @Cached PythonObjectFactory factory, - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Exclusive @Cached PRaiseNode raiseNode) { CompilerAsserts.partialEvaluationConstant(countBefore); CompilerAsserts.partialEvaluationConstant(countAfter); int resultStackTop = initialStackTop + countBefore + 1 + countAfter; @@ -122,20 +122,20 @@ static int doUnpackIterable(VirtualFrame frame, int initialStackTop, Object coll iterator = getIter.execute(frame, inliningTarget, collection); } catch (PException e) { e.expectTypeError(inliningTarget, notIterableProfile); - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CANNOT_UNPACK_NON_ITERABLE, collection); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANNOT_UNPACK_NON_ITERABLE, collection); } - stackTop = moveItemsToStack(frame, inliningTarget, iterator, stackTop, 0, countBefore, countBefore + countAfter, getNextNode, stopIterationProfile, raiseNode); + stackTop = moveItemsToStack(frame, inliningTarget, iterator, stackTop, 0, countBefore, countBefore + countAfter, nextNode, raiseNode); PList starAndAfter = constructListNode.execute(frame, iterator); SequenceStorage storage = starAndAfter.getSequenceStorage(); int lenAfter = storage.length(); if (lenAfter < countAfter) { - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK_EX, countBefore + countAfter, countBefore + lenAfter); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK_EX, countBefore + countAfter, countBefore + lenAfter); } if (countAfter == 0) { frame.setObject(stackTop, starAndAfter); } else { int starLen = lenAfter - countAfter; - PList starList = factory.createList(getItemSliceNode.execute(storage, 0, starLen, 1, starLen)); + PList starList = PFactory.createList(language, getItemSliceNode.execute(storage, 0, starLen, 1, starLen)); frame.setObject(stackTop--, starList); moveItemsToStack(frame, inliningTarget, storage, stackTop, starLen, countAfter, getItemNode); } @@ -143,17 +143,16 @@ static int doUnpackIterable(VirtualFrame frame, int initialStackTop, Object coll } @ExplodeLoop - private static int moveItemsToStack(VirtualFrame frame, Node inliningTarget, Object iterator, int initialStackTop, int offset, int length, int totalLength, GetNextNode getNextNode, - IsBuiltinObjectProfile stopIterationProfile, PRaiseNode.Lazy raiseNode) { + private static int moveItemsToStack(VirtualFrame frame, Node inliningTarget, Object iterator, int initialStackTop, int offset, int length, int totalLength, PyIterNextNode nextNode, + PRaiseNode raiseNode) { CompilerAsserts.partialEvaluationConstant(length); int stackTop = initialStackTop; for (int i = 0; i < length; i++) { try { - Object item = getNextNode.execute(frame, iterator); + Object item = nextNode.execute(frame, inliningTarget, iterator); frame.setObject(stackTop--, item); - } catch (PException e) { - e.expectStopIteration(inliningTarget, stopIterationProfile); - throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK_EX, totalLength, offset + i); + } catch (IteratorExhausted e) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK_EX, totalLength, offset + i); } } return stackTop; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/UnpackSequenceNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/UnpackSequenceNode.java index ba0058e701..a2a4d5e5d9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/UnpackSequenceNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/UnpackSequenceNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,7 +45,8 @@ import com.oracle.graal.python.builtins.objects.common.SequenceNodes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; -import com.oracle.graal.python.lib.GetNextNode; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; @@ -90,9 +91,9 @@ static int doUnpackSequence(VirtualFrame frame, int initialStackTop, PSequence s } } else { if (len < count) { - throw raiseNode.raise(ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK, count, len); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK, count, len); } else { - throw raiseNode.raise(ValueError, ErrorMessages.TOO_MANY_VALUES_TO_UNPACK, count); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.TOO_MANY_VALUES_TO_UNPACK, count); } } return resultStackTop; @@ -103,10 +104,8 @@ static int doUnpackSequence(VirtualFrame frame, int initialStackTop, PSequence s static int doUnpackIterable(Frame frame, int initialStackTop, Object collection, int count, @Bind("this") Node inliningTarget, @Cached PyObjectGetIter getIter, - @Cached GetNextNode getNextNode, + @Cached PyIterNextNode nextNode, @Cached IsBuiltinObjectProfile notIterableProfile, - @Cached IsBuiltinObjectProfile stopIterationProfile1, - @Cached IsBuiltinObjectProfile stopIterationProfile2, @Shared("raise") @Cached PRaiseNode raiseNode) { CompilerAsserts.partialEvaluationConstant(count); int resultStackTop = initialStackTop + count; @@ -116,24 +115,22 @@ static int doUnpackIterable(Frame frame, int initialStackTop, Object collection, iterator = getIter.execute(frame, inliningTarget, collection); } catch (PException e) { e.expectTypeError(inliningTarget, notIterableProfile); - throw raiseNode.raise(TypeError, ErrorMessages.CANNOT_UNPACK_NON_ITERABLE, collection); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANNOT_UNPACK_NON_ITERABLE, collection); } for (int i = 0; i < count; i++) { try { - Object item = getNextNode.execute(frame, iterator); + Object item = nextNode.execute(frame, inliningTarget, iterator); frame.setObject(stackTop--, item); - } catch (PException e) { - e.expectStopIteration(inliningTarget, stopIterationProfile1); - throw raiseNode.raise(ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK, count, i); + } catch (IteratorExhausted e) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK, count, i); } } try { - getNextNode.execute(frame, iterator); - } catch (PException e) { - e.expectStopIteration(inliningTarget, stopIterationProfile2); + nextNode.execute(frame, inliningTarget, iterator); + } catch (IteratorExhausted e) { return resultStackTop; } - throw raiseNode.raise(ValueError, ErrorMessages.TOO_MANY_VALUES_TO_UNPACK, count); + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.TOO_MANY_VALUES_TO_UNPACK, count); } public static UnpackSequenceNode create() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/instrumentation/InstrumentationSupport.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/instrumentation/InstrumentationSupport.java index ca1734135a..28c0807e52 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/instrumentation/InstrumentationSupport.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/instrumentation/InstrumentationSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,7 +40,7 @@ */ package com.oracle.graal.python.nodes.bytecode.instrumentation; -import com.oracle.graal.python.compiler.CodeUnit; +import com.oracle.graal.python.compiler.BytecodeCodeUnit; import com.oracle.graal.python.compiler.OpCodes; import com.oracle.graal.python.nodes.BuiltinNames; import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode; @@ -62,7 +62,7 @@ * @see InstrumentationRoot */ public final class InstrumentationSupport extends Node { - final CodeUnit code; + final BytecodeCodeUnit code; @Children InstrumentedBytecodeStatement[] statements; /* * When instrumentation is active, this array is used instead of PBytecodeRootNode#adoptedNodes diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/BytecodeDSLCodeUnit.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/BytecodeDSLCodeUnit.java new file mode 100644 index 0000000000..d43796c1ec --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/BytecodeDSLCodeUnit.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.nodes.bytecode_dsl; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.oracle.graal.python.builtins.modules.MarshalModuleBuiltins; +import com.oracle.graal.python.builtins.modules.MarshalModuleBuiltins.PBytecodeDSLSerializer; +import com.oracle.graal.python.compiler.CodeUnit; +import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.bytecode.BytecodeRootNodes; +import com.oracle.truffle.api.bytecode.serialization.BytecodeSerializer; +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.strings.TruffleString; + +public final class BytecodeDSLCodeUnit extends CodeUnit { + /* + * A {@link BytecodeDSLCodeUnit} is a context-independent representation of a root node. It + * contains the bytes produced from Bytecode DSL serialization. + * + * Since it is expensive to serialize every root node, we perform serialization lazily using the + * {@link BytecodeNodes} produced during parsing. + * + * When this code unit is directly instantiated via unmarshaling, there is no {@link + * BytecodeNodes}; instead, we store the serialized bytes directly. + */ + private volatile byte[] serialized; + private final BytecodeRootNodes nodes; + public final int classcellIndex; + public final int selfIndex; + + public BytecodeDSLCodeUnit(TruffleString name, TruffleString qualname, int argCount, int kwOnlyArgCount, int positionalOnlyArgCount, int flags, TruffleString[] names, TruffleString[] varnames, + TruffleString[] cellvars, TruffleString[] freevars, int[] cell2arg, Object[] constants, int startLine, int startColumn, int endLine, int endColumn, + int classcellIndex, int selfIndex, byte[] serialized, BytecodeRootNodes nodes) { + super(name, qualname, argCount, kwOnlyArgCount, positionalOnlyArgCount, flags, names, varnames, cellvars, freevars, cell2arg, constants, startLine, startColumn, endLine, endColumn); + // Only one of these fields should be set. The other gets computed dynamically. + assert serialized == null ^ nodes == null; + this.serialized = serialized; + this.nodes = nodes; + this.classcellIndex = classcellIndex; + this.selfIndex = selfIndex; + } + + @TruffleBoundary + public PBytecodeDSLRootNode createRootNode(PythonContext context, Source source) { + byte[] toDeserialize = getSerialized(context); + BytecodeRootNodes deserialized = MarshalModuleBuiltins.deserializeBytecodeNodes(context, source, toDeserialize); + assert deserialized.count() == 1; + PBytecodeDSLRootNode result = deserialized.getNode(0); + result.setMetadata(this, null); + return result; + } + + public byte[] getSerialized(PythonContext context) { + CompilerAsserts.neverPartOfCompilation(); + byte[] result = serialized; + if (result == null) { + synchronized (this) { + result = serialized; + if (result == null) { + result = serialized = computeSerialized(context); + } + } + } + return result; + } + + @SuppressWarnings("unchecked") + @TruffleBoundary + private byte[] computeSerialized(PythonContext context) { + try { + BytecodeSerializer serializer = new PBytecodeDSLSerializer(context); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + nodes.serialize(new DataOutputStream(bytes), serializer); + return bytes.toByteArray(); + } catch (IOException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + + public TruffleString getDocstring() { + // The first constant in the code unit is the docstring (if available) or PNone. + if (constants.length > 0 && constants[0] instanceof TruffleString docstring) { + return docstring; + } + return null; + } + + @Override + protected void dumpBytecode(StringBuilder sb, boolean optimized) { + for (int i = 0; i < nodes.count(); i++) { + if (i != 0) { + sb.append('\n'); + } + sb.append(nodes.getNode(i).dump()); + sb.append('\n'); // dump does not print newline at the end + } + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/CallArithmeticRootNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/BytecodeDSLFrameInfo.java similarity index 61% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/CallArithmeticRootNode.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/BytecodeDSLFrameInfo.java index 3fc2045168..1ef3e7a87e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/CallArithmeticRootNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/BytecodeDSLFrameInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,54 +38,47 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.nodes.expression; +package com.oracle.graal.python.nodes.bytecode_dsl; -import com.oracle.graal.python.nodes.PRootNode; -import com.oracle.graal.python.runtime.ExecutionContext.CalleeContext; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.TruffleLanguage; -import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.graal.python.compiler.CodeUnit; +import com.oracle.graal.python.nodes.bytecode.FrameInfo; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.frame.Frame; -/** - * A simple base class for root nodes that call an arithmetic operation. - */ -abstract class CallArithmeticRootNode extends PRootNode { - - @Child private CalleeContext calleeContext; +public class BytecodeDSLFrameInfo implements FrameInfo { + @CompilationFinal PBytecodeDSLRootNode rootNode; - protected CallArithmeticRootNode(TruffleLanguage language) { - super(language); + /** + * The root node cannot be created without a frame descriptor, which cannot be created without + * the frame info, so we have to set the root node after the frame info is constructed. + */ + void setRootNode(PBytecodeDSLRootNode rootNode) { + this.rootNode = rootNode; } @Override - public boolean isInternal() { - return true; + public PBytecodeDSLRootNode getRootNode() { + return rootNode; } @Override - public boolean isPythonInternal() { - return true; + public int getFirstLineNumber() { + return rootNode.getFirstLineno(); } @Override - public Object execute(VirtualFrame frame) { - if (calleeContext == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - calleeContext = insert(CalleeContext.create()); - } - - calleeContext.enter(frame); - try { - return doCall(frame); - } finally { - calleeContext.exit(frame, this); - } + public Object getYieldFrom(Frame generatorFrame, int bci, int stackTop) { + // TODO implement + throw new UnsupportedOperationException("not implemented"); } - protected abstract Object doCall(VirtualFrame frame); + @Override + public CodeUnit getCodeUnit() { + return rootNode.getCodeUnit(); + } @Override - public boolean setsUpCalleeContext() { - return true; + public boolean includeInTraceback() { + return !rootNode.isInternal(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/DeleteAttributeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/MakeSetStorageNode.java similarity index 63% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/DeleteAttributeNode.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/MakeSetStorageNode.java index 0878e51610..357c09f1ec 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/DeleteAttributeNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/MakeSetStorageNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,14 +38,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.nodes.attributes; +package com.oracle.graal.python.nodes.bytecode_dsl; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.util.PythonUtils; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; +import com.oracle.graal.python.builtins.objects.common.ObjectHashMap; +import com.oracle.graal.python.builtins.objects.common.ObjectHashMap.PutNode; +import com.oracle.graal.python.lib.PyObjectHashNode; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -53,24 +52,26 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedIntValueProfile; -@GenerateUncached @GenerateInline +@GenerateUncached @GenerateCached(false) -public abstract class DeleteAttributeNode extends PNodeWithContext { - public abstract void execute(VirtualFrame frame, Node inliningTarget, Object object, Object key); +public abstract class MakeSetStorageNode extends Node { + public abstract EconomicMapStorage execute(VirtualFrame frame, Node inliningTarget, Object[] elements); @Specialization - protected void doIt(VirtualFrame frame, Object object, Object key, - @Cached(value = "create(DelAttr)", inline = false) LookupAndCallBinaryNode call) { - call.executeObject(frame, object, key); - } - - @Specialization(replaces = "doIt") - protected void doItUncached(VirtualFrame frame, Object object, Object key) { - PythonUtils.assertUncached(); - Object klass = GetClassNode.executeUncached(object); - Object method = LookupCallableSlotInMRONode.getUncached(SpecialMethodSlot.DelAttr).execute(klass); - CallBinaryMethodNode.getUncached().executeObject(frame, method, object, key); + public static EconomicMapStorage doNonEmpty(VirtualFrame frame, Node inliningTarget, Object[] elements, + @Cached InlinedIntValueProfile lengthProfile, + @Cached PyObjectHashNode hashNode, + @Cached PutNode putNode) { + int profiledLen = lengthProfile.profile(inliningTarget, elements.length); + ObjectHashMap map = new ObjectHashMap(profiledLen, false); + for (int i = 0; i < profiledLen; i++) { + Object key = elements[i]; + long keyHash = hashNode.execute(frame, inliningTarget, key); + putNode.put(frame, inliningTarget, map, key, keyHash, PNone.NONE); + } + return new EconomicMapStorage(map, false); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLGeneratorFunctionRootNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLGeneratorFunctionRootNode.java new file mode 100644 index 0000000000..1d3840e2d2 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLGeneratorFunctionRootNode.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.nodes.bytecode_dsl; + +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.function.PArguments; +import com.oracle.graal.python.builtins.objects.function.PFunction; +import com.oracle.graal.python.builtins.objects.function.Signature; +import com.oracle.graal.python.nodes.PRootNode; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.api.strings.TruffleString; + +public final class PBytecodeDSLGeneratorFunctionRootNode extends PRootNode { + private final PBytecodeDSLRootNode rootNode; + private final TruffleString originalName; + private final ConditionProfile isIterableCoroutine = ConditionProfile.create(); + + public PBytecodeDSLGeneratorFunctionRootNode(PythonLanguage language, FrameDescriptor frameDescriptor, PBytecodeDSLRootNode rootNode, TruffleString originalName) { + super(language, frameDescriptor); + CompilerAsserts.neverPartOfCompilation(); + this.rootNode = rootNode; + this.originalName = originalName; + } + + @Override + public Object execute(VirtualFrame frame) { + Object[] arguments = frame.getArguments(); + + // This is passed from InvokeNode node + PFunction generatorFunction = PArguments.getGeneratorFunction(arguments); + assert generatorFunction != null; + if (rootNode.getCodeUnit().isGenerator()) { + // if CO_ITERABLE_COROUTINE was explicitly set (likely by types.coroutine), we have to + // pass the information to the generator + // .gi_code.co_flags will still be wrong, but at least await will work correctly + if (isIterableCoroutine.profile((generatorFunction.getCode().getFlags() & 0x100) != 0)) { + return PFactory.createIterableCoroutine(rootNode.getLanguage(), generatorFunction.getName(), generatorFunction.getQualname(), rootNode, arguments); + } else { + return PFactory.createGenerator(rootNode.getLanguage(), generatorFunction.getName(), generatorFunction.getQualname(), rootNode, arguments); + } + } else if (rootNode.getCodeUnit().isCoroutine()) { + return PFactory.createCoroutine(rootNode.getLanguage(), generatorFunction.getName(), generatorFunction.getQualname(), rootNode, arguments); + } else if (rootNode.getCodeUnit().isAsyncGenerator()) { + /* + * TODO: Support async generators. + * + * We need to produce something instead of failing here because async generators are + * instantiated in frozen module code. + */ + return PNone.NONE; + } + throw CompilerDirectives.shouldNotReachHere("Unknown generator/coroutine type"); + } + + @Override + public String getName() { + return originalName.toJavaStringUncached(); + } + + @Override + public String toString() { + CompilerAsserts.neverPartOfCompilation(); + return ""; + } + + @Override + public Signature getSignature() { + return rootNode.getSignature(); + } + + @Override + public boolean isPythonInternal() { + return rootNode.isPythonInternal(); + } + + @Override + public SourceSection getSourceSection() { + return rootNode.getSourceSection(); + } + + @Override + protected byte[] extractCode() { + return rootNode.extractCode(); + } + + public PBytecodeDSLRootNode getBytecodeRootNode() { + return rootNode; + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java new file mode 100644 index 0000000000..c293129ab7 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java @@ -0,0 +1,3370 @@ +/* + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.nodes.bytecode_dsl; + +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.AttributeError; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.GeneratorExit; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; +import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___ANNOTATIONS__; +import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AENTER__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AEXIT__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ENTER__; +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___EXIT__; +import static com.oracle.graal.python.runtime.exception.PythonErrorType.AssertionError; +import static com.oracle.graal.python.util.PythonUtils.tsLiteral; + +import java.math.BigInteger; +import java.util.Iterator; + +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.modules.BuiltinFunctions.FormatNode; +import com.oracle.graal.python.builtins.modules.MarshalModuleBuiltins; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.asyncio.GetAwaitableNode; +import com.oracle.graal.python.builtins.objects.cell.PCell; +import com.oracle.graal.python.builtins.objects.code.PCode; +import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; +import com.oracle.graal.python.builtins.objects.common.HashingStorage; +import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem; +import com.oracle.graal.python.builtins.objects.common.ObjectHashMap; +import com.oracle.graal.python.builtins.objects.common.SequenceNodes; +import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; +import com.oracle.graal.python.builtins.objects.dict.DictNodes; +import com.oracle.graal.python.builtins.objects.dict.PDict; +import com.oracle.graal.python.builtins.objects.exception.ChainExceptionsNode; +import com.oracle.graal.python.builtins.objects.exception.ExceptionNodes; +import com.oracle.graal.python.builtins.objects.exception.PBaseException; +import com.oracle.graal.python.builtins.objects.exception.StopIterationBuiltins; +import com.oracle.graal.python.builtins.objects.frame.PFrame; +import com.oracle.graal.python.builtins.objects.function.PArguments; +import com.oracle.graal.python.builtins.objects.function.PFunction; +import com.oracle.graal.python.builtins.objects.function.PKeyword; +import com.oracle.graal.python.builtins.objects.function.Signature; +import com.oracle.graal.python.builtins.objects.generator.CommonGeneratorBuiltins; +import com.oracle.graal.python.builtins.objects.generator.PGenerator; +import com.oracle.graal.python.builtins.objects.iterator.PDoubleSequenceIterator; +import com.oracle.graal.python.builtins.objects.iterator.PIntRangeIterator; +import com.oracle.graal.python.builtins.objects.iterator.PIntegerIterator; +import com.oracle.graal.python.builtins.objects.iterator.PIntegerSequenceIterator; +import com.oracle.graal.python.builtins.objects.iterator.PLongSequenceIterator; +import com.oracle.graal.python.builtins.objects.iterator.PObjectSequenceIterator; +import com.oracle.graal.python.builtins.objects.list.PList; +import com.oracle.graal.python.builtins.objects.set.PFrozenSet; +import com.oracle.graal.python.builtins.objects.set.PSet; +import com.oracle.graal.python.builtins.objects.set.SetNodes; +import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; +import com.oracle.graal.python.compiler.CodeUnit; +import com.oracle.graal.python.compiler.RaisePythonExceptionErrorCallback; +import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyIterCheckNode; +import com.oracle.graal.python.lib.PyIterNextNode; +import com.oracle.graal.python.lib.PyNumberAddNode; +import com.oracle.graal.python.lib.PyNumberAndNode; +import com.oracle.graal.python.lib.PyNumberFloorDivideNode; +import com.oracle.graal.python.lib.PyNumberInPlaceAddNode; +import com.oracle.graal.python.lib.PyNumberInPlaceAndNode; +import com.oracle.graal.python.lib.PyNumberInPlaceFloorDivideNode; +import com.oracle.graal.python.lib.PyNumberInPlaceLshiftNode; +import com.oracle.graal.python.lib.PyNumberInPlaceMatrixMultiplyNode; +import com.oracle.graal.python.lib.PyNumberInPlaceMultiplyNode; +import com.oracle.graal.python.lib.PyNumberInPlaceOrNode; +import com.oracle.graal.python.lib.PyNumberInPlacePowerNode; +import com.oracle.graal.python.lib.PyNumberInPlaceRemainderNode; +import com.oracle.graal.python.lib.PyNumberInPlaceRshiftNode; +import com.oracle.graal.python.lib.PyNumberInPlaceSubtractNode; +import com.oracle.graal.python.lib.PyNumberInPlaceTrueDivideNode; +import com.oracle.graal.python.lib.PyNumberInPlaceXorNode; +import com.oracle.graal.python.lib.PyNumberInvertNode; +import com.oracle.graal.python.lib.PyNumberLshiftNode; +import com.oracle.graal.python.lib.PyNumberMatrixMultiplyNode; +import com.oracle.graal.python.lib.PyNumberMultiplyNode; +import com.oracle.graal.python.lib.PyNumberNegativeNode; +import com.oracle.graal.python.lib.PyNumberOrNode; +import com.oracle.graal.python.lib.PyNumberPositiveNode; +import com.oracle.graal.python.lib.PyNumberPowerNode; +import com.oracle.graal.python.lib.PyNumberRemainderNode; +import com.oracle.graal.python.lib.PyNumberRshiftNode; +import com.oracle.graal.python.lib.PyNumberSubtractNode; +import com.oracle.graal.python.lib.PyNumberTrueDivideNode; +import com.oracle.graal.python.lib.PyNumberXorNode; +import com.oracle.graal.python.lib.PyObjectAsciiNode; +import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; +import com.oracle.graal.python.lib.PyObjectDelItem; +import com.oracle.graal.python.lib.PyObjectFunctionStr; +import com.oracle.graal.python.lib.PyObjectGetItem; +import com.oracle.graal.python.lib.PyObjectGetIter; +import com.oracle.graal.python.lib.PyObjectGetMethod; +import com.oracle.graal.python.lib.PyObjectHashNode; +import com.oracle.graal.python.lib.PyObjectIsNotTrueNode; +import com.oracle.graal.python.lib.PyObjectIsTrueNode; +import com.oracle.graal.python.lib.PyObjectLookupAttr; +import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode; +import com.oracle.graal.python.lib.PyObjectRichCompare.GenericRichCompare; +import com.oracle.graal.python.lib.PyObjectSetAttr; +import com.oracle.graal.python.lib.PyObjectSetAttrO; +import com.oracle.graal.python.lib.PyObjectSetItem; +import com.oracle.graal.python.lib.PyObjectSizeNode; +import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode; +import com.oracle.graal.python.lib.PySequenceContainsNode; +import com.oracle.graal.python.lib.RichCmpOp; +import com.oracle.graal.python.nodes.BuiltinNames; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PGuards; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.PRootNode; +import com.oracle.graal.python.nodes.WriteUnraisableNode; +import com.oracle.graal.python.nodes.argument.keywords.ConcatDictToStorageNode; +import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode; +import com.oracle.graal.python.nodes.argument.keywords.NonMappingException; +import com.oracle.graal.python.nodes.argument.keywords.SameDictKeyException; +import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetFixedAttributeNode; +import com.oracle.graal.python.nodes.builtins.ListNodes; +import com.oracle.graal.python.nodes.bytecode.CopyDictWithoutKeysNode; +import com.oracle.graal.python.nodes.bytecode.GetSendValueNode; +import com.oracle.graal.python.nodes.bytecode.GetTPFlagsNode; +import com.oracle.graal.python.nodes.bytecode.GetYieldFromIterNode; +import com.oracle.graal.python.nodes.bytecode.ImportFromNode; +import com.oracle.graal.python.nodes.bytecode.ImportNode; +import com.oracle.graal.python.nodes.bytecode.ImportStarNode; +import com.oracle.graal.python.nodes.bytecode.MatchClassNode; +import com.oracle.graal.python.nodes.bytecode.MatchKeysNode; +import com.oracle.graal.python.nodes.bytecode.PrintExprNode; +import com.oracle.graal.python.nodes.bytecode.RaiseNode; +import com.oracle.graal.python.nodes.bytecode.SetupAnnotationsNode; +import com.oracle.graal.python.nodes.call.CallNode; +import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode; +import com.oracle.graal.python.nodes.call.special.CallQuaternaryMethodNode; +import com.oracle.graal.python.nodes.call.special.CallTernaryMethodNode; +import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; +import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodNode; +import com.oracle.graal.python.nodes.exception.ExceptMatchNode; +import com.oracle.graal.python.nodes.frame.DeleteGlobalNode; +import com.oracle.graal.python.nodes.frame.GetFrameLocalsNode; +import com.oracle.graal.python.nodes.frame.MaterializeFrameNode; +import com.oracle.graal.python.nodes.frame.ReadFromLocalsNode; +import com.oracle.graal.python.nodes.frame.ReadGlobalOrBuiltinNode; +import com.oracle.graal.python.nodes.frame.ReadNameNode; +import com.oracle.graal.python.nodes.frame.WriteGlobalNode; +import com.oracle.graal.python.nodes.frame.WriteNameNode; +import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; +import com.oracle.graal.python.nodes.object.IsNode; +import com.oracle.graal.python.nodes.util.ExceptionStateNodes; +import com.oracle.graal.python.runtime.ExecutionContext.CalleeContext; +import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.PythonContext.ProfileEvent; +import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; +import com.oracle.graal.python.runtime.PythonContext.TraceEvent; +import com.oracle.graal.python.runtime.PythonOptions; +import com.oracle.graal.python.runtime.exception.ExceptionUtils; +import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.graal.python.runtime.exception.PythonErrorType; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.graal.python.runtime.sequence.PSequence; +import com.oracle.graal.python.runtime.sequence.storage.BoolSequenceStorage; +import com.oracle.graal.python.runtime.sequence.storage.DoubleSequenceStorage; +import com.oracle.graal.python.runtime.sequence.storage.IntSequenceStorage; +import com.oracle.graal.python.runtime.sequence.storage.LongSequenceStorage; +import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; +import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; +import com.oracle.graal.python.util.ArrayBuilder; +import com.oracle.graal.python.util.PythonUtils; +import com.oracle.truffle.api.Assumption; +import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.bytecode.BytecodeConfig; +import com.oracle.truffle.api.bytecode.BytecodeLocation; +import com.oracle.truffle.api.bytecode.BytecodeNode; +import com.oracle.truffle.api.bytecode.BytecodeRootNode; +import com.oracle.truffle.api.bytecode.ConstantOperand; +import com.oracle.truffle.api.bytecode.EpilogExceptional; +import com.oracle.truffle.api.bytecode.EpilogReturn; +import com.oracle.truffle.api.bytecode.GenerateBytecode; +import com.oracle.truffle.api.bytecode.Instruction; +import com.oracle.truffle.api.bytecode.Instrumentation; +import com.oracle.truffle.api.bytecode.LocalAccessor; +import com.oracle.truffle.api.bytecode.LocalRangeAccessor; +import com.oracle.truffle.api.bytecode.Operation; +import com.oracle.truffle.api.bytecode.OperationProxy; +import com.oracle.truffle.api.bytecode.Prolog; +import com.oracle.truffle.api.bytecode.ShortCircuitOperation; +import com.oracle.truffle.api.bytecode.ShortCircuitOperation.Operator; +import com.oracle.truffle.api.bytecode.Variadic; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Cached.Exclusive; +import com.oracle.truffle.api.dsl.Cached.Shared; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Idempotent; +import com.oracle.truffle.api.dsl.ImportStatic; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.dsl.NonIdempotent; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.exception.AbstractTruffleException; +import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.library.CachedLibrary; +import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.UnexpectedResultException; +import com.oracle.truffle.api.object.DynamicObjectLibrary; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.api.strings.TruffleString; +import com.oracle.truffle.api.strings.TruffleStringBuilder; +import com.oracle.truffle.api.strings.TruffleStringBuilderUTF32; + +@GenerateBytecode(// + languageClass = PythonLanguage.class, // + enableBlockScoping = false, // + enableYield = true, // + enableSerialization = true, // + enableTagInstrumentation = true, // + boxingEliminationTypes = {int.class}, // + storeBytecodeIndexInFrame = true // +) +@OperationProxy(PyNumberSubtractNode.class) +@OperationProxy(PyNumberTrueDivideNode.class) +@OperationProxy(PyNumberFloorDivideNode.class) +@OperationProxy(PyNumberRemainderNode.class) +@OperationProxy(PyNumberLshiftNode.class) +@OperationProxy(PyNumberRshiftNode.class) +@OperationProxy(PyNumberAndNode.class) +@OperationProxy(PyNumberOrNode.class) +@OperationProxy(PyNumberXorNode.class) +@OperationProxy(PyNumberMatrixMultiplyNode.class) +@OperationProxy(PyNumberMultiplyNode.class) +@OperationProxy(PyNumberAddNode.class) +@OperationProxy(PyNumberPositiveNode.class) +@OperationProxy(PyNumberNegativeNode.class) +@OperationProxy(PyNumberInvertNode.class) +@OperationProxy(PyNumberInPlaceAddNode.class) +@OperationProxy(PyNumberInPlaceSubtractNode.class) +@OperationProxy(PyNumberInPlaceMultiplyNode.class) +@OperationProxy(PyNumberInPlaceTrueDivideNode.class) +@OperationProxy(PyNumberInPlaceFloorDivideNode.class) +@OperationProxy(PyNumberInPlaceRemainderNode.class) +@OperationProxy(PyNumberInPlaceMatrixMultiplyNode.class) +@OperationProxy(PyNumberInPlaceAndNode.class) +@OperationProxy(PyNumberInPlaceOrNode.class) +@OperationProxy(PyNumberInPlaceXorNode.class) +@OperationProxy(PyNumberInPlaceLshiftNode.class) +@OperationProxy(PyNumberInPlaceRshiftNode.class) +@OperationProxy(IsNode.class) +@OperationProxy(FormatNode.class) +@OperationProxy(ExceptMatchNode.class) +@OperationProxy(GetYieldFromIterNode.class) +@OperationProxy(GetAwaitableNode.class) +@OperationProxy(SetupAnnotationsNode.class) +@OperationProxy(value = CopyDictWithoutKeysNode.class, name = "CopyDictWithoutKeys") +@OperationProxy(value = PyObjectIsTrueNode.class, name = "Yes") +@OperationProxy(value = PyObjectIsNotTrueNode.class, name = "Not") +@OperationProxy(value = ListNodes.AppendNode.class, name = "ListAppend") +@OperationProxy(value = SetNodes.AddNode.class, name = "SetAdd") +@ShortCircuitOperation(name = "BoolAnd", booleanConverter = PyObjectIsTrueNode.class, operator = Operator.AND_RETURN_VALUE) +@ShortCircuitOperation(name = "BoolOr", booleanConverter = PyObjectIsTrueNode.class, operator = Operator.OR_RETURN_VALUE) +@ShortCircuitOperation(name = "PrimitiveBoolAnd", operator = Operator.AND_RETURN_VALUE) +@SuppressWarnings("unused") +public abstract class PBytecodeDSLRootNode extends PRootNode implements BytecodeRootNode { + public static final int EXPLODE_LOOP_THRESHOLD = 30; + private static final BytecodeConfig TRACE_AND_PROFILE_CONFIG = PBytecodeDSLRootNodeGen.newConfigBuilder().// + addInstrumentation(TraceOrProfileCall.class).// + addInstrumentation(TraceLine.class).// + addInstrumentation(TraceLineAtLoopHeader.class).// + addInstrumentation(TraceOrProfileReturn.class).// + addInstrumentation(TraceException.class).// + build(); + + @Child private transient CalleeContext calleeContext = CalleeContext.create(); + @Child private transient ExceptionStateNodes.GetCaughtExceptionNode getCaughtExceptionNode; + @Child private transient MaterializeFrameNode traceMaterializeFrameNode = null; + @Child private transient ChainExceptionsNode chainExceptionsNode; + + // These fields are effectively final, but can only be set after construction. + @CompilationFinal protected transient BytecodeDSLCodeUnit co; + @CompilationFinal protected transient Signature signature; + @CompilationFinal protected transient int selfIndex; + @CompilationFinal protected transient int classcellIndex; + + private transient boolean pythonInternal; + @CompilationFinal private transient boolean internal; + + // For deferred deprecation warnings + @CompilationFinal private transient RaisePythonExceptionErrorCallback parserErrorCallback; + + @SuppressWarnings("this-escape") + protected PBytecodeDSLRootNode(PythonLanguage language, FrameDescriptor.Builder frameDescriptorBuilder) { + super(language, frameDescriptorBuilder.info(new BytecodeDSLFrameInfo()).build()); + ((BytecodeDSLFrameInfo) getFrameDescriptor().getInfo()).setRootNode(this); + } + + public final PythonLanguage getLanguage() { + return getLanguage(PythonLanguage.class); + } + + public void setMetadata(BytecodeDSLCodeUnit co, RaisePythonExceptionErrorCallback parserErrorCallback) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + this.co = co; + this.signature = co.computeSignature(); + this.classcellIndex = co.classcellIndex; + this.selfIndex = co.selfIndex; + this.internal = getSource().isInternal(); + this.parserErrorCallback = parserErrorCallback; + } + + @Override + public final boolean isInternal() { + return internal; + } + + @Override + public final boolean isPythonInternal() { + return pythonInternal; + } + + public final void setPythonInternal(boolean pythonInternal) { + this.pythonInternal = pythonInternal; + } + + public final void triggerDeferredDeprecationWarnings() { + if (parserErrorCallback != null) { + parserErrorCallback.triggerDeprecationWarnings(); + } + } + + @Override + public String toString() { + return ""; + } + + @Prolog + public static final class EnterCalleeContext { + @Specialization + public static void doEnter(VirtualFrame frame, + @Bind PBytecodeDSLRootNode root) { + root.calleeContext.enter(frame); + + if (root.needsTraceAndProfileInstrumentation()) { + root.ensureTraceAndProfileEnabled(); + root.getThreadState().pushInstrumentationData(root); + } + } + } + + @EpilogReturn + public static final class EpilogForReturn { + @Specialization + public static Object doExit(VirtualFrame frame, Object returnValue, + @Bind PBytecodeDSLRootNode root, + @Bind Node location) { + if (root.needsTraceAndProfileInstrumentation()) { + root.getThreadState().popInstrumentationData(root); + } + + root.calleeContext.exit(frame, root, location); + return returnValue; + } + } + + @EpilogExceptional + public static final class EpilogForException { + @Specialization + public static void doExit(VirtualFrame frame, AbstractTruffleException ate, + @Bind PBytecodeDSLRootNode root, + @Bind Node location) { + if (ate instanceof PException pe) { + pe.notifyAddedTracebackFrame(!root.isInternal()); + } + + if (root.needsTraceAndProfileInstrumentation()) { + root.traceOrProfileReturn(frame, location, null); + root.getThreadState().popInstrumentationData(root); + } + + root.calleeContext.exit(frame, root, location); + } + } + + /* + * Data for tracing, profiling and instrumentation + */ + public static final class InstrumentationData { + private final InstrumentationData previous; + private final PBytecodeDSLRootNode rootNode; + private int pastLine; + + public InstrumentationData(PBytecodeDSLRootNode rootNode, InstrumentationData previous) { + this.previous = previous; + this.rootNode = rootNode; + this.pastLine = -1; + } + + public InstrumentationData getPrevious() { + return previous; + } + + public PBytecodeDSLRootNode getRootNode() { + return rootNode; + } + + int getPastLine() { + return pastLine; + } + + void setPastLine(int pastLine) { + this.pastLine = pastLine; + } + + void clearPastLine() { + this.pastLine = -1; + } + } + + @NonIdempotent + public final boolean needsTraceAndProfileInstrumentation() { + // We need instrumentation only if the assumption is invalid and the root node is visible. + return !getLanguage().noTracingOrProfilingAssumption.isValid() && !isInternal(); + } + + @NonIdempotent + public final PythonThreadState getThreadState() { + return PythonContext.get(this).getThreadState(getLanguage()); + } + + /** + * Reparses with instrumentations for settrace and setprofile enabled. + */ + public final void ensureTraceAndProfileEnabled() { + assert !isInternal(); + getRootNodes().update(TRACE_AND_PROFILE_CONFIG); + } + + private PFrame ensurePyFrame(VirtualFrame frame, Node location) { + if (traceMaterializeFrameNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + traceMaterializeFrameNode = insert(MaterializeFrameNode.create()); + } + return traceMaterializeFrameNode.execute(frame, location, true, true); + } + + private void syncLocalsBackToFrame(VirtualFrame frame, PFrame pyFrame) { + GetFrameLocalsNode.syncLocalsBackToFrame(co, this, pyFrame, frame); + } + + /** + * When tracing/profiling is enabled, we emit a lot of extra operations. Reduce compiled code + * size by putting the calls behind a boundary (the uncached invoke will eventually perform an + * indirect call anyway). + */ + @TruffleBoundary + private static Object doInvokeProfileOrTraceFunction(Object fun, PFrame pyFrame, TruffleString eventName, Object arg) { + return CallTernaryMethodNode.getUncached().execute(null, fun, pyFrame, eventName, arg == null ? PNone.NONE : arg); + } + + @InliningCutoff + private void invokeProfileFunction(VirtualFrame virtualFrame, Node location, Object profileFun, + PythonContext.PythonThreadState threadState, PythonContext.ProfileEvent event, Object arg) { + if (threadState.isProfiling()) { + return; + } + threadState.profilingStart(); + PFrame pyFrame = ensurePyFrame(virtualFrame, location); + EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent(); + Node oldEncapsulatingNode = encapsulating.set(location); + try { + // Force locals dict sync, so that we can sync them back later + GetFrameLocalsNode.executeUncached(pyFrame); + Object result = doInvokeProfileOrTraceFunction(profileFun, pyFrame, event.name, arg); + syncLocalsBackToFrame(virtualFrame, pyFrame); + Object realResult = result == PNone.NONE ? null : result; + pyFrame.setLocalTraceFun(realResult); + } catch (Throwable e) { + threadState.setProfileFun(null, getLanguage()); + throw e; + } finally { + threadState.profilingStop(); + encapsulating.set(oldEncapsulatingNode); + } + } + + @InliningCutoff + private void invokeTraceFunction(VirtualFrame virtualFrame, Node location, Object traceFun, PythonContext.PythonThreadState threadState, + PythonContext.TraceEvent event, Object arg, int line) { + if (threadState.isTracing()) { + return; + } + assert event != PythonContext.TraceEvent.DISABLED; + threadState.tracingStart(event); + PFrame pyFrame = ensurePyFrame(virtualFrame, location); + /** + * Call events use the thread-local trace function, which returns a "local" trace function + * to use for other trace events. + */ + boolean useLocalFn = event != TraceEvent.CALL; + Object traceFn = useLocalFn ? pyFrame.getLocalTraceFun() : traceFun; + if (traceFn == null) { + threadState.tracingStop(); + return; + } + Object nonNullArg = arg == null ? PNone.NONE : arg; + + EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent(); + Node oldEncapsulatingNode = encapsulating.set(location); + try { + /** + * The PFrame syncs to the line of the current bci. Sometimes this location is + * inaccurate and needs to be overridden (e.g., when tracing an implicit return at the + * end of a function, we need to trace the line of the last statement executed). + */ + if (line != -1) { + pyFrame.setLineLock(line); + } + + // Force locals dict sync, so that we can sync them back later + GetFrameLocalsNode.executeUncached(pyFrame); + Object result = doInvokeProfileOrTraceFunction(traceFn, pyFrame, event.pythonName, nonNullArg); + syncLocalsBackToFrame(virtualFrame, pyFrame); + // https://github.com/python/cpython/issues/104232 + if (useLocalFn) { + Object realResult = result == PNone.NONE ? traceFn : result; + pyFrame.setLocalTraceFun(realResult); + } else if (result != PNone.NONE) { + pyFrame.setLocalTraceFun(result); + } else { + pyFrame.setLocalTraceFun(null); + } + } catch (Throwable e) { + threadState.setTraceFun(null, getLanguage()); + throw e; + } finally { + if (line != -1) { + pyFrame.lineUnlock(); + } + threadState.tracingStop(); + encapsulating.set(oldEncapsulatingNode); + } + } + + private void traceOrProfileCall(VirtualFrame frame, Node location, BytecodeNode bytecode, int bci) { + PythonThreadState threadState = getThreadState(); + Object traceFun = threadState.getTraceFun(); + if (traceFun != null) { + int line = bciToLine(bci, bytecode); + invokeTraceFunction(frame, location, traceFun, threadState, TraceEvent.CALL, null, line); + } + Object profileFun = threadState.getProfileFun(); + if (profileFun != null) { + invokeProfileFunction(frame, location, profileFun, threadState, ProfileEvent.CALL, null); + } + } + + @InliningCutoff + private void traceLine(VirtualFrame frame, Node location, int line) { + PythonThreadState threadState = getThreadState(); + InstrumentationData instrumentationData = threadState.getInstrumentationData(this); + + // TODO: this should never happen by nature of how we emit TraceLine, but sometimes does. + // needs investigation. + if (line == instrumentationData.getPastLine()) { + return; + } + instrumentationData.setPastLine(line); + + PFrame pyFrame = ensurePyFrame(frame, location); + if (pyFrame.getTraceLine()) { + Object traceFun = threadState.getTraceFun(); + if (traceFun != null) { + invokeTraceFunction(frame, location, traceFun, threadState, TraceEvent.LINE, null, line); + } + } + } + + @InliningCutoff + private void traceLineAtLoopHeader(VirtualFrame frame, Node location, int line) { + PythonThreadState threadState = getThreadState(); + InstrumentationData instrumentationData = threadState.getInstrumentationData(this); + int pastLine = instrumentationData.getPastLine(); + + /** + * A loop should always be traced once, even if it is not entered. We also need to trace the + * loop header on each iteration. To accomplish this, we emit a TraceLine at the top of each + * loop (before loop initialization) and a TraceLineAtLoopHeader before the loop condition + * evaluates. To avoid tracing twice on the first iteration, we need to check our line + * against pastLine. + */ + if (line != pastLine) { + Object traceFun = threadState.getTraceFun(); + if (traceFun != null) { + invokeTraceFunction(frame, location, traceFun, threadState, TraceEvent.LINE, null, line); + } + } + /** + * If the loop is all on one line, we need to trace on each iteration (even though the line + * hasn't changed). Clear pastLine so the line comparison above succeeds. + */ + instrumentationData.clearPastLine(); + } + + private void traceOrProfileReturn(VirtualFrame frame, Node location, Object value) { + PythonThreadState threadState = getThreadState(); + Object traceFun = threadState.getTraceFun(); + if (traceFun != null) { + invokeTraceFunction(frame, location, traceFun, threadState, TraceEvent.RETURN, value, threadState.getInstrumentationData(this).getPastLine()); + } + Object profileFun = threadState.getProfileFun(); + if (profileFun != null) { + invokeProfileFunction(frame, location, profileFun, threadState, ProfileEvent.RETURN, value); + } + } + + @InliningCutoff + private PException traceException(VirtualFrame frame, BytecodeNode bytecode, int bci, PException pe) { + PException result = pe; + + PythonThreadState threadState = getThreadState(); + // We should only trace the exception if tracing is enabled. + if (threadState.getTraceFun() != null) { + PFrame pyFrame = ensurePyFrame(frame, bytecode); + // We use the local function for tracing exceptions. + if (pyFrame.getLocalTraceFun() != null) { + pe.markAsCaught(frame, this); + Object peForPython = pe.getEscapedException(); + Object peType = GetClassNode.executeUncached(peForPython); + Object traceback = ExceptionNodes.GetTracebackNode.executeUncached(peForPython); + try { + invokeTraceFunction(frame, bytecode, null, threadState, TraceEvent.EXCEPTION, + PFactory.createTuple(getLanguage(), new Object[]{peType, peForPython, traceback}), + bciToLine(bci, bytecode)); + } catch (PException newPe) { + // If the trace function raises, handle its exception instead. + result = newPe; + // Below, we get the exception for reraise in order to hide the original + // raising site that's being traced (i.e., hiding the original cause). + } + // The exception was reified already. Return a new exception that looks like this + // catch didn't happen. + result = result.getExceptionForReraise(!isInternal()); + result.setCatchLocation(bci, bytecode); + } + } + return result; + } + + @Instrumentation + public static final class TraceOrProfileCall { + @Specialization + public static void perform(VirtualFrame frame, + @Bind Node location, + @Bind PBytecodeDSLRootNode root, + @Bind BytecodeNode bytecode, + @Bind("$bytecodeIndex") int bci) { + root.traceOrProfileCall(frame, location, bytecode, bci); + } + } + + @Instrumentation + @ConstantOperand(type = int.class) + public static final class TraceLine { + @Specialization + public static void perform(VirtualFrame frame, + int line, + @Bind Node location, + @Bind PBytecodeDSLRootNode root) { + root.traceLine(frame, location, line); + } + } + + @Instrumentation + @ConstantOperand(type = int.class) + public static final class TraceLineAtLoopHeader { + @Specialization + public static void perform(VirtualFrame frame, + int line, + @Bind Node location, + @Bind PBytecodeDSLRootNode root) { + root.traceLineAtLoopHeader(frame, location, line); + } + } + + @Instrumentation + public static final class TraceOrProfileReturn { + @Specialization + public static Object perform(VirtualFrame frame, Object value, + @Bind Node location, + @Bind PBytecodeDSLRootNode root) { + root.traceOrProfileReturn(frame, location, value); + return value; + } + } + + @Instrumentation + public static final class TraceException { + @Specialization + public static void perform() { + throw new UnsupportedOperationException("trace exception not implemented"); + } + } + + @Override + public Throwable interceptInternalException(Throwable throwable, VirtualFrame frame, BytecodeNode bytecodeNode, int bci) { + PythonLanguage language = getLanguage(); + if (language.getEngineOption(PythonOptions.CatchAllExceptions) && (throwable instanceof Exception || throwable instanceof AssertionError)) { + return ExceptionUtils.wrapJavaException(throwable, this, PFactory.createBaseException(language, SystemError, ErrorMessages.M, new Object[]{throwable})); + } + PException wrapped = ExceptionUtils.wrapJavaExceptionIfApplicable(this, throwable); + return wrapped != null ? wrapped : throwable; + } + + @Override + public AbstractTruffleException interceptTruffleException(AbstractTruffleException ex, VirtualFrame frame, BytecodeNode bytecodeNode, int bci) { + if (ex instanceof PException pe) { + pe.setCatchLocation(bci, bytecodeNode); + + if (needsTraceAndProfileInstrumentation() && !getThreadState().isTracing()) { + pe = traceException(frame, bytecodeNode, bci, pe); + } + + // Fill in the __context__, if available. + if (getCaughtExceptionNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getCaughtExceptionNode = insert(ExceptionStateNodes.GetCaughtExceptionNode.create()); + } + AbstractTruffleException context = getCaughtExceptionNode.execute(frame); + if (context instanceof PException pe2) { + if (chainExceptionsNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + chainExceptionsNode = insert(ChainExceptionsNode.create()); + } + chainExceptionsNode.execute(pe, pe2); + } + return pe; + } + + return ex; + } + + // TODO: ContinuationRootNodeImpl does not provide this, nor it is PRootNode, do we need to + // handle it in ReadCallerFrame#getFrame, and other places that iterate frames and/or check if a + // root node is PRootNode? + @Override + public boolean setsUpCalleeContext() { + return true; + } + + @Override + public String getName() { + if (co == null) { + // getName can be called by validation code before the code unit has been set. + return null; + } + return co.name.toJavaStringUncached(); + } + + @Override + public Signature getSignature() { + return signature; + } + + public BytecodeDSLCodeUnit getCodeUnit() { + return co; + } + + public int getFirstLineno() { + return co.startLine; + } + + protected Source getSource() { + SourceSection section = getSourceSection(); + if (section == null) { + return PythonUtils.createFakeSource(); + } + return section.getSource(); + } + + @TruffleBoundary + public int bciToLine(int bci, BytecodeNode bytecodeNode) { + return getSourceSectionForLocation(bci, bytecodeNode).getStartLine(); + } + + @TruffleBoundary + public SourceSection getSourceSectionForLocation(BytecodeLocation location) { + SourceSection sourceSection = null; + if (location != null) { + sourceSection = location.getSourceLocation(); + } + + if (sourceSection == null) { + /** + * If we don't have a source section, fall back on the root node's source section. This + * can happen, for example, when throwing into an unstarted generator, where we don't + * have an actual location (and the first line of the root node is expected). + */ + sourceSection = getSourceSection(); + } + + return sourceSection; + } + + @TruffleBoundary + public SourceSection getSourceSectionForLocation(int bci, BytecodeNode bytecodeNode) { + BytecodeLocation location = null; + if (bytecodeNode != null) { + location = bytecodeNode.getBytecodeLocation(bci); + } + return getSourceSectionForLocation(location); + } + + public static int bciToLasti(int bci, BytecodeNode bytecodeNode) { + if (bci <= 0) { + return bci; + } + int number = 0; + for (Instruction instruction : bytecodeNode.getInstructions()) { + if (instruction.isInstrumentation()) { + continue; + } + if (instruction.getBytecodeIndex() >= bci) { + return number; + } + // Emulate CPython's fixed 2-word instructions. + number += 2; + } + return -1; + } + + public static int lastiToBci(int lasti, BytecodeNode bytecodeNode) { + if (lasti < 0) { + return 0; + } + Iterator iter = bytecodeNode.getInstructions().iterator(); + assert iter.hasNext(); + + int nexti = 0; + Instruction result; + do { + result = iter.next(); + if (result.isInstrumentation()) { + continue; + } + nexti += 2; + } while (nexti <= lasti && iter.hasNext()); + return result.getBytecodeIndex(); + } + + @Override + protected byte[] extractCode() { + return MarshalModuleBuiltins.serializeCodeUnit(this, PythonContext.get(this), co); + } + + private static Object checkUnboundCell(PCell cell, int index, PBytecodeDSLRootNode rootNode, Node inliningTarget, PRaiseNode raiseNode) { + Object result = cell.getRef(); + if (result == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + CodeUnit codeUnit = rootNode.getCodeUnit(); + if (index < codeUnit.cellvars.length) { + TruffleString localName = codeUnit.cellvars[index]; + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.UnboundLocalError, ErrorMessages.LOCAL_VAR_REFERENCED_BEFORE_ASSIGMENT, localName); + } else { + TruffleString localName = codeUnit.freevars[index - codeUnit.cellvars.length]; + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.NameError, ErrorMessages.UNBOUNDFREEVAR, localName); + } + } + return result; + } + + public PCell readClassCell(Frame frame) { + if (classcellIndex < 0) { + return null; + } + return (PCell) getBytecodeNode().getLocalValue(0, frame, classcellIndex); + } + + public Object readSelf(Frame frame) { + if (selfIndex < 0) { + return null; + } else if (selfIndex == 0) { + return getBytecodeNode().getLocalValue(0, frame, 0); + } else { + PCell selfCell = (PCell) getBytecodeNode().getLocalValue(0, frame, selfIndex); + return selfCell.getRef(); + } + } + + @Operation + @ConstantOperand(type = int.class) + public static final class ArrayIndex { + @Specialization + public static Object doObject(int i, Object[] array) { + return array[i]; + } + } + + @Operation + public static final class UnwrapException { + @Specialization + public static Object doPException(PException ex) { + return ex.getEscapedException(); + } + + @Fallback + public static Object doOther(Object ex) { + // Let interop exceptions be + assert ex instanceof AbstractTruffleException; + return ex; + } + } + + /** + * Some operations take a single Object[] operand (e.g., {@link MakeTuple}). To pass a + * fixed-length sequence of elements to these operands (e.g., to instantiate a constant tuple) + * we need to first collect the values into an Object[]. + */ + @Operation + public static final class CollectToObjectArray { + @Specialization + public static Object[] perform(@Variadic Object[] values) { + return values; + } + } + + @Operation + public static final class Contains { + @Specialization + static Object contains(VirtualFrame frame, Object item, Object container, + @Bind Node inliningTarget, + @Cached PySequenceContainsNode containsNode) { + return containsNode.execute(frame, inliningTarget, container, item); + } + } + + @Operation + @ConstantOperand(type = TruffleString.class) + public static final class WriteName { + @Specialization + public static void perform(VirtualFrame frame, TruffleString name, Object value, + @Cached WriteNameNode writeNode) { + writeNode.execute(frame, name, value); + } + } + + @Operation + @ConstantOperand(type = TruffleString.class) + public static final class ReadName { + @Specialization + public static Object perform(VirtualFrame frame, TruffleString name, + @Cached ReadNameNode readNode) { + return readNode.execute(frame, name); + } + } + + @Operation + @ConstantOperand(type = TruffleString.class) + public static final class DeleteName { + @Specialization(guards = "hasLocals(frame)") + public static void performLocals(VirtualFrame frame, TruffleString name, + @Bind Node inliningTarget, + @Cached PyObjectDelItem deleteNode) { + deleteNode.execute(frame, inliningTarget, PArguments.getSpecialArgument(frame), name); + } + + @Specialization(guards = "!hasLocals(frame)") + public static void performGlobals(VirtualFrame frame, TruffleString name, + @Cached DeleteGlobalNode deleteNode) { + deleteNode.executeWithGlobals(frame, PArguments.getGlobals(frame), name); + } + + public static boolean hasLocals(VirtualFrame frame) { + return PArguments.getSpecialArgument(frame) != null; + } + } + + @Operation + public static final class LoadVariableArguments { + @Specialization + public static Object perform(VirtualFrame frame, + @Bind PBytecodeDSLRootNode rootNode) { + return PFactory.createTuple(rootNode.getLanguage(), PArguments.getVariableArguments(frame)); + } + } + + @Operation + public static final class LoadKeywordArguments { + @Specialization + public static Object perform(VirtualFrame frame, + @Bind PBytecodeDSLRootNode rootNode) { + return PFactory.createDict(rootNode.getLanguage(), PArguments.getKeywordArguments(frame)); + } + } + + @Operation + @ConstantOperand(type = double.class) + @ConstantOperand(type = double.class) + public static final class LoadComplex { + @Specialization + public static Object perform(double real, double imag, + @Bind PBytecodeDSLRootNode rootNode) { + return PFactory.createComplex(rootNode.getLanguage(), real, imag); + } + } + + @Operation + @ConstantOperand(type = BigInteger.class) + public static final class LoadBigInt { + @Specialization + public static Object perform(BigInteger bigInt, + @Bind PBytecodeDSLRootNode rootNode) { + return PFactory.createInt(rootNode.getLanguage(), bigInt); + } + } + + @Operation + @ConstantOperand(type = byte[].class, dimensions = 0) + public static final class LoadBytes { + @Specialization + public static Object perform(byte[] bytes, + @Bind PBytecodeDSLRootNode rootNode) { + return PFactory.createBytes(rootNode.getLanguage(), bytes); + } + } + + @Operation + public static final class GetIter { + @Specialization + public static Object perform(VirtualFrame frame, Object receiver, + @Bind Node inliningTarget, + @Cached PyObjectGetIter getIterNode) { + return getIterNode.execute(frame, inliningTarget, receiver); + } + } + + @Operation + public static final class FormatStr { + @Specialization + public static TruffleString perform(VirtualFrame frame, Object object, + @Bind Node inliningTarget, + @Cached PyObjectStrAsTruffleStringNode asTruffleStringNode) { + return asTruffleStringNode.execute(frame, inliningTarget, object); + } + } + + @Operation + public static final class FormatRepr { + @Specialization + public static TruffleString perform(VirtualFrame frame, Object object, + @Bind Node inliningTarget, + @Cached PyObjectReprAsTruffleStringNode asTruffleStringNode) { + return asTruffleStringNode.execute(frame, inliningTarget, object); + } + } + + @Operation + public static final class FormatAscii { + @Specialization + public static TruffleString perform(VirtualFrame frame, Object object, + @Bind Node inliningTarget, + @Cached PyObjectAsciiNode asTruffleStringNode) { + return asTruffleStringNode.execute(frame, inliningTarget, object); + } + } + + @Operation + public static final class PrintExpr { + @Specialization + public static void perform(VirtualFrame frame, Object object, + @Cached PrintExprNode printExprNode) { + printExprNode.execute(frame, object); + } + } + + @Operation + @ConstantOperand(type = LocalAccessor.class) + public static final class MatchKeys { + @Specialization + public static boolean perform(VirtualFrame frame, LocalAccessor values, Object map, Object[] keys, @Bind BytecodeNode bytecodeNode, @Cached MatchKeysNode node) { + values.setObject(bytecodeNode, frame, node.execute(frame, map, keys)); + return node.execute(frame, map, keys) != PNone.NONE; + } + } + + @Operation + @ConstantOperand(type = LocalAccessor.class) + public static final class MatchClass { + @Specialization + public static Object perform(VirtualFrame frame, LocalAccessor attributes, Object subject, Object type, int nargs, TruffleString[] kwArgs, @Bind BytecodeNode bytecodeNode, + @Cached MatchClassNode node) { + Object attrs = node.execute(frame, subject, type, nargs, kwArgs); + attributes.setObject(bytecodeNode, frame, attrs); + return attrs != null; + } + } + + @Operation + @ConstantOperand(type = TruffleString.class, name = "name") + @ConstantOperand(type = TruffleString.class, name = "qualifiedName") + @ConstantOperand(type = BytecodeDSLCodeUnit.class) + public static final class MakeFunction { + @Specialization(guards = {"isSingleContext(rootNode)", "!codeUnit.isGeneratorOrCoroutine()"}) + public static Object functionSingleContext(VirtualFrame frame, + TruffleString name, + TruffleString qualifiedName, + BytecodeDSLCodeUnit codeUnit, + Object[] defaults, + Object[] kwDefaultsObject, + Object closure, + Object annotations, + @Bind PBytecodeDSLRootNode rootNode, + @Cached(value = "createFunctionRootNode(rootNode, codeUnit)", adopt = false) PBytecodeDSLRootNode functionRootNode, + @Cached("createCode(rootNode, codeUnit, functionRootNode)") PCode cachedCode, + @Shared @CachedLibrary(limit = "1") DynamicObjectLibrary dylib) { + return createFunction(frame, name, qualifiedName, codeUnit.getDocstring(), cachedCode, defaults, kwDefaultsObject, closure, annotations, rootNode, dylib); + } + + @Specialization(replaces = "functionSingleContext", guards = "!codeUnit.isGeneratorOrCoroutine()") + public static Object functionMultiContext(VirtualFrame frame, + TruffleString name, + TruffleString qualifiedName, + BytecodeDSLCodeUnit codeUnit, + Object[] defaults, + Object[] kwDefaultsObject, + Object closure, + Object annotations, + @Bind PBytecodeDSLRootNode rootNode, + @Cached(value = "createFunctionRootNode(rootNode, codeUnit)", adopt = false) PBytecodeDSLRootNode functionRootNode, + @Shared @CachedLibrary(limit = "1") DynamicObjectLibrary dylib) { + PCode code = createCode(rootNode, codeUnit, functionRootNode); + return createFunction(frame, name, qualifiedName, codeUnit.getDocstring(), code, defaults, kwDefaultsObject, closure, annotations, rootNode, dylib); + } + + @Specialization(guards = {"isSingleContext(rootNode)", "codeUnit.isGeneratorOrCoroutine()"}) + public static Object generatorOrCoroutineSingleContext(VirtualFrame frame, + TruffleString name, + TruffleString qualifiedName, + BytecodeDSLCodeUnit codeUnit, + Object[] defaults, + Object[] kwDefaultsObject, + Object closure, + Object annotations, + @Bind PBytecodeDSLRootNode rootNode, + @Cached(value = "createFunctionRootNode(rootNode, codeUnit)", adopt = false) PBytecodeDSLRootNode functionRootNode, + @Cached(value = "createGeneratorRootNode(rootNode, functionRootNode, codeUnit)", adopt = false) PBytecodeDSLGeneratorFunctionRootNode generatorRootNode, + @Cached("createCode(rootNode, codeUnit, generatorRootNode)") PCode cachedCode, + @Shared @CachedLibrary(limit = "1") DynamicObjectLibrary dylib) { + return createFunction(frame, name, qualifiedName, codeUnit.getDocstring(), cachedCode, defaults, kwDefaultsObject, closure, annotations, rootNode, dylib); + } + + @Specialization(replaces = "generatorOrCoroutineSingleContext", guards = "codeUnit.isGeneratorOrCoroutine()") + public static Object generatorOrCoroutineMultiContext(VirtualFrame frame, + TruffleString name, + TruffleString qualifiedName, + BytecodeDSLCodeUnit codeUnit, + Object[] defaults, + Object[] kwDefaultsObject, + Object closure, + Object annotations, + @Bind PBytecodeDSLRootNode rootNode, + @Cached(value = "createFunctionRootNode(rootNode, codeUnit)", adopt = false) PBytecodeDSLRootNode functionRootNode, + @Cached(value = "createGeneratorRootNode(rootNode, functionRootNode, codeUnit)", adopt = false) PBytecodeDSLGeneratorFunctionRootNode generatorRootNode, + @Shared @CachedLibrary(limit = "1") DynamicObjectLibrary dylib) { + PCode code = createCode(rootNode, codeUnit, generatorRootNode); + return createFunction(frame, name, qualifiedName, codeUnit.getDocstring(), code, defaults, kwDefaultsObject, closure, annotations, rootNode, dylib); + } + + @Idempotent + protected static boolean isSingleContext(Node node) { + return PythonLanguage.get(node).isSingleContext(); + } + + @NeverDefault + protected static PBytecodeDSLRootNode createFunctionRootNode(PBytecodeDSLRootNode outerRootNode, BytecodeDSLCodeUnit codeUnit) { + return codeUnit.createRootNode(PythonContext.get(outerRootNode), outerRootNode.getSource()); + } + + @NeverDefault + protected static PBytecodeDSLGeneratorFunctionRootNode createGeneratorRootNode(PBytecodeDSLRootNode outerRootNode, PBytecodeDSLRootNode functionRootNode, + BytecodeDSLCodeUnit codeUnit) { + return new PBytecodeDSLGeneratorFunctionRootNode(PythonLanguage.get(outerRootNode), functionRootNode.getFrameDescriptor(), functionRootNode, codeUnit.name); + } + + @NeverDefault + protected static PCode createCode(PBytecodeDSLRootNode outerRootNode, BytecodeDSLCodeUnit codeUnit, PRootNode rootNode) { + return PFactory.createCode( + PythonLanguage.get(outerRootNode), + rootNode.getCallTarget(), + rootNode.getSignature(), + codeUnit); + } + + protected static PFunction createFunction(VirtualFrame frame, + TruffleString name, TruffleString qualifiedName, TruffleString doc, + PCode code, Object[] defaults, + Object[] kwDefaultsObject, Object closure, Object annotations, + PBytecodeDSLRootNode node, + DynamicObjectLibrary dylib) { + PKeyword[] kwDefaults = new PKeyword[kwDefaultsObject.length]; + // Note: kwDefaultsObject should be a result of operation MakeKeywords, which produces + // PKeyword[] + System.arraycopy(kwDefaultsObject, 0, kwDefaults, 0, kwDefaults.length); + PFunction function = PFactory.createFunction(PythonLanguage.get(node), name, qualifiedName, code, PArguments.getGlobals(frame), defaults, kwDefaults, (PCell[]) closure); + + if (annotations != null) { + dylib.put(function, T___ANNOTATIONS__, annotations); + } + if (doc != null) { + dylib.put(function, T___DOC__, doc); + } + + return function; + } + } + + @Operation + public static final class Pow { + @Specialization + public static Object doIt(VirtualFrame frame, Object left, Object right, + @Cached PyNumberPowerNode powNode) { + return powNode.execute(frame, left, right); + } + } + + @Operation + public static final class InPlacePow { + @Specialization + public static Object doIt(VirtualFrame frame, Object left, Object right, + @Cached PyNumberInPlacePowerNode ipowNode) { + return ipowNode.execute(frame, left, right); + } + } + + @Operation + @ConstantOperand(type = LocalAccessor.class) + public static final class ForIterate { + + @Specialization + public static boolean doIntegerSequence(VirtualFrame frame, LocalAccessor output, PIntegerSequenceIterator iterator, + @Bind BytecodeNode bytecode) { + return doInteger(frame, output, iterator, bytecode); + } + + @Specialization + public static boolean doIntRange(VirtualFrame frame, LocalAccessor output, PIntRangeIterator iterator, + @Bind BytecodeNode bytecode) { + return doInteger(frame, output, iterator, bytecode); + } + + private static boolean doInteger(VirtualFrame frame, LocalAccessor output, + PIntegerIterator iterator, BytecodeNode bytecode) { + if (!iterator.hasNext()) { + iterator.setExhausted(); + return false; + } + output.setInt(bytecode, frame, iterator.next()); + return true; + } + + @Specialization + public static boolean doObjectIterator(VirtualFrame frame, LocalAccessor output, PObjectSequenceIterator iterator, + @Bind BytecodeNode bytecode) { + if (!iterator.hasNext()) { + iterator.setExhausted(); + output.setObject(bytecode, frame, null); + return false; + } + Object value = iterator.next(); + output.setObject(bytecode, frame, value); + return value != null; + } + + @Specialization + public static boolean doLongIterator(VirtualFrame frame, LocalAccessor output, PLongSequenceIterator iterator, + @Bind BytecodeNode bytecode) { + if (!iterator.hasNext()) { + iterator.setExhausted(); + return false; + } + output.setLong(bytecode, frame, iterator.next()); + return true; + } + + @Specialization + public static boolean doDoubleIterator(VirtualFrame frame, LocalAccessor output, PDoubleSequenceIterator iterator, + @Bind BytecodeNode bytecode) { + if (!iterator.hasNext()) { + iterator.setExhausted(); + return false; + } + output.setDouble(bytecode, frame, iterator.next()); + return true; + } + + @Specialization + @InliningCutoff + public static boolean doIterator(VirtualFrame frame, LocalAccessor output, Object object, + @Bind Node inliningTarget, + @Bind BytecodeNode bytecode, + @Cached PyIterNextNode next, + @Cached IsBuiltinObjectProfile errorProfile) { + try { + Object value = next.execute(frame, inliningTarget, object); + output.setObject(bytecode, frame, value); + return true; + } catch (IteratorExhausted e) { + output.setObject(bytecode, frame, null); + return false; + } + } + } + + @Operation + @ConstantOperand(type = TruffleString.class) + public static final class GetMethod { + @Specialization + public static Object doIt(VirtualFrame frame, + TruffleString name, Object obj, + @Bind Node inliningTarget, + @Cached PyObjectGetMethod getMethod) { + return getMethod.execute(frame, inliningTarget, obj, name); + } + } + + @Operation + @ConstantOperand(type = TruffleString.class) + public static final class GetAttribute { + @Specialization + @InliningCutoff + public static Object doIt(VirtualFrame frame, + TruffleString name, + Object obj, + @Cached("create(name)") GetFixedAttributeNode getAttributeNode) { + return getAttributeNode.execute(frame, obj); + } + } + + @Operation + @ConstantOperand(type = TruffleString.class) + public static final class SetAttribute { + @Specialization + @InliningCutoff + public static void doIt(VirtualFrame frame, + TruffleString key, + Object value, + Object object, + @Bind Node inliningTarget, + @Cached PyObjectSetAttr setAttrNode) { + setAttrNode.execute(frame, inliningTarget, object, key, value); + } + } + + @Operation + @ConstantOperand(type = TruffleString.class) + public static final class DeleteAttribute { + @Specialization + @InliningCutoff + public static void doObject(VirtualFrame frame, + TruffleString key, + Object object, + @Bind Node inliningTarget, + @Cached PyObjectSetAttrO setAttrO) { + setAttrO.execute(frame, inliningTarget, object, key, PNone.NO_VALUE); + + } + } + + @Operation + public static final class DeleteItem { + @Specialization + public static void doWithFrame(VirtualFrame frame, Object primary, Object index, + @Bind Node inliningTarget, + @Cached PyObjectDelItem delItemNode) { + delItemNode.execute(frame, inliningTarget, primary, index); + } + } + + @Operation + @ConstantOperand(type = TruffleString.class) + public static final class ReadGlobal { + @Specialization + public static Object perform(VirtualFrame frame, TruffleString name, + @Cached ReadGlobalOrBuiltinNode readNode) { + return readNode.execute(frame, name); + } + } + + @Operation + @ConstantOperand(type = TruffleString.class) + public static final class WriteGlobal { + @Specialization + public static void perform(VirtualFrame frame, TruffleString name, Object value, + @Cached WriteGlobalNode writeNode) { + writeNode.executeObject(frame, name, value); + } + } + + @Operation + @ConstantOperand(type = TruffleString.class) + public static final class DeleteGlobal { + @Specialization + public static void perform(VirtualFrame frame, TruffleString name, + @Cached DeleteGlobalNode deleteNode) { + deleteNode.executeWithGlobals(frame, PArguments.getGlobals(frame), name); + } + } + + @Operation + public static final class BuildClass { + + public static final TruffleString NAME = BuiltinNames.T___BUILD_CLASS__; + + @Specialization + @InliningCutoff + public static Object perform(VirtualFrame frame, + @Cached ReadGlobalOrBuiltinNode readNode) { + return readNode.execute(frame, NAME); + } + } + + @Operation + public static final class MakeList { + @Specialization + public static PList perform(Object[] elements, + @Bind PBytecodeDSLRootNode rootNode) { + return PFactory.createList(rootNode.getLanguage(), elements); + } + } + + @Operation + @ImportStatic({PBytecodeDSLRootNode.class}) + public static final class MakeSet { + @Specialization(guards = "elements.length == 0") + public static PSet doEmpty(VirtualFrame frame, Object[] elements, + @Bind PBytecodeDSLRootNode rootNode) { + // creates set backed by empty HashingStorage + return PFactory.createSet(rootNode.getLanguage()); + } + + @Specialization(guards = "elements.length != 0") + public static PSet doNonEmpty(VirtualFrame frame, Object[] elements, + @Bind PBytecodeDSLRootNode rootNode, + @Bind Node inliningTarget, + @Cached MakeSetStorageNode makeSetStorageNode) { + return PFactory.createSet(rootNode.getLanguage(), makeSetStorageNode.execute(frame, inliningTarget, elements)); + } + } + + @Operation + public static final class MakeFrozenSet { + @Specialization(guards = "elements.length == 0") + public static PFrozenSet doEmpty(VirtualFrame frame, @Variadic Object[] elements, + @Bind PBytecodeDSLRootNode rootNode) { + // creates set backed by empty HashingStorage + return PFactory.createFrozenSet(rootNode.getLanguage()); + } + + @Specialization(guards = "elements.length != 0") + public static PFrozenSet doNonEmpty(VirtualFrame frame, @Variadic Object[] elements, + @Bind PBytecodeDSLRootNode rootNode, + @Bind Node inliningTarget, + @Cached MakeSetStorageNode makeSetStorageNode) { + return PFactory.createFrozenSet(rootNode.getLanguage(), makeSetStorageNode.execute(frame, inliningTarget, elements)); + } + } + + @Operation + public static final class MakeTuple { + @Specialization + public static Object perform(Object[] elements, + @Bind PBytecodeDSLRootNode rootNode) { + return PFactory.createTuple(rootNode.getLanguage(), elements); + } + } + + @Operation + @ConstantOperand(type = int[].class, dimensions = 0) + public static final class MakeConstantIntList { + @Specialization + public static PList perform(int[] array, + @Bind PBytecodeDSLRootNode rootNode) { + SequenceStorage storage = new IntSequenceStorage(PythonUtils.arrayCopyOf(array, array.length)); + return PFactory.createList(rootNode.getLanguage(), storage); + } + } + + @Operation + @ConstantOperand(type = long[].class, dimensions = 0) + public static final class MakeConstantLongList { + @Specialization + public static PList perform(long[] array, + @Bind PBytecodeDSLRootNode rootNode) { + SequenceStorage storage = new LongSequenceStorage(PythonUtils.arrayCopyOf(array, array.length)); + return PFactory.createList(rootNode.getLanguage(), storage); + } + } + + @Operation + @ConstantOperand(type = boolean[].class, dimensions = 0) + public static final class MakeConstantBooleanList { + @Specialization + public static PList perform(boolean[] array, + @Bind PBytecodeDSLRootNode rootNode) { + SequenceStorage storage = new BoolSequenceStorage(PythonUtils.arrayCopyOf(array, array.length)); + return PFactory.createList(rootNode.getLanguage(), storage); + } + } + + @Operation + @ConstantOperand(type = double[].class, dimensions = 0) + public static final class MakeConstantDoubleList { + @Specialization + public static PList perform(double[] array, + @Bind PBytecodeDSLRootNode rootNode) { + SequenceStorage storage = new DoubleSequenceStorage(PythonUtils.arrayCopyOf(array, array.length)); + return PFactory.createList(rootNode.getLanguage(), storage); + } + } + + @Operation + @ConstantOperand(type = Object[].class, dimensions = 0) + public static final class MakeConstantObjectList { + @Specialization + public static PList perform(Object[] array, + @Bind PBytecodeDSLRootNode rootNode) { + SequenceStorage storage = new ObjectSequenceStorage(PythonUtils.arrayCopyOf(array, array.length)); + return PFactory.createList(rootNode.getLanguage(), storage); + } + } + + @Operation + @ConstantOperand(type = int[].class, dimensions = 0) + public static final class MakeConstantIntTuple { + @Specialization + public static PTuple perform(int[] array, + @Bind PBytecodeDSLRootNode rootNode) { + SequenceStorage storage = new IntSequenceStorage(array); + return PFactory.createTuple(rootNode.getLanguage(), storage); + } + } + + @Operation + @ConstantOperand(type = long[].class, dimensions = 0) + public static final class MakeConstantLongTuple { + @Specialization + public static PTuple perform(long[] array, + @Bind PBytecodeDSLRootNode rootNode) { + SequenceStorage storage = new LongSequenceStorage(array); + return PFactory.createTuple(rootNode.getLanguage(), storage); + } + } + + @Operation + @ConstantOperand(type = boolean[].class, dimensions = 0) + public static final class MakeConstantBooleanTuple { + @Specialization + public static PTuple perform(boolean[] array, + @Bind PBytecodeDSLRootNode rootNode) { + SequenceStorage storage = new BoolSequenceStorage(array); + return PFactory.createTuple(rootNode.getLanguage(), storage); + } + } + + @Operation + @ConstantOperand(type = double[].class, dimensions = 0) + public static final class MakeConstantDoubleTuple { + @Specialization + public static PTuple perform(double[] array, + @Bind PBytecodeDSLRootNode rootNode) { + SequenceStorage storage = new DoubleSequenceStorage(array); + return PFactory.createTuple(rootNode.getLanguage(), storage); + } + } + + @Operation + @ConstantOperand(type = Object[].class, dimensions = 0) + public static final class MakeConstantObjectTuple { + @Specialization + public static PTuple perform(Object[] array, + @Bind PBytecodeDSLRootNode rootNode) { + SequenceStorage storage = new ObjectSequenceStorage(array); + return PFactory.createTuple(rootNode.getLanguage(), storage); + } + } + + @Operation + public static final class MakeSlice { + + @Specialization + public static Object doIII(int start, int end, int step, + @Bind PBytecodeDSLRootNode rootNode) { + return PFactory.createIntSlice(rootNode.getLanguage(), start, end, step); + } + + @Specialization + public static Object doNIN(PNone start, int end, PNone step, + @Bind PBytecodeDSLRootNode rootNode) { + return PFactory.createIntSlice(rootNode.getLanguage(), 0, end, 1, true, true); + } + + @Specialization + public static Object doIIN(int start, int end, PNone step, + @Bind PBytecodeDSLRootNode rootNode) { + return PFactory.createIntSlice(rootNode.getLanguage(), start, end, 1, false, true); + } + + @Specialization + public static Object doNII(PNone start, int end, int step, + @Bind PBytecodeDSLRootNode rootNode) { + return PFactory.createIntSlice(rootNode.getLanguage(), 0, end, step, true, false); + } + + @Specialization + @InliningCutoff + public static Object doGeneric(Object start, Object end, Object step, + @Bind PBytecodeDSLRootNode rootNode) { + return PFactory.createObjectSlice(rootNode.getLanguage(), start, end, step); + } + } + + @Operation + @ConstantOperand(type = TruffleString[].class, dimensions = 0, specifyAtEnd = true) + public static final class MakeKeywords { + @Specialization + public static PKeyword[] perform(@Variadic Object[] values, TruffleString[] keys) { + CompilerAsserts.partialEvaluationConstant(keys.length); + PKeyword[] result = new PKeyword[keys.length]; + for (int i = 0; i < keys.length; i++) { + result[i] = new PKeyword(keys[i], values[i]); + } + return result; + } + } + + @Operation + public static final class MappingToKeywords { + @Specialization + public static PKeyword[] perform(Object sourceCollection, + @Bind Node inliningTarget, + @Cached ExpandKeywordStarargsNode expandKeywordStarargsNode, + @Cached PRaiseNode raise) { + return expandKeywordStarargsNode.execute(inliningTarget, sourceCollection); + } + } + + @Operation + @ConstantOperand(type = int.class) + public static final class MakeDict { + @Specialization(guards = "entries == 0") + public static PDict empty(VirtualFrame frame, int entries, @Variadic Object[] keysAndValues, + @Bind PBytecodeDSLRootNode rootNode) { + // creates a dict with empty hashing storage + return PFactory.createDict(rootNode.getLanguage()); + } + + @Specialization + public static PDict empty(VirtualFrame frame, int entries, @Variadic Object[] keysAndValues, + @Bind PBytecodeDSLRootNode rootNode, + @Bind Node inliningTarget, + @Cached PyObjectHashNode hashNode, + @Cached ObjectHashMap.PutNode putNode, + @Cached DictNodes.UpdateNode updateNode) { + if (keysAndValues.length != entries * 2) { + throw CompilerDirectives.shouldNotReachHere(); + } + ObjectHashMap map = new ObjectHashMap(keysAndValues.length / 2, false); + PDict dict = PFactory.createDict(rootNode.getLanguage(), new EconomicMapStorage(map, false)); + for (int i = 0; i < entries; i++) { + Object key = keysAndValues[i * 2]; + Object value = keysAndValues[i * 2 + 1]; + // Each entry represents either a k: v pair or a **splats. splats have no key. + if (key == PNone.NO_VALUE) { + updateNode.execute(frame, dict, value); + assert dict.getDictStorage() instanceof EconomicMapStorage es && es.mapIsEqualTo(map); + } else { + long hash = hashNode.execute(frame, inliningTarget, key); + putNode.put(frame, inliningTarget, map, key, hash, value); + } + } + return dict; + } + } + + @Operation + public static final class SetDictItem { + @Specialization + public static void perform(VirtualFrame frame, PDict item, Object key, Object value, + @Bind Node inliningTarget, + @Cached HashingStorageSetItem setItem) { + item.setDictStorage(setItem.execute(frame, inliningTarget, item.getDictStorage(), key, value)); + } + } + + public static final class LiteralBoolean { + @Specialization + public static boolean doBoolean(boolean value) { + return value; + } + } + + @Operation + public static final class SetItem { + @Specialization + public static void doIt(VirtualFrame frame, Object value, Object primary, Object slice, + @Bind Node inliningTarget, + @Shared @Cached PyObjectSetItem setItemNode) { + setItemNode.execute(frame, inliningTarget, primary, slice, value); + } + } + + @Operation + @ConstantOperand(type = LocalRangeAccessor.class) + @ImportStatic({PGuards.class}) + public static final class UnpackToLocals { + @Specialization(guards = "isBuiltinSequence(sequence)") + public static void doUnpackSequence(VirtualFrame localFrame, LocalRangeAccessor results, PSequence sequence, + @Bind Node inliningTarget, + @Bind BytecodeNode bytecode, + @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode, + @Cached SequenceStorageNodes.GetItemScalarNode getItemNode, + @Shared @Cached PRaiseNode raiseNode) { + SequenceStorage storage = getSequenceStorageNode.execute(inliningTarget, sequence); + int len = storage.length(); + int count = results.getLength(); + CompilerAsserts.partialEvaluationConstant(count); + + if (len != count) { + raiseError(inliningTarget, raiseNode, len, count); + } + + for (int i = 0; i < count; i++) { + results.setObject(bytecode, localFrame, i, getItemNode.execute(inliningTarget, storage, i)); + } + } + + @InliningCutoff + private static void raiseError(Node inliningTarget, PRaiseNode raiseNode, int len, int count) { + if (len < count) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK, count, len); + } else { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.TOO_MANY_VALUES_TO_UNPACK, count); + } + } + + @Specialization + @InliningCutoff + public static void doUnpackIterable(VirtualFrame virtualFrame, LocalRangeAccessor results, Object collection, + @Bind Node inliningTarget, + @Bind BytecodeNode bytecode, + @Cached PyObjectGetIter getIter, + @Cached PyIterNextNode getNextNode, + @Cached IsBuiltinObjectProfile notIterableProfile, + @Shared @Cached PRaiseNode raiseNode) { + int count = results.getLength(); + CompilerAsserts.partialEvaluationConstant(count); + + Object iterator; + try { + iterator = getIter.execute(virtualFrame, inliningTarget, collection); + } catch (PException e) { + e.expectTypeError(inliningTarget, notIterableProfile); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_UNPACK_NON_ITERABLE, collection); + } + for (int i = 0; i < count; i++) { + try { + Object value = getNextNode.execute(virtualFrame, inliningTarget, iterator); + results.setObject(bytecode, virtualFrame, i, value); + } catch (IteratorExhausted e) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK, count, i); + } + } + try { + Object value = getNextNode.execute(virtualFrame, inliningTarget, iterator); + } catch (IteratorExhausted e) { + return; + } + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.TOO_MANY_VALUES_TO_UNPACK, count); + } + } + + @Operation + @ConstantOperand(type = int.class) + @ConstantOperand(type = LocalRangeAccessor.class) + @ImportStatic({PGuards.class}) + @SuppressWarnings("truffle-interpreted-performance") + public static final class UnpackStarredToLocals { + @Specialization(guards = "isBuiltinSequence(sequence)") + public static void doUnpackSequence(VirtualFrame localFrame, + int starIndex, + LocalRangeAccessor results, + PSequence sequence, + @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode, + @Shared @Cached SequenceStorageNodes.GetItemScalarNode getItemNode, + @Shared @Cached SequenceStorageNodes.GetItemSliceNode getItemSliceNode, + @Bind PBytecodeDSLRootNode rootNode, + @Bind BytecodeNode bytecode, + @Bind Node inliningTarget, + @Shared @Cached PRaiseNode raiseNode) { + int resultsLength = results.getLength(); + int countBefore = starIndex; + int countAfter = resultsLength - starIndex - 1; + + SequenceStorage storage = getSequenceStorageNode.execute(inliningTarget, sequence); + int len = storage.length(); + + int starLen = len - resultsLength + 1; + if (starLen < 0) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK_EX, countBefore + countAfter, len); + } + + copyToLocalsFromSequence(storage, 0, 0, countBefore, results, localFrame, inliningTarget, bytecode, getItemNode); + PList starList = PFactory.createList(rootNode.getLanguage(), getItemSliceNode.execute(storage, countBefore, countBefore + starLen, 1, starLen)); + results.setObject(bytecode, localFrame, starIndex, starList); + copyToLocalsFromSequence(storage, starIndex + 1, len - countAfter, countAfter, results, localFrame, inliningTarget, bytecode, getItemNode); + } + + @Specialization + @InliningCutoff + public static void doUnpackIterable(VirtualFrame frame, + int starIndex, + LocalRangeAccessor results, + Object collection, + @Cached PyObjectGetIter getIter, + @Cached PyIterNextNode getNextNode, + @Cached IsBuiltinObjectProfile notIterableProfile, + @Cached ListNodes.ConstructListNode constructListNode, + @Shared @Cached SequenceStorageNodes.GetItemScalarNode getItemNode, + @Shared @Cached SequenceStorageNodes.GetItemSliceNode getItemSliceNode, + @Bind PBytecodeDSLRootNode rootNode, + @Bind BytecodeNode bytecode, + @Bind Node inliningTarget, + @Shared @Cached PRaiseNode raiseNode) { + int resultsLength = results.getLength(); + int countBefore = starIndex; + int countAfter = resultsLength - starIndex - 1; + + Object iterator; + try { + iterator = getIter.execute(frame, inliningTarget, collection); + } catch (PException e) { + e.expectTypeError(inliningTarget, notIterableProfile); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CANNOT_UNPACK_NON_ITERABLE, collection); + } + + copyToLocalsFromIterator(frame, inliningTarget, iterator, countBefore, results, bytecode, countBefore + countAfter, getNextNode, raiseNode); + + PList starAndAfter = constructListNode.execute(frame, iterator); + SequenceStorage storage = starAndAfter.getSequenceStorage(); + int lenAfter = storage.length(); + if (lenAfter < countAfter) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK_EX, countBefore + countAfter, countBefore + lenAfter); + } + if (countAfter == 0) { + results.setObject(bytecode, frame, starIndex, starAndAfter); + } else { + int starLen = lenAfter - countAfter; + PList starList = PFactory.createList(rootNode.getLanguage(), getItemSliceNode.execute(storage, 0, starLen, 1, starLen)); + results.setObject(bytecode, frame, starIndex, starList); + + copyToLocalsFromSequence(storage, starIndex + 1, starLen, countAfter, results, frame, inliningTarget, bytecode, getItemNode); + } + } + + private static void copyToLocalsFromIterator(VirtualFrame frame, Node inliningTarget, Object iterator, int length, LocalRangeAccessor results, + BytecodeNode bytecode, int requiredLength, + PyIterNextNode getNextNode, PRaiseNode raiseNode) { + CompilerAsserts.partialEvaluationConstant(length); + for (int i = 0; i < length; i++) { + try { + Object item = getNextNode.execute(frame, inliningTarget, iterator); + results.setObject(bytecode, frame, i, item); + } catch (IteratorExhausted e) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK_EX, requiredLength, i); + } + } + } + + private static void copyToLocalsFromSequence(SequenceStorage storage, int runOffset, int offset, int length, LocalRangeAccessor run, + VirtualFrame localFrame, Node inliningTarget, BytecodeNode bytecode, SequenceStorageNodes.GetItemScalarNode getItemNode) { + CompilerAsserts.partialEvaluationConstant(length); + for (int i = 0; i < length; i++) { + run.setObject(bytecode, localFrame, runOffset + i, getItemNode.execute(inliningTarget, storage, offset + i)); + } + } + } + + private static RuntimeException notSupported(Object left, Object right, Node nodeForRaise, TruffleString operator) { + throw PRaiseNode.raiseStatic(nodeForRaise, PythonErrorType.TypeError, ErrorMessages.NOT_SUPPORTED_BETWEEN_INSTANCES, operator, left, right); + } + + @Operation + public static final class Le { + @Specialization + public static boolean cmp(int left, int right) { + return left <= right; + } + + @Specialization + public static boolean cmp(long left, long right) { + return left <= right; + } + + @Specialization + public static boolean cmp(char left, char right) { + return left <= right; + } + + @Specialization + public static boolean cmp(byte left, byte right) { + return left <= right; + } + + @Specialization + public static boolean cmp(double left, double right) { + return left <= right; + } + + @Specialization + public static boolean cmp(int left, double right) { + return left <= right; + } + + @Specialization + public static boolean cmp(double left, int right) { + return left <= right; + } + + @Specialization + @InliningCutoff + public static Object doGeneric(VirtualFrame frame, Object left, Object right, + @Cached GenericRichCompare richCompareNode) { + return richCompareNode.execute(frame, left, right, RichCmpOp.Py_LE); + } + } + + @Operation + public static final class Lt { + @Specialization + public static boolean cmp(int left, int right) { + return left < right; + } + + @Specialization + public static boolean cmp(long left, long right) { + return left < right; + } + + @Specialization + public static boolean cmp(char left, char right) { + return left < right; + } + + @Specialization + public static boolean cmp(byte left, byte right) { + return left < right; + } + + @Specialization + public static boolean cmp(double left, double right) { + return left < right; + } + + @Specialization + public static boolean cmp(int left, double right) { + return left < right; + } + + @Specialization + public static boolean cmp(double left, int right) { + return left < right; + } + + @Specialization + @InliningCutoff + public static Object doGeneric(VirtualFrame frame, Object left, Object right, + @Cached GenericRichCompare richCompareNode) { + return richCompareNode.execute(frame, left, right, RichCmpOp.Py_LT); + } + } + + @Operation + public static final class Ge { + @Specialization + public static boolean cmp(int left, int right) { + return left >= right; + } + + @Specialization + public static boolean cmp(long left, long right) { + return left >= right; + } + + @Specialization + public static boolean cmp(char left, char right) { + return left >= right; + } + + @Specialization + public static boolean cmp(byte left, byte right) { + return left >= right; + } + + @Specialization + public static boolean cmp(double left, double right) { + return left >= right; + } + + @Specialization + public static boolean cmp(int left, double right) { + return left >= right; + } + + @Specialization + public static boolean cmp(double left, int right) { + return left >= right; + } + + @Specialization + @InliningCutoff + public static Object doGeneric(VirtualFrame frame, Object left, Object right, + @Cached GenericRichCompare richCompareNode) { + return richCompareNode.execute(frame, left, right, RichCmpOp.Py_GE); + } + } + + @Operation + public static final class Gt { + @Specialization + public static boolean cmp(int left, int right) { + return left > right; + } + + @Specialization + public static boolean cmp(long left, long right) { + return left > right; + } + + @Specialization + public static boolean cmp(char left, char right) { + return left > right; + } + + @Specialization + public static boolean cmp(byte left, byte right) { + return left > right; + } + + @Specialization + public static boolean cmp(double left, double right) { + return left > right; + } + + @Specialization + public static boolean cmp(int left, double right) { + return left > right; + } + + @Specialization + public static boolean cmp(double left, int right) { + return left > right; + } + + @Specialization + @InliningCutoff + public static final Object doGeneric(VirtualFrame frame, Object left, Object right, + @Cached GenericRichCompare richCompareNode) { + return richCompareNode.execute(frame, left, right, RichCmpOp.Py_GT); + } + } + + @Operation + public static final class Eq { + @Specialization + public static boolean cmp(int left, int right) { + return left == right; + } + + @Specialization + public static boolean cmp(long left, long right) { + return left == right; + } + + @Specialization + public static boolean cmp(char left, char right) { + return left == right; + } + + @Specialization + public static boolean cmp(byte left, byte right) { + return left == right; + } + + @Specialization + public static boolean cmp(double left, double right) { + return left == right; + } + + @Specialization + public static boolean cmp(TruffleString left, TruffleString right, + @Cached TruffleString.EqualNode equalNode) { + return equalNode.execute(left, right, PythonUtils.TS_ENCODING); + } + + @Specialization + public static boolean cmp(int left, double right) { + return left == right; + } + + @Specialization + public static boolean cmp(double left, int right) { + return left == right; + } + + @Specialization + @InliningCutoff + public static Object doGeneric(VirtualFrame frame, Object left, Object right, + @Cached GenericRichCompare richCompareNode) { + return richCompareNode.execute(frame, left, right, RichCmpOp.Py_EQ); + } + } + + @Operation + public static final class Ne { + @Specialization + public static boolean cmp(int left, int right) { + return left != right; + } + + @Specialization + public static boolean cmp(long left, long right) { + return left != right; + } + + @Specialization + public static boolean cmp(char left, char right) { + return left != right; + } + + @Specialization + public static boolean cmp(byte left, byte right) { + return left != right; + } + + @Specialization + public static boolean cmp(double left, double right) { + return left != right; + } + + @Specialization + public static boolean cmp(TruffleString left, TruffleString right, + @Cached TruffleString.EqualNode equalNode) { + return !equalNode.execute(left, right, PythonUtils.TS_ENCODING); + } + + @Specialization + public static boolean cmp(int left, double right) { + return left != right; + } + + @Specialization + public static boolean cmp(double left, int right) { + return left != right; + } + + @Specialization + @InliningCutoff + public static Object doGeneric(VirtualFrame frame, Object left, Object right, + @Cached GenericRichCompare richCompareNode) { + return richCompareNode.execute(frame, left, right, RichCmpOp.Py_NE); + } + } + + @Operation + @ConstantOperand(type = TruffleString.class) + @ConstantOperand(type = TruffleString[].class, dimensions = 0) + @ConstantOperand(type = int.class) + public static final class Import { + @Specialization + @InliningCutoff + public static Object doImport(VirtualFrame frame, TruffleString name, TruffleString[] fromList, int level, + @Cached ImportNode node) { + return node.execute(frame, name, PArguments.getGlobals(frame), fromList, level); + } + } + + @Operation + @ConstantOperand(type = TruffleString.class) + public static final class ImportFrom { + @Specialization + @InliningCutoff + public static Object doImport(VirtualFrame frame, TruffleString name, Object module, + @Cached ImportFromNode node) { + return node.execute(frame, module, name); + } + } + + @Operation + @ConstantOperand(type = TruffleString.class) + @ConstantOperand(type = int.class) + public static final class ImportStar { + @Specialization + @InliningCutoff + public static void doImport(VirtualFrame frame, TruffleString name, int level, + @Cached("create(name, level)") ImportStarNode node) { + node.execute(frame, name, level); + } + + @NeverDefault + static ImportStarNode create(TruffleString name, int level) { + return ImportStarNode.create(); + } + } + + @Operation + public static final class Raise { + @Specialization + public static void perform(VirtualFrame frame, Object typeOrExceptionObject, Object cause, + @Bind PBytecodeDSLRootNode root, + @Cached RaiseNode raiseNode) { + raiseNode.execute(frame, typeOrExceptionObject, cause, !root.isInternal()); + } + } + + @Operation + public static final class Reraise { + @Specialization + public static void doPException(PException ex, + @Bind PBytecodeDSLRootNode root) { + throw ex.getExceptionForReraise(!root.isInternal()); + } + + @Specialization + public static void doAbstractTruffleException(AbstractTruffleException ex) { + throw ex; + } + } + + /** + * Throw is used internally for our try-catch-finally implementation when we need to throw an + * exception and catch it elsewhere. We don't need to do any of the work done by RaiseNode. + */ + @Operation + public static final class Throw { + @Specialization + public static void doAbstractTruffleException(AbstractTruffleException ex) { + throw ex; + } + } + + @Operation + public static final class GetCurrentException { + @Specialization + public static AbstractTruffleException doPException(VirtualFrame frame) { + return PArguments.getException(frame); + } + } + + @Operation + public static final class SetCurrentException { + @Specialization + @InliningCutoff + public static void doPException(VirtualFrame frame, AbstractTruffleException ex) { + PArguments.setException(frame, ex); + } + } + + @Operation + public static final class MarkExceptionAsCaught { + @Specialization + @InliningCutoff + public static void doPException(VirtualFrame frame, PException ex, + @Bind PBytecodeDSLRootNode rootNode) { + ex.markAsCaught(frame, rootNode); + } + + @Fallback + @InliningCutoff + public static void doNothing(@SuppressWarnings("unused") Object ex) { + } + } + + @Operation + public static final class AssertFailed { + @Specialization + public static void doAssertFailed(VirtualFrame frame, Object assertionMessage, + @Bind PBytecodeDSLRootNode rooNode) { + if (assertionMessage == PNone.NO_VALUE) { + throw PRaiseNode.raiseStatic(rooNode, AssertionError); + } else { + throw PRaiseNode.raiseStatic(rooNode, AssertionError, new Object[]{assertionMessage}); + } + } + } + + @Operation + @ConstantOperand(type = int.class) + public static final class LoadCell { + @Specialization + public static Object doLoadCell(int index, PCell cell, + @Bind PBytecodeDSLRootNode rootNode, + @Bind Node inliningTarget, + @Cached PRaiseNode raiseNode) { + return checkUnboundCell(cell, index, rootNode, inliningTarget, raiseNode); + } + } + + @Operation + @ConstantOperand(type = int.class) + public static final class ClassLoadCell { + @Specialization + public static Object doLoadCell(VirtualFrame frame, int index, PCell cell, + @Bind PBytecodeDSLRootNode rootNode, + @Bind Node inliningTarget, + @Cached ReadFromLocalsNode readLocalsNode, + @Cached PRaiseNode raiseNode) { + CodeUnit co = rootNode.getCodeUnit(); + TruffleString name = co.freevars[index - co.cellvars.length]; + Object locals = PArguments.getSpecialArgument(frame); + Object value = readLocalsNode.execute(frame, inliningTarget, locals, name); + if (value != PNone.NO_VALUE) { + return value; + } else { + return checkUnboundCell(cell, index, rootNode, inliningTarget, raiseNode); + } + } + } + + @Operation + public static final class StoreCell { + @Specialization + public static void doStoreCell(PCell cell, Object value) { + cell.setRef(value); + } + } + + @Operation + public static final class CreateCell { + @Specialization + public static PCell doCreateCell(Object value) { + PCell cell = new PCell(Assumption.create()); + cell.setRef(value); + return cell; + } + } + + @Operation + @ConstantOperand(type = int.class) + public static final class ClearCell { + @Specialization + public static void doClearCell(int index, PCell cell, + @Bind PBytecodeDSLRootNode rootNode, + @Bind Node inliningTarget, + @Cached PRaiseNode raiseNode) { + checkUnboundCell(cell, index, rootNode, inliningTarget, raiseNode); + cell.clearRef(); + } + } + + @Operation + @ConstantOperand(type = LocalAccessor.class) + public static final class ClearLocal { + @Specialization + public static void doClearLocal(VirtualFrame frame, LocalAccessor localAccessor, + @Bind BytecodeNode bytecode) { + localAccessor.setObject(bytecode, frame, null); + } + } + + @Operation + public static final class LoadClosure { + @Specialization + public static PCell[] doLoadClosure(VirtualFrame frame) { + return PArguments.getClosure(frame); + } + } + + @Operation + @ConstantOperand(type = LocalRangeAccessor.class) + public static final class StoreRange { + @Specialization + public static void perform(VirtualFrame frame, LocalRangeAccessor locals, Object[] values, + @Bind BytecodeNode bytecode) { + CompilerAsserts.partialEvaluationConstant(locals.getLength()); + assert values.length == locals.getLength(); + for (int i = 0; i < locals.getLength(); i++) { + locals.setObject(bytecode, frame, i, values[i]); + } + } + } + + @Operation + public static final class MakeCellArray { + @Specialization + public static PCell[] doMakeCellArray(@Variadic Object[] cells) { + return PCell.toCellArray(cells); + } + } + + /** + * Flattens an array of arrays. Used for splatting Starred expressions. + */ + @Operation + @ConstantOperand(type = int.class, specifyAtEnd = true) + public static final class Unstar { + @Specialization(guards = "length != 1") + public static Object[] perform(@Variadic Object[] values, int length) { + // if len <= 1, we should emit load constant "empty array", or emit just unpack starred + assert length > 1; + CompilerAsserts.partialEvaluationConstant(length); + int totalLength = 0; + for (int i = 0; i < length; i++) { + totalLength += ((Object[]) values[i]).length; + } + Object[] result = new Object[totalLength]; + int idx = 0; + for (int i = 0; i < length; i++) { + int nl = ((Object[]) values[i]).length; + System.arraycopy(values[i], 0, result, idx, nl); + idx += nl; + } + return result; + } + } + + @Operation + @ConstantOperand(type = LocalAccessor.class) + public static final class KwargsMerge { + @Specialization + public static PDict doMerge(VirtualFrame frame, + LocalAccessor callee, + PDict dict, + Object toMerge, + @Bind PBytecodeDSLRootNode rootNode, + @Bind Node inliningTarget, + @Bind BytecodeNode bytecodeNode, + @Cached ConcatDictToStorageNode concatNode, + @Cached PRaiseNode raise) { + try { + HashingStorage resultStorage = concatNode.execute(frame, dict.getDictStorage(), toMerge); + dict.setDictStorage(resultStorage); + } catch (SameDictKeyException e) { + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.S_GOT_MULTIPLE_VALUES_FOR_KEYWORD_ARG, + PyObjectFunctionStr.execute(callee.getObject(bytecodeNode, frame)), + e.getKey()); + } catch (NonMappingException e) { + throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ARG_AFTER_MUST_BE_MAPPING, PyObjectFunctionStr.execute(callee.getObject(bytecodeNode, frame)), + toMerge); + } + return dict; + } + } + + @Operation + @ImportStatic({PGuards.class}) + public static final class UnpackStarred { + public static boolean isListOrTuple(PSequence obj, Node inliningTarget, InlinedConditionProfile isListProfile) { + return isListProfile.profile(inliningTarget, PGuards.isBuiltinList(obj)) || PGuards.isBuiltinTuple(obj); + } + + @Specialization(guards = "isListOrTuple(seq, inliningTarget, isListProfile)", limit = "1") + static Object[] fromListOrTuple(PSequence seq, + @Bind Node inliningTarget, + @SuppressWarnings("unused") @Cached InlinedConditionProfile isListProfile, + @Exclusive @Cached SequenceNodes.GetPSequenceStorageNode getStorage, + @Exclusive @Cached SequenceStorageNodes.ToArrayNode toArrayNode) { + return toArrayNode.execute(inliningTarget, getStorage.execute(inliningTarget, seq)); + } + + @Specialization(guards = "isNoValue(none)") + static Object[] none(@SuppressWarnings("unused") PNone none) { + return PythonUtils.EMPTY_OBJECT_ARRAY; + } + + @Fallback + @InliningCutoff + public static Object[] doUnpackIterable(VirtualFrame virtualFrame, Object collection, + @Bind Node inliningTarget, + @Cached PyObjectGetIter getIter, + @Cached PyIterNextNode getNextNode, + @Cached IsBuiltinObjectProfile notIterableProfile, + @Shared @Cached PRaiseNode raiseNode) { + + Object iterator; + try { + iterator = getIter.execute(virtualFrame, inliningTarget, collection); + } catch (PException e) { + e.expectTypeError(inliningTarget, notIterableProfile); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_UNPACK_NON_ITERABLE, collection); + } + ArrayBuilder result = new ArrayBuilder<>(); + while (true) { + try { + Object item = getNextNode.execute(virtualFrame, inliningTarget, iterator); + result.add(item); + } catch (IteratorExhausted e) { + return result.toArray(new Object[0]); + } + } + } + } + + @Operation + @ConstantOperand(type = int.class) + @ImportStatic({PGuards.class}) + public static final class UnpackSequence { + @Specialization(guards = "isBuiltinSequence(sequence)") + public static Object[] doUnpackSequence(VirtualFrame localFrame, int count, PSequence sequence, + @Bind Node inliningTarget, + @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode, + @Cached SequenceStorageNodes.GetItemScalarNode getItemNode, + @Exclusive @Cached PRaiseNode raiseNode) { + CompilerAsserts.partialEvaluationConstant(count); + SequenceStorage storage = getSequenceStorageNode.execute(inliningTarget, sequence); + int len = storage.length(); + if (len != count) { + throw raiseError(inliningTarget, raiseNode, len, count); + } + Object[] result = new Object[len]; + for (int i = 0; i < count; i++) { + result[i] = getItemNode.execute(inliningTarget, storage, i); + } + return result; + } + + @InliningCutoff + private static PException raiseError(Node inliningTarget, PRaiseNode raiseNode, int len, int count) { + if (len < count) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK, count, len); + } else { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.TOO_MANY_VALUES_TO_UNPACK, count); + } + } + + @Specialization + @InliningCutoff + public static Object[] doUnpackIterable(VirtualFrame virtualFrame, + int count, + Object collection, + @Bind Node inliningTarget, + @Cached PyObjectGetIter getIter, + @Cached PyIterNextNode getNextNode, + @Cached IsBuiltinObjectProfile notIterableProfile, + @Exclusive @Cached PRaiseNode raiseNode) { + CompilerAsserts.partialEvaluationConstant(count); + Object iterator; + try { + iterator = getIter.execute(virtualFrame, inliningTarget, collection); + } catch (PException e) { + e.expectTypeError(inliningTarget, notIterableProfile); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_UNPACK_NON_ITERABLE, collection); + } + + Object[] result = new Object[count]; + for (int i = 0; i < count; i++) { + try { + Object value = getNextNode.execute(virtualFrame, inliningTarget, iterator); + result[i] = value; + } catch (IteratorExhausted e) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK, count, i); + } + } + try { + Object value = getNextNode.execute(virtualFrame, inliningTarget, iterator); + } catch (IteratorExhausted e) { + return result; + } + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.TOO_MANY_VALUES_TO_UNPACK, count); + } + } + + @Operation + @ConstantOperand(type = int.class) + @ConstantOperand(type = int.class) + @ImportStatic({PGuards.class}) + public static final class UnpackEx { + @Specialization(guards = "isBuiltinSequence(sequence)") + public static Object[] doUnpackSequence(VirtualFrame localFrame, + int countBefore, + int countAfter, + PSequence sequence, + @Bind Node inliningTarget, + @SuppressWarnings("unused") @Cached GetPythonObjectClassNode getClassNode, + @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode, + @Exclusive @Cached SequenceStorageNodes.GetItemScalarNode getItemNode, + @Exclusive @Cached SequenceStorageNodes.GetItemSliceNode getItemSliceNode, + @Exclusive @Cached PRaiseNode raiseNode) { + SequenceStorage storage = getSequenceStorageNode.execute(inliningTarget, sequence); + int len = storage.length(); + int starLen = len - countBefore - countAfter; + if (starLen < 0) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK_EX, countBefore + countAfter, len); + } + + Object[] result = new Object[countBefore + 1 + countAfter]; + copyItemsToArray(inliningTarget, storage, 0, result, 0, countBefore, getItemNode); + result[countBefore] = PFactory.createList(PythonLanguage.get(inliningTarget), getItemSliceNode.execute(storage, countBefore, countBefore + starLen, 1, starLen)); + copyItemsToArray(inliningTarget, storage, len - countAfter, result, countBefore + 1, countAfter, getItemNode); + return result; + } + + @Specialization + @InliningCutoff + public static Object[] doUnpackIterable(VirtualFrame virtualFrame, + int countBefore, + int countAfter, + Object collection, + @Bind Node inliningTarget, + @Cached PyObjectGetIter getIter, + @Cached PyIterNextNode getNextNode, + @Cached IsBuiltinObjectProfile notIterableProfile, + @Cached ListNodes.ConstructListNode constructListNode, + @Exclusive @Cached SequenceStorageNodes.GetItemScalarNode getItemNode, + @Exclusive @Cached SequenceStorageNodes.GetItemSliceNode getItemSliceNode, + @Exclusive @Cached PRaiseNode raiseNode) { + Object iterator; + try { + iterator = getIter.execute(virtualFrame, inliningTarget, collection); + } catch (PException e) { + e.expectTypeError(inliningTarget, notIterableProfile); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_UNPACK_NON_ITERABLE, collection); + } + + Object[] result = new Object[countBefore + 1 + countAfter]; + copyItemsToArray(virtualFrame, inliningTarget, iterator, result, 0, countBefore, countBefore + countAfter, getNextNode, raiseNode); + PList starAndAfter = constructListNode.execute(virtualFrame, iterator); + SequenceStorage storage = starAndAfter.getSequenceStorage(); + int lenAfter = storage.length(); + if (lenAfter < countAfter) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK_EX, countBefore + countAfter, countBefore + lenAfter); + } + if (countAfter == 0) { + result[countBefore] = starAndAfter; + } else { + int starLen = lenAfter - countAfter; + PList starList = PFactory.createList(PythonLanguage.get(inliningTarget), getItemSliceNode.execute(storage, 0, starLen, 1, starLen)); + result[countBefore] = starList; + copyItemsToArray(inliningTarget, storage, starLen, result, countBefore + 1, countAfter, getItemNode); + } + return result; + } + + private static void copyItemsToArray(VirtualFrame frame, Node inliningTarget, Object iterator, Object[] destination, int destinationOffset, int length, int totalLength, + PyIterNextNode getNextNode, PRaiseNode raiseNode) { + CompilerAsserts.partialEvaluationConstant(destinationOffset); + CompilerAsserts.partialEvaluationConstant(length); + CompilerAsserts.partialEvaluationConstant(totalLength); + for (int i = 0; i < length; i++) { + try { + Object value = getNextNode.execute(frame, inliningTarget, iterator); + destination[destinationOffset + i] = value; + } catch (IteratorExhausted e) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK_EX, totalLength, destinationOffset + i); + } + } + } + + private static void copyItemsToArray(Node inliningTarget, SequenceStorage source, int sourceOffset, Object[] destination, int destinationOffset, int length, + SequenceStorageNodes.GetItemScalarNode getItemNode) { + CompilerAsserts.partialEvaluationConstant(sourceOffset); + CompilerAsserts.partialEvaluationConstant(destinationOffset); + CompilerAsserts.partialEvaluationConstant(length); + for (int i = 0; i < length; i++) { + destination[destinationOffset + i] = getItemNode.execute(inliningTarget, source, sourceOffset + i); + } + } + } + + @Operation + public static final class CallNilaryMethod { + @Specialization + @InliningCutoff + public static Object doCall(VirtualFrame frame, Object callable, + @Cached CallNode node) { + return node.execute(frame, callable, PythonUtils.EMPTY_OBJECT_ARRAY, PKeyword.EMPTY_KEYWORDS); + } + } + + @Operation + public static final class CallUnaryMethod { + @Specialization + @InliningCutoff + public static Object doCall(VirtualFrame frame, Object callable, Object arg0, + @Cached CallUnaryMethodNode node) { + return node.executeObject(frame, callable, arg0); + } + } + + @Operation + public static final class CallBinaryMethod { + @Specialization + @InliningCutoff + public static Object doObject(VirtualFrame frame, Object callable, Object arg0, Object arg1, + @Cached CallBinaryMethodNode node) { + return node.executeObject(frame, callable, arg0, arg1); + } + } + + @Operation + public static final class CallTernaryMethod { + @Specialization + @InliningCutoff + public static Object doCall(VirtualFrame frame, Object callable, Object arg0, Object arg1, Object arg2, + @Cached CallTernaryMethodNode node) { + return node.execute(frame, callable, arg0, arg1, arg2); + } + } + + @Operation + public static final class CallQuaternaryMethod { + @Specialization + @InliningCutoff + public static Object doCall(VirtualFrame frame, Object callable, Object arg0, Object arg1, Object arg2, Object arg3, + @Cached CallQuaternaryMethodNode node) { + return node.execute(frame, callable, arg0, arg1, arg2, arg3); + } + } + + @Operation + public static final class CallVarargsMethod { + @Specialization + @InliningCutoff + public static Object doCall(VirtualFrame frame, Object callable, Object[] args, PKeyword[] keywords, + @Cached CallNode node) { + return node.execute(frame, callable, args, keywords); + } + } + + @Operation + @ConstantOperand(type = LocalAccessor.class) + @ConstantOperand(type = LocalAccessor.class) + public static final class ContextManagerEnter { + @Specialization + @InliningCutoff + public static void doEnter(VirtualFrame frame, + LocalAccessor exitSetter, + LocalAccessor resultSetter, + Object contextManager, + @Bind Node inliningTarget, + @Bind BytecodeNode bytecode, + @Cached GetClassNode getClass, + @Cached LookupSpecialMethodNode.Dynamic lookupEnter, + @Cached LookupSpecialMethodNode.Dynamic lookupExit, + @Cached CallUnaryMethodNode callEnter, + @Cached PRaiseNode raiseNode) { + Object type = getClass.execute(inliningTarget, contextManager); + Object enter = lookupEnter.execute(frame, inliningTarget, type, T___ENTER__, contextManager); + if (enter == PNone.NO_VALUE) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.N_OBJECT_DOES_NOT_SUPPORT_CONTEXT_MANAGER_PROTOCOL, type); + } + Object exit = lookupExit.execute(frame, inliningTarget, type, T___EXIT__, contextManager); + if (exit == PNone.NO_VALUE) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.N_OBJECT_DOES_NOT_SUPPORT_CONTEXT_MANAGER_PROTOCOL_EXIT, type); + } + Object result = callEnter.executeObject(frame, enter, contextManager); + exitSetter.setObject(bytecode, frame, exit); + resultSetter.setObject(bytecode, frame, result); + } + } + + @Operation + public static final class ContextManagerExit { + @Specialization + public static void doRegular(VirtualFrame frame, PNone none, Object exit, Object contextManager, + @Shared @Cached CallQuaternaryMethodNode callExit) { + callExit.execute(frame, exit, contextManager, PNone.NONE, PNone.NONE, PNone.NONE); + } + + @Specialization + @InliningCutoff + public static void doExceptional(VirtualFrame frame, + Object exception, Object exit, Object contextManager, + @Bind Node inliningTarget, + @Bind PBytecodeDSLRootNode rootNode, + @Shared @Cached CallQuaternaryMethodNode callExit, + @Cached GetClassNode getClass, + @Cached ExceptionNodes.GetTracebackNode getTraceback, + @Cached PyObjectIsTrueNode isTrue) { + AbstractTruffleException savedExcState = PArguments.getException(frame); + try { + Object pythonException = exception; + if (exception instanceof PException pException) { + PArguments.setException(frame, pException); + pythonException = pException.getEscapedException(); + } + Object excType = getClass.execute(inliningTarget, pythonException); + Object excTraceback = getTraceback.execute(inliningTarget, pythonException); + Object result = callExit.execute(frame, exit, contextManager, excType, pythonException, excTraceback); + if (!isTrue.execute(frame, result)) { + if (exception instanceof PException pException) { + throw pException.getExceptionForReraise(!rootNode.isInternal()); + } else if (exception instanceof AbstractTruffleException ate) { + throw ate; + } else { + throw CompilerDirectives.shouldNotReachHere("Exception not on stack"); + } + } + } finally { + PArguments.setException(frame, savedExcState); + } + } + } + + @Operation + @ConstantOperand(type = LocalAccessor.class) + @ConstantOperand(type = LocalAccessor.class) + public static final class AsyncContextManagerEnter { + @Specialization + @InliningCutoff + public static void doEnter(VirtualFrame frame, + LocalAccessor exitSetter, + LocalAccessor resultSetter, + Object contextManager, + @Bind Node inliningTarget, + @Bind BytecodeNode bytecode, + @Cached GetClassNode getClass, + @Cached LookupSpecialMethodNode.Dynamic lookupEnter, + @Cached LookupSpecialMethodNode.Dynamic lookupExit, + @Cached CallUnaryMethodNode callEnter, + @Cached PRaiseNode raiseNode) { + Object type = getClass.execute(inliningTarget, contextManager); + Object enter = lookupEnter.execute(frame, inliningTarget, type, T___AENTER__, contextManager); + if (enter == PNone.NO_VALUE) { + throw raiseNode.raise(inliningTarget, AttributeError, new Object[]{T___AENTER__}); + } + Object exit = lookupExit.execute(frame, inliningTarget, type, T___AEXIT__, contextManager); + if (exit == PNone.NO_VALUE) { + throw raiseNode.raise(inliningTarget, AttributeError, new Object[]{T___AEXIT__}); + } + Object result = callEnter.executeObject(frame, enter, contextManager); + exitSetter.setObject(bytecode, frame, exit); + resultSetter.setObject(bytecode, frame, result); + } + } + + @Operation + public static final class AsyncContextManagerCallExit { + @Specialization + public static Object doRegular(VirtualFrame frame, + PNone none, Object exit, Object contextManager, + @Shared @Cached CallQuaternaryMethodNode callExit) { + return callExit.execute(frame, exit, contextManager, PNone.NONE, PNone.NONE, PNone.NONE); + } + + @Specialization + @InliningCutoff + public static Object doExceptional(VirtualFrame frame, + Object exception, Object exit, Object contextManager, + @Bind Node inliningTarget, + @Bind PBytecodeDSLRootNode rootNode, + @Shared @Cached CallQuaternaryMethodNode callExit, + @Cached GetClassNode getClass, + @Cached ExceptionNodes.GetTracebackNode getTraceback, + @Cached PyObjectIsTrueNode isTrue) { + AbstractTruffleException savedExcState = PArguments.getException(frame); + try { + Object pythonException = exception; + if (exception instanceof PException) { + PArguments.setException(frame, (PException) exception); + pythonException = ((PException) exception).getEscapedException(); + } + Object excType = getClass.execute(inliningTarget, pythonException); + Object excTraceback = getTraceback.execute(inliningTarget, pythonException); + return callExit.execute(frame, exit, contextManager, excType, pythonException, excTraceback); + } finally { + PArguments.setException(frame, savedExcState); + } + } + } + + @Operation + public static final class AsyncContextManagerExit { + /** + * NB: There is nothing to do after awaiting __exit__(None, None, None), so this operation + * is only emitted for the case where the context manager exits due to an exception. + */ + @Specialization + @InliningCutoff + public static void doExceptional(VirtualFrame frame, + Object exception, Object result, + @Bind Node inliningTarget, + @Bind PBytecodeDSLRootNode rootNode, + @Cached CallQuaternaryMethodNode callExit, + @Cached GetClassNode getClass, + @Cached ExceptionNodes.GetTracebackNode getTraceback, + @Cached PyObjectIsTrueNode isTrue) { + if (!isTrue.execute(frame, result)) { + if (exception instanceof PException) { + throw ((PException) exception).getExceptionForReraise(!rootNode.isInternal()); + } else if (exception instanceof AbstractTruffleException) { + throw (AbstractTruffleException) exception; + } else { + throw CompilerDirectives.shouldNotReachHere("Exception not on stack"); + } + } + } + } + + @Operation + @ConstantOperand(type = int.class) + public static final class BuildString { + @Specialization + public static Object perform( + int length, + @Variadic Object[] strings, + @Cached TruffleStringBuilder.AppendStringNode appendNode, + @Cached TruffleStringBuilder.ToStringNode toString) { + var tsb = TruffleStringBuilderUTF32.create(PythonUtils.TS_ENCODING); + CompilerAsserts.partialEvaluationConstant(length); + for (int i = 0; i < length; i++) { + appendNode.execute(tsb, (TruffleString) strings[i]); + } + return toString.execute(tsb); + } + } + + @Operation + @ConstantOperand(type = LocalAccessor.class) + public static final class TeeLocal { + @Specialization + public static int doInt(VirtualFrame frame, LocalAccessor local, int value, + @Bind BytecodeNode bytecode) { + local.setInt(bytecode, frame, value); + return value; + } + + @Specialization + public static double doDouble(VirtualFrame frame, LocalAccessor local, double value, + @Bind BytecodeNode bytecode) { + local.setDouble(bytecode, frame, value); + return value; + } + + @Specialization + public static long doLong(VirtualFrame frame, LocalAccessor local, long value, + @Bind BytecodeNode bytecode) { + local.setLong(bytecode, frame, value); + return value; + } + + @Specialization(replaces = {"doInt", "doDouble", "doLong"}) + public static Object doObject(VirtualFrame frame, LocalAccessor local, Object value, + @Bind BytecodeNode bytecode) { + local.setObject(bytecode, frame, value); + return value; + } + } + + @Operation + public static final class GetLen { + @Specialization + public static int doObject(VirtualFrame frame, Object value, + @Bind Node inliningTarget, + @Cached PyObjectSizeNode sizeNode) { + return sizeNode.execute(frame, inliningTarget, value); + } + } + + @Operation + @ConstantOperand(type = long.class) + public static final class CheckTypeFlags { + @Specialization + public static boolean doObject(long typeFlags, Object value, + @Cached GetTPFlagsNode getTPFlagsNode) { + return (getTPFlagsNode.execute(value) & typeFlags) != 0; + } + } + + @Operation + @ImportStatic(PGuards.class) + public static final class BinarySubscript { + // TODO: GR-64248, the result is not BE'd because of the UnexpectedResultException. maybe we + // should explicitly check for an int storage type? + @Specialization(rewriteOn = UnexpectedResultException.class, guards = "isBuiltinList(list)") + public static int doIntList(PList list, int index, + @Shared @Cached("createForList()") SequenceStorageNodes.GetItemNode getListItemNode) throws UnexpectedResultException { + return getListItemNode.executeInt(list.getSequenceStorage(), index); + } + + @Specialization(rewriteOn = UnexpectedResultException.class, guards = "isBuiltinList(list)") + public static double doDoubleList(PList list, int index, + @Shared @Cached("createForList()") SequenceStorageNodes.GetItemNode getListItemNode) throws UnexpectedResultException { + return getListItemNode.executeDouble(list.getSequenceStorage(), index); + } + + @Specialization(replaces = {"doIntList", "doDoubleList"}, guards = "isBuiltinList(list)") + public static Object doObjectList(PList list, int index, + @Shared @Cached("createForList()") SequenceStorageNodes.GetItemNode getListItemNode) { + return getListItemNode.execute(list.getSequenceStorage(), index); + } + + @Specialization(rewriteOn = UnexpectedResultException.class, guards = "isBuiltinTuple(tuple)") + public static int doIntTuple(PTuple tuple, int index, + @Shared @Cached("createForTuple()") SequenceStorageNodes.GetItemNode getTupleItemNode) throws UnexpectedResultException { + return getTupleItemNode.executeInt(tuple.getSequenceStorage(), index); + + } + + @Specialization(rewriteOn = UnexpectedResultException.class, guards = "isBuiltinTuple(tuple)") + public static double doDoubleTuple(PTuple tuple, int index, + @Shared @Cached("createForTuple()") SequenceStorageNodes.GetItemNode getTupleItemNode) throws UnexpectedResultException { + return getTupleItemNode.executeDouble(tuple.getSequenceStorage(), index); + } + + @Specialization(replaces = {"doIntTuple", "doDoubleTuple"}, guards = "isBuiltinTuple(tuple)") + public static Object doObjectTuple(PTuple tuple, int index, + @Shared @Cached("createForTuple()") SequenceStorageNodes.GetItemNode getTupleItemNode) { + return getTupleItemNode.execute(tuple.getSequenceStorage(), index); + } + + @Fallback + public static Object doOther(VirtualFrame frame, Object receiver, Object key, + @Bind("this") Node inliningTarget, + @Cached GetObjectSlotsNode getSlotsNode, + @Cached PyObjectGetItem.PyObjectGetItemGeneric getItemNode) { + TpSlots slots = getSlotsNode.execute(inliningTarget, receiver); + return getItemNode.execute(frame, inliningTarget, receiver, slots, key); + } + } + + /** + * Performs some clean-up steps before suspending execution. + */ + @Operation + public static final class PreYield { + @Specialization + public static Object doObject(VirtualFrame frame, Object value, + @Bind Node location, + @Bind PBytecodeDSLRootNode root) { + if (root.needsTraceAndProfileInstrumentation()) { + root.traceOrProfileReturn(frame, location, value); + root.getThreadState().popInstrumentationData(root); + } + return value; + } + } + + /** + * Resumes execution after yield. + */ + @Operation + public static final class ResumeYield { + @Specialization + public static Object doObject(VirtualFrame frame, Object sendValue, + @Bind Node location, + @Bind PBytecodeDSLRootNode root, + @Bind BytecodeNode bytecode, + @Bind("$bytecodeIndex") int bci, + @Cached GetSendValueNode getSendValue) { + if (root.needsTraceAndProfileInstrumentation()) { + // We may not have reparsed the root with instrumentation yet. + root.ensureTraceAndProfileEnabled(); + root.getThreadState().pushInstrumentationData(root); + root.traceOrProfileCall(frame, location, bytecode, bci); + } + + return getSendValue.execute(sendValue); + } + } + + @Operation + @ConstantOperand(type = LocalAccessor.class) + @ConstantOperand(type = LocalAccessor.class) + @SuppressWarnings("truffle-interpreted-performance") + public static final class YieldFromSend { + private static final TruffleString T_SEND = tsLiteral("send"); + + @Specialization + static boolean doGenerator(VirtualFrame virtualFrame, + LocalAccessor yieldedValue, + LocalAccessor returnedValue, + PGenerator generator, + Object arg, + @Bind Node inliningTarget, + @Bind BytecodeNode bytecode, + @Cached CommonGeneratorBuiltins.SendNode sendNode, + @Shared @Cached IsBuiltinObjectProfile stopIterationProfile, + @Shared @Cached StopIterationBuiltins.StopIterationValueNode getValue) { + try { + Object value = sendNode.execute(virtualFrame, generator, arg); + yieldedValue.setObject(bytecode, virtualFrame, value); + return false; + } catch (PException e) { + handleException(virtualFrame, e, inliningTarget, bytecode, stopIterationProfile, getValue, returnedValue); + return true; + } + } + + @Specialization(guards = "iterCheck.execute(inliningTarget, iter)", limit = "1") + static boolean doIterator(VirtualFrame virtualFrame, + LocalAccessor yieldedValue, + LocalAccessor returnedValue, + Object iter, + @SuppressWarnings("unused") PNone arg, + @Bind Node inliningTarget, + @Bind BytecodeNode bytecode, + @SuppressWarnings("unused") @Cached PyIterCheckNode iterCheck, + @Cached PyIterNextNode getNextNode, + @Shared @Cached IsBuiltinObjectProfile stopIterationProfile, + @Shared @Cached StopIterationBuiltins.StopIterationValueNode getValue) { + try { + Object value = getNextNode.execute(virtualFrame, inliningTarget, iter); + yieldedValue.setObject(bytecode, virtualFrame, value); + return false; + } catch (IteratorExhausted e) { + returnedValue.setObject(bytecode, virtualFrame, PNone.NONE); + return true; + } + } + + @Fallback + static boolean doOther(VirtualFrame virtualFrame, + LocalAccessor yieldedValue, + LocalAccessor returnedValue, + Object obj, + Object arg, + @Bind Node inliningTarget, + @Bind BytecodeNode bytecode, + @Bind("$bytecodeIndex") int bci, + @Cached PyObjectCallMethodObjArgs callMethodNode, + @Shared @Cached IsBuiltinObjectProfile stopIterationProfile, + @Shared @Cached StopIterationBuiltins.StopIterationValueNode getValue) { + try { + Object value = callMethodNode.execute(virtualFrame, inliningTarget, obj, T_SEND, arg); + yieldedValue.setObject(bytecode, virtualFrame, value); + return false; + } catch (PException e) { + handleException(virtualFrame, e, inliningTarget, bytecode, stopIterationProfile, getValue, returnedValue); + return true; + } + } + + private static void handleException(VirtualFrame frame, PException e, Node inliningTarget, BytecodeNode bytecode, + IsBuiltinObjectProfile stopIterationProfile, + StopIterationBuiltins.StopIterationValueNode getValue, + LocalAccessor returnedValue) { + e.expectStopIteration(inliningTarget, stopIterationProfile); + returnedValue.setObject(bytecode, frame, getValue.execute((PBaseException) e.getUnreifiedException())); + } + + } + + @Operation + @ConstantOperand(type = LocalAccessor.class) + @ConstantOperand(type = LocalAccessor.class) + @SuppressWarnings("truffle-interpreted-performance") + public static final class YieldFromThrow { + + private static final TruffleString T_CLOSE = tsLiteral("close"); + private static final TruffleString T_THROW = tsLiteral("throw"); + + @Specialization + static boolean doGenerator(VirtualFrame frame, + LocalAccessor yieldedValue, + LocalAccessor returnedValue, + PGenerator generator, + PException exception, + @Bind Node inliningTarget, + @Bind BytecodeNode bytecode, + @Cached CommonGeneratorBuiltins.ThrowNode throwNode, + @Cached CommonGeneratorBuiltins.CloseNode closeNode, + @Shared @Cached IsBuiltinObjectProfile profileExit, + @Shared @Cached IsBuiltinObjectProfile stopIterationProfile, + @Shared @Cached StopIterationBuiltins.StopIterationValueNode getValue) { + if (profileExit.profileException(inliningTarget, exception, GeneratorExit)) { + closeNode.execute(frame, generator); + throw exception; + } else { + try { + Object value = throwNode.execute(frame, generator, exception.getEscapedException(), PNone.NO_VALUE, PNone.NO_VALUE); + yieldedValue.setObject(bytecode, frame, value); + return false; + } catch (PException e) { + handleException(frame, e, inliningTarget, bytecode, stopIterationProfile, getValue, returnedValue); + return true; + } + } + } + + @Fallback + static boolean doOther(VirtualFrame frame, + LocalAccessor yieldedValue, + LocalAccessor returnedValue, + Object obj, + Object exception, + @Bind Node inliningTarget, + @Bind BytecodeNode bytecode, + @Cached PyObjectLookupAttr lookupThrow, + @Cached PyObjectLookupAttr lookupClose, + @Cached CallNode callThrow, + @Cached CallNode callClose, + @Cached WriteUnraisableNode writeUnraisableNode, + @Shared @Cached IsBuiltinObjectProfile profileExit, + @Shared @Cached IsBuiltinObjectProfile stopIterationProfile, + @Shared @Cached StopIterationBuiltins.StopIterationValueNode getValue) { + PException pException = (PException) exception; + if (profileExit.profileException(inliningTarget, pException, GeneratorExit)) { + Object close = PNone.NO_VALUE; + try { + close = lookupClose.execute(frame, inliningTarget, obj, T_CLOSE); + } catch (PException e) { + writeUnraisableNode.execute(frame, e.getEscapedException(), null, obj); + } + if (close != PNone.NO_VALUE) { + callClose.execute(frame, close); + } + throw pException; + } else { + Object throwMethod = lookupThrow.execute(frame, inliningTarget, obj, T_THROW); + if (throwMethod == PNone.NO_VALUE) { + throw pException; + } + try { + Object value = callThrow.execute(frame, throwMethod, pException.getEscapedException()); + yieldedValue.setObject(bytecode, frame, value); + return false; + } catch (PException e) { + handleException(frame, e, inliningTarget, bytecode, stopIterationProfile, getValue, returnedValue); + return true; + } + } + } + + private static void handleException(VirtualFrame frame, PException e, Node inliningTarget, BytecodeNode bytecode, + IsBuiltinObjectProfile stopIterationProfile, StopIterationBuiltins.StopIterationValueNode getValue, + LocalAccessor returnedValue) { + e.expectStopIteration(inliningTarget, stopIterationProfile); + returnedValue.setObject(bytecode, frame, getValue.execute((PBaseException) e.getUnreifiedException())); + } + } + + /** + * Loads a user-defined local variable. Unlike a built-in LoadLocal, this operation raises an + * unbound local error if the local has not been set. + *

      + * This operation makes use of Truffle's boxing overloads. When an operation tries to quicken + * this one for boxing elimination, the correct overload will be selected. + */ + @Operation + @ConstantOperand(type = LocalAccessor.class) + @ConstantOperand(type = int.class) + public static final class CheckAndLoadLocal { + @Specialization(rewriteOn = UnexpectedResultException.class) + public static int doInt(VirtualFrame frame, LocalAccessor accessor, int index, + @Bind PBytecodeDSLRootNode rootNode, + @Bind BytecodeNode bytecodeNode, + @Bind Node inliningTarget, + @Shared @Cached InlinedBranchProfile localUnboundProfile) throws UnexpectedResultException { + if (accessor.isCleared(bytecodeNode, frame)) { + localUnboundProfile.enter(inliningTarget); + throw raiseUnbound(rootNode, inliningTarget, index); + } + return accessor.getInt(bytecodeNode, frame); + } + + @Specialization(rewriteOn = UnexpectedResultException.class) + public static boolean doBoolean(VirtualFrame frame, LocalAccessor accessor, int index, + @Bind PBytecodeDSLRootNode rootNode, + @Bind BytecodeNode bytecodeNode, + @Bind Node inliningTarget, + @Shared @Cached InlinedBranchProfile localUnboundProfile) throws UnexpectedResultException { + if (accessor.isCleared(bytecodeNode, frame)) { + localUnboundProfile.enter(inliningTarget); + throw raiseUnbound(rootNode, inliningTarget, index); + } + return accessor.getBoolean(bytecodeNode, frame); + } + + @Specialization(replaces = {"doInt", "doBoolean"}) + public static Object doObject(VirtualFrame frame, LocalAccessor accessor, int index, + @Bind PBytecodeDSLRootNode rootNode, + @Bind BytecodeNode bytecodeNode, + @Bind Node inliningTarget, + @Cached InlinedBranchProfile localUnboundProfile) { + if (accessor.isCleared(bytecodeNode, frame)) { + localUnboundProfile.enter(inliningTarget); + throw raiseUnbound(rootNode, inliningTarget, index); + } + return accessor.getObject(bytecodeNode, frame); + } + } + + @Operation + @ConstantOperand(type = LocalAccessor.class) + @ConstantOperand(type = int.class) + public static final class DeleteLocal { + @Specialization + public static void doObject(VirtualFrame frame, LocalAccessor accessor, int index, + @Bind PBytecodeDSLRootNode rootNode, + @Bind BytecodeNode bytecodeNode, + @Bind Node inliningTarget, + @Cached InlinedBranchProfile localUnboundProfile) { + if (accessor.isCleared(bytecodeNode, frame)) { + localUnboundProfile.enter(inliningTarget); + throw raiseUnbound(rootNode, inliningTarget, index); + } + accessor.clear(bytecodeNode, frame); + } + } + + @TruffleBoundary + private static PException raiseUnbound(PBytecodeDSLRootNode rootNode, Node inliningTarget, int index) { + TruffleString localName = rootNode.getCodeUnit().varnames[index]; + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.UnboundLocalError, ErrorMessages.LOCAL_VAR_REFERENCED_BEFORE_ASSIGMENT, localName); + } + + @Operation + public static final class RaiseNotImplementedError { + @Specialization + public static void doRaise(VirtualFrame frame, TruffleString name, + @Bind Node node) { + throw PRaiseNode.raiseStatic(node, PythonBuiltinClassType.NotImplementedError, name); + + } + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallDispatchNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallDispatchNode.java deleted file mode 100644 index 48816e085d..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallDispatchNode.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. - * Copyright (c) 2014, Regents of the University of California - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.oracle.graal.python.nodes.call; - -import com.oracle.graal.python.builtins.objects.code.CodeNodes.GetCodeCallTargetNode; -import com.oracle.graal.python.builtins.objects.code.PCode; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.function.PFunction; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetCallTargetNode; -import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetFunctionCodeNode; -import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.ReportPolymorphism.Megamorphic; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.Frame; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; - -@ImportStatic(PythonOptions.class) -@GenerateUncached -@SuppressWarnings("truffle-inlining") // footprint reduction 48 -> 29 -public abstract class CallDispatchNode extends PNodeWithContext { - - @NeverDefault - protected static FunctionInvokeNode createInvokeNode(PFunction callee) { - return FunctionInvokeNode.create(callee); - } - - @NeverDefault - protected static FunctionInvokeNode createInvokeNode(PBuiltinFunction callee) { - return FunctionInvokeNode.create(callee); - } - - @NeverDefault - protected static CallTargetInvokeNode createCtInvokeNode(PFunction callee) { - return CallTargetInvokeNode.create(callee); - } - - @NeverDefault - protected static CallTargetInvokeNode createCtInvokeNode(PBuiltinFunction callee) { - return CallTargetInvokeNode.create(callee); - } - - @NeverDefault - public static CallDispatchNode create() { - return CallDispatchNodeGen.create(); - } - - public static CallDispatchNode getUncached() { - return CallDispatchNodeGen.getUncached(); - } - - public final Object executeCall(VirtualFrame frame, PFunction callee, Object[] arguments) { - return executeInternal(frame, callee, arguments); - } - - public final Object executeCall(VirtualFrame frame, PBuiltinFunction callee, Object[] arguments) { - return executeInternal(frame, callee, arguments); - } - - protected abstract Object executeInternal(Frame frame, PFunction callee, Object[] arguments); - - protected abstract Object executeInternal(Frame frame, PBuiltinFunction callee, Object[] arguments); - - // We only have a single context and this function never changed its code - @Specialization(guards = {"isSingleContext()", "callee == cachedCallee"}, limit = "getCallSiteInlineCacheMaxDepth()", assumptions = "cachedCallee.getCodeStableAssumption()") - protected static Object callFunctionCached(VirtualFrame frame, @SuppressWarnings("unused") PFunction callee, Object[] arguments, - @SuppressWarnings("unused") @Cached("callee") PFunction cachedCallee, - @Cached("createInvokeNode(cachedCallee)") FunctionInvokeNode invoke) { - return invoke.execute(frame, arguments); - } - - // We only have a single context and this function changed its code before, but now it's - // constant - protected PCode getCode(Node inliningTarget, GetFunctionCodeNode getFunctionCodeNode, PFunction function) { - return getFunctionCodeNode.execute(inliningTarget, function); - } - - @Specialization(guards = {"isSingleContext()", "callee == cachedCallee", "getCode(inliningTarget, getFunctionCodeNode, callee) == cachedCode"}, // - replaces = "callFunctionCached", limit = "getCallSiteInlineCacheMaxDepth()") - protected static Object callFunctionCachedCode(VirtualFrame frame, @SuppressWarnings("unused") PFunction callee, Object[] arguments, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached("callee") PFunction cachedCallee, - @SuppressWarnings("unused") @Cached GetFunctionCodeNode getFunctionCodeNode, - @SuppressWarnings("unused") @Cached("getCode(inliningTarget, getFunctionCodeNode, callee)") PCode cachedCode, - @Cached("createInvokeNode(cachedCallee)") FunctionInvokeNode invoke) { - return invoke.execute(frame, arguments); - } - - protected static RootCallTarget getCallTargetUncached(PFunction callee) { - CompilerAsserts.neverPartOfCompilation(); - return GetCallTargetNode.getUncached().execute(callee); - } - - // We have multiple contexts, don't cache the objects so that contexts can be cleaned up - @Specialization(guards = {"getCt.execute(inliningTarget, callee.getCode()) == ct"}, limit = "getCallSiteInlineCacheMaxDepth()", replaces = "callFunctionCachedCode") - protected static Object callFunctionCachedCt(VirtualFrame frame, PFunction callee, Object[] arguments, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached("getCallTargetUncached(callee)") RootCallTarget ct, - @SuppressWarnings("unused") @Cached GetCodeCallTargetNode getCt, - @Cached("createCtInvokeNode(callee)") CallTargetInvokeNode invoke) { - return invoke.execute(frame, callee, callee.getGlobals(), callee.getClosure(), arguments); - } - - @Specialization(guards = {"isSingleContext()", "callee == cachedCallee"}, limit = "getCallSiteInlineCacheMaxDepth()") - protected static Object callBuiltinFunctionCached(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinFunction callee, Object[] arguments, - @SuppressWarnings("unused") @Cached("callee") PBuiltinFunction cachedCallee, - @Cached("createInvokeNode(cachedCallee)") FunctionInvokeNode invoke) { - return invoke.execute(frame, arguments); - } - - @Specialization(guards = "callee.getCallTarget() == ct", limit = "getCallSiteInlineCacheMaxDepth()") - protected static Object callBuiltinFunctionCachedCt(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinFunction callee, Object[] arguments, - @SuppressWarnings("unused") @Cached("callee.getCallTarget()") RootCallTarget ct, - @Cached("createCtInvokeNode(callee)") CallTargetInvokeNode invoke) { - return invoke.execute(frame, null, null, null, arguments); - } - - @Specialization(replaces = {"callFunctionCached", "callFunctionCachedCode", "callFunctionCachedCt"}) - @Megamorphic - protected static Object callFunctionUncached(Frame frame, PFunction callee, Object[] arguments, - @Shared @Cached GenericInvokeNode invoke) { - return invoke.executeInternal(frame, callee, arguments); - } - - @Specialization(replaces = {"callBuiltinFunctionCached", "callBuiltinFunctionCachedCt"}) - @Megamorphic - protected static Object callBuiltinFunctionUncached(Frame frame, PBuiltinFunction callee, Object[] arguments, - @Shared @Cached GenericInvokeNode invoke) { - return invoke.executeInternal(frame, callee, arguments); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallDispatchers.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallDispatchers.java new file mode 100644 index 0000000000..afb61882f0 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallDispatchers.java @@ -0,0 +1,508 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.nodes.call; + +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.builtins.objects.function.PArguments; +import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; +import com.oracle.graal.python.builtins.objects.function.PFunction; +import com.oracle.graal.python.builtins.objects.function.PKeyword; +import com.oracle.graal.python.builtins.objects.function.Signature; +import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; +import com.oracle.graal.python.builtins.objects.module.PythonModule; +import com.oracle.graal.python.nodes.PNodeWithContext; +import com.oracle.graal.python.nodes.argument.CreateArgumentsNode; +import com.oracle.graal.python.nodes.bytecode.PBytecodeGeneratorFunctionRootNode; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLGeneratorFunctionRootNode; +import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; +import com.oracle.graal.python.runtime.ExecutionContext; +import com.oracle.graal.python.runtime.ExecutionContext.IndirectCalleeContext; +import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; +import com.oracle.graal.python.runtime.PythonOptions; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.ImportStatic; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.dsl.ReportPolymorphism.Megamorphic; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.DirectCallNode; +import com.oracle.truffle.api.nodes.IndirectCallNode; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; + +public class CallDispatchers { + + private static boolean isGeneratorFunction(RootCallTarget callTarget) { + return callTarget.getRootNode() instanceof PBytecodeGeneratorFunctionRootNode || callTarget.getRootNode() instanceof PBytecodeDSLGeneratorFunctionRootNode; + } + + @NeverDefault + public static DirectCallNode createDirectCallNodeFor(PBuiltinFunction callee) { + DirectCallNode callNode = Truffle.getRuntime().createDirectCallNode(callee.getCallTarget()); + if (PythonLanguage.get(null).getEngineOption(PythonOptions.EnableForcedSplits) || + (callee.getFunctionRootNode() instanceof BuiltinFunctionRootNode root && root.getBuiltin().forceSplitDirectCalls())) { + callNode.cloneCallTarget(); + } + return callNode; + } + + @NeverDefault + public static DirectCallNode createDirectCallNodeFor(PFunction callee) { + boolean isGenerator = isGeneratorFunction(callee.getCallTarget()); + DirectCallNode callNode = Truffle.getRuntime().createDirectCallNode(callee.getCallTarget()); + if (callee.forceSplitDirectCalls()) { + callNode.cloneCallTarget(); + } + if (isGenerator && PythonLanguage.get(null).getEngineOption(PythonOptions.ForceInlineGeneratorCalls)) { + callNode.forceInlining(); + } + return callNode; + } + + public static boolean sameCallTarget(RootCallTarget callTarget, DirectCallNode callNode) { + return callTarget == callNode.getCallTarget(); + } + + /** + * Node for invoking call targets of builtin functions, modules or generators when the call + * target is a PE constant. Use {@link #createDirectCallNodeFor(PBuiltinFunction)} to create the + * direct call node for builtin functions. Takes PArguments + */ + @GenerateInline + @GenerateCached(false) + public abstract static class SimpleDirectInvokeNode extends Node { + + public abstract Object execute(VirtualFrame frame, Node inliningTarget, DirectCallNode callNode, Object[] arguments); + + @Specialization + static Object doDirect(VirtualFrame frame, Node inliningTarget, DirectCallNode callNode, Object[] arguments, + @Cached InlinedConditionProfile profileIsNullFrame, + @Cached ExecutionContext.CallContext callContext) { + RootCallTarget callTarget = (RootCallTarget) callNode.getCurrentCallTarget(); + if (profileIsNullFrame.profile(inliningTarget, frame == null)) { + PythonContext context = PythonContext.get(inliningTarget); + PythonThreadState threadState = context.getThreadState(context.getLanguage(inliningTarget)); + Object state = IndirectCalleeContext.enter(threadState, arguments, callTarget); + try { + return callNode.call(arguments); + } finally { + IndirectCalleeContext.exit(threadState, state); + } + } else { + callContext.prepareCall(frame, arguments, callTarget, callNode); + return callNode.call(arguments); + } + } + } + + /** + * Node for invoking call targets of builtin functions, modules or generators when the call + * target is dynamic. Takes PArguments + */ + @GenerateInline(inlineByDefault = true) + @GenerateUncached + public abstract static class SimpleIndirectInvokeNode extends Node { + + public abstract Object execute(Frame frame, Node inliningTarget, RootCallTarget callTarget, Object[] arguments); + + public final Object executeCached(VirtualFrame frame, RootCallTarget callTarget, Object[] arguments) { + return execute(frame, this, callTarget, arguments); + } + + public static Object executeUncached(RootCallTarget callTarget, Object[] arguments) { + return CallDispatchersFactory.SimpleIndirectInvokeNodeGen.getUncached().execute(null, null, callTarget, arguments); + } + + @Specialization + static Object doDirect(VirtualFrame frame, Node inliningTarget, RootCallTarget callTarget, Object[] arguments, + @Cached InlinedConditionProfile profileIsNullFrame, + @Cached ExecutionContext.CallContext callContext, + @Cached IndirectCallNode callNode) { + if (profileIsNullFrame.profile(inliningTarget, frame == null)) { + PythonContext context = PythonContext.get(inliningTarget); + PythonThreadState threadState = context.getThreadState(context.getLanguage(inliningTarget)); + Object state = IndirectCalleeContext.enterIndirect(threadState, arguments); + try { + return callNode.call(callTarget, arguments); + } finally { + IndirectCalleeContext.exit(threadState, state); + } + } else { + callContext.prepareIndirectCall(frame, arguments, callNode); + return callNode.call(callTarget, arguments); + } + } + + @NeverDefault + public static SimpleIndirectInvokeNode create() { + return CallDispatchersFactory.SimpleIndirectInvokeNodeGen.create(); + } + } + + /** + * Node for invoking builtin functions with an inline cache on the function object and a + * secondary inline cache on the call target. Takes PArguments + */ + @GenerateInline + @GenerateCached(false) + @GenerateUncached + @ImportStatic({CallDispatchers.class, PythonOptions.class}) + public abstract static class BuiltinFunctionCachedInvokeNode extends PNodeWithContext { + public abstract Object execute(VirtualFrame frame, Node inliningTarget, PBuiltinFunction callee, Object[] arguments); + + @Specialization(guards = {"isSingleContext()", "callee == cachedCallee"}, limit = "getCallSiteInlineCacheMaxDepth()") + static Object callBuiltinFunctionCached(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") PBuiltinFunction callee, Object[] arguments, + @SuppressWarnings("unused") @Cached("callee") PBuiltinFunction cachedCallee, + @Cached("createDirectCallNodeFor(callee)") DirectCallNode callNode, + @Cached SimpleDirectInvokeNode invoke) { + return invoke.execute(frame, inliningTarget, callNode, arguments); + } + + @Specialization(guards = "sameCallTarget(callee.getCallTarget(), callNode)", limit = "getCallSiteInlineCacheMaxDepth()", replaces = "callBuiltinFunctionCached") + static Object callBuiltinFunctionCachedCt(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") PBuiltinFunction callee, Object[] arguments, + @Cached("createDirectCallNodeFor(callee)") DirectCallNode callNode, + @Cached SimpleDirectInvokeNode invoke) { + return invoke.execute(frame, inliningTarget, callNode, arguments); + } + + @Specialization(replaces = {"callBuiltinFunctionCached", "callBuiltinFunctionCachedCt"}) + @Megamorphic + @InliningCutoff + static Object callBuiltinFunctionMegamorphic(VirtualFrame frame, Node inliningTarget, PBuiltinFunction callee, Object[] arguments, + @Cached SimpleIndirectInvokeNode invoke) { + return invoke.execute(frame, inliningTarget, callee.getCallTarget(), arguments); + } + } + + /** + * Node for calling builtin functions with an inline cache on the function object and a + * secondary inline cache on the call target. + */ + @GenerateInline + @GenerateCached(false) + @GenerateUncached + @ImportStatic({CallDispatchers.class, PythonOptions.class}) + public abstract static class BuiltinFunctionCachedCallNode extends PNodeWithContext { + + public abstract Object execute(VirtualFrame frame, Node inliningTarget, PBuiltinFunction callee, Object[] arguments, PKeyword[] keywords); + + @Specialization(guards = {"isSingleContext()", "callee == cachedCallee"}, limit = "getCallSiteInlineCacheMaxDepth()") + static Object callBuiltinFunctionCached(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") PBuiltinFunction callee, Object[] arguments, PKeyword[] keywords, + @Cached("callee") PBuiltinFunction cachedCallee, + @Cached CreateArgumentsNode createArgs, + @Cached("createDirectCallNodeFor(callee)") DirectCallNode callNode, + @Cached SimpleDirectInvokeNode invoke) { + Object[] pArguments = createArgs.execute(inliningTarget, cachedCallee, arguments, keywords, cachedCallee.getSignature(), null, null, + cachedCallee.getDefaults(), cachedCallee.getKwDefaults(), false); + return invoke.execute(frame, inliningTarget, callNode, pArguments); + } + + @Specialization(guards = "sameCallTarget(callee.getCallTarget(), callNode)", limit = "getCallSiteInlineCacheMaxDepth()", replaces = "callBuiltinFunctionCached") + static Object callBuiltinFunctionCachedCt(VirtualFrame frame, Node inliningTarget, PBuiltinFunction callee, Object[] arguments, PKeyword[] keywords, + @Cached CreateArgumentsNode createArgs, + @Cached("createDirectCallNodeFor(callee)") DirectCallNode callNode, + @Cached SimpleDirectInvokeNode invoke) { + Signature signature; + /* + * The signature is PE-constant for a given callTarget, but getting it from there needs + * multiple virtual calls in the interpreter. + */ + if (CompilerDirectives.inCompiledCode()) { + signature = Signature.fromCallTarget((RootCallTarget) callNode.getCallTarget()); + } else { + signature = callee.getSignature(); + } + Object[] pArguments = createArgs.execute(inliningTarget, callee, arguments, keywords, signature, null, null, + callee.getDefaults(), callee.getKwDefaults(), false); + return invoke.execute(frame, inliningTarget, callNode, pArguments); + } + + @Specialization(replaces = {"callBuiltinFunctionCached", "callBuiltinFunctionCachedCt"}) + @Megamorphic + @InliningCutoff + static Object callBuiltinFunctionMegamorphic(VirtualFrame frame, Node inliningTarget, PBuiltinFunction callee, Object[] arguments, PKeyword[] keywords, + @Cached CreateArgumentsNode createArgs, + @Cached SimpleIndirectInvokeNode invoke) { + Object[] pArguments = createArgs.execute(inliningTarget, callee, arguments, keywords, callee.getSignature(), null, null, + callee.getDefaults(), callee.getKwDefaults(), false); + return invoke.execute(frame, inliningTarget, callee.getCallTarget(), pArguments); + } + } + + /** + * Node for calling builtin functions with an inline cache on the method object and a secondary + * inline cache on the call target. + */ + @GenerateInline + @GenerateCached(false) + @GenerateUncached + @ImportStatic({CallDispatchers.class, PythonOptions.class}) + public abstract static class BuiltinMethodCachedCallNode extends PNodeWithContext { + + public abstract Object execute(VirtualFrame frame, Node inliningTarget, PBuiltinMethod callee, Object[] arguments, PKeyword[] keywords); + + @Specialization(guards = {"isSingleContext()", "callee == cachedCallee"}, limit = "getCallSiteInlineCacheMaxDepth()") + static Object callBuiltinMethodCached(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") PBuiltinMethod callee, Object[] arguments, PKeyword[] keywords, + @Cached(value = "callee", weak = true) PBuiltinMethod cachedCallee, + @Bind("cachedCallee.getBuiltinFunction()") PBuiltinFunction function, + @Cached CreateArgumentsNode createArgs, + @Cached("createDirectCallNodeFor(function)") DirectCallNode callNode, + @Cached SimpleDirectInvokeNode invoke) { + Object[] pArguments = createArgs.execute(inliningTarget, cachedCallee, arguments, keywords, function.getSignature(), callee.getSelf(), callee.getClassObject(), + function.getDefaults(), function.getKwDefaults(), isMethodcall(callee)); + return invoke.execute(frame, inliningTarget, callNode, pArguments); + } + + @Specialization(guards = "sameCallTarget(function.getCallTarget(), callNode)", limit = "getCallSiteInlineCacheMaxDepth()", replaces = "callBuiltinMethodCached") + static Object callBuiltinMethodCachedCt(VirtualFrame frame, Node inliningTarget, PBuiltinMethod callee, Object[] arguments, PKeyword[] keywords, + @Bind("callee.getBuiltinFunction()") PBuiltinFunction function, + @Cached CreateArgumentsNode createArgs, + @Cached("createDirectCallNodeFor(function)") DirectCallNode callNode, + @Cached SimpleDirectInvokeNode invoke) { + Signature signature; + /* + * The signature is PE-constant for a given callTarget, but getting it from there needs + * multiple virtual calls in the interpreter. + */ + if (CompilerDirectives.inCompiledCode()) { + signature = Signature.fromCallTarget((RootCallTarget) callNode.getCallTarget()); + } else { + signature = function.getSignature(); + } + Object[] pArguments = createArgs.execute(inliningTarget, callee, arguments, keywords, signature, callee.getSelf(), callee.getClassObject(), + function.getDefaults(), function.getKwDefaults(), isMethodcall(callee)); + return invoke.execute(frame, inliningTarget, callNode, pArguments); + } + + @Specialization(replaces = {"callBuiltinMethodCached", "callBuiltinMethodCachedCt"}) + @Megamorphic + @InliningCutoff + static Object callBuiltinMethodMegamorphic(VirtualFrame frame, Node inliningTarget, PBuiltinMethod callee, Object[] arguments, PKeyword[] keywords, + @Cached CreateArgumentsNode createArgs, + @Cached SimpleIndirectInvokeNode invoke) { + PBuiltinFunction function = callee.getBuiltinFunction(); + Object[] pArguments = createArgs.execute(inliningTarget, callee, arguments, keywords, function.getSignature(), callee.getSelf(), callee.getClassObject(), + function.getDefaults(), function.getKwDefaults(), isMethodcall(callee)); + return invoke.execute(frame, inliningTarget, function.getCallTarget(), pArguments); + } + + private static boolean isMethodcall(PBuiltinMethod callee) { + return !(callee.getSelf() instanceof PythonModule); + } + } + + /** + * Node for invoking python functions when the call target of the function is PE constant (the + * function itself doesn't have to be). Use {@link #createDirectCallNodeFor(PFunction)} to + * create the call node. Takes PArguments + */ + @GenerateInline + @GenerateCached(false) + public abstract static class FunctionDirectInvokeNode extends Node { + + public abstract Object execute(VirtualFrame frame, Node inliningTarget, DirectCallNode callNode, PFunction callee, Object[] arguments); + + @Specialization + static Object doDirect(VirtualFrame frame, Node inliningTarget, DirectCallNode callNode, PFunction callee, Object[] arguments, + @Cached SimpleDirectInvokeNode invoke) { + assert callee.getCallTarget() == callNode.getCallTarget(); + PArguments.setGlobals(arguments, callee.getGlobals()); + PArguments.setClosure(arguments, callee.getClosure()); + RootCallTarget callTarget = (RootCallTarget) callNode.getCurrentCallTarget(); + if (isGeneratorFunction(callTarget)) { + PArguments.setGeneratorFunction(arguments, callee); + } + return invoke.execute(frame, inliningTarget, callNode, arguments); + } + } + + /** + * Node for invoking python functions when the call target is dynamic. Takes PArguments + */ + @GenerateInline + @GenerateCached(false) + @GenerateUncached + public abstract static class FunctionIndirectInvokeNode extends Node { + + public abstract Object execute(Frame frame, Node inliningTarget, PFunction callee, Object[] arguments); + + @Specialization + static Object doDirect(VirtualFrame frame, Node inliningTarget, PFunction callee, Object[] arguments, + @Cached SimpleIndirectInvokeNode invoke, + @Cached InlinedConditionProfile generatorProfile) { + PArguments.setGlobals(arguments, callee.getGlobals()); + PArguments.setClosure(arguments, callee.getClosure()); + RootCallTarget callTarget = callee.getCallTarget(); + if (generatorProfile.profile(inliningTarget, isGeneratorFunction(callTarget))) { + PArguments.setGeneratorFunction(arguments, callee); + } + return invoke.execute(frame, inliningTarget, callTarget, arguments); + } + } + + /** + * Node for invoking python functions with an inline cache on the function object and a + * secondary inline cache on the call target. Takes PArguments + */ + @GenerateInline + @GenerateCached(false) + @GenerateUncached + @ImportStatic({CallDispatchers.class, PythonOptions.class}) + public abstract static class FunctionCachedInvokeNode extends PNodeWithContext { + public abstract Object execute(VirtualFrame frame, Node inliningTarget, PFunction callee, Object[] arguments); + + // We only have a single context and this function never changed its code + @Specialization(guards = {"isSingleContext()", "callee == cachedCallee"}, limit = "getCallSiteInlineCacheMaxDepth()", assumptions = "cachedCallee.getCodeStableAssumption()") + static Object callFunctionCached(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") PFunction callee, Object[] arguments, + @SuppressWarnings("unused") @Cached(value = "callee", weak = true) PFunction cachedCallee, + @Cached("createDirectCallNodeFor(callee)") DirectCallNode callNode, + @Cached FunctionDirectInvokeNode invoke) { + return invoke.execute(frame, inliningTarget, callNode, cachedCallee, arguments); + } + + // We have multiple contexts, don't cache the objects so that contexts can be cleaned up + @Specialization(guards = {"sameCallTarget(callee.getCallTarget(), callNode)"}, limit = "getCallSiteInlineCacheMaxDepth()", replaces = "callFunctionCached") + static Object callFunctionCachedCt(VirtualFrame frame, Node inliningTarget, PFunction callee, Object[] arguments, + @Cached("createDirectCallNodeFor(callee)") DirectCallNode callNode, + @Cached FunctionDirectInvokeNode invoke) { + return invoke.execute(frame, inliningTarget, callNode, callee, arguments); + } + + @Specialization(replaces = {"callFunctionCached", "callFunctionCachedCt"}) + @Megamorphic + @InliningCutoff + static Object callFunctionMegamorphic(VirtualFrame frame, Node inliningTarget, PFunction callee, Object[] arguments, + @Cached FunctionIndirectInvokeNode invoke) { + return invoke.execute(frame, inliningTarget, callee, arguments); + } + } + + /** + * Node for calling python functions with an inline cache on the function object and a secondary + * inline cache on the call target. Takes PArguments + */ + @GenerateInline + @GenerateCached(false) + @GenerateUncached + @ImportStatic({CallDispatchers.class, PythonOptions.class}) + public abstract static class FunctionCachedCallNode extends PNodeWithContext { + public abstract Object execute(VirtualFrame frame, Node inliningTarget, PFunction callee, Object[] arguments, PKeyword[] keywords); + + // We only have a single context and this function never changed its code + @Specialization(guards = {"isSingleContext()", "callee == cachedCallee"}, limit = "getCallSiteInlineCacheMaxDepth()", assumptions = "cachedCallee.getCodeStableAssumption()") + static Object callFunctionCached(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") PFunction callee, Object[] arguments, PKeyword[] keywords, + @SuppressWarnings("unused") @Cached(value = "callee", weak = true) PFunction cachedCallee, + @Cached CreateArgumentsNode createArgs, + @Cached("createDirectCallNodeFor(callee)") DirectCallNode callNode, + @Cached FunctionDirectInvokeNode invoke) { + Object[] pArguments = createArgs.execute(inliningTarget, cachedCallee, arguments, keywords, cachedCallee.getCode().getSignature(), null, null, + cachedCallee.getDefaults(), cachedCallee.getKwDefaults(), false); + return invoke.execute(frame, inliningTarget, callNode, cachedCallee, pArguments); + } + + // We have multiple contexts, don't cache the objects so that contexts can be cleaned up + @Specialization(guards = {"sameCallTarget(callee.getCallTarget(), callNode)"}, limit = "getCallSiteInlineCacheMaxDepth()", replaces = "callFunctionCached") + static Object callFunctionCachedCt(VirtualFrame frame, Node inliningTarget, PFunction callee, Object[] arguments, PKeyword[] keywords, + @Cached CreateArgumentsNode createArgs, + @Cached("createDirectCallNodeFor(callee)") DirectCallNode callNode, + @Cached FunctionDirectInvokeNode invoke) { + Signature signature; + /* + * The signature is PE-constant for a given callTarget, but getting it from there needs + * multiple virtual calls in the interpreter. + */ + if (CompilerDirectives.inCompiledCode()) { + signature = Signature.fromCallTarget((RootCallTarget) callNode.getCallTarget()); + } else { + signature = callee.getCode().getSignature(); + } + Object[] pArguments = createArgs.execute(inliningTarget, callee, arguments, keywords, signature, null, null, + callee.getDefaults(), callee.getKwDefaults(), false); + return invoke.execute(frame, inliningTarget, callNode, callee, pArguments); + } + + @Specialization(replaces = {"callFunctionCached", "callFunctionCachedCt"}) + @Megamorphic + @InliningCutoff + static Object callFunctionMegamorphic(VirtualFrame frame, Node inliningTarget, PFunction callee, Object[] arguments, PKeyword[] keywords, + @Cached CreateArgumentsNode createArgs, + @Cached FunctionIndirectInvokeNode invoke) { + Object[] pArguments = createArgs.execute(inliningTarget, callee, arguments, keywords, callee.getCode().getSignature(), null, null, + callee.getDefaults(), callee.getKwDefaults(), false); + return invoke.execute(frame, inliningTarget, callee, pArguments); + } + } + + /** + * Node for invoking a call target with an inline cache. Takes PArguments + */ + @GenerateInline + @GenerateCached(false) + @GenerateUncached + @ImportStatic({CallDispatchers.class, PythonOptions.class}) + public abstract static class CallTargetCachedInvokeNode extends Node { + + public abstract Object execute(VirtualFrame frame, Node inliningTarget, RootCallTarget callTarget, Object[] pythonArguments); + + @Specialization(guards = "sameCallTarget(callTarget, callNode)", limit = "getCallSiteInlineCacheMaxDepth()") + static Object doCallTargetDirect(VirtualFrame frame, Node inliningTarget, @SuppressWarnings("unused") RootCallTarget callTarget, Object[] args, + @Cached(parameters = "callTarget") DirectCallNode callNode, + @Cached SimpleDirectInvokeNode invoke) { + return invoke.execute(frame, inliningTarget, callNode, args); + } + + @Specialization(replaces = "doCallTargetDirect") + static Object doCallTargetIndirect(VirtualFrame frame, Node inliningTarget, RootCallTarget callTarget, Object[] args, + @Cached SimpleIndirectInvokeNode invoke) { + return invoke.execute(frame, inliningTarget, callTarget, args); + } + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallNode.java index 05bd298067..b7b8793a4d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,24 +42,20 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; import com.oracle.graal.python.builtins.objects.function.PFunction; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; -import com.oracle.graal.python.builtins.objects.method.PMethod; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotVarargs.CallSlotTpCallNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.SpecialMethodNames; -import com.oracle.graal.python.nodes.argument.CreateArgumentsNode; -import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode; import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.truffle.PythonTypes; import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.exception.PythonErrorType; import com.oracle.graal.python.util.PythonUtils; @@ -67,15 +63,13 @@ import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; +import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.ReportPolymorphism.Megamorphic; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ArityException; @@ -87,7 +81,6 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; -@TypeSystemReference(PythonTypes.class) @ImportStatic({PGuards.class, SpecialMethodNames.class}) @GenerateUncached @SuppressWarnings("truffle-inlining") // footprint reduction 60 -> 44 @@ -138,63 +131,29 @@ public final Object execute(Frame frame, Object callableObject, Object... argume } @Specialization - protected static Object boundDescriptor(VirtualFrame frame, BoundDescriptor descriptor, Object[] arguments, PKeyword[] keywords, + static Object boundDescriptor(VirtualFrame frame, BoundDescriptor descriptor, Object[] arguments, PKeyword[] keywords, @Cached CallNode subNode) { return subNode.executeInternal(frame, descriptor.descriptor, PythonUtils.arrayCopyOfRange(arguments, 1, arguments.length), keywords); } @Specialization - protected static Object functionCall(VirtualFrame frame, PFunction callable, Object[] arguments, PKeyword[] keywords, - @Shared("dispatchNode") @Cached CallDispatchNode dispatch, - @Shared("argsNode") @Cached CreateArgumentsNode createArgs) { - return dispatch.executeCall(frame, callable, createArgs.execute(callable, arguments, keywords)); + static Object functionCall(VirtualFrame frame, PFunction callable, Object[] arguments, PKeyword[] keywords, + @Bind Node inliningTarget, + @Cached CallDispatchers.FunctionCachedCallNode callNode) { + return callNode.execute(frame, inliningTarget, callable, arguments, keywords); } @Specialization - protected static Object builtinFunctionCall(VirtualFrame frame, PBuiltinFunction callable, Object[] arguments, PKeyword[] keywords, - @Shared("dispatchNode") @Cached CallDispatchNode dispatch, - @Shared("argsNode") @Cached CreateArgumentsNode createArgs) { - return dispatch.executeCall(frame, callable, createArgs.execute(callable, arguments, keywords)); - } - - @Specialization - protected static Object doType(VirtualFrame frame, PythonBuiltinClassType callableObject, Object[] arguments, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Shared("raise") @Cached PRaiseNode raise, - @Shared("getClassNode") @Cached GetClassNode getClassNode, - @Shared("lookupCall") @Cached(parameters = "Call") LookupSpecialMethodSlotNode lookupCall, - @Shared("callCall") @Cached CallVarargsMethodNode callCallNode) { - Object call = lookupCall.execute(frame, getClassNode.execute(inliningTarget, callableObject), callableObject); - return callCall(frame, callableObject, arguments, keywords, raise, callCallNode, call); - } - - @Specialization(guards = "isPythonClass(callableObject)", replaces = "doType") - protected static Object doPythonClass(VirtualFrame frame, Object callableObject, Object[] arguments, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Shared("raise") @Cached PRaiseNode raise, - @Shared("getClassNode") @Cached GetClassNode getClassNode, - @Shared("lookupCall") @Cached(parameters = "Call") LookupSpecialMethodSlotNode lookupCall, - @Shared("callCall") @Cached CallVarargsMethodNode callCallNode) { - Object call = lookupCall.execute(frame, getClassNode.execute(inliningTarget, callableObject), callableObject); - return callCall(frame, callableObject, arguments, keywords, raise, callCallNode, call); - } - - @Specialization(guards = {"!isCallable(callableObject)", "!isForeignMethod(callableObject)"}, replaces = {"doType", "doPythonClass"}) - protected static Object doObjectAndType(VirtualFrame frame, Object callableObject, Object[] arguments, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Shared("raise") @Cached PRaiseNode raise, - @Shared("getClassNode") @Cached GetClassNode getClassNode, - @Shared("lookupCall") @Cached(parameters = "Call") LookupSpecialMethodSlotNode lookupCall, - @Shared("callCall") @Cached CallVarargsMethodNode callCallNode) { - Object call = lookupCall.execute(frame, getClassNode.execute(inliningTarget, callableObject), callableObject); - return callCall(frame, callableObject, arguments, keywords, raise, callCallNode, call); + static Object builtinFunctionCall(VirtualFrame frame, PBuiltinFunction callable, Object[] arguments, PKeyword[] keywords, + @Bind Node inliningTarget, + @Cached CallDispatchers.BuiltinFunctionCachedCallNode callNode) { + return callNode.execute(frame, inliningTarget, callable, arguments, keywords); } @Specialization @InliningCutoff protected static Object doForeignMethod(ForeignMethod callable, Object[] arguments, PKeyword[] keywords, @Bind("this") Node inliningTarget, - @Shared("raise") @Cached PRaiseNode raise, @Cached PForeignToPTypeNode fromForeign, @Cached InlinedBranchProfile keywordsError, @Cached InlinedBranchProfile typeError, @@ -202,14 +161,14 @@ protected static Object doForeignMethod(ForeignMethod callable, Object[] argumen @CachedLibrary(limit = "getCallSiteInlineCacheMaxDepth()") InteropLibrary interop) { if (keywords.length != 0) { keywordsError.enter(inliningTarget); - throw raise.raise(PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ); + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ); } gil.release(true); try { return fromForeign.executeConvert(interop.invokeMember(callable.receiver, callable.methodName, arguments)); } catch (ArityException | UnsupportedTypeException | UnsupportedMessageException e) { typeError.enter(inliningTarget); - throw raise.raise(TypeError, e); + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, e); } catch (UnknownIdentifierException e) { // PyObjectGetMethod is supposed to have checked isMemberInvocable throw CompilerDirectives.shouldNotReachHere("Cannot invoke member"); @@ -218,104 +177,26 @@ protected static Object doForeignMethod(ForeignMethod callable, Object[] argumen } } - private static Object callCall(VirtualFrame frame, Object callableObject, Object[] arguments, PKeyword[] keywords, PRaiseNode raise, CallVarargsMethodNode callCallNode, Object call) { - if (call == PNone.NO_VALUE) { - throw raise.raise(TypeError, ErrorMessages.OBJ_ISNT_CALLABLE, callableObject); - } - return callCallNode.execute(frame, call, PythonUtils.prependArgument(callableObject, arguments), keywords); - } - - @Specialization(guards = "isPBuiltinFunction(callable.getFunction())") - protected static Object methodCallBuiltinDirect(VirtualFrame frame, PMethod callable, Object[] arguments, PKeyword[] keywords, - @Shared("dispatchNode") @Cached CallDispatchNode dispatch, - @Shared("argsNode") @Cached CreateArgumentsNode createArgs) { - // functions must be called directly otherwise the call stack is incorrect - return dispatch.executeCall(frame, (PBuiltinFunction) callable.getFunction(), createArgs.execute(callable, arguments, keywords)); - } - - @Specialization(guards = "isPFunction(callable.getFunction())", replaces = "methodCallBuiltinDirect") - protected static Object methodCallDirect(VirtualFrame frame, PMethod callable, Object[] arguments, PKeyword[] keywords, - @Shared("dispatchNode") @Cached CallDispatchNode dispatch, - @Shared("argsNode") @Cached CreateArgumentsNode createArgs) { - // functions must be called directly otherwise the call stack is incorrect - return dispatch.executeCall(frame, (PFunction) callable.getFunction(), createArgs.execute(callable, arguments, keywords)); - } - - @Specialization(limit = "1", guards = {"isSingleContext()", "callable == cachedCallable", "isPBuiltinFunction(cachedCallable.getFunction())"}) - protected static Object builtinMethodCallBuiltinDirectCached(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinMethod callable, Object[] arguments, PKeyword[] keywords, - @Cached(value = "callable", weak = true) PBuiltinMethod cachedCallable, - @Shared("dispatchNode") @Cached CallDispatchNode dispatch, - @Shared("argsNode") @Cached CreateArgumentsNode createArgs) { - // functions must be called directly otherwise the call stack is incorrect - return dispatch.executeCall(frame, cachedCallable.getBuiltinFunction(), createArgs.execute(cachedCallable, arguments, keywords)); - } - - @Specialization(guards = "isPBuiltinFunction(callable.getFunction())", replaces = "builtinMethodCallBuiltinDirectCached") - protected static Object builtinMethodCallBuiltinDirect(VirtualFrame frame, PBuiltinMethod callable, Object[] arguments, PKeyword[] keywords, - @Shared("dispatchNode") @Cached CallDispatchNode dispatch, - @Shared("argsNode") @Cached CreateArgumentsNode createArgs) { - // functions must be called directly otherwise the call stack is incorrect - return dispatch.executeCall(frame, callable.getBuiltinFunction(), createArgs.execute(callable, arguments, keywords)); - } - - @Specialization(guards = "!isFunction(callable.getFunction())") - protected static Object methodCall(VirtualFrame frame, PMethod callable, Object[] arguments, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Shared("raise") @Cached PRaiseNode raise, - @Shared("getClassNode") @Cached GetClassNode getClassNode, - @Shared("lookupCall") @Cached(parameters = "Call") LookupSpecialMethodSlotNode lookupCall, - @Shared("callCall") @Cached CallVarargsMethodNode callCallNode) { - return doObjectAndType(frame, callable, arguments, keywords, inliningTarget, raise, getClassNode, lookupCall, callCallNode); + @Specialization + static Object builtinMethodCall(VirtualFrame frame, PBuiltinMethod callable, Object[] arguments, PKeyword[] keywords, + @Bind Node inliningTarget, + @Cached CallDispatchers.BuiltinMethodCachedCallNode callNode) { + return callNode.execute(frame, inliningTarget, callable, arguments, keywords); } - @Specialization(guards = "!isFunction(callable.getFunction())") - protected static Object builtinMethodCall(VirtualFrame frame, PBuiltinMethod callable, Object[] arguments, PKeyword[] keywords, + @Fallback + static Object doGeneric(VirtualFrame frame, Object callableObject, Object[] arguments, PKeyword[] keywords, @Bind("this") Node inliningTarget, - @Shared("raise") @Cached PRaiseNode raise, - @Shared("getClassNode") @Cached GetClassNode getClassNode, - @Shared("lookupCall") @Cached(parameters = "Call") LookupSpecialMethodSlotNode lookupCall, - @Shared("callVarargs") @Cached CallVarargsMethodNode callCallNode) { - return doObjectAndType(frame, callable, arguments, keywords, inliningTarget, raise, getClassNode, lookupCall, callCallNode); - } - - @Specialization(replaces = {"doObjectAndType", "methodCallBuiltinDirect", "methodCallDirect", "builtinMethodCallBuiltinDirectCached", - "builtinMethodCallBuiltinDirect", "methodCall", "builtinMethodCall", "functionCall", "builtinFunctionCall"}, guards = "!isForeignMethod(callableObject)") - @Megamorphic - @InliningCutoff - protected static Object doGeneric(VirtualFrame frame, Object callableObject, Object[] arguments, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Shared("dispatchNode") @Cached CallDispatchNode dispatch, - @Shared("argsNode") @Cached CreateArgumentsNode createArgs, - @Shared("raise") @Cached PRaiseNode raise, - @Shared("getClassNode") @Cached GetClassNode getClassNode, - @Shared("lookupCall") @Cached(parameters = "Call") LookupSpecialMethodSlotNode lookupCall, - @Shared("callVarargs") @Cached CallVarargsMethodNode callCallNode) { - if (callableObject instanceof PFunction) { - return functionCall(frame, (PFunction) callableObject, arguments, keywords, dispatch, createArgs); - } else if (callableObject instanceof PBuiltinFunction) { - return builtinFunctionCall(frame, (PBuiltinFunction) callableObject, arguments, keywords, dispatch, createArgs); - } else if (callableObject instanceof PMethod) { - PMethod method = (PMethod) callableObject; - Object func = method.getFunction(); - if (func instanceof PFunction) { - return methodCallDirect(frame, method, arguments, keywords, dispatch, createArgs); - } else if (func instanceof PBuiltinFunction) { - return methodCallBuiltinDirect(frame, method, arguments, keywords, dispatch, createArgs); - } - } else if (callableObject instanceof PBuiltinMethod) { - PBuiltinMethod method = (PBuiltinMethod) callableObject; - return builtinMethodCallBuiltinDirect(frame, method, arguments, keywords, dispatch, createArgs); - } else if (callableObject instanceof BoundDescriptor) { - return doGeneric(frame, ((BoundDescriptor) callableObject).descriptor, - PythonUtils.arrayCopyOfRange(arguments, 1, arguments.length), keywords, - inliningTarget, dispatch, createArgs, raise, getClassNode, lookupCall, callCallNode); + @Cached PRaiseNode raise, + @Cached GetClassNode getClassNode, + @Cached GetCachedTpSlotsNode getSlots, + @Cached CallSlotTpCallNode callSlot) { + Object type = getClassNode.execute(inliningTarget, callableObject); + TpSlots slots = getSlots.execute(inliningTarget, type); + if (slots.tp_call() != null) { + return callSlot.execute(frame, inliningTarget, slots.tp_call(), callableObject, arguments, keywords); } - Object callableType = getClassNode.execute(inliningTarget, callableObject); - return callCall(frame, callableObject, arguments, keywords, raise, callCallNode, lookupCall.execute(frame, callableType, callableObject)); - } - - protected static boolean isForeignMethod(Object object) { - return object instanceof ForeignMethod; + throw raise.raise(inliningTarget, TypeError, ErrorMessages.OBJ_ISNT_CALLABLE, callableObject); } @GenerateInline diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallTargetInvokeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallTargetInvokeNode.java deleted file mode 100644 index be02778227..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallTargetInvokeNode.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.call; - -import com.oracle.graal.python.builtins.objects.cell.PCell; -import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.function.PFunction; -import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.nodes.bytecode.PBytecodeGeneratorFunctionRootNode; -import com.oracle.graal.python.runtime.ExecutionContext.CallContext; -import com.oracle.graal.python.runtime.ExecutionContext.IndirectCalleeContext; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.DirectCallNode; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; - -public abstract class CallTargetInvokeNode extends DirectInvokeNode { - @Child private DirectCallNode callNode; - @Child private CallContext callContext; - protected final boolean isBuiltin; - - protected CallTargetInvokeNode(CallTarget callTarget, boolean isBuiltin, boolean isGenerator) { - this.callNode = Truffle.getRuntime().createDirectCallNode(callTarget); - if (isBuiltin) { - callNode.cloneCallTarget(); - } - if (isGenerator && shouldInlineGenerators()) { - this.callNode.forceInlining(); - } - this.callContext = CallContext.create(); - this.isBuiltin = isBuiltin; - } - - @TruffleBoundary - public static CallTargetInvokeNode create(PFunction callee) { - RootCallTarget callTarget = getCallTarget(callee); - boolean builtin = isBuiltin(callee); - boolean isGenerator = callTarget.getRootNode() instanceof PBytecodeGeneratorFunctionRootNode; - return CallTargetInvokeNodeGen.create(callTarget, builtin, isGenerator); - } - - @TruffleBoundary - public static CallTargetInvokeNode create(PBuiltinFunction callee) { - RootCallTarget callTarget = getCallTarget(callee); - boolean builtin = isBuiltin(callee); - return CallTargetInvokeNodeGen.create(callTarget, builtin, false); - } - - public static CallTargetInvokeNode create(CallTarget callTarget, boolean isBuiltin, boolean isGenerator) { - return CallTargetInvokeNodeGen.create(callTarget, isBuiltin, isGenerator); - } - - /** - * @param callee A PFunction if the callee is one, otherwise null. Used for generator functions - * only. - */ - public abstract Object execute(VirtualFrame frame, PFunction callee, PythonObject globals, PCell[] closure, Object[] arguments); - - @Specialization(guards = {"globals == null", "closure == null"}) - protected Object doNoClosure(VirtualFrame frame, PFunction callee, @SuppressWarnings("unused") PythonObject globals, @SuppressWarnings("unused") PCell[] closure, Object[] arguments, - @Bind("this") Node inliningTarget, - @Shared @Cached InlinedConditionProfile generatorFunctionProfile) { - RootCallTarget ct = (RootCallTarget) callNode.getCurrentCallTarget(); - optionallySetGeneratorFunction(inliningTarget, arguments, ct, generatorFunctionProfile, callee); - // If the frame is 'null', we expect the execution state (i.e. caller info and exception - // state) in the context. There are two common reasons for having a 'null' frame: - // 1. This node is the first invoke node used via interop. - // 2. This invoke node is (indirectly) used behind a TruffleBoundary. - // This is preferably prepared using 'IndirectCallContext.enter'. - if (profileIsNullFrame(frame == null)) { - PythonContext context = PythonContext.get(this); - PythonThreadState threadState = context.getThreadState(context.getLanguage(this)); - Object state = IndirectCalleeContext.enter(threadState, arguments, ct); - try { - return callNode.call(arguments); - } finally { - IndirectCalleeContext.exit(threadState, state); - } - } else { - callContext.prepareCall(frame, arguments, ct, this); - return callNode.call(arguments); - } - } - - @Specialization(replaces = "doNoClosure") - protected Object doGeneric(VirtualFrame frame, PFunction callee, PythonObject globals, PCell[] closure, Object[] arguments, - @Bind("this") Node inliningTarget, - @Shared @Cached InlinedConditionProfile generatorFunctionProfile) { - PArguments.setGlobals(arguments, globals); - PArguments.setClosure(arguments, closure); - return doNoClosure(frame, callee, null, null, arguments, inliningTarget, generatorFunctionProfile); - } - - public final CallTarget getCallTarget() { - return callNode.getCallTarget(); - } - - public final RootNode getCurrentRootNode() { - return callNode.getCurrentRootNode(); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/FunctionInvokeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/FunctionInvokeNode.java deleted file mode 100644 index 9f53665577..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/FunctionInvokeNode.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.call; - -import com.oracle.graal.python.builtins.objects.cell.PCell; -import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.function.PFunction; -import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.nodes.bytecode.PBytecodeGeneratorFunctionRootNode; -import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; -import com.oracle.graal.python.runtime.ExecutionContext.CallContext; -import com.oracle.graal.python.runtime.ExecutionContext.IndirectCalleeContext; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.DirectCallNode; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; - -public abstract class FunctionInvokeNode extends DirectInvokeNode { - @Child private DirectCallNode callNode; - @Child private CallContext callContext; - - // Needed only for generator functions, will be null for builtins - private final PFunction callee; - private final PythonObject globals; - private final PCell[] closure; - protected final boolean isBuiltin; - - protected FunctionInvokeNode(PFunction callee, CallTarget callTarget, PythonObject globals, PCell[] closure, boolean isBuiltin, boolean isGenerator, boolean split) { - this.callee = callee; - this.callNode = Truffle.getRuntime().createDirectCallNode(callTarget); - if (split) { - callNode.cloneCallTarget(); - } - if (isGenerator && shouldInlineGenerators()) { - this.callNode.forceInlining(); - } - this.globals = globals; - this.closure = closure; - this.isBuiltin = isBuiltin; - this.callContext = CallContext.create(); - } - - public abstract Object execute(VirtualFrame frame, Object[] arguments); - - @Specialization - protected Object doDirect(VirtualFrame frame, Object[] arguments, - @Bind("this") Node inliningTarget, - @Cached InlinedConditionProfile isGeneratorFunctionProfile) { - PArguments.setGlobals(arguments, globals); - PArguments.setClosure(arguments, closure); - RootCallTarget ct = (RootCallTarget) callNode.getCurrentCallTarget(); - optionallySetGeneratorFunction(inliningTarget, arguments, ct, isGeneratorFunctionProfile, callee); - if (profileIsNullFrame(frame == null)) { - PythonContext context = PythonContext.get(this); - PythonThreadState threadState = context.getThreadState(context.getLanguage(this)); - Object state = IndirectCalleeContext.enter(threadState, arguments, ct); - try { - return callNode.call(arguments); - } finally { - IndirectCalleeContext.exit(threadState, state); - } - } else { - callContext.prepareCall(frame, arguments, ct, this); - return callNode.call(arguments); - } - } - - public final RootNode getCurrentRootNode() { - return callNode.getCurrentRootNode(); - } - - @TruffleBoundary - public static FunctionInvokeNode create(PFunction callee) { - RootCallTarget callTarget = getCallTarget(callee); - return FunctionInvokeNodeGen.create(callee, callTarget, callee.getGlobals(), callee.getClosure(), false, callTarget.getRootNode() instanceof PBytecodeGeneratorFunctionRootNode, - callee.forceSplitDirectCalls()); - } - - @TruffleBoundary - public static FunctionInvokeNode create(PBuiltinFunction callee) { - RootCallTarget callTarget = getCallTarget(callee); - boolean split = forceSplitBuiltins() || (callee.getFunctionRootNode() instanceof BuiltinFunctionRootNode root && root.getBuiltin().forceSplitDirectCalls()); - return FunctionInvokeNodeGen.create(null, callTarget, null, null, true, false, split); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/GenericInvokeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/GenericInvokeNode.java deleted file mode 100644 index 1f4622f115..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/GenericInvokeNode.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.call; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.function.PFunction; -import com.oracle.graal.python.runtime.ExecutionContext.CallContext; -import com.oracle.graal.python.runtime.ExecutionContext.IndirectCalleeContext; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.Frame; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.IndirectCallNode; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; - -@GenerateUncached -@SuppressWarnings("truffle-inlining") // footprint reduction 28 -> 10 -// Not inlined because it passes "this" to prepareIndirectCall() -public abstract class GenericInvokeNode extends InvokeNode { - - @NeverDefault - public static GenericInvokeNode create() { - return GenericInvokeNodeGen.create(); - } - - public static GenericInvokeNode getUncached() { - return GenericInvokeNodeGen.getUncached(); - } - - protected GenericInvokeNode() { - } - - /** - * To be used when this node is called adopted. - * - * @param frame - the current frame - * @param callee - either a {@link PFunction}, {@link PBuiltinFunction}, or - * {@link RootCallTarget}. - * @param arguments - the complete (runtime + user) frame arguments for the call - */ - public final Object execute(VirtualFrame frame, Object callee, Object[] arguments) { - return executeInternal(frame, callee, arguments); - } - - protected abstract Object executeInternal(Frame frame, Object callee, Object[] arguments); - - /** - * Can be used when this node is called unadopted or from a place where no frame is available. - * However, it will be slower than passing a frame, because the threadstate is read from the - * Python context. - * - * @param callee - either a {@link PFunction}, {@link PBuiltinFunction}, or - * {@link RootCallTarget}. - * @param arguments - the complete (runtime + user) frame arguments for the call - */ - public final Object execute(Object callee, Object[] arguments) { - return executeInternal(null, callee, arguments); - } - - private Object doCall(Frame frame, Node inliningTarget, PFunction callee, RootCallTarget callTarget, Object[] arguments, - PythonLanguage language, PythonContext context, - IndirectCallNode callNode, CallContext callContext, - InlinedConditionProfile isNullFrameProfile, InlinedConditionProfile isGeneratorFunctionProfile) { - optionallySetGeneratorFunction(inliningTarget, arguments, callTarget, isGeneratorFunctionProfile, callee); - if (isNullFrameProfile.profile(inliningTarget, frame == null)) { - PythonThreadState threadState = context.getThreadState(language); - Object state = IndirectCalleeContext.enterIndirect(threadState, arguments); - try { - return callNode.call(callTarget, arguments); - } finally { - IndirectCalleeContext.exit(threadState, state); - } - } else { - assert frame instanceof VirtualFrame : "GenericInvokeNode should not be executed with non-virtual frames"; - callContext.prepareIndirectCall((VirtualFrame) frame, arguments, this); - return callNode.call(callTarget, arguments); - } - } - - private Object doCallWithFrame(Frame frame, Node inlinlingTarget, PFunction callee, RootCallTarget callTarget, Object[] arguments, - IndirectCallNode callNode, CallContext callContext, InlinedConditionProfile isGeneratorFunctionProfile) { - optionallySetGeneratorFunction(inlinlingTarget, arguments, callTarget, isGeneratorFunctionProfile, callee); - assert frame instanceof VirtualFrame : "GenericInvokeNode should not be executed with non-virtual frames"; - callContext.prepareIndirectCall((VirtualFrame) frame, arguments, this); - return callNode.call(callTarget, arguments); - } - - @Specialization(guards = "frame != null") - Object invokeFunctionWithFrame(Frame frame, PFunction callee, Object[] arguments, - @Bind("this") Node inliningTarget, - @Shared("callNode") @Cached IndirectCallNode callNode, - @Shared("callContext") @Cached CallContext callContext, - @Shared("isGeneratorFunctionProfile") @Cached InlinedConditionProfile isGeneratorFunctionProfile) { - PArguments.setGlobals(arguments, callee.getGlobals()); - PArguments.setClosure(arguments, callee.getClosure()); - RootCallTarget callTarget = getCallTarget(callee); - return doCallWithFrame(frame, inliningTarget, callee, callTarget, arguments, callNode, callContext, isGeneratorFunctionProfile); - } - - @Specialization(guards = "frame != null") - Object invokeBuiltinWithFrame(Frame frame, PBuiltinFunction callee, Object[] arguments, - @Bind("this") Node inliningTarget, - @Shared("callNode") @Cached IndirectCallNode callNode, - @Shared("callContext") @Cached CallContext callContext, - @Shared("isGeneratorFunctionProfile") @Cached InlinedConditionProfile isGeneratorFunctionProfile) { - RootCallTarget callTarget = getCallTarget(callee); - return doCallWithFrame(frame, inliningTarget, null, callTarget, arguments, callNode, callContext, isGeneratorFunctionProfile); - } - - @Specialization(guards = "frame != null") - Object invokeCallTargetWithFrame(Frame frame, RootCallTarget callTarget, Object[] arguments, - @Bind("this") Node inliningTarget, - @Shared("callNode") @Cached IndirectCallNode callNode, - @Shared("callContext") @Cached CallContext callContext, - @Shared("isGeneratorFunctionProfile") @Cached InlinedConditionProfile isGeneratorFunctionProfile) { - return doCallWithFrame(frame, inliningTarget, null, callTarget, arguments, callNode, callContext, isGeneratorFunctionProfile); - } - - @Specialization(replaces = "invokeFunctionWithFrame") - Object invokeFunction(Frame frame, PFunction callee, Object[] arguments, - @Bind("this") Node inliningTarget, - @Shared("callNode") @Cached IndirectCallNode callNode, - @Shared("callContext") @Cached CallContext callContext, - @Shared("isNullFrameProfile") @Cached InlinedConditionProfile isNullFrameProfile, - @Shared("isGeneratorFunctionProfile") @Cached InlinedConditionProfile isGeneratorFunctionProfile) { - PArguments.setGlobals(arguments, callee.getGlobals()); - PArguments.setClosure(arguments, callee.getClosure()); - RootCallTarget callTarget = getCallTarget(callee); - PythonContext context = PythonContext.get(this); - return doCall(frame, inliningTarget, callee, callTarget, arguments, context.getLanguage(this), context, callNode, callContext, isNullFrameProfile, isGeneratorFunctionProfile); - } - - @Specialization(replaces = "invokeBuiltinWithFrame") - Object invokeBuiltin(Frame frame, PBuiltinFunction callee, Object[] arguments, - @Bind("this") Node inliningTarget, - @Shared("callNode") @Cached IndirectCallNode callNode, - @Shared("callContext") @Cached CallContext callContext, - @Shared("isNullFrameProfile") @Cached InlinedConditionProfile isNullFrameProfile, - @Shared("isGeneratorFunctionProfile") @Cached InlinedConditionProfile isGeneratorFunctionProfile) { - RootCallTarget callTarget = getCallTarget(callee); - PythonContext context = PythonContext.get(this); - return doCall(frame, inliningTarget, null, callTarget, arguments, context.getLanguage(this), context, callNode, callContext, isNullFrameProfile, isGeneratorFunctionProfile); - } - - @Specialization(replaces = "invokeCallTargetWithFrame") - Object invokeCallTarget(Frame frame, RootCallTarget callTarget, Object[] arguments, - @Bind("this") Node inliningTarget, - @Shared("callNode") @Cached IndirectCallNode callNode, - @Shared("callContext") @Cached CallContext callContext, - @Shared("isNullFrameProfile") @Cached InlinedConditionProfile isNullFrameProfile, - @Shared("isGeneratorFunctionProfile") @Cached InlinedConditionProfile isGeneratorFunctionProfile) { - PythonContext context = PythonContext.get(this); - return doCall(frame, inliningTarget, null, callTarget, arguments, context.getLanguage(this), context, callNode, callContext, isNullFrameProfile, isGeneratorFunctionProfile); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/InvokeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/InvokeNode.java deleted file mode 100644 index 68fbf82cfe..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/InvokeNode.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. - * Copyright (c) 2014, Regents of the University of California - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.oracle.graal.python.nodes.call; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.function.PFunction; -import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; -import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetCallTargetNode; -import com.oracle.graal.python.nodes.bytecode.PBytecodeGeneratorFunctionRootNode; -import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; - -public abstract class InvokeNode extends Node { - protected static boolean shouldInlineGenerators() { - CompilerAsserts.neverPartOfCompilation(); - return PythonLanguage.get(null).getEngineOption(PythonOptions.ForceInlineGeneratorCalls); - } - - protected static boolean forceSplitBuiltins() { - CompilerAsserts.neverPartOfCompilation(); - return PythonLanguage.get(null).getEngineOption(PythonOptions.EnableForcedSplits); - } - - @TruffleBoundary - protected static RootCallTarget getCallTarget(Object callee) { - Object actualCallee = callee; - RootCallTarget callTarget = GetCallTargetNode.getUncached().execute(actualCallee); - if (callTarget == null) { - throw CompilerDirectives.shouldNotReachHere("Unsupported callee type " + actualCallee); - } - return callTarget; - } - - protected static void optionallySetGeneratorFunction(Node inliningTarget, Object[] arguments, CallTarget callTarget, InlinedConditionProfile isGeneratorFunctionProfile, PFunction callee) { - RootNode rootNode = ((RootCallTarget) callTarget).getRootNode(); - if (isGeneratorFunctionProfile.profile(inliningTarget, rootNode instanceof PBytecodeGeneratorFunctionRootNode)) { - assert callee != null : "generator function callee not passed to invoke node"; - PArguments.setGeneratorFunction(arguments, callee); - } - } - - protected static boolean isBuiltin(Object callee) { - return callee instanceof PBuiltinFunction || callee instanceof PBuiltinMethod; - } - - public static Object invokeUncached(PBuiltinFunction callee, Object[] arguments) { - return GenericInvokeNode.getUncached().execute(callee, arguments); - } - - public static Object invokeUncached(RootCallTarget ct, Object[] arguments) { - return GenericInvokeNode.getUncached().execute(ct, arguments); - } -} - -abstract class DirectInvokeNode extends InvokeNode { - - @CompilationFinal private int state = 0; - - protected boolean profileIsNullFrame(boolean isNullFrame) { - if (state == 0) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - if (isNullFrame) { - state = 0x1; - } else { - state = 0x2; - } - } - - if (state == 0x1) { - if (!isNullFrame) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw new IllegalStateException("Invoke node was initialized for a null frame. Cannot use it with non-null frame now."); - } - return true; - } - assert state == 0x2; - if (isNullFrame) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw new IllegalStateException("Invoke node was initialized for a non-null frame. Cannot use it with null frame now."); - } - return false; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/AbstractCallMethodNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/AbstractCallMethodNode.java index eedc98b468..7515225fce 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/AbstractCallMethodNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/AbstractCallMethodNode.java @@ -40,24 +40,16 @@ */ package com.oracle.graal.python.nodes.call.special; -import static com.oracle.graal.python.nodes.ErrorMessages.EXPECTED_D_ARGS; - import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.Slot.SlotSignature; import com.oracle.graal.python.builtins.Builtin; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.BinaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.TernaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.UnaryBuiltinDescriptor; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.builtins.objects.method.PMethod; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotBuiltin; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.PRootNode; import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetCallTargetNode; import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; @@ -66,23 +58,18 @@ import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; -import com.oracle.graal.python.nodes.truffle.PythonTypes; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.util.PythonUtils.NodeCounterWithLimit; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.NodeField; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; -@TypeSystemReference(PythonTypes.class) @ImportStatic({PythonOptions.class, PGuards.class}) @NodeField(name = "maxSizeExceeded", type = boolean.class) abstract class AbstractCallMethodNode extends PNodeWithContext { @@ -101,6 +88,11 @@ protected PythonBuiltinBaseNode getBuiltin(VirtualFrame frame, PBuiltinFunction if (builtinNodeFactory == null) { return null; // see for example MethodDescriptorRoot and subclasses } + if (TpSlotBuiltin.isSlotFactory(builtinNodeFactory)) { + // slot wrapper must perform validation implemented in WrapperDescrCall inside the + // PBuiltinRootNode + return null; + } Class nodeClass = builtinNodeFactory.getNodeClass(); int builtinNodeArity = getBuiltinNodeArity(nodeClass); if (builtinNodeArity == -1 || builtinNodeArity < nargs) { @@ -111,7 +103,7 @@ protected PythonBuiltinBaseNode getBuiltin(VirtualFrame frame, PBuiltinFunction if (slotSignature.needsFrame() || nargs < slotSignature.minNumOfPositionalArgs()) { return null; } - int maxArgs = Math.max(slotSignature.minNumOfPositionalArgs(), slotSignature.parameterNames().length); + int maxArgs = Math.max(Math.max(slotSignature.maxNumOfPositionalArgs(), slotSignature.minNumOfPositionalArgs()), slotSignature.parameterNames().length); if (nargs > maxArgs) { return null; } @@ -127,9 +119,6 @@ protected PythonBuiltinBaseNode getBuiltin(VirtualFrame frame, PBuiltinFunction if (nargs < builtinAnnotation.minNumOfPositionalArgs() || nargs > maxArgs) { return null; } - } else { - // for slots without SlotSignature the max args is implied by the node class - assert TpSlotBuiltin.isSlotFactory(builtinNodeFactory) : nodeClass.getName(); } } PythonBuiltinBaseNode builtinNode = builtinNodeFactory.createNode(); @@ -152,30 +141,6 @@ private static int getBuiltinNodeArity(Class no return -1; } - public PythonUnaryBuiltinNode getBuiltin(UnaryBuiltinDescriptor descriptor) { - PythonUnaryBuiltinNode builtin = descriptor.createNode(); - if (!callerExceedsMaxSize(builtin)) { - return builtin; - } - return null; - } - - public PythonBinaryBuiltinNode getBuiltin(BinaryBuiltinDescriptor descriptor) { - PythonBinaryBuiltinNode builtin = descriptor.createNode(); - if (!callerExceedsMaxSize(builtin)) { - return builtin; - } - return null; - } - - public PythonTernaryBuiltinNode getBuiltin(TernaryBuiltinDescriptor descriptor) { - PythonTernaryBuiltinNode builtin = descriptor.createNode(); - if (!callerExceedsMaxSize(builtin)) { - return builtin; - } - return null; - } - private boolean callerExceedsMaxSize(T builtinNode) { CompilerAsserts.neverPartOfCompilation(); if (isAdoptable() && !isMaxSizeExceeded()) { @@ -228,29 +193,6 @@ private boolean callerExceedsMaxSize(T builtin return true; } - PythonVarargsBuiltinNode getVarargs(VirtualFrame frame, Object func) { - CompilerAsserts.neverPartOfCompilation(); - if (func instanceof PBuiltinFunction builtinFunc) { - NodeFactory builtinNodeFactory = builtinFunc.getBuiltinNodeFactory(); - if (builtinNodeFactory == null) { - return null; // see for example MethodDescriptorRoot and subclasses - } - if (!PythonVarargsBuiltinNode.class.isAssignableFrom(builtinNodeFactory.getNodeClass())) { - // This filters out slots for now. They do not have @Builtin annotation - return null; - } - assert builtinNodeFactory.getNodeClass().getAnnotationsByType(Builtin.class).length > 0 : "PBuiltinFunction " + builtinFunc + " is expected to have a Builtin annotated node."; - if (builtinNodeFactory.getNodeClass().getAnnotationsByType(Builtin.class)[0].needsFrame() && frame == null) { - return null; - } - PythonVarargsBuiltinNode builtinNode = (PythonVarargsBuiltinNode) builtinFunc.getBuiltinNodeFactory().createNode(); - if (!callerExceedsMaxSize(builtinNode)) { - return builtinNode; - } - } - return null; - } - protected static boolean takesSelfArg(Object func) { if (func instanceof PBuiltinFunction) { RootNode functionRootNode = ((PBuiltinFunction) func).getFunctionRootNode(); @@ -271,17 +213,6 @@ protected static RootCallTarget getCallTarget(PBuiltinMethod meth, GetCallTarget return getCtNode.execute(meth.getFunction()); } - protected void raiseInvalidArgsNumUncached(boolean hasValidArgsNum, BuiltinMethodDescriptor descr) { - if (!hasValidArgsNum) { - raiseInvalidArgsNumUncached(descr); - } - } - - @TruffleBoundary - private void raiseInvalidArgsNumUncached(BuiltinMethodDescriptor descr) { - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.TypeError, EXPECTED_D_ARGS, descr.minNumOfPositionalArgs()); - } - protected static Object callUnaryBuiltin(VirtualFrame frame, PythonBuiltinBaseNode builtin, Object arg1) { CompilerAsserts.partialEvaluationConstant(builtin); if (builtin instanceof PythonUnaryBuiltinNode) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallBinaryMethodNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallBinaryMethodNode.java index b8a6919a62..49f334de7e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallBinaryMethodNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallBinaryMethodNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,22 +40,13 @@ */ package com.oracle.graal.python.nodes.call.special; -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.BinaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.TernaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetCallTargetNode; import com.oracle.graal.python.nodes.call.BoundDescriptor; import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.call.GenericInvokeNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.dsl.Bind; @@ -73,7 +64,7 @@ import com.oracle.truffle.api.profiles.InlinedConditionProfile; @GenerateUncached -public abstract class CallBinaryMethodNode extends CallReversibleMethodNode { +public abstract class CallBinaryMethodNode extends AbstractCallMethodNode { @NeverDefault public static CallBinaryMethodNode create() { return CallBinaryMethodNodeGen.create(); @@ -95,74 +86,19 @@ public final Object executeObject(Object callable, Object arg1, Object arg2) { return executeObject(null, callable, arg1, arg2); } - @Specialization(guards = {"cachedInfo == info", "node != null"}, limit = "getCallSiteInlineCacheMaxDepth()") - static Object callBinarySpecialMethodSlotInlined(VirtualFrame frame, @SuppressWarnings("unused") BinaryBuiltinDescriptor info, Object arg1, Object arg2, - @SuppressWarnings("unused") @Cached("info") BinaryBuiltinDescriptor cachedInfo, - @Cached("getBuiltin(cachedInfo)") PythonBinaryBuiltinNode node) { - if (cachedInfo.isReverseOperation()) { - return node.execute(frame, arg2, arg1); - } else { - return node.execute(frame, arg1, arg2); - } - } - - protected static boolean hasAllowedArgsNum(BuiltinMethodDescriptor descr) { - return descr.minNumOfPositionalArgs() <= 2; - } - - @Specialization(guards = {"cachedInfo == info", "node != null"}, limit = "getCallSiteInlineCacheMaxDepth()") - Object callTernarySpecialMethodSlotInlined(VirtualFrame frame, @SuppressWarnings("unused") TernaryBuiltinDescriptor info, Object arg1, Object arg2, - @SuppressWarnings("unused") @Cached("info") TernaryBuiltinDescriptor cachedInfo, - @Cached("hasAllowedArgsNum(cachedInfo)") boolean hasValidArgsNum, - @Cached("getBuiltin(cachedInfo)") PythonTernaryBuiltinNode node) { - raiseInvalidArgsNumUncached(hasValidArgsNum, cachedInfo); - if (cachedInfo.isReverseOperation()) { - return node.execute(frame, arg2, arg1, PNone.NO_VALUE); - } - return node.execute(frame, arg1, arg2, PNone.NO_VALUE); - } - - protected static boolean isBinaryOrTernaryBuiltinDescriptor(Object value) { - return value instanceof BinaryBuiltinDescriptor || value instanceof TernaryBuiltinDescriptor; - } - - @Specialization(guards = "isBinaryOrTernaryBuiltinDescriptor(info)", replaces = {"callBinarySpecialMethodSlotInlined", "callTernarySpecialMethodSlotInlined"}) - @InliningCutoff - Object callSpecialMethodSlotCallTarget(VirtualFrame frame, BuiltinMethodDescriptor info, Object arg1, Object arg2, - @Bind("this") Node inliningTarget, - @Exclusive @Cached InlinedConditionProfile invalidArgsProfile, - @Cached GenericInvokeNode invokeNode) { - raiseInvalidArgsNumUncached(invalidArgsProfile.profile(inliningTarget, hasAllowedArgsNum(info)), info); - RootCallTarget callTarget = PythonLanguage.get(this).getDescriptorCallTarget(info); - Object[] arguments = PArguments.create(2); - PArguments.setArgument(arguments, 0, arg1); - PArguments.setArgument(arguments, 1, arg2); - return invokeNode.execute(frame, callTarget, arguments); - } - @Specialization(guards = {"isSingleContext()", "func == cachedFunc", "builtinNode != null"}, limit = "getCallSiteInlineCacheMaxDepth()") static Object callObjectSingleContext(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinFunction func, Object arg1, Object arg2, @SuppressWarnings("unused") @Cached("func") PBuiltinFunction cachedFunc, - @SuppressWarnings("unused") @Cached("isForReverseBinaryOperation(func.getCallTarget())") boolean isReverse, @Cached("getBuiltin(frame, func, 2)") PythonBuiltinBaseNode builtinNode) { - if (isReverse) { - return callBinaryBuiltin(frame, builtinNode, arg2, arg1); - } else { - return callBinaryBuiltin(frame, builtinNode, arg1, arg2); - } + return callBinaryBuiltin(frame, builtinNode, arg1, arg2); } @Specialization(guards = {"func.getCallTarget() == ct", "builtinNode != null"}, // limit = "getCallSiteInlineCacheMaxDepth()") static Object callObject(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinFunction func, Object arg1, Object arg2, @SuppressWarnings("unused") @Cached("func.getCallTarget()") RootCallTarget ct, - @SuppressWarnings("unused") @Cached("isForReverseBinaryOperation(func.getCallTarget())") boolean isReverse, @Cached("getBuiltin(frame, func, 2)") PythonBuiltinBaseNode builtinNode) { - if (isReverse) { - return callBinaryBuiltin(frame, builtinNode, arg2, arg1); - } else { - return callBinaryBuiltin(frame, builtinNode, arg1, arg2); - } + return callBinaryBuiltin(frame, builtinNode, arg1, arg2); } @Specialization(guards = {"isSingleContext()", "func == cachedFunc", "builtinNode != null", "!takesSelfArg"}, limit = "getCallSiteInlineCacheMaxDepth()") @@ -199,8 +135,7 @@ static Object callMethodSelf(VirtualFrame frame, @SuppressWarnings("unused") PBu return callTernaryBuiltin(frame, builtinNode, func.getSelf(), arg1, arg2); } - @Specialization(guards = "!isBinaryOrTernaryBuiltinDescriptor(func)", // - replaces = {"callObjectSingleContext", "callObject", "callMethodSingleContext", "callMethod", "callMethodSingleContextSelf", "callMethodSelf"}) + @Specialization(replaces = {"callObjectSingleContext", "callObject", "callMethodSingleContext", "callMethod", "callMethodSingleContextSelf", "callMethodSelf"}) @Megamorphic @InliningCutoff static Object call(VirtualFrame frame, Object func, Object arg1, Object arg2, diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallReversibleMethodNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallReversibleMethodNode.java deleted file mode 100644 index 46a95d623e..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallReversibleMethodNode.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.call.special; - -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.RootCallTarget; - -abstract class CallReversibleMethodNode extends AbstractCallMethodNode { - protected boolean isForReverseBinaryOperation(RootCallTarget ct) { - CompilerAsserts.neverPartOfCompilation(); - return PBuiltinFunction.isReverseOperationSlot(ct); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallTernaryMethodNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallTernaryMethodNode.java index d630b50122..5a368adefb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallTernaryMethodNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallTernaryMethodNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,18 +40,13 @@ */ package com.oracle.graal.python.nodes.call.special; -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.TernaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetCallTargetNode; import com.oracle.graal.python.nodes.call.BoundDescriptor; import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.call.GenericInvokeNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.dsl.Bind; @@ -67,7 +62,7 @@ import com.oracle.truffle.api.profiles.InlinedConditionProfile; @GenerateUncached -public abstract class CallTernaryMethodNode extends CallReversibleMethodNode { +public abstract class CallTernaryMethodNode extends AbstractCallMethodNode { @NeverDefault public static CallTernaryMethodNode create() { return CallTernaryMethodNodeGen.create(); @@ -79,59 +74,21 @@ public static CallTernaryMethodNode getUncached() { public abstract Object execute(Frame frame, Object callable, Object arg1, Object arg2, Object arg3); - @Specialization(guards = {"cachedInfo == info", "node != null"}, limit = "getCallSiteInlineCacheMaxDepth()") - static Object callSpecialMethodSlotInlined(VirtualFrame frame, @SuppressWarnings("unused") TernaryBuiltinDescriptor info, Object arg1, Object arg2, Object arg3, - @SuppressWarnings("unused") @Cached("info") TernaryBuiltinDescriptor cachedInfo, - @Cached("getBuiltin(cachedInfo)") PythonTernaryBuiltinNode node) { - return node.execute(frame, arg1, arg2, arg3); - } - - @Specialization(replaces = "callSpecialMethodSlotInlined") - @InliningCutoff - static Object callSpecialMethodSlotCallTarget(VirtualFrame frame, TernaryBuiltinDescriptor info, Object arg1, Object arg2, Object arg3, - @Cached GenericInvokeNode invokeNode) { - RootCallTarget callTarget = PythonLanguage.get(invokeNode).getDescriptorCallTarget(info); - Object[] arguments = PArguments.create(3); - PArguments.setArgument(arguments, 0, arg1); - PArguments.setArgument(arguments, 1, arg2); - PArguments.setArgument(arguments, 2, arg3); - return invokeNode.execute(frame, callTarget, arguments); - } - - @Specialization(guards = {"isSingleContext()", "func == cachedFunc", "builtinNode != null", "!isReverse"}, limit = "getCallSiteInlineCacheMaxDepth()") + @Specialization(guards = {"isSingleContext()", "func == cachedFunc", "builtinNode != null"}, limit = "getCallSiteInlineCacheMaxDepth()") static Object doBuiltinFunctionCached(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinFunction func, Object arg1, Object arg2, Object arg3, @SuppressWarnings("unused") @Cached("func") PBuiltinFunction cachedFunc, - @SuppressWarnings("unused") @Cached("isForReverseBinaryOperation(func.getCallTarget())") boolean isReverse, @Cached("getBuiltin(frame, func, 3)") PythonBuiltinBaseNode builtinNode) { return callTernaryBuiltin(frame, builtinNode, arg1, arg2, arg3); } - @Specialization(guards = {"isSingleContext()", "func == cachedFunc", "builtinNode != null", "isReverse"}, limit = "getCallSiteInlineCacheMaxDepth()") - static Object doBuiltinFunctionCachedReverse(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinFunction func, Object arg1, Object arg2, Object arg3, - @SuppressWarnings("unused") @Cached("func") PBuiltinFunction cachedFunc, - @SuppressWarnings("unused") @Cached("isForReverseBinaryOperation(func.getCallTarget())") boolean isReverse, - @Cached("getBuiltin(frame, func, 3)") PythonBuiltinBaseNode builtinNode) { - return callTernaryBuiltin(frame, builtinNode, arg2, arg1, arg3); - } - - @Specialization(guards = {"func.getCallTarget() == ct", "builtinNode != null", "!isReverse"}, // + @Specialization(guards = {"func.getCallTarget() == ct", "builtinNode != null"}, // limit = "getCallSiteInlineCacheMaxDepth()") static Object doBuiltinFunctionCtCached(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinFunction func, Object arg1, Object arg2, Object arg3, @SuppressWarnings("unused") @Cached("func.getCallTarget()") RootCallTarget ct, - @SuppressWarnings("unused") @Cached("isForReverseBinaryOperation(func.getCallTarget())") boolean isReverse, @Cached("getBuiltin(frame, func, 3)") PythonBuiltinBaseNode builtinNode) { return callTernaryBuiltin(frame, builtinNode, arg1, arg2, arg3); } - @Specialization(guards = {"func.getCallTarget() == ct", "builtinNode != null", "isReverse"}, // - limit = "getCallSiteInlineCacheMaxDepth()") - static Object doBuiltinFunctionCtCachedReverse(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinFunction func, Object arg1, Object arg2, Object arg3, - @SuppressWarnings("unused") @Cached("func.getCallTarget()") RootCallTarget ct, - @SuppressWarnings("unused") @Cached("isForReverseBinaryOperation(func.getCallTarget())") boolean isReverse, - @Cached("getBuiltin(frame, func, 3)") PythonBuiltinBaseNode builtinNode) { - return callTernaryBuiltin(frame, builtinNode, arg2, arg1, arg3); - } - @Specialization(guards = {"isSingleContext()", "func == cachedFunc", "builtinNode != null", "!takesSelfArg"}, limit = "getCallSiteInlineCacheMaxDepth()") static Object doBuiltinMethodCached(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinMethod func, Object arg1, Object arg2, Object arg3, @SuppressWarnings("unused") @Cached("func") PBuiltinMethod cachedFunc, @@ -166,8 +123,8 @@ static Object callSelfMethod(VirtualFrame frame, @SuppressWarnings("unused") PBu return callQuaternaryBuiltin(frame, builtinNode, func.getSelf(), arg1, arg2, arg3); } - @Specialization(guards = "!isTernaryBuiltinDescriptor(func)", replaces = {"doBuiltinFunctionCached", "doBuiltinFunctionCtCached", "doBuiltinFunctionCachedReverse", - "doBuiltinFunctionCtCachedReverse", "doBuiltinMethodCached", "doBuiltinMethodCtCached", "callSelfMethodSingleContext", "callSelfMethod"}) + @Specialization(replaces = {"doBuiltinFunctionCached", "doBuiltinFunctionCtCached", + "doBuiltinMethodCached", "doBuiltinMethodCtCached", "callSelfMethodSingleContext", "callSelfMethod"}) @Megamorphic @InliningCutoff static Object call(VirtualFrame frame, Object func, Object arg1, Object arg2, Object arg3, diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallUnaryMethodNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallUnaryMethodNode.java index d7a5053b05..8c2934ce7e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallUnaryMethodNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallUnaryMethodNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,24 +40,13 @@ */ package com.oracle.graal.python.nodes.call.special; -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.BinaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.TernaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.UnaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetCallTargetNode; import com.oracle.graal.python.nodes.call.BoundDescriptor; import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.call.GenericInvokeNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.RootCallTarget; @@ -92,48 +81,6 @@ public final Object executeObject(Object callable, Object receiver) { return executeObject(null, callable, receiver); } - @Specialization(guards = {"cachedInfo == info", "node != null"}, limit = "getCallSiteInlineCacheMaxDepth()") - Object callUnarySpecialMethodSlotInlined(VirtualFrame frame, @SuppressWarnings("unused") UnaryBuiltinDescriptor info, Object receiver, - @SuppressWarnings("unused") @Cached("info") UnaryBuiltinDescriptor cachedInfo, - @Cached("getBuiltin(cachedInfo)") PythonUnaryBuiltinNode node) { - return node.execute(frame, receiver); - } - - protected static boolean hasAllowedArgsNum(BuiltinMethodDescriptor descr) { - return descr.minNumOfPositionalArgs() <= 1; - } - - @Specialization(guards = {"cachedInfo == info", "node != null"}, limit = "getCallSiteInlineCacheMaxDepth()") - Object callBinarySpecialMethodSlotInlined(VirtualFrame frame, @SuppressWarnings("unused") BinaryBuiltinDescriptor info, Object receiver, - @SuppressWarnings("unused") @Cached("info") BinaryBuiltinDescriptor cachedInfo, - @Cached("hasAllowedArgsNum(cachedInfo)") boolean hasValidArgsNum, - @Cached("getBuiltin(cachedInfo)") PythonBinaryBuiltinNode node) { - raiseInvalidArgsNumUncached(hasValidArgsNum, cachedInfo); - return node.execute(frame, receiver, PNone.NO_VALUE); - } - - @Specialization(guards = {"cachedInfo == info", "node != null"}, limit = "getCallSiteInlineCacheMaxDepth()") - Object callTernarySpecialMethodSlotInlined(VirtualFrame frame, @SuppressWarnings("unused") TernaryBuiltinDescriptor info, Object receiver, - @SuppressWarnings("unused") @Cached("info") TernaryBuiltinDescriptor cachedInfo, - @Cached("hasAllowedArgsNum(cachedInfo)") boolean hasValidArgsNum, - @Cached("getBuiltin(cachedInfo)") PythonTernaryBuiltinNode node) { - raiseInvalidArgsNumUncached(hasValidArgsNum, cachedInfo); - return node.execute(frame, receiver, PNone.NO_VALUE, PNone.NO_VALUE); - } - - @Specialization(guards = "isBuiltinDescriptor(info)", replaces = {"callUnarySpecialMethodSlotInlined", "callBinarySpecialMethodSlotInlined", "callTernarySpecialMethodSlotInlined"}) - @InliningCutoff - Object callSpecialMethodSlotCallTarget(VirtualFrame frame, BuiltinMethodDescriptor info, Object receiver, - @Bind("this") Node inliningTarget, - @Exclusive @Cached InlinedConditionProfile invalidArgsProfile, - @Cached GenericInvokeNode invokeNode) { - raiseInvalidArgsNumUncached(invalidArgsProfile.profile(inliningTarget, hasAllowedArgsNum(info)), info); - RootCallTarget callTarget = PythonLanguage.get(this).getDescriptorCallTarget(info); - Object[] arguments = PArguments.create(1); - PArguments.setArgument(arguments, 0, receiver); - return invokeNode.execute(frame, callTarget, arguments); - } - @Specialization(guards = {"isSingleContext()", "func == cachedFunc", "builtinNode != null"}, // limit = "getCallSiteInlineCacheMaxDepth()") Object callObjectSingle(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinFunction func, Object receiver, @@ -184,7 +131,7 @@ Object callSelfMethod(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinMe return callBinaryBuiltin(frame, builtinNode, func.getSelf(), arg); } - @Specialization(guards = "!isBuiltinDescriptor(func)", replaces = {"callObjectSingle", "callObject", "callMethodSingleContext", "callSelfMethodSingleContext", "callMethod", "callSelfMethod"}) + @Specialization(replaces = {"callObjectSingle", "callObject", "callMethodSingleContext", "callSelfMethodSingleContext", "callMethod", "callSelfMethod"}) @Megamorphic @InliningCutoff static Object call(VirtualFrame frame, Object func, Object receiver, diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallVarargsMethodNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallVarargsMethodNode.java deleted file mode 100644 index 47ee314679..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallVarargsMethodNode.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.call.special; - -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; -import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetCallTargetNode; -import com.oracle.graal.python.nodes.call.BoundDescriptor; -import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode.VarargsBuiltinDirectInvocationNotSupported; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.ReportPolymorphism.Megamorphic; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.Frame; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; - -@GenerateUncached -public abstract class CallVarargsMethodNode extends AbstractCallMethodNode { - - public abstract Object execute(Frame frame, Object callable, Object[] arguments, PKeyword[] keywords); - - @NeverDefault - public static CallVarargsMethodNode create() { - return CallVarargsMethodNodeGen.create(); - } - - public static CallVarargsMethodNode getUncached() { - return CallVarargsMethodNodeGen.getUncached(); - } - - @Specialization(guards = {"isSingleContext()", "func == cachedFunc", "builtinNode != null"}, // - limit = "getCallSiteInlineCacheMaxDepth()", // - rewriteOn = VarargsBuiltinDirectInvocationNotSupported.class) - static Object callVarargsDirect(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinFunction func, Object[] arguments, PKeyword[] keywords, - @Cached("func") @SuppressWarnings("unused") PBuiltinFunction cachedFunc, - @Cached("getVarargs(frame, func)") PythonVarargsBuiltinNode builtinNode) throws VarargsBuiltinDirectInvocationNotSupported { - return builtinNode.varArgExecute(frame, PNone.NO_VALUE, arguments, keywords); - } - - @Specialization(guards = {"func.getCallTarget() == ct", "builtinNode != null"}, limit = "getCallSiteInlineCacheMaxDepth()", rewriteOn = VarargsBuiltinDirectInvocationNotSupported.class) - static Object callVarargs(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinFunction func, Object[] arguments, PKeyword[] keywords, - @SuppressWarnings("unused") @Cached("func.getCallTarget()") RootCallTarget ct, - @Cached("getVarargs(frame, func)") PythonVarargsBuiltinNode builtinNode) throws VarargsBuiltinDirectInvocationNotSupported { - return builtinNode.varArgExecute(frame, PNone.NO_VALUE, arguments, keywords); - } - - @Specialization(guards = {"isSingleContext()", "func == cachedFunc", "builtinNode != null", - "takesSelfArg"}, rewriteOn = VarargsBuiltinDirectInvocationNotSupported.class, limit = "getCallSiteInlineCacheMaxDepth()") - static Object callSelfMethodSingleContext(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinMethod func, Object[] arguments, PKeyword[] keywords, - @SuppressWarnings("unused") @Cached(value = "func", weak = true) PBuiltinMethod cachedFunc, - @SuppressWarnings("unused") @Cached("takesSelfArg(func)") boolean takesSelfArg, - @Cached("getVarargs(frame, func.getBuiltinFunction())") PythonVarargsBuiltinNode builtinNode) { - return builtinNode.varArgExecute(frame, func.getSelf(), arguments, keywords); - } - - @Specialization(guards = {"builtinNode != null", "getCallTarget(func, getCt) == ct", "takesSelfArg"}, // - limit = "getCallSiteInlineCacheMaxDepth()", rewriteOn = VarargsBuiltinDirectInvocationNotSupported.class) - static Object callSelfMethod(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinMethod func, Object[] arguments, PKeyword[] keywords, - @SuppressWarnings("unused") @Shared @Cached GetCallTargetNode getCt, - @SuppressWarnings("unused") @Cached("getCallTarget(func, getCt)") RootCallTarget ct, - @SuppressWarnings("unused") @Cached("takesSelfArg(func)") boolean takesSelfArg, - @Cached("getVarargs(frame, func.getBuiltinFunction())") PythonVarargsBuiltinNode builtinNode) { - return builtinNode.varArgExecute(frame, func.getSelf(), arguments, keywords); - } - - @Specialization(guards = {"isSingleContext()", "func == cachedFunc", "builtinNode != null", - "!takesSelfArg"}, rewriteOn = VarargsBuiltinDirectInvocationNotSupported.class, limit = "getCallSiteInlineCacheMaxDepth()") - static Object callSelfMethodSingleContextNoSelf(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinMethod func, Object[] arguments, PKeyword[] keywords, - @SuppressWarnings("unused") @Cached("func") PBuiltinMethod cachedFunc, - @SuppressWarnings("unused") @Cached("takesSelfArg(func)") boolean takesSelfArg, - @Cached("getVarargs(frame, func.getBuiltinFunction())") PythonVarargsBuiltinNode builtinNode) { - return builtinNode.varArgExecute(frame, PNone.NO_VALUE, arguments, keywords); - } - - @Specialization(guards = {"builtinNode != null", "getCallTarget(func, getCt) == ct", "!takesSelfArg"}, // - rewriteOn = VarargsBuiltinDirectInvocationNotSupported.class, limit = "getCallSiteInlineCacheMaxDepth()") - static Object callSelfMethodNoSelf(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinMethod func, Object[] arguments, PKeyword[] keywords, - @SuppressWarnings("unused") @Shared @Cached GetCallTargetNode getCt, - @SuppressWarnings("unused") @Cached("getCallTarget(func, getCt)") RootCallTarget ct, - @SuppressWarnings("unused") @Cached("takesSelfArg(func)") boolean takesSelfArg, - @Cached("getVarargs(frame, func.getBuiltinFunction())") PythonVarargsBuiltinNode builtinNode) { - return builtinNode.varArgExecute(frame, PNone.NO_VALUE, arguments, keywords); - } - - @Specialization(guards = {"arguments.length == 1", "keywords.length == 0"}) - static Object callUnary(VirtualFrame frame, Object callable, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords, - @Cached CallUnaryMethodNode callUnaryMethodNode) { - return callUnaryMethodNode.executeObject(frame, callable, arguments[0]); - } - - @Specialization(guards = {"arguments.length == 2", "keywords.length == 0"}) - static Object callBinary(VirtualFrame frame, Object callable, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords, - @Cached CallBinaryMethodNode callBinaryMethodNode) { - return callBinaryMethodNode.executeObject(frame, callable, arguments[0], arguments[1]); - } - - @Specialization(guards = {"arguments.length == 3", "keywords.length == 0"}) - static Object callTernary(VirtualFrame frame, Object callable, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords, - @Cached CallTernaryMethodNode callTernaryMethodNode) { - return callTernaryMethodNode.execute(frame, callable, arguments[0], arguments[1], arguments[2]); - } - - @Specialization(guards = {"arguments.length == 4", "keywords.length == 0"}) - static Object callQuaternary(VirtualFrame frame, Object callable, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords, - @Cached CallQuaternaryMethodNode callQuaternaryMethodNode) { - return callQuaternaryMethodNode.execute(frame, callable, arguments[0], arguments[1], arguments[2], arguments[3]); - } - - @Specialization(replaces = {"callVarargsDirect", "callVarargs", "callSelfMethodSingleContext", "callSelfMethod", "callSelfMethodSingleContextNoSelf", "callSelfMethodNoSelf", "callUnary", - "callBinary", "callTernary", "callQuaternary"}) - @Megamorphic - @InliningCutoff - static Object call(VirtualFrame frame, Object func, Object[] arguments, PKeyword[] keywords, - @Bind("this") Node inliningTarget, - @Cached CallNode callNode, - @Cached InlinedConditionProfile isBoundProfile) { - if (isBoundProfile.profile(inliningTarget, func instanceof BoundDescriptor)) { - Object[] boundArguments = new Object[arguments.length - 1]; - PythonUtils.arraycopy(arguments, 1, boundArguments, 0, boundArguments.length); - return callNode.execute(frame, ((BoundDescriptor) func).descriptor, boundArguments, keywords); - } else { - return callNode.execute(frame, func, arguments, keywords); - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallBinaryNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallBinaryNode.java index 86761bac30..a6a30e33a3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallBinaryNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallBinaryNode.java @@ -40,174 +40,113 @@ */ package com.oracle.graal.python.nodes.call.special; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.nodes.PNodeWithContext; +import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; +import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.util.Supplier; import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.dsl.ReportPolymorphism.Megamorphic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; -// cpython://Objects/abstract.c#binary_op1 -// Order operations are tried until either a valid result or error: w.op(v,w)[*], v.op(v,w), w.op(v,w) -// -// [*] only when v->ob_type != w->ob_type && w->ob_type is a subclass of v->ob_type -// -// The (long, double) and (double, long) specializations are needed since long->double conversion -// is not always correct (it can lose information). See FloatBuiltins.EqNode.compareDoubleToLong(). -// The (int, double) and (double, int) specializations are needed to avoid int->long conversion. -// Although it would produce correct results, the special handling of long to double comparison -// is slower than converting int->double, which is always correct. +/** + * Helper node for what would be a sequence of {@code _PyObject_LookupSpecial} and + * {@code PyObject_CallXXXA}. Callers should handle exception {@link SpecialMethodNotFound}, which + * indicates that the method was not found. + */ @ImportStatic(PythonOptions.class) public abstract class LookupAndCallBinaryNode extends Node { - - public abstract static class NotImplementedHandler extends PNodeWithContext { - public abstract Object execute(VirtualFrame frame, Object arg, Object arg2); - } - - protected final Supplier handlerFactory; - protected final boolean ignoreDescriptorException; - @Child private CallBinaryMethodNode dispatchNode; - @Child private NotImplementedHandler handler; + protected final TruffleString name; - LookupAndCallBinaryNode(Supplier handlerFactory, boolean ignoreDescriptorException) { - this.handlerFactory = handlerFactory; - this.ignoreDescriptorException = ignoreDescriptorException; + LookupAndCallBinaryNode(TruffleString name) { + this.name = name; } - public abstract Object executeObject(VirtualFrame frame, Object arg, Object arg2); + public abstract Object executeObject(VirtualFrame frame, Object arg, Object arg2) throws SpecialMethodNotFound; @NeverDefault public static LookupAndCallBinaryNode create(TruffleString name) { - // Use SpecialMethodSlot overload for special slots, if there is a need to create - // LookupAndCallBinaryNode for dynamic name, then we should change this method or the caller - // to try to lookup a slot and use that if found - assert SpecialMethodSlot.findSpecialSlotUncached(name) == null : name; - return LookupAndCallNonReversibleBinaryNodeGen.create(name, null, false); + return LookupAndCallBinaryNodeGen.create(name); } - @NeverDefault - public static LookupAndCallBinaryNode create(SpecialMethodSlot slot) { - return LookupAndCallNonReversibleBinaryNodeGen.create(slot, null, false); + protected final CallBinaryMethodNode ensureDispatch() { + // this also serves as a branch profile + if (dispatchNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + dispatchNode = insert(CallBinaryMethodNode.create()); + } + return dispatchNode; } - @NeverDefault - public static LookupAndCallBinaryNode create(SpecialMethodSlot slot, Supplier handlerFactory) { - return LookupAndCallNonReversibleBinaryNodeGen.create(slot, handlerFactory, false); + protected final PythonBinaryBuiltinNode getBinaryBuiltin(PythonBuiltinClassType clazz) { + Object attribute = LookupAttributeInMRONode.Dynamic.getUncached().execute(clazz, name); + if (attribute instanceof PBuiltinFunction) { + PBuiltinFunction builtinFunction = (PBuiltinFunction) attribute; + if (PythonBinaryBuiltinNode.class.isAssignableFrom(builtinFunction.getBuiltinNodeFactory().getNodeClass())) { + return (PythonBinaryBuiltinNode) builtinFunction.getBuiltinNodeFactory().createNode(); + } + } + return null; } - @NeverDefault - public static LookupAndCallBinaryNode createReversible(SpecialMethodSlot slot, SpecialMethodSlot rslot, Supplier handlerFactory) { - return LookupAndCallReversibleBinaryNodeGen.create(slot, rslot, handlerFactory, false, false); + protected static PythonBuiltinClassType getBuiltinClass(Node inliningTarget, Object receiver, GetClassNode getClassNode) { + Object clazz = getClassNode.execute(inliningTarget, receiver); + return clazz instanceof PythonBuiltinClassType ? (PythonBuiltinClassType) clazz : null; } - @NeverDefault - public static LookupAndCallBinaryNode create(SpecialMethodSlot slot, SpecialMethodSlot rslot, boolean alwaysCheckReverse, boolean ignoreDescriptorException) { - return LookupAndCallReversibleBinaryNodeGen.create(slot, rslot, null, alwaysCheckReverse, ignoreDescriptorException); + protected static boolean isClazz(Node inliningTarget, PythonBuiltinClassType clazz, Object receiver, GetClassNode getClassNode) { + return getClassNode.execute(inliningTarget, receiver) == clazz; } - @ImportStatic(PGuards.class) - @GenerateInline - @GenerateCached(false) - protected abstract static class AreSameCallables extends Node { - public abstract boolean execute(Node inliningTarget, Object left, Object right); - - @Specialization(guards = "a == b") - static boolean areIdenticalFastPath(@SuppressWarnings("unused") Object a, @SuppressWarnings("unused") Object b) { - return true; - } - - @Specialization(guards = "isNone(a) || isNone(b)") - static boolean noneFastPath(@SuppressWarnings("unused") Object a, @SuppressWarnings("unused") Object b) { - return a == b; - } - - @Specialization(replaces = "areIdenticalFastPath") - static boolean doDescrs(BuiltinMethodDescriptor a, BuiltinMethodDescriptor b) { - return a == b; - } - - @Specialization(replaces = "areIdenticalFastPath") - static boolean doDescrFun1(BuiltinMethodDescriptor a, PBuiltinFunction b) { - return a.isDescriptorOf(b); - } + // Object, Object - @Specialization(replaces = "areIdenticalFastPath") - static boolean doDescrFun2(PBuiltinFunction a, BuiltinMethodDescriptor b) { - return b.isDescriptorOf(a); - } - - @Specialization(replaces = "areIdenticalFastPath") - static boolean doDescrMeth1(BuiltinMethodDescriptor a, PBuiltinMethod b) { - return doDescrFun1(a, b.getBuiltinFunction()); - } - - @Specialization(replaces = "areIdenticalFastPath") - static boolean doDescrMeth2(PBuiltinMethod a, BuiltinMethodDescriptor b) { - return doDescrFun2(a.getBuiltinFunction(), b); - } - - @Fallback - static boolean doGenericRuntimeObjects(Object a, Object b) { - return a == b; - } + @Specialization(guards = {"clazz != null", "function != null", "isClazz(inliningTarget, clazz, left, getClassNode)"}, limit = "getCallSiteInlineCacheMaxDepth()") + static Object callObjectBuiltin(VirtualFrame frame, Object left, Object right, + @SuppressWarnings("unused") @Bind("this") Node inliningTarget, + @SuppressWarnings("unused") @Exclusive @Cached GetClassNode getClassNode, + @SuppressWarnings("unused") @Cached("getBuiltinClass(this, left, getClassNode)") PythonBuiltinClassType clazz, + @Cached("getBinaryBuiltin(clazz)") PythonBinaryBuiltinNode function) { + return function.execute(frame, left, right); } - @ImportStatic(PGuards.class) - @GenerateInline - @GenerateCached(false) - protected abstract static class GetEnclosingType extends Node { - public abstract Object execute(Node inliningTarget, Object callable); - - @Specialization - static Object doDescrs(BuiltinMethodDescriptor descriptor) { - return descriptor.getEnclosingType(); - } - - @Specialization - static Object doBuiltinFun(PBuiltinFunction fun) { - return fun.getEnclosingType(); - } - - @Specialization - static Object doBuiltinMethod(PBuiltinMethod a) { - return doBuiltinFun(a.getBuiltinFunction()); - } - - @Fallback - static Object doOthers(@SuppressWarnings("unused") Object callable) { - return null; - } + @Specialization(guards = {"left.getClass() == cachedLeftClass", "right.getClass() == cachedRightClass"}, limit = "5") + @SuppressWarnings("truffle-static-method") + Object callObjectGeneric(VirtualFrame frame, Object left, Object right, + @Bind("this") Node inliningTarget, + @SuppressWarnings("unused") @Cached("left.getClass()") Class cachedLeftClass, + @SuppressWarnings("unused") @Cached("right.getClass()") Class cachedRightClass, + @Exclusive @Cached GetClassNode getClassNode, + @Exclusive @Cached("create(name)") LookupSpecialMethodNode getattr) { + return doCallObject(frame, inliningTarget, left, right, getClassNode, getattr); } - public abstract TruffleString getName(); - - protected final CallBinaryMethodNode ensureDispatch() { - // this also serves as a branch profile - if (dispatchNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - dispatchNode = insert(CallBinaryMethodNode.create()); - } - return dispatchNode; + @Specialization(replaces = "callObjectGeneric") + @Megamorphic + @SuppressWarnings("truffle-static-method") + Object callObjectMegamorphic(VirtualFrame frame, Object left, Object right, + @Bind("this") Node inliningTarget, + @Exclusive @Cached GetClassNode getClassNode, + @Exclusive @Cached("create(name)") LookupSpecialMethodNode getattr) { + return doCallObject(frame, inliningTarget, left, right, getClassNode, getattr); } - protected final Object runErrorHandler(VirtualFrame frame, Object left, Object right) { - if (handler == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - handler = insert(handlerFactory.get()); + private Object doCallObject(VirtualFrame frame, Node inliningTarget, Object left, Object right, GetClassNode getClassNode, LookupSpecialMethodNode getattr) { + Object leftClass = getClassNode.execute(inliningTarget, left); + Object leftCallable = getattr.execute(frame, leftClass, left); + if (PGuards.isNoValue(leftCallable)) { + throw SpecialMethodNotFound.INSTANCE; } - return handler.execute(frame, left, right); + return ensureDispatch().executeObject(frame, leftCallable, left, right); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallNonReversibleBinaryNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallNonReversibleBinaryNode.java deleted file mode 100644 index 50f55749fc..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallNonReversibleBinaryNode.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.call.special; - -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.BinaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.util.Supplier; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.ReportPolymorphism.Megamorphic; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.strings.TruffleString; - -@ImportStatic(PythonOptions.class) -abstract class LookupAndCallNonReversibleBinaryNode extends LookupAndCallBinaryNode { - protected final SpecialMethodSlot slot; - protected final TruffleString name; - - LookupAndCallNonReversibleBinaryNode(TruffleString name, Supplier handlerFactory, boolean ignoreDescriptorException) { - super(handlerFactory, ignoreDescriptorException); - this.name = name; - this.slot = null; - } - - LookupAndCallNonReversibleBinaryNode(SpecialMethodSlot slot, Supplier handlerFactory, boolean ignoreDescriptorException) { - super(handlerFactory, ignoreDescriptorException); - // If the slot is reversible, use LookupAndCallReversibleBinaryNode via factory in - // LookupAndCallBinaryNode - assert slot.getReverse() == null; - this.name = slot.getName(); - this.slot = slot; - } - - protected final PythonBinaryBuiltinNode getBinaryBuiltin(PythonBuiltinClassType clazz) { - if (slot != null) { - Object attribute = slot.getValue(clazz); - if (attribute instanceof BinaryBuiltinDescriptor) { - return ((BinaryBuiltinDescriptor) attribute).createNode(); - } - // If the slot does not contain builtin, full lookup wouldn't find a builtin either - return null; - } - Object attribute = LookupAttributeInMRONode.Dynamic.getUncached().execute(clazz, name); - if (attribute instanceof PBuiltinFunction) { - PBuiltinFunction builtinFunction = (PBuiltinFunction) attribute; - if (PythonBinaryBuiltinNode.class.isAssignableFrom(builtinFunction.getBuiltinNodeFactory().getNodeClass())) { - return (PythonBinaryBuiltinNode) builtinFunction.getBuiltinNodeFactory().createNode(); - } - } - return null; - } - - protected static PythonBuiltinClassType getBuiltinClass(Node inliningTarget, Object receiver, GetClassNode getClassNode) { - Object clazz = getClassNode.execute(inliningTarget, receiver); - return clazz instanceof PythonBuiltinClassType ? (PythonBuiltinClassType) clazz : null; - } - - protected static boolean isClazz(Node inliningTarget, PythonBuiltinClassType clazz, Object receiver, GetClassNode getClassNode) { - return getClassNode.execute(inliningTarget, receiver) == clazz; - } - - // Object, Object - - @Specialization(guards = {"clazz != null", "function != null", "isClazz(inliningTarget, clazz, left, getClassNode)"}, limit = "getCallSiteInlineCacheMaxDepth()") - static Object callObjectBuiltin(VirtualFrame frame, Object left, Object right, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached GetClassNode getClassNode, - @SuppressWarnings("unused") @Cached("getBuiltinClass(this, left, getClassNode)") PythonBuiltinClassType clazz, - @Cached("getBinaryBuiltin(clazz)") PythonBinaryBuiltinNode function) { - return function.execute(frame, left, right); - } - - @Specialization(guards = {"left.getClass() == cachedLeftClass", "right.getClass() == cachedRightClass"}, limit = "5") - @SuppressWarnings("truffle-static-method") - Object callObjectGeneric(VirtualFrame frame, Object left, Object right, - @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached("left.getClass()") Class cachedLeftClass, - @SuppressWarnings("unused") @Cached("right.getClass()") Class cachedRightClass, - @Exclusive @Cached GetClassNode getClassNode, - @Exclusive @Cached("createLookup()") LookupSpecialBaseNode getattr) { - return doCallObject(frame, inliningTarget, left, right, getClassNode, getattr); - } - - @Specialization(replaces = "callObjectGeneric") - @Megamorphic - @SuppressWarnings("truffle-static-method") - Object callObjectMegamorphic(VirtualFrame frame, Object left, Object right, - @Bind("this") Node inliningTarget, - @Exclusive @Cached GetClassNode getClassNode, - @Exclusive @Cached("createLookup()") LookupSpecialBaseNode getattr) { - return doCallObject(frame, inliningTarget, left, right, getClassNode, getattr); - } - - private Object doCallObject(VirtualFrame frame, Node inliningTarget, Object left, Object right, GetClassNode getClassNode, LookupSpecialBaseNode getattr) { - Object leftClass = getClassNode.execute(inliningTarget, left); - Object leftCallable; - try { - leftCallable = getattr.execute(frame, leftClass, left); - } catch (PException e) { - if (ignoreDescriptorException) { - leftCallable = PNone.NO_VALUE; - } else { - throw e; - } - } - if (leftCallable == PNone.NO_VALUE) { - if (handlerFactory != null) { - return runErrorHandler(frame, left, right); - } else { - return PNotImplemented.NOT_IMPLEMENTED; - } - } - return ensureDispatch().executeObject(frame, leftCallable, left, right); - } - - @NeverDefault - protected final LookupSpecialBaseNode createLookup() { - if (slot != null) { - return LookupSpecialMethodSlotNode.create(slot); - } - return LookupSpecialMethodNode.create(name); - } - - @Override - public final TruffleString getName() { - return name; - } - -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallNonReversibleTernaryNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallNonReversibleTernaryNode.java deleted file mode 100644 index e6b0a0413f..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallNonReversibleTernaryNode.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.call.special; - -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.TernaryBuiltinDescriptor; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.nodes.SpecialMethodNames; -import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; -import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.ReportPolymorphism.Megamorphic; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.strings.TruffleString; - -// cpython://Objects/abstract.c#ternary_op -// Order operations are tried until either a valid result or error: v.op(v,w,z), w.op(v,w,z), z.op(v,w,z) -@ImportStatic({SpecialMethodNames.class, PythonOptions.class}) -public abstract class LookupAndCallNonReversibleTernaryNode extends LookupAndCallTernaryNode { - - LookupAndCallNonReversibleTernaryNode(TruffleString name) { - super(name); - } - - LookupAndCallNonReversibleTernaryNode(SpecialMethodSlot slot) { - super(slot); - } - - protected static PythonBuiltinClassType getBuiltinClass(Node inliningTarget, Object receiver, GetClassNode getClassNode) { - Object clazz = getClassNode.execute(inliningTarget, receiver); - return clazz instanceof PythonBuiltinClassType ? (PythonBuiltinClassType) clazz : null; - } - - protected static boolean isClazz(Node inliningTarget, PythonBuiltinClassType clazz, Object receiver, GetClassNode getClassNode) { - return getClassNode.execute(inliningTarget, receiver) == clazz; - } - - protected final PythonTernaryBuiltinNode getTernaryBuiltin(PythonBuiltinClassType clazz) { - if (slot != null) { - Object attribute = slot.getValue(clazz); - if (attribute instanceof TernaryBuiltinDescriptor) { - return ((TernaryBuiltinDescriptor) attribute).createNode(); - } - // If the slot does not contain builtin, full lookup wouldn't find a builtin either - return null; - } - Object attribute = LookupAttributeInMRONode.Dynamic.getUncached().execute(clazz, name); - if (attribute instanceof PBuiltinFunction) { - PBuiltinFunction builtinFunction = (PBuiltinFunction) attribute; - if (PythonTernaryBuiltinNode.class.isAssignableFrom(builtinFunction.getBuiltinNodeFactory().getNodeClass())) { - return (PythonTernaryBuiltinNode) builtinFunction.getBuiltinNodeFactory().createNode(); - } - } - return null; - } - - @Specialization(guards = {"clazz != null", "function != null", "isClazz(inliningTarget, clazz, v, getClassNode)"}, limit = "getCallSiteInlineCacheMaxDepth()") - static Object callObjectBuiltin(VirtualFrame frame, Object v, Object w, Object z, - @SuppressWarnings("unused") @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached GetClassNode getClassNode, - @SuppressWarnings("unused") @Cached("getBuiltinClass(this, v, getClassNode)") PythonBuiltinClassType clazz, - @Cached("getTernaryBuiltin(clazz)") PythonTernaryBuiltinNode function) { - return function.execute(frame, v, w, z); - } - - @Specialization(guards = "arg1.getClass() == cachedArg1Class", limit = "getCallSiteInlineCacheMaxDepth()") - static Object callObject(VirtualFrame frame, Object arg1, Object arg2, Object arg3, - @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached("arg1.getClass()") Class cachedArg1Class, - @Exclusive @Cached GetClassNode getClassNode, - @Exclusive @Cached("createLookup()") LookupSpecialBaseNode getattr, - @Exclusive @Cached CallTernaryMethodNode dispatchNode) { - Object klass = getClassNode.execute(inliningTarget, arg1); - return dispatchNode.execute(frame, getattr.execute(frame, klass, arg1), arg1, arg2, arg3); - } - - @Specialization(replaces = "callObject") - @Megamorphic - static Object callObjectMegamorphic(VirtualFrame frame, Object arg1, Object arg2, Object arg3, - @Bind("this") Node inliningTarget, - @Exclusive @Cached GetClassNode getClassNode, - @Exclusive @Cached("createLookup()") LookupSpecialBaseNode getattr, - @Exclusive @Cached CallTernaryMethodNode dispatchNode) { - Object klass = getClassNode.execute(inliningTarget, arg1); - return dispatchNode.execute(frame, getattr.execute(frame, klass, arg1), arg1, arg2, arg3); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallReversibleBinaryNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallReversibleBinaryNode.java deleted file mode 100644 index 81d18936e9..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallReversibleBinaryNode.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.call.special; - -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; - -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.classes.IsSubtypeNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.util.Supplier; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.ReportPolymorphism.Megamorphic; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedBranchProfile; -import com.oracle.truffle.api.profiles.InlinedConditionProfile; -import com.oracle.truffle.api.strings.TruffleString; - -// cpython://Objects/abstract.c#binary_op1 -// Order operations are tried until either a valid result or error: w.op(v,w)[*], v.op(v,w), w.op(v,w) -// -// [*] only when v->ob_type != w->ob_type && w->ob_type is a subclass of v->ob_type -@ImportStatic(PythonOptions.class) -abstract class LookupAndCallReversibleBinaryNode extends LookupAndCallBinaryNode { - - protected final SpecialMethodSlot slot; - protected final SpecialMethodSlot rslot; - private final boolean alwaysCheckReverse; - - @Child private PRaiseNode raiseNode; - @Child private GetNameNode getNameNode; - @Child private CallBinaryMethodNode reverseDispatchNode; - - LookupAndCallReversibleBinaryNode(SpecialMethodSlot slot, SpecialMethodSlot rslot, Supplier handlerFactory, boolean alwaysCheckReverse, boolean ignoreDescriptorException) { - super(handlerFactory, ignoreDescriptorException); - assert slot != null; - assert rslot != null; - this.slot = slot; - this.rslot = rslot; - this.alwaysCheckReverse = alwaysCheckReverse; - } - - private PRaiseNode ensureRaiseNode() { - if (raiseNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - raiseNode = insert(PRaiseNode.create()); - } - return raiseNode; - } - - private GetNameNode ensureGetNameNode() { - if (getNameNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - getNameNode = insert(GetNameNode.create()); - } - return getNameNode; - } - - private CallBinaryMethodNode ensureReverseDispatch() { - // this also serves as a branch profile - if (reverseDispatchNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - reverseDispatchNode = insert(CallBinaryMethodNode.create()); - } - return reverseDispatchNode; - } - - @Specialization(guards = {"left.getClass() == cachedLeftClass", "right.getClass() == cachedRightClass"}, limit = "5") - @SuppressWarnings("truffle-static-method") - Object callObjectGenericR(VirtualFrame frame, Object left, Object right, - @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached("left.getClass()") Class cachedLeftClass, - @SuppressWarnings("unused") @Cached("right.getClass()") Class cachedRightClass, - @Exclusive @Cached("create(slot)") LookupSpecialMethodSlotNode getattr, - @Exclusive @Cached("create(rslot)") LookupSpecialMethodSlotNode getattrR, - @Exclusive @Cached GetClassNode getLeftClassNode, - @Exclusive @Cached GetClassNode getRightClassNode, - @Exclusive @Cached IsSameTypeNode isSameTypeNode, - @Exclusive @Cached IsSubtypeNode isSubtype, - @Exclusive @Cached InlinedConditionProfile hasLeftCallable, - @Exclusive @Cached InlinedConditionProfile hasRightCallable, - @Exclusive @Cached InlinedConditionProfile notImplementedProfile, - @Exclusive @Cached InlinedBranchProfile noLeftBuiltinClassType, - @Exclusive @Cached InlinedBranchProfile noRightBuiltinClassType, - @Exclusive @Cached InlinedBranchProfile gotResultBranch, - @Exclusive @Cached AreSameCallables areSameCallables, - @Exclusive @Cached GetEnclosingType getEnclosingType) { - return doCallObjectR(frame, inliningTarget, left, right, getattr, getattrR, getLeftClassNode, getRightClassNode, isSameTypeNode, isSubtype, hasLeftCallable, hasRightCallable, - notImplementedProfile, noLeftBuiltinClassType, noRightBuiltinClassType, gotResultBranch, areSameCallables, getEnclosingType); - } - - @Specialization(replaces = "callObjectGenericR") - @Megamorphic - @SuppressWarnings("truffle-static-method") - Object callObjectRMegamorphic(VirtualFrame frame, Object left, Object right, - @Bind("this") Node inliningTarget, - @Exclusive @Cached("create(slot)") LookupSpecialMethodSlotNode getattr, - @Exclusive @Cached("create(rslot)") LookupSpecialMethodSlotNode getattrR, - @Exclusive @Cached GetClassNode getLeftClassNode, - @Exclusive @Cached GetClassNode getRightClassNode, - @Exclusive @Cached IsSameTypeNode isSameTypeNode, - @Exclusive @Cached IsSubtypeNode isSubtype, - @Exclusive @Cached InlinedConditionProfile hasLeftCallable, - @Exclusive @Cached InlinedConditionProfile hasRightCallable, - @Exclusive @Cached InlinedConditionProfile notImplementedProfile, - @Exclusive @Cached InlinedBranchProfile noLeftBuiltinClassType, - @Exclusive @Cached InlinedBranchProfile noRightBuiltinClassType, - @Exclusive @Cached InlinedBranchProfile gotResultBranch, - @Exclusive @Cached AreSameCallables areSameCallables, - @Exclusive @Cached GetEnclosingType getEnclosingType) { - return doCallObjectR(frame, inliningTarget, left, right, getattr, getattrR, getLeftClassNode, getRightClassNode, isSameTypeNode, isSubtype, hasLeftCallable, hasRightCallable, - notImplementedProfile, noLeftBuiltinClassType, noRightBuiltinClassType, gotResultBranch, areSameCallables, getEnclosingType); - } - - private Object doCallObjectR(VirtualFrame frame, Node inliningTarget, Object left, Object right, LookupSpecialMethodSlotNode getattr, LookupSpecialMethodSlotNode getattrR, - GetClassNode getLeftClassNode, GetClassNode getRightClassNode, IsSameTypeNode isSameTypeNode, IsSubtypeNode isSubtype, - InlinedConditionProfile hasLeftCallable, InlinedConditionProfile hasRightCallable, InlinedConditionProfile notImplementedProfile, InlinedBranchProfile noLeftBuiltinClassType, - InlinedBranchProfile noRightBuiltinClassType, InlinedBranchProfile gotResultBranch, AreSameCallables areSameCallables, GetEnclosingType getEnclosingType) { - // This specialization implements the logic from cpython://Objects/abstract.c#binary_op1 - // (the structure is modelled closely on it), as well as the additional logic in - // cpython://Objects/typeobject.c#SLOT1BINFULL. The latter has the addition that it swaps - // the arguments around. The swapping of arguments is undone when the call ends up in a - // builtin function using a wrapper in CPython. We implement this reversal in our - // BuiltinFunctionRootNode. This is opposite to what CPython does (and more in line with - // what PyPy does), in that CPython always dispatches with the same argument order and has - // slot wrappers for heap types __r*__ methods to swap the arguments, but we don't wrap heap - // types' methods and instead have our swapping for the builtin types. - - Object result = PNotImplemented.NOT_IMPLEMENTED; - Object leftClass = getLeftClassNode.execute(inliningTarget, left); - Object leftCallable; - try { - leftCallable = getattr.execute(frame, leftClass, left); - } catch (PException e) { - if (ignoreDescriptorException) { - leftCallable = PNone.NO_VALUE; - } else { - throw e; - } - } - Object rightClass = getRightClassNode.execute(inliningTarget, right); - Object rightCallable; - try { - rightCallable = getattrR.execute(frame, rightClass, right); - } catch (PException e) { - if (ignoreDescriptorException) { - rightCallable = PNone.NO_VALUE; - } else { - throw e; - } - } - - if (!alwaysCheckReverse && areSameCallables.execute(inliningTarget, leftCallable, rightCallable)) { - rightCallable = PNone.NO_VALUE; - } - - if (hasLeftCallable.profile(inliningTarget, leftCallable != PNone.NO_VALUE)) { - if (hasRightCallable.profile(inliningTarget, rightCallable != PNone.NO_VALUE) && - (!isSameTypeNode.execute(inliningTarget, leftClass, rightClass) && isSubtype.execute(frame, rightClass, leftClass) || - isFlagSequenceCompat(inliningTarget, leftClass, rightClass, slot, noLeftBuiltinClassType, noRightBuiltinClassType))) { - result = dispatch(frame, inliningTarget, ensureReverseDispatch(), rightCallable, right, left, rightClass, rslot, isSubtype, getEnclosingType); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - gotResultBranch.enter(inliningTarget); - rightCallable = PNone.NO_VALUE; - } - result = dispatch(frame, inliningTarget, ensureDispatch(), leftCallable, left, right, leftClass, slot, isSubtype, getEnclosingType); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - gotResultBranch.enter(inliningTarget); - } - if (notImplementedProfile.profile(inliningTarget, rightCallable != PNone.NO_VALUE)) { - result = dispatch(frame, inliningTarget, ensureReverseDispatch(), rightCallable, right, left, rightClass, rslot, isSubtype, getEnclosingType); - } - if (handlerFactory != null && result == PNotImplemented.NOT_IMPLEMENTED) { - return runErrorHandler(frame, left, right); - } - return result; - } - - private Object dispatch(VirtualFrame frame, Node inliningTarget, CallBinaryMethodNode dispatch, Object callable, Object leftValue, - Object rightValue, Object leftClass, SpecialMethodSlot op, IsSubtypeNode isSubtype, GetEnclosingType getEnclosingType) { - // see descrobject.c/wrapperdescr_call() - Object enclosing = getEnclosingType.execute(inliningTarget, callable); - if (enclosing != null && !isSubtype.execute(leftClass, enclosing)) { - throw ensureRaiseNode().raise(TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, op.getName(), ensureGetNameNode().executeCached(leftClass), leftValue); - } - return dispatch.executeObject(frame, callable, leftValue, rightValue); - } - - @SuppressWarnings("unused") - private static boolean isFlagSequenceCompat(Node inliningTarget, Object leftClass, Object rightClass, SpecialMethodSlot slot, InlinedBranchProfile gotLeftBuiltinClassType, - InlinedBranchProfile gotRightBuiltinClassType) { - return false; - // Mul slot was converted to CPython like slots, this flag should never apply here - /*- - if (PGuards.isNativeClass(leftClass) || PGuards.isNativeClass(rightClass)) { - return false; - } - // see pypy descroperation.py#_make_binop_impl() - boolean isSeqBugCompatOperation = (slot == SpecialMethodSlot.Mul); - return isSeqBugCompatOperation && isFlagSequenceBugCompat(inliningTarget, leftClass, gotLeftBuiltinClassType) && !isFlagSequenceBugCompat(inliningTarget, rightClass, gotRightBuiltinClassType); - */ - } - - private static boolean isFlagSequenceBugCompat(Node inliningTarget, Object clazz, InlinedBranchProfile gotBuiltinClassType) { - PythonBuiltinClassType type = null; - if (clazz instanceof PythonBuiltinClassType) { - type = (PythonBuiltinClassType) clazz; - } else if (clazz instanceof PythonBuiltinClass) { - type = ((PythonBuiltinClass) clazz).getType(); - } else { - return false; - } - gotBuiltinClassType.enter(inliningTarget); - return type == PythonBuiltinClassType.PString || - type == PythonBuiltinClassType.PByteArray || - type == PythonBuiltinClassType.PBytes || - type == PythonBuiltinClassType.PList || - type == PythonBuiltinClassType.PTuple; - } - - @Override - public TruffleString getName() { - return slot.getName(); - } - -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallReversibleTernaryNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallReversibleTernaryNode.java deleted file mode 100644 index 9bf7623ace..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallReversibleTernaryNode.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.call.special; - -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; -import com.oracle.graal.python.nodes.SpecialMethodNames; -import com.oracle.graal.python.nodes.classes.IsSubtypeNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.util.Supplier; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.ReportPolymorphism.Megamorphic; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.InlinedBranchProfile; -import com.oracle.truffle.api.strings.TruffleString; - -@ImportStatic({SpecialMethodNames.class, PythonOptions.class}) -public abstract class LookupAndCallReversibleTernaryNode extends LookupAndCallTernaryNode { - - @Child private CallTernaryMethodNode reverseDispatchNode; - @Child private CallTernaryMethodNode thirdDispatchNode; - @Child protected LookupSpecialMethodNode getThirdAttrNode; - - @Child protected NotImplementedHandler handler; - protected final Supplier handlerFactory; - - LookupAndCallReversibleTernaryNode(TruffleString name, Supplier handlerFactory) { - super(name); - this.handlerFactory = handlerFactory; - } - - public LookupAndCallReversibleTernaryNode(SpecialMethodSlot slot, Supplier handlerFactory) { - super(slot); - this.handlerFactory = handlerFactory; - } - - @Specialization(guards = "v.getClass() == cachedVClass", limit = "getCallSiteInlineCacheMaxDepth()") - @SuppressWarnings("truffle-static-method") - Object callObjectR(VirtualFrame frame, Object v, Object w, Object z, - @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Cached("v.getClass()") Class cachedVClass, - @Exclusive @Cached("createLookup()") LookupSpecialBaseNode getattr, - @Exclusive @Cached("createLookup()") LookupSpecialBaseNode getattrR, - @Exclusive @Cached GetClassNode getClass, - @Exclusive @Cached GetClassNode getClassR, - @Exclusive @Cached GetClassNode getThirdClass, - @Exclusive @Cached IsSubtypeNode isSubtype, - @Exclusive @Cached IsSameTypeNode isSameTypeNode, - @Exclusive @Cached InlinedBranchProfile notImplementedBranch, - @Exclusive @Cached CallTernaryMethodNode dispatchNode) { - return doCallObjectR(frame, inliningTarget, v, w, z, getattr, getattrR, getClass, getClassR, getThirdClass, isSubtype, isSameTypeNode, notImplementedBranch, dispatchNode); - } - - @Specialization(replaces = "callObjectR") - @Megamorphic - @SuppressWarnings("truffle-static-method") - Object callObjectRMegamorphic(VirtualFrame frame, Object v, Object w, Object z, - @Bind("this") Node inliningTarget, - @Exclusive @Cached("createLookup()") LookupSpecialBaseNode getattr, - @Exclusive @Cached("createLookup()") LookupSpecialBaseNode getattrR, - @Exclusive @Cached GetClassNode getClass, - @Exclusive @Cached GetClassNode getClassR, - @Exclusive @Cached GetClassNode getThirdClass, - @Exclusive @Cached IsSubtypeNode isSubtype, - @Exclusive @Cached IsSameTypeNode isSameTypeNode, - @Exclusive @Cached InlinedBranchProfile notImplementedBranch, - @Exclusive @Cached CallTernaryMethodNode dispatchNode) { - return doCallObjectR(frame, inliningTarget, v, w, z, getattr, getattrR, getClass, getClassR, getThirdClass, isSubtype, isSameTypeNode, notImplementedBranch, dispatchNode); - } - - private Object doCallObjectR(VirtualFrame frame, Node inliningTarget, Object v, Object w, Object z, LookupSpecialBaseNode getattr, - LookupSpecialBaseNode getattrR, GetClassNode getClass, GetClassNode getClassR, GetClassNode getThirdClass, - IsSubtypeNode isSubtype, IsSameTypeNode isSameTypeNode, InlinedBranchProfile notImplementedBranch, - CallTernaryMethodNode dispatchNode) { - // c.f. mostly slot_nb_power and wrap_ternaryfunc_r. like - // cpython://Object/abstract.c#ternary_op we try all three combinations, and the structure - // of this method is modeled after this. However, this method also merges the logic from - // slot_nb_power/wrap_ternaryfunc_r in that it swaps arguments around. The reversal is - // undone for builtin functions in BuiltinFunctionRootNode, just like it would be undone in - // CPython using its slot wrappers - Object leftClass = getClass.execute(inliningTarget, v); - Object rightClass = getClassR.execute(inliningTarget, w); - - Object result = PNotImplemented.NOT_IMPLEMENTED; - Object leftCallable = getattr.execute(frame, leftClass, v); - Object rightCallable = PNone.NO_VALUE; - - if (!isSameTypeNode.execute(inliningTarget, leftClass, rightClass)) { - rightCallable = getattrR.execute(frame, rightClass, w); - if (rightCallable == leftCallable) { - rightCallable = PNone.NO_VALUE; - } - } - if (leftCallable != PNone.NO_VALUE) { - if (rightCallable != PNone.NO_VALUE && isSubtype.execute(frame, rightClass, leftClass)) { - result = ensureReverseDispatch().execute(frame, rightCallable, v, w, z); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - rightCallable = PNone.NO_VALUE; - } - result = dispatchNode.execute(frame, leftCallable, v, w, z); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - } - if (rightCallable != PNone.NO_VALUE) { - result = ensureReverseDispatch().execute(frame, rightCallable, v, w, z); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - } - - Object zCallable = ensureGetAttrZ().execute(frame, getThirdClass.execute(inliningTarget, z), z); - if (zCallable != PNone.NO_VALUE && zCallable != leftCallable && zCallable != rightCallable) { - result = ensureThirdDispatch().execute(frame, zCallable, v, w, z); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - } - - notImplementedBranch.enter(inliningTarget); - if (handlerFactory != null) { - if (handler == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - handler = insert(handlerFactory.get()); - } - return handler.execute(v, w, z); - } - return result; - } - - protected CallTernaryMethodNode ensureReverseDispatch() { - // this also serves as a branch profile - if (reverseDispatchNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - reverseDispatchNode = insert(CallTernaryMethodNode.create()); - } - return reverseDispatchNode; - } - - protected CallTernaryMethodNode ensureThirdDispatch() { - // this also serves as a branch profile - if (thirdDispatchNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - thirdDispatchNode = insert(CallTernaryMethodNode.create()); - } - return thirdDispatchNode; - } - - protected LookupSpecialMethodNode ensureGetAttrZ() { - // this also serves as a branch profile - if (getThirdAttrNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - getThirdAttrNode = insert(LookupSpecialMethodNode.create(name)); - } - return getThirdAttrNode; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallTernaryNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallTernaryNode.java deleted file mode 100644 index 07ca21e71c..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallTernaryNode.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.call.special; - -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.SpecialMethodNames; -import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.util.Supplier; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.strings.TruffleString; - -// actual implementation is in the subclasses: one for reversible, other for non-reversible. -@ImportStatic({SpecialMethodNames.class, PythonOptions.class}) -public abstract class LookupAndCallTernaryNode extends Node { - public abstract static class NotImplementedHandler extends PNodeWithContext { - public abstract Object execute(Object arg, Object arg2, Object arg3); - } - - protected final TruffleString name; - protected final SpecialMethodSlot slot; - - public abstract Object execute(VirtualFrame frame, Object arg1, Object arg2, Object arg3); - - @NeverDefault - public static LookupAndCallTernaryNode create(TruffleString name) { - // Use SpecialMethodSlot overload for special slots, if there is a need to create - // LookupAndCallBinaryNode for dynamic name, then we should change this method or the caller - // to try to lookup a slot and use that if found - assert SpecialMethodSlot.findSpecialSlotUncached(name) == null : name; - return LookupAndCallNonReversibleTernaryNodeGen.create(name); - } - - @NeverDefault - public static LookupAndCallTernaryNode create(SpecialMethodSlot slot) { - return LookupAndCallNonReversibleTernaryNodeGen.create(slot); - } - - @NeverDefault - public static LookupAndCallTernaryNode createReversible(TruffleString name, Supplier handlerFactory) { - return LookupAndCallReversibleTernaryNodeGen.create(name, handlerFactory); - } - - @NeverDefault - public static LookupAndCallTernaryNode createReversible(SpecialMethodSlot slot, Supplier handlerFactory) { - return LookupAndCallReversibleTernaryNodeGen.create(slot, handlerFactory); - } - - LookupAndCallTernaryNode(TruffleString name) { - this.name = name; - this.slot = null; - } - - LookupAndCallTernaryNode(SpecialMethodSlot slot) { - this.slot = slot; - this.name = slot.getName(); - } - - @NeverDefault - protected final LookupSpecialBaseNode createLookup() { - if (slot != null) { - return LookupSpecialMethodSlotNode.create(slot); - } - return LookupSpecialMethodNode.create(name); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallUnaryNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallUnaryNode.java index 6b0549a2b0..c4ec60d959 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallUnaryNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallUnaryNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,11 +42,10 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.UnaryBuiltinDescriptor; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; +import com.oracle.graal.python.nodes.expression.UnaryOpNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.PythonOptions; @@ -66,27 +65,26 @@ import com.oracle.truffle.api.strings.TruffleString; @ImportStatic(PythonOptions.class) -public abstract class LookupAndCallUnaryNode extends Node { +public abstract class LookupAndCallUnaryNode extends UnaryOpNode { public abstract static class NoAttributeHandler extends PNodeWithContext { public abstract Object execute(Object receiver); } protected final TruffleString name; - private final SpecialMethodSlot slot; protected final Supplier handlerFactory; @Child private NoAttributeHandler handler; public abstract Object executeObject(VirtualFrame frame, Object receiver); - @NeverDefault - public static LookupAndCallUnaryNode create(TruffleString name) { - return LookupAndCallUnaryNodeGen.create(name, null); + @Override + public Object execute(VirtualFrame frame, Object receiver) { + return executeObject(frame, receiver); } @NeverDefault - public static LookupAndCallUnaryNode create(SpecialMethodSlot slot) { - return LookupAndCallUnaryNodeGen.create(slot, null); + public static LookupAndCallUnaryNode create(TruffleString name) { + return LookupAndCallUnaryNodeGen.create(name, null); } @NeverDefault @@ -94,19 +92,7 @@ public static LookupAndCallUnaryNode create(TruffleString name, Supplier handlerFactory) { - return LookupAndCallUnaryNodeGen.create(slot, handlerFactory); - } - - LookupAndCallUnaryNode(SpecialMethodSlot slot, Supplier handlerFactory) { - this.slot = slot; - this.name = slot.getName(); - this.handlerFactory = handlerFactory; - } - LookupAndCallUnaryNode(TruffleString name, Supplier handlerFactory) { - this.slot = null; this.name = name; this.handlerFactory = handlerFactory; } @@ -116,14 +102,6 @@ public TruffleString getMethodName() { } protected final PythonUnaryBuiltinNode getUnaryBuiltin(PythonBuiltinClassType clazz) { - if (slot != null) { - Object attribute = slot.getValue(clazz); - if (attribute instanceof UnaryBuiltinDescriptor) { - return ((UnaryBuiltinDescriptor) attribute).createNode(); - } - // If the slot does not contain builtin, full lookup wouldn't find a builtin either - return null; - } Object attribute = LookupAttributeInMRONode.Dynamic.getUncached().execute(clazz, name); if (attribute instanceof PBuiltinFunction) { PBuiltinFunction builtinFunction = (PBuiltinFunction) attribute; @@ -159,7 +137,7 @@ Object callObjectGeneric(VirtualFrame frame, Object receiver, @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Cached("receiver.getClass()") Class cachedClass, @Shared @Cached GetClassNode getClassNode, - @Shared @Cached("createLookup()") LookupSpecialBaseNode getattr, + @Shared @Cached("create(name)") LookupSpecialMethodNode getattr, @Shared @Cached CallUnaryMethodNode dispatchNode) { return doCallObject(frame, inliningTarget, receiver, getClassNode, getattr, dispatchNode); } @@ -170,7 +148,7 @@ Object callObjectGeneric(VirtualFrame frame, Object receiver, Object callObjectMegamorphic(VirtualFrame frame, Object receiver, @Bind("this") Node inliningTarget, @Shared @Cached GetClassNode getClassNode, - @Shared @Cached("createLookup()") LookupSpecialBaseNode getattr, + @Shared @Cached("create(name)") LookupSpecialMethodNode getattr, @Shared @Cached CallUnaryMethodNode dispatchNode) { return doCallObject(frame, inliningTarget, receiver, getClassNode, getattr, dispatchNode); } @@ -179,7 +157,7 @@ protected Class getObjectClass(Object object) { return object.getClass(); } - private Object doCallObject(VirtualFrame frame, Node inliningTarget, Object receiver, GetClassNode getClassNode, LookupSpecialBaseNode getattr, CallUnaryMethodNode dispatchNode) { + private Object doCallObject(VirtualFrame frame, Node inliningTarget, Object receiver, GetClassNode getClassNode, LookupSpecialMethodNode getattr, CallUnaryMethodNode dispatchNode) { Object attr = getattr.execute(frame, getClassNode.execute(inliningTarget, receiver), receiver); if (attr == PNone.NO_VALUE) { if (handlerFactory != null) { @@ -195,14 +173,6 @@ private Object doCallObject(VirtualFrame frame, Node inliningTarget, Object rece } } - @NeverDefault - protected final LookupSpecialBaseNode createLookup() { - if (slot != null) { - return LookupSpecialMethodSlotNode.create(slot); - } - return LookupSpecialMethodNode.create(name); - } - @GenerateUncached @SuppressWarnings("truffle-inlining") // footprint reduction 36 -> 20 public abstract static class LookupAndCallUnaryDynamicNode extends PNodeWithContext { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupSpecialMethodNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupSpecialMethodNode.java index 630cc12d43..130c97d3af 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupSpecialMethodNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupSpecialMethodNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,6 +40,7 @@ */ package com.oracle.graal.python.nodes.call.special; +import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -60,13 +61,15 @@ * differentiate it from the unbound case. {@link CallUnaryMethodNode} and other method calling * nodes handle this wrapper. */ -public abstract class LookupSpecialMethodNode extends LookupSpecialBaseNode { +public abstract class LookupSpecialMethodNode extends PNodeWithContext { protected final TruffleString name; public LookupSpecialMethodNode(TruffleString name) { this.name = name; } + public abstract Object execute(Frame frame, Object type, Object receiver); + @NeverDefault public static LookupSpecialMethodNode create(TruffleString name) { return LookupSpecialMethodNodeGen.create(name); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupSpecialMethodSlotNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupSpecialMethodSlotNode.java deleted file mode 100644 index 3e3c6bd5ba..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupSpecialMethodSlotNode.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.call.special; - -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.Frame; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; - -/** - * The same as {@link LookupSpecialMethodNode}, but this searches the special slots first. On top of - * the possible types of return values of {@link LookupSpecialMethodNode}, this node may also return - * {@link BuiltinMethodDescriptor}, which all the {@link CallBinaryMethodNode} and similar should - * handle as well. - */ -public abstract class LookupSpecialMethodSlotNode extends LookupSpecialBaseNode { - protected abstract static class CachedLookup extends LookupSpecialMethodSlotNode { - protected final SpecialMethodSlot slot; - - public CachedLookup(SpecialMethodSlot slot) { - this.slot = slot; - } - - @Specialization - Object lookup(VirtualFrame frame, Object type, Object receiver, - @Bind("this") Node inliningTarget, - @Cached(parameters = "slot") LookupCallableSlotInMRONode lookupSlot, - @Cached MaybeBindDescriptorNode bind) { - return bind.execute(frame, inliningTarget, lookupSlot.execute(type), receiver, type); - } - } - - @NeverDefault - public static LookupSpecialMethodSlotNode create(SpecialMethodSlot slot) { - return LookupSpecialMethodSlotNodeFactory.CachedLookupNodeGen.create(slot); - } - - private static final class UncachedLookup extends LookupSpecialMethodSlotNode { - protected final LookupCallableSlotInMRONode lookup; - - public UncachedLookup(SpecialMethodSlot slot) { - this.lookup = LookupCallableSlotInMRONode.getUncached(slot); - } - - @Override - public Object execute(Frame frame, Object type, Object receiver) { - return executeImpl(type, receiver); - } - - @TruffleBoundary - private Object executeImpl(Object type, Object receiver) { - return MaybeBindDescriptorNode.executeUncached(null, lookup.execute(type), receiver, type); - } - - @Override - public boolean isAdoptable() { - return false; - } - - private static final UncachedLookup[] UNCACHEDS = new UncachedLookup[SpecialMethodSlot.values().length]; - static { - SpecialMethodSlot[] values = SpecialMethodSlot.values(); - for (int i = 0; i < values.length; i++) { - SpecialMethodSlot slot = values[i]; - UNCACHEDS[i] = new UncachedLookup(slot); - } - } - } - - public static LookupSpecialMethodSlotNode getUncached(SpecialMethodSlot slot) { - return UncachedLookup.UNCACHEDS[slot.ordinal()]; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/MaybeBindDescriptorNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/MaybeBindDescriptorNode.java index 117967d873..4efcba0dc6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/MaybeBindDescriptorNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/MaybeBindDescriptorNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,11 +41,9 @@ package com.oracle.graal.python.nodes.call.special; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; import com.oracle.graal.python.builtins.objects.function.PFunction; import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.CallSlotDescrGet; @@ -55,7 +53,6 @@ import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; @@ -68,7 +65,6 @@ @GenerateUncached @GenerateInline @GenerateCached(false) -@ImportStatic(SpecialMethodSlot.class) public abstract class MaybeBindDescriptorNode extends PNodeWithContext { public abstract Object execute(Frame frame, Node inliningTarget, Object descriptor, Object receiver, Object receiverType); @@ -82,11 +78,6 @@ static Object doNoValue(Object descriptor, @SuppressWarnings("unused") Object re return descriptor; } - @Specialization - static Object doBuiltin(BuiltinMethodDescriptor descriptor, @SuppressWarnings("unused") Object receiver, @SuppressWarnings("unused") Object receiverType) { - return descriptor; - } - @Specialization static Object doBuiltin(PBuiltinFunction descriptor, @SuppressWarnings("unused") Object receiver, @SuppressWarnings("unused") Object receiverType) { return descriptor; @@ -103,8 +94,7 @@ static Object doFunction(PFunction descriptor, @SuppressWarnings("unused") Objec } public static boolean isMethodDescriptor(Object descriptor) { - return descriptor instanceof BuiltinMethodDescriptor || (descriptor instanceof PBuiltinFunction pbf && !pbf.needsDeclaringType()) || - descriptor instanceof PFunction; + return (descriptor instanceof PBuiltinFunction pbf && !pbf.needsDeclaringType()) || descriptor instanceof PFunction; } public static boolean needsToBind(Object descriptor) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupSpecialBaseNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/SpecialMethodNotFound.java similarity index 82% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupSpecialBaseNode.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/SpecialMethodNotFound.java index e7922117a9..04ed6925b8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupSpecialBaseNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/SpecialMethodNotFound.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,9 +40,14 @@ */ package com.oracle.graal.python.nodes.call.special; -import com.oracle.truffle.api.frame.Frame; -import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.ControlFlowException; -public abstract class LookupSpecialBaseNode extends Node { - public abstract Object execute(Frame frame, Object type, Object receiver); +/** + * Thrown from {@code LookupAndCallNAry} nodes when the method does not exist. + */ +public final class SpecialMethodNotFound extends ControlFlowException { + public static final SpecialMethodNotFound INSTANCE = new SpecialMethodNotFound(); + + private SpecialMethodNotFound() { + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectGetBasesNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectGetBasesNode.java index 0a7f68af11..42f8123f57 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectGetBasesNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectGetBasesNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,72 +41,32 @@ package com.oracle.graal.python.nodes.classes; import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___BASES__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETATTRIBUTE__; import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.lib.PyObjectGetAttr; +import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.SpecialMethodNames; -import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode; -import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +@GenerateInline +@GenerateCached(false) @GenerateUncached -@ImportStatic({SpecialMethodNames.class}) -@SuppressWarnings("truffle-inlining") // footprint reduction 44 -> 26 public abstract class AbstractObjectGetBasesNode extends PNodeWithContext { - @NeverDefault - public static AbstractObjectGetBasesNode create() { - return AbstractObjectGetBasesNodeGen.create(); - } - - protected abstract PTuple executeInternal(Frame frame, Object cls); - - public final PTuple execute(VirtualFrame frame, Object cls) { - return executeInternal(frame, cls); - } - @Specialization(guards = "!isUncachedNode()") - static PTuple getBasesCached(VirtualFrame frame, Object cls, - @Bind("this") Node inliningTarget, - @Cached PyObjectGetAttr getAttributeNode, - @Exclusive @Cached IsBuiltinObjectProfile exceptionMaskProfile) { - try { - Object bases = getAttributeNode.execute(frame, inliningTarget, cls, T___BASES__); - if (bases instanceof PTuple) { - return (PTuple) bases; - } - } catch (PException pe) { - pe.expectAttributeError(inliningTarget, exceptionMaskProfile); - } - return null; - } + public abstract PTuple execute(Frame frame, Node inliningTarget, Object cls); - @Specialization(replaces = "getBasesCached") - static PTuple getBasesUncached(VirtualFrame frame, Object cls, - @Bind("this") Node inliningTarget, - @Cached LookupInheritedAttributeNode.Dynamic lookupGetattributeNode, - @Cached CallNode callGetattributeNode, - @Exclusive @Cached IsBuiltinObjectProfile exceptionMaskProfile) { - Object getattr = lookupGetattributeNode.execute(inliningTarget, cls, T___GETATTRIBUTE__); - try { - Object bases = callGetattributeNode.execute(frame, getattr, cls, T___BASES__); - if (bases instanceof PTuple) { - return (PTuple) bases; - } - } catch (PException pe) { - pe.expectAttributeError(inliningTarget, exceptionMaskProfile); + @Specialization + static PTuple getBasesCached(VirtualFrame frame, Node inliningTarget, Object cls, + @Cached PyObjectLookupAttr lookupAttr) { + Object bases = lookupAttr.execute(frame, inliningTarget, cls, T___BASES__); + if (bases instanceof PTuple) { + return (PTuple) bases; } return null; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectIsSubclassNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectIsSubclassNode.java index 2d78aee141..6084e71f71 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectIsSubclassNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectIsSubclassNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -106,7 +106,7 @@ static boolean doSubclass(VirtualFrame frame, @SuppressWarnings("unused") Object @Cached AbstractObjectIsSubclassNode isSubclassNode, @Shared @Cached GetObjectArrayNode getObjectArrayNode) { CompilerAsserts.partialEvaluationConstant(depth); - PTuple bases = getBasesNode.execute(frame, cachedDerived); + PTuple bases = getBasesNode.execute(frame, inliningTarget, cachedDerived); if (bases == null || isEmpty(bases)) { return false; } @@ -158,7 +158,7 @@ static boolean doGeneric(VirtualFrame frame, Object derived, Object cls, int dep return true; } - PTuple bases = getBasesNode.execute(frame, derived); + PTuple bases = getBasesNode.execute(frame, inliningTarget, derived); if (bases == null || isEmpty(bases)) { return false; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/IsSubtypeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/IsSubtypeNode.java index 5522c20922..78869215aa 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/IsSubtypeNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/IsSubtypeNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,12 +46,9 @@ import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroStorageNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; -import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.runtime.exception.PythonErrorType; import com.oracle.graal.python.runtime.sequence.storage.MroSequenceStorage; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; @@ -64,25 +61,24 @@ import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.ReportPolymorphism.Megamorphic; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.Frame; -import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.nodes.ExplodeLoop.LoopExplosionKind; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedConditionProfile; +/** + * Equivalent of CPython's {@code PyType_IsSubtype}. + */ @GenerateUncached @ImportStatic({PythonOptions.class, PGuards.class}) @SuppressWarnings("truffle-inlining") // footprint reduction 84 -> 67 public abstract class IsSubtypeNode extends PNodeWithContext { - protected abstract boolean executeInternal(Frame frame, Object derived, Object cls); - - public final boolean execute(VirtualFrame frame, Object derived, Object cls) { - return executeInternal(frame, derived, cls); - } + protected abstract boolean executeInternal(Object derived, Object cls); public final boolean execute(Object derived, Object cls) { - return executeInternal(null, derived, cls); + assert TypeNodes.IsTypeNode.executeUncached(derived); + assert TypeNodes.IsTypeNode.executeUncached(cls); + return executeInternal(derived, cls); } protected static boolean isSameType(Node inliningTarget, IsSameTypeNode isSameTypeNode, Object cls, Object cachedCls) { @@ -191,7 +187,6 @@ static boolean isVariableSubtypeOfConstantTypeCachedMultiContext(@SuppressWarnin @Specialization(guards = { "isSingleContext()", - "isTypeDerived.execute(inliningTarget, derived)", "isTypeCls.execute(inliningTarget, cls)", "isSameType(inliningTarget, isSameDerivedNode, derived, cachedDerived)", "isSameType(inliningTarget, isSameClsNode, cls, cachedCls)", }, limit = "getVariableArgumentInlineCacheLimit()", replaces = { @@ -206,8 +201,6 @@ static boolean isSubtypeOfCached(Object derived, Object cls, @Bind("this") Node inliningTarget, @Cached("derived") Object cachedDerived, @Cached("cls") Object cachedCls, - @Shared @Cached TypeNodes.IsTypeNode isTypeDerived, - @Shared @Cached TypeNodes.IsTypeNode isTypeCls, @Shared @Cached IsSameTypeNode isSameDerivedNode, @Shared @Cached IsSameTypeNode isSameClsNode, @Shared @Cached IsSameTypeNode isSameTypeInLoopNode, @@ -219,7 +212,6 @@ static boolean isSubtypeOfCached(Object derived, Object cls, @Specialization(guards = { "isSingleContext()", - "isTypeDerived.execute(inliningTarget, derived)", "isTypeCls.execute(inliningTarget, cls)", "isSameType(inliningTarget, isSameDerivedNode, derived, cachedDerived)", "mro.getInternalClassArray().length < 32" }, limit = "getVariableArgumentInlineCacheLimit()", replaces = { @@ -233,8 +225,6 @@ static boolean isSubtypeOfCached(Object derived, Object cls, static boolean isSubtypeOfVariableTypeCached(@SuppressWarnings("unused") Object derived, Object cls, @Bind("this") Node inliningTarget, @Cached("derived") @SuppressWarnings("unused") Object cachedDerived, - @SuppressWarnings("unused") @Shared @Cached TypeNodes.IsTypeNode isTypeDerived, - @SuppressWarnings("unused") @Shared @Cached TypeNodes.IsTypeNode isTypeCls, @SuppressWarnings("unused") @Shared @Cached GetMroStorageNode getMro, @Cached("getMro.execute(inliningTarget, cachedDerived)") MroSequenceStorage mro, @Cached("mro.getInternalClassArray().length") int sz, @@ -273,7 +263,6 @@ static boolean isVariableSubtypeOfConstantTypeCached(@SuppressWarnings("unused") } @Specialization(guards = { - "isTypeDerived.execute(inliningTarget, derived)", "isTypeCls.execute(inliningTarget, cls)", "mro.getInternalClassArray().length == sz", "sz < 16" }, limit = "getVariableArgumentInlineCacheLimit()", replaces = { @@ -286,8 +275,6 @@ static boolean isVariableSubtypeOfConstantTypeCached(@SuppressWarnings("unused") @InliningCutoff static boolean isSubtypeGenericCachedLen(@SuppressWarnings("unused") Object derived, Object cls, @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Shared @Cached TypeNodes.IsTypeNode isTypeDerived, - @SuppressWarnings("unused") @Shared @Cached TypeNodes.IsTypeNode isTypeCls, @SuppressWarnings("unused") @Shared @Cached GetMroStorageNode getMro, @Bind("getMro.execute(inliningTarget, derived)") MroSequenceStorage mro, @Cached("mro.getInternalClassArray().length") int sz, @@ -295,7 +282,7 @@ static boolean isSubtypeGenericCachedLen(@SuppressWarnings("unused") Object deri return isInMro(inliningTarget, cls, mro, sz, isSameTypeInLoopNode); } - @Specialization(guards = {"isTypeDerived.execute(inliningTarget, derived)", "isTypeCls.execute(inliningTarget, cls)"}, replaces = { + @Specialization(replaces = { "isVariableSubtypeOfConstantTypeCached", "isSubtypeOfCachedMultiContext", "isVariableSubtypeOfConstantTypeCachedMultiContext", @@ -307,8 +294,6 @@ static boolean isSubtypeGenericCachedLen(@SuppressWarnings("unused") Object deri @Megamorphic static boolean issubTypeGeneric(Object derived, Object cls, @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.IsTypeNode isTypeDerived, - @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.IsTypeNode isTypeCls, @Exclusive @Cached InlinedConditionProfile builtinClassIsSubtypeProfile, @Exclusive @Cached IsSameTypeNode isSameTypeNode, @Exclusive @Cached GetMroStorageNode getMro) { @@ -324,29 +309,6 @@ static boolean issubTypeGeneric(Object derived, Object cls, return false; } - @Specialization(guards = {"!isTypeDerived.execute(inliningTarget, derived) || !isTypeCls.execute(inliningTarget, cls)"}, limit = "1") - @Megamorphic - @InliningCutoff - static boolean fallback(VirtualFrame frame, Object derived, Object cls, - @Bind("this") Node inliningTarget, - @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.IsTypeNode isTypeDerived, - @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.IsTypeNode isTypeCls, - @Cached AbstractObjectGetBasesNode getBasesNode, - @Cached AbstractObjectIsSubclassNode abstractIsSubclassNode, - @Exclusive @Cached InlinedConditionProfile exceptionDerivedProfile, - @Exclusive @Cached InlinedConditionProfile exceptionClsProfile, - @Cached PRaiseNode.Lazy raise) { - if (exceptionDerivedProfile.profile(inliningTarget, getBasesNode.execute(frame, derived) == null)) { - throw raise.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.ARG_D_MUST_BE_S, "issubclass()", 1, "class"); - } - - if (exceptionClsProfile.profile(inliningTarget, getBasesNode.execute(frame, cls) == null)) { - throw raise.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.ISSUBCLASS_MUST_BE_CLASS_OR_TUPLE); - } - - return abstractIsSubclassNode.execute(frame, derived, cls); - } - private static boolean isBuiltinClass(Object cls) { return cls instanceof PythonBuiltinClass || cls instanceof PythonBuiltinClassType; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/ExceptMatchNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/ExceptMatchNode.java index 589bae4724..a782944922 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/ExceptMatchNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/ExceptMatchNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -51,6 +51,7 @@ import com.oracle.graal.python.runtime.exception.PythonErrorType; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -68,39 +69,35 @@ @ImportStatic(PGuards.class) @GenerateUncached +@OperationProxy.Proxyable @SuppressWarnings("truffle-inlining") // footprint reduction 44 -> 25 public abstract class ExceptMatchNode extends Node { public abstract boolean executeMatch(Frame frame, Object exception, Object clause); - private static void raiseIfNoException(VirtualFrame frame, Object clause, ValidExceptionNode isValidException, PRaiseNode raiseNode) { + private static void raiseIfNoException(VirtualFrame frame, Node inliningTarget, Object clause, ValidExceptionNode isValidException) { if (!isValidException.execute(frame, clause)) { - raiseNoException(raiseNode); + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.TypeError, ErrorMessages.CATCHING_CLS_NOT_ALLOWED); } } - private static void raiseNoException(PRaiseNode raiseNode) { - throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.CATCHING_CLS_NOT_ALLOWED); - } - @Specialization(guards = "!isPTuple(clause)") public static boolean matchPythonSingle(VirtualFrame frame, PException e, Object clause, @Bind("this") Node inliningTarget, @Shared @Cached ValidExceptionNode isValidException, @Cached GetClassNode getClassNode, - @Cached IsSubtypeNode isSubtype, - @Shared @Cached PRaiseNode raiseNode) { - raiseIfNoException(frame, clause, isValidException, raiseNode); - return isSubtype.execute(frame, getClassNode.execute(inliningTarget, e.getUnreifiedException()), clause); + @Cached IsSubtypeNode isSubtype) { + raiseIfNoException(frame, inliningTarget, clause, isValidException); + return isSubtype.execute(getClassNode.execute(inliningTarget, e.getUnreifiedException()), clause); } @Specialization(guards = {"!isPTuple(clause)", "!isPException(e)"}, limit = "1") public static boolean matchJava(VirtualFrame frame, AbstractTruffleException e, Object clause, + @Bind("this") Node inliningTarget, @Shared @Cached ValidExceptionNode isValidException, - @CachedLibrary("clause") InteropLibrary clauseLib, - @Shared @Cached PRaiseNode raiseNode) { + @CachedLibrary("clause") InteropLibrary clauseLib) { // n.b.: we can only allow Java exceptions in clauses, because we cannot tell for other // foreign exception types if they *are* exception types - raiseIfNoException(frame, clause, isValidException, raiseNode); + raiseIfNoException(frame, inliningTarget, clause, isValidException); if (clauseLib.isMetaObject(clause)) { try { return clauseLib.isMetaInstance(clause, e); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/TopLevelExceptionHandler.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/TopLevelExceptionHandler.java index 53f1fe05d0..34eab35e83 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/TopLevelExceptionHandler.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/TopLevelExceptionHandler.java @@ -72,7 +72,7 @@ import com.oracle.graal.python.runtime.exception.PythonExitException; import com.oracle.graal.python.runtime.exception.PythonInterruptedException; import com.oracle.graal.python.runtime.exception.PythonThreadKillException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -219,7 +219,7 @@ private static boolean isSystemExit(PBaseException pythonException) { @TruffleBoundary private void handleJavaException(Throwable e) { - PException pe = ExceptionUtils.wrapJavaExceptionIfApplicable(this, e, PythonObjectFactory.getUncached()); + PException pe = ExceptionUtils.wrapJavaExceptionIfApplicable(this, e); if (pe != null) { throw handlePythonException(pe); } @@ -308,9 +308,10 @@ private Object run(VirtualFrame frame) { } PythonContext pythonContext = getContext(); PythonModule mainModule = null; + PythonLanguage language = getPythonLanguage(); if (source.isInternal()) { // internal sources are not run in the main module - PArguments.setGlobals(arguments, pythonContext.factory().createDict()); + PArguments.setGlobals(arguments, PFactory.createDict(language)); } else { mainModule = pythonContext.getMainModule(); PDict mainDict = GetOrCreateDictNode.executeUncached(mainModule); @@ -318,7 +319,7 @@ private Object run(VirtualFrame frame) { PArguments.setSpecialArgument(arguments, mainDict); PArguments.setException(arguments, PException.NO_EXCEPTION); } - Object state = IndirectCalleeContext.enterIndirect(getPythonLanguage(), pythonContext, arguments); + Object state = IndirectCalleeContext.enterIndirect(language, pythonContext, arguments); try { Object result = innerCallTarget.call(arguments); if (mainModule != null && result == PNone.NONE && !source.isInteractive()) { @@ -327,7 +328,7 @@ private Object run(VirtualFrame frame) { return result; } } finally { - IndirectCalleeContext.exit(getPythonLanguage(), pythonContext, state); + IndirectCalleeContext.exit(language, pythonContext, state); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/ValidExceptionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/ValidExceptionNode.java index a34ab2d51d..e08bc79185 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/ValidExceptionNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/ValidExceptionNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -52,7 +52,6 @@ import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; -import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; @@ -88,11 +87,11 @@ static boolean isPythonExceptionClassCached(@SuppressWarnings("unused") PythonBu } @Specialization(guards = "isTypeNode.execute(inliningTarget, type)", limit = "1", replaces = {"isPythonExceptionTypeCached", "isPythonExceptionClassCached"}) - static boolean isPythonException(VirtualFrame frame, Object type, + static boolean isPythonException(Object type, @SuppressWarnings("unused") @Bind("this") Node inliningTarget, @SuppressWarnings("unused") @Cached TypeNodes.IsTypeNode isTypeNode, @Cached IsSubtypeNode isSubtype) { - return isSubtype.execute(frame, type, PythonBuiltinClassType.PBaseException); + return isSubtype.execute(type, PythonBuiltinClassType.PBaseException); } @Specialization(guards = "isForeignObjectNode.execute(inliningTarget, type)", limit = "1") diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryArithmetic.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryArithmetic.java deleted file mode 100644 index e907bda862..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryArithmetic.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.expression; - -import static com.oracle.graal.python.nodes.BuiltinNames.T_PRINT; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; -import static com.oracle.graal.python.util.PythonUtils.tsArray; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.function.Signature; -import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.lib.PyNumberAddNode; -import com.oracle.graal.python.lib.PyNumberAndNode; -import com.oracle.graal.python.lib.PyNumberDivmodNode; -import com.oracle.graal.python.lib.PyNumberFloorDivideNode; -import com.oracle.graal.python.lib.PyNumberLshiftNode; -import com.oracle.graal.python.lib.PyNumberMatrixMultiplyNode; -import com.oracle.graal.python.lib.PyNumberMultiplyNode; -import com.oracle.graal.python.lib.PyNumberOrNode; -import com.oracle.graal.python.lib.PyNumberRemainderNode; -import com.oracle.graal.python.lib.PyNumberRshiftNode; -import com.oracle.graal.python.lib.PyNumberSubtractNode; -import com.oracle.graal.python.lib.PyNumberTrueDivideNode; -import com.oracle.graal.python.lib.PyNumberXorNode; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.SpecialMethodNames; -import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode.NotImplementedHandler; -import com.oracle.graal.python.util.Supplier; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.strings.TruffleString; - -@SuppressWarnings("truffle-inlining") -public enum BinaryArithmetic { - Add(PyNumberAddNode::create), - Sub(PyNumberSubtractNode::create), - Mul(PyNumberMultiplyNode::create), - TrueDiv(PyNumberTrueDivideNode::create), - FloorDiv(PyNumberFloorDivideNode::create), - Mod(PyNumberRemainderNode::create), - LShift(PyNumberLshiftNode::create), - RShift(PyNumberRshiftNode::create), - And(PyNumberAndNode::create), - Or(PyNumberOrNode::create), - Xor(PyNumberXorNode::create), - MatMul(PyNumberMatrixMultiplyNode::create), - Pow(BinaryArithmeticFactory.PowNodeGen::create), - DivMod(PyNumberDivmodNode::create); - - interface CreateBinaryOp { - BinaryOpNode create(); - } - - private final CreateBinaryOp create; - - BinaryArithmetic(CreateBinaryOp create) { - this.create = create; - } - - /** - * A helper root node that dispatches to {@link LookupAndCallBinaryNode} to execute the provided - * ternary operator. Note: this is just a root node and won't do any signature checking. - */ - static final class CallBinaryArithmeticRootNode extends CallArithmeticRootNode { - static final Signature SIGNATURE_BINARY = new Signature(2, false, -1, false, tsArray("$self", "other"), null); - - @Child private BinaryOpNode callBinaryNode; - - private final BinaryArithmetic binaryOperator; - - CallBinaryArithmeticRootNode(PythonLanguage language, BinaryArithmetic binaryOperator) { - super(language); - this.binaryOperator = binaryOperator; - } - - @Override - public Signature getSignature() { - return SIGNATURE_BINARY; - } - - @Override - protected Object doCall(VirtualFrame frame) { - if (callBinaryNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - callBinaryNode = insert(binaryOperator.create()); - } - return callBinaryNode.executeObject(frame, PArguments.getArgument(frame, 0), PArguments.getArgument(frame, 1)); - } - } - - @NeverDefault - public BinaryOpNode create() { - return create.create(); - } - - /** - * Creates a root node for this binary operator such that the operator can be executed via a - * full call. - */ - public RootNode createRootNode(PythonLanguage language) { - return new CallBinaryArithmeticRootNode(language, this); - } - - @ImportStatic(SpecialMethodNames.class) - public abstract static class BinaryArithmeticNode extends BinaryOpNode { - - static Supplier createHandler(String operator) { - return () -> new NotImplementedHandler() { - @Child private PRaiseNode raiseNode = PRaiseNode.create(); - - @Override - public Object execute(VirtualFrame frame, Object arg, Object arg2) { - throw raiseNode.raise(TypeError, getErrorMessage(arg), operator, arg, arg2); - } - - @CompilerDirectives.TruffleBoundary - private TruffleString getErrorMessage(Object arg) { - if (operator.equals(">>") && arg instanceof PBuiltinMethod && ((PBuiltinMethod) arg).getBuiltinFunction().getName().equalsUncached(T_PRINT, TS_ENCODING)) { - return ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P_PRINT; - } - return ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P; - } - }; - } - - @NeverDefault - public static LookupAndCallBinaryNode createCallNode(SpecialMethodSlot slot, Supplier handler) { - assert slot.getReverse() != null; - return LookupAndCallBinaryNode.createReversible(slot, slot.getReverse(), handler); - } - - } - - public abstract static class PowNode extends BinaryArithmeticNode { - - public static final Supplier NOT_IMPLEMENTED = createHandler("** or pow()"); - - @Specialization - public static Object doGeneric(VirtualFrame frame, Object left, Object right, - // TODO: ternary_op is not implemented (GR-<2????>) - @Cached("createCallNode(Pow, NOT_IMPLEMENTED)") LookupAndCallBinaryNode callNode) { - return callNode.executeObject(frame, left, right); - } - } - - public abstract static class GenericBinaryArithmeticNode extends BinaryArithmeticNode { - - private final SpecialMethodSlot slot; - - protected GenericBinaryArithmeticNode(SpecialMethodSlot slot) { - this.slot = slot; - } - - @Specialization - public static Object doGeneric(VirtualFrame frame, Object left, Object right, - @Cached("createCallNode()") LookupAndCallBinaryNode callNode) { - return callNode.executeObject(frame, left, right); - } - - @NeverDefault - protected LookupAndCallBinaryNode createCallNode() { - return LookupAndCallBinaryNode.create(slot, createHandler(slot.getName().toString())); - } - - @NeverDefault - public static GenericBinaryArithmeticNode create(SpecialMethodSlot slot) { - return BinaryArithmeticFactory.GenericBinaryArithmeticNodeGen.create(slot); - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryComparisonNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryComparisonNode.java deleted file mode 100644 index 535b57ecf4..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryComparisonNode.java +++ /dev/null @@ -1,542 +0,0 @@ -/* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. - * Copyright (c) 2013, Regents of the University of California - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.oracle.graal.python.nodes.expression; - -import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; - -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.str.StringUtils; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode; -import com.oracle.graal.python.nodes.expression.BinaryComparisonNodeFactory.EqNodeGen; -import com.oracle.graal.python.nodes.expression.BinaryComparisonNodeFactory.GeNodeGen; -import com.oracle.graal.python.nodes.expression.BinaryComparisonNodeFactory.GtNodeGen; -import com.oracle.graal.python.nodes.expression.BinaryComparisonNodeFactory.LeNodeGen; -import com.oracle.graal.python.nodes.expression.BinaryComparisonNodeFactory.LtNodeGen; -import com.oracle.graal.python.nodes.expression.BinaryComparisonNodeFactory.NeNodeGen; -import com.oracle.graal.python.nodes.object.IsNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.UnexpectedResultException; -import com.oracle.truffle.api.strings.TruffleString; - -@TypeSystemReference(PythonArithmeticTypes.class) -public abstract class BinaryComparisonNode extends BinaryOpNode { - - private abstract static class ErrorNode extends BinaryComparisonNode { - @Child private PRaiseNode raiseNode; - - protected final RuntimeException noSupported(Object left, Object right) { - if (raiseNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - raiseNode = insert(PRaiseNode.create()); - } - throw raiseNode.raise(TypeError, ErrorMessages.NOT_SUPPORTED_BETWEEN_INSTANCES, operator(), left, right); - } - - protected abstract String operator(); - - public abstract boolean cmp(TruffleString l, TruffleString r, TruffleString.CompareIntsUTF32Node compareIntsUTF32Node); - } - - private abstract static class FallbackNode extends BinaryComparisonNode { - @Child private IsNode isNode; - - protected final IsNode ensureIsNode() { - if (isNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - isNode = insert(IsNode.create()); - } - return isNode; - } - - public abstract boolean cmp(TruffleString l, TruffleString r, TruffleString.EqualNode equalNode); - } - - public abstract boolean cmp(int l, int r); - - public abstract boolean cmp(long l, long r); - - public abstract boolean cmp(char l, char r); - - public abstract boolean cmp(byte l, byte r); - - public abstract boolean cmp(double l, double r); - - public abstract boolean executeBool(VirtualFrame frame, Object left, Object right) throws UnexpectedResultException; - - public abstract static class LeNode extends ErrorNode { - - @Specialization - @Override - public final boolean cmp(int l, int r) { - return l <= r; - } - - @Specialization - @Override - public final boolean cmp(long l, long r) { - return l <= r; - } - - @Specialization - @Override - public final boolean cmp(char l, char r) { - return l <= r; - } - - @Specialization - @Override - public final boolean cmp(byte l, byte r) { - return l <= r; - } - - @Specialization - @Override - public final boolean cmp(double l, double r) { - return l <= r; - } - - @Specialization - @Override - public final boolean cmp(TruffleString l, TruffleString r, - @Cached TruffleString.CompareIntsUTF32Node compareIntsUTF32Node) { - return StringUtils.compareStrings(l, r, compareIntsUTF32Node) <= 0; - } - - @Specialization - static boolean cmp(int l, double r) { - return l <= r; - } - - @Specialization - static boolean cmp(double l, int r) { - return l <= r; - } - - @Specialization - protected final Object doGeneric(VirtualFrame frame, Object left, Object right, - @Cached("createCallNode()") LookupAndCallBinaryNode callNode) { - Object result = callNode.executeObject(frame, left, right); - if (result == PNotImplemented.NOT_IMPLEMENTED) { - throw noSupported(left, right); - } - return result; - } - - @NeverDefault - protected static LookupAndCallBinaryNode createCallNode() { - return LookupAndCallBinaryNode.create(SpecialMethodSlot.Le, SpecialMethodSlot.Ge, true, true); - } - - @Override - protected final String operator() { - return "<="; - } - - @NeverDefault - public static LeNode create() { - return LeNodeGen.create(); - } - } - - public abstract static class LtNode extends ErrorNode { - - @Specialization - @Override - public final boolean cmp(int l, int r) { - return l < r; - } - - @Specialization - @Override - public final boolean cmp(long l, long r) { - return l < r; - } - - @Specialization - @Override - public final boolean cmp(char l, char r) { - return l < r; - } - - @Specialization - @Override - public final boolean cmp(byte l, byte r) { - return l < r; - } - - @Specialization - @Override - public final boolean cmp(double l, double r) { - return l < r; - } - - @Specialization - @Override - public final boolean cmp(TruffleString l, TruffleString r, - @Cached TruffleString.CompareIntsUTF32Node compareIntsUTF32Node) { - return StringUtils.compareStrings(l, r, compareIntsUTF32Node) < 0; - } - - @Specialization - static boolean cmp(int l, double r) { - return l < r; - } - - @Specialization - static boolean cmp(double l, int r) { - return l < r; - } - - @Specialization - protected final Object doGeneric(VirtualFrame frame, Object left, Object right, - @Cached("createCallNode()") LookupAndCallBinaryNode callNode) { - Object result = callNode.executeObject(frame, left, right); - if (result == PNotImplemented.NOT_IMPLEMENTED) { - throw noSupported(left, right); - } - return result; - } - - @NeverDefault - protected static LookupAndCallBinaryNode createCallNode() { - return LookupAndCallBinaryNode.create(SpecialMethodSlot.Lt, SpecialMethodSlot.Gt, true, true); - } - - @Override - protected String operator() { - return "<"; - } - - @NeverDefault - public static LtNode create() { - return LtNodeGen.create(); - } - } - - public abstract static class GeNode extends ErrorNode { - - @Specialization - @Override - public final boolean cmp(int l, int r) { - return l >= r; - } - - @Specialization - @Override - public final boolean cmp(long l, long r) { - return l >= r; - } - - @Specialization - @Override - public final boolean cmp(char l, char r) { - return l >= r; - } - - @Specialization - @Override - public final boolean cmp(byte l, byte r) { - return l >= r; - } - - @Specialization - @Override - public final boolean cmp(double l, double r) { - return l >= r; - } - - @Specialization - @Override - public final boolean cmp(TruffleString l, TruffleString r, - @Cached TruffleString.CompareIntsUTF32Node compareIntsUTF32Node) { - return StringUtils.compareStrings(l, r, compareIntsUTF32Node) >= 0; - } - - @Specialization - static boolean cmp(int l, double r) { - return l >= r; - } - - @Specialization - static boolean cmp(double l, int r) { - return l >= r; - } - - @Specialization - protected final Object doGeneric(VirtualFrame frame, Object left, Object right, - @Cached("createCallNode()") LookupAndCallBinaryNode callNode) { - Object result = callNode.executeObject(frame, left, right); - if (result == PNotImplemented.NOT_IMPLEMENTED) { - throw noSupported(left, right); - } - return result; - } - - @NeverDefault - protected static LookupAndCallBinaryNode createCallNode() { - return LookupAndCallBinaryNode.create(SpecialMethodSlot.Ge, SpecialMethodSlot.Le, true, true); - } - - @Override - protected String operator() { - return ">="; - } - - @NeverDefault - public static GeNode create() { - return GeNodeGen.create(); - } - } - - public abstract static class GtNode extends ErrorNode { - - @Specialization - @Override - public final boolean cmp(int l, int r) { - return l > r; - } - - @Specialization - @Override - public final boolean cmp(long l, long r) { - return l > r; - } - - @Specialization - @Override - public final boolean cmp(char l, char r) { - return l > r; - } - - @Specialization - @Override - public final boolean cmp(byte l, byte r) { - return l > r; - } - - @Specialization - @Override - public final boolean cmp(double l, double r) { - return l > r; - } - - @Specialization - @Override - public final boolean cmp(TruffleString l, TruffleString r, - @Cached TruffleString.CompareIntsUTF32Node compareIntsUTF32Node) { - return StringUtils.compareStrings(l, r, compareIntsUTF32Node) > 0; - } - - @Specialization - static boolean cmp(int l, double r) { - return l > r; - } - - @Specialization - static boolean cmp(double l, int r) { - return l > r; - } - - @Specialization - protected final Object doGeneric(VirtualFrame frame, Object left, Object right, - @Cached("createCallNode()") LookupAndCallBinaryNode callNode) { - Object result = callNode.executeObject(frame, left, right); - if (result == PNotImplemented.NOT_IMPLEMENTED) { - throw noSupported(left, right); - } - return result; - } - - @NeverDefault - protected static LookupAndCallBinaryNode createCallNode() { - return LookupAndCallBinaryNode.create(SpecialMethodSlot.Gt, SpecialMethodSlot.Lt, true, true); - } - - @Override - protected String operator() { - return ">"; - } - - @NeverDefault - public static GtNode create() { - return GtNodeGen.create(); - } - } - - public abstract static class EqNode extends FallbackNode { - - @Specialization - @Override - public final boolean cmp(int l, int r) { - return l == r; - } - - @Specialization - @Override - public final boolean cmp(long l, long r) { - return l == r; - } - - @Specialization - @Override - public final boolean cmp(char l, char r) { - return l == r; - } - - @Specialization - @Override - public final boolean cmp(byte l, byte r) { - return l == r; - } - - @Specialization - @Override - public final boolean cmp(double l, double r) { - return l == r; - } - - @Specialization - @Override - public final boolean cmp(TruffleString l, TruffleString r, - @Cached TruffleString.EqualNode equalNode) { - return equalNode.execute(l, r, TS_ENCODING); - } - - @Specialization - static boolean cmp(int l, double r) { - return l == r; - } - - @Specialization - static boolean cmp(double l, int r) { - return l == r; - } - - @Specialization - protected final Object doGeneric(VirtualFrame frame, Object left, Object right, - @Cached("createCallNode()") LookupAndCallBinaryNode callNode) { - Object result = callNode.executeObject(frame, left, right); - if (result == PNotImplemented.NOT_IMPLEMENTED) { - // just like python, if no implementation is available, do something sensible for - // == and != - return ensureIsNode().execute(left, right); - } - return result; - } - - @NeverDefault - protected static LookupAndCallBinaryNode createCallNode() { - return LookupAndCallBinaryNode.create(SpecialMethodSlot.Eq, SpecialMethodSlot.Eq, true, true); - } - - @NeverDefault - public static EqNode create() { - return EqNodeGen.create(); - } - } - - public abstract static class NeNode extends FallbackNode { - - @Specialization - @Override - public final boolean cmp(int l, int r) { - return l != r; - } - - @Specialization - @Override - public final boolean cmp(long l, long r) { - return l != r; - } - - @Specialization - @Override - public final boolean cmp(char l, char r) { - return l != r; - } - - @Specialization - @Override - public final boolean cmp(byte l, byte r) { - return l != r; - } - - @Specialization - @Override - public final boolean cmp(double l, double r) { - return l != r; - } - - @Specialization - @Override - public final boolean cmp(TruffleString l, TruffleString r, - @Cached TruffleString.EqualNode equalNode) { - return !equalNode.execute(l, r, TS_ENCODING); - } - - @Specialization - static boolean cmp(int l, double r) { - return l != r; - } - - @Specialization - static boolean cmp(double l, int r) { - return l != r; - } - - @Specialization - protected final Object doGeneric(VirtualFrame frame, Object left, Object right, - @Cached("createCallNode()") LookupAndCallBinaryNode callNode) { - Object result = callNode.executeObject(frame, left, right); - if (result == PNotImplemented.NOT_IMPLEMENTED) { - // just like python, if no implementation is available, do something sensible for - // == and != - return !ensureIsNode().execute(left, right); - } - return result; - } - - @NeverDefault - protected static LookupAndCallBinaryNode createCallNode() { - return LookupAndCallBinaryNode.create(SpecialMethodSlot.Ne, SpecialMethodSlot.Ne, true, true); - } - - @NeverDefault - public static NeNode create() { - return NeNodeGen.create(); - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryOp.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryOp.java index de1eb5746b..4dce665264 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryOp.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryOp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,5 +43,5 @@ import com.oracle.truffle.api.frame.VirtualFrame; public interface BinaryOp { - Object executeObject(VirtualFrame frame, Object left, Object right); + Object execute(VirtualFrame frame, Object left, Object right); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryOpNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryOpNode.java index f0b51431bd..86039e7a50 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryOpNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryOpNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -30,5 +30,5 @@ public abstract class BinaryOpNode extends PNodeWithContext implements BinaryOp { @Override - public abstract Object executeObject(VirtualFrame frame, Object left, Object right); + public abstract Object execute(VirtualFrame frame, Object left, Object right); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/CastToListExpressionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/CastToListExpressionNode.java index d172f0b484..9033de6eae 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/CastToListExpressionNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/CastToListExpressionNode.java @@ -43,19 +43,16 @@ import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetObjectArrayNode; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.list.PList; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.nodes.BuiltinNames; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.SpecialMethodNames; -import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; import com.oracle.graal.python.nodes.builtins.ListNodes.ConstructListNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.expression.CastToListExpressionNodeGen.CastToListNodeGen; @@ -64,11 +61,10 @@ import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -98,7 +94,7 @@ public abstract static class CastToListNode extends Node { @Specialization(guards = {"isBuiltinTuple(v)", "cachedLength == getLength(v)", "cachedLength < 32"}, limit = "2") @ExplodeLoop static PList starredTupleCachedLength(PTuple v, - @Exclusive @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached("getLength(v)") int cachedLength, @Cached SequenceStorageNodes.GetItemNode getItemNode) { SequenceStorage s = v.getSequenceStorage(); @@ -106,15 +102,15 @@ static PList starredTupleCachedLength(PTuple v, for (int i = 0; i < cachedLength; i++) { array[i] = getItemNode.execute(s, i); } - return factory.createList(array); + return PFactory.createList(language, array); } @Specialization(replaces = "starredTupleCachedLength", guards = "isBuiltinTuple(v)") static PList starredTuple(PTuple v, @Bind("this") Node inliningTarget, - @Exclusive @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Cached GetObjectArrayNode getObjectArrayNode) { - return factory.createList(getObjectArrayNode.execute(inliningTarget, v).clone()); + return PFactory.createList(language, getObjectArrayNode.execute(inliningTarget, v).clone()); } @Specialization(guards = "isBuiltinList(v)") @@ -151,7 +147,7 @@ static PList starredGeneric(VirtualFrame frame, Object v, return constructListNode.execute(frame, v); } catch (PException e) { e.expectAttributeError(inliningTarget, attrProfile); - throw raise.raise(TypeError, ErrorMessages.OBJ_NOT_ITERABLE, v); + throw raise.raise(inliningTarget, TypeError, ErrorMessages.OBJ_NOT_ITERABLE, v); } finally { IndirectCallContext.exit(frame, language, context, state); } @@ -200,9 +196,7 @@ private static final class CastToListUncachedNode extends CastToListInteropNode @Override public PList executeWithGlobalState(Object list) { - Object builtins = PythonContext.get(this).getBuiltins(); - Object listType = ReadAttributeFromObjectNode.getUncached().execute(builtins, BuiltinNames.T_LIST); - return (PList) CallNode.executeUncached(LookupInheritedAttributeNode.Dynamic.executeUncached(listType, SpecialMethodNames.T___CALL__), listType, list); + return (PList) CallNode.executeUncached(PythonBuiltinClassType.PList, list); } @Override diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/ContainsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/ContainsNode.java deleted file mode 100644 index e8f75d827e..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/ContainsNode.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.expression; - -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.lib.GetNextNode; -import com.oracle.graal.python.lib.PyObjectGetIter; -import com.oracle.graal.python.lib.PyObjectIsTrueNode; -import com.oracle.graal.python.lib.PyObjectRichCompareBool; -import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode; -import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.UnexpectedResultException; - -@GenerateInline(false) -public abstract class ContainsNode extends BinaryOpNode { - @NeverDefault - public static ContainsNode create() { - return ContainsNodeGen.create(); - } - - @NeverDefault - public static LookupAndCallBinaryNode createCallNode() { - return LookupAndCallBinaryNode.create(SpecialMethodSlot.Contains); - } - - @Specialization(rewriteOn = UnexpectedResultException.class) - public static boolean doBoolean(VirtualFrame frame, boolean item, Object iter, - @Bind("this") Node inliningTarget, - @Shared @Cached PyObjectIsTrueNode castBool, - @Shared("callNode") @Cached("createCallNode()") LookupAndCallBinaryNode callNode, - @Shared("errorProfile") @Cached IsBuiltinObjectProfile errorProfile, - @Shared("getIter") @Cached PyObjectGetIter getIter, - @Shared("eqNode") @Cached PyObjectRichCompareBool.EqNode eqNode, - @Shared("nextNode") @Cached GetNextNode nextNode) throws UnexpectedResultException { - Object result = callNode.executeObject(frame, iter, item); - if (result == PNotImplemented.NOT_IMPLEMENTED) { - Object iterator = getIter.execute(frame, inliningTarget, iter); - return sequenceContains(frame, iterator, item, eqNode, nextNode, inliningTarget, errorProfile); - } - return castBool.execute(frame, result); - } - - @Specialization(rewriteOn = UnexpectedResultException.class) - public static boolean doInt(VirtualFrame frame, int item, Object iter, - @Bind("this") Node inliningTarget, - @Shared @Cached PyObjectIsTrueNode castBool, - @Shared("callNode") @Cached("createCallNode()") LookupAndCallBinaryNode callNode, - @Shared("errorProfile") @Cached IsBuiltinObjectProfile errorProfile, - @Shared("getIter") @Cached PyObjectGetIter getIter, - @Shared("eqNode") @Cached PyObjectRichCompareBool.EqNode eqNode, - @Shared("nextNode") @Cached GetNextNode nextNode) throws UnexpectedResultException { - Object result = callNode.executeObject(frame, iter, item); - if (result == PNotImplemented.NOT_IMPLEMENTED) { - return sequenceContains(frame, getIter.execute(frame, inliningTarget, iter), item, eqNode, nextNode, inliningTarget, errorProfile); - } - return castBool.execute(frame, result); - } - - @Specialization(rewriteOn = UnexpectedResultException.class) - public static boolean doLong(VirtualFrame frame, long item, Object iter, - @Bind("this") Node inliningTarget, - @Shared @Cached PyObjectIsTrueNode castBool, - @Shared("callNode") @Cached("createCallNode()") LookupAndCallBinaryNode callNode, - @Shared("errorProfile") @Cached IsBuiltinObjectProfile errorProfile, - @Shared("getIter") @Cached PyObjectGetIter getIter, - @Shared("eqNode") @Cached PyObjectRichCompareBool.EqNode eqNode, - @Shared("nextNode") @Cached GetNextNode nextNode) throws UnexpectedResultException { - Object result = callNode.executeObject(frame, iter, item); - if (result == PNotImplemented.NOT_IMPLEMENTED) { - return sequenceContains(frame, getIter.execute(frame, inliningTarget, iter), item, eqNode, nextNode, inliningTarget, errorProfile); - } - return castBool.execute(frame, result); - } - - @Specialization(rewriteOn = UnexpectedResultException.class) - public static boolean doDouble(VirtualFrame frame, double item, Object iter, - @Bind("this") Node inliningTarget, - @Shared @Cached PyObjectIsTrueNode castBool, - @Shared("callNode") @Cached("createCallNode()") LookupAndCallBinaryNode callNode, - @Shared("errorProfile") @Cached IsBuiltinObjectProfile errorProfile, - @Shared("getIter") @Cached PyObjectGetIter getIter, - @Shared("eqNode") @Cached PyObjectRichCompareBool.EqNode eqNode, - @Shared("nextNode") @Cached GetNextNode nextNode) throws UnexpectedResultException { - Object result = callNode.executeObject(frame, iter, item); - if (result == PNotImplemented.NOT_IMPLEMENTED) { - return sequenceContains(frame, getIter.execute(frame, inliningTarget, iter), item, eqNode, nextNode, inliningTarget, errorProfile); - } - return castBool.execute(frame, result); - } - - @Specialization - public static boolean doGeneric(VirtualFrame frame, Object item, Object iter, - @Bind("this") Node inliningTarget, - @Shared @Cached PyObjectIsTrueNode castBool, - @Shared("callNode") @Cached("createCallNode()") LookupAndCallBinaryNode callNode, - @Shared("errorProfile") @Cached IsBuiltinObjectProfile errorProfile, - @Shared("getIter") @Cached PyObjectGetIter getIter, - @Shared("eqNode") @Cached PyObjectRichCompareBool.EqNode eqNode, - @Shared("nextNode") @Cached GetNextNode nextNode) { - Object result = callNode.executeObject(frame, iter, item); - if (result == PNotImplemented.NOT_IMPLEMENTED) { - return sequenceContainsObject(frame, getIter.execute(frame, inliningTarget, iter), item, eqNode, nextNode, inliningTarget, errorProfile); - } - return castBool.execute(frame, result); - } - - private static void handleUnexpectedResult(VirtualFrame frame, Object iterator, Object item, UnexpectedResultException e, PyObjectRichCompareBool.EqNode eqNode, GetNextNode nextNode, - Node inliningTarget, IsBuiltinObjectProfile errorProfile) throws UnexpectedResultException { - // If we got an unexpected (non-primitive) result from the iterator, we need to compare it - // and continue iterating with "next" through the generic case. However, we also want the - // specialization to go away, so we wrap the boolean result in a new - // UnexpectedResultException. This will cause the DSL to disable the specialization with the - // primitive value and return the result we got, without iterating again. - Object result = e.getResult(); - if (eqNode.compare(frame, inliningTarget, result, item)) { - result = true; - } else { - result = sequenceContainsObject(frame, iterator, item, eqNode, nextNode, inliningTarget, errorProfile); - } - throw new UnexpectedResultException(result); - } - - private static boolean sequenceContains(VirtualFrame frame, Object iterator, boolean item, PyObjectRichCompareBool.EqNode eqNode, GetNextNode nextNode, - Node inliningTarget, IsBuiltinObjectProfile errorProfile) throws UnexpectedResultException { - while (true) { - try { - if (nextNode.executeBoolean(frame, iterator) == item) { - return true; - } - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); - return false; - } catch (UnexpectedResultException e) { - handleUnexpectedResult(frame, iterator, item, e, eqNode, nextNode, inliningTarget, errorProfile); - } - } - } - - private static boolean sequenceContains(VirtualFrame frame, Object iterator, int item, PyObjectRichCompareBool.EqNode eqNode, GetNextNode nextNode, - Node inliningTarget, IsBuiltinObjectProfile errorProfile) throws UnexpectedResultException { - while (true) { - try { - if (nextNode.executeInt(frame, iterator) == item) { - return true; - } - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); - return false; - } catch (UnexpectedResultException e) { - handleUnexpectedResult(frame, iterator, item, e, eqNode, nextNode, inliningTarget, errorProfile); - } - } - } - - private static boolean sequenceContains(VirtualFrame frame, Object iterator, long item, PyObjectRichCompareBool.EqNode eqNode, GetNextNode nextNode, - Node inliningTarget, IsBuiltinObjectProfile errorProfile) throws UnexpectedResultException { - while (true) { - try { - if (nextNode.executeLong(frame, iterator) == item) { - return true; - } - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); - return false; - } catch (UnexpectedResultException e) { - handleUnexpectedResult(frame, iterator, item, e, eqNode, nextNode, inliningTarget, errorProfile); - } - } - } - - private static boolean sequenceContains(VirtualFrame frame, Object iterator, double item, PyObjectRichCompareBool.EqNode eqNode, GetNextNode nextNode, - Node inliningTarget, IsBuiltinObjectProfile errorProfile) throws UnexpectedResultException { - while (true) { - try { - if (nextNode.executeDouble(frame, iterator) == item) { - return true; - } - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); - return false; - } catch (UnexpectedResultException e) { - handleUnexpectedResult(frame, iterator, item, e, eqNode, nextNode, inliningTarget, errorProfile); - } - } - } - - private static boolean sequenceContainsObject(VirtualFrame frame, Object iterator, Object item, PyObjectRichCompareBool.EqNode eqNode, GetNextNode nextNode, - Node inliningTarget, IsBuiltinObjectProfile errorProfile) { - while (true) { - try { - if (eqNode.compare(frame, inliningTarget, nextNode.execute(frame, iterator), item)) { - return true; - } - } catch (PException e) { - e.expectStopIteration(inliningTarget, errorProfile); - return false; - } - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/InplaceArithmetic.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/InplaceArithmetic.java deleted file mode 100644 index 4bf4b17619..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/InplaceArithmetic.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.expression; - -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ADD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AND__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___FLOORDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IAND__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IFLOORDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ILSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IMATMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IMOD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IOR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IPOW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IRSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ISUB__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ITRUEDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___IXOR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___LSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MATMUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MOD__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___MUL__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___OR__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___POW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___RSHIFT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___SUB__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___TRUEDIV__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___XOR__; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.function.Signature; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.expression.BinaryArithmetic.CallBinaryArithmeticRootNode; -import com.oracle.graal.python.nodes.expression.TernaryArithmetic.CallTernaryArithmeticRootNode; -import com.oracle.graal.python.util.Supplier; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.strings.TruffleString; - -public enum InplaceArithmetic { - IAdd(SpecialMethodSlot.IAdd, T___ADD__, "+=", BinaryArithmetic.Add), - ISub(T___ISUB__, T___SUB__, "-=", BinaryArithmetic.Sub), - IMul(SpecialMethodSlot.IMul, T___MUL__, "*=", BinaryArithmetic.Mul), - ITrueDiv(T___ITRUEDIV__, T___TRUEDIV__, "/=", BinaryArithmetic.TrueDiv), - IFloorDiv(T___IFLOORDIV__, T___FLOORDIV__, "//=", BinaryArithmetic.FloorDiv), - IMod(T___IMOD__, T___MOD__, "%=", BinaryArithmetic.Mod), - IPow(T___IPOW__, T___POW__, "**=", BinaryArithmetic.Pow, true), - ILShift(T___ILSHIFT__, T___LSHIFT__, "<<=", BinaryArithmetic.LShift), - IRShift(T___IRSHIFT__, T___RSHIFT__, ">>=", BinaryArithmetic.RShift), - IAnd(T___IAND__, T___AND__, "&=", BinaryArithmetic.And), - IOr(T___IOR__, T___OR__, "|=", BinaryArithmetic.Or), - IXor(T___IXOR__, T___XOR__, "^=", BinaryArithmetic.Xor), - IMatMul(T___IMATMUL__, T___MATMUL__, "@", BinaryArithmetic.MatMul); - - final TruffleString methodName; - final SpecialMethodSlot slot; - final boolean isTernary; - final Supplier notImplementedHandler; - final BinaryArithmetic binary; - final TruffleString binaryOpName; - - InplaceArithmetic(TruffleString methodName, TruffleString binaryOpName, String operator, BinaryArithmetic binary) { - this(methodName, binaryOpName, operator, binary, false); - } - - InplaceArithmetic(SpecialMethodSlot slot, TruffleString binaryOpName, String operator, BinaryArithmetic binary) { - this(slot.getName(), binaryOpName, operator, binary, false, slot); - } - - InplaceArithmetic(TruffleString methodName, TruffleString binaryOpName, String operator, BinaryArithmetic binary, boolean isTernary) { - this(methodName, binaryOpName, operator, binary, isTernary, null); - } - - InplaceArithmetic(TruffleString methodName, TruffleString binaryOpName, @SuppressWarnings("unused") String operator, BinaryArithmetic binary, boolean isTernary, SpecialMethodSlot slot) { - assert methodName.toJavaStringUncached().startsWith("__i") && methodName.toJavaStringUncached().substring(3).equals(binaryOpName.toJavaStringUncached().substring(2)); - this.methodName = methodName; - this.binary = binary; - this.isTernary = isTernary; - this.binaryOpName = binaryOpName; - this.slot = slot; - - this.notImplementedHandler = () -> new LookupAndCallInplaceNode.NotImplementedHandler() { - @Child private PRaiseNode raiseNode = PRaiseNode.create(); - - @Override - public Object execute(Object arg, Object arg2) { - throw raiseNode.raise(TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_AND_P, operator, arg, arg2); - } - }; - } - - public TruffleString getMethodName() { - return methodName; - } - - public boolean isTernary() { - return isTernary; - } - - /** - * A helper root node that dispatches to {@link LookupAndCallInplaceNode} to execute the - * provided in-place operator. This node is mostly useful to use such operators from a location - * without a frame (e.g. from interop). Note: this is just a root node and won't do any - * signature checking. - */ - static final class CallInplaceArithmeticRootNode extends CallArithmeticRootNode { - - @Child private LookupAndCallInplaceNode callInplaceNode; - - private final InplaceArithmetic inplaceOperator; - - CallInplaceArithmeticRootNode(PythonLanguage language, InplaceArithmetic inplaceOperator) { - super(language); - this.inplaceOperator = inplaceOperator; - } - - @Override - public Signature getSignature() { - if (inplaceOperator.isTernary()) { - return CallTernaryArithmeticRootNode.SIGNATURE_TERNARY; - } - return CallBinaryArithmeticRootNode.SIGNATURE_BINARY; - } - - @Override - protected Object doCall(VirtualFrame frame) { - if (callInplaceNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - callInplaceNode = insert(inplaceOperator.create()); - } - // most of the in-place operators are binary but there can also be ternary - if (inplaceOperator.isTernary()) { - return callInplaceNode.executeTernary(frame, PArguments.getArgument(frame, 0), PArguments.getArgument(frame, 1), PArguments.getArgument(frame, 2)); - } - return callInplaceNode.execute(frame, PArguments.getArgument(frame, 0), PArguments.getArgument(frame, 1)); - } - } - - public LookupAndCallInplaceNode create() { - return LookupAndCallInplaceNode.create(this); - } - - /** - * Creates a root node for this in-place operator such that the operator can be executed via a - * full call. - */ - public RootNode createRootNode(PythonLanguage language) { - return new CallInplaceArithmeticRootNode(language, this); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/LookupAndCallInplaceNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/LookupAndCallInplaceNode.java deleted file mode 100644 index 5753161223..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/LookupAndCallInplaceNode.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.expression; - -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; -import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; -import com.oracle.graal.python.nodes.attributes.LookupInMROBaseNode; -import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallTernaryNode; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; - -public abstract class LookupAndCallInplaceNode extends PNodeWithContext implements BinaryOp { - - public abstract static class NotImplementedHandler extends PNodeWithContext { - public abstract Object execute(Object arg, Object arg2); - } - - @Child private CallBinaryMethodNode callBinaryMethodNode; - @Child private BinaryOpNode binaryOpNode; - @Child private LookupAndCallTernaryNode lookupAndCallTernaryNode; - @Child private NotImplementedHandler handler; - - final InplaceArithmetic arithmetic; - - LookupAndCallInplaceNode(InplaceArithmetic arithmetic) { - this.arithmetic = arithmetic; - } - - public static LookupAndCallInplaceNode create(InplaceArithmetic arithmetic) { - return LookupAndCallInplaceNodeGen.create(arithmetic); - } - - private CallBinaryMethodNode ensureBinaryCallNode() { - if (callBinaryMethodNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - callBinaryMethodNode = insert(CallBinaryMethodNode.create()); - } - return callBinaryMethodNode; - } - - private BinaryOpNode ensureLookupAndCallBinaryNode() { - if (binaryOpNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - binaryOpNode = insert(arithmetic.binary.create()); - } - return binaryOpNode; - } - - private LookupAndCallTernaryNode ensureLookupAndCallTernaryNode() { - if (lookupAndCallTernaryNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - lookupAndCallTernaryNode = insert(LookupAndCallTernaryNode.createReversible(arithmetic.binaryOpName, null)); - } - return lookupAndCallTernaryNode; - } - - @Override - public final Object executeObject(VirtualFrame frame, Object left, Object right) { - return execute(frame, left, right); - } - - public final Object execute(VirtualFrame frame, Object left, Object right) { - return executeTernary(frame, left, right, PNone.NO_VALUE); - } - - public abstract Object executeTernary(VirtualFrame frame, Object x, Object y, Object z); - - @NeverDefault - protected final LookupInMROBaseNode createInplaceLookup() { - if (arithmetic.slot != null) { - return LookupCallableSlotInMRONode.create(arithmetic.slot); - } else { - return LookupAttributeInMRONode.create(arithmetic.methodName); - } - } - - @Specialization - Object doBinary(VirtualFrame frame, Object left, Object right, Object z, - @Bind("this") Node inliningTarget, - @Cached GetClassNode getClassNode, - @Cached("createInplaceLookup()") LookupInMROBaseNode lookupInplace) { - Object result; - Object inplaceCallable = lookupInplace.execute(getClassNode.execute(inliningTarget, left)); - if (inplaceCallable != PNone.NO_VALUE) { - // nb.: The only ternary in-place operator is '__ipow__' but according to 'typeobject.c: - // slot_nb_inplace_power', this is always called as binary. - result = ensureBinaryCallNode().executeObject(frame, inplaceCallable, left, right); - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - } - - // try non-inplace variant - boolean isBinary = PGuards.isPNone(z); - if (isBinary) { - result = ensureLookupAndCallBinaryNode().executeObject(frame, left, right); - } else { - result = ensureLookupAndCallTernaryNode().execute(frame, left, right, z); - } - if (result != PNotImplemented.NOT_IMPLEMENTED) { - return result; - } - if (handler == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - handler = insert(arithmetic.notImplementedHandler.get()); - } - return handler.execute(left, right); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/TernaryArithmetic.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/TernaryArithmetic.java deleted file mode 100644 index 1a83d7d96e..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/TernaryArithmetic.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.expression; - -import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; -import static com.oracle.graal.python.util.PythonUtils.tsArray; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.function.Signature; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.SpecialMethodNames; -import com.oracle.graal.python.nodes.call.special.LookupAndCallTernaryNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallTernaryNode.NotImplementedHandler; -import com.oracle.graal.python.util.Supplier; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.strings.TruffleString; - -public enum TernaryArithmetic { - Pow(SpecialMethodNames.T___POW__, "**", "pow"); - - private final TruffleString methodName; - private final Supplier notImplementedHandler; - - TernaryArithmetic(TruffleString methodName, @SuppressWarnings("unused") String operator, String operatorFunction) { - this.methodName = methodName; - this.notImplementedHandler = () -> new NotImplementedHandler() { - @Child private PRaiseNode raiseNode = PRaiseNode.create(); - - @Override - public Object execute(Object arg, Object arg2, Object arg3) { - if (arg3 instanceof PNone) { - throw raiseNode.raise(TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_PR_S_P_AND_P, operator, operatorFunction, arg, arg2); - } else { - throw raiseNode.raise(TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_FOR_S_P_P_P, operatorFunction, arg, arg2, arg3); - } - } - }; - } - - public TruffleString getMethodName() { - return methodName; - } - - /** - * A helper root node that dispatches to {@link LookupAndCallTernaryNode} to execute the - * provided ternary operator. This node is mostly useful to use such operators from a location - * without a frame (e.g. from interop). Note: this is just a root node and won't do any - * signature checking. - */ - static final class CallTernaryArithmeticRootNode extends CallArithmeticRootNode { - static final Signature SIGNATURE_TERNARY = new Signature(3, false, -1, false, tsArray("x", "y", "z"), null); - - @Child private LookupAndCallTernaryNode callTernaryNode; - - private final TernaryArithmetic ternaryOperator; - - private CallTernaryArithmeticRootNode(PythonLanguage language, TernaryArithmetic ternaryOperator) { - super(language); - this.ternaryOperator = ternaryOperator; - } - - @Override - public Signature getSignature() { - return SIGNATURE_TERNARY; - } - - @Override - protected Object doCall(VirtualFrame frame) { - if (callTernaryNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - callTernaryNode = insert(ternaryOperator.create()); - } - return callTernaryNode.execute(frame, PArguments.getArgument(frame, 0), PArguments.getArgument(frame, 1), PArguments.getArgument(frame, 2)); - } - } - - public LookupAndCallTernaryNode create() { - return LookupAndCallTernaryNode.createReversible(methodName, notImplementedHandler); - } - - /** - * Creates a root node for this ternary operator such that the operator can be executed via a - * full call. - */ - public RootNode createRootNode(PythonLanguage language) { - return new CallTernaryArithmeticRootNode(language, this); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/UnaryArithmetic.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/UnaryArithmetic.java deleted file mode 100644 index fc64f03be0..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/UnaryArithmetic.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.expression; - -import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; -import static com.oracle.graal.python.util.PythonUtils.tsArray; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.function.Signature; -import com.oracle.graal.python.lib.PyNumberInvertNode; -import com.oracle.graal.python.lib.PyNumberNegativeNode; -import com.oracle.graal.python.lib.PyNumberPositiveNode; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.SpecialMethodNames; -import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; -import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode.NoAttributeHandler; -import com.oracle.graal.python.util.Supplier; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.strings.TruffleString; - -public enum UnaryArithmetic { - Pos(PyNumberPositiveNode::create), - Neg(PyNumberNegativeNode::create), - Invert(PyNumberInvertNode::create); - - interface CreateUnaryOp { - UnaryOpNode create(); - } - - private final CreateUnaryOp create; - - UnaryArithmetic(CreateUnaryOp create) { - this.create = create; - } - - /** - * A helper root node that dispatches to {@link LookupAndCallUnaryNode} to execute the provided - * unary operator. This node is mostly useful to use such operators from a location without a - * frame (e.g. from interop). Note: this is just a root node and won't do any signature - * checking. - */ - static final class CallUnaryArithmeticRootNode extends CallArithmeticRootNode { - private static final Signature SIGNATURE_UNARY = new Signature(1, false, -1, false, tsArray("$self"), null); - - @Child private UnaryOpNode callUnaryNode; - - private final UnaryArithmetic unaryOperator; - - CallUnaryArithmeticRootNode(PythonLanguage language, UnaryArithmetic unaryOperator) { - super(language); - this.unaryOperator = unaryOperator; - } - - @Override - public Signature getSignature() { - return SIGNATURE_UNARY; - } - - @Override - protected Object doCall(VirtualFrame frame) { - if (callUnaryNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - callUnaryNode = insert(unaryOperator.create()); - } - return callUnaryNode.executeCached(frame, PArguments.getArgument(frame, 0)); - } - } - - public UnaryOpNode create() { - return create.create(); - } - - /** - * Creates a root node for this unary operator such that the operator can be executed via a full - * call. - */ - public RootNode createRootNode(PythonLanguage language) { - return new CallUnaryArithmeticRootNode(language, this); - } - - @ImportStatic(SpecialMethodNames.class) - public abstract static class UnaryArithmeticNode extends UnaryOpNode { - - static Supplier createHandler(String operator) { - - return () -> new NoAttributeHandler() { - @Child private PRaiseNode raiseNode = PRaiseNode.create(); - - @Override - public Object execute(Object receiver) { - throw raiseNode.raise(TypeError, ErrorMessages.BAD_OPERAND_FOR, "unary ", operator, receiver); - } - }; - } - - @NeverDefault - public static LookupAndCallUnaryNode createCallNode(TruffleString name, Supplier handler) { - return LookupAndCallUnaryNode.create(name, handler); - } - } - - @GenerateCached - public abstract static class GenericUnaryArithmeticNode extends UnaryArithmeticNode { - - private final TruffleString specialMethodName; - - protected GenericUnaryArithmeticNode(TruffleString specialMethodName) { - this.specialMethodName = specialMethodName; - } - - public final Object execute(VirtualFrame frame, Node inliningTarget, Object value) { - return execute(frame, value); - } - - protected abstract Object execute(VirtualFrame frame, Object value); - - @Specialization - public static Object doGeneric(VirtualFrame frame, Object arg, - @Cached("createCallNode()") LookupAndCallUnaryNode callNode) { - return callNode.executeObject(frame, arg); - } - - @NeverDefault - protected LookupAndCallUnaryNode createCallNode() { - return createCallNode(specialMethodName, createHandler(specialMethodName.toString())); - } - - @NeverDefault - public static GenericUnaryArithmeticNode create(TruffleString specialMethodName) { - return UnaryArithmeticFactory.GenericUnaryArithmeticNodeGen.create(specialMethodName); - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/UnaryOpNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/UnaryOpNode.java index 15e1bdd0ed..23d41297ca 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/UnaryOpNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/UnaryOpNode.java @@ -29,5 +29,5 @@ import com.oracle.truffle.api.frame.VirtualFrame; public abstract class UnaryOpNode extends PNodeWithContext { - public abstract Object executeCached(VirtualFrame frame, Object value); + public abstract Object execute(VirtualFrame frame, Object value); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/DeleteGlobalNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/DeleteGlobalNode.java index e24332f33f..c5278467fb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/DeleteGlobalNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/DeleteGlobalNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,13 +43,14 @@ import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.lib.PyObjectDelItem; +import com.oracle.graal.python.lib.PyObjectSetAttr; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.attributes.DeleteAttributeNode; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @@ -58,6 +59,7 @@ @GenerateUncached @SuppressWarnings("truffle-inlining") // footprint reduction 52 -> 36 public abstract class DeleteGlobalNode extends PNodeWithContext { + @NeverDefault public static DeleteGlobalNode create() { return DeleteGlobalNodeGen.create(); } @@ -88,14 +90,14 @@ static void deleteDict(VirtualFrame frame, PDict globals, TruffleString attribut static void deleteModuleCached(VirtualFrame frame, @SuppressWarnings("unused") PythonModule globals, TruffleString attributeId, @Bind("this") Node inliningTarget, @Cached(value = "globals", weak = true) PythonModule cachedGlobals, - @Shared @Cached DeleteAttributeNode storeNode) { - storeNode.execute(frame, inliningTarget, cachedGlobals, attributeId); + @Shared @Cached PyObjectSetAttr setAttr) { + setAttr.delete(frame, inliningTarget, cachedGlobals, attributeId); } @Specialization(replaces = "deleteModuleCached") static void deleteModule(VirtualFrame frame, PythonModule globals, TruffleString attributeId, @Bind("this") Node inliningTarget, - @Shared @Cached DeleteAttributeNode storeNode) { - storeNode.execute(frame, inliningTarget, globals, attributeId); + @Shared @Cached PyObjectSetAttr setAttr) { + setAttr.delete(frame, inliningTarget, globals, attributeId); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/GetFrameLocalsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/GetFrameLocalsNode.java index 34d03bad18..27cded0b2a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/GetFrameLocalsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/GetFrameLocalsNode.java @@ -40,6 +40,7 @@ */ package com.oracle.graal.python.nodes.frame; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.cell.PCell; import com.oracle.graal.python.builtins.objects.common.HashingStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageDelItem; @@ -48,8 +49,13 @@ import com.oracle.graal.python.builtins.objects.frame.PFrame; import com.oracle.graal.python.compiler.CodeUnit; import com.oracle.graal.python.lib.PyDictGetItem; +import com.oracle.graal.python.nodes.PRootNode; import com.oracle.graal.python.nodes.bytecode.FrameInfo; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.nodes.bytecode_dsl.BytecodeDSLFrameInfo; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode; +import com.oracle.graal.python.runtime.PythonOptions; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.bytecode.BytecodeNode; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -64,6 +70,7 @@ import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.strings.TruffleString; /** @@ -86,14 +93,15 @@ public static Object executeUncached(PFrame pyFrame) { } @Specialization(guards = "!pyFrame.hasCustomLocals()") - static Object doLoop(PFrame pyFrame, - @Cached(inline = false) PythonObjectFactory factory, + static Object doLoop(Node inliningTarget, PFrame pyFrame, + @Cached InlinedBranchProfile create, @Cached(inline = false) CopyLocalsToDict copyLocalsToDict) { MaterializedFrame locals = pyFrame.getLocals(); // It doesn't have custom locals, so it has to be a builtin dict or null PDict localsDict = (PDict) pyFrame.getLocalsDict(); if (localsDict == null) { - localsDict = factory.createDict(); + create.enter(inliningTarget); + localsDict = PFactory.createDict(PythonLanguage.get(inliningTarget)); pyFrame.setLocalsDict(localsDict); } copyLocalsToDict.execute(locals, localsDict); @@ -121,10 +129,19 @@ void doCachedFd(MaterializedFrame locals, PDict dict, @Bind("info.getVariableCount()") int count, @Shared("setItem") @Cached HashingStorageSetItem setItem, @Shared("delItem") @Cached HashingStorageDelItem delItem) { - CodeUnit co = info.getRootNode().getCodeUnit(); - int regularVarCount = co.varnames.length; - for (int i = 0; i < count; i++) { - copyItem(inliningTarget, locals, info, dict, setItem, delItem, i, i >= regularVarCount); + int regularVarCount = info.getRegularVariableCount(); + + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + BytecodeDSLFrameInfo bytecodeDSLFrameInfo = (BytecodeDSLFrameInfo) info; + PBytecodeDSLRootNode rootNode = bytecodeDSLFrameInfo.getRootNode(); + Object[] localsArray = rootNode.getBytecodeNode().getLocalValues(0, locals); + for (int i = 0; i < count; i++) { + copyItem(inliningTarget, localsArray[i], info, dict, setItem, delItem, i, i >= regularVarCount); + } + } else { + for (int i = 0; i < count; i++) { + copyItem(inliningTarget, locals.getValue(i), info, dict, setItem, delItem, i, i >= regularVarCount); + } } } @@ -135,16 +152,25 @@ void doGeneric(MaterializedFrame locals, PDict dict, @Shared("delItem") @Cached HashingStorageDelItem delItem) { FrameInfo info = getInfo(locals.getFrameDescriptor()); int count = info.getVariableCount(); - CodeUnit co = info.getRootNode().getCodeUnit(); - int regularVarCount = co.varnames.length; - for (int i = 0; i < count; i++) { - copyItem(inliningTarget, locals, info, dict, setItem, delItem, i, i >= regularVarCount); + int regularVarCount = info.getRegularVariableCount(); + + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + BytecodeDSLFrameInfo bytecodeDSLFrameInfo = (BytecodeDSLFrameInfo) info; + PBytecodeDSLRootNode rootNode = bytecodeDSLFrameInfo.getRootNode(); + Object[] localsArray = rootNode.getBytecodeNode().getLocalValues(0, locals); + for (int i = 0; i < count; i++) { + copyItem(inliningTarget, localsArray[i], info, dict, setItem, delItem, i, i >= regularVarCount); + } + } else { + for (int i = 0; i < count; i++) { + copyItem(inliningTarget, locals.getValue(i), info, dict, setItem, delItem, i, i >= regularVarCount); + } } } - private static void copyItem(Node inliningTarget, MaterializedFrame locals, FrameInfo info, PDict dict, HashingStorageSetItem setItem, HashingStorageDelItem delItem, int i, boolean deref) { + private static void copyItem(Node inliningTarget, Object localValue, FrameInfo info, PDict dict, HashingStorageSetItem setItem, HashingStorageDelItem delItem, int i, boolean deref) { TruffleString name = info.getVariableName(i); - Object value = locals.getValue(i); + Object value = localValue; if (deref && value != null) { value = ((PCell) value).getRef(); } @@ -165,24 +191,39 @@ protected static FrameInfo getInfo(FrameDescriptor fd) { /** * Equivalent of CPython's {@code PyFrame_LocalsToFast} */ - public static void syncLocalsBackToFrame(CodeUnit co, PFrame pyFrame, Frame localFrame) { + public static void syncLocalsBackToFrame(CodeUnit co, PRootNode root, PFrame pyFrame, Frame localFrame) { if (!pyFrame.hasCustomLocals()) { PDict localsDict = (PDict) pyFrame.getLocalsDict(); - copyLocalsArray(localFrame, localsDict, co.varnames, 0, false); - copyLocalsArray(localFrame, localsDict, co.cellvars, co.varnames.length, true); - copyLocalsArray(localFrame, localsDict, co.freevars, co.varnames.length + co.cellvars.length, true); + copyLocalsArray(localFrame, root, localsDict, co.varnames, 0, false); + copyLocalsArray(localFrame, root, localsDict, co.cellvars, co.varnames.length, true); + copyLocalsArray(localFrame, root, localsDict, co.freevars, co.varnames.length + co.cellvars.length, true); } } - private static void copyLocalsArray(Frame localFrame, PDict localsDict, TruffleString[] namesArray, int offset, boolean deref) { - for (int i = 0; i < namesArray.length; i++) { - TruffleString varname = namesArray[i]; - Object value = PyDictGetItem.executeUncached(localsDict, varname); - if (deref) { - PCell cell = (PCell) localFrame.getObject(offset + i); - cell.setRef(value); - } else { - localFrame.setObject(offset + i, value); + private static void copyLocalsArray(Frame localFrame, PRootNode root, PDict localsDict, TruffleString[] namesArray, int offset, boolean deref) { + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + PBytecodeDSLRootNode bytecodeDSLRootNode = (PBytecodeDSLRootNode) root; + BytecodeNode bytecodeNode = bytecodeDSLRootNode.getBytecodeNode(); + for (int i = 0; i < namesArray.length; i++) { + TruffleString varname = namesArray[i]; + Object value = PyDictGetItem.executeUncached(localsDict, varname); + if (deref) { + PCell cell = (PCell) bytecodeNode.getLocalValue(0, localFrame, offset + i); + cell.setRef(value); + } else { + bytecodeNode.setLocalValue(0, localFrame, offset + i, value); + } + } + } else { + for (int i = 0; i < namesArray.length; i++) { + TruffleString varname = namesArray[i]; + Object value = PyDictGetItem.executeUncached(localsDict, varname); + if (deref) { + PCell cell = (PCell) localFrame.getObject(offset + i); + cell.setRef(value); + } else { + localFrame.setObject(offset + i, value); + } } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/MaterializeFrameNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/MaterializeFrameNode.java index 113f6234cc..396ecf6644 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/MaterializeFrameNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/MaterializeFrameNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,12 +40,18 @@ */ package com.oracle.graal.python.nodes.frame; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.frame.PFrame; import com.oracle.graal.python.builtins.objects.function.PArguments; +import com.oracle.graal.python.nodes.bytecode.BytecodeFrameInfo; import com.oracle.graal.python.nodes.bytecode.FrameInfo; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.nodes.bytecode_dsl.BytecodeDSLFrameInfo; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode; +import com.oracle.graal.python.runtime.PythonOptions; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.bytecode.BytecodeNode; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -107,39 +113,38 @@ public final PFrame execute(Frame frame, Node location, boolean markAsEscaped, b "!hasCustomLocals(frameToMaterialize)"}, limit = "1") static PFrame freshPFrameCachedFD(Node location, boolean markAsEscaped, boolean forceSync, Frame frameToMaterialize, @Cached(value = "frameToMaterialize.getFrameDescriptor()") FrameDescriptor cachedFD, - @Shared("factory") @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Shared("syncValuesNode") @Cached SyncFrameValuesNode syncValuesNode) { MaterializedFrame locals = createLocalsFrame(cachedFD); - PFrame escapedFrame = factory.createPFrame(PArguments.getCurrentFrameInfo(frameToMaterialize), location, locals); - return doEscapeFrame(frameToMaterialize, escapedFrame, markAsEscaped, forceSync, syncValuesNode); + PFrame escapedFrame = PFactory.createPFrame(language, PArguments.getCurrentFrameInfo(frameToMaterialize), location, locals); + return doEscapeFrame(frameToMaterialize, escapedFrame, markAsEscaped, forceSync, location, syncValuesNode); } @Specialization(guards = {"getPFrame(frameToMaterialize) == null", "!hasGeneratorFrame(frameToMaterialize)", "!hasCustomLocals(frameToMaterialize)"}, replaces = "freshPFrameCachedFD") static PFrame freshPFrame(Node location, boolean markAsEscaped, boolean forceSync, Frame frameToMaterialize, - @Shared("factory") @Cached PythonObjectFactory factory, + @Bind PythonLanguage language, @Shared("syncValuesNode") @Cached SyncFrameValuesNode syncValuesNode) { MaterializedFrame locals = createLocalsFrame(frameToMaterialize.getFrameDescriptor()); - PFrame escapedFrame = factory.createPFrame(PArguments.getCurrentFrameInfo(frameToMaterialize), location, locals); - return doEscapeFrame(frameToMaterialize, escapedFrame, markAsEscaped, forceSync, syncValuesNode); + PFrame escapedFrame = PFactory.createPFrame(language, PArguments.getCurrentFrameInfo(frameToMaterialize), location, locals); + return doEscapeFrame(frameToMaterialize, escapedFrame, markAsEscaped, forceSync, location, syncValuesNode); } @Specialization(guards = {"getPFrame(frameToMaterialize) == null", "!hasGeneratorFrame(frameToMaterialize)", "hasCustomLocals(frameToMaterialize)"}) static PFrame freshPFrameCusstomLocals(Node location, boolean markAsEscaped, @SuppressWarnings("unused") boolean forceSync, Frame frameToMaterialize, - @Shared("factory") @Cached PythonObjectFactory factory) { - PFrame escapedFrame = factory.createPFrame(PArguments.getCurrentFrameInfo(frameToMaterialize), location, null); + @Bind PythonLanguage language) { + PFrame escapedFrame = PFactory.createPFrame(language, PArguments.getCurrentFrameInfo(frameToMaterialize), location, null); escapedFrame.setLocalsDict(PArguments.getSpecialArgument(frameToMaterialize)); - return doEscapeFrame(frameToMaterialize, escapedFrame, markAsEscaped, false, null); + return doEscapeFrame(frameToMaterialize, escapedFrame, markAsEscaped, false, location, null); } @Specialization(guards = {"getPFrame(frameToMaterialize) == null", "hasGeneratorFrame(frameToMaterialize)"}) - static PFrame freshPFrameForGenerator(Node location, @SuppressWarnings("unused") boolean markAsEscaped, @SuppressWarnings("unused") boolean forceSync, Frame frameToMaterialize, - @Shared("factory") @Cached PythonObjectFactory factory) { + static PFrame freshPFrameForGenerator(Node location, @SuppressWarnings("unused") boolean markAsEscaped, @SuppressWarnings("unused") boolean forceSync, Frame frameToMaterialize) { MaterializedFrame generatorFrame = PArguments.getGeneratorFrame(frameToMaterialize); PFrame.Reference frameRef = PArguments.getCurrentFrameInfo(frameToMaterialize); - PFrame escapedFrame = materializeGeneratorFrame(location, generatorFrame, frameRef, factory); + PFrame escapedFrame = materializeGeneratorFrame(location, generatorFrame, frameRef); frameRef.setPyFrame(escapedFrame); - return doEscapeFrame(frameToMaterialize, escapedFrame, markAsEscaped, false, null); + return doEscapeFrame(frameToMaterialize, escapedFrame, markAsEscaped, false, location, null); } @Specialization(guards = "getPFrame(frameToMaterialize) != null") @@ -154,7 +159,7 @@ static PFrame alreadyEscapedFrame(@SuppressWarnings("unused") Node location, boo if (markAsEscaped) { pyFrame.getRef().markAsEscaped(); } - processBytecodeFrame(frameToMaterialize, pyFrame); + processBytecodeFrame(frameToMaterialize, pyFrame, location); return pyFrame; } @@ -162,22 +167,40 @@ private static MaterializedFrame createLocalsFrame(FrameDescriptor cachedFD) { return Truffle.getRuntime().createMaterializedFrame(PythonUtils.EMPTY_OBJECT_ARRAY, cachedFD); } - public static PFrame materializeGeneratorFrame(Node location, MaterializedFrame generatorFrame, PFrame.Reference frameRef, PythonObjectFactory factory) { - PFrame escapedFrame = factory.createPFrame(frameRef, location, generatorFrame); + public static PFrame materializeGeneratorFrame(Node location, MaterializedFrame generatorFrame, PFrame.Reference frameRef) { + PFrame escapedFrame = PFactory.createPFrame(PythonLanguage.get(location), frameRef, location, generatorFrame); PArguments.synchronizeArgs(generatorFrame, escapedFrame); return escapedFrame; } - private static void processBytecodeFrame(Frame frameToMaterialize, PFrame pyFrame) { - FrameInfo info = (FrameInfo) frameToMaterialize.getFrameDescriptor().getInfo(); - if (info != null) { - pyFrame.setBci(info.getBci(frameToMaterialize)); - pyFrame.setLocation(info.getRootNode()); + private static void processBytecodeFrame(Frame frameToMaterialize, PFrame pyFrame, Node location) { + Object info = frameToMaterialize.getFrameDescriptor().getInfo(); + if (info == null) { + return; + } + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + BytecodeNode bytecodeNode = BytecodeNode.get(location); + if (bytecodeNode == null) { + /** + * Sometimes we don't have a precise location (see + * {@link ReadCallerFrameNode#getFrame}). Set bci to -1 to mark the location as + * unknown. + */ + pyFrame.setBci(-1); + pyFrame.setLocation(location); + } else { + pyFrame.setBci(bytecodeNode.getBytecodeIndex(frameToMaterialize)); + pyFrame.setLocation(bytecodeNode); + } + } else { + BytecodeFrameInfo bytecodeFrameInfo = (BytecodeFrameInfo) info; + pyFrame.setBci(bytecodeFrameInfo.getBci(frameToMaterialize)); + pyFrame.setLocation(bytecodeFrameInfo.getRootNode()); } } private static PFrame doEscapeFrame(Frame frameToMaterialize, PFrame escapedFrame, boolean markAsEscaped, boolean forceSync, - SyncFrameValuesNode syncValuesNode) { + Node location, SyncFrameValuesNode syncValuesNode) { PFrame.Reference topFrameRef = PArguments.getCurrentFrameInfo(frameToMaterialize); topFrameRef.setPyFrame(escapedFrame); @@ -189,12 +212,13 @@ private static PFrame doEscapeFrame(Frame frameToMaterialize, PFrame escapedFram if (markAsEscaped) { topFrameRef.markAsEscaped(); } - processBytecodeFrame(frameToMaterialize, escapedFrame); + processBytecodeFrame(frameToMaterialize, escapedFrame, location); return escapedFrame; } protected static boolean hasGeneratorFrame(Frame frame) { - return PArguments.getGeneratorFrame(frame) != null; + return !PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER && + PArguments.getGeneratorFrame(frame) != null; } protected static boolean hasCustomLocals(Frame frame) { @@ -216,7 +240,8 @@ public abstract static class SyncFrameValuesNode extends Node { public abstract void execute(PFrame pyFrame, Frame frameToSync); - @Specialization(guards = {"!pyFrame.hasCustomLocals()", "frameToSync.getFrameDescriptor() == cachedFd", + @Specialization(guards = {"!pyFrame.hasCustomLocals()", + "frameToSync.getFrameDescriptor() == cachedFd", "variableSlotCount(cachedFd) < 32"}, limit = "1") @ExplodeLoop static void doSyncExploded(PFrame pyFrame, Frame frameToSync, @@ -224,17 +249,37 @@ static void doSyncExploded(PFrame pyFrame, Frame frameToSync, MaterializedFrame target = pyFrame.getLocals(); assert cachedFd == target.getFrameDescriptor(); int slotCount = variableSlotCount(cachedFd); - for (int slot = 0; slot < slotCount; slot++) { - PythonUtils.copyFrameSlot(frameToSync, target, slot); + + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + FrameInfo info = (FrameInfo) cachedFd.getInfo(); + if (info instanceof BytecodeDSLFrameInfo bytecodeDSLFrameInfo) { + PBytecodeDSLRootNode rootNode = bytecodeDSLFrameInfo.getRootNode(); + rootNode.getBytecodeNode().copyLocalValues(0, frameToSync, target, 0, slotCount); + } + } else { + for (int i = 0; i < slotCount; i++) { + PythonUtils.copyFrameSlot(frameToSync, target, i); + } } } @Specialization(guards = "!pyFrame.hasCustomLocals()", replaces = "doSyncExploded") - static void doSyncLoop(PFrame pyFrame, Frame frameToSync) { + @ExplodeLoop + static void doSync(PFrame pyFrame, Frame frameToSync) { MaterializedFrame target = pyFrame.getLocals(); - int slotCount = variableSlotCount(frameToSync.getFrameDescriptor()); - for (int slot = 0; slot < slotCount; slot++) { - PythonUtils.copyFrameSlot(frameToSync, target, slot); + FrameDescriptor fd = target.getFrameDescriptor(); + int slotCount = variableSlotCount(fd); + + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + FrameInfo info = (FrameInfo) fd.getInfo(); + if (info instanceof BytecodeDSLFrameInfo bytecodeDSLFrameInfo) { + PBytecodeDSLRootNode rootNode = bytecodeDSLFrameInfo.getRootNode(); + rootNode.getBytecodeNode().copyLocalValues(0, frameToSync, target, 0, slotCount); + } + } else { + for (int i = 0; i < slotCount; i++) { + PythonUtils.copyFrameSlot(frameToSync, target, i); + } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadCallerFrameNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadCallerFrameNode.java index cb377ffbd2..82084a442b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadCallerFrameNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadCallerFrameNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,17 +42,16 @@ import java.util.Objects; -import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.frame.PFrame; import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.nodes.PRootNode; import com.oracle.graal.python.runtime.IndirectCallData; -import com.oracle.graal.python.runtime.PythonContext; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.bytecode.ContinuationRootNode; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameInstance; @@ -274,26 +273,22 @@ public static Frame getCallerFrame(PFrame.Reference startFrame, FrameInstance.Fr @TruffleBoundary private static Frame getFrame(Node requestingNode, PFrame.Reference startFrame, FrameInstance.FrameAccess frameAccess, FrameSelector selector, int level) { - final Frame[] outputFrame = new Frame[1]; - Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor() { + Frame[] outputFrame = new Frame[1]; + Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<>() { int i = -1; /** * We may find the Python frame at the level we desire, but the {@link PRootNode} - * associated with it may have been called from a different language, and thus not have - * Python {@link IndirectCallData}. That means that we cannot immediately return when we + * associated with it may have been called from a different language, and thus not be + * able to pass the caller frame. That means that we cannot immediately return when we * find the correct level frame, but instead we need to remember the frame in * {@code outputFrame} and then keep going until we find the previous Python caller on - * the stack (or not). That last Python caller before the Python frame we need must push - * the info. - * - * This can easily be seen when this is used to - * {@link PythonContext#peekTopFrameInfo(PythonLanguage)} , because in that case, that - * info must be set by the caller that is somewhere up the stack. + * the stack (or not). That last Python caller should have {@link IndirectCallData} that + * will be marked to pass the frame through the context. * *

                    *                      ================
      -             *                   ,>| PythonCallNode |
      +             *                   ,>| IndirectCallData |
                    *                   |  ================
                    *                   | |  LLVMRootNode  |
                    *                   | |  LLVMCallNode  |
      @@ -308,14 +303,16 @@ private static Frame getFrame(Node requestingNode, PFrame.Reference startFrame,
                    * 
      */ public Frame visitFrame(FrameInstance frameInstance) { - RootCallTarget target = (RootCallTarget) frameInstance.getCallTarget(); - RootNode rootNode = target.getRootNode(); + RootNode rootNode = getRootNode(frameInstance); Node callNode = frameInstance.getCallNode(); boolean didMark = IndirectCallData.setEncapsulatingNeedsToPassCallerFrame(callNode != null ? callNode : requestingNode); - if (outputFrame[0] == null && rootNode instanceof PRootNode pRootNode && pRootNode.setsUpCalleeContext()) { - pRootNode.setNeedsCallerFrame(); + if (rootNode instanceof PRootNode pRootNode && pRootNode.setsUpCalleeContext()) { + if (outputFrame[0] != null) { + return outputFrame[0]; + } + boolean needsCallerFrame = true; if (i < 0 && startFrame != null) { - Frame roFrame = frameInstance.getFrame(FrameInstance.FrameAccess.READ_ONLY); + Frame roFrame = getFrame(frameInstance, FrameInstance.FrameAccess.READ_ONLY); if (PArguments.getCurrentFrameInfo(roFrame) == startFrame) { i = 0; } @@ -324,7 +321,7 @@ public Frame visitFrame(FrameInstance frameInstance) { // a Python frame in CPython. if (!selector.skip(pRootNode)) { if (i == level || startFrame == null) { - Frame frame = frameInstance.getFrame(frameAccess); + Frame frame = getFrame(frameInstance, frameAccess); assert PArguments.isPythonFrame(frame); PFrame.Reference info = PArguments.getCurrentFrameInfo(frame); // avoid overriding the location if we don't know it @@ -340,10 +337,14 @@ public Frame visitFrame(FrameInstance frameInstance) { // cannot materialize it. assert info.getCallNode() != null : "tried to read frame without location (root: " + pRootNode + ")"; outputFrame[0] = frame; + needsCallerFrame = false; } i += 1; } } + if (needsCallerFrame) { + pRootNode.setNeedsCallerFrame(); + } } if (didMark) { return outputFrame[0]; @@ -355,6 +356,25 @@ public Frame visitFrame(FrameInstance frameInstance) { return outputFrame[0]; } + private static RootNode getRootNode(FrameInstance frameInstance) { + RootCallTarget target = (RootCallTarget) frameInstance.getCallTarget(); + RootNode rootNode = target.getRootNode(); + if (rootNode instanceof ContinuationRootNode continuationRoot) { + return (RootNode) continuationRoot.getSourceRootNode(); + } + return rootNode; + } + + private static Frame getFrame(FrameInstance frameInstance, FrameInstance.FrameAccess frameAccess) { + Frame frame = frameInstance.getFrame(frameAccess); + + RootCallTarget target = (RootCallTarget) frameInstance.getCallTarget(); + if (target.getRootNode() instanceof ContinuationRootNode) { + return (Frame) frame.getArguments()[0]; + } + return frame; + } + private MaterializeFrameNode ensureMaterializeNode() { if (materializeNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadGlobalOrBuiltinNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadGlobalOrBuiltinNode.java index 465481c0aa..d91eaef145 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadGlobalOrBuiltinNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadGlobalOrBuiltinNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -215,7 +215,7 @@ abstract class ReadBuiltinNode extends PNodeWithContext { @Specialization(guards = "isSingleContext(this)") Object returnBuiltinFromConstantModule(TruffleString attributeId, @Bind("this") Node inliningTarget, - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Exclusive @Cached InlinedConditionProfile isBuiltinProfile, @Shared @Cached ReadAttributeFromObjectNode readFromBuiltinsNode, @SuppressWarnings("unused") @Cached("getBuiltins()") PythonModule builtins) { @@ -223,15 +223,15 @@ Object returnBuiltinFromConstantModule(TruffleString attributeId, } @InliningCutoff - private static PException raiseNameNotDefined(PRaiseNode raiseNode, TruffleString attributeId) { - throw raiseNode.raise(NameError, ErrorMessages.NAME_NOT_DEFINED, attributeId); + private static PException raiseNameNotDefined(Node inliningTarget, PRaiseNode raiseNode, TruffleString attributeId) { + throw raiseNode.raise(inliningTarget, NameError, ErrorMessages.NAME_NOT_DEFINED, attributeId); } @InliningCutoff @Specialization(replaces = "returnBuiltinFromConstantModule") Object returnBuiltin(TruffleString attributeId, @Bind("this") Node inliningTarget, - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Exclusive @Cached InlinedConditionProfile isBuiltinProfile, @Shared @Cached ReadAttributeFromObjectNode readFromBuiltinsNode, @Exclusive @Cached InlinedConditionProfile ctxInitializedProfile) { @@ -239,14 +239,14 @@ Object returnBuiltin(TruffleString attributeId, return returnBuiltinFromConstantModule(attributeId, inliningTarget, raiseNode, isBuiltinProfile, readFromBuiltinsNode, builtins); } - private static Object readBuiltinFromModule(TruffleString attributeId, PRaiseNode.Lazy raiseNode, Node inliningTarget, + private static Object readBuiltinFromModule(TruffleString attributeId, PRaiseNode raiseNode, Node inliningTarget, InlinedConditionProfile isBuiltinProfile, PythonModule builtins, ReadAttributeFromObjectNode readFromBuiltinsNode) { Object builtin = readFromBuiltinsNode.execute(builtins, attributeId); if (isBuiltinProfile.profile(inliningTarget, builtin != PNone.NO_VALUE)) { return builtin; } else { - throw raiseNameNotDefined(raiseNode.get(inliningTarget), attributeId); + throw raiseNameNotDefined(inliningTarget, raiseNode, attributeId); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadNameNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadNameNode.java index 2914a0f998..2ca8e9aba3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadNameNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadNameNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -53,6 +53,7 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @@ -68,6 +69,7 @@ public final Object execute(VirtualFrame frame, TruffleString attributeId) { public abstract Object executeImpl(VirtualFrame frame, TruffleString attributeId); + @NeverDefault public static ReadNameNode create() { return ReadNameNodeGen.create(); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/WriteGlobalNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/WriteGlobalNode.java index ade2eadf09..59694b6a9d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/WriteGlobalNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/WriteGlobalNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/WriteNameNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/WriteNameNode.java index cadc06ea8e..d4d6641546 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/WriteNameNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/WriteNameNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/BuiltinFunctionRootNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/BuiltinFunctionRootNode.java index 448caf3553..7d76f1cfd8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/BuiltinFunctionRootNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/BuiltinFunctionRootNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -56,8 +56,8 @@ import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.WrapBinaryfuncR; import com.oracle.graal.python.nodes.function.builtins.WrapTpNew; +import com.oracle.graal.python.nodes.function.builtins.WrapperDescrCall; import com.oracle.graal.python.runtime.ExecutionContext.CalleeContext; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerAsserts; @@ -89,10 +89,10 @@ public final class BuiltinFunctionRootNode extends PRootNode { private final boolean declaresExplicitSelf; @Child private BuiltinCallNode body; @Child private CalleeContext calleeContext = CalleeContext.create(); - private final PythonBuiltinClassType constructsClass; + private final PythonBuiltinClassType wrapsSlotForClass; public BuiltinFunctionRootNode(PythonLanguage language, Signature signature, Builtin builtin, NodeFactory factory, boolean declaresExplicitSelf, - PythonBuiltinClassType constructsClass) { + PythonBuiltinClassType wrapsSlotForClass) { super(language); CompilerAsserts.neverPartOfCompilation(); this.signature = signature; @@ -100,25 +100,25 @@ public BuiltinFunctionRootNode(PythonLanguage language, Signature signature, Bui this.name = builtin.name(); this.factory = factory; this.declaresExplicitSelf = declaresExplicitSelf; - this.constructsClass = constructsClass; + this.wrapsSlotForClass = wrapsSlotForClass; if (builtin.alwaysNeedsCallerFrame()) { setNeedsCallerFrame(); } } - public BuiltinFunctionRootNode(PythonLanguage language, Builtin builtin, NodeFactory factory, boolean declaresExplicitSelf, - PythonBuiltinClassType constructsClass) { - this(language, createSignature(factory, builtin, declaresExplicitSelf, constructsClass != PythonBuiltinClassType.nil), builtin, factory, declaresExplicitSelf, constructsClass); + public BuiltinFunctionRootNode(PythonLanguage language, Builtin builtin, NodeFactory factory, boolean declaresExplicitSelf) { + this(language, createSignature(factory, builtin, declaresExplicitSelf, false), builtin, factory, declaresExplicitSelf, null); } - public BuiltinFunctionRootNode(PythonLanguage language, Builtin builtin, NodeFactory factory, boolean declaresExplicitSelf) { - this(language, builtin, factory, declaresExplicitSelf, builtin.constructsClass()); + public BuiltinFunctionRootNode(PythonLanguage language, Builtin builtin, NodeFactory factory, boolean declaresExplicitSelf, + PythonBuiltinClassType wrapsSlotForClass) { + this(language, createSignature(factory, builtin, declaresExplicitSelf, false), builtin, factory, declaresExplicitSelf, wrapsSlotForClass); } /** * Should return a signature compatible with {@link #createArgumentsList(Builtin, boolean)} */ - private static Signature createSignature(NodeFactory factory, Builtin builtin, boolean declaresExplicitSelf, boolean constructsClass) { + public static Signature createSignature(NodeFactory factory, Builtin builtin, boolean declaresExplicitSelf, boolean constructsClass) { TruffleString[] parameterNames = toTruffleStringArrayUncached(builtin.parameterNames()); int maxNumPosArgs = Math.max(builtin.minNumOfPositionalArgs(), parameterNames.length); @@ -153,9 +153,6 @@ private static Signature createSignature(NodeFactory factory, Builtin builtin) { @@ -197,6 +194,9 @@ private static boolean validateBuiltin(NodeFactory 0 || + builtin.keywordOnlyNames().length > 0 : "PythonVararagsBuiltin subclass must not define any parameters on the @Builtin annotation, it must do all parameter parsing and validation themselves, builtin" + + nodeClass.getName(); } return true; } @@ -219,7 +219,7 @@ private static void validateBuiltinForArity(Builtin builtin, Class clazz) { @@ -321,10 +321,12 @@ public Object execute(VirtualFrame frame) { } } - if (builtin.reverseOperation()) { - body = insert(new WrapBinaryfuncR(newBody)); - } else if (constructsClass != PythonBuiltinClassType.nil) { - body = insert(new WrapTpNew(newBody, constructsClass)); + if (wrapsSlotForClass != null) { + if (declaresExplicitSelf) { + body = insert(new WrapperDescrCall(newBody, name, wrapsSlotForClass)); + } else { + body = insert(new WrapTpNew(newBody, wrapsSlotForClass)); + } } else { body = insert(newBody); } @@ -383,6 +385,6 @@ protected boolean isCloneUninitializedSupported() { @Override protected RootNode cloneUninitialized() { - return new BuiltinFunctionRootNode(getLanguage(PythonLanguage.class), signature, builtin, factory, declaresExplicitSelf, constructsClass); + return new BuiltinFunctionRootNode(getLanguage(PythonLanguage.class), signature, builtin, factory, declaresExplicitSelf, wrapsSlotForClass); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/PythonVarargsBuiltinNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/PythonVarargsBuiltinNode.java index 9e398bdd70..f9eb3df857 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/PythonVarargsBuiltinNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/PythonVarargsBuiltinNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,79 +40,11 @@ */ package com.oracle.graal.python.nodes.function.builtins; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.ControlFlowException; -import com.oracle.truffle.api.strings.TruffleString; -/** - * Subclasses must override {@link #varArgExecute(VirtualFrame, Object, Object[], PKeyword[])} to - * call the e.g. {@link #execute(VirtualFrame, Object, Object[], PKeyword[])} or whatever is right - * for them, otherwise they will never be on the direct call path. - */ public abstract class PythonVarargsBuiltinNode extends PythonBuiltinBaseNode { - @Child private PythonObjectFactory objectFactory; - @Child private PRaiseNode raiseNode; - - protected final PythonObjectFactory factory() { - if (objectFactory == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - if (isAdoptable()) { - objectFactory = insert(PythonObjectFactory.create()); - } else { - objectFactory = getContext().factory(); - } - } - return objectFactory; - } - - protected final PRaiseNode getRaiseNode() { - if (raiseNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - if (isAdoptable()) { - raiseNode = insert(PRaiseNode.create()); - } else { - raiseNode = PRaiseNode.getUncached(); - } - } - return raiseNode; - } - - public PException raise(PythonBuiltinClassType type, TruffleString string) { - return getRaiseNode().raise(type, string); - } - - public final PException raise(PythonBuiltinClassType type, TruffleString format, Object... arguments) { - return getRaiseNode().raise(type, format, arguments); - } - - public static final class VarargsBuiltinDirectInvocationNotSupported extends ControlFlowException { - public static final VarargsBuiltinDirectInvocationNotSupported INSTANCE = new VarargsBuiltinDirectInvocationNotSupported(); - private static final long serialVersionUID = 1L; - - private VarargsBuiltinDirectInvocationNotSupported() { - } - } - - /** - * {@code frame} may be null. This function must not be called "execute" - */ - @SuppressWarnings("unused") - public Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords) - throws VarargsBuiltinDirectInvocationNotSupported { - throw VarargsBuiltinDirectInvocationNotSupported.INSTANCE; - } - - /** - * {@code frame} may be null. Most varargs invocations will be (self, *args, *kwargs), so this - * execute method won't hurt. - */ public abstract Object execute(VirtualFrame frame, Object self, Object[] arguments, PKeyword[] keywords); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/WrapBinaryfuncR.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/WrapBinaryfuncR.java deleted file mode 100644 index 51db45cf57..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/WrapBinaryfuncR.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.function.builtins; - -import com.oracle.graal.python.nodes.argument.ReadArgumentNode; - -// also implements wrap_ternaryfunc_r, because it's the same thing -public final class WrapBinaryfuncR extends SlotWrapper { - public WrapBinaryfuncR(BuiltinCallNode func) { - super(func); - if (func instanceof BuiltinBinaryCallNode) { - ReadArgumentNode arg1 = ((BuiltinBinaryCallNode) func).arg1; - ReadArgumentNode arg2 = ((BuiltinBinaryCallNode) func).arg2; - // they are already adopted as children, so no harm in swapping them - ((BuiltinBinaryCallNode) func).arg1 = arg2; - ((BuiltinBinaryCallNode) func).arg2 = arg1; - } else if (func instanceof BuiltinTernaryCallNode) { - ReadArgumentNode arg1 = ((BuiltinTernaryCallNode) func).arg1; - ReadArgumentNode arg2 = ((BuiltinTernaryCallNode) func).arg2; - // they are already adopted as children, so no harm in swapping them - ((BuiltinTernaryCallNode) func).arg1 = arg2; - ((BuiltinTernaryCallNode) func).arg2 = arg1; - } else { - throw new IllegalStateException("reverse wrappers can only apply to binary and ternary nodes"); - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/WrapTpNew.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/WrapTpNew.java index 828d30d799..445479956b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/WrapTpNew.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/WrapTpNew.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,50 +40,89 @@ */ package com.oracle.graal.python.nodes.function.builtins; -import org.graalvm.collections.Pair; - import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.function.PArguments; -import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPythonSingle; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.SpecialMethodNames; -import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.NodeFactory; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.ExplodeLoop; -import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile; /** * Implements cpython://Objects/typeobject.c#tp_new_wrapper. */ public final class WrapTpNew extends SlotWrapper { - @Child private IsTypeNode isType; - @Child private IsSubtypeNode isSubtype; - @Child private PRaiseNode raiseNode; - @Child private LookupAttributeInMRONode lookupNewNode; - @CompilationFinal private ValueProfile builtinProfile; - @CompilationFinal private byte state = 0; private final PythonBuiltinClassType owner; - // we cache two node classes here, otherwise we use a truffle boundary lookup - @CompilationFinal(dimensions = 1) private final Pair[] cachedFactoriesNodeClasses = new Pair[2]; - - private static final byte NOT_SUBTP_STATE = 0b100; - private static final byte NOT_CLASS_STATE = 0b010; - private static final byte IS_UNSAFE_STATE = 0b001; + @Child private CheckNode checkNode; public WrapTpNew(BuiltinCallNode func, PythonBuiltinClassType owner) { super(func); this.owner = owner; } + @GenerateInline(false) + abstract static class CheckNode extends Node { + abstract void execute(PythonBuiltinClassType owner, Object cls); + + @Specialization + static void check(PythonBuiltinClassType owner, Object cls, + @Bind Node inliningTarget, + @Cached IsTypeNode isTypeNode, + @Cached IsSubtypeNode isSubtypeNode, + @Cached GetCachedTpSlotsNode getSlotsCls, + @Cached GetCachedTpSlotsNode getSlotsBase1, + @Cached GetCachedTpSlotsNode getSlotsBase2, + @Cached GetBaseClassNode getBase1, + @Cached GetBaseClassNode getBase2, + @Cached InlinedLoopConditionProfile loopProfile, + @Cached PRaiseNode raiseNotType, + @Cached PRaiseNode raiseNotSubytpe, + @Cached PRaiseNode raiseNotSafe) { + if (!isTypeNode.execute(inliningTarget, cls)) { + throw raiseNotType.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.NEW_X_ISNT_TYPE_OBJ, owner.getName(), cls); + } + if (!isSubtypeNode.execute(cls, owner)) { + throw raiseNotSubytpe.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.IS_NOT_SUBTYPE_OF, owner.getName(), cls, cls, owner.getName()); + } + /* + * CPython comment: Check that the use doesn't do something silly and unsafe like + * object.__new__(dict). To do this, we check that the most derived base that's not a + * heap type is this type. + */ + // We unroll the first iteration for better specialization + Object staticBase = cls; + TpSlot staticBaseNew = getSlotsCls.execute(inliningTarget, staticBase).tp_new(); + if (staticBaseNew instanceof TpSlotPythonSingle) { + staticBase = getBase1.execute(inliningTarget, staticBase); + staticBaseNew = getSlotsBase1.execute(inliningTarget, staticBase).tp_new(); + while (loopProfile.profile(inliningTarget, staticBaseNew instanceof TpSlotPythonSingle)) { + staticBase = getBase2.execute(inliningTarget, staticBase); + staticBaseNew = getSlotsBase2.execute(inliningTarget, staticBase).tp_new(); + } + } + if (staticBaseNew != owner.getSlots().tp_new()) { + throw raiseNotSafe.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.NEW_IS_NOT_SAFE_USE_ELSE, owner.getName(), cls, cls); + } + } + + @NeverDefault + public static CheckNode create() { + return WrapTpNewFactory.CheckNodeGen.create(); + } + } + @Override public Object execute(VirtualFrame frame) { Object cls; @@ -95,94 +134,12 @@ public Object execute(VirtualFrame frame) { throw new IllegalStateException(owner.getName() + ".__new__ called without arguments"); } if (cls != owner) { - if (isType == null) { + if (checkNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - reportPolymorphicSpecialize(); - isType = insert(IsTypeNode.create()); - } - if (!isType.executeCached(cls)) { - if ((state & NOT_CLASS_STATE) == 0) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - reportPolymorphicSpecialize(); - state |= NOT_CLASS_STATE; - } - throw getRaiseNode().raise(PythonBuiltinClassType.TypeError, ErrorMessages.NEW_X_ISNT_TYPE_OBJ, owner.getName(), cls); - } - if (isSubtype == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - reportPolymorphicSpecialize(); - isSubtype = insert(IsSubtypeNode.create()); - } - if (!isSubtype.execute(cls, owner)) { - if ((state & NOT_SUBTP_STATE) == 0) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - reportPolymorphicSpecialize(); - state |= NOT_SUBTP_STATE; - } - throw getRaiseNode().raise(PythonBuiltinClassType.TypeError, - ErrorMessages.IS_NOT_SUBTYPE_OF, - owner.getName(), cls, cls, owner.getName()); - } - // CPython walks the bases and checks that the first non-heaptype base has the new that - // we're in. We have our optimizations for this lookup that the compiler can then - // (hopefully) merge with the initial lookup of the new method before entering it. - if (lookupNewNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - reportPolymorphicSpecialize(); - lookupNewNode = insert(LookupAttributeInMRONode.createForLookupOfUnmanagedClasses(SpecialMethodNames.T___NEW__)); - } - Object newMethod = lookupNewNode.execute(cls); - if (newMethod instanceof PBuiltinMethod) { - if (builtinProfile == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - builtinProfile = PythonUtils.createValueIdentityProfile(); - } - NodeFactory factory = ((PBuiltinMethod) builtinProfile.profile(newMethod)).getBuiltinFunction().getBuiltinNodeFactory(); - if (factory != null) { - if (!getFactoryNodeClass(factory).isInstance(getNode())) { - if ((state & IS_UNSAFE_STATE) == 0) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - reportPolymorphicSpecialize(); - state |= IS_UNSAFE_STATE; - } - throw getRaiseNode().raise(PythonBuiltinClassType.TypeError, ErrorMessages.NEW_IS_NOT_SAFE_USE_ELSE, owner.getName(), cls, cls); - } - } - // we explicitly allow non-Java functions to pass here, since a PythonBuiltinClass - // with a non-java function is explicitly written in the core to allow this + checkNode = insert(CheckNode.create()); } + checkNode.execute(owner, cls); } return super.execute(frame); } - - @ExplodeLoop - @SuppressWarnings("unchecked") - private final Class getFactoryNodeClass(NodeFactory factory) { - for (int i = 0; i < cachedFactoriesNodeClasses.length; i++) { - Pair, Class> pair = (Pair, Class>) cachedFactoriesNodeClasses[i]; - if (pair == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - reportPolymorphicSpecialize(); - Class nodeclass = factory.getNodeClass(); - cachedFactoriesNodeClasses[i] = Pair.create(factory, nodeclass); - return nodeclass; - } else if (pair.getLeft() == factory) { - return pair.getRight(); - } - } - return getFactoryNodeClassUncached(factory); - } - - @TruffleBoundary - private static final Class getFactoryNodeClassUncached(NodeFactory factory) { - return factory.getNodeClass(); - } - - private PRaiseNode getRaiseNode() { - if (raiseNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - raiseNode = insert(PRaiseNode.create()); - } - return raiseNode; - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/WrapperDescrCall.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/WrapperDescrCall.java new file mode 100644 index 0000000000..7a985b8de7 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/WrapperDescrCall.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.nodes.function.builtins; + +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.objects.function.PArguments; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.classes.IsSubtypeNode; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.frame.VirtualFrame; + +/** + * Equivalent of {@code wrapperdescr_call} in CPython. We use this wrapper only for type slots. The + * assumption is that type slots are usually not called explicitly through the magic methods, so we + * can afford the extra checks for slot wrappers. + *

      + * TODO: handle this validation efficiently for wrappers of other builtin methods, where the + * performance is more important. + */ +public final class WrapperDescrCall extends SlotWrapper { + private final String name; + private final PythonBuiltinClassType type; + @Child IsSubtypeNode isSubtypeNode = IsSubtypeNode.create(); + @Child GetClassNode getClassNode = GetClassNode.create(); + + public WrapperDescrCall(BuiltinCallNode func, String name, PythonBuiltinClassType type) { + super(func); + this.name = name; + this.type = type; + } + + @Override + public Object execute(VirtualFrame frame) { + Object[] args = frame.getArguments(); + if (PArguments.getUserArgumentLength(args) <= 0) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.DESCRIPTOR_NEED_OBJ, name, "_"); + } + Object self = PArguments.getArgument(args, 0); + Object selfClass = getClassNode.executeCached(self); + if (selfClass != type && !isSubtypeNode.execute(selfClass, type)) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, name, type, self); + } + return super.execute(frame); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/CodePointConversionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/CodePointConversionNode.java index 51625b80c1..0d85c0e369 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/CodePointConversionNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/CodePointConversionNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -87,7 +87,7 @@ int doOthers(Object value, @Cached CastToTruffleStringNode castToStringNode, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { TruffleString str = castToStringNode.execute(inliningTarget, value); if (codePointLengthNode.execute(str, TS_ENCODING) == 1) { @@ -96,7 +96,7 @@ int doOthers(Object value, } catch (CannotCastException ex) { // handled below } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_BRACKETS_ARG_MUST_BE_S_NOT_P, builtinName, "unicode character", value); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_BRACKETS_ARG_MUST_BE_S_NOT_P, builtinName, "unicode character", value); } @ClinicConverterFactory diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/SliceIndexConversionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/SliceIndexConversionNode.java index cc1758b9b4..71c314477b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/SliceIndexConversionNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/SliceIndexConversionNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -68,11 +68,11 @@ static int doOthers(VirtualFrame frame, Object value, @Bind("this") Node inliningTarget, @Cached PyIndexCheckNode indexCheckNode, @Cached PyNumberAsSizeNode asSizeNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { if (indexCheckNode.execute(inliningTarget, value)) { return asSizeNode.executeLossy(frame, inliningTarget, value); } - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.SLICE_INDICES_TYPE_ERROR); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.SLICE_INDICES_TYPE_ERROR); } @ClinicConverterFactory(shortCircuitPrimitive = PrimitiveType.Int) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/TruffleStringConverterNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/TruffleStringConverterNode.java index 23b5470c1e..5a54fe5b76 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/TruffleStringConverterNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/TruffleStringConverterNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -71,11 +71,11 @@ static Object doString(TruffleString value) { Object doOthers(Object value, @Bind("this") Node inliningTarget, @Cached CastToTruffleStringNode castToStringNode, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { return castToStringNode.execute(inliningTarget, value); } catch (CannotCastException ex) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, ErrorMessages.S_BRACKETS_ARG_MUST_BE_S_NOT_P, builtinName, "str", value); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.S_BRACKETS_ARG_MUST_BE_S_NOT_P, builtinName, "str", value); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/TupleConversionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/TupleConversionNode.java index e1f61306a5..173b0e94de 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/TupleConversionNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/TupleConversionNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -71,8 +71,8 @@ static Object[] doTuple(PTuple t, @Fallback static Object doOthers(Object value, - @Cached PRaiseNode raiseNode) { - throw raiseNode.raise(PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, value, "a tuple", value); + @Bind("this") Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, value, "a tuple", value); } @ClinicConverterFactory diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/WritableBufferConversionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/WritableBufferConversionNode.java index eb793e1e79..1462c5e602 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/WritableBufferConversionNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/WritableBufferConversionNode.java @@ -72,11 +72,11 @@ Object doObject(VirtualFrame frame, Object value, @Bind PythonContext context, @Cached("createFor(this)") IndirectCallData indirectCallData, @CachedLibrary("value") PythonBufferAcquireLibrary acquireLib, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { return acquireLib.acquireWritable(value, frame, context, context.getLanguage(inliningTarget), indirectCallData); } catch (PException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.S_BRACKETS_ARG_MUST_BE_READ_WRITE_BYTES_LIKE_NOT_P, builtinName, value); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_BRACKETS_ARG_MUST_BE_READ_WRITE_BYTES_LIKE_NOT_P, builtinName, value); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/interop/GetInteropBehaviorValueNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/interop/GetInteropBehaviorValueNode.java index c7e5dfa45f..efa8715cf0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/interop/GetInteropBehaviorValueNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/interop/GetInteropBehaviorValueNode.java @@ -77,7 +77,7 @@ @SuppressWarnings("truffle-inlining") // some of the cached nodes in the specialization are not // inlineable public abstract class GetInteropBehaviorValueNode extends PNodeWithContext { - public final boolean executeBoolean(Node inliningTarget, InteropBehavior behavior, InteropBehaviorMethod method, CastToJavaBooleanNode toBooleanNode, PRaiseNode.Lazy raiseNode, + public final boolean executeBoolean(Node inliningTarget, InteropBehavior behavior, InteropBehaviorMethod method, CastToJavaBooleanNode toBooleanNode, PRaiseNode raiseNode, PythonAbstractObject receiver, Object... extraArguments) { assert extraArguments.length == method.extraArguments : "number of passed arguments to GetInteropBehaviorValueNode does not match expected number of arguments for method"; try { @@ -85,76 +85,76 @@ public final boolean executeBoolean(Node inliningTarget, InteropBehavior behavio try { return toBooleanNode.execute(inliningTarget, value); } catch (CannotCastException cce) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, "return value", "a boolean", value); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, "return value", "a boolean", value); } } catch (UnsupportedMessageException usm) { return false; } } - public final byte executeByte(Node inliningTarget, InteropBehavior behavior, InteropBehaviorMethod method, CastToJavaByteNode toByteNode, PRaiseNode.Lazy raiseNode, PythonAbstractObject receiver, + public final byte executeByte(Node inliningTarget, InteropBehavior behavior, InteropBehaviorMethod method, CastToJavaByteNode toByteNode, PRaiseNode raiseNode, PythonAbstractObject receiver, Object... extraArguments) throws UnsupportedMessageException { assert extraArguments.length == method.extraArguments : "number of passed arguments to GetInteropBehaviorValueNode does not match expected number of arguments for method"; Object value = execute(inliningTarget, behavior, method, receiver, extraArguments); try { return toByteNode.execute(inliningTarget, value); } catch (CannotCastException cce) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, "return value", "a byte", value); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, "return value", "a byte", value); } } - public final short executeShort(Node inliningTarget, InteropBehavior behavior, InteropBehaviorMethod method, CastToJavaShortNode toShortNode, PRaiseNode.Lazy raiseNode, + public final short executeShort(Node inliningTarget, InteropBehavior behavior, InteropBehaviorMethod method, CastToJavaShortNode toShortNode, PRaiseNode raiseNode, PythonAbstractObject receiver, Object... extraArguments) throws UnsupportedMessageException { assert extraArguments.length == method.extraArguments : "number of passed arguments to GetInteropBehaviorValueNode does not match expected number of arguments for method"; Object value = execute(inliningTarget, behavior, method, receiver, extraArguments); try { return toShortNode.execute(inliningTarget, value); } catch (CannotCastException cce) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, "return value", "a short", value); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, "return value", "a short", value); } } - public final int executeInt(Node inliningTarget, InteropBehavior behavior, InteropBehaviorMethod method, CastToJavaIntExactNode toIntNode, PRaiseNode.Lazy raiseNode, PythonAbstractObject receiver, + public final int executeInt(Node inliningTarget, InteropBehavior behavior, InteropBehaviorMethod method, CastToJavaIntExactNode toIntNode, PRaiseNode raiseNode, PythonAbstractObject receiver, Object... extraArguments) throws UnsupportedMessageException { assert extraArguments.length == method.extraArguments : "number of passed arguments to GetInteropBehaviorValueNode does not match expected number of arguments for method"; Object value = execute(inliningTarget, behavior, method, receiver, extraArguments); try { return toIntNode.execute(inliningTarget, value); } catch (CannotCastException cce) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, "return value", "an int", value); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, "return value", "an int", value); } } - public final long executeLong(Node inliningTarget, InteropBehavior behavior, InteropBehaviorMethod method, CastToJavaLongExactNode toLongNode, PRaiseNode.Lazy raiseNode, + public final long executeLong(Node inliningTarget, InteropBehavior behavior, InteropBehaviorMethod method, CastToJavaLongExactNode toLongNode, PRaiseNode raiseNode, PythonAbstractObject receiver, Object... extraArguments) throws UnsupportedMessageException { assert extraArguments.length == method.extraArguments : "number of passed arguments to GetInteropBehaviorValueNode does not match expected number of arguments for method"; Object value = execute(inliningTarget, behavior, method, receiver, extraArguments); try { return toLongNode.execute(inliningTarget, value); } catch (CannotCastException cce) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, "return value", "a long", value); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, "return value", "a long", value); } } - public final double executeDouble(Node inliningTarget, InteropBehavior behavior, InteropBehaviorMethod method, CastToJavaDoubleNode toDoubleNode, PRaiseNode.Lazy raiseNode, + public final double executeDouble(Node inliningTarget, InteropBehavior behavior, InteropBehaviorMethod method, CastToJavaDoubleNode toDoubleNode, PRaiseNode raiseNode, PythonAbstractObject receiver, Object... extraArguments) throws UnsupportedMessageException { assert extraArguments.length == method.extraArguments : "number of passed arguments to GetInteropBehaviorValueNode does not match expected number of arguments for method"; Object value = execute(inliningTarget, behavior, method, receiver, extraArguments); try { return toDoubleNode.execute(inliningTarget, value); } catch (CannotCastException cce) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, "return value", "a double", value); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, "return value", "a double", value); } } - public final String executeString(Node inliningTarget, InteropBehavior behavior, InteropBehaviorMethod method, CastToJavaStringNode toStringNode, PRaiseNode.Lazy raiseNode, + public final String executeString(Node inliningTarget, InteropBehavior behavior, InteropBehaviorMethod method, CastToJavaStringNode toStringNode, PRaiseNode raiseNode, PythonAbstractObject receiver, Object... extraArguments) throws UnsupportedMessageException { assert extraArguments.length == method.extraArguments : "number of passed arguments to GetInteropBehaviorValueNode does not match expected number of arguments for method"; Object value = execute(inliningTarget, behavior, method, receiver, extraArguments); try { return toStringNode.execute(value); } catch (CannotCastException cce) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, "return value", "a string", value); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, S_MUST_BE_S_NOT_P, "return value", "a string", value); } } @@ -209,7 +209,7 @@ static Object getValue(Node inliningTarget, InteropBehavior behavior, InteropBeh static Object getValueComputedWrongArity(Node inliningTarget, InteropBehavior behavior, InteropBehaviorMethod method, PythonAbstractObject receiver, Object[] extraArguments, @Cached PRaiseNode raiseNode) throws UnsupportedMessageException { assert behavior.isDefined(method) : "interop behavior method is not defined!"; - throw raiseNode.raise(PythonBuiltinClassType.TypeError, FUNC_TAKES_EXACTLY_D_ARGS, method.extraArguments, extraArguments.length); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, FUNC_TAKES_EXACTLY_D_ARGS, method.extraArguments, extraArguments.length); } @NeverDefault diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/DeleteDictNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/DeleteDictNode.java index 13f5adfde0..3c41dce9fb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/DeleteDictNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/DeleteDictNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,6 +40,7 @@ */ package com.oracle.graal.python.nodes.object; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageCopy; @@ -48,7 +49,7 @@ import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateUncached; @@ -66,8 +67,7 @@ static void doPythonObject(PythonObject object, @Bind("this") Node inliningTarget, @Cached HiddenAttr.ReadNode readHiddenAttrNode, @Cached HiddenAttr.WriteNode writeHiddenAttrNode, - @Cached HashingStorageCopy copyNode, - @Cached PythonObjectFactory factory) { + @Cached HashingStorageCopy copyNode) { /* There is no special handling for class MROs because type.__dict__ cannot be deleted. */ assert !PGuards.isPythonClass(object); PDict oldDict = (PDict) readHiddenAttrNode.execute(inliningTarget, object, HiddenAttr.DICT, null); @@ -86,7 +86,7 @@ static void doPythonObject(PythonObject object, * empty dict dissociated from this object seems like the cleanest option. The disadvantage * is that the current values won't get garbage collected. */ - PDict newDict = factory.createDict(); + PDict newDict = PFactory.createDict(PythonLanguage.get(inliningTarget)); object.setDict(inliningTarget, writeHiddenAttrNode, newDict); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetClassNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetClassNode.java index 966bcf711b..92939aaae0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetClassNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetClassNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -55,7 +55,6 @@ import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.truffle.PythonTypes; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -65,12 +64,10 @@ import com.oracle.truffle.api.dsl.Idempotent; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.strings.TruffleString; -@TypeSystemReference(PythonTypes.class) @GenerateUncached @GenerateInline(inlineByDefault = true) public abstract class GetClassNode extends PNodeWithContext { @@ -218,8 +215,8 @@ protected static boolean hasInitialClass(Shape shape) { } @Specialization - static Object getPBCT(@SuppressWarnings("unused") PythonBuiltinClassType object) { - return PythonBuiltinClassType.PythonClass; + static Object getPBCT(PythonBuiltinClassType object) { + return object.getType(); } @Specialization diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetDictIfExistsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetDictIfExistsNode.java index f1f11eb81d..701091e9b3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetDictIfExistsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetDictIfExistsNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,6 +43,7 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_OBJECT_GET_DICT_PTR; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; @@ -56,7 +57,7 @@ import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; @@ -69,6 +70,7 @@ import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; @GenerateUncached @SuppressWarnings("truffle-inlining") // footprint reduction 36 -> 17 @@ -121,11 +123,12 @@ static PDict doPythonObject(PythonObject object, @Specialization @InliningCutoff PDict doNativeObject(PythonAbstractNativeObject object, + @Bind("this") Node inliningTarget, @CachedLibrary(limit = "1") InteropLibrary lib, @Cached PythonToNativeNode toNative, @Cached CStructAccess.ReadObjectNode readObjectNode, @Cached CStructAccess.WriteObjectNewRefNode writeObjectNode, - @Cached PythonObjectFactory factory, + @Cached InlinedBranchProfile createDict, @Cached CExtNodes.PCallCapiFunction callGetDictPtr) { Object dictPtr = callGetDictPtr.call(FUN_PY_OBJECT_GET_DICT_PTR, toNative.execute(object)); if (lib.isNull(dictPtr)) { @@ -133,14 +136,15 @@ PDict doNativeObject(PythonAbstractNativeObject object, } else { Object dictObject = readObjectNode.readGeneric(dictPtr, 0); if (dictObject == PNone.NO_VALUE) { - PDict dict = factory.createDict(); + createDict.enter(inliningTarget); + PDict dict = PFactory.createDict(PythonLanguage.get(inliningTarget)); writeObjectNode.write(dictPtr, dict); return dict; } else if (dictObject instanceof PDict dict) { return dict; } else { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(this, SystemError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, dictObject); + throw PRaiseNode.raiseStatic(this, SystemError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, dictObject); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetForeignObjectClassNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetForeignObjectClassNode.java index f2ba18eb96..cd317456af 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetForeignObjectClassNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetForeignObjectClassNode.java @@ -52,8 +52,12 @@ import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; import com.oracle.graal.python.builtins.objects.type.PythonClass; import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeFlags; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -249,8 +253,12 @@ private PythonManagedClass resolvePolyglotForeignClass(PythonContext context, in PythonModule polyglotModule = context.lookupBuiltinModule(T_POLYGLOT); - PythonClass pythonClass = context.factory().createPythonClassAndFixupSlots(context.getLanguage(), PythonBuiltinClassType.PythonClass, name, base, bases); + PythonClass pythonClass = PFactory.createPythonClassAndFixupSlots(context.getLanguage(), name, base, bases); pythonClass.setAttribute(T___MODULE__, T_POLYGLOT); + if (!Trait.INSTANTIABLE.isSet(traits)) { + pythonClass.setTpSlots(pythonClass.getTpSlots().copy().set(TpSlots.TpSlotMeta.TP_NEW, null).build()); + TypeNodes.SetTypeFlagsNode.executeUncached(pythonClass, TypeNodes.GetTypeFlagsNode.executeUncached(pythonClass) | TypeFlags.DISALLOW_INSTANTIATION); + } assert polyglotModule.getAttribute(name) == PNone.NO_VALUE : name; polyglotModule.setAttribute(name, pythonClass); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetOrCreateDictNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetOrCreateDictNode.java index 9290b4d348..cdf3323ca0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetOrCreateDictNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetOrCreateDictNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,14 +42,16 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateCached; @@ -81,11 +83,11 @@ static PDict doPythonObject(Node inliningTarget, PythonObject object, @Shared("getDict") @Cached(inline = false) GetDictIfExistsNode getDictIfExistsNode, @Cached SetDictNode setDictNode, @Cached InlinedBranchProfile createDict, - @Cached(inline = false) PythonObjectFactory factory) { + @Bind PythonLanguage language) { PDict dict = getDictIfExistsNode.execute(object); if (dict == null) { createDict.enter(inliningTarget); - dict = factory.createDictFixedStorage(object); + dict = PFactory.createDictFixedStorage(language, object); setDictNode.execute(inliningTarget, object, dict); } return dict; @@ -97,7 +99,7 @@ static PDict doOther(Node inliningTarget, Object object, PDict dict = getDict.execute(object); if (dict == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, SystemError, ErrorMessages.UNABLE_SET_DICT_OF_OBJ, object); + throw PRaiseNode.raiseStatic(inliningTarget, SystemError, ErrorMessages.UNABLE_SET_DICT_OF_OBJ, object); } return dict; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetRegisteredClassNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetRegisteredClassNode.java index 3158eff127..cdb38b382a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetRegisteredClassNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetRegisteredClassNode.java @@ -58,6 +58,7 @@ import com.oracle.graal.python.nodes.SpecialAttributeNames; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.ArrayBuilder; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; @@ -190,11 +191,11 @@ private static PythonClass buildClassAndRegister(Object foreignObject, PythonClass pythonClass; try { // The call might not succeed if, for instance, the MRO can't be constructed - pythonClass = context.factory().createPythonClassAndFixupSlots(context.getLanguage(), PythonBuiltinClassType.PythonClass, className, bases[0], basesWithForeign); + pythonClass = PFactory.createPythonClassAndFixupSlots(context.getLanguage(), className, bases[0], basesWithForeign); } catch (PException e) { // Catch the error to additionally print the collected classes and specify the error // occurred during class creation - throw PRaiseNode.getUncached().raiseWithCause(PythonBuiltinClassType.TypeError, e, ErrorMessages.INTEROP_CLASS_CREATION_NOT_POSSIBLE, + throw PRaiseNode.raiseWithCauseStatic(inliningTarget, PythonBuiltinClassType.TypeError, e, ErrorMessages.INTEROP_CLASS_CREATION_NOT_POSSIBLE, interopLibrary.getMetaQualifiedName(metaObject), Arrays.toString(basesWithForeign)); } @@ -234,7 +235,7 @@ private static Object lookupWithInheritance(Node inliningTarget, Object foreignO metaObject, foundClasses.toArray(), inliningTarget, - ObjectHashMapFactory.PutNodeGen.getUncached()); + ObjectHashMap.PutNode.getUncached()); } catch (UnsupportedMessageException | InvalidArrayIndexException e) { throw CompilerDirectives.shouldNotReachHere(e); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/IsForeignObjectNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/IsForeignObjectNode.java index b34fda5084..8dfe622eb8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/IsForeignObjectNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/IsForeignObjectNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,13 +43,11 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PythonAbstractObject; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.truffle.PythonTypes; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -57,7 +55,6 @@ * Checks whether the object is a foreign object, i.e. is neither a python primitive value, nor a * python object. */ -@TypeSystemReference(PythonTypes.class) @GenerateUncached @GenerateInline @GenerateCached(false) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/IsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/IsNode.java index fb5dd6d72e..80ed581381 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/IsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/IsNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,26 +44,29 @@ import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; -import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; import com.oracle.graal.python.builtins.objects.code.CodeNodes; import com.oracle.graal.python.builtins.objects.code.PCode; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.builtins.objects.str.StringNodes; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; +import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.bytecode.PBytecodeGeneratorFunctionRootNode; import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLGeneratorFunctionRootNode; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode; import com.oracle.graal.python.nodes.expression.BinaryOp; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsAnyBuiltinObjectProfile; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.util.ComparisonOp; import com.oracle.graal.python.util.OverflowException; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.bytecode.OperationProxy; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateUncached; @@ -79,6 +82,7 @@ @ImportStatic(PythonOptions.class) @GenerateUncached +@OperationProxy.Proxyable @SuppressWarnings("truffle-inlining") // footprint reduction 44 -> 26 public abstract class IsNode extends Node implements BinaryOp { @@ -87,7 +91,7 @@ public abstract class IsNode extends Node implements BinaryOp { protected abstract boolean executeInternal(boolean left, Object right); @Override - public final Object executeObject(VirtualFrame frame, Object left, Object right) { + public final Object execute(VirtualFrame frame, Object left, Object right) { return execute(left, right); } @@ -174,7 +178,7 @@ public static boolean doLP(long left, PInt right, public static boolean doDD(double left, double right) { // n.b. we simulate that the primitive NaN is a singleton; this is required to make // 'nan = float("nan"); nan is nan' work - return left == right || (Double.isNaN(left) && Double.isNaN(right)); + return left == right || (Double.doubleToRawLongBits(left) == Double.doubleToRawLongBits(right)); } @Specialization @@ -210,14 +214,19 @@ public static boolean doTC(PythonBuiltinClassType left, PythonBuiltinClass right // native objects @Specialization + @InliningCutoff public static boolean doNative(PythonAbstractNativeObject left, PythonAbstractNativeObject right, - @Bind("this") Node inliningTarget, - @Cached CExtNodes.PointerCompareNode pointerCompareNode) { - return pointerCompareNode.execute(inliningTarget, ComparisonOp.EQ, left, right); + @Exclusive @CachedLibrary(limit = "1") InteropLibrary interop) { + // Assumption: not perf critical, instead of refactoring + // PythonAbstractNativeObject.isIdentical into a separate node, we just piggy-back on + // interop library. We do not need two libraries, this will always specialize only to + // PythonAbstractNativeObject + return interop.isIdentical(left, right, interop); } // code @Specialization + @InliningCutoff public static boolean doCode(PCode left, PCode right, @Bind("this") Node inliningTarget, @Cached CodeNodes.GetCodeCallTargetNode getCt) { @@ -229,14 +238,28 @@ public static boolean doCode(PCode left, PCode right, if (leftCt != null && rightCt != null) { RootNode leftRootNode = leftCt.getRootNode(); RootNode rightRootNode = rightCt.getRootNode(); - if (leftRootNode instanceof PBytecodeGeneratorFunctionRootNode) { - leftRootNode = ((PBytecodeGeneratorFunctionRootNode) leftRootNode).getBytecodeRootNode(); - } - if (rightRootNode instanceof PBytecodeGeneratorFunctionRootNode) { - rightRootNode = ((PBytecodeGeneratorFunctionRootNode) rightRootNode).getBytecodeRootNode(); - } - if (leftRootNode instanceof PBytecodeRootNode && rightRootNode instanceof PBytecodeRootNode) { - return ((PBytecodeRootNode) leftRootNode).getCodeUnit() == ((PBytecodeRootNode) rightRootNode).getCodeUnit(); + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + if (leftRootNode instanceof PBytecodeDSLGeneratorFunctionRootNode l) { + leftRootNode = l.getBytecodeRootNode(); + } + if (rightRootNode instanceof PBytecodeDSLGeneratorFunctionRootNode r) { + rightRootNode = r.getBytecodeRootNode(); + } + + if (leftRootNode instanceof PBytecodeDSLRootNode l && rightRootNode instanceof PBytecodeDSLRootNode r) { + return l.getCodeUnit() == r.getCodeUnit(); + } + } else { + if (leftRootNode instanceof PBytecodeGeneratorFunctionRootNode l) { + leftRootNode = l.getBytecodeRootNode(); + } + if (rightRootNode instanceof PBytecodeGeneratorFunctionRootNode r) { + rightRootNode = r.getBytecodeRootNode(); + } + + if (leftRootNode instanceof PBytecodeRootNode l && rightRootNode instanceof PBytecodeRootNode r) { + return l.getCodeUnit() == r.getCodeUnit(); + } } return leftRootNode == rightRootNode; } else { @@ -246,29 +269,33 @@ public static boolean doCode(PCode left, PCode right, return true; } + public static boolean someIsNone(Object left, Object right) { + return PGuards.isPNone(left) || PGuards.isPNone(right); + } + // none - @Specialization - public static boolean doObjectPNone(Object left, PNone right, + @Specialization(guards = "someIsNone(left, right)") + public static boolean doPNone(Object left, Object right, @Bind("this") Node inliningTarget, @Shared @Cached IsForeignObjectNode isForeignObjectNode, @Shared @CachedLibrary(limit = "3") InteropLibrary lib) { if (left == right) { return true; } + return doPNoneSlowpath(left, right, inliningTarget, isForeignObjectNode, lib); + } + + @InliningCutoff + private static boolean doPNoneSlowpath(Object left, Object right, Node inliningTarget, IsForeignObjectNode isForeignObjectNode, InteropLibrary lib) { if (isForeignObjectNode.execute(inliningTarget, left)) { return lib.isNull(left); } + if (isForeignObjectNode.execute(inliningTarget, right)) { + return lib.isNull(right); + } return false; } - @Specialization - public static boolean doPNoneObject(PNone left, Object right, - @Bind("this") Node inliningTarget, - @Shared @Cached IsForeignObjectNode isForeignObjectNode, - @Shared @CachedLibrary(limit = "3") InteropLibrary lib) { - return doObjectPNone(right, left, inliningTarget, isForeignObjectNode, lib); - } - // pstring (may be interned) @Specialization public static boolean doPString(PString left, PString right, @@ -284,6 +311,7 @@ public static boolean doPString(PString left, PString right, // everything else @Fallback + @InliningCutoff public static boolean doOther(Object left, Object right, @Bind("this") Node inliningTarget, @Shared @Cached IsForeignObjectNode isForeignObjectNode, diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/statement/AbstractImportNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/statement/AbstractImportNode.java index c5da70de2d..3679765bb6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/statement/AbstractImportNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/statement/AbstractImportNode.java @@ -79,7 +79,7 @@ import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.ValueType; @@ -113,19 +113,19 @@ public static PythonModule importModule(TruffleString name) { if (builtinImport == PNone.NO_VALUE) { throw PConstructAndRaiseNode.getUncached().raiseImportError(null, IMPORT_NOT_FOUND); } - Object fromList = context.factory().createTuple(PythonUtils.EMPTY_TRUFFLESTRING_ARRAY); + Object fromList = PFactory.createTuple(context.getLanguage(), PythonUtils.EMPTY_TRUFFLESTRING_ARRAY); CallNode.executeUncached(builtinImport, name, PNone.NONE, PNone.NONE, fromList, 0); PythonModule sysModule = context.lookupBuiltinModule(T_SYS); Object modules = sysModule.getAttribute(T_MODULES); if (modules == PNone.NO_VALUE) { - throw PRaiseNode.getUncached().raise(RuntimeError, ErrorMessages.UNABLE_TO_GET_S, "sys.modules"); + throw PRaiseNode.raiseStatic(null, RuntimeError, ErrorMessages.UNABLE_TO_GET_S, "sys.modules"); } Object module = PyObjectGetItem.executeUncached(modules, name); if (module instanceof PythonModule pythonModule) { return pythonModule; } // FIXME CPython allows putting any object in sys.modules - throw PRaiseNode.getUncached().raise(NotImplementedError, ErrorMessages.PUTTING_NON_MODULE_OBJECTS_IN_SYS_MODULES_IS_NOT_SUPPORTED); + throw PRaiseNode.raiseStatic(null, NotImplementedError, ErrorMessages.PUTTING_NON_MODULE_OBJECTS_IN_SYS_MODULES_IS_NOT_SUPPORTED); } protected final Object importModule(VirtualFrame frame, TruffleString name, Object globals, TruffleString[] fromList, int level, ImportName importNameNode) { @@ -170,7 +170,6 @@ static Object importName(VirtualFrame frame, PythonContext context, PythonModule @Cached PConstructAndRaiseNode.Lazy raiseNode, @Cached CallNode importCallNode, @Cached GetDictFromGlobalsNode getDictNode, - @Cached PythonObjectFactory factory, @Cached PyImportImportModuleLevelObject importModuleLevel) { Object importFunc = readAttrNode.execute(builtins, T___IMPORT__, null); if (importFunc == null) { @@ -183,7 +182,7 @@ static Object importName(VirtualFrame frame, PythonContext context, PythonModule } else { globalsArg = getDictNode.execute(inliningTarget, globals); } - return importCallNode.execute(frame, importFunc, name, globalsArg, PNone.NONE, factory.createTuple(fromList), level); + return importCallNode.execute(frame, importFunc, name, globalsArg, PNone.NONE, PFactory.createTuple(PythonLanguage.get(inliningTarget), fromList), level); } return importModuleLevel.execute(frame, context, name, globals, fromList, level); } @@ -206,7 +205,7 @@ public abstract static class PyImportImportModuleLevelObject extends Node { @SuppressWarnings("unused") @Specialization(guards = "level < 0") Object levelLtZero(VirtualFrame frame, PythonContext context, TruffleString name, Object globals, TruffleString[] fromList, int level) { - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.TypeError, ErrorMessages.LEVEL_MUST_BE_AT_LEAST_ZERO); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.LEVEL_MUST_BE_AT_LEAST_ZERO); } protected static boolean containsDot(TruffleString name, TruffleString.CodePointLengthNode codePointLengthNode, TruffleString.IndexOfCodePointNode indexOfCodePointNode) { @@ -218,7 +217,7 @@ public static Object levelZeroNoFromlist(VirtualFrame frame, PythonContext conte @SuppressWarnings("unused") TruffleString[] fromList, @SuppressWarnings("unused") int level, @Bind("this") Node inliningTarget, - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Exclusive @Cached PyDictGetItem getModuleNode, @Exclusive @Cached EnsureInitializedNode ensureInitialized, @Exclusive @Cached FindAndLoad findAndLoad, @@ -226,7 +225,7 @@ public static Object levelZeroNoFromlist(VirtualFrame frame, PythonContext conte @Exclusive @Cached @SuppressWarnings("unused") TruffleString.IndexOfCodePointNode indexOfCodePointNode) { final TruffleString absName = name; if (name.isEmpty()) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.EMPTY_MOD_NAME); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.EMPTY_MOD_NAME); } PDict sysModules = context.getSysModules(); Object mod = getModuleNode.execute(frame, inliningTarget, sysModules, absName); // import_get_module @@ -254,12 +253,11 @@ private ModuleFront(TruffleString front) { static Object genericImport(VirtualFrame frame, PythonContext context, TruffleString name, Object globals, TruffleString[] fromList, int level, @Bind("this") Node inliningTarget, @Cached ResolveName resolveName, - @Exclusive @Cached PRaiseNode.Lazy raiseNode, + @Exclusive @Cached PRaiseNode raiseNode, @Exclusive @Cached PyDictGetItem getModuleNode, @Exclusive @Cached EnsureInitializedNode ensureInitialized, @Cached PyObjectLookupAttr getPathNode, @Cached PyObjectCallMethodObjArgs callHandleFromlist, - @Cached PythonObjectFactory factory, @Exclusive @Cached FindAndLoad findAndLoad, @Cached InlinedConditionProfile recursiveCase, @Exclusive @Cached TruffleString.CodePointLengthNode codePointLengthNode, @@ -270,7 +268,7 @@ static Object genericImport(VirtualFrame frame, PythonContext context, TruffleSt absName = resolveName.execute(frame, name, globals, level); } else { if (name.isEmpty()) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.EMPTY_MOD_NAME); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.EMPTY_MOD_NAME); } absName = name; } @@ -312,7 +310,7 @@ static Object genericImport(VirtualFrame frame, PythonContext context, TruffleSt TruffleString toReturn = substringNode.execute(absName, 0, codePointLengthNode.execute(absName, TS_ENCODING) - cutoff, TS_ENCODING, true); Object finalModule = getModuleNode.execute(frame, inliningTarget, sysModules, toReturn); // import_get_module if (finalModule == null) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.KeyError, ErrorMessages.S_NOT_IN_SYS_MODS, toReturn); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.KeyError, ErrorMessages.S_NOT_IN_SYS_MODS, toReturn); } return finalModule; } @@ -324,7 +322,7 @@ static Object genericImport(VirtualFrame frame, PythonContext context, TruffleSt if (path != PNone.NO_VALUE) { return callHandleFromlist.execute(frame, inliningTarget, context.getImportlib(), T__HANDLE_FROMLIST, mod, - factory.createTuple(fromList), + PFactory.createTuple(PythonLanguage.get(inliningTarget), fromList), context.importFunc()); } else { return mod; @@ -333,7 +331,7 @@ static Object genericImport(VirtualFrame frame, PythonContext context, TruffleSt } static Object genericImportRecursion(VirtualFrame frame, Node inliningTarget, PythonContext context, ModuleFront front, - PRaiseNode.Lazy raiseNode, + PRaiseNode raiseNode, PyDictGetItem getModuleNode, EnsureInitializedNode ensureInitialized, FindAndLoad findAndLoad, @@ -342,7 +340,7 @@ static Object genericImportRecursion(VirtualFrame frame, Node inliningTarget, Py TruffleString.SubstringNode substringNode) { TruffleString absName = front.front; if (absName.isEmpty()) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.EMPTY_MOD_NAME); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.EMPTY_MOD_NAME); } PDict sysModules = context.getSysModules(); Object mod = getModuleNode.execute(frame, inliningTarget, sysModules, absName); // import_get_module @@ -482,7 +480,7 @@ TruffleString resolveName(VirtualFrame frame, TruffleString name, Object globals CompilerDirectives.transferToInterpreterAndInvalidate(); branchStates[0] |= CANNOT_CAST; } - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.TypeError, ErrorMessages.PACKAGE_MUST_BE_A_STRING); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.PACKAGE_MUST_BE_A_STRING); } if (spec != null && spec != PNone.NONE) { if ((branchStates[0] & SPEC_IS_STH) == 0) { @@ -508,7 +506,7 @@ TruffleString resolveName(VirtualFrame frame, TruffleString name, Object globals CompilerDirectives.transferToInterpreterAndInvalidate(); branchStates[0] |= CANNOT_CAST; } - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.TypeError, ErrorMessages.SPEC_PARENT_MUST_BE_A_STRING); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.SPEC_PARENT_MUST_BE_A_STRING); } } else { if ((branchStates[0] & NO_SPEC_PKG) == 0) { @@ -528,7 +526,7 @@ TruffleString resolveName(VirtualFrame frame, TruffleString name, Object globals CompilerDirectives.transferToInterpreterAndInvalidate(); branchStates[0] |= GOT_NO_NAME; } - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.KeyError, ErrorMessages.NAME_NOT_IN_GLOBALS); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.KeyError, ErrorMessages.NAME_NOT_IN_GLOBALS); } try { pkgString = castPackageNode.execute(inliningTarget, pkg); @@ -537,7 +535,7 @@ TruffleString resolveName(VirtualFrame frame, TruffleString name, Object globals CompilerDirectives.transferToInterpreterAndInvalidate(); branchStates[0] |= CANNOT_CAST; } - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.TypeError, ErrorMessages.NAME_MUST_BE_A_STRING); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.TypeError, ErrorMessages.NAME_MUST_BE_A_STRING); } Object path = getPackageOrNameNode.execute(frame, inliningTarget, globalsDict, SpecialAttributeNames.T___PATH__); if (path == null) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/truffle/PythonArithmeticTypes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/truffle/PythonArithmeticTypes.java deleted file mode 100644 index c8b5d6b682..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/truffle/PythonArithmeticTypes.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. - * Copyright (c) 2013, Regents of the University of California - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.oracle.graal.python.nodes.truffle; - -import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass; -import com.oracle.graal.python.builtins.objects.cext.PythonNativeObject; -import com.oracle.graal.python.builtins.objects.floats.PFloat; -import com.oracle.graal.python.nodes.PGuards; -import com.oracle.truffle.api.dsl.ImplicitCast; -import com.oracle.truffle.api.dsl.TypeCast; -import com.oracle.truffle.api.dsl.TypeCheck; -import com.oracle.truffle.api.dsl.TypeSystem; - -/** - * This type system is supposed to be used in builtin nodes to reduce the number of specializations - * due to type combinations. A node that needs to handle all combinations of Python {@code int} and - * {@code float} types can just use the most general primitive type, i.e., in case of Python type - * {@code int} use Java {@code long} and in case of Python type {@code float} use Java - * {@code double}. {@code PInt} needs to be treated separately because of its arbitrary precision. - * - * Only use in nodes where it is known that {@code PInt} and {@code PFloat} objects are not - * subclassed! - */ -@TypeSystem -public abstract class PythonArithmeticTypes { - - @ImplicitCast - public static double PFloatToDouble(PFloat value) { - // NOTE: That's correct because we just use it in arithmetic operations where CPython also - // access the value ('f_val') directly. So, even if the object is subclassed, it is ignored. - return value.getValue(); - } - - @ImplicitCast - public static int booleanToInt(boolean value) { - return value ? 1 : 0; - } - - @ImplicitCast - public static long booleanToLong(boolean value) { - return value ? 1 : 0; - } - - @ImplicitCast - public static long intToLong(int value) { - return value; - } - - @TypeCheck(PythonNativeObject.class) - public static boolean isNativeObject(Object object) { - return PythonNativeObject.isInstance(object); - } - - @TypeCast(PythonNativeObject.class) - public static PythonNativeObject asNativeObject(Object object) { - return PythonNativeObject.cast(object); - } - - @TypeCheck(PythonNativeClass.class) - public static boolean isNativeClass(Object object) { - return PGuards.isNativeClass(object); - } - - @TypeCast(PythonNativeClass.class) - public static PythonNativeClass asNativeClass(Object object) { - return PythonNativeClass.cast(object); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyTypeExtra.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/truffle/PythonIntegerAndFloatTypes.java similarity index 70% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyTypeExtra.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/truffle/PythonIntegerAndFloatTypes.java index 16a6c18c4e..fe6433b80f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyTypeExtra.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/truffle/PythonIntegerAndFloatTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -38,24 +38,22 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.oracle.graal.python.builtins.objects.cext.hpy; +package com.oracle.graal.python.nodes.truffle; -public final class HPyTypeExtra { - public final long flags; - public final long basicSize; - public final long itemSize; - public final Object tpName; - public final int builtinShape; +import com.oracle.graal.python.builtins.objects.floats.PFloat; +import com.oracle.truffle.api.dsl.ImplicitCast; +import com.oracle.truffle.api.dsl.TypeSystem; - public Object defaultCallFunc; - public Object hpyDestroyFunc; - public long vectorcallOffset = Long.MIN_VALUE; - - public HPyTypeExtra(long flags, long basicSize, long itemSize, Object tpName, int builtinShape) { - this.flags = flags; - this.basicSize = basicSize; - this.itemSize = itemSize; - this.tpName = tpName; - this.builtinShape = builtinShape; +/** + * Type system that automatically unpacks PFloat object to the contained double value. Should only + * be used in nodes where CPython directly accesses f_val. + */ +@TypeSystem +public class PythonIntegerAndFloatTypes extends PythonIntegerTypes { + @ImplicitCast + public static double PFloatToDouble(PFloat value) { + // NOTE: That's correct because we just use it in arithmetic operations where CPython also + // access the value ('f_val') directly. So, even if the object is subclassed, it is ignored. + return value.getValue(); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/truffle/PythonTypes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/truffle/PythonIntegerTypes.java similarity index 62% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/truffle/PythonTypes.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/truffle/PythonIntegerTypes.java index 7815ff437a..054c7a4508 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/truffle/PythonTypes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/truffle/PythonIntegerTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -25,39 +25,29 @@ */ package com.oracle.graal.python.nodes.truffle; -import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass; -import com.oracle.graal.python.builtins.objects.cext.PythonNativeObject; -import com.oracle.graal.python.nodes.PGuards; import com.oracle.truffle.api.dsl.ImplicitCast; -import com.oracle.truffle.api.dsl.TypeCast; -import com.oracle.truffle.api.dsl.TypeCheck; import com.oracle.truffle.api.dsl.TypeSystem; +/** + * This type system is supposed to be used in builtin nodes to reduce the number of specializations + * due to type combinations. Booleans and ints are converted to long. PInt needs to be handled + * separately. + */ @TypeSystem -public abstract class PythonTypes { +public abstract class PythonIntegerTypes { @ImplicitCast - public static long intToLong(int value) { - return value; + public static int booleanToInt(boolean value) { + return value ? 1 : 0; } - @TypeCheck(PythonNativeObject.class) - public static boolean isNativeObject(Object object) { - return PythonNativeObject.isInstance(object); - } - - @TypeCast(PythonNativeObject.class) - public static PythonNativeObject asNativeObject(Object object) { - return PythonNativeObject.cast(object); - } - - @TypeCheck(PythonNativeClass.class) - public static boolean isNativeClass(Object object) { - return PGuards.isNativeClass(object); + @ImplicitCast + public static long booleanToLong(boolean value) { + return value ? 1 : 0; } - @TypeCast(PythonNativeClass.class) - public static PythonNativeClass asNativeClass(Object object) { - return PythonNativeClass.cast(object); + @ImplicitCast + public static long intToLong(int value) { + return value; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/BadOPCodeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/BadOPCodeNode.java index 6bf32be4ca..9af5d0866a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/BadOPCodeNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/BadOPCodeNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -66,7 +66,7 @@ public BadOPCodeNode(TruffleLanguage language, TruffleString name) { @Override public Object execute(VirtualFrame frame) { - throw PRaiseNode.raiseUncached(this, PythonBuiltinClassType.SystemError, ErrorMessages.UNKNOWN_OPCODE); + throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.SystemError, ErrorMessages.UNKNOWN_OPCODE); } @Override diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToByteNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToByteNode.java index f3d49fb712..70db749531 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToByteNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToByteNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -53,7 +53,6 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.util.BiFunction; import com.oracle.graal.python.util.OverflowException; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.ImportStatic; @@ -61,18 +60,19 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.BranchProfile; @ImportStatic(PGuards.class) public abstract class CastToByteNode extends Node { public static final CastToByteNode UNCACHED_INSTANCE = CastToByteNode.create(); - @Child private PRaiseNode raiseNode; + private final BranchProfile errorProfile = BranchProfile.create(); - private final BiFunction rangeErrorHandler; - private final BiFunction typeErrorHandler; + private final BiFunction rangeErrorHandler; + private final BiFunction typeErrorHandler; protected final boolean coerce; - protected CastToByteNode(BiFunction rangeErrorHandler, BiFunction typeErrorHandler, boolean coerce) { + protected CastToByteNode(BiFunction rangeErrorHandler, BiFunction typeErrorHandler, boolean coerce) { this.rangeErrorHandler = rangeErrorHandler; this.typeErrorHandler = typeErrorHandler; this.coerce = coerce; @@ -170,27 +170,21 @@ protected byte doObject(VirtualFrame frame, Object value, return doError(value); } - private byte doError(@SuppressWarnings("unused") Object val) { - if (raiseNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - raiseNode = insert(PRaiseNode.create()); - } + private byte doError(Object val) { + errorProfile.enter(); if (typeErrorHandler != null) { - return typeErrorHandler.apply(val, raiseNode); + return typeErrorHandler.apply(this, val); } else { - throw raiseNode.raise(TypeError, ErrorMessages.INTEGER_REQUIRED_GOT, val); + throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.INTEGER_REQUIRED_GOT, val); } } private byte handleRangeError(Object val) { - if (raiseNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - raiseNode = insert(PRaiseNode.create()); - } + errorProfile.enter(); if (rangeErrorHandler != null) { - return rangeErrorHandler.apply(val, raiseNode); + return rangeErrorHandler.apply(this, val); } else { - throw raiseNode.raise(ValueError, ErrorMessages.BYTE_MUST_BE_IN_RANGE); + throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.BYTE_MUST_BE_IN_RANGE); } } @@ -209,12 +203,7 @@ public static CastToByteNode create(boolean coerce) { } @NeverDefault - public static CastToByteNode create(BiFunction rangeErrorHandler, BiFunction typeErrorHandler) { + public static CastToByteNode create(BiFunction rangeErrorHandler, BiFunction typeErrorHandler) { return CastToByteNodeGen.create(rangeErrorHandler, typeErrorHandler, false); } - - @NeverDefault - public static CastToByteNode create(BiFunction rangeErrorHandler, BiFunction typeErrorHandler, boolean coerce) { - return CastToByteNodeGen.create(rangeErrorHandler, typeErrorHandler, coerce); - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaBigIntegerNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaBigIntegerNode.java index a51aebe08b..2b1f875931 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaBigIntegerNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaBigIntegerNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -51,7 +51,6 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; @@ -59,10 +58,8 @@ import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.nodes.Node; -@TypeSystemReference(PythonArithmeticTypes.class) @GenerateUncached @GenerateInline(inlineByDefault = true) @GenerateCached @@ -101,7 +98,7 @@ protected static BigInteger fromPInt(PInt x) { @Specialization protected static BigInteger generic(Node inliningTarget, Object x, - @Cached PRaiseNode.Lazy raise, + @Cached PRaiseNode raise, @Cached(inline = false) CastToJavaBigIntegerNode rec, @Cached GetClassNode getClassNode, @Cached PyIndexCheckNode indexCheckNode, @@ -109,6 +106,6 @@ protected static BigInteger generic(Node inliningTarget, Object x, if (indexCheckNode.execute(inliningTarget, x)) { return rec.execute(null, indexNode.execute(null, inliningTarget, x)); } - throw raise.get(inliningTarget).raise(TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, getClassNode.execute(inliningTarget, x)); + throw raise.raise(inliningTarget, TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, getClassNode.execute(inliningTarget, x)); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaBooleanNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaBooleanNode.java index 40fa79e60c..78ee5de6ac 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaBooleanNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaBooleanNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -106,7 +106,7 @@ static boolean doNativeObject(Node inliningTarget, PythonNativeObject x, @Shared @Cached(inline = false) IsSubtypeNode isSubtypeNode) { if (isSubtypeNode.execute(getClassNode.execute(inliningTarget, x), PythonBuiltinClassType.Boolean)) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, ErrorMessages.CASTING_A_NATIVE_INT_OBJECT_IS_NOT_IMPLEMENTED_YET); + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, ErrorMessages.CASTING_A_NATIVE_INT_OBJECT_IS_NOT_IMPLEMENTED_YET); } // the object's type is not a subclass of 'int' throw CannotCastException.INSTANCE; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaByteNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaByteNode.java index 4e90ebee00..84ecb014d8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaByteNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaByteNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -94,33 +94,33 @@ static byte fromPInt(PInt x) { @Specialization(replaces = "fromInt") @InliningCutoff static byte fromIntErr(Node inliningTarget, int x, - @Shared("raiseNode") @Cached PRaiseNode.Lazy raiseNode) { + @Shared("raiseNode") @Cached PRaiseNode raiseNode) { try { return PInt.byteValueExact(x); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.BYTE_MUST_BE_IN_RANGE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.BYTE_MUST_BE_IN_RANGE); } } @Specialization(replaces = "fromLong") @InliningCutoff static byte fromLongErr(Node inliningTarget, long x, - @Shared("raiseNode") @Cached PRaiseNode.Lazy raiseNode) { + @Shared("raiseNode") @Cached PRaiseNode raiseNode) { try { return PInt.byteValueExact(x); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.BYTE_MUST_BE_IN_RANGE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.BYTE_MUST_BE_IN_RANGE); } } @Specialization(replaces = "fromPInt") @InliningCutoff static byte fromPIntErr(Node inliningTarget, PInt x, - @Shared("raiseNode") @Cached PRaiseNode.Lazy raiseNode) { + @Shared("raiseNode") @Cached PRaiseNode raiseNode) { try { return x.byteValueExact(); } catch (ArithmeticException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.BYTE_MUST_BE_IN_RANGE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.BYTE_MUST_BE_IN_RANGE); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaDoubleNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaDoubleNode.java index baadf51e10..7f9f6b80e1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaDoubleNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaDoubleNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -50,7 +50,7 @@ import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; +import com.oracle.graal.python.nodes.truffle.PythonIntegerAndFloatTypes; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Cached; @@ -73,8 +73,8 @@ @GenerateUncached @GenerateInline @GenerateCached(false) -@TypeSystemReference(PythonArithmeticTypes.class) @ImportStatic(MathGuards.class) +@TypeSystemReference(PythonIntegerAndFloatTypes.class) public abstract class CastToJavaDoubleNode extends PNodeWithContext { public abstract double execute(Node inliningTarget, Object x); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaIntExactNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaIntExactNode.java index 310b6d7e15..c9b3c77218 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaIntExactNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaIntExactNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -67,15 +67,15 @@ @GenerateCached public abstract class CastToJavaIntExactNode extends CastToJavaIntNode { - public final int executeWithThrowSystemError(Node inliningTarget, Object x, PRaiseNode.Lazy raiseNode) { + public final int executeWithThrowSystemError(Node inliningTarget, Object x, PRaiseNode raiseNode) { return executeWithThrow(inliningTarget, x, raiseNode, SystemError); } - public final int executeWithThrow(Node inliningTarget, Object x, PRaiseNode.Lazy raiseNode, PythonBuiltinClassType errType) { + public final int executeWithThrow(Node inliningTarget, Object x, PRaiseNode raiseNode, PythonBuiltinClassType errType) { try { return execute(inliningTarget, x); } catch (CannotCastException cce) { - throw raiseNode.get(inliningTarget).raise(errType, MUST_BE_S_NOT_P, "an int", x); + throw raiseNode.raise(inliningTarget, errType, MUST_BE_S_NOT_P, "an int", x); } } @@ -117,21 +117,21 @@ static int pIntToInt(PInt x) throws OverflowException { @Specialization(replaces = "longToInt") static int longToIntOverflow(Node inliningTarget, long x, - @Shared("raise") @Cached PRaiseNode.Lazy raiseNode) { + @Shared("raise") @Cached PRaiseNode raiseNode) { try { return PInt.intValueExact(x); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "int"); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "int"); } } @Specialization(replaces = "pIntToInt") static int pIntToIntOverflow(Node inliningTarget, PInt x, - @Shared("raise") @Cached PRaiseNode.Lazy raiseNode) { + @Shared("raise") @Cached PRaiseNode raiseNode) { try { return x.intValueExact(); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "int"); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "int"); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaIntNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaIntNode.java index d9584d01b7..7ab4b8ba5f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaIntNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaIntNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,7 +42,7 @@ import com.oracle.graal.python.builtins.modules.MathGuards; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -51,7 +51,7 @@ import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.nodes.Node; -@TypeSystemReference(PythonArithmeticTypes.class) +@TypeSystemReference(PythonIntegerTypes.class) @ImportStatic(MathGuards.class) @GenerateInline @GenerateCached(false) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaLongExactNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaLongExactNode.java index 5557e336df..0bae6be64f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaLongExactNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaLongExactNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -65,15 +65,15 @@ @GenerateCached(false) public abstract class CastToJavaLongExactNode extends CastToJavaLongNode { - public final long executeWithThrowSystemError(Node inliningTarget, Object x, PRaiseNode.Lazy raiseNode) { + public final long executeWithThrowSystemError(Node inliningTarget, Object x, PRaiseNode raiseNode) { return executeWithThrow(inliningTarget, x, raiseNode, SystemError); } - public final long executeWithThrow(Node inliningTarget, Object x, PRaiseNode.Lazy raiseNode, PythonBuiltinClassType errType) { + public final long executeWithThrow(Node inliningTarget, Object x, PRaiseNode raiseNode, PythonBuiltinClassType errType) { try { return execute(inliningTarget, x); } catch (CannotCastException cce) { - throw raiseNode.get(inliningTarget).raise(errType, MUST_BE_S_NOT_P, "a long", x); + throw raiseNode.raise(inliningTarget, errType, MUST_BE_S_NOT_P, "a long", x); } } @@ -88,11 +88,11 @@ protected static long toLongNoOverflow(PInt x) throws OverflowException { @Specialization(replaces = "toLongNoOverflow") protected static long toLong(Node inliningTarget, PInt x, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { try { return x.longValueExact(); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "long"); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "long"); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaLongNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaLongNode.java index 65f49c412c..42d2c10365 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaLongNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaLongNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -94,7 +94,7 @@ static long doNativeObject(Node inliningTarget, PythonNativeObject x, @Cached(inline = false) IsSubtypeNode isSubtypeNode) { if (isSubtypeNode.execute(getClassNode.execute(inliningTarget, x), PythonBuiltinClassType.PInt)) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, ErrorMessages.CASTING_A_NATIVE_INT_OBJECT_IS_NOT_IMPLEMENTED_YET); + throw PRaiseNode.raiseStatic(inliningTarget, NotImplementedError, ErrorMessages.CASTING_A_NATIVE_INT_OBJECT_IS_NOT_IMPLEMENTED_YET); } // the object's type is not a subclass of 'int' throw CannotCastException.INSTANCE; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaShortNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaShortNode.java index a5f9b5c724..44c254f575 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaShortNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaShortNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -92,31 +92,31 @@ static short fromPInt(PInt x) { @Specialization(replaces = "fromInt") static short fromIntErr(Node inliningTarget, int x, - @Shared("raiseNode") @Cached PRaiseNode.Lazy raiseNode) { + @Shared("raiseNode") @Cached PRaiseNode raiseNode) { try { return PInt.shortValueExact(x); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.SHORT_MUST_BE_IN_RANGE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.SHORT_MUST_BE_IN_RANGE); } } @Specialization(replaces = "fromLong") static short fromLongErr(Node inliningTarget, long x, - @Shared("raiseNode") @Cached PRaiseNode.Lazy raiseNode) { + @Shared("raiseNode") @Cached PRaiseNode raiseNode) { try { return PInt.shortValueExact(x); } catch (OverflowException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.SHORT_MUST_BE_IN_RANGE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.SHORT_MUST_BE_IN_RANGE); } } @Specialization(replaces = "fromPInt") static short fromPIntErr(Node inliningTarget, PInt x, - @Shared("raiseNode") @Cached PRaiseNode.Lazy raiseNode) { + @Shared("raiseNode") @Cached PRaiseNode raiseNode) { try { return x.shortValueExact(); } catch (ArithmeticException e) { - throw raiseNode.get(inliningTarget).raise(PythonBuiltinClassType.ValueError, ErrorMessages.SHORT_MUST_BE_IN_RANGE); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.SHORT_MUST_BE_IN_RANGE); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaUnsignedLongNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaUnsignedLongNode.java index 729cf92e31..c825a8e1ae 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaUnsignedLongNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaUnsignedLongNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -49,7 +49,7 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; +import com.oracle.graal.python.nodes.truffle.PythonIntegerTypes; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; @@ -72,7 +72,7 @@ * Note that since Java {@code long} is signed, the values in the between 2^63 and 2^64-1 are * returned as negative numbers. */ -@TypeSystemReference(PythonArithmeticTypes.class) +@TypeSystemReference(PythonIntegerTypes.class) @GenerateUncached @GenerateInline @GenerateCached(false) @@ -85,34 +85,33 @@ public static long executeUncached(Object arg) { @Specialization static long toUnsignedLong(Node inliningTarget, long x, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { checkNegative(x < 0, inliningTarget, raiseNode); return x; } @Specialization static long toUnsignedLong(Node inliningTarget, PInt x, - @Shared @Cached PRaiseNode.Lazy raiseNode) { + @Shared @Cached PRaiseNode raiseNode) { checkNegative(x.isNegative(), inliningTarget, raiseNode); return convertBigInt(x.getValue(), inliningTarget); } @Fallback - static long doUnsupported(Node inliningTarget, @SuppressWarnings("unused") Object x, - @Shared @Cached PRaiseNode.Lazy raiseNode) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.INTEGER_REQUIRED); + static long doUnsupported(Node inliningTarget, @SuppressWarnings("unused") Object x) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.INTEGER_REQUIRED); } - private static void checkNegative(boolean negative, Node inliningTarget, PRaiseNode.Lazy raiseNode) { + private static void checkNegative(boolean negative, Node inliningTarget, PRaiseNode raiseNode) { if (negative) { - throw raiseNode.get(inliningTarget).raise(OverflowError, ErrorMessages.CANNOT_CONVERT_NEGATIVE_VALUE_TO_UNSIGNED_INT); + throw raiseNode.raise(inliningTarget, OverflowError, ErrorMessages.CANNOT_CONVERT_NEGATIVE_VALUE_TO_UNSIGNED_INT); } } @TruffleBoundary private static long convertBigInt(BigInteger bi, Node nodeForRaise) { if (bi.bitLength() > 64) { - throw PRaiseNode.raiseUncached(nodeForRaise, OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "unsigned long"); + throw PRaiseNode.raiseStatic(nodeForRaise, OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "unsigned long"); } return bi.longValue(); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CoerceToComplexNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CoerceToComplexNode.java index a601e6518a..848adfa7c2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CoerceToComplexNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CoerceToComplexNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,6 +42,7 @@ import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.complex.PComplex; import com.oracle.graal.python.lib.PyFloatAsDoubleNode; @@ -50,10 +51,10 @@ import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.nodes.truffle.PythonIntegerAndFloatTypes; +import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.ImportStatic; @@ -64,7 +65,7 @@ @GenerateInline @GenerateCached(false) -@TypeSystemReference(PythonArithmeticTypes.class) +@TypeSystemReference(PythonIntegerAndFloatTypes.class) @ImportStatic(PGuards.class) public abstract class CoerceToComplexNode extends PNodeWithContext { @@ -72,14 +73,14 @@ public abstract class CoerceToComplexNode extends PNodeWithContext { @Specialization static PComplex doLong(long x, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createComplex(x, 0); + @Bind PythonLanguage language) { + return PFactory.createComplex(language, x, 0); } @Specialization static PComplex doDouble(double x, - @Shared @Cached(inline = false) PythonObjectFactory factory) { - return factory.createComplex(x, 0); + @Bind PythonLanguage language) { + return PFactory.createComplex(language, x, 0); } @Specialization @@ -91,8 +92,8 @@ static PComplex doComplex(PComplex x) { static PComplex toComplex(VirtualFrame frame, Node inliningTarget, Object x, @Cached(value = "create(T___COMPLEX__)", inline = false) LookupAndCallUnaryNode callComplexFunc, @Cached PyFloatAsDoubleNode asDoubleNode, - @Shared @Cached(inline = false) PythonObjectFactory factory, - @Cached PRaiseNode.Lazy raiseNode) { + @Bind PythonLanguage language, + @Cached PRaiseNode raiseNode) { Object result = callComplexFunc.executeObject(frame, x); if (result != PNone.NO_VALUE) { if (result instanceof PComplex) { @@ -103,9 +104,9 @@ static PComplex toComplex(VirtualFrame frame, Node inliningTarget, Object x, // and may be removed in a future version of Python. return (PComplex) result; } else { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.SHOULD_RETURN, "__complex__", "complex object"); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.SHOULD_RETURN, "__complex__", "complex object"); } } - return factory.createComplex(asDoubleNode.execute(frame, inliningTarget, x), 0); + return PFactory.createComplex(language, asDoubleNode.execute(frame, inliningTarget, x), 0); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/NarrowBigIntegerNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/NarrowBigIntegerNode.java index 66c6f99559..ba7025a57e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/NarrowBigIntegerNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/NarrowBigIntegerNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,9 +42,10 @@ import java.math.BigInteger; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -72,14 +73,13 @@ static Object narrowBigInteger0(@SuppressWarnings("unused") BigInteger x) { @Specialization(guards = "x.signum() != 0") static Object narrowBigInteger(Node inliningTarget, BigInteger x, @Cached InlinedConditionProfile fitsIntProfile, - @Cached InlinedConditionProfile fitsLongProfile, - @Cached(inline = false) PythonObjectFactory factory) { + @Cached InlinedConditionProfile fitsLongProfile) { if (fitsIntProfile.profile(inliningTarget, PInt.fitsIn(x, PInt.MIN_INT, PInt.MAX_INT))) { return PInt.intValue(x); } if (fitsLongProfile.profile(inliningTarget, PInt.fitsIn(x, PInt.MIN_LONG, PInt.MAX_LONG))) { return PInt.longValue(x); } - return factory.createInt(x); + return PFactory.createInt(PythonLanguage.get(inliningTarget), x); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/AsyncHandler.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/AsyncHandler.java index d714ad6cf6..026324c85e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/AsyncHandler.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/AsyncHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,6 +46,7 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; +import java.util.Objects; import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; @@ -54,14 +55,12 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import org.graalvm.nativeimage.ImageInfo; - import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.function.Signature; import com.oracle.graal.python.nodes.PRootNode; import com.oracle.graal.python.nodes.call.CallNode; -import com.oracle.graal.python.nodes.call.GenericInvokeNode; +import com.oracle.graal.python.nodes.call.CallDispatchers; import com.oracle.graal.python.nodes.frame.ReadCallerFrameNode; import com.oracle.graal.python.runtime.ExecutionContext.CalleeContext; import com.oracle.graal.python.runtime.exception.ExceptionUtils; @@ -156,7 +155,7 @@ public final void execute(PythonContext context) { } debugger.disableStepping(); try { - GenericInvokeNode.getUncached().execute(context.getAsyncHandler().callTarget, args); + CallDispatchers.SimpleIndirectInvokeNode.executeUncached(context.getAsyncHandler().callTarget, args); } catch (PException e) { handleException(e); } finally { @@ -316,10 +315,11 @@ public boolean setsUpCalleeContext() { * regular intervals to run on a separate thread, or if it will be polled. The caller needs to * ensure that the AsyncAction passed into this method does not block in the latter case. */ - @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH") // context.get() is never null here + @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH") // incorrect warning void registerAction(Supplier actionSupplier) { CompilerAsserts.neverPartOfCompilation(); - if (ImageInfo.inImageBuildtimeCode() || context.get().getOption(PythonOptions.NoAsyncActions)) { + var context = Objects.requireNonNull(this.context.get()); + if (context.getEnv().isPreInitialization() || context.getOption(PythonOptions.NoAsyncActions)) { return; } if (PythonOptions.AUTOMATIC_ASYNC_ACTIONS) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/EmulatedPosixSupport.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/EmulatedPosixSupport.java index 5a8afb7fe1..d8d92c94d5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/EmulatedPosixSupport.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/EmulatedPosixSupport.java @@ -251,6 +251,7 @@ import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.TruffleLogger; +import com.oracle.truffle.api.TruffleOptions; import com.oracle.truffle.api.TruffleSafepoint; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -361,7 +362,7 @@ static UnsupportedPosixFeatureException createUnsupportedFeature(String message) @Override public void setEnv(Env env) { super.setEnv(env); - if (!ImageInfo.inImageBuildtimeCode()) { + if (!env.isPreInitialization()) { environ.putAll(env.getEnvironment()); } } @@ -996,6 +997,36 @@ public int[] getTerminalSize(int fd) throws PosixException { return new int[]{context.getOption(PythonOptions.TerminalWidth), context.getOption(PythonOptions.TerminalHeight)}; } + @ExportMessage + @TruffleBoundary + public long sysconf(int name) throws PosixException { + // Constants derived from POSIX specs or common kernel configs + if (name == PosixConstants._SC_ARG_MAX.value) { + return 4096; + } else if (name == PosixConstants._SC_CHILD_MAX.value) { + return 25; + } else if (name == PosixConstants._SC_LOGIN_NAME_MAX.value) { + return 255; + } else if (name == PosixConstants._SC_CLK_TCK.value) { + return 100; + } else if (name == PosixConstants._SC_OPEN_MAX.value) { + return 20; + } else if (name == PosixConstants._SC_PAGESIZE.value) { + return 4096; + } else if (name == PosixConstants._SC_PAGE_SIZE.value) { + return 4096; + } else if (name == PosixConstants._SC_SEM_NSEMS_MAX.value) { + return 32; + } else if (name == PosixConstants._SC_PHYS_PAGES.value) { + return Runtime.getRuntime().totalMemory() / 4096; + } else if (name == PosixConstants._SC_NPROCESSORS_CONF.value) { + return Runtime.getRuntime().availableProcessors(); + } else if (name == PosixConstants._SC_NPROCESSORS_ONLN.value) { + return Runtime.getRuntime().availableProcessors(); + } + throw posixException(OSErrorEnum.EINVAL); + } + @ExportMessage public long[] fstatat(int dirFd, Object path, boolean followSymlinks, @Bind("$node") Node inliningTarget, @@ -1289,7 +1320,7 @@ private static int posixPermissionsToMode(int inputMode, final Setgot_exception in * their code is handled automatically by the Truffle lazy exceptions, so here we only @@ -234,12 +309,12 @@ public void exit(VirtualFrame frame, PRootNode node) { PFrame.Reference info = PArguments.getCurrentFrameInfo(frame); CompilerAsserts.partialEvaluationConstant(node); if (node.getFrameEscapedProfile().profile(info.isEscaped())) { - exitEscaped(frame, node, info); + exitEscaped(frame, node, location, info); } } @InliningCutoff - private void exitEscaped(VirtualFrame frame, PRootNode node, Reference info) { + private void exitEscaped(VirtualFrame frame, PRootNode node, Node location, Reference info) { if (!everEscaped) { CompilerDirectives.transferToInterpreterAndInvalidate(); everEscaped = true; @@ -267,7 +342,7 @@ private void exitEscaped(VirtualFrame frame, PRootNode node, Reference info) { } // force the frame so that it can be accessed later - ensureMaterializeNode().execute(frame, node, false, true); + ensureMaterializeNode().execute(frame, location, false, true); // if this frame escaped we must ensure that also f_back does callerInfo.markAsEscaped(); info.setBackref(callerInfo); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/IndirectCallData.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/IndirectCallData.java index f243370e36..ecb2d1b573 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/IndirectCallData.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/IndirectCallData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,7 +41,6 @@ package com.oracle.graal.python.runtime; import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.nodes.call.InvokeNode; import com.oracle.truffle.api.Assumption; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; @@ -104,10 +103,6 @@ public void setCalleeNeedsExceptionState() { public static boolean setEncapsulatingNeedsToPassCallerFrame(final Node callNode) { Node pythonCallNode = callNode; while (pythonCallNode != null) { - if (pythonCallNode instanceof InvokeNode) { - // see GR-50465 - return true; - } IndirectCallData data = PythonLanguage.lookupIndirectCallData(pythonCallNode); if (data != null) { data.setCalleeNeedsCallerFrame(); @@ -121,10 +116,6 @@ public static boolean setEncapsulatingNeedsToPassCallerFrame(final Node callNode public static void setEncapsulatingNeedsToPassExceptionState(Node callNode) { Node pythonCallNode = callNode; while (pythonCallNode != null) { - if (pythonCallNode instanceof InvokeNode) { - // see GR-50465 - break; - } IndirectCallData data = PythonLanguage.lookupIndirectCallData(pythonCallNode); if (data != null) { data.setCalleeNeedsExceptionState(); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/LoggingPosixSupport.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/LoggingPosixSupport.java index 2c023ccfbc..042b782152 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/LoggingPosixSupport.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/LoggingPosixSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -361,6 +361,17 @@ final int[] getTerminalSize(int fd, } } + @ExportMessage + final long sysconf(int name, + @CachedLibrary("this.delegate") PosixSupportLibrary lib) throws PosixException { + logEnter("sysconf", "%d", name); + try { + return logExit("sysconf", "%s", lib.sysconf(delegate, name)); + } catch (PosixException e) { + throw logException("sysconf", e); + } + } + @ExportMessage final long[] fstatat(int dirFd, Object pathname, boolean followSymlinks, @CachedLibrary("this.delegate") PosixSupportLibrary lib) throws PosixException { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/NFIPosixSupport.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/NFIPosixSupport.java index f38d0d289a..ba4279a864 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/NFIPosixSupport.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/NFIPosixSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,7 +44,6 @@ import static com.oracle.graal.python.nodes.StringLiterals.J_DEFAULT; import static com.oracle.graal.python.nodes.StringLiterals.J_NATIVE; import static com.oracle.graal.python.nodes.StringLiterals.J_NFI_LANGUAGE; -import static com.oracle.graal.python.nodes.StringLiterals.T_LLVM_LANGUAGE; import static com.oracle.graal.python.nodes.StringLiterals.T_NATIVE; import static com.oracle.graal.python.runtime.NFIPosixConstants.OFFSETOF_STRUCT_IN6_ADDR_S6_ADDR; import static com.oracle.graal.python.runtime.NFIPosixConstants.OFFSETOF_STRUCT_IN_ADDR_S_ADDR; @@ -89,8 +88,6 @@ import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.logging.Level; -import org.graalvm.nativeimage.ImageInfo; - import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonOS; @@ -307,6 +304,8 @@ private enum PosixNativeFunction { call_ioctl_bytes("(sint32, uint64, [sint8]):sint32"), call_ioctl_int("(sint32, uint64, sint32):sint32"), + call_sysconf("(sint32):sint64"), + crypt("([sint8], [sint8]):sint64"); private final String signature; @@ -455,7 +454,7 @@ public InteropLibrary getResultInterop() { @CompilationFinal(dimensions = 1) private long[] constantValues; public NFIPosixSupport(PythonContext context, TruffleString nfiBackend) { - assert nfiBackend.equalsUncached(T_NATIVE, TS_ENCODING) || nfiBackend.equalsUncached(T_LLVM_LANGUAGE, TS_ENCODING); + assert nfiBackend.equalsUncached(T_NATIVE, TS_ENCODING); this.context = context; this.nfiBackend = nfiBackend; this.cachedFunctions = new AtomicReferenceArray<>(PosixNativeFunction.values().length); @@ -476,7 +475,7 @@ long getConstant(NFIPosixConstants constant) { @Override public void setEnv(Env env) { - if (ImageInfo.inImageBuildtimeCode()) { + if (env.isPreInitialization()) { return; } // Java NIO (and TruffleFile) do not expect/support changing native working directory since @@ -752,6 +751,19 @@ public int[] getTerminalSize(int fd, return size; } + @ExportMessage + public long sysconf(int name, + @Shared("invoke") @Cached InvokeNativeFunction invokeNode) throws PosixException { + long result = invokeNode.callLong(this, PosixNativeFunction.call_sysconf, name); + if (result == -1) { + int errno = getErrno(invokeNode); + if (errno != 0) { + throw newPosixException(invokeNode, errno); + } + } + return result; + } + @ExportMessage public long[] fstatat(int dirFd, Object pathname, boolean followSymlinks, @Shared("invoke") @Cached InvokeNativeFunction invokeNode) throws PosixException { @@ -1902,7 +1914,7 @@ public TruffleString crypt(TruffleString word, TruffleString salt, cryptLibrary = InvokeNativeFunction.loadLibrary(this, PythonOS.getPythonOS() != PythonOS.PLATFORM_DARWIN ? "libcrypt.so" : null); } catch (Throwable e) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(invokeNode, PythonBuiltinClassType.SystemError, ErrorMessages.UNABLE_TO_LOAD_LIBCRYPT); + throw PRaiseNode.raiseStatic(invokeNode, PythonBuiltinClassType.SystemError, ErrorMessages.UNABLE_TO_LOAD_LIBCRYPT); } } PosixNativeFunction function = PosixNativeFunction.crypt; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/NativeBufferContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/NativeBufferContext.java index 46e7f44904..b42b0c932d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/NativeBufferContext.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/NativeBufferContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,7 +44,7 @@ import java.util.concurrent.ConcurrentHashMap; import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext; +import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext; import com.oracle.graal.python.runtime.native_memory.NativeBuffer; import com.oracle.graal.python.runtime.native_memory.NativePrimitiveReference; import com.oracle.graal.python.runtime.sequence.storage.NativeIntSequenceStorage; @@ -107,7 +107,7 @@ private ReferenceQueue getReferenceQueue() { } static final class NativeBufferDeallocatorRunnable extends PythonSystemThreadTask { - private static final TruffleLogger LOGGER = GraalHPyContext.getLogger(NativeBufferDeallocatorRunnable.class); + private static final TruffleLogger LOGGER = CApiContext.getLogger(NativeBufferDeallocatorRunnable.class); private final ReferenceQueue referenceQueue; private final ConcurrentHashMap references; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstants.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstants.java index ce050b11e4..b67dedc9fa 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstants.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -332,6 +332,39 @@ public final class PosixConstants { public static final OptionalIntConstant IPV6_RECVPATHMTU; public static final OptionalIntConstant IPV6_TCLASS; public static final OptionalIntConstant IPV6_USE_MIN_MTU; + public static final MandatoryIntConstant _SC_ARG_MAX; + public static final MandatoryIntConstant _SC_CHILD_MAX; + public static final OptionalIntConstant _SC_HOST_NAME_MAX; + public static final MandatoryIntConstant _SC_LOGIN_NAME_MAX; + public static final OptionalIntConstant _SC_NGROUPS_MAX; + public static final MandatoryIntConstant _SC_CLK_TCK; + public static final MandatoryIntConstant _SC_OPEN_MAX; + public static final MandatoryIntConstant _SC_PAGESIZE; + public static final MandatoryIntConstant _SC_PAGE_SIZE; + public static final OptionalIntConstant _SC_RE_DUP_MAX; + public static final OptionalIntConstant _SC_STREAM_MAX; + public static final OptionalIntConstant _SC_SYMLOOP_MAX; + public static final OptionalIntConstant _SC_TTY_NAME_MAX; + public static final OptionalIntConstant _SC_TZNAME_MAX; + public static final OptionalIntConstant _SC_VERSION; + public static final OptionalIntConstant _SC_BC_BASE_MAX; + public static final OptionalIntConstant _SC_BC_DIM_MAX; + public static final OptionalIntConstant _SC_BC_SCALE_MAX; + public static final OptionalIntConstant _SC_BC_STRING_MAX; + public static final OptionalIntConstant _SC_COLL_WEIGHTS_MAX; + public static final OptionalIntConstant _SC_EXPR_NEST_MAX; + public static final OptionalIntConstant _SC_LINE_MAX; + public static final OptionalIntConstant _SC_2_VERSION; + public static final OptionalIntConstant _SC_2_C_DEV; + public static final OptionalIntConstant _SC_2_FORT_DEV; + public static final OptionalIntConstant _SC_2_FORT_RUN; + public static final OptionalIntConstant _SC_2_LOCALEDEF; + public static final OptionalIntConstant _SC_2_SW_DEV; + public static final MandatoryIntConstant _SC_SEM_NSEMS_MAX; + public static final MandatoryIntConstant _SC_PHYS_PAGES; + public static final OptionalIntConstant _SC_AVPHYS_PAGES; + public static final MandatoryIntConstant _SC_NPROCESSORS_CONF; + public static final MandatoryIntConstant _SC_NPROCESSORS_ONLN; public static final IntConstant[] openFlags; public static final IntConstant[] fileType; @@ -355,6 +388,7 @@ public final class PosixConstants { public static final IntConstant[] socketOptions; public static final IntConstant[] tcpOptions; public static final IntConstant[] ipv6Options; + public static final IntConstant[] sysconfigNames; static { Registry reg = Registry.create(); @@ -614,6 +648,39 @@ public final class PosixConstants { IPV6_RECVPATHMTU = reg.createOptionalInt("IPV6_RECVPATHMTU"); IPV6_TCLASS = reg.createOptionalInt("IPV6_TCLASS"); IPV6_USE_MIN_MTU = reg.createOptionalInt("IPV6_USE_MIN_MTU"); + _SC_ARG_MAX = reg.createMandatoryInt("_SC_ARG_MAX"); + _SC_CHILD_MAX = reg.createMandatoryInt("_SC_CHILD_MAX"); + _SC_HOST_NAME_MAX = reg.createOptionalInt("_SC_HOST_NAME_MAX"); + _SC_LOGIN_NAME_MAX = reg.createMandatoryInt("_SC_LOGIN_NAME_MAX"); + _SC_NGROUPS_MAX = reg.createOptionalInt("_SC_NGROUPS_MAX"); + _SC_CLK_TCK = reg.createMandatoryInt("_SC_CLK_TCK"); + _SC_OPEN_MAX = reg.createMandatoryInt("_SC_OPEN_MAX"); + _SC_PAGESIZE = reg.createMandatoryInt("_SC_PAGESIZE"); + _SC_PAGE_SIZE = reg.createMandatoryInt("_SC_PAGE_SIZE"); + _SC_RE_DUP_MAX = reg.createOptionalInt("_SC_RE_DUP_MAX"); + _SC_STREAM_MAX = reg.createOptionalInt("_SC_STREAM_MAX"); + _SC_SYMLOOP_MAX = reg.createOptionalInt("_SC_SYMLOOP_MAX"); + _SC_TTY_NAME_MAX = reg.createOptionalInt("_SC_TTY_NAME_MAX"); + _SC_TZNAME_MAX = reg.createOptionalInt("_SC_TZNAME_MAX"); + _SC_VERSION = reg.createOptionalInt("_SC_VERSION"); + _SC_BC_BASE_MAX = reg.createOptionalInt("_SC_BC_BASE_MAX"); + _SC_BC_DIM_MAX = reg.createOptionalInt("_SC_BC_DIM_MAX"); + _SC_BC_SCALE_MAX = reg.createOptionalInt("_SC_BC_SCALE_MAX"); + _SC_BC_STRING_MAX = reg.createOptionalInt("_SC_BC_STRING_MAX"); + _SC_COLL_WEIGHTS_MAX = reg.createOptionalInt("_SC_COLL_WEIGHTS_MAX"); + _SC_EXPR_NEST_MAX = reg.createOptionalInt("_SC_EXPR_NEST_MAX"); + _SC_LINE_MAX = reg.createOptionalInt("_SC_LINE_MAX"); + _SC_2_VERSION = reg.createOptionalInt("_SC_2_VERSION"); + _SC_2_C_DEV = reg.createOptionalInt("_SC_2_C_DEV"); + _SC_2_FORT_DEV = reg.createOptionalInt("_SC_2_FORT_DEV"); + _SC_2_FORT_RUN = reg.createOptionalInt("_SC_2_FORT_RUN"); + _SC_2_LOCALEDEF = reg.createOptionalInt("_SC_2_LOCALEDEF"); + _SC_2_SW_DEV = reg.createOptionalInt("_SC_2_SW_DEV"); + _SC_SEM_NSEMS_MAX = reg.createMandatoryInt("_SC_SEM_NSEMS_MAX"); + _SC_PHYS_PAGES = reg.createMandatoryInt("_SC_PHYS_PAGES"); + _SC_AVPHYS_PAGES = reg.createOptionalInt("_SC_AVPHYS_PAGES"); + _SC_NPROCESSORS_CONF = reg.createMandatoryInt("_SC_NPROCESSORS_CONF"); + _SC_NPROCESSORS_ONLN = reg.createMandatoryInt("_SC_NPROCESSORS_ONLN"); openFlags = new IntConstant[]{O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_TRUNC, O_APPEND, O_NONBLOCK, O_NOCTTY, O_NDELAY, O_DSYNC, O_CLOEXEC, O_SYNC, O_DIRECT, O_RSYNC, O_TMPFILE, O_TEMPORARY, O_DIRECTORY, O_BINARY, O_TEXT, O_XATTR, O_LARGEFILE, O_SHLOCK, O_EXLOCK, O_EXEC, O_SEARCH, O_PATH, O_TTY_INIT}; @@ -646,6 +713,10 @@ public final class PosixConstants { ipv6Options = new IntConstant[]{IPV6_JOIN_GROUP, IPV6_LEAVE_GROUP, IPV6_MULTICAST_HOPS, IPV6_MULTICAST_IF, IPV6_MULTICAST_LOOP, IPV6_UNICAST_HOPS, IPV6_V6ONLY, IPV6_CHECKSUM, IPV6_DONTFRAG, IPV6_DSTOPTS, IPV6_HOPLIMIT, IPV6_HOPOPTS, IPV6_NEXTHOP, IPV6_PATHMTU, IPV6_PKTINFO, IPV6_RECVDSTOPTS, IPV6_RECVHOPLIMIT, IPV6_RECVHOPOPTS, IPV6_RECVPKTINFO, IPV6_RECVRTHDR, IPV6_RECVTCLASS, IPV6_RTHDR, IPV6_RTHDRDSTOPTS, IPV6_RTHDR_TYPE_0, IPV6_RECVPATHMTU, IPV6_TCLASS, IPV6_USE_MIN_MTU}; + sysconfigNames = new IntConstant[]{_SC_ARG_MAX, _SC_CHILD_MAX, _SC_HOST_NAME_MAX, _SC_LOGIN_NAME_MAX, _SC_NGROUPS_MAX, _SC_CLK_TCK, _SC_OPEN_MAX, _SC_PAGESIZE, _SC_PAGE_SIZE, _SC_RE_DUP_MAX, + _SC_STREAM_MAX, _SC_SYMLOOP_MAX, _SC_TTY_NAME_MAX, _SC_TZNAME_MAX, _SC_VERSION, _SC_BC_BASE_MAX, _SC_BC_DIM_MAX, _SC_BC_SCALE_MAX, _SC_BC_STRING_MAX, _SC_COLL_WEIGHTS_MAX, + _SC_EXPR_NEST_MAX, _SC_LINE_MAX, _SC_2_VERSION, _SC_2_C_DEV, _SC_2_FORT_DEV, _SC_2_FORT_RUN, _SC_2_LOCALEDEF, _SC_2_SW_DEV, _SC_SEM_NSEMS_MAX, _SC_PHYS_PAGES, _SC_AVPHYS_PAGES, + _SC_NPROCESSORS_CONF, _SC_NPROCESSORS_ONLN}; } // end generated by gen_native_cfg.py // @formatter:on diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstantsDarwin.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstantsDarwin.java index 2ae39c5780..a6ac5ddfe8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstantsDarwin.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstantsDarwin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -242,5 +242,22 @@ static void getConstants(PosixConstants.Registry constants) { constants.put("IPV6_RECVTCLASS", 35); constants.put("IPV6_RTHDR_TYPE_0", 0); constants.put("IPV6_TCLASS", 36); + constants.put("_SC_ARG_MAX", 1); + constants.put("_SC_CHILD_MAX", 2); + constants.put("_SC_LOGIN_NAME_MAX", 73); + constants.put("_SC_NGROUPS_MAX", 4); + constants.put("_SC_CLK_TCK", 3); + constants.put("_SC_OPEN_MAX", 5); + constants.put("_SC_PAGESIZE", 29); + constants.put("_SC_PAGE_SIZE", 29); + constants.put("_SC_RE_DUP_MAX", 16); + constants.put("_SC_STREAM_MAX", 26); + constants.put("_SC_TTY_NAME_MAX", 101); + constants.put("_SC_TZNAME_MAX", 27); + constants.put("_SC_VERSION", 8); + constants.put("_SC_SEM_NSEMS_MAX", 49); + constants.put("_SC_PHYS_PAGES", 200); + constants.put("_SC_NPROCESSORS_CONF", 83); + constants.put("_SC_NPROCESSORS_ONLN", 84); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstantsLinux.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstantsLinux.java index 97c90ef632..8b82c45635 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstantsLinux.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstantsLinux.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,8 +40,8 @@ */ package com.oracle.graal.python.runtime; -// Auto generated by gen_native_cfg.py at 2023-10-20 10:35:45.655413 -// on Linux arisu 6.5.7-100.fc37.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Oct 11 03:54:39 UTC 2023 x86_64 x86_64 +// Auto generated by gen_native_cfg.py at 2025-05-20 13:24:18.395774 +// on Linux FrankTheTank 5.15.167.4-microsoft-standard-WSL2 #1 SMP Tue Nov 5 00:21:55 UTC 2024 x86_64 x86_64 class PosixConstantsLinux { private PosixConstantsLinux() { @@ -290,5 +290,38 @@ static void getConstants(PosixConstants.Registry constants) { constants.put("IPV6_RTHDR_TYPE_0", 0); constants.put("IPV6_RECVPATHMTU", 60); constants.put("IPV6_TCLASS", 67); + constants.put("_SC_ARG_MAX", 0); + constants.put("_SC_CHILD_MAX", 1); + constants.put("_SC_HOST_NAME_MAX", 180); + constants.put("_SC_LOGIN_NAME_MAX", 71); + constants.put("_SC_NGROUPS_MAX", 3); + constants.put("_SC_CLK_TCK", 2); + constants.put("_SC_OPEN_MAX", 4); + constants.put("_SC_PAGESIZE", 30); + constants.put("_SC_PAGE_SIZE", 30); + constants.put("_SC_RE_DUP_MAX", 44); + constants.put("_SC_STREAM_MAX", 5); + constants.put("_SC_SYMLOOP_MAX", 173); + constants.put("_SC_TTY_NAME_MAX", 72); + constants.put("_SC_TZNAME_MAX", 6); + constants.put("_SC_VERSION", 29); + constants.put("_SC_BC_BASE_MAX", 36); + constants.put("_SC_BC_DIM_MAX", 37); + constants.put("_SC_BC_SCALE_MAX", 38); + constants.put("_SC_BC_STRING_MAX", 39); + constants.put("_SC_COLL_WEIGHTS_MAX", 40); + constants.put("_SC_EXPR_NEST_MAX", 42); + constants.put("_SC_LINE_MAX", 43); + constants.put("_SC_2_VERSION", 46); + constants.put("_SC_2_C_DEV", 48); + constants.put("_SC_2_FORT_DEV", 49); + constants.put("_SC_2_FORT_RUN", 50); + constants.put("_SC_2_LOCALEDEF", 52); + constants.put("_SC_2_SW_DEV", 51); + constants.put("_SC_SEM_NSEMS_MAX", 32); + constants.put("_SC_PHYS_PAGES", 85); + constants.put("_SC_AVPHYS_PAGES", 86); + constants.put("_SC_NPROCESSORS_CONF", 83); + constants.put("_SC_NPROCESSORS_ONLN", 84); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstantsWin32.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstantsWin32.java index 076fa3e7b0..fd441c7f4f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstantsWin32.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixConstantsWin32.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -215,5 +215,16 @@ static void getConstants(PosixConstants.Registry constants) { constants.put("IPV6_RECVTCLASS", 40); constants.put("IPV6_RTHDR", 32); constants.put("IPV6_TCLASS", 39); + constants.put("_SC_ARG_MAX", 0); + constants.put("_SC_CHILD_MAX", 1); + constants.put("_SC_LOGIN_NAME_MAX", 2); + constants.put("_SC_CLK_TCK", 3); + constants.put("_SC_OPEN_MAX", 4); + constants.put("_SC_PAGESIZE", 5); + constants.put("_SC_PAGE_SIZE", 5); + constants.put("_SC_SEM_NSEMS_MAX", 7); + constants.put("_SC_PHYS_PAGES", 8); + constants.put("_SC_NPROCESSORS_CONF", 9); + constants.put("_SC_NPROCESSORS_ONLN", 9); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixSupportLibrary.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixSupportLibrary.java index e92f0af5fc..0e91cfba18 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixSupportLibrary.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixSupportLibrary.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -125,6 +125,8 @@ public abstract class PosixSupportLibrary extends Library { public abstract int[] getTerminalSize(Object receiver, int fd) throws PosixException; + public abstract long sysconf(Object receiver, int name) throws PosixException; + // see stat_struct_to_longs in posix.c for the layout of the array public abstract long[] fstatat(Object receiver, int dirFd, Object pathname, boolean followSymlinks) throws PosixException; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ImageBuildtimePosixSupport.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PreInitPosixSupport.java similarity index 87% rename from graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ImageBuildtimePosixSupport.java rename to graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PreInitPosixSupport.java index 078a154f4f..a4d36183e5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ImageBuildtimePosixSupport.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PreInitPosixSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -45,8 +45,6 @@ import java.util.HashSet; import java.util.IdentityHashMap; -import org.graalvm.nativeimage.ImageInfo; - import com.oracle.graal.python.runtime.PosixSupportLibrary.AcceptResult; import com.oracle.graal.python.runtime.PosixSupportLibrary.AddrInfoCursor; import com.oracle.graal.python.runtime.PosixSupportLibrary.Buffer; @@ -72,14 +70,16 @@ import com.oracle.truffle.api.strings.TruffleString; @ExportLibrary(PosixSupportLibrary.class) -public class ImageBuildtimePosixSupport extends PosixSupport { +public class PreInitPosixSupport extends PosixSupport { protected final PosixSupport nativePosixSupport; private PosixSupport emulatedPosixSupport; private HashSet emulatedFds; private IdentityHashMap emulatedDirStreams; + private boolean inPreInitialization; - public ImageBuildtimePosixSupport(PosixSupport nativePosixSupport, PosixSupport emulatedPosixSupport) { + public PreInitPosixSupport(Env env, PosixSupport nativePosixSupport, PosixSupport emulatedPosixSupport) { + this.inPreInitialization = env.isPreInitialization(); this.nativePosixSupport = nativePosixSupport; this.emulatedPosixSupport = emulatedPosixSupport; if (emulatedPosixSupport != null) { @@ -90,12 +90,13 @@ public ImageBuildtimePosixSupport(PosixSupport nativePosixSupport, PosixSupport @Override public void setEnv(Env env) { - assert !ImageInfo.inImageBuildtimeCode(); + assert !env.isPreInitialization(); + this.inPreInitialization = env.isPreInitialization(); nativePosixSupport.setEnv(env); } public void checkLeakingResources() { - assert ImageInfo.inImageBuildtimeCode(); + assert inPreInitialization; if (!emulatedFds.isEmpty()) { throw shouldNotReachHere("Emulated fds leaked into the image"); } @@ -107,9 +108,9 @@ public void checkLeakingResources() { emulatedDirStreams = null; } - private static void checkNotInImageBuildtime() { - if (ImageInfo.inImageBuildtimeCode()) { - throw shouldNotReachHere("Posix call not expected during image buildtime"); + private void checkNotInPreInitialization() { + if (inPreInitialization) { + throw shouldNotReachHere("Posix call not expected during pre-initialization"); } } @@ -151,34 +152,34 @@ private Object removeDirStream(Object dirStream) { @ExportMessage final TruffleString getBackend(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getBackend(nativePosixSupport); } @ExportMessage final TruffleString strerror(int errorCode, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.strerror(nativePosixSupport, errorCode); } @ExportMessage final long getpid(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getpid(nativePosixSupport); } @ExportMessage final int umask(int mask, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.umask(nativePosixSupport, mask); } @ExportMessage final int openat(int dirFd, Object pathname, int flags, int mode, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { return addFd(PosixSupportLibrary.getUncached().openat(emulatedPosixSupport, dirFd, pathname, flags, mode)); } return nativeLib.openat(nativePosixSupport, dirFd, pathname, flags, mode); @@ -187,7 +188,7 @@ final int openat(int dirFd, Object pathname, int flags, int mode, @ExportMessage final int close(int fd, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { return PosixSupportLibrary.getUncached().close(emulatedPosixSupport, removeFd(fd)); } return nativeLib.close(nativePosixSupport, fd); @@ -196,7 +197,7 @@ final int close(int fd, @ExportMessage final Buffer read(int fd, long length, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { return PosixSupportLibrary.getUncached().read(emulatedPosixSupport, fd, length); } return nativeLib.read(nativePosixSupport, fd, length); @@ -205,35 +206,35 @@ final Buffer read(int fd, long length, @ExportMessage final long write(int fd, Buffer data, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.write(nativePosixSupport, fd, data); } @ExportMessage final int dup(int fd, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.dup(nativePosixSupport, fd); } @ExportMessage final int dup2(int fd, int fd2, boolean inheritable, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.dup2(nativePosixSupport, fd, fd2, inheritable); } @ExportMessage final boolean getInheritable(int fd, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getInheritable(nativePosixSupport, fd); } @ExportMessage final void setInheritable(int fd, boolean inheritable, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { PosixSupportLibrary.getUncached().setInheritable(emulatedPosixSupport, fd, inheritable); return; } @@ -242,21 +243,21 @@ final void setInheritable(int fd, boolean inheritable, @ExportMessage final int[] pipe(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.pipe(nativePosixSupport); } @ExportMessage final SelectResult select(int[] readfds, int[] writefds, int[] errorfds, Timeval timeout, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.select(nativePosixSupport, readfds, writefds, errorfds, timeout); } @ExportMessage final long lseek(int fd, long offset, int how, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { return PosixSupportLibrary.getUncached().lseek(emulatedPosixSupport, fd, offset, how); } return nativeLib.lseek(nativePosixSupport, fd, offset, how); @@ -265,63 +266,70 @@ final long lseek(int fd, long offset, int how, @ExportMessage final void ftruncate(int fd, long length, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.ftruncate(nativePosixSupport, fd, length); } @ExportMessage final void truncate(Object path, long length, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.truncate(nativePosixSupport, path, length); } @ExportMessage final void fsync(int fd, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.fsync(nativePosixSupport, fd); } @ExportMessage final void flock(int fd, int operation, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.flock(nativePosixSupport, fd, operation); } @ExportMessage final void fcntlLock(int fd, boolean blocking, int lockType, int whence, long start, long length, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.fcntlLock(nativePosixSupport, fd, blocking, lockType, whence, start, length); } @ExportMessage final boolean getBlocking(int fd, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getBlocking(nativePosixSupport, fd); } @ExportMessage final void setBlocking(int fd, boolean blocking, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.setBlocking(nativePosixSupport, fd, blocking); } @ExportMessage final int[] getTerminalSize(int fd, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getTerminalSize(nativePosixSupport, fd); } + @ExportMessage + final long sysconf(int name, + @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { + checkNotInPreInitialization(); + return nativeLib.sysconf(nativePosixSupport, name); + } + @ExportMessage final long[] fstatat(int dirFd, Object pathname, boolean followSymlinks, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { return PosixSupportLibrary.getUncached().fstatat(emulatedPosixSupport, dirFd, pathname, followSymlinks); } return nativeLib.fstatat(nativePosixSupport, dirFd, pathname, followSymlinks); @@ -330,7 +338,7 @@ final long[] fstatat(int dirFd, Object pathname, boolean followSymlinks, @ExportMessage final long[] fstat(int fd, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { return PosixSupportLibrary.getUncached().fstat(emulatedPosixSupport, fd); } return nativeLib.fstat(nativePosixSupport, fd); @@ -339,7 +347,7 @@ final long[] fstat(int fd, @ExportMessage final long[] statvfs(Object path, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { return PosixSupportLibrary.getUncached().statvfs(emulatedPosixSupport, path); } return nativeLib.statvfs(nativePosixSupport, path); @@ -348,7 +356,7 @@ final long[] statvfs(Object path, @ExportMessage final long[] fstatvfs(int fd, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { return PosixSupportLibrary.getUncached().fstatvfs(emulatedPosixSupport, fd); } return nativeLib.fstatvfs(nativePosixSupport, fd); @@ -356,69 +364,69 @@ final long[] fstatvfs(int fd, @ExportMessage final Object[] uname(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.uname(nativePosixSupport); } @ExportMessage final void unlinkat(int dirFd, Object pathname, boolean rmdir, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.unlinkat(nativePosixSupport, dirFd, pathname, rmdir); } @ExportMessage final void linkat(int oldFdDir, Object oldPath, int newFdDir, Object newPath, int flags, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.linkat(nativePosixSupport, oldFdDir, oldPath, newFdDir, newPath, flags); } @ExportMessage final void symlinkat(Object target, int linkpathDirFd, Object linkpath, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.symlinkat(nativePosixSupport, target, linkpathDirFd, linkpath); } @ExportMessage final void mkdirat(int dirFd, Object pathname, int mode, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.mkdirat(nativePosixSupport, dirFd, pathname, mode); } @ExportMessage final Object getcwd(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getcwd(nativePosixSupport); } @ExportMessage final void chdir(Object path, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.chdir(nativePosixSupport, path); } @ExportMessage final void fchdir(int fd, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.fchdir(nativePosixSupport, fd); } @ExportMessage final boolean isatty(int fd, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.isatty(nativePosixSupport, fd); } @ExportMessage final Object opendir(Object path, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { return addDirStream(PosixSupportLibrary.getUncached().opendir(emulatedPosixSupport, path)); } return nativeLib.opendir(nativePosixSupport, path); @@ -427,14 +435,14 @@ final Object opendir(Object path, @ExportMessage final Object fdopendir(int fd, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.fdopendir(nativePosixSupport, fd); } @ExportMessage final void closedir(Object dirStream, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { PosixSupportLibrary.getUncached().closedir(emulatedPosixSupport, removeDirStream(dirStream)); return; } @@ -444,7 +452,7 @@ final void closedir(Object dirStream, @ExportMessage final Object readdir(Object dirStream, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { return PosixSupportLibrary.getUncached().readdir(emulatedPosixSupport, dirStream); } return nativeLib.readdir(nativePosixSupport, dirStream); @@ -453,7 +461,7 @@ final Object readdir(Object dirStream, @ExportMessage final void rewinddir(Object dirStream, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { PosixSupportLibrary.getUncached().rewinddir(emulatedPosixSupport, dirStream); } nativeLib.rewinddir(nativePosixSupport, dirStream); @@ -462,7 +470,7 @@ final void rewinddir(Object dirStream, @ExportMessage final Object dirEntryGetName(Object dirEntry, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { return PosixSupportLibrary.getUncached().dirEntryGetName(emulatedPosixSupport, dirEntry); } return nativeLib.dirEntryGetName(nativePosixSupport, dirEntry); @@ -471,292 +479,292 @@ final Object dirEntryGetName(Object dirEntry, @ExportMessage final Object dirEntryGetPath(Object dirEntry, Object scandirPath, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.dirEntryGetPath(nativePosixSupport, dirEntry, scandirPath); } @ExportMessage final long dirEntryGetInode(Object dirEntry, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.dirEntryGetInode(nativePosixSupport, dirEntry); } @ExportMessage final int dirEntryGetType(Object dirEntry, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.dirEntryGetType(nativePosixSupport, dirEntry); } @ExportMessage final void utimensat(int dirFd, Object pathname, long[] timespec, boolean followSymlinks, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.utimensat(nativePosixSupport, dirFd, pathname, timespec, followSymlinks); } @ExportMessage final void futimens(int fd, long[] timespec, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.futimens(nativePosixSupport, fd, timespec); } @ExportMessage final void futimes(int fd, Timeval[] timeval, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.futimes(nativePosixSupport, fd, timeval); } @ExportMessage final void lutimes(Object filename, Timeval[] timeval, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.lutimes(nativePosixSupport, filename, timeval); } @ExportMessage final void utimes(Object filename, Timeval[] timeval, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.utimes(nativePosixSupport, filename, timeval); } @ExportMessage final void renameat(int oldDirFd, Object oldPath, int newDirFd, Object newPath, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.renameat(nativePosixSupport, oldDirFd, oldPath, newDirFd, newPath); } @ExportMessage final boolean faccessat(int dirFd, Object path, int mode, boolean effectiveIds, boolean followSymlinks, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.faccessat(nativePosixSupport, dirFd, path, mode, effectiveIds, followSymlinks); } @ExportMessage final void fchmodat(int dirFd, Object path, int mode, boolean followSymlinks, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.fchmodat(nativePosixSupport, dirFd, path, mode, followSymlinks); } @ExportMessage final void fchmod(int fd, int mode, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.fchmod(nativePosixSupport, fd, mode); } @ExportMessage final void fchownat(int dirFd, Object path, long owner, long group, boolean followSymlinks, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.fchownat(nativePosixSupport, dirFd, path, owner, group, followSymlinks); } @ExportMessage final void fchown(int fd, long owner, long group, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.fchown(nativePosixSupport, fd, owner, group); } @ExportMessage final Object readlinkat(int dirFd, Object path, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.readlinkat(nativePosixSupport, dirFd, path); } @ExportMessage final void kill(long pid, int signal, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.kill(nativePosixSupport, pid, signal); } @ExportMessage final void killpg(long pgid, int signal, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.killpg(nativePosixSupport, pgid, signal); } @ExportMessage final long[] waitpid(long pid, int options, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.waitpid(nativePosixSupport, pid, options); } @ExportMessage final void abort(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.abort(nativePosixSupport); } @ExportMessage final boolean wcoredump(int status, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.wcoredump(nativePosixSupport, status); } @ExportMessage final boolean wifcontinued(int status, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.wifcontinued(nativePosixSupport, status); } @ExportMessage final boolean wifstopped(int status, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.wifstopped(nativePosixSupport, status); } @ExportMessage final boolean wifsignaled(int status, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.wifsignaled(nativePosixSupport, status); } @ExportMessage final boolean wifexited(int status, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.wifexited(nativePosixSupport, status); } @ExportMessage final int wexitstatus(int status, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.wexitstatus(nativePosixSupport, status); } @ExportMessage final int wtermsig(int status, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.wtermsig(nativePosixSupport, status); } @ExportMessage final int wstopsig(int status, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.wstopsig(nativePosixSupport, status); } @ExportMessage final long getuid(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getuid(nativePosixSupport); } @ExportMessage final long geteuid(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.geteuid(nativePosixSupport); } @ExportMessage final long getgid(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getgid(nativePosixSupport); } @ExportMessage final long getegid(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getegid(nativePosixSupport); } @ExportMessage final long getppid(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getppid(nativePosixSupport); } @ExportMessage final long getpgid(long pid, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getpgid(nativePosixSupport, pid); } @ExportMessage final void setpgid(long pid, long pgid, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.setpgid(nativePosixSupport, pid, pgid); } @ExportMessage final long getpgrp(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getpgrp(nativePosixSupport); } @ExportMessage final long getsid(long pid, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getsid(nativePosixSupport, pid); } @ExportMessage final long setsid( @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.setsid(nativePosixSupport); } @ExportMessage final long[] getgroups( @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getgroups(nativePosixSupport); } @ExportMessage final RusageResult getrusage(int who, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getrusage(nativePosixSupport, who); } @ExportMessage final OpenPtyResult openpty(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.openpty(nativePosixSupport); } @ExportMessage final TruffleString ctermid(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.ctermid(nativePosixSupport); } @ExportMessage final void setenv(Object name, Object value, boolean overwrite, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.setenv(nativePosixSupport, name, value, overwrite); } @ExportMessage final void unsetenv(Object name, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.unsetenv(nativePosixSupport, name); } @@ -764,7 +772,7 @@ final void unsetenv(Object name, final int forkExec(Object[] executables, Object[] args, Object cwd, Object[] env, int stdinReadFd, int stdinWriteFd, int stdoutReadFd, int stdoutWriteFd, int stderrReadFd, int stderrWriteFd, int errPipeReadFd, int errPipeWriteFd, boolean closeFds, boolean restoreSignals, boolean callSetsid, int[] fdsToKeep, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.forkExec(nativePosixSupport, executables, args, cwd, env, stdinReadFd, stdinWriteFd, stdoutReadFd, stdoutWriteFd, stderrReadFd, stderrWriteFd, errPipeReadFd, errPipeWriteFd, closeFds, restoreSignals, callSetsid, fdsToKeep); } @@ -772,63 +780,63 @@ final int forkExec(Object[] executables, Object[] args, Object cwd, Object[] env @ExportMessage final void execv(Object pathname, Object[] args, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.execv(nativePosixSupport, pathname, args); } @ExportMessage final int system(Object command, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.system(nativePosixSupport, command); } @ExportMessage final Object mmap(long length, int prot, int flags, int fd, long offset, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.mmap(nativePosixSupport, length, prot, flags, fd, offset); } @ExportMessage final byte mmapReadByte(Object mmap, long index, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.mmapReadByte(nativePosixSupport, mmap, index); } @ExportMessage final void mmapWriteByte(Object mmap, long index, byte value, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.mmapWriteByte(nativePosixSupport, mmap, index, value); } @ExportMessage final int mmapReadBytes(Object mmap, long index, byte[] bytes, int length, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.mmapReadBytes(nativePosixSupport, mmap, index, bytes, length); } @ExportMessage final void mmapWriteBytes(Object mmap, long index, byte[] bytes, int length, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.mmapWriteBytes(nativePosixSupport, mmap, index, bytes, length); } @ExportMessage final void mmapFlush(Object mmap, long offset, long length, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.mmapFlush(nativePosixSupport, mmap, offset, length); } @ExportMessage final void mmapUnmap(Object mmap, long length, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.mmapUnmap(nativePosixSupport, mmap, length); } @@ -836,21 +844,21 @@ final void mmapUnmap(Object mmap, long length, @SuppressWarnings("static-method") final long mmapGetPointer(Object mmap, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.mmapGetPointer(nativePosixSupport, mmap); } @ExportMessage public PwdResult getpwuid(long uid, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getpwuid(nativePosixSupport, uid); } @ExportMessage public PwdResult getpwnam(Object name, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getpwnam(nativePosixSupport, name); } @@ -861,265 +869,265 @@ public boolean hasGetpwentries(@CachedLibrary("this.nativePosixSupport") PosixSu @ExportMessage public PwdResult[] getpwentries(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getpwentries(nativePosixSupport); } @ExportMessage final int ioctlBytes(int fd, long request, byte[] arg, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.ioctlBytes(nativePosixSupport, fd, request, arg); } @ExportMessage final int ioctlInt(int fd, long request, int arg, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.ioctlInt(nativePosixSupport, fd, request, arg); } @ExportMessage final int socket(int domain, int type, int protocol, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.socket(nativePosixSupport, domain, type, protocol); } @ExportMessage final AcceptResult accept(int sockfd, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.accept(nativePosixSupport, sockfd); } @ExportMessage final void bind(int sockfd, UniversalSockAddr addr, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.bind(nativePosixSupport, sockfd, addr); } @ExportMessage final void connect(int sockfd, UniversalSockAddr addr, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.connect(nativePosixSupport, sockfd, addr); } @ExportMessage final void listen(int sockfd, int backlog, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.listen(nativePosixSupport, sockfd, backlog); } @ExportMessage final UniversalSockAddr getpeername(int sockfd, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getpeername(nativePosixSupport, sockfd); } @ExportMessage final UniversalSockAddr getsockname(int sockfd, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getsockname(nativePosixSupport, sockfd); } @ExportMessage final int send(int sockfd, byte[] buf, int offset, int len, int flags, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.send(nativePosixSupport, sockfd, buf, offset, len, flags); } @ExportMessage final int sendto(int sockfd, byte[] buf, int offset, int len, int flags, UniversalSockAddr destAddr, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.sendto(nativePosixSupport, sockfd, buf, offset, len, flags, destAddr); } @ExportMessage final int recv(int sockfd, byte[] buf, int offset, int len, int flags, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.recv(nativePosixSupport, sockfd, buf, offset, len, flags); } @ExportMessage final RecvfromResult recvfrom(int sockfd, byte[] buf, int offset, int len, int flags, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.recvfrom(nativePosixSupport, sockfd, buf, offset, len, flags); } @ExportMessage final void shutdown(int sockfd, int how, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.shutdown(nativePosixSupport, sockfd, how); } @ExportMessage final int getsockopt(int sockfd, int level, int optname, byte[] optval, int optlen, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getsockopt(nativePosixSupport, sockfd, level, optname, optval, optlen); } @ExportMessage final void setsockopt(int sockfd, int level, int optname, byte[] optval, int optlen, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); nativeLib.setsockopt(nativePosixSupport, sockfd, level, optname, optval, optlen); } @ExportMessage final int inet_addr(Object src, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.inet_addr(nativePosixSupport, src); } @ExportMessage final int inet_aton(Object src, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws InvalidAddressException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.inet_aton(nativePosixSupport, src); } @ExportMessage final Object inet_ntoa(int address, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.inet_ntoa(nativePosixSupport, address); } @ExportMessage final byte[] inet_pton(int family, Object src, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException, InvalidAddressException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.inet_pton(nativePosixSupport, family, src); } @ExportMessage final Object inet_ntop(int family, byte[] src, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.inet_ntop(nativePosixSupport, family, src); } @ExportMessage final Object gethostname(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.gethostname(nativePosixSupport); } @ExportMessage final Object[] getnameinfo(UniversalSockAddr addr, int flags, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws GetAddrInfoException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getnameinfo(nativePosixSupport, addr, flags); } @ExportMessage final AddrInfoCursor getaddrinfo(Object node, Object service, int family, int sockType, int protocol, int flags, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws GetAddrInfoException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.getaddrinfo(nativePosixSupport, node, service, family, sockType, protocol, flags); } @ExportMessage final TruffleString crypt(TruffleString word, TruffleString salt, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.crypt(nativePosixSupport, word, salt); } @ExportMessage final long semOpen(Object name, int openFlags, int mode, int value, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary lib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return lib.semOpen(nativePosixSupport, name, openFlags, mode, value); } @ExportMessage final void semClose(long handle, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary lib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); lib.semClose(nativePosixSupport, handle); } @ExportMessage final void semUnlink(Object name, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary lib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); lib.semUnlink(nativePosixSupport, name); } @ExportMessage final int semGetValue(long handle, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary lib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return lib.semGetValue(nativePosixSupport, handle); } @ExportMessage final void semPost(long handle, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary lib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); lib.semPost(nativePosixSupport, handle); } @ExportMessage final void semWait(long handle, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary lib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); lib.semWait(nativePosixSupport, handle); } @ExportMessage final boolean semTryWait(long handle, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary lib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return lib.semTryWait(nativePosixSupport, handle); } @ExportMessage final boolean semTimedWait(long handle, long deadlineNs, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary lib) throws PosixException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return lib.semTimedWait(nativePosixSupport, handle, deadlineNs); } @ExportMessage final UniversalSockAddr createUniversalSockAddrInet4(Inet4SockAddr src, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.createUniversalSockAddrInet4(nativePosixSupport, src); } @ExportMessage final UniversalSockAddr createUniversalSockAddrInet6(Inet6SockAddr src, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.createUniversalSockAddrInet6(nativePosixSupport, src); } @ExportMessage final UniversalSockAddr createUniversalSockAddrUnix(UnixSockAddr src, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws InvalidUnixSocketPathException { - checkNotInImageBuildtime(); + checkNotInPreInitialization(); return nativeLib.createUniversalSockAddrUnix(nativePosixSupport, src); } @ExportMessage final Object createPathFromString(TruffleString path, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { return PosixSupportLibrary.getUncached().createPathFromString(emulatedPosixSupport, path); } return nativeLib.createPathFromString(nativePosixSupport, path); @@ -1128,7 +1136,7 @@ final Object createPathFromString(TruffleString path, @ExportMessage final Object createPathFromBytes(byte[] path, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { return PosixSupportLibrary.getUncached().createPathFromBytes(emulatedPosixSupport, path); } return nativeLib.createPathFromBytes(nativePosixSupport, path); @@ -1137,7 +1145,7 @@ final Object createPathFromBytes(byte[] path, @ExportMessage final TruffleString getPathAsString(Object path, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { return PosixSupportLibrary.getUncached().getPathAsString(emulatedPosixSupport, path); } return nativeLib.getPathAsString(nativePosixSupport, path); @@ -1146,7 +1154,7 @@ final TruffleString getPathAsString(Object path, @ExportMessage final Buffer getPathAsBytes(Object path, @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) { - if (ImageInfo.inImageBuildtimeCode()) { + if (inPreInitialization) { return PosixSupportLibrary.getUncached().getPathAsBytes(emulatedPosixSupport, path); } return nativeLib.getPathAsBytes(nativePosixSupport, path); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java index 2a27d077bf..79a6c80206 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java @@ -48,8 +48,6 @@ import static com.oracle.graal.python.nodes.StringLiterals.J_EXT_DYLIB; import static com.oracle.graal.python.nodes.StringLiterals.J_EXT_SO; import static com.oracle.graal.python.nodes.StringLiterals.J_LIB_PREFIX; -import static com.oracle.graal.python.nodes.StringLiterals.J_LLVM_LANGUAGE; -import static com.oracle.graal.python.nodes.StringLiterals.J_NATIVE; import static com.oracle.graal.python.nodes.StringLiterals.J_NFI_LANGUAGE; import static com.oracle.graal.python.nodes.StringLiterals.T_DASH; import static com.oracle.graal.python.nodes.StringLiterals.T_DOT; @@ -57,7 +55,6 @@ import static com.oracle.graal.python.nodes.StringLiterals.T_EXT_PYD; import static com.oracle.graal.python.nodes.StringLiterals.T_EXT_SO; import static com.oracle.graal.python.nodes.StringLiterals.T_JAVA; -import static com.oracle.graal.python.nodes.StringLiterals.T_LLVM_LANGUAGE; import static com.oracle.graal.python.nodes.StringLiterals.T_NATIVE; import static com.oracle.graal.python.nodes.StringLiterals.T_PATH; import static com.oracle.graal.python.nodes.StringLiterals.T_SITE; @@ -100,7 +97,6 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; -import org.graalvm.nativeimage.ImageInfo; import org.graalvm.options.OptionKey; import com.oracle.graal.python.PythonLanguage; @@ -116,9 +112,7 @@ import com.oracle.graal.python.builtins.objects.cext.capi.PyTruffleObjectFree; import com.oracle.graal.python.builtins.objects.cext.capi.PythonNativeWrapper.PythonAbstractObjectNativeWrapper; import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandleContext; -import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ApiInitException; import com.oracle.graal.python.builtins.objects.cext.common.NativePointer; -import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContext; import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; import com.oracle.graal.python.builtins.objects.common.HashingStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem; @@ -157,20 +151,22 @@ import com.oracle.graal.python.nodes.SpecialMethodNames; import com.oracle.graal.python.nodes.WriteUnraisableNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.object.SetDictNode; import com.oracle.graal.python.nodes.statement.AbstractImportNode; +import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaIntLossyNode; +import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.AsyncHandler.AsyncAction; import com.oracle.graal.python.runtime.PythonContextFactory.GetThreadStateNodeGen; import com.oracle.graal.python.runtime.arrow.ArrowSupport; -import com.oracle.graal.python.runtime.arrow.ArrowVectorSupport; import com.oracle.graal.python.runtime.exception.ExceptionUtils; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonThreadKillException; import com.oracle.graal.python.runtime.locale.PythonLocale; import com.oracle.graal.python.runtime.object.IDUtils; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.Consumer; import com.oracle.graal.python.util.PythonSystemThreadTask; import com.oracle.graal.python.util.PythonUtils; @@ -186,6 +182,7 @@ import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.ThreadLocalAction; +import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.TruffleContext; import com.oracle.truffle.api.TruffleContext.Builder; import com.oracle.truffle.api.TruffleFile; @@ -193,6 +190,7 @@ import com.oracle.truffle.api.TruffleLanguage.ContextReference; import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.TruffleLogger; +import com.oracle.truffle.api.TruffleOptions; import com.oracle.truffle.api.TruffleSafepoint; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.GenerateInline; @@ -222,7 +220,6 @@ public final class PythonContext extends Python3Core { public final HandleContext nativeContext = new HandleContext(DEBUG_CAPI); public final NativeBufferContext nativeBufferContext = new NativeBufferContext(); - public final ArrowVectorSupport arrowVectorSupport = new ArrowVectorSupport(this); public final ArrowSupport arrowSupport = new ArrowSupport(this); private volatile boolean finalizing; @@ -242,8 +239,6 @@ public static String getSupportLibName(String libName) { return getSupportLibName(getPythonOS(), libName); } - public static final String J_PYTHON_JNI_LIBRARY_NAME = System.getProperty("python.jni.library", getSupportLibName("pythonjni")); - /** * An enum of events which can currently be traced using python's tracing */ @@ -386,6 +381,13 @@ public static final class PythonThreadState { */ Object asyncgenFirstIter; + /* + * Instrumentation data (Bytecode DSL interpreter only). For the manual bytecode + * interpreter, this data is stored in a local state variable, but the DSL interpreter must + * use a thread local. + */ + PBytecodeDSLRootNode.InstrumentationData instrumentationData; + /* * Counter for C-level recursion depth used for Py_(Enter/Leave)RecursiveCall. */ @@ -525,7 +527,7 @@ public void setNativeWrapper(PThreadState nativeWrapper) { public PContextVarsContext getContextVarsContext() { if (contextVarsContext == null) { - contextVarsContext = PythonObjectFactory.getUncached().createContextVarsContext(); + contextVarsContext = PFactory.createContextVarsContext(PythonLanguage.get(null)); } return contextVarsContext; } @@ -566,13 +568,48 @@ public void dispose(PythonContext context, boolean canRunGuestCode) { } } + private static void invalidateNoTracingOrProfilingAssumption(PythonLanguage language) { + if (language.noTracingOrProfilingAssumption.isValid()) { + language.noTracingOrProfilingAssumption.invalidate(); + + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + enableTracingOrProfilingForActiveRootNodes(); + } + } + } + + @TruffleBoundary + private static void enableTracingOrProfilingForActiveRootNodes() { + final List rootNodes = new ArrayList<>(); + + // Ensure tracing + profiling are enabled for each method on the stack. + Truffle.getRuntime().iterateFrames((frameInstance) -> { + if (frameInstance.getCallTarget() instanceof RootCallTarget c && c.getRootNode() instanceof PBytecodeDSLRootNode r) { + if (r.needsTraceAndProfileInstrumentation()) { + r.ensureTraceAndProfileEnabled(); + } + rootNodes.add(r); + } + return null; + }); + + /** + * Normally, a root node will push + pop the instrumentation data in its prolog/epilog. + * Since these nodes are on stack, we need to push them manually, starting from the + * deepest stack frame. + */ + for (PBytecodeDSLRootNode rootNode : rootNodes.reversed()) { + rootNode.getThreadState().pushInstrumentationData(rootNode); + } + } + public Object getTraceFun() { return traceFun; } public void setTraceFun(Object traceFun, PythonLanguage language) { if (this.traceFun != traceFun) { - language.noTracingOrProfilingAssumption.invalidate(); + invalidateNoTracingOrProfilingAssumption(language); this.traceFun = traceFun; } } @@ -601,7 +638,7 @@ public void setTracingWhat(TraceEvent tracingWhat) { public void setProfileFun(Object profileFun, PythonLanguage language) { if (this.profileFun != profileFun) { - language.noTracingOrProfilingAssumption.invalidate(); + invalidateNoTracingOrProfilingAssumption(language); this.profileFun = profileFun; } } @@ -623,6 +660,24 @@ public void profilingStop() { this.profiling = false; } + public PBytecodeDSLRootNode.InstrumentationData getInstrumentationData(PBytecodeDSLRootNode rootNode) { + assert PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER; + assert instrumentationData != null && instrumentationData.getRootNode() == rootNode; + return instrumentationData; + } + + public void pushInstrumentationData(PBytecodeDSLRootNode rootNode) { + assert PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER; + instrumentationData = new PBytecodeDSLRootNode.InstrumentationData(rootNode, instrumentationData); + } + + public void popInstrumentationData(PBytecodeDSLRootNode rootNode) { + assert PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER; + assert instrumentationData != null; + assert instrumentationData.getRootNode() == rootNode : instrumentationData.getRootNode(); + instrumentationData = instrumentationData.getPrevious(); + } + public Object getAsyncgenFirstIter() { return asyncgenFirstIter; } @@ -732,7 +787,6 @@ PythonThreadState getThreadState(Node n) { private static final String J_NO_CORE_WARNING = "could not determine Graal.Python's core path - you may need to pass --python.CoreHome."; private static final String J_NO_STDLIB = "could not determine Graal.Python's standard library path. You need to pass --python.StdLibHome if you want to use the standard library."; private static final String J_NO_CAPI = "could not determine Graal.Python's C API library path. You need to pass --python.CAPI if you want to use the C extension modules."; - private static final String J_NO_JNI = "could not determine Graal.Python's JNI library. You need to pass --python.JNILibrary if you want to run, for example, binary HPy extension modules."; private PythonModule mainModule; private final List shutdownHooks = new ArrayList<>(); @@ -774,7 +828,6 @@ PythonThreadState getThreadState(Node n) { private OutputStream err; private InputStream in; @CompilationFinal private CApiContext cApiContext; - @CompilationFinal private GraalHPyContext hPyContext; @CompilationFinal private boolean nativeAccessAllowed; private TruffleString soABI; // cache for soAPI @@ -843,7 +896,7 @@ public Thread getOwner() { private final ConcurrentHashMap deserializationId = new ConcurrentHashMap<>(); - private final long perfCounterStart = ImageInfo.inImageBuildtimeCode() ? 0 : System.nanoTime(); + @CompilationFinal private long perfCounterStart = System.nanoTime(); public static final String CHILD_CONTEXT_DATA = "childContextData"; @CompilationFinal private List childContextFDs; @@ -1250,7 +1303,7 @@ public void putChildContextData(long id, ChildContextData data) { } public PythonContext(PythonLanguage language, TruffleLanguage.Env env) { - super(language, env.isNativeAccessAllowed(), env.isSocketIOAllowed()); + super(language, env); this.env = env; this.allocationReporter = env.lookup(AllocationReporter.class); this.childContextData = (ChildContextData) env.getConfig().get(CHILD_CONTEXT_DATA); @@ -1296,7 +1349,7 @@ public long spawnTruffleContext(int fd, int sentinel, int[] fdsToKeep) { forceSharing(getOption(PythonOptions.ForceSharingForInnerContexts)).// inheritAllAccess(true).// initializeCreatorContext(true).// - option("python.NativeModules", "false").// + option("python.IsolateNativeModules", "true").// // TODO always force java posix in spawned: test_multiprocessing_spawn fails // with that. Gives "OSError: [Errno 9] Bad file number" // option("python.PosixModuleBackend", "java").// @@ -1510,7 +1563,7 @@ public long getPerfCounterStart() { * Get a SecureRandom instance using a non-blocking source. */ public SecureRandom getSecureRandom() { - assert !ImageInfo.inImageBuildtimeCode(); + assert !env.isPreInitialization(); if (secureRandom == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); try { @@ -1531,7 +1584,7 @@ public SecureRandom getSecureRandom() { } public byte[] getHashSecret() { - assert !ImageInfo.inImageBuildtimeCode(); + assert !env.isPreInitialization(); return hashSecret; } @@ -1562,18 +1615,23 @@ public void initialize() { initializePosixSupport(); initialize(this); setupRuntimeInformation(false); - postInitialize(); - if (!ImageInfo.inImageBuildtimeCode()) { + postInitialize(env); + if (!env.isPreInitialization()) { importSiteIfForced(); - } else if (posixSupport instanceof ImageBuildtimePosixSupport) { - ((ImageBuildtimePosixSupport) posixSupport).checkLeakingResources(); + } else if (posixSupport instanceof PreInitPosixSupport) { + ((PreInitPosixSupport) posixSupport).checkLeakingResources(); } } finally { - if (ImageInfo.inImageBuildtimeCode()) { + if (env.isPreInitialization()) { mainThread = null; } releaseGil(); } + PythonOptions.checkBytecodeDSLEnv(); + } + + public void resetPerfCounter() { + perfCounterStart = System.nanoTime(); } public void patch(Env newEnv) { @@ -1586,11 +1644,12 @@ public void patch(Env newEnv) { mainThread = new WeakReference<>(Thread.currentThread()); setEnv(newEnv); setupRuntimeInformation(true); - postInitialize(); + postInitialize(newEnv); importSiteIfForced(); } finally { releaseGil(); } + PythonOptions.checkBytecodeDSLEnv(); } private void importSiteIfForced() { @@ -1672,21 +1731,16 @@ private void patchPackagePaths(TruffleString from, TruffleString to) { Object[] paths = SequenceStorageNodes.CopyInternalArrayNode.executeUncached(((PList) path).getSequenceStorage()); for (int i = 0; i < paths.length; i++) { Object pathElement = paths[i]; - TruffleString strPath; - if (pathElement instanceof PString) { - strPath = ((PString) pathElement).getValueUncached(); - } else if (isJavaString(pathElement)) { - strPath = toTruffleStringUncached((String) pathElement); - } else if (pathElement instanceof TruffleString) { - strPath = (TruffleString) pathElement; - } else { - continue; - } - if (strPath.regionEqualsUncached(0, from, 0, from.codePointLengthUncached(TS_ENCODING), TS_ENCODING)) { - paths[i] = StringReplaceNode.getUncached().execute(strPath, from, to, -1); + try { + TruffleString strPath = CastToTruffleStringNode.executeUncached(pathElement); + if (strPath.regionEqualsUncached(0, from, 0, from.codePointLengthUncached(TS_ENCODING), TS_ENCODING)) { + paths[i] = StringReplaceNode.getUncached().execute(strPath, from, to, -1); + } + } catch (CannotCastException e) { + // ignore } } - ((PythonModule) v).setAttribute(SpecialAttributeNames.T___PATH__, factory().createList(paths)); + ((PythonModule) v).setAttribute(SpecialAttributeNames.T___PATH__, PFactory.createList(PythonLanguage.get(null), paths)); } // Update module.__file__ @@ -1711,7 +1765,7 @@ private void initializeLocale() { } private void setupRuntimeInformation(boolean isPatching) { - if (!ImageInfo.inImageBuildtimeCode()) { + if (!env.isPreInitialization()) { initializeHashSecret(); } initializeLocale(); @@ -1722,17 +1776,17 @@ private void setupRuntimeInformation(boolean isPatching) { nativeLZMA = NFILZMASupport.createNative(this, ""); } - mainModule = factory().createPythonModule(T___MAIN__); + mainModule = PFactory.createPythonModule(getLanguage(), T___MAIN__); mainModule.setAttribute(T___BUILTINS__, getBuiltins()); - mainModule.setAttribute(T___ANNOTATIONS__, factory().createDict()); - SetDictNode.executeUncached(mainModule, factory().createDictFixedStorage(mainModule)); + mainModule.setAttribute(T___ANNOTATIONS__, PFactory.createDict(getLanguage())); + SetDictNode.executeUncached(mainModule, PFactory.createDictFixedStorage(getLanguage(), mainModule)); getSysModules().setItem(T___MAIN__, mainModule); - if (ImageInfo.inImageBuildtimeCode()) { + if (env.isPreInitialization()) { // Patch any pre-loaded packages' paths if we're running // pre-initialization patchPackagePaths(getStdlibHome(), T_STD_LIB_PLACEHOLDER); - } else if (isPatching && ImageInfo.inImageRuntimeCode()) { + } else if (isPatching) { // Patch any pre-loaded packages' paths to the new stdlib home if // we're patching a pre-initialized context patchPackagePaths(T_STD_LIB_PLACEHOLDER, getStdlibHome()); @@ -1743,7 +1797,7 @@ private void setupRuntimeInformation(boolean isPatching) { } private void initializeHashSecret() { - assert !ImageInfo.inImageBuildtimeCode(); + assert !env.isPreInitialization(); Optional hashSeed = getOption(PythonOptions.HashSeed); if (hashSeed.isPresent()) { int hashSeedValue = hashSeed.get(); @@ -1787,14 +1841,18 @@ private void initializePosixSupport() { "switching to Java backend."); } result = new EmulatedPosixSupport(this); - } else if (eqNode.execute(T_NATIVE, option, TS_ENCODING) || eqNode.execute(T_LLVM_LANGUAGE, option, TS_ENCODING)) { - if (ImageInfo.inImageBuildtimeCode()) { + } else if (eqNode.execute(T_NATIVE, option, TS_ENCODING)) { + if (env.isPreInitialization()) { EmulatedPosixSupport emulatedPosixSupport = new EmulatedPosixSupport(this); NFIPosixSupport nativePosixSupport = new NFIPosixSupport(this, option); - result = new ImageBuildtimePosixSupport(nativePosixSupport, emulatedPosixSupport); - } else if (ImageInfo.inImageRuntimeCode()) { + result = new PreInitPosixSupport(env, nativePosixSupport, emulatedPosixSupport); + } else if (TruffleOptions.AOT) { + // We always use a PreInitPosixSupport on SVM to keep the type of the posixSupport + // field consistent for both pre-initialized and not-pre-initialized contexts so + // that host inlining and PE see only one type, and also to avoid polymorphism when + // calling library methods. NFIPosixSupport nativePosixSupport = new NFIPosixSupport(this, option); - result = new ImageBuildtimePosixSupport(nativePosixSupport, null); + result = new PreInitPosixSupport(env, nativePosixSupport, null); } else { if (!getOption(PythonOptions.RunViaLauncher)) { writeWarning("Native Posix backend is not fully supported when embedding. For example, standard I/O always uses file " + @@ -1812,12 +1870,12 @@ private void initializePosixSupport() { } } - private TruffleString langHome, sysPrefix, basePrefix, coreHome, capiHome, jniHome, stdLibHome; + private TruffleString langHome, sysPrefix, basePrefix, coreHome, capiHome, stdLibHome; public void initializeHomeAndPrefixPaths(Env newEnv, String languageHome) { - if (ImageInfo.inImageBuildtimeCode()) { + if (env.isPreInitialization()) { // at buildtime we do not need these paths to be valid, since all boot files are frozen - basePrefix = sysPrefix = langHome = coreHome = stdLibHome = capiHome = jniHome = T_DOT; + basePrefix = sysPrefix = langHome = coreHome = stdLibHome = capiHome = T_DOT; return; } @@ -1863,7 +1921,6 @@ public void initializeHomeAndPrefixPaths(Env newEnv, String languageHome) { coreHome = newEnv.getOptions().get(PythonOptions.CoreHome); stdLibHome = newEnv.getOptions().get(PythonOptions.StdLibHome); capiHome = newEnv.getOptions().get(PythonOptions.CAPI); - jniHome = newEnv.getOptions().get(PythonOptions.JNIHome); final TruffleFile homeCandidate = (TruffleFile) homeCandidateSupplier.get(); if (homeCandidate == null) { continue; @@ -1877,8 +1934,7 @@ public void initializeHomeAndPrefixPaths(Env newEnv, String languageHome) { "\n\tCoreHome: {3}" + "\n\tStdLibHome: {4}" + "\n\tCAPI: {5}" + - "\n\tJNI library: {6}" + - "\n\tHome candidate: {7}", languageHome, sysPrefix, basePrefix, coreHome, stdLibHome, capiHome, jniHome, homeCandidate.toString())); + "\n\tHome candidate: {6}", languageHome, sysPrefix, basePrefix, coreHome, stdLibHome, capiHome, homeCandidate.toString())); langHome = toTruffleStringUncached(homeCandidate.toString()); TruffleString prefix = toTruffleStringUncached(homeCandidate.getAbsoluteFile().getPath()); @@ -1946,10 +2002,6 @@ public void initializeHomeAndPrefixPaths(Env newEnv, String languageHome) { capiHome = coreHome; } - if (jniHome.isEmpty()) { - jniHome = coreHome; - } - if (homeSeemsValid) { break; } @@ -1962,9 +2014,7 @@ public void initializeHomeAndPrefixPaths(Env newEnv, String languageHome) { "\n\tCoreHome: {3}" + "\n\tStdLibHome: {4}" + "\n\tExecutable: {5}" + - "\n\tCAPI: {6}" + - "\n\tJNI library: {7}", langHome, sysPrefix, basePrefix, coreHome, stdLibHome, newEnv.getOptions().get(PythonOptions.Executable), capiHome, - jniHome)); + "\n\tCAPI: {6}", langHome, sysPrefix, basePrefix, coreHome, stdLibHome, newEnv.getOptions().get(PythonOptions.Executable), capiHome)); } @TruffleBoundary @@ -2027,15 +2077,6 @@ public TruffleString getCAPIHome() { return capiHome; } - @TruffleBoundary - public TruffleString getJNIHome() { - if (jniHome.isEmpty()) { - writeWarning(J_NO_JNI); - return jniHome; - } - return jniHome; - } - private static void writeWarning(String warning) { LOGGER.warning(warning); } @@ -2093,7 +2134,6 @@ public void finalizeContext() { } // interrupt and join or kill system threads joinSystemThreads(); - cleanupHPyResources(); for (int fd : getChildContextFDs()) { if (!getSharedMultiprocessingData().decrementFDRefCount(fd)) { getSharedMultiprocessingData().closePipe(fd); @@ -2160,7 +2200,8 @@ public void runShutdownHooks() { } catch (PException e) { // It was printed already, so just discard } - for (ShutdownHook h : shutdownHooks) { + for (int i = shutdownHooks.size() - 1; i >= 0; i--) { + ShutdownHook h = shutdownHooks.get(i); h.call(this); } } @@ -2177,12 +2218,6 @@ private void disposeThreadStates() { threadStateMapping.clear(); } - private void cleanupHPyResources() { - if (hPyContext != null) { - hPyContext.finalizeContext(); - } - } - /** * This method is the equivalent to {@code pylifecycle.c: wait_for_thread_shutdown} and calls * {@code threading._shutdown} (if the threading module was loaded) to tear down all threads @@ -2515,8 +2550,8 @@ public TruffleFile getPublicTruffleFileRelaxed(TruffleString path, TruffleString TruffleFile f = env.getInternalTruffleFile(path.toJavaStringUncached()); // 'isDirectory' does deliberately not follow symlinks because otherwise this could allow to // escape the language home directory. - // Also, during image build time, we allow full internal access. - if (ImageInfo.inImageBuildtimeCode() || isPyFileInLanguageHome(f) && (f.isDirectory(LinkOption.NOFOLLOW_LINKS) || hasAllowedSuffix(path, allowedSuffixes))) { + // Also, during pre-initialization, we allow full internal access. + if (env.isPreInitialization() || isPyFileInLanguageHome(f) && (f.isDirectory(LinkOption.NOFOLLOW_LINKS) || hasAllowedSuffix(path, allowedSuffixes))) { return f; } else { return env.getPublicTruffleFile(path.toJavaStringUncached()); @@ -2543,7 +2578,7 @@ private static boolean hasAllowedSuffix(TruffleString path, TruffleString[] allo */ @TruffleBoundary public boolean isPyFileInLanguageHome(TruffleFile path) { - assert !ImageInfo.inImageBuildtimeCode() : "language home won't be available during image build time"; + assert !env.isPreInitialization() : "language home won't be available during pre-initialization"; // The language home may be 'null' if an embedder uses Python. In this case, IO must just be // allowed. if (langHome != null) { @@ -2678,34 +2713,6 @@ public void runCApiHooks() { capiHooks.clear(); } - public boolean hasHPyContext() { - return hPyContext != null; - } - - public synchronized GraalHPyContext createHPyContext(Object hpyLibrary) throws ApiInitException { - assert hPyContext == null : "tried to create new HPy context but it was already created"; - GraalHPyContext hpyContext = new GraalHPyContext(this, hpyLibrary); - this.hPyContext = hpyContext; - return hpyContext; - } - - public GraalHPyContext getHPyContext() { - assert hPyContext != null : "tried to get HPy context but was not created yet"; - return hPyContext; - } - - /** - * Equivalent of {@code debug_ctx.c: hpy_debug_init_ctx}. - */ - @TruffleBoundary - private Object initDebugMode() { - if (!hasHPyContext()) { - throw CompilerDirectives.shouldNotReachHere("cannot initialize HPy debug context without HPy universal context"); - } - // TODO: call 'hpy_debug_init_ctx' - throw CompilerDirectives.shouldNotReachHere("not yet implemented"); - } - public GCState getGcState() { return gcState; } @@ -2738,24 +2745,10 @@ public long getDeserializationId(TruffleString fileName) { return deserializationId.computeIfAbsent(fileName, f -> new AtomicLong()).incrementAndGet(); } - public void ensureLLVMLanguage(Node nodeForRaise) { - if (!env.getInternalLanguages().containsKey(J_LLVM_LANGUAGE)) { - throw PRaiseNode.raiseUncached(nodeForRaise, PythonBuiltinClassType.SystemError, ErrorMessages.LLVM_NOT_AVAILABLE); - } - } - public void ensureNFILanguage(Node nodeForRaise, String optionName, String optionValue) { if (!env.getInternalLanguages().containsKey(J_NFI_LANGUAGE)) { - throw PRaiseNode.raiseUncached(nodeForRaise, PythonBuiltinClassType.SystemError, ErrorMessages.NFI_NOT_AVAILABLE, optionName, optionValue); - } - } - - @TruffleBoundary - public String getLLVMSupportExt(String libName) { - if (!getOption(PythonOptions.NativeModules)) { - ensureLLVMLanguage(null); + throw PRaiseNode.raiseStatic(nodeForRaise, PythonBuiltinClassType.SystemError, ErrorMessages.NFI_NOT_AVAILABLE, optionName, optionValue); } - return PythonContext.getSupportLibName(libName + '-' + J_NATIVE); } @TruffleBoundary diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonImageBuildOptions.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonImageBuildOptions.java index 31c1bb4324..5ddd8d29e0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonImageBuildOptions.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonImageBuildOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -76,10 +76,6 @@ public final class PythonImageBuildOptions { * This property can be used to exclude socket and inet support from the Java posix backend. */ public static final boolean WITHOUT_JAVA_INET = Boolean.getBoolean("python.WithoutJavaInet"); - /** - * This property can be used to disable any usage of JNI. - */ - public static final boolean WITHOUT_JNI = Boolean.getBoolean("python.WithoutJNI"); private PythonImageBuildOptions() { } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonOptions.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonOptions.java index aad42772ea..d033d40536 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonOptions.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -38,7 +38,6 @@ import java.lang.annotation.Target; import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -83,26 +82,23 @@ public final class PythonOptions { */ public static final boolean AUTOMATIC_ASYNC_ACTIONS = !"false".equalsIgnoreCase(System.getProperty("python.AutomaticAsyncActions")); - public enum HPyBackendMode { - NFI, - JNI, - LLVM - } - - static final OptionType HPY_BACKEND_TYPE = new OptionType<>("HPyBackend", s -> { - try { - return HPyBackendMode.valueOf(s.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Backend can be one of: " + Arrays.toString(HPyBackendMode.values())); - } - }); - + /** + * Whether to use the experimental Bytecode DSL interpreter instead of the manually-written + * bytecode interpreter. + */ + public static final boolean ENABLE_BYTECODE_DSL_INTERPRETER = Boolean.getBoolean("python.EnableBytecodeDSLInterpreter"); private static final OptionType TS_OPTION_TYPE = new OptionType<>("graal.python.TruffleString", PythonUtils::toTruffleStringUncached); private PythonOptions() { // no instances } + public static void checkBytecodeDSLEnv() { + if (!ENABLE_BYTECODE_DSL_INTERPRETER && "true".equalsIgnoreCase(System.getenv("BYTECODE_DSL_INTERPRETER"))) { + System.err.println("WARNING: found environment variable BYTECODE_DSL_INTERPRETER=true, but the python.EnableBytecodeDSLInterpreter Java property was not set."); + } + } + @Option(category = OptionCategory.EXPERT, help = "Set the home of Python. Equivalent of GRAAL_PYTHONHOME env variable. " + "Determines default values for the CoreHome, StdLibHome, SysBasePrefix, SysPrefix.", usageSyntax = "", stability = OptionStability.STABLE) // public static final OptionKey PythonHome = new OptionKey<>(""); @@ -244,20 +240,6 @@ private PythonOptions() { @EngineOption @Option(category = OptionCategory.INTERNAL, usageSyntax = "true|false", help = "Enable catching all Exceptions in generic try-catch statements.") // public static final OptionKey CatchAllExceptions = new OptionKey<>(false); - @EngineOption @Option(category = OptionCategory.INTERNAL, help = "Choose the backend for HPy binary mode.", usageSyntax = "jni|nfi|llvm", stability = OptionStability.EXPERIMENTAL) // - public static final OptionKey HPyBackend = new OptionKey<>(HPyBackendMode.JNI, HPY_BACKEND_TYPE); - - @EngineOption @Option(category = OptionCategory.INTERNAL, usageSyntax = "true|false", help = "If {@code true}, code is enabled that tries to reduce expensive upcalls into the runtime" + - "when HPy API functions are used. This is achieved by mirroring data in native memory.", stability = OptionStability.EXPERIMENTAL) // - public static final OptionKey HPyEnableJNIFastPaths = new OptionKey<>(true); - - @EngineOption @Option(category = OptionCategory.INTERNAL, usageSyntax = "

        + *
      1. First, we use a hook in the DSL to set the catch location every time an exception is + * thrown from the bytecode loop ({@link #setCatchLocation}).
      2. + *
      3. Then, we mark the exception as "caught" when we reach a handler + * ({@link #markAsCaught(Frame, PBytecodeDSLRootNode)}. Once it's "caught", the catch location + * is frozen.
      4. + *
      + * + * (It is necessary to freeze the location after calling + * {@link #markAsCaught(Frame, PBytecodeDSLRootNode)} because Python-level try-except-finally + * blocks are implemented with multiple DSL-level throws; these throws will trigger subsequent + * {@link #setCatchLocation} calls that would overwrite the location.) + * + * Since the catch location is set unconditionally, it could refer to a location that had no + * handler (i.e., the location is invalid). Code should not use the location unless the other + * frame info (e.g., the {@link #rootNode}) has been set, which indicates that a handler was + * found and that the catch location actually refers to a guarded instruction. + */ + public void setCatchLocation(int catchBci, BytecodeNode bytecodeNode) { + assert PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER; + // Overwrite the catchBci as long as no handler has been found yet. + if (!isCaught()) { + this.catchBci = catchBci; + this.bytecodeNode = bytecodeNode; + } + } + + public void markAsCaught(Frame frame, PBytecodeDSLRootNode catchLocation) { + assert PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER; + if (!isCaught()) { + this.frameInfo = PArguments.getCurrentFrameInfo(frame); + this.rootNode = catchLocation; + } + } + + private boolean isCaught() { + assert PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER; + return rootNode != null; + } + public void markEscaped() { markFrameEscaped(); if (!(pythonException instanceof PBaseException)) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/BytesFormatProcessor.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/BytesFormatProcessor.java index 2e7e18c640..692621f783 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/BytesFormatProcessor.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/BytesFormatProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -49,6 +49,7 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.BufferFlags; @@ -69,6 +70,7 @@ import com.oracle.graal.python.runtime.formatting.FormattingBuffer.BytesFormattingBuffer; import com.oracle.graal.python.runtime.formatting.InternalFormat.Formatter; import com.oracle.graal.python.runtime.formatting.InternalFormat.Spec; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -98,7 +100,7 @@ char pop() { try { return (char) formatBytes[index++]; } catch (ArrayIndexOutOfBoundsException e) { - throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.INCOMPLETE_FORMAT); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.INCOMPLETE_FORMAT); } } @@ -115,7 +117,7 @@ int parseNumber(int start, int end) { @Override Object parseMappingKey(int start, int end) { - return core.factory().createBytes(Arrays.copyOfRange(formatBytes, start, end)); + return PFactory.createBytes(PythonLanguage.get(null), Arrays.copyOfRange(formatBytes, start, end)); } @Override @@ -130,7 +132,7 @@ protected double asFloat(Object arg) { return super.asFloat(arg); } catch (PException ex) { // exactly like in CPython, all errors are translated to this - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.FLOAT_ARG_REQUIRED, arg); + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.FLOAT_ARG_REQUIRED, arg); } } @@ -180,7 +182,7 @@ protected Formatter handleSingleCharacterFormat(Spec spec) { } if (!foundByte) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.C_REQUIRES_INT_IN_BYTE_RANGE_OR_SINGLE_BYTE); + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.C_REQUIRES_INT_IN_BYTE_RANGE_OR_SINGLE_BYTE); } BytesFormatter f = new BytesFormatter(buffer, spec, raisingNode); @@ -189,7 +191,7 @@ protected Formatter handleSingleCharacterFormat(Spec spec) { } private PException raiseOverflow() { - throw PRaiseNode.raiseUncached(raisingNode, OverflowError, ErrorMessages.C_ARG_NOT_IN_RANGE256_DECIMAL); + throw PRaiseNode.raiseStatic(raisingNode, OverflowError, ErrorMessages.C_ARG_NOT_IN_RANGE256_DECIMAL); } @Override @@ -226,14 +228,14 @@ private byte[] asBytes(Object arg) { if (attribute != PNone.NO_VALUE) { Object bytesResult = call(attribute, arg); if (!(bytesResult instanceof PBytes)) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.RETURNED_NONBYTES, T___BYTES__, arg); + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.RETURNED_NONBYTES, T___BYTES__, arg); } return toBytes((PBytes) bytesResult); } // otherwise: use the buffer protocol byte[] result = byteBufferAsBytesOrNull(arg); if (result == null) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.B_REQUIRES_BYTES_OR_OBJ_THAT_IMPLEMENTS_S_NOT_P, T___BYTES__, arg); + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.B_REQUIRES_BYTES_OR_OBJ_THAT_IMPLEMENTS_S_NOT_P, T___BYTES__, arg); } return result; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/ErrorMessageFormatter.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/ErrorMessageFormatter.java index cb82d7fa97..91b874931f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/ErrorMessageFormatter.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/ErrorMessageFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,7 +47,7 @@ import java.util.regex.Pattern; import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.util.PythonUtils; @@ -94,19 +94,22 @@ public static String format(String format, Object... args) { while (m.find(idx)) { String group = m.group(); if ("%p".equals(group)) { - String name = getClassName(args[matchIdx]); + // %p is equivalent of CPython's Py_TYPE(o)->tp_name + String name = getClassTpName(args[matchIdx]); sb.replace(m.start() + offset, m.end() + offset, name); offset += name.length() - (m.end() - m.start()); args[matchIdx] = REMOVED_MARKER; removedCnt++; } else if ("%P".equals(group)) { - String name = ""; + // %p is equivalent of CPython's _PyType_Name(Py_TYPE(o)) + String name = getClassTypeName(args[matchIdx]); sb.replace(m.start() + offset, m.end() + offset, name); offset += name.length() - (m.end() - m.start()); args[matchIdx] = REMOVED_MARKER; removedCnt++; } else if ("%N".equals(group)) { - String name = getClassNameOfClass(args[matchIdx]); + // %N is equivalent of CPython's t->tp_name + String name = getTpName(args[matchIdx]); sb.replace(m.start() + offset, m.end() + offset, name); offset += name.length() - (m.end() - m.start()); args[matchIdx] = REMOVED_MARKER; @@ -143,12 +146,16 @@ private static String getMessage(Throwable exception) { return message; } - private static String getClassName(Object obj) { - return getClassNameOfClass(GetClassNode.executeUncached(obj)); + private static String getClassTpName(Object obj) { + return getTpName(GetClassNode.executeUncached(obj)); } - private static String getClassNameOfClass(Object type) { - return GetNameNode.doSlowPath(type).toJavaStringUncached(); + private static String getClassTypeName(Object obj) { + return TypeNodes.GetNameNode.executeUncached(GetClassNode.executeUncached(obj)).toJavaStringUncached(); + } + + private static String getTpName(Object type) { + return TypeNodes.GetTpNameNode.executeUncached(type).toJavaStringUncached(); } /** diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/FormatProcessor.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/FormatProcessor.java index a0bdb89c56..7d2bb423b9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/FormatProcessor.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/FormatProcessor.java @@ -15,6 +15,7 @@ import java.math.BigInteger; import java.math.MathContext; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.function.PKeyword; @@ -37,6 +38,7 @@ import com.oracle.graal.python.nodes.util.CastToJavaLongLossyNode; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.formatting.InternalFormat.Spec; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -126,7 +128,7 @@ Object getArg() { break; } if (ret == null) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.NOT_ENOUGH_ARGS_FOR_FORMAT_STRING); + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.NOT_ENOUGH_ARGS_FOR_FORMAT_STRING); } return ret; } @@ -138,11 +140,11 @@ int getNumber() { try { long value = CastToJavaLongLossyNode.executeUncached(o); if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) { - throw PRaiseNode.raiseUncached(raisingNode, OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "size"); + throw PRaiseNode.raiseStatic(raisingNode, OverflowError, ErrorMessages.PYTHON_INT_TOO_LARGE_TO_CONV_TO, "size"); } return (int) value; } catch (CannotCastException e) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.STAR_WANTS_INT); + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.STAR_WANTS_INT); } } else { if (Character.isDigit(c)) { @@ -154,7 +156,7 @@ int getNumber() { try { return parseNumber(numStart, index); } catch (NumberFormatException e) { - throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.TOO_MANY_DECIMAL_DIGITS_IN_FORMAT_STRING); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.TOO_MANY_DECIMAL_DIGITS_IN_FORMAT_STRING); } } index -= 1; @@ -180,7 +182,7 @@ protected final Object asNumber(Object arg, char specType) { if (allowsFloat(specType)) { // Fast path for simple double values, instead of __int__ BigDecimal decimal = new BigDecimal((Double) arg, MathContext.UNLIMITED); - return core.factory().createInt(decimal.toBigInteger()); + return PFactory.createInt(PythonLanguage.get(null), decimal.toBigInteger()); } else { // non-integer result indicates to the caller that it could not be converted return arg; @@ -245,7 +247,7 @@ public T format(Object args1) { try { return formatImpl(args1); } catch (OutOfMemoryError e) { - throw PRaiseNode.raiseUncached(raisingNode, MemoryError); + throw PRaiseNode.raiseStatic(raisingNode, MemoryError); } } @@ -309,7 +311,7 @@ private T formatImpl(Object args1) { if (c == '(') { // Mapping key, consisting of a parenthesised sequence of characters. if (mapping == null) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.FORMAT_REQUIRES_MAPPING); + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.FORMAT_REQUIRES_MAPPING); } // Scan along until a matching close parenthesis is found int parens = 1; @@ -448,9 +450,9 @@ private T formatImpl(Object args1) { f = formatInteger(asNumber(arg, spec.type), spec); if (f == null) { if (allowsFloat(spec.type)) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.S_FORMAT_NUMBER_IS_REQUIRED_NOT_S, spec.type, arg); + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.S_FORMAT_NUMBER_IS_REQUIRED_NOT_S, spec.type, arg); } else { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.S_FORMAT_INTEGER_IS_REQUIRED_NOT_S, spec.type, arg); + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.S_FORMAT_INTEGER_IS_REQUIRED_NOT_S, spec.type, arg); } } break; @@ -472,7 +474,7 @@ private T formatImpl(Object args1) { default: f = handleRemainingFormats(spec); if (f == null) { - throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.UNSUPPORTED_FORMAT_CHAR_AT_INDEX, spec.type, (int) spec.type, index - 1); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.UNSUPPORTED_FORMAT_CHAR_AT_INDEX, spec.type, (int) spec.type, index - 1); } } @@ -488,7 +490,7 @@ private T formatImpl(Object args1) { * that has not yet been used. */ if (argIndex == -1 || (argIndex >= 0 && PyObjectSizeNode.executeUncached(args1) >= argIndex + 1)) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.NOT_ALL_ARGS_CONVERTED_DURING_FORMATTING, getFormatType()); + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.NOT_ALL_ARGS_CONVERTED_DURING_FORMATTING, getFormatType()); } // Return the final buffer contents as a str or unicode as appropriate. diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/IntegerFormatter.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/IntegerFormatter.java index 8d382e375d..d8b79363e7 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/IntegerFormatter.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/IntegerFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) -2016 Jython Developers * * Licensed under PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -286,7 +286,7 @@ void format_b(BigInteger value) { final void format_c(BigInteger value) { assert !bytes; // for bytes we use directly BytesFormatter if (value.signum() < 0 || value.compareTo(LIMIT_UNICODE) >= 0) { - throw PRaiseNode.raiseUncached(raisingNode, OverflowError, ErrorMessages.C_ARG_NOT_IN_RANGE, toHexString(LIMIT_UNICODE)); + throw PRaiseNode.raiseStatic(raisingNode, OverflowError, ErrorMessages.C_ARG_NOT_IN_RANGE, toHexString(LIMIT_UNICODE)); } result.appendCodePoint(value.intValue()); } @@ -466,7 +466,7 @@ void format_b(int value) { final void format_c(int value) { assert !bytes; // for bytes we use directly BytesFormatter if (value < 0 || value >= LIMIT_UNICODE.intValue()) { - throw PRaiseNode.raiseUncached(raisingNode, OverflowError, ErrorMessages.C_ARG_NOT_IN_RANGE, toHexString(LIMIT_UNICODE)); + throw PRaiseNode.raiseStatic(raisingNode, OverflowError, ErrorMessages.C_ARG_NOT_IN_RANGE, toHexString(LIMIT_UNICODE)); } result.appendCodePoint(value); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/InternalFormat.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/InternalFormat.java index e9b7ef25a6..ca4d7e6df3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/InternalFormat.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/InternalFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) -2016 Jython Developers * * Licensed under PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -508,7 +508,7 @@ protected void zeroPadAfterSignWithGroupingFixup(int groupSize, char comma) { * @return exception to throw */ public static PException unknownFormat(char code, String forType, Node raisingNode) { - throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.UNKNOWN_FORMAT_CODE, code, forType); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.UNKNOWN_FORMAT_CODE, code, forType); } /** @@ -520,7 +520,7 @@ public static PException unknownFormat(char code, String forType, Node raisingNo * @return exception to throw */ public PException precisionTooLarge(String type) { - throw PRaiseNode.raiseUncached(raisingNode, OverflowError, ErrorMessages.FORMATED_S_TOO_LONG, type); + throw PRaiseNode.raiseStatic(raisingNode, OverflowError, ErrorMessages.FORMATED_S_TOO_LONG, type); } } @@ -806,7 +806,7 @@ Spec parse(char defaultType, char defaultAlignment, Node raisingNode) { width = scanInteger(); } catch (NumberFormatException ex) { // CPython seems to happily parse big ints and then it chokes on the allocation - throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.WIDTH_TOO_BIG); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.WIDTH_TOO_BIG); } } @@ -816,11 +816,11 @@ Spec parse(char defaultType, char defaultAlignment, Node raisingNode) { } if (scanPast('_')) { if (specified(grouping)) { - throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.CANNOT_SPECIFY_BOTH_COMMA_AND_UNDERSCORE); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.CANNOT_SPECIFY_BOTH_COMMA_AND_UNDERSCORE); } grouping = '_'; if (scanPast(',')) { - throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.CANNOT_SPECIFY_BOTH_COMMA_AND_UNDERSCORE); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.CANNOT_SPECIFY_BOTH_COMMA_AND_UNDERSCORE); } } @@ -830,10 +830,10 @@ Spec parse(char defaultType, char defaultAlignment, Node raisingNode) { try { precision = scanInteger(); } catch (NumberFormatException ex) { - throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.PRECISION_TOO_BIG); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.PRECISION_TOO_BIG); } } else { - throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.FMT_SPECIFIER_MISSING_PRECISION); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.FMT_SPECIFIER_MISSING_PRECISION); } } @@ -844,7 +844,7 @@ Spec parse(char defaultType, char defaultAlignment, Node raisingNode) { // If we haven't reached the end, something is wrong if (ptr != spec.length()) { - throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.INVALID_CONVERSION_SPECIFICATION); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.INVALID_CONVERSION_SPECIFICATION); } // Some basic validation @@ -875,7 +875,7 @@ Spec parse(char defaultType, char defaultAlignment, Node raisingNode) { valid = false; } if (!valid) { - throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.CANNOT_SPECIFY_C_WITH_C, grouping, type); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.CANNOT_SPECIFY_C_WITH_C, grouping, type); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/StringFormatProcessor.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/StringFormatProcessor.java index 29d67a20a4..b16ebcdc2b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/StringFormatProcessor.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/StringFormatProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) -2016 Jython Developers * * Licensed under PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -45,7 +45,7 @@ public char pop() { try { return formatText.charAt(index++); } catch (StringIndexOutOfBoundsException e) { - throw PRaiseNode.raiseUncached(raisingNode, ValueError, ErrorMessages.INCOMPLETE_FORMAT); + throw PRaiseNode.raiseStatic(raisingNode, ValueError, ErrorMessages.INCOMPLETE_FORMAT); } } @@ -91,7 +91,7 @@ protected InternalFormat.Formatter handleSingleCharacterFormat(Spec spec) { } else { f = formatInteger(asNumber(arg, spec.type), spec); if (f == null) { - throw PRaiseNode.raiseUncached(raisingNode, TypeError, ErrorMessages.REQUIRES_INT_OR_CHAR, spec.type); + throw PRaiseNode.raiseStatic(raisingNode, TypeError, ErrorMessages.REQUIRES_INT_OR_CHAR, spec.type); } } return f; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/IDUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/IDUtils.java index 1d9cd21891..d1cc7c2f89 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/IDUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/IDUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -46,6 +46,7 @@ import java.util.WeakHashMap; import java.util.concurrent.atomic.AtomicLong; +import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.util.WeakIdentityHashMap; import com.oracle.truffle.api.CompilerDirectives; @@ -106,11 +107,11 @@ private static BigInteger asMaskedBigIntId(long id, BigInteger mask) { return BigInteger.valueOf(id).shiftLeft(2).or(mask); } - private static Object asMaskedId(long id, PythonObjectFactory factory, long max, long mask, BigInteger biMask) { + private static Object asMaskedId(PythonLanguage language, long id, long max, long mask, BigInteger biMask) { if (Long.compareUnsigned(id, max) <= 0) { return (id << 2) | mask; } - return factory.createInt(asMaskedBigIntId(id, biMask)); + return PFactory.createInt(language, asMaskedBigIntId(id, biMask)); } private static long getId(ReservedID reservedID) { @@ -125,13 +126,13 @@ public static Object getId(int id) { return ((long) id << 2) | ID_MASK_LONG; } - public static Object getId(long id, PythonObjectFactory factory) { - return asMaskedId(id, factory, MAX_OBJECT_ID, ID_MASK_LONG, ID_MASK_LONG_BI); + public static Object getId(PythonLanguage language, long id) { + return asMaskedId(language, id, MAX_OBJECT_ID, ID_MASK_LONG, ID_MASK_LONG_BI); } - public static Object getId(double id, PythonObjectFactory factory) { + public static Object getId(PythonLanguage language, double id) { long ieee754 = Double.doubleToLongBits(id); - return asMaskedId(ieee754, factory, MAX_DOUBLE_ID, ID_MASK_DOUBLE, ID_MASK_DOUBLE_BI); + return asMaskedId(language, ieee754, MAX_DOUBLE_ID, ID_MASK_DOUBLE, ID_MASK_DOUBLE_BI); } @CompilerDirectives.TruffleBoundary(allowInlining = true) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PFactory.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PFactory.java new file mode 100644 index 0000000000..b39bc8bed0 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PFactory.java @@ -0,0 +1,1684 @@ +/* + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. + * Copyright (c) 2013, Regents of the University of California + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.oracle.graal.python.runtime.object; + +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEW__; +import static com.oracle.graal.python.util.PythonUtils.EMPTY_OBJECT_ARRAY; + +import java.lang.ref.ReferenceQueue; +import java.math.BigInteger; +import java.util.LinkedHashMap; +import java.util.concurrent.Semaphore; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; + +import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.modules.PosixModuleBuiltins.PosixFileHandle; +import com.oracle.graal.python.builtins.modules.bz2.BZ2Object; +import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteCodec; +import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteCodecObject; +import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteIncrementalDecoderObject; +import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteIncrementalEncoderObject; +import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteStreamReaderObject; +import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteStreamWriterObject; +import com.oracle.graal.python.builtins.modules.codecs.PEncodingMap; +import com.oracle.graal.python.builtins.modules.csv.CSVDialect; +import com.oracle.graal.python.builtins.modules.csv.CSVReader; +import com.oracle.graal.python.builtins.modules.csv.CSVWriter; +import com.oracle.graal.python.builtins.modules.csv.QuoteStyle; +import com.oracle.graal.python.builtins.modules.ctypes.CDataObject; +import com.oracle.graal.python.builtins.modules.ctypes.CFieldObject; +import com.oracle.graal.python.builtins.modules.ctypes.CThunkObject; +import com.oracle.graal.python.builtins.modules.ctypes.PyCArgObject; +import com.oracle.graal.python.builtins.modules.ctypes.PyCFuncPtrObject; +import com.oracle.graal.python.builtins.modules.ctypes.StgDictObject; +import com.oracle.graal.python.builtins.modules.ctypes.memory.Pointer; +import com.oracle.graal.python.builtins.modules.functools.LruCacheObject; +import com.oracle.graal.python.builtins.modules.functools.PKeyWrapper; +import com.oracle.graal.python.builtins.modules.functools.PPartial; +import com.oracle.graal.python.builtins.modules.hashlib.DigestObject; +import com.oracle.graal.python.builtins.modules.io.PBuffered; +import com.oracle.graal.python.builtins.modules.io.PBytesIO; +import com.oracle.graal.python.builtins.modules.io.PBytesIOBuffer; +import com.oracle.graal.python.builtins.modules.io.PFileIO; +import com.oracle.graal.python.builtins.modules.io.PNLDecoder; +import com.oracle.graal.python.builtins.modules.io.PRWPair; +import com.oracle.graal.python.builtins.modules.io.PStringIO; +import com.oracle.graal.python.builtins.modules.io.PTextIO; +import com.oracle.graal.python.builtins.modules.json.PJSONEncoder; +import com.oracle.graal.python.builtins.modules.json.PJSONEncoder.FastEncode; +import com.oracle.graal.python.builtins.modules.json.PJSONScanner; +import com.oracle.graal.python.builtins.modules.lsprof.Profiler; +import com.oracle.graal.python.builtins.modules.lzma.LZMAObject; +import com.oracle.graal.python.builtins.modules.multiprocessing.PGraalPySemLock; +import com.oracle.graal.python.builtins.modules.multiprocessing.PSemLock; +import com.oracle.graal.python.builtins.modules.pickle.PPickleBuffer; +import com.oracle.graal.python.builtins.modules.pickle.PPickler; +import com.oracle.graal.python.builtins.modules.pickle.PPicklerMemoProxy; +import com.oracle.graal.python.builtins.modules.pickle.PUnpickler; +import com.oracle.graal.python.builtins.modules.pickle.PUnpicklerMemoProxy; +import com.oracle.graal.python.builtins.modules.zlib.ZLibCompObject; +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.array.PArray; +import com.oracle.graal.python.builtins.objects.asyncio.PANextAwaitable; +import com.oracle.graal.python.builtins.objects.asyncio.PAsyncGen; +import com.oracle.graal.python.builtins.objects.asyncio.PAsyncGenASend; +import com.oracle.graal.python.builtins.objects.asyncio.PAsyncGenAThrow; +import com.oracle.graal.python.builtins.objects.asyncio.PAsyncGenWrappedValue; +import com.oracle.graal.python.builtins.objects.asyncio.PCoroutineWrapper; +import com.oracle.graal.python.builtins.objects.bytes.PByteArray; +import com.oracle.graal.python.builtins.objects.bytes.PBytes; +import com.oracle.graal.python.builtins.objects.capsule.PyCapsule; +import com.oracle.graal.python.builtins.objects.cell.PCell; +import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr; +import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper; +import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers; +import com.oracle.graal.python.builtins.objects.cext.common.CExtContext; +import com.oracle.graal.python.builtins.objects.code.PCode; +import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage; +import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; +import com.oracle.graal.python.builtins.objects.common.EmptyStorage; +import com.oracle.graal.python.builtins.objects.common.ForeignHashingStorage; +import com.oracle.graal.python.builtins.objects.common.HashingStorage; +import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes; +import com.oracle.graal.python.builtins.objects.common.KeywordsStorage; +import com.oracle.graal.python.builtins.objects.common.PHashingCollection; +import com.oracle.graal.python.builtins.objects.complex.PComplex; +import com.oracle.graal.python.builtins.objects.contextvars.PContextIterator; +import com.oracle.graal.python.builtins.objects.contextvars.PContextVar; +import com.oracle.graal.python.builtins.objects.contextvars.PContextVarsContext; +import com.oracle.graal.python.builtins.objects.contextvars.PContextVarsToken; +import com.oracle.graal.python.builtins.objects.deque.PDeque; +import com.oracle.graal.python.builtins.objects.deque.PDequeIter; +import com.oracle.graal.python.builtins.objects.dict.PDefaultDict; +import com.oracle.graal.python.builtins.objects.dict.PDict; +import com.oracle.graal.python.builtins.objects.dict.PDictView; +import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictItemIterator; +import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictItemsView; +import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictKeyIterator; +import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictKeysView; +import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictValueIterator; +import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictValuesView; +import com.oracle.graal.python.builtins.objects.enumerate.PEnumerate; +import com.oracle.graal.python.builtins.objects.exception.PBaseException; +import com.oracle.graal.python.builtins.objects.exception.PBaseExceptionGroup; +import com.oracle.graal.python.builtins.objects.floats.PFloat; +import com.oracle.graal.python.builtins.objects.frame.PFrame; +import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; +import com.oracle.graal.python.builtins.objects.function.PFunction; +import com.oracle.graal.python.builtins.objects.function.PKeyword; +import com.oracle.graal.python.builtins.objects.function.Signature; +import com.oracle.graal.python.builtins.objects.generator.PGenerator; +import com.oracle.graal.python.builtins.objects.getsetdescriptor.GetSetDescriptor; +import com.oracle.graal.python.builtins.objects.getsetdescriptor.IndexedSlotDescriptor; +import com.oracle.graal.python.builtins.objects.ints.PInt; +import com.oracle.graal.python.builtins.objects.iterator.PArrayIterator; +import com.oracle.graal.python.builtins.objects.iterator.PBaseSetIterator; +import com.oracle.graal.python.builtins.objects.iterator.PBigRangeIterator; +import com.oracle.graal.python.builtins.objects.iterator.PDoubleSequenceIterator; +import com.oracle.graal.python.builtins.objects.iterator.PIntRangeIterator; +import com.oracle.graal.python.builtins.objects.iterator.PIntegerSequenceIterator; +import com.oracle.graal.python.builtins.objects.iterator.PLongSequenceIterator; +import com.oracle.graal.python.builtins.objects.iterator.PObjectSequenceIterator; +import com.oracle.graal.python.builtins.objects.iterator.PSentinelIterator; +import com.oracle.graal.python.builtins.objects.iterator.PSequenceIterator; +import com.oracle.graal.python.builtins.objects.iterator.PStringIterator; +import com.oracle.graal.python.builtins.objects.iterator.PStructUnpackIterator; +import com.oracle.graal.python.builtins.objects.iterator.PZip; +import com.oracle.graal.python.builtins.objects.itertools.PAccumulate; +import com.oracle.graal.python.builtins.objects.itertools.PChain; +import com.oracle.graal.python.builtins.objects.itertools.PCombinations; +import com.oracle.graal.python.builtins.objects.itertools.PCombinationsWithReplacement; +import com.oracle.graal.python.builtins.objects.itertools.PCompress; +import com.oracle.graal.python.builtins.objects.itertools.PCount; +import com.oracle.graal.python.builtins.objects.itertools.PCycle; +import com.oracle.graal.python.builtins.objects.itertools.PDropwhile; +import com.oracle.graal.python.builtins.objects.itertools.PFilterfalse; +import com.oracle.graal.python.builtins.objects.itertools.PGroupBy; +import com.oracle.graal.python.builtins.objects.itertools.PGrouper; +import com.oracle.graal.python.builtins.objects.itertools.PIslice; +import com.oracle.graal.python.builtins.objects.itertools.PPairwise; +import com.oracle.graal.python.builtins.objects.itertools.PPermutations; +import com.oracle.graal.python.builtins.objects.itertools.PProduct; +import com.oracle.graal.python.builtins.objects.itertools.PRepeat; +import com.oracle.graal.python.builtins.objects.itertools.PStarmap; +import com.oracle.graal.python.builtins.objects.itertools.PTakewhile; +import com.oracle.graal.python.builtins.objects.itertools.PTee; +import com.oracle.graal.python.builtins.objects.itertools.PTeeDataObject; +import com.oracle.graal.python.builtins.objects.itertools.PZipLongest; +import com.oracle.graal.python.builtins.objects.list.PList; +import com.oracle.graal.python.builtins.objects.map.PMap; +import com.oracle.graal.python.builtins.objects.mappingproxy.PMappingproxy; +import com.oracle.graal.python.builtins.objects.memoryview.BufferLifecycleManager; +import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; +import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; +import com.oracle.graal.python.builtins.objects.method.PDecoratedMethod; +import com.oracle.graal.python.builtins.objects.method.PMethod; +import com.oracle.graal.python.builtins.objects.mmap.PMMap; +import com.oracle.graal.python.builtins.objects.module.PythonModule; +import com.oracle.graal.python.builtins.objects.namespace.PSimpleNamespace; +import com.oracle.graal.python.builtins.objects.object.PythonObject; +import com.oracle.graal.python.builtins.objects.ordereddict.POrderedDict; +import com.oracle.graal.python.builtins.objects.ordereddict.POrderedDictIterator; +import com.oracle.graal.python.builtins.objects.posix.PDirEntry; +import com.oracle.graal.python.builtins.objects.posix.PScandirIterator; +import com.oracle.graal.python.builtins.objects.property.PProperty; +import com.oracle.graal.python.builtins.objects.queue.PSimpleQueue; +import com.oracle.graal.python.builtins.objects.random.PRandom; +import com.oracle.graal.python.builtins.objects.range.PBigRange; +import com.oracle.graal.python.builtins.objects.range.PIntRange; +import com.oracle.graal.python.builtins.objects.referencetype.PReferenceType; +import com.oracle.graal.python.builtins.objects.reversed.PSequenceReverseIterator; +import com.oracle.graal.python.builtins.objects.reversed.PStringReverseIterator; +import com.oracle.graal.python.builtins.objects.set.PBaseSet; +import com.oracle.graal.python.builtins.objects.set.PFrozenSet; +import com.oracle.graal.python.builtins.objects.set.PSet; +import com.oracle.graal.python.builtins.objects.slice.PIntSlice; +import com.oracle.graal.python.builtins.objects.slice.PObjectSlice; +import com.oracle.graal.python.builtins.objects.socket.PSocket; +import com.oracle.graal.python.builtins.objects.ssl.PMemoryBIO; +import com.oracle.graal.python.builtins.objects.ssl.PSSLContext; +import com.oracle.graal.python.builtins.objects.ssl.PSSLSocket; +import com.oracle.graal.python.builtins.objects.ssl.SSLMethod; +import com.oracle.graal.python.builtins.objects.str.NativeCharSequence; +import com.oracle.graal.python.builtins.objects.str.PString; +import com.oracle.graal.python.builtins.objects.struct.PStruct; +import com.oracle.graal.python.builtins.objects.superobject.SuperObject; +import com.oracle.graal.python.builtins.objects.thread.PLock; +import com.oracle.graal.python.builtins.objects.thread.PRLock; +import com.oracle.graal.python.builtins.objects.thread.PThreadLocal; +import com.oracle.graal.python.builtins.objects.tokenize.PTokenizerIter; +import com.oracle.graal.python.builtins.objects.traceback.LazyTraceback; +import com.oracle.graal.python.builtins.objects.traceback.PTraceback; +import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.tuple.PTupleGetter; +import com.oracle.graal.python.builtins.objects.tuple.StructSequence.BuiltinTypeDescriptor; +import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; +import com.oracle.graal.python.builtins.objects.type.PythonClass; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroStorageNode; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; +import com.oracle.graal.python.builtins.objects.types.PGenericAlias; +import com.oracle.graal.python.builtins.objects.types.PGenericAliasIterator; +import com.oracle.graal.python.builtins.objects.types.PUnionType; +import com.oracle.graal.python.compiler.BytecodeCodeUnit; +import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode; +import com.oracle.graal.python.nodes.bytecode_dsl.BytecodeDSLCodeUnit; +import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode; +import com.oracle.graal.python.runtime.NFIZlibSupport; +import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage; +import com.oracle.graal.python.runtime.sequence.storage.DoubleSequenceStorage; +import com.oracle.graal.python.runtime.sequence.storage.EmptySequenceStorage; +import com.oracle.graal.python.runtime.sequence.storage.IntSequenceStorage; +import com.oracle.graal.python.runtime.sequence.storage.LongSequenceStorage; +import com.oracle.graal.python.runtime.sequence.storage.MroSequenceStorage; +import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; +import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; +import com.oracle.graal.python.util.BufferFormat; +import com.oracle.graal.python.util.OverflowException; +import com.oracle.graal.python.util.PythonUtils; +import com.oracle.truffle.api.Assumption; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.instrumentation.AllocationReporter; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.object.Shape; +import com.oracle.truffle.api.strings.TruffleString; +import com.oracle.truffle.tools.profiler.CPUSampler; + +public final class PFactory { + private PFactory() { + } + + private static T trace(PythonLanguage language, T newInstance) { + AllocationReporter reporter = language.getAllocationReporter(); + if (reporter.isActive()) { + doTrace(newInstance, reporter); + } + return newInstance; + } + + @InliningCutoff + private static void doTrace(T newInstance, AllocationReporter reporter) { + reporter.onEnter(null, 0, AllocationReporter.SIZE_UNKNOWN); + reporter.onReturnValue(newInstance, 0, AllocationReporter.SIZE_UNKNOWN); + } + + /* + * Python objects + */ + public static PythonObject createPythonObject(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PythonObject(cls, shape)); + } + + public static PythonNativeVoidPtr createNativeVoidPtr(PythonLanguage language, Object obj) { + return trace(language, new PythonNativeVoidPtr(obj)); + } + + public static PythonNativeVoidPtr createNativeVoidPtr(PythonLanguage language, Object obj, long nativePtr) { + return trace(language, new PythonNativeVoidPtr(obj, nativePtr)); + } + + public static SuperObject createSuperObject(PythonLanguage language) { + return createSuperObject(language, PythonBuiltinClassType.Super, PythonBuiltinClassType.Super.getInstanceShape(language)); + } + + public static SuperObject createSuperObject(PythonLanguage language, Object self, Shape shape) { + return trace(language, new SuperObject(self, shape)); + } + + public static PInt createInt(PythonLanguage language, long value) { + return createInt(language, PythonBuiltinClassType.PInt, language.getBuiltinTypeInstanceShape(PythonBuiltinClassType.PInt), asBigInt(value)); + } + + @TruffleBoundary + private static BigInteger asBigInt(long value) { + return BigInteger.valueOf(value); + } + + public static PInt createInt(PythonLanguage language, BigInteger value) { + return createInt(language, PythonBuiltinClassType.PInt, language.getBuiltinTypeInstanceShape(PythonBuiltinClassType.PInt), value); + } + + public static PInt createInt(PythonLanguage language, Object cls, Shape shape, long value) { + return createInt(language, cls, shape, asBigInt(value)); + } + + public static PInt createInt(PythonLanguage language, Object cls, Shape shape, BigInteger value) { + return trace(language, new PInt(cls, shape, value)); + } + + public static PFloat createFloat(PythonLanguage language, double value) { + return createFloat(language, PythonBuiltinClassType.PFloat, language.getBuiltinTypeInstanceShape(PythonBuiltinClassType.PFloat), value); + } + + public static PFloat createFloat(PythonLanguage language, Object cls, Shape shape, double value) { + return trace(language, new PFloat(cls, shape, value)); + } + + public static PString createString(PythonLanguage language, TruffleString string) { + return createString(language, PythonBuiltinClassType.PString, language.getBuiltinTypeInstanceShape(PythonBuiltinClassType.PString), string); + } + + public static PString createString(PythonLanguage language, Object cls, Shape shape, TruffleString string) { + return trace(language, new PString(cls, shape, string)); + } + + public static PString createString(PythonLanguage language, NativeCharSequence string) { + return createString(language, PythonBuiltinClassType.PString, language.getBuiltinTypeInstanceShape(PythonBuiltinClassType.PString), string); + } + + public static PString createString(PythonLanguage language, Object cls, Shape shape, NativeCharSequence string) { + return trace(language, new PString(cls, shape, string)); + } + + public static PBytes createEmptyBytes(PythonLanguage language) { + if (CompilerDirectives.inInterpreter()) { + return createBytes(language, PythonUtils.EMPTY_BYTE_ARRAY); + } else { + return createBytes(language, new byte[0]); + } + } + + public static PBytes createBytes(PythonLanguage language, byte[] array) { + return createBytes(language, array, array.length); + } + + public static PBytes createBytes(PythonLanguage language, byte[] array, int length) { + return createBytes(language, new ByteSequenceStorage(array, length)); + } + + public static PBytes createBytes(PythonLanguage language, SequenceStorage storage) { + return createBytes(language, PythonBuiltinClassType.PBytes, PythonBuiltinClassType.PBytes.getInstanceShape(language), storage); + } + + public static PBytes createBytes(PythonLanguage language, Object cls, Shape shape, byte[] bytes) { + return createBytes(language, cls, shape, new ByteSequenceStorage(bytes)); + } + + public static PBytes createBytes(PythonLanguage language, Object cls, Shape shape, SequenceStorage storage) { + return trace(language, new PBytes(cls, shape, storage)); + } + + public static PTuple createEmptyTuple(PythonLanguage language) { + return createTuple(language, EmptySequenceStorage.INSTANCE); + } + + public static PTuple createEmptyTuple(PythonLanguage language, Object cls, Shape shape) { + return createTuple(language, cls, shape, EmptySequenceStorage.INSTANCE); + } + + public static PTuple createTuple(PythonLanguage language, Object[] objects) { + return createTuple(language, new ObjectSequenceStorage(objects)); + } + + public static PTuple createTuple(PythonLanguage language, int[] ints) { + return createTuple(language, new IntSequenceStorage(ints)); + } + + public static PTuple createTuple(PythonLanguage language, SequenceStorage store) { + return createTuple(language, PythonBuiltinClassType.PTuple, PythonBuiltinClassType.PTuple.getInstanceShape(language), store); + } + + public static PTuple createTuple(PythonLanguage language, Object cls, Shape shape, SequenceStorage store) { + return trace(language, new PTuple(cls, shape, store)); + } + + public static PTuple createStructSeq(PythonLanguage language, BuiltinTypeDescriptor desc, Object... values) { + assert desc.inSequence <= values.length && values.length <= desc.fieldNames.length; + return createTuple(language, desc.type, desc.type.getInstanceShape(language), new ObjectSequenceStorage(values, desc.inSequence)); + } + + public static PTupleGetter createTupleGetter(PythonLanguage language, int index, Object doc) { + return createTupleGetter(language, PythonBuiltinClassType.PTupleGetter, PythonBuiltinClassType.PTupleGetter.getInstanceShape(language), index, doc); + } + + public static PTupleGetter createTupleGetter(PythonLanguage language, Object cls, Shape shape, int index, Object doc) { + return trace(language, new PTupleGetter(cls, shape, index, doc)); + } + + public static PComplex createComplex(PythonLanguage language, Object cls, Shape shape, double real, double imag) { + return trace(language, new PComplex(cls, shape, real, imag)); + } + + public static PComplex createComplex(PythonLanguage language, double real, double imag) { + return createComplex(language, PythonBuiltinClassType.PComplex, PythonBuiltinClassType.PComplex.getInstanceShape(language), real, imag); + } + + public static PIntRange createIntRange(PythonLanguage language, int stop) { + return trace(language, new PIntRange(language, 0, stop, 1, stop)); + } + + public static PIntRange createIntRange(PythonLanguage language, int start, int stop, int step, int len) { + return trace(language, new PIntRange(language, start, stop, step, len)); + } + + public static PBigRange createBigRange(PythonLanguage language, PInt start, PInt stop, PInt step, PInt len) { + return trace(language, new PBigRange(language, start, stop, step, len)); + } + + public static PIntSlice createIntSlice(PythonLanguage language, int start, int stop, int step) { + return trace(language, new PIntSlice(language, start, stop, step)); + } + + public static PIntSlice createIntSlice(PythonLanguage language, int start, int stop, int step, boolean isStartNone, boolean isStepNone) { + return trace(language, new PIntSlice(language, start, stop, step, isStartNone, isStepNone)); + } + + public static PObjectSlice createObjectSlice(PythonLanguage language, Object start, Object stop, Object step) { + return trace(language, new PObjectSlice(language, start, stop, step)); + } + + public static PRandom createRandom(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PRandom(cls, shape)); + } + + /* + * Classes, methods and functions + */ + + /** + * Only to be used during context creation + */ + public static PythonModule createPythonModule(PythonLanguage language, TruffleString name) { + return trace(language, PythonModule.createInternal(name)); + } + + public static PythonModule createPythonModule(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PythonModule(cls, shape)); + } + + public static PythonClass createPythonClassAndFixupSlots(PythonLanguage language, TruffleString name, Object base, PythonAbstractClass[] bases) { + return createPythonClassAndFixupSlots(language, PythonBuiltinClassType.PythonClass, PythonBuiltinClassType.PythonClass.getInstanceShape(language), name, base, bases); + } + + public static PythonClass createPythonClassAndFixupSlots(PythonLanguage language, Object metaclass, Shape metaclassShape, TruffleString name, Object base, PythonAbstractClass[] bases) { + PythonClass result = trace(language, new PythonClass(language, metaclass, metaclassShape, name, base, bases)); + // Fixup tp slots + MroSequenceStorage mro = GetMroStorageNode.executeUncached(result); + TpSlots.inherit(result, null, mro, true); + TpSlots.fixupSlotDispatchers(result); + result.initializeMroShape(language); + return result; + } + + public static PythonClass createPythonClass(PythonLanguage language, Object metaclass, Shape metaclassShape, TruffleString name, boolean invokeMro, Object base, PythonAbstractClass[] bases) { + return trace(language, new PythonClass(language, metaclass, metaclassShape, name, invokeMro, base, bases)); + } + + public static PMemoryView createMemoryView(PythonLanguage language, PythonContext context, BufferLifecycleManager bufferLifecycleManager, Object buffer, Object owner, + int len, boolean readonly, int itemsize, BufferFormat format, TruffleString formatString, int ndim, Object bufPointer, + int offset, int[] shape, int[] strides, int[] suboffsets, int flags) { + PythonBuiltinClassType cls = PythonBuiltinClassType.PMemoryView; + return trace(language, new PMemoryView(cls, cls.getInstanceShape(language), context, bufferLifecycleManager, buffer, owner, len, readonly, itemsize, format, formatString, + ndim, bufPointer, offset, shape, strides, suboffsets, flags)); + } + + public static PMemoryView createMemoryViewForManagedObject(PythonLanguage language, Object buffer, Object owner, int itemsize, int length, boolean readonly, TruffleString format, + TruffleString.CodePointLengthNode lengthNode, TruffleString.CodePointAtIndexNode atIndexNode) { + PythonBuiltinClassType cls = PythonBuiltinClassType.PMemoryView; + return trace(language, new PMemoryView(cls, cls.getInstanceShape(language), null, null, buffer, owner, length, readonly, itemsize, + BufferFormat.forMemoryView(format, lengthNode, atIndexNode), format, 1, null, 0, new int[]{length / itemsize}, new int[]{itemsize}, null, + PMemoryView.FLAG_C | PMemoryView.FLAG_FORTRAN)); + } + + public static PMethod createMethod(PythonLanguage language, Object cls, Shape shape, Object self, Object function) { + return trace(language, new PMethod(cls, shape, self, function)); + } + + public static PMethod createMethod(PythonLanguage language, Object self, Object function) { + return createMethod(language, PythonBuiltinClassType.PMethod, PythonBuiltinClassType.PMethod.getInstanceShape(language), self, function); + } + + public static PMethod createBuiltinMethod(PythonLanguage language, Object self, PFunction function) { + return createMethod(language, PythonBuiltinClassType.PBuiltinFunctionOrMethod, PythonBuiltinClassType.PBuiltinFunctionOrMethod.getInstanceShape(language), self, function); + } + + public static PBuiltinMethod createBuiltinMethod(PythonLanguage language, Object cls, Shape shape, Object self, PBuiltinFunction function) { + return trace(language, new PBuiltinMethod(cls, shape, self, function, null)); + } + + public static PBuiltinMethod createBuiltinMethod(PythonLanguage language, Object self, PBuiltinFunction function, Object classObject) { + return trace(language, new PBuiltinMethod(PythonBuiltinClassType.PBuiltinMethod, PythonBuiltinClassType.PBuiltinMethod.getInstanceShape(language), self, function, classObject)); + } + + public static PBuiltinMethod createBuiltinMethod(PythonLanguage language, Object self, PBuiltinFunction function) { + return createBuiltinMethod(language, PythonBuiltinClassType.PBuiltinFunctionOrMethod, PythonBuiltinClassType.PBuiltinFunctionOrMethod.getInstanceShape(language), self, function); + } + + public static PFunction createFunction(PythonLanguage language, TruffleString name, PCode code, PythonObject globals, PCell[] closure) { + return trace(language, new PFunction(language, name, name, code, globals, closure)); + } + + public static PFunction createFunction(PythonLanguage language, TruffleString name, TruffleString qualname, PCode code, PythonObject globals, Object[] defaultValues, PKeyword[] kwDefaultValues, + PCell[] closure) { + return trace(language, new PFunction(language, name, qualname, code, globals, defaultValues, kwDefaultValues, closure)); + } + + public static PFunction createFunction(PythonLanguage language, TruffleString name, PCode code, PythonObject globals, Object[] defaultValues, PKeyword[] kwDefaultValues, PCell[] closure) { + return trace(language, new PFunction(language, name, name, code, globals, defaultValues, kwDefaultValues, closure)); + } + + public static PFunction createFunction(PythonLanguage language, TruffleString name, TruffleString qualname, PCode code, PythonObject globals, Object[] defaultValues, PKeyword[] kwDefaultValues, + PCell[] closure, Assumption codeStableAssumption) { + return trace(language, new PFunction(language, name, qualname, code, globals, defaultValues, kwDefaultValues, closure, codeStableAssumption)); + } + + public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, TruffleString name, Object type, int numDefaults, int flags, RootCallTarget callTarget) { + return trace(language, new PBuiltinFunction(PythonBuiltinClassType.PBuiltinFunction, PythonBuiltinClassType.PBuiltinFunction.getInstanceShape(language), name, type, + PBuiltinFunction.generateDefaults(numDefaults), null, flags, callTarget)); + } + + public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, TruffleString name, Object type, Object[] defaults, PKeyword[] kw, int flags, RootCallTarget callTarget) { + return trace(language, new PBuiltinFunction(PythonBuiltinClassType.PBuiltinFunction, PythonBuiltinClassType.PBuiltinFunction.getInstanceShape(language), name, type, defaults, kw, flags, + callTarget)); + } + + public static PBuiltinFunction createWrapperDescriptor(PythonLanguage language, TruffleString name, Object type, int numDefaults, int flags, RootCallTarget callTarget, TpSlot slot, + PExternalFunctionWrapper slotWrapper) { + return trace(language, new PBuiltinFunction(PythonBuiltinClassType.WrapperDescriptor, PythonBuiltinClassType.WrapperDescriptor.getInstanceShape(language), name, type, + PBuiltinFunction.generateDefaults(numDefaults), null, flags, callTarget, slot, slotWrapper)); + } + + public static PBuiltinFunction createWrapperDescriptor(PythonLanguage language, TruffleString name, Object type, Object[] defaults, PKeyword[] kw, int flags, RootCallTarget callTarget, + TpSlot slot, PExternalFunctionWrapper slotWrapper) { + return trace(language, new PBuiltinFunction(PythonBuiltinClassType.WrapperDescriptor, PythonBuiltinClassType.WrapperDescriptor.getInstanceShape(language), name, type, defaults, kw, flags, + callTarget, slot, slotWrapper)); + } + + public static PBuiltinMethod createNewWrapper(PythonLanguage language, Object type, Object[] defaults, PKeyword[] kwdefaults, RootCallTarget callTarget, TpSlot slot) { + PBuiltinFunction func = createWrapperDescriptor(language, T___NEW__, type, defaults, kwdefaults, CExtContext.METH_VARARGS | CExtContext.METH_KEYWORDS, callTarget, slot, + PExternalFunctionWrapper.NEW); + return createBuiltinMethod(language, type, func); + } + + public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, PBuiltinFunction function, Object klass) { + PythonBuiltinClassType type = (PythonBuiltinClassType) function.getInitialPythonClass(); + return trace(language, new PBuiltinFunction(type, type.getInstanceShape(language), function.getName(), klass, + function.getDefaults(), function.getKwDefaults(), function.getFlags(), function.getCallTarget(), + function.getSlot(), function.getSlotWrapper())); + } + + public static GetSetDescriptor createGetSetDescriptor(PythonLanguage language, Object get, Object set, TruffleString name, Object type, boolean allowsDelete) { + return trace(language, new GetSetDescriptor(language, get, set, name, type, allowsDelete)); + } + + public static GetSetDescriptor createMemberDescriptor(PythonLanguage language, Object get, Object set, TruffleString name, Object type) { + return trace(language, new GetSetDescriptor(PythonBuiltinClassType.MemberDescriptor, PythonBuiltinClassType.MemberDescriptor.getInstanceShape(language), get, set, name, type, set != null)); + } + + public static IndexedSlotDescriptor createIndexedSlotDescriptor(PythonLanguage language, TruffleString name, int index, Object type) { + return trace(language, new IndexedSlotDescriptor(language, name, index, type)); + } + + public static PDecoratedMethod createClassmethod(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PDecoratedMethod(cls, shape)); + } + + public static PDecoratedMethod createClassmethodFromCallableObj(PythonLanguage language, Object callable) { + return trace(language, new PDecoratedMethod(PythonBuiltinClassType.PClassmethod, PythonBuiltinClassType.PClassmethod.getInstanceShape(language), callable)); + } + + public static PDecoratedMethod createBuiltinClassmethodFromCallableObj(PythonLanguage language, Object callable) { + return trace(language, new PDecoratedMethod(PythonBuiltinClassType.PBuiltinClassMethod, PythonBuiltinClassType.PBuiltinClassMethod.getInstanceShape(language), callable)); + } + + public static PDecoratedMethod createInstancemethod(PythonLanguage language) { + return createInstancemethod(language, PythonBuiltinClassType.PInstancemethod, PythonBuiltinClassType.PInstancemethod.getInstanceShape(language)); + } + + public static PDecoratedMethod createInstancemethod(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PDecoratedMethod(cls, shape)); + } + + public static PDecoratedMethod createStaticmethod(PythonLanguage language) { + return createStaticmethod(language, PythonBuiltinClassType.PStaticmethod, PythonBuiltinClassType.PStaticmethod.getInstanceShape(language)); + } + + public static PDecoratedMethod createStaticmethod(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PDecoratedMethod(cls, shape)); + } + + public static PDecoratedMethod createStaticmethodFromCallableObj(PythonLanguage language, Object callable) { + Object func; + if (callable instanceof PBuiltinFunction builtinFunction) { + /* + * CPython's C static methods contain an object of type `builtin_function_or_method` + * (our PBuiltinMethod). Their self points to their type, but when called they get NULL + * as the first argument instead. + */ + func = createBuiltinMethod(language, builtinFunction.getEnclosingType(), builtinFunction); + } else { + func = callable; + } + return trace(language, new PDecoratedMethod(PythonBuiltinClassType.PStaticmethod, PythonBuiltinClassType.PStaticmethod.getInstanceShape(language), func)); + } + + /* + * Lists, sets and dicts + */ + + public static PList createList(PythonLanguage language) { + return createList(language, EmptySequenceStorage.INSTANCE); + } + + public static PList createList(PythonLanguage language, Object[] array) { + return createList(language, new ObjectSequenceStorage(array)); + } + + public static PList createList(PythonLanguage language, SequenceStorage storage) { + return createList(language, storage, (PList.ListOrigin) null); + } + + public static PList createList(PythonLanguage language, SequenceStorage storage, PList.ListOrigin origin) { + return createList(language, PythonBuiltinClassType.PList, PythonBuiltinClassType.PList.getInstanceShape(language), storage, origin); + } + + public static PList createList(PythonLanguage language, Object cls, Shape shape) { + return createList(language, cls, shape, EmptySequenceStorage.INSTANCE); + } + + public static PList createList(PythonLanguage language, Object cls, Shape shape, SequenceStorage storage) { + return createList(language, cls, shape, storage, null); + } + + public static PList createList(PythonLanguage language, Object cls, Shape shape, SequenceStorage storage, PList.ListOrigin origin) { + return trace(language, new PList(cls, shape, storage, origin)); + } + + public static PSet createSet(PythonLanguage language) { + return createSet(language, EmptyStorage.INSTANCE); + } + + public static PSet createSet(PythonLanguage language, HashingStorage storage) { + return createSet(language, PythonBuiltinClassType.PSet, PythonBuiltinClassType.PSet.getInstanceShape(language), storage); + } + + public static PSet createSet(PythonLanguage language, Object cls, Shape shape) { + return createSet(language, cls, shape, EmptyStorage.INSTANCE); + } + + public static PSet createSet(PythonLanguage language, Object cls, Shape shape, HashingStorage storage) { + return trace(language, new PSet(cls, shape, storage)); + } + + public static PFrozenSet createFrozenSet(PythonLanguage language) { + return createFrozenSet(language, EmptyStorage.INSTANCE); + } + + public static PFrozenSet createFrozenSet(PythonLanguage language, HashingStorage storage) { + return createFrozenSet(language, PythonBuiltinClassType.PFrozenSet, PythonBuiltinClassType.PFrozenSet.getInstanceShape(language), storage); + } + + public static PFrozenSet createFrozenSet(PythonLanguage language, Object cls, Shape shape, HashingStorage storage) { + return trace(language, new PFrozenSet(cls, shape, storage)); + } + + public static PDict createDict(PythonLanguage language) { + return createDict(language, EmptyStorage.INSTANCE); + } + + public static PDict createDict(PythonLanguage language, PKeyword[] keywords) { + return createDict(language, new KeywordsStorage(keywords)); + } + + public static PDict createDict(PythonLanguage language, HashingStorage storage) { + return createDict(language, PythonBuiltinClassType.PDict, PythonBuiltinClassType.PDict.getInstanceShape(language), storage); + } + + public static PDict createDict(PythonLanguage language, Object cls, Shape shape, HashingStorage storage) { + return trace(language, new PDict(cls, shape, storage)); + } + + public static POrderedDict createOrderedDict(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new POrderedDict(cls, shape)); + } + + public static PDictKeysView createOrderedDictKeys(PythonLanguage language, POrderedDict dict) { + PythonBuiltinClassType cls = PythonBuiltinClassType.POrderedDictKeys; + return trace(language, new PDictKeysView(cls, cls.getInstanceShape(language), dict)); + } + + public static PDictValuesView createOrderedDictValues(PythonLanguage language, POrderedDict dict) { + PythonBuiltinClassType cls = PythonBuiltinClassType.POrderedDictValues; + return trace(language, new PDictValuesView(cls, cls.getInstanceShape(language), dict)); + } + + public static PDictItemsView createOrderedDictItems(PythonLanguage language, POrderedDict dict) { + PythonBuiltinClassType cls = PythonBuiltinClassType.POrderedDictItems; + return trace(language, new PDictItemsView(cls, cls.getInstanceShape(language), dict)); + } + + public static POrderedDictIterator createOrderedDictIterator(PythonLanguage language, POrderedDict dict, POrderedDictIterator.IteratorType type, boolean reversed) { + PythonBuiltinClassType cls = PythonBuiltinClassType.POrderedDictIterator; + return trace(language, new POrderedDictIterator(cls, cls.getInstanceShape(language), dict, type, reversed)); + } + + public static PDict createDictFromMap(PythonLanguage language, LinkedHashMap map) { + return createDict(language, EconomicMapStorage.create(map)); + } + + /** + * Generic version of {@link #createDictFromMap(PythonLanguage, LinkedHashMap)} that allows any + * type of keys. Note that this means that unless the keys are known to be side effect free, + * e.g., builtin types, this may end up calling Python code, so indirect call context should be + * properly set-up. This helper is meant for Truffle boundary code, in PE code build a storage + * by setting elements one by one starting from empty storage. + */ + public static PDict createDictFromMapGeneric(PythonLanguage language, LinkedHashMap map) { + return createDict(language, EconomicMapStorage.createGeneric(map)); + } + + public static PDict createDictFixedStorage(PythonLanguage language, PythonObject pythonObject, MroSequenceStorage mroSequenceStorage) { + return createDict(language, new DynamicObjectStorage(pythonObject, mroSequenceStorage)); + } + + public static PDict createDictFixedStorage(PythonLanguage language, PythonObject pythonObject) { + return createDict(language, new DynamicObjectStorage(pythonObject)); + } + + public static PSimpleNamespace createSimpleNamespace(PythonLanguage language) { + return createSimpleNamespace(language, PythonBuiltinClassType.PSimpleNamespace, PythonBuiltinClassType.PSimpleNamespace.getInstanceShape(language)); + } + + public static PSimpleNamespace createSimpleNamespace(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PSimpleNamespace(cls, shape)); + } + + public static PKeyWrapper createKeyWrapper(PythonLanguage language, Object cmp) { + return trace(language, new PKeyWrapper(PythonBuiltinClassType.PKeyWrapper, PythonBuiltinClassType.PKeyWrapper.getInstanceShape(language), cmp)); + } + + public static PPartial createPartial(PythonLanguage language, Object cls, Shape shape, Object function, Object[] args, PDict kwDict) { + return trace(language, new PPartial(cls, shape, function, args, kwDict)); + } + + public static LruCacheObject createLruCacheObject(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new LruCacheObject(cls, shape)); + } + + public static PDefaultDict createDefaultDict(PythonLanguage language, Object cls, Shape shape) { + return createDefaultDict(language, cls, shape, PNone.NONE); + } + + public static PDefaultDict createDefaultDict(PythonLanguage language, Object cls, Shape shape, Object defaultFactory) { + return trace(language, new PDefaultDict(cls, shape, defaultFactory)); + } + + public static PDefaultDict createDefaultDict(PythonLanguage language, Object defaultFactory, HashingStorage storage) { + return createDefaultDict(language, PythonBuiltinClassType.PDefaultDict, PythonBuiltinClassType.PDefaultDict.getInstanceShape(language), defaultFactory, storage); + } + + public static PDefaultDict createDefaultDict(PythonLanguage language, Object cls, Shape shape, Object defaultFactory, HashingStorage storage) { + return trace(language, new PDefaultDict(cls, shape, storage, defaultFactory)); + } + + public static PDictView createDictKeysView(PythonLanguage language, PHashingCollection dict) { + return trace(language, new PDictKeysView(PythonBuiltinClassType.PDictKeysView, PythonBuiltinClassType.PDictKeysView.getInstanceShape(language), dict)); + } + + public static PDictView createDictKeysView(PythonLanguage language, Object dict, ForeignHashingStorage foreignHashingStorage) { + return trace(language, new PDictKeysView(PythonBuiltinClassType.PDictKeysView, PythonBuiltinClassType.PDictKeysView.getInstanceShape(language), dict, foreignHashingStorage)); + } + + public static PDictView createDictValuesView(PythonLanguage language, PHashingCollection dict) { + return trace(language, new PDictValuesView(PythonBuiltinClassType.PDictValuesView, PythonBuiltinClassType.PDictValuesView.getInstanceShape(language), dict)); + } + + public static PDictView createDictValuesView(PythonLanguage language, Object dict, ForeignHashingStorage foreignHashingStorage) { + return trace(language, new PDictValuesView(PythonBuiltinClassType.PDictValuesView, PythonBuiltinClassType.PDictValuesView.getInstanceShape(language), dict, foreignHashingStorage)); + } + + public static PDictView createDictItemsView(PythonLanguage language, PHashingCollection dict) { + return trace(language, new PDictItemsView(PythonBuiltinClassType.PDictItemsView, PythonBuiltinClassType.PDictItemsView.getInstanceShape(language), dict)); + } + + public static PDictView createDictItemsView(PythonLanguage language, Object dict, ForeignHashingStorage foreignHashingStorage) { + return trace(language, new PDictItemsView(PythonBuiltinClassType.PDictItemsView, PythonBuiltinClassType.PDictItemsView.getInstanceShape(language), dict, foreignHashingStorage)); + } + + /* + * Special objects: generators, proxies, references, cells + */ + + public static PGenerator createGenerator(PythonLanguage language, TruffleString name, TruffleString qualname, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, Object[] arguments) { + return trace(language, PGenerator.create(language, name, qualname, rootNode, callTargets, arguments, PythonBuiltinClassType.PGenerator)); + } + + public static PGenerator createGenerator(PythonLanguage language, TruffleString name, TruffleString qualname, PBytecodeDSLRootNode rootNode, Object[] arguments) { + return trace(language, PGenerator.create(language, name, qualname, rootNode, arguments, PythonBuiltinClassType.PGenerator)); + } + + public static PGenerator createIterableCoroutine(PythonLanguage language, TruffleString name, TruffleString qualname, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, + Object[] arguments) { + return trace(language, PGenerator.create(language, name, qualname, rootNode, callTargets, arguments, PythonBuiltinClassType.PGenerator, true)); + } + + public static PGenerator createIterableCoroutine(PythonLanguage language, TruffleString name, TruffleString qualname, PBytecodeDSLRootNode rootNode, + Object[] arguments) { + return trace(language, PGenerator.create(language, name, qualname, rootNode, arguments, PythonBuiltinClassType.PGenerator, true)); + } + + public static PGenerator createCoroutine(PythonLanguage language, TruffleString name, TruffleString qualname, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, Object[] arguments) { + return trace(language, PGenerator.create(language, name, qualname, rootNode, callTargets, arguments, PythonBuiltinClassType.PCoroutine)); + } + + public static PGenerator createCoroutine(PythonLanguage language, TruffleString name, TruffleString qualname, PBytecodeDSLRootNode rootNode, Object[] arguments) { + return trace(language, PGenerator.create(language, name, qualname, rootNode, arguments, PythonBuiltinClassType.PCoroutine)); + } + + public static PCoroutineWrapper createCoroutineWrapper(PythonLanguage language, PGenerator generator) { + return trace(language, new PCoroutineWrapper(language, generator)); + } + + public static PAsyncGen createAsyncGenerator(PythonLanguage language, TruffleString name, TruffleString qualname, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, Object[] arguments) { + return trace(language, PAsyncGen.create(language, name, qualname, rootNode, callTargets, arguments)); + } + + public static PANextAwaitable createANextAwaitable(PythonLanguage language, Object wrapped, Object defaultValue) { + return trace(language, new PANextAwaitable(PythonBuiltinClassType.PAnextAwaitable, PythonBuiltinClassType.PAnextAwaitable.getInstanceShape(language), wrapped, defaultValue)); + } + + public static PMappingproxy createMappingproxy(PythonLanguage language, Object object) { + return createMappingproxy(language, PythonBuiltinClassType.PMappingproxy, PythonBuiltinClassType.PMappingproxy.getInstanceShape(language), object); + } + + public static PMappingproxy createMappingproxy(PythonLanguage language, Object cls, Shape shape, Object object) { + return trace(language, new PMappingproxy(cls, shape, object)); + } + + public static PReferenceType createReferenceType(PythonLanguage language, Object cls, Shape shape, Object object, Object callback, ReferenceQueue queue) { + return trace(language, new PReferenceType(cls, shape, object, callback, queue)); + } + + public static PCell createCell(PythonLanguage language, Assumption effectivelyFinal) { + return trace(language, new PCell(effectivelyFinal)); + } + + /* + * Frames, traces and exceptions + */ + + public static PFrame createPFrame(PythonLanguage language, PFrame.Reference frameInfo, Node location, MaterializedFrame locals) { + return trace(language, new PFrame(language, frameInfo, location, locals)); + } + + public static PFrame createPFrame(PythonLanguage language, Object threadState, PCode code, PythonObject globals, Object localsDict) { + return trace(language, new PFrame(language, threadState, code, globals, localsDict)); + } + + public static PTraceback createTraceback(PythonLanguage language, PFrame frame, int lineno, PTraceback next) { + return trace(language, new PTraceback(language, frame, lineno, -1, next)); + } + + public static PTraceback createTracebackWithLasti(PythonLanguage language, PFrame frame, int lineno, int lasti, PTraceback next) { + return trace(language, new PTraceback(language, frame, lineno, lasti, next)); + } + + public static PTraceback createTraceback(PythonLanguage language, LazyTraceback tb) { + return trace(language, new PTraceback(language, tb)); + } + + public static PBaseException createBaseException(PythonLanguage language, Object cls, Shape shape, PTuple args) { + return createBaseException(language, cls, shape, null, args); + } + + public static PBaseException createBaseException(PythonLanguage language, PythonBuiltinClassType cls, PTuple args) { + return createBaseException(language, cls, cls.getInstanceShape(language), null, args); + } + + public static PBaseException createBaseException(PythonLanguage language, PythonBuiltinClassType type, Object[] data, PTuple args) { + return createBaseException(language, type, type.getInstanceShape(language), data, args); + } + + public static PBaseException createBaseException(PythonLanguage language, Object cls, Shape shape, Object[] data, PTuple args) { + return trace(language, new PBaseException(cls, shape, data, args)); + } + + /* + * Note: we use this method to convert a Java StackOverflowError into a Python RecursionError. + * At the time when this is done, some Java stack frames were already unwinded but there is no + * guarantee on how many. Therefore, it is important that this method is simple. In particular, + * do not add calls if that can be avoided. + */ + public static PBaseException createBaseException(PythonLanguage language, Object cls, Shape shape, TruffleString format, Object[] formatArgs) { + return createBaseException(language, cls, shape, null, format, formatArgs); + } + + public static PBaseException createBaseException(PythonLanguage language, PythonBuiltinClassType type, TruffleString format, Object[] formatArgs) { + return createBaseException(language, type, type.getInstanceShape(language), null, format, formatArgs); + } + + public static PBaseException createBaseException(PythonLanguage language, PythonBuiltinClassType type, Object[] data, TruffleString format, Object[] formatArgs) { + return createBaseException(language, type, type.getInstanceShape(language), data, format, formatArgs); + } + + public static PBaseException createBaseException(PythonLanguage language, Object cls, Shape shape, Object[] data, TruffleString format, Object[] formatArgs) { + assert format != null; + return trace(language, new PBaseException(cls, shape, data, format, formatArgs)); + } + + public static PBaseException createBaseException(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PBaseException(cls, shape, null)); + } + + public static PBaseException createBaseException(PythonLanguage language, PythonBuiltinClassType type) { + return trace(language, new PBaseException(type, type.getInstanceShape(language), null)); + } + + public static PBaseException createBaseException(PythonLanguage language, PythonBuiltinClassType type, TruffleString format) { + return trace(language, new PBaseException(type, type.getInstanceShape(language), null, format, EMPTY_OBJECT_ARRAY)); + } + + public static PBaseExceptionGroup createBaseExceptionGroup(PythonLanguage language, Object cls, Shape shape, TruffleString message, Object[] exceptions, Object[] args) { + return trace(language, new PBaseExceptionGroup(cls, shape, message, exceptions, createTuple(language, args))); + } + + /* + * Arrays + */ + + public static PArray createArray(PythonLanguage language, Object cls, Shape shape, TruffleString formatString, BufferFormat format) { + assert format != null; + return trace(language, new PArray(cls, shape, formatString, format)); + } + + public static PArray createArray(PythonLanguage language, TruffleString formatString, BufferFormat format, int length) throws OverflowException { + return createArray(language, PythonBuiltinClassType.PArray, PythonBuiltinClassType.PArray.getInstanceShape(language), formatString, format, length); + } + + public static PArray createArray(PythonLanguage language, Object cls, Shape shape, TruffleString formatString, BufferFormat format, int length) throws OverflowException { + assert format != null; + int byteSize = PythonUtils.multiplyExact(length, format.bytesize); + return trace(language, new PArray(cls, shape, formatString, format, byteSize)); + } + + public static PByteArray createByteArray(PythonLanguage language, byte[] array) { + return createByteArray(language, array, array.length); + } + + public static PByteArray createByteArray(PythonLanguage language, Object cls, Shape shape, byte[] array) { + return createByteArray(language, cls, shape, array, array.length); + } + + public static PByteArray createByteArray(PythonLanguage language, byte[] array, int length) { + return createByteArray(language, new ByteSequenceStorage(array, length)); + } + + public static PByteArray createByteArray(PythonLanguage language, Object cls, Shape shape, byte[] array, int length) { + return createByteArray(language, cls, shape, new ByteSequenceStorage(array, length)); + } + + public static PByteArray createByteArray(PythonLanguage language, SequenceStorage storage) { + return createByteArray(language, PythonBuiltinClassType.PByteArray, PythonBuiltinClassType.PByteArray.getInstanceShape(language), storage); + } + + public static PByteArray createByteArray(PythonLanguage language, Object cls, Shape shape, SequenceStorage storage) { + return trace(language, new PByteArray(cls, shape, storage)); + } + + /* + * Iterators + */ + + public static PStringIterator createStringIterator(PythonLanguage language, TruffleString str) { + return trace(language, new PStringIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(language), str)); + } + + public static PStringReverseIterator createStringReverseIterator(PythonLanguage language, Object cls, Shape shape, TruffleString str) { + return trace(language, new PStringReverseIterator(cls, shape, str)); + } + + public static PIntegerSequenceIterator createIntegerSequenceIterator(PythonLanguage language, IntSequenceStorage storage, Object list) { + return trace(language, new PIntegerSequenceIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(language), storage, list)); + } + + public static PLongSequenceIterator createLongSequenceIterator(PythonLanguage language, LongSequenceStorage storage, Object list) { + return trace(language, new PLongSequenceIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(language), storage, list)); + } + + public static PDoubleSequenceIterator createDoubleSequenceIterator(PythonLanguage language, DoubleSequenceStorage storage, Object list) { + return trace(language, new PDoubleSequenceIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(language), storage, list)); + } + + public static PObjectSequenceIterator createObjectSequenceIterator(PythonLanguage language, ObjectSequenceStorage storage, Object list) { + return trace(language, new PObjectSequenceIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(language), storage, list)); + } + + public static PSequenceIterator createSequenceIterator(PythonLanguage language, Object sequence) { + return trace(language, new PSequenceIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(language), sequence)); + } + + public static PSequenceReverseIterator createSequenceReverseIterator(PythonLanguage language, Object sequence, int lengthHint) { + return createSequenceReverseIterator(language, PythonBuiltinClassType.PReverseIterator, PythonBuiltinClassType.PReverseIterator.getInstanceShape(language), sequence, lengthHint); + } + + public static PSequenceReverseIterator createSequenceReverseIterator(PythonLanguage language, Object cls, Shape shape, Object sequence, int lengthHint) { + return trace(language, new PSequenceReverseIterator(cls, shape, sequence, lengthHint)); + } + + public static PIntRangeIterator createIntRangeIterator(PythonLanguage language, PIntRange fastRange) { + return createIntRangeIterator(language, fastRange.getIntStart(), fastRange.getIntStop(), fastRange.getIntStep(), fastRange.getIntLength()); + } + + public static PIntRangeIterator createIntRangeIterator(PythonLanguage language, int start, int stop, int step, int len) { + return trace(language, new PIntRangeIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(language), start, stop, step, len)); + } + + public static PBigRangeIterator createBigRangeIterator(PythonLanguage language, PInt start, PInt stop, PInt step, PInt len) { + return trace(language, new PBigRangeIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(language), start, stop, step, len)); + } + + public static PBigRangeIterator createBigRangeIterator(PythonLanguage language, PBigRange longRange) { + return createBigRangeIterator(language, longRange.getPIntStart(), longRange.getPIntStop(), longRange.getPIntStep(), longRange.getPIntLength()); + } + + public static PBigRangeIterator createBigRangeIterator(PythonLanguage language, BigInteger start, BigInteger stop, BigInteger step, BigInteger len) { + return createBigRangeIterator(language, createInt(language, start), createInt(language, stop), createInt(language, step), createInt(language, len)); + } + + public static PArrayIterator createArrayIterator(PythonLanguage language, PArray array) { + return trace(language, new PArrayIterator(PythonBuiltinClassType.PArrayIterator, PythonBuiltinClassType.PArrayIterator.getInstanceShape(language), array)); + } + + public static PBaseSetIterator createBaseSetIterator(PythonLanguage language, PBaseSet set, HashingStorageNodes.HashingStorageIterator iterator, int initialSize) { + return trace(language, new PBaseSetIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(language), set, iterator, initialSize)); + } + + public static PDictItemIterator createDictItemIterator(PythonLanguage language, HashingStorageNodes.HashingStorageIterator iterator, HashingStorage hashingStorage, int initialSize) { + return trace(language, new PDictItemIterator(PythonBuiltinClassType.PDictItemIterator, PythonBuiltinClassType.PDictItemIterator.getInstanceShape(language), iterator, hashingStorage, + initialSize)); + } + + public static PDictKeyIterator createDictKeyIterator(PythonLanguage language, HashingStorageNodes.HashingStorageIterator iterator, HashingStorage hashingStorage, int initialSize) { + return trace(language, + new PDictKeyIterator(PythonBuiltinClassType.PDictKeyIterator, PythonBuiltinClassType.PDictKeyIterator.getInstanceShape(language), iterator, hashingStorage, initialSize)); + } + + public static PDictValueIterator createDictValueIterator(PythonLanguage language, HashingStorageNodes.HashingStorageIterator iterator, HashingStorage hashingStorage, int initialSize) { + return trace(language, new PDictValueIterator(PythonBuiltinClassType.PDictValueIterator, PythonBuiltinClassType.PDictValueIterator.getInstanceShape(language), iterator, hashingStorage, + initialSize)); + } + + public static Object createSentinelIterator(PythonLanguage language, Object callable, Object sentinel) { + return trace(language, new PSentinelIterator(PythonBuiltinClassType.PSentinelIterator, PythonBuiltinClassType.PSentinelIterator.getInstanceShape(language), callable, sentinel)); + } + + public static PEnumerate createEnumerate(PythonLanguage language, Object cls, Shape shape, Object iterator, long start) { + return trace(language, new PEnumerate(cls, shape, iterator, start)); + } + + public static PEnumerate createEnumerate(PythonLanguage language, Object cls, Shape shape, Object iterator, PInt start) { + return trace(language, new PEnumerate(cls, shape, iterator, start)); + } + + public static PMap createMap(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PMap(cls, shape)); + } + + public static PZip createZip(PythonLanguage language, Object cls, Shape shape, Object[] iterables, boolean strict) { + return trace(language, new PZip(cls, shape, iterables, strict)); + } + + public static PCode createCode(PythonLanguage language, RootCallTarget ct) { + return trace(language, new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), ct)); + } + + public static PCode createCode(PythonLanguage language, RootCallTarget ct, int flags, int firstlineno, byte[] linetable, TruffleString filename) { + return trace(language, new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), ct, flags, firstlineno, linetable, filename)); + } + + public static PCode createCode(PythonLanguage language, RootCallTarget callTarget, Signature signature, BytecodeCodeUnit codeUnit) { + return trace(language, new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), callTarget, signature, codeUnit)); + } + + public static PCode createCode(PythonLanguage language, RootCallTarget callTarget, Signature signature, BytecodeDSLCodeUnit codeUnit) { + return trace(language, new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), callTarget, signature, codeUnit)); + } + + public static PCode createCode(PythonLanguage language, RootCallTarget callTarget, Signature signature, int nlocals, + int stacksize, int flags, Object[] constants, + TruffleString[] names, TruffleString[] varnames, + TruffleString[] freevars, TruffleString[] cellvars, + TruffleString filename, TruffleString name, TruffleString qualname, + int firstlineno, byte[] linetable) { + return trace(language, new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), callTarget, signature, + nlocals, stacksize, flags, constants, names, varnames, freevars, cellvars, + filename, name, qualname, firstlineno, linetable)); + } + + /* + * Socket + */ + + public static PSocket createSocket(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PSocket(cls, shape)); + } + + /* + * Threading + */ + + public static PThreadLocal createThreadLocal(PythonLanguage language, Object cls, Shape shape, Object[] args, PKeyword[] kwArgs) { + return trace(language, new PThreadLocal(cls, shape, args, kwArgs)); + } + + public static PLock createLock(PythonLanguage language) { + return createLock(language, PythonBuiltinClassType.PLock, PythonBuiltinClassType.PLock.getInstanceShape(language)); + } + + public static PLock createLock(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PLock(cls, shape)); + } + + public static PRLock createRLock(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PRLock(cls, shape)); + } + + public static PSemLock createSemLock(PythonLanguage language, Object cls, Shape shape, long handle, int kind, int maxValue, TruffleString name) { + return trace(language, new PSemLock(cls, shape, handle, kind, maxValue, name)); + } + + public static PGraalPySemLock createGraalPySemLock(PythonLanguage language, TruffleString name, int kind, Semaphore sharedSemaphore) { + return createGraalPySemLock(language, PythonBuiltinClassType.PGraalPySemLock, PythonBuiltinClassType.PGraalPySemLock.getInstanceShape(language), name, kind, sharedSemaphore); + } + + public static PGraalPySemLock createGraalPySemLock(PythonLanguage language, Object cls, Shape shape, TruffleString name, int kind, Semaphore sharedSemaphore) { + return trace(language, new PGraalPySemLock(cls, shape, name, kind, sharedSemaphore)); + } + + public static PScandirIterator createScandirIterator(PythonLanguage language, PythonContext context, Object dirStream, PosixFileHandle path, boolean needsRewind) { + return trace(language, + new PScandirIterator(PythonBuiltinClassType.PScandirIterator, PythonBuiltinClassType.PScandirIterator.getInstanceShape(language), context, dirStream, path, needsRewind)); + } + + public static PDirEntry createDirEntry(PythonLanguage language, Object dirEntryData, PosixFileHandle path) { + return trace(language, new PDirEntry(PythonBuiltinClassType.PDirEntry, PythonBuiltinClassType.PDirEntry.getInstanceShape(language), dirEntryData, path)); + } + + public static PEncodingMap createEncodingMap(PythonLanguage language, int count2, int count3, byte[] level1, byte[] level23) { + return trace(language, new PEncodingMap(PythonBuiltinClassType.PEncodingMap, PythonBuiltinClassType.PEncodingMap.getInstanceShape(language), count2, count3, level1, level23)); + } + + public static PMMap createMMap(PythonLanguage language, PythonContext context, Object cls, Shape shape, Object mmapHandle, int fd, long length, int access) { + return trace(language, new PMMap(cls, shape, context, mmapHandle, fd, length, access)); + } + + public static BZ2Object.BZ2Compressor createBZ2Compressor(PythonLanguage language) { + return createBZ2Compressor(language, PythonBuiltinClassType.BZ2Compressor, PythonBuiltinClassType.BZ2Compressor.getInstanceShape(language)); + } + + public static BZ2Object.BZ2Compressor createBZ2Compressor(PythonLanguage language, Object cls, Shape shape) { + return trace(language, BZ2Object.createCompressor(cls, shape)); + } + + public static BZ2Object.BZ2Decompressor createBZ2Decompressor(PythonLanguage language) { + return createBZ2Decompressor(language, PythonBuiltinClassType.BZ2Decompressor, PythonBuiltinClassType.BZ2Decompressor.getInstanceShape(language)); + } + + public static BZ2Object.BZ2Decompressor createBZ2Decompressor(PythonLanguage language, Object cls, Shape shape) { + return trace(language, BZ2Object.createDecompressor(cls, shape)); + } + + public static ZLibCompObject createJavaZLibCompObjectCompress(PythonLanguage language, Object stream, int level, int wbits, int strategy, byte[] zdict) { + return createJavaZLibCompObject(language, PythonBuiltinClassType.ZlibCompress, PythonBuiltinClassType.ZlibCompress.getInstanceShape(language), stream, level, wbits, strategy, zdict); + } + + public static ZLibCompObject createJavaZLibCompObject(PythonLanguage language, Object cls, Shape shape, Object stream, int level, int wbits, int strategy, byte[] zdict) { + return trace(language, ZLibCompObject.createJava(cls, shape, stream, level, wbits, strategy, zdict)); + } + + public static ZLibCompObject createJavaZLibCompObjectDecompress(PythonLanguage language, Object stream, int wbits, byte[] zdict) { + return createJavaZLibCompObject(language, PythonBuiltinClassType.ZlibDecompress, PythonBuiltinClassType.ZlibDecompress.getInstanceShape(language), stream, wbits, zdict); + } + + public static ZLibCompObject createJavaZLibCompObject(PythonLanguage language, Object cls, Shape shape, Object stream, int wbits, byte[] zdict) { + return trace(language, ZLibCompObject.createJava(cls, shape, stream, wbits, zdict)); + } + + public static ZLibCompObject createNativeZLibCompObjectCompress(PythonLanguage language, Object zst, NFIZlibSupport zlibSupport) { + return createNativeZLibCompObject(language, PythonBuiltinClassType.ZlibCompress, PythonBuiltinClassType.ZlibCompress.getInstanceShape(language), zst, zlibSupport); + } + + public static ZLibCompObject createNativeZLibCompObjectDecompress(PythonLanguage language, Object zst, NFIZlibSupport zlibSupport) { + return createNativeZLibCompObject(language, PythonBuiltinClassType.ZlibDecompress, PythonBuiltinClassType.ZlibDecompress.getInstanceShape(language), zst, zlibSupport); + } + + public static ZLibCompObject createNativeZLibCompObject(PythonLanguage language, Object cls, Shape shape, Object zst, NFIZlibSupport zlibSupport) { + return trace(language, ZLibCompObject.createNative(cls, shape, zst, zlibSupport)); + } + + public static LZMAObject.LZMADecompressor createLZMADecompressor(PythonLanguage language, Object cls, Shape shape, boolean isNative) { + return trace(language, LZMAObject.createDecompressor(cls, shape, isNative)); + } + + public static LZMAObject.LZMACompressor createLZMACompressor(PythonLanguage language, Object cls, Shape shape, boolean isNative) { + return trace(language, LZMAObject.createCompressor(cls, shape, isNative)); + } + + public static CSVReader createCSVReader(PythonLanguage language, Object inputIter, CSVDialect dialect) { + return createCSVReader(language, PythonBuiltinClassType.CSVReader, PythonBuiltinClassType.CSVReader.getInstanceShape(language), inputIter, dialect); + } + + public static CSVReader createCSVReader(PythonLanguage language, Object cls, Shape shape, Object inputIter, CSVDialect dialect) { + return trace(language, new CSVReader(cls, shape, inputIter, dialect)); + } + + public static CSVWriter createCSVWriter(PythonLanguage language, Object write, CSVDialect dialect) { + return createCSVWriter(language, PythonBuiltinClassType.CSVWriter, PythonBuiltinClassType.CSVWriter.getInstanceShape(language), write, dialect); + } + + public static CSVWriter createCSVWriter(PythonLanguage language, Object cls, Shape shape, Object write, CSVDialect dialect) { + return trace(language, new CSVWriter(cls, shape, write, dialect)); + } + + public static CSVDialect createCSVDialect(PythonLanguage language, Object cls, Shape shape, TruffleString delimiter, int delimiterCodePoint, boolean doubleQuote, TruffleString escapeChar, + int escapeCharCodePoint, + TruffleString lineTerminator, TruffleString quoteChar, int quoteCharCodePoint, QuoteStyle quoting, boolean skipInitialSpace, boolean strict) { + return trace(language, new CSVDialect(cls, shape, delimiter, delimiterCodePoint, doubleQuote, escapeChar, escapeCharCodePoint, lineTerminator, quoteChar, quoteCharCodePoint, quoting, + skipInitialSpace, strict)); + } + + public static PFileIO createFileIO(PythonLanguage language) { + return createFileIO(language, PythonBuiltinClassType.PFileIO, PythonBuiltinClassType.PFileIO.getInstanceShape(language)); + } + + public static PFileIO createFileIO(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PFileIO(cls, shape)); + } + + public static PChain createChain(PythonLanguage language) { + return createChain(language, PythonBuiltinClassType.PChain, PythonBuiltinClassType.PChain.getInstanceShape(language)); + } + + public static PChain createChain(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PChain(cls, shape)); + } + + public static PCount createCount(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PCount(cls, shape)); + } + + public static PIslice createIslice(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PIslice(cls, shape)); + } + + public static PPairwise createPairwise(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PPairwise(cls, shape)); + } + + public static PPermutations createPermutations(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PPermutations(cls, shape)); + } + + public static PProduct createProduct(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PProduct(cls, shape)); + } + + public static PRepeat createRepeat(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PRepeat(cls, shape)); + } + + public static PAccumulate createAccumulate(PythonLanguage language) { + return createAccumulate(language, PythonBuiltinClassType.PAccumulate, PythonBuiltinClassType.PAccumulate.getInstanceShape(language)); + } + + public static PAccumulate createAccumulate(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PAccumulate(cls, shape)); + } + + public static PDropwhile createDropwhile(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PDropwhile(cls, shape)); + } + + public static PCombinations createCombinations(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PCombinations(cls, shape)); + } + + public static PCombinationsWithReplacement createCombinationsWithReplacement(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PCombinationsWithReplacement(cls, shape)); + } + + public static PCompress createCompress(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PCompress(cls, shape)); + } + + public static PCycle createCycle(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PCycle(cls, shape)); + } + + public static PFilterfalse createFilterfalse(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PFilterfalse(cls, shape)); + } + + public static PGroupBy createGroupBy(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PGroupBy(cls, shape)); + } + + public static PGrouper createGrouper(PythonLanguage language, PGroupBy parent, Object tgtKey) { + return trace(language, new PGrouper(parent, tgtKey, PythonBuiltinClassType.PGrouper, PythonBuiltinClassType.PGrouper.getInstanceShape(language))); + } + + public static PTee createTee(PythonLanguage language, PTeeDataObject dataObj, int index) { + return trace(language, new PTee(dataObj, index, PythonBuiltinClassType.PTee, PythonBuiltinClassType.PTee.getInstanceShape(language))); + } + + public static PStarmap createStarmap(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PStarmap(cls, shape)); + } + + public static PTakewhile createTakewhile(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PTakewhile(cls, shape)); + } + + public static PTeeDataObject createTeeDataObject(PythonLanguage language) { + return trace(language, new PTeeDataObject(PythonBuiltinClassType.PTeeDataObject, PythonBuiltinClassType.PTeeDataObject.getInstanceShape(language))); + } + + public static PTeeDataObject createTeeDataObject(PythonLanguage language, Object it) { + return trace(language, new PTeeDataObject(it, PythonBuiltinClassType.PTeeDataObject, PythonBuiltinClassType.PTeeDataObject.getInstanceShape(language))); + } + + public static PZipLongest createZipLongest(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PZipLongest(cls, shape)); + } + + public static PTextIO createTextIO(PythonLanguage language) { + return createTextIO(language, PythonBuiltinClassType.PTextIOWrapper, PythonBuiltinClassType.PTextIOWrapper.getInstanceShape(language)); + } + + public static PTextIO createTextIO(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PTextIO(cls, shape)); + } + + public static PStringIO createStringIO(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PStringIO(cls, shape)); + } + + public static PBytesIO createBytesIO(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PBytesIO(cls, shape)); + } + + public static PBytesIOBuffer createBytesIOBuf(PythonLanguage language, PBytesIO source) { + return createBytesIOBuf(language, PythonBuiltinClassType.PBytesIOBuf, PythonBuiltinClassType.PBytesIOBuf.getInstanceShape(language), source); + } + + public static PBytesIOBuffer createBytesIOBuf(PythonLanguage language, Object cls, Shape shape, PBytesIO source) { + return trace(language, new PBytesIOBuffer(cls, shape, source)); + } + + public static PNLDecoder createNLDecoder(PythonLanguage language) { + return createNLDecoder(language, PythonBuiltinClassType.PIncrementalNewlineDecoder, PythonBuiltinClassType.PIncrementalNewlineDecoder.getInstanceShape(language)); + } + + public static PNLDecoder createNLDecoder(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PNLDecoder(cls, shape)); + } + + public static PBuffered createBufferedReader(PythonLanguage language) { + return createBufferedReader(language, PythonBuiltinClassType.PBufferedReader, PythonBuiltinClassType.PBufferedReader.getInstanceShape(language)); + } + + public static PBuffered createBufferedReader(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PBuffered(cls, shape, true, false)); + } + + public static PBuffered createBufferedWriter(PythonLanguage language) { + return createBufferedWriter(language, PythonBuiltinClassType.PBufferedWriter, PythonBuiltinClassType.PBufferedWriter.getInstanceShape(language)); + } + + public static PBuffered createBufferedWriter(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PBuffered(cls, shape, false, true)); + } + + public static PBuffered createBufferedRandom(PythonLanguage language) { + return createBufferedRandom(language, PythonBuiltinClassType.PBufferedRandom, PythonBuiltinClassType.PBufferedRandom.getInstanceShape(language)); + } + + public static PBuffered createBufferedRandom(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PBuffered(cls, shape, true, true)); + } + + public static PRWPair createRWPair(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PRWPair(cls, shape)); + } + + public static PyCArgObject createCArgObject(PythonLanguage language) { + return trace(language, new PyCArgObject(PythonBuiltinClassType.CArgObject, PythonBuiltinClassType.CArgObject.getInstanceShape(language))); + } + + public static CThunkObject createCThunkObject(PythonLanguage language, int nArgs) { + return createCThunkObject(language, PythonBuiltinClassType.CThunkObject, PythonBuiltinClassType.CThunkObject.getInstanceShape(language), nArgs); + } + + public static CThunkObject createCThunkObject(PythonLanguage language, Object cls, Shape shape, int nArgs) { + return trace(language, new CThunkObject(cls, shape, nArgs)); + } + + // Don't use directly, use CtypesNodes.CreateCDataObjectNode + public static CDataObject createCDataObject(PythonLanguage language, Object cls, Shape shape, Pointer b_ptr, int b_size, boolean b_needsfree) { + return trace(language, new CDataObject(cls, shape, b_ptr, b_size, b_needsfree)); + } + + // Don't use directly, use CtypesNodes.CreateCDataObjectNode + public static PyCFuncPtrObject createPyCFuncPtrObject(PythonLanguage language, Object cls, Shape shape, Pointer b_ptr, int b_size, boolean b_needsfree) { + return trace(language, new PyCFuncPtrObject(cls, shape, b_ptr, b_size, b_needsfree)); + } + + public static CFieldObject createCFieldObject(PythonLanguage language) { + return createCFieldObject(language, PythonBuiltinClassType.CField, PythonBuiltinClassType.CField.getInstanceShape(language)); + } + + public static CFieldObject createCFieldObject(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new CFieldObject(cls, shape)); + } + + public static StgDictObject createStgDictObject(PythonLanguage language) { + return createStgDictObject(language, PythonBuiltinClassType.StgDict, PythonBuiltinClassType.StgDict.getInstanceShape(language)); + } + + public static StgDictObject createStgDictObject(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new StgDictObject(cls, shape)); + } + + public static PSSLContext createSSLContext(PythonLanguage language, Object cls, Shape shape, SSLMethod method, int verifyFlags, boolean checkHostname, int verifyMode, SSLContext context) { + return trace(language, new PSSLContext(cls, shape, method, verifyFlags, checkHostname, verifyMode, context)); + } + + public static PSSLSocket createSSLSocket(PythonLanguage language, PSSLContext context, SSLEngine engine, PSocket socket) { + return createSSLSocket(language, PythonBuiltinClassType.PSSLSocket, PythonBuiltinClassType.PSSLSocket.getInstanceShape(language), context, engine, socket); + } + + public static PSSLSocket createSSLSocket(PythonLanguage language, Object cls, Shape shape, PSSLContext context, SSLEngine engine, PSocket socket) { + return trace(language, new PSSLSocket(cls, shape, context, engine, socket, createMemoryBIO(language), createMemoryBIO(language), createMemoryBIO(language))); + } + + public static PSSLSocket createSSLSocket(PythonLanguage language, PSSLContext context, SSLEngine engine, PMemoryBIO inbound, PMemoryBIO outbound) { + return createSSLSocket(language, PythonBuiltinClassType.PSSLSocket, PythonBuiltinClassType.PSSLSocket.getInstanceShape(language), context, engine, inbound, outbound); + } + + public static PSSLSocket createSSLSocket(PythonLanguage language, Object cls, Shape shape, PSSLContext context, SSLEngine engine, PMemoryBIO inbound, PMemoryBIO outbound) { + return trace(language, new PSSLSocket(cls, shape, context, engine, null, inbound, outbound, createMemoryBIO(language))); + } + + public static PMemoryBIO createMemoryBIO(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PMemoryBIO(cls, shape)); + } + + public static PMemoryBIO createMemoryBIO(PythonLanguage language) { + return trace(language, new PMemoryBIO(PythonBuiltinClassType.PMemoryBIO, PythonBuiltinClassType.PMemoryBIO.getInstanceShape(language))); + } + + public static PProperty createProperty(PythonLanguage language) { + return trace(language, new PProperty(PythonBuiltinClassType.PProperty, PythonBuiltinClassType.PProperty.getInstanceShape(language))); + } + + public static PProperty createProperty(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PProperty(cls, shape)); + } + + // JSON + // (not created on fast path, thus TruffleBoundary) + + @TruffleBoundary + public static PJSONScanner createJSONScanner(PythonLanguage language, Object cls, Shape shape, boolean strict, Object objectHook, Object objectPairsHook, Object parseFloat, Object parseInt, + Object parseConstant) { + return trace(language, new PJSONScanner(cls, shape, strict, objectHook, objectPairsHook, parseFloat, parseInt, parseConstant)); + } + + @TruffleBoundary + public static PJSONEncoder createJSONEncoder(PythonLanguage language, Object cls, Shape shape, Object markers, Object defaultFn, Object encoder, Object indent, TruffleString keySeparator, + TruffleString itemSeparator, + boolean sortKeys, boolean skipKeys, boolean allowNan, FastEncode fastEncode) { + return trace(language, new PJSONEncoder(cls, shape, markers, defaultFn, encoder, indent, keySeparator, itemSeparator, sortKeys, skipKeys, allowNan, fastEncode)); + } + + public static PDeque createDeque(PythonLanguage language) { + return trace(language, new PDeque(PythonBuiltinClassType.PDeque, PythonBuiltinClassType.PDeque.getInstanceShape(language))); + } + + public static PDeque createDeque(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PDeque(cls, shape)); + } + + public static PDequeIter createDequeIter(PythonLanguage language, PDeque deque) { + return trace(language, new PDequeIter(PythonBuiltinClassType.PDequeIter, PythonBuiltinClassType.PDequeIter.getInstanceShape(language), deque, false)); + } + + public static PDequeIter createDequeRevIter(PythonLanguage language, PDeque deque) { + return trace(language, new PDequeIter(PythonBuiltinClassType.PDequeRevIter, PythonBuiltinClassType.PDequeRevIter.getInstanceShape(language), deque, true)); + } + + public static PSimpleQueue createSimpleQueue(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PSimpleQueue(cls, shape)); + } + + public static PContextVar createContextVar(PythonLanguage language, TruffleString name, Object def) { + return trace(language, new PContextVar(PythonBuiltinClassType.ContextVar, PythonBuiltinClassType.ContextVar.getInstanceShape(language), name, def)); + } + + public static PContextVarsContext createContextVarsContext(PythonLanguage language) { + return trace(language, new PContextVarsContext(PythonBuiltinClassType.ContextVarsContext, PythonBuiltinClassType.ContextVarsContext.getInstanceShape(language))); + } + + public static PContextIterator createContextIterator(PythonLanguage language, PContextVarsContext ctx, PContextIterator.ItemKind kind) { + return trace(language, new PContextIterator(PythonBuiltinClassType.ContextIterator, PythonBuiltinClassType.ContextIterator.getInstanceShape(language), ctx, kind)); + } + + public static PContextVarsContext copyContextVarsContext(PythonLanguage language, PContextVarsContext original) { + return trace(language, new PContextVarsContext(original, PythonBuiltinClassType.ContextVarsContext, PythonBuiltinClassType.ContextVarsContext.getInstanceShape(language))); + } + + public static PContextVarsToken createContextVarsToken(PythonLanguage language, PContextVar var, Object oldValue) { + return trace(language, new PContextVarsToken(var, oldValue, PythonBuiltinClassType.ContextVarsToken, PythonBuiltinClassType.ContextVarsToken.getInstanceShape(language))); + } + + public static PGenericAlias createGenericAlias(PythonLanguage language, Object cls, Shape shape, Object origin, Object arguments, boolean starred) { + PTuple argumentsTuple; + if (arguments instanceof PTuple) { + argumentsTuple = (PTuple) arguments; + } else { + argumentsTuple = createTuple(language, new Object[]{arguments}); + } + return trace(language, new PGenericAlias(cls, shape, origin, argumentsTuple, starred)); + } + + public static PGenericAlias createGenericAlias(PythonLanguage language, Object origin, Object arguments, boolean starred) { + return createGenericAlias(language, PythonBuiltinClassType.PGenericAlias, PythonBuiltinClassType.PGenericAlias.getInstanceShape(language), origin, arguments, starred); + } + + public static PGenericAlias createGenericAlias(PythonLanguage language, Object origin, Object arguments) { + return createGenericAlias(language, origin, arguments, false); + } + + public static PGenericAliasIterator createGenericAliasIterator(PythonLanguage language, PGenericAlias object) { + return trace(language, new PGenericAliasIterator(PythonBuiltinClassType.PGenericAliasIterator, PythonBuiltinClassType.PGenericAliasIterator.getInstanceShape(language), object)); + } + + public static PUnionType createUnionType(PythonLanguage language, Object[] args) { + return trace(language, new PUnionType(PythonBuiltinClassType.PUnionType, PythonBuiltinClassType.PUnionType.getInstanceShape(language), createTuple(language, args))); + } + + public static DigestObject createDigestObject(PythonLanguage language, PythonBuiltinClassType type, String name, Object digest) { + return trace(language, DigestObject.create(type, type.getInstanceShape(language), name, digest)); + } + + public static PyCapsule createCapsuleNativeName(PythonLanguage language, Object pointer, Object name) { + return createCapsule(language, new PyCapsule.CapsuleData(pointer, name)); + } + + public static PyCapsule createCapsuleJavaName(PythonLanguage language, Object pointer, byte[] name) { + return createCapsule(language, new PyCapsule.CapsuleData(pointer, new CArrayWrappers.CByteArrayWrapper(name))); + } + + public static PyCapsule createCapsule(PythonLanguage language, PyCapsule.CapsuleData data) { + return trace(language, new PyCapsule(language, data)); + } + + public static MultibyteIncrementalDecoderObject createMultibyteIncrementalDecoderObject(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new MultibyteIncrementalDecoderObject(cls, shape)); + } + + public static MultibyteIncrementalEncoderObject createMultibyteIncrementalEncoderObject(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new MultibyteIncrementalEncoderObject(cls, shape)); + } + + public static MultibyteStreamReaderObject createMultibyteStreamReaderObject(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new MultibyteStreamReaderObject(cls, shape)); + } + + public static MultibyteStreamWriterObject createMultibyteStreamWriterObject(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new MultibyteStreamWriterObject(cls, shape)); + } + + public static MultibyteCodecObject createMultibyteCodecObject(PythonLanguage language, MultibyteCodec codec) { + return createMultibyteCodecObject(language, PythonBuiltinClassType.MultibyteCodec, PythonBuiltinClassType.MultibyteCodec.getInstanceShape(language), codec); + } + + public static MultibyteCodecObject createMultibyteCodecObject(PythonLanguage language, Object cls, Shape shape, MultibyteCodec codec) { + return trace(language, new MultibyteCodecObject(cls, shape, codec)); + } + + public static PAsyncGenASend createAsyncGeneratorASend(PythonLanguage language, PAsyncGen receiver, Object message) { + return trace(language, new PAsyncGenASend(language, receiver, message)); + } + + public static PAsyncGenAThrow createAsyncGeneratorAThrow(PythonLanguage language, PAsyncGen receiver, Object arg1, Object arg2, Object arg3) { + return trace(language, new PAsyncGenAThrow(language, receiver, arg1, arg2, arg3)); + } + + public static PAsyncGenWrappedValue createAsyncGeneratorWrappedValue(PythonLanguage language, Object wrapped) { + return trace(language, new PAsyncGenWrappedValue(language, wrapped)); + } + + // pickle + + public static PPickleBuffer createPickleBuffer(PythonLanguage language, Object view) { + return createPickleBuffer(language, view, PythonBuiltinClassType.PickleBuffer, PythonBuiltinClassType.PickleBuffer.getInstanceShape(language)); + } + + public static PPickleBuffer createPickleBuffer(PythonLanguage language, Object view, Object cls, Shape shape) { + return trace(language, new PPickleBuffer(cls, shape, view)); + } + + public static PPickler createPickler(PythonLanguage language) { + return createPickler(language, PythonBuiltinClassType.Pickler, PythonBuiltinClassType.Pickler.getInstanceShape(language)); + } + + public static PPickler createPickler(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PPickler(cls, shape)); + } + + public static PUnpickler createUnpickler(PythonLanguage language) { + return createUnpickler(language, PythonBuiltinClassType.Unpickler, PythonBuiltinClassType.Unpickler.getInstanceShape(language)); + } + + public static PUnpickler createUnpickler(PythonLanguage language, Object cls, Shape shape) { + return trace(language, new PUnpickler(cls, shape)); + } + + public static PPicklerMemoProxy createPicklerMemoProxy(PythonLanguage language, PPickler pickler) { + return createPicklerMemoProxy(language, pickler, PythonBuiltinClassType.PicklerMemoProxy, PythonBuiltinClassType.PicklerMemoProxy.getInstanceShape(language)); + } + + public static PPicklerMemoProxy createPicklerMemoProxy(PythonLanguage language, PPickler pickler, Object cls, Shape shape) { + return trace(language, new PPicklerMemoProxy(cls, shape, pickler)); + } + + public static PUnpicklerMemoProxy createUnpicklerMemoProxy(PythonLanguage language, PUnpickler unpickler) { + return createUnpicklerMemoProxy(language, unpickler, PythonBuiltinClassType.UnpicklerMemoProxy, PythonBuiltinClassType.UnpicklerMemoProxy.getInstanceShape(language)); + } + + public static PUnpicklerMemoProxy createUnpicklerMemoProxy(PythonLanguage language, PUnpickler unpickler, Object cls, Shape shape) { + return trace(language, new PUnpicklerMemoProxy(cls, shape, unpickler)); + } + + public static PStruct createStruct(PythonLanguage language, PStruct.StructInfo structInfo) { + return trace(language, new PStruct(PythonBuiltinClassType.PStruct, PythonBuiltinClassType.PStruct.getInstanceShape(language), structInfo)); + } + + public static PStructUnpackIterator createStructUnpackIterator(PythonLanguage language, PStruct struct, Object buffer) { + return trace(language, new PStructUnpackIterator(PythonBuiltinClassType.PStructUnpackIterator, PythonBuiltinClassType.PStructUnpackIterator.getInstanceShape(language), struct, buffer)); + } + + public static PTokenizerIter createTokenizerIter(PythonLanguage language, String sourceString) { + return createTokenizerIter(language, PythonBuiltinClassType.PTokenizerIter, PythonBuiltinClassType.PTokenizerIter.getInstanceShape(language), sourceString); + } + + public static PTokenizerIter createTokenizerIter(PythonLanguage language, Object cls, Shape shape, String sourceString) { + return trace(language, new PTokenizerIter(cls, shape, sourceString)); + } + + public static Profiler createProfiler(PythonLanguage language, Object cls, Shape shape, CPUSampler sampler) { + return trace(language, new Profiler(cls, shape, sampler)); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PythonObjectFactory.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PythonObjectFactory.java deleted file mode 100644 index ade6180bd8..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PythonObjectFactory.java +++ /dev/null @@ -1,1739 +0,0 @@ -/* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. - * Copyright (c) 2013, Regents of the University of California - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.oracle.graal.python.runtime.object; - -import java.lang.ref.ReferenceQueue; -import java.math.BigInteger; -import java.util.LinkedHashMap; -import java.util.concurrent.Semaphore; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLEngine; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.builtins.Python3Core; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.modules.PosixModuleBuiltins.PosixFileHandle; -import com.oracle.graal.python.builtins.modules.bz2.BZ2Object; -import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteCodec; -import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteCodecObject; -import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteIncrementalDecoderObject; -import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteIncrementalEncoderObject; -import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteStreamReaderObject; -import com.oracle.graal.python.builtins.modules.cjkcodecs.MultibyteStreamWriterObject; -import com.oracle.graal.python.builtins.modules.codecs.PEncodingMap; -import com.oracle.graal.python.builtins.modules.csv.CSVDialect; -import com.oracle.graal.python.builtins.modules.csv.CSVReader; -import com.oracle.graal.python.builtins.modules.csv.CSVWriter; -import com.oracle.graal.python.builtins.modules.csv.QuoteStyle; -import com.oracle.graal.python.builtins.modules.ctypes.CDataObject; -import com.oracle.graal.python.builtins.modules.ctypes.CFieldObject; -import com.oracle.graal.python.builtins.modules.ctypes.CThunkObject; -import com.oracle.graal.python.builtins.modules.ctypes.PyCArgObject; -import com.oracle.graal.python.builtins.modules.ctypes.PyCFuncPtrObject; -import com.oracle.graal.python.builtins.modules.ctypes.StgDictObject; -import com.oracle.graal.python.builtins.modules.ctypes.StructParamObject; -import com.oracle.graal.python.builtins.modules.ctypes.memory.Pointer; -import com.oracle.graal.python.builtins.modules.functools.LruCacheObject; -import com.oracle.graal.python.builtins.modules.functools.PKeyWrapper; -import com.oracle.graal.python.builtins.modules.functools.PPartial; -import com.oracle.graal.python.builtins.modules.hashlib.DigestObject; -import com.oracle.graal.python.builtins.modules.io.PBuffered; -import com.oracle.graal.python.builtins.modules.io.PBytesIO; -import com.oracle.graal.python.builtins.modules.io.PBytesIOBuffer; -import com.oracle.graal.python.builtins.modules.io.PFileIO; -import com.oracle.graal.python.builtins.modules.io.PNLDecoder; -import com.oracle.graal.python.builtins.modules.io.PRWPair; -import com.oracle.graal.python.builtins.modules.io.PStringIO; -import com.oracle.graal.python.builtins.modules.io.PTextIO; -import com.oracle.graal.python.builtins.modules.json.PJSONEncoder; -import com.oracle.graal.python.builtins.modules.json.PJSONEncoder.FastEncode; -import com.oracle.graal.python.builtins.modules.json.PJSONScanner; -import com.oracle.graal.python.builtins.modules.lzma.LZMAObject; -import com.oracle.graal.python.builtins.modules.multiprocessing.PGraalPySemLock; -import com.oracle.graal.python.builtins.modules.multiprocessing.PSemLock; -import com.oracle.graal.python.builtins.modules.pickle.PPickleBuffer; -import com.oracle.graal.python.builtins.modules.pickle.PPickler; -import com.oracle.graal.python.builtins.modules.pickle.PPicklerMemoProxy; -import com.oracle.graal.python.builtins.modules.pickle.PUnpickler; -import com.oracle.graal.python.builtins.modules.pickle.PUnpicklerMemoProxy; -import com.oracle.graal.python.builtins.modules.zlib.ZLibCompObject; -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.array.PArray; -import com.oracle.graal.python.builtins.objects.asyncio.PAsyncGen; -import com.oracle.graal.python.builtins.objects.asyncio.PAsyncGenASend; -import com.oracle.graal.python.builtins.objects.asyncio.PAsyncGenAThrow; -import com.oracle.graal.python.builtins.objects.asyncio.PAsyncGenWrappedValue; -import com.oracle.graal.python.builtins.objects.asyncio.PCoroutineWrapper; -import com.oracle.graal.python.builtins.objects.bytes.PByteArray; -import com.oracle.graal.python.builtins.objects.bytes.PBytes; -import com.oracle.graal.python.builtins.objects.capsule.PyCapsule; -import com.oracle.graal.python.builtins.objects.cell.PCell; -import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr; -import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper; -import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers; -import com.oracle.graal.python.builtins.objects.cext.hpy.PythonHPyObject; -import com.oracle.graal.python.builtins.objects.code.PCode; -import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage; -import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; -import com.oracle.graal.python.builtins.objects.common.ForeignHashingStorage; -import com.oracle.graal.python.builtins.objects.common.HashingStorage; -import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes; -import com.oracle.graal.python.builtins.objects.common.PHashingCollection; -import com.oracle.graal.python.builtins.objects.complex.PComplex; -import com.oracle.graal.python.builtins.objects.contextvars.PContextIterator; -import com.oracle.graal.python.builtins.objects.contextvars.PContextVar; -import com.oracle.graal.python.builtins.objects.contextvars.PContextVarsContext; -import com.oracle.graal.python.builtins.objects.contextvars.PContextVarsToken; -import com.oracle.graal.python.builtins.objects.deque.PDeque; -import com.oracle.graal.python.builtins.objects.deque.PDequeIter; -import com.oracle.graal.python.builtins.objects.dict.PDefaultDict; -import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.dict.PDictView; -import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictItemIterator; -import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictItemsView; -import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictKeyIterator; -import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictKeysView; -import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictValueIterator; -import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictValuesView; -import com.oracle.graal.python.builtins.objects.enumerate.PEnumerate; -import com.oracle.graal.python.builtins.objects.exception.PBaseException; -import com.oracle.graal.python.builtins.objects.exception.PBaseExceptionGroup; -import com.oracle.graal.python.builtins.objects.floats.PFloat; -import com.oracle.graal.python.builtins.objects.frame.PFrame; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.function.PFunction; -import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.builtins.objects.function.Signature; -import com.oracle.graal.python.builtins.objects.generator.PGenerator; -import com.oracle.graal.python.builtins.objects.getsetdescriptor.GetSetDescriptor; -import com.oracle.graal.python.builtins.objects.getsetdescriptor.IndexedSlotDescriptor; -import com.oracle.graal.python.builtins.objects.ints.PInt; -import com.oracle.graal.python.builtins.objects.iterator.PArrayIterator; -import com.oracle.graal.python.builtins.objects.iterator.PBaseSetIterator; -import com.oracle.graal.python.builtins.objects.iterator.PBigRangeIterator; -import com.oracle.graal.python.builtins.objects.iterator.PDoubleSequenceIterator; -import com.oracle.graal.python.builtins.objects.iterator.PIntRangeIterator; -import com.oracle.graal.python.builtins.objects.iterator.PIntegerSequenceIterator; -import com.oracle.graal.python.builtins.objects.iterator.PLongSequenceIterator; -import com.oracle.graal.python.builtins.objects.iterator.PObjectSequenceIterator; -import com.oracle.graal.python.builtins.objects.iterator.PSentinelIterator; -import com.oracle.graal.python.builtins.objects.iterator.PSequenceIterator; -import com.oracle.graal.python.builtins.objects.iterator.PStringIterator; -import com.oracle.graal.python.builtins.objects.iterator.PStructUnpackIterator; -import com.oracle.graal.python.builtins.objects.iterator.PZip; -import com.oracle.graal.python.builtins.objects.itertools.PAccumulate; -import com.oracle.graal.python.builtins.objects.itertools.PChain; -import com.oracle.graal.python.builtins.objects.itertools.PCombinations; -import com.oracle.graal.python.builtins.objects.itertools.PCombinationsWithReplacement; -import com.oracle.graal.python.builtins.objects.itertools.PCompress; -import com.oracle.graal.python.builtins.objects.itertools.PCount; -import com.oracle.graal.python.builtins.objects.itertools.PCycle; -import com.oracle.graal.python.builtins.objects.itertools.PDropwhile; -import com.oracle.graal.python.builtins.objects.itertools.PFilterfalse; -import com.oracle.graal.python.builtins.objects.itertools.PGroupBy; -import com.oracle.graal.python.builtins.objects.itertools.PGrouper; -import com.oracle.graal.python.builtins.objects.itertools.PIslice; -import com.oracle.graal.python.builtins.objects.itertools.PPairwise; -import com.oracle.graal.python.builtins.objects.itertools.PPermutations; -import com.oracle.graal.python.builtins.objects.itertools.PProduct; -import com.oracle.graal.python.builtins.objects.itertools.PRepeat; -import com.oracle.graal.python.builtins.objects.itertools.PStarmap; -import com.oracle.graal.python.builtins.objects.itertools.PTakewhile; -import com.oracle.graal.python.builtins.objects.itertools.PTee; -import com.oracle.graal.python.builtins.objects.itertools.PTeeDataObject; -import com.oracle.graal.python.builtins.objects.itertools.PZipLongest; -import com.oracle.graal.python.builtins.objects.list.PList; -import com.oracle.graal.python.builtins.objects.list.PList.ListOrigin; -import com.oracle.graal.python.builtins.objects.map.PMap; -import com.oracle.graal.python.builtins.objects.mappingproxy.PMappingproxy; -import com.oracle.graal.python.builtins.objects.memoryview.BufferLifecycleManager; -import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; -import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; -import com.oracle.graal.python.builtins.objects.method.PDecoratedMethod; -import com.oracle.graal.python.builtins.objects.method.PMethod; -import com.oracle.graal.python.builtins.objects.mmap.PMMap; -import com.oracle.graal.python.builtins.objects.module.PythonModule; -import com.oracle.graal.python.builtins.objects.namespace.PSimpleNamespace; -import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.builtins.objects.ordereddict.POrderedDict; -import com.oracle.graal.python.builtins.objects.ordereddict.POrderedDictIterator; -import com.oracle.graal.python.builtins.objects.posix.PDirEntry; -import com.oracle.graal.python.builtins.objects.posix.PScandirIterator; -import com.oracle.graal.python.builtins.objects.property.PProperty; -import com.oracle.graal.python.builtins.objects.queue.PSimpleQueue; -import com.oracle.graal.python.builtins.objects.random.PRandom; -import com.oracle.graal.python.builtins.objects.range.PBigRange; -import com.oracle.graal.python.builtins.objects.range.PIntRange; -import com.oracle.graal.python.builtins.objects.referencetype.PReferenceType; -import com.oracle.graal.python.builtins.objects.reversed.PSequenceReverseIterator; -import com.oracle.graal.python.builtins.objects.reversed.PStringReverseIterator; -import com.oracle.graal.python.builtins.objects.set.PBaseSet; -import com.oracle.graal.python.builtins.objects.set.PFrozenSet; -import com.oracle.graal.python.builtins.objects.set.PSet; -import com.oracle.graal.python.builtins.objects.slice.PIntSlice; -import com.oracle.graal.python.builtins.objects.slice.PObjectSlice; -import com.oracle.graal.python.builtins.objects.socket.PSocket; -import com.oracle.graal.python.builtins.objects.ssl.PMemoryBIO; -import com.oracle.graal.python.builtins.objects.ssl.PSSLContext; -import com.oracle.graal.python.builtins.objects.ssl.PSSLSocket; -import com.oracle.graal.python.builtins.objects.ssl.SSLMethod; -import com.oracle.graal.python.builtins.objects.str.NativeCharSequence; -import com.oracle.graal.python.builtins.objects.str.PString; -import com.oracle.graal.python.builtins.objects.struct.FormatAlignment; -import com.oracle.graal.python.builtins.objects.struct.FormatCode; -import com.oracle.graal.python.builtins.objects.struct.PStruct; -import com.oracle.graal.python.builtins.objects.superobject.SuperObject; -import com.oracle.graal.python.builtins.objects.thread.PLock; -import com.oracle.graal.python.builtins.objects.thread.PRLock; -import com.oracle.graal.python.builtins.objects.thread.PThread; -import com.oracle.graal.python.builtins.objects.thread.PThreadLocal; -import com.oracle.graal.python.builtins.objects.tokenize.PTokenizerIter; -import com.oracle.graal.python.builtins.objects.traceback.LazyTraceback; -import com.oracle.graal.python.builtins.objects.traceback.PTraceback; -import com.oracle.graal.python.builtins.objects.tuple.PTuple; -import com.oracle.graal.python.builtins.objects.tuple.PTupleGetter; -import com.oracle.graal.python.builtins.objects.tuple.StructSequence.BuiltinTypeDescriptor; -import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; -import com.oracle.graal.python.builtins.objects.type.PythonClass; -import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot; -import com.oracle.graal.python.builtins.objects.type.TpSlots; -import com.oracle.graal.python.builtins.objects.type.TypeNodes; -import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroStorageNode; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; -import com.oracle.graal.python.builtins.objects.types.PGenericAlias; -import com.oracle.graal.python.builtins.objects.types.PGenericAliasIterator; -import com.oracle.graal.python.builtins.objects.types.PUnionType; -import com.oracle.graal.python.compiler.CodeUnit; -import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode; -import com.oracle.graal.python.runtime.NFIZlibSupport; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonOptions; -import com.oracle.graal.python.runtime.object.PythonObjectFactoryNodeGen.LazyNodeGen; -import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage; -import com.oracle.graal.python.runtime.sequence.storage.DoubleSequenceStorage; -import com.oracle.graal.python.runtime.sequence.storage.EmptySequenceStorage; -import com.oracle.graal.python.runtime.sequence.storage.IntSequenceStorage; -import com.oracle.graal.python.runtime.sequence.storage.LongSequenceStorage; -import com.oracle.graal.python.runtime.sequence.storage.MroSequenceStorage; -import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage; -import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; -import com.oracle.graal.python.runtime.sequence.storage.SequenceStorageFactory; -import com.oracle.graal.python.util.BufferFormat; -import com.oracle.graal.python.util.OverflowException; -import com.oracle.graal.python.util.PythonUtils; -import com.oracle.graal.python.util.Supplier; -import com.oracle.truffle.api.Assumption; -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; -import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.GenerateCached; -import com.oracle.truffle.api.dsl.GenerateInline; -import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.instrumentation.AllocationReporter; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.object.Shape; -import com.oracle.truffle.api.strings.TruffleString; - -/** - * Factory for Python objects that also reports to Truffle's {@link AllocationReporter}. The - * reporting needs current context. There are several implementations of this abstract class. Use - * this rule of thumb when choosing which one to use: - *
        - *
      • In partially evaluated code: use adopted (@Child/@Cached) {@link PythonObjectFactory} node - *
      • - *
      • Behind {@code TruffleBoundary}: - *
          - *
        • When the current context is already available, use {@link Python3Core#factory()}. This avoids - * repeated context lookups inside the factory.
        • - *
        • When the current context is not available, but multiple objects will be created: lookup the - * context and use {@link Python3Core#factory()}. This executes only one context lookup. Note: first - * check if the caller could pass the context to avoid looking it up behind {@code TruffleBoundary}. - *
        • - *
        • When the current context is not available, and only one object is to be created: use - * {@link PythonObjectFactory#getUncached()}.
        • - *
        - *
      • - *
      - */ -@GenerateUncached -@ImportStatic(PythonOptions.class) -@GenerateInline(false) // Footprint reduction 28 -> 9 -public abstract class PythonObjectFactory extends Node { - // Note: we're keeping this not inlined for now because: - // - overwhelming number of usages of non-execute entry points to refactor - // - often used lazily and as a @Child, most notably in all the builtins - - @NeverDefault - public static PythonObjectFactory create() { - return PythonObjectFactoryNodeGen.create(); - } - - public static PythonObjectFactory getUncached() { - return PythonObjectFactoryNodeGen.getUncached(); - } - - protected abstract AllocationReporter executeTrace(Object o, long size); - - protected abstract Shape executeGetShape(Object o, boolean flag); - - @Specialization - static Shape getShape(Object o, @SuppressWarnings("unused") boolean flag, - @Cached TypeNodes.GetInstanceShape getShapeNode) { - return getShapeNode.execute(o); - } - - @Specialization - static AllocationReporter doTrace(Object o, long size, - @Cached(value = "getAllocationReporter()", allowUncached = true) AllocationReporter reporter) { - if (reporter.isActive()) { - doTraceImpl(o, size, reporter); - } - return null; - } - - @InliningCutoff - private static void doTraceImpl(Object o, long size, AllocationReporter reporter) { - reporter.onEnter(null, 0, size); - reporter.onReturnValue(o, 0, size); - } - - @NeverDefault - protected AllocationReporter getAllocationReporter() { - return PythonContext.get(this).getAllocationReporter(); - } - - public PythonLanguage getLanguage() { - return PythonLanguage.get(this); - } - - public final Shape getShape(PythonBuiltinClassType cls) { - return cls.getInstanceShape(getLanguage()); - } - - public final Shape getShape(Object cls) { - return executeGetShape(cls, true); - } - - public final T trace(T allocatedObject) { - executeTrace(allocatedObject, AllocationReporter.SIZE_UNKNOWN); - return allocatedObject; - } - - /* - * Python objects - */ - - /** - * Creates a PythonObject for the given class. This is potentially slightly slower than if the - * shape had been cached, due to the additional shape lookup. - */ - public final PythonObject createPythonObject(Object cls) { - return createPythonObject(cls, getShape(cls)); - } - - /** - * Creates a PythonObject for the given class. This is potentially slightly slower than if the - * shape had been cached, due to the additional shape lookup. - */ - public final PythonObject createPythonHPyObject(Object cls, Object hpyNativeSpace) { - return trace(new PythonHPyObject(cls, getShape(cls), hpyNativeSpace)); - } - - /** - * Creates a Python object with the given shape. Python object shapes store the class in the - * shape if possible. - */ - public final PythonObject createPythonObject(Object klass, Shape instanceShape) { - return trace(new PythonObject(klass, instanceShape)); - } - - public final PythonNativeVoidPtr createNativeVoidPtr(Object obj) { - return trace(new PythonNativeVoidPtr(obj)); - } - - public final PythonNativeVoidPtr createNativeVoidPtr(Object obj, long nativePtr) { - return trace(new PythonNativeVoidPtr(obj, nativePtr)); - } - - public final SuperObject createSuperObject(Object self) { - return trace(new SuperObject(self, getShape(self))); - } - - /* - * Primitive types - */ - public final PInt createInt(int value) { - Shape shape = getLanguage().getBuiltinTypeInstanceShape(PythonBuiltinClassType.PInt); - return trace(new PInt(PythonBuiltinClassType.PInt, shape, PInt.longToBigInteger(value))); - } - - public final PInt createInt(long value) { - Shape shape = getLanguage().getBuiltinTypeInstanceShape(PythonBuiltinClassType.PInt); - return trace(new PInt(PythonBuiltinClassType.PInt, shape, PInt.longToBigInteger(value))); - } - - public final PInt createInt(BigInteger value) { - Shape shape = getLanguage().getBuiltinTypeInstanceShape(PythonBuiltinClassType.PInt); - return trace(new PInt(PythonBuiltinClassType.PInt, shape, value)); - } - - public final Object createInt(Object cls, int value) { - return createInt(cls, PInt.longToBigInteger(value)); - } - - public final Object createInt(Object cls, long value) { - return createInt(cls, PInt.longToBigInteger(value)); - } - - public final PInt createInt(Object cls, BigInteger value) { - return trace(new PInt(cls, getShape(cls), value)); - } - - public final PFloat createFloat(double value) { - Shape shape = getLanguage().getBuiltinTypeInstanceShape(PythonBuiltinClassType.PFloat); - return trace(new PFloat(PythonBuiltinClassType.PFloat, shape, value)); - } - - public final PFloat createFloat(Object cls, double value) { - return trace(new PFloat(cls, getShape(cls), value)); - } - - public final PString createString(TruffleString string) { - Shape shape = getLanguage().getBuiltinTypeInstanceShape(PythonBuiltinClassType.PString); - return trace(new PString(PythonBuiltinClassType.PString, shape, string)); - } - - public final PString createString(Object cls, TruffleString string) { - return trace(new PString(cls, getShape(cls), string)); - } - - public final PString createString(NativeCharSequence string) { - return createString(PythonBuiltinClassType.PString, string); - } - - public final PString createString(Object cls, NativeCharSequence string) { - return trace(new PString(cls, getShape(cls), string)); - } - - public final PBytes createEmptyBytes() { - if (CompilerDirectives.inInterpreter()) { - return createBytes(PythonUtils.EMPTY_BYTE_ARRAY); - } else { - return createBytes(new byte[0]); - } - } - - public final PBytes createBytes(byte[] array) { - return createBytes(array, array.length); - } - - public final PBytes createBytes(byte[] array, int offset, int length) { - if (length != array.length) { - byte[] buf = new byte[length]; - PythonUtils.arraycopy(array, offset, buf, 0, buf.length); - return createBytes(buf, length); - } - return createBytes(array, length); - } - - public final PBytes createBytes(Object cls, byte[] array) { - return createBytes(cls, array, array.length); - } - - public final PBytes createBytes(byte[] array, int length) { - return createBytes(new ByteSequenceStorage(array, length)); - } - - public final PBytes createBytes(Object cls, byte[] array, int length) { - return createBytes(cls, new ByteSequenceStorage(array, length)); - } - - public final PBytes createBytes(SequenceStorage storage) { - return trace(new PBytes(PythonBuiltinClassType.PBytes, getShape(PythonBuiltinClassType.PBytes), storage)); - } - - public final PBytes createBytes(Object cls, SequenceStorage storage) { - return trace(new PBytes(cls, getShape(cls), storage)); - } - - public final PTuple createEmptyTuple() { - return createTuple(PythonUtils.EMPTY_OBJECT_ARRAY); - } - - public final PTuple createEmptyTuple(Object cls) { - return createTuple(cls, EmptySequenceStorage.INSTANCE); - } - - public final PTuple createTuple(Object[] objects) { - Shape shape = PythonBuiltinClassType.PTuple.getInstanceShape(getLanguage()); - return trace(new PTuple(PythonBuiltinClassType.PTuple, shape, objects)); - } - - public final PTuple createTuple(int[] ints) { - return createTuple(new IntSequenceStorage(ints)); - } - - public final PTuple createTuple(SequenceStorage store) { - Shape shape = PythonBuiltinClassType.PTuple.getInstanceShape(getLanguage()); - return trace(new PTuple(PythonBuiltinClassType.PTuple, shape, store)); - } - - public final PTuple createTuple(Object cls, Shape instanceShape, Object[] objects) { - return trace(new PTuple(cls, instanceShape, objects)); - } - - public final PTuple createTuple(Object cls, Object[] objects) { - return trace(new PTuple(cls, getShape(cls), objects)); - } - - public final PTuple createTuple(Object cls, SequenceStorage store) { - return trace(new PTuple(cls, getShape(cls), store)); - } - - public final PTuple createStructSeq(BuiltinTypeDescriptor desc, Object... values) { - assert desc.inSequence <= values.length && values.length <= desc.fieldNames.length; - return createTuple(desc.type, new ObjectSequenceStorage(values, desc.inSequence)); - } - - public final PTupleGetter createTupleGetter(int index, Object doc) { - return createTupleGetter(PythonBuiltinClassType.PTupleGetter, index, doc); - } - - public final PTupleGetter createTupleGetter(Object cls, int index, Object doc) { - return trace(new PTupleGetter(cls, getShape(cls), index, doc)); - } - - public final PComplex createComplex(Object cls, double real, double imag) { - return trace(new PComplex(cls, getShape(cls), real, imag)); - } - - public final PComplex createComplex(double real, double imag) { - return createComplex(PythonBuiltinClassType.PComplex, real, imag); - } - - public final PIntRange createIntRange(int stop) { - return trace(new PIntRange(getLanguage(), 0, stop, 1, stop)); - } - - public final PIntRange createIntRange(int start, int stop, int step, int len) { - return trace(new PIntRange(getLanguage(), start, stop, step, len)); - } - - public final PBigRange createBigRange(BigInteger start, BigInteger stop, BigInteger step, BigInteger len) { - return createBigRange(createInt(start), createInt(stop), createInt(step), createInt(len)); - } - - public final PBigRange createBigRange(PInt start, PInt stop, PInt step, PInt len) { - return trace(new PBigRange(getLanguage(), start, stop, step, len)); - } - - public final PIntSlice createIntSlice(int start, int stop, int step) { - return trace(new PIntSlice(getLanguage(), start, stop, step)); - } - - public final PIntSlice createIntSlice(int start, int stop, int step, boolean isStartNone, boolean isStepNone) { - return trace(new PIntSlice(getLanguage(), start, stop, step, isStartNone, isStepNone)); - } - - public final PObjectSlice createObjectSlice(Object start, Object stop, Object step) { - return trace(new PObjectSlice(getLanguage(), start, stop, step)); - } - - public final PRandom createRandom(Object cls) { - return trace(new PRandom(cls, getShape(cls))); - } - - /* - * Classes, methods and functions - */ - - /** - * Only to be used during context creation - */ - public final PythonModule createPythonModule(TruffleString name) { - return trace(PythonModule.createInternal(name)); - } - - public final PythonModule createPythonModule(Object cls) { - return trace(new PythonModule(cls, getShape(cls))); - } - - public final PythonClass createPythonClassAndFixupSlots(PythonLanguage language, Object metaclass, TruffleString name, Object base, PythonAbstractClass[] bases) { - PythonClass result = trace(new PythonClass(language, metaclass, getShape(metaclass), name, base, bases)); - // Fixup tp slots - MroSequenceStorage mro = GetMroStorageNode.executeUncached(result); - SpecialMethodSlot.initializeSpecialMethodSlots(result, mro, language); - TpSlots.inherit(result, mro, true); - TpSlots.fixupSlotDispatchers(result); - result.initializeMroShape(language); - return result; - } - - public final PythonClass createPythonClass(Object metaclass, TruffleString name, boolean invokeMro, Object base, PythonAbstractClass[] bases) { - // Note: called from type ctor, which itself will invoke setupSpecialMethodSlots at the - // right point - return trace(new PythonClass(getLanguage(), metaclass, getShape(metaclass), name, invokeMro, base, bases)); - } - - public final PMemoryView createMemoryView(PythonContext context, BufferLifecycleManager bufferLifecycleManager, Object buffer, Object owner, - int len, boolean readonly, int itemsize, BufferFormat format, TruffleString formatString, int ndim, Object bufPointer, - int offset, int[] shape, int[] strides, int[] suboffsets, int flags) { - PythonBuiltinClassType cls = PythonBuiltinClassType.PMemoryView; - return trace(new PMemoryView(cls, getShape(cls), context, bufferLifecycleManager, buffer, owner, len, readonly, itemsize, format, formatString, - ndim, bufPointer, offset, shape, strides, suboffsets, flags)); - } - - private final PMemoryView createMemoryView(PythonContext context, BufferLifecycleManager bufferLifecycleManager, Object buffer, Object owner, - int len, boolean readonly, int itemsize, TruffleString formatString, int ndim, Object bufPointer, - int offset, int[] shape, int[] strides, int[] suboffsets, int flags, TruffleString.CodePointLengthNode lengthNode, TruffleString.CodePointAtIndexNode atIndexNode) { - PythonBuiltinClassType cls = PythonBuiltinClassType.PMemoryView; - return trace(new PMemoryView(cls, getShape(cls), context, bufferLifecycleManager, buffer, owner, len, readonly, itemsize, - BufferFormat.forMemoryView(formatString, lengthNode, atIndexNode), formatString, ndim, bufPointer, offset, shape, strides, suboffsets, flags)); - } - - public final PMemoryView createMemoryViewForManagedObject(Object buffer, Object owner, int itemsize, int length, boolean readonly, TruffleString format, - TruffleString.CodePointLengthNode lengthNode, TruffleString.CodePointAtIndexNode atIndexNode) { - return createMemoryView(null, null, buffer, owner, length, readonly, itemsize, format, 1, - null, 0, new int[]{length / itemsize}, new int[]{itemsize}, null, - PMemoryView.FLAG_C | PMemoryView.FLAG_FORTRAN, lengthNode, atIndexNode); - } - - public final PMemoryView createMemoryViewForManagedObject(Object owner, int itemsize, int length, boolean readonly, TruffleString format, TruffleString.CodePointLengthNode lengthNode, - TruffleString.CodePointAtIndexNode atIndexNode) { - return createMemoryViewForManagedObject(owner, owner, itemsize, length, readonly, format, lengthNode, atIndexNode); - } - - public final PMethod createMethod(Object cls, Object self, Object function) { - return trace(new PMethod(cls, getShape(cls), self, function)); - } - - public final PMethod createMethod(Object self, Object function) { - return createMethod(PythonBuiltinClassType.PMethod, self, function); - } - - public final PMethod createBuiltinMethod(Object self, PFunction function) { - return createMethod(PythonBuiltinClassType.PBuiltinFunctionOrMethod, self, function); - } - - public final PBuiltinMethod createBuiltinMethod(Object cls, Object self, PBuiltinFunction function) { - return trace(new PBuiltinMethod(cls, getShape(cls), self, function, null)); - } - - public final PBuiltinMethod createBuiltinMethod(Object self, PBuiltinFunction function, Object classObject) { - return trace(new PBuiltinMethod(PythonBuiltinClassType.PBuiltinMethod, getShape(PythonBuiltinClassType.PBuiltinMethod), self, function, classObject)); - } - - public final PBuiltinMethod createBuiltinMethod(Object self, PBuiltinFunction function) { - return createBuiltinMethod(PythonBuiltinClassType.PBuiltinFunctionOrMethod, self, function); - } - - public final PFunction createFunction(TruffleString name, PCode code, PythonObject globals, PCell[] closure) { - return trace(new PFunction(getLanguage(), name, name, code, globals, closure)); - } - - public final PFunction createFunction(TruffleString name, TruffleString qualname, PCode code, PythonObject globals, Object[] defaultValues, PKeyword[] kwDefaultValues, PCell[] closure) { - return trace(new PFunction(getLanguage(), name, qualname, code, globals, defaultValues, kwDefaultValues, closure)); - } - - public final PFunction createFunction(TruffleString name, PCode code, PythonObject globals, Object[] defaultValues, PKeyword[] kwDefaultValues, PCell[] closure) { - return trace(new PFunction(getLanguage(), name, name, code, globals, defaultValues, kwDefaultValues, closure)); - } - - public final PFunction createFunction(TruffleString name, TruffleString qualname, PCode code, PythonObject globals, Object[] defaultValues, PKeyword[] kwDefaultValues, PCell[] closure, - Assumption codeStableAssumption, Assumption defaultsStableAssumption) { - return trace(new PFunction(getLanguage(), name, qualname, code, globals, defaultValues, kwDefaultValues, closure, - codeStableAssumption, defaultsStableAssumption)); - } - - public final PBuiltinFunction createBuiltinFunction(TruffleString name, Object type, int numDefaults, int flags, RootCallTarget callTarget) { - return trace(new PBuiltinFunction(PythonBuiltinClassType.PBuiltinFunction, PythonBuiltinClassType.PBuiltinFunction.getInstanceShape(getLanguage()), name, type, - PBuiltinFunction.generateDefaults(numDefaults), null, flags, callTarget)); - } - - public final PBuiltinFunction createBuiltinFunction(TruffleString name, Object type, Object[] defaults, PKeyword[] kw, int flags, RootCallTarget callTarget) { - return trace(new PBuiltinFunction(PythonBuiltinClassType.PBuiltinFunction, PythonBuiltinClassType.PBuiltinFunction.getInstanceShape(getLanguage()), name, type, defaults, kw, flags, - callTarget)); - } - - public final PBuiltinFunction createWrapperDescriptor(TruffleString name, Object type, int numDefaults, int flags, RootCallTarget callTarget, TpSlot slot, PExternalFunctionWrapper slotWrapper) { - return trace(new PBuiltinFunction(PythonBuiltinClassType.WrapperDescriptor, PythonBuiltinClassType.WrapperDescriptor.getInstanceShape(getLanguage()), name, type, - PBuiltinFunction.generateDefaults(numDefaults), null, flags, callTarget, slot, slotWrapper)); - } - - public final PBuiltinFunction createWrapperDescriptor(TruffleString name, Object type, Object[] defaults, PKeyword[] kw, int flags, RootCallTarget callTarget, TpSlot slot, - PExternalFunctionWrapper slotWrapper) { - return trace(new PBuiltinFunction(PythonBuiltinClassType.WrapperDescriptor, PythonBuiltinClassType.WrapperDescriptor.getInstanceShape(getLanguage()), name, type, defaults, kw, flags, - callTarget, slot, slotWrapper)); - } - - public final PBuiltinFunction createBuiltinFunction(PBuiltinFunction function, Object klass) { - PythonBuiltinClassType type = (PythonBuiltinClassType) function.getInitialPythonClass(); - return trace(new PBuiltinFunction(type, type.getInstanceShape(getLanguage()), function.getName(), klass, - function.getDefaults(), function.getKwDefaults(), function.getFlags(), function.getCallTarget(), - function.getSlot(), function.getSlotWrapper())); - } - - public final GetSetDescriptor createGetSetDescriptor(Object get, Object set, TruffleString name, Object type) { - return trace(new GetSetDescriptor(getLanguage(), get, set, name, type)); - } - - public final GetSetDescriptor createGetSetDescriptor(Object get, Object set, TruffleString name, Object type, boolean allowsDelete) { - return trace(new GetSetDescriptor(getLanguage(), get, set, name, type, allowsDelete)); - } - - public final GetSetDescriptor createMemberDescriptor(Object get, Object set, TruffleString name, Object type) { - return trace(new GetSetDescriptor(PythonBuiltinClassType.MemberDescriptor, PythonBuiltinClassType.MemberDescriptor.getInstanceShape(getLanguage()), get, set, name, type, set != null)); - } - - public final IndexedSlotDescriptor createIndexedSlotDescriptor(TruffleString name, int index, Object type) { - return trace(new IndexedSlotDescriptor(getLanguage(), name, index, type)); - } - - public final PDecoratedMethod createClassmethod(Object cls) { - return trace(new PDecoratedMethod(cls, getShape(cls))); - } - - public final PDecoratedMethod createClassmethodFromCallableObj(Object callable) { - return trace(new PDecoratedMethod(PythonBuiltinClassType.PClassmethod, PythonBuiltinClassType.PClassmethod.getInstanceShape(getLanguage()), callable)); - } - - public final PDecoratedMethod createBuiltinClassmethodFromCallableObj(Object callable) { - return trace(new PDecoratedMethod(PythonBuiltinClassType.PBuiltinClassMethod, PythonBuiltinClassType.PBuiltinClassMethod.getInstanceShape(getLanguage()), callable)); - } - - public final PDecoratedMethod createInstancemethod(Object cls) { - return trace(new PDecoratedMethod(cls, getShape(cls))); - } - - public final PDecoratedMethod createStaticmethod(Object cls) { - return trace(new PDecoratedMethod(cls, getShape(cls))); - } - - public final PDecoratedMethod createStaticmethodFromCallableObj(Object callable) { - Object func = callable; - if (func instanceof PBuiltinFunction) { - /* - * CPython's C static methods contain an object of type `builtin_function_or_method` - * (our PBuiltinMethod). Their self points to their type, but when called they get NULL - * as the first argument instead. - */ - func = createBuiltinMethod(((PBuiltinFunction) func).getEnclosingType(), (PBuiltinFunction) func); - } - return trace(new PDecoratedMethod(PythonBuiltinClassType.PStaticmethod, PythonBuiltinClassType.PStaticmethod.getInstanceShape(getLanguage()), func)); - } - - /* - * Lists, sets and dicts - */ - - public final PList createList() { - return createList(PythonUtils.EMPTY_OBJECT_ARRAY); - } - - public final PList createList(SequenceStorage storage) { - return createList(PythonBuiltinClassType.PList, storage); - } - - public final PList createList(Object cls, Shape instanceShape, SequenceStorage storage) { - return trace(new PList(cls, instanceShape, storage)); - } - - public final PList createList(SequenceStorage storage, ListOrigin origin) { - return trace(new PList(PythonBuiltinClassType.PList, PythonBuiltinClassType.PList.getInstanceShape(getLanguage()), storage, origin)); - } - - public final PList createList(Object cls, SequenceStorage storage) { - return trace(new PList(cls, getShape(cls), storage)); - } - - public final PList createList(Object cls) { - return createList(cls, PythonUtils.EMPTY_OBJECT_ARRAY); - } - - public final PList createList(Object[] array) { - return createList(PythonBuiltinClassType.PList, array); - } - - public final PList createList(Object cls, Object[] array) { - return trace(new PList(cls, getShape(cls), SequenceStorageFactory.createStorage(array))); - } - - public final PSet createSet() { - Shape shape = PythonBuiltinClassType.PSet.getInstanceShape(getLanguage()); - return trace(new PSet(PythonBuiltinClassType.PSet, shape)); - } - - public final PSet createSet(Object cls) { - return trace(new PSet(cls, getShape(cls))); - } - - public final PSet createSet(Object cls, Shape instanceShape) { - return trace(new PSet(cls, instanceShape)); - } - - public final PSet createSet(HashingStorage storage) { - Shape shape = PythonBuiltinClassType.PSet.getInstanceShape(getLanguage()); - return trace(new PSet(PythonBuiltinClassType.PSet, shape, storage)); - } - - public final PFrozenSet createFrozenSet(Object cls) { - return trace(new PFrozenSet(cls, getShape(cls))); - } - - public final PFrozenSet createFrozenSet(Object cls, HashingStorage storage) { - return trace(new PFrozenSet(cls, getShape(cls), storage)); - } - - public final PFrozenSet createFrozenSet(HashingStorage storage) { - Shape shape = PythonBuiltinClassType.PFrozenSet.getInstanceShape(getLanguage()); - return trace(new PFrozenSet(PythonBuiltinClassType.PFrozenSet, shape, storage)); - } - - public final PDict createDict() { - Shape shape = PythonBuiltinClassType.PDict.getInstanceShape(getLanguage()); - return trace(new PDict(PythonBuiltinClassType.PDict, shape)); - } - - public final PDict createDict(PKeyword[] keywords) { - Shape shape = PythonBuiltinClassType.PDict.getInstanceShape(getLanguage()); - return trace(new PDict(PythonBuiltinClassType.PDict, shape, keywords)); - } - - public final PDict createDict(Object cls) { - return trace(new PDict(cls, getShape(cls))); - } - - public final POrderedDict createOrderedDict(Object cls) { - return trace(new POrderedDict(cls, getShape(cls))); - } - - public final PDictKeysView createOrderedDictKeys(POrderedDict dict) { - PythonBuiltinClassType cls = PythonBuiltinClassType.POrderedDictKeys; - return trace(new PDictKeysView(cls, cls.getInstanceShape(getLanguage()), dict)); - } - - public final PDictValuesView createOrderedDictValues(POrderedDict dict) { - PythonBuiltinClassType cls = PythonBuiltinClassType.POrderedDictValues; - return trace(new PDictValuesView(cls, cls.getInstanceShape(getLanguage()), dict)); - } - - public final PDictItemsView createOrderedDictItems(POrderedDict dict) { - PythonBuiltinClassType cls = PythonBuiltinClassType.POrderedDictItems; - return trace(new PDictItemsView(cls, cls.getInstanceShape(getLanguage()), dict)); - } - - public POrderedDictIterator createOrderedDictIterator(POrderedDict dict, POrderedDictIterator.IteratorType type, boolean reversed) { - PythonBuiltinClassType cls = PythonBuiltinClassType.POrderedDictIterator; - return trace(new POrderedDictIterator(cls, cls.getInstanceShape(getLanguage()), dict, type, reversed)); - } - - @SuppressWarnings("unchecked") - public final PDict createDictFromMap(LinkedHashMap map) { - return createDict(EconomicMapStorage.create(map)); - } - - /** - * Generic version of {@link #createDictFromMap(LinkedHashMap)} that allows any type of keys. - * Note that this means that unless the keys are known to be side effect free, e.g., builtin - * types, this may end up calling Python code, so indirect call context should be properly - * set-up. This helper is meant for Truffle boundary code, in PE code build a storage by setting - * elements one by one starting from empty storage. - */ - @SuppressWarnings("unchecked") - public final PDict createDictFromMapGeneric(LinkedHashMap map) { - return createDict(EconomicMapStorage.createGeneric(map)); - } - - public final PDict createDictFixedStorage(PythonObject pythonObject, MroSequenceStorage mroSequenceStorage) { - return createDict(new DynamicObjectStorage(pythonObject, mroSequenceStorage)); - } - - public final PDict createDictFixedStorage(PythonObject pythonObject) { - return createDict(new DynamicObjectStorage(pythonObject)); - } - - public final PDict createDict(Object cls, HashingStorage storage) { - return trace(new PDict(cls, getShape(cls), storage)); - } - - public final PDict createDict(HashingStorage storage) { - return createDict(PythonBuiltinClassType.PDict, storage); - } - - public final PDict createDict(Object cls, Shape instanceShape, HashingStorage storage) { - return trace(new PDict(cls, instanceShape, storage)); - } - - public final PSimpleNamespace createSimpleNamespace() { - return createSimpleNamespace(PythonBuiltinClassType.PSimpleNamespace); - } - - public final PSimpleNamespace createSimpleNamespace(Object cls) { - return createSimpleNamespace(cls, getShape(cls)); - } - - public final PSimpleNamespace createSimpleNamespace(Object cls, Shape instanceShape) { - return trace(new PSimpleNamespace(cls, instanceShape)); - } - - public final PKeyWrapper createKeyWrapper(Object cmp) { - return trace(new PKeyWrapper(PythonBuiltinClassType.PKeyWrapper, getShape(PythonBuiltinClassType.PKeyWrapper), cmp)); - } - - public final PPartial createPartial(Object cls, Object function, Object[] args, PDict kwDict) { - return trace(new PPartial(cls, getShape(cls), function, args, kwDict)); - } - - public LruCacheObject createLruCacheObject(Object cls) { - return trace(new LruCacheObject(cls, getShape(cls))); - } - - public final PDefaultDict createDefaultDict(Object cls) { - return createDefaultDict(cls, PNone.NONE); - } - - public final PDefaultDict createDefaultDict(Object cls, Object defaultFactory) { - return trace(new PDefaultDict(cls, getShape(cls), defaultFactory)); - } - - public final PDefaultDict createDefaultDict(Object defaultFactory, HashingStorage storage) { - return createDefaultDict(PythonBuiltinClassType.PDefaultDict, defaultFactory, storage); - } - - public final PDefaultDict createDefaultDict(Object cls, Object defaultFactory, HashingStorage storage) { - return trace(new PDefaultDict(cls, getShape(cls), storage, defaultFactory)); - } - - public final PDictView createDictKeysView(PHashingCollection dict) { - return trace(new PDictKeysView(PythonBuiltinClassType.PDictKeysView, PythonBuiltinClassType.PDictKeysView.getInstanceShape(getLanguage()), dict)); - } - - public final PDictView createDictKeysView(Object dict, ForeignHashingStorage foreignHashingStorage) { - return trace(new PDictKeysView(PythonBuiltinClassType.PDictKeysView, PythonBuiltinClassType.PDictKeysView.getInstanceShape(getLanguage()), dict, foreignHashingStorage)); - } - - public final PDictView createDictValuesView(PHashingCollection dict) { - return trace(new PDictValuesView(PythonBuiltinClassType.PDictValuesView, PythonBuiltinClassType.PDictValuesView.getInstanceShape(getLanguage()), dict)); - } - - public final PDictView createDictValuesView(Object dict, ForeignHashingStorage foreignHashingStorage) { - return trace(new PDictValuesView(PythonBuiltinClassType.PDictValuesView, PythonBuiltinClassType.PDictValuesView.getInstanceShape(getLanguage()), dict, foreignHashingStorage)); - } - - public final PDictView createDictItemsView(PHashingCollection dict) { - return trace(new PDictItemsView(PythonBuiltinClassType.PDictItemsView, PythonBuiltinClassType.PDictItemsView.getInstanceShape(getLanguage()), dict)); - } - - public final PDictView createDictItemsView(Object dict, ForeignHashingStorage foreignHashingStorage) { - return trace(new PDictItemsView(PythonBuiltinClassType.PDictItemsView, PythonBuiltinClassType.PDictItemsView.getInstanceShape(getLanguage()), dict, foreignHashingStorage)); - } - - /* - * Special objects: generators, proxies, references, cells - */ - - public final PGenerator createGenerator(TruffleString name, TruffleString qualname, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, Object[] arguments) { - return trace(PGenerator.create(getLanguage(), name, qualname, rootNode, callTargets, arguments, PythonBuiltinClassType.PGenerator)); - } - - public final PGenerator createIterableCoroutine(TruffleString name, TruffleString qualname, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, Object[] arguments) { - return trace(PGenerator.create(getLanguage(), name, qualname, rootNode, callTargets, arguments, PythonBuiltinClassType.PGenerator, true)); - } - - public final PGenerator createCoroutine(TruffleString name, TruffleString qualname, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, Object[] arguments) { - return trace(PGenerator.create(getLanguage(), name, qualname, rootNode, callTargets, arguments, PythonBuiltinClassType.PCoroutine)); - } - - public final PCoroutineWrapper createCoroutineWrapper(PGenerator generator) { - return trace(new PCoroutineWrapper(getLanguage(), generator)); - } - - public final PAsyncGen createAsyncGenerator(TruffleString name, TruffleString qualname, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, Object[] arguments) { - return trace(PAsyncGen.create(getLanguage(), name, qualname, rootNode, callTargets, arguments)); - } - - public final PMappingproxy createMappingproxy(Object object) { - PythonBuiltinClassType mpClass = PythonBuiltinClassType.PMappingproxy; - return trace(new PMappingproxy(mpClass, mpClass.getInstanceShape(getLanguage()), object)); - } - - public final PMappingproxy createMappingproxy(Object cls, Object object) { - return trace(new PMappingproxy(cls, getShape(cls), object)); - } - - public final PReferenceType createReferenceType(Object cls, Object object, Object callback, ReferenceQueue queue) { - return trace(new PReferenceType(cls, getShape(cls), object, callback, queue)); - } - - public final PReferenceType createReferenceType(Object object, Object callback, ReferenceQueue queue) { - return createReferenceType(PythonBuiltinClassType.PReferenceType, object, callback, queue); - } - - public final PCell createCell(Assumption effectivelyFinal) { - return trace(new PCell(effectivelyFinal)); - } - - /* - * Frames, traces and exceptions - */ - - public final PFrame createPFrame(PFrame.Reference frameInfo, Node location, MaterializedFrame locals) { - return trace(new PFrame(getLanguage(), frameInfo, location, locals)); - } - - public final PFrame createPFrame(Object threadState, PCode code, PythonObject globals, Object localsDict) { - return trace(new PFrame(getLanguage(), threadState, code, globals, localsDict)); - } - - public final PTraceback createTraceback(PFrame frame, int lineno, PTraceback next) { - return trace(new PTraceback(getLanguage(), frame, lineno, -1, next)); - } - - public final PTraceback createTracebackWithLasti(PFrame frame, int lineno, int lasti, PTraceback next) { - return trace(new PTraceback(getLanguage(), frame, lineno, lasti, next)); - } - - public final PTraceback createTraceback(LazyTraceback tb) { - return trace(new PTraceback(getLanguage(), tb)); - } - - public final PBaseException createBaseException(Object cls, PTuple args) { - return createBaseException(cls, null, args); - } - - public final PBaseException createBaseException(Object cls, Object[] data, PTuple args) { - return trace(new PBaseException(cls, getShape(cls), data, args)); - } - - /* - * Note: we use this method to convert a Java StackOverflowError into a Python RecursionError. - * At the time when this is done, some Java stack frames were already unwinded but there is no - * guarantee on how many. Therefore, it is important that this method is simple. In particular, - * do not add calls if that can be avoided. - */ - public final PBaseException createBaseException(Object cls, TruffleString format, Object[] args) { - return createBaseException(cls, null, format, args); - } - - public final PBaseException createBaseException(Object cls, Object[] data, TruffleString format, Object[] args) { - assert format != null; - return trace(new PBaseException(cls, getShape(cls), data, format, args)); - } - - public final PBaseException createBaseException(Object cls) { - return trace(new PBaseException(cls, getShape(cls), null)); - } - - public final PBaseException createBaseException(Object cls, Object[] data) { - return trace(new PBaseException(cls, getShape(cls), data)); - } - - public final PBaseExceptionGroup createBaseExceptionGroup(Object cls, TruffleString message, Object[] exceptions, Object[] args) { - return trace(new PBaseExceptionGroup(cls, getShape(cls), message, exceptions, createTuple(args))); - } - - /* - * Arrays - */ - - public final PArray createArray(Object cls, TruffleString formatString, BufferFormat format) { - assert format != null; - return trace(new PArray(cls, getShape(cls), formatString, format)); - } - - public final PArray createArray(TruffleString formatString, BufferFormat format, int length) throws OverflowException { - return createArray(PythonBuiltinClassType.PArray, formatString, format, length); - } - - public final PArray createArray(Object cls, TruffleString formatString, BufferFormat format, int length) throws OverflowException { - assert format != null; - return trace(new PArray(cls, getShape(cls), formatString, format, length)); - } - - public final PByteArray createByteArray(byte[] array) { - return createByteArray(array, array.length); - } - - public final PByteArray createByteArray(Object cls, byte[] array) { - return createByteArray(cls, array, array.length); - } - - public final PByteArray createByteArray(byte[] array, int length) { - return createByteArray(new ByteSequenceStorage(array, length)); - } - - public final PByteArray createByteArray(Object cls, byte[] array, int length) { - return createByteArray(cls, new ByteSequenceStorage(array, length)); - } - - public final PByteArray createByteArray(SequenceStorage storage) { - return createByteArray(PythonBuiltinClassType.PByteArray, storage); - } - - public final PByteArray createByteArray(Object cls, SequenceStorage storage) { - return trace(new PByteArray(cls, getShape(cls), storage)); - } - - /* - * Iterators - */ - - public final PStringIterator createStringIterator(TruffleString str) { - return trace(new PStringIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(getLanguage()), str)); - } - - public final PStringReverseIterator createStringReverseIterator(Object cls, TruffleString str) { - return trace(new PStringReverseIterator(cls, getShape(cls), str)); - } - - public final PIntegerSequenceIterator createIntegerSequenceIterator(IntSequenceStorage storage, Object list) { - return trace(new PIntegerSequenceIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(getLanguage()), storage, list)); - } - - public final PLongSequenceIterator createLongSequenceIterator(LongSequenceStorage storage, Object list) { - return trace(new PLongSequenceIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(getLanguage()), storage, list)); - } - - public final PDoubleSequenceIterator createDoubleSequenceIterator(DoubleSequenceStorage storage, Object list) { - return trace(new PDoubleSequenceIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(getLanguage()), storage, list)); - } - - public final PObjectSequenceIterator createObjectSequenceIterator(ObjectSequenceStorage storage, Object list) { - return trace(new PObjectSequenceIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(getLanguage()), storage, list)); - } - - public final PSequenceIterator createSequenceIterator(Object sequence) { - return trace(new PSequenceIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(getLanguage()), sequence)); - } - - public final PSequenceReverseIterator createSequenceReverseIterator(Object cls, Object sequence, int lengthHint) { - return trace(new PSequenceReverseIterator(cls, getShape(cls), sequence, lengthHint)); - } - - public final PIntRangeIterator createIntRangeIterator(PIntRange fastRange) { - return createIntRangeIterator(fastRange.getIntStart(), fastRange.getIntStop(), fastRange.getIntStep(), fastRange.getIntLength()); - } - - public final PIntRangeIterator createIntRangeIterator(int start, int stop, int step, int len) { - return trace(new PIntRangeIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(getLanguage()), start, stop, step, len)); - } - - public final PBigRangeIterator createBigRangeIterator(PInt start, PInt stop, PInt step, PInt len) { - return trace(new PBigRangeIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(getLanguage()), start, stop, step, len)); - } - - public final PBigRangeIterator createBigRangeIterator(PBigRange longRange) { - return createBigRangeIterator(longRange.getPIntStart(), longRange.getPIntStop(), longRange.getPIntStep(), longRange.getPIntLength()); - } - - public final PBigRangeIterator createBigRangeIterator(BigInteger start, BigInteger stop, BigInteger step, BigInteger len) { - return createBigRangeIterator(createInt(start), createInt(stop), createInt(step), createInt(len)); - } - - public final PArrayIterator createArrayIterator(PArray array) { - return trace(new PArrayIterator(PythonBuiltinClassType.PArrayIterator, PythonBuiltinClassType.PArrayIterator.getInstanceShape(getLanguage()), array)); - } - - public final PBaseSetIterator createBaseSetIterator(PBaseSet set, HashingStorageNodes.HashingStorageIterator iterator, int initialSize) { - return trace(new PBaseSetIterator(PythonBuiltinClassType.PIterator, PythonBuiltinClassType.PIterator.getInstanceShape(getLanguage()), set, iterator, initialSize)); - } - - public final PDictItemIterator createDictItemIterator(HashingStorageNodes.HashingStorageIterator iterator, HashingStorage hashingStorage, int initialSize) { - return trace(new PDictItemIterator(PythonBuiltinClassType.PDictItemIterator, PythonBuiltinClassType.PDictItemIterator.getInstanceShape(getLanguage()), iterator, hashingStorage, initialSize)); - } - - public final PDictKeyIterator createDictKeyIterator(HashingStorageNodes.HashingStorageIterator iterator, HashingStorage hashingStorage, int initialSize) { - return trace(new PDictKeyIterator(PythonBuiltinClassType.PDictKeyIterator, PythonBuiltinClassType.PDictKeyIterator.getInstanceShape(getLanguage()), iterator, hashingStorage, initialSize)); - } - - public final PDictValueIterator createDictValueIterator(HashingStorageNodes.HashingStorageIterator iterator, HashingStorage hashingStorage, int initialSize) { - return trace(new PDictValueIterator(PythonBuiltinClassType.PDictValueIterator, PythonBuiltinClassType.PDictValueIterator.getInstanceShape(getLanguage()), iterator, hashingStorage, - initialSize)); - } - - public final Object createSentinelIterator(Object callable, Object sentinel) { - return trace(new PSentinelIterator(PythonBuiltinClassType.PSentinelIterator, PythonBuiltinClassType.PSentinelIterator.getInstanceShape(getLanguage()), callable, sentinel)); - } - - public final PEnumerate createEnumerate(Object cls, Object iterator, long start) { - return trace(new PEnumerate(cls, getShape(cls), iterator, start)); - } - - public final PEnumerate createEnumerate(Object cls, Object iterator, PInt start) { - return trace(new PEnumerate(cls, getShape(cls), iterator, start)); - } - - public final PMap createMap(Object cls) { - return trace(new PMap(cls, getShape(cls))); - } - - public final PZip createZip(Object cls, Object[] iterables, boolean strict) { - return trace(new PZip(cls, getShape(cls), iterables, strict)); - } - - public final PCode createCode(RootCallTarget ct) { - return trace(new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(getLanguage()), ct)); - } - - public final PCode createCode(RootCallTarget ct, int flags, int firstlineno, byte[] linetable, TruffleString filename) { - return trace(new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(getLanguage()), ct, flags, firstlineno, linetable, filename)); - } - - public final PCode createCode(RootCallTarget callTarget, Signature signature, CodeUnit codeUnit) { - return trace(new PCode(PythonBuiltinClassType.PCode, getShape(PythonBuiltinClassType.PCode), callTarget, signature, codeUnit)); - } - - public final PCode createCode(RootCallTarget callTarget, Signature signature, int nlocals, - int stacksize, int flags, Object[] constants, - TruffleString[] names, TruffleString[] varnames, - TruffleString[] freevars, TruffleString[] cellvars, - TruffleString filename, TruffleString name, TruffleString qualname, - int firstlineno, byte[] linetable) { - return trace(new PCode(PythonBuiltinClassType.PCode, getShape(PythonBuiltinClassType.PCode), callTarget, signature, - nlocals, stacksize, flags, constants, names, varnames, freevars, cellvars, - filename, name, qualname, firstlineno, linetable)); - } - - public PCode createCode(Supplier createCode, int flags, int firstlineno, byte[] lnotab, TruffleString filename) { - return trace(new PCode(PythonBuiltinClassType.PCode, getShape(PythonBuiltinClassType.PCode), createCode, flags, firstlineno, lnotab, filename)); - } - - /* - * Socket - */ - - public final PSocket createSocket(Object cls) { - return trace(new PSocket(cls, getShape(cls))); - } - - /* - * Threading - */ - - public PThreadLocal createThreadLocal(Object cls, Object[] args, PKeyword[] kwArgs) { - return trace(new PThreadLocal(cls, getShape(cls), args, kwArgs)); - } - - public final PLock createLock() { - return createLock(PythonBuiltinClassType.PLock); - } - - public final PLock createLock(Object cls) { - return trace(new PLock(cls, getShape(cls))); - } - - public final PRLock createRLock() { - return createRLock(PythonBuiltinClassType.PRLock); - } - - public final PRLock createRLock(Object cls) { - return trace(new PRLock(cls, getShape(cls))); - } - - public final PThread createPythonThread(Thread thread) { - return trace(new PThread(PythonBuiltinClassType.PThread, PythonBuiltinClassType.PThread.getInstanceShape(getLanguage()), thread)); - } - - public final PThread createPythonThread(Object cls, Thread thread) { - return trace(new PThread(cls, getShape(cls), thread)); - } - - public final PSemLock createSemLock(Object cls, long handle, int kind, int maxValue, TruffleString name) { - return trace(new PSemLock(cls, getShape(cls), handle, kind, maxValue, name)); - } - - public final PGraalPySemLock createGraalPySemLock(Object cls, TruffleString name, int kind, Semaphore sharedSemaphore) { - return trace(new PGraalPySemLock(cls, getShape(cls), name, kind, sharedSemaphore)); - } - - public final PScandirIterator createScandirIterator(PythonContext context, Object dirStream, PosixFileHandle path, boolean needsRewind) { - return trace(new PScandirIterator(PythonBuiltinClassType.PScandirIterator, PythonBuiltinClassType.PScandirIterator.getInstanceShape(getLanguage()), context, dirStream, path, needsRewind)); - } - - public final PDirEntry createDirEntry(Object dirEntryData, PosixFileHandle path) { - return trace(new PDirEntry(PythonBuiltinClassType.PDirEntry, PythonBuiltinClassType.PDirEntry.getInstanceShape(getLanguage()), dirEntryData, path)); - } - - public final PEncodingMap createEncodingMap(int count2, int count3, byte[] level1, byte[] level23) { - return trace(new PEncodingMap(PythonBuiltinClassType.PEncodingMap, PythonBuiltinClassType.PEncodingMap.getInstanceShape(getLanguage()), count2, count3, level1, level23)); - } - - public final PMMap createMMap(PythonContext context, Object clazz, Object mmapHandle, int fd, long length, int access) { - return trace(new PMMap(clazz, getShape(clazz), context, mmapHandle, fd, length, access)); - } - - public final BZ2Object.BZ2Compressor createBZ2Compressor(Object clazz) { - return trace(BZ2Object.createCompressor(clazz, getShape(clazz))); - } - - public final BZ2Object.BZ2Decompressor createBZ2Decompressor(Object clazz) { - return trace(BZ2Object.createDecompressor(clazz, getShape(clazz))); - } - - public final ZLibCompObject createJavaZLibCompObject(Object clazz, Object stream, int level, int wbits, int strategy, byte[] zdict) { - return trace(ZLibCompObject.createJava(clazz, getShape(clazz), stream, level, wbits, strategy, zdict)); - } - - public final ZLibCompObject createJavaZLibCompObject(Object clazz, Object stream, int wbits, byte[] zdict) { - return trace(ZLibCompObject.createJava(clazz, getShape(clazz), stream, wbits, zdict)); - } - - public final ZLibCompObject createNativeZLibCompObject(Object clazz, Object zst, NFIZlibSupport zlibSupport) { - return trace(ZLibCompObject.createNative(clazz, getShape(clazz), zst, zlibSupport)); - } - - public final LZMAObject.LZMADecompressor createLZMADecompressor(Object clazz, boolean isNative) { - return trace(LZMAObject.createDecompressor(clazz, getShape(clazz), isNative)); - } - - public final LZMAObject.LZMACompressor createLZMACompressor(Object clazz, boolean isNative) { - return trace(LZMAObject.createCompressor(clazz, getShape(clazz), isNative)); - } - - public final CSVReader createCSVReader(Object clazz, Object inputIter, CSVDialect dialect) { - return trace(new CSVReader(clazz, getShape(clazz), inputIter, dialect)); - } - - public final CSVWriter createCSVWriter(Object clazz, Object write, CSVDialect dialect) { - return trace(new CSVWriter(clazz, getShape(clazz), write, dialect)); - } - - public final CSVDialect createCSVDialect(Object clazz, TruffleString delimiter, int delimiterCodePoint, boolean doubleQuote, TruffleString escapeChar, int escapeCharCodePoint, - TruffleString lineTerminator, TruffleString quoteChar, int quoteCharCodePoint, QuoteStyle quoting, boolean skipInitialSpace, boolean strict) { - return trace(new CSVDialect(clazz, getShape(clazz), delimiter, delimiterCodePoint, doubleQuote, escapeChar, escapeCharCodePoint, lineTerminator, quoteChar, quoteCharCodePoint, quoting, - skipInitialSpace, strict)); - } - - public final PFileIO createFileIO(Object clazz) { - return trace(new PFileIO(clazz, getShape(clazz))); - } - - public final PChain createChain(Object cls) { - return trace(new PChain(cls, getShape(cls))); - } - - public final PCount createCount(Object cls) { - return trace(new PCount(cls, getShape(cls))); - } - - public final PIslice createIslice(Object cls) { - return trace(new PIslice(cls, getShape(cls))); - } - - public final PPairwise createPairwise(Object cls) { - return trace(new PPairwise(cls, getShape(cls))); - } - - public final PPermutations createPermutations(Object cls) { - return trace(new PPermutations(cls, getShape(cls))); - } - - public final PProduct createProduct(Object cls) { - return trace(new PProduct(cls, getShape(cls))); - } - - public final PRepeat createRepeat(Object cls) { - return trace(new PRepeat(cls, getShape(cls))); - } - - public final PAccumulate createAccumulate(Object cls) { - return trace(new PAccumulate(cls, getShape(cls))); - } - - public final PDropwhile createDropwhile(Object cls) { - return trace(new PDropwhile(cls, getShape(cls))); - } - - public final PCombinations createCombinations(Object cls) { - return trace(new PCombinations(cls, getShape(cls))); - } - - public final PCombinationsWithReplacement createCombinationsWithReplacement(Object cls) { - return trace(new PCombinationsWithReplacement(cls, getShape(cls))); - } - - public final PCompress createCompress(Object cls) { - return trace(new PCompress(cls, getShape(cls))); - } - - public final PCycle createCycle(Object cls) { - return trace(new PCycle(cls, getShape(cls))); - } - - public final PFilterfalse createFilterfalse(Object cls) { - return trace(new PFilterfalse(cls, getShape(cls))); - } - - public final PGroupBy createGroupBy(Object cls) { - return trace(new PGroupBy(cls, getShape(cls))); - } - - public final PGrouper createGrouper(Object cls) { - return trace(new PGrouper(cls, getShape(cls))); - } - - public final PGrouper createGrouper(PGroupBy parent, Object tgtKey) { - return trace(new PGrouper(parent, tgtKey, PythonBuiltinClassType.PGrouper, PythonBuiltinClassType.PGrouper.getInstanceShape(getLanguage()))); - } - - public final PTee createTee() { - return trace(new PTee(PythonBuiltinClassType.PTee, PythonBuiltinClassType.PTee.getInstanceShape(getLanguage()))); - } - - public final PTee createTee(PTeeDataObject dataObj, int index) { - return trace(new PTee(dataObj, index, PythonBuiltinClassType.PTee, PythonBuiltinClassType.PTee.getInstanceShape(getLanguage()))); - } - - public final PStarmap createStarmap(Object cls) { - return trace(new PStarmap(cls, getShape(cls))); - } - - public final PTakewhile createTakewhile(Object cls) { - return trace(new PTakewhile(cls, getShape(cls))); - } - - public final PTeeDataObject createTeeDataObject() { - return trace(new PTeeDataObject(PythonBuiltinClassType.PTeeDataObject, PythonBuiltinClassType.PTeeDataObject.getInstanceShape(getLanguage()))); - } - - public final PTeeDataObject createTeeDataObject(Object it) { - return trace(new PTeeDataObject(it, PythonBuiltinClassType.PTeeDataObject, PythonBuiltinClassType.PTeeDataObject.getInstanceShape(getLanguage()))); - } - - public final PZipLongest createZipLongest(Object cls) { - return trace(new PZipLongest(cls, getShape(cls))); - } - - public final PTextIO createTextIO(Object clazz) { - return trace(new PTextIO(clazz, getShape(clazz))); - } - - public final PStringIO createStringIO(Object clazz) { - return trace(new PStringIO(clazz, getShape(clazz))); - } - - public final PBytesIO createBytesIO(Object clazz) { - return trace(new PBytesIO(clazz, getShape(clazz))); - } - - public final PBytesIOBuffer createBytesIOBuf(Object clazz, PBytesIO source) { - return trace(new PBytesIOBuffer(clazz, getShape(clazz), source)); - } - - public final PNLDecoder createNLDecoder(Object clazz) { - return trace(new PNLDecoder(clazz, getShape(clazz))); - } - - public final PBuffered createBufferedReader(Object clazz) { - return trace(new PBuffered(clazz, getShape(clazz), true, false)); - } - - public final PBuffered createBufferedWriter(Object clazz) { - return trace(new PBuffered(clazz, getShape(clazz), false, true)); - } - - public final PBuffered createBufferedRandom(Object clazz) { - return trace(new PBuffered(clazz, getShape(clazz), true, true)); - } - - public final PRWPair createRWPair(Object clazz) { - return trace(new PRWPair(clazz, getShape(clazz))); - } - - public final PyCArgObject createCArgObject() { - return trace(new PyCArgObject(PythonBuiltinClassType.CArgObject, getShape(PythonBuiltinClassType.CArgObject))); - } - - public final CThunkObject createCThunkObject(Object clazz, int nArgs) { - return trace(new CThunkObject(clazz, getShape(clazz), nArgs)); - } - - public final StructParamObject createStructParamObject(Object clazz) { - return trace(new StructParamObject(clazz, getShape(clazz))); - } - - // Don't use directly, use CtypesNodes.CreateCDataObjectNode - public final CDataObject createCDataObject(Object clazz, Pointer b_ptr, int b_size, boolean b_needsfree) { - return trace(new CDataObject(clazz, getShape(clazz), b_ptr, b_size, b_needsfree)); - } - - // Don't use directly, use CtypesNodes.CreateCDataObjectNode - public final PyCFuncPtrObject createPyCFuncPtrObject(Object clazz, Pointer b_ptr, int b_size, boolean b_needsfree) { - return trace(new PyCFuncPtrObject(clazz, getShape(clazz), b_ptr, b_size, b_needsfree)); - } - - public final CFieldObject createCFieldObject(Object clazz) { - return trace(new CFieldObject(clazz, getShape(clazz))); - } - - public final StgDictObject createStgDictObject(Object clazz) { - return trace(new StgDictObject(clazz, getShape(clazz))); - } - - public final PSSLContext createSSLContext(Object clazz, SSLMethod method, int verifyFlags, boolean checkHostname, int verifyMode, SSLContext context) { - return trace(new PSSLContext(clazz, getShape(clazz), method, verifyFlags, checkHostname, verifyMode, context)); - } - - public final PSSLSocket createSSLSocket(Object clazz, PSSLContext context, SSLEngine engine, PSocket socket) { - return trace(new PSSLSocket(clazz, getShape(clazz), context, engine, socket, createMemoryBIO(), createMemoryBIO(), createMemoryBIO())); - } - - public final PSSLSocket createSSLSocket(Object clazz, PSSLContext context, SSLEngine engine, PMemoryBIO inbound, PMemoryBIO outbound) { - return trace(new PSSLSocket(clazz, getShape(clazz), context, engine, null, inbound, outbound, createMemoryBIO())); - } - - public final PMemoryBIO createMemoryBIO(Object clazz) { - return trace(new PMemoryBIO(clazz, getShape(clazz))); - } - - public final PMemoryBIO createMemoryBIO() { - return trace(new PMemoryBIO(PythonBuiltinClassType.PMemoryBIO, getShape(PythonBuiltinClassType.PMemoryBIO))); - } - - public final PProperty createProperty() { - return trace(new PProperty(PythonBuiltinClassType.PProperty, getShape(PythonBuiltinClassType.PProperty))); - } - - public final PProperty createProperty(Object cls) { - return trace(new PProperty(cls, getShape(cls))); - } - - // JSON - // (not created on fast path, thus TruffleBoundary) - - @TruffleBoundary - public final PJSONScanner createJSONScanner(Object clazz, boolean strict, Object objectHook, Object objectPairsHook, Object parseFloat, Object parseInt, Object parseConstant) { - return trace(new PJSONScanner(clazz, getShape(clazz), strict, objectHook, objectPairsHook, parseFloat, parseInt, parseConstant)); - } - - @TruffleBoundary - public final PJSONEncoder createJSONEncoder(Object clazz, Object markers, Object defaultFn, Object encoder, Object indent, TruffleString keySeparator, TruffleString itemSeparator, - boolean sortKeys, boolean skipKeys, boolean allowNan, FastEncode fastEncode) { - return trace(new PJSONEncoder(clazz, getShape(clazz), markers, defaultFn, encoder, indent, keySeparator, itemSeparator, sortKeys, skipKeys, allowNan, fastEncode)); - } - - public final PDeque createDeque() { - return trace(new PDeque(PythonBuiltinClassType.PDeque, getShape(PythonBuiltinClassType.PDeque))); - } - - public final PDeque createDeque(Object cls) { - return trace(new PDeque(cls, getShape(cls))); - } - - public final PDequeIter createDequeIter(PDeque deque) { - return trace(new PDequeIter(PythonBuiltinClassType.PDequeIter, getShape(PythonBuiltinClassType.PDequeIter), deque, false)); - } - - public final PDequeIter createDequeRevIter(PDeque deque) { - return trace(new PDequeIter(PythonBuiltinClassType.PDequeRevIter, getShape(PythonBuiltinClassType.PDequeRevIter), deque, true)); - } - - public final PSimpleQueue createSimpleQueue(Object cls) { - return trace(new PSimpleQueue(cls, getShape(cls))); - } - - public final PContextVar createContextVar(TruffleString name, Object def) { - return trace(new PContextVar(PythonBuiltinClassType.ContextVar, getShape(PythonBuiltinClassType.ContextVar), name, def)); - } - - public final PContextVarsContext createContextVarsContext() { - return trace(new PContextVarsContext(PythonBuiltinClassType.ContextVarsContext, getShape(PythonBuiltinClassType.ContextVarsContext))); - } - - public final PContextIterator createContextIterator(PContextVarsContext ctx, PContextIterator.ItemKind kind) { - return trace(new PContextIterator(PythonBuiltinClassType.ContextIterator, getShape(PythonBuiltinClassType.ContextIterator), ctx, kind)); - } - - public final PContextVarsContext copyContextVarsContext(PContextVarsContext original) { - return trace(new PContextVarsContext(original, PythonBuiltinClassType.ContextVarsContext, getShape(PythonBuiltinClassType.ContextVarsContext))); - } - - public final PContextVarsToken createContextVarsToken(PContextVar var, Object oldValue) { - return trace(new PContextVarsToken(var, oldValue, PythonBuiltinClassType.ContextVarsToken, getShape(PythonBuiltinClassType.ContextVarsToken))); - } - - public final PGenericAlias createGenericAlias(Object cls, Object origin, Object arguments, boolean starred) { - PTuple argumentsTuple; - if (arguments instanceof PTuple) { - argumentsTuple = (PTuple) arguments; - } else { - argumentsTuple = createTuple(new Object[]{arguments}); - } - return trace(new PGenericAlias(cls, getShape(cls), origin, argumentsTuple, starred)); - } - - public final PGenericAlias createGenericAlias(Object origin, Object arguments, boolean starred) { - return createGenericAlias(PythonBuiltinClassType.PGenericAlias, origin, arguments, starred); - } - - public final PGenericAlias createGenericAlias(Object origin, Object arguments) { - return createGenericAlias(PythonBuiltinClassType.PGenericAlias, origin, arguments, false); - } - - public final PGenericAliasIterator createGenericAliasIterator(PGenericAlias object) { - PythonBuiltinClassType type = PythonBuiltinClassType.PGenericAliasIterator; - return trace(new PGenericAliasIterator(type, getShape(type), object)); - } - - public final PUnionType createUnionType(Object[] args) { - return trace(new PUnionType(PythonBuiltinClassType.PUnionType, getShape(PythonBuiltinClassType.PUnionType), createTuple(args))); - } - - public final DigestObject createDigestObject(PythonBuiltinClassType type, String name, Object digest) { - return trace(DigestObject.create(type, getShape(type), name, digest)); - } - - public final PyCapsule createCapsuleNativeName(Object pointer, Object name) { - return createCapsule(new PyCapsule.CapsuleData(pointer, name)); - } - - public final PyCapsule createCapsuleJavaName(Object pointer, byte[] name) { - return createCapsule(new PyCapsule.CapsuleData(pointer, new CArrayWrappers.CByteArrayWrapper(name))); - } - - public final PyCapsule createCapsule(PyCapsule.CapsuleData data) { - return trace(new PyCapsule(getLanguage(), data)); - } - - public final MultibyteIncrementalDecoderObject createMultibyteIncrementalDecoderObject(Object type) { - return trace(new MultibyteIncrementalDecoderObject(type, getShape(type))); - } - - public final MultibyteIncrementalEncoderObject createMultibyteIncrementalEncoderObject(Object type) { - return trace(new MultibyteIncrementalEncoderObject(type, getShape(type))); - } - - public final MultibyteStreamReaderObject createMultibyteStreamReaderObject(Object type) { - return trace(new MultibyteStreamReaderObject(type, getShape(type))); - } - - public final MultibyteStreamWriterObject createMultibyteStreamWriterObject(Object type) { - return trace(new MultibyteStreamWriterObject(type, getShape(type))); - } - - public final MultibyteCodecObject createMultibyteCodecObject(Object type, MultibyteCodec codec) { - return trace(new MultibyteCodecObject(type, getShape(type), codec)); - } - - public PAsyncGenASend createAsyncGeneratorASend(PAsyncGen receiver, Object message) { - return trace(new PAsyncGenASend(getLanguage(), receiver, message)); - } - - public PAsyncGenAThrow createAsyncGeneratorAThrow(PAsyncGen receiver, Object arg1, Object arg2, Object arg3) { - return trace(new PAsyncGenAThrow(getLanguage(), receiver, arg1, arg2, arg3)); - } - - public PAsyncGenWrappedValue createAsyncGeneratorWrappedValue(Object wrapped) { - return trace(new PAsyncGenWrappedValue(getLanguage(), wrapped)); - } - - // pickle - - public PPickleBuffer createPickleBuffer(Object view) { - return createPickleBuffer(view, PythonBuiltinClassType.PickleBuffer); - } - - public PPickleBuffer createPickleBuffer(Object view, Object cls) { - return trace(new PPickleBuffer(cls, getShape(cls), view)); - } - - public PPickler createPickler() { - return createPickler(PythonBuiltinClassType.Pickler); - } - - public PPickler createPickler(Object cls) { - return trace(new PPickler(cls, getShape(cls))); - } - - public PUnpickler createUnpickler() { - return createUnpickler(PythonBuiltinClassType.Unpickler); - } - - public PUnpickler createUnpickler(Object cls) { - return trace(new PUnpickler(cls, getShape(cls))); - } - - public PPicklerMemoProxy createPicklerMemoProxy(PPickler pickler) { - return createPicklerMemoProxy(pickler, PythonBuiltinClassType.PicklerMemoProxy); - } - - public PPicklerMemoProxy createPicklerMemoProxy(PPickler pickler, Object cls) { - return trace(new PPicklerMemoProxy(cls, getShape(cls), pickler)); - } - - public PUnpicklerMemoProxy createUnpicklerMemoProxy(PUnpickler unpickler) { - return createUnpicklerMemoProxy(unpickler, PythonBuiltinClassType.UnpicklerMemoProxy); - } - - public PUnpicklerMemoProxy createUnpicklerMemoProxy(PUnpickler unpickler, Object cls) { - return trace(new PUnpicklerMemoProxy(cls, getShape(cls), unpickler)); - } - - public PStruct createStruct(PStruct.StructInfo structInfo) { - return trace(new PStruct(PythonBuiltinClassType.PStruct, getShape(PythonBuiltinClassType.PStruct), structInfo)); - } - - public PStruct createStruct(byte[] format, int size, int len, FormatAlignment formatAlignment, FormatCode[] codes) { - return trace(new PStruct(PythonBuiltinClassType.PStruct, getShape(PythonBuiltinClassType.PStruct), format, size, len, formatAlignment, codes)); - } - - public PStructUnpackIterator createStructUnpackIterator(PStruct struct, Object buffer) { - return trace( - new PStructUnpackIterator(PythonBuiltinClassType.PStructUnpackIterator, getShape(PythonBuiltinClassType.PStructUnpackIterator), struct, buffer)); - } - - public final PTokenizerIter createTokenizerIter(Object cls, String sourceString) { - return trace(new PTokenizerIter(cls, getShape(cls), sourceString)); - } - - @GenerateInline - @GenerateUncached - @GenerateCached(false) - public abstract static class Lazy extends Node { - public static Lazy getUncached() { - return LazyNodeGen.getUncached(); - } - - public final PythonObjectFactory get(Node inliningTarget) { - return execute(inliningTarget); - } - - abstract PythonObjectFactory execute(Node inliningTarget); - - @Specialization - static PythonObjectFactory doIt(@Cached(inline = false) PythonObjectFactory node) { - return node; - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PythonObjectSlowPathFactory.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PythonObjectSlowPathFactory.java deleted file mode 100644 index 57bde9aff7..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PythonObjectSlowPathFactory.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.runtime.object; - -import java.util.Objects; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.instrumentation.AllocationReporter; -import com.oracle.truffle.api.object.Shape; - -/** - * A subclass of {@link PythonObjectFactory} which is basically an uncached version of it but - * directly stores a reference to the {@link AllocationReporter} instead of doing a context lookup - * and getting it from the context. This class is meant to be used on slow path where the context is - * explicitly available. - * - * Objects of this class should not be created directly, but retrieved from - * {@link com.oracle.graal.python.builtins.Python3Core}. Note that - * {@link PythonObjectSlowPathFactory} is context dependent object. It must not be stored in AST or - * in {@link com.oracle.graal.python.PythonLanguage}, for example. - */ -public final class PythonObjectSlowPathFactory extends PythonObjectFactory { - - private final AllocationReporter reporter; - private final PythonLanguage language; - private final SlowPathGetInstanceShapeNode getInstanceShapeNode; - - public PythonObjectSlowPathFactory(AllocationReporter reporter, PythonLanguage language) { - this.reporter = Objects.requireNonNull(reporter); - this.language = language; - this.getInstanceShapeNode = new SlowPathGetInstanceShapeNode(language); - } - - @Override - public PythonLanguage getLanguage() { - return language; - } - - @TruffleBoundary - @Override - protected AllocationReporter executeTrace(Object arg0Value, long arg1Value) { - assert PythonContext.get(null).getAllocationReporter() == reporter; - return PythonObjectFactory.doTrace(arg0Value, arg1Value, reporter); - } - - @TruffleBoundary - @Override - protected Shape executeGetShape(Object arg0Value, boolean arg1Value) { - return getInstanceShapeNode.execute(arg0Value); - } - - @Override - public boolean isAdoptable() { - return false; - } - -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/PSequence.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/PSequence.java index 6b4045453f..a30b321d6e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/PSequence.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/PSequence.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -64,79 +64,79 @@ public PSequence(Object cls, Shape instanceShape) { @ExportMessage @SuppressWarnings("static-method") - public boolean isNumber() { + public final boolean isNumber() { return false; } @ExportMessage @SuppressWarnings("static-method") - public byte asByte() throws UnsupportedMessageException { + public final byte asByte() throws UnsupportedMessageException { throw UnsupportedMessageException.create(); } @ExportMessage @SuppressWarnings("static-method") - public boolean fitsInByte() { + public final boolean fitsInByte() { return false; } @ExportMessage @SuppressWarnings("static-method") - public short asShort() throws UnsupportedMessageException { + public final short asShort() throws UnsupportedMessageException { throw UnsupportedMessageException.create(); } @ExportMessage @SuppressWarnings("static-method") - public boolean fitsInShort() { + public final boolean fitsInShort() { return false; } @ExportMessage @SuppressWarnings("static-method") - public int asInt() throws UnsupportedMessageException { + public final int asInt() throws UnsupportedMessageException { throw UnsupportedMessageException.create(); } @ExportMessage @SuppressWarnings("static-method") - public boolean fitsInInt() { + public final boolean fitsInInt() { return false; } @ExportMessage @SuppressWarnings("static-method") - public long asLong() throws UnsupportedMessageException { + public final long asLong() throws UnsupportedMessageException { throw UnsupportedMessageException.create(); } @ExportMessage @SuppressWarnings("static-method") - public boolean fitsInLong() { + public final boolean fitsInLong() { return false; } @ExportMessage @SuppressWarnings("static-method") - public float asFloat() throws UnsupportedMessageException { + public final float asFloat() throws UnsupportedMessageException { throw UnsupportedMessageException.create(); } @ExportMessage @SuppressWarnings("static-method") - public boolean fitsInFloat() { + public final boolean fitsInFloat() { return false; } @ExportMessage @SuppressWarnings("static-method") - public double asDouble() throws UnsupportedMessageException { + public final double asDouble() throws UnsupportedMessageException { throw UnsupportedMessageException.create(); } @ExportMessage @SuppressWarnings("static-method") - public boolean fitsInDouble() { + public final boolean fitsInDouble() { return false; } @@ -148,17 +148,17 @@ public boolean isString() { @ExportMessage @SuppressWarnings("static-method") - public String asString() throws UnsupportedMessageException { + public final String asString() throws UnsupportedMessageException { throw UnsupportedMessageException.create(); } @ExportMessage - public boolean hasArrayElements() { + public final boolean hasArrayElements() { return true; } @ExportMessage - public long getArraySize(@Bind("$node") Node inliningTarget, + public final long getArraySize(@Bind("$node") Node inliningTarget, @Exclusive @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode, @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); @@ -170,7 +170,7 @@ public long getArraySize(@Bind("$node") Node inliningTarget, } @ExportMessage - public Object readArrayElement(long index, + public final Object readArrayElement(long index, @Bind("$node") Node inliningTarget, @Exclusive @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode, @Exclusive @Cached SequenceStorageNodes.GetItemScalarNode getItem, @@ -189,7 +189,7 @@ public Object readArrayElement(long index, } @ExportMessage - public void writeArrayElement(long index, Object value, + public final void writeArrayElement(long index, Object value, @Bind("$node") Node inliningTarget, @Exclusive @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode, @Exclusive @Cached PForeignToPTypeNode convert, @@ -209,7 +209,7 @@ public void writeArrayElement(long index, Object value, } @ExportMessage - public void removeArrayElement(long index, + public final void removeArrayElement(long index, @Bind("$node") Node inliningTarget, @Exclusive @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode, @Exclusive @Cached SequenceStorageNodes.DeleteItemNode delItem, @@ -228,7 +228,7 @@ public void removeArrayElement(long index, } @ExportMessage - public boolean isArrayElementReadable(long idx, + public final boolean isArrayElementReadable(long idx, @Bind("$node") Node inliningTarget, @Exclusive @Cached SequenceNodes.IsInBoundsNode isInBoundsNode, @Exclusive @Cached GilNode gil) { @@ -241,7 +241,7 @@ public boolean isArrayElementReadable(long idx, } @ExportMessage - public boolean isArrayElementModifiable(long idx, + public final boolean isArrayElementModifiable(long idx, @Bind("$node") Node inliningTarget, @Exclusive @Cached SequenceNodes.IsInBoundsNode isInBoundsNode, @Exclusive @Cached GilNode gil) { @@ -254,7 +254,7 @@ public boolean isArrayElementModifiable(long idx, } @ExportMessage - public boolean isArrayElementInsertable(long idx, + public final boolean isArrayElementInsertable(long idx, @Bind("$node") Node inliningTarget, @Exclusive @Cached SequenceNodes.IsInBoundsNode isInBoundsNode, @Exclusive @Cached GilNode gil) { @@ -267,7 +267,7 @@ public boolean isArrayElementInsertable(long idx, } @ExportMessage - public boolean isArrayElementRemovable(long idx, + public final boolean isArrayElementRemovable(long idx, @Bind("$node") Node inliningTarget, @Exclusive @Cached SequenceNodes.IsInBoundsNode isInBoundsNode, @Exclusive @Cached GilNode gil) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/BoolSequenceStorage.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/BoolSequenceStorage.java index 3ac38dc127..30f226b7da 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/BoolSequenceStorage.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/BoolSequenceStorage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -25,10 +25,9 @@ */ package com.oracle.graal.python.runtime.sequence.storage; +import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; -import java.util.Arrays; - public final class BoolSequenceStorage extends ArrayBasedSequenceStorage { private boolean[] values; @@ -54,7 +53,7 @@ public BoolSequenceStorage(int capacity) { } private void increaseCapacityExactWithCopy(int newCapacity) { - values = Arrays.copyOf(values, newCapacity); + values = PythonUtils.arrayCopyOf(values, newCapacity); capacity = values.length; } @@ -119,7 +118,7 @@ public Object getInternalArrayObject() { @Override public Object getCopyOfInternalArrayObject() { - return Arrays.copyOf(values, length); + return PythonUtils.arrayCopyOf(values, length); } public Object[] getCopyOfInternalArray() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/ByteSequenceStorage.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/ByteSequenceStorage.java index 43fdab4a8e..23d8a0ab96 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/ByteSequenceStorage.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/ByteSequenceStorage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -57,7 +57,7 @@ public ByteSequenceStorage(int capacity) { } private void increaseCapacityExactWithCopy(int newCapacity) { - values = Arrays.copyOf(values, newCapacity); + values = PythonUtils.arrayCopyOf(values, newCapacity); capacity = values.length; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/DoubleSequenceStorage.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/DoubleSequenceStorage.java index 9a878a285d..b8987eebc9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/DoubleSequenceStorage.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/DoubleSequenceStorage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -25,10 +25,11 @@ */ package com.oracle.graal.python.runtime.sequence.storage; -import com.oracle.truffle.api.CompilerDirectives; - import java.util.Arrays; +import com.oracle.graal.python.util.PythonUtils; +import com.oracle.truffle.api.CompilerDirectives; + public final class DoubleSequenceStorage extends ArrayBasedSequenceStorage { private double[] values; @@ -56,7 +57,7 @@ public DoubleSequenceStorage(int capacity) { } private void increaseCapacityExactWithCopy(int newCapacity) { - values = Arrays.copyOf(values, newCapacity); + values = PythonUtils.arrayCopyOf(values, newCapacity); capacity = values.length; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/ForeignSequenceStorage.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/ForeignSequenceStorage.java index 427909f13f..95dca71385 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/ForeignSequenceStorage.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/ForeignSequenceStorage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,6 +40,9 @@ */ package com.oracle.graal.python.runtime.sequence.storage; +import static com.oracle.graal.python.runtime.exception.PythonErrorType.IndexError; +import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; + import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; @@ -63,9 +66,6 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.IndexError; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; - /* * NOTE: We are not using IndirectCallContext here in this file because it seems unlikely that these interop messages * would call back to Python and that we would also need precise frame info for that case. @@ -131,14 +131,14 @@ public abstract static class ReadNoConversionNode extends PNodeWithContext { static Object read(Node inliningTarget, ForeignSequenceStorage storage, int index, @CachedLibrary(limit = "getCallSiteInlineCacheMaxDepth()") InteropLibrary interop, @Cached(inline = false) GilNode gil, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { gil.release(true); try { return interop.readArrayElement(storage.foreignArray, index); } catch (UnsupportedMessageException ex) { - throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.ITEM_S_OF_S_OBJ_IS_NOT_READABLE, index, storage.foreignArray); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.ITEM_S_OF_S_OBJ_IS_NOT_READABLE, index, storage.foreignArray); } catch (InvalidArrayIndexException ex) { - throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.INVALID_INDEX_S, index); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.INVALID_INDEX_S, index); } finally { gil.acquire(); } @@ -172,16 +172,16 @@ public abstract static class WriteNode extends PNodeWithContext { static void write(Node inliningTarget, ForeignSequenceStorage storage, int index, Object value, @CachedLibrary(limit = "getCallSiteInlineCacheMaxDepth()") InteropLibrary interop, @Cached(inline = false) GilNode gil, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { gil.release(true); try { interop.writeArrayElement(storage.foreignArray, index, value); } catch (InvalidArrayIndexException e) { - throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.INVALID_INDEX_S, index); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.INVALID_INDEX_S, index); } catch (UnsupportedMessageException e) { - throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.ITEM_S_OF_S_OBJ_IS_NOT_WRITABLE, index, storage.foreignArray); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.ITEM_S_OF_S_OBJ_IS_NOT_WRITABLE, index, storage.foreignArray); } catch (UnsupportedTypeException e) { - throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.TYPE_P_NOT_SUPPORTED_BY_FOREIGN_OBJ, value); + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TYPE_P_NOT_SUPPORTED_BY_FOREIGN_OBJ, value); } finally { gil.acquire(); } @@ -199,12 +199,12 @@ public abstract static class RemoveNode extends PNodeWithContext { static void remove(Node inliningTarget, ForeignSequenceStorage storage, int index, @CachedLibrary(limit = "getCallSiteInlineCacheMaxDepth()") InteropLibrary interop, @Cached(inline = false) GilNode gil, - @Cached PRaiseNode.Lazy raiseNode) { + @Cached PRaiseNode raiseNode) { gil.release(true); try { interop.removeArrayElement(storage.foreignArray, index); } catch (InvalidArrayIndexException | UnsupportedMessageException e) { - throw raiseNode.get(inliningTarget).raise(IndexError, ErrorMessages.ITEM_S_OF_S_OBJ_IS_NOT_REMOVABLE, index, storage.foreignArray); + throw raiseNode.raise(inliningTarget, IndexError, ErrorMessages.ITEM_S_OF_S_OBJ_IS_NOT_REMOVABLE, index, storage.foreignArray); } finally { gil.acquire(); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/IntSequenceStorage.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/IntSequenceStorage.java index e102939517..30f813598b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/IntSequenceStorage.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/IntSequenceStorage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -25,10 +25,11 @@ */ package com.oracle.graal.python.runtime.sequence.storage; -import com.oracle.truffle.api.CompilerDirectives; - import java.util.Arrays; +import com.oracle.graal.python.util.PythonUtils; +import com.oracle.truffle.api.CompilerDirectives; + public final class IntSequenceStorage extends ArrayBasedSequenceStorage { private int[] values; @@ -56,7 +57,7 @@ public IntSequenceStorage(int capacity) { } private void increaseCapacityExactWithCopy(int newCapacity) { - values = Arrays.copyOf(values, newCapacity); + values = PythonUtils.arrayCopyOf(values, newCapacity); capacity = values.length; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/LongSequenceStorage.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/LongSequenceStorage.java index b52677fb63..55bbe3db42 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/LongSequenceStorage.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/LongSequenceStorage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -25,10 +25,11 @@ */ package com.oracle.graal.python.runtime.sequence.storage; -import com.oracle.truffle.api.CompilerDirectives; - import java.util.Arrays; +import com.oracle.graal.python.util.PythonUtils; +import com.oracle.truffle.api.CompilerDirectives; + public final class LongSequenceStorage extends ArrayBasedSequenceStorage { private long[] values; @@ -56,7 +57,7 @@ public LongSequenceStorage(int capacity) { } private void increaseCapacityExactWithCopy(int newCapacity) { - values = Arrays.copyOf(values, newCapacity); + values = PythonUtils.arrayCopyOf(values, newCapacity); capacity = values.length; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/ComparisonOp.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/ComparisonOp.java deleted file mode 100644 index 91d538fd2f..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/ComparisonOp.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.util; - -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EQ__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___GT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LE__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___LT__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NE__; - -import com.oracle.truffle.api.CompilerDirectives; - -public enum ComparisonOp { - - EQ(J___EQ__, 2, a -> a == 0), - NE(J___NE__, 3, a -> a != 0), - LT(J___LT__, 0, a -> a < 0), - GT(J___GT__, 4, a -> a > 0), - LE(J___LE__, 1, a -> a <= 0), - GE(J___GE__, 5, a -> a >= 0); - - public final String builtinName; - /** - * The integer code of the operation as used by CPython (and in native code). - */ - public final int opCode; - public final IntPredicate intPredicate; - - ComparisonOp(String builtinName, int opCode, IntPredicate intPredicate) { - this.builtinName = builtinName; - this.opCode = opCode; - this.intPredicate = intPredicate; - } - - public boolean cmpResultToBool(int cmpResult) { - return intPredicate.test(cmpResult); - } - - public boolean isEqualityOp() { - return this == EQ || this == NE; - } - - public static boolean isEqualityOpCode(int op) { - assert EQ.opCode == 2 && NE.opCode == 3; - return op == 2 || op == 3; - } - - public static ComparisonOp fromOpCode(int op) { - ComparisonOp result; - switch (op) { - case 0: - result = LT; - break; - case 1: - result = LE; - break; - case 2: - result = EQ; - break; - case 3: - result = NE; - break; - case 4: - result = GT; - break; - case 5: - result = GE; - break; - default: - CompilerDirectives.transferToInterpreterAndInvalidate(); - throw CompilerDirectives.shouldNotReachHere("unexpected operation: " + op); - } - assert result.opCode == op; - return result; - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/NumericSupport.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/NumericSupport.java index 1d99d9a29f..adba7ba6bc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/NumericSupport.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/NumericSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -127,7 +127,7 @@ static short floatToShortBits(double value, Node raisingNode) { e = (int) fraction[1]; if (f < 0.5 || f >= 1.0) { - throw PRaiseNode.raiseUncached(raisingNode, SystemError, RES_O_O_RANGE, "frexp()"); + throw PRaiseNode.raiseStatic(raisingNode, SystemError, RES_O_O_RANGE, "frexp()"); } // Normalize f to be in the range [1.0, 2.0) @@ -135,7 +135,7 @@ static short floatToShortBits(double value, Node raisingNode) { e--; if (e >= 16) { - throw PRaiseNode.raiseUncached(raisingNode, OverflowError, FLOAT_TO_LARGE_TO_PACK_WITH_S_FMT, "e"); + throw PRaiseNode.raiseStatic(raisingNode, OverflowError, FLOAT_TO_LARGE_TO_PACK_WITH_S_FMT, "e"); } else if (e < -25) { // |x| < 2**-25. Underflow to zero. f = 0.0; @@ -162,7 +162,7 @@ static short floatToShortBits(double value, Node raisingNode) { bits = 0; ++e; if (e == 31) { - throw PRaiseNode.raiseUncached(raisingNode, OverflowError, FLOAT_TO_LARGE_TO_PACK_WITH_S_FMT, "e"); + throw PRaiseNode.raiseStatic(raisingNode, OverflowError, FLOAT_TO_LARGE_TO_PACK_WITH_S_FMT, "e"); } } } @@ -391,7 +391,7 @@ public double getDouble(byte[] buffer, int index, int numBytes) throws IndexOutO } } - public void putDouble(Node inliningTarget, byte[] buffer, int index, double value, int numBytes, PRaiseNode.Lazy raiseNode) throws IndexOutOfBoundsException { + public void putDouble(Node inliningTarget, byte[] buffer, int index, double value, int numBytes, PRaiseNode raiseNode) throws IndexOutOfBoundsException { switch (numBytes) { case 2: putHalfFloat(buffer, index, value, inliningTarget); @@ -399,7 +399,7 @@ public void putDouble(Node inliningTarget, byte[] buffer, int index, double valu case 4: final float fValue = (float) value; if (Float.isInfinite(fValue) && Double.isFinite(value)) { - throw raiseNode.get(inliningTarget).raise(OverflowError, FLOAT_TO_LARGE_TO_PACK_WITH_S_FMT, "f"); + throw raiseNode.raise(inliningTarget, OverflowError, FLOAT_TO_LARGE_TO_PACK_WITH_S_FMT, "f"); } putFloat(buffer, index, fValue); break; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/PythonUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/PythonUtils.java index 00c43e123d..90b9798b8e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/PythonUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/PythonUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,8 +42,6 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PString; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; -import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__; -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___NEW__; import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING; import static com.oracle.truffle.api.CompilerDirectives.shouldNotReachHere; @@ -64,30 +62,26 @@ import javax.management.ObjectName; import javax.management.ReflectionException; -import org.graalvm.nativeimage.ImageInfo; import org.graalvm.nativeimage.VMRuntime; import org.graalvm.polyglot.io.ByteSequence; import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.Builtin; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod; import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; -import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.pegparser.scope.ScopeEnvironment; import com.oracle.graal.python.pegparser.sst.ConstantValue; -import com.oracle.graal.python.runtime.object.PythonObjectFactory; -import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory; +import com.oracle.graal.python.runtime.PythonOptions; +import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; @@ -223,7 +217,7 @@ public static TruffleString[] toTruffleStringArrayUncached(String[] s) { /** * Creates an array of {@link Object}'s. The intended use of this method is in slow-path in - * calls to methods like {@link PythonObjectFactory#createTuple(Object[])}. + * calls to methods like {@link PFactory#createTuple}. */ public static Object[] convertToObjectArray(TruffleString[] src) { if (src == null) { @@ -472,7 +466,7 @@ public static int toIntError(long x) { int r = (int) x; if (r != x) { CompilerDirectives.transferToInterpreterAndInvalidate(); - throw PRaiseNode.raiseUncached(null, SystemError, ErrorMessages.INTERNAL_INT_OVERFLOW); + throw PRaiseNode.raiseStatic(null, SystemError, ErrorMessages.INTERNAL_INT_OVERFLOW); } return r; } @@ -514,7 +508,7 @@ public static boolean isDivisible(int number, int twoExponent) { private static final ObjectName OBJECT_NAME; static { - if (ImageInfo.inImageCode()) { + if (TruffleOptions.AOT) { OBJECT_NAME = null; SERVER = null; } else { @@ -547,7 +541,7 @@ public static void forceFullGC() { @TruffleBoundary public static void dumpHeap(String path) { - if (ImageInfo.inImageCode()) { + if (TruffleOptions.AOT) { try { VMRuntime.dumpHeap(path, true); } catch (UnsupportedOperationException | IOException e) { @@ -697,39 +691,21 @@ public static PBuiltinFunction createMethod(PythonLanguage language, Object klas Class nodeClass = nodeFactory.getNodeClass(); Builtin builtin = nodeClass.getAnnotation(Builtin.class); RootCallTarget callTarget = language.createCachedCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, nodeFactory, true), nodeClass); - return createMethod(PythonObjectFactory.getUncached(), klass, builtin, callTarget, type, numDefaults); + return createMethod(klass, builtin, callTarget, type, numDefaults); } @TruffleBoundary - public static PBuiltinFunction createMethod(PythonObjectFactory factory, Object klass, Builtin builtin, RootCallTarget callTarget, Object type, - int numDefaults) { + public static PBuiltinFunction createMethod(Object klass, Builtin builtin, RootCallTarget callTarget, Object type, int numDefaults) { assert callTarget.getRootNode() instanceof BuiltinFunctionRootNode r && r.getBuiltin() == builtin; int flags = PBuiltinFunction.getFlags(builtin, callTarget); TruffleString name = toTruffleStringUncached(builtin.name()); - PBuiltinFunction function = factory.createBuiltinFunction(name, type, numDefaults, flags, callTarget); + PBuiltinFunction function = PFactory.createBuiltinFunction(PythonLanguage.get(null), name, type, numDefaults, flags, callTarget); if (klass != null) { WriteAttributeToObjectNode.getUncached(true).execute(klass, name, function); } return function; } - @TruffleBoundary - public static void createConstructor(PythonObjectSlowPathFactory factory, Object klass, Builtin builtin, RootCallTarget callTarget) { - assert J___NEW__.equals(builtin.name()); - assert IsSubtypeNode.getUncached().execute(klass, PythonBuiltinClassType.PTuple); - int flags = PBuiltinFunction.getFlags(builtin, callTarget); - PBuiltinFunction function = factory.createBuiltinFunction(toTruffleStringUncached(builtin.name()), PythonBuiltinClassType.PTuple, 1, flags, callTarget); - PBuiltinMethod method = factory.createBuiltinMethod(PythonBuiltinClassType.PTuple, function); - WriteAttributeToObjectNode.getUncached(true).execute(klass, T___NEW__, method); - } - - private static Object[] createCalltargetKeys(Object[] callTargetCacheKeys, Class nodeClass) { - Object[] keys = new Object[callTargetCacheKeys.length + 1]; - keys[0] = nodeClass; - arraycopy(callTargetCacheKeys, 0, keys, 1, callTargetCacheKeys.length); - return keys; - } - public static Unsafe initUnsafe() { try { return Unsafe.getUnsafe(); @@ -779,7 +755,12 @@ public static Source createFakeSource() { @TruffleBoundary public static Source createFakeSource(TruffleString name) { - return Source.newBuilder(PythonLanguage.ID, EMPTY_BYTE_SEQUENCE, name.toJavaStringUncached()).build(); + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { + // The DSL interpreter requires character-based sources. + return Source.newBuilder(PythonLanguage.ID, "", name.toJavaStringUncached()).content(Source.CONTENT_NONE).build(); + } else { + return Source.newBuilder(PythonLanguage.ID, EMPTY_BYTE_SEQUENCE, name.toJavaStringUncached()).build(); + } } public static Object[] prependArgument(Object primary, Object[] arguments) { @@ -842,7 +823,7 @@ public boolean isOverLimit() { } } - public static Object pythonObjectFromConstantValue(ConstantValue v, PythonObjectFactory factory) { + public static Object pythonObjectFromConstantValue(ConstantValue v) { switch (v.kind) { case BOOLEAN: return v.getBoolean(); @@ -857,16 +838,16 @@ public static Object pythonObjectFromConstantValue(ConstantValue v, PythonObject return v.getDouble(); case COMPLEX: { double[] c = v.getComplex(); - return factory.createComplex(c[0], c[1]); + return PFactory.createComplex(PythonLanguage.get(null), c[0], c[1]); } case NONE: return PNone.NONE; case ELLIPSIS: return PEllipsis.INSTANCE; case BIGINTEGER: - return factory.createInt(v.getBigInteger()); + return PFactory.createInt(PythonLanguage.get(null), v.getBigInteger()); case BYTES: - return factory.createBytes(v.getBytes()); + return PFactory.createBytes(PythonLanguage.get(null), v.getBytes()); case RAW: return v.getRaw(TruffleString.class); case TUPLE: diff --git a/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/ManageResourcesMojo.java b/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/AbstractGraalPyMojo.java similarity index 88% rename from graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/ManageResourcesMojo.java rename to graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/AbstractGraalPyMojo.java index bc2b69ceae..b81bf0fa00 100644 --- a/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/ManageResourcesMojo.java +++ b/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/AbstractGraalPyMojo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,14 +40,6 @@ */ package org.graalvm.python.maven.plugin; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; -import java.util.stream.Collectors; - import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.artifact.handler.DefaultArtifactHandler; @@ -55,22 +47,23 @@ import org.apache.maven.model.Resource; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; - -import org.apache.maven.plugins.annotations.*; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.*; import org.eclipse.aether.graph.Dependency; import org.graalvm.python.embedding.tools.vfs.VFSUtils; -import static org.graalvm.python.embedding.tools.vfs.VFSUtils.GRAALPY_GROUP_ID; -import static org.graalvm.python.embedding.tools.vfs.VFSUtils.LAUNCHER_NAME; -import static org.graalvm.python.embedding.tools.vfs.VFSUtils.VFS_ROOT; -import static org.graalvm.python.embedding.tools.vfs.VFSUtils.VFS_VENV; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Collectors; +import static org.graalvm.python.embedding.tools.vfs.VFSUtils.*; -@Mojo(name = "process-graalpy-resources", defaultPhase = LifecyclePhase.PROCESS_RESOURCES, - requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME, - requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME) -public class ManageResourcesMojo extends AbstractMojo { +public abstract class AbstractGraalPyMojo extends AbstractMojo { private static final String PYTHON_LAUNCHER_ARTIFACT_ID = "python-launcher"; @@ -85,11 +78,14 @@ public class ManageResourcesMojo extends AbstractMojo { @Parameter String pythonResourcesDirectory; - @Parameter + @Parameter(property = "externalDirectory") String externalDirectory; - @Parameter + @Parameter(property = "resourceDirectory") String resourceDirectory; + + @Parameter(property = "graalPyLockFile", defaultValue = "graalpy.lock") + String graalPyLockFile; @Parameter List packages; @@ -110,18 +106,31 @@ public static class PythonHome { private Set launcherClassPath; - private static String normalizeEmpty(String s) { - if (s == null) { - return s; + protected void manageNativeImageConfig() throws MojoExecutionException { + try { + VFSUtils.writeNativeImageConfig(Path.of(project.getBuild().getOutputDirectory(), "META-INF"), GRAALPY_MAVEN_PLUGIN_ARTIFACT_ID, resourceDirectory); + } catch (IOException e) { + throw new MojoExecutionException("failed to create native image configuration files", e); } - String trimmed = s.trim(); - return trimmed.isEmpty() ? null : trimmed; } - public void execute() throws MojoExecutionException { + protected void listGraalPyResources() throws MojoExecutionException { + Path vfs = Path.of(project.getBuild().getOutputDirectory(), resourceDirectory); + if (Files.exists(vfs)) { + try { + VFSUtils.generateVFSFilesList(Path.of(project.getBuild().getOutputDirectory()), vfs); + } catch (IOException e) { + throw new MojoExecutionException(String.format("Failed to generate files list in '%s'", vfs), e); + } + } + } + + protected void preExec(boolean enableWarnings) throws MojoExecutionException { pythonResourcesDirectory = normalizeEmpty(pythonResourcesDirectory); externalDirectory = normalizeEmpty(externalDirectory); resourceDirectory = normalizeEmpty(resourceDirectory); + graalPyLockFile = normalizeEmpty(graalPyLockFile); + packages = packages != null ? packages.stream().filter(p -> p != null && !p.trim().isEmpty()).toList() : Collections.EMPTY_LIST; if(pythonResourcesDirectory != null) { if (externalDirectory != null) { @@ -145,7 +154,7 @@ public void execute() throws MojoExecutionException { } if (resourceDirectory == null) { - if (externalDirectory != null) { + if (enableWarnings && externalDirectory == null) { getLog().info(String.format("Virtual filesystem is deployed to default resources directory '%s'. " + "This can cause conflicts if used with other Java libraries that also deploy GraalPy virtual filesystem. " + "Consider adding GRAALPY-VFS/${project.groupId}/${project.artifactId} to your pom.xml, " + @@ -158,17 +167,15 @@ public void execute() throws MojoExecutionException { resourceDirectory = VFS_ROOT; } - if(pythonHome != null) { + if(enableWarnings && pythonHome != null) { getLog().warn("The GraalPy plugin configuration setting was deprecated and has no effect anymore.\n" + "For execution in jvm mode, the python language home is always available.\n" + "When building a native executable using GraalVM Native Image, then the full python language home is by default embedded into the native executable.\n" + - "For more details, please refer to the documentation of GraalVM Native Image options IncludeLanguageResources and CopyLanguageResources documentation."); + "For more details, please refer to the documentation of GraalVM Native Image options IncludeLanguageResources and CopyLanguageResources."); } - - manageVenv(); - listGraalPyResources(); - manageNativeImageConfig(); - + } + + protected void postExec() throws MojoExecutionException { for(Resource r : project.getBuild().getResources()) { if (Files.exists(Path.of(r.getDirectory(), resourceDirectory, "proj"))) { getLog().warn(String.format("usage of %s is deprecated, use %s instead", Path.of(resourceDirectory, "proj"), Path.of(resourceDirectory, "src"))); @@ -178,7 +185,7 @@ public void execute() throws MojoExecutionException { // => looks like a project created < 24.1.0 throw new MojoExecutionException(String.format( "Wrong virtual filesystem root!\n" + - "Since 24.1.0 the virtual filesystem root has to be '%s'.\n" + + "Since 24.1.0 the virtual filesystem root has to be '%s'.\n" + "Please rename the resource directory '%s' to '%s'", resourceDirectory, Path.of(r.getDirectory(), "vfs"), Path.of(r.getDirectory(), resourceDirectory))); } Path srcPath = Path.of(r.getDirectory(), resourceDirectory, "src"); @@ -193,46 +200,41 @@ public void execute() throws MojoExecutionException { )); } } - - } - - private void manageNativeImageConfig() throws MojoExecutionException { - try { - VFSUtils.writeNativeImageConfig(Path.of(project.getBuild().getOutputDirectory(), "META-INF"), GRAALPY_MAVEN_PLUGIN_ARTIFACT_ID, resourceDirectory); - } catch (IOException e) { - throw new MojoExecutionException("failed to create native image configuration files", e); - } } - private void listGraalPyResources() throws MojoExecutionException { - Path vfs = Path.of(project.getBuild().getOutputDirectory(), resourceDirectory); - if (Files.exists(vfs)) { - try { - VFSUtils.generateVFSFilesList(Path.of(project.getBuild().getOutputDirectory()), vfs); - } catch (IOException e) { - throw new MojoExecutionException(String.format("Failed to generate files list in '%s'", vfs), e); - } - } - } - - private void manageVenv() throws MojoExecutionException { + protected Path getVenvDirectory() { Path venvDirectory; if(externalDirectory == null) { venvDirectory = Path.of(project.getBuild().getOutputDirectory(), resourceDirectory, VFS_VENV); } else { venvDirectory = Path.of(externalDirectory, VFS_VENV); } + return venvDirectory; + } - try { - if (packages == null && externalDirectory == null) { - getLog().info(String.format("No venv packages declared, deleting %s", venvDirectory)); - delete(venvDirectory); - return; + private static String normalizeEmpty(String s) { + if (s == null) { + return s; + } + String trimmed = s.trim(); + return trimmed.isEmpty() ? null : trimmed; + } + + protected Launcher createLauncher() { + Launcher launcherArg = new Launcher(getLauncherPath()) { + public Set computeClassPath() throws IOException { + return calculateLauncherClasspath(project); } + }; + return launcherArg; + } - VFSUtils.createVenv(venvDirectory, new ArrayList(packages), getLauncherPath(), () -> calculateLauncherClasspath(project), getGraalPyVersion(project), new MavenDelegateLog(getLog()), (s) -> getLog().info(s)); - } catch (IOException e) { - throw new MojoExecutionException(String.format("failed to create venv %s", venvDirectory), e); + protected Path getLockFile() { + Path rfp = Path.of(graalPyLockFile); + if(rfp.isAbsolute()) { + return rfp; + } else { + return project.getBasedir().toPath().resolve(graalPyLockFile); } } @@ -252,7 +254,7 @@ private Path getLauncherPath() { return Paths.get(project.getBuild().getDirectory(), LAUNCHER_NAME); } - private static String getGraalPyVersion(MavenProject project) throws IOException { + protected static String getGraalPyVersion(MavenProject project) throws IOException { DefaultArtifact a = (DefaultArtifact) getGraalPyArtifact(project); String version = a.getVersion(); if(a.isSnapshot()) { diff --git a/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/InstallPackagesMojo.java b/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/InstallPackagesMojo.java new file mode 100644 index 0000000000..8f415a72c6 --- /dev/null +++ b/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/InstallPackagesMojo.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.python.maven.plugin; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.graalvm.python.embedding.tools.vfs.VFSUtils; +import org.graalvm.python.embedding.tools.vfs.VFSUtils.PackagesChangedException; + +import java.io.IOException; +import java.nio.file.Path; + +@Mojo(name = "process-graalpy-resources", defaultPhase = LifecyclePhase.PROCESS_RESOURCES, + requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME, + requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME) +public class InstallPackagesMojo extends AbstractGraalPyMojo { + + private static final String PACKAGES_CHANGED_ERROR = """ + + Install of python packages is based on lock file %s, + but packages and their version constraints in graalpy-maven-plugin configuration are different then previously used to generate the lock file. + + Packages currently declared in graalpy-maven-plugin configuration: %s + Packages which were used to generate the lock file: %s + + The lock file has to be refreshed by running the maven goal 'org.graalvm.python:graalpy-maven-plugin:lock-packages'. + + For more information, please refer to https://www.graalvm.org/latest/reference-manual/python/Embedding-Build-Tools#Python-Dependency-Management + """; + + protected static final String MISSING_LOCK_FILE_WARNING = """ + + The list of installed Python packages does not match the packages specified in the graalpy-maven-plugin configuration. + This could indicate that either extra dependencies were installed or some packages were installed with a more specific versions than declared. + + In such cases, it is strongly recommended to lock the Python dependencies by executing the Maven goal 'org.graalvm.python:graalpy-maven-plugin:lock-packages'. + + For more details on managing Python dependencies, please refer to https://www.graalvm.org/latest/reference-manual/python/Embedding-Build-Tools#Python-Dependency-Management + + """; + + public void execute() throws MojoExecutionException { + preExec(true); + + manageVenv(); + listGraalPyResources(); + manageNativeImageConfig(); + + postExec(); + } + + private void manageVenv() throws MojoExecutionException { + Path venvDirectory = getVenvDirectory(); + MavenDelegateLog log = new MavenDelegateLog(getLog()); + Path lockFile = getLockFile(); + try { + VFSUtils.createVenv(venvDirectory, packages, lockFile, MISSING_LOCK_FILE_WARNING, createLauncher(), getGraalPyVersion(project), log); + } catch(PackagesChangedException pce) { + String pluginPkgsString = pce.getPluginPackages().isEmpty() ? "None" : String.join(", ", pce.getPluginPackages()); + String lockFilePkgsString = pce.getLockFilePackages().isEmpty() ? "None" : String.join(", ", pce.getLockFilePackages()); + throw new MojoExecutionException(String.format(PACKAGES_CHANGED_ERROR, lockFile, pluginPkgsString, lockFilePkgsString)); + } catch (IOException e) { + throw new MojoExecutionException(String.format("failed to create venv %s", venvDirectory), e); + } + } + +} diff --git a/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/LockPackagesMojo.java b/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/LockPackagesMojo.java new file mode 100644 index 0000000000..c0bea2e693 --- /dev/null +++ b/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/LockPackagesMojo.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.graalvm.python.maven.plugin; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.ResolutionScope; + +import org.graalvm.python.embedding.tools.vfs.VFSUtils; + +import java.io.IOException; +import java.nio.file.Path; + +@Mojo(name = "lock-packages", + requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME, + requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME) +public class LockPackagesMojo extends AbstractGraalPyMojo { + + protected static final String LOCK_FILE_HEADER = """ + This file was generated by maven goal 'org.graalvm.python:graalpy-maven-plugin:lock-packages'. + + WARNING: Any manual changes are done at your own risk and will be overwritten when the goal is executed. + + This file is meant to be tracked in a version control system. + + This file contains a list of all required Python packages with their specific versions, + based on the packages defined in the plugin configuration and their dependencies. + """; + + public void execute() throws MojoExecutionException { + preExec(false); + checkEmptyPackages(); + + manageVenv(); + listGraalPyResources(); + + postExec(); + } + + protected void manageVenv() throws MojoExecutionException { + Path venvDirectory = getVenvDirectory(); + MavenDelegateLog log = new MavenDelegateLog(getLog()); + Path requirements = getLockFile(); + + try { + VFSUtils.lockPackages(venvDirectory, packages, requirements, LOCK_FILE_HEADER, createLauncher(), getGraalPyVersion(project), log); + } catch (IOException e) { + throw new MojoExecutionException(String.format("failed to create venv %s", venvDirectory), e); + } + } + + private void checkEmptyPackages() throws MojoExecutionException { + if((packages == null || packages.isEmpty())) { + getLog().error(""); + getLog().error("In order to run the lock-packages goal there have to be python packages declared in the graalpy-maven-plugin configuration."); + getLog().error(""); + getLog().error("NOTE that the section has to be declared for the whole graalpy-maven-plugin"); + getLog().error("and not specifically for the process-graalpy-resources execution goal."); + getLog().error(""); + getLog().error("Please add the section to your configuration as follows:"); + getLog().error(""); + getLog().error(" org.graalvm.python"); + getLog().error(" graalpy-maven-plugin"); + getLog().error(" "); + getLog().error(" "); + getLog().error(" {package_name}=={package_version}"); + getLog().error(" "); + getLog().error(" ..."); + getLog().error(" "); + getLog().error(""); + + getLog().error("For more information, please refer to https://github.com/oracle/graalpython/blob/master/docs/user/Embedding-Build-Tools.md"); + getLog().error(""); + + throw new MojoExecutionException("missing python packages in plugin configuration"); + } + } +} diff --git a/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/MavenDelegateLog.java b/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/MavenDelegateLog.java index 139f7b13fa..052ce093e6 100644 --- a/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/MavenDelegateLog.java +++ b/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/MavenDelegateLog.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,20 +41,73 @@ package org.graalvm.python.maven.plugin; import org.apache.maven.plugin.logging.Log; -import org.graalvm.python.embedding.tools.exec.SubprocessLog; +import org.graalvm.python.embedding.tools.exec.BuildToolLog; -final class MavenDelegateLog implements SubprocessLog { +final class MavenDelegateLog implements BuildToolLog { private final Log delegate; MavenDelegateLog(Log delegate) { this.delegate = delegate; } - public void log(CharSequence var1) { - delegate.info(var1); + @Override + public void info(String txt) { + delegate.info(txt); } - public void log(CharSequence var1, Throwable t) { - delegate.error(var1, t); + @Override + public void warning(String txt) { + delegate.warn(txt); + } + + @Override + public void warning(String txt, Throwable t) { + delegate.warn(txt, t); + } + + @Override + public void error(String txt) { + delegate.error(txt); + } + + @Override + public void debug(String txt) { + delegate.debug(txt); + } + + @Override + public void subProcessOut(String out) { + // don't annotate output with [INFO] + System.out.println(out); + } + + @Override + public void subProcessErr(String err) { + delegate.error(err); + } + + @Override + public boolean isDebugEnabled() { + return delegate.isDebugEnabled(); + } + + @Override + public boolean isWarningEnabled() { + return delegate.isWarnEnabled(); + } + + @Override + public boolean isErrorEnabled() { + return delegate.isErrorEnabled(); + } + + @Override + public boolean isSubprocessOutEnabled() { + return delegate.isInfoEnabled(); + } + + @Override + public boolean isInfoEnabled() { + return delegate.isInfoEnabled(); } } diff --git a/graalpython/hpy/.gitattributes b/graalpython/hpy/.gitattributes new file mode 100644 index 0000000000..1c5f632434 --- /dev/null +++ b/graalpython/hpy/.gitattributes @@ -0,0 +1 @@ +**/autogen_* linguist-generated=true diff --git a/graalpython/hpy/.github/FUNDING.yml b/graalpython/hpy/.github/FUNDING.yml new file mode 100644 index 0000000000..950b3021c6 --- /dev/null +++ b/graalpython/hpy/.github/FUNDING.yml @@ -0,0 +1 @@ +open_collective: hpy diff --git a/graalpython/hpy/.github/workflows/ci.yml b/graalpython/hpy/.github/workflows/ci.yml new file mode 100644 index 0000000000..0ec548c068 --- /dev/null +++ b/graalpython/hpy/.github/workflows/ci.yml @@ -0,0 +1,427 @@ +--- +name: tests + +on: [pull_request] + +jobs: + main_tests: + name: Main tests ${{ matrix.os }} ${{ matrix.python-version }} ${{ matrix.compiler }} + runs-on: ${{ matrix.os }} + continue-on-error: true + strategy: + # Duplicate changes to this matrix to 'poc_tests' + matrix: + os: [ubuntu-latest, macos-13, windows-latest] + python-version: ['3.9', '3.10'] + compiler: [""] + include: + - os: ubuntu-latest + python-version: '3.8' + - os: ubuntu-latest + python-version: '3.10' + compiler: 'g++' + - os: ubuntu-latest + python-version: '3.11' + - os: ubuntu-latest + python-version: '3.12' + + steps: + - uses: actions/checkout@v4 + + # - template: azure-templates/ccache.yml + # parameters: + # pythonVersion: $(python.version) + # - template: azure-templates/python.yml + # parameters: + # pythonVersion: $(python.version) + + - name: Set up Python + uses: actions/setup-python@v5.4 + with: + python-version: ${{ matrix.python-version }} + allow-prereleases: true + + - name: Install/Upgrade Python dependencies + run: python -m pip install --upgrade pip wheel 'setuptools>=60.2' + + - name: Build + run: | + make + python -m pip install . + + - if: ${{ matrix.compiler }} + # Only set the compiler for the tests, not for the build + run: echo "CC=${{ matrix.compiler }}" >> $GITHUB_ENV + + - name: Run tests + run: | + python -m pip install pytest pytest-xdist filelock + python -m pytest --basetemp=.tmpdir --durations=16 -n auto test/ + + main_tests_debug: + name: Main tests on CPython debug builds + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + # Cannot install 3.12 on ubuntu-latest + python-version: ['3.11', '3.10', '3.9', '3.8'] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python from deadsnakes + uses: deadsnakes/action@v3.2.0 + with: + python-version: ${{ matrix.python-version }} + debug: true + + - name: Check Python debug build + run: python -c "import sys; print(hasattr(sys, 'gettotalrefcount'))" + + - name: Install/Upgrade Python dependencies + run: python -m pip install --upgrade pip wheel + + - name: Build + run: | + make + python -m pip install . + + - name: Run tests + run: | + python -m pip install pytest pytest-xdist filelock + python -m pytest --durations=16 -n auto test/ + + poc_tests: + name: Proof of concept tests + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-13, windows-latest] + python-version: ['3.10'] + include: + - os: ubuntu-latest + python-version: '3.8' + - os: ubuntu-latest + python-version: '3.9' + - os: ubuntu-latest + python-version: '3.11' + - os: ubuntu-latest + python-version: '3.12' + + steps: + - uses: actions/checkout@v4 + + # - template: azure-templates/ccache.yml + # parameters: + # pythonVersion: $(python.version) + # - template: azure-templates/python.yml + # parameters: + # pythonVersion: $(python.version) + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + allow-prereleases: true + + - name: Install/Upgrade Python dependencies + run: python -m pip install --upgrade pip wheel + shell: bash + + - name: 'Test setup.py --hpy-abi=cpython bdist_wheel' + run: proof-of-concept/test_pof.sh wheel cpython + shell: bash + + - name: 'Test setup.py --hpy-abi=universal bdist_wheel' + run: proof-of-concept/test_pof.sh wheel universal + shell: bash + + - name: 'Test setup.py --hpy-abi=cpython install' + run: proof-of-concept/test_pof.sh setup_py_install cpython + shell: bash + + - name: 'Test setup.py --hpy-abi=universal install' + run: proof-of-concept/test_pof.sh setup_py_install universal + shell: bash + + - name: 'Test setup.py --hpy-abi=cpython build_ext --inplace' + run: proof-of-concept/test_pof.sh setup_py_build_ext_inplace cpython + shell: bash + + - name: 'Test setup.py --hpy-abi=universal build_ext --inplace' + run: proof-of-concept/test_pof.sh setup_py_build_ext_inplace universal + shell: bash + + + porting_example_tests: + name: Porting example tests + runs-on: ${{ matrix.os }} + continue-on-error: true + strategy: + matrix: + os: [ubuntu-latest, macos-13, windows-latest] + python-version: ['3.9'] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install/Upgrade Python dependencies + run: python -m pip install --upgrade pip wheel + shell: bash + + - name: Install HPy + run: python -m pip install . + + - name: Install pytest + run: | + python -m pip install pytest + + - name: Run tests + run: make porting-example-tests + shell: bash + + - name: Run tests of completed port in debug mode + env: + HPY_DEBUG: "1" + TEST_ARGS: "-s -k hpy_final" + run: make porting-example-tests + shell: bash + + + valgrind_tests_1: + name: 'Valgrind tests (1/3)' + uses: ./.github/workflows/valgrind-tests.yml + with: + portion: '1/3' + + + valgrind_tests_2: + name: 'Valgrind tests (2/3)' + uses: ./.github/workflows/valgrind-tests.yml + with: + portion: '2/3' + + + valgrind_tests_3: + name: 'Valgrind tests (3/3)' + uses: ./.github/workflows/valgrind-tests.yml + with: + portion: '3/3' + + + docs_examples_tests: + name: Documentation examples tests + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-13, windows-latest] + python-version: ['3.10'] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install/Upgrade Python dependencies + run: python -m pip install --upgrade pip wheel + shell: bash + + - name: Install HPy + run: python -m pip install . + + - name: Install pytest + run: | + python -m pip install pytest pytest-xdist filelock + - name: Run tests + run: make docs-examples-tests + shell: bash + + build_docs: + name: Build documentation + runs-on: 'ubuntu-latest' + steps: + - uses: actions/checkout@v4 + + # - template: azure-templates/python.yml + + - name: Install / Upgrade system requirements + run: sudo apt update && sudo apt install -y libclang-17-dev + + - name: Install / Upgrade Python requirements + run: | + python -m pip install --upgrade pip + python -m pip install -r docs/requirements.txt + + - name: Build docs + run: | + cd docs; + python -m sphinx -T -W -E -b html -d _build/doctrees -D language=en . _build/html + + - name: Upload built HTML files + uses: actions/upload-artifact@v4 + with: + name: hpy_html_docs + path: docs/_build/html/* + if-no-files-found: error + retention-days: 5 + + c_tests: + name: C tests + runs-on: 'ubuntu-latest' + steps: + - uses: actions/checkout@v4 + - run: make -C c_test + + + check_autogen: + name: Check autogen + runs-on: 'ubuntu-latest' + steps: + - uses: actions/checkout@v4 + + # - template: azure-templates/python.yml + + - name: Set up Python + uses: actions/setup-python@v5 + with: + # autogen needs distutils + python-version: '3.11' + + - name: Install/Upgrade Python dependencies + run: python -m pip install --upgrade pip wheel + + - name: Install autogen dependencies + run: pip install -r requirements-autogen.txt + + - name: make autogen + run: | + make autogen + if [ -z "$(git status --porcelain)" ]; then + # clean working copy + echo "Working copy is clean, everything ok" + else + # Uncommitted changes + echo "ERROR: uncommitted changes after running make autogen" + echo "git status" + git status + echo + echo "git diff" + git diff + exit 1 + fi + + + check_py27_compat: + name: Check Python 2.7 compatibility + runs-on: 'ubuntu-20.04' + steps: + - uses: actions/checkout@v4 + + # - template: azure-templates/python.yml + # parameters: + # pythonVersion: "2.7" + + - name: Set up Python2 + # Copied from cython's ci.yml + run: | + sudo ln -fs python2 /usr/bin/python + sudo apt-get update + sudo apt-get install python-setuptools python2.7 python2.7-dev + curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py + sudo python2 get-pip.py + ls -l /usr/bin/pip* /usr/local/bin/pip* + which pip + + - name: Install/Upgrade Python dependencies + run: python -m pip install --upgrade pip wheel + + - name: check_py27_compat.py + run: | + python -m pip install pytest pytest-xdist filelock pathlib + python test/check_py27_compat.py + + + cpp_check: + name: Cppcheck static analysis + runs-on: 'ubuntu-22.04' + continue-on-error: true + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Install Cppcheck + run: sudo apt-get -qq -y install cppcheck=2.7-1 + + - name: Run Cppcheck + run: make cppcheck + + + infer: + name: Infer static analysis + runs-on: 'ubuntu-latest' + steps: + - uses: actions/checkout@v4 + + # - template: azure-templates/python.yml + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Install/Upgrade Python dependencies + run: python -m pip install --upgrade pip wheel + + - name: Install Infer + run: | + python -m pip install compiledb wheel; + VERSION=1.1.0; \ + curl -sSL "https://github.com/facebook/infer/releases/download/v$VERSION/infer-linux64-v$VERSION.tar.xz" \ + | sudo tar -C /opt -xJ && \ + echo "/opt/infer-linux64-v$VERSION/bin" >> $GITHUB_PATH + + - name: Run Infer + run: make infer + + check_microbench: + name: Check micro benchmarks + runs-on: 'ubuntu-latest' + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install / Upgrade system dependencies + run: sudo apt update && sudo apt install -y valgrind + + - name: Install / Upgrade Python requirements + run: | + python -m pip install --upgrade pip wheel 'setuptools>=60.2' + python -m pip install pytest cffi + + - name: Build and install HPy + run: | + make + python -m pip install . + + - name: Run microbenchmarks + run: | + cd microbench + python setup.py build_ext -i + python -m pytest -v diff --git a/graalpython/hpy/.github/workflows/release-pypi.yml b/graalpython/hpy/.github/workflows/release-pypi.yml new file mode 100644 index 0000000000..959a779170 --- /dev/null +++ b/graalpython/hpy/.github/workflows/release-pypi.yml @@ -0,0 +1,136 @@ +--- +name: Publish to PyPI + +# manually trigger this workflow +on: + workflow_dispatch: + inputs: + tag: + description: 'The Git tag to create or test a release for. Official releases should always be made from an existing tag.' + required: true + type: string + official: + description: 'If true, publish to official PyPI and create GitHub release. Otherwise publish only to test PyPI.' + default: false + type: boolean + +jobs: + build_sdist: + name: Build source package + runs-on: 'ubuntu-latest' + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ inputs.tag }} + + - name: Set up Python + uses: actions/setup-python@v4 + with: + # HPy requires at least Python 3.8; we mostly work with >=3.10 + python-version: '>=3.10' + + - name: Install/Upgrade Python dependencies + run: python -m pip install --upgrade pip wheel 'setuptools>=60.2' + + - name: Build and install Python source package + run: | + python setup.py sdist + python -m pip install dist/*.tar.gz + + - name: Run tests + run: | + make + pip install pytest pytest-xdist filelock + pytest -n auto test/ + + - uses: actions/upload-artifact@v3 + with: + path: dist/*.tar.gz + retention-days: 5 + + + build_bdist: + name: Build binary wheels + runs-on: ${{ matrix.os }} + strategy: + matrix: + # Windows tests fail when built as a binary wheel for some reason + # 'macos-12' doesn't pass the tests + os: [ubuntu-latest, macos-11] # windows-latest + + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ inputs.tag }} + + # setup Python for cibuildwheel + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.x' + + # for other architectures, see: https://cibuildwheel.readthedocs.io/en/stable/faq/#emulation + - name: Build wheels for CPython + uses: pypa/cibuildwheel@v2.12.3 + env: + # cibuildwheel automatically reads 'python_requires' from 'setup.py' + CIBW_BUILD: 'cp*' # no PyPy builds + CIBW_ARCHS_LINUX: "x86_64" # only Intel 64-bit + CIBW_ARCHS_MACOS: "x86_64" # only Intel 64-bit + CIBW_TEST_REQUIRES: pytest pytest-xdist filelock setuptools>=60.2 + # only copy test dir to current working dir + CIBW_TEST_COMMAND: cp -R {project}/test ./ && pytest --basetemp=.tmpdir --ignore=test/hpy_devel -n auto ./test/ + + - uses: actions/upload-artifact@v3 + with: + path: ./wheelhouse/*.whl + retention-days: 5 + + upload_pypi: + name: Publish packages to (Test) PyPI + needs: [build_sdist, build_bdist] + runs-on: ubuntu-latest + # don't do this action on forks by default + if: github.repository == 'hpyproject/hpy' + steps: + - uses: actions/download-artifact@v3 + with: + name: artifact + path: dist + + - name: Upload to Test PyPI + uses: pypa/gh-action-pypi-publish@v1.8.5 + if: ${{ !inputs.official }} + with: + verbose: true + user: __token__ + password: ${{ secrets.TEST_PYPI_API_TOKEN }} + repository-url: https://test.pypi.org/legacy/ + + - name: Upload to PyPI + uses: pypa/gh-action-pypi-publish@v1.8.5 + if: ${{ inputs.official }} + with: + verbose: true + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} + + create_gh_release: + needs: [upload_pypi] + runs-on: ubuntu-latest + # don't do this action on forks by default + if: github.repository == 'hpyproject/hpy' + steps: + - uses: actions/download-artifact@v3 + with: + name: artifact + path: dist + + - name: Release + uses: softprops/action-gh-release@v1 + with: + files: dist/* + # consider tags in form '*.*.*rc*' to indicate a pre-release + prerelease: ${{ contains(inputs.tag, 'rc') }} + draft: ${{ !inputs.official }} + tag_name: ${{ inputs.tag }} diff --git a/graalpython/hpy/.github/workflows/valgrind-tests.yml b/graalpython/hpy/.github/workflows/valgrind-tests.yml new file mode 100644 index 0000000000..ab739252eb --- /dev/null +++ b/graalpython/hpy/.github/workflows/valgrind-tests.yml @@ -0,0 +1,38 @@ +on: + workflow_call: + inputs: + portion: + description: 'Select portion of tests to run under Valgrind (default runs all)' + default: '' + type: string + required: false + +jobs: + valgrind_tests: + # name: Valgrind tests + runs-on: 'ubuntu-latest' + steps: + - uses: actions/checkout@v4 + + - name: Install / Upgrade system dependencies + run: sudo apt update && sudo apt install -y valgrind + + - name: Set up Python + uses: actions/setup-python@v5.4 + with: + python-version: 3.9 + + - name: Install / Upgrade Python dependencies + run: python -m pip install --upgrade pip wheel setuptools + + - name: Build + run: | + make + python -m pip install . + + - name: Run tests + env: + HPY_TEST_PORTION: ${{ inputs.portion }} + run: | + python -m pip install pytest pytest-valgrind pytest-portion filelock + make valgrind diff --git a/graalpython/hpy/.gitignore b/graalpython/hpy/.gitignore new file mode 100644 index 0000000000..2877066982 --- /dev/null +++ b/graalpython/hpy/.gitignore @@ -0,0 +1,92 @@ +# HPy autogen +hpy/tools/autogen/autogen_pypy.txt + +# generated by setup.py:get_scm_config() +hpy/devel/include/hpy/version.h +hpy/devel/version.py + +# stubs created by setup.py when doing build_ext --inplace +proof-of-concept/pof.py +proof-of-concept/pofpackage/foo.py + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions and static libs +*.so +*.o +*.a +*.lib +vc140.pdb +c_test/test_debug_handles + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +test-output.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +.hpy.lock + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# cppcheck +.cppcheck + +# Sphinx +docs/_build/ + +# vscode +.vscode diff --git a/graalpython/hpy/.readthedocs.yml b/graalpython/hpy/.readthedocs.yml new file mode 100644 index 0000000000..7ee9eedb2e --- /dev/null +++ b/graalpython/hpy/.readthedocs.yml @@ -0,0 +1,10 @@ +# readthedocs.org configuration + +version: 2 +sphinx: + configuration: docs/conf.py +formats: all +python: + version: 3.7 + install: + - requirements: docs/requirements.txt diff --git a/graalpython/hpy/AUTHORS b/graalpython/hpy/AUTHORS new file mode 100644 index 0000000000..707ed38f94 --- /dev/null +++ b/graalpython/hpy/AUTHORS @@ -0,0 +1,38 @@ +# This is the list of HPy's significant contributors. +# +# This does not necessarily list everyone who has contributed code, +# especially since many employees of one corporation may be contributing. +# To see the full list of contributors, see the revision history in +# source control. +Alexander Schremmer +Ammar Askar +Ankith (ankith26) +Antonio Cuni +Armin Rigo +Charlie Hayden +Christian Klein +Daniel Alley +Dominic Davis-Foster +Jaime Resano Aísa +Joachim Trouverie +Julian Berman +Krish Patel +Kyle Lawlor-Bagcal +Mathieu Dupuy +Matti Picus +Max Horn +Maxwell Bernstein +Mohamed Koubaa +Nico Rittinghaus +Omer Katz +Oracle and/or its affiliates +Paul Prescod +Pierre Augier +Robert O'Shea +Ronan Lamy +Simon Cross +Stefan Behnel +Stefano Rivera +Victor Stinner +Vytautas Liuolia +Łukasz Langa diff --git a/graalpython/hpy/CONTRIBUTING.md b/graalpython/hpy/CONTRIBUTING.md new file mode 100644 index 0000000000..7178db511c --- /dev/null +++ b/graalpython/hpy/CONTRIBUTING.md @@ -0,0 +1,55 @@ +Contributing +============ + +Contributions are welcome, and they are greatly appreciated! Every +little bit helps. + +You can contribute in many ways: + +Types of Contributions +---------------------- + +### Report Bugs + +Report bugs at . + +When reporting a bug, please include: + +- Your operating system name and version. +- Any details about your local setup that might be helpful in + troubleshooting. +- Detailed steps to reproduce the bug. + +### Donate to HPy + +Become a financial contributor and help us sustain the HPy community: [Contribute to HPy](https://opencollective.com/hpy/contribute). + +### Fix Bugs or Implement Features + +Look through the GitHub issues for bugs or proposals being discussed +or ready for implementation. + +### Write Documentation + +HPy could always use more documentation, whether as part of the +official HPy docs, in docstrings, or even on the web in blog +posts, articles, and such. + +Get Started! +------------ + +You can test your environment by running + +```bash +proof-of-concept/test_pof.sh wheel universal +``` + +This should build HPy and a proof of concept (demo) extension and +then run a pytest that validates both. + +Until we get around to more comprehensive documentation, you +can reverse engineer how the system works by looking at these +files: + +- `proof-of-concept/test_pof.sh` +- `proof-of-concept/setup.py` diff --git a/graalpython/hpy/LICENSE b/graalpython/hpy/LICENSE new file mode 100644 index 0000000000..a5b403aa3f --- /dev/null +++ b/graalpython/hpy/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 The HPy Authors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/graalpython/hpy/MANIFEST.in b/graalpython/hpy/MANIFEST.in new file mode 100644 index 0000000000..7a4b248c98 --- /dev/null +++ b/graalpython/hpy/MANIFEST.in @@ -0,0 +1 @@ +recursive-include hpy/devel/include *.h diff --git a/graalpython/hpy/Makefile b/graalpython/hpy/Makefile new file mode 100644 index 0000000000..6d0f1c0db8 --- /dev/null +++ b/graalpython/hpy/Makefile @@ -0,0 +1,86 @@ +.PHONY: all +all: hpy.universal + +.PHONY: hpy.universal +hpy.universal: + python3 setup.py build_clib -f build_ext -if + +.PHONY: dist-info +dist-info: + python3 setup.py dist_info + +debug: + HPY_DEBUG_BUILD=1 make all + +autogen: + python3 -m hpy.tools.autogen . + +cppcheck-build-dir: + mkdir -p $(or ${CPPCHECK_BUILD_DIR}, .cppcheck) + +.PHONY: cppcheck +cppcheck: cppcheck-build-dir + # azure pipelines doesn't show stderr, so we write the errors to a file and cat it later :( + $(eval PYTHON_INC = $(shell python3 -q -c "from sysconfig import get_paths as gp; print(gp()['include'])")) + $(eval PYTHON_PLATINC = $(shell python3 -q -c "from sysconfig import get_paths as gp; print(gp()['platinclude'])")) + cppcheck --version + cppcheck \ + -v \ + --error-exitcode=1 \ + --cppcheck-build-dir=$(or ${CPPCHECK_BUILD_DIR}, .cppcheck) \ + --enable=warning,performance,portability,information,missingInclude \ + --inline-suppr \ + --suppress=syntaxError \ + -I /usr/local/include/ \ + -I /usr/include/ \ + -I ${PYTHON_INC} \ + -I ${PYTHON_PLATINC} \ + -I . \ + -I hpy/devel/include/ \ + -I hpy/devel/include/hpy/ \ + -I hpy/devel/include/hpy/cpython/ \ + -I hpy/devel/include/hpy/universal/ \ + -I hpy/devel/include/hpy/runtime/ \ + -I hpy/universal/src/ \ + -I hpy/debug/src/ \ + -I hpy/debug/src/include \ + -I hpy/trace/src/ \ + -I hpy/trace/src/include \ + --force \ + -D NULL=0 \ + -D HPY_ABI_CPYTHON \ + -D __linux__=1 \ + -D __x86_64__=1 \ + -D __LP64__=1 \ + . + +infer: + python3 setup.py build_ext -if -U NDEBUG | compiledb + # see commit cd8cd6e for why we need to ignore debug_ctx.c + @infer --fail-on-issue --compilation-database compile_commands.json --report-blacklist-path-regex "hpy/debug/src/debug_ctx.c" + +valgrind_args = --suppressions=hpy/tools/valgrind/python.supp --suppressions=hpy/tools/valgrind/hpy.supp --leak-check=full --show-leak-kinds=definite,indirect --log-file=/tmp/valgrind-output +python_args = -m pytest --valgrind --valgrind-log=/tmp/valgrind-output + +.PHONY: valgrind +valgrind: +ifeq ($(HPY_TEST_PORTION),) + PYTHONMALLOC=malloc valgrind $(valgrind_args) python3 $(python_args) test/ +else + PYTHONMALLOC=malloc valgrind $(valgrind_args) python3 $(python_args) --portion $(HPY_TEST_PORTION) test/ +endif + +porting-example-tests: + cd docs/porting-example/steps && python3 setup00.py build_ext -i + cd docs/porting-example/steps && python3 setup01.py build_ext -i + cd docs/porting-example/steps && python3 setup02.py build_ext -i + cd docs/porting-example/steps && python3 setup03.py --hpy-abi=universal build_ext -i + python3 -m pytest docs/porting-example/steps/ ${TEST_ARGS} + +docs-examples-tests: + cd docs/examples/simple-example && python3 setup.py --hpy-abi=universal install + cd docs/examples/mixed-example && python3 setup.py install + cd docs/examples/snippets && python3 setup.py --hpy-abi=universal install + cd docs/examples/quickstart && python3 setup.py --hpy-abi=universal install + cd docs/examples/hpytype-example && python3 setup.py --hpy-abi=universal install + python3 -m pytest docs/examples/tests.py ${TEST_ARGS} diff --git a/graalpython/hpy/README-gdb.md b/graalpython/hpy/README-gdb.md new file mode 100644 index 0000000000..c1bacca196 --- /dev/null +++ b/graalpython/hpy/README-gdb.md @@ -0,0 +1,207 @@ +How to debug HPy on CPython +============================ + +This document describes how to make debugging easier when running HPy on +CPython. At the moment it is structured as a collection of notes, PRs to make +it more structured are welcome. + +**NOTE**: this document is **not** about the HPy debug mode, but it's about +debugging HPy itself. + + +Build a debug version of CPython +--------------------------------- + +This is highly recommended. It takes only few minutes and helps a lot during +debugging for two reasons: + +1. You can easily view CPython's source code inside GDB + +2. CPython is compiled with `-Og`, which means it will be easier to follow the + code step-by-step and to inspect variables + +3. The `py-*` GDB commands work out of the box. + +``` +$ cd /path/to/cpython +$ git checkout v3.8.2 +$ ./configure --with-pydebug --prefix=/opt/python-debug/ +$ make install +``` + +Enable `python-gdb.py` +---------------------- + +`python-gdb.py` is a GDB script to make it easier to inspect the state of a +Python process from whitin GDB. It is documented +[in the CPython's dev guide](https://devguide.python.org/gdb/). + +The script add a series of GBD commands such as: + + - `py-bt`: prints the Python-level traceback of the current function + + - `py-up`, `py-down`: navigate up and down the Python function stack by + going to the previous/next occurrence of `_PyEval_EvalFrameDefault`. They + are more or less equivalent to `up` and `down` inside `pdb`. + + - `py-print`: print the value of a Python-level variable + +**WARNING**: the CPython's dev guide suggests to add `add-auto-load-safe-path` +to your `~/.gdbinit`, but it doesn't work for me. What works for me is the +following: + +``` +# add this to your ~/.gdbinit +source /path/to/cpython/python-gdb.py +``` + +To check that the `py-*` commands work as expected, you can do the following: + +``` +$ gdb --args /opt/python-debug/bin/python3 -c 'for i in range(10000000): pass' +GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2 +... +(gdb) run # start the python process +... + +^C +... +(gdb) py-bt +Traceback (most recent call first): + File "", line 1, in +(gdb) py-print i +global 'i' = 9657683 +``` + +Inspect `PyObject *` and `HPy` inside GDB +------------------------------------------ + +**WARNING**: `py-dump` and `hpy-dump` prints to stderr, and this interacts +badly with pytest's capturing. Make sure to run `py.test -s`, else you might +not see the output. The included script `gdb-py.test` automatically pass `-s`. + +`python-gdb.py` installs a GDB pretty-printer for `PyObject *` variables, +which sometimes can be confusing: often, it prints the Python repr of the +variable: + +``` +(gdb) set $x = PyLong_FromLong(42) +(gdb) p $x +$5 = 42 +(gdb) p (void*)$x +$7 = (void *) 0x555555903ca0 +(gdb) p *$x +$6 = {ob_refcnt = 10, ob_type = 0x5555558d5560 } +``` + +For some reason which is unknown to me, sometimes it prints a rather obscure +string: here, `type` is the Python type of the object, and `0x5555558ce88` is +its address: + +``` +(gdb) p PyExc_ValueError +$12 = +(gdb) p (void*)PyExc_ValueError +$13 = (void *) 0x5555558ce880 <_PyExc_ValueError> +``` + +Another useful trick is to define these two custom GDB commands in your +`~/.gdbinit`: + +``` +# put this in your ~/.gdbinit +define py-dump +call _PyObject_Dump($arg0) +end + +# NOTE: +# 1. this assumes that you have a variable called "ctx" available +# 2. this assumes that it's a debug version of HPy, which was compiled with +# -fkeep-inline-functions +# 3. if you don't have _HPy_Dump available, you can call manually +# ctx->ctx_Dump (but only in universal mode) +define hpy-dump +call _HPy_Dump(ctx, $arg0) +end +``` + +Example of usage: + +``` +(gdb) set $x = PyLong_FromLong(42) +(gdb) py-dump $x +object address : 0x555555903ca0 +object refcount : 11 +object type : 0x5555558d5560 +object type name: int +object repr : 42 + +(gdb) py-dump PyExc_ValueError +object address : 0x5555558ce880 +object refcount : 14 +object type : 0x5555558dd8e0 +object type name: type +object repr : + +(gdb) set $h = ctx->ctx_Long_FromLong(ctx, 1234) +(gdb) p $h +$2 = {_i = 77} +(gdb) hpy-dump $h +object address : 0x7ffff64b0580 +object refcount : 1 +object type : 0x5555558d5560 +object type name: int +object repr : 1234 +``` + + + +Create a venv for python-debug and install hpy +----------------------------------------------- + +The following commands create a `venv` based on the newly built +`python-debug`, and installs `hpy` in "editable mode". + +``` +$ cd /path/to/hpy +$ /opt/python-debug/bin/python3 -m venv venv/hpy-debug +$ . venv/hpy-debug/bin/activate +$ python setup.py develop +``` + +Once hpy is installed this way, you can edit the C files and rebuild it easily +by using `make`: + +``` +$ make # build normally +$ make debug # build HPY with -O0 -g +``` + +Run a specific HPy test under GDB +--------------------------------- + +To run `py.test` under GDB, use the script `./gdb-py.test`. + +**Tip:** most HPy tests export a Python function called `f`. You can easily +put a breakpoint into it by using `b f_impl`: + +``` +$ ./gdb-py.test -s test/test_00_basic.py -k 'test_float_asdouble and universal' +... +(gdb) b f_impl +Breakpoint 1 at 0x7ffff63a0284: file /tmp/pytest-of-antocuni/pytest-219/test_float_asdouble_universal_0/mytest.c, line 5. +(gdb) run +... +Breakpoint 1, f_impl (ctx=0x7ffff64191d0, self=..., arg=...) at /tmp/pytest-of-antocuni/pytest-220/test_float_asdouble_universal_0/mytest.c:5 +5 { +(gdb) next +6 double a = HPyFloat_AsDouble(ctx, arg); +(gdb) p arg +$1 = {_i = 75} +(gdb) hpy-dump arg +object address : 0x7ffff7017700 +object refcount : 3 +object type : 0x5555558d3400 +object type name: float +object repr : 1.0 +``` diff --git a/graalpython/hpy/README.md b/graalpython/hpy/README.md new file mode 100644 index 0000000000..311199e6bc --- /dev/null +++ b/graalpython/hpy/README.md @@ -0,0 +1,81 @@ +# HPy: a better API for Python + +[![Build](https://github.com/hpyproject/hpy/actions/workflows/ci.yml/badge.svg)](https://github.com/hpyproject/hpy/actions/workflows/ci.yml) +[![Documentation](https://readthedocs.org/projects/hpy/badge/)](https://hpy.readthedocs.io/) +[![Join the discord server at https://discord.gg/xSzxUbPkTQ](https://img.shields.io/discord/1077164940906995813.svg?color=7389D8&labelColor=6A7EC2&logo=discord&logoColor=ffffff&style=flat-square)](https://discord.gg/xSzxUbPkTQ) + +**Website**: [hpyproject.org](https://hpyproject.org/) \ +**Community**: [HPy Discord server](https://discord.gg/xSzxUbPkTQ) \ +**Mailing list**: [hpy-dev@python.org](https://mail.python.org/mailman3/lists/hpy-dev.python.org/) + +## Summary + +HPy is a better API for extending Python +in C. The old C API is specific to the current implementation of CPython. +It exposes a lot of internal details which makes it hard to: + + - implement it for other Python implementations (e.g. PyPy, GraalPy, + Jython, IronPython, etc.). + - experiment with new things inside CPython itself: e.g. using a GC + instead of refcounting, or to remove the GIL + - guarantee binary stability + +HPy is a specification of a new API and ABI for extending Python that is +Python implementation agnostic and designed to hide and abstract internal +details such that it: + + - can stay binary compatible even if the underlying Python internals change significantly + - does not hinder internal progress of CPython and other Pythons + +Please read the [documentation](https://docs.hpyproject.org/en/latest/overview.html) +for more details on HPy motivation, goals, and features, for example: + + - debug mode for better developer experience + - support for incremental porting from CPython API to HPy + - CPython ABI for raw performance on CPython + - and others + +Do you want to see how HPy API looks in code? Check out +our [quickstart example](https://docs.hpyproject.org/en/latest/quickstart.html). + +You may also be interested in HPy's +[API reference](https://docs.hpyproject.org/en/latest/api-reference/index.html). + +This repository contains the API and ABI specification and implementation +for the CPython interpreter. Other interpreters that support HPy natively: GraalPy +and PyPy, provide their own builtin HPy implementations. + + +## Why should I care about this stuff? + + - the existing C API is becoming a problem for CPython and for the + evolution of the language itself: this project makes it possible to make + experiments which might be "officially" adopted in the future + + - for PyPy, it will give obvious speed benefits: for example, data + scientists will be able to get the benefit of fast C libraries *and* fast + Python code at the same time, something which is hard to achieve now + + - the current implementation is too tied to CPython and proved to be a + problem for almost all the other alternative implementations. Having an + API which is designed to work well on two different implementations will + make the job much easier for future ones: going from 2 to N is much easier + than going from 1 to 2 + + - arguably, it will be easier to learn and understand than the massive + CPython C API + +See also [Python Performance: Past, Present, +Future](https://github.com/vstinner/talks/raw/main/2019-EuroPython/python_performance.pdf) +by Victor Stinner. + + +## What does `HPy` mean? + +The "H" in `HPy` stands for "handle": one of the key idea of the new API is to +use fully opaque handles to represent and pass around Python objects. + + +## Donate to HPy + +Become a financial contributor and help us sustain the HPy community: [Contribute to HPy](https://opencollective.com/hpy/contribute). diff --git a/graalpython/hpy/build.py b/graalpython/hpy/build.py new file mode 100644 index 0000000000..43eb5c3d69 --- /dev/null +++ b/graalpython/hpy/build.py @@ -0,0 +1,91 @@ +# +# Copyright (c) 2025, Oracle and/or its affiliates. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or other materials provided +# with the distribution. +# 3. Neither the name of the copyright holder nor the names of its contributors may be used to +# endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + +VERSION = "0.9.0" + +import argparse +import os +import shlex +import subprocess +import sys +import tempfile +import venv + +from pathlib import Path + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--out", required=True) + parser.add_argument("--cflags", required=True) + parsed_args = parser.parse_args() + + setup = Path(__file__).parent.absolute() / "setup.py" + build = Path(parsed_args.out).absolute() + build.mkdir(parents=True, exist_ok=True) + + if sys.platform != "win32": + executable = " ".join(map(shlex.quote, __graalpython__.executable_list)) + with open(build / "graalpy", "w") as f: + p = Path(f.name).absolute() + f.write(f"""#!/bin/bash + exec {executable} -B --DisableFrozenModules --Executable="$0" "$@" + """) + p.chmod(0o777) + sys._base_executable = sys.executable = str(p) + else: + # win32 works because venv generates a venvlauncher there + pass + + venv.main(args=[str(build / "venv")]) + if sys.platform == "win32": + exe = build / "venv" / "Scripts" / "graalpy.exe" + else: + exe = build / "venv" / "bin" / "graalpy" + + subprocess.run( + map(str, [ + exe, + setup, + "build", + "--build-lib", + build / "build", + "--build-temp", + build / "temp", + "install", + "--single-version-externally-managed", + "--root=/", + ]), + cwd=setup.parent, + check=True, + env=os.environ.copy() | { + "SETUPTOOLS_SCM_PRETEND_VERSION": VERSION, + "CFLAGS": os.environ.get("CFLAGS", "") + f" {parsed_args.cflags}" + }, + ) diff --git a/graalpython/hpy/c_test/Makefile b/graalpython/hpy/c_test/Makefile new file mode 100644 index 0000000000..2e93170d4c --- /dev/null +++ b/graalpython/hpy/c_test/Makefile @@ -0,0 +1,16 @@ +CC ?= gcc +INCLUDE=-I.. -I../hpy/devel/include -I../hpy/debug/src/include +CFLAGS = -O0 -UNDEBUG -g -Wall -Werror -Wfatal-errors $(INCLUDE) -DHPY_ABI_UNIVERSAL + +test: test_debug_handles test_stacktrace + ./test_debug_handles + ./test_stacktrace + +test_debug_handles: test_debug_handles.o ../hpy/debug/src/dhqueue.o + $(CC) -o $@ $^ + +test_stacktrace: test_stacktrace.o ../hpy/debug/src/stacktrace.o + $(CC) -o $@ $^ + +%.o : %.c + $(CC) -c $(CFLAGS) $< -o $@ diff --git a/graalpython/hpy/c_test/acutest.h b/graalpython/hpy/c_test/acutest.h new file mode 100644 index 0000000000..a05eb41cd0 --- /dev/null +++ b/graalpython/hpy/c_test/acutest.h @@ -0,0 +1,1794 @@ +/* + * Acutest -- Another C/C++ Unit Test facility + * + * + * Copyright 2013-2020 Martin Mitas + * Copyright 2019 Garrett D'Amore + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef ACUTEST_H +#define ACUTEST_H + + +/************************ + *** Public interface *** + ************************/ + +/* By default, "acutest.h" provides the main program entry point (function + * main()). However, if the test suite is composed of multiple source files + * which include "acutest.h", then this causes a problem of multiple main() + * definitions. To avoid this problem, #define macro TEST_NO_MAIN in all + * compilation units but one. + */ + +/* Macro to specify list of unit tests in the suite. + * The unit test implementation MUST provide list of unit tests it implements + * with this macro: + * + * TEST_LIST = { + * { "test1_name", test1_func_ptr }, + * { "test2_name", test2_func_ptr }, + * ... + * { NULL, NULL } // zeroed record marking the end of the list + * }; + * + * The list specifies names of each test (must be unique) and pointer to + * a function implementing it. The function does not take any arguments + * and has no return values, i.e. every test function has to be compatible + * with this prototype: + * + * void test_func(void); + * + * Note the list has to be ended with a zeroed record. + */ +#define TEST_LIST const struct acutest_test_ acutest_list_[] + + +/* Macros for testing whether an unit test succeeds or fails. These macros + * can be used arbitrarily in functions implementing the unit tests. + * + * If any condition fails throughout execution of a test, the test fails. + * + * TEST_CHECK takes only one argument (the condition), TEST_CHECK_ allows + * also to specify an error message to print out if the condition fails. + * (It expects printf-like format string and its parameters). The macros + * return non-zero (condition passes) or 0 (condition fails). + * + * That can be useful when more conditions should be checked only if some + * preceding condition passes, as illustrated in this code snippet: + * + * SomeStruct* ptr = allocate_some_struct(); + * if(TEST_CHECK(ptr != NULL)) { + * TEST_CHECK(ptr->member1 < 100); + * TEST_CHECK(ptr->member2 > 200); + * } + */ +#define TEST_CHECK_(cond,...) acutest_check_((cond), __FILE__, __LINE__, __VA_ARGS__) +#define TEST_CHECK(cond) acutest_check_((cond), __FILE__, __LINE__, "%s", #cond) + + +/* These macros are the same as TEST_CHECK_ and TEST_CHECK except that if the + * condition fails, the currently executed unit test is immediately aborted. + * + * That is done either by calling abort() if the unit test is executed as a + * child process; or via longjmp() if the unit test is executed within the + * main Acutest process. + * + * As a side effect of such abortion, your unit tests may cause memory leaks, + * unflushed file descriptors, and other phenomena caused by the abortion. + * + * Therefore you should not use these as a general replacement for TEST_CHECK. + * Use it with some caution, especially if your test causes some other side + * effects to the outside world (e.g. communicating with some server, inserting + * into a database etc.). + */ +#define TEST_ASSERT_(cond,...) \ + do { \ + if(!acutest_check_((cond), __FILE__, __LINE__, __VA_ARGS__)) \ + acutest_abort_(); \ + } while(0) +#define TEST_ASSERT(cond) \ + do { \ + if(!acutest_check_((cond), __FILE__, __LINE__, "%s", #cond)) \ + acutest_abort_(); \ + } while(0) + + +#ifdef __cplusplus +/* Macros to verify that the code (the 1st argument) throws exception of given + * type (the 2nd argument). (Note these macros are only available in C++.) + * + * TEST_EXCEPTION_ is like TEST_EXCEPTION but accepts custom printf-like + * message. + * + * For example: + * + * TEST_EXCEPTION(function_that_throw(), ExpectedExceptionType); + * + * If the function_that_throw() throws ExpectedExceptionType, the check passes. + * If the function throws anything incompatible with ExpectedExceptionType + * (or if it does not thrown an exception at all), the check fails. + */ +#define TEST_EXCEPTION(code, exctype) \ + do { \ + bool exc_ok_ = false; \ + const char *msg_ = NULL; \ + try { \ + code; \ + msg_ = "No exception thrown."; \ + } catch(exctype const&) { \ + exc_ok_= true; \ + } catch(...) { \ + msg_ = "Unexpected exception thrown."; \ + } \ + acutest_check_(exc_ok_, __FILE__, __LINE__, #code " throws " #exctype);\ + if(msg_ != NULL) \ + acutest_message_("%s", msg_); \ + } while(0) +#define TEST_EXCEPTION_(code, exctype, ...) \ + do { \ + bool exc_ok_ = false; \ + const char *msg_ = NULL; \ + try { \ + code; \ + msg_ = "No exception thrown."; \ + } catch(exctype const&) { \ + exc_ok_= true; \ + } catch(...) { \ + msg_ = "Unexpected exception thrown."; \ + } \ + acutest_check_(exc_ok_, __FILE__, __LINE__, __VA_ARGS__); \ + if(msg_ != NULL) \ + acutest_message_("%s", msg_); \ + } while(0) +#endif /* #ifdef __cplusplus */ + + +/* Sometimes it is useful to split execution of more complex unit tests to some + * smaller parts and associate those parts with some names. + * + * This is especially handy if the given unit test is implemented as a loop + * over some vector of multiple testing inputs. Using these macros allow to use + * sort of subtitle for each iteration of the loop (e.g. outputting the input + * itself or a name associated to it), so that if any TEST_CHECK condition + * fails in the loop, it can be easily seen which iteration triggers the + * failure, without the need to manually output the iteration-specific data in + * every single TEST_CHECK inside the loop body. + * + * TEST_CASE allows to specify only single string as the name of the case, + * TEST_CASE_ provides all the power of printf-like string formatting. + * + * Note that the test cases cannot be nested. Starting a new test case ends + * implicitly the previous one. To end the test case explicitly (e.g. to end + * the last test case after exiting the loop), you may use TEST_CASE(NULL). + */ +#define TEST_CASE_(...) acutest_case_(__VA_ARGS__) +#define TEST_CASE(name) acutest_case_("%s", name) + + +/* Maximal output per TEST_CASE call. Longer messages are cut. + * You may define another limit prior including "acutest.h" + */ +#ifndef TEST_CASE_MAXSIZE + #define TEST_CASE_MAXSIZE 64 +#endif + + +/* printf-like macro for outputting an extra information about a failure. + * + * Intended use is to output some computed output versus the expected value, + * e.g. like this: + * + * if(!TEST_CHECK(produced == expected)) { + * TEST_MSG("Expected: %d", expected); + * TEST_MSG("Produced: %d", produced); + * } + * + * Note the message is only written down if the most recent use of any checking + * macro (like e.g. TEST_CHECK or TEST_EXCEPTION) in the current test failed. + * This means the above is equivalent to just this: + * + * TEST_CHECK(produced == expected); + * TEST_MSG("Expected: %d", expected); + * TEST_MSG("Produced: %d", produced); + * + * The macro can deal with multi-line output fairly well. It also automatically + * adds a final new-line if there is none present. + */ +#define TEST_MSG(...) acutest_message_(__VA_ARGS__) + + +/* Maximal output per TEST_MSG call. Longer messages are cut. + * You may define another limit prior including "acutest.h" + */ +#ifndef TEST_MSG_MAXSIZE + #define TEST_MSG_MAXSIZE 1024 +#endif + + +/* Macro for dumping a block of memory. + * + * Its intended use is very similar to what TEST_MSG is for, but instead of + * generating any printf-like message, this is for dumping raw block of a + * memory in a hexadecimal form: + * + * TEST_CHECK(size_produced == size_expected && + * memcmp(addr_produced, addr_expected, size_produced) == 0); + * TEST_DUMP("Expected:", addr_expected, size_expected); + * TEST_DUMP("Produced:", addr_produced, size_produced); + */ +#define TEST_DUMP(title, addr, size) acutest_dump_(title, addr, size) + +/* Maximal output per TEST_DUMP call (in bytes to dump). Longer blocks are cut. + * You may define another limit prior including "acutest.h" + */ +#ifndef TEST_DUMP_MAXSIZE + #define TEST_DUMP_MAXSIZE 1024 +#endif + + +/* Common test initialization/clean-up + * + * In some test suites, it may be needed to perform some sort of the same + * initialization and/or clean-up in all the tests. + * + * Such test suites may use macros TEST_INIT and/or TEST_FINI prior including + * this header. The expansion of the macro is then used as a body of helper + * function called just before executing every single (TEST_INIT) or just after + * it ends (TEST_FINI). + * + * Examples of various ways how to use the macro TEST_INIT: + * + * #define TEST_INIT my_init_func(); + * #define TEST_INIT my_init_func() // Works even without the semicolon + * #define TEST_INIT setlocale(LC_ALL, NULL); + * #define TEST_INIT { setlocale(LC_ALL, NULL); my_init_func(); } + * + * TEST_FINI is to be used in the same way. + */ + + +/********************** + *** Implementation *** + **********************/ + +/* The unit test files should not rely on anything below. */ + +#include +#include +#include +#include +#include +#include + +#if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__) + #define ACUTEST_UNIX_ 1 + #include + #include + #include + #include + #include + #include + #include + + #if defined CLOCK_PROCESS_CPUTIME_ID && defined CLOCK_MONOTONIC + #define ACUTEST_HAS_POSIX_TIMER_ 1 + #endif +#endif + +#if defined(_gnu_linux_) || defined(__linux__) + #define ACUTEST_LINUX_ 1 + #include + #include +#endif + +#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) + #define ACUTEST_WIN_ 1 + #include + #include +#endif + +#ifdef __cplusplus + #include +#endif + +#ifdef __has_include + #if __has_include() + #include + #endif +#endif + +/* Enable the use of the non-standard keyword __attribute__ to silence warnings under some compilers */ +#if defined(__GNUC__) || defined(__clang__) + #define ACUTEST_ATTRIBUTE_(attr) __attribute__((attr)) +#else + #define ACUTEST_ATTRIBUTE_(attr) +#endif + +/* Note our global private identifiers end with '_' to mitigate risk of clash + * with the unit tests implementation. */ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef _MSC_VER + /* In the multi-platform code like ours, we cannot use the non-standard + * "safe" functions from Microsoft C lib like e.g. sprintf_s() instead of + * standard sprintf(). Hence, lets disable the warning C4996. */ + #pragma warning(push) + #pragma warning(disable: 4996) +#endif + + +struct acutest_test_ { + const char* name; + void (*func)(void); +}; + +struct acutest_test_data_ { + unsigned char flags; + double duration; +}; + +enum { + ACUTEST_FLAG_RUN_ = 1 << 0, + ACUTEST_FLAG_SUCCESS_ = 1 << 1, + ACUTEST_FLAG_FAILURE_ = 1 << 2, +}; + +extern const struct acutest_test_ acutest_list_[]; + +int acutest_check_(int cond, const char* file, int line, const char* fmt, ...); +void acutest_case_(const char* fmt, ...); +void acutest_message_(const char* fmt, ...); +void acutest_dump_(const char* title, const void* addr, size_t size); +void acutest_abort_(void) ACUTEST_ATTRIBUTE_(noreturn); + + +#ifndef TEST_NO_MAIN + +static char* acutest_argv0_ = NULL; +static size_t acutest_list_size_ = 0; +static struct acutest_test_data_* acutest_test_data_ = NULL; +static size_t acutest_count_ = 0; +static int acutest_no_exec_ = -1; +static int acutest_no_summary_ = 0; +static int acutest_tap_ = 0; +static int acutest_skip_mode_ = 0; +static int acutest_worker_ = 0; +static int acutest_worker_index_ = 0; +static int acutest_cond_failed_ = 0; +static int acutest_was_aborted_ = 0; +static FILE *acutest_xml_output_ = NULL; + +static int acutest_stat_failed_units_ = 0; +static int acutest_stat_run_units_ = 0; + +static const struct acutest_test_* acutest_current_test_ = NULL; +static int acutest_current_index_ = 0; +static char acutest_case_name_[TEST_CASE_MAXSIZE] = ""; +static int acutest_test_already_logged_ = 0; +static int acutest_case_already_logged_ = 0; +static int acutest_verbose_level_ = 2; +static int acutest_test_failures_ = 0; +static int acutest_colorize_ = 0; +static int acutest_timer_ = 0; + +static int acutest_abort_has_jmp_buf_ = 0; +static jmp_buf acutest_abort_jmp_buf_; + + +static void +acutest_cleanup_(void) +{ + free((void*) acutest_test_data_); +} + +static void ACUTEST_ATTRIBUTE_(noreturn) +acutest_exit_(int exit_code) +{ + acutest_cleanup_(); + exit(exit_code); +} + +#if defined ACUTEST_WIN_ + typedef LARGE_INTEGER acutest_timer_type_; + static LARGE_INTEGER acutest_timer_freq_; + static acutest_timer_type_ acutest_timer_start_; + static acutest_timer_type_ acutest_timer_end_; + + static void + acutest_timer_init_(void) + { + QueryPerformanceFrequency(´st_timer_freq_); + } + + static void + acutest_timer_get_time_(LARGE_INTEGER* ts) + { + QueryPerformanceCounter(ts); + } + + static double + acutest_timer_diff_(LARGE_INTEGER start, LARGE_INTEGER end) + { + double duration = (double)(end.QuadPart - start.QuadPart); + duration /= (double)acutest_timer_freq_.QuadPart; + return duration; + } + + static void + acutest_timer_print_diff_(void) + { + printf("%.6lf secs", acutest_timer_diff_(acutest_timer_start_, acutest_timer_end_)); + } +#elif defined ACUTEST_HAS_POSIX_TIMER_ + static clockid_t acutest_timer_id_; + typedef struct timespec acutest_timer_type_; + static acutest_timer_type_ acutest_timer_start_; + static acutest_timer_type_ acutest_timer_end_; + + static void + acutest_timer_init_(void) + { + if(acutest_timer_ == 1) + acutest_timer_id_ = CLOCK_MONOTONIC; + else if(acutest_timer_ == 2) + acutest_timer_id_ = CLOCK_PROCESS_CPUTIME_ID; + } + + static void + acutest_timer_get_time_(struct timespec* ts) + { + clock_gettime(acutest_timer_id_, ts); + } + + static double + acutest_timer_diff_(struct timespec start, struct timespec end) + { + double endns; + double startns; + + endns = end.tv_sec; + endns *= 1e9; + endns += end.tv_nsec; + + startns = start.tv_sec; + startns *= 1e9; + startns += start.tv_nsec; + + return ((endns - startns)/ 1e9); + } + + static void + acutest_timer_print_diff_(void) + { + printf("%.6lf secs", + acutest_timer_diff_(acutest_timer_start_, acutest_timer_end_)); + } +#else + typedef int acutest_timer_type_; + static acutest_timer_type_ acutest_timer_start_; + static acutest_timer_type_ acutest_timer_end_; + + void + acutest_timer_init_(void) + {} + + static void + acutest_timer_get_time_(int* ts) + { + (void) ts; + } + + static double + acutest_timer_diff_(int start, int end) + { + (void) start; + (void) end; + return 0.0; + } + + static void + acutest_timer_print_diff_(void) + {} +#endif + +#define ACUTEST_COLOR_DEFAULT_ 0 +#define ACUTEST_COLOR_GREEN_ 1 +#define ACUTEST_COLOR_RED_ 2 +#define ACUTEST_COLOR_DEFAULT_INTENSIVE_ 3 +#define ACUTEST_COLOR_GREEN_INTENSIVE_ 4 +#define ACUTEST_COLOR_RED_INTENSIVE_ 5 + +static int ACUTEST_ATTRIBUTE_(format (printf, 2, 3)) +acutest_colored_printf_(int color, const char* fmt, ...) +{ + va_list args; + char buffer[256]; + int n; + + va_start(args, fmt); + vsnprintf(buffer, sizeof(buffer), fmt, args); + va_end(args); + buffer[sizeof(buffer)-1] = '\0'; + + if(!acutest_colorize_) { + return printf("%s", buffer); + } + +#if defined ACUTEST_UNIX_ + { + const char* col_str; + switch(color) { + case ACUTEST_COLOR_GREEN_: col_str = "\033[0;32m"; break; + case ACUTEST_COLOR_RED_: col_str = "\033[0;31m"; break; + case ACUTEST_COLOR_GREEN_INTENSIVE_: col_str = "\033[1;32m"; break; + case ACUTEST_COLOR_RED_INTENSIVE_: col_str = "\033[1;31m"; break; + case ACUTEST_COLOR_DEFAULT_INTENSIVE_: col_str = "\033[1m"; break; + default: col_str = "\033[0m"; break; + } + printf("%s", col_str); + n = printf("%s", buffer); + printf("\033[0m"); + return n; + } +#elif defined ACUTEST_WIN_ + { + HANDLE h; + CONSOLE_SCREEN_BUFFER_INFO info; + WORD attr; + + h = GetStdHandle(STD_OUTPUT_HANDLE); + GetConsoleScreenBufferInfo(h, &info); + + switch(color) { + case ACUTEST_COLOR_GREEN_: attr = FOREGROUND_GREEN; break; + case ACUTEST_COLOR_RED_: attr = FOREGROUND_RED; break; + case ACUTEST_COLOR_GREEN_INTENSIVE_: attr = FOREGROUND_GREEN | FOREGROUND_INTENSITY; break; + case ACUTEST_COLOR_RED_INTENSIVE_: attr = FOREGROUND_RED | FOREGROUND_INTENSITY; break; + case ACUTEST_COLOR_DEFAULT_INTENSIVE_: attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; break; + default: attr = 0; break; + } + if(attr != 0) + SetConsoleTextAttribute(h, attr); + n = printf("%s", buffer); + SetConsoleTextAttribute(h, info.wAttributes); + return n; + } +#else + n = printf("%s", buffer); + return n; +#endif +} + +static void +acutest_begin_test_line_(const struct acutest_test_* test) +{ + if(!acutest_tap_) { + if(acutest_verbose_level_ >= 3) { + acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Test %s:\n", test->name); + acutest_test_already_logged_++; + } else if(acutest_verbose_level_ >= 1) { + int n; + char spaces[48]; + + n = acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Test %s... ", test->name); + memset(spaces, ' ', sizeof(spaces)); + if(n < (int) sizeof(spaces)) + printf("%.*s", (int) sizeof(spaces) - n, spaces); + } else { + acutest_test_already_logged_ = 1; + } + } +} + +static void +acutest_finish_test_line_(int result) +{ + if(acutest_tap_) { + const char* str = (result == 0) ? "ok" : "not ok"; + + printf("%s %d - %s\n", str, acutest_current_index_ + 1, acutest_current_test_->name); + + if(result == 0 && acutest_timer_) { + printf("# Duration: "); + acutest_timer_print_diff_(); + printf("\n"); + } + } else { + int color = (result == 0) ? ACUTEST_COLOR_GREEN_INTENSIVE_ : ACUTEST_COLOR_RED_INTENSIVE_; + const char* str = (result == 0) ? "OK" : "FAILED"; + printf("[ "); + acutest_colored_printf_(color, "%s", str); + printf(" ]"); + + if(result == 0 && acutest_timer_) { + printf(" "); + acutest_timer_print_diff_(); + } + + printf("\n"); + } +} + +static void +acutest_line_indent_(int level) +{ + static const char spaces[] = " "; + int n = level * 2; + + if(acutest_tap_ && n > 0) { + n--; + printf("#"); + } + + while(n > 16) { + printf("%s", spaces); + n -= 16; + } + printf("%.*s", n, spaces); +} + +int ACUTEST_ATTRIBUTE_(format (printf, 4, 5)) +acutest_check_(int cond, const char* file, int line, const char* fmt, ...) +{ + const char *result_str; + int result_color; + int verbose_level; + + if(cond) { + result_str = "ok"; + result_color = ACUTEST_COLOR_GREEN_; + verbose_level = 3; + } else { + if(!acutest_test_already_logged_ && acutest_current_test_ != NULL) + acutest_finish_test_line_(-1); + + result_str = "failed"; + result_color = ACUTEST_COLOR_RED_; + verbose_level = 2; + acutest_test_failures_++; + acutest_test_already_logged_++; + } + + if(acutest_verbose_level_ >= verbose_level) { + va_list args; + + if(!acutest_case_already_logged_ && acutest_case_name_[0]) { + acutest_line_indent_(1); + acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Case %s:\n", acutest_case_name_); + acutest_test_already_logged_++; + acutest_case_already_logged_++; + } + + acutest_line_indent_(acutest_case_name_[0] ? 2 : 1); + if(file != NULL) { +#ifdef ACUTEST_WIN_ + const char* lastsep1 = strrchr(file, '\\'); + const char* lastsep2 = strrchr(file, '/'); + if(lastsep1 == NULL) + lastsep1 = file-1; + if(lastsep2 == NULL) + lastsep2 = file-1; + file = (lastsep1 > lastsep2 ? lastsep1 : lastsep2) + 1; +#else + const char* lastsep = strrchr(file, '/'); + if(lastsep != NULL) + file = lastsep+1; +#endif + printf("%s:%d: Check ", file, line); + } + + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + + printf("... "); + acutest_colored_printf_(result_color, "%s", result_str); + printf("\n"); + acutest_test_already_logged_++; + } + + acutest_cond_failed_ = (cond == 0); + return !acutest_cond_failed_; +} + +void ACUTEST_ATTRIBUTE_(format (printf, 1, 2)) +acutest_case_(const char* fmt, ...) +{ + va_list args; + + if(acutest_verbose_level_ < 2) + return; + + if(acutest_case_name_[0]) { + acutest_case_already_logged_ = 0; + acutest_case_name_[0] = '\0'; + } + + if(fmt == NULL) + return; + + va_start(args, fmt); + vsnprintf(acutest_case_name_, sizeof(acutest_case_name_) - 1, fmt, args); + va_end(args); + acutest_case_name_[sizeof(acutest_case_name_) - 1] = '\0'; + + if(acutest_verbose_level_ >= 3) { + acutest_line_indent_(1); + acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Case %s:\n", acutest_case_name_); + acutest_test_already_logged_++; + acutest_case_already_logged_++; + } +} + +void ACUTEST_ATTRIBUTE_(format (printf, 1, 2)) +acutest_message_(const char* fmt, ...) +{ + char buffer[TEST_MSG_MAXSIZE]; + char* line_beg; + char* line_end; + va_list args; + + if(acutest_verbose_level_ < 2) + return; + + /* We allow extra message only when something is already wrong in the + * current test. */ + if(acutest_current_test_ == NULL || !acutest_cond_failed_) + return; + + va_start(args, fmt); + vsnprintf(buffer, TEST_MSG_MAXSIZE, fmt, args); + va_end(args); + buffer[TEST_MSG_MAXSIZE-1] = '\0'; + + line_beg = buffer; + while(1) { + line_end = strchr(line_beg, '\n'); + if(line_end == NULL) + break; + acutest_line_indent_(acutest_case_name_[0] ? 3 : 2); + printf("%.*s\n", (int)(line_end - line_beg), line_beg); + line_beg = line_end + 1; + } + if(line_beg[0] != '\0') { + acutest_line_indent_(acutest_case_name_[0] ? 3 : 2); + printf("%s\n", line_beg); + } +} + +void +acutest_dump_(const char* title, const void* addr, size_t size) +{ + static const size_t BYTES_PER_LINE = 16; + size_t line_beg; + size_t truncate = 0; + + if(acutest_verbose_level_ < 2) + return; + + /* We allow extra message only when something is already wrong in the + * current test. */ + if(acutest_current_test_ == NULL || !acutest_cond_failed_) + return; + + if(size > TEST_DUMP_MAXSIZE) { + truncate = size - TEST_DUMP_MAXSIZE; + size = TEST_DUMP_MAXSIZE; + } + + acutest_line_indent_(acutest_case_name_[0] ? 3 : 2); + printf((title[strlen(title)-1] == ':') ? "%s\n" : "%s:\n", title); + + for(line_beg = 0; line_beg < size; line_beg += BYTES_PER_LINE) { + size_t line_end = line_beg + BYTES_PER_LINE; + size_t off; + + acutest_line_indent_(acutest_case_name_[0] ? 4 : 3); + printf("%08lx: ", (unsigned long)line_beg); + for(off = line_beg; off < line_end; off++) { + if(off < size) + printf(" %02x", ((const unsigned char*)addr)[off]); + else + printf(" "); + } + + printf(" "); + for(off = line_beg; off < line_end; off++) { + unsigned char byte = ((const unsigned char*)addr)[off]; + if(off < size) + printf("%c", (iscntrl(byte) ? '.' : byte)); + else + break; + } + + printf("\n"); + } + + if(truncate > 0) { + acutest_line_indent_(acutest_case_name_[0] ? 4 : 3); + printf(" ... (and more %u bytes)\n", (unsigned) truncate); + } +} + +/* This is called just before each test */ +static void +acutest_init_(const char *test_name) +{ +#ifdef TEST_INIT + TEST_INIT + ; /* Allow for a single unterminated function call */ +#endif + + /* Suppress any warnings about unused variable. */ + (void) test_name; +} + +/* This is called after each test */ +static void +acutest_fini_(const char *test_name) +{ +#ifdef TEST_FINI + TEST_FINI + ; /* Allow for a single unterminated function call */ +#endif + + /* Suppress any warnings about unused variable. */ + (void) test_name; +} + +void +acutest_abort_(void) +{ + if(acutest_abort_has_jmp_buf_) { + longjmp(acutest_abort_jmp_buf_, 1); + } else { + if(acutest_current_test_ != NULL) + acutest_fini_(acutest_current_test_->name); + abort(); + } +} + +static void +acutest_list_names_(void) +{ + const struct acutest_test_* test; + + printf("Unit tests:\n"); + for(test = ´st_list_[0]; test->func != NULL; test++) + printf(" %s\n", test->name); +} + +static void +acutest_remember_(int i) +{ + if(acutest_test_data_[i].flags & ACUTEST_FLAG_RUN_) + return; + + acutest_test_data_[i].flags |= ACUTEST_FLAG_RUN_; + acutest_count_++; +} + +static void +acutest_set_success_(int i, int success) +{ + acutest_test_data_[i].flags |= success ? ACUTEST_FLAG_SUCCESS_ : ACUTEST_FLAG_FAILURE_; +} + +static void +acutest_set_duration_(int i, double duration) +{ + acutest_test_data_[i].duration = duration; +} + +static int +acutest_name_contains_word_(const char* name, const char* pattern) +{ + static const char word_delim[] = " \t-_/.,:;"; + const char* substr; + size_t pattern_len; + + pattern_len = strlen(pattern); + + substr = strstr(name, pattern); + while(substr != NULL) { + int starts_on_word_boundary = (substr == name || strchr(word_delim, substr[-1]) != NULL); + int ends_on_word_boundary = (substr[pattern_len] == '\0' || strchr(word_delim, substr[pattern_len]) != NULL); + + if(starts_on_word_boundary && ends_on_word_boundary) + return 1; + + substr = strstr(substr+1, pattern); + } + + return 0; +} + +static int +acutest_lookup_(const char* pattern) +{ + int i; + int n = 0; + + /* Try exact match. */ + for(i = 0; i < (int) acutest_list_size_; i++) { + if(strcmp(acutest_list_[i].name, pattern) == 0) { + acutest_remember_(i); + n++; + break; + } + } + if(n > 0) + return n; + + /* Try word match. */ + for(i = 0; i < (int) acutest_list_size_; i++) { + if(acutest_name_contains_word_(acutest_list_[i].name, pattern)) { + acutest_remember_(i); + n++; + } + } + if(n > 0) + return n; + + /* Try relaxed match. */ + for(i = 0; i < (int) acutest_list_size_; i++) { + if(strstr(acutest_list_[i].name, pattern) != NULL) { + acutest_remember_(i); + n++; + } + } + + return n; +} + + +/* Called if anything goes bad in Acutest, or if the unit test ends in other + * way then by normal returning from its function (e.g. exception or some + * abnormal child process termination). */ +static void ACUTEST_ATTRIBUTE_(format (printf, 1, 2)) +acutest_error_(const char* fmt, ...) +{ + if(acutest_verbose_level_ == 0) + return; + + if(acutest_verbose_level_ >= 2) { + va_list args; + + acutest_line_indent_(1); + if(acutest_verbose_level_ >= 3) + acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "ERROR: "); + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + printf("\n"); + } + + if(acutest_verbose_level_ >= 3) { + printf("\n"); + } +} + +/* Call directly the given test unit function. */ +static int +acutest_do_run_(const struct acutest_test_* test, int index) +{ + int status = -1; + + acutest_was_aborted_ = 0; + acutest_current_test_ = test; + acutest_current_index_ = index; + acutest_test_failures_ = 0; + acutest_test_already_logged_ = 0; + acutest_cond_failed_ = 0; + +#ifdef __cplusplus + try { +#endif + acutest_init_(test->name); + acutest_begin_test_line_(test); + + /* This is good to do in case the test unit crashes. */ + fflush(stdout); + fflush(stderr); + + if(!acutest_worker_) { + acutest_abort_has_jmp_buf_ = 1; + if(setjmp(acutest_abort_jmp_buf_) != 0) { + acutest_was_aborted_ = 1; + goto aborted; + } + } + + acutest_timer_get_time_(´st_timer_start_); + test->func(); +aborted: + acutest_abort_has_jmp_buf_ = 0; + acutest_timer_get_time_(´st_timer_end_); + + if(acutest_verbose_level_ >= 3) { + acutest_line_indent_(1); + if(acutest_test_failures_ == 0) { + acutest_colored_printf_(ACUTEST_COLOR_GREEN_INTENSIVE_, "SUCCESS: "); + printf("All conditions have passed.\n"); + + if(acutest_timer_) { + acutest_line_indent_(1); + printf("Duration: "); + acutest_timer_print_diff_(); + printf("\n"); + } + } else { + acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED: "); + if(!acutest_was_aborted_) { + printf("%d condition%s %s failed.\n", + acutest_test_failures_, + (acutest_test_failures_ == 1) ? "" : "s", + (acutest_test_failures_ == 1) ? "has" : "have"); + } else { + printf("Aborted.\n"); + } + } + printf("\n"); + } else if(acutest_verbose_level_ >= 1 && acutest_test_failures_ == 0) { + acutest_finish_test_line_(0); + } + + status = (acutest_test_failures_ == 0) ? 0 : -1; + +#ifdef __cplusplus + } catch(std::exception& e) { + const char* what = e.what(); + acutest_check_(0, NULL, 0, "Threw std::exception"); + if(what != NULL) + acutest_message_("std::exception::what(): %s", what); + + if(acutest_verbose_level_ >= 3) { + acutest_line_indent_(1); + acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED: "); + printf("C++ exception.\n\n"); + } + } catch(...) { + acutest_check_(0, NULL, 0, "Threw an exception"); + + if(acutest_verbose_level_ >= 3) { + acutest_line_indent_(1); + acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED: "); + printf("C++ exception.\n\n"); + } + } +#endif + + acutest_fini_(test->name); + acutest_case_(NULL); + acutest_current_test_ = NULL; + + return status; +} + +/* Trigger the unit test. If possible (and not suppressed) it starts a child + * process who calls acutest_do_run_(), otherwise it calls acutest_do_run_() + * directly. */ +static void +acutest_run_(const struct acutest_test_* test, int index, int master_index) +{ + int failed = 1; + acutest_timer_type_ start, end; + + acutest_current_test_ = test; + acutest_test_already_logged_ = 0; + acutest_timer_get_time_(&start); + + if(!acutest_no_exec_) { + +#if defined(ACUTEST_UNIX_) + + pid_t pid; + int exit_code; + + /* Make sure the child starts with empty I/O buffers. */ + fflush(stdout); + fflush(stderr); + + pid = fork(); + if(pid == (pid_t)-1) { + acutest_error_("Cannot fork. %s [%d]", strerror(errno), errno); + failed = 1; + } else if(pid == 0) { + /* Child: Do the test. */ + acutest_worker_ = 1; + failed = (acutest_do_run_(test, index) != 0); + acutest_exit_(failed ? 1 : 0); + } else { + /* Parent: Wait until child terminates and analyze its exit code. */ + waitpid(pid, &exit_code, 0); + if(WIFEXITED(exit_code)) { + switch(WEXITSTATUS(exit_code)) { + case 0: failed = 0; break; /* test has passed. */ + case 1: /* noop */ break; /* "normal" failure. */ + default: acutest_error_("Unexpected exit code [%d]", WEXITSTATUS(exit_code)); + } + } else if(WIFSIGNALED(exit_code)) { + char tmp[32]; + const char* signame; + switch(WTERMSIG(exit_code)) { + case SIGINT: signame = "SIGINT"; break; + case SIGHUP: signame = "SIGHUP"; break; + case SIGQUIT: signame = "SIGQUIT"; break; + case SIGABRT: signame = "SIGABRT"; break; + case SIGKILL: signame = "SIGKILL"; break; + case SIGSEGV: signame = "SIGSEGV"; break; + case SIGILL: signame = "SIGILL"; break; + case SIGTERM: signame = "SIGTERM"; break; + default: sprintf(tmp, "signal %d", WTERMSIG(exit_code)); signame = tmp; break; + } + acutest_error_("Test interrupted by %s.", signame); + } else { + acutest_error_("Test ended in an unexpected way [%d].", exit_code); + } + } + +#elif defined(ACUTEST_WIN_) + + char buffer[512] = {0}; + STARTUPINFOA startupInfo; + PROCESS_INFORMATION processInfo; + DWORD exitCode; + + /* Windows has no fork(). So we propagate all info into the child + * through a command line arguments. */ + _snprintf(buffer, sizeof(buffer)-1, + "%s --worker=%d %s --no-exec --no-summary %s --verbose=%d --color=%s -- \"%s\"", + acutest_argv0_, index, acutest_timer_ ? "--time" : "", + acutest_tap_ ? "--tap" : "", acutest_verbose_level_, + acutest_colorize_ ? "always" : "never", + test->name); + memset(&startupInfo, 0, sizeof(startupInfo)); + startupInfo.cb = sizeof(STARTUPINFO); + if(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo)) { + WaitForSingleObject(processInfo.hProcess, INFINITE); + GetExitCodeProcess(processInfo.hProcess, &exitCode); + CloseHandle(processInfo.hThread); + CloseHandle(processInfo.hProcess); + failed = (exitCode != 0); + if(exitCode > 1) { + switch(exitCode) { + case 3: acutest_error_("Aborted."); break; + case 0xC0000005: acutest_error_("Access violation."); break; + default: acutest_error_("Test ended in an unexpected way [%lu].", exitCode); break; + } + } + } else { + acutest_error_("Cannot create unit test subprocess [%ld].", GetLastError()); + failed = 1; + } + +#else + + /* A platform where we don't know how to run child process. */ + failed = (acutest_do_run_(test, index) != 0); + +#endif + + } else { + /* Child processes suppressed through --no-exec. */ + failed = (acutest_do_run_(test, index) != 0); + } + acutest_timer_get_time_(&end); + + acutest_current_test_ = NULL; + + acutest_stat_run_units_++; + if(failed) + acutest_stat_failed_units_++; + + acutest_set_success_(master_index, !failed); + acutest_set_duration_(master_index, acutest_timer_diff_(start, end)); +} + +#if defined(ACUTEST_WIN_) +/* Callback for SEH events. */ +static LONG CALLBACK +acutest_seh_exception_filter_(EXCEPTION_POINTERS *ptrs) +{ + acutest_check_(0, NULL, 0, "Unhandled SEH exception"); + acutest_message_("Exception code: 0x%08lx", ptrs->ExceptionRecord->ExceptionCode); + acutest_message_("Exception address: 0x%p", ptrs->ExceptionRecord->ExceptionAddress); + + fflush(stdout); + fflush(stderr); + + return EXCEPTION_EXECUTE_HANDLER; +} +#endif + + +#define ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ 0x0001 +#define ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_ 0x0002 + +#define ACUTEST_CMDLINE_OPTID_NONE_ 0 +#define ACUTEST_CMDLINE_OPTID_UNKNOWN_ (-0x7fffffff + 0) +#define ACUTEST_CMDLINE_OPTID_MISSINGARG_ (-0x7fffffff + 1) +#define ACUTEST_CMDLINE_OPTID_BOGUSARG_ (-0x7fffffff + 2) + +typedef struct acutest_test_CMDLINE_OPTION_ { + char shortname; + const char* longname; + int id; + unsigned flags; +} ACUTEST_CMDLINE_OPTION_; + +static int +acutest_cmdline_handle_short_opt_group_(const ACUTEST_CMDLINE_OPTION_* options, + const char* arggroup, + int (*callback)(int /*optval*/, const char* /*arg*/)) +{ + const ACUTEST_CMDLINE_OPTION_* opt; + int i; + int ret = 0; + + for(i = 0; arggroup[i] != '\0'; i++) { + for(opt = options; opt->id != 0; opt++) { + if(arggroup[i] == opt->shortname) + break; + } + + if(opt->id != 0 && !(opt->flags & ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_)) { + ret = callback(opt->id, NULL); + } else { + /* Unknown option. */ + char badoptname[3]; + badoptname[0] = '-'; + badoptname[1] = arggroup[i]; + badoptname[2] = '\0'; + ret = callback((opt->id != 0 ? ACUTEST_CMDLINE_OPTID_MISSINGARG_ : ACUTEST_CMDLINE_OPTID_UNKNOWN_), + badoptname); + } + + if(ret != 0) + break; + } + + return ret; +} + +#define ACUTEST_CMDLINE_AUXBUF_SIZE_ 32 + +static int +acutest_cmdline_read_(const ACUTEST_CMDLINE_OPTION_* options, int argc, char** argv, + int (*callback)(int /*optval*/, const char* /*arg*/)) +{ + + const ACUTEST_CMDLINE_OPTION_* opt; + char auxbuf[ACUTEST_CMDLINE_AUXBUF_SIZE_+1]; + int after_doubledash = 0; + int i = 1; + int ret = 0; + + auxbuf[ACUTEST_CMDLINE_AUXBUF_SIZE_] = '\0'; + + while(i < argc) { + if(after_doubledash || strcmp(argv[i], "-") == 0) { + /* Non-option argument. */ + ret = callback(ACUTEST_CMDLINE_OPTID_NONE_, argv[i]); + } else if(strcmp(argv[i], "--") == 0) { + /* End of options. All the remaining members are non-option arguments. */ + after_doubledash = 1; + } else if(argv[i][0] != '-') { + /* Non-option argument. */ + ret = callback(ACUTEST_CMDLINE_OPTID_NONE_, argv[i]); + } else { + for(opt = options; opt->id != 0; opt++) { + if(opt->longname != NULL && strncmp(argv[i], "--", 2) == 0) { + size_t len = strlen(opt->longname); + if(strncmp(argv[i]+2, opt->longname, len) == 0) { + /* Regular long option. */ + if(argv[i][2+len] == '\0') { + /* with no argument provided. */ + if(!(opt->flags & ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_)) + ret = callback(opt->id, NULL); + else + ret = callback(ACUTEST_CMDLINE_OPTID_MISSINGARG_, argv[i]); + break; + } else if(argv[i][2+len] == '=') { + /* with an argument provided. */ + if(opt->flags & (ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ | ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_)) { + ret = callback(opt->id, argv[i]+2+len+1); + } else { + sprintf(auxbuf, "--%s", opt->longname); + ret = callback(ACUTEST_CMDLINE_OPTID_BOGUSARG_, auxbuf); + } + break; + } else { + continue; + } + } + } else if(opt->shortname != '\0' && argv[i][0] == '-') { + if(argv[i][1] == opt->shortname) { + /* Regular short option. */ + if(opt->flags & ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_) { + if(argv[i][2] != '\0') + ret = callback(opt->id, argv[i]+2); + else if(i+1 < argc) + ret = callback(opt->id, argv[++i]); + else + ret = callback(ACUTEST_CMDLINE_OPTID_MISSINGARG_, argv[i]); + break; + } else { + ret = callback(opt->id, NULL); + + /* There might be more (argument-less) short options + * grouped together. */ + if(ret == 0 && argv[i][2] != '\0') + ret = acutest_cmdline_handle_short_opt_group_(options, argv[i]+2, callback); + break; + } + } + } + } + + if(opt->id == 0) { /* still not handled? */ + if(argv[i][0] != '-') { + /* Non-option argument. */ + ret = callback(ACUTEST_CMDLINE_OPTID_NONE_, argv[i]); + } else { + /* Unknown option. */ + char* badoptname = argv[i]; + + if(strncmp(badoptname, "--", 2) == 0) { + /* Strip any argument from the long option. */ + char* assignment = strchr(badoptname, '='); + if(assignment != NULL) { + size_t len = assignment - badoptname; + if(len > ACUTEST_CMDLINE_AUXBUF_SIZE_) + len = ACUTEST_CMDLINE_AUXBUF_SIZE_; + strncpy(auxbuf, badoptname, len); + auxbuf[len] = '\0'; + badoptname = auxbuf; + } + } + + ret = callback(ACUTEST_CMDLINE_OPTID_UNKNOWN_, badoptname); + } + } + } + + if(ret != 0) + return ret; + i++; + } + + return ret; +} + +static void +acutest_help_(void) +{ + printf("Usage: %s [options] [test...]\n", acutest_argv0_); + printf("\n"); + printf("Run the specified unit tests; or if the option '--skip' is used, run all\n"); + printf("tests in the suite but those listed. By default, if no tests are specified\n"); + printf("on the command line, all unit tests in the suite are run.\n"); + printf("\n"); + printf("Options:\n"); + printf(" -s, --skip Execute all unit tests but the listed ones\n"); + printf(" --exec[=WHEN] If supported, execute unit tests as child processes\n"); + printf(" (WHEN is one of 'auto', 'always', 'never')\n"); + printf(" -E, --no-exec Same as --exec=never\n"); +#if defined ACUTEST_WIN_ + printf(" -t, --time Measure test duration\n"); +#elif defined ACUTEST_HAS_POSIX_TIMER_ + printf(" -t, --time Measure test duration (real time)\n"); + printf(" --time=TIMER Measure test duration, using given timer\n"); + printf(" (TIMER is one of 'real', 'cpu')\n"); +#endif + printf(" --no-summary Suppress printing of test results summary\n"); + printf(" --tap Produce TAP-compliant output\n"); + printf(" (See https://testanything.org/)\n"); + printf(" -x, --xml-output=FILE Enable XUnit output to the given file\n"); + printf(" -l, --list List unit tests in the suite and exit\n"); + printf(" -v, --verbose Make output more verbose\n"); + printf(" --verbose=LEVEL Set verbose level to LEVEL:\n"); + printf(" 0 ... Be silent\n"); + printf(" 1 ... Output one line per test (and summary)\n"); + printf(" 2 ... As 1 and failed conditions (this is default)\n"); + printf(" 3 ... As 1 and all conditions (and extended summary)\n"); + printf(" -q, --quiet Same as --verbose=0\n"); + printf(" --color[=WHEN] Enable colorized output\n"); + printf(" (WHEN is one of 'auto', 'always', 'never')\n"); + printf(" --no-color Same as --color=never\n"); + printf(" -h, --help Display this help and exit\n"); + + if(acutest_list_size_ < 16) { + printf("\n"); + acutest_list_names_(); + } +} + +static const ACUTEST_CMDLINE_OPTION_ acutest_cmdline_options_[] = { + { 's', "skip", 's', 0 }, + { 0, "exec", 'e', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, + { 'E', "no-exec", 'E', 0 }, +#if defined ACUTEST_WIN_ + { 't', "time", 't', 0 }, + { 0, "timer", 't', 0 }, /* kept for compatibility */ +#elif defined ACUTEST_HAS_POSIX_TIMER_ + { 't', "time", 't', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, + { 0, "timer", 't', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, /* kept for compatibility */ +#endif + { 0, "no-summary", 'S', 0 }, + { 0, "tap", 'T', 0 }, + { 'l', "list", 'l', 0 }, + { 'v', "verbose", 'v', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, + { 'q', "quiet", 'q', 0 }, + { 0, "color", 'c', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, + { 0, "no-color", 'C', 0 }, + { 'h', "help", 'h', 0 }, + { 0, "worker", 'w', ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_ }, /* internal */ + { 'x', "xml-output", 'x', ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_ }, + { 0, NULL, 0, 0 } +}; + +static int +acutest_cmdline_callback_(int id, const char* arg) +{ + switch(id) { + case 's': + acutest_skip_mode_ = 1; + break; + + case 'e': + if(arg == NULL || strcmp(arg, "always") == 0) { + acutest_no_exec_ = 0; + } else if(strcmp(arg, "never") == 0) { + acutest_no_exec_ = 1; + } else if(strcmp(arg, "auto") == 0) { + /*noop*/ + } else { + fprintf(stderr, "%s: Unrecognized argument '%s' for option --exec.\n", acutest_argv0_, arg); + fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); + acutest_exit_(2); + } + break; + + case 'E': + acutest_no_exec_ = 1; + break; + + case 't': +#if defined ACUTEST_WIN_ || defined ACUTEST_HAS_POSIX_TIMER_ + if(arg == NULL || strcmp(arg, "real") == 0) { + acutest_timer_ = 1; + #ifndef ACUTEST_WIN_ + } else if(strcmp(arg, "cpu") == 0) { + acutest_timer_ = 2; + #endif + } else { + fprintf(stderr, "%s: Unrecognized argument '%s' for option --time.\n", acutest_argv0_, arg); + fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); + acutest_exit_(2); + } +#endif + break; + + case 'S': + acutest_no_summary_ = 1; + break; + + case 'T': + acutest_tap_ = 1; + break; + + case 'l': + acutest_list_names_(); + acutest_exit_(0); + break; + + case 'v': + acutest_verbose_level_ = (arg != NULL ? atoi(arg) : acutest_verbose_level_+1); + break; + + case 'q': + acutest_verbose_level_ = 0; + break; + + case 'c': + if(arg == NULL || strcmp(arg, "always") == 0) { + acutest_colorize_ = 1; + } else if(strcmp(arg, "never") == 0) { + acutest_colorize_ = 0; + } else if(strcmp(arg, "auto") == 0) { + /*noop*/ + } else { + fprintf(stderr, "%s: Unrecognized argument '%s' for option --color.\n", acutest_argv0_, arg); + fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); + acutest_exit_(2); + } + break; + + case 'C': + acutest_colorize_ = 0; + break; + + case 'h': + acutest_help_(); + acutest_exit_(0); + break; + + case 'w': + acutest_worker_ = 1; + acutest_worker_index_ = atoi(arg); + break; + case 'x': + acutest_xml_output_ = fopen(arg, "w"); + if (!acutest_xml_output_) { + fprintf(stderr, "Unable to open '%s': %s\n", arg, strerror(errno)); + acutest_exit_(2); + } + break; + + case 0: + if(acutest_lookup_(arg) == 0) { + fprintf(stderr, "%s: Unrecognized unit test '%s'\n", acutest_argv0_, arg); + fprintf(stderr, "Try '%s --list' for list of unit tests.\n", acutest_argv0_); + acutest_exit_(2); + } + break; + + case ACUTEST_CMDLINE_OPTID_UNKNOWN_: + fprintf(stderr, "Unrecognized command line option '%s'.\n", arg); + fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); + acutest_exit_(2); + break; + + case ACUTEST_CMDLINE_OPTID_MISSINGARG_: + fprintf(stderr, "The command line option '%s' requires an argument.\n", arg); + fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); + acutest_exit_(2); + break; + + case ACUTEST_CMDLINE_OPTID_BOGUSARG_: + fprintf(stderr, "The command line option '%s' does not expect an argument.\n", arg); + fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); + acutest_exit_(2); + break; + } + + return 0; +} + + +#ifdef ACUTEST_LINUX_ +static int +acutest_is_tracer_present_(void) +{ + /* Must be large enough so the line 'TracerPid: ${PID}' can fit in. */ + static const int OVERLAP = 32; + + char buf[256+OVERLAP+1]; + int tracer_present = 0; + int fd; + size_t n_read = 0; + + fd = open("/proc/self/status", O_RDONLY); + if(fd == -1) + return 0; + + while(1) { + static const char pattern[] = "TracerPid:"; + const char* field; + + while(n_read < sizeof(buf) - 1) { + ssize_t n; + + n = read(fd, buf + n_read, sizeof(buf) - 1 - n_read); + if(n <= 0) + break; + n_read += n; + } + buf[n_read] = '\0'; + + field = strstr(buf, pattern); + if(field != NULL && field < buf + sizeof(buf) - OVERLAP) { + pid_t tracer_pid = (pid_t) atoi(field + sizeof(pattern) - 1); + tracer_present = (tracer_pid != 0); + break; + } + + if(n_read == sizeof(buf)-1) { + memmove(buf, buf + sizeof(buf)-1 - OVERLAP, OVERLAP); + n_read = OVERLAP; + } else { + break; + } + } + + close(fd); + return tracer_present; +} +#endif + +int +main(int argc, char** argv) +{ + int i; + + acutest_argv0_ = argv[0]; + +#if defined ACUTEST_UNIX_ + acutest_colorize_ = isatty(STDOUT_FILENO); +#elif defined ACUTEST_WIN_ + #if defined _BORLANDC_ + acutest_colorize_ = isatty(_fileno(stdout)); + #else + acutest_colorize_ = _isatty(_fileno(stdout)); + #endif +#else + acutest_colorize_ = 0; +#endif + + /* Count all test units */ + acutest_list_size_ = 0; + for(i = 0; acutest_list_[i].func != NULL; i++) + acutest_list_size_++; + + acutest_test_data_ = (struct acutest_test_data_*)calloc(acutest_list_size_, sizeof(struct acutest_test_data_)); + if(acutest_test_data_ == NULL) { + fprintf(stderr, "Out of memory.\n"); + acutest_exit_(2); + } + + /* Parse options */ + acutest_cmdline_read_(acutest_cmdline_options_, argc, argv, acutest_cmdline_callback_); + + /* Initialize the proper timer. */ + acutest_timer_init_(); + +#if defined(ACUTEST_WIN_) + SetUnhandledExceptionFilter(acutest_seh_exception_filter_); +#ifdef _MSC_VER + _set_abort_behavior(0, _WRITE_ABORT_MSG); +#endif +#endif + + /* By default, we want to run all tests. */ + if(acutest_count_ == 0) { + for(i = 0; acutest_list_[i].func != NULL; i++) + acutest_remember_(i); + } + + /* Guess whether we want to run unit tests as child processes. */ + if(acutest_no_exec_ < 0) { + acutest_no_exec_ = 0; + + if(acutest_count_ <= 1) { + acutest_no_exec_ = 1; + } else { +#ifdef ACUTEST_WIN_ + if(IsDebuggerPresent()) + acutest_no_exec_ = 1; +#endif +#ifdef ACUTEST_LINUX_ + if(acutest_is_tracer_present_()) + acutest_no_exec_ = 1; +#endif +#ifdef RUNNING_ON_VALGRIND + /* RUNNING_ON_VALGRIND is provided by optionally included */ + if(RUNNING_ON_VALGRIND) + acutest_no_exec_ = 1; +#endif + } + } + + if(acutest_tap_) { + /* TAP requires we know test result ("ok", "not ok") before we output + * anything about the test, and this gets problematic for larger verbose + * levels. */ + if(acutest_verbose_level_ > 2) + acutest_verbose_level_ = 2; + + /* TAP harness should provide some summary. */ + acutest_no_summary_ = 1; + + if(!acutest_worker_) + printf("1..%d\n", (int) acutest_count_); + } + + int index = acutest_worker_index_; + for(i = 0; acutest_list_[i].func != NULL; i++) { + int run = (acutest_test_data_[i].flags & ACUTEST_FLAG_RUN_); + if (acutest_skip_mode_) /* Run all tests except those listed. */ + run = !run; + if(run) + acutest_run_(´st_list_[i], index++, i); + } + + /* Write a summary */ + if(!acutest_no_summary_ && acutest_verbose_level_ >= 1) { + if(acutest_verbose_level_ >= 3) { + acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Summary:\n"); + + printf(" Count of all unit tests: %4d\n", (int) acutest_list_size_); + printf(" Count of run unit tests: %4d\n", acutest_stat_run_units_); + printf(" Count of failed unit tests: %4d\n", acutest_stat_failed_units_); + printf(" Count of skipped unit tests: %4d\n", (int) acutest_list_size_ - acutest_stat_run_units_); + } + + if(acutest_stat_failed_units_ == 0) { + acutest_colored_printf_(ACUTEST_COLOR_GREEN_INTENSIVE_, "SUCCESS:"); + printf(" All unit tests have passed.\n"); + } else { + acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED:"); + printf(" %d of %d unit tests %s failed.\n", + acutest_stat_failed_units_, acutest_stat_run_units_, + (acutest_stat_failed_units_ == 1) ? "has" : "have"); + } + + if(acutest_verbose_level_ >= 3) + printf("\n"); + } + + if (acutest_xml_output_) { +#if defined ACUTEST_UNIX_ + char *suite_name = basename(argv[0]); +#elif defined ACUTEST_WIN_ + char suite_name[_MAX_FNAME]; + _splitpath(argv[0], NULL, NULL, suite_name, NULL); +#else + const char *suite_name = argv[0]; +#endif + fprintf(acutest_xml_output_, "\n"); + fprintf(acutest_xml_output_, "\n", + suite_name, (int)acutest_list_size_, acutest_stat_failed_units_, acutest_stat_failed_units_, + (int)acutest_list_size_ - acutest_stat_run_units_); + for(i = 0; acutest_list_[i].func != NULL; i++) { + struct acutest_test_data_ *details = ´st_test_data_[i]; + fprintf(acutest_xml_output_, " \n", acutest_list_[i].name, details->duration); + if (details->flags & ACUTEST_FLAG_FAILURE_) + fprintf(acutest_xml_output_, " \n"); + if (!(details->flags & ACUTEST_FLAG_FAILURE_) && !(details->flags & ACUTEST_FLAG_SUCCESS_)) + fprintf(acutest_xml_output_, " \n"); + fprintf(acutest_xml_output_, " \n"); + } + fprintf(acutest_xml_output_, "\n"); + fclose(acutest_xml_output_); + } + + acutest_cleanup_(); + + return (acutest_stat_failed_units_ == 0) ? 0 : 1; +} + + +#endif /* #ifndef TEST_NO_MAIN */ + +#ifdef _MSC_VER + #pragma warning(pop) +#endif + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* #ifndef ACUTEST_H */ diff --git a/graalpython/hpy/c_test/test_debug_handles.c b/graalpython/hpy/c_test/test_debug_handles.c new file mode 100644 index 0000000000..a5584fdb39 --- /dev/null +++ b/graalpython/hpy/c_test/test_debug_handles.c @@ -0,0 +1,99 @@ +#include +#include "acutest.h" // https://github.com/mity/acutest +#include "hpy/debug/src/debug_internal.h" + +static void check_DHQueue(DHQueue *q, HPy_ssize_t size, ...) +{ + va_list argp; + va_start(argp, size); + DHQueue_sanity_check(q); + TEST_CHECK(q->size == size); + DHQueueNode *h = q->head; + while(h != NULL) { + DHQueueNode *expected = va_arg(argp, DHQueueNode*); + TEST_CHECK(h == expected); + h = h->next; + } + va_end(argp); +} + +void test_DHQueue_init(void) +{ + DHQueue q; + DHQueue_init(&q); + TEST_CHECK(q.head == NULL); + TEST_CHECK(q.tail == NULL); + TEST_CHECK(q.size == 0); + DHQueue_sanity_check(&q); +} + +void test_DHQueue_append(void) +{ + DHQueue q; + DHQueueNode h1; + DHQueueNode h2; + DHQueueNode h3; + DHQueue_init(&q); + DHQueue_append(&q, &h1); + DHQueue_append(&q, &h2); + DHQueue_append(&q, &h3); + check_DHQueue(&q, 3, &h1, &h2, &h3); +} + +void test_DHQueue_popfront(void) +{ + DHQueue q; + DHQueueNode h1; + DHQueueNode h2; + DHQueueNode h3; + DHQueue_init(&q); + DHQueue_append(&q, &h1); + DHQueue_append(&q, &h2); + DHQueue_append(&q, &h3); + + TEST_CHECK(DHQueue_popfront(&q) == &h1); + check_DHQueue(&q, 2, &h2, &h3); + + TEST_CHECK(DHQueue_popfront(&q) == &h2); + check_DHQueue(&q, 1, &h3); + + TEST_CHECK(DHQueue_popfront(&q) == &h3); + check_DHQueue(&q, 0); +} + + +void test_DHQueue_remove(void) +{ + DHQueue q; + DHQueueNode h1; + DHQueueNode h2; + DHQueueNode h3; + DHQueueNode h4; + DHQueue_init(&q); + DHQueue_append(&q, &h1); + DHQueue_append(&q, &h2); + DHQueue_append(&q, &h3); + DHQueue_append(&q, &h4); + + DHQueue_remove(&q, &h3); // try to remove something in the middle + check_DHQueue(&q, 3, &h1, &h2, &h4); + + DHQueue_remove(&q, &h1); // try to remove the head + check_DHQueue(&q, 2, &h2, &h4); + + DHQueue_remove(&q, &h4); // try to remove the tail + check_DHQueue(&q, 1, &h2); + + DHQueue_remove(&q, &h2); // try to remove the only element + check_DHQueue(&q, 0); +} + +#define MYTEST(X) { #X, X } + +TEST_LIST = { + MYTEST(test_DHQueue_init), + MYTEST(test_DHQueue_append), + MYTEST(test_DHQueue_popfront), + MYTEST(test_DHQueue_remove), + { NULL, NULL } +}; diff --git a/graalpython/hpy/c_test/test_stacktrace.c b/graalpython/hpy/c_test/test_stacktrace.c new file mode 100644 index 0000000000..5d02eced84 --- /dev/null +++ b/graalpython/hpy/c_test/test_stacktrace.c @@ -0,0 +1,22 @@ +// Smoke test for the create_stacktrace function + +#include +#include "acutest.h" // https://github.com/mity/acutest +#include "hpy/debug/src/debug_internal.h" + +void test_create_stacktrace(void) +{ + char *trace; + create_stacktrace(&trace, 16); + if (trace != NULL) { + printf("\n\nTRACE:\n%s\n\n", trace); + free(trace); + } +} + +#define MYTEST(X) { #X, X } + +TEST_LIST = { + MYTEST(test_create_stacktrace), + { NULL, NULL } +}; \ No newline at end of file diff --git a/graalpython/hpy/docs/Makefile b/graalpython/hpy/docs/Makefile new file mode 100644 index 0000000000..7164c8d0e5 --- /dev/null +++ b/graalpython/hpy/docs/Makefile @@ -0,0 +1,28 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +livehtml: + @sphinx-autobuild \ + "$(SOURCEDIR)" \ + -b html \ + --ignore "*~" \ + --ignore ".#*" \ + $(SPHINXOPTS) $(BUILDDIR)/html diff --git a/graalpython/hpy/docs/_static/README.txt b/graalpython/hpy/docs/_static/README.txt new file mode 100644 index 0000000000..4d871f5a5a --- /dev/null +++ b/graalpython/hpy/docs/_static/README.txt @@ -0,0 +1 @@ +Static files for the Sphinx documentation. diff --git a/graalpython/hpy/docs/_templates/README.txt b/graalpython/hpy/docs/_templates/README.txt new file mode 100644 index 0000000000..2dc51448da --- /dev/null +++ b/graalpython/hpy/docs/_templates/README.txt @@ -0,0 +1 @@ +Template files for the Sphinx documentation. diff --git a/graalpython/hpy/docs/api-reference/argument-parsing.rst b/graalpython/hpy/docs/api-reference/argument-parsing.rst new file mode 100644 index 0000000000..ff22665254 --- /dev/null +++ b/graalpython/hpy/docs/api-reference/argument-parsing.rst @@ -0,0 +1,5 @@ +Argument Parsing +================ + +.. autocmodule:: runtime/argparse.c + :members: diff --git a/graalpython/hpy/docs/api-reference/build-value.rst b/graalpython/hpy/docs/api-reference/build-value.rst new file mode 100644 index 0000000000..a8cafb6bfe --- /dev/null +++ b/graalpython/hpy/docs/api-reference/build-value.rst @@ -0,0 +1,5 @@ +Building Complex Python Objects +=============================== + +.. autocmodule:: runtime/buildvalue.c + :members: diff --git a/graalpython/hpy/docs/api-reference/formatting.rst b/graalpython/hpy/docs/api-reference/formatting.rst new file mode 100644 index 0000000000..f4ea6f26f4 --- /dev/null +++ b/graalpython/hpy/docs/api-reference/formatting.rst @@ -0,0 +1,5 @@ +String Formatting Helpers +========================= + +.. autocmodule:: runtime/format.c + :no-members: diff --git a/graalpython/hpy/docs/api-reference/function-index.rst b/graalpython/hpy/docs/api-reference/function-index.rst new file mode 100644 index 0000000000..5e2cbcb59b --- /dev/null +++ b/graalpython/hpy/docs/api-reference/function-index.rst @@ -0,0 +1,187 @@ + +.. note: DO NOT EDIT THIS FILE! + This file is automatically generated by hpy.tools.autogen.doc.autogen_function_index + See also hpy.tools.autogen and hpy/tools/public_api.h + + Run this to regenerate: + make autogen + +HPy Core API Function Index +########################### + +* :c:func:`HPyBool_FromBool` +* :c:func:`HPyBytes_AS_STRING` +* :c:func:`HPyBytes_AsString` +* :c:func:`HPyBytes_Check` +* :c:func:`HPyBytes_FromString` +* :c:func:`HPyBytes_FromStringAndSize` +* :c:func:`HPyBytes_GET_SIZE` +* :c:func:`HPyBytes_Size` +* :c:func:`HPyCallable_Check` +* :c:func:`HPyCapsule_Get` +* :c:func:`HPyCapsule_IsValid` +* :c:func:`HPyCapsule_New` +* :c:func:`HPyCapsule_Set` +* :c:func:`HPyContextVar_Get` +* :c:func:`HPyContextVar_New` +* :c:func:`HPyContextVar_Set` +* :c:func:`HPyDict_Check` +* :c:func:`HPyDict_Copy` +* :c:func:`HPyDict_Keys` +* :c:func:`HPyDict_New` +* :c:func:`HPyErr_Clear` +* :c:func:`HPyErr_ExceptionMatches` +* :c:func:`HPyErr_NewException` +* :c:func:`HPyErr_NewExceptionWithDoc` +* :c:func:`HPyErr_NoMemory` +* :c:func:`HPyErr_Occurred` +* :c:func:`HPyErr_SetFromErrnoWithFilename` +* :c:func:`HPyErr_SetFromErrnoWithFilenameObjects` +* :c:func:`HPyErr_SetObject` +* :c:func:`HPyErr_SetString` +* :c:func:`HPyErr_WarnEx` +* :c:func:`HPyErr_WriteUnraisable` +* :c:func:`HPyField_Load` +* :c:func:`HPyField_Store` +* :c:func:`HPyFloat_AsDouble` +* :c:func:`HPyFloat_FromDouble` +* :c:func:`HPyGlobal_Load` +* :c:func:`HPyGlobal_Store` +* :c:func:`HPyImport_ImportModule` +* :c:func:`HPyIter_Check` +* :c:func:`HPyIter_Next` +* :c:func:`HPyListBuilder_Build` +* :c:func:`HPyListBuilder_Cancel` +* :c:func:`HPyListBuilder_New` +* :c:func:`HPyListBuilder_Set` +* :c:func:`HPyList_Append` +* :c:func:`HPyList_Check` +* :c:func:`HPyList_Insert` +* :c:func:`HPyList_New` +* :c:func:`HPyLong_AsDouble` +* :c:func:`HPyLong_AsInt32_t` +* :c:func:`HPyLong_AsInt64_t` +* :c:func:`HPyLong_AsSize_t` +* :c:func:`HPyLong_AsSsize_t` +* :c:func:`HPyLong_AsUInt32_t` +* :c:func:`HPyLong_AsUInt32_tMask` +* :c:func:`HPyLong_AsUInt64_t` +* :c:func:`HPyLong_AsUInt64_tMask` +* :c:func:`HPyLong_AsVoidPtr` +* :c:func:`HPyLong_FromInt32_t` +* :c:func:`HPyLong_FromInt64_t` +* :c:func:`HPyLong_FromSize_t` +* :c:func:`HPyLong_FromSsize_t` +* :c:func:`HPyLong_FromUInt32_t` +* :c:func:`HPyLong_FromUInt64_t` +* :c:func:`HPyNumber_Check` +* :c:func:`HPySlice_New` +* :c:func:`HPySlice_Unpack` +* :c:func:`HPyTracker_Add` +* :c:func:`HPyTracker_Close` +* :c:func:`HPyTracker_ForgetAll` +* :c:func:`HPyTracker_New` +* :c:func:`HPyTupleBuilder_Build` +* :c:func:`HPyTupleBuilder_Cancel` +* :c:func:`HPyTupleBuilder_New` +* :c:func:`HPyTupleBuilder_Set` +* :c:func:`HPyTuple_Check` +* :c:func:`HPyTuple_FromArray` +* :c:func:`HPyType_FromSpec` +* :c:func:`HPyType_GenericNew` +* :c:func:`HPyType_GetName` +* :c:func:`HPyType_IsSubtype` +* :c:func:`HPyUnicode_AsASCIIString` +* :c:func:`HPyUnicode_AsLatin1String` +* :c:func:`HPyUnicode_AsUTF8AndSize` +* :c:func:`HPyUnicode_AsUTF8String` +* :c:func:`HPyUnicode_Check` +* :c:func:`HPyUnicode_DecodeASCII` +* :c:func:`HPyUnicode_DecodeFSDefault` +* :c:func:`HPyUnicode_DecodeFSDefaultAndSize` +* :c:func:`HPyUnicode_DecodeLatin1` +* :c:func:`HPyUnicode_EncodeFSDefault` +* :c:func:`HPyUnicode_FromEncodedObject` +* :c:func:`HPyUnicode_FromString` +* :c:func:`HPyUnicode_FromWideChar` +* :c:func:`HPyUnicode_ReadChar` +* :c:func:`HPyUnicode_Substring` +* :c:func:`HPy_ASCII` +* :c:func:`HPy_Absolute` +* :c:func:`HPy_Add` +* :c:func:`HPy_And` +* :c:func:`HPy_AsPyObject` +* :c:func:`HPy_Bytes` +* :c:func:`HPy_Call` +* :c:func:`HPy_CallMethod` +* :c:func:`HPy_CallTupleDict` +* :c:func:`HPy_Close` +* :c:func:`HPy_Compile_s` +* :c:func:`HPy_Contains` +* :c:func:`HPy_DelItem` +* :c:func:`HPy_DelItem_i` +* :c:func:`HPy_DelItem_s` +* :c:func:`HPy_DelSlice` +* :c:func:`HPy_Divmod` +* :c:func:`HPy_Dup` +* :c:func:`HPy_EvalCode` +* :c:func:`HPy_FatalError` +* :c:func:`HPy_Float` +* :c:func:`HPy_FloorDivide` +* :c:func:`HPy_FromPyObject` +* :c:func:`HPy_GetAttr` +* :c:func:`HPy_GetAttr_s` +* :c:func:`HPy_GetItem` +* :c:func:`HPy_GetItem_i` +* :c:func:`HPy_GetItem_s` +* :c:func:`HPy_GetIter` +* :c:func:`HPy_GetSlice` +* :c:func:`HPy_HasAttr` +* :c:func:`HPy_HasAttr_s` +* :c:func:`HPy_Hash` +* :c:func:`HPy_InPlaceAdd` +* :c:func:`HPy_InPlaceAnd` +* :c:func:`HPy_InPlaceFloorDivide` +* :c:func:`HPy_InPlaceLshift` +* :c:func:`HPy_InPlaceMatrixMultiply` +* :c:func:`HPy_InPlaceMultiply` +* :c:func:`HPy_InPlaceOr` +* :c:func:`HPy_InPlacePower` +* :c:func:`HPy_InPlaceRemainder` +* :c:func:`HPy_InPlaceRshift` +* :c:func:`HPy_InPlaceSubtract` +* :c:func:`HPy_InPlaceTrueDivide` +* :c:func:`HPy_InPlaceXor` +* :c:func:`HPy_Index` +* :c:func:`HPy_Invert` +* :c:func:`HPy_Is` +* :c:func:`HPy_IsTrue` +* :c:func:`HPy_LeavePythonExecution` +* :c:func:`HPy_Length` +* :c:func:`HPy_Long` +* :c:func:`HPy_Lshift` +* :c:func:`HPy_MatrixMultiply` +* :c:func:`HPy_Multiply` +* :c:func:`HPy_Negative` +* :c:func:`HPy_Or` +* :c:func:`HPy_Positive` +* :c:func:`HPy_Power` +* :c:func:`HPy_ReenterPythonExecution` +* :c:func:`HPy_Remainder` +* :c:func:`HPy_Repr` +* :c:func:`HPy_RichCompare` +* :c:func:`HPy_RichCompareBool` +* :c:func:`HPy_Rshift` +* :c:func:`HPy_SetAttr` +* :c:func:`HPy_SetAttr_s` +* :c:func:`HPy_SetCallFunction` +* :c:func:`HPy_SetItem` +* :c:func:`HPy_SetItem_i` +* :c:func:`HPy_SetItem_s` +* :c:func:`HPy_SetSlice` +* :c:func:`HPy_Str` +* :c:func:`HPy_Subtract` +* :c:func:`HPy_TrueDivide` +* :c:func:`HPy_Type` +* :c:func:`HPy_TypeCheck` +* :c:func:`HPy_Xor` diff --git a/graalpython/hpy/docs/api-reference/helpers.rst b/graalpython/hpy/docs/api-reference/helpers.rst new file mode 100644 index 0000000000..df7725f8d4 --- /dev/null +++ b/graalpython/hpy/docs/api-reference/helpers.rst @@ -0,0 +1,5 @@ +Misc Helpers +============ + +.. autocmodule:: runtime/helpers.c + :members: diff --git a/graalpython/hpy/docs/api-reference/hpy-call.rst b/graalpython/hpy/docs/api-reference/hpy-call.rst new file mode 100644 index 0000000000..d685898f1e --- /dev/null +++ b/graalpython/hpy/docs/api-reference/hpy-call.rst @@ -0,0 +1,5 @@ +HPy Call API +============ + +.. autocmodule:: autogen/public_api.h + :members: HPy_Call,HPy_CallMethod,HPy_CallTupleDict diff --git a/graalpython/hpy/docs/api-reference/hpy-ctx.rst b/graalpython/hpy/docs/api-reference/hpy-ctx.rst new file mode 100644 index 0000000000..040903f005 --- /dev/null +++ b/graalpython/hpy/docs/api-reference/hpy-ctx.rst @@ -0,0 +1,9 @@ +HPy Context +=========== + +The ``HPyContext`` structure is also part of the API since it provides handles +for built-in objects. For a high-level description of the context, please also +read :ref:`api:hpycontext`. + +.. autocstruct:: hpy/cpython/autogen_ctx.h::_HPyContext_s + :members: diff --git a/graalpython/hpy/docs/api-reference/hpy-dict.rst b/graalpython/hpy/docs/api-reference/hpy-dict.rst new file mode 100644 index 0000000000..fb9400f4c1 --- /dev/null +++ b/graalpython/hpy/docs/api-reference/hpy-dict.rst @@ -0,0 +1,5 @@ +HPy Dict +======== + +.. autocmodule:: autogen/public_api.h + :members: HPyDict_Check, HPyDict_New, HPyDict_Keys, HPyDict_Copy diff --git a/graalpython/hpy/docs/api-reference/hpy-err.rst b/graalpython/hpy/docs/api-reference/hpy-err.rst new file mode 100644 index 0000000000..aeba618295 --- /dev/null +++ b/graalpython/hpy/docs/api-reference/hpy-err.rst @@ -0,0 +1,5 @@ +Exception Handling +================== + +.. autocmodule:: autogen/public_api.h + :members: HPyErr_SetFromErrnoWithFilename, HPyErr_SetFromErrnoWithFilenameObjects, HPy_FatalError, HPyErr_SetString, HPyErr_SetObject, HPyErr_Occurred, HPyErr_ExceptionMatches, HPyErr_NoMemory, HPyErr_Clear, HPyErr_NewException, HPyErr_NewExceptionWithDoc, HPyErr_WarnEx, HPyErr_WriteUnraisable diff --git a/graalpython/hpy/docs/api-reference/hpy-eval.rst b/graalpython/hpy/docs/api-reference/hpy-eval.rst new file mode 100644 index 0000000000..4e73e6d6fe --- /dev/null +++ b/graalpython/hpy/docs/api-reference/hpy-eval.rst @@ -0,0 +1,8 @@ +HPy Eval +======== + +.. autocmodule:: hpy.h + :members: HPy_SourceKind + +.. autocmodule:: autogen/public_api.h + :members: HPy_Compile_s,HPy_EvalCode diff --git a/graalpython/hpy/docs/api-reference/hpy-field.rst b/graalpython/hpy/docs/api-reference/hpy-field.rst new file mode 100644 index 0000000000..2973af4c5e --- /dev/null +++ b/graalpython/hpy/docs/api-reference/hpy-field.rst @@ -0,0 +1,5 @@ +HPyField +======== + +.. autocmodule:: autogen/public_api.h + :members: HPyField_Load,HPyField_Store diff --git a/graalpython/hpy/docs/api-reference/hpy-gil.rst b/graalpython/hpy/docs/api-reference/hpy-gil.rst new file mode 100644 index 0000000000..b64f96042d --- /dev/null +++ b/graalpython/hpy/docs/api-reference/hpy-gil.rst @@ -0,0 +1,5 @@ +Leave/enter Python execution (GIL) +================================== + +.. autocmodule:: autogen/public_api.h + :members: HPy_LeavePythonExecution,HPy_ReenterPythonExecution diff --git a/graalpython/hpy/docs/api-reference/hpy-global.rst b/graalpython/hpy/docs/api-reference/hpy-global.rst new file mode 100644 index 0000000000..9cbaa539e4 --- /dev/null +++ b/graalpython/hpy/docs/api-reference/hpy-global.rst @@ -0,0 +1,5 @@ +HPyGlobal +========= + +.. autocmodule:: autogen/public_api.h + :members: HPyGlobal_Store,HPyGlobal_Load diff --git a/graalpython/hpy/docs/api-reference/hpy-object.rst b/graalpython/hpy/docs/api-reference/hpy-object.rst new file mode 100644 index 0000000000..eeb5a6544b --- /dev/null +++ b/graalpython/hpy/docs/api-reference/hpy-object.rst @@ -0,0 +1,5 @@ +HPy Object +========== + +.. autocmodule:: autogen/public_api.h + :members: HPy_IsTrue,HPy_GetAttr,HPy_GetAttr_s,HPy_HasAttr,HPy_HasAttr_s,HPy_SetAttr,HPy_SetAttr_s,HPy_GetItem,HPy_GetItem_s,HPy_GetItem_i,HPy_GetSlice,HPy_SetItem,HPy_SetItem_s,HPy_SetItem_i,HPy_SetSlice,HPy_DelItem,HPy_DelItem_s,HPy_DelItem_i,HPy_DelSlice,HPy_Type,HPy_TypeCheck,HPy_Is,HPy_Repr,HPy_Str,HPy_ASCII,HPy_Bytes,HPy_RichCompare,HPy_RichCompareBool,HPy_Hash,HPy_SetCallFunction diff --git a/graalpython/hpy/docs/api-reference/hpy-sequence.rst b/graalpython/hpy/docs/api-reference/hpy-sequence.rst new file mode 100644 index 0000000000..21b7756e03 --- /dev/null +++ b/graalpython/hpy/docs/api-reference/hpy-sequence.rst @@ -0,0 +1,23 @@ +HPy Lists and Tuples +==================== + +Building Tuples and Lists +------------------------- + +.. autocmodule:: autogen/public_api.h + :members: HPyTupleBuilder_New,HPyTupleBuilder_Set,HPyTupleBuilder_Build,HPyTupleBuilder_Cancel + +.. autocmodule:: autogen/public_api.h + :members: HPyListBuilder_New,HPyListBuilder_Set,HPyListBuilder_Build,HPyListBuilder_Cancel + +Tuples +------ + +.. autocmodule:: autogen/public_api.h + :members: HPyTuple_Check,HPyTuple_FromArray + +Lists +----- + +.. autocmodule:: autogen/public_api.h + :members: HPyList_Check,HPyList_New,HPyList_Append,HPyList_Insert diff --git a/graalpython/hpy/docs/api-reference/hpy-type.rst b/graalpython/hpy/docs/api-reference/hpy-type.rst new file mode 100644 index 0000000000..9fccdfa37a --- /dev/null +++ b/graalpython/hpy/docs/api-reference/hpy-type.rst @@ -0,0 +1,50 @@ +HPy Types and Modules +===================== + +Types, modules and their attributes (i.e. methods, members, slots, get-set +descriptors) are defined in a similar way. Section `HPy Type`_ documents the +type-specific and `HPy Module`_ documents the module-specific part. Section +`HPy Definition`_ documents how to define attributes for both, types and +modules. + + +HPy Type +-------- + +Definition +~~~~~~~~~~ + +.. autocmodule:: hpy/hpytype.h + :members: HPyType_Spec,HPyType_BuiltinShape,HPyType_SpecParam,HPyType_SpecParam_Kind,HPyType_HELPERS,HPyType_LEGACY_HELPERS,HPy_TPFLAGS_DEFAULT,HPy_TPFLAGS_BASETYPE,HPy_TPFLAGS_HAVE_GC + +Construction and More +~~~~~~~~~~~~~~~~~~~~~ + +.. autocmodule:: autogen/public_api.h + :members: HPyType_FromSpec, HPyType_GetName, HPyType_IsSubtype + +HPy Module +---------- + +.. c:macro:: HPY_EMBEDDED_MODULES + + If ``HPY_EMBEDDED_MODULES`` is defined, this means that there will be + several embedded HPy modules (and so, several ``HPy_MODINIT`` usages) in the + same binary. In this case, some restrictions apply: + + 1. all of the module's methods/member/slots/... must be defined in the same + file + 2. the embedder **MUST** declare the module to be *embeddable* by using macro + :c:macro:`HPY_MOD_EMBEDDABLE`. + +.. autocmodule:: hpy/hpymodule.h + :members: HPY_MOD_EMBEDDABLE,HPyModuleDef,HPy_MODINIT + +HPy Definition +-------------- + +Defining slots, methods, members, and get-set descriptors for types and modules +is done with HPy definition (represented by C struct :c:struct:`HPyDef`). + +.. autocmodule:: hpy/hpydef.h + :members: HPyDef,HPyDef_Kind,HPySlot,HPyMeth,HPyMember_FieldType,HPyMember,HPyGetSet,HPyDef_SLOT,HPyDef_METH,HPyDef_MEMBER,HPyDef_GET,HPyDef_SET,HPyDef_GETSET,HPyDef_CALL_FUNCTION diff --git a/graalpython/hpy/docs/api-reference/index.rst b/graalpython/hpy/docs/api-reference/index.rst new file mode 100644 index 0000000000..89380d6377 --- /dev/null +++ b/graalpython/hpy/docs/api-reference/index.rst @@ -0,0 +1,69 @@ +API Reference +============= + +HPy's public API consists of three parts: + +1. The **Core API** as defined in the :doc:`public-api` +2. **HPy Helper** functions +3. **Inline Helper** functions + +Core API +-------- + +The **Core API** consists of inline functions that call into the Python +interpreter. Those functions will be implemented by each Python interpreter. In +:term:`CPython ABI` mode, many of these inline functions will just delegate to +a C API functions. In :term:`HPy Universal ABI` mode, they will call a function +pointer from the HPy context. This is the source of the performance change +between the modes. + +.. toctree:: + :maxdepth: 2 + + function-index + hpy-ctx + hpy-object + hpy-type + hpy-call + hpy-field + hpy-global + hpy-dict + hpy-sequence + hpy-gil + hpy-err + hpy-eval + public-api + + +HPy Helper Functions +-------------------- + +**HPy Helper** functions are functions (written in C) that will be compiled +together with the HPy extension's sources. The appropriate source files are +automatically added to the extension sources. The helper functions will, of +course, use the core API to interact with the interpreter. The main reason for +having the helper functions in the HPy extension is to avoid compatibility +problems due to different compilers. + +.. toctree:: + :maxdepth: 2 + + argument-parsing + build-value + formatting + structseq + helpers + + +Inline Helper Functions +----------------------- + +**Inline Helper** functions are ``static inline`` functions (written in C). +Those functions are usually small convenience functions that everyone could +write but in order to avoid duplicated effort, they are defined by HPy. + +.. toctree:: + :maxdepth: 2 + + inline-helpers + diff --git a/graalpython/hpy/docs/api-reference/inline-helpers.rst b/graalpython/hpy/docs/api-reference/inline-helpers.rst new file mode 100644 index 0000000000..2e719caf77 --- /dev/null +++ b/graalpython/hpy/docs/api-reference/inline-helpers.rst @@ -0,0 +1,14 @@ +Inline Helpers +============== + +**Inline Helper** functions are ``static inline`` functions (written in C). +Those functions are usually small convenience functions that everyone could +write but in order to avoid duplicated effort, they are defined by HPy. + +One category of inline helpers are functions that convert the commonly used +but not fixed width C types, such as ``int``, or ``long long``, to HPy API. +The HPy API always uses well-defined fixed width types like ``int32`` or +``unsigned int8``. + +.. autocmodule:: hpy/inline_helpers.h + :members: diff --git a/graalpython/hpy/docs/api-reference/public-api.rst b/graalpython/hpy/docs/api-reference/public-api.rst new file mode 100644 index 0000000000..992df114f8 --- /dev/null +++ b/graalpython/hpy/docs/api-reference/public-api.rst @@ -0,0 +1,9 @@ +Public API Header +================= + +The core API is defined in `public_api.h +`_: + +.. literalinclude:: ../../hpy/tools/autogen/public_api.h + :language: c + :linenos: diff --git a/graalpython/hpy/docs/api-reference/structseq.rst b/graalpython/hpy/docs/api-reference/structseq.rst new file mode 100644 index 0000000000..2772b3edfe --- /dev/null +++ b/graalpython/hpy/docs/api-reference/structseq.rst @@ -0,0 +1,15 @@ +Struct Sequences +================ + +Struct sequences are subclasses of tuple. Similar to the API for creating +tuples, HPy provides an API to create struct sequences. This is a builder API +such that the struct sequence is guaranteed not to be written after it is +created. + +.. note:: + + There is no specific getter function for struct sequences. Just use one of + :c:func:`HPy_GetItem`, :c:func:`HPy_GetItem_i`, or :c:func:`HPy_GetItem_s`. + +.. autocmodule:: hpy/runtime/structseq.h + :members: HPyStructSequence_Field,HPyStructSequence_Desc,HPyStructSequence_UnnamedField,HPyStructSequence_NewType,HPyStructSequence_New diff --git a/graalpython/hpy/docs/api.rst b/graalpython/hpy/docs/api.rst new file mode 100644 index 0000000000..7146e024e2 --- /dev/null +++ b/graalpython/hpy/docs/api.rst @@ -0,0 +1,581 @@ +HPy API Introduction +==================== + +Handles +------- + +The "H" in HPy stands for **handle**, which is a central concept: handles are +used to hold a C reference to Python objects, and they are represented by the +C ``HPy`` type. They play the same role as ``PyObject *`` in the ``Python.h`` +API, albeit with some important differences which are detailed below. + +When they are no longer needed, handles must be closed by calling +``HPy_Close``, which plays more or less the same role as ``Py_DECREF``. +Similarly, if you need a new handle for an existing object, you can duplicate +it by calling ``HPy_Dup``, which plays more or less the same role as +``Py_INCREF``. + +The HPy API strictly follows these rules: + +- ``HPy`` handles returned by a function are **never borrowed**, i.e., + the caller must either close or return it. +- ``HPy`` handles passed as function arguments are **never stolen**; + if you receive a ``HPy`` handle argument from your caller, you should never close it. + +These rules makes the code simpler to reason about. Moreover, no reference +borrowing enables the Python implementations to use whatever internal +representation they wish. For example, the object returned by ``HPy_GetItem_i`` +may be created on demand from some compact internal representation, which does +not need to convert itself to full blown representation in order to hold onto +the borrowed object. + +We strongly encourage the users of HPy to also internally follow these rules +for their own internal APIs and helper functions. For the sake of simplicity +and easier local reasoning and also because in the future, code adhering +to those rules may be suitable target for some scalable and precise static +analysis tool. + +The concept of handles is certainly not unique to HPy. Other examples include +Unix file descriptors, where you have ``dup()`` and ``close()``, and Windows' +``HANDLE``, where you have ``DuplicateHandle()`` and ``CloseHandle()``. + + +Handles vs ``PyObject *`` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +In order to fully understand the way HPy handles work, it is useful to discuss +the ``Pyobject *`` pointer in ``Python.h``. These pointers always +point to the same object, and a python object's identity is completely given +by its address in memory, and two pointers with the same address can +be passed to ``Python.h`` API functions interchangeably. As a result, ``Py_INCREF`` +and ``Py_DECREF`` can be called with any reference to an object as long as the +total number of calls of ``incref`` is equal to the number of calls of ``decref`` +at the end of the object lifetime. + +Whereas using HPy API, each handle must be closed independently. + +Thus, the following perfectly valid piece of code using ``Python.h``:: + + void foo(void) + { + PyObject *x = PyLong_FromLong(42); // implicit INCREF on x + PyObject *y = x; + Py_INCREF(y); // INCREF on y + /* ... */ + Py_DECREF(x); + Py_DECREF(x); // two DECREF on x + } + +Becomes using HPy API: + +.. literalinclude:: examples/snippets/snippets.c + :start-after: // BEGIN: foo + :end-before: // END: foo + +Calling any HPy function on a closed handle is an error. Calling +``HPy_Close()`` on the same handle twice is an error. Forgetting to call +``HPy_Close()`` on a handle results in a memory leak. When running in +:ref:`debug-mode:debug mode`, HPy actively checks that you don't +close a handle twice and that you don't forget to close any. + + +.. note:: + Debug mode is a good example of how powerful it is to decouple the + identity and therefore the lifetime of handles and those of objects. + If you find a memory leak on CPython, you know that you are missing a + ``Py_DECREF`` somewhere but the only way to find the corresponding + ``Py_INCREF`` is to manually and carefully study the source code. + On the other hand, if you forget to call ``HPy_Close()``, debug mode + is able to identify the precise code location which created the unclosed + handle. Similarly, if you try to operate on a closed handle, it will + identify the precise code locations which created and closed it. This is + possible because handles are associated with a single call to a C/API + function. As a result, given a handle that is leaked or used after freeing, + it is possible to identify exactly the C/API function that produced it. + + +Remember that ``Python.h`` guarantees that multiple references to the same +object results in the very same ``PyObject *`` pointer. Thus, it is +possible to compare the pointer addresses to check whether they refer +to the same object:: + + int is_same_object(PyObject *x, PyObject *y) + { + return x == y; + } + +On the other hand, in HPy, each handle is independent and it is common to have +two different handles which point to the same underlying object, so comparing +two handles directly is ill-defined. To prevent this kind of common error +(especially when porting existing code to HPy), the ``HPy`` C type is opaque +and the C compiler actively forbids comparisons between them. To check for +identity, you can use ``HPy_Is()``: + +.. literalinclude:: examples/snippets/snippets.c + :start-after: // BEGIN: is_same_object + :end-before: // END: is_same_object + +.. note:: + The main benefit of opaque handle semantics is that implementations are + allowed to use very different models of memory management. On CPython, + implementing handles is trivial because ``HPy`` is basically ``PyObject *`` + in disguise, and ``HPy_Dup()`` and ``HPy_Close()`` are just aliases for + ``Py_INCREF`` and ``Py_DECREF``. + + Unlike CPython, PyPy does not use reference counting to manage memory: + instead, it uses a *moving GC*, which means that the address of an object + might change during its lifetime, and this makes it hard to implement + semantics like ``PyObject *``'s where the address *identifies* the object, + and this is directly exposed to the user. HPy solves this problem: on + PyPy, handles are integers which represent indices into a list, which + is itself managed by the GC. When an address changes, the GC edits the + list, without having to touch all the handles which have been passed to C. + + +HPyContext +----------- + +All HPy function calls take an ``HPyContext`` as a first argument, which +represents the Python interpreter all the handles belong to. Strictly +speaking, it would be possible to design the HPy API without using +``HPyContext``: after all, all HPy function calls are ultimately mapped to +``Python.h`` function call, where there is no notion of context. + +One of the reasons to include ``HPyContext`` from the day one is to be +future-proof: it is conceivable to use it to hold the interpreter or the +thread state in the future, in particular when there will be support for +sub-interpreters. Another possible usage could be to embed different versions +or implementations of Python inside the same process. In addition, the +``HPyContext`` may also be extended by adding new functions to the end without +breaking any extensions built against the current ``HPyContext``. + +Moreover, ``HPyContext`` is used by the :term:`HPy Universal ABI` to contain a +sort of virtual function table which is used by the C extensions to call back +into the Python interpreter. + +.. _simple example: + +A simple example +----------------- + +In this section, we will see how to write a simple C extension using HPy. It +is assumed that you are already familiar with the existing ``Python.h`` API, so we +will underline the similarities and the differences with it. + +We want to create a function named ``myabs`` and ``double`` which takes a +single argument and computes its absolute value: + +.. literalinclude:: examples/simple-example/simple.c + :start-after: // BEGIN: myabs + :end-before: // END: myabs + +There are a couple of points which are worth noting: + + * We use the macro ``HPyDef_METH`` to declare we are going to define a HPy + function called ``myabs``. + + * The function will be available under the name ``"myabs"`` in our Python + module. + + * The actual C function which implements ``myabs`` is called ``myabs_impl`` + and is inferred by the macro. The macro takes the name and adds ``_impl`` + to the end of it. + + * It uses the ``HPyFunc_O`` calling convention. Like ``METH_O`` in ``Python.h``, + ``HPyFunc_O`` means that the function receives a single argument on top of + ``self``. + + * ``myabs_impl`` takes two arguments of type ``HPy``: handles for ``self`` + and the argument, which are guaranteed to be valid. They are automatically + closed by the caller, so there is no need to call ``HPy_Close`` on them. + + * ``myabs_impl`` returns a handle, which has to be closed by the caller. + + * ``HPy_Absolute`` is the equivalent of ``PyNumber_Absolute`` and + computes the absolute value of the given argument. + + * We also do not call ``HPy_Close`` on the result returned to the caller. + We must return a valid handle. + +.. note:: + Among other things, + the ``HPyDef_METH`` macro is needed to maintain compatibility with CPython. + In CPython, C functions and methods have a C signature that is different to + the one used by HPy: they don't receive an ``HPyContext`` and their arguments + have the type ``PyObject *`` instead of ``HPy``. The macro automatically + generates a trampoline function whose signature is appropriate for CPython and + which calls the ``myabs_impl``. This trampoline is then used from both the + CPython ABI and the CPython implementation of the universal ABI, but other + implementations of the universal ABI will usually call directly the HPy + function itself. + +The second function definition is a bit different: + +.. literalinclude:: examples/simple-example/simple.c + :start-after: // BEGIN: double + :end-before: // END: double + +This shows off the other way of creating functions. + + * This example is much the same but the difference is that we use + ``HPyDef_METH_IMPL`` to define a function named ``double``. + + * The difference between ``HPyDef_METH_IMPL`` and ``HPyDef_METH`` is that + the former needs to be given a name for a the functions as the third + argument. + +Now, we can define our module: + +.. literalinclude:: examples/simple-example/simple.c + :start-after: // BEGIN: methodsdef + :end-before: // END: methodsdef + +This part is very similar to the one you would write with ``Python.h``. Note that +we specify ``myabs`` (and **not** ``myabs_impl``) in the method table. There +is also the ``.legacy_methods`` field, which allows to add methods that use the +``Python.h`` API, i.e., the value should be an array of ``PyMethodDef``. This +feature enables support for hybrid extensions in which some of the methods +are still written using the ``Python.h`` API. + +Note that the HPy module does not specify its name. HPy does not support the legacy +single phase module initialization and the only module initialization approach is +the multi-phase initialization (`PEP 489 `_). +With multi-phase module initialization, +the name of the module is always taken from the ``ModuleSpec`` (`PEP 451 `_) +, i.e., most likely from the name used in the ``import {{name}}`` statement that +imported your module. + +This is the only difference stemming from multi-phase module initialization in this +simple example. +As long as there is no need for any further initialization, we can just "register" +our module using the ``HPy_MODINIT`` convenience macro. The first argument is the +name of the extension file and is needed for HPy, among other things, to be able +to generate the entry point for CPython called ``PyInit_{{name}}``. The second argument +is the ``HPyModuleDef`` we just defined. + +.. literalinclude:: examples/simple-example/simple.c + :start-after: // BEGIN: moduledef + :end-before: // END: moduledef + +Building the module +~~~~~~~~~~~~~~~~~~~~ + +Let's write a ``setup.py`` to build our extension: + +.. literalinclude:: examples/simple-example/setup.py + :language: python + +We can now build the extension by running ``python setup.py build_ext -i``. On +CPython, it will target the :term:`CPython ABI` by default, so you will end up with +a file named e.g. ``simple.cpython-37m-x86_64-linux-gnu.so`` which can be +imported directly on CPython with no dependency on HPy. + +To target the :term:`HPy Universal ABI` instead, it is possible to pass the +option ``--hpy-abi=universal`` to ``setup.py``. The following command will +produce a file called ``simple.hpy.so`` (note that you need to specify +``--hpy-abi`` **before** ``build_ext``, since it is a global option):: + + python setup.py --hpy-abi=universal build_ext -i + +.. note:: + This command will also produce a Python file named ``simple.py``, which + loads the HPy module using the ``universal.load`` function from + the ``hpy`` Python package. + +VARARGS calling convention +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If we want to receive more than a single arguments, we need the +``HPy_METH_VARARGS`` calling convention. Let's add a function ``add_ints`` +which adds two integers: + +.. literalinclude:: examples/snippets/hpyvarargs.c + :start-after: // BEGIN: add_ints + :end-before: // END: add_ints + +There are a few things to note: + + * The C signature is different than the corresponding ``Python.h`` + ``METH_VARARGS``: in particular, instead of taking a tuple ``PyObject *args``, + we take an array of ``HPy`` and its size. This allows the call to happen + more efficiently, because you don't need to create a tuple just to pass the + arguments. + + * We call ``HPyArg_Parse`` to parse the arguments. Contrarily to almost all + the other HPy functions, this is **not** a thin wrapper around + ``PyArg_ParseTuple`` because as stated above we don't have a tuple to pass + to it, although the idea is to mimic its behavior as closely as + possible. The parsing logic is implemented from scratch inside HPy, and as + such there might be missing functionality during the early stages of HPy + development. + + * If an error occurs, we return ``HPy_NULL``: we cannot simply ``return NULL`` + because ``HPy`` is not a pointer type. + +Once we have written our function, we can add it to the ``SimpleMethods[]`` +table, which now becomes: + +.. literalinclude:: examples/snippets/hpyvarargs.c + :start-after: // BEGIN: methodsdef + :end-before: // END: methodsdef + +Creating types in HPy +--------------------- + +Creating Python types in an HPy extension is again very similar to the C API +with the difference that HPy only supports creating types from a specification. +This is necessary because there is no such C-level type as ``PyTypeObject`` +since that would expose the internal implementation. + + +Creating a simple type in HPy +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section assumes that the user wants to define a type that stores some data +in a C-level structure. As an example, we will create a simple C structure +``PointObject`` that represents a two-dimensional point. + +.. literalinclude:: examples/hpytype-example/simple_type.c + :start-after: // BEGIN: PointObject + :end-before: // END: PointObject + +The macro call ``HPyType_HELPERS(PointObject)`` generates useful helper +facilities for working with the type. It generates a C enum +``PointObject_SHAPE`` and a helper function ``PointObject_AsStruct``. The enum +is used in the type specification. The helper function is used to efficiently +retrieving the pointer ``PointObject *`` from an HPy handle to be able to access +the C structure. We will use this helper function to implement the methods, +get-set descriptors, and slots. + +It makes sense to expose fields ``PointObject.x`` and ``PointObject.y`` as +Python-level members. To do so, we need to define members by specifying their +name, type, and location using HPy's convenience macro ``HPyDef_MEMBER``: + +.. literalinclude:: examples/hpytype-example/simple_type.c + :start-after: // BEGIN: members + :end-before: // END: members + +The first argument of the macro is the name for the C glabal variable that will +store the necessary information. We will need that later for registration of +the type. The second, third, and fourth arguments are the Python-level name, the +C type of the member, and the offset in the C structure, respectively. + +Similarly, methods and get-set descriptors can be defined. For example, method +``foo`` is an instance method that takes no arguments (the self argument is, of +course, implicit), does some computation with fields ``x`` and ``y`` and +returns a Python ``int``: + +.. literalinclude:: examples/hpytype-example/simple_type.c + :start-after: // BEGIN: methods + :end-before: // END: methods + +Get-set descriptors are also defined in a very similar way as methods. The +following example defines a get-set descriptor for attribute ``z`` which is +calculated from the ``x`` and ``y`` fields of the struct. + +.. literalinclude:: examples/hpytype-example/simple_type.c + :start-after: // BEGIN: getset + :end-before: // END: getset + +It is also possible to define a get-descriptor or a set-descriptor by using +HPy's macros ``HPyDef_GET`` and ``HPyDef_SET`` in the same way. + +HPy also supports type slots. In this example, we will define slot +``HPy_tp_new`` (which corresponds to magic method ``__new__``) to initialize +fields ``x`` and ``y`` when constructing the object: + +.. literalinclude:: examples/hpytype-example/simple_type.c + :start-after: // BEGIN: slots + :end-before: // END: slots + +After everything was defined, we need to create a list of all defines such that +we are able to eventually register them to the type: + +.. literalinclude:: examples/hpytype-example/simple_type.c + :start-after: // BEGIN: defines + :end-before: // END: defines + +Please note that it is required to terminate the list with ``NULL``. +We can now create the actual type specification by appropriately filling an +``HPyType_Spec`` structure: + +.. literalinclude:: examples/hpytype-example/simple_type.c + :start-after: // BEGIN: spec + :end-before: // END: spec + +First, we need to define the name of the type by setting a C string to member +``name``. Since this type has a C structure, we need to define the ``basicsize`` +and best practice is to set it to ``sizeof(PointObject)``. Also best practice is +to set ``builtin_shape`` to ``PointObject_SHAPE`` where ``PointObject_SHAPE`` is +generated by the previous usage of macro ``HPyType_HELPERS(PointObject)``. Last +but not least, we need to register the defines by setting field ``defines`` to +the previously defined array ``Point_defines``. + +The type specification for the simple type ``simple_type.Point`` represented in +C by structure ``PointObject`` is now complete. All that remains is to create +the type object and add it to the module. + +We will define a module execute slot, which is executed by the runtime right +after the module is created. The purpose of the execute slot is to initialize +the newly created module object. We can then add the type by using +:c:func:`HPyHelpers_AddType`: + +.. literalinclude:: examples/hpytype-example/simple_type.c + :start-after: // BEGIN: add_type + :end-before: // END: add_type + +Also look at the full example at: :doc:`examples/hpytype-example/simple_type`. + + +Legacy types +~~~~~~~~~~~~ + +A type whose struct starts with ``PyObject_HEAD`` (either directly by +embedding it in the type struct or indirectly by embedding another struct like +``PyLongObject``) is a *legacy type*. A legacy type must set +``.builtin_shape = HPyType_BuiltinShape_Legacy`` +in its ``HPyType_Spec``. The counterpart (i.e. a non-legacy type) is called HPy +pure type. + +Legacy types are available to allow gradual porting of existing CPython +extensions. It is possible to reuse existing ``PyType_Slot`` entities (i.e. +slots, methods, members, and get/set descriptors). The idea is that you can then +migrate one after each other while still running the tests. + +The major restriction when using legacy types is that you cannot build a +universal binary of your HPy extension (i.e. you cannot use :term:`HPy Universal +ABI`). The resulting binary will be specific to the Python interpreter used for +building. Therefore, the goal should always be to fully migrate to HPy pure +types. + +A type with ``.legacy_slots != NULL`` is required to have +``HPyType_BuiltinShape_Legacy`` and to include ``PyObject_HEAD`` at the start of +its struct. It would be easy to relax this requirement on CPython (where the +``PyObject_HEAD`` fields are always present) but a large burden on other +implementations (e.g. PyPy, GraalPy) where a struct starting with +``PyObject_HEAD`` might not exist. + +Types created via the old Python C API are automatically legacy types. + +This section does not provide a dedicated example for how to create and use +legacy types because the :doc:`porting-example/index` already shows how that +is useful during incremental migration to HPy. + +Inherit from a built-in type +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +HPy also supports inheriting from following built-in types: + + * ``type`` + + * ``int`` + + * ``float`` + + * ``unicode`` + + * ``tuple`` + + * ``list`` + +Inheriting from built-in types is straight forward if you don't have a C +structure that represents your type. In other words, you can simply inherit +from, e.g., ``str`` if the ``basicsize`` in your type specification is ``0``. +For example: + +.. literalinclude:: examples/hpytype-example/builtin_type.c + :start-after: // BEGIN: spec_Dummy + :end-before: // END: spec_Dummy + +.. literalinclude:: examples/hpytype-example/builtin_type.c + :start-after: // BEGIN: add_Dummy + :end-before: // END: add_Dummy + +This case is simple because there is no ``Dummy_AsStruct`` since there is no +associated C-level structure. + +It is, however, more involved if your type also defines its own C structure +(i.e. ``basicsize > 0`` in the type specification). In this case, it is strictly +necessary to use the right *built-in shape*. + +**What is the right built-in shape?** + +This question is easy to answer: Each built-in shape (except of +:c:enumerator:`HPyType_BuiltinShape_Legacy`) represents a built-in type. You +need to use the built-in shape that fits to the specified base class. The +mapping is described in :c:enum:`HPyType_BuiltinShape`. + +Let's do an example. Assume we want to define a type that stores the natural +language of a unicode string to the unicode object but the object should still +just behave like a Python unicode object. So, we define struct +``LanguageObject``: + +.. literalinclude:: examples/hpytype-example/builtin_type.c + :start-after: // BEGIN: LanguageObject + :end-before: // END: LanguageObject + +As you can see, we already specify the built-in shape here using +``HPyType_HELPERS(LanguageObject, HPyType_BuiltinShape_Unicode)``. Then, in the +type specification, we do: + +.. literalinclude:: examples/hpytype-example/builtin_type.c + :start-after: // BEGIN: spec_Language + :end-before: // END: spec_Language + +In the last step, when actually creating the type from the specification, we +need to define that its base class is ``str`` (aka. ``UnicodeType``): + +.. literalinclude:: examples/hpytype-example/builtin_type.c + :start-after: // BEGIN: add_Language + :end-before: // END: add_Language + +Function ``LanguageObject_AsStruct`` (which is generated by ``HPyType_HELPERS``) +will then return a pointer to ``LanguageObject``. + +To summarize this: Specifying a type that inherits from a built-in type needs to +be considered in three places: + +1. Pass the appropriate built-in shape to :c:macro:`HPyType_HELPERS`. +2. Assign ``SHAPE(TYPE)`` to :c:member:`HPyType_Spec.builtin_shape`. +3. Specify the desired base class in the type specification parameters. + +For more information about the built-in shape and for a technical explanation +for why it is required, see :c:member:`HPyType_Spec.builtin_shape` and +:c:enum:`HPyType_BuiltinShape`. + +More Examples +------------- + +The :doc:`porting-example/index` shows another complete example +of HPy extension ported from Python/C API. + +The `HPy project space `_ on GitHub +contains forks of some popular Python extensions ported to HPy as +a proof of concept/feasibility studies, such as the +`Kiwi solver `_. +Note that those forks may not be up to date with their upstream projects +or with the upstream HPy changes. + +HPy unit tests +~~~~~~~~~~~~~~ + +HPy usually has tests for each API function. This means that there is lots of +examples available by looking at the tests. However, the test source uses +many macros and is hard to read. To overcome this we supply a utility to +export clean C sources for the tests. Since the HPy tests are not shipped by +default, you need to clone the HPy repository from GitHub: + +.. code-block:: console + + > git clone https://github.com/hpyproject/hpy.git + +After that, install all test requirements and dump the sources: + +.. code-block:: console + + > cd hpy + > python3 -m pip install pytest filelock + > python3 -m pytest --dump-dir=test_sources test/ + +This will dump the generated test sources into folder ``test_sources``. Note, +that the tests won't be executed but skipped with an appropriate message. diff --git a/graalpython/hpy/docs/changelog.rst b/graalpython/hpy/docs/changelog.rst new file mode 100644 index 0000000000..e2915b98d3 --- /dev/null +++ b/graalpython/hpy/docs/changelog.rst @@ -0,0 +1,235 @@ +Changelog +========= + +Version 0.9 (April 25th, 2023) +------------------------------ + +This release adds numerous major features and indicates the end of HPy's *alhpa* +phase. We've migrated several key packages to HPy (for a list, see our website +https://hpyproject.org) and we are now confident that HPy is mature enough for +being used as serious extension API. We also plan that the next major release +will be ``1.0``. + +Major new features +~~~~~~~~~~~~~~~~~~ + +Support subclasses of built-in types + It is now possible to create pure HPy types that inherit from built-in types + like ``type`` or ``float``. This was already possible before but in a very + limited way, i.e., by setting :c:member:`HPyType_Spec.basicsize` to ``0``. In + this case, the type implicitly inherited the basic size of the supertype but + that also means that you cannot have a custom C struct. It is now possible + inherit from a built-in type **AND** have a custom C struct. For further + reference, see :c:member:`HPyType_Spec.builtin_shape` and + :c:enum:`HPyType_BuiltinShape`. + +Support for metaclasses + HPy now supports creating types with metaclasses. This can be done by passing + type specification parameter with kind + :c:enumerator:`HPyType_SpecParam_Metaclass` when calling + :c:func:`HPyType_FromSpec`. + +:term:`HPy Hybrid ABI` + In addition to :term:`CPython ABI` and :term:`HPy Universal ABI`, we now + introduced the Hybrid ABI. The major difference is that whenever you use a + legacy API like :c:func:`HPy_AsPyObject` or :c:func:`HPy_FromPyObject`, the + prdouced binary will then be specific to one interpreter. This was necessary + to ensure that universal binaries are really portable and can be used on any + HPy-capable interpreter. + +:doc:`trace-mode` + Similar to the :doc:`debug-mode`, HPy now provides the Trace Mode that can be + enabled at runtime and helps analyzing API usage and identifying performance + issues. + +:ref:`porting-guide:multi-phase module initialization` + HPy now support multi-phase module initialization which is an important + feature in particular needed for two important use cases: (1) module state + support (which is planned to be introduced in the next major release), and (2) + subinterpreters. We decided to drop support for single-phase module + initialization since this makes the API cleaner and easier to use. + +HPy :ref:`porting-guide:calling protocol` + This was a big missing piece and is now eventually available. It enables slot + ``HPy_tp_call``, which can now be used in the HPy type specification. We + decided to use a calling convention similar to CPython's vectorcall calling + convention. This is: the arguments are passed in a C array and the keyword + argument names are provided as a Python tuple. Before this release, the only + way to create a callable type was to set the special method ``__call__``. + However, this has several disadvantages. In particlar, poor performance on + CPython (and maybe other implementations) and it was not possible to have + specialized call function implementations per object (see + :c:func:`HPy_SetCallFunction`) + +Added APIs +~~~~~~~~~~ + +Deleting attributes and items + :c:func:`HPy_DelAttr`, :c:func:`HPy_DelAttr_s`, :c:func:`HPy_DelItem`, :c:func:`HPy_DelItem_i`, :c:func:`HPy_DelItem_s` + +Capsule API + :c:func:`HPyCapsule_New`, :c:func:`HPyCapsule_IsValid`, :c:func:`HPyCapsule_Get`, :c:func:`HPyCapsule_Set` + +Eval API + :c:func:`HPy_Compile_s` and :c:func:`HPy_EvalCode` + +Formatting helpers + :c:func:`HPyUnicode_FromFormat` and :c:func:`HPyErr_Format` + +Contextvar API + :c:func:`HPyContextVar_New`, :c:func:`HPyContextVar_Get`, :c:func:`HPyContextVar_Set` + +Unicode API + :c:func:`HPyUnicode_FromEncodedObject` and :c:func:`HPyUnicode_Substring` + +Dict API + :c:func:`HPyDict_Keys` and :c:func:`HPyDict_Copy` + +Type API + :c:func:`HPyType_GetName` and :c:func:`HPyType_IsSubtype` + +Slice API + :c:func:`HPySlice_Unpack` and :c:func:`HPySlice_AdjustIndices` + +Structseq API + :c:func:`HPyStructSequence_NewType`, :c:func:`HPyStructSequence_New` + +Call API + :c:func:`HPy_Call`, :c:func:`HPy_CallMethod`, :c:func:`HPy_CallMethodTupleDict`, :c:func:`HPy_CallMethodTupleDict_s` + +HPy call protocol + :c:func:`HPy_SetCallFunction` + +Debug mode +~~~~~~~~~~ + +* Detect closing and returning (without dup) of context handles +* Detect invalid usage of stored ``HPyContext *`` pointer +* Detect invalid usage of tuple and list builders +* Added Windows support for checking invalid use of raw data pointers (e.g + ``HPyUnicode_AsUTF8AndSize``) after handle was closed. +* Added support for backtrace on MacOS + +Documentation +~~~~~~~~~~~~~ + +* Added incremental :doc:`porting-example/index` +* Added :doc:`quickstart` guide +* Extended :doc:`api-reference/index` +* Added :doc:`api-reference/function-index` +* Added possiblity to generate examples from tests with argument ``--dump-dir`` + (see :ref:`api:hpy unit tests`) +* Added initial :doc:`contributing/index` docs + +Incompatible changes to version 0.0.4 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Simplified ``HPyDef_*`` macros +* Changed macro :c:macro:`HPy_MODINIT` because of multi-phase module init + support. +* Replace environment variable ``HPY_DEBUG`` by ``HPY`` (see :doc:`debug-mode` + or :doc:`trace-mode`). +* Changed signature of ``HPyFunc_VARARGS`` and ``HPyFunc_ KEYWORDS`` to align + with HPy's call protocol calling convention. + +Supported Python versions +~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Added Python 3.11 support +* Preliminary Python 3.12 support +* Dropped Python 3.6 support (since EOL) +* Dropped Python 3.7 support (since EOL by June 2023) + +Misc +~~~~ + +* Ensure deterministic auto-generation +* Ensure ABI backwards compatibility + + * Explicitly define slot within HPyContext of function pointers and handles + * Compile HPy ABI version into binary and verify at load time +* Added proper support for object members ``HPyMember_OBJECT`` +* Changed :c:func:`HPyBytes_AsString` and :c:func:`HPyBytes_AS_STRING` to return ``const char *`` +* Use fixed-width integers in context functions + + + +Version 0.0.4 (May 25th, 2022) +------------------------------ + +New Features/API: + + - HPy headers are C++ compliant + - Python 3.10 support + - `HPyField `_: + References to Python objects that can be stored in raw native memory owned by Python objects. + + - New API functions: ``HPyField_Load``, ``HPyField_Store`` + - `HPyGlobal `_: + References to Python objects that can be stored into a C global variable. + + - New API functions: ``HPyGlobal_Load``, ``HPyGlobal_Store`` + - Note: ``HPyGlobal`` does not allow to share Python objects between (sub)interpreters + + - `GIL support `_ + - New API functions: ``HPy_ReenterPythonExecution``, ``HPy_LeavePythonExecution`` + + - `Value building support `_ (``HPy_BuildValue``) + + - New type slots + + - ``HPy_mp_ass_subscript``, ``HPy_mp_length``, ``HPy_mp_subscript`` + - ``HPy_tp_finalize`` + + - Other new API functions + + - ``HPyErr_SetFromErrnoWithFilename``, ``HPyErr_SetFromErrnoWithFilenameObjects`` + - ``HPyErr_ExceptionMatches`` + - ``HPyErr_WarnEx`` + - ``HPyErr_WriteUnraisable`` + - ``HPy_Contains`` + - ``HPyLong_AsVoidPtr`` + - ``HPyLong_AsDouble`` + - ``HPyUnicode_AsASCIIString``, ``HPyUnicode_DecodeASCII`` + - ``HPyUnicode_AsLatin1String``, ``HPyUnicode_DecodeLatin1`` + - ``HPyUnicode_DecodeFSDefault``, ``HPyUnicode_DecodeFSDefaultAndSize`` + - ``HPyUnicode_ReadChar`` + +Debug mode: + + - Support activation of debug mode via environment variable ``HPY_DEBUG`` + - Support capturing stack traces of handle allocations + - Check for invalid use of raw data pointers (e.g ``HPyUnicode_AsUTF8AndSize``) after handle was closed. + - Detect invalid handles returned from extension functions + - Detect incorrect closing of handles passed as arguments + +Misc Changes: + + - Removed unnecessary prefix ``"m_"`` from fields of ``HPyModuleDef`` (incompatible change) + - For HPy implementors: new pytest mark for HPy tests assuming synchronous GC + +Version 0.0.3 (September 22nd, 2021) +------------------------------------ + +This release adds various new API functions (see below) and extends the debug +mode with the ability to track closed handles. +The default ABI mode now is 'universal' for non-CPython implementations. +Also, the type definition of ``HPyContext`` was changed and it's no longer a +pointer type. +The name of the HPy dev package was changed to 'hpy' (formerly: 'hpy.devel'). +Macro HPy_CAST was replaced by HPy_AsStruct. + +New features: + + - Added helper HPyHelpers_AddType for creating new types + - Support format specifier 's' in HPyArg_Parse + - Added API functions: HPy_Is, HPy_AsStructLegacy (for legacy types), + HPyBytes_FromStringAndSize, HPyErr_NewException, HPyErr_NewExceptionWithDoc, + HPyUnicode_AsUTF8AndSize, HPyUnicode_DecodeFSDefault, HPyImport_ImportModule + - Debug mode: Implemented tracking of closed handles + - Debug mode: Add hook for invalid handle access + +Bug fixes: + + - Distinguish between pure and legacy types + - Fix Sphinx doc errors diff --git a/graalpython/hpy/docs/conf.py b/graalpython/hpy/docs/conf.py new file mode 100644 index 0000000000..45a9077616 --- /dev/null +++ b/graalpython/hpy/docs/conf.py @@ -0,0 +1,134 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + +import sys +import os +import re +import datetime + +# -- Project information ----------------------------------------------------- + +project = "HPy" +copyright = "2019-{}, HPy Collective".format(datetime.date.today().year) +author = "HPy Collective" + +# The full version, including alpha/beta/rc tags +release = "0.9" + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autosectionlabel", + "sphinx_c_autodoc", + "sphinx_c_autodoc.viewcode", + "sphinx_rtd_theme", +] + +autosectionlabel_prefix_document = True + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +# -- autodoc ----------------------------------------------------------------- + +autodoc_member_order = "bysource" + +# -- sphinx_c_autodoc -------------------------------------------------------- + +c_autodoc_roots = [ + "../hpy/devel/include", + "../hpy/devel/src", + "../hpy/tools", +] + + +def pre_process(app, filename, contents, *args): + # FIXME: the missing typedef for 'HPy' causes the file formatting to fail + if filename.endswith('public_api.h'): + contents[0] = '#include "../../devel/include/hpy.h"\n' + contents[0] + if filename.endswith('autogen_ctx.h'): + contents[0] = 'typedef int HPy;' + contents[0] + + # remove HPyAPI_HELPER so that the sphinx-c-autodoc and clang + # find and render the API functions + contents[:] = [ + re.sub(r"^(HPyAPI_HELPER|HPyAPI_INLINE_HELPER|HPy_ID\(\d+\))", r"", part, flags=re.MULTILINE) + for part in contents + ] + + +def setup(app): + app.connect("c-autodoc-pre-process", pre_process) + + +def setup_clang(): + """ + Make sure clang is set up correctly for the sphinx_c_autodoc extension. + + The Python clang package requires a matching libclang*.so. Our + ``doc/requirements.txt`` file specifies ``clang==10.0.1``, so we need + ``libclang-10``. + + On Ubuntu 20.04 (and possibly later), this can be installed with + ``apt install libclang-10-dev`` and the Python clang package finds the + appropriate .so automatically. + + However, ReadTheDocs has an older Ubuntu that only packages libclang-6.0. + The Python ``clang==10.0.1`` packages supports this older .so, but + needs to be explicitly told where to find it. + + If you encounter issues with a local build, please start by checking that + the ``libclang-10-dev`` system package or equivalent is installed. + """ + from clang import cindex + if 'READTHEDOCS' in os.environ: + # TODO: Hopefully we can remove this setting of the libclang path once + # readthedocs updates its docker image to Ubuntu 20.04 which + # supports clang-10 and clang-11. + cindex.Config.set_library_file( + "/usr/lib/x86_64-linux-gnu/libclang-6.0.so.1" + ) + elif sys.platform == "darwin": + cindex.Config.set_library_file( + "/Library/Developer/CommandLineTools/usr/lib/libclang.dylib" + ) + + +setup_clang() + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "sphinx_rtd_theme" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +# most the the code examples will be in C, let's make it the default +highlight_language = 'C' diff --git a/graalpython/hpy/docs/contributing/index.rst b/graalpython/hpy/docs/contributing/index.rst new file mode 100644 index 0000000000..1dba877a90 --- /dev/null +++ b/graalpython/hpy/docs/contributing/index.rst @@ -0,0 +1,33 @@ +Contributing +============ + +Getting Started +--------------- + +TBD + + +Adding New API +-------------- + +1. Add the function to ``hpy/tools/autogen/public_api.h``. If the CPython + equivalent function name is not the same (after removing the leading ``H``, + add an appropriate CPython function mapping in ``hpy/tools/autogen/conf.py``. + If the signature is complicated or there is no clear equivalent function, + the mapping should be ``None``, and follow the directions in the next step. + Otherwise all the needed functions will be autogenerated. + +2. If the function cannot be autogenerated (i.e. the mapping does not exist), + you must write the wrapper by hand. Add the function to ``NO_WRAPPER`` in + ``hpy/tools/autogen/debug.py``, and add a ``ctx_fname`` function to + ``hyp/devel/src/runtime/*.c`` (possibly adding the new file to ``setup.py``), + add a debug wrapper to ``hpy/debug/src/debug_ctx.c``, add a implementation + that uses the ``ctx`` variant to ``hpy/devel/include/hpy/cpython/misc.h`` and + add the declaration to ``hpy/devel/include/hpy/runtime/ctx_funcs.h``. + +3. Run ``make autogen`` which will turn the mapping into autogenerated functions + +4. Add a test for the functionality + +5. Build with ``python setup.py build_ext``. After that works, build with + ``python -m pip install -e .``, then run the test with ``python -m pytest ...``. diff --git a/graalpython/hpy/docs/debug-mode.rst b/graalpython/hpy/docs/debug-mode.rst new file mode 100644 index 0000000000..0f59bc9486 --- /dev/null +++ b/graalpython/hpy/docs/debug-mode.rst @@ -0,0 +1,169 @@ +Debug Mode +========== + +HPy includes a debug mode which does useful run-time checks to ensure that C +extensions use the API correctly. Its features include: + + 1. No special compilation flags are required: it is enough to compile the + extension with the Universal ABI. + + 2. Debug mode can be activated at *import time*, and it can be activated + per-extension. + + 3. You pay the overhead of debug mode only if you use it. Extensions loaded + without the debug mode run at full speed. + +This is possible because the whole of the HPy API is provided as part of the HPy +context, so debug mode can pass in a special debugging context without affecting +the performance of the regular context at all. + +.. note:: The debug mode is only available if the module (you want to use it + for) was built for :term:`HPy Universal ABI`. + +The debugging context can already check for: + +* Leaked handles. +* Handles used after they are closed. +* Tuple and list builder used after they were *closed* (i.e. cancelled or the + tuple/list was built). +* Reading from a memory which is no longer guaranteed to be still valid, + for example, the buffer returned by :c:func:`HPyUnicode_AsUTF8AndSize`, + :c:func:`HPyBytes_AsString`, and :c:func:`HPyBytes_AS_STRING`, after the + corresponding ``HPy`` handle was closed. +* Writing to memory which should be read-only, for example the buffer + returned by :c:func:`HPyUnicode_AsUTF8AndSize`, :c:func:`HPyBytes_AsString`, + and :c:func:`HPyBytes_AS_STRING` + + +Activating Debug Mode +--------------------- + +Debug mode works *only* for extensions built with HPy universal ABI. + +To enable debug mode, use environment variable ``HPY``. If ``HPY=debug``, then +all HPy modules are loaded with the trace context. Alternatively, it is also +possible to specify the mode per module like this: +``HPY=modA:debug,modB:debug``. + +In order to verify that your extension is being loaded in debug mode, use +environment variable ``HPY_LOG``. If this variable is set, then all HPy +extensions built in universal ABI mode print a message when loaded, such as: + +.. code-block:: console + + > import snippets + Loading 'snippets' in HPy universal mode with a debug context + +.. Note: the output above is tested in test_leak_detector_with_traces_output + +If the extension is built in CPython ABI mode, then the ``HPY_LOG`` environment +variable has no effect. + +An HPy extension module may be also explicitly loaded in debug mode using: + +.. code-block:: python + + from hpy.universal import load, MODE_DEBUG + mod = load(module_name, so_filename, mode=MODE_DEBUG) + +When loading HPy extensions explicitly, environment variables ``HPY_LOG`` +and ``HPY`` have no effect for that extension. + + +Using Debug Mode +---------------- + +By default, when debug mode detects an error it will either abort the process +(using :c:func:`HPy_FatalError`) or raise a fatal exception. This may sound very +strict but in general, it is not safe to continue the execution. + +When testing, aborting the process is unwanted. Module ``hpy.debug`` exposes the +``LeakDetector`` class to detect leaked ``HPy`` handles. For example: + +.. literalinclude:: examples/tests.py + :language: python + :start-at: def test_leak_detector + :end-before: # END: test_leak_detector + +Additionally, the debug module also provides a pytest fixture, ``hpy_debug``, +that for the time being, enables the ``LeakDetector``. In the future, it +may also enable other useful debugging facilities. + +.. literalinclude:: examples/tests.py + :language: python + :start-at: from hpy.debug.pytest import hpy_debug + :end-at: # Run some HPy extension code + +.. warning:: The usage of ``LeakDetector`` or ``hpy_debug`` by itself does not + enable HPy debug mode! If debug mode is not enabled for any extension, then + those features have no effect. + +When dealing with handle leaks, it is useful to get a stack trace of the +allocation of the leaked handle. This feature has large memory requirements +and is therefore opt-in. It can be activated by: + +.. literalinclude:: examples/tests.py + :language: python + :start-at: hpy.debug.set_handle_stack_trace_limit + :end-at: hpy.debug.set_handle_stack_trace_limit + +and disabled by: + +.. literalinclude:: examples/tests.py + :language: python + :start-at: hpy.debug.disable_handle_stack_traces + :end-at: hpy.debug.disable_handle_stack_traces + + +Example +------- + +.. note: The following output is tested in test_leak_detector_with_traces_output + +Following HPy function leaks a handle: + +.. literalinclude:: examples/snippets/snippets.c + :start-after: // BEGIN: test_leak_stacktrace + :end-before: // END: test_leak_stacktrace + +When this script is executed in debug mode: + +.. literalinclude:: examples/debug-example.py + :language: python + :end-before: print("SUCCESS") + +The output is:: + + Traceback (most recent call last): + File "/path/to/hpy/docs/examples/debug-example.py", line 7, in + snippets.test_leak_stacktrace() + File "/path/to/hpy/debug/leakdetector.py", line 43, in __exit__ + self.stop() + File "/path/to/hpy/debug/leakdetector.py", line 36, in stop + raise HPyLeakError(leaks) + hpy.debug.leakdetector.HPyLeakError: 1 unclosed handle: + + Allocation stacktrace: + /path/to/site-packages/hpy-0.0.4.dev227+gd7eeec6.d20220510-py3.8-linux-x86_64.egg/hpy/universal.cpython-38d-x86_64-linux-gnu.so(debug_ctx_Long_FromLong+0x45) [0x7f1d928c48c4] + /path/to/site-packages/hpy_snippets-0.0.0-py3.8-linux-x86_64.egg/snippets.hpy.so(+0x122c) [0x7f1d921a622c] + /path/to/site-packages/hpy_snippets-0.0.0-py3.8-linux-x86_64.egg/snippets.hpy.so(+0x14b1) [0x7f1d921a64b1] + /path/to/site-packages/hpy-0.0.4.dev227+gd7eeec6.d20220510-py3.8-linux-x86_64.egg/hpy/universal.cpython-38d-x86_64-linux-gnu.so(debug_ctx_CallRealFunctionFromTrampoline+0xca) [0x7f1d928bde1e] + /path/to/site-packages/hpy_snippets-0.0.0-py3.8-linux-x86_64.egg/snippets.hpy.so(+0x129b) [0x7f1d921a629b] + /path/to/site-packages/hpy_snippets-0.0.0-py3.8-linux-x86_64.egg/snippets.hpy.so(+0x1472) [0x7f1d921a6472] + /path/to/libpython3.8d.so.1.0(+0x10a022) [0x7f1d93807022] + /path/to/libpython3.8d.so.1.0(+0x1e986b) [0x7f1d938e686b] + /path/to/libpython3.8d.so.1.0(+0x2015e9) [0x7f1d938fe5e9] + /path/to/libpython3.8d.so.1.0(_PyEval_EvalFrameDefault+0x1008c) [0x7f1d938f875a] + /path/to/libpython3.8d.so.1.0(PyEval_EvalFrameEx+0x64) [0x7f1d938e86b8] + /path/to/libpython3.8d.so.1.0(_PyEval_EvalCodeWithName+0xfaa) [0x7f1d938fc8af] + /path/to/libpython3.8d.so.1.0(PyEval_EvalCodeEx+0x86) [0x7f1d938fca25] + /path/to/libpython3.8d.so.1.0(PyEval_EvalCode+0x4b) [0x7f1d938e862b] + +For the time being, HPy uses the glibc ``backtrace`` and ``backtrace_symbols`` +`functions `_. +Therefore all their caveats and limitations apply. Usual recommendations to get +more symbols in the traces and not only addresses, such as ``snippets.hpy.so(+0x122c)``, are: + +* link your native code with ``-rdynamic`` flag (``LDFLAGS="-rdynamic"``) +* build your code without optimizations and with debug symbols (``CFLAGS="-O0 -g"``) +* use ``addr2line`` command line utility, e.g.: ``addr2line -e /path/to/snippets.hpy.so -C -f +0x122c`` diff --git a/graalpython/hpy/docs/examples/debug-example.py b/graalpython/hpy/docs/examples/debug-example.py new file mode 100644 index 0000000000..0cd16cae36 --- /dev/null +++ b/graalpython/hpy/docs/examples/debug-example.py @@ -0,0 +1,10 @@ +# Run with HPY=debug +import hpy.debug +import snippets + +hpy.debug.set_handle_stack_trace_limit(16) +from hpy.debug.pytest import LeakDetector +with LeakDetector() as ld: + snippets.test_leak_stacktrace() + +print("SUCCESS") # Should not be actually printed diff --git a/graalpython/hpy/docs/examples/hpytype-example/builtin_type.c b/graalpython/hpy/docs/examples/hpytype-example/builtin_type.c new file mode 100644 index 0000000000..5ec749b690 --- /dev/null +++ b/graalpython/hpy/docs/examples/hpytype-example/builtin_type.c @@ -0,0 +1,106 @@ +#include +#include + +// BEGIN: spec_Dummy +static HPyType_Spec Dummy_spec = { + .name = "builtin_type.Dummy", + .basicsize = 0 +}; + +// END: spec_Dummy +static void make_Dummy(HPyContext *ctx, HPy module) +{ +// BEGIN: add_Dummy + HPyType_SpecParam param[] = { + { HPyType_SpecParam_Base, ctx->h_UnicodeType }, + { (HPyType_SpecParam_Kind)0 } + }; + if (!HPyHelpers_AddType(ctx, module, "Dummy", &Dummy_spec, param)) + return; +// END: add_Dummy +} + +// BEGIN: LanguageObject +typedef struct { + char *language; +} LanguageObject; +HPyType_HELPERS(LanguageObject, HPyType_BuiltinShape_Unicode) +// END: LanguageObject + +HPyDef_GETSET(Language_lang, "lang") +static HPy Language_lang_get(HPyContext *ctx, HPy self, void *closure) +{ + LanguageObject *data = LanguageObject_AsStruct(ctx, self); + return HPyUnicode_FromString(ctx, data->language); +} +static int Language_lang_set(HPyContext *ctx, HPy self, HPy value, void *closure) +{ + LanguageObject *data = LanguageObject_AsStruct(ctx, self); + HPy_ssize_t size; + const char *s = HPyUnicode_AsUTF8AndSize(ctx, value, &size); + if (s == NULL) + return -1; + data->language = (char *)calloc(size+1, sizeof(char)); + strncpy(data->language, s, size); + return 0; +} + +HPyDef_SLOT(Language_destroy, HPy_tp_destroy) +static void Language_destroy_impl(void *data) +{ + LanguageObject *ldata = (LanguageObject *)data; + if (ldata->language) + free(ldata->language); +} + +HPyDef *Language_defines[] = { + &Language_lang, + &Language_destroy, + NULL +}; + + +// BEGIN: spec_Language +static HPyType_Spec Language_spec = { + .name = "builtin_type.Language", + .basicsize = sizeof(LanguageObject), + .builtin_shape = SHAPE(LanguageObject), + .defines = Language_defines +}; +// END: spec_Language + +static void make_Language(HPyContext *ctx, HPy module) +{ +// BEGIN: add_Language + HPyType_SpecParam param[] = { + { HPyType_SpecParam_Base, ctx->h_UnicodeType }, + { (HPyType_SpecParam_Kind)0 } + }; + if (!HPyHelpers_AddType(ctx, module, "Language", &Language_spec, param)) + return; +// END: add_Language +} + +HPyDef_SLOT(simple_exec, HPy_mod_exec) +static int simple_exec_impl(HPyContext *ctx, HPy m) { + make_Dummy(ctx, m); + if (HPyErr_Occurred(ctx)) + return -1; + + make_Language(ctx, m); + if (HPyErr_Occurred(ctx)) + return -1; + + return 0; // success +} + +static HPyDef *mod_defines[] = { + &simple_exec, // 'simple_exec' is generated by the HPyDef_SLOT macro + NULL, +}; + +static HPyModuleDef moduledef = { + .defines = mod_defines +}; + +HPy_MODINIT(builtin_type, moduledef) diff --git a/graalpython/hpy/docs/examples/hpytype-example/setup.py b/graalpython/hpy/docs/examples/hpytype-example/setup.py new file mode 100644 index 0000000000..f740a424e1 --- /dev/null +++ b/graalpython/hpy/docs/examples/hpytype-example/setup.py @@ -0,0 +1,11 @@ +from setuptools import setup, Extension +from os import path + +setup( + name="hpy-type-example", + hpy_ext_modules=[ + Extension('simple_type', sources=['simple_type.c']), + Extension('builtin_type', sources=['builtin_type.c']), + ], + setup_requires=['hpy'], +) diff --git a/graalpython/hpy/docs/examples/hpytype-example/simple_type.c b/graalpython/hpy/docs/examples/hpytype-example/simple_type.c new file mode 100644 index 0000000000..40b1fba715 --- /dev/null +++ b/graalpython/hpy/docs/examples/hpytype-example/simple_type.c @@ -0,0 +1,102 @@ +#include + +// BEGIN: PointObject +typedef struct { + long x; + long y; +} PointObject; +HPyType_HELPERS(PointObject) +// END: PointObject + +// BEGIN: members +HPyDef_MEMBER(Point_x, "x", HPyMember_LONG, offsetof(PointObject, x)) +HPyDef_MEMBER(Point_y, "y", HPyMember_LONG, offsetof(PointObject, y)) +// END: members + +// BEGIN: methods +HPyDef_METH(Point_foo, "foo", HPyFunc_NOARGS) +static HPy Point_foo_impl(HPyContext *ctx, HPy self) +{ + PointObject *point = PointObject_AsStruct(ctx, self); + return HPyLong_FromLong(ctx, point->x * 10 + point->y); +} +// END: methods + +// BEGIN: getset +HPyDef_GETSET(Point_z, "z", .closure=(void *)1000) +static HPy Point_z_get(HPyContext *ctx, HPy self, void *closure) +{ + PointObject *point = PointObject_AsStruct(ctx, self); + return HPyLong_FromLong(ctx, point->x*10 + point->y + (long)(HPy_ssize_t)closure); +} + +static int Point_z_set(HPyContext *ctx, HPy self, HPy value, void *closure) +{ + PointObject *point = PointObject_AsStruct(ctx, self); + long current = point->x*10 + point->y + (long)(HPy_ssize_t)closure; + long target = HPyLong_AsLong(ctx, value); // assume no exception + point->y += target - current; + return 0; +} +// END: getset + +// BEGIN: slots +HPyDef_SLOT(Point_new, HPy_tp_new) +static HPy Point_new_impl(HPyContext *ctx, HPy cls, const HPy *args, + HPy_ssize_t nargs, HPy kw) +{ + long x, y; + if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &x, &y)) + return HPy_NULL; + PointObject *point; + HPy h_point = HPy_New(ctx, cls, &point); + if (HPy_IsNull(h_point)) + return HPy_NULL; + point->x = x; + point->y = y; + return h_point; +} +// END: slots + +// BEGIN: defines +static HPyDef *Point_defines[] = { + &Point_x, + &Point_y, + &Point_z, + &Point_new, + &Point_foo, + NULL +}; +// END: defines + +// BEGIN: spec +static HPyType_Spec Point_spec = { + .name = "simple_type.Point", + .basicsize = sizeof(PointObject), + .builtin_shape = PointObject_SHAPE, + .defines = Point_defines +}; +// END: spec + +// BEGIN: add_type +HPyDef_SLOT(simple_exec, HPy_mod_exec) +static int simple_exec_impl(HPyContext *ctx, HPy m) { + if (!HPyHelpers_AddType(ctx, m, "Point", &Point_spec, NULL)) { + return -1; + } + return 0; // success +} + +static HPyDef *mod_defines[] = { + &simple_exec, // 'simple_exec' is generated by the HPyDef_SLOT macro + NULL, +}; + +static HPyModuleDef moduledef = { + .defines = mod_defines, + // ... +// END: add_type + .doc = "A simple HPy type", +}; + +HPy_MODINIT(simple_type, moduledef) \ No newline at end of file diff --git a/graalpython/hpy/docs/examples/hpytype-example/simple_type.rst b/graalpython/hpy/docs/examples/hpytype-example/simple_type.rst new file mode 100644 index 0000000000..d611e5113c --- /dev/null +++ b/graalpython/hpy/docs/examples/hpytype-example/simple_type.rst @@ -0,0 +1,8 @@ +:orphan: + +simple_type.c +============= + +.. literalinclude:: ./simple_type.c + :language: c + :linenos: diff --git a/graalpython/hpy/docs/examples/mixed-example/mixed.c b/graalpython/hpy/docs/examples/mixed-example/mixed.c new file mode 100644 index 0000000000..d041f3f41c --- /dev/null +++ b/graalpython/hpy/docs/examples/mixed-example/mixed.c @@ -0,0 +1,49 @@ +/* Simple C module that shows how to mix CPython API and HPY. + * At the moment, this code is not referenced from the documentation, but it is + * tested nonetheless. + */ + +#include "hpy.h" + +/* a HPy style function */ +HPyDef_METH(add_ints, "add_ints", HPyFunc_VARARGS) +static HPy add_ints_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) +{ + long a, b; + if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &a, &b)) + return HPy_NULL; + return HPyLong_FromLong(ctx, a+b); +} + + +/* Add an old-style function */ +static PyObject * +add_ints2(PyObject *self, PyObject *args) +{ + + long a, b, ret; + if (!PyArg_ParseTuple(args, "ll", &a, &b)) + return NULL; + ret = a + b; + return PyLong_FromLong(ret); +} + +static HPyDef *hpy_defines[] = { + &add_ints, + NULL +}; + +static PyMethodDef py_defines[] = { + {"add_ints_legacy", add_ints2, METH_VARARGS, "add two ints"}, + {NULL, NULL, 0, NULL} /* Sentinel */ +}; + +static HPyModuleDef moduledef = { + .doc = "HPy Example of mixing CPython API and HPy API", + .size = 0, + .defines = hpy_defines, + .legacy_methods = py_defines +}; + + +HPy_MODINIT(mixed, moduledef) diff --git a/graalpython/hpy/docs/examples/mixed-example/setup.py b/graalpython/hpy/docs/examples/mixed-example/setup.py new file mode 100644 index 0000000000..75af734583 --- /dev/null +++ b/graalpython/hpy/docs/examples/mixed-example/setup.py @@ -0,0 +1,10 @@ +from setuptools import setup, Extension +from os import path + +setup( + name="hpy-mixed-example", + hpy_ext_modules=[ + Extension('mixed', sources=[path.join(path.dirname(__file__), 'mixed.c')]), + ], + setup_requires=['hpy'], +) diff --git a/graalpython/hpy/docs/examples/quickstart/quickstart.c b/graalpython/hpy/docs/examples/quickstart/quickstart.c new file mode 100644 index 0000000000..ce9542046a --- /dev/null +++ b/graalpython/hpy/docs/examples/quickstart/quickstart.c @@ -0,0 +1,39 @@ +// quickstart.c + +// This header file is the entrypoint to the HPy API: +#include "hpy.h" + +// HPy method: the HPyDef_METH macro generates some boilerplate code, +// the same code can be also written manually if desired +HPyDef_METH(say_hello, "say_hello", HPyFunc_NOARGS) +static HPy say_hello_impl(HPyContext *ctx, HPy self) +{ + // Methods take HPyContext, which must be passed as the first argument to + // all HPy API functions. Other than that HPyUnicode_FromString does the + // same thing as PyUnicode_FromString. + // + // HPy type represents a "handle" to a Python object, but may not be + // a pointer to the object itself. It should be fully "opaque" to the + // users. Try uncommenting the following two lines to see the difference + // from PyObject*: + // + // if (self == self) + // HPyUnicode_FromString(ctx, "Surprise? Try HPy_Is(ctx, self, self)"); + + return HPyUnicode_FromString(ctx, "Hello world"); +} + +static HPyDef *QuickstartMethods[] = { + &say_hello, // 'say_hello' generated for us by the HPyDef_METH macro + NULL, +}; + +static HPyModuleDef quickstart_def = { + .doc = "HPy Quickstart Example", + .defines = QuickstartMethods, +}; + +// The Python interpreter will create the module for us from the +// HPyModuleDef specification. Additional initialization can be +// done in the HPy_mod_exec slot +HPy_MODINIT(quickstart, quickstart_def) diff --git a/graalpython/hpy/docs/examples/quickstart/setup.py b/graalpython/hpy/docs/examples/quickstart/setup.py new file mode 100644 index 0000000000..0d56aefec4 --- /dev/null +++ b/graalpython/hpy/docs/examples/quickstart/setup.py @@ -0,0 +1,13 @@ +# setup.py + +from setuptools import setup, Extension +from os import path + +DIR = path.dirname(__file__) +setup( + name="hpy-quickstart", + hpy_ext_modules=[ + Extension('quickstart', sources=[path.join(DIR, 'quickstart.c')]), + ], + setup_requires=['hpy'], +) diff --git a/graalpython/hpy/docs/examples/simple-example/setup.py b/graalpython/hpy/docs/examples/simple-example/setup.py new file mode 100644 index 0000000000..af81861942 --- /dev/null +++ b/graalpython/hpy/docs/examples/simple-example/setup.py @@ -0,0 +1,10 @@ +from setuptools import setup, Extension +from os import path + +setup( + name="hpy-simple-example", + hpy_ext_modules=[ + Extension('simple', sources=[path.join(path.dirname(__file__), 'simple.c')]), + ], + setup_requires=['hpy'], +) diff --git a/graalpython/hpy/docs/examples/simple-example/simple.c b/graalpython/hpy/docs/examples/simple-example/simple.c new file mode 100644 index 0000000000..49883a950a --- /dev/null +++ b/graalpython/hpy/docs/examples/simple-example/simple.c @@ -0,0 +1,43 @@ +/* Simple C module that defines single simple function "myabs". + * We need to have a separate standalone package for those snippets, because we + * want to show the source code in its entirety, including the HPyDef array + * initialization, the module definition, and the setup.py script, so there is + * no room left for mixing these code snippets with other code snippets. + */ + +// BEGIN: myabs +#include "hpy.h" + +HPyDef_METH(myabs, "myabs", HPyFunc_O) +static HPy myabs_impl(HPyContext *ctx, HPy self, HPy arg) +{ + return HPy_Absolute(ctx, arg); +} +// END: myabs + +// BEGIN: double +HPyDef_METH_IMPL(double_num, "double", double_impl, HPyFunc_O) +static HPy double_impl(HPyContext *ctx, HPy self, HPy arg) +{ + return HPy_Add(ctx, arg, arg); +} +// END: double + +// BEGIN: methodsdef +static HPyDef *SimpleMethods[] = { + &myabs, + &double_num, + NULL, +}; + +static HPyModuleDef simple = { + .doc = "HPy Example", + .size = 0, + .defines = SimpleMethods, + .legacy_methods = NULL +}; +// END: methodsdef + +// BEGIN: moduledef +HPy_MODINIT(simple, simple) +// END: moduledef \ No newline at end of file diff --git a/graalpython/hpy/docs/examples/snippets/hpycall.c b/graalpython/hpy/docs/examples/snippets/hpycall.c new file mode 100644 index 0000000000..9fc51e1f3e --- /dev/null +++ b/graalpython/hpy/docs/examples/snippets/hpycall.c @@ -0,0 +1,196 @@ +#include + +// BEGIN EuclideanVectorObject +typedef struct { + long x; + long y; +} EuclideanVectorObject; +HPyType_HELPERS(EuclideanVectorObject) +// END EuclideanVectorObject + +// BEGIN HPy_tp_call +HPyDef_SLOT(call, HPy_tp_call) +static HPy +call_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs, + HPy kwnames) +{ + static const char *keywords[] = { "x1", "y1", NULL }; + long x1, y1; + HPyTracker ht; + if (!HPyArg_ParseKeywords(ctx, &ht, args, nargs, kwnames, "ll", keywords, + &x1, &y1)) { + return HPy_NULL; + } + EuclideanVectorObject *data = EuclideanVectorObject_AsStruct(ctx, self); + return HPyLong_FromLong(ctx, data->x * x1 + data->y * y1); +} +// END HPy_tp_call + +// BEGIN HPy_SetCallFunction +HPyDef_CALL_FUNCTION(special_call) +static HPy +special_call_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs, + HPy kwnames) +{ + HPy tmp = call_impl(ctx, self, args, nargs, kwnames); + HPy res = HPy_Negative(ctx, tmp); + HPy_Close(ctx, tmp); + return res; +} + +HPyDef_SLOT(new, HPy_tp_new) +static HPy +new_impl(HPyContext *ctx, HPy cls, const HPy *args, HPy_ssize_t nargs, HPy kw) +{ + static const char *keywords[] = { "x", "y", "use_special_call", NULL }; + HPyTracker ht; + long x, y; + HPy use_special_call = ctx->h_False; + if (!HPyArg_ParseKeywordsDict(ctx, &ht, args, nargs, kw, "ll|O", keywords, + &x, &y, &use_special_call)) { + return HPy_NULL; + } + EuclideanVectorObject *vector; + HPy h_point = HPy_New(ctx, cls, &vector); + if (HPy_IsNull(h_point)) { + HPyTracker_Close(ctx, ht); + return HPy_NULL; + } + if (HPy_IsTrue(ctx, use_special_call) && + HPy_SetCallFunction(ctx, h_point, &special_call) < 0) { + HPyTracker_Close(ctx, ht); + HPy_Close(ctx, h_point); + return HPy_NULL; + } + HPyTracker_Close(ctx, ht); + vector->x = x; + vector->y = y; + return h_point; +} +// END HPy_SetCallFunction + +// BEGIN FooObject +typedef struct { + void *a; + HPyCallFunction call_func; + void *b; +} FooObject; +HPyType_HELPERS(FooObject) +// END FooObject + +// BEGIN vectorcalloffset +HPyDef_MEMBER(Foo_call_func_offset, "__vectorcalloffset__", HPyMember_HPYSSIZET, + offsetof(FooObject, call_func), .readonly=1) + +HPyDef_CALL_FUNCTION(Foo_call_func) +static HPy +Foo_call_func_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs, + HPy kwnames) +{ + return HPyUnicode_FromString(ctx, + "hello manually initialized call function"); +} + +HPyDef_SLOT(Foo_new, HPy_tp_new) +static HPy Foo_new_impl(HPyContext *ctx, HPy cls, const HPy *args, + HPy_ssize_t nargs, HPy kw) +{ + FooObject *data; + HPy h_obj = HPy_New(ctx, cls, &data); + if (HPy_IsNull(h_obj)) + return HPy_NULL; + data->call_func = Foo_call_func; + return h_obj; +} +// END vectorcalloffset + +// BEGIN pack_args +// function using legacy 'tp_call' calling convention +static HPy +Pack_call_legacy(HPyContext *ctx, HPy self, HPy args, HPy kwd) +{ + // use 'args' and 'kwd' + return HPy_Dup(ctx, ctx->h_None); +} + +// function using HPy calling convention +HPyDef_SLOT(Pack_call, HPy_tp_call) +static HPy +Pack_call_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs, + HPy kwnames) +{ + HPy args_tuple, kwd; + HPy result; + if (!HPyHelpers_PackArgsAndKeywords(ctx, args, nargs, kwnames, + &args_tuple, &kwd)) { + return HPy_NULL; + } + result = Pack_call_legacy(ctx, self, args_tuple, kwd); + HPy_Close(ctx, args_tuple); + HPy_Close(ctx, kwd); + return result; +} +// END pack_args + +static HPyDef *Point_defines[] = { + &call, + &new, + NULL +}; +static HPyType_Spec EuclideanVector_spec = { + .name = "hpycall.EuclideanVector", + .basicsize = sizeof(EuclideanVectorObject), + .builtin_shape = SHAPE(EuclideanVectorObject), + .defines = Point_defines +}; + +static HPyDef *Foo_defines[] = { + &Foo_call_func_offset, + &Foo_new, + NULL +}; +static HPyType_Spec Foo_spec = { + .name = "hpycall.Foo", + .basicsize = sizeof(FooObject), + .builtin_shape = SHAPE(FooObject), + .defines = Foo_defines +}; + +static HPyDef *Pack_defines[] = { + &Pack_call, + NULL +}; +static HPyType_Spec Pack_spec = { + .name = "hpycall.Pack", + .defines = Pack_defines +}; + +HPyDef_SLOT(init, HPy_mod_exec) +static int init_impl(HPyContext *ctx, HPy m) +{ + if (!HPyHelpers_AddType(ctx, m, "EuclideanVector", &EuclideanVector_spec, NULL)) { + return -1; + } + if (!HPyHelpers_AddType(ctx, m, "Foo", &Foo_spec, NULL)) { + return -1; + } + if (!HPyHelpers_AddType(ctx, m, "Pack", &Pack_spec, NULL)) { + return -1; + } + return 0; +} + +static HPyDef *moduledefs[] = { + &init, + NULL +}; + +static HPyModuleDef moduledef = { + .doc = "HPy call protocol usage example", + .size = 0, + .legacy_methods = NULL, + .defines = moduledefs, + +}; + +HPy_MODINIT(hpycall, moduledef) diff --git a/graalpython/hpy/docs/examples/snippets/hpyinit.c b/graalpython/hpy/docs/examples/snippets/hpyinit.c new file mode 100644 index 0000000000..f23bba29eb --- /dev/null +++ b/graalpython/hpy/docs/examples/snippets/hpyinit.c @@ -0,0 +1,22 @@ +#include "hpy.h" + +// BEGIN +HPyDef_SLOT(my_exec, HPy_mod_exec) +int my_exec_impl(HPyContext *ctx, HPy mod) { + + // Some initialization: add types, constants, ... + + return 0; // success +} + +static HPyDef *Methods[] = { + &my_exec, // HPyDef_SLOT macro generated `my_exec` for us + NULL, +}; + +static HPyModuleDef mod_def = { + .defines = Methods +}; + +HPy_MODINIT(hpyinit, mod_def) +// END \ No newline at end of file diff --git a/graalpython/hpy/docs/examples/snippets/hpyvarargs.c b/graalpython/hpy/docs/examples/snippets/hpyvarargs.c new file mode 100644 index 0000000000..a95617d542 --- /dev/null +++ b/graalpython/hpy/docs/examples/snippets/hpyvarargs.c @@ -0,0 +1,45 @@ +/* Simple C module that defines simple functions "myabs" and "add_ints". + * + * This module represents an incremental change over the "simple" package + * and shows how to add a method with VARARGS calling convention. + * + * We need to have a separate standalone C module for those snippets, because we + * want to show the source code including the HPyDef array initialization, so + * there is no room left for adding other entry points for other code snippets. + */ + +#include "hpy.h" + +// This is here to make the module look like an incremental change to simple-example +HPyDef_METH(myabs, "myabs", HPyFunc_O) +static HPy myabs_impl(HPyContext *ctx, HPy self, HPy arg) +{ + return HPy_Absolute(ctx, arg); +} + +// BEGIN: add_ints +HPyDef_METH(add_ints, "add_ints", HPyFunc_VARARGS) +static HPy add_ints_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) +{ + long a, b; + if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &a, &b)) + return HPy_NULL; + return HPyLong_FromLong(ctx, a+b); +} +// END: add_ints + +// BEGIN: methodsdef +static HPyDef *SimpleMethods[] = { + &myabs, + &add_ints, + NULL, +}; +// END: methodsdef + +static HPyModuleDef def = { + .doc = "HPy Example of varargs calling convention", + .size = 0, + .defines = SimpleMethods +}; + +HPy_MODINIT(hpyvarargs, def) diff --git a/graalpython/hpy/docs/examples/snippets/legacyinit.c b/graalpython/hpy/docs/examples/snippets/legacyinit.c new file mode 100644 index 0000000000..f10381b617 --- /dev/null +++ b/graalpython/hpy/docs/examples/snippets/legacyinit.c @@ -0,0 +1,20 @@ +#include + +// BEGIN +static struct PyModuleDef mod_def = { + PyModuleDef_HEAD_INIT, + .m_name = "legacyinit", + .m_size = -1 +}; + +PyMODINIT_FUNC +PyInit_legacyinit(void) +{ + PyObject *mod = PyModule_Create(&mod_def); + if (mod == NULL) return NULL; + + // Some initialization: add types, constants, ... + + return mod; +} +// END \ No newline at end of file diff --git a/graalpython/hpy/docs/examples/snippets/setup.py b/graalpython/hpy/docs/examples/snippets/setup.py new file mode 100644 index 0000000000..6c097b0385 --- /dev/null +++ b/graalpython/hpy/docs/examples/snippets/setup.py @@ -0,0 +1,16 @@ +from setuptools import setup, Extension +from os import path + +setup( + name="hpy-snippets", + hpy_ext_modules=[ + Extension('hpyvarargs', sources=[path.join(path.dirname(__file__), 'hpyvarargs.c')]), + Extension('snippets', sources=[path.join(path.dirname(__file__), 'snippets.c')]), + Extension('hpyinit', sources=[path.join(path.dirname(__file__), 'hpyinit.c')]), + Extension('hpycall', sources=[path.join(path.dirname(__file__), 'hpycall.c')]), + ], + ext_modules=[ + Extension('legacyinit', sources=[path.join(path.dirname(__file__), 'legacyinit.c')]), + ], + setup_requires=['hpy'], +) diff --git a/graalpython/hpy/docs/examples/snippets/snippets.c b/graalpython/hpy/docs/examples/snippets/snippets.c new file mode 100644 index 0000000000..7e60a52cab --- /dev/null +++ b/graalpython/hpy/docs/examples/snippets/snippets.c @@ -0,0 +1,81 @@ +/* Module with various code snippets used in the docs. + * All code snippets should be put into this file if possible. Notable + * exception are code snippets showing definition of the module or the + * HPyDef array initialization. Remember to also add tests to ../tests.py + */ +#include "hpy.h" + +// ------------------------------------ +// Snippets used in api.rst + +// BEGIN: foo +void foo(HPyContext *ctx) +{ + HPy x = HPyLong_FromLong(ctx, 42); + HPy y = HPy_Dup(ctx, x); + /* ... */ + // we need to close x and y independently + HPy_Close(ctx, x); + HPy_Close(ctx, y); +} +// END: foo + +// BEGIN: is_same_object +int is_same_object(HPyContext *ctx, HPy x, HPy y) +{ + // return x == y; // compilation error! + return HPy_Is(ctx, x, y); +} +// END: is_same_object + +// dummy entry point so that we can test the snippets: +HPyDef_METH(test_foo_and_is_same_object, "test_foo_and_is_same_object", HPyFunc_VARARGS) +static HPy test_foo_and_is_same_object_impl(HPyContext *ctx, HPy self, + const HPy *args, size_t nargs) +{ + foo(ctx); // not much we can test here + return HPyLong_FromLong(ctx, is_same_object(ctx, args[0], args[1])); +} + +// BEGIN: test_leak_stacktrace +HPyDef_METH(test_leak_stacktrace, "test_leak_stacktrace", HPyFunc_NOARGS) +static HPy test_leak_stacktrace_impl(HPyContext *ctx, HPy self) +{ + HPy num = HPyLong_FromLong(ctx, 42); + if (HPy_IsNull(num)) { + return HPy_NULL; + } + // No HPy_Close(ctx, num); + return HPy_Dup(ctx, ctx->h_None); +} +// END: test_leak_stacktrace + +// BEGIN: add +HPyDef_METH(add, "add", HPyFunc_VARARGS) +static HPy add_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) +{ + if (nargs != 2) { + HPyErr_SetString(ctx, ctx->h_TypeError, "expected exactly two args"); + return HPy_NULL; + } + return HPy_Add(ctx, args[0], args[1]); +} +// END: add + +// ------------------------------------ +// Dummy module definition, so that we can test the snippets + +static HPyDef *Methods[] = { + &test_foo_and_is_same_object, + &test_leak_stacktrace, + &add, + NULL, +}; + +static HPyModuleDef snippets = { + .doc = "Various HPy code snippets for the docs", + .size = 0, + .defines = Methods +}; + +HPy_MODINIT(snippets, snippets) diff --git a/graalpython/hpy/docs/examples/tests.py b/graalpython/hpy/docs/examples/tests.py new file mode 100644 index 0000000000..8a8ee5f5df --- /dev/null +++ b/graalpython/hpy/docs/examples/tests.py @@ -0,0 +1,124 @@ +import os +import os.path +import re +import subprocess +import sys + +import simple +import mixed +import hpyvarargs +import snippets +import simple_type +import builtin_type +import hpycall + + +def test_simple_abs(): + assert simple.myabs(-42) == 42 + assert simple.myabs(42) == 42 + + +def test_hpyvarargs(): + assert hpyvarargs.add_ints(40, 2) == 42 + + +def test_mixed_add_ints(): + assert mixed.add_ints_legacy(40, 2) == 42 + assert mixed.add_ints(40, 2) == 42 + + +def test_snippets(): + x = 2 + assert snippets.test_foo_and_is_same_object(x, x) == 1 + assert snippets.test_foo_and_is_same_object(x, 42) == 0 + + +def test_simple_type(): + p = simple_type.Point(4, 5) + assert p.x == 4 + assert p.y == 5 + assert p.foo() == 45 + assert p.z == 1045 + p.z = 2000 + assert p.y == 960 + assert p.z == 2000 + + +def test_quickstart(): + import quickstart + assert quickstart.say_hello() == "Hello world" +# END: test_quickstart + + +def test_builtin_type(): + obj = builtin_type.Dummy("hello") + assert obj == "hello" + + obj = builtin_type.Language("hello") + obj.lang = "en" + assert obj == "hello" + assert obj.lang == "en" + + +def test_leak_detector(): + from hpy.debug.pytest import LeakDetector + with LeakDetector() as ld: + # add_ints is an HPy C function. If it forgets to close a handle, + # LeakDetector will complain + assert mixed.add_ints(40, 2) == 42 +# END: test_leak_detector + +from hpy.debug.pytest import hpy_debug +def test_that_uses_leak_detector_fixture(hpy_debug): + # Run some HPy extension code + assert mixed.add_ints(40, 2) == 42 + + +def test_leak_detector_with_traces(): + import hpy.debug + hpy.debug.set_handle_stack_trace_limit(16) + assert mixed.add_ints(40, 2) == 42 + hpy.debug.disable_handle_stack_traces() + + +def test_leak_detector_with_traces_output(): + # Update the debug documentation if anything here changes! + env = os.environ.copy() + env['HPY'] = 'debug' + env['HPY_LOG'] = '1' + script = os.path.join(os.path.dirname(__file__), 'debug-example.py') + result = subprocess.run([sys.executable, script], env=env, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + # Rudimentary check that the output contains what we have in the documentation + out = result.stdout.decode('latin-1') + assert out == "Loading 'snippets' in HPy universal mode with a debug context" + os.linesep + err = result.stderr.decode('latin-1') + assert 'hpy.debug.leakdetector.HPyLeakError: 1 unclosed handle:' in err + assert re.search('', err) + assert 'Allocation stacktrace:' in err + if sys.platform.startswith(("linux", "darwin")): + assert 'snippets.hpy0.so' in err # Should be somewhere in the stack trace + else: + assert 'At the moment this is only supported on Linux with glibc' in err + +def test_trace_mode_output(): + # Update the trace mode documentation if anything here changes! + env = os.environ.copy() + env['HPY'] = 'trace' + env['HPY_LOG'] = '1' + script = os.path.join(os.path.dirname(__file__), 'trace-example.py') + result = subprocess.run([sys.executable, script], env=env, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + # Rudimentary check that the output contains what we have in the documentation + out = result.stdout.decode('latin-1') + assert 'get_call_counts()["ctx_Add"] == 1' in out + +def test_call_dot_product(): + vec = hpycall.EuclideanVector(4, 5) + assert vec(6, 7) == 4 * 6 + 5 * 7 + vec = hpycall.EuclideanVector(4, 5, use_special_call=True) + assert vec(6, 7) == -(4 * 6 + 5 * 7) + foo = hpycall.Foo() + assert foo() == 'hello manually initialized call function' + pack = hpycall.Pack() + assert pack() is None diff --git a/graalpython/hpy/docs/examples/trace-example.py b/graalpython/hpy/docs/examples/trace-example.py new file mode 100644 index 0000000000..2a4d92838e --- /dev/null +++ b/graalpython/hpy/docs/examples/trace-example.py @@ -0,0 +1,9 @@ +# Run with HPY=trace +from hpy.trace import get_call_counts +import snippets + +add_count_0 = get_call_counts()["ctx_Add"] +snippets.add(1, 2) == 3 +add_count_1 = get_call_counts()["ctx_Add"] + +print('get_call_counts()["ctx_Add"] == %d' % (add_count_1 - add_count_0)) diff --git a/graalpython/hpy/docs/index.rst b/graalpython/hpy/docs/index.rst new file mode 100644 index 0000000000..9ca101b753 --- /dev/null +++ b/graalpython/hpy/docs/index.rst @@ -0,0 +1,80 @@ +.. HPy documentation master file, created by + sphinx-quickstart on Thu Apr 2 23:01:08 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +HPy: a better API for Python +=============================== + +HPy provides a new API for extending Python in C. + +There are several advantages to writing C extensions in HPy: + + - **Speed**: it runs much faster on PyPy, GraalPy, and at native speed on CPython + + - **Deployment**: it is possible to compile a single binary which runs unmodified on all + supported Python implementations and versions -- think "stable ABI" on steroids + + - **Simplicity**: it is simpler and more manageable than the ``Python.h`` API, both for + the users and the Pythons implementing it + + - **Debugging**: it provides an improved debugging experience. Debug mode can be turned + on at runtime without the need to recompile the extension or the Python running it. + HPy design is more suitable for automated checks. + +The official `Python/C API `_, +also informally known as ``#include ``, is +specific to the current implementation of CPython: it exposes a lot of +internal details which makes it hard to: + + - implement it for other Python implementations (e.g. PyPy, GraalPy, + Jython, ...) + + - experiment with new approaches inside CPython itself, for example: + + - use a tracing garbage collection instead of reference counting + - remove the global interpreter lock (GIL) to take full advantage of multicore architectures + - use tagged pointers to reduce memory footprint + +Where to go next: +----------------- + + - Show me the code: + + - :doc:`Quickstart` + - :ref:`Simple documented HPy extension example` + - :doc:`Tutorial: porting Python/C API extension to HPy` + + - Details: + + - :doc:`HPy overview: motivation, goals, current status` + - :doc:`HPy API concepts introduction` + - :doc:`Python/C API to HPy Porting guide` + - :doc:`HPy API reference` + + +Full table of contents: +----------------------- + +.. toctree:: + :maxdepth: 2 + + quickstart + overview + api + porting-guide + porting-example/index + debug-mode + trace-mode + api-reference/index + contributing/index + misc/index + changelog + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/graalpython/hpy/docs/leysin-2020-design-decisions.md b/graalpython/hpy/docs/leysin-2020-design-decisions.md new file mode 100644 index 0000000000..b50bb081c5 --- /dev/null +++ b/graalpython/hpy/docs/leysin-2020-design-decisions.md @@ -0,0 +1,295 @@ +Leysin Sprint 2020 Design Decisions +=================================== + +Closing and duping HPy_NULL +--------------------------- + +Question: Should `HPy_Close` silently ignore attempts to close `HPy_NULL`? + +Decisions: + +* `HPy_Close` should function like `Py_XDECREF` and silently not close `HPy_NULL`. +* `HPy_Dup` should silently not dup `HPy_NULL` for symmetry with `HPy_Close`, + i.e. `HPy_Dup(ctx, HPy_NULL)` should return `HPy_NULL`. +* Both the API and ABI versions should have this behaviour. +* We should add tests for this behaviour. + + +Attribute and item access +------------------------- + +Question: Should we have separate HPySequence_GetItem and HPyMapping_GetItem +or just one HPy_GetItem? Should we explore the idea of protocols for such +access. + +Decisions: + +* We should start with `HPy_GetItem` and `HPy_SetItem` and `HPy_GetItem_i` and + `HPy_SetItem_i` for item access and `HPy_GetAttr`, `HPy_SetAttr`, + `HPy_GetAttr_s` and `HPy_SetAttr_s` for attribute access.. +* We could add an `hpy/compat.h` that supports accessing the old Python mapping + and sequence get item slots. For example, `HPyDict_GetItem_NotBorrowed`. + `PyDict_GetItem` returns a borrower reference. `HPyDict_GetItem_NotBorrowed` + should return a new handle that has to be closed. +* HPy API functions MUST NOT return a borrowed reference and we should add this + to our official documentation. +* We should add an `HPyBuffer` protocol later (with the design still to be + decided). + +Proposed function signatures: + +```C +HPy HPy_GetItem(HPyContext ctx, HPy obj, HPy idx); +HPy HPy_GetItem_i(HPyContext ctx, HPy obj, HPy_ssize_t idx); +HPy HPy_GetItem_s(HPyContext ctx, HPy obj, const char * idx); // UTF8 bytes + +int HPy_SetItem(HPyContext ctx, HPy obj, HPy idx, HPy value); +int HPy_SetItem_i(HPyContext ctx, HPy obj, HPy_ssize_t idx, HPy value); +int HPy_SetItem_s(HPyContext ctx, HPy obj, const char * idx, HPy value); // UTF8 bytes + +HPy HPy_GetAttr(HPyContext ctx, HPy obj, HPy idx); +HPy HPy_GetAttr_s(HPyContext ctx, HPy obj, const char * idx); // UTF8 bytes + +int HPy_SetAttr(HPyContext ctx, HPy obj, HPy idx, HPy value); +int HPy_SetAttr_s(HPyContext ctx, HPy obj, const char * idx, HPy value); // UTF8 bytes +``` + +Macro for returning None +------------------------ + +Question: Should we have an HPy_RETURN_NONE macro? + +Decisions: + +* Yes we should, but it should be `HPy_RETURN_NONE(ctx)`. +* We should also change `HPy_IsNull(x)` to `HPy_IsNull(ctx, x)`. + +Proposed macros: + +```C +#define HPy_RETURN_NONE(ctx) return HPy_Dup(ctx, ctx->h_None); +#define HPy_IsNull(ctx, x) ...; +``` + +Passing handles as void pointers +-------------------------------- + +Question: Should we add `HPy_AsVoidP` and `HPy_FromVoidP` to the API? Should they +be on the ctx or not? + +Decisions: + +* Yes, they should be part of the API. +* They should take the ctx as an argument in case a future implementation needs + it (much like `HPy_IsNull`). + +Proposed functions: + +```C +// universal +static inline HPy HPy_FromVoidP(HPyContext ctx, void *p) { return (HPy){(HPy_ssize_t)p}; } +static inline void* HPy_AsVoidP(HPyContext ctx, HPy h) { return (void*)h._i; } + +// cpython (the -/+4 is to avoid people casting it to PyObject) +static inline HPy HPy_FromVoidP(HPyContext ctx, void *p) { return (HPy){(HPy_ssize_t)p - 4}; } +static inline void* HPy_AsVoidP(HPyContext ctx, HPy h) { return (void*)h._o + 4; } +``` + +/* + * Should we implement HPy_Dump? + * + * Question: What should it print and where should it print it? + * + * Decision: It's useful for debugging if all macros are also available as functions + * definitions. + * + * Decision: It should dump to stderr just like PyObject_Dump. + */ + +/* + * How do we silence warnings from using HPy_METH_KEYWORDS? + * + * Decision: Write a cast to HPyMeth. + */ + +{"add_ints_kw", (HPyMeth) add_ints_kw, HPy_METH_KEYWORDS, ""} + +/* + * How should HPyErr_Format be implemented? Should we avoid va_args? + * + * Decision: + */ + +HPyErr_Format(ctx, const char *fmt, ...) { + const char *msg = HPyStr_Format(ctx, fmt, ...); + HPyErr_SetString(msg); +} + +ctx->ctx_HPyErr_Format(???) + +/* + * Should make specifying values for optional arguments & dup / closing them + * less messy? + * + * Decision: Right now, No. In the future, someone should invent + * ARGUMENT_CLINIC for HPy. + */ + +/* + * Should we rename "struct _object*" to "PyObject*" and "_HPy_PyCFunction" + * to "PyCFunction" in universal/hpy.h? + * + * Decision: No. This would generate a warning if one imports Python.h. + * + * Decision: Comment in the code that this _object* is PyObject* and why we + * cannot call it that. + * + * Decision: In user documentation, just call ing PyObject *. + */ + +/* + * How should the API pass around exceptions? + * + * Decision: Follow CPython for each API call. + * + */ + +// E.g. API call returns HPy: + +HPy h = HPyLong_FromLong(ctx, 5); +if (HPy_IsNull(ctx, h)) { + // handle error + // python error has been set by the API call +} + +// or + +HPy h = HPyLong_FromLong(ctx, 5); +if (HPyErr_Occurred(ctx)) { + // handle error + // python error has been set by the API call +} + +// E.g. API call returns a value that is not an HPy: + +long l = HPyLong_AsLong(ctx, h); +if (l == -1 && HPyErr_Occurred(ctx)) { + // handle error + // python error has been set by the API call +} + +// E.g. API call returns a success or error flag: + +// int error = HPyArg_Parse(...); +if (!HPyArg_Parse(...)) { + // handle error + // python error has been set by the API call +} + +/* + * How should support for creating custom Python types look? + * + * Decisions: + * + * + */ + +// When using C-API: + +typedef struct { + PyObject_HEAD + /* Type-specific fields go here. */ + PyObject *x; + PyObject *y; + double *data; + int size; +} PointObject; + +// When using HPy: + +typedef struct { + HPyObject_HEAD + double x; + double y; +} HPy_Point; + +typedef struct { + HPyObject_HEAD + HPyField a; + HPyField b; +} HPy_Rectangle; + +/* Possible HPy code */ + +typedef struct { + ??? ob_type; +} _HPy_ObjectHeader; + +#define HPyObject_HEAD _HPy_ObjectHeader head; + +#define HPy_STORE(ctx, obj, field, value) ((ctx)->ctx_HPy_StoreInto((_HPy_ObjectHeader *) obj, &((obj)->field), value)) +#define HPy_STORE_INTO(ctx, obj, pointer, value) ((ctx)->ctx_HPy_StoreInto((_HPy_ObjectHeader *) obj, pointer, value)) + +// Using the debug mode ctx, this should check that obj->ob_type->tp_traverse is not NULL. +void HPy_StoreInto(HPyContext ctx, _HPy_ObjectHeader *obj, HPyField *pointer, HPy value) + +// HPy_New: +// +// * Should return a handle. +// * It should be possible to go from the handle to struct, but not +// from struct to handle. E.g. HPy_CAST(ctx, HPyRectangle, h) -> HPyRectangle, +// but no inverse. +// * We should not have an HPy_Init at the moment -- HPy_New both allocates +// the object and initializes it. We will add separate allocation and init +// later if we encounter a need for it. +// * HPyTypeSpec should follow the CPython type spec. + +#define HPy_CAST(ctx, return_type, h) (return_type *) ctx->ctx_HPy_Cast(h) + +void* HPy_Cast(ctx, HPy h); + +HPy HPy_TypeFromSpec(ctx, HPyTypeSpec type_spec); +HPy HPy_New(ctx, HPy h_type); + +/* end of possible HPy code */ + +HPy new_rect(HPy p1, HPy p2) { + // HPy_New always initialize the whole object to 0. We can also have + // HPy_NewUninitialized if we don't want to pay the penalty + HPy_Rectangle *rect; + HPy rect_handle = HPy_New(ctx, HPy_Rectangle, h_rectangle_type, &rect); + + // HPy_Store does a write barrier on PyPy, and DECREF the old rect->a on + // CPython if needed + HPy_Store(ctx, rect, a, p1); + HPy_Store(ctx, rect, b, p2); + return rect_handle; +} + +double calc_diagonal(HPy rect_handle) { + // rect is valid until rect_handle is closed. on PyPy we pin the object, and + // we unpin it when we close the handle + HPy_Rectangle *rect = HPy_Cast(HPy_Rectangle, rect_handle); + + // HPy_Load reads a field and turn it into a handle + HPy p1_handle = HPy_Load(rect->a); // p1 is a handle which must be closed + HPy_Point *p1 = HPy_Cast(HPy_Point, p1_handle); + + // for C99 compilers, we can also provide a macro which declares p2 and + // p2_handle automatically and does the equivalent of the two lines above + HPY_LOAD(HPy_Point, p2, rect->b); + + double diag = sqrt(p1->x - p2->x /* etc. etc. */); + + // close all the handles + HPy_Close(p1_handle); + HPy_Close(p2_handle); + + return diag; +} + +/* + * Should HPy support Python without the GIL? + * + * Problem left as an exercise for the reader. + */ diff --git a/graalpython/hpy/docs/misc/embedding.rst b/graalpython/hpy/docs/misc/embedding.rst new file mode 100644 index 0000000000..cb85d2bc10 --- /dev/null +++ b/graalpython/hpy/docs/misc/embedding.rst @@ -0,0 +1,46 @@ +Embedding HPy modules +===================== + +There might be cases where it is beneficial or even necessary to embed multiple +HPy modules into one library. HPy itself already makes use of that. The debug +and the trace module do not have individual libraries but are embedded into the +universal module. + +To achieve that, the embedder will use the macro :c:macro:`HPy_MODINIT` several times. +Unfortunately, this macro defines global state and cannot repeatedly be used by +default. In order to correctly embed several HPy modules into one library, the +embedder needs to consider following: + +* The modules must be compiled with preprocessor macro + :c:macro:`HPY_EMBEDDED_MODULES` defined to enable this feature. + +* There is one major restriction: All HPy-specific module pieces must be + in the same compilation unit. *HPy-specific pieces* are things like the + module's init function (``HPy_MODINIT``) and all slots, members, methods of + the module or any type of it (``HPyDef_*``). The implementation functions + (usually the ``*_impl`` functions) of the slots, members, methods, etc. and + any helper functions may still be in different compilation units. The reason + for this is that the global state induced by ``HPy_MODINIT`` is, of course, + made local (e.g. using C modifier ``static``). + +* It is also necessary to use macro :c:macro:`HPY_MOD_EMBEDDABLE` before the + first usage of any ``HPyDef_*`` macro. + +Also refer to the API reference :ref:`api-reference/hpy-type:hpy module`. + + +**Example** + +.. code-block:: c + + // compile with -DHPY_EMBEDDED_MODULES + + HPY_MOD_EMBEDDABLE(hpymodA) + + HPyDef_METH(foo, /* ... */) + static HPy foo_impl(/* ... */) + { + // ... + } + + HPy_MODINIT(extension_name, hpymodA) diff --git a/graalpython/hpy/docs/misc/index.rst b/graalpython/hpy/docs/misc/index.rst new file mode 100644 index 0000000000..f305c8ed01 --- /dev/null +++ b/graalpython/hpy/docs/misc/index.rst @@ -0,0 +1,7 @@ +Misc Notes +========== + +.. toctree:: + :maxdepth: 1 + + embedding diff --git a/graalpython/hpy/docs/module-state.txt b/graalpython/hpy/docs/module-state.txt new file mode 100644 index 0000000000..3682a8820e --- /dev/null +++ b/graalpython/hpy/docs/module-state.txt @@ -0,0 +1,44 @@ +How to replace global variables +------------------------------- + +In a given .c source, write: + + +typedef struct { + long x; + HPy y; +} my_globals_t; + +static void my_globals_traverse(traversefunc traverse, my_globals_t *g) +{ + traverse(g->y); +} + +HPyGlobalSpec my_globals = { + .m_size = sizeof(my_globals_t), + .m_traverse = my_globals_traverse +}; + + +There can be several HPyGlobalSpec structures around; in CPython it's done as +part of the PyModuleDef type, but there is no real reason for why it should +be tightly tied to a module. + + +To use: + + my_globals_t *g = HPy_GetState(ctx, &my_globals); + g->x++; + HPy_DoRandomStuffWithHandle(ctx, g->y); + + +Implementation: the type HPyGlobalSpec contains extra internal fields +which should give us a very fast cache: _last_ctx and _last_result, +and HPy_GetState() can be: + + if (ctx == globspec->_last_ctx) + return globspec->_last_result; + else + look up globspec in a dictionary attached to ctx, or vice-versa, + or maybe initialize globspec->_index with a unique incrementing + index and use that to index an array attached to ctx diff --git a/graalpython/hpy/docs/overview.rst b/graalpython/hpy/docs/overview.rst new file mode 100644 index 0000000000..e4c9e30b86 --- /dev/null +++ b/graalpython/hpy/docs/overview.rst @@ -0,0 +1,444 @@ +HPy Overview +============ + +Motivation and goals +--------------------- + +The superpower of the Python ecosystem is its libraries, which are developed by +users. Over time, these libraries have grown in number, quality, and +applicability. While it is possible to write python libraries entirely in +python, many of them, especially in the scientific community, are written in C +and exposed to Python using the `Python.h API +`_. The existence of these C +extensions using the ``Python.h`` API leads to some issues: + + 1. Usually, alternative implementation of the Python programming language + want to support C extensions. To do so, they must implement the same + ``Python.h`` API or provide a compatibility layer. + + 2. CPython developers cannot experiment with new designs or refactoring + without breaking compatibility with existing extensions. + +Over the years, it has become evident that emulating ``Python.h`` in an +efficient way is `challenging, if not impossible +`_. +To summarize, it is mainly due to leaking of implementation details of CPython +into the C/API - which makes it difficult to make different design choices than +those made by CPython. As such - the main goal of HPy is to provide a **C API +which makes as few assumptions as possible about the design decisions of any +implementation of Python, allowing diverse implementations to support it +efficiently and without compromise**. In particular, **reference counting is not +part of the API**: we want a more generic way of managing resources that is +possible to implement with different strategies, including the existing +reference counting and/or with a moving *Garbage Collector* (like the ones used +by PyPy, GraalPy or Java, for example). Moreover, each implementation can +experiment with new memory layout of objects, add optimizations, etc. The +following is a list of sub-goals. + + +Performance on CPython + HPy is usable on CPython from day 1 with no performance impact compared to + the existing ``Python.h`` API. + + +Incremental adoption + It is possible to port existing C extensions piece by piece and to use + the old and the new API side-by-side during the transition. + + +Easy migration + It should be easy to migrate existing C extensions to HPy. Thanks to an + appropriate and regular naming convention it should be obvious what the + HPy equivalent of any existing ``Python.h`` API is. When a perfect replacement + does not exist, the documentation explains what the alternative options are. + + +Better debugging + In debug mode, you get early and precise errors and warnings when you make + some specific kind of mistakes and/or violate the API rules and + assumptions. For example, you get an error if you try to use a handle + (see :ref:`api:handles`) which has already been closed. It is possible to + turn on the debug mode at startup time, *without needing to recompile*. + +Simplicity + The HPy API aims to be smaller and easier to study/use/manage than the + existing ``Python.h`` API. Sometimes there is a trade-off between this goal and + the others above, in particular *Performance on CPython* and *Easy migration*. + The general approach is to have an API which is "as simple as possible" while + not violating the other goals. + + +Universal binaries + It is possible to compile extensions to a single binary which is + ABI-compatible across multiple Python versions and/or multiple + implementation. See :ref:`hpy-target-abis`. + + +Opt-in low level data structures + Internal details might still be available, but in a opt-in way: for example, + if Cython wants to iterate over a list of integers, it can ask if the + implementation provides a direct low-level access to the content (e.g. in + the form of a ``int64_t[]`` array) and use that. But at the same time, be + ready to handle the generic fallback case. + + +API vs ABI +----------- + +HPy defines *both* an API and an ABI. Before digging further into details, +let's distinguish them: + + - The **API** works at the level of source code: it is the set of functions, + macros, types and structs which developers can use to write their own + extension modules. For C programs, the API is generally made available + through one or more header files (``*.h``). + + - The **ABI** works at the level of compiled code: it is the interface between + the host interpreter and the compiled DLL. Given a target CPU and + operating system it defines things like the set of exported symbols, the + precise memory layout of objects, the size of types, etc. + +In general it is possible to compile the same source into multiple compiled +libraries, each one targeting a different ABI. :pep:`3149` states that the +filename of the compiled extension should contain the *ABI tag* to specify +what the target ABI is. For example, if you compile an extension called +``simple.c`` on CPython 3.8, you get a DLL called +``simple.cpython-38-x86_64-linux-gnu.so``: + + - ``cpython-38`` is the ABI tag, in this case CPython 3.8 + + - ``x86_64`` is the CPU architecture + + - ``linux-gnu`` is the operating system + +The same source code compiled on PyPy3.6 7.2.0 results in a file called +``simple.pypy38-pp73-x86_64-linux-gnu.so``: + + - ``pypy38-pp73`` is the ABI tag, in this case "PyPy3.8", version "7.3.x" + +The HPy C API is exposed to the user by including ``hpy.h`` and it is +explained in its own section of the documentation. + + +Legacy and compatibility features +--------------------------------- + +To allow an incremental transition to HPy, it is possible to use both +``hpy.h`` and ``Python.h`` API calls in the same extension. Using *HPy legacy +features* you can: + + - mix ``Python.h`` and HPy method defs in the same HPy module + + - mix ``Python.h`` and HPy method defs and slots in the same HPy type + + - convert ``HPy`` handles to and from ``PyObject *`` using + ``HPy_AsPyObject()`` and ``HPy_FromPyObject()`` + + +Thanks to this, you can port your code to HPy one method and one type at a +time, while keeping the extension fully functional during the transition +period. See the :ref:`porting-guide:Porting guide` for a concrete example. + +Legacy features are available only if you target the CPython or HPy Hybrid +ABIs, as explained in the next section. + + +.. _hpy-target-abis: + +Target ABIs +----------- + +Depending on the compilation options, an HPy extension can target three +different ABIs: + +.. glossary:: + + CPython ABI + In this mode, HPy is implemented as a set of C macros and ``static inline`` + functions which translate the HPy API into the CPython API at compile + time. The result is a compiled extension which is indistinguishable from a + "normal" one and can be distributed using all the standard tools and will + run at the very same speed. + + *Legacy features* are available. + + The output filename is e.g. ``simple.cpython-38-x86_64-linux-gnu.so``. + + + HPy Universal ABI + As the name suggests, the HPy Universal ABI is designed to be loaded and + executed by a variety of different Python implementations. Compiled + extensions can be loaded unmodified on all the interpreters which support + it. PyPy and GraalPy support it natively. CPython supports it by using the + ``hpy.universal`` package, and there is a small speed penalty [#f1]_ compared to + the CPython ABI. + + *Legacy features* are **not** available and it is forbidden to ``#include ``. + + The resulting filename is e.g. ``simple.hpy0.so``. + + HPy Hybrid ABI + + The HPy Hybrid ABI is essentially the same as the Universal ABI, with + the big difference that it allows to ``#include ``, to use the + legacy features and thus to allow incremental porting. + + At the ABI level the resulting binary depends on *both* HPy and the + specific Python implementation which was used to compile the extension. + As the name suggests, this means that the binary is not "universal", + thus negating some of the benefits of HPy. The main benefit of using + the HPy Hybrid ABI instead of the CPython ABI is being able to use the + :ref:`debug-mode:Debug mode` on the HPy parts, and faster speed on + alternative implementations. + + *Legacy features* are available. + + The resulting filename is e.g. ``simple.hpy0-cp38.so``. + + +Moreover, each alternative Python implementation could decide to implement its +own non-universal ABI if it makes sense for them. For example, a hypothetical +project *DummyPython* could decide to ship its own ``hpy.h`` which implements +the HPy API but generates a DLL which targets the DummyPython ABI. + +This means that to compile an extension for CPython, you can choose whether to +target the CPython ABI or the Universal ABI. The advantage of the former is +that it runs at native speed, while the advantage of the latter is that you +can distribute a single binary, although with a small speed penalty on +CPython. Obviously, nothing stops you compiling and distributing both +versions: this is very similar to what most projects are already doing, since +they automatically compile and distribute extensions for many different +CPython versions. + +From the user point of view, extensions compiled for the CPython ABI can be +distributed and installed as usual, while those compiled for the HPy Universal +or HPy Hybrid ABIs require installing the ``hpy.universal`` package on +CPython and have no further requirements on Pythons that support HPy natively. + + +Benefits for the Python ecosystem +--------------------------------- + +The HPy project offers some benefits to the python ecosystem, both to Python +users and to library developers. + + - C extensions can achieve much better speed on alternative implementions, + including PyPy and GraalPy: according to early :ref:`benchmarks`, an + extension written in HPy can be ~3x faster than the equivalent extension + written using ``Python.h``. + - Improved debugging: when you load extensions in :ref:`debug-mode:debug mode`, + many common mistakes are checked and reported automatically. + - Universal binaries: libraries can choose to distribute only Universal ABI + binaries. By doing so, they can support all Python implementations and + version of CPython (like PyPy, GraalPy, CPython 3.10, CPython 3.11, etc) + for which an HPy loader exists, including those that do not yet exist! This + currently comes with a small speed penalty on CPython, but for + non-performance critical libraries it might still be a good tradeoff. + - Python environments: With general availability of universal ABI binaries for + popular packages, users can create equivalent python environments that + target different Python implementations. Thus, Python users can try their + workload against different implementations and pick the one best suited for + their usage. + - In a situation where most or all popular Python extensions target the + universal ABI, it will be more feasible for CPython to make breaking changes + to its C/API for performance or maintainability reasons. + + +Cython extensions +----------------- + +If you use Cython, you can't use HPy directly. There is a +`work in progress `_ to +add Cython backend which emits HPy code instead of using ``Python.h`` code: once this is +done, you will get the benefits of HPy automatically. + + +Extensions in other languages +----------------------------- + +On the API side, HPy is designed with C in mind, so it is not directly useful +if you want to write an extension in a language other than C. + +However, Python bindings for other languages could decide to target the +:term:`HPy Universal ABI` instead of the :term:`CPython ABI`, and generate +extensions which can be loaded seamlessly on all Python implementations which +supports it. This is the route taken, for example, by `Rust +`_. + + +Benefits for alternative Python implementations +----------------------------------------------- + +If you are writing an alternative Python implementation, there is a good +chance that you already know how painful it is to support the ``Python.h`` API. +HPy is designed to be both faster and easier to implement! + +You have two choices: + + - support the Universal ABI: in this case, you just need to export the + needed functions and to add a hook to ``dlopen()`` the desired libraries + + - use a custom ABI: in this case, you have to write your own replacement for + ``hpy.h`` and recompile the C extensions with it. + + +Current status and roadmap +-------------------------- + +HPy left the early stages of development and already provides a noticeable set +of features. As on April 2023, the following milestones have been reached: + + - some prominent real-world Python packages have been ported to HPy API. There + is a list of HPy-compatible packages we know about on the HPy website + `hpyproject.org `_. + + - one can write extensions which expose module-level functions, with all + the various kinds of calling conventions. + + - there is support for argument parsing (i.e., the equivalents of + ``PyArg_ParseTuple`` and ``PyArg_ParseTupleAndKeywords``), and a + convenient complex value building (i.e., the equivalent ``Py_BuildValue``). + + - one can implement custom types, whose struct may contain references to other + Python objects using ``HPyField``. + + - there is a support for globally accessible Python object handles: ``HPyGlobal``, + which can still provide isolation for subinterpreters if needed. + + - there is support for raising and catching exceptions. + + - debug mode has been implemented and can be activated at run-time without + recompiling. It can detect leaked handles or handles used after + being closed. + + - trace mode has been implemented and can be activated just like the debug + mode. It helps analyzing the API usage (in particular wrt. performance). + + - wheels can be built for HPy extensions with ``python setup.py bdist_wheel`` + and can be installed with ``pip install``. + + - it is possible to choose between the :term:`CPython ABI` and the + :term:`HPy Universal ABI` when compiling an extension module. + + - extensions compiled with the CPython ABI work out of the box on + CPython. + + - it is possible to load HPy Universal extensions on CPython, thanks to the + ``hpy.universal`` package. + + - it is possible to load HPy Universal extensions on + PyPy (using the PyPy `hpy branch `_). + + - it is possible to load HPy Universal extensions on `GraalPy + `_. + + - there is support for multi-phase module initialization. + + - support for metaclasses has been added. + + +However, there is still a long road before HPy is usable for the general +public. In particular, the following features are on our roadmap but have not +been implemented yet: + + - many of the original ``Python.h`` functions have not been ported to + HPy yet. Porting most of them is straightforward, so for now the priority + is to test HPy with real-world Python packages and primarily resolve the + "hard" features to prove that the HPy approach works. + + - add C-level module state to complement the ``HPyGlobal`` approach. While ``HPyGlobal`` + is easier to use, it will make the migration simpler for existing extensions that + use CPython module state. + + - the integration with Cython is work in progress + + - it is not clear yet how to approach pybind11 and similar C++ bindings. They serve two use-cases: + + - As C++ wrappers for CPython API. HPy is fundamentally different in some ways, so fully compatible + pybind11 port of this API to HPy does not make sense. There can be a similar or even partially pybind11 + compatible C++ wrapper for HPy adhering to the HPy semantics and conventions (e.g., passing the + HPyContext pointer argument around, no reference stealing, etc.). + + - Way to expose (or "bind") mostly pure C++ functions as Python functions where the C++ templating + machinery takes care of the conversion between the Python world, i.e., ``PyObject*``, and the C++ + types. Porting this abstraction to HPy is possible and desired in the future. To determine the priority + or such effort, we need to get more knowledge about existing pybind11 use-cases. + + +.. _benchmarks: + +Early benchmarks +----------------- + +To validate our approach, we ported a simple yet performance critical module +to HPy. We chose `ultrajson `_ +because it is simple enough to require porting only a handful of API +functions, but at the same time it is performance critical and performs many +API calls during the parsing of a JSON file. + +This `blog post `_ +explains the results in more detail, but they can be summarized as follows: + + - ``ujson-hpy`` compiled with the CPython ABI is as fast as the original + ``ujson``. + + - A bit surprisingly, ``ujson-hpy`` compiled with the HPy Universal ABI is + only 10% slower on CPython. We need more evidence than a single benchmark + of course, but if the overhead of the HPy Universal ABI is only 10% on + CPython, many projects may find it small enough that the benefits + of distributing extensions using only the HPy Universal ABI out weight + the performance costs. + + - On PyPy, ``ujson-hpy`` runs 3x faster than the original ``ujson``. Note + the HPy implementation on PyPy is not fully optimized yet, so we expect + even bigger speedups eventually. + + +Projects involved +----------------- + +HPy was born during EuroPython 2019, were a small group of people started to +discuss the problems of the ``Python.h`` API and how it would be nice to +have a way to fix them. Since then, it has gathered the attention and interest +of people who are involved in many projects within the Python ecosystem. The +following is a (probably incomplete) list of projects whose core developers +are involved in HPy, in one way or the other. The mere presence in this list +does not mean that the project as a whole endorse or recognize HPy in any way, +just that some of the people involved contributed to the +code/design/discussions of HPy: + + - PyPy + + - CPython + + - Cython + + - GraalPy + + - RustPython + + - rust-hpy (fork of the `cpython crate `_) + + +Related work +------------- + +A partial list of alternative implementations which offer a ``Python.h`` +compatibility layer include: + + - `PyPy `_ + + - `Jython `_ + + - `IronPython `_ + + - `GraalPy `_ + +.. rubric:: Footnotes + +.. [#f1] The reason for this minor performance penalty is a layer of pointer + indirection. For instance, ``ctx->HPyLong_FromLong`` is called from the + CPython extension, which in universal mode simply forwards the call to + ``PyLong_FromLong``. It is technically possible to implement a CPython + universal module loader which edits the program's executable code at runtime + to replace that call. Note that this is not at all trivial. diff --git a/graalpython/hpy/docs/porting-example/index.rst b/graalpython/hpy/docs/porting-example/index.rst new file mode 100644 index 0000000000..e5a6dcd7b8 --- /dev/null +++ b/graalpython/hpy/docs/porting-example/index.rst @@ -0,0 +1,356 @@ +Porting Example +=============== + +HPy supports *incrementally* porting an existing C extension from the +original Python C API to the HPy API and to have the extension compile and +run at each step along the way. + +Here we walk through porting a small C extension that implements a Point type +with some simple methods (a norm and a dot product). The Point type is minimal, +but does contain additional C attributes (the x and y values of the point) +and an attribute (obj) that contains a Python object (that we will need to +convert from a ``PyObject *`` to an ``HPyField``). + +There is a separate C file illustrating each step of the incremental port: + +* :doc:`steps/step_00_c_api`: The original C API version that we are going to + port. + +* :doc:`steps/step_01_hpy_legacy`: A possible first step where all methods still + receive ``PyObject *`` arguments and may still cast them to ``PyPointObject *`` + if they are instances of Point. + +* :doc:`steps/step_02_hpy_legacy`: Shows how to transition some methods to HPy + methods that receive ``HPy`` handles as arguments while still supporting legacy + methods that receive ``PyObject *`` arguments. + +* :doc:`steps/step_03_hpy_final`: The completed port to HPy where all methods + receive ``HPy`` handles and ``PyObject_HEAD`` has been removed. + +Take a moment to read through :doc:`steps/step_00_c_api`. Then, once you're +ready, keep reading. + +Each section below corresponds to one of the three porting steps above: + +.. contents:: + :local: + :depth: 2 + +.. note:: + The steps used here are one approach to porting a module. The specific + steps are not required. They're just an example approach. + + +Step 01: Converting the module to a (legacy) HPy module +------------------------------------------------------- + +First for the easy bit -- let's include ``hpy.h``: + +.. literalinclude:: steps/step_01_hpy_legacy.c + :lineno-match: + :start-at: #include + :end-at: #include + +We'd like to differentiate between references to ``PyPointObject`` that have +been ported to HPy and those that haven't, so let's rename it to ``PointObject`` +and alias ``PyPointObject`` to ``PointObject``. We'll keep ``PyPointObject`` for +the instances that haven't been ported yet (the legacy ones) and use +``PointObject`` where we have ported the references: + +.. literalinclude:: steps/step_01_hpy_legacy.c + :lineno-match: + :start-at: typedef struct { + :end-at: } PointObject; + +.. literalinclude:: steps/step_01_hpy_legacy.c + :lineno-match: + :start-at: typedef PointObject PyPointObject; + :end-at: typedef PointObject PyPointObject; + +For this step, all references will be to ``PyPointObject`` -- we'll only start +porting references in the next step. + +Let's also call ``HPyType_LEGACY_HELPERS`` to define some helper functions +for use with the ``PointObject`` struct: + +.. literalinclude:: steps/step_01_hpy_legacy.c + :lineno-match: + :start-at: HPyType_LEGACY_HELPERS(PointObject) + :end-at: HPyType_LEGACY_HELPERS(PointObject) + +Again, we won't use these helpers in this step -- we're just setting things +up for later. + +Now for the big steps. + +We need to replace ``PyType_Spec`` for the ``Point`` type with the equivalent +``HPyType_Spec``: + +.. literalinclude:: steps/step_01_hpy_legacy.c + :lineno-match: + :start-at: // HPy type methods and slots (no methods or slots have been ported yet) + :end-before: // Legacy module methods (the "dot" method is still a PyCFunction) + +Initially the list of ported methods in ``point_defines`` is empty and all of +the methods are still in ``Point_slots`` which we have renamed to +``Point_legacy_slots`` for clarity. + +``SHAPE(PointObject)`` is a macro that retrieves the shape of ``PointObject`` as it +was defined by the ``HPyType_LEGACY_HELPERS`` macro and will be set to +``HPyType_BuiltinShape_Legacy`` until we replace the legacy macro with the +``HPyType_HELPERS`` one. Any type with ``legacy_slots`` or that still includes +``PyObject_HEAD`` in its struct should have ``.builtin_shape`` set to +``HPyType_BuiltinShape_Legacy``. + +Similarly we replace ``PyModuleDef`` with ``HPyModuleDef``: + +.. literalinclude:: steps/step_01_hpy_legacy.c + :lineno-match: + :start-at: // Legacy module methods (the "dot" method is still a PyCFunction) + :end-before: // END-OF: HPyModuleDef + +Like the type, the list of ported methods in ``module_defines`` is initially +almost empty: all the regular methods are still in ``PointModuleMethods`` which has +been renamed to ``PointModuleLegacyMethods``. However, because HPy supports only +multiphase module initialization, we must convert our module initialization code +to an "exec" slot on the module and add that slot to ``module_defines``. + +Now all that is left is to replace the module initialization function with +one that uses ``HPy_MODINIT``. The first argument is the name of the extension, +i.e., what was ``XXX`` in ``PyInit_XXX``, and the second argument +is the ``HPyModuleDef``. + +.. literalinclude:: steps/step_01_hpy_legacy.c + :lineno-match: + :start-at: HPy_MODINIT(step_01_hpy_legacy, moduledef) + +And we're done! + +Instead of the ``PyInit_XXX``, we now have an "exec" slot on the module. +We implement it with a C function that that takes an ``HPyContext *ctx`` and ``HPy mod`` +as arguments. The ``ctx`` must be forwarded as the first argument to calls to +HPy API methods. The ``mod`` argument is a handle for the module object. The runtime +creates the module for us from the provided ``HPyModuleDef``. There is no need to +call API like ``PyModule_Create`` explicitly. + +Next step is to replace ``PyType_FromSpec`` by ``HPyType_FromSpec``. + +``HPy_SetAttr_s`` is used to add the ``Point`` class to the module. HPy requires no +special ``PyModule_AddObject`` method. + +.. literalinclude:: steps/step_01_hpy_legacy.c + :lineno-match: + :start-at: HPyDef_SLOT(module_exec, HPy_mod_exec) + :end-at: } + + +Step 02: Transition some methods to HPy +--------------------------------------- + +In the previous step we put in place the type and module definitions required +to create an HPy extension module. In this step we will port some individual +methods. + +Let us start by migrating ``Point_traverse``. First we need to change +``PyObject *obj`` in the ``PointObject`` struct to ``HPyField obj``: + +.. literalinclude:: steps/step_02_hpy_legacy.c + :lineno-match: + :start-at: typedef struct { + :end-at: } PointObject; + +``HPy`` handles can only be short-lived -- i.e. local variables, arguments to +functions or return values. ``HPyField`` is the way to store long-lived +references to Python objects. For more information, please refer to the +documentation of :ref:`api-reference/hpy-field:HPyField`. + +Now we can update ``Point_traverse``: + +.. literalinclude:: steps/step_02_hpy_legacy.c + :lineno-match: + :start-at: HPyDef_SLOT(Point_traverse, HPy_tp_traverse) + :end-before: // this is a method for creating a Point + +In the first line we used the ``HPyDef_SLOT`` macro to define a small structure +that describes the slot being implemented. The first argument, ``Point_traverse``, +is the name to assign the structure to. By convention, the ``HPyDef_SLOT`` macro +expects a function called ``Point_traverse_impl`` implementing the slot. The +second argument, ``HPy_tp_traverse``, specifies the kind of slot. + +This is a change from how slots are defined in the old C API. In the old API, +the kind of slot is only specified much lower down in ``Point_legacy_slots``. In +HPy the implementation and kind are defined in one place using a syntax +reminiscent of Python decorators. + +The implementation of traverse is now a bit simpler than in the old C API. +We no longer need to visit ``Py_TYPE(self)`` and need only ``HPy_VISIT`` +``self->obj``. HPy ensures that interpreter knows that the type of the instance +is still referenced. + +Only struct members of type ``HPyField`` can be visited with ``HPy_VISIT``, which +is why we needed to convert ``obj`` to an ``HPyField`` before we implemented the +HPy traverse. + +Next we must update ``Point_init`` to store the value of ``obj`` as an ``HPyField``: + +.. literalinclude:: steps/step_02_hpy_legacy.c + :lineno-match: + :start-at: HPyDef_SLOT(Point_init, HPy_tp_init) + :end-before: // this is the getter for the associated object + +There are a few new HPy constructs used here: + +- The kind of the slot passed to ``HPyDef_SLOT`` is ``HPy_tp_init``. + +- ``PointObject_AsStruct`` is defined by ``HPyType_LEGACY_HELPERS`` and returns + an instance of the ``PointObject`` struct. Because we still include + ``PyObject_HEAD`` at the start of the struct this is still a valid ``PyObject *`` + but once we finish the port the struct will no longer contain ``PyObject_HEAD`` + and this will just be an ordinary C struct with no memory overhead! + +- We use ``HPyTracker`` when parsing the arguments with ``HPyArg_ParseKeywords``. + The ``HPyTracker`` keeps track of open handles so that they can be closed + easily at the end with ``HPyTracker_Close``. + +- ``HPyArg_ParseKeywords`` is the equivalent of ``PyArg_ParseTupleAndKeywords``. + Note that the HPy version does not steal a reference like the Python + version. + +- ``HPyField_Store`` is used to store a reference to ``obj`` in the struct. The + arguments are the context (``ctx``), a handle to the object that owns the + reference (``self``), the address of the ``HPyField`` (``&p->obj``), and the + handle to the object (``obj``). + +.. note:: + + An ``HPyTracker`` is not strictly needed for ``HPyArg_ParseKeywords`` + in ``Point_init``. The arguments ``x`` and ``y`` are C floats (so there are no + handles to close) and the handle stored in ``obj`` was passed in to the + ``Point_init`` as an argument and so should not be closed. + + We showed the tracker here to demonstrate its use. You can read more + about argument parsing in the + :doc:`API docs `. + + If a tracker is needed and one is not provided, ``HPyArg_ParseKeywords`` + will return an error. + + +The last update we need to make for the change to ``HPyField`` is to migrate +``Point_obj_get`` which retrieves ``obj`` from the stored ``HPyField``: + +.. literalinclude:: steps/step_02_hpy_legacy.c + :lineno-match: + :start-at: HPyDef_GET(Point_obj, "obj", .doc="Associated object.") + :end-before: // an HPy method of Point + +Above we have used ``PointObject_AsStruct`` again, and then ``HPyField_Load`` to +retrieve the value of ``obj`` from the ``HPyField``. + +We've now finished all of the changes needed by introducing ``HPyField``. We +could stop here, but let's migrate one ordinary method, ``Point_norm``, to end +off this stage of the port: + +.. literalinclude:: steps/step_02_hpy_legacy.c + :lineno-match: + :start-at: HPyDef_METH(Point_norm, "norm", HPyFunc_NOARGS, .doc="Distance from origin.") + :end-before: // this is an LEGACY function which casts a PyObject* into a PyPointObject* + +To define a method we use ``HPyDef_METH`` instead of ``HPyDef_SLOT``. ``HPyDef_METH`` +creates a small structure defining the method. The first argument is the name +to assign to the structure (``Point_norm``). The second is the Python name of +the method (``norm``). The third specifies the method signature (``HPyFunc_NOARGS`` +-- i.e. no additional arguments in this case). The last provides the docstring. +The macro then expects a function named ``Point_norm_impl`` implementing the +method. + +The rest of the implementation remains similar, except that we use +``HPyFloat_FromDouble`` to create a handle to a Python float containing the +result (i.e. the distance of the point from the origin). + +Now we are done and just have to remove the old implementations from +``Point_legacy_slots`` and add them to ``point_defines``: + +.. literalinclude:: steps/step_02_hpy_legacy.c + :lineno-match: + :start-at: static HPyDef *point_defines[] = { + :end-before: static HPyType_Spec Point_Type_spec = { + + +Step 03: Complete the port to HPy +--------------------------------- + +In this step we'll complete the port. We'll no longer include Python, remove +``PyObject_HEAD`` from the ``PointObject`` struct, and port the remaining methods. + +First, let's remove the import of ``Python.h``: + +.. literalinclude:: steps/step_03_hpy_final.c + :lineno-match: + :start-at: // #include // disallow use of the old C API + :end-at: // #include // disallow use of the old C API + +And ``PyObject_HEAD`` from the struct: + +.. literalinclude:: steps/step_03_hpy_final.c + :lineno-match: + :start-at: typedef struct { + :end-at: } PointObject; + +And the typedef of ``PointObject`` to ``PyPointObject``: + +.. literalinclude:: steps/step_03_hpy_final.c + :lineno-match: + :start-at: // typedef PointObject PyPointObject; + :end-at: // typedef PointObject PyPointObject; + +Now any code that has not been ported should result in a compilation error. + +We must also change the type helpers from ``HPyType_LEGACY_HELPERS`` to +``HPyType_HELPERS`` so that ``PointObject_AsStruct`` knows that ``PyObject_HEAD`` +has been removed: + +.. literalinclude:: steps/step_03_hpy_final.c + :lineno-match: + :start-at: HPyType_HELPERS(PointObject) + :end-at: HPyType_HELPERS(PointObject) + +There is one more method to port, the ``dot`` method which is a module method +that implements the dot product between two points: + +.. literalinclude:: steps/step_03_hpy_final.c + :lineno-match: + :start-at: HPyDef_METH(dot, "dot", HPyFunc_VARARGS, .doc="Dot product.") + :end-before: // Method, type and module definitions. In this porting step all + +The changes are similar to those used in porting the ``norm`` method, except: + +- We use ``HPyArg_Parse`` instead of ``HPyArg_ParseKeywordsDict``. + +- We opted not to use an ``HPyTracker`` by passing ``NULL`` as the pointer to the + tracker when calling ``HPyArg_Parse``. There is no reason not to use a + tracker here, but the handles to the two points are passed in as arguments + to ``dot_impl`` and thus there is no need to close them (and they should not + be closed). + +We use ``PointObject_AsStruct`` and ``HPyFloat_FromDouble`` as before. + +Now that we have ported everything we can remove ``PointMethods``, +``Point_legacy_slots`` and ``PointModuleLegacyMethods``. The resulting +type definition is much cleaner: + +.. literalinclude:: steps/step_03_hpy_final.c + :lineno-match: + :start-at: static HPyDef *point_defines[] = { + :end-before: // HPy module methods + +and the module definition is simpler too: + +.. literalinclude:: steps/step_03_hpy_final.c + :lineno-match: + :start-at: static HPyDef *module_defines[] = { + :end-before: HPy_MODINIT(step_03_hpy_final, moduledef) + +Now that the port is complete, when we compile our extension in HPy +universal mode, we obtain a built extension that depends only on the HPy ABI +and not on the CPython ABI at all! diff --git a/graalpython/hpy/docs/porting-example/steps/.gitignore b/graalpython/hpy/docs/porting-example/steps/.gitignore new file mode 100644 index 0000000000..36733d4937 --- /dev/null +++ b/graalpython/hpy/docs/porting-example/steps/.gitignore @@ -0,0 +1 @@ +step_03_hpy_final.py diff --git a/graalpython/hpy/docs/porting-example/steps/conftest.py b/graalpython/hpy/docs/porting-example/steps/conftest.py new file mode 100644 index 0000000000..06b7c319ee --- /dev/null +++ b/graalpython/hpy/docs/porting-example/steps/conftest.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- + +""" Pytest configuration for the porting example tests. """ + +import glob +import os +import sys + +import pytest + + +sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + + +class PortingStep: + def __init__(self, src): + self.name = os.path.splitext(os.path.basename(src))[0] + self.src = src + + def import_step(self): + return __import__(self.name) + + +PORTING_STEPS = [ + PortingStep(src) for src in sorted( + glob.glob(os.path.join(os.path.dirname(__file__), "step_*.c"))) +] + + +@pytest.fixture( + params=PORTING_STEPS, + ids=[step.name for step in PORTING_STEPS], +) +def step(request): + return request.param diff --git a/graalpython/hpy/docs/porting-example/steps/setup00.py b/graalpython/hpy/docs/porting-example/steps/setup00.py new file mode 100644 index 0000000000..b3ea47b7aa --- /dev/null +++ b/graalpython/hpy/docs/porting-example/steps/setup00.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +from setuptools import setup, Extension + + +setup( + name="hpy-porting-example", + ext_modules=[ + Extension("step_00_c_api", sources=["step_00_c_api.c"]) + ], + py_modules=["step_00_c_api"], +) diff --git a/graalpython/hpy/docs/porting-example/steps/setup01.py b/graalpython/hpy/docs/porting-example/steps/setup01.py new file mode 100644 index 0000000000..33803453a7 --- /dev/null +++ b/graalpython/hpy/docs/porting-example/steps/setup01.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + +from setuptools import setup, Extension + + +setup( + name="hpy-porting-example", + hpy_ext_modules=[ + Extension("step_01_hpy_legacy", sources=["step_01_hpy_legacy.c"]) + ], + py_modules=["step_01_hpy_legacy"], + setup_requires=['hpy'], +) diff --git a/graalpython/hpy/docs/porting-example/steps/setup02.py b/graalpython/hpy/docs/porting-example/steps/setup02.py new file mode 100644 index 0000000000..6ab9b95e73 --- /dev/null +++ b/graalpython/hpy/docs/porting-example/steps/setup02.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + +from setuptools import setup, Extension + + +setup( + name="hpy-porting-example", + hpy_ext_modules=[ + Extension("step_02_hpy_legacy", sources=["step_02_hpy_legacy.c"]) + ], + py_modules=["step_02_hpy_legacy"], + setup_requires=['hpy'], +) diff --git a/graalpython/hpy/docs/porting-example/steps/setup03.py b/graalpython/hpy/docs/porting-example/steps/setup03.py new file mode 100644 index 0000000000..c12ec40020 --- /dev/null +++ b/graalpython/hpy/docs/porting-example/steps/setup03.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- + +from setuptools import setup, Extension + +# now we can add --hpy-abi=universal to the invocation of setup.py to build a +# universal binary +setup( + name="hpy-porting-example", + hpy_ext_modules=[ + Extension("step_03_hpy_final", sources=["step_03_hpy_final.c"]) + ], + py_modules=["step_03_hpy_final"], + setup_requires=['hpy'], +) diff --git a/graalpython/hpy/docs/porting-example/steps/step_00_c_api.c b/graalpython/hpy/docs/porting-example/steps/step_00_c_api.c new file mode 100644 index 0000000000..0b2742fd4d --- /dev/null +++ b/graalpython/hpy/docs/porting-example/steps/step_00_c_api.c @@ -0,0 +1,165 @@ +#include +#include + +// Porting to HPy, Step 0: Original Python C API version +// +// An example of porting a C extension that implements a Point type +// with a couple of simple methods (a norm and a dot product). It +// illustrates the steps needed to port types that contain additional +// C attributes (in this case, x and y). +// +// This file contains the original C API version that needs to be ported. +// +// HPy supports porting C extensions piece by piece. +// +// point_hpy_legacy_1.c illustrates a possible first step where all +// methods still receive PyObject arguments and may still cast them to +// PyPointObject if they are instances of Point. +// +// point_hpy_legacy_2.c shows how to transition some methods to HPy methods +// that receive HPy handles as arguments while still supporting legacy +// methods that receive PyObject arguments. +// +// point_hpy_final.c shows the completed port to HPy where all methods receive +// HPy handles and PyObject_HEAD has been removed. + +typedef struct { + PyObject_HEAD + double x; + double y; + PyObject *obj; +} PyPointObject; + +int Point_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(((PyPointObject*)self)->obj); + Py_VISIT(Py_TYPE(self)); + return 0; +} + +void Point_dealloc(PyObject *self) +{ + Py_CLEAR(((PyPointObject*)self)->obj); + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free(self); + Py_DECREF(tp); +} + +// this is a method for creating a Point +int Point_init(PyObject *self, PyObject *args, PyObject *kw) +{ + static char *kwlist[] = {"x", "y", "obj", NULL}; + PyPointObject *p = (PyPointObject *)self; + p->x = 0.0; + p->y = 0.0; + p->obj = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kw, "|ddO", kwlist, + &p->x, &p->y, &p->obj)) + return -1; + if (p->obj == NULL) + p->obj = Py_None; + Py_INCREF(p->obj); + return 0; +} + +// this is a method of Point +PyObject* Point_norm(PyObject *self) +{ + PyPointObject *p = (PyPointObject *)self; + double norm; + PyObject *result; + norm = sqrt(p->x * p->x + p->y * p->y); + result = PyFloat_FromDouble(norm); + return result; +} + +// this is the getter for the associated object +PyObject* Point_obj_get(PyObject *self, void *context) +{ + PyPointObject *p = (PyPointObject *)self; + Py_INCREF(p->obj); + return p->obj; +} + +// this is an unrelated function which happens to cast a PyObject* into a +// PyPointObject* +PyObject* dot(PyObject *self, PyObject *args) +{ + PyObject *point1, *point2; + if (!PyArg_ParseTuple(args, "OO", &point1, &point2)) + return NULL; + + PyPointObject *p1 = (PyPointObject *)point1; + PyPointObject *p2 = (PyPointObject *)point2; + + double dp; + PyObject *result; + dp = p1->x * p2->x + p1->y * p2->y; + result = PyFloat_FromDouble(dp); + return result; +} + + +// Method, type and module definitions. These will be updated to add HPy +// module support in point_hpy_legacy_1.c. + +static PyMethodDef PointMethods[] = { + {"norm", (PyCFunction)Point_norm, METH_NOARGS, "Distance from origin."}, + {NULL, NULL, 0, NULL} +}; + +static PyGetSetDef PointGetSets[] = { + {"obj", (getter)Point_obj_get, NULL, "Associated object.", NULL}, + {NULL, NULL, 0, NULL} +}; + +static PyType_Slot Point_slots[] = { + {Py_tp_doc, "Point (Step 0; C API implementation)"}, + {Py_tp_init, Point_init}, + {Py_tp_methods, PointMethods}, + {Py_tp_getset, PointGetSets}, + {Py_tp_traverse, Point_traverse}, + {Py_tp_dealloc, Point_dealloc}, + {0, 0} +}; + +static PyType_Spec Point_Type_spec = { + .name = "point_capi.Point", + .basicsize = sizeof(PyPointObject), + .itemsize = 0, + .flags = Py_TPFLAGS_DEFAULT, + .slots = Point_slots +}; + +static PyMethodDef PointModuleMethods[] = { + {"dot", (PyCFunction)dot, METH_VARARGS, "Dot product."}, + {NULL, NULL, 0, NULL} +}; + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "step_00_c_api", + "Point module (Step 0; C API implementation)", + -1, + PointModuleMethods, + NULL, + NULL, + NULL, + NULL, +}; + +PyMODINIT_FUNC +PyInit_step_00_c_api(void) +{ + PyObject* m; + m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; + + PyObject *point_type = PyType_FromSpec(&Point_Type_spec); + if (point_type == NULL) + return NULL; + PyModule_AddObject(m, "Point", point_type); + + return m; +} diff --git a/graalpython/hpy/docs/porting-example/steps/step_00_c_api.rst b/graalpython/hpy/docs/porting-example/steps/step_00_c_api.rst new file mode 100644 index 0000000000..c9e9b76c18 --- /dev/null +++ b/graalpython/hpy/docs/porting-example/steps/step_00_c_api.rst @@ -0,0 +1,8 @@ +:orphan: + +step_00_c_api.c +=============== + +.. literalinclude:: ./step_00_c_api.c + :language: c + :linenos: diff --git a/graalpython/hpy/docs/porting-example/steps/step_01_hpy_legacy.c b/graalpython/hpy/docs/porting-example/steps/step_01_hpy_legacy.c new file mode 100644 index 0000000000..48137cc589 --- /dev/null +++ b/graalpython/hpy/docs/porting-example/steps/step_01_hpy_legacy.c @@ -0,0 +1,189 @@ +#include +#include +#include + +// Porting to HPy, Step 1: All legacy methods +// +// An example of porting a C extension that implements a Point type +// with a couple of simple methods (a norm and a dot product). It +// illustrates the steps needed to port types that contain additional +// C attributes (in this case, x and y). +// +// This file contains an example first step of the port in which all methods +// still receive PyObject arguments and may still cast them to +// PyPointObject if they are instances of Point. + +typedef struct { + // PyObject_HEAD is required while legacy_slots are still used + // but can (and should) be removed once the port to HPy is completed. + PyObject_HEAD + double x; + double y; + PyObject *obj; +} PointObject; + +// This defines PyPointObject as an alias of PointObject so that existing +// code that still uses PyPointObject and expects PyObject_HEAD continues to +// compile and run. Once PyObject_HEAD has been removed, this alias should be +// removed so that code that still expects PyObject_HEAD will fail to compile. +typedef PointObject PyPointObject; + +// The legacy type helper macro defines an PointObject_AsStruct function allows +// non-legacy methods to convert HPy handles to PointObject structs. It is not +// used in this file, but is provided so that methods can start to be ported +// (see point_hpy_legacy_2.c). The legacy type helper macro is used because +// PyObject_HEAD is still present in PointObject. Once PyObject_HEAD has been +// removed (see point_hpy_final.c) we will use HPy_TYPE_HELPERS instead. +HPyType_LEGACY_HELPERS(PointObject) + +int Point_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(((PyPointObject*)self)->obj); + Py_VISIT(Py_TYPE(self)); + return 0; +} + +void Point_dealloc(PyObject *self) +{ + Py_CLEAR(((PyPointObject*)self)->obj); + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free(self); + Py_DECREF(tp); +} + +// this is a method for creating a Point +int Point_init(PyObject *self, PyObject *args, PyObject *kw) +{ + static char *kwlist[] = {"x", "y", "obj", NULL}; + PyPointObject *p = (PyPointObject *)self; + p->x = 0.0; + p->y = 0.0; + p->obj = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kw, "|ddO", kwlist, + &p->x, &p->y, &p->obj)) + return -1; + if (p->obj == NULL) + p->obj = Py_None; + Py_INCREF(p->obj); + return 0; +} + +// this is a LEGACY method of Point +PyObject* Point_norm(PyObject *self) +{ + PyPointObject *p = (PyPointObject *)self; + double norm; + norm = sqrt(p->x * p->x + p->y * p->y); + return PyFloat_FromDouble(norm); +} + +// this is the getter for the associated object +PyObject* Point_obj_get(PyObject *self, void *context) +{ + PyPointObject *p = (PyPointObject *)self; + Py_INCREF(p->obj); + return p->obj; +} + +// this is an LEGACY function which casts a PyObject* into a PyPointObject* +PyObject* dot(PyObject *self, PyObject *args) +{ + PyObject *point1, *point2; + if (!PyArg_ParseTuple(args, "OO", &point1, &point2)) + return NULL; + + PyPointObject *p1 = (PyPointObject *)point1; + PyPointObject *p2 = (PyPointObject *)point2; + + double dp; + dp = p1->x * p2->x + p1->y * p2->y; + return PyFloat_FromDouble(dp); +} + + +// Method, type and module definitions. In this porting step, the module and +// type definitions have been ported to HPy, but the methods themselves +// remaining legacy methods. + +// Legacy methods (all methods are still legacy methods) +static PyMethodDef PointMethods[] = { + {"norm", (PyCFunction)Point_norm, METH_NOARGS, "Distance from origin."}, + {NULL, NULL, 0, NULL} +}; + +// Legacy getsets +static PyGetSetDef PointGetSets[] = { + {"obj", (getter)Point_obj_get, NULL, "Associated object.", NULL}, + {NULL, NULL, 0, NULL} +}; + +// Legacy slots (all slots are still legacy slots) +static PyType_Slot Point_legacy_slots[] = { + {Py_tp_doc, "Point (Step 1; All legacy methods)"}, + {Py_tp_init, Point_init}, + {Py_tp_methods, PointMethods}, + {Py_tp_getset, PointGetSets}, + {Py_tp_traverse, Point_traverse}, + {Py_tp_dealloc, Point_dealloc}, + {0, 0} +}; + +// HPy type methods and slots (no methods or slots have been ported yet) +static HPyDef *point_defines[] = { + NULL +}; + +static HPyType_Spec Point_Type_spec = { + .name = "point_hpy_legacy_1.Point", + .basicsize = sizeof(PointObject), + .itemsize = 0, + .flags = HPy_TPFLAGS_DEFAULT, + .builtin_shape = SHAPE(PointObject), + .legacy_slots = Point_legacy_slots, + .defines = point_defines, +}; + +// HPy supports only multiphase module initialization, so we must migrate the +// single phase initialization by extracting the code that populates the module +// object with attributes into a separate 'exec' slot. The module is not +// created manually by calling API like PyModule_Create, but the runtime creates +// the module for us from the specification in HPyModuleDef, and we can provide +// additional slots to populate the module before its initialization is finalized +HPyDef_SLOT(module_exec, HPy_mod_exec) +static int module_exec_impl(HPyContext *ctx, HPy mod) +{ + HPy point_type = HPyType_FromSpec(ctx, &Point_Type_spec, NULL); + if (HPy_IsNull(point_type)) + return -1; + HPy_SetAttr_s(ctx, mod, "Point", point_type); + return 0; +} + +// Legacy module methods (the "dot" method is still a PyCFunction) +static PyMethodDef PointModuleLegacyMethods[] = { + {"dot", (PyCFunction)dot, METH_VARARGS, "Dot product."}, + {NULL, NULL, 0, NULL} +}; + +// HPy module methods: no regular methods have been ported yet, +// but we add the module execute slot +static HPyDef *module_defines[] = { + &module_exec, + NULL +}; + +static HPyModuleDef moduledef = { + // .name = "step_01_hpy_legacy", + // ^-- .name is not needed for multiphase module initialization, + // it is always taken from the ModuleSpec + .doc = "Point module (Step 1; All legacy methods)", + .size = 0, + .legacy_methods = PointModuleLegacyMethods, + .defines = module_defines, +}; +// END-OF: HPyModuleDef + +// HPy_MODINIT takes the extension name, i.e., what would be XXX in PyInit_XXX, +// and the module definition. The module will be created by the runtime and +// passed to the HPy_mod_exec slots if any are defined +HPy_MODINIT(step_01_hpy_legacy, moduledef) diff --git a/graalpython/hpy/docs/porting-example/steps/step_01_hpy_legacy.rst b/graalpython/hpy/docs/porting-example/steps/step_01_hpy_legacy.rst new file mode 100644 index 0000000000..7ba453ac10 --- /dev/null +++ b/graalpython/hpy/docs/porting-example/steps/step_01_hpy_legacy.rst @@ -0,0 +1,8 @@ +:orphan: + +step_01_hpy_legacy.c +==================== + +.. literalinclude:: ./step_01_hpy_legacy.c + :language: c + :linenos: diff --git a/graalpython/hpy/docs/porting-example/steps/step_02_hpy_legacy.c b/graalpython/hpy/docs/porting-example/steps/step_02_hpy_legacy.c new file mode 100644 index 0000000000..0d4ff7b04b --- /dev/null +++ b/graalpython/hpy/docs/porting-example/steps/step_02_hpy_legacy.c @@ -0,0 +1,169 @@ +#include +#include +#include + +// Porting to HPy, Step 2: Porting some methods +// +// An example of porting a C extension that implements a Point type +// with a couple of simple methods (a norm and a dot product). It +// illustrates the steps needed to port types that contain additional +// C attributes (in this case, x and y). +// +// This file contains an example second step of the port in which some methods +// have been converted to HPy methods that receive handles as arguments, but +// other methods are still legacy methods that receive PyObject arguments. + +typedef struct { + // PyObject_HEAD is required while legacy methods still access + // PointObject and should be removed once the port to HPy is completed. + PyObject_HEAD + double x; + double y; + // HPy handles are shortlived to support all GC strategies + // For that reason, PyObject* in C structs are replaced by HPyField + HPyField obj; +} PointObject; + +// This defines PyPointObject as an alias of PointObject so that existing +// code that still uses PyPointObject and expects PyObject_HEAD continues to +// compile and run. Once PyObject_HEAD has been removed, this alias should be +// removed so that code that still expects PyObject_HEAD will fail to compile. +typedef PointObject PyPointObject; + +// The legacy type helper macro defines an PointObject_AsStruct function allows +// non-legacy methods to convert HPy handles to PointObject structs. The legacy +// type helper macro is used because PyObject_HEAD is still present in +// PointObject. Once PyObject_HEAD has been removed (see point_hpy_final.c) we +// will use HPy_TYPE_HELPERS instead. +HPyType_LEGACY_HELPERS(PointObject) + +HPyDef_SLOT(Point_traverse, HPy_tp_traverse) +int Point_traverse_impl(void *self, HPyFunc_visitproc visit, void *arg) +{ + HPy_VISIT(&((PointObject*)self)->obj); + return 0; +} + +// this is a method for creating a Point +HPyDef_SLOT(Point_init, HPy_tp_init) +int Point_init_impl(HPyContext *ctx, HPy self, const HPy *args, + HPy_ssize_t nargs, HPy kw) +{ + static const char *kwlist[] = {"x", "y", "obj", NULL}; + PointObject *p = PointObject_AsStruct(ctx, self); + p->x = 0.0; + p->y = 0.0; + HPy obj = HPy_NULL; + HPyTracker ht; + if (!HPyArg_ParseKeywordsDict(ctx, &ht, args, nargs, kw, "|ddO", kwlist, + &p->x, &p->y, &obj)) + return -1; + if (HPy_IsNull(obj)) + obj = ctx->h_None; + /* INCREF not needed because HPyArg_ParseKeywordsDict does not steal a + reference */ + HPyField_Store(ctx, self, &p->obj, obj); + HPyTracker_Close(ctx, ht); + return 0; +} + +// this is the getter for the associated object +HPyDef_GET(Point_obj, "obj", .doc="Associated object.") +HPy Point_obj_get(HPyContext *ctx, HPy self, void* closure) +{ + PointObject *p = PointObject_AsStruct(ctx, self); + return HPyField_Load(ctx, self, p->obj); +} + +// an HPy method of Point +HPyDef_METH(Point_norm, "norm", HPyFunc_NOARGS, .doc="Distance from origin.") +HPy Point_norm_impl(HPyContext *ctx, HPy self) +{ + PointObject *p = PointObject_AsStruct(ctx, self); + double norm; + norm = sqrt(p->x * p->x + p->y * p->y); + return HPyFloat_FromDouble(ctx, norm); +} + +// this is an LEGACY function which casts a PyObject* into a PyPointObject* +PyObject* dot(PyObject *self, PyObject *args) +{ + PyObject *point1, *point2; + if (!PyArg_ParseTuple(args, "OO", &point1, &point2)) + return NULL; + + PyPointObject *p1 = (PyPointObject *)point1; + PyPointObject *p2 = (PyPointObject *)point2; + + double dp; + dp = p1->x * p2->x + p1->y * p2->y; + return PyFloat_FromDouble(dp); +} + +// Method, type and module definitions. In this porting step .norm() +// is ported to HPy, but dot(...) remains a legacy methods. +// Point.__init__ and Point.__doc__ are ported from legacy slots to +// HPy type defines. + +// Legacy methods (there are no legacy methods left now) +static PyMethodDef PointMethods[] = { + {NULL, NULL, 0, NULL} +}; + +// Legacy slots (all slots are still legacy slots) +static PyType_Slot Point_legacy_slots[] = { + {Py_tp_doc, "Point (Step 2; Porting some methods)"}, + {Py_tp_methods, PointMethods}, + {0, 0} +}; + +// HPy type methods and slots +static HPyDef *point_defines[] = { + &Point_init, + &Point_norm, + &Point_obj, + &Point_traverse, + NULL +}; + +static HPyType_Spec Point_Type_spec = { + .name = "point_hpy_legacy_2.Point", + .basicsize = sizeof(PointObject), + .itemsize = 0, + .flags = HPy_TPFLAGS_DEFAULT, + .builtin_shape = SHAPE(PointObject), + .legacy_slots = Point_legacy_slots, + .defines = point_defines +}; + +// Legacy module methods (the "dot" method is still a PyCFunction) +static PyMethodDef PointModuleLegacyMethods[] = { + {"dot", (PyCFunction)dot, METH_VARARGS, "Dot product."}, + {NULL, NULL, 0, NULL} +}; + +HPyDef_SLOT(module_exec, HPy_mod_exec) +static int module_exec_impl(HPyContext *ctx, HPy mod) +{ + HPy point_type = HPyType_FromSpec(ctx, &Point_Type_spec, NULL); + if (HPy_IsNull(point_type)) + return -1; + HPy_SetAttr_s(ctx, mod, "Point", point_type); + return 0; +} + +// HPy module methods: no regular methods have been ported yet, +// but we add the module execute slot +static HPyDef *module_defines[] = { + &module_exec, + NULL +}; + +static HPyModuleDef moduledef = { + .doc = "Point module (Step 2; Porting some methods)", + .size = 0, + .legacy_methods = PointModuleLegacyMethods, + .defines = module_defines, +}; + +HPy_MODINIT(step_02_hpy_legacy, moduledef) diff --git a/graalpython/hpy/docs/porting-example/steps/step_02_hpy_legacy.rst b/graalpython/hpy/docs/porting-example/steps/step_02_hpy_legacy.rst new file mode 100644 index 0000000000..5523681465 --- /dev/null +++ b/graalpython/hpy/docs/porting-example/steps/step_02_hpy_legacy.rst @@ -0,0 +1,8 @@ +:orphan: + +step_02_hpy_legacy.c +==================== + +.. literalinclude:: ./step_02_hpy_legacy.c + :language: c + :linenos: diff --git a/graalpython/hpy/docs/porting-example/steps/step_03_hpy_final.c b/graalpython/hpy/docs/porting-example/steps/step_03_hpy_final.c new file mode 100644 index 0000000000..8f49ecf857 --- /dev/null +++ b/graalpython/hpy/docs/porting-example/steps/step_03_hpy_final.c @@ -0,0 +1,153 @@ +#include +// #include // disallow use of the old C API +#include + +// Porting to HPy, Step 3: All methods ported +// +// An example of porting a C extension that implements a Point type +// with a couple of simple methods (a norm and a dot product). It +// illustrates the steps needed to port types that contain additional +// C attributes (in this case, x and y). +// +// This file contains an example final step of the port in which all methods +// have been converted to HPy methods and PyObject_HEAD has been removed. + +typedef struct { + // PyObject_HEAD is no longer available in PointObject. In CPython, + // of course, it still exists but is inaccessible from HPy_AsStruct. In + // other Python implementations (e.g. PyPy) it might no longer exist at + // all. + double x; + double y; + HPyField obj; +} PointObject; + +// Code using PyPointObject relied on PyObject_HEAD and is no longer valid +// (PyObject_HEAD has been removed from the PointObject struct above). The +// typedef below has been deleted to ensure that such code is now generates +// an error during compilation. +// typedef PointObject PyPointObject; + +// The type helper macro defines an PointObject_AsStruct function allows +// converting HPy handles to PointObject structs. We no longer need to use +// the legacy type helper macro because PyObject_HEAD has been removed from +// PointObject. +HPyType_HELPERS(PointObject) + +HPyDef_SLOT(Point_traverse, HPy_tp_traverse) +int Point_traverse_impl(void *self, HPyFunc_visitproc visit, void *arg) +{ + HPy_VISIT(&((PointObject*)self)->obj); + return 0; +} + +// this is a method for creating a Point +HPyDef_SLOT(Point_init, HPy_tp_init) +int Point_init_impl(HPyContext *ctx, HPy self, const HPy *args, + HPy_ssize_t nargs, HPy kw) +{ + static const char *kwlist[] = {"x", "y", "obj", NULL}; + PointObject *p = PointObject_AsStruct(ctx, self); + p->x = 0.0; + p->y = 0.0; + HPy obj = HPy_NULL; + HPyTracker ht; + if (!HPyArg_ParseKeywordsDict(ctx, &ht, args, nargs, kw, "|ddO", kwlist, + &p->x, &p->y, &obj)) + return -1; + if (HPy_IsNull(obj)) + obj = ctx->h_None; + /* INCREF not needed because HPyArg_ParseKeywordsDict does not steal a + reference */ + HPyField_Store(ctx, self, &p->obj, obj); + HPyTracker_Close(ctx, ht); + return 0; +} + +// this is the getter for the associated object +HPyDef_GET(Point_obj, "obj", .doc="Associated object.") +HPy Point_obj_get(HPyContext *ctx, HPy self, void* closure) +{ + PointObject *p = PointObject_AsStruct(ctx, self); + return HPyField_Load(ctx, self, p->obj); +} + +// an HPy method of Point +HPyDef_METH(Point_norm, "norm", HPyFunc_NOARGS, .doc="Distance from origin.") +HPy Point_norm_impl(HPyContext *ctx, HPy self) +{ + PointObject *p = PointObject_AsStruct(ctx, self); + double norm; + norm = sqrt(p->x * p->x + p->y * p->y); + return HPyFloat_FromDouble(ctx, norm); +} + +// this is an HPy function that uses Point +HPyDef_METH(dot, "dot", HPyFunc_VARARGS, .doc="Dot product.") +HPy dot_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) +{ + HPy point1, point2; + if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &point1, &point2)) + return HPy_NULL; + PointObject *p1 = PointObject_AsStruct(ctx, point1); + PointObject *p2 = PointObject_AsStruct(ctx, point2); + double dp; + dp = p1->x * p2->x + p1->y * p2->y; + return HPyFloat_FromDouble(ctx, dp); +} + +// Method, type and module definitions. In this porting step all +// methods and slots have been ported to HPy and all legacy support +// has been removed. + +// Support for legacy methods and slots has been removed. It used to be: +/// +// static PyMethodDef PointMethods[] = { ... } +// static PyType_Slot Point_legacy_slots[] = { ... } +// static PyMethodDef PointModuleLegacyMethods[] = { ... } +// +// and .legacy_slots and .legacy_defines have been removed from HPyType_Spec +// HPyModuleDef respectively. + +// HPy type methods and slots +static HPyDef *point_defines[] = { + &Point_init, + &Point_norm, + &Point_obj, + &Point_traverse, + NULL +}; + +static HPyType_Spec Point_Type_spec = { + .name = "point_hpy_final.Point", + .doc = "Point (Step 03)", + .basicsize = sizeof(PointObject), + .itemsize = 0, + .flags = HPy_TPFLAGS_DEFAULT, + .defines = point_defines +}; + +HPyDef_SLOT(module_exec, HPy_mod_exec) +static int module_exec_impl(HPyContext *ctx, HPy mod) +{ + HPy point_type = HPyType_FromSpec(ctx, &Point_Type_spec, NULL); + if (HPy_IsNull(point_type)) + return -1; + HPy_SetAttr_s(ctx, mod, "Point", point_type); + return 0; +} + +// HPy module methods +static HPyDef *module_defines[] = { + &module_exec, + &dot, + NULL +}; + +static HPyModuleDef moduledef = { + .doc = "Point module (Step 3; Porting complete)", + .size = 0, + .defines = module_defines, +}; + +HPy_MODINIT(step_03_hpy_final, moduledef) diff --git a/graalpython/hpy/docs/porting-example/steps/step_03_hpy_final.rst b/graalpython/hpy/docs/porting-example/steps/step_03_hpy_final.rst new file mode 100644 index 0000000000..3b8f561fc7 --- /dev/null +++ b/graalpython/hpy/docs/porting-example/steps/step_03_hpy_final.rst @@ -0,0 +1,8 @@ +:orphan: + +step_03_hpy_final.c +=================== + +.. literalinclude:: ./step_03_hpy_final.c + :language: c + :linenos: diff --git a/graalpython/hpy/docs/porting-example/steps/test_porting_example.py b/graalpython/hpy/docs/porting-example/steps/test_porting_example.py new file mode 100644 index 0000000000..013b010c03 --- /dev/null +++ b/graalpython/hpy/docs/porting-example/steps/test_porting_example.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- + +""" Porting example tests. """ + +import pytest +import math +import types + + +class TestPorting: + def test_load_module(self, step): + mod = step.import_step() + assert isinstance(mod, types.ModuleType) + assert mod.__name__ == step.name + assert mod.__doc__.startswith("Point module (Step ") + assert type(mod.Point) == type + assert mod.Point.__doc__.startswith("Point (Step ") + assert isinstance(mod.dot, types.BuiltinFunctionType) + assert mod.dot.__doc__ == "Dot product." + + def test_create_point(self, step): + mod = step.import_step() + p = mod.Point(1, 2) + assert type(p) == mod.Point + + def test_norm(self, step): + mod = step.import_step() + assert mod.Point(1, 2).norm() == math.sqrt(5.0) + assert mod.Point(1.5).norm() == 1.5 + + def test_dot(self, step): + mod = step.import_step() + p1 = mod.Point(1, 2) + p2 = mod.Point(3, 2) + assert mod.dot(p1, p2) == 7.0 + + def test_object(self, step): + mod = step.import_step() + p1 = mod.Point(23, 42, ...) + assert p1.obj is ... + p2 = mod.Point(23, 42) + assert p2.obj is None + + def test_leak_checker(self, step): + if "hpy_final" not in step.name: + pytest.skip("Can only check for leaks in universal mode") + mod = step.import_step() + import hpy.debug + hpy.debug.set_handle_stack_trace_limit(10) + with hpy.debug.LeakDetector(): + p1 = mod.Point(1, 2, ...) + p2 = mod.Point(3, 2) + + assert p1.obj is ... + assert p2.obj is None + assert p1.norm() == math.sqrt(5.0) + assert mod.dot(p1, p2) == 7.0 + + del p1 + del p2 diff --git a/graalpython/hpy/docs/porting-guide.rst b/graalpython/hpy/docs/porting-guide.rst new file mode 100644 index 0000000000..c21961366d --- /dev/null +++ b/graalpython/hpy/docs/porting-guide.rst @@ -0,0 +1,569 @@ +Porting Guide +============= + +Porting ``PyObject *`` to HPy API constructs +-------------------------------------------- + +While in CPython one always uses ``PyObject *`` to reference to Python objects, +in HPy there are several types of handles that should be used depending on the +life-time of the handle: ``HPy``, ``HPyField``, and ``HPyGlobal``. + +- ``HPy`` represents short lived handles that live no longer than the duration of + one call from Python to HPy extension function. Rule of thumb: use for local + variables, arguments, and return values. + +- ``HPyField`` represents handles that are Python object struct fields, i.e., + live in native memory attached to some Python object. + +- ``HPyGlobal`` represents handles stored in C global variables. ``HPyGlobal`` + can provide isolation between subinterpreters. + +.. warning:: Never use a local variable of type ``HPyField``, for any reason! If + the GC kicks in, it might become invalid and become a dangling pointer. + +.. warning:: Never store `HPy` handles to a long-lived memory, for example: C + global variables or Python object structs. + +The ``HPy``/``HPyField`` dichotomy might seem arbitrary at first, but it is +needed to allow Python implementations to use a moving GC, such as PyPy. It is +easier to explain and understand the rules by thinking about how a moving GC +interacts with the C code inside an HPy extension. + +It is worth remembering that during the collection phase, a moving GC might +move an existing object to another memory location, and in that case it needs +to update all the places which store a pointer to it. In order to do so, it +needs to *know* where the pointers are. If there is a local C variable which is +unknown to the GC but contains a pointer to a GC-managed object, the variable +will point to invalid memory as soon as the object is moved. + +Back to ``HPy`` vs ``HPyField`` vs ``HPyGlobal``: + + * ``HPy`` handles must be used for all C local variables, function arguments + and function return values. They are supposed to be short-lived and closed + as soon as they are no longer needed. The debug mode will report a + long-lived ``HPy`` as a potential memory leak. + + * In PyPy and GraalPy, ``HPy`` handles are implemented using an + indirection: they are indexes inside a big list of GC-managed objects: this + big list is tracked by the GC, so when an object moves its pointer is + correctly updated. + + * ``HPyField`` is for long-lived references, and the GC must be aware of + their location in memory. In PyPy, an ``HPyField`` is implemented as a + direct pointer to the object, and thus we need a way to inform the GC + where it is in memory, so that it can update its value upon moving: this + job is done by ``tp_traverse``, as explained in the next section. + + * ``HPyGlobal`` is for long-lived references that are supposed to be closed + implicitly when the module is unloaded (once module unloading is actually + implemented). ``HPyGlobal`` provides indirection to isolate subinterpreters. + Implementation wise, ``HPyGlobal`` will usually contain an index to a table + with Python objects stored in the interpreter state. + + * On CPython without subinterpreters support, ``HPy``, ``HPyGlobal``, + and ``HPyField`` are implemented as ``PyObject *``. + + * On CPython with subinterpreters support, ``HPyGlobal`` will be implemented + by an indirection through the interpreter state. Note that thanks to the HPy + design, switching between this and the more efficient implementation without + subinterpreter support will not require rebuilding of the extension (in HPy + universal mode), nor rebuilding of CPython. + +.. note:: If you write a custom type using ``HPyField``, you **MUST** also write + a ``tp_traverse`` slot. Note that this is different than the old ``Python.h`` + API, where you need ``tp_traverse`` only under certain conditions. See the + next section for more details. + +.. note:: The contract of ``tp_traverse`` is that it must visit all members of + type ``HPyField`` contained within given struct, or more precisely *owned* by + given Python object (in the sense of the *owner* argument to + ``HPyField_Store``), and nothing more, nothing less. Some Python + implementations may choose to not call the provided ``tp_traverse`` if they + know how to visit all members of type ``HPyField`` by other means (for + example, when they track them internally already). The debug mode will check + this contract. + +``tp_traverse``, ``tp_clear``, ``Py_TPFLAGS_HAVE_GC`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let's quote the ``Python.h`` documentation about `GC support +`_ + + Python's support for detecting and collecting garbage which involves + circular references requires support from object types which are + “containers” for other objects which may also be containers. Types which do + not store references to other objects, or which only store references to + atomic types (such as numbers or strings), do not need to provide any + explicit support for garbage collection. + +A good rule of thumb is that if your type contains ``PyObject *`` fields, you +need to: + + 1. provide a ``tp_traverse`` slot; + + 2. provide a ``tp_clear`` slot; + + 3. add the ``Py_TPFLAGS_GC`` to the ``tp_flags``. + + +However, if you know that your ``PyObject *`` fields will contain only +"atomic" types, you can avoid these steps. + +In HPy the rules are slightly different: + + 1. if you have a field of type ``HPyField``, you always **MUST** provide a + ``tp_traverse``. This is needed so that a moving GC can track the + relevant areas of memory. However, you **MUST NOT** rely on + ``tp_traverse`` to be called; + + 2. ``tp_clear`` does not exist. On CPython, ``HPy`` automatically generates + one for you, by using ``tp_traverse`` to know which are the fields to + clear. Other implementations are free to ignore it, if it's not needed; + + 3. ``HPy_TPFLAGS_GC`` is still needed, especially on CPython. If you don't + specify it, your type will not be tracked by CPython's GC and thus it + might cause memory leaks if it's part of a reference cycle. However, + other implementations are free to ignore the flag and track the objects + anyway, if their GC implementation allows it. + +``tp_dealloc`` and ``Py_DECREF`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Generally speaking, if you have one or more ``PyObject *`` fields in the old +``Python.h``, you must provide a ``tp_dealloc`` slot where you ``Py_DECREF`` all +of them. In HPy this is not needed and will be handled automatically by the +system. + +In particular, when running on top of CPython, HPy will automatically provide +a ``tp_dealloc`` which decrefs all the fields listed by ``tp_traverse``. + +See also, :ref:`dealloc`. + + +Direct C API to HPy mappings +---------------------------- + +In many cases, migrating to HPy is as easy as just replacing a certain C API +function by the appropriate HPy API function. Table :ref:`table-mapping` gives a +mapping between C API and HPy API functions. This mapping is generated together +with the code for the :term:`CPython ABI` mode, so it is guaranteed to be correct. + + +.. mark: BEGIN API MAPPING +.. _table-mapping: +.. table:: Safe API function mapping + :widths: auto + + ================================================================================================================================== ================================================ + C API function HPY API function + ================================================================================================================================== ================================================ + `PyBool_FromLong `_ :c:func:`HPyBool_FromLong` + `PyBytes_AS_STRING `_ :c:func:`HPyBytes_AS_STRING` + `PyBytes_AsString `_ :c:func:`HPyBytes_AsString` + `PyBytes_Check `_ :c:func:`HPyBytes_Check` + `PyBytes_FromString `_ :c:func:`HPyBytes_FromString` + `PyBytes_GET_SIZE `_ :c:func:`HPyBytes_GET_SIZE` + `PyBytes_Size `_ :c:func:`HPyBytes_Size` + `PyCallable_Check `_ :c:func:`HPyCallable_Check` + `PyCapsule_IsValid `_ :c:func:`HPyCapsule_IsValid` + `PyContextVar_Get `_ :c:func:`HPyContextVar_Get` + `PyContextVar_New `_ :c:func:`HPyContextVar_New` + `PyContextVar_Set `_ :c:func:`HPyContextVar_Set` + `PyDict_Check `_ :c:func:`HPyDict_Check` + `PyDict_Copy `_ :c:func:`HPyDict_Copy` + `PyDict_Keys `_ :c:func:`HPyDict_Keys` + `PyDict_New `_ :c:func:`HPyDict_New` + `PyErr_Clear `_ :c:func:`HPyErr_Clear` + `PyErr_ExceptionMatches `_ :c:func:`HPyErr_ExceptionMatches` + `PyErr_NewException `_ :c:func:`HPyErr_NewException` + `PyErr_NewExceptionWithDoc `_ :c:func:`HPyErr_NewExceptionWithDoc` + `PyErr_NoMemory `_ :c:func:`HPyErr_NoMemory` + `PyErr_SetFromErrnoWithFilename `_ :c:func:`HPyErr_SetFromErrnoWithFilename` + `PyErr_SetFromErrnoWithFilenameObjects `_ :c:func:`HPyErr_SetFromErrnoWithFilenameObjects` + `PyErr_SetObject `_ :c:func:`HPyErr_SetObject` + `PyErr_SetString `_ :c:func:`HPyErr_SetString` + `PyErr_WarnEx `_ :c:func:`HPyErr_WarnEx` + `PyErr_WriteUnraisable `_ :c:func:`HPyErr_WriteUnraisable` + `PyEval_EvalCode `_ :c:func:`HPy_EvalCode` + `PyEval_RestoreThread `_ :c:func:`HPy_ReenterPythonExecution` + `PyEval_SaveThread `_ :c:func:`HPy_LeavePythonExecution` + `PyFloat_AsDouble `_ :c:func:`HPyFloat_AsDouble` + `PyFloat_FromDouble `_ :c:func:`HPyFloat_FromDouble` + `PyImport_ImportModule `_ :c:func:`HPyImport_ImportModule` + `PyIter_Check `_ :c:func:`HPyIter_Check` + `PyIter_Next `_ :c:func:`HPyIter_Next` + `PyList_Append `_ :c:func:`HPyList_Append` + `PyList_Check `_ :c:func:`HPyList_Check` + `PyList_Insert `_ :c:func:`HPyList_Insert` + `PyList_New `_ :c:func:`HPyList_New` + `PyLong_AsDouble `_ :c:func:`HPyLong_AsDouble` + `PyLong_AsLong `_ :c:func:`HPyLong_AsLong` + `PyLong_AsLongLong `_ :c:func:`HPyLong_AsLongLong` + `PyLong_AsSize_t `_ :c:func:`HPyLong_AsSize_t` + `PyLong_AsSsize_t `_ :c:func:`HPyLong_AsSsize_t` + `PyLong_AsUnsignedLong `_ :c:func:`HPyLong_AsUnsignedLong` + `PyLong_AsUnsignedLongLong `_ :c:func:`HPyLong_AsUnsignedLongLong` + `PyLong_AsUnsignedLongLongMask `_ :c:func:`HPyLong_AsUnsignedLongLongMask` + `PyLong_AsUnsignedLongMask `_ :c:func:`HPyLong_AsUnsignedLongMask` + `PyLong_AsVoidPtr `_ :c:func:`HPyLong_AsVoidPtr` + `PyLong_FromLong `_ :c:func:`HPyLong_FromLong` + `PyLong_FromLongLong `_ :c:func:`HPyLong_FromLongLong` + `PyLong_FromSize_t `_ :c:func:`HPyLong_FromSize_t` + `PyLong_FromSsize_t `_ :c:func:`HPyLong_FromSsize_t` + `PyLong_FromUnsignedLong `_ :c:func:`HPyLong_FromUnsignedLong` + `PyLong_FromUnsignedLongLong `_ :c:func:`HPyLong_FromUnsignedLongLong` + `PyNumber_Absolute `_ :c:func:`HPy_Absolute` + `PyNumber_Add `_ :c:func:`HPy_Add` + `PyNumber_And `_ :c:func:`HPy_And` + `PyNumber_Check `_ :c:func:`HPyNumber_Check` + `PyNumber_Divmod `_ :c:func:`HPy_Divmod` + `PyNumber_Float `_ :c:func:`HPy_Float` + `PyNumber_FloorDivide `_ :c:func:`HPy_FloorDivide` + `PyNumber_InPlaceAdd `_ :c:func:`HPy_InPlaceAdd` + `PyNumber_InPlaceAnd `_ :c:func:`HPy_InPlaceAnd` + `PyNumber_InPlaceFloorDivide `_ :c:func:`HPy_InPlaceFloorDivide` + `PyNumber_InPlaceLshift `_ :c:func:`HPy_InPlaceLshift` + `PyNumber_InPlaceMatrixMultiply `_ :c:func:`HPy_InPlaceMatrixMultiply` + `PyNumber_InPlaceMultiply `_ :c:func:`HPy_InPlaceMultiply` + `PyNumber_InPlaceOr `_ :c:func:`HPy_InPlaceOr` + `PyNumber_InPlacePower `_ :c:func:`HPy_InPlacePower` + `PyNumber_InPlaceRemainder `_ :c:func:`HPy_InPlaceRemainder` + `PyNumber_InPlaceRshift `_ :c:func:`HPy_InPlaceRshift` + `PyNumber_InPlaceSubtract `_ :c:func:`HPy_InPlaceSubtract` + `PyNumber_InPlaceTrueDivide `_ :c:func:`HPy_InPlaceTrueDivide` + `PyNumber_InPlaceXor `_ :c:func:`HPy_InPlaceXor` + `PyNumber_Index `_ :c:func:`HPy_Index` + `PyNumber_Invert `_ :c:func:`HPy_Invert` + `PyNumber_Long `_ :c:func:`HPy_Long` + `PyNumber_Lshift `_ :c:func:`HPy_Lshift` + `PyNumber_MatrixMultiply `_ :c:func:`HPy_MatrixMultiply` + `PyNumber_Multiply `_ :c:func:`HPy_Multiply` + `PyNumber_Negative `_ :c:func:`HPy_Negative` + `PyNumber_Or `_ :c:func:`HPy_Or` + `PyNumber_Positive `_ :c:func:`HPy_Positive` + `PyNumber_Power `_ :c:func:`HPy_Power` + `PyNumber_Remainder `_ :c:func:`HPy_Remainder` + `PyNumber_Rshift `_ :c:func:`HPy_Rshift` + `PyNumber_Subtract `_ :c:func:`HPy_Subtract` + `PyNumber_TrueDivide `_ :c:func:`HPy_TrueDivide` + `PyNumber_Xor `_ :c:func:`HPy_Xor` + `PyObject_ASCII `_ :c:func:`HPy_ASCII` + `PyObject_Bytes `_ :c:func:`HPy_Bytes` + `PyObject_Call `_ :c:func:`HPy_CallTupleDict` + `PyObject_DelItem `_ :c:func:`HPy_DelItem` + `PyObject_GetAttr `_ :c:func:`HPy_GetAttr` + `PyObject_GetAttrString `_ :c:func:`HPy_GetAttr_s` + `PyObject_GetItem `_ :c:func:`HPy_GetItem` + `PyObject_GetIter `_ :c:func:`HPy_GetIter` + `PyObject_HasAttr `_ :c:func:`HPy_HasAttr` + `PyObject_HasAttrString `_ :c:func:`HPy_HasAttr_s` + `PyObject_Hash `_ :c:func:`HPy_Hash` + `PyObject_IsTrue `_ :c:func:`HPy_IsTrue` + `PyObject_Length `_ :c:func:`HPy_Length` + `PyObject_Repr `_ :c:func:`HPy_Repr` + `PyObject_RichCompare `_ :c:func:`HPy_RichCompare` + `PyObject_RichCompareBool `_ :c:func:`HPy_RichCompareBool` + `PyObject_SetAttr `_ :c:func:`HPy_SetAttr` + `PyObject_SetAttrString `_ :c:func:`HPy_SetAttr_s` + `PyObject_SetItem `_ :c:func:`HPy_SetItem` + `PyObject_Str `_ :c:func:`HPy_Str` + `PyObject_Type `_ :c:func:`HPy_Type` + `PyObject_TypeCheck `_ :c:func:`HPy_TypeCheck` + `PyObject_Vectorcall `_ :c:func:`HPy_Call` + `PyObject_VectorcallMethod `_ :c:func:`HPy_CallMethod` + `PySequence_Contains `_ :c:func:`HPy_Contains` + `PySequence_DelSlice `_ :c:func:`HPy_DelSlice` + `PySequence_GetSlice `_ :c:func:`HPy_GetSlice` + `PySequence_SetSlice `_ :c:func:`HPy_SetSlice` + `PySlice_AdjustIndices `_ :c:func:`HPySlice_AdjustIndices` + `PySlice_New `_ :c:func:`HPySlice_New` + `PySlice_Unpack `_ :c:func:`HPySlice_Unpack` + `PyTuple_Check `_ :c:func:`HPyTuple_Check` + `PyType_IsSubtype `_ :c:func:`HPyType_IsSubtype` + `PyUnicode_AsASCIIString `_ :c:func:`HPyUnicode_AsASCIIString` + `PyUnicode_AsLatin1String `_ :c:func:`HPyUnicode_AsLatin1String` + `PyUnicode_AsUTF8AndSize `_ :c:func:`HPyUnicode_AsUTF8AndSize` + `PyUnicode_AsUTF8String `_ :c:func:`HPyUnicode_AsUTF8String` + `PyUnicode_Check `_ :c:func:`HPyUnicode_Check` + `PyUnicode_DecodeASCII `_ :c:func:`HPyUnicode_DecodeASCII` + `PyUnicode_DecodeFSDefault `_ :c:func:`HPyUnicode_DecodeFSDefault` + `PyUnicode_DecodeFSDefaultAndSize `_ :c:func:`HPyUnicode_DecodeFSDefaultAndSize` + `PyUnicode_DecodeLatin1 `_ :c:func:`HPyUnicode_DecodeLatin1` + `PyUnicode_EncodeFSDefault `_ :c:func:`HPyUnicode_EncodeFSDefault` + `PyUnicode_FromEncodedObject `_ :c:func:`HPyUnicode_FromEncodedObject` + `PyUnicode_FromString `_ :c:func:`HPyUnicode_FromString` + `PyUnicode_FromWideChar `_ :c:func:`HPyUnicode_FromWideChar` + `PyUnicode_ReadChar `_ :c:func:`HPyUnicode_ReadChar` + `PyUnicode_Substring `_ :c:func:`HPyUnicode_Substring` + `Py_FatalError `_ :c:func:`HPy_FatalError` + ================================================================================================================================== ================================================ +.. mark: END API MAPPING + + +.. note: There are, of course, also cases where it is not possible to map directly and safely from a C API function (or concept) to an HPy API function (or concept). + +Reference Counting ``Py_INCREF`` and ``Py_DECREF`` +-------------------------------------------------- + +The equivalents of ``Py_INCREF`` and ``Py_DECREF`` are essentially +:c:func:`HPy_Dup` and :c:func:`HPy_Close`, respectively. The main difference is +that :c:func:`HPy_Dup` gives you a *new handle* to the same object which means +that the two handles may be different if comparing them with ``memcmp`` but +still reference the same object. As a consequence, you may close a handle only +once, i.e., you cannot call :c:func:`HPy_Close` twice on the same ``HPy`` +handle, even if returned from ``HPy_Dup``. For examples, see also sections +:ref:`api:handles` and :ref:`api:handles vs ``pyobject *``` + +Calling functions ``PyObject_Call`` and ``PyObject_CallObject`` +--------------------------------------------------------------- + +Both ``PyObject_Call`` and ``PyObject_CallObject`` are replaced by +``HPy_CallTupleDict(callable, args, kwargs)`` in which either or both of +``args`` and ``kwargs`` may be null handles. + +``PyObject_Call(callable, args, kwargs)`` becomes:: + + HPy result = HPy_CallTupleDict(ctx, callable, args, kwargs); + +``PyObject_CallObject(callable, args)`` becomes:: + + HPy result = HPy_CallTupleDict(ctx, callable, args, HPy_NULL); + +If ``args`` is not a handle to a tuple or ``kwargs`` is not a handle to a +dictionary, ``HPy_CallTupleDict`` will return ``HPy_NULL`` and raise a +``TypeError``. This is different to ``PyObject_Call`` and +``PyObject_CallObject`` which may segfault instead. + +Calling Protocol +---------------- + +Both the *tp_call* and *vectorcall* calling protocols are replaced by HPy's +calling protocol. This is done by defining slot ``HPy_tp_call``. HPy uses only +one calling convention which is similar to the vectorcall calling convention. +In the following example, we implement a call function for a simple Euclidean +vector type. The function computes the dot product of two vectors. + +.. literalinclude:: examples/snippets/hpycall.c + :start-after: // BEGIN EuclideanVectorObject + :end-before: // END EuclideanVectorObject + +.. literalinclude:: examples/snippets/hpycall.c + :start-after: // BEGIN HPy_tp_call + :end-before: // END HPy_tp_call + +Positional and keyword arguments are passed as C array ``args``. Argument +``nargs`` specifies the number of positional arguments. Argument ``kwnames`` is +a tuple containing the names of the keyword arguments. The keyword argument +values are appended to positional arguments and start at ``args[nargs]`` (if +there are any). + +In the above example, function ``call_impl`` will be used by default to call all +instances of the corresponding type. It is also possible to install (maybe +specialized) call function implementations per instances by using function +:c:func:`HPy_SetCallFunction`. This needs to be done in the constructor of an +object. For example: + +.. literalinclude:: examples/snippets/hpycall.c + :start-after: // BEGIN HPy_SetCallFunction + :end-before: // END HPy_SetCallFunction + +Limitations +~~~~~~~~~~~ + + 1. It is not possible to use slot ``HPy_tp_call`` for a *var object* (i.e. if + :c:member:`HPyType_Spec.itemsize` is greater ``0``). Reason: HPy installs + a hidden field in the object's data to store the call function pointer + which is appended to everything else. In case of ``EuclideanVectorObject``, + a field is implicitly appended after member ``y``. This is not possible for + var objects because the variable part will also start after the fixed + members. + + 2. It is also not possible to use slot ``HPy_tp_call`` with a legacy type that + inherits the basicsize (i.e. if :c:member:`HPyType_Spec.basicsize` is + ``0``) for the same reason as above. + +To overcome these limitations, it is still possible to manually embed a field +for the call function pointer in a type's C struct and tell HPy where this field +is. In this case, it is always necessary to set the call function pointer using +:c:func:`HPy_SetCallFunction` in the object's constructor. This procedure is +less convenient than just using slot ``HPy_tp_cal`` but still not hard to use. +Consider following example. We define a struct ``FooObject`` and declare field +``HPyCallFunction call_func`` which will be used to store the call function's +pointer. We need to register the offset of that field with member +``__vectorcalloffset__`` and in the constructor ``Foo_new``, we assign the call +function ``Foo_call_func``. + +.. literalinclude:: examples/snippets/hpycall.c + :start-after: // BEGIN FooObject + :end-before: // END FooObject + +.. literalinclude:: examples/snippets/hpycall.c + :start-after: // BEGIN vectorcalloffset + :end-before: // END vectorcalloffset + +.. note:: + + In contrast to CPython's vectorcall protocol, ``nargs`` will never have flag + ``PY_VECTORCALL_ARGUMENTS_OFFSET`` set. It will **only** be the positional + argument count. + +.. _call-migration: + +Incremental Migration to HPy's Calling Protocol +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In order to support incremental migration, HPy provides helper function +:c:func:`HPyHelpers_PackArgsAndKeywords` that converts from HPy's calling +convention to CPython's *tp_call* calling convention. Consider following +example: + +.. literalinclude:: examples/snippets/hpycall.c + :start-after: // BEGIN pack_args + :end-before: // END pack_args + +In this example, ``args``, ``nargs``, and ``kwnames`` are used to create a tuple +of positional arguments ``args_tuple`` and a keyword arguments dictionary +``kwd``. + +PyModule_AddObject +------------------ + +``PyModule_AddObject`` is replaced with a regular :c:func:`HPy_SetAttr_s`. There +is no ``HPyModule_AddObject`` function because it has an unusual refcount +behavior (stealing a reference but only when it returns ``0``). + + +.. _dealloc: + +Deallocator slot ``Py_tp_dealloc`` +---------------------------------- + +``Py_tp_dealloc`` essentially becomes ``HPy_tp_destroy``. The name intentionally +differs because there are major differences: while the slot function of +``Py_tp_dealloc`` receives the full object (which makes it possible to resurrect +it) and while there are no restrictions on what you may call in the C API +deallocator, you must not do that in HPy's deallocator. + +The two major restrictions apply to the slot function of ``HPy_tp_destroy``: + +1. The function must be **thread-safe**. +2. The function **must not** call into the interpreter. + +The idea is, that ``HPy_tp_destroy`` just releases native resources (e.g. by +using C lib's ``free`` function). Therefore, it only receives a pointer to the +object's native data (and not a handle to the object) and it does not receive an +``HPyContext`` pointer argument. + +For the time being, HPy will support the ``HPy_tp_finalize`` slot where those +tight restrictions do not apply at the (significant) cost of performance. + +Special slots ``Py_tp_methods``, ``Py_tp_members``, and ``Py_tp_getset`` +------------------------------------------------------------------------ + +There is no direct replacement for C API slots ``Py_tp_methods``, +``Py_tp_members``, and ``Py_tp_getset`` because they are no longer needed. +Methods, members, and get/set descriptors are specified *flatly* together with +the other slots, using the standard mechanisms of :c:macro:`HPyDef_METH`, +:c:macro:`HPyDef_MEMBER`, and :c:macro:`HPyDef_GETSET`. The resulting ``HPyDef`` +structures are then accumulated in :c:member:`HPyType_Spec.defines`. + +Creating lists and tuples +------------------------- + +The C API way of creating lists and tuples is to create an empty list or tuple +object using ``PyList_New(n)`` or ``PyTuple_New(n)``, respectively, and then to +fill the empty object using ``PyList_SetItem / PyList_SET_ITEM`` or +``PyTuple_SetItem / PyTuple_SET_ITEM``, respectively. + +This is in particular problematic for tuples because they are actually +immutable. HPy goes a different way and provides a dedicated *builder* API to +avoid the (temporary) inconsistent state during object initialization. + +Long story short, doing the same in HPy with builders is still very simple and +straight forward. Following an example for creating a list: + +.. code-block:: c + + PyObject *list = PyList_New(5); + if (list == NULL) + return NULL; /* error */ + PyList_SET_ITEM(list, 0, item0); + PyList_SET_ITEM(list, 1, item0); + ... + PyList_SET_ITEM(list, 4, item0); + /* now 'list' is ready to use */ + +becomes + +.. code-block:: c + + HPyListBuilder builder = HPyListBuilder_New(ctx, 5); + HPyListBuilder_Set(ctx, builder, 0, h_item0); + HPyListBuilder_Set(ctx, builder, 1, h_item1); + ... + HPyListBuilder_Set(ctx, builder, 4, h_item4); + HPy h_list = HPyListBuilder_Build(ctx, builder); + if (HPy_IsNull(h_list)) + return HPy_NULL; /* error */ + +.. note:: In contrast to ``PyList_SetItem``, ``PyList_SET_ITEM``, + ``PyTuple_SetItem``, and ``PyTuple_SET_ITEM``, the builder functions + :c:func:`HPyListBuilder_Set` and :c:func:`HPyTupleBuilder_Set` are **NOT** + stealing references. It is necessary to close the passed item handles (e.g. + ``h_item0`` in the above example) if they are no longer needed. + +If an error occurs during building the list or tuple, it is necessary to call +:c:func:`HPyListBuilder_Cancel` or :c:func:`HPyTupleBuilder_Cancel`, +respectively, to avoid memory leaks. + +For details, see the API reference documentation +:doc:`api-reference/hpy-sequence`. + +Buffers +------- + +The buffer API in HPy is implemented using the ``HPy_buffer`` struct, which looks +very similar to ``Py_buffer`` (refer to the `CPython documentation +`_ for the +meaning of the fields):: + + typedef struct { + void *buf; + HPy obj; + HPy_ssize_t len; + HPy_ssize_t itemsize; + int readonly; + int ndim; + char *format; + HPy_ssize_t *shape; + HPy_ssize_t *strides; + HPy_ssize_t *suboffsets; + void *internal; + } HPy_buffer; + +Buffer slots for HPy types are specified using slots ``HPy_bf_getbuffer`` and +``HPy_bf_releasebuffer`` on all supported Python versions, even though the +matching PyType_Spec slots, ``Py_bf_getbuffer`` and ``Py_bf_releasebuffer``, are +only available starting from CPython 3.9. + +Multi-phase Module Initialization +--------------------------------- + +HPy supports only multi-phase module initialization (PEP 451). This means that +the module object is typically created by interpreter from the ``HPyModuleDef`` +specification and there is no "init" function. However, the module can define +one or more ``HPy_mod_exec`` slots, which will be executed just after the module +object is created. Inside the code of those slots, one can usually perform the same +initialization as before. + +Example of legacy single phase module initialization that uses Python/C API: + +.. literalinclude:: examples/snippets/legacyinit.c + :start-after: // BEGIN + :end-before: // END + +The same code structure ported to HPy and multi-phase module initialization: + +.. literalinclude:: examples/snippets/hpyinit.c + :start-after: // BEGIN + :end-before: // END diff --git a/graalpython/hpy/docs/quickstart.rst b/graalpython/hpy/docs/quickstart.rst new file mode 100644 index 0000000000..f57063cfa8 --- /dev/null +++ b/graalpython/hpy/docs/quickstart.rst @@ -0,0 +1,55 @@ +HPy Quickstart +============== + +This section shows how to quickly get started with HPy by creating +a simple HPy extension from scratch. + +Install latest HPy release: + +.. code-block:: console + + python3 -m pip install hpy + +Alternatively, you can also install HPy from the development repository: + +.. code-block:: console + + python3 -m pip install git+https://github.com/hpyproject/hpy.git#egg=hpy + +Create a new directory for the new HPy extension. Location and name of the directory +do not matter. Add the following two files: + +.. literalinclude:: examples/quickstart/quickstart.c + +.. literalinclude:: examples/quickstart/setup.py + :language: python + +Build the extension: + +.. code-block:: console + + python3 setup.py --hpy-abi=universal develop + +Try it out -- start Python console in the same directory and type: + +.. literalinclude:: examples/tests.py + :start-after: test_quickstart + :end-before: # END: test_quickstart + +Notice the shared library that was created by running ``setup.py``: + +.. code-block:: console + + > ls *.so + quickstart.hpy0.so + +It does not have Python version encoded in it. If you happen to have +GraalPy or PyPy installation that supports given HPy version, you can +try running the same extension on it. For example, start +``$GRAALVM_HOME/bin/graalpy`` in the same directory and type the same +Python code: the extension should load and work just fine. + +Where to go next? + + - :ref:`Simple documented HPy extension example` + - :doc:`Tutorial: porting Python/C API extension to HPy` diff --git a/graalpython/hpy/docs/requirements.txt b/graalpython/hpy/docs/requirements.txt new file mode 100644 index 0000000000..bb561e010f --- /dev/null +++ b/graalpython/hpy/docs/requirements.txt @@ -0,0 +1,8 @@ +# Requirements for building the documentation +Jinja2==3.1.3 +sphinx==5.0.2 +sphinx-rtd-theme==2.0.0 +sphinx-autobuild==2021.3.14 +sphinx-c-autodoc==1.3.0 +clang==17.0.6 +docutils==0.16 # docutils >= 0.17 fails to render bullet lists :/ diff --git a/graalpython/hpy/docs/trace-mode.rst b/graalpython/hpy/docs/trace-mode.rst new file mode 100644 index 0000000000..b8763b4220 --- /dev/null +++ b/graalpython/hpy/docs/trace-mode.rst @@ -0,0 +1,64 @@ +Trace Mode +========== + +HPy's trace mode allows you to analyze the usage of the HPy API. The two +fundamental metrics are ``call count`` and ``duration``. As the name already +suggests, ``call count`` tells you how often a certain HPy API function was called +and ``duration`` uses a monotonic clock to measure how much (accumulated) time was +spent in a certain HPy API function. It is further possible to register custom +*on-enter* and *on-exit* Python functions. + +As with the debug mode, the trace mode can be activated at *import time*, so no +recompilation is required. + + +Activating Trace Mode +--------------------- + +Similar to how the +:ref:`debug mode is activated `, use +environment variable ``HPY``. If ``HPY=trace``, then all HPy modules are loaded +with the trace context. Alternatively, it is also possible to specify the mode +per module like this: ``HPY=modA:trace,modB:trace``. +Environment variable ``HPY_LOG`` also works. + + +Using Trace Mode +---------------- + +The trace mode can be accessed via the shipped module ``hpy.trace``. It provides +following functions: + +* ``get_call_counts()`` returns a dict. The HPy API function names are used as + keys and the corresponding call count is the value. +* ``get_durations()`` also returns a dict similar to ``get_call_counts`` but + the value is the accumulated time spent in the corresponding HPy API + function (in nanoseconds). Note, the used clock does not necessarily have a + nanosecond resolution which means that the least significant digits may not be + accurate. +* ``set_trace_functions(on_enter=None, on_exit=None)`` allows the user to + register custom trace functions. The function provided for ``on_enter`` and + ``on_exit`` functions will be executed before and after and HPy API function + is and was executed, respectively. Passing ``None`` to any of the two + arguments or omitting one will clear the corresponding function. +* ``get_frequency()`` returns the resolution of the used clock to measure the + time in Hertz. For example, a value of ``10000000`` corresponds to + ``10 MHz``. In that case, the two least significant digits of the durations + are inaccurate. + + +Example +------- + +Following HPy function uses ``HPy_Add``: + +.. literalinclude:: examples/snippets/snippets.c + :start-after: // BEGIN: add + :end-before: // END: add + +When this script is executed in trace mode: + +.. literalinclude:: examples/trace-example.py + :language: python + +The output is ``get_call_counts()["ctx_Add"] == 1``. diff --git a/graalpython/hpy/docs/xxx-unsorted-notes.txt b/graalpython/hpy/docs/xxx-unsorted-notes.txt new file mode 100644 index 0000000000..159b6e315c --- /dev/null +++ b/graalpython/hpy/docs/xxx-unsorted-notes.txt @@ -0,0 +1,91 @@ +Goal: better C API for CPython and 1st-class citizen on PyPy + +- everything should be opaque by default + + - should we have an API to "query" if an object supports a certain low-level layout? E.g list-of-integer + + - should we have an API to e.g. ask "give me the nth C-level long in the + list? And then rely on the compiler to turn this into an efficient loop: + long PyObject_GetLongItem(PyHandle h, long index) ? + + +- we need PyObject_GetItem(handle) and PyObject_GetItem(int_index) + +- PyHandle PyObject_GetMappingProtocol(PyHandle o): ask a python object if it + has the "mapping" interface; then you can close it when you are done with it + and e.g. PyPy can release when it's no longer needed + +- should we write a tool to convert from the old API to the new API? + +- how we do deploy it? Should we have a single PyHandle.h file which is enough + to include? Or do like numpy.get_include_dirs()? + + - we need to do what cffi does (and ship our version on PyPy) + + - cython might need/want to ship its own vendored version of PyHandle + +- we need a versioning system which is possible to query at runtime? (to check + that it was compiled with the "correct/expected" PyHandle version + +- what to do with existing code which actively check whether the refcount is 1? E.g. PyString_Resize? + +- fast c-to-c calls: should we use argument clinic or something similar? + + + +Protocol sketch +---------------- + +HPySequence_long x = HPy_AsSequence_long(obj); /* it is possible to fail and you should be ready to handle the fallback */ +int len = HPy_Sequence_Len_long(x, obj); +for(int i=0; i sequence index access +* comparisons (<, <=, ==, !=, >=, >) + * rich comparisons + * boolean comparisons (0/1) +* call (call/vectorcall/method/special-method) + * e.g. PyCall_SpecialMethodOneArg(obj, __add__, arg) -> call specific macro + * … +* context manager (enter/exit) + * -> call special method +* async (await/aiter/anext) + * -> call special method diff --git a/graalpython/hpy/gdb-py.test b/graalpython/hpy/gdb-py.test new file mode 100755 index 0000000000..7412a06214 --- /dev/null +++ b/graalpython/hpy/gdb-py.test @@ -0,0 +1,3 @@ +#!/bin/bash + +gdb --eval-command run --args python3 -m pytest -s "$@" diff --git a/graalpython/hpy/hpy/debug/__init__.py b/graalpython/hpy/hpy/debug/__init__.py new file mode 100644 index 0000000000..71ece53923 --- /dev/null +++ b/graalpython/hpy/hpy/debug/__init__.py @@ -0,0 +1,11 @@ +from .leakdetector import HPyDebugError, HPyLeakError, LeakDetector + + +def set_handle_stack_trace_limit(limit): + from hpy.universal import _debug + _debug.set_handle_stack_trace_limit(limit) + + +def disable_handle_stack_traces(): + from hpy.universal import _debug + _debug.set_handle_stack_trace_limit(None) diff --git a/graalpython/hpy/hpy/debug/leakdetector.py b/graalpython/hpy/hpy/debug/leakdetector.py new file mode 100644 index 0000000000..56a68d344c --- /dev/null +++ b/graalpython/hpy/hpy/debug/leakdetector.py @@ -0,0 +1,43 @@ +from hpy.universal import _debug + +class HPyDebugError(Exception): + pass + +class HPyLeakError(HPyDebugError): + def __init__(self, leaks): + super().__init__() + self.leaks = leaks + + def __str__(self): + lines = [] + n = len(self.leaks) + s = 's' if n != 1 else '' + lines.append(f'{n} unclosed handle{s}:') + for dh in self.leaks: + lines.append(' %r' % dh) + return '\n'.join(lines) + + +class LeakDetector: + + def __init__(self): + self.generation = None + + def start(self): + if self.generation is not None: + raise ValueError('LeakDetector already started') + self.generation = _debug.new_generation() + + def stop(self): + if self.generation is None: + raise ValueError('LeakDetector not started yet') + leaks = _debug.get_open_handles(self.generation) + if leaks: + raise HPyLeakError(leaks) + + def __enter__(self): + self.start() + return self + + def __exit__(self, etype, evalue, tb): + self.stop() diff --git a/graalpython/hpy/hpy/debug/pytest.py b/graalpython/hpy/hpy/debug/pytest.py new file mode 100644 index 0000000000..9a33c51343 --- /dev/null +++ b/graalpython/hpy/hpy/debug/pytest.py @@ -0,0 +1,31 @@ +# hpy.debug / pytest integration + +import pytest +from .leakdetector import LeakDetector + +# For now "hpy_debug" just does leak detection, but in the future it might +# grows extra features: that's why it's called generically "hpy_debug" instead +# of "detect_leaks". + +# NOTE: the fixture itself is currently untested :(. It turns out that testing +# that the fixture raises during the teardown is complicated and probably +# requires to write a full-fledged plugin. We might want to turn this into a +# real plugin in the future, but for now I think this is enough. + +# pypy still uses a very ancient version of pytest, 2.9.2: pytest<3.x needs to +# use @yield_fixture, which is deprecated in newer version of pytest (where +# you can just use @fixture) +if pytest.__version__ < '3': + fixture = pytest.yield_fixture +else: + fixture = pytest.fixture + +@fixture +def hpy_debug(request): + """ + pytest fixture which makes it possible to control hpy.debug from within a test. + + In particular, it automatically check that the test doesn't leak. + """ + with LeakDetector() as ld: + yield ld diff --git a/graalpython/com.oracle.graal.python.jni/src/debug/_debugmod.c b/graalpython/hpy/hpy/debug/src/_debugmod.c similarity index 92% rename from graalpython/com.oracle.graal.python.jni/src/debug/_debugmod.c rename to graalpython/hpy/hpy/debug/src/_debugmod.c index e67601e210..2bd71f3262 100644 --- a/graalpython/com.oracle.graal.python.jni/src/debug/_debugmod.c +++ b/graalpython/hpy/hpy/debug/src/_debugmod.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - // Python-level interface for the _debug module. Written in HPy itself, the // idea is that it should be reusable by other implementations @@ -34,7 +10,7 @@ static UHPy new_DebugHandleObj(HPyContext *uctx, UHPy u_DebugHandleType, DebugHandle *handle); -HPY_MOD_EMBEDDABLE(_trace) +HPY_MOD_EMBEDDABLE(_debug) HPyDef_METH(new_generation, "new_generation", HPyFunc_NOARGS) static UHPy new_generation_impl(HPyContext *uctx, UHPy self) diff --git a/graalpython/hpy/hpy/debug/src/autogen_debug_ctx_call.i b/graalpython/hpy/hpy/debug/src/autogen_debug_ctx_call.i new file mode 100644 index 0000000000..0cd23a98aa --- /dev/null +++ b/graalpython/hpy/hpy/debug/src/autogen_debug_ctx_call.i @@ -0,0 +1,468 @@ + +/* + DO NOT EDIT THIS FILE! + + This file is automatically generated by hpy.tools.autogen.debug.autogen_debug_ctx_call_i + See also hpy.tools.autogen and hpy/tools/public_api.h + + Run this to regenerate: + make autogen + +*/ + + case HPyFunc_NOARGS: { + HPyFunc_noargs f = (HPyFunc_noargs)func; + _HPyFunc_args_NOARGS *a = (_HPyFunc_args_NOARGS*)args; + DHPy dh_self = _py2dh(dctx, a->self); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + DHPy dh_result = f(next_dctx, dh_self); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_self); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_O: { + HPyFunc_o f = (HPyFunc_o)func; + _HPyFunc_args_O *a = (_HPyFunc_args_O*)args; + DHPy dh_self = _py2dh(dctx, a->self); + DHPy dh_arg = _py2dh(dctx, a->arg); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + DHPy dh_result = f(next_dctx, dh_self, dh_arg); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_self); + DHPy_close_and_check(dctx, dh_arg); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_UNARYFUNC: { + HPyFunc_unaryfunc f = (HPyFunc_unaryfunc)func; + _HPyFunc_args_UNARYFUNC *a = (_HPyFunc_args_UNARYFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + DHPy dh_result = f(next_dctx, dh_arg0); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_BINARYFUNC: { + HPyFunc_binaryfunc f = (HPyFunc_binaryfunc)func; + _HPyFunc_args_BINARYFUNC *a = (_HPyFunc_args_BINARYFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + DHPy dh_arg1 = _py2dh(dctx, a->arg1); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + DHPy_close_and_check(dctx, dh_arg1); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_TERNARYFUNC: { + HPyFunc_ternaryfunc f = (HPyFunc_ternaryfunc)func; + _HPyFunc_args_TERNARYFUNC *a = (_HPyFunc_args_TERNARYFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + DHPy dh_arg1 = _py2dh(dctx, a->arg1); + DHPy dh_arg2 = _py2dh(dctx, a->arg2); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + DHPy_close_and_check(dctx, dh_arg1); + DHPy_close_and_check(dctx, dh_arg2); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_INQUIRY: { + HPyFunc_inquiry f = (HPyFunc_inquiry)func; + _HPyFunc_args_INQUIRY *a = (_HPyFunc_args_INQUIRY*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = -1; + return; + } + a->result = f(next_dctx, dh_arg0); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + return; + } + case HPyFunc_LENFUNC: { + HPyFunc_lenfunc f = (HPyFunc_lenfunc)func; + _HPyFunc_args_LENFUNC *a = (_HPyFunc_args_LENFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = -1; + return; + } + a->result = f(next_dctx, dh_arg0); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + return; + } + case HPyFunc_SSIZEARGFUNC: { + HPyFunc_ssizeargfunc f = (HPyFunc_ssizeargfunc)func; + _HPyFunc_args_SSIZEARGFUNC *a = (_HPyFunc_args_SSIZEARGFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + DHPy dh_result = f(next_dctx, dh_arg0, a->arg1); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_SSIZESSIZEARGFUNC: { + HPyFunc_ssizessizeargfunc f = (HPyFunc_ssizessizeargfunc)func; + _HPyFunc_args_SSIZESSIZEARGFUNC *a = (_HPyFunc_args_SSIZESSIZEARGFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + DHPy dh_result = f(next_dctx, dh_arg0, a->arg1, a->arg2); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_SSIZEOBJARGPROC: { + HPyFunc_ssizeobjargproc f = (HPyFunc_ssizeobjargproc)func; + _HPyFunc_args_SSIZEOBJARGPROC *a = (_HPyFunc_args_SSIZEOBJARGPROC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + DHPy dh_arg2 = _py2dh(dctx, a->arg2); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = -1; + return; + } + a->result = f(next_dctx, dh_arg0, a->arg1, dh_arg2); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + DHPy_close_and_check(dctx, dh_arg2); + return; + } + case HPyFunc_SSIZESSIZEOBJARGPROC: { + HPyFunc_ssizessizeobjargproc f = (HPyFunc_ssizessizeobjargproc)func; + _HPyFunc_args_SSIZESSIZEOBJARGPROC *a = (_HPyFunc_args_SSIZESSIZEOBJARGPROC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + DHPy dh_arg3 = _py2dh(dctx, a->arg3); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = -1; + return; + } + a->result = f(next_dctx, dh_arg0, a->arg1, a->arg2, dh_arg3); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + DHPy_close_and_check(dctx, dh_arg3); + return; + } + case HPyFunc_OBJOBJARGPROC: { + HPyFunc_objobjargproc f = (HPyFunc_objobjargproc)func; + _HPyFunc_args_OBJOBJARGPROC *a = (_HPyFunc_args_OBJOBJARGPROC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + DHPy dh_arg1 = _py2dh(dctx, a->arg1); + DHPy dh_arg2 = _py2dh(dctx, a->arg2); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = -1; + return; + } + a->result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + DHPy_close_and_check(dctx, dh_arg1); + DHPy_close_and_check(dctx, dh_arg2); + return; + } + case HPyFunc_FREEFUNC: { + HPyFunc_freefunc f = (HPyFunc_freefunc)func; + _HPyFunc_args_FREEFUNC *a = (_HPyFunc_args_FREEFUNC*)args; + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + return; + } + f(next_dctx, a->arg0); + _switch_back_to_original_dctx(dctx, next_dctx); + return; + } + case HPyFunc_GETATTRFUNC: { + HPyFunc_getattrfunc f = (HPyFunc_getattrfunc)func; + _HPyFunc_args_GETATTRFUNC *a = (_HPyFunc_args_GETATTRFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + DHPy dh_result = f(next_dctx, dh_arg0, a->arg1); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_GETATTROFUNC: { + HPyFunc_getattrofunc f = (HPyFunc_getattrofunc)func; + _HPyFunc_args_GETATTROFUNC *a = (_HPyFunc_args_GETATTROFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + DHPy dh_arg1 = _py2dh(dctx, a->arg1); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + DHPy_close_and_check(dctx, dh_arg1); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_SETATTRFUNC: { + HPyFunc_setattrfunc f = (HPyFunc_setattrfunc)func; + _HPyFunc_args_SETATTRFUNC *a = (_HPyFunc_args_SETATTRFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + DHPy dh_arg2 = _py2dh(dctx, a->arg2); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = -1; + return; + } + a->result = f(next_dctx, dh_arg0, a->arg1, dh_arg2); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + DHPy_close_and_check(dctx, dh_arg2); + return; + } + case HPyFunc_SETATTROFUNC: { + HPyFunc_setattrofunc f = (HPyFunc_setattrofunc)func; + _HPyFunc_args_SETATTROFUNC *a = (_HPyFunc_args_SETATTROFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + DHPy dh_arg1 = _py2dh(dctx, a->arg1); + DHPy dh_arg2 = _py2dh(dctx, a->arg2); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = -1; + return; + } + a->result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + DHPy_close_and_check(dctx, dh_arg1); + DHPy_close_and_check(dctx, dh_arg2); + return; + } + case HPyFunc_REPRFUNC: { + HPyFunc_reprfunc f = (HPyFunc_reprfunc)func; + _HPyFunc_args_REPRFUNC *a = (_HPyFunc_args_REPRFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + DHPy dh_result = f(next_dctx, dh_arg0); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_HASHFUNC: { + HPyFunc_hashfunc f = (HPyFunc_hashfunc)func; + _HPyFunc_args_HASHFUNC *a = (_HPyFunc_args_HASHFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = -1; + return; + } + a->result = f(next_dctx, dh_arg0); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + return; + } + case HPyFunc_RICHCMPFUNC: { + HPyFunc_richcmpfunc f = (HPyFunc_richcmpfunc)func; + _HPyFunc_args_RICHCMPFUNC *a = (_HPyFunc_args_RICHCMPFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + DHPy dh_arg1 = _py2dh(dctx, a->arg1); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1, a->arg2); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + DHPy_close_and_check(dctx, dh_arg1); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_GETITERFUNC: { + HPyFunc_getiterfunc f = (HPyFunc_getiterfunc)func; + _HPyFunc_args_GETITERFUNC *a = (_HPyFunc_args_GETITERFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + DHPy dh_result = f(next_dctx, dh_arg0); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_ITERNEXTFUNC: { + HPyFunc_iternextfunc f = (HPyFunc_iternextfunc)func; + _HPyFunc_args_ITERNEXTFUNC *a = (_HPyFunc_args_ITERNEXTFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + DHPy dh_result = f(next_dctx, dh_arg0); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_DESCRGETFUNC: { + HPyFunc_descrgetfunc f = (HPyFunc_descrgetfunc)func; + _HPyFunc_args_DESCRGETFUNC *a = (_HPyFunc_args_DESCRGETFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + DHPy dh_arg1 = _py2dh(dctx, a->arg1); + DHPy dh_arg2 = _py2dh(dctx, a->arg2); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + DHPy_close_and_check(dctx, dh_arg1); + DHPy_close_and_check(dctx, dh_arg2); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_DESCRSETFUNC: { + HPyFunc_descrsetfunc f = (HPyFunc_descrsetfunc)func; + _HPyFunc_args_DESCRSETFUNC *a = (_HPyFunc_args_DESCRSETFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + DHPy dh_arg1 = _py2dh(dctx, a->arg1); + DHPy dh_arg2 = _py2dh(dctx, a->arg2); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = -1; + return; + } + a->result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + DHPy_close_and_check(dctx, dh_arg1); + DHPy_close_and_check(dctx, dh_arg2); + return; + } + case HPyFunc_GETTER: { + HPyFunc_getter f = (HPyFunc_getter)func; + _HPyFunc_args_GETTER *a = (_HPyFunc_args_GETTER*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + DHPy dh_result = f(next_dctx, dh_arg0, a->arg1); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_SETTER: { + HPyFunc_setter f = (HPyFunc_setter)func; + _HPyFunc_args_SETTER *a = (_HPyFunc_args_SETTER*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + DHPy dh_arg1 = _py2dh(dctx, a->arg1); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = -1; + return; + } + a->result = f(next_dctx, dh_arg0, dh_arg1, a->arg2); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + DHPy_close_and_check(dctx, dh_arg1); + return; + } + case HPyFunc_OBJOBJPROC: { + HPyFunc_objobjproc f = (HPyFunc_objobjproc)func; + _HPyFunc_args_OBJOBJPROC *a = (_HPyFunc_args_OBJOBJPROC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + DHPy dh_arg1 = _py2dh(dctx, a->arg1); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = -1; + return; + } + a->result = f(next_dctx, dh_arg0, dh_arg1); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + DHPy_close_and_check(dctx, dh_arg1); + return; + } + case HPyFunc_DESTRUCTOR: { + HPyFunc_destructor f = (HPyFunc_destructor)func; + _HPyFunc_args_DESTRUCTOR *a = (_HPyFunc_args_DESTRUCTOR*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + return; + } + f(next_dctx, dh_arg0); + _switch_back_to_original_dctx(dctx, next_dctx); + DHPy_close_and_check(dctx, dh_arg0); + return; + } diff --git a/graalpython/com.oracle.graal.python.jni/src/debug/autogen_debug_ctx_init.h b/graalpython/hpy/hpy/debug/src/autogen_debug_ctx_init.h similarity index 95% rename from graalpython/com.oracle.graal.python.jni/src/debug/autogen_debug_ctx_init.h rename to graalpython/hpy/hpy/debug/src/autogen_debug_ctx_init.h index d2ddd85633..c394c362ce 100644 --- a/graalpython/com.oracle.graal.python.jni/src/debug/autogen_debug_ctx_init.h +++ b/graalpython/hpy/hpy/debug/src/autogen_debug_ctx_init.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /* DO NOT EDIT THIS FILE! @@ -95,6 +71,9 @@ int debug_ctx_Callable_Check(HPyContext *dctx, DHPy h); DHPy debug_ctx_CallTupleDict(HPyContext *dctx, DHPy callable, DHPy args, DHPy kw); DHPy debug_ctx_Call(HPyContext *dctx, DHPy callable, const DHPy *args, size_t nargs, DHPy kwnames); DHPy debug_ctx_CallMethod(HPyContext *dctx, DHPy name, const DHPy *args, size_t nargs, DHPy kwnames); +DHPy debug_ctx_GetIter(HPyContext *dctx, DHPy obj); +DHPy debug_ctx_Iter_Next(HPyContext *dctx, DHPy obj); +int debug_ctx_Iter_Check(HPyContext *dctx, DHPy obj); void debug_ctx_FatalError(HPyContext *dctx, const char *message); void debug_ctx_Err_SetString(HPyContext *dctx, DHPy h_type, const char *utf8_message); void debug_ctx_Err_SetObject(HPyContext *dctx, DHPy h_type, DHPy h_value); @@ -120,13 +99,16 @@ int debug_ctx_SetAttr_s(HPyContext *dctx, DHPy obj, const char *utf8_name, DHPy DHPy debug_ctx_GetItem(HPyContext *dctx, DHPy obj, DHPy key); DHPy debug_ctx_GetItem_i(HPyContext *dctx, DHPy obj, HPy_ssize_t idx); DHPy debug_ctx_GetItem_s(HPyContext *dctx, DHPy obj, const char *utf8_key); +DHPy debug_ctx_GetSlice(HPyContext *dctx, DHPy obj, HPy_ssize_t start, HPy_ssize_t end); int debug_ctx_Contains(HPyContext *dctx, DHPy container, DHPy key); int debug_ctx_SetItem(HPyContext *dctx, DHPy obj, DHPy key, DHPy value); int debug_ctx_SetItem_i(HPyContext *dctx, DHPy obj, HPy_ssize_t idx, DHPy value); int debug_ctx_SetItem_s(HPyContext *dctx, DHPy obj, const char *utf8_key, DHPy value); +int debug_ctx_SetSlice(HPyContext *dctx, DHPy obj, HPy_ssize_t start, HPy_ssize_t end, DHPy value); int debug_ctx_DelItem(HPyContext *dctx, DHPy obj, DHPy key); int debug_ctx_DelItem_i(HPyContext *dctx, DHPy obj, HPy_ssize_t idx); int debug_ctx_DelItem_s(HPyContext *dctx, DHPy obj, const char *utf8_key); +int debug_ctx_DelSlice(HPyContext *dctx, DHPy obj, HPy_ssize_t start, HPy_ssize_t end); DHPy debug_ctx_Type(HPyContext *dctx, DHPy obj); int debug_ctx_TypeCheck(HPyContext *dctx, DHPy obj, DHPy type); const char *debug_ctx_Type_GetName(HPyContext *dctx, DHPy type); @@ -140,6 +122,7 @@ void *debug_ctx_AsStruct_Float(HPyContext *dctx, DHPy h); void *debug_ctx_AsStruct_Unicode(HPyContext *dctx, DHPy h); void *debug_ctx_AsStruct_Tuple(HPyContext *dctx, DHPy h); void *debug_ctx_AsStruct_List(HPyContext *dctx, DHPy h); +void *debug_ctx_AsStruct_Dict(HPyContext *dctx, DHPy h); HPyType_BuiltinShape debug_ctx_Type_GetBuiltinShape(HPyContext *dctx, DHPy h_type); DHPy debug_ctx_New(HPyContext *dctx, DHPy h_type, void **data); DHPy debug_ctx_Repr(HPyContext *dctx, DHPy obj); @@ -174,12 +157,14 @@ DHPy debug_ctx_Unicode_Substring(HPyContext *dctx, DHPy str, HPy_ssize_t start, int debug_ctx_List_Check(HPyContext *dctx, DHPy h); DHPy debug_ctx_List_New(HPyContext *dctx, HPy_ssize_t len); int debug_ctx_List_Append(HPyContext *dctx, DHPy h_list, DHPy h_item); +int debug_ctx_List_Insert(HPyContext *dctx, DHPy h_list, HPy_ssize_t index, DHPy h_item); int debug_ctx_Dict_Check(HPyContext *dctx, DHPy h); DHPy debug_ctx_Dict_New(HPyContext *dctx); DHPy debug_ctx_Dict_Keys(HPyContext *dctx, DHPy h); DHPy debug_ctx_Dict_Copy(HPyContext *dctx, DHPy h); int debug_ctx_Tuple_Check(HPyContext *dctx, DHPy h); -DHPy debug_ctx_Tuple_FromArray(HPyContext *dctx, DHPy items[], HPy_ssize_t n); +DHPy debug_ctx_Tuple_FromArray(HPyContext *dctx, const DHPy items[], HPy_ssize_t n); +DHPy debug_ctx_Slice_New(HPyContext *dctx, DHPy start, DHPy stop, DHPy step); int debug_ctx_Slice_Unpack(HPyContext *dctx, DHPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step); DHPy debug_ctx_Import_ImportModule(HPyContext *dctx, const char *utf8_name); DHPy debug_ctx_Capsule_New(HPyContext *dctx, void *pointer, const char *utf8_name, HPyCapsule_Destructor *destructor); @@ -299,6 +284,7 @@ static inline void debug_ctx_init_fields(HPyContext *dctx, HPyContext *uctx) dctx->h_MemoryViewType = DHPy_open_immortal(dctx, uctx->h_MemoryViewType); dctx->h_CapsuleType = DHPy_open_immortal(dctx, uctx->h_CapsuleType); dctx->h_SliceType = DHPy_open_immortal(dctx, uctx->h_SliceType); + dctx->h_DictType = DHPy_open_immortal(dctx, uctx->h_DictType); dctx->h_Builtins = DHPy_open_immortal(dctx, uctx->h_Builtins); dctx->ctx_Dup = &debug_ctx_Dup; dctx->ctx_Close = &debug_ctx_Close; @@ -361,6 +347,9 @@ static inline void debug_ctx_init_fields(HPyContext *dctx, HPyContext *uctx) dctx->ctx_CallTupleDict = &debug_ctx_CallTupleDict; dctx->ctx_Call = &debug_ctx_Call; dctx->ctx_CallMethod = &debug_ctx_CallMethod; + dctx->ctx_GetIter = &debug_ctx_GetIter; + dctx->ctx_Iter_Next = &debug_ctx_Iter_Next; + dctx->ctx_Iter_Check = &debug_ctx_Iter_Check; dctx->ctx_FatalError = &debug_ctx_FatalError; dctx->ctx_Err_SetString = &debug_ctx_Err_SetString; dctx->ctx_Err_SetObject = &debug_ctx_Err_SetObject; @@ -386,13 +375,16 @@ static inline void debug_ctx_init_fields(HPyContext *dctx, HPyContext *uctx) dctx->ctx_GetItem = &debug_ctx_GetItem; dctx->ctx_GetItem_i = &debug_ctx_GetItem_i; dctx->ctx_GetItem_s = &debug_ctx_GetItem_s; + dctx->ctx_GetSlice = &debug_ctx_GetSlice; dctx->ctx_Contains = &debug_ctx_Contains; dctx->ctx_SetItem = &debug_ctx_SetItem; dctx->ctx_SetItem_i = &debug_ctx_SetItem_i; dctx->ctx_SetItem_s = &debug_ctx_SetItem_s; + dctx->ctx_SetSlice = &debug_ctx_SetSlice; dctx->ctx_DelItem = &debug_ctx_DelItem; dctx->ctx_DelItem_i = &debug_ctx_DelItem_i; dctx->ctx_DelItem_s = &debug_ctx_DelItem_s; + dctx->ctx_DelSlice = &debug_ctx_DelSlice; dctx->ctx_Type = &debug_ctx_Type; dctx->ctx_TypeCheck = &debug_ctx_TypeCheck; dctx->ctx_Type_GetName = &debug_ctx_Type_GetName; @@ -406,6 +398,7 @@ static inline void debug_ctx_init_fields(HPyContext *dctx, HPyContext *uctx) dctx->ctx_AsStruct_Unicode = &debug_ctx_AsStruct_Unicode; dctx->ctx_AsStruct_Tuple = &debug_ctx_AsStruct_Tuple; dctx->ctx_AsStruct_List = &debug_ctx_AsStruct_List; + dctx->ctx_AsStruct_Dict = &debug_ctx_AsStruct_Dict; dctx->ctx_Type_GetBuiltinShape = &debug_ctx_Type_GetBuiltinShape; dctx->ctx_New = &debug_ctx_New; dctx->ctx_Repr = &debug_ctx_Repr; @@ -440,12 +433,14 @@ static inline void debug_ctx_init_fields(HPyContext *dctx, HPyContext *uctx) dctx->ctx_List_Check = &debug_ctx_List_Check; dctx->ctx_List_New = &debug_ctx_List_New; dctx->ctx_List_Append = &debug_ctx_List_Append; + dctx->ctx_List_Insert = &debug_ctx_List_Insert; dctx->ctx_Dict_Check = &debug_ctx_Dict_Check; dctx->ctx_Dict_New = &debug_ctx_Dict_New; dctx->ctx_Dict_Keys = &debug_ctx_Dict_Keys; dctx->ctx_Dict_Copy = &debug_ctx_Dict_Copy; dctx->ctx_Tuple_Check = &debug_ctx_Tuple_Check; dctx->ctx_Tuple_FromArray = &debug_ctx_Tuple_FromArray; + dctx->ctx_Slice_New = &debug_ctx_Slice_New; dctx->ctx_Slice_Unpack = &debug_ctx_Slice_Unpack; dctx->ctx_Import_ImportModule = &debug_ctx_Import_ImportModule; dctx->ctx_Capsule_New = &debug_ctx_Capsule_New; diff --git a/graalpython/com.oracle.graal.python.jni/src/debug/autogen_debug_wrappers.c b/graalpython/hpy/hpy/debug/src/autogen_debug_wrappers.c similarity index 94% rename from graalpython/com.oracle.graal.python.jni/src/debug/autogen_debug_wrappers.c rename to graalpython/hpy/hpy/debug/src/autogen_debug_wrappers.c index c4337edee4..e9eb6a15c3 100644 --- a/graalpython/com.oracle.graal.python.jni/src/debug/autogen_debug_wrappers.c +++ b/graalpython/hpy/hpy/debug/src/autogen_debug_wrappers.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /* DO NOT EDIT THIS FILE! @@ -755,6 +731,42 @@ DHPy debug_ctx_CallTupleDict(HPyContext *dctx, DHPy callable, DHPy args, DHPy kw return DHPy_open(dctx, universal_result); } +DHPy debug_ctx_GetIter(HPyContext *dctx, DHPy obj) +{ + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_GetIter(get_info(dctx)->uctx, dh_obj); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); +} + +DHPy debug_ctx_Iter_Next(HPyContext *dctx, DHPy obj) +{ + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyIter_Next(get_info(dctx)->uctx, dh_obj); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); +} + +int debug_ctx_Iter_Check(HPyContext *dctx, DHPy obj) +{ + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPyIter_Check(get_info(dctx)->uctx, dh_obj); + get_ctx_info(dctx)->is_valid = true; + return universal_result; +} + void debug_ctx_FatalError(HPyContext *dctx, const char *message) { if (!get_ctx_info(dctx)->is_valid) { @@ -1031,6 +1043,18 @@ DHPy debug_ctx_GetItem_s(HPyContext *dctx, DHPy obj, const char *utf8_key) return DHPy_open(dctx, universal_result); } +DHPy debug_ctx_GetSlice(HPyContext *dctx, DHPy obj, HPy_ssize_t start, HPy_ssize_t end) +{ + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_GetSlice(get_info(dctx)->uctx, dh_obj, start, end); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); +} + int debug_ctx_Contains(HPyContext *dctx, DHPy container, DHPy key) { if (!get_ctx_info(dctx)->is_valid) { @@ -1084,6 +1108,19 @@ int debug_ctx_SetItem_s(HPyContext *dctx, DHPy obj, const char *utf8_key, DHPy v return universal_result; } +int debug_ctx_SetSlice(HPyContext *dctx, DHPy obj, HPy_ssize_t start, HPy_ssize_t end, DHPy value) +{ + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + HPy dh_value = DHPy_unwrap(dctx, value); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_SetSlice(get_info(dctx)->uctx, dh_obj, start, end, dh_value); + get_ctx_info(dctx)->is_valid = true; + return universal_result; +} + int debug_ctx_DelItem(HPyContext *dctx, DHPy obj, DHPy key) { if (!get_ctx_info(dctx)->is_valid) { @@ -1121,6 +1158,18 @@ int debug_ctx_DelItem_s(HPyContext *dctx, DHPy obj, const char *utf8_key) return universal_result; } +int debug_ctx_DelSlice(HPyContext *dctx, DHPy obj, HPy_ssize_t start, HPy_ssize_t end) +{ + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_DelSlice(get_info(dctx)->uctx, dh_obj, start, end); + get_ctx_info(dctx)->is_valid = true; + return universal_result; +} + DHPy debug_ctx_Type(HPyContext *dctx, DHPy obj) { if (!get_ctx_info(dctx)->is_valid) { @@ -1500,6 +1549,19 @@ int debug_ctx_List_Append(HPyContext *dctx, DHPy h_list, DHPy h_item) return universal_result; } +int debug_ctx_List_Insert(HPyContext *dctx, DHPy h_list, HPy_ssize_t index, DHPy h_item) +{ + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h_list = DHPy_unwrap(dctx, h_list); + HPy dh_h_item = DHPy_unwrap(dctx, h_item); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPyList_Insert(get_info(dctx)->uctx, dh_h_list, index, dh_h_item); + get_ctx_info(dctx)->is_valid = true; + return universal_result; +} + int debug_ctx_Dict_Check(HPyContext *dctx, DHPy h) { if (!get_ctx_info(dctx)->is_valid) { @@ -1559,6 +1621,20 @@ int debug_ctx_Tuple_Check(HPyContext *dctx, DHPy h) return universal_result; } +DHPy debug_ctx_Slice_New(HPyContext *dctx, DHPy start, DHPy stop, DHPy step) +{ + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_start = DHPy_unwrap(dctx, start); + HPy dh_stop = DHPy_unwrap(dctx, stop); + HPy dh_step = DHPy_unwrap(dctx, step); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPySlice_New(get_info(dctx)->uctx, dh_start, dh_stop, dh_step); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); +} + int debug_ctx_Slice_Unpack(HPyContext *dctx, DHPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step) { if (!get_ctx_info(dctx)->is_valid) { diff --git a/graalpython/com.oracle.graal.python.jni/src/debug/debug_ctx.c b/graalpython/hpy/hpy/debug/src/debug_ctx.c similarity index 83% rename from graalpython/com.oracle.graal.python.jni/src/debug/debug_ctx.c rename to graalpython/hpy/hpy/debug/src/debug_ctx.c index bb02fa5588..de661ea2c9 100644 --- a/graalpython/com.oracle.graal.python.jni/src/debug/debug_ctx.c +++ b/graalpython/hpy/hpy/debug/src/debug_ctx.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #include #include #include "debug_internal.h" @@ -31,6 +7,12 @@ # include /* for alloca() */ #endif +static struct _HPyContext_s g_debug_ctx = { + .name = "HPy Debug Mode ABI", + ._private = NULL, + .abi_version = HPY_ABI_VERSION, +}; + static HPyDebugCtxInfo *init_ctx_info(HPyContext *dctx, HPyContext *uctx) { HPyDebugCtxInfo *ctx_info = (HPyDebugCtxInfo*) malloc(sizeof(HPyDebugCtxInfo)); if (ctx_info == NULL) { @@ -71,7 +53,7 @@ static int init_dctx_cache(HPyContext *dctx, HPyDebugInfo *info) { // same. If/when we migrate to a system in which we can have multiple // independent contexts, this function should ensure to create a different // debug wrapper for each of them. -_HPy_HIDDEN int hpy_debug_ctx_init(HPyContext *dctx, HPyContext *uctx) +int hpy_debug_ctx_init(HPyContext *dctx, HPyContext *uctx) { if (dctx->_private != NULL) { // already initialized @@ -109,9 +91,23 @@ _HPy_HIDDEN int hpy_debug_ctx_init(HPyContext *dctx, HPyContext *uctx) return 0; } -_HPy_HIDDEN void hpy_debug_ctx_free(HPyContext *dctx) +HPyContext * hpy_debug_get_ctx(HPyContext *uctx) { - free(dctx->_private); + HPyContext *dctx = &g_debug_ctx; + if (uctx == dctx) { + HPy_FatalError(uctx, "hpy_debug_get_ctx: expected an universal ctx, " + "got a debug ctx"); + } + if (hpy_debug_ctx_init(dctx, uctx) < 0) { + HPyErr_SetString(uctx, uctx->h_SystemError, "Could not create debug context"); + return NULL; + } + return dctx; +} + +void hpy_debug_set_ctx(HPyContext *dctx) +{ + g_debug_ctx = *dctx; } HPy hpy_debug_open_handle(HPyContext *dctx, HPy uh) @@ -131,10 +127,11 @@ void hpy_debug_close_handle(HPyContext *dctx, HPy dh) // this function is supposed to be called from gdb: it tries to determine // whether a handle is universal or debug by looking at the last bit +extern struct _HPyContext_s g_universal_ctx; #ifndef _MSC_VER __attribute__((unused)) #endif -static void hpy_magic_dump(HPyContext *uctx, HPy h) +static void hpy_magic_dump(HPy h) { int universal = h._i & 1; if (universal) @@ -148,7 +145,7 @@ static void hpy_magic_dump(HPyContext *uctx, HPy h) fprintf(stderr, "raw value: %lx (%ld)\n", h._i, h._i); #endif if (universal) - _HPy_Dump(uctx, h); + _HPy_Dump(&g_universal_ctx, h); else { DebugHandle *dh = as_DebugHandle(h); #ifdef _MSC_VER @@ -156,7 +153,7 @@ static void hpy_magic_dump(HPyContext *uctx, HPy h) #else fprintf(stderr, "dh->uh: %lx\n", dh->uh._i); #endif - _HPy_Dump(uctx, dh->uh); + _HPy_Dump(&g_universal_ctx, dh->uh); } } @@ -259,7 +256,7 @@ const char *debug_ctx_Bytes_AS_STRING(HPyContext *dctx, DHPy h) return (const char *)protect_and_associate_data_ptr(h, (void *)ptr, data_size); } -DHPy debug_ctx_Tuple_FromArray(HPyContext *dctx, DHPy dh_items[], HPy_ssize_t n) +DHPy debug_ctx_Tuple_FromArray(HPyContext *dctx, const DHPy dh_items[], HPy_ssize_t n) { if (!get_ctx_info(dctx)->is_valid) { report_invalid_debug_context(); @@ -331,6 +328,7 @@ static const char *get_builtin_shape_name(HPyType_BuiltinShape shape) SHAPE_NAME(HPyType_BuiltinShape_Unicode) SHAPE_NAME(HPyType_BuiltinShape_Tuple) SHAPE_NAME(HPyType_BuiltinShape_List) + SHAPE_NAME(HPyType_BuiltinShape_Dict) } return ""; #undef SHAPE_NAME @@ -375,8 +373,78 @@ MAKE_debug_ctx_AsStruct(Tuple) MAKE_debug_ctx_AsStruct(List) -/* ~~~ debug mode implementation of HPyTracker ~~~ */ -/* MOVED TO file 'debug_ctx_tracker.c' */ +MAKE_debug_ctx_AsStruct(Dict) + +/* ~~~ debug mode implementation of HPyTracker ~~~ + + This is a bit special and it's worth explaining what is going on. + + The HPyTracker functions need their own debug mode implementation because + the debug mode needs to be aware of when a DHPy is closed, for the same + reason for why we need debug_ctx_Close. + + So, in theory here we should have our own implementation of a + DebugHPyTracker which manages a growable list of handles, and which calls + debug_ctx_Close at the end. But, we ALREADY have the logic available, it's + implemented in ctx_tracker.c. + + So, here we simply implement debug_ctx_Tracker_* in terms of ctx_Tracker_*: + but note that it's VERY different than what the autogen wrappers do: + + - the autogen wrappers DHPy_unwrap() all the handles before calling the + "super" implementation. Here we don't, we pass the DHPys directly. + + - the autogen wrappers pass the uctx to the "super" implementation, here + we pass the dctx. + + Conceptually, it is equivalent to just have our own implementation of a + growable array, but by using this trick we can easily reuse the existing + code. + + It is better understood if you think of what happens on PyPy (or any other + universal implementation): normally, on PyPy HPyTracker_Add calls PyPy's + own implementation (see interp_tracker.py). But when in debug mode, + HPyTracker_Add will call the ctx_Tracker_Add defined in ctx_tracker.c, + completely bypassing PyPy's own tracker (which is fine). Incidentally, this + also means that if PyPy wants to bundle the debug mode, it also needs to + compile ctx_tracker.c +*/ + +HPyTracker debug_ctx_Tracker_New(HPyContext *dctx, HPy_ssize_t size) +{ + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + return ctx_Tracker_New(dctx, size); +} + +int debug_ctx_Tracker_Add(HPyContext *dctx, HPyTracker ht, DHPy dh) +{ + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + return ctx_Tracker_Add(dctx, ht, dh); +} + +void debug_ctx_Tracker_ForgetAll(HPyContext *dctx, HPyTracker ht) +{ + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + ctx_Tracker_ForgetAll(dctx, ht); +} + +void debug_ctx_Tracker_Close(HPyContext *dctx, HPyTracker ht) +{ + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + // note: ctx_Tracker_Close internally calls HPy_Close() to close each + // handle: since we are calling it with the dctx, it will end up calling + // debug_ctx_Close, which is exactly what we need to properly record that + // the handles were closed. + ctx_Tracker_Close(dctx, ht); +} HPyListBuilder debug_ctx_ListBuilder_New(HPyContext *dctx, HPy_ssize_t size) { diff --git a/graalpython/hpy/hpy/debug/src/debug_ctx_cpython.c b/graalpython/hpy/hpy/debug/src/debug_ctx_cpython.c new file mode 100644 index 0000000000..01d9c64788 --- /dev/null +++ b/graalpython/hpy/hpy/debug/src/debug_ctx_cpython.c @@ -0,0 +1,299 @@ +/* =========== CPython-ONLY =========== + In the following code, we use _py2h and _h2py and we assumed they are the + ones defined by CPython's version of hpy.universal. + + DO NOT COMPILE THIS FILE UNLESS YOU ARE BUILDING CPython's hpy.universal. + + If you want to compile the debug mode into your own non-CPython version of + hpy.universal, you should include debug_ctx_not_cpython.c. + ==================================== + + In theory, the debug mode is completely generic and can wrap a generic + uctx. However, CPython is special because it does not have native support + for HPy, so uctx contains the logic to call HPy functions from CPython, by + using _HPy_CallRealFunctionFromTrampoline. + + uctx->ctx_CallRealFunctionFromTrampoline converts PyObject* into UHPy. So + for the debug mode we need to: + + 1. convert the PyObject* args into UHPys. + 2. wrap the UHPys into DHPys. + 3. unwrap the resulting DHPy and convert to PyObject*. +*/ + +#include +#include "debug_internal.h" +#include "hpy/runtime/ctx_type.h" // for call_traverseproc_from_trampoline +#include "hpy/runtime/ctx_module.h" +#include "handles.h" // for _py2h and _h2py + +#if defined(_MSC_VER) +# include /* for alloca() */ +#endif + +static inline DHPy _py2dh(HPyContext *dctx, PyObject *obj) +{ + return DHPy_open(dctx, _py2h(obj)); +} + +static inline PyObject *_dh2py(HPyContext *dctx, DHPy dh) +{ + return _h2py(DHPy_unwrap(dctx, dh)); +} + +static void _buffer_h2py(HPyContext *dctx, const HPy_buffer *src, Py_buffer *dest) +{ + dest->buf = src->buf; + dest->obj = HPy_AsPyObject(dctx, src->obj); + dest->len = src->len; + dest->itemsize = src->itemsize; + dest->readonly = src->readonly; + dest->ndim = src->ndim; + dest->format = src->format; + dest->shape = src->shape; + dest->strides = src->strides; + dest->suboffsets = src->suboffsets; + dest->internal = src->internal; +} + +static void _buffer_py2h(HPyContext *dctx, const Py_buffer *src, HPy_buffer *dest) +{ + dest->buf = src->buf; + dest->obj = HPy_FromPyObject(dctx, src->obj); + dest->len = src->len; + dest->itemsize = src->itemsize; + dest->readonly = src->readonly; + dest->ndim = src->ndim; + dest->format = src->format; + dest->shape = src->shape; + dest->strides = src->strides; + dest->suboffsets = src->suboffsets; + dest->internal = src->internal; +} + +static HPyContext* _switch_to_next_dctx_from_cache(HPyContext *current_dctx) { + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(current_dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(current_dctx); + get_ctx_info(current_dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + return NULL; + } + get_ctx_info(current_dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + return next_dctx; +} + +static void _switch_back_to_original_dctx(HPyContext *original_dctx, HPyContext *next_dctx) { + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(original_dctx)->is_valid = true; +} + +void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, + HPyFunc_Signature sig, + void *func, void *args) +{ + switch (sig) { + case HPyFunc_VARARGS: { + HPyFunc_varargs f = (HPyFunc_varargs)func; + _HPyFunc_args_VARARGS *a = (_HPyFunc_args_VARARGS*)args; + DHPy dh_self = _py2dh(dctx, a->self); + DHPy *dh_args = (DHPy *)alloca(a->nargs * sizeof(DHPy)); + for (HPy_ssize_t i = 0; i < a->nargs; i++) { + dh_args[i] = _py2dh(dctx, a->args[i]); + } + + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + + DHPy dh_result = f(next_dctx, dh_self, dh_args, a->nargs); + + _switch_back_to_original_dctx(dctx, next_dctx); + + DHPy_close_and_check(dctx, dh_self); + for (HPy_ssize_t i = 0; i < a->nargs; i++) { + DHPy_close_and_check(dctx, dh_args[i]); + } + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_KEYWORDS: { + HPyFunc_keywords f = (HPyFunc_keywords)func; + _HPyFunc_args_KEYWORDS *a = (_HPyFunc_args_KEYWORDS*)args; + DHPy dh_self = _py2dh(dctx, a->self); + size_t n_kwnames = a->kwnames != NULL ? PyTuple_GET_SIZE(a->kwnames) : 0; + size_t nargs = PyVectorcall_NARGS(a->nargsf); + size_t nargs_with_kw = nargs + n_kwnames; + DHPy *dh_args = (DHPy *)alloca(nargs_with_kw * sizeof(DHPy)); + for (size_t i = 0; i < nargs_with_kw; i++) { + dh_args[i] = _py2dh(dctx, a->args[i]); + } + DHPy dh_kwnames = _py2dh(dctx, a->kwnames); + + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + + DHPy dh_result = f(next_dctx, dh_self, dh_args, nargs, dh_kwnames); + + _switch_back_to_original_dctx(dctx, next_dctx); + + DHPy_close_and_check(dctx, dh_self); + for (size_t i = 0; i < nargs_with_kw; i++) { + DHPy_close_and_check(dctx, dh_args[i]); + } + DHPy_close_and_check(dctx, dh_kwnames); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_INITPROC: { + HPyFunc_initproc f = (HPyFunc_initproc)func; + _HPyFunc_args_INITPROC *a = (_HPyFunc_args_INITPROC*)args; + DHPy dh_self = _py2dh(dctx, a->self); + Py_ssize_t nargs = PyTuple_GET_SIZE(a->args); + DHPy *dh_args = (DHPy *)alloca(nargs * sizeof(DHPy)); + for (Py_ssize_t i = 0; i < nargs; i++) { + dh_args[i] = _py2dh(dctx, PyTuple_GET_ITEM(a->args, i)); + } + DHPy dh_kw = _py2dh(dctx, a->kw); + + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = -1; + return; + } + + a->result = f(next_dctx, dh_self, dh_args, nargs, dh_kw); + + _switch_back_to_original_dctx(dctx, next_dctx); + + DHPy_close_and_check(dctx, dh_self); + for (Py_ssize_t i = 0; i < nargs; i++) { + DHPy_close_and_check(dctx, dh_args[i]); + } + DHPy_close_and_check(dctx, dh_kw); + return; + } + case HPyFunc_NEWFUNC: { + HPyFunc_newfunc f = (HPyFunc_newfunc)func; + _HPyFunc_args_NEWFUNC *a = (_HPyFunc_args_NEWFUNC*)args; + DHPy dh_self = _py2dh(dctx, a->self); + Py_ssize_t nargs = PyTuple_GET_SIZE(a->args); + DHPy *dh_args = (DHPy *)alloca(nargs * sizeof(DHPy)); + for (Py_ssize_t i = 0; i < nargs; i++) { + dh_args[i] = _py2dh(dctx, PyTuple_GET_ITEM(a->args, i)); + } + DHPy dh_kw = _py2dh(dctx, a->kw); + + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = NULL; + return; + } + + DHPy dh_result = f(next_dctx, dh_self, dh_args, nargs, dh_kw); + + _switch_back_to_original_dctx(dctx, next_dctx); + + DHPy_close_and_check(dctx, dh_self); + for (Py_ssize_t i = 0; i < nargs; i++) { + DHPy_close_and_check(dctx, dh_args[i]); + } + DHPy_close_and_check(dctx, dh_kw); + a->result = _dh2py(dctx, dh_result); + DHPy_close(dctx, dh_result); + return; + } + case HPyFunc_GETBUFFERPROC: { + HPyFunc_getbufferproc f = (HPyFunc_getbufferproc)func; + _HPyFunc_args_GETBUFFERPROC *a = (_HPyFunc_args_GETBUFFERPROC*)args; + HPy_buffer hbuf; + DHPy dh_self = _py2dh(dctx, a->self); + + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = -1; + return; + } + + a->result = f(next_dctx, dh_self, &hbuf, a->flags); + + _switch_back_to_original_dctx(dctx, next_dctx); + + DHPy_close_and_check(dctx, dh_self); + if (a->result < 0) { + a->view->obj = NULL; + return; + } + _buffer_h2py(dctx, &hbuf, a->view); + HPy_Close(dctx, hbuf.obj); + return; + } + case HPyFunc_RELEASEBUFFERPROC: { + HPyFunc_releasebufferproc f = (HPyFunc_releasebufferproc)func; + _HPyFunc_args_RELEASEBUFFERPROC *a = (_HPyFunc_args_RELEASEBUFFERPROC*)args; + HPy_buffer hbuf; + _buffer_py2h(dctx, a->view, &hbuf); + DHPy dh_self = _py2dh(dctx, a->self); + + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + return; + } + + f(next_dctx, dh_self, &hbuf); + + _switch_back_to_original_dctx(dctx, next_dctx); + + DHPy_close_and_check(dctx, dh_self); + // XXX: copy back from hbuf? + HPy_Close(dctx, hbuf.obj); + return; + } + case HPyFunc_TRAVERSEPROC: { + HPyFunc_traverseproc f = (HPyFunc_traverseproc)func; + _HPyFunc_args_TRAVERSEPROC *a = (_HPyFunc_args_TRAVERSEPROC*)args; + + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + a->result = -1; + return; + } + + a->result = call_traverseproc_from_trampoline(f, a->self, + a->visit, a->arg); + + _switch_back_to_original_dctx(dctx, next_dctx); + return; + } + case HPyFunc_CAPSULE_DESTRUCTOR: { + HPyFunc_Capsule_Destructor f = (HPyFunc_Capsule_Destructor)func; + PyObject *capsule = (PyObject *)args; + const char *name = PyCapsule_GetName(capsule); + f(name, PyCapsule_GetPointer(capsule, name), + PyCapsule_GetContext(capsule)); + return; + } + case HPyFunc_MOD_CREATE: { + HPyFunc_unaryfunc f = (HPyFunc_unaryfunc)func; + _HPyFunc_args_UNARYFUNC *a = (_HPyFunc_args_UNARYFUNC*)args; + DHPy dh_arg0 = _py2dh(dctx, a->arg0); + DHPy dh_result = f(dctx, dh_arg0); + DHPy_close_and_check(dctx, dh_arg0); + a->result = _dh2py(dctx, dh_result); + _HPyModule_CheckCreateSlotResult(&a->result); + DHPy_close(dctx, dh_result); + return; + } +#include "autogen_debug_ctx_call.i" + default: + Py_FatalError("Unsupported HPyFunc_Signature in debug_ctx_cpython.c"); + } +} diff --git a/graalpython/hpy/hpy/debug/src/debug_ctx_not_cpython.c b/graalpython/hpy/hpy/debug/src/debug_ctx_not_cpython.c new file mode 100644 index 0000000000..7df607ee76 --- /dev/null +++ b/graalpython/hpy/hpy/debug/src/debug_ctx_not_cpython.c @@ -0,0 +1,16 @@ +// This is for non-CPython implementations! +// +// If you want to bundle the debug mode into your own version of +// hpy.universal, make sure to compile this file and NOT debug_ctx_cpython.c + +#include "debug_internal.h" + +void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, + HPyFunc_Signature sig, + void *func, void *args) +{ + HPyContext *uctx = get_info(dctx)->uctx; + HPy_FatalError(uctx, + "Something is very wrong! _HPy_CallRealFunctionFromTrampoline() " + "should be used only by the CPython version of hpy.universal"); +} diff --git a/graalpython/com.oracle.graal.python.jni/src/debug/debug_handles.c b/graalpython/hpy/hpy/debug/src/debug_handles.c similarity index 90% rename from graalpython/com.oracle.graal.python.jni/src/debug/debug_handles.c rename to graalpython/hpy/hpy/debug/src/debug_handles.c index aaca064244..fe2d32cb7d 100644 --- a/graalpython/com.oracle.graal.python.jni/src/debug/debug_handles.c +++ b/graalpython/hpy/hpy/debug/src/debug_handles.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #include #include "debug_internal.h" diff --git a/graalpython/com.oracle.graal.python.jni/src/debug/debug_internal.h b/graalpython/hpy/hpy/debug/src/debug_internal.h similarity index 92% rename from graalpython/com.oracle.graal.python.jni/src/debug/debug_internal.h rename to graalpython/hpy/hpy/debug/src/debug_internal.h index d56861e426..af21732c7d 100644 --- a/graalpython/com.oracle.graal.python.jni/src/debug/debug_internal.h +++ b/graalpython/hpy/hpy/debug/src/debug_internal.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /* Internal header for all the files in hpy/debug/src. The public API is in include/hpy_debug.h */ diff --git a/graalpython/com.oracle.graal.python.jni/src/debug/dhqueue.c b/graalpython/hpy/hpy/debug/src/dhqueue.c similarity index 69% rename from graalpython/com.oracle.graal.python.jni/src/debug/dhqueue.c rename to graalpython/hpy/hpy/debug/src/dhqueue.c index e6875aabca..86e8c17679 100644 --- a/graalpython/com.oracle.graal.python.jni/src/debug/dhqueue.c +++ b/graalpython/hpy/hpy/debug/src/dhqueue.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #include "debug_internal.h" // TODO: we need to make DHQueue thread-safe if we want to use the same diff --git a/graalpython/com.oracle.graal.python.jni/src/debug/include/hpy_debug.h b/graalpython/hpy/hpy/debug/src/include/hpy_debug.h similarity index 64% rename from graalpython/com.oracle.graal.python.jni/src/debug/include/hpy_debug.h rename to graalpython/hpy/hpy/debug/src/include/hpy_debug.h index 858cf5960b..f2fb9471b3 100644 --- a/graalpython/com.oracle.graal.python.jni/src/debug/include/hpy_debug.h +++ b/graalpython/hpy/hpy/debug/src/include/hpy_debug.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #ifndef HPY_DEBUG_H #define HPY_DEBUG_H diff --git a/graalpython/com.oracle.graal.python.jni/src/debug/memprotect.c b/graalpython/hpy/hpy/debug/src/memprotect.c similarity index 67% rename from graalpython/com.oracle.graal.python.jni/src/debug/memprotect.c rename to graalpython/hpy/hpy/debug/src/memprotect.c index 909372b125..9f2ffe69f6 100644 --- a/graalpython/com.oracle.graal.python.jni/src/debug/memprotect.c +++ b/graalpython/hpy/hpy/debug/src/memprotect.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #include "debug_internal.h" // Implements OS dependent abstraction of memory protection diff --git a/graalpython/com.oracle.graal.python.jni/src/debug/stacktrace.c b/graalpython/hpy/hpy/debug/src/stacktrace.c similarity index 68% rename from graalpython/com.oracle.graal.python.jni/src/debug/stacktrace.c rename to graalpython/hpy/hpy/debug/src/stacktrace.c index 17e2c7f20d..cc556b3bbd 100644 --- a/graalpython/com.oracle.graal.python.jni/src/debug/stacktrace.c +++ b/graalpython/hpy/hpy/debug/src/stacktrace.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #include "debug_internal.h" #if ((__linux__ && __GNU_LIBRARY__) || __APPLE__) @@ -115,4 +91,4 @@ void create_stacktrace(char **target, HPy_ssize_t max_frames_count) { memcpy(*target, msg, sizeof(msg)); } -#endif +#endif \ No newline at end of file diff --git a/graalpython/lib-graalpython/modules/hpy/devel/__init__.py b/graalpython/hpy/hpy/devel/__init__.py similarity index 89% rename from graalpython/lib-graalpython/modules/hpy/devel/__init__.py rename to graalpython/hpy/hpy/devel/__init__.py index a54ba1fd56..3b7f6e6d18 100644 --- a/graalpython/lib-graalpython/modules/hpy/devel/__init__.py +++ b/graalpython/hpy/hpy/devel/__init__.py @@ -1,25 +1,5 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. +# NOTE: this file is also imported by PyPy tests, so it must be compatible +# with both Python 2.7 and Python 3.x import sys import os.path @@ -33,6 +13,15 @@ # But this file needs to be importable also in py27 (for pypy tests), and we # don't care about setuptools version in that case. import setuptools +import distutils +if (sys.version_info.major > 2 and + distutils is not getattr(setuptools, '_distutils', None)): + raise Exception( + "setuptools' monkey-patching of distutils did not work. " + "Most likely this is caused by:\n" + " - a too old setuptools. Try installing setuptools>=60.2\n" + " - the env variable SETUPTOOLS_USE_DISTUTILS=stdlib. Try to unset it." + ) from distutils import log from distutils.errors import DistutilsError import setuptools.command as cmd @@ -124,27 +113,6 @@ def get_ctx_sources(self): """ return list(map(str, self.src_dir.glob('ctx_*.c'))) - @staticmethod - def _ctx_lib_needsBuild(sources, ctx_lib): - return True - if not os.path.exists(ctx_lib): - log.debug("Building %s (did not exist)", ctx_lib) - return True - # Compare timestamps; if any sources is newer than 'ctx_lib' -> rebuild - ts_newest_source = 0 - newest_source_file = None - for f in sources: - ts = os.path.getmtime(f) - if ts_newest_source < ts: - ts_newest_source = ts - newest_source_file = f - ts_lib = os.path.getmtime(ctx_lib) - if ts_lib < ts_newest_source: - log.debug("Rebuild needed for %s (%s newer than %s)", ctx_lib, newest_source_file, ts_lib) - return True - log.debug("%s is up-to-date", ctx_lib) - return False - def fix_distribution(self, dist): """ Override build_ext to support hpy modules. @@ -460,7 +428,7 @@ def write_stub(self, output_dir, ext, compile=False): ext_file = os.path.basename(ext._file_name) module_name = ext_file.split(".")[0] if not self.dry_run: - with open(stub_file, 'w') as f: + with open(stub_file, 'w', encoding='utf-8') as f: f.write(_HPY_UNIVERSAL_MODULE_STUB_TEMPLATE.format( ext_file=ext_file, module_name=module_name) ) diff --git a/graalpython/lib-graalpython/modules/hpy/devel/abitag.py b/graalpython/hpy/hpy/devel/abitag.py similarity index 67% rename from graalpython/lib-graalpython/modules/hpy/devel/abitag.py rename to graalpython/hpy/hpy/devel/abitag.py index 2bd61fd697..2d31668d02 100644 --- a/graalpython/lib-graalpython/modules/hpy/devel/abitag.py +++ b/graalpython/hpy/hpy/devel/abitag.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - import sys from distutils import sysconfig diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy.h b/graalpython/hpy/hpy/devel/include/hpy.h similarity index 82% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy.h rename to graalpython/hpy/hpy/devel/include/hpy.h index 46afd8ee05..17509d5c7e 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy.h +++ b/graalpython/hpy/hpy/devel/include/hpy.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #ifndef HPy_H #define HPy_H #ifdef __cplusplus @@ -209,7 +185,6 @@ extern "C" { - Debug mode: _i is a pointer to a DebugHandle, which contains a another HPy among other stuff */ -#ifndef GRAALVM_PYTHON_LLVM typedef struct _HPy_s { intptr_t _i; } HPy; typedef struct { intptr_t _i; } HPyField; typedef struct { intptr_t _i; } HPyGlobal; @@ -217,29 +192,12 @@ typedef struct { intptr_t _lst; } HPyListBuilder; typedef struct { intptr_t _tup; } HPyTupleBuilder; typedef struct { intptr_t _i; } HPyTracker; typedef struct { intptr_t _i; } HPyThreadState; -#else -typedef struct _HPy_s { void* _i; } HPy; -typedef struct { void* _i; } HPyField; -typedef struct { void* _i; } HPyGlobal; -typedef struct { void* _lst; } HPyListBuilder; -typedef struct { void* _tup; } HPyTupleBuilder; -typedef struct { void* _i; } HPyTracker; -typedef struct { void* _i; } HPyThreadState; -#endif /* A null handle is officially defined as a handle whose _i is 0. This is true in all ABI modes. */ -#ifndef GRAALVM_PYTHON_LLVM #define HPy_NULL _hconv(0) #define HPy_IsNull(h) ((h)._i == 0) -#else -#define HPy_NULL _hconv(NULL) -#define HPy_IsNull(h) ((h)._i == NULL) -#endif - -#define HPyListBuilder_IsNull(h) ((h)._lst == 0) -#define HPyTupleBuilder_IsNull(h) ((h)._tup == 0) #define HPyField_NULL _hfconv(0) #define HPyField_IsNull(f) ((f)._i == 0) @@ -247,13 +205,8 @@ typedef struct { void* _i; } HPyThreadState; /* Convenience functions to cast between HPy and void*. We need to decide whether these are part of the official API or not, and maybe introduce a better naming convention. For now, they are needed for ujson. */ -#ifndef GRAALVM_PYTHON_LLVM static inline HPy HPy_FromVoidP(void *p) { return _hconv((intptr_t)p); } static inline void* HPy_AsVoidP(HPy h) { return (void*)h._i; } -#else -static inline HPy HPy_FromVoidP(void *p) { return _hconv(p); } -static inline void* HPy_AsVoidP(HPy h) { return h._i; } -#endif /* ~~~~~~~~~~~~~~~~ Definition of other types ~~~~~~~~~~~~~~~~ */ diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/autogen_hpyfunc_declare.h b/graalpython/hpy/hpy/devel/include/hpy/autogen_hpyfunc_declare.h similarity index 84% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/autogen_hpyfunc_declare.h rename to graalpython/hpy/hpy/devel/include/hpy/autogen_hpyfunc_declare.h index ab9ac55e5e..334a36f8d1 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/autogen_hpyfunc_declare.h +++ b/graalpython/hpy/hpy/devel/include/hpy/autogen_hpyfunc_declare.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /* DO NOT EDIT THIS FILE! diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/autogen_hpyslot.h b/graalpython/hpy/hpy/devel/include/hpy/autogen_hpyslot.h similarity index 81% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/autogen_hpyslot.h rename to graalpython/hpy/hpy/devel/include/hpy/autogen_hpyslot.h index 6d04c4f27a..117e6ccae0 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/autogen_hpyslot.h +++ b/graalpython/hpy/hpy/devel/include/hpy/autogen_hpyslot.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /* DO NOT EDIT THIS FILE! @@ -82,6 +58,7 @@ typedef enum { HPy_sq_length = 45, HPy_sq_repeat = 46, HPy_tp_call = 50, + HPy_tp_descr_get = 54, HPy_tp_hash = 59, HPy_tp_init = 60, HPy_tp_new = 65, @@ -144,6 +121,7 @@ typedef enum { #define _HPySlot_SIG__HPy_sq_length HPyFunc_LENFUNC #define _HPySlot_SIG__HPy_sq_repeat HPyFunc_SSIZEARGFUNC #define _HPySlot_SIG__HPy_tp_call HPyFunc_KEYWORDS +#define _HPySlot_SIG__HPy_tp_descr_get HPyFunc_TERNARYFUNC #define _HPySlot_SIG__HPy_tp_hash HPyFunc_HASHFUNC #define _HPySlot_SIG__HPy_tp_init HPyFunc_INITPROC #define _HPySlot_SIG__HPy_tp_new HPyFunc_NEWFUNC diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpy_types.h b/graalpython/hpy/hpy/devel/include/hpy/cpy_types.h similarity index 61% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpy_types.h rename to graalpython/hpy/hpy/devel/include/hpy/cpy_types.h index fd2efc7ad8..4c59f5e84e 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpy_types.h +++ b/graalpython/hpy/hpy/devel/include/hpy/cpy_types.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #ifndef HPY_UNIVERSAL_CPY_TYPES_H #define HPY_UNIVERSAL_CPY_TYPES_H diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/autogen_api_impl.h b/graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_api_impl.h similarity index 91% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/autogen_api_impl.h rename to graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_api_impl.h index 9016982e7a..4a55fc6dc6 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/autogen_api_impl.h +++ b/graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_api_impl.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /* DO NOT EDIT THIS FILE! @@ -264,6 +240,21 @@ HPyAPI_FUNC int HPyCallable_Check(HPyContext *ctx, HPy h) return PyCallable_Check(_h2py(h)); } +HPyAPI_FUNC HPy HPy_GetIter(HPyContext *ctx, HPy obj) +{ + return _py2h(PyObject_GetIter(_h2py(obj))); +} + +HPyAPI_FUNC HPy HPyIter_Next(HPyContext *ctx, HPy obj) +{ + return _py2h(PyIter_Next(_h2py(obj))); +} + +HPyAPI_FUNC int HPyIter_Check(HPyContext *ctx, HPy obj) +{ + return PyIter_Check(_h2py(obj)); +} + HPyAPI_FUNC HPy HPyErr_SetString(HPyContext *ctx, HPy h_type, const char *utf8_message) { PyErr_SetString(_h2py(h_type), utf8_message); @@ -363,6 +354,11 @@ HPyAPI_FUNC HPy HPy_GetItem(HPyContext *ctx, HPy obj, HPy key) return _py2h(PyObject_GetItem(_h2py(obj), _h2py(key))); } +HPyAPI_FUNC HPy HPy_GetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) +{ + return _py2h(PySequence_GetSlice(_h2py(obj), start, end)); +} + HPyAPI_FUNC int HPy_Contains(HPyContext *ctx, HPy container, HPy key) { return PySequence_Contains(_h2py(container), _h2py(key)); @@ -373,14 +369,19 @@ HPyAPI_FUNC int HPy_SetItem(HPyContext *ctx, HPy obj, HPy key, HPy value) return PyObject_SetItem(_h2py(obj), _h2py(key), _h2py(value)); } +HPyAPI_FUNC int HPy_SetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end, HPy value) +{ + return PySequence_SetSlice(_h2py(obj), start, end, _h2py(value)); +} + HPyAPI_FUNC int HPy_DelItem(HPyContext *ctx, HPy obj, HPy key) { return PyObject_DelItem(_h2py(obj), _h2py(key)); } -HPyAPI_FUNC HPy HPy_Type(HPyContext *ctx, HPy obj) +HPyAPI_FUNC int HPy_DelSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) { - return _py2h(PyObject_Type(_h2py(obj))); + return PySequence_DelSlice(_h2py(obj), start, end); } HPyAPI_FUNC HPy HPy_Repr(HPyContext *ctx, HPy obj) @@ -538,6 +539,11 @@ HPyAPI_FUNC int HPyList_Append(HPyContext *ctx, HPy h_list, HPy h_item) return PyList_Append(_h2py(h_list), _h2py(h_item)); } +HPyAPI_FUNC int HPyList_Insert(HPyContext *ctx, HPy h_list, HPy_ssize_t index, HPy h_item) +{ + return PyList_Insert(_h2py(h_list), index, _h2py(h_item)); +} + HPyAPI_FUNC int HPyDict_Check(HPyContext *ctx, HPy h) { return PyDict_Check(_h2py(h)); @@ -563,6 +569,11 @@ HPyAPI_FUNC int HPyTuple_Check(HPyContext *ctx, HPy h) return PyTuple_Check(_h2py(h)); } +HPyAPI_FUNC HPy HPySlice_New(HPyContext *ctx, HPy start, HPy stop, HPy step) +{ + return _py2h(PySlice_New(_h2py(start), _h2py(stop), _h2py(step))); +} + HPyAPI_FUNC int HPySlice_Unpack(HPyContext *ctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step) { return PySlice_Unpack(_h2py(slice), start, stop, step); diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/autogen_ctx.h b/graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_ctx.h similarity index 66% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/autogen_ctx.h rename to graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_ctx.h index a8d028f081..6f9fb0d7dc 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/autogen_ctx.h +++ b/graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_ctx.h @@ -1,26 +1,3 @@ -/* MIT License - * - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ /* DO NOT EDIT THIS FILE! @@ -119,4 +96,5 @@ struct _HPyContext_s { HPy h_CapsuleType; HPy h_SliceType; HPy h_Builtins; + HPy h_DictType; }; diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/autogen_hpyfunc_trampolines.h b/graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_hpyfunc_trampolines.h similarity index 89% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/autogen_hpyfunc_trampolines.h rename to graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_hpyfunc_trampolines.h index df91efee3a..852268ee53 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/autogen_hpyfunc_trampolines.h +++ b/graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_hpyfunc_trampolines.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /* DO NOT EDIT THIS FILE! diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/hpyfunc_trampolines.h b/graalpython/hpy/hpy/devel/include/hpy/cpython/hpyfunc_trampolines.h similarity index 80% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/hpyfunc_trampolines.h rename to graalpython/hpy/hpy/devel/include/hpy/cpython/hpyfunc_trampolines.h index d026df297c..0e8898360e 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/hpyfunc_trampolines.h +++ b/graalpython/hpy/hpy/devel/include/hpy/cpython/hpyfunc_trampolines.h @@ -1,34 +1,6 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #ifndef HPY_CPYTHON_HPYFUNC_TRAMPOLINES_H #define HPY_CPYTHON_HPYFUNC_TRAMPOLINES_H -/* This is a GraalPy-specific accessor function for a tuple object's items - array. There is no public header for that symbol, so we define it ad-hoc. */ -extern PyObject** (*GraalPy_get_PyTupleObject_ob_item)(PyTupleObject*); - typedef HPy (*_HPyCFunction_VARARGS)(HPyContext*, HPy, const HPy *, size_t); #define _HPyFunc_TRAMPOLINE_HPyFunc_VARARGS(SYM, IMPL) \ static PyObject* \ @@ -59,7 +31,7 @@ typedef int (*_HPyCFunction_INITPROC)(HPyContext*, HPy, const HPy *, HPy_ssize_t { \ /* get the tuple elements as an array of "PyObject *", which */ \ /* is equivalent to an array of "HPy" with enough casting... */ \ - PyObject *const *items = GraalPy_get_PyTupleObject_ob_item((PyTupleObject *)args); \ + PyObject *const *items = &PyTuple_GET_ITEM(args, 0); \ Py_ssize_t nargs = PyTuple_GET_SIZE(args); \ _HPyCFunction_INITPROC func = (_HPyCFunction_INITPROC)IMPL; \ return func(_HPyGetContext(), _py2h(self), \ @@ -73,7 +45,7 @@ typedef HPy (*_HPyCFunction_NEWFUNC)(HPyContext*, HPy, const HPy *, HPy_ssize_t, { \ /* get the tuple elements as an array of "PyObject *", which */ \ /* is equivalent to an array of "HPy" with enough casting... */ \ - PyObject *const *items = GraalPy_get_PyTupleObject_ob_item((PyTupleObject *)args); \ + PyObject *const *items = &PyTuple_GET_ITEM(args, 0); \ Py_ssize_t nargs = PyTuple_GET_SIZE(args); \ _HPyCFunction_NEWFUNC func = (_HPyCFunction_NEWFUNC)IMPL; \ return _h2py(func(_HPyGetContext(), _py2h(self), \ diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/misc.h b/graalpython/hpy/hpy/devel/include/hpy/cpython/misc.h similarity index 92% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/misc.h rename to graalpython/hpy/hpy/devel/include/hpy/cpython/misc.h index 64009cfa97..6df576e7ff 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/misc.h +++ b/graalpython/hpy/hpy/devel/include/hpy/cpython/misc.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #ifndef HPY_CPYTHON_MISC_H #define HPY_CPYTHON_MISC_H @@ -34,19 +10,11 @@ static inline PyObject* _h2py(HPy h) { } static inline HPy _py2h(PyObject *o) { -#ifdef GRAALVM_PYTHON_LLVM - return _hconv((void*)o); -#else return _hconv((intptr_t)o); -#endif } static inline HPyThreadState _threads2h(PyThreadState *s) { -#ifdef GRAALVM_PYTHON_LLVM - return _htsconv((void*)s); -#else return _htsconv((intptr_t)s); -#endif } static inline PyThreadState* _h2threads(HPyThreadState h) { @@ -176,6 +144,7 @@ HPyAPI_FUNC HPyContext * _HPyGetContext(void) { ctx->h_MemoryViewType = _py2h((PyObject *)&PyMemoryView_Type); ctx->h_CapsuleType = _py2h((PyObject *)&PyCapsule_Type); ctx->h_SliceType = _py2h((PyObject *)&PySlice_Type); + ctx->h_DictType = _py2h((PyObject *)&PyDict_Type); /* Reflection */ ctx->h_Builtins = _py2h(PyEval_GetBuiltins()); } @@ -303,6 +272,11 @@ HPyAPI_FUNC void* _HPy_AsStruct_List(HPyContext *ctx, HPy h) return ctx_AsStruct_List(ctx, h); } +HPyAPI_FUNC void* _HPy_AsStruct_Dict(HPyContext *ctx, HPy h) +{ + return ctx_AsStruct_Dict(ctx, h); +} + HPyAPI_FUNC HPy HPy_CallTupleDict(HPyContext *ctx, HPy callable, HPy args, HPy kw) { return ctx_CallTupleDict(ctx, callable, args, kw); @@ -337,6 +311,13 @@ HPyAPI_FUNC void _HPy_Dump(HPyContext *ctx, HPy h) ctx_Dump(ctx, h); } +HPyAPI_FUNC HPy HPy_Type(HPyContext *ctx, HPy h_obj) +{ + PyTypeObject *tp = Py_TYPE(_h2py(h_obj)); + Py_INCREF(tp); + return _py2h((PyObject *)tp); +} + HPyAPI_FUNC int HPy_TypeCheck(HPyContext *ctx, HPy h_obj, HPy h_type) { return ctx_TypeCheck(ctx, h_obj, h_type); @@ -344,7 +325,7 @@ HPyAPI_FUNC int HPy_TypeCheck(HPyContext *ctx, HPy h_obj, HPy h_type) HPyAPI_FUNC int HPy_Is(HPyContext *ctx, HPy h_obj, HPy h_other) { - return ctx_Is(ctx, h_obj, h_other); + return _h2py(h_obj) == _h2py(h_other); } HPyAPI_FUNC HPyListBuilder HPyListBuilder_New(HPyContext *ctx, HPy_ssize_t initial_size) diff --git a/graalpython/hpy/hpy/devel/include/hpy/forbid_python_h/Python.h b/graalpython/hpy/hpy/devel/include/hpy/forbid_python_h/Python.h new file mode 100644 index 0000000000..ba44575650 --- /dev/null +++ b/graalpython/hpy/hpy/devel/include/hpy/forbid_python_h/Python.h @@ -0,0 +1,6 @@ +// sanity check +#ifndef HPY_ABI_UNIVERSAL +# error "Internal HPy error, something is wrong with your build system. The directory hpy/forbid_python_h has been added to the include_dirs but the target ABI does not seems to be 'universal'" +#endif + +#error "It is forbidden to #include when targeting the HPy Universal ABI" diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpydef.h b/graalpython/hpy/hpy/devel/include/hpy/hpydef.h similarity index 93% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpydef.h rename to graalpython/hpy/hpy/devel/include/hpy/hpydef.h index 6fce75b944..db45de2e80 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpydef.h +++ b/graalpython/hpy/hpy/devel/include/hpy/hpydef.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #ifndef HPY_UNIVERSAL_HPYDEF_H #define HPY_UNIVERSAL_HPYDEF_H #ifdef __cplusplus @@ -34,7 +10,7 @@ extern "C" { #include "hpy/autogen_hpyslot.h" #include "hpy/cpy_types.h" -typedef void* (*HPyCFunction)(); +typedef void* (*HPyCFunction)(void); typedef void (*HPyFunc_Capsule_Destructor)(const char *name, void *pointer, void *context); /** diff --git a/graalpython/hpy/hpy/devel/include/hpy/hpyexports.h b/graalpython/hpy/hpy/devel/include/hpy/hpyexports.h new file mode 100644 index 0000000000..9e28d854b2 --- /dev/null +++ b/graalpython/hpy/hpy/devel/include/hpy/hpyexports.h @@ -0,0 +1,13 @@ +#ifndef HPy_EXPORTS_H +#define HPy_EXPORTS_H + +// Copied from Python's exports.h +#ifndef HPy_EXPORTED_SYMBOL + #if defined(_WIN32) || defined(__CYGWIN__) + #define HPy_EXPORTED_SYMBOL __declspec(dllexport) + #else + #define HPy_EXPORTED_SYMBOL __attribute__ ((visibility ("default"))) + #endif +#endif + +#endif /* HPy_EXPORTS_H */ diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpyfunc.h b/graalpython/hpy/hpy/devel/include/hpy/hpyfunc.h similarity index 76% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpyfunc.h rename to graalpython/hpy/hpy/devel/include/hpy/hpyfunc.h index a11db14e7f..4a15a34523 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpyfunc.h +++ b/graalpython/hpy/hpy/devel/include/hpy/hpyfunc.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #ifndef HPY_UNIVERSAL_HPYFUNC_H #define HPY_UNIVERSAL_HPYFUNC_H diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpymodule.h b/graalpython/hpy/hpy/devel/include/hpy/hpymodule.h similarity index 82% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpymodule.h rename to graalpython/hpy/hpy/devel/include/hpy/hpymodule.h index 4badb12cfa..fc6a72f608 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpymodule.h +++ b/graalpython/hpy/hpy/devel/include/hpy/hpymodule.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #ifndef HPY_UNIVERSAL_HPYMODULE_H #define HPY_UNIVERSAL_HPYMODULE_H @@ -153,17 +129,23 @@ typedef struct { */ #define HPy_MODINIT(ext_name, mod_def) \ HPy_EXPORTED_FUNC uint32_t \ - get_required_hpy_major_version_##ext_name() \ + get_required_hpy_major_version_##ext_name(void); \ + uint32_t \ + get_required_hpy_major_version_##ext_name(void) \ { \ return HPY_ABI_VERSION; \ } \ HPy_EXPORTED_FUNC uint32_t \ - get_required_hpy_minor_version_##ext_name() \ + get_required_hpy_minor_version_##ext_name(void); \ + uint32_t \ + get_required_hpy_minor_version_##ext_name(void) \ { \ return HPY_ABI_VERSION_MINOR; \ } \ _HPy_CTX_MODIFIER HPyContext *_ctx_for_trampolines; \ HPy_EXPORTED_FUNC void \ + HPyInitGlobalContext_##ext_name(HPyContext *ctx); \ + void \ HPyInitGlobalContext_##ext_name(HPyContext *ctx) \ { \ _ctx_for_trampolines = ctx; \ diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpytype.h b/graalpython/hpy/hpy/devel/include/hpy/hpytype.h similarity index 90% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpytype.h rename to graalpython/hpy/hpy/devel/include/hpy/hpytype.h index 38a0a301a7..167bd6def5 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpytype.h +++ b/graalpython/hpy/hpy/devel/include/hpy/hpytype.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #ifndef HPY_UNIVERSAL_HPYTYPE_H #define HPY_UNIVERSAL_HPYTYPE_H @@ -97,6 +73,12 @@ typedef enum { * need to specify base class ``ctx->h_ListType``. */ HPyType_BuiltinShape_List = 6, + + /** + * The type inherits from built-in type ``dict``. If using this shape, you + * need to specify base class ``ctx->h_DictType``. + */ + HPyType_BuiltinShape_Dict = 7, } HPyType_BuiltinShape; typedef struct { @@ -226,7 +208,16 @@ typedef struct { #define HPy_TPFLAGS_HAVE_GC (1UL << 14) /** Convenience macro which is equivalent to: - ``HPyType_HELPERS(TYPE, HPyType_BuiltinShape_Legacy)`` */ + ``HPyType_HELPERS(TYPE, HPyType_BuiltinShape_Legacy)`` + For instance, HPyType_LEGACY_HELPERS(DummyMeta) will produce:: + + enum { DummyMeta_SHAPE = (int)HPyType_BuiltinShape_Legacy }; + __attribute__((unused)) static inline + DummyMeta * + DummyMeta_AsStruct(HPyContext *ctx, HPy h) { + return (DummyMeta *) _HPy_AsStruct_Legacy(ctx, h); + } +*/ #define HPyType_LEGACY_HELPERS(TYPE) \ HPyType_HELPERS(TYPE, HPyType_BuiltinShape_Legacy) @@ -307,5 +298,6 @@ _HPyType_HELPER_X(_HPyType_HELPER_FNAME(__VA_ARGS__))(HPyContext *ctx, HPy h) \ #define HPyType_BuiltinShape_Unicode_AsStruct _HPy_AsStruct_Unicode #define HPyType_BuiltinShape_Tuple_AsStruct _HPy_AsStruct_Tuple #define HPyType_BuiltinShape_List_AsStruct _HPy_AsStruct_List +#define HPyType_BuiltinShape_Dict_AsStruct _HPy_AsStruct_Dict #endif /* HPY_UNIVERSAL_HPYTYPE_H */ diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/inline_helpers.h b/graalpython/hpy/hpy/devel/include/hpy/inline_helpers.h similarity index 93% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/inline_helpers.h rename to graalpython/hpy/hpy/devel/include/hpy/inline_helpers.h index c362616bb9..ba09657d53 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/inline_helpers.h +++ b/graalpython/hpy/hpy/devel/include/hpy/inline_helpers.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #ifndef HPY_INLINE_HELPERS_H #define HPY_INLINE_HELPERS_H diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/macros.h b/graalpython/hpy/hpy/devel/include/hpy/macros.h similarity index 71% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/macros.h rename to graalpython/hpy/hpy/devel/include/hpy/macros.h index fc1df4e60b..8616930fc1 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/macros.h +++ b/graalpython/hpy/hpy/devel/include/hpy/macros.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /* We define HPy_New as a macro around _HPy_New to suppress a warning. Usually, we expected it to be called this way: diff --git a/graalpython/hpy/hpy/devel/include/hpy/runtime/argparse.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/argparse.h new file mode 100644 index 0000000000..5d43db1635 --- /dev/null +++ b/graalpython/hpy/hpy/devel/include/hpy/runtime/argparse.h @@ -0,0 +1,26 @@ +#ifndef HPY_COMMON_RUNTIME_ARGPARSE_H +#define HPY_COMMON_RUNTIME_ARGPARSE_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "hpy.h" + +HPyAPI_HELPER int +HPyArg_Parse(HPyContext *ctx, HPyTracker *ht, const HPy *args, + size_t nargs, const char *fmt, ...); + +HPyAPI_HELPER int +HPyArg_ParseKeywords(HPyContext *ctx, HPyTracker *ht, const HPy *args, + size_t nargs, HPy kwnames, const char *fmt, + const char *keywords[], ...); + +HPyAPI_HELPER int +HPyArg_ParseKeywordsDict(HPyContext *ctx, HPyTracker *ht, const HPy *args, + HPy_ssize_t nargs, HPy kw, const char *fmt, + const char *keywords[], ...); + +#ifdef __cplusplus +} +#endif +#endif /* HPY_COMMON_RUNTIME_ARGPARSE_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/runtime/buildvalue.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/buildvalue.h new file mode 100644 index 0000000000..cd5667782c --- /dev/null +++ b/graalpython/hpy/hpy/devel/include/hpy/runtime/buildvalue.h @@ -0,0 +1,9 @@ +#ifndef HPY_COMMON_RUNTIME_BUILDVALUE_H +#define HPY_COMMON_RUNTIME_BUILDVALUE_H + +#include "hpy.h" + +HPyAPI_HELPER HPy +HPy_BuildValue(HPyContext *ctx, const char *fmt, ...); + +#endif /* HPY_COMMON_RUNTIME_BUILDVALUE_H */ diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/ctx_funcs.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_funcs.h similarity index 82% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/ctx_funcs.h rename to graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_funcs.h index 6653c2c4a9..d32aa75592 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/ctx_funcs.h +++ b/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_funcs.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #ifndef HPY_RUNTIME_CTX_FUNCS_H #define HPY_RUNTIME_CTX_FUNCS_H @@ -55,6 +31,7 @@ _HPy_HIDDEN HPy ctx_Module_Create(HPyContext *ctx, HPyModuleDef *hpydef); // ctx_object.c _HPy_HIDDEN void ctx_Dump(HPyContext *ctx, HPy h); +_HPy_HIDDEN HPy ctx_Type(HPyContext *ctx, HPy h_obj); _HPy_HIDDEN int ctx_TypeCheck(HPyContext *ctx, HPy h_obj, HPy h_type); _HPy_HIDDEN int ctx_Is(HPyContext *ctx, HPy h_obj, HPy h_other); _HPy_HIDDEN HPy ctx_GetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx); @@ -80,7 +57,7 @@ _HPy_HIDDEN void ctx_TupleBuilder_Cancel(HPyContext *ctx, HPyTupleBuilder builder); // ctx_tuple.c -_HPy_HIDDEN HPy ctx_Tuple_FromArray(HPyContext *ctx, HPy items[], HPy_ssize_t n); +_HPy_HIDDEN HPy ctx_Tuple_FromArray(HPyContext *ctx, const HPy items[], HPy_ssize_t n); // ctx_capsule.c _HPy_HIDDEN HPy ctx_Capsule_New(HPyContext *ctx, @@ -111,6 +88,7 @@ _HPy_HIDDEN void* ctx_AsStruct_Float(HPyContext *ctx, HPy h); _HPy_HIDDEN void* ctx_AsStruct_Unicode(HPyContext *ctx, HPy h); _HPy_HIDDEN void* ctx_AsStruct_Tuple(HPyContext *ctx, HPy h); _HPy_HIDDEN void* ctx_AsStruct_List(HPyContext *ctx, HPy h); +_HPy_HIDDEN void* ctx_AsStruct_Dict(HPyContext *ctx, HPy h); _HPy_HIDDEN void* ctx_AsStruct_Slow(HPyContext *ctx, HPy h); _HPy_HIDDEN HPy ctx_Type_FromSpec(HPyContext *ctx, HPyType_Spec *hpyspec, HPyType_SpecParam *params); diff --git a/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_module.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_module.h new file mode 100644 index 0000000000..8cb6549cc9 --- /dev/null +++ b/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_module.h @@ -0,0 +1,25 @@ +#ifndef HPY_COMMON_RUNTIME_CTX_MODULE_H +#define HPY_COMMON_RUNTIME_CTX_MODULE_H + +#include +#include "hpy.h" + +// Helper functions for CPython implementation (both CPython ABI and +// HPy universal module impl for CPython) + +/** Converts HPy module definition to CPython module definition for multiphase + * initialization */ +_HPy_HIDDEN PyModuleDef* +_HPyModuleDef_CreatePyModuleDef(HPyModuleDef *hpydef); + +/** Converts HPy module definition to PyObject that wraps CPython module + * definition for multiphase initialization */ +_HPy_HIDDEN PyObject* +_HPyModuleDef_AsPyInit(HPyModuleDef *hpydef); + +/** Implements the extra HPy specific validation that should be applied to the + * result of the HPy_mod_create slot. */ +_HPy_HIDDEN void +_HPyModule_CheckCreateSlotResult(PyObject **result); + +#endif //HPY_COMMON_RUNTIME_CTX_MODULE_H diff --git a/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_type.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_type.h new file mode 100644 index 0000000000..f8648ae654 --- /dev/null +++ b/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_type.h @@ -0,0 +1,16 @@ +#ifndef HPY_COMMON_RUNTIME_CTX_TYPE_H +#define HPY_COMMON_RUNTIME_CTX_TYPE_H + +#include +#include "hpy.h" +#include "hpy/hpytype.h" + +_HPy_HIDDEN PyMethodDef *create_method_defs(HPyDef *hpydefs[], + PyMethodDef *legacy_methods); + +_HPy_HIDDEN int call_traverseproc_from_trampoline(HPyFunc_traverseproc tp_traverse, + PyObject *self, + cpy_visitproc cpy_visit, + void *cpy_arg); + +#endif /* HPY_COMMON_RUNTIME_CTX_TYPE_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/runtime/format.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/format.h new file mode 100644 index 0000000000..f44135ac43 --- /dev/null +++ b/graalpython/hpy/hpy/devel/include/hpy/runtime/format.h @@ -0,0 +1,18 @@ +/** + * String formatting helpers. These functions are not part of HPy ABI. The implementation will be linked into HPy extensions. + */ +#ifndef HPY_COMMON_RUNTIME_FORMAT_H +#define HPY_COMMON_RUNTIME_FORMAT_H + +#include "hpy.h" + +HPyAPI_HELPER HPy +HPyUnicode_FromFormat(HPyContext *ctx, const char *fmt, ...); + +HPyAPI_HELPER HPy +HPyUnicode_FromFormatV(HPyContext *ctx, const char *format, va_list vargs); + +HPyAPI_HELPER HPy +HPyErr_Format(HPyContext *ctx, HPy h_type, const char *fmt, ...); + +#endif /* HPY_COMMON_RUNTIME_FORMAT_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/runtime/helpers.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/helpers.h new file mode 100644 index 0000000000..4f5af609ce --- /dev/null +++ b/graalpython/hpy/hpy/devel/include/hpy/runtime/helpers.h @@ -0,0 +1,15 @@ +#ifndef HPY_COMMON_RUNTIME_HELPERS_H +#define HPY_COMMON_RUNTIME_HELPERS_H + +#include "hpy.h" +#include "hpy/hpytype.h" + +HPyAPI_HELPER int +HPyHelpers_AddType(HPyContext *ctx, HPy obj, const char *name, + HPyType_Spec *hpyspec, HPyType_SpecParam *params); + +HPyAPI_HELPER int +HPyHelpers_PackArgsAndKeywords(HPyContext *ctx, const HPy *args, size_t nargs, + HPy kwnames, HPy *out_args_tuple, HPy *out_kwd); + +#endif /* HPY_COMMON_RUNTIME_HELPERS_H */ diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/structseq.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/structseq.h similarity index 75% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/structseq.h rename to graalpython/hpy/hpy/devel/include/hpy/runtime/structseq.h index f8af3a79d3..700fbcdf7c 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/structseq.h +++ b/graalpython/hpy/hpy/devel/include/hpy/runtime/structseq.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #ifndef HPY_COMMON_RUNTIME_STRUCTSEQ_H #define HPY_COMMON_RUNTIME_STRUCTSEQ_H diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/autogen_ctx.h b/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_ctx.h similarity index 71% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/autogen_ctx.h rename to graalpython/hpy/hpy/devel/include/hpy/universal/autogen_ctx.h index ef205ad4bd..1abb8e5d1c 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/autogen_ctx.h +++ b/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_ctx.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /* DO NOT EDIT THIS FILE! @@ -34,106 +10,87 @@ */ -typedef HPy* _HPyPtr; -typedef const HPy* _ConstHPyPtr; -typedef HPyField* _HPyFieldPtr; -typedef HPy _HPyConst; -typedef HPyGlobal* _HPyGlobalPtr; - -#ifdef GRAALVM_PYTHON_LLVM -#define HPy void* -#define HPyListBuilder void* -#define HPyTupleBuilder void* -#define HPyTracker void* -#define HPyField void* -#define HPyThreadState void* -#define HPyGlobal void* -#define _HPyCapsule_key int32_t -#define HPy_SourceKind int32_t -#endif - - struct _HPyContext_s { const char *name; // used just to make debugging and testing easier void *_private; // used by implementations to store custom data int abi_version; - _HPyConst h_None; - _HPyConst h_True; - _HPyConst h_False; - _HPyConst h_NotImplemented; - _HPyConst h_Ellipsis; - _HPyConst h_BaseException; - _HPyConst h_Exception; - _HPyConst h_StopAsyncIteration; - _HPyConst h_StopIteration; - _HPyConst h_GeneratorExit; - _HPyConst h_ArithmeticError; - _HPyConst h_LookupError; - _HPyConst h_AssertionError; - _HPyConst h_AttributeError; - _HPyConst h_BufferError; - _HPyConst h_EOFError; - _HPyConst h_FloatingPointError; - _HPyConst h_OSError; - _HPyConst h_ImportError; - _HPyConst h_ModuleNotFoundError; - _HPyConst h_IndexError; - _HPyConst h_KeyError; - _HPyConst h_KeyboardInterrupt; - _HPyConst h_MemoryError; - _HPyConst h_NameError; - _HPyConst h_OverflowError; - _HPyConst h_RuntimeError; - _HPyConst h_RecursionError; - _HPyConst h_NotImplementedError; - _HPyConst h_SyntaxError; - _HPyConst h_IndentationError; - _HPyConst h_TabError; - _HPyConst h_ReferenceError; - _HPyConst h_SystemError; - _HPyConst h_SystemExit; - _HPyConst h_TypeError; - _HPyConst h_UnboundLocalError; - _HPyConst h_UnicodeError; - _HPyConst h_UnicodeEncodeError; - _HPyConst h_UnicodeDecodeError; - _HPyConst h_UnicodeTranslateError; - _HPyConst h_ValueError; - _HPyConst h_ZeroDivisionError; - _HPyConst h_BlockingIOError; - _HPyConst h_BrokenPipeError; - _HPyConst h_ChildProcessError; - _HPyConst h_ConnectionError; - _HPyConst h_ConnectionAbortedError; - _HPyConst h_ConnectionRefusedError; - _HPyConst h_ConnectionResetError; - _HPyConst h_FileExistsError; - _HPyConst h_FileNotFoundError; - _HPyConst h_InterruptedError; - _HPyConst h_IsADirectoryError; - _HPyConst h_NotADirectoryError; - _HPyConst h_PermissionError; - _HPyConst h_ProcessLookupError; - _HPyConst h_TimeoutError; - _HPyConst h_Warning; - _HPyConst h_UserWarning; - _HPyConst h_DeprecationWarning; - _HPyConst h_PendingDeprecationWarning; - _HPyConst h_SyntaxWarning; - _HPyConst h_RuntimeWarning; - _HPyConst h_FutureWarning; - _HPyConst h_ImportWarning; - _HPyConst h_UnicodeWarning; - _HPyConst h_BytesWarning; - _HPyConst h_ResourceWarning; - _HPyConst h_BaseObjectType; - _HPyConst h_TypeType; - _HPyConst h_BoolType; - _HPyConst h_LongType; - _HPyConst h_FloatType; - _HPyConst h_UnicodeType; - _HPyConst h_TupleType; - _HPyConst h_ListType; + HPy h_None; + HPy h_True; + HPy h_False; + HPy h_NotImplemented; + HPy h_Ellipsis; + HPy h_BaseException; + HPy h_Exception; + HPy h_StopAsyncIteration; + HPy h_StopIteration; + HPy h_GeneratorExit; + HPy h_ArithmeticError; + HPy h_LookupError; + HPy h_AssertionError; + HPy h_AttributeError; + HPy h_BufferError; + HPy h_EOFError; + HPy h_FloatingPointError; + HPy h_OSError; + HPy h_ImportError; + HPy h_ModuleNotFoundError; + HPy h_IndexError; + HPy h_KeyError; + HPy h_KeyboardInterrupt; + HPy h_MemoryError; + HPy h_NameError; + HPy h_OverflowError; + HPy h_RuntimeError; + HPy h_RecursionError; + HPy h_NotImplementedError; + HPy h_SyntaxError; + HPy h_IndentationError; + HPy h_TabError; + HPy h_ReferenceError; + HPy h_SystemError; + HPy h_SystemExit; + HPy h_TypeError; + HPy h_UnboundLocalError; + HPy h_UnicodeError; + HPy h_UnicodeEncodeError; + HPy h_UnicodeDecodeError; + HPy h_UnicodeTranslateError; + HPy h_ValueError; + HPy h_ZeroDivisionError; + HPy h_BlockingIOError; + HPy h_BrokenPipeError; + HPy h_ChildProcessError; + HPy h_ConnectionError; + HPy h_ConnectionAbortedError; + HPy h_ConnectionRefusedError; + HPy h_ConnectionResetError; + HPy h_FileExistsError; + HPy h_FileNotFoundError; + HPy h_InterruptedError; + HPy h_IsADirectoryError; + HPy h_NotADirectoryError; + HPy h_PermissionError; + HPy h_ProcessLookupError; + HPy h_TimeoutError; + HPy h_Warning; + HPy h_UserWarning; + HPy h_DeprecationWarning; + HPy h_PendingDeprecationWarning; + HPy h_SyntaxWarning; + HPy h_RuntimeWarning; + HPy h_FutureWarning; + HPy h_ImportWarning; + HPy h_UnicodeWarning; + HPy h_BytesWarning; + HPy h_ResourceWarning; + HPy h_BaseObjectType; + HPy h_TypeType; + HPy h_BoolType; + HPy h_LongType; + HPy h_FloatType; + HPy h_UnicodeType; + HPy h_TupleType; + HPy h_ListType; HPy (*ctx_Dup)(HPyContext *ctx, HPy h); void (*ctx_Close)(HPyContext *ctx, HPy h); HPy (*ctx_Long_FromInt32_t)(HPyContext *ctx, int32_t value); @@ -208,7 +165,7 @@ struct _HPyContext_s { void (*ctx_Err_WriteUnraisable)(HPyContext *ctx, HPy obj); int (*ctx_IsTrue)(HPyContext *ctx, HPy h); HPy (*ctx_Type_FromSpec)(HPyContext *ctx, HPyType_Spec *spec, HPyType_SpecParam *params); - HPy (*ctx_Type_GenericNew)(HPyContext *ctx, HPy type, _ConstHPyPtr args, HPy_ssize_t nargs, HPy kw); + HPy (*ctx_Type_GenericNew)(HPyContext *ctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw); HPy (*ctx_GetAttr)(HPyContext *ctx, HPy obj, HPy name); HPy (*ctx_GetAttr_s)(HPyContext *ctx, HPy obj, const char *utf8_name); int (*ctx_HasAttr)(HPyContext *ctx, HPy obj, HPy name); @@ -261,7 +218,7 @@ struct _HPyContext_s { int (*ctx_Dict_Check)(HPyContext *ctx, HPy h); HPy (*ctx_Dict_New)(HPyContext *ctx); int (*ctx_Tuple_Check)(HPyContext *ctx, HPy h); - HPy (*ctx_Tuple_FromArray)(HPyContext *ctx, _HPyPtr items, HPy_ssize_t n); + HPy (*ctx_Tuple_FromArray)(HPyContext *ctx, const HPy items[], HPy_ssize_t n); HPy (*ctx_Import_ImportModule)(HPyContext *ctx, const char *utf8_name); HPy (*ctx_FromPyObject)(HPyContext *ctx, cpy_PyObject *obj); cpy_PyObject *(*ctx_AsPyObject)(HPyContext *ctx, HPy h); @@ -278,11 +235,11 @@ struct _HPyContext_s { int (*ctx_Tracker_Add)(HPyContext *ctx, HPyTracker ht, HPy h); void (*ctx_Tracker_ForgetAll)(HPyContext *ctx, HPyTracker ht); void (*ctx_Tracker_Close)(HPyContext *ctx, HPyTracker ht); - void (*ctx_Field_Store)(HPyContext *ctx, HPy target_object, _HPyFieldPtr target_field, HPy h); + void (*ctx_Field_Store)(HPyContext *ctx, HPy target_object, HPyField *target_field, HPy h); HPy (*ctx_Field_Load)(HPyContext *ctx, HPy source_object, HPyField source_field); void (*ctx_ReenterPythonExecution)(HPyContext *ctx, HPyThreadState state); HPyThreadState (*ctx_LeavePythonExecution)(HPyContext *ctx); - void (*ctx_Global_Store)(HPyContext *ctx, _HPyGlobalPtr global, HPy h); + void (*ctx_Global_Store)(HPyContext *ctx, HPyGlobal *global, HPy h); HPy (*ctx_Global_Load)(HPyContext *ctx, HPyGlobal global); void (*ctx_Dump)(HPyContext *ctx, HPy h); void *(*ctx_AsStruct_Type)(HPyContext *ctx, HPy h); @@ -295,12 +252,12 @@ struct _HPyContext_s { int (*ctx_DelItem)(HPyContext *ctx, HPy obj, HPy key); int (*ctx_DelItem_i)(HPyContext *ctx, HPy obj, HPy_ssize_t idx); int (*ctx_DelItem_s)(HPyContext *ctx, HPy obj, const char *utf8_key); - _HPyConst h_ComplexType; - _HPyConst h_BytesType; - _HPyConst h_MemoryViewType; - _HPyConst h_CapsuleType; - _HPyConst h_SliceType; - _HPyConst h_Builtins; + HPy h_ComplexType; + HPy h_BytesType; + HPy h_MemoryViewType; + HPy h_CapsuleType; + HPy h_SliceType; + HPy h_Builtins; HPy (*ctx_Capsule_New)(HPyContext *ctx, void *pointer, const char *utf8_name, HPyCapsule_Destructor *destructor); void *(*ctx_Capsule_Get)(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, const char *utf8_name); int (*ctx_Capsule_IsValid)(HPyContext *ctx, HPy capsule, const char *utf8_name); @@ -308,7 +265,7 @@ struct _HPyContext_s { HPy (*ctx_Compile_s)(HPyContext *ctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind); HPy (*ctx_EvalCode)(HPyContext *ctx, HPy code, HPy globals, HPy locals); HPy (*ctx_ContextVar_New)(HPyContext *ctx, const char *name, HPy default_value); - int32_t (*ctx_ContextVar_Get)(HPyContext *ctx, HPy context_var, HPy default_value, _HPyPtr result); + int32_t (*ctx_ContextVar_Get)(HPyContext *ctx, HPy context_var, HPy default_value, HPy *result); HPy (*ctx_ContextVar_Set)(HPyContext *ctx, HPy context_var, HPy value); const char *(*ctx_Type_GetName)(HPyContext *ctx, HPy type); int (*ctx_Type_IsSubtype)(HPyContext *ctx, HPy sub, HPy type); @@ -318,18 +275,16 @@ struct _HPyContext_s { HPy (*ctx_Dict_Copy)(HPyContext *ctx, HPy h); int (*ctx_Slice_Unpack)(HPyContext *ctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step); int (*ctx_SetCallFunction)(HPyContext *ctx, HPy h, HPyCallFunction *func); - HPy (*ctx_Call)(HPyContext *ctx, HPy callable, _ConstHPyPtr args, size_t nargs, HPy kwnames); - HPy (*ctx_CallMethod)(HPyContext *ctx, HPy name, _ConstHPyPtr args, size_t nargs, HPy kwnames); + HPy (*ctx_Call)(HPyContext *ctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames); + HPy (*ctx_CallMethod)(HPyContext *ctx, HPy name, const HPy *args, size_t nargs, HPy kwnames); + HPy h_DictType; + void *(*ctx_AsStruct_Dict)(HPyContext *ctx, HPy h); + int (*ctx_List_Insert)(HPyContext *ctx, HPy h_list, HPy_ssize_t index, HPy h_item); + HPy (*ctx_GetSlice)(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end); + int (*ctx_SetSlice)(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end, HPy value); + int (*ctx_DelSlice)(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end); + HPy (*ctx_GetIter)(HPyContext *ctx, HPy obj); + HPy (*ctx_Iter_Next)(HPyContext *ctx, HPy obj); + int (*ctx_Iter_Check)(HPyContext *ctx, HPy obj); + HPy (*ctx_Slice_New)(HPyContext *ctx, HPy start, HPy stop, HPy step); }; - -#ifdef GRAALVM_PYTHON_LLVM -#undef HPy -#undef HPyListBuilder -#undef HPyTupleBuilder -#undef HPyTracker -#undef HPyField -#undef HPyThreadState -#undef HPyGlobal -#undef _HPyCapsule_key -#undef HPy_SourceKind -#endif diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/autogen_hpyfunc_trampolines.h b/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_hpyfunc_trampolines.h similarity index 91% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/autogen_hpyfunc_trampolines.h rename to graalpython/hpy/hpy/devel/include/hpy/universal/autogen_hpyfunc_trampolines.h index d873b50f2a..568b5621db 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/autogen_hpyfunc_trampolines.h +++ b/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_hpyfunc_trampolines.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /* DO NOT EDIT THIS FILE! diff --git a/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_trampolines.h b/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_trampolines.h new file mode 100644 index 0000000000..4579b5591b --- /dev/null +++ b/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_trampolines.h @@ -0,0 +1,760 @@ + +/* + DO NOT EDIT THIS FILE! + + This file is automatically generated by hpy.tools.autogen.trampolines.autogen_trampolines_h + See also hpy.tools.autogen and hpy/tools/public_api.h + + Run this to regenerate: + make autogen + +*/ + +HPyAPI_FUNC HPy HPy_Dup(HPyContext *ctx, HPy h) { + return ctx->ctx_Dup ( ctx, h ); +} + +HPyAPI_FUNC void HPy_Close(HPyContext *ctx, HPy h) { + ctx->ctx_Close ( ctx, h ); +} + +HPyAPI_FUNC HPy HPyLong_FromInt32_t(HPyContext *ctx, int32_t value) { + return ctx->ctx_Long_FromInt32_t ( ctx, value ); +} + +HPyAPI_FUNC HPy HPyLong_FromUInt32_t(HPyContext *ctx, uint32_t value) { + return ctx->ctx_Long_FromUInt32_t ( ctx, value ); +} + +HPyAPI_FUNC HPy HPyLong_FromInt64_t(HPyContext *ctx, int64_t v) { + return ctx->ctx_Long_FromInt64_t ( ctx, v ); +} + +HPyAPI_FUNC HPy HPyLong_FromUInt64_t(HPyContext *ctx, uint64_t v) { + return ctx->ctx_Long_FromUInt64_t ( ctx, v ); +} + +HPyAPI_FUNC HPy HPyLong_FromSize_t(HPyContext *ctx, size_t value) { + return ctx->ctx_Long_FromSize_t ( ctx, value ); +} + +HPyAPI_FUNC HPy HPyLong_FromSsize_t(HPyContext *ctx, HPy_ssize_t value) { + return ctx->ctx_Long_FromSsize_t ( ctx, value ); +} + +HPyAPI_FUNC int32_t HPyLong_AsInt32_t(HPyContext *ctx, HPy h) { + return ctx->ctx_Long_AsInt32_t ( ctx, h ); +} + +HPyAPI_FUNC uint32_t HPyLong_AsUInt32_t(HPyContext *ctx, HPy h) { + return ctx->ctx_Long_AsUInt32_t ( ctx, h ); +} + +HPyAPI_FUNC uint32_t HPyLong_AsUInt32_tMask(HPyContext *ctx, HPy h) { + return ctx->ctx_Long_AsUInt32_tMask ( ctx, h ); +} + +HPyAPI_FUNC int64_t HPyLong_AsInt64_t(HPyContext *ctx, HPy h) { + return ctx->ctx_Long_AsInt64_t ( ctx, h ); +} + +HPyAPI_FUNC uint64_t HPyLong_AsUInt64_t(HPyContext *ctx, HPy h) { + return ctx->ctx_Long_AsUInt64_t ( ctx, h ); +} + +HPyAPI_FUNC uint64_t HPyLong_AsUInt64_tMask(HPyContext *ctx, HPy h) { + return ctx->ctx_Long_AsUInt64_tMask ( ctx, h ); +} + +HPyAPI_FUNC size_t HPyLong_AsSize_t(HPyContext *ctx, HPy h) { + return ctx->ctx_Long_AsSize_t ( ctx, h ); +} + +HPyAPI_FUNC HPy_ssize_t HPyLong_AsSsize_t(HPyContext *ctx, HPy h) { + return ctx->ctx_Long_AsSsize_t ( ctx, h ); +} + +HPyAPI_FUNC void *HPyLong_AsVoidPtr(HPyContext *ctx, HPy h) { + return ctx->ctx_Long_AsVoidPtr ( ctx, h ); +} + +HPyAPI_FUNC double HPyLong_AsDouble(HPyContext *ctx, HPy h) { + return ctx->ctx_Long_AsDouble ( ctx, h ); +} + +HPyAPI_FUNC HPy HPyFloat_FromDouble(HPyContext *ctx, double v) { + return ctx->ctx_Float_FromDouble ( ctx, v ); +} + +HPyAPI_FUNC double HPyFloat_AsDouble(HPyContext *ctx, HPy h) { + return ctx->ctx_Float_AsDouble ( ctx, h ); +} + +HPyAPI_FUNC HPy HPyBool_FromBool(HPyContext *ctx, bool v) { + return ctx->ctx_Bool_FromBool ( ctx, v ); +} + +HPyAPI_FUNC HPy_ssize_t HPy_Length(HPyContext *ctx, HPy h) { + return ctx->ctx_Length ( ctx, h ); +} + +HPyAPI_FUNC int HPyNumber_Check(HPyContext *ctx, HPy h) { + return ctx->ctx_Number_Check ( ctx, h ); +} + +HPyAPI_FUNC HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_Add ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_Subtract(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_Subtract ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_Multiply(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_Multiply ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_MatrixMultiply(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_MatrixMultiply ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_FloorDivide(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_FloorDivide ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_TrueDivide(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_TrueDivide ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_Remainder(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_Remainder ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_Divmod(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_Divmod ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_Power(HPyContext *ctx, HPy h1, HPy h2, HPy h3) { + return ctx->ctx_Power ( ctx, h1, h2, h3 ); +} + +HPyAPI_FUNC HPy HPy_Negative(HPyContext *ctx, HPy h1) { + return ctx->ctx_Negative ( ctx, h1 ); +} + +HPyAPI_FUNC HPy HPy_Positive(HPyContext *ctx, HPy h1) { + return ctx->ctx_Positive ( ctx, h1 ); +} + +HPyAPI_FUNC HPy HPy_Absolute(HPyContext *ctx, HPy h1) { + return ctx->ctx_Absolute ( ctx, h1 ); +} + +HPyAPI_FUNC HPy HPy_Invert(HPyContext *ctx, HPy h1) { + return ctx->ctx_Invert ( ctx, h1 ); +} + +HPyAPI_FUNC HPy HPy_Lshift(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_Lshift ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_Rshift(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_Rshift ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_And(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_And ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_Xor(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_Xor ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_Or(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_Or ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_Index(HPyContext *ctx, HPy h1) { + return ctx->ctx_Index ( ctx, h1 ); +} + +HPyAPI_FUNC HPy HPy_Long(HPyContext *ctx, HPy h1) { + return ctx->ctx_Long ( ctx, h1 ); +} + +HPyAPI_FUNC HPy HPy_Float(HPyContext *ctx, HPy h1) { + return ctx->ctx_Float ( ctx, h1 ); +} + +HPyAPI_FUNC HPy HPy_InPlaceAdd(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_InPlaceAdd ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_InPlaceSubtract(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_InPlaceSubtract ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_InPlaceMultiply(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_InPlaceMultiply ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_InPlaceMatrixMultiply(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_InPlaceMatrixMultiply ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_InPlaceFloorDivide(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_InPlaceFloorDivide ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_InPlaceTrueDivide(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_InPlaceTrueDivide ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_InPlaceRemainder(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_InPlaceRemainder ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_InPlacePower(HPyContext *ctx, HPy h1, HPy h2, HPy h3) { + return ctx->ctx_InPlacePower ( ctx, h1, h2, h3 ); +} + +HPyAPI_FUNC HPy HPy_InPlaceLshift(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_InPlaceLshift ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_InPlaceRshift(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_InPlaceRshift ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_InPlaceAnd(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_InPlaceAnd ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_InPlaceXor(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_InPlaceXor ( ctx, h1, h2 ); +} + +HPyAPI_FUNC HPy HPy_InPlaceOr(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_InPlaceOr ( ctx, h1, h2 ); +} + +HPyAPI_FUNC int HPyCallable_Check(HPyContext *ctx, HPy h) { + return ctx->ctx_Callable_Check ( ctx, h ); +} + +HPyAPI_FUNC HPy HPy_CallTupleDict(HPyContext *ctx, HPy callable, HPy args, HPy kw) { + return ctx->ctx_CallTupleDict ( ctx, callable, args, kw ); +} + +HPyAPI_FUNC HPy HPy_Call(HPyContext *ctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames) { + return ctx->ctx_Call ( ctx, callable, args, nargs, kwnames ); +} + +HPyAPI_FUNC HPy HPy_CallMethod(HPyContext *ctx, HPy name, const HPy *args, size_t nargs, HPy kwnames) { + return ctx->ctx_CallMethod ( ctx, name, args, nargs, kwnames ); +} + +HPyAPI_FUNC HPy HPy_GetIter(HPyContext *ctx, HPy obj) { + return ctx->ctx_GetIter ( ctx, obj ); +} + +HPyAPI_FUNC HPy HPyIter_Next(HPyContext *ctx, HPy obj) { + return ctx->ctx_Iter_Next ( ctx, obj ); +} + +HPyAPI_FUNC int HPyIter_Check(HPyContext *ctx, HPy obj) { + return ctx->ctx_Iter_Check ( ctx, obj ); +} + +HPyAPI_FUNC HPy HPyErr_SetString(HPyContext *ctx, HPy h_type, const char *utf8_message) { + ctx->ctx_Err_SetString ( ctx, h_type, utf8_message ); return HPy_NULL; +} + +HPyAPI_FUNC HPy HPyErr_SetObject(HPyContext *ctx, HPy h_type, HPy h_value) { + ctx->ctx_Err_SetObject ( ctx, h_type, h_value ); return HPy_NULL; +} + +HPyAPI_FUNC HPy HPyErr_SetFromErrnoWithFilename(HPyContext *ctx, HPy h_type, const char *filename_fsencoded) { + return ctx->ctx_Err_SetFromErrnoWithFilename ( ctx, h_type, filename_fsencoded ); +} + +HPyAPI_FUNC HPy HPyErr_SetFromErrnoWithFilenameObjects(HPyContext *ctx, HPy h_type, HPy filename1, HPy filename2) { + ctx->ctx_Err_SetFromErrnoWithFilenameObjects ( ctx, h_type, filename1, filename2 ); return HPy_NULL; +} + +HPyAPI_FUNC int HPyErr_Occurred(HPyContext *ctx) { + return ctx->ctx_Err_Occurred ( ctx ); +} + +HPyAPI_FUNC int HPyErr_ExceptionMatches(HPyContext *ctx, HPy exc) { + return ctx->ctx_Err_ExceptionMatches ( ctx, exc ); +} + +HPyAPI_FUNC HPy HPyErr_NoMemory(HPyContext *ctx) { + ctx->ctx_Err_NoMemory ( ctx ); return HPy_NULL; +} + +HPyAPI_FUNC void HPyErr_Clear(HPyContext *ctx) { + ctx->ctx_Err_Clear ( ctx ); +} + +HPyAPI_FUNC HPy HPyErr_NewException(HPyContext *ctx, const char *utf8_name, HPy base, HPy dict) { + return ctx->ctx_Err_NewException ( ctx, utf8_name, base, dict ); +} + +HPyAPI_FUNC HPy HPyErr_NewExceptionWithDoc(HPyContext *ctx, const char *utf8_name, const char *utf8_doc, HPy base, HPy dict) { + return ctx->ctx_Err_NewExceptionWithDoc ( ctx, utf8_name, utf8_doc, base, dict ); +} + +HPyAPI_FUNC int HPyErr_WarnEx(HPyContext *ctx, HPy category, const char *utf8_message, HPy_ssize_t stack_level) { + return ctx->ctx_Err_WarnEx ( ctx, category, utf8_message, stack_level ); +} + +HPyAPI_FUNC void HPyErr_WriteUnraisable(HPyContext *ctx, HPy obj) { + ctx->ctx_Err_WriteUnraisable ( ctx, obj ); +} + +HPyAPI_FUNC int HPy_IsTrue(HPyContext *ctx, HPy h) { + return ctx->ctx_IsTrue ( ctx, h ); +} + +HPyAPI_FUNC HPy HPyType_FromSpec(HPyContext *ctx, HPyType_Spec *spec, HPyType_SpecParam *params) { + return ctx->ctx_Type_FromSpec ( ctx, spec, params ); +} + +HPyAPI_FUNC HPy HPyType_GenericNew(HPyContext *ctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw) { + return ctx->ctx_Type_GenericNew ( ctx, type, args, nargs, kw ); +} + +HPyAPI_FUNC HPy HPy_GetAttr(HPyContext *ctx, HPy obj, HPy name) { + return ctx->ctx_GetAttr ( ctx, obj, name ); +} + +HPyAPI_FUNC HPy HPy_GetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name) { + return ctx->ctx_GetAttr_s ( ctx, obj, utf8_name ); +} + +HPyAPI_FUNC int HPy_HasAttr(HPyContext *ctx, HPy obj, HPy name) { + return ctx->ctx_HasAttr ( ctx, obj, name ); +} + +HPyAPI_FUNC int HPy_HasAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name) { + return ctx->ctx_HasAttr_s ( ctx, obj, utf8_name ); +} + +HPyAPI_FUNC int HPy_SetAttr(HPyContext *ctx, HPy obj, HPy name, HPy value) { + return ctx->ctx_SetAttr ( ctx, obj, name, value ); +} + +HPyAPI_FUNC int HPy_SetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name, HPy value) { + return ctx->ctx_SetAttr_s ( ctx, obj, utf8_name, value ); +} + +HPyAPI_FUNC HPy HPy_GetItem(HPyContext *ctx, HPy obj, HPy key) { + return ctx->ctx_GetItem ( ctx, obj, key ); +} + +HPyAPI_FUNC HPy HPy_GetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx) { + return ctx->ctx_GetItem_i ( ctx, obj, idx ); +} + +HPyAPI_FUNC HPy HPy_GetItem_s(HPyContext *ctx, HPy obj, const char *utf8_key) { + return ctx->ctx_GetItem_s ( ctx, obj, utf8_key ); +} + +HPyAPI_FUNC HPy HPy_GetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) { + return ctx->ctx_GetSlice ( ctx, obj, start, end ); +} + +HPyAPI_FUNC int HPy_Contains(HPyContext *ctx, HPy container, HPy key) { + return ctx->ctx_Contains ( ctx, container, key ); +} + +HPyAPI_FUNC int HPy_SetItem(HPyContext *ctx, HPy obj, HPy key, HPy value) { + return ctx->ctx_SetItem ( ctx, obj, key, value ); +} + +HPyAPI_FUNC int HPy_SetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx, HPy value) { + return ctx->ctx_SetItem_i ( ctx, obj, idx, value ); +} + +HPyAPI_FUNC int HPy_SetItem_s(HPyContext *ctx, HPy obj, const char *utf8_key, HPy value) { + return ctx->ctx_SetItem_s ( ctx, obj, utf8_key, value ); +} + +HPyAPI_FUNC int HPy_SetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end, HPy value) { + return ctx->ctx_SetSlice ( ctx, obj, start, end, value ); +} + +HPyAPI_FUNC int HPy_DelItem(HPyContext *ctx, HPy obj, HPy key) { + return ctx->ctx_DelItem ( ctx, obj, key ); +} + +HPyAPI_FUNC int HPy_DelItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx) { + return ctx->ctx_DelItem_i ( ctx, obj, idx ); +} + +HPyAPI_FUNC int HPy_DelItem_s(HPyContext *ctx, HPy obj, const char *utf8_key) { + return ctx->ctx_DelItem_s ( ctx, obj, utf8_key ); +} + +HPyAPI_FUNC int HPy_DelSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) { + return ctx->ctx_DelSlice ( ctx, obj, start, end ); +} + +HPyAPI_FUNC HPy HPy_Type(HPyContext *ctx, HPy obj) { + return ctx->ctx_Type ( ctx, obj ); +} + +HPyAPI_FUNC int HPy_TypeCheck(HPyContext *ctx, HPy obj, HPy type) { + return ctx->ctx_TypeCheck ( ctx, obj, type ); +} + +HPyAPI_FUNC const char *HPyType_GetName(HPyContext *ctx, HPy type) { + return ctx->ctx_Type_GetName ( ctx, type ); +} + +HPyAPI_FUNC int HPyType_IsSubtype(HPyContext *ctx, HPy sub, HPy type) { + return ctx->ctx_Type_IsSubtype ( ctx, sub, type ); +} + +HPyAPI_FUNC int HPy_Is(HPyContext *ctx, HPy obj, HPy other) { + return ctx->ctx_Is ( ctx, obj, other ); +} + +HPyAPI_FUNC void *_HPy_AsStruct_Object(HPyContext *ctx, HPy h) { + return ctx->ctx_AsStruct_Object ( ctx, h ); +} + +HPyAPI_FUNC void *_HPy_AsStruct_Legacy(HPyContext *ctx, HPy h) { + return ctx->ctx_AsStruct_Legacy ( ctx, h ); +} + +HPyAPI_FUNC void *_HPy_AsStruct_Type(HPyContext *ctx, HPy h) { + return ctx->ctx_AsStruct_Type ( ctx, h ); +} + +HPyAPI_FUNC void *_HPy_AsStruct_Long(HPyContext *ctx, HPy h) { + return ctx->ctx_AsStruct_Long ( ctx, h ); +} + +HPyAPI_FUNC void *_HPy_AsStruct_Float(HPyContext *ctx, HPy h) { + return ctx->ctx_AsStruct_Float ( ctx, h ); +} + +HPyAPI_FUNC void *_HPy_AsStruct_Unicode(HPyContext *ctx, HPy h) { + return ctx->ctx_AsStruct_Unicode ( ctx, h ); +} + +HPyAPI_FUNC void *_HPy_AsStruct_Tuple(HPyContext *ctx, HPy h) { + return ctx->ctx_AsStruct_Tuple ( ctx, h ); +} + +HPyAPI_FUNC void *_HPy_AsStruct_List(HPyContext *ctx, HPy h) { + return ctx->ctx_AsStruct_List ( ctx, h ); +} + +HPyAPI_FUNC void *_HPy_AsStruct_Dict(HPyContext *ctx, HPy h) { + return ctx->ctx_AsStruct_Dict ( ctx, h ); +} + +HPyAPI_FUNC HPyType_BuiltinShape _HPyType_GetBuiltinShape(HPyContext *ctx, HPy h_type) { + return ctx->ctx_Type_GetBuiltinShape ( ctx, h_type ); +} + +HPyAPI_FUNC HPy HPy_Repr(HPyContext *ctx, HPy obj) { + return ctx->ctx_Repr ( ctx, obj ); +} + +HPyAPI_FUNC HPy HPy_Str(HPyContext *ctx, HPy obj) { + return ctx->ctx_Str ( ctx, obj ); +} + +HPyAPI_FUNC HPy HPy_ASCII(HPyContext *ctx, HPy obj) { + return ctx->ctx_ASCII ( ctx, obj ); +} + +HPyAPI_FUNC HPy HPy_Bytes(HPyContext *ctx, HPy obj) { + return ctx->ctx_Bytes ( ctx, obj ); +} + +HPyAPI_FUNC HPy HPy_RichCompare(HPyContext *ctx, HPy v, HPy w, int op) { + return ctx->ctx_RichCompare ( ctx, v, w, op ); +} + +HPyAPI_FUNC int HPy_RichCompareBool(HPyContext *ctx, HPy v, HPy w, int op) { + return ctx->ctx_RichCompareBool ( ctx, v, w, op ); +} + +HPyAPI_FUNC HPy_hash_t HPy_Hash(HPyContext *ctx, HPy obj) { + return ctx->ctx_Hash ( ctx, obj ); +} + +HPyAPI_FUNC int HPyBytes_Check(HPyContext *ctx, HPy h) { + return ctx->ctx_Bytes_Check ( ctx, h ); +} + +HPyAPI_FUNC HPy_ssize_t HPyBytes_Size(HPyContext *ctx, HPy h) { + return ctx->ctx_Bytes_Size ( ctx, h ); +} + +HPyAPI_FUNC HPy_ssize_t HPyBytes_GET_SIZE(HPyContext *ctx, HPy h) { + return ctx->ctx_Bytes_GET_SIZE ( ctx, h ); +} + +HPyAPI_FUNC const char *HPyBytes_AsString(HPyContext *ctx, HPy h) { + return ctx->ctx_Bytes_AsString ( ctx, h ); +} + +HPyAPI_FUNC const char *HPyBytes_AS_STRING(HPyContext *ctx, HPy h) { + return ctx->ctx_Bytes_AS_STRING ( ctx, h ); +} + +HPyAPI_FUNC HPy HPyBytes_FromString(HPyContext *ctx, const char *bytes) { + return ctx->ctx_Bytes_FromString ( ctx, bytes ); +} + +HPyAPI_FUNC HPy HPyBytes_FromStringAndSize(HPyContext *ctx, const char *bytes, HPy_ssize_t len) { + return ctx->ctx_Bytes_FromStringAndSize ( ctx, bytes, len ); +} + +HPyAPI_FUNC HPy HPyUnicode_FromString(HPyContext *ctx, const char *utf8) { + return ctx->ctx_Unicode_FromString ( ctx, utf8 ); +} + +HPyAPI_FUNC int HPyUnicode_Check(HPyContext *ctx, HPy h) { + return ctx->ctx_Unicode_Check ( ctx, h ); +} + +HPyAPI_FUNC HPy HPyUnicode_AsASCIIString(HPyContext *ctx, HPy h) { + return ctx->ctx_Unicode_AsASCIIString ( ctx, h ); +} + +HPyAPI_FUNC HPy HPyUnicode_AsLatin1String(HPyContext *ctx, HPy h) { + return ctx->ctx_Unicode_AsLatin1String ( ctx, h ); +} + +HPyAPI_FUNC HPy HPyUnicode_AsUTF8String(HPyContext *ctx, HPy h) { + return ctx->ctx_Unicode_AsUTF8String ( ctx, h ); +} + +HPyAPI_FUNC const char *HPyUnicode_AsUTF8AndSize(HPyContext *ctx, HPy h, HPy_ssize_t *size) { + return ctx->ctx_Unicode_AsUTF8AndSize ( ctx, h, size ); +} + +HPyAPI_FUNC HPy HPyUnicode_FromWideChar(HPyContext *ctx, const wchar_t *w, HPy_ssize_t size) { + return ctx->ctx_Unicode_FromWideChar ( ctx, w, size ); +} + +HPyAPI_FUNC HPy HPyUnicode_DecodeFSDefault(HPyContext *ctx, const char *v) { + return ctx->ctx_Unicode_DecodeFSDefault ( ctx, v ); +} + +HPyAPI_FUNC HPy HPyUnicode_DecodeFSDefaultAndSize(HPyContext *ctx, const char *v, HPy_ssize_t size) { + return ctx->ctx_Unicode_DecodeFSDefaultAndSize ( ctx, v, size ); +} + +HPyAPI_FUNC HPy HPyUnicode_EncodeFSDefault(HPyContext *ctx, HPy h) { + return ctx->ctx_Unicode_EncodeFSDefault ( ctx, h ); +} + +HPyAPI_FUNC HPy_UCS4 HPyUnicode_ReadChar(HPyContext *ctx, HPy h, HPy_ssize_t index) { + return ctx->ctx_Unicode_ReadChar ( ctx, h, index ); +} + +HPyAPI_FUNC HPy HPyUnicode_DecodeASCII(HPyContext *ctx, const char *ascii, HPy_ssize_t size, const char *errors) { + return ctx->ctx_Unicode_DecodeASCII ( ctx, ascii, size, errors ); +} + +HPyAPI_FUNC HPy HPyUnicode_DecodeLatin1(HPyContext *ctx, const char *latin1, HPy_ssize_t size, const char *errors) { + return ctx->ctx_Unicode_DecodeLatin1 ( ctx, latin1, size, errors ); +} + +HPyAPI_FUNC HPy HPyUnicode_FromEncodedObject(HPyContext *ctx, HPy obj, const char *encoding, const char *errors) { + return ctx->ctx_Unicode_FromEncodedObject ( ctx, obj, encoding, errors ); +} + +HPyAPI_FUNC HPy HPyUnicode_Substring(HPyContext *ctx, HPy str, HPy_ssize_t start, HPy_ssize_t end) { + return ctx->ctx_Unicode_Substring ( ctx, str, start, end ); +} + +HPyAPI_FUNC int HPyList_Check(HPyContext *ctx, HPy h) { + return ctx->ctx_List_Check ( ctx, h ); +} + +HPyAPI_FUNC HPy HPyList_New(HPyContext *ctx, HPy_ssize_t len) { + return ctx->ctx_List_New ( ctx, len ); +} + +HPyAPI_FUNC int HPyList_Append(HPyContext *ctx, HPy h_list, HPy h_item) { + return ctx->ctx_List_Append ( ctx, h_list, h_item ); +} + +HPyAPI_FUNC int HPyList_Insert(HPyContext *ctx, HPy h_list, HPy_ssize_t index, HPy h_item) { + return ctx->ctx_List_Insert ( ctx, h_list, index, h_item ); +} + +HPyAPI_FUNC int HPyDict_Check(HPyContext *ctx, HPy h) { + return ctx->ctx_Dict_Check ( ctx, h ); +} + +HPyAPI_FUNC HPy HPyDict_New(HPyContext *ctx) { + return ctx->ctx_Dict_New ( ctx ); +} + +HPyAPI_FUNC HPy HPyDict_Keys(HPyContext *ctx, HPy h) { + return ctx->ctx_Dict_Keys ( ctx, h ); +} + +HPyAPI_FUNC HPy HPyDict_Copy(HPyContext *ctx, HPy h) { + return ctx->ctx_Dict_Copy ( ctx, h ); +} + +HPyAPI_FUNC int HPyTuple_Check(HPyContext *ctx, HPy h) { + return ctx->ctx_Tuple_Check ( ctx, h ); +} + +HPyAPI_FUNC HPy HPyTuple_FromArray(HPyContext *ctx, const HPy items[], HPy_ssize_t n) { + return ctx->ctx_Tuple_FromArray ( ctx, items, n ); +} + +HPyAPI_FUNC HPy HPySlice_New(HPyContext *ctx, HPy start, HPy stop, HPy step) { + return ctx->ctx_Slice_New ( ctx, start, stop, step ); +} + +HPyAPI_FUNC int HPySlice_Unpack(HPyContext *ctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step) { + return ctx->ctx_Slice_Unpack ( ctx, slice, start, stop, step ); +} + +HPyAPI_FUNC HPy HPyImport_ImportModule(HPyContext *ctx, const char *utf8_name) { + return ctx->ctx_Import_ImportModule ( ctx, utf8_name ); +} + +HPyAPI_FUNC HPy HPyCapsule_New(HPyContext *ctx, void *pointer, const char *utf8_name, HPyCapsule_Destructor *destructor) { + return ctx->ctx_Capsule_New ( ctx, pointer, utf8_name, destructor ); +} + +HPyAPI_FUNC void *HPyCapsule_Get(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, const char *utf8_name) { + return ctx->ctx_Capsule_Get ( ctx, capsule, key, utf8_name ); +} + +HPyAPI_FUNC int HPyCapsule_IsValid(HPyContext *ctx, HPy capsule, const char *utf8_name) { + return ctx->ctx_Capsule_IsValid ( ctx, capsule, utf8_name ); +} + +HPyAPI_FUNC int HPyCapsule_Set(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, void *value) { + return ctx->ctx_Capsule_Set ( ctx, capsule, key, value ); +} + +HPyAPI_FUNC HPy HPy_FromPyObject(HPyContext *ctx, cpy_PyObject *obj) { + return ctx->ctx_FromPyObject ( ctx, obj ); +} + +HPyAPI_FUNC cpy_PyObject *HPy_AsPyObject(HPyContext *ctx, HPy h) { + return ctx->ctx_AsPyObject ( ctx, h ); +} + +HPyAPI_FUNC void _HPy_CallRealFunctionFromTrampoline(HPyContext *ctx, HPyFunc_Signature sig, HPyCFunction func, void *args) { + ctx->ctx_CallRealFunctionFromTrampoline ( ctx, sig, func, args ); +} + +HPyAPI_FUNC HPyListBuilder HPyListBuilder_New(HPyContext *ctx, HPy_ssize_t size) { + return ctx->ctx_ListBuilder_New ( ctx, size ); +} + +HPyAPI_FUNC void HPyListBuilder_Set(HPyContext *ctx, HPyListBuilder builder, HPy_ssize_t index, HPy h_item) { + ctx->ctx_ListBuilder_Set ( ctx, builder, index, h_item ); +} + +HPyAPI_FUNC HPy HPyListBuilder_Build(HPyContext *ctx, HPyListBuilder builder) { + return ctx->ctx_ListBuilder_Build ( ctx, builder ); +} + +HPyAPI_FUNC void HPyListBuilder_Cancel(HPyContext *ctx, HPyListBuilder builder) { + ctx->ctx_ListBuilder_Cancel ( ctx, builder ); +} + +HPyAPI_FUNC HPyTupleBuilder HPyTupleBuilder_New(HPyContext *ctx, HPy_ssize_t size) { + return ctx->ctx_TupleBuilder_New ( ctx, size ); +} + +HPyAPI_FUNC void HPyTupleBuilder_Set(HPyContext *ctx, HPyTupleBuilder builder, HPy_ssize_t index, HPy h_item) { + ctx->ctx_TupleBuilder_Set ( ctx, builder, index, h_item ); +} + +HPyAPI_FUNC HPy HPyTupleBuilder_Build(HPyContext *ctx, HPyTupleBuilder builder) { + return ctx->ctx_TupleBuilder_Build ( ctx, builder ); +} + +HPyAPI_FUNC void HPyTupleBuilder_Cancel(HPyContext *ctx, HPyTupleBuilder builder) { + ctx->ctx_TupleBuilder_Cancel ( ctx, builder ); +} + +HPyAPI_FUNC HPyTracker HPyTracker_New(HPyContext *ctx, HPy_ssize_t size) { + return ctx->ctx_Tracker_New ( ctx, size ); +} + +HPyAPI_FUNC int HPyTracker_Add(HPyContext *ctx, HPyTracker ht, HPy h) { + return ctx->ctx_Tracker_Add ( ctx, ht, h ); +} + +HPyAPI_FUNC void HPyTracker_ForgetAll(HPyContext *ctx, HPyTracker ht) { + ctx->ctx_Tracker_ForgetAll ( ctx, ht ); +} + +HPyAPI_FUNC void HPyTracker_Close(HPyContext *ctx, HPyTracker ht) { + ctx->ctx_Tracker_Close ( ctx, ht ); +} + +HPyAPI_FUNC void HPyField_Store(HPyContext *ctx, HPy target_object, HPyField *target_field, HPy h) { + ctx->ctx_Field_Store ( ctx, target_object, target_field, h ); +} + +HPyAPI_FUNC HPy HPyField_Load(HPyContext *ctx, HPy source_object, HPyField source_field) { + return ctx->ctx_Field_Load ( ctx, source_object, source_field ); +} + +HPyAPI_FUNC void HPy_ReenterPythonExecution(HPyContext *ctx, HPyThreadState state) { + ctx->ctx_ReenterPythonExecution ( ctx, state ); +} + +HPyAPI_FUNC HPyThreadState HPy_LeavePythonExecution(HPyContext *ctx) { + return ctx->ctx_LeavePythonExecution ( ctx ); +} + +HPyAPI_FUNC void HPyGlobal_Store(HPyContext *ctx, HPyGlobal *global, HPy h) { + ctx->ctx_Global_Store ( ctx, global, h ); +} + +HPyAPI_FUNC HPy HPyGlobal_Load(HPyContext *ctx, HPyGlobal global) { + return ctx->ctx_Global_Load ( ctx, global ); +} + +HPyAPI_FUNC void _HPy_Dump(HPyContext *ctx, HPy h) { + ctx->ctx_Dump ( ctx, h ); +} + +HPyAPI_FUNC HPy HPy_Compile_s(HPyContext *ctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind) { + return ctx->ctx_Compile_s ( ctx, utf8_source, utf8_filename, kind ); +} + +HPyAPI_FUNC HPy HPy_EvalCode(HPyContext *ctx, HPy code, HPy globals, HPy locals) { + return ctx->ctx_EvalCode ( ctx, code, globals, locals ); +} + +HPyAPI_FUNC HPy HPyContextVar_New(HPyContext *ctx, const char *name, HPy default_value) { + return ctx->ctx_ContextVar_New ( ctx, name, default_value ); +} + +HPyAPI_FUNC int32_t HPyContextVar_Get(HPyContext *ctx, HPy context_var, HPy default_value, HPy *result) { + return ctx->ctx_ContextVar_Get ( ctx, context_var, default_value, result ); +} + +HPyAPI_FUNC HPy HPyContextVar_Set(HPyContext *ctx, HPy context_var, HPy value) { + return ctx->ctx_ContextVar_Set ( ctx, context_var, value ); +} + +HPyAPI_FUNC int HPy_SetCallFunction(HPyContext *ctx, HPy h, HPyCallFunction *func) { + return ctx->ctx_SetCallFunction ( ctx, h, func ); +} + diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/hpyfunc_trampolines.h b/graalpython/hpy/hpy/devel/include/hpy/universal/hpyfunc_trampolines.h similarity index 87% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/hpyfunc_trampolines.h rename to graalpython/hpy/hpy/devel/include/hpy/universal/hpyfunc_trampolines.h index f06419b5d8..6d8764f4b8 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/hpyfunc_trampolines.h +++ b/graalpython/hpy/hpy/devel/include/hpy/universal/hpyfunc_trampolines.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #ifndef HPY_UNIVERSAL_HPYFUNC_TRAMPOLINES_H #define HPY_UNIVERSAL_HPYFUNC_TRAMPOLINES_H diff --git a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/misc_trampolines.h b/graalpython/hpy/hpy/devel/include/hpy/universal/misc_trampolines.h similarity index 54% rename from graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/misc_trampolines.h rename to graalpython/hpy/hpy/devel/include/hpy/universal/misc_trampolines.h index 159e3d01a1..f20545bc65 100644 --- a/graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/misc_trampolines.h +++ b/graalpython/hpy/hpy/devel/include/hpy/universal/misc_trampolines.h @@ -1,38 +1,6 @@ -/* MIT License - * - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #ifndef HPY_MISC_TRAMPOLINES_H #define HPY_MISC_TRAMPOLINES_H -#ifdef GRAALVM_PYTHON_LLVM -#define UNWRAP(_h) ((_h)._i) -#define WRAP(_ptr) ((HPy){(_ptr)}) -#else -#define UNWRAP(_h) _h -#define WRAP(_ptr) _ptr -#endif - static inline HPy _HPy_New(HPyContext *ctx, HPy h_type, void **data) { /* Performance hack: the autogenerated version of this trampoline would simply forward data to ctx_New. @@ -50,7 +18,7 @@ static inline HPy _HPy_New(HPyContext *ctx, HPy h_type, void **data) { See https://github.com/pyhandle/hpy/pull/22#pullrequestreview-413365845 */ void *data_result; - HPy h = WRAP(ctx->ctx_New(ctx, UNWRAP(h_type), &data_result)); + HPy h = ctx->ctx_New(ctx, h_type, &data_result); *data = data_result; return h; } @@ -69,42 +37,42 @@ static inline void * HPyCapsule_GetPointer(HPyContext *ctx, HPy capsule, const char *name) { return ctx->ctx_Capsule_Get( - ctx, UNWRAP(capsule), HPyCapsule_key_Pointer, name); + ctx, capsule, HPyCapsule_key_Pointer, name); } static inline const char * HPyCapsule_GetName(HPyContext *ctx, HPy capsule) { return (const char *) ctx->ctx_Capsule_Get( - ctx, UNWRAP(capsule), HPyCapsule_key_Name, NULL); + ctx, capsule, HPyCapsule_key_Name, NULL); } static inline void * HPyCapsule_GetContext(HPyContext *ctx, HPy capsule) { return ctx->ctx_Capsule_Get( - ctx, UNWRAP(capsule), HPyCapsule_key_Context, NULL); + ctx, capsule, HPyCapsule_key_Context, NULL); } static inline int HPyCapsule_SetPointer(HPyContext *ctx, HPy capsule, void *pointer) { return ctx->ctx_Capsule_Set( - ctx, UNWRAP(capsule), HPyCapsule_key_Pointer, pointer); + ctx, capsule, HPyCapsule_key_Pointer, pointer); } static inline int HPyCapsule_SetName(HPyContext *ctx, HPy capsule, const char *name) { return ctx->ctx_Capsule_Set( - ctx, UNWRAP(capsule), HPyCapsule_key_Name, (void *) name); + ctx, capsule, HPyCapsule_key_Name, (void *) name); } static inline int HPyCapsule_SetContext(HPyContext *ctx, HPy capsule, void *context) { return ctx->ctx_Capsule_Set( - ctx, UNWRAP(capsule), HPyCapsule_key_Context, context); + ctx, capsule, HPyCapsule_key_Context, context); } static inline int @@ -112,10 +80,7 @@ HPyCapsule_SetDestructor(HPyContext *ctx, HPy capsule, HPyCapsule_Destructor *destructor) { return ctx->ctx_Capsule_Set( - ctx, UNWRAP(capsule), HPyCapsule_key_Destructor, (void *) destructor); + ctx, capsule, HPyCapsule_key_Destructor, (void *) destructor); } -#undef UNWRAP -#undef WRAP - #endif /* HPY_MISC_TRAMPOLINES_H */ diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/argparse.c b/graalpython/hpy/hpy/devel/src/runtime/argparse.c similarity index 95% rename from graalpython/lib-graalpython/modules/hpy/devel/src/runtime/argparse.c rename to graalpython/hpy/hpy/devel/src/runtime/argparse.c index 2e466dfa15..9f2b972126 100644 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/argparse.c +++ b/graalpython/hpy/hpy/devel/src/runtime/argparse.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /** * Implementation of HPyArg_Parse and HPyArg_ParseKeywords. * diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/buildvalue.c b/graalpython/hpy/hpy/devel/src/runtime/buildvalue.c similarity index 87% rename from graalpython/lib-graalpython/modules/hpy/devel/src/runtime/buildvalue.c rename to graalpython/hpy/hpy/devel/src/runtime/buildvalue.c index 1440332fb9..8e786ff4d6 100644 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/buildvalue.c +++ b/graalpython/hpy/hpy/devel/src/runtime/buildvalue.c @@ -1,43 +1,3 @@ -/* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ /** * Implementation of HPy_BuildValue. * diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_bytes.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_bytes.c new file mode 100644 index 0000000000..8a4845e015 --- /dev/null +++ b/graalpython/hpy/hpy/devel/src/runtime/ctx_bytes.c @@ -0,0 +1,25 @@ +#include +#include "hpy.h" +#include "hpy/runtime/ctx_funcs.h" + +#ifndef HPY_ABI_CPYTHON + // for _h2py and _py2h +# include "handles.h" +#endif + + +_HPy_HIDDEN HPy +ctx_Bytes_FromStringAndSize(HPyContext *ctx, const char *v, HPy_ssize_t len) +{ + if (v == NULL) { + // The CPython API allows passing a null pointer to + // PyBytes_FromStringAndSize and returns uninitialized memory of the + // requested size which can then be initialized after the call. + // In HPy the underlying memory is opaque and so cannot be initialized + // after the call and so we raise an error instead. + HPyErr_SetString(ctx, ctx->h_ValueError, + "NULL char * passed to HPyBytes_FromStringAndSize"); + return HPy_NULL; + } + return _py2h(PyBytes_FromStringAndSize(v, len)); +} diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_call.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_call.c similarity index 75% rename from graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_call.c rename to graalpython/hpy/hpy/devel/src/runtime/ctx_call.c index e2a4253e08..e85fd236b4 100644 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_call.c +++ b/graalpython/hpy/hpy/devel/src/runtime/ctx_call.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #include #include "hpy.h" #if defined(_MSC_VER) diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_capsule.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_capsule.c similarity index 68% rename from graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_capsule.c rename to graalpython/hpy/hpy/devel/src/runtime/ctx_capsule.c index 666e3bc1af..703b686164 100644 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_capsule.c +++ b/graalpython/hpy/hpy/devel/src/runtime/ctx_capsule.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #include #include "hpy.h" diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_contextvar.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_contextvar.c new file mode 100644 index 0000000000..d0cc4fc31d --- /dev/null +++ b/graalpython/hpy/hpy/devel/src/runtime/ctx_contextvar.c @@ -0,0 +1,16 @@ +#include +#include "hpy.h" + +#ifndef HPY_ABI_CPYTHON + // for _h2py and _py2h +# include "handles.h" +#endif + +_HPy_HIDDEN int32_t +ctx_ContextVar_Get(HPyContext *ctx, HPy context_var, HPy default_value, HPy *result) +{ + PyObject * py_result; + int32_t ret = PyContextVar_Get(_h2py(context_var), _h2py(default_value), &py_result); + *result = _py2h(py_result); + return ret; +} diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_err.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_err.c new file mode 100644 index 0000000000..783683efe5 --- /dev/null +++ b/graalpython/hpy/hpy/devel/src/runtime/ctx_err.c @@ -0,0 +1,13 @@ +#include +#include "hpy.h" +#include "hpy/runtime/ctx_funcs.h" + +#ifndef HPY_ABI_CPYTHON + // for _h2py and _py2h +# include "handles.h" +#endif + +_HPy_HIDDEN int +ctx_Err_Occurred(HPyContext *ctx) { + return PyErr_Occurred() ? 1 : 0; +} diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_eval.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_eval.c new file mode 100644 index 0000000000..945db30777 --- /dev/null +++ b/graalpython/hpy/hpy/devel/src/runtime/ctx_eval.c @@ -0,0 +1,23 @@ +#include +#include "hpy.h" + +#ifndef HPY_ABI_CPYTHON + // for _h2py and _py2h +# include "handles.h" +#endif + +_HPy_HIDDEN HPy +ctx_Compile_s(HPyContext *ctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind) +{ + int start; + switch (kind) + { + case HPy_SourceKind_Expr: start = Py_eval_input; break; + case HPy_SourceKind_File: start = Py_file_input; break; + case HPy_SourceKind_Single: start = Py_single_input; break; + default: + PyErr_SetString(PyExc_SystemError, "invalid source kind"); + return HPy_NULL; + } + return _py2h(Py_CompileString(utf8_source, utf8_filename, start)); +} diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_listbuilder.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_listbuilder.c similarity index 54% rename from graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_listbuilder.c rename to graalpython/hpy/hpy/devel/src/runtime/ctx_listbuilder.c index 69b787c0bb..d048502023 100644 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_listbuilder.c +++ b/graalpython/hpy/hpy/devel/src/runtime/ctx_listbuilder.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #include #include #include "hpy.h" @@ -38,11 +14,7 @@ ctx_ListBuilder_New(HPyContext *ctx, HPy_ssize_t size) PyObject *lst = PyList_New(size); if (lst == NULL) PyErr_Clear(); /* delay the MemoryError */ -#ifdef GRAALVM_PYTHON_LLVM - return (HPyListBuilder){(void*)lst}; -#else return (HPyListBuilder){(HPy_ssize_t)lst}; -#endif } _HPy_HIDDEN void diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_long.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_long.c similarity index 75% rename from graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_long.c rename to graalpython/hpy/hpy/devel/src/runtime/ctx_long.c index ef50f1ff66..a1609d66d3 100644 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_long.c +++ b/graalpython/hpy/hpy/devel/src/runtime/ctx_long.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #include #include "hpy.h" diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_module.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_module.c similarity index 81% rename from graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_module.c rename to graalpython/hpy/hpy/devel/src/runtime/ctx_module.c index fd9c86b972..8d318c03eb 100644 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_module.c +++ b/graalpython/hpy/hpy/devel/src/runtime/ctx_module.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #include #include "hpy.h" #include "hpy/runtime/ctx_type.h" diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_object.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_object.c similarity index 66% rename from graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_object.c rename to graalpython/hpy/hpy/devel/src/runtime/ctx_object.c index 16b37743b5..9fa72a205c 100644 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_object.c +++ b/graalpython/hpy/hpy/devel/src/runtime/ctx_object.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #include #include "hpy.h" @@ -39,6 +15,14 @@ ctx_Dump(HPyContext *ctx, HPy h) _PyObject_Dump(_h2py(h)); } +_HPy_HIDDEN HPy +ctx_Type(HPyContext *ctx, HPy obj) +{ + PyTypeObject *tp = Py_TYPE(_h2py(obj)); + Py_INCREF(tp); + return _py2h((PyObject *)tp); +} + /* NOTE: In contrast to CPython, HPy has to check that 'h_type' is a type. This is not necessary on CPython because it requires C type 'PyTypeObject *' but here we can only receive an HPy handle. Appropriate checking of the argument @@ -58,10 +42,14 @@ ctx_Is(HPyContext *ctx, HPy h_obj, HPy h_other) _HPy_HIDDEN HPy ctx_GetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx) { + PyObject *py_obj = _h2py(obj); + if (PySequence_Check(py_obj)) { + return _py2h(PySequence_GetItem(py_obj, idx)); + } PyObject* key = PyLong_FromSsize_t(idx); if (key == NULL) return HPy_NULL; - HPy result = _py2h(PyObject_GetItem(_h2py(obj), key)); + HPy result = _py2h(PyObject_GetItem(py_obj, key)); Py_DECREF(key); return result; } diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_tracker.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_tracker.c similarity index 76% rename from graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_tracker.c rename to graalpython/hpy/hpy/devel/src/runtime/ctx_tracker.c index 5364cb45a5..17a3909f8e 100644 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_tracker.c +++ b/graalpython/hpy/hpy/devel/src/runtime/ctx_tracker.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /** * A manager for HPy handles, allowing handles to be tracked * and closed as a group. @@ -96,11 +72,7 @@ static inline _HPyTracker_s *_ht2hp(HPyTracker ht) { return (_HPyTracker_s *) (ht)._i; } static inline HPyTracker _hp2ht(_HPyTracker_s *hp) { -#ifdef GRAALVM_PYTHON_LLVM - return (HPyTracker) {(void*) (hp)}; -#else return (HPyTracker) {(HPy_ssize_t) (hp)}; -#endif } diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_tuple.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_tuple.c new file mode 100644 index 0000000000..42661f8fea --- /dev/null +++ b/graalpython/hpy/hpy/devel/src/runtime/ctx_tuple.c @@ -0,0 +1,22 @@ +#include +#include "hpy.h" + +#ifndef HPY_ABI_CPYTHON + // for _h2py and _py2h +# include "handles.h" +#endif + + +_HPy_HIDDEN HPy +ctx_Tuple_FromArray(HPyContext *ctx, const HPy items[], HPy_ssize_t n) +{ + PyObject *res = PyTuple_New(n); + if (!res) + return HPy_NULL; + for(HPy_ssize_t i=0; i #include #include "hpy.h" @@ -45,11 +21,7 @@ ctx_TupleBuilder_New(HPyContext *ctx, HPy_ssize_t size) HPyTupleBuilder_Build() will re-raise the MemoryError and so it's enough for the caller to check at that point. */ } -#ifdef GRAALVM_PYTHON_LLVM - return (HPyTupleBuilder){(void*)tup}; -#else return (HPyTupleBuilder){(HPy_ssize_t)tup}; -#endif } _HPy_HIDDEN void diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_type.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_type.c similarity index 97% rename from graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_type.c rename to graalpython/hpy/hpy/devel/src/runtime/ctx_type.c index 9be31206a0..ef89e2590d 100644 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_type.c +++ b/graalpython/hpy/hpy/devel/src/runtime/ctx_type.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #include #include #include "structmember.h" // for PyMemberDef @@ -100,6 +76,7 @@ FULLY_ALIGNED_SPACE(PyFloatObject) FULLY_ALIGNED_SPACE(PyUnicodeObject) FULLY_ALIGNED_SPACE(PyTupleObject) FULLY_ALIGNED_SPACE(PyListObject) +FULLY_ALIGNED_SPACE(PyDictObject) #define _HPy_HEAD_SIZE(HEAD) (offsetof(_HPy_FullyAlignedSpaceFor##HEAD, payload)) @@ -125,6 +102,8 @@ _HPy_GetHeaderSize(HPyType_BuiltinShape shape) return _HPy_HEAD_SIZE(PyTupleObject); case HPyType_BuiltinShape_List: return _HPy_HEAD_SIZE(PyListObject); + case HPyType_BuiltinShape_Dict: + return _HPy_HEAD_SIZE(PyDictObject); } return -1; } @@ -1528,6 +1507,12 @@ ctx_AsStruct_List(HPyContext *ctx, HPy h) return _HPy_Payload(_h2py(h), HPyType_BuiltinShape_List); } +_HPy_HIDDEN void* +ctx_AsStruct_Dict(HPyContext *ctx, HPy h) +{ + return _HPy_Payload(_h2py(h), HPyType_BuiltinShape_Dict); +} + _HPy_HIDDEN void* ctx_AsStruct_Slow(HPyContext *ctx, HPy h) { diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/format.c b/graalpython/hpy/hpy/devel/src/runtime/format.c similarity index 95% rename from graalpython/lib-graalpython/modules/hpy/devel/src/runtime/format.c rename to graalpython/hpy/hpy/devel/src/runtime/format.c index 9d0c4eb0f0..32edd52889 100644 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/format.c +++ b/graalpython/hpy/hpy/devel/src/runtime/format.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /** * HPy string formatting helpers. * diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/helpers.c b/graalpython/hpy/hpy/devel/src/runtime/helpers.c similarity index 78% rename from graalpython/lib-graalpython/modules/hpy/devel/src/runtime/helpers.c rename to graalpython/hpy/hpy/devel/src/runtime/helpers.c index 300c9a0237..42e7648f11 100644 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/helpers.c +++ b/graalpython/hpy/hpy/devel/src/runtime/helpers.c @@ -1,38 +1,3 @@ -/* MIT License - * - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * Runtime helper functions. - * - * These are not part of the HPy context or ABI, but are available for - * HPy extensions to incorporate at compile time. - * - * Runtime Helpers API - * ------------------- - * - */ - #include "hpy.h" /** diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/structseq.c b/graalpython/hpy/hpy/devel/src/runtime/structseq.c similarity index 86% rename from graalpython/lib-graalpython/modules/hpy/devel/src/runtime/structseq.c rename to graalpython/hpy/hpy/devel/src/runtime/structseq.c index df79ab79e7..9acd237756 100644 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/structseq.c +++ b/graalpython/hpy/hpy/devel/src/runtime/structseq.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /* * Helper functions to create struct sequences. * diff --git a/graalpython/hpy/hpy/tools/autogen/__init__.py b/graalpython/hpy/hpy/tools/autogen/__init__.py new file mode 100644 index 0000000000..81eb61e746 --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/__init__.py @@ -0,0 +1,21 @@ +import pycparser +from packaging import version + +if version.parse(pycparser.__version__) < version.parse('2.21'): + raise ImportError('You need pycparser>=2.21 to run autogen') + +from .parse import HPyAPI, AUTOGEN_H + + +def generate(generators, *gen_args): + """ + Takes a sequence of autogen generators that will have access to the parse + tree of 'public_api.c' and can then generate files or whatever. + :param generators: A sequence (e.g. tuple) of classes or callables that + will produce objects with a 'write' method. The 'gen_args' will be passed + to the 'write' method on invocation. + :param gen_args: Arguments for the autogen generator instances. + """ + api = HPyAPI.parse(AUTOGEN_H) + for cls in generators: + cls(api).write(*gen_args) diff --git a/graalpython/hpy/hpy/tools/autogen/__main__.py b/graalpython/hpy/hpy/tools/autogen/__main__.py new file mode 100644 index 0000000000..59cdf04872 --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/__main__.py @@ -0,0 +1,66 @@ +""" +Parse public_api.h and generate various stubs around +""" +import sys +import py +import pycparser +from packaging import version + +if version.parse(pycparser.__version__) < version.parse('2.21'): + raise ImportError('You need pycparser>=2.21 to run autogen') + +from . import generate +from .ctx import (autogen_ctx_h, + autogen_ctx_def_h, + cpython_autogen_ctx_h) +from .trampolines import (autogen_trampolines_h, + cpython_autogen_api_impl_h, + universal_autogen_ctx_impl_h) +from .hpyfunc import autogen_hpyfunc_declare_h +from .hpyfunc import autogen_hpyfunc_trampoline_h +from .hpyfunc import autogen_ctx_call_i +from .hpyfunc import autogen_cpython_hpyfunc_trampoline_h +from .hpyslot import autogen_hpyslot_h +from .debug import (autogen_debug_ctx_init_h, + autogen_debug_wrappers, + autogen_debug_ctx_call_i) +from .trace import (autogen_tracer_ctx_init_h, + autogen_tracer_wrappers, + autogen_trace_func_table_c) +from .pypy import autogen_pypy_txt +from .doc import (autogen_function_index, + autogen_doc_api_mapping) + +DEFAULT_GENERATORS = (autogen_ctx_h, + autogen_ctx_def_h, + cpython_autogen_ctx_h, + autogen_trampolines_h, + cpython_autogen_api_impl_h, + universal_autogen_ctx_impl_h, + autogen_hpyfunc_declare_h, + autogen_hpyfunc_trampoline_h, + autogen_ctx_call_i, + autogen_cpython_hpyfunc_trampoline_h, + autogen_hpyslot_h, + autogen_debug_ctx_init_h, + autogen_debug_wrappers, + autogen_debug_ctx_call_i, + autogen_tracer_ctx_init_h, + autogen_tracer_wrappers, + autogen_trace_func_table_c, + autogen_pypy_txt, + autogen_function_index, + autogen_doc_api_mapping) + + +def main(): + if len(sys.argv) != 2: + print('Usage: python -m hpy.tools.autogen OUTDIR') + sys.exit(1) + outdir = py.path.local(sys.argv[1]) + + generate(DEFAULT_GENERATORS, outdir) + + +if __name__ == '__main__': + main() diff --git a/graalpython/hpy/hpy/tools/autogen/autogen.h b/graalpython/hpy/hpy/tools/autogen/autogen.h new file mode 100644 index 0000000000..78bae31617 --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/autogen.h @@ -0,0 +1,40 @@ +#define STRINGIFY(X) #X +#define HPy_ID(X) _Pragma(STRINGIFY(id=X)) \ + +#define AUTOGEN 1 + +// These are not real typedefs: they are there only to make pycparser happy +typedef int HPy; +typedef int HPyContext; +typedef int HPyModuleDef; +typedef int HPyType_Spec; +typedef int HPyType_SpecParam; +typedef int HPyCFunction; +typedef int HPy_ssize_t; +typedef int HPy_hash_t; +typedef int wchar_t; +typedef int size_t; +typedef int HPyFunc_Signature; +typedef int cpy_PyObject; +typedef int HPyField; +typedef int HPyGlobal; +typedef int HPyListBuilder; +typedef int HPyTupleBuilder; +typedef int HPyTracker; +typedef int HPy_RichCmpOp; +typedef int HPy_buffer; +typedef int HPyFunc_visitproc; +typedef int HPy_UCS4; +typedef int HPyThreadState; +typedef int HPyType_BuiltinShape; +typedef int _HPyCapsule_key; +typedef int HPyCapsule_Destructor; +typedef int int32_t; +typedef int uint32_t; +typedef int int64_t; +typedef int uint64_t; +typedef int bool; +typedef int HPy_SourceKind; +typedef int HPyCallFunction; + +#include "public_api.h" diff --git a/graalpython/hpy/hpy/tools/autogen/autogenfile.py b/graalpython/hpy/hpy/tools/autogen/autogenfile.py new file mode 100644 index 0000000000..d4fddb74c7 --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/autogenfile.py @@ -0,0 +1,35 @@ +C_DISCLAIMER = """ +/* + DO NOT EDIT THIS FILE! + + This file is automatically generated by {clsname} + See also hpy.tools.autogen and hpy/tools/public_api.h + + Run this to regenerate: + make autogen + +*/ +""" + +class AutoGenFile: + LANGUAGE = 'C' + PATH = None + DISCLAIMER = None + + def __init__(self, api): + if self.DISCLAIMER is None and self.LANGUAGE == 'C': + self.DISCLAIMER = C_DISCLAIMER + self.api = api + + def generate(self): + raise NotImplementedError + + def write(self, root): + cls = self.__class__ + clsname = '%s.%s' % (cls.__module__, cls.__name__) + with root.join(self.PATH).open('w', encoding='utf-8') as f: + if self.DISCLAIMER is not None: + f.write(self.DISCLAIMER.format(clsname=clsname)) + f.write('\n') + f.write(self.generate()) + f.write('\n') diff --git a/graalpython/hpy/hpy/tools/autogen/conf.py b/graalpython/hpy/hpy/tools/autogen/conf.py new file mode 100644 index 0000000000..5ebf345783 --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/conf.py @@ -0,0 +1,211 @@ +# Defines parameters for the code generation + +# Handwritten trampolines: +NO_TRAMPOLINES = { + '_HPy_New', + 'HPy_FatalError', +} + +# Generated trampoline returns given constant, +# but the context function is void +RETURN_CONSTANT = { + 'HPyErr_SetString': 'HPy_NULL', + 'HPyErr_SetObject': 'HPy_NULL', + 'HPyErr_SetFromErrnoWithFilenameObjects': 'HPy_NULL', + 'HPyErr_NoMemory': 'HPy_NULL' +} + +# If the HPy function delegates to C Python API of a different name or, in the +# case of None, if the HPy function is implemented by hand +SPECIAL_CASES = { + 'HPy_Dup': None, + 'HPy_Close': None, + 'HPyField_Load': None, + 'HPyField_Store': None, + 'HPyModule_Create': None, + 'HPy_GetAttr': 'PyObject_GetAttr', + 'HPy_GetAttr_s': 'PyObject_GetAttrString', + 'HPy_HasAttr': 'PyObject_HasAttr', + 'HPy_HasAttr_s': 'PyObject_HasAttrString', + 'HPy_SetAttr': 'PyObject_SetAttr', + 'HPy_SetAttr_s': 'PyObject_SetAttrString', + 'HPy_GetIter': 'PyObject_GetIter', + 'HPy_GetItem': 'PyObject_GetItem', + 'HPy_GetItem_i': None, + 'HPy_GetItem_s': None, + 'HPy_GetSlice': 'PySequence_GetSlice', + 'HPy_SetItem': 'PyObject_SetItem', + 'HPy_SetItem_i': None, + 'HPy_SetItem_s': None, + 'HPy_SetSlice': 'PySequence_SetSlice', + 'HPy_DelItem': 'PyObject_DelItem', + 'HPy_DelItem_i': None, + 'HPy_DelItem_s': None, + 'HPy_DelSlice': 'PySequence_DelSlice', + 'HPy_Contains': 'PySequence_Contains', + 'HPy_Length': 'PyObject_Length', + 'HPy_CallTupleDict': None, + 'HPy_Call': None, # 'PyObject_Vectorcall', no auto arg conversion + 'HPy_CallMethod': None, # 'PyObject_VectorcallMethod',no auto arg conversion + 'HPy_FromPyObject': None, + 'HPy_AsPyObject': None, + '_HPy_AsStruct_Object': None, + '_HPy_AsStruct_Type': None, + '_HPy_AsStruct_Long': None, + '_HPy_AsStruct_Float': None, + '_HPy_AsStruct_Unicode': None, + '_HPy_AsStruct_Tuple': None, + '_HPy_AsStruct_List': None, + '_HPy_AsStruct_Dict': None, + '_HPy_AsStruct_Legacy': None, + '_HPyType_GetBuiltinShape': None, + '_HPy_CallRealFunctionFromTrampoline': None, + '_HPy_CallDestroyAndThenDealloc': None, + 'HPyErr_Occurred': None, + 'HPy_FatalError': None, + 'HPy_Add': 'PyNumber_Add', + 'HPy_Subtract': 'PyNumber_Subtract', + 'HPy_Multiply': 'PyNumber_Multiply', + 'HPy_MatrixMultiply': 'PyNumber_MatrixMultiply', + 'HPy_FloorDivide': 'PyNumber_FloorDivide', + 'HPy_TrueDivide': 'PyNumber_TrueDivide', + 'HPy_Remainder': 'PyNumber_Remainder', + 'HPy_Divmod': 'PyNumber_Divmod', + 'HPy_Power': 'PyNumber_Power', + 'HPy_Negative': 'PyNumber_Negative', + 'HPy_Positive': 'PyNumber_Positive', + 'HPy_Absolute': 'PyNumber_Absolute', + 'HPy_Invert': 'PyNumber_Invert', + 'HPy_Lshift': 'PyNumber_Lshift', + 'HPy_Rshift': 'PyNumber_Rshift', + 'HPy_And': 'PyNumber_And', + 'HPy_Xor': 'PyNumber_Xor', + 'HPy_Or': 'PyNumber_Or', + 'HPy_Index': 'PyNumber_Index', + 'HPy_Long': 'PyNumber_Long', + 'HPy_Float': 'PyNumber_Float', + 'HPy_InPlaceAdd': 'PyNumber_InPlaceAdd', + 'HPy_InPlaceSubtract': 'PyNumber_InPlaceSubtract', + 'HPy_InPlaceMultiply': 'PyNumber_InPlaceMultiply', + 'HPy_InPlaceMatrixMultiply': 'PyNumber_InPlaceMatrixMultiply', + 'HPy_InPlaceFloorDivide': 'PyNumber_InPlaceFloorDivide', + 'HPy_InPlaceTrueDivide': 'PyNumber_InPlaceTrueDivide', + 'HPy_InPlaceRemainder': 'PyNumber_InPlaceRemainder', + 'HPy_InPlacePower': 'PyNumber_InPlacePower', + 'HPy_InPlaceLshift': 'PyNumber_InPlaceLshift', + 'HPy_InPlaceRshift': 'PyNumber_InPlaceRshift', + 'HPy_InPlaceAnd': 'PyNumber_InPlaceAnd', + 'HPy_InPlaceXor': 'PyNumber_InPlaceXor', + 'HPy_InPlaceOr': 'PyNumber_InPlaceOr', + '_HPy_New': None, + 'HPyType_FromSpec': None, + 'HPyType_GenericNew': None, + 'HPy_Repr': 'PyObject_Repr', + 'HPy_Str': 'PyObject_Str', + 'HPy_ASCII': 'PyObject_ASCII', + 'HPy_Bytes': 'PyObject_Bytes', + 'HPy_IsTrue': 'PyObject_IsTrue', + 'HPy_RichCompare': 'PyObject_RichCompare', + 'HPy_RichCompareBool': 'PyObject_RichCompareBool', + 'HPy_Hash': 'PyObject_Hash', + 'HPyIter_Next': 'PyIter_Next', + 'HPyIter_Check': 'PyIter_Check', + 'HPyListBuilder_New': None, + 'HPyListBuilder_Set': None, + 'HPyListBuilder_Build': None, + 'HPyListBuilder_Cancel': None, + 'HPyTuple_FromArray': None, + 'HPyTupleBuilder_New': None, + 'HPyTupleBuilder_Set': None, + 'HPyTupleBuilder_Build': None, + 'HPyTupleBuilder_Cancel': None, + 'HPyTracker_New': None, + 'HPyTracker_Add': None, + 'HPyTracker_ForgetAll': None, + 'HPyTracker_Close': None, + '_HPy_Dump': None, + 'HPy_Type': None, + 'HPy_TypeCheck': None, + 'HPy_Is': None, + 'HPyBytes_FromStringAndSize': None, + 'HPy_LeavePythonExecution': 'PyEval_SaveThread', + 'HPy_ReenterPythonExecution': 'PyEval_RestoreThread', + 'HPyGlobal_Load': None, + 'HPyGlobal_Store': None, + 'HPyCapsule_New': None, + 'HPyCapsule_Get': None, + 'HPyCapsule_Set': None, + 'HPyLong_FromInt32_t': None, + 'HPyLong_FromUInt32_t': None, + 'HPyLong_FromInt64_t': None, + 'HPyLong_FromUInt64_t': None, + 'HPyLong_AsInt32_t': None, + 'HPyLong_AsUInt32_t': None, + 'HPyLong_AsUInt32_tMask': None, + 'HPyLong_AsInt64_t': None, + 'HPyLong_AsUInt64_t': None, + 'HPyLong_AsUInt64_tMask': None, + 'HPyBool_FromBool': 'PyBool_FromLong', + 'HPy_Compile_s': None, + 'HPy_EvalCode': 'PyEval_EvalCode', + 'HPyContextVar_Get': None, + 'HPyType_GetName': None, + 'HPyType_IsSubtype': None, + 'HPy_SetCallFunction': None, +} + +################################################################################ +# Configuration for auto-generating docs # +################################################################################ + +# A manual mapping of between CPython C API functions and HPy API functions. +# Most of the mapping will be generated automatically from 'public_api.h' if an +# HPy API function is not a special case (see 'conf.py'). However, in some +# cases, it might be that we have inline helper functions or something similar +# that map to a CPython C API function which cannot be determined automatically. +# In those cases, the mapping can be manually specified here. Also, manual +# mapping will always take precedence over automatically derived mappings. +DOC_MANUAL_API_MAPPING = { + # key = C API function name + # value = HPy API function name + 'Py_FatalError': 'HPy_FatalError', + 'PyContextVar_Get': 'HPyContextVar_Get', + 'PyLong_FromLong': 'HPyLong_FromLong', + 'PyLong_FromLongLong': 'HPyLong_FromLongLong', + 'PyLong_FromUnsignedLong': 'HPyLong_FromUnsignedLong', + 'PyLong_FromUnsignedLongLong': 'HPyLong_FromUnsignedLongLong', + 'PyLong_AsLong': 'HPyLong_AsLong', + 'PyLong_AsLongLong': 'HPyLong_AsLongLong', + 'PyLong_AsUnsignedLong': 'HPyLong_AsUnsignedLong', + 'PyLong_AsUnsignedLongMask': 'HPyLong_AsUnsignedLongMask', + 'PyLong_AsUnsignedLongLong': 'HPyLong_AsUnsignedLongLong', + 'PyLong_AsUnsignedLongLongMask': 'HPyLong_AsUnsignedLongLongMask', + 'PyBool_FromLong': 'HPyBool_FromLong', + 'PyObject_TypeCheck': 'HPy_TypeCheck', + 'PySlice_AdjustIndices': 'HPySlice_AdjustIndices', + 'PyType_IsSubtype': 'HPyType_IsSubtype', + 'PyObject_Call': 'HPy_CallTupleDict', + 'PyObject_Type': 'HPy_Type', + 'PyObject_Vectorcall': 'HPy_Call', + 'PyObject_VectorcallMethod': 'HPy_CallMethod', +} + +# Some C API functions are documented in very different pages. +DOC_C_API_PAGES_SPECIAL_CASES = { + 'Py_FatalError': 'sys', + 'PyEval_SaveThread': 'init', + 'PyEval_RestoreThread': 'init', + 'PyEval_EvalCode': 'veryhigh', + 'PyObject_Call': 'call', + 'PyObject_Vectorcall': 'call', + 'PyObject_VectorcallMethod': 'call', +} + +# We assume that, e.g., prefix 'PyLong_Something' belongs to 'longobject.c' and +# its documentation is in '.../3/c-api/long.html'. In some cases, the prefix +# maps to a different page and this can be specified here. E.g. +# 'PyErr_Something' is documented in page '.../3/c-api/exceptions.html' +DOC_PREFIX_TABLE = { + 'err': 'exceptions', + 'contextvar': 'contextvars' +} \ No newline at end of file diff --git a/graalpython/hpy/hpy/tools/autogen/ctx.py b/graalpython/hpy/hpy/tools/autogen/ctx.py new file mode 100644 index 0000000000..4f569f1f35 --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/ctx.py @@ -0,0 +1,106 @@ +from copy import deepcopy +from pycparser import c_ast +from .autogenfile import AutoGenFile +from .parse import toC, find_typedecl, maybe_make_void + + +class autogen_ctx_h(AutoGenFile): + PATH = 'hpy/devel/include/hpy/universal/autogen_ctx.h' + + ## struct _HPyContext_s { + ## const char *name; + ## void *_private; + ## int abi_version; + ## HPy h_None; + ## ... + ## HPy (*ctx_Module_Create)(HPyContext *ctx, HPyModuleDef *def); + ## ... + ## } + + def generate(self): + # Put all declarations (variables and functions) into one list in order + # to be able to sort them by their given context index. + # We need to remember the output function per item (either + # 'declare_var' or 'declare_func'). So, we create tuples with structure + # '(decl, declare_*)'. + all_decls = [(x, self.declare_var) for x in self.api.variables] + all_decls += [(x, self.declare_func) for x in self.api.functions] + + # sort the list of all declaration by 'decl.ctx_index' + all_decls.sort(key=lambda x: x[0].ctx_index) + + lines = [] + w = lines.append + w('struct _HPyContext_s {') + w(' const char *name; // used just to make debugging and testing easier') + w(' void *_private; // used by implementations to store custom data') + w(' int abi_version;') + for var, cons in all_decls: + w(' %s;' % cons(var)) + w('};') + return '\n'.join(lines) + + def declare_var(self, var): + return toC(var.node) + + def declare_func(self, func): + # e.g. "HPy (*ctx_Module_Create)(HPyContext *ctx, HPyModuleDef *def)" + # + # turn the function declaration into a function POINTER declaration + newnode = deepcopy(func.node) + newnode.type = c_ast.PtrDecl(type=newnode.type, quals=[]) + maybe_make_void(func, newnode) + + # fix the name of the function pointer + typedecl = find_typedecl(newnode) + typedecl.declname = func.ctx_name() + return toC(newnode) + + +class autogen_ctx_def_h(AutoGenFile): + PATH = 'hpy/universal/src/autogen_ctx_def.h' + + ## struct _HPyContext_s g_universal_ctx = { + ## .name = "...", + ## ._private = NULL, + ## .abi_version = HPY_ABI_VERSION, + ## .h_None = {CONSTANT_H_NONE}, + ## ... + ## .ctx_Module_Create = &ctx_Module_Create, + ## ... + ## } + + def generate(self): + lines = [] + w = lines.append + w('struct _HPyContext_s g_universal_ctx = {') + w(' .name = "HPy Universal ABI (CPython backend)",') + w(' ._private = NULL,') + w(' .abi_version = HPY_ABI_VERSION,') + w(' /* h_None & co. are initialized by init_universal_ctx() */') + for func in self.api.functions: + w(' .%s = &%s,' % (func.ctx_name(), func.ctx_name())) + w('};') + return '\n'.join(lines) + + +class cpython_autogen_ctx_h(AutoGenFile): + PATH = 'hpy/devel/include/hpy/cpython/autogen_ctx.h' + + def generate(self): + # Put all variable declarations into a list in order + # to be able to sort them by their given context index. + var_decls = list(self.api.variables) + + # sort the list of var declaration by 'decl.ctx_index' + var_decls.sort(key=lambda x: x.ctx_index) + + lines = [] + w = lines.append + w('struct _HPyContext_s {') + w(' const char *name;') + w(' int abi_version;') + for var in var_decls: + w(' %s;' % toC(var.node)) + w('};') + return '\n'.join(lines) diff --git a/graalpython/hpy/hpy/tools/autogen/debug.py b/graalpython/hpy/hpy/tools/autogen/debug.py new file mode 100644 index 0000000000..eb8783ba0a --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/debug.py @@ -0,0 +1,228 @@ +from copy import deepcopy +from pycparser import c_ast +from .autogenfile import AutoGenFile +from .parse import toC, find_typedecl, get_context_return_type, \ + maybe_make_void, make_void, get_return_constant +from .hpyfunc import NO_CALL + + +class HPy_2_DHPy_Visitor(c_ast.NodeVisitor): + "Visitor which renames all HPy types to DHPy" + + def visit_IdentifierType(self, node): + if node.names == ['HPy']: + node.names = ['DHPy'] + + def visit_TypeDecl(self, node): + if node.declname == 'ctx': + node.declname = 'dctx' + self.generic_visit(node) + +def funcnode_with_new_name(node, name): + newnode = deepcopy(node) + typedecl = find_typedecl(newnode) + typedecl.declname = name + return newnode + +def get_debug_wrapper_node(func): + newnode = funcnode_with_new_name(func.node, 'debug_%s' % func.ctx_name()) + maybe_make_void(func, newnode) + # fix all the types + visitor = HPy_2_DHPy_Visitor() + visitor.visit(newnode) + return newnode + + +class autogen_debug_ctx_init_h(AutoGenFile): + PATH = 'hpy/debug/src/autogen_debug_ctx_init.h' + + def generate(self): + lines = [] + w = lines.append + # emit the declarations for all the debug_ctx_* functions + for func in self.api.functions: + w(toC(get_debug_wrapper_node(func)) + ';') + w('') + w('static inline void debug_ctx_init_fields(HPyContext *dctx, HPyContext *uctx)') + w('{') + for var in self.api.variables: + name = var.name + w(f' dctx->{name} = DHPy_open_immortal(dctx, uctx->{name});') + for func in self.api.functions: + name = func.ctx_name() + w(f' dctx->{name} = &debug_{name};') + + w('}') + return '\n'.join(lines) + + +class autogen_debug_wrappers(AutoGenFile): + PATH = 'hpy/debug/src/autogen_debug_wrappers.c' + + NO_WRAPPER = { + '_HPy_CallRealFunctionFromTrampoline', + 'HPy_Close', + 'HPyUnicode_AsUTF8AndSize', + 'HPyTuple_FromArray', + 'HPyType_GenericNew', + 'HPyType_FromSpec', + '_HPy_AsStruct_Legacy', + '_HPy_AsStruct_Object', + '_HPy_AsStruct_Type', + '_HPy_AsStruct_Long', + '_HPy_AsStruct_Float', + '_HPy_AsStruct_Unicode', + '_HPy_AsStruct_Tuple', + '_HPy_AsStruct_List', + '_HPy_AsStruct_Dict', + 'HPyTracker_New', + 'HPyTracker_Add', + 'HPyTracker_ForgetAll', + 'HPyTracker_Close', + 'HPyBytes_AsString', + 'HPyBytes_AS_STRING', + 'HPyTupleBuilder_New', + 'HPyTupleBuilder_Set', + 'HPyTupleBuilder_Build', + 'HPyTupleBuilder_Cancel', + 'HPyListBuilder_New', + 'HPyListBuilder_Set', + 'HPyListBuilder_Build', + 'HPyListBuilder_Cancel', + 'HPy_TypeCheck', + 'HPyContextVar_Get', + 'HPyType_GetName', + 'HPyType_IsSubtype', + 'HPyUnicode_Substring', + 'HPy_Call', + 'HPy_CallMethod', + } + + def generate(self): + lines = [] + w = lines.append + w('#include "debug_internal.h"') + w('') + for func in self.api.functions: + debug_wrapper = self.gen_debug_wrapper(func) + if debug_wrapper: + w(debug_wrapper) + w('') + return '\n'.join(lines) + + def gen_debug_wrapper(self, func): + if func.name in self.NO_WRAPPER: + return + # + assert not func.is_varargs() + node = get_debug_wrapper_node(func) + const_return = get_return_constant(func) + if const_return: + make_void(node) + signature = toC(node) + rettype = get_context_return_type(node, const_return) + # + def get_params_and_decls(): + lst = [] + decls = [] + for p in node.type.args.params: + if p.name == 'ctx': + lst.append('get_info(dctx)->uctx') + elif toC(p.type) == 'DHPy': + decls.append(' HPy dh_%s = DHPy_unwrap(dctx, %s);' % (p.name, p.name)) + lst.append('dh_%s' % p.name) + elif toC(p.type) in ('DHPy *', 'DHPy []'): + assert False, ('C type %s not supported, please write the wrapper ' + 'for %s by hand' % (toC(p.type), func.name)) + else: + lst.append(p.name) + return (', '.join(lst), '\n'.join(decls)) + (params, param_decls) = get_params_and_decls() + # + lines = [] + w = lines.append + w(signature) + w('{') + w(' if (!get_ctx_info(dctx)->is_valid) {') + w(' report_invalid_debug_context();') + w(' }') + if param_decls: + w(param_decls) + w(' get_ctx_info(dctx)->is_valid = false;') + if rettype == 'void': + w(f' {func.name}({params});') + w(' get_ctx_info(dctx)->is_valid = true;') + elif rettype == 'DHPy': + w(f' HPy universal_result = {func.name}({params});') + w(' get_ctx_info(dctx)->is_valid = true;') + w(' return DHPy_open(dctx, universal_result);') + else: + w(f' {rettype} universal_result = {func.name}({params});') + w(' get_ctx_info(dctx)->is_valid = true;') + w(' return universal_result;') + w('}') + return '\n'.join(lines) + + +class autogen_debug_ctx_call_i(AutoGenFile): + PATH = 'hpy/debug/src/autogen_debug_ctx_call.i' + + def generate(self): + lines = [] + w = lines.append + for hpyfunc in self.api.hpyfunc_typedefs: + name = hpyfunc.base_name() + NAME = name.upper() + if NAME in NO_CALL: + continue + # + c_ret_type = toC(hpyfunc.return_type()) + args = ['next_dctx'] + dhpys = [] + for i, param in enumerate(hpyfunc.params()[1:]): + pname = param.name + if pname is None: + pname = 'arg%d' % i + if toC(param.type) == 'HPy': + dhpys.append(pname) + args.append(f'dh_{pname}') + else: + args.append(f'a->{pname}') + args = ', '.join(args) + # + w(f' case HPyFunc_{NAME}: {{') + w(f' HPyFunc_{name} f = (HPyFunc_{name})func;') + w(f' _HPyFunc_args_{NAME} *a = (_HPyFunc_args_{NAME}*)args;') + for pname in dhpys: + w(f' DHPy dh_{pname} = _py2dh(dctx, a->{pname});') + # + w(' HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx);') + w(' if (next_dctx == NULL) {') + if c_ret_type == 'HPy': + w(' a->result = NULL;') + elif c_ret_type == 'int' or c_ret_type == 'HPy_ssize_t' or c_ret_type == 'HPy_hash_t': + w(' a->result = -1;') + else: + assert c_ret_type == 'void', c_ret_type + " not implemented" + w(' return;') + w(' }') + # + if c_ret_type == 'void': + w(f' f({args});') + elif c_ret_type == 'HPy': + w(f' DHPy dh_result = f({args});') + else: + w(f' a->result = f({args});') + # + w(' _switch_back_to_original_dctx(dctx, next_dctx);') + # + for pname in dhpys: + w(f' DHPy_close_and_check(dctx, dh_{pname});') + # + if c_ret_type == 'HPy': + w(f' a->result = _dh2py(dctx, dh_result);') + w(f' DHPy_close(dctx, dh_result);') + # + w(f' return;') + w(f' }}') + return '\n'.join(lines) diff --git a/graalpython/hpy/hpy/tools/autogen/doc.py b/graalpython/hpy/hpy/tools/autogen/doc.py new file mode 100644 index 0000000000..9824768866 --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/doc.py @@ -0,0 +1,173 @@ +import textwrap +import re + +from .autogenfile import AutoGenFile +from .parse import toC +from .ctx import autogen_ctx_h +from .conf import (DOC_C_API_PAGES_SPECIAL_CASES, + DOC_MANUAL_API_MAPPING, + DOC_PREFIX_TABLE) + + +CTX_NAME = '_HPyContext_s' + +RST_DISCLAIMER = """ +.. note: DO NOT EDIT THIS FILE! + This file is automatically generated by {clsname} + See also hpy.tools.autogen and hpy/tools/public_api.h + + Run this to regenerate: + make autogen +""" + +class AutoGenRstFile(AutoGenFile): + LANGUAGE = 'rst' + PATH = None + DISCLAIMER = None + + def __init__(self, api): + if self.DISCLAIMER is None and self.LANGUAGE == 'rst': + self.DISCLAIMER = RST_DISCLAIMER + self.api = api + +class autogen_function_index(AutoGenRstFile): + PATH = 'docs/api-reference/function-index.rst' + LANGUAGE = 'rst' + + def generate(self): + lines = [] + w = lines.append + w('HPy Core API Function Index') + w('###########################') + w('') + functions = list(self.api.functions) + # sort the list of functions by 'func.name' + functions.sort(key=lambda x: x.name) + for func in functions: + if func.name[0] != '_': + w(f'* :c:func:`{func.name}`') + return '\n'.join(lines) + + +class AutoGenFilePart: + PATH = None + BEGIN_MARKER = None + END_MARKER = None + + def __init__(self, api): + self.api = api + + def generate(self, old): + raise NotImplementedError + + def write(self, root): + if not self.BEGIN_MARKER or not self.END_MARKER: + raise RuntimeError("missing BEGIN_MARKER or END_MARKER") + n_begin = len(self.BEGIN_MARKER) + with root.join(self.PATH).open('r', encoding='utf-8') as f: + content = f.read() + start = content.find(self.BEGIN_MARKER) + if start < 0: + raise RuntimeError(f'begin marker "{self.BEGIN_MARKER}" not found' + f'in file {self.PATH}') + end = content.find(self.END_MARKER, start + n_begin) + if end < 0: + raise RuntimeError(f'end marker "{self.END_MARKER}" not found in' + f'file {self.PATH}') + new_content = self.generate(content[(start+n_begin):end]) + with root.join(self.PATH).open('w', encoding='utf-8') as f: + f.write(content[:start + n_begin] + new_content + content[end:]) + + +GROUP_PATTERN = re.compile('Py(\\w+)_.*') + +class autogen_doc_api_mapping(AutoGenFilePart): + PATH = 'docs/porting-guide.rst' + BEGIN_MARKER = '.. mark: BEGIN API MAPPING\n' + END_MARKER = '.. mark: END API MAPPING\n' + + def _get_page(self, cpython_fun_name): + if cpython_fun_name in DOC_C_API_PAGES_SPECIAL_CASES: + return DOC_C_API_PAGES_SPECIAL_CASES[cpython_fun_name] + '.html' + + first_underscore = cpython_fun_name.find('_') + if cpython_fun_name.startswith('Py') and first_underscore != -1: + prefix = cpython_fun_name[2:first_underscore].lower() + return DOC_PREFIX_TABLE.get(prefix, prefix) + '.html' + else: + return 'abstract.html' + + def generate(self, old_content): + table_directive = '.. _table-mapping:\n.. table:: Safe API function mapping\n' + assert old_content.strip().startswith(table_directive) + + lines = [] + w = lines.append + w(':widths: auto') + w('') + mapping = {x.cpython_name: x.name for x in self.api.functions if x.cpython_name} + mapping.update(DOC_MANUAL_API_MAPPING) + max_width0 = 0 + max_width1 = 0 + rows = [] + cpy_functions = list(mapping.keys()) + # sort the list of functions by 'cpython_name' + cpy_functions.sort() + for cpy_func in cpy_functions: + assert cpy_func + page = self._get_page(cpy_func) + col0 = f'`{cpy_func} `_' + col1 = f':c:func:`{mapping[cpy_func]}`' + rows.append((col0, col1)) + max_width0 = max(max_width0, len(col0)) + max_width1 = max(max_width1, len(col1)) + + sep = '=' * max_width0 + ' ' + '=' * max_width1 + w(sep) + w('C API function'.ljust(max_width0) + ' HPY API function') + w(sep) + for row in rows: + w(f'{row[0].ljust(max_width0)} {row[1]}') + w(sep) + w('') + return table_directive + textwrap.indent('\n'.join(lines), ' ' * 4) + + +class autogen_hpy_ctx(AutoGenRstFile): + PATH = 'docs/api-reference/hpy-ctx.rst' + + def generate(self): + lines = [] + w = lines.append + w(textwrap.dedent( + ''' + HPy Context + =========== + + The ``HPyContext`` structure is also part of the API since it provides handles + for built-in objects. For a high-level description of the context, please also + read :ref:`api:hpycontext`. + + .. warning:: It is fine to use handles from the context (e.g. ``ctx->h_None``) + but it is **STRONGLY** discouraged to directly call any context function. + This is because, for example, when compiling for :term:`CPython ABI`, the + context functions won't be used. + ''')) + # Put all variable declarations into a list in order + # to be able to sort them by their given context index. + var_decls = list(self.api.variables) + + # sort the list of var declaration by 'decl.ctx_index' + var_decls.sort(key=lambda x: x.ctx_index) + + w(f'.. c:struct:: {CTX_NAME}') + w(f' :module: {autogen_ctx_h.PATH}') + w('') + w(f' .. c:member:: const char *{CTX_NAME}.name') + w('') + w(f' .. c:member:: int {CTX_NAME}.abi_version') + for var in var_decls: + w('') + w(f' .. c:member:: {toC(var.node)}') + return '\n'.join(lines) + diff --git a/graalpython/hpy/hpy/tools/autogen/hpyfunc.py b/graalpython/hpy/hpy/tools/autogen/hpyfunc.py new file mode 100644 index 0000000000..1e233277f2 --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/hpyfunc.py @@ -0,0 +1,204 @@ +from copy import deepcopy +from pycparser import c_ast +from .autogenfile import AutoGenFile +from .parse import toC, find_typedecl + +NO_CALL = ('VARARGS', 'KEYWORDS', 'INITPROC', 'DESTROYFUNC', + 'GETBUFFERPROC', 'RELEASEBUFFERPROC', 'TRAVERSEPROC', 'MOD_CREATE', + 'VECTORCALLFUNC', 'NEWFUNC') +NO_TRAMPOLINE = NO_CALL + ('RICHCMPFUNC',) + +# This is a list of type that can automatically be converted from Python to HPy +# and vice versa. +AUTO_CONVERSION_TYPES = ('HPy', 'HPy_ssize_t', 'void *', 'int', 'char *', + 'HPy_hash_t', 'HPy_RichCmpOp', 'void') + +class autogen_hpyfunc_declare_h(AutoGenFile): + PATH = 'hpy/devel/include/hpy/autogen_hpyfunc_declare.h' + + ## #define _HPyFunc_DECLARE_HPyFunc_NOARGS(SYM) \ + ## static HPy SYM(HPyContext *ctx, HPy self) + + def generate(self): + lines = [] + w = lines.append + for hpyfunc in self.api.hpyfunc_typedefs: + # declare a function named 'SYM' of the appropriate type + funcdecl = hpyfunc.node.type.type + symdecl = deepcopy(funcdecl) + if isinstance(symdecl.type, c_ast.PtrDecl): + symdecl.type = symdecl.type.type + symdecl.type.declname = 'SYM' + symdecl = toC(symdecl) + # + # generate a macro emitting 'symdecl' + name = hpyfunc.base_name().upper() + w(f'#define _HPyFunc_DECLARE_HPyFunc_{name}(SYM) static {symdecl}') + w('') + + for hpyfunc in self.api.hpyfunc_typedefs: + # generate the typedef for HPyFunc_{base_name} + w(f'{toC(hpyfunc.node)};') + + return '\n'.join(lines) + + +def hpy_to_cpy(declnode): + if toC(declnode.type) == 'HPy': + declnode = deepcopy(declnode) + declnode.type.type.names = ['cpy_PyObject'] + declnode.type = c_ast.PtrDecl(type=declnode.type, quals=[]) + return declnode + + +class autogen_hpyfunc_trampoline_h(AutoGenFile): + PATH = 'hpy/devel/include/hpy/universal/autogen_hpyfunc_trampolines.h' + + def generate(self): + lines = [] + w = lines.append + for hpyfunc in self.api.hpyfunc_typedefs: + NAME = hpyfunc.base_name().upper() + if NAME in NO_TRAMPOLINE: + continue + # + tramp_node = deepcopy(hpyfunc.node.type.type) + if isinstance(tramp_node.type, c_ast.PtrDecl): + tramp_node.type = tramp_node.type.type + tramp_node.type.declname = 'SYM' + tramp_node = hpy_to_cpy(tramp_node) + assert toC(tramp_node.args.params[0].type) in ['void', 'HPyContext *'] + tramp_node.args.params = [hpy_to_cpy(p) + for p in tramp_node.args.params[1:]] + for i, param in enumerate(tramp_node.args.params): + typedecl = find_typedecl(param.type) + if typedecl.declname is None: + param.name = 'arg%d' % i + typedecl.declname = 'arg%d' % i + arg_names = [param.name for param in tramp_node.args.params] + arg_names = ', '.join(arg_names) + # + # generate the struct that will contain all parameters + w(f'typedef struct {{') + for param in tramp_node.args.params: + w(f' {toC(param)};') + if toC(tramp_node.type) != 'void': + w(f' {toC(tramp_node.type)} result;') + w(f'}} _HPyFunc_args_{NAME};') + w('') + # + # generate the trampoline itself + w(f'#define _HPyFunc_TRAMPOLINE_HPyFunc_{NAME}(SYM, IMPL) \\') + w(f' static {toC(tramp_node)} \\') + w(f' {{ \\') + w(f' _HPyFunc_args_{NAME} a = {{ {arg_names} }}; \\') + w(f' _HPy_CallRealFunctionFromTrampoline( \\') + w(f' _ctx_for_trampolines, HPyFunc_{NAME}, (HPyCFunction)IMPL, &a); \\') + if toC(tramp_node.type) == 'void': + w(f' return; \\') + else: + w(f' return a.result; \\') + w(f' }}') + w('') + return '\n'.join(lines) + + +def _py2h(type): + if type == 'HPy': + return '_py2h' + elif type in AUTO_CONVERSION_TYPES: + return '' + raise TypeError(f'cannot generate automatic conversion for type \'{type}\'') + + +def _h2py(type): + if type == 'HPy': + return '_h2py' + elif type in AUTO_CONVERSION_TYPES: + return '' + raise TypeError(f'cannot generate automatic conversion for type \'{type}\'') + + +class autogen_ctx_call_i(AutoGenFile): + PATH = 'hpy/universal/src/autogen_ctx_call.i' + + def generate(self): + lines = [] + w = lines.append + for hpyfunc in self.api.hpyfunc_typedefs: + name = hpyfunc.base_name() + NAME = name.upper() + if NAME in NO_CALL: + continue + # + c_ret_type = toC(hpyfunc.return_type()) + args = ['ctx'] + for i, param in enumerate(hpyfunc.params()[1:]): + pname = param.name + if pname is None: + pname = 'arg%d' % i + args.append(f'{_py2h(toC(param.type))}(a->{pname})') + args = ', '.join(args) + # + w(f' case HPyFunc_{NAME}: {{') + w(f' HPyFunc_{name} f = (HPyFunc_{name})func;') + w(f' _HPyFunc_args_{NAME} *a = (_HPyFunc_args_{NAME}*)args;') + if c_ret_type == 'void': + w(f' f({args});') + else: + w(f' a->result = {_h2py(c_ret_type)}(f({args}));') + w(f' return;') + w(f' }}') + return '\n'.join(lines) + + +class autogen_cpython_hpyfunc_trampoline_h(AutoGenFile): + PATH = 'hpy/devel/include/hpy/cpython/autogen_hpyfunc_trampolines.h' + + def generate(self): + lines = [] + w = lines.append + for hpyfunc in self.api.hpyfunc_typedefs: + name = hpyfunc.base_name() + NAME = name.upper() + if NAME in NO_TRAMPOLINE: + continue + # + tramp_node = deepcopy(hpyfunc.node.type.type) + if isinstance(tramp_node.type, c_ast.PtrDecl): + tramp_node.type = tramp_node.type.type + tramp_node.type.declname = 'SYM' + tramp_node = hpy_to_cpy(tramp_node) + tramp_node.args.params = [hpy_to_cpy(p) + for p in tramp_node.args.params[1:]] + for i, param in enumerate(tramp_node.args.params): + typedecl = find_typedecl(param.type) + if typedecl.declname is None: + param.name = 'arg%d' % i + typedecl.declname = 'arg%d' % i + + result = _h2py(toC(hpyfunc.return_type())) + args = ['_HPyGetContext()'] + func_ptr_ret_type = toC(hpyfunc.return_type()) + func_ptr_sig = ['HPyContext *'] + for i, param in enumerate(hpyfunc.params()[1:]): + pname = param.name + if pname is None: + pname = 'arg%d' % i + func_ptr_sig.append(toC(param.type)) + args.append(f'{_py2h(toC(param.type))}({pname})') + args = ', '.join(args) + func_ptr_sig = ', '.join(func_ptr_sig) + # + w(f'typedef {func_ptr_ret_type} (*_HPyCFunction_{NAME})({func_ptr_sig});') + w(f'#define _HPyFunc_TRAMPOLINE_HPyFunc_{NAME}(SYM, IMPL) \\') + w(f' static {toC(tramp_node)} \\') + w(f' {{ \\') + w(f' _HPyCFunction_{NAME} func = (_HPyCFunction_{NAME})IMPL; \\') + if toC(tramp_node.type) == 'void': + w(f' func({args}); \\') + w(f' return; \\') + else: + w(f' return {result}(func({args})); \\') + w(f' }}') + return '\n'.join(lines) diff --git a/graalpython/hpy/hpy/tools/autogen/hpyslot.py b/graalpython/hpy/hpy/tools/autogen/hpyslot.py new file mode 100644 index 0000000000..3eff4d81ca --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/hpyslot.py @@ -0,0 +1,18 @@ +from pycparser import c_ast +from .autogenfile import AutoGenFile +from .parse import toC + +class autogen_hpyslot_h(AutoGenFile): + PATH = 'hpy/devel/include/hpy/autogen_hpyslot.h' + + def generate(self): + lines = [] + w = lines.append + w('typedef enum {') + for slot in self.api.hpyslots: + w(f' {slot.name} = {slot.value},') + w('} HPySlot_Slot;') + w('') + for slot in self.api.hpyslots: + w(f'#define _HPySlot_SIG__{slot.name} {slot.hpyfunc}') + return '\n'.join(lines) diff --git a/graalpython/hpy/hpy/tools/autogen/parse.py b/graalpython/hpy/hpy/tools/autogen/parse.py new file mode 100644 index 0000000000..6615eb1d50 --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/parse.py @@ -0,0 +1,278 @@ +from copy import deepcopy +import sys +import attr +import re +import py +import pycparser +import shutil +from pycparser import c_ast +from pycparser.c_generator import CGenerator +from sysconfig import get_config_var +from .conf import SPECIAL_CASES, RETURN_CONSTANT + +PUBLIC_API_H = py.path.local(__file__).dirpath('public_api.h') +CURRENT_DIR = py.path.local(__file__).dirpath() +AUTOGEN_H = py.path.local(__file__).dirpath('autogen.h') + + +def toC(node): + return toC.gen.visit(node) +toC.gen = CGenerator() + +def find_typedecl(node): + while not isinstance(node, c_ast.TypeDecl): + node = node.type + return node + +def get_context_return_type(func_node, const_return): + return 'void' if const_return else toC(func_node.type.type) + +def make_void(func_node): + voidid = c_ast.IdentifierType(names=['void']) + func_node.type.type.type = c_ast.TypeDecl(declname='void', quals=[], align=[], type=voidid) + +def get_return_constant(func): + return RETURN_CONSTANT.get(func.node.name) + +def maybe_make_void(func, node): + if RETURN_CONSTANT.get(func.node.name): + make_void(node) + +@attr.s +class Function: + _BASE_NAME = re.compile(r'^_?HPy_?') + + name = attr.ib() + cpython_name = attr.ib() + ctx_index = attr.ib() + node = attr.ib(repr=False) + + def base_name(self): + return self._BASE_NAME.sub('', self.name) + + def ctx_name(self): + # e.g. "ctx_Module_Create" + return self._BASE_NAME.sub(r'ctx_', self.name) + + def is_varargs(self): + return (len(self.node.type.args.params) > 0 and + isinstance(self.node.type.args.params[-1], c_ast.EllipsisParam)) + + +@attr.s +class GlobalVar: + name = attr.ib() + ctx_index = attr.ib() + node = attr.ib(repr=False) + + def ctx_name(self): + return self.name + + +@attr.s +class HPyFunc: + _BASE_NAME = re.compile(r'^HPyFunc_?') + + name = attr.ib() + node = attr.ib(repr=False) + + def base_name(self): + return self._BASE_NAME.sub('', self.name) + + def params(self): + return self.node.type.type.args.params + + def return_type(self): + return self.node.type.type.type + +@attr.s +class HPySlot: + # represent a declaration contained inside enum HPySlot_Slot, such as: + # HPy_nb_add = SLOT(7, HPyFunc_BINARYFUNC) + + name = attr.ib() # "HPy_nb_add" + value = attr.ib() # "7" + hpyfunc = attr.ib() # "HPyFunc_BINARYFUNC" + node = attr.ib(repr=False) + + +class HPyAPIVisitor(pycparser.c_ast.NodeVisitor): + def __init__(self, api, convert_name): + self.api = api + self.convert_name = convert_name + self.cur_index = -1 + self.all_indices = [] + + def _consume_ctx_index(self): + idx = self.cur_index + self.all_indices.append(idx) + self.cur_index = -1 + return idx + + def verify_context_indices(self): + """ + Verifies if context indices are without gaps. This function raises an + assertion error if not. + For example: + [0, 1, 2, 3] is valid + [0, 1, 3] is invalid + """ + self.all_indices.sort() + for i in range(1, len(self.all_indices)): + prev = self.all_indices[i-1] + cur = self.all_indices[i] + assert prev + 1 == cur, \ + "context indices have gaps: %s -> %s" % (prev, cur) + + def _is_function_ptr(self, node): + return (isinstance(node, c_ast.PtrDecl) and + isinstance(node.type, c_ast.FuncDecl)) + + def visit_Decl(self, node): + if isinstance(node.type, c_ast.FuncDecl): + self._visit_function(node) + elif isinstance(node.type, c_ast.TypeDecl): + self._visit_global_var(node) + + def visit_Typedef(self, node): + # find only typedefs to function pointers whose name starts by HPyFunc_ + if node.name.startswith('HPyFunc_') and self._is_function_ptr(node.type): + self._visit_hpyfunc_typedef(node) + elif node.name == 'HPySlot_Slot': + self._visit_hpyslot_slot(node) + + def visit_Pragma(self, node): + parts = node.string.split('=') + if len(parts) != 2: + raise ValueError('invalid pragma: %s' % node) + self.cur_index = int(parts[1]) + + def _visit_function(self, node): + name = node.name + if not name.startswith('HPy') and not name.startswith('_HPy'): + print('WARNING: Ignoring non-hpy declaration: %s' % name) + return + for p in node.type.args.params: + if hasattr(p, 'name') and p.name is None: + raise ValueError("non-named argument in declaration of %s" % + name) + cpy_name = self.convert_name(name) + idx = self._consume_ctx_index() + if idx == -1: + raise ValueError('missing context index for %s' % name) + func = Function(name, cpy_name, idx, node) + self.api.functions.append(func) + + def _visit_global_var(self, node): + name = node.name + if not name.startswith('h_'): + print('WARNING: Ignoring non-hpy variable declaration: %s' % name) + return + assert toC(node.type.type) == "HPy" + idx = self._consume_ctx_index() + if idx == -1: + raise ValueError('missing context index for %s' % name) + var = GlobalVar(name, idx, node) + self.api.variables.append(var) + + def _visit_hpyfunc_typedef(self, node): + hpyfunc = HPyFunc(node.name, node) + self.api.hpyfunc_typedefs.append(hpyfunc) + + def _visit_hpyslot_slot(self, node): + for e in node.type.type.values.enumerators: + call = e.value + assert isinstance(call, c_ast.FuncCall) and call.name.name == 'SLOT' + assert len(call.args.exprs) == 2 + const_value, id_hpyfunc = call.args.exprs + assert isinstance(const_value, c_ast.Constant) and const_value.type == 'int' + assert isinstance(id_hpyfunc, c_ast.ID) + value = const_value.value + hpyfunc = id_hpyfunc.name + self.api.hpyslots.append(HPySlot(e.name, value, hpyfunc, e)) + + +def convert_name(hpy_name): + if hpy_name in SPECIAL_CASES: + return SPECIAL_CASES[hpy_name] + return re.sub(r'^_?HPy_?', 'Py', hpy_name) + + +class HPyAPI: + _r_comment = re.compile(r"/\*.*?\*/|//([^\n\\]|\\.)*?$", + re.DOTALL | re.MULTILINE) + + def __init__(self, filename): + cpp_cmd = get_config_var('CC') + if cpp_cmd: + cpp_cmd = cpp_cmd.split(' ') + elif sys.platform == 'win32': + cpp_cmd = [shutil.which("cl.exe")] + if sys.platform == 'win32': + cpp_cmd += ['/E', '/I%s' % CURRENT_DIR] + else: + cpp_cmd += ['-E', '-I%s' % CURRENT_DIR] + + msvc = "cl.exe" in cpp_cmd[0].casefold() + + csource = pycparser.preprocess_file(filename, + cpp_path=str(cpp_cmd[0]), + cpp_args=cpp_cmd[1:]) + + # MSVC preprocesses _Pragma(foo) to __pragma(foo), + # but cparser needs to see a #pragma, not __pragma. + if msvc: + csource = re.sub(r'__pragma\(([^)]+)\)', r'#pragma \1\n', csource) + + # Remove comments. NOTE: this assumes that comments are never inside + # string literals, but there shouldn't be any here. + def replace_keeping_newlines(m): + return ' ' + m.group().count('\n') * '\n' + csource = self._r_comment.sub(replace_keeping_newlines, csource) + self.ast = pycparser.CParser().parse(csource) + ## print(); self.ast.show() + self.collect_declarations() + + @classmethod + def parse(cls, filename): + return cls(filename) + + def get_func(self, name): + return self._lookup(name, self.functions) + + def get_var(self, name): + return self._lookup(name, self.variables) + + def get_hpyfunc_typedef(self, name): + return self._lookup(name, self.hpyfunc_typedefs) + + def get_slot(self, name): + return self._lookup(name, self.hpyslots) + + def _lookup(self, name, collection): + for x in collection: + if x.name == name: + return x + raise KeyError(name) + + def collect_declarations(self): + self.functions = [] + self.variables = [] + self.hpyfunc_typedefs = [] + self.hpyslots = [] + v = HPyAPIVisitor(self, convert_name) + v.visit(self.ast) + + v.verify_context_indices() + + # Sort lists such that the generated files are deterministic. + # List elements are either 'Function', 'GlobalVar', or 'HPyFunc'. All + # of them have a 'node' attribute and the nodes have a 'coord' attr + # that provides the line and column number. We use that to sort. + def node_key(e): + coord = e.node.coord + return coord.line, coord.column + self.functions.sort(key=node_key) + self.variables.sort(key=node_key) + self.hpyfunc_typedefs.sort(key=node_key) + self.hpyslots.sort(key=node_key) diff --git a/graalpython/hpy/hpy/tools/autogen/public_api.h b/graalpython/hpy/hpy/tools/autogen/public_api.h new file mode 100644 index 0000000000..b081d943a8 --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/public_api.h @@ -0,0 +1,1557 @@ +/* HPy public API */ + +/* + * IMPORTANT: In order to ensure backwards compatibility of HPyContext, it is + * necessary to define the order of the context members. To do so, use macro + * 'HPy_ID(idx)' for context handles and functions. When adding members, it + * doesn't matter where they are located in this file. It's just important that + * the maximum context index is incremented by exactly one. + */ + +#ifdef AUTOGEN + +/* Constants */ +HPy_ID(0) HPy h_None; +HPy_ID(1) HPy h_True; +HPy_ID(2) HPy h_False; +HPy_ID(3) HPy h_NotImplemented; +HPy_ID(4) HPy h_Ellipsis; + +/* Exceptions */ +HPy_ID(5) HPy h_BaseException; +HPy_ID(6) HPy h_Exception; +HPy_ID(7) HPy h_StopAsyncIteration; +HPy_ID(8) HPy h_StopIteration; +HPy_ID(9) HPy h_GeneratorExit; +HPy_ID(10) HPy h_ArithmeticError; +HPy_ID(11) HPy h_LookupError; +HPy_ID(12) HPy h_AssertionError; +HPy_ID(13) HPy h_AttributeError; +HPy_ID(14) HPy h_BufferError; +HPy_ID(15) HPy h_EOFError; +HPy_ID(16) HPy h_FloatingPointError; +HPy_ID(17) HPy h_OSError; +HPy_ID(18) HPy h_ImportError; +HPy_ID(19) HPy h_ModuleNotFoundError; +HPy_ID(20) HPy h_IndexError; +HPy_ID(21) HPy h_KeyError; +HPy_ID(22) HPy h_KeyboardInterrupt; +HPy_ID(23) HPy h_MemoryError; +HPy_ID(24) HPy h_NameError; +HPy_ID(25) HPy h_OverflowError; +HPy_ID(26) HPy h_RuntimeError; +HPy_ID(27) HPy h_RecursionError; +HPy_ID(28) HPy h_NotImplementedError; +HPy_ID(29) HPy h_SyntaxError; +HPy_ID(30) HPy h_IndentationError; +HPy_ID(31) HPy h_TabError; +HPy_ID(32) HPy h_ReferenceError; +HPy_ID(33) HPy h_SystemError; +HPy_ID(34) HPy h_SystemExit; +HPy_ID(35) HPy h_TypeError; +HPy_ID(36) HPy h_UnboundLocalError; +HPy_ID(37) HPy h_UnicodeError; +HPy_ID(38) HPy h_UnicodeEncodeError; +HPy_ID(39) HPy h_UnicodeDecodeError; +HPy_ID(40) HPy h_UnicodeTranslateError; +HPy_ID(41) HPy h_ValueError; +HPy_ID(42) HPy h_ZeroDivisionError; +HPy_ID(43) HPy h_BlockingIOError; +HPy_ID(44) HPy h_BrokenPipeError; +HPy_ID(45) HPy h_ChildProcessError; +HPy_ID(46) HPy h_ConnectionError; +HPy_ID(47) HPy h_ConnectionAbortedError; +HPy_ID(48) HPy h_ConnectionRefusedError; +HPy_ID(49) HPy h_ConnectionResetError; +HPy_ID(50) HPy h_FileExistsError; +HPy_ID(51) HPy h_FileNotFoundError; +HPy_ID(52) HPy h_InterruptedError; +HPy_ID(53) HPy h_IsADirectoryError; +HPy_ID(54) HPy h_NotADirectoryError; +HPy_ID(55) HPy h_PermissionError; +HPy_ID(56) HPy h_ProcessLookupError; +HPy_ID(57) HPy h_TimeoutError; +// EnvironmentError, IOError and WindowsError are intentionally omitted (they +// are all aliases of OSError since Python 3.3). + +/* Warnings */ +HPy_ID(58) HPy h_Warning; +HPy_ID(59) HPy h_UserWarning; +HPy_ID(60) HPy h_DeprecationWarning; +HPy_ID(61) HPy h_PendingDeprecationWarning; +HPy_ID(62) HPy h_SyntaxWarning; +HPy_ID(63) HPy h_RuntimeWarning; +HPy_ID(64) HPy h_FutureWarning; +HPy_ID(65) HPy h_ImportWarning; +HPy_ID(66) HPy h_UnicodeWarning; +HPy_ID(67) HPy h_BytesWarning; +HPy_ID(68) HPy h_ResourceWarning; + +/* Types */ +HPy_ID(69) HPy h_BaseObjectType; /* built-in 'object' */ +HPy_ID(70) HPy h_TypeType; /* built-in 'type' */ +HPy_ID(71) HPy h_BoolType; /* built-in 'bool' */ +HPy_ID(72) HPy h_LongType; /* built-in 'int' */ +HPy_ID(73) HPy h_FloatType; /* built-in 'float' */ +HPy_ID(74) HPy h_UnicodeType; /* built-in 'str' */ +HPy_ID(75) HPy h_TupleType; /* built-in 'tuple' */ +HPy_ID(76) HPy h_ListType; /* built-in 'list' */ +HPy_ID(238) HPy h_ComplexType; /* built-in 'complex' */ +HPy_ID(239) HPy h_BytesType; /* built-in 'bytes' */ +HPy_ID(240) HPy h_MemoryViewType; /* built-in 'memoryview' */ +HPy_ID(241) HPy h_CapsuleType; /* built-in 'capsule' */ +HPy_ID(242) HPy h_SliceType; /* built-in 'slice' */ +HPy_ID(263) HPy h_DictType; /* built-in 'dict' */ + +/* Reflection */ +HPy_ID(243) HPy h_Builtins; /* dict of builtins */ + +#endif + +HPy_ID(77) +HPy HPy_Dup(HPyContext *ctx, HPy h); +HPy_ID(78) +void HPy_Close(HPyContext *ctx, HPy h); + +HPy_ID(79) +HPy HPyLong_FromInt32_t(HPyContext *ctx, int32_t value); +HPy_ID(80) +HPy HPyLong_FromUInt32_t(HPyContext *ctx, uint32_t value); +HPy_ID(81) +HPy HPyLong_FromInt64_t(HPyContext *ctx, int64_t v); +HPy_ID(82) +HPy HPyLong_FromUInt64_t(HPyContext *ctx, uint64_t v); +HPy_ID(83) +HPy HPyLong_FromSize_t(HPyContext *ctx, size_t value); +HPy_ID(84) +HPy HPyLong_FromSsize_t(HPyContext *ctx, HPy_ssize_t value); + +HPy_ID(85) +int32_t HPyLong_AsInt32_t(HPyContext *ctx, HPy h); +HPy_ID(86) +uint32_t HPyLong_AsUInt32_t(HPyContext *ctx, HPy h); +HPy_ID(87) +uint32_t HPyLong_AsUInt32_tMask(HPyContext *ctx, HPy h); +HPy_ID(88) +int64_t HPyLong_AsInt64_t(HPyContext *ctx, HPy h); +HPy_ID(89) +uint64_t HPyLong_AsUInt64_t(HPyContext *ctx, HPy h); +HPy_ID(90) +uint64_t HPyLong_AsUInt64_tMask(HPyContext *ctx, HPy h); +HPy_ID(91) +size_t HPyLong_AsSize_t(HPyContext *ctx, HPy h); +HPy_ID(92) +HPy_ssize_t HPyLong_AsSsize_t(HPyContext *ctx, HPy h); +HPy_ID(93) +void* HPyLong_AsVoidPtr(HPyContext *ctx, HPy h); +HPy_ID(94) +double HPyLong_AsDouble(HPyContext *ctx, HPy h); + +HPy_ID(95) +HPy HPyFloat_FromDouble(HPyContext *ctx, double v); +HPy_ID(96) +double HPyFloat_AsDouble(HPyContext *ctx, HPy h); + +HPy_ID(97) +HPy HPyBool_FromBool(HPyContext *ctx, bool v); + + +/* abstract.h */ +HPy_ID(98) +HPy_ssize_t HPy_Length(HPyContext *ctx, HPy h); + +HPy_ID(99) +int HPyNumber_Check(HPyContext *ctx, HPy h); +HPy_ID(100) +HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(101) +HPy HPy_Subtract(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(102) +HPy HPy_Multiply(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(103) +HPy HPy_MatrixMultiply(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(104) +HPy HPy_FloorDivide(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(105) +HPy HPy_TrueDivide(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(106) +HPy HPy_Remainder(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(107) +HPy HPy_Divmod(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(108) +HPy HPy_Power(HPyContext *ctx, HPy h1, HPy h2, HPy h3); +HPy_ID(109) +HPy HPy_Negative(HPyContext *ctx, HPy h1); +HPy_ID(110) +HPy HPy_Positive(HPyContext *ctx, HPy h1); +HPy_ID(111) +HPy HPy_Absolute(HPyContext *ctx, HPy h1); +HPy_ID(112) +HPy HPy_Invert(HPyContext *ctx, HPy h1); +HPy_ID(113) +HPy HPy_Lshift(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(114) +HPy HPy_Rshift(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(115) +HPy HPy_And(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(116) +HPy HPy_Xor(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(117) +HPy HPy_Or(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(118) +HPy HPy_Index(HPyContext *ctx, HPy h1); +HPy_ID(119) +HPy HPy_Long(HPyContext *ctx, HPy h1); +HPy_ID(120) +HPy HPy_Float(HPyContext *ctx, HPy h1); + +HPy_ID(121) +HPy HPy_InPlaceAdd(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(122) +HPy HPy_InPlaceSubtract(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(123) +HPy HPy_InPlaceMultiply(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(124) +HPy HPy_InPlaceMatrixMultiply(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(125) +HPy HPy_InPlaceFloorDivide(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(126) +HPy HPy_InPlaceTrueDivide(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(127) +HPy HPy_InPlaceRemainder(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(128) +HPy HPy_InPlacePower(HPyContext *ctx, HPy h1, HPy h2, HPy h3); +HPy_ID(129) +HPy HPy_InPlaceLshift(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(130) +HPy HPy_InPlaceRshift(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(131) +HPy HPy_InPlaceAnd(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(132) +HPy HPy_InPlaceXor(HPyContext *ctx, HPy h1, HPy h2); +HPy_ID(133) +HPy HPy_InPlaceOr(HPyContext *ctx, HPy h1, HPy h2); + +HPy_ID(134) +int HPyCallable_Check(HPyContext *ctx, HPy h); + +/** + * Call a Python object. + * + * :param ctx: + * The execution context. + * :param callable: + * A handle to the Python object to call (must not be ``HPy_NULL``). + * :param args: + * A handle to a tuple containing the positional arguments (must not be + * ``HPy_NULL`` but can, of course, be empty). + * :param kw: + * A handle to a Python dictionary containing the keyword arguments (may be + * ``HPy_NULL``). + * + * :returns: + * The result of the call on success, or ``HPy_NULL`` in case of an error. + */ +HPy_ID(135) +HPy HPy_CallTupleDict(HPyContext *ctx, HPy callable, HPy args, HPy kw); + +/** + * Call a Python object. + * + * :param ctx: + * The execution context. + * :param callable: + * A handle to the Python object to call (must not be ``HPy_NULL``). + * :param args: + * A pointer to an array of positional and keyword arguments. This argument + * must not be ``NULL`` if ``nargs > 0`` or + * ``HPy_Length(ctx, kwnames) > 0``. + * :param nargs: + * The number of positional arguments in ``args``. + * :param kwnames: + * A handle to the tuple of keyword argument names (may be ``HPy_NULL``). + * The values of the keyword arguments are also passed in ``args`` appended + * to the positional arguments. Argument ``nargs`` does not include the + * keyword argument count. + * + * :returns: + * The result of the call on success, or ``HPy_NULL`` in case of an error. + */ +HPy_ID(261) +HPy HPy_Call(HPyContext *ctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames); + +/** + * Call a method of a Python object. + * + * :param ctx: + * The execution context. + * :param name: + * A handle to the name (a Unicode object) of the method. Must not be + * ``HPy_NULL``. + * :param args: + * A pointer to an array of the arguments. The receiver is ``args[0]``, and + * the positional and keyword arguments are starting at ``args[1]``. This + * argument must not be ``NULL`` since a receiver is always required. + * :param nargs: + * The number of positional arguments in ``args`` including the receiver at + * ``args[0]`` (therefore, ``nargs`` must be at least ``1``). + * :param kwnames: + * A handle to the tuple of keyword argument names (may be ``HPy_NULL``). + * The values of the keyword arguments are also passed in ``args`` appended + * to the positional arguments. Argument ``nargs`` does not include the + * keyword argument count. + * + * :returns: + * The result of the call on success, or ``HPy_NULL`` in case of an error. + */ +HPy_ID(262) +HPy HPy_CallMethod(HPyContext *ctx, HPy name, const HPy *args, size_t nargs, HPy kwnames); + +/** + * Return a new iterator for iterable object ``obj``. This is the equivalent + * of the Python expression ``iter(obj)``. + * + * :param ctx: + * The execution context. + * :param obj: + * An iterable Python object (must not be ``HPy_NULL``). If the object is + * not iterable, a ``TypeError`` will be raised. + * + * :returns: + * The new iterator, ``obj`` itself if it is already an iterator, or + * ``HPy_NULL`` on failure. + */ +HPy_ID(269) +HPy HPy_GetIter(HPyContext *ctx, HPy obj); + +/** + * Return the next value from iterator ``obj``. + * + * :param ctx: + * The execution context. + * :param obj: + * An iterator Python object (must not be ``HPy_NULL``). This can be + * verified with ``HPy_IterCheck``. Otherwise, the behavior is undefined. + * + * :returns: + * The new value in iterator ``obj``, or ``HPy_NULL`` on failure. If the + * iterator was exhausted normally, an exception will not be set. In + * case of some other error, one will be set. + */ +HPy_ID(270) +HPy HPyIter_Next(HPyContext *ctx, HPy obj); + +/** + * Tests if an object is an instance of a Python iterator. + * + * :param ctx: + * The execution context. + * :param obj: + * A handle to an arbitrary object (must not be ``HPy_NULL``). + * + * :returns: + * Non-zero if object ``obj`` provides the ``Iterator`` protocol, and ``0`` + * otherwise. + */ +HPy_ID(271) +int HPyIter_Check(HPyContext *ctx, HPy obj); + +/* pyerrors.h */ +HPy_ID(136) +void HPy_FatalError(HPyContext *ctx, const char *message); +HPy_ID(137) +HPy HPyErr_SetString(HPyContext *ctx, HPy h_type, const char *utf8_message); +HPy_ID(138) +HPy HPyErr_SetObject(HPyContext *ctx, HPy h_type, HPy h_value); + +/** + * Similar to :c:func:`HPyErr_SetFromErrnoWithFilenameObjects` but takes one + * filename (a C string) that will be decoded using + * :c:func:`HPyUnicode_DecodeFSDefault`. + * + * :param ctx: + * The execution context. + * :param h_type: + * The exception type to raise. + * :param filename_fsencoded: + * a filename; may be ``NULL`` + * + * :return: + * always returns ``HPy_NULL`` + */ +HPy_ID(139) +HPy HPyErr_SetFromErrnoWithFilename(HPyContext *ctx, HPy h_type, const char *filename_fsencoded); + +/** + * A convenience function to raise an exception when a C library function has + * returned an error and set the C variable ``errno``. It constructs an + * instance of the provided exception type ``h_type`` by calling + * ``h_type(errno, strerror(errno), filename1, 0, filename2)``. The exception + * instance is then raised. + * + * :param ctx: + * The execution context. + * :param h_type: + * The exception type to raise. + * :param filename1: + * A filename; may be ``HPy_NULL``. In the case of ``h_type`` is the + * ``OSError`` exception, this is used to define the filename attribute of + * the exception instance. + * :param filename2: + * another filename argument; may be ``HPy_NULL`` + * + * :return: + * always returns ``HPy_NULL`` + */ +HPy_ID(140) +HPy HPyErr_SetFromErrnoWithFilenameObjects(HPyContext *ctx, HPy h_type, HPy filename1, HPy filename2); +/* note: HPyErr_Occurred() returns a flag 0-or-1, instead of a 'PyObject *' */ +HPy_ID(141) +int HPyErr_Occurred(HPyContext *ctx); +HPy_ID(142) +int HPyErr_ExceptionMatches(HPyContext *ctx, HPy exc); +HPy_ID(143) +HPy HPyErr_NoMemory(HPyContext *ctx); +HPy_ID(144) +void HPyErr_Clear(HPyContext *ctx); +HPy_ID(145) +HPy HPyErr_NewException(HPyContext *ctx, const char *utf8_name, HPy base, HPy dict); +HPy_ID(146) +HPy HPyErr_NewExceptionWithDoc(HPyContext *ctx, const char *utf8_name, const char *utf8_doc, HPy base, HPy dict); +HPy_ID(147) +int HPyErr_WarnEx(HPyContext *ctx, HPy category, const char *utf8_message, HPy_ssize_t stack_level); +HPy_ID(148) +void HPyErr_WriteUnraisable(HPyContext *ctx, HPy obj); + +/* object.h */ +HPy_ID(149) +int HPy_IsTrue(HPyContext *ctx, HPy h); + +/** + * Create a type from a :c:struct:`HPyType_Spec` and an additional list of + * specification parameters. + * + * :param ctx: + * The execution context. + * :param spec: + * The type spec to use to create the type. + * :param params: + * A 0-terminated list of type specification parameters or ``NULL``. + * + * :returns: a handle of the created type on success, ``HPy_NULL`` on failure. + */ +HPy_ID(150) +HPy HPyType_FromSpec(HPyContext *ctx, HPyType_Spec *spec, + HPyType_SpecParam *params); +HPy_ID(151) +HPy HPyType_GenericNew(HPyContext *ctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw); + +HPy_ID(152) +HPy HPy_GetAttr(HPyContext *ctx, HPy obj, HPy name); +HPy_ID(153) +HPy HPy_GetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name); + +HPy_ID(154) +int HPy_HasAttr(HPyContext *ctx, HPy obj, HPy name); +HPy_ID(155) +int HPy_HasAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name); + +HPy_ID(156) +int HPy_SetAttr(HPyContext *ctx, HPy obj, HPy name, HPy value); +HPy_ID(157) +int HPy_SetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name, HPy value); + +HPy_ID(158) +HPy HPy_GetItem(HPyContext *ctx, HPy obj, HPy key); +HPy_ID(159) +HPy HPy_GetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx); +HPy_ID(160) +HPy HPy_GetItem_s(HPyContext *ctx, HPy obj, const char *utf8_key); + +/** + * Return the slice of sequence object ``obj`` between ``start`` and ``end``. + * This is the equivalent of the Python expression ``obj[start:end]``. + * + * :param ctx: + * The execution context. + * :param obj: + * A sliceable Python object (must not be ``HPy_NULL`` otherwise a + * ``SystemError`` will be raised). If the object is not sliceable, a + * ``TypeError`` will be raised. + * :param start: + * The start index (inclusive). + * :param end: + * The end index (exclusive). + * + * :returns: + * The requested slice or ``HPy_NULL`` on failure. + */ +HPy_ID(266) +HPy HPy_GetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end); + +HPy_ID(161) +int HPy_Contains(HPyContext *ctx, HPy container, HPy key); + +HPy_ID(162) +int HPy_SetItem(HPyContext *ctx, HPy obj, HPy key, HPy value); +HPy_ID(163) +int HPy_SetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx, HPy value); +HPy_ID(164) +int HPy_SetItem_s(HPyContext *ctx, HPy obj, const char *utf8_key, HPy value); + +/** + * Assign the sequence object ``value`` to the slice in sequence object ``obj`` + * from ``start`` to ``end``. This is the equivalent of the Python statement + * ``obj[start:end] = value``. + * + * :param ctx: + * The execution context. + * :param obj: + * A sliceable Python object (must not be ``HPy_NULL`` otherwise a + * ``SystemError`` will be raised). If the object is not sliceable, a + * ``TypeError`` will be raised. + * :param start: + * The start index (inclusive). + * :param end: + * The end index (exclusive). + * :param value: + * The sequence object to assign (must not be ``HPy_NULL``). + * + * :returns: + * ``0`` on success; ``-1`` on failure + */ +HPy_ID(267) +int HPy_SetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end, HPy value); + +HPy_ID(235) +int HPy_DelItem(HPyContext *ctx, HPy obj, HPy key); +HPy_ID(236) +int HPy_DelItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx); +HPy_ID(237) +int HPy_DelItem_s(HPyContext *ctx, HPy obj, const char *utf8_key); + +/** + * Delete the slice of sequence object ``obj`` between ``start`` and ``end``. + * This is the equivalent of the Python statement ``del obj[start:end]``. + * + * :param ctx: + * The execution context. + * :param obj: + * A sliceable Python object (must not be ``HPy_NULL`` otherwise a + * ``SystemError`` will be raised). If the object is not sliceable, a + * ``TypeError`` will be raised. + * :param start: + * The start index (inclusive). + * :param end: + * The end index (exclusive). + * + * :returns: + * ``0`` on success; ``-1`` on failure + */ +HPy_ID(268) +int HPy_DelSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end); + +/** + * Returns the type of the given object ``obj``. + * + * On failure, raises ``SystemError`` and returns ``HPy_NULL``. This is + * equivalent to the Python expression``type(obj)``. + * + * :param ctx: + * The execution context. + * :param obj: + * a Python object (must not be ``HPy_NULL``) + * + * :returns: + * The type of ``obj`` or ``HPy_NULL`` in case of errors. + */ +HPy_ID(165) +HPy HPy_Type(HPyContext *ctx, HPy obj); + +/** + * Checks if ``ob`` is an instance of ``type`` or any subtype of ``type``. + * + * :param ctx: + * The execution context. + * :param obj: + * a Python object (must not be ``HPy_NULL``) + * :param type: + * A Python type object. This argument must not be ``HPy_NULL`` and must be + * a type (i.e. it must inherit from Python ``type``). If this is not the + * case, the behavior is undefined (verification of the argument is only + * done in debug mode). + * + * :returns: + * Non-zero if object ``obj`` is an instance of type ``type`` or an instance + * of a subtype of ``type``, and ``0`` otherwise. + */ +HPy_ID(166) +int HPy_TypeCheck(HPyContext *ctx, HPy obj, HPy type); + +/** + * Return the type's name. + * + * Equivalent to getting the type's ``__name__`` attribute. If you want to + * retrieve the type's name as a handle that refers to a ``str``, then just use + * ``HPy_GetAttr_s(ctx, type, "__name__")``. + * + * :param ctx: + * The execution context. + * :param type: + * A Python type object. This argument must not be ``HPy_NULL`` and must be + * a type (i.e. it must inherit from Python ``type``). If this is not the + * case, the behavior is undefined (verification of the argument is only + * done in debug mode). + * + * :returns: + * The name of the type as C string (UTF-8 encoded) or ``NULL`` in case of + * an error. The returned pointer is read-only and guaranteed to be valid as + * long as the handle ``type`` is valid. + */ +HPy_ID(253) +const char *HPyType_GetName(HPyContext *ctx, HPy type); + +/** + * Checks if ``sub`` is a subtype of ``type``. + * + * This function only checks for actual subtypes, which means that + * ``__subclasscheck__()`` is not called on ``type``. + * + * :param ctx: + * The execution context. + * :param sub: + * A Python type object. This argument must not be ``HPy_NULL`` and must be + * a type (i.e. it must inherit from Python ``type``). If this is not the + * case, the behavior is undefined (verification of the argument is only + * done in debug mode). + * :param type: + * A Python type object. This argument must not be ``HPy_NULL`` and must be + * a type (i.e. it must inherit from Python ``type``). If this is not the + * case, the behavior is undefined (verification of the argument is only + * done in debug mode). + * + * :returns: + * Non-zero if ``sub`` is a subtype of ``type``. + */ +HPy_ID(254) +int HPyType_IsSubtype(HPyContext *ctx, HPy sub, HPy type); + +HPy_ID(167) +int HPy_Is(HPyContext *ctx, HPy obj, HPy other); + +HPy_ID(168) +void* _HPy_AsStruct_Object(HPyContext *ctx, HPy h); +HPy_ID(169) +void* _HPy_AsStruct_Legacy(HPyContext *ctx, HPy h); +HPy_ID(228) +void* _HPy_AsStruct_Type(HPyContext *ctx, HPy h); +HPy_ID(229) +void* _HPy_AsStruct_Long(HPyContext *ctx, HPy h); +HPy_ID(230) +void* _HPy_AsStruct_Float(HPyContext *ctx, HPy h); +HPy_ID(231) +void* _HPy_AsStruct_Unicode(HPyContext *ctx, HPy h); +HPy_ID(232) +void* _HPy_AsStruct_Tuple(HPyContext *ctx, HPy h); +HPy_ID(233) +void* _HPy_AsStruct_List(HPyContext *ctx, HPy h); +HPy_ID(264) +void* _HPy_AsStruct_Dict(HPyContext *ctx, HPy h); +HPy_ID(234) +HPyType_BuiltinShape _HPyType_GetBuiltinShape(HPyContext *ctx, HPy h_type); + +HPy_ID(170) +HPy _HPy_New(HPyContext *ctx, HPy h_type, void **data); + +HPy_ID(171) +HPy HPy_Repr(HPyContext *ctx, HPy obj); +HPy_ID(172) +HPy HPy_Str(HPyContext *ctx, HPy obj); +HPy_ID(173) +HPy HPy_ASCII(HPyContext *ctx, HPy obj); +HPy_ID(174) +HPy HPy_Bytes(HPyContext *ctx, HPy obj); + +HPy_ID(175) +HPy HPy_RichCompare(HPyContext *ctx, HPy v, HPy w, int op); +HPy_ID(176) +int HPy_RichCompareBool(HPyContext *ctx, HPy v, HPy w, int op); + +HPy_ID(177) +HPy_hash_t HPy_Hash(HPyContext *ctx, HPy obj); + +/* bytesobject.h */ +HPy_ID(178) +int HPyBytes_Check(HPyContext *ctx, HPy h); +HPy_ID(179) +HPy_ssize_t HPyBytes_Size(HPyContext *ctx, HPy h); +HPy_ID(180) +HPy_ssize_t HPyBytes_GET_SIZE(HPyContext *ctx, HPy h); +HPy_ID(181) +const char* HPyBytes_AsString(HPyContext *ctx, HPy h); +HPy_ID(182) +const char* HPyBytes_AS_STRING(HPyContext *ctx, HPy h); +HPy_ID(183) +HPy HPyBytes_FromString(HPyContext *ctx, const char *bytes); +HPy_ID(184) +HPy HPyBytes_FromStringAndSize(HPyContext *ctx, const char *bytes, HPy_ssize_t len); + +/* unicodeobject.h */ +HPy_ID(185) +HPy HPyUnicode_FromString(HPyContext *ctx, const char *utf8); +HPy_ID(186) +int HPyUnicode_Check(HPyContext *ctx, HPy h); +HPy_ID(187) +HPy HPyUnicode_AsASCIIString(HPyContext *ctx, HPy h); +HPy_ID(188) +HPy HPyUnicode_AsLatin1String(HPyContext *ctx, HPy h); +HPy_ID(189) +HPy HPyUnicode_AsUTF8String(HPyContext *ctx, HPy h); +HPy_ID(190) +const char* HPyUnicode_AsUTF8AndSize(HPyContext *ctx, HPy h, HPy_ssize_t *size); +HPy_ID(191) +HPy HPyUnicode_FromWideChar(HPyContext *ctx, const wchar_t *w, HPy_ssize_t size); +HPy_ID(192) +HPy HPyUnicode_DecodeFSDefault(HPyContext *ctx, const char *v); +HPy_ID(193) +HPy HPyUnicode_DecodeFSDefaultAndSize(HPyContext *ctx, const char *v, HPy_ssize_t size); +HPy_ID(194) +HPy HPyUnicode_EncodeFSDefault(HPyContext *ctx, HPy h); +HPy_ID(195) +HPy_UCS4 HPyUnicode_ReadChar(HPyContext *ctx, HPy h, HPy_ssize_t index); +HPy_ID(196) +HPy HPyUnicode_DecodeASCII(HPyContext *ctx, const char *ascii, HPy_ssize_t size, const char *errors); +HPy_ID(197) +HPy HPyUnicode_DecodeLatin1(HPyContext *ctx, const char *latin1, HPy_ssize_t size, const char *errors); + +/** + * Decode a bytes-like object to a Unicode object. + * + * The bytes of the bytes-like object are decoded according to the given + * encoding and using the error handling defined by ``errors``. + * + * :param ctx: + * The execution context. + * :param obj: + * A bytes-like object. This can be, for example, Python *bytes*, + * *bytearray*, *memoryview*, *array.array* and objects that support the + * Buffer protocol. If this argument is `HPy_NULL``, a ``SystemError`` will + * be raised. If the argument is not a bytes-like object, a ``TypeError`` + * will be raised. + * :param encoding: + * The name (UTF-8 encoded C string) of the encoding to use. If the encoding + * does not exist, a ``LookupError`` will be raised. If this argument is + * ``NULL``, the default encoding ``UTF-8`` will be used. + * :param errors: + * The error handling (UTF-8 encoded C string) to use when decoding. The + * possible values depend on the used encoding. This argument may be + * ``NULL`` in which case it will default to ``"strict"``. + * + * :returns: + * A handle to a ``str`` object created from the decoded bytes or + * ``HPy_NULL`` in case of errors. + */ +HPy_ID(255) +HPy HPyUnicode_FromEncodedObject(HPyContext *ctx, HPy obj, const char *encoding, const char *errors); + +/** + * Return a substring of ``str``, from character index ``start`` (included) to + * character index ``end`` (excluded). + * + * Indices ``start`` and ``end`` must not be negative, otherwise an + * ``IndexError`` will be raised. If ``start >= len(str)`` or if + * ``end < start``, an empty string will be returned. If ``end > len(str)`` then + * ``end == len(str)`` will be assumed. + * + * :param ctx: + * The execution context. + * :param str: + * A Python Unicode object (must not be ``HPy_NULL``). Otherwise, the + * behavior is undefined (verification of the argument is only done in + * debug mode). + * :param start: + * The non-negative start index (inclusive). + * :param end: + * The non-negative end index (exclusive). + * + * :returns: + * The requested substring or ``HPy_NULL`` in case of an error. + */ +HPy_ID(256) +HPy HPyUnicode_Substring(HPyContext *ctx, HPy str, HPy_ssize_t start, HPy_ssize_t end); + +/* listobject.h */ + +/** + * Tests if an object is an instance of a Python list. + * + * :param ctx: + * The execution context. + * :param h: + * A handle to an arbitrary object (must not be ``HPy_NULL``). + * + * :returns: + * Non-zero if object ``h`` is an instance of type ``list`` or an instance + * of a subtype of ``list``, and ``0`` otherwise. + */ +HPy_ID(198) +int HPyList_Check(HPyContext *ctx, HPy h); + +/** + * Creates a new list instance with length ``len``. + * + * :param ctx: + * The execution context. + * :param len: + * A Python list object (must not be ``HPy_NULL``). Otherwise, a + * ``SystemError`` will be raised. + * + * :returns: + * The new list instance on success, or ``HPy_NULL`` on failure. + */ +HPy_ID(199) +HPy HPyList_New(HPyContext *ctx, HPy_ssize_t len); + +/** + * Append item ``h_item`` to list ``h_list``. + * + * :param ctx: + * The execution context. + * :param h_list: + * A Python list object (must not be ``HPy_NULL``). Otherwise, a + * ``SystemError`` will be raised. + * :param h_item: + * The item to append (must not be ``HPy_NULL``). + * + * :returns: + * Return ``0`` if successful; return ``-1`` and set an exception if + * unsuccessful. + */ +HPy_ID(200) +int HPyList_Append(HPyContext *ctx, HPy h_list, HPy h_item); + +/** + * Insert the item ``h_item`` into list ``h_list`` in front of index ``index``. + * + * :param ctx: + * The execution context. + * :param h_list: + * A Python list object (must not be ``HPy_NULL``). Otherwise, a + * ``SystemError`` will be raised. + * :param index: + * The index where the element should be inserted before. A negative index + * is allowed and is then interpreted to be relative to the end of sequence. + * E.g. ``index == -1`` is the last element. + * If ``index < -n`` (where ``n`` is the length of the list), it will be + * replaced by ``0``. If ``index > n``, it will be replaced by ``n``. + * :param h_item: + * The item to insert (must not be ``HPy_NULL``). + * + * :returns: + * Return ``0`` if successful; return ``-1`` and set an exception if + * unsuccessful. + */ +HPy_ID(265) +int HPyList_Insert(HPyContext *ctx, HPy h_list, HPy_ssize_t index, HPy h_item); + +/* dictobject.h */ + +/** + * Tests if an object is an instance of a Python dict. + * + * :param ctx: + * The execution context. + * :param h: + * A handle to an arbitrary object (must not be ``HPy_NULL``). + * + * :returns: + * Non-zero if object ``h`` is an instance of type ``dict`` or an instance + * of a subtype of ``dict``, and ``0`` otherwise. + */ +HPy_ID(201) +int HPyDict_Check(HPyContext *ctx, HPy h); + +/** + * Creates a new empty Python dictionary. + * + * :param ctx: + * The execution context. + * + * :returns: + * A handle to the new and empty Python dictionary or ``HPy_NULL`` in case + * of an error. + */ +HPy_ID(202) +HPy HPyDict_New(HPyContext *ctx); + +/** + * Returns a list of all keys from the dictionary. + * + * Note: This function will directly access the storage of the dict object and + * therefore ignores if method ``keys`` was overwritten. + * + * :param ctx: + * The execution context. + * :param h: + * A Python dict object. If this argument is ``HPy_NULL`` or not an + * instance of a Python dict, a ``SystemError`` will be raised. + * + * :returns: + * A Python list object containing all keys of the given dictionary or + * ``HPy_NULL`` in case of an error. + */ +HPy_ID(257) +HPy HPyDict_Keys(HPyContext *ctx, HPy h); + +/** + * Creates a copy of the provided Python dict object. + * + * :param ctx: + * The execution context. + * :param h: + * A Python dict object. If this argument is ``HPy_NULL`` or not an + * instance of a Python dict, a ``SystemError`` will be raised. + * + * :returns: + * Return a new dictionary that contains the same key-value pairs as ``h`` + * or ``HPy_NULL`` in case of an error. + */ +HPy_ID(258) +HPy HPyDict_Copy(HPyContext *ctx, HPy h); + +/* tupleobject.h */ + +/** + * Tests if an object is an instance of a Python tuple. + * + * :param ctx: + * The execution context. + * :param h: + * A handle to an arbitrary object (must not be ``HPy_NULL``). + * + * :returns: + * Non-zero if object ``h`` is an instance of type ``tuple`` or an instance + * of a subtype of ``tuple``, and ``0`` otherwise. + */ +HPy_ID(203) +int HPyTuple_Check(HPyContext *ctx, HPy h); + +/** + * Create a tuple from an array. + * + * Note: Consider to use the convenience function :c:func:`HPyTuple_Pack` to + * create a tuple. + * + * :param ctx: + * The execution context. + * :param items: + * An array of items to use for initialization of the tuple. + * :param n: + * The number of elements in array ``items``. + * + * :return: + * A new tuple with ``n`` elements or ``HPy_NULL`` in case of an error + * occurred. + */ +HPy_ID(204) +HPy HPyTuple_FromArray(HPyContext *ctx, const HPy items[], HPy_ssize_t n); + +/* sliceobject.h */ + +/** + * Creates a new empty Python slice object. + * + * :param ctx: + * The execution context. + * + * :param start: + * A handle to an object to be used as the slice start value. + * :param end: + * A handle to an object to be used as the slice end value. + * :param step: + * A handle to an object to be used as the slice step value. + * + * :returns: + * A handle to the new and empty Python slice object or ``HPy_NULL`` in case + * of an error. + */ +HPy_ID(272) +HPy HPySlice_New(HPyContext *ctx, HPy start, HPy stop, HPy step); + +/** + * Extract the start, stop and step data members from a slice object as C + * integers. + * + * The slice members may be arbitrary int-like objects. If they are not Python + * int objects, they will be coerced to int objects by calling their + * ``__index__`` method. + * + * If a slice member value is out of bounds, it will be set to the maximum value + * of ``HPy_ssize_t`` if the member was a positive number, or to the minimum + * value of ``HPy_ssize_t`` if it was a negative number. + * + * :param ctx: + * The execution context. + * :param slice: + * A handle to a Python slice object. This argument must be a slice object + * and must not be ``HPy_NULL``. Otherwise, behavior is undefined. + * :param start: + * A pointer to a variable where to write the unpacked slice start. Must not + * be ``NULL``. + * :param end: + * A pointer to a variable where to write the unpacked slice end. Must not + * :param step: + * A pointer to a variable where to write the unpacked slice step. Must not + * be ``NULL``. + * + * :returns: + * ``-1`` on error, ``0`` on success + */ + +HPy_ID(259) +int HPySlice_Unpack(HPyContext *ctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step); + +/* import.h */ +HPy_ID(205) +HPy HPyImport_ImportModule(HPyContext *ctx, const char *utf8_name); + +/* pycapsule.h */ +HPy_ID(244) +HPy HPyCapsule_New(HPyContext *ctx, void *pointer, const char *utf8_name, HPyCapsule_Destructor *destructor); +HPy_ID(245) +void* HPyCapsule_Get(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, const char *utf8_name); +HPy_ID(246) +int HPyCapsule_IsValid(HPyContext *ctx, HPy capsule, const char *utf8_name); +HPy_ID(247) +int HPyCapsule_Set(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, void *value); + +/* integration with the old CPython API */ +HPy_ID(206) +HPy HPy_FromPyObject(HPyContext *ctx, cpy_PyObject *obj); +HPy_ID(207) +cpy_PyObject *HPy_AsPyObject(HPyContext *ctx, HPy h); + +/* internal helpers which need to be exposed to modules for practical reasons :( */ +HPy_ID(208) +void _HPy_CallRealFunctionFromTrampoline(HPyContext *ctx, + HPyFunc_Signature sig, + HPyCFunction func, + void *args); + +/* Builders */ + +/** + * Create a new list builder for ``size`` elements. The builder is then able to + * take at most ``size`` elements. This function does not raise any + * exception (even if running out of memory). + * + * :param ctx: + * The execution context. + * :param size: + * The number of elements to hold. + */ +HPy_ID(209) +HPyListBuilder HPyListBuilder_New(HPyContext *ctx, HPy_ssize_t size); + +/** + * Assign an element to a certain index of the builder. Valid indices are in + * range ``0 <= index < size`` where ``size`` is the value passed to + * :c:func:`HPyListBuilder_New`. This function does not raise any exception. + * + * :param ctx: + * The execution context. + * :param builder: + * A list builder handle. + * :param index: + * The index to assign the object to. + * :param h_item: + * An HPy handle of the object to store or ``HPy_NULL``. Please note that + * HPy **never** steals handles and so, ``h_item`` needs to be closed by + * the caller. + */ +HPy_ID(210) +void HPyListBuilder_Set(HPyContext *ctx, HPyListBuilder builder, + HPy_ssize_t index, HPy h_item); + +/** + * Build a list from a list builder. + * + * :param ctx: + * The execution context. + * :param builder: + * A list builder handle. + * + * :returns: + * An HPy handle to a list containing the values inserted with + * :c:func:`HPyListBuilder_Set` or ``HPy_NULL`` in case an error occurred + * during building or earlier when creating the builder or setting the + * items. + */ +HPy_ID(211) +HPy HPyListBuilder_Build(HPyContext *ctx, HPyListBuilder builder); + +/** + * Cancel building of a tuple and free any acquired resources. + * This function ignores if any error occurred previously when using the tuple + * builder. + * + * :param ctx: + * The execution context. + * :param builder: + * A tuple builder handle. + */ +HPy_ID(212) +void HPyListBuilder_Cancel(HPyContext *ctx, HPyListBuilder builder); + +/** + * Create a new tuple builder for ``size`` elements. The builder is then able + * to take at most ``size`` elements. This function does not raise any + * exception (even if running out of memory). + * + * :param ctx: + * The execution context. + * :param size: + * The number of elements to hold. + */ +HPy_ID(213) +HPyTupleBuilder HPyTupleBuilder_New(HPyContext *ctx, HPy_ssize_t size); + +/** + * Assign an element to a certain index of the builder. Valid indices are in + * range ``0 <= index < size`` where ``size`` is the value passed to + * :c:func:`HPyTupleBuilder_New`. This function does not raise * any exception. + * + * :param ctx: + * The execution context. + * :param builder: + * A tuple builder handle. + * :param index: + * The index to assign the object to. + * :param h_item: + * An HPy handle of the object to store or ``HPy_NULL``. Please note that + * HPy **never** steals handles and so, ``h_item`` needs to be closed by + * the caller. + */ +HPy_ID(214) +void HPyTupleBuilder_Set(HPyContext *ctx, HPyTupleBuilder builder, + HPy_ssize_t index, HPy h_item); + +/** + * Build a tuple from a tuple builder. + * + * :param ctx: + * The execution context. + * :param builder: + * A tuple builder handle. + * + * :returns: + * An HPy handle to a tuple containing the values inserted with + * :c:func:`HPyTupleBuilder_Set` or ``HPy_NULL`` in case an error occurred + * during building or earlier when creating the builder or setting the + * items. + */ +HPy_ID(215) +HPy HPyTupleBuilder_Build(HPyContext *ctx, HPyTupleBuilder builder); + +/** + * Cancel building of a tuple and free any acquired resources. + * This function ignores if any error occurred previously when using the tuple + * builder. + * + * :param ctx: + * The execution context. + * :param builder: + * A tuple builder handle. + */ +HPy_ID(216) +void HPyTupleBuilder_Cancel(HPyContext *ctx, HPyTupleBuilder builder); + +/* Helper for correctly closing handles */ + +HPy_ID(217) +HPyTracker HPyTracker_New(HPyContext *ctx, HPy_ssize_t size); +HPy_ID(218) +int HPyTracker_Add(HPyContext *ctx, HPyTracker ht, HPy h); +HPy_ID(219) +void HPyTracker_ForgetAll(HPyContext *ctx, HPyTracker ht); +HPy_ID(220) +void HPyTracker_Close(HPyContext *ctx, HPyTracker ht); + +/** + * HPyFields should be used ONLY in parts of memory which is known to the GC, + * e.g. memory allocated by HPy_New: + * + * - NEVER declare a local variable of type HPyField + * - NEVER use HPyField on a struct allocated by e.g. malloc() + * + * **CPython's note**: contrary to PyObject*, you don't need to manually + * manage refcounting when using HPyField: if you use HPyField_Store to + * overwrite an existing value, the old object will be automatically decrefed. + * This means that you CANNOT use HPyField_Store to write memory which + * contains uninitialized values, because it would try to decref a dangling + * pointer. + * + * Note that HPy_New automatically zeroes the memory it allocates, so + * everything works well out of the box. In case you are using manually + * allocated memory, you should initialize the HPyField to HPyField_NULL. + * + * Note the difference: + * + * - ``obj->f = HPyField_NULL``: this should be used only to initialize + * uninitialized memory. If you use it to overwrite a valid HPyField, you + * will cause a memory leak (at least on CPython) + * + * - HPyField_Store(ctx, &obj->f, HPy_NULL): this does the right thing and + * decref the old value. However, you CANNOT use it if the memory is not + * initialized. + * + * Note: target_object and source_object are there in case an implementation + * needs to add write and/or read barriers on the objects. They are ignored by + * CPython but e.g. PyPy needs a write barrier. +*/ +HPy_ID(221) +void HPyField_Store(HPyContext *ctx, HPy target_object, HPyField *target_field, HPy h); +HPy_ID(222) +HPy HPyField_Load(HPyContext *ctx, HPy source_object, HPyField source_field); + +/** + * Leaving Python execution: for releasing GIL and other use-cases. + * + * In most situations, users should prefer using convenience macros: + * HPy_BEGIN_LEAVE_PYTHON(context)/HPy_END_LEAVE_PYTHON(context) + * + * HPy extensions may leave Python execution when running Python independent + * code: long-running computations or blocking operations. When an extension + * has left the Python execution it must not call any HPy API other than + * HPy_ReenterPythonExecution. It can access pointers returned by HPy API, + * e.g., HPyUnicode_AsUTF8String, provided that they are valid at the point + * of calling HPy_LeavePythonExecution. + * + * Python execution must be reentered on the same thread as where it was left. + * The leave/enter calls must not be nested. Debug mode will, in the future, + * enforce these constraints. + * + * Python implementations may use this knowledge however they wish. The most + * obvious use case is to release the GIL, in which case the + * HPy_BEGIN_LEAVE_PYTHON/HPy_END_LEAVE_PYTHON becomes equivalent to + * Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS. +*/ +HPy_ID(223) +void HPy_ReenterPythonExecution(HPyContext *ctx, HPyThreadState state); +HPy_ID(224) +HPyThreadState HPy_LeavePythonExecution(HPyContext *ctx); + +/** + * HPyGlobal is an alternative to module state. HPyGlobal must be a statically + * allocated C global variable registered in HPyModuleDef.globals array. + * A HPyGlobal can be used only after the HPy module where it is registered was + * created using HPyModule_Create. + * + * HPyGlobal serves as an identifier of a Python object that should be globally + * available per one Python interpreter. Python objects referenced by HPyGlobals + * are destroyed automatically on the interpreter exit (not necessarily the + * process exit). + * + * HPyGlobal instance does not allow anything else but loading and storing + * a HPy handle using a HPyContext. Even if the HPyGlobal C variable may + * be shared between threads or different interpreter instances within one + * process, the API to load and store a handle from HPyGlobal is thread-safe (but + * like any other HPy API must not be called in HPy_LeavePythonExecution blocks). + * + * Given that a handle to object X1 is stored to HPyGlobal using HPyContext of + * Python interpreter I1, then loading a handle from the same HPyGlobal using + * HPyContext of Python interpreter I1 should give a handle to the same object + * X1. Another Python interpreter I2 running within the same process and using + * the same HPyGlobal variable will not be able to load X1 from it, it will have + * its own view on what is stored in the given HPyGlobal. + * + * Python interpreters may use indirection to isolate different interpreter + * instances, but alternative techniques such as copy-on-write or immortal + * objects can be used to avoid that indirection (even selectively on per + * object basis using tagged pointers). + * + * CPython HPy implementation may even provide configuration option that + * switches between a faster version that directly stores PyObject* to + * HPyGlobal but does not support subinterpreters, or a version that supports + * subinterpreters. For now, CPython HPy always stores PyObject* directly + * to HPyGlobal. + * + * While the standard implementation does not fully enforce the documented + * contract, the HPy debug mode will enforce it (not implemented yet). + * + * **Implementation notes:** + * All Python interpreters running in one process must be compatible, because + * they will share all HPyGlobal C level variables. The internal data stored + * in HPyGlobal are specific for each HPy implementation, each implementation + * is also responsible for handling thread-safety when initializing the + * internal data in HPyModule_Create. Note that HPyModule_Create may be called + * concurrently depending on the semantics of the Python implementation (GIL vs + * no GIL) and also depending on the whether there may be multiple instances of + * given Python interpreter running within the same process. In the future, HPy + * ABI may include a contract that internal data of each HPyGlobal must be + * initialized to its address using atomic write and HPy implementations will + * not be free to choose what to store in HPyGlobal, however, this will allow + * multiple different HPy implementations within one process. This contract may + * also be activated only by some runtime option, letting the HPy implementation + * use more optimized HPyGlobal implementation otherwise. +*/ +HPy_ID(225) +void HPyGlobal_Store(HPyContext *ctx, HPyGlobal *global, HPy h); +HPy_ID(226) +HPy HPyGlobal_Load(HPyContext *ctx, HPyGlobal global); + +/* Debugging helpers */ +HPy_ID(227) +void _HPy_Dump(HPyContext *ctx, HPy h); + +/* Evaluating Python statements/expressions */ + +/** + * Parse and compile the Python source code. + * + * :param ctx: + * The execution context. + * :param utf8_source: + * Python source code given as UTF-8 encoded C string (must not be ``NULL``). + * :param utf8_filename: + * The filename (UTF-8 encoded C string) to use for construction of the code + * object. It may appear in tracebacks or in ``SyntaxError`` exception + * messages. + * :param kind: + * The source kind which tells the parser if a single expression, statement, + * or a whole file should be parsed (see enum :c:enum:`HPy_SourceKind`). + * + * :returns: + * A Python code object resulting from the parsed and compiled Python source + * code or ``HPy_NULL`` in case of errors. + */ +HPy_ID(248) +HPy HPy_Compile_s(HPyContext *ctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind); + +/** + * Evaluate a precompiled code object. + * + * Code objects can be compiled from a string using :c:func:`HPy_Compile_s`. + * + * :param ctx: + * The execution context. + * :param code: + * The code object to evaluate. + * :param globals: + * A Python dictionary defining the global variables for the evaluation. + * :param locals: + * A mapping object defining the local variables for the evaluation. + * + * :returns: + * The result produced by the executed code. May be ``HPy_NULL`` in case of + * errors. + */ +HPy_ID(249) +HPy HPy_EvalCode(HPyContext *ctx, HPy code, HPy globals, HPy locals); +HPy_ID(250) +HPy HPyContextVar_New(HPyContext *ctx, const char *name, HPy default_value); +HPy_ID(251) +int32_t HPyContextVar_Get(HPyContext *ctx, HPy context_var, HPy default_value, HPy *result); +HPy_ID(252) +HPy HPyContextVar_Set(HPyContext *ctx, HPy context_var, HPy value); + +/** + * Set the call function for the given object. + * + * By defining slot ``HPy_tp_call`` for some type, instances of this type will + * be callable objects. The specified call function will be used by default for + * every instance. This should account for the most common case (every instance + * of an object uses the same call function) but to still provide the necessary + * flexibility, function ``HPy_SetCallFunction`` allows to set different (maybe + * specialized) call functions for each instance. This must be done in the + * constructor of an object. + * + * A more detailed description on how to use that function can be found in + * section :ref:`porting-guide:calling protocol`. + * + * :param ctx: + * The execution context. + * :param h: + * A handle to an object implementing the call protocol, i.e., the object's + * type must have slot ``HPy_tp_call``. Otherwise, a ``TypeError`` will be + * raised. This argument must not be ``HPy_NULL``. + * :param def: + * A pointer to the call function definition to set (must not be + * ``NULL``). The definition is usually created using + * :c:macro:`HPyDef_CALL_FUNCTION` + * + * :returns: + * ``0`` in case of success and ``-1`` in case of an error. + */ +HPy_ID(260) +int HPy_SetCallFunction(HPyContext *ctx, HPy h, HPyCallFunction *func); + +/* ******* + hpyfunc + ******* + + These typedefs are used to generate the various macros used by + include/common/hpyfunc.h +*/ +typedef HPy (*HPyFunc_noargs)(HPyContext *ctx, HPy self); +typedef HPy (*HPyFunc_o)(HPyContext *ctx, HPy self, HPy arg); +typedef HPy (*HPyFunc_varargs)(HPyContext *ctx, HPy self, const HPy *args, size_t nargs); +typedef HPy (*HPyFunc_keywords)(HPyContext *ctx, HPy self, const HPy *args, + size_t nargs, HPy kwnames); + +typedef HPy (*HPyFunc_unaryfunc)(HPyContext *ctx, HPy); +typedef HPy (*HPyFunc_binaryfunc)(HPyContext *ctx, HPy, HPy); +typedef HPy (*HPyFunc_ternaryfunc)(HPyContext *ctx, HPy, HPy, HPy); +typedef int (*HPyFunc_inquiry)(HPyContext *ctx, HPy); +typedef HPy_ssize_t (*HPyFunc_lenfunc)(HPyContext *ctx, HPy); +typedef HPy (*HPyFunc_ssizeargfunc)(HPyContext *ctx, HPy, HPy_ssize_t); +typedef HPy (*HPyFunc_ssizessizeargfunc)(HPyContext *ctx, HPy, HPy_ssize_t, HPy_ssize_t); +typedef int (*HPyFunc_ssizeobjargproc)(HPyContext *ctx, HPy, HPy_ssize_t, HPy); +typedef int (*HPyFunc_ssizessizeobjargproc)(HPyContext *ctx, HPy, HPy_ssize_t, HPy_ssize_t, HPy); +typedef int (*HPyFunc_objobjargproc)(HPyContext *ctx, HPy, HPy, HPy); +typedef void (*HPyFunc_freefunc)(HPyContext *ctx, void *); +typedef HPy (*HPyFunc_getattrfunc)(HPyContext *ctx, HPy, char *); +typedef HPy (*HPyFunc_getattrofunc)(HPyContext *ctx, HPy, HPy); +typedef int (*HPyFunc_setattrfunc)(HPyContext *ctx, HPy, char *, HPy); +typedef int (*HPyFunc_setattrofunc)(HPyContext *ctx, HPy, HPy, HPy); +typedef HPy (*HPyFunc_reprfunc)(HPyContext *ctx, HPy); +typedef HPy_hash_t (*HPyFunc_hashfunc)(HPyContext *ctx, HPy); +typedef HPy (*HPyFunc_richcmpfunc)(HPyContext *ctx, HPy, HPy, HPy_RichCmpOp); +typedef HPy (*HPyFunc_getiterfunc)(HPyContext *ctx, HPy); +typedef HPy (*HPyFunc_iternextfunc)(HPyContext *ctx, HPy); +typedef HPy (*HPyFunc_descrgetfunc)(HPyContext *ctx, HPy, HPy, HPy); +typedef int (*HPyFunc_descrsetfunc)(HPyContext *ctx, HPy, HPy, HPy); +typedef int (*HPyFunc_initproc)(HPyContext *ctx, HPy self, + const HPy *args, HPy_ssize_t nargs, HPy kw); +typedef HPy (*HPyFunc_newfunc)(HPyContext *ctx, HPy type, const HPy *args, + HPy_ssize_t nargs, HPy kw); +typedef HPy (*HPyFunc_getter)(HPyContext *ctx, HPy, void *); +typedef int (*HPyFunc_setter)(HPyContext *ctx, HPy, HPy, void *); +typedef int (*HPyFunc_objobjproc)(HPyContext *ctx, HPy, HPy); +typedef int (*HPyFunc_getbufferproc)(HPyContext *ctx, HPy, HPy_buffer *, int); +typedef void (*HPyFunc_releasebufferproc)(HPyContext *ctx, HPy, HPy_buffer *); +typedef int (*HPyFunc_traverseproc)(void *object, HPyFunc_visitproc visit, void *arg); +typedef void (*HPyFunc_destructor)(HPyContext *ctx, HPy); + +typedef void (*HPyFunc_destroyfunc)(void *); + +// Note: separate type, because we need a different trampoline +typedef HPy (*HPyFunc_mod_create)(HPyContext *ctx, HPy); + + +/* ~~~ HPySlot_Slot ~~~ + + The following enum is used to generate autogen_hpyslot.h, which contains: + + - The real definition of the enum HPySlot_Slot + + - the macros #define _HPySlot_SIGNATURE_* + +*/ + +// NOTE: if you uncomment/enable a slot below, make sure to write a corresponding +// test in test_slots.py + +/* Note that the magic numbers are the same as CPython */ +typedef enum { + HPy_bf_getbuffer = SLOT(1, HPyFunc_GETBUFFERPROC), + HPy_bf_releasebuffer = SLOT(2, HPyFunc_RELEASEBUFFERPROC), + HPy_mp_ass_subscript = SLOT(3, HPyFunc_OBJOBJARGPROC), + HPy_mp_length = SLOT(4, HPyFunc_LENFUNC), + HPy_mp_subscript = SLOT(5, HPyFunc_BINARYFUNC), + HPy_nb_absolute = SLOT(6, HPyFunc_UNARYFUNC), + HPy_nb_add = SLOT(7, HPyFunc_BINARYFUNC), + HPy_nb_and = SLOT(8, HPyFunc_BINARYFUNC), + HPy_nb_bool = SLOT(9, HPyFunc_INQUIRY), + HPy_nb_divmod = SLOT(10, HPyFunc_BINARYFUNC), + HPy_nb_float = SLOT(11, HPyFunc_UNARYFUNC), + HPy_nb_floor_divide = SLOT(12, HPyFunc_BINARYFUNC), + HPy_nb_index = SLOT(13, HPyFunc_UNARYFUNC), + HPy_nb_inplace_add = SLOT(14, HPyFunc_BINARYFUNC), + HPy_nb_inplace_and = SLOT(15, HPyFunc_BINARYFUNC), + HPy_nb_inplace_floor_divide = SLOT(16, HPyFunc_BINARYFUNC), + HPy_nb_inplace_lshift = SLOT(17, HPyFunc_BINARYFUNC), + HPy_nb_inplace_multiply = SLOT(18, HPyFunc_BINARYFUNC), + HPy_nb_inplace_or = SLOT(19, HPyFunc_BINARYFUNC), + HPy_nb_inplace_power = SLOT(20, HPyFunc_TERNARYFUNC), + HPy_nb_inplace_remainder = SLOT(21, HPyFunc_BINARYFUNC), + HPy_nb_inplace_rshift = SLOT(22, HPyFunc_BINARYFUNC), + HPy_nb_inplace_subtract = SLOT(23, HPyFunc_BINARYFUNC), + HPy_nb_inplace_true_divide = SLOT(24, HPyFunc_BINARYFUNC), + HPy_nb_inplace_xor = SLOT(25, HPyFunc_BINARYFUNC), + HPy_nb_int = SLOT(26, HPyFunc_UNARYFUNC), + HPy_nb_invert = SLOT(27, HPyFunc_UNARYFUNC), + HPy_nb_lshift = SLOT(28, HPyFunc_BINARYFUNC), + HPy_nb_multiply = SLOT(29, HPyFunc_BINARYFUNC), + HPy_nb_negative = SLOT(30, HPyFunc_UNARYFUNC), + HPy_nb_or = SLOT(31, HPyFunc_BINARYFUNC), + HPy_nb_positive = SLOT(32, HPyFunc_UNARYFUNC), + HPy_nb_power = SLOT(33, HPyFunc_TERNARYFUNC), + HPy_nb_remainder = SLOT(34, HPyFunc_BINARYFUNC), + HPy_nb_rshift = SLOT(35, HPyFunc_BINARYFUNC), + HPy_nb_subtract = SLOT(36, HPyFunc_BINARYFUNC), + HPy_nb_true_divide = SLOT(37, HPyFunc_BINARYFUNC), + HPy_nb_xor = SLOT(38, HPyFunc_BINARYFUNC), + HPy_sq_ass_item = SLOT(39, HPyFunc_SSIZEOBJARGPROC), + HPy_sq_concat = SLOT(40, HPyFunc_BINARYFUNC), + HPy_sq_contains = SLOT(41, HPyFunc_OBJOBJPROC), + HPy_sq_inplace_concat = SLOT(42, HPyFunc_BINARYFUNC), + HPy_sq_inplace_repeat = SLOT(43, HPyFunc_SSIZEARGFUNC), + HPy_sq_item = SLOT(44, HPyFunc_SSIZEARGFUNC), + HPy_sq_length = SLOT(45, HPyFunc_LENFUNC), + HPy_sq_repeat = SLOT(46, HPyFunc_SSIZEARGFUNC), + //HPy_tp_alloc = SLOT(47, HPyFunc_X), NOT SUPPORTED + //HPy_tp_base = SLOT(48, HPyFunc_X), + //HPy_tp_bases = SLOT(49, HPyFunc_X), + HPy_tp_call = SLOT(50, HPyFunc_KEYWORDS), + //HPy_tp_clear = SLOT(51, HPyFunc_X), NOT SUPPORTED, use tp_traverse + //HPy_tp_dealloc = SLOT(52, HPyFunc_X), NOT SUPPORTED + //HPy_tp_del = SLOT(53, HPyFunc_X), + HPy_tp_descr_get = SLOT(54, HPyFunc_TERNARYFUNC), + //HPy_tp_descr_set = SLOT(55, HPyFunc_X), + //HPy_tp_doc = SLOT(56, HPyFunc_X), + //HPy_tp_getattr = SLOT(57, HPyFunc_X), + //HPy_tp_getattro = SLOT(58, HPyFunc_X), + HPy_tp_hash = SLOT(59, HPyFunc_HASHFUNC), + HPy_tp_init = SLOT(60, HPyFunc_INITPROC), + //HPy_tp_is_gc = SLOT(61, HPyFunc_X), + //HPy_tp_iter = SLOT(62, HPyFunc_X), + //HPy_tp_iternext = SLOT(63, HPyFunc_X), + //HPy_tp_methods = SLOT(64, HPyFunc_X), NOT SUPPORTED + HPy_tp_new = SLOT(65, HPyFunc_NEWFUNC), + HPy_tp_repr = SLOT(66, HPyFunc_REPRFUNC), + HPy_tp_richcompare = SLOT(67, HPyFunc_RICHCMPFUNC), + //HPy_tp_setattr = SLOT(68, HPyFunc_X), + //HPy_tp_setattro = SLOT(69, HPyFunc_X), + HPy_tp_str = SLOT(70, HPyFunc_REPRFUNC), + HPy_tp_traverse = SLOT(71, HPyFunc_TRAVERSEPROC), + //HPy_tp_members = SLOT(72, HPyFunc_X), NOT SUPPORTED + //HPy_tp_getset = SLOT(73, HPyFunc_X), NOT SUPPORTED + //HPy_tp_free = SLOT(74, HPyFunc_X), NOT SUPPORTED + HPy_nb_matrix_multiply = SLOT(75, HPyFunc_BINARYFUNC), + HPy_nb_inplace_matrix_multiply = SLOT(76, HPyFunc_BINARYFUNC), + //HPy_am_await = SLOT(77, HPyFunc_X), + //HPy_am_aiter = SLOT(78, HPyFunc_X), + //HPy_am_anext = SLOT(79, HPyFunc_X), + HPy_tp_finalize = SLOT(80, HPyFunc_DESTRUCTOR), + + /* extra HPy slots */ + HPy_tp_destroy = SLOT(1000, HPyFunc_DESTROYFUNC), + + /** + * Module create slot: the function receives loader spec and should + * return an HPy handle representing the module. Currently, creating + * real module objects cannot be done by user code, so the only other + * useful thing that this slot can do is to create another object that + * can work as a module, such as SimpleNamespace. + */ + HPy_mod_create = SLOT(2000, HPyFunc_MOD_CREATE), + /** + * Module exec slot: the function receives module object that was created + * by the runtime from HPyModuleDef. This slot can do any initialization + * of the module, such as adding types. There can be multiple exec slots + * and they will be executed in the declaration order. + */ + HPy_mod_exec = SLOT(2001, HPyFunc_INQUIRY), + +} HPySlot_Slot; diff --git a/graalpython/hpy/hpy/tools/autogen/pypy.py b/graalpython/hpy/hpy/tools/autogen/pypy.py new file mode 100644 index 0000000000..702a519e84 --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/pypy.py @@ -0,0 +1,40 @@ +from .autogenfile import AutoGenFile +from .parse import toC + +# this class should probably be moved somewhere in the PyPy repo +class autogen_pypy_txt(AutoGenFile): + PATH = 'hpy/tools/autogen/autogen_pypy.txt' + LANGUAGE = 'txt' # to avoid inserting the disclaimer + + def generate(self): + lines = [] + w = lines.append + w("typedef struct _HPyContext_s {") + w(" int abi_version;") + for var in self.api.variables: + w(" struct _HPy_s %s;" % var.ctx_name()) + for func in self.api.functions: + w(" void * %s;" % func.ctx_name()) + w("} _struct_HPyContext_s;") + w("") + w("") + # generate stubs for all the API functions + for func in self.api.functions: + w(self.stub(func)) + return '\n'.join(lines) + + def stub(self, func): + signature = toC(func.node) + if func.is_varargs(): + return '# %s' % signature + # + argnames = [p.name for p in func.node.type.args.params] + lines = [] + w = lines.append + w('@API.func("%s")' % signature) + w('def %s(space, %s):' % (func.name, ', '.join(argnames))) + w(' from rpython.rlib.nonconst import NonConstant # for the annotator') + w(' if NonConstant(False): return 0') + w(' raise NotImplementedError') + w('') + return '\n'.join(lines) diff --git a/graalpython/hpy/hpy/tools/autogen/testing/__init__.py b/graalpython/hpy/hpy/tools/autogen/testing/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/graalpython/hpy/hpy/tools/autogen/testing/test_autogen.py b/graalpython/hpy/hpy/tools/autogen/testing/test_autogen.py new file mode 100644 index 0000000000..2e1a971d63 --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/testing/test_autogen.py @@ -0,0 +1,224 @@ +import textwrap +import difflib +import py +import pytest +from hpy.tools.autogen.parse import HPyAPI +from hpy.tools.autogen.ctx import autogen_ctx_h, autogen_ctx_def_h +from hpy.tools.autogen.trampolines import (autogen_trampolines_h, + cpython_autogen_api_impl_h) +from hpy.tools.autogen.hpyslot import autogen_hpyslot_h + +def src_equal(exp, got): + # try to compare two C sources, ignoring whitespace + exp = textwrap.dedent(exp).strip() + got = textwrap.dedent(got).strip() + if exp.split() != got.split(): + diff = difflib.unified_diff(exp.splitlines(), got.splitlines(), + fromfile='expected', + tofile='got') + print() + for line in diff: + print(line) + return False + return True + +@pytest.mark.usefixtures('initargs') +class BaseTestAutogen: + + @pytest.fixture + def initargs(self, tmpdir): + self.tmpdir = tmpdir + + def parse(self, src): + fname = self.tmpdir.join('test_api.h') + # automatically add useful typedefs + src = """ + #define STRINGIFY(X) #X + #define HPy_ID(X) _Pragma(STRINGIFY(id=X)) \\ + + typedef int HPy; + typedef int HPyContext; + """ + src + fname.write(src) + return HPyAPI.parse(fname) + + +class TestHPyAPI(BaseTestAutogen): + + def test_ctx_name(self): + api = self.parse(""" + HPy_ID(0) HPy h_None; + HPy_ID(1) HPy HPy_Dup(HPyContext *ctx, HPy h); + HPy_ID(2) void* _HPy_AsStruct(HPyContext *ctx, HPy h); + """) + assert api.get_var('h_None').ctx_name() == 'h_None' + assert api.get_func('HPy_Dup').ctx_name() == 'ctx_Dup' + assert api.get_func('_HPy_AsStruct').ctx_name() == 'ctx_AsStruct' + + def test_cpython_name(self): + api = self.parse(""" + HPy_ID(0) HPy HPy_Dup(HPyContext *ctx, HPy h); + HPy_ID(1) long HPyLong_AsLong(HPyContext *ctx, HPy h); + HPy_ID(2) HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2); + """) + assert api.get_func('HPy_Dup').cpython_name is None + assert api.get_func('HPyLong_AsLong').cpython_name == 'PyLong_AsLong' + assert api.get_func('HPy_Add').cpython_name == 'PyNumber_Add' + + def test_hpyslot(self): + api = self.parse(""" + typedef enum { + HPy_nb_add = SLOT(7, HPyFunc_BINARYFUNC), + HPy_tp_repr = SLOT(66, HPyFunc_REPRFUNC), + } HPySlot_Slot; + """) + nb_add = api.get_slot('HPy_nb_add') + assert nb_add.value == '7' + assert nb_add.hpyfunc == 'HPyFunc_BINARYFUNC' + # + tp_repr = api.get_slot('HPy_tp_repr') + assert tp_repr.value == '66' + assert tp_repr.hpyfunc == 'HPyFunc_REPRFUNC' + + def test_parse_id(self): + api = self.parse(""" + HPy_ID(0) HPy h_Foo; + HPy_ID(1) + long HPyFoo_Bar(HPyContext *ctx, HPy h); + """) + assert len(api.variables) == 1 + assert len(api.functions) == 1 + assert api.variables[0].ctx_index == 0 + assert api.functions[0].ctx_index == 1 + + # don't allow gaps in the sequence of IDs + with pytest.raises(AssertionError): + self.parse(""" + HPy_ID(0) HPy h_Foo; + HPy_ID(3) long HPyFoo_Bar(HPyContext *ctx, HPy h); + """) + + # don't allow re-using of IDs + with pytest.raises(AssertionError): + self.parse(""" + HPy_ID(0) HPy h_Foo; + HPy_ID(0) HPy h_Foo; + """) + + # all context members must have an ID + with pytest.raises(ValueError): + self.parse("HPy h_Foo;") + + # pragmas must be of form '#pramga key=value' + with pytest.raises(ValueError): + self.parse("#pragma hello\nHPy h_Foo;") + + # pragmas value must be an integer + with pytest.raises(ValueError): + self.parse("#pragma hello=world\nHPy h_Foo;") + +class TestAutoGen(BaseTestAutogen): + + def test_autogen_ctx_h(self): + api = self.parse(""" + HPy_ID(0) HPy h_None; + HPy_ID(1) HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2); + """) + got = autogen_ctx_h(api).generate() + exp = """ + struct _HPyContext_s { + const char *name; // used just to make debugging and testing easier + void *_private; // used by implementations to store custom data + int abi_version; + HPy h_None; + HPy (*ctx_Add)(HPyContext *ctx, HPy h1, HPy h2); + }; + """ + assert src_equal(exp, got) + + def test_autogen_ctx_def_h(self): + api = self.parse(""" + HPy_ID(0) HPy h_None; + HPy_ID(1) HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2); + """) + got = autogen_ctx_def_h(api).generate() + exp = """ + struct _HPyContext_s g_universal_ctx = { + .name = "HPy Universal ABI (CPython backend)", + ._private = NULL, + .abi_version = HPY_ABI_VERSION, + /* h_None & co. are initialized by init_universal_ctx() */ + .ctx_Add = &ctx_Add, + }; + """ + assert src_equal(exp, got) + + def test_autogen_trampolines_h(self): + api = self.parse(""" + HPy_ID(0) HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2); + HPy_ID(1) void HPy_Close(HPyContext *ctx, HPy h); + HPy_ID(2) void* _HPy_AsStruct(HPyContext *ctx, HPy h); + """) + got = autogen_trampolines_h(api).generate() + exp = """ + HPyAPI_FUNC HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2) { + return ctx->ctx_Add ( ctx, h1, h2 ); + } + + HPyAPI_FUNC void HPy_Close(HPyContext *ctx, HPy h) { + ctx->ctx_Close ( ctx, h ); + } + + HPyAPI_FUNC void *_HPy_AsStruct(HPyContext *ctx, HPy h) { + return ctx->ctx_AsStruct ( ctx, h ); + } + """ + assert src_equal(got, exp) + + def test_cpython_api_impl_h(self): + api = self.parse(""" + HPy_ID(0) HPy HPy_Dup(HPyContext *ctx, HPy h); + HPy_ID(1) HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2); + HPy_ID(2) HPy HPyLong_FromLong(HPyContext *ctx, long value); + HPy_ID(3) char* HPyBytes_AsString(HPyContext *ctx, HPy h); + """) + got = cpython_autogen_api_impl_h(api).generate() + exp = """ + HPyAPI_FUNC + HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2) + { + return _py2h(PyNumber_Add(_h2py(h1), _h2py(h2))); + } + + HPyAPI_FUNC + HPy HPyLong_FromLong(HPyContext *ctx, long value) + { + return _py2h(PyLong_FromLong(value)); + } + + HPyAPI_FUNC + char *HPyBytes_AsString(HPyContext *ctx, HPy h) + { + return PyBytes_AsString(_h2py(h)); + } + """ + assert src_equal(got, exp) + + def test_autogen_hpyslot_h(self): + api = self.parse(""" + typedef enum { + HPy_nb_add = SLOT(7, HPyFunc_BINARYFUNC), + HPy_tp_repr = SLOT(66, HPyFunc_REPRFUNC), + } HPySlot_Slot; + """) + got = autogen_hpyslot_h(api).generate() + exp = """ + typedef enum { + HPy_nb_add = 7, + HPy_tp_repr = 66, + } HPySlot_Slot; + + #define _HPySlot_SIG__HPy_nb_add HPyFunc_BINARYFUNC + #define _HPySlot_SIG__HPy_tp_repr HPyFunc_REPRFUNC + """ + assert src_equal(got, exp) diff --git a/graalpython/hpy/hpy/tools/autogen/testing/test_hpyfunc.py b/graalpython/hpy/hpy/tools/autogen/testing/test_hpyfunc.py new file mode 100644 index 0000000000..7e0032979d --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/testing/test_hpyfunc.py @@ -0,0 +1,145 @@ +from hpy.tools.autogen.hpyfunc import autogen_hpyfunc_declare_h +from hpy.tools.autogen.hpyfunc import autogen_hpyfunc_trampoline_h +from hpy.tools.autogen.hpyfunc import autogen_ctx_call_i +from hpy.tools.autogen.hpyfunc import autogen_cpython_hpyfunc_trampoline_h +from hpy.tools.autogen.testing.test_autogen import BaseTestAutogen, src_equal + +class TestHPyFunc(BaseTestAutogen): + + def test_parse(self): + api = self.parse(""" + typedef int HPyFunc_Signature; + typedef HPy (*HPyFunc_noargs)(HPyContext *ctx, HPy self); + """) + assert len(api.hpyfunc_typedefs) == 1 + hpyfunc = api.get_hpyfunc_typedef('HPyFunc_noargs') + assert hpyfunc.name == 'HPyFunc_noargs' + assert hpyfunc.base_name() == 'noargs' + + def test_autogen_hpyfunc_declare_h(self): + api = self.parse(""" + typedef HPy (*HPyFunc_foo)(HPyContext *ctx, HPy self); + typedef HPy (*HPyFunc_bar)(HPyContext *ctx, HPy, int); + """) + got = autogen_hpyfunc_declare_h(api).generate() + exp = """ + #define _HPyFunc_DECLARE_HPyFunc_FOO(SYM) static HPy SYM(HPyContext *ctx, HPy self) + #define _HPyFunc_DECLARE_HPyFunc_BAR(SYM) static HPy SYM(HPyContext *ctx, HPy, int) + + typedef HPy (*HPyFunc_foo)(HPyContext *ctx, HPy self); + typedef HPy (*HPyFunc_bar)(HPyContext *ctx, HPy, int); + """ + assert src_equal(got, exp) + + def test_autogen_hpyfunc_trampoline_h(self): + api = self.parse(""" + typedef HPy (*HPyFunc_foo)(HPyContext *ctx, HPy arg, int xy); + typedef HPy (*HPyFunc_bar)(HPyContext *ctx, HPy, int); + typedef void (*HPyFunc_proc)(HPyContext *ctx, int x); + """) + got = autogen_hpyfunc_trampoline_h(api).generate() + exp = r""" + typedef struct { + cpy_PyObject *arg; + int xy; + cpy_PyObject * result; + } _HPyFunc_args_FOO; + + #define _HPyFunc_TRAMPOLINE_HPyFunc_FOO(SYM, IMPL) \ + static cpy_PyObject *SYM(cpy_PyObject *arg, int xy) \ + { \ + _HPyFunc_args_FOO a = { arg, xy }; \ + _HPy_CallRealFunctionFromTrampoline( \ + _ctx_for_trampolines, HPyFunc_FOO, (HPyCFunction)IMPL, &a); \ + return a.result; \ + } + + typedef struct { + cpy_PyObject *arg0; + int arg1; + cpy_PyObject * result; + } _HPyFunc_args_BAR; + + #define _HPyFunc_TRAMPOLINE_HPyFunc_BAR(SYM, IMPL) \ + static cpy_PyObject *SYM(cpy_PyObject *arg0, int arg1) \ + { \ + _HPyFunc_args_BAR a = { arg0, arg1 }; \ + _HPy_CallRealFunctionFromTrampoline( \ + _ctx_for_trampolines, HPyFunc_BAR, (HPyCFunction)IMPL, &a); \ + return a.result; \ + } + + typedef struct { + int x; + } _HPyFunc_args_PROC; + + #define _HPyFunc_TRAMPOLINE_HPyFunc_PROC(SYM, IMPL) \ + static void SYM(int x) \ + { \ + _HPyFunc_args_PROC a = { x }; \ + _HPy_CallRealFunctionFromTrampoline( \ + _ctx_for_trampolines, HPyFunc_PROC, (HPyCFunction)IMPL, &a); \ + return; \ + } + """ + assert src_equal(got, exp) + + def test_autogen_ctx_call_i(self): + api = self.parse(""" + typedef HPy (*HPyFunc_foo)(HPyContext *ctx, HPy arg, int xy); + typedef int (*HPyFunc_bar)(HPyContext *ctx); + typedef int (*HPyFunc_baz)(HPyContext *ctx, HPy, int); + typedef void (*HPyFunc_proc)(HPyContext *ctx, int x); + """) + got = autogen_ctx_call_i(api).generate() + exp = r""" + case HPyFunc_FOO: { + HPyFunc_foo f = (HPyFunc_foo)func; + _HPyFunc_args_FOO *a = (_HPyFunc_args_FOO*)args; + a->result = _h2py(f(ctx, _py2h(a->arg), a->xy)); + return; + } + case HPyFunc_BAR: { + HPyFunc_bar f = (HPyFunc_bar)func; + _HPyFunc_args_BAR *a = (_HPyFunc_args_BAR*)args; + a->result = f(ctx); + return; + } + case HPyFunc_BAZ: { + HPyFunc_baz f = (HPyFunc_baz)func; + _HPyFunc_args_BAZ *a = (_HPyFunc_args_BAZ*)args; + a->result = f(ctx, _py2h(a->arg0), a->arg1); + return; + } + case HPyFunc_PROC: { + HPyFunc_proc f = (HPyFunc_proc)func; + _HPyFunc_args_PROC *a = (_HPyFunc_args_PROC*)args; + f(ctx, a->x); + return; + } + """ + assert src_equal(got, exp) + + def test_autogen_cpython_hpyfunc_trampoline_h(self): + api = self.parse(""" + typedef HPy (*HPyFunc_foo)(HPyContext *ctx, HPy arg, int xy); + typedef HPy (*HPyFunc_bar)(HPyContext *ctx, HPy, int); + """) + got = autogen_cpython_hpyfunc_trampoline_h(api).generate() + exp = r""" + typedef HPy (*_HPyCFunction_FOO)(HPyContext *, HPy, int); + #define _HPyFunc_TRAMPOLINE_HPyFunc_FOO(SYM, IMPL) \ + static cpy_PyObject *SYM(cpy_PyObject *arg, int xy) \ + { \ + _HPyCFunction_FOO func = (_HPyCFunction_FOO)IMPL; \ + return _h2py(func(_HPyGetContext(), _py2h(arg), xy)); \ + } + typedef HPy (*_HPyCFunction_BAR)(HPyContext *, HPy, int); + #define _HPyFunc_TRAMPOLINE_HPyFunc_BAR(SYM, IMPL) \ + static cpy_PyObject *SYM(cpy_PyObject *arg0, int arg1) \ + { \ + _HPyCFunction_BAR func = (_HPyCFunction_BAR)IMPL; \ + return _h2py(func(_HPyGetContext(), _py2h(arg0), arg1)); \ + } + """ + assert src_equal(got, exp) diff --git a/graalpython/hpy/hpy/tools/autogen/trace.py b/graalpython/hpy/hpy/tools/autogen/trace.py new file mode 100644 index 0000000000..5cdc212081 --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/trace.py @@ -0,0 +1,182 @@ +from copy import deepcopy +from pycparser import c_ast +from .autogenfile import AutoGenFile +from .parse import toC, find_typedecl, get_context_return_type, \ + maybe_make_void, make_void, get_return_constant + + +# We will call the delegate context's function but we still need to unwrap +# the context. This is in contrast to, e.g., the debug mode, where you would +# manually write a wrapper function. Here we can generate that as well. +NO_WRAPPER = { + '_HPy_CallRealFunctionFromTrampoline', + 'HPy_FatalError', +} + +class Ctx2TctxVisitor(c_ast.NodeVisitor): + """Visitor which renames all ctx to tctx""" + + def visit_TypeDecl(self, node): + if node.declname == 'ctx': + node.declname = 'tctx' + self.generic_visit(node) + +def funcnode_with_new_name(node, name): + newnode = deepcopy(node) + typedecl = find_typedecl(newnode) + typedecl.declname = name + return newnode + +def get_trace_wrapper_node(func): + newnode = funcnode_with_new_name(func.node, 'trace_%s' % func.ctx_name()) + maybe_make_void(func, newnode) + # rename ctx to tctx + visitor = Ctx2TctxVisitor() + visitor.visit(newnode) + return newnode + +class autogen_tracer_ctx_init_h(AutoGenFile): + PATH = 'hpy/trace/src/autogen_trace_ctx_init.h' + + def generate(self): + lines = [] + w = lines.append + # emit the declarations for all the trace_ctx_* functions + for func in self.api.functions: + if func.name not in NO_WRAPPER: + w(toC(get_trace_wrapper_node(func)) + ';') + n_decls = len(self.api.functions) + len(self.api.variables) + w('') + w(f'static inline void trace_ctx_init_info(HPyTraceInfo *info, HPyContext *uctx)') + w('{') + w(f' info->magic_number = HPY_TRACE_MAGIC;') + w(f' info->uctx = uctx;') + w(f' info->call_counts = (uint64_t *)calloc({n_decls}, sizeof(uint64_t));') + w(f' info->durations = (_HPyTime_t *)calloc({n_decls}, sizeof(_HPyTime_t));') + w(f' info->on_enter_func = HPy_NULL;') + w(f' info->on_exit_func = HPy_NULL;') + w('}') + w('') + w(f'static inline void trace_ctx_free_info(HPyTraceInfo *info)') + w('{') + w(f' assert(info->magic_number == HPY_TRACE_MAGIC);') + w(f' free(info->call_counts);') + w(f' free(info->durations);') + w(f' HPy_Close(info->uctx, info->on_enter_func);') + w(f' HPy_Close(info->uctx, info->on_exit_func);') + w('}') + w('') + w(f'static inline void trace_ctx_init_fields(HPyContext *tctx, HPyContext *uctx)') + w('{') + for var in self.api.variables: + name = var.name + w(f' tctx->{name} = uctx->{name};') + for func in self.api.functions: + if func.name in NO_WRAPPER: + name = func.ctx_name() + w(f' tctx->{name} = uctx->{name};') + else: + name = func.ctx_name() + w(f' tctx->{name} = &trace_{name};') + w('}') + return '\n'.join(lines) + + +class autogen_tracer_wrappers(AutoGenFile): + PATH = 'hpy/trace/src/autogen_trace_wrappers.c' + + def generate(self): + lines = [] + w = lines.append + w('#include "trace_internal.h"') + w('') + for func in self.api.functions: + debug_wrapper = self.gen_trace_wrapper(func) + if debug_wrapper: + w(debug_wrapper) + w('') + return '\n'.join(lines) + + def gen_trace_wrapper(self, func): + if func.name in NO_WRAPPER: + return + + assert not func.is_varargs() + node = get_trace_wrapper_node(func) + const_return = get_return_constant(func) + if const_return: + make_void(node) + signature = toC(node) + rettype = get_context_return_type(node, const_return) + + def get_params(): + lst = [] + for p in node.type.args.params: + if p.name == 'ctx': + lst.append('uctx') + else: + lst.append(p.name) + return ', '.join(lst) + params = get_params() + + lines = [] + w = lines.append + w(signature) + w('{') + w(f' HPyTraceInfo *info = hpy_trace_on_enter(tctx, {func.ctx_index});') + w(f' HPyContext *uctx = info->uctx;') + w(f' _HPyTime_t _ts_start, _ts_end;') + w(f' _HPyClockStatus_t r0, r1;') + w(f' r0 = get_monotonic_clock(&_ts_start);') + if rettype == 'void': + w(f' {func.name}({params});') + else: + w(f' {rettype} res = {func.name}({params});') + w(f' r1 = get_monotonic_clock(&_ts_end);') + w(f' hpy_trace_on_exit(info, {func.ctx_index}, r0, r1, &_ts_start, &_ts_end);') + if rettype != 'void': + w(f' return res;') + w('}') + return '\n'.join(lines) + + +class autogen_trace_func_table_c(AutoGenFile): + PATH = 'hpy/trace/src/autogen_trace_func_table.c' + + def generate(self): + lines = [] + w = lines.append + + n_funcs = len(self.api.functions) + n_decls = n_funcs + len(self.api.variables) + func_table = ['NO_FUNC'] * n_decls + for func in self.api.functions: + name = func.ctx_name() + func_table[func.ctx_index] = f'"{name}"' + + w('#include "trace_internal.h"') + w('') + w(f'#define TRACE_NFUNC {n_funcs}') + w('') + w('#define NO_FUNC ""') + w('static const char *trace_func_table[] = {') + for func in func_table: + w(f' {func},') + w(f' NULL /* sentinel */') + w('};') + w('') + w('int hpy_trace_get_nfunc(void)') + w('{') + w(' return TRACE_NFUNC;') + w('}') + w('') + w('const char * hpy_trace_get_func_name(int idx)') + w('{') + w(f' if (idx >= 0 && idx < {n_decls})') + w(' return trace_func_table[idx];') + w(' return NULL;') + w('}') + w('') + return '\n'.join(lines) + + diff --git a/graalpython/hpy/hpy/tools/autogen/trampolines.py b/graalpython/hpy/hpy/tools/autogen/trampolines.py new file mode 100644 index 0000000000..366f27cd4a --- /dev/null +++ b/graalpython/hpy/hpy/tools/autogen/trampolines.py @@ -0,0 +1,140 @@ +from copy import deepcopy +from .autogenfile import AutoGenFile +from .parse import toC,find_typedecl, get_context_return_type, \ + make_void, get_return_constant +from . import conf + + +class autogen_trampolines_h(AutoGenFile): + PATH = 'hpy/devel/include/hpy/universal/autogen_trampolines.h' + + def generate(self): + lines = [] + for func in self.api.functions: + trampoline = self.gen_trampoline(func) + if trampoline: + lines.append(trampoline) + lines.append('') + return '\n'.join(lines) + + def gen_trampoline(self, func): + # HPyAPI_FUNC HPy HPyModule_Create(HPyContext *ctx, HPyModuleDef *def) { + # return ctx->ctx_Module_Create ( ctx, def ); + # } + if func.name in conf.NO_TRAMPOLINES: + return None + const_return = get_return_constant(func) + rettype = get_context_return_type(func.node, const_return) + parts = [] + w = parts.append + w('HPyAPI_FUNC') + w(toC(func.node)) + w('{\n ') + + # trampolines cannot deal with varargs easily + assert not func.is_varargs() + + if rettype == 'void': + w('ctx->%s' % func.ctx_name()) + else: + w('return ctx->%s' % func.ctx_name()) + w('(') + params = [p.name for p in func.node.type.args.params] + w(', '.join(params)) + w(');') + + if const_return: + w('return %s;' % const_return) + + w('\n}') + return ' '.join(parts) + + +class cpython_autogen_api_impl_h(AutoGenFile): + PATH = 'hpy/devel/include/hpy/cpython/autogen_api_impl.h' + GENERATE_CONST_RETURN = True + + def signature(self, func, const_return): + """ + Return the C signature of the impl function. + + In CPython mode, the name it's the same as in public_api: + HPy_Add ==> HPyAPI_FUNC HPy_Add + HPyLong_FromLong ==> HPyAPI_FUNC HPyLong_FromLong + + See also universal_autogen_ctx_impl_h. + """ + sig = toC(func.node) + return 'HPyAPI_FUNC %s' % sig + + def generate(self): + lines = [] + for func in self.api.functions: + if not func.cpython_name: + continue + lines.append(self.gen_implementation(func)) + lines.append('') + return '\n'.join(lines) + + def gen_implementation(self, func): + def call(pyfunc, return_type): + # return _py2h(PyNumber_Add(_h2py(x), _h2py(y))) + args = [] + for p in func.node.type.args.params: + if toC(p.type) == 'HPyContext *': + continue + elif toC(p.type) == 'HPy': + arg = '_h2py(%s)' % p.name + elif toC(p.type) == 'HPyThreadState': + arg = '_h2threads(%s)' % p.name + else: + arg = p.name + args.append(arg) + result = '%s(%s)' % (pyfunc, ', '.join(args)) + if return_type == 'HPy': + result = '_py2h(%s)' % result + elif return_type == 'HPyThreadState': + result = '_threads2h(%s)' % result + return result + # + lines = [] + w = lines.append + pyfunc = func.cpython_name + if not pyfunc: + raise ValueError(f"Cannot generate implementation for {self}") + const_return = get_return_constant(func) + return_type = get_context_return_type(func.node, const_return) + return_stmt = '' if return_type == 'void' else 'return ' + w(self.signature(func, const_return)) + w('{') + w(' %s%s;' % (return_stmt, call(pyfunc, return_type))) + + if self.GENERATE_CONST_RETURN and const_return: + w(' return %s;' % const_return) + + w('}') + return '\n'.join(lines) + + +class universal_autogen_ctx_impl_h(cpython_autogen_api_impl_h): + PATH = 'hpy/universal/src/autogen_ctx_impl.h' + GENERATE_CONST_RETURN = False + + def signature(self, func, const_return): + """ + Return the C signature of the impl function. + + In Universal mode, the name is prefixed by ctx_: + HPy_Add ==> HPyAPI_IMPL ctx_Add + HPyLong_FromLong ==> HPyAPI_IMPL ctx_Long_FromLong + + See also cpython_autogen_api_impl_h. + """ + newnode = deepcopy(func.node) + if const_return: + make_void(newnode) + typedecl = find_typedecl(newnode) + # rename the function + typedecl.declname = func.ctx_name() + sig = toC(newnode) + return 'HPyAPI_IMPL %s' % sig diff --git a/graalpython/hpy/hpy/tools/include_path.py b/graalpython/hpy/hpy/tools/include_path.py new file mode 100644 index 0000000000..61dd06a28d --- /dev/null +++ b/graalpython/hpy/hpy/tools/include_path.py @@ -0,0 +1,4 @@ +"""Prints the include path for the current Python interpreter.""" + +from sysconfig import get_paths as gp +print(gp()['include']) diff --git a/graalpython/hpy/hpy/tools/valgrind/hpy.supp b/graalpython/hpy/hpy/tools/valgrind/hpy.supp new file mode 100644 index 0000000000..c1139552a8 --- /dev/null +++ b/graalpython/hpy/hpy/tools/valgrind/hpy.supp @@ -0,0 +1,44 @@ +{ + <_HPyModuleDef_CreatePyModuleDef_leak> + Memcheck:Leak + match-leak-kinds: definite,indirect + ... + fun:_HPyModuleDef_CreatePyModuleDef + ... +} + +{ + + Memcheck:Leak + match-leak-kinds: definite + ... + fun:ctx_Type_FromSpec + ... +} + +{ + + Memcheck:Leak + match-leak-kinds: definite + ... + fun:PyUnicode_New.part.42 + ... +} + +{ + + Memcheck:Leak + match-leak-kinds: definite + ... + fun:PyUnicode_New + ... +} + +{ + + Memcheck:Leak + match-leak-kinds: definite + ... + fun:PyLong_FromLong + ... +} diff --git a/graalpython/hpy/hpy/tools/valgrind/python.supp b/graalpython/hpy/hpy/tools/valgrind/python.supp new file mode 100644 index 0000000000..26a6f22c89 --- /dev/null +++ b/graalpython/hpy/hpy/tools/valgrind/python.supp @@ -0,0 +1,389 @@ +# +# This is a valgrind suppression file that should be used when using valgrind. +# +# Here's an example of running valgrind: +# +# cd python/dist/src +# valgrind --tool=memcheck --suppressions=Misc/valgrind-python.supp \ +# ./python -E -tt ./Lib/test/regrtest.py -u bsddb,network +# +# You must edit Objects/obmalloc.c and uncomment Py_USING_MEMORY_DEBUGGER +# to use the preferred suppressions with Py_ADDRESS_IN_RANGE. +# +# If you do not want to recompile Python, you can uncomment +# suppressions for PyObject_Free and PyObject_Realloc. +# +# See Misc/README.valgrind for more information. + +# all tool names: Addrcheck,Memcheck,cachegrind,helgrind,massif +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Addr4 + fun:Py_ADDRESS_IN_RANGE +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Value4 + fun:Py_ADDRESS_IN_RANGE +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64 aka amd64) + Memcheck:Value8 + fun:Py_ADDRESS_IN_RANGE +} + +{ + ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value + Memcheck:Cond + fun:Py_ADDRESS_IN_RANGE +} + +# +# Leaks (including possible leaks) +# Hmmm, I wonder if this masks some real leaks. I think it does. +# Will need to fix that. +# + +{ + Suppress leaking the GIL. Happens once per process, see comment in ceval.c. + Memcheck:Leak + fun:malloc + fun:PyThread_allocate_lock + fun:PyEval_InitThreads +} + +{ + Suppress leaking the GIL after a fork. + Memcheck:Leak + fun:malloc + fun:PyThread_allocate_lock + fun:PyEval_ReInitThreads +} + +{ + Suppress leaking the autoTLSkey. This looks like it shouldn't leak though. + Memcheck:Leak + fun:malloc + fun:PyThread_create_key + fun:_PyGILState_Init + fun:Py_InitializeEx + fun:Py_Main +} + +{ + Hmmm, is this a real leak or like the GIL? + Memcheck:Leak + fun:malloc + fun:PyThread_ReInitTLS +} + +{ + Handle PyMalloc confusing valgrind (possibly leaked) + Memcheck:Leak + fun:realloc + fun:_PyObject_GC_Resize + fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING +} + +{ + Handle PyMalloc confusing valgrind (possibly leaked) + Memcheck:Leak + fun:malloc + fun:_PyObject_GC_New + fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING +} + +{ + Handle PyMalloc confusing valgrind (possibly leaked) + Memcheck:Leak + fun:malloc + fun:_PyObject_GC_NewVar + fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING +} + +# +# Non-python specific leaks +# + +{ + Handle pthread issue (possibly leaked) + Memcheck:Leak + fun:calloc + fun:allocate_dtv + fun:_dl_allocate_tls_storage + fun:_dl_allocate_tls +} + +{ + Handle pthread issue (possibly leaked) + Memcheck:Leak + fun:memalign + fun:_dl_allocate_tls_storage + fun:_dl_allocate_tls +} + +###{ +### ADDRESS_IN_RANGE/Invalid read of size 4 +### Memcheck:Addr4 +### fun:PyObject_Free +###} +### +###{ +### ADDRESS_IN_RANGE/Invalid read of size 4 +### Memcheck:Value4 +### fun:PyObject_Free +###} +### +###{ +### ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value +### Memcheck:Cond +### fun:PyObject_Free +###} + +###{ +### ADDRESS_IN_RANGE/Invalid read of size 4 +### Memcheck:Addr4 +### fun:PyObject_Realloc +###} +### +###{ +### ADDRESS_IN_RANGE/Invalid read of size 4 +### Memcheck:Value4 +### fun:PyObject_Realloc +###} +### +###{ +### ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value +### Memcheck:Cond +### fun:PyObject_Realloc +###} + +### +### All the suppressions below are for errors that occur within libraries +### that Python uses. The problems to not appear to be related to Python's +### use of the libraries. +### + +{ + Generic ubuntu ld problems + Memcheck:Addr8 + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so + obj:/lib/ld-2.4.so +} + +{ + Generic gentoo ld problems + Memcheck:Cond + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so +} + +{ + DBM problems, see test_dbm + Memcheck:Param + write(buf) + fun:write + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + fun:dbm_close +} + +{ + DBM problems, see test_dbm + Memcheck:Value8 + fun:memmove + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + fun:dbm_store + fun:dbm_ass_sub +} + +{ + DBM problems, see test_dbm + Memcheck:Cond + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + fun:dbm_store + fun:dbm_ass_sub +} + +{ + DBM problems, see test_dbm + Memcheck:Cond + fun:memmove + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + obj:/usr/lib/libdb1.so.2 + fun:dbm_store + fun:dbm_ass_sub +} + +{ + GDBM problems, see test_gdbm + Memcheck:Param + write(buf) + fun:write + fun:gdbm_open + +} + +{ + ZLIB problems, see test_gzip + Memcheck:Cond + obj:/lib/libz.so.1.2.3 + obj:/lib/libz.so.1.2.3 + fun:deflate +} + +{ + Avoid problems w/readline doing a putenv and leaking on exit + Memcheck:Leak + fun:malloc + fun:xmalloc + fun:sh_set_lines_and_columns + fun:_rl_get_screen_size + fun:_rl_init_terminal_io + obj:/lib/libreadline.so.4.3 + fun:rl_initialize +} + +### +### These occur from somewhere within the SSL, when running +### test_socket_sll. They are too general to leave on by default. +### +###{ +### somewhere in SSL stuff +### Memcheck:Cond +### fun:memset +###} +###{ +### somewhere in SSL stuff +### Memcheck:Value4 +### fun:memset +###} +### +###{ +### somewhere in SSL stuff +### Memcheck:Cond +### fun:MD5_Update +###} +### +###{ +### somewhere in SSL stuff +### Memcheck:Value4 +### fun:MD5_Update +###} + +# +# All of these problems come from using test_socket_ssl +# +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_bin2bn +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_num_bits_word +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:BN_num_bits_word +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_mod_exp_mont_word +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_mod_exp_mont +} + +{ + from test_socket_ssl + Memcheck:Param + write(buf) + fun:write + obj:/usr/lib/libcrypto.so.0.9.7 +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:RSA_verify +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:RSA_verify +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:DES_set_key_unchecked +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:DES_encrypt2 +} + +{ + from test_socket_ssl + Memcheck:Cond + obj:/usr/lib/libssl.so.0.9.7 +} + +{ + from test_socket_ssl + Memcheck:Value4 + obj:/usr/lib/libssl.so.0.9.7 +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BUF_MEM_grow_clean +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:memcpy + fun:ssl3_read_bytes +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:SHA1_Update +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:SHA1_Update +} diff --git a/graalpython/hpy/hpy/trace/__init__.py b/graalpython/hpy/hpy/trace/__init__.py new file mode 100644 index 0000000000..83d5308790 --- /dev/null +++ b/graalpython/hpy/hpy/trace/__init__.py @@ -0,0 +1,6 @@ +import hpy.universal + +get_call_counts = hpy.universal._trace.get_call_counts +get_durations = hpy.universal._trace.get_durations +set_trace_functions = hpy.universal._trace.set_trace_functions +get_frequency = hpy.universal._trace.get_frequency diff --git a/graalpython/com.oracle.graal.python.jni/src/trace/_tracemod.c b/graalpython/hpy/hpy/trace/src/_tracemod.c similarity index 70% rename from graalpython/com.oracle.graal.python.jni/src/trace/_tracemod.c rename to graalpython/hpy/hpy/trace/src/_tracemod.c index e52bb5a464..954a437944 100644 --- a/graalpython/com.oracle.graal.python.jni/src/trace/_tracemod.c +++ b/graalpython/hpy/hpy/trace/src/_tracemod.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - // Python-level interface for the _trace module. Written in HPy itself, the // idea is that it should be reusable by other implementations @@ -170,49 +146,6 @@ static int check_and_set_func(HPyContext *uctx, HPy arg, HPy *out) return 0; } -static const char *set_trace_funcs_kwlist[] = { "on_enter", "on_exit", NULL }; - -static int -get_optional_arg(HPyContext *ctx, const HPy *args, size_t nargs, HPy kwnames, - HPy_ssize_t i, const char *kwname, HPy *out) -{ - HPy_ssize_t nkw, j; - HPy h_kwname, h_item; - // if given as positional arg - if (i < (HPy_ssize_t) nargs) { - *out = args[i]; - return 0; - } - - if (HPy_IsNull(kwnames)) { - return 0; - } - - nkw = HPy_Length(ctx, kwnames); - if (nkw < 0) { - return -1; - } - h_kwname = HPyUnicode_FromString(ctx, kwname); - if (HPy_IsNull(h_kwname)) { - return -1; - } - for (j=0; j < nkw; j++) { - h_item = HPy_GetItem_i(ctx, kwnames, j); - if (HPy_IsNull(h_item)) { - HPy_Close(ctx, h_kwname); - return -1; - } - if (HPy_RichCompareBool(ctx, h_kwname, h_item, HPy_EQ)) { - HPy_Close(ctx, h_kwname); - HPy_Close(ctx, h_item); - *out = args[nargs + j]; - return 0; - } - HPy_Close(ctx, h_item); - } - return 0; -} - HPyDef_METH(set_trace_functions, "set_trace_functions", HPyFunc_KEYWORDS, .doc="Set the functions to call if an HPy API is entered/exited.") static HPy set_trace_functions_impl(HPyContext *uctx, HPy self, const HPy *args, @@ -222,18 +155,17 @@ static HPy set_trace_functions_impl(HPyContext *uctx, HPy self, const HPy *args, HPy h_on_exit = HPy_NULL; HPyContext *dctx = hpy_trace_get_ctx(uctx); HPyTraceInfo *info = get_info(dctx); + HPyTracker ht; - // GraalPy change: avoid usage of HPyArg_ParseKeywords - if (get_optional_arg(uctx, args, nargs, kwnames, 0, - set_trace_funcs_kwlist[0], &h_on_enter) < 0 - || get_optional_arg(uctx, args, nargs, kwnames, 1, - set_trace_funcs_kwlist[1], &h_on_exit) < 0) - { + static const char *kwlist[] = { "on_enter", "on_exit", NULL }; + if (!HPyArg_ParseKeywords(uctx, &ht, args, nargs, kwnames, "|OO", kwlist, + &h_on_enter, &h_on_exit)) { return HPy_NULL; } int r = check_and_set_func(uctx, h_on_enter, &info->on_enter_func) < 0 || check_and_set_func(uctx, h_on_exit, &info->on_exit_func) < 0; + HPyTracker_Close(uctx, ht); if (r) { return HPy_NULL; } diff --git a/graalpython/com.oracle.graal.python.jni/src/trace/autogen_trace_ctx_init.h b/graalpython/hpy/hpy/trace/src/autogen_trace_ctx_init.h similarity index 95% rename from graalpython/com.oracle.graal.python.jni/src/trace/autogen_trace_ctx_init.h rename to graalpython/hpy/hpy/trace/src/autogen_trace_ctx_init.h index cbcfd1a31e..fef5028491 100644 --- a/graalpython/com.oracle.graal.python.jni/src/trace/autogen_trace_ctx_init.h +++ b/graalpython/hpy/hpy/trace/src/autogen_trace_ctx_init.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /* DO NOT EDIT THIS FILE! @@ -95,6 +71,9 @@ int trace_ctx_Callable_Check(HPyContext *tctx, HPy h); HPy trace_ctx_CallTupleDict(HPyContext *tctx, HPy callable, HPy args, HPy kw); HPy trace_ctx_Call(HPyContext *tctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames); HPy trace_ctx_CallMethod(HPyContext *tctx, HPy name, const HPy *args, size_t nargs, HPy kwnames); +HPy trace_ctx_GetIter(HPyContext *tctx, HPy obj); +HPy trace_ctx_Iter_Next(HPyContext *tctx, HPy obj); +int trace_ctx_Iter_Check(HPyContext *tctx, HPy obj); void trace_ctx_Err_SetString(HPyContext *tctx, HPy h_type, const char *utf8_message); void trace_ctx_Err_SetObject(HPyContext *tctx, HPy h_type, HPy h_value); HPy trace_ctx_Err_SetFromErrnoWithFilename(HPyContext *tctx, HPy h_type, const char *filename_fsencoded); @@ -119,13 +98,16 @@ int trace_ctx_SetAttr_s(HPyContext *tctx, HPy obj, const char *utf8_name, HPy va HPy trace_ctx_GetItem(HPyContext *tctx, HPy obj, HPy key); HPy trace_ctx_GetItem_i(HPyContext *tctx, HPy obj, HPy_ssize_t idx); HPy trace_ctx_GetItem_s(HPyContext *tctx, HPy obj, const char *utf8_key); +HPy trace_ctx_GetSlice(HPyContext *tctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end); int trace_ctx_Contains(HPyContext *tctx, HPy container, HPy key); int trace_ctx_SetItem(HPyContext *tctx, HPy obj, HPy key, HPy value); int trace_ctx_SetItem_i(HPyContext *tctx, HPy obj, HPy_ssize_t idx, HPy value); int trace_ctx_SetItem_s(HPyContext *tctx, HPy obj, const char *utf8_key, HPy value); +int trace_ctx_SetSlice(HPyContext *tctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end, HPy value); int trace_ctx_DelItem(HPyContext *tctx, HPy obj, HPy key); int trace_ctx_DelItem_i(HPyContext *tctx, HPy obj, HPy_ssize_t idx); int trace_ctx_DelItem_s(HPyContext *tctx, HPy obj, const char *utf8_key); +int trace_ctx_DelSlice(HPyContext *tctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end); HPy trace_ctx_Type(HPyContext *tctx, HPy obj); int trace_ctx_TypeCheck(HPyContext *tctx, HPy obj, HPy type); const char *trace_ctx_Type_GetName(HPyContext *tctx, HPy type); @@ -139,6 +121,7 @@ void *trace_ctx_AsStruct_Float(HPyContext *tctx, HPy h); void *trace_ctx_AsStruct_Unicode(HPyContext *tctx, HPy h); void *trace_ctx_AsStruct_Tuple(HPyContext *tctx, HPy h); void *trace_ctx_AsStruct_List(HPyContext *tctx, HPy h); +void *trace_ctx_AsStruct_Dict(HPyContext *tctx, HPy h); HPyType_BuiltinShape trace_ctx_Type_GetBuiltinShape(HPyContext *tctx, HPy h_type); HPy trace_ctx_New(HPyContext *tctx, HPy h_type, void **data); HPy trace_ctx_Repr(HPyContext *tctx, HPy obj); @@ -173,12 +156,14 @@ HPy trace_ctx_Unicode_Substring(HPyContext *tctx, HPy str, HPy_ssize_t start, HP int trace_ctx_List_Check(HPyContext *tctx, HPy h); HPy trace_ctx_List_New(HPyContext *tctx, HPy_ssize_t len); int trace_ctx_List_Append(HPyContext *tctx, HPy h_list, HPy h_item); +int trace_ctx_List_Insert(HPyContext *tctx, HPy h_list, HPy_ssize_t index, HPy h_item); int trace_ctx_Dict_Check(HPyContext *tctx, HPy h); HPy trace_ctx_Dict_New(HPyContext *tctx); HPy trace_ctx_Dict_Keys(HPyContext *tctx, HPy h); HPy trace_ctx_Dict_Copy(HPyContext *tctx, HPy h); int trace_ctx_Tuple_Check(HPyContext *tctx, HPy h); -HPy trace_ctx_Tuple_FromArray(HPyContext *tctx, HPy items[], HPy_ssize_t n); +HPy trace_ctx_Tuple_FromArray(HPyContext *tctx, const HPy items[], HPy_ssize_t n); +HPy trace_ctx_Slice_New(HPyContext *tctx, HPy start, HPy stop, HPy step); int trace_ctx_Slice_Unpack(HPyContext *tctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step); HPy trace_ctx_Import_ImportModule(HPyContext *tctx, const char *utf8_name); HPy trace_ctx_Capsule_New(HPyContext *tctx, void *pointer, const char *utf8_name, HPyCapsule_Destructor *destructor); @@ -217,8 +202,8 @@ static inline void trace_ctx_init_info(HPyTraceInfo *info, HPyContext *uctx) { info->magic_number = HPY_TRACE_MAGIC; info->uctx = uctx; - info->call_counts = (uint64_t *)calloc(263, sizeof(uint64_t)); - info->durations = (_HPyTime_t *)calloc(263, sizeof(_HPyTime_t)); + info->call_counts = (uint64_t *)calloc(273, sizeof(uint64_t)); + info->durations = (_HPyTime_t *)calloc(273, sizeof(_HPyTime_t)); info->on_enter_func = HPy_NULL; info->on_exit_func = HPy_NULL; } @@ -316,6 +301,7 @@ static inline void trace_ctx_init_fields(HPyContext *tctx, HPyContext *uctx) tctx->h_MemoryViewType = uctx->h_MemoryViewType; tctx->h_CapsuleType = uctx->h_CapsuleType; tctx->h_SliceType = uctx->h_SliceType; + tctx->h_DictType = uctx->h_DictType; tctx->h_Builtins = uctx->h_Builtins; tctx->ctx_Dup = &trace_ctx_Dup; tctx->ctx_Close = &trace_ctx_Close; @@ -378,6 +364,9 @@ static inline void trace_ctx_init_fields(HPyContext *tctx, HPyContext *uctx) tctx->ctx_CallTupleDict = &trace_ctx_CallTupleDict; tctx->ctx_Call = &trace_ctx_Call; tctx->ctx_CallMethod = &trace_ctx_CallMethod; + tctx->ctx_GetIter = &trace_ctx_GetIter; + tctx->ctx_Iter_Next = &trace_ctx_Iter_Next; + tctx->ctx_Iter_Check = &trace_ctx_Iter_Check; tctx->ctx_FatalError = uctx->ctx_FatalError; tctx->ctx_Err_SetString = &trace_ctx_Err_SetString; tctx->ctx_Err_SetObject = &trace_ctx_Err_SetObject; @@ -403,13 +392,16 @@ static inline void trace_ctx_init_fields(HPyContext *tctx, HPyContext *uctx) tctx->ctx_GetItem = &trace_ctx_GetItem; tctx->ctx_GetItem_i = &trace_ctx_GetItem_i; tctx->ctx_GetItem_s = &trace_ctx_GetItem_s; + tctx->ctx_GetSlice = &trace_ctx_GetSlice; tctx->ctx_Contains = &trace_ctx_Contains; tctx->ctx_SetItem = &trace_ctx_SetItem; tctx->ctx_SetItem_i = &trace_ctx_SetItem_i; tctx->ctx_SetItem_s = &trace_ctx_SetItem_s; + tctx->ctx_SetSlice = &trace_ctx_SetSlice; tctx->ctx_DelItem = &trace_ctx_DelItem; tctx->ctx_DelItem_i = &trace_ctx_DelItem_i; tctx->ctx_DelItem_s = &trace_ctx_DelItem_s; + tctx->ctx_DelSlice = &trace_ctx_DelSlice; tctx->ctx_Type = &trace_ctx_Type; tctx->ctx_TypeCheck = &trace_ctx_TypeCheck; tctx->ctx_Type_GetName = &trace_ctx_Type_GetName; @@ -423,6 +415,7 @@ static inline void trace_ctx_init_fields(HPyContext *tctx, HPyContext *uctx) tctx->ctx_AsStruct_Unicode = &trace_ctx_AsStruct_Unicode; tctx->ctx_AsStruct_Tuple = &trace_ctx_AsStruct_Tuple; tctx->ctx_AsStruct_List = &trace_ctx_AsStruct_List; + tctx->ctx_AsStruct_Dict = &trace_ctx_AsStruct_Dict; tctx->ctx_Type_GetBuiltinShape = &trace_ctx_Type_GetBuiltinShape; tctx->ctx_New = &trace_ctx_New; tctx->ctx_Repr = &trace_ctx_Repr; @@ -457,12 +450,14 @@ static inline void trace_ctx_init_fields(HPyContext *tctx, HPyContext *uctx) tctx->ctx_List_Check = &trace_ctx_List_Check; tctx->ctx_List_New = &trace_ctx_List_New; tctx->ctx_List_Append = &trace_ctx_List_Append; + tctx->ctx_List_Insert = &trace_ctx_List_Insert; tctx->ctx_Dict_Check = &trace_ctx_Dict_Check; tctx->ctx_Dict_New = &trace_ctx_Dict_New; tctx->ctx_Dict_Keys = &trace_ctx_Dict_Keys; tctx->ctx_Dict_Copy = &trace_ctx_Dict_Copy; tctx->ctx_Tuple_Check = &trace_ctx_Tuple_Check; tctx->ctx_Tuple_FromArray = &trace_ctx_Tuple_FromArray; + tctx->ctx_Slice_New = &trace_ctx_Slice_New; tctx->ctx_Slice_Unpack = &trace_ctx_Slice_Unpack; tctx->ctx_Import_ImportModule = &trace_ctx_Import_ImportModule; tctx->ctx_Capsule_New = &trace_ctx_Capsule_New; diff --git a/graalpython/com.oracle.graal.python.jni/src/trace/autogen_trace_func_table.c b/graalpython/hpy/hpy/trace/src/autogen_trace_func_table.c similarity index 82% rename from graalpython/com.oracle.graal.python.jni/src/trace/autogen_trace_func_table.c rename to graalpython/hpy/hpy/trace/src/autogen_trace_func_table.c index edc0987a02..97d8308d53 100644 --- a/graalpython/com.oracle.graal.python.jni/src/trace/autogen_trace_func_table.c +++ b/graalpython/hpy/hpy/trace/src/autogen_trace_func_table.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /* DO NOT EDIT THIS FILE! @@ -36,7 +12,7 @@ #include "trace_internal.h" -#define TRACE_NFUNC 180 +#define TRACE_NFUNC 189 #define NO_FUNC "" static const char *trace_func_table[] = { @@ -303,6 +279,16 @@ static const char *trace_func_table[] = { "ctx_SetCallFunction", "ctx_Call", "ctx_CallMethod", + NO_FUNC, + "ctx_AsStruct_Dict", + "ctx_List_Insert", + "ctx_GetSlice", + "ctx_SetSlice", + "ctx_DelSlice", + "ctx_GetIter", + "ctx_Iter_Next", + "ctx_Iter_Check", + "ctx_Slice_New", NULL /* sentinel */ }; @@ -313,7 +299,7 @@ int hpy_trace_get_nfunc(void) const char * hpy_trace_get_func_name(int idx) { - if (idx >= 0 && idx < 263) + if (idx >= 0 && idx < 273) return trace_func_table[idx]; return NULL; } diff --git a/graalpython/com.oracle.graal.python.jni/src/trace/autogen_trace_wrappers.c b/graalpython/hpy/hpy/trace/src/autogen_trace_wrappers.c similarity index 95% rename from graalpython/com.oracle.graal.python.jni/src/trace/autogen_trace_wrappers.c rename to graalpython/hpy/hpy/trace/src/autogen_trace_wrappers.c index 095bb5377d..4940a12a9d 100644 --- a/graalpython/com.oracle.graal.python.jni/src/trace/autogen_trace_wrappers.c +++ b/graalpython/hpy/hpy/trace/src/autogen_trace_wrappers.c @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /* DO NOT EDIT THIS FILE! @@ -828,6 +804,45 @@ HPy trace_ctx_CallMethod(HPyContext *tctx, HPy name, const HPy *args, size_t nar return res; } +HPy trace_ctx_GetIter(HPyContext *tctx, HPy obj) +{ + HPyTraceInfo *info = hpy_trace_on_enter(tctx, 269); + HPyContext *uctx = info->uctx; + _HPyTime_t _ts_start, _ts_end; + _HPyClockStatus_t r0, r1; + r0 = get_monotonic_clock(&_ts_start); + HPy res = HPy_GetIter(uctx, obj); + r1 = get_monotonic_clock(&_ts_end); + hpy_trace_on_exit(info, 269, r0, r1, &_ts_start, &_ts_end); + return res; +} + +HPy trace_ctx_Iter_Next(HPyContext *tctx, HPy obj) +{ + HPyTraceInfo *info = hpy_trace_on_enter(tctx, 270); + HPyContext *uctx = info->uctx; + _HPyTime_t _ts_start, _ts_end; + _HPyClockStatus_t r0, r1; + r0 = get_monotonic_clock(&_ts_start); + HPy res = HPyIter_Next(uctx, obj); + r1 = get_monotonic_clock(&_ts_end); + hpy_trace_on_exit(info, 270, r0, r1, &_ts_start, &_ts_end); + return res; +} + +int trace_ctx_Iter_Check(HPyContext *tctx, HPy obj) +{ + HPyTraceInfo *info = hpy_trace_on_enter(tctx, 271); + HPyContext *uctx = info->uctx; + _HPyTime_t _ts_start, _ts_end; + _HPyClockStatus_t r0, r1; + r0 = get_monotonic_clock(&_ts_start); + int res = HPyIter_Check(uctx, obj); + r1 = get_monotonic_clock(&_ts_end); + hpy_trace_on_exit(info, 271, r0, r1, &_ts_start, &_ts_end); + return res; +} + void trace_ctx_Err_SetString(HPyContext *tctx, HPy h_type, const char *utf8_message) { HPyTraceInfo *info = hpy_trace_on_enter(tctx, 137); @@ -1134,6 +1149,19 @@ HPy trace_ctx_GetItem_s(HPyContext *tctx, HPy obj, const char *utf8_key) return res; } +HPy trace_ctx_GetSlice(HPyContext *tctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) +{ + HPyTraceInfo *info = hpy_trace_on_enter(tctx, 266); + HPyContext *uctx = info->uctx; + _HPyTime_t _ts_start, _ts_end; + _HPyClockStatus_t r0, r1; + r0 = get_monotonic_clock(&_ts_start); + HPy res = HPy_GetSlice(uctx, obj, start, end); + r1 = get_monotonic_clock(&_ts_end); + hpy_trace_on_exit(info, 266, r0, r1, &_ts_start, &_ts_end); + return res; +} + int trace_ctx_Contains(HPyContext *tctx, HPy container, HPy key) { HPyTraceInfo *info = hpy_trace_on_enter(tctx, 161); @@ -1186,6 +1214,19 @@ int trace_ctx_SetItem_s(HPyContext *tctx, HPy obj, const char *utf8_key, HPy val return res; } +int trace_ctx_SetSlice(HPyContext *tctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end, HPy value) +{ + HPyTraceInfo *info = hpy_trace_on_enter(tctx, 267); + HPyContext *uctx = info->uctx; + _HPyTime_t _ts_start, _ts_end; + _HPyClockStatus_t r0, r1; + r0 = get_monotonic_clock(&_ts_start); + int res = HPy_SetSlice(uctx, obj, start, end, value); + r1 = get_monotonic_clock(&_ts_end); + hpy_trace_on_exit(info, 267, r0, r1, &_ts_start, &_ts_end); + return res; +} + int trace_ctx_DelItem(HPyContext *tctx, HPy obj, HPy key) { HPyTraceInfo *info = hpy_trace_on_enter(tctx, 235); @@ -1225,6 +1266,19 @@ int trace_ctx_DelItem_s(HPyContext *tctx, HPy obj, const char *utf8_key) return res; } +int trace_ctx_DelSlice(HPyContext *tctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) +{ + HPyTraceInfo *info = hpy_trace_on_enter(tctx, 268); + HPyContext *uctx = info->uctx; + _HPyTime_t _ts_start, _ts_end; + _HPyClockStatus_t r0, r1; + r0 = get_monotonic_clock(&_ts_start); + int res = HPy_DelSlice(uctx, obj, start, end); + r1 = get_monotonic_clock(&_ts_end); + hpy_trace_on_exit(info, 268, r0, r1, &_ts_start, &_ts_end); + return res; +} + HPy trace_ctx_Type(HPyContext *tctx, HPy obj) { HPyTraceInfo *info = hpy_trace_on_enter(tctx, 165); @@ -1394,6 +1448,19 @@ void *trace_ctx_AsStruct_List(HPyContext *tctx, HPy h) return res; } +void *trace_ctx_AsStruct_Dict(HPyContext *tctx, HPy h) +{ + HPyTraceInfo *info = hpy_trace_on_enter(tctx, 264); + HPyContext *uctx = info->uctx; + _HPyTime_t _ts_start, _ts_end; + _HPyClockStatus_t r0, r1; + r0 = get_monotonic_clock(&_ts_start); + void * res = _HPy_AsStruct_Dict(uctx, h); + r1 = get_monotonic_clock(&_ts_end); + hpy_trace_on_exit(info, 264, r0, r1, &_ts_start, &_ts_end); + return res; +} + HPyType_BuiltinShape trace_ctx_Type_GetBuiltinShape(HPyContext *tctx, HPy h_type) { HPyTraceInfo *info = hpy_trace_on_enter(tctx, 234); @@ -1836,6 +1903,19 @@ int trace_ctx_List_Append(HPyContext *tctx, HPy h_list, HPy h_item) return res; } +int trace_ctx_List_Insert(HPyContext *tctx, HPy h_list, HPy_ssize_t index, HPy h_item) +{ + HPyTraceInfo *info = hpy_trace_on_enter(tctx, 265); + HPyContext *uctx = info->uctx; + _HPyTime_t _ts_start, _ts_end; + _HPyClockStatus_t r0, r1; + r0 = get_monotonic_clock(&_ts_start); + int res = HPyList_Insert(uctx, h_list, index, h_item); + r1 = get_monotonic_clock(&_ts_end); + hpy_trace_on_exit(info, 265, r0, r1, &_ts_start, &_ts_end); + return res; +} + int trace_ctx_Dict_Check(HPyContext *tctx, HPy h) { HPyTraceInfo *info = hpy_trace_on_enter(tctx, 201); @@ -1901,7 +1981,7 @@ int trace_ctx_Tuple_Check(HPyContext *tctx, HPy h) return res; } -HPy trace_ctx_Tuple_FromArray(HPyContext *tctx, HPy items[], HPy_ssize_t n) +HPy trace_ctx_Tuple_FromArray(HPyContext *tctx, const HPy items[], HPy_ssize_t n) { HPyTraceInfo *info = hpy_trace_on_enter(tctx, 204); HPyContext *uctx = info->uctx; @@ -1914,6 +1994,19 @@ HPy trace_ctx_Tuple_FromArray(HPyContext *tctx, HPy items[], HPy_ssize_t n) return res; } +HPy trace_ctx_Slice_New(HPyContext *tctx, HPy start, HPy stop, HPy step) +{ + HPyTraceInfo *info = hpy_trace_on_enter(tctx, 272); + HPyContext *uctx = info->uctx; + _HPyTime_t _ts_start, _ts_end; + _HPyClockStatus_t r0, r1; + r0 = get_monotonic_clock(&_ts_start); + HPy res = HPySlice_New(uctx, start, stop, step); + r1 = get_monotonic_clock(&_ts_end); + hpy_trace_on_exit(info, 272, r0, r1, &_ts_start, &_ts_end); + return res; +} + int trace_ctx_Slice_Unpack(HPyContext *tctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step) { HPyTraceInfo *info = hpy_trace_on_enter(tctx, 259); diff --git a/graalpython/com.oracle.graal.python.jni/src/trace/hpy_trace.h b/graalpython/hpy/hpy/trace/src/include/hpy_trace.h similarity index 51% rename from graalpython/com.oracle.graal.python.jni/src/trace/hpy_trace.h rename to graalpython/hpy/hpy/trace/src/include/hpy_trace.h index 70d6320239..e75b76186e 100644 --- a/graalpython/com.oracle.graal.python.jni/src/trace/hpy_trace.h +++ b/graalpython/hpy/hpy/trace/src/include/hpy_trace.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #ifndef HPY_TRACE_H #define HPY_TRACE_H diff --git a/graalpython/com.oracle.graal.python.jni/src/trace/trace_ctx.c b/graalpython/hpy/hpy/trace/src/trace_ctx.c similarity index 76% rename from graalpython/com.oracle.graal.python.jni/src/trace/trace_ctx.c rename to graalpython/hpy/hpy/trace/src/trace_ctx.c index 1e8a68a519..1b18096fe5 100644 --- a/graalpython/com.oracle.graal.python.jni/src/trace/trace_ctx.c +++ b/graalpython/hpy/hpy/trace/src/trace_ctx.c @@ -1,30 +1,12 @@ -/* MIT License - * - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - #include "trace_internal.h" #include "autogen_trace_ctx_init.h" +static struct _HPyContext_s g_trace_ctx = { + .name = "HPy Trace Mode ABI", + ._private = NULL, + .abi_version = HPY_ABI_VERSION, +}; + // NOTE: at the moment this function assumes that uctx is always the // same. If/when we migrate to a system in which we can have multiple // independent contexts, this function should ensure to create a different @@ -60,6 +42,23 @@ int hpy_trace_ctx_free(HPyContext *tctx) return 0; } +HPyContext * hpy_trace_get_ctx(HPyContext *uctx) +{ + HPyContext *tctx = &g_trace_ctx; + if (uctx == tctx) { + HPy_FatalError(uctx, "hpy_trace_get_ctx: expected an universal ctx, " + "got a trace ctx"); + } + if (hpy_trace_ctx_init(tctx, uctx) < 0) + return NULL; + return tctx; +} + +void hpy_trace_set_ctx(HPyContext *tctx) +{ + g_trace_ctx = *tctx; +} + static HPy create_trace_func_args(HPyContext *uctx, int id) { HPy h_name = HPyUnicode_FromString(uctx, hpy_trace_get_func_name(id)); diff --git a/graalpython/com.oracle.graal.python.jni/src/trace/trace_internal.h b/graalpython/hpy/hpy/trace/src/trace_internal.h similarity index 60% rename from graalpython/com.oracle.graal.python.jni/src/trace/trace_internal.h rename to graalpython/hpy/hpy/trace/src/trace_internal.h index 30c3da6d85..5075bb968c 100644 --- a/graalpython/com.oracle.graal.python.jni/src/trace/trace_internal.h +++ b/graalpython/hpy/hpy/trace/src/trace_internal.h @@ -1,27 +1,3 @@ -/* MIT License - * - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - /* Internal header for all the files in hpy/debug/src. The public API is in include/hpy_debug.h */ diff --git a/graalpython/hpy/hpy/universal/src/api.h b/graalpython/hpy/hpy/universal/src/api.h new file mode 100644 index 0000000000..ea4b8108eb --- /dev/null +++ b/graalpython/hpy/hpy/universal/src/api.h @@ -0,0 +1,18 @@ +#ifndef HPY_API_H +#define HPY_API_H + +#include "hpy.h" + +extern struct _HPyContext_s g_universal_ctx; + +/* declare alloca() */ +#if defined(_MSC_VER) +# include /* for alloca() */ +#else +# include +# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux) +# include +# endif +#endif + +#endif /* HPY_API_H */ diff --git a/graalpython/hpy/hpy/universal/src/autogen_ctx_call.i b/graalpython/hpy/hpy/universal/src/autogen_ctx_call.i new file mode 100644 index 0000000000..7c6a759f11 --- /dev/null +++ b/graalpython/hpy/hpy/universal/src/autogen_ctx_call.i @@ -0,0 +1,180 @@ + +/* + DO NOT EDIT THIS FILE! + + This file is automatically generated by hpy.tools.autogen.hpyfunc.autogen_ctx_call_i + See also hpy.tools.autogen and hpy/tools/public_api.h + + Run this to regenerate: + make autogen + +*/ + + case HPyFunc_NOARGS: { + HPyFunc_noargs f = (HPyFunc_noargs)func; + _HPyFunc_args_NOARGS *a = (_HPyFunc_args_NOARGS*)args; + a->result = _h2py(f(ctx, _py2h(a->self))); + return; + } + case HPyFunc_O: { + HPyFunc_o f = (HPyFunc_o)func; + _HPyFunc_args_O *a = (_HPyFunc_args_O*)args; + a->result = _h2py(f(ctx, _py2h(a->self), _py2h(a->arg))); + return; + } + case HPyFunc_UNARYFUNC: { + HPyFunc_unaryfunc f = (HPyFunc_unaryfunc)func; + _HPyFunc_args_UNARYFUNC *a = (_HPyFunc_args_UNARYFUNC*)args; + a->result = _h2py(f(ctx, _py2h(a->arg0))); + return; + } + case HPyFunc_BINARYFUNC: { + HPyFunc_binaryfunc f = (HPyFunc_binaryfunc)func; + _HPyFunc_args_BINARYFUNC *a = (_HPyFunc_args_BINARYFUNC*)args; + a->result = _h2py(f(ctx, _py2h(a->arg0), _py2h(a->arg1))); + return; + } + case HPyFunc_TERNARYFUNC: { + HPyFunc_ternaryfunc f = (HPyFunc_ternaryfunc)func; + _HPyFunc_args_TERNARYFUNC *a = (_HPyFunc_args_TERNARYFUNC*)args; + a->result = _h2py(f(ctx, _py2h(a->arg0), _py2h(a->arg1), _py2h(a->arg2))); + return; + } + case HPyFunc_INQUIRY: { + HPyFunc_inquiry f = (HPyFunc_inquiry)func; + _HPyFunc_args_INQUIRY *a = (_HPyFunc_args_INQUIRY*)args; + a->result = (f(ctx, _py2h(a->arg0))); + return; + } + case HPyFunc_LENFUNC: { + HPyFunc_lenfunc f = (HPyFunc_lenfunc)func; + _HPyFunc_args_LENFUNC *a = (_HPyFunc_args_LENFUNC*)args; + a->result = (f(ctx, _py2h(a->arg0))); + return; + } + case HPyFunc_SSIZEARGFUNC: { + HPyFunc_ssizeargfunc f = (HPyFunc_ssizeargfunc)func; + _HPyFunc_args_SSIZEARGFUNC *a = (_HPyFunc_args_SSIZEARGFUNC*)args; + a->result = _h2py(f(ctx, _py2h(a->arg0), (a->arg1))); + return; + } + case HPyFunc_SSIZESSIZEARGFUNC: { + HPyFunc_ssizessizeargfunc f = (HPyFunc_ssizessizeargfunc)func; + _HPyFunc_args_SSIZESSIZEARGFUNC *a = (_HPyFunc_args_SSIZESSIZEARGFUNC*)args; + a->result = _h2py(f(ctx, _py2h(a->arg0), (a->arg1), (a->arg2))); + return; + } + case HPyFunc_SSIZEOBJARGPROC: { + HPyFunc_ssizeobjargproc f = (HPyFunc_ssizeobjargproc)func; + _HPyFunc_args_SSIZEOBJARGPROC *a = (_HPyFunc_args_SSIZEOBJARGPROC*)args; + a->result = (f(ctx, _py2h(a->arg0), (a->arg1), _py2h(a->arg2))); + return; + } + case HPyFunc_SSIZESSIZEOBJARGPROC: { + HPyFunc_ssizessizeobjargproc f = (HPyFunc_ssizessizeobjargproc)func; + _HPyFunc_args_SSIZESSIZEOBJARGPROC *a = (_HPyFunc_args_SSIZESSIZEOBJARGPROC*)args; + a->result = (f(ctx, _py2h(a->arg0), (a->arg1), (a->arg2), _py2h(a->arg3))); + return; + } + case HPyFunc_OBJOBJARGPROC: { + HPyFunc_objobjargproc f = (HPyFunc_objobjargproc)func; + _HPyFunc_args_OBJOBJARGPROC *a = (_HPyFunc_args_OBJOBJARGPROC*)args; + a->result = (f(ctx, _py2h(a->arg0), _py2h(a->arg1), _py2h(a->arg2))); + return; + } + case HPyFunc_FREEFUNC: { + HPyFunc_freefunc f = (HPyFunc_freefunc)func; + _HPyFunc_args_FREEFUNC *a = (_HPyFunc_args_FREEFUNC*)args; + f(ctx, (a->arg0)); + return; + } + case HPyFunc_GETATTRFUNC: { + HPyFunc_getattrfunc f = (HPyFunc_getattrfunc)func; + _HPyFunc_args_GETATTRFUNC *a = (_HPyFunc_args_GETATTRFUNC*)args; + a->result = _h2py(f(ctx, _py2h(a->arg0), (a->arg1))); + return; + } + case HPyFunc_GETATTROFUNC: { + HPyFunc_getattrofunc f = (HPyFunc_getattrofunc)func; + _HPyFunc_args_GETATTROFUNC *a = (_HPyFunc_args_GETATTROFUNC*)args; + a->result = _h2py(f(ctx, _py2h(a->arg0), _py2h(a->arg1))); + return; + } + case HPyFunc_SETATTRFUNC: { + HPyFunc_setattrfunc f = (HPyFunc_setattrfunc)func; + _HPyFunc_args_SETATTRFUNC *a = (_HPyFunc_args_SETATTRFUNC*)args; + a->result = (f(ctx, _py2h(a->arg0), (a->arg1), _py2h(a->arg2))); + return; + } + case HPyFunc_SETATTROFUNC: { + HPyFunc_setattrofunc f = (HPyFunc_setattrofunc)func; + _HPyFunc_args_SETATTROFUNC *a = (_HPyFunc_args_SETATTROFUNC*)args; + a->result = (f(ctx, _py2h(a->arg0), _py2h(a->arg1), _py2h(a->arg2))); + return; + } + case HPyFunc_REPRFUNC: { + HPyFunc_reprfunc f = (HPyFunc_reprfunc)func; + _HPyFunc_args_REPRFUNC *a = (_HPyFunc_args_REPRFUNC*)args; + a->result = _h2py(f(ctx, _py2h(a->arg0))); + return; + } + case HPyFunc_HASHFUNC: { + HPyFunc_hashfunc f = (HPyFunc_hashfunc)func; + _HPyFunc_args_HASHFUNC *a = (_HPyFunc_args_HASHFUNC*)args; + a->result = (f(ctx, _py2h(a->arg0))); + return; + } + case HPyFunc_RICHCMPFUNC: { + HPyFunc_richcmpfunc f = (HPyFunc_richcmpfunc)func; + _HPyFunc_args_RICHCMPFUNC *a = (_HPyFunc_args_RICHCMPFUNC*)args; + a->result = _h2py(f(ctx, _py2h(a->arg0), _py2h(a->arg1), (a->arg2))); + return; + } + case HPyFunc_GETITERFUNC: { + HPyFunc_getiterfunc f = (HPyFunc_getiterfunc)func; + _HPyFunc_args_GETITERFUNC *a = (_HPyFunc_args_GETITERFUNC*)args; + a->result = _h2py(f(ctx, _py2h(a->arg0))); + return; + } + case HPyFunc_ITERNEXTFUNC: { + HPyFunc_iternextfunc f = (HPyFunc_iternextfunc)func; + _HPyFunc_args_ITERNEXTFUNC *a = (_HPyFunc_args_ITERNEXTFUNC*)args; + a->result = _h2py(f(ctx, _py2h(a->arg0))); + return; + } + case HPyFunc_DESCRGETFUNC: { + HPyFunc_descrgetfunc f = (HPyFunc_descrgetfunc)func; + _HPyFunc_args_DESCRGETFUNC *a = (_HPyFunc_args_DESCRGETFUNC*)args; + a->result = _h2py(f(ctx, _py2h(a->arg0), _py2h(a->arg1), _py2h(a->arg2))); + return; + } + case HPyFunc_DESCRSETFUNC: { + HPyFunc_descrsetfunc f = (HPyFunc_descrsetfunc)func; + _HPyFunc_args_DESCRSETFUNC *a = (_HPyFunc_args_DESCRSETFUNC*)args; + a->result = (f(ctx, _py2h(a->arg0), _py2h(a->arg1), _py2h(a->arg2))); + return; + } + case HPyFunc_GETTER: { + HPyFunc_getter f = (HPyFunc_getter)func; + _HPyFunc_args_GETTER *a = (_HPyFunc_args_GETTER*)args; + a->result = _h2py(f(ctx, _py2h(a->arg0), (a->arg1))); + return; + } + case HPyFunc_SETTER: { + HPyFunc_setter f = (HPyFunc_setter)func; + _HPyFunc_args_SETTER *a = (_HPyFunc_args_SETTER*)args; + a->result = (f(ctx, _py2h(a->arg0), _py2h(a->arg1), (a->arg2))); + return; + } + case HPyFunc_OBJOBJPROC: { + HPyFunc_objobjproc f = (HPyFunc_objobjproc)func; + _HPyFunc_args_OBJOBJPROC *a = (_HPyFunc_args_OBJOBJPROC*)args; + a->result = (f(ctx, _py2h(a->arg0), _py2h(a->arg1))); + return; + } + case HPyFunc_DESTRUCTOR: { + HPyFunc_destructor f = (HPyFunc_destructor)func; + _HPyFunc_args_DESTRUCTOR *a = (_HPyFunc_args_DESTRUCTOR*)args; + f(ctx, _py2h(a->arg0)); + return; + } diff --git a/graalpython/hpy/hpy/universal/src/autogen_ctx_def.h b/graalpython/hpy/hpy/universal/src/autogen_ctx_def.h new file mode 100644 index 0000000000..4bdeec338e --- /dev/null +++ b/graalpython/hpy/hpy/universal/src/autogen_ctx_def.h @@ -0,0 +1,207 @@ + +/* + DO NOT EDIT THIS FILE! + + This file is automatically generated by hpy.tools.autogen.ctx.autogen_ctx_def_h + See also hpy.tools.autogen and hpy/tools/public_api.h + + Run this to regenerate: + make autogen + +*/ + +struct _HPyContext_s g_universal_ctx = { + .name = "HPy Universal ABI (CPython backend)", + ._private = NULL, + .abi_version = HPY_ABI_VERSION, + /* h_None & co. are initialized by init_universal_ctx() */ + .ctx_Dup = &ctx_Dup, + .ctx_Close = &ctx_Close, + .ctx_Long_FromInt32_t = &ctx_Long_FromInt32_t, + .ctx_Long_FromUInt32_t = &ctx_Long_FromUInt32_t, + .ctx_Long_FromInt64_t = &ctx_Long_FromInt64_t, + .ctx_Long_FromUInt64_t = &ctx_Long_FromUInt64_t, + .ctx_Long_FromSize_t = &ctx_Long_FromSize_t, + .ctx_Long_FromSsize_t = &ctx_Long_FromSsize_t, + .ctx_Long_AsInt32_t = &ctx_Long_AsInt32_t, + .ctx_Long_AsUInt32_t = &ctx_Long_AsUInt32_t, + .ctx_Long_AsUInt32_tMask = &ctx_Long_AsUInt32_tMask, + .ctx_Long_AsInt64_t = &ctx_Long_AsInt64_t, + .ctx_Long_AsUInt64_t = &ctx_Long_AsUInt64_t, + .ctx_Long_AsUInt64_tMask = &ctx_Long_AsUInt64_tMask, + .ctx_Long_AsSize_t = &ctx_Long_AsSize_t, + .ctx_Long_AsSsize_t = &ctx_Long_AsSsize_t, + .ctx_Long_AsVoidPtr = &ctx_Long_AsVoidPtr, + .ctx_Long_AsDouble = &ctx_Long_AsDouble, + .ctx_Float_FromDouble = &ctx_Float_FromDouble, + .ctx_Float_AsDouble = &ctx_Float_AsDouble, + .ctx_Bool_FromBool = &ctx_Bool_FromBool, + .ctx_Length = &ctx_Length, + .ctx_Number_Check = &ctx_Number_Check, + .ctx_Add = &ctx_Add, + .ctx_Subtract = &ctx_Subtract, + .ctx_Multiply = &ctx_Multiply, + .ctx_MatrixMultiply = &ctx_MatrixMultiply, + .ctx_FloorDivide = &ctx_FloorDivide, + .ctx_TrueDivide = &ctx_TrueDivide, + .ctx_Remainder = &ctx_Remainder, + .ctx_Divmod = &ctx_Divmod, + .ctx_Power = &ctx_Power, + .ctx_Negative = &ctx_Negative, + .ctx_Positive = &ctx_Positive, + .ctx_Absolute = &ctx_Absolute, + .ctx_Invert = &ctx_Invert, + .ctx_Lshift = &ctx_Lshift, + .ctx_Rshift = &ctx_Rshift, + .ctx_And = &ctx_And, + .ctx_Xor = &ctx_Xor, + .ctx_Or = &ctx_Or, + .ctx_Index = &ctx_Index, + .ctx_Long = &ctx_Long, + .ctx_Float = &ctx_Float, + .ctx_InPlaceAdd = &ctx_InPlaceAdd, + .ctx_InPlaceSubtract = &ctx_InPlaceSubtract, + .ctx_InPlaceMultiply = &ctx_InPlaceMultiply, + .ctx_InPlaceMatrixMultiply = &ctx_InPlaceMatrixMultiply, + .ctx_InPlaceFloorDivide = &ctx_InPlaceFloorDivide, + .ctx_InPlaceTrueDivide = &ctx_InPlaceTrueDivide, + .ctx_InPlaceRemainder = &ctx_InPlaceRemainder, + .ctx_InPlacePower = &ctx_InPlacePower, + .ctx_InPlaceLshift = &ctx_InPlaceLshift, + .ctx_InPlaceRshift = &ctx_InPlaceRshift, + .ctx_InPlaceAnd = &ctx_InPlaceAnd, + .ctx_InPlaceXor = &ctx_InPlaceXor, + .ctx_InPlaceOr = &ctx_InPlaceOr, + .ctx_Callable_Check = &ctx_Callable_Check, + .ctx_CallTupleDict = &ctx_CallTupleDict, + .ctx_Call = &ctx_Call, + .ctx_CallMethod = &ctx_CallMethod, + .ctx_GetIter = &ctx_GetIter, + .ctx_Iter_Next = &ctx_Iter_Next, + .ctx_Iter_Check = &ctx_Iter_Check, + .ctx_FatalError = &ctx_FatalError, + .ctx_Err_SetString = &ctx_Err_SetString, + .ctx_Err_SetObject = &ctx_Err_SetObject, + .ctx_Err_SetFromErrnoWithFilename = &ctx_Err_SetFromErrnoWithFilename, + .ctx_Err_SetFromErrnoWithFilenameObjects = &ctx_Err_SetFromErrnoWithFilenameObjects, + .ctx_Err_Occurred = &ctx_Err_Occurred, + .ctx_Err_ExceptionMatches = &ctx_Err_ExceptionMatches, + .ctx_Err_NoMemory = &ctx_Err_NoMemory, + .ctx_Err_Clear = &ctx_Err_Clear, + .ctx_Err_NewException = &ctx_Err_NewException, + .ctx_Err_NewExceptionWithDoc = &ctx_Err_NewExceptionWithDoc, + .ctx_Err_WarnEx = &ctx_Err_WarnEx, + .ctx_Err_WriteUnraisable = &ctx_Err_WriteUnraisable, + .ctx_IsTrue = &ctx_IsTrue, + .ctx_Type_FromSpec = &ctx_Type_FromSpec, + .ctx_Type_GenericNew = &ctx_Type_GenericNew, + .ctx_GetAttr = &ctx_GetAttr, + .ctx_GetAttr_s = &ctx_GetAttr_s, + .ctx_HasAttr = &ctx_HasAttr, + .ctx_HasAttr_s = &ctx_HasAttr_s, + .ctx_SetAttr = &ctx_SetAttr, + .ctx_SetAttr_s = &ctx_SetAttr_s, + .ctx_GetItem = &ctx_GetItem, + .ctx_GetItem_i = &ctx_GetItem_i, + .ctx_GetItem_s = &ctx_GetItem_s, + .ctx_GetSlice = &ctx_GetSlice, + .ctx_Contains = &ctx_Contains, + .ctx_SetItem = &ctx_SetItem, + .ctx_SetItem_i = &ctx_SetItem_i, + .ctx_SetItem_s = &ctx_SetItem_s, + .ctx_SetSlice = &ctx_SetSlice, + .ctx_DelItem = &ctx_DelItem, + .ctx_DelItem_i = &ctx_DelItem_i, + .ctx_DelItem_s = &ctx_DelItem_s, + .ctx_DelSlice = &ctx_DelSlice, + .ctx_Type = &ctx_Type, + .ctx_TypeCheck = &ctx_TypeCheck, + .ctx_Type_GetName = &ctx_Type_GetName, + .ctx_Type_IsSubtype = &ctx_Type_IsSubtype, + .ctx_Is = &ctx_Is, + .ctx_AsStruct_Object = &ctx_AsStruct_Object, + .ctx_AsStruct_Legacy = &ctx_AsStruct_Legacy, + .ctx_AsStruct_Type = &ctx_AsStruct_Type, + .ctx_AsStruct_Long = &ctx_AsStruct_Long, + .ctx_AsStruct_Float = &ctx_AsStruct_Float, + .ctx_AsStruct_Unicode = &ctx_AsStruct_Unicode, + .ctx_AsStruct_Tuple = &ctx_AsStruct_Tuple, + .ctx_AsStruct_List = &ctx_AsStruct_List, + .ctx_AsStruct_Dict = &ctx_AsStruct_Dict, + .ctx_Type_GetBuiltinShape = &ctx_Type_GetBuiltinShape, + .ctx_New = &ctx_New, + .ctx_Repr = &ctx_Repr, + .ctx_Str = &ctx_Str, + .ctx_ASCII = &ctx_ASCII, + .ctx_Bytes = &ctx_Bytes, + .ctx_RichCompare = &ctx_RichCompare, + .ctx_RichCompareBool = &ctx_RichCompareBool, + .ctx_Hash = &ctx_Hash, + .ctx_Bytes_Check = &ctx_Bytes_Check, + .ctx_Bytes_Size = &ctx_Bytes_Size, + .ctx_Bytes_GET_SIZE = &ctx_Bytes_GET_SIZE, + .ctx_Bytes_AsString = &ctx_Bytes_AsString, + .ctx_Bytes_AS_STRING = &ctx_Bytes_AS_STRING, + .ctx_Bytes_FromString = &ctx_Bytes_FromString, + .ctx_Bytes_FromStringAndSize = &ctx_Bytes_FromStringAndSize, + .ctx_Unicode_FromString = &ctx_Unicode_FromString, + .ctx_Unicode_Check = &ctx_Unicode_Check, + .ctx_Unicode_AsASCIIString = &ctx_Unicode_AsASCIIString, + .ctx_Unicode_AsLatin1String = &ctx_Unicode_AsLatin1String, + .ctx_Unicode_AsUTF8String = &ctx_Unicode_AsUTF8String, + .ctx_Unicode_AsUTF8AndSize = &ctx_Unicode_AsUTF8AndSize, + .ctx_Unicode_FromWideChar = &ctx_Unicode_FromWideChar, + .ctx_Unicode_DecodeFSDefault = &ctx_Unicode_DecodeFSDefault, + .ctx_Unicode_DecodeFSDefaultAndSize = &ctx_Unicode_DecodeFSDefaultAndSize, + .ctx_Unicode_EncodeFSDefault = &ctx_Unicode_EncodeFSDefault, + .ctx_Unicode_ReadChar = &ctx_Unicode_ReadChar, + .ctx_Unicode_DecodeASCII = &ctx_Unicode_DecodeASCII, + .ctx_Unicode_DecodeLatin1 = &ctx_Unicode_DecodeLatin1, + .ctx_Unicode_FromEncodedObject = &ctx_Unicode_FromEncodedObject, + .ctx_Unicode_Substring = &ctx_Unicode_Substring, + .ctx_List_Check = &ctx_List_Check, + .ctx_List_New = &ctx_List_New, + .ctx_List_Append = &ctx_List_Append, + .ctx_List_Insert = &ctx_List_Insert, + .ctx_Dict_Check = &ctx_Dict_Check, + .ctx_Dict_New = &ctx_Dict_New, + .ctx_Dict_Keys = &ctx_Dict_Keys, + .ctx_Dict_Copy = &ctx_Dict_Copy, + .ctx_Tuple_Check = &ctx_Tuple_Check, + .ctx_Tuple_FromArray = &ctx_Tuple_FromArray, + .ctx_Slice_New = &ctx_Slice_New, + .ctx_Slice_Unpack = &ctx_Slice_Unpack, + .ctx_Import_ImportModule = &ctx_Import_ImportModule, + .ctx_Capsule_New = &ctx_Capsule_New, + .ctx_Capsule_Get = &ctx_Capsule_Get, + .ctx_Capsule_IsValid = &ctx_Capsule_IsValid, + .ctx_Capsule_Set = &ctx_Capsule_Set, + .ctx_FromPyObject = &ctx_FromPyObject, + .ctx_AsPyObject = &ctx_AsPyObject, + .ctx_CallRealFunctionFromTrampoline = &ctx_CallRealFunctionFromTrampoline, + .ctx_ListBuilder_New = &ctx_ListBuilder_New, + .ctx_ListBuilder_Set = &ctx_ListBuilder_Set, + .ctx_ListBuilder_Build = &ctx_ListBuilder_Build, + .ctx_ListBuilder_Cancel = &ctx_ListBuilder_Cancel, + .ctx_TupleBuilder_New = &ctx_TupleBuilder_New, + .ctx_TupleBuilder_Set = &ctx_TupleBuilder_Set, + .ctx_TupleBuilder_Build = &ctx_TupleBuilder_Build, + .ctx_TupleBuilder_Cancel = &ctx_TupleBuilder_Cancel, + .ctx_Tracker_New = &ctx_Tracker_New, + .ctx_Tracker_Add = &ctx_Tracker_Add, + .ctx_Tracker_ForgetAll = &ctx_Tracker_ForgetAll, + .ctx_Tracker_Close = &ctx_Tracker_Close, + .ctx_Field_Store = &ctx_Field_Store, + .ctx_Field_Load = &ctx_Field_Load, + .ctx_ReenterPythonExecution = &ctx_ReenterPythonExecution, + .ctx_LeavePythonExecution = &ctx_LeavePythonExecution, + .ctx_Global_Store = &ctx_Global_Store, + .ctx_Global_Load = &ctx_Global_Load, + .ctx_Dump = &ctx_Dump, + .ctx_Compile_s = &ctx_Compile_s, + .ctx_EvalCode = &ctx_EvalCode, + .ctx_ContextVar_New = &ctx_ContextVar_New, + .ctx_ContextVar_Get = &ctx_ContextVar_Get, + .ctx_ContextVar_Set = &ctx_ContextVar_Set, + .ctx_SetCallFunction = &ctx_SetCallFunction, +}; diff --git a/graalpython/hpy/hpy/universal/src/autogen_ctx_impl.h b/graalpython/hpy/hpy/universal/src/autogen_ctx_impl.h new file mode 100644 index 0000000000..15c6e35b39 --- /dev/null +++ b/graalpython/hpy/hpy/universal/src/autogen_ctx_impl.h @@ -0,0 +1,612 @@ + +/* + DO NOT EDIT THIS FILE! + + This file is automatically generated by hpy.tools.autogen.trampolines.universal_autogen_ctx_impl_h + See also hpy.tools.autogen and hpy/tools/public_api.h + + Run this to regenerate: + make autogen + +*/ + +HPyAPI_IMPL HPy ctx_Long_FromSize_t(HPyContext *ctx, size_t value) +{ + return _py2h(PyLong_FromSize_t(value)); +} + +HPyAPI_IMPL HPy ctx_Long_FromSsize_t(HPyContext *ctx, HPy_ssize_t value) +{ + return _py2h(PyLong_FromSsize_t(value)); +} + +HPyAPI_IMPL size_t ctx_Long_AsSize_t(HPyContext *ctx, HPy h) +{ + return PyLong_AsSize_t(_h2py(h)); +} + +HPyAPI_IMPL HPy_ssize_t ctx_Long_AsSsize_t(HPyContext *ctx, HPy h) +{ + return PyLong_AsSsize_t(_h2py(h)); +} + +HPyAPI_IMPL void *ctx_Long_AsVoidPtr(HPyContext *ctx, HPy h) +{ + return PyLong_AsVoidPtr(_h2py(h)); +} + +HPyAPI_IMPL double ctx_Long_AsDouble(HPyContext *ctx, HPy h) +{ + return PyLong_AsDouble(_h2py(h)); +} + +HPyAPI_IMPL HPy ctx_Float_FromDouble(HPyContext *ctx, double v) +{ + return _py2h(PyFloat_FromDouble(v)); +} + +HPyAPI_IMPL double ctx_Float_AsDouble(HPyContext *ctx, HPy h) +{ + return PyFloat_AsDouble(_h2py(h)); +} + +HPyAPI_IMPL HPy ctx_Bool_FromBool(HPyContext *ctx, bool v) +{ + return _py2h(PyBool_FromLong(v)); +} + +HPyAPI_IMPL HPy_ssize_t ctx_Length(HPyContext *ctx, HPy h) +{ + return PyObject_Length(_h2py(h)); +} + +HPyAPI_IMPL int ctx_Number_Check(HPyContext *ctx, HPy h) +{ + return PyNumber_Check(_h2py(h)); +} + +HPyAPI_IMPL HPy ctx_Add(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_Add(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_Subtract(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_Subtract(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_Multiply(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_Multiply(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_MatrixMultiply(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_MatrixMultiply(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_FloorDivide(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_FloorDivide(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_TrueDivide(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_TrueDivide(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_Remainder(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_Remainder(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_Divmod(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_Divmod(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_Power(HPyContext *ctx, HPy h1, HPy h2, HPy h3) +{ + return _py2h(PyNumber_Power(_h2py(h1), _h2py(h2), _h2py(h3))); +} + +HPyAPI_IMPL HPy ctx_Negative(HPyContext *ctx, HPy h1) +{ + return _py2h(PyNumber_Negative(_h2py(h1))); +} + +HPyAPI_IMPL HPy ctx_Positive(HPyContext *ctx, HPy h1) +{ + return _py2h(PyNumber_Positive(_h2py(h1))); +} + +HPyAPI_IMPL HPy ctx_Absolute(HPyContext *ctx, HPy h1) +{ + return _py2h(PyNumber_Absolute(_h2py(h1))); +} + +HPyAPI_IMPL HPy ctx_Invert(HPyContext *ctx, HPy h1) +{ + return _py2h(PyNumber_Invert(_h2py(h1))); +} + +HPyAPI_IMPL HPy ctx_Lshift(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_Lshift(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_Rshift(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_Rshift(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_And(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_And(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_Xor(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_Xor(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_Or(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_Or(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_Index(HPyContext *ctx, HPy h1) +{ + return _py2h(PyNumber_Index(_h2py(h1))); +} + +HPyAPI_IMPL HPy ctx_Long(HPyContext *ctx, HPy h1) +{ + return _py2h(PyNumber_Long(_h2py(h1))); +} + +HPyAPI_IMPL HPy ctx_Float(HPyContext *ctx, HPy h1) +{ + return _py2h(PyNumber_Float(_h2py(h1))); +} + +HPyAPI_IMPL HPy ctx_InPlaceAdd(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_InPlaceAdd(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_InPlaceSubtract(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_InPlaceSubtract(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_InPlaceMultiply(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_InPlaceMultiply(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_InPlaceMatrixMultiply(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_InPlaceMatrixMultiply(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_InPlaceFloorDivide(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_InPlaceFloorDivide(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_InPlaceTrueDivide(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_InPlaceTrueDivide(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_InPlaceRemainder(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_InPlaceRemainder(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_InPlacePower(HPyContext *ctx, HPy h1, HPy h2, HPy h3) +{ + return _py2h(PyNumber_InPlacePower(_h2py(h1), _h2py(h2), _h2py(h3))); +} + +HPyAPI_IMPL HPy ctx_InPlaceLshift(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_InPlaceLshift(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_InPlaceRshift(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_InPlaceRshift(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_InPlaceAnd(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_InPlaceAnd(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_InPlaceXor(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_InPlaceXor(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL HPy ctx_InPlaceOr(HPyContext *ctx, HPy h1, HPy h2) +{ + return _py2h(PyNumber_InPlaceOr(_h2py(h1), _h2py(h2))); +} + +HPyAPI_IMPL int ctx_Callable_Check(HPyContext *ctx, HPy h) +{ + return PyCallable_Check(_h2py(h)); +} + +HPyAPI_IMPL HPy ctx_GetIter(HPyContext *ctx, HPy obj) +{ + return _py2h(PyObject_GetIter(_h2py(obj))); +} + +HPyAPI_IMPL HPy ctx_Iter_Next(HPyContext *ctx, HPy obj) +{ + return _py2h(PyIter_Next(_h2py(obj))); +} + +HPyAPI_IMPL int ctx_Iter_Check(HPyContext *ctx, HPy obj) +{ + return PyIter_Check(_h2py(obj)); +} + +HPyAPI_IMPL void ctx_Err_SetString(HPyContext *ctx, HPy h_type, const char *utf8_message) +{ + PyErr_SetString(_h2py(h_type), utf8_message); +} + +HPyAPI_IMPL void ctx_Err_SetObject(HPyContext *ctx, HPy h_type, HPy h_value) +{ + PyErr_SetObject(_h2py(h_type), _h2py(h_value)); +} + +HPyAPI_IMPL HPy ctx_Err_SetFromErrnoWithFilename(HPyContext *ctx, HPy h_type, const char *filename_fsencoded) +{ + return _py2h(PyErr_SetFromErrnoWithFilename(_h2py(h_type), filename_fsencoded)); +} + +HPyAPI_IMPL void ctx_Err_SetFromErrnoWithFilenameObjects(HPyContext *ctx, HPy h_type, HPy filename1, HPy filename2) +{ + PyErr_SetFromErrnoWithFilenameObjects(_h2py(h_type), _h2py(filename1), _h2py(filename2)); +} + +HPyAPI_IMPL int ctx_Err_ExceptionMatches(HPyContext *ctx, HPy exc) +{ + return PyErr_ExceptionMatches(_h2py(exc)); +} + +HPyAPI_IMPL void ctx_Err_NoMemory(HPyContext *ctx) +{ + PyErr_NoMemory(); +} + +HPyAPI_IMPL void ctx_Err_Clear(HPyContext *ctx) +{ + PyErr_Clear(); +} + +HPyAPI_IMPL HPy ctx_Err_NewException(HPyContext *ctx, const char *utf8_name, HPy base, HPy dict) +{ + return _py2h(PyErr_NewException(utf8_name, _h2py(base), _h2py(dict))); +} + +HPyAPI_IMPL HPy ctx_Err_NewExceptionWithDoc(HPyContext *ctx, const char *utf8_name, const char *utf8_doc, HPy base, HPy dict) +{ + return _py2h(PyErr_NewExceptionWithDoc(utf8_name, utf8_doc, _h2py(base), _h2py(dict))); +} + +HPyAPI_IMPL int ctx_Err_WarnEx(HPyContext *ctx, HPy category, const char *utf8_message, HPy_ssize_t stack_level) +{ + return PyErr_WarnEx(_h2py(category), utf8_message, stack_level); +} + +HPyAPI_IMPL void ctx_Err_WriteUnraisable(HPyContext *ctx, HPy obj) +{ + PyErr_WriteUnraisable(_h2py(obj)); +} + +HPyAPI_IMPL int ctx_IsTrue(HPyContext *ctx, HPy h) +{ + return PyObject_IsTrue(_h2py(h)); +} + +HPyAPI_IMPL HPy ctx_GetAttr(HPyContext *ctx, HPy obj, HPy name) +{ + return _py2h(PyObject_GetAttr(_h2py(obj), _h2py(name))); +} + +HPyAPI_IMPL HPy ctx_GetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name) +{ + return _py2h(PyObject_GetAttrString(_h2py(obj), utf8_name)); +} + +HPyAPI_IMPL int ctx_HasAttr(HPyContext *ctx, HPy obj, HPy name) +{ + return PyObject_HasAttr(_h2py(obj), _h2py(name)); +} + +HPyAPI_IMPL int ctx_HasAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name) +{ + return PyObject_HasAttrString(_h2py(obj), utf8_name); +} + +HPyAPI_IMPL int ctx_SetAttr(HPyContext *ctx, HPy obj, HPy name, HPy value) +{ + return PyObject_SetAttr(_h2py(obj), _h2py(name), _h2py(value)); +} + +HPyAPI_IMPL int ctx_SetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name, HPy value) +{ + return PyObject_SetAttrString(_h2py(obj), utf8_name, _h2py(value)); +} + +HPyAPI_IMPL HPy ctx_GetItem(HPyContext *ctx, HPy obj, HPy key) +{ + return _py2h(PyObject_GetItem(_h2py(obj), _h2py(key))); +} + +HPyAPI_IMPL HPy ctx_GetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) +{ + return _py2h(PySequence_GetSlice(_h2py(obj), start, end)); +} + +HPyAPI_IMPL int ctx_Contains(HPyContext *ctx, HPy container, HPy key) +{ + return PySequence_Contains(_h2py(container), _h2py(key)); +} + +HPyAPI_IMPL int ctx_SetItem(HPyContext *ctx, HPy obj, HPy key, HPy value) +{ + return PyObject_SetItem(_h2py(obj), _h2py(key), _h2py(value)); +} + +HPyAPI_IMPL int ctx_SetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end, HPy value) +{ + return PySequence_SetSlice(_h2py(obj), start, end, _h2py(value)); +} + +HPyAPI_IMPL int ctx_DelItem(HPyContext *ctx, HPy obj, HPy key) +{ + return PyObject_DelItem(_h2py(obj), _h2py(key)); +} + +HPyAPI_IMPL int ctx_DelSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) +{ + return PySequence_DelSlice(_h2py(obj), start, end); +} + +HPyAPI_IMPL HPy ctx_Repr(HPyContext *ctx, HPy obj) +{ + return _py2h(PyObject_Repr(_h2py(obj))); +} + +HPyAPI_IMPL HPy ctx_Str(HPyContext *ctx, HPy obj) +{ + return _py2h(PyObject_Str(_h2py(obj))); +} + +HPyAPI_IMPL HPy ctx_ASCII(HPyContext *ctx, HPy obj) +{ + return _py2h(PyObject_ASCII(_h2py(obj))); +} + +HPyAPI_IMPL HPy ctx_Bytes(HPyContext *ctx, HPy obj) +{ + return _py2h(PyObject_Bytes(_h2py(obj))); +} + +HPyAPI_IMPL HPy ctx_RichCompare(HPyContext *ctx, HPy v, HPy w, int op) +{ + return _py2h(PyObject_RichCompare(_h2py(v), _h2py(w), op)); +} + +HPyAPI_IMPL int ctx_RichCompareBool(HPyContext *ctx, HPy v, HPy w, int op) +{ + return PyObject_RichCompareBool(_h2py(v), _h2py(w), op); +} + +HPyAPI_IMPL HPy_hash_t ctx_Hash(HPyContext *ctx, HPy obj) +{ + return PyObject_Hash(_h2py(obj)); +} + +HPyAPI_IMPL int ctx_Bytes_Check(HPyContext *ctx, HPy h) +{ + return PyBytes_Check(_h2py(h)); +} + +HPyAPI_IMPL HPy_ssize_t ctx_Bytes_Size(HPyContext *ctx, HPy h) +{ + return PyBytes_Size(_h2py(h)); +} + +HPyAPI_IMPL HPy_ssize_t ctx_Bytes_GET_SIZE(HPyContext *ctx, HPy h) +{ + return PyBytes_GET_SIZE(_h2py(h)); +} + +HPyAPI_IMPL const char *ctx_Bytes_AsString(HPyContext *ctx, HPy h) +{ + return PyBytes_AsString(_h2py(h)); +} + +HPyAPI_IMPL const char *ctx_Bytes_AS_STRING(HPyContext *ctx, HPy h) +{ + return PyBytes_AS_STRING(_h2py(h)); +} + +HPyAPI_IMPL HPy ctx_Bytes_FromString(HPyContext *ctx, const char *bytes) +{ + return _py2h(PyBytes_FromString(bytes)); +} + +HPyAPI_IMPL HPy ctx_Unicode_FromString(HPyContext *ctx, const char *utf8) +{ + return _py2h(PyUnicode_FromString(utf8)); +} + +HPyAPI_IMPL int ctx_Unicode_Check(HPyContext *ctx, HPy h) +{ + return PyUnicode_Check(_h2py(h)); +} + +HPyAPI_IMPL HPy ctx_Unicode_AsASCIIString(HPyContext *ctx, HPy h) +{ + return _py2h(PyUnicode_AsASCIIString(_h2py(h))); +} + +HPyAPI_IMPL HPy ctx_Unicode_AsLatin1String(HPyContext *ctx, HPy h) +{ + return _py2h(PyUnicode_AsLatin1String(_h2py(h))); +} + +HPyAPI_IMPL HPy ctx_Unicode_AsUTF8String(HPyContext *ctx, HPy h) +{ + return _py2h(PyUnicode_AsUTF8String(_h2py(h))); +} + +HPyAPI_IMPL const char *ctx_Unicode_AsUTF8AndSize(HPyContext *ctx, HPy h, HPy_ssize_t *size) +{ + return PyUnicode_AsUTF8AndSize(_h2py(h), size); +} + +HPyAPI_IMPL HPy ctx_Unicode_FromWideChar(HPyContext *ctx, const wchar_t *w, HPy_ssize_t size) +{ + return _py2h(PyUnicode_FromWideChar(w, size)); +} + +HPyAPI_IMPL HPy ctx_Unicode_DecodeFSDefault(HPyContext *ctx, const char *v) +{ + return _py2h(PyUnicode_DecodeFSDefault(v)); +} + +HPyAPI_IMPL HPy ctx_Unicode_DecodeFSDefaultAndSize(HPyContext *ctx, const char *v, HPy_ssize_t size) +{ + return _py2h(PyUnicode_DecodeFSDefaultAndSize(v, size)); +} + +HPyAPI_IMPL HPy ctx_Unicode_EncodeFSDefault(HPyContext *ctx, HPy h) +{ + return _py2h(PyUnicode_EncodeFSDefault(_h2py(h))); +} + +HPyAPI_IMPL HPy_UCS4 ctx_Unicode_ReadChar(HPyContext *ctx, HPy h, HPy_ssize_t index) +{ + return PyUnicode_ReadChar(_h2py(h), index); +} + +HPyAPI_IMPL HPy ctx_Unicode_DecodeASCII(HPyContext *ctx, const char *ascii, HPy_ssize_t size, const char *errors) +{ + return _py2h(PyUnicode_DecodeASCII(ascii, size, errors)); +} + +HPyAPI_IMPL HPy ctx_Unicode_DecodeLatin1(HPyContext *ctx, const char *latin1, HPy_ssize_t size, const char *errors) +{ + return _py2h(PyUnicode_DecodeLatin1(latin1, size, errors)); +} + +HPyAPI_IMPL HPy ctx_Unicode_FromEncodedObject(HPyContext *ctx, HPy obj, const char *encoding, const char *errors) +{ + return _py2h(PyUnicode_FromEncodedObject(_h2py(obj), encoding, errors)); +} + +HPyAPI_IMPL HPy ctx_Unicode_Substring(HPyContext *ctx, HPy str, HPy_ssize_t start, HPy_ssize_t end) +{ + return _py2h(PyUnicode_Substring(_h2py(str), start, end)); +} + +HPyAPI_IMPL int ctx_List_Check(HPyContext *ctx, HPy h) +{ + return PyList_Check(_h2py(h)); +} + +HPyAPI_IMPL HPy ctx_List_New(HPyContext *ctx, HPy_ssize_t len) +{ + return _py2h(PyList_New(len)); +} + +HPyAPI_IMPL int ctx_List_Append(HPyContext *ctx, HPy h_list, HPy h_item) +{ + return PyList_Append(_h2py(h_list), _h2py(h_item)); +} + +HPyAPI_IMPL int ctx_List_Insert(HPyContext *ctx, HPy h_list, HPy_ssize_t index, HPy h_item) +{ + return PyList_Insert(_h2py(h_list), index, _h2py(h_item)); +} + +HPyAPI_IMPL int ctx_Dict_Check(HPyContext *ctx, HPy h) +{ + return PyDict_Check(_h2py(h)); +} + +HPyAPI_IMPL HPy ctx_Dict_New(HPyContext *ctx) +{ + return _py2h(PyDict_New()); +} + +HPyAPI_IMPL HPy ctx_Dict_Keys(HPyContext *ctx, HPy h) +{ + return _py2h(PyDict_Keys(_h2py(h))); +} + +HPyAPI_IMPL HPy ctx_Dict_Copy(HPyContext *ctx, HPy h) +{ + return _py2h(PyDict_Copy(_h2py(h))); +} + +HPyAPI_IMPL int ctx_Tuple_Check(HPyContext *ctx, HPy h) +{ + return PyTuple_Check(_h2py(h)); +} + +HPyAPI_IMPL HPy ctx_Slice_New(HPyContext *ctx, HPy start, HPy stop, HPy step) +{ + return _py2h(PySlice_New(_h2py(start), _h2py(stop), _h2py(step))); +} + +HPyAPI_IMPL int ctx_Slice_Unpack(HPyContext *ctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step) +{ + return PySlice_Unpack(_h2py(slice), start, stop, step); +} + +HPyAPI_IMPL HPy ctx_Import_ImportModule(HPyContext *ctx, const char *utf8_name) +{ + return _py2h(PyImport_ImportModule(utf8_name)); +} + +HPyAPI_IMPL int ctx_Capsule_IsValid(HPyContext *ctx, HPy capsule, const char *utf8_name) +{ + return PyCapsule_IsValid(_h2py(capsule), utf8_name); +} + +HPyAPI_IMPL void ctx_ReenterPythonExecution(HPyContext *ctx, HPyThreadState state) +{ + PyEval_RestoreThread(_h2threads(state)); +} + +HPyAPI_IMPL HPyThreadState ctx_LeavePythonExecution(HPyContext *ctx) +{ + return _threads2h(PyEval_SaveThread()); +} + +HPyAPI_IMPL HPy ctx_EvalCode(HPyContext *ctx, HPy code, HPy globals, HPy locals) +{ + return _py2h(PyEval_EvalCode(_h2py(code), _h2py(globals), _h2py(locals))); +} + +HPyAPI_IMPL HPy ctx_ContextVar_New(HPyContext *ctx, const char *name, HPy default_value) +{ + return _py2h(PyContextVar_New(name, _h2py(default_value))); +} + +HPyAPI_IMPL HPy ctx_ContextVar_Set(HPyContext *ctx, HPy context_var, HPy value) +{ + return _py2h(PyContextVar_Set(_h2py(context_var), _h2py(value))); +} + diff --git a/graalpython/hpy/hpy/universal/src/ctx.c b/graalpython/hpy/hpy/universal/src/ctx.c new file mode 100644 index 0000000000..4e9860233b --- /dev/null +++ b/graalpython/hpy/hpy/universal/src/ctx.c @@ -0,0 +1,10 @@ +#include "hpy.h" +#include "handles.h" + +#include "hpy/runtime/ctx_funcs.h" +#include "hpy/runtime/ctx_type.h" +#include "ctx_meth.h" +#include "ctx_misc.h" + +#include "autogen_ctx_impl.h" +#include "autogen_ctx_def.h" diff --git a/graalpython/hpy/hpy/universal/src/ctx_meth.c b/graalpython/hpy/hpy/universal/src/ctx_meth.c new file mode 100644 index 0000000000..923f81e23f --- /dev/null +++ b/graalpython/hpy/hpy/universal/src/ctx_meth.c @@ -0,0 +1,136 @@ +#include +#include "ctx_meth.h" +#include "hpy/runtime/ctx_type.h" +#include "hpy/runtime/ctx_module.h" +#include "handles.h" + +static void _buffer_h2py(HPyContext *ctx, const HPy_buffer *src, Py_buffer *dest) +{ + dest->buf = src->buf; + dest->obj = HPy_AsPyObject(ctx, src->obj); + dest->len = src->len; + dest->itemsize = src->itemsize; + dest->readonly = src->readonly; + dest->ndim = src->ndim; + dest->format = src->format; + dest->shape = src->shape; + dest->strides = src->strides; + dest->suboffsets = src->suboffsets; + dest->internal = src->internal; +} + +static void _buffer_py2h(HPyContext *ctx, const Py_buffer *src, HPy_buffer *dest) +{ + dest->buf = src->buf; + dest->obj = HPy_FromPyObject(ctx, src->obj); + dest->len = src->len; + dest->itemsize = src->itemsize; + dest->readonly = src->readonly; + dest->ndim = src->ndim; + dest->format = src->format; + dest->shape = src->shape; + dest->strides = src->strides; + dest->suboffsets = src->suboffsets; + dest->internal = src->internal; +} + +HPyAPI_IMPL void +ctx_CallRealFunctionFromTrampoline(HPyContext *ctx, HPyFunc_Signature sig, + HPyCFunction func, void *args) +{ + switch (sig) { + case HPyFunc_VARARGS: { + HPyFunc_varargs f = (HPyFunc_varargs)func; + _HPyFunc_args_VARARGS *a = (_HPyFunc_args_VARARGS*)args; + HPy *h_args = (HPy *)alloca(a->nargs * sizeof(HPy)); + for (HPy_ssize_t i = 0; i < a->nargs; i++) { + h_args[i] = _py2h(a->args[i]); + } + a->result = _h2py(f(ctx, _py2h(a->self), h_args, a->nargs)); + return; + } + case HPyFunc_KEYWORDS: { + HPyFunc_keywords f = (HPyFunc_keywords)func; + _HPyFunc_args_KEYWORDS *a = (_HPyFunc_args_KEYWORDS*)args; + size_t n_kwnames = a->kwnames != NULL ? PyTuple_GET_SIZE(a->kwnames) : 0; + size_t nargs = PyVectorcall_NARGS(a->nargsf); + size_t nargs_with_kw = nargs + n_kwnames; + HPy *h_args = (HPy *)alloca(nargs_with_kw * sizeof(HPy)); + for (size_t i = 0; i < nargs_with_kw; i++) { + h_args[i] = _py2h(a->args[i]); + } + a->result = _h2py(f(ctx, _py2h(a->self), h_args, nargs, _py2h(a->kwnames))); + return; + } + case HPyFunc_INITPROC: { + HPyFunc_initproc f = (HPyFunc_initproc)func; + _HPyFunc_args_INITPROC *a = (_HPyFunc_args_INITPROC*)args; + Py_ssize_t nargs = PyTuple_GET_SIZE(a->args); + HPy *h_args = (HPy *)alloca(nargs * sizeof(HPy)); + for (Py_ssize_t i = 0; i < nargs; i++) { + h_args[i] = _py2h(PyTuple_GET_ITEM(a->args, i)); + } + a->result = f(ctx, _py2h(a->self), h_args, nargs, _py2h(a->kw)); + return; + } + case HPyFunc_NEWFUNC: { + HPyFunc_newfunc f = (HPyFunc_newfunc)func; + _HPyFunc_args_NEWFUNC *a = (_HPyFunc_args_NEWFUNC*)args; + Py_ssize_t nargs = PyTuple_GET_SIZE(a->args); + HPy *h_args = (HPy *)alloca(nargs * sizeof(HPy)); + for (Py_ssize_t i = 0; i < nargs; i++) { + h_args[i] = _py2h(PyTuple_GET_ITEM(a->args, i)); + } + a->result = _h2py(f(ctx, _py2h(a->self), h_args, nargs, _py2h(a->kw))); + return; + } + case HPyFunc_GETBUFFERPROC: { + HPyFunc_getbufferproc f = (HPyFunc_getbufferproc)func; + _HPyFunc_args_GETBUFFERPROC *a = (_HPyFunc_args_GETBUFFERPROC*)args; + HPy_buffer hbuf; + a->result = f(ctx, _py2h(a->self), &hbuf, a->flags); + if (a->result < 0) { + a->view->obj = NULL; + return; + } + _buffer_h2py(ctx, &hbuf, a->view); + HPy_Close(ctx, hbuf.obj); + return; + } + case HPyFunc_RELEASEBUFFERPROC: { + HPyFunc_releasebufferproc f = (HPyFunc_releasebufferproc)func; + _HPyFunc_args_RELEASEBUFFERPROC *a = (_HPyFunc_args_RELEASEBUFFERPROC*)args; + HPy_buffer hbuf; + _buffer_py2h(ctx, a->view, &hbuf); + f(ctx, _py2h(a->self), &hbuf); + // XXX: copy back from hbuf? + HPy_Close(ctx, hbuf.obj); + return; + } + case HPyFunc_TRAVERSEPROC: { + HPyFunc_traverseproc f = (HPyFunc_traverseproc)func; + _HPyFunc_args_TRAVERSEPROC *a = (_HPyFunc_args_TRAVERSEPROC*)args; + a->result = call_traverseproc_from_trampoline(f, a->self, + a->visit, a->arg); + return; + } + case HPyFunc_CAPSULE_DESTRUCTOR: { + HPyFunc_Capsule_Destructor f = (HPyFunc_Capsule_Destructor)func; + PyObject *capsule = (PyObject *)args; + const char *name = PyCapsule_GetName(capsule); + f(name, PyCapsule_GetPointer(capsule, name), + PyCapsule_GetContext(capsule)); + return; + } + case HPyFunc_MOD_CREATE: { + HPyFunc_unaryfunc f = (HPyFunc_unaryfunc)func; + _HPyFunc_args_UNARYFUNC *a = (_HPyFunc_args_UNARYFUNC*)args; + a->result = _h2py(f(ctx, _py2h(a->arg0))); + _HPyModule_CheckCreateSlotResult(&a->result); + return; + } +#include "autogen_ctx_call.i" + default: + Py_FatalError("Unsupported HPyFunc_Signature in ctx_meth.c"); + } +} diff --git a/graalpython/hpy/hpy/universal/src/ctx_meth.h b/graalpython/hpy/hpy/universal/src/ctx_meth.h new file mode 100644 index 0000000000..16e8a4b47c --- /dev/null +++ b/graalpython/hpy/hpy/universal/src/ctx_meth.h @@ -0,0 +1,6 @@ +#include "hpy.h" +#include "api.h" + +HPyAPI_IMPL void +ctx_CallRealFunctionFromTrampoline(HPyContext *ctx, HPyFunc_Signature sig, + HPyCFunction func, void *args); diff --git a/graalpython/hpy/hpy/universal/src/ctx_misc.c b/graalpython/hpy/hpy/universal/src/ctx_misc.c new file mode 100644 index 0000000000..753354d43c --- /dev/null +++ b/graalpython/hpy/hpy/universal/src/ctx_misc.c @@ -0,0 +1,83 @@ +#include +#include "hpy.h" +#include "handles.h" +#include "ctx_misc.h" + +HPyAPI_IMPL HPy +ctx_FromPyObject(HPyContext *ctx, cpy_PyObject *obj) +{ + Py_XINCREF(obj); + return _py2h(obj); +} + +HPyAPI_IMPL cpy_PyObject * +ctx_AsPyObject(HPyContext *ctx, HPy h) +{ + PyObject *obj = _h2py(h); + Py_XINCREF(obj); + return obj; +} + +HPyAPI_IMPL void +ctx_Close(HPyContext *ctx, HPy h) +{ + PyObject *obj = _h2py(h); + Py_XDECREF(obj); +} + +HPyAPI_IMPL HPy +ctx_Dup(HPyContext *ctx, HPy h) +{ + PyObject *obj = _h2py(h); + Py_XINCREF(obj); + return _py2h(obj); +} + +HPyAPI_IMPL void +ctx_Field_Store(HPyContext *ctx, HPy target_object, HPyField *target_field, HPy h) +{ + PyObject *obj = _h2py(h); + PyObject *target_py_obj = _hf2py(*target_field); + Py_XINCREF(obj); + *target_field = _py2hf(obj); + Py_XDECREF(target_py_obj); +} + +HPyAPI_IMPL HPy +ctx_Field_Load(HPyContext *ctx, HPy source_object, HPyField source_field) +{ + PyObject *obj = _hf2py(source_field); + Py_INCREF(obj); + return _py2h(obj); +} + + +HPyAPI_IMPL void +ctx_Global_Store(HPyContext *ctx, HPyGlobal *global, HPy h) +{ + PyObject *obj = _h2py(h); + Py_XDECREF(_hg2py(*global)); + Py_XINCREF(obj); + *global = _py2hg(obj); +} + +HPyAPI_IMPL HPy +ctx_Global_Load(HPyContext *ctx, HPyGlobal global) +{ + PyObject *obj = _hg2py(global); + Py_INCREF(obj); + return _py2h(obj); +} + +HPyAPI_IMPL void +ctx_FatalError(HPyContext *ctx, const char *message) +{ + Py_FatalError(message); +} + +HPyAPI_IMPL int +ctx_Type_IsSubtype(HPyContext *ctx, HPy sub, HPy type) +{ + return PyType_IsSubtype((PyTypeObject *)_h2py(sub), + (PyTypeObject *)_h2py(type)); +} diff --git a/graalpython/hpy/hpy/universal/src/ctx_misc.h b/graalpython/hpy/hpy/universal/src/ctx_misc.h new file mode 100644 index 0000000000..deb27ec5e5 --- /dev/null +++ b/graalpython/hpy/hpy/universal/src/ctx_misc.h @@ -0,0 +1,20 @@ +#ifndef HPY_CTX_MISC_H +#define HPY_CTX_MISC_H + +#include "hpy.h" +#include "api.h" + +HPyAPI_IMPL HPy ctx_FromPyObject(HPyContext *ctx, cpy_PyObject *obj); +HPyAPI_IMPL cpy_PyObject *ctx_AsPyObject(HPyContext *ctx, HPy h); +HPyAPI_IMPL void ctx_Close(HPyContext *ctx, HPy h); +HPyAPI_IMPL HPy ctx_Dup(HPyContext *ctx, HPy h); +HPyAPI_IMPL void ctx_Field_Store(HPyContext *ctx, HPy target_object, + HPyField *target_field, HPy h); +HPyAPI_IMPL HPy ctx_Field_Load(HPyContext *ctx, HPy source_object, + HPyField source_field); +HPyAPI_IMPL void ctx_Global_Store(HPyContext *ctx, HPyGlobal *global, HPy h); +HPyAPI_IMPL HPy ctx_Global_Load(HPyContext *ctx, HPyGlobal global); +HPyAPI_IMPL void ctx_FatalError(HPyContext *ctx, const char *message); +HPyAPI_IMPL int ctx_Type_IsSubtype(HPyContext *ctx, HPy sub, HPy type); + +#endif /* HPY_CTX_MISC_H */ diff --git a/graalpython/hpy/hpy/universal/src/handles.h b/graalpython/hpy/hpy/universal/src/handles.h new file mode 100644 index 0000000000..3d0282d786 --- /dev/null +++ b/graalpython/hpy/hpy/universal/src/handles.h @@ -0,0 +1,58 @@ +#ifndef HPY_HANDLES_H +#define HPY_HANDLES_H + +#include +#include "hpy.h" + +// The main reason for +1/-1 is to make sure that if people casts HPy to +// PyObject* directly, things explode. Moreover, with this we can easily +// distinguish normal and debug handles in gdb, by only looking at the last +// bit. + +static inline HPy _py2h(PyObject *obj) { + if (obj == NULL) + return HPy_NULL; + return (HPy){(HPy_ssize_t)obj + 1}; +} + +static inline PyObject *_h2py(HPy h) { + if HPy_IsNull(h) + return NULL; + return (PyObject *)(h._i - 1); +} + +static inline HPyField _py2hf(PyObject *obj) +{ + HPy h = _py2h(obj); + return (HPyField){ ._i = h._i }; +} + +static inline PyObject * _hf2py(HPyField hf) +{ + HPy h = { ._i = hf._i }; + return _h2py(h); +} + +static inline HPyThreadState _threads2h(PyThreadState* s) +{ + return (HPyThreadState) { (intptr_t) s }; +} + +static inline PyThreadState* _h2threads(HPyThreadState h) +{ + return (PyThreadState*) h._i; +} + +static inline HPyGlobal _py2hg(PyObject *obj) +{ + HPy h = _py2h(obj); + return (HPyGlobal){ ._i = h._i }; +} + +static inline PyObject * _hg2py(HPyGlobal hf) +{ + HPy h = { ._i = hf._i }; + return _h2py(h); +} + +#endif /* HPY_HANDLES_H */ diff --git a/graalpython/hpy/hpy/universal/src/hpymodule.c b/graalpython/hpy/hpy/universal/src/hpymodule.c new file mode 100644 index 0000000000..6ae8b54859 --- /dev/null +++ b/graalpython/hpy/hpy/universal/src/hpymodule.c @@ -0,0 +1,688 @@ +#define PY_SSIZE_T_CLEAN +#include +#ifdef MS_WIN32 +# include +# include "misc_win32.h" +#else +# include +// required for strncasecmp +#include +#endif +#include +#include + + +#include "api.h" +#include "handles.h" +#include "hpy/version.h" +#include "hpy_debug.h" +#include "hpy_trace.h" +#include "hpy/runtime/ctx_module.h" + +#ifdef PYPY_VERSION +# error "Cannot build hpy.universal on top of PyPy. PyPy comes with its own version of it" +#endif + +static const char *hpy_mode_names[] = { + "MODE_UNIVERSAL", + "MODE_DEBUG", + "MODE_TRACE", + // "MODE_DEBUG_TRACE", + // "MODE_TRACE_DEBUG", + NULL +}; + +typedef enum { + MODE_INVALID = -1, + MODE_UNIVERSAL = 0, + MODE_DEBUG = 1, + MODE_TRACE = 2, + /* We do currently not test the combinations of debug and trace mode, so we + do not offer them right now. This may change in future. */ + // MODE_DEBUG_TRACE = 3, + // MODE_TRACE_DEBUG = 4 +} HPyMode; + +typedef uint32_t (*VersionGetterFuncPtr)(void); +typedef HPyModuleDef* (*InitFuncPtr)(void); +typedef void (*InitContextFuncPtr)(HPyContext*); + +static const char *init_prefix = "HPyInit"; +static const char *init_ctx_prefix = "HPyInitGlobalContext_"; + +static inline int +_hpy_strncmp_ignore_case(const char *s0, const char *s1, size_t n) +{ +#ifdef MS_WIN32 + return _strnicmp(s0, s1, n); +#else + return strncasecmp(s0, s1, n); +#endif +} + +static HPyContext * get_context(HPyMode mode) +{ + switch (mode) + { + case MODE_INVALID: + return NULL; + case MODE_DEBUG: + return hpy_debug_get_ctx(&g_universal_ctx); + case MODE_TRACE: + return hpy_trace_get_ctx(&g_universal_ctx); + // case MODE_DEBUG_TRACE: + // return hpy_debug_get_ctx(hpy_trace_get_ctx(&g_universal_ctx)); + // case MODE_TRACE_DEBUG: + // return hpy_trace_get_ctx(hpy_debug_get_ctx(&g_universal_ctx)); + default: + return &g_universal_ctx; + } +} + +static PyObject * +get_encoded_name(PyObject *name) { + PyObject *tmp; + PyObject *encoded = NULL; + PyObject *modname = NULL; + Py_ssize_t name_len, lastdot; + + /* Get the short name (substring after last dot) */ + name_len = PyUnicode_GetLength(name); + lastdot = PyUnicode_FindChar(name, '.', 0, name_len, -1); + if (lastdot < -1) { + return NULL; + } else if (lastdot >= 0) { + tmp = PyUnicode_Substring(name, lastdot + 1, name_len); + if (tmp == NULL) + return NULL; + name = tmp; + /* "name" now holds a new reference to the substring */ + } else { + Py_INCREF(name); + } + + /* Encode to ASCII */ + encoded = PyUnicode_AsEncodedString(name, "ascii", NULL); + if (encoded != NULL) { + } else { + goto error; + } + + /* Replace '-' by '_' */ + modname = PyObject_CallMethod(encoded, "replace", "cc", '-', '_'); + if (modname == NULL) + goto error; + + Py_DECREF(name); + Py_DECREF(encoded); + return modname; +error: + Py_DECREF(name); + Py_XDECREF(encoded); + return NULL; +} + +static bool validate_abi_tag(const char *shortname, const char *soname, + uint32_t required_major_version, uint32_t required_minor_version) { + char *substr = strstr(soname, ".hpy"); + if (substr != NULL) { + substr += strlen(".hpy"); + if (*substr >= '0' && *substr <= '9') { + // It is a number w/o sign and whitespace, we can now parse it with atoi + uint32_t abi_tag = (uint32_t) atoi(substr); + if (abi_tag == required_major_version) { + return true; + } + PyErr_Format(PyExc_RuntimeError, + "HPy extension module '%s' at path '%s': mismatch between the " + "HPy ABI tag encoded in the filename and the major version requested " + "by the HPy extension itself. Major version tag parsed from " + "filename: %" PRIu32 ". Requested version: %" PRIu32 ".%" PRIu32 ".", + shortname, soname, abi_tag, required_major_version, required_minor_version); + return false; + } + } + PyErr_Format(PyExc_RuntimeError, + "HPy extension module '%s' at path '%s': could not find " + "HPy ABI tag encoded in the filename. The extension claims to be compiled with " + "HPy ABI version: %" PRIu32 ".%" PRIu32 ".", + shortname, soname, required_major_version, required_minor_version); + return false; +} + +static void dlsym_error(const char *soname, const char *symbol_name) { + const char *error = dlerror(); + if (error == NULL) + error = "no error message provided by the system"; + PyErr_Format(PyExc_RuntimeError, + "Error during loading of the HPy extension module at " + "path '%s' while trying to find symbol '%s'. Did you use" + "the HPy_MODINIT macro to register your module? Error " + "message from dlsym/WinAPI: %s", soname, symbol_name, error); +} + +static PyObject *do_load(PyObject *name_unicode, PyObject *path, HPyMode mode, PyObject *spec) +{ + PyObject *name = NULL; + PyObject *pathbytes = NULL; + PyModuleDef *pydef = NULL; + PyObject *py_mod = NULL; + + name = get_encoded_name(name_unicode); + if (name == NULL) { + goto error; + } + + pathbytes = PyUnicode_EncodeFSDefault(path); + if (pathbytes == NULL) + goto error; + const char *soname = PyBytes_AS_STRING(pathbytes); + + void *mylib = dlopen(soname, RTLD_NOW); // who closes this? + if (mylib == NULL) { + const char *error = dlerror(); + if (error == NULL) + error = "no error message provided by the system"; + PyErr_Format(PyExc_RuntimeError, + "Error during loading of the HPy extension module at path " + "'%s'. Error message from dlopen/WinAPI: %s", soname, error); + goto error; + } + + const char *shortname = PyBytes_AS_STRING(name); + char minor_version_symbol_name[258]; + char major_version_symbol_name[258]; + PyOS_snprintf(minor_version_symbol_name, sizeof(minor_version_symbol_name), + "get_required_hpy_minor_version_%.200s", shortname); + PyOS_snprintf(major_version_symbol_name, sizeof(major_version_symbol_name), + "get_required_hpy_major_version_%.200s", shortname); + void *minor_version_ptr = dlsym(mylib, minor_version_symbol_name); + void *major_version_ptr = dlsym(mylib, major_version_symbol_name); + if (minor_version_ptr == NULL || major_version_ptr == NULL) { + const char *error = dlerror(); + if (error == NULL) + error = "no error message provided by the system"; + PyErr_Format(PyExc_RuntimeError, + "Error during loading of the HPy extension module at path " + "'%s'. Cannot locate the required minimal HPy versions as symbols '%s' and `%s`. " + "Error message from dlopen/WinAPI: %s", + soname, minor_version_symbol_name, major_version_symbol_name, error); + goto error; + } + uint32_t required_minor_version = ((VersionGetterFuncPtr) minor_version_ptr)(); + uint32_t required_major_version = ((VersionGetterFuncPtr) major_version_ptr)(); + if (required_major_version != HPY_ABI_VERSION || required_minor_version > HPY_ABI_VERSION_MINOR) { + // For now, we have only one major version, but in the future at this + // point we would decide which HPyContext to create + PyErr_Format(PyExc_RuntimeError, + "HPy extension module '%s' requires unsupported version of the HPy runtime. " + "Requested version: %" PRIu32 ".%" PRIu32 ". Current HPy version: %" PRIu32 ".%" PRIu32 ".", + shortname, required_major_version, required_minor_version, + HPY_ABI_VERSION, HPY_ABI_VERSION_MINOR); + goto error; + } + + // Sanity check of the tag in the shared object filename + if (!validate_abi_tag(shortname, soname, required_major_version, required_minor_version)) { + goto error; + } + + HPyContext *ctx = get_context(mode); + if (ctx == NULL) + goto error; + + char init_ctx_name[258]; + PyOS_snprintf(init_ctx_name, sizeof(init_ctx_name), "%.20s_%.200s", + init_ctx_prefix, shortname); + void *initctxfn = dlsym(mylib, init_ctx_name); + if (initctxfn == NULL) { + dlsym_error(soname, init_ctx_name); + goto error; + } + ((InitContextFuncPtr)initctxfn)(ctx); + + char init_name[258]; + PyOS_snprintf(init_name, sizeof(init_name), "%.20s_%.200s", + init_prefix, shortname); + void *initfn = dlsym(mylib, init_name); + if (initfn == NULL) { + dlsym_error(soname, init_name); + goto error; + } + + HPyModuleDef* hpydef = ((InitFuncPtr)initfn)(); + if (hpydef == NULL) { + PyErr_Format(PyExc_RuntimeError, + "Error during loading of the HPy extension module at " + "path '%s'. Function '%s' returned NULL.", soname, init_name); + goto error; + } + + pydef = _HPyModuleDef_CreatePyModuleDef(hpydef); + if (pydef == NULL) { + goto error; + } + + py_mod = PyModule_FromDefAndSpec(pydef, spec); + if (py_mod == NULL) + goto error; + + if (PyModule_Check(py_mod)) { + if (PyModule_ExecDef(py_mod, pydef) != 0) + goto error; + } + + Py_XDECREF(name); + Py_XDECREF(pathbytes); + return py_mod; +error: + Py_XDECREF(py_mod); + if (pydef != NULL) + PyMem_Free(pydef); + Py_XDECREF(name); + Py_XDECREF(pathbytes); + return NULL; +} + +static PyObject *load(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = {"name", "path", "spec", "debug", "mode", NULL}; + PyObject *name_unicode; + PyObject *path; + PyObject *spec; + int debug = 0; + int mode = -1; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOO|pi", kwlist, + &name_unicode, &path, &spec, &debug, &mode)) { + return NULL; + } + HPyMode hmode = debug ? MODE_DEBUG : MODE_UNIVERSAL; + // 'mode' just overwrites 'debug' + if (mode > 0) + { + hmode = (HPyMode) mode; + } + return do_load(name_unicode, path, hmode, spec); +} + +static HPyMode get_mode_from_string(const char *s, Py_ssize_t n) +{ + if (_hpy_strncmp_ignore_case("debug", s, n) == 0) + return MODE_DEBUG; + if (_hpy_strncmp_ignore_case("trace", s, n) == 0) + return MODE_TRACE; + // if (_hpy_strncmp_ignore_case("debug+trace", s, n) == 0) + // return MODE_DEBUG_TRACE; + // if (_hpy_strncmp_ignore_case("trace+debug", s, n) == 0) + // return MODE_TRACE_DEBUG; + if (_hpy_strncmp_ignore_case("universal", s, n) == 0) + return MODE_UNIVERSAL; + return MODE_INVALID; +} + +/* + * A little helper that does a fast-path if 'mapping' is a dict. + */ +static int mapping_get_item(PyObject *mapping, const char *skey, PyObject **value) +{ + PyObject *key = PyUnicode_FromString(skey); + if (key == NULL) + return 1; + + // fast-path if 'mapping' is a dict + if (PyDict_Check(mapping)) { + *value = PyDict_GetItem(mapping, key); + Py_DECREF(key); + /* 'NULL' means, the key is not present in the dict, so just return + 'NULL'. Since PyDict_GetItem does not set an error, we don't need to + clear any error. */ + } else { + *value = PyObject_GetItem(mapping, key); + Py_DECREF(key); + if (*value == NULL) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_Clear(); + } else { + return 1; + } + } + } + return 0; +} + +/* + * HPY_MODE := MODE | (MODULE_NAME ':' MODE { ',' MODULE_NAME ':' MODE }) + * MODULE_NAME := IDENTIFIER + * MODE := 'debug' | 'trace' | 'universal' + */ +static HPyMode get_hpy_mode_from_environ(const char *s_name, PyObject *env) +{ + PyObject *value; + Py_ssize_t size; + HPyMode res; + const char *s_value; + + if (mapping_get_item(env, "HPY", &value)) { + return MODE_INVALID; + } + + /* 'value == NULL' is not an error; this just means that the key was not + present in 'env'. */ + if (value == NULL) { + return MODE_UNIVERSAL; + } + + s_value = PyUnicode_AsUTF8AndSize(value, &size); + if (s_value == NULL) { + Py_DECREF(value); + return MODE_INVALID; + } + res = MODE_INVALID; + char *colon = strchr(s_value, ':'); + if (colon) { + // case 2: modes are specified per module + char *name_start = (char *)s_value; + char *comma; + size_t mode_len; + while (colon) { + comma = strchr(colon + 1, ','); + if (comma) { + mode_len = comma - colon - 1; + } else { + mode_len = (s_value + size) - colon - 1; + } + if (strncmp(s_name, name_start, colon - name_start) == 0) { + res = get_mode_from_string(colon + 1, mode_len); + break; + } + if (comma) { + name_start = comma + 1; + colon = strchr(name_start, ':'); + } else { + colon = NULL; + } + } + } else { + // case 1: mode was globally specified + res = get_mode_from_string(s_value, size); + } + + if (res == MODE_INVALID) + PyErr_Format(PyExc_ValueError, "invalid HPy mode: %.50s", s_value); + Py_DECREF(value); + return res; +} + +static PyObject * +load_bootstrap(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = {"name", "ext_name", "package", "file", "loader", "spec", + "env", NULL}; + PyObject *module_name, *name, *package, *file, *loader, *spec, *env; + PyObject *log_obj, *m; + HPyMode hmode; + const char *s_module_name, *log_msg; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOOOOOO", kwlist, + &module_name, &name, &package, &file, + &loader, &spec, &env)) { + return NULL; + } + + s_module_name = PyUnicode_AsUTF8AndSize(module_name, NULL); + if (s_module_name == NULL) { + return NULL; + } + + hmode = get_hpy_mode_from_environ(s_module_name, env); + if (hmode == MODE_INVALID) + return NULL; + + if (mapping_get_item(env, "HPY_LOG", &log_obj)) + return NULL; + + if (log_obj != NULL) { + Py_DECREF(log_obj); + switch (hmode) { + case MODE_DEBUG: + log_msg = " with a debug context"; + break; + case MODE_TRACE: + log_msg = " with a trace context"; + break; + case MODE_UNIVERSAL: + log_msg = ""; + break; + default: + // that's not possible but required for the compiler + return NULL; + } + PySys_FormatStdout("Loading '%.200s' in HPy universal mode%.200s\n", + s_module_name, log_msg); + } + + m = do_load(module_name, file, hmode, spec); + if (m == NULL) + return NULL; + + PyObject_SetAttrString(m, "__file__", file); + PyObject_SetAttrString(m, "__loader__", loader); + PyObject_SetAttrString(m, "__name__", name); + PyObject_SetAttrString(m, "__package__", package); + PyObject_SetAttrString(spec, "origin", file); + PyObject_SetAttrString(m, "__spec__", spec); + + return m; +} + +static PyObject *get_version(PyObject *self, PyObject *ignored) +{ + return Py_BuildValue("ss", HPY_VERSION, HPY_GIT_REVISION); +} + +PyDoc_STRVAR(load_bootstrap_doc, "Internal function intended to be used by " + "the stub loader. This function will honor env var 'HPY' and correctly" + " set the attributes of the module."); + +static PyMethodDef HPyMethods[] = { + {"load", (PyCFunction)load, METH_VARARGS | METH_KEYWORDS, + ("Load a ." HPY_ABI_TAG ".so file")}, + {"_load_bootstrap", (PyCFunction)load_bootstrap, + METH_VARARGS | METH_KEYWORDS, load_bootstrap_doc}, + {"get_version", (PyCFunction)get_version, METH_NOARGS, + "Return a tuple ('version', 'git revision')"}, + {NULL, NULL, 0, NULL} +}; + + +static int exec_module(PyObject *mod); +static PyModuleDef_Slot hpymodule_slots[] = { + {Py_mod_exec, exec_module}, + {0, NULL}, +}; + +static struct PyModuleDef hpy_pydef = { + PyModuleDef_HEAD_INIT, + .m_name = "hpy.universal", + .m_doc = "HPy universal runtime for CPython", + .m_size = 0, + .m_methods = HPyMethods, + .m_slots = hpymodule_slots, +}; + +static int initialize_module(HPyContext *ctx, PyObject *hpy_universal, const char* name, + const char *full_name, HPyModuleDef *hpydef, + PyObject* spec_from_file_and_location, PyObject *location) +{ + PyObject *spec = NULL, *new_mod = NULL; + int result = -1; + + spec = PyObject_CallFunction(spec_from_file_and_location, "sO", full_name, location); + PyModuleDef *pydef = _HPyModuleDef_CreatePyModuleDef(hpydef); + new_mod = PyModule_FromDefAndSpec(pydef, spec); + if (new_mod == NULL) + goto cleanup; + + if (PyModule_ExecDef(new_mod, pydef) != 0) + goto cleanup; + + Py_INCREF(new_mod); // PyModule_AddObject steals the reference + if (PyModule_AddObject(hpy_universal, name, new_mod) < 0) + goto cleanup; + + result = 0; + +cleanup: + Py_XDECREF(new_mod); + Py_XDECREF(spec); + return result; +} + +// module initialization function +int exec_module(PyObject* mod) { + HPyContext *ctx = &g_universal_ctx; + + PyObject *importlib_util = PyImport_ImportModule("importlib.util"); + if (importlib_util == NULL) + return -1; + + PyObject *spec_from_file_and_location = PyObject_GetAttrString(importlib_util, "spec_from_file_location"); + Py_DecRef(importlib_util); + if (spec_from_file_and_location == NULL) + return -1; + + PyObject *current_mod_spec = PyObject_GetAttrString(mod, "__spec__"); + if (current_mod_spec == NULL) + return -1; + + PyObject *location = PyObject_GetAttrString(current_mod_spec, "origin"); + if (location == NULL) + return -1; + + HPyInitGlobalContext__debug(ctx); + int result = initialize_module(ctx, mod, "_debug", "hpy.debug._debug", + HPyInit__debug(), spec_from_file_and_location, location); + if (result != 0) + return result; + + HPyInitGlobalContext__trace(ctx); + result = initialize_module(ctx, mod, "_trace", "hpy.trace._trace", + HPyInit__trace(), spec_from_file_and_location, location); + if (result != 0) + return result; + + for (int i=0; hpy_mode_names[i]; i++) + { + if (PyModule_AddIntConstant(mod, hpy_mode_names[i], i) < 0) + return -1; + } + + return 0; +} + +static void init_universal_ctx(HPyContext *ctx) +{ + if (!HPy_IsNull(ctx->h_None)) + // already initialized + return; + + // XXX this code is basically the same as found in cpython/hpy.h. We + // should probably share and/or autogenerate both versions + /* Constants */ + ctx->h_None = _py2h(Py_None); + ctx->h_True = _py2h(Py_True); + ctx->h_False = _py2h(Py_False); + ctx->h_NotImplemented = _py2h(Py_NotImplemented); + ctx->h_Ellipsis = _py2h(Py_Ellipsis); + /* Exceptions */ + ctx->h_BaseException = _py2h(PyExc_BaseException); + ctx->h_Exception = _py2h(PyExc_Exception); + ctx->h_StopAsyncIteration = _py2h(PyExc_StopAsyncIteration); + ctx->h_StopIteration = _py2h(PyExc_StopIteration); + ctx->h_GeneratorExit = _py2h(PyExc_GeneratorExit); + ctx->h_ArithmeticError = _py2h(PyExc_ArithmeticError); + ctx->h_LookupError = _py2h(PyExc_LookupError); + ctx->h_AssertionError = _py2h(PyExc_AssertionError); + ctx->h_AttributeError = _py2h(PyExc_AttributeError); + ctx->h_BufferError = _py2h(PyExc_BufferError); + ctx->h_EOFError = _py2h(PyExc_EOFError); + ctx->h_FloatingPointError = _py2h(PyExc_FloatingPointError); + ctx->h_OSError = _py2h(PyExc_OSError); + ctx->h_ImportError = _py2h(PyExc_ImportError); + ctx->h_ModuleNotFoundError = _py2h(PyExc_ModuleNotFoundError); + ctx->h_IndexError = _py2h(PyExc_IndexError); + ctx->h_KeyError = _py2h(PyExc_KeyError); + ctx->h_KeyboardInterrupt = _py2h(PyExc_KeyboardInterrupt); + ctx->h_MemoryError = _py2h(PyExc_MemoryError); + ctx->h_NameError = _py2h(PyExc_NameError); + ctx->h_OverflowError = _py2h(PyExc_OverflowError); + ctx->h_RuntimeError = _py2h(PyExc_RuntimeError); + ctx->h_RecursionError = _py2h(PyExc_RecursionError); + ctx->h_NotImplementedError = _py2h(PyExc_NotImplementedError); + ctx->h_SyntaxError = _py2h(PyExc_SyntaxError); + ctx->h_IndentationError = _py2h(PyExc_IndentationError); + ctx->h_TabError = _py2h(PyExc_TabError); + ctx->h_ReferenceError = _py2h(PyExc_ReferenceError); + ctx->h_SystemError = _py2h(PyExc_SystemError); + ctx->h_SystemExit = _py2h(PyExc_SystemExit); + ctx->h_TypeError = _py2h(PyExc_TypeError); + ctx->h_UnboundLocalError = _py2h(PyExc_UnboundLocalError); + ctx->h_UnicodeError = _py2h(PyExc_UnicodeError); + ctx->h_UnicodeEncodeError = _py2h(PyExc_UnicodeEncodeError); + ctx->h_UnicodeDecodeError = _py2h(PyExc_UnicodeDecodeError); + ctx->h_UnicodeTranslateError = _py2h(PyExc_UnicodeTranslateError); + ctx->h_ValueError = _py2h(PyExc_ValueError); + ctx->h_ZeroDivisionError = _py2h(PyExc_ZeroDivisionError); + ctx->h_BlockingIOError = _py2h(PyExc_BlockingIOError); + ctx->h_BrokenPipeError = _py2h(PyExc_BrokenPipeError); + ctx->h_ChildProcessError = _py2h(PyExc_ChildProcessError); + ctx->h_ConnectionError = _py2h(PyExc_ConnectionError); + ctx->h_ConnectionAbortedError = _py2h(PyExc_ConnectionAbortedError); + ctx->h_ConnectionRefusedError = _py2h(PyExc_ConnectionRefusedError); + ctx->h_ConnectionResetError = _py2h(PyExc_ConnectionResetError); + ctx->h_FileExistsError = _py2h(PyExc_FileExistsError); + ctx->h_FileNotFoundError = _py2h(PyExc_FileNotFoundError); + ctx->h_InterruptedError = _py2h(PyExc_InterruptedError); + ctx->h_IsADirectoryError = _py2h(PyExc_IsADirectoryError); + ctx->h_NotADirectoryError = _py2h(PyExc_NotADirectoryError); + ctx->h_PermissionError = _py2h(PyExc_PermissionError); + ctx->h_ProcessLookupError = _py2h(PyExc_ProcessLookupError); + ctx->h_TimeoutError = _py2h(PyExc_TimeoutError); + /* Warnings */ + ctx->h_Warning = _py2h(PyExc_Warning); + ctx->h_UserWarning = _py2h(PyExc_UserWarning); + ctx->h_DeprecationWarning = _py2h(PyExc_DeprecationWarning); + ctx->h_PendingDeprecationWarning = _py2h(PyExc_PendingDeprecationWarning); + ctx->h_SyntaxWarning = _py2h(PyExc_SyntaxWarning); + ctx->h_RuntimeWarning = _py2h(PyExc_RuntimeWarning); + ctx->h_FutureWarning = _py2h(PyExc_FutureWarning); + ctx->h_ImportWarning = _py2h(PyExc_ImportWarning); + ctx->h_UnicodeWarning = _py2h(PyExc_UnicodeWarning); + ctx->h_BytesWarning = _py2h(PyExc_BytesWarning); + ctx->h_ResourceWarning = _py2h(PyExc_ResourceWarning); + /* Types */ + ctx->h_BaseObjectType = _py2h((PyObject *)&PyBaseObject_Type); + ctx->h_TypeType = _py2h((PyObject *)&PyType_Type); + ctx->h_BoolType = _py2h((PyObject *)&PyBool_Type); + ctx->h_LongType = _py2h((PyObject *)&PyLong_Type); + ctx->h_FloatType = _py2h((PyObject *)&PyFloat_Type); + ctx->h_UnicodeType = _py2h((PyObject *)&PyUnicode_Type); + ctx->h_TupleType = _py2h((PyObject *)&PyTuple_Type); + ctx->h_ListType = _py2h((PyObject *)&PyList_Type); + ctx->h_ComplexType = _py2h((PyObject *)&PyComplex_Type); + ctx->h_BytesType = _py2h((PyObject *)&PyBytes_Type); + ctx->h_MemoryViewType = _py2h((PyObject *)&PyMemoryView_Type); + ctx->h_CapsuleType = _py2h((PyObject *)&PyCapsule_Type); + ctx->h_SliceType = _py2h((PyObject *)&PySlice_Type); + ctx->h_DictType = _py2h((PyObject *)&PyDict_Type); + /* Reflection */ + ctx->h_Builtins = _py2h(PyEval_GetBuiltins()); +} + + +PyMODINIT_FUNC +PyInit_universal(void) +{ + init_universal_ctx(&g_universal_ctx); + PyObject *mod = PyModuleDef_Init(&hpy_pydef); + return mod; +} diff --git a/graalpython/hpy/hpy/universal/src/misc_win32.h b/graalpython/hpy/hpy/universal/src/misc_win32.h new file mode 100644 index 0000000000..d267e758e7 --- /dev/null +++ b/graalpython/hpy/hpy/universal/src/misc_win32.h @@ -0,0 +1,55 @@ +/************************************************************/ +/* Emulate dlopen()&co. from the Windows API */ + +#define RTLD_LAZY 0 +#define RTLD_NOW 0 +#define RTLD_GLOBAL 0 +#define RTLD_LOCAL 0 + +static void *dlopen(const char *filename, int flag) +{ + return (void *)LoadLibraryA(filename); +} + +static void *dlopenW(const wchar_t *filename) +{ + return (void *)LoadLibraryW(filename); +} + +static void *dlsym(void *handle, const char *symbol) +{ + void *address = GetProcAddress((HMODULE)handle, symbol); +#ifndef MS_WIN64 + if (!address) { + /* If 'symbol' is not found, then try '_symbol@N' for N in + (0, 4, 8, 12, ..., 124). Unlike ctypes, we try to do that + for any symbol, although in theory it should only be done + for __stdcall functions. + */ + int i; + char mangled_name[1 + strlen(symbol) + 1 + 3 + 1]; + for (i = 0; i < 32; i++) { + sprintf(mangled_name, "_%s@%d", symbol, i * 4); + address = GetProcAddress((HMODULE)handle, mangled_name); + if (address) + break; + } + } +#endif + return address; +} + +static int dlclose(void *handle) +{ + return FreeLibrary((HMODULE)handle) ? 0 : -1; +} + +static const char *dlerror(void) +{ + static char buf[32]; + DWORD dw = GetLastError(); + if (dw == 0) + return NULL; + sprintf(buf, "error 0x%x", (unsigned int)dw); + return buf; +} diff --git a/graalpython/hpy/microbench/README.md b/graalpython/hpy/microbench/README.md new file mode 100644 index 0000000000..c25916088c --- /dev/null +++ b/graalpython/hpy/microbench/README.md @@ -0,0 +1,29 @@ +To run the microbenchmarks +-------------------------- + +1. You need to have `hpy` installed in your virtuanenv. The easiest way + to do it is: + + $ cd /path/to/hpy + $ python setup.py develop + +2. Build the extension modules needed for the microbenchmarks + + $ cd /path/to/hpy/microbench + $ pip install cffi # needed to build _valgrind + $ python setup.py build_ext --inplace + +2. `py.test -v` + +3. To run only cpy or hpy tests, use -m (to select markers): + + $ py.test -v -m hpy + $ py.test -v -m cpy + +4. Step (2) build `hpy_simple` using the CPython ABI by default. If you want + to benchmark the universal mode, you need to build it explicitly: + + $ cd /path/to/hpy/microbench + $ rm *.so # make sure to delete CPython-ABI versions + $ python setup.py --hpy-abi=universal build_ext --inplace + $ py.test -v diff --git a/graalpython/hpy/microbench/_valgrind_build.py b/graalpython/hpy/microbench/_valgrind_build.py new file mode 100644 index 0000000000..4cbbc1ec7d --- /dev/null +++ b/graalpython/hpy/microbench/_valgrind_build.py @@ -0,0 +1,29 @@ +from cffi import FFI +ffibuilder = FFI() + +ffibuilder.cdef(""" + void callgrind_start(void); + void callgrind_stop(void); + int is_running_on_valgrind(void); +""") + + +ffibuilder.set_source("_valgrind", """ +#include +void callgrind_start(void) { + CALLGRIND_START_INSTRUMENTATION; +} + +void callgrind_stop(void) { + CALLGRIND_STOP_INSTRUMENTATION; + CALLGRIND_DUMP_STATS; +} + +int is_running_on_valgrind(void) { + return RUNNING_ON_VALGRIND; +} +""", + libraries=[]) + +if __name__ == "__main__": + ffibuilder.compile(verbose=True) diff --git a/graalpython/hpy/microbench/conftest.py b/graalpython/hpy/microbench/conftest.py new file mode 100644 index 0000000000..8e553ffe76 --- /dev/null +++ b/graalpython/hpy/microbench/conftest.py @@ -0,0 +1,124 @@ +import re +import time +from collections import defaultdict +import pytest +import _valgrind + +class Timer: + + def __init__(self, nodeid): + self.nodeid = nodeid + self.start = None + self.stop = None + + def __enter__(self): + if self.start is not None: + raise ValueError('You cannot use "with timer:" more than once') + _valgrind.lib.callgrind_start() + self.start = time.time() + + def __exit__(self, etype, evalue, tb): + self.stop = time.time() + _valgrind.lib.callgrind_stop() + + def __str__(self): + if self.start is None: + return '[NO TIMING]' + if self.stop is None: + return '[IN-PROGRESS]' + usec = (self.stop - self.start) * 1000 + return f'{usec:.2f} us' + + @property + def elapsed(self): + if self.start is not None and self.stop is not None: + return self.stop - self.start + return None + + +class TimerSession: + + NODEID = re.compile(r'(.*)\[(.*)\]') + + def __init__(self): + self.apis = set() # ['cpy', 'hpy', ...] + self.table = defaultdict(dict) # {shortid: {api: timer}} + self.timers = {} # nodeid -> Timer + + def new_timer(self, nodeid): + shortid, api = self.split_nodeid(nodeid) + timer = Timer(nodeid) + self.apis.add(api) + self.table[shortid][api] = timer + self.timers[nodeid] = timer + return timer + + def get_timer(self, nodeid): + return self.timers.get(nodeid) + + def split_nodeid(self, nodeid): + shortid = '::'.join(nodeid.split('::')[-2:]) # take only class::function + m = self.NODEID.match(shortid) + if not m: + return shortid, '' + return m.group(1), m.group(2) + + def format_ratio(self, reference, value): + if reference and reference.elapsed and value and value.elapsed: + ratio = value.elapsed / reference.elapsed + return f'[{ratio:.2f}]' + return '' + + def display_summary(self, tr): + w = tr.write_line + w('') + tr.write_sep('=', 'BENCHMARKS', cyan=True) + w(' '*40 + ' cpy hpy') + w(' '*40 + '---------------- -------------------') + for shortid, timings in self.table.items(): + cpy = timings.get('cpy') + hpy = timings.get('hpy') + hpy_ratio = self.format_ratio(cpy, hpy) + cpy = cpy or '' + hpy = hpy or '' + w(f'{shortid:<40} {cpy!s:>15} {hpy!s:>15} {hpy_ratio}') + w('') + + + +@pytest.fixture +def timer(request, api): + nodeid = request.node.nodeid + return request.config._timersession.new_timer(nodeid) + +def pytest_configure(config): + config._timersession = TimerSession() + config.addinivalue_line("markers", "hpy: mark modules using the HPy API") + config.addinivalue_line("markers", "cpy: mark modules using the old Python/C API") + +def pytest_addoption(parser): + parser.addoption( + "--fast", action="http://github.com/store_true", default=False, help="run microbench faster" + ) + parser.addoption( + "--slow", action="http://github.com/store_true", default=False, help="run microbench slower" + ) + + +VERBOSE_TEST_NAME_LENGTH = 90 + +@pytest.hookimpl(hookwrapper=True) +def pytest_report_teststatus(report, config): + outcome = yield + category, letter, word = outcome.get_result() + timer = config._timersession.get_timer(report.nodeid) + if category == 'passed' and timer: + L = VERBOSE_TEST_NAME_LENGTH - len(report.nodeid) + word = str(timer).rjust(L) + markup = None + if timer.elapsed is None: + markup = {'yellow': True} + outcome.force_result((category, letter, (word, markup))) + +def pytest_terminal_summary(terminalreporter, config): + config._timersession.display_summary(terminalreporter) diff --git a/graalpython/hpy/microbench/pytest_valgrind.sh b/graalpython/hpy/microbench/pytest_valgrind.sh new file mode 100755 index 0000000000..8271381d0b --- /dev/null +++ b/graalpython/hpy/microbench/pytest_valgrind.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +valgrind --tool=callgrind --instr-atstart=no python3-dbg -m pytest "$@" diff --git a/graalpython/hpy/microbench/setup.py b/graalpython/hpy/microbench/setup.py new file mode 100644 index 0000000000..16988b0aef --- /dev/null +++ b/graalpython/hpy/microbench/setup.py @@ -0,0 +1,17 @@ +from setuptools import setup, Extension + +setup( + name="hpy.microbench", + setup_requires=['cffi', 'hpy'], + ext_modules = [ + Extension('cpy_simple', + ['src/cpy_simple.c'], + extra_compile_args=['-g']) + ], + hpy_ext_modules = [ + Extension('hpy_simple', + ['src/hpy_simple.c'], + extra_compile_args=['-g']), + ], + cffi_modules=["_valgrind_build.py:ffibuilder"], +) diff --git a/graalpython/hpy/microbench/src/cpy_simple.c b/graalpython/hpy/microbench/src/cpy_simple.c new file mode 100644 index 0000000000..dc754de64e --- /dev/null +++ b/graalpython/hpy/microbench/src/cpy_simple.c @@ -0,0 +1,174 @@ +#include + +/* module-level functions */ + +static PyObject* noargs(PyObject* self, PyObject* args) +{ + Py_RETURN_NONE; +} + +static PyObject* onearg(PyObject* self, PyObject* arg) +{ + Py_RETURN_NONE; +} + +static PyObject* varargs(PyObject* self, PyObject* args) +{ + Py_RETURN_NONE; +} + +static PyObject* call_with_tuple(PyObject* self, PyObject* args) +{ + PyObject* f; + PyObject* f_args; + f = PyTuple_GetItem(args, 0); + if (f == NULL) + Py_RETURN_NONE; + f_args = PyTuple_GetItem(args, 1); + if (f_args == NULL) + Py_RETURN_NONE; + return PyObject_CallObject(f, f_args); +} + +static PyObject* call_with_tuple_and_dict(PyObject* self, PyObject* args) +{ + PyObject* f; + PyObject* f_args; + PyObject* f_kw; + f = PyTuple_GetItem(args, 0); + if (f == NULL) + Py_RETURN_NONE; + f_args = PyTuple_GetItem(args, 1); + if (f_args == NULL) + Py_RETURN_NONE; + f_kw = PyTuple_GetItem(args, 2); + if (f_kw == NULL) + Py_RETURN_NONE; + return PyObject_Call(f, f_args, f_kw); +} + +static PyObject* allocate_int(PyObject* self, PyObject* args) +{ + return PyLong_FromLong(2048); +} + +static PyObject* allocate_tuple(PyObject* self, PyObject* args) +{ + return Py_BuildValue("ii", 2048, 2049); +} + +static PyObject * Foo_getitem(PyObject *self, Py_ssize_t i) +{ + Py_RETURN_NONE; +} + +static Py_ssize_t Foo_len(PyObject *self) +{ + return 42; +} + +static PyMethodDef SimpleMethods[] = { + {"noargs", (PyCFunction)noargs, METH_NOARGS, ""}, + {"onearg", (PyCFunction)onearg, METH_O, ""}, + {"varargs", (PyCFunction)varargs, METH_VARARGS, ""}, + {"call_with_tuple", (PyCFunction)call_with_tuple, METH_VARARGS, ""}, + {"call_with_tuple_and_dict", (PyCFunction)call_with_tuple_and_dict, METH_VARARGS, ""}, + {"allocate_int", (PyCFunction)allocate_int, METH_NOARGS, ""}, + {"allocate_tuple", (PyCFunction)allocate_tuple, METH_NOARGS, ""}, + {NULL, NULL, 0, NULL} +}; + + +static PySequenceMethods FooSequence = { + .sq_length = (lenfunc)Foo_len, + .sq_item = (ssizeargfunc)Foo_getitem, + NULL, +}; + + +/* types */ + +typedef struct { + PyObject_HEAD +} FooObject; + +static PyTypeObject Foo_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "cpy_simple.Foo", /* tp_name */ + sizeof(FooObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + &FooSequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "Foo objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + SimpleMethods, /* tp_methods, reuse the same functions */ +}; + + +static PyType_Slot HTFoo_slots[] = { + {Py_tp_doc, "HTFoo objects"}, + {Py_tp_methods, SimpleMethods}, + {Py_sq_item, Foo_getitem}, + {Py_sq_length, Foo_len}, + {0, 0} +}; + +static PyType_Spec HTFoo_Type_spec = { + .name = "cpy_simple.Foo", + .basicsize = sizeof(FooObject), + .itemsize = 0, + .flags = Py_TPFLAGS_DEFAULT, + .slots = HTFoo_slots +}; + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "cpy_simple", + "Module Doc", + -1, + SimpleMethods, + NULL, + NULL, + NULL, + NULL, +}; + +PyMODINIT_FUNC +PyInit_cpy_simple(void) +{ + PyObject* m; + Foo_Type.tp_new = PyType_GenericNew; + if (PyType_Ready(&Foo_Type) < 0) + return NULL; + m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; + Py_INCREF(&Foo_Type); + PyModule_AddObject(m, "Foo", (PyObject *)&Foo_Type); + + PyObject *HTFoo_Type = PyType_FromSpec(&HTFoo_Type_spec); + if (HTFoo_Type == NULL) + return NULL; + PyModule_AddObject(m, "HTFoo", HTFoo_Type); + + return m; +} diff --git a/graalpython/hpy/microbench/src/hpy_simple.c b/graalpython/hpy/microbench/src/hpy_simple.c new file mode 100644 index 0000000000..a5dddadd63 --- /dev/null +++ b/graalpython/hpy/microbench/src/hpy_simple.c @@ -0,0 +1,135 @@ +#include "hpy.h" + +/* module-level functions */ + +HPyDef_METH(noargs, "noargs", HPyFunc_NOARGS) +static HPy noargs_impl(HPyContext *ctx, HPy self) +{ + return HPy_Dup(ctx, ctx->h_None); +} + +HPyDef_METH(onearg, "onearg", HPyFunc_O) +static HPy onearg_impl(HPyContext *ctx, HPy self, HPy arg) +{ + return HPy_Dup(ctx, ctx->h_None); +} + +HPyDef_METH(varargs, "varargs", HPyFunc_VARARGS) +static HPy varargs_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) +{ + return HPy_Dup(ctx, ctx->h_None); +} + +HPyDef_METH(call_with_tuple, "call_with_tuple", HPyFunc_VARARGS) +static HPy call_with_tuple_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) +{ + HPy f, f_args; + if (nargs != 2) { + HPyErr_SetString(ctx, ctx->h_TypeError, "call_with_tuple requires two arguments"); + return HPy_NULL; + } + f = args[0]; + f_args = args[1]; + return HPy_CallTupleDict(ctx, f, f_args, HPy_NULL); +} + +HPyDef_METH(call_with_tuple_and_dict, "call_with_tuple_and_dict", HPyFunc_VARARGS) +static HPy call_with_tuple_and_dict_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) +{ + HPy f, f_args, f_kw; + if (nargs != 3) { + HPyErr_SetString(ctx, ctx->h_TypeError, "call_with_tuple_and_dict requires three arguments"); + return HPy_NULL; + } + f = args[0]; + f_args = args[1]; + f_kw = args[2]; + return HPy_CallTupleDict(ctx, f, f_args, f_kw); +} + +HPyDef_METH(allocate_int, "allocate_int", HPyFunc_NOARGS) +static HPy allocate_int_impl(HPyContext *ctx, HPy self) +{ + return HPyLong_FromLong(ctx, 2048); +} + +HPyDef_METH(allocate_tuple, "allocate_tuple", HPyFunc_NOARGS) +static HPy allocate_tuple_impl(HPyContext *ctx, HPy self) +{ + return HPy_BuildValue(ctx, "ii", 2048, 2049); +} + + +/* Foo type */ + +typedef struct { + long x; + long y; +} FooObject; + +HPyDef_SLOT(Foo_getitem, HPy_sq_item) +static HPy Foo_getitem_impl(HPyContext *ctx, HPy self, HPy_ssize_t i) +{ + return HPy_Dup(ctx, ctx->h_None); +} + +HPyDef_SLOT(Foo_len, HPy_sq_length) +static HPy_ssize_t Foo_len_impl(HPyContext *ctx, HPy self) +{ + return 42; +} + + +// note that we can reuse the same HPyDef for both module-level and type-level +// methods +static HPyDef *foo_defines[] = { + &noargs, + &onearg, + &varargs, + &allocate_int, + &allocate_tuple, + &Foo_getitem, + &Foo_len, +}; + + +static HPyType_Spec Foo_spec = { + .name = "hpy_simple.Foo", + .basicsize = sizeof(FooObject), + .flags = HPy_TPFLAGS_DEFAULT, + .defines = foo_defines +}; + + +/* Module defines */ + +HPyDef_SLOT(init_hpy_simple, HPy_mod_exec) +static int init_hpy_simple_impl(HPyContext *ctx, HPy m) +{ + HPy h_Foo = HPyType_FromSpec(ctx, &Foo_spec, NULL); + if (HPy_IsNull(h_Foo)) + return -1; + HPy_SetAttr_s(ctx, m, "Foo", h_Foo); + HPy_SetAttr_s(ctx, m, "HTFoo", h_Foo); + return 0; +} + +static HPyDef *module_defines[] = { + &noargs, + &onearg, + &varargs, + &call_with_tuple, + &call_with_tuple_and_dict, + &allocate_int, + &allocate_tuple, + &init_hpy_simple, + NULL +}; + +static HPyModuleDef moduledef = { + .doc = "HPy microbenchmarks", + .size = 0, + .defines = module_defines, +}; + +HPy_MODINIT(hpy_simple, moduledef) diff --git a/graalpython/hpy/microbench/test_microbench.py b/graalpython/hpy/microbench/test_microbench.py new file mode 100644 index 0000000000..ed59a243f0 --- /dev/null +++ b/graalpython/hpy/microbench/test_microbench.py @@ -0,0 +1,226 @@ +""" +These are not real tests, but microbenchmarks. The machinery to record the +timing and display the results is inside conftest.py +""" + +import pytest +import _valgrind + +API_PARAMS = [ + pytest.param('cpy', marks=pytest.mark.cpy), + pytest.param('hpy', marks=pytest.mark.hpy) + ] + +@pytest.fixture(params=API_PARAMS) +def api(request): + return request.param + +@pytest.fixture +def simple(request, api): + if api == 'cpy': + import cpy_simple + return cpy_simple + elif api == 'hpy': + import hpy_simple + return hpy_simple + else: + assert False, 'Unkown param: %s' % request.param + +@pytest.fixture +def N(request): + n = 10000000 + if request.config.option.fast: + n //= 100 + if request.config.option.slow: + n *= 10 + if _valgrind.lib.is_running_on_valgrind(): + n //= 100 + return n + + +class TestModule: + + def test_noargs(self, simple, timer, N): + with timer: + for i in range(N): + simple.noargs() + + def test_onearg_None(self, simple, timer, N): + with timer: + for i in range(N): + simple.onearg(None) + + def test_onearg_int(self, simple, timer, N): + with timer: + for i in range(N): + simple.onearg(i) + + def test_varargs(self, simple, timer, N): + with timer: + for i in range(N): + simple.varargs(None, None) + + def test_call_with_tuple(self, simple, timer, N): + def f(a, b): + return a + b + + with timer: + for i in range(N): + simple.call_with_tuple(f, (1, 2)) + + def test_call_with_tuple_and_dict(self, simple, timer, N): + def f(a, b): + return a + b + + with timer: + for i in range(N): + simple.call_with_tuple_and_dict(f, (1,), {"b": 2}) + + def test_allocate_int(self, simple, timer, N): + with timer: + for i in range(N): + simple.allocate_int() + + def test_allocate_tuple(self, api, simple, timer, N): + with timer: + for i in range(N): + simple.allocate_tuple() + + +class TestType: + """ Compares the performance of operations on types. + + The kinds of type used are: + + * cpy: a static type + * hpy: a heap type (HPy only has heap types) + + The type is named `simple.Foo` in both cases. + """ + + def test_allocate_obj(self, simple, timer, N): + import gc + Foo = simple.Foo + objs = [None] * N + gc.collect() + with timer: + for i in range(N): + objs[i] = Foo() + del objs + gc.collect() + + def test_method_lookup(self, simple, timer, N): + obj = simple.Foo() + with timer: + for i in range(N): + # note: here we are NOT calling it, we want to measure just + # the lookup + obj.noargs + + def test_noargs(self, simple, timer, N): + obj = simple.Foo() + with timer: + for i in range(N): + obj.noargs() + + def test_onearg_None(self, simple, timer, N): + obj = simple.Foo() + with timer: + for i in range(N): + obj.onearg(None) + + def test_onearg_int(self, simple, timer, N): + obj = simple.Foo() + with timer: + for i in range(N): + obj.onearg(i) + + def test_varargs(self, simple, timer, N): + obj = simple.Foo() + with timer: + for i in range(N): + obj.varargs(None, None) + + def test_len(self, simple, timer, N): + obj = simple.Foo() + with timer: + for i in range(N): + len(obj) + + def test_getitem(self, simple, timer, N): + obj = simple.Foo() + with timer: + for i in range(N): + obj[0] + + +class TestHeapType: + """ Compares the performance of operations on heap types. + + The type is named `simple.HTFoo` and is a heap type in all cases. + """ + + def test_allocate_obj_and_survive(self, simple, timer, N): + import gc + HTFoo = simple.HTFoo + objs = [None] * N + gc.collect() + with timer: + for i in range(N): + objs[i] = HTFoo() + del objs + gc.collect() + + def test_allocate_obj_and_die(self, simple, timer, N): + import gc + HTFoo = simple.HTFoo + gc.collect() + with timer: + for i in range(N): + obj = HTFoo() + obj.onearg(None) + gc.collect() + + def test_method_lookup(self, simple, timer, N): + obj = simple.HTFoo() + with timer: + for i in range(N): + # note: here we are NOT calling it, we want to measure just + # the lookup + obj.noargs + + def test_noargs(self, simple, timer, N): + obj = simple.HTFoo() + with timer: + for i in range(N): + obj.noargs() + + def test_onearg_None(self, simple, timer, N): + obj = simple.HTFoo() + with timer: + for i in range(N): + obj.onearg(None) + + def test_onearg_int(self, simple, timer, N): + obj = simple.HTFoo() + with timer: + for i in range(N): + obj.onearg(i) + + def test_varargs(self, simple, timer, N): + obj = simple.HTFoo() + with timer: + for i in range(N): + obj.varargs(None, None) + + def test_len(self, simple, timer, N): + obj = simple.HTFoo() + with timer: + for i in range(N): + len(obj) + + def test_getitem(self, simple, timer, N): + obj = simple.HTFoo() + with timer: + for i in range(N): + obj[0] diff --git a/graalpython/hpy/proof-of-concept/pof.c b/graalpython/hpy/proof-of-concept/pof.c new file mode 100644 index 0000000000..672a9a0199 --- /dev/null +++ b/graalpython/hpy/proof-of-concept/pof.c @@ -0,0 +1,109 @@ +#include "hpy.h" +#include + +HPyDef_METH(do_nothing, "do_nothing", HPyFunc_NOARGS) +static HPy do_nothing_impl(HPyContext *ctx, HPy self) +{ + return HPy_Dup(ctx, ctx->h_None); +} + +HPyDef_METH(double_obj, "double", HPyFunc_O) +static HPy double_obj_impl(HPyContext *ctx, HPy self, HPy obj) +{ + return HPy_Add(ctx, obj, obj); +} + +HPyDef_METH(add_ints, "add_ints", HPyFunc_VARARGS) +static HPy add_ints_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) +{ + long a, b; + if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &a, &b)) + return HPy_NULL; + return HPyLong_FromLong(ctx, a+b); +} + +HPyDef_METH(add_ints_kw, "add_ints_kw", HPyFunc_KEYWORDS) +static HPy add_ints_kw_impl(HPyContext *ctx, HPy self, const HPy *args, + size_t nargs, HPy kwnames) +{ + long a, b; + const char* kwlist[] = {"a", "b", NULL}; + if (!HPyArg_ParseKeywords(ctx, NULL, args, nargs, kwnames, "ll", + kwlist, &a, &b)) + return HPy_NULL; + return HPyLong_FromLong(ctx, a+b); +} + +typedef struct { + double x; + double y; +} PointObject; + +HPyType_HELPERS(PointObject) + +HPyDef_SLOT(Point_new, HPy_tp_new) +static HPy Point_new_impl (HPyContext *ctx, HPy cls, const HPy *args, + HPy_ssize_t nargs, HPy kwnames) +{ + double x, y; + if (!HPyArg_Parse(ctx, NULL, args, nargs, "dd", &x, &y)) + return HPy_NULL; + PointObject *point; + HPy h_point = HPy_New(ctx, cls, &point); + if (HPy_IsNull(h_point)) + return HPy_NULL; + point->x = x; + point->y = y; + return h_point; +} + +HPyDef_SLOT(Point_repr, HPy_tp_repr) +static HPy Point_repr_impl(HPyContext *ctx, HPy self) +{ + PointObject *point = PointObject_AsStruct(ctx, self); + char msg[256]; + snprintf(msg, 256, "Point(%g, %g)", point->x, point->y); + return HPyUnicode_FromString(ctx, msg); + //return HPyUnicode_FromFormat("Point(%g, %g)", point->x, point->y); +} + + +static HPyDef *point_type_defines[] = { + &Point_new, + &Point_repr, + NULL +}; +static HPyType_Spec point_type_spec = { + .name = "pof.Point", + .basicsize = sizeof(PointObject), + .flags = HPy_TPFLAGS_DEFAULT, + .defines = point_type_defines +}; + +HPyDef_SLOT(mod_exec, HPy_mod_exec) +static int mod_exec_impl(HPyContext *ctx, HPy m) +{ + HPy h_point_type = HPyType_FromSpec(ctx, &point_type_spec, NULL); + if (HPy_IsNull(h_point_type)) + return -1; + HPy_SetAttr_s(ctx, m, "Point", h_point_type); + HPy_Close(ctx, h_point_type); + return 0; +} + +static HPyDef *module_defines[] = { + &do_nothing, + &double_obj, + &add_ints, + &add_ints_kw, + &mod_exec, + NULL +}; + +static HPyModuleDef moduledef = { + .doc = "HPy Proof of Concept", + .size = 0, + .defines = module_defines +}; + +HPy_MODINIT(pof, moduledef) diff --git a/graalpython/hpy/proof-of-concept/pofcpp.cpp b/graalpython/hpy/proof-of-concept/pofcpp.cpp new file mode 100644 index 0000000000..6214c5f87c --- /dev/null +++ b/graalpython/hpy/proof-of-concept/pofcpp.cpp @@ -0,0 +1,117 @@ +#include "hpy.h" +#include + +HPyDef_METH(do_nothing, "do_nothing", HPyFunc_NOARGS) +static HPy do_nothing_impl(HPyContext *ctx, HPy self) +{ + return HPy_Dup(ctx, ctx->h_None); +} + +HPyDef_METH(double_obj, "double", HPyFunc_O) +static HPy double_obj_impl(HPyContext *ctx, HPy self, HPy obj) +{ + return HPy_Add(ctx, obj, obj); +} + +HPyDef_METH(add_ints, "add_ints", HPyFunc_VARARGS) +static HPy add_ints_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) +{ + long a, b; + if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &a, &b)) + return HPy_NULL; + return HPyLong_FromLong(ctx, a+b); +} + +HPyDef_METH(add_ints_kw, "add_ints_kw", HPyFunc_KEYWORDS) +static HPy add_ints_kw_impl(HPyContext *ctx, HPy self, const HPy *args, + size_t nargs, HPy kwnames) +{ + long a, b; + const char* kwlist[] = {"a", "b", NULL}; + if (!HPyArg_ParseKeywords(ctx, NULL, args, nargs, kwnames, "ll", + kwlist, &a, &b)) + return HPy_NULL; + return HPyLong_FromLong(ctx, a+b); +} + +typedef struct { + double x; + double y; +} PointObject; + +HPyType_HELPERS(PointObject) + +HPyDef_SLOT(Point_new, HPy_tp_new) +static HPy Point_new_impl (HPyContext *ctx, HPy cls, const HPy *args, + HPy_ssize_t nargs, HPy kwnames) +{ + double x, y; + if (!HPyArg_Parse(ctx, NULL, args, nargs, "dd", &x, &y)) + return HPy_NULL; + PointObject *point; + HPy h_point = HPy_New(ctx, cls, &point); + if (HPy_IsNull(h_point)) + return HPy_NULL; + point->x = x; + point->y = y; + return h_point; +} + +HPyDef_SLOT(Point_repr, HPy_tp_repr) +static HPy Point_repr_impl(HPyContext *ctx, HPy self) +{ + PointObject *point = PointObject_AsStruct(ctx, self); + char msg[256]; + snprintf(msg, 256, "Point(%g, %g)", point->x, point->y); + return HPyUnicode_FromString(ctx, msg); + //return HPyUnicode_FromFormat("Point(%g, %g)", point->x, point->y); +} + + +static HPyDef *point_type_defines[] = { + &Point_new, + &Point_repr, + NULL +}; + +static HPyType_Spec point_type_spec = { + .name = "pofcpp.Point", + .basicsize = sizeof(PointObject), + .flags = HPy_TPFLAGS_DEFAULT, + .defines = point_type_defines +}; + +HPyDef_SLOT(mod_exec, HPy_mod_exec) +static int mod_exec_impl(HPyContext *ctx, HPy m) +{ + HPy h_point_type = HPyType_FromSpec(ctx, &point_type_spec, NULL); + if (HPy_IsNull(h_point_type)) + return -1; + HPy_SetAttr_s(ctx, m, "Point", h_point_type); + HPy_Close(ctx, h_point_type); + return 0; +} + +static HPyDef *module_defines[] = { + &do_nothing, + &double_obj, + &add_ints, + &add_ints_kw, + &mod_exec, + NULL +}; +static HPyModuleDef moduledef = { + .doc = "HPy c++ Proof of Concept", + .size = 0, + .defines = module_defines +}; + +#ifdef __cplusplus +extern "C" { +#endif + +HPy_MODINIT(pofcpp, moduledef) + +#ifdef __cplusplus +} +#endif diff --git a/graalpython/hpy/proof-of-concept/pofpackage/bar.cpp b/graalpython/hpy/proof-of-concept/pofpackage/bar.cpp new file mode 100644 index 0000000000..01726d2d6f --- /dev/null +++ b/graalpython/hpy/proof-of-concept/pofpackage/bar.cpp @@ -0,0 +1,45 @@ +#include "hpy.h" + +class Bar +{ + int foo; + public: + Bar(int f) + { + foo = f; + } + + int boo(HPyContext *ctx, HPy obj) + { + return foo + HPyLong_AsLong(ctx, obj); + } +}; + +HPyDef_METH(hello, "hello", HPyFunc_O) +static HPy hello_impl(HPyContext *ctx, HPy self, HPy obj) +{ + Bar b(21); + return HPyLong_FromLong(ctx, b.boo(ctx, obj)); +} + + +static HPyDef *module_defines[] = { + &hello, + NULL +}; +static HPyModuleDef moduledef = { + .doc = "HPy C++ Proof of Concept", + .size = 0, + .defines = module_defines +}; + +#ifdef __cplusplus +extern "C" { +#endif + + +HPy_MODINIT(bar, moduledef) + +#ifdef __cplusplus +} +#endif diff --git a/graalpython/hpy/proof-of-concept/pofpackage/foo.c b/graalpython/hpy/proof-of-concept/pofpackage/foo.c new file mode 100644 index 0000000000..3a265efa25 --- /dev/null +++ b/graalpython/hpy/proof-of-concept/pofpackage/foo.c @@ -0,0 +1,20 @@ +#include "hpy.h" + +HPyDef_METH(hello, "hello", HPyFunc_NOARGS) +static HPy hello_impl(HPyContext *ctx, HPy self) +{ + return HPyUnicode_FromString(ctx, "hello from pofpackage.foo"); +} + + +static HPyDef *module_defines[] = { + &hello, + NULL +}; +static HPyModuleDef moduledef = { + .doc = "HPy Proof of Concept", + .size = 0, + .defines = module_defines +}; + +HPy_MODINIT(foo, moduledef) diff --git a/graalpython/lib-graalpython/modules/hpy.egg-info/top_level.txt b/graalpython/hpy/proof-of-concept/requirements.txt similarity index 100% rename from graalpython/lib-graalpython/modules/hpy.egg-info/top_level.txt rename to graalpython/hpy/proof-of-concept/requirements.txt diff --git a/graalpython/hpy/proof-of-concept/setup.py b/graalpython/hpy/proof-of-concept/setup.py new file mode 100644 index 0000000000..8132e1f2dc --- /dev/null +++ b/graalpython/hpy/proof-of-concept/setup.py @@ -0,0 +1,36 @@ +from setuptools import setup, Extension +import platform + +cpp_compile_extra_args = [] + +if platform.system() == "Windows": + compile_extra_args = ['/WX'] + cpp_compile_extra_args = [ + "/std:c++latest", # MSVC C7555 + ] +else: + compile_extra_args = ['-Werror'] + + +setup( + name="hpy-pof", + packages = ['pofpackage'], + zip_safe=False, + hpy_ext_modules=[ + Extension('pof', + sources=['pof.c'], + extra_compile_args=compile_extra_args), + Extension('pofpackage.foo', + sources=['pofpackage/foo.c'], + extra_compile_args=compile_extra_args), + Extension('pofcpp', + sources=['pofcpp.cpp'], + language='C++', + extra_compile_args=compile_extra_args + cpp_compile_extra_args), + Extension('pofpackage.bar', + sources=['pofpackage/bar.cpp'], + language='C++', + extra_compile_args=compile_extra_args + cpp_compile_extra_args), + ], + setup_requires=['hpy'], +) diff --git a/graalpython/hpy/proof-of-concept/test_pof.py b/graalpython/hpy/proof-of-concept/test_pof.py new file mode 100644 index 0000000000..54c6851c3f --- /dev/null +++ b/graalpython/hpy/proof-of-concept/test_pof.py @@ -0,0 +1,44 @@ +import pof +import pofpackage.foo +import pofcpp +import pofpackage.bar + +def test_do_nothing(): + assert pof.do_nothing() is None + +def test_double(): + assert pof.double(21) == 42 + +def test_add_ints(): + assert pof.add_ints(30, 12) == 42 + +def test_add_ints_kw(): + assert pof.add_ints_kw(b=30, a=12) == 42 + +def test_point(): + p = pof.Point(1, 2) + assert repr(p) == 'Point(1, 2)' # fixme when we have HPyFloat_FromDouble + +def test_pofpackage(): + assert pofpackage.foo.__name__ == "pofpackage.foo" + assert pofpackage.foo.hello() == 'hello from pofpackage.foo' + +def test_cpp_do_nothing(): + assert pofcpp.do_nothing() is None + +def test_cpp_double(): + assert pofcpp.double(21) == 42 + +def test_cpp_add_ints(): + assert pofcpp.add_ints(30, 12) == 42 + +def test_cpp_add_ints_kw(): + assert pofcpp.add_ints_kw(b=30, a=12) == 42 + +def test_cpp_point(): + p = pofcpp.Point(1, 2) + assert repr(p) == 'Point(1, 2)' # fixme when we have HPyFloat_FromDouble + +def test_cpp_pofpackage(): + assert pofpackage.bar.__name__ == "pofpackage.bar" + assert pofpackage.bar.hello(21) == 42 diff --git a/graalpython/hpy/proof-of-concept/test_pof.sh b/graalpython/hpy/proof-of-concept/test_pof.sh new file mode 100755 index 0000000000..1ac800769c --- /dev/null +++ b/graalpython/hpy/proof-of-concept/test_pof.sh @@ -0,0 +1,177 @@ +#!/bin/bash +set -e +ROOT=`pwd` # we expect this script to be run from the repo root + +# Allow the caller to override the Python runtime used +PYTHON=${PYTHON:-python3} + +_install_hpy() { + echo "Installing hpy" + # at the moment this install hpy.devel and hpy.universal. Eventually, we + # will want to split those into two separate packages + local PYTHON="$1" + pushd ${ROOT} + ${PYTHON} -m pip install -U pip + ${PYTHON} -m pip install wheel + ${PYTHON} -m pip install . + popd +} + +_test_pof() { + echo "==== testing pof ====" + # this assumes that pof is already installed, e.g. after calling + # wheel or setup_py_install + ${PYTHON} -m pip install pytest pytest-azurepipelines + cd proof-of-concept + ${PYTHON} -m pytest +} + +_build_wheel() { + HPY_ABI="$1" + local VENV="venv/wheel_builder_$HPY_ABI" + # we use this venv just to build the wheel, and then we install the wheel + # in the currently active virtualenv + echo "Create venv: $VENV" + ${PYTHON} -m venv "$VENV" + local PY_BUILDER="`pwd`/$VENV/bin/python3" + if [ -x "`pwd`/$VENV/Scripts/python.exe" ] + then + # Set the correct python executable for Windows + PY_BUILDER="`pwd`/$VENV/Scripts/python.exe" + fi + echo + echo "Installing hpy and requirements" + _install_hpy ${PY_BUILDER} + pushd proof-of-concept + ${PY_BUILDER} -m pip install -r requirements.txt + echo + echo "Building wheel" + ${PY_BUILDER} setup.py --hpy-abi="$HPY_ABI" bdist_wheel + popd +} + +_myrm() { + for path in "$@" + do + if [ -d "$path" -o -f "$path" ] + then + echo "rm $path" + rm -rf "$path" + else + echo "skipping $path" + fi + done +} + +clean() { + echo "=== cleaning up old stuff ===" + _myrm ${ROOT}/venv/wheel_builder_{cpython,universal} + _myrm ${ROOT}/venv/wheel_runner_{cpython,universal} + _myrm ${ROOT}/venv/setup_py_install_{cpython,universal} + _myrm ${ROOT}/venv/setup_py_build_ext_inplace_{cpython,universal} + _myrm ${ROOT}/build + _myrm ${ROOT}/proof-of-concept/build + _myrm ${ROOT}/proof-of-concept/dist + # remove files written by build_ext --inplace + _myrm ${ROOT}/proof-of-concept/pof*{.so,.py} + _myrm ${ROOT}/proof-of-concept/pofpackage/foo*{.so,.py} + _myrm ${ROOT}/proof-of-concept/pofcpp*{.so,.py} + _myrm ${ROOT}/proof-of-concept/pofpackage/bar*{.so,.py} + echo +} + +wheel() { + # build a wheel, install and test + HPY_ABI="$1" + local VENV="venv/wheel_runner_$HPY_ABI" + clean + echo "=== testing setup.py bdist_wheel" $HPY_ABI "===" + _build_wheel "$HPY_ABI" + WHEEL=`ls proof-of-concept/dist/*.whl` + echo "Wheel created: ${WHEEL}" + echo + echo "Create venv: $VENV" + ${PYTHON} -m venv "$VENV" + if [ -e "$VENV/bin/activate" ] ; then + source "$VENV/bin/activate" + else + source "$VENV/Scripts/activate" + fi + _install_hpy ${PYTHON} + echo "Installing wheel" + ${PYTHON} -m pip install $WHEEL + echo + _test_pof +} + +setup_py_install() { + # install proof-of-concept using setup.py install and run tests + HPY_ABI="$1" + VENV="venv/setup_py_install_$HPY_ABI" + clean + echo "=== testing setup.py --hpy-abi=$HPY_ABI install ===" + echo "Create venv: $VENV" + ${PYTHON} -m venv "$VENV" + if [ -e "$VENV/bin/activate" ] ; then + source "$VENV/bin/activate" + else + source "$VENV/Scripts/activate" + fi + _install_hpy ${PYTHON} + echo + echo "Running setup.py" + pushd proof-of-concept + ${PYTHON} setup.py --hpy-abi="$HPY_ABI" install + popd + echo + _test_pof +} + +setup_py_build_ext_inplace() { + # install proof-of-concept using setup.py install and run tests + HPY_ABI="$1" + VENV="venv/setup_py_build_ext_inplace_$HPY_ABI" + clean + echo "=== testing setup.py --hpy-abi=$HPY_ABI build_ext --inplace ===" + echo "Create venv: $VENV" + ${PYTHON} -m venv "$VENV" + if [ -e "$VENV/bin/activate" ] ; then + source "$VENV/bin/activate" + else + source "$VENV/Scripts/activate" + fi + _install_hpy ${PYTHON} + echo + echo "Running setup.py" + pushd proof-of-concept + echo python is $(which ${PYTHON}) + ${PYTHON} setup.py --hpy-abi="$HPY_ABI" build_ext --inplace + popd + echo + _test_pof +} + +# ======== main code ======= + +# validate arguments +if [[ "$#" -lt 1 || ( "$#" -lt 2 && "$1" != "clean") ]]; then + echo "Usage: $0 COMMAND [TARGET_ABI]" >&2 + echo "Commands:" >&2 + echo " wheel TARGET_ABI: build a wheel, install and test" + echo " setup_py_install TARGET_ABI: install poc using 'setup.py install' & run tests" >&2 + echo " clean: clean build artifacts" >&2 + echo "Target ABIs:" >&2 + echo " universal: Binary intended for any Python implementation" >&2 + echo " cpython : Binary optimized for CPython" >&2 + exit 1 +fi + +if [ ! -d "proof-of-concept" ] ; then + echo "Script must be run in the repo root" >&2 + exit 1 +fi + +# call the function mentioned as the first arg +COMMAND="$1" +shift +$COMMAND "$@" diff --git a/graalpython/hpy/pyproject.toml b/graalpython/hpy/pyproject.toml new file mode 100644 index 0000000000..a3194aec78 --- /dev/null +++ b/graalpython/hpy/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = [ "setuptools>=64.0", "setuptools-scm[toml]>=6.0", "wheel>=0.34.2",] +build-backend = "setuptools.build_meta" diff --git a/graalpython/hpy/requirements-autogen.txt b/graalpython/hpy/requirements-autogen.txt new file mode 100644 index 0000000000..8c9e2a7384 --- /dev/null +++ b/graalpython/hpy/requirements-autogen.txt @@ -0,0 +1,4 @@ +pycparser==2.21 +py==1.11.0 +packaging==19.2 +attrs==19.3.0 diff --git a/graalpython/hpy/setup.py b/graalpython/hpy/setup.py new file mode 100644 index 0000000000..9a1cb9f2eb --- /dev/null +++ b/graalpython/hpy/setup.py @@ -0,0 +1,269 @@ +import sys +import os.path +from setuptools import setup, Extension +from setuptools.command.build_clib import build_clib +import platform + +# this package is supposed to be installed ONLY on CPython and GraalPy. Try to +# bail out with a meaningful error message in other cases. +if sys.implementation.name not in ('cpython', 'graalpy'): + msg = 'ERROR: Cannot install and/or update hpy on this python implementation:\n' + msg += f' sys.implementation.name == {sys.implementation.name!r}\n\n' + if '_hpy_universal' in sys.builtin_module_names: + # this is a python which comes with its own hpy implementation + import _hpy_universal + if hasattr(_hpy_universal, 'get_version'): + hpy_version, git_rev = _hpy_universal.get_version() + msg += f'This python implementation comes with its own version of hpy=={hpy_version}\n' + msg += '\n' + msg += 'If you are trying to install hpy through pip, consider to put the\n' + msg += 'following in your requirements.txt, to make sure that pip will NOT\n' + msg += 'try to re-install it:\n' + msg += f' hpy=={hpy_version}' + else: + msg += 'This python implementation comes with its own version of hpy,\n' + msg += 'but the exact version could not be determined.\n' + # + else: + # this seems to be a python which does not support hpy + msg += 'This python implementation does not seem to support hpy:\n' + msg += '(built-in module _hpy_universal not found).\n' + msg += 'Please contact your vendor for more information.' + sys.exit(msg) + + +this_directory = os.path.abspath(os.path.dirname(__file__)) +with open(os.path.join(this_directory, 'README.md'), encoding='utf-8') as f: + LONG_DESCRIPTION = f.read() + +if 'HPY_DEBUG_BUILD' in os.environ: + # -fkeep-inline-functions is needed to make sure that the stubs for HPy_* + # functions are available to call inside GDB + EXTRA_COMPILE_ARGS = [ + '-g', '-O0', '-UNDEBUG', + '-fkeep-inline-functions', + # + ## these flags are useful but don't work on all + ## platforms/compilers. Uncomment temporarily if you need them. + #'-Wfatal-errors', # stop after one error (unrelated to warnings) + #'-Werror', # turn warnings into errors + ] +else: + EXTRA_COMPILE_ARGS = [] + +if '_HPY_DEBUG_FORCE_DEFAULT_MEM_PROTECT' not in os.environ: + EXTRA_COMPILE_ARGS += ['-D_HPY_DEBUG_MEM_PROTECT_USEMMAP'] + +if platform.system() == "Windows": + EXTRA_COMPILE_ARGS += ['/WX'] +else: + EXTRA_COMPILE_ARGS += ['-Werror'] + + +def get_scm_config(): + """ + We use this function as a hook to generate version.h before building. + """ + import textwrap + import subprocess + import pathlib + import setuptools_scm + + version = setuptools_scm.get_version() + try: + gitrev = subprocess.check_output('git rev-parse --short HEAD'.split(), + encoding='utf-8') + gitrev = gitrev.strip() + except subprocess.CalledProcessError: + gitrev = "__UNKNOWN__" + + version_h = pathlib.Path('.').joinpath('hpy', 'devel', 'include', 'hpy', 'version.h') + version_h.write_text(textwrap.dedent(f""" + // automatically generated by setup.py:get_scm_config() + #define HPY_VERSION "{version}" + #define HPY_GIT_REVISION "{gitrev}" + """)) + + version_py = pathlib.Path('.').joinpath('hpy', 'devel', 'version.py') + version_py.write_text(textwrap.dedent(f""" + # automatically generated by setup.py:get_scm_config() + __version__ = "{version}" + __git_revision__ = "{gitrev}" + """)) + + return {} # use the default config + +HPY_EXTRA_SOURCES = [ + 'hpy/devel/src/runtime/argparse.c', + 'hpy/devel/src/runtime/buildvalue.c', + 'hpy/devel/src/runtime/format.c', + 'hpy/devel/src/runtime/helpers.c', + 'hpy/devel/src/runtime/structseq.c', +] + +HPY_CTX_SOURCES = [ + 'hpy/devel/src/runtime/ctx_bytes.c', + 'hpy/devel/src/runtime/ctx_call.c', + 'hpy/devel/src/runtime/ctx_capsule.c', + 'hpy/devel/src/runtime/ctx_err.c', + 'hpy/devel/src/runtime/ctx_eval.c', + 'hpy/devel/src/runtime/ctx_long.c', + 'hpy/devel/src/runtime/ctx_module.c', + 'hpy/devel/src/runtime/ctx_object.c', + 'hpy/devel/src/runtime/ctx_type.c', + 'hpy/devel/src/runtime/ctx_tracker.c', + 'hpy/devel/src/runtime/ctx_listbuilder.c', + 'hpy/devel/src/runtime/ctx_tuple.c', + 'hpy/devel/src/runtime/ctx_tuplebuilder.c', + 'hpy/devel/src/runtime/ctx_contextvar.c', +] + +HPY_INCLUDE_DIRS = [ + 'hpy/devel/include', + 'hpy/universal/src', + 'hpy/debug/src/include', + 'hpy/trace/src/include', +] + +HPY_EXTRA_UNIVERSAL_LIB_NAME = "hpy-extra-universal" +HPY_EXTRA_HYBRID_LIB_NAME = "hpy-extra-hybrid" +HPY_CTX_LIB_NAME = "hpy-ctx-cpython" + +HPY_BUILD_CLIB_ABI_ATTR = "hpy_abi" + +class build_clib_hpy(build_clib): + """ Special build_clib command for building HPy's static libraries defined + by 'STATIC_LIBS' below. The behavior differs in following points: + (1) Option 'force' is set such that static libs will always be renewed. + (2) Method 'get_library_names' always returns 'None'. This is because + we only use this command to build static libraries for testing. + That means, we only use them in-place. We don't need them for + linking here. + (3) This command consumes a custom build info key + HPY_BUILD_CLIB_ABI_ATTR that is used to create separate build + temp directories for each ABI. This is necessary to avoid + incorrect sharing of (temporary) build artifacts. + (4) This command will use the include directories from command + 'build_ext'. + """ + def finalize_options(self): + super().finalize_options() + # we overwrite the include dirs and use the ones from 'build_ext' + build_ext_includes = self.get_finalized_command('build_ext').include_dirs or [] + self.include_dirs = HPY_INCLUDE_DIRS + build_ext_includes + self.force = 1 + + def get_library_names(self): + # We only build static libraries for testing. We just use them + # in-place. We don't want that our extensions (i.e. 'hpy.universal' + # etc) link to these libs. + return None + + def build_libraries(self, libraries): + # we just inherit the 'inplace' option from 'build_ext' + build_ext = self.get_finalized_command('build_ext') + inplace = build_ext.inplace + if inplace: + # the inplace option requires to find the package directory + # using the build_py command for that + build_py = self.get_finalized_command('build_py') + lib_dir = os.path.abspath(build_py.get_package_dir('hpy.devel')) + else: + lib_dir = os.path.join(build_ext.build_lib, 'hpy', 'devel') + + import pathlib + for lib in libraries: + lib_name, build_info = lib + abi = build_info.get(HPY_BUILD_CLIB_ABI_ATTR) + # Call super's build_libraries with just one library in the list + # such that we can temporarily change the 'build_temp'. + orig_build_temp = self.build_temp + orig_build_clib = self.build_clib + self.build_temp = os.path.join(orig_build_temp, 'lib', abi) + self.build_clib = os.path.join(lib_dir, 'lib', abi) + # ensure that 'build_clib' directory exists + pathlib.Path(self.build_clib).mkdir(parents=True, exist_ok=True) + try: + super().build_libraries([lib]) + finally: + self.build_temp = orig_build_temp + self.build_clib = orig_build_clib + + +STATIC_LIBS = [(HPY_EXTRA_UNIVERSAL_LIB_NAME, + {'sources': HPY_EXTRA_SOURCES, + HPY_BUILD_CLIB_ABI_ATTR: 'universal', + 'macros': [('HPY_ABI_UNIVERSAL', None)]}), + (HPY_EXTRA_HYBRID_LIB_NAME, + {'sources': HPY_EXTRA_SOURCES, + HPY_BUILD_CLIB_ABI_ATTR: 'hybrid', + 'macros': [('HPY_ABI_HYBRID', None)]}), + (HPY_CTX_LIB_NAME, + {'sources': HPY_EXTRA_SOURCES + HPY_CTX_SOURCES, + HPY_BUILD_CLIB_ABI_ATTR: 'cpython', + 'macros': [('HPY_ABI_CPYTHON', None)]})] + +EXT_MODULES = [ + Extension('hpy.universal', + ['hpy/universal/src/hpymodule.c', + 'hpy/universal/src/ctx.c', + 'hpy/universal/src/ctx_meth.c', + 'hpy/universal/src/ctx_misc.c', + 'hpy/debug/src/debug_ctx.c', + 'hpy/debug/src/debug_ctx_cpython.c', + 'hpy/debug/src/debug_handles.c', + 'hpy/debug/src/dhqueue.c', + 'hpy/debug/src/memprotect.c', + 'hpy/debug/src/stacktrace.c', + 'hpy/debug/src/_debugmod.c', + 'hpy/debug/src/autogen_debug_wrappers.c', + 'hpy/trace/src/trace_ctx.c', + 'hpy/trace/src/_tracemod.c', + 'hpy/trace/src/autogen_trace_wrappers.c', + 'hpy/trace/src/autogen_trace_func_table.c'] + + HPY_EXTRA_SOURCES + + HPY_CTX_SOURCES, + include_dirs=HPY_INCLUDE_DIRS, + extra_compile_args=[ + # so we need to enable the HYBRID ABI in order to implement + # the legacy features + '-DHPY_ABI_HYBRID', + '-DHPY_DEBUG_ENABLE_UHPY_SANITY_CHECK', + '-DHPY_EMBEDDED_MODULES', + ] + EXTRA_COMPILE_ARGS + ) + ] + +DEV_REQUIREMENTS = [ + "pytest", + "pytest-xdist", + "filelock", +] + +setup( + name="hpy", + author='The HPy team', + author_email='hpy-dev@python.org', + url='https://hpyproject.org/', + license='MIT', + description='A better C API for Python', + long_description=LONG_DESCRIPTION, + long_description_content_type='text/markdown', + packages=['hpy.devel', 'hpy.debug', 'hpy.trace'], + include_package_data=True, + extras_require={ + "dev": DEV_REQUIREMENTS, + }, + libraries=STATIC_LIBS, + ext_modules=EXT_MODULES, + entry_points={ + "distutils.setup_keywords": [ + "hpy_ext_modules = hpy.devel:handle_hpy_ext_modules", + ], + }, + cmdclass={"build_clib": build_clib_hpy}, + use_scm_version=get_scm_config, + setup_requires=['setuptools_scm'], + install_requires=['setuptools>=64.0'], + python_requires='>=3.8', +) diff --git a/graalpython/hpy/test/__init__.py b/graalpython/hpy/test/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/check_py27_compat.py b/graalpython/hpy/test/check_py27_compat.py similarity index 67% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/check_py27_compat.py rename to graalpython/hpy/test/check_py27_compat.py index 3c15890655..1b85bc372a 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/check_py27_compat.py +++ b/graalpython/hpy/test/check_py27_compat.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """ Some of the files in this repo are used also by PyPy tests, which run on python2.7. diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/conftest.py b/graalpython/hpy/test/conftest.py similarity index 62% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/conftest.py rename to graalpython/hpy/test/conftest.py index 916169e287..01c5a61103 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/conftest.py +++ b/graalpython/hpy/test/conftest.py @@ -1,35 +1,11 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import os -import sys import pytest +import sys from .support import ExtensionCompiler, DefaultExtensionTemplate,\ PythonSubprocessRunner, HPyDebugCapture, make_hpy_abi_fixture -from hpy.debug.leakdetector import LeakDetector from pathlib import Path IS_VALGRIND_RUN = False + def pytest_addoption(parser): parser.addoption( "--compiler-v", action="http://github.com/store_true", @@ -56,27 +32,17 @@ def pytest_configure(config): config.addinivalue_line( "markers", "syncgc: Mark tests that rely on a synchronous GC." ) - config.addinivalue_line( - "markers", "tp_traverse: Mark tests that rely tp_traverse being called." - ) def pytest_runtest_setup(item): - if (sys.implementation.name in ["graalpy", "pypy"] and - "syncgc" in [mark.name for mark in item.iter_markers()]): - pytest.skip(f"cannot run syncgc test on {sys.implementation.name}") - if (sys.implementation.name in ["graalpy"] and - "tp_traverse" in [mark.name for mark in item.iter_markers()]): - pytest.skip(f"{sys.implementation.name} does not call tp_traverse") + if any(item.iter_markers(name="syncgc")): + if sys.implementation.name in ("pypy", "graalpy"): + pytest.skip("requires synchronous garbage collector") # this is the default set of hpy_abi for all the tests. Individual files and # classes can override it. -SELECTED_ABI_MODE = os.environ.get("TEST_HPY_ABI", None) -if SELECTED_ABI_MODE: - hpy_abi = make_hpy_abi_fixture([SELECTED_ABI_MODE]) -else: - hpy_abi = make_hpy_abi_fixture('default') +hpy_abi = make_hpy_abi_fixture('default') @pytest.fixture(scope='session') @@ -89,6 +55,7 @@ def leakdetector(hpy_abi): """ Automatically detect leaks when the hpy_abi == 'debug' """ + from hpy.debug.leakdetector import LeakDetector if 'debug' in hpy_abi: with LeakDetector() as ld: yield ld @@ -120,13 +87,6 @@ def compiler(request, tmpdir, hpy_devel, hpy_abi, ExtensionTemplate): ExtensionTemplate=ExtensionTemplate) -@pytest.fixture() -def skip_cpython_abi(hpy_abi): - # skip all tests in this class for CPython ABI mode - if hpy_abi == 'cpython': - pytest.skip() - - @pytest.fixture(scope="session") def fatal_exit_code(request): import sys diff --git a/graalpython/hpy/test/debug/__init__.py b/graalpython/hpy/test/debug/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_builder_invalid.py b/graalpython/hpy/test/debug/test_builder_invalid.py similarity index 82% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_builder_invalid.py rename to graalpython/hpy/test/debug/test_builder_invalid.py index 132a24cc64..ebe708c0e0 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_builder_invalid.py +++ b/graalpython/hpy/test/debug/test_builder_invalid.py @@ -1,31 +1,5 @@ -# MIT License -# -# Copyright (c) 2023, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - import pytest from hpy.debug.leakdetector import LeakDetector -from hpytest.support import HPyTest - -pytestmark = pytest.mark.skipif(not HPyTest.supports_debug_mode(), reason="debug mode not supported") @pytest.fixture def hpy_abi(): diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_charptr.py b/graalpython/hpy/test/debug/test_charptr.py similarity index 83% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_charptr.py rename to graalpython/hpy/test/debug/test_charptr.py index 4544ee92f9..cc1fb9406f 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_charptr.py +++ b/graalpython/hpy/test/debug/test_charptr.py @@ -1,47 +1,7 @@ -# Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# The Universal Permissive License (UPL), Version 1.0 -# -# Subject to the condition set forth below, permission is hereby granted to any -# person obtaining a copy of this software, associated documentation and/or -# data (collectively the "Software"), free of charge and under any and all -# copyright rights in the Software, and any and all patent rights owned or -# freely licensable by each licensor hereunder covering either (i) the -# unmodified Software as contributed to or provided by such licensor, or (ii) -# the Larger Works (as defined below), to deal in both -# -# (a) the Software, and -# -# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -# one is included with the Software each a "Larger Work" to which the Software -# is contributed by such licensors), -# -# without restriction, including without limitation the rights to copy, create -# derivative works of, display, perform, and distribute the Software and make, -# use, sell, offer for sale, import, export, have made, and have sold the -# Software and the Larger Work(s), and to sublicense the foregoing rights on -# either these or other terms. -# -# This license is subject to the following condition: -# -# The above copyright notice and either this complete permission notice or at a -# minimum a reference to the UPL must be included in all copies or substantial -# portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - import os import pytest -from hpytest.support import SUPPORTS_SYS_EXECUTABLE, SUPPORTS_MEM_PROTECTION, HPyTest - -pytestmark = pytest.mark.skipif(not HPyTest.supports_debug_mode(), reason="debug mode not supported") +import sys +from ..support import SUPPORTS_SYS_EXECUTABLE, SUPPORTS_MEM_PROTECTION, IS_GRAALPY # Tests detection of usage of char pointers associated with invalid already # closed handles. For now, the debug mode does not provide any hook for this @@ -54,7 +14,7 @@ def hpy_abi(): yield "debug" -@pytest.mark.xfail +@pytest.mark.skipif(IS_GRAALPY, reason="fails on GraalPy") @pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") def test_charptr_use_after_implicit_arg_handle_close(compiler, python_subprocess): mod = compiler.compile_module(""" @@ -112,7 +72,7 @@ def test_charptr_use_after_implicit_arg_handle_close(compiler, python_subprocess assert b"UnicodeDecodeError" in result.stderr -@pytest.mark.xfail +@pytest.mark.skipif(IS_GRAALPY, reason="fails on GraalPy") @pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") def test_charptr_use_after_handle_close(compiler, python_subprocess): mod = compiler.compile_module(""" @@ -164,7 +124,7 @@ def test_charptr_use_after_handle_close(compiler, python_subprocess): assert b"UnicodeDecodeError" in result.stderr -@pytest.mark.xfail +@pytest.mark.skipif(IS_GRAALPY, reason="transiently fails on GraalPy") @pytest.mark.skipif(not SUPPORTS_MEM_PROTECTION, reason= "Could be implemented by checking the contents on close.") @pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") @@ -235,7 +195,6 @@ def test_charptr_correct_usage(compiler): assert mod.f('I wont be leaked!') == 'I wont be leaked!'; -@pytest.mark.xfail def test_charptr_limit_stress_test(compiler): from hpy.universal import _debug mod = compiler.make_module(""" diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_context_reuse.py b/graalpython/hpy/test/debug/test_context_reuse.py similarity index 74% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_context_reuse.py rename to graalpython/hpy/test/debug/test_context_reuse.py index d6b6881adc..164505cf31 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_context_reuse.py +++ b/graalpython/hpy/test/debug/test_context_reuse.py @@ -1,36 +1,15 @@ -# MIT License -# -# Copyright (c) 2023, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - import pytest -from hpytest.support import HPyTest +import sys + +from ..support import IS_GRAALPY -pytestmark = pytest.mark.skipif(not HPyTest.supports_debug_mode(), reason="debug mode not supported") @pytest.fixture def hpy_abi(): return "debug" +@pytest.mark.skipif(IS_GRAALPY, reason="Hangs on GraalPy") def test_reuse_context_from_global_variable(compiler, python_subprocess): mod = compiler.compile_module(""" #include diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_handles_invalid.py b/graalpython/hpy/test/debug/test_handles_invalid.py similarity index 67% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_handles_invalid.py rename to graalpython/hpy/test/debug/test_handles_invalid.py index b05ac61bf9..355470c088 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_handles_invalid.py +++ b/graalpython/hpy/test/debug/test_handles_invalid.py @@ -1,48 +1,8 @@ -# Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# The Universal Permissive License (UPL), Version 1.0 -# -# Subject to the condition set forth below, permission is hereby granted to any -# person obtaining a copy of this software, associated documentation and/or -# data (collectively the "Software"), free of charge and under any and all -# copyright rights in the Software, and any and all patent rights owned or -# freely licensable by each licensor hereunder covering either (i) the -# unmodified Software as contributed to or provided by such licensor, or (ii) -# the Larger Works (as defined below), to deal in both -# -# (a) the Software, and -# -# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -# one is included with the Software each a "Larger Work" to which the Software -# is contributed by such licensors), -# -# without restriction, including without limitation the rights to copy, create -# derivative works of, display, perform, and distribute the Software and make, -# use, sell, offer for sale, import, export, have made, and have sold the -# Software and the Larger Work(s), and to sublicense the foregoing rights on -# either these or other terms. -# -# This license is subject to the following condition: -# -# The above copyright notice and either this complete permission notice or at a -# minimum a reference to the UPL must be included in all copies or substantial -# portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - import pytest +import sys from hpy.debug.leakdetector import LeakDetector -from hpytest.support import SUPPORTS_SYS_EXECUTABLE, IS_PYTHON_DEBUG_BUILD, GRAALPYTHON, HPyTest -from hpytest.conftest import IS_VALGRIND_RUN - -pytestmark = pytest.mark.skipif(not HPyTest.supports_debug_mode(), reason="debug mode not supported") +from ..support import SUPPORTS_SYS_EXECUTABLE, IS_PYTHON_DEBUG_BUILD, IS_GRAALPY +from ..conftest import IS_VALGRIND_RUN @pytest.fixture def hpy_abi(): @@ -50,6 +10,10 @@ def hpy_abi(): yield "debug" +@pytest.mark.skipif(sys.implementation.name == 'pypy', + reason="Cannot recover from use-after-close on pypy") +@pytest.mark.skipif(IS_GRAALPY, + reason="This corrupts process memory on GraalPy and crashes later") def test_no_invalid_handle(compiler, hpy_debug_capture): # Basic sanity check that valid code does not trigger any error reports mod = compiler.make_module(""" @@ -74,6 +38,10 @@ def test_no_invalid_handle(compiler, hpy_debug_capture): assert hpy_debug_capture.invalid_handles_count == 0 +@pytest.mark.skipif(sys.implementation.name == 'pypy', + reason="Cannot recover from use-after-close on pypy") +@pytest.mark.skipif(IS_GRAALPY, + reason="This corrupts process memory on GraalPy and crashes later") def test_cant_use_closed_handle(compiler, hpy_debug_capture): mod = compiler.make_module(""" HPyDef_METH(f, "f", HPyFunc_O, .doc="double close") @@ -143,18 +111,14 @@ def test_cant_use_closed_handle(compiler, hpy_debug_capture): assert hpy_debug_capture.invalid_handles_count == 4 mod.f_varargs('foo', 'bar') assert hpy_debug_capture.invalid_handles_count == 5 - if not GRAALPYTHON: - # GraalPython does not support this test because of the strict - # separation between universal adn debug context. The debug context - # still correctly detects the invalid handle access but later, the - # runtime will still try to close the argument handle and there is - # no means to propagate that information to the handle owner. - # Hence, an assertion will fail. - mod.h('baz') - assert hpy_debug_capture.invalid_handles_count == 6 - - -@pytest.mark.xfail(reason="graalpython does not prevent reuse of leaked handles for other handles and thus cannot always catch this") + mod.h('baz') + assert hpy_debug_capture.invalid_handles_count == 6 + + +@pytest.mark.skipif(sys.implementation.name == 'pypy', + reason="Cannot recover from use-after-close on pypy") +@pytest.mark.skipif(IS_GRAALPY, + reason="This corrupts process memory on GraalPy and crashes later") def test_keeping_and_reusing_argument_handle(compiler, hpy_debug_capture): mod = compiler.make_module(""" HPy keep; @@ -184,6 +148,7 @@ def test_keeping_and_reusing_argument_handle(compiler, hpy_debug_capture): assert hpy_debug_capture.invalid_handles_count == 1 +@pytest.mark.skipif(IS_GRAALPY, reason="Crashes on GraalPy") def test_return_ctx_constant_without_dup(compiler, python_subprocess, fatal_exit_code): # Since this puts the context->h_None into an inconsistent state, we run # this test in a subprocess and check fatal error instead @@ -205,6 +170,7 @@ def test_return_ctx_constant_without_dup(compiler, python_subprocess, fatal_exit assert b"Invalid usage of already closed handle" in result.stderr +@pytest.mark.skipif(IS_GRAALPY, reason="Crashes on GraalPy") def test_close_ctx_constant(compiler, python_subprocess, fatal_exit_code): # Since this puts the context->h_True into an inconsistent state, we run # this test in a subprocess and check fatal error instead @@ -227,7 +193,7 @@ def test_close_ctx_constant(compiler, python_subprocess, fatal_exit_code): assert b"Invalid usage of already closed handle" in result.stderr -@pytest.mark.xfail(reason="set_handle_stack_trace_limit not implemented yet") +@pytest.mark.skipif(IS_GRAALPY, reason="Crashes on GraalPy") def test_invalid_handle_crashes_python_if_no_hook(compiler, python_subprocess, fatal_exit_code): if not SUPPORTS_SYS_EXECUTABLE: pytest.skip("no sys.executable") diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_handles_leak.py b/graalpython/hpy/test/debug/test_handles_leak.py similarity index 80% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_handles_leak.py rename to graalpython/hpy/test/debug/test_handles_leak.py index d485532803..b0cca5f27a 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_handles_leak.py +++ b/graalpython/hpy/test/debug/test_handles_leak.py @@ -1,47 +1,5 @@ -# Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# The Universal Permissive License (UPL), Version 1.0 -# -# Subject to the condition set forth below, permission is hereby granted to any -# person obtaining a copy of this software, associated documentation and/or -# data (collectively the "Software"), free of charge and under any and all -# copyright rights in the Software, and any and all patent rights owned or -# freely licensable by each licensor hereunder covering either (i) the -# unmodified Software as contributed to or provided by such licensor, or (ii) -# the Larger Works (as defined below), to deal in both -# -# (a) the Software, and -# -# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -# one is included with the Software each a "Larger Work" to which the Software -# is contributed by such licensors), -# -# without restriction, including without limitation the rights to copy, create -# derivative works of, display, perform, and distribute the Software and make, -# use, sell, offer for sale, import, export, have made, and have sold the -# Software and the Larger Work(s), and to sublicense the foregoing rights on -# either these or other terms. -# -# This license is subject to the following condition: -# -# The above copyright notice and either this complete permission notice or at a -# minimum a reference to the UPL must be included in all copies or substantial -# portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - import pytest from hpy.debug import set_handle_stack_trace_limit, disable_handle_stack_traces -from hpytest.support import HPyTest - -pytestmark = pytest.mark.skipif(not HPyTest.supports_debug_mode(), reason="debug mode not supported") @pytest.fixture def hpy_abi(): diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_misc.py b/graalpython/hpy/test/debug/test_misc.py similarity index 80% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_misc.py rename to graalpython/hpy/test/debug/test_misc.py index f6d7672625..3640459798 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_misc.py +++ b/graalpython/hpy/test/debug/test_misc.py @@ -1,36 +1,13 @@ -# MIT License -# -# Copyright (c) 2023, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - import pytest -from hpytest.support import SUPPORTS_SYS_EXECUTABLE, SUPPORTS_MEM_PROTECTION, HPyTest - -pytestmark = pytest.mark.skipif(not HPyTest.supports_debug_mode(), reason="debug mode not supported") +import sys +from ..support import SUPPORTS_SYS_EXECUTABLE, SUPPORTS_MEM_PROTECTION, IS_GRAALPY @pytest.fixture def hpy_abi(): return "debug" +@pytest.mark.skipif(IS_GRAALPY, reason="hangs on GraalPy") @pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") def test_use_invalid_as_struct(compiler, python_subprocess): mod = compiler.compile_module(""" @@ -63,6 +40,7 @@ def test_use_invalid_as_struct(compiler, python_subprocess): assert "Invalid usage of _HPy_AsStruct_Object" in result.stderr.decode("utf-8") +@pytest.mark.skipif(IS_GRAALPY, reason="hangs on GraalPy") @pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") def test_typecheck(compiler, python_subprocess): mod = compiler.compile_module(""" @@ -85,10 +63,10 @@ def test_typecheck(compiler, python_subprocess): assert "HPy_TypeCheck arg 2 must be a type" in result.stderr.decode("utf-8") +@pytest.mark.skipif(IS_GRAALPY, reason="hangs on GraalPy") @pytest.mark.skipif(not SUPPORTS_MEM_PROTECTION, reason= "Could be implemented by checking the contents on close.") @pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") -@pytest.mark.skipif(not HPyTest.supports_debug_mode(), reason="debug mode not supported") def test_type_getname(compiler, python_subprocess): mod = compiler.compile_module(""" #define MODE_READ_ONLY 0 @@ -145,6 +123,7 @@ def test_type_getname(compiler, python_subprocess): assert result.returncode != 0 +@pytest.mark.skipif(IS_GRAALPY, reason="hangs on GraalPy") @pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") def test_type_issubtype(compiler, python_subprocess): mod = compiler.compile_module(""" @@ -169,6 +148,7 @@ def test_type_issubtype(compiler, python_subprocess): assert "HPyType_IsSubtype arg 1 must be a type" in result.stderr.decode("utf-8") +@pytest.mark.skipif(IS_GRAALPY, reason="transiently fails on GraalPy") @pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") def test_unicode_substring(compiler, python_subprocess): mod = compiler.compile_module(""" diff --git a/graalpython/hpy/test/hpy_devel/__init__.py b/graalpython/hpy/test/hpy_devel/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/graalpython/hpy/test/hpy_devel/test_abitag.py b/graalpython/hpy/test/hpy_devel/test_abitag.py new file mode 100644 index 0000000000..819763891b --- /dev/null +++ b/graalpython/hpy/test/hpy_devel/test_abitag.py @@ -0,0 +1,25 @@ +from hpy.devel.abitag import parse_ext_suffix, get_hpy_ext_suffix, HPY_ABI_TAG + +def test_parse_ext_suffix_ext(): + _, ext = parse_ext_suffix('.cpython-310-x86_64-linux-gnu.so') + assert ext == 'so' + +def test_parse_ext_suffix_abi_tag(): + def abi_tag(suffix): + tag, ext = parse_ext_suffix(suffix) + return tag + + assert abi_tag('.cpython-38-x86_64-linux-gnu.so') == 'cp38' + assert abi_tag('.cpython-38d-x86_64-linux-gnu.so') == 'cp38d' + assert abi_tag('.cpython-310-x86_64-linux-gnu.so') == 'cp310' + assert abi_tag('.cpython-310d-x86_64-linux-gnu.so') == 'cp310d' + assert abi_tag('.cpython-310-darwin.so') == 'cp310' + assert abi_tag('.cp310-win_amd64.pyd') == 'cp310' + assert abi_tag('.pypy38-pp73-x86_64-linux-gnu.so') == 'pypy38-pp73' + assert abi_tag('.graalpy-38-native-x86_64-darwin.dylib') == 'graalpy-38-native' + +def test_get_hpy_ext_suffix(): + get = get_hpy_ext_suffix + hpy0 = HPY_ABI_TAG + assert get('universal', '.cpython-38-x86_64-linux-gnu.so') == f'.{hpy0}.so' + assert get('hybrid', '.cpython-38-x86_64-linux-gnu.so') == f'.{hpy0}-cp38.so' diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/hpy_devel/test_distutils.py b/graalpython/hpy/test/hpy_devel/test_distutils.py similarity index 89% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/hpy_devel/test_distutils.py rename to graalpython/hpy/test/hpy_devel/test_distutils.py index 3d87a7d977..62904f0957 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/hpy_devel/test_distutils.py +++ b/graalpython/hpy/test/hpy_devel/test_distutils.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2023, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """ Test the hpy+distutils integration. Most of the relevant code is in hpy/devel/__init__.py. @@ -39,9 +16,7 @@ import py import pytest -from hpytest.support import atomic_run, HPY_ROOT - -pytestmark = pytest.mark.skip("not supported on GraalPy because of legacy distutils") +from ..support import atomic_run, HPY_ROOT, IS_GRAALPY # ====== IMPORTANT DEVELOPMENT TIP ===== # You can use py.test --reuse-venv to speed up local testing. @@ -68,7 +43,7 @@ def print_CalledProcessError(p): @pytest.fixture(scope='session') def venv_template(request, tmpdir_factory): - if request.config.option.reuse_venv: + if getattr(request.config.option, "reuse_venv", False): d = py.path.local('/tmp/venv-for-hpytest') if d.check(dir=True): # if it exists, we assume it's correct. If you want to recreate, @@ -84,7 +59,7 @@ def venv_template(request, tmpdir_factory): # it's just easier to use e.g. python -m pip attach_python_to_venv(d) for script in d.bin.listdir(): - if script.basename.startswith('python'): + if script.basename.startswith(('python', 'graalpy')): continue script.remove() # @@ -120,7 +95,7 @@ def initargs(self, pytestconfig, tmpdir, venv_template): self.tmpdir = tmpdir # create a fresh venv by copying the template self.venv = tmpdir.join('venv') - shutil.copytree(venv_template, self.venv) + shutil.copytree(venv_template, self.venv, symlinks=True) attach_python_to_venv(self.venv) # create the files for our test project self.hpy_test_project = tmpdir.join('hpy_test_project').ensure(dir=True) @@ -315,6 +290,7 @@ def test_hpymod_wheel(self, hpy_abi): doc = self.get_docstring('hpymod') assert doc == f'hpymod with HPy ABI: {hpy_abi}' + @pytest.mark.skipif(IS_GRAALPY, reason='not supported on GraalPy') def test_dont_mix_cpython_and_universal_abis(self): """ See issue #322 @@ -353,6 +329,8 @@ def test_dont_mix_cpython_and_universal_abis(self): def test_hpymod_legacy(self, hpy_abi): if hpy_abi == 'universal': pytest.skip('only for cpython and hybrid ABIs') + if IS_GRAALPY: + pytest.skip('not supported on GraalPy') self.gen_setup_py(""" setup(name = "hpy_test_project", hpy_ext_modules = [hpymod_legacy], diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/support.py b/graalpython/hpy/test/support.py similarity index 89% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/support.py rename to graalpython/hpy/test/support.py index 7711a08c31..d102e398e7 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/support.py +++ b/graalpython/hpy/test/support.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - import os, sys from filelock import FileLock import pytest @@ -31,8 +8,6 @@ import distutils PY2 = sys.version_info[0] == 2 -GRAALPYTHON = sys.implementation.name == 'graalpy' -DARWIN_NATIVE = sys.platform == 'darwin' HPY_ROOT = Path(__file__).parent.parent LOCK = FileLock(HPY_ROOT / ".hpy.lock") @@ -44,6 +19,8 @@ # True if we are running on the CPython debug build IS_PYTHON_DEBUG_BUILD = hasattr(sys, 'gettotalrefcount') +IS_GRAALPY = getattr(getattr(sys, "implementation", None), "name", None) == 'graalpy' + # pytest marker to run tests only on linux ONLY_LINUX = pytest.mark.skipif(sys.platform!='linux', reason='linux only') @@ -74,23 +51,19 @@ def make_hpy_abi_fixture(ABIs, class_fixture=False): class TestFoo(HPyTest): hpy_abi = make_hpy_abi_fixture('with hybrid', class_fixture=True) """ - if ABIs == 'default': - ABIs = ['cpython', 'universal', 'debug'] - elif ABIs == 'with hybrid': - ABIs = ['cpython', 'hybrid', 'hybrid+debug'] - elif isinstance(ABIs, list): + is_cpython = not hasattr(sys, "implementation") or sys.implementation.name == 'cpython' + if isinstance(ABIs, list): pass else: - raise ValueError("ABIs must be 'default', 'with hybrid' " - "or a list of strings. Got: %s" % ABIs) - - # GraalPy only supports the debug mode if running native - if not GRAALPYTHON: - if 'debug' in ABIs: - ABIs.remove('debug') - elif 'hybrid+debug' in ABIs: - ABIs.remove('hybrid+debug') - + if ABIs == 'default': + ABIs = ['universal', 'debug'] + elif ABIs == 'with hybrid': + ABIs = ['hybrid', 'hybrid+debug'] + else: + raise ValueError("ABIs must be 'default', 'with hybrid' " + "or a list of strings. Got: %s" % ABIs) + if is_cpython: + ABIs.append('cpython') if class_fixture: @pytest.fixture(params=ABIs) def hpy_abi(self, request): @@ -284,7 +257,6 @@ def __init__(self, tmpdir, hpy_devel, hpy_abi, compiler_verbose=False, self.compiler_verbose = compiler_verbose self.ExtensionTemplate = ExtensionTemplate self.extra_include_dirs = extra_include_dirs - self._sysconfig_universal = None def _expand(self, ExtensionTemplate, name, template): source = ExtensionTemplate(template, name).expand() @@ -337,8 +309,7 @@ def compile_module(self, main_src, ExtensionTemplate=None, name='mytest', extra_ ] else: compile_args = [ - '-g', # TRUFFLE CHANGE: we removed '-O0' for mem2reg opt - '-Wno-gnu-variable-sized-type-not-at-end', + '-g', '-O0', '-Wfatal-errors', # stop after one error (unrelated to warnings) '-Werror', # turn warnings into errors (all, for now) ] @@ -472,6 +443,7 @@ def run(self, mod, code): @pytest.mark.usefixtures('initargs') class HPyTest: + is_graalpy = IS_GRAALPY # Exposed here for tests running as PyPy apptests ExtensionTemplate = DefaultExtensionTemplate @pytest.fixture() @@ -529,28 +501,6 @@ def supports_ordinary_make_module_imports(self): """ return True - @staticmethod - def supports_debug_mode(): - """ Returns True if the underlying Python implementation supports - the debug mode. - """ - from hpy.universal import _debug - try: - return _debug.get_open_handles() is not None - except: - return False - - @staticmethod - def supports_trace_mode(): - """ Returns True if the underlying Python implementation supports - the trace mode. - """ - from hpy.universal import _trace - try: - return _trace.get_call_counts() is not None - except: - return False - class HPyDebugCapture: """ @@ -619,7 +569,7 @@ def _build(tmpdir, ext, hpy_devel, hpy_abi, compiler_verbose=0, debug=None): dist.hpy_abi = hpy_abi # For testing, we want to use static libs to avoid repeated compilation # of the same sources which slows down testing. - dist.hpy_use_static_libs = False + dist.hpy_use_static_libs = True dist.hpy_ext_modules = [ext] # We need to explicitly specify which Python modules we expect because some # test cases create several distributions in the same temp directory. diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_00_basic.py b/graalpython/hpy/test/test_00_basic.py similarity index 94% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_00_basic.py rename to graalpython/hpy/test/test_00_basic.py index f3ac32a6b4..7fc483407e 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_00_basic.py +++ b/graalpython/hpy/test/test_00_basic.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """ NOTE: this tests are also meant to be run as PyPy "applevel" tests. @@ -31,7 +8,6 @@ """ from .support import HPyTest from hpy.devel.abitag import HPY_ABI_VERSION, HPY_ABI_VERSION_MINOR -import shutil class TestBasic(HPyTest): @@ -71,6 +47,7 @@ def test_abi_version_check(self): assert False, "Expected exception" def test_abi_tag_check(self): + import shutil if self.compiler.hpy_abi != 'universal': return @@ -285,6 +262,7 @@ def test_builtin_handles(self): case 20: h = ctx->h_MemoryViewType; break; case 21: h = ctx->h_SliceType; break; case 22: h = ctx->h_Builtins; break; + case 23: h = ctx->h_DictType; break; case 2048: h = ctx->h_CapsuleType; break; default: HPyErr_SetString(ctx, ctx->h_ValueError, "invalid choice"); @@ -301,7 +279,7 @@ def test_builtin_handles(self): '', None, False, True, ValueError, TypeError, IndexError, SystemError, object, type, bool, int, float, str, tuple, list, NotImplemented, Ellipsis, complex, bytes, memoryview, slice, - builtins.__dict__ + builtins.__dict__, dict ) for i, obj in enumerate(builtin_objs): if i == 0: @@ -583,3 +561,20 @@ def test_leave_python(self): @INIT """) assert mod.f("abraka") == 3 + + def test_dup_null(self): + mod = self.make_module(""" + HPyDef_METH(f, "f", HPyFunc_NOARGS) + static HPy f_impl(HPyContext *ctx, HPy self) + { + HPy h = HPy_Dup(ctx, HPy_NULL); + if (HPy_IsNull(h)) { + return HPyLong_FromSize_t(ctx, 0); + } + HPy_Close(ctx, h); + return HPyLong_FromSize_t(ctx, -1); + } + @EXPORT(f) + @INIT + """) + assert mod.f() == 0 diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_argparse.py b/graalpython/hpy/test/test_argparse.py similarity index 94% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_argparse.py rename to graalpython/hpy/test/test_argparse.py index d6f985457a..55bdd31c6d 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_argparse.py +++ b/graalpython/hpy/test/test_argparse.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """ NOTE: this tests are also meant to be run as PyPy "applevel" tests. @@ -29,7 +6,6 @@ to be able to use e.g. pytest.raises (which on PyPy will be implemented by a "fake pytest module") """ -import pytest from .support import HPyTest @@ -99,7 +75,7 @@ def test_s(self): "function a str is required" ) - def test_B(self): + def test_upper_b(self): mod = self.make_parse_item("B", "char", "char_to_hpybytes") assert mod.f(0) == b"\x00" assert mod.f(1) == b"\x01" @@ -126,7 +102,7 @@ def test_h(self): "function signed short integer is less than minimum" ) - def test_H_short(self): + def test_upper_h_short(self): mod = self.make_parse_item("H", "short", "HPyLong_FromLong") assert mod.f(0) == 0 assert mod.f(1) == 1 @@ -138,7 +114,7 @@ def test_H_short(self): assert mod.f(2**16) == 0 assert mod.f(-2**16) == 0 - def test_H_unsigned_short(self): + def test_upper_h_unsigned_short(self): mod = self.make_parse_item( "H", "unsigned short", "HPyLong_FromUnsignedLong" ) @@ -171,7 +147,7 @@ def test_i(self): "Python int too large to convert to C long", # where sizeof(long) == 4 ) - def test_I_signed(self): + def test_upper_i_signed(self): mod = self.make_parse_item("I", "int", "HPyLong_FromLong") assert mod.f(0) == 0 assert mod.f(1) == 1 @@ -183,7 +159,7 @@ def test_I_signed(self): assert mod.f(2**32) == 0 assert mod.f(-2**32) == 0 - def test_I_unsigned(self): + def test_upper_i_unsigned(self): mod = self.make_parse_item( "I", "unsigned int", "HPyLong_FromUnsignedLong" ) @@ -235,7 +211,7 @@ def test_k_unsigned(self): assert mod.f(2**ULONG_BITS) == 0 assert mod.f(-2**ULONG_BITS) == 0 - def test_L(self): + def test_upper_l(self): import pytest mod = self.make_parse_item("L", "long long", "HPyLong_FromLongLong") assert mod.f(0) == 0 @@ -248,7 +224,7 @@ def test_L(self): with pytest.raises(OverflowError): mod.f(-2**63 - 1) - def test_K_signed(self): + def test_upper_k_signed(self): mod = self.make_parse_item("K", "long long", "HPyLong_FromLongLong") assert mod.f(0) == 0 assert mod.f(1) == 1 @@ -260,7 +236,7 @@ def test_K_signed(self): assert mod.f(2**64) == 0 assert mod.f(-2**64) == 0 - def test_K_unsigned(self): + def test_upper_k_unsigned(self): mod = self.make_parse_item( "K", "unsigned long long", "HPyLong_FromUnsignedLongLong" ) @@ -301,7 +277,7 @@ def test_d(self): with pytest.raises(TypeError): mod.f("x") - def test_O(self): + def test_upper_o(self): mod = self.make_parse_item("O", "HPy", "HPy_Dup") assert mod.f("a") == "a" assert mod.f(5) == 5 diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_call.py b/graalpython/hpy/test/test_call.py similarity index 90% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_call.py rename to graalpython/hpy/test/test_call.py index 64468160ef..3702063946 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_call.py +++ b/graalpython/hpy/test/test_call.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2021, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - from .support import HPyTest @@ -241,9 +218,8 @@ def __getitem__(self, key): mod.call(dict) # dict subclass for keywords - # TODO(fa): GR-47126 - # kwdict = KwDict(x=11, y=12, z=13) - # assert mod.call(dict, **kwdict) == dict(kwdict) + kwdict = KwDict(x=11, y=12, z=13) + assert mod.call(dict, **kwdict) == dict(kwdict) with pytest.raises(ValueError): mod.call(foo) diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_capsule.py b/graalpython/hpy/test/test_capsule.py similarity index 93% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_capsule.py rename to graalpython/hpy/test/test_capsule.py index 3f0b7b683a..546b264f01 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_capsule.py +++ b/graalpython/hpy/test/test_capsule.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2022, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """ NOTE: these tests are also meant to be run as PyPy "applevel" tests. @@ -179,6 +156,7 @@ class TestHPyCapsule(HPyTest): ExtensionTemplate = CapsuleTemplate def test_capsule_new(self): + import pytest mod = self.make_module(""" @DEFINE_SomeObject @DEFINE_Capsule_New @@ -200,8 +178,8 @@ def test_capsule_new(self): with pytest.raises(ValueError): mod.capsule_new() - @pytest.mark.skip def test_capsule_getter_and_setter(self): + import pytest mod = self.make_module(""" #include @@ -409,6 +387,7 @@ def test_capsule_getter_and_setter(self): mod.capsule_freename(p) def test_capsule_isvalid(self): + import pytest mod = self.make_module(""" @DEFINE_SomeObject @DEFINE_Capsule_New @@ -479,6 +458,7 @@ def test_capsule_new_with_destructor(self): assert mod.pointer_freed() def test_capsule_new_with_invalid_destructor(self): + import pytest mod = self.make_module(""" static HPyCapsule_Destructor mydtor = { NULL, NULL }; diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_capsule_legacy.py b/graalpython/hpy/test/test_capsule_legacy.py similarity index 71% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_capsule_legacy.py rename to graalpython/hpy/test/test_capsule_legacy.py index 364baa3f13..ed4a0ba936 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_capsule_legacy.py +++ b/graalpython/hpy/test/test_capsule_legacy.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2023, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - import pytest from .support import HPyTest, make_hpy_abi_fixture from .test_capsule import CapsuleTemplate diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_contextvar.py b/graalpython/hpy/test/test_contextvar.py similarity index 61% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_contextvar.py rename to graalpython/hpy/test/test_contextvar.py index 88558b7ee3..dec376a256 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_contextvar.py +++ b/graalpython/hpy/test/test_contextvar.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2023, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """ NOTE: this tests are also meant to be run as PyPy "applevel" tests. diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_cpy_compat.py b/graalpython/hpy/test/test_cpy_compat.py similarity index 80% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_cpy_compat.py rename to graalpython/hpy/test/test_cpy_compat.py index 3c1142a4a3..8151be0dd9 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_cpy_compat.py +++ b/graalpython/hpy/test/test_cpy_compat.py @@ -1,27 +1,5 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -from .support import HPyTest, make_hpy_abi_fixture +import pytest +from .support import HPyTest, make_hpy_abi_fixture, IS_GRAALPY class TestCPythonCompatibility(HPyTest): @@ -53,6 +31,7 @@ def test_abi(self): expected = 'hybrid' assert hpy_abi == expected + @pytest.mark.skipif(IS_GRAALPY, reason="Crashes on GraalPy") def test_frompyobject(self): mod = self.make_module(""" #include @@ -60,9 +39,9 @@ def test_frompyobject(self): static HPy f_impl(HPyContext *ctx, HPy self) { PyObject *o = PyList_New(0); - Py_ssize_t initial_refcount = Py_REFCNT(o); + Py_ssize_t initial_refcount = o->ob_refcnt; HPy h = HPy_FromPyObject(ctx, o); - Py_ssize_t final_refcount = Py_REFCNT(o); + Py_ssize_t final_refcount = o->ob_refcnt; PyList_Append(o, PyLong_FromLong(1234)); PyList_Append(o, PyLong_FromSsize_t(final_refcount - @@ -155,6 +134,7 @@ def foo(self): obj = MyClass() assert mod.f(obj) == 1234 + @pytest.mark.skipif(IS_GRAALPY, reason="Crashes on GraalPy") def test_hpy_close(self): mod = self.make_module(""" #include @@ -164,9 +144,9 @@ def test_hpy_close(self): PyObject *o = PyList_New(0); HPy h = HPy_FromPyObject(ctx, o); - Py_ssize_t initial_refcount = Py_REFCNT(o); + Py_ssize_t initial_refcount = o->ob_refcnt; HPy_Close(ctx, h); - Py_ssize_t final_refcount = Py_REFCNT(o); + Py_ssize_t final_refcount = o->ob_refcnt; Py_DECREF(o); return HPyLong_FromLong(ctx, (long)(final_refcount - @@ -179,6 +159,7 @@ def test_hpy_close(self): if self.supports_refcounts(): assert x == -1 + @pytest.mark.skipif(IS_GRAALPY, reason="Crashes on GraalPy") def test_hpy_dup(self): mod = self.make_module(""" #include @@ -188,9 +169,9 @@ def test_hpy_dup(self): PyObject *o = PyList_New(0); HPy h = HPy_FromPyObject(ctx, o); - Py_ssize_t initial_refcount = Py_REFCNT(o); + Py_ssize_t initial_refcount = o->ob_refcnt; HPy h2 = HPy_Dup(ctx, h); - Py_ssize_t final_refcount = Py_REFCNT(o); + Py_ssize_t final_refcount = o->ob_refcnt; HPy_Close(ctx, h); HPy_Close(ctx, h2); @@ -205,6 +186,7 @@ def test_hpy_dup(self): if self.supports_refcounts(): assert x == +1 + @pytest.mark.skipif(IS_GRAALPY, reason="Crashes on GraalPy") def test_many_handles(self): mod = self.make_module(""" #include @@ -219,7 +201,7 @@ def test_many_handles(self): Py_ssize_t result = -42; HPy handles[NUM_HANDLES]; int i; - Py_ssize_t initial_refcount = Py_REFCNT(o); + Py_ssize_t initial_refcount = o->ob_refcnt; for (i = 0; i < NUM_HANDLES; i++) handles[i] = HPy_FromPyObject(ctx, o); for (i = 0; i < NUM_HANDLES; i++) @@ -227,7 +209,7 @@ def test_many_handles(self): goto error; for (i = 0; i < NUM_HANDLES; i++) HPy_Close(ctx, handles[i]); - final_refcount = Py_REFCNT(o); + final_refcount = o->ob_refcnt; result = final_refcount - initial_refcount; error: diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_eval.py b/graalpython/hpy/test/test_eval.py similarity index 71% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_eval.py rename to graalpython/hpy/test/test_eval.py index d019012245..441c0ab838 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_eval.py +++ b/graalpython/hpy/test/test_eval.py @@ -1,32 +1,9 @@ -# MIT License -# -# Copyright (c) 2023, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -from textwrap import dedent from .support import HPyTest class TestEval(HPyTest): def test_compile(self): import pytest + from textwrap import dedent mod = self.make_module(""" HPyDef_METH(f, "f", HPyFunc_VARARGS) static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_helpers.py b/graalpython/hpy/test/test_helpers.py similarity index 81% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_helpers.py rename to graalpython/hpy/test/test_helpers.py index 5fa41a8524..d16e4632eb 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_helpers.py +++ b/graalpython/hpy/test/test_helpers.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2021, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """ NOTE: this tests are also meant to be run as PyPy "applevel" tests. diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpybuildvalue.py b/graalpython/hpy/test/test_hpybuildvalue.py similarity index 81% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpybuildvalue.py rename to graalpython/hpy/test/test_hpybuildvalue.py index dc6e468c5a..059a39ed1c 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpybuildvalue.py +++ b/graalpython/hpy/test/test_hpybuildvalue.py @@ -1,42 +1,3 @@ -# Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# The Universal Permissive License (UPL), Version 1.0 -# -# Subject to the condition set forth below, permission is hereby granted to any -# person obtaining a copy of this software, associated documentation and/or -# data (collectively the "Software"), free of charge and under any and all -# copyright rights in the Software, and any and all patent rights owned or -# freely licensable by each licensor hereunder covering either (i) the -# unmodified Software as contributed to or provided by such licensor, or (ii) -# the Larger Works (as defined below), to deal in both -# -# (a) the Software, and -# -# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -# one is included with the Software each a "Larger Work" to which the Software -# is contributed by such licensors), -# -# without restriction, including without limitation the rights to copy, create -# derivative works of, display, perform, and distribute the Software and make, -# use, sell, offer for sale, import, export, have made, and have sold the -# Software and the Larger Work(s), and to sublicense the foregoing rights on -# either these or other terms. -# -# This license is subject to the following condition: -# -# The above copyright notice and either this complete permission notice or at a -# minimum a reference to the UPL must be included in all copies or substantial -# portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -import pytest from .support import HPyTest @@ -137,7 +98,7 @@ def test_bad_formats(self): for i, (code, expected_error) in enumerate(test_cases): with pytest.raises(SystemError) as e: mod.f(i) - assert expected_error in str(e.value), code + assert expected_error in str(e), code def test_O_and_aliases(self): mod = self.make_module(""" @@ -215,11 +176,11 @@ def test_O_with_null(self): for i in [0, 1]: with pytest.raises(ValueError) as e: mod.with_msg(i) - assert "Some err msg that will be asserted" in str(e.value) + assert "Some err msg that will be asserted" in str(e) for i in [0, 1]: with pytest.raises(SystemError) as e: mod.no_msg(i) - assert 'HPy_NULL object passed to HPy_BuildValue' in str(e.value) + assert 'HPy_NULL object passed to HPy_BuildValue' in str(e) def test_OO_pars_with_new_objects(self): diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpybytes.py b/graalpython/hpy/test/test_hpybytes.py similarity index 79% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpybytes.py rename to graalpython/hpy/test/test_hpybytes.py index 3068d26c81..c713bcb97a 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpybytes.py +++ b/graalpython/hpy/test/test_hpybytes.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - from .support import HPyTest class TestBytes(HPyTest): diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpydict.py b/graalpython/hpy/test/test_hpydict.py similarity index 76% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpydict.py rename to graalpython/hpy/test/test_hpydict.py index 23ee585184..64d0fb792d 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpydict.py +++ b/graalpython/hpy/test/test_hpydict.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - from .support import HPyTest class TestDict(HPyTest): diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyerr.py b/graalpython/hpy/test/test_hpyerr.py similarity index 96% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyerr.py rename to graalpython/hpy/test/test_hpyerr.py index d036216569..20426aaa31 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyerr.py +++ b/graalpython/hpy/test/test_hpyerr.py @@ -1,28 +1,5 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - import pytest -from .support import HPyTest, SUPPORTS_SYS_EXECUTABLE, trampoline +from .support import HPyTest, SUPPORTS_SYS_EXECUTABLE, trampoline, IS_GRAALPY class TestErr(HPyTest): @@ -41,6 +18,7 @@ def test_NoMemory(self): with pytest.raises(MemoryError): mod.f() + @pytest.mark.skipif(IS_GRAALPY, reason="Fails transiently on GraalPy especially with xdist") def test_FatalError(self, python_subprocess, fatal_exit_code): mod = self.compile_module(""" HPyDef_METH(f, "f", HPyFunc_NOARGS) @@ -696,6 +674,7 @@ def do_not_raise_exception(*args): with pytest.raises(DummyException): mod.f(raise_exception, (DummyException, ), exc_types) + @pytest.mark.skipif(IS_GRAALPY, reason="Fails transiently on GraalPy especially with xdist") def test_HPyErr_WriteUnraisable(self, python_subprocess): mod = self.compile_module(""" HPyDef_METH(f, "f", HPyFunc_NOARGS) diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyfield.py b/graalpython/hpy/test/test_hpyfield.py similarity index 87% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyfield.py rename to graalpython/hpy/test/test_hpyfield.py index 82a9997637..5e67515a13 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyfield.py +++ b/graalpython/hpy/test/test_hpyfield.py @@ -1,42 +1,3 @@ -# Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# The Universal Permissive License (UPL), Version 1.0 -# -# Subject to the condition set forth below, permission is hereby granted to any -# person obtaining a copy of this software, associated documentation and/or -# data (collectively the "Software"), free of charge and under any and all -# copyright rights in the Software, and any and all patent rights owned or -# freely licensable by each licensor hereunder covering either (i) the -# unmodified Software as contributed to or provided by such licensor, or (ii) -# the Larger Works (as defined below), to deal in both -# -# (a) the Software, and -# -# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -# one is included with the Software each a "Larger Work" to which the Software -# is contributed by such licensors), -# -# without restriction, including without limitation the rights to copy, create -# derivative works of, display, perform, and distribute the Software and make, -# use, sell, offer for sale, import, export, have made, and have sold the -# Software and the Larger Work(s), and to sublicense the foregoing rights on -# either these or other terms. -# -# This license is subject to the following condition: -# -# The above copyright notice and either this complete permission notice or at a -# minimum a reference to the UPL must be included in all copies or substantial -# portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """ NOTE: these tests are also meant to be run as PyPy "applevel" tests. @@ -183,9 +144,10 @@ def test_gc_track_no_gc_flag(self): p = mod.Pair("hello", "world") assert not gc.is_tracked(p) - @pytest.mark.tp_traverse def test_tp_traverse(self): - import sys + if self.is_graalpy: + import pytest + pytest.skip("Crashes on GraalPy") import gc mod = self.make_module(""" @DEFINE_PairObject @@ -347,8 +309,10 @@ def count_pairs(): gc.collect() assert count_pairs() == 0 - @pytest.mark.syncgc def test_tp_finalize(self): + if self.is_graalpy: + import pytest + pytest.skip("Crashes on GraalPy") # Tests the contract of tp_finalize: what it should see # if called from within HPyField_Store mod = self.make_module(""" @@ -367,6 +331,7 @@ def test_tp_finalize(self): // nicely with pytest, but if the finalizer gets called after the // test has finished, we have no choice but to abort to signal // the error + static void on_unexpected_finalize_call(void); static void on_unexpected_finalize_call() { if (test_finished) abort(); diff --git a/graalpython/hpy/test/test_hpyglobal.py b/graalpython/hpy/test/test_hpyglobal.py new file mode 100644 index 0000000000..238e6aa7fc --- /dev/null +++ b/graalpython/hpy/test/test_hpyglobal.py @@ -0,0 +1,38 @@ +""" +NOTE: this tests are also meant to be run as PyPy "applevel" tests. + +This means that global imports will NOT be visible inside the test +functions. In particular, you have to "import pytest" inside the test in order +to be able to use e.g. pytest.raises (which on PyPy will be implemented by a +"fake pytest module") +""" +from .support import HPyTest + + +class TestHPyGlobal(HPyTest): + + def test_basics(self): + mod = self.make_module(""" + HPyGlobal myglobal; + + HPyDef_METH(setg, "setg", HPyFunc_O) + static HPy setg_impl(HPyContext *ctx, HPy self, HPy arg) + { + HPyGlobal_Store(ctx, &myglobal, arg); + return HPy_Dup(ctx, ctx->h_None); + } + + HPyDef_METH(getg, "getg", HPyFunc_NOARGS) + static HPy getg_impl(HPyContext *ctx, HPy self) + { + return HPyGlobal_Load(ctx, myglobal); + } + + @EXPORT(setg) + @EXPORT(getg) + @EXPORT_GLOBAL(myglobal) + @INIT + """) + obj = {'hello': 'world'} + assert mod.setg(obj) is None + assert mod.getg() is obj diff --git a/graalpython/hpy/test/test_hpyimport.py b/graalpython/hpy/test/test_hpyimport.py new file mode 100644 index 0000000000..7bb922c807 --- /dev/null +++ b/graalpython/hpy/test/test_hpyimport.py @@ -0,0 +1,24 @@ +from .support import HPyTest + +class TestImport(HPyTest): + + def test_ImportModule(self): + import pytest + import sys + mod = self.make_module(""" + HPyDef_METH(f, "f", HPyFunc_O) + static HPy f_impl(HPyContext *ctx, HPy self, HPy h_name) + { + // we use bytes because ATM we don't have HPyUnicode_AsUTF8 or similar + const char *name = HPyBytes_AsString(ctx, h_name); + if (name == NULL) + return HPy_NULL; + return HPyImport_ImportModule(ctx, name); + } + @EXPORT(f) + @INIT + """) + sys2 = mod.f(b'sys') + assert sys is sys2 + with pytest.raises(ImportError): + mod.f(b'This is the name of a module which does not exist, hopefully') diff --git a/graalpython/hpy/test/test_hpyiter.py b/graalpython/hpy/test/test_hpyiter.py new file mode 100644 index 0000000000..58387253f9 --- /dev/null +++ b/graalpython/hpy/test/test_hpyiter.py @@ -0,0 +1,90 @@ +from .support import HPyTest + +class TestIter(HPyTest): + + def test_Check(self): + mod = self.make_module(""" + HPyDef_METH(f, "f", HPyFunc_O) + static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) + { + if (HPyIter_Check(ctx, arg)) + return HPy_Dup(ctx, ctx->h_True); + return HPy_Dup(ctx, ctx->h_False); + } + @EXPORT(f) + @INIT + """) + + class CustomIterable: + def __init__(self): + self._iter = iter([1, 2, 3]) + + def __iter__(self): + return self._iter + + class CustomIterator: + def __init__(self): + self._iter = iter([1, 2, 3]) + + def __iter__(self): + return self._iter + + def __next__(self): + return next(self._iter) + + assert mod.f(object()) is False + assert mod.f(10) is False + + assert mod.f((1, 2)) is False + assert mod.f(iter((1, 2))) is True + + assert mod.f([]) is False + assert mod.f(iter([])) is True + + assert mod.f('hello') is False + assert mod.f(iter('hello')) is True + + assert mod.f(map(int, ("1", "2"))) is True + assert mod.f(range(1, 10)) is False + + assert mod.f(CustomIterable()) is False + assert mod.f(iter(CustomIterable())) is True + assert mod.f(CustomIterator()) is True + + def test_Next(self): + mod = self.make_module(""" + HPyDef_METH(f, "f", HPyFunc_O) + static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) + { + HPy result = HPyIter_Next(ctx, arg); + int is_null = HPy_IsNull(result); + + if (is_null && HPyErr_Occurred(ctx)) + return HPy_NULL; + if (is_null) + return HPyErr_SetObject(ctx, ctx->h_StopIteration, ctx->h_None); + return result; + } + @EXPORT(f) + @INIT + """) + + class CustomIterator: + def __init__(self): + self._iter = iter(["a", "b", "c"]) + + def __iter__(self): + return self._iter + + def __next__(self): + return next(self._iter) + + assert mod.f(iter([3, 2, 1])) == 3 + assert mod.f((i for i in range(1, 10))) == 1 + assert mod.f(CustomIterator()) == "a" + + import pytest + with pytest.raises(StopIteration): + assert mod.f(iter([])) + + diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpylist.py b/graalpython/hpy/test/test_hpylist.py similarity index 65% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpylist.py rename to graalpython/hpy/test/test_hpylist.py index 1c3eaa1d96..42270cdc6d 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpylist.py +++ b/graalpython/hpy/test/test_hpylist.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - from .support import HPyTest class TestList(HPyTest): @@ -98,3 +75,38 @@ def test_ListBuilder(self): @INIT """) assert mod.f("xy") == ["xy", True, -42] + + def test_Insert(self): + import pytest + mod = self.make_module(""" + HPyDef_METH(f, "f", HPyFunc_VARARGS) + static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) + { + HPy_ssize_t index; + if (nargs != 3) { + HPyErr_SetString(ctx, ctx->h_ValueError, "expected exactly three arguments"); + return HPy_NULL; + } + index = HPyLong_AsSsize_t(ctx, args[1]); + if (index == -1 && HPyErr_Occurred(ctx)) { + return HPy_NULL; + } + if (HPyList_Insert(ctx, args[0], index, args[2]) == -1) + return HPy_NULL; + return HPy_Dup(ctx, args[0]); + } + @EXPORT(f) + @INIT + """) + l = [] + assert mod.f(l, 0, 0) == [0] + l = [] + assert mod.f(l, -1, 0) == [0] + l = [1, 2, 4] + assert mod.f(l, 0, 0) == [0, 1, 2, 4] + assert mod.f(l, -1, 3) == [0, 1, 2, 3, 4] + assert mod.f(l, -3, 1.5) == [0, 1, 1.5, 2, 3, 4] + assert mod.f(l, 1000, 5) == [0, 1, 1.5, 2, 3, 4, 5] + assert mod.f(l, -1000, -1) == [-1, 0, 1, 1.5, 2, 3, 4, 5] + with pytest.raises(SystemError): + mod.f(None, 0, 0) diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpylong.py b/graalpython/hpy/test/test_hpylong.py similarity index 93% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpylong.py rename to graalpython/hpy/test/test_hpylong.py index 6a63d23428..5900ab2843 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpylong.py +++ b/graalpython/hpy/test/test_hpylong.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - from .support import HPyTest, DefaultExtensionTemplate class HPyLongTemplate(DefaultExtensionTemplate): diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpymodule.py b/graalpython/hpy/test/test_hpymodule.py similarity index 88% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpymodule.py rename to graalpython/hpy/test/test_hpymodule.py index db44fdd9cf..5b675c98df 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpymodule.py +++ b/graalpython/hpy/test/test_hpymodule.py @@ -1,28 +1,3 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import types -import pytest from .support import HPyTest class TestModule(HPyTest): @@ -116,6 +91,7 @@ def test_HPyModule_custom_create_returns_non_module(self): runtime and the extension can only populate that module object in the init slots. """ + import types mod = self.make_module(""" HPyDef_SLOT(create, HPy_mod_create) static HPy create_impl(HPyContext *ctx, HPy spec) @@ -127,7 +103,7 @@ def test_HPyModule_custom_create_returns_non_module(self): return HPy_NULL; ns_type = HPy_GetAttr_s(ctx, types, "SimpleNamespace"); - if (HPy_IsNull(types)) + if (HPy_IsNull(ns_type)) goto cleanup; dict = HPyDict_New(ctx); HPy_SetItem_s(ctx, dict, "spec", spec); @@ -167,6 +143,7 @@ def test_HPyModule_error_when_create_returns_module(self): there are any actual use-cases, the purpose of the 'create' slot is to create non-builtin-module objects. """ + import pytest expected_message = "HPy_mod_create slot returned a builtin module " \ "object. This is currently not supported." with pytest.raises(SystemError, match=expected_message): @@ -194,6 +171,7 @@ def test_HPyModule_error_when_create_returns_module(self): """) def test_HPyModule_create_raises(self): + import pytest with pytest.raises(RuntimeError, match="Test error"): self.make_module(""" HPyDef_SLOT(create, HPy_mod_create) @@ -220,6 +198,7 @@ def test_HPyModule_create_raises(self): """) def test_HPyModule_create_and_nondefault_values(self): + import pytest expected_message = r'^HPyModuleDef defines a HPy_mod_create slot.*' with pytest.raises(SystemError, match=expected_message): self.make_module(""" @@ -247,6 +226,7 @@ def test_HPyModule_create_and_nondefault_values(self): """) def test_HPyModule_create_and_exec_slots(self): + import pytest expected_message = r'^HPyModuleDef defines a HPy_mod_create slot.*' with pytest.raises(SystemError, match=expected_message): self.make_module(""" @@ -284,6 +264,7 @@ def test_HPyModule_negative_size(self): """ The simplest fully declarative module creation. """ + import pytest expected_message = "HPy does not permit HPyModuleDef.size < 0" with pytest.raises(SystemError, match=expected_message): self.make_module(""" diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyslice.py b/graalpython/hpy/test/test_hpyslice.py similarity index 80% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyslice.py rename to graalpython/hpy/test/test_hpyslice.py index bda7743fdc..97f45b77b7 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyslice.py +++ b/graalpython/hpy/test/test_hpyslice.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2023, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - from .support import HPyTest class TestSlice(HPyTest): @@ -131,3 +108,31 @@ def test_adjust_indices(self): assert mod.f(10, 9, 0, -3) == (3, 9, 0, -3) assert mod.f(10, -1, -10, -3) == (3, 9, 0, -3) assert mod.f(10, 5, 5, -3) == (0, 5, 5, -3) + + def test_new(self): + mod = self.make_module(""" + HPyDef_METH(f, "f", HPyFunc_VARARGS) + static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) + { + HPy start, stop, step; + + if (nargs != 3) { + HPyErr_SetString(ctx, ctx->h_TypeError, + "expected exactly 3 arguments"); + return HPy_NULL; + } + + if (HPyArg_Parse(ctx, NULL, args, nargs, "OOO", + &start, &stop, &step) < 0) { + return HPy_NULL; + } + return HPySlice_New(ctx, start, stop, step); + } + @EXPORT(f) + @INIT + """) + + assert mod.f(0, 10, 1) == slice(0, 10, 1) + assert mod.f(None, 10, 1) == slice(None, 10, 1) + assert mod.f(1, None, 1) == slice(1, None, 1) + assert mod.f(0, 10, None) == slice(0, 10, None) \ No newline at end of file diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpystructseq.py b/graalpython/hpy/test/test_hpystructseq.py similarity index 76% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpystructseq.py rename to graalpython/hpy/test/test_hpystructseq.py index 11c6386a55..aee7578ae2 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpystructseq.py +++ b/graalpython/hpy/test/test_hpystructseq.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2023, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """ NOTE: this tests are also meant to be run as PyPy "applevel" tests. @@ -33,10 +10,8 @@ class TestHPyStructSequence(HPyTest): - def test_structseq(self, hpy_abi): + def test_structseq(self): import pytest - if hpy_abi == "cpython": - pytest.skip("structseq not supported on GraalPy") mod = self.make_module(""" static HPyStructSequence_Field structseq_fields[] = { { "field0", "doc0" }, diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpytuple.py b/graalpython/hpy/test/test_hpytuple.py similarity index 69% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpytuple.py rename to graalpython/hpy/test/test_hpytuple.py index 90c366822b..1a44cba6bc 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpytuple.py +++ b/graalpython/hpy/test/test_hpytuple.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - from .support import HPyTest class TestTuple(HPyTest): diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpytype.py b/graalpython/hpy/test/test_hpytype.py similarity index 97% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpytype.py rename to graalpython/hpy/test/test_hpytype.py index c19148106f..4d39fbcd0a 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpytype.py +++ b/graalpython/hpy/test/test_hpytype.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """ NOTE: these tests are also meant to be run as PyPy "applevel" tests. @@ -30,7 +7,6 @@ "fake pytest module") """ from .support import HPyTest, DefaultExtensionTemplate -import pytest class PointTemplate(DefaultExtensionTemplate): @@ -845,7 +821,7 @@ def test_HPyDef_Member_others(self): del foo.OBJECT_NULL_member assert foo.OBJECT_NULL_member is None - with pytest.raises(AttributeError): + with pytest.raises(AttributeError, match="OBJECT_EX_member"): foo.OBJECT_EX_member foo.OBJECT_EX_member = 1 assert foo.OBJECT_EX_member == 1 @@ -1126,12 +1102,13 @@ def test_call_invalid_specs(self): @EXPORT(create_vcall) @INIT """) - with pytest.raises(TypeError): + with pytest.raises(TypeError) as err: mod.create_var_type() - with pytest.raises(TypeError): + assert "Cannot use HPy call protocol with var" in str(err.value) + with pytest.raises(TypeError) as err: mod.create_call_and_vectorcalloffset_type() + # assert "Cannot have HPy_tp_call and explicit member" in str(err.value) - @pytest.mark.skip("not yet implemented") def test_call_explicit_offset(self): mod = self.make_module(""" @TYPE_STRUCT_BEGIN(FooObject) @@ -1507,11 +1484,8 @@ def __new__(self): with pytest.raises(TypeError): mod.create_type("mytest.DummyIntMeta", int) - def test_get_name(self, hpy_abi): - import pytest - if "debug" in hpy_abi: - pytest.skip("unsupported on GraalPy") - import array + def test_get_name(self): + import struct mod = self.make_module(""" static HPyType_Spec Dummy_spec = { .name = "mytest.Dummy", @@ -1536,7 +1510,7 @@ def test_get_name(self, hpy_abi): assert mod.Dummy.__name__ == "Dummy" assert mod.get_name(mod.Dummy) == "Dummy" assert mod.get_name(str) == "str" - assert mod.get_name(array.array) == "array" + assert mod.get_name(struct.Struct) == "Struct" def test_issubtype(self): mod = self.make_module(""" @@ -1619,10 +1593,10 @@ class TestPureHPyType(HPyTest): ExtensionTemplate = PointTemplate - def test_builtin_shape(self, hpy_abi): - import pytest - if hpy_abi == 'cpython': - pytest.skip('native int subclasses are not supported on GraalPy') + def test_builtin_shape(self): + if self.is_graalpy: + import pytest + pytest.skip("Not yet implemented on GraalPy") mod = self.make_module(""" @DEFINE_PointObject(HPyType_BuiltinShape_Long) @DEFINE_Point_xy diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpytype_legacy.py b/graalpython/hpy/test/test_hpytype_legacy.py similarity index 86% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpytype_legacy.py rename to graalpython/hpy/test/test_hpytype_legacy.py index b9bbe75b09..fa9710c58f 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpytype_legacy.py +++ b/graalpython/hpy/test/test_hpytype_legacy.py @@ -1,29 +1,7 @@ -# MIT License -# -# Copyright (c) 2021, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """ HPyType tests on legacy types. """ import pytest +import sys from .support import HPyTest, make_hpy_abi_fixture from .test_hpytype import PointTemplate, TestType as _TestType @@ -104,7 +82,6 @@ def test_legacy_dealloc(self): import gc; gc.collect() assert mod.get_counter() == 1 - @pytest.mark.syncgc def test_legacy_dealloc_and_HPy_tp_traverse(self): import pytest mod_src = """ @@ -139,7 +116,6 @@ def test_legacy_dealloc_and_HPy_tp_traverse(self): mod = self.make_module(mod_src) assert "legacy tp_dealloc" in str(err.value) - @pytest.mark.syncgc def test_legacy_dealloc_and_HPy_tp_destroy(self): import pytest mod_src = """ @@ -282,6 +258,57 @@ def test_call_zero_basicsize(self): @INIT """) + @pytest.mark.skipif(sys.version_info < (3, 9), reason="not for python<3.9") + def test_legacy_class_method(self): + mod = self.make_module(""" + @DEFINE_PointObject + @DEFINE_Point_xy + static PyObject * point_class_getitem(PyObject *cls, PyObject *args) + { + Py_ssize_t args_len = PyTuple_Check(args) ? PyTuple_Size(args) : 1; + if (args_len != 1) { + return PyErr_Format(PyExc_TypeError, + "Too %s arguments for %s", + args_len > 1 ? "many" : "few", + ((PyTypeObject *)cls)->tp_name); + } + return Py_GenericAlias(cls, args); + } + + static PyMethodDef point_methods[] = { + /* for typing; requires python >= 3.9 */ + {"__class_getitem__", + (PyCFunction)point_class_getitem, + METH_CLASS | METH_O, NULL}, + {NULL, NULL, 0, NULL} /* sentinel */ + }; + + + static PyType_Slot Point_slots[] = { + {Py_tp_methods, point_methods}, + {Py_tp_new, (void*)PyType_GenericNew}, + {0, NULL}, + }; + static HPyDef *Point_defines[] = {&Point_x, &Point_y, NULL}; + static HPyType_Spec Point_spec = { + .name = "mytest.Point", + .basicsize = sizeof(PointObject), + .builtin_shape = SHAPE(PointObject), + .legacy_slots = Point_slots, + .defines = Point_defines, + }; + + @EXPORT_TYPE("Point", Point_spec) + @INIT + """) + # Calls __class_getitem__ + t = mod.Point[int] + assert str(t) == "mytest.Point[int]" + pt = mod.Point() + assert pt.x == 0 + assert pt.y == 0 + + class TestCustomLegacyFeatures(HPyTest): def test_legacy_methods(self): diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyunicode.py b/graalpython/hpy/test/test_hpyunicode.py similarity index 97% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyunicode.py rename to graalpython/hpy/test/test_hpyunicode.py index c29b9b3d12..6f6ce29d16 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyunicode.py +++ b/graalpython/hpy/test/test_hpyunicode.py @@ -1,33 +1,6 @@ # -*- encoding: utf-8 -*- -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import itertools -import re import sys -import pytest - from .support import HPyTest class TestUnicode(HPyTest): @@ -249,6 +222,9 @@ def test_FromFormat(self, hpy_abi): # Later we generate an HPy function for each case described below: # Most of the test cases are taken from CPython:Modules/_testcapi/unicode.c # Future work can improve this to add tests from Lib/test/test_capi/test_unicode.py + import itertools + import re + import pytest cases = [ # Unrecognized ( "%y%d", (SystemError, "invalid format string"), "'w', 42"), @@ -715,6 +691,7 @@ def check_cpython_raises_any(name): def test_FromFormat_Ptr(self): # '%p' is platform dependent to some extent, so we need to use regex + import re mod = self.make_module(""" HPyDef_METH(p, "p", HPyFunc_NOARGS) static HPy p_impl(HPyContext *ctx, HPy self) @@ -773,6 +750,7 @@ def __repr__(self): assert mod.A(MyObj()) == 'prefix-MyObj.__repr__\\xfc-suffix' def test_FromFormat_NoAsciiEncodedFmt(self): + import pytest mod = self.make_module(""" HPyDef_METH(no_ascii_fmt, "no_ascii_fmt", HPyFunc_O) static HPy no_ascii_fmt_impl(HPyContext *ctx, HPy self, HPy arg) @@ -832,6 +810,7 @@ def test_FromFormat_LongFormat(self): def test_FromFormat_Limits(self): import sys + import pytest mod = self.make_module(""" #include diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_importing.py b/graalpython/hpy/test/test_importing.py similarity index 57% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_importing.py rename to graalpython/hpy/test/test_importing.py index 0085dac5a8..a16fa74c74 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_importing.py +++ b/graalpython/hpy/test/test_importing.py @@ -1,31 +1,7 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - import pytest from .support import HPyTest -from hpy.devel.abitag import get_hpy_ext_suffix -@pytest.fixture(params=['cpython', 'universal', 'hybrid'] + (['debug'] if HPyTest.supports_debug_mode() else [])) +@pytest.fixture(params=['cpython', 'universal', 'hybrid', 'debug']) def hpy_abi(request): abi = request.param yield abi @@ -59,6 +35,7 @@ def test_importing_attributes(self, hpy_abi, tmpdir): import pytest if not self.supports_ordinary_make_module_imports(): pytest.skip() + from hpy.devel.abitag import get_hpy_ext_suffix mod = self.make_module(""" @INIT """, name='mytest') diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_legacy_forbidden.py b/graalpython/hpy/test/test_legacy_forbidden.py similarity index 66% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_legacy_forbidden.py rename to graalpython/hpy/test/test_legacy_forbidden.py index 5ff6f91976..6dfe29be51 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_legacy_forbidden.py +++ b/graalpython/hpy/test/test_legacy_forbidden.py @@ -1,34 +1,8 @@ -# MIT License -# -# Copyright (c) 2023, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - - """ In this file we check that if we use legacy features in universal mode, we get the expected compile time errors """ -import sys -import pytest from .support import HPyTest, make_hpy_abi_fixture, ONLY_LINUX # this is not strictly correct, we should check whether the actual compiler @@ -40,7 +14,6 @@ # also for other compilers ONLY_GCC = ONLY_LINUX -pytestmark = pytest.mark.skip("capfd not working properly on GraalPy") class TestLegacyForbidden(HPyTest): @@ -54,7 +27,6 @@ def test_expect_make_error(self): """ self.expect_make_error(src, "this is a compile time error") - @pytest.mark.skip("different include dir order on GraalPy") def test_Python_h_forbidden(self, capfd): src = """ #include diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_number.py b/graalpython/hpy/test/test_number.py similarity index 64% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_number.py rename to graalpython/hpy/test/test_number.py index 347bd6d675..2b92924fb8 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_number.py +++ b/graalpython/hpy/test/test_number.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - from .support import HPyTest @@ -65,77 +42,65 @@ def test_bool_from_bool_and_long(self): def test_unary(self): import pytest import operator - ops = ( - ('Negative', operator.neg), - ('Positive', operator.pos), - ('Absolute', abs), - ('Invert', operator.invert), - ('Index', operator.index), - ('Long', int), - ('Float', float), - ) - template = """ - HPyDef_METH(f_{c_name}, "f_{c_name}", HPyFunc_O) - static HPy f_{c_name}_impl(HPyContext *ctx, HPy self, HPy arg) - {{ - return HPy_{c_name}(ctx, arg); - }} - @EXPORT(f_{c_name}) - """ - code = [] - for c_name, _ in ops: - code.append(template.format(c_name=c_name)) - code.append('@INIT') - mod = self.make_module('\n'.join(code), name='unary_ops') - for c_name, op in ops: - c_op = getattr(mod, 'f_%s' % c_name) - assert c_op(-5) == op(-5) - assert c_op(6) == op(6) + for c_name, op in [ + ('Negative', operator.neg), + ('Positive', operator.pos), + ('Absolute', abs), + ('Invert', operator.invert), + ('Index', operator.index), + ('Long', int), + ('Float', float), + ]: + mod = self.make_module(""" + HPyDef_METH(f, "f", HPyFunc_O) + static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) + { + return HPy_%s(ctx, arg); + } + @EXPORT(f) + @INIT + """ % (c_name,), name='number_'+c_name) + assert mod.f(-5) == op(-5) + assert mod.f(6) == op(6) try: res = op(4.75) except Exception as e: with pytest.raises(e.__class__): - c_op(4.75) + mod.f(4.75) else: - assert c_op(4.75) == res + assert mod.f(4.75) == res def test_binary(self): import operator - ops = ( - ('Add', operator.add), - ('Subtract', operator.sub), - ('Multiply', operator.mul), - ('FloorDivide', operator.floordiv), - ('TrueDivide', operator.truediv), - ('Remainder', operator.mod), - ('Divmod', divmod), - ('Lshift', operator.lshift), - ('Rshift', operator.rshift), - ('And', operator.and_), - ('Xor', operator.xor), - ('Or', operator.or_), - ) - template = """ - HPyDef_METH(f_{c_name}, "f_{c_name}", HPyFunc_VARARGS) - static HPy f_{c_name}_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - {{ - HPy a, b; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) - return HPy_NULL; - return HPy_{c_name}(ctx, a, b); - }} - @EXPORT(f_{c_name}) - """ - code = [] - for c_name, _ in ops: - code.append(template.format(c_name=c_name)) - code.append('@INIT') - mod = self.make_module('\n'.join(code), name='binary_ops') - for c_name, op in ops: - c_op = getattr(mod, 'f_%s' % c_name) - assert c_op(5, 4) == op(5, 4) - assert c_op(6, 3) == op(6, 3) + for c_name, op in [ + ('Add', operator.add), + ('Subtract', operator.sub), + ('Multiply', operator.mul), + ('FloorDivide', operator.floordiv), + ('TrueDivide', operator.truediv), + ('Remainder', operator.mod), + ('Divmod', divmod), + ('Lshift', operator.lshift), + ('Rshift', operator.rshift), + ('And', operator.and_), + ('Xor', operator.xor), + ('Or', operator.or_), + ]: + mod = self.make_module(""" + HPyDef_METH(f, "f", HPyFunc_VARARGS) + static HPy f_impl(HPyContext *ctx, HPy self, + const HPy *args, size_t nargs) + { + HPy a, b; + if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) + return HPy_NULL; + return HPy_%s(ctx, a, b); + } + @EXPORT(f) + @INIT + """ % (c_name,), name='number_'+c_name) + assert mod.f(5, 4) == op(5, 4) + assert mod.f(6, 3) == op(6, 3) def test_power(self): mod = self.make_module(""" diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_object.py b/graalpython/hpy/test/test_object.py similarity index 76% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_object.py rename to graalpython/hpy/test/test_object.py index 8a5bbfc291..369b1500ad 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_object.py +++ b/graalpython/hpy/test/test_object.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """ NOTE: this tests are also meant to be run as PyPy "applevel" tests. @@ -319,10 +296,8 @@ def foo(self, value): mod.f(b) assert b.foo is True - def test_delattr(self, hpy_abi): + def test_delattr(self): import pytest - if hpy_abi == "cpython": - pytest.skip("delattr not supported on GraalPy") mod = self.make_module(""" HPyDef_METH(del_foo, "del_foo", HPyFunc_O) static HPy del_foo_impl(HPyContext *ctx, HPy self, HPy arg) @@ -403,10 +378,8 @@ def set_foo(obj): with pytest.raises(AttributeError): c.foo - def test_delattr_s(self, hpy_abi): + def test_delattr_s(self): import pytest - if hpy_abi == "cpython": - pytest.skip("delattr not supported on GraalPy") mod = self.make_module(""" HPyDef_METH(del_foo, "del_foo", HPyFunc_O) static HPy del_foo_impl(HPyContext *ctx, HPy self, HPy arg) @@ -557,6 +530,56 @@ def test_getitem_s(self): with pytest.raises(TypeError): mod.f([]) + def test_getslice(self): + import pytest + if self.is_graalpy: + pytest.skip("Not yet implemented on GraalPy") + mod = self.make_module(""" + HPyDef_METH(f, "f", HPyFunc_VARARGS) + static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) + { + HPy seq; + HPy_ssize_t i1, i2; + if (!HPyArg_Parse(ctx, NULL, args, nargs, "Onn", &seq, &i1, &i2)) { + return HPy_NULL; + } + if (HPy_Is(ctx, seq, ctx->h_None)) { + seq = HPy_NULL; + } + return HPy_GetSlice(ctx, seq, i1, i2); + } + @EXPORT(f) + @INIT + """) + l = [1,2,3,4,5] + assert mod.f(l, 0, 5) == l + assert mod.f(l, 2, 3) == [3] + assert mod.f(l, 1, 3) == [2, 3] + + s = "hello" + assert mod.f(s, 0, 5) == "hello" + assert mod.f(s, 1, 3) == "el" + + class Sliceable: + def __getitem__(self, key): + # assume 'key' is a slice + if key.start < 0: + raise ValueError + return key.start + key.stop + + o = Sliceable() + assert mod.f(o, 5, 13) == 18 + + # test that errors are propagated + with pytest.raises(ValueError): + mod.f(o, -1, 1) + + # 'None' will be mapped to 'HPy_NULL' by the C function + with pytest.raises(SystemError): + mod.f(None, 0, 1) + with pytest.raises(TypeError): + mod.f(123, 0, 1) + def test_setitem(self): import pytest mod = self.make_module(""" @@ -630,6 +653,69 @@ def test_setitem_s(self): with pytest.raises(TypeError): mod.f([]) + def test_setslice(self): + import pytest + if self.is_graalpy: + pytest.skip("Not yet implemented on GraalPy") + mod = self.make_module(""" + HPyDef_METH(f, "f", HPyFunc_VARARGS) + static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) + { + int res; + HPy seq, value; + HPy_ssize_t i1, i2; + if (!HPyArg_Parse(ctx, NULL, args, nargs, "OnnO", &seq, &i1, &i2, &value)) { + return HPy_NULL; + } + if (HPy_Is(ctx, seq, ctx->h_None)) { + seq = HPy_NULL; + } + res = HPy_SetSlice(ctx, seq, i1, i2, value); + if (res == 0) { + return HPy_Dup(ctx, seq); + } else if (res == -1) { + return HPy_NULL; + } + HPyErr_SetString(ctx, ctx->h_SystemError, + "HPy_SetSlice returned an invalid result code"); + return HPy_NULL; + } + @EXPORT(f) + @INIT + """) + l = [1,2,3,4,5] + val = [11,22,33,44,55] + x = mod.f(l, 0, 5, val) + assert x is l + assert x is not val + assert l == val + + l = [1,2,3,4,5] + assert mod.f(l, 0, 5, []) == [] + + l = [1,2,3,4,5] + assert mod.f(l, 1, 3, [10, 11, 12]) == [1, 10, 11, 12, 4, 5] + + class Sliceable: + def __setitem__(self, key, value): + # assume 'key' is a slice + if key.start < 0: + raise ValueError + self.value = (key.start, key.stop, value) + + o = Sliceable() + assert mod.f(o, 5, 13, [7, 8, 9]).value == (5, 13, [7, 8, 9]) + + # test that errors are propagated + with pytest.raises(ValueError): + mod.f(o, -1, 1, []) + + # 'None' will be mapped to 'HPy_NULL' by the C function + with pytest.raises(SystemError): + mod.f(None, 0, 1, []) + with pytest.raises(TypeError): + mod.f(123, 0, 1, []) + def test_delitem(self): import pytest mod = self.make_module(""" @@ -702,6 +788,64 @@ def test_delitem(self): with pytest.raises(TypeError): mod.delitem_s3([1, 2, 3, 4]) + def test_delslice(self): + import pytest + if self.is_graalpy: + pytest.skip("Not yet implemented on GraalPy") + mod = self.make_module(""" + HPyDef_METH(f, "f", HPyFunc_VARARGS) + static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) + { + int res; + HPy seq; + HPy_ssize_t i1, i2; + if (!HPyArg_Parse(ctx, NULL, args, nargs, "Onn", &seq, &i1, &i2)) { + return HPy_NULL; + } + if (HPy_Is(ctx, seq, ctx->h_None)) { + seq = HPy_NULL; + } + res = HPy_DelSlice(ctx, seq, i1, i2); + if (res == 0) { + return HPy_Dup(ctx, seq); + } else if (res == -1) { + return HPy_NULL; + } + HPyErr_SetString(ctx, ctx->h_SystemError, + "HPy_DelSlice returned an invalid result code"); + return HPy_NULL; + } + @EXPORT(f) + @INIT + """) + l = [1,2,3,4,5] + x = mod.f(l, 0, 5) + assert x is l + assert l == [] + + l = [1,2,3,4,5] + assert mod.f(l, 1, 3) == [1, 4, 5] + + class Sliceable: + def __delitem__(self, key): + # assume 'key' is a slice + if key.start < 0: + raise ValueError + self.value = key.start + key.stop + + o = Sliceable() + assert mod.f(o, 5, 13).value == 18 + + # test that errors are propagated + with pytest.raises(ValueError): + mod.f(o, -1, 1) + + # 'None' will be mapped to 'HPy_NULL' by the C function + with pytest.raises(SystemError): + mod.f(None, 0, 1) + with pytest.raises(TypeError): + mod.f(123, 0, 1) + def test_length(self): mod = self.make_module(""" HPyDef_METH(f, "f", HPyFunc_O) @@ -767,6 +911,64 @@ class Dummy: import pytest with pytest.raises(TypeError): mod.f(Dummy(), 42) + + def test_getiter(self): + mod = self.make_module(""" + HPyDef_METH(f, "f", HPyFunc_O) + static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) + { + HPy iterator; + iterator = HPy_GetIter(ctx, arg); + if HPy_IsNull(iterator) + return HPy_NULL; + return iterator; + } + @EXPORT(f) + @INIT + """) + + def test_for_loop(iterator): + results = [] + for obj in iterator: + results.append(obj) + return results + + class WithIter: + def __iter__(self): + return (1, 2, 3).__iter__() + + class WithoutIter: + pass + + case = [1, 2, 3] + result = mod.f(case) + assert result + assert test_for_loop(result) == [1, 2, 3] + + case = iter([1, 2, 3]) + result = mod.f(case) + assert result + assert test_for_loop(result) == [1, 2, 3] + + case = zip((1, 2, 3), [4, 5, 6]) + result = mod.f(case) + assert result + assert test_for_loop(result) == [(1, 4), (2, 5), (3, 6)] + + case = range(10) + result = mod.f(case) + assert result + assert test_for_loop(result) == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + + case = WithIter() + result = mod.f(case) + assert result + assert test_for_loop(result) == [1, 2, 3] + + import pytest + with pytest.raises(TypeError): + assert mod.f(WithoutIter()) + def test_dump(self): # _HPy_Dump is supposed to be used e.g. inside a gdb session: it diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_slots.py b/graalpython/hpy/test/test_slots.py similarity index 95% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_slots.py rename to graalpython/hpy/test/test_slots.py index 84b79a6ce4..ac9cbe2fc7 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_slots.py +++ b/graalpython/hpy/test/test_slots.py @@ -1,29 +1,6 @@ -# MIT License -# -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - +import pytest from .support import HPyTest from .test_hpytype import PointTemplate -import pytest class TestSlots(HPyTest): @@ -485,6 +462,7 @@ def test_tp_repr_and_tp_str(self): assert repr(p) == 'repr(Point(1, 2))' def test_tp_hash(self): + import pytest mod = self.make_module(""" @DEFINE_PointObject @DEFINE_Point_new @@ -633,10 +611,7 @@ def test_sq_item_and_sq_length(self): assert len(p) == 1234 assert p[4] == 8 assert p[21] == 42 - assert p[-1] == 1233 * 2, str(p[-1]) - assert p.__getitem__(4) == 8 - assert p.__getitem__(21) == 42 - assert p.__getitem__(-1) == 1233 * 2 + assert p[-1] == 1233 * 2 def test_sq_ass_item(self): import pytest @@ -797,7 +772,6 @@ def test_sq_contains(self): 'hello' in p def test_tp_richcompare(self): - import pytest mod = self.make_module(""" @DEFINE_PointObject @DEFINE_Point_new @@ -833,3 +807,27 @@ def test_tp_richcompare(self): # assert not p1 >= p2 assert p1 >= p1 + + def test_tp_descr_get(self): + mod = self.make_module(""" + @DEFINE_PointObject + @DEFINE_Point_new + + HPyDef_SLOT(Point_get, HPy_tp_descr_get); + static HPy + Point_get_impl(HPyContext *ctx, HPy self, HPy obj, HPy type) + { + if (HPy_IsNull(obj) || HPy_Is(ctx, self, ctx->h_None)) { + return HPy_Dup(ctx, self); + } + return HPyLong_FromLong(ctx, 123); + } + + @EXPORT_POINT_TYPE(&Point_new, &Point_get) + @INIT + """) + p = mod.Point(10, 10) + class Dummy: + point_func = p + assert Dummy.point_func is p + assert Dummy().point_func == 123 diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_slots_legacy.py b/graalpython/hpy/test/test_slots_legacy.py similarity index 87% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_slots_legacy.py rename to graalpython/hpy/test/test_slots_legacy.py index fd77e275eb..9cc5feb05c 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_slots_legacy.py +++ b/graalpython/hpy/test/test_slots_legacy.py @@ -1,28 +1,4 @@ -# MIT License -# -# Copyright (c) 2021, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """ HPyType slot tests on legacy types. """ -import pytest from .support import HPyTest, make_hpy_abi_fixture from .test_hpytype_legacy import LegacyPointTemplate diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_support.py b/graalpython/hpy/test/test_support.py similarity index 54% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_support.py rename to graalpython/hpy/test/test_support.py index 09745b1793..dbf8745dcd 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_support.py +++ b/graalpython/hpy/test/test_support.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - import pytest from pathlib import Path from . import support diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_tracker.py b/graalpython/hpy/test/test_tracker.py similarity index 78% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_tracker.py rename to graalpython/hpy/test/test_tracker.py index f73d00b9d9..5df8371bde 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_tracker.py +++ b/graalpython/hpy/test/test_tracker.py @@ -1,26 +1,3 @@ -# MIT License -# -# Copyright (c) 2021, 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """ NOTE: this tests are also meant to be run as PyPy "applevel" tests. diff --git a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/trace/test_trace.py b/graalpython/hpy/test/trace/test_trace.py similarity index 74% rename from graalpython/com.oracle.graal.python.hpy.test/src/hpytest/trace/test_trace.py rename to graalpython/hpy/test/trace/test_trace.py index 675f68d16c..275d314dfe 100644 --- a/graalpython/com.oracle.graal.python.hpy.test/src/hpytest/trace/test_trace.py +++ b/graalpython/hpy/test/trace/test_trace.py @@ -1,32 +1,6 @@ -# MIT License -# -# Copyright (c) 2023, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - import pytest -from hpytest.support import HPyTest from hpy.trace import get_call_counts, get_durations, set_trace_functions -pytestmark = pytest.mark.skipif(not HPyTest.supports_trace_mode(), reason="trace mode not supported") - @pytest.fixture def hpy_abi(): return "trace" diff --git a/graalpython/lib-graalpython/_nt.py b/graalpython/lib-graalpython/_nt.py new file mode 100644 index 0000000000..2d07202b13 --- /dev/null +++ b/graalpython/lib-graalpython/_nt.py @@ -0,0 +1,54 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import nt + + +def _add_dll_directory(path): + import ctypes + return ctypes.windll.kernel32.AddDllDirectory(path) + + +def _remove_dll_directory(cookie): + import ctypes + return ctypes.windll.kernel32.RemoveDllDirectory(cookie) + + +nt._add_dll_directory = _add_dll_directory +nt._remove_dll_directory = _remove_dll_directory diff --git a/graalpython/lib-graalpython/_sre.py b/graalpython/lib-graalpython/_sre.py index 316cb8af6f..e0f0be492d 100644 --- a/graalpython/lib-graalpython/_sre.py +++ b/graalpython/lib-graalpython/_sre.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -44,6 +44,9 @@ from sys import maxsize +# This does not load _polyglot.py (as desired for faster startup), due to AbstractImportNode.importModule(), +# when the context is not initialized, only looking up builtin modules (and not running their postInitialize()). +import polyglot def _check_pos(pos): if pos > maxsize: @@ -265,7 +268,7 @@ def __init__(self, pattern, flags): self.groupindex = {} self.__indexgroup = {} else: - group_names = dir(groups) + group_names = polyglot.__keys__(groups) self.groupindex = _mappingproxy({name: getattr(groups, name) for name in group_names}) self.__indexgroup = {getattr(groups, name): name for name in group_names} diff --git a/graalpython/lib-graalpython/_sysconfig.py b/graalpython/lib-graalpython/_sysconfig.py index dbac1041b0..c5333edf51 100644 --- a/graalpython/lib-graalpython/_sysconfig.py +++ b/graalpython/lib-graalpython/_sysconfig.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -54,11 +54,7 @@ def _get_posix_vars(): so_ext = ".so" assert _imp.extension_suffixes()[0] == "." + so_abi + so_ext, "mismatch between extension suffix to _imp.extension_suffixes" - use_system_toolchain = __graalpython__.use_system_toolchain - if use_system_toolchain: - get_toolchain = __graalpython__.determine_system_toolchain().get - else: - get_toolchain = __graalpython__.get_toolchain_tool_path + get_toolchain = __graalpython__.determine_system_toolchain().get toolchain_cxx = get_toolchain('CXX') have_cxx = toolchain_cxx is not None @@ -78,8 +74,6 @@ def _get_posix_vars(): g['CC'] = get_toolchain('CC') g['CXX'] = toolchain_cxx if have_cxx else get_toolchain('CC') + ' --driver-mode=g++' opt_flags = ["-DNDEBUG"] - if not use_system_toolchain: - opt_flags += ["-stdlib=libc++"] g['OPT'] = ' '.join(opt_flags) g['INCLUDEPY'] = python_inc g['CONFINCLUDEPY'] = python_inc @@ -87,15 +81,18 @@ def _get_posix_vars(): gnu_source = "-D_GNU_SOURCE=1" g['USE_GNU_SOURCE'] = gnu_source cflags_default = list(opt_flags) - if not use_system_toolchain: - cflags_default += ["-Wno-unused-command-line-argument", "-DGRAALVM_PYTHON_LLVM"] - cflags_default += ["-DGRAALVM_PYTHON_LLVM_NATIVE"] if win32_native: cflags_default += ["-DMS_WINDOWS", "-DPy_ENABLE_SHARED", "-DHAVE_DECLSPEC_DLL"] g['CFLAGS_DEFAULT'] = ' '.join(cflags_default) g['CFLAGS'] = ' '.join(cflags_default + [gnu_source]) g['LDFLAGS'] = "" g['CCSHARED'] = fpic + if darwin_native: + # MACOSX_DEPLOYMENT_TARGET is taken from the minimum version we build + # GraalPy for, which is currently BigSur + g['MACOSX_DEPLOYMENT_TARGET'] = "11" + else: + g['MACOSX_DEPLOYMENT_TARGET'] = "" if darwin_native: g['LDFLAGS'] = "-bundle -undefined dynamic_lookup" ldshared_common = g['LDFLAGS'] diff --git a/graalpython/lib-graalpython/_polyglot.py b/graalpython/lib-graalpython/modules/_polyglot.py similarity index 67% rename from graalpython/lib-graalpython/_polyglot.py rename to graalpython/lib-graalpython/modules/_polyglot.py index caf9cebdc0..770575c8a8 100644 --- a/graalpython/lib-graalpython/_polyglot.py +++ b/graalpython/lib-graalpython/modules/_polyglot.py @@ -1,4 +1,4 @@ -# Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,9 +37,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -import datetime import polyglot -import time def interop_type(foreign_class, allow_method_overwrites=False): @@ -112,37 +110,6 @@ def wrapper(python_class): setattr(polyglot, "interop_behavior", interop_behavior) -def _date_time_tz(dt: datetime.datetime): - if dt.tzinfo is not None: - utcoffset = dt.tzinfo.utcoffset(dt) - return utcoffset.days * 3600 * 24 + utcoffset.seconds - raise polyglot.UnsupportedMessage - - -def _struct_time_tz(st: time.struct_time): - if st.tm_gmtoff is not None: - return st.tm_gmtoff - return st.tm_zone - - -polyglot.register_interop_behavior(datetime.time, - is_time=True, as_time=lambda d: (d.hour, d.minute, d.second, d.microsecond), - is_time_zone=lambda t: t.tzinfo is not None, as_time_zone=_date_time_tz) - -polyglot.register_interop_behavior(datetime.date, - is_date=True, as_date=lambda d: (d.year, d.month, d.day)) - -polyglot.register_interop_behavior(datetime.datetime, - is_date=True, as_date=lambda d: (d.year, d.month, d.day), - is_time=True, as_time=lambda d: (d.hour, d.minute, d.second, d.microsecond), - is_time_zone=lambda t: t.tzinfo is not None, as_time_zone=_date_time_tz) - -polyglot.register_interop_behavior(time.struct_time, - is_date=True, as_date=lambda t: (t.tm_year, t.tm_mon, t.tm_mday), - is_time=True, as_time=lambda t: (t.tm_hour, t.tm_min, t.tm_sec, 0), - is_time_zone=lambda t: t.tm_zone is not None or t.tm_gmtoff is not None, - as_time_zone=_struct_time_tz) - # loading arrow structures on demand def __getattr__(name): if name == "arrow": @@ -153,33 +120,3 @@ def __getattr__(name): setattr(polyglot, "__getattr__", __getattr__) setattr(polyglot, "__path__", ".") - -# example extending time.struct_time using the decorator wrapper -# -# @polyglot.interop_behavior(time.struct_time) -# class StructTimeInteropBehavior: -# @staticmethod -# def is_date(t): -# return True -# -# @staticmethod -# def as_date(t): -# return t.tm_year, t.tm_mon, t.tm_mday -# -# @staticmethod -# def is_time(t): -# return True -# -# @staticmethod -# def as_time(t): -# return t.tm_hour, t.tm_min, t.tm_sec, 0 -# -# @staticmethod -# def is_time_zone(t): -# return t.tm_zone is not None or t.tm_gmtoff is not None -# -# @staticmethod -# def as_time_zone(t): -# if t.tm_gmtoff is not None: -# return t.tm_gmtoff -# return t.tm_zone diff --git a/graalpython/lib-graalpython/modules/_polyglot_arrow.py b/graalpython/lib-graalpython/modules/_polyglot_arrow.py index ecc5c36829..904f5460ac 100644 --- a/graalpython/lib-graalpython/modules/_polyglot_arrow.py +++ b/graalpython/lib-graalpython/modules/_polyglot_arrow.py @@ -39,6 +39,8 @@ import polyglot import java +import gc +import atexit try: java.type("org.apache.arrow.vector.BaseFixedWidthVector") @@ -56,7 +58,7 @@ def __len__(self): return self.getValueCount() def __arrow_c_array__(self, requested_schema=None): - return __graalpython__.export_arrow_vector(self) + return Data.export_vector(self) class SmallIntVector: @@ -65,7 +67,7 @@ def __len__(self): return self.getValueCount() def __arrow_c_array__(self, requested_schema=None): - return __graalpython__.export_arrow_vector(self) + return Data.export_vector(self) class IntVector: @@ -74,7 +76,7 @@ def __len__(self): return self.getValueCount() def __arrow_c_array__(self, requested_schema=None): - return __graalpython__.export_arrow_vector(self) + return Data.export_vector(self) class BigIntVector: @@ -83,7 +85,7 @@ def __len__(self): return self.getValueCount() def __arrow_c_array__(self, requested_schema=None): - return __graalpython__.export_arrow_vector(self) + return Data.export_vector(self) class BitVector: @@ -92,7 +94,7 @@ def __len__(self): return self.getValueCount() def __arrow_c_array__(self, requested_schema=None): - return __graalpython__.export_arrow_vector(self) + return Data.export_vector(self) class Float2Vector: @@ -101,7 +103,7 @@ def __len__(self): return self.getValueCount() def __arrow_c_array__(self, requested_schema=None): - return __graalpython__.export_arrow_vector(self) + return Data.export_vector(self) class Float4Vector: @@ -110,7 +112,7 @@ def __len__(self): return self.getValueCount() def __arrow_c_array__(self, requested_schema=None): - return __graalpython__.export_arrow_vector(self) + return Data.export_vector(self) class Float8Vector: @@ -119,7 +121,94 @@ def __len__(self): return self.getValueCount() def __arrow_c_array__(self, requested_schema=None): - return __graalpython__.export_arrow_vector(self) + return Data.export_vector(self) + +class Table: + + def __arrow_c_array__(self, requested_schema=None): + return Data.export_table(self) + +class ArrowArray: + _jarrow_array_class = java.type("org.apache.arrow.c.ArrowArray") + _graalpy_arrow_array_class = java.type("com.oracle.graal.python.nodes.arrow.ArrowArray") + + @staticmethod + def allocate_new(allocator): + return ArrowArray._jarrow_array_class.allocateNew(allocator) + + @staticmethod + def transfer_to_managed(arrow_array): + snapshot = arrow_array.snapshot() + managed_arrow_array = ArrowArray._graalpy_arrow_array_class.allocate( + snapshot.length, + snapshot.null_count, + snapshot.offset, + snapshot.n_buffers, + snapshot.n_children, + snapshot.buffers, + snapshot.children, + snapshot.dictionary, + snapshot.release, + snapshot.private_data + ) + + arrow_array.close() + return managed_arrow_array + + +class ArrowSchema: + _jarrow_schema_class = java.type("org.apache.arrow.c.ArrowSchema") + _graalpy_arrow_schema_class = java.type("com.oracle.graal.python.nodes.arrow.ArrowSchema") + + @staticmethod + def allocate_new(allocator): + return ArrowSchema._jarrow_schema_class.allocateNew(allocator) + + @staticmethod + def transfer_to_managed(arrow_schema): + snapshot = arrow_schema.snapshot() + managed_arrow_schema = ArrowSchema._graalpy_arrow_schema_class.allocate( + snapshot.format, + snapshot.name, + snapshot.metadata, + snapshot.flags, + snapshot.n_children, + snapshot.children, + snapshot.dictionary, + snapshot.release, + snapshot.private_data + ) + arrow_schema.close() + return managed_arrow_schema + + +class Data: + _jdata_class = java.type("org.apache.arrow.c.Data") + + @staticmethod + def export_table(table: Table): + vector_schema_root = table.toVectorSchemaRoot() + allocator = vector_schema_root.getFieldVectors().getFirst().getAllocator().getRoot() + arrow_array = ArrowArray.allocate_new(allocator) + arrow_schema = ArrowSchema.allocate_new(allocator) + Data._jdata_class.exportVectorSchemaRoot(allocator, vector_schema_root, None, arrow_array, arrow_schema) + vector_schema_root.close() + managed_arrow_array = ArrowArray.transfer_to_managed(arrow_array) + managed_arrow_schema = ArrowSchema.transfer_to_managed(arrow_schema) + + return __graalpython__.create_arrow_py_capsule(managed_arrow_array.memoryAddress(), managed_arrow_schema.memoryAddress()) + + @staticmethod + def export_vector(vector): + allocator = vector.getAllocator() + arrow_array = ArrowArray.allocate_new(allocator) + arrow_schema = ArrowSchema.allocate_new(allocator) + + Data._jdata_class.exportVector(allocator, vector, None, arrow_array, arrow_schema) + managed_arrow_array = ArrowArray.transfer_to_managed(arrow_array) + managed_arrow_schema = ArrowSchema.transfer_to_managed(arrow_schema) + + return __graalpython__.create_arrow_py_capsule(managed_arrow_array.memoryAddress(), managed_arrow_schema.memoryAddress()) __enabled_java_integration = False @@ -137,30 +226,42 @@ def enable_java_integration(allow_method_overwrites: bool = False): if not __enabled_java_integration: __enabled_java_integration = True # Ints - int8_vector_class_path = java.type("org.apache.arrow.vector.TinyIntVector") - int16_vector_class_path = java.type("org.apache.arrow.vector.SmallIntVector") - int32_vector_class_path = java.type("org.apache.arrow.vector.IntVector") - int64_vector_class_path = java.type("org.apache.arrow.vector.BigIntVector") + int8_vector_class = java.type("org.apache.arrow.vector.TinyIntVector") + int16_vector_class = java.type("org.apache.arrow.vector.SmallIntVector") + int32_vector_class = java.type("org.apache.arrow.vector.IntVector") + int64_vector_class = java.type("org.apache.arrow.vector.BigIntVector") # Boolean - boolean_vector_class_path = java.type("org.apache.arrow.vector.BitVector") + boolean_vector_class = java.type("org.apache.arrow.vector.BitVector") # Floats - float2_vector_class_path = java.type("org.apache.arrow.vector.Float2Vector") - float4_vector_class_path = java.type("org.apache.arrow.vector.Float4Vector") - float8_vector_class_path = java.type("org.apache.arrow.vector.Float8Vector") + float2_vector_class = java.type("org.apache.arrow.vector.Float2Vector") + float4_vector_class = java.type("org.apache.arrow.vector.Float4Vector") + float8_vector_class = java.type("org.apache.arrow.vector.Float8Vector") + # Table + table_class = java.type("org.apache.arrow.vector.table.Table") - polyglot.register_interop_type(int8_vector_class_path, TinyIntVector, + polyglot.register_interop_type(int8_vector_class, TinyIntVector, allow_method_overwrites=allow_method_overwrites) - polyglot.register_interop_type(int16_vector_class_path, SmallIntVector, + polyglot.register_interop_type(int16_vector_class, SmallIntVector, allow_method_overwrites=allow_method_overwrites) - polyglot.register_interop_type(int32_vector_class_path, IntVector, + polyglot.register_interop_type(int32_vector_class, IntVector, allow_method_overwrites=allow_method_overwrites) - polyglot.register_interop_type(int64_vector_class_path, BigIntVector, + polyglot.register_interop_type(int64_vector_class, BigIntVector, allow_method_overwrites=allow_method_overwrites) - polyglot.register_interop_type(boolean_vector_class_path, BitVector, + polyglot.register_interop_type(boolean_vector_class, BitVector, allow_method_overwrites=allow_method_overwrites) - polyglot.register_interop_type(float2_vector_class_path, Float2Vector, + polyglot.register_interop_type(float2_vector_class, Float2Vector, allow_method_overwrites=allow_method_overwrites) - polyglot.register_interop_type(float4_vector_class_path, Float4Vector, + polyglot.register_interop_type(float4_vector_class, Float4Vector, allow_method_overwrites=allow_method_overwrites) - polyglot.register_interop_type(float8_vector_class_path, Float8Vector, + polyglot.register_interop_type(float8_vector_class, Float8Vector, allow_method_overwrites=allow_method_overwrites) + polyglot.register_interop_type(table_class, Table, allow_method_overwrites=allow_method_overwrites) + + + + def force_gc(): + gc.collect() + gc.collect() + gc.collect() + + atexit.register(force_gc) diff --git a/graalpython/lib-graalpython/modules/_polyglot_datetime.py b/graalpython/lib-graalpython/modules/_polyglot_datetime.py new file mode 100644 index 0000000000..80f73a74de --- /dev/null +++ b/graalpython/lib-graalpython/modules/_polyglot_datetime.py @@ -0,0 +1,60 @@ +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import datetime +import polyglot + +def _date_time_tz(dt: datetime.datetime): + if dt.tzinfo is not None: + utcoffset = dt.tzinfo.utcoffset(dt) + return utcoffset.days * 3600 * 24 + utcoffset.seconds + raise polyglot.UnsupportedMessage + + +polyglot.register_interop_behavior(datetime.time, + is_time=True, as_time=lambda d: (d.hour, d.minute, d.second, d.microsecond), + is_time_zone=lambda t: t.tzinfo is not None, as_time_zone=_date_time_tz) + +polyglot.register_interop_behavior(datetime.date, + is_date=True, as_date=lambda d: (d.year, d.month, d.day)) + +polyglot.register_interop_behavior(datetime.datetime, + is_date=True, as_date=lambda d: (d.year, d.month, d.day), + is_time=True, as_time=lambda d: (d.hour, d.minute, d.second, d.microsecond), + is_time_zone=lambda t: t.tzinfo is not None, as_time_zone=_date_time_tz) diff --git a/graalpython/lib-graalpython/modules/_polyglot_time.py b/graalpython/lib-graalpython/modules/_polyglot_time.py new file mode 100644 index 0000000000..ed4dc0fc54 --- /dev/null +++ b/graalpython/lib-graalpython/modules/_polyglot_time.py @@ -0,0 +1,84 @@ +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import time +import polyglot + + +def _struct_time_tz(st: time.struct_time): + if st.tm_gmtoff is not None: + return st.tm_gmtoff + return st.tm_zone + + +polyglot.register_interop_behavior(time.struct_time, + is_date=True, as_date=lambda t: (t.tm_year, t.tm_mon, t.tm_mday), + is_time=True, as_time=lambda t: (t.tm_hour, t.tm_min, t.tm_sec, 0), + is_time_zone=lambda t: t.tm_zone is not None or t.tm_gmtoff is not None, + as_time_zone=_struct_time_tz) + +# example extending time.struct_time using the decorator wrapper +# +# @polyglot.interop_behavior(time.struct_time) +# class StructTimeInteropBehavior: +# @staticmethod +# def is_date(t): +# return True +# +# @staticmethod +# def as_date(t): +# return t.tm_year, t.tm_mon, t.tm_mday +# +# @staticmethod +# def is_time(t): +# return True +# +# @staticmethod +# def as_time(t): +# return t.tm_hour, t.tm_min, t.tm_sec, 0 +# +# @staticmethod +# def is_time_zone(t): +# return t.tm_zone is not None or t.tm_gmtoff is not None +# +# @staticmethod +# def as_time_zone(t): +# if t.tm_gmtoff is not None: +# return t.tm_gmtoff +# return t.tm_zone diff --git a/graalpython/lib-graalpython/modules/hpy.egg-info/PKG-INFO b/graalpython/lib-graalpython/modules/hpy.egg-info/PKG-INFO deleted file mode 100644 index 716a50197c..0000000000 --- a/graalpython/lib-graalpython/modules/hpy.egg-info/PKG-INFO +++ /dev/null @@ -1,9 +0,0 @@ -Metadata-Version: 2.1 -Name: hpy -Version: 0.9.0 -Summary: UNKNOWN -Home-page: UNKNOWN -License: UNKNOWN -Description: UNKNOWN -Platform: UNKNOWN -Provides-Extra: dev \ No newline at end of file diff --git a/graalpython/lib-graalpython/modules/hpy.egg-info/SOURCES.txt b/graalpython/lib-graalpython/modules/hpy.egg-info/SOURCES.txt deleted file mode 100644 index a46175d746..0000000000 --- a/graalpython/lib-graalpython/modules/hpy.egg-info/SOURCES.txt +++ /dev/null @@ -1,18 +0,0 @@ -hpy.egg-info/PKG-INFO -hpy.egg-info/SOURCES.txt -hpy.egg-info/dependency_links.txt -hpy.egg-info/top_level.txt -hpy/devel/__init__.py -hpy/devel/version.py -hpy/devel/src/runtime/argparse.c -hpy/devel/src/runtime/ctx_bytes.c -hpy/devel/src/runtime/ctx_call.c -hpy/devel/src/runtime/ctx_err.c -hpy/devel/src/runtime/ctx_listbuilder.c -hpy/devel/src/runtime/ctx_module.c -hpy/devel/src/runtime/ctx_object.c -hpy/devel/src/runtime/ctx_tracker.c -hpy/devel/src/runtime/ctx_tuple.c -hpy/devel/src/runtime/ctx_tuplebuilder.c -hpy/devel/src/runtime/ctx_type.c -hpy/devel/src/runtime/helpers.c diff --git a/graalpython/lib-graalpython/modules/hpy.egg-info/entry_points.txt b/graalpython/lib-graalpython/modules/hpy.egg-info/entry_points.txt deleted file mode 100644 index c714c2cb79..0000000000 --- a/graalpython/lib-graalpython/modules/hpy.egg-info/entry_points.txt +++ /dev/null @@ -1,3 +0,0 @@ -[distutils.setup_keywords] -hpy_ext_modules = hpy.devel:handle_hpy_ext_modules - diff --git a/graalpython/lib-graalpython/modules/hpy/debug/__init__.py b/graalpython/lib-graalpython/modules/hpy/debug/__init__.py deleted file mode 100644 index 0d46b706f4..0000000000 --- a/graalpython/lib-graalpython/modules/hpy/debug/__init__.py +++ /dev/null @@ -1,34 +0,0 @@ -# MIT License -# -# Copyright (c) 2021, 2022, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -from .leakdetector import HPyDebugError, HPyLeakError, LeakDetector - - -def set_handle_stack_trace_limit(limit): - from hpy.universal import _debug - _debug.set_handle_stack_trace_limit(limit) - - -def disable_handle_stack_traces(): - from hpy.universal import _debug - _debug.set_handle_stack_trace_limit(None) diff --git a/graalpython/lib-graalpython/modules/hpy/debug/leakdetector.py b/graalpython/lib-graalpython/modules/hpy/debug/leakdetector.py deleted file mode 100644 index 59352b430d..0000000000 --- a/graalpython/lib-graalpython/modules/hpy/debug/leakdetector.py +++ /dev/null @@ -1,66 +0,0 @@ -# MIT License -# -# Copyright (c) 2021, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -from hpy.universal import _debug - -class HPyDebugError(Exception): - pass - -class HPyLeakError(HPyDebugError): - def __init__(self, leaks): - super().__init__() - self.leaks = leaks - - def __str__(self): - lines = [] - n = len(self.leaks) - s = 's' if n != 1 else '' - lines.append(f'{n} unclosed handle{s}:') - for dh in self.leaks: - lines.append(' %r' % dh) - return '\n'.join(lines) - - -class LeakDetector: - - def __init__(self): - self.generation = None - - def start(self): - if self.generation is not None: - raise ValueError('LeakDetector already started') - self.generation = _debug.new_generation() - - def stop(self): - if self.generation is None: - raise ValueError('LeakDetector not started yet') - leaks = _debug.get_open_handles(self.generation) - if leaks: - raise HPyLeakError(leaks) - - def __enter__(self): - self.start() - return self - - def __exit__(self, etype, evalue, tb): - self.stop() diff --git a/graalpython/lib-graalpython/modules/hpy/debug/pytest.py b/graalpython/lib-graalpython/modules/hpy/debug/pytest.py deleted file mode 100644 index f46a26f512..0000000000 --- a/graalpython/lib-graalpython/modules/hpy/debug/pytest.py +++ /dev/null @@ -1,54 +0,0 @@ -# MIT License -# -# Copyright (c) 2021, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# hpy.debug / pytest integration - -import pytest -from .leakdetector import LeakDetector - -# For now "hpy_debug" just does leak detection, but in the future it might -# grows extra features: that's why it's called generically "hpy_debug" instead -# of "detect_leaks". - -# NOTE: the fixture itself is currently untested :(. It turns out that testing -# that the fixture raises during the teardown is complicated and probably -# requires to write a full-fledged plugin. We might want to turn this into a -# real plugin in the future, but for now I think this is enough. - -# pypy still uses a very ancient version of pytest, 2.9.2: pytest<3.x needs to -# use @yield_fixture, which is deprecated in newer version of pytest (where -# you can just use @fixture) -if pytest.__version__ < '3': - fixture = pytest.yield_fixture -else: - fixture = pytest.fixture - -@fixture -def hpy_debug(request): - """ - pytest fixture which makes it possible to control hpy.debug from within a test. - - In particular, it automatically check that the test doesn't leak. - """ - with LeakDetector() as ld: - yield ld diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_bytes.c b/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_bytes.c deleted file mode 100644 index dde8fb5b66..0000000000 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_bytes.c +++ /dev/null @@ -1,49 +0,0 @@ -/* MIT License - * - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include "hpy.h" -#include "hpy/runtime/ctx_funcs.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - - -_HPy_HIDDEN HPy -ctx_Bytes_FromStringAndSize(HPyContext *ctx, const char *v, HPy_ssize_t len) -{ - if (v == NULL) { - // The CPython API allows passing a null pointer to - // PyBytes_FromStringAndSize and returns uninitialized memory of the - // requested size which can then be initialized after the call. - // In HPy the underlying memory is opaque and so cannot be initialized - // after the call and so we raise an error instead. - HPyErr_SetString(ctx, ctx->h_ValueError, - "NULL char * passed to HPyBytes_FromStringAndSize"); - return HPy_NULL; - } - return _py2h(PyBytes_FromStringAndSize(v, len)); -} diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_contextvar.c b/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_contextvar.c deleted file mode 100644 index f939b2e0a9..0000000000 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_contextvar.c +++ /dev/null @@ -1,40 +0,0 @@ -/* MIT License - * - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include "hpy.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - -_HPy_HIDDEN int32_t -ctx_ContextVar_Get(HPyContext *ctx, HPy context_var, HPy default_value, HPy *result) -{ - PyObject * py_result; - int32_t ret = PyContextVar_Get(_h2py(context_var), _h2py(default_value), &py_result); - *result = _py2h(py_result); - return ret; -} diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_err.c b/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_err.c deleted file mode 100644 index b8155aee61..0000000000 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_err.c +++ /dev/null @@ -1,37 +0,0 @@ -/* MIT License - * - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include "hpy.h" -#include "hpy/runtime/ctx_funcs.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - -_HPy_HIDDEN int -ctx_Err_Occurred(HPyContext *ctx) { - return PyErr_Occurred() ? 1 : 0; -} diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_eval.c b/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_eval.c deleted file mode 100644 index 356f4a2121..0000000000 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_eval.c +++ /dev/null @@ -1,47 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include "hpy.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - -_HPy_HIDDEN HPy -ctx_Compile_s(HPyContext *ctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind) -{ - int start; - switch (kind) - { - case HPy_SourceKind_Expr: start = Py_eval_input; break; - case HPy_SourceKind_File: start = Py_file_input; break; - case HPy_SourceKind_Single: start = Py_single_input; break; - default: - PyErr_SetString(PyExc_SystemError, "invalid source kind"); - return HPy_NULL; - } - return _py2h(Py_CompileString(utf8_source, utf8_filename, start)); -} diff --git a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_tuple.c b/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_tuple.c deleted file mode 100644 index a0dba716a8..0000000000 --- a/graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_tuple.c +++ /dev/null @@ -1,46 +0,0 @@ -/* MIT License - * - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include "hpy.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - - -_HPy_HIDDEN HPy -ctx_Tuple_FromArray(HPyContext *ctx, HPy items[], HPy_ssize_t n) -{ - PyObject *res = PyTuple_New(n); - if (!res) - return HPy_NULL; - for(HPy_ssize_t i=0; i=43", + "wheel", ++ "Cython==3.0.10", + ] + build-backend = "setuptools.build_meta" + + [tool.cibuildwheel] +-before-build = [ +- "pip install cython==3.0.10", +- "cython {project}/jq.pyx", +-] + test-requires = "-r test-requirements.txt" + test-command = "pytest {project}/tests" +diff --git a/setup.py b/setup.py +index 0b97097..54ed7b3 100644 +--- a/setup.py ++++ b/setup.py +@@ -94,15 +94,27 @@ else: + os.path.join(jq_lib_dir, "modules/oniguruma/src/.libs/libonig.a"), + ] + ++ ++try: ++ # Follow recommendation from https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#distributing-cython-modules ++ from Cython.Build import cythonize ++except ImportError: ++ cythonize = lambda o: o ++ ext = ".c" ++else: ++ ext = ".pyx" ++ ++ + jq_extension = Extension( + "jq", +- sources=["jq.c"], ++ sources=[_path_in_dir(f"jq{ext}")], + define_macros=[("MS_WIN64" , 1)] if os.name == "nt" and sys.maxsize > 2**32 else None, # https://github.com/cython/cython/issues/2670 + include_dirs=[os.path.join(jq_lib_dir, "src")], + extra_link_args=["-lm"] + (["-Wl,-Bstatic", "-lpthread", "-lshlwapi", "-static-libgcc"] if os.name == 'nt' else []) + link_args_deps, + extra_objects=extra_objects, + ) + ++ + setup( + name='jq', + version='1.8.0', +@@ -112,7 +124,7 @@ setup( + url='https://github.com/mwilliamson/jq.py', + python_requires='>=3.6', + license='BSD 2-Clause', +- ext_modules = [jq_extension], ++ ext_modules = cythonize([jq_extension]), + cmdclass={"build_ext": jq_build_ext}, + classifiers=[ + 'Development Status :: 5 - Production/Stable', diff --git a/graalpython/lib-graalpython/patches/lxml-4.9.1.patch b/graalpython/lib-graalpython/patches/lxml-4.9.patch similarity index 100% rename from graalpython/lib-graalpython/patches/lxml-4.9.1.patch rename to graalpython/lib-graalpython/patches/lxml-4.9.patch diff --git a/graalpython/lib-graalpython/patches/lxml-5.0.patch b/graalpython/lib-graalpython/patches/lxml-5.0.patch new file mode 100644 index 0000000000..67ecbb35dc --- /dev/null +++ b/graalpython/lib-graalpython/patches/lxml-5.0.patch @@ -0,0 +1,22 @@ +diff --git a/pyproject.toml b/pyproject.toml +new file mode 100644 +index 0000000..2a76435 +--- /dev/null ++++ b/pyproject.toml +@@ -0,0 +1,3 @@ ++[build-system] ++requires = ["setuptools >= 40.6.0", "wheel", "Cython==3.0.11"] ++build-backend = "setuptools.build_meta:__legacy__" +diff --git a/setupinfo.py b/setupinfo.py +index 5feb13b..6ea719a 100644 +--- a/setupinfo.py ++++ b/setupinfo.py +@@ -539,7 +539,7 @@ OPTION_WITH_UNICODE_STRINGS = has_option('with-unicode-strings') + OPTION_WITHOUT_ASSERT = has_option('without-assert') + OPTION_WITHOUT_THREADING = has_option('without-threading') + OPTION_WITHOUT_CYTHON = has_option('without-cython') +-OPTION_WITH_CYTHON = has_option('with-cython') ++OPTION_WITH_CYTHON = True # GraalVM change + OPTION_WITH_CYTHON_GDB = has_option('cython-gdb') + OPTION_WITH_REFNANNY = has_option('with-refnanny') + OPTION_WITH_COVERAGE = has_option('with-coverage') diff --git a/graalpython/lib-graalpython/patches/lxml-5.1.0.patch b/graalpython/lib-graalpython/patches/lxml-5.1.0.patch new file mode 100644 index 0000000000..97dfd3e8f5 --- /dev/null +++ b/graalpython/lib-graalpython/patches/lxml-5.1.0.patch @@ -0,0 +1,24 @@ +diff --git a/pyproject.toml b/pyproject.toml +index 85c9214..90c6da8 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -1,5 +1,6 @@ + [build-system] + requires = ["Cython>=3.0.7", "setuptools", "wheel"] ++build-backend = "setuptools.build_meta:__legacy__" + + [tool.cibuildwheel] + build-verbosity = 2 +diff --git a/setupinfo.py b/setupinfo.py +index d111128..5ad5a23 100644 +--- a/setupinfo.py ++++ b/setupinfo.py +@@ -536,7 +536,7 @@ OPTION_WITH_UNICODE_STRINGS = has_option('with-unicode-strings') + OPTION_WITHOUT_ASSERT = has_option('without-assert') + OPTION_WITHOUT_THREADING = has_option('without-threading') + OPTION_WITHOUT_CYTHON = has_option('without-cython') +-OPTION_WITH_CYTHON = has_option('with-cython') ++OPTION_WITH_CYTHON = True + OPTION_WITH_CYTHON_GDB = has_option('cython-gdb') + OPTION_WITH_REFNANNY = has_option('with-refnanny') + OPTION_WITH_COVERAGE = has_option('with-coverage') diff --git a/graalpython/lib-graalpython/patches/lxml-5.1.1.patch b/graalpython/lib-graalpython/patches/lxml-5.1.1.patch new file mode 100644 index 0000000000..2efbe28189 --- /dev/null +++ b/graalpython/lib-graalpython/patches/lxml-5.1.1.patch @@ -0,0 +1,24 @@ +diff --git a/pyproject.toml b/pyproject.toml +index e7f6bb6..230f261 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -1,5 +1,6 @@ + [build-system] + requires = ["Cython>=3.0.9", "setuptools", "wheel"] ++build-backend = "setuptools.build_meta:__legacy__" + + [tool.cibuildwheel] + build-verbosity = 2 +diff --git a/setupinfo.py b/setupinfo.py +index 43e283f..d415905 100644 +--- a/setupinfo.py ++++ b/setupinfo.py +@@ -564,7 +564,7 @@ OPTION_WITH_UNICODE_STRINGS = has_option('with-unicode-strings') + OPTION_WITHOUT_ASSERT = has_option('without-assert') + OPTION_WITHOUT_THREADING = has_option('without-threading') + OPTION_WITHOUT_CYTHON = has_option('without-cython') +-OPTION_WITH_CYTHON = has_option('with-cython') ++OPTION_WITH_CYTHON = True + OPTION_WITH_CYTHON_GDB = has_option('cython-gdb') + OPTION_WITH_REFNANNY = has_option('with-refnanny') + OPTION_WITH_COVERAGE = has_option('with-coverage') diff --git a/graalpython/lib-graalpython/patches/lxml-5.2.patch b/graalpython/lib-graalpython/patches/lxml-5.2.patch new file mode 100644 index 0000000000..f20eff3910 --- /dev/null +++ b/graalpython/lib-graalpython/patches/lxml-5.2.patch @@ -0,0 +1,24 @@ +diff --git a/pyproject.toml b/pyproject.toml +index 1720657..b3cd9ab 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -1,5 +1,6 @@ + [build-system] + requires = ["Cython>=3.0.10", "setuptools", "wheel"] ++build-backend = "setuptools.build_meta:__legacy__" + + [tool.cibuildwheel] + build-verbosity = 2 +diff --git a/setupinfo.py b/setupinfo.py +index 97e3399..9079171 100644 +--- a/setupinfo.py ++++ b/setupinfo.py +@@ -563,7 +563,7 @@ OPTION_WITH_UNICODE_STRINGS = has_option('with-unicode-strings') + OPTION_WITHOUT_ASSERT = has_option('without-assert') + OPTION_WITHOUT_THREADING = has_option('without-threading') + OPTION_WITHOUT_CYTHON = has_option('without-cython') +-OPTION_WITH_CYTHON = has_option('with-cython') ++OPTION_WITH_CYTHON = True + OPTION_WITH_CYTHON_GDB = has_option('cython-gdb') + OPTION_WITH_REFNANNY = has_option('with-refnanny') + OPTION_WITH_COVERAGE = has_option('with-coverage') diff --git a/graalpython/lib-graalpython/patches/lxml-5.4.0.patch b/graalpython/lib-graalpython/patches/lxml-5.4.0.patch new file mode 100644 index 0000000000..93bf808911 --- /dev/null +++ b/graalpython/lib-graalpython/patches/lxml-5.4.0.patch @@ -0,0 +1,24 @@ +diff --git a/pyproject.toml b/pyproject.toml +index f2edb28..259ed3c 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -1,5 +1,6 @@ + [build-system] + requires = ["Cython>=3.0.11, < 3.1.0", "setuptools", "wheel"] ++build-backend = "setuptools.build_meta:__legacy__" + + [tool.cibuildwheel] + build-verbosity = 1 +diff --git a/setupinfo.py b/setupinfo.py +index 2aa3dca..e715c86 100644 +--- a/setupinfo.py ++++ b/setupinfo.py +@@ -557,7 +557,7 @@ OPTION_WITH_UNICODE_STRINGS = has_option('with-unicode-strings') + OPTION_WITHOUT_ASSERT = has_option('without-assert') + OPTION_WITHOUT_THREADING = has_option('without-threading') + OPTION_WITHOUT_CYTHON = has_option('without-cython') +-OPTION_WITH_CYTHON = has_option('with-cython') ++OPTION_WITH_CYTHON = True + OPTION_WITH_CYTHON_GDB = has_option('cython-gdb') + OPTION_WITH_REFNANNY = has_option('with-refnanny') + OPTION_WITH_COVERAGE = has_option('with-coverage') diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml index 7356d3a129..84502ba38a 100644 --- a/graalpython/lib-graalpython/patches/metadata.toml +++ b/graalpython/lib-graalpython/patches/metadata.toml @@ -48,9 +48,6 @@ version = '== 2.2.1' patch = 'cloudpickle-2.2.1.patch' license = 'BSD-3-Clause' -[[cppy.rules]] -version = '==1.2.1' - [[cramjam.rules]] version = '== 2.7.0' patch = 'cramjam-2.7.0.patch' @@ -105,7 +102,7 @@ patch = 'cryptography-42.0.5.patch' license = 'Apache-2.0 OR BSD-3-Clause' [[Cython.rules]] -version = '>= 3.0.10, < 3.0.12' +version = '>= 3.0.10, <= 3.0.12' patch = 'Cython-3.0.10.patch' license = 'Apache-2.0' @@ -155,6 +152,14 @@ version = '>= 1.64.0' patch = 'grpcio-1.66.1.patch' license = 'Apache-2.0' +[[grpcio.rules]] +# Force re-cythonize + other fixes +# The rc version won't get matched by the version range above +version = '== 1.72.0rc1' +install-priority = 0 +patch = 'grpcio-1.66.1.patch' +license = 'Apache-2.0' + [[h2o.rules]] patch = 'h2o.patch' license = 'Apache-2.0' @@ -200,6 +205,15 @@ version = '<=1.3.2' patch = 'joblib-1.3.2.patch' license = 'BSD-3-Clause' +[[jq.rules]] +version = '==1.8.0' +patch = 'jq-1.8.0.patch' +license = 'BSD-2-Clause' + +[[jq.add-sources]] +version = '1.8.0' +url = 'https://github.com/mwilliamson/jq.py/archive/refs/tags/1.8.0.tar.gz' + [[jupyter_server.rules]] patch = 'jupyter_server.patch' license = 'BSD-3-Clause' @@ -227,13 +241,38 @@ patch = 'llvmlite.patch' license = 'BSD-2-Clause' [[lxml.rules]] -version = '== 5.3.0' +version = '>= 5.3.2, <= 5.4.0' +patch = 'lxml-5.4.0.patch' +license = 'BSD-3-Clause' + +[[lxml.rules]] +version = '>= 5.3.0, < 5.3.2' patch = 'lxml-5.3.0.patch' license = 'BSD-3-Clause' [[lxml.rules]] -version = '== 4.9.1' -patch = 'lxml-4.9.1.patch' +version = '== 5.2.*' +patch = 'lxml-5.2.patch' +license = 'BSD-3-Clause' + +[[lxml.rules]] +version = '== 5.1.1' +patch = 'lxml-5.1.1.patch' +license = 'BSD-3-Clause' + +[[lxml.rules]] +version = '== 5.1.0' +patch = 'lxml-5.1.0.patch' +license = 'BSD-3-Clause' + +[[lxml.rules]] +version = '== 5.0.*' +patch = 'lxml-5.0.patch' +license = 'BSD-3-Clause' + +[[lxml.rules]] +version = '>= 4.9, < 5' +patch = 'lxml-4.9.patch' license = 'BSD-3-Clause' # Patch already upstreamed, keeping it around for older versions @@ -251,10 +290,6 @@ install-priority = 0 patch = 'meson-python.patch' license = 'MIT' -[[ml_dtypes.rules]] -# 0.4.0 requires numpy==2.0rc1 -version = "< 0.4.0" - [[mlx.rules]] patch = 'mlx.patch' license = 'MIT' @@ -287,7 +322,7 @@ patch = 'numba-0.59.1.patch' license = 'BSD-2-Clause' [[numpy.rules]] -version = '>= 2.0.0rc1, < 2.1' +version = '>= 2.0.0rc1, < 2.3' patch = 'numpy-2.0.0.patch' license = 'BSD-3-Clause' dist-type = 'sdist' @@ -337,6 +372,11 @@ version = '== 3.10.5' patch = 'orjson-3.10.5.patch' license = 'Apache-2.0 OR MIT' +[[ormsgpack.rules]] +version = '>= 1.8.0, <= 1.9.1' +patch = 'ormsgpack-1.8.0-1.9.1.patch' +license = 'Apache-2.0 OR MIT' + [[overrides.rules]] version = '== 7.4.0' # Important: This patch esentially breaks the package, it's not upstreamable. The package relies on bytecode parsing @@ -358,6 +398,12 @@ patch = 'pandas-2.2.2.patch' license = 'BSD-3-Clause' dist-type = 'sdist' +[[pandas.rules]] +version = '== 2.2.3' +patch = 'pandas-2.2.3.patch' +license = 'BSD-3-Clause' +dist-type = 'sdist' + [[pandas.rules]] version = '== 2.0.3' patch = 'pandas-2.0.3.patch' @@ -375,7 +421,6 @@ version = '== 3.0.0' patch = 'pendulum-3.0.0.patch' license = 'MIT' - [[pip.rules]] version = '== 23.2.1' patch = 'pip-23.2.1.patch' @@ -388,10 +433,19 @@ patch = 'prompt_toolkit.patch' license = 'BSD-3-Clause' [[protobuf.rules]] +patch = 'protobuf.patch' +license = 'BSD-3-Clause' +# There are 'none-any' wheels on pypi, this is only needed on sdists +dist-type = 'sdist' +install-priority = 0 + +[[protobuf.rules]] +# msimacek: This version doesn't exist, but the patch file is referenced from the tensorflow patch which I'm afraid to touch version = '== 3.21.9' -# Also referenced outside of pip from tensorflow patches patch = 'protobuf-3.21.9.patch' license = 'BSD-3-Clause' +dist-type = 'sdist' +install-priority = 0 [[psycopg2.rules]] version = '<= 2.9.9' @@ -433,6 +487,11 @@ version = '== 19.0.0' patch = 'pyarrow-19.0.0.patch' license = 'Apache-2.0' +[[pyarrow.rules]] +version = '== 19.0.1' +patch = 'pyarrow-19.0.1.patch' +license = 'Apache-2.0' + [[pybind11.rules]] # Upstreamed install-priority = 0 @@ -450,27 +509,33 @@ version = '>= 2.10.1, < 2.11.0' patch = 'pybind11-2.10.1.patch' license = 'BSD-3-Clause' -[[pydantic.rules]] -# Pin to match our pinned pydantic-core -version = '== 2.10.3' - [[pydantic-core.rules]] version = '== 2.10.1' +install-priority = 0 patch = 'pydantic-core-2.10.1.patch' license = 'MIT' [[pydantic-core.rules]] version = '== 2.23.4' +install-priority = 0 patch = 'pydantic-core-2.23.4.patch' license = 'MIT' [[pydantic-core.rules]] version = '== 2.27.1' +install-priority = 0 +patch = 'pydantic-core-2.27.1.patch' +license = 'MIT' + +[[pydantic-core.rules]] +version = '== 2.27.2' +install-priority = 0 patch = 'pydantic-core-2.27.1.patch' license = 'MIT' [[pydantic-core.rules]] version = '== 2.26.0' +install-priority = 0 patch = 'pydantic-core-2.26.0.patch' license = 'MIT' @@ -483,6 +548,11 @@ version = '== 2.*' patch = 'pygame-2.patch' license = 'LGPL-2.0-or-later' +[[pygobject.rules]] +version = '== 3.52.3' +patch = 'pygobject-3.52.3.patch' +license = 'LGPL-2.0-or-later' + [[pymongo.rules]] version = "< 4.8.0" patch = 'pymongo.patch' @@ -493,26 +563,27 @@ version = ">= 4.8.0" patch = 'pymongo-4.8.0.patch' license = 'Apache-2.0' -[[pyOpenSSL.rules]] -# Pin this version to avoid pulling newer cryptography than we have patch for -version = "== 23.2.0" - -[[pyparsing.rules]] -version = '== 3.0.8' +[[PyMuPDF.rules]] +version = "== 1.25.4" +patch = "pymupdf.patch" +# That project is AGPL, so do not actually include *any* code of pymupdf in the patch, not even an +# empty line, in the diff context. The code we write in the patch is UPL - that is compatible with +# AGPL in the sense that if someone were to apply it and distribute *that*, our patch is now part +# of the AGPL'd codebase +license = 'UPL' [[pyperf.rules]] version = '== 2.3.0' +install-priority = 0 patch = 'pyperf-2.3.0.patch' license = 'MIT' [[pyperf.rules]] version = '== 2.3.1' +install-priority = 0 patch = 'pyperf-2.3.1.patch' license = 'MIT' -[[pyperf.rules]] -version = '== 2.5.0' - [[pyperformance.rules]] version = '== 1.0.5' patch = 'pyperformance-1.0.5.patch' @@ -535,22 +606,41 @@ patch = 'pythran-0.13.patch' license = 'BSD-3-Clause' [[pythran.rules]] -version = '>= 0.14' +version = '>= 0.14, < 0.16' patch = 'pythran-0.15.patch' license = 'BSD-3-Clause' +[[pythran.rules]] +version = '>= 0.16' +patch = 'pythran-0.16.patch' +license = 'BSD-3-Clause' + [[pyzmq.rules]] -# 26+ needs Cython 3 version = '< 26' +install-priority = 0 # The patch just makes it re-cythonize to pick up our cython changes patch = 'pyzmq.patch' license = 'BSD-3-Clause' dist-type = 'sdist' [[rapidfuzz.rules]] +version = '< 3.10' patch = 'rapidfuzz.patch' license = 'MIT' +[[rapidfuzz.rules]] +version = '>= 3.10.0, <= 3.12.2' +patch = 'rapidfuzz-3.10.patch' +license = 'MIT' + +[[levenshtein.add-sources]] +version = '0.26.1' +url = 'https://github.com/rapidfuzz/Levenshtein/archive/refs/tags/v0.26.1.zip' + +[[levenshtein.add-sources]] +version = '0.27.1' +url = 'https://github.com/rapidfuzz/Levenshtein/archive/refs/tags/v0.27.1.zip' + [[ray.rules]] version = '== 2.3.0' patch = 'ray-2.3.0.patch' @@ -569,10 +659,6 @@ license = 'Apache-2.0' version = '2.9.1' url = 'https://github.com/ray-project/ray/archive/refs/tags/ray-2.9.1.tar.gz' -[[readme-renderer.rules]] -# Newer version depends nh3 which is built with maturin, which is currently broken -version = '< 42' - [[rpds_py.rules]] # Patch not needed anymore in recent version since pyo3 changes have been upstreamed install-priority = 0 @@ -587,6 +673,11 @@ version = '== 0.3.3' patch = 'safetensors-0.3.3.patch' license = 'Apache-2.0' +[[scikit-build-core.rules]] +version = '~= 0.11.0' +patch = 'scikit-build-core.patch' +license = 'Apache-2.0' + [[scikit-learn.rules]] version = '== 1.5.2' patch = 'scikit-learn-1.5.2.patch' @@ -605,11 +696,9 @@ patch = 'scikit-learn-1.1.3.patch' license = 'BSD-3-Clause' dist-type = 'sdist' -[[scipy.rules]] -version = '== 1.13.1' - [[scipy.rules]] version = '== 1.10.1' +install-priority = 0 patch = 'scipy-1.10.1.patch' license = 'BSD-3-Clause' dist-type = 'sdist' @@ -619,10 +708,6 @@ version = '>= 1.2.2' patch = 'setproctitle-1.2.2.patch' license = 'BSD-3-Clause' -[[statsmodels.rules]] -# Pin older versions for now, the new ones require numpy-2rc1 and cython 3 -version = '<= 0.14.1' - [[tensorflow.rules]] version = '== 2.15.0' patch = 'tensorflow-2.15.0.patch' @@ -661,21 +746,19 @@ url = 'https://github.com/tensorflow/io/archive/refs/tags/v0.34.0.tar.gz' [[tiktoken.rules]] version = '== 0.7.0' +install-priority = 0 patch = 'tiktoken-0.7.0.patch' license = 'MIT' -[[tokenizers.rules]] -version = '>= 0.19' -patch = 'tokenizers-0.19-plus.patch' -license = 'Apache-2.0' - [[tokenizers.rules]] version = '== 0.13.3' +install-priority = 0 patch = 'tokenizers-0.13.3.patch' license = 'Apache-2.0' [[tokenizers.rules]] version = '== 0.15.0' +install-priority = 0 patch = 'tokenizers-0.15.0.patch' license = 'Apache-2.0' @@ -697,6 +780,12 @@ patch = 'torch-2.4.1.patch' license = 'BSD-3-Clause' dist-type = 'sdist' +[[torch.rules]] +version = '== 2.7.0' +patch = 'torch-2.7.0.patch' +license = 'BSD-3-Clause' +dist-type = 'sdist' + [[torch.add-sources]] version = '1.13.1' url = 'https://github.com/pytorch/pytorch/releases/download/v1.13.1/pytorch-v1.13.1.tar.gz' @@ -709,9 +798,22 @@ url = 'https://github.com/pytorch/pytorch/releases/download/v2.2.1/pytorch-v2.2.%20version%20='2.4.1' url = 'https://github.com/pytorch/pytorch/releases/download/v2.4.1/pytorch-v2.4.1.tar.gz' +[[torch.add-sources]] +version = '2.7.0' +url = 'https://github.com/pytorch/pytorch/releases/download/v2.7.0/pytorch-v2.7.0.tar.gz' + +[[torchvision.rules]] +version = '== 0.22.0' +patch = 'torchvision-0.22.0.patch' +license = 'BSD-3-Clause' + +[[torchvision.add-sources]] +version = '0.19.1' +url = 'https://github.com/pytorch/vision/archive/refs/tags/v0.22.0.tar.gz' + [[torchvision.rules]] version = '== 0.19.1' -patch = 'torchvision-1.19.1.patch' +patch = 'torchvision-0.19.1.patch' license = 'BSD-3-Clause' [[torchvision.add-sources]] @@ -720,19 +822,16 @@ url = 'https://github.com/pytorch/vision/archive/refs/tags/v0.19.1.tar.gz' [[torchvision.rules]] version = '== 0.17.1' -patch = 'torchvision-1.17.1.patch' +patch = 'torchvision-0.17.1.patch' license = 'BSD-3-Clause' [[torchvision.add-sources]] version = '0.17.1' url = 'https://github.com/pytorch/vision/archive/refs/tags/v0.17.1.tar.gz' -[[tox.rules]] -version = '== 3.*' - -[[transformers.rules]] -# transformers tends to depend on a specific version of tokenizers. Pin it to avoid pulling unpatched tokenizers -version = '== 4.33.3' +[[trio.rules]] +patch = 'trio.patch' +license = 'Apache-2.0 OR MIT' [[typing_extensions.rules]] patch = 'typing_extensions.patch' @@ -749,6 +848,7 @@ version = '>= 2, < 2.0.3' install-priority = 0 [[uvloop.rules]] +version = '<= 0.19.0' patch = 'uvloop.patch' license = 'MIT' @@ -815,6 +915,13 @@ license = 'MIT' subdir = 'src' install-priority = 0 +[[xmlschema.rules]] +version = '>= 4.0.0, <= 4.0.1' +# Submitted upstream, optimistically assuming it'll get merged before the next release +install-priority = 0 +patch = 'xmlschema.patch' +license = 'MIT' + [[zstandard.rules]] patch = 'zstandard.patch' license = 'BSD-3-Clause' diff --git a/graalpython/lib-graalpython/patches/numpy-1.26.4.patch b/graalpython/lib-graalpython/patches/numpy-1.26.4.patch index a42d76ba53..d382e5bf16 100644 --- a/graalpython/lib-graalpython/patches/numpy-1.26.4.patch +++ b/graalpython/lib-graalpython/patches/numpy-1.26.4.patch @@ -92,15 +92,3 @@ index 1c59bf3..519fabc 100644 volatile char NPY_UNUSED(c) = *(char *)param; } -diff --git a/vendored-meson/meson/mesonbuild/utils/universal.py b/vendored-meson/meson/mesonbuild/utils/universal.py -index 1694912..a555fe3 100644 ---- a/vendored-meson/meson/mesonbuild/utils/universal.py -+++ b/vendored-meson/meson/mesonbuild/utils/universal.py -@@ -727,6 +727,7 @@ def windows_detect_native_arch() -> str: - """ - if sys.platform != 'win32': - return '' -+ return 'amd64' # Workaround for GraalPy bug on Windows with kernel32.GetCurrentProcess() - try: - import ctypes - process_arch = ctypes.c_ushort() diff --git a/graalpython/lib-graalpython/patches/numpy-2.0.0.patch b/graalpython/lib-graalpython/patches/numpy-2.0.0.patch index a381cefd59..4df9996c99 100644 --- a/graalpython/lib-graalpython/patches/numpy-2.0.0.patch +++ b/graalpython/lib-graalpython/patches/numpy-2.0.0.patch @@ -105,15 +105,3 @@ index 1c59bf3..519fabc 100644 volatile char NPY_UNUSED(c) = *(char *)param; } -diff --git a/vendored-meson/meson/mesonbuild/utils/universal.py b/vendored-meson/meson/mesonbuild/utils/universal.py -index 1694912..a555fe3 100644 ---- a/vendored-meson/meson/mesonbuild/utils/universal.py -+++ b/vendored-meson/meson/mesonbuild/utils/universal.py -@@ -727,6 +727,7 @@ def windows_detect_native_arch() -> str: - """ - if sys.platform != 'win32': - return '' -+ return 'amd64' # Workaround for GraalPy bug on Windows with kernel32.GetCurrentProcess() - try: - import ctypes - process_arch = ctypes.c_ushort() diff --git a/graalpython/lib-graalpython/patches/ormsgpack-1.8.0-1.9.1.patch b/graalpython/lib-graalpython/patches/ormsgpack-1.8.0-1.9.1.patch new file mode 100644 index 0000000000..3a9542a058 --- /dev/null +++ b/graalpython/lib-graalpython/patches/ormsgpack-1.8.0-1.9.1.patch @@ -0,0 +1,364 @@ +diff --git a/src/deserialize/deserializer.rs b/src/deserialize/deserializer.rs +index 41cf7f1..99cd68e 100644 +--- a/src/deserialize/deserializer.rs ++++ b/src/deserialize/deserializer.rs +@@ -292,7 +292,10 @@ impl<'de> Deserializer<'de> { + marker => Err(Error::InvalidType(marker)), + }?; + let value = self.deserialize()?; ++ #[cfg(not(GraalPy))] + let pyhash = unsafe { (*key.as_ptr().cast::()).hash }; ++ #[cfg(GraalPy)] ++ let pyhash = unsafe { pyo3::ffi::PyObject_Hash(key.as_ptr()) }; + let _ = ffi!(_PyDict_SetItem_KnownHash( + dict_ptr, + key.as_ptr(), +@@ -471,7 +474,7 @@ impl<'de> Deserializer<'de> { + let ptr = ffi!(PyTuple_New(len as pyo3::ffi::Py_ssize_t)); + for i in 0..len { + let elem = self.deserialize_map_key()?; +- ffi!(PyTuple_SET_ITEM( ++ ffi!(PyTuple_SetItem( + ptr, + i as pyo3::ffi::Py_ssize_t, + elem.as_ptr() +diff --git a/src/ext.rs b/src/ext.rs +index b2573b4..9668d4f 100644 +--- a/src/ext.rs ++++ b/src/ext.rs +@@ -22,7 +22,7 @@ unsafe extern "C" fn ext_new( + ); + return null_mut(); + } +- let tag = PyTuple_GET_ITEM(args, 0); ++ let tag = PyTuple_GetItem(args, 0); + if PyLong_Check(tag) == 0 { + PyErr_SetString( + PyExc_TypeError, +@@ -30,7 +30,7 @@ unsafe extern "C" fn ext_new( + ); + return null_mut(); + } +- let data = PyTuple_GET_ITEM(args, 1); ++ let data = PyTuple_GetItem(args, 1); + if PyBytes_Check(data) == 0 { + PyErr_SetString( + PyExc_TypeError, +diff --git a/src/ffi.rs b/src/ffi.rs +index 4e5ddc3..20c9db4 100644 +--- a/src/ffi.rs ++++ b/src/ffi.rs +@@ -7,13 +7,16 @@ use std::ptr::NonNull; + #[allow(non_snake_case)] + #[inline(always)] + pub unsafe fn PyBytes_AS_STRING(op: *mut PyObject) -> *const c_char { +- &(*op.cast::()).ob_sval as *const c_char ++ #[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API)))] ++ return &(*op.cast::()).ob_sval as *const c_char; ++ #[cfg(any(PyPy, GraalPy, Py_LIMITED_API))] ++ return crate::PyBytes_AsString(op); + } + + #[allow(non_snake_case)] + #[inline(always)] + pub unsafe fn PyBytes_GET_SIZE(op: *mut PyObject) -> Py_ssize_t { +- (*op.cast::()).ob_size ++ Py_SIZE(op) + } + + #[repr(C)] +@@ -63,11 +66,21 @@ pub fn pylong_is_positive(op: *mut PyObject) -> bool { + unsafe { (*(op as *mut PyLongObject)).long_value.lv_tag & SIGN_MASK == 0 } + } + +-#[cfg(not(Py_3_12))] ++#[cfg(not(any(Py_3_12, GraalPy)))] + pub fn pylong_is_positive(op: *mut PyObject) -> bool { + unsafe { (*(op as *mut PyVarObject)).ob_size > 0 } + } + ++extern "C" { ++ #[cfg(not(PyPy))] ++ pub fn _PyLong_Sign(v: *mut PyObject) -> c_int; ++} ++ ++#[cfg(GraalPy)] ++pub fn pylong_is_positive(op: *mut PyObject) -> bool { ++ unsafe { _PyLong_Sign(op) > 0 } ++} ++ + pub struct PyDictIter { + op: *mut PyObject, + pos: isize, +diff --git a/src/lib.rs b/src/lib.rs +index f10b1c4..1a9768b 100644 +--- a/src/lib.rs ++++ b/src/lib.rs +@@ -143,7 +143,7 @@ fn raise_unpackb_exception(msg: &str) -> *mut PyObject { + let err_msg = + PyUnicode_FromStringAndSize(msg.as_ptr() as *const c_char, msg.len() as isize); + let args = PyTuple_New(1); +- PyTuple_SET_ITEM(args, 0, err_msg); ++ PyTuple_SetItem(args, 0, err_msg); + PyErr_SetObject(typeref::MsgpackDecodeError, args); + Py_DECREF(args); + }; +@@ -199,10 +199,10 @@ pub unsafe extern "C" fn unpackb( + if !kwnames.is_null() { + let tuple_size = PyTuple_GET_SIZE(kwnames); + for i in 0..tuple_size { +- let arg = PyTuple_GET_ITEM(kwnames, i as Py_ssize_t); +- if arg == typeref::EXT_HOOK { ++ let arg = PyTuple_GetItem(kwnames, i as Py_ssize_t); ++ if PyUnicode_Compare(arg, typeref::EXT_HOOK) == 0 { + ext_hook = Some(NonNull::new_unchecked(*args.offset(num_args + i))); +- } else if arg == typeref::OPTION { ++ } else if PyUnicode_Compare(arg, typeref::OPTION) == 0 { + optsptr = Some(NonNull::new_unchecked(*args.offset(num_args + i))); + } else { + return raise_unpackb_exception("unpackb() got an unexpected keyword argument"); +@@ -247,15 +247,15 @@ pub unsafe extern "C" fn packb( + if !kwnames.is_null() { + let tuple_size = PyTuple_GET_SIZE(kwnames); + for i in 0..tuple_size { +- let arg = PyTuple_GET_ITEM(kwnames, i as Py_ssize_t); +- if arg == typeref::DEFAULT { ++ let arg = PyTuple_GetItem(kwnames, i as Py_ssize_t); ++ if PyUnicode_Compare(arg, typeref::DEFAULT) == 0 { + if unlikely!(default.is_some()) { + return raise_packb_exception( + "packb() got multiple values for argument: 'default'", + ); + } + default = Some(NonNull::new_unchecked(*args.offset(num_args + i))); +- } else if arg == typeref::OPTION { ++ } else if PyUnicode_Compare(arg, typeref::OPTION) == 0 { + if unlikely!(optsptr.is_some()) { + return raise_packb_exception( + "packb() got multiple values for argument: 'option'", +diff --git a/src/serialize/datetime.rs b/src/serialize/datetime.rs +index 63212d6..5ac2b2b 100644 +--- a/src/serialize/datetime.rs ++++ b/src/serialize/datetime.rs +@@ -61,9 +61,14 @@ pub struct Time { + + impl Time { + pub fn new(ptr: *mut pyo3::ffi::PyObject, opts: Opt) -> Result { ++ #[cfg(not(GraalPy))] + if unsafe { (*(ptr as *mut pyo3::ffi::PyDateTime_Time)).hastzinfo != 0 } { + return Err(TimeError::HasTimezone); + } ++ #[cfg(GraalPy)] ++ if unsafe { pyo3::ffi::PyDateTime_TIME_GET_TZINFO(ptr) != crate::typeref::NONE } { ++ return Err(TimeError::HasTimezone); ++ } + Ok(Time { + ptr: ptr, + opts: opts, +@@ -114,23 +119,28 @@ impl std::fmt::Display for DateTimeError { + } + + fn utcoffset(ptr: *mut pyo3::ffi::PyObject) -> Result { ++ #[cfg(not(GraalPy))] + if !unsafe { (*(ptr as *mut pyo3::ffi::PyDateTime_DateTime)).hastzinfo == 1 } { + return Ok(Offset::default()); + } + + let tzinfo = ffi!(PyDateTime_DATE_GET_TZINFO(ptr)); ++ #[cfg(GraalPy)] ++ if unsafe { tzinfo == crate::typeref::NONE } { ++ return Ok(Offset::default()); ++ } + let py_offset: *mut pyo3::ffi::PyObject; + if ffi!(PyObject_HasAttr(tzinfo, CONVERT_METHOD_STR)) == 1 { + // pendulum +- py_offset = ffi!(PyObject_CallMethodNoArgs(ptr, UTCOFFSET_METHOD_STR)); ++ py_offset = unsafe { pyo3::ffi::compat::PyObject_CallMethodNoArgs(ptr, UTCOFFSET_METHOD_STR) }; + } else if ffi!(PyObject_HasAttr(tzinfo, NORMALIZE_METHOD_STR)) == 1 { + // pytz +- let normalized = ffi!(PyObject_CallMethodOneArg(tzinfo, NORMALIZE_METHOD_STR, ptr)); +- py_offset = ffi!(PyObject_CallMethodNoArgs(normalized, UTCOFFSET_METHOD_STR)); ++ let normalized = ffi!(PyObject_CallMethodObjArgs(tzinfo, NORMALIZE_METHOD_STR, ptr, std::ptr::null_mut::())); ++ py_offset = unsafe { pyo3::ffi::compat::PyObject_CallMethodNoArgs(normalized, UTCOFFSET_METHOD_STR) }; + ffi!(Py_DECREF(normalized)); + } else if ffi!(PyObject_HasAttr(tzinfo, DST_STR)) == 1 { + // dateutil/arrow, datetime.timezone.utc +- py_offset = ffi!(PyObject_CallMethodOneArg(tzinfo, UTCOFFSET_METHOD_STR, ptr)); ++ py_offset = ffi!(PyObject_CallMethodObjArgs(tzinfo, UTCOFFSET_METHOD_STR, ptr, std::ptr::null_mut::())); + } else { + return Err(DateTimeError::LibraryUnsupported); + } +@@ -193,7 +203,10 @@ impl TimeLike for DateTime { + + impl DateTimeLike for DateTime { + fn has_tz(&self) -> bool { +- unsafe { (*(self.ptr as *mut pyo3::ffi::PyDateTime_DateTime)).hastzinfo == 1 } ++ #[cfg(not(GraalPy))] ++ return unsafe { (*(self.ptr as *mut pyo3::ffi::PyDateTime_DateTime)).hastzinfo == 1 }; ++ #[cfg(GraalPy)] ++ return unsafe { pyo3::ffi::PyDateTime_TIME_GET_TZINFO(self.ptr) != crate::typeref::NONE }; + } + + fn offset(&self) -> Offset { +diff --git a/src/serialize/numpy.rs b/src/serialize/numpy.rs +index afc5cdf..4d007bd 100644 +--- a/src/serialize/numpy.rs ++++ b/src/serialize/numpy.rs +@@ -392,8 +392,8 @@ impl NumpyDatetimeUnit { + fn from_pyobject(ptr: *mut PyObject) -> Self { + let dtype = ffi!(PyObject_GetAttr(ptr, DTYPE_STR)); + let descr = ffi!(PyObject_GetAttr(dtype, DESCR_STR)); +- let el0 = ffi!(PyList_GET_ITEM(descr, 0)); +- let descr_str = ffi!(PyTuple_GET_ITEM(el0, 1)); ++ let el0 = ffi!(PyList_GetItem(descr, 0)); ++ let descr_str = ffi!(PyTuple_GetItem(el0, 1)); + let uni = crate::unicode::unicode_to_str(descr_str).unwrap(); + if uni.len() < 5 { + return Self::NaT; +diff --git a/src/serialize/serializer.rs b/src/serialize/serializer.rs +index 309e6e1..6f7dec7 100644 +--- a/src/serialize/serializer.rs ++++ b/src/serialize/serializer.rs +@@ -864,7 +864,7 @@ impl Serialize for DictTupleKey { + let len = ffi!(PyTuple_GET_SIZE(self.ptr)) as usize; + let mut seq = serializer.serialize_seq(Some(len)).unwrap(); + for i in 0..len { +- let item = ffi!(PyTuple_GET_ITEM(self.ptr, i as isize)); ++ let item = ffi!(PyTuple_GetItem(self.ptr, i as isize)); + let value = DictKey::new(item, self.opts, self.recursion + 1); + seq.serialize_element(&value)?; + } +diff --git a/src/serialize/tuple.rs b/src/serialize/tuple.rs +index fa81cb6..9b66019 100644 +--- a/src/serialize/tuple.rs ++++ b/src/serialize/tuple.rs +@@ -41,7 +41,7 @@ impl Serialize for Tuple { + let len = ffi!(PyTuple_GET_SIZE(self.ptr)) as usize; + let mut seq = serializer.serialize_seq(Some(len)).unwrap(); + for i in 0..len { +- let item = ffi!(PyTuple_GET_ITEM(self.ptr, i as isize)); ++ let item = ffi!(PyTuple_GetItem(self.ptr, i as isize)); + let value = PyObject::new( + item, + self.opts, +diff --git a/src/serialize/writer.rs b/src/serialize/writer.rs +index a790bdd..35346d9 100644 +--- a/src/serialize/writer.rs ++++ b/src/serialize/writer.rs +@@ -27,7 +27,6 @@ impl BytesWriter { + pub fn finish(&mut self) -> NonNull { + unsafe { + std::ptr::write(self.buffer_ptr(), 0); +- (*self.bytes.cast::()).ob_size = self.len as Py_ssize_t; + self.resize(self.len); + NonNull::new_unchecked(self.bytes as *mut PyObject) + } +@@ -35,10 +34,14 @@ impl BytesWriter { + + fn buffer_ptr(&self) -> *mut u8 { + unsafe { +- std::mem::transmute::<*mut [c_char; 1], *mut u8>(std::ptr::addr_of_mut!( ++ #[cfg(not(GraalPy))] ++ return std::mem::transmute::<*mut [c_char; 1], *mut u8>(std::ptr::addr_of_mut!( + (*self.bytes).ob_sval + )) +- .add(self.len) ++ .add(self.len); ++ #[cfg(GraalPy)] ++ return std::mem::transmute::<*mut i8, *mut u8>(PyBytes_AsString(self.bytes.cast::())) ++ .add(self.len); + } + } + +diff --git a/src/unicode.rs b/src/unicode.rs +index 53aca09..552fa6c 100644 +--- a/src/unicode.rs ++++ b/src/unicode.rs +@@ -6,6 +6,7 @@ use pyo3::ffi::*; + + // see unicodeobject.h for documentation + ++#[cfg(not(GraalPy))] + pub fn unicode_from_str(buf: &str) -> *mut PyObject { + if buf.is_empty() { + ffi!(Py_INCREF(EMPTY_UNICODE)); +@@ -27,6 +28,13 @@ pub fn unicode_from_str(buf: &str) -> *mut PyObject { + } + } + ++#[cfg(GraalPy)] ++pub fn unicode_from_str(buf: &str) -> *mut PyObject { ++ unsafe { ++ PyUnicode_FromStringAndSize(buf.as_ptr() as *const i8, buf.len() as isize) ++ } ++} ++ + fn pyunicode_ascii(buf: &str) -> *mut PyObject { + unsafe { + let ptr = ffi!(PyUnicode_New(buf.len() as isize, 127)); +@@ -80,6 +88,7 @@ fn pyunicode_fourbyte(buf: &str, num_chars: usize) -> *mut PyObject { + + #[inline] + pub fn hash_str(op: *mut PyObject) -> Py_hash_t { ++ #[cfg(not(GraalPy))] + unsafe { + let data_ptr: *mut c_void = if (*op.cast::()).compact() == 1 + && (*op.cast::()).ascii() == 1 +@@ -92,7 +101,11 @@ pub fn hash_str(op: *mut PyObject) -> Py_hash_t { + (*(op as *mut PyASCIIObject)).length * ((*(op as *mut PyASCIIObject)).kind()) as isize; + let hash = _Py_HashBytes(data_ptr, num_bytes); + (*op.cast::()).hash = hash; +- hash ++ return hash; ++ } ++ #[cfg(GraalPy)] ++ unsafe { ++ return PyObject_Hash(op); + } + } + +@@ -109,19 +122,24 @@ pub fn unicode_to_str_via_ffi(op: *mut PyObject) -> Option<&'static str> { + + #[inline] + pub fn unicode_to_str(op: *mut PyObject) -> Option<&'static str> { ++ #[cfg(not(GraalPy))] + unsafe { + if unlikely!((*op.cast::()).compact() == 0) { +- unicode_to_str_via_ffi(op) ++ return unicode_to_str_via_ffi(op); + } else if (*op.cast::()).ascii() == 1 { + let ptr = op.cast::().offset(1) as *const u8; + let len = (*op.cast::()).length as usize; +- Some(str_from_slice!(ptr, len)) ++ return Some(str_from_slice!(ptr, len)); + } else if (*op.cast::()).utf8_length != 0 { + let ptr = (*op.cast::()).utf8 as *const u8; + let len = (*op.cast::()).utf8_length as usize; +- Some(str_from_slice!(ptr, len)) ++ return Some(str_from_slice!(ptr, len)); + } else { +- unicode_to_str_via_ffi(op) ++ return unicode_to_str_via_ffi(op); + } + } ++ #[cfg(GraalPy)] ++ unsafe { ++ return unicode_to_str_via_ffi(op); ++ } + } +diff --git a/src/util.rs b/src/util.rs +index 2bcc32d..89faf1a 100644 +--- a/src/util.rs ++++ b/src/util.rs +@@ -8,7 +8,7 @@ macro_rules! py_is { + + macro_rules! ob_type { + ($obj:expr) => { +- unsafe { (*($obj as *mut pyo3::ffi::PyObject)).ob_type } ++ unsafe { pyo3::ffi::Py_TYPE($obj as *mut pyo3::ffi::PyObject) } + }; + } + +-- +2.43.0 + diff --git a/graalpython/lib-graalpython/patches/pandas-2.2.3.patch b/graalpython/lib-graalpython/patches/pandas-2.2.3.patch new file mode 100644 index 0000000000..1312dfbb7d --- /dev/null +++ b/graalpython/lib-graalpython/patches/pandas-2.2.3.patch @@ -0,0 +1,52 @@ +diff --git a/pandas/_libs/include/pandas/vendored/klib/khash_python.h b/pandas/_libs/include/pandas/vendored/klib/khash_python.h +index 5a933b4..f579fc6 100644 +--- a/pandas/_libs/include/pandas/vendored/klib/khash_python.h ++++ b/pandas/_libs/include/pandas/vendored/klib/khash_python.h +@@ -173,13 +173,15 @@ static inline int floatobject_cmp(PyFloatObject *a, PyFloatObject *b) { + // PyObject_RichCompareBool for complexobjects has a different behavior + // needs to be replaced + static inline int complexobject_cmp(PyComplexObject *a, PyComplexObject *b) { +- return (Py_IS_NAN(a->cval.real) && Py_IS_NAN(b->cval.real) && +- Py_IS_NAN(a->cval.imag) && Py_IS_NAN(b->cval.imag)) || +- (Py_IS_NAN(a->cval.real) && Py_IS_NAN(b->cval.real) && +- a->cval.imag == b->cval.imag) || +- (a->cval.real == b->cval.real && Py_IS_NAN(a->cval.imag) && +- Py_IS_NAN(b->cval.imag)) || +- (a->cval.real == b->cval.real && a->cval.imag == b->cval.imag); ++ Py_complex a_cval = PyComplex_AsCComplex((PyObject*)a); ++ Py_complex b_cval = PyComplex_AsCComplex((PyObject*)b); ++ return (Py_IS_NAN(a_cval.real) && Py_IS_NAN(b_cval.real) && ++ Py_IS_NAN(a_cval.imag) && Py_IS_NAN(b_cval.imag)) || ++ (Py_IS_NAN(a_cval.real) && Py_IS_NAN(b_cval.real) && ++ a_cval.imag == b_cval.imag) || ++ (a_cval.real == b_cval.real && Py_IS_NAN(a_cval.imag) && ++ Py_IS_NAN(b_cval.imag)) || ++ (a_cval.real == b_cval.real && a_cval.imag == b_cval.imag); + } + + static inline int pyobject_cmp(PyObject *a, PyObject *b); +@@ -250,8 +252,9 @@ static inline Py_hash_t floatobject_hash(PyFloatObject *key) { + + // replaces _Py_HashDouble with _Pandas_HashDouble + static inline Py_hash_t complexobject_hash(PyComplexObject *key) { +- Py_uhash_t realhash = (Py_uhash_t)_Pandas_HashDouble(key->cval.real); +- Py_uhash_t imaghash = (Py_uhash_t)_Pandas_HashDouble(key->cval.imag); ++ Py_complex cval = PyComplex_AsCComplex((PyObject*)key); ++ Py_uhash_t realhash = (Py_uhash_t)_Pandas_HashDouble(cval.real); ++ Py_uhash_t imaghash = (Py_uhash_t)_Pandas_HashDouble(cval.imag); + if (realhash == (Py_uhash_t)-1 || imaghash == (Py_uhash_t)-1) { + return -1; + } +diff --git a/pyproject.toml b/pyproject.toml +index db9f055..c191232 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -5,7 +5,7 @@ requires = [ + "meson-python==0.13.1", + "meson==1.2.1", + "wheel", +- "Cython~=3.0.5", # Note: sync with setup.py, environment.yml and asv.conf.json ++ "Cython==3.0.10", # Note: sync with setup.py, environment.yml and asv.conf.json + # Force numpy higher than 2.0, so that built wheels are compatible + # with both numpy 1 and 2 + "numpy>=2.0", diff --git a/graalpython/lib-graalpython/patches/protobuf.patch b/graalpython/lib-graalpython/patches/protobuf.patch new file mode 100644 index 0000000000..85b8bd50ac --- /dev/null +++ b/graalpython/lib-graalpython/patches/protobuf.patch @@ -0,0 +1,15 @@ +diff --git a/google/protobuf/internal/api_implementation.py b/google/protobuf/internal/api_implementation.py +index b40446b..48e684f 100644 +--- a/google/protobuf/internal/api_implementation.py ++++ b/google/protobuf/internal/api_implementation.py +@@ -70,8 +70,8 @@ if _implementation_type not in ('python', 'cpp', 'upb'): + 'supported. Please set to \'python\', \'cpp\' or ' + '\'upb\'.'.format(_implementation_type)) + +-if 'PyPy' in sys.version and _implementation_type == 'cpp': +- warnings.warn('PyPy does not work yet with cpp protocol buffers. ' ++if sys.implementation.name in ('pypy', 'graalpy') and _implementation_type == 'cpp': ++ warnings.warn('PyPy and GraalPy do not work yet with cpp protocol buffers. ' + 'Falling back to the python implementation.') + _implementation_type = 'python' + diff --git a/graalpython/lib-graalpython/patches/pyarrow-12.0.0.patch b/graalpython/lib-graalpython/patches/pyarrow-12.0.0.patch index 0051000a1c..b82828a56d 100644 --- a/graalpython/lib-graalpython/patches/pyarrow-12.0.0.patch +++ b/graalpython/lib-graalpython/patches/pyarrow-12.0.0.patch @@ -115,7 +115,7 @@ index 0000000..c9826ce + '-DARROW_WITH_BROTLI=ON', + ]) + subprocess.check_call([ -+ 'cmake', '--build', str(build_dir), '--parallel', ++ 'cmake', '--build', str(build_dir), + ]) + subprocess.check_call([ + 'cmake', '--install', str(build_dir), diff --git a/graalpython/lib-graalpython/patches/pyarrow-15.0.0.patch b/graalpython/lib-graalpython/patches/pyarrow-15.0.0.patch index 727ca72f9a..607b6dd982 100644 --- a/graalpython/lib-graalpython/patches/pyarrow-15.0.0.patch +++ b/graalpython/lib-graalpython/patches/pyarrow-15.0.0.patch @@ -115,7 +115,7 @@ index 0000000..955ac8d + '-DARROW_WITH_BROTLI=ON', + ]) + subprocess.check_call([ -+ 'cmake', '--build', str(build_dir), '--parallel', ++ 'cmake', '--build', str(build_dir), + ]) + subprocess.check_call([ + 'cmake', '--install', str(build_dir), diff --git a/graalpython/lib-graalpython/patches/pyarrow-19.0.0.patch b/graalpython/lib-graalpython/patches/pyarrow-19.0.0.patch index 70adda0ede..26a329f3ad 100644 --- a/graalpython/lib-graalpython/patches/pyarrow-19.0.0.patch +++ b/graalpython/lib-graalpython/patches/pyarrow-19.0.0.patch @@ -115,7 +115,7 @@ index 0000000..0929c5f + '-DARROW_WITH_BROTLI=ON', + ]) + subprocess.check_call([ -+ 'cmake', '--build', str(build_dir), '--parallel', ++ 'cmake', '--build', str(build_dir), + ]) + subprocess.check_call([ + 'cmake', '--install', str(build_dir), @@ -162,3 +162,27 @@ index ef2043f..cb08a86 100644 [project] name = "pyarrow" +diff --git a/MANIFEST.in b/MANIFEST.in +index ef2043f..cb08a86 100644 +--- a/MANIFEST.in ++++ b/MANIFEST.in +@@ -1,6 +1,4 @@ + include README.md +-include ../LICENSE.txt +-include ../NOTICE.txt + + global-include CMakeLists.txt + graft pyarrow +diff --git a/setup.cfg b/setup.cfg +index ef2043f..cb08a86 100644 +--- a/setup.cfg ++++ b/setup.cfg +@@ -1,7 +1,6 @@ + [metadata] + license_files = +- ../LICENSE.txt +- ../NOTICE.txt ++ README.md + + [build_sphinx] + source-dir = doc/ diff --git a/graalpython/lib-graalpython/patches/pyarrow-19.0.1.patch b/graalpython/lib-graalpython/patches/pyarrow-19.0.1.patch new file mode 100644 index 0000000000..3659ac4d27 --- /dev/null +++ b/graalpython/lib-graalpython/patches/pyarrow-19.0.1.patch @@ -0,0 +1,188 @@ +diff --git a/pyarrow/error.pxi b/pyarrow/error.pxi +index cbe2552..8d0d9d9 100644 +--- a/pyarrow/error.pxi ++++ b/pyarrow/error.pxi +@@ -248,7 +248,7 @@ cdef class SignalStopHandler: + if exc_value.signum: + # Re-emit the exact same signal. We restored the Python signal + # handler above, so it should receive it. +- if os.name == 'nt': ++ if os.name == 'nt' or sys.implementation.name == 'graalpy': + SendSignal(exc_value.signum) + else: + SendSignalToThread(exc_value.signum, +diff --git a/pyarrow/memory.pxi b/pyarrow/memory.pxi +index 1ddcb01..6805e42 100644 +--- a/pyarrow/memory.pxi ++++ b/pyarrow/memory.pxi +@@ -20,6 +20,10 @@ + # cython: embedsignature = True + + ++cdef extern from "Python.h": ++ void Py_INCREF(object) ++ ++ + cdef class MemoryPool(_Weakrefable): + """ + Base class for memory allocation. +@@ -35,6 +39,13 @@ cdef class MemoryPool(_Weakrefable): + + cdef void init(self, CMemoryPool* pool): + self.pool = pool ++ # GraalPy change: pyarrow doesn't maintain python references from ++ # buffers to pools, but they dereference the pointer to the pool in the ++ # destructor. They just assume buffers will get GC'ed before their ++ # pools. You can easily get a segfault even on CPython if you make ++ # a buffer outlive its pool. Since we can't guarantee destruction ++ # order, we just leak the pool. ++ Py_INCREF(self) + + def release_unused(self): + """ +diff --git a/pyarrow_build_backend.py b/pyarrow_build_backend.py +new file mode 100644 +index 0000000..0929c5f +--- /dev/null ++++ b/pyarrow_build_backend.py +@@ -0,0 +1,93 @@ ++import os ++import re ++import sys ++import tarfile ++import subprocess ++import tempfile ++import shutil ++import tarfile ++import urllib.request ++from pathlib import Path ++ ++VERSION = '19.0.1' ++ ++ ++def build_sdist(sdist_directory, config_settings=None): ++ nv = f'pyarrow-{VERSION}' ++ srcdir = Path(__file__).parent ++ archive_path = Path(sdist_directory) / f'{nv}.tar.gz' ++ ++ def tarfilter(info): ++ if re.match(r'\./(?:.git|venv|[^-/]+-venv|dist)', info.name): ++ return None ++ info.name = f'./{nv}/{info.name}' ++ return info ++ ++ with tarfile.open(archive_path, 'w:gz') as tar: ++ tar.add('.', filter=tarfilter) ++ return archive_path.name ++ ++ ++def build_wheel(wheel_directory, config_settings=None, metadata_directory=None): ++ wheel_directory = Path(wheel_directory).absolute() ++ with tempfile.TemporaryDirectory() as tmpdir: ++ tmpdir = Path(tmpdir).absolute() ++ tarname = f'apache-arrow-{VERSION}.tar.gz' ++ tarpath = tmpdir / tarname ++ urllib.request.urlretrieve(f"https://github.com/apache/arrow/archive/refs/tags/%7Btarname%7D", tarpath) ++ with tarfile.open(tarpath) as tar: ++ tar.extractall(tmpdir) ++ arrow_dir = tmpdir / f'arrow-apache-arrow-{VERSION}' ++ assert arrow_dir.is_dir() ++ arrow_dist = tmpdir / 'arrow-dist' ++ build_dir = tmpdir / 'arrow-build' ++ subprocess.check_call([ ++ 'cmake', '-S', str(arrow_dir / 'cpp'), '-B', str(build_dir), ++ '-DCMAKE_INSTALL_LIBDIR=lib', ++ f'-DCMAKE_INSTALL_PREFIX={arrow_dist}', ++ '-DCMAKE_BUILD_TYPE=Release', ++ '-DARROW_RPATH_ORIGIN=ON', ++ '-DARROW_BUILD_TESTS=OFF', ++ '-DARROW_BUILD_SHARED=ON', ++ '-DARROW_BUILD_STATIC=OFF', ++ # Features ++ '-DARROW_COMPUTE=ON', ++ '-DARROW_CSV=ON', ++ '-DARROW_JSON=ON', ++ '-DARROW_FILESYSTEM=ON', ++ '-DARROW_DATASET=ON', ++ '-DARROW_PARQUET=ON', ++ '-DPARQUET_REQUIRE_ENCRYPTION=ON', ++ '-DARROW_GANDIVA=ON', ++ '-DARROW_WITH_BZ2=ON', ++ '-DARROW_WITH_ZLIB=ON', ++ '-DARROW_WITH_ZSTD=ON', ++ '-DARROW_WITH_LZ4=ON', ++ '-DARROW_WITH_SNAPPY=ON', ++ '-DARROW_WITH_BROTLI=ON', ++ ]) ++ subprocess.check_call([ ++ 'cmake', '--build', str(build_dir), ++ ]) ++ subprocess.check_call([ ++ 'cmake', '--install', str(build_dir), ++ ]) ++ env = os.environ.copy() ++ env['ARROW_HOME'] = str(arrow_dist) ++ env['CMAKE_PREFIX_PATH'] = str(arrow_dist) ++ env['PYARROW_WITH_DATASET'] = '1' ++ env['PYARROW_WITH_PARQUET'] = '1' ++ env['PYARROW_WITH_PARQUET_ENCRYPTION'] = '1' ++ env['PYARROW_WITH_GANDIVA'] = '1' ++ env['PYARROW_BUNDLE_ARROW_CPP'] = '1' ++ env['PYARROW_BUNDLE_CYTHON_CPP'] = '1' ++ subprocess.run( ++ [sys.executable, 'setup.py', 'bdist_wheel'], ++ env=env, ++ check=True, ++ ) ++ wheels = list(Path('dist').glob('*.whl')) ++ assert len(wheels) == 1, f"Expected 1 wheel, found {len(wheels)}" ++ wheel = wheels[0] ++ shutil.copyfile(wheel, wheel_directory / wheel.name) ++ return str(wheel.name) +diff --git a/pyproject.toml b/pyproject.toml +index ef2043f..cb08a86 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -17,7 +17,7 @@ + + [build-system] + requires = [ +- "cython >= 0.29.31", ++ "cython >= 0.29.31, < 3", + # Starting with NumPy 1.25, NumPy is (by default) as far back compatible + # as oldest-support-numpy was (customizable with a NPY_TARGET_VERSION + # define). For older Python versions (where NumPy 1.25 is not yet available) +@@ -29,7 +29,8 @@ requires = [ + "setuptools_scm[toml]>=8", + "setuptools>=64", + ] +-build-backend = "setuptools.build_meta" ++build-backend = "pyarrow_build_backend" ++backend-path = ["."] + + [project] + name = "pyarrow" +diff --git a/MANIFEST.in b/MANIFEST.in +index ef2043f..cb08a86 100644 +--- a/MANIFEST.in ++++ b/MANIFEST.in +@@ -1,6 +1,4 @@ + include README.md +-include ../LICENSE.txt +-include ../NOTICE.txt + + global-include CMakeLists.txt + graft pyarrow +diff --git a/setup.cfg b/setup.cfg +index ef2043f..cb08a86 100644 +--- a/setup.cfg ++++ b/setup.cfg +@@ -1,7 +1,6 @@ + [metadata] + license_files = +- ../LICENSE.txt +- ../NOTICE.txt ++ README.md + + [build_sphinx] + source-dir = doc/ diff --git a/graalpython/lib-graalpython/patches/pygobject-3.52.3.patch b/graalpython/lib-graalpython/patches/pygobject-3.52.3.patch new file mode 100644 index 0000000000..1c637d559a --- /dev/null +++ b/graalpython/lib-graalpython/patches/pygobject-3.52.3.patch @@ -0,0 +1,282 @@ +diff --git a/gi/pygenum.c b/gi/pygenum.c +index d8ab0e25..f9881110 100644 +--- a/gi/pygenum.c ++++ b/gi/pygenum.c +@@ -90,13 +90,28 @@ add_value (PyObject *dict, const char *value_nick, int value) + } + + /* skip if the name already exists in the dictionary */ ++#if !defined(GRAALPY_VERSION_NUM) || GRAALPY_VERSION_NUM >= 0x190000a0 + if (PyMapping_HasKeyString (dict, upper)) { + g_free (upper); + return; + } + + v = PyLong_FromLong (value); + PyMapping_SetItemString (dict, upper, v); ++#else ++ PyObject *key = PyUnicode_FromString(upper); ++ PyObject *keyValue = PyObject_GetItem (dict, key); ++ if (keyValue != NULL) { ++ Py_DECREF(keyValue); ++ Py_DECREF(key); ++ g_free (upper); ++ return; ++ } ++ PyErr_Clear(); ++ v = PyLong_FromLong (value); ++ PyObject_SetItem (dict, key, v); ++ Py_DECREF(key); ++#endif + Py_DECREF (v); + g_free (upper); + } +@@ -179,13 +184,21 @@ pyg_enum_add_full (PyObject *module, + if (module) { + PyObject *module_name = PyModule_GetNameObject (module); + ++#if !defined(GRAALPY_VERSION_NUM) || GRAALPY_VERSION_NUM >= 0x190000a0 + PyMapping_SetItemString (values, "__module__", module_name); ++#else ++ PyDict_SetItemString (values, "__module__", module_name); ++#endif + Py_DECREF (module_name); + } + if (gtype != G_TYPE_NONE) { + PyObject *o = pyg_type_wrapper_new (gtype); + ++#if !defined(GRAALPY_VERSION_NUM) || GRAALPY_VERSION_NUM >= 0x190000a0 + PyMapping_SetItemString(values, "__gtype__", o); ++#else ++ PyDict_SetItemString(values, "__gtype__", o); ++#endif + Py_DECREF (o); + } + +diff --git a/gi/pygflags.c b/gi/pygflags.c +index f0047a13..7717f175 100644 +--- a/gi/pygflags.c ++++ b/gi/pygflags.c +@@ -89,6 +89,7 @@ add_value (PyObject *dict, const char *value_nick, unsigned int value) + } + + /* skip if the name already exists in the dictionary */ ++#if !defined(GRAALPY_VERSION_NUM) || GRAALPY_VERSION_NUM >= 0x190000a0 + if (PyMapping_HasKeyString (dict, upper)) { + g_free (upper); + return; +@@ -96,6 +97,20 @@ add_value (PyObject *dict, const char *value_nick, unsigned int value) + + v = PyLong_FromUnsignedLong (value); + PyMapping_SetItemString (dict, upper, v); ++#else ++ PyObject *key = PyUnicode_FromString(upper); ++ PyObject *keyValue = PyObject_GetItem (dict, key); ++ if (keyValue != NULL) { ++ Py_DECREF(keyValue); ++ Py_DECREF(key); ++ g_free (upper); ++ return; ++ } ++ PyErr_Clear(); ++ v = PyLong_FromUnsignedLong (value); ++ PyObject_SetItem (dict, key, v); ++ Py_DECREF(key); ++#endif + Py_DECREF (v); + g_free (upper); + } +@@ -178,13 +183,21 @@ pyg_flags_add_full (PyObject *module, + if (module) { + PyObject *module_name = PyModule_GetNameObject (module); + ++#if !defined(GRAALPY_VERSION_NUM) || GRAALPY_VERSION_NUM >= 0x190000a0 + PyMapping_SetItemString (values, "__module__", module_name); ++#else ++ PyDict_SetItemString (values, "__module__", module_name); ++#endif + Py_DECREF (module_name); + } + if (gtype != G_TYPE_NONE) { + PyObject *o = pyg_type_wrapper_new (gtype); + ++#if !defined(GRAALPY_VERSION_NUM) || GRAALPY_VERSION_NUM >= 0x190000a0 + PyMapping_SetItemString(values, "__gtype__", o); ++#else ++ PyDict_SetItemString(values, "__gtype__", o); ++#endif + Py_DECREF (o); + } + +diff --git a/gi/gimodule.c b/gi/gimodule.c +index ace6fa5b..57bfa63a 100644 +--- a/gi/gimodule.c ++++ b/gi/gimodule.c +@@ -2120,7 +2120,7 @@ _wrap_pyig_pyos_getsig (PyObject *self, PyObject *args) + if (!PyArg_ParseTuple (args, "i:pyos_getsig", &sig_num)) + return NULL; + +- return PyLong_FromVoidPtr ((void *)(PyOS_getsig (sig_num))); ++ return PyLong_FromVoidPtr ((void *)(SIG_IGN)); + } + + static PyObject * +diff --git a/gi/gimodule.c b/gi/gimodule.c +index 57bfa63a..8f32734d 100644 +--- a/gi/gimodule.c ++++ b/gi/gimodule.c +@@ -2402,7 +2402,7 @@ _gi_exec (PyObject *module) + PyObject *module_dict = PyModule_GetDict (module); + int ret; + +-#if PY_VERSION_HEX < 0x03090000 || defined(PYPY_VERSION) ++#if PY_VERSION_HEX < 0x03090000 || defined(PYPY_VERSION) || defined(GRAALPY_VERSION) + /* Deprecated since 3.9 */ + /* Except in PyPy it's still not a no-op: https://foss.heptapod.net/pypy/pypy/-/issues/3691 */ + +diff --git a/gi/pygi-async.c b/gi/pygi-async.c +index 248e1fb6..00d2d377 100644 +--- a/gi/pygi-async.c ++++ b/gi/pygi-async.c +@@ -32,7 +32,7 @@ + + static PyObject *asyncio_InvalidStateError; + static PyObject *asyncio_get_running_loop; +-#if defined(PYPY_VERSION) ++#if defined(PYPY_VERSION) || defined(GRAALPY_VERSION) + static PyObject *contextvars_copy_context; + #endif + static PyObject *cancellable_info; +@@ -155,7 +155,7 @@ async_add_done_callback (PyGIAsync *self, PyObject *args, PyObject *kwargs) + + Py_INCREF(callback.func); + if (callback.context == NULL) +-#ifndef PYPY_VERSION ++#if !defined(PYPY_VERSION) && !defined(GRAALPY_VERSION) + callback.context = PyContext_CopyCurrent (); + #else + callback.context = PyObject_CallObject (contextvars_copy_context, NULL); +@@ -411,7 +411,7 @@ finally: + static void + async_dealloc(PyGIAsync *self) + { +-#ifndef PYPY_VERSION ++#if !defined(PYPY_VERSION) && !defined(GRAALPY_VERSION) + /* The finalizer might resurrect the object */ + if (PyObject_CallFinalizerFromDealloc((PyObject *)self) < 0) + return; +@@ -587,11 +587,11 @@ static struct PyMemberDef async_members[] = { + */ + int pygi_async_register_types(PyObject *module) { + PyObject *asyncio = NULL; +-#ifdef PYPY_VERSION ++#if defined(PYPY_VERSION) || defined(GRAALPY_VERSION) + PyObject *contextvars = NULL; + #endif + +-#ifndef PYPY_VERSION ++#if !defined(PYPY_VERSION) && !defined(GRAALPY_VERSION) + PyGIAsync_Type.tp_finalize = (destructor)async_finalize; + #else + PyGIAsync_Type.tp_del = (destructor)async_finalize; +@@ -629,7 +629,7 @@ int pygi_async_register_types(PyObject *module) { + if (asyncio_get_running_loop == NULL) + goto fail; + +-#if defined(PYPY_VERSION) ++#if defined(PYPY_VERSION) || defined(GRAALPY_VERSION) + contextvars = PyImport_ImportModule("contextvars"); + if (contextvars == NULL) { + goto fail; +diff --git a/gi/pygi-resulttuple.c b/gi/pygi-resulttuple.c +index c1281d20..4a7a9beb 100644 +--- a/gi/pygi-resulttuple.c ++++ b/gi/pygi-resulttuple.c +@@ -28,7 +28,7 @@ static char tuple_indices_key[] = "__tuple_indices"; + + #define PYGI_USE_FREELIST + +-#ifdef PYPY_VERSION ++#if defined(PYPY_VERSION) || defined(GRAALPY_VERSION) + #undef PYGI_USE_FREELIST + #endif + +diff --git a/gi/pygobject-object.c b/gi/pygobject-object.c +index b7ade53b..edf98caa 100644 +--- a/gi/pygobject-object.c ++++ b/gi/pygobject-object.c +@@ -54,7 +54,7 @@ GQuark pygobject_has_updated_constructor_key; + GQuark pygobject_instance_data_key; + + /* PyPy doesn't support tp_dictoffset, so we have to work around it */ +-#ifndef PYPY_VERSION ++#if !defined(PYPY_VERSION) && !defined(GRAALPY_VERSION) + #define PYGI_OBJECT_USE_CUSTOM_DICT + #endif + +diff --git a/gi/pygi-resulttuple.c b/gi/pygi-resulttuple.c +index 4a7a9beb..55226da2 100644 +--- a/gi/pygi-resulttuple.c ++++ b/gi/pygi-resulttuple.c +@@ -257,6 +257,11 @@ pygi_resulttuple_new_type(PyObject *tuple_names) { + /* disallow subclassing as that would break the free list caching + * since we assume that all subclasses use PyTupleObject */ + new_type->tp_flags &= ~Py_TPFLAGS_BASETYPE; ++#ifdef GRAALPY_VERSION ++ /* GraalPy has a custom tp_alloc for tuples, but the managed ++ * type we have created here has PyType_GenericAlloc */ ++ new_type->tp_alloc = (&PyTuple_Type)->tp_alloc; ++#endif + } + + return new_type; +diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c +index 37f570c9..383c8524 100644 +--- a/gi/pygi-closure.c ++++ b/gi/pygi-closure.c +@@ -375,8 +375,21 @@ _pygi_closure_convert_arguments (PyGIInvokeState *state, + } + + user_data_len = PyTuple_Size (py_user_data); ++#if !defined(GRAALPY_VERSION_NUM) || GRAALPY_VERSION_NUM >= 0x190000a0 + _PyTuple_Resize (&state->py_in_args, + state->n_py_in_args + user_data_len - 1); ++#else ++ { ++ Py_ssize_t newSize = state->n_py_in_args + user_data_len - 1; ++ Py_ssize_t oldSize = Py_SIZE(state->py_in_args); ++ PyObject *newTuple = PyTuple_New(newSize); ++ for (int idx = 0; idx < newSize && idx < oldSize; ++idx) { ++ PyTuple_SetItem(newTuple, idx, PySequence_GetItem(state->py_in_args, idx)); ++ } ++ Py_DECREF(state->py_in_args); ++ state->py_in_args = newTuple; ++ } ++#endif + + for (j = 0; j < user_data_len; j++, n_in_args++) { + value = PyTuple_GetItem (py_user_data, j); +@@ -413,8 +426,20 @@ _pygi_closure_convert_arguments (PyGIInvokeState *state, + } + } + ++#if !defined(GRAALPY_VERSION_NUM) || GRAALPY_VERSION_NUM >= 0x190000a0 + if (_PyTuple_Resize (&state->py_in_args, n_in_args) == -1) + return FALSE; ++#else ++ { ++ PyObject *newTuple = PyTuple_New(n_in_args); ++ Py_ssize_t oldSize = Py_SIZE(state->py_in_args); ++ for (int idx = 0; idx < n_in_args && idx < oldSize; ++idx) { ++ PyTuple_SetItem(newTuple, idx, PySequence_GetItem(state->py_in_args, idx)); ++ } ++ Py_DECREF(state->py_in_args); ++ state->py_in_args = newTuple; ++ } ++#endif + + return TRUE; + } +-- +2.43.0 + diff --git a/graalpython/lib-graalpython/patches/pymupdf.patch b/graalpython/lib-graalpython/patches/pymupdf.patch new file mode 100644 index 0000000000..3adcf03f9b --- /dev/null +++ b/graalpython/lib-graalpython/patches/pymupdf.patch @@ -0,0 +1,129 @@ +diff --git a/graalpy-config b/graalpy-config +new file mode 100755 +index 00000000..1f69f726 +--- /dev/null ++++ b/graalpy-config +@@ -0,0 +1,78 @@ ++#!/bin/sh ++ ++# Adapted from CPython but deferring to GraalPy ++ ++exit_with_usage () ++{ ++ echo "Usage: $0 --prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--help|--abiflags|--configdir|--embed" ++ exit $1 ++} ++ ++if [ "$1" = "" ] ; then ++ exit_with_usage 1 ++fi ++ ++# Returns the actual prefix where this script was installed to. ++EXE=$(cd $(dirname "$0") && pwd -P) ++if which readlink >/dev/null 2>&1 ; then ++ if readlink -f "$RESULT" >/dev/null 2>&1; then ++ EXE=$(readlink -f "$RESULT") ++ fi ++fi ++EXE=$EXE/graalpy ++ ++if ! test -x "$EXE" ; then ++ EXE=graalpy ++fi ++ ++# Scan for --help or unknown argument. ++for ARG in $* ++do ++ case $ARG in ++ --help) ++ exit_with_usage 0 ++ ;; ++ --embed) ++ echo "graalpy-config does not print embedding flags" ++ exit 1 ++ ;; ++ --prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--abiflags|--configdir) ++ ;; ++ *) ++ exit_with_usage 1 ++ ;; ++ esac ++done ++ ++for ARG in "$@" ++do ++ case "$ARG" in ++ --prefix) ++ $EXE -c "print(__import__('sysconfig').get_config_var('prefix'))" ++ ;; ++ --exec-prefix) ++ $EXE -c "print(__import__('sysconfig').get_config_var('exec_prefix'))" ++ ;; ++ --includes) ++ $EXE -c "from sysconfig import get_path; print('-I'+get_path('include'), '-I'+get_path('platinclude'))" ++ ;; ++ --cflags) ++ $EXE -c "import sysconfig as s; print('-I' + s.get_path('include'), '-I' + s.get_path('platinclude'), s.get_config_var('CFLAGS').replace('NDEBUG', 'DEBUG'), s.get_config_var('OPT').replace('NDEBUG', 'DEBUG'))" ++ ;; ++ --libs) ++ $EXE -c "import sysconfig as s; print('-L' + s.get_config_var('LIBDIR'))" ++ ;; ++ --ldflags) ++ $EXE -c "import sysconfig as s; print('-L' + s.get_config_var('LIBDIR'))" ++ ;; ++ --extension-suffix) ++ $EXE -c "import sysconfig as s; print(s.get_config_var('EXT_SUFFIX'))" ++ ;; ++ --abiflags) ++ $EXE -c "import sysconfig as s; print(s.get_config_var('ABIFLAGS'))" ++ ;; ++ --configdir) ++ echo "" ++ ;; ++esac ++done +diff --git a/setup.py b/setup.py +index 5fba2c97..3fe63b07 100755 +--- a/setup.py ++++ b/setup.py +@@ -1452,0 +1452,40 @@ ++if sys.implementation.name == "graalpy": ++ import os ++ import re ++ import subprocess ++ import shutil ++ import sysconfig ++ from pathlib import Path ++ ++ def build_wheel(wheel_directory, config_settings=None, metadata_directory=None): ++ wheel_directory = Path(wheel_directory).absolute() ++ sdir = Path(__file__).absolute().parent ++ cpythonname = os.environ.get("CPYTHON_EXE", "python3.11") ++ cpython = shutil.which(cpythonname) or cpythonname ++ if not os.path.exists(cpython): ++ raise RuntimeError(f"{cpythonname} must be available on the PATH for cross-compilation") ++ env = os.environ.copy() ++ env["PIPCL_PYTHON_CONFIG"] = str(sdir / "graalpy-config") ++ env["PYMUPDF_SETUP_PY_LIMITED_API"] = "1" ++ subprocess.run( ++ [cpython, "setup.py", "bdist_wheel"], ++ env=env, ++ cwd=sdir, ++ check=True, ++ ) ++ wheels = list((sdir / 'dist').glob('*.whl')) ++ assert len(wheels) == 1, f"Expected 1 wheel, found {len(wheels)}" ++ wheel = wheels[0] ++ cpabi = "cp3" ++ cpabi += subprocess.check_output([cpython, "-c", "import sys;print(sys.implementation.version.minor)"], text=True).strip() ++ cpabi += "-abi3" ++ assert cpabi in wheel.name, f"Expected wheel to be for {cpabi}, got {wheel.name}" ++ graalpy_ext_suffix = sysconfig.get_config_var("EXT_SUFFIX") ++ m = re.match(r"\.graalpy(\d+[^\-]*)-(\d+)", sysconfig.get_config_var("EXT_SUFFIX")) ++ gpver = m[1] ++ cpver = m[2] ++ graalpy_wheel_tag = f"graalpy{cpver}-graalpy{gpver}_{cpver}_native" ++ name = wheel.name.replace(cpabi, graalpy_wheel_tag) ++ shutil.copyfile(wheel, wheel_directory / name) ++ print('Produced', wheel.name, 'compatible to', name) ++ return str(name) diff --git a/graalpython/lib-graalpython/patches/pythran-0.16.patch b/graalpython/lib-graalpython/patches/pythran-0.16.patch new file mode 100644 index 0000000000..3fda5ec7ab --- /dev/null +++ b/graalpython/lib-graalpython/patches/pythran-0.16.patch @@ -0,0 +1,70 @@ +diff --git a/pythran/pythonic/python/core.hpp b/pythran/pythonic/python/core.hpp +index 4cbe3e0..24340b0 100644 +--- a/pythran/pythonic/python/core.hpp ++++ b/pythran/pythonic/python/core.hpp +@@ -53,7 +53,14 @@ namespace python + { + + #ifndef PyString_AS_STRING +-#define PyString_AS_STRING (char *)_PyUnicode_COMPACT_DATA ++ static inline const char* PyString_AS_STRING(PyObject* obj) { ++ const char* str = PyUnicode_AsUTF8(obj); ++ if (!str) { ++ PyErr_Clear(); ++ str = ""; ++ } ++ return str; ++ } + #endif + + inline void PyObject_TypePrettyPrinter(std::ostream &oss, PyObject *obj) +diff --git a/pythran/pythonic/types/str.hpp b/pythran/pythonic/types/str.hpp +index e5dbe60..41d1658 100644 +--- a/pythran/pythonic/types/str.hpp ++++ b/pythran/pythonic/types/str.hpp +@@ -741,10 +741,17 @@ namespace std + #define PyString_FromStringAndSize PyUnicode_FromStringAndSize + + #ifndef PyString_Check +-#define PyString_Check(x) PyUnicode_Check(x) && PyUnicode_IS_COMPACT_ASCII(x) ++#define PyString_Check(x) PyUnicode_Check(x) + #endif + #ifndef PyString_AS_STRING +-#define PyString_AS_STRING (char *)_PyUnicode_COMPACT_DATA ++ static inline const char* PyString_AS_STRING(PyObject* obj) { ++ const char* str = PyUnicode_AsUTF8(obj); ++ if (!str) { ++ PyErr_Clear(); ++ str = ""; ++ } ++ return str; ++ } + #endif + #ifndef PyString_GET_SIZE + #define PyString_GET_SIZE PyUnicode_GET_LENGTH +diff --git a/pythran/tables.py b/pythran/tables.py +index d62abe1..4ba279d 100644 +--- a/pythran/tables.py ++++ b/pythran/tables.py +@@ -4617,7 +4617,10 @@ def save_arguments(module_name, elements): + # some function are actually forward function, detect those + # and accept to use our description instead. + if looks_like_a_forward_function(spec): +- assert signature.args.args, "{} require an explicit description".format(elem) ++ # GraalPy change: we have signatures for more builtins than ++ # CPython and this trips up on type constructors like `dict` or ++ # `BaseException`. ++ # assert signature.args.args, "{} require an explicit description".format(elem) + continue + + args = [ast.Name(arg, ast.Param(), None, None) +@@ -4630,7 +4633,8 @@ def save_arguments(module_name, elements): + defaults = list(spec.defaults or []) + args += [ast.Name(arg, ast.Param(), None, None) + for arg in spec.kwonlyargs] +- defaults += [spec.kwonlydefaults[kw] for kw in spec.kwonlyargs] ++ if spec.kwonlydefaults: ++ defaults += [spec.kwonlydefaults[kw] for kw in spec.kwonlyargs] + + # Check if we already have a pythran description for that object + if signature.args.args: diff --git a/graalpython/lib-graalpython/patches/rapidfuzz-3.10.patch b/graalpython/lib-graalpython/patches/rapidfuzz-3.10.patch new file mode 100644 index 0000000000..4cb200aee8 --- /dev/null +++ b/graalpython/lib-graalpython/patches/rapidfuzz-3.10.patch @@ -0,0 +1,28 @@ +diff --git a/src/rapidfuzz/CMakeLists.txt b/src/rapidfuzz/CMakeLists.txt +index c8cdfd6..8c99251 100644 +--- a/src/rapidfuzz/CMakeLists.txt ++++ b/src/rapidfuzz/CMakeLists.txt +@@ -1,9 +1,9 @@ + function(create_cython_target _name) +- if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/${_name}.cxx) +- set(${_name} +- ${CMAKE_CURRENT_LIST_DIR}/${_name}.cxx +- PARENT_SCOPE) +- else() ++ # if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/${_name}.cxx) ++ # set(${_name} ++ # ${CMAKE_CURRENT_LIST_DIR}/${_name}.cxx ++ # PARENT_SCOPE) ++ # else() + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_name}.cxx" + MAIN_DEPENDENCY "${CMAKE_CURRENT_LIST_DIR}/${_name}.pyx" +@@ -16,7 +16,7 @@ function(create_cython_target _name) + set(${_name} + ${CMAKE_CURRENT_BINARY_DIR}/${_name}.cxx + PARENT_SCOPE) +- endif() ++ # endif() + endfunction(create_cython_target) + + function(rf_add_library name) diff --git a/graalpython/lib-graalpython/patches/scikit-build-core.patch b/graalpython/lib-graalpython/patches/scikit-build-core.patch new file mode 100644 index 0000000000..809e3f9d0a --- /dev/null +++ b/graalpython/lib-graalpython/patches/scikit-build-core.patch @@ -0,0 +1,11 @@ +--- a/scikit_build_core/_vendor/pyproject_metadata/__init__.py ++++ b/scikit_build_core/_vendor/pyproject_metadata/__init__.py +@@ -308,7 +308,7 @@ + project = pyproject_table["project"] + project_dir = pathlib.Path(project_dir) + +- if not allow_extra_keys: ++ if False: + extra_keys = extras_project(data) + if extra_keys: + extra_keys_str = ", ".join(sorted(f"{k!r}" for k in extra_keys)) diff --git a/graalpython/lib-graalpython/patches/tokenizers-0.19-plus.patch b/graalpython/lib-graalpython/patches/tokenizers-0.19-plus.patch deleted file mode 100644 index c1b9923c82..0000000000 --- a/graalpython/lib-graalpython/patches/tokenizers-0.19-plus.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff --git a/bindings/python/src/lib.rs b/bindings/python/src/lib.rs -index 3f1e713..6dd3c72 100644 ---- a/bindings/python/src/lib.rs -+++ b/bindings/python/src/lib.rs -@@ -50,14 +50,16 @@ extern "C" fn child_after_fork() { - pub fn tokenizers(m: &Bound<'_, PyModule>) -> PyResult<()> { - let _ = env_logger::try_init_from_env("TOKENIZERS_LOG"); - -+ // GraalPy change: Disable the atfork warning. This triggers a ton of false positives when -+ // jline calls stty and we don't support fork anyway - // Register the fork callback -- #[cfg(target_family = "unix")] -- unsafe { -- if !REGISTERED_FORK_CALLBACK { -- libc::pthread_atfork(None, None, Some(child_after_fork)); -- REGISTERED_FORK_CALLBACK = true; -- } -- } -+ // #[cfg(target_family = "unix")] -+ // unsafe { -+ // if !REGISTERED_FORK_CALLBACK { -+ // libc::pthread_atfork(None, None, Some(child_after_fork)); -+ // REGISTERED_FORK_CALLBACK = true; -+ // } -+ // } - - m.add_class::()?; - m.add_class::()?; diff --git a/graalpython/lib-graalpython/patches/torch-2.4.1.patch b/graalpython/lib-graalpython/patches/torch-2.4.1.patch index 5f7724d365..3dc4d354e3 100644 --- a/graalpython/lib-graalpython/patches/torch-2.4.1.patch +++ b/graalpython/lib-graalpython/patches/torch-2.4.1.patch @@ -178,6 +178,19 @@ index f5fdbf155..d76176cb6 100644 class TestWrapperSubclassAliasing(TestCase): +diff --git a/third_party/fbgemm/CMakeLists.txt b/third_party/fbgemm/CMakeLists.txt +index 134523e7d..a00538e3c 100644 +--- a/third_party/fbgemm/CMakeLists.txt ++++ b/third_party/fbgemm/CMakeLists.txt +@@ -10,6 +10,8 @@ + + cmake_minimum_required(VERSION 3.16 FATAL_ERROR) + ++add_compile_options(-Wno-error=maybe-uninitialized -Wno-error=uninitialized -Wno-error=restrict) ++ + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") + + # Define function to extract filelists from defs.bzl file diff --git a/third_party/pybind11/include/pybind11/detail/common.h b/third_party/pybind11/include/pybind11/detail/common.h index 454e6061b..7feafc7d7 100644 --- a/third_party/pybind11/include/pybind11/detail/common.h @@ -614,6 +627,24 @@ index cbe9ab37a..18740a0d8 100644 return module; } +diff --git a/torch/csrc/dynamo/extra_state.cpp b/torch/csrc/dynamo/extra_state.cpp +index 7c9b4be00..b8edbcfda 100644 +--- a/torch/csrc/dynamo/extra_state.cpp ++++ b/torch/csrc/dynamo/extra_state.cpp +@@ -65,11 +65,13 @@ void destroy_extra_state(void* obj) { + } + + void set_extra_state(PyCodeObject* code, ExtraState* extra_state) { ++#if 0 // GraalPy change + ExtraState* old_extra_state = get_extra_state(code); + CHECK( + old_extra_state == nullptr || old_extra_state == SKIP_CODE || + old_extra_state != extra_state); + _PyCode_SetExtra((PyObject*)code, extra_index, extra_state); ++#endif // GraalPy change + } + + ExtraState* init_and_set_extra_state(PyCodeObject* code) { diff --git a/torch/csrc/jit/python/python_tracer.cpp b/torch/csrc/jit/python/python_tracer.cpp index 92e6e2d3a..4d2ec0bfe 100644 --- a/torch/csrc/jit/python/python_tracer.cpp diff --git a/graalpython/lib-graalpython/patches/torch-2.7.0.patch b/graalpython/lib-graalpython/patches/torch-2.7.0.patch new file mode 100644 index 0000000000..54adc4d9df --- /dev/null +++ b/graalpython/lib-graalpython/patches/torch-2.7.0.patch @@ -0,0 +1,774 @@ +diff --git a/functorch/csrc/dim/dim.cpp b/functorch/csrc/dim/dim.cpp +index 23179ad0e..ad9dbdbf7 100644 +--- a/functorch/csrc/dim/dim.cpp ++++ b/functorch/csrc/dim/dim.cpp +@@ -22,7 +22,9 @@ PyObject* Dim_init() { + + #include "minpybind.h" + #include ++#if 0 // GraalPy change + #include ++#endif // GraalPy change + #include + #include + #include +@@ -40,7 +42,9 @@ PyObject* Dim_init() { + #if IS_PYTHON_3_11_PLUS + + #define Py_BUILD_CORE ++#if 0 // GraalPy change + #include "internal/pycore_opcode.h" ++#endif // GraalPy change + #undef Py_BUILD_CORE + #endif + +@@ -1458,6 +1462,7 @@ PyTypeObject Tensor::Type = { + + // dim() -------------------- + ++#if 0 // GraalPy change + static bool relevant_op(_Py_CODEUNIT c) { + switch(c) { + case STORE_NAME: +@@ -1469,6 +1474,7 @@ static bool relevant_op(_Py_CODEUNIT c) { + return false; + } + } ++#endif // GraalPy change + + static mpy::object create_dim(mpy::object name, mpy::handle size) { + auto d = Dim::create(std::move(name)); +@@ -1502,6 +1508,7 @@ static mpy::object create_dimlist(mpy::object name, mpy::handle size) { + #endif + + namespace{ ++#if 0 // GraalPy change + struct PyInstDecoder { + PyInstDecoder(PyCodeObject* code_object, int lasti) + : code_object_(code_object), code_(_PyCode_CODE(code_object)), offset_(lasti / sizeof(_Py_CODEUNIT)) {} +@@ -1547,6 +1554,7 @@ private: + _Py_CODEUNIT* code_; + int offset_; + }; ++#endif // GraalPy change + + template + static PyObject* _dims(PyObject *self, +@@ -1572,6 +1580,7 @@ static PyObject* _dims(PyObject *self, + } + } + ++#if 0 // GraalPy change + PyThreadState* state = PyThreadState_GET(); + auto f = mpy::obj::steal(PyThreadState_GetFrame(state)); + auto c = mpy::obj::steal(PyFrame_GetCode(f.ptr())); +@@ -1592,10 +1601,12 @@ static PyObject* _dims(PyObject *self, + found_ndims = decoder.oparg(); + decoder.next(); + } ++#endif // GraalPy change + + if (specified_ndims == -1) { + if (found_ndims == 0) { +- mpy::raise_error(PyExc_SyntaxError, "dims() must be assigned to a sequence of variable names or have argument n specified"); ++ // GraalPy change ++ mpy::raise_error(PyExc_SyntaxError, "dims() without arguments doesn't work on GraalPy, use the explicit dims(number) form"); + } + specified_ndims = found_ndims; + } +@@ -1605,14 +1616,18 @@ static PyObject* _dims(PyObject *self, + + auto genobject = [&](int i) -> mpy::object { + mpy::object name; ++#if 0 // GraalPy change + if (i < found_ndims) { + name = decoder.name(); + } ++#endif // GraalPy change + if (!name.ptr()) { + name = mpy::unicode_from_format("d%d", i); + found_ndims = 0; // once we fail at finding a name, we can find any more + } else { ++#if 0 // GraalPy change + decoder.next(); ++#endif // GraalPy change + } + return create_object(std::move(name), sizes != -1 ? mpy::sequence_view(py_sizes)[i] : mpy::handle(Py_None)); + }; +@@ -2059,12 +2074,12 @@ struct IndexingInfo { + IndexingInfo getsetitem_flat(Arena& A, TensorInfo self_info, Slice input, Slice keys, Slice values, bool has_dimpacks_or_none); + namespace{ + Slice as_slice(mpy::tuple_view tv) { +- PyObject** begin = &PyTuple_GET_ITEM(tv.ptr(),0); ++ PyObject** begin = PySequence_Fast_ITEMS(tv.ptr()); + return Slice((mpy::handle*)begin, (mpy::handle*) (begin + tv.size())); + } + + Slice as_slice(mpy::list_view tv) { +- PyObject** begin = &PyList_GET_ITEM(tv.ptr(),0); ++ PyObject** begin = PySequence_Fast_ITEMS(tv.ptr()); + return Slice((mpy::handle*)begin, (mpy::handle*) (begin + tv.size())); + } + +diff --git a/pyproject.toml b/pyproject.toml +index e84d980ff..649a53a0a 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -4,9 +4,11 @@ requires = [ + "wheel", + "astunparse", + "numpy", +- "ninja", ++ # GraalPy change: require ninja on the system, the wheel wrapper goes through python, making the build very slow ++ # "ninja", + "pyyaml", +- "cmake", ++ # GraalPy change: same as ninja ++ # "cmake", + "typing-extensions>=4.10.0", + "requests", + ] +diff --git a/test/test_overrides.py b/test/test_overrides.py +index cc7c904a1..1249f9cce 100644 +--- a/test/test_overrides.py ++++ b/test/test_overrides.py +@@ -1561,12 +1561,9 @@ class TestTorchFunctionMode(TestCase): + pass + + x = A(torch.randn(5)) +- with torch._C.DisableTorchFunctionSubclass(): +- g = torch._C._EnableTorchFunction() +- try: ++ with torch._C.DisableTorchFunctionSubclass(), \ ++ torch._C._EnableTorchFunction(): + self.assertIsInstance(torch.sum(x), A) +- finally: +- del g + + def test_disable_enable_torch_function_ctx(self): + class A(torch.Tensor): +diff --git a/test/test_python_dispatch.py b/test/test_python_dispatch.py +index 2e6bbd406..0c77b21f7 100644 +--- a/test/test_python_dispatch.py ++++ b/test/test_python_dispatch.py +@@ -2470,16 +2470,16 @@ def forward(self, x_1): + class TestPythonDispatcher(TestCase): + def test_basic(self): + x = torch.randn(2, requires_grad=True) +- r = torch._C._EnablePythonDispatcher() +- torch.add(x, x) ++ with torch._C._EnablePythonDispatcher(): ++ torch.add(x, x) + + def test_lstsq(self): + a = torch.randn(4, 3) + b = torch.rand(4, 3) + expected_shape = torch.linalg.lstsq(a, b).solution.shape +- r = torch._C._EnablePythonDispatcher() +- python_disp_shape = torch.linalg.lstsq(a, b).solution.shape +- self.assertEqual(expected_shape, python_disp_shape) ++ with torch._C._EnablePythonDispatcher(): ++ python_disp_shape = torch.linalg.lstsq(a, b).solution.shape ++ self.assertEqual(expected_shape, python_disp_shape) + + + class TestWrapperSubclassAliasing(TestCase): +diff --git a/third_party/fbgemm/CMakeLists.txt b/third_party/fbgemm/CMakeLists.txt +index 134523e7d..a00538e3c 100644 +--- a/third_party/fbgemm/CMakeLists.txt ++++ b/third_party/fbgemm/CMakeLists.txt +@@ -10,6 +10,8 @@ + + cmake_minimum_required(VERSION 3.16 FATAL_ERROR) + ++add_compile_options(-Wno-error=maybe-uninitialized -Wno-error=uninitialized -Wno-error=restrict) ++ + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") + + # Define function to extract filelists from defs.bzl file +diff --git a/third_party/pybind11/include/pybind11/detail/common.h b/third_party/pybind11/include/pybind11/detail/common.h +index c51d1d60b..3976dd32b 100644 +--- a/third_party/pybind11/include/pybind11/detail/common.h ++++ b/third_party/pybind11/include/pybind11/detail/common.h +@@ -299,7 +299,7 @@ PYBIND11_WARNING_DISABLE_MSVC(4505) + # define PYBIND11_INTERNAL_NUMPY_1_ONLY_DETECTED + #endif + +-#if defined(PYPY_VERSION) && !defined(PYBIND11_SIMPLE_GIL_MANAGEMENT) ++#if (defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)) && !defined(PYBIND11_SIMPLE_GIL_MANAGEMENT) + # define PYBIND11_SIMPLE_GIL_MANAGEMENT + #endif + +diff --git a/third_party/pybind11/include/pybind11/detail/internals.h b/third_party/pybind11/include/pybind11/detail/internals.h +index 232bc32d8..acde741f2 100644 +--- a/third_party/pybind11/include/pybind11/detail/internals.h ++++ b/third_party/pybind11/include/pybind11/detail/internals.h +@@ -449,7 +449,7 @@ inline void translate_local_exception(std::exception_ptr p) { + + inline object get_python_state_dict() { + object state_dict; +-#if PYBIND11_INTERNALS_VERSION <= 4 || PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION) ++#if PYBIND11_INTERNALS_VERSION <= 4 || PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION) || defined(GRAALVM_PYTHON) + state_dict = reinterpret_borrow(PyEval_GetBuiltins()); + #else + # if PY_VERSION_HEX < 0x03090000 +diff --git a/third_party/pybind11/include/pybind11/detail/type_caster_base.h b/third_party/pybind11/include/pybind11/detail/type_caster_base.h +index e40e44ba6..e7b94aff2 100644 +--- a/third_party/pybind11/include/pybind11/detail/type_caster_base.h ++++ b/third_party/pybind11/include/pybind11/detail/type_caster_base.h +@@ -459,7 +459,7 @@ PYBIND11_NOINLINE handle get_object_handle(const void *ptr, const detail::type_i + } + + inline PyThreadState *get_thread_state_unchecked() { +-#if defined(PYPY_VERSION) ++#if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON) + return PyThreadState_GET(); + #elif PY_VERSION_HEX < 0x030D0000 + return _PyThreadState_UncheckedGet(); +diff --git a/third_party/pybind11/include/pybind11/eval.h b/third_party/pybind11/include/pybind11/eval.h +index bd5f981f5..ee271672d 100644 +--- a/third_party/pybind11/include/pybind11/eval.h ++++ b/third_party/pybind11/include/pybind11/eval.h +@@ -94,18 +94,18 @@ void exec(const char (&s)[N], object global = globals(), object local = object() + eval(s, std::move(global), std::move(local)); + } + +-#if defined(PYPY_VERSION) ++#if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON) + template + object eval_file(str, object, object) { +- pybind11_fail("eval_file not supported in PyPy3. Use eval"); ++ pybind11_fail("eval_file not supported in PyPy3 or GraalPy. Use eval"); + } + template + object eval_file(str, object) { +- pybind11_fail("eval_file not supported in PyPy3. Use eval"); ++ pybind11_fail("eval_file not supported in PyPy3 or GraalPy. Use eval"); + } + template + object eval_file(str) { +- pybind11_fail("eval_file not supported in PyPy3. Use eval"); ++ pybind11_fail("eval_file not supported in PyPy3 or GraalPy. Use eval"); + } + #else + template +diff --git a/third_party/pybind11/include/pybind11/pybind11.h b/third_party/pybind11/include/pybind11/pybind11.h +index 949bc9bb4..6e17baa03 100644 +--- a/third_party/pybind11/include/pybind11/pybind11.h ++++ b/third_party/pybind11/include/pybind11/pybind11.h +@@ -573,8 +573,7 @@ protected: + // chain. + chain_start = rec; + rec->next = chain; +- auto rec_capsule +- = reinterpret_borrow(((PyCFunctionObject *) m_ptr)->m_self); ++ auto rec_capsule = reinterpret_borrow(PyCFunction_GET_SELF(m_ptr)); + rec_capsule.set_pointer(unique_rec.release()); + guarded_strdup.release(); + } else { +@@ -636,9 +635,15 @@ protected: + + /* Install docstring */ + auto *func = (PyCFunctionObject *) m_ptr; ++#if !defined(GRAALVM_PYTHON) + //std::free(const_cast(GraalPyCFunction_GetDoc((PyObject*)(func)))); + // Install docstring if it's non-empty (when at least one option is enabled) + GraalPyCFunction_SetDoc((PyObject*)(func), signatures.empty() ? nullptr : PYBIND11_COMPAT_STRDUP(signatures.c_str())); ++#else ++ std::free(const_cast(GraalPyCFunction_GetDoc(m_ptr))); ++ GraalPyCFunction_SetDoc( ++ m_ptr, signatures.empty() ? nullptr : PYBIND11_COMPAT_STRDUP(signatures.c_str())); ++#endif + + if (rec->is_method) { + m_ptr = PYBIND11_INSTANCE_METHOD_NEW(m_ptr, rec->scope.ptr()); +@@ -2766,8 +2771,8 @@ get_type_override(const void *this_ptr, const type_info *this_type, const char * + } + + /* Don't call dispatch code if invoked from overridden function. +- Unfortunately this doesn't work on PyPy. */ +-#if !defined(PYPY_VERSION) ++ Unfortunately this doesn't work on PyPy and GraalPy. */ ++#if !defined(PYPY_VERSION) && !defined(GRAALVM_PYTHON) + # if PY_VERSION_HEX >= 0x03090000 + PyFrameObject *frame = PyThreadState_GetFrame(PyThreadState_Get()); + if (frame != nullptr) { +diff --git a/third_party/pybind11/include/pybind11/pytypes.h b/third_party/pybind11/include/pybind11/pytypes.h +index 8052f2ed0..7aafab6dc 100644 +--- a/third_party/pybind11/include/pybind11/pytypes.h ++++ b/third_party/pybind11/include/pybind11/pytypes.h +@@ -643,7 +643,7 @@ struct error_fetch_and_normalize { + + bool have_trace = false; + if (m_trace) { +-#if !defined(PYPY_VERSION) ++#if !defined(PYPY_VERSION) && !defined(GRAALVM_PYTHON) + auto *tb = reinterpret_cast(m_trace.ptr()); + + // Get the deepest trace possible. +diff --git a/tools/build_pytorch_libs.py b/tools/build_pytorch_libs.py +index 5dd5a2219..357bf15d8 100644 +--- a/tools/build_pytorch_libs.py ++++ b/tools/build_pytorch_libs.py +@@ -86,6 +86,7 @@ def _create_build_env() -> dict[str, str]: + + + def read_nccl_pin() -> str: ++ return 'v2.26.5-1' + nccl_file = "nccl-cu12.txt" + if os.getenv("DESIRED_CUDA", "").startswith("11") or os.getenv( + "CUDA_VERSION", "" +@@ -120,7 +121,7 @@ def build_pytorch( + ) -> None: + my_env = _create_build_env() + checkout_nccl() +- build_test = not check_negative_env_flag("BUILD_TEST") ++ build_test = not check_negative_env_flag("BUILD_TEST", "OFF") + cmake.generate( + version, cmake_python_library, build_python, build_test, my_env, rerun_cmake + ) +diff --git a/tools/generate_torch_version.py b/tools/generate_torch_version.py +index a33ea171e..400ae922f 100644 +--- a/tools/generate_torch_version.py ++++ b/tools/generate_torch_version.py +@@ -50,6 +50,8 @@ def get_tag(pytorch_root: str | Path) -> str: + def get_torch_version(sha: str | None = None) -> str: + pytorch_root = Path(__file__).absolute().parent.parent + version = open(pytorch_root / "version.txt").read().strip() ++ # GraalPy change ++ return re.sub(r'a.*', '', version) + + if os.getenv("PYTORCH_BUILD_VERSION"): + assert os.getenv("PYTORCH_BUILD_NUMBER") is not None +diff --git a/torch/_dynamo/decorators.py b/torch/_dynamo/decorators.py +index b9009f729..52e851d7e 100644 +--- a/torch/_dynamo/decorators.py ++++ b/torch/_dynamo/decorators.py +@@ -94,7 +94,8 @@ def skip(fn=None): + return skip + fn = innermost_fn(fn) + assert callable(fn) +- skip_code(fn.__code__) ++ # GraalPy change ++ # skip_code(fn.__code__) + fn._torchdynamo_disable = True + return fn + +@@ -396,15 +397,16 @@ def substitute_in_graph( + + wildcard_sig = inspect.signature(lambda *args, **kwargs: None) + +- if ( +- sig_ident(original_sig) != sig_ident(traceable_sig) +- and sig_ident(original_sig) != sig_ident(wildcard_sig) +- and sig_ident(traceable_sig) != sig_ident(wildcard_sig) +- ): +- raise TypeError( +- f"Signature mismatch between {original_fn} and {traceable_fn}: " +- f"{original_sig} != {traceable_sig}" +- ) ++ # GraalPy change ++ # if ( ++ # sig_ident(original_sig) != sig_ident(traceable_sig) ++ # and sig_ident(original_sig) != sig_ident(wildcard_sig) ++ # and sig_ident(traceable_sig) != sig_ident(wildcard_sig) ++ # ): ++ # raise TypeError( ++ # f"Signature mismatch between {original_fn} and {traceable_fn}: " ++ # f"{original_sig} != {traceable_sig}" ++ # ) + + from torch._dynamo.guards import GuardBuilder + from torch._dynamo.trace_rules import ( +diff --git a/torch/_tensor_str.py b/torch/_tensor_str.py +index b13daaeba..0124d81b2 100644 +--- a/torch/_tensor_str.py ++++ b/torch/_tensor_str.py +@@ -705,6 +705,6 @@ def _functorch_wrapper_str_intern(tensor, *, tensor_contents=None): + + + def _str(self, *, tensor_contents=None): +- with torch.no_grad(), torch.utils._python_dispatch._disable_current_modes(): +- guard = torch._C._DisableFuncTorch() # noqa: F841 ++ with torch.no_grad(), torch.utils._python_dispatch._disable_current_modes(), \ ++ torch._C._DisableFuncTorch(): + return _str_intern(self, tensor_contents=tensor_contents) +diff --git a/torch/csrc/Generator.cpp b/torch/csrc/Generator.cpp +index ce2b4789e..74da13115 100644 +--- a/torch/csrc/Generator.cpp ++++ b/torch/csrc/Generator.cpp +@@ -266,7 +266,7 @@ static PyObject* THPGenerator_reduce(PyObject* _self, PyObject* noargs) { + static PyObject* THPGenerator_pickleSetState(PyObject* _self, PyObject* state) { + HANDLE_TH_ERRORS + THPGenerator_manualSeed(_self, PyTuple_GET_ITEM(state, 0)); +- auto& offset = PyTuple_GET_ITEM(state, 1); ++ PyObject* offset = PyTuple_GET_ITEM(state, 1); + if (offset != Py_None) { + THPGenerator_setOffset(_self, offset); + } +diff --git a/torch/csrc/Module.cpp b/torch/csrc/Module.cpp +index 1ac30fecf..53c5a8c32 100644 +--- a/torch/csrc/Module.cpp ++++ b/torch/csrc/Module.cpp +@@ -436,46 +436,16 @@ static PyObject* THPModule_addDocStr(PyObject* _unused, PyObject* args) { + doc_str = all_docs.back().c_str(); + } + +- if (Py_TYPE(obj) == &PyCFunction_Type) { +- PyCFunctionObject* f = (PyCFunctionObject*)obj; +- if (GraalPyCFunction_GetDoc((PyObject*)(f))) { +- return PyErr_Format( +- PyExc_RuntimeError, +- "function '%s' already has a docstring", +- _PyCFunction_GetMethodDef((PyObject*)(f))->ml_name); +- } +- GraalPyCFunction_SetDoc((PyObject*)(f), doc_str); +- } else if (strcmp(Py_TYPE(obj)->tp_name, "method_descriptor") == 0) { +- PyMethodDescrObject* m = (PyMethodDescrObject*)obj; +- if (m->d_method->ml_doc) { +- return PyErr_Format( +- PyExc_RuntimeError, +- "method '%s' already has a docstring", +- m->d_method->ml_name); +- } +- m->d_method->ml_doc = doc_str; +- } else if (strcmp(Py_TYPE(obj)->tp_name, "getset_descriptor") == 0) { +- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast) +- PyGetSetDescrObject* m = (PyGetSetDescrObject*)obj; +- if (m->d_getset->doc) { +- return PyErr_Format( +- PyExc_RuntimeError, +- "attribute '%s' already has a docstring", +- m->d_getset->name); +- } +- m->d_getset->doc = doc_str; +- } else if (Py_TYPE(obj) == &PyType_Type) { +- PyTypeObject* t = (PyTypeObject*)obj; +- if (t->tp_doc) { +- return PyErr_Format( +- PyExc_RuntimeError, "Type '%s' already has a docstring", t->tp_name); +- } +- t->tp_doc = doc_str; +- } else { ++ // GraalPy change ++ if (PyObject_GetDoc(obj)) { + return PyErr_Format( +- PyExc_TypeError, +- "don't know how to add docstring to type '%s'", +- Py_TYPE(obj)->tp_name); ++ PyExc_RuntimeError, ++ "object '%100R' already has a docstring", ++ obj); ++ } ++ // GraalPy change ++ if (PyObject_SetDoc(obj, doc_str) < 0) { ++ return NULL; + } + + Py_INCREF(obj); +diff --git a/torch/csrc/autograd/python_variable_indexing.cpp b/torch/csrc/autograd/python_variable_indexing.cpp +index ae1780e66..018c0e03f 100644 +--- a/torch/csrc/autograd/python_variable_indexing.cpp ++++ b/torch/csrc/autograd/python_variable_indexing.cpp +@@ -140,25 +140,28 @@ inline Variable valueToTensor( + + static void recordSliceTrace(PyObject* obj) { + PySliceObject* sliceobj = (PySliceObject*)obj; +- if (THPVariable_Check(sliceobj->start)) { ++ PyObject* slicestart = PySlice_Start(sliceobj); ++ if (THPVariable_Check(slicestart)) { + torch::jit::tracer::ArgumentStash::stashValue( + std::string("start"), + 1, +- THPVariable_Unpack(sliceobj->start), ++ THPVariable_Unpack(slicestart), + torch::jit::IntType::get()); + } +- if (THPVariable_Check(sliceobj->stop)) { ++ PyObject* slicestop = PySlice_Stop(sliceobj); ++ if (THPVariable_Check(slicestop)) { + torch::jit::tracer::ArgumentStash::stashValue( + std::string("end"), + 1, +- THPVariable_Unpack(sliceobj->stop), ++ THPVariable_Unpack(slicestop), + torch::jit::IntType::get()); + } +- if (THPVariable_Check(sliceobj->step)) { ++ PyObject* slicestep = PySlice_Step(sliceobj); ++ if (THPVariable_Check(slicestep)) { + torch::jit::tracer::ArgumentStash::stashValue( + std::string("step"), + 1, +- THPVariable_Unpack(sliceobj->step), ++ THPVariable_Unpack(slicestep), + torch::jit::IntType::get()); + } + } +diff --git a/torch/csrc/autograd/python_variable_indexing.h b/torch/csrc/autograd/python_variable_indexing.h +index 7efab1dcf..67b3cf44e 100644 +--- a/torch/csrc/autograd/python_variable_indexing.h ++++ b/torch/csrc/autograd/python_variable_indexing.h +@@ -37,14 +37,15 @@ inline UnpackedSlice __PySlice_Unpack(PyObject* _r) { + return val; + }; + +- if (r->step == Py_None) { ++ PyObject* stepObj = PySlice_Step(r); ++ if (stepObj == Py_None) { + step_sym = c10::SymInt(1); + } else { +- if (torch::is_symint(r->step)) { +- step_sym = py::handle(r->step).cast(); ++ if (torch::is_symint(stepObj)) { ++ step_sym = py::handle(stepObj).cast(); + } else { + Py_ssize_t step = 0; +- if (!_PyEval_SliceIndex(r->step, &step)) { ++ if (!_PyEval_SliceIndex(stepObj, &step)) { + throw python_error(); + } + if (step == 0) { +@@ -56,27 +57,29 @@ inline UnpackedSlice __PySlice_Unpack(PyObject* _r) { + } + } + +- if (torch::is_symint(r->start)) { +- start_sym = py::handle(r->start).cast(); +- } else if (r->start == Py_None) { ++ PyObject* startObj = PySlice_Start(r); ++ if (torch::is_symint(startObj)) { ++ start_sym = py::handle(startObj).cast(); ++ } else if (startObj == Py_None) { + start_sym = c10::SymInt(step_sym < 0 ? PY_SSIZE_T_MAX : 0); + } else { + Py_ssize_t start = 0; +- if (!_PyEval_SliceIndex(r->start, &start)) { ++ if (!_PyEval_SliceIndex(startObj, &start)) { + throw python_error(); + } + start = clip_val(start); + start_sym = c10::SymInt(start); + } + +- if (torch::is_symint(r->stop)) { +- stop_sym = py::handle(r->stop).cast(); +- } else if (r->stop == Py_None) { ++ PyObject* stopObj = PySlice_Stop(r); ++ if (torch::is_symint(stopObj)) { ++ stop_sym = py::handle(stopObj).cast(); ++ } else if (stopObj == Py_None) { + stop_sym = c10::SymInt( + step_sym < 0 ? c10::SymInt::min_representable_int() : PY_SSIZE_T_MAX); + } else { + Py_ssize_t stop = 0; +- if (!_PyEval_SliceIndex(r->stop, &stop)) { ++ if (!_PyEval_SliceIndex(stopObj, &stop)) { + throw python_error(); + } + stop = clip_val(stop); +diff --git a/torch/csrc/dynamo/cpython_defs.c b/torch/csrc/dynamo/cpython_defs.c +index b68ef894a..0837d95be 100644 +--- a/torch/csrc/dynamo/cpython_defs.c ++++ b/torch/csrc/dynamo/cpython_defs.c +@@ -2,6 +2,7 @@ + #include + #include + ++#if 0 // GraalPy change + #if IS_PYTHON_3_11_PLUS + + #define Py_BUILD_CORE +@@ -349,7 +350,8 @@ THP_PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame * frame) + + #endif + +-#if IS_PYTHON_3_11_PLUS ++// GraalPy change ++// #if IS_PYTHON_3_11_PLUS + + const uint8_t* THP_PyOpcode_Caches = _PyOpcode_Caches; + const int THP_PyOpcode_Caches_size = sizeof(_PyOpcode_Caches) / sizeof(uint8_t); +diff --git a/torch/csrc/dynamo/eval_frame.c b/torch/csrc/dynamo/eval_frame.c +index 048bb4e2c..51a302293 100644 +--- a/torch/csrc/dynamo/eval_frame.c ++++ b/torch/csrc/dynamo/eval_frame.c +@@ -1,5 +1,7 @@ + #define PY_SSIZE_T_CLEAN ++#if 0 // GraalPy change + #include ++#endif // GraalPy change + #include + #include + #include +@@ -34,7 +36,8 @@ void eval_frame_callback_set(PyObject* obj) { + } + + // 3.14 Not supported at all. See cpython_defs.c for hints +-#if !(IS_PYTHON_3_14_PLUS) ++// GraalPy change ++#if 0 + + #define DECLARE_PYOBJ_ATTR(name) \ + static PyObject* THPPyInterpreterFrame_##name( \ +@@ -543,9 +546,15 @@ static PyObject* set_eval_frame( + Py_INCREF(old_callback); + + if (old_callback != Py_None && new_callback == Py_None) { +- decrement_working_threads(tstate, module); ++ // GraalPy change ++ PyErr_SetString(PyExc_NotImplementedError, "dynamo compilation is not supported on GraalPy"); ++ return NULL; ++ // decrement_working_threads(tstate, module); + } else if (old_callback == Py_None && new_callback != Py_None) { +- increment_working_threads(tstate, module); ++ // GraalPy change ++ PyErr_SetString(PyExc_NotImplementedError, "dynamo compilation is not supported on GraalPy"); ++ return NULL; ++ // increment_working_threads(tstate, module); + } + + Py_INCREF(new_callback); +@@ -600,7 +609,8 @@ static PyObject* reset_code(PyObject* dummy, PyObject* code) { + } + + // set_extra_state destroys the existing object on extra scratch space. +- set_extra_state((PyCodeObject*)code, NULL); ++ // GraalPy change ++ // set_extra_state((PyCodeObject*)code, NULL); + Py_RETURN_NONE; + } + +@@ -679,12 +689,14 @@ static struct PyModuleDef _module = { + #endif + + PyObject* torch_c_dynamo_eval_frame_init(void) { ++#if 0 // GraalPy change + extra_index = _PyEval_RequestCodeExtraIndex(destroy_extra_state); + if (extra_index < 0) { + PyErr_SetString( + PyExc_RuntimeError, "dynamo: unable to register extra index"); + return NULL; + } ++#endif + + int result = PyThread_tss_create(&eval_frame_callback_key); + CHECK(result == 0); +diff --git a/torch/csrc/dynamo/eval_frame_cpp.cpp b/torch/csrc/dynamo/eval_frame_cpp.cpp +index f029fec22..0104c1812 100644 +--- a/torch/csrc/dynamo/eval_frame_cpp.cpp ++++ b/torch/csrc/dynamo/eval_frame_cpp.cpp +@@ -9,6 +9,7 @@ + + const char* cache_lookup_profiler_str = "TorchDynamo Cache Lookup"; + ++#if 0 // GraalPy change + // Remember to update the type signature for DynamoCallbackFn.__call__ in + // torch/_dynamo/types.py if this function's signature changes. + static py::object dynamo_call_callback( +@@ -290,8 +291,10 @@ PyObject* dynamo__custom_eval_frame( + } + return eval_result; + } ++#endif // GraalPy change + + PyObject* set_code_exec_strategy(PyObject* dummy, PyObject* args) { ++#if 0 // GraalPy change + PyObject* code_obj = nullptr; + PyObject* strategy_obj = nullptr; + if (!PyArg_ParseTuple(args, "OO", &code_obj, &strategy_obj)) { +@@ -313,4 +316,8 @@ PyObject* set_code_exec_strategy(PyObject* dummy, PyObject* args) { + + extra_state_set_exec_strategy(extra, strategy); + Py_RETURN_NONE; ++#endif // GraalPy change ++ // GraalPy change ++ PyErr_SetString(PyExc_NotImplementedError, "dynamo compilation is not supported on GraalPy"); ++ return NULL; + } +diff --git a/torch/csrc/dynamo/extra_state.cpp b/torch/csrc/dynamo/extra_state.cpp +index 2e60816aa..a06c0c830 100644 +--- a/torch/csrc/dynamo/extra_state.cpp ++++ b/torch/csrc/dynamo/extra_state.cpp +@@ -101,9 +101,7 @@ void destroy_extra_state(void* obj) { + } + + void set_extra_state(PyCodeObject* code, ExtraState* extra_state) { +- ExtraState* old_extra_state = get_extra_state(code); +- CHECK(extra_state == nullptr || old_extra_state != extra_state); +- _PyCode_SetExtra((PyObject*)code, extra_index, extra_state); ++ // GraalPy change: removed + } + + ExtraState* init_and_set_extra_state(PyCodeObject* code) { +diff --git a/torch/csrc/dynamo/framelocals_mapping.cpp b/torch/csrc/dynamo/framelocals_mapping.cpp +index b839fb26f..b7853029f 100644 +--- a/torch/csrc/dynamo/framelocals_mapping.cpp ++++ b/torch/csrc/dynamo/framelocals_mapping.cpp +@@ -4,7 +4,9 @@ + #include + #include + ++#if 0 // GraalPy change + #include ++#endif // GraalPy change + + #if IS_PYTHON_3_11_PLUS + +@@ -26,6 +28,7 @@ FrameLocalsMapping::FrameLocalsMapping(FrameLocalsFrameType* frame) + PyCodeObject* co = F_CODE(frame); + _framelocals.resize(co->co_nlocalsplus, nullptr); + ++#if 0 // GraalPy change + if (!frame->stacktop) { + return; + } +@@ -65,9 +68,11 @@ FrameLocalsMapping::FrameLocalsMapping(FrameLocalsFrameType* frame) + // NOTE no need to move the instruction pointer to after COPY_FREE_VARS + // since we don't actually copy free vars from the closure to the frame + // localsplus. ++#endif // GraalPy change + } + + void FrameLocalsMapping::_realize_dict() { ++#if 0 // GraalPy change + _dict = py::dict(); + py::tuple framelocals_names = code_framelocals_names(_code_obj); + +@@ -78,11 +83,13 @@ void FrameLocalsMapping::_realize_dict() { + _dict[framelocals_names[i]] = _framelocals[i]; + } + } ++#endif // GraalPy change + } + + py::tuple code_framelocals_names(py::handle code) { + CHECK(PyCode_Check(code.ptr())); +- return py::cast(((PyCodeObject*)code.ptr())->co_localsplusnames); ++ // GraalPy change ++ return code.attr("co_varnames") + code.attr("co_cellvars") + code.attr("co_freevars"); + } + + #else +diff --git a/torch/csrc/jit/python/python_tracer.cpp b/torch/csrc/jit/python/python_tracer.cpp +index 876186743..041348257 100644 +--- a/torch/csrc/jit/python/python_tracer.cpp ++++ b/torch/csrc/jit/python/python_tracer.cpp +@@ -31,11 +31,15 @@ std::vector _pythonCallstack() { + while (nullptr != frame) { + auto code = THPCodeObjectPtr(PyFrame_GetCode(frame)); + size_t line = PyCode_Addr2Line(code.get(), PyFrame_GetLasti(frame)); +- std::string filename = THPUtils_unpackString(code->co_filename); +- std::string funcname = THPUtils_unpackString(code->co_name); ++ PyObject* filenameObj = PyCode_GetFileName(code); ++ std::string filename = THPUtils_unpackString(filenameObj); ++ PyObject* funcnameObj = PyCode_GetName(code); ++ std::string funcname = THPUtils_unpackString(funcnameObj); + auto source = std::make_shared(funcname, filename, line); + entries.emplace_back( + StackEntry{funcname, SourceRange(source, 0, funcname.size())}); ++ Py_DECREF(funcnameObj); ++ Py_DECREF(filenameObj); + auto new_frame = PyFrame_GetBack(frame); + Py_DECREF(frame); + frame = new_frame; diff --git a/graalpython/lib-graalpython/patches/torchvision-1.17.1.patch b/graalpython/lib-graalpython/patches/torchvision-0.17.1.patch similarity index 100% rename from graalpython/lib-graalpython/patches/torchvision-1.17.1.patch rename to graalpython/lib-graalpython/patches/torchvision-0.17.1.patch diff --git a/graalpython/lib-graalpython/patches/torchvision-1.19.1.patch b/graalpython/lib-graalpython/patches/torchvision-0.19.1.patch similarity index 100% rename from graalpython/lib-graalpython/patches/torchvision-1.19.1.patch rename to graalpython/lib-graalpython/patches/torchvision-0.19.1.patch diff --git a/graalpython/lib-graalpython/patches/torchvision-0.22.0.patch b/graalpython/lib-graalpython/patches/torchvision-0.22.0.patch new file mode 100644 index 0000000000..394bfe2399 --- /dev/null +++ b/graalpython/lib-graalpython/patches/torchvision-0.22.0.patch @@ -0,0 +1,14 @@ +diff --git a/setup.py b/setup.py +index a42aef6..a619588 100644 +--- a/setup.py ++++ b/setup.py +@@ -104,6 +104,9 @@ def get_requirements(): + # supported on a best-effort basis, we don't guarantee that this won't + # eventually break (and we don't test it.) + pytorch_dep += f">={version_pin_ge},<{version_pin_lt}" ++ else: ++ # GraalPy change ++ pytorch_dep += "==" + torch.__version__ + + requirements = [ + "numpy", diff --git a/graalpython/lib-graalpython/patches/trio.patch b/graalpython/lib-graalpython/patches/trio.patch new file mode 100644 index 0000000000..dee5d3d252 --- /dev/null +++ b/graalpython/lib-graalpython/patches/trio.patch @@ -0,0 +1,103 @@ +diff --git a/trio/_socket.py b/trio/_socket.py +index 003f6c4..da7411c 100644 +--- a/trio/_socket.py ++++ b/trio/_socket.py +@@ -317,9 +317,7 @@ def fromfd( + return from_stdlib_socket(_stdlib_socket.fromfd(fd, family, type_, proto)) + + +-if sys.platform == "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket, "fromshare") +-): ++if hasattr(_stdlib_socket, "fromshare"): + + @_wraps(_stdlib_socket.fromshare, assigned=(), updated=()) + def fromshare(info: bytes) -> SocketType: +@@ -606,9 +604,7 @@ class SocketType: + def set_inheritable(self, inheritable: bool) -> None: + raise NotImplementedError + +- if sys.platform == "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "share") +- ): ++ if hasattr(_stdlib_socket.socket, "share"): + + def share(self, process_id: int) -> bytes: + raise NotImplementedError +@@ -699,9 +695,7 @@ class SocketType: + ) -> Awaitable[tuple[int, AddressFormat]]: + raise NotImplementedError + +- if sys.platform != "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "recvmsg") +- ): ++ if hasattr(_stdlib_socket.socket, "recvmsg"): + + def recvmsg( + self, +@@ -712,9 +706,7 @@ class SocketType: + ) -> Awaitable[tuple[bytes, list[tuple[int, int, bytes]], int, object]]: + raise NotImplementedError + +- if sys.platform != "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "recvmsg_into") +- ): ++ if hasattr(_stdlib_socket.socket, "recvmsg_into"): + + def recvmsg_into( + self, +@@ -748,9 +740,7 @@ class SocketType: + async def sendto(self, *args: object) -> int: + raise NotImplementedError + +- if sys.platform != "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "sendmsg") +- ): ++ if hasattr(_stdlib_socket.socket, "sendmsg"): + + @_wraps(_stdlib_socket.socket.sendmsg, assigned=(), updated=()) + async def sendmsg( +@@ -867,9 +857,7 @@ class _SocketType(SocketType): + def set_inheritable(self, inheritable: bool) -> None: + return self._sock.set_inheritable(inheritable) + +- if sys.platform == "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "share") +- ): ++ if hasattr(_stdlib_socket.socket, "share"): + + def share(self, process_id: int) -> bytes: + return self._sock.share(process_id) +@@ -1181,9 +1169,7 @@ class _SocketType(SocketType): + # recvmsg + ################################################################ + +- if sys.platform != "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "recvmsg") +- ): ++ if hasattr(_stdlib_socket.socket, "recvmsg"): + if TYPE_CHECKING: + + def recvmsg( +@@ -1204,9 +1190,7 @@ class _SocketType(SocketType): + # recvmsg_into + ################################################################ + +- if sys.platform != "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "recvmsg_into") +- ): ++ if hasattr(_stdlib_socket.socket, "recvmsg_into"): + if TYPE_CHECKING: + + def recvmsg_into( +@@ -1276,9 +1260,7 @@ class _SocketType(SocketType): + # sendmsg + ################################################################ + +- if sys.platform != "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "sendmsg") +- ): ++ if hasattr(_stdlib_socket.socket, "sendmsg"): + + @_wraps(_stdlib_socket.socket.sendmsg, assigned=(), updated=()) + async def sendmsg( diff --git a/graalpython/lib-graalpython/patches/xmlschema.patch b/graalpython/lib-graalpython/patches/xmlschema.patch new file mode 100644 index 0000000000..454d15ec52 --- /dev/null +++ b/graalpython/lib-graalpython/patches/xmlschema.patch @@ -0,0 +1,13 @@ +diff --git a/xmlschema/validators/builders.py b/xmlschema/validators/builders.py +index 1ac8b8e..f39ada8 100644 +--- a/xmlschema/validators/builders.py ++++ b/xmlschema/validators/builders.py +@@ -8,7 +8,7 @@ + # @author Davide Brunato + # + import copy +-from _operator import itemgetter ++from operator import itemgetter + from abc import abstractmethod + from collections import Counter + from collections.abc import Callable, ItemsView, Iterator, Mapping, ValuesView, Iterable diff --git a/graalpython/lib-python/3/datetime.py b/graalpython/lib-python/3/datetime.py index e284a733ef..b7ab16777a 100644 --- a/graalpython/lib-python/3/datetime.py +++ b/graalpython/lib-python/3/datetime.py @@ -683,7 +683,8 @@ def __new__(cls, days=0, seconds=0, microseconds=0, if abs(d) > 999999999: raise OverflowError("timedelta # of days is too large: %d" % d) - self = object.__new__(cls) + # GraalPy change: unsafe ctor to allow native subclasses + self = __graalpython__.unsafe_object_new(cls) self._days = d self._seconds = s self._microseconds = us @@ -940,12 +941,14 @@ def __new__(cls, year, month=None, day=None): "Failed to encode latin1 string when unpickling " "a date object. " "pickle.load(data, encoding='latin1') is assumed.") - self = object.__new__(cls) + # GraalPy change: unsafe ctor to allow native subclasses + self = __graalpython__.unsafe_object_new(cls) self.__setstate(year) self._hashcode = -1 return self year, month, day = _check_date_fields(year, month, day) - self = object.__new__(cls) + # GraalPy change: unsafe ctor to allow native subclasses + self = __graalpython__.unsafe_object_new(cls) self._year = year self._month = month self._day = day @@ -1355,14 +1358,16 @@ def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold "Failed to encode latin1 string when unpickling " "a time object. " "pickle.load(data, encoding='latin1') is assumed.") - self = object.__new__(cls) + # GraalPy change: unsafe ctor to allow native subclasses + self = __graalpython__.unsafe_object_new(cls) self.__setstate(hour, minute or None) self._hashcode = -1 return self hour, minute, second, microsecond, fold = _check_time_fields( hour, minute, second, microsecond, fold) _check_tzinfo_arg(tzinfo) - self = object.__new__(cls) + # GraalPy change: unsafe ctor to allow native subclasses + self = __graalpython__.unsafe_object_new(cls) self._hour = hour self._minute = minute self._second = second @@ -1684,7 +1689,8 @@ def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, "Failed to encode latin1 string when unpickling " "a datetime object. " "pickle.load(data, encoding='latin1') is assumed.") - self = object.__new__(cls) + # GraalPy change: unsafe ctor to allow native subclasses + self = __graalpython__.unsafe_object_new(cls) self.__setstate(year, month) self._hashcode = -1 return self @@ -1692,7 +1698,8 @@ def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, hour, minute, second, microsecond, fold = _check_time_fields( hour, minute, second, microsecond, fold) _check_tzinfo_arg(tzinfo) - self = object.__new__(cls) + # GraalPy change: unsafe ctor to allow native subclasses + self = __graalpython__.unsafe_object_new(cls) self._year = year self._month = month self._day = day @@ -2642,3 +2649,5 @@ def _name_from_offset(delta): # appropriate to maintain a single module level docstring and # remove the following line. from _datetime import __doc__ + +import _polyglot_datetime # GraalPy change: register interop behavior on datetime as soon as datetime is defined diff --git a/graalpython/lib-python/3/distutils/ccompiler.py b/graalpython/lib-python/3/distutils/ccompiler.py index a6c1d3fe64..702eafcbbd 100644 --- a/graalpython/lib-python/3/distutils/ccompiler.py +++ b/graalpython/lib-python/3/distutils/ccompiler.py @@ -930,7 +930,7 @@ def mkpath (self, name, mode=0o777): # OS name mappings ('posix', 'unix'), - ('nt', 'msvc') if __graalpython__.use_system_toolchain else ('nt', 'unix'), + ('nt', 'msvc'), ) def get_default_compiler(osname=None, platform=None): diff --git a/graalpython/lib-python/3/importlib/_bootstrap_external.py b/graalpython/lib-python/3/importlib/_bootstrap_external.py index 7a7c5cdd03..41044bd189 100644 --- a/graalpython/lib-python/3/importlib/_bootstrap_external.py +++ b/graalpython/lib-python/3/importlib/_bootstrap_external.py @@ -454,7 +454,7 @@ def cache_from_source(path, debug_override=None, *, optimization=None): If sys.implementation.cache_tag is None then NotImplementedError is raised. """ - if __graalpython__.in_image_buildtime: + if __graalpython__.in_preinitialization: return if debug_override is not None: _warnings.warn('the debug_override parameter is deprecated; use ' diff --git a/graalpython/lib-python/3/inspect.py b/graalpython/lib-python/3/inspect.py index 655b04b0ee..c7533f3b34 100644 --- a/graalpython/lib-python/3/inspect.py +++ b/graalpython/lib-python/3/inspect.py @@ -2069,6 +2069,9 @@ def _signature_is_builtin(obj): return (isbuiltin(obj) or ismethoddescriptor(obj) or isinstance(obj, _NonUserDefinedCallables) or + # Truffle change: treat foreign executables as builtin + (isinstance(obj, __graalpython__.ForeignType) and callable(obj)) or + # End Truffle change # Can't test 'isinstance(type)' here, as it would # also be True for regular python classes obj in (type, object)) diff --git a/graalpython/lib-python/3/subprocess.py b/graalpython/lib-python/3/subprocess.py index 7bdc1f2a6d..c352d182c2 100644 --- a/graalpython/lib-python/3/subprocess.py +++ b/graalpython/lib-python/3/subprocess.py @@ -1817,7 +1817,10 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, executable = next(shlex.shlex(list2cmdline(args))) if executable.startswith('"') and executable.endswith('"'): executable = executable[1:-1] - if (len(args) == 1 and executable != args[0]) or shell: + if len(args) == 1 and executable != args[0] and executable.startswith("cmd /u /c "): + executable = "cmd.exe" + args = ["cmd.exe", "/u", "/c", args[0][len("cmd /u /c "):]] + elif (len(args) == 1 and executable != args[0]) or shell: if not shell: warnings.warn(f"Running\n\t{args[0]!r} in a cmd shell", RuntimeWarning) shell = False diff --git a/graalpython/lib-python/3/test/support/__init__.py b/graalpython/lib-python/3/test/support/__init__.py index 630166deeb..9a133593fe 100644 --- a/graalpython/lib-python/3/test/support/__init__.py +++ b/graalpython/lib-python/3/test/support/__init__.py @@ -1057,6 +1057,17 @@ def impl_detail(msg=None, **guards): msg = msg.format(' or '.join(guardnames)) return unittest.skip(msg) +def bytecode_dsl_excluded(test): + """ + Decorator for tests that don't apply to the Bytecode DSL interpreter. + """ + try: + if sys.implementation.name == 'graalpy' and __graalpython__.is_bytecode_dsl_interpreter: + return unittest.skip("Not supported by the Bytecode DSL interpreter") + except NameError: + pass + return test + def _parse_guards(guards): # Returns a tuple ({platform_name: run_me}, default_value) if not guards: diff --git a/graalpython/lib-python/3/test/test_cmd_line.py b/graalpython/lib-python/3/test/test_cmd_line.py index 1c33be2858..8f4438fba2 100644 --- a/graalpython/lib-python/3/test/test_cmd_line.py +++ b/graalpython/lib-python/3/test/test_cmd_line.py @@ -78,7 +78,8 @@ def test_site_flag(self): self.verify_valid_flag('-S') def test_version(self): - version = ('Python %d.%d' % sys.version_info[:2]).encode("ascii") + # GraalPy change: expect GraalPy name + version = ('GraalPy %d.%d' % sys.version_info[:2]).encode("ascii") for switch in '-V', '--version', '-VV': rc, out, err = assert_python_ok(switch) self.assertFalse(err.startswith(version)) diff --git a/graalpython/lib-python/3/test/test_sys_settrace.py b/graalpython/lib-python/3/test/test_sys_settrace.py index e97e122534..5c4f83b679 100644 --- a/graalpython/lib-python/3/test/test_sys_settrace.py +++ b/graalpython/lib-python/3/test/test_sys_settrace.py @@ -1,3 +1,42 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + # Testing the line trace facility. from test import support @@ -1869,6 +1908,8 @@ def no_jump_without_trace_function(): raise AssertionError("Trace-function-less jump failed to fail") +# GraalPy Bytecode DSL: for the time being, arbitrary jumps are not supported by Truffle Bytecode DSL +@support.bytecode_dsl_excluded class JumpTestCase(unittest.TestCase): def setUp(self): self.addCleanup(sys.settrace, sys.gettrace()) diff --git a/graalpython/lib-python/3/venv/__init__.py b/graalpython/lib-python/3/venv/__init__.py index 8eafdcd513..01b5c3adbd 100644 --- a/graalpython/lib-python/3/venv/__init__.py +++ b/graalpython/lib-python/3/venv/__init__.py @@ -74,10 +74,6 @@ def create(self, env_dir): self.setup_python(context) if self.with_pip: self._setup_pip(context) - # Truffle change - if not __graalpython__.use_system_toolchain: - self._install_compilers(context) - # End of Truffle change if not self.upgrade: self.setup_scripts(context) self.post_setup(context) @@ -183,50 +179,6 @@ def create_if_needed(d): context.env_exec_cmd = real_env_exe return context - - def _install_compilers(self, context): - """Puts the Graal LLVM compiler tools on the path.""" - bin_dir = os.path.join(context.env_dir, context.bin_name) - for (tool_path, names) in __graalpython__.get_toolchain_tools_for_venv().items(): - for name in names: - dest = os.path.join(bin_dir, name) - if not os.path.exists(dest): - os.symlink(tool_path, dest) - - self._wrap_gfortran(context) - - def _which_gfortran(self, context): - wrapper_path = os.path.join(context.bin_path, "gfortran") - extensions = [".bat", ".exe"] if sys.platform == "win32" else [""] - for p in os.environ.get("PATH", "").split(";" if sys.platform == "win32" else ":"): - if p != wrapper_path: - for ext in extensions: - gfortran = os.path.join(p, "gfortran{}".format(ext)) - if os.path.exists(gfortran): - return gfortran - return None - - def _wrap_gfortran(self, context): - gfortran = self._which_gfortran(context) - if gfortran: - script = os.path.join(context.bin_path, "gfortran") - logger.warning("gfortran compiler found: {}, creating wrapper: {}".format(gfortran, script)) - if sys.platform == 'win32': - script += ".bat" - - with open(script, "w") as f: - if sys.platform != "win32": - f.write("#!/bin/sh\n") - f.write("{} -shared -fPIC".format(gfortran)) - if sys.platform == "win32": - f.write(" %*") - else: - f.write(" \"$@\"") - - if sys.platform != "win32": - os.chmod(script, 0o777) - - def create_configuration(self, context): """ Create a configuration file indicating where the environment's Python diff --git a/graalpython/org.graalvm.python.embedding.tools/src/org/graalvm/python/embedding/tools/exec/BuildToolLog.java b/graalpython/org.graalvm.python.embedding.tools/src/org/graalvm/python/embedding/tools/exec/BuildToolLog.java new file mode 100644 index 0000000000..2a4db4798b --- /dev/null +++ b/graalpython/org.graalvm.python.embedding.tools/src/org/graalvm/python/embedding/tools/exec/BuildToolLog.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.graalvm.python.embedding.tools.exec; + +import java.util.ArrayList; +import java.util.List; + +/** + * Build tool verbosity: maven - debug, info, warning, error gradle - debug, info, lifecycle, + * warning, error + */ +public interface BuildToolLog { + void subProcessOut(String out); + + void subProcessErr(String err); + + default void lifecycle(String s) { + info(s); + } + + void info(String s); + + void warning(String s); + + void warning(String s, Throwable t); + + void error(String s); + + void debug(String s); + + boolean isWarningEnabled(); + + default boolean isLifecycleEnabled() { + return true; + } + + boolean isInfoEnabled(); + + boolean isErrorEnabled(); + + boolean isDebugEnabled(); + + boolean isSubprocessOutEnabled(); + + final class CollectOutputLog implements BuildToolLog { + private final List output = new ArrayList<>(); + private final BuildToolLog delegate; + + public CollectOutputLog(BuildToolLog delegate) { + this.delegate = delegate; + } + + public List getOutput() { + return output; + } + + @Override + public boolean isDebugEnabled() { + return delegate.isDebugEnabled(); + } + + @Override + public boolean isInfoEnabled() { + return delegate.isInfoEnabled(); + } + + @Override + public void info(String s) { + delegate.info(s); + } + + @Override + public void warning(String s) { + delegate.warning(s); + } + + @Override + public void warning(String s, Throwable t) { + delegate.warning(s, t); + } + + @Override + public void error(String s) { + delegate.error(s); + } + + @Override + public void debug(String s) { + delegate.debug(s); + } + + @Override + public boolean isWarningEnabled() { + return delegate.isWarningEnabled(); + } + + @Override + public boolean isErrorEnabled() { + return delegate.isErrorEnabled(); + } + + @Override + public boolean isSubprocessOutEnabled() { + return true; + } + + @Override + public void subProcessOut(String s) { + output.add(s); + } + + @Override + public void subProcessErr(String s) { + delegate.error(s); + } + } +} diff --git a/graalpython/org.graalvm.python.embedding.tools/src/org/graalvm/python/embedding/tools/exec/GraalPyRunner.java b/graalpython/org.graalvm.python.embedding.tools/src/org/graalvm/python/embedding/tools/exec/GraalPyRunner.java index f9bef8a7b3..14833396e9 100644 --- a/graalpython/org.graalvm.python.embedding.tools/src/org/graalvm/python/embedding/tools/exec/GraalPyRunner.java +++ b/graalpython/org.graalvm.python.embedding.tools/src/org/graalvm/python/embedding/tools/exec/GraalPyRunner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -51,6 +51,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Set; @@ -60,15 +61,29 @@ public class GraalPyRunner { private static final String BIN_DIR = IS_WINDOWS ? "Scripts" : "bin"; private static final String EXE_SUFFIX = IS_WINDOWS ? ".exe" : ""; - public static void run(Set classpath, SubprocessLog log, String... args) throws IOException, InterruptedException { + public static String[] getExtraJavaOptions() { + String javaVersion = System.getProperty("java.version"); + try { + if (Integer.parseInt(javaVersion) >= 24) { + return new String[]{"--sun-misc-unsafe-memory-access=allow"}; + } + } catch (NumberFormatException ex) { + // covers also javaVersion being 'null' + } + return new String[0]; + } + + public static void run(Set classpath, BuildToolLog log, String... args) throws IOException, InterruptedException { run(String.join(File.pathSeparator, classpath), log, args); } - public static void run(String classpath, SubprocessLog log, String... args) throws IOException, InterruptedException { + public static void run(String classpath, BuildToolLog log, String... args) throws IOException, InterruptedException { String workdir = System.getProperty("exec.workingdir"); Path java = Paths.get(System.getProperty("java.home"), "bin", "java"); List cmd = new ArrayList<>(); cmd.add(java.toString()); + cmd.add("--enable-native-access=ALL-UNNAMED"); + cmd.addAll(Arrays.asList(getExtraJavaOptions())); cmd.add("-classpath"); cmd.add(classpath); cmd.add("com.oracle.graal.python.shell.GraalPythonMain"); @@ -77,20 +92,20 @@ public static void run(String classpath, SubprocessLog log, String... args) thro if (workdir != null) { pb.directory(new File(workdir)); } - log.log(String.format("Running GraalPy: %s", String.join(" ", cmd))); + infoCmd(log, "Running GraalPy:", cmd); runProcess(pb, log); } - public static void runLauncher(String launcherPath, SubprocessLog log, String... args) throws IOException, InterruptedException { + public static void runLauncher(String launcherPath, BuildToolLog log, String... args) throws IOException, InterruptedException { var cmd = new ArrayList(); cmd.add(launcherPath); cmd.addAll(List.of(args)); - log.log(String.format("Running: %s", String.join(" ", cmd))); + infoCmd(log, "Running:", cmd); var pb = new ProcessBuilder(cmd); runProcess(pb, log); } - public static void runPip(Path venvDirectory, String command, SubprocessLog log, String... args) throws IOException, InterruptedException { + public static void runPip(Path venvDirectory, String command, BuildToolLog log, String... args) throws IOException, InterruptedException { var newArgs = new ArrayList(); newArgs.add("-m"); newArgs.add("pip"); @@ -101,15 +116,15 @@ public static void runPip(Path venvDirectory, String command, SubprocessLog log, runVenvBin(venvDirectory, "graalpy", log, newArgs); } - public static void runVenvBin(Path venvDirectory, String command, SubprocessLog log, String... args) throws IOException, InterruptedException { + public static void runVenvBin(Path venvDirectory, String command, BuildToolLog log, String... args) throws IOException, InterruptedException { runVenvBin(venvDirectory, command, log, List.of(args)); } - private static void runVenvBin(Path venvDirectory, String command, SubprocessLog log, List args) throws IOException, InterruptedException { + private static void runVenvBin(Path venvDirectory, String command, BuildToolLog log, List args) throws IOException, InterruptedException { var cmd = new ArrayList(); cmd.add(venvDirectory.resolve(BIN_DIR).resolve(command + EXE_SUFFIX).toString()); cmd.addAll(args); - log.log(String.join(" ", cmd)); + infoCmd(log, "Executing:", cmd); var pb = new ProcessBuilder(cmd); runProcess(pb, log); } @@ -139,7 +154,7 @@ private static String fixProtocol(String proxyAddress, String protocol) { return proxyAddress.startsWith(protocol) ? proxyAddress : protocol + "://" + proxyAddress; } - private static void runProcess(ProcessBuilder pb, SubprocessLog log) throws IOException, InterruptedException { + private static void runProcess(ProcessBuilder pb, BuildToolLog log) throws IOException, InterruptedException { pb.redirectError(); pb.redirectOutput(); Process process = pb.start(); @@ -147,12 +162,12 @@ private static void runProcess(ProcessBuilder pb, SubprocessLog log) throws IOEx try (InputStream is = process.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is))) { String line; while ((line = reader.readLine()) != null) { - log.subProcessOut(line); + subProcessOut(log, line); } } catch (IOException e) { // Do nothing for now. Probably is not good idea to stop the // execution at this moment - log.log("exception while reading subprocess out", e); + warn(log, "exception while reading subprocess out", e); } }); outputReader.start(); @@ -162,12 +177,12 @@ private static void runProcess(ProcessBuilder pb, SubprocessLog log) throws IOEx BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); String line; while ((line = errorBufferedReader.readLine()) != null) { - log.subProcessErr(line); + subProcessErr(log, line); } } catch (IOException e) { // Do nothing for now. Probably is not good idea to stop the // execution at this moment - log.log("exception while reading subprocess err", e); + warn(log, "exception while reading subprocess err", e); } }); errorReader.start(); @@ -181,4 +196,27 @@ private static void runProcess(ProcessBuilder pb, SubprocessLog log) throws IOEx } } + private static void warn(BuildToolLog log, String txt, Throwable t) { + if (log.isWarningEnabled()) { + log.warning(txt, t); + } + } + + private static void infoCmd(BuildToolLog log, String msg, List cmd) { + if (log.isInfoEnabled()) { + log.info(String.format("%s %s", msg, String.join(" ", cmd))); + } + } + + private static void subProcessOut(BuildToolLog log, String txt) { + if (log.isSubprocessOutEnabled()) { + log.subProcessOut(txt); + } + } + + private static void subProcessErr(BuildToolLog log, String txt) { + if (log.isErrorEnabled()) { + log.subProcessErr(txt); + } + } } diff --git a/graalpython/org.graalvm.python.embedding.tools/src/org/graalvm/python/embedding/tools/vfs/VFSUtils.java b/graalpython/org.graalvm.python.embedding.tools/src/org/graalvm/python/embedding/tools/vfs/VFSUtils.java index 46637889eb..90538ff66d 100644 --- a/graalpython/org.graalvm.python.embedding.tools/src/org/graalvm/python/embedding/tools/vfs/VFSUtils.java +++ b/graalpython/org.graalvm.python.embedding.tools/src/org/graalvm/python/embedding/tools/vfs/VFSUtils.java @@ -44,32 +44,142 @@ import java.io.FileWriter; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.nio.file.attribute.PosixFilePermission; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Objects; import java.util.Set; import java.util.TreeSet; import java.util.function.Consumer; +import org.graalvm.python.embedding.tools.exec.BuildToolLog; +import org.graalvm.python.embedding.tools.exec.BuildToolLog.CollectOutputLog; import org.graalvm.python.embedding.tools.exec.GraalPyRunner; -import org.graalvm.python.embedding.tools.exec.SubprocessLog; -import org.graalvm.python.embedding.tools.exec.SubprocessLog.CollectOutputLog; public final class VFSUtils { + /** + * Patterns which should be excluded by default, like .gitignore or SCM files. + *
        + *
      • Misc: **/*~, **/#*#, **/.#*, **/%*%, + * **/._*
      • + *
      • CVS: **/CVS, **/CVS/**, **/.cvsignore
      • + *
      • RCS: **/RCS, **/RCS/**
      • + *
      • SCCS: **/SCCS, **/SCCS/**
      • + *
      • VSSercer: **/vssver.scc
      • + *
      • MKS: **/project.pj
      • + *
      • SVN: **/.svn, **/.svn/**
      • + *
      • GNU: **/.arch-ids, **/.arch-ids/**
      • + *
      • Bazaar: **/.bzr, **/.bzr/**
      • + *
      • SurroundSCM: **/.MySCMServerInfo
      • + *
      • Mac: **/.DS_Store
      • + *
      • Serena Dimension: **/.metadata, **/.metadata/**
      • + *
      • Mercurial: **/.hg, **/.hg/**
      • + *
      • Git: **/.git, **/.git/**, **/.gitignore
      • + *
      • Bitkeeper: **/BitKeeper, **/BitKeeper/**, **/ChangeSet, + * **/ChangeSet/**
      • + *
      • Darcs: **/_darcs, **/_darcs/**, **/.darcsrepo, + * **/.darcsrepo/****/-darcs-backup*, **/.darcs-temp-mail + *
      + * + * + * The list is a copy of the one used in tools like the Maven JAR Plugin. @see DEFAULTEXCLUDES + */ + private static final String[] DEFAULT_EXCLUDES = { + // Miscellaneous typical temporary files + "**/*~", + "**/#*#", + "**/.#*", + "**/%*%", + "**/._*", + + // CVS + "**/CVS", + "**/CVS/**", + "**/.cvsignore", + + // RCS + "**/RCS", + "**/RCS/**", + + // SCCS + "**/SCCS", + "**/SCCS/**", + + // Visual SourceSafe + "**/vssver.scc", + + // MKS + "**/project.pj", + + // Subversion + "**/.svn", + "**/.svn/**", + + // Arch + "**/.arch-ids", + "**/.arch-ids/**", + + // Bazaar + "**/.bzr", + "**/.bzr/**", + + // SurroundSCM + "**/.MySCMServerInfo", + + // Mac + "**/.DS_Store", + + // Serena Dimensions Version 10 + "**/.metadata", + "**/.metadata/**", + + // Mercurial + "**/.hg", + "**/.hg/**", + + // git + "**/.git", + "**/.git/**", + "**/.gitignore", + + // BitKeeper + "**/BitKeeper", + "**/BitKeeper/**", + "**/ChangeSet", + "**/ChangeSet/**", + + // darcs + "**/_darcs", + "**/_darcs/**", + "**/.darcsrepo", + "**/.darcsrepo/**", + "**/-darcs-backup*", + "**/.darcs-temp-mail" + }; + public static final String VFS_ROOT = "org.graalvm.python.vfs"; public static final String VFS_VENV = "venv"; public static final String VFS_FILESLIST = "fileslist.txt"; public static final String GRAALPY_GROUP_ID = "org.graalvm.python"; + private static final String PLATFORM = System.getProperty("os.name") + " " + System.getProperty("os.arch"); + private static final String NATIVE_IMAGE_RESOURCES_CONFIG = """ { "resources": { @@ -130,13 +240,6 @@ private static String normalizeResourcePath(String path) { return REPLACE_BACKSLASHES ? path.replace("\\", "/") : path; } - /** - * Adds the VFS filelist entries to given set. Caller may provide a non-empty set. - */ - public static void generateVFSFilesList(Path vfs, Set ret, Consumer duplicateHandler) throws IOException { - generateVFSFilesList(null, vfs, ret, duplicateHandler); - } - public static void generateVFSFilesList(Path resourcesRoot, Path vfs, Set ret, Consumer duplicateHandler) throws IOException { if (!Files.isDirectory(vfs)) { throw new IOException(String.format("'%s' has to exist and be a directory.\n", vfs)); @@ -152,23 +255,35 @@ public static void generateVFSFilesList(Path resourcesRoot, Path vfs, Set { - String entry = null; - if (Files.isDirectory(p)) { - String dirPath = makeDirPath(p.toAbsolutePath()); - entry = dirPath.substring(rootEndIdx); - } else if (Files.isRegularFile(p)) { - entry = p.toAbsolutePath().toString().substring(rootEndIdx); - } - if (entry != null) { - entry = normalizeResourcePath(entry); - if (!ret.add(entry) && duplicateHandler != null) { - duplicateHandler.accept(entry); + if (!shouldPathBeExcluded(p)) { + String entry = null; + if (Files.isDirectory(p)) { + String dirPath = makeDirPath(p.toAbsolutePath()); + entry = dirPath.substring(rootEndIdx); + } else if (Files.isRegularFile(p)) { + entry = p.toAbsolutePath().toString().substring(rootEndIdx); + } + if (entry != null) { + entry = normalizeResourcePath(entry); + if (!ret.add(entry) && duplicateHandler != null) { + duplicateHandler.accept(entry); + } } } }); } } + private static boolean shouldPathBeExcluded(Path path) { + for (String glob : DEFAULT_EXCLUDES) { + var matcher = FileSystems.getDefault().getPathMatcher("glob:" + glob); + if (matcher.matches(path)) { + return true; + } + } + return false; + } + private static String makeDirPath(Path p) { String ret = p.toString(); if (!ret.endsWith(File.separator)) { @@ -177,16 +292,7 @@ private static String makeDirPath(Path p) { return ret; } - @FunctionalInterface - public interface LauncherClassPath { - Set get() throws IOException; - } - - public interface Log { - void info(String s); - } - - public static void delete(Path dir) throws IOException { + private static void delete(Path dir) throws IOException { if (!Files.exists(dir)) { return; } @@ -199,77 +305,505 @@ public static void delete(Path dir) throws IOException { } } - public static void createVenv(Path venvDirectory, List packages, Path launcher, LauncherClassPath launcherClassPath, String graalPyVersion, SubprocessLog subprocessLog, Log log) - throws IOException { - Path launcherPath = launcher; - String externalLauncher = System.getProperty("graalpy.vfs.venvLauncher"); - if (externalLauncher == null || externalLauncher.trim().isEmpty()) { - generateLaunchers(launcherPath, launcherClassPath, subprocessLog, log); - } else { - launcherPath = Path.of(externalLauncher); + public abstract static class Launcher { + private final Path launcherPath; + + protected Launcher(Path launcherPath) { + Objects.requireNonNull(launcherPath); + this.launcherPath = launcherPath; } - if (packages != null) { - trim(packages); + protected abstract Set computeClassPath() throws IOException; + } + + private static class InstalledPackages { + final Path venvDirectory; + final Path installedFile; + List packages; + + private InstalledPackages(Path venvDirectory, Path installedFile, List packages) { + this.venvDirectory = venvDirectory; + this.installedFile = installedFile; + this.packages = packages; } - List installedPackages = new ArrayList<>(); - var tag = venvDirectory.resolve("contents"); + static InstalledPackages fromVenv(Path venvDirectory) throws IOException { + Path installed = venvDirectory.resolve("installed.txt"); + List pkgs = Files.exists(installed) ? readPackagesFromFile(installed) : Collections.emptyList(); + return new InstalledPackages(venvDirectory, installed, pkgs); + } - if (Files.exists(venvDirectory)) { - checkLauncher(venvDirectory, launcherPath, log); - - if (Files.isReadable(tag)) { - List lines = null; - try { - lines = Files.readAllLines(tag); - } catch (IOException e) { - throw new IOException(String.format("failed to read tag file %s", tag), e); + List freeze(BuildToolLog log) throws IOException { + CollectOutputLog collectOutputLog = new CollectOutputLog(log); + runPip(venvDirectory, "freeze", collectOutputLog, "--local"); + packages = new ArrayList<>(collectOutputLog.getOutput()); + + String toWrite = "# Generated by GraalPy Maven or Gradle plugin using pip freeze\n" + + "# This file is used by GraalPy VirtualFileSystem\n" + + String.join("\n", packages); + Files.write(installedFile, toWrite.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); + + logDebug(log, packages, "VFSUtils venv packages after install %s:", installedFile); + + return packages; + } + } + + private static class VenvContents { + private static final String KEY_VERSION = "version"; + private static final String KEY_PACKAGES = "input_packages"; + private static final String KEY_PLATFORM = "platform"; + private static final String CONTENTS_FILE_NAME = "contents"; + final Path contentsFile; + List packages; + final String graalPyVersion; + final String platform; + + private VenvContents(Path contentsFile, List packages, String graalPyVersion, String platform) { + this.contentsFile = contentsFile; + this.packages = packages; + this.graalPyVersion = graalPyVersion; + this.platform = platform; + } + + static VenvContents create(Path venvDirectory, String graalPyVersion) { + return new VenvContents(venvDirectory.resolve(CONTENTS_FILE_NAME), Collections.emptyList(), graalPyVersion, PLATFORM); + } + + static VenvContents fromVenv(Path venvDirectory) throws IOException { + Path contentsFile = venvDirectory.resolve(CONTENTS_FILE_NAME); + if (Files.exists(contentsFile)) { + List lines = Files.readAllLines(contentsFile); + if (lines.isEmpty()) { + return null; } - if (lines.isEmpty() || !graalPyVersion.equals(lines.get(0))) { - log.info(String.format("Stale GraalPy venv, updating to %s", graalPyVersion)); - delete(venvDirectory); + if (lines.get(0).startsWith("version=")) { + // this was created with version >= 25 + Map m = new HashMap<>(); + Iterator it = lines.iterator(); + while (it.hasNext()) { + String l = it.next(); + int idx = l.indexOf("="); + m.put(l.substring(0, idx), l.substring(idx + 1)); + } + String graalPyVersion = m.get(KEY_VERSION); + String platform = m.get(KEY_PLATFORM); + String packagesLine = m.get(KEY_PACKAGES); + List packages = packagesLine != null ? Arrays.asList(packagesLine.split(",")) : Collections.emptyList(); + return new VenvContents(contentsFile, packages, graalPyVersion, platform); } else { - for (int i = 1; i < lines.size(); i++) { - installedPackages.add(lines.get(i)); + List packages = new ArrayList<>(); + String graalPyVersion; + Iterator it = lines.iterator(); + graalPyVersion = it.next(); + while (it.hasNext()) { + packages.add(it.next()); } + return new VenvContents(contentsFile, packages, graalPyVersion, null); } } + return null; } - if (!Files.exists(venvDirectory)) { - log.info(String.format("Creating GraalPy %s venv", graalPyVersion)); - runLauncher(launcherPath.toString(), subprocessLog, "-m", "venv", venvDirectory.toString(), "--without-pip"); - runVenvBin(venvDirectory, "graalpy", subprocessLog, "-I", "-m", "ensurepip"); - } - - Iterable frozenPkgs = null; - if (packages != null) { - boolean needsUpdate = false; - needsUpdate |= deleteUnwantedPackages(venvDirectory, packages, installedPackages, subprocessLog); - needsUpdate |= installWantedPackages(venvDirectory, packages, installedPackages, subprocessLog); - if (needsUpdate) { - var freezeLog = new CollectOutputLog(); - runPip(venvDirectory, "freeze", freezeLog, "--local"); - frozenPkgs = freezeLog.getOutput(); + void write(List pkgs) throws IOException { + List lines = new ArrayList<>(); + lines.add(KEY_VERSION + "=" + graalPyVersion); + lines.add(KEY_PLATFORM + "=" + PLATFORM); + lines.add(KEY_PACKAGES + "=" + String.join(",", pkgs)); + Files.write(contentsFile, lines, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); + } + } + + private static final String GRAALPY_VERSION_PREFIX = "# graalpy-version: "; + private static final String INPUT_PACKAGES_PREFIX = "# input-packages: "; + private static final String INPUT_PACKAGES_DELIMITER = ","; + + private static class LockFile { + + final Path path; + final List packages; + final List inputPackages; + + private LockFile(Path path, List inputPackages, List packages) { + this.path = path; + this.packages = packages; + this.inputPackages = inputPackages; + } + + static LockFile fromFile(Path file, BuildToolLog log) throws IOException { + List packages = new ArrayList<>(); + List inputPackages = null; + List lines; + try { + lines = Files.readAllLines(file); + } catch (IOException e) { + throw new IOException(String.format("Cannot read the lock file from '%s'", file), e); + } + if (lines.isEmpty()) { + throw wrongFormat(file, lines, log); + } + // format: + // 1.) a multiline header comment + // 2.) graalpy version - 1 line (starting with comment #) + // 2.) input packages - 1 line (starting with comment #) + // 3.) locked packages - 1 line each (as input for pip install) + // see also LockFile.write() + Iterator it = lines.iterator(); + try { + // graalpy version, we don't care about it for now, but with future versions the + // file format might change, and we will need to know to parse differently + String graalPyVersion = null; + while (it.hasNext()) { + String line = it.next(); + if (line.startsWith(GRAALPY_VERSION_PREFIX)) { + graalPyVersion = line.substring(GRAALPY_VERSION_PREFIX.length()).trim(); + if (graalPyVersion.isEmpty()) { + throw wrongFormat(file, lines, log); + } + break; + } + } + if (graalPyVersion == null) { + throw wrongFormat(file, lines, log); + } + // input packages + String line = it.next(); + if (!line.startsWith(INPUT_PACKAGES_PREFIX)) { + throw wrongFormat(file, lines, log); + } + String pkgs = line.substring(INPUT_PACKAGES_PREFIX.length()).trim(); + if (pkgs.isEmpty()) { + throw wrongFormat(file, lines, log); + } + inputPackages = Arrays.asList(pkgs.split(INPUT_PACKAGES_DELIMITER)); + // locked packages + while (it.hasNext()) { + packages.add(it.next()); + } + } catch (NoSuchElementException e) { + throw wrongFormat(file, lines, log); + } + return new LockFile(file, inputPackages, packages); + } + + private static IOException wrongFormat(Path file, List lines, BuildToolLog log) { + if (log.isDebugEnabled()) { + log.debug("wrong format of lock file " + file); + for (String l : lines) { + log.debug(l); + } + log.debug(""); + } + return new IOException(String.format("Cannot read the lock file from '%s'\n(turn on debug log level to see the contents)", file)); + } + + private static void write(Path venvDirectory, Path lockFile, String lockFileHeader, List inputPackages, String graalPyVersion, BuildToolLog log) throws IOException { + Objects.requireNonNull(venvDirectory); + Objects.requireNonNull(lockFile); + Objects.requireNonNull(lockFileHeader); + Objects.requireNonNull(log); + + assert Files.exists(venvDirectory); + + InstalledPackages installedPackages = InstalledPackages.fromVenv(venvDirectory); + List header = getHeaderList(lockFileHeader); + header.add(GRAALPY_VERSION_PREFIX + graalPyVersion); + header.add(INPUT_PACKAGES_PREFIX + String.join(INPUT_PACKAGES_DELIMITER, inputPackages)); + Files.write(lockFile, header, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); + Files.write(lockFile, installedPackages.packages, StandardOpenOption.APPEND); + + lifecycle(log, "Created GraalPy lock file: %s", lockFile); + logDebug(log, installedPackages.packages, null); + } + + private static List getHeaderList(String lockFileHeader) { + List list = new ArrayList<>(); + String[] lines = lockFileHeader.split("\n"); + for (String l : lines) { + list.add("# " + l); } + return list; + } + } + + public static final class PackagesChangedException extends Exception { + private static final long serialVersionUID = 9162516912727973035L; + + private final transient List pluginPackages; + private final transient List lockFilePackages; + + private PackagesChangedException(List pluginPackages, List lockFilePackages) { + this.pluginPackages = pluginPackages; + this.lockFilePackages = lockFilePackages; + } + + public List getPluginPackages() { + return pluginPackages; } + public List getLockFilePackages() { + return lockFilePackages; + } + + } + + public static void createVenv(Path venvDirectory, List packagesArgs, Launcher launcherArgs, String graalPyVersion, BuildToolLog log) throws IOException { try { - Files.write(tag, List.of(graalPyVersion), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); - Files.write(tag, packages, StandardOpenOption.APPEND); - if (frozenPkgs != null) { - String toWrite = "# Generated by GraalPy Maven or Gradle plugin using pip freeze\n" + - "# This file is used by GraalPy VirtualFileSystem\n" + - String.join("\n", frozenPkgs); - Files.write(venvDirectory.resolve("installed.txt"), toWrite.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); + createVenv(venvDirectory, packagesArgs, null, null, launcherArgs, graalPyVersion, log); + } catch (PackagesChangedException e) { + // should not happen + assert false; + throw new IllegalStateException(e); + } + } + + public static void createVenv(Path venvDirectory, List packages, Path lockFilePath, String missingLockFileWarning, Launcher launcher, String graalPyVersion, BuildToolLog log) + throws IOException, PackagesChangedException { + Objects.requireNonNull(venvDirectory); + Objects.requireNonNull(packages); + Objects.requireNonNull(launcher); + Objects.requireNonNull(graalPyVersion); + Objects.requireNonNull(log); + + logVenvArgs(venvDirectory, packages, lockFilePath, launcher, graalPyVersion, log); + + List pluginPackages = trim(packages); + LockFile lockFile = null; + if (lockFilePath != null && Files.exists(lockFilePath)) { + lockFile = LockFile.fromFile(lockFilePath, log); + } + + if (!checkPackages(venvDirectory, pluginPackages, lockFile, log)) { + return; + } + + VenvContents venvContents = ensureVenv(venvDirectory, graalPyVersion, launcher, log); + + InstalledPackages installedPackages = InstalledPackages.fromVenv(venvDirectory); + boolean installed; + if (lockFile != null) { + installed = install(venvDirectory, installedPackages, lockFile, log); + } else { + installed = install(venvDirectory, pluginPackages, venvContents, log); + } + if (installed) { + venvContents.write(pluginPackages); + installedPackages.freeze(log); + } + if (lockFile == null) { + missingLockFileWarning(venvDirectory, pluginPackages, missingLockFileWarning, log); + } + } + + private static boolean removedFromPluginPackages(Path venvDirectory, List pluginPackages) throws IOException { + if (Files.exists(venvDirectory)) { + // compare with contents from prev install if such already present + VenvContents contents = VenvContents.fromVenv(venvDirectory); + if (contents == null || contents.packages == null) { + return false; + } + List installedPackages = InstalledPackages.fromVenv(venvDirectory).packages; + return removedFromPluginPackages(pluginPackages, contents.packages, installedPackages); + } + return false; + } + + private static boolean removedFromPluginPackages(List pluginPackages, List contentsPackages, List installedPackages) { + for (String contentsPackage : contentsPackages) { + if (!pluginPackages.contains(contentsPackage)) { + // a previously installed package is missing + // in the current plugin packages list + if (!contentsPackage.contains("==")) { + // it had previously no version specified, + // check if it is requested with the same version as installed + String pkgAndVersion = getByName(contentsPackage, pluginPackages); + if (pkgAndVersion != null) { + // yes, a version was added to a package + if (installedPackages.contains(pkgAndVersion)) { + // and it happened to be already installed with the same version + continue; + } + } + } + return true; } - } catch (IOException e) { - throw new IOException(String.format("failed to write tag file %s", tag), e); } + return false; } - private static void checkLauncher(Path venvDirectory, Path launcherPath, Log log) throws IOException { + private static String getByName(String name, List packages) { + for (String p : packages) { + int idx = p.indexOf("=="); + if (idx > -1) { + String n = p.split("==")[0]; + if (n.equals(name)) { + return p; + } + } + } + return null; + } + + public static void lockPackages(Path venvDirectory, List packages, Path lockFile, String lockFileHeader, Launcher launcher, + String graalPyVersion, BuildToolLog log) throws IOException { + Objects.requireNonNull(venvDirectory); + Objects.requireNonNull(packages); + Objects.requireNonNull(lockFile); + Objects.requireNonNull(lockFileHeader); + Objects.requireNonNull(graalPyVersion); + Objects.requireNonNull(log); + + createVenv(venvDirectory, packages, launcher, graalPyVersion, log); + + if (Files.exists(venvDirectory)) { + LockFile.write(venvDirectory, lockFile, lockFileHeader, packages, graalPyVersion, log); + } else { + // how comes? + warning(log, "did not generate new python lock file due to missing python virtual environment"); + } + } + + private static void logVenvArgs(Path venvDirectory, List packages, Path lockFile, Launcher launcherArgs, String graalPyVersion, BuildToolLog log) + throws IOException { + if (log.isDebugEnabled()) { + // avoid computing classpath if not necessary + Set lcp = launcherArgs.computeClassPath(); + log.debug("VFSUtils.createVenv with:"); + log.debug(" graalPyVersion: " + graalPyVersion); + log.debug(" venvDirectory: " + venvDirectory); + log.debug(" packages: " + packages); + log.debug(" lock file: " + lockFile); + log.debug(" launcher: " + launcherArgs.launcherPath); + log.debug(" launcher classpath: " + lcp); + } + } + + private static boolean checkPackages(Path venvDirectory, List pluginPackages, LockFile lockFile, BuildToolLog log) throws IOException, PackagesChangedException { + if (lockFile != null) { + checkPluginPackagesInLockFile(pluginPackages, lockFile); + logPackages(lockFile.packages, lockFile.path, log); + return needVenv(venvDirectory, lockFile.packages, log); + } else { + if (removedFromPluginPackages(venvDirectory, pluginPackages)) { + // a package was removed, and we do not know if it did not leave behind any + // transitive dependencies - rather create whole venv again to avoid it growing + info(log, "A package with transitive dependencies was removed since last install, setting up a clean venv"); + delete(venvDirectory); + } + logPackages(pluginPackages, null, log); + return needVenv(venvDirectory, pluginPackages, log); + } + } + + private static boolean needVenv(Path venvDirectory, List packages, BuildToolLog log) throws IOException { + if ((packages.isEmpty())) { + if (Files.exists(venvDirectory)) { + info(log, "No packages to install, deleting venv"); + delete(venvDirectory); + } else { + debug(log, "VFSUtils skipping venv create - no package or lock file provided"); + } + return false; + } + return true; + } + + private static void logPackages(List packages, Path lockFile, BuildToolLog log) { + if (lockFile != null) { + info(log, "Got %s python package(s) in lock file: %s", packages.size(), lockFile); + } else { + info(log, "Got %s python package(s) in GraalPy plugin configuration", packages.size()); + } + if (log.isDebugEnabled()) { + for (String pkg : packages) { + log.debug(" " + pkg); + } + } + } + + private static List readPackagesFromFile(Path file) throws IOException { + return Files.readAllLines(file).stream().filter((s) -> { + if (s == null) { + return false; + } + String l = s.trim(); + return !l.startsWith("#") && !s.isEmpty(); + }).toList(); + } + + private static VenvContents ensureVenv(Path venvDirectory, String graalPyVersion, Launcher launcher, BuildToolLog log) throws IOException { + Path launcherPath = ensureLauncher(launcher, log); + VenvContents contents = null; + if (Files.exists(venvDirectory)) { + checkVenvLauncher(venvDirectory, launcherPath, log); + contents = VenvContents.fromVenv(venvDirectory); + if (contents == null) { + warning(log, "Reinstalling GraalPy venv due to corrupt contents file"); + delete(venvDirectory); + } else if (!graalPyVersion.equals(contents.graalPyVersion)) { + contents = null; + info(log, "Stale GraalPy virtual environment, updating to %s", graalPyVersion); + delete(venvDirectory); + } else if (!PLATFORM.equals(contents.platform)) { + info(log, "Reinstalling GraalPy venv created on %s, but current is'%s", contents.platform, PLATFORM); + contents = null; + delete(venvDirectory); + } + } + + if (!Files.exists(venvDirectory)) { + info(log, "Creating GraalPy %s venv", graalPyVersion); + runLauncher(launcherPath.toString(), log, "-m", "venv", venvDirectory.toString(), "--without-pip"); + runVenvBin(venvDirectory, "graalpy", log, "-I", "-m", "ensurepip"); + } + + if (contents == null) { + contents = VenvContents.create(venvDirectory, graalPyVersion); + } + + return contents; + } + + private static boolean install(Path venvDirectory, InstalledPackages installedPackages, LockFile lockFile, BuildToolLog log) throws IOException { + if (installedPackages.packages.size() != lockFile.packages.size() || deleteUnwantedPackages(venvDirectory, lockFile.packages, installedPackages.packages, log)) { + runPip(venvDirectory, "install", log, "-r", lockFile.path.toString()); + return true; + } else { + info(log, "Virtual environment is up to date with lock file, skipping install"); + } + return false; + } + + private static boolean install(Path venvDirectory, List newPackages, VenvContents venvContents, BuildToolLog log) throws IOException { + boolean needsUpdate = false; + needsUpdate |= deleteUnwantedPackages(venvDirectory, newPackages, venvContents.packages, log); + needsUpdate |= installWantedPackages(venvDirectory, newPackages, venvContents.packages, log); + return needsUpdate; + } + + private static void missingLockFileWarning(Path venvDirectory, List newPackages, String missingLockFileWarning, BuildToolLog log) throws IOException { + if (missingLockFileWarning != null && !Boolean.getBoolean("graalpy.vfs.skipMissingLockFileWarning")) { + if (!newPackages.containsAll(InstalledPackages.fromVenv(venvDirectory).packages)) { + if (log.isWarningEnabled()) { + String txt = missingLockFileWarning + "\n"; + for (String t : txt.split("\n")) { + log.warning(t); + } + } + } + } + } + + /** + * check that there are no plugin packages missing in lock file + */ + private static void checkPluginPackagesInLockFile(List pluginPackages, LockFile lockFile) throws PackagesChangedException { + if (pluginPackages.size() != lockFile.inputPackages.size() || !pluginPackages.containsAll(lockFile.inputPackages)) { + throw new PackagesChangedException(new ArrayList<>(pluginPackages), new ArrayList<>(lockFile.inputPackages)); + } + } + + private static void checkVenvLauncher(Path venvDirectory, Path launcherPath, BuildToolLog log) throws IOException { if (!Files.exists(launcherPath)) { throw new IOException(String.format("Launcher file does not exist '%s'", launcherPath)); } @@ -285,7 +819,7 @@ private static void checkLauncher(Path venvDirectory, Path launcherPath, Log log if (l.trim().equals("executable")) { Path cfgLauncherPath = Path.of(r); if (!Files.exists(cfgLauncherPath) || !Files.isSameFile(launcherPath, cfgLauncherPath)) { - log.info(String.format("Deleting GraalPy venv due to changed launcher path")); + info(log, "Deleting GraalPy venv due to changed launcher path"); delete(venvDirectory); } break; @@ -297,95 +831,121 @@ private static void checkLauncher(Path venvDirectory, Path launcherPath, Log log throw new IOException(String.format("failed to read config file %s", cfg), e); } } else { - log.info(String.format("missing venv config file: '%s'", cfg)); - } - } - - private static void generateLaunchers(Path laucherPath, LauncherClassPath launcherClassPath, SubprocessLog subprocessLog, Log log) throws IOException { - if (!Files.exists(laucherPath)) { - log.info("Generating GraalPy launchers"); - createParentDirectories(laucherPath); - Path java = Paths.get(System.getProperty("java.home"), "bin", "java"); - String classpath = String.join(File.pathSeparator, launcherClassPath.get()); - if (!IS_WINDOWS) { - var script = String.format(""" - #!/usr/bin/env bash - %s --enable-native-access=ALL-UNNAMED -classpath %s %s --python.Executable="$0" "$@" - """, - java, - String.join(File.pathSeparator, classpath), - GRAALPY_MAIN_CLASS); - try { - Files.writeString(laucherPath, script); - var perms = Files.getPosixFilePermissions(laucherPath); - perms.addAll(List.of(PosixFilePermission.OWNER_EXECUTE, PosixFilePermission.GROUP_EXECUTE, PosixFilePermission.OTHERS_EXECUTE)); - Files.setPosixFilePermissions(laucherPath, perms); - } catch (IOException e) { - throw new IOException(String.format("failed to create launcher %s", laucherPath), e); - } - } else { - // on windows, generate a venv launcher that executes our mvn target - var script = String.format(""" - import os, shutil, struct, venv - from pathlib import Path - vl = os.path.join(venv.__path__[0], 'scripts', 'nt', 'graalpy.exe') - tl = os.path.join(r'%s') - os.makedirs(Path(tl).parent.absolute(), exist_ok=True) - shutil.copy(vl, tl) - cmd = r'%s --enable-native-access=ALL-UNNAMED -classpath "%s" %s' - pyvenvcfg = os.path.join(os.path.dirname(tl), "pyvenv.cfg") - with open(pyvenvcfg, 'w', encoding='utf-8') as f: - f.write('venvlauncher_command = ') - f.write(cmd) - """, - laucherPath, - java, - classpath, - GRAALPY_MAIN_CLASS); - File tmp; - try { - tmp = File.createTempFile("create_launcher", ".py"); - } catch (IOException e) { - throw new IOException("failed to create tmp launcher", e); - } - tmp.deleteOnExit(); - try (var wr = new FileWriter(tmp)) { - wr.write(script); - } catch (IOException e) { - throw new IOException(String.format("failed to write tmp launcher %s", tmp), e); - } + info(log, "Missing venv config file: '%s'", cfg); + } + } - try { - GraalPyRunner.run(classpath, subprocessLog, tmp.getAbsolutePath()); - } catch (InterruptedException e) { - throw new IOException(String.format("failed to run Graalpy launcher"), e); + private static Path ensureLauncher(Launcher launcherArgs, BuildToolLog log) throws IOException { + String externalLauncher = System.getProperty("graalpy.vfs.venvLauncher"); + if (externalLauncher == null || externalLauncher.trim().isEmpty()) { + generateLaunchers(launcherArgs, log); + return launcherArgs.launcherPath; + } else { + return Path.of(externalLauncher); + } + } + + private static boolean checkWinLauncherJavaPath(Path venvCfg, Path java) { + try { + for (String line : Files.readAllLines(venvCfg)) { + if (line.trim().startsWith("venvlauncher_command = " + java)) { + return true; } } + } catch (IOException ignore) { + } + return false; + } + + private static void generateLaunchers(Launcher launcherArgs, BuildToolLog log) throws IOException { + debug(log, "Generating GraalPy launchers"); + createParentDirectories(launcherArgs.launcherPath); + Path java = Paths.get(System.getProperty("java.home"), "bin", "java"); + String classpath = String.join(File.pathSeparator, launcherArgs.computeClassPath()); + String extraJavaOptions = String.join(" ", GraalPyRunner.getExtraJavaOptions()); + if (!IS_WINDOWS) { + // we do not bother checking if it exists and has correct java home, since it is simple + // to regenerate the launcher + var script = String.format(""" + #!/usr/bin/env bash + %s --enable-native-access=ALL-UNNAMED %s -classpath %s %s --python.Executable="$0" "$@" + """, + java, + extraJavaOptions, + String.join(File.pathSeparator, classpath), + GRAALPY_MAIN_CLASS); + try { + Files.writeString(launcherArgs.launcherPath, script); + var perms = Files.getPosixFilePermissions(launcherArgs.launcherPath); + perms.addAll(List.of(PosixFilePermission.OWNER_EXECUTE, PosixFilePermission.GROUP_EXECUTE, PosixFilePermission.OTHERS_EXECUTE)); + Files.setPosixFilePermissions(launcherArgs.launcherPath, perms); + } catch (IOException e) { + throw new IOException(String.format("failed to create launcher %s", launcherArgs.launcherPath), e); + } + } else if (!Files.exists(launcherArgs.launcherPath) || !checkWinLauncherJavaPath(launcherArgs.launcherPath.getParent().resolve("pyenv.cfg"), java)) { + // on windows, generate a venv launcher that executes the java command + var script = String.format(""" + import os, shutil, struct, venv + from pathlib import Path + vl = os.path.join(venv.__path__[0], 'scripts', 'nt', 'graalpy.exe') + tl = os.path.join(r'%s') + os.makedirs(Path(tl).parent.absolute(), exist_ok=True) + shutil.copy(vl, tl) + cmd = r'%s --enable-native-access=ALL-UNNAMED %s -classpath "%s" %s' + pyvenvcfg = os.path.join(os.path.dirname(tl), "pyvenv.cfg") + with open(pyvenvcfg, 'w', encoding='utf-8') as f: + f.write('venvlauncher_command = ') + f.write(cmd) + """, + launcherArgs.launcherPath, + java, + extraJavaOptions, + classpath, + GRAALPY_MAIN_CLASS); + File tmp; + try { + tmp = File.createTempFile("create_launcher", ".py"); + } catch (IOException e) { + throw new IOException("failed to create tmp launcher", e); + } + tmp.deleteOnExit(); + try (var wr = new FileWriter(tmp)) { + wr.write(script); + } catch (IOException e) { + throw new IOException(String.format("failed to write tmp launcher %s", tmp), e); + } + + try { + GraalPyRunner.run(classpath, log, tmp.getAbsolutePath()); + } catch (InterruptedException e) { + throw new IOException("failed to run Graalpy launcher", e); + } } } - private static boolean installWantedPackages(Path venvDirectory, List packages, List installedPackages, SubprocessLog subprocessLog) throws IOException { + private static boolean installWantedPackages(Path venvDirectory, List packages, List installedPackages, BuildToolLog log) throws IOException { Set pkgsToInstall = new HashSet<>(packages); pkgsToInstall.removeAll(installedPackages); if (pkgsToInstall.isEmpty()) { return false; } - runPip(venvDirectory, "install", subprocessLog, pkgsToInstall.toArray(new String[pkgsToInstall.size()])); + runPip(venvDirectory, "install", log, pkgsToInstall.toArray(new String[pkgsToInstall.size()])); return true; } - private static boolean deleteUnwantedPackages(Path venvDirectory, List packages, List installedPackages, SubprocessLog subprocessLog) throws IOException { + private static boolean deleteUnwantedPackages(Path venvDirectory, List packages, List installedPackages, BuildToolLog log) throws IOException { List args = new ArrayList<>(installedPackages); args.removeAll(packages); if (args.isEmpty()) { return false; } args.add(0, "-y"); - runPip(venvDirectory, "uninstall", subprocessLog, args.toArray(new String[args.size()])); + + runPip(venvDirectory, "uninstall", log, args.toArray(new String[args.size()])); return true; } - private static void runLauncher(String launcherPath, SubprocessLog log, String... args) throws IOException { + private static void runLauncher(String launcherPath, BuildToolLog log, String... args) throws IOException { try { GraalPyRunner.runLauncher(launcherPath, log, args); } catch (IOException | InterruptedException e) { @@ -393,7 +953,7 @@ private static void runLauncher(String launcherPath, SubprocessLog log, String.. } } - private static void runPip(Path venvDirectory, String command, SubprocessLog log, String... args) throws IOException { + private static void runPip(Path venvDirectory, String command, BuildToolLog log, String... args) throws IOException { try { GraalPyRunner.runPip(venvDirectory, command, log, args); } catch (IOException | InterruptedException e) { @@ -401,7 +961,7 @@ private static void runPip(Path venvDirectory, String command, SubprocessLog log } } - private static void runVenvBin(Path venvDirectory, String bin, SubprocessLog log, String... args) throws IOException { + private static void runVenvBin(Path venvDirectory, String bin, BuildToolLog log, String... args) throws IOException { try { GraalPyRunner.runVenvBin(venvDirectory, bin, log, args); } catch (IOException | InterruptedException e) { @@ -409,7 +969,7 @@ private static void runVenvBin(Path venvDirectory, String bin, SubprocessLog log } } - public static List trim(List l) { + private static List trim(List l) { Iterator it = l.iterator(); while (it.hasNext()) { String p = it.next(); @@ -419,4 +979,36 @@ public static List trim(List l) { } return l; } + + private static void warning(BuildToolLog log, String txt) { + log.warning(txt); + } + + private static void info(BuildToolLog log, String txt, Object... args) { + if (log.isInfoEnabled()) { + log.info(String.format(txt, args)); + } + } + + private static void lifecycle(BuildToolLog log, String txt, Object... args) { + if (log.isLifecycleEnabled()) { + log.lifecycle(String.format(txt, args)); + } + } + + private static void debug(BuildToolLog log, String txt) { + log.debug(txt); + } + + private static void logDebug(BuildToolLog log, List l, String msg, Object... args) { + if (log.isDebugEnabled()) { + if (msg != null) { + log.debug(String.format(msg, args)); + } + for (String p : l) { + log.debug(" " + p); + } + } + } + } diff --git a/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java b/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java index 7efc01cd3a..cc4bc00384 100644 --- a/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java +++ b/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java @@ -76,10 +76,12 @@ *

      * *

      - * In order to make this work, it is necessary for those embedded resources to have their root - * directory set to /org.graalvm.python.vfs which in python code will be mapped to - * the virtual filesystem mount point, by default /graalpy_vfs. Refer to - * {@link VirtualFileSystem.Builder} documentation for more details. + * In order to make this work, it is necessary for those embedded resources to have a common + * resource root directory. The default value is /org.graalvm.python.vfs, + * however the recommended convention is to use {@code GRAALPY-VFS/{groupId}/{artifactId}}. This + * root directory will then be in python code mapped to the virtual filesystem mount point, + * by default /graalpy_vfs. Refer to + * {@link VirtualFileSystem.Builder#resourceDirectory(String)} documentation for more details. *

      * *

      External Directory

      @@ -198,7 +200,12 @@ private GraalPyResources() { * location *
    • /org.graalvm.python.vfs/src - is set as the python sources location
    • * - *

      + *

      + * When the virtual filesystem is located in other than the default resource directory, + * {@code org.graalvm.python.vfs}, i.e., using Maven or Gradle option {@code resourceDirectory}, + * use {@link #contextBuilder(VirtualFileSystem)} and + * {@link VirtualFileSystem.Builder#resourceDirectory(String)} when building the + * {@link VirtualFileSystem}. * * @return a new {@link Context} instance * @since 24.2.0 @@ -233,6 +240,12 @@ public static Context createContext() { * } * } * + *

      + * When the virtual filesystem is located in other than the default resource directory, + * {@code org.graalvm.python.vfs}, i.e., using Maven or Gradle option {@code resourceDirectory}, + * use {@link #contextBuilder(VirtualFileSystem)} and + * {@link VirtualFileSystem.Builder#resourceDirectory(String)} when building the + * {@link VirtualFileSystem}. * * @see PythonOptions @@ -308,13 +321,14 @@ public static Context.Builder contextBuilder(VirtualFileSystem vfs) { /** * Creates a GraalPy context preconfigured with GraalPy and polyglot Context configuration - * options for use with resources located in a real filesystem. + * options for use with resources located in an external directory in real filesystem. *

      * Following resource paths are preconfigured: *

        - *
      • ${resourcesDirectory}/venv - is set as the python virtual environment + *
      • ${externalResourcesDirectory}/venv - is set as the python virtual + * environment location
      • + *
      • ${externalResourcesDirectory}/src - is set as the python sources * location
      • - *
      • ${resourcesDirectory}/src - is set as the python sources location
      • *
      *

      *

      @@ -342,20 +356,27 @@ public static Context.Builder contextBuilder(VirtualFileSystem vfs) { * /python/venv (python virtual environment) * *

      - * - * @param resourcesDirectory the root directory with GraalPy specific embedding resources + * + *

      + * When Maven or Gradle GraalPy plugin is used to build the virtual environment, it also has to + * be configured to generate the virtual environment into the same directory using the + * {@code } tag in Maven or the {@code externalDirectory} field in Gradle. + *

      + * + * @param externalResourcesDirectory the root directory with GraalPy specific embedding + * resources * @return a new {@link org.graalvm.polyglot.Context.Builder} instance * @since 24.2.0 */ - public static Context.Builder contextBuilder(Path resourcesDirectory) { + public static Context.Builder contextBuilder(Path externalResourcesDirectory) { String execPath; if (VirtualFileSystemImpl.isWindows()) { - execPath = resourcesDirectory.resolve(VirtualFileSystemImpl.VFS_VENV).resolve("Scripts").resolve("python.exe").toAbsolutePath().toString(); + execPath = externalResourcesDirectory.resolve(VirtualFileSystemImpl.VFS_VENV).resolve("Scripts").resolve("python.exe").toAbsolutePath().toString(); } else { - execPath = resourcesDirectory.resolve(VirtualFileSystemImpl.VFS_VENV).resolve("bin").resolve("python").toAbsolutePath().toString(); + execPath = externalResourcesDirectory.resolve(VirtualFileSystemImpl.VFS_VENV).resolve("bin").resolve("python").toAbsolutePath().toString(); } - String srcPath = resourcesDirectory.resolve(VirtualFileSystemImpl.VFS_SRC).toAbsolutePath().toString(); + String srcPath = externalResourcesDirectory.resolve(VirtualFileSystemImpl.VFS_SRC).toAbsolutePath().toString(); return createContextBuilder(). // allow all IO access allowIO(IOAccess.ALL). @@ -398,7 +419,7 @@ private static Context.Builder createContextBuilder() { /** * Determines a native executable path if running in {@link ImageInfo#inImageRuntimeCode()}. *

      - * Example creating a GraalPy context precofigured with an external resource directory + * Example creating a GraalPy context preconfigured with an external resource directory * located next to a native image executable. * *

      @@ -437,8 +458,9 @@ public static Path getNativeExecutablePath() {
            * The structure of the created resource directory will stay the same like the embedded Python
            * resources structure:
            * 
        - *
      • ${resourcesDirectory}/venv - the python virtual environment location
      • - *
      • ${resourcesDirectory}/src - the python sources location
      • + *
      • ${externalResourcesDirectory}/venv - the python virtual environment + * location
      • + *
      • ${externalResourcesDirectory}/src - the python sources location
      • *
      *

      *

      @@ -456,17 +478,17 @@ public static Path getNativeExecutablePath() { *

      * * @param vfs the {@link VirtualFileSystem} from which resources are to be extracted - * @param resourcesDirectory the target directory to extract the resources to + * @param externalResourcesDirectory the target directory to extract the resources to * @throws IOException if resources isn't a directory * @see #contextBuilder(Path) * @see VirtualFileSystem.Builder#resourceLoadingClass(Class) * * @since 24.2.0 */ - public static void extractVirtualFileSystemResources(VirtualFileSystem vfs, Path resourcesDirectory) throws IOException { - if (Files.exists(resourcesDirectory) && !Files.isDirectory(resourcesDirectory)) { - throw new IOException(String.format("%s has to be a directory", resourcesDirectory.toString())); + public static void extractVirtualFileSystemResources(VirtualFileSystem vfs, Path externalResourcesDirectory) throws IOException { + if (Files.exists(externalResourcesDirectory) && !Files.isDirectory(externalResourcesDirectory)) { + throw new IOException(String.format("%s has to be a directory", externalResourcesDirectory.toString())); } - vfs.impl.extractResources(resourcesDirectory); + vfs.impl.extractResources(externalResourcesDirectory); } } diff --git a/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/VirtualFileSystem.java b/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/VirtualFileSystem.java index d6ab34a421..a96a9a47e9 100644 --- a/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/VirtualFileSystem.java +++ b/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/VirtualFileSystem.java @@ -119,10 +119,17 @@ private Builder() { *

      * User scripts, data files, and other resources that should be accessible in Python should * be put into this resource directory, e.g., - * {@code src/main/resources/org.graalvm.python.vfs} for the default value of this option - * and assuming the usual layout of a Maven or Gradle project. + * {@code src/main/resources/org.graalvm.python.vfs/src} where: + *

        + *
      • assuming the usual layout of a Maven or Gradle project then the + * {@code src/main/resources/org.graalvm.python.vfs} prefix is the default value of the + * {@code resourceDirectory} option
      • + *
      • and the following {@code src} directory is the folder used by {@link GraalPyResources + * convention} for Python application files and is configured as the default search path for + * Python module files. + *
      *

      - * When Maven and Gradle GraalPy plugin is used to build the virtual environment, it should + * When Maven or Gradle GraalPy plugin is used to build the virtual environment, it should * be configured to generate the virtual environment into the same directory using the * {@code } tag in Maven or the {@code resourceDirectory} field in * Gradle. diff --git a/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/VirtualFileSystemImpl.java b/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/VirtualFileSystemImpl.java index 9757dc79e2..708277501b 100644 --- a/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/VirtualFileSystemImpl.java +++ b/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/VirtualFileSystemImpl.java @@ -136,6 +136,13 @@ private static String absoluteResourcePath(String... components) { private static final String DEFAULT_VFS_ROOT = "org.graalvm.python.vfs"; + /** + * The current platform. Format has to match with VFSUtils.PLATFORM + */ + public static final String PLATFORM = System.getProperty("os.name") + " " + System.getProperty("os.arch"); + + private static final String KEY_PLATFORM = "platform"; + static final String VFS_VENV = "venv"; static final String VFS_SRC = "src"; @@ -151,6 +158,10 @@ private static String absoluteResourcePath(String... components) { */ private final String vfsRoot; + private String platformVenvPath; + + private String platformSrcPath; + private final VirtualFileSystem.HostIO allowHostIO; /* @@ -293,17 +304,17 @@ private void removeExtractDir() { HostIO allowHostIO, Class resourceLoadingClass, boolean caseInsensitive) { - this.vfsRoot = resourceDirectory == null ? DEFAULT_VFS_ROOT : resourceDirectory; if (resourceLoadingClass != null) { this.resourceLoadingClass = resourceLoadingClass; } else { this.resourceLoadingClass = VirtualFileSystem.class; } - this.caseInsensitive = caseInsensitive; this.mountPoint = mountPoint; - this.mountPointLowerCase = mountPoint.toString().toLowerCase(Locale.ROOT); + this.vfsRoot = resourceDirectory == null ? DEFAULT_VFS_ROOT : resourceDirectory; + this.platformVenvPath = resourcePathToPlatformPath(absoluteResourcePath(vfsRoot, VFS_VENV)); + this.platformSrcPath = resourcePathToPlatformPath(absoluteResourcePath(vfsRoot, VFS_SRC)); fine("VirtualFilesystem %s, allowHostIO: %s, resourceLoadingClass: %s, caseInsensitive: %s, extractOnStartup: %s%s", mountPoint, allowHostIO.toString(), this.resourceLoadingClass.getName(), caseInsensitive, extractOnStartup, extractFilter != null ? "" : ", extractFilter: null"); @@ -362,11 +373,11 @@ static boolean isWindows() { } String vfsSrcPath() { - return resourcePathToPlatformPath(absoluteResourcePath(vfsRoot, VFS_SRC)); + return this.platformSrcPath; } String vfsVenvPath() { - return resourcePathToPlatformPath(absoluteResourcePath(vfsRoot, VFS_VENV)); + return this.platformVenvPath; } /** @@ -440,6 +451,7 @@ private void initEntries() { String srcPath = absoluteResourcePath(vfsRoot, VFS_SRC); String venvPath = absoluteResourcePath(vfsRoot, VFS_VENV); List filelistUrls = getFilelistURLs(filelistPath); + boolean hasNativeFiles = false; for (URL url : filelistUrls) { try (InputStream stream = url.openStream()) { if (stream == null) { @@ -447,23 +459,24 @@ private void initEntries() { return; } BufferedReader br = new BufferedReader(new InputStreamReader(stream)); - String line; + String resourcePath; finest("VFS entries:"); - while ((line = br.readLine()) != null) { - if (line.isBlank()) { + while ((resourcePath = br.readLine()) != null) { + if (resourcePath.isBlank()) { // allow empty lines, some tools insert empty lines when concatenating files continue; } String projPath = absoluteResourcePath(vfsRoot, PROJ_DIR); - if (!projWarning && line.startsWith(projPath)) { + if (!projWarning && resourcePath.startsWith(projPath)) { projWarning = true; - LOGGER.warning(""); - LOGGER.warning(String.format("%s source root was deprecated, use %s instead.", projPath, srcPath)); - LOGGER.warning(""); + extendedWarn(String.format("%s source root was deprecated, use %s instead.", projPath, srcPath)); + } + if (!hasNativeFiles && resourcePath.startsWith(venvPath) && (resourcePath.endsWith(".so") || resourcePath.endsWith(".dylib") || resourcePath.endsWith(".dll"))) { + hasNativeFiles = true; } - String platformPath = resourcePathToPlatformPath(line); + String platformPath = resourcePathToPlatformPath(resourcePath); int i = mountPoint.toString().length(); DirEntry parent = null; do { @@ -495,11 +508,11 @@ private void initEntries() { if (previous instanceof DirEntry) { throw fileDirDuplicateMismatchError(platformPath); } - if (filelistUrls.size() > 1 && !line.startsWith(venvPath) && !line.equals(absFilelistPath)) { + if (filelistUrls.size() > 1 && !resourcePath.startsWith(venvPath) && !resourcePath.equals(absFilelistPath)) { reportFailedMultiVFSCheck(multipleLocationsErrorMessage("There are duplicate entries originating from different virtual " + - "filesystem instances. The duplicate entries path: %s.", line)); + "filesystem instances. The duplicate entries path: %s.", resourcePath)); } - fine(multipleLocationsErrorMessage("Duplicate entries virtual filesystem entries: " + line)); + fine(multipleLocationsErrorMessage("Duplicate entries virtual filesystem entries: " + resourcePath)); } finest(" %s", fileEntry.getResourcePath()); parent.entries.add(fileEntry); @@ -521,6 +534,33 @@ private void initEntries() { if (filelistUrls.size() > 1) { validateMultipleVFSLocations(filelistUrls); } + if (hasNativeFiles) { + checkPlatform(); + } + } + + private void checkPlatform() { + Path contentsPath = mountPoint.resolve("venv").resolve("contents"); + BaseEntry contentsEntry = getEntry(contentsPath); + if (contentsEntry != null) { + assert contentsEntry instanceof FileEntry; + String contents; + try { + contents = new String(((FileEntry) contentsEntry).getData()); + } catch (IOException ex) { + throw new IllegalStateException(String.format("IO error while reading venv contents file'%s'.", contentsPath), ex); + } + for (String line : contents.split("\n")) { + if (line.startsWith(KEY_PLATFORM + "=")) { + String platform = line.substring(KEY_PLATFORM.length() + 1); + if (!platform.equals(PLATFORM)) { + extendedWarn(String.format("Virtual filesystem contains third-party Python packages built for %s, which is not compatible with the current platform %s.", + platform, PLATFORM)); + } + break; + } + } + } } private List getFilelistURLs(String filelistPath) { @@ -1270,6 +1310,14 @@ private static void warn(String msgFormat, Object... args) { } } + private static void extendedWarn(String msgFormat, Object... args) { + if (LOGGER.isLoggable(Level.WARNING)) { + LOGGER.log(Level.WARNING, ""); + LOGGER.log(Level.WARNING, String.format(msgFormat, args)); + LOGGER.log(Level.WARNING, ""); + } + } + private static void fine(String msgFormat, Object... args) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, String.format(msgFormat, args)); diff --git a/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/utils/GraalPyResources.java b/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/utils/GraalPyResources.java deleted file mode 100644 index 63706889ca..0000000000 --- a/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/utils/GraalPyResources.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.graalvm.python.embedding.utils; - -import org.graalvm.polyglot.Context; -import java.io.IOException; -import java.nio.file.Path; - -/** - * @deprecated use {@link org.graalvm.python.embedding.GraalPyResources} instead - */ -@SuppressWarnings("deprecation") -@Deprecated -public final class GraalPyResources { - - private GraalPyResources() { - } - - /** - * @deprecated use {@link org.graalvm.python.embedding.GraalPyResources#createContext()} instead - */ - @Deprecated - public static Context createContext() { - return org.graalvm.python.embedding.GraalPyResources.createContext(); - } - - /** - * @deprecated use {@link org.graalvm.python.embedding.GraalPyResources#contextBuilder()} - * instead - */ - @Deprecated - public static Context.Builder contextBuilder() { - return org.graalvm.python.embedding.GraalPyResources.contextBuilder(); - } - - /** - * @deprecated use - * {@link org.graalvm.python.embedding.GraalPyResources#contextBuilder(org.graalvm.python.embedding.VirtualFileSystem)} - * instead - */ - @Deprecated - public static Context.Builder contextBuilder(VirtualFileSystem vfs) { - return org.graalvm.python.embedding.GraalPyResources.contextBuilder(vfs.delegate); - } - - /** - * @deprecated use {@link org.graalvm.python.embedding.GraalPyResources#contextBuilder(Path)} - * instead - */ - @Deprecated - public static Context.Builder contextBuilder(Path resourcesDirectory) { - return org.graalvm.python.embedding.GraalPyResources.contextBuilder(resourcesDirectory); - } - - /** - * @deprecated use - * {@link org.graalvm.python.embedding.GraalPyResources#getNativeExecutablePath()} - * instead - */ - @Deprecated - public static Path getNativeExecutablePath() { - return org.graalvm.python.embedding.GraalPyResources.getNativeExecutablePath(); - } - - /** - * @deprecated use - * {@link org.graalvm.python.embedding.GraalPyResources#extractVirtualFileSystemResources(org.graalvm.python.embedding.VirtualFileSystem, Path)} - * instead - */ - @Deprecated - public static void extractVirtualFileSystemResources(VirtualFileSystem vfs, Path resourcesDirectory) throws IOException { - org.graalvm.python.embedding.GraalPyResources.extractVirtualFileSystemResources(vfs.delegate, resourcesDirectory); - } -} diff --git a/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/utils/VirtualFileSystem.java b/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/utils/VirtualFileSystem.java deleted file mode 100644 index a64736c9f3..0000000000 --- a/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/utils/VirtualFileSystem.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.graalvm.python.embedding.utils; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.Locale; -import java.util.function.Predicate; - -/** - * @deprecated use {@link org.graalvm.python.embedding.VirtualFileSystem} instead - */ -@Deprecated -public final class VirtualFileSystem implements AutoCloseable { - - final org.graalvm.python.embedding.VirtualFileSystem delegate; - - /** - * @deprecated use {@link org.graalvm.python.embedding.VirtualFileSystem} instead - */ - @Deprecated - public static enum HostIO { - NONE, - READ, - READ_WRITE, - } - - /** - * @deprecated use {@link org.graalvm.python.embedding.VirtualFileSystem.Builder} instead - */ - @Deprecated - public static final class Builder { - - org.graalvm.python.embedding.VirtualFileSystem.Builder delegate; - - private Builder(org.graalvm.python.embedding.VirtualFileSystem.Builder delegate) { - this.delegate = delegate; - } - - /** - * @deprecated use {@link org.graalvm.python.embedding.VirtualFileSystem.Builder} instead - */ - @Deprecated - public Builder caseInsensitive(boolean value) { - delegate = delegate.caseInsensitive(value); - return this; - } - - /** - * @deprecated use {@link org.graalvm.python.embedding.VirtualFileSystem.Builder} instead - */ - @Deprecated - public Builder allowHostIO(HostIO b) { - delegate = delegate.allowHostIO(switch (b) { - case NONE -> org.graalvm.python.embedding.VirtualFileSystem.HostIO.NONE; - case READ -> org.graalvm.python.embedding.VirtualFileSystem.HostIO.READ; - case READ_WRITE -> org.graalvm.python.embedding.VirtualFileSystem.HostIO.READ_WRITE; - }); - return this; - } - - /** - * @deprecated use {@link org.graalvm.python.embedding.VirtualFileSystem.Builder} instead - */ - @Deprecated - public Builder windowsMountPoint(String windowsMountPoint) { - delegate = delegate.windowsMountPoint(windowsMountPoint); - return this; - } - - /** - * @deprecated use {@link org.graalvm.python.embedding.VirtualFileSystem.Builder} instead - */ - @Deprecated - public Builder unixMountPoint(String unixMountPoint) { - delegate = delegate.unixMountPoint(unixMountPoint); - return this; - } - - /** - * @deprecated use {@link org.graalvm.python.embedding.VirtualFileSystem.Builder} instead - */ - @Deprecated - public Builder resourceLoadingClass(Class c) { - delegate = delegate.resourceLoadingClass(c); - return this; - } - - /** - * @deprecated use {@link org.graalvm.python.embedding.VirtualFileSystem.Builder} instead - */ - @Deprecated - public Builder extractFilter(Predicate filter) { - delegate.extractFilter(filter); - return this; - } - - /** - * @deprecated use {@link org.graalvm.python.embedding.VirtualFileSystem.Builder} instead - */ - @Deprecated - public VirtualFileSystem build() { - return new VirtualFileSystem(delegate.build()); - } - } - - private VirtualFileSystem(org.graalvm.python.embedding.VirtualFileSystem delegate) { - this.delegate = delegate; - } - - /** - * @deprecated use {@link org.graalvm.python.embedding.VirtualFileSystem} instead - */ - @Deprecated - public static Builder newBuilder() { - return new Builder(org.graalvm.python.embedding.VirtualFileSystem.newBuilder()); - } - - /** - * @deprecated use {@link org.graalvm.python.embedding.VirtualFileSystem} instead - */ - @Deprecated - public static VirtualFileSystem create() { - return newBuilder().build(); - } - - /** - * @deprecated use {@link org.graalvm.python.embedding.VirtualFileSystem} instead - */ - @Deprecated - public String getMountPoint() { - return delegate.getMountPoint(); - } - - /** - * @deprecated use {@link org.graalvm.python.embedding.VirtualFileSystem} instead - */ - @Override - @Deprecated - public void close() throws IOException { - delegate.close(); - } - - static boolean isWindows() { - return System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("windows"); - } - -} diff --git a/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/GraalPyGradlePlugin.java b/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/GraalPyGradlePlugin.java index f0ff56f0e1..6cf8920df6 100644 --- a/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/GraalPyGradlePlugin.java +++ b/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/GraalPyGradlePlugin.java @@ -41,8 +41,10 @@ package org.graalvm.python; import org.graalvm.python.dsl.GraalPyExtension; +import org.graalvm.python.tasks.AbstractPackagesTask; +import org.graalvm.python.tasks.LockPackagesTask; import org.graalvm.python.tasks.MetaInfTask; -import org.graalvm.python.tasks.ResourcesTask; +import org.graalvm.python.tasks.InstallPackagesTask; import org.graalvm.python.tasks.VFSFilesListTask; import org.gradle.api.GradleException; import org.gradle.api.Plugin; @@ -51,9 +53,14 @@ import org.gradle.api.artifacts.ConfigurationContainer; import org.gradle.api.artifacts.Dependency; import org.gradle.api.artifacts.ExternalModuleDependency; +import org.gradle.api.file.Directory; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.ProjectLayout; +import org.gradle.api.file.RegularFile; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginExtension; import org.gradle.api.provider.Provider; +import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.TaskProvider; import org.gradle.jvm.tasks.Jar; @@ -69,6 +76,7 @@ import static org.graalvm.python.embedding.tools.vfs.VFSUtils.GRAALPY_GROUP_ID; import static org.graalvm.python.embedding.tools.vfs.VFSUtils.VFS_ROOT; +import static org.graalvm.python.embedding.tools.vfs.VFSUtils.VFS_VENV; public abstract class GraalPyGradlePlugin implements Plugin { private static final String LAUNCHER_CONFIGURATION_NAME = "pythonLauncherClasspath"; @@ -84,9 +92,11 @@ public abstract class GraalPyGradlePlugin implements Plugin { private static final String DEFAULT_RESOURCES_DIRECTORY = "generated" + File.separator + "graalpy" + File.separator + "resources"; private static final String DEFAULT_FILESLIST_DIRECTORY = "generated" + File.separator + "graalpy" + File.separator + "fileslist"; private static final String GRAALPY_META_INF_DIRECTORY = "generated" + File.separator + "graalpy" + File.separator + "META-INF"; - private static final String GRAALPY_RESOURCES_TASK = "graalPyResources"; + private static final String GRAALPY_INSTALL_PACKAGES_TASK = "graalPyInstallPackages"; + private static final String GRAALPY_LOCK_PACKAGES_TASK = "graalPyLockPackages"; private static final String GRAALPY_META_INF_TASK_TASK = "graalPyMetaInf"; private static final String GRAALPY_VFS_FILESLIST_TASK = "graalPyVFSFilesList"; + private static final String GRAALPY_LOCK_FILE = "graalpy.lock"; GraalPyExtension extension; Project project; @@ -102,12 +112,15 @@ public void apply(Project project) { var launcherClasspath = createLauncherClasspath(); var javaPluginExtension = project.getExtensions().getByType(JavaPluginExtension.class); - var resourcesTask = registerResourcesTask(project, launcherClasspath, extension); + TaskProvider installPackagesTask = registerInstallPackagesTask(project, launcherClasspath, extension); registerMetaInfTask(extension); - var vfsFilesListTask = registerCreateVfsFilesListTask(resourcesTask, javaPluginExtension, extension); + TaskProvider vfsFilesListTask = registerCreateVfsFilesListTask(installPackagesTask, javaPluginExtension, extension); var mainSourceSet = javaPluginExtension.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME); - mainSourceSet.getResources().srcDir(resourcesTask); + mainSourceSet.getResources().srcDir(installPackagesTask); + + registerLockPackagesTask(project, launcherClasspath, extension); + addDependencies(); project.afterEvaluate(proj -> { @@ -117,11 +130,11 @@ public void apply(Project project) { if (extension.getPythonResourcesDirectory().isPresent() && extension.getExternalDirectory().isPresent()) { throw new GradleException( - "Cannot set both 'externalDirectory' and 'resourcesDirectory' at the same time. " + + "Cannot set both 'externalDirectory' and 'resourceDirectory' at the same time. " + "New property 'externalDirectory' is a replacement for deprecated 'pythonResourcesDirectory'. " + "If you want to deploy the virtual environment into physical filesystem, use 'externalDirectory'. " + "The deployment of the external directory alongside the application is not handled by the GraalPy Maven plugin in such case." + - "If you wish to bundle the virtual filesystem in Java resources, use 'resourcesDirectory'. " + + "If you wish to bundle the virtual filesystem in Java resources, use 'resourcesDirectory'. \n" + "For more details, please refer to https://www.graalvm.org/latest/reference-manual/python/Embedding-Build-Tools. "); } @@ -132,11 +145,11 @@ public void apply(Project project) { // Run the vfsFilesListTask conditionally only if 'externalDirectory' is not set if (!extension.getPythonResourcesDirectory().isPresent() && !extension.getExternalDirectory().isPresent()) { if (!extension.getResourceDirectory().isPresent()) { - proj.getLogger().info(String.format("Virtual filesystem is deployed to default resources directory '%s'. " + + proj.getLogger().warn(String.format("Virtual filesystem is deployed to default resources directory '%s'. " + "This can cause conflicts if used with other Java libraries that also deploy GraalPy virtual filesystem. " + - "Consider adding `resourcesDirectory = \"GRAALPY-VFS/${groupId}/${artifactId}\"` to your build.gradle script " + + "Consider adding `resourceDirectory = \"GRAALPY-VFS/${groupId}/${artifactId}\"` to your build.gradle script " + "(replace the placeholders with values specific to your project), " + - "moving any existing sources from '%s' to '%s', and using VirtualFileSystem$Builder#resourceDirectory." + + "moving any existing sources from '%s' to '%s', and using VirtualFileSystem$Builder#resourceDirectory.\n" + "For more details, please refer to https://www.graalvm.org/latest/reference-manual/python/Embedding-Build-Tools. ", VFS_ROOT, Path.of(VFS_ROOT, "src"), @@ -153,12 +166,12 @@ public void apply(Project project) { * @param resourcesTask the resources task * @return the task provider */ - private TaskProvider registerCreateVfsFilesListTask(TaskProvider resourcesTask, JavaPluginExtension javaPluginExtension, GraalPyExtension extension) { + private TaskProvider registerCreateVfsFilesListTask(TaskProvider installPackagesTask, JavaPluginExtension javaPluginExtension, GraalPyExtension extension) { var srcDirs = javaPluginExtension.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME).getResources().getSrcDirs(); return project.getTasks().register(GRAALPY_VFS_FILESLIST_TASK, VFSFilesListTask.class, t -> { t.setGroup(GRAALPY_GRADLE_PLUGIN_TASK_GROUP); t.getResourceDirectory().set(extension.getResourceDirectory()); - t.getVfsDirectories().from(resourcesTask.flatMap(ResourcesTask::getOutput)); + t.getVfsDirectories().from(installPackagesTask.flatMap(InstallPackagesTask::getOutput)); srcDirs.forEach(t.getVfsDirectories()::from); t.getVfsFilesListOutputDir().convention(project.getLayout().getBuildDirectory().dir(DEFAULT_FILESLIST_DIRECTORY)); }); @@ -182,8 +195,8 @@ private void registerMetaInfTask(GraalPyExtension extension) { * @param launcherClasspath the classpath of the Python launcher * @return the resources task provider */ - private TaskProvider registerResourcesTask(Project project, Configuration launcherClasspath, GraalPyExtension extension) { - return project.getTasks().register(GRAALPY_RESOURCES_TASK, ResourcesTask.class, t -> { + private TaskProvider registerInstallPackagesTask(Project project, Configuration launcherClasspath, GraalPyExtension extension) { + return project.getTasks().register(GRAALPY_INSTALL_PACKAGES_TASK, InstallPackagesTask.class, t -> { t.getLauncherClasspath().from(launcherClasspath); t.getLauncherDirectory().convention(project.getLayout().getBuildDirectory().dir("python-launcher")); t.getPolyglotVersion().convention(extension.getPolyglotVersion().orElse(determineGraalPyDefaultVersion())); @@ -192,22 +205,45 @@ private TaskProvider registerResourcesTask(Project project, Confi t.getLogger().warn("The GraalPy plugin pythonHome configuration setting was deprecated and has no effect anymore.\n" + "For execution in jvm mode, the python language home is always available.\n" + "When building a native executable using GraalVM Native Image, then the full python language home is by default embedded into the native executable.\n" + - "For more details, please refer to the documentation of GraalVM Native Image options IncludeLanguageResources and CopyLanguageResources documentation."); + "For more details, please refer to the documentation of GraalVM Native Image options IncludeLanguageResources and CopyLanguageResources."); } - t.getPackages().set(extension.getPackages()); - - t.getOutput().convention( - extension.getExternalDirectory().orElse( - extension.getPythonResourcesDirectory() - .orElse(project.getLayout().getBuildDirectory().dir(DEFAULT_RESOURCES_DIRECTORY)))); - t.getIncludeVfsRoot().convention(extension.getExternalDirectory().map(d -> false) - .orElse(extension.getPythonResourcesDirectory().map(d -> false).orElse(true))); - t.getResourceDirectory().set(extension.getResourceDirectory()); + registerPackagesTask(project, launcherClasspath, extension, t); + }); + } - t.setGroup(GRAALPY_GRADLE_PLUGIN_TASK_GROUP); + private TaskProvider registerLockPackagesTask(Project project, Configuration launcherClasspath, GraalPyExtension extension) { + return project.getTasks().register(GRAALPY_LOCK_PACKAGES_TASK, LockPackagesTask.class, t -> { + registerPackagesTask(project, launcherClasspath, extension, t); }); } + private void registerPackagesTask(Project project, Configuration launcherClasspath, GraalPyExtension extension, AbstractPackagesTask t) { + ProjectLayout layout = project.getLayout(); + DirectoryProperty buildDirectory = layout.getBuildDirectory(); + Directory projectDirectory = layout.getProjectDirectory(); + + t.getLauncherClasspath().from(launcherClasspath); + t.getLauncherDirectory().convention(buildDirectory.dir("python-launcher")); + t.getPolyglotVersion().convention(extension.getPolyglotVersion().orElse(determineGraalPyDefaultVersion())); + t.getPackages().set(extension.getPackages()); + + DirectoryProperty externalDirectory = extension.getExternalDirectory(); + Directory output = externalDirectory.orElse(extension.getPythonResourcesDirectory().orElse(buildDirectory.dir(DEFAULT_RESOURCES_DIRECTORY))).get(); + t.getOutput().convention(output); + + String vfsRoot = externalDirectory.isPresent() ? "" : extension.getResourceDirectory().getOrElse(VFS_ROOT); + t.getVenvDirectory().set(output.getAsFile().toPath().resolve(vfsRoot).resolve(VFS_VENV).toFile()); + + RegularFile graalPyLockFile = extension.getGraalPyLockFile().orElse(projectDirectory.file(GRAALPY_LOCK_FILE)).get(); + File glfFile = graalPyLockFile.getAsFile(); + if(!glfFile.isAbsolute()) { + graalPyLockFile = projectDirectory.file(glfFile.getPath()); + } + t.getGraalPyLockFile().set(graalPyLockFile); + + t.setGroup(GRAALPY_GRADLE_PLUGIN_TASK_GROUP); + } + private boolean userPythonHome() { return !(extension.getPythonHome().getIncludes().get().size() == 1 && extension.getPythonHome().getExcludes().get().size() == 1 && diff --git a/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/GradleLogger.java b/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/GradleLogger.java index 1612dc9ffa..1a69b77b83 100644 --- a/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/GradleLogger.java +++ b/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/GradleLogger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,10 +40,10 @@ */ package org.graalvm.python; -import org.graalvm.python.embedding.tools.exec.SubprocessLog; +import org.graalvm.python.embedding.tools.exec.BuildToolLog; import org.gradle.api.logging.Logger; -public class GradleLogger implements SubprocessLog { +public class GradleLogger implements BuildToolLog { private Logger logger; private GradleLogger(Logger logger) { @@ -51,23 +51,73 @@ private GradleLogger(Logger logger) { } @Override - public void subProcessOut(CharSequence out) { - logger.lifecycle(out.toString()); + public void subProcessOut(String out) { + logger.info(out.toString()); } @Override - public void subProcessErr(CharSequence err) { + public void subProcessErr(String err) { logger.warn(err.toString()); } @Override - public void log(CharSequence txt) { - logger.lifecycle(txt.toString()); + public void lifecycle(String txt) { + logger.lifecycle(txt); } @Override - public void log(CharSequence txt, Throwable t) { - logger.lifecycle(txt.toString(), t); + public void info(String txt) { + logger.info(txt.toString()); + } + + @Override + public void warning(String txt, Throwable t) { + logger.warn(txt, t); + } + + @Override + public void warning(String txt) { + logger.warn(txt); + } + + @Override + public void error(String txt) { + logger.error(txt); + } + + @Override + public void debug(String txt) { + logger.debug(txt); + } + + @Override + public boolean isDebugEnabled() { + return logger.isDebugEnabled(); + } + + @Override + public boolean isWarningEnabled() { + return logger.isWarnEnabled(); + } + + @Override + public boolean isErrorEnabled() { + return logger.isErrorEnabled(); + } + + @Override + public boolean isInfoEnabled() { + return logger.isInfoEnabled(); + } + + @Override + public boolean isLifecycleEnabled() { + return logger.isLifecycleEnabled(); + } + + @Override + public boolean isSubprocessOutEnabled() { + return logger.isInfoEnabled(); } public static GradleLogger of(Logger logger) { diff --git a/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/dsl/GraalPyExtension.java b/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/dsl/GraalPyExtension.java index 3b54b2bd71..df51d7e99f 100644 --- a/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/dsl/GraalPyExtension.java +++ b/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/dsl/GraalPyExtension.java @@ -43,6 +43,7 @@ import org.gradle.api.Action; import org.gradle.api.Incubating; import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.RegularFileProperty; import org.gradle.api.provider.Property; import org.gradle.api.provider.SetProperty; import org.gradle.api.tasks.Nested; @@ -62,7 +63,7 @@ public interface GraalPyExtension { /** * Optional external directory supposed to be populated with python resources, namely the - * virtual environment in the "venv" subdirectory. Existing files and directories other + * virtual environment in the "venv" subdirectory. Existing files and directories other * than the "venv" subdirectory will not be touched by the plugin and can be maintained manually. * Mutually exclusive with {@link #getResourceDirectory()}. */ @@ -75,6 +76,16 @@ public interface GraalPyExtension { */ Property getResourceDirectory(); + /** + * GraalPy lock file. + * + * If present then used as exclusive input when installing python packages + * for GraalPy usage instead of {@link #getPackages()}. + * + * @see #getPackages() + */ + RegularFileProperty getGraalPyLockFile(); + /** * Experimental property. Allows overriding the default Polyglot and GraalPy version. * This is intended only for testing of new unreleased versions. It is recommended @@ -84,7 +95,10 @@ public interface GraalPyExtension { Property getPolyglotVersion(); /** - * Determines third party python packages to be installed for graalpy usage. + * Determines third party python packages to be installed for GraalPy usage in case + * no GraalPy lock file is provided by {@link #getGraalPyLockFile()}. + * + * @see #getGraalPyLockFile() */ SetProperty getPackages(); diff --git a/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/tasks/ResourcesTask.java b/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/tasks/AbstractPackagesTask.java similarity index 59% rename from graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/tasks/ResourcesTask.java rename to graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/tasks/AbstractPackagesTask.java index 132e3ee43b..de41e89b2a 100644 --- a/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/tasks/ResourcesTask.java +++ b/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/tasks/AbstractPackagesTask.java @@ -40,50 +40,48 @@ */ package org.graalvm.python.tasks; -import org.graalvm.python.GraalPyGradlePlugin; import org.graalvm.python.GradleLogger; import org.graalvm.python.dsl.GraalPyExtension; import org.graalvm.python.embedding.tools.vfs.VFSUtils; +import org.graalvm.python.embedding.tools.vfs.VFSUtils.Launcher; import org.gradle.api.DefaultTask; -import org.gradle.api.GradleException; import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.RegularFileProperty; import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.Property; -import org.gradle.api.tasks.CacheableTask; import org.gradle.api.tasks.Classpath; import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.OutputDirectory; -import org.gradle.api.tasks.TaskAction; +import org.gradle.api.tasks.PathSensitive; +import org.gradle.api.tasks.PathSensitivity; import org.jetbrains.annotations.NotNull; import java.io.File; -import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; import java.util.Set; import java.util.stream.Collectors; import static org.graalvm.python.embedding.tools.vfs.VFSUtils.LAUNCHER_NAME; -import static org.graalvm.python.embedding.tools.vfs.VFSUtils.VFS_ROOT; -import static org.graalvm.python.embedding.tools.vfs.VFSUtils.VFS_VENV; /** - * This task is responsible for setting up the Python launcher and installing the dependencies which - * were requested by the user. This is either done in generated resources folder or in external - * directory provided by the user in {@link GraalPyExtension#getExternalDirectory()}. + * This task is responsible installing the dependencies which were requested by the user. + * This is either done in generated resources folder or in external directory provided by the user + * in {@link GraalPyExtension#getExternalDirectory()}. + * + *

      + * In scope of this task: + *

        + *
      1. The GraalPy launcher is set up.
      2. + *
      3. A python venv is created.
      4. + *
      5. Python packages are installed into the venv.
      6. + *
      + * */ -@CacheableTask -public abstract class ResourcesTask extends DefaultTask { - - /** @see #getOutput() */ - @Input - @Optional - public abstract Property getIncludeVfsRoot(); +public abstract class AbstractPackagesTask extends DefaultTask { @Input public abstract ListProperty getPackages(); @@ -95,21 +93,18 @@ public abstract class ResourcesTask extends DefaultTask { public abstract ConfigurableFileCollection getLauncherClasspath(); /** - * The directory where the virtual filesystem should be generated. If {@link #getIncludeVfsRoot()} is set, - * then this is the parent directory where the actual VFS directory should be created and populated with - * "venv" subdirectory (this is the case when we generate the VFS to Java resources). Otherwise, this path - * is used as is. + * The directory where the virtual filesystem should be generated. */ @OutputDirectory public abstract DirectoryProperty getOutput(); - /** - * The directory where the VFS should be generated within Java resources, i.e., applied only when - * {@link #getIncludeVfsRoot()} is set. - */ - @Input + @InputFiles @Optional - public abstract Property getResourceDirectory(); + @PathSensitive(PathSensitivity.RELATIVE) + public abstract RegularFileProperty getGraalPyLockFile(); + + @Internal + public abstract RegularFileProperty getVenvDirectory(); /** * Desired polyglot runtime and GraalPy version. @@ -117,29 +112,21 @@ public abstract class ResourcesTask extends DefaultTask { @Input public abstract Property getPolyglotVersion(); - @Input - protected String getOperatingSystem() { - return System.getProperty("os.name"); - } - - @TaskAction - public void exec() throws IOException { - Files.createDirectories(computeLauncherDirectory()); - manageVenv(); + protected Set calculateLauncherClasspath() { + return getLauncherClasspath().getFiles().stream().map(File::getAbsolutePath).collect(Collectors.toUnmodifiableSet()); } - private void manageVenv() { - List packages = getPackages().getOrElse(null); - try { - VFSUtils.createVenv(getVenvDirectory(), new ArrayList(packages), getLauncherPath(), this::calculateLauncherClasspath, getPolyglotVersion().get(), - GradleLogger.of(getLogger()), (s) -> getLogger().lifecycle(s)); - } catch (IOException e) { - throw new GradleException(String.format("failed to create venv %s", getVenvDirectory()), e); - } + protected Launcher createLauncher() { + return new Launcher( getLauncherPath()) { + public Set computeClassPath() { + return calculateLauncherClasspath(); + } + }; } - private Set calculateLauncherClasspath() { - return getLauncherClasspath().getFiles().stream().map(File::getAbsolutePath).collect(Collectors.toUnmodifiableSet()); + @Internal + protected GradleLogger getLog() { + return GradleLogger.of(getLogger()); } private Path getLauncherPath() { @@ -147,15 +134,13 @@ private Path getLauncherPath() { } @NotNull - private Path computeLauncherDirectory() { + protected Path computeLauncherDirectory() { return getLauncherDirectory().get().getAsFile().toPath(); } - private Path getVenvDirectory() { - String path = ""; - if (getIncludeVfsRoot().getOrElse(true)) { - path = getResourceDirectory().getOrElse(VFS_ROOT); - } - return Path.of(getOutput().get().getAsFile().toURI()).resolve(path).resolve(VFS_VENV); + @Internal + protected Path getLockFilePath() { + return getGraalPyLockFile().get().getAsFile().toPath(); } + } diff --git a/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/tasks/InstallPackagesTask.java b/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/tasks/InstallPackagesTask.java new file mode 100644 index 0000000000..21da31e2a2 --- /dev/null +++ b/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/tasks/InstallPackagesTask.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.python.tasks; + +import org.graalvm.python.dsl.GraalPyExtension; +import org.gradle.api.GradleException; +import org.gradle.api.tasks.*; + +import java.io.IOException; +import java.nio.file.Path; + +import org.graalvm.python.embedding.tools.vfs.VFSUtils; +import org.graalvm.python.embedding.tools.vfs.VFSUtils.PackagesChangedException; + +/** + * This task is responsible installing the dependencies which were requested by the user. + * This is either done in generated resources folder or in external directory provided by the user + * in {@link GraalPyExtension#getExternalDirectory()}. + * + *

      + * In scope of this task: + *

        + *
      1. The GraalPy launcher is set up.
      2. + *
      3. A python venv is created.
      4. + *
      5. Python packages are installed into the venv.
      6. + *
      + * + */ +@CacheableTask +public abstract class InstallPackagesTask extends AbstractPackagesTask { + + private static final String PACKAGES_CHANGED_ERROR = """ + Install of python packages is based on lock file %s, + but packages and their version constraints in graalpy-gradle-plugin configuration are different then previously used to generate the lock file. + + Packages currently declared in graalpy-gradle-plugin configuration: %s + Packages which were used to generate the lock file: %s + + The lock file has to be refreshed by running the gradle task 'graalPyLockPackages'. + + For more information, please refer to https://www.graalvm.org/latest/reference-manual/python/Embedding-Build-Tools#Python-Dependency-Management + + """; + + protected static final String MISSING_LOCK_FILE_WARNING = """ + + WARNING: The list of installed Python packages does not match the packages specified in the graalpy-maven-plugin configuration. + WARNING: This could indicate that either extra dependencies were installed or some packages were installed with a more specific versions than declared. + + WARNING: In such cases, it is strongly recommended to lock the Python dependencies by executing the Gradle task 'graalPyLockPackages'. + + For more details on managing Python dependencies, please refer to https://www.graalvm.org/latest/reference-manual/python/Embedding-Build-Tools#Python-Dependency-Management + + """; + + @TaskAction + public void exec() throws GradleException { + Path venvDirectory = getVenvDirectory().get().getAsFile().toPath(); + Path lockFilePath = getLockFilePath(); + try { + VFSUtils.createVenv(venvDirectory, getPackages().get(), lockFilePath, MISSING_LOCK_FILE_WARNING, createLauncher(), getPolyglotVersion().get(), getLog()); + } catch(PackagesChangedException pce) { + String pluginPkgsString = pce.getPluginPackages().isEmpty() ? "None" : String.join(", ", pce.getPluginPackages()); + String lockFilePkgsString = pce.getLockFilePackages().isEmpty() ? "None" : String.join(", ", pce.getLockFilePackages()); + throw new GradleException(String.format(PACKAGES_CHANGED_ERROR, lockFilePath, pluginPkgsString, lockFilePkgsString)); + } catch (IOException e) { + throw new GradleException(String.format("failed to create python virtual environment in %s", venvDirectory), e); + } + } +} diff --git a/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/tasks/LockPackagesTask.java b/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/tasks/LockPackagesTask.java new file mode 100644 index 0000000000..064cd8a712 --- /dev/null +++ b/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/tasks/LockPackagesTask.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.python.tasks; + +import org.gradle.api.GradleException; +import org.gradle.api.tasks.UntrackedTask; +import org.gradle.api.tasks.TaskAction; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; + +import org.graalvm.python.embedding.tools.vfs.VFSUtils; + +/** + * Creates a GraalPy lock file from packages declared in plugin configuration. + * + * If there is no virtual environment preset then it is first created and packages are installed the same way + * as in scope of {@link InstallPackagesTask}. + */ +@UntrackedTask(because="manually triggered, should always run") +public abstract class LockPackagesTask extends AbstractPackagesTask { + + protected static final String LOCK_FILE_HEADER = """ + This file was generated by gradle task 'graalPyLockPackages'. + + WARNING: Any manual changes are done at your own risk and will be overwritten when the task is executed. + + This file is meant to be tracked in a version control system. + + This file contains a list of all required Python packages with their specific versions, + based on the packages defined in the plugin configuration and their dependencies. + + """; + + @TaskAction + public void exec() throws GradleException { + checkEmptyPackages(); + + Path venvDirectory = getVenvDirectory().get().getAsFile().toPath(); + try { + VFSUtils.lockPackages(venvDirectory, getPackages().get(), getLockFilePath(), LOCK_FILE_HEADER, createLauncher(), getPolyglotVersion().get(), getLog()); + } catch (IOException e) { + throw new GradleException(String.format("failed to lock packages in python virtual environment %s", venvDirectory), e); + } + } + + private void checkEmptyPackages() throws GradleException { + List packages = getPackages().get(); + if((packages == null || packages.isEmpty())) { + String msg = """ + In order to run the graalPyLockPackages task there have to be python packages declared in the graalpy-gradle-plugin configuration. + + For more information, please refer to https://github.com/oracle/graalpython/blob/master/docs/user/Embedding-Build-Tools.md + """; + throw new GradleException(msg); + } + } +} diff --git a/graalpython/org.graalvm.python.jbang/src/org/graalvm/python/jbang/JBangIntegration.java b/graalpython/org.graalvm.python.jbang/src/org/graalvm/python/jbang/JBangIntegration.java index 17822c07b3..e4605c6b8d 100644 --- a/graalpython/org.graalvm.python.jbang/src/org/graalvm/python/jbang/JBangIntegration.java +++ b/graalpython/org.graalvm.python.jbang/src/org/graalvm/python/jbang/JBangIntegration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -41,8 +41,9 @@ package org.graalvm.python.jbang; -import org.graalvm.python.embedding.tools.exec.SubprocessLog; +import org.graalvm.python.embedding.tools.exec.BuildToolLog; import org.graalvm.python.embedding.tools.vfs.VFSUtils; +import org.graalvm.python.embedding.tools.vfs.VFSUtils.Launcher; import java.io.File; import java.io.IOException; @@ -58,6 +59,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -75,8 +77,70 @@ public class JBangIntegration { private static final boolean IS_WINDOWS = System.getProperty("os.name").startsWith("Windows"); private static final String LAUNCHER = IS_WINDOWS ? "graalpy.exe" : "graalpy.sh"; - private static final SubprocessLog LOG = new SubprocessLog() { + private static final BuildToolLog BUILD_TOOL_LOG = new BuildToolLog() { + private static final boolean debugEnabled = Boolean.getBoolean("org.graalvm.python.jbang.log.debug"); + + @Override + public void subProcessOut(String out) { + System.out.println(out); + } + + @Override + public void subProcessErr(String err) { + System.err.println(err); + } + + @Override + public void info(String s) { + System.out.println(s); + } + + @Override + public void warning(String s) { + System.out.println(s); + } + + @Override + public void warning(String s, Throwable t) { + System.out.println(s); + } + + @Override + public void error(String s) { + System.err.println(s); + } + + @Override + public void debug(String s) { + System.out.println(s); + } + + @Override + public boolean isWarningEnabled() { + return true; + } + + @Override + public boolean isInfoEnabled() { + return true; + } + + @Override + public boolean isErrorEnabled() { + return true; + } + + @Override + public boolean isDebugEnabled() { + return debugEnabled; + } + + @Override + public boolean isSubprocessOutEnabled() { + return true; + } }; + private static final String JBANG_COORDINATES = "org.graalvm.python:jbang:jar"; /** @@ -170,7 +234,13 @@ private static void handleVenv(Path venv, List> dependen // perhaps already checked by jbang throw new IllegalStateException("could not resolve parent for venv path: " + venv); } - VFSUtils.createVenv(venv, pkgs, getLauncherPath(venvParent.toString()), () -> calculateClasspath(dependencies), graalPyVersion, LOG, (txt) -> LOG.log(txt)); + Launcher launcher = new Launcher(getLauncherPath(venvParent.toString())) { + @Override + public Set computeClassPath() { + return calculateClasspath(dependencies); + } + }; + VFSUtils.createVenv(venv, pkgs, launcher, graalPyVersion, BUILD_TOOL_LOG); if (dropPip) { try { @@ -234,6 +304,8 @@ private static HashSet calculateClasspath(List> } private static void log(String txt) { - LOG.log("[graalpy jbang integration] " + txt); + if (BUILD_TOOL_LOG.isInfoEnabled()) { + BUILD_TOOL_LOG.info("[graalpy jbang integration] " + txt); + } } } diff --git a/graalpython/python-libposix/src/posix.c b/graalpython/python-libposix/src/posix.c index 29dc4132c7..64cb005ae9 100644 --- a/graalpython/python-libposix/src/posix.c +++ b/graalpython/python-libposix/src/posix.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -1080,6 +1080,11 @@ int32_t call_ioctl_int(int32_t fd, uint64_t request, int32_t arg) { return ioctl(fd, request, (int)arg); } +int64_t call_sysconf(int32_t name) { + errno = 0; + return sysconf(name); +} + int32_t get_errno() { return errno; } diff --git a/mx.graalpython/copyrights/overrides b/mx.graalpython/copyrights/overrides index 7111d0cbab..bde7793089 100644 --- a/mx.graalpython/copyrights/overrides +++ b/mx.graalpython/copyrights/overrides @@ -324,97 +324,6 @@ graalpython/com.oracle.graal.python.cext/src/unicodectype.c,python.copyright graalpython/com.oracle.graal.python.cext/src/unicodeobject.c,python.copyright graalpython/com.oracle.graal.python.cext/src/unicodetype_db.h,python.copyright graalpython/com.oracle.graal.python.frozen/freeze_modules.py,python.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/autogen_hpyfunc_declare.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/autogen_hpyslot.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpy_types.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/autogen_api_impl.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/autogen_ctx.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/autogen_hpyfunc_trampolines.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/hpyfunc_trampolines.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/cpython/misc.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/forbid_python_h/Python.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpydef.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpyexports.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpyfunc.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpymodule.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/hpytype.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/inline_helpers.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/macros.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/argparse.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/buildvalue.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/ctx_funcs.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/ctx_module.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/ctx_type.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/format.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/helpers.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/runtime/structseq.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/autogen_ctx.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/autogen_hpyfunc_trampolines.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/hpyfunc_trampolines.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/misc_trampolines.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/version.h,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/__init__.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/check_py27_compat.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/conftest.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_builder_invalid.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_context_reuse.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/debug/test_misc.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/hpy_devel/test_abitag.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/hpy_devel/test_distutils.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/support.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_00_basic.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_argparse.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_call.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_capsule.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_capsule_legacy.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_contextvar.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_cpy_compat.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_eval.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_helpers.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpybytes.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpydict.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyerr.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyimport.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpylist.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpylong.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpymodule.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyslice.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpystructseq.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpytuple.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpytype.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpytype_legacy.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_hpyunicode.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_importing.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_legacy_forbidden.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_number.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_object.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_slots.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_slots_legacy.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_support.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_tracker.py,hpy.copyright -graalpython/com.oracle.graal.python.hpy.test/src/hpytest/trace/test_trace.py,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/ctx_tracker.c,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/debug/_debugmod.c,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/debug/autogen_debug_ctx_init.h,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/debug/autogen_debug_wrappers.c,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/debug/debug_ctx.c,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/debug/debug_ctx_not_cpython.c,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/debug/debug_handles.c,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/debug/debug_internal.h,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/debug/dhqueue.c,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/debug/hpy_debug.h,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/debug/include/hpy_debug.h,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/debug/memprotect.c,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/debug/stacktrace.c,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/trace/_tracemod.c,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/trace/autogen_trace_ctx_init.h,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/trace/autogen_trace_func_table.c,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/trace/autogen_trace_wrappers.c,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/trace/hpy_trace.h,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/trace/include/hpy_trace.h,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/trace/trace_ctx.c,hpy.copyright -graalpython/com.oracle.graal.python.jni/src/trace/trace_internal.h,hpy.copyright graalpython/com.oracle.graal.python.pegparser.generator/asdl/asdl.py,python.copyright graalpython/com.oracle.graal.python.pegparser.generator/diff_generator.py,python.copyright graalpython/com.oracle.graal.python.pegparser.generator/pegen/__init__.py,python.copyright @@ -575,7 +484,6 @@ graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3 graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltins.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ArrayModuleBuiltins.java,zippy.copyright -graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CmathModuleBuiltins.java,python.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GcModuleBuiltins.java,zippy.copyright @@ -647,8 +555,8 @@ graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/PSequenceIterator.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/PStringIterator.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/PZip.java,zippy.copyright -graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/PZipBuiltins.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/SentinelIteratorBuiltins.java,zippy.copyright +graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/ZipBuiltins.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/list/ListBuiltins.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/list/PList.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java,zippy.copyright @@ -689,16 +597,12 @@ graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/R graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/ReadVarKeywordsNode.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ImportStarNode.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/RaiseNode.java,zippy.copyright -graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallDispatchNode.java,zippy.copyright -graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/InvokeNode.java,zippy.copyright -graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryComparisonNode.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/BinaryOpNode.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/UnaryOpNode.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadGlobalOrBuiltinNode.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/BuiltinFunctionRootNode.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/PythonBuiltinNode.java,zippy.copyright -graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/truffle/PythonArithmeticTypes.java,zippy.copyright -graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/truffle/PythonTypes.java,zippy.copyright +graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/truffle/PythonIntegerTypes.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonOptions.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/exception/PythonErrorType.java,zippy.copyright @@ -708,7 +612,7 @@ graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatti graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/InternalFormat.java,jython.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/StringFormatProcessor.java,jython.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/TextFormatter.java,jython.copyright -graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PythonObjectFactory.java,zippy.copyright +graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PFactory.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/PSequence.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/BoolSequenceStorage.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/ByteSequenceStorage.java,zippy.copyright @@ -720,31 +624,6 @@ graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/SequenceStorage.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/SequenceStorageFactory.java,zippy.copyright graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/SequenceStoreException.java,zippy.copyright -graalpython/lib-graalpython/modules/hpy/debug/__init__.py,hpy.copyright -graalpython/lib-graalpython/modules/hpy/debug/leakdetector.py,hpy.copyright -graalpython/lib-graalpython/modules/hpy/debug/pytest.py,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/__init__.py,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/abitag.py,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/argparse.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_bytes.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_call.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_capsule.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_contextvar.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_err.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_eval.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_listbuilder.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_long.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_module.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_object.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_tracker.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_tuple.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_tuplebuilder.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/ctx_type.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/format.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/helpers.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/src/runtime/structseq.c,hpy.copyright -graalpython/lib-graalpython/modules/hpy/devel/version.py,hpy.copyright -graalpython/lib-graalpython/modules/hpy/trace/__init__.py,hpy.copyright graalpython/python-libposix/src/fork_exec.c,python.copyright graalpython/python-venvlauncher/src/venvlauncher.c,python.copyright mx.graalpython/mx_graalpython.py,zippy.copyright diff --git a/mx.graalpython/eclipse-settings/org.eclipse.jdt.core.prefs b/mx.graalpython/eclipse-settings/org.eclipse.jdt.core.prefs index 7d85ef6a1e..1e928980c3 100644 --- a/mx.graalpython/eclipse-settings/org.eclipse.jdt.core.prefs +++ b/mx.graalpython/eclipse-settings/org.eclipse.jdt.core.prefs @@ -1,2 +1,2 @@ org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore diff --git a/mx.graalpython/env_files.md b/mx.graalpython/env_files.md new file mode 100644 index 0000000000..7bb92f7f2f --- /dev/null +++ b/mx.graalpython/env_files.md @@ -0,0 +1,11 @@ +Here is how the various env files relate to each other: +* `jvm` + * `jvm-ce`: + GraalVM Community Compiler + * `jvm-ce-libgraal`: + libgraal + * `native-ce`: + libpythonvm + `Truffle Macro` + * `jvm-ee`: + Oracle GraalVM Compiler + `Truffle enterprise` + license + `LLVM Runtime Native Enterprise` + * `jvm-ee-libgraal`: + libgraal + * `native-ee`: + libpythonvm + `Truffle Macro Enterprise` + Native Image G1 + * `native-ee-aux`: + `AuxiliaryEngineCache`, - Native Image G1 (currently incompatible) + +They all build the GraalPy standalone and nothing else to optimize build time. diff --git a/mx.graalpython/graalpython-svm-standalone b/mx.graalpython/graalpython-svm-standalone deleted file mode 100644 index a1b92094a6..0000000000 --- a/mx.graalpython/graalpython-svm-standalone +++ /dev/null @@ -1,6 +0,0 @@ -# The lightest configuration that allows building PYTHON_NATIVE_STANDALONE_SVM_JAVA21. -# For example: mx --dy /vm build --dep PYTHON_NATIVE_STANDALONE_SVM_JAVA21 -DYNAMIC_IMPORTS=/compiler,/regex,/sdk,/substratevm,/sulong,/tools,/truffle,graalpython -COMPONENTS=antlr4,cmp,cov,dap,dis,gu,gvm,icu4j,xz,ins,insight,insightheap,lg,llp,llrc,llrl,llrn,lsp,nfi-libffi,pbm,pmh,poly,polynative,pro,pyn,pynl,rgx,sdk,sdkl,tfl,tfla,tflc,tflm,truffle-json -NATIVE_IMAGES=lib:pythonvm -DISABLE_INSTALLABLES=False diff --git a/mx.graalpython/jvm b/mx.graalpython/jvm new file mode 100644 index 0000000000..a5372c6504 --- /dev/null +++ b/mx.graalpython/jvm @@ -0,0 +1,3 @@ +DYNAMIC_IMPORTS=/tools +BUILD_TARGETS=GRAALPY_JVM_STANDALONE +EXCLUDE_TRUFFLE_RUNTIME=true diff --git a/mx.graalpython/jvm-ce b/mx.graalpython/jvm-ce new file mode 100644 index 0000000000..14ccce3576 --- /dev/null +++ b/mx.graalpython/jvm-ce @@ -0,0 +1,2 @@ +DYNAMIC_IMPORTS=/tools,/compiler +BUILD_TARGETS=GRAALPY_JVM_STANDALONE diff --git a/mx.graalpython/jvm-ce-libgraal b/mx.graalpython/jvm-ce-libgraal new file mode 100644 index 0000000000..4c95daec3f --- /dev/null +++ b/mx.graalpython/jvm-ce-libgraal @@ -0,0 +1,5 @@ +DYNAMIC_IMPORTS=/tools,/compiler,/substratevm +BUILD_TARGETS=GRAALPY_JVM_STANDALONE +COMPONENTS=LibGraal +NATIVE_IMAGES=lib:jvmcicompiler +GRAALVM_SKIP_ARCHIVE=true diff --git a/mx.graalpython/jvm-ee b/mx.graalpython/jvm-ee new file mode 100644 index 0000000000..28f9637b0c --- /dev/null +++ b/mx.graalpython/jvm-ee @@ -0,0 +1,2 @@ +DYNAMIC_IMPORTS=/tools,/graal-enterprise,/truffle-enterprise,/vm-enterprise +BUILD_TARGETS=GRAALPY_JVM_STANDALONE diff --git a/mx.graalpython/jvm-ee-libgraal b/mx.graalpython/jvm-ee-libgraal new file mode 100644 index 0000000000..9853c22406 --- /dev/null +++ b/mx.graalpython/jvm-ee-libgraal @@ -0,0 +1,5 @@ +DYNAMIC_IMPORTS=/tools,/graal-enterprise,/truffle-enterprise,/vm-enterprise,/substratevm-enterprise +BUILD_TARGETS=GRAALPY_JVM_STANDALONE +COMPONENTS=LibGraal Enterprise +NATIVE_IMAGES=lib:jvmcicompiler +GRAALVM_SKIP_ARCHIVE=true diff --git a/mx.graalpython/live_heap_tracker.py b/mx.graalpython/live_heap_tracker.py new file mode 100644 index 0000000000..ad99b581b3 --- /dev/null +++ b/mx.graalpython/live_heap_tracker.py @@ -0,0 +1,75 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import sys +import time + +import re +import subprocess + +TOTAL_RE = re.compile(r'^Total +\d+ +(\d+)', re.MULTILINE) + + +def main(): + output_file = sys.argv[1] + iterations = int(sys.argv[2]) + jmap_binary = sys.argv[3] + benchmark = sys.argv[4:] + with open(output_file, 'w') as f: + for _ in range(iterations): + proc = subprocess.Popen(benchmark) + while proc.poll() is None: + time.sleep(0.3) + try: + jmap_output = subprocess.check_output( + [jmap_binary, '-histo:live', str(proc.pid)], + universal_newlines=True, + stderr=subprocess.DEVNULL, + ) + if match := TOTAL_RE.search(jmap_output): + heap_bytes = int(match.group(1)) + f.write(f'{heap_bytes}\n') + except subprocess.CalledProcessError: + pass + if proc.returncode != 0: + sys.exit(proc.returncode) + + +if __name__ == '__main__': + main() diff --git a/mx.graalpython/mx_graalpython.py b/mx.graalpython/mx_graalpython.py index 7f98cfa7e3..cc18bd0c5c 100644 --- a/mx.graalpython/mx_graalpython.py +++ b/mx.graalpython/mx_graalpython.py @@ -41,6 +41,7 @@ from pathlib import Path from textwrap import dedent +import mx_graalpython_benchmark import mx_graalpython_gradleproject import mx_urlrewrites @@ -55,12 +56,12 @@ import mx import mx_util -import mx_benchmark import mx_gate import mx_native import mx_unittest import mx_sdk import mx_subst +import mx_truffle import mx_graalpython_bisect import mx_graalpython_import import mx_graalpython_python_benchmarks @@ -71,18 +72,11 @@ from mx_graalpython_gradleproject import GradlePluginProject #pylint: disable=unused-import from mx_gate import Task -from mx_graalpython_bench_param import PATH_MESO, BENCHMARKS, WARMUP_BENCHMARKS, JAVA_DRIVER_BENCHMARKS -from mx_graalpython_benchmark import PythonBenchmarkSuite, python_vm_registry, CPythonVm, PyPyVm, JythonVm, \ - GraalPythonVm, \ - CONFIGURATION_DEFAULT, CONFIGURATION_SANDBOXED, CONFIGURATION_NATIVE, \ - CONFIGURATION_DEFAULT_MULTI, CONFIGURATION_SANDBOXED_MULTI, CONFIGURATION_NATIVE_MULTI, \ - CONFIGURATION_DEFAULT_MULTI_TIER, CONFIGURATION_NATIVE_MULTI_TIER, \ - PythonVmWarmupBenchmarkSuite, \ - CONFIGURATION_INTERPRETER, CONFIGURATION_INTERPRETER_MULTI, CONFIGURATION_NATIVE_INTERPRETER, \ - CONFIGURATION_NATIVE_INTERPRETER_MULTI, PythonJavaEmbeddingBenchmarkSuite, python_java_embedding_vm_registry, \ - GraalPythonJavaDriverVm, CONFIGURATION_JAVA_EMBEDDING_INTERPRETER_MULTI_SHARED, \ - CONFIGURATION_JAVA_EMBEDDING_INTERPRETER_MULTI, CONFIGURATION_JAVA_EMBEDDING_MULTI_SHARED, \ - CONFIGURATION_JAVA_EMBEDDING_MULTI, CONFIGURATION_PANAMA, PythonJMHDistMxBenchmarkSuite +from mx_graalpython_bench_param import PATH_MESO + + +# re-export custom mx project classes, so they can be used from suite.py +from mx_sdk_vm_ng import StandaloneLicenses, ThinLauncherProject, LanguageLibraryProject, DynamicPOMDistribution, DeliverableStandaloneArchive # pylint: disable=unused-import if not sys.modules.get("__main__"): # workaround for pdb++ @@ -100,23 +94,25 @@ def get_boolean_env(name, default=False): SUITE_COMPILER = mx.suite("compiler", fatalIfMissing=False) GRAAL_VERSION = SUITE.suiteDict['version'] +IS_RELEASE = SUITE.suiteDict['release'] GRAAL_VERSION_MAJ_MIN = ".".join(GRAAL_VERSION.split(".")[:2]) PYTHON_VERSION = SUITE.suiteDict[f'{SUITE.name}:pythonVersion'] PYTHON_VERSION_MAJ_MIN = ".".join(PYTHON_VERSION.split('.')[:2]) +LATEST_JAVA_HOME = {"JAVA_HOME": os.environ.get("LATEST_JAVA_HOME", mx.get_jdk().home)} +RUNNING_ON_LATEST_JAVA = os.environ.get("LATEST_JAVA_HOME", os.environ.get("JAVA_HOME")) == mx.get_jdk().home + + # this environment variable is used by some of our maven projects and jbang integration to build against the unreleased master version during development os.environ["GRAALPY_VERSION"] = GRAAL_VERSION MAIN_BRANCH = 'master' -HPY_IMPORT_ORPHAN_BRANCH_NAME = "hpy-import" GRAALPYTHON_MAIN_CLASS = "com.oracle.graal.python.shell.GraalPythonMain" SANDBOXED_OPTIONS = [ '--experimental-options', - '--python.UseSystemToolchain=false', # Use the Sulong toolchain - '--python.NativeModules=false', # Load extensions with Sulong '--python.PosixModuleBackend=java', '--python.Sha3ModuleBackend=java', ] @@ -130,6 +126,21 @@ def get_boolean_env(name, default=False): CI = get_boolean_env("CI") WIN32 = sys.platform == "win32" BUILD_NATIVE_IMAGE_WITH_ASSERTIONS = get_boolean_env('BUILD_WITH_ASSERTIONS', CI) +BYTECODE_DSL_INTERPRETER = get_boolean_env('BYTECODE_DSL_INTERPRETER', False) + +mx_gate.add_jacoco_excludes([ + "com.oracle.graal.python.pegparser.sst", + "com.oracle.graal.python.pegparser.test", + "com.oracle.truffle.api.staticobject.test", + "com.oracle.truffle.regex.tregex.test", + "com.oracle.truffle.tck", + "com.oracle.truffle.tools.chromeinspector.test", + "com.oracle.truffle.tools.coverage.test", + "com.oracle.truffle.tools.dap.test", + "com.oracle.truffle.tools.profiler.test", + "org.graalvm.tools.insight.test", + "org.graalvm.tools.lsp.test", +]) if CI and not os.environ.get("GRAALPYTEST_FAIL_FAST"): os.environ["GRAALPYTEST_FAIL_FAST"] = "true" @@ -170,6 +181,8 @@ def getArchivableResultsWithLib(self, *args, **kwargs): if os.path.isfile(os.path.join(os.path.abspath(p), "cl.exe")): mx.log("LIB and INCLUDE set, cl.exe on PATH, assuming this is a VS shell") os.environ["DISTUTILS_USE_SDK"] = "1" + if not os.environ.get("MSSdk"): + os.environ["MSSdk"] = os.environ.get("WindowsSdkDir", "unset") break else: mx.log("cl.exe not on PATH, not a VS shell") @@ -191,9 +204,6 @@ def _get_capi_home(args=None): return os.path.join(mx.distribution("GRAALPYTHON_NATIVE_LIBS").get_output(), mx.get_os(), mx.get_arch()) -_get_jni_home = _get_capi_home - - def _extract_graalpython_internal_options(args): non_internal = [] additional_dists = [] @@ -233,6 +243,13 @@ def get_jdk(): return mx.get_jdk() +# Called from suite.py +def graalpy_standalone_deps(): + include_truffle_runtime = not os.environ.get("EXCLUDE_TRUFFLE_RUNTIME") + deps = mx_truffle.resolve_truffle_dist_names(use_optimized_runtime=include_truffle_runtime) + return deps + + def full_python(args, env=None): """Run python from standalone build (unless kwargs are given). Does not build GraalPython sources automatically.""" @@ -268,7 +285,7 @@ def full_python(args, env=None): "To build it: mx python-jvm\n" + "Alternatively use: mx python --hosted") - mx.run([graalpy_path] + args, env=env) + run([graalpy_path] + args, env=env) def handle_debug_arg(args): @@ -286,17 +303,10 @@ def python(args, **kwargs): def do_run_python(args, extra_vm_args=None, env=None, jdk=None, extra_dists=None, cp_prefix=None, cp_suffix=None, main_class=GRAALPYTHON_MAIN_CLASS, minimal=False, **kwargs): - experimental_opt_added = False if not any(arg.startswith("--python.CAPI") for arg in args): capi_home = _get_capi_home() args.insert(0, "--python.CAPI=%s" % capi_home) args.insert(0, "--experimental-options") - experimental_opt_added = True - - if not any(arg.startswith("--python.JNIHome") for arg in args): - args.insert(0, "--python.JNIHome=" + _get_jni_home()) - if not experimental_opt_added: - args.insert(0, "--experimental-options") if not env: env = os.environ.copy() @@ -321,7 +331,7 @@ def do_run_python(args, extra_vm_args=None, env=None, jdk=None, extra_dists=None cp_prefix = ver_dep if cp_prefix is None else (ver_dep + os.pathsep + cp_prefix) else: dists = ['GRAALPYTHON'] - dists += ['TRUFFLE_NFI', 'SULONG_NATIVE', 'GRAALPYTHON-LAUNCHER'] + dists += ['TRUFFLE_NFI', 'TRUFFLE_NFI_LIBFFI', 'GRAALPYTHON-LAUNCHER'] vm_args, graalpython_args = mx.extract_VM_args(args, useDoubleDash=True, defaultAllVMArgs=False) if minimal: @@ -361,7 +371,7 @@ def do_run_python(args, extra_vm_args=None, env=None, jdk=None, extra_dists=None def node_footprint_analyzer(args, **kwargs): main_class = 'com.oracle.graal.python.test.advanced.NodeFootprintAnalyzer' - vm_args = mx.get_runtime_jvm_args(['GRAALPYTHON_UNIT_TESTS', 'GRAALPYTHON', 'TRUFFLE_NFI', 'SULONG_NATIVE']) + vm_args = mx.get_runtime_jvm_args(['GRAALPYTHON_UNIT_TESTS', 'GRAALPYTHON', 'TRUFFLE_NFI', 'TRUFFLE_NFI_LIBFFI']) return mx.run_java(vm_args + [main_class] + args, **kwargs) @@ -374,12 +384,36 @@ def _dev_pythonhome(): return os.path.join(SUITE.dir, "graalpython") +def get_path_with_patchelf(): + path = os.environ.get("PATH", "") + if mx.is_linux() and not shutil.which("patchelf"): + venv = Path(SUITE.get_output_root()).absolute() / "patchelf-venv" + path += os.pathsep + str(venv / "bin") + if not shutil.which("patchelf", path=path): + mx.log(f"{time.strftime('[%H:%M:%S] ')} Building patchelf-venv with {sys.executable}... [patchelf not found on PATH]") + t0 = time.time() + subprocess.check_call([sys.executable, "-m", "venv", str(venv)]) + subprocess.check_call([str(venv / "bin" / "pip"), "install", "patchelf"]) + mx.log(f"{time.strftime('[%H:%M:%S] ')} Building patchelf-venv with {sys.executable}... [duration: {time.time() - t0}]") + if mx.is_windows() and not shutil.which("delvewheel"): + venv = Path(SUITE.get_output_root()).absolute() / "delvewheel-venv" + path += os.pathsep + str(venv / "Scripts") + if not shutil.which("delvewheel", path=path): + mx.log(f"{time.strftime('[%H:%M:%S] ')} Building delvewheel-venv with {sys.executable}... [delvewheel not found on PATH]") + t0 = time.time() + subprocess.check_call([sys.executable, "-m", "venv", str(venv)]) + subprocess.check_call([str(venv / "Scripts" / "pip.exe"), "install", "delvewheel"]) + mx.log(f"{time.strftime('[%H:%M:%S] ')} Building delvewheel-venv with {sys.executable}... [duration: {time.time() - t0}]") + return path + + def punittest(ars, report=False): """ Runs GraalPython junit tests and memory leak tests, which can be skipped using --no-leak-tests. Pass --regex to further filter the junit and TSK tests. GraalPy tests are always run in two configurations: with language home on filesystem and with language home served from the Truffle resources. """ + path = get_path_with_patchelf() args = [] if ars is None else ars @dataclass class TestConfig: @@ -400,6 +434,9 @@ def __str__(self): vm_args = ['-Dpolyglot.engine.WarnInterpreterOnly=false'] + if BYTECODE_DSL_INTERPRETER: + vm_args.append("-Dpython.EnableBytecodeDSLInterpreter=true") + # Note: we must use filters instead of --regex so that mx correctly processes the unit test configs, # but it is OK to apply --regex on top of the filters graalpy_tests = ['com.oracle.graal.python.test', 'com.oracle.graal.python.pegparser.test', 'org.graalvm.python.embedding.test'] @@ -418,11 +455,14 @@ def __str__(self): if '--regex' not in args: async_regex = ['--regex', r'com\.oracle\.graal\.python\.test\.integration\.advanced\.AsyncActionThreadingTest'] configs.append(TestConfig("async", vm_args + ['-Dpython.AutomaticAsyncActions=false', 'com.oracle.graal.python.test', 'org.graalvm.python.embedding.test'] + async_regex + args, True, False)) + else: + skip_leak_tests = True for c in configs: mx.log(f"Python JUnit tests configuration: {c}") PythonMxUnittestConfig.useResources = c.useResources - mx_unittest.unittest(c.args, test_report_tags=({"task": f"punittest-{c.identifier}-{'w' if c.useResources else 'wo'}-resources"} if c.reportConfig else None)) + with set_env(PATH=path): + mx_unittest.unittest(c.args, test_report_tags=({"task": f"punittest-{c.identifier}-{'w' if c.useResources else 'wo'}-resources"} if c.reportConfig else None)) if skip_leak_tests: return @@ -450,8 +490,6 @@ def __str__(self): "python-liblzma", "python-libzsupport", "python-libposix", - "com.oracle.graal.python.hpy.llvm", - "com.oracle.graal.python.jni", "com.oracle.graal.python.cext"] @@ -465,16 +503,6 @@ def nativeclean(args): mx.clean(["--dependencies", ",".join(PYTHON_NATIVE_PROJECTS + PYTHON_ARCHIVES)]) -def python3_unittests(args): - """run the cPython stdlib unittests""" - mx.run([sys.executable, "graalpython/com.oracle.graal.python.test/src/python_unittests.py", "-v"] + args) - - -def compare_unittests(args): - """compare the output of two runs of the cPython stdlib unittests""" - mx.run([sys.executable, "graalpython/com.oracle.graal.python.test/src/compare_unittests.py", "-v"] + args) - - class GraalPythonTags(object): junit = 'python-junit' junit_maven = 'python-junit-maven' @@ -492,6 +520,7 @@ class GraalPythonTags(object): unittest_gradle_plugin_long_run = 'python-unittest-gradle-plugin-long-run' unittest_maven_plugin = 'python-unittest-maven-plugin' unittest_maven_plugin_long_run = 'python-unittest-maven-plugin-long-run' + junit_vfsutils = 'python-junit-vfsutils' tagged = 'python-tagged-unittest' svmunit = 'python-svm-unittest' svmunit_sandboxed = 'python-svm-unittest-sandboxed' @@ -535,7 +564,7 @@ def find_eclipse(): for f in os.listdir(pardir)]: if os.path.basename(f) == "eclipse" and os.path.isdir(f): mx.log("Automatically choosing %s for Eclipse" % f) - eclipse_exe = os.path.join(f, "eclipse") + eclipse_exe = os.path.join(f, f"eclipse{'.exe' if mx.is_windows() else ''}") if os.path.exists(eclipse_exe): os.environ["ECLIPSE_EXE"] = eclipse_exe return @@ -563,6 +592,7 @@ def _graalpy_launcher(): return f"{name}.exe" if WIN32 else name +# dev means Default TruffleRuntime and "build the minimum possible" def graalpy_standalone_home(standalone_type, enterprise=False, dev=False, build=True): assert standalone_type in ['native', 'jvm'] assert not (enterprise and dev), "EE dev standalones are not implemented yet" @@ -570,7 +600,7 @@ def graalpy_standalone_home(standalone_type, enterprise=False, dev=False, build= # Check if GRAALPY_HOME points to some compatible pre-built GraalPy standalone python_home = os.environ.get("GRAALPY_HOME", None) - if python_home and "*" in python_home: + if python_home: python_home = os.path.abspath(glob.glob(python_home)[0]) mx.log("Using GraalPy standalone from GRAALPY_HOME: " + python_home) # Try to verify that we're getting what we expect: @@ -592,50 +622,47 @@ def graalpy_standalone_home(standalone_type, enterprise=False, dev=False, build= launcher = os.path.join(python_home, 'bin', _graalpy_launcher()) out = mx.OutputCapture() - import_ee_status = mx.run([launcher, "-c", "import sys; assert 'Oracle GraalVM' in sys.version"], nonZeroIsFatal=False, out=out, err=out) - if enterprise != (import_ee_status == 0): - mx.abort(f"GRAALPY_HOME is not compatible with requested distribution kind ({import_ee_status=}, {enterprise=}, {out=}).") + mx.run([launcher, "-c", "print(__graalpython__.is_bytecode_dsl_interpreter)"], nonZeroIsFatal=False, out=out, err=out) + is_bytecode_dsl_interpreter = out.data.strip() == "True" + if is_bytecode_dsl_interpreter != BYTECODE_DSL_INTERPRETER: + requested = "Bytecode DSL" if BYTECODE_DSL_INTERPRETER else "Manual" + actual = "Bytecode DSL" if is_bytecode_dsl_interpreter else "Manual" + mx.abort(f"GRAALPY_HOME is not compatible with requested interpreter kind ({requested=}, {actual=})") + return python_home - env_file = 'ce-python' - vm_suite_path = os.path.join(mx.suite('truffle').dir, '..', 'vm') - svm_component = '_SVM' - if enterprise: - env_file = 'ee-python' - enterprise_suite = mx.suite('graal-enterprise', fatalIfMissing=False) - enterprise_suite_dir = enterprise_suite.dir if enterprise_suite else os.path.join(SUITE.dir, '..', 'graal-enterprise', 'graal-enterprise') - vm_suite_path = os.path.join(enterprise_suite_dir, '..', 'vm-enterprise') - svm_component = '_SVM_SVMEE' - if dev: - if standalone_type == 'jvm': - svm_component = '' - mx_args = ['--dy', '/vm'] + # Build + if standalone_type == 'jvm': + if dev: + env_file = 'jvm' else: - dev_env_file = os.path.join(os.path.abspath(SUITE.dir), 'mx.graalpython/graalpython-svm-standalone') - mx_args = ['-p', vm_suite_path, '--env', dev_env_file] + env_file = 'jvm-ee-libgraal' if enterprise else 'jvm-ce-libgraal' + standalone_dist = 'GRAALPY_JVM_STANDALONE' + if "GraalVM" in subprocess.check_output([get_jdk().java, '-version'], stderr=subprocess.STDOUT, universal_newlines=True): + env_file = "" else: - mx_args = ['-p', vm_suite_path, '--env', env_file] + env_file = 'native-ee' if enterprise else 'native-ce' + standalone_dist = 'GRAALPY_NATIVE_STANDALONE' + mx_args = ['-p', SUITE.dir, *(['--env', env_file] if env_file else [])] mx_args.append("--extra-image-builder-argument=-g") - if BUILD_NATIVE_IMAGE_WITH_ASSERTIONS: mx_args.append("--extra-image-builder-argument=-ea") if mx_gate.get_jacoco_agent_args() or (build and not DISABLE_REBUILD): - dep_type = 'JAVA' if standalone_type == 'jvm' else 'NATIVE' - # Example of a string we're building here: PYTHON_JAVA_STANDALONE_SVM_SVMEE_JAVA21 - mx.run_mx(mx_args + ["build", "--dep", f"PYTHON_{dep_type}_STANDALONE{svm_component}_JAVA{jdk_version.parts[0]}"]) + mx_build_args = mx_args + if BYTECODE_DSL_INTERPRETER: + mx_build_args = mx_args + ["--extra-image-builder-argument=-Dpython.EnableBytecodeDSLInterpreter=true"] + # This build is purposefully done without the LATEST_JAVA_HOME in the + # environment, so we can build JVM standalones on an older Graal JDK + run_mx(mx_build_args + ["build", "--target", standalone_dist]) + + python_home = os.path.join(SUITE.dir, 'mxbuild', f"{mx.get_os()}-{mx.get_arch()}", standalone_dist) - out = mx.OutputCapture() - # note: 'quiet=True' is important otherwise if the outer MX runs verbose, - # this might fail because of additional output - mx.run_mx(mx_args + ["standalone-home", "--type", standalone_type, "python"], out=out, quiet=True) - python_home = out.data.splitlines()[-1].strip() if dev and standalone_type == 'native': - path = Path(python_home) - debuginfo = path / '../../libpythonvm.so.image/libpythonvm.so.debug' - if debuginfo.exists(): - shutil.copy(debuginfo, path / 'lib') + debuginfo = os.path.join(SUITE.dir, 'mxbuild', f"{mx.get_os()}-{mx.get_arch()}", "libpythonvm", "libpythonvm.so.debug") + if os.path.exists(debuginfo): + shutil.copy(debuginfo, os.path.join(python_home, 'lib')) return python_home @@ -669,11 +696,13 @@ def graalvm_jdk(): # Check if GRAAL_JDK_HOME points to some compatible pre-built gvm graal_jdk_home = os.environ.get("GRAAL_JDK_HOME", None) - if graal_jdk_home and "*" in graal_jdk_home: + if graal_jdk_home: graal_jdk_home = os.path.abspath(glob.glob(graal_jdk_home)[0]) if sys.platform == "darwin": - graal_jdk_home = os.path.join(graal_jdk_home, 'Contents', 'Home') - mx.log("Using GraalPy standalone from GRAAL_JDK_HOME: " + graal_jdk_home) + jdk_home_subdir = os.path.join(graal_jdk_home, 'Contents', 'Home') + if os.path.exists(jdk_home_subdir): + graal_jdk_home = jdk_home_subdir + mx.log("Using Graal from GRAAL_JDK_HOME: " + graal_jdk_home) # Try to verify that we're getting what we expect: has_java = os.path.exists(os.path.join(graal_jdk_home, 'bin', mx.exe_suffix('java'))) @@ -685,14 +714,11 @@ def graalvm_jdk(): mx.abort(f"No 'release' file in GRAAL_JDK_HOME.") java_version = None - implementor = None with open(release, 'r') as f: - while not (java_version and implementor): + while not java_version: line = f.readline() if 'JAVA_VERSION=' in line: java_version = line - if 'IMPLEMENTOR=' in line: - implementor = line if not java_version: mx.abort(f"Could not check Java version in GRAAL_JDK_HOME 'release' file.") @@ -701,18 +727,14 @@ def graalvm_jdk(): mx.abort(f"GRAAL_JDK_HOME is not compatible with the requested JDK version.\n" f"actual version: '{actual_jdk_version}', version string: {java_version}, requested version: {jdk_version}.") - if not implementor: - mx.abort(f"Could not check implementor in GRAAL_JDK_HOME 'release' file.") - if 'GraalVM' not in implementor: - mx.abort(f"GRAAL_JDK_HOME 'releases' has an unexpected implementor: '{implementor}'.") return graal_jdk_home jdk_major_version = mx.get_jdk().version.parts[0] mx_args = ['-p', os.path.join(mx.suite('truffle').dir, '..', 'vm'), '--env', 'ce'] if not DISABLE_REBUILD: - mx.run_mx(mx_args + ["build", "--dep", f"GRAALVM_COMMUNITY_JAVA{jdk_major_version}"]) + run_mx(mx_args + ["build", "--dep", f"GRAALVM_COMMUNITY_JAVA{jdk_major_version}"], env={**os.environ, **LATEST_JAVA_HOME}) out = mx.OutputCapture() - mx.run_mx(mx_args + ["graalvm-home"], out=out) + run_mx(mx_args + ["graalvm-home"], out=out) return out.data.splitlines()[-1].strip() def get_maven_cache(): @@ -730,15 +752,23 @@ def deploy_local_maven_repo(): env['MAVEN_OPTS'] = maven_opts mx.log(f'Added {mvn_repo_local} to MAVEN_OPTS={maven_opts}') + run_mx_args = [ + '-p', + os.path.join(mx.suite('truffle').dir, '..', 'vm'), + '--dy', + 'graalpython', + ] + if not DISABLE_REBUILD: # build GraalPy and all the necessary dependencies, so that we can deploy them - mx.run_mx(["-p", os.path.join(mx.suite('truffle').dir, '..', 'vm'), "--dy", "graalpython", "build"], env=env) + run_mx(run_mx_args + ["build"], env={**env, **LATEST_JAVA_HOME}) # deploy maven artifacts version = GRAAL_VERSION path = os.path.join(SUITE.get_mx_output_dir(), 'public-maven-repo') licenses = ['EPL-2.0', 'PSF-License', 'GPLv2-CPE', 'ICU,GPLv2', 'BSD-simplified', 'BSD-new', 'UPL', 'MIT'] - deploy_args = [ + deploy_args = run_mx_args + [ + 'maven-deploy', '--tags=public', '--all-suites', '--all-distribution-types', @@ -753,11 +783,7 @@ def deploy_local_maven_repo(): if not DISABLE_REBUILD: mx.rmtree(path, ignore_errors=True) os.mkdir(path) - if m2_cache: - with set_env(MAVEN_OPTS = maven_opts): - mx.maven_deploy(deploy_args) - else: - mx.maven_deploy(deploy_args) + run_mx(deploy_args, env={**env, **LATEST_JAVA_HOME}) return path, version, env @@ -828,22 +854,6 @@ def python_svm(_=None): return launcher -def native_image(args): - mx.run_mx([ - "-p", os.path.join(mx.suite("truffle").dir, "..", "substratevm"), - "--dy", "graalpython", - "--native-images=", - "build", - ]) - mx.run_mx([ - "-p", os.path.join(mx.suite("truffle").dir, "..", "substratevm"), - "--dy", "graalpython", - "--native-images=", - "native-image", - *args - ]) - - def _python_test_runner(): return os.path.join(SUITE.dir, "graalpython", "com.oracle.graal.python.test", "src", "runner.py") @@ -851,13 +861,6 @@ def _python_unittest_root(): return os.path.join(SUITE.dir, "graalpython", "com.oracle.graal.python.test", "src", "tests") -# name of the project containing the HPy tests -HPY_TEST_PROJECT = "com.oracle.graal.python.hpy.test" - -def _hpy_test_root(): - return os.path.join(mx.dependency(HPY_TEST_PROJECT).get_output_root(), "bin", "hpytest") - - def graalpytest(args): # help is delegated to the runner, it will fake the mx-specific options as well parser = ArgumentParser(prog='mx graalpytest', add_help=False) @@ -873,7 +876,7 @@ def graalpytest(args): python_args = [] runner_args = [] for arg in unknown_args: - if arg.startswith(('--python.', '--engine.', '--llvm.', '--vm.', '--inspect', '--log.', '--experimental-options')): + if arg.startswith(('--python.', '--engine.', '--vm.', '--inspect', '--log.', '--experimental-options')): python_args.append(arg) else: runner_args.append(arg) @@ -890,6 +893,9 @@ def graalpytest(args): gp_args = ["--vm.ea", "--vm.esa", "--experimental-options=true", "--python.EnableDebuggingBuiltins"] mx.log(f"Executable seems to be GraalPy, prepending arguments: {gp_args}") python_args += gp_args + if is_graalpy and BYTECODE_DSL_INTERPRETER: + python_args.insert(0, "--vm.Dpython.EnableBytecodeDSLInterpreter=true") + runner_args.append(f'--subprocess-args={shlex.join(python_args)}') cmd_args = [*python_args, _python_test_runner(), 'run', *runner_args] delete_bad_env_keys(env) @@ -898,7 +904,12 @@ def graalpytest(args): pythonpath += [p for p in env.get('PYTHONPATH', '').split(os.pathsep) if p] env['PYTHONPATH'] = os.pathsep.join(pythonpath) if python_binary: - return mx.run([python_binary, *cmd_args], nonZeroIsFatal=True, env=env) + try: + result = run([python_binary, *cmd_args], nonZeroIsFatal=True, env=env) + print(f"back from mx.run, returning {result}") + return result + except BaseException as e: + print(f"Exception raised: {e}") else: return full_python(cmd_args, env=env) @@ -947,6 +958,8 @@ def run_python_unittests(python_binary, args=None, paths=None, exclude=None, env # Windows machines don't seem to have much memory parallel = min(parallel, 2) + parallelism = str(min(os.cpu_count(), parallel)) + args = args or [] args = [ "--vm.ea", @@ -962,21 +975,9 @@ def run_python_unittests(python_binary, args=None, paths=None, exclude=None, env if mx.primary_suite() != SUITE: env.setdefault("GRAALPYTEST_ALLOW_NO_JAVA_ASSERTIONS", "true") - # just to be able to verify, print C ext mode (also works for CPython) - mx.run( - [ - python_binary, - *args, - "-c", - "import sys; print('C EXT MODE: ' + (__graalpython__.ext_mode if sys.implementation.name == 'graalpy' else 'cpython'))", - ], - nonZeroIsFatal=True, env=env, out=out, err=err, - ) - - if use_pytest: - args += ["-m", "pytest", "-v", "--assert=plain", "--tb=native"] - else: - args += [_python_test_runner(), "run", "--durations", "10", "-n", str(min(os.cpu_count(), parallel)), f"--subprocess-args={shlex.join(args)}"] + if BYTECODE_DSL_INTERPRETER: + args += ['--vm.Dpython.EnableBytecodeDSLInterpreter=true'] + args += [_python_test_runner(), "run", "--durations", "10", "-n", parallelism, f"--subprocess-args={shlex.join(args)}"] if runner_args: args += runner_args @@ -986,17 +987,15 @@ def run_python_unittests(python_binary, args=None, paths=None, exclude=None, env args += ['--ignore', file] if is_collecting_coverage() and mx_gate.get_jacoco_agent_args(): - if not use_pytest: - # jacoco only dumps the data on exit, and when we run all our unittests - # at once it generates so much data we run out of heap space - args.append('--separate-workers') + # jacoco only dumps the data on exit, and when we run all our unittests + # at once it generates so much data we run out of heap space + args.append('--separate-workers') if report: reportfile = None t0 = time.time() - if not use_pytest: - reportfile = os.path.abspath(tempfile.mktemp(prefix="test-report-", suffix=".json")) - args += ["--mx-report", reportfile] + reportfile = os.path.abspath(tempfile.mktemp(prefix="test-report-", suffix=".json")) + args += ["--mx-report", reportfile] if paths is not None: args += paths @@ -1006,7 +1005,7 @@ def run_python_unittests(python_binary, args=None, paths=None, exclude=None, env mx.logv(shlex.join([python_binary] + args)) if lock: lock.release() - result = mx.run([python_binary] + args, nonZeroIsFatal=nonZeroIsFatal, env=env, cwd=cwd, out=out, err=err, timeout=timeout) + result = run([python_binary] + args, nonZeroIsFatal=nonZeroIsFatal, env=env, cwd=cwd, out=out, err=err, timeout=timeout) if lock: lock.acquire() @@ -1024,93 +1023,15 @@ def run_python_unittests(python_binary, args=None, paths=None, exclude=None, env return result -def run_hpy_unittests(python_binary, args=None, include_native=True, env=None, nonZeroIsFatal=True, timeout=None, report=False): - args = [] if args is None else args - mx.command_function("build")(["--dep", HPY_TEST_PROJECT]) - with tempfile.TemporaryDirectory(prefix='hpy-test-site-') as d: - env = env or os.environ.copy() - prefix = str(d) - env.update(PYTHONUSERBASE=prefix) - delete_bad_env_keys(env) - mx.run_mx(["build", "--dependencies", "LLVM_TOOLCHAIN"]) - env.update(LLVM_TOOLCHAIN_VANILLA=mx_subst.path_substitutions.substitute('/bin')) - mx.log("LLVM Toolchain (vanilla): {!s}".format(env["LLVM_TOOLCHAIN_VANILLA"])) - mx.run([python_binary] + args + ["-m", "ensurepip", "--user"], - nonZeroIsFatal=nonZeroIsFatal, env=env, timeout=timeout) - mx.run([python_binary] + args + ["-m", "pip", "install", "--user", "pytest<=6.2.3", "pytest-xdist", "filelock"], - nonZeroIsFatal=nonZeroIsFatal, env=env, timeout=timeout) - if not is_collecting_coverage(): - global DISABLE_REBUILD - DISABLE_REBUILD = True - # parallelize - import threading - threads = [] - lock = threading.RLock() - - class HPyUnitTestsThread(threading.Thread): - def __init__(self, **tkwargs): - super().__init__(**tkwargs) - self.out = mx.LinesOutputCapture() - self.result = None - - def run(self): - # Note: for some reason catching BaseException is not enough to catch mx.abort, - # so we use nonZeroIsFatal=False instead. - try: - self.result = run_python_unittests(python_binary, args=args, paths=[_hpy_test_root()], - env=tenv, use_pytest=True, lock=lock, nonZeroIsFatal=False, - out=self.out, err=self.out, timeout=timeout, report=report) - self.out.lines.append(f"Thread {self.name} finished with result {self.result}") - except BaseException as e: # pylint: disable=broad-except; - self.out.lines.append(f"Thread {self.name} finished with exception {e}") - self.result = e - else: - threads = [] - class HPyUnitTestsThread: - def __init__(self, name): - self.name = name - self.out = mx.LinesOutputCapture() - - def start(self): - self.result = run_python_unittests(python_binary, args=args, paths=[_hpy_test_root()], - env=tenv, use_pytest=True, nonZeroIsFatal=nonZeroIsFatal, - timeout=timeout, report=report) - print(f"Thread {self.name} finished with result {self.result}") - - def join(self, *args, **kwargs): - return - - def is_alive(self): - return False - - abi_list = ['cpython', 'universal'] - if include_native: - # modes 'debug' and 'nfi' can only be used if native access is allowed - abi_list.append('debug') - for abi in abi_list: - tenv = env.copy() - tenv["TEST_HPY_ABI"] = abi - thread = HPyUnitTestsThread(name=abi) - threads.append(thread) - thread.start() - - alive = [True] * len(threads) - while any(alive): - for i, t in enumerate(threads): - t.join(timeout=1.0) - mx.logv("## Progress (last 5 lines) of thread %r:\n%s\n" % (t.name, os.linesep.join(t.out.lines[-5:]))) - alive[i] = t.is_alive() - - failed_threads = [t for t in threads if t.result != 0] - for t in threads: - mx.log("\n\n### Output of thread %r: \n\n%s" % (t.name, t.out)) - if any(failed_threads): - threads_info = [f"{t.name} (result: {t.result})" for t in failed_threads] - message = "HPy testing threads failed: " + ', '.join(threads_info) - if nonZeroIsFatal: - mx.abort("ERROR: " + message) - else: - mx.warn(message) +def run_hpy_unittests(python_binary, args=None, env=None, nonZeroIsFatal=True, timeout=None, report=False): + t0 = time.time() + result = downstream_test_hpy(python_binary, args=args, env=env, nonZeroIsFatal=nonZeroIsFatal, timeout=timeout) + if report: + mx_gate.make_test_report([{ + "name": report.title, + "status": "PASSED" if result == 0 else "FAILED", + "duration": int((time.time() - t0) * 1000) + }], report.title) def run_tagged_unittests(python_binary, env=None, cwd=None, nonZeroIsFatal=True, checkIfWithGraalPythonEE=False, @@ -1162,6 +1083,9 @@ def setup_graalpy_plugin_tests(): env['JAVA_HOME'] = gvm_jdk env['PYTHON_STANDALONE_HOME'] = standalone_home + env['GRAAL_VERSION'] = GRAAL_VERSION + if not IS_RELEASE: + env['GRAAL_VERSION'] += '-dev' # setup maven downloader overrides env['MAVEN_REPO_OVERRIDE'] = ",".join([ @@ -1203,13 +1127,14 @@ def graalpython_gate_runner(args, tasks): # JUnit tests with Task('GraalPython JUnit', tasks, tags=[GraalPythonTags.junit]) as task: if task: + run_mx(["build"], env={**os.environ, **LATEST_JAVA_HOME}) if WIN32: punittest( [ "--verbose", "--no-leak-tests", "--regex", - r'((graal\.python\.test\.integration)|(graal\.python\.test\.(builtin|interop|util)))' + r'((graal\.python\.test\.integration)|(graal\.python\.test\.(builtin|interop|util))|(org\.graalvm\.python\.embedding\.(test|test\.integration)))' ], report=True ) @@ -1253,6 +1178,8 @@ def graalpython_gate_runner(args, tasks): f'-Dcom.oracle.graal.python.test.central_repo={central_override}', '--batch-mode'] + env['PATH'] = get_path_with_patchelf() + mx.log("Running integration JUnit tests on GraalVM SDK") env['JAVA_HOME'] = graalvm_jdk() mx.run_maven(mvn_cmd_base + ['-U', 'clean', 'test'], env=env) @@ -1275,7 +1202,7 @@ def graalpython_gate_runner(args, tasks): if task: env = extend_os_env(PYTHONHASHSEED='0') test_args = [get_cpython(), _python_test_runner(), "run", "-n", "6", "graalpython/com.oracle.graal.python.test/src/tests"] - mx.run(test_args, nonZeroIsFatal=True, env=env) + run(test_args, nonZeroIsFatal=True, env=env) with Task('GraalPython sandboxed tests', tasks, tags=[GraalPythonTags.unittest_sandboxed]) as task: if task: @@ -1299,7 +1226,7 @@ def graalpython_gate_runner(args, tasks): with Task('GraalPython HPy sandboxed tests', tasks, tags=[GraalPythonTags.unittest_hpy_sandboxed]) as task: if task: - run_hpy_unittests(graalpy_standalone_native_enterprise(), args=SANDBOXED_OPTIONS, include_native=False, report=report()) + run_hpy_unittests(graalpy_standalone_native_enterprise(), args=SANDBOXED_OPTIONS, report=report()) with Task('GraalPython posix module tests', tasks, tags=[GraalPythonTags.unittest_posix]) as task: if task: @@ -1314,7 +1241,10 @@ def graalpython_gate_runner(args, tasks): standalone_home = graalpy_standalone_home('jvm') mvn_repo_path, version, env = deploy_local_maven_repo() - env['ENABLE_STANDALONE_UNITTESTS'] = 'true' + if RUNNING_ON_LATEST_JAVA: + # our standalone python binary is meant for standalone graalpy + # releases which are only for latest + env['ENABLE_STANDALONE_UNITTESTS'] = 'true' env['ENABLE_JBANG_INTEGRATION_UNITTESTS'] ='true' env['JAVA_HOME'] = gvm_jdk env['PYTHON_STANDALONE_HOME'] = standalone_home @@ -1389,7 +1319,7 @@ def graalpython_gate_runner(args, tasks): parallel=3, ) - with Task('GraalPython maven plugin long runnning tests', tasks, tags=[GraalPythonTags.unittest_maven_plugin_long_run]) as task: + with Task('GraalPython maven plugin long running tests', tasks, tags=[GraalPythonTags.unittest_maven_plugin_long_run]) as task: if task: standalone_home, env = setup_maven_plugin_tests() env['ENABLE_MAVEN_PLUGIN_LONG_RUNNING_UNITTESTS'] = 'true' @@ -1404,6 +1334,13 @@ def graalpython_gate_runner(args, tasks): parallel=3, ) + with Task('GraalPython VFSUtils long running tests', tasks, tags=[GraalPythonTags.junit_vfsutils]) as task: + if task: + run_mx(["build"], env={**os.environ, **LATEST_JAVA_HOME}) + args =['--verbose'] + vm_args = ['-Dpolyglot.engine.WarnInterpreterOnly=false'] + mx_unittest.unittest(vm_args + ['org.graalvm.python.embedding.vfs.test'] + args + ["--use-graalvm"]) + with Task('GraalPython Python tests', tasks, tags=[GraalPythonTags.tagged]) as task: if task: # don't fail this task if we're running with the jacoco agent, we know that some tests don't pass with it enabled @@ -1428,7 +1365,7 @@ def graalpython_gate_runner(args, tasks): svm_image = python_svm() benchmark = os.path.join(PATH_MESO, "image-magix.py") out = mx.OutputCapture() - mx.run([svm_image, "-S", "--log.python.level=FINE", benchmark], nonZeroIsFatal=True, out=mx.TeeOutputCapture(out), err=mx.TeeOutputCapture(out)) + run([svm_image, "-S", "--log.python.level=FINE", benchmark], nonZeroIsFatal=True, out=mx.TeeOutputCapture(out), err=mx.TeeOutputCapture(out)) success = "\n".join([ "[0, 0, 0, 0, 0, 0, 10, 10, 10, 0, 0, 10, 3, 10, 0, 0, 10, 10, 10, 0, 0, 0, 0, 0, 0]", ]) @@ -1439,13 +1376,13 @@ def graalpython_gate_runner(args, tasks): with Task('Python SVM Truffle TCK', tasks, tags=[GraalPythonTags.language_checker], report=True) as task: if task: - mx.run_mx([ + run_mx([ "--dy", "graalpython,/substratevm", "-p", os.path.join(mx.suite("truffle"), "..", "vm"), "--native-images=", "build", - ]) - mx.run_mx([ + ], env={**os.environ, **LATEST_JAVA_HOME}) + run_mx([ "--dy", "graalpython,/substratevm", "-p", os.path.join(mx.suite("truffle"), "..", "vm"), "--native-images=", @@ -1460,108 +1397,29 @@ def graalpython_gate_runner(args, tasks): mx.log("TIP: run 'mx help tox-example' to learn more about reproducing this test locally") raise - - with Task('Python exclusion of security relevant classes', tasks, tags=[GraalPythonTags.exclusions_checker]) as task: - if task: - native_image([ - "--language:python", - "-Dpython.WithoutSSL=true", - "-Dpython.WithoutPlatformAccess=true", - "-Dpython.WithoutCompressionLibraries=true", - "-Dpython.WithoutNativePosix=true", - "-Dpython.WithoutJavaInet=true", - "-Dimage-build-time.PreinitializeContexts=", - "-Dtruffle.TruffleRuntime=com.oracle.truffle.api.impl.DefaultTruffleRuntime", - "-H:+ReportExceptionStackTraces", - *map( - lambda s: f"-H:ReportAnalysisForbiddenType={s}", - """ - com.sun.security.auth.UnixNumericGroupPrincipal - com.sun.security.auth.module.UnixSystem - java.security.KeyManagementException - java.security.KeyStore - java.security.KeyStoreException - java.security.SignatureException - java.security.UnrecoverableEntryException - java.security.UnrecoverableKeyException - java.security.cert.CRL - java.security.cert.CRLException - java.security.cert.CertPathBuilder - java.security.cert.CertPathBuilderSpi - java.security.cert.CertPathChecker - java.security.cert.CertPathParameters - java.security.cert.CertSelector - java.security.cert.CertStore - java.security.cert.CertStoreParameters - java.security.cert.CertStoreSpi - java.security.cert.CertificateEncodingException - java.security.cert.CertificateParsingException - java.security.cert.CollectionCertStoreParameters - java.security.cert.Extension - java.security.cert.PKIXBuilderParameters - java.security.cert.PKIXCertPathChecker - java.security.cert.PKIXParameters - java.security.cert.PKIXRevocationChecker - java.security.cert.PKIXRevocationChecker$Option - java.security.cert.TrustAnchor - java.security.cert.X509CRL - java.security.cert.X509CertSelector - java.security.cert.X509Certificate - java.security.cert.X509Extension - sun.security.x509.AVA - sun.security.x509.AVAComparator - sun.security.x509.AVAKeyword - sun.security.x509.AuthorityInfoAccessExtension - sun.security.x509.AuthorityKeyIdentifierExtension - sun.security.x509.BasicConstraintsExtension - sun.security.x509.CRLDistributionPointsExtension - sun.security.x509.CertAttrSet - sun.security.x509.CertificatePoliciesExtension - sun.security.x509.CertificatePolicySet - sun.security.x509.DNSName - sun.security.x509.EDIPartyName - sun.security.x509.ExtendedKeyUsageExtension - sun.security.x509.Extension - sun.security.x509.GeneralName - sun.security.x509.GeneralNameInterface - sun.security.x509.GeneralSubtree - sun.security.x509.GeneralSubtrees - sun.security.x509.IPAddressName - sun.security.x509.IssuerAlternativeNameExtension - sun.security.x509.KeyUsageExtension - sun.security.x509.NameConstraintsExtension - sun.security.x509.NetscapeCertTypeExtension - sun.security.x509.OIDMap - sun.security.x509.OIDMap$OIDInfo - sun.security.x509.OIDName - sun.security.x509.OtherName - sun.security.x509.PKIXExtensions - sun.security.x509.PrivateKeyUsageExtension - sun.security.x509.RDN - sun.security.x509.RFC822Name - sun.security.x509.SubjectAlternativeNameExtension - sun.security.x509.SubjectKeyIdentifierExtension - sun.security.x509.URIName - sun.security.x509.X400Address - sun.security.x509.X500Name - - com.oracle.graal.python.runtime.NFIPosixSupport - - java.util.zip.Adler32 - - org.graalvm.shadowed.org.tukaani.xz.XZ - org.graalvm.shadowed.org.tukaani.xz.XZOutputStream - org.graalvm.shadowed.org.tukaani.xz.LZMA2Options - org.graalvm.shadowed.org.tukaani.xz.FilterOptions - - java.util.zip.ZipInputStream - - java.nio.channels.ServerSocketChannel - """.split() - ), - "-cp", mx.dependency("com.oracle.graal.python.test").classpath_repr(), - "com.oracle.graal.python.test.advanced.ExclusionsTest" - ]) + if WIN32 and is_collecting_coverage(): + mx.log("Ask for shutdown of any remaining graalpy.exe processes") + # On windows, the jacoco command can fail if the file is still locked + # by lingering test processes, so we try to give it a bit of a cleanup + mx.run([ + 'taskkill.exe', + '/T', # with children + '/IM', + 'graalpy.exe', + ], nonZeroIsFatal=False) + time.sleep(2) + mx.log("Forcefully terminate any remaining graalpy.exe processes") + mx.run([ + 'taskkill.exe', + '/F', # force + '/T', # with children + '/IM', + 'graalpy.exe', + ], nonZeroIsFatal=False) + # Forcefully killing processes on Windows does not release file + # locks immediately, so we still need to sleep for a bit in the + # hopes that the OS will release + time.sleep(8) mx_gate.add_gate_runner(SUITE, graalpython_gate_runner) @@ -1762,9 +1620,12 @@ def _get_src_dir(projectname): def _get_output_root(projectname): + prefix, _, suffix = projectname.rpartition(":") for suite in mx.suites(): - for p in suite.projects: - if p.name == projectname: + if prefix and suite.name != prefix: + continue + for p in itertools.chain(suite.projects, suite.dists): + if p.name == suffix: return p.get_output_root() mx.abort("Could not find out dir for project %s" % projectname) @@ -1800,6 +1661,8 @@ def graal_version_short(variant=None, **kwargs): for i in range(3): num <<= 8 num |= int(parts[i]) if i < len(parts) else 0 + num <<= 8 + num |= release_level('int') << 4 return hex(num) else: return '.'.join(GRAAL_VERSION.split('.')[:3]) @@ -1810,20 +1673,20 @@ def release_level(variant=None): level = 'alpha' if SUITE.suiteDict['release']: level = 'final' - if variant == 'binary': + if variant in ('binary', 'int'): level_num = { 'alpha': 0xA, 'beta': 0xB, 'candidate': 0xC, 'final': 0xF, }[level] - return chr(level_num + ord(VERSION_BASE)) + if variant == 'binary': + return chr(level_num + ord(VERSION_BASE)) + return level_num return level -def graalpy_ext(llvm_mode, **kwargs): - if not llvm_mode: - mx.abort("substitution 'graalpy_ext' is missing argument 'llvm_mode'") +def graalpy_ext(*args, **kwargs): os = mx_subst.path_substitutions.substitute('') arch = mx_subst.path_substitutions.substitute('') if arch == 'amd64': @@ -1839,7 +1702,7 @@ def graalpy_ext(llvm_mode, **kwargs): # on Windows we use '.pyd' else '.so' but never '.dylib' (similar to CPython): # https://github.com/python/cpython/issues/37510 ext = 'pyd' if os == 'windows' else 'so' - return f'.graalpy{GRAAL_VERSION_MAJ_MIN.replace(".", "") + dev_tag()}-{PYTHON_VERSION_MAJ_MIN.replace(".", "")}-{llvm_mode}-{arch}-{pyos}.{ext}' + return f'.graalpy{GRAAL_VERSION_MAJ_MIN.replace(".", "") + dev_tag()}-{PYTHON_VERSION_MAJ_MIN.replace(".", "")}-native-{arch}-{pyos}.{ext}' def dev_tag(arg=None, **kwargs): @@ -1874,8 +1737,8 @@ def dev_tag(arg=None, **kwargs): mx_subst.path_substitutions.register_with_arg('release_level', release_level) mx_subst.results_substitutions.register_with_arg('dev_tag', dev_tag) -mx_subst.path_substitutions.register_with_arg('graalpy_ext', graalpy_ext) -mx_subst.results_substitutions.register_with_arg('graalpy_ext', graalpy_ext) +mx_subst.path_substitutions.register_no_arg('graalpy_ext', graalpy_ext) +mx_subst.results_substitutions.register_no_arg('graalpy_ext', graalpy_ext) def update_import(name, suite_py, args): @@ -2001,7 +1864,7 @@ def update_import_cmd(args): join(overlaydir, "python", "graal", "ci"), dirs_exist_ok=True) - mx.run_mx(['--dynamicimports', '/graal-enterprise', 'checkout-downstream', 'compiler', 'graal-enterprise']) + run_mx(['--dynamicimports', '/graal-enterprise', 'checkout-downstream', 'compiler', 'graal-enterprise']) enterprisedir = join(SUITE.dir, "..", "graal-enterprise") shutil.copy( join(enterprisedir, "common.json"), @@ -2018,9 +1881,9 @@ def update_import_cmd(args): for repo in repos: basename = os.path.basename(repo) cmdname = "%s-update-import" % basename - is_mx_command = mx.run_mx(["-p", repo, "help", cmdname], out=output, err=output, nonZeroIsFatal=False, quiet=True) == 0 + is_mx_command = run_mx(["-p", repo, "help", cmdname], out=output, err=output, nonZeroIsFatal=False, quiet=True) == 0 if is_mx_command: - mx.run_mx(["-p", repo, cmdname, "--overlaydir=%s" % overlaydir], suite=repo, nonZeroIsFatal=True) + run_mx(["-p", repo, cmdname, "--overlaydir=%s" % overlaydir], suite=repo, nonZeroIsFatal=True) else: print(mx.colorize('%s command for %s.. skipped!' % (cmdname, basename), color='magenta', bright=True, stream=sys.stdout)) @@ -2070,6 +1933,9 @@ def python_style_checks(args): def python_checkcopyrights(args): + if mx.is_windows(): + # skip, broken with crlf stuff + return # we wan't to ignore lib-python/3, because that's just crazy listfilename = tempfile.mktemp() with open(listfilename, "w") as listfile: @@ -2078,7 +1944,7 @@ def python_checkcopyrights(args): content = listfile.read() with open(listfilename, "w") as listfile: for line in content.split("\n"): - if "lib-python/3" in line or "com.oracle.graal.python.test/testData" in line or "com.oracle.graal.python.pegparser.test/testData" in line: + if any(x in line for x in ["lib-python/3", ".test/testData", "/hpy/"]): pass elif os.path.splitext(line)[1] in [".py", ".java", ".c", ".h", ".sh"]: listfile.write(line) @@ -2138,11 +2004,18 @@ def _python_checkpatchfiles(): standalone_dependencies_common = { - 'LLVM Runtime Core': ('lib/sulong', []), - 'LLVM Runtime Native': ('lib/sulong', []), - 'LLVM.org toolchain': ('lib/llvm-toolchain', []), + "Truffle NFI": "truffle:TRUFFLE_NFI", + "Truffle NFI LIBFFI": "truffle:TRUFFLE_NFI_LIBFFI", } +def bytecode_dsl_build_args(): + return ['-Dpython.EnableBytecodeDSLInterpreter=true'] if BYTECODE_DSL_INTERPRETER else [] + +mx_subst.results_substitutions.register_no_arg( + 'bytecode_dsl_build_args', + lambda: f'-Dpython.EnableBytecodeDSLInterpreter={repr(BYTECODE_DSL_INTERPRETER).lower()}' +) + mx_sdk.register_graalvm_component(mx_sdk.GraalVmLanguage( suite=SUITE, name='GraalVM Python', @@ -2156,8 +2029,6 @@ def _python_checkpatchfiles(): dependencies=[ 'pynl', 'Truffle', - 'LLVM Runtime Native', - 'LLVM.org toolchain', 'TRegex', 'ICU4J', 'XZ', @@ -2166,10 +2037,6 @@ def _python_checkpatchfiles(): 'GraalVM Python license files': ('', []), }}, standalone_dependencies_enterprise={**standalone_dependencies_common, **{ - **({} if mx.is_windows() else { - 'LLVM Runtime Enterprise': ('lib/sulong', []), - 'LLVM Runtime Native Enterprise': ('lib/sulong', []), - }), 'GraalVM Python license files EE': ('', []), 'GraalVM enterprise license files': ('', ['LICENSE.txt', 'GRAALVM-README.md']), }}, @@ -2186,7 +2053,7 @@ def _python_checkpatchfiles(): ], library_configs=[ mx_sdk.LanguageLibraryConfig( - launchers=['bin/', 'bin/', 'bin/', 'bin/', 'libexec/'], + launchers=['bin/', 'bin/', 'bin/', 'libexec/'], jar_distributions=['graalpython:GRAALPYTHON-LAUNCHER', 'sdk:MAVEN_DOWNLOADER'], main_class=GRAALPYTHON_MAIN_CLASS, build_args=[ @@ -2195,7 +2062,7 @@ def _python_checkpatchfiles(): '-H:-CopyLanguageResources', '-Dpolyglot.python.PosixModuleBackend=native', '-Dpolyglot.python.Sha3ModuleBackend=native', - ], + ] + bytecode_dsl_build_args(), language='python', default_vm_args=[ '--vm.Xss16777216', # request 16M of stack @@ -2212,75 +2079,6 @@ def _python_checkpatchfiles(): # post init # # ---------------------------------------------------------------------------------------------------------------------- -def _register_vms(namespace): - # cpython - python_vm_registry.add_vm(CPythonVm(config_name=CONFIGURATION_DEFAULT), SUITE) - - # pypy - python_vm_registry.add_vm(PyPyVm(config_name=CONFIGURATION_DEFAULT), SUITE) - - # jython - python_vm_registry.add_vm(JythonVm(config_name=CONFIGURATION_DEFAULT), SUITE) - - # graalpython - python_vm_registry.add_vm(GraalPythonVm(config_name=CONFIGURATION_DEFAULT), SUITE, 10) - python_vm_registry.add_vm(GraalPythonVm(config_name=CONFIGURATION_INTERPRETER, extra_polyglot_args=[ - '--experimental-options', '--engine.Compilation=false' - ]), SUITE, 10) - python_vm_registry.add_vm(GraalPythonVm(config_name=CONFIGURATION_DEFAULT_MULTI, extra_polyglot_args=[ - '--experimental-options', '-multi-context', - ]), SUITE, 10) - python_vm_registry.add_vm(GraalPythonVm(config_name=CONFIGURATION_INTERPRETER_MULTI, extra_polyglot_args=[ - '--experimental-options', '-multi-context', '--engine.Compilation=false' - ]), SUITE, 10) - python_vm_registry.add_vm(GraalPythonVm(config_name=CONFIGURATION_DEFAULT_MULTI_TIER, extra_polyglot_args=[ - '--experimental-options', '--engine.MultiTier=true', - ]), SUITE, 10) - python_vm_registry.add_vm(GraalPythonVm(config_name=CONFIGURATION_SANDBOXED, extra_polyglot_args=SANDBOXED_OPTIONS), SUITE, 10) - python_vm_registry.add_vm(GraalPythonVm(config_name=CONFIGURATION_NATIVE, extra_polyglot_args=[ - '--experimental-options', '--python.HPyBackend=JNI' - ]), SUITE, 10) - python_vm_registry.add_vm(GraalPythonVm(config_name=CONFIGURATION_NATIVE_INTERPRETER, extra_polyglot_args=[ - '--experimental-options', '--engine.Compilation=false', '--python.HPyBackend=JNI']), SUITE, 10) - python_vm_registry.add_vm(GraalPythonVm(config_name=CONFIGURATION_SANDBOXED_MULTI, extra_polyglot_args=[ - '--experimental-options', '-multi-context'] + SANDBOXED_OPTIONS), SUITE, 10) - python_vm_registry.add_vm(GraalPythonVm(config_name=CONFIGURATION_NATIVE_MULTI, extra_polyglot_args=[ - '--experimental-options', '-multi-context', '--python.HPyBackend=JNI' - ]), SUITE, 10) - python_vm_registry.add_vm(GraalPythonVm(config_name=CONFIGURATION_NATIVE_INTERPRETER_MULTI, extra_polyglot_args=[ - '--experimental-options', '-multi-context', '--engine.Compilation=false', '--python.HPyBackend=JNI' - ]), SUITE, 10) - python_vm_registry.add_vm(GraalPythonVm(config_name=CONFIGURATION_NATIVE_MULTI_TIER, extra_polyglot_args=[ - '--experimental-options', '--engine.MultiTier=true', '--python.HPyBackend=JNI' - ]), SUITE, 10) - python_vm_registry.add_vm(GraalPythonVm(config_name=CONFIGURATION_PANAMA, extra_polyglot_args=[ - '--experimental-options', '--python.UsePanama=true' - ]), SUITE, 10) - - # java embedding driver - python_java_embedding_vm_registry.add_vm( - GraalPythonJavaDriverVm(config_name=CONFIGURATION_JAVA_EMBEDDING_MULTI, - extra_polyglot_args=['-multi-context']), SUITE, 10) - python_java_embedding_vm_registry.add_vm( - GraalPythonJavaDriverVm(config_name=CONFIGURATION_JAVA_EMBEDDING_MULTI_SHARED, - extra_polyglot_args=['-multi-context', '-shared-engine']), SUITE, 10) - python_java_embedding_vm_registry.add_vm( - GraalPythonJavaDriverVm(config_name=CONFIGURATION_JAVA_EMBEDDING_INTERPRETER_MULTI, - extra_polyglot_args=['-multi-context', '-interpreter']), SUITE, 10) - python_java_embedding_vm_registry.add_vm( - GraalPythonJavaDriverVm(config_name=CONFIGURATION_JAVA_EMBEDDING_INTERPRETER_MULTI_SHARED, - extra_polyglot_args=['-multi-context', '-interpreter', '-shared-engine']), SUITE, 10) - - -def _register_bench_suites(namespace): - for py_bench_suite in PythonBenchmarkSuite.get_benchmark_suites(BENCHMARKS): - mx_benchmark.add_bm_suite(py_bench_suite) - for py_bench_suite in PythonJavaEmbeddingBenchmarkSuite.get_benchmark_suites(JAVA_DRIVER_BENCHMARKS): - mx_benchmark.add_bm_suite(py_bench_suite) - for py_bench_suite in PythonVmWarmupBenchmarkSuite.get_benchmark_suites(WARMUP_BENCHMARKS): - mx_benchmark.add_bm_suite(py_bench_suite) - mx_benchmark.add_bm_suite(PythonJMHDistMxBenchmarkSuite()) - class CharsetFilteringPariticpant: """ @@ -2353,8 +2151,8 @@ def hardcoded_ver_is_behind_major_minor(m): def mx_post_parse_cmd_line(namespace): # all projects are now available at this time - _register_vms(namespace) - _register_bench_suites(namespace) + mx_graalpython_benchmark.register_vms(SUITE, SANDBOXED_OPTIONS) + mx_graalpython_benchmark.register_suites() mx_graalpython_python_benchmarks.register_python_benchmarks() for dist in mx.suite('graalpython').dists: @@ -2373,8 +2171,9 @@ def python_coverage(args): truffle_parser.set_defaults(mode='truffle') args = parser.parse_args(args) - # do not endlessly rebuild tests - mx.command_function("build")(["--dep", "com.oracle.graal.python.test"]) + # do not endlessly rebuild tests, build once for all + run_mx(["build"], env={**os.environ, **LATEST_JAVA_HOME}) + run_mx(["build", "--dep", "com.oracle.graal.python.test"], env={**os.environ, **LATEST_JAVA_HOME}) env = extend_os_env( GRAALPYTHON_MX_DISABLE_REBUILD="True", GRAALPYTEST_FAIL_FAST="False", @@ -2391,32 +2190,23 @@ def python_coverage(args): '--jacocout', 'coverage', '--jacoco-format', 'lcov', ] - mx.run_mx([ + run_mx([ '--strict-compliance', '--primary', 'gate', '-B=--force-deprecation-as-warning-for-dependencies', '--strict-mode', '--tags', args.tags, ] + jacoco_args, env=env) - # On windows, the command can fail if the file is still locked by lingering test processes - retries = 3 if WIN32 else 1 - while True: - retval = mx.run_mx([ - '--strict-compliance', - '--kill-with-sigquit', - 'jacocoreport', - '--format', 'lcov', - '--omit-excluded', - 'coverage', - '--generic-paths', - '--exclude-src-gen', - ], env=env) - if retval == 0: - break - retries -= 1 - if not retries: - sys.exit("Failed to collect coverage report") - time.sleep(10) + run_mx([ + '--strict-compliance', + '--kill-with-sigquit', + 'jacocoreport', + '--format', 'lcov', + '--omit-excluded', + 'coverage', + '--generic-paths', + '--exclude-src-gen', + ], env=env) if args.mode == 'truffle': executable = graalpy_standalone_jvm() @@ -2425,15 +2215,12 @@ def python_coverage(args): {"args": []}, # Run only a few tagged tests that are relevant to the files in lib-graalpython {"tagged": True, "paths": ["test_re.py", "test_unicodedata.py"]}, - # Sulong is not reporting coverage with Truffle coverage very well, so we just disable it - # {"args": SANDBOXED_OPTIONS}, {"args": ["--python.EmulateJython"], "paths": ["test_interop.py"]}, {"hpy": True}, ] common_coverage_args = [ "--experimental-options", - "--llvm.lazyParsing=false", "--python.DisableFrozenModules", # To have proper source information about lib-graalpython "--coverage", "--coverage.TrackInternal", @@ -2650,214 +2437,35 @@ def getBuildEnv(self, replaceVar=mx_subst.path_substitutions): return ret -orig_clean = mx.command_function("clean") -def python_clean(args): - orig_clean(args) - count = 0 - for path in os.walk(SUITE.dir): - for file in glob.iglob(os.path.join(path[0], '*.pyc')): - count += 1 - os.remove(file) - - if count > 0: - print('Cleaning', count, "`*.pyc` files...") - -def update_hpy_import_cmd(args): - """Update our import of HPy sources.""" - parser = ArgumentParser('mx python-update-hpy-import') - parser.add_argument('--pull', action='http://github.com/store_true', help='Perform a pull of the HPy repo first.', required=False) - parser.add_argument('hpy_repo', metavar='HPY_REPO', help='Path to the HPy repo to import from.') - parsed_args, _ = parser.parse_known_args(args) +class GraalpythonFrozenModuleBuildTask(GraalpythonBuildTask): + def build(self): + # We freeze modules twice: once for the manual Bytecode interpreter and once for the DSL interpreter. + args = [mx_subst.path_substitutions.substitute(a, dependency=self) for a in self.subject.args] + return self.run(args, "manual bytecode") or self.run(args, "dsl", extra_vm_args=["-Dpython.EnableBytecodeDSLInterpreter=true"]) - join = os.path.join - vc = SUITE.vc + def run(self, args, interpreter_kind, extra_vm_args=None): + mx.log(f"Building frozen modules for {interpreter_kind} interpreter.") + return super().run(args, extra_vm_args=extra_vm_args) - current_branch = vc.active_branch(SUITE.dir) - if current_branch == "master": - mx.abort("updating imports should be done on a branch") - if vc.isDirty(SUITE.dir): - mx.abort("updating imports should be done on a clean branch") - hpy_repo_path = parsed_args.hpy_repo - - # do sanity check of the HPy repo - hpy_repo_include_dir = join(hpy_repo_path, "hpy", "devel", "include") - hpy_repo_src_dir = join(hpy_repo_path, "hpy", "devel", "src") - hpy_repo_debug_dir = join(hpy_repo_path, "hpy", "debug") - hpy_repo_trace_dir = join(hpy_repo_path, "hpy", "trace") - hpy_repo_test_dir = join(hpy_repo_path, "test") - for d in [hpy_repo_path, hpy_repo_include_dir, hpy_repo_src_dir, hpy_repo_test_dir]: - if not os.path.isdir(d): - mx.abort("HPy import repo is missing directory {}".format(d)) - - # We should use 'SUITE.vc' here because HPy always uses Git and this may be different from 'SUITE.vc'. - vc_git = mx.vc_system("git") - - # Now that we know the 'hpy_repo_path' looks sane, do a pull if requested. - if parsed_args.pull: - if not vc_git.is_this_vc(hpy_repo_path): - mx.abort("Cannot perform pull for HPy repo because {} is not a valid Git repo.".format(hpy_repo_path)) - vc_git.pull(hpy_repo_path, update=True) - - # determine short revision of HPy - import_version = vc_git.git_command(hpy_repo_path, ["rev-parse", "--short", "HEAD"]).strip() - mx.log("Determined HPy revision {}".format(import_version)) - - if vc_git.isDirty(hpy_repo_path): - res = input("WARNING: your HPy repo is not clean. Do you want to proceed? (n/y) ") - if str(res).strip().lower() != "y": - return - - # switch to the HPy import orphan branch - vc.git_command(SUITE.dir, ["checkout", HPY_IMPORT_ORPHAN_BRANCH_NAME]) - assert not SUITE.vc.isDirty(SUITE.dir) - - def import_file(src_file, dest_file): - mx.logv("Importing HPy file {} to {}".format(src_file, dest_file)) - - # ensure that relative parent directories already exist (ignore existing) - os.makedirs(os.path.dirname(dest_file), exist_ok=True) - - # copy file (overwrite existing) - mx.copyfile(src_file, dest_file) - # we may copy ignored files - vc.add(SUITE.dir, dest_file, abortOnError=False) - - def import_files(from_dir, to_dir, exclude=lambda x: False): - mx.log("Importing HPy files from {}".format(from_dir)) - for dirpath, _, filenames in os.walk(from_dir): - relative_dir_path = os.path.relpath(dirpath, start=from_dir) - for filename in filenames: - src_file = join(dirpath, filename) - relative_src_file = join(relative_dir_path, filename) - if not exclude(relative_src_file): - dest_file = join(to_dir, relative_src_file) - import_file(src_file, dest_file) - - def remove_inexistent_file(src_file, dest_file): - if not os.path.exists(dest_file): - mx.logv("Removing file {} since {} does not exist".format(src_file, dest_file)) - vc.git_command(SUITE.dir, ["rm", src_file]) - - def remove_inexistent_files(hpy_dir, our_dir): - mx.log("Looking for removed files in {} (HPy reference dir {})".format(our_dir, hpy_dir)) - for dirpath, _, filenames in os.walk(our_dir): - relative_dir_path = os.path.relpath(dirpath, start=our_dir) - for filename in filenames: - src_file = join(dirpath, filename) - dest_file = join(hpy_dir, relative_dir_path, filename) - remove_inexistent_file(src_file, dest_file) - - def exclude_subdir(subdir): - return lambda relpath: relpath.startswith(subdir) - - def exclude_files(*files): - return lambda relpath: str(os.path.normpath(relpath)) in files - - # headers go into 'com.oracle.graal.python.hpy.llvm/include' - header_dest = join(mx.project("com.oracle.graal.python.hpy.llvm").dir, "include") - - # copy 'hpy/devel/__init__.py' to 'lib-graalpython/module/hpy/devel/__init__.py' - dest_devel_file = join(_get_core_home(), "modules", "hpy", "devel", "__init__.py") - src_devel_file = join(hpy_repo_path, "hpy", "devel", "__init__.py") - if not os.path.exists(src_devel_file): - SUITE.vc.git_command(SUITE.dir, ["reset", "--hard"]) - SUITE.vc.git_command(SUITE.dir, ["checkout", "-"]) - mx.abort("File '{}' is missing but required.".format(src_devel_file)) - import_file(src_devel_file, dest_devel_file) - - # 'version.py' goes to 'lib-graalpython/module/hpy/devel/' - dest_version_file = join(_get_core_home(), "modules", "hpy", "devel", "version.py") - src_version_file = join(hpy_repo_path, "hpy", "devel", "version.py") - if not os.path.exists(src_version_file): - SUITE.vc.git_command(SUITE.dir, ["reset", "--hard"]) - SUITE.vc.git_command(SUITE.dir, ["checkout", "-"]) - mx.abort("File 'version.py' is not available. Did you forget to run 'setup.py build' ?") - import_file(src_version_file, dest_version_file) - - # 'abitag.py' goes to 'lib-graalpython/module/hpy/devel/' - dest_abitag_file = join(_get_core_home(), "modules", "hpy", "devel", "abitag.py") - src_abitag_file = join(hpy_repo_path, "hpy", "devel", "abitag.py") - if not os.path.exists(src_abitag_file): - SUITE.vc.git_command(SUITE.dir, ["reset", "--hard"]) - SUITE.vc.git_command(SUITE.dir, ["checkout", "-"]) - mx.abort("File 'abitag.py' is not available. Did you forget to run 'setup.py build' ?") - import_file(src_abitag_file, dest_abitag_file) - - # copy headers from .../hpy/hpy/devel/include' to 'header_dest' - # but exclude subdir 'cpython' (since that's only for CPython) - import_files(hpy_repo_include_dir, header_dest) - remove_inexistent_files(hpy_repo_include_dir, header_dest) - - - # runtime sources go into 'lib-graalpython/module/hpy/devel/src' - runtime_files_dest = join(_get_core_home(), "modules", "hpy", "devel", "src") - import_files(hpy_repo_src_dir, runtime_files_dest) - remove_inexistent_files(hpy_repo_src_dir, runtime_files_dest) - - # 'ctx_tracker.c' also goes to 'com.oracle.graal.python.jni/src/ctx_tracker.c' - tracker_file_src = join(hpy_repo_src_dir, "runtime", "ctx_tracker.c") - if not os.path.exists(tracker_file_src): - mx.abort("File '{}' is missing but required.".format(tracker_file_src)) - jni_project_dir = mx.project("com.oracle.graal.python.jni").dir - tracker_file_dest = join(jni_project_dir, "src", "ctx_tracker.c") - import_file(tracker_file_src, tracker_file_dest) - - # tests go to 'com.oracle.graal.python.hpy.test/src/hpytest' - test_files_dest = join(mx.dependency(HPY_TEST_PROJECT).dir, "src", "hpytest") - import_files(hpy_repo_test_dir, test_files_dest) - remove_inexistent_files(hpy_repo_test_dir, test_files_dest) - - # debug Python sources go into 'lib-graalpython/module/hpy/debug' - debug_files_dest = join(_get_core_home(), "modules", "hpy", "debug") - import_files(hpy_repo_debug_dir, debug_files_dest, exclude_subdir("src")) - remove_inexistent_files(hpy_repo_debug_dir, debug_files_dest) - - # debug mode goes into 'com.oracle.graal.python.jni/src/debug' - debugctx_src = join(hpy_repo_debug_dir, "src") - debugctx_dest = join(jni_project_dir, "src", "debug") - debugctx_hdr = join(debugctx_src, "include", "hpy_debug.h") - import_files(debugctx_src, debugctx_dest, exclude_files( - "autogen_debug_ctx_call.i", "debug_ctx_cpython.c", debugctx_hdr)) - import_file(debugctx_hdr, join(debugctx_dest, "hpy_debug.h")) - - # trace Python sources go into 'lib-graalpython/module/hpy/trace' - trace_files_dest = join(_get_core_home(), "modules", "hpy", "trace") - import_files(hpy_repo_debug_dir, trace_files_dest, exclude_subdir("src")) - remove_inexistent_files(hpy_repo_trace_dir, trace_files_dest) - - # trace mode goes into 'com.oracle.graal.python.jni/src/trace' - tracectx_src = join(hpy_repo_trace_dir, "src") - tracectx_dest = join(jni_project_dir, "src", "trace") - tracectx_hdr = join(tracectx_src, "include", "hpy_trace.h") - import_files(tracectx_src, tracectx_dest, exclude_files(tracectx_hdr)) - import_file(tracectx_hdr, join(tracectx_dest, "hpy_trace.h")) - - # import 'version.py' by path and read '__version__' - from importlib import util - spec = util.spec_from_file_location("version", dest_version_file) - version_module = util.module_from_spec(spec) - spec.loader.exec_module(version_module) - imported_version = version_module.__version__ - - SUITE.vc.git_command(SUITE.dir, ["add", header_dest, test_files_dest, runtime_files_dest, tracker_file_dest]) - input("Check that the updated files look as intended, then press RETURN...") - SUITE.vc.commit(SUITE.dir, "Update HPy inlined files: %s" % import_version) - SUITE.vc.git_command(SUITE.dir, ["checkout", "-"]) - SUITE.vc.git_command(SUITE.dir, ["merge", HPY_IMPORT_ORPHAN_BRANCH_NAME]) - - # update PKG-INFO version - pkg_info_file = join(_get_core_home(), "modules", "hpy.egg-info", "PKG-INFO") - with open(pkg_info_file, "w") as f: - f.write("Metadata-Version: 2.1\n" - "Name: hpy\n" - "Version: {}\n" - "Summary: UNKNOWN\n" - "Home-page: UNKNOWN\n" - "License: UNKNOWN\n" - "Description: UNKNOWN\n" - "Platform: UNKNOWN\n" - "Provides-Extra: dev\n".format(imported_version).strip()) +class GraalpythonFrozenProject(GraalpythonProject): + def getBuildTask(self, args): + return GraalpythonFrozenModuleBuildTask(args, self) + + +orig_clean = mx.command_function("clean") +def python_clean(args): + if '--just-pyc' not in args: + orig_clean(args) + if not args: + count = 0 + for path in os.walk(SUITE.dir): + for file in glob.iglob(os.path.join(path[0], '*.pyc')): + count += 1 + os.remove(file) + + if count > 0: + print('Cleaning', count, "`*.pyc` files...") def run_leak_launcher(input_args): @@ -2881,7 +2489,7 @@ def run_leak_launcher(input_args): env = os.environ.copy() - dists = ['GRAALPYTHON', 'GRAALPYTHON_RESOURCES', 'TRUFFLE_NFI', 'SULONG_NATIVE', 'GRAALPYTHON_UNIT_TESTS'] + dists = ['GRAALPYTHON', 'GRAALPYTHON_RESOURCES', 'TRUFFLE_NFI', 'TRUFFLE_NFI_LIBFFI', 'GRAALPYTHON_UNIT_TESTS'] vm_args, graalpython_args = mx.extract_VM_args(args, useDoubleDash=True, defaultAllVMArgs=False) vm_args += mx.get_runtime_jvm_args(dists) @@ -2919,6 +2527,43 @@ def inner(*args, **kwargs): return inner +def run(args, *splat, **kwargs): + if not mx.get_opts().quiet: + msg = "Running: " + env = kwargs.get("env") + if env: + extra_env = shlex.join([f"{k}={v}" for k, v in env.items() if os.environ.get(k) != v]) + msg += f'{extra_env} ' + msg += shlex.join(args) + mx.log(mx.colorize(msg, color="green")) + return mx.run(args, *splat, **kwargs) + + +def run_mx(args, *splat, **kwargs): + env = kwargs.get("env", os.environ) + extra_env = {k: v for k, v in env.items() if os.environ.get(k) != v} + + # Sigh. mx.run_mx forcibly overrides the environment JAVA_HOME by passing + # --java-home to the subprocess... + if jh := extra_env.get("JAVA_HOME"): + args = [f"--java-home={jh}"] + args + + if "-p" not in args and "--dy" not in args and "--dynamicimports" not in args: + if dy := mx.get_dynamic_imports(): + args = [ + "--dy", + ",".join(f"{'/' if subdir else ''}{name}" for name, subdir in dy) + ] + args + + msg = "Running: " + if extra_env: + msg += shlex.join([f"{k}={v}" for k, v in extra_env.items()]) + msg += f" mx {shlex.join(args)}" + if not mx.get_opts().quiet: + mx.log(mx.colorize(msg, color="green")) + return mx.run_mx(args, *splat, **kwargs) + + def host_inlining_log_extract_method(args_in): parser = ArgumentParser(description="Extracts single method from host inlining log file. " "Result, when saved to file, can be visualized with: java scripts/HostInliningVisualizer.java filename") @@ -2961,7 +2606,6 @@ class PythonMxUnittestConfig(mx_unittest.MxUnittestConfig): # We use global state, which influences what this unit-test config is going to do # The global state can be adjusted before a test run to achieve a different tests configuration useResources = True # Whether to use resources, or language home of filesystem - # Possible future extensions: useSulong = True def apply(self, config): (vmArgs, mainClass, mainClassArgs) = config @@ -2970,6 +2614,7 @@ def apply(self, config): mainClassArgs.extend(['-JUnitOpenPackages', 'org.graalvm.py/*=ALL-UNNAMED']) # for Python internals mainClassArgs.extend(['-JUnitOpenPackages', 'org.graalvm.py.launcher/*=ALL-UNNAMED']) # for Python launcher internals mainClassArgs.extend(['-JUnitOpenPackages', 'org.graalvm.python.embedding/*=ALL-UNNAMED']) + mainClassArgs.extend(['-JUnitOpenPackages', 'org.graalvm.python.embedding.tools/*=ALL-UNNAMED']) if not PythonMxUnittestConfig.useResources: vmArgs.append('-Dorg.graalvm.language.python.home=' + mx.dependency("GRAALPYTHON_GRAALVM_SUPPORT").get_output()) if mx._opts.verbose: @@ -3006,6 +2651,107 @@ def graalpy_jmh(args): mx.run_java(vm_args + ['org.openjdk.jmh.Main'] + args) +def run_in_venv(venv, cmd, **kwargs): + return mx.run(['sh', '-c', f". {venv}/bin/activate && {shlex.join(cmd)}"], **kwargs) + + +DOWNSTREAM_TESTS = {} + +def downstream_test(name): + def decorator(fn): + DOWNSTREAM_TESTS[name] = fn + return fn + return decorator + + +@downstream_test('hpy') +def downstream_test_hpy(graalpy, args=None, env=None, nonZeroIsFatal=True, timeout=None): + testdir = Path('upstream-tests').absolute() + shutil.rmtree(testdir, ignore_errors=True) + testdir.mkdir(exist_ok=True) + hpy_root = os.path.join(mx.dependency("hpy").dir) + shutil.copytree(hpy_root, testdir / "hpy") + hpy_root = testdir / "hpy" + hpy_test_root = hpy_root / "test" + venv = testdir / 'hpy_venv' + mx.run([graalpy, "-m", "venv", str(venv)]) + run_in_venv(venv, ["pip", "install", "pytest", "pytest-xdist", "pytest-rerunfailures", "filelock"]) + env = env or os.environ.copy() + env["SETUPTOOLS_SCM_PRETEND_VERSION"] = "0.9.0" + run_in_venv(venv, ["pip", "install", "-e", "."], cwd=str(hpy_root), env=env) + parallelism = str(min(os.cpu_count(), int(os.cpu_count() / 4))) + args = args or [] + args = [ + "python", + "--vm.ea", + "--experimental-options=true", + "--python.EnableDebuggingBuiltins", + *args, + "-m", "pytest", + "-v", + # for those cases where testing invalid handles corrupts the process so + # much that we crash - we don't recover gracefully in some cases :( + "--reruns", "3", + "-n", parallelism, + str(hpy_test_root), + # test_distutils is just slow and testing the build infrastructure + "-k", "not test_distutils" + ] + mx.logv(shlex.join(args)) + return run_in_venv(venv, args, env=env, cwd=str(hpy_root), nonZeroIsFatal=nonZeroIsFatal, timeout=timeout) + + +@downstream_test('pybind11') +def downstream_test_pybind11(graalpy): + testdir = Path('upstream-tests').absolute() + shutil.rmtree(testdir, ignore_errors=True) + testdir.mkdir(exist_ok=True) + mx.run(['git', 'clone', 'https://github.com/pybind/pybind11.git'], cwd=testdir) + src = testdir / 'pybind11' + venv = src / 'venv' + mx.run([graalpy, '-m', 'venv', str(venv)]) + run_in_venv(venv, ['pip', 'install', 'pytest']) + run_in_venv(venv, ['cmake', '-S', '.', '-B', 'build', '-DPYBIND11_WERROR=ON'], cwd=src) + run_in_venv(venv, ['cmake', '--build', 'build', '--parallel'], cwd=src) + env = os.environ.copy() + env['PYTHONPATH'] = 'build/tests' + run_in_venv(venv, ['pytest', '-v', '--tb=short', 'tests'], cwd=src, env=env) + + +@downstream_test('virtualenv') +def downstream_test_virtualenv(graalpy): + testdir = Path('upstream-tests').absolute() + shutil.rmtree(testdir, ignore_errors=True) + testdir.mkdir(exist_ok=True) + mx.run(['git', 'clone', 'https://github.com/pypa/virtualenv.git', '-b', 'main'], cwd=testdir) + src = testdir / 'virtualenv' + venv = src / 'venv' + mx.run([graalpy, '-m', 'venv', str(venv)]) + env = os.environ.copy() + env.pop('VIRTUAL_ENV_DISABLE_PROMPT', None) + env['CI_RUN'] = '1' + # Need to avoid pulling in graalpy seeder + env['PIP_GRAALPY_DISABLE_PATCHING'] = '1' + run_in_venv(venv, ['pip', 'install', f'{src}[test]'], env=env) + # Don't activate the venv, it interferes with the test + mx.run([ + str(venv / 'bin' / 'pytest'), '-v', '--tb=short', 'tests', + '-k', 'not fish and not csh and not nushell and not powershell', + ], cwd=src, env=env) + + +def run_downstream_test(args): + parser = ArgumentParser(description="Runs important upstream packages tests using their main branch") + parser.add_argument('project', choices=sorted(DOWNSTREAM_TESTS)) + parser.add_argument('--dev', action='http://github.com/store_true', help="Use JVM dev standalone") + args = parser.parse_args(args) + if args.dev: + graalpy = graalpy_standalone('jvm', dev=True) + else: + graalpy = graalpy_standalone_native() + DOWNSTREAM_TESTS[args.project](graalpy) + + # ---------------------------------------------------------------------------------------------------------------------- # # register the suite commands (if any) @@ -3023,16 +2769,13 @@ def graalpy_jmh(args): 'python-jvm': [no_return(python_jvm), ''], 'graalpy-standalone': [graalpy_standalone_wrapper, '[jvm|native] [ce|ee] [--no-build]'], 'python-gvm': [no_return(python_gvm), ''], - 'python-unittests': [python3_unittests, ''], - 'python-compare-unittests': [compare_unittests, ''], 'nativebuild': [nativebuild, ''], 'nativeclean': [nativeclean, ''], 'python-src-import': [mx_graalpython_import.import_python_sources, ''], 'python-coverage': [python_coverage, ''], 'punittest': [punittest, ''], 'graalpytest': [graalpytest, '[-h] [--python PYTHON] [TESTS]'], - 'clean': [python_clean, ''], - 'python-update-hpy-import': [update_hpy_import_cmd, '[--no-pull] PATH_TO_HPY'], + 'clean': [python_clean, '[--just-pyc]'], 'bisect-benchmark': [mx_graalpython_bisect.bisect_benchmark, ''], 'python-leak-test': [run_leak_launcher, ''], 'python-nodes-footprint': [node_footprint_analyzer, ''], @@ -3041,4 +2784,5 @@ def graalpy_jmh(args): 'tox-example': [tox_example, ''], 'graalpy-jmh': [graalpy_jmh, ''], 'deploy-local-maven-repo': [deploy_local_maven_repo_wrapper, ''], + 'downstream-test': [run_downstream_test, ''], }) diff --git a/mx.graalpython/mx_graalpython_bench_param.py b/mx.graalpython/mx_graalpython_bench_param.py index 2833b14bfd..d0ec69ee43 100644 --- a/mx.graalpython/mx_graalpython_bench_param.py +++ b/mx.graalpython/mx_graalpython_bench_param.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017, 2024, Oracle and/or its affiliates. +# Copyright (c) 2017, 2025, Oracle and/or its affiliates. # Copyright (c) 2013, Regents of the University of California # # All rights reserved. @@ -39,6 +39,7 @@ PATH_WARMUP = os.path.join(_BASE_PATH, 'warmup') PATH_INTEROP = os.path.join(_BASE_PATH, 'host_interop') PATH_JAVA_EMBEDDING = os.path.join(_BASE_PATH, 'java-embedding') +PATH_HEAP = os.path.join(_BASE_PATH, 'heap') # ---------------------------------------------------------------------------------------------------------------------- # @@ -331,3 +332,11 @@ def _pickling_benchmarks(module='pickle'): WARMUP_BENCHMARKS = { "python-warmup": [PATH_WARMUP, WARMUP_BENCHMARKS], } + +HEAP_BENCHMARKS = { + "heap": [PATH_HEAP, { + "post-startup": [], + "import-a-lot": [], + "allocate-objects": [], + }] +} diff --git a/mx.graalpython/mx_graalpython_benchmark.py b/mx.graalpython/mx_graalpython_benchmark.py index d6fe937cfd..2b6dcaa46f 100644 --- a/mx.graalpython/mx_graalpython_benchmark.py +++ b/mx.graalpython/mx_graalpython_benchmark.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. # Copyright (c) 2013, Regents of the University of California # # All rights reserved. @@ -23,16 +23,23 @@ # OF THE POSSIBILITY OF SUCH DAMAGE. from __future__ import print_function +import itertools +import functools +import statistics +import sys import os import re +import shlex import subprocess -from abc import ABCMeta, abstractproperty, abstractmethod +from abc import ABC, abstractproperty from contextlib import contextmanager from os.path import join +from datetime import datetime +from pathlib import Path import mx import mx_benchmark -from mx_benchmark import StdOutRule, java_vm_registry, Vm, GuestVm, VmBenchmarkSuite, AveragingBenchmarkMixin +from mx_benchmark import StdOutRule, java_vm_registry, OutputCapturingVm, GuestVm, VmBenchmarkSuite, AveragingBenchmarkMixin from mx_graalpython_bench_param import HARNESS_PATH # ---------------------------------------------------------------------------------------------------------------------- @@ -41,20 +48,14 @@ # # ---------------------------------------------------------------------------------------------------------------------- SUITE = mx.suite("graalpython") +DIR = Path(__file__).parent.resolve() # ---------------------------------------------------------------------------------------------------------------------- # # constants # # ---------------------------------------------------------------------------------------------------------------------- -ENV_PYPY_HOME = "PYPY_HOME" -ENV_PYTHON3_HOME = "PYTHON3_HOME" -ENV_VIRTUAL_ENV = "VIRTUAL_ENV" -ENV_JYTHON_JAR = "JYTHON_JAR" VM_NAME_GRAALPYTHON = "graalpython" -VM_NAME_CPYTHON = "cpython" -VM_NAME_PYPY = "pypy" -VM_NAME_JYTHON = "jython" VM_NAME_GRAALPYTHON_SVM = "graalpython-svm" GROUP_GRAAL = "Graal" SUBGROUP_GRAAL_PYTHON = "graalpython" @@ -89,35 +90,11 @@ # utils # # ---------------------------------------------------------------------------------------------------------------------- -def _check_vm_args(name, args): - if len(args) < 2: - mx.abort("Expected at least 2 args (a single benchmark path in addition to the harness), " - "got {} instead".format(args)) - def is_sandboxed_configuration(conf): return conf in (CONFIGURATION_SANDBOXED, CONFIGURATION_SANDBOXED_MULTI) -# from six -def add_metaclass(metaclass): - """Class decorator for creating a class with a metaclass.""" - def wrapper(cls): - orig_vars = cls.__dict__.copy() - slots = orig_vars.get('__slots__') - if slots is not None: - if isinstance(slots, str): - slots = [slots] - for slots_var in slots: - orig_vars.pop(slots_var) - orig_vars.pop('__dict__', None) - orig_vars.pop('__weakref__', None) - if hasattr(cls, '__qualname__'): - orig_vars['__qualname__'] = cls.__qualname__ - return metaclass(cls.__name__, cls.__bases__, orig_vars) - return wrapper - - @contextmanager def environ(env): def _handle_var(key_value): @@ -145,59 +122,47 @@ def _handle_var(key_value): # the vm definitions # # ---------------------------------------------------------------------------------------------------------------------- -@add_metaclass(ABCMeta) -class AbstractPythonVm(Vm): - def __init__(self, config_name, options=None, env=None): - super(AbstractPythonVm, self).__init__() +class AbstractPythonVm(OutputCapturingVm, ABC): + def __init__(self, name, config_name, options=None): + super().__init__() + self._name = name self._config_name = config_name self._options = options - self._env = env @property def options(self): return self._options - def config_name(self): - """ - The configuration name - - :return: the configuration name - :rtype: str or unicode - """ - return self._config_name - - @abstractmethod def name(self): - """ - The VM name + return self._name - :return: the vm name - :rtype: str or unicode - """ - return None + def config_name(self): + return self._config_name @abstractproperty def interpreter(self): - """ - the python like interpreter - - :return: the interpreter - :rtype: str or unicode - """ return None - def run(self, cwd, args): - _check_vm_args(self.name(), args) - out = mx.OutputCapture() - stdout_capture = mx.TeeOutputCapture(out) - ret_code = mx.run([self.interpreter] + args, out=stdout_capture, err=stdout_capture, env=self._env) - return ret_code, out.data + def post_process_command_line_args(self, args): + return args + + def run_vm(self, args, out=None, err=None, cwd=None, nonZeroIsFatal=False, env=None): + cmd = [self.interpreter] + args + cmd = mx.apply_command_mapper_hooks(cmd, self.command_mapper_hooks) + mx.logv(shlex.join(cmd)) + return mx.run( + cmd, + out=out, + err=err, + cwd=cwd, + nonZeroIsFatal=nonZeroIsFatal, + env=env, + ) -@add_metaclass(ABCMeta) class AbstractPythonIterationsControlVm(AbstractPythonVm): - def __init__(self, config_name, options=None, env=None, iterations=None): - super(AbstractPythonIterationsControlVm, self).__init__(config_name, options=options, env=env) + def __init__(self, name, config_name, options=None, iterations=None): + super().__init__(name, config_name, options=options) try: self._iterations = int(iterations) except: @@ -218,39 +183,52 @@ def _override_iterations_args(self, args): i += 1 return _args - def run(self, cwd, args): + def run_vm(self, args, *splat, **kwargs): args = self._override_iterations_args(args) - return super(AbstractPythonIterationsControlVm, self).run(cwd, args) + return super().run_vm(args, *splat, **kwargs) class CPythonVm(AbstractPythonIterationsControlVm): - PYTHON_INTERPRETER = "python3" - - def __init__(self, config_name, options=None, env=None, virtualenv=None, iterations=0): - super(CPythonVm, self).__init__(config_name, options=options, env=env, iterations=iterations) + def __init__(self, config_name, options=None, virtualenv=None, iterations=0): + super().__init__("cpython", config_name, options=options, iterations=iterations) self._virtualenv = virtualenv + def override_iterations(self, requested_iterations): + # CPython has no JIT right now, just a quickening interpreter + return min(requested_iterations, 3) + @property def interpreter(self): - venv = self._virtualenv if self._virtualenv else mx.get_env(ENV_VIRTUAL_ENV) - if venv: - mx.log(f"CPythonVM virtualenv={venv}") - return os.path.join(venv, 'bin', CPythonVm.PYTHON_INTERPRETER) - home = mx.get_env(ENV_PYTHON3_HOME) - if home: - mx.log(f"CPythonVM python3 home={home}") - return os.path.join(home, CPythonVm.PYTHON_INTERPRETER) - return CPythonVm.PYTHON_INTERPRETER - - def name(self): - return VM_NAME_CPYTHON + candidates_pre = [ + self._virtualenv, + mx.get_env("VIRTUAL_ENV"), + mx.get_env("PYTHON3_HOME"), + ] + candidates_suf = [ + join("bin", "python3"), + join("bin", "python"), + "python3", + "python", + sys.executable, + ] + for p, s in itertools.product(candidates_pre, candidates_suf): + if os.path.exists(exe := os.path.join(p or "", s)): + mx.log(f"CPython VM {exe=}") + return exe + assert False, "sys.executable should really exist" + + def run_vm(self, args, *splat, **kwargs): + for idx, arg in enumerate(args): + if "--vm.Xmx" in arg: + mx.warn(f"Ignoring {arg}, cannot restrict memory on CPython.") + args = args[:idx] + args[idx + 1 :] + break + return super().run_vm(args, *splat, **kwargs) class PyPyVm(AbstractPythonIterationsControlVm): - PYPY_INTERPRETER = "pypy3" - - def __init__(self, config_name, options=None, env=None, iterations=None): - super(PyPyVm, self).__init__(config_name, options=options, env=env, iterations=iterations) + def __init__(self, config_name, options=None, virtualenv=None, iterations=0): + super().__init__("pypy", config_name, options=options, iterations=iterations) def override_iterations(self, requested_iterations): # PyPy warms up much faster, half should be enough @@ -258,95 +236,124 @@ def override_iterations(self, requested_iterations): @property def interpreter(self): - home = mx.get_env(ENV_PYPY_HOME) - if not home: + if home := mx.get_env("PYPY_HOME"): + exe = join(home, "bin", "pypy3") + else: try: - return subprocess.check_output("which %s" % PyPyVm.PYPY_INTERPRETER, shell=True).decode().strip() + exe = subprocess.check_output("which pypy3", shell=True).decode().strip() except OSError: - mx.abort("{} is not set!".format(ENV_PYPY_HOME)) - return join(home, 'bin', PyPyVm.PYPY_INTERPRETER) - - def name(self): - return VM_NAME_PYPY - + mx.abort("PYPY_HOME is not set!") + mx.log(f"PyPy {exe=}") + return exe + + def run_vm(self, args, *splat, env=None, **kwargs): + env = env or os.environ.copy() + xmxArg = re.compile("--vm.Xmx([0-9]+)([kKgGmM])") + pypyGcMax = "8GB" + for idx, arg in enumerate(args): + if m := xmxArg.search(arg): + args = args[:idx] + args[idx + 1 :] + pypyGcMax = f"{m.group(1)}{m.group(2).upper()}B" + mx.log(f"Setting PYPY_GC_MAX={pypyGcMax} via {arg}") + break + else: + mx.log( + f"Setting PYPY_GC_MAX={pypyGcMax}, use --vm.Xmx argument to override it" + ) + env["PYPY_GC_MAX"] = pypyGcMax + return super().run_vm(args, *splat, env=env, **kwargs) -class JythonVm(AbstractPythonIterationsControlVm, GuestVm): - JYTHON_INTERPRETER = "jython" - def __init__(self, config_name, options=None, env=None, iterations=None, host_vm=None): - AbstractPythonIterationsControlVm.__init__(self, config_name, options=options, env=env, iterations=iterations) - GuestVm.__init__(self, host_vm=host_vm) - - def override_iterations(self, requested_iterations): - return 3 - - def hosting_registry(self): - return java_vm_registry +class GraalPythonVm(AbstractPythonIterationsControlVm): + def __init__(self, config_name, options=None, virtualenv=None, iterations=None, extra_polyglot_args=None): + super().__init__(VM_NAME_GRAALPYTHON, config_name, options=options, iterations=iterations) + self._extra_polyglot_args = extra_polyglot_args or [] @property - def interpreter(self): - try: - return subprocess.check_output("which %s" % JythonVm.JYTHON_INTERPRETER, shell=True).decode().strip() - except Exception as e: # pylint: disable=broad-except - mx.log_error(e) - mx.abort("`jython` is neither on the path, nor is {} set!\n".format(ENV_JYTHON_JAR)) - - def run(self, cwd, args): - jar = mx.get_env(ENV_JYTHON_JAR) - if jar: - _check_vm_args(self.name(), args) - host_vm = self.host_vm() - - vm_args = mx.get_runtime_jvm_args([]) - vm_args += ["-jar", jar] - for a in args[:]: - if a.startswith("-D") or a.startswith("-XX"): - vm_args.insert(0, a) - args.remove(a) - args = self._override_iterations_args(args) - cmd = vm_args + args - - if not self._env: - self._env = dict() - with environ(self._env): - return host_vm.run(cwd, cmd) + @functools.lru_cache + def launcher_type(self): + if mx.dependency("GRAALPY_NATIVE_STANDALONE", fatalIfMissing=False): + return "native" else: - return AbstractPythonIterationsControlVm.run(self, cwd, args) - - def config_name(self): - return self._config_name + return "jvm" - def with_host_vm(self, host_vm): - return self.__class__(config_name=self._config_name, options=self._options, env=self._env, - iterations=self._iterations, host_vm=host_vm) + @property + @functools.lru_cache + def interpreter(self): + from mx_graalpython import graalpy_standalone + launcher = graalpy_standalone(self.launcher_type, build=False) + mx.log(f"Using {launcher} based on enabled/excluded GraalPy standalone build targets.") + return launcher + + def post_process_command_line_args(self, args): + if os.environ.get('BYTECODE_DSL_INTERPRETER', '').lower() == 'true' and not self.is_bytecode_dsl_config(): + print("Found environment variable BYTECODE_DSL_INTERPRETER, but the guest vm config is not Bytecode DSL config.") + print("Did you want to use, e.g., `mx benchmark ... -- --host-vm-config=default-bc-dsl`?") + sys.exit(1) + return self.get_extra_polyglot_args() + args + + def is_bytecode_dsl_config(self): + return '--vm.Dpython.EnableBytecodeDSLInterpreter=true' in self.get_extra_polyglot_args() + + def extract_vm_info(self, args=None): + out_version = subprocess.check_output([self.interpreter, '--version'], universal_newlines=True) + # The benchmark data goes back a ways, we modify the reported dims for + # continuity with the historical queries + graalvm_version_match = re.search(r"\(([^\)]+ ((?:\d+\.?)+)).*\)", out_version) + if not graalvm_version_match: + mx.log(f"Using {out_version} as platform version string input") + graalvm_version_match = [out_version, out_version, out_version] + dims = { + 'guest-vm': self.name(), + 'guest-vm-config': self.config_name(), + 'host-vm': 'graalvm-' + ('ee' if 'Oracle GraalVM' in out_version else 'ce'), + 'host-vm-config': self.launcher_type, + "platform.graalvm-edition": 'EE' if 'Oracle GraalVM' in out_version else 'CE', + "platform.graalvm-version": graalvm_version_match[2], + "platform.graalvm-version-string": graalvm_version_match[1], + } + if dims['guest-vm-config'].endswith('-3-compiler-threads'): + dims['guest-vm-config'] = dims['guest-vm-config'].replace('-3-compiler-threads', '') + dims['host-vm-config'] += '-3-compiler-threads' + self._dims = dims + + def run(self, *args, **kwargs): + code, out, dims = super().run(*args, **kwargs) + dims.update(self._dims) + + is_bytecode_dsl_config = self.is_bytecode_dsl_config() + if "using bytecode DSL interpreter:" not in out: + # Let's be lenient unless in CI + print(f"BENCHMARK WARNING: could not verify whether running on bytecode DSL or not") + elif code == 0 and not f"using bytecode DSL interpreter: {is_bytecode_dsl_config}" in out: + print(f"ERROR: host VM config does not match what the the harness reported. " + f"Expected Bytecode DSL interpreter = {is_bytecode_dsl_config}. Harness output:\n{out}", file=sys.stderr) + return 1, out, dims + return code, out, dims - def name(self): - return VM_NAME_JYTHON + def get_extra_polyglot_args(self): + return ["--experimental-options", "-snapshot-startup", "--python.MaxNativeMemory=%s" % (2**34), *self._extra_polyglot_args] -class GraalPythonVmBase(GuestVm): - def __init__(self, config_name=CONFIGURATION_DEFAULT, distributions=None, cp_suffix=None, cp_prefix=None, - host_vm=None, extra_vm_args=None, extra_polyglot_args=None, env=None): - super(GraalPythonVmBase, self).__init__(host_vm=host_vm) +class GraalPythonJavaDriverVm(GuestVm): + def __init__(self, config_name=CONFIGURATION_DEFAULT, cp_suffix=None, distributions=None, cp_prefix=None, + host_vm=None, extra_vm_args=None, extra_polyglot_args=None): + super().__init__(host_vm=host_vm) self._config_name = config_name - self._distributions = distributions + self._distributions = distributions or ['GRAALPYTHON_BENCH'] self._cp_suffix = cp_suffix self._cp_prefix = cp_prefix self._extra_vm_args = extra_vm_args self._extra_polyglot_args = extra_polyglot_args if isinstance(extra_polyglot_args, list) else [] - self._env = env - - def hosting_registry(self): - return java_vm_registry - def launcher_class(self): - raise NotImplementedError() + def name(self): + return VM_NAME_GRAALPYTHON - def run_in_graalvm(self, cwd, args, extra_polyglot_args, host_vm): - raise NotImplementedError() + def config_name(self): + return self._config_name - def get_extra_polyglot_args(self): - raise NotImplementedError() + def hosting_registry(self): + return java_vm_registry def get_classpath(self): cp = [] @@ -356,131 +363,36 @@ def get_classpath(self): cp.append(self._cp_suffix) return cp - @staticmethod - def _remove_vm_prefix(argument): - if argument.startswith('--vm.'): - return '-' + argument.strip('--vm.') - else: - return argument - - def run(self, cwd, args): - _check_vm_args(self.name(), args) - extra_polyglot_args = self.get_extra_polyglot_args() - - host_vm = self.host_vm() - if hasattr(host_vm, 'run_lang'): # this is a full GraalVM build - return self.run_in_graalvm(cwd, args, extra_polyglot_args, host_vm) - - # Otherwise, we're running from the source tree - args = [self._remove_vm_prefix(x) for x in args] - truffle_options = [ - # "-Dpolyglot.engine.CompilationExceptionsAreFatal=true" - ] - - dists = ["GRAALPYTHON", "TRUFFLE_NFI", "GRAALPYTHON-LAUNCHER"] - # add configuration specified distributions - if self._distributions: - assert isinstance(self._distributions, list), "distributions must be either None or a list" - dists += self._distributions - - if mx.suite("tools", fatalIfMissing=False): - dists.extend(('CHROMEINSPECTOR', 'TRUFFLE_PROFILER')) - if mx.suite("sulong", fatalIfMissing=False): - dists.append('SULONG_NATIVE') - - extra_polyglot_args += [ - "--python.CAPI=%s" % SUITE.extensions._get_capi_home(), - "--python.JNIHome=%s" % SUITE.extensions._get_jni_home() - ] - - vm_args = mx.get_runtime_jvm_args(dists, cp_suffix=self._cp_suffix, cp_prefix=self._cp_prefix) - if isinstance(self._extra_vm_args, list): - vm_args += self._extra_vm_args - vm_args += [ - "-Dorg.graalvm.language.python.home=%s" % mx.dependency("GRAALPYTHON_GRAALVM_SUPPORT").get_output(), - self.launcher_class(), - ] - for a in args[:]: - if a.startswith("-D") or a.startswith("-XX"): - vm_args.insert(0, a) - args.remove(a) - cmd = truffle_options + vm_args + extra_polyglot_args + args - - if not self._env: - self._env = dict() - with environ(self._env): - return host_vm.run(cwd, cmd) - - def name(self): - return VM_NAME_GRAALPYTHON - - def config_name(self): - return self._config_name - def with_host_vm(self, host_vm): return self.__class__(config_name=self._config_name, distributions=self._distributions, cp_suffix=self._cp_suffix, cp_prefix=self._cp_prefix, host_vm=host_vm, - extra_vm_args=self._extra_vm_args, extra_polyglot_args=self._extra_polyglot_args, - env=self._env) - - -class GraalPythonVm(GraalPythonVmBase): - def __init__(self, config_name=CONFIGURATION_DEFAULT, distributions=None, cp_suffix=None, cp_prefix=None, - host_vm=None, extra_vm_args=None, extra_polyglot_args=None, env=None): - super(GraalPythonVm, self).__init__(config_name=config_name, cp_suffix=cp_suffix, distributions=distributions, - cp_prefix=cp_prefix, host_vm=host_vm, extra_vm_args=extra_vm_args, - extra_polyglot_args=extra_polyglot_args, env=env) - - def launcher_class(self): - # We need to do it lazily because 'mx_graalpython' is importing this module - from mx_graalpython import GRAALPYTHON_MAIN_CLASS - return GRAALPYTHON_MAIN_CLASS - - def run_in_graalvm(self, cwd, args, extra_polyglot_args, host_vm): - with environ(self._env or {}): - cp = self.get_classpath() - if len(cp) > 0: - extra_polyglot_args.append("--vm.classpath=" + ":".join(cp)) - launcher_name = 'graalpy' - return host_vm.run_launcher(launcher_name, extra_polyglot_args + args, cwd) - - def get_extra_polyglot_args(self): - return ["--experimental-options", "-snapshot-startup", "--python.MaxNativeMemory=%s" % (2**34)] + self._extra_polyglot_args - - -class GraalPythonJavaDriverVm(GraalPythonVmBase): - def __init__(self, config_name=CONFIGURATION_DEFAULT, cp_suffix=None, distributions=None, cp_prefix=None, - host_vm=None, extra_vm_args=None, extra_polyglot_args=None, env=None): - super(GraalPythonJavaDriverVm, self).__init__(config_name=config_name, cp_suffix=cp_suffix, - distributions=['GRAALPYTHON_BENCH'] if not distributions else distributions, - cp_prefix=cp_prefix, host_vm=host_vm, extra_vm_args=extra_vm_args, - extra_polyglot_args=extra_polyglot_args, env=env) + extra_vm_args=self._extra_vm_args, extra_polyglot_args=self._extra_polyglot_args) def launcher_class(self): return 'com.oracle.graal.python.benchmarks.JavaBenchmarkDriver' - def run_in_graalvm(self, cwd, args, extra_polyglot_args, host_vm): - # In GraalVM we run the Java benchmarks driver like one would run any other Java application - # that embeds GraalPython on GraalVM. We need to add the dependencies on class path, and since - # we use run_java, we need to do some output postprocessing that normally run_launcher would do - with environ(self._env or {}): - cp = self.get_classpath() - jhm = mx.dependency("mx:JMH_1_21") - cp_deps = [ - mx.distribution('GRAALPYTHON_BENCH', fatalIfMissing=True), - jhm, - mx.dependency("sdk:LAUNCHER_COMMON") - ] + jhm.deps - cp += [x.classpath_repr() for x in cp_deps] - java_args = ['-cp', ':'.join(cp)] + [self.launcher_class()] - out = mx.TeeOutputCapture(mx.OutputCapture()) - code = host_vm.run_java(java_args + extra_polyglot_args + args, cwd=cwd, out=out, err=out) - out = out.underlying.data - dims = host_vm.dimensions(cwd, args, code, out) - return code, out, dims + def run(self, cwd, args): + extra_polyglot_args = self.get_extra_polyglot_args() + host_vm = self.host_vm() + cp = self.get_classpath() + jhm = mx.dependency("mx:JMH_1_21") + cp_deps = mx.classpath_entries(filter(None, [ + mx.distribution('GRAALPYTHON_BENCH', fatalIfMissing=True), + mx.distribution('TRUFFLE_RUNTIME', fatalIfMissing=True), + mx.distribution('TRUFFLE_ENTERPRISE', fatalIfMissing=False), + jhm, + mx.dependency("sdk:LAUNCHER_COMMON") + ] + jhm.deps)) + cp += [x.classpath_repr() for x in cp_deps] + java_args = ['-cp', ':'.join(cp)] + [self.launcher_class()] + out = mx.TeeOutputCapture(mx.OutputCapture()) + code = host_vm.run_java(java_args + extra_polyglot_args + args, cwd=cwd, out=out, err=out) + out = out.underlying.data + dims = host_vm.dimensions(cwd, args, code, out) + return code, out, dims def get_extra_polyglot_args(self): - return ["--experimental-options", "--python.MaxNativeMemory=%s" % (2**34)] + self._extra_polyglot_args + return ["--experimental-options", "--python.MaxNativeMemory=%s" % (2**34), *self._extra_polyglot_args] # ---------------------------------------------------------------------------------------------------------------------- @@ -494,7 +406,7 @@ def get_extra_polyglot_args(self): class PythonBaseBenchmarkSuite(VmBenchmarkSuite, AveragingBenchmarkMixin): def __init__(self, name, benchmarks): - super(PythonBaseBenchmarkSuite, self).__init__() + super().__init__() self._checkup = 'GRAALPYTHON_BENCHMARKS_CHECKUP' in os.environ self._name = name self._benchmarks = benchmarks @@ -608,7 +520,8 @@ def name(self): def subgroup(self): return SUBGROUP_GRAAL_PYTHON - def with_branch_and_commit_dict(self, d): + @staticmethod + def with_branch_and_commit_dict(d): """ We run our benchmark from the graalpython directories, but with other suites as primary suites in the CI, so we potentially want to update @@ -690,17 +603,8 @@ def rules(self, output, benchmarks, bm_suite_args): ] def runAndReturnStdOut(self, benchmarks, bmSuiteArgs): - ret_code, out, dims = super(PythonBaseBenchmarkSuite, self).runAndReturnStdOut(benchmarks, bmSuiteArgs) + ret_code, out, dims = super().runAndReturnStdOut(benchmarks, bmSuiteArgs) - # host-vm rewrite rules - def _replace_host_vm(key): - host_vm = dims.get("host-vm") - if host_vm and host_vm.startswith(key): - dims['host-vm'] = key - mx.logv("[DEBUG] replace 'host-vm': '{key}-python' -> '{key}'".format(key=key)) - - _replace_host_vm('graalvm-ce') - _replace_host_vm('graalvm-ee') self.post_run_graph(benchmarks[0], dims['host-vm-config'], dims['guest-vm-config']) if self._checkup: @@ -712,7 +616,7 @@ def run(self, benchmarks, bm_suite_args): if '--checkup' in bm_suite_args: self._checkup = True bm_suite_args.remove('--checkup') - results = super(PythonBaseBenchmarkSuite, self).run(benchmarks, bm_suite_args) + results = super().run(benchmarks, bm_suite_args) self.addAverageAcrossLatestResults(results) return results @@ -824,7 +728,7 @@ def checkup(self, out): class PythonBenchmarkSuite(PythonBaseBenchmarkSuite): def __init__(self, name, bench_path, benchmarks, python_path=None): - super(PythonBenchmarkSuite, self).__init__(name, benchmarks) + super().__init__(name, benchmarks) self._python_path = python_path self._harness_path = HARNESS_PATH self._harness_path = join(SUITE.dir, self._harness_path) @@ -892,7 +796,7 @@ def get_benchmark_suites(cls, benchmarks): class PythonJavaEmbeddingBenchmarkSuite(PythonBaseBenchmarkSuite): def __init__(self, name, bench_path, benchmarks): - super(PythonJavaEmbeddingBenchmarkSuite, self).__init__(name, benchmarks) + super().__init__(name, benchmarks) self._bench_path = bench_path def get_vm_registry(self): @@ -994,8 +898,6 @@ def createCommandLineArgs(self, benchmarks, bmSuiteArgs): dists = ["GRAALPYTHON", "GRAALPYTHON-LAUNCHER"] if mx.suite("tools", fatalIfMissing=False): dists.extend(('CHROMEINSPECTOR', 'TRUFFLE_PROFILER')) - if mx.suite("sulong", fatalIfMissing=False): - dists.append('SULONG_NATIVE') vmArgs += [ "-Dorg.graalvm.language.python.home=%s" % mx.dependency("GRAALPYTHON_GRAALVM_SUPPORT").get_output(), @@ -1031,3 +933,150 @@ def filter_distribution(self, dist): # but by overriding this method we fix that and also get the nice property # that one cannot accidentally run some other JMH benchmarks via this class return dist.name == 'GRAALPYTHON_BENCH' + + +class LiveHeapTracker(mx_benchmark.Tracker): + def __init__(self, bmSuite): + super().__init__(bmSuite) + self.out_file = None + + def map_command(self, cmd): + bench_name = self.bmSuite.currently_running_benchmark() if self.bmSuite else "benchmark" + if self.bmSuite: + bench_name = f"{self.bmSuite.name()}-{bench_name}" + ts = datetime.now().strftime("%Y%m%d-%H%M%S") + jmap_command = mx.get_jdk().exe_path('jmap') + self.out_file = os.path.join(os.getcwd(), f"heap_tracker_{bench_name}_{ts}.txt") + iterations = 3 + return [sys.executable, str(DIR / 'live_heap_tracker.py'), self.out_file, str(iterations), jmap_command, *cmd] + + def get_rules(self, bmSuiteArgs): + return [self.LiveHeapRule(self, bmSuiteArgs)] + + class LiveHeapRule(mx_benchmark.Rule): + def __init__(self, tracker, bmSuiteArgs): + self.tracker = tracker + self.bmSuiteArgs = bmSuiteArgs + + def parse(self, text): + with open(self.tracker.out_file) as f: + heap_mb = [int(line.strip()) / (1024 ** 2) for line in f if line] + os.unlink(self.tracker.out_file) + self.tracker.out_file = None + deciles = statistics.quantiles(heap_mb, n=10) + print(f"Heap size deciles (MiB): {deciles}") + return [ + PythonBaseBenchmarkSuite.with_branch_and_commit_dict({ + "benchmark": self.tracker.bmSuite.currently_running_benchmark(), + "bench-suite": self.tracker.bmSuite.benchSuiteName(self.bmSuiteArgs), + "config.vm-flags": ' '.join(self.tracker.bmSuite.vmArgs(self.bmSuiteArgs)), + "metric.name": "allocated-memory", + "metric.value": deciles[-1], + "metric.unit": "MB", + "metric.type": "numeric", + "metric.score-function": "id", + "metric.better": "lower", + "metric.iteration": 0 + }) + ] + + +class PythonHeapBenchmarkSuite(PythonBaseBenchmarkSuite): + def __init__(self, name, bench_path, benchmarks): + super().__init__(name, benchmarks) + super().register_tracker('live-heap', LiveHeapTracker) + self._bench_path = bench_path + + def get_vm_registry(self): + return python_vm_registry + + def rules(self, output, benchmarks, bm_suite_args): + return [] # Tracker will add a rule + + def register_tracker(self, name, tracker_type): + # We don't want any other trackers + pass + + def createCommandLineArgs(self, benchmarks, bmSuiteArgs): + benchmark = benchmarks[0] + bench_path = os.path.join(self._bench_path, f'{benchmark}.py') + return [*self.vmArgs(bmSuiteArgs), bench_path, *self.runArgs(bmSuiteArgs)] + + def successPatterns(self): + return [] + + def failurePatterns(self): + return [] + + @classmethod + def get_benchmark_suites(cls, benchmarks): + assert isinstance(benchmarks, dict), "benchmarks must be a dict: {suite: [path, {bench: args, ... }], ...}" + return [cls(suite_name, suite_info[0], suite_info[1]) + for suite_name, suite_info in benchmarks.items()] + + +def register_vms(suite, sandboxed_options): + # Other Python VMs: + python_vm_registry.add_vm(CPythonVm(config_name=CONFIGURATION_DEFAULT), suite) + python_vm_registry.add_vm(PyPyVm(config_name=CONFIGURATION_DEFAULT), suite) + # For continuity with old datapoints, provide CPython and PyPy with launcher config_name + python_vm_registry.add_vm(CPythonVm(config_name="launcher"), suite) + python_vm_registry.add_vm(PyPyVm(config_name="launcher"), suite) + + graalpy_vms = [] + + def add_graalpy_vm(name, *extra_polyglot_args): + graalpy_vms.append((name, extra_polyglot_args)) + python_vm_registry.add_vm(GraalPythonVm(config_name=name, extra_polyglot_args=extra_polyglot_args), suite, 10) + + # GraalPy VMs: + add_graalpy_vm(CONFIGURATION_DEFAULT) + add_graalpy_vm(CONFIGURATION_INTERPRETER, '--experimental-options', '--engine.Compilation=false') + add_graalpy_vm(CONFIGURATION_DEFAULT_MULTI, '--experimental-options', '-multi-context') + add_graalpy_vm(CONFIGURATION_INTERPRETER_MULTI, '--experimental-options', '-multi-context', '--engine.Compilation=false') + add_graalpy_vm(CONFIGURATION_DEFAULT_MULTI_TIER, '--experimental-options', '--engine.MultiTier=true') + add_graalpy_vm(CONFIGURATION_SANDBOXED, *sandboxed_options) + add_graalpy_vm(CONFIGURATION_NATIVE) + add_graalpy_vm(CONFIGURATION_NATIVE_INTERPRETER, '--experimental-options', '--engine.Compilation=false') + add_graalpy_vm(CONFIGURATION_SANDBOXED_MULTI, '--experimental-options', '-multi-context', *sandboxed_options) + add_graalpy_vm(CONFIGURATION_NATIVE_MULTI, '--experimental-options', '-multi-context') + add_graalpy_vm(CONFIGURATION_NATIVE_INTERPRETER_MULTI, '--experimental-options', '-multi-context', '--engine.Compilation=false') + add_graalpy_vm(CONFIGURATION_NATIVE_MULTI_TIER, '--experimental-options', '--engine.MultiTier=true') + add_graalpy_vm(CONFIGURATION_PANAMA, '--experimental-options', '--python.UsePanama=true') + + # all of the graalpy vms, but with bc dsl + for name, extra_polyglot_args in graalpy_vms[:]: + add_graalpy_vm(f'{name}-bc-dsl', *['--vm.Dpython.EnableBytecodeDSLInterpreter=true', *extra_polyglot_args]) + + # all of the graalpy vms, but with different numbers of compiler threads + for name, extra_polyglot_args in graalpy_vms[:]: + add_graalpy_vm(f'{name}-1-compiler-threads', *['--engine.CompilerThreads=1', *extra_polyglot_args]) + add_graalpy_vm(f'{name}-3-compiler-threads', *['--engine.CompilerThreads=3', *extra_polyglot_args]) + + # java embedding driver + python_java_embedding_vm_registry.add_vm( + GraalPythonJavaDriverVm(config_name=CONFIGURATION_JAVA_EMBEDDING_MULTI, + extra_polyglot_args=['-multi-context']), suite, 10) + python_java_embedding_vm_registry.add_vm( + GraalPythonJavaDriverVm(config_name=CONFIGURATION_JAVA_EMBEDDING_MULTI_SHARED, + extra_polyglot_args=['-multi-context', '-shared-engine']), suite, 10) + python_java_embedding_vm_registry.add_vm( + GraalPythonJavaDriverVm(config_name=CONFIGURATION_JAVA_EMBEDDING_INTERPRETER_MULTI, + extra_polyglot_args=['-multi-context', '-interpreter']), suite, 10) + python_java_embedding_vm_registry.add_vm( + GraalPythonJavaDriverVm(config_name=CONFIGURATION_JAVA_EMBEDDING_INTERPRETER_MULTI_SHARED, + extra_polyglot_args=['-multi-context', '-interpreter', '-shared-engine']), suite, 10) + + +def register_suites(): + from mx_graalpython_bench_param import BENCHMARKS, JAVA_DRIVER_BENCHMARKS, WARMUP_BENCHMARKS, HEAP_BENCHMARKS + + for py_bench_suite in PythonBenchmarkSuite.get_benchmark_suites(BENCHMARKS): + mx_benchmark.add_bm_suite(py_bench_suite) + for py_bench_suite in PythonJavaEmbeddingBenchmarkSuite.get_benchmark_suites(JAVA_DRIVER_BENCHMARKS): + mx_benchmark.add_bm_suite(py_bench_suite) + for py_bench_suite in PythonVmWarmupBenchmarkSuite.get_benchmark_suites(WARMUP_BENCHMARKS): + mx_benchmark.add_bm_suite(py_bench_suite) + mx_benchmark.add_bm_suite(PythonJMHDistMxBenchmarkSuite()) + for py_bench_suite in PythonHeapBenchmarkSuite.get_benchmark_suites(HEAP_BENCHMARKS): + mx_benchmark.add_bm_suite(py_bench_suite) diff --git a/mx.graalpython/mx_graalpython_python_benchmarks.py b/mx.graalpython/mx_graalpython_python_benchmarks.py index af37b0bcef..19a5985314 100644 --- a/mx.graalpython/mx_graalpython_python_benchmarks.py +++ b/mx.graalpython/mx_graalpython_python_benchmarks.py @@ -46,10 +46,9 @@ import os import re import shutil -import subprocess import sys -from os.path import join, abspath, exists +from os.path import join, abspath SUITE = None @@ -372,121 +371,6 @@ def parse(self, text: str) -> list: return r -class GraalPyVm(mx_benchmark.GuestVm): - def __init__(self, config_name, options, host_vm=None): - super(GraalPyVm, self).__init__(host_vm=host_vm) - self._config_name = config_name - self._options = options - - def name(self): - return "graalpython" - - def config_name(self): - return self._config_name - - def hosting_registry(self): - return mx_benchmark.java_vm_registry - - def with_host_vm(self, host_vm): - return self.__class__(self.config_name(), self._options, host_vm) - - def run(self, cwd, args): - for arg in args: - if "--vm.Xmx" in arg: - mx.log(f"Setting Xmx from {arg}") - break - else: - xmxArg = "--vm.Xmx8G" - mx.log(f"Setting Xmx as {xmxArg}") - args.insert(0, xmxArg) - try: - old_gp_arg = os.environ.get("GRAAL_PYTHON_ARGS") - if old_gp_arg: - os.environ["GRAAL_PYTHON_ARGS"] = old_gp_arg + " " + xmxArg - else: - os.environ["GRAAL_PYTHON_ARGS"] = xmxArg - old_java_opts = os.environ.get("JAVA_OPTS") - if old_java_opts: - os.environ["JAVA_OPTS"] = old_java_opts + " " + xmxArg.replace("--vm", "-") - else: - os.environ["JAVA_OPTS"] = xmxArg.replace("--vm.", "-") - mx.log("Running with `JAVA_OPTS={JAVA_OPTS}` and `GRAAL_PYTHON_ARGS={GRAAL_PYTHON_ARGS}`".format(**os.environ)) - return self.host_vm().run_launcher("graalpy", self._options + args, cwd) - finally: - if old_java_opts: - os.environ["JAVA_OPTS"] = old_java_opts - else: - del os.environ["JAVA_OPTS"] - if old_gp_arg: - os.environ["GRAAL_PYTHON_ARGS"] = old_gp_arg - else: - del os.environ["GRAAL_PYTHON_ARGS"] - - -class PyPyVm(mx_benchmark.Vm): - def config_name(self): - return "launcher" - - def name(self): - return "pypy" - - def interpreter(self): - home = mx.get_env("PYPY_HOME") - if not home: - try: - return ( - subprocess.check_output("which pypy3", shell=True).decode().strip() - ) - except OSError: - mx.abort("{} is not set!".format("PYPY_HOME")) - return join(home, "bin", "pypy3") - - def run(self, cwd, args): - env = os.environ.copy() - xmxArg = re.compile("--vm.Xmx([0-9]+)([kKgGmM])") - pypyGcMax = "8GB" - for idx, arg in enumerate(args): - if m := xmxArg.search(arg): - args = args[:idx] + args[idx + 1 :] - pypyGcMax = f"{m.group(1)}{m.group(2).upper()}B" - mx.log(f"Setting PYPY_GC_MAX={pypyGcMax} via {arg}") - break - else: - mx.log( - f"Setting PYPY_GC_MAX={pypyGcMax}, use --vm.Xmx argument to override it" - ) - env["PYPY_GC_MAX"] = pypyGcMax - return mx.run([self.interpreter()] + args, cwd=cwd, env=env) - - -class Python3Vm(mx_benchmark.Vm): - def config_name(self): - return "launcher" - - def name(self): - return "cpython" - - def interpreter(self): - home = mx.get_env("PYTHON3_HOME") - if not home: - return sys.executable - if exists(exe := join(home, "bin", "python3")): - return exe - elif exists(exe := join(home, "python3")): - return exe - elif exists(exe := join(home, "python")): - return exe - return join(home, "bin", "python") - - def run(self, cwd, args): - for idx, arg in enumerate(args): - if "--vm.Xmx" in arg: - mx.warn(f"Ignoring {arg}, cannot restrict memory on CPython.") - args = args[:idx] + args[idx + 1 :] - break - return mx.run([self.interpreter()] + args, cwd=cwd) - - class WildcardList: """It is not easy to track for external suites which benchmarks are available, so we just return a wildcard list and assume the caller knows @@ -509,19 +393,7 @@ def __iter__(self): class PySuite(mx_benchmark.TemporaryWorkdirMixin, mx_benchmark.VmBenchmarkSuite): - def runAndReturnStdOut(self, benchmarks, bmSuiteArgs): - ret_code, out, dims = super().runAndReturnStdOut(benchmarks, bmSuiteArgs) - - def _replace_host_vm(old, new): - host_vm = dims.get("host-vm") - if host_vm and old in host_vm: - dims['host-vm'] = host_vm.replace(old, new) - mx.logv(f"[DEBUG] replace 'host-vm': '{host_vm}' -> '{dims['host-vm']}'") - - _replace_host_vm('graalvm-ce-python', 'graalvm-ce') - _replace_host_vm('graalvm-ee-python', 'graalvm-ee') - - return ret_code, out, dims + pass class PyPerformanceSuite(PySuite): @@ -551,6 +423,7 @@ def get_vm_registry(self): def _vmRun(self, vm, workdir, command, benchmarks, bmSuiteArgs): workdir = abspath(workdir) vm_venv = f"{self.name()}-{vm.name()}-{vm.config_name()}" + _, _, vm_dims = vm.run(workdir, ["--version"]) if not hasattr(self, "prepared"): self.prepared = True @@ -603,7 +476,7 @@ def _vmRun(self, vm, workdir, command, benchmarks, bmSuiteArgs): mx.log(f"Return code of benchmark harness: {retcode}") shutil.copy(join(workdir, json_file), join(SUITE.dir, "raw_results.json")) shutil.copy(join(workdir, json_file_memory), join(SUITE.dir, "raw_results_memory.json")) - return retcode, ",".join([join(workdir, json_file), join(workdir, json_file_memory)]) + return retcode, ",".join([join(workdir, json_file), join(workdir, json_file_memory)]), vm_dims class PyPySuite(PySuite): @@ -633,6 +506,7 @@ def get_vm_registry(self): def _vmRun(self, vm, workdir, command, benchmarks, bmSuiteArgs): workdir = abspath(workdir) vm_venv = f"{self.name()}-{vm.name()}-{vm.config_name()}" + _, _, vm_dims = vm.run(workdir, ["--version"]) if not hasattr(self, "prepared"): self.prepared = True @@ -684,11 +558,11 @@ def _vmRun(self, vm, workdir, command, benchmarks, bmSuiteArgs): ) shutil.copy(join(workdir, json_file), join(SUITE.dir, "raw_results.json")) mx.log(f"Return code of benchmark harness: {retcode}") - return retcode, join(workdir, json_file) + return retcode, join(workdir, json_file), vm_dims class NumPySuite(PySuite): - VERSION = "v1.26.4" + VERSION = "1.26.4" BENCHMARK_REQ = [ "asv==0.5.1", @@ -726,6 +600,7 @@ def _vmRun(self, vm, workdir, command, benchmarks, bmSuiteArgs): workdir = abspath(workdir) benchdir = join(workdir, "numpy", "benchmarks") vm_venv = f"{self.name()}-{vm.name()}-{vm.config_name()}" + _, _, vm_dims = vm.run(workdir, ["--version"]) if not hasattr(self, "prepared"): self.prepared = True @@ -742,7 +617,7 @@ def _vmRun(self, vm, workdir, command, benchmarks, bmSuiteArgs): "1", "https://github.com/numpy/numpy.git", "--branch", - self.VERSION, + f"v{self.VERSION}", "--single-branch", ], cwd=workdir, @@ -774,7 +649,7 @@ def _vmRun(self, vm, workdir, command, benchmarks, bmSuiteArgs): "-e", "--python=same", "--set-commit-hash", - self.VERSION, + f"v{self.VERSION}", "-b", create_asv_benchmark_selection(benchmarks, skipped=SKIPPED_NUMPY_BENCHMARKS), ], cwd=benchdir, @@ -786,9 +661,9 @@ def _vmRun(self, vm, workdir, command, benchmarks, bmSuiteArgs): if json_file: json_file = json_file[0] shutil.copy(json_file, join(SUITE.dir, "raw_results.json")) - return retcode, json_file + return retcode, json_file, vm_dims else: - return -1, "" + return -1, "", vm_dims class PandasSuite(PySuite): @@ -835,6 +710,7 @@ def _vmRun(self, vm, workdir, command, benchmarks, bmSuiteArgs): workdir = abspath(workdir) benchdir = join(workdir, "pandas", "asv_bench") vm_venv = f"{self.name()}-{vm.name()}-{vm.config_name()}" + _, _, vm_dims = vm.run(workdir, ["--version"]) if not hasattr(self, "prepared"): self.prepared = True @@ -913,9 +789,9 @@ def _vmRun(self, vm, workdir, command, benchmarks, bmSuiteArgs): if json_file: json_file = json_file[0] shutil.copy(json_file, join(SUITE.dir, "raw_results.json")) - return retcode, json_file + return retcode, json_file, vm_dims else: - return -1, "" + return -1, "", vm_dims def register_python_benchmarks(): @@ -924,16 +800,8 @@ def register_python_benchmarks(): from mx_graalpython_benchmark import python_vm_registry as vm_registry python_vm_registry = vm_registry - SUITE = mx.suite("graalpython") - python_vm_registry.add_vm(PyPyVm()) - python_vm_registry.add_vm(Python3Vm()) - for config_name, options, priority in [ - ("launcher", [], 5), - ]: - python_vm_registry.add_vm(GraalPyVm(config_name, options), SUITE, priority) - mx_benchmark.add_bm_suite(PyPerformanceSuite()) mx_benchmark.add_bm_suite(PyPySuite()) mx_benchmark.add_bm_suite(NumPySuite()) diff --git a/mx.graalpython/native-ce b/mx.graalpython/native-ce new file mode 100644 index 0000000000..391de960db --- /dev/null +++ b/mx.graalpython/native-ce @@ -0,0 +1,5 @@ +DYNAMIC_IMPORTS=/tools,/compiler,/substratevm +BUILD_TARGETS=GRAALPY_NATIVE_STANDALONE +COMPONENTS=SubstrateVM,Truffle SVM Macro +NATIVE_IMAGES=lib:pythonvm +GRAALVM_SKIP_ARCHIVE=true diff --git a/mx.graalpython/native-ee b/mx.graalpython/native-ee new file mode 100644 index 0000000000..b6f1526c30 --- /dev/null +++ b/mx.graalpython/native-ee @@ -0,0 +1,5 @@ +DYNAMIC_IMPORTS=/tools,/graal-enterprise,/truffle-enterprise,/vm-enterprise,/substratevm-enterprise,substratevm-enterprise-gcs +BUILD_TARGETS=GRAALPY_NATIVE_STANDALONE +COMPONENTS=SubstrateVM Enterprise,Truffle SVM Macro Enterprise,suite:substratevm-enterprise-gcs +NATIVE_IMAGES=lib:pythonvm +GRAALVM_SKIP_ARCHIVE=true diff --git a/mx.graalpython/native-ee-aux b/mx.graalpython/native-ee-aux new file mode 100644 index 0000000000..afe2e09872 --- /dev/null +++ b/mx.graalpython/native-ee-aux @@ -0,0 +1,7 @@ +DYNAMIC_IMPORTS=/tools,/graal-enterprise,/truffle-enterprise,/vm-enterprise,/substratevm-enterprise +BUILD_TARGETS=GRAALPY_NATIVE_STANDALONE +COMPONENTS=SubstrateVM Enterprise,Truffle SVM Macro Enterprise +NATIVE_IMAGES=lib:pythonvm +EXTRA_IMAGE_BUILDER_ARGUMENTS=pythonvm:-H:+AuxiliaryEngineCache pythonvm:-H:ReservedAuxiliaryImageBytes=1073741824 +NATIVE_IMAGE_AUXILIARY_ENGINE_CACHE=true +GRAALVM_SKIP_ARCHIVE=true diff --git a/mx.graalpython/native-image.properties b/mx.graalpython/native-image.properties index 81c5b0d544..0764a3e689 100644 --- a/mx.graalpython/native-image.properties +++ b/mx.graalpython/native-image.properties @@ -1,6 +1,6 @@ # This file contains native-image arguments needed to build graalpython -Requires = language:regex language:llvm language:nfi language:xz +Requires = language:regex language:nfi language:xz JavaArgs = -Dpolyglot.image-build-time.PreinitializeContexts=python \ --add-exports org.graalvm.nativeimage/org.graalvm.nativeimage.impl=ALL-UNNAMED diff --git a/mx.graalpython/pyrightconfig.json b/mx.graalpython/pyrightconfig.json new file mode 100644 index 0000000000..c1fef0a8ae --- /dev/null +++ b/mx.graalpython/pyrightconfig.json @@ -0,0 +1,5 @@ +{ + "extraPaths": [ + "../../mx/src/" + ] +} diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index ebdc42a3e9..7ef36c1213 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -5,7 +5,7 @@ # METADATA # # -------------------------------------------------------------------------------------------------------------- - "mxversion": "7.33.0", + "mxversion": "7.45.0", "name": "graalpython", "versionConflictResolution": "latest", @@ -37,7 +37,7 @@ "suites": [ { "name": "truffle", - "versionFrom": "sulong", + "versionFrom": "regex", "subdir": True, "urls": [ {"url": "https://github.com/oracle/graal", "kind": "git"}, @@ -45,7 +45,7 @@ }, { "name": "sdk", - "version": "f3b5ff623b69e2904057365ebb934dc567e48e76", + "versionFrom": "truffle", "subdir": True, "urls": [ {"url": "https://github.com/oracle/graal", "kind": "git"}, @@ -53,23 +53,15 @@ }, { "name": "tools", - "version": "f3b5ff623b69e2904057365ebb934dc567e48e76", + "version": "69f10d3d658a6aeca3d5ce59c64af6a18336f14c", "subdir": True, "urls": [ {"url": "https://github.com/oracle/graal", "kind": "git"}, ], }, - { - "name": "sulong", - "version": "f3b5ff623b69e2904057365ebb934dc567e48e76", - "subdir": True, - "urls": [ - {"url": "https://github.com/oracle/graal", "kind": "git"}, - ] - }, { "name": "regex", - "version": "f3b5ff623b69e2904057365ebb934dc567e48e76", + "version": "69f10d3d658a6aeca3d5ce59c64af6a18336f14c", "subdir": True, "urls": [ {"url": "https://github.com/oracle/graal", "kind": "git"}, @@ -218,24 +210,6 @@ ], }, - "com.oracle.graal.python.hpy.llvm": { - "type": "python", - "path": "graalpython/com.oracle.graal.python.hpy.llvm", - "source": [ - "include", - "src", - ], - }, - - "com.oracle.graal.python.jni": { - "type": "python", - "path": "graalpython/com.oracle.graal.python.jni", - "source": [ - "include", - "src", - ], - }, - "python-liblzma": { "type": "python", "path": "graalpython/python-liblzma", @@ -376,7 +350,7 @@ "com.oracle.graal.python.frozen": { "subDir": "graalpython", "vpath": True, - "type": "GraalpythonProject", + "type": "GraalpythonFrozenProject", "args": [ "/freeze_modules.py", "--python-lib", @@ -388,16 +362,31 @@ ], "platformDependent": False, "buildDependencies": [ - # a bit ugly, we need the same dist dependencies as the full GRAALPYTHON dist + python-lib "com.oracle.graal.python", "GRAALPYTHON-LAUNCHER", - "GRAALPYTHON_RESOURCES", - "truffle:TRUFFLE_API", - "tools:TRUFFLE_PROFILER", "regex:TREGEX", - "sdk:POLYGLOT", - "sulong:SULONG_API", - "sulong:SULONG_NATIVE", # this is actually just a runtime dependency + "truffle:TRUFFLE_NFI_LIBFFI", + ], + }, + + # HPy + "hpy": { + "subDir": "graalpython", + "vpath": True, + "type": "GraalpythonProject", + "defaultBuild": False, + "args": [ + "/build.py", + "--out", + "", + "--cflags", + "-I/jni_gen -I/ -I/include", + ], + "platformDependent": True, + "buildDependencies": [ + "com.oracle.graal.python", + "GRAALPYTHON-LAUNCHER", + "regex:TREGEX", ], }, @@ -429,7 +418,6 @@ "truffle:TRUFFLE_NFI", "tools:TRUFFLE_PROFILER", "sdk:POLYGLOT", - "sulong:SULONG_API", "truffle:TRUFFLE_XZ", "truffle:TRUFFLE_ICU4J", "regex:TREGEX", @@ -515,23 +503,6 @@ "testProject": True, }, - "com.oracle.graal.python.hpy.test": { - "subDir": "graalpython", - "sourceDirs": ["src"], - "dependencies": [ - "GRAALPYTHON", - "GRAALPYTHON_NATIVE_LIBS", - ], - "jacoco": "exclude", - "checkstyle": "com.oracle.graal.python", - "javaCompliance": "17+", - "workingSets": "Truffle,Python", - "testProject": True, - "javaProperties": { - "test.graalpython.home": "/graalpython" - }, - }, - # GRAALPYTHON BENCH "com.oracle.graal.python.benchmarks": { "subDir": "graalpython", @@ -615,8 +586,6 @@ }, }, "buildDependencies": [ - "sulong:SULONG_HOME", - "sulong:SULONG_BOOTSTRAP_TOOLCHAIN", "BZIP2", ], "buildEnv": { @@ -677,7 +646,7 @@ "max_jobs": "1", "ninja_targets": ["all"], "cmakeConfig": { - "GRAALPY_VERSION": "", + "GRAALPY_VERSION": "", "GRAALPY_VERSION_NUM": "", }, "results": [ @@ -688,7 +657,6 @@ "com.oracle.graal.python.cext": { "subDir": "graalpython", "class": "CMakeNinjaProject", - "toolchain": "sulong:SULONG_BOOTSTRAP_TOOLCHAIN", "max_jobs": "8", "vpath": True, "use_jdk_headers": True, # not actually, just making mx happy @@ -700,21 +668,18 @@ "cmakeConfig": { "CAPI_INC_DIR": "/jni_gen", "PYCONFIG_INCLUDE_DIR": "/", - "GRAALVM_LLVM_LIB_DIR": "/native/lib", - "TRUFFLE_H_INC": "/include", "TRUFFLE_NFI_H_INC": "/include", - "CMAKE_C_COMPILER": "", "GRAALPY_PARENT_DIR": "", - "GRAALPY_EXT": "", + "GRAALPY_EXT": "", }, "results": [ "bin/", "bin/python-native.lib", - "bin/modules/_sqlite3", - "bin/modules/_cpython_sre", - "bin/modules/_cpython_unicodedata", - "bin/modules/_sha3", - "bin/modules/pyexpat", + "bin/modules/_sqlite3", + "bin/modules/_cpython_sre", + "bin/modules/_cpython_unicodedata", + "bin/modules/_sha3", + "bin/modules/pyexpat", ], }, }, @@ -723,132 +688,32 @@ "cmakeConfig": { "CAPI_INC_DIR": "/jni_gen", "PYCONFIG_INCLUDE_DIR": "/", - "TRUFFLE_H_INC": "/include", "TRUFFLE_NFI_H_INC": "/include", - "CMAKE_C_COMPILER": "", "GRAALPY_PARENT_DIR": "", - "GRAALPY_EXT": "", + "GRAALPY_EXT": "", }, "results": [ "bin/", - "bin/modules/_sqlite3", - "bin/modules/_cpython_sre", - "bin/modules/_cpython_unicodedata", - "bin/modules/_sha3", - "bin/modules/_testcapi", - "bin/modules/_testbuffer", - "bin/modules/_testmultiphase", - "bin/modules/_ctypes_test", - "bin/modules/pyexpat", - "bin/modules/termios", + "bin/modules/_sqlite3", + "bin/modules/_cpython_sre", + "bin/modules/_cpython_unicodedata", + "bin/modules/_sha3", + "bin/modules/_testcapi", + "bin/modules/_testbuffer", + "bin/modules/_testmultiphase", + "bin/modules/_ctypes_test", + "bin/modules/pyexpat", + "bin/modules/termios", ], }, }, }, "buildDependencies": [ - "sulong:SULONG_HOME", - "sulong:SULONG_BOOTSTRAP_TOOLCHAIN", - "sulong:SULONG_LEGACY", "graalpy-pyconfig", "com.oracle.graal.python", ], }, - "com.oracle.graal.python.hpy.llvm": { - "subDir": "graalpython", - "class": "CMakeNinjaProject", - "toolchain": "sulong:SULONG_BOOTSTRAP_TOOLCHAIN", - "max_jobs": "8", - "vpath": True, - "ninja_targets": [ - "", - ], - "ninja_install_targets": ["install"], - "results": [ - "bin/", - ], - "buildDependencies": [ - "graalpy-pyconfig", - "sulong:SULONG_HOME", - "sulong:SULONG_BOOTSTRAP_TOOLCHAIN", - "sulong:SULONG_LEGACY", - ], - "os_arch": { - "windows": { - "": { - "cmakeConfig": { - "PYCONFIG_INCLUDE_DIR": "/", - "GRAALVM_LLVM_LIB_DIR": "/native/lib", - "GRAALVM_HPY_INCLUDE_DIR": "/include", - "GRAALVM_PYTHON_INCLUDE_DIR": "/include", - "TRUFFLE_H_INC": "/include", - "CMAKE_C_COMPILER": "", - "GRAALPY_PARENT_DIR": "", - }, - }, - }, - "": { - "": { - "cmakeConfig": { - "PYCONFIG_INCLUDE_DIR": "/", - "GRAALVM_HPY_INCLUDE_DIR": "/include", - "GRAALVM_PYTHON_INCLUDE_DIR": "/include", - "TRUFFLE_H_INC": "/include", - "CMAKE_C_COMPILER": "", - "GRAALPY_PARENT_DIR": "", - }, - }, - }, - }, - }, - - "com.oracle.graal.python.jni": { - "dir": "graalpython/com.oracle.graal.python.jni", - "native": "shared_lib", - "deliverable": "pythonjni", - "buildDependencies": [ - "graalpy-pyconfig", - "com.oracle.graal.python", # for the generated JNI header file - ], - "use_jdk_headers": True, # the generated JNI header includes jni.h - "ldlibs": [ - "-lm" - ], - "os_arch": { - "windows": { - "": { - "cflags": [ - "-DHPY_ABI_HYBRID", "-DHPY_EMBEDDED_MODULES", "-DNDEBUG", "-DMS_WINDOWS", - # cflags equivalent to -O3 -Wall (/W3, could be /Wall) -Werror (/WX) - "-D_CRT_SECURE_NO_WARNINGS", "/O2", "/W3", "/WX", - "-I\"/include\"", - "-I\"/include/internal\"", - "-I\"/src\"", - "-I\"/include\"", - "-I\"/src\"", - "-I\"/include\"", - "-I\"/\"", - ], - }, - }, - "": { - "": { - "cflags": [ - "-DHPY_ABI_HYBRID", "-DHPY_EMBEDDED_MODULES", "-DNDEBUG", - "-O3", "-Wall", "-Werror", "-fPIC", - "-I\"/include\"", - "-I\"/include/internal\"", - "-I\"/src\"", - "-I\"/include\"", - "-I\"/src\"", - "-I\"/include\"", - "-I\"/\"", - ], - }, - }, - }, - }, - "python-libzsupport": { "subDir": "graalpython", "native": "shared_lib", @@ -928,6 +793,56 @@ "ignorePatterns": [], "license": ["PSF-License"], }, + + "graalpy_licenses": { + "class": "StandaloneLicenses", + "community_license_file": "LICENSE.txt", + "community_3rd_party_license_file": "THIRD_PARTY_LICENSE.txt", + }, + + "graalpy_thin_launcher": { + "class": "ThinLauncherProject", + "mainClass": "com.oracle.graal.python.shell.GraalPythonMain", + "jar_distributions": ["graalpython:GRAALPYTHON-LAUNCHER"], + "relative_home_paths": { + "python": "..", + }, + "relative_jre_path": "../jvm", + "relative_module_path": "../modules", + "relative_extracted_lib_paths": { + "truffle.attach.library": "../jvmlibs/", + "truffle.nfi.library": "../jvmlibs/", + }, + "liblang_relpath": "../lib/", + "default_vm_args": [ + "--vm.Xss16777216", # request 16M of stack + ], + }, + + "libpythonvm": { + "class": "LanguageLibraryProject", + "dependencies": [ + "GRAALPY_STANDALONE_DEPENDENCIES", + ], + "buildDependencies": [ + "GRAALPY_STANDALONE_COMMON", + ], + "build_args": [ + # From mx.graalpython/native-image.properties + "-Dpolyglot.image-build-time.PreinitializeContexts=python", + "--add-exports", "org.graalvm.nativeimage/org.graalvm.nativeimage.impl=ALL-UNNAMED", + "-R:StackSize=16777216", + "-H:+AddAllCharsets", + "-H:IncludeLocales=no,be,ro,ru,es,se,in,ka,hu,hr,bg,is,mk,da,nn,cs,sq,fr,pl,fo,bs,kl,fa,sv,it,uk,af,tg,ps,de", + # Configure launcher + "-Dorg.graalvm.launcher.class=com.oracle.graal.python.shell.GraalPythonMain", + # GraalPy standalone specific flags + "-J-Xms14g", # GR-46399: libpythonvm needs more than the default minimum of 8 GB to be built + "-Dpolyglot.python.PosixModuleBackend=native", + "-Dpolyglot.python.Sha3ModuleBackend=native", + "", + ], + }, }, "licenses": { @@ -968,7 +883,6 @@ "name": "org.graalvm.python.embedding", "exports": [ "org.graalvm.python.embedding", - "org.graalvm.python.embedding.utils", ] }, "useModulePath": True, @@ -1071,9 +985,7 @@ "": { "layout": { "//": [ - "dependency:com.oracle.graal.python.jni/*", "dependency:com.oracle.graal.python.cext/bin/*", - "dependency:com.oracle.graal.python.hpy.llvm/bin/*", "dependency:python-libbz2/bin/*", ] }, @@ -1083,11 +995,9 @@ "": { "layout": { "//": [ - "dependency:com.oracle.graal.python.jni/*", "dependency:com.oracle.graal.python.cext/bin/*", "dependency:python-libzsupport/*", "dependency:python-libposix/*", - "dependency:com.oracle.graal.python.hpy.llvm/bin/*", "dependency:python-libbz2/bin/*", "dependency:python-liblzma/bin/*", ] @@ -1147,9 +1057,6 @@ "exports": [ "com.oracle.graal.python.* to org.graalvm.py.enterprise", ], - "uses": [ - "com.oracle.graal.python.builtins.PythonBuiltins", - ], }, "useModulePath": True, "dependencies": [ @@ -1166,7 +1073,6 @@ "sdk:COLLECTIONS", "truffle:TRUFFLE_NFI", "truffle:TRUFFLE_NFI_LIBFFI", # runtime dependency for convenience - "sulong:SULONG_API", "truffle:TRUFFLE_ICU4J", "truffle:TRUFFLE_XZ", ], @@ -1184,7 +1090,7 @@ "BOUNCYCASTLE-UTIL", ], "javaProperties": { - "python.jni.library": "" + # "python.jni.library": "" }, "description": "GraalPy, a high-performance embeddable Python 3 runtime for Java. This artifact includes the core language runtime without standard libraries. It is not recommended to depend on the artifact directly. Instead, use \'org.graalvm.polyglot:python\' or \'org.graalvm.polyglot:python-community\' to ensure all dependencies are pulled in correctly.", "maven": { @@ -1207,7 +1113,7 @@ "GRAALPYTHON_RESOURCES", "truffle:TRUFFLE_RUNTIME", ], - "description": "GraalPy, a high-performance embeddable Python 3 runtime for Java. This POM dependency pulls in GraalPy dependencies and Truffle Community Edition.", + "description": "GraalPy, a high-performance embeddable Python 3 runtime for Java. This POM dependency includes GraalPy dependencies and Truffle Community Edition.", "maven": { "groupId": "org.graalvm.python", "artifactId": "python-community", @@ -1240,7 +1146,6 @@ "GRAALPYTHON", "GRAALPYTHON-LAUNCHER", "GRAALPYTHON_EMBEDDING_TOOLS", # See MultiContextCExtTest - "sulong:SULONG_NATIVE", # See MultiContextTest#testSharingWithStruct "truffle:TRUFFLE_TCK", "GRAALPYTHON_INTEGRATION_UNIT_TESTS", ], @@ -1259,7 +1164,6 @@ "GRAALPYTHON", "GRAALPYTHON_RESOURCES", "GRAALPYTHON_EMBEDDING", - "sulong:SULONG_NATIVE", # See MultiContextTest#testSharingWithStruct "sdk:GRAAL_SDK", ], "testDistribution": True, @@ -1356,7 +1260,7 @@ "maven": False, }, - # The Python and HPy headers. These go to "/include" on windows and + # The Python headers. These go to "/include" on windows and # "/include/python" on unix "GRAALPYTHON_INCLUDE_RESOURCES": { "native": False, @@ -1369,7 +1273,6 @@ "./META-INF/resources/include/": [ "dependency:graalpy-pyconfig/pyconfig.h", "file:graalpython/com.oracle.graal.python.cext/include/*", - "file:graalpython/com.oracle.graal.python.hpy.llvm/include/*", ], }, "maven": False, @@ -1514,6 +1417,105 @@ "maven": False, }, + "GRAALPY_STANDALONE_DEPENDENCIES": { + "description": "GraalPy standalone dependencies", + "class": "DynamicPOMDistribution", + "distDependencies": [ + "graalpython:GRAALPYTHON-LAUNCHER", + "graalpython:GRAALPYTHON", + "graalpython:BOUNCYCASTLE-PROVIDER", + "graalpython:BOUNCYCASTLE-PKIX", + "graalpython:BOUNCYCASTLE-UTIL", + "sdk:TOOLS_FOR_STANDALONE", + ], + "dynamicDistDependencies": "graalpy_standalone_deps", + "maven": False, + }, + + "GRAALPY_STANDALONE_COMMON": { + "description": "Common base layout for Native and JVM standalones", + "type": "dir", + "platformDependent": True, + "platforms": "local", + "layout": { + "./": [ + "extracted-dependency:GRAALPYTHON_GRAALVM_SUPPORT", + "extracted-dependency:GRAALPYTHON_GRAALVM_DOCS", + "extracted-dependency:GRAALPY_VIRTUALENV_SEEDER", + "dependency:graalpy_licenses/*", + ], + "bin/": "dependency:graalpy_thin_launcher", + "bin/": "dependency:graalpy_thin_launcher", + "bin/": "dependency:graalpy_thin_launcher", + "libexec/": "dependency:graalpy_thin_launcher", + "release": "dependency:sdk:STANDALONE_JAVA_HOME/release", + }, + }, + + "GRAALPY_NATIVE_STANDALONE": { + "description": "GraalPy Native standalone", + "type": "dir", + "platformDependent": True, + "platforms": "local", + "layout": { + "./": [ + "dependency:GRAALPY_STANDALONE_COMMON/*", + ], + "lib/": "dependency:libpythonvm", + }, + }, + + "GRAALPY_JVM_STANDALONE": { + "description": "GraalPy JVM standalone", + "type": "dir", + "platformDependent": True, + "platforms": "local", + "layout": { + "./": [ + "dependency:GRAALPY_STANDALONE_COMMON/*", + ], + "jvm/": { + "source_type": "dependency", + "dependency": "sdk:STANDALONE_JAVA_HOME", + "path": "*", + "exclude": [ + # Native Image-related + "bin/native-image*", + "lib/static", + "lib/svm", + "lib/", + "lib/", + # Unnecessary and big + "lib/src.zip", + "jmods", + ], + }, + "jvmlibs/": [ + "extracted-dependency:truffle:TRUFFLE_ATTACH_GRAALVM_SUPPORT", + "extracted-dependency:truffle:TRUFFLE_NFI_NATIVE_GRAALVM_SUPPORT", + ], + "modules/": [ + "classpath-dependencies:GRAALPY_STANDALONE_DEPENDENCIES", + ], + }, + }, + + "GRAALPY_NATIVE_STANDALONE_RELEASE_ARCHIVE": { + "class": "DeliverableStandaloneArchive", + "platformDependent": True, + "standalone_dist": "GRAALPY_NATIVE_STANDALONE", + "community_archive_name": "graalpy-community", + "enterprise_archive_name": "graalpy", + }, + + "GRAALPY_JVM_STANDALONE_RELEASE_ARCHIVE": { + "class": "DeliverableStandaloneArchive", + "platformDependent": True, + "standalone_dist": "GRAALPY_JVM_STANDALONE", + "community_archive_name": "graalpy-community-jvm", + "enterprise_archive_name": "graalpy-jvm", + }, + "graalpy-archetype-polyglot-app": { "class": "MavenProject", "subDir": "graalpython", diff --git a/mx.graalpython/test_json_parsing_data.py b/mx.graalpython/test_json_parsing_data.py index 168b5f03be..f5078c32b7 100644 --- a/mx.graalpython/test_json_parsing_data.py +++ b/mx.graalpython/test_json_parsing_data.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -44,7 +44,7 @@ PYPERF_INPUT_SINGLE = """ -{"benchmarks":[{"runs":[{"metadata":{"calibrate_loops":1,"date":"2022-08-19 14:43:12.284000","duration":1.5133943570253905,"load_avg_1min":3.48,"runnable_threads":3,"uptime":248948.3410000801},"warmups":[[1,0.2034990079991985],[1,0.6674845249799546],[1,0.21809560799738392],[1,0.21727570798248053]]},{"metadata":{"date":"2022-08-19 14:43:16.922000","duration":1.4495818620198406,"load_avg_1min":3.36,"runnable_threads":2,"uptime":248952.97600007057},"values":[0.6122827270010021,0.21183780900901183,0.23465331000625156],"warmups":[[1,0.19920430800993927]]},{"metadata":{"date":"2022-08-19 14:43:20.961000","duration":1.290273555991007,"load_avg_1min":3.36,"runnable_threads":2,"uptime":248957.01699995995},"values":[0.6467954269901384,0.14579120700364,0.08507430300232954],"warmups":[[1,0.19187260899343528]]},{"metadata":{"date":"2022-08-19 14:43:24.901000","duration":1.2151426489872392,"load_avg_1min":3.25,"runnable_threads":10,"uptime":248960.96499991417},"values":[0.5333167220233008,0.12577070499537513,0.09821140297572128],"warmups":[[1,0.20218100800411776]]},{"metadata":{"date":"2022-08-19 14:43:29.150000","duration":1.3432138439966366,"load_avg_1min":3.07,"runnable_threads":7,"uptime":248965.20600008965},"values":[0.5848380230017938,0.19675420800922439,0.17337670698179863],"warmups":[[1,0.20151760801672935]]},{"metadata":{"date":"2022-08-19 14:43:33.186000","duration":1.2043760640081018,"load_avg_1min":2.98,"runnable_threads":2,"uptime":248969.2809998989},"values":[0.6005827819753904,0.10146239699679427,0.08088209698325954],"warmups":[[1,0.19464509401586838]]},{"metadata":{"date":"2022-08-19 14:43:37.296000","duration":1.3772097550099716,"load_avg_1min":3.31,"runnable_threads":2,"uptime":248973.35400009155},"values":[0.6266321820148733,0.20589119399664924,0.14757319501950406],"warmups":[[1,0.1985264940012712]]},{"metadata":{"date":"2022-08-19 14:43:41.404000","duration":1.1919402469939087,"load_avg_1min":3.31,"runnable_threads":2,"uptime":248977.4579999447},"values":[0.28510188800282776,0.23789468899485655,0.29366678700898774],"warmups":[[1,0.19282549098716117]]},{"metadata":{"date":"2022-08-19 14:43:45.401000","duration":1.2719772529962938,"load_avg_1min":3.6,"runnable_threads":2,"uptime":248981.46000003815},"values":[0.6037096730142366,0.16613589398912154,0.1068304979999084],"warmups":[[1,0.18227749201469123]]},{"metadata":{"date":"2022-08-19 14:43:49.467000","duration":1.320978773990646,"load_avg_1min":3.47,"runnable_threads":2,"uptime":248985.5230000019},"values":[0.5956775880185887,0.17856919698533602,0.1609844969934784],"warmups":[[1,0.18809049599803984]]},{"metadata":{"date":"2022-08-19 14:43:53.471000","duration":1.169618988991715,"load_avg_1min":3.76,"runnable_threads":2,"uptime":248989.52399992943},"values":[0.2995226939965505,0.21542829598183744,0.28052380098961294],"warmups":[[1,0.18820919599966146]]},{"metadata":{"date":"2022-08-19 14:43:57.601000","duration":1.4640219129796606,"load_avg_1min":3.54,"runnable_threads":2,"uptime":248993.66000008583},"values":[0.6062809050199576,0.20838060198002495,0.26318330198409967],"warmups":[[1,0.1994099020084832]]},{"metadata":{"date":"2022-08-19 14:44:02.200000","duration":1.3735116379975807,"load_avg_1min":3.41,"runnable_threads":7,"uptime":248998.257999897},"values":[0.6009430660051294,0.21229795200633816,0.15631846399628557],"warmups":[[1,0.2004223020048812]]},{"metadata":{"date":"2022-08-19 14:44:06.571000","duration":1.4131140270037577,"load_avg_1min":3.41,"runnable_threads":2,"uptime":249002.65000009537},"values":[0.5782643709972035,0.19758390198694542,0.199973103008233],"warmups":[[1,0.2259684489981737]]},{"metadata":{"date":"2022-08-19 14:44:10.895000","duration":1.4828982100007124,"load_avg_1min":3.54,"runnable_threads":3,"uptime":249006.95700001717},"values":[0.6024837039876729,0.18436720099998638,0.21817150100832805],"warmups":[[1,0.26018120200023986]]},{"metadata":{"date":"2022-08-19 14:44:15.244000","duration":1.3325314090179745,"load_avg_1min":3.42,"runnable_threads":2,"uptime":249011.29999995232},"values":[0.5968962039914913,0.1725292009941768,0.18248940099147148],"warmups":[[1,0.18711190100293607]]},{"metadata":{"date":"2022-08-19 14:44:19.428000","duration":1.2289271690242458,"load_avg_1min":3.54,"runnable_threads":2,"uptime":249015.51399993896},"values":[0.5882582850172184,0.11573719698935747,0.09515989801730029],"warmups":[[1,0.2046087950002402]]},{"metadata":{"date":"2022-08-19 14:44:23.513000","duration":1.3189586669905111,"load_avg_1min":3.9,"runnable_threads":2,"uptime":249019.5680000782},"values":[0.6117184849863406,0.18111939501250163,0.11810939700808376],"warmups":[[1,0.2095351949974429]]},{"metadata":{"date":"2022-08-19 14:44:27.739000","duration":1.4485228130070027,"load_avg_1min":3.91,"runnable_threads":2,"uptime":249023.79099988937},"values":[0.6204450630175415,0.19965468798181973,0.2308200859988574],"warmups":[[1,0.21127248700940982]]},{"metadata":{"date":"2022-08-19 14:44:31.864000","duration":1.4313957140257116,"load_avg_1min":3.91,"runnable_threads":2,"uptime":249027.92700004578},"values":[0.6440523619821761,0.18948208901565522,0.19637738799792714],"warmups":[[1,0.20359288700274192]]},{"metadata":{"date":"2022-08-19 14:44:36.076000","duration":1.4206666439713445,"load_avg_1min":4.0,"runnable_threads":2,"uptime":249032.13000011444},"values":[0.634143175004283,0.1954176920116879,0.20625719201052561],"warmups":[[1,0.1949982919904869]]}]}],"metadata":{"aslr":"Full randomization","boot_time":"2022-08-16 17:34:04","cpu_config":"idle:none","cpu_count":16,"cpu_freq":"0-15=2400 MHz","cpu_model_name":"Intel(R) Core(TM) i9-10885H CPU @ 2.40GHz","description":"DeltaBlue benchmark","hostname":"DESKTOP-UOQCHD2","loops":1,"mem_max_rss":48869933056,"name":"deltablue","perf_version":"2.3.0","performance_version":"1.0.5","platform":"Linux-5.15.57.1-microsoft-standard-WSL2-x86_64-with","python_cflags":"-Wno-unused-command-line-argument -stdlib=libc++ -DNDEBUG -DGRAALVM_PYTHON_LLVM -D_GNU_SOURCE=1","python_executable":"/home/tim/Dev/performance/venv/graalpython3.8-f2bc0f304e1c-compat-84ebb708f58d/bin/graalpython","python_implementation":"graalpython","python_version":"3.8.5 (64-bit)","timer":"perf_counter, resolution: 1.00 us","unit":"second"},"version":"1.0"} +{"benchmarks":[{"runs":[{"metadata":{"calibrate_loops":1,"date":"2022-08-19 14:43:12.284000","duration":1.5133943570253905,"load_avg_1min":3.48,"runnable_threads":3,"uptime":248948.3410000801},"warmups":[[1,0.2034990079991985],[1,0.6674845249799546],[1,0.21809560799738392],[1,0.21727570798248053]]},{"metadata":{"date":"2022-08-19 14:43:16.922000","duration":1.4495818620198406,"load_avg_1min":3.36,"runnable_threads":2,"uptime":248952.97600007057},"values":[0.6122827270010021,0.21183780900901183,0.23465331000625156],"warmups":[[1,0.19920430800993927]]},{"metadata":{"date":"2022-08-19 14:43:20.961000","duration":1.290273555991007,"load_avg_1min":3.36,"runnable_threads":2,"uptime":248957.01699995995},"values":[0.6467954269901384,0.14579120700364,0.08507430300232954],"warmups":[[1,0.19187260899343528]]},{"metadata":{"date":"2022-08-19 14:43:24.901000","duration":1.2151426489872392,"load_avg_1min":3.25,"runnable_threads":10,"uptime":248960.96499991417},"values":[0.5333167220233008,0.12577070499537513,0.09821140297572128],"warmups":[[1,0.20218100800411776]]},{"metadata":{"date":"2022-08-19 14:43:29.150000","duration":1.3432138439966366,"load_avg_1min":3.07,"runnable_threads":7,"uptime":248965.20600008965},"values":[0.5848380230017938,0.19675420800922439,0.17337670698179863],"warmups":[[1,0.20151760801672935]]},{"metadata":{"date":"2022-08-19 14:43:33.186000","duration":1.2043760640081018,"load_avg_1min":2.98,"runnable_threads":2,"uptime":248969.2809998989},"values":[0.6005827819753904,0.10146239699679427,0.08088209698325954],"warmups":[[1,0.19464509401586838]]},{"metadata":{"date":"2022-08-19 14:43:37.296000","duration":1.3772097550099716,"load_avg_1min":3.31,"runnable_threads":2,"uptime":248973.35400009155},"values":[0.6266321820148733,0.20589119399664924,0.14757319501950406],"warmups":[[1,0.1985264940012712]]},{"metadata":{"date":"2022-08-19 14:43:41.404000","duration":1.1919402469939087,"load_avg_1min":3.31,"runnable_threads":2,"uptime":248977.4579999447},"values":[0.28510188800282776,0.23789468899485655,0.29366678700898774],"warmups":[[1,0.19282549098716117]]},{"metadata":{"date":"2022-08-19 14:43:45.401000","duration":1.2719772529962938,"load_avg_1min":3.6,"runnable_threads":2,"uptime":248981.46000003815},"values":[0.6037096730142366,0.16613589398912154,0.1068304979999084],"warmups":[[1,0.18227749201469123]]},{"metadata":{"date":"2022-08-19 14:43:49.467000","duration":1.320978773990646,"load_avg_1min":3.47,"runnable_threads":2,"uptime":248985.5230000019},"values":[0.5956775880185887,0.17856919698533602,0.1609844969934784],"warmups":[[1,0.18809049599803984]]},{"metadata":{"date":"2022-08-19 14:43:53.471000","duration":1.169618988991715,"load_avg_1min":3.76,"runnable_threads":2,"uptime":248989.52399992943},"values":[0.2995226939965505,0.21542829598183744,0.28052380098961294],"warmups":[[1,0.18820919599966146]]},{"metadata":{"date":"2022-08-19 14:43:57.601000","duration":1.4640219129796606,"load_avg_1min":3.54,"runnable_threads":2,"uptime":248993.66000008583},"values":[0.6062809050199576,0.20838060198002495,0.26318330198409967],"warmups":[[1,0.1994099020084832]]},{"metadata":{"date":"2022-08-19 14:44:02.200000","duration":1.3735116379975807,"load_avg_1min":3.41,"runnable_threads":7,"uptime":248998.257999897},"values":[0.6009430660051294,0.21229795200633816,0.15631846399628557],"warmups":[[1,0.2004223020048812]]},{"metadata":{"date":"2022-08-19 14:44:06.571000","duration":1.4131140270037577,"load_avg_1min":3.41,"runnable_threads":2,"uptime":249002.65000009537},"values":[0.5782643709972035,0.19758390198694542,0.199973103008233],"warmups":[[1,0.2259684489981737]]},{"metadata":{"date":"2022-08-19 14:44:10.895000","duration":1.4828982100007124,"load_avg_1min":3.54,"runnable_threads":3,"uptime":249006.95700001717},"values":[0.6024837039876729,0.18436720099998638,0.21817150100832805],"warmups":[[1,0.26018120200023986]]},{"metadata":{"date":"2022-08-19 14:44:15.244000","duration":1.3325314090179745,"load_avg_1min":3.42,"runnable_threads":2,"uptime":249011.29999995232},"values":[0.5968962039914913,0.1725292009941768,0.18248940099147148],"warmups":[[1,0.18711190100293607]]},{"metadata":{"date":"2022-08-19 14:44:19.428000","duration":1.2289271690242458,"load_avg_1min":3.54,"runnable_threads":2,"uptime":249015.51399993896},"values":[0.5882582850172184,0.11573719698935747,0.09515989801730029],"warmups":[[1,0.2046087950002402]]},{"metadata":{"date":"2022-08-19 14:44:23.513000","duration":1.3189586669905111,"load_avg_1min":3.9,"runnable_threads":2,"uptime":249019.5680000782},"values":[0.6117184849863406,0.18111939501250163,0.11810939700808376],"warmups":[[1,0.2095351949974429]]},{"metadata":{"date":"2022-08-19 14:44:27.739000","duration":1.4485228130070027,"load_avg_1min":3.91,"runnable_threads":2,"uptime":249023.79099988937},"values":[0.6204450630175415,0.19965468798181973,0.2308200859988574],"warmups":[[1,0.21127248700940982]]},{"metadata":{"date":"2022-08-19 14:44:31.864000","duration":1.4313957140257116,"load_avg_1min":3.91,"runnable_threads":2,"uptime":249027.92700004578},"values":[0.6440523619821761,0.18948208901565522,0.19637738799792714],"warmups":[[1,0.20359288700274192]]},{"metadata":{"date":"2022-08-19 14:44:36.076000","duration":1.4206666439713445,"load_avg_1min":4.0,"runnable_threads":2,"uptime":249032.13000011444},"values":[0.634143175004283,0.1954176920116879,0.20625719201052561],"warmups":[[1,0.1949982919904869]]}]}],"metadata":{"aslr":"Full randomization","boot_time":"2022-08-16 17:34:04","cpu_config":"idle:none","cpu_count":16,"cpu_freq":"0-15=2400 MHz","cpu_model_name":"Intel(R) Core(TM) i9-10885H CPU @ 2.40GHz","description":"DeltaBlue benchmark","hostname":"DESKTOP-UOQCHD2","loops":1,"mem_max_rss":48869933056,"name":"deltablue","perf_version":"2.3.0","performance_version":"1.0.5","platform":"Linux-5.15.57.1-microsoft-standard-WSL2-x86_64-with","python_cflags":"-Wno-unused-command-line-argument -stdlib=libc++ -DNDEBUG -D_GNU_SOURCE=1","python_executable":"/home/tim/Dev/performance/venv/graalpython3.8-f2bc0f304e1c-compat-84ebb708f58d/bin/graalpython","python_implementation":"graalpython","python_version":"3.8.5 (64-bit)","timer":"perf_counter, resolution: 1.00 us","unit":"second"},"version":"1.0"} """ diff --git a/mx.graalpython/verify_patches.py b/mx.graalpython/verify_patches.py index 1ebc371694..8aa4e84c10 100644 --- a/mx.graalpython/verify_patches.py +++ b/mx.graalpython/verify_patches.py @@ -1,4 +1,4 @@ -# Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -45,6 +45,7 @@ # Approved license identifiers in SPDX "short identifier" format ALLOWED_LICENSES = { + 'UPL', # https://spdx.org/licenses/UPL-1.0.html 'MIT', # https://spdx.org/licenses/MIT.html 'BSD-3-Clause', # https://spdx.org/licenses/BSD-3-Clause.html 'BSD-2-Clause', # https://spdx.org/licenses/BSD-2-Clause.html diff --git a/scripts/gen_native_cfg.py b/scripts/gen_native_cfg.py index f7aee6d680..973bdaa3ea 100644 --- a/scripts/gen_native_cfg.py +++ b/scripts/gen_native_cfg.py @@ -1,4 +1,4 @@ -# Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -121,6 +121,7 @@ # `x` - int, appearing in hexadecimal in the generated source # `b` - boolean, will be true if the plaform is Linux (WTF?) # Column #3 - the name of the constant +# Comments can come after that starting with "//" constant_defs = ''' b HAVE_FUTIMENS b HAVE_UTIMENSAT @@ -429,6 +430,41 @@ * i IPV6_RECVPATHMTU * i IPV6_TCLASS * i IPV6_USE_MIN_MTU + +[sysconfigNames] // These names use some sensible overlapping default values for windows +0 i _SC_ARG_MAX // I made those required which are on both Mac and Linux +1 i _SC_CHILD_MAX +* i _SC_HOST_NAME_MAX +2 i _SC_LOGIN_NAME_MAX +* i _SC_NGROUPS_MAX +3 i _SC_CLK_TCK +4 i _SC_OPEN_MAX +5 i _SC_PAGESIZE +5 i _SC_PAGE_SIZE +* i _SC_RE_DUP_MAX +* i _SC_STREAM_MAX +* i _SC_SYMLOOP_MAX +* i _SC_TTY_NAME_MAX +* i _SC_TZNAME_MAX +* i _SC_VERSION +* i _SC_BC_BASE_MAX +* i _SC_BC_DIM_MAX +* i _SC_BC_SCALE_MAX +* i _SC_BC_STRING_MAX +* i _SC_COLL_WEIGHTS_MAX +* i _SC_EXPR_NEST_MAX +* i _SC_LINE_MAX +* i _SC_2_VERSION +* i _SC_2_C_DEV +* i _SC_2_FORT_DEV +* i _SC_2_FORT_RUN +* i _SC_2_LOCALEDEF +* i _SC_2_SW_DEV +7 i _SC_SEM_NSEMS_MAX +8 i _SC_PHYS_PAGES +* i _SC_AVPHYS_PAGES +9 i _SC_NPROCESSORS_CONF +9 i _SC_NPROCESSORS_ONLN ''' layout_defs = ''' @@ -461,7 +497,7 @@ ''' java_copyright = '''/* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -524,7 +560,7 @@ class PosixConstants{platform} {{ def parse_defs(): - regex = re.compile(r'\[(\w+)\]|(\*|u|\d?)\s*(\w+)\s+(\w+)') + regex = re.compile(r'(?:\[(\w+)\]|(\*|u|\d?)\s*(\w+)\s+(\w+))( *\/\/.*)?') current_group = [] groups = {} constants = [] @@ -678,7 +714,7 @@ def generate_posix_constants(constants, groups): defs = [] def add_constant(opt, typ, name): - prefix = 'Optional' if opt == "*" else 'Mandatory' + prefix = 'Optional' if opt else 'Mandatory' decls.append(f' public static final {prefix}{typ}Constant {name};\n') defs.append(f' {name} = reg.create{prefix}{typ}("{name}");\n') diff --git a/scripts/hpy_autogen_graalpy.py b/scripts/hpy_autogen_graalpy.py deleted file mode 100644 index 910f6514c2..0000000000 --- a/scripts/hpy_autogen_graalpy.py +++ /dev/null @@ -1,1280 +0,0 @@ -# Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# The Universal Permissive License (UPL), Version 1.0 -# -# Subject to the condition set forth below, permission is hereby granted to any -# person obtaining a copy of this software, associated documentation and/or -# data (collectively the "Software"), free of charge and under any and all -# copyright rights in the Software, and any and all patent rights owned or -# freely licensable by each licensor hereunder covering either (i) the -# unmodified Software as contributed to or provided by such licensor, or (ii) -# the Larger Works (as defined below), to deal in both -# -# (a) the Software, and -# -# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -# one is included with the Software each a "Larger Work" to which the Software -# is contributed by such licensors), -# -# without restriction, including without limitation the rights to copy, create -# derivative works of, display, perform, and distribute the Software and make, -# use, sell, offer for sale, import, export, have made, and have sold the -# Software and the Larger Work(s), and to sublicense the foregoing rights on -# either these or other terms. -# -# This license is subject to the following condition: -# -# The above copyright notice and either this complete permission notice or at a -# minimum a reference to the UPL must be included in all copies or substantial -# portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import textwrap -from copy import deepcopy -from . import conf -from .autogenfile import C_DISCLAIMER -from .parse import toC, find_typedecl, get_context_return_type, \ - maybe_make_void, make_void, get_return_constant -import re - - -class GraalPyAutoGenFile: - LANGUAGE = 'C' - PATH = None - DISCLAIMER = None - COPYRIGHT_FILE = 'mx.graalpython/copyrights/oracle.copyright.star' - - def __init__(self, api): - if self.DISCLAIMER is None and self.LANGUAGE == 'C': - self.DISCLAIMER = C_DISCLAIMER - self.api = api - - def generate(self, root): - raise NotImplementedError - - def write(self, root): - cls = self.__class__ - clsname = '%s.%s' % (cls.__module__, cls.__name__) - with root.join(self.COPYRIGHT_FILE).open('r') as f: - copyright_header = f.read() - with root.join(self.PATH).open('w') as f: - f.write(copyright_header + '\n') - if self.DISCLAIMER is not None: - f.write(self.DISCLAIMER.format(clsname=clsname) + '\n') - f.write(self.generate(root)) - f.write('\n') - -class AutoGenFilePart: - JAVA_FORMATTER_STOP = "// @formatter:off\n// Checkstyle: stop" - JAVA_FORMATTER_RESUME = "// @formatter:on\n// Checkstyle: resume\n" - JAVA_DISCLAIMER = "// DO NOT EDIT THIS PART!\n// This part is automatically generated by {clsname}" - LANGUAGE = 'Java' - PATH = None - BEGIN_MARKER = None - END_MARKER = None - INDENT = None - - def __init__(self, api): - self.api = api - # determine indentation from BEGIN_MARKER - if self.INDENT is None: - indent_match = re.match('(^[ \t]*)(?:[^ \t\n])', self.BEGIN_MARKER) - if indent_match: - self.INDENT = indent_match.group(1) - - def generate(self, old, root): - raise NotImplementedError - - def write(self, root): - if not self.BEGIN_MARKER or not self.END_MARKER: - raise RuntimeError("missing BEGIN_MARKER or END_MARKER") - n_begin = len(self.BEGIN_MARKER) - with root.join(self.PATH).open('r') as f: - content = f.read() - start = content.find(self.BEGIN_MARKER) - if start < 0: - raise RuntimeError(f'begin marker "{self.BEGIN_MARKER}" not found' - f'in file {self.PATH}') - end = content.find(self.END_MARKER, start + n_begin) - if end < 0: - raise RuntimeError(f'end marker "{self.END_MARKER}" not found in' - f'file {self.PATH}') - old_content = content[(start+n_begin):end] - new_content = self.generate(old_content, root) - if self.LANGUAGE.lower() == 'java': - gen_prefix = [] - if self.JAVA_FORMATTER_STOP is not None: - gen_prefix.append(self.JAVA_FORMATTER_STOP) - if self.JAVA_DISCLAIMER is not None: - cls = self.__class__ - clsname = '%s.%s' % (cls.__module__, cls.__name__) - gen_prefix.append(self.JAVA_DISCLAIMER.format(clsname=clsname)) - gen_prefix.append(new_content) - if self.JAVA_FORMATTER_RESUME is not None: - gen_prefix.append(self.JAVA_FORMATTER_RESUME) - new_content = '\n'.join(gen_prefix) - new_content = textwrap.indent(new_content, prefix=self.INDENT) - - # only write file if content changed (to avoid updating the 'mtime') - if old_content != new_content: - with root.join(self.PATH).open('w') as f: - f.write(content[:start + n_begin] + new_content + content[end:]) - - -def cap(s): - return s[0].upper() + s[1:] - - -def java_qname_to_path(java_class_qname): - return java_class_qname.replace('.', '/') + '.java' - - -def get_context_member_enum(ctx_name): - return ctx_name.upper() - -# If contained in this set, we won't generate anything for this HPy API func. -NO_WRAPPER = { - '_HPy_CallRealFunctionFromTrampoline', -} - -HPY_CONTEXT_PKG = 'com.oracle.graal.python.builtins.objects.cext.hpy.' -HPY_CONTEXT_CLASS = 'GraalHPyNativeContext' -HPY_CONTEXT_MEMBER_CLASS = 'HPyContextMember' -HPY_CONTEXT_FUNCTIONS_CLASS = 'GraalHPyContextFunctions' - -# A set of C structs for which we will generate descriptors such that they can -# be accessed from Java. -GENERATE_STRUCT_ACCESS = { - 'HPyType_Spec', 'HPyType_Spec', 'HPyType_SpecParam', - 'HPyCapsule_Destructor', 'HPyCallFunction' -} - -############################################################################### -# COMMON PARTS # -############################################################################### - -class autogen_ctx_member_enum(AutoGenFilePart): - """ - Generates the enum of context members. - """ - INDENT = ' ' - PATH = 'graalpython/com.oracle.graal.python/src/' + java_qname_to_path(HPY_CONTEXT_PKG + HPY_CONTEXT_MEMBER_CLASS) - BEGIN_MARKER = INDENT + '// {{start ctx members}}\n' - END_MARKER = INDENT + '// {{end ctx members}}\n' - - def generate(self, old, root): - lines = [] - w = lines.append - for var in self.api.variables: - mname = var.name.upper() - w(f'{mname}("{var.name}")') - for func in self.api.functions: - if func.name not in NO_WRAPPER: - ctx_name = func.ctx_name() - mname = get_context_member_enum(ctx_name) - node = deepcopy(func.node) # copy node because 'maybe_make_void' might modify the tree - maybe_make_void(func, node) - rettype = get_signature_type(node.type.type) - params = [] - for p in node.type.args.params: - params.append(get_signature_type(p.type)) - assert params - signature = ', '.join(params) - w(f'{mname}("{ctx_name}", {rettype}, {signature})') - return ',\n'.join(lines) + ';\n' - - -# @HPyContextFunction("ctx_Module_Create") -# @GenerateUncached -# public abstract static class GraalHPyModuleCreate extends HPyBinaryContextFunction { -class autogen_ctx_function_factory(AutoGenFilePart): - """ - """ - INDENT = ' ' - PATH = 'graalpython/com.oracle.graal.python/src/' + java_qname_to_path(HPY_CONTEXT_PKG + HPY_CONTEXT_FUNCTIONS_CLASS) - INPUT_FILE = PATH - BEGIN_MARKER = INDENT + '// {{start ctx func factory}}\n' - END_MARKER = INDENT + '// {{end ctx func factory}}\n' - - CTX_FUNC_NODE_NAME_REGEX = re.compile(r'\s*public (?:abstract )?static (?:final )?class (?P\w+) ') - CTX_FUNC_ANNOTATION_REGEX = re.compile(r'\s*@HPyContextFunction\("(?P\w+)"\)') - CTX_FUNC_ANNOTATION= '@HPyContextFunction' - - def generate(self, old, root): - ctx_func_nodes = {} - with root.join(self.INPUT_FILE).open('r') as f: - func_node = [] - for line in f.readlines(): - match_annotation = self.CTX_FUNC_ANNOTATION_REGEX.match(line) - assert self.CTX_FUNC_ANNOTATION not in line or match_annotation is not None, line - if match_annotation: - func_node.append(match_annotation.group('ctx_name')) - match_class = self.CTX_FUNC_NODE_NAME_REGEX.match(line) - if match_class and func_node: - ctx_func_nodes[match_class.group('cls')] = func_node - func_node = [] - - lines = [] - w = lines.append - w('@NeverDefault'); - w('public static GraalHPyContextFunction create(HPyContextMember member) {'); - w(' return switch (member) {') - for cls_name, ctx_funcs in ctx_func_nodes.items(): - key = ', '.join([x.upper() for x in ctx_funcs]) - w(f' case {key} -> {cls_name}NodeGen.create();') - w(' default -> throw CompilerDirectives.shouldNotReachHere();') - w(' };') - w('}') - w('') - w('public static GraalHPyContextFunction getUncached(HPyContextMember member) {'); - w(' return switch (member) {') - for cls_name, ctx_funcs in ctx_func_nodes.items(): - key = ', '.join([x.upper() for x in ctx_funcs]) - w(f' case {key} -> {cls_name}NodeGen.getUncached();') - w(' default -> throw CompilerDirectives.shouldNotReachHere();') - w(' };') - w('}') - w('') - return '\n'.join(lines) - -############################################################################### -# JNI BACKEND # -############################################################################### - -# If contained in this set, we won't generate anything for the JNI backend. -JNI_NO_WRAPPER = NO_WRAPPER.union({ - 'HPy_GetItem_s', 'HPy_SetItem_s', 'HPy_GetAttr_s', 'HPyTuple_FromArray', 'HPyContextVar_Get', - 'HPyField_Store', 'HPyGlobal_Store', 'HPyTracker_New', 'HPyTracker_Add', 'HPyTracker_ForgetAll', - 'HPyTracker_Close' -}) - -# If contained in this set, we won't generate a default upcall stub. But we -# will still generate the function declaration and such. The common use case -# for that is if you provide a custom upcall stub implementation. -JNI_NO_DEFAULT_UPCALL_STUB = JNI_NO_WRAPPER.union({ - 'HPyListBuilder_New', 'HPyListBuilder_Set','HPyListBuilder_Build','HPyListBuilder_Cancel', - 'HPyTupleBuilder_New', 'HPyTupleBuilder_Set','HPyTupleBuilder_Build','HPyTupleBuilder_Cancel', - 'HPyUnicode_FromWideChar', 'HPyGlobal_Load' -}) - -JNI_HPY_CONTEXT_PKG = HPY_CONTEXT_PKG + 'jni.' - -# The qualified name of the Java class that represents the HPy context. This -# class will contain the appropriate up- and downcall methods. -JNI_HPY_CONTEXT_CLASS = JNI_HPY_CONTEXT_PKG + 'GraalHPyJNIContext' - -# This class will contain the appropriate downcall methods (the HPy function -# trampolines) -JNI_HPY_TRAMPOLINES_CLASS = 'GraalHPyJNITrampolines' -JNI_HPY_BACKEND_CLASS = 'GraalHPyJNIContext' - -# The name of the native HPy context (will be used for HPyContext.name) -JNI_HPY_CONTEXT_NAME = 'HPy Universal ABI (GraalVM backend, JNI)' - -JNI_FUN_PREFIX = 'Java_' + (JNI_HPY_CONTEXT_PKG + JNI_HPY_TRAMPOLINES_CLASS).replace('.', '_') + '_' -JNI_METHOD_PREFIX = 'jniMethod_' - -UCTX_ARG = 'ctx' - -JNI_UPCALL_TYPE_CASTS = { - 'HPy': 'HPY_UP', - 'void *': 'PTR_UP', - 'int': 'INT_UP', - 'int32_t': 'INT_UP', - 'uint32_t': 'INT_UP', - 'long': 'LONG_UP', - 'int64_t': 'LONG_UP', - 'uint64_t': 'LONG_UP', - 'double': 'DOUBLE_UP', - 'size_t': 'SIZE_T_UP', - 'HPyTracker': 'TRACKER_UP', - '_HPyCapsule_key': 'INT_UP', - 'HPy_SourceKind': 'INT_UP' -} - -JNI_UPCALLS = { - 'void', 'DO_UPCALL_VOID', - 'HPy', 'DO_UPCALL_HPY', - # "DO_UPCALL_HPY_NOARGS", - 'DO_UPCALL_TRACKER', - 'void *', 'DO_UPCALL_PTR', - 'const char *', 'DO_UPCALL_PTR', - 'char *', 'DO_UPCALL_PTR', - 'cpy_PyObject *', 'DO_UPCALL_PTR', - # "DO_UPCALL_PTR_NOARGS", - 'DO_UPCALL_SIZE_T', - 'int', 'DO_UPCALL_INT', - 'int32_t', 'DO_UPCALL_INT32', - 'double', 'DO_UPCALL_DOUBLE', - 'long', 'DO_UPCALL_LONG', - 'int64_t', 'DO_UPCALL_INT64', - 'HPy_UCS4', 'DO_UPCALL_UCS4', -} - -JNI_UPCALL_ARG_CASTS = { - 'HPy': 'HPY_UP', - 'int': 'INT_UP', - 'long': 'LONG_UP', - 'double': 'DOUBLE_UP', - 'HPy_ssize_t': 'SIZE_T_UP', - 'HPyTracker': 'TRACKER_UP', - '_HPyCapsule_key': 'INT_UP', - 'HPy_SourceKind': 'INT_UP' -} - -# The following table maps HPy context handles to Java objects (and a construct with additional arguments). -# This table unfortunately needs to be maintained manually because there is no uniform pattern on how to -# map HPy context member names to Java objects. -# The table is later used to generate the initialization code for 'HPyContext *'. -# -# {ctx_name: (jobject, jctor, jctor_arg)} -CTX_HANDLES = { - "h_None": ("PNone.NONE", "createSingletonConstant", ["SINGLETON_HANDLE_NONE"]), - "h_True": ("context.getContext().getTrue()", "createConstant", []), - "h_False": ("context.getContext().getFalse()", "createConstant", []), - "h_NotImplemented": ("PNotImplemented.NOT_IMPLEMENTED", "createSingletonConstant", ["SINGLETON_HANDLE_NOT_IMPLEMENTED"]), - "h_Ellipsis": ("PEllipsis.INSTANCE", "createSingletonConstant", ["SINGLETON_HANDLE_ELIPSIS"]), - "h_BaseException": ("PythonBuiltinClassType.PBaseException", "createTypeConstant", []), - "h_Exception": ("PythonBuiltinClassType.Exception", "createTypeConstant", []), - "h_StopAsyncIteration": ("PythonBuiltinClassType.StopAsyncIteration", "createTypeConstant", []), - "h_StopIteration": ("PythonBuiltinClassType.StopIteration", "createTypeConstant", []), - "h_GeneratorExit": ("PythonBuiltinClassType.GeneratorExit", "createTypeConstant", []), - "h_ArithmeticError": ("PythonBuiltinClassType.ArithmeticError", "createTypeConstant", []), - "h_LookupError": ("PythonBuiltinClassType.LookupError", "createTypeConstant", []), - "h_AssertionError": ("PythonBuiltinClassType.AssertionError", "createTypeConstant", []), - "h_AttributeError": ("PythonBuiltinClassType.AttributeError", "createTypeConstant", []), - "h_BufferError": ("PythonBuiltinClassType.BufferError", "createTypeConstant", []), - "h_EOFError": ("PythonBuiltinClassType.EOFError", "createTypeConstant", []), - "h_FloatingPointError": ("PythonBuiltinClassType.FloatingPointError", "createTypeConstant", []), - "h_OSError": ("PythonBuiltinClassType.OSError", "createTypeConstant", []), - "h_ImportError": ("PythonBuiltinClassType.ImportError", "createTypeConstant", []), - "h_ModuleNotFoundError": ("PythonBuiltinClassType.ModuleNotFoundError", "createTypeConstant", []), - "h_IndexError": ("PythonBuiltinClassType.IndexError", "createTypeConstant", []), - "h_KeyError": ("PythonBuiltinClassType.KeyError", "createTypeConstant", []), - "h_KeyboardInterrupt": ("PythonBuiltinClassType.KeyboardInterrupt", "createTypeConstant", []), - "h_MemoryError": ("PythonBuiltinClassType.MemoryError", "createTypeConstant", []), - "h_NameError": ("PythonBuiltinClassType.NameError", "createTypeConstant", []), - "h_OverflowError": ("PythonBuiltinClassType.OverflowError", "createTypeConstant", []), - "h_RuntimeError": ("PythonBuiltinClassType.RuntimeError", "createTypeConstant", []), - "h_RecursionError": ("PythonBuiltinClassType.RecursionError", "createTypeConstant", []), - "h_NotImplementedError": ("PythonBuiltinClassType.NotImplementedError", "createTypeConstant", []), - "h_SyntaxError": ("PythonBuiltinClassType.SyntaxError", "createTypeConstant", []), - "h_IndentationError": ("PythonBuiltinClassType.IndentationError", "createTypeConstant", []), - "h_TabError": ("PythonBuiltinClassType.TabError", "createTypeConstant", []), - "h_ReferenceError": ("PythonBuiltinClassType.ReferenceError", "createTypeConstant", []), - "h_SystemError": ("SystemError", "createTypeConstant", []), - "h_SystemExit": ("PythonBuiltinClassType.SystemExit", "createTypeConstant", []), - "h_TypeError": ("PythonBuiltinClassType.TypeError", "createTypeConstant", []), - "h_UnboundLocalError": ("PythonBuiltinClassType.UnboundLocalError", "createTypeConstant", []), - "h_UnicodeError": ("PythonBuiltinClassType.UnicodeError", "createTypeConstant", []), - "h_UnicodeEncodeError": ("PythonBuiltinClassType.UnicodeEncodeError", "createTypeConstant", []), - "h_UnicodeDecodeError": ("PythonBuiltinClassType.UnicodeDecodeError", "createTypeConstant", []), - "h_UnicodeTranslateError": ("PythonBuiltinClassType.UnicodeTranslateError", "createTypeConstant", []), - "h_ValueError": ("PythonBuiltinClassType.ValueError", "createTypeConstant", []), - "h_ZeroDivisionError": ("PythonBuiltinClassType.ZeroDivisionError", "createTypeConstant", []), - "h_BlockingIOError": ("PythonBuiltinClassType.BlockingIOError", "createTypeConstant", []), - "h_BrokenPipeError": ("PythonBuiltinClassType.BrokenPipeError", "createTypeConstant", []), - "h_ChildProcessError": ("PythonBuiltinClassType.ChildProcessError", "createTypeConstant", []), - "h_ConnectionError": ("PythonBuiltinClassType.ConnectionError", "createTypeConstant", []), - "h_ConnectionAbortedError": ("PythonBuiltinClassType.ConnectionAbortedError", "createTypeConstant", []), - "h_ConnectionRefusedError": ("PythonBuiltinClassType.ConnectionRefusedError", "createTypeConstant", []), - "h_ConnectionResetError": ("PythonBuiltinClassType.ConnectionResetError", "createTypeConstant", []), - "h_FileExistsError": ("PythonBuiltinClassType.FileExistsError", "createTypeConstant", []), - "h_FileNotFoundError": ("PythonBuiltinClassType.FileNotFoundError", "createTypeConstant", []), - "h_InterruptedError": ("PythonBuiltinClassType.InterruptedError", "createTypeConstant", []), - "h_IsADirectoryError": ("PythonBuiltinClassType.IsADirectoryError", "createTypeConstant", []), - "h_NotADirectoryError": ("PythonBuiltinClassType.NotADirectoryError", "createTypeConstant", []), - "h_PermissionError": ("PythonBuiltinClassType.PermissionError", "createTypeConstant", []), - "h_ProcessLookupError": ("PythonBuiltinClassType.ProcessLookupError", "createTypeConstant", []), - "h_TimeoutError": ("PythonBuiltinClassType.TimeoutError", "createTypeConstant", []), - "h_Warning": ("PythonBuiltinClassType.Warning", "createTypeConstant", []), - "h_UserWarning": ("PythonBuiltinClassType.UserWarning", "createTypeConstant", []), - "h_DeprecationWarning": ("PythonBuiltinClassType.DeprecationWarning", "createTypeConstant", []), - "h_PendingDeprecationWarning": ("PythonBuiltinClassType.PendingDeprecationWarning", "createTypeConstant", []), - "h_SyntaxWarning": ("PythonBuiltinClassType.SyntaxWarning", "createTypeConstant", []), - "h_RuntimeWarning": ("PythonBuiltinClassType.RuntimeWarning", "createTypeConstant", []), - "h_FutureWarning": ("PythonBuiltinClassType.FutureWarning", "createTypeConstant", []), - "h_ImportWarning": ("PythonBuiltinClassType.ImportWarning", "createTypeConstant", []), - "h_UnicodeWarning": ("PythonBuiltinClassType.UnicodeWarning", "createTypeConstant", []), - "h_BytesWarning": ("PythonBuiltinClassType.BytesWarning", "createTypeConstant", []), - "h_ResourceWarning": ("PythonBuiltinClassType.ResourceWarning", "createTypeConstant", []), - "h_BaseObjectType": ("PythonBuiltinClassType.PythonObject", "createTypeConstant", []), - "h_TypeType": ("PythonBuiltinClassType.PythonClass", "createTypeConstant", []), - "h_BoolType": ("PythonBuiltinClassType.Boolean", "createTypeConstant", []), - "h_LongType": ("PythonBuiltinClassType.PInt", "createTypeConstant", []), - "h_FloatType": ("PythonBuiltinClassType.PFloat", "createTypeConstant", []), - "h_UnicodeType": ("PythonBuiltinClassType.PString", "createTypeConstant", []), - "h_TupleType": ("PythonBuiltinClassType.PTuple", "createTypeConstant", []), - "h_ListType": ("PythonBuiltinClassType.PList", "createTypeConstant", []), - "h_ComplexType": ("PythonBuiltinClassType.PComplex", "createTypeConstant", []), - "h_BytesType": ("PythonBuiltinClassType.PBytes", "createTypeConstant", []), - "h_MemoryViewType": ("PythonBuiltinClassType.PMemoryView", "createTypeConstant", []), - "h_CapsuleType": ("PythonBuiltinClassType.Capsule", "createTypeConstant", []), - "h_SliceType": ("PythonBuiltinClassType.PSlice", "createTypeConstant", []), - "h_Builtins": ("", "createBuiltinsConstant", []), -} - -def get_cast_fun(type_name): - if type_name == 'HPy': - return 'HPY_UP' - elif type_name == 'HPyGlobal': - return 'HPY_GLOBAL_UP' - elif type_name == 'HPyField': - return 'HPY_FIELD_UP' - elif type_is_pointer(type_name): - return 'PTR_UP' - elif type_name in ('int', '_HPyCapsule_key', 'HPyType_BuiltinShape', 'HPy_SourceKind'): - return 'INT_UP' - elif type_name == 'int32_t': - return 'INT32_UP' - elif type_name == 'uint32_t': - return 'UINT32_UP' - elif type_name == 'long': - return 'LONG_UP' - elif type_name == 'double': - return 'DOUBLE_UP' - elif type_name == 'HPy_ssize_t': - return 'SIZE_T_UP' - elif type_name == 'HPyTracker': - return 'HPY_TRACKER_UP' - elif type_name == 'HPyListBuilder': - return 'HPY_LIST_BUILDER_UP' - elif type_name == 'HPyThreadState': - return 'HPY_THREAD_STATE_UP' - return 'LONG_UP' - -def get_jni_signature_type(type_name): - if type_name in ('int', 'int32_t', 'uint32_t', '_HPyCapsule_key', 'HPy_UCS4', 'HPyType_BuiltinShape', 'HPy_SourceKind'): - return 'I' - elif type_name == 'long': - return 'J' - elif type_name == 'double': - return 'D' - elif type_name == 'void': - return 'V' - elif type_name == 'bool': - return 'Z' - return 'J' - -def get_jni_c_type(type_name): - if type_name in ('int', 'int32_t', 'uint32_t', '_HPyCapsule_key', 'HPy_UCS4', 'HPyType_BuiltinShape', 'HPy_SourceKind'): - return 'jint' - elif type_name == 'double': - return 'jdouble' - elif type_name == 'void': - return 'void' - elif type_name == 'bool': - return 'jboolean' - # also covers type_name == 'long' - return 'jlong' - -def get_java_signature_type(type): - type_name = toC(type) - if type_name in ('int', 'int32_t', 'uint32_t', '_HPyCapsule_key', 'HPy_UCS4', 'HPyType_BuiltinShape', 'HPy_SourceKind'): - return 'int' - if type_name == 'bool': - return 'boolean' - # also covers type_name == 'long' - if type_name == 'double' or type_name == 'void': - return type_name - return 'long' - -def type_is_pointer(type): - return '*' in type - -def funcnode_with_new_name(node, name): - newnode = deepcopy(node) - typedecl = find_typedecl(newnode) - typedecl.declname = name - return newnode - -def get_trace_wrapper_node(func): - newnode = funcnode_with_new_name(func.node, '%s_jni' % func.ctx_name()) - maybe_make_void(func, newnode) - return newnode - -def get_jni_class_header(java_class_qname): - return java_class_qname.replace('.', '_') + '.h' - -def get_jni_function_prefix(java_class_qname): - return 'Java_' + java_class_qname.replace('.', '_') + '_' - -AUTOGEN_CTX_INIT_JNI_H_FILE = 'autogen_ctx_init_jni.h' - -class autogen_ctx_init_jni_h(GraalPyAutoGenFile): - PATH = 'graalpython/com.oracle.graal.python.jni/src/' + AUTOGEN_CTX_INIT_JNI_H_FILE - - def generate(self, root): - lines = [] - w = lines.append - w(f'_HPy_HIDDEN int init_autogen_jni_ctx(JNIEnv *env, jclass clazz, HPyContext *{UCTX_ARG}, jlongArray jctx_handles);') - # emit the declarations for all the ctx_*_jni functions - for func in self.api.functions: - fname = func.name - # since JNI_NO_DEFAULT_UPCALL_STUB contains JNI_NO_WRAPPER, we need to check JNI_NO_WRAPPER first - if fname not in JNI_NO_WRAPPER: - if fname in JNI_NO_DEFAULT_UPCALL_STUB: - w(f'_HPy_HIDDEN extern jmethodID jniMethod_{func.ctx_name()};') - w(f'_HPy_HIDDEN {toC(get_trace_wrapper_node(func))};') - w('') - return '\n'.join(lines) - - -class autogen_wrappers_jni(GraalPyAutoGenFile): - PATH = 'graalpython/com.oracle.graal.python.jni/src/autogen_wrappers_jni.c' - - def generate(self, root): - lines = [] - w = lines.append - w('#include "hpy_jni.h"') - w('#include "hpynative.h"') - w('#include "hpy_log.h"') - w(f'#include "{get_jni_class_header(JNI_HPY_CONTEXT_PKG + JNI_HPY_BACKEND_CLASS)}"') - w(f'#include "{AUTOGEN_CTX_INIT_JNI_H_FILE}"') - w('') - w(f'#define TRAMPOLINE(FUN_NAME) {get_jni_function_prefix(JNI_HPY_CONTEXT_PKG + JNI_HPY_BACKEND_CLASS)} ## FUN_NAME') - w('') - - # generate global variables for JNI method IDs - for func in self.api.functions: - fname = func.name - # since JNI_NO_DEFAULT_UPCALL_STUB contains JNI_NO_WRAPPER, we need to check JNI_NO_WRAPPER first - if fname not in JNI_NO_WRAPPER: - if fname in JNI_NO_DEFAULT_UPCALL_STUB: - w(f'_HPy_HIDDEN jmethodID jniMethod_{func.ctx_name()};') - else : - w(f'static jmethodID jniMethod_{func.ctx_name()};') - w(f'static {toC(get_trace_wrapper_node(func))};') - w('') - - # start of 'init_autogen_jni_ctx' - w(f'_HPy_HIDDEN int init_autogen_jni_ctx(JNIEnv *env, jclass clazz, HPyContext *{UCTX_ARG}, jlongArray jctx_handles)') - w('{') - - # initialize context handles - w('') - w(' jlong *ctx_handles = (*env)->GetPrimitiveArrayCritical(env, jctx_handles, NULL);') - w(' if (ctx_handles == NULL) {') - w(f' LOGS("ERROR: Could not access Java context handle array elements\\n");') - w(' return 1;') - w(' }') - for var in self.api.variables: - w(f' {UCTX_ARG}->{var.ctx_name()} = _jlong2h(ctx_handles[{var.ctx_index}]);') - w(' (*env)->ReleasePrimitiveArrayCritical(env, jctx_handles, ctx_handles, JNI_ABORT);') - w('') - - # initialize context function pointers - for func in self.api.functions: - self.gen_jni_method_init(w, func) - w(f' return 0;') - - # end of 'init_autogen_jni_ctx' - w('}') - w('') - - # generate upcall trampolines - for func in self.api.functions: - debug_wrapper = self.gen_trace_wrapper(func) - if debug_wrapper: - w(debug_wrapper) - w('') - return '\n'.join(lines) - - def gen_jni_method_init(self, w, func): - if func.name in JNI_NO_WRAPPER: - return - node = get_trace_wrapper_node(func) - name = func.ctx_name() - - # compute JNI signature - jni_params = [] - assert node.type.args.params[0].name == "ctx" - # skip the context parameter - for p in node.type.args.params[1:]: - param_type = toC(p.type) - jni_params.append(get_jni_signature_type(param_type)) - jni_sig = "".join(jni_params) - rettype = get_context_return_type(node, False) - jni_ret_type = get_jni_signature_type(rettype) - - jname = name.replace('_', '') - w(f' {JNI_METHOD_PREFIX}{name} = (*env)->GetMethodID(env, clazz, "{jname}", "({jni_sig}){jni_ret_type}");') - w(f' if ({JNI_METHOD_PREFIX}{name} == NULL) {{') - w(f' LOGS("ERROR: Java method {jname} not found found !\\n");') - w(' return 1;') - w(' }') - w(f' {UCTX_ARG}->{name} = &{name}_jni;') - - def gen_trace_wrapper(self, func): - if func.name in JNI_NO_DEFAULT_UPCALL_STUB: - return - - assert not func.is_varargs() - node = get_trace_wrapper_node(func) - #typedecl = find_typedecl(func) - #typedecl.declname = name - const_return = get_return_constant(func) - if const_return: - make_void(node) - signature = toC(node) - rettype = get_context_return_type(node, const_return) - - param_names = [] - assert node.type.args.params[0].name == "ctx" - # skip the context parameter - for p in node.type.args.params[1:]: - param_type = toC(p.type) - cast_fun = get_cast_fun(param_type) - param_names.append(f'{cast_fun}({p.name})') - - lines = [] - w = lines.append - w(f'static {signature}') - w('{') - - suffix = '' if param_names else '0' - all_params = [f'CONTEXT_INSTANCE({UCTX_ARG})', func.ctx_name()] + param_names - params = ", ".join(all_params) - if rettype == 'void': - w(f' DO_UPCALL_VOID{suffix}({params});') - elif rettype == 'HPy': - w(f' return DO_UPCALL_HPY{suffix}({params});') - elif type_is_pointer(rettype): - w(f' return ({rettype})DO_UPCALL_PTR{suffix}({params});') - else: - w(f' return DO_UPCALL_{rettype.replace(" ", "_").upper()}{suffix}({params});') - w('}') - return '\n'.join(lines) - -JNI_NO_UPCALL = tuple() - -class autogen_ctx_jni_upcall_enum(AutoGenFilePart): - """ - """ - INDENT = ' ' - PATH = 'graalpython/com.oracle.graal.python/src/' + java_qname_to_path(JNI_HPY_CONTEXT_PKG + JNI_HPY_BACKEND_CLASS) - BEGIN_MARKER = INDENT + '// {{start jni upcalls}}\n' - END_MARKER = INDENT + '// {{end jni upcalls}}\n' - - def generate(self, old, root): - lines = [] - w = lines.append - for func in self.api.functions: - w(cap(func.name.replace('_', ''))) - return ',\n'.join(lines) + ';\n' - - -class autogen_ctx_handles_init(AutoGenFilePart): - """ - Generates a Java long array that contains the handles used to initialize the - context handles like, e.g., 'h_None'. - For this, the generator iterates over all variables as specified in - 'public_api.h' and emits the constructor call. - The position where the handle is written into the array is the context index - as specified in 'public_api.h'. This is to ensure that the consumer of the - array (i.e. 'autogen_wrappers_jni') will assign the right value to the - appropriate context member. - - For example: 'h_Ellipsis' has context index '4'. The generator will emit - code like 'ctxHandles[4] = createHandle(PEllipsis.INSTANCE);'. - - The mapping of context handles to Java objects and how the handle is created - is specified by table 'CTX_HANDLES'. - """ - INDENT = ' ' - PATH = 'graalpython/com.oracle.graal.python/src/' + java_qname_to_path(JNI_HPY_CONTEXT_PKG + JNI_HPY_BACKEND_CLASS) - BEGIN_MARKER = INDENT + '// {{start ctx handles array}}\n' - END_MARKER = INDENT + '// {{end ctx handles array}}' - - def generate(self, old, root): - lines = [] - w = lines.append - max_ctx_index = max([v.ctx_index for v in self.api.variables]) - w(f'long[] ctxHandles = new long[{max_ctx_index + 1}];') - def gen_ctor(var_name): - data = CTX_HANDLES[var_name] - args = ", ".join([data[0]] + data[2]) - return f'{data[1]}({args})' - - for var in self.api.variables: - w(f'ctxHandles[{var.ctx_index}] = {gen_ctor(var.ctx_name())};') - w('return ctxHandles;') - w('') - return '\n'.join(lines) - - -class autogen_svm_jni_upcall_config(AutoGenFilePart): - """ - """ - INDENT = ' ' - PATH = 'graalpython/com.oracle.graal.python/src/com/oracle/graal/python/JNIFeature.java' - BEGIN_MARKER = INDENT + '// {{start jni upcall config}}\n' - END_MARKER = INDENT + '// {{end jni upcall config}}' - - def generate(self, old, root): - lines = [] - w = lines.append - for func in self.api.functions: - if func.name in JNI_NO_WRAPPER: - continue - node = func.node - jname = func.ctx_name().replace('_', '') - jni_params = [f'"{jname}"'] - for p in node.type.args.params[1:]: - jtype = get_java_signature_type(p.type) - jni_params.append(f'{jtype}.class') - w(f'RuntimeJNIAccess.register(GraalHPyJNIContext.class.getDeclaredMethod({", ".join(jni_params)}));') - - return '\n'.join(lines) - - -class autogen_jni_upcall_method_stub(AutoGenFilePart): - """ - Generates empty JNI upcall methods like - 'public long ctxLongFromLongLong(long v) { /* ... */ }'. This generator will - not generate methods if they already exist. - """ - INDENT = ' ' - PATH = 'graalpython/com.oracle.graal.python/src/' + java_qname_to_path(JNI_HPY_CONTEXT_PKG + JNI_HPY_BACKEND_CLASS) - BEGIN_MARKER = INDENT + '// {{start ctx funcs}}\n' - END_MARKER = INDENT + '// {{end ctx funcs}}\n' - - # In this case, we don't want to disable the formatter nor print the - # disclaimer because the generated code is just a starting point. - JAVA_FORMATTER_STOP = None - JAVA_FORMATTER_RESUME = None - JAVA_DISCLAIMER = None - - def generate(self, old, root): - # We need to remove indentation from 'old' otherwise it would be - # indented again - lines = [textwrap.dedent(old)] - w = lines.append - for func in self.api.functions: - if func.name in JNI_NO_WRAPPER: - continue - - func_type = get_trace_wrapper_node(func).type - - # context member enum, e.g., 'CTX_MODULECREATE' - ctx_enum = get_context_member_enum(func.ctx_name()) - - # context function name w/o underscores, e.g., 'ctxGetItemi' - jname = func.ctx_name().replace('_', '') - - # HPy API function name w/o underscores, e.g., 'HPyGetItemi' - fname = func.name.replace('_', '') - - rettype = get_java_signature_type(func_type.type) - if f' {jname}(' not in old: - java_params = [] - all_longs = True - java_param_names = [] - for i, p in enumerate(func_type.args.params[1:]): - jtype = get_java_signature_type(p.type) - p_name = p.name if p.name else f'arg{i}' - java_params.append(f'{jtype} {p_name}') - all_longs = all_longs and (jtype == 'long') - java_param_names.append(p_name) - - w(f'public {rettype} {jname}({", ".join(java_params)}) {{') - w(f' increment(HPyJNIUpcall.{fname});') - return_result = '' if rettype == 'void' else 'return ' - arr_type = 'long' if all_longs else 'Object' - arity = len(java_param_names) - args = ', '.join(java_param_names) - if rettype == 'int' or rettype == 'void': - prefix = 'Int' - elif rettype == 'long': - prefix = 'Long' - arity_name = '' - arg_s = args - if arity == 1: - arity_name = 'Binary' - elif arity == 2: - arity_name = 'Ternary' - else: - arg_s = f'new {arr_type}[]{{{args}}}' - w(f' {return_result}execute{prefix}{arity_name}ContextFunction({HPY_CONTEXT_MEMBER_CLASS}.{ctx_enum}, {arg_s});') - w('}') - w('') - return '\n'.join(lines) - - -NO_CALL = ('DESTROYFUNC', 'TRAVERSEPROC') -NO_DEBUG_TRAMPOLINE = NO_CALL + ('KEYWORDS', 'GETBUFFERPROC', 'RELEASEBUFFERPROC') -NO_UNIVERSAL_TRAMPOLINE = NO_CALL - -def get_jni_trampoline_name(base_name): - return base_name.replace('_', '').capitalize() - - -class autogen_ctx_jni(AutoGenFilePart): - """ - Generates the Java JNI trampoline class for calling native functions of a - certain signature like 'HPy_tp_init'. - """ - PATH = 'graalpython/com.oracle.graal.python/src/' + java_qname_to_path(JNI_HPY_CONTEXT_PKG + JNI_HPY_TRAMPOLINES_CLASS) - BEGIN_MARKER = ' // {{start autogen}}\n' - END_MARKER = ' // {{end autogen}}\n' - - def generate(self, old, root): - lines_universal = [] - u = lines_universal.append - lines_debug = [] - d = lines_debug.append - for hpyfunc in self.api.hpyfunc_typedefs: - name = get_jni_trampoline_name(hpyfunc.base_name()) - if name.upper() in NO_CALL: - continue - # - rettype = get_java_signature_type(hpyfunc.return_type()) - args = ['long target', 'long ctx'] - for i, param in enumerate(hpyfunc.params()[1:]): - pname = param.name - if pname is None: - pname = 'arg%d' % i - jtype = get_java_signature_type(param.type) - args.append(f'{jtype} {pname}') - args = ', '.join(args) - u(f'// {toC(hpyfunc.node)}') - u('@TruffleBoundary') - u(f'public static native {rettype} execute{name}({args});') - u('') - d(f'// {toC(hpyfunc.node)}') - d('@TruffleBoundary') - d(f'public static native {rettype} executeDebug{name}({args});') - d('') - return '\n'.join(lines_universal + lines_debug) - - -class autogen_ctx_call_jni(GraalPyAutoGenFile): - """ - Generates the JNI call trampolines that will be used to call HPy functions - from Java (for both, universal or debug mode). - """ - PATH = 'graalpython/com.oracle.graal.python.jni/src/autogen_ctx_call_jni.c' - - def generate(self, root): - lines = [] - w = lines.append - jni_include = JNI_HPY_CONTEXT_PKG.replace('.', '_') + JNI_HPY_TRAMPOLINES_CLASS - w(f'#include "hpy_jni.h"') - w(f'#include "{jni_include}.h"') - w('') - w(f'#define TRAMPOLINE(name) {JNI_FUN_PREFIX} ## name') - w('') - self.generateUniversal(w) - w('') - self.generateDebug(w) - w('#undef TRAMPOLINE') - return '\n'.join(lines) - - def generateUniversal(self, w): - w('/*******************************************************************') - w(' * UNIVERSAL MODE TRAMPOLINES *') - w(' ******************************************************************/') - w('') - w(f'JNIEXPORT jlong JNICALL TRAMPOLINE(executeModuleInit)(JNIEnv *env, jclass clazz, jlong target)') - w('{') - w(' return (jlong) (((HPyModuleDef *(*)(void)) target)());') - w('}') - w('') - for hpyfunc in self.api.hpyfunc_typedefs: - name = hpyfunc.base_name() - if name.upper() in NO_CALL: - continue - # - c_rettype = toC(hpyfunc.return_type()) - jni_c_rettype = get_jni_c_type(c_rettype) - args = ['(HPyContext *)ctx'] - trampoline_args = ['jlong target', 'jlong ctx'] - for i, param in enumerate(hpyfunc.params()[1:]): - pname = param.name - if pname is None: - pname = 'arg%d' % i - c_param_type = toC(param.type) - jni_type = get_jni_c_type(c_param_type) - trampoline_args.append(f'{jni_type} {pname}') - if c_param_type == 'HPy': - args.append(f'_jlong2h({pname})') - else: - args.append(f'({c_param_type}) {pname}') - trampoline_args = ', '.join(trampoline_args) - args = ', '.join(args) - # - w(f'JNIEXPORT {jni_c_rettype} JNICALL TRAMPOLINE(execute{get_jni_trampoline_name(name)})(JNIEnv *env, jclass clazz, {trampoline_args})') - w('{') - w(f' HPyFunc_{name} f = (HPyFunc_{name})target;') - if c_rettype == 'void': - w(f' f({args});') - elif c_rettype == 'HPy': - w(f' return _h2jlong(f({args}));') - else: - w(f' return ({jni_c_rettype}) f({args});') - w('}') - w('') - - def generateDebug(self, w): - w('/*******************************************************************') - w(' * DEBUG MODE TRAMPOLINES *') - w(' ******************************************************************/') - w('') - for hpyfunc in self.api.hpyfunc_typedefs: - name = hpyfunc.base_name() - if name.upper() in NO_DEBUG_TRAMPOLINE: - continue - # - c_rettype = toC(hpyfunc.return_type()) - jni_c_rettype = get_jni_c_type(c_rettype) - args = ['dctx'] - dh_init = [''] * len(args) - dh_arr = [] - has_args_param = False - trampoline_args = ['jlong target', 'jlong ctx'] - for i, param in enumerate(hpyfunc.params()[1:]): - pname = param.name - if pname is None: - pname = f'arg{i}' - c_param_type = toC(param.type) - jni_type = get_jni_c_type(c_param_type) - trampoline_args.append(f'{jni_type} {pname}') - if c_param_type == 'HPy': - dh_arg = f'dh_{pname}' - dh_init.append(pname) - args.append(dh_arg) - elif (c_param_type == 'HPy *' or c_param_type == 'const HPy *') and pname == 'args': - dh_init.append('') - args.append('dh_args') - has_args_param = True - else: - dh_init.append('') - args.append(f'({c_param_type}){pname}') - trampoline_args = ', '.join(trampoline_args) - s_args = ', '.join(args) - # - w(f'JNIEXPORT {jni_c_rettype} JNICALL TRAMPOLINE(executeDebug{get_jni_trampoline_name(name)})(JNIEnv *env, jclass clazz, {trampoline_args})') - w('{') - w(' HPyContext *dctx = (HPyContext *) ctx;') - w(f' HPyFunc_{name} f = (HPyFunc_{name})target;') - for dh_arg, h_arg in zip(args, dh_init): - if h_arg: - w(f' DHPy {dh_arg} = _jlong2dh(dctx, {h_arg});') - if has_args_param: - w(f' _ARR_JLONG2DH(dctx, dh_args, args, nargs)') - retvar = '' - if c_rettype == 'void': - w(f' f({s_args});') - elif c_rettype == 'HPy': - retvar = 'dh_result' - w(f' DHPy {retvar} = f({s_args});') - else: - retvar = 'result' - w(f' {jni_c_rettype} {retvar} = ({jni_c_rettype}) f({s_args});') - if has_args_param: - w(f' _ARR_DH_CLOSE(dctx, dh_args, nargs)') - for dh_arg, h_arg in zip(args, dh_init): - if h_arg: - w(f' DHPy_close_and_check(dctx, {dh_arg});') - if c_rettype == 'HPy': - w(f' return from_dh(dctx, {retvar});') - elif retvar: - w(f' return {retvar};') - w('}') - w('') - - -############################################################################### -# LLVM BACKEND # -############################################################################### - -LLVM_HPY_CONTEXT_PKG = HPY_CONTEXT_PKG + 'llvm.' -LLVM_HPY_BACKEND_CLASS = 'GraalHPyLLVMContext' - -# The name of the native HPy context (will be used for HPyContext.name) -LLVM_HPY_CONTEXT_NAME = 'HPy Universal ABI (GraalVM backend, LLVM)' - - -def get_signature_type(type): - """ - Convert a C type to a HPyContextSignatureType descriptor. - """ - type_name = toC(type) - - # split at spaces - parts = type_name.split(' ') - - def normalize(part): - if part == '*': - return 'Ptr' - elif part == '**': - return 'PtrPtr' - elif part == '[]': - return 'Ptr' - return cap(part) - - # replace '*' by 'Ptr' and capitalize each part - result = ''.join([normalize(x) for x in parts]) - - # avoid name clashes with Java types; prefix with 'C' - if result in ('Void', 'Long', 'Double', 'Float'): - result = 'C' + result - return result - - -class autogen_ctx_llvm_init(AutoGenFilePart): - """ - Generates initialization code for the context handles like, e.g., 'h_None'. - For this, the generator iterates over all variables as specified in - 'public_api.h' and emits the constructor call. - - The mapping of context handles to Java objects and how the handle is created - is specified by table 'CTX_HANDLES'. - """ - INDENT = ' ' - PATH = 'graalpython/com.oracle.graal.python/src/' + java_qname_to_path(LLVM_HPY_CONTEXT_PKG + LLVM_HPY_BACKEND_CLASS) - BEGIN_MARKER = INDENT + '// {{start llvm ctx init}}\n' - END_MARKER = INDENT + '// {{end llvm ctx init}}\n' - - def generate(self, old, root): - lines = [] - w = lines.append - def gen_ctor(var_name): - data = CTX_HANDLES[var_name] - args = ", ".join([data[0]] + data[2]) - return f'{data[1]}({args})' - - for var in self.api.variables: - ctx_name = var.ctx_name() - w(f'members[HPyContextMember.{ctx_name.upper()}.ordinal()] = {gen_ctor(ctx_name)};') - w('') - for func in self.api.functions: - if func.name not in NO_WRAPPER: - mname = func.ctx_name().upper() - w(f'members[HPyContextMember.{mname}.ordinal()] = createContextFunction(HPyContextMember.{mname});') - w('') - return '\n'.join(lines) - -llvm_return_cast_func = { - 'HPy': 'WRAP', - 'HPyGlobal': 'WRAP_GLOBAL', - 'HPyField': 'WRAP_FIELD', - 'HPyTracker': 'WRAP_TRACKER', - 'HPyListBuilder': 'WRAP_LIST_BUILDER', - 'HPyTupleBuilder': 'WRAP_TUPLE_BUILDER', - 'HPyThreadState': 'WRAP_THREADSTATE', -} - - -llvm_param_cast_func = { - 'HPy': 'UNWRAP', - 'HPyGlobal': 'UNWRAP_GLOBAL', - 'HPyField': 'UNWRAP_FIELD', - 'HPyTracker': 'UNWRAP_TRACKER', - 'HPyListBuilder': 'UNWRAP_LIST_BUILDER', - 'HPyTupleBuilder': 'UNWRAP_TUPLE_BUILDER', - 'HPyThreadState': 'UNWRAP_THREADSTATE', - 'HPy_SourceKind': 'UNWRAP_SOURCE_KIND', -} - - -class autogen_llvm_trampolines_h(GraalPyAutoGenFile): - PATH = 'graalpython/com.oracle.graal.python.hpy.llvm/include/hpy/universal/autogen_trampolines.h' - - def generate(self, root): - lines = [] - w = lines.append - w('#ifdef GRAALVM_PYTHON_LLVM') - w('#define UNWRAP(_h) ((_h)._i)') - w('#define WRAP(_ptr) ((HPy){(_ptr)})') - w('#define UNWRAP_TUPLE_BUILDER(_h) ((_h)._tup)') - w('#define WRAP_TUPLE_BUILDER(_ptr) ((HPyTupleBuilder){(_ptr)})') - w('#define UNWRAP_LIST_BUILDER(_h) ((_h)._lst)') - w('#define WRAP_LIST_BUILDER(_ptr) ((HPyListBuilder){(_ptr)})') - w('#define UNWRAP_TRACKER(_h) ((_h)._i)') - w('#define WRAP_TRACKER(_ptr) ((HPyTracker){(_ptr)})') - w('#define UNWRAP_THREADSTATE(_ts) ((_ts)._i)') - w('#define WRAP_THREADSTATE(_ptr) ((HPyThreadState){(_ptr)})') - w('#define UNWRAP_FIELD(_h) ((_h)._i)') - w('#define WRAP_FIELD(_ptr) ((HPyField){(_ptr)})') - w('#define UNWRAP_GLOBAL(_h) ((_h)._i)') - w('#define WRAP_GLOBAL(_ptr) ((HPyGlobal){(_ptr)})') - w('#define UNWRAP_SOURCE_KIND(_h) ((int)(_h))') - w('#else') - w('#define UNWRAP(_h) _h') - w('#define WRAP(_ptr) _ptr') - w('#define UNWRAP_TUPLE_BUILDER(_h) _h') - w('#define WRAP_TUPLE_BUILDER(_ptr) _ptr') - w('#define UNWRAP_LIST_BUILDER(_h) _h') - w('#define WRAP_LIST_BUILDER(_ptr) _ptr') - w('#define UNWRAP_TRACKER(_h) _h') - w('#define WRAP_TRACKER(_ptr) _ptr') - w('#define UNWRAP_THREADSTATE(_ts) _ts') - w('#define WRAP_THREADSTATE(_data) _data') - w('#define UNWRAP_FIELD(_h) _h') - w('#define WRAP_FIELD(_ptr) _ptr') - w('#define UNWRAP_GLOBAL(_h) _h') - w('#define WRAP_GLOBAL(_ptr) _ptr') - w('#define UNWRAP_SOURCE_KIND(_h) _h') - w('#endif') - for func in self.api.functions: - trampoline = self.gen_trampoline(func) - if trampoline: - lines.append(trampoline) - lines.append('') - return '\n'.join(lines) - - def gen_trampoline(self, func): - # HPyAPI_FUNC HPy HPyModule_Create(HPyContext *ctx, HPyModuleDef *def) { - # return ctx->ctx_Module_Create ( ctx, def ); - # } - if func.name in conf.NO_TRAMPOLINES: - return None - const_return = get_return_constant(func) - rettype = get_context_return_type(func.node, const_return) - parts = [] - w = parts.append - w('HPyAPI_FUNC') - w(toC(func.node)) - w('{') - - # trampolines cannot deal with varargs easily - assert not func.is_varargs() - - call = [] - wc = call.append - wc(' ') - cast_fun = llvm_return_cast_func.get(rettype, '') - if rettype == 'void': - wc(f'ctx->{func.ctx_name()}') - else: - if cast_fun: - wc(f'return {cast_fun}(ctx->{func.ctx_name()}') - else: - wc(f'return ctx->{func.ctx_name()}') - wc('(') - params = [] - for p in func.node.type.args.params: - param_type_name = toC(p.type) - arg_cast_fun = llvm_param_cast_func.get(param_type_name, '') - params.append(f'{arg_cast_fun}({p.name})') - wc(', '.join(params)) - if cast_fun: - wc('));') - else: - wc(');') - - w(''.join(call)) - if const_return: - w(f'return {const_return};') - - w('}') - return '\n'.join(parts) - - -class autogen_c_access(GraalPyAutoGenFile): - """ - Generates the enum of context members. - """ - INDENT = ' ' - PATH = 'graalpython/com.oracle.graal.python.hpy.llvm/src/autogen_c_access.h' - INPUT_FILE = 'graalpython/com.oracle.graal.python/src/' + java_qname_to_path(HPY_CONTEXT_PKG + 'HPyContextSignatureType') - CFIELD_FILE = 'graalpython/com.oracle.graal.python/src/' + java_qname_to_path(HPY_CONTEXT_PKG + 'GraalHPyCField') - - # HPyType_SpecParam("HPyType_SpecParam", null, null), - CTYPE_REGEX = re.compile(r'\s*(?P[\w_]+)\("(?P[\w_ \*]+)".*\)(?P[,;])\s*') - - # HPyType_SpecParam__kind(Int32_t), - CFIELD_REGEX = re.compile(r'\s*(?P[\w_]+)\((?:[\w_]+)\)(?P[,;])\s*') - - BEGIN_MARKER = 'enum HPyContextSignatureType' - BEGIN_MARKER_CFIELD = 'enum GraalHPyCField' - - def generate(self, root): - lines = [] - w = lines.append - - c_types = [] - with root.join(self.INPUT_FILE).open('r') as f: - read_enum_value = False - i = 0 - for line in f.readlines(): - if self.BEGIN_MARKER in line: - read_enum_value = True - elif read_enum_value: - match = self.CTYPE_REGEX.match(line) - if match: - c_types.append((i, match.group('c_name'))) - read_enum_value = match.group('terminator') == ',' - if line: - i += 1 - - c_fields = [] - with root.join(self.CFIELD_FILE).open('r') as f: - read_enum_value = False - i = 0 - for line in f.readlines(): - if self.BEGIN_MARKER_CFIELD in line: - read_enum_value = True - elif read_enum_value: - match = self.CFIELD_REGEX.match(line) - if match: - val_name = match.group('val_name').replace("__", ".") - first_dot = val_name.find('.') - if first_dot: - c_fields.append((i, val_name[:first_dot], val_name[first_dot+1:])) - read_enum_value = match.group('terminator') == ',' - if line: - i += 1 - - w('#ifndef _AUTOGEN_C_ACCESS_H') - w('#define _AUTOGEN_C_ACCESS_H') - w('#include ') - w('') - w('#include "Python.h"') - w('#include "structmember.h"') - w('') - w('static int fill_c_type_sizes(int32_t *ctype_sizes)') - w('{') - for i, c_name in c_types: - if c_name == 'void': - w(f'{self.INDENT}ctype_sizes[{i}] = (int32_t) 0;') - else: - w(f'{self.INDENT}ctype_sizes[{i}] = (int32_t) sizeof({c_name});') - w(f'{self.INDENT}return 0;') - w('};') - w('') - w('static int fill_c_field_offsets(int32_t *cfield_offsets)') - w('{') - for i, struct_name, field_name in c_fields: - w(f'{self.INDENT}cfield_offsets[{i}] = (int32_t) offsetof({struct_name}, {field_name});' ) - w(f'{self.INDENT}return 0;') - w('};') - w('') - w('#endif') - w('') - return '\n'.join(lines) - - -generators = (autogen_ctx_init_jni_h, - autogen_wrappers_jni, - autogen_ctx_jni, - autogen_ctx_call_jni, - autogen_ctx_jni_upcall_enum, - autogen_svm_jni_upcall_config, - autogen_jni_upcall_method_stub, - autogen_ctx_handles_init, - autogen_ctx_member_enum, - autogen_ctx_llvm_init, - autogen_ctx_function_factory, - autogen_llvm_trampolines_h, - # autogen_llvm_upcall_wrappers, - autogen_c_access) diff --git a/scripts/slot_fuzzer.py b/scripts/slot_fuzzer.py index e9cb890365..59e6f40aa6 100755 --- a/scripts/slot_fuzzer.py +++ b/scripts/slot_fuzzer.py @@ -1,4 +1,4 @@ -# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,19 +37,34 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -# Generates self-contained Python scripts that: + +# Simplistic fuzzer testing interactions between slots, magic methods and builtin functions +# +# How to use: +# +# Run the fuzzer as follows: # -# 1) contain from 1 to 3 classes, each class is either pure Python or native heap type -# (the script itself takes care of compiling and loading the extension). Python class -# N inherits from class N-1. +# python3 slot_fuzzer.py --graalpy /path/to/bin/graalpy --cpython /path/to/bin/python3 --iterations 100 # -# 2) invoke various Python operations on the last class in the hierarchy. The results are -# printed to the stdout. If there is an exception, only its type is printed to the stdout +# It is recommended to use debug build of CPython, so that wrong usages of the C API fail the CPython run, +# and we do not even run such bogus tests on GraalPy. # -# After each such Python script is generated it is executed on both CPython and GraalPy -# and the output is compared. If CPython segfaults, we ignore the test case. +# Triaging a failed test, for example, test number 42: +# cpython42.out is the CPython output +# graalpy42.out is GraaPy output -> compare the two using some diff tool +# test42.py is the self-contained test, running it again is as simple as: +# `/path/to/bin/graalpy test42.py` or `/path/to/bin/python3 test42.py` +# the test itself compiles and loads the native extension +# test42.c is the native extension code +# backup test42.py and manually reduce the code in it to get a smaller reproducer suitable for debugging # -# After the experiment, one can simply manually rerun the problematic test scripts. +# Adding a new slot: +# - add example implementations to "SLOTS" and "MAGIC" +# - single line implementation is assumed to be an expression and will be transformed to a proper function body +# - multiline implementation is taken as-is +# - add tests to 'slots_tester' function + + import os.path import sys import dataclasses @@ -57,6 +72,7 @@ import itertools import subprocess import textwrap +import time from argparse import ArgumentParser from collections import defaultdict @@ -67,11 +83,14 @@ import traceback import operator def slots_tester(Klass, other_klasses): + def normalize_output(text): + return re.sub(r'object at 0x[0-9a-fA-F]+', '', text) + def test(fun, name): try: print(f'{name}:', end='') result = repr(fun()) - result = re.sub(r'object at 0x[0-9a-fA-F]+', '', result) + result = normalize_output(result) print(result) except Exception as e: if '--verbose' in sys.argv or '-v' in sys.argv: @@ -81,9 +100,9 @@ def test(fun, name): def test_dunder(obj, fun_name, *args): # avoid going through tp_getattr/o, which may be overridden to something funky - args_str = ','.join([repr(x) for x in args]) - test(lambda: Klass.__dict__[fun_name](obj, *args), f"{fun_name} via class dict") - test(lambda: getattr(obj, fun_name)(*args), f"{fun_name}") + args_str = normalize_output(','.join([repr(x) for x in [obj, *args]])) + test(lambda: type(obj).__dict__[fun_name](obj, *args), f"{fun_name} via class dict for {args_str}") + test(lambda: getattr(obj, fun_name)(*args), f"{fun_name} for {args_str}") def write_attr(obj, attr, value): if attr == 'foo': @@ -152,16 +171,32 @@ def del_descr(self): del self.descr other_objs = [K() for K in other_klasses] + [42, 3.14, 'string', (1,2,3)] for obj2 in other_objs: obj1 = Klass() - test(lambda: obj1 + obj2, f"{Klass} + {type(obj2)}") - test(lambda: obj2 + obj1, f"{type(obj2)} + {Klass}") - test(lambda: obj1 * obj2, f"{Klass} * {type(obj2)}") - test(lambda: obj2 * obj1, f"{type(obj2)} * {Klass}") - test(lambda: operator.concat(obj1, obj2), f"operator.concat({type(obj2)}, {Klass})") - test(lambda: operator.mul(obj1, obj2), f"operator.mul({type(obj2)}, {Klass})") - test_dunder(obj1, "__add__", obj2) - test_dunder(obj1, "__radd__", obj2) - test_dunder(obj1, "__mul__", obj2) + for op in [operator.add, operator.mul, operator.lt, operator.le, operator.eq, + operator.ne, operator.gt, operator.ge, operator.concat]: + test(lambda: op(obj1, obj2), f"{op.__name__}: {Klass}, {type(obj2)}") + test(lambda: op(obj2, obj1), f"{op.__name__}: {type(obj2)}, {Klass}") + for dunder in ["__add__", "__radd__", "__mul__", "__rmul__", "__lt__", "__le__", "__eq__", "__ne__", "__gt__", "__ge__"]: + test_dunder(obj1, dunder, obj2) + test_dunder(obj2, dunder, obj1) + + def safe_hashattr(x, name): + try: + return hasattr(x, name) + except: + return False + + if safe_hashattr(Klass(), '__hash__'): + if Klass().__hash__ is None: + print("Klass().__hash__ is None") + else: + # just check presence/absence of exception + def test_hash(): + hash(Klass()) + return 'dummy result' + test(test_hash, '__hash__') + else: + print("Klass().__hash__ does not exist") ''' # language=Python @@ -282,7 +317,16 @@ def tp_decl(self, name_prefix): Py_XDECREF(global_stash2); global_stash2 = value; return 0; - ''']) + ''']), + Slot(NO_GROUP, 'tp_hash', 'Py_hash_t $name$(PyObject* self)', ['0', None, '42', '-2', 'PY_SSIZE_T_MAX']), + Slot(NO_GROUP, 'tp_richcompare', 'PyObject* $name$(PyObject* v, PyObject* w, int op)', [ + 'Py_RETURN_FALSE', 'Py_RETURN_TRUE', None, 'Py_RETURN_NONE', 'Py_RETURN_NOTIMPLEMENTED', + *[f''' + if (op == {ops_true[0]} || op == {ops_true[1]}) Py_RETURN_TRUE; + if (op == {ops_false[0]} || op == {ops_false[1]}) Py_RETURN_FALSE; + Py_RETURN_NOTIMPLEMENTED; + ''' for ops_true in itertools.combinations(range(0, 6), 2) + for ops_false in itertools.combinations(set(range(0, 6)) - set(ops_true), 2)]]), ] PY_GLOBALS = ''' @@ -317,15 +361,13 @@ def tp_decl(self, name_prefix): del global_dict1[name] return None '''], - '__getitem__(self, index)': [None, 'True', 'repr(index)'] + '__getitem__(self, index)': [None, 'True', 'repr(index)'], + '__hash__(self)': [None, '1', '-2', '44', '123456788901223442423234234'], + **{name + '(self, other)': [None, 'True', 'False', 'NotImplemented'] + for name in ['__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__']} } -def all_magic_impls(key): - for body in MAGIC[key]: - yield magic_impl(key, body) - - def magic_impl(magic_key, magic_body): if magic_body is None: return '' @@ -336,8 +378,8 @@ def magic_impl(magic_key, magic_body): return f" def {magic_key}:\n{b}" -# One of the combinations is going to be all empty implementations -magic_combinations = [x for x in itertools.product(*[all_magic_impls(key) for key in MAGIC.keys()])] +def magic_combinations_choose_random(): + return list([magic_impl(key, impls[rand.randint(0, len(impls)-1)]) for (key, impls) in MAGIC.items()]) def managed_class_impl(name, bases, magic_impls): @@ -351,11 +393,6 @@ def managed_class_impl(name, bases, magic_impls): return code -def all_slot_impls(slot:Slot): - for body in slot.impls: - yield (slot, body) - - def native_heap_type_impl(name, mod_name, slots): slot_defs = '\n'.join([s.impl(name, body) for (s, body) in slots if body]) slot_decls = ',\n'.join([s.tp_decl(name) for (s, body) in slots if body] + ["{0}"]) @@ -432,20 +469,26 @@ def native_static_type_impl(name, mod_name, slots): ''') -slot_combinations = [x for x in itertools.product(*[all_slot_impls(slot) for slot in SLOTS])] +def slot_combinations_choose_random(): + return list([(slot, slot.impls[rand.randint(0, len(slot.impls) - 1)]) for slot in SLOTS]) + + +def choose_random(l): + return l[rand.randint(0, len(l)-1)] + parser = ArgumentParser() parser.add_argument('--graalpy', dest='graalpy', required=True) parser.add_argument('--cpython', dest='cpython', required=True) parser.add_argument('--iterations', type=int, default=200) -parser.add_argument('--output-dir', dest='output_dir', required=True, - help='where to store generated test cases and logs from test runs') +parser.add_argument('--output-dir', dest='output_dir', + help='Where to store generated test cases and logs from test runs. If not provided the program uses "experiment-{timestamp}"') parser.add_argument('--seed', type=int, default=0) args, _ = parser.parse_known_args() graalpy = args.graalpy cpython = args.cpython -output_dir = args.output_dir +output_dir = args.output_dir if args.output_dir else f'./experiment-{int(time.time())}' if os.path.exists(output_dir): if not os.path.isdir(output_dir): @@ -474,12 +517,6 @@ def log(*args, **kwargs): log() rand = random.Random(seed) - -def choose_random(l): - index = rand.randint(0, len(l)-1) - return l[index] - - for test_case_idx in range(args.iterations): classes_count = max(3, rand.randint(1, 5)) # Make it more likely that it's 3... classes = [] @@ -493,14 +530,14 @@ def choose_random(l): class_name = 'Native' + str(i) native_classes.append(class_name) if i == 0 and rand.randint(0, 2) < 2: - c_source += native_static_type_impl(class_name, test_module_name, choose_random(slot_combinations)) + c_source += native_static_type_impl(class_name, test_module_name, slot_combinations_choose_random()) else: - c_source += native_heap_type_impl(class_name, test_module_name, choose_random(slot_combinations)) + c_source += native_heap_type_impl(class_name, test_module_name, slot_combinations_choose_random()) c_source += '\n' py_source += f"{class_name} = {test_module_name}.create_{class_name}(({base}, ))\n" else: class_name = 'Managed' + str(i) - py_source += managed_class_impl(class_name, (base,), choose_random(magic_combinations)) + py_source += managed_class_impl(class_name, (base,), magic_combinations_choose_random()) py_source += '\n' classes.append(class_name) @@ -546,26 +583,28 @@ def choose_random(l): write_all(os.path.join(output_dir, py_filename), py_source) log(f"Test case {test_case_idx:5}: ", end='') + cpy_output_path = os.path.join(output_dir, f"cpython{test_case_idx}.out") try: cpython_out = subprocess.check_output([cpython, py_filename], stderr=subprocess.STDOUT, cwd=output_dir).decode() - write_all(os.path.join(output_dir, f"cpython{test_case_idx}.out"), cpython_out) + write_all(cpy_output_path, cpython_out) except subprocess.CalledProcessError as e: output = e.output.decode() - log("CPython error; ⚠️") - write_all(os.path.join(output_dir, f"cpython{test_case_idx}.out"), output) + log(f"CPython error; ⚠️ {os.path.abspath(cpy_output_path)}") + write_all(cpy_output_path, output) continue log("CPython succeeded; ", end='') + gpy_output_path = os.path.join(output_dir, f"graalpy{test_case_idx}.out") try: graalpy_out = subprocess.check_output([graalpy, '--vm.ea', '--vm.esa', py_filename], stderr=subprocess.STDOUT, cwd=output_dir).decode() - write_all(os.path.join(output_dir, f"graalpy{test_case_idx}.out"), graalpy_out) + write_all(gpy_output_path, graalpy_out) except subprocess.CalledProcessError as e: output = e.output.decode() - log("❌ fatal error in GraalPy") - write_all(os.path.join(output_dir, f"graalpy{test_case_idx}.out"), output) + log(f"❌ fatal error in GraalPy {os.path.abspath(gpy_output_path)}") + write_all(gpy_output_path, output) continue if cpython_out != graalpy_out: - log(f"❌ output does not match!") + log(f"❌ output does not match! {os.path.abspath(cpy_output_path)} {os.path.abspath(gpy_output_path)}") else: log("✅ GraalPy succeeded") diff --git a/scripts/wheelbuilder/README.md b/scripts/wheelbuilder/README.md index c12d7c5643..8f314373fa 100644 --- a/scripts/wheelbuilder/README.md +++ b/scripts/wheelbuilder/README.md @@ -33,3 +33,51 @@ That can be useful to put things like package installations specific to GitHub A Just run the `build_wheels.py` script. It expects a URL to download the GraalPy release from. You can set the environment variable `PACKAGES_TO_BUILD` to a comma-separated list of package build scripts you want to consider. + +You can build wheels locally. +The way to go about it is to make sure to include the packages you care about in the packages.txt. + +For Linux/amd64, I use [act](https://github.com/nektos/act/releases) on a Linux machine: +```shell +git clone https://github.com/oracle/graalpython +cd graalpython +VERSION=24.2.0 +BINDIR=. curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/nektos/act/master/install.sh | bash +echo "graalpy_url=https://github.com/oracle/graalpython/releases/download/graal-$VERSION/graalpy-$VERSION-linux-amd64.tar.gz" > .input +podman system service -t 0 unix:///tmp/podman.sock & +export DOCKER_HOST=unix:///tmp/podman.sock +./act --env http_proxy=$http_proxy --env https_proxy=$https_proxy -W .github/workflows/build-linux-amd64-wheels.yml --artifact-server-path=$(pwd)/artifacts +``` + +For Linux/aarch64, I use act on a mac, those are usually beefy ARM machines that a developer has in front of them, if we make sure the podman VM has enough memory. +```shell +git clone https://github.com/oracle/graalpython +cd graalpython +VERSION=24.2.0 +brew install act +echo "graalpy_url=https://github.com/oracle/graalpython/releases/download/graal-$VERSION/graalpy-$VERSION-linux-aarch64.tar.gz" > .input +podman machine init -m 16384 --now +act --env http_proxy=$http_proxy --env https_proxy=$https_proxy -W .github/workflows/build-linux-aarch64-wheels.yml --artifact-server-path=$(pwd)/artifacts --container-architecture linux/aarch64 +``` + +For macOS/aarch64, you get no isolation from act, so I just run it directly. +```shell +git clone https://github.com/oracle/graalpython +VERSION=24.2.0 +export GITHUB_RUN_ID=doesntMatterJustTriggerBrewInstallScripts +export PIP_GRAALPY_PATCHES_URL="$(pwd)/graalpython/graalpython/lib-graalpython/patches" +python3 -m venv wheelbuilder-venv +. wheelbuilder-venv/bin/activate +python3 graalpython/scripts/wheelbuilder/build_wheels.py https://github.com/oracle/graalpython/releases/download/graal-$VERSION/graalpy-$VERSION-macos-aarch64.tar.gz +``` + +For Windows/amd64, you get no isolation from act, so I just run it directly in Visual Studio powershell. +```shell +git clone https://github.com/oracle/graalpython +$VERSION="24.2.0" +$env:GITHUB_RUN_ID="doesntMatterJustTriggerBrewInstallScripts" +$env:PIP_GRAALPY_PATCHES_URL="$PWD/graalpython/graalpython/lib-graalpython/patches" +python3 -m venv wheelbuilder-venv +wheelbuilder-venv/scripts/activate +python3 graalpython/scripts/wheelbuilder/build_wheels.py https://github.com/oracle/graalpython/releases/download/graal-$VERSION/graalpy-$VERSION-windows-amd64.zip +``` diff --git a/scripts/wheelbuilder/build_wheels.py b/scripts/wheelbuilder/build_wheels.py index 605032e50d..4797fde2d1 100644 --- a/scripts/wheelbuilder/build_wheels.py +++ b/scripts/wheelbuilder/build_wheels.py @@ -1,4 +1,4 @@ -# Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -50,6 +50,7 @@ import hashlib import importlib import os +import platform import re import shlex import shutil @@ -60,22 +61,25 @@ from argparse import ArgumentParser from glob import glob -from os.path import abspath, basename, dirname, exists, isabs, join, splitext +from os.path import abspath, basename, dirname, exists, expanduser, isabs, isdir, join, splitext from tempfile import TemporaryDirectory from urllib.request import urlretrieve -def ensure_installed(name): +def ensure_installed(name, *extra): try: return importlib.import_module(name) except ImportError: - subprocess.check_call([sys.executable, "-m", "pip", "install", name]) + subprocess.check_call([sys.executable, "-m", "pip", "install", name, *extra]) return importlib.import_module(name) def download(url, out): - print("Downloading", url, flush=True) - urlretrieve(url, out) + if not os.path.exists(out): + print("Downloading", url, flush=True) + urlretrieve(url, out) + else: + print("Using previously downloaded", out, flush=True) def extract(archive): @@ -100,18 +104,47 @@ def create_venv(): subprocess.check_call([binary, "-m", "venv", "graalpy"]) print("Installing wheel with", pip, flush=True) subprocess.check_call([pip, "install", "wheel"]) + print("Installing paatch to provide patch.exe", flush=True) + p = subprocess.run([pip, "install", "paatch"]) + if p.returncode != 0: + print("Installing paatch failed, assuming a GNU patch compatible binary is on PATH", flush=True) return pip +def prepare_environment(pip_exe): + env = os.environ.copy() + env["PATH"] = abspath(dirname(pip_exe)) + os.pathsep + env["PATH"] + env["VIRTUAL_ENV"] = abspath(dirname(dirname(pip_exe))) + if not shutil.which("cargo"): + cargo_bin = join(expanduser("~"), ".cargo", "bin") + if isdir(cargo_bin): + env["PATH"] += os.pathsep + cargo_bin + return env + + def build_wheels(pip): - packages_selected = [s for s in os.environ.get("PACKAGES_TO_BUILD", "").split(",") if s] - packages_to_build = set() with open(join(dirname(__file__), "packages.txt")) as f: - for line in f.readlines(): - line = line.strip() - name, version = line.split("==") - if not packages_selected or name in packages_selected or line in packages_selected: - packages_to_build.add(line) + packages_from_txt = [tuple(l.strip().split("==")) for l in f] + packages_to_build = [] + for s in os.environ.get("PACKAGES_TO_BUILD", "").split(","): + s = s.strip() + if not s: + continue + elif "==" in s: + name, version = s.split("==") + else: + name, version = s, None + for n, v in packages_from_txt: + if n == name: + version = v + break + if not version: + print("ERROR: Asked to build", s, "but no version given") + return False + packages_to_build.append((name, version)) + if not packages_to_build: + packages_to_build = packages_from_txt + print("About to build", packages_to_build) scriptdir = abspath(join(dirname(__file__), sys.platform)) if sys.platform == "win32": script_ext = "bat" @@ -121,66 +154,105 @@ def build_wheels(pip): available_scripts = {s.lower(): s for s in os.listdir(scriptdir)} else: available_scripts = {} - for spec in packages_to_build: - name, version = spec.split("==") - whl_count = len(glob("*.whl")) - script = f"{name}.{version}.{script_ext}".lower() - if script not in available_scripts: - script = f"{name}.{script_ext}".lower() - if script in available_scripts: - script = join(scriptdir, available_scripts[script]) - env = os.environ.copy() - env["PATH"] = abspath(dirname(pip)) + os.pathsep + env["PATH"] - env["VIRTUAL_ENV"] = abspath(dirname(dirname(pip))) - print("Building", name, version, "with", script, flush=True) - if sys.platform == "win32": - cmd = [script, version] # Python's subprocess.py does the quoting we need - else: - cmd = f"{shlex.quote(script)} {version}" - subprocess.check_call(cmd, shell=True, env=env) - if not len(glob("*.whl")) > whl_count: - print("Building wheel for", name, version, "after", script, "did not", flush=True) - subprocess.check_call([pip, "wheel", spec]) - else: + remaining_packages = 0 + while remaining_packages != len(packages_to_build): + remaining_packages = len(packages_to_build) + for name, version in packages_to_build.copy(): + whl_count = len(glob("*.whl")) + script = f"{name}.{version}.{script_ext}".lower() + if script not in available_scripts: + script = f"{name}.{script_ext}".lower() + if script in available_scripts: + script = join(scriptdir, available_scripts[script]) + env = prepare_environment(pip) + print("Building", name, version, "with", script, flush=True) + if sys.platform == "win32": + cmd = [script, version] # Python's subprocess.py does the quoting we need + else: + cmd = f"{os.environ.get('SHELL', '/bin/sh')} {shlex.quote(script)} {version}" + p = subprocess.run(cmd, shell=True, env=env) + if p.returncode != 0: + continue + if len(glob("*.whl")) > whl_count: + packages_to_build.remove((name, version)) + continue + print(script, "did not build a wheel, we will do so now", flush=True) print("Building", name, version, flush=True) - subprocess.check_call([pip, "wheel", spec]) + p = subprocess.run([pip, "wheel", f"{name}=={version}"]) + if p.returncode == 0: + packages_to_build.remove((name, version)) + if packages_to_build: + print("Failed to build all packages, the following packages failed") + print(packages_to_build) + return False + else: + return True def repair_wheels(): - if sys.platform == "win32": - ensure_installed("delvewheel") - env = os.environ.copy() - env["PYTHONUTF8"] = "1" - subprocess.check_call( - [ - sys.executable, - "-m", - "delvewheel", - "repair", - "-v", - "--exclude", - "python-native.dll", - "-w", - "wheelhouse", - *glob("*.whl"), - ], - env=env, - ) - elif sys.platform == "linux": - ensure_installed("auditwheel") - subprocess.check_call( - [join(dirname(sys.executable), "auditwheel"), "repair", "-w", "wheelhouse", *glob("*.whl")] - ) - elif sys.platform == "darwin": - ensure_installed("delocate") - subprocess.check_call( - [join(dirname(sys.executable), "delocate-wheel"), "-v", "-w", "wheelhouse", *glob("*.whl")] - ) + whls = glob("*graalpy*.whl") + env = os.environ.copy() + env["PYTHONUTF8"] = "1" + env["PATH"] = abspath(dirname(sys.executable)) + os.pathsep + env["PATH"] + for whl in whls: + if sys.platform == "win32": + ensure_installed("delvewheel") + p = subprocess.run( + [ + sys.executable, + "-m", + "delvewheel", + "repair", + "-v", + "--exclude", + "python-native.dll", + "-w", + "wheelhouse", + whl, + ], + env=env, + ) + elif sys.platform == "linux": + ensure_installed("auditwheel", "patchelf") + p = subprocess.run( + [ + join(dirname(sys.executable), "auditwheel"), + "repair", + "--plat", + "manylinux_2_28_x86_64" if platform.processor() == "x86_64" else "manylinux_2_28_aarch64", + "-w", + "wheelhouse", + whl, + ], + env=env, + ) + elif sys.platform == "darwin": + ensure_installed("delocate") + p = subprocess.run( + [ + join(dirname(sys.executable), "delocate-wheel"), + "-v", + "--ignore-missing-dependencies", + "--require-archs", + "arm64" if platform.processor() == "arm" else "x86_64", + "-w", + "wheelhouse", + whl, + ], + env=env, + ) + if p.returncode != 0: + print("Repairing", whl, "failed, copying as is.") + try: + shutil.copy(whl, "wheelhouse") + except: + pass if __name__ == "__main__": parser = ArgumentParser() parser.add_argument("graalpy_url") + parser.add_argument("--ignore-failures", action="http://github.com/store_true", default=False) args = parser.parse_args() ext = splitext(args.graalpy_url)[1] outpath = f"graalpy{ext}" @@ -188,5 +260,7 @@ def repair_wheels(): download(args.graalpy_url, outpath) extract(outpath) pip = create_venv() - build_wheels(pip) + success = build_wheels(pip) repair_wheels() + if not success and not args.ignore_failures: + sys.exit(1) diff --git a/scripts/wheelbuilder/darwin/cryptography.sh b/scripts/wheelbuilder/darwin/cryptography.sh new file mode 100755 index 0000000000..500059fb52 --- /dev/null +++ b/scripts/wheelbuilder/darwin/cryptography.sh @@ -0,0 +1,48 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -n "$GITHUB_RUN_ID" ]; then + brew install pkg-config libffi openssl +fi +export PKG_CONFIG_PATH=/opt/homebrew/opt/openssl/lib/pkgconfig +if [ -n "$1" ]; then + pip wheel "cryptography==$1" +else + pip wheel cryptography +fi diff --git a/scripts/wheelbuilder/darwin/levenshtein.0.26.1.sh b/scripts/wheelbuilder/darwin/levenshtein.0.26.1.sh new file mode 100644 index 0000000000..04be0e91b7 --- /dev/null +++ b/scripts/wheelbuilder/darwin/levenshtein.0.26.1.sh @@ -0,0 +1,62 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -n "$GITHUB_RUN_ID" ]; then + git clone --single-branch --branch v3.3.2 --depth 1 https://github.com/rapidfuzz/rapidfuzz-cpp.git rapidfuzz-cpp + cd rapidfuzz-cpp + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=Release + cmake --build . + sudo cmake --build . --target install + cd .. + cd .. +fi + +pip install 'Cython==3.0.11' 'scikit_build_core==0.11.1' +pip install --no-build-isolation 'rapidfuzz==3.12.1' +pip wheel --no-build-isolation 'levenshtein==0.26.1' + +if [ -n "$GITHUB_RUN_ID" ]; then + cd rapidfuzz-cpp + cd build + xargs rm < install_manifest.txt + cd .. + cd .. + rm -rf rapidfuzz-cpp +fi diff --git a/scripts/wheelbuilder/darwin/pandas.sh b/scripts/wheelbuilder/darwin/pandas.sh new file mode 100755 index 0000000000..9217005d7b --- /dev/null +++ b/scripts/wheelbuilder/darwin/pandas.sh @@ -0,0 +1,49 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -n "$GITHUB_RUN_ID" ]; then + brew install gcc openblas pkg-config + export PKG_CONFIG_PATH=/opt/homebrew/opt/openblas/lib/pkgconfig +fi +export FFLAGS=-fallow-argument-mismatch +if [ -n "$1" ]; then + pip wheel "pandas==$1" +else + pip wheel pandas +fi diff --git a/scripts/wheelbuilder/darwin/pymupdf.sh b/scripts/wheelbuilder/darwin/pymupdf.sh new file mode 100755 index 0000000000..c26844ef46 --- /dev/null +++ b/scripts/wheelbuilder/darwin/pymupdf.sh @@ -0,0 +1,81 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -n "$GITHUB_RUN_ID" ]; then + export CPYTHON_EXE="$HOMEBREW_PREFIX/bin/python" +fi + +# BSD patch fails to apply our pymupdf.patch +pip install git+https://github.com/timfel/python-patch-ng + +# darwin's linker does not support --gc-sections but mupdf passes that we wrap +# cc and pass all arguments on, but we remove the argument -Wl,--gc-sections +mkdir cc_bin +export PATH="$(pwd)/cc_bin:$PATH" +original_cc=`which cc` +cat < cc_bin/cc +#!/bin/bash +# Wrapper for cc that removes --gc-sections from command line arguments if present +# Pass on all arguments, but remove -Wl,--gc-sections if it is given + +if [[ "\$@" == *"-Wl,--gc-sections"* ]]; then + echo "Removing -Wl,--gc-sections argument from command line..." + newargs=() + for arg in "\$@"; do + if [ \$arg != "-Wl,--gc-sections" ]; then + newargs+=("\$arg") + fi + done + exec $original_cc "\${newargs[@]}" +else + exec $original_cc "\$@" +fi +EOF +chmod +x cc_bin/cc +export CC="$(pwd)/cc_bin/cc" + +export USE_SONAME="no" + +if [ -n "$1" ]; then + pip wheel "pymupdf==$1" +else + pip wheel pymupdf +fi + +rm -rf cc_bin diff --git a/scripts/wheelbuilder/darwin/pynacl.sh b/scripts/wheelbuilder/darwin/pynacl.sh new file mode 100644 index 0000000000..cb10d556a6 --- /dev/null +++ b/scripts/wheelbuilder/darwin/pynacl.sh @@ -0,0 +1,51 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -n "$GITHUB_RUN_ID" ]; then + brew install libsodium pkg-config + export PKG_CONFIG_PATH=/opt/homebrew/opt/openblas/lib/pkgconfig +fi +export SODIUM_INSTALL=system +export CFLAGS="-arch arm64 $(pkg-config libsodium --cflags)" +export LDFLAGS="$(pkg-config libsodium --libs)" +if [ -n "$1" ]; then + pip wheel "pynacl==$1" +else + pip wheel pynacl +fi diff --git a/scripts/gate_python_quickstyle.sh b/scripts/wheelbuilder/darwin/rapidfuzz.3.12.1.sh old mode 100755 new mode 100644 similarity index 90% rename from scripts/gate_python_quickstyle.sh rename to scripts/wheelbuilder/darwin/rapidfuzz.3.12.1.sh index d9f034d53f..8c083b59b0 --- a/scripts/gate_python_quickstyle.sh +++ b/scripts/wheelbuilder/darwin/rapidfuzz.3.12.1.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,6 +37,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -# mx --strict-compliance --dynamicimports sulong --primary gate --tags style -mx python-gate --tags style,python-license - +pip install 'Cython==3.0.11' 'scikit_build_core==0.11.1' +pip wheel --no-build-isolation 'rapidfuzz==3.12.1' diff --git a/graalpython/lib-graalpython/modules/hpy/__init__.py b/scripts/wheelbuilder/darwin/shapely.sh old mode 100644 new mode 100755 similarity index 93% rename from graalpython/lib-graalpython/modules/hpy/__init__.py rename to scripts/wheelbuilder/darwin/shapely.sh index 56ec9705bd..4064af4fa0 --- a/graalpython/lib-graalpython/modules/hpy/__init__.py +++ b/scripts/wheelbuilder/darwin/shapely.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,3 +37,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +if [ -n "$GITHUB_RUN_ID" ]; then + brew install geos +fi diff --git a/scripts/wheelbuilder/linux/cffi.sh b/scripts/wheelbuilder/linux/cffi.sh index 6770b98e27..21c79d86b7 100755 --- a/scripts/wheelbuilder/linux/cffi.sh +++ b/scripts/wheelbuilder/linux/cffi.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,6 +37,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -if command -v manylinux-interpreters 2>&1 >/dev/null; then +if [ -n "$GITHUB_RUN_ID" ]; then dnf install -y libffi-devel fi diff --git a/scripts/wheelbuilder/linux/cryptography.sh b/scripts/wheelbuilder/linux/cryptography.sh new file mode 100755 index 0000000000..eb9b402c81 --- /dev/null +++ b/scripts/wheelbuilder/linux/cryptography.sh @@ -0,0 +1,42 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -n "$GITHUB_RUN_ID" ]; then + dnf install -y libffi-devel openssl-devel +fi diff --git a/scripts/wheelbuilder/linux/h5py.sh b/scripts/wheelbuilder/linux/h5py.sh index 82172d55f0..7c70c6eba1 100755 --- a/scripts/wheelbuilder/linux/h5py.sh +++ b/scripts/wheelbuilder/linux/h5py.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,6 +37,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -if command -v manylinux-interpreters 2>&1 >/dev/null; then +if [ -n "$GITHUB_RUN_ID" ]; then dnf install -y hdf5-devel fi diff --git a/scripts/wheelbuilder/linux/levenshtein.0.26.1.sh b/scripts/wheelbuilder/linux/levenshtein.0.26.1.sh new file mode 100644 index 0000000000..04be0e91b7 --- /dev/null +++ b/scripts/wheelbuilder/linux/levenshtein.0.26.1.sh @@ -0,0 +1,62 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -n "$GITHUB_RUN_ID" ]; then + git clone --single-branch --branch v3.3.2 --depth 1 https://github.com/rapidfuzz/rapidfuzz-cpp.git rapidfuzz-cpp + cd rapidfuzz-cpp + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=Release + cmake --build . + sudo cmake --build . --target install + cd .. + cd .. +fi + +pip install 'Cython==3.0.11' 'scikit_build_core==0.11.1' +pip install --no-build-isolation 'rapidfuzz==3.12.1' +pip wheel --no-build-isolation 'levenshtein==0.26.1' + +if [ -n "$GITHUB_RUN_ID" ]; then + cd rapidfuzz-cpp + cd build + xargs rm < install_manifest.txt + cd .. + cd .. + rm -rf rapidfuzz-cpp +fi diff --git a/scripts/gate_python_style.sh b/scripts/wheelbuilder/linux/lxml.sh old mode 100755 new mode 100644 similarity index 91% rename from scripts/gate_python_style.sh rename to scripts/wheelbuilder/linux/lxml.sh index 0714826530..40cf8d251e --- a/scripts/gate_python_style.sh +++ b/scripts/wheelbuilder/linux/lxml.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,6 +37,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -# mx --strict-compliance --dynamicimports sulong --primary gate --tags style -mx python-gate --tags style,fullbuild - +if [ -n "$GITHUB_RUN_ID" ]; then + dnf install -y libxml2-devel libxslt-devel +fi diff --git a/scripts/wheelbuilder/linux/numpy.1.23.2.sh b/scripts/wheelbuilder/linux/numpy.1.23.2.sh new file mode 100644 index 0000000000..473b91359d --- /dev/null +++ b/scripts/wheelbuilder/linux/numpy.1.23.2.sh @@ -0,0 +1,43 @@ +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -n "$GITHUB_RUN_ID" ]; then + dnf install -y gcc-toolset-9 gcc-toolset-9-gcc-gfortran openblas-devel + scl enable gcc-toolset-9 'pip wheel "numpy==1.23.2"' +fi diff --git a/scripts/wheelbuilder/linux/numpy.1.23.5.sh b/scripts/wheelbuilder/linux/numpy.1.23.5.sh new file mode 100644 index 0000000000..2293b2c906 --- /dev/null +++ b/scripts/wheelbuilder/linux/numpy.1.23.5.sh @@ -0,0 +1,43 @@ +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -n "$GITHUB_RUN_ID" ]; then + dnf install -y gcc-toolset-9 gcc-toolset-9-gcc-gfortran openblas-devel + scl enable gcc-toolset-9 'pip wheel "numpy==1.23.5"' +fi diff --git a/scripts/wheelbuilder/linux/numpy.1.24.3.sh b/scripts/wheelbuilder/linux/numpy.1.24.3.sh new file mode 100644 index 0000000000..f9e524e3d4 --- /dev/null +++ b/scripts/wheelbuilder/linux/numpy.1.24.3.sh @@ -0,0 +1,43 @@ +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -n "$GITHUB_RUN_ID" ]; then + dnf install -y gcc-toolset-9 gcc-toolset-9-gcc-gfortran openblas-devel + scl enable gcc-toolset-9 'pip wheel "numpy==1.24.3"' +fi diff --git a/scripts/wheelbuilder/linux/numpy.sh b/scripts/wheelbuilder/linux/numpy.sh index a24e6a2aa3..8cd8c11077 100755 --- a/scripts/wheelbuilder/linux/numpy.sh +++ b/scripts/wheelbuilder/linux/numpy.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,6 +37,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -if command -v manylinux-interpreters 2>&1 >/dev/null; then +if [ -n "$GITHUB_RUN_ID" ]; then dnf install -y gcc-toolset-12-gcc-gfortran openblas-devel fi diff --git a/scripts/wheelbuilder/linux/pillow.sh b/scripts/wheelbuilder/linux/pillow.sh index e6d64d0863..4b535f89df 100755 --- a/scripts/wheelbuilder/linux/pillow.sh +++ b/scripts/wheelbuilder/linux/pillow.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,6 +37,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -if command -v manylinux-interpreters 2>&1 >/dev/null; then +if [ -n "$GITHUB_RUN_ID" ]; then dnf install -y libtiff-devel libjpeg-devel openjpeg2-devel zlib-devel freetype-devel lcms2-devel fi diff --git a/scripts/wheelbuilder/linux/pyarrow.sh b/scripts/wheelbuilder/linux/pyarrow.sh new file mode 100644 index 0000000000..1f56c7bee9 --- /dev/null +++ b/scripts/wheelbuilder/linux/pyarrow.sh @@ -0,0 +1,58 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -n "$GITHUB_RUN_ID" ]; then + dnf install -y libffi-devel \ + boost-devel \ + snappy-devel \ + brotli-devel \ + openssl-devel \ + thrift-devel \ + jemalloc-devel \ + xsimd-devel \ + libzstd-devel \ + re2-devel \ + mimalloc-devel \ + lz4-devel \ + bzip2-devel \ + llvm llvm-libs llvm-devel \ + llvm-cmake-utils \ + lld lld-devel \ + clang clang-libs clang-devel +fi diff --git a/scripts/wheelbuilder/linux/pymupdf.sh b/scripts/wheelbuilder/linux/pymupdf.sh new file mode 100755 index 0000000000..d949e7d332 --- /dev/null +++ b/scripts/wheelbuilder/linux/pymupdf.sh @@ -0,0 +1,51 @@ +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -n "$GITHUB_RUN_ID" ]; then + dnf install -y /usr/bin/c++ /usr/bin/make /usr/bin/which /usr/bin/python3 + export CPYTHON_EXE=/usr/bin/python3 +fi + +export USE_SONAME="no" + +if [ -n "$1" ]; then + pip wheel "pymupdf==$1" +else + pip wheel pymupdf +fi diff --git a/scripts/wheelbuilder/linux/pynacl.sh b/scripts/wheelbuilder/linux/pynacl.sh new file mode 100644 index 0000000000..8d488965e9 --- /dev/null +++ b/scripts/wheelbuilder/linux/pynacl.sh @@ -0,0 +1,42 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -n "$GITHUB_RUN_ID" ]; then + dnf install -y libffi-devel +fi diff --git a/scripts/wheelbuilder/linux/rapidfuzz.3.12.1.sh b/scripts/wheelbuilder/linux/rapidfuzz.3.12.1.sh new file mode 100644 index 0000000000..8c083b59b0 --- /dev/null +++ b/scripts/wheelbuilder/linux/rapidfuzz.3.12.1.sh @@ -0,0 +1,41 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +pip install 'Cython==3.0.11' 'scikit_build_core==0.11.1' +pip wheel --no-build-isolation 'rapidfuzz==3.12.1' diff --git a/scripts/wheelbuilder/linux/scipy.sh b/scripts/wheelbuilder/linux/scipy.sh index cb127c5abc..19cffbffc4 100755 --- a/scripts/wheelbuilder/linux/scipy.sh +++ b/scripts/wheelbuilder/linux/scipy.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,7 +37,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -if command -v manylinux-interpreters 2>&1 >/dev/null; then +if [ -n "$GITHUB_RUN_ID" ]; then dnf install -y gcc-toolset-12-gcc-gfortran openblas-devel fi export FFLAGS=-fallow-argument-mismatch diff --git a/scripts/wheelbuilder/linux/shapely.sh b/scripts/wheelbuilder/linux/shapely.sh new file mode 100644 index 0000000000..8fd92732b3 --- /dev/null +++ b/scripts/wheelbuilder/linux/shapely.sh @@ -0,0 +1,42 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -n "$GITHUB_RUN_ID" ]; then + dnf install -y libgeos-devel +fi diff --git a/scripts/wheelbuilder/linux/tensorflow.sh b/scripts/wheelbuilder/linux/tensorflow.sh index f67401d4bf..03259d33cd 100755 --- a/scripts/wheelbuilder/linux/tensorflow.sh +++ b/scripts/wheelbuilder/linux/tensorflow.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,7 +37,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -if command -v manylinux-interpreters 2>&1 >/dev/null; then +if [ -n "$GITHUB_RUN_ID" ]; then dnf install -y openblas-devel /usr/bin/cmake /usr/bin/sudo /usr/bin/curl java-11-openjdk-devel fi pip install pip numpy wheel packaging requests opt_einsum diff --git a/scripts/wheelbuilder/linux/torch.sh b/scripts/wheelbuilder/linux/torch.sh index e931f26abd..b2c54a9644 100755 --- a/scripts/wheelbuilder/linux/torch.sh +++ b/scripts/wheelbuilder/linux/torch.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -37,7 +37,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -if command -v manylinux-interpreters 2>&1 >/dev/null; then +if [ -n "$GITHUB_RUN_ID" ]; then dnf install -y openblas-devel /usr/bin/cmake /usr/bin/sudo libffi-devel export USE_CUDA=0 fi diff --git a/scripts/wheelbuilder/linux/zstandard.sh b/scripts/wheelbuilder/linux/zstandard.sh new file mode 100644 index 0000000000..8d488965e9 --- /dev/null +++ b/scripts/wheelbuilder/linux/zstandard.sh @@ -0,0 +1,42 @@ +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or +# data (collectively the "Software"), free of charge and under any and all +# copyright rights in the Software, and any and all patent rights owned or +# freely licensable by each licensor hereunder covering either (i) the +# unmodified Software as contributed to or provided by such licensor, or (ii) +# the Larger Works (as defined below), to deal in both +# +# (a) the Software, and +# +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# +# The above copyright notice and either this complete permission notice or at a +# minimum a reference to the UPL must be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -n "$GITHUB_RUN_ID" ]; then + dnf install -y libffi-devel +fi diff --git a/scripts/wheelbuilder/packages.txt b/scripts/wheelbuilder/packages.txt index aa4de2a2f1..d9504374aa 100644 --- a/scripts/wheelbuilder/packages.txt +++ b/scripts/wheelbuilder/packages.txt @@ -1,6 +1,80 @@ +Deprecated==1.2.18 +FLAML==2.1.2 +aiofiles==24.1.0 +annotated-types==0.7.0 +anyio==4.4.0 +anyio==4.8.0 +autogen-agentchat==0.4.6 +autogen-agentchat==0.4.9 +autogen-agentchat==0.4.9.3 +autogen-core==0.4.6 +autogen-core==0.4.9 +autogen-core==0.4.9.3 +autogen-ext==0.4.6 +autogen-ext==0.4.9.3 +autogen-ext[openai]==0.4.9 +blis==0.7.11 +certifi==2024.7.4 +certifi==2025.1.31 +cffi==1.17.1 +charset-normalizer==3.1.0 +charset-normalizer==3.4.1 +circuitbreaker==2.1.3 +cryptography==41.0.7 +deprecated==1.2.18 +diskcache==5.6.3 +distro==1.9.0 +docker==7.1.0 +exceptiongroup==1.2.1 +h11==0.14.0 +httpcore==1.0.5 +httpcore==1.0.7 +httpx==0.27.0 +httpx==0.28.1 +idna==3.10 +idna==3.7 +jiter==0.8.2 +jsonref==1.1.0 +marisa_trie==1.2.1 +numpy==1.23.2 +numpy==1.23.5 +numpy==1.24.3 numpy==1.26.4 -httptools==0.6.1 -kiwisolver==1.4.5 -psutil==5.9.8 -ujson==5.10.0 -xxhash==3.4.1 +oci==2.149.2 +openai==1.35.10 +openai==1.62.0 +opentelemetry-api==1.30.0 +opentelemetry-api==1.31.1 +packaging==24.1 +pandas==1.5.2 +pillow==11.1.0 +preshed==3.0.9 +protobuf==5.29.3 +protobuf==5.29.4 +pyOpenSSL==23.2.0 +pyautogen==0.2.32 +pycparser==2.22 +pydantic-core==2.10.1 +pydantic-core==2.27.2 +pydantic-core==2.29.0 +pydantic==2.10.6 +pydantic==2.11.0a2 +pydantic==2.4.2 +python-dotenv==1.0.1 +pytz==2025.2 +regex==2024.11.6 +regex==2024.5.15 +requests==2.32.3 +sniffio==1.3.1 +spacy==3.6.1 +termcolor==2.4.0 +thinc==8.1.12 +tiktoken==0.7.0 +tiktoken==0.8.0 +tqdm==4.66.4 +tqdm==4.67.1 +typing-extensions==4.12.2 +urllib3==2.2.2 +urllib3==2.3.0 +wrapt==1.17.2 +zipp==3.21.0